diff --git a/.editorconfig b/.editorconfig index 2bd8cf9e86d..c85531eb0b5 100644 --- a/.editorconfig +++ b/.editorconfig @@ -17,3 +17,6 @@ charset = utf-8-bom [*.md] trim_trailing_whitespace = false + +[*.snap] +trim_trailing_whitespace = false diff --git a/.eslintignore b/.eslintignore deleted file mode 100644 index f9f03214300..00000000000 --- a/.eslintignore +++ /dev/null @@ -1,24 +0,0 @@ -# Ignore node_modules -node_modules - -# Ignore some folders -benchmark -coverage - -# Ignore not support files -!.*.js -.eslintrc.js -*.d.ts - -# Ignore some test files -test/* -!test/*Cases -!test/helpers -!test/*.js -test/*Cases/**/*.js -!test/*Cases/**/webpack.config.js - -# Ignore some examples files -examples/**/*.js -!examples/*/webpack.config.js - diff --git a/.eslintrc.js b/.eslintrc.js deleted file mode 100644 index 28d47e83dca..00000000000 --- a/.eslintrc.js +++ /dev/null @@ -1,104 +0,0 @@ -module.exports = { - root: true, - plugins: ["prettier", "node", "jest", "jsdoc"], - extends: [ - "eslint:recommended", - "plugin:node/recommended", - "plugin:prettier/recommended" - ], - env: { - node: true, - es6: true - }, - parserOptions: { - ecmaVersion: 2018 - }, - rules: { - "prettier/prettier": "error", - "no-template-curly-in-string": "error", - "no-caller": "error", - "no-control-regex": "off", - yoda: "error", - eqeqeq: "error", - "eol-last": "error", - "no-extra-bind": "warn", - "no-process-exit": "warn", - "no-use-before-define": "off", - "no-unused-vars": ["error", { args: "none", ignoreRestSiblings: true }], - "no-loop-func": "warn", - "node/no-missing-require": ["error", { allowModules: ["webpack"] }], - "jsdoc/check-indentation": "error", - "jsdoc/check-param-names": "error", - "jsdoc/check-property-names": "error", - "jsdoc/check-tag-names": "error", - "jsdoc/require-hyphen-before-param-description": ["error", "never"], - "jsdoc/require-param-description": "error", - "jsdoc/require-param-name": "error", - "jsdoc/require-param-type": "error", - "jsdoc/require-param": "error", - "jsdoc/require-property": "error", - "jsdoc/require-property-name": "error", - "jsdoc/require-property-type": "error", - "jsdoc/require-returns-description": "error", - "jsdoc/require-returns-type": "error", - "jsdoc/require-returns": "error", - // Disallow @ts-ignore directive. Use @ts-expect-error instead - "no-warning-comments": [ - "error", - { terms: ["@ts-ignore"], location: "start" } - ] - }, - settings: { - jsdoc: { - mode: "typescript", - // supported tags https://github.com/microsoft/TypeScript-wiki/blob/master/JSDoc-support-in-JavaScript.md - tagNamePreference: { - ...["implements", "const", "memberof", "readonly", "yields"].reduce( - (acc, tag) => { - acc[tag] = { - message: `@${tag} currently not supported in Typescript` - }; - return acc; - }, - {} - ), - extends: "extends", - return: "returns", - constructor: "constructor", - prop: "property", - arg: "param", - augments: "extends", - description: false, - desc: false, - inheritdoc: false, - class: "constructor" - }, - overrideReplacesDocs: false - } - }, - overrides: [ - { - files: ["lib/**/*.runtime.js", "hot/*.js"], - env: { - es6: false, - browser: true - }, - globals: { - Promise: false - }, - parserOptions: { - ecmaVersion: 5 - } - }, - { - files: ["test/**/*.js"], - env: { - "jest/globals": true - }, - globals: { - nsObj: false, - jasmine: false - } - } - ] -}; diff --git a/.gitattributes b/.gitattributes index 46ada865c8d..4a65e411fbd 100644 --- a/.gitattributes +++ b/.gitattributes @@ -3,3 +3,5 @@ test/statsCases/** eol=lf examples/* eol=lf bin/* eol=lf *.svg eol=lf +*.css eol=lf +**/*webpack.lock.data/** -text diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md index ba313faa478..3b257921146 100644 --- a/.github/ISSUE_TEMPLATE.md +++ b/.github/ISSUE_TEMPLATE.md @@ -2,9 +2,11 @@ -**Do you want to request a *feature* or report a *bug*?** +**Do you want to request a _feature_ or report a _bug_?** - + + + **What is the current behavior?** diff --git a/.github/ISSUE_TEMPLATE/Bug_report.md b/.github/ISSUE_TEMPLATE/Bug_report.md index 437637672bb..de70ffd482d 100644 --- a/.github/ISSUE_TEMPLATE/Bug_report.md +++ b/.github/ISSUE_TEMPLATE/Bug_report.md @@ -8,17 +8,15 @@ about: Create a report to help us improve # Bug report - + + - **What is the current behavior?** - **If the current behavior is a bug, please provide the steps to reproduce.** - @@ -28,12 +26,11 @@ about: Create a report to help us improve **What is the expected behavior?** - **Other relevant information:** webpack version: -Node.js version: -Operating System: +Node.js version: +Operating System: Additional tools: diff --git a/.github/ISSUE_TEMPLATE/Feature_request.md b/.github/ISSUE_TEMPLATE/Feature_request.md index ff728e6db23..704020c0671 100644 --- a/.github/ISSUE_TEMPLATE/Feature_request.md +++ b/.github/ISSUE_TEMPLATE/Feature_request.md @@ -1,7 +1,6 @@ --- name: Feature request about: Suggest an idea for this project - --- @@ -16,12 +15,9 @@ about: Suggest an idea for this project **What is the expected behavior?** - **What is motivation or use case for adding/changing the behavior?** - **How should this be implemented in your opinion?** - **Are you willing to work on this yourself?** yes diff --git a/.github/ISSUE_TEMPLATE/Other.md b/.github/ISSUE_TEMPLATE/Other.md index 033e88fcad4..3faf967c321 100644 --- a/.github/ISSUE_TEMPLATE/Other.md +++ b/.github/ISSUE_TEMPLATE/Other.md @@ -1,9 +1,10 @@ --- name: Other about: Something else - --- - + + + diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 8967c8f0169..89efe54b7d5 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -2,7 +2,6 @@ - **What kind of change does this PR introduce?** diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 00000000000..d5be4141d14 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,31 @@ +version: 2 +updates: + - package-ecosystem: npm + directory: "/" + schedule: + interval: daily + time: "04:00" + timezone: Europe/Berlin + open-pull-requests-limit: 20 + labels: + - dependencies + versioning-strategy: widen + groups: + dependencies: + patterns: + - "*" + exclude-patterns: + - "eslint-scope" + - "json-parse-even-better-errors" + - "schema-utils" + - "strip-ansi" + - "rimraf" + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: daily + time: "04:00" + timezone: Europe/Berlin + open-pull-requests-limit: 20 + labels: + - dependencies diff --git a/.github/workflows/dependency-review.yml b/.github/workflows/dependency-review.yml new file mode 100644 index 00000000000..b14a81db447 --- /dev/null +++ b/.github/workflows/dependency-review.yml @@ -0,0 +1,60 @@ +name: "Dependency Review" + +on: [pull_request] + +permissions: + contents: read + +jobs: + dependency-review: + runs-on: ubuntu-latest + steps: + - name: "Checkout Repository" + uses: actions/checkout@v4 + - name: "Dependency Review" + uses: actions/dependency-review-action@v4 + with: + allow-licenses: | + 0BSD, + AFL-1.1, + AFL-1.2, + AFL-2.0, + AFL-2.1, + AFL-3.0, + AGPL-3.0-only, + AGPL-3.0-or-later, + Apache-1.1, + Apache-2.0, + APSL-2.0, + Artistic-2.0, + BlueOak-1.0.0, + BSD-2-Clause, + BSD-3-Clause-Clear, + BSD-3-Clause, + BSL-1.0, + CAL-1.0, + CC-BY-3.0, + CC-BY-4.0, + CC-BY-SA-4.0, + CDDL-1.0, + CC0-1.0, + EPL-2.0, + GPL-2.0-only, + GPL-2.0-or-later, + GPL-2.0, + GPL-3.0-or-later, + ISC, + LGPL-2.0-only, + LGPL-2.1-only, + LGPL-2.1-or-later, + LGPL-2.1, + LGPL-3.0-only, + LGPL-3.0, + MIT, + MPL-2.0, + OFL-1.1, + PSF-2.0, + Python-2.0, + Python-2.0.1, + Unicode-DFS-2016, + Unlicense diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 0223101a0dc..673cb200b5e 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -1,129 +1,191 @@ -name: Test - -# cspell:word Ignus -# cspell:word eslintcache +name: Github Actions on: push: branches: - - master + - main - dev-1 pull_request: branches: - - master + - main - dev-1 +permissions: + contents: read + jobs: lint: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - name: Use Node.js - uses: actions/setup-node@v1 - with: - node-version: 14.x - - id: yarn-cache-dir-path - run: echo "::set-output name=dir::$(yarn cache dir)" - - uses: actions/cache@v1 + uses: actions/setup-node@v4 with: - path: ${{ steps.yarn-cache-dir-path.outputs.dir }} - key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }} - restore-keys: ${{ runner.os }}-yarn- + node-version: lts/* + cache: "yarn" - run: yarn --frozen-lockfile - - uses: actions/cache@v1 + - name: Cache prettier result + uses: actions/cache@v4 + with: + path: ./node_modules/.cache/prettier/.prettier-cache + key: lint-prettier-${{ runner.os }}-node-${{ hashFiles('**/yarn.lock', '**/.prettierrc.js') }} + restore-keys: lint-prettier- + - name: Cache eslint result + uses: actions/cache@v4 with: path: .eslintcache - key: lint-${{ env.GITHUB_SHA }} - restore-keys: lint- + key: lint-eslint-${{ runner.os }}-node-${{ hashFiles('**/yarn.lock', '**/eslint.config.js') }} + restore-keys: lint-eslint- + - name: Cache cspell result + uses: actions/cache@v4 + with: + path: .cspellcache + key: lint-cspell-${{ runner.os }}-node-${{ hashFiles('**/yarn.lock', '**/cspell.json') }} + restore-keys: lint-cspell- - run: yarn lint basic: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - name: Use Node.js - uses: actions/setup-node@v1 + uses: actions/setup-node@v4 with: - node-version: 14.x - - id: yarn-cache-dir-path - run: echo "::set-output name=dir::$(yarn cache dir)" - - uses: actions/cache@v1 - with: - path: ${{ steps.yarn-cache-dir-path.outputs.dir }} - key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }} - restore-keys: ${{ runner.os }}-yarn- + node-version: lts/* + cache: "yarn" - run: yarn --frozen-lockfile - run: yarn link --frozen-lockfile || true - run: yarn link webpack --frozen-lockfile - - run: yarn test:basic --ci --reporters=default --reporters=jest-junit - - uses: codecov/codecov-action@v1 + - run: yarn test:basic --ci + - uses: codecov/codecov-action@v4 with: flags: basic functionalities: gcov - unit: + env: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} + validate-legacy-node: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - name: Use Node.js - uses: actions/setup-node@v1 + uses: actions/setup-node@v4 with: - node-version: 14.x - - id: yarn-cache-dir-path - run: echo "::set-output name=dir::$(yarn cache dir)" - - uses: actions/cache@v1 + node-version: 10.x + cache: "yarn" + # Remove `devDependencies` from `package.json` to avoid `yarn install` compatibility error + - run: node -e "const content = require('./package.json');delete content.devDependencies;require('fs').writeFileSync('package.json', JSON.stringify(content, null, 2));" + - run: yarn install --production --frozen-lockfile + unit: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Use Node.js + uses: actions/setup-node@v4 with: - path: ${{ steps.yarn-cache-dir-path.outputs.dir }} - key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }} - restore-keys: ${{ runner.os }}-yarn- + node-version: lts/* + cache: "yarn" - run: yarn --frozen-lockfile - run: yarn link --frozen-lockfile || true - run: yarn link webpack --frozen-lockfile - - uses: actions/cache@v1 + - uses: actions/cache@v4 with: path: .jest-cache key: jest-unit-${{ env.GITHUB_SHA }} - restore-keys: jest-unit- - - run: yarn cover:unit --ci --cacheDirectory .jest-cache --reporters=default --reporters=jest-junit - - uses: codecov/codecov-action@v1 + restore-keys: jest-unit-${{ hashFiles('**/yarn.lock', '**/jest.config.js') }} + - run: yarn cover:unit --ci --cacheDirectory .jest-cache + - uses: codecov/codecov-action@v4 with: flags: unit functionalities: gcov + env: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} integration: needs: basic strategy: fail-fast: false matrix: os: [ubuntu-latest, windows-latest, macos-latest] - node-version: [10.x, 14.x] + node-version: [10.x, 20.x] + part: [a, b] include: + # Test with main branches of webpack dependencies + - os: ubuntu-latest + node-version: lts/* + part: a + use_main_branches: 1 + - os: ubuntu-latest + node-version: lts/* + part: b + use_main_branches: 1 + # Test on the latest version of Node.js + - os: ubuntu-latest + node-version: 22.x + part: a + - os: ubuntu-latest + node-version: 22.x + part: b + # Test on the old LTS version of Node.js - os: ubuntu-latest - node-version: 15.x + node-version: 18.x + part: a + - os: ubuntu-latest + node-version: 18.x + part: b + # Test on old Node.js versions + - os: ubuntu-latest + node-version: 16.x + part: a + - os: ubuntu-latest + node-version: 14.x + part: a - os: ubuntu-latest node-version: 12.x + part: a runs-on: ${{ matrix.os }} steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 + - uses: actions/github-script@v7 + id: calculate_architecture + with: + result-encoding: string + script: | + if ('${{ matrix.os }}' === 'macos-latest' && '${{ matrix['node-version'] }}' === '10.x') { + return "x64" + } else { + return '' + } - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v1 + uses: actions/setup-node@v4 with: node-version: ${{ matrix.node-version }} - - id: yarn-cache-dir-path - run: echo "::set-output name=dir::$(yarn cache dir)" - - uses: actions/cache@v1 - with: - path: ${{ steps.yarn-cache-dir-path.outputs.dir }} - key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }} - restore-keys: ${{ runner.os }}-yarn- + architecture: ${{ steps.calculate_architecture.outputs.result }} + cache: "yarn" + # Install old `jest` version and deps for legacy node versions + - run: | + yarn upgrade jest@^27.5.0 jest-circus@^27.5.0 jest-cli@^27.5.0 jest-diff@^27.5.0 jest-environment-node@^27.5.0 jest-junit@^13.0.0 @types/jest@^27.4.0 pretty-format@^27.0.2 husky@^8.0.3 lint-staged@^13.2.1 cspell@^6.31.1 open-cli@^7.2.0 coffee-loader@^1.0.0 babel-loader@^8.1.0 style-loader@^2.0.0 css-loader@^5.0.1 less-loader@^8.1.1 mini-css-extract-plugin@^1.6.1 --ignore-engines + yarn --frozen-lockfile --ignore-engines + if: matrix.node-version == '10.x' || matrix.node-version == '12.x' || matrix.node-version == '14.x' + - run: | + yarn upgrade husky@^8.0.3 lint-staged@^13.2.1 nyc@^15.1.0 coffee-loader@1.0.0 babel-loader@^8.1.0 style-loader@^2.0.0 css-loader@^5.0.1 less-loader@^8.1.1 mini-css-extract-plugin@^1.6.1 --ignore-engines + yarn --frozen-lockfile + if: matrix.node-version == '16.x' + # Install main version of our deps + - run: yarn upgrade enhanced-resolve@webpack/enhanced-resolve#main loader-runner@webpack/loader-runner#main webpack-sources@webpack/webpack-sources#main watchpack@webpack/watchpack#main tapable@webpack/tapable#master + if: matrix.use_main_branches == '1' + # Install dependencies for LTS node versions - run: yarn --frozen-lockfile + if: matrix.node-version != '10.x' && matrix.node-version != '12.x' && matrix.node-version != '14.x' && matrix.node-version != '16.x' - run: yarn link --frozen-lockfile || true - run: yarn link webpack --frozen-lockfile - - uses: actions/cache@v1 + - uses: actions/cache@v4 with: path: .jest-cache key: jest-integration-${{ env.GITHUB_SHA }} - restore-keys: jest-integration- - - run: yarn cover:integration --ci --cacheDirectory .jest-cache --reporters=default --reporters=jest-junit - - if: ${{ matrix.os != 'windows-latest' }} - uses: codecov/codecov-action@v1 + restore-keys: jest-integration-${{ hashFiles('**/yarn.lock', '**/jest.config.js') }} + - run: yarn cover:integration:${{ matrix.part }} --ci --cacheDirectory .jest-cache || yarn cover:integration:${{ matrix.part }} --ci --cacheDirectory .jest-cache -f + - run: yarn cover:merge + - uses: codecov/codecov-action@v4 with: flags: integration functionalities: gcov + env: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} diff --git a/.gitignore b/.gitignore index 4719028a0ea..8ae0b40e9dc 100644 --- a/.gitignore +++ b/.gitignore @@ -4,14 +4,20 @@ /test/fixtures/temp-* /test/temp /test/ChangesAndRemovals +/test/**/dev-defaults.webpack.lock /benchmark/js /benchmark/fixtures /examples/**/dist +/assembly/**/*.wat +/assembly/**/*.wasm /coverage +/.nyc_output +/.jest-cache .DS_Store *.log .idea .vscode .cache .eslintcache +.cspellcache package-lock.json diff --git a/.husky/.gitignore b/.husky/.gitignore deleted file mode 100644 index 31354ec1389..00000000000 --- a/.husky/.gitignore +++ /dev/null @@ -1 +0,0 @@ -_ diff --git a/.husky/pre-commit b/.husky/pre-commit index d37daa075e2..041c660c92b 100755 --- a/.husky/pre-commit +++ b/.husky/pre-commit @@ -1,4 +1 @@ -#!/bin/sh -. "$(dirname "$0")/_/husky.sh" - npx --no-install lint-staged diff --git a/.prettierignore b/.prettierignore index dceadd34a1f..eeb72ea7218 100644 --- a/.prettierignore +++ b/.prettierignore @@ -1,11 +1,33 @@ package.json -# Ignore test fixtures -test/*.* +# Ignore some test files +test/**/*.* !test/*.js !test/**/webpack.config.js +!test/**/test.config.js +!test/**/test.filter.js +!test/**/errors.js +!test/**/warnings.js !test/**/deprecations.js +!test/*.md +!test/helpers/*.* + +# Ignore some folders +benchmark/ +coverage/ + +# Ignore generated files +*.check.js + +# Ignore not supported files +*.d.ts +!module.d.ts + +# Ignore precompiled schemas +schemas/**/*.check.js # Ignore example fixtures -examples/*.* +examples/ !examples/**/webpack.config.js + +.vscode/**/*.* diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 409ddaf9503..00000000000 --- a/.travis.yml +++ /dev/null @@ -1,74 +0,0 @@ -dist: trusty -language: node_js - -branches: - only: - - webpack-4 - - master - - next - - dev-1 - -cache: - yarn: true - directories: - - ".jest-cache" - - ".eslintcache" - -stages: - - basic - - advanced - -matrix: - include: - - os: linux - node_js: "12" - env: NO_WATCH_TESTS=1 JEST="--maxWorkers=2 --cacheDirectory .jest-cache" JOB_PART=basic - stage: basic - - os: linux - node_js: "12" - env: NO_WATCH_TESTS=1 JEST="--maxWorkers=2 --cacheDirectory .jest-cache" JOB_PART=lintunit - stage: advanced - - os: linux - node_js: "12" - env: NO_WATCH_TESTS=1 JEST="--maxWorkers=2 --cacheDirectory .jest-cache" JOB_PART=integration - stage: advanced - - os: linux - node_js: "12" - env: NO_WATCH_TESTS=1 ALTERNATIVE_SORT=1 JEST="--maxWorkers=2 --cacheDirectory .jest-cache" JOB_PART=integration - stage: advanced - - os: linux - node_js: "10" - env: - - NODEJS_VERSION=v15.0.0-nightly2020082003293aa3a1 - - YARN_EXTRA_ARGS="--ignore-engines" - - NO_WATCH_TESTS=1 - - JEST="--maxWorkers=2 --cacheDirectory .jest-cache" - - JOB_PART=integration - stage: advanced - fast_finish: true - -before_install: - - | - if [ "$NODEJS_VERSION" != "" ]; - then - mkdir /opt/node - curl --silent "https://nodejs.org/download/nightly/$NODEJS_VERSION/node-$NODEJS_VERSION-linux-x64.tar.gz" | tar -zxf - --directory /opt/node - export PATH="/opt/node/node-$NODEJS_VERSION-linux-x64/bin:$PATH" - node --version - fi - -install: - - yarn --frozen-lockfile $YARN_EXTRA_ARGS - - yarn link --frozen-lockfile $YARN_EXTRA_ARGS || true - - yarn link webpack --frozen-lockfile $YARN_EXTRA_ARGS - -script: yarn travis:$JOB_PART - -after_success: - - cat ./coverage/lcov.info | node_modules/.bin/coveralls --verbose - - bash <(curl -s https://codecov.io/bash) -F $JOB_PART -X gcov - - rm -f .jest-cache/haste-map* .jest-cache/perf-cache* - -notifications: - slack: - secure: JduSdKWwbnLCwo7Z4E59SGE+Uw832UwnXzQiKEpg1BV45MYDPRiGltly1tRHmPh9OGjvGx3XSkC2tNGOBLtL4UL2SCkf012x0t7jDutKRfcv/njynl8jk8l+UhPmaWiHXDQAgGiiKdL4RfzPLW3HeVHCOWm0LKMzcarTa8tw+rE= diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 146a567a0c0..700cae8fab1 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -55,6 +55,18 @@ greatly appreciate any time spent fixing typos or clarifying sections in the documentation. [See a list of issues with the documentation tag](https://github.com/webpack/webpack/labels/documentation), or [check out the issues on the documentation website's repository](https://github.com/webpack/webpack.js.org/issues). +## Types + +webpack is statically typed using JSDoc annotation and TypeScript. If you would like to export a new type which doesn't belong to a public API, then you can do so by declaring it in `webpack/lib/index.js`. + +`webpack/lib/index.js` + +```js +/** @typedef {import("./NormalModuleFactory").ResolveData} ResolveData */ +``` + +Then, automatically generate the type declarations by running `yarn fix` locally, and the changes you have made will be reflected in `types.d.ts`. + ## Discussions Gitter is only for small questions. To discuss a subject in detail, please send a link to your forum or blog in the Gitter chat. diff --git a/README.md b/README.md index 5f993035bd2..e26e3b2782f 100644 --- a/README.md +++ b/README.md @@ -8,17 +8,15 @@ [![npm][npm]][npm-url] [![node][node]][node-url] -[![deps][deps]][deps-url] -[![tests][tests]][tests-url] -[![builds][builds]][builds-url] +[![builds1][builds1]][builds1-url] [![builds2][builds2]][builds2-url] +[![dependency-review][dependency-review]][dependency-review-url] [![coverage][cover]][cover-url] -[![licenses][licenses]][licenses-url] [![PR's welcome][prs]][prs-url]
- - + + @@ -35,12 +33,18 @@ - - + + + + + + + +

webpack

- webpack is a module bundler. Its main purpose is to bundle JavaScript files for usage in a browser, yet it is also capable of transforming, bundling, or packaging just about any resource or asset. + Webpack is a module bundler. Its main purpose is to bundle JavaScript files for usage in a browser, yet it is also capable of transforming, bundling, or packaging just about any resource or asset.

@@ -77,7 +81,7 @@ yarn add webpack --dev

Introduction

-webpack is a bundler for modules. The main purpose is to bundle JavaScript +Webpack is a bundler for modules. The main purpose is to bundle JavaScript files for usage in a browser, yet it is also capable of transforming, bundling, or packaging just about any resource or asset. @@ -95,14 +99,14 @@ Check out webpack's quick [**Get Started**](https://webpack.js.org/guides/gettin ### Browser Compatibility -webpack supports all browsers that are [ES5-compliant](https://kangax.github.io/compat-table/es5/) (IE8 and below are not supported). -webpack also needs `Promise` for `import()` and `require.ensure()`. If you want to support older browsers, you will need to [load a polyfill](https://webpack.js.org/guides/shimming/) before using these expressions. +Webpack supports all browsers that are [ES5-compliant](https://kangax.github.io/compat-table/es5/) (IE8 and below are not supported). +Webpack also needs `Promise` for `import()` and `require.ensure()`. If you want to support older browsers, you will need to [load a polyfill](https://webpack.js.org/guides/shimming/) before using these expressions.

Concepts

### [Plugins](https://webpack.js.org/plugins/) -webpack has a [rich plugin +Webpack has a [rich plugin interface](https://webpack.js.org/plugins/). Most of the features within webpack itself use this plugin interface. This makes webpack very **flexible**. @@ -112,6 +116,7 @@ within webpack itself use this plugin interface. This makes webpack very | [mini-css-extract-plugin][mini-css] | ![mini-css-npm] | ![mini-css-size] | Extracts CSS into separate files. It creates a CSS file per JS file which contains CSS. | | [compression-webpack-plugin][compression] | ![compression-npm] | ![compression-size] | Prepares compressed versions of assets to serve them with Content-Encoding | | [html-webpack-plugin][html-plugin] | ![html-plugin-npm] | ![html-plugin-size] | Simplifies creation of HTML files (`index.html`) to serve your bundles | +| [pug-plugin][pug-plugin] | ![pug-plugin-npm] | ![pug-plugin-size] | Renders Pug files to HTML, extracts JS and CSS from sources specified directly in Pug. | [common-npm]: https://img.shields.io/npm/v/webpack.svg [mini-css]: https://github.com/webpack-contrib/mini-css-extract-plugin @@ -126,10 +131,13 @@ within webpack itself use this plugin interface. This makes webpack very [html-plugin]: https://github.com/jantimon/html-webpack-plugin [html-plugin-npm]: https://img.shields.io/npm/v/html-webpack-plugin.svg [html-plugin-size]: https://packagephobia.com/badge?p=html-webpack-plugin +[pug-plugin]: https://github.com/webdiscus/pug-plugin +[pug-plugin-npm]: https://img.shields.io/npm/v/pug-plugin.svg +[pug-plugin-size]: https://packagephobia.com/badge?p=pug-plugin ### [Loaders](https://webpack.js.org/loaders/) -webpack enables the use of loaders to preprocess files. This allows you to bundle +Webpack enables the use of loaders to preprocess files. This allows you to bundle **any static resource** way beyond JavaScript. You can easily [write your own loaders](https://webpack.js.org/api/loaders/) using Node.js. @@ -138,25 +146,13 @@ or are automatically applied via regex from your webpack configuration. #### Files -| Name | Status | Install Size | Description | -| :-----------------: | :---------: | :----------: | :---------------------------------------------------------------------------------------- | -| [raw-loader][raw] | ![raw-npm] | ![raw-size] | Loads raw content of a file (utf-8) | -| [val-loader][val] | ![val-npm] | ![val-size] | Executes code as module and considers exports as JS code | -| [url-loader][url] | ![url-npm] | ![url-size] | Works like the file loader, but can return a Data Url if the file is smaller than a limit | -| [file-loader][file] | ![file-npm] | ![file-size] | Emits the file into the output folder and returns the (relative) url | +| Name | Status | Install Size | Description | +| :---------------: | :--------: | :----------: | :------------------------------------------------------- | +| [val-loader][val] | ![val-npm] | ![val-size] | Executes code as module and considers exports as JS code | -[raw]: https://github.com/webpack-contrib/raw-loader -[raw-npm]: https://img.shields.io/npm/v/raw-loader.svg -[raw-size]: https://packagephobia.com/badge?p=raw-loader [val]: https://github.com/webpack-contrib/val-loader [val-npm]: https://img.shields.io/npm/v/val-loader.svg [val-size]: https://packagephobia.com/badge?p=val-loader -[url]: https://github.com/webpack-contrib/url-loader -[url-npm]: https://img.shields.io/npm/v/url-loader.svg -[url-size]: https://packagephobia.com/badge?p=url-loader -[file]: https://github.com/webpack-contrib/file-loader -[file-npm]: https://img.shields.io/npm/v/file-loader.svg -[file-size]: https://packagephobia.com/badge?p=file-loader #### JSON @@ -169,17 +165,14 @@ or are automatically applied via regex from your webpack configuration. #### Transpiling -| Name | Status | Install Size | Description | -| :--------------------------------------------------------------------------------------------------------------------------------------------------------: | :------------: | :-------------: | :--------------------------------------------------------------------------------------------------- | -| | ![babel-npm] | ![babel-size] | Loads ES2015+ code and transpiles to ES5 using Babel | -| | ![traceur-npm] | ![traceur-size] | Loads ES2015+ code and transpiles to ES5 using [Traceur](https://github.com/google/traceur-compiler) | -| | ![type-npm] | ![type-size] | Loads TypeScript like JavaScript | -| | ![coffee-npm] | ![coffee-size] | Loads CoffeeScript like JavaScript | +| Name | Status | Install Size | Description | +| :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-----------: | :------------: | :------------------------------------------------------------------------------------------------ | +| | ![babel-npm] | ![babel-size] | Loads ES2015+ code and transpiles to ES5 using Babel | +| | ![type-npm] | ![type-size] | Loads TypeScript like JavaScript | +| | ![coffee-npm] | ![coffee-size] | Loads CoffeeScript like JavaScript | [babel-npm]: https://img.shields.io/npm/v/babel-loader.svg [babel-size]: https://packagephobia.com/badge?p=babel-loader -[traceur-npm]: https://img.shields.io/npm/v/traceur-loader.svg -[traceur-size]: https://packagephobia.com/badge?p=traceur-loader [coffee-npm]: https://img.shields.io/npm/v/coffee-loader.svg [coffee-size]: https://packagephobia.com/badge?p=coffee-loader [type-npm]: https://img.shields.io/npm/v/ts-loader.svg @@ -187,18 +180,21 @@ or are automatically applied via regex from your webpack configuration. #### Templating -| Name | Status | Install Size | Description | -| :-------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-------------: | :--------------: | :-------------------------------------------------------------------------------------- | -| | ![html-npm] | ![html-size] | Exports HTML as string, requires references to static resources | -| | ![pug-npm] | ![pug-size] | Loads Pug templates and returns a function | -| | ![md-npm] | ![md-size] | Compiles Markdown to HTML | -| | ![posthtml-npm] | ![posthtml-size] | Loads and transforms a HTML file using [PostHTML](https://github.com/posthtml/posthtml) | -| | ![hbs-npm] | ![hbs-size] | Compiles Handlebars to HTML | +| Name | Status | Install Size | Description | +| :-----------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-------------: | :--------------: | :-------------------------------------------------------------------------------------- | +| | ![html-npm] | ![html-size] | Exports HTML as string, requires references to static resources | +| | ![pug-npm] | ![pug-size] | Loads Pug templates and returns a function | +| | ![pug3-npm] | ![pug3-size] | Compiles Pug to a function or HTML string, useful for use with Vue, React, Angular | +| | ![md-npm] | ![md-size] | Compiles Markdown to HTML | +| | ![posthtml-npm] | ![posthtml-size] | Loads and transforms a HTML file using [PostHTML](https://github.com/posthtml/posthtml) | +| | ![hbs-npm] | ![hbs-size] | Compiles Handlebars to HTML | [html-npm]: https://img.shields.io/npm/v/html-loader.svg [html-size]: https://packagephobia.com/badge?p=html-loader [pug-npm]: https://img.shields.io/npm/v/pug-loader.svg [pug-size]: https://packagephobia.com/badge?p=pug-loader +[pug3-npm]: https://img.shields.io/npm/v/@webdiscus/pug-loader.svg +[pug3-size]: https://packagephobia.com/badge?p=@webdiscus/pug-loader [jade-npm]: https://img.shields.io/npm/v/jade-loader.svg [jade-size]: https://packagephobia.com/badge?p=jade-loader [md-npm]: https://img.shields.io/npm/v/markdown-loader.svg @@ -240,6 +236,7 @@ or are automatically applied via regex from your webpack configuration. | | ![polymer-npm] | ![polymer-size] | Process HTML & CSS with preprocessor of choice and `require()` Web Components like first-class modules | | | ![angular-npm] | ![angular-size] | Loads and compiles Angular 2 Components | | | ![riot-npm] | ![riot-size] | Riot official webpack loader | +| | ![svelte-npm] | ![svelte-size] | Official Svelte loader | [vue-npm]: https://img.shields.io/npm/v/vue-loader.svg [vue-size]: https://packagephobia.com/badge?p=vue-loader @@ -249,26 +246,28 @@ or are automatically applied via regex from your webpack configuration. [angular-size]: https://packagephobia.com/badge?p=angular2-template-loader [riot-npm]: https://img.shields.io/npm/v/riot-tag-loader.svg [riot-size]: https://packagephobia.com/badge?p=riot-tag-loader +[svelte-npm]: https://img.shields.io/npm/v/svelte-loader.svg +[svelte-size]: https://packagephobia.com/badge?p=svelte-loader ### Performance -webpack uses async I/O and has multiple caching levels. This makes webpack fast +Webpack uses async I/O and has multiple caching levels. This makes webpack fast and incredibly **fast** on incremental compilations. ### Module Formats -webpack supports ES2015+, CommonJS and AMD modules **out of the box**. It performs clever static +Webpack supports ES2015+, CommonJS and AMD modules **out of the box**. It performs clever static analysis on the AST of your code. It even has an evaluation engine to evaluate simple expressions. This allows you to **support most existing libraries** out of the box. ### [Code Splitting](https://webpack.js.org/guides/code-splitting/) -webpack allows you to split your codebase into multiple chunks. Chunks are +Webpack allows you to split your codebase into multiple chunks. Chunks are loaded asynchronously at runtime. This reduces the initial loading time. ### [Optimizations](https://webpack.js.org/guides/production-build/) -webpack can do many optimizations to **reduce the output size of your +Webpack can do many optimizations to **reduce the output size of your JavaScript** by deduplicating frequently used modules, minifying, and giving you full control of what is loaded initially and what is loaded at runtime through code splitting. It can also make your code chunks **cache @@ -290,7 +289,7 @@ Contributions go far beyond pull requests and commits. Although we love giving y - [Blogging, speaking about, or creating tutorials](https://github.com/webpack-contrib/awesome-webpack) about one of webpack's many features. - Helping others in our webpack [gitter channel](https://gitter.im/webpack/webpack). -To get started have a look at our [documentation on contributing](https://github.com/webpack/webpack/blob/master/CONTRIBUTING.md). +To get started have a look at our [documentation on contributing](https://github.com/webpack/webpack/blob/main/CONTRIBUTING.md). If you are worried or don't know where to start, you can **always** reach out to [Sean Larkin (@TheLarkInn) on Twitter](https://twitter.com/thelarkinn) or simply submit an issue and a maintainer can help give you guidance! @@ -317,7 +316,7 @@ a question to [StackOverflow with the webpack tag](https://stackoverflow.com/tag If you are twitter savvy you can tweet #webpack with your question and someone should be able to reach out and help also. -If you have discovered a ๐Ÿœ or have a feature suggestion, feel free to create an issue on Github. +If you have discovered a ๐Ÿœ or have a feature suggestion, feel free to create an issue on GitHub. ### License @@ -407,7 +406,7 @@ src="https://static.monei.net/monei-logo.svg" height="30" alt="MONEI">

Gold Sponsors

-[Become a gold sponsor](https://opencollective.com/webpack#sponsor) and get your logo on our README on Github with a link to your site. +[Become a gold sponsor](https://opencollective.com/webpack#sponsor) and get your logo on our README on GitHub with a link to your site.
@@ -446,7 +445,7 @@ src="https://static.monei.net/monei-logo.svg" height="30" alt="MONEI">

Silver Sponsors

-[Become a silver sponsor](https://opencollective.com/webpack#sponsor) and get your logo on our README on Github with a link to your site. +[Become a silver sponsor](https://opencollective.com/webpack#sponsor) and get your logo on our README on GitHub with a link to your site.
@@ -485,7 +484,7 @@ src="https://static.monei.net/monei-logo.svg" height="30" alt="MONEI">

Bronze Sponsors

-[Become a bronze sponsor](https://opencollective.com/webpack#sponsor) and get your logo on our README on Github with a link to your site. +[Become a bronze sponsor](https://opencollective.com/webpack#sponsor) and get your logo on our README on GitHub with a link to your site.
@@ -595,7 +594,7 @@ src="https://static.monei.net/monei-logo.svg" height="30" alt="MONEI">

Backers

-[Become a backer](https://opencollective.com/webpack#backer) and get your image on our README on Github with a link to your site. +[Become a backer](https://opencollective.com/webpack#backer) and get your image on our README on GitHub with a link to your site. @@ -704,7 +703,7 @@ src="https://static.monei.net/monei-logo.svg" height="30" alt="MONEI"> - [@google](https://github.com/google) for [Google Web Toolkit (GWT)](http://www.gwtproject.org/), which aims to compile Java to JavaScript. It features a similar [Code Splitting](http://www.gwtproject.org/doc/latest/DevGuideCodeSplitting.html) as webpack. - [@medikoo](https://github.com/medikoo) for [modules-webmake](https://github.com/medikoo/modules-webmake), which is a similar project. webpack was born because I wanted Code Splitting for modules-webmake. Interestingly the [Code Splitting issue is still open](https://github.com/medikoo/modules-webmake/issues/7) (thanks also to @Phoscur for the discussion). -- [@substack](https://github.com/substack) for [browserify](http://browserify.org/), which is a similar project and source for many ideas. +- [@substack](https://github.com/substack) for [browserify](https://browserify.org/), which is a similar project and source for many ideas. - [@jrburke](https://github.com/jrburke) for [require.js](https://requirejs.org/), which is a similar project and source for many ideas. - [@defunctzombie](https://github.com/defunctzombie) for the [browser-field spec](https://github.com/defunctzombie/package-browser-field-spec), which makes modules available for node.js, browserify and webpack. - Every early webpack user, which contributed to webpack by writing issues or PRs. You influenced the direction... @@ -716,17 +715,13 @@ src="https://static.monei.net/monei-logo.svg" height="30" alt="MONEI"> [npm-url]: https://npmjs.com/package/webpack [node]: https://img.shields.io/node/v/webpack.svg [node-url]: https://nodejs.org -[deps]: https://img.shields.io/david/webpack/webpack.svg -[deps-url]: https://david-dm.org/webpack/webpack -[tests]: https://img.shields.io/travis/webpack/webpack/master.svg -[tests-url]: https://travis-ci.org/webpack/webpack [prs]: https://img.shields.io/badge/PRs-welcome-brightgreen.svg [prs-url]: https://webpack.js.org/contribute/ -[builds-url]: https://ci.appveyor.com/project/sokra/webpack/branch/master -[builds]: https://ci.appveyor.com/api/projects/status/github/webpack/webpack?svg=true -[builds2]: https://dev.azure.com/webpack/webpack/_apis/build/status/webpack.webpack -[builds2-url]: https://dev.azure.com/webpack/webpack/_build/latest?definitionId=3 -[licenses-url]: https://app.fossa.io/projects/git%2Bhttps%3A%2F%2Fgithub.com%2Fwebpack%2Fwebpack?ref=badge_shield -[licenses]: https://app.fossa.io/api/projects/git%2Bhttps%3A%2F%2Fgithub.com%2Fwebpack%2Fwebpack.svg?type=shield -[cover]: https://img.shields.io/coveralls/webpack/webpack.svg -[cover-url]: https://coveralls.io/r/webpack/webpack/ +[builds1]: https://github.com/webpack/webpack/actions/workflows/test.yml/badge.svg +[builds1-url]: https://github.com/webpack/webpack/actions/workflows/test.yml +[builds2]: https://dev.azure.com/webpack/webpack/_apis/build/status%2Fwebpack.webpack?branchName=main +[builds2-url]: https://dev.azure.com/webpack/webpack/_build/latest?definitionId=3&branchName=main +[dependency-review-url]: https://github.com/webpack/webpack/actions/workflows/dependency-review.yml +[dependency-review]: https://github.com/webpack/webpack/actions/workflows/dependency-review.yml/badge.svg +[cover]: https://codecov.io/gh/webpack/webpack/branch/master/graph/badge.svg?token=mDP3mQJNnn +[cover-url]: https://codecov.io/gh/webpack/webpack diff --git a/appveyor.yml b/appveyor.yml deleted file mode 100644 index dc77d985d68..00000000000 --- a/appveyor.yml +++ /dev/null @@ -1,37 +0,0 @@ -# appveyor file -# http://www.appveyor.com/docs/appveyor-yml - -branches: - only: - - webpack-4 - - master - - next - - dev-1 - -init: - - git config --global core.autocrlf input - -cache: - - "..\\.yarn-cache" - - ".jest-cache" - -install: - - ps: Install-Product node 14 x64 - - yarn --frozen-lockfile --preferred-cache-folder ..\\.yarn-cache - - yarn link --frozen-lockfile --preferred-cache-folder ..\\.yarn-cache || yarn link --frozen-lockfile --preferred-cache-folder ..\\.yarn-cache - - yarn link webpack --frozen-lockfile --preferred-cache-folder ..\\.yarn-cache - -build: off - -matrix: - fast_finish: true - -test_script: - - node --version - - yarn --version - - cmd: set JEST=--maxWorkers=2 --cacheDirectory .jest-cache - - cmd: yarn appveyor:integration - - cmd: yarn istanbul report --report lcovonly - - cmd: yarn unlink webpack - - cmd: yarn global add codecov && codecov -F integration --disable=gcov - - cmd: del /F /Q .jest-cache\\haste-map* .jest-cache\\perf-cache* 2> null || Ver > null diff --git a/assembly/hash/md4.asm.ts b/assembly/hash/md4.asm.ts new file mode 100644 index 00000000000..3388ecc57e9 --- /dev/null +++ b/assembly/hash/md4.asm.ts @@ -0,0 +1,177 @@ +/* + ** ******************************************************************** + ** md4.c -- Implementation of MD4 Message Digest Algorithm ** + ** Updated: 2/16/90 by Ronald L. Rivest ** + ** (C) 1990 RSA Data Security, Inc. ** + ** ******************************************************************** + */ + +// Ported to assemblyscript by Tobias Koppers + +let totalLength: u32; +let A: u32; +let B: u32; +let C: u32; +let D: u32; + +function F(x: u32, y: u32, z: u32): u32 { + return z ^ (x & (y ^ z)); +} +function G(x: u32, y: u32, z: u32): u32 { + return (x & (y | z)) | (y & z); +} +function H(x: u32, y: u32, z: u32): u32 { + return x ^ y ^ z; +} + +function roundF(a: u32, b: u32, c: u32, d: u32, i: u32, s: u32): u32 { + return rotl(a + F(b, c, d) + load(i), s); +} +function roundG(a: u32, b: u32, c: u32, d: u32, i: u32, s: u32): u32 { + return rotl(a + G(b, c, d) + load(i) + 0x5a827999, s); +} +function roundH(a: u32, b: u32, c: u32, d: u32, i: u32, s: u32): u32 { + return rotl(a + H(b, c, d) + load(i) + 0x6ed9eba1, s); +} + +export function init(): void { + A = 0x67452301; + B = 0xefcdab89; + C = 0x98badcfe; + D = 0x10325476; + totalLength = 0; +} + +function body(size: u32): void { + let _A = A; + let _B = B; + let _C = C; + let _D = D; + + for (let i: u32 = 0; i < size; i += 64) { + let a = _A; + let b = _B; + let c = _C; + let d = _D; + + // Round F + + a = roundF(a, b, c, d, i + 4 * 0, 3); + d = roundF(d, a, b, c, i + 4 * 1, 7); + c = roundF(c, d, a, b, i + 4 * 2, 11); + b = roundF(b, c, d, a, i + 4 * 3, 19); + + a = roundF(a, b, c, d, i + 4 * 4, 3); + d = roundF(d, a, b, c, i + 4 * 5, 7); + c = roundF(c, d, a, b, i + 4 * 6, 11); + b = roundF(b, c, d, a, i + 4 * 7, 19); + + a = roundF(a, b, c, d, i + 4 * 8, 3); + d = roundF(d, a, b, c, i + 4 * 9, 7); + c = roundF(c, d, a, b, i + 4 * 10, 11); + b = roundF(b, c, d, a, i + 4 * 11, 19); + + a = roundF(a, b, c, d, i + 4 * 12, 3); + d = roundF(d, a, b, c, i + 4 * 13, 7); + c = roundF(c, d, a, b, i + 4 * 14, 11); + b = roundF(b, c, d, a, i + 4 * 15, 19); + + // Round G + + a = roundG(a, b, c, d, i + 4 * 0, 3); + d = roundG(d, a, b, c, i + 4 * 4, 5); + c = roundG(c, d, a, b, i + 4 * 8, 9); + b = roundG(b, c, d, a, i + 4 * 12, 13); + + a = roundG(a, b, c, d, i + 4 * 1, 3); + d = roundG(d, a, b, c, i + 4 * 5, 5); + c = roundG(c, d, a, b, i + 4 * 9, 9); + b = roundG(b, c, d, a, i + 4 * 13, 13); + + a = roundG(a, b, c, d, i + 4 * 2, 3); + d = roundG(d, a, b, c, i + 4 * 6, 5); + c = roundG(c, d, a, b, i + 4 * 10, 9); + b = roundG(b, c, d, a, i + 4 * 14, 13); + + a = roundG(a, b, c, d, i + 4 * 3, 3); + d = roundG(d, a, b, c, i + 4 * 7, 5); + c = roundG(c, d, a, b, i + 4 * 11, 9); + b = roundG(b, c, d, a, i + 4 * 15, 13); + + // Round H + + a = roundH(a, b, c, d, i + 4 * 0, 3); + d = roundH(d, a, b, c, i + 4 * 8, 9); + c = roundH(c, d, a, b, i + 4 * 4, 11); + b = roundH(b, c, d, a, i + 4 * 12, 15); + + a = roundH(a, b, c, d, i + 4 * 2, 3); + d = roundH(d, a, b, c, i + 4 * 10, 9); + c = roundH(c, d, a, b, i + 4 * 6, 11); + b = roundH(b, c, d, a, i + 4 * 14, 15); + + a = roundH(a, b, c, d, i + 4 * 1, 3); + d = roundH(d, a, b, c, i + 4 * 9, 9); + c = roundH(c, d, a, b, i + 4 * 5, 11); + b = roundH(b, c, d, a, i + 4 * 13, 15); + + a = roundH(a, b, c, d, i + 4 * 3, 3); + d = roundH(d, a, b, c, i + 4 * 11, 9); + c = roundH(c, d, a, b, i + 4 * 7, 11); + b = roundH(b, c, d, a, i + 4 * 15, 15); + + _A += a; + _B += b; + _C += c; + _D += d; + } + + A = _A; + B = _B; + C = _C; + D = _D; +} + +export function update(length: u32): void { + body(length); + totalLength += length; +} + +export function final(length: u32): void { + const bits: u64 = u64(totalLength + length) << 3; + const finalLength: u32 = (length + 9 + 63) & ~63; + const bitsPosition = finalLength - 8; + + // end + store(length++, 0x80); + + // padding + for (; length & 7 && length < finalLength; length++) store(length, 0); + for (; length < finalLength; length += 8) store(length, 0); + + // bits + store(bitsPosition, bits); + + body(finalLength); + + store(0, u32ToHex(A)); + store(8, u32ToHex(B)); + store(16, u32ToHex(C)); + store(24, u32ToHex(D)); +} + +function u32ToHex(x: u64): u64 { + // from https://johnnylee-sde.github.io/Fast-unsigned-integer-to-hex-string/ + + x = ((x & 0xffff0000) << 16) | (x & 0xffff); + x = ((x & 0x0000ff000000ff00) << 8) | (x & 0x000000ff000000ff); + x = ((x & 0x00f000f000f000f0) >> 4) | ((x & 0x000f000f000f000f) << 8); + + const mask = ((x + 0x0606060606060606) >> 4) & 0x0101010101010101; + + x |= 0x3030303030303030; + + x += 0x27 * mask; + + return x; +} diff --git a/assembly/hash/xxhash64.asm.ts b/assembly/hash/xxhash64.asm.ts new file mode 100644 index 00000000000..7f6b9df43f9 --- /dev/null +++ b/assembly/hash/xxhash64.asm.ts @@ -0,0 +1,129 @@ +// ////////////////////////////////////////////////////////// +// xxhash64.h +// Copyright (c) 2016 Stephan Brumme. All rights reserved. +// see http://create.stephan-brumme.com/disclaimer.html +// +// XXHash (64 bit), based on Yann Collet's descriptions, see +// http://cyan4973.github.io/xxHash/ +// +// Modified for hash-wasm by Dani Birรณ +// +// Ported to assemblyscript by Tobias Koppers +// Modifications: +// - seed is always 0 +// - update is only called with a multiple of 32 +// - final takes the remaining 0 - 31 bytes +// + +const Prime1: u64 = 11400714785074694791; +const Prime2: u64 = 14029467366897019727; +const Prime3: u64 = 1609587929392839161; +const Prime4: u64 = 9650029242287828579; +const Prime5: u64 = 2870177450012600261; + +let state0: u64; +let state1: u64; +let state2: u64; +let state3: u64; +let totalLength: u64; + +function processSingle(previous: u64, input: u64): u64 { + return rotl(previous + input * Prime2, 31) * Prime1; +} + +export function init(): void { + state0 = Prime1 + Prime2; + state1 = Prime2; + state2 = 0; + state3 = 0 - Prime1; + totalLength = 0; +} + +export function update(length: u32): void { + if (length == 0) return; + + totalLength += length; + + let dataPtr: u32 = 0; + + let s0 = state0; + let s1 = state1; + let s2 = state2; + let s3 = state3; + + do { + s0 = processSingle(s0, load(dataPtr)); + s1 = processSingle(s1, load(dataPtr + 8)); + s2 = processSingle(s2, load(dataPtr + 16)); + s3 = processSingle(s3, load(dataPtr + 24)); + dataPtr += 32; + } while (dataPtr < length); + + state0 = s0; + state1 = s1; + state2 = s2; + state3 = s3; +} + +export function final(length: u32): void { + // fold 256 bit state into one single 64 bit value + let result: u64; + if (totalLength > 0) { + result = + rotl(state0, 1) + rotl(state1, 7) + rotl(state2, 12) + rotl(state3, 18); + result = (result ^ processSingle(0, state0)) * Prime1 + Prime4; + result = (result ^ processSingle(0, state1)) * Prime1 + Prime4; + result = (result ^ processSingle(0, state2)) * Prime1 + Prime4; + result = (result ^ processSingle(0, state3)) * Prime1 + Prime4; + } else { + result = Prime5; + } + + result += totalLength + length; + + let dataPtr: u32 = 0; + + // at least 8 bytes left ? => eat 8 bytes per step + for (; dataPtr + 8 <= length; dataPtr += 8) { + result = + rotl(result ^ processSingle(0, load(dataPtr)), 27) * Prime1 + Prime4; + } + + // 4 bytes left ? => eat those + if (dataPtr + 4 <= length) { + result = rotl(result ^ (load(dataPtr) * Prime1), 23) * Prime2 + Prime3; + dataPtr += 4; + } + + // take care of remaining 0..3 bytes, eat 1 byte per step + while (dataPtr !== length) { + result = rotl(result ^ (load(dataPtr) * Prime5), 11) * Prime1; + dataPtr++; + } + + // mix bits + result ^= result >> 33; + result *= Prime2; + result ^= result >> 29; + result *= Prime3; + result ^= result >> 32; + + store(0, u32ToHex(result >> 32)); + store(8, u32ToHex(result & 0xffffffff)); +} + +function u32ToHex(x: u64): u64 { + // from https://johnnylee-sde.github.io/Fast-unsigned-integer-to-hex-string/ + + x = ((x & 0xffff) << 32) | ((x & 0xffff0000) >> 16); + x = ((x & 0x0000ff000000ff00) >> 8) | ((x & 0x000000ff000000ff) << 16); + x = ((x & 0x00f000f000f000f0) >> 4) | ((x & 0x000f000f000f000f) << 8); + + const mask = ((x + 0x0606060606060606) >> 4) & 0x0101010101010101; + + x |= 0x3030303030303030; + + x += 0x27 * mask; + + return x; +} diff --git a/assembly/tsconfig.json b/assembly/tsconfig.json new file mode 100644 index 00000000000..ec198544982 --- /dev/null +++ b/assembly/tsconfig.json @@ -0,0 +1,4 @@ +{ + "extends": "assemblyscript/std/assembly.json", + "include": ["./**/*.asm.ts"] +} diff --git a/azure-pipelines.yml b/azure-pipelines.yml index ec5901b8dd5..5c8fd1cfe7b 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -6,38 +6,34 @@ jobs: pool: vmImage: ubuntu-latest steps: - - task: NodeTool@0 + - task: UseNode@1 inputs: - versionSpec: "^14.0.0" + version: "18.x" displayName: "Install Node.js" - script: | - curl -o- -L https://yarnpkg.com/install.sh | bash - displayName: "Install Yarn" - - script: | - set -e - export PATH="$HOME/.yarn/bin:$HOME/.config/yarn/global/node_modules/.bin:$PATH" node -v yarn -v displayName: "Print versions" - - task: CacheBeta@1 + - task: Cache@2 inputs: - key: yarn | $(Agent.OS) | yarn.lock + key: 'yarn | "$(Agent.OS)" | yarn.lock' + restoreKeys: | + yarn | "$(Agent.OS)" + yarn path: $(YARN_CACHE_FOLDER) displayName: "Cache Yarn packages" - script: | - set -e - export PATH="$HOME/.yarn/bin:$HOME/.config/yarn/global/node_modules/.bin:$PATH" yarn --frozen-lockfile yarn link --frozen-lockfile || true yarn link webpack --frozen-lockfile displayName: "Install dependencies" - script: | - set -e - export PATH="$HOME/.yarn/bin:$HOME/.config/yarn/global/node_modules/.bin:$PATH" export JEST_JUNIT_OUTPUT_NAME=basic-junit.xml - yarn test:basic --ci --reporters=jest-junit + yarn test:basic --ci --reporters=default --reporters=jest-junit export JEST_JUNIT_OUTPUT_NAME=unit-junit.xml - yarn test:unit --ci --reporters=jest-junit + yarn test:unit --ci --reporters=default --reporters=jest-junit + env: + CI: "true" displayName: "Run basic tests" - task: PublishTestResults@2 inputs: @@ -45,6 +41,9 @@ jobs: testResultsFiles: "**/basic-junit.xml" condition: succeededOrFailed() displayName: "Publish basic test results" + - script: | + node -e "const fs = require('fs');let data = fs.readFileSync('unit-junit.xml', 'utf-8');fs.writeFileSync('unit-junit.xml', data.replace(/\0/g, 'NULL_CHARACTER'))" + displayName: "Fix junit output" - task: PublishTestResults@2 inputs: testRunTitle: "unit" @@ -56,47 +55,32 @@ jobs: pool: vmImage: ubuntu-latest steps: - - task: NodeTool@0 + - task: UseNode@1 inputs: - versionSpec: "^14.0.0" + version: "18.x" displayName: "Install Node.js" - script: | - curl -o- -L https://yarnpkg.com/install.sh | bash - displayName: "Install Yarn" - - script: | - set -e - export PATH="$HOME/.yarn/bin:$HOME/.config/yarn/global/node_modules/.bin:$PATH" node -v yarn -v displayName: "Print versions" - - task: CacheBeta@1 + - task: Cache@2 inputs: - key: yarn | $(Agent.OS) | yarn.lock + key: 'yarn | "$(Agent.OS)" | yarn.lock' + restoreKeys: | + yarn | "$(Agent.OS)" + yarn path: $(YARN_CACHE_FOLDER) displayName: "Cache Yarn packages" - script: | - set -e - export PATH="$HOME/.yarn/bin:$HOME/.config/yarn/global/node_modules/.bin:$PATH" yarn --frozen-lockfile yarn link --frozen-lockfile || true yarn link webpack --frozen-lockfile displayName: "Install dependencies" - script: | - set -e - export PATH="$HOME/.yarn/bin:$HOME/.config/yarn/global/node_modules/.bin:$PATH" - yarn -s run code-lint --format junit > junit.xml - yarn special-lint - yarn type-lint - yarn typings-lint - yarn pretty-lint - yarn spellcheck + yarn lint + env: + CI: "true" displayName: "Run linting" - - task: PublishTestResults@2 - inputs: - testRunTitle: "lint" - testResultsFiles: "**/junit.xml" - condition: succeededOrFailed() - displayName: "Publish lint results" - job: Windows dependsOn: @@ -105,40 +89,63 @@ jobs: pool: vmImage: windows-latest strategy: - maxParallel: 3 + maxParallel: 6 matrix: - node-10: - node_version: ^10.13.0 - node-12: - node_version: ^12.4.0 - node-14: - node_version: ^14.0.0 + node-10-a: + node_version: 10.x + part: a + node-10-b: + node_version: 10.x + part: b + node-18-a: + node_version: 18.x + part: a + node-18-b: + node_version: 18.x + part: b + node-20-a: + node_version: 20.x + part: a + node-20-b: + node_version: 20.x + part: b steps: - - task: NodeTool@0 + - task: UseNode@1 inputs: - versionSpec: $(node_version) + version: $(node_version) displayName: "Install Node.js $(node_version)" - - script: | - npm install --global yarn - displayName: "Install Yarn" - script: | node -v yarn -v displayName: "Print versions" - - task: CacheBeta@1 + - task: Cache@2 inputs: - key: yarn | $(Agent.OS) | yarn.lock + key: 'yarn | "$(Agent.OS)" | yarn.lock' + restoreKeys: | + yarn | "$(Agent.OS)" + yarn path: $(YARN_CACHE_FOLDER) displayName: "Cache Yarn packages" + # Install old `jest` version and ignore platform problem for legacy node versions + - script: | + node -e "const fs = require('fs');fs.createReadStream('yarn.lock').pipe(fs.createWriteStream('.yarn.lock'));" + yarn upgrade jest@^27.5.0 jest-circus@^27.5.0 jest-cli@^27.5.0 jest-diff@^27.5.0 jest-environment-node@^27.5.0 jest-junit@^13.0.0 @types/jest@^27.4.0 pretty-format@^27.0.2 husky@^8.0.3 lint-staged@^13.2.1 cspell@^6.31.1 open-cli@^7.2.0 coffee-loader@^1.0.0 babel-loader@^8.1.0 style-loader@^2.0.0 css-loader@^5.0.1 less-loader@^8.1.1 mini-css-extract-plugin@^1.6.1 --ignore-engines + yarn --frozen-lockfile --ignore-engines + displayName: "Install dependencies (old node.js version)" + condition: eq(variables['node_version'], '10.x') - script: yarn --frozen-lockfile displayName: "Install dependencies" + condition: not(eq(variables['node_version'], '10.x')) - script: yarn link --frozen-lockfile || true displayName: "Link webpack" continueOnError: true - script: yarn link webpack --frozen-lockfile displayName: "Link webpack into node_modules" - script: | - yarn cover:integration --ci --maxWorkers=2 --reporters=jest-junit + yarn cover:integration:$(part) --ci --maxWorkers=2 --reporters=default --reporters=jest-junit || yarn cover:integration:$(part) --ci --maxWorkers=2 --reporters=default --reporters=jest-junit -f + yarn cover:merge + env: + CI: "true" displayName: "Run tests with coverage" - task: PublishTestResults@2 inputs: @@ -146,6 +153,10 @@ jobs: testResultsFiles: "**/junit.xml" condition: succeededOrFailed() displayName: "Publish test results" + - script: node -e "const fs = require('fs');fs.createReadStream('.yarn.lock').pipe(fs.createWriteStream('yarn.lock'));" + displayName: "Restore original yarn.lock" + condition: eq(variables['node_version'], '10.x') + - job: Linux dependsOn: - basic @@ -153,46 +164,66 @@ jobs: pool: vmImage: ubuntu-latest strategy: - maxParallel: 4 + maxParallel: 6 matrix: - node-10: - node_version: ^10.13.0 - node-12: - node_version: ^12.4.0 - node-14: - node_version: ^14.0.0 - node-15: - node_version: ^15.0.0 + node-10-a: + node_version: 10.x + part: a + node-10-b: + node_version: 10.x + part: b + node-18-a: + node_version: 18.x + part: a + node-18-b: + node_version: 18.x + part: b + node-20-a: + node_version: 20.x + part: a + node-20-b: + node_version: 20.x + part: b steps: - - task: NodeTool@0 + - task: UseNode@1 inputs: - versionSpec: $(node_version) + version: $(node_version) displayName: "Install Node.js $(node_version)" - script: | - curl -o- -L https://yarnpkg.com/install.sh | bash - displayName: "Install Yarn" - - script: | - set -e - export PATH="$HOME/.yarn/bin:$HOME/.config/yarn/global/node_modules/.bin:$PATH" node -v yarn -v displayName: "Print versions" - - task: CacheBeta@1 + - task: Cache@2 inputs: - key: yarn | $(Agent.OS) | yarn.lock + key: 'yarn | "$(Agent.OS)" | yarn.lock' + restoreKeys: | + yarn | "$(Agent.OS)" + yarn path: $(YARN_CACHE_FOLDER) displayName: "Cache Yarn packages" + # Doesn't work due to modified yarn.lock + condition: not(eq(variables['node_version'], '10.x')) + # Install old `jest` version and ignore platform problem for legacy node versions + - script: | + node -e "const fs = require('fs');fs.createReadStream('yarn.lock').pipe(fs.createWriteStream('.yarn.lock'));" + yarn upgrade jest@^27.5.0 jest-circus@^27.5.0 jest-cli@^27.5.0 jest-diff@^27.5.0 jest-environment-node@^27.5.0 jest-junit@^13.0.0 @types/jest@^27.4.0 pretty-format@^27.0.2 husky@^8.0.3 lint-staged@^13.2.1 cspell@^6.31.1 open-cli@^7.2.0 coffee-loader@^1.0.0 babel-loader@^8.1.0 style-loader@^2.0.0 css-loader@^5.0.1 less-loader@^8.1.1 mini-css-extract-plugin@^1.6.1 --ignore-engines + yarn --frozen-lockfile --ignore-engines + displayName: "Install dependencies (old node.js version)" + condition: eq(variables['node_version'], '10.x') - script: | - set -e - export PATH="$HOME/.yarn/bin:$HOME/.config/yarn/global/node_modules/.bin:$PATH" yarn --frozen-lockfile - yarn link --frozen-lockfile || true - yarn link webpack --frozen-lockfile displayName: "Install dependencies" + condition: not(eq(variables['node_version'], '10.x')) + - script: yarn link --frozen-lockfile || true + displayName: "Link webpack" + continueOnError: true + - script: yarn link webpack --frozen-lockfile + displayName: "Link webpack into node_modules" - script: | - set -e - export PATH="$HOME/.yarn/bin:$HOME/.config/yarn/global/node_modules/.bin:$PATH" - yarn cover:integration --ci --maxWorkers=2 --reporters=jest-junit + yarn cover:integration:$(part) --ci --maxWorkers=2 --reporters=default --reporters=jest-junit || yarn cover:integration:$(part) --ci --maxWorkers=2 --reporters=default --reporters=jest-junit -f + yarn cover:merge + env: + CI: "true" displayName: "Run tests with coverage" - task: PublishTestResults@2 inputs: @@ -200,6 +231,9 @@ jobs: testResultsFiles: "**/junit.xml" condition: succeededOrFailed() displayName: "Publish test results" + - script: node -e "const fs = require('fs');fs.createReadStream('.yarn.lock').pipe(fs.createWriteStream('yarn.lock'));" + displayName: "Restore original yarn.lock" + condition: eq(variables['node_version'], '10.x') - job: macOS dependsOn: @@ -208,42 +242,65 @@ jobs: pool: vmImage: macOS-latest strategy: - maxParallel: 2 + maxParallel: 6 matrix: - node-12: - node_version: ^12.4.0 - node-14: - node_version: ^14.0.0 + node-10-a: + node_version: 10.x + part: a + node-10-b: + node_version: 10.x + part: b + node-18-a: + node_version: 18.x + part: a + node-18-b: + node_version: 18.x + part: b + node-20-a: + node_version: 20.x + part: a + node-20-b: + node_version: 20.x + part: b steps: - - task: NodeTool@0 + - task: UseNode@1 inputs: - versionSpec: $(node_version) + version: $(node_version) displayName: "Install Node.js $(node_version)" - script: | - curl -o- -L https://yarnpkg.com/install.sh | bash - displayName: "Install Yarn" - - script: | - set -e - export PATH="$HOME/.yarn/bin:$HOME/.config/yarn/global/node_modules/.bin:$PATH" node -v yarn -v displayName: "Print versions" - - task: CacheBeta@1 + - task: Cache@2 inputs: - key: yarn | $(Agent.OS) | yarn.lock + key: 'yarn | "$(Agent.OS)" | yarn.lock' + restoreKeys: | + yarn | "$(Agent.OS)" + yarn path: $(YARN_CACHE_FOLDER) displayName: "Cache Yarn packages" + # Doesn't work due to modified yarn.lock + condition: not(eq(variables['node_version'], '10.x')) + - script: | + node -e "const fs = require('fs');fs.createReadStream('yarn.lock').pipe(fs.createWriteStream('.yarn.lock'));" + yarn upgrade jest@^27.5.0 jest-circus@^27.5.0 jest-cli@^27.5.0 jest-diff@^27.5.0 jest-environment-node@^27.5.0 jest-junit@^13.0.0 @types/jest@^27.4.0 pretty-format@^27.0.2 husky@^8.0.3 lint-staged@^13.2.1 cspell@^6.31.1 open-cli@^7.2.0 coffee-loader@^1.0.0 babel-loader@^8.1.0 style-loader@^2.0.0 css-loader@^5.0.1 less-loader@^8.1.1 mini-css-extract-plugin@^1.6.1 --ignore-engines + yarn --frozen-lockfile --ignore-engines + displayName: "Install dependencies (old node.js version)" + condition: eq(variables['node_version'], '10.x') - script: | - set -e - export PATH="$HOME/.yarn/bin:$HOME/.config/yarn/global/node_modules/.bin:$PATH" yarn --frozen-lockfile - yarn link --frozen-lockfile || true - yarn link webpack --frozen-lockfile displayName: "Install dependencies" + condition: not(eq(variables['node_version'], '10.x')) + - script: yarn link --frozen-lockfile || true + displayName: "Link webpack" + continueOnError: true + - script: yarn link webpack --frozen-lockfile + displayName: "Link webpack into node_modules" - script: | - set -e - export PATH="$HOME/.yarn/bin:$HOME/.config/yarn/global/node_modules/.bin:$PATH" - yarn cover:integration --ci --reporters=jest-junit + yarn cover:integration:$(part) --ci --reporters=default --reporters=jest-junit || yarn cover:integration:$(part) --ci --reporters=default --reporters=jest-junit -f + yarn cover:merge + env: + CI: "true" displayName: "Run tests with coverage" - task: PublishTestResults@2 inputs: @@ -251,3 +308,6 @@ jobs: testResultsFiles: "**/junit.xml" condition: succeededOrFailed() displayName: "Publish test results" + - script: node -e "const fs = require('fs');fs.createReadStream('.yarn.lock').pipe(fs.createWriteStream('yarn.lock'));" + displayName: "Restore original yarn.lock" + condition: eq(variables['node_version'], '10.x') diff --git a/benchmark/md4-cache.js b/benchmark/md4-cache.js new file mode 100644 index 00000000000..00d02519df5 --- /dev/null +++ b/benchmark/md4-cache.js @@ -0,0 +1,39 @@ +const createHash = require("../lib/util/createHash"); + +const compare = require("./micro-compare"); + +const size = 50; + +const strings = []; +for (let count = 1; ; count *= 10) { + while (strings.length < count) { + const s = require("crypto").randomBytes(size).toString("hex"); + strings.push(s); + const hash = createHash("native-md4"); + hash.update(s); + hash.update(s); + hash.digest("hex"); + } + let i = 0; + console.log( + `${count} different 200 char strings: ` + + compare( + "native md4", + () => { + const hash = createHash("native-md4"); + const s = strings[(i = (i + 1) % strings.length)]; + hash.update(s); + hash.update(s); + return hash.digest("hex"); + }, + "wasm md4", + () => { + const hash = createHash("md4"); + const s = strings[(i = (i + 1) % strings.length)]; + hash.update(s); + hash.update(s); + return hash.digest("hex"); + } + ) + ); +} diff --git a/benchmark/md4.js b/benchmark/md4.js new file mode 100644 index 00000000000..3b50d659c75 --- /dev/null +++ b/benchmark/md4.js @@ -0,0 +1,49 @@ +const createHash = require("../lib/util/createHash"); + +const compare = require("./micro-compare"); + +for (const size of [ + 1, 10, 20, 40, 60, 80, 100, 200, 400, 1000, 1001, 5000, 8183, 8184, 8185, + 10000, 20000, 32768, 32769, 50000, 100000, 200000 +]) { + const longString = require("crypto").randomBytes(size).toString("hex"); + const buffer = require("crypto").randomBytes(size * 2); + console.log( + `string ${longString.length} chars: ` + + compare( + "native md4", + () => { + const hash = createHash("native-md4"); + hash.update(longString); + hash.update(longString); + return hash.digest("hex"); + }, + "wasm md4", + () => { + const hash = createHash("md4"); + hash.update(longString); + hash.update(longString); + return hash.digest("hex"); + } + ) + ); + console.log( + `buffer ${buffer.length} bytes: ` + + compare( + "native md4", + () => { + const hash = createHash("native-md4"); + hash.update(buffer); + hash.update(buffer); + return hash.digest("hex"); + }, + "wasm md4", + () => { + const hash = createHash("md4"); + hash.update(buffer); + hash.update(buffer); + return hash.digest("hex"); + } + ) + ); +} diff --git a/benchmark/micro-compare.js b/benchmark/micro-compare.js new file mode 100644 index 00000000000..fb4541bddcb --- /dev/null +++ b/benchmark/micro-compare.js @@ -0,0 +1,44 @@ +let result; + +const measure = (fn, count) => { + const start = process.hrtime.bigint(); + for (let i = 0; i < count; i++) result = fn(); + return Number(process.hrtime.bigint() - start); +}; + +const NS_PER_MS = 1000000; // 1ms +const MIN_DURATION = 100 * NS_PER_MS; // 100ms +const MAX_DURATION = 1000 * NS_PER_MS; // 1000ms +const MAX_WARMUP_DURATION = 1 * NS_PER_MS; // 1ms + +const format = (fast, slow, fastName, slowName, count) => { + return `${fastName} is ${ + Math.round(((slow - fast) * 1000) / slow) / 10 + }% faster than ${slowName} (${Math.round(fast / 100 / count) / 10} ยตs vs ${ + Math.round(slow / 100 / count) / 10 + } ยตs, ${count}x)`; +}; + +const compare = (n1, f1, n2, f2) => { + let count = 1; + while (true) { + const timings = [f1, f2, f1, f2, f1, f2].map(f => measure(f, count)); + const t1 = Math.min(timings[0], timings[2], timings[4]); + const t2 = Math.min(timings[1], timings[3], timings[5]); + if (count === 1 && (t1 > MAX_WARMUP_DURATION || t2 > MAX_WARMUP_DURATION)) { + continue; + } + if ( + (t1 > MIN_DURATION && t2 > MIN_DURATION) || + t1 > MAX_DURATION || + t2 > MAX_DURATION + ) { + return t1 > t2 + ? format(t2, t1, n2, n1, count) + : format(t1, t2, n1, n2, count); + } + count *= 2; + } +}; + +module.exports = compare; diff --git a/benchmark/xxhash64-vs-md4.js b/benchmark/xxhash64-vs-md4.js new file mode 100644 index 00000000000..0ed6085596d --- /dev/null +++ b/benchmark/xxhash64-vs-md4.js @@ -0,0 +1,45 @@ +const createHash = require("../lib/util/createHash"); + +const compare = require("./micro-compare"); + +for (const size of [ + 1, 10, 20, 40, 60, 80, 100, 200, 400, 1000, 1001, 5000, 8183, 8184, 8185, + 10000, 20000, 32768, 32769, 50000, 100000, 200000 +]) { + const longString = require("crypto").randomBytes(size).toString("hex"); + const buffer = require("crypto").randomBytes(size * 2); + console.log( + `string ${longString.length} chars: ` + + compare( + "wasm xxhash64", + () => { + const hash = createHash("xxhash64"); + hash.update(longString); + return hash.digest("hex"); + }, + "wasm md4", + () => { + const hash = createHash("md4"); + hash.update(longString); + return hash.digest("hex"); + } + ) + ); + console.log( + `buffer ${buffer.length} bytes: ` + + compare( + "wasm xxhash64", + () => { + const hash = createHash("xxhash64"); + hash.update(buffer); + return hash.digest("hex"); + }, + "wasm md4", + () => { + const hash = createHash("md4"); + hash.update(buffer); + return hash.digest("hex"); + } + ) + ); +} diff --git a/benchmark/xxhash64.js b/benchmark/xxhash64.js new file mode 100644 index 00000000000..7219b233e8a --- /dev/null +++ b/benchmark/xxhash64.js @@ -0,0 +1,49 @@ +const createHash = require("../lib/util/createHash"); + +const compare = require("./micro-compare"); + +for (const size of [ + 1, 10, 20, 40, 60, 80, 100, 200, 400, 1000, 1001, 5000, 8183, 8184, 8185, + 10000, 20000, 32768, 32769, 50000, 100000, 200000 +]) { + const longString = require("crypto").randomBytes(size).toString("hex"); + const buffer = require("crypto").randomBytes(size * 2); + console.log( + `string ${longString.length} chars: ` + + compare( + "wasm xxhash64", + () => { + const hash = createHash("xxhash64"); + hash.update(longString); + hash.update(longString); + return hash.digest("hex"); + }, + "native md4", + () => { + const hash = createHash("native-md4"); + hash.update(longString); + hash.update(longString); + return hash.digest("hex"); + } + ) + ); + console.log( + `buffer ${buffer.length} bytes: ` + + compare( + "wasm xxhash64", + () => { + const hash = createHash("xxhash64"); + hash.update(buffer); + hash.update(buffer); + return hash.digest("hex"); + }, + "native md4", + () => { + const hash = createHash("native-md4"); + hash.update(buffer); + hash.update(buffer); + return hash.digest("hex"); + } + ) + ); +} diff --git a/bin/webpack.js b/bin/webpack.js index 0421e3c1b78..cbb748f7e6d 100755 --- a/bin/webpack.js +++ b/bin/webpack.js @@ -32,13 +32,41 @@ const runCommand = (command, args) => { * @returns {boolean} is the package installed? */ const isInstalled = packageName => { - try { - require.resolve(packageName); - + if (process.versions.pnp) { return true; - } catch (err) { - return false; } + + const path = require("path"); + const fs = require("graceful-fs"); + + let dir = __dirname; + + do { + try { + if ( + fs.statSync(path.join(dir, "node_modules", packageName)).isDirectory() + ) { + return true; + } + } catch (_error) { + // Nothing + } + } while (dir !== (dir = path.dirname(dir))); + + // https://github.com/nodejs/node/blob/v18.9.1/lib/internal/modules/cjs/loader.js#L1274 + // eslint-disable-next-line no-warning-comments + // @ts-ignore + for (const internalPath of require("module").globalPaths) { + try { + if (fs.statSync(path.join(internalPath, packageName)).isDirectory()) { + return true; + } + } catch (_error) { + // Nothing + } + } + + return false; }; /** @@ -48,14 +76,22 @@ const isInstalled = packageName => { const runCli = cli => { const path = require("path"); const pkgPath = require.resolve(`${cli.package}/package.json`); - // eslint-disable-next-line node/no-missing-require const pkg = require(pkgPath); - // eslint-disable-next-line node/no-missing-require - require(path.resolve(path.dirname(pkgPath), pkg.bin[cli.binName])); + + if (pkg.type === "module" || /\.mjs/i.test(pkg.bin[cli.binName])) { + import(path.resolve(path.dirname(pkgPath), pkg.bin[cli.binName])).catch( + err => { + console.error(err); + process.exitCode = 1; + } + ); + } else { + require(path.resolve(path.dirname(pkgPath), pkg.bin[cli.binName])); + } }; /** - * @typedef {Object} CliOption + * @typedef {object} CliOption * @property {string} name display name * @property {string} package npm package name * @property {string} binName name of the executable file @@ -77,11 +113,11 @@ if (!cli.installed) { const fs = require("graceful-fs"); const readLine = require("readline"); - const notify = - "CLI for webpack must be installed.\n" + ` ${cli.name} (${cli.url})\n`; + const notify = `CLI for webpack must be installed.\n ${cli.name} (${cli.url})\n`; console.error(notify); + /** @type {string | undefined} */ let packageManager; if (fs.existsSync(path.resolve(process.cwd(), "yarn.lock"))) { @@ -100,7 +136,7 @@ if (!cli.installed) { )} ${cli.package}".` ); - const question = `Do you want to install 'webpack-cli' (yes/no): `; + const question = "Do you want to install 'webpack-cli' (yes/no): "; const questionInterface = readLine.createInterface({ input: process.stdin, @@ -134,12 +170,15 @@ if (!cli.installed) { }')...` ); - runCommand(packageManager, installOptions.concat(cli.package)) + runCommand( + /** @type {string} */ (packageManager), + installOptions.concat(cli.package) + ) .then(() => { runCli(cli); }) - .catch(error => { - console.error(error); + .catch(err => { + console.error(err); process.exitCode = 1; }); }); diff --git a/codecov.yml b/codecov.yml index 9082ed53a44..24fc54029bb 100644 --- a/codecov.yml +++ b/codecov.yml @@ -1,5 +1,5 @@ codecov: - branch: master + branch: main coverage: precision: 2 round: down diff --git a/cspell.json b/cspell.json index 1f5e3a39996..14086b9e9c2 100644 --- a/cspell.json +++ b/cspell.json @@ -1,231 +1,329 @@ { - "version": "0.1", + "version": "0.2", "language": "en", "words": [ - "webpack", - "webpack's", - "endregion", - "entrypoint", - "entrypoints", - "splitted", - "dedupe", - "deduplication", - "deduplicating", - "unoptimized", - "prefetch", - "prefetching", - "prefetched", - "preload", - "preloading", - "preloaded", - "gzipping", - "submodule", - "submodules", - "typeof", - "devtool", - "wasi", - "wasm", - "webassembly", - "IIFE", - "IIFE's", + "absolutify", + "abortable", + "acircular", + "amdmodule", + "analyse", + "analysed", + "asmjs", + "assemblyscript", + "asyncloader", + "atlaskit", + "autocrlf", + "babeljs", + "backport", + "backported", + "basictest", "bigint", - "unexception", - "etag", + "bindgen", + "Birรณ", + "bitfield", + "bomfile", + "booleanized", + "boolish", + "brotli", + "browserified", + "browserslist", + "browserslistrc", + "browsertest", + "Brumme", + "bugfix", + "bugfixes", "builtins", - "uncacheable", "cacheable", - "mergeable", + "callme", + "camelcase", + "chainable", + "chunkfilename", + "chunkhash", + "chunkname", + "cmodule", + "codecov", + "cofounder", + "Collet's", + "compat", + "concated", + "contenthash", + "contextifies", + "cspellcache", + "crossorigin", + "csvg", + "cujojs", + "Dani", + "darkblue", + "darkgreen", + "darkred", + "datastructures", + "declarators", + "dedupe", + "deduplicating", + "deduplication", + "defunctzombie", + "deopt", + "deopts", + "dependabot", + "Descr", + "deserialization", + "destructure", + "devtool", "devtools", - "transpiled", - "mixins", - "subdir", + "donotcallme", + "eslintcache", + "endregion", + "entrypoint", + "entrypoints", + "Eoksni", + "eqeqeq", "errored", + "esmodule", + "estree", + "etag", + "etags", "eval", - "multiplicator", - "finalizer", - "promisify", - "absolutify", - "camelcase", + "Ewald", + "exitance", + "fetchpriority", "filebase", - "moduleid", - "modulehash", - "chunkfilename", - "chunkname", - "chunkhash", + "fileoverview", + "filepath", + "finalizer", + "fsevents", "fullhash", - "contenthash", + "funcindex", + "functype", + "gcov", + "gibibytes", + "gitattributes", + "gitter", + "global's", + "globstar", + "gzipping", "hashable", + "hashbang", + "hashchange", + "hashs", + "hotpink", "hotupdatechunk", + "ident", + "idents", + "IIFE", + "IIFE's", + "informations", + "instanceof", + "inversed", + "jhnns", + "jrburke", + "jsfile", + "jsons", + "junit", + "Junya", + "jsdoc", + "kaios", + "Kees", + "kibibytes", + "Kluskens", + "Koppers", + "laof", + "Larkin", + "lcov", + "lcovonly", + "lintunit", + "loadername", + "loglevel", + "longnameforexport", + "longtest", + "mangleable", + "MCEP", + "mebibytes", + "medikoo", + "membertest", + "memfs", + "mergeable", + "metacharacters", + "microtask", + "microtasks", "middleware", "middlewares", + "mimetype", + "mixins", + "modulehash", + "moduleid", + "modulos", + "moji", + "MONEI", + "mult", + "multiplicator", + "mylibrary", + "mynamespace", + "navigations", + "nmodule", + "noimport", + "nonexistentfile", + "nonrecursive", + "nosource", + "nosources", + "nwjs", + "onconnect", + "opencollective", + "opensource", + "opuuus", + "overridable", + "overridables", + "parallelism", + "passthrough", + "pathinfo", + "performant", + "Phoscur", + "pmodule", + "pnpm", + "polyfilled", + "popstate", + "posthtml", + "precompute", + "prefetch", + "prefetched", + "prefetching", + "preload", + "preloaded", + "preloading", + "preparsed", + "preprocess", + "prettierrc", + "prewalking", + "prioritise", + "promisify", + "proxied", + "quasis", + "queryloader", + "querystrings", + "RBDT", + "reconsume", + "recurse", + "redeclaration", + "reexecuted", + "referenceable", + "referencer", + "repo", + "repos", + "return'development", + "returnfalse", + "revparse", + "rimraf", + "Rivest", + "rrrlll", + "runtime", + "runtimes", + "samsunginternet", + "sandboxed", + "serializables", "serializer", "serializers", - "deserialization", - "referenceable", - "polyfilled", - "transpiling", - "transpile", - "transpiles", + "shama", + "skypack", "snapshotting", + "sokra", + "somepackage", + "somepath", "sourcemap", - "nosources", - "filepath", + "sourcemapped", + "splitted", + "stylesheet", + "slsh", + "subdir", + "subfolder", + "submodule", + "submodules", "subpath", - "pathinfo", - "undelayed", - "microtask", - "microtasks", - "deopt", - "deopts", - "sandboxed", - "mangleable", - "passthrough", - "prioritise", - "booleanized", - "serializables", - "unreviewed", - "unshifted", - "nonrecursive", + "substack", "symlinked", - "subfolder", - "prettierrc", + "syncloader", + "systemjs", + "tapable", "templated", "templating", - "kibibytes", - "mebibytes", - "gibibytes", - "typechecker", - "recurse", - "preparsed", - "autocrlf", - "lcov", - "lcovonly", - "gcov", - "lintunit", - "instanceof", - "loglevel", - "runtime", - "runtimes", - "mimetype", + "testcase", + "testlink", + "testloader", "testvalue", + "timestamping", + "tmpl", + "toplevel", + "traceur", + "transpile", + "transpiled", + "transpiles", + "transpiling", + "triaging", + "Tshs", + "typechecker", + "typeof", + "ufeff", + "uncacheable", + "undefine", + "undelayed", + "unexception", + "unoptimized", + "unreviewed", + "unshifted", + "unsplittable", + "untaint", "unusedkey", "unusedvalue", - "performant", - "watchings", - "jsons", - "exitance", - "ident", - "idents", - "globstar", - "inversed", - "concated", - "RBDT", - "opensource", - "bugfix", - "bugfixes", - "declarators", - "rrrlll", - "undefine", - "finializer", - "quasis", - "hashs", - "functype", - "funcindex", - "Descr", + "url's", + "valign", "valtype", - "informations", - "reexecuted", - "global's", - "unsplittable", - "chainable", - "metacharacters", + "wasi", + "wasm", + "watchings", + "watchpack", + "webassembly", + "webassemblyjs", + "webmake", + "webpack", + "webpack's", "Xarray", + "Xexports", "Xfactory", "Xmodule", - "Xexports", - "moji", - "bitfield", - "precompute", - "toplevel", - "modulos", - "untaint", - "ufeff", - "timestamping", - "loadername", - "laof", - "cofounder", - "hashchange", - "popstate", - "hotpink", - "navigations", - "compat", - "noimport", - "tmpl", - "csvg", - "repo", - "repos", - "triaging", - "valign", - "returnfalse", - "return'development", - "datastructures", - "prewalking", - "overridables", - "overridable", - "darkblue", - "darkgreen", - "darkred", - "eqeqeq", - "boolish", - "analysing", - "etags", - "destructure", - "onconnect", - "nwjs", - "redeclaration", - "kaios", - "parallelism", - - "webassemblyjs", - "fsevents", - "watchpack", - "tapable", - "junit", - "memfs", - "rimraf", - "estree", - "posthtml", - "MCEP", - "traceur", - "atlaskit", + "xxhash", "xxhashjs", - "systemjs", - - "sokra", - "Koppers", - "Junya", - "Eoksni", - "Ewald", - "Larkin", - "Kees", - "Kluskens", - "Phoscur", - "defunctzombie", - "shama", - "jhnns", - "substack", - "MONEI", - "medikoo", - "webmake", - "jrburke", - "gitter", - "codecov", - "opencollective", - "dependabot", - "browserslist", - "samsunginternet", - "pnpm" + "Yann", + "readonly", + "commithash", + "formaters" + ], + "ignoreRegExpList": [ + "/Author.+/", + "/data:.*/", + "/\"mappings\":\".+\"/", + "/toMatchInlineSnapshot\\(\\s*`[^`]*`\\s*\\)/" ], - "ignoreRegExpList": ["/Author.+/", "/data:.*/", "/\"mappings\":\".+\"/"], - "ignorePaths": ["**/dist/**", "examples/**/README.md"] + "ignorePaths": [ + "**/dist/**", + "**/node_modules/**", + "examples/**/README.md", + "examples/wasm-bindgen*/pkg/*_bg.js", + "examples/wasm-bindgen*/pkg/*_bg*.d.ts", + "**/webpack.lock.data/**", + "package.json", + "yarn.lock", + "types.d.ts", + "**/**/*.snap", + "test/cases/json/weird-properties/globals.json", + "test/JavascriptParser.unittest.js", + "**/*.svg", + "*.log", + "**/*.wasm", + "coverage/**", + "test/**/module.js", + "test/js/**", + "test/cases/**", + "test/configCases/**", + "test/statsCases/**", + "test/fixtures/**", + "test/memoryLimitCases/**" + ] } diff --git a/declarations.d.ts b/declarations.d.ts index 93ef7942486..787a6d57c50 100644 --- a/declarations.d.ts +++ b/declarations.d.ts @@ -124,17 +124,19 @@ declare module "neo-async" { // There are no typings for @webassemblyjs/ast declare module "@webassemblyjs/ast" { + export interface Visitor { + ModuleImport?: (p: NodePath) => void; + ModuleExport?: (p: NodePath) => void; + Start?: (p: NodePath) => void; + Global?: (p: NodePath) => void; + } export function traverse( ast: any, - visitor: { - ModuleImport?: (p: NodePath) => void; - ModuleExport?: (p: NodePath) => void; - Start?: (p: NodePath) => void; - Global?: (p: NodePath) => void; - } + visitor: Visitor ): void; export class NodePath { node: T; + remove(): void; } export class Node {} export class Identifier extends Node { @@ -148,6 +150,7 @@ declare module "@webassemblyjs/ast" { valtype?: string; id?: Identifier; signature?: Signature; + mutability: string; } export class ModuleImport extends Node { module: string; @@ -171,6 +174,7 @@ declare module "@webassemblyjs/ast" { export class FloatLiteral extends Node {} export class GlobalType extends Node { valtype: string; + mutability: string; } export class Global extends Node { init: Instruction[]; @@ -204,7 +208,7 @@ declare module "@webassemblyjs/ast" { raw?: string ): FloatLiteral; export function global(globalType: string, nodes: Node[]): Global; - export function identifier(indentifier: string): Identifier; + export function identifier(identifier: string): Identifier; export function funcParam(valType: string, id: Identifier): FuncParam; export function instruction(inst: string, args?: Node[]): Instruction; export function callInstruction(funcIndex: Index): CallInstruction; @@ -214,9 +218,9 @@ declare module "@webassemblyjs/ast" { init: Node[] ): ObjectInstruction; export function signature(params: FuncParam[], results: string[]): Signature; - export function func(initFuncId, signature: Signature, funcBody): Func; + export function func(initFuncId: Identifier, signature: Signature, funcBody: Instruction[]): Func; export function typeInstruction( - id: Identifier, + id: Identifier | undefined, functype: Signature ): TypeInstruction; export function indexInFuncSection(index: Index): IndexInFuncSection; @@ -229,7 +233,7 @@ declare module "@webassemblyjs/ast" { index: Index ): ModuleExportDescr; - export function getSectionMetadata(ast: any, section: string); + export function getSectionMetadata(ast: any, section: string): { vectorOfSize: { value: number } }; export class FuncSignature { args: string[]; result: string[]; @@ -243,17 +247,34 @@ declare module "@webassemblyjs/ast" { export function isFuncImportDescr(n: Node): boolean; } +declare module "@webassemblyjs/wasm-parser" { + export function decode(source: string | Buffer, options: { dump?: boolean, ignoreCodeSection?: boolean, ignoreDataSection?: boolean, ignoreCustomNameSection?: boolean }): any; +} + +declare module "@webassemblyjs/wasm-edit" { + export function addWithAST(ast: any, bin: any, newNodes: import("@webassemblyjs/ast").Node[]): ArrayBuffer; + export function editWithAST(ast: any, bin: any, visitors: import("@webassemblyjs/ast").Visitor): ArrayBuffer; +} + declare module "webpack-sources" { export type MapOptions = { columns?: boolean; module?: boolean }; + export type RawSourceMap = { + version: number; + sources: string[]; + names: string[]; + sourceRoot?: string; + sourcesContent?: string[]; + mappings: string; + file: string; + }; + export abstract class Source { size(): number; - map(options?: MapOptions): Object; + map(options?: MapOptions): RawSourceMap | null; - sourceAndMap( - options?: MapOptions - ): { + sourceAndMap(options?: MapOptions): { source: string | Buffer; map: Object; }; @@ -373,6 +394,18 @@ declare module "browserslist" { export = browserslist; } +declare module "json-parse-even-better-errors" { + function parseJson(text: string, reviver?: (this: any, key: string, value: any) => any, context?: number): any; + export = parseJson; +} + +// TODO remove that when @types/estree is updated +interface ImportAttributeNode { + type: "ImportAttribute"; + key: import("estree").Identifier | import("estree").Literal; + value: import("estree").Literal; +} + type TODO = any; type RecursiveArrayOrRecord = diff --git a/declarations/LoaderContext.d.ts b/declarations/LoaderContext.d.ts new file mode 100644 index 00000000000..533a60828f8 --- /dev/null +++ b/declarations/LoaderContext.d.ts @@ -0,0 +1,292 @@ +import type { SourceMap } from "../lib/NormalModule"; +import type Module from "../lib/Module"; +import type { validate } from "schema-utils"; +import type { AssetInfo } from "../lib/Compilation"; +import type { ResolveOptionsWithDependencyType } from "../lib/ResolverFactory"; +import type Compilation from "../lib/Compilation"; +import type Compiler from "../lib/Compiler"; +import type NormalModule from "../lib/NormalModule"; +import type Hash from "../lib/util/Hash"; +import type { InputFileSystem } from "../lib/util/fs"; +import type { Logger } from "../lib/logging/Logger"; +import type { + ImportModuleCallback, + ImportModuleOptions +} from "../lib/dependencies/LoaderPlugin"; +import type { Resolver } from "enhanced-resolve"; +import type { Environment } from "./WebpackOptions"; + +type ResolveCallback = Parameters[4]; +type Schema = Parameters[0]; + +/** These properties are added by the NormalModule */ +export interface NormalModuleLoaderContext { + version: number; + getOptions(): OptionsType; + getOptions(schema: Schema): OptionsType; + emitWarning(warning: Error): void; + emitError(error: Error): void; + getLogger(name?: string): Logger; + resolve(context: string, request: string, callback: ResolveCallback): any; + getResolve( + options?: ResolveOptionsWithDependencyType + ): ((context: string, request: string, callback: ResolveCallback) => void) & + ((context: string, request: string) => Promise); + emitFile( + name: string, + content: string | Buffer, + sourceMap?: string, + assetInfo?: AssetInfo + ): void; + addBuildDependency(dep: string): void; + utils: { + absolutify: (context: string, request: string) => string; + contextify: (context: string, request: string) => string; + createHash: (algorithm?: string | typeof Hash) => Hash; + }; + rootContext: string; + fs: InputFileSystem; + sourceMap?: boolean; + mode: "development" | "production" | "none"; + webpack?: boolean; + _module?: NormalModule; + _compilation?: Compilation; + _compiler?: Compiler; +} + +/** These properties are added by the HotModuleReplacementPlugin */ +export interface HotModuleReplacementPluginLoaderContext { + hot?: boolean; +} + +/** These properties are added by the LoaderPlugin */ +export interface LoaderPluginLoaderContext { + /** + * Resolves the given request to a module, applies all configured loaders and calls + * back with the generated source, the sourceMap and the module instance (usually an + * instance of NormalModule). Use this function if you need to know the source code + * of another module to generate the result. + */ + loadModule( + request: string, + callback: ( + err: Error | null, + source?: string | Buffer, + sourceMap?: object | null, + module?: Module + ) => void + ): void; + + importModule( + request: string, + options: ImportModuleOptions | undefined, + callback: ImportModuleCallback + ): void; + importModule(request: string, options?: ImportModuleOptions): Promise; +} + +/** The properties are added by https://github.com/webpack/loader-runner */ +export interface LoaderRunnerLoaderContext { + /** + * Add a directory as dependency of the loader result. + */ + addContextDependency(context: string): void; + + /** + * Adds a file as dependency of the loader result in order to make them watchable. + * For example, html-loader uses this technique as it finds src and src-set attributes. + * Then, it sets the url's for those attributes as dependencies of the html file that is parsed. + */ + addDependency(file: string): void; + + addMissingDependency(context: string): void; + + /** + * Make this loader async. + */ + async(): WebpackLoaderContextCallback; + + /** + * Make this loader result cacheable. By default it's cacheable. + * A cacheable loader must have a deterministic result, when inputs and dependencies haven't changed. + * This means the loader shouldn't have other dependencies than specified with this.addDependency. + * Most loaders are deterministic and cacheable. + */ + cacheable(flag?: boolean): void; + + callback: WebpackLoaderContextCallback; + + /** + * Remove all dependencies of the loader result. Even initial dependencies and these of other loaders. + */ + clearDependencies(): void; + + /** + * The directory of the module. Can be used as context for resolving other stuff. + * eg '/workspaces/ts-loader/examples/vanilla/src' + */ + context: string; + + readonly currentRequest: string; + + readonly data: any; + /** + * alias of addDependency + * Adds a file as dependency of the loader result in order to make them watchable. + * For example, html-loader uses this technique as it finds src and src-set attributes. + * Then, it sets the url's for those attributes as dependencies of the html file that is parsed. + */ + dependency(file: string): void; + + getContextDependencies(): string[]; + + getDependencies(): string[]; + + getMissingDependencies(): string[]; + + /** + * The index in the loaders array of the current loader. + * In the example: in loader1: 0, in loader2: 1 + */ + loaderIndex: number; + + readonly previousRequest: string; + + readonly query: string | OptionsType; + + readonly remainingRequest: string; + + readonly request: string; + + /** + * An array of all the loaders. It is writeable in the pitch phase. + * loaders = [{request: string, path: string, query: string, module: function}] + * + * In the example: + * [ + * { request: "/abc/loader1.js?xyz", + * path: "/abc/loader1.js", + * query: "?xyz", + * module: [Function] + * }, + * { request: "/abc/node_modules/loader2/index.js", + * path: "/abc/node_modules/loader2/index.js", + * query: "", + * module: [Function] + * } + * ] + */ + loaders: { + request: string; + path: string; + query: string; + fragment: string; + options: object | string | undefined; + ident: string; + normal: Function | undefined; + pitch: Function | undefined; + raw: boolean | undefined; + data: object | undefined; + pitchExecuted: boolean; + normalExecuted: boolean; + type?: "commonjs" | "module" | undefined; + }[]; + + /** + * The resource path. + * In the example: "/abc/resource.js" + */ + resourcePath: string; + + /** + * The resource query string. + * Example: "?query" + */ + resourceQuery: string; + + /** + * The resource fragment. + * Example: "#frag" + */ + resourceFragment: string; + + /** + * The resource inclusive query and fragment. + * Example: "/abc/resource.js?query#frag" + */ + resource: string; + + /** + * Target of compilation. + * Example: "web" + */ + target: string; + + /** + * Tell what kind of ES-features may be used in the generated runtime-code. + * Example: { arrowFunction: true } + */ + environment: Environment; +} + +type AdditionalData = { + webpackAST: object; + [index: string]: any; +}; + +type WebpackLoaderContextCallback = ( + err: Error | undefined | null, + content?: string | Buffer, + sourceMap?: string | SourceMap, + additionalData?: AdditionalData +) => void; + +type LoaderContext = NormalModuleLoaderContext & + LoaderRunnerLoaderContext & + LoaderPluginLoaderContext & + HotModuleReplacementPluginLoaderContext; + +type PitchLoaderDefinitionFunction = ( + this: LoaderContext & ContextAdditions, + remainingRequest: string, + previousRequest: string, + data: object +) => string | Buffer | Promise | void; + +type LoaderDefinitionFunction = ( + this: LoaderContext & ContextAdditions, + content: string, + sourceMap?: string | SourceMap, + additionalData?: AdditionalData +) => string | Buffer | Promise | void; + +type RawLoaderDefinitionFunction = ( + this: LoaderContext & ContextAdditions, + content: Buffer, + sourceMap?: string | SourceMap, + additionalData?: AdditionalData +) => string | Buffer | Promise | void; + +export type LoaderDefinition< + OptionsType = {}, + ContextAdditions = {} +> = LoaderDefinitionFunction & { + raw?: false; + pitch?: PitchLoaderDefinitionFunction; +}; + +export type RawLoaderDefinition< + OptionsType = {}, + ContextAdditions = {} +> = RawLoaderDefinitionFunction & { + raw: true; + pitch?: PitchLoaderDefinitionFunction; +}; + +export interface LoaderModule { + default?: + | RawLoaderDefinitionFunction + | LoaderDefinitionFunction; + raw?: false; + pitch?: PitchLoaderDefinitionFunction; +} diff --git a/declarations/WebpackOptions.d.ts b/declarations/WebpackOptions.d.ts index 793f421c758..1b7e8f875e7 100644 --- a/declarations/WebpackOptions.d.ts +++ b/declarations/WebpackOptions.d.ts @@ -35,6 +35,14 @@ export type Context = string; * References to other configurations to depend on. */ export type Dependencies = string[]; +/** + * Options for the webpack-dev-server. + */ +export type DevServer = + | false + | { + [k: string]: any; + }; /** * A developer tool to enhance debugging (false | eval | [inline-|hidden-|eval-][nosources-][cheap-[module-]]source-map). */ @@ -56,14 +64,14 @@ export type EntryStatic = EntryObject | EntryUnnamed; */ export type EntryItem = string[] | string; /** - * The method of loading chunks (methods included by default are 'jsonp' (web), 'importScripts' (WebWorker), 'require' (sync node.js), 'async-node' (async node.js), but others might be added by plugins). + * The method of loading chunks (methods included by default are 'jsonp' (web), 'import' (ESM), 'importScripts' (WebWorker), 'require' (sync node.js), 'async-node' (async node.js), but others might be added by plugins). */ export type ChunkLoading = false | ChunkLoadingType; /** - * The method of loading chunks (methods included by default are 'jsonp' (web), 'importScripts' (WebWorker), 'require' (sync node.js), 'async-node' (async node.js), but others might be added by plugins). + * The method of loading chunks (methods included by default are 'jsonp' (web), 'import' (ESM), 'importScripts' (WebWorker), 'require' (sync node.js), 'async-node' (async node.js), but others might be added by plugins). */ export type ChunkLoadingType = - | ("jsonp" | "import-scripts" | "require" | "async-node") + | ("jsonp" | "import-scripts" | "require" | "async-node" | "import") | string; /** * Specifies the filename of the output file on disk. You must **not** specify an absolute path here, but the path may contain folders separated by '/'! The specified path is joined with the value of the 'output.path' option to determine the location on disk. @@ -82,6 +90,10 @@ export type FilenameTemplate = * Specifies the layer in which modules of this entrypoint are placed. */ export type Layer = null | string; +/** + * Add a container for define/require functions in the AMD module. + */ +export type AmdContainer = string; /** * Add a comment in the UMD wrapper. */ @@ -95,7 +107,7 @@ export type LibraryExport = string[] | string; */ export type LibraryName = string[] | string | LibraryCustomUmdObject; /** - * Type of library (types included by default are 'var', 'module', 'assign', 'assign-properties', 'this', 'window', 'self', 'global', 'commonjs', 'commonjs2', 'commonjs-module', 'amd', 'amd-require', 'umd', 'umd2', 'jsonp', 'system', but others might be added by plugins). + * Type of library (types included by default are 'var', 'module', 'assign', 'assign-properties', 'this', 'window', 'self', 'global', 'commonjs', 'commonjs2', 'commonjs-module', 'commonjs-static', 'amd', 'amd-require', 'umd', 'umd2', 'jsonp', 'system', but others might be added by plugins). */ export type LibraryType = | ( @@ -110,6 +122,7 @@ export type LibraryType = | "commonjs" | "commonjs2" | "commonjs-module" + | "commonjs-static" | "amd" | "amd-require" | "umd" @@ -122,10 +135,23 @@ export type LibraryType = * If `output.libraryTarget` is set to umd and `output.library` is set, setting this to true will name the AMD module. */ export type UmdNamedDefine = boolean; +/** + * The 'publicPath' specifies the public URL address of the output files when referenced in a browser. + */ +export type PublicPath = "auto" | RawPublicPath; +/** + * The 'publicPath' specifies the public URL address of the output files when referenced in a browser. + */ +export type RawPublicPath = + | string + | (( + pathData: import("../lib/Compilation").PathData, + assetInfo?: import("../lib/Compilation").AssetInfo + ) => string); /** * The name of the runtime chunk. If set a runtime chunk with this name is created or an existing entrypoint is used as runtime. */ -export type EntryRuntime = string; +export type EntryRuntime = false | string; /** * The method of loading WebAssembly Modules (methods included by default are 'fetch' (web/WebWorker), 'async-node' (node.js), but others might be added by plugins). */ @@ -140,6 +166,18 @@ export type WasmLoadingType = * An entry point without name. */ export type EntryUnnamed = EntryItem; +/** + * Enables/Disables experiments (experimental features with relax SemVer compatibility). + */ +export type Experiments = ExperimentsCommon & ExperimentsExtra; +/** + * Extend configuration from another configuration (only works when using webpack-cli). + */ +export type Extends = ExtendsItem[] | ExtendsItem; +/** + * Path to the configuration to be extended (only works when using webpack-cli). + */ +export type ExtendsItem = string; /** * Specify dependencies that shouldn't be resolved by webpack, but should become dependencies of the resulting bundle. The kind of the dependency depends on `output.libraryTarget`. */ @@ -154,7 +192,7 @@ export type ExternalItem = | ( | (( data: ExternalItemFunctionData, - callback: (err?: Error, result?: ExternalItemValue) => void + callback: (err?: Error | null, result?: ExternalItemValue) => void ) => void) | ((data: ExternalItemFunctionData) => Promise) ); @@ -172,6 +210,7 @@ export type ExternalsType = | "commonjs" | "commonjs2" | "commonjs-module" + | "commonjs-static" | "amd" | "amd-require" | "umd" @@ -180,7 +219,9 @@ export type ExternalsType = | "system" | "promise" | "import" - | "script"; + | "module-import" + | "script" + | "node-commonjs"; /** * Ignore specific warnings. */ @@ -217,6 +258,10 @@ export type FilterItemTypes = RegExp | string | ((value: string) => boolean); * Enable production optimizations or development hints. */ export type Mode = "development" | "production" | "none"; +/** + * These values will be ignored by webpack and created to be used with '&&' or '||' to improve readability of configurations. + */ +export type Falsy = false | 0 | "" | null | undefined; /** * One or multiple rule conditions. */ @@ -227,21 +272,8 @@ export type RuleSetConditionOrConditions = RuleSetCondition | RuleSetConditions; export type RuleSetCondition = | RegExp | string - | { - /** - * Logical AND. - */ - and?: RuleSetConditions; - /** - * Logical NOT. - */ - not?: RuleSetConditions; - /** - * Logical OR. - */ - or?: RuleSetConditions; - } | ((value: string) => boolean) + | RuleSetLogicalConditions | RuleSetConditions; /** * A list of rule conditions. @@ -259,21 +291,8 @@ export type RuleSetConditionOrConditionsAbsolute = export type RuleSetConditionAbsolute = | RegExp | string - | { - /** - * Logical AND. - */ - and?: RuleSetConditionsAbsolute; - /** - * Logical NOT. - */ - not?: RuleSetConditionsAbsolute; - /** - * Logical OR. - */ - or?: RuleSetConditionsAbsolute; - } | ((value: string) => boolean) + | RuleSetLogicalConditionsAbsolute | RuleSetConditionsAbsolute; /** * A list of rule conditions matching an absolute path. @@ -315,18 +334,33 @@ export type ResolveAlias = */ [k: string]: string[] | false | string; }; +/** + * Plugin instance. + */ +export type ResolvePluginInstance = + | { + /** + * The run point of the plugin, required method. + */ + apply: (arg0: import("enhanced-resolve").Resolver) => void; + [k: string]: any; + } + | (( + this: import("enhanced-resolve").Resolver, + arg1: import("enhanced-resolve").Resolver + ) => void); /** * A list of descriptions of loaders applied. */ export type RuleSetUse = - | RuleSetUseItem[] + | (Falsy | RuleSetUseItem)[] | ((data: { resource: string; realResource: string; resourceQuery: string; issuer: string; compiler: string; - }) => RuleSetUseItem[]) + }) => (Falsy | RuleSetUseItem)[]) | RuleSetUseItem; /** * A description of an applied loader. @@ -346,12 +380,12 @@ export type RuleSetUseItem = */ options?: RuleSetLoaderOptions; } - | ((data: object) => RuleSetUseItem | RuleSetUseItem[]) + | ((data: object) => RuleSetUseItem | (Falsy | RuleSetUseItem)[]) | RuleSetLoader; /** * A list of rules. */ -export type RuleSetRules = ("..." | RuleSetRule)[]; +export type RuleSetRules = ("..." | Falsy | RuleSetRule)[]; /** * Specify options for each generator. */ @@ -426,9 +460,11 @@ export type Charset = boolean; */ export type ChunkFilename = FilenameTemplate; /** - * The format of chunks (formats included by default are 'array-push' (web/WebWorker), 'commonjs' (node.js), but others might be added by plugins). + * The format of chunks (formats included by default are 'array-push' (web/WebWorker), 'commonjs' (node.js), 'module' (ESM), but others might be added by plugins). */ -export type ChunkFormat = ("array-push" | "commonjs" | false) | string; +export type ChunkFormat = + | ("array-push" | "commonjs" | "module" | false) + | string; /** * Number of milliseconds before chunk request expires. */ @@ -449,6 +485,18 @@ export type CompareBeforeEmit = boolean; * This option enables cross-origin loading of chunks. */ export type CrossOriginLoading = false | "anonymous" | "use-credentials"; +/** + * Specifies the filename template of non-initial output css files on disk. You must **not** specify an absolute path here, but the path may contain folders separated by '/'! The specified path is joined with the value of the 'output.path' option to determine the location on disk. + */ +export type CssChunkFilename = FilenameTemplate; +/** + * Specifies the filename template of output css files on disk. You must **not** specify an absolute path here, but the path may contain folders separated by '/'! The specified path is joined with the value of the 'output.path' option to determine the location on disk. + */ +export type CssFilename = FilenameTemplate; +/** + * Compress the data in the head tag of CSS files. + */ +export type CssHeadDataCompression = boolean; /** * Similar to `output.devtoolModuleFilenameTemplate`, but used in the case of duplicate module identifiers. */ @@ -537,16 +585,6 @@ export type Path = string; * Include comments with information about the modules. */ export type Pathinfo = "verbose" | boolean; -/** - * The `publicPath` specifies the public URL address of the output files when referenced in a browser. - */ -export type PublicPath = - | "auto" - | string - | (( - pathData: import("../lib/Compilation").PathData, - assetInfo?: import("../lib/Compilation").AssetInfo - ) => string); /** * This option enables loading async chunks via a custom script type, such as script type="module". */ @@ -575,6 +613,10 @@ export type UniqueName = string; * The filename of WebAssembly modules as relative path inside the 'output.path' directory. */ export type WebassemblyModuleFilename = string; +/** + * Worker public path. Much like the public path, this sets the location where the worker script file is intended to be found. If not set, webpack will use the publicPath. Don't set this option unless your worker scripts are located at a different path from your other script files. + */ +export type WorkerPublicPath = string; /** * The number of parallel processed modules in the compilation. */ @@ -586,7 +628,7 @@ export type Performance = false | PerformanceOptions; /** * Add additional plugins to the compiler. */ -export type Plugins = (WebpackPluginInstance | WebpackPluginFunction)[]; +export type Plugins = (Falsy | WebpackPluginInstance | WebpackPluginFunction)[]; /** * Capture timing information for each module. */ @@ -687,7 +729,7 @@ export type AssetGeneratorDataUrl = | AssetGeneratorDataUrlOptions | AssetGeneratorDataUrlFunction; /** - * Function that executes for module and should return an DataUrl string. + * Function that executes for module and should return an DataUrl string. It can have a string as 'ident' property which contributes to the module hash. */ export type AssetGeneratorDataUrlFunction = ( source: string | Buffer, @@ -698,6 +740,15 @@ export type AssetGeneratorDataUrlFunction = ( */ export type AssetGeneratorOptions = AssetInlineGeneratorOptions & AssetResourceGeneratorOptions; +/** + * Emit the asset in the specified folder relative to 'output.path'. This should only be needed when custom 'publicPath' is specified to match the folder structure there. + */ +export type AssetModuleOutputPath = + | string + | (( + pathData: import("../lib/Compilation").PathData, + assetInfo?: import("../lib/Compilation").AssetInfo + ) => string); /** * Function that executes for module and should return whenever asset should be inlined as DataUrl. */ @@ -705,6 +756,28 @@ export type AssetParserDataUrlFunction = ( source: string | Buffer, context: {filename: string; module: import("../lib/Module")} ) => boolean; +/** + * Configure the generated JS modules that use the ES modules syntax. + */ +export type CssGeneratorEsModule = boolean; +/** + * Specifies the convention of exported names. + */ +export type CssGeneratorExportsConvention = + | ("as-is" | "camel-case" | "camel-case-only" | "dashes" | "dashes-only") + | ((name: string) => string); +/** + * Avoid generating and loading a stylesheet and only embed exports from css into output javascript files. + */ +export type CssGeneratorExportsOnly = boolean; +/** + * Configure the generated local ident name. + */ +export type CssGeneratorLocalIdentName = string; +/** + * Use ES modules named export for css exports. + */ +export type CssParserNamedExports = boolean; /** * A Function returning a Promise resolving to a normalized entry. */ @@ -713,6 +786,11 @@ export type EntryDynamicNormalized = () => Promise; * The entry point(s) of the compilation. */ export type EntryNormalized = EntryDynamicNormalized | EntryStaticNormalized; +/** + * Enables/Disables experiments (experimental features with relax SemVer compatibility). + */ +export type ExperimentsNormalized = ExperimentsCommon & + ExperimentsNormalizedExtra; /** * The dependency used for the external. */ @@ -723,6 +801,18 @@ export type ExternalItemValue = | { [k: string]: any; }; +/** + * List of allowed URIs for building http resources. + */ +export type HttpUriAllowedUris = HttpUriOptionsAllowedUris; +/** + * List of allowed URIs (resp. the beginning of them). + */ +export type HttpUriOptionsAllowedUris = ( + | RegExp + | string + | ((uri: string) => boolean) +)[]; /** * Ignore specific warnings. */ @@ -791,6 +881,10 @@ export interface WebpackOptions { * Enables/Disables experiments (experimental features with relax SemVer compatibility). */ experiments?: Experiments; + /** + * Extend configuration from another configuration (only works when using webpack-cli). + */ + extends?: Extends; /** * Specify dependencies that shouldn't be resolved by webpack, but should become dependencies of the resulting bundle. The kind of the dependency depends on `output.libraryTarget`. */ @@ -900,6 +994,14 @@ export interface WebpackOptions { * Options object for in-memory caching. */ export interface MemoryCacheOptions { + /** + * Additionally cache computation of modules that are unchanged and reference only unchanged modules. + */ + cacheUnaffected?: boolean; + /** + * Number of generations unused cache entries stay in memory cache at minimum (1 = may be removed after unused for a single compilation, ..., Infinity: kept forever). + */ + maxGenerations?: number; /** * In memory caching. */ @@ -909,6 +1011,10 @@ export interface MemoryCacheOptions { * Options object for persistent file-based caching. */ export interface FileCacheOptions { + /** + * Allows to collect unused memory allocated during deserialization. This requires copying data into smaller buffers and has a performance cost. + */ + allowCollectingMemory?: boolean; /** * Dependencies the build depends on (in multiple categories, default categories: 'defaultWebpack'). */ @@ -926,30 +1032,58 @@ export interface FileCacheOptions { * Locations for the cache (defaults to cacheDirectory / name). */ cacheLocation?: string; + /** + * Compression type used for the cache files. + */ + compression?: false | "gzip" | "brotli"; /** * Algorithm used for generation the hash (see node.js crypto package). */ hashAlgorithm?: string; /** - * Time in ms after which idle period the cache storing should happen (only for store: 'pack' or 'idle'). + * Time in ms after which idle period the cache storing should happen. */ idleTimeout?: number; /** - * Time in ms after which idle period the initial cache storing should happen (only for store: 'pack' or 'idle'). + * Time in ms after which idle period the cache storing should happen when larger changes has been detected (cumulative build time > 2 x avg cache store time). + */ + idleTimeoutAfterLargeChanges?: number; + /** + * Time in ms after which idle period the initial cache storing should happen. */ idleTimeoutForInitialStore?: number; /** * List of paths that are managed by a package manager and contain a version or hash in its path so all files are immutable. */ - immutablePaths?: string[]; + immutablePaths?: (RegExp | string)[]; /** * List of paths that are managed by a package manager and can be trusted to not be modified otherwise. */ - managedPaths?: string[]; + managedPaths?: (RegExp | string)[]; + /** + * Time for which unused cache entries stay in the filesystem cache at minimum (in milliseconds). + */ + maxAge?: number; + /** + * Number of generations unused cache entries stay in memory cache at minimum (0 = no memory cache used, 1 = may be removed after unused for a single compilation, ..., Infinity: kept forever). Cache entries will be deserialized from disk when removed from memory cache. + */ + maxMemoryGenerations?: number; + /** + * Additionally cache computation of modules that are unchanged and reference only unchanged modules in memory. + */ + memoryCacheUnaffected?: boolean; /** * Name for the cache. Different names will lead to different coexisting caches. */ name?: string; + /** + * Track and log detailed timing information for individual cache items. + */ + profile?: boolean; + /** + * Enable/disable readonly mode. + */ + readonly?: boolean; /** * When to store data to the filesystem. (pack: Store data when compiler is idle in a single file). */ @@ -963,12 +1097,6 @@ export interface FileCacheOptions { */ version?: string; } -/** - * Options for the webpack-dev-server. - */ -export interface DevServer { - [k: string]: any; -} /** * Multiple entry bundles are created. The key is the entry name. The value can be a string, an array or an entry description object. */ @@ -983,7 +1111,15 @@ export interface EntryObject { */ export interface EntryDescription { /** - * The method of loading chunks (methods included by default are 'jsonp' (web), 'importScripts' (WebWorker), 'require' (sync node.js), 'async-node' (async node.js), but others might be added by plugins). + * Enable/disable creating async chunks that are loaded on demand. + */ + asyncChunks?: boolean; + /** + * Base uri for this entry. + */ + baseUri?: string; + /** + * The method of loading chunks (methods included by default are 'jsonp' (web), 'import' (ESM), 'importScripts' (WebWorker), 'require' (sync node.js), 'async-node' (async node.js), but others might be added by plugins). */ chunkLoading?: ChunkLoading; /** @@ -1006,6 +1142,10 @@ export interface EntryDescription { * Options for library. */ library?: LibraryOptions; + /** + * The 'publicPath' specifies the public URL address of the output files when referenced in a browser. + */ + publicPath?: PublicPath; /** * The name of the runtime chunk. If set a runtime chunk with this name is created or an existing entrypoint is used as runtime. */ @@ -1019,6 +1159,10 @@ export interface EntryDescription { * Options for library. */ export interface LibraryOptions { + /** + * Add a container for define/require functions in the AMD module. + */ + amdContainer?: AmdContainer; /** * Add a comment in the UMD wrapper. */ @@ -1032,7 +1176,7 @@ export interface LibraryOptions { */ name?: LibraryName; /** - * Type of library (types included by default are 'var', 'module', 'assign', 'assign-properties', 'this', 'window', 'self', 'global', 'commonjs', 'commonjs2', 'commonjs-module', 'amd', 'amd-require', 'umd', 'umd2', 'jsonp', 'system', but others might be added by plugins). + * Type of library (types included by default are 'var', 'module', 'assign', 'assign-properties', 'this', 'window', 'self', 'global', 'commonjs', 'commonjs2', 'commonjs-module', 'commonjs-static', 'amd', 'amd-require', 'umd', 'umd2', 'jsonp', 'system', but others might be added by plugins). */ type: LibraryType; /** @@ -1078,71 +1222,6 @@ export interface LibraryCustomUmdObject { */ root?: string[] | string; } -/** - * Enables/Disables experiments (experimental features with relax SemVer compatibility). - */ -export interface Experiments { - /** - * Allow module type 'asset' to generate assets. - */ - asset?: boolean; - /** - * Support WebAssembly as asynchronous EcmaScript Module. - */ - asyncWebAssembly?: boolean; - /** - * Enable module and chunk layers. - */ - layers?: boolean; - /** - * Compile entrypoints and import()s only when they are accessed. - */ - lazyCompilation?: - | boolean - | { - /** - * A custom backend. - */ - backend?: - | (( - compiler: import("../lib/Compiler"), - client: string, - callback: (err?: Error, api?: any) => void - ) => void) - | (( - compiler: import("../lib/Compiler"), - client: string - ) => Promise); - /** - * A custom client. - */ - client?: string; - /** - * Enable/disable lazy compilation for entries. - */ - entries?: boolean; - /** - * Enable/disable lazy compilation for import() modules. - */ - imports?: boolean; - /** - * Specify which entrypoints or import()ed modules should be lazily compiled. This is matched with the imported module and not the entrypoint name. - */ - test?: RegExp | string | ((module: import("../lib/Module")) => boolean); - }; - /** - * Allow output javascript files as module source type. - */ - outputModule?: boolean; - /** - * Support WebAssembly as synchronous EcmaScript Module (outdated). - */ - syncWebAssembly?: boolean; - /** - * Allow using top-level-await in EcmaScript Modules. - */ - topLevelAwait?: boolean; -} /** * Enable presets of externals for specific targets. */ @@ -1184,6 +1263,18 @@ export interface ExternalsPresets { * Options for infrastructure level logging. */ export interface InfrastructureLogging { + /** + * Only appends lines to the output. Avoids updating existing output e. g. for status messages. This option is only used when no custom console is provided. + */ + appendOnly?: boolean; + /** + * Enables/Disables colorful output. This option is only used when no custom console is provided. + */ + colors?: boolean; + /** + * Custom console used for logging. + */ + console?: Console; /** * Enable debug logging for specific loggers. */ @@ -1192,6 +1283,10 @@ export interface InfrastructureLogging { * Log level. */ level?: "none" | "error" | "warn" | "info" | "log" | "verbose"; + /** + * Stream used for logging output. Defaults to process.stderr. This option is only used when no custom console is provided. + */ + stream?: NodeJS.WritableStream; } /** * Custom values available in the loader context. @@ -1284,6 +1379,12 @@ export interface ModuleOptions { * A rule description with conditions and effects for modules. */ export interface RuleSetRule { + /** + * Match on import assertions of the dependency. + */ + assert?: { + [k: string]: RuleSetConditionOrConditions; + }; /** * Match the child compiler name. */ @@ -1339,7 +1440,7 @@ export interface RuleSetRule { /** * Only execute the first matching rule in this array. */ - oneOf?: RuleSetRule[]; + oneOf?: (Falsy | RuleSetRule)[]; /** * Shortcut for use.options. */ @@ -1373,7 +1474,11 @@ export interface RuleSetRule { /** * Match and execute these rules when this rule is matched. */ - rules?: RuleSetRule[]; + rules?: (Falsy | RuleSetRule)[]; + /** + * Match module scheme. + */ + scheme?: RuleSetConditionOrConditions; /** * Flags a module as with or without side effects. */ @@ -1390,6 +1495,46 @@ export interface RuleSetRule { * Modifiers applied to the module when rule is matched. */ use?: RuleSetUse; + /** + * Match on import attributes of the dependency. + */ + with?: { + [k: string]: RuleSetConditionOrConditions; + }; +} +/** + * Logic operators used in a condition matcher. + */ +export interface RuleSetLogicalConditions { + /** + * Logical AND. + */ + and?: RuleSetConditions; + /** + * Logical NOT. + */ + not?: RuleSetCondition; + /** + * Logical OR. + */ + or?: RuleSetConditions; +} +/** + * Logic operators used in a condition matcher. + */ +export interface RuleSetLogicalConditionsAbsolute { + /** + * Logical AND. + */ + and?: RuleSetConditionsAbsolute; + /** + * Logical NOT. + */ + not?: RuleSetConditionAbsolute; + /** + * Logical OR. + */ + or?: RuleSetConditionsAbsolute; } /** * Options object for resolving requests. @@ -1442,6 +1587,15 @@ export interface ResolveOptions { * Field names from the description file (usually package.json) which are used to provide entry points of a package. */ exportsFields?: string[]; + /** + * An object which maps extension to extension aliases. + */ + extensionAlias?: { + /** + * Extension alias. + */ + [k: string]: string[] | string; + }; /** * Extensions added to the request when trying to find the file. */ @@ -1477,7 +1631,7 @@ export interface ResolveOptions { /** * Plugins for the resolver. */ - plugins?: ("..." | ResolvePluginInstance)[]; + plugins?: ("..." | Falsy | ResolvePluginInstance)[]; /** * Prefer to resolve server-relative URLs (starting with '/') as absolute paths before falling back to resolve in 'resolve.roots'. */ @@ -1515,16 +1669,6 @@ export interface ResolveOptions { */ useSyncFileSystemCalls?: boolean; } -/** - * Plugin instance. - */ -export interface ResolvePluginInstance { - /** - * The run point of the plugin, required method. - */ - apply: (resolver: import("enhanced-resolve").Resolver) => void; - [k: string]: any; -} /** * Options object for node compatibility features. */ @@ -1532,15 +1676,21 @@ export interface NodeOptions { /** * Include a polyfill for the '__dirname' variable. */ - __dirname?: false | true | "mock" | "eval-only"; + __dirname?: false | true | "warn-mock" | "mock" | "node-module" | "eval-only"; /** * Include a polyfill for the '__filename' variable. */ - __filename?: false | true | "mock" | "eval-only"; + __filename?: + | false + | true + | "warn-mock" + | "mock" + | "node-module" + | "eval-only"; /** * Include a polyfill for the 'global' variable. */ - global?: boolean; + global?: false | true | "warn"; } /** * Enables/Disables integrated optimizations. @@ -1595,7 +1745,7 @@ export interface Optimization { /** * Minimizer(s) to use for minimizing the output. */ - minimizer?: ("..." | WebpackPluginInstance | WebpackPluginFunction)[]; + minimizer?: ("..." | Falsy | WebpackPluginInstance | WebpackPluginFunction)[]; /** * Define the algorithm to choose module ids (natural: numeric ids in order of usage, named: readable ids for better debugging, hashed: (deprecated) short hashes as ids for better long term caching, deterministic: numeric hash ids for better long term caching, size: numeric ids focused on minimal initial download size, false: no algorithm used, as custom one can be provided via plugin). */ @@ -1682,6 +1832,7 @@ export interface OptimizationSplitChunksOptions { */ chunks?: | ("initial" | "async" | "all") + | RegExp | ((chunk: import("../lib/Chunk")) => boolean); /** * Sets the size types which are used when a number is used for sizes. @@ -1699,6 +1850,13 @@ export interface OptimizationSplitChunksOptions { * Sets the name delimiter for created chunks. */ automaticNameDelimiter?: string; + /** + * Select chunks for determining shared modules (defaults to "async", "initial" and "all" requires adding these chunks to the HTML). + */ + chunks?: + | ("initial" | "async" | "all") + | RegExp + | ((chunk: import("../lib/Chunk")) => boolean); /** * Maximal size hint for the on-demand chunks. */ @@ -1715,6 +1873,10 @@ export interface OptimizationSplitChunksOptions { * Minimal size for the created chunk. */ minSize?: OptimizationSplitChunksSizes; + /** + * Minimum size reduction due to the created chunk. + */ + minSizeReduction?: OptimizationSplitChunksSizes; }; /** * Sets the template for the filename for created chunks. @@ -1761,6 +1923,10 @@ export interface OptimizationSplitChunksOptions { * Minimal size for the created chunks. */ minSize?: OptimizationSplitChunksSizes; + /** + * Minimum size reduction due to the created chunk. + */ + minSizeReduction?: OptimizationSplitChunksSizes; /** * Give chunks created a name (chunks with equal name are merged). */ @@ -1783,6 +1949,7 @@ export interface OptimizationSplitChunksCacheGroup { */ chunks?: | ("initial" | "async" | "all") + | RegExp | ((chunk: import("../lib/Chunk")) => boolean); /** * Ignore minimum size, minimum chunks and maximum requests and always create chunks for this cache group. @@ -1841,6 +2008,10 @@ export interface OptimizationSplitChunksCacheGroup { * Minimal size for the created chunk. */ minSize?: OptimizationSplitChunksSizes; + /** + * Minimum size reduction due to the created chunk. + */ + minSizeReduction?: OptimizationSplitChunksSizes; /** * Give chunks for this cache group a name (chunks with equal name are merged). */ @@ -1870,10 +2041,18 @@ export interface OptimizationSplitChunksCacheGroup { * Options affecting the output of the compilation. `output` options tell webpack how to write the compiled files to disk. */ export interface Output { + /** + * Add a container for define/require functions in the AMD module. + */ + amdContainer?: AmdContainer; /** * The filename of asset modules as relative path inside the 'output.path' directory. */ assetModuleFilename?: AssetModuleFilename; + /** + * Enable/disable creating async chunks that are loaded on demand. + */ + asyncChunks?: boolean; /** * Add a comment in the UMD wrapper. */ @@ -1887,7 +2066,7 @@ export interface Output { */ chunkFilename?: ChunkFilename; /** - * The format of chunks (formats included by default are 'array-push' (web/WebWorker), 'commonjs' (node.js), but others might be added by plugins). + * The format of chunks (formats included by default are 'array-push' (web/WebWorker), 'commonjs' (node.js), 'module' (ESM), but others might be added by plugins). */ chunkFormat?: ChunkFormat; /** @@ -1895,7 +2074,7 @@ export interface Output { */ chunkLoadTimeout?: ChunkLoadTimeout; /** - * The method of loading chunks (methods included by default are 'jsonp' (web), 'importScripts' (WebWorker), 'require' (sync node.js), 'async-node' (async node.js), but others might be added by plugins). + * The method of loading chunks (methods included by default are 'jsonp' (web), 'import' (ESM), 'importScripts' (WebWorker), 'require' (sync node.js), 'async-node' (async node.js), but others might be added by plugins). */ chunkLoading?: ChunkLoading; /** @@ -1914,6 +2093,18 @@ export interface Output { * This option enables cross-origin loading of chunks. */ crossOriginLoading?: CrossOriginLoading; + /** + * Specifies the filename template of non-initial output css files on disk. You must **not** specify an absolute path here, but the path may contain folders separated by '/'! The specified path is joined with the value of the 'output.path' option to determine the location on disk. + */ + cssChunkFilename?: CssChunkFilename; + /** + * Specifies the filename template of output css files on disk. You must **not** specify an absolute path here, but the path may contain folders separated by '/'! The specified path is joined with the value of the 'output.path' option to determine the location on disk. + */ + cssFilename?: CssFilename; + /** + * Compress the data in the head tag of CSS files. + */ + cssHeadDataCompression?: CssHeadDataCompression; /** * Similar to `output.devtoolModuleFilenameTemplate`, but used in the case of duplicate module identifiers. */ @@ -1978,6 +2169,10 @@ export interface Output { * The filename of the Hot Update Main File. It is inside the 'output.path' directory. */ hotUpdateMainFilename?: HotUpdateMainFilename; + /** + * Ignore warnings in the browser. + */ + ignoreBrowserWarnings?: boolean; /** * Wrap javascript code into IIFE's to avoid leaking into global scope. */ @@ -1999,7 +2194,7 @@ export interface Output { */ libraryExport?: LibraryExport; /** - * Type of library (types included by default are 'var', 'module', 'assign', 'assign-properties', 'this', 'window', 'self', 'global', 'commonjs', 'commonjs2', 'commonjs-module', 'amd', 'amd-require', 'umd', 'umd2', 'jsonp', 'system', but others might be added by plugins). + * Type of library (types included by default are 'var', 'module', 'assign', 'assign-properties', 'this', 'window', 'self', 'global', 'commonjs', 'commonjs2', 'commonjs-module', 'commonjs-static', 'amd', 'amd-require', 'umd', 'umd2', 'jsonp', 'system', but others might be added by plugins). */ libraryTarget?: LibraryType; /** @@ -2015,7 +2210,7 @@ export interface Output { */ pathinfo?: Pathinfo; /** - * The `publicPath` specifies the public URL address of the output files when referenced in a browser. + * The 'publicPath' specifies the public URL address of the output files when referenced in a browser. */ publicPath?: PublicPath; /** @@ -2038,6 +2233,10 @@ export interface Output { * Handles exceptions in module loading correctly at a performance cost (Deprecated). This will handle module error compatible with the Node.js CommonJS way. */ strictModuleExceptionHandling?: StrictModuleExceptionHandling; + /** + * Use a Trusted Types policy to create urls for chunks. 'output.uniqueName' is used a default policy name. Passing a string sets a custom policy name. + */ + trustedTypes?: true | string | TrustedTypes; /** * If `output.libraryTarget` is set to umd and `output.library` is set, setting this to true will name the AMD module. */ @@ -2055,9 +2254,13 @@ export interface Output { */ webassemblyModuleFilename?: WebassemblyModuleFilename; /** - * The method of loading chunks (methods included by default are 'jsonp' (web), 'importScripts' (WebWorker), 'require' (sync node.js), 'async-node' (async node.js), but others might be added by plugins). + * The method of loading chunks (methods included by default are 'jsonp' (web), 'import' (ESM), 'importScripts' (WebWorker), 'require' (sync node.js), 'async-node' (async node.js), but others might be added by plugins). */ workerChunkLoading?: ChunkLoading; + /** + * Worker public path. Much like the public path, this sets the location where the worker script file is intended to be found. If not set, webpack will use the publicPath. Don't set this option unless your worker scripts are located at a different path from your other script files. + */ + workerPublicPath?: WorkerPublicPath; /** * The method of loading WebAssembly Modules (methods included by default are 'fetch' (web/WebWorker), 'async-node' (node.js), but others might be added by plugins). */ @@ -2084,6 +2287,10 @@ export interface Environment { * The environment supports arrow functions ('() => { ... }'). */ arrowFunction?: boolean; + /** + * The environment supports async function and await ('async function () { await ... }'). + */ + asyncFunction?: boolean; /** * The environment supports BigInt as literal (123n). */ @@ -2096,18 +2303,55 @@ export interface Environment { * The environment supports destructuring ('{ a, b } = obj'). */ destructuring?: boolean; + /** + * The environment supports 'document'. + */ + document?: boolean; /** * The environment supports an async import() function to import EcmaScript modules. */ dynamicImport?: boolean; + /** + * The environment supports an async import() is available when creating a worker. + */ + dynamicImportInWorker?: boolean; /** * The environment supports 'for of' iteration ('for (const x of array) { ... }'). */ forOf?: boolean; + /** + * The environment supports 'globalThis'. + */ + globalThis?: boolean; /** * The environment supports EcmaScript Module syntax to import EcmaScript modules (import ... from '...'). */ module?: boolean; + /** + * The environment supports `node:` prefix for Node.js core modules. + */ + nodePrefixForCoreModules?: boolean; + /** + * The environment supports optional chaining ('obj?.a' or 'obj?.()'). + */ + optionalChaining?: boolean; + /** + * The environment supports template literals. + */ + templateLiteral?: boolean; +} +/** + * Use a Trusted Types policy to create urls for chunks. + */ +export interface TrustedTypes { + /** + * If the call to `trustedTypes.createPolicy(...)` fails -- e.g., due to the policy name missing from the CSP `trusted-types` list, or it being a duplicate name, etc. -- controls whether to continue with loading in the hope that `require-trusted-types-for 'script'` isn't enforced yet, versus fail immediately. Default behavior is 'stop'. + */ + onPolicyCreationFailure?: "continue" | "stop"; + /** + * The name of the Trusted Types policy created by webpack to serve bundle chunks. + */ + policyName?: string; } /** * Configuration object for web performance recommendations. @@ -2150,11 +2394,11 @@ export interface SnapshotOptions { /** * List of paths that are managed by a package manager and contain a version or hash in its path so all files are immutable. */ - immutablePaths?: string[]; + immutablePaths?: (RegExp | string)[]; /** * List of paths that are managed by a package manager and can be trusted to not be modified otherwise. */ - managedPaths?: string[]; + managedPaths?: (RegExp | string)[]; /** * Options for snapshotting dependencies of modules to determine if they need to be built again. */ @@ -2194,6 +2438,10 @@ export interface SnapshotOptions { */ timestamp?: boolean; }; + /** + * List of paths that are not managed by a package manager and the contents are subject to change. + */ + unmanagedPaths?: (RegExp | string)[]; } /** * Stats options object. @@ -2342,6 +2590,10 @@ export interface StatsOptions { * Add errors count. */ errorsCount?: boolean; + /** + * Space to display errors (value is in number of lines). + */ + errorsSpace?: number; /** * Please use excludeModules instead. */ @@ -2394,6 +2646,14 @@ export interface StatsOptions { * Group modules by their path. */ groupModulesByPath?: boolean; + /** + * Group modules by their type. + */ + groupModulesByType?: boolean; + /** + * Group reasons by their origin module. + */ + groupReasonsByOrigin?: boolean; /** * Add the hash of the compilation. */ @@ -2474,6 +2734,10 @@ export interface StatsOptions { * Add information about the reasons why modules are included. */ reasons?: boolean; + /** + * Space to display reasons (groups will be collapsed to fit this space). + */ + reasonsSpace?: number; /** * Add information about assets that are related to other assets (like SourceMaps for assets). */ @@ -2514,6 +2778,10 @@ export interface StatsOptions { * Suppress listing warnings that match the specified filters (they will still be counted). Filters can be Strings, RegExps or Functions. */ warningsFilter?: WarningFilterTypes; + /** + * Space to display warnings (value is in number of lines). + */ + warningsSpace?: number; } /** * Options for the watcher. @@ -2557,6 +2825,10 @@ export interface AssetGeneratorDataUrlOptions { * Generator options for asset/inline modules. */ export interface AssetInlineGeneratorOptions { + /** + * Whether or not this asset module should be considered binary. This can be set to 'false' to treat this asset module as text. + */ + binary?: boolean; /** * The options for data url generator. */ @@ -2584,6 +2856,10 @@ export interface AssetParserOptions { * Generator options for asset/resource modules. */ export interface AssetResourceGeneratorOptions { + /** + * Whether or not this asset module should be considered binary. This can be set to 'false' to treat this asset module as text. + */ + binary?: boolean; /** * Emit an output asset from this asset module. This can be set to 'false' to omit emitting e. g. for SSR. */ @@ -2592,6 +2868,126 @@ export interface AssetResourceGeneratorOptions { * Specifies the filename template of output files on disk. You must **not** specify an absolute path here, but the path may contain folders separated by '/'! The specified path is joined with the value of the 'output.path' option to determine the location on disk. */ filename?: FilenameTemplate; + /** + * Emit the asset in the specified folder relative to 'output.path'. This should only be needed when custom 'publicPath' is specified to match the folder structure there. + */ + outputPath?: AssetModuleOutputPath; + /** + * The 'publicPath' specifies the public URL address of the output files when referenced in a browser. + */ + publicPath?: RawPublicPath; +} +/** + * Generator options for css/auto modules. + */ +export interface CssAutoGeneratorOptions { + /** + * Configure the generated JS modules that use the ES modules syntax. + */ + esModule?: CssGeneratorEsModule; + /** + * Specifies the convention of exported names. + */ + exportsConvention?: CssGeneratorExportsConvention; + /** + * Avoid generating and loading a stylesheet and only embed exports from css into output javascript files. + */ + exportsOnly?: CssGeneratorExportsOnly; + /** + * Configure the generated local ident name. + */ + localIdentName?: CssGeneratorLocalIdentName; +} +/** + * Parser options for css/auto modules. + */ +export interface CssAutoParserOptions { + /** + * Use ES modules named export for css exports. + */ + namedExports?: CssParserNamedExports; +} +/** + * Generator options for css modules. + */ +export interface CssGeneratorOptions { + /** + * Configure the generated JS modules that use the ES modules syntax. + */ + esModule?: CssGeneratorEsModule; + /** + * Avoid generating and loading a stylesheet and only embed exports from css into output javascript files. + */ + exportsOnly?: CssGeneratorExportsOnly; +} +/** + * Generator options for css/global modules. + */ +export interface CssGlobalGeneratorOptions { + /** + * Configure the generated JS modules that use the ES modules syntax. + */ + esModule?: CssGeneratorEsModule; + /** + * Specifies the convention of exported names. + */ + exportsConvention?: CssGeneratorExportsConvention; + /** + * Avoid generating and loading a stylesheet and only embed exports from css into output javascript files. + */ + exportsOnly?: CssGeneratorExportsOnly; + /** + * Configure the generated local ident name. + */ + localIdentName?: CssGeneratorLocalIdentName; +} +/** + * Parser options for css/global modules. + */ +export interface CssGlobalParserOptions { + /** + * Use ES modules named export for css exports. + */ + namedExports?: CssParserNamedExports; +} +/** + * Generator options for css/module modules. + */ +export interface CssModuleGeneratorOptions { + /** + * Configure the generated JS modules that use the ES modules syntax. + */ + esModule?: CssGeneratorEsModule; + /** + * Specifies the convention of exported names. + */ + exportsConvention?: CssGeneratorExportsConvention; + /** + * Avoid generating and loading a stylesheet and only embed exports from css into output javascript files. + */ + exportsOnly?: CssGeneratorExportsOnly; + /** + * Configure the generated local ident name. + */ + localIdentName?: CssGeneratorLocalIdentName; +} +/** + * Parser options for css/module modules. + */ +export interface CssModuleParserOptions { + /** + * Use ES modules named export for css exports. + */ + namedExports?: CssParserNamedExports; +} +/** + * Parser options for css modules. + */ +export interface CssParserOptions { + /** + * Use ES modules named export for css exports. + */ + namedExports?: CssParserNamedExports; } /** * No generator options are supported for this module type. @@ -2606,7 +3002,15 @@ export interface EmptyParserOptions {} */ export interface EntryDescriptionNormalized { /** - * The method of loading chunks (methods included by default are 'jsonp' (web), 'importScripts' (WebWorker), 'require' (sync node.js), 'async-node' (async node.js), but others might be added by plugins). + * Enable/disable creating async chunks that are loaded on demand. + */ + asyncChunks?: boolean; + /** + * Base uri for this entry. + */ + baseUri?: string; + /** + * The method of loading chunks (methods included by default are 'jsonp' (web), 'import' (ESM), 'importScripts' (WebWorker), 'require' (sync node.js), 'async-node' (async node.js), but others might be added by plugins). */ chunkLoading?: ChunkLoading; /** @@ -2629,6 +3033,10 @@ export interface EntryDescriptionNormalized { * Options for library. */ library?: LibraryOptions; + /** + * The 'publicPath' specifies the public URL address of the output files when referenced in a browser. + */ + publicPath?: PublicPath; /** * The name of the runtime chunk. If set a runtime chunk with this name is created or an existing entrypoint is used as runtime. */ @@ -2647,6 +3055,43 @@ export interface EntryStaticNormalized { */ [k: string]: EntryDescriptionNormalized; } +/** + * Enables/Disables experiments (experimental features with relax SemVer compatibility). + */ +export interface ExperimentsCommon { + /** + * Support WebAssembly as asynchronous EcmaScript Module. + */ + asyncWebAssembly?: boolean; + /** + * Enable backward-compat layer with deprecation warnings for many webpack 4 APIs. + */ + backCompat?: boolean; + /** + * Enable additional in memory caching of modules that are unchanged and reference only unchanged modules. + */ + cacheUnaffected?: boolean; + /** + * Apply defaults of next major version. + */ + futureDefaults?: boolean; + /** + * Enable module layers. + */ + layers?: boolean; + /** + * Allow output javascript files as module source type. + */ + outputModule?: boolean; + /** + * Support WebAssembly as synchronous EcmaScript Module (outdated). + */ + syncWebAssembly?: boolean; + /** + * Allow using top-level-await in EcmaScript Modules. + */ + topLevelAwait?: boolean; +} /** * Data object passed as argument when a function is set for 'externals'. */ @@ -2659,6 +3104,10 @@ export interface ExternalItemFunctionData { * Contextual information. */ contextInfo?: import("../lib/ModuleFactory").ModuleFactoryCreateDataContextInfo; + /** + * The category of the referencing dependencies. + */ + dependencyType?: string; /** * Get a resolve function with the current resolver options. */ @@ -2676,6 +3125,35 @@ export interface ExternalItemFunctionData { */ request?: string; } +/** + * Options for building http resources. + */ +export interface HttpUriOptions { + /** + * List of allowed URIs (resp. the beginning of them). + */ + allowedUris: HttpUriOptionsAllowedUris; + /** + * Location where resource content is stored for lockfile entries. It's also possible to disable storing by passing false. + */ + cacheLocation?: false | string; + /** + * When set, anything that would lead to a modification of the lockfile or any resource content, will result in an error. + */ + frozen?: boolean; + /** + * Location of the lockfile. + */ + lockfileLocation?: string; + /** + * Proxy configuration, which can be used to specify a proxy server to use for HTTP requests. + */ + proxy?: string; + /** + * When set, resources of existing lockfile entries will be fetched and entries will be upgraded when resource content has changed. + */ + upgrade?: boolean; +} /** * Parser options for javascript modules. */ @@ -2696,6 +3174,30 @@ export interface JavascriptParserOptions { * Enable/disable parsing of magic comments in CommonJs syntax. */ commonjsMagicComments?: boolean; + /** + * Enable/disable parsing "import { createRequire } from "module"" and evaluating createRequire(). + */ + createRequire?: boolean | string; + /** + * Specifies global fetchPriority for dynamic import. + */ + dynamicImportFetchPriority?: "low" | "high" | "auto" | false; + /** + * Specifies global mode for dynamic import. + */ + dynamicImportMode?: "eager" | "weak" | "lazy" | "lazy-once"; + /** + * Specifies global prefetch for dynamic import. + */ + dynamicImportPrefetch?: number | boolean; + /** + * Specifies global preload for dynamic import. + */ + dynamicImportPreload?: number | boolean; + /** + * Specifies the behavior of invalid export names in "import ... from ..." and "export ... from ...". + */ + exportsPresence?: "error" | "warn" | "auto" | false; /** * Enable warnings for full dynamic dependencies. */ @@ -2720,10 +3222,30 @@ export interface JavascriptParserOptions { * Enable/disable parsing of import() syntax. */ import?: boolean; + /** + * Specifies the behavior of invalid export names in "import ... from ...". + */ + importExportsPresence?: "error" | "warn" | "auto" | false; + /** + * Enable/disable evaluating import.meta. + */ + importMeta?: boolean; + /** + * Enable/disable evaluating import.meta.webpackContext. + */ + importMetaContext?: boolean; /** * Include polyfills or mocks for various node stuff. */ node?: Node; + /** + * Override the module to strict or non-strict. This may affect the behavior of the module (some behaviors differ between strict and non-strict), so please configure this option carefully. + */ + overrideStrict?: "strict" | "non-strict"; + /** + * Specifies the behavior of invalid export names in "export ... from ...". This might be useful to disable during the migration from "export ... from ..." to "export type ... from ..." when reexporting types in TypeScript. + */ + reexportExportsPresence?: "error" | "warn" | "auto" | false; /** * Enable/disable parsing of require.context syntax. */ @@ -2741,7 +3263,7 @@ export interface JavascriptParserOptions { */ requireJs?: boolean; /** - * Emit errors instead of warnings when imported names don't exist in imported module. + * Deprecated in favor of "exportsPresence". Emit errors instead of warnings when imported names don't exist in imported module. */ strictExportPresence?: boolean; /** @@ -2790,6 +3312,66 @@ export interface JavascriptParserOptions { wrappedContextRegExp?: RegExp; [k: string]: any; } +/** + * Options for the default backend. + */ +export interface LazyCompilationDefaultBackendOptions { + /** + * A custom client. + */ + client?: string; + /** + * Specifies where to listen to from the server. + */ + listen?: + | number + | import("net").ListenOptions + | ((server: import("net").Server) => void); + /** + * Specifies the protocol the client should use to connect to the server. + */ + protocol?: "http" | "https"; + /** + * Specifies how to create the server handling the EventSource requests. + */ + server?: + | (import("https").ServerOptions | import("http").ServerOptions) + | (() => import("net").Server); +} +/** + * Options for compiling entrypoints and import()s only when they are accessed. + */ +export interface LazyCompilationOptions { + /** + * Specifies the backend that should be used for handling client keep alive. + */ + backend?: + | ( + | (( + compiler: import("../lib/Compiler"), + callback: ( + err?: Error, + api?: import("../lib/hmr/LazyCompilationPlugin").BackendApi + ) => void + ) => void) + | (( + compiler: import("../lib/Compiler") + ) => Promise) + ) + | LazyCompilationDefaultBackendOptions; + /** + * Enable/disable lazy compilation for entries. + */ + entries?: boolean; + /** + * Enable/disable lazy compilation for import() modules. + */ + imports?: boolean; + /** + * Specify which entrypoints or import()ed modules should be lazily compiled. This is matched with the imported module and not the entrypoint name. + */ + test?: RegExp | string | ((module: import("../lib/Module")) => boolean); +} /** * Options affecting the normal modules (`NormalModuleFactory`). */ @@ -2827,6 +3409,10 @@ export interface OutputNormalized { * The filename of asset modules as relative path inside the 'output.path' directory. */ assetModuleFilename?: AssetModuleFilename; + /** + * Enable/disable creating async chunks that are loaded on demand. + */ + asyncChunks?: boolean; /** * Add charset attribute for script tag. */ @@ -2836,7 +3422,7 @@ export interface OutputNormalized { */ chunkFilename?: ChunkFilename; /** - * The format of chunks (formats included by default are 'array-push' (web/WebWorker), 'commonjs' (node.js), but others might be added by plugins). + * The format of chunks (formats included by default are 'array-push' (web/WebWorker), 'commonjs' (node.js), 'module' (ESM), but others might be added by plugins). */ chunkFormat?: ChunkFormat; /** @@ -2844,7 +3430,7 @@ export interface OutputNormalized { */ chunkLoadTimeout?: ChunkLoadTimeout; /** - * The method of loading chunks (methods included by default are 'jsonp' (web), 'importScripts' (WebWorker), 'require' (sync node.js), 'async-node' (async node.js), but others might be added by plugins). + * The method of loading chunks (methods included by default are 'jsonp' (web), 'import' (ESM), 'importScripts' (WebWorker), 'require' (sync node.js), 'async-node' (async node.js), but others might be added by plugins). */ chunkLoading?: ChunkLoading; /** @@ -2863,6 +3449,18 @@ export interface OutputNormalized { * This option enables cross-origin loading of chunks. */ crossOriginLoading?: CrossOriginLoading; + /** + * Specifies the filename template of non-initial output css files on disk. You must **not** specify an absolute path here, but the path may contain folders separated by '/'! The specified path is joined with the value of the 'output.path' option to determine the location on disk. + */ + cssChunkFilename?: CssChunkFilename; + /** + * Specifies the filename template of output css files on disk. You must **not** specify an absolute path here, but the path may contain folders separated by '/'! The specified path is joined with the value of the 'output.path' option to determine the location on disk. + */ + cssFilename?: CssFilename; + /** + * Compress the data in the head tag of CSS files. + */ + cssHeadDataCompression?: CssHeadDataCompression; /** * Similar to `output.devtoolModuleFilenameTemplate`, but used in the case of duplicate module identifiers. */ @@ -2927,6 +3525,10 @@ export interface OutputNormalized { * The filename of the Hot Update Main File. It is inside the 'output.path' directory. */ hotUpdateMainFilename?: HotUpdateMainFilename; + /** + * Ignore warnings in the browser. + */ + ignoreBrowserWarnings?: boolean; /** * Wrap javascript code into IIFE's to avoid leaking into global scope. */ @@ -2956,7 +3558,7 @@ export interface OutputNormalized { */ pathinfo?: Pathinfo; /** - * The `publicPath` specifies the public URL address of the output files when referenced in a browser. + * The 'publicPath' specifies the public URL address of the output files when referenced in a browser. */ publicPath?: PublicPath; /** @@ -2979,6 +3581,10 @@ export interface OutputNormalized { * Handles exceptions in module loading correctly at a performance cost (Deprecated). This will handle module error compatible with the Node.js CommonJS way. */ strictModuleExceptionHandling?: StrictModuleExceptionHandling; + /** + * Use a Trusted Types policy to create urls for chunks. + */ + trustedTypes?: TrustedTypes; /** * A unique name of the webpack build to avoid multiple webpack runtimes to conflict when using globals. */ @@ -2992,9 +3598,13 @@ export interface OutputNormalized { */ webassemblyModuleFilename?: WebassemblyModuleFilename; /** - * The method of loading chunks (methods included by default are 'jsonp' (web), 'importScripts' (WebWorker), 'require' (sync node.js), 'async-node' (async node.js), but others might be added by plugins). + * The method of loading chunks (methods included by default are 'jsonp' (web), 'import' (ESM), 'importScripts' (WebWorker), 'require' (sync node.js), 'async-node' (async node.js), but others might be added by plugins). */ workerChunkLoading?: ChunkLoading; + /** + * Worker public path. Much like the public path, this sets the location where the worker script file is intended to be found. If not set, webpack will use the publicPath. Don't set this option unless your worker scripts are located at a different path from your other script files. + */ + workerPublicPath?: WorkerPublicPath; /** * The method of loading WebAssembly Modules (methods included by default are 'fetch' (web/WebWorker), 'async-node' (node.js), but others might be added by plugins). */ @@ -3039,7 +3649,7 @@ export interface WebpackOptionsNormalized { /** * Enables/Disables experiments (experimental features with relax SemVer compatibility). */ - experiments: Experiments; + experiments: ExperimentsNormalized; /** * Specify dependencies that shouldn't be resolved by webpack, but should become dependencies of the resulting bundle. The kind of the dependency depends on `output.libraryTarget`. */ @@ -3141,6 +3751,40 @@ export interface WebpackOptionsNormalized { */ watchOptions: WatchOptions; } +/** + * Enables/Disables experiments (experimental features with relax SemVer compatibility). + */ +export interface ExperimentsExtra { + /** + * Build http(s): urls using a lockfile and resource content cache. + */ + buildHttp?: HttpUriAllowedUris | HttpUriOptions; + /** + * Enable css support. + */ + css?: boolean; + /** + * Compile entrypoints and import()s only when they are accessed. + */ + lazyCompilation?: boolean | LazyCompilationOptions; +} +/** + * Enables/Disables experiments (experimental features with relax SemVer compatibility). + */ +export interface ExperimentsNormalizedExtra { + /** + * Build http(s): urls using a lockfile and resource content cache. + */ + buildHttp?: HttpUriOptions; + /** + * Enable css support. + */ + css?: boolean; + /** + * Compile entrypoints and import()s only when they are accessed. + */ + lazyCompilation?: false | LazyCompilationOptions; +} /** * If an dependency matches exactly a property of the object, the property value is used as dependency. */ @@ -3176,6 +3820,22 @@ export interface GeneratorOptionsByModuleTypeKnown { * Generator options for asset/resource modules. */ "asset/resource"?: AssetResourceGeneratorOptions; + /** + * Generator options for css modules. + */ + css?: CssGeneratorOptions; + /** + * Generator options for css/auto modules. + */ + "css/auto"?: CssAutoGeneratorOptions; + /** + * Generator options for css/global modules. + */ + "css/global"?: CssGlobalGeneratorOptions; + /** + * Generator options for css/module modules. + */ + "css/module"?: CssModuleGeneratorOptions; /** * No generator options are supported for this module type. */ @@ -3224,6 +3884,22 @@ export interface ParserOptionsByModuleTypeKnown { * No parser options are supported for this module type. */ "asset/source"?: EmptyParserOptions; + /** + * Parser options for css modules. + */ + css?: CssParserOptions; + /** + * Parser options for css/auto modules. + */ + "css/auto"?: CssAutoParserOptions; + /** + * Parser options for css/global modules. + */ + "css/global"?: CssGlobalParserOptions; + /** + * Parser options for css/module modules. + */ + "css/module"?: CssModuleParserOptions; /** * Parser options for javascript modules. */ diff --git a/declarations/_container.d.ts b/declarations/_container.d.ts deleted file mode 100644 index 912089e9f46..00000000000 --- a/declarations/_container.d.ts +++ /dev/null @@ -1,78 +0,0 @@ -/* - * This file was automatically generated. - * DO NOT MODIFY BY HAND. - * Run `yarn special-lint-fix` to update - */ - -/** - * Modules that should be exposed by this container. When provided, property name is used as public name, otherwise public name is automatically inferred from request. - */ -export type Exposes = (ExposesItem | ExposesObject)[] | ExposesObject; -/** - * Module that should be exposed by this container. - */ -export type ExposesItem = string; -/** - * Modules that should be exposed by this container. - */ -export type ExposesItems = ExposesItem[]; -/** - * Container locations and request scopes from which modules should be resolved and loaded at runtime. When provided, property name is used as request scope, otherwise request scope is automatically inferred from container location. - */ -export type Remotes = (RemotesItem | RemotesObject)[] | RemotesObject; -/** - * Container location from which modules should be resolved and loaded at runtime. - */ -export type RemotesItem = string; -/** - * Container locations from which modules should be resolved and loaded at runtime. - */ -export type RemotesItems = RemotesItem[]; - -export interface _Container { - [k: string]: any; -} -/** - * Modules that should be exposed by this container. Property names are used as public paths. - */ -export interface ExposesObject { - /** - * Modules that should be exposed by this container. - */ - [k: string]: ExposesConfig | ExposesItem | ExposesItems; -} -/** - * Advanced configuration for modules that should be exposed by this container. - */ -export interface ExposesConfig { - /** - * Request to a module that should be exposed by this container. - */ - import: ExposesItem | ExposesItems; - /** - * Custom chunk name for the exposed module. - */ - name?: string; -} -/** - * Container locations from which modules should be resolved and loaded at runtime. Property names are used as request scopes. - */ -export interface RemotesObject { - /** - * Container locations from which modules should be resolved and loaded at runtime. - */ - [k: string]: RemotesConfig | RemotesItem | RemotesItems; -} -/** - * Advanced configuration for container locations from which modules should be resolved and loaded at runtime. - */ -export interface RemotesConfig { - /** - * Container locations from which modules should be resolved and loaded at runtime. - */ - external: RemotesItem | RemotesItems; - /** - * The name of the share scope shared with this remote. - */ - shareScope?: string; -} diff --git a/declarations/_sharing.d.ts b/declarations/_sharing.d.ts deleted file mode 100644 index 88084d43b35..00000000000 --- a/declarations/_sharing.d.ts +++ /dev/null @@ -1,68 +0,0 @@ -/* - * This file was automatically generated. - * DO NOT MODIFY BY HAND. - * Run `yarn special-lint-fix` to update - */ - -/** - * Modules that should be shared in the share scope. When provided, property names are used to match requested modules in this compilation. - */ -export type Shared = (SharedItem | SharedObject)[] | SharedObject; -/** - * A module that should be shared in the share scope. - */ -export type SharedItem = string; - -export interface _Sharing { - [k: string]: any; -} -/** - * Modules that should be shared in the share scope. Property names are used to match requested modules in this compilation. Relative requests are resolved, module requests are matched unresolved, absolute paths will match resolved requests. A trailing slash will match all requests with this prefix. In this case shareKey must also have a trailing slash. - */ -export interface SharedObject { - /** - * Modules that should be shared in the share scope. - */ - [k: string]: SharedConfig | SharedItem; -} -/** - * Advanced configuration for modules that should be shared in the share scope. - */ -export interface SharedConfig { - /** - * Include the provided and fallback module directly instead behind an async request. This allows to use this shared module in initial load too. All possible shared modules need to be eager too. - */ - eager?: boolean; - /** - * Provided module that should be provided to share scope. Also acts as fallback module if no shared module is found in share scope or version isn't valid. Defaults to the property name. - */ - import?: false | SharedItem; - /** - * Package name to determine required version from description file. This is only needed when package name can't be automatically determined from request. - */ - packageName?: string; - /** - * Version requirement from module in share scope. - */ - requiredVersion?: false | string; - /** - * Module is looked up under this key from the share scope. - */ - shareKey?: string; - /** - * Share scope name. - */ - shareScope?: string; - /** - * Allow only a single version of the shared module in share scope (disabled by default). - */ - singleton?: boolean; - /** - * Do not accept shared module if version is not valid (defaults to yes, if local fallback module is available and shared module is not a singleton, otherwise no, has no effect if there is no required version specified). - */ - strictVersion?: boolean; - /** - * Version of the provided module. Will replace lower matching versions, but not higher. - */ - version?: false | string; -} diff --git a/declarations/index.d.ts b/declarations/index.d.ts new file mode 100644 index 00000000000..a9475f0809c --- /dev/null +++ b/declarations/index.d.ts @@ -0,0 +1,9 @@ +export type { + LoaderModule, + RawLoaderDefinition, + LoaderDefinition, + LoaderDefinitionFunction, + PitchLoaderDefinitionFunction, + RawLoaderDefinitionFunction, + LoaderContext +} from "./LoaderContext"; diff --git a/declarations/plugins/BannerPlugin.d.ts b/declarations/plugins/BannerPlugin.d.ts index 0a4511c376f..d42d50d6576 100644 --- a/declarations/plugins/BannerPlugin.d.ts +++ b/declarations/plugins/BannerPlugin.d.ts @@ -12,7 +12,7 @@ export type BannerPluginArgument = * The banner as function, it will be wrapped in a comment. */ export type BannerFunction = (data: { - hash: string; + hash?: string; chunk: import("../../lib/Chunk"); filename: string; }) => string; @@ -38,6 +38,10 @@ export interface BannerPluginOptions { * Exclude all modules matching any of these conditions. */ exclude?: Rules; + /** + * If true, banner will be placed at the end of the output. + */ + footer?: boolean; /** * Include all modules matching any of these conditions. */ @@ -46,6 +50,10 @@ export interface BannerPluginOptions { * If true, banner will not be wrapped in a comment. */ raw?: boolean; + /** + * Specifies the banner. + */ + stage?: number; /** * Include all modules that pass test assertion. */ diff --git a/declarations/plugins/HashedModuleIdsPlugin.d.ts b/declarations/plugins/HashedModuleIdsPlugin.d.ts index 931c0bd6036..faea6fb5031 100644 --- a/declarations/plugins/HashedModuleIdsPlugin.d.ts +++ b/declarations/plugins/HashedModuleIdsPlugin.d.ts @@ -4,6 +4,11 @@ * Run `yarn special-lint-fix` to update */ +/** + * Algorithm used for generation the hash (see node.js crypto package). + */ +export type HashFunction = string | typeof import("../../lib/util/Hash"); + export interface HashedModuleIdsPluginOptions { /** * The context directory for creating names. @@ -20,5 +25,5 @@ export interface HashedModuleIdsPluginOptions { /** * The hashing algorithm to use, defaults to 'md4'. All functions from Node.JS' crypto.createHash are supported. */ - hashFunction?: string; + hashFunction?: HashFunction; } diff --git a/declarations/plugins/IgnorePlugin.d.ts b/declarations/plugins/IgnorePlugin.d.ts index e71e3b1e1ff..281504f9f90 100644 --- a/declarations/plugins/IgnorePlugin.d.ts +++ b/declarations/plugins/IgnorePlugin.d.ts @@ -13,11 +13,11 @@ export type IgnorePluginOptions = /** * A RegExp to test the request against. */ - resourceRegExp?: RegExp; + resourceRegExp: RegExp; } | { /** * A filter function for resource and context. */ - checkResource?: (resource: string, context: string) => boolean; + checkResource: (resource: string, context: string) => boolean; }; diff --git a/declarations/plugins/SourceMapDevToolPlugin.d.ts b/declarations/plugins/SourceMapDevToolPlugin.d.ts index c9f8b431c05..e0104874453 100644 --- a/declarations/plugins/SourceMapDevToolPlugin.d.ts +++ b/declarations/plugins/SourceMapDevToolPlugin.d.ts @@ -17,7 +17,13 @@ export interface SourceMapDevToolPluginOptions { /** * Appends the given value to the original asset. Usually the #sourceMappingURL comment. [url] is replaced with a URL to the source map file. false disables the appending. */ - append?: (false | null) | string; + append?: + | (false | null) + | string + | (( + pathData: import("../../lib/Compilation").PathData, + assetInfo?: import("../../lib/Compilation").AssetInfo + ) => string); /** * Indicates whether column mappings should be used (defaults to true). */ diff --git a/declarations/plugins/container/ContainerPlugin.d.ts b/declarations/plugins/container/ContainerPlugin.d.ts index 3c47757ba41..f0c0608a0cf 100644 --- a/declarations/plugins/container/ContainerPlugin.d.ts +++ b/declarations/plugins/container/ContainerPlugin.d.ts @@ -16,6 +16,10 @@ export type ExposesItem = string; * Modules that should be exposed by this container. */ export type ExposesItems = ExposesItem[]; +/** + * Add a container for define/require functions in the AMD module. + */ +export type AmdContainer = string; /** * Add a comment in the UMD wrapper. */ @@ -29,7 +33,7 @@ export type LibraryExport = string[] | string; */ export type LibraryName = string[] | string | LibraryCustomUmdObject; /** - * Type of library (types included by default are 'var', 'module', 'assign', 'assign-properties', 'this', 'window', 'self', 'global', 'commonjs', 'commonjs2', 'commonjs-module', 'amd', 'amd-require', 'umd', 'umd2', 'jsonp', 'system', but others might be added by plugins). + * Type of library (types included by default are 'var', 'module', 'assign', 'assign-properties', 'this', 'window', 'self', 'global', 'commonjs', 'commonjs2', 'commonjs-module', 'commonjs-static', 'amd', 'amd-require', 'umd', 'umd2', 'jsonp', 'system', but others might be added by plugins). */ export type LibraryType = | ( @@ -44,6 +48,7 @@ export type LibraryType = | "commonjs" | "commonjs2" | "commonjs-module" + | "commonjs-static" | "amd" | "amd-require" | "umd" @@ -56,6 +61,10 @@ export type LibraryType = * If `output.libraryTarget` is set to umd and `output.library` is set, setting this to true will name the AMD module. */ export type UmdNamedDefine = boolean; +/** + * The name of the runtime chunk. If set a runtime chunk with this name is created or an existing entrypoint is used as runtime. + */ +export type EntryRuntime = false | string; export interface ContainerPluginOptions { /** @@ -74,6 +83,10 @@ export interface ContainerPluginOptions { * The name for this container. */ name: string; + /** + * The name of the runtime chunk. If set a runtime chunk with this name is created or an existing entrypoint is used as runtime. + */ + runtime?: EntryRuntime; /** * The name of the share scope which is shared with the host (defaults to 'default'). */ @@ -105,6 +118,10 @@ export interface ExposesConfig { * Options for library. */ export interface LibraryOptions { + /** + * Add a container for define/require functions in the AMD module. + */ + amdContainer?: AmdContainer; /** * Add a comment in the UMD wrapper. */ @@ -118,7 +135,7 @@ export interface LibraryOptions { */ name?: LibraryName; /** - * Type of library (types included by default are 'var', 'module', 'assign', 'assign-properties', 'this', 'window', 'self', 'global', 'commonjs', 'commonjs2', 'commonjs-module', 'amd', 'amd-require', 'umd', 'umd2', 'jsonp', 'system', but others might be added by plugins). + * Type of library (types included by default are 'var', 'module', 'assign', 'assign-properties', 'this', 'window', 'self', 'global', 'commonjs', 'commonjs2', 'commonjs-module', 'commonjs-static', 'amd', 'amd-require', 'umd', 'umd2', 'jsonp', 'system', but others might be added by plugins). */ type: LibraryType; /** diff --git a/declarations/plugins/container/ContainerReferencePlugin.d.ts b/declarations/plugins/container/ContainerReferencePlugin.d.ts index c81cad2481a..3ac0dbb63d0 100644 --- a/declarations/plugins/container/ContainerReferencePlugin.d.ts +++ b/declarations/plugins/container/ContainerReferencePlugin.d.ts @@ -18,6 +18,7 @@ export type ExternalsType = | "commonjs" | "commonjs2" | "commonjs-module" + | "commonjs-static" | "amd" | "amd-require" | "umd" @@ -26,7 +27,9 @@ export type ExternalsType = | "system" | "promise" | "import" - | "script"; + | "module-import" + | "script" + | "node-commonjs"; /** * Container locations and request scopes from which modules should be resolved and loaded at runtime. When provided, property name is used as request scope, otherwise request scope is automatically inferred from container location. */ diff --git a/declarations/plugins/container/ModuleFederationPlugin.d.ts b/declarations/plugins/container/ModuleFederationPlugin.d.ts index 40c9e4f9a61..e2a99e19736 100644 --- a/declarations/plugins/container/ModuleFederationPlugin.d.ts +++ b/declarations/plugins/container/ModuleFederationPlugin.d.ts @@ -16,6 +16,10 @@ export type ExposesItem = string; * Modules that should be exposed by this container. */ export type ExposesItems = ExposesItem[]; +/** + * Add a container for define/require functions in the AMD module. + */ +export type AmdContainer = string; /** * Add a comment in the UMD wrapper. */ @@ -29,7 +33,7 @@ export type LibraryExport = string[] | string; */ export type LibraryName = string[] | string | LibraryCustomUmdObject; /** - * Type of library (types included by default are 'var', 'module', 'assign', 'assign-properties', 'this', 'window', 'self', 'global', 'commonjs', 'commonjs2', 'commonjs-module', 'amd', 'amd-require', 'umd', 'umd2', 'jsonp', 'system', but others might be added by plugins). + * Type of library (types included by default are 'var', 'module', 'assign', 'assign-properties', 'this', 'window', 'self', 'global', 'commonjs', 'commonjs2', 'commonjs-module', 'commonjs-static', 'amd', 'amd-require', 'umd', 'umd2', 'jsonp', 'system', but others might be added by plugins). */ export type LibraryType = | ( @@ -44,6 +48,7 @@ export type LibraryType = | "commonjs" | "commonjs2" | "commonjs-module" + | "commonjs-static" | "amd" | "amd-require" | "umd" @@ -70,6 +75,7 @@ export type ExternalsType = | "commonjs" | "commonjs2" | "commonjs-module" + | "commonjs-static" | "amd" | "amd-require" | "umd" @@ -78,7 +84,9 @@ export type ExternalsType = | "system" | "promise" | "import" - | "script"; + | "module-import" + | "script" + | "node-commonjs"; /** * Container locations and request scopes from which modules should be resolved and loaded at runtime. When provided, property name is used as request scope, otherwise request scope is automatically inferred from container location. */ @@ -91,6 +99,10 @@ export type RemotesItem = string; * Container locations from which modules should be resolved and loaded at runtime. */ export type RemotesItems = RemotesItem[]; +/** + * The name of the runtime chunk. If set a runtime chunk with this name is created or an existing entrypoint is used as runtime. + */ +export type EntryRuntime = false | string; /** * Modules that should be shared in the share scope. When provided, property names are used to match requested modules in this compilation. */ @@ -125,6 +137,10 @@ export interface ModuleFederationPluginOptions { * Container locations and request scopes from which modules should be resolved and loaded at runtime. When provided, property name is used as request scope, otherwise request scope is automatically inferred from container location. */ remotes?: Remotes; + /** + * The name of the runtime chunk. If set a runtime chunk with this name is created or an existing entrypoint is used as runtime. + */ + runtime?: EntryRuntime; /** * Share scope name used for all shared modules (defaults to 'default'). */ @@ -160,6 +176,10 @@ export interface ExposesConfig { * Options for library. */ export interface LibraryOptions { + /** + * Add a container for define/require functions in the AMD module. + */ + amdContainer?: AmdContainer; /** * Add a comment in the UMD wrapper. */ @@ -173,7 +193,7 @@ export interface LibraryOptions { */ name?: LibraryName; /** - * Type of library (types included by default are 'var', 'module', 'assign', 'assign-properties', 'this', 'window', 'self', 'global', 'commonjs', 'commonjs2', 'commonjs-module', 'amd', 'amd-require', 'umd', 'umd2', 'jsonp', 'system', but others might be added by plugins). + * Type of library (types included by default are 'var', 'module', 'assign', 'assign-properties', 'this', 'window', 'self', 'global', 'commonjs', 'commonjs2', 'commonjs-module', 'commonjs-static', 'amd', 'amd-require', 'umd', 'umd2', 'jsonp', 'system', but others might be added by plugins). */ type: LibraryType; /** diff --git a/declarations/plugins/schemes/HttpUriPlugin.d.ts b/declarations/plugins/schemes/HttpUriPlugin.d.ts new file mode 100644 index 00000000000..2d0e869831b --- /dev/null +++ b/declarations/plugins/schemes/HttpUriPlugin.d.ts @@ -0,0 +1,45 @@ +/* + * This file was automatically generated. + * DO NOT MODIFY BY HAND. + * Run `yarn special-lint-fix` to update + */ + +export type HttpUriPluginOptions = HttpUriOptions; +/** + * List of allowed URIs (resp. the beginning of them). + */ +export type HttpUriOptionsAllowedUris = ( + | RegExp + | string + | ((uri: string) => boolean) +)[]; + +/** + * Options for building http resources. + */ +export interface HttpUriOptions { + /** + * List of allowed URIs (resp. the beginning of them). + */ + allowedUris: HttpUriOptionsAllowedUris; + /** + * Location where resource content is stored for lockfile entries. It's also possible to disable storing by passing false. + */ + cacheLocation?: false | string; + /** + * When set, anything that would lead to a modification of the lockfile or any resource content, will result in an error. + */ + frozen?: boolean; + /** + * Location of the lockfile. + */ + lockfileLocation?: string; + /** + * Proxy configuration, which can be used to specify a proxy server to use for HTTP requests. + */ + proxy?: string; + /** + * When set, resources of existing lockfile entries will be fetched and entries will be upgraded when resource content has changed. + */ + upgrade?: boolean; +} diff --git a/eslint.config.js b/eslint.config.js new file mode 100644 index 00000000000..ce34ca4f482 --- /dev/null +++ b/eslint.config.js @@ -0,0 +1,432 @@ +const js = require("@eslint/js"); +const prettier = require("eslint-plugin-prettier"); +const n = require("eslint-plugin-n"); +const jest = require("eslint-plugin-jest"); +const jsdoc = require("eslint-plugin-jsdoc"); +const prettierConfig = require("eslint-config-prettier"); +const globals = require("globals"); +const stylistic = require("@stylistic/eslint-plugin"); +const unicorn = require("eslint-plugin-unicorn"); + +const nodeConfig = n.configs["flat/recommended"]; +const jsdocConfig = jsdoc.configs["flat/recommended-typescript-flavor-error"]; + +module.exports = [ + { + ignores: [ + // Ignore some test files + "test/**/*.*", + "!test/*.js", + "!test/**/webpack.config.js", + "!test/**/test.config.js", + "!test/**/test.filter.js", + "test/cases/parsing/es2022/test.filter.js", + "!test/**/errors.js", + "!test/**/warnings.js", + "!test/**/deprecations.js", + "!test/helpers/*.*", + + // Ignore some folders + "benchmark", + "coverage", + + // Ignore generated files + "*.check.js", + + // Ignore not supported files + "*.d.ts", + + // Ignore precompiled schemas + "schemas/**/*.check.js", + + // Auto generation + "lib/util/semver.js", + + // Ignore some examples files + "examples/**/*.js", + "examples/**/*.mjs", + "!examples/*/webpack.config.js" + ] + }, + { + ...js.configs.recommended, + languageOptions: { + ecmaVersion: 2018, + globals: { + ...globals.node, + ...globals.es2018, + WebAssembly: true + } + }, + linterOptions: { + reportUnusedDisableDirectives: true + }, + rules: { + ...js.configs.recommended.rules, + "no-template-curly-in-string": "error", + "no-caller": "error", + "no-control-regex": "off", + yoda: "error", + eqeqeq: "error", + "eol-last": "error", + "no-extra-bind": "warn", + "no-process-exit": "warn", + "no-use-before-define": "off", + "no-unused-vars": [ + "error", + { + vars: "all", + varsIgnorePattern: "^_", + args: "none", + argsIgnorePattern: "^_", + caughtErrors: "all", + caughtErrorsIgnorePattern: "^_", + ignoreRestSiblings: true + } + ], + "no-inner-declarations": "error", + "prefer-const": [ + "error", + { + destructuring: "all", + ignoreReadBeforeAssign: true + } + ], + "object-shorthand": "error", + "no-else-return": "error", + "no-lonely-if": "error", + "no-undef-init": "error", + // Disallow @ts-ignore directive. Use @ts-expect-error instead + "no-warning-comments": [ + "error", + { terms: ["@ts-ignore"], location: "start" } + ], + "no-constructor-return": "error", + "symbol-description": "error", + "array-callback-return": [ + "error", + { + allowImplicit: true + } + ], + "no-promise-executor-return": "error", + "no-undef": "error", + "guard-for-in": "error", + "no-constant-condition": "error", + camelcase: [ + "error", + { + allow: [ + "__webpack_require__", + "__webpack_public_path__", + "__webpack_base_uri__", + "__webpack_modules__", + "__webpack_chunk_load__", + "__non_webpack_require__", + "__webpack_nonce__", + "__webpack_hash__", + "__webpack_chunkname__", + "__webpack_get_script_filename__", + "__webpack_runtime_id__", + "__system_context__", + "__webpack_share_scopes__", + "__webpack_init_sharing__", + "__webpack_require_module__", + "_stream_duplex", + "_stream_passthrough", + "_stream_readable", + "_stream_transform", + "_stream_writable", + "string_decoder" + ] + } + ], + "prefer-exponentiation-operator": "error", + "no-useless-return": "error", + "no-return-assign": "error", + "default-case-last": "error", + "default-param-last": "error", + "dot-notation": "error", + "grouped-accessor-pairs": "error", + "id-match": [ + "error", + "^[$a-zA-Z_][$a-zA-Z0-9_]*$", + { + properties: true + } + ], + "no-extra-label": "error", + "no-label-var": "error", + "no-lone-blocks": "error", + "no-multi-str": "error", + "no-new-func": "error", + "no-unneeded-ternary": ["error", { defaultAssignment: false }], + "no-useless-call": "error", + "no-useless-concat": "error", + "prefer-object-spread": "error", + "prefer-regex-literals": "error", + "prefer-rest-params": "error", + "no-var": "error", + "one-var": ["error", "never"], + "prefer-template": "error", + "no-implicit-coercion": [ + "error", + { + boolean: true, + number: true, + string: true + } + ], + "arrow-body-style": ["error", "as-needed"], + "new-cap": [ + "error", + { + newIsCapExceptions: [], + capIsNewExceptions: ["A", "F", "D", "MODULES_GROUPERS"] + } + ], + "func-style": [ + "error", + "declaration", + { + allowArrowFunctions: true + } + ], + "no-loop-func": "error", + "no-unreachable-loop": "error", + "no-unmodified-loop-condition": "error", + "prefer-spread": "error", + "no-sequences": "error", + // TODO Enable + "id-length": "off", + "prefer-destructuring": "off" + } + }, + { + plugins: { + unicorn + }, + rules: { + "unicorn/catch-error-name": [ + "error", + { name: "err", ignore: [/(^_|[0-9]+$)/i] } + ], + "unicorn/prefer-includes": "error", + "unicorn/no-zero-fractions": "error", + "unicorn/prefer-string-starts-ends-with": "error", + "unicorn/prefer-default-parameters": "error", + "unicorn/prefer-negative-index": "error", + "unicorn/prefer-ternary": ["error", "only-single-line"], + "unicorn/prefer-array-find": "error", + "unicorn/no-lonely-if": "error", + "unicorn/no-hex-escape": "error", + "unicorn/escape-case": "error", + "unicorn/no-array-for-each": "error", + "unicorn/prefer-number-properties": "error", + "unicorn/prefer-native-coercion-functions": "error", + // TODO Enable + "unicorn/prefer-spread": "off" + } + }, + { + plugins: { + "@stylistic": stylistic + }, + rules: { + "@stylistic/lines-between-class-members": "error", + "@stylistic/quotes": [ + "error", + "double", + { avoidEscape: true, allowTemplateLiterals: false } + ], + "@stylistic/spaced-comment": [ + "error", + "always", + { + line: { + markers: ["=", "!"], // Space here to support sprockets directives + exceptions: ["-", "+"] + }, + block: { + markers: ["=", "!"], // Space here to support sprockets directives + exceptions: ["-", "+"], + balanced: true + } + } + ] + } + }, + { + ...nodeConfig, + rules: { + ...nodeConfig.rules, + "n/no-missing-require": ["error", { allowModules: ["webpack"] }], + "n/no-unsupported-features/node-builtins": [ + "error", + { + ignores: ["zlib.createBrotliCompress", "zlib.createBrotliDecompress"] + } + ], + "n/exports-style": "error" + } + }, + { + ...jsdocConfig, + settings: { + jsdoc: { + mode: "typescript", + // supported tags https://github.com/microsoft/TypeScript-wiki/blob/master/JSDoc-support-in-JavaScript.md + tagNamePreference: { + ...["implements", "const", "memberof", "yields"].reduce( + (acc, tag) => { + acc[tag] = { + message: `@${tag} currently not supported in TypeScript` + }; + return acc; + }, + {} + ), + extends: "extends", + return: "returns", + constructor: "constructor", + prop: "property", + arg: "param", + augments: "extends", + description: false, + desc: false, + inheritdoc: false, + class: "constructor" + }, + overrideReplacesDocs: false + } + }, + rules: { + ...jsdocConfig.rules, + // Override recommended + // TODO remove me after switch to typescript strict mode + "jsdoc/require-jsdoc": "off", + // Doesn't support function overloading/tuples/`readonly`/module keyword/etc + // Also `typescript` reports this itself + "jsdoc/valid-types": "off", + // A lot of false positive with loops/`switch`/`if`/etc + "jsdoc/require-returns-check": "off", + // TODO fix and enable in future + "jsdoc/require-property-description": "off", + + // More rules + "jsdoc/check-indentation": "error", + "jsdoc/no-bad-blocks": "error", + "jsdoc/require-hyphen-before-param-description": ["error", "never"], + "jsdoc/require-template": "error", + "jsdoc/no-blank-block-descriptions": "error", + "jsdoc/no-blank-blocks": "error", + "jsdoc/require-asterisk-prefix": "error" + } + }, + { + files: ["bin/**/*.js"], + // Allow to use `dynamic` import + languageOptions: { + ecmaVersion: 2020 + }, + rules: { + "n/no-unsupported-features/es-syntax": [ + "error", + { + ignores: ["hashbang", "dynamic-import"] + } + ] + } + }, + { + files: ["lib/**/*.runtime.js", "hot/*.js"], + languageOptions: { + ecmaVersion: 5, + globals: { + ...globals.browser, + ...globals.es5 + } + }, + rules: { + "prefer-const": "off", + "object-shorthand": "off", + "no-undef-init": "off", + "no-var": "off", + "n/exports-style": "off", + "prefer-template": "off", + "no-implicit-coercion": "off", + "func-style": "off", + "unicorn/prefer-includes": "off", + "unicorn/no-useless-undefined": "off", + "unicorn/no-array-for-each": "off" + } + }, + { + files: ["tooling/**/*.js"], + languageOptions: { + ecmaVersion: 2020, + globals: { + ...globals.es2020 + } + } + }, + { + ...jest.configs["flat/recommended"], + files: ["test/**/*.js"], + languageOptions: { + ecmaVersion: 2020, + globals: { + ...globals.jest, + nsObj: false + } + }, + rules: { + ...jest.configs["flat/recommended"].rules, + "jest/no-standalone-expect": "off", + "jest/valid-title": [ + "error", + { + ignoreTypeOfDescribeName: true, + ignoreTypeOfTestName: true + } + ], + "jest/no-done-callback": "off", + "jest/expect-expect": "off", + "jest/no-conditional-expect": "off", + "n/no-unsupported-features/node-builtins": [ + "error", + { + allowExperimental: true + } + ], + "object-shorthand": "off", + camelcase: "off", + "no-var": "off" + } + }, + { + files: [ + "test/configCases/{dll-plugin-entry,dll-plugin-side-effects,dll-plugin}/**/webpack.config.js" + ], + rules: { + "n/no-missing-require": "off" + } + }, + { + files: ["examples/**/*.js"], + rules: { + "n/no-missing-require": "off" + } + }, + { + ...prettierConfig, + plugins: { + ...prettierConfig.plugins, + prettier + }, + rules: { + ...prettierConfig.rules, + "prettier/prettier": "error" + } + } +]; diff --git a/examples/README.md b/examples/README.md index 0bbade59b91..6e9361f51ef 100644 --- a/examples/README.md +++ b/examples/README.md @@ -23,9 +23,10 @@ 19. [Scope Hoisting](#scope-hoisting) 20. [Side Effects](#side-effects) 21. [Source Map](#source-map) -22. [Web Worker](#web-worker) -23. [Requests](#requests) -24. [Building an Example](#building-an-example) +22. [WebAssembly](#webassembly) +23. [Web Worker](#web-worker) +24. [Requests](#requests) +25. [Building an Example](#building-an-example) ## Aggressive Merging @@ -49,8 +50,6 @@ [two-explicit-vendor-chunks](two-explicit-vendor-chunks) ## Code Splitted -[code-splitted-css-bundle](code-splitted-css-bundle) - [code-splitted-require.context-amd](code-splitted-require.context-amd) example demonstrating contexts in a code-split environment with AMD. [code-splitted-require.context](code-splitted-require.context) example demonstrating contexts in a code-split environment. @@ -58,7 +57,7 @@ ## Code Splitting [code-splitting](code-splitting) example demonstrating a very simple case of Code Splitting. -[code-splitting-bundle-loader](code-splitting-bundle-loader) example demonstrating Code Splitting through the builder loader +[code-splitting-bundle-loader](code-splitting-bundle-loader) example demonstrating Code Splitting through the bundle loader [code-splitting-harmony](code-splitting-harmony) @@ -130,6 +129,10 @@ ## Source Map [source-map](source-map) +## WebAssembly +[wasm-simple](wasm-simple) example demonstrating simple import from a WebAssembly module +[wasm-complex](wasm-complex) example demonstrating top-level await and import of WebAssembly text format with wast-loader + ## Web Worker [web-worker](worker) example demonstrating creating WebWorkers with webpack. diff --git a/examples/aggressive-merging/README.md b/examples/aggressive-merging/README.md index 1b3e91e4731..959c4632409 100644 --- a/examples/aggressive-merging/README.md +++ b/examples/aggressive-merging/README.md @@ -60,9 +60,9 @@ module.exports = { ## Unoptimized ``` -asset pageA.bundle.js 8.91 KiB [emitted] (name: pageA) -asset pageB.bundle.js 8.91 KiB [emitted] (name: pageB) -asset pageC.bundle.js 8.91 KiB [emitted] (name: pageC) +asset pageA.bundle.js 8.9 KiB [emitted] (name: pageA) +asset pageB.bundle.js 8.9 KiB [emitted] (name: pageB) +asset pageC.bundle.js 8.9 KiB [emitted] (name: pageC) asset 456.chunk.js 6.28 KiB [emitted] asset 394.chunk.js 606 bytes [emitted] chunk (runtime: pageB) pageB.bundle.js (pageB) 69 bytes (javascript) 4.97 KiB (runtime) [entry] [rendered] @@ -113,15 +113,15 @@ chunk (runtime: pageA, pageB) 456.chunk.js 5.45 KiB [rendered] cjs self exports reference ./common.js 1:0-14 amd require ./common ./pageA.js 1:0-3:2 amd require ./common ./pageB.js 1:0-3:2 -webpack 5.11.1 compiled successfully +webpack 5.78.0 compiled successfully ``` ## Production mode ``` -asset pageC.bundle.js 1.73 KiB [emitted] [minimized] (name: pageC) -asset pageA.bundle.js 1.72 KiB [emitted] [minimized] (name: pageA) -asset pageB.bundle.js 1.72 KiB [emitted] [minimized] (name: pageB) +asset pageC.bundle.js 1.74 KiB [emitted] [minimized] (name: pageC) +asset pageA.bundle.js 1.73 KiB [emitted] [minimized] (name: pageA) +asset pageB.bundle.js 1.73 KiB [emitted] [minimized] (name: pageB) asset 456.chunk.js 155 bytes [emitted] [minimized] asset 394.chunk.js 104 bytes [emitted] [minimized] chunk (runtime: pageB) pageB.bundle.js (pageB) 69 bytes (javascript) 4.97 KiB (runtime) [entry] [rendered] @@ -172,5 +172,5 @@ chunk (runtime: pageA, pageB) 456.chunk.js 5.45 KiB [rendered] cjs self exports reference ./common.js 1:0-14 amd require ./common ./pageA.js 1:0-3:2 amd require ./common ./pageB.js 1:0-3:2 -webpack 5.11.1 compiled successfully +webpack 5.78.0 compiled successfully ``` diff --git a/examples/aggressive-merging/webpack.config.js b/examples/aggressive-merging/webpack.config.js index 2887ce355e8..b4b6e38eec1 100644 --- a/examples/aggressive-merging/webpack.config.js +++ b/examples/aggressive-merging/webpack.config.js @@ -1,5 +1,5 @@ -var path = require("path"); -var { AggressiveMergingPlugin } = require("../../").optimize; +const path = require("path"); +const { AggressiveMergingPlugin } = require("../..").optimize; module.exports = { // mode: "development" || "production", diff --git a/examples/asset-advanced/README.md b/examples/asset-advanced/README.md index 73e519639c2..6210a32cafe 100644 --- a/examples/asset-advanced/README.md +++ b/examples/asset-advanced/README.md @@ -74,48 +74,7 @@ module.exports = { /******/ (() => { // webpackBootstrap /******/ "use strict"; /******/ var __webpack_modules__ = ([ -/* 0 */ -/*!********************!*\ - !*** ./example.js ***! - \********************/ -/*! namespace exports */ -/*! exports [not provided] [no usage info] */ -/*! runtime requirements: __webpack_require__, __webpack_require__.r, __webpack_exports__, __webpack_require__.* */ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -__webpack_require__.r(__webpack_exports__); -/* harmony import */ var _images_file_svg__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./images/file.svg */ 1); - - -const container = document.createElement("div"); -Object.assign(container.style, { - display: "flex", - justifyContent: "center" -}); -document.body.appendChild(container); - -function createImageElement(title, src) { - const div = document.createElement("div"); - div.style.textAlign = "center"; - - const h2 = document.createElement("h2"); - h2.textContent = title; - div.appendChild(h2); - - const img = document.createElement("img"); - img.setAttribute("src", src); - img.setAttribute("width", "150"); - div.appendChild(img); - - container.appendChild(div); -} - -[_images_file_svg__WEBPACK_IMPORTED_MODULE_0__].forEach(src => { - createImageElement(src.split(".").pop(), src); -}); - - -/***/ }), +/* 0 */, /* 1 */ /*!*************************!*\ !*** ./images/file.svg ***! @@ -141,8 +100,9 @@ module.exports = "data:image/svg+xml,%3csvg xmlns='http://www.w3.or...3c/svg%3e" /******/ // The require function /******/ function __webpack_require__(moduleId) { /******/ // Check if module is in cache -/******/ if(__webpack_module_cache__[moduleId]) { -/******/ return __webpack_module_cache__[moduleId].exports; +/******/ var cachedModule = __webpack_module_cache__[moduleId]; +/******/ if (cachedModule !== undefined) { +/******/ return cachedModule.exports; /******/ } /******/ // Create a new module (and put it into the cache) /******/ var module = __webpack_module_cache__[moduleId] = { @@ -176,10 +136,48 @@ module.exports = "data:image/svg+xml,%3csvg xmlns='http://www.w3.or...3c/svg%3e" ``` js -/******/ // startup -/******/ // Load entry module -/******/ __webpack_require__(0); -/******/ // This entry module used 'exports' so it can't be inlined +var __webpack_exports__ = {}; +// This entry need to be wrapped in an IIFE because it need to be isolated against other modules in the chunk. +(() => { +/*!********************!*\ + !*** ./example.js ***! + \********************/ +/*! namespace exports */ +/*! exports [not provided] [no usage info] */ +/*! runtime requirements: __webpack_require__, __webpack_require__.r, __webpack_exports__, __webpack_require__.* */ +__webpack_require__.r(__webpack_exports__); +/* harmony import */ var _images_file_svg__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./images/file.svg */ 1); + + +const container = document.createElement("div"); +Object.assign(container.style, { + display: "flex", + justifyContent: "center" +}); +document.body.appendChild(container); + +function createImageElement(title, src) { + const div = document.createElement("div"); + div.style.textAlign = "center"; + + const h2 = document.createElement("h2"); + h2.textContent = title; + div.appendChild(h2); + + const img = document.createElement("img"); + img.setAttribute("src", src); + img.setAttribute("width", "150"); + div.appendChild(img); + + container.appendChild(div); +} + +[_images_file_svg__WEBPACK_IMPORTED_MODULE_0__].forEach(src => { + createImageElement(src.split(".").pop(), src); +}); + +})(); + /******/ })() ; ``` @@ -189,7 +187,7 @@ module.exports = "data:image/svg+xml,%3csvg xmlns='http://www.w3.or...3c/svg%3e" ## webpack output ``` -asset output.js 3.86 KiB [emitted] (name: main) +asset output.js 3.81 KiB [emitted] (name: main) chunk (runtime: main) output.js (main) 1.54 KiB (javascript) 274 bytes (runtime) [entry] [rendered] > ./example.js main dependent modules 915 bytes [dependent] 1 module @@ -198,5 +196,5 @@ chunk (runtime: main) output.js (main) 1.54 KiB (javascript) 274 bytes (runtime) [no exports] [used exports unknown] entry ./example.js main -webpack 5.11.1 compiled successfully +webpack 5.78.0 compiled successfully ``` diff --git a/examples/asset-simple/README.md b/examples/asset-simple/README.md index 0841a580c8e..c2f5e4c477e 100644 --- a/examples/asset-simple/README.md +++ b/examples/asset-simple/README.md @@ -61,59 +61,14 @@ module.exports = { /******/ (() => { // webpackBootstrap /******/ "use strict"; /******/ var __webpack_modules__ = ([ -/* 0 */ -/*!********************!*\ - !*** ./example.js ***! - \********************/ -/*! namespace exports */ -/*! exports [not provided] [no usage info] */ -/*! runtime requirements: __webpack_require__, __webpack_require__.r, __webpack_exports__, __webpack_require__.* */ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -__webpack_require__.r(__webpack_exports__); -/* harmony import */ var _images_file_png__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./images/file.png */ 1); -/* harmony import */ var _images_file_jpg__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./images/file.jpg */ 2); -/* harmony import */ var _images_file_svg__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./images/file.svg */ 3); - - - - -const container = document.createElement("div"); -Object.assign(container.style, { - display: "flex", - justifyContent: "center" -}); -document.body.appendChild(container); - -function createImageElement(title, src) { - const div = document.createElement("div"); - div.style.textAlign = "center"; - - const h2 = document.createElement("h2"); - h2.textContent = title; - div.appendChild(h2); - - const img = document.createElement("img"); - img.setAttribute("src", src); - img.setAttribute("width", "150"); - div.appendChild(img); - - container.appendChild(div); -} - -[_images_file_png__WEBPACK_IMPORTED_MODULE_0__, _images_file_jpg__WEBPACK_IMPORTED_MODULE_1__, _images_file_svg__WEBPACK_IMPORTED_MODULE_2__].forEach(src => { - createImageElement(src.split(".").pop(), src); -}); - - -/***/ }), +/* 0 */, /* 1 */ /*!*************************!*\ !*** ./images/file.png ***! \*************************/ /*! default exports */ /*! exports [not provided] [no usage info] */ -/*! runtime requirements: module, __webpack_require__.p, __webpack_require__.* */ +/*! runtime requirements: __webpack_require__.p, module, __webpack_require__.* */ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { module.exports = __webpack_require__.p + "images/89a353e9c515885abd8e.png"; @@ -156,8 +111,9 @@ module.exports = "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDo...vc3ZnPgo=" /******/ // The require function /******/ function __webpack_require__(moduleId) { /******/ // Check if module is in cache -/******/ if(__webpack_module_cache__[moduleId]) { -/******/ return __webpack_module_cache__[moduleId].exports; +/******/ var cachedModule = __webpack_module_cache__[moduleId]; +/******/ if (cachedModule !== undefined) { +/******/ return cachedModule.exports; /******/ } /******/ // Create a new module (and put it into the cache) /******/ var module = __webpack_module_cache__[moduleId] = { @@ -196,10 +152,52 @@ module.exports = "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDo...vc3ZnPgo=" ``` js -/******/ // startup -/******/ // Load entry module -/******/ __webpack_require__(0); -/******/ // This entry module used 'exports' so it can't be inlined +var __webpack_exports__ = {}; +// This entry need to be wrapped in an IIFE because it need to be isolated against other modules in the chunk. +(() => { +/*!********************!*\ + !*** ./example.js ***! + \********************/ +/*! namespace exports */ +/*! exports [not provided] [no usage info] */ +/*! runtime requirements: __webpack_require__, __webpack_require__.r, __webpack_exports__, __webpack_require__.* */ +__webpack_require__.r(__webpack_exports__); +/* harmony import */ var _images_file_png__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./images/file.png */ 1); +/* harmony import */ var _images_file_jpg__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./images/file.jpg */ 2); +/* harmony import */ var _images_file_svg__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./images/file.svg */ 3); + + + + +const container = document.createElement("div"); +Object.assign(container.style, { + display: "flex", + justifyContent: "center" +}); +document.body.appendChild(container); + +function createImageElement(title, src) { + const div = document.createElement("div"); + div.style.textAlign = "center"; + + const h2 = document.createElement("h2"); + h2.textContent = title; + div.appendChild(h2); + + const img = document.createElement("img"); + img.setAttribute("src", src); + img.setAttribute("width", "150"); + div.appendChild(img); + + container.appendChild(div); +} + +[_images_file_png__WEBPACK_IMPORTED_MODULE_0__, _images_file_jpg__WEBPACK_IMPORTED_MODULE_1__, _images_file_svg__WEBPACK_IMPORTED_MODULE_2__].forEach(src => { + createImageElement(src.split(".").pop(), src); +}); + +})(); + /******/ })() ; ``` @@ -219,5 +217,5 @@ chunk (runtime: main) output.js (main) 9.58 KiB (javascript) 14.6 KiB (asset) 30 [no exports] [used exports unknown] entry ./example.js main -webpack 5.11.1 compiled successfully +webpack 5.78.0 compiled successfully ``` diff --git a/examples/build-common.js b/examples/build-common.js index 41d554c3b06..7293b32d604 100644 --- a/examples/build-common.js +++ b/examples/build-common.js @@ -16,7 +16,8 @@ const targetArgs = global.NO_TARGET_ARGS ? "" : "--entry ./example.js --output-f const displayReasons = global.NO_REASONS ? "" : "--stats-reasons --stats-used-exports --stats-provided-exports"; const statsArgs = global.NO_STATS_OPTIONS ? "" : "--stats-chunks --stats-modules-space 99999 --stats-chunk-origins"; const publicPathArgs = global.NO_PUBLIC_PATH ? "" : '--output-public-path "dist/"'; -const commonArgs = `--no-stats-colors ${statsArgs} ${publicPathArgs} ${extraArgs} ${targetArgs}`; +const statsColorsArg = global.STATS_COLORS ? "" : "--no-stats-colors"; +const commonArgs = `${statsColorsArg} ${statsArgs} ${publicPathArgs} ${extraArgs} ${targetArgs}`; let readme = fs.readFileSync(require("path").join(process.cwd(), "template.md"), "utf-8"); @@ -50,7 +51,30 @@ const doCompileAndReplace = (args, prefix, callback) => { throw new Error("Please install webpack-cli at root."); } - cp.exec(`node ${path.resolve(__dirname, "../bin/webpack.js")} ${args} ${displayReasons} ${commonArgs}`, (error, stdout, stderr) => { + const connectIO = (subprocess) => { + const { stdin, stdout, stderr } = process; + const { stdin: _stdin, stdout: _stdout, stderr: _stderr } = subprocess; + const inputPair = [[stdin, _stdin]]; + const outputPair = [[stdout, _stdout], [stderr, _stderr]]; + inputPair.forEach(pair => { + pair[0].pipe(pair[1]) + }) + outputPair.forEach(pair => { + pair[1].pipe(pair[0]) + }) + disconnectIO = () => { + inputPair.forEach(pair => { + pair[0].unpipe(pair[1]) + }) + outputPair.forEach(pair => { + pair[1].unpipe(pair[0]) + }) + } + } + let disconnectIO = null; + + const subprocess = cp.exec(`node ${path.resolve(__dirname, "../bin/webpack.js")} ${args} ${displayReasons} ${commonArgs}`, (error, stdout, stderr) => { + disconnectIO && disconnectIO(); if (stderr) console.log(stderr); if (error !== null) @@ -63,6 +87,7 @@ const doCompileAndReplace = (args, prefix, callback) => { } callback(); }); + connectIO(subprocess); }; async.series([ diff --git a/examples/build-http/README.md b/examples/build-http/README.md new file mode 100644 index 00000000000..088ca7e5a01 --- /dev/null +++ b/examples/build-http/README.md @@ -0,0 +1,92 @@ +# example.js + +```javascript +import pMap1 from "https://cdn.skypack.dev/p-map"; +import pMap2 from "https://cdn.esm.sh/p-map"; +import pMap3 from "https://jspm.dev/p-map"; +import pMap4 from "https://unpkg.com/p-map-series?module"; // unpkg doesn't support p-map :( +console.log(pMap1); +console.log(pMap2); +console.log(pMap3); +console.log(pMap4); +``` + +# webpack.config.js + +```javascript +module.exports = { + // enable debug logging to see network requests! + // stats: { + // loggingDebug: /HttpUriPlugin/ + // }, + experiments: { + buildHttp: [ + "https://cdn.esm.sh/", + "https://cdn.skypack.dev/", + "https://jspm.dev/", + /^https:\/\/unpkg\.com\/.+\?module$/ + ] + } +}; +``` + +# Info + +## Unoptimized + +``` +asset output.js 82.6 KiB [emitted] (name: main) +runtime modules 670 bytes 3 modules +modules by path https:// 30 KiB + modules by path https://jspm.dev/ 16.1 KiB 12 modules + modules by path https://cdn.esm.sh/ 6.15 KiB + https://cdn.esm.sh/p-map 173 bytes [built] [code generated] + [exports: default, pMapSkip] + [used exports unknown] + harmony side effect evaluation https://cdn.esm.sh/p-map ./example.js 2:0-45 + harmony import specifier https://cdn.esm.sh/p-map ./example.js 6:12-17 + https://cdn.esm.sh/v53/p-map@5.1.0/es2015/p-map.js 1.18 KiB [built] [code generated] + [exports: default, pMapSkip] + [used exports unknown] + harmony side effect evaluation https://cdn.esm.sh/v53/p-map@5.1.0/es2015/p-map.js https://cdn.esm.sh/p-map 2:0-67 + harmony export imported specifier https://cdn.esm.sh/v53/p-map@5.1.0/es2015/p-map.js https://cdn.esm.sh/p-map 2:0-67 + harmony side effect evaluation https://cdn.esm.sh/v53/p-map@5.1.0/es2015/p-map.js https://cdn.esm.sh/p-map 3:0-77 + harmony export imported specifier https://cdn.esm.sh/v53/p-map@5.1.0/es2015/p-map.js https://cdn.esm.sh/p-map 3:0-77 + + 5 modules + modules by path https://cdn.skypack.dev/ 7.46 KiB + https://cdn.skypack.dev/p-map 757 bytes [built] [code generated] + [exports: default, pMapSkip] + [used exports unknown] + harmony side effect evaluation https://cdn.skypack.dev/p-map ./example.js 1:0-50 + harmony import specifier https://cdn.skypack.dev/p-map ./example.js 5:12-17 + https://cdn.skypack.dev/-/p-map@v5.1.0-7ixXvZxXPKKt9unR9LT0/dist=es2020,mode=imports/optimized/p-map.js 2.29 KiB [built] [code generated] + [exports: default, pMapSkip] + [used exports unknown] + harmony side effect evaluation /-/p-map@v5.1.0-7ixXvZxXPKKt9unR9LT0/dist=es2020,mode=imports/optimized/p-map.js https://cdn.skypack.dev/p-map 15:0-97 + harmony export imported specifier /-/p-map@v5.1.0-7ixXvZxXPKKt9unR9LT0/dist=es2020,mode=imports/optimized/p-map.js https://cdn.skypack.dev/p-map 15:0-97 + harmony side effect evaluation /-/p-map@v5.1.0-7ixXvZxXPKKt9unR9LT0/dist=es2020,mode=imports/optimized/p-map.js https://cdn.skypack.dev/p-map 16:0-105 + harmony export imported specifier /-/p-map@v5.1.0-7ixXvZxXPKKt9unR9LT0/dist=es2020,mode=imports/optimized/p-map.js https://cdn.skypack.dev/p-map 16:0-105 + + 4 modules + https://unpkg.com/p-map-series?module 263 bytes [built] [code generated] + [exports: default] + [used exports unknown] + harmony side effect evaluation https://unpkg.com/p-map-series?module ./example.js 4:0-58 + harmony import specifier https://unpkg.com/p-map-series?module ./example.js 8:12-17 +./example.js 314 bytes [built] [code generated] + [no exports] + [used exports unknown] + entry ./example.js main +webpack 5.78.0 compiled successfully +``` + +## Production mode + +``` +asset output.js 12.4 KiB [emitted] [minimized] (name: main) +orphan modules 30 KiB [orphan] 26 modules +./example.js + 25 modules 30.2 KiB [built] [code generated] + [no exports] + [no exports used] + entry ./example.js main +webpack 5.78.0 compiled successfully +``` diff --git a/examples/build-http/build.js b/examples/build-http/build.js new file mode 100644 index 00000000000..1d8b07db18b --- /dev/null +++ b/examples/build-http/build.js @@ -0,0 +1,2 @@ +global.NO_STATS_OPTIONS = true; +require("../build-common"); diff --git a/examples/build-http/example.js b/examples/build-http/example.js new file mode 100644 index 00000000000..4dd7204b019 --- /dev/null +++ b/examples/build-http/example.js @@ -0,0 +1,8 @@ +import pMap1 from "https://cdn.skypack.dev/p-map"; +import pMap2 from "https://cdn.esm.sh/p-map"; +import pMap3 from "https://jspm.dev/p-map"; +import pMap4 from "https://unpkg.com/p-map-series?module"; // unpkg doesn't support p-map :( +console.log(pMap1); +console.log(pMap2); +console.log(pMap3); +console.log(pMap4); diff --git a/examples/build-http/template.md b/examples/build-http/template.md new file mode 100644 index 00000000000..2df3585bde6 --- /dev/null +++ b/examples/build-http/template.md @@ -0,0 +1,25 @@ +# example.js + +```javascript +_{{example.js}}_ +``` + +# webpack.config.js + +```javascript +_{{webpack.config.js}}_ +``` + +# Info + +## Unoptimized + +``` +_{{stdout}}_ +``` + +## Production mode + +``` +_{{production:stdout}}_ +``` diff --git a/examples/build-http/webpack.config.js b/examples/build-http/webpack.config.js new file mode 100644 index 00000000000..ca271913b30 --- /dev/null +++ b/examples/build-http/webpack.config.js @@ -0,0 +1,14 @@ +module.exports = { + // enable debug logging to see network requests! + // stats: { + // loggingDebug: /HttpUriPlugin/ + // }, + experiments: { + buildHttp: [ + "https://cdn.esm.sh/", + "https://cdn.skypack.dev/", + "https://jspm.dev/", + /^https:\/\/unpkg\.com\/.+\?module$/ + ] + } +}; diff --git a/examples/build-http/webpack.lock b/examples/build-http/webpack.lock new file mode 100644 index 00000000000..f696523fd3e --- /dev/null +++ b/examples/build-http/webpack.lock @@ -0,0 +1,29 @@ +{ + "https://cdn.esm.sh/p-map": { "integrity": "sha512-TfztRxlC5elIRa7x3oz4bfhtxJr5hIhoa+bliQkroNj8haEMPp1mv/eAsfzBt032G1oK6JT6y3135FP0vRh13Q==", "contentType": "application/javascript; charset=utf-8" }, + "https://cdn.esm.sh/v53/aggregate-error@4.0.0/es2015/aggregate-error.js": { "integrity": "sha512-4iHvwySJO0Dn0aenl2XY1XCGEoMZFaJ+PkuO8Op0BRVNwHiZaKrCuMnPZqUblPhvAG2o8SEA4JdB/fhS3IQZLg==", "contentType": "application/javascript" }, + "https://cdn.esm.sh/v53/clean-stack@4.1.0/es2015/clean-stack.js": { "integrity": "sha512-VzcwF50IxKsmW4O2DpY8WB6TmYh9caBctTqA2EkE3p9K8JjITMD/qBNqfVmUKAlmq4CFgI3c0xegzMf1BRWbyQ==", "contentType": "application/javascript" }, + "https://cdn.esm.sh/v53/escape-string-regexp@5.0.0/es2015/escape-string-regexp.js": { "integrity": "sha512-vst7rz+jFlvZMjo5GUzNBSq7QvFoaqOQ+hDq0m40ZJYGts6ptt+QKLZOMDWgoEq3Fabnhiy+hsoIfaHMmVdbSQ==", "contentType": "application/javascript" }, + "https://cdn.esm.sh/v53/indent-string@5.0.0/es2015/indent-string.js": { "integrity": "sha512-o1hDF1EyRTCiDpcxD2i0XpIuHCMFrc9XkKrkMISIaiWpJdKU7HBRhtqXfBcpVfJF1uNAFJ7/1v40vpPH2r7X8w==", "contentType": "application/javascript" }, + "https://cdn.esm.sh/v53/os-browserify@0.3.0/es2015/browser.js": { "integrity": "sha512-8JOZWkDGX6WNFtXIk/aOawVo35LZSIgCdbMrleK4QL8kHcYti2oTjfqfn99AJm6SOUsTt0uY5K808uHAvVe3eA==", "contentType": "application/javascript" }, + "https://cdn.esm.sh/v53/p-map@5.1.0/es2015/p-map.js": { "integrity": "sha512-3kEIICBOLKnEn6SNNixOBy+VGgwh0DYtn07yxHfagwiSJV8om7q/37RdHVbQ2pol8B/6oVMHo7Y6YYhmpYKDUA==", "contentType": "application/javascript" }, + "https://cdn.skypack.dev/-/aggregate-error@v4.0.0-rCH8s5R9g4kQQ807o58j/dist=es2020,mode=imports/optimized/aggregate-error.js": { "integrity": "sha512-E5rN3mgPTqyfHSovQ++ZyZWQkMUniuyjbeHHX+E4G3MStEx6TfObScB8tfHeIyuawSp86nVsFfMZjCruD61rdg==", "contentType": "application/javascript; charset=utf-8" }, + "https://cdn.skypack.dev/-/clean-stack@v4.1.0-DgWUKXHVzThBBZtsHXhC/dist=es2020,mode=imports/optimized/clean-stack.js": { "integrity": "sha512-1nEMT4Vc2YLu3EbeBnck7Traj0/D6G9MMSGraGpsoQIMKVuhQjq4gP76X6RxUn5GoiHv90KfrFMSWlbBn26Dhw==", "contentType": "application/javascript; charset=utf-8" }, + "https://cdn.skypack.dev/-/escape-string-regexp@v5.0.0-SUDdAhYOdAgXIYndxZss/dist=es2020,mode=imports/optimized/escape-string-regexp.js": { "integrity": "sha512-54oHYow5obgsKb0twQZMNLvCH2tV5MCOY4YHB0LQH+zVonIAn7JYZseUPWhC3MMkJFK5EkeNWDAX7P2camp27g==", "contentType": "application/javascript; charset=utf-8" }, + "https://cdn.skypack.dev/-/indent-string@v5.0.0-VgKPSgi4hUX5NbF4n3aC/dist=es2020,mode=imports/optimized/indent-string.js": { "integrity": "sha512-lSZAs06jEHkVlPMEeMtKbygGhrSmJUMVmpB6/2ChdG2F0694vRU1v6N12bUyqR5uGbbteTJ7atP5PmPtTVmlcw==", "contentType": "application/javascript; charset=utf-8" }, + "https://cdn.skypack.dev/-/p-map@v5.1.0-7ixXvZxXPKKt9unR9LT0/dist=es2020,mode=imports/optimized/p-map.js": { "integrity": "sha512-mZyhNJe8VlqEqafSkUGTooFrKcQPSwVjB3UxAAPqywSFD+age77uTRP6ul8uAMEQ3lllmengXX1q45igRxRcDw==", "contentType": "application/javascript; charset=utf-8" }, + "https://cdn.skypack.dev/p-map": { "integrity": "sha512-FFu6R9j8mrGqTvw8WL37XsWhI9P65XdPD9Jfs/47jiYNdex12f0XJNsIy+fI81PbOkCuEQRgm2nf0P76ieBlag==", "contentType": "application/javascript; charset=utf-8" }, + "https://jspm.dev/npm:@jspm/core@2.0.0-beta.11/nodelibs/os": { "integrity": "sha512-Jsg9UMzfNTnlPDu6FeftYzdp6XULJwLDI7xFSzULhMqjQUoOIHJhkAToEgr3NnEKCkLZQMIPuBvHAn0ud6gT+w==", "contentType": "application/javascript; charset=utf-8" }, + "https://jspm.dev/npm:@jspm/core@2.0.0-beta.11/nodelibs/process": { "integrity": "sha512-KIYEmkrnT7TL5EKA5coPbbdoqfL2twHFBVXKTZS+PU5aZFX90yELxZHrm4DhxSQ33FLAWo51/nQLQmqGekWNMw==", "contentType": "application/javascript; charset=utf-8" }, + "https://jspm.dev/npm:@jspm/core@2/nodelibs/os": { "integrity": "sha512-g2ppEW1AVdbIpc486D0ZmLIR5CtzMITkBwqoBgxvhiIq5/qHP4/unZ7Czk3q8A1UwdTI4wbGzRWndXAUa4/Q0Q==", "contentType": "application/javascript; charset=utf-8" }, + "https://jspm.dev/npm:aggregate-error@4": { "integrity": "sha512-XfXd6EZ09/SKLmWFFvjPCSkqv0E08IxKc8mFm9mePyLIiEiGyAKokeFt1wql+kG8ikGmI7YqKBsDf07/I31VvA==", "contentType": "application/javascript; charset=utf-8" }, + "https://jspm.dev/npm:aggregate-error@4.0.0": { "integrity": "sha512-HEobsVYXVCp5H4Z+6qAlKno8XAJwHQrfF4ivR4PHrp4ttM0Yg0zDfOcsjqJOnTP5hEnKR1K6OzQdPfR2r9of4g==", "contentType": "application/javascript; charset=utf-8" }, + "https://jspm.dev/npm:clean-stack@4": { "integrity": "sha512-3wh/QTJY4tw/GInIcn5I+0hsHSirJi8Tf3kmH85hzQsuwB5k2lghBFZyKZPO7/Ql3muvZeDgN02pYkZap59Qrw==", "contentType": "application/javascript; charset=utf-8" }, + "https://jspm.dev/npm:clean-stack@4.1.0": { "integrity": "sha512-VgNMH/ju9thH4YuxxA5trzs0u66nzRZhMa43jkhk8q6jxlEBhd7G6ZZxswy2a0ZXiXjPQVhzXfFkAIkY/pxTOg==", "contentType": "application/javascript; charset=utf-8" }, + "https://jspm.dev/npm:escape-string-regexp@5.0.0": { "integrity": "sha512-Hz7n4npzwf0UgkdjQvLN2HxudnAzllTEM9AzJPlnzf9ktGhkwlFltPQBjEM3xyDHeTj1xI1nYpBSRVQmMCl6bw==", "contentType": "application/javascript; charset=utf-8" }, + "https://jspm.dev/npm:indent-string@5": { "integrity": "sha512-hjMQ8+LX0q8xe2sCp/DEBJW2MrVFbiDv20pK0PWwENkYCkRlyP5L4t5AUiXLEXfJLUhTVrUfZtf+hmrnGJB/zA==", "contentType": "application/javascript; charset=utf-8" }, + "https://jspm.dev/npm:indent-string@5.0.0": { "integrity": "sha512-1KRJ7I1gDWWBAXz+NpwQnlJXDiSpaxaftugln1zHywLbqhA/akcZYM6+nTdfSSuQ7wiVong69R5X9l/QKWqO7g==", "contentType": "application/javascript; charset=utf-8" }, + "https://jspm.dev/npm:p-map@5.1.0": { "integrity": "sha512-Ml4ozElyzZEvq3G61nmeDVjEPVbjNzhWwIfvVcEr0OsUu58yT/ieSJWr6VSSHbNGY8B1IYjJCEO2zFrgIT9plQ==", "contentType": "application/javascript; charset=utf-8" }, + "https://jspm.dev/p-map": { "integrity": "sha512-Ztuu37YpSElOGm1OnAmLzhgTuTSyeDXCudBO94yRDDicb2zwUTIDEaVnHMJ6Gb7AVnKk26uubHB+Hw0XxKRnrw==", "contentType": "application/javascript; charset=utf-8" }, + "https://unpkg.com/p-map-series?module": { "resolved": "https://unpkg.com/p-map-series@3.0.0/index.js?module", "integrity": "sha512-e68FFGx6Hb3/2x4o16EWcd6rdmyiov0OLjPnj2bmc60JrrNowav76umw0Gc5TmT+UOjaJo9Xk2lTGQT1/Y6Jug==", "contentType": "application/javascript; charset=utf-8" }, + "version": 1 +} diff --git a/examples/build-http/webpack.lock.data/https_cdn.esm.sh/p-map_9dd32c023fd5f3d3e7f2 b/examples/build-http/webpack.lock.data/https_cdn.esm.sh/p-map_9dd32c023fd5f3d3e7f2 new file mode 100644 index 00000000000..5034fb3895a --- /dev/null +++ b/examples/build-http/webpack.lock.data/https_cdn.esm.sh/p-map_9dd32c023fd5f3d3e7f2 @@ -0,0 +1,3 @@ +/* esm.sh - p-map@5.1.0 */ +export * from "https://cdn.esm.sh/v53/p-map@5.1.0/es2015/p-map.js"; +export { default } from "https://cdn.esm.sh/v53/p-map@5.1.0/es2015/p-map.js"; diff --git a/examples/build-http/webpack.lock.data/https_cdn.esm.sh/v53_aggregate-error_4.0.0_es2015_aggregate-error_ff6bcc1ba33bf3b1810a.js b/examples/build-http/webpack.lock.data/https_cdn.esm.sh/v53_aggregate-error_4.0.0_es2015_aggregate-error_ff6bcc1ba33bf3b1810a.js new file mode 100644 index 00000000000..7d5f29fd065 --- /dev/null +++ b/examples/build-http/webpack.lock.data/https_cdn.esm.sh/v53_aggregate-error_4.0.0_es2015_aggregate-error_ff6bcc1ba33bf3b1810a.js @@ -0,0 +1,4 @@ +/* esm.sh - esbuild bundle(aggregate-error@4.0.0) es2015 production */ +var l=Object.defineProperty;var f=(n,t,e)=>t in n?l(n,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):n[t]=e;var s=(n,t,e)=>(f(n,typeof t!="symbol"?t+"":t,e),e),i=(n,t,e)=>{if(!t.has(n))throw TypeError("Cannot "+e)};var c=(n,t,e)=>(i(n,t,"read from private field"),e?e.call(n):t.get(n)),g=(n,t,e)=>{if(t.has(n))throw TypeError("Cannot add the same private member more than once");t instanceof WeakSet?t.add(n):t.set(n,e)},o=(n,t,e,a)=>(i(n,t,"write to private field"),a?a.call(n,e):t.set(n,e),e);import u from"/v53/indent-string@5.0.0/es2015/indent-string.js";import m from"/v53/clean-stack@4.1.0/es2015/clean-stack.js";var d=n=>n.replace(/\s+at .*aggregate-error\/index.js:\d+:\d+\)?/g,""),r,p=class extends Error{constructor(t){if(!Array.isArray(t))throw new TypeError(`Expected input to be an Array, got ${typeof t}`);t=t.map(a=>a instanceof Error?a:a!==null&&typeof a=="object"?Object.assign(new Error(a.message),a):new Error(a));let e=t.map(a=>typeof a.stack=="string"?d(m(a.stack)):String(a)).join(` +`);e=` +`+u(e,4);super(e);g(this,r,void 0);s(this,"name","AggregateError");o(this,r,t)}get errors(){return c(this,r).slice()}};r=new WeakMap;export{p as default}; diff --git a/examples/build-http/webpack.lock.data/https_cdn.esm.sh/v53_clean-stack_4.1.0_es2015_clean-stack_87b32b37ae264a8e8a1c.js b/examples/build-http/webpack.lock.data/https_cdn.esm.sh/v53_clean-stack_4.1.0_es2015_clean-stack_87b32b37ae264a8e8a1c.js new file mode 100644 index 00000000000..a3c644a1fb2 --- /dev/null +++ b/examples/build-http/webpack.lock.data/https_cdn.esm.sh/v53_clean-stack_4.1.0_es2015_clean-stack_87b32b37ae264a8e8a1c.js @@ -0,0 +1,4 @@ +/* esm.sh - esbuild bundle(clean-stack@4.1.0) es2015 production */ +import s from"/v53/os-browserify@0.3.0/es2015/browser.js";import i from"/v53/escape-string-regexp@5.0.0/es2015/escape-string-regexp.js";var p=/\s+at.*[(\s](.*)\)?/,l=/^(?:(?:(?:node|node:[\w/]+|(?:(?:node:)?internal\/[\w/]*|.*node_modules\/(?:babel-polyfill|pirates)\/.*)?\w+)(?:\.js)?:\d+:\d+)|native)/,f=typeof s.homedir=="undefined"?"":s.homedir().replace(/\\/g,"/");function u(n,{pretty:c=!1,basePath:a}={}){let o=a&&new RegExp(`(at | \\()${i(a.replace(/\\/g,"/"))}`,"g");if(typeof n=="string")return n.replace(/\\/g,"/").split(` +`).filter(e=>{let r=e.match(p);if(r===null||!r[1])return!0;let t=r[1];return t.includes(".app/Contents/Resources/electron.asar")||t.includes(".app/Contents/Resources/default_app.asar")?!1:!l.test(t)}).filter(e=>e.trim()!=="").map(e=>(o&&(e=e.replace(o,"$1")),c&&(e=e.replace(p,(r,t)=>r.replace(t,t.replace(f,"~")))),e)).join(` +`)}export{u as default}; diff --git a/examples/build-http/webpack.lock.data/https_cdn.esm.sh/v53_escape-string-regexp_5.0.0_es2015_escape-string-regexp_2c814e466860133eca86.js b/examples/build-http/webpack.lock.data/https_cdn.esm.sh/v53_escape-string-regexp_5.0.0_es2015_escape-string-regexp_2c814e466860133eca86.js new file mode 100644 index 00000000000..a70aa3b9a9e --- /dev/null +++ b/examples/build-http/webpack.lock.data/https_cdn.esm.sh/v53_escape-string-regexp_5.0.0_es2015_escape-string-regexp_2c814e466860133eca86.js @@ -0,0 +1,2 @@ +/* esm.sh - esbuild bundle(escape-string-regexp@5.0.0) es2015 production */ +function r(e){if(typeof e!="string")throw new TypeError("Expected a string");return e.replace(/[|\\{}()[\]^$+*?.]/g,"\\$&").replace(/-/g,"\\x2d")}export{r as default}; diff --git a/examples/build-http/webpack.lock.data/https_cdn.esm.sh/v53_indent-string_5.0.0_es2015_indent-string_171b2b5ba89965a085b6.js b/examples/build-http/webpack.lock.data/https_cdn.esm.sh/v53_indent-string_5.0.0_es2015_indent-string_171b2b5ba89965a085b6.js new file mode 100644 index 00000000000..758f021c33e --- /dev/null +++ b/examples/build-http/webpack.lock.data/https_cdn.esm.sh/v53_indent-string_5.0.0_es2015_indent-string_171b2b5ba89965a085b6.js @@ -0,0 +1,2 @@ +/* esm.sh - esbuild bundle(indent-string@5.0.0) es2015 production */ +function i(t,e=1,o={}){let{indent:r=" ",includeEmptyLines:n=!1}=o;if(typeof t!="string")throw new TypeError(`Expected \`input\` to be a \`string\`, got \`${typeof t}\``);if(typeof e!="number")throw new TypeError(`Expected \`count\` to be a \`number\`, got \`${typeof e}\``);if(e<0)throw new RangeError(`Expected \`count\` to be at least 0, got \`${e}\``);if(typeof r!="string")throw new TypeError(`Expected \`options.indent\` to be a \`string\`, got \`${typeof r}\``);if(e===0)return t;let p=n?/^/gm:/^(?!\s*$)/gm;return t.replace(p,r.repeat(e))}export{i as default}; diff --git a/examples/build-http/webpack.lock.data/https_cdn.esm.sh/v53_os-browserify_0.3.0_es2015_browser_476a088316baaea08336.js b/examples/build-http/webpack.lock.data/https_cdn.esm.sh/v53_os-browserify_0.3.0_es2015_browser_476a088316baaea08336.js new file mode 100644 index 00000000000..951e12edff7 --- /dev/null +++ b/examples/build-http/webpack.lock.data/https_cdn.esm.sh/v53_os-browserify_0.3.0_es2015_browser_476a088316baaea08336.js @@ -0,0 +1,3 @@ +/* esm.sh - esbuild bundle(os-browserify@0.3.0/browser) es2015 production */ +var f=Object.create;var o=Object.defineProperty;var s=Object.getOwnPropertyDescriptor;var m=Object.getOwnPropertyNames;var c=Object.getPrototypeOf,p=Object.prototype.hasOwnProperty;var d=e=>o(e,"__esModule",{value:!0});var l=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports);var w=(e,t,i)=>{if(t&&typeof t=="object"||typeof t=="function")for(let n of m(t))!p.call(e,n)&&n!=="default"&&o(e,n,{get:()=>t[n],enumerable:!(i=s(t,n))||i.enumerable});return e},a=e=>w(d(o(e!=null?f(c(e)):{},"default",e&&e.__esModule&&"default"in e?{get:()=>e.default,enumerable:!0}:{value:e,enumerable:!0})),e);var u=l(r=>{r.endianness=function(){return"LE"};r.hostname=function(){return typeof location!="undefined"?location.hostname:""};r.loadavg=function(){return[]};r.uptime=function(){return 0};r.freemem=function(){return Number.MAX_VALUE};r.totalmem=function(){return Number.MAX_VALUE};r.cpus=function(){return[]};r.type=function(){return"Browser"};r.release=function(){return typeof navigator!="undefined"?navigator.appVersion:""};r.networkInterfaces=r.getNetworkInterfaces=function(){return{}};r.arch=function(){return"javascript"};r.platform=function(){return"browser"};r.tmpdir=r.tmpDir=function(){return"/tmp"};r.EOL=` +`;r.homedir=function(){return"/"}});var b=a(u()),h=a(u()),{endianness:v,hostname:E,loadavg:L,uptime:k,freemem:A,totalmem:I,cpus:N,type:_,release:V,networkInterfaces:x,getNetworkInterfaces:D,arch:M,platform:O,tmpdir:U,tmpDir:X,EOL:j,homedir:B}=b;var export_default=h.default;export{j as EOL,M as arch,N as cpus,export_default as default,v as endianness,A as freemem,D as getNetworkInterfaces,B as homedir,E as hostname,L as loadavg,x as networkInterfaces,O as platform,V as release,X as tmpDir,U as tmpdir,I as totalmem,_ as type,k as uptime}; diff --git a/examples/build-http/webpack.lock.data/https_cdn.esm.sh/v53_p-map_5.1.0_es2015_p-map_cd0c09542673ea9d78f0.js b/examples/build-http/webpack.lock.data/https_cdn.esm.sh/v53_p-map_5.1.0_es2015_p-map_cd0c09542673ea9d78f0.js new file mode 100644 index 00000000000..8baf6a8521d --- /dev/null +++ b/examples/build-http/webpack.lock.data/https_cdn.esm.sh/v53_p-map_5.1.0_es2015_p-map_cd0c09542673ea9d78f0.js @@ -0,0 +1,2 @@ +/* esm.sh - esbuild bundle(p-map@5.1.0) es2015 production */ +var g=(l,s,e)=>new Promise((f,x)=>{var N=t=>{try{n(e.next(t))}catch(r){x(r)}},p=t=>{try{n(e.throw(t))}catch(r){x(r)}},n=t=>t.done?f(t.value):Promise.resolve(t.value).then(N,p);n((e=e.apply(l,s)).next())});import y from"/v53/aggregate-error@4.0.0/es2015/aggregate-error.js";function S(x,N){return g(this,arguments,function*(l,s,{concurrency:e=Number.POSITIVE_INFINITY,stopOnError:f=!0}={}){return new Promise((p,n)=>{if(typeof s!="function")throw new TypeError("Mapper function is required");if(!((Number.isSafeInteger(e)||e===Number.POSITIVE_INFINITY)&&e>=1))throw new TypeError(`Expected \`concurrency\` to be an integer from 1 and up or \`Infinity\`, got \`${e}\` (${typeof e})`);let t=[],r=[],m=[],h=l[Symbol.iterator](),u=!1,c=!1,a=0,b=0,I=()=>{if(u)return;let i=h.next(),d=b;if(b++,i.done){if(c=!0,a===0)if(!f&&r.length>0)n(new y(r));else{for(let o of m)t.splice(o,1);p(t)}return}a++,(()=>g(this,null,function*(){try{let o=yield i.value;if(u)return;let w=yield s(o,d);w===T?m.push(d):t[d]=w,a--,I()}catch(o){f?(u=!0,n(o)):(r.push(o),a--,I())}}))()};for(let i=0;i { + if (typeof key !== "symbol") + key += ""; + if (key in obj) + return __defProp(obj, key, {enumerable: true, configurable: true, writable: true, value}); + return obj[key] = value; +}; +var __accessCheck = (obj, member, msg) => { + if (!member.has(obj)) + throw TypeError("Cannot " + msg); +}; +var __privateGet = (obj, member, getter) => { + __accessCheck(obj, member, "read from private field"); + return getter ? getter.call(obj) : member.get(obj); +}; +var __privateSet = (obj, member, value, setter) => { + __accessCheck(obj, member, "write to private field"); + setter ? setter.call(obj, value) : member.set(obj, value); + return value; +}; +var _errors; +import indentString from "/-/indent-string@v5.0.0-VgKPSgi4hUX5NbF4n3aC/dist=es2020,mode=imports/optimized/indent-string.js"; +import cleanStack from "/-/clean-stack@v4.1.0-DgWUKXHVzThBBZtsHXhC/dist=es2020,mode=imports/optimized/clean-stack.js"; +const cleanInternalStack = (stack) => stack.replace(/\s+at .*aggregate-error\/index.js:\d+:\d+\)?/g, ""); +class AggregateError extends Error { + constructor(errors) { + _errors.set(this, void 0); + __publicField(this, "name", "AggregateError"); + if (!Array.isArray(errors)) { + throw new TypeError(`Expected input to be an Array, got ${typeof errors}`); + } + errors = errors.map((error) => { + if (error instanceof Error) { + return error; + } + if (error !== null && typeof error === "object") { + return Object.assign(new Error(error.message), error); + } + return new Error(error); + }); + let message = errors.map((error) => { + return typeof error.stack === "string" ? cleanInternalStack(cleanStack(error.stack)) : String(error); + }).join("\n"); + message = "\n" + indentString(message, 4); + super(message); + __privateSet(this, _errors, errors); + } + get errors() { + return __privateGet(this, _errors).slice(); + } +} +_errors = new WeakMap(); +export default AggregateError; diff --git a/examples/build-http/webpack.lock.data/https_cdn.skypack.dev/clean-stack_v4.1.0-DgWUKXHVzThBBZtsHXhC_dist_es2020_mode_imports_optimized_clean-stack_25e0e8c6773c790b5bc1.js b/examples/build-http/webpack.lock.data/https_cdn.skypack.dev/clean-stack_v4.1.0-DgWUKXHVzThBBZtsHXhC_dist_es2020_mode_imports_optimized_clean-stack_25e0e8c6773c790b5bc1.js new file mode 100644 index 00000000000..d8afc7bdf1c --- /dev/null +++ b/examples/build-http/webpack.lock.data/https_cdn.skypack.dev/clean-stack_v4.1.0-DgWUKXHVzThBBZtsHXhC_dist_es2020_mode_imports_optimized_clean-stack_25e0e8c6773c790b5bc1.js @@ -0,0 +1,31 @@ +import escapeStringRegexp from "/-/escape-string-regexp@v5.0.0-SUDdAhYOdAgXIYndxZss/dist=es2020,mode=imports/optimized/escape-string-regexp.js"; +var os = {}; +const extractPathRegex = /\s+at.*[(\s](.*)\)?/; +const pathRegex = /^(?:(?:(?:node|node:[\w/]+|(?:(?:node:)?internal\/[\w/]*|.*node_modules\/(?:babel-polyfill|pirates)\/.*)?\w+)(?:\.js)?:\d+:\d+)|native)/; +const homeDir = typeof os.homedir === "undefined" ? "" : os.homedir().replace(/\\/g, "/"); +function cleanStack(stack, {pretty = false, basePath} = {}) { + const basePathRegex = basePath && new RegExp(`(at | \\()${escapeStringRegexp(basePath.replace(/\\/g, "/"))}`, "g"); + if (typeof stack !== "string") { + return void 0; + } + return stack.replace(/\\/g, "/").split("\n").filter((line) => { + const pathMatches = line.match(extractPathRegex); + if (pathMatches === null || !pathMatches[1]) { + return true; + } + const match = pathMatches[1]; + if (match.includes(".app/Contents/Resources/electron.asar") || match.includes(".app/Contents/Resources/default_app.asar")) { + return false; + } + return !pathRegex.test(match); + }).filter((line) => line.trim() !== "").map((line) => { + if (basePathRegex) { + line = line.replace(basePathRegex, "$1"); + } + if (pretty) { + line = line.replace(extractPathRegex, (m, p1) => m.replace(p1, p1.replace(homeDir, "~"))); + } + return line; + }).join("\n"); +} +export default cleanStack; diff --git a/examples/build-http/webpack.lock.data/https_cdn.skypack.dev/escape-string-regexp_v5.0.0-SUDdAhYOdAgXIYndxZss_dist_es2020_mode_imports_optimized_escape-string-regexp_95a4ae8a862c0536f335.js b/examples/build-http/webpack.lock.data/https_cdn.skypack.dev/escape-string-regexp_v5.0.0-SUDdAhYOdAgXIYndxZss_dist_es2020_mode_imports_optimized_escape-string-regexp_95a4ae8a862c0536f335.js new file mode 100644 index 00000000000..d0aaf2eea76 --- /dev/null +++ b/examples/build-http/webpack.lock.data/https_cdn.skypack.dev/escape-string-regexp_v5.0.0-SUDdAhYOdAgXIYndxZss_dist_es2020_mode_imports_optimized_escape-string-regexp_95a4ae8a862c0536f335.js @@ -0,0 +1,7 @@ +function escapeStringRegexp(string) { + if (typeof string !== "string") { + throw new TypeError("Expected a string"); + } + return string.replace(/[|\\{}()[\]^$+*?.]/g, "\\$&").replace(/-/g, "\\x2d"); +} +export default escapeStringRegexp; diff --git a/examples/build-http/webpack.lock.data/https_cdn.skypack.dev/indent-string_v5.0.0-VgKPSgi4hUX5NbF4n3aC_dist_es2020_mode_imports_optimized_indent-string_c9ee21b059896b4e6290.js b/examples/build-http/webpack.lock.data/https_cdn.skypack.dev/indent-string_v5.0.0-VgKPSgi4hUX5NbF4n3aC_dist_es2020_mode_imports_optimized_indent-string_c9ee21b059896b4e6290.js new file mode 100644 index 00000000000..307e1901ff0 --- /dev/null +++ b/examples/build-http/webpack.lock.data/https_cdn.skypack.dev/indent-string_v5.0.0-VgKPSgi4hUX5NbF4n3aC_dist_es2020_mode_imports_optimized_indent-string_c9ee21b059896b4e6290.js @@ -0,0 +1,24 @@ +function indentString(string, count = 1, options = {}) { + const { + indent = " ", + includeEmptyLines = false + } = options; + if (typeof string !== "string") { + throw new TypeError(`Expected \`input\` to be a \`string\`, got \`${typeof string}\``); + } + if (typeof count !== "number") { + throw new TypeError(`Expected \`count\` to be a \`number\`, got \`${typeof count}\``); + } + if (count < 0) { + throw new RangeError(`Expected \`count\` to be at least 0, got \`${count}\``); + } + if (typeof indent !== "string") { + throw new TypeError(`Expected \`options.indent\` to be a \`string\`, got \`${typeof indent}\``); + } + if (count === 0) { + return string; + } + const regex = includeEmptyLines ? /^/gm : /^(?!\s*$)/gm; + return string.replace(regex, indent.repeat(count)); +} +export default indentString; diff --git a/examples/build-http/webpack.lock.data/https_cdn.skypack.dev/p-map_85ed609042d47e169edd b/examples/build-http/webpack.lock.data/https_cdn.skypack.dev/p-map_85ed609042d47e169edd new file mode 100644 index 00000000000..aca926092c6 --- /dev/null +++ b/examples/build-http/webpack.lock.data/https_cdn.skypack.dev/p-map_85ed609042d47e169edd @@ -0,0 +1,16 @@ +/* + * Skypack CDN - p-map@5.1.0 + * + * Learn more: + * ๐Ÿ“™ Package Documentation: https://www.skypack.dev/view/p-map + * ๐Ÿ“˜ Skypack Documentation: https://www.skypack.dev/docs + * + * Pinned URL: (Optimized for Production) + * โ–ถ๏ธ Normal: https://cdn.skypack.dev/pin/p-map@v5.1.0-7ixXvZxXPKKt9unR9LT0/mode=imports/optimized/p-map.js + * โฉ Minified: https://cdn.skypack.dev/pin/p-map@v5.1.0-7ixXvZxXPKKt9unR9LT0/mode=imports,min/optimized/p-map.js + * + */ + +// Browser-Optimized Imports (Don't directly import the URLs below in your application!) +export * from '/-/p-map@v5.1.0-7ixXvZxXPKKt9unR9LT0/dist=es2020,mode=imports/optimized/p-map.js'; +export {default} from '/-/p-map@v5.1.0-7ixXvZxXPKKt9unR9LT0/dist=es2020,mode=imports/optimized/p-map.js'; diff --git a/examples/build-http/webpack.lock.data/https_cdn.skypack.dev/p-map_v5.1.0-7ixXvZxXPKKt9unR9LT0_dist_es2020_mode_imports_optimized_p-map_ddf2a76b117954d701e6.js b/examples/build-http/webpack.lock.data/https_cdn.skypack.dev/p-map_v5.1.0-7ixXvZxXPKKt9unR9LT0_dist_es2020_mode_imports_optimized_p-map_ddf2a76b117954d701e6.js new file mode 100644 index 00000000000..921f352df03 --- /dev/null +++ b/examples/build-http/webpack.lock.data/https_cdn.skypack.dev/p-map_v5.1.0-7ixXvZxXPKKt9unR9LT0_dist_es2020_mode_imports_optimized_p-map_ddf2a76b117954d701e6.js @@ -0,0 +1,79 @@ +import AggregateError from "/-/aggregate-error@v4.0.0-rCH8s5R9g4kQQ807o58j/dist=es2020,mode=imports/optimized/aggregate-error.js"; +async function pMap(iterable, mapper, { + concurrency = Number.POSITIVE_INFINITY, + stopOnError = true +} = {}) { + return new Promise((resolve, reject) => { + if (typeof mapper !== "function") { + throw new TypeError("Mapper function is required"); + } + if (!((Number.isSafeInteger(concurrency) || concurrency === Number.POSITIVE_INFINITY) && concurrency >= 1)) { + throw new TypeError(`Expected \`concurrency\` to be an integer from 1 and up or \`Infinity\`, got \`${concurrency}\` (${typeof concurrency})`); + } + const result = []; + const errors = []; + const skippedIndexes = []; + const iterator = iterable[Symbol.iterator](); + let isRejected = false; + let isIterableDone = false; + let resolvingCount = 0; + let currentIndex = 0; + const next = () => { + if (isRejected) { + return; + } + const nextItem = iterator.next(); + const index = currentIndex; + currentIndex++; + if (nextItem.done) { + isIterableDone = true; + if (resolvingCount === 0) { + if (!stopOnError && errors.length > 0) { + reject(new AggregateError(errors)); + } else { + for (const skippedIndex of skippedIndexes) { + result.splice(skippedIndex, 1); + } + resolve(result); + } + } + return; + } + resolvingCount++; + (async () => { + try { + const element = await nextItem.value; + if (isRejected) { + return; + } + const value = await mapper(element, index); + if (value === pMapSkip) { + skippedIndexes.push(index); + } else { + result[index] = value; + } + resolvingCount--; + next(); + } catch (error) { + if (stopOnError) { + isRejected = true; + reject(error); + } else { + errors.push(error); + resolvingCount--; + next(); + } + } + })(); + }; + for (let index = 0; index < concurrency; index++) { + next(); + if (isIterableDone) { + break; + } + } + }); +} +const pMapSkip = Symbol("skip"); +export default pMap; +export {pMapSkip}; diff --git a/examples/build-http/webpack.lock.data/https_jspm.dev/npm_aggregate-error_4.0_50f751f77af91e405af4.0 b/examples/build-http/webpack.lock.data/https_jspm.dev/npm_aggregate-error_4.0_50f751f77af91e405af4.0 new file mode 100644 index 00000000000..65063d10575 --- /dev/null +++ b/examples/build-http/webpack.lock.data/https_jspm.dev/npm_aggregate-error_4.0_50f751f77af91e405af4.0 @@ -0,0 +1,48 @@ +import indentString from './npm:indent-string@5'; +import cleanStack from './npm:clean-stack@4'; + +const cleanInternalStack = stack => stack.replace(/\s+at .*aggregate-error\/index.js:\d+:\d+\)?/g, ''); + +class AggregateError extends Error { + #errors; + + name = 'AggregateError'; + + constructor(errors) { + if (!Array.isArray(errors)) { + throw new TypeError(`Expected input to be an Array, got ${typeof errors}`); + } + + errors = errors.map(error => { + if (error instanceof Error) { + return error; + } + + if (error !== null && typeof error === 'object') { + // Handle plain error objects with message property and/or possibly other metadata + return Object.assign(new Error(error.message), error); + } + + return new Error(error); + }); + + let message = errors + .map(error => { + // The `stack` property is not standardized, so we can't assume it exists + return typeof error.stack === 'string' ? cleanInternalStack(cleanStack(error.stack)) : String(error); + }) + .join('\n'); + message = '\n' + indentString(message, 4); + super(message); + + this.#errors = errors; + } + + get errors() { + return this.#errors.slice(); + } +} + +export default AggregateError; + +//# sourceMappingURL=npm:aggregate-error@4.0.0.map \ No newline at end of file diff --git a/examples/build-http/webpack.lock.data/https_jspm.dev/npm_aggregate-error_4_a354b9220c6e41b430f0 b/examples/build-http/webpack.lock.data/https_jspm.dev/npm_aggregate-error_4_a354b9220c6e41b430f0 new file mode 100644 index 00000000000..511f78a97ed --- /dev/null +++ b/examples/build-http/webpack.lock.data/https_jspm.dev/npm_aggregate-error_4_a354b9220c6e41b430f0 @@ -0,0 +1,3 @@ +import "/npm:indent-string@5"; +import "/npm:clean-stack@4"; +export { default } from "/npm:aggregate-error@4.0.0"; diff --git a/examples/build-http/webpack.lock.data/https_jspm.dev/npm_clean-stack_4.1_b2805ba009abd32b0160.0 b/examples/build-http/webpack.lock.data/https_jspm.dev/npm_clean-stack_4.1_b2805ba009abd32b0160.0 new file mode 100644 index 00000000000..8d14e04d2a0 --- /dev/null +++ b/examples/build-http/webpack.lock.data/https_jspm.dev/npm_clean-stack_4.1_b2805ba009abd32b0160.0 @@ -0,0 +1,52 @@ +import os from './npm:@jspm/core@2/nodelibs/os'; +import escapeStringRegexp from './npm:escape-string-regexp@5.0.0'; + +const extractPathRegex = /\s+at.*[(\s](.*)\)?/; +const pathRegex = /^(?:(?:(?:node|node:[\w/]+|(?:(?:node:)?internal\/[\w/]*|.*node_modules\/(?:babel-polyfill|pirates)\/.*)?\w+)(?:\.js)?:\d+:\d+)|native)/; +const homeDir = typeof os.homedir === 'undefined' ? '' : os.homedir().replace(/\\/g, '/'); + +function cleanStack(stack, {pretty = false, basePath} = {}) { + const basePathRegex = basePath && new RegExp(`(at | \\()${escapeStringRegexp(basePath.replace(/\\/g, '/'))}`, 'g'); + + if (typeof stack !== 'string') { + return undefined; + } + + return stack.replace(/\\/g, '/') + .split('\n') + .filter(line => { + const pathMatches = line.match(extractPathRegex); + if (pathMatches === null || !pathMatches[1]) { + return true; + } + + const match = pathMatches[1]; + + // Electron + if ( + match.includes('.app/Contents/Resources/electron.asar') || + match.includes('.app/Contents/Resources/default_app.asar') + ) { + return false; + } + + return !pathRegex.test(match); + }) + .filter(line => line.trim() !== '') + .map(line => { + if (basePathRegex) { + line = line.replace(basePathRegex, '$1'); + } + + if (pretty) { + line = line.replace(extractPathRegex, (m, p1) => m.replace(p1, p1.replace(homeDir, '~'))); + } + + return line; + }) + .join('\n'); +} + +export default cleanStack; + +//# sourceMappingURL=npm:clean-stack@4.1.0.map \ No newline at end of file diff --git a/examples/build-http/webpack.lock.data/https_jspm.dev/npm_clean-stack_4_760ca83301f78911741b b/examples/build-http/webpack.lock.data/https_jspm.dev/npm_clean-stack_4_760ca83301f78911741b new file mode 100644 index 00000000000..256472ccdd7 --- /dev/null +++ b/examples/build-http/webpack.lock.data/https_jspm.dev/npm_clean-stack_4_760ca83301f78911741b @@ -0,0 +1,3 @@ +import "/npm:@jspm/core@2/nodelibs/os"; +import "/npm:escape-string-regexp@5.0.0"; +export { default } from "/npm:clean-stack@4.1.0"; diff --git a/examples/build-http/webpack.lock.data/https_jspm.dev/npm_escape-string-regexp_5.0_703470061c4748c30ba2.0 b/examples/build-http/webpack.lock.data/https_jspm.dev/npm_escape-string-regexp_5.0_703470061c4748c30ba2.0 new file mode 100644 index 00000000000..3e1c303b111 --- /dev/null +++ b/examples/build-http/webpack.lock.data/https_jspm.dev/npm_escape-string-regexp_5.0_703470061c4748c30ba2.0 @@ -0,0 +1,15 @@ +function escapeStringRegexp(string) { + if (typeof string !== 'string') { + throw new TypeError('Expected a string'); + } + + // Escape characters with special meaning either inside or outside character sets. + // Use a simple backslash escape when itโ€™s always valid, and a `\xnn` escape when the simpler form would be disallowed by Unicode patternsโ€™ stricter grammar. + return string + .replace(/[|\\{}()[\]^$+*?.]/g, '\\$&') + .replace(/-/g, '\\x2d'); +} + +export default escapeStringRegexp; + +//# sourceMappingURL=npm:escape-string-regexp@5.0.0.map \ No newline at end of file diff --git a/examples/build-http/webpack.lock.data/https_jspm.dev/npm_indent-string_5.0_39c50c3c56a92bbf73ba.0 b/examples/build-http/webpack.lock.data/https_jspm.dev/npm_indent-string_5.0_39c50c3c56a92bbf73ba.0 new file mode 100644 index 00000000000..f4ccda81d23 --- /dev/null +++ b/examples/build-http/webpack.lock.data/https_jspm.dev/npm_indent-string_5.0_39c50c3c56a92bbf73ba.0 @@ -0,0 +1,42 @@ +function indentString(string, count = 1, options = {}) { + const { + indent = ' ', + includeEmptyLines = false + } = options; + + if (typeof string !== 'string') { + throw new TypeError( + `Expected \`input\` to be a \`string\`, got \`${typeof string}\`` + ); + } + + if (typeof count !== 'number') { + throw new TypeError( + `Expected \`count\` to be a \`number\`, got \`${typeof count}\`` + ); + } + + if (count < 0) { + throw new RangeError( + `Expected \`count\` to be at least 0, got \`${count}\`` + ); + } + + if (typeof indent !== 'string') { + throw new TypeError( + `Expected \`options.indent\` to be a \`string\`, got \`${typeof indent}\`` + ); + } + + if (count === 0) { + return string; + } + + const regex = includeEmptyLines ? /^/gm : /^(?!\s*$)/gm; + + return string.replace(regex, indent.repeat(count)); +} + +export default indentString; + +//# sourceMappingURL=npm:indent-string@5.0.0.map \ No newline at end of file diff --git a/examples/build-http/webpack.lock.data/https_jspm.dev/npm_indent-string_5_01a4f4bd5c5dc36ce1b7 b/examples/build-http/webpack.lock.data/https_jspm.dev/npm_indent-string_5_01a4f4bd5c5dc36ce1b7 new file mode 100644 index 00000000000..f8b9348076a --- /dev/null +++ b/examples/build-http/webpack.lock.data/https_jspm.dev/npm_indent-string_5_01a4f4bd5c5dc36ce1b7 @@ -0,0 +1 @@ +export { default } from "/npm:indent-string@5.0.0"; diff --git a/examples/build-http/webpack.lock.data/https_jspm.dev/npm_jspm_core_2.0.0-beta_12b8110471722e74fcb6.11_nodelibs_process b/examples/build-http/webpack.lock.data/https_jspm.dev/npm_jspm_core_2.0.0-beta_12b8110471722e74fcb6.11_nodelibs_process new file mode 100644 index 00000000000..203f79bb446 --- /dev/null +++ b/examples/build-http/webpack.lock.data/https_jspm.dev/npm_jspm_core_2.0.0-beta_12b8110471722e74fcb6.11_nodelibs_process @@ -0,0 +1,277 @@ +function unimplemented(name) { + throw new Error('Node.js process ' + name + ' is not supported by JSPM core outside of Node.js'); +} + +var queue = []; +var draining = false; +var currentQueue; +var queueIndex = -1; + +function cleanUpNextTick() { + if (!draining || !currentQueue) + return; + draining = false; + if (currentQueue.length) { + queue = currentQueue.concat(queue); + } + else { + queueIndex = -1; + } + if (queue.length) + drainQueue(); +} + +function drainQueue() { + if (draining) + return; + var timeout = setTimeout(cleanUpNextTick, 0); + draining = true; + + var len = queue.length; + while(len) { + currentQueue = queue; + queue = []; + while (++queueIndex < len) { + if (currentQueue) + currentQueue[queueIndex].run(); + } + queueIndex = -1; + len = queue.length; + } + currentQueue = null; + draining = false; + clearTimeout(timeout); +} + +function nextTick (fun) { + var args = new Array(arguments.length - 1); + if (arguments.length > 1) { + for (var i = 1; i < arguments.length; i++) + args[i - 1] = arguments[i]; + } + queue.push(new Item(fun, args)); + if (queue.length === 1 && !draining) + setTimeout(drainQueue, 0); +} +// v8 likes predictible objects +function Item(fun, array) { + this.fun = fun; + this.array = array; +} +Item.prototype.run = function () { + this.fun.apply(null, this.array); +}; + +var title = 'browser'; +var arch = 'x64'; +var platform = 'browser'; +var env = { + PATH: '/usr/bin', + LANG: navigator.language + '.UTF-8', + PWD: '/', + HOME: '/home', + TMP: '/tmp', +}; +var argv = ['/usr/bin/node']; +var execArgv = []; +var version = 'v16.8.0'; +var versions = { node: '16.8.0' }; + +var emitWarning = function(message, type) { + console.warn((type ? (type + ': ') : '') + message); +}; + +var binding = function(name) { unimplemented('binding'); }; + +var umask = function(mask) { return 0; }; + +var cwd = function() { return '/'; }; +var chdir = function(dir) {}; + +var release = { + name: 'node', + sourceUrl: '', + headersUrl: '', + libUrl: '', +}; + +function noop() {} + +var _rawDebug = noop; +var moduleLoadList = []; +function _linkedBinding(name) { unimplemented('_linkedBinding'); } +var domain = {}; +var _exiting = false; +var config = {}; +function dlopen(name) { unimplemented('dlopen'); } +function _getActiveRequests() { return []; } +function _getActiveHandles() { return []; } +var reallyExit = noop; +var _kill = noop; +var cpuUsage = function() { return {}; }; +var resourceUsage = cpuUsage; +var memoryUsage = cpuUsage; +var kill = noop; +var exit = noop; +var openStdin = noop; +var allowedNodeEnvironmentFlags = {}; +function assert(condition, message) { + if (!condition) throw new Error(message || 'assertion error'); +} +var features = { + inspector: false, + debug: false, + uv: false, + ipv6: false, + tls_alpn: false, + tls_sni: false, + tls_ocsp: false, + tls: false, + cached_builtins: true, +}; +var _fatalExceptions = noop; +var setUncaughtExceptionCaptureCallback = noop; +function hasUncaughtExceptionCaptureCallback() { return false; }var _tickCallback = noop; +var _debugProcess = noop; +var _debugEnd = noop; +var _startProfilerIdleNotifier = noop; +var _stopProfilerIdleNotifier = noop; +var stdout = undefined; +var stderr = undefined; +var stdin = undefined; +var abort = noop; +var pid = 2; +var ppid = 1; +var execPath = '/bin/usr/node'; +var debugPort = 9229; +var argv0 = 'node'; +var _preload_modules = []; +var setSourceMapsEnabled = noop; + +var _performance = { + now: typeof performance !== 'undefined' ? performance.now.bind(performance) : undefined, + timing: typeof performance !== 'undefined' ? performance.timing : undefined, +}; +if (_performance.now === undefined) { + var nowOffset = Date.now(); + + if (_performance.timing && _performance.timing.navigationStart) { + nowOffset = _performance.timing.navigationStart; + } + _performance.now = () => Date.now() - nowOffset; +} + +function uptime() { + return _performance.now() / 1000; +} + +var nanoPerSec = 1000000000; +function hrtime(previousTimestamp) { + var baseNow = Math.floor((Date.now() - _performance.now()) * 1e-3); + var clocktime = _performance.now() * 1e-3; + var seconds = Math.floor(clocktime) + baseNow; + var nanoseconds = Math.floor((clocktime % 1) * 1e9); + if (previousTimestamp) { + seconds = seconds - previousTimestamp[0]; + nanoseconds = nanoseconds - previousTimestamp[1]; + if (nanoseconds < 0) { + seconds--; + nanoseconds += nanoPerSec; + } + } + return [seconds, nanoseconds]; +}hrtime.bigint = function(time) { + var diff = hrtime(time); + if (typeof BigInt === 'undefined') { + return diff[0] * nanoPerSec + diff[1]; + } + return BigInt(diff[0] * nanoPerSec) + BigInt(diff[1]); +}; + +var _maxListeners = 10; +var _events = {}; +var _eventsCount = 0; +function on () { return process }var addListener = on; +var once = on; +var off = on; +var removeListener = on; +var removeAllListeners = on; +var emit = noop; +var prependListener = on; +var prependOnceListener = on; +function listeners (name) { return []; } +var process = { + version, + versions, + arch, + platform, + release, + _rawDebug, + moduleLoadList, + binding, + _linkedBinding, + _events, + _eventsCount, + _maxListeners, + on, + addListener, + once, + off, + removeListener, + removeAllListeners, + emit, + prependListener, + prependOnceListener, + listeners, + domain, + _exiting, + config, + dlopen, + uptime, + _getActiveRequests, + _getActiveHandles, + reallyExit, + _kill, + cpuUsage, + resourceUsage, + memoryUsage, + kill, + exit, + openStdin, + allowedNodeEnvironmentFlags, + assert, + features, + _fatalExceptions, + setUncaughtExceptionCaptureCallback, + hasUncaughtExceptionCaptureCallback, + emitWarning, + nextTick, + _tickCallback, + _debugProcess, + _debugEnd, + _startProfilerIdleNotifier, + _stopProfilerIdleNotifier, + stdout, + stdin, + stderr, + abort, + umask, + chdir, + cwd, + env, + title, + argv, + execArgv, + pid, + ppid, + execPath, + debugPort, + hrtime, + argv0, + _preload_modules, + setSourceMapsEnabled, +}; + +export { _debugEnd, _debugProcess, _events, _eventsCount, _exiting, _fatalExceptions, _getActiveHandles, _getActiveRequests, _kill, _linkedBinding, _maxListeners, _preload_modules, _rawDebug, _startProfilerIdleNotifier, _stopProfilerIdleNotifier, _tickCallback, abort, addListener, allowedNodeEnvironmentFlags, arch, argv, argv0, assert, binding, chdir, config, cpuUsage, cwd, debugPort, process as default, dlopen, domain, emit, emitWarning, env, execArgv, execPath, exit, features, hasUncaughtExceptionCaptureCallback, hrtime, kill, listeners, memoryUsage, moduleLoadList, nextTick, off, on, once, openStdin, pid, platform, ppid, prependListener, prependOnceListener, reallyExit, release, removeAllListeners, removeListener, resourceUsage, setSourceMapsEnabled, setUncaughtExceptionCaptureCallback, stderr, stdin, stdout, title, umask, uptime, version, versions }; + +//# sourceMappingURL=process.map \ No newline at end of file diff --git a/examples/build-http/webpack.lock.data/https_jspm.dev/npm_jspm_core_2.0.0-beta_1620e8f9e144fe702a06.11_nodelibs_os b/examples/build-http/webpack.lock.data/https_jspm.dev/npm_jspm_core_2.0.0-beta_1620e8f9e144fe702a06.11_nodelibs_os new file mode 100644 index 00000000000..65ca57a8711 --- /dev/null +++ b/examples/build-http/webpack.lock.data/https_jspm.dev/npm_jspm_core_2.0.0-beta_1620e8f9e144fe702a06.11_nodelibs_os @@ -0,0 +1,113 @@ +import { uptime } from './process'; +export { uptime } from './process'; + +var exports = {}, + _dewExec = false; +function dew() { + if (_dewExec) return exports; + _dewExec = true; + + exports.endianness = function () { + return "LE"; + }; + + exports.hostname = function () { + if (typeof location !== "undefined") { + return location.hostname; + } else return ""; + }; + + exports.loadavg = function () { + return []; + }; + + exports.uptime = function () { + return 0; + }; + + exports.freemem = function () { + return Number.MAX_VALUE; + }; + + exports.totalmem = function () { + return Number.MAX_VALUE; + }; + + exports.cpus = function () { + return []; + }; + + exports.type = function () { + return "Browser"; + }; + + exports.release = function () { + if (typeof navigator !== "undefined") { + return navigator.appVersion; + } + + return ""; + }; + + exports.networkInterfaces = exports.getNetworkInterfaces = function () { + return {}; + }; + + exports.arch = function () { + return "javascript"; + }; + + exports.platform = function () { + return "browser"; + }; + + exports.tmpdir = exports.tmpDir = function () { + return "/tmp"; + }; + + exports.EOL = "\n"; + + exports.homedir = function () { + return "/"; + }; + + return exports; +} + +var os = dew(); + +var _endianness = new Uint8Array(new Uint16Array([1]).buffer)[0] === 1 ? 'LE' : 'BE'; +os.endianness = function() { return _endianness; }; +os.homedir = function() { return '/home'; }; +os.version = function() { return ''; }; +os.arch = function() { return 'x64'; }; +os.totalmem = function() { + return navigator.deviceMemory !== undefined ? navigator.deviceMemory * (1 << 30) : 2 * (1 << 30); +}; +os.cpus = function () { + return Array(navigator.hardwareConcurrency || 0).fill({ model: '', times: {} }); +}; +os.uptime = uptime; +os.constants = {}; +var version = os.version; +var constants = os.constants; +var EOL = os.EOL; +var arch = os.arch; +var cpus = os.cpus; +var endianness = os.endianness; +var freemem = os.freemem; +var getNetworkInterfaces = os.getNetworkInterfaces; +var homedir = os.homedir; +var hostname = os.hostname; +var loadavg = os.loadavg; +var networkInterfaces = os.networkInterfaces; +var platform = os.platform; +var release = os.release; +var tmpDir = os.tmpDir; +var tmpdir = os.tmpdir; +var totalmem = os.totalmem; +var type = os.type; + +export { EOL, arch, constants, cpus, os as default, endianness, freemem, getNetworkInterfaces, homedir, hostname, loadavg, networkInterfaces, platform, release, tmpDir, tmpdir, totalmem, type, version }; + +//# sourceMappingURL=os.map \ No newline at end of file diff --git a/examples/build-http/webpack.lock.data/https_jspm.dev/npm_jspm_core_2_nodelibs_os_3fe9447e10c5fed754bb b/examples/build-http/webpack.lock.data/https_jspm.dev/npm_jspm_core_2_nodelibs_os_3fe9447e10c5fed754bb new file mode 100644 index 00000000000..4accb6487ef --- /dev/null +++ b/examples/build-http/webpack.lock.data/https_jspm.dev/npm_jspm_core_2_nodelibs_os_3fe9447e10c5fed754bb @@ -0,0 +1,3 @@ +import "/npm:@jspm/core@2.0.0-beta.11/nodelibs/process"; +export * from "/npm:@jspm/core@2.0.0-beta.11/nodelibs/os"; +export { default } from "/npm:@jspm/core@2.0.0-beta.11/nodelibs/os"; diff --git a/examples/build-http/webpack.lock.data/https_jspm.dev/npm_p-map_5.1_9895e1a83d37d06ab277.0 b/examples/build-http/webpack.lock.data/https_jspm.dev/npm_p-map_5.1_9895e1a83d37d06ab277.0 new file mode 100644 index 00000000000..5166d74476e --- /dev/null +++ b/examples/build-http/webpack.lock.data/https_jspm.dev/npm_p-map_5.1_9895e1a83d37d06ab277.0 @@ -0,0 +1,103 @@ +import AggregateError from './npm:aggregate-error@4'; + +async function pMap( + iterable, + mapper, + { + concurrency = Number.POSITIVE_INFINITY, + stopOnError = true + } = {} +) { + return new Promise((resolve, reject) => { + if (typeof mapper !== 'function') { + throw new TypeError('Mapper function is required'); + } + + if (!((Number.isSafeInteger(concurrency) || concurrency === Number.POSITIVE_INFINITY) && concurrency >= 1)) { + throw new TypeError(`Expected \`concurrency\` to be an integer from 1 and up or \`Infinity\`, got \`${concurrency}\` (${typeof concurrency})`); + } + + const result = []; + const errors = []; + const skippedIndexes = []; + const iterator = iterable[Symbol.iterator](); + let isRejected = false; + let isIterableDone = false; + let resolvingCount = 0; + let currentIndex = 0; + + const next = () => { + if (isRejected) { + return; + } + + const nextItem = iterator.next(); + const index = currentIndex; + currentIndex++; + + if (nextItem.done) { + isIterableDone = true; + + if (resolvingCount === 0) { + if (!stopOnError && errors.length > 0) { + reject(new AggregateError(errors)); + } else { + for (const skippedIndex of skippedIndexes) { + result.splice(skippedIndex, 1); + } + + resolve(result); + } + } + + return; + } + + resolvingCount++; + + (async () => { + try { + const element = await nextItem.value; + + if (isRejected) { + return; + } + + const value = await mapper(element, index); + if (value === pMapSkip) { + skippedIndexes.push(index); + } else { + result[index] = value; + } + + resolvingCount--; + next(); + } catch (error) { + if (stopOnError) { + isRejected = true; + reject(error); + } else { + errors.push(error); + resolvingCount--; + next(); + } + } + })(); + }; + + for (let index = 0; index < concurrency; index++) { + next(); + + if (isIterableDone) { + break; + } + } + }); +} + +const pMapSkip = Symbol('skip'); + +export default pMap; +export { pMapSkip }; + +//# sourceMappingURL=npm:p-map@5.1.0.map \ No newline at end of file diff --git a/examples/build-http/webpack.lock.data/https_jspm.dev/p-map_875efed0b6bd20646dd2 b/examples/build-http/webpack.lock.data/https_jspm.dev/p-map_875efed0b6bd20646dd2 new file mode 100644 index 00000000000..95b490c4578 --- /dev/null +++ b/examples/build-http/webpack.lock.data/https_jspm.dev/p-map_875efed0b6bd20646dd2 @@ -0,0 +1,3 @@ +import "/npm:aggregate-error@4"; +export * from "/npm:p-map@5.1.0"; +export { default } from "/npm:p-map@5.1.0"; diff --git a/examples/build-http/webpack.lock.data/https_unpkg.com/p-map-series_3.0.0_index_module_cb329557880410b778cf.js b/examples/build-http/webpack.lock.data/https_unpkg.com/p-map-series_3.0.0_index_module_cb329557880410b778cf.js new file mode 100644 index 00000000000..f9ee01a45ae --- /dev/null +++ b/examples/build-http/webpack.lock.data/https_unpkg.com/p-map-series_3.0.0_index_module_cb329557880410b778cf.js @@ -0,0 +1,11 @@ +export default async function pMapSeries(iterable, mapper) { + const result = []; + let index = 0; + + for (const value of iterable) { + // eslint-disable-next-line no-await-in-loop + result.push((await mapper((await value), index++))); + } + + return result; +} \ No newline at end of file diff --git a/examples/chunkhash/README.md b/examples/chunkhash/README.md index a18d19a83df..fee9f799de2 100644 --- a/examples/chunkhash/README.md +++ b/examples/chunkhash/README.md @@ -20,7 +20,7 @@ import("./async2"); ```javascript var path = require("path"); module.exports = { - // mode: "development || "production", + // mode: "development" || "production", entry: { main: "./example" }, @@ -43,7 +43,7 @@ module.exports = { @@ -69,8 +69,9 @@ module.exports = { /******/ // The require function /******/ function __webpack_require__(moduleId) { /******/ // Check if module is in cache -/******/ if(__webpack_module_cache__[moduleId]) { -/******/ return __webpack_module_cache__[moduleId].exports; +/******/ var cachedModule = __webpack_module_cache__[moduleId]; +/******/ if (cachedModule !== undefined) { +/******/ return cachedModule.exports; /******/ } /******/ // Create a new module (and put it into the cache) /******/ var module = __webpack_module_cache__[moduleId] = { @@ -89,13 +90,42 @@ module.exports = { /******/ // expose the modules object (__webpack_modules__) /******/ __webpack_require__.m = __webpack_modules__; /******/ -/******/ // the startup function -/******/ // It's empty as some runtime module handles the default behavior -/******/ __webpack_require__.x = x => {} /************************************************************************/ +/******/ /* webpack/runtime/chunk loaded */ +/******/ (() => { +/******/ var deferred = []; +/******/ __webpack_require__.O = (result, chunkIds, fn, priority) => { +/******/ if(chunkIds) { +/******/ priority = priority || 0; +/******/ for(var i = deferred.length; i > 0 && deferred[i - 1][2] > priority; i--) deferred[i] = deferred[i - 1]; +/******/ deferred[i] = [chunkIds, fn, priority]; +/******/ return; +/******/ } +/******/ var notFulfilled = Infinity; +/******/ for (var i = 0; i < deferred.length; i++) { +/******/ var [chunkIds, fn, priority] = deferred[i]; +/******/ var fulfilled = true; +/******/ for (var j = 0; j < chunkIds.length; j++) { +/******/ if ((priority & 1 === 0 || notFulfilled >= priority) && Object.keys(__webpack_require__.O).every((key) => (__webpack_require__.O[key](chunkIds[j])))) { +/******/ chunkIds.splice(j--, 1); +/******/ } else { +/******/ fulfilled = false; +/******/ if(priority < notFulfilled) notFulfilled = priority; +/******/ } +/******/ } +/******/ if(fulfilled) { +/******/ deferred.splice(i--, 1) +/******/ var r = fn(); +/******/ if (r !== undefined) result = r; +/******/ } +/******/ } +/******/ return result; +/******/ }; +/******/ })(); +/******/ /******/ /* webpack/runtime/create fake namespace object */ /******/ (() => { -/******/ var getProto = Object.getPrototypeOf ? (obj) => Object.getPrototypeOf(obj) : (obj) => obj.__proto__; +/******/ var getProto = Object.getPrototypeOf ? (obj) => (Object.getPrototypeOf(obj)) : (obj) => (obj.__proto__); /******/ var leafPrototypes; /******/ // create a fake namespace object /******/ // mode & 1: value is a module id, require it @@ -115,9 +145,9 @@ module.exports = { /******/ var def = {}; /******/ leafPrototypes = leafPrototypes || [null, getProto({}), getProto([]), getProto(getProto)]; /******/ for(var current = mode & 2 && value; typeof current == 'object' && !~leafPrototypes.indexOf(current); current = getProto(current)) { -/******/ Object.getOwnPropertyNames(current).forEach(key => def[key] = () => value[key]); +/******/ Object.getOwnPropertyNames(current).forEach((key) => (def[key] = () => (value[key]))); /******/ } -/******/ def['default'] = () => value; +/******/ def['default'] = () => (value); /******/ __webpack_require__.d(ns, def); /******/ return ns; /******/ }; @@ -159,7 +189,7 @@ module.exports = { /******/ /******/ /* webpack/runtime/hasOwnProperty shorthand */ /******/ (() => { -/******/ __webpack_require__.o = (obj, prop) => Object.prototype.hasOwnProperty.call(obj, prop) +/******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop)) /******/ })(); /******/ /******/ /* webpack/runtime/load script */ @@ -167,7 +197,7 @@ module.exports = { /******/ var inProgress = {}; /******/ // data-webpack is not used as build has no uniqueName /******/ // loadScript function to load a script via script tag -/******/ __webpack_require__.l = (url, done, key) => { +/******/ __webpack_require__.l = (url, done, key, chunkId) => { /******/ if(inProgress[url]) { inProgress[url].push(done); return; } /******/ var script, needAttach; /******/ if(key !== undefined) { @@ -197,10 +227,9 @@ module.exports = { /******/ var doneFns = inProgress[url]; /******/ delete inProgress[url]; /******/ script.parentNode && script.parentNode.removeChild(script); -/******/ doneFns && doneFns.forEach((fn) => fn(event)); +/******/ doneFns && doneFns.forEach((fn) => (fn(event))); /******/ if(prev) return prev(event); /******/ } -/******/ ; /******/ var timeout = setTimeout(onScriptComplete.bind(null, undefined, { type: 'timeout', target: script }), 120000); /******/ script.onerror = onScriptComplete.bind(null, script.onerror); /******/ script.onload = onScriptComplete.bind(null, script.onload); @@ -230,14 +259,11 @@ module.exports = { /******/ /******/ // object to store loaded and loading chunks /******/ // undefined = chunk not loaded, null = chunk preloaded/prefetched -/******/ // Promise = chunk loading, 0 = chunk loaded +/******/ // [resolve, reject, Promise] = chunk loading, 0 = chunk loaded /******/ var installedChunks = { /******/ 1: 0 /******/ }; /******/ -/******/ var deferredModules = [ -/******/ -/******/ ]; /******/ __webpack_require__.f.j = (chunkId, promises) => { /******/ // JSONP chunk loading for javascript /******/ var installedChunkData = __webpack_require__.o(installedChunks, chunkId) ? installedChunks[chunkId] : undefined; @@ -247,11 +273,9 @@ module.exports = { /******/ if(installedChunkData) { /******/ promises.push(installedChunkData[2]); /******/ } else { -/******/ if(true) { // all chunks have JS +/******/ if(1 != chunkId) { /******/ // setup Promise in chunk cache -/******/ var promise = new Promise((resolve, reject) => { -/******/ installedChunkData = installedChunks[chunkId] = [resolve, reject]; -/******/ }); +/******/ var promise = new Promise((resolve, reject) => (installedChunkData = installedChunks[chunkId] = [resolve, reject])); /******/ promises.push(installedChunkData[2] = promise); /******/ /******/ // start chunk loading @@ -273,7 +297,7 @@ module.exports = { /******/ } /******/ } /******/ }; -/******/ __webpack_require__.l(url, loadingEnded, "chunk-" + chunkId); +/******/ __webpack_require__.l(url, loadingEnded, "chunk-" + chunkId, chunkId); /******/ } else installedChunks[chunkId] = 0; /******/ } /******/ } @@ -287,69 +311,36 @@ module.exports = { /******/ /******/ // no HMR manifest /******/ -/******/ var checkDeferredModules = x => {}; +/******/ __webpack_require__.O.j = (chunkId) => (installedChunks[chunkId] === 0); /******/ /******/ // install a JSONP callback for chunk loading /******/ var webpackJsonpCallback = (parentChunkLoadingFunction, data) => { -/******/ var [chunkIds, moreModules, runtime, executeModules] = data; +/******/ var [chunkIds, moreModules, runtime] = data; /******/ // add "moreModules" to the modules object, /******/ // then flag all "chunkIds" as loaded and fire callback -/******/ var moduleId, chunkId, i = 0, resolves = []; +/******/ var moduleId, chunkId, i = 0; +/******/ if(chunkIds.some((id) => (installedChunks[id] !== 0))) { +/******/ for(moduleId in moreModules) { +/******/ if(__webpack_require__.o(moreModules, moduleId)) { +/******/ __webpack_require__.m[moduleId] = moreModules[moduleId]; +/******/ } +/******/ } +/******/ if(runtime) var result = runtime(__webpack_require__); +/******/ } +/******/ if(parentChunkLoadingFunction) parentChunkLoadingFunction(data); /******/ for(;i < chunkIds.length; i++) { /******/ chunkId = chunkIds[i]; /******/ if(__webpack_require__.o(installedChunks, chunkId) && installedChunks[chunkId]) { -/******/ resolves.push(installedChunks[chunkId][0]); +/******/ installedChunks[chunkId][0](); /******/ } /******/ installedChunks[chunkId] = 0; /******/ } -/******/ for(moduleId in moreModules) { -/******/ if(__webpack_require__.o(moreModules, moduleId)) { -/******/ __webpack_require__.m[moduleId] = moreModules[moduleId]; -/******/ } -/******/ } -/******/ if(runtime) runtime(__webpack_require__); -/******/ if(parentChunkLoadingFunction) parentChunkLoadingFunction(data); -/******/ while(resolves.length) { -/******/ resolves.shift()(); -/******/ } -/******/ -/******/ // add entry modules from loaded chunk to deferred list -/******/ if(executeModules) deferredModules.push.apply(deferredModules, executeModules); -/******/ -/******/ // run deferred modules when all chunks ready -/******/ return checkDeferredModules(); +/******/ return __webpack_require__.O(result); /******/ } /******/ /******/ var chunkLoadingGlobal = self["webpackChunk"] = self["webpackChunk"] || []; /******/ chunkLoadingGlobal.forEach(webpackJsonpCallback.bind(null, 0)); /******/ chunkLoadingGlobal.push = webpackJsonpCallback.bind(null, chunkLoadingGlobal.push.bind(chunkLoadingGlobal)); -/******/ -/******/ function checkDeferredModulesImpl() { -/******/ var result; -/******/ for(var i = 0; i < deferredModules.length; i++) { -/******/ var deferredModule = deferredModules[i]; -/******/ var fulfilled = true; -/******/ for(var j = 1; j < deferredModule.length; j++) { -/******/ var depId = deferredModule[j]; -/******/ if(installedChunks[depId] !== 0) fulfilled = false; -/******/ } -/******/ if(fulfilled) { -/******/ deferredModules.splice(i--, 1); -/******/ result = __webpack_require__(__webpack_require__.s = deferredModule[0]); -/******/ } -/******/ } -/******/ if(deferredModules.length === 0) { -/******/ __webpack_require__.x(); -/******/ __webpack_require__.x = x => {}; -/******/ } -/******/ return result; -/******/ } -/******/ var startup = __webpack_require__.x; -/******/ __webpack_require__.x = () => { -/******/ // reset startup function so it can be called again when more startup code is added -/******/ __webpack_require__.x = startup || (x => {}); -/******/ return (checkDeferredModules = checkDeferredModulesImpl)(); -/******/ }; /******/ })(); /******/ /************************************************************************/ @@ -358,8 +349,8 @@ module.exports = { ``` js -/******/ // run startup -/******/ return __webpack_require__.x(); +/******/ +/******/ /******/ })() ; ``` @@ -383,7 +374,11 @@ __webpack_require__.e(/*! import() */ 3).then(__webpack_require__.t.bind(__webpa /***/ }) ], -0,[[0,1]]]); +/******/ __webpack_require__ => { // webpackRuntimeModules +/******/ var __webpack_exec__ = (moduleId) => (__webpack_require__(__webpack_require__.s = moduleId)) +/******/ var __webpack_exports__ = (__webpack_exec__(0)); +/******/ } +]); ``` # Info @@ -391,19 +386,19 @@ __webpack_require__.e(/*! import() */ 3).then(__webpack_require__.t.bind(__webpa ## Unoptimized ``` -asset runtime~main.[chunkhash].js 12.5 KiB [emitted] (name: runtime~main) -asset main.[chunkhash].js 652 bytes [emitted] (name: main) +asset runtime~main.[chunkhash].js 12.2 KiB [emitted] (name: runtime~main) +asset main.[chunkhash].js 873 bytes [emitted] (name: main) asset 2.[chunkhash].js 285 bytes [emitted] asset 3.[chunkhash].js 279 bytes [emitted] -Entrypoint main 13.1 KiB = runtime~main.[chunkhash].js 12.5 KiB main.[chunkhash].js 652 bytes +Entrypoint main 13 KiB = runtime~main.[chunkhash].js 12.2 KiB main.[chunkhash].js 873 bytes chunk (runtime: runtime~main) main.[chunkhash].js (main) 55 bytes [initial] [rendered] > ./example main ./example.js 55 bytes [built] [code generated] [used exports unknown] entry ./example main -chunk (runtime: runtime~main) runtime~main.[chunkhash].js (runtime~main) 7.7 KiB [entry] [rendered] +chunk (runtime: runtime~main) runtime~main.[chunkhash].js (runtime~main) 7.59 KiB [entry] [rendered] > ./example main - runtime modules 7.7 KiB 9 modules + runtime modules 7.59 KiB 10 modules chunk (runtime: runtime~main) 2.[chunkhash].js 28 bytes [rendered] > ./async1 ./example.js 2:0-18 ./async1.js 28 bytes [built] [code generated] @@ -414,17 +409,17 @@ chunk (runtime: runtime~main) 3.[chunkhash].js 28 bytes [rendered] ./async2.js 28 bytes [built] [code generated] [used exports unknown] import() ./async2 ./example.js 3:0-18 -webpack 5.11.1 compiled successfully +webpack 5.78.0 compiled successfully ``` ## Production mode ``` -asset runtime~main.[chunkhash].js 2.63 KiB [emitted] [minimized] (name: runtime~main) -asset main.[chunkhash].js 155 bytes [emitted] [minimized] (name: main) +asset runtime~main.[chunkhash].js 2.73 KiB [emitted] [minimized] (name: runtime~main) +asset main.[chunkhash].js 157 bytes [emitted] [minimized] (name: main) asset 114.[chunkhash].js 69 bytes [emitted] [minimized] asset 172.[chunkhash].js 69 bytes [emitted] [minimized] -Entrypoint main 2.78 KiB = runtime~main.[chunkhash].js 2.63 KiB main.[chunkhash].js 155 bytes +Entrypoint main 2.88 KiB = runtime~main.[chunkhash].js 2.73 KiB main.[chunkhash].js 157 bytes chunk (runtime: runtime~main) 114.[chunkhash].js 28 bytes [rendered] > ./async1 ./example.js 2:0-18 ./async1.js 28 bytes [built] [code generated] @@ -440,8 +435,8 @@ chunk (runtime: runtime~main) main.[chunkhash].js (main) 55 bytes [initial] [ren ./example.js 55 bytes [built] [code generated] [no exports used] entry ./example main -chunk (runtime: runtime~main) runtime~main.[chunkhash].js (runtime~main) 7.7 KiB [entry] [rendered] +chunk (runtime: runtime~main) runtime~main.[chunkhash].js (runtime~main) 7.59 KiB [entry] [rendered] > ./example main - runtime modules 7.7 KiB 9 modules -webpack 5.11.1 compiled successfully + runtime modules 7.59 KiB 10 modules +webpack 5.78.0 compiled successfully ``` diff --git a/examples/chunkhash/webpack.config.js b/examples/chunkhash/webpack.config.js index cc34d5591f9..727e187cf1b 100644 --- a/examples/chunkhash/webpack.config.js +++ b/examples/chunkhash/webpack.config.js @@ -1,6 +1,7 @@ -var path = require("path"); +const path = require("path"); + module.exports = { - // mode: "development || "production", + // mode: "development" || "production", entry: { main: "./example" }, diff --git a/examples/cjs-tree-shaking/README.md b/examples/cjs-tree-shaking/README.md index 99aac42c798..de5a11748f0 100644 --- a/examples/cjs-tree-shaking/README.md +++ b/examples/cjs-tree-shaking/README.md @@ -65,7 +65,7 @@ exports.multiply = function multiply() { /***/ ((__unused_webpack_module, exports, __webpack_require__) => { var __webpack_unused_export__; -const add = __webpack_require__(/*! ./math */ 2)/* .add */ .I; +const add = (__webpack_require__(/*! ./math */ 2)/* .add */ .I); exports.nP = function increment(val) { return add(val, 1); }; @@ -126,8 +126,9 @@ __webpack_unused_export__ = function multiply() { /******/ // The require function /******/ function __webpack_require__(moduleId) { /******/ // Check if module is in cache -/******/ if(__webpack_module_cache__[moduleId]) { -/******/ return __webpack_module_cache__[moduleId].exports; +/******/ var cachedModule = __webpack_module_cache__[moduleId]; +/******/ if (cachedModule !== undefined) { +/******/ return cachedModule.exports; /******/ } /******/ // Create a new module (and put it into the cache) /******/ var module = __webpack_module_cache__[moduleId] = { @@ -149,13 +150,15 @@ __webpack_unused_export__ = function multiply() { ``` js +var __webpack_exports__ = {}; +// This entry need to be wrapped in an IIFE because it need to be isolated against other modules in the chunk. (() => { /*!********************!*\ !*** ./example.js ***! \********************/ /*! unknown exports (runtime-defined) */ /*! runtime requirements: __webpack_require__ */ -const inc = __webpack_require__(/*! ./increment */ 1)/* .increment */ .nP; +const inc = (__webpack_require__(/*! ./increment */ 1)/* .increment */ .nP); var a = 1; inc(a); // 2 @@ -169,14 +172,14 @@ inc(a); // 2 ```javascript /*! For license information please see output.js.LICENSE.txt */ -(()=>{var r=[,(r,n,t)=>{const e=t(2).I;n.nP=function(r){return e(r,1)}},(r,n)=>{n.I=function(){for(var r=0,n=0,t=arguments,e=t.length;n{var r=[,(r,n,t)=>{const o=t(2).I;n.nP=function(r){return o(r,1)}},(r,n)=>{n.I=function(){for(var r=0,n=0,t=arguments,o=t.length;n{var n=[,(n,r,t)=>{const e=t(2).add;r.increment=function(n){return e(n,1)},r.incrementBy2=function(n){return e(n,2)},r.decrement=function(n){return e(n,1)}},(n,r)=>{r.add=function(){for(var n=0,r=0,t=arguments,e=t.length;r{var n=[,(n,r,t)=>{const e=t(2).add;r.increment=function(n){return e(n,1)},r.incrementBy2=function(n){return e(n,2)},r.decrement=function(n){return e(n,1)}},(n,r)=>{r.add=function(){for(var n=0,r=0,t=arguments,e=t.length;r ./example.js main dependent modules 564 bytes [dependent] 2 modules ./example.js 70 bytes [built] [code generated] [no exports used] entry ./example.js main -webpack 5.11.1 compiled successfully +webpack 5.78.0 compiled successfully -asset without.js 2.91 KiB [emitted] (name: main) +asset without.js 3.08 KiB [emitted] (name: main) chunk (runtime: main) without.js (main) 634 bytes [entry] [rendered] > ./example.js main dependent modules 564 bytes [dependent] 2 modules ./example.js 70 bytes [built] [code generated] [used exports unknown] entry ./example.js main -webpack 5.11.1 compiled successfully +webpack 5.78.0 compiled successfully ``` ## Production mode ``` -asset output.js 351 bytes [emitted] [minimized] (name: main) 1 related asset +asset output.js 365 bytes [emitted] [minimized] (name: main) 1 related asset chunk (runtime: main) output.js (main) 634 bytes [entry] [rendered] > ./example.js main dependent modules 564 bytes [dependent] 2 modules ./example.js 70 bytes [built] [code generated] [no exports used] entry ./example.js main -webpack 5.11.1 compiled successfully +webpack 5.78.0 compiled successfully -asset without.js 537 bytes [emitted] [minimized] (name: main) 1 related asset +asset without.js 551 bytes [emitted] [minimized] (name: main) 1 related asset chunk (runtime: main) without.js (main) 634 bytes [entry] [rendered] > ./example.js main dependent modules 564 bytes [dependent] 2 modules ./example.js 70 bytes [built] [code generated] [used exports unknown] entry ./example.js main -webpack 5.11.1 compiled successfully +webpack 5.78.0 compiled successfully ``` diff --git a/examples/code-splitted-require.context-amd/README.md b/examples/code-splitted-require.context-amd/README.md index 0645f2375a2..abe1922c425 100644 --- a/examples/code-splitted-require.context-amd/README.md +++ b/examples/code-splitted-require.context-amd/README.md @@ -31,8 +31,9 @@ getTemplate("b", function(b) { /******/ // The require function /******/ function __webpack_require__(moduleId) { /******/ // Check if module is in cache -/******/ if(__webpack_module_cache__[moduleId]) { -/******/ return __webpack_module_cache__[moduleId].exports; +/******/ var cachedModule = __webpack_module_cache__[moduleId]; +/******/ if (cachedModule !== undefined) { +/******/ return cachedModule.exports; /******/ } /******/ // Create a new module (and put it into the cache) /******/ var module = __webpack_module_cache__[moduleId] = { @@ -76,7 +77,7 @@ getTemplate("b", function(b) { /******/ /******/ /* webpack/runtime/hasOwnProperty shorthand */ /******/ (() => { -/******/ __webpack_require__.o = (obj, prop) => Object.prototype.hasOwnProperty.call(obj, prop) +/******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop)) /******/ })(); /******/ /******/ /* webpack/runtime/load script */ @@ -84,7 +85,7 @@ getTemplate("b", function(b) { /******/ var inProgress = {}; /******/ // data-webpack is not used as build has no uniqueName /******/ // loadScript function to load a script via script tag -/******/ __webpack_require__.l = (url, done, key) => { +/******/ __webpack_require__.l = (url, done, key, chunkId) => { /******/ if(inProgress[url]) { inProgress[url].push(done); return; } /******/ var script, needAttach; /******/ if(key !== undefined) { @@ -114,10 +115,9 @@ getTemplate("b", function(b) { /******/ var doneFns = inProgress[url]; /******/ delete inProgress[url]; /******/ script.parentNode && script.parentNode.removeChild(script); -/******/ doneFns && doneFns.forEach((fn) => fn(event)); +/******/ doneFns && doneFns.forEach((fn) => (fn(event))); /******/ if(prev) return prev(event); /******/ } -/******/ ; /******/ var timeout = setTimeout(onScriptComplete.bind(null, undefined, { type: 'timeout', target: script }), 120000); /******/ script.onerror = onScriptComplete.bind(null, script.onerror); /******/ script.onload = onScriptComplete.bind(null, script.onload); @@ -136,12 +136,11 @@ getTemplate("b", function(b) { /******/ /******/ // object to store loaded and loading chunks /******/ // undefined = chunk not loaded, null = chunk preloaded/prefetched -/******/ // Promise = chunk loading, 0 = chunk loaded +/******/ // [resolve, reject, Promise] = chunk loading, 0 = chunk loaded /******/ var installedChunks = { /******/ 179: 0 /******/ }; /******/ -/******/ /******/ __webpack_require__.f.j = (chunkId, promises) => { /******/ // JSONP chunk loading for javascript /******/ var installedChunkData = __webpack_require__.o(installedChunks, chunkId) ? installedChunks[chunkId] : undefined; @@ -153,9 +152,7 @@ getTemplate("b", function(b) { /******/ } else { /******/ if(true) { // all chunks have JS /******/ // setup Promise in chunk cache -/******/ var promise = new Promise((resolve, reject) => { -/******/ installedChunkData = installedChunks[chunkId] = [resolve, reject]; -/******/ }); +/******/ var promise = new Promise((resolve, reject) => (installedChunkData = installedChunks[chunkId] = [resolve, reject])); /******/ promises.push(installedChunkData[2] = promise); /******/ /******/ // start chunk loading @@ -177,7 +174,7 @@ getTemplate("b", function(b) { /******/ } /******/ } /******/ }; -/******/ __webpack_require__.l(url, loadingEnded, "chunk-" + chunkId); +/******/ __webpack_require__.l(url, loadingEnded, "chunk-" + chunkId, chunkId); /******/ } else installedChunks[chunkId] = 0; /******/ } /******/ } @@ -191,39 +188,36 @@ getTemplate("b", function(b) { /******/ /******/ // no HMR manifest /******/ -/******/ // no deferred startup +/******/ // no on chunks loaded /******/ /******/ // install a JSONP callback for chunk loading /******/ var webpackJsonpCallback = (parentChunkLoadingFunction, data) => { /******/ var [chunkIds, moreModules, runtime] = data; /******/ // add "moreModules" to the modules object, /******/ // then flag all "chunkIds" as loaded and fire callback -/******/ var moduleId, chunkId, i = 0, resolves = []; +/******/ var moduleId, chunkId, i = 0; +/******/ if(chunkIds.some((id) => (installedChunks[id] !== 0))) { +/******/ for(moduleId in moreModules) { +/******/ if(__webpack_require__.o(moreModules, moduleId)) { +/******/ __webpack_require__.m[moduleId] = moreModules[moduleId]; +/******/ } +/******/ } +/******/ if(runtime) var result = runtime(__webpack_require__); +/******/ } +/******/ if(parentChunkLoadingFunction) parentChunkLoadingFunction(data); /******/ for(;i < chunkIds.length; i++) { /******/ chunkId = chunkIds[i]; /******/ if(__webpack_require__.o(installedChunks, chunkId) && installedChunks[chunkId]) { -/******/ resolves.push(installedChunks[chunkId][0]); +/******/ installedChunks[chunkId][0](); /******/ } /******/ installedChunks[chunkId] = 0; /******/ } -/******/ for(moduleId in moreModules) { -/******/ if(__webpack_require__.o(moreModules, moduleId)) { -/******/ __webpack_require__.m[moduleId] = moreModules[moduleId]; -/******/ } -/******/ } -/******/ if(runtime) runtime(__webpack_require__); -/******/ if(parentChunkLoadingFunction) parentChunkLoadingFunction(data); -/******/ while(resolves.length) { -/******/ resolves.shift()(); -/******/ } /******/ /******/ } /******/ /******/ var chunkLoadingGlobal = self["webpackChunk"] = self["webpackChunk"] || []; /******/ chunkLoadingGlobal.forEach(webpackJsonpCallback.bind(null, 0)); /******/ chunkLoadingGlobal.push = webpackJsonpCallback.bind(null, chunkLoadingGlobal.push.bind(chunkLoadingGlobal)); -/******/ -/******/ // no deferred startup /******/ })(); /******/ /************************************************************************/ @@ -232,6 +226,7 @@ getTemplate("b", function(b) { ``` js +var __webpack_exports__ = {}; /*!********************!*\ !*** ./example.js ***! \********************/ @@ -240,7 +235,7 @@ getTemplate("b", function(b) { function getTemplate(templateName, callback) { __webpack_require__.e(/*! AMD require */ 577).then(function() { var __WEBPACK_AMD_REQUIRE_ARRAY__ = [__webpack_require__(1)("./"+templateName)]; (function(tmpl) { callback(tmpl()); - }).apply(null, __WEBPACK_AMD_REQUIRE_ARRAY__);}).catch(__webpack_require__.oe); + }).apply(null, __WEBPACK_AMD_REQUIRE_ARRAY__);})['catch'](__webpack_require__.oe); } getTemplate("a", function(a) { console.log(a); @@ -361,7 +356,7 @@ chunk (runtime: main) 577.output.js 457 bytes [rendered] [no exports] [used exports unknown] amd require context ./example.js 2:1-4:3 -webpack 5.11.1 compiled successfully +webpack 5.78.0 compiled successfully ``` ## Production mode @@ -381,5 +376,5 @@ chunk (runtime: main) 577.output.js 457 bytes [rendered] ../require.context/templates/ sync ^\.\/.*$ 217 bytes [built] [code generated] [no exports] amd require context ./example.js 2:1-4:3 -webpack 5.11.1 compiled successfully +webpack 5.78.0 compiled successfully ``` diff --git a/examples/code-splitted-require.context/README.md b/examples/code-splitted-require.context/README.md index 1073a2b087d..89fe83e2106 100644 --- a/examples/code-splitted-require.context/README.md +++ b/examples/code-splitted-require.context/README.md @@ -31,8 +31,9 @@ getTemplate("b", function(b) { /******/ // The require function /******/ function __webpack_require__(moduleId) { /******/ // Check if module is in cache -/******/ if(__webpack_module_cache__[moduleId]) { -/******/ return __webpack_module_cache__[moduleId].exports; +/******/ var cachedModule = __webpack_module_cache__[moduleId]; +/******/ if (cachedModule !== undefined) { +/******/ return cachedModule.exports; /******/ } /******/ // Create a new module (and put it into the cache) /******/ var module = __webpack_module_cache__[moduleId] = { @@ -76,7 +77,7 @@ getTemplate("b", function(b) { /******/ /******/ /* webpack/runtime/hasOwnProperty shorthand */ /******/ (() => { -/******/ __webpack_require__.o = (obj, prop) => Object.prototype.hasOwnProperty.call(obj, prop) +/******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop)) /******/ })(); /******/ /******/ /* webpack/runtime/load script */ @@ -84,7 +85,7 @@ getTemplate("b", function(b) { /******/ var inProgress = {}; /******/ // data-webpack is not used as build has no uniqueName /******/ // loadScript function to load a script via script tag -/******/ __webpack_require__.l = (url, done, key) => { +/******/ __webpack_require__.l = (url, done, key, chunkId) => { /******/ if(inProgress[url]) { inProgress[url].push(done); return; } /******/ var script, needAttach; /******/ if(key !== undefined) { @@ -114,10 +115,9 @@ getTemplate("b", function(b) { /******/ var doneFns = inProgress[url]; /******/ delete inProgress[url]; /******/ script.parentNode && script.parentNode.removeChild(script); -/******/ doneFns && doneFns.forEach((fn) => fn(event)); +/******/ doneFns && doneFns.forEach((fn) => (fn(event))); /******/ if(prev) return prev(event); /******/ } -/******/ ; /******/ var timeout = setTimeout(onScriptComplete.bind(null, undefined, { type: 'timeout', target: script }), 120000); /******/ script.onerror = onScriptComplete.bind(null, script.onerror); /******/ script.onload = onScriptComplete.bind(null, script.onload); @@ -136,12 +136,11 @@ getTemplate("b", function(b) { /******/ /******/ // object to store loaded and loading chunks /******/ // undefined = chunk not loaded, null = chunk preloaded/prefetched -/******/ // Promise = chunk loading, 0 = chunk loaded +/******/ // [resolve, reject, Promise] = chunk loading, 0 = chunk loaded /******/ var installedChunks = { /******/ 179: 0 /******/ }; /******/ -/******/ /******/ __webpack_require__.f.j = (chunkId, promises) => { /******/ // JSONP chunk loading for javascript /******/ var installedChunkData = __webpack_require__.o(installedChunks, chunkId) ? installedChunks[chunkId] : undefined; @@ -153,9 +152,7 @@ getTemplate("b", function(b) { /******/ } else { /******/ if(true) { // all chunks have JS /******/ // setup Promise in chunk cache -/******/ var promise = new Promise((resolve, reject) => { -/******/ installedChunkData = installedChunks[chunkId] = [resolve, reject]; -/******/ }); +/******/ var promise = new Promise((resolve, reject) => (installedChunkData = installedChunks[chunkId] = [resolve, reject])); /******/ promises.push(installedChunkData[2] = promise); /******/ /******/ // start chunk loading @@ -177,7 +174,7 @@ getTemplate("b", function(b) { /******/ } /******/ } /******/ }; -/******/ __webpack_require__.l(url, loadingEnded, "chunk-" + chunkId); +/******/ __webpack_require__.l(url, loadingEnded, "chunk-" + chunkId, chunkId); /******/ } else installedChunks[chunkId] = 0; /******/ } /******/ } @@ -191,39 +188,36 @@ getTemplate("b", function(b) { /******/ /******/ // no HMR manifest /******/ -/******/ // no deferred startup +/******/ // no on chunks loaded /******/ /******/ // install a JSONP callback for chunk loading /******/ var webpackJsonpCallback = (parentChunkLoadingFunction, data) => { /******/ var [chunkIds, moreModules, runtime] = data; /******/ // add "moreModules" to the modules object, /******/ // then flag all "chunkIds" as loaded and fire callback -/******/ var moduleId, chunkId, i = 0, resolves = []; +/******/ var moduleId, chunkId, i = 0; +/******/ if(chunkIds.some((id) => (installedChunks[id] !== 0))) { +/******/ for(moduleId in moreModules) { +/******/ if(__webpack_require__.o(moreModules, moduleId)) { +/******/ __webpack_require__.m[moduleId] = moreModules[moduleId]; +/******/ } +/******/ } +/******/ if(runtime) var result = runtime(__webpack_require__); +/******/ } +/******/ if(parentChunkLoadingFunction) parentChunkLoadingFunction(data); /******/ for(;i < chunkIds.length; i++) { /******/ chunkId = chunkIds[i]; /******/ if(__webpack_require__.o(installedChunks, chunkId) && installedChunks[chunkId]) { -/******/ resolves.push(installedChunks[chunkId][0]); +/******/ installedChunks[chunkId][0](); /******/ } /******/ installedChunks[chunkId] = 0; /******/ } -/******/ for(moduleId in moreModules) { -/******/ if(__webpack_require__.o(moreModules, moduleId)) { -/******/ __webpack_require__.m[moduleId] = moreModules[moduleId]; -/******/ } -/******/ } -/******/ if(runtime) runtime(__webpack_require__); -/******/ if(parentChunkLoadingFunction) parentChunkLoadingFunction(data); -/******/ while(resolves.length) { -/******/ resolves.shift()(); -/******/ } /******/ /******/ } /******/ /******/ var chunkLoadingGlobal = self["webpackChunk"] = self["webpackChunk"] || []; /******/ chunkLoadingGlobal.forEach(webpackJsonpCallback.bind(null, 0)); /******/ chunkLoadingGlobal.push = webpackJsonpCallback.bind(null, chunkLoadingGlobal.push.bind(chunkLoadingGlobal)); -/******/ -/******/ // no deferred startup /******/ })(); /******/ /************************************************************************/ @@ -232,6 +226,7 @@ getTemplate("b", function(b) { ``` js +var __webpack_exports__ = {}; /*!********************!*\ !*** ./example.js ***! \********************/ @@ -240,7 +235,7 @@ getTemplate("b", function(b) { function getTemplate(templateName, callback) { __webpack_require__.e(/*! require.ensure */ 577).then((function(require) { callback(__webpack_require__(1)("./"+templateName)()); - }).bind(null, __webpack_require__)).catch(__webpack_require__.oe); + }).bind(null, __webpack_require__))['catch'](__webpack_require__.oe); } getTemplate("a", function(a) { console.log(a); @@ -346,7 +341,7 @@ module.exports = function() { ## Unoptimized ``` -asset output.js 8.96 KiB [emitted] (name: main) +asset output.js 8.95 KiB [emitted] (name: main) asset 577.output.js 2.23 KiB [emitted] chunk (runtime: main) output.js (main) 266 bytes (javascript) 4.97 KiB (runtime) [entry] [rendered] > ./example.js main @@ -361,7 +356,7 @@ chunk (runtime: main) 577.output.js 457 bytes [rendered] [no exports] [used exports unknown] cjs require context ./example.js 3:11-64 -webpack 5.11.1 compiled successfully +webpack 5.78.0 compiled successfully ``` ## Production mode @@ -381,5 +376,5 @@ chunk (runtime: main) 577.output.js 457 bytes [rendered] ../require.context/templates/ sync ^\.\/.*$ 217 bytes [built] [code generated] [no exports] cjs require context ./example.js 3:11-64 -webpack 5.11.1 compiled successfully +webpack 5.78.0 compiled successfully ``` diff --git a/examples/code-splitting-bundle-loader/README.md b/examples/code-splitting-bundle-loader/README.md index 25c3fe5aed7..4ab296f9c6e 100644 --- a/examples/code-splitting-bundle-loader/README.md +++ b/examples/code-splitting-bundle-loader/README.md @@ -44,7 +44,7 @@ __webpack_require__.e(/*! require.ensure */ 929).then((function(require) { for(var i = 0, l = callbacks.length; i < l; i++) { callbacks[i](data); } -}).bind(null, __webpack_require__)).catch(__webpack_require__.oe); +}).bind(null, __webpack_require__))['catch'](__webpack_require__.oe); /***/ }) /******/ ]); @@ -60,8 +60,9 @@ __webpack_require__.e(/*! require.ensure */ 929).then((function(require) { /******/ // The require function /******/ function __webpack_require__(moduleId) { /******/ // Check if module is in cache -/******/ if(__webpack_module_cache__[moduleId]) { -/******/ return __webpack_module_cache__[moduleId].exports; +/******/ var cachedModule = __webpack_module_cache__[moduleId]; +/******/ if (cachedModule !== undefined) { +/******/ return cachedModule.exports; /******/ } /******/ // Create a new module (and put it into the cache) /******/ var module = __webpack_module_cache__[moduleId] = { @@ -105,7 +106,7 @@ __webpack_require__.e(/*! require.ensure */ 929).then((function(require) { /******/ /******/ /* webpack/runtime/hasOwnProperty shorthand */ /******/ (() => { -/******/ __webpack_require__.o = (obj, prop) => Object.prototype.hasOwnProperty.call(obj, prop) +/******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop)) /******/ })(); /******/ /******/ /* webpack/runtime/load script */ @@ -113,7 +114,7 @@ __webpack_require__.e(/*! require.ensure */ 929).then((function(require) { /******/ var inProgress = {}; /******/ // data-webpack is not used as build has no uniqueName /******/ // loadScript function to load a script via script tag -/******/ __webpack_require__.l = (url, done, key) => { +/******/ __webpack_require__.l = (url, done, key, chunkId) => { /******/ if(inProgress[url]) { inProgress[url].push(done); return; } /******/ var script, needAttach; /******/ if(key !== undefined) { @@ -143,10 +144,9 @@ __webpack_require__.e(/*! require.ensure */ 929).then((function(require) { /******/ var doneFns = inProgress[url]; /******/ delete inProgress[url]; /******/ script.parentNode && script.parentNode.removeChild(script); -/******/ doneFns && doneFns.forEach((fn) => fn(event)); +/******/ doneFns && doneFns.forEach((fn) => (fn(event))); /******/ if(prev) return prev(event); /******/ } -/******/ ; /******/ var timeout = setTimeout(onScriptComplete.bind(null, undefined, { type: 'timeout', target: script }), 120000); /******/ script.onerror = onScriptComplete.bind(null, script.onerror); /******/ script.onload = onScriptComplete.bind(null, script.onload); @@ -165,12 +165,11 @@ __webpack_require__.e(/*! require.ensure */ 929).then((function(require) { /******/ /******/ // object to store loaded and loading chunks /******/ // undefined = chunk not loaded, null = chunk preloaded/prefetched -/******/ // Promise = chunk loading, 0 = chunk loaded +/******/ // [resolve, reject, Promise] = chunk loading, 0 = chunk loaded /******/ var installedChunks = { /******/ 179: 0 /******/ }; /******/ -/******/ /******/ __webpack_require__.f.j = (chunkId, promises) => { /******/ // JSONP chunk loading for javascript /******/ var installedChunkData = __webpack_require__.o(installedChunks, chunkId) ? installedChunks[chunkId] : undefined; @@ -182,9 +181,7 @@ __webpack_require__.e(/*! require.ensure */ 929).then((function(require) { /******/ } else { /******/ if(true) { // all chunks have JS /******/ // setup Promise in chunk cache -/******/ var promise = new Promise((resolve, reject) => { -/******/ installedChunkData = installedChunks[chunkId] = [resolve, reject]; -/******/ }); +/******/ var promise = new Promise((resolve, reject) => (installedChunkData = installedChunks[chunkId] = [resolve, reject])); /******/ promises.push(installedChunkData[2] = promise); /******/ /******/ // start chunk loading @@ -206,7 +203,7 @@ __webpack_require__.e(/*! require.ensure */ 929).then((function(require) { /******/ } /******/ } /******/ }; -/******/ __webpack_require__.l(url, loadingEnded, "chunk-" + chunkId); +/******/ __webpack_require__.l(url, loadingEnded, "chunk-" + chunkId, chunkId); /******/ } else installedChunks[chunkId] = 0; /******/ } /******/ } @@ -220,39 +217,36 @@ __webpack_require__.e(/*! require.ensure */ 929).then((function(require) { /******/ /******/ // no HMR manifest /******/ -/******/ // no deferred startup +/******/ // no on chunks loaded /******/ /******/ // install a JSONP callback for chunk loading /******/ var webpackJsonpCallback = (parentChunkLoadingFunction, data) => { /******/ var [chunkIds, moreModules, runtime] = data; /******/ // add "moreModules" to the modules object, /******/ // then flag all "chunkIds" as loaded and fire callback -/******/ var moduleId, chunkId, i = 0, resolves = []; +/******/ var moduleId, chunkId, i = 0; +/******/ if(chunkIds.some((id) => (installedChunks[id] !== 0))) { +/******/ for(moduleId in moreModules) { +/******/ if(__webpack_require__.o(moreModules, moduleId)) { +/******/ __webpack_require__.m[moduleId] = moreModules[moduleId]; +/******/ } +/******/ } +/******/ if(runtime) var result = runtime(__webpack_require__); +/******/ } +/******/ if(parentChunkLoadingFunction) parentChunkLoadingFunction(data); /******/ for(;i < chunkIds.length; i++) { /******/ chunkId = chunkIds[i]; /******/ if(__webpack_require__.o(installedChunks, chunkId) && installedChunks[chunkId]) { -/******/ resolves.push(installedChunks[chunkId][0]); +/******/ installedChunks[chunkId][0](); /******/ } /******/ installedChunks[chunkId] = 0; /******/ } -/******/ for(moduleId in moreModules) { -/******/ if(__webpack_require__.o(moreModules, moduleId)) { -/******/ __webpack_require__.m[moduleId] = moreModules[moduleId]; -/******/ } -/******/ } -/******/ if(runtime) runtime(__webpack_require__); -/******/ if(parentChunkLoadingFunction) parentChunkLoadingFunction(data); -/******/ while(resolves.length) { -/******/ resolves.shift()(); -/******/ } /******/ /******/ } /******/ /******/ var chunkLoadingGlobal = self["webpackChunk"] = self["webpackChunk"] || []; /******/ chunkLoadingGlobal.forEach(webpackJsonpCallback.bind(null, 0)); /******/ chunkLoadingGlobal.push = webpackJsonpCallback.bind(null, chunkLoadingGlobal.push.bind(chunkLoadingGlobal)); -/******/ -/******/ // no deferred startup /******/ })(); /******/ /************************************************************************/ @@ -261,6 +255,8 @@ __webpack_require__.e(/*! require.ensure */ 929).then((function(require) { ``` js +var __webpack_exports__ = {}; +// This entry need to be wrapped in an IIFE because it need to be isolated against other modules in the chunk. (() => { /*!********************!*\ !*** ./example.js ***! @@ -303,7 +299,7 @@ module.exports = "It works"; ## Unoptimized ``` -asset output.js 9.58 KiB [emitted] (name: main) +asset output.js 9.68 KiB [emitted] (name: main) asset 929.output.js 354 bytes [emitted] chunk (runtime: main) output.js (main) 375 bytes (javascript) 4.97 KiB (runtime) [entry] [rendered] > ./example.js main @@ -318,13 +314,13 @@ chunk (runtime: main) 929.output.js 28 bytes [rendered] [used exports unknown] cjs self exports reference ./file.js 1:0-14 cjs require !!./file.js ../../node_modules/bundle-loader/index.js!./file.js 8:8-30 -webpack 5.11.1 compiled successfully +webpack 5.78.0 compiled successfully ``` ## Production mode ``` -asset output.js 1.84 KiB [emitted] [minimized] (name: main) +asset output.js 1.85 KiB [emitted] [minimized] (name: main) asset 929.output.js 88 bytes [emitted] [minimized] chunk (runtime: main) output.js (main) 375 bytes (javascript) 4.97 KiB (runtime) [entry] [rendered] > ./example.js main @@ -339,5 +335,5 @@ chunk (runtime: main) 929.output.js 28 bytes [rendered] [used exports unknown] cjs self exports reference ./file.js 1:0-14 cjs require !!./file.js ../../node_modules/bundle-loader/index.js!./file.js 8:8-30 -webpack 5.11.1 compiled successfully +webpack 5.78.0 compiled successfully ``` diff --git a/examples/code-splitting-depend-on-advanced/README.md b/examples/code-splitting-depend-on-advanced/README.md index 66766b04e01..09b2c0df6cb 100644 --- a/examples/code-splitting-depend-on-advanced/README.md +++ b/examples/code-splitting-depend-on-advanced/README.md @@ -79,8 +79,9 @@ console.log(lodash, isomorphicFetch); /******/ // The require function /******/ function __webpack_require__(moduleId) { /******/ // Check if module is in cache -/******/ if(__webpack_module_cache__[moduleId]) { -/******/ return __webpack_module_cache__[moduleId].exports; +/******/ var cachedModule = __webpack_module_cache__[moduleId]; +/******/ if (cachedModule !== undefined) { +/******/ return cachedModule.exports; /******/ } /******/ // Create a new module (and put it into the cache) /******/ var module = __webpack_module_cache__[moduleId] = { @@ -99,17 +100,46 @@ console.log(lodash, isomorphicFetch); /******/ // expose the modules object (__webpack_modules__) /******/ __webpack_require__.m = __webpack_modules__; /******/ -/******/ // the startup function -/******/ // It's empty as some runtime module handles the default behavior -/******/ __webpack_require__.x = x => {} /************************************************************************/ +/******/ /* webpack/runtime/chunk loaded */ +/******/ (() => { +/******/ var deferred = []; +/******/ __webpack_require__.O = (result, chunkIds, fn, priority) => { +/******/ if(chunkIds) { +/******/ priority = priority || 0; +/******/ for(var i = deferred.length; i > 0 && deferred[i - 1][2] > priority; i--) deferred[i] = deferred[i - 1]; +/******/ deferred[i] = [chunkIds, fn, priority]; +/******/ return; +/******/ } +/******/ var notFulfilled = Infinity; +/******/ for (var i = 0; i < deferred.length; i++) { +/******/ var [chunkIds, fn, priority] = deferred[i]; +/******/ var fulfilled = true; +/******/ for (var j = 0; j < chunkIds.length; j++) { +/******/ if ((priority & 1 === 0 || notFulfilled >= priority) && Object.keys(__webpack_require__.O).every((key) => (__webpack_require__.O[key](chunkIds[j])))) { +/******/ chunkIds.splice(j--, 1); +/******/ } else { +/******/ fulfilled = false; +/******/ if(priority < notFulfilled) notFulfilled = priority; +/******/ } +/******/ } +/******/ if(fulfilled) { +/******/ deferred.splice(i--, 1) +/******/ var r = fn(); +/******/ if (r !== undefined) result = r; +/******/ } +/******/ } +/******/ return result; +/******/ }; +/******/ })(); +/******/ /******/ /* webpack/runtime/compat get default export */ /******/ (() => { /******/ // getDefaultExport function for compatibility with non-harmony modules /******/ __webpack_require__.n = (module) => { /******/ var getter = module && module.__esModule ? -/******/ () => module['default'] : -/******/ () => module; +/******/ () => (module['default']) : +/******/ () => (module); /******/ __webpack_require__.d(getter, { a: getter }); /******/ return getter; /******/ }; @@ -151,7 +181,7 @@ console.log(lodash, isomorphicFetch); /******/ /******/ /* webpack/runtime/hasOwnProperty shorthand */ /******/ (() => { -/******/ __webpack_require__.o = (obj, prop) => Object.prototype.hasOwnProperty.call(obj, prop) +/******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop)) /******/ })(); /******/ /******/ /* webpack/runtime/load script */ @@ -159,7 +189,7 @@ console.log(lodash, isomorphicFetch); /******/ var inProgress = {}; /******/ // data-webpack is not used as build has no uniqueName /******/ // loadScript function to load a script via script tag -/******/ __webpack_require__.l = (url, done, key) => { +/******/ __webpack_require__.l = (url, done, key, chunkId) => { /******/ if(inProgress[url]) { inProgress[url].push(done); return; } /******/ var script, needAttach; /******/ if(key !== undefined) { @@ -189,10 +219,9 @@ console.log(lodash, isomorphicFetch); /******/ var doneFns = inProgress[url]; /******/ delete inProgress[url]; /******/ script.parentNode && script.parentNode.removeChild(script); -/******/ doneFns && doneFns.forEach((fn) => fn(event)); +/******/ doneFns && doneFns.forEach((fn) => (fn(event))); /******/ if(prev) return prev(event); /******/ } -/******/ ; /******/ var timeout = setTimeout(onScriptComplete.bind(null, undefined, { type: 'timeout', target: script }), 120000); /******/ script.onerror = onScriptComplete.bind(null, script.onerror); /******/ script.onload = onScriptComplete.bind(null, script.onload); @@ -222,14 +251,11 @@ console.log(lodash, isomorphicFetch); /******/ /******/ // object to store loaded and loading chunks /******/ // undefined = chunk not loaded, null = chunk preloaded/prefetched -/******/ // Promise = chunk loading, 0 = chunk loaded +/******/ // [resolve, reject, Promise] = chunk loading, 0 = chunk loaded /******/ var installedChunks = { /******/ "runtime": 0 /******/ }; /******/ -/******/ var deferredModules = [ -/******/ -/******/ ]; /******/ __webpack_require__.f.j = (chunkId, promises) => { /******/ // JSONP chunk loading for javascript /******/ var installedChunkData = __webpack_require__.o(installedChunks, chunkId) ? installedChunks[chunkId] : undefined; @@ -239,11 +265,9 @@ console.log(lodash, isomorphicFetch); /******/ if(installedChunkData) { /******/ promises.push(installedChunkData[2]); /******/ } else { -/******/ if(true) { // all chunks have JS +/******/ if("runtime" != chunkId) { /******/ // setup Promise in chunk cache -/******/ var promise = new Promise((resolve, reject) => { -/******/ installedChunkData = installedChunks[chunkId] = [resolve, reject]; -/******/ }); +/******/ var promise = new Promise((resolve, reject) => (installedChunkData = installedChunks[chunkId] = [resolve, reject])); /******/ promises.push(installedChunkData[2] = promise); /******/ /******/ // start chunk loading @@ -265,7 +289,7 @@ console.log(lodash, isomorphicFetch); /******/ } /******/ } /******/ }; -/******/ __webpack_require__.l(url, loadingEnded, "chunk-" + chunkId); +/******/ __webpack_require__.l(url, loadingEnded, "chunk-" + chunkId, chunkId); /******/ } else installedChunks[chunkId] = 0; /******/ } /******/ } @@ -279,69 +303,36 @@ console.log(lodash, isomorphicFetch); /******/ /******/ // no HMR manifest /******/ -/******/ var checkDeferredModules = x => {}; +/******/ __webpack_require__.O.j = (chunkId) => (installedChunks[chunkId] === 0); /******/ /******/ // install a JSONP callback for chunk loading /******/ var webpackJsonpCallback = (parentChunkLoadingFunction, data) => { -/******/ var [chunkIds, moreModules, runtime, executeModules] = data; +/******/ var [chunkIds, moreModules, runtime] = data; /******/ // add "moreModules" to the modules object, /******/ // then flag all "chunkIds" as loaded and fire callback -/******/ var moduleId, chunkId, i = 0, resolves = []; +/******/ var moduleId, chunkId, i = 0; +/******/ if(chunkIds.some((id) => (installedChunks[id] !== 0))) { +/******/ for(moduleId in moreModules) { +/******/ if(__webpack_require__.o(moreModules, moduleId)) { +/******/ __webpack_require__.m[moduleId] = moreModules[moduleId]; +/******/ } +/******/ } +/******/ if(runtime) var result = runtime(__webpack_require__); +/******/ } +/******/ if(parentChunkLoadingFunction) parentChunkLoadingFunction(data); /******/ for(;i < chunkIds.length; i++) { /******/ chunkId = chunkIds[i]; /******/ if(__webpack_require__.o(installedChunks, chunkId) && installedChunks[chunkId]) { -/******/ resolves.push(installedChunks[chunkId][0]); +/******/ installedChunks[chunkId][0](); /******/ } /******/ installedChunks[chunkId] = 0; /******/ } -/******/ for(moduleId in moreModules) { -/******/ if(__webpack_require__.o(moreModules, moduleId)) { -/******/ __webpack_require__.m[moduleId] = moreModules[moduleId]; -/******/ } -/******/ } -/******/ if(runtime) runtime(__webpack_require__); -/******/ if(parentChunkLoadingFunction) parentChunkLoadingFunction(data); -/******/ while(resolves.length) { -/******/ resolves.shift()(); -/******/ } -/******/ -/******/ // add entry modules from loaded chunk to deferred list -/******/ if(executeModules) deferredModules.push.apply(deferredModules, executeModules); -/******/ -/******/ // run deferred modules when all chunks ready -/******/ return checkDeferredModules(); +/******/ return __webpack_require__.O(result); /******/ } /******/ /******/ var chunkLoadingGlobal = self["webpackChunk"] = self["webpackChunk"] || []; /******/ chunkLoadingGlobal.forEach(webpackJsonpCallback.bind(null, 0)); /******/ chunkLoadingGlobal.push = webpackJsonpCallback.bind(null, chunkLoadingGlobal.push.bind(chunkLoadingGlobal)); -/******/ -/******/ function checkDeferredModulesImpl() { -/******/ var result; -/******/ for(var i = 0; i < deferredModules.length; i++) { -/******/ var deferredModule = deferredModules[i]; -/******/ var fulfilled = true; -/******/ for(var j = 1; j < deferredModule.length; j++) { -/******/ var depId = deferredModule[j]; -/******/ if(installedChunks[depId] !== 0) fulfilled = false; -/******/ } -/******/ if(fulfilled) { -/******/ deferredModules.splice(i--, 1); -/******/ result = __webpack_require__(__webpack_require__.s = deferredModule[0]); -/******/ } -/******/ } -/******/ if(deferredModules.length === 0) { -/******/ __webpack_require__.x(); -/******/ __webpack_require__.x = x => {}; -/******/ } -/******/ return result; -/******/ } -/******/ var startup = __webpack_require__.x; -/******/ __webpack_require__.x = () => { -/******/ // reset startup function so it can be called again when more startup code is added -/******/ __webpack_require__.x = startup || (x => {}); -/******/ return (checkDeferredModules = checkDeferredModulesImpl)(); -/******/ }; /******/ })(); /******/ /************************************************************************/ @@ -350,8 +341,8 @@ console.log(lodash, isomorphicFetch); ``` js -/******/ // run startup -/******/ return __webpack_require__.x(); +/******/ +/******/ /******/ })() ; ``` @@ -359,9 +350,10 @@ console.log(lodash, isomorphicFetch); # dist/app.js ```javascript +"use strict"; (self["webpackChunk"] = self["webpackChunk"] || []).push([["app"],{ -/***/ 7: +/***/ 6: /*!****************!*\ !*** ./app.js ***! \****************/ @@ -370,7 +362,6 @@ console.log(lodash, isomorphicFetch); /*! runtime requirements: __webpack_require__, __webpack_require__.n, __webpack_require__.r, __webpack_exports__, __webpack_require__.* */ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { -"use strict"; __webpack_require__.r(__webpack_exports__); /* harmony import */ var isomorphic_fetch__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! isomorphic-fetch */ 5); /* harmony import */ var isomorphic_fetch__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(isomorphic_fetch__WEBPACK_IMPORTED_MODULE_0__); @@ -385,15 +376,21 @@ console.log((isomorphic_fetch__WEBPACK_IMPORTED_MODULE_0___default()), (lodash__ /***/ }) }, -0,[[7,"runtime","other-vendors"]]]); +/******/ __webpack_require__ => { // webpackRuntimeModules +/******/ var __webpack_exec__ = (moduleId) => (__webpack_require__(__webpack_require__.s = moduleId)) +/******/ __webpack_require__.O(0, ["other-vendors"], () => (__webpack_exec__(6))); +/******/ var __webpack_exports__ = __webpack_require__.O(); +/******/ } +]); ``` # dist/page1.js ```javascript +"use strict"; (self["webpackChunk"] = self["webpackChunk"] || []).push([["page1"],{ -/***/ 6: +/***/ 7: /*!******************!*\ !*** ./page1.js ***! \******************/ @@ -402,7 +399,6 @@ console.log((isomorphic_fetch__WEBPACK_IMPORTED_MODULE_0___default()), (lodash__ /*! runtime requirements: __webpack_require__, __webpack_require__.n, __webpack_require__.r, __webpack_exports__, __webpack_require__.e, __webpack_require__.* */ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { -"use strict"; __webpack_require__.r(__webpack_exports__); /* harmony import */ var isomorphic_fetch__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! isomorphic-fetch */ 5); /* harmony import */ var isomorphic_fetch__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(isomorphic_fetch__WEBPACK_IMPORTED_MODULE_0__); @@ -422,7 +418,12 @@ __webpack_require__.e(/*! import() */ "lazy_js").then(__webpack_require__.bind(_ /***/ }) }, -0,[[6,"app","runtime","react-vendors","other-vendors"]]]); +/******/ __webpack_require__ => { // webpackRuntimeModules +/******/ var __webpack_exec__ = (moduleId) => (__webpack_require__(__webpack_require__.s = moduleId)) +/******/ __webpack_require__.O(0, ["app","react-vendors","other-vendors"], () => (__webpack_exec__(7))); +/******/ var __webpack_exports__ = __webpack_require__.O(); +/******/ } +]); ``` # dist/other-vendors.js @@ -482,7 +483,11 @@ module.exports = "isomorphic-fetch"; /***/ }) ], -0,[[3,"runtime"]]]); +/******/ __webpack_require__ => { // webpackRuntimeModules +/******/ var __webpack_exec__ = (moduleId) => (__webpack_require__(__webpack_require__.s = moduleId)) +/******/ var __webpack_exports__ = (__webpack_exec__(3)); +/******/ } +]); ``` # dist/react-vendors.js @@ -529,7 +534,11 @@ module.exports = 'prop-types'; /***/ }) ], -0,[[0,"runtime"],[1,"runtime"],[2,"runtime"]]]); +/******/ __webpack_require__ => { // webpackRuntimeModules +/******/ var __webpack_exec__ = (moduleId) => (__webpack_require__(__webpack_require__.s = moduleId)) +/******/ var __webpack_exports__ = (__webpack_exec__(0), __webpack_exec__(1), __webpack_exec__(2)); +/******/ } +]); ``` # Info @@ -537,16 +546,16 @@ module.exports = 'prop-types'; ## Unoptimized ``` -asset runtime.js 11.4 KiB [emitted] (name: runtime) -asset other-vendors.js 1.92 KiB [emitted] (name: other-vendors) -asset page1.js 1.64 KiB [emitted] (name: page1) -asset app.js 1.17 KiB [emitted] (name: app) +asset runtime.js 11.1 KiB [emitted] (name: runtime) +asset other-vendors.js 2.13 KiB [emitted] (name: other-vendors) +asset page1.js 1.91 KiB [emitted] (name: page1) +asset app.js 1.44 KiB [emitted] (name: app) +asset react-vendors.js 1.33 KiB [emitted] (name: react-vendors) asset lazy_js.js 1.11 KiB [emitted] -asset react-vendors.js 1.1 KiB [emitted] (name: react-vendors) -Entrypoint app 1.17 KiB = app.js -Entrypoint page1 1.64 KiB = page1.js -Entrypoint react-vendors 12.5 KiB = runtime.js 11.4 KiB react-vendors.js 1.1 KiB -Entrypoint other-vendors 13.3 KiB = runtime.js 11.4 KiB other-vendors.js 1.92 KiB +Entrypoint app 1.44 KiB = app.js +Entrypoint page1 1.91 KiB = page1.js +Entrypoint react-vendors 12.4 KiB = runtime.js 11.1 KiB react-vendors.js 1.33 KiB +Entrypoint other-vendors 13.3 KiB = runtime.js 11.1 KiB other-vendors.js 2.13 KiB chunk (runtime: runtime) app.js (app) 116 bytes <{other-vendors}> <{runtime}> >{page1}< [initial] [rendered] > ./app.js app ./app.js 116 bytes [built] [code generated] @@ -578,44 +587,47 @@ chunk (runtime: runtime) react-vendors.js (react-vendors) 87 bytes ={runtime}= > > react-dom react-vendors ./node_modules/prop-types.js 31 bytes [built] [code generated] [used exports unknown] - harmony side effect evaluation prop-types ./lazy.js 2:0-35 - harmony import specifier prop-types ./lazy.js 4:20-29 + from origin ./lazy.js + harmony side effect evaluation prop-types ./lazy.js 2:0-35 + harmony import specifier prop-types ./lazy.js 4:20-29 cjs self exports reference ./node_modules/prop-types.js 1:0-14 entry prop-types react-vendors ./node_modules/react-dom.js 30 bytes [built] [code generated] [used exports unknown] + from origin ./page1.js + harmony side effect evaluation react-dom ./page1.js 3:0-33 + harmony import specifier react-dom ./page1.js 5:36-44 cjs self exports reference ./node_modules/react-dom.js 1:0-14 - harmony side effect evaluation react-dom ./page1.js 3:0-33 - harmony import specifier react-dom ./page1.js 5:36-44 entry react-dom react-vendors ./node_modules/react.js 26 bytes [built] [code generated] [used exports unknown] + from origin ./page1.js + harmony side effect evaluation react ./page1.js 2:0-26 + harmony import specifier react ./page1.js 5:29-34 cjs self exports reference ./node_modules/react.js 1:0-14 - harmony side effect evaluation react ./page1.js 2:0-26 - harmony import specifier react ./page1.js 5:29-34 entry react react-vendors -chunk (runtime: runtime) runtime.js (runtime) 6.85 KiB ={other-vendors}= ={react-vendors}= >{app}< >{page1}< [entry] [rendered] +chunk (runtime: runtime) runtime.js (runtime) 6.74 KiB ={other-vendors}= ={react-vendors}= >{app}< >{page1}< [entry] [rendered] > ./other-vendors other-vendors > prop-types react-vendors > react react-vendors > react-dom react-vendors - runtime modules 6.85 KiB 9 modules -webpack 5.11.1 compiled successfully + runtime modules 6.74 KiB 10 modules +webpack 5.78.0 compiled successfully ``` ## Production mode ``` -asset runtime.js 2.26 KiB [emitted] [minimized] (name: runtime) -asset page1.js 264 bytes [emitted] [minimized] (name: page1) -asset other-vendors.js 243 bytes [emitted] [minimized] (name: other-vendors) -asset react-vendors.js 208 bytes [emitted] [minimized] (name: react-vendors) -asset app.js 184 bytes [emitted] [minimized] (name: app) +asset runtime.js 2.37 KiB [emitted] [minimized] (name: runtime) +asset page1.js 287 bytes [emitted] [minimized] (name: page1) +asset other-vendors.js 239 bytes [emitted] [minimized] (name: other-vendors) +asset app.js 207 bytes [emitted] [minimized] (name: app) +asset react-vendors.js 200 bytes [emitted] [minimized] (name: react-vendors) asset lazy_js.js 159 bytes [emitted] [minimized] -Entrypoint app 184 bytes = app.js -Entrypoint page1 264 bytes = page1.js -Entrypoint react-vendors 2.46 KiB = runtime.js 2.26 KiB react-vendors.js 208 bytes -Entrypoint other-vendors 2.5 KiB = runtime.js 2.26 KiB other-vendors.js 243 bytes +Entrypoint app 207 bytes = app.js +Entrypoint page1 287 bytes = page1.js +Entrypoint react-vendors 2.56 KiB = runtime.js 2.37 KiB react-vendors.js 200 bytes +Entrypoint other-vendors 2.6 KiB = runtime.js 2.37 KiB other-vendors.js 239 bytes chunk (runtime: runtime) app.js (app) 116 bytes <{other-vendors}> <{runtime}> >{page1}< [initial] [rendered] > ./app.js app ./app.js 116 bytes [built] [code generated] @@ -646,27 +658,30 @@ chunk (runtime: runtime) react-vendors.js (react-vendors) 87 bytes ={runtime}= > > react-dom react-vendors ./node_modules/prop-types.js 31 bytes [built] [code generated] [used exports unknown] - harmony side effect evaluation prop-types ./lazy.js 2:0-35 - harmony import specifier prop-types ./lazy.js 4:20-29 + from origin ./lazy.js + harmony side effect evaluation prop-types ./lazy.js 2:0-35 + harmony import specifier prop-types ./lazy.js 4:20-29 cjs self exports reference ./node_modules/prop-types.js 1:0-14 entry prop-types react-vendors ./node_modules/react-dom.js 30 bytes [built] [code generated] [used exports unknown] + from origin ./page1.js + harmony side effect evaluation react-dom ./page1.js 3:0-33 + harmony import specifier react-dom ./page1.js 5:36-44 cjs self exports reference ./node_modules/react-dom.js 1:0-14 - harmony side effect evaluation react-dom ./page1.js 3:0-33 - harmony import specifier react-dom ./page1.js 5:36-44 entry react-dom react-vendors ./node_modules/react.js 26 bytes [built] [code generated] [used exports unknown] + from origin ./page1.js + harmony side effect evaluation react ./page1.js 2:0-26 + harmony import specifier react ./page1.js 5:29-34 cjs self exports reference ./node_modules/react.js 1:0-14 - harmony side effect evaluation react ./page1.js 2:0-26 - harmony import specifier react ./page1.js 5:29-34 entry react react-vendors -chunk (runtime: runtime) runtime.js (runtime) 6.85 KiB ={other-vendors}= ={react-vendors}= >{app}< >{page1}< [entry] [rendered] +chunk (runtime: runtime) runtime.js (runtime) 6.74 KiB ={other-vendors}= ={react-vendors}= >{app}< >{page1}< [entry] [rendered] > ./other-vendors other-vendors > prop-types react-vendors > react react-vendors > react-dom react-vendors - runtime modules 6.85 KiB 9 modules -webpack 5.11.1 compiled successfully + runtime modules 6.74 KiB 10 modules +webpack 5.78.0 compiled successfully ``` diff --git a/examples/code-splitting-depend-on-simple/README.md b/examples/code-splitting-depend-on-simple/README.md index ce39033f28e..df67b1bbcc0 100644 --- a/examples/code-splitting-depend-on-simple/README.md +++ b/examples/code-splitting-depend-on-simple/README.md @@ -31,6 +31,7 @@ console.log(react, reactDOM, propTypes); # dist/app.js ```javascript +"use strict"; (self["webpackChunk"] = self["webpackChunk"] || []).push([["app"],{ /***/ 3: @@ -42,7 +43,6 @@ console.log(react, reactDOM, propTypes); /*! runtime requirements: __webpack_require__, __webpack_require__.n, __webpack_require__.r, __webpack_exports__, __webpack_require__.* */ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { -"use strict"; __webpack_require__.r(__webpack_exports__); /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react */ 0); /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__); @@ -60,7 +60,11 @@ console.log((react__WEBPACK_IMPORTED_MODULE_0___default()), (react_dom__WEBPACK_ /***/ }) }, -0,[[3,"react-vendors"]]]); +/******/ __webpack_require__ => { // webpackRuntimeModules +/******/ var __webpack_exec__ = (moduleId) => (__webpack_require__(__webpack_require__.s = moduleId)) +/******/ var __webpack_exports__ = (__webpack_exec__(3)); +/******/ } +]); ``` # dist/react-vendors.js @@ -120,8 +124,9 @@ module.exports = 'prop-types'; /******/ // The require function /******/ function __webpack_require__(moduleId) { /******/ // Check if module is in cache -/******/ if(__webpack_module_cache__[moduleId]) { -/******/ return __webpack_module_cache__[moduleId].exports; +/******/ var cachedModule = __webpack_module_cache__[moduleId]; +/******/ if (cachedModule !== undefined) { +/******/ return cachedModule.exports; /******/ } /******/ // Create a new module (and put it into the cache) /******/ var module = __webpack_module_cache__[moduleId] = { @@ -140,17 +145,46 @@ module.exports = 'prop-types'; /******/ // expose the modules object (__webpack_modules__) /******/ __webpack_require__.m = __webpack_modules__; /******/ -/******/ // the startup function -/******/ // It's empty as some runtime module handles the default behavior -/******/ __webpack_require__.x = x => {} /************************************************************************/ +/******/ /* webpack/runtime/chunk loaded */ +/******/ (() => { +/******/ var deferred = []; +/******/ __webpack_require__.O = (result, chunkIds, fn, priority) => { +/******/ if(chunkIds) { +/******/ priority = priority || 0; +/******/ for(var i = deferred.length; i > 0 && deferred[i - 1][2] > priority; i--) deferred[i] = deferred[i - 1]; +/******/ deferred[i] = [chunkIds, fn, priority]; +/******/ return; +/******/ } +/******/ var notFulfilled = Infinity; +/******/ for (var i = 0; i < deferred.length; i++) { +/******/ var [chunkIds, fn, priority] = deferred[i]; +/******/ var fulfilled = true; +/******/ for (var j = 0; j < chunkIds.length; j++) { +/******/ if ((priority & 1 === 0 || notFulfilled >= priority) && Object.keys(__webpack_require__.O).every((key) => (__webpack_require__.O[key](chunkIds[j])))) { +/******/ chunkIds.splice(j--, 1); +/******/ } else { +/******/ fulfilled = false; +/******/ if(priority < notFulfilled) notFulfilled = priority; +/******/ } +/******/ } +/******/ if(fulfilled) { +/******/ deferred.splice(i--, 1) +/******/ var r = fn(); +/******/ if (r !== undefined) result = r; +/******/ } +/******/ } +/******/ return result; +/******/ }; +/******/ })(); +/******/ /******/ /* webpack/runtime/compat get default export */ /******/ (() => { /******/ // getDefaultExport function for compatibility with non-harmony modules /******/ __webpack_require__.n = (module) => { /******/ var getter = module && module.__esModule ? -/******/ () => module['default'] : -/******/ () => module; +/******/ () => (module['default']) : +/******/ () => (module); /******/ __webpack_require__.d(getter, { a: getter }); /******/ return getter; /******/ }; @@ -170,7 +204,7 @@ module.exports = 'prop-types'; /******/ /******/ /* webpack/runtime/hasOwnProperty shorthand */ /******/ (() => { -/******/ __webpack_require__.o = (obj, prop) => Object.prototype.hasOwnProperty.call(obj, prop) +/******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop)) /******/ })(); /******/ /******/ /* webpack/runtime/make namespace object */ @@ -190,16 +224,11 @@ module.exports = 'prop-types'; /******/ /******/ // object to store loaded and loading chunks /******/ // undefined = chunk not loaded, null = chunk preloaded/prefetched -/******/ // Promise = chunk loading, 0 = chunk loaded +/******/ // [resolve, reject, Promise] = chunk loading, 0 = chunk loaded /******/ var installedChunks = { /******/ "react-vendors": 0 /******/ }; /******/ -/******/ var deferredModules = [ -/******/ [0], -/******/ [1], -/******/ [2] -/******/ ]; /******/ // no chunk on demand loading /******/ /******/ // no prefetching @@ -210,69 +239,36 @@ module.exports = 'prop-types'; /******/ /******/ // no HMR manifest /******/ -/******/ var checkDeferredModules = x => {}; +/******/ __webpack_require__.O.j = (chunkId) => (installedChunks[chunkId] === 0); /******/ /******/ // install a JSONP callback for chunk loading /******/ var webpackJsonpCallback = (parentChunkLoadingFunction, data) => { -/******/ var [chunkIds, moreModules, runtime, executeModules] = data; +/******/ var [chunkIds, moreModules, runtime] = data; /******/ // add "moreModules" to the modules object, /******/ // then flag all "chunkIds" as loaded and fire callback -/******/ var moduleId, chunkId, i = 0, resolves = []; +/******/ var moduleId, chunkId, i = 0; +/******/ if(chunkIds.some((id) => (installedChunks[id] !== 0))) { +/******/ for(moduleId in moreModules) { +/******/ if(__webpack_require__.o(moreModules, moduleId)) { +/******/ __webpack_require__.m[moduleId] = moreModules[moduleId]; +/******/ } +/******/ } +/******/ if(runtime) var result = runtime(__webpack_require__); +/******/ } +/******/ if(parentChunkLoadingFunction) parentChunkLoadingFunction(data); /******/ for(;i < chunkIds.length; i++) { /******/ chunkId = chunkIds[i]; /******/ if(__webpack_require__.o(installedChunks, chunkId) && installedChunks[chunkId]) { -/******/ resolves.push(installedChunks[chunkId][0]); +/******/ installedChunks[chunkId][0](); /******/ } /******/ installedChunks[chunkId] = 0; /******/ } -/******/ for(moduleId in moreModules) { -/******/ if(__webpack_require__.o(moreModules, moduleId)) { -/******/ __webpack_require__.m[moduleId] = moreModules[moduleId]; -/******/ } -/******/ } -/******/ if(runtime) runtime(__webpack_require__); -/******/ if(parentChunkLoadingFunction) parentChunkLoadingFunction(data); -/******/ while(resolves.length) { -/******/ resolves.shift()(); -/******/ } -/******/ -/******/ // add entry modules from loaded chunk to deferred list -/******/ if(executeModules) deferredModules.push.apply(deferredModules, executeModules); -/******/ -/******/ // run deferred modules when all chunks ready -/******/ return checkDeferredModules(); +/******/ return __webpack_require__.O(result); /******/ } /******/ /******/ var chunkLoadingGlobal = self["webpackChunk"] = self["webpackChunk"] || []; /******/ chunkLoadingGlobal.forEach(webpackJsonpCallback.bind(null, 0)); /******/ chunkLoadingGlobal.push = webpackJsonpCallback.bind(null, chunkLoadingGlobal.push.bind(chunkLoadingGlobal)); -/******/ -/******/ function checkDeferredModulesImpl() { -/******/ var result; -/******/ for(var i = 0; i < deferredModules.length; i++) { -/******/ var deferredModule = deferredModules[i]; -/******/ var fulfilled = true; -/******/ for(var j = 1; j < deferredModule.length; j++) { -/******/ var depId = deferredModule[j]; -/******/ if(installedChunks[depId] !== 0) fulfilled = false; -/******/ } -/******/ if(fulfilled) { -/******/ deferredModules.splice(i--, 1); -/******/ result = __webpack_require__(__webpack_require__.s = deferredModule[0]); -/******/ } -/******/ } -/******/ if(deferredModules.length === 0) { -/******/ __webpack_require__.x(); -/******/ __webpack_require__.x = x => {}; -/******/ } -/******/ return result; -/******/ } -/******/ var startup = __webpack_require__.x; -/******/ __webpack_require__.x = () => { -/******/ // reset startup function so it can be called again when more startup code is added -/******/ __webpack_require__.x = startup || (x => {}); -/******/ return (checkDeferredModules = checkDeferredModulesImpl)(); -/******/ }; /******/ })(); /******/ /************************************************************************/ @@ -281,8 +277,15 @@ module.exports = 'prop-types'; ``` js -/******/ // run startup -/******/ return __webpack_require__.x(); +/******/ +/******/ // startup +/******/ // Load entry module and return exports +/******/ // This entry module is referenced by other modules so it can't be inlined +/******/ __webpack_require__(0); +/******/ __webpack_require__(1); +/******/ var __webpack_exports__ = __webpack_require__(2); +/******/ __webpack_exports__ = __webpack_require__.O(__webpack_exports__); +/******/ /******/ })() ; ``` @@ -292,75 +295,81 @@ module.exports = 'prop-types'; ## Unoptimized ``` -asset react-vendors.js 7.56 KiB [emitted] (name: react-vendors) -asset app.js 1.43 KiB [emitted] (name: app) +asset react-vendors.js 7.62 KiB [emitted] (name: react-vendors) +asset app.js 1.63 KiB [emitted] (name: app) chunk (runtime: react-vendors) app.js (app) 139 bytes <{react-vendors}> [initial] [rendered] > ./app.js app ./app.js 139 bytes [built] [code generated] [no exports] [used exports unknown] entry ./app.js app -chunk (runtime: react-vendors) react-vendors.js (react-vendors) 87 bytes (javascript) 3.42 KiB (runtime) >{app}< [entry] [rendered] +chunk (runtime: react-vendors) react-vendors.js (react-vendors) 87 bytes (javascript) 3.29 KiB (runtime) >{app}< [entry] [rendered] > prop-types react-vendors > react react-vendors > react-dom react-vendors - runtime modules 3.42 KiB 5 modules + runtime modules 3.29 KiB 6 modules cacheable modules 87 bytes ./node_modules/prop-types.js 31 bytes [built] [code generated] [used exports unknown] - harmony side effect evaluation prop-types ./app.js 3:0-35 - harmony import specifier prop-types ./app.js 5:29-38 + from origin ./app.js + harmony side effect evaluation prop-types ./app.js 3:0-35 + harmony import specifier prop-types ./app.js 5:29-38 cjs self exports reference ./node_modules/prop-types.js 1:0-14 entry prop-types react-vendors ./node_modules/react-dom.js 30 bytes [built] [code generated] [used exports unknown] - harmony side effect evaluation react-dom ./app.js 2:0-33 - harmony import specifier react-dom ./app.js 5:19-27 + from origin ./app.js + harmony side effect evaluation react-dom ./app.js 2:0-33 + harmony import specifier react-dom ./app.js 5:19-27 cjs self exports reference ./node_modules/react-dom.js 1:0-14 entry react-dom react-vendors ./node_modules/react.js 26 bytes [built] [code generated] [used exports unknown] - harmony side effect evaluation react ./app.js 1:0-26 - harmony import specifier react ./app.js 5:12-17 + from origin ./app.js + harmony side effect evaluation react ./app.js 1:0-26 + harmony import specifier react ./app.js 5:12-17 cjs self exports reference ./node_modules/react.js 1:0-14 entry react react-vendors -webpack 5.11.1 compiled successfully +webpack 5.78.0 compiled successfully ``` ## Production mode ``` -asset react-vendors.js 1.05 KiB [emitted] [minimized] (name: react-vendors) -asset app.js 195 bytes [emitted] [minimized] (name: app) +asset react-vendors.js 1.15 KiB [emitted] [minimized] (name: react-vendors) +asset app.js 185 bytes [emitted] [minimized] (name: app) chunk (runtime: react-vendors) app.js (app) 139 bytes <{react-vendors}> [initial] [rendered] > ./app.js app ./app.js 139 bytes [built] [code generated] [no exports] [no exports used] entry ./app.js app -chunk (runtime: react-vendors) react-vendors.js (react-vendors) 87 bytes (javascript) 3.15 KiB (runtime) >{app}< [entry] [rendered] +chunk (runtime: react-vendors) react-vendors.js (react-vendors) 87 bytes (javascript) 3.03 KiB (runtime) >{app}< [entry] [rendered] > prop-types react-vendors > react react-vendors > react-dom react-vendors - runtime modules 3.15 KiB 4 modules + runtime modules 3.03 KiB 5 modules cacheable modules 87 bytes ./node_modules/prop-types.js 31 bytes [built] [code generated] [used exports unknown] - harmony side effect evaluation prop-types ./app.js 3:0-35 - harmony import specifier prop-types ./app.js 5:29-38 + from origin ./app.js + harmony side effect evaluation prop-types ./app.js 3:0-35 + harmony import specifier prop-types ./app.js 5:29-38 cjs self exports reference ./node_modules/prop-types.js 1:0-14 entry prop-types react-vendors ./node_modules/react-dom.js 30 bytes [built] [code generated] [used exports unknown] - harmony side effect evaluation react-dom ./app.js 2:0-33 - harmony import specifier react-dom ./app.js 5:19-27 + from origin ./app.js + harmony side effect evaluation react-dom ./app.js 2:0-33 + harmony import specifier react-dom ./app.js 5:19-27 cjs self exports reference ./node_modules/react-dom.js 1:0-14 entry react-dom react-vendors ./node_modules/react.js 26 bytes [built] [code generated] [used exports unknown] - harmony side effect evaluation react ./app.js 1:0-26 - harmony import specifier react ./app.js 5:12-17 + from origin ./app.js + harmony side effect evaluation react ./app.js 1:0-26 + harmony import specifier react ./app.js 5:12-17 cjs self exports reference ./node_modules/react.js 1:0-14 entry react react-vendors -webpack 5.11.1 compiled successfully +webpack 5.78.0 compiled successfully ``` diff --git a/examples/code-splitting-harmony/README.md b/examples/code-splitting-harmony/README.md index 7ffefdb5c4c..7372a379e99 100644 --- a/examples/code-splitting-harmony/README.md +++ b/examples/code-splitting-harmony/README.md @@ -29,35 +29,7 @@ Promise.all([loadC("1"), loadC("2")]).then(function(arr) { ```javascript /******/ (() => { // webpackBootstrap /******/ var __webpack_modules__ = ([ -/* 0 */ -/*!********************!*\ - !*** ./example.js ***! - \********************/ -/*! namespace exports */ -/*! exports [not provided] [no usage info] */ -/*! runtime requirements: __webpack_require__, __webpack_require__.n, __webpack_require__.r, __webpack_exports__, __webpack_require__.e, __webpack_require__.t, __webpack_require__.* */ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony import */ var a__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! a */ 1); -/* harmony import */ var a__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(a__WEBPACK_IMPORTED_MODULE_0__); - - -__webpack_require__.e(/*! import() */ 644).then(__webpack_require__.t.bind(__webpack_require__, /*! b */ 3, 23)).then(function(b) { - console.log("b loaded", b); -}) - -function loadC(name) { - return __webpack_require__(2)("./" + name); -} - -Promise.all([loadC("1"), loadC("2")]).then(function(arr) { - console.log("c/1 and c/2 loaded", arr); -}); - - -/***/ }), +/* 0 */, /* 1 */ /*!***************************!*\ !*** ./node_modules/a.js ***! @@ -107,10 +79,10 @@ function webpackAsyncContext(req) { var ids = map[req], id = ids[0]; return __webpack_require__.e(ids[1]).then(() => { - return __webpack_require__.t(id, 7); + return __webpack_require__.t(id, 7 | 16); }); } -webpackAsyncContext.keys = () => Object.keys(map); +webpackAsyncContext.keys = () => (Object.keys(map)); webpackAsyncContext.id = 2; module.exports = webpackAsyncContext; @@ -128,8 +100,9 @@ module.exports = webpackAsyncContext; /******/ // The require function /******/ function __webpack_require__(moduleId) { /******/ // Check if module is in cache -/******/ if(__webpack_module_cache__[moduleId]) { -/******/ return __webpack_module_cache__[moduleId].exports; +/******/ var cachedModule = __webpack_module_cache__[moduleId]; +/******/ if (cachedModule !== undefined) { +/******/ return cachedModule.exports; /******/ } /******/ // Create a new module (and put it into the cache) /******/ var module = __webpack_module_cache__[moduleId] = { @@ -154,8 +127,8 @@ module.exports = webpackAsyncContext; /******/ // getDefaultExport function for compatibility with non-harmony modules /******/ __webpack_require__.n = (module) => { /******/ var getter = module && module.__esModule ? -/******/ () => module['default'] : -/******/ () => module; +/******/ () => (module['default']) : +/******/ () => (module); /******/ __webpack_require__.d(getter, { a: getter }); /******/ return getter; /******/ }; @@ -163,7 +136,7 @@ module.exports = webpackAsyncContext; /******/ /******/ /* webpack/runtime/create fake namespace object */ /******/ (() => { -/******/ var getProto = Object.getPrototypeOf ? (obj) => Object.getPrototypeOf(obj) : (obj) => obj.__proto__; +/******/ var getProto = Object.getPrototypeOf ? (obj) => (Object.getPrototypeOf(obj)) : (obj) => (obj.__proto__); /******/ var leafPrototypes; /******/ // create a fake namespace object /******/ // mode & 1: value is a module id, require it @@ -183,9 +156,9 @@ module.exports = webpackAsyncContext; /******/ var def = {}; /******/ leafPrototypes = leafPrototypes || [null, getProto({}), getProto([]), getProto(getProto)]; /******/ for(var current = mode & 2 && value; typeof current == 'object' && !~leafPrototypes.indexOf(current); current = getProto(current)) { -/******/ Object.getOwnPropertyNames(current).forEach(key => def[key] = () => value[key]); +/******/ Object.getOwnPropertyNames(current).forEach((key) => (def[key] = () => (value[key]))); /******/ } -/******/ def['default'] = () => value; +/******/ def['default'] = () => (value); /******/ __webpack_require__.d(ns, def); /******/ return ns; /******/ }; @@ -227,7 +200,7 @@ module.exports = webpackAsyncContext; /******/ /******/ /* webpack/runtime/hasOwnProperty shorthand */ /******/ (() => { -/******/ __webpack_require__.o = (obj, prop) => Object.prototype.hasOwnProperty.call(obj, prop) +/******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop)) /******/ })(); /******/ /******/ /* webpack/runtime/load script */ @@ -235,7 +208,7 @@ module.exports = webpackAsyncContext; /******/ var inProgress = {}; /******/ // data-webpack is not used as build has no uniqueName /******/ // loadScript function to load a script via script tag -/******/ __webpack_require__.l = (url, done, key) => { +/******/ __webpack_require__.l = (url, done, key, chunkId) => { /******/ if(inProgress[url]) { inProgress[url].push(done); return; } /******/ var script, needAttach; /******/ if(key !== undefined) { @@ -265,10 +238,9 @@ module.exports = webpackAsyncContext; /******/ var doneFns = inProgress[url]; /******/ delete inProgress[url]; /******/ script.parentNode && script.parentNode.removeChild(script); -/******/ doneFns && doneFns.forEach((fn) => fn(event)); +/******/ doneFns && doneFns.forEach((fn) => (fn(event))); /******/ if(prev) return prev(event); /******/ } -/******/ ; /******/ var timeout = setTimeout(onScriptComplete.bind(null, undefined, { type: 'timeout', target: script }), 120000); /******/ script.onerror = onScriptComplete.bind(null, script.onerror); /******/ script.onload = onScriptComplete.bind(null, script.onload); @@ -298,12 +270,11 @@ module.exports = webpackAsyncContext; /******/ /******/ // object to store loaded and loading chunks /******/ // undefined = chunk not loaded, null = chunk preloaded/prefetched -/******/ // Promise = chunk loading, 0 = chunk loaded +/******/ // [resolve, reject, Promise] = chunk loading, 0 = chunk loaded /******/ var installedChunks = { /******/ 179: 0 /******/ }; /******/ -/******/ /******/ __webpack_require__.f.j = (chunkId, promises) => { /******/ // JSONP chunk loading for javascript /******/ var installedChunkData = __webpack_require__.o(installedChunks, chunkId) ? installedChunks[chunkId] : undefined; @@ -315,9 +286,7 @@ module.exports = webpackAsyncContext; /******/ } else { /******/ if(true) { // all chunks have JS /******/ // setup Promise in chunk cache -/******/ var promise = new Promise((resolve, reject) => { -/******/ installedChunkData = installedChunks[chunkId] = [resolve, reject]; -/******/ }); +/******/ var promise = new Promise((resolve, reject) => (installedChunkData = installedChunks[chunkId] = [resolve, reject])); /******/ promises.push(installedChunkData[2] = promise); /******/ /******/ // start chunk loading @@ -339,7 +308,7 @@ module.exports = webpackAsyncContext; /******/ } /******/ } /******/ }; -/******/ __webpack_require__.l(url, loadingEnded, "chunk-" + chunkId); +/******/ __webpack_require__.l(url, loadingEnded, "chunk-" + chunkId, chunkId); /******/ } else installedChunks[chunkId] = 0; /******/ } /******/ } @@ -353,39 +322,36 @@ module.exports = webpackAsyncContext; /******/ /******/ // no HMR manifest /******/ -/******/ // no deferred startup +/******/ // no on chunks loaded /******/ /******/ // install a JSONP callback for chunk loading /******/ var webpackJsonpCallback = (parentChunkLoadingFunction, data) => { /******/ var [chunkIds, moreModules, runtime] = data; /******/ // add "moreModules" to the modules object, /******/ // then flag all "chunkIds" as loaded and fire callback -/******/ var moduleId, chunkId, i = 0, resolves = []; +/******/ var moduleId, chunkId, i = 0; +/******/ if(chunkIds.some((id) => (installedChunks[id] !== 0))) { +/******/ for(moduleId in moreModules) { +/******/ if(__webpack_require__.o(moreModules, moduleId)) { +/******/ __webpack_require__.m[moduleId] = moreModules[moduleId]; +/******/ } +/******/ } +/******/ if(runtime) var result = runtime(__webpack_require__); +/******/ } +/******/ if(parentChunkLoadingFunction) parentChunkLoadingFunction(data); /******/ for(;i < chunkIds.length; i++) { /******/ chunkId = chunkIds[i]; /******/ if(__webpack_require__.o(installedChunks, chunkId) && installedChunks[chunkId]) { -/******/ resolves.push(installedChunks[chunkId][0]); +/******/ installedChunks[chunkId][0](); /******/ } /******/ installedChunks[chunkId] = 0; /******/ } -/******/ for(moduleId in moreModules) { -/******/ if(__webpack_require__.o(moreModules, moduleId)) { -/******/ __webpack_require__.m[moduleId] = moreModules[moduleId]; -/******/ } -/******/ } -/******/ if(runtime) runtime(__webpack_require__); -/******/ if(parentChunkLoadingFunction) parentChunkLoadingFunction(data); -/******/ while(resolves.length) { -/******/ resolves.shift()(); -/******/ } /******/ /******/ } /******/ /******/ var chunkLoadingGlobal = self["webpackChunk"] = self["webpackChunk"] || []; /******/ chunkLoadingGlobal.forEach(webpackJsonpCallback.bind(null, 0)); /******/ chunkLoadingGlobal.push = webpackJsonpCallback.bind(null, chunkLoadingGlobal.push.bind(chunkLoadingGlobal)); -/******/ -/******/ // no deferred startup /******/ })(); /******/ /************************************************************************/ @@ -394,10 +360,35 @@ module.exports = webpackAsyncContext; ``` js -/******/ // startup -/******/ // Load entry module -/******/ __webpack_require__(0); -/******/ // This entry module used 'exports' so it can't be inlined +var __webpack_exports__ = {}; +// This entry need to be wrapped in an IIFE because it need to be in strict mode. +(() => { +"use strict"; +/*!********************!*\ + !*** ./example.js ***! + \********************/ +/*! namespace exports */ +/*! exports [not provided] [no usage info] */ +/*! runtime requirements: __webpack_require__, __webpack_require__.n, __webpack_require__.r, __webpack_exports__, __webpack_require__.e, __webpack_require__.t, __webpack_require__.* */ +__webpack_require__.r(__webpack_exports__); +/* harmony import */ var a__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! a */ 1); +/* harmony import */ var a__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(a__WEBPACK_IMPORTED_MODULE_0__); + + +__webpack_require__.e(/*! import() */ 644).then(__webpack_require__.t.bind(__webpack_require__, /*! b */ 3, 23)).then(function(b) { + console.log("b loaded", b); +}) + +function loadC(name) { + return __webpack_require__(2)("./" + name); +} + +Promise.all([loadC("1"), loadC("2")]).then(function(arr) { + console.log("c/1 and c/2 loaded", arr); +}); + +})(); + /******/ })() ; ``` @@ -407,7 +398,7 @@ module.exports = webpackAsyncContext; ## Unoptimized ``` -asset output.js 13.7 KiB [emitted] (name: main) +asset output.js 13.6 KiB [emitted] (name: main) asset 346.output.js 296 bytes [emitted] asset 98.output.js 295 bytes [emitted] asset 644.output.js 288 bytes [emitted] @@ -416,11 +407,11 @@ chunk (runtime: main) 98.output.js 13 bytes [rendered] > ./2.js ./node_modules/c/ lazy ^\.\/.*$ namespace object ./2.js ./node_modules/c/2.js 13 bytes [optional] [built] [code generated] [used exports unknown] - context element ./2 ./node_modules/c/ lazy ^\.\/.*$ namespace object ./2 - context element ./2.js ./node_modules/c/ lazy ^\.\/.*$ namespace object ./2.js -chunk (runtime: main) output.js (main) 414 bytes (javascript) 6.9 KiB (runtime) [entry] [rendered] + import() context element ./2 ./node_modules/c/ lazy ^\.\/.*$ namespace object ./2 + import() context element ./2.js ./node_modules/c/ lazy ^\.\/.*$ namespace object ./2.js +chunk (runtime: main) output.js (main) 414 bytes (javascript) 6.91 KiB (runtime) [entry] [rendered] > ./example.js main - runtime modules 6.9 KiB 10 modules + runtime modules 6.91 KiB 10 modules dependent modules 171 bytes [dependent] 2 modules ./example.js 243 bytes [built] [code generated] [no exports] @@ -431,14 +422,14 @@ chunk (runtime: main) 346.output.js 13 bytes [rendered] > ./1.js ./node_modules/c/ lazy ^\.\/.*$ namespace object ./1.js ./node_modules/c/1.js 13 bytes [optional] [built] [code generated] [used exports unknown] - context element ./1 ./node_modules/c/ lazy ^\.\/.*$ namespace object ./1 - context element ./1.js ./node_modules/c/ lazy ^\.\/.*$ namespace object ./1.js + import() context element ./1 ./node_modules/c/ lazy ^\.\/.*$ namespace object ./1 + import() context element ./1.js ./node_modules/c/ lazy ^\.\/.*$ namespace object ./1.js chunk (runtime: main) 644.output.js 11 bytes [rendered] > b ./example.js 3:0-11 ./node_modules/b.js 11 bytes [built] [code generated] [used exports unknown] import() b ./example.js 3:0-11 -webpack 5.11.1 compiled successfully +webpack 5.78.0 compiled successfully ``` ## Production mode @@ -453,11 +444,11 @@ chunk (runtime: main) 98.output.js 13 bytes [rendered] > ./2.js ./node_modules/c/ lazy ^\.\/.*$ namespace object ./2.js ./node_modules/c/2.js 13 bytes [optional] [built] [code generated] [used exports unknown] - context element ./2 ./node_modules/c/ lazy ^\.\/.*$ namespace object ./2 - context element ./2.js ./node_modules/c/ lazy ^\.\/.*$ namespace object ./2.js -chunk (runtime: main) output.js (main) 403 bytes (javascript) 6.64 KiB (runtime) [entry] [rendered] + import() context element ./2 ./node_modules/c/ lazy ^\.\/.*$ namespace object ./2 + import() context element ./2.js ./node_modules/c/ lazy ^\.\/.*$ namespace object ./2.js +chunk (runtime: main) output.js (main) 403 bytes (javascript) 6.65 KiB (runtime) [entry] [rendered] > ./example.js main - runtime modules 6.64 KiB 9 modules + runtime modules 6.65 KiB 9 modules dependent modules 160 bytes [dependent] 1 module ./example.js 243 bytes [built] [code generated] [no exports] @@ -468,12 +459,12 @@ chunk (runtime: main) 346.output.js 13 bytes [rendered] > ./1.js ./node_modules/c/ lazy ^\.\/.*$ namespace object ./1.js ./node_modules/c/1.js 13 bytes [optional] [built] [code generated] [used exports unknown] - context element ./1 ./node_modules/c/ lazy ^\.\/.*$ namespace object ./1 - context element ./1.js ./node_modules/c/ lazy ^\.\/.*$ namespace object ./1.js + import() context element ./1 ./node_modules/c/ lazy ^\.\/.*$ namespace object ./1 + import() context element ./1.js ./node_modules/c/ lazy ^\.\/.*$ namespace object ./1.js chunk (runtime: main) 644.output.js 11 bytes [rendered] > b ./example.js 3:0-11 ./node_modules/b.js 11 bytes [built] [code generated] [used exports unknown] import() b ./example.js 3:0-11 -webpack 5.11.1 compiled successfully +webpack 5.78.0 compiled successfully ``` diff --git a/examples/code-splitting-native-import-context-filter/README.md b/examples/code-splitting-native-import-context-filter/README.md index 05287021f41..2eaaedfc945 100644 --- a/examples/code-splitting-native-import-context-filter/README.md +++ b/examples/code-splitting-native-import-context-filter/README.md @@ -98,7 +98,7 @@ function webpackAsyncContext(req) { return __webpack_require__(id); }); } -webpackAsyncContext.keys = () => Object.keys(map); +webpackAsyncContext.keys = () => (Object.keys(map)); webpackAsyncContext.id = 1; module.exports = webpackAsyncContext; @@ -116,8 +116,9 @@ module.exports = webpackAsyncContext; /******/ // The require function /******/ function __webpack_require__(moduleId) { /******/ // Check if module is in cache -/******/ if(__webpack_module_cache__[moduleId]) { -/******/ return __webpack_module_cache__[moduleId].exports; +/******/ var cachedModule = __webpack_module_cache__[moduleId]; +/******/ if (cachedModule !== undefined) { +/******/ return cachedModule.exports; /******/ } /******/ // Create a new module (and put it into the cache) /******/ var module = __webpack_module_cache__[moduleId] = { @@ -173,7 +174,7 @@ module.exports = webpackAsyncContext; /******/ /******/ /* webpack/runtime/hasOwnProperty shorthand */ /******/ (() => { -/******/ __webpack_require__.o = (obj, prop) => Object.prototype.hasOwnProperty.call(obj, prop) +/******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop)) /******/ })(); /******/ /******/ /* webpack/runtime/load script */ @@ -181,7 +182,7 @@ module.exports = webpackAsyncContext; /******/ var inProgress = {}; /******/ // data-webpack is not used as build has no uniqueName /******/ // loadScript function to load a script via script tag -/******/ __webpack_require__.l = (url, done, key) => { +/******/ __webpack_require__.l = (url, done, key, chunkId) => { /******/ if(inProgress[url]) { inProgress[url].push(done); return; } /******/ var script, needAttach; /******/ if(key !== undefined) { @@ -211,10 +212,9 @@ module.exports = webpackAsyncContext; /******/ var doneFns = inProgress[url]; /******/ delete inProgress[url]; /******/ script.parentNode && script.parentNode.removeChild(script); -/******/ doneFns && doneFns.forEach((fn) => fn(event)); +/******/ doneFns && doneFns.forEach((fn) => (fn(event))); /******/ if(prev) return prev(event); /******/ } -/******/ ; /******/ var timeout = setTimeout(onScriptComplete.bind(null, undefined, { type: 'timeout', target: script }), 120000); /******/ script.onerror = onScriptComplete.bind(null, script.onerror); /******/ script.onload = onScriptComplete.bind(null, script.onload); @@ -244,12 +244,11 @@ module.exports = webpackAsyncContext; /******/ /******/ // object to store loaded and loading chunks /******/ // undefined = chunk not loaded, null = chunk preloaded/prefetched -/******/ // Promise = chunk loading, 0 = chunk loaded +/******/ // [resolve, reject, Promise] = chunk loading, 0 = chunk loaded /******/ var installedChunks = { /******/ 179: 0 /******/ }; /******/ -/******/ /******/ __webpack_require__.f.j = (chunkId, promises) => { /******/ // JSONP chunk loading for javascript /******/ var installedChunkData = __webpack_require__.o(installedChunks, chunkId) ? installedChunks[chunkId] : undefined; @@ -261,9 +260,7 @@ module.exports = webpackAsyncContext; /******/ } else { /******/ if(true) { // all chunks have JS /******/ // setup Promise in chunk cache -/******/ var promise = new Promise((resolve, reject) => { -/******/ installedChunkData = installedChunks[chunkId] = [resolve, reject]; -/******/ }); +/******/ var promise = new Promise((resolve, reject) => (installedChunkData = installedChunks[chunkId] = [resolve, reject])); /******/ promises.push(installedChunkData[2] = promise); /******/ /******/ // start chunk loading @@ -285,7 +282,7 @@ module.exports = webpackAsyncContext; /******/ } /******/ } /******/ }; -/******/ __webpack_require__.l(url, loadingEnded, "chunk-" + chunkId); +/******/ __webpack_require__.l(url, loadingEnded, "chunk-" + chunkId, chunkId); /******/ } else installedChunks[chunkId] = 0; /******/ } /******/ } @@ -299,39 +296,36 @@ module.exports = webpackAsyncContext; /******/ /******/ // no HMR manifest /******/ -/******/ // no deferred startup +/******/ // no on chunks loaded /******/ /******/ // install a JSONP callback for chunk loading /******/ var webpackJsonpCallback = (parentChunkLoadingFunction, data) => { /******/ var [chunkIds, moreModules, runtime] = data; /******/ // add "moreModules" to the modules object, /******/ // then flag all "chunkIds" as loaded and fire callback -/******/ var moduleId, chunkId, i = 0, resolves = []; +/******/ var moduleId, chunkId, i = 0; +/******/ if(chunkIds.some((id) => (installedChunks[id] !== 0))) { +/******/ for(moduleId in moreModules) { +/******/ if(__webpack_require__.o(moreModules, moduleId)) { +/******/ __webpack_require__.m[moduleId] = moreModules[moduleId]; +/******/ } +/******/ } +/******/ if(runtime) var result = runtime(__webpack_require__); +/******/ } +/******/ if(parentChunkLoadingFunction) parentChunkLoadingFunction(data); /******/ for(;i < chunkIds.length; i++) { /******/ chunkId = chunkIds[i]; /******/ if(__webpack_require__.o(installedChunks, chunkId) && installedChunks[chunkId]) { -/******/ resolves.push(installedChunks[chunkId][0]); +/******/ installedChunks[chunkId][0](); /******/ } /******/ installedChunks[chunkId] = 0; /******/ } -/******/ for(moduleId in moreModules) { -/******/ if(__webpack_require__.o(moreModules, moduleId)) { -/******/ __webpack_require__.m[moduleId] = moreModules[moduleId]; -/******/ } -/******/ } -/******/ if(runtime) runtime(__webpack_require__); -/******/ if(parentChunkLoadingFunction) parentChunkLoadingFunction(data); -/******/ while(resolves.length) { -/******/ resolves.shift()(); -/******/ } /******/ /******/ } /******/ /******/ var chunkLoadingGlobal = self["webpackChunk"] = self["webpackChunk"] || []; /******/ chunkLoadingGlobal.forEach(webpackJsonpCallback.bind(null, 0)); /******/ chunkLoadingGlobal.push = webpackJsonpCallback.bind(null, chunkLoadingGlobal.push.bind(chunkLoadingGlobal)); -/******/ -/******/ // no deferred startup /******/ })(); /******/ /************************************************************************/ @@ -340,6 +334,8 @@ module.exports = webpackAsyncContext; ``` js +var __webpack_exports__ = {}; +// This entry need to be wrapped in an IIFE because it need to be isolated against other modules in the chunk. (() => { /*!********************!*\ !*** ./example.js ***! @@ -375,10 +371,10 @@ getTemplate("baz.noimport"); ## Unoptimized ``` -asset output.js 11.1 KiB [emitted] (name: main) -asset 398.output.js 856 bytes [emitted] -asset 544.output.js 856 bytes [emitted] -asset 718.output.js 856 bytes [emitted] +asset output.js 11.2 KiB [emitted] (name: main) +asset 398.output.js 858 bytes [emitted] +asset 544.output.js 858 bytes [emitted] +asset 718.output.js 858 bytes [emitted] chunk (runtime: main) output.js (main) 597 bytes (javascript) 5.54 KiB (runtime) [entry] [rendered] > ./example.js main runtime modules 5.54 KiB 8 modules @@ -392,25 +388,25 @@ chunk (runtime: main) 398.output.js 38 bytes [rendered] ./templates/bar.js 38 bytes [optional] [built] [code generated] [exports: default] [used exports unknown] - context element ./bar ./templates/ lazy ^\.\/.*$ include: \.js$ exclude: \.noimport\.js$ namespace object ./bar - context element ./bar.js ./templates/ lazy ^\.\/.*$ include: \.js$ exclude: \.noimport\.js$ namespace object ./bar.js + import() context element ./bar ./templates/ lazy ^\.\/.*$ include: \.js$ exclude: \.noimport\.js$ namespace object ./bar + import() context element ./bar.js ./templates/ lazy ^\.\/.*$ include: \.js$ exclude: \.noimport\.js$ namespace object ./bar.js chunk (runtime: main) 544.output.js 38 bytes [rendered] > ./baz ./templates/ lazy ^\.\/.*$ include: \.js$ exclude: \.noimport\.js$ namespace object ./baz > ./baz.js ./templates/ lazy ^\.\/.*$ include: \.js$ exclude: \.noimport\.js$ namespace object ./baz.js ./templates/baz.js 38 bytes [optional] [built] [code generated] [exports: default] [used exports unknown] - context element ./baz ./templates/ lazy ^\.\/.*$ include: \.js$ exclude: \.noimport\.js$ namespace object ./baz - context element ./baz.js ./templates/ lazy ^\.\/.*$ include: \.js$ exclude: \.noimport\.js$ namespace object ./baz.js + import() context element ./baz ./templates/ lazy ^\.\/.*$ include: \.js$ exclude: \.noimport\.js$ namespace object ./baz + import() context element ./baz.js ./templates/ lazy ^\.\/.*$ include: \.js$ exclude: \.noimport\.js$ namespace object ./baz.js chunk (runtime: main) 718.output.js 38 bytes [rendered] > ./foo ./templates/ lazy ^\.\/.*$ include: \.js$ exclude: \.noimport\.js$ namespace object ./foo > ./foo.js ./templates/ lazy ^\.\/.*$ include: \.js$ exclude: \.noimport\.js$ namespace object ./foo.js ./templates/foo.js 38 bytes [optional] [built] [code generated] [exports: default] [used exports unknown] - context element ./foo ./templates/ lazy ^\.\/.*$ include: \.js$ exclude: \.noimport\.js$ namespace object ./foo - context element ./foo.js ./templates/ lazy ^\.\/.*$ include: \.js$ exclude: \.noimport\.js$ namespace object ./foo.js -webpack 5.11.1 compiled successfully + import() context element ./foo ./templates/ lazy ^\.\/.*$ include: \.js$ exclude: \.noimport\.js$ namespace object ./foo + import() context element ./foo.js ./templates/ lazy ^\.\/.*$ include: \.js$ exclude: \.noimport\.js$ namespace object ./foo.js +webpack 5.78.0 compiled successfully ``` ## Production mode @@ -432,21 +428,21 @@ chunk (runtime: main) 398.output.js 38 bytes [rendered] > ./bar.js ./templates/ lazy ^\.\/.*$ include: \.js$ exclude: \.noimport\.js$ namespace object ./bar.js ./templates/bar.js 38 bytes [optional] [built] [code generated] [exports: default] - context element ./bar ./templates/ lazy ^\.\/.*$ include: \.js$ exclude: \.noimport\.js$ namespace object ./bar - context element ./bar.js ./templates/ lazy ^\.\/.*$ include: \.js$ exclude: \.noimport\.js$ namespace object ./bar.js + import() context element ./bar ./templates/ lazy ^\.\/.*$ include: \.js$ exclude: \.noimport\.js$ namespace object ./bar + import() context element ./bar.js ./templates/ lazy ^\.\/.*$ include: \.js$ exclude: \.noimport\.js$ namespace object ./bar.js chunk (runtime: main) 544.output.js 38 bytes [rendered] > ./baz ./templates/ lazy ^\.\/.*$ include: \.js$ exclude: \.noimport\.js$ namespace object ./baz > ./baz.js ./templates/ lazy ^\.\/.*$ include: \.js$ exclude: \.noimport\.js$ namespace object ./baz.js ./templates/baz.js 38 bytes [optional] [built] [code generated] [exports: default] - context element ./baz ./templates/ lazy ^\.\/.*$ include: \.js$ exclude: \.noimport\.js$ namespace object ./baz - context element ./baz.js ./templates/ lazy ^\.\/.*$ include: \.js$ exclude: \.noimport\.js$ namespace object ./baz.js + import() context element ./baz ./templates/ lazy ^\.\/.*$ include: \.js$ exclude: \.noimport\.js$ namespace object ./baz + import() context element ./baz.js ./templates/ lazy ^\.\/.*$ include: \.js$ exclude: \.noimport\.js$ namespace object ./baz.js chunk (runtime: main) 718.output.js 38 bytes [rendered] > ./foo ./templates/ lazy ^\.\/.*$ include: \.js$ exclude: \.noimport\.js$ namespace object ./foo > ./foo.js ./templates/ lazy ^\.\/.*$ include: \.js$ exclude: \.noimport\.js$ namespace object ./foo.js ./templates/foo.js 38 bytes [optional] [built] [code generated] [exports: default] - context element ./foo ./templates/ lazy ^\.\/.*$ include: \.js$ exclude: \.noimport\.js$ namespace object ./foo - context element ./foo.js ./templates/ lazy ^\.\/.*$ include: \.js$ exclude: \.noimport\.js$ namespace object ./foo.js -webpack 5.11.1 compiled successfully + import() context element ./foo ./templates/ lazy ^\.\/.*$ include: \.js$ exclude: \.noimport\.js$ namespace object ./foo + import() context element ./foo.js ./templates/ lazy ^\.\/.*$ include: \.js$ exclude: \.noimport\.js$ namespace object ./foo.js +webpack 5.78.0 compiled successfully ``` diff --git a/examples/code-splitting-native-import-context/README.md b/examples/code-splitting-native-import-context/README.md index e530c9b9dd0..081d3de6353 100644 --- a/examples/code-splitting-native-import-context/README.md +++ b/examples/code-splitting-native-import-context/README.md @@ -87,7 +87,7 @@ function webpackAsyncContext(req) { return __webpack_require__(id); }); } -webpackAsyncContext.keys = () => Object.keys(map); +webpackAsyncContext.keys = () => (Object.keys(map)); webpackAsyncContext.id = 1; module.exports = webpackAsyncContext; @@ -105,8 +105,9 @@ module.exports = webpackAsyncContext; /******/ // The require function /******/ function __webpack_require__(moduleId) { /******/ // Check if module is in cache -/******/ if(__webpack_module_cache__[moduleId]) { -/******/ return __webpack_module_cache__[moduleId].exports; +/******/ var cachedModule = __webpack_module_cache__[moduleId]; +/******/ if (cachedModule !== undefined) { +/******/ return cachedModule.exports; /******/ } /******/ // Create a new module (and put it into the cache) /******/ var module = __webpack_module_cache__[moduleId] = { @@ -162,7 +163,7 @@ module.exports = webpackAsyncContext; /******/ /******/ /* webpack/runtime/hasOwnProperty shorthand */ /******/ (() => { -/******/ __webpack_require__.o = (obj, prop) => Object.prototype.hasOwnProperty.call(obj, prop) +/******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop)) /******/ })(); /******/ /******/ /* webpack/runtime/load script */ @@ -170,7 +171,7 @@ module.exports = webpackAsyncContext; /******/ var inProgress = {}; /******/ // data-webpack is not used as build has no uniqueName /******/ // loadScript function to load a script via script tag -/******/ __webpack_require__.l = (url, done, key) => { +/******/ __webpack_require__.l = (url, done, key, chunkId) => { /******/ if(inProgress[url]) { inProgress[url].push(done); return; } /******/ var script, needAttach; /******/ if(key !== undefined) { @@ -200,10 +201,9 @@ module.exports = webpackAsyncContext; /******/ var doneFns = inProgress[url]; /******/ delete inProgress[url]; /******/ script.parentNode && script.parentNode.removeChild(script); -/******/ doneFns && doneFns.forEach((fn) => fn(event)); +/******/ doneFns && doneFns.forEach((fn) => (fn(event))); /******/ if(prev) return prev(event); /******/ } -/******/ ; /******/ var timeout = setTimeout(onScriptComplete.bind(null, undefined, { type: 'timeout', target: script }), 120000); /******/ script.onerror = onScriptComplete.bind(null, script.onerror); /******/ script.onload = onScriptComplete.bind(null, script.onload); @@ -233,12 +233,11 @@ module.exports = webpackAsyncContext; /******/ /******/ // object to store loaded and loading chunks /******/ // undefined = chunk not loaded, null = chunk preloaded/prefetched -/******/ // Promise = chunk loading, 0 = chunk loaded +/******/ // [resolve, reject, Promise] = chunk loading, 0 = chunk loaded /******/ var installedChunks = { /******/ 179: 0 /******/ }; /******/ -/******/ /******/ __webpack_require__.f.j = (chunkId, promises) => { /******/ // JSONP chunk loading for javascript /******/ var installedChunkData = __webpack_require__.o(installedChunks, chunkId) ? installedChunks[chunkId] : undefined; @@ -250,9 +249,7 @@ module.exports = webpackAsyncContext; /******/ } else { /******/ if(true) { // all chunks have JS /******/ // setup Promise in chunk cache -/******/ var promise = new Promise((resolve, reject) => { -/******/ installedChunkData = installedChunks[chunkId] = [resolve, reject]; -/******/ }); +/******/ var promise = new Promise((resolve, reject) => (installedChunkData = installedChunks[chunkId] = [resolve, reject])); /******/ promises.push(installedChunkData[2] = promise); /******/ /******/ // start chunk loading @@ -274,7 +271,7 @@ module.exports = webpackAsyncContext; /******/ } /******/ } /******/ }; -/******/ __webpack_require__.l(url, loadingEnded, "chunk-" + chunkId); +/******/ __webpack_require__.l(url, loadingEnded, "chunk-" + chunkId, chunkId); /******/ } else installedChunks[chunkId] = 0; /******/ } /******/ } @@ -288,39 +285,36 @@ module.exports = webpackAsyncContext; /******/ /******/ // no HMR manifest /******/ -/******/ // no deferred startup +/******/ // no on chunks loaded /******/ /******/ // install a JSONP callback for chunk loading /******/ var webpackJsonpCallback = (parentChunkLoadingFunction, data) => { /******/ var [chunkIds, moreModules, runtime] = data; /******/ // add "moreModules" to the modules object, /******/ // then flag all "chunkIds" as loaded and fire callback -/******/ var moduleId, chunkId, i = 0, resolves = []; +/******/ var moduleId, chunkId, i = 0; +/******/ if(chunkIds.some((id) => (installedChunks[id] !== 0))) { +/******/ for(moduleId in moreModules) { +/******/ if(__webpack_require__.o(moreModules, moduleId)) { +/******/ __webpack_require__.m[moduleId] = moreModules[moduleId]; +/******/ } +/******/ } +/******/ if(runtime) var result = runtime(__webpack_require__); +/******/ } +/******/ if(parentChunkLoadingFunction) parentChunkLoadingFunction(data); /******/ for(;i < chunkIds.length; i++) { /******/ chunkId = chunkIds[i]; /******/ if(__webpack_require__.o(installedChunks, chunkId) && installedChunks[chunkId]) { -/******/ resolves.push(installedChunks[chunkId][0]); +/******/ installedChunks[chunkId][0](); /******/ } /******/ installedChunks[chunkId] = 0; /******/ } -/******/ for(moduleId in moreModules) { -/******/ if(__webpack_require__.o(moreModules, moduleId)) { -/******/ __webpack_require__.m[moduleId] = moreModules[moduleId]; -/******/ } -/******/ } -/******/ if(runtime) runtime(__webpack_require__); -/******/ if(parentChunkLoadingFunction) parentChunkLoadingFunction(data); -/******/ while(resolves.length) { -/******/ resolves.shift()(); -/******/ } /******/ /******/ } /******/ /******/ var chunkLoadingGlobal = self["webpackChunk"] = self["webpackChunk"] || []; /******/ chunkLoadingGlobal.forEach(webpackJsonpCallback.bind(null, 0)); /******/ chunkLoadingGlobal.push = webpackJsonpCallback.bind(null, chunkLoadingGlobal.push.bind(chunkLoadingGlobal)); -/******/ -/******/ // no deferred startup /******/ })(); /******/ /************************************************************************/ @@ -329,6 +323,8 @@ module.exports = webpackAsyncContext; ``` js +var __webpack_exports__ = {}; +// This entry need to be wrapped in an IIFE because it need to be isolated against other modules in the chunk. (() => { /*!********************!*\ !*** ./example.js ***! @@ -362,10 +358,10 @@ getTemplate("baz"); ## Unoptimized ``` -asset output.js 10.9 KiB [emitted] (name: main) -asset 398.output.js 856 bytes [emitted] -asset 544.output.js 856 bytes [emitted] -asset 718.output.js 856 bytes [emitted] +asset output.js 11 KiB [emitted] (name: main) +asset 398.output.js 858 bytes [emitted] +asset 544.output.js 858 bytes [emitted] +asset 718.output.js 858 bytes [emitted] chunk (runtime: main) output.js (main) 441 bytes (javascript) 5.54 KiB (runtime) [entry] [rendered] > ./example.js main runtime modules 5.54 KiB 8 modules @@ -379,25 +375,25 @@ chunk (runtime: main) 398.output.js 38 bytes [rendered] ./templates/bar.js 38 bytes [optional] [built] [code generated] [exports: default] [used exports unknown] - context element ./bar ./templates/ lazy ^\.\/.*$ namespace object ./bar - context element ./bar.js ./templates/ lazy ^\.\/.*$ namespace object ./bar.js + import() context element ./bar ./templates/ lazy ^\.\/.*$ namespace object ./bar + import() context element ./bar.js ./templates/ lazy ^\.\/.*$ namespace object ./bar.js chunk (runtime: main) 544.output.js 38 bytes [rendered] > ./baz ./templates/ lazy ^\.\/.*$ namespace object ./baz > ./baz.js ./templates/ lazy ^\.\/.*$ namespace object ./baz.js ./templates/baz.js 38 bytes [optional] [built] [code generated] [exports: default] [used exports unknown] - context element ./baz ./templates/ lazy ^\.\/.*$ namespace object ./baz - context element ./baz.js ./templates/ lazy ^\.\/.*$ namespace object ./baz.js + import() context element ./baz ./templates/ lazy ^\.\/.*$ namespace object ./baz + import() context element ./baz.js ./templates/ lazy ^\.\/.*$ namespace object ./baz.js chunk (runtime: main) 718.output.js 38 bytes [rendered] > ./foo ./templates/ lazy ^\.\/.*$ namespace object ./foo > ./foo.js ./templates/ lazy ^\.\/.*$ namespace object ./foo.js ./templates/foo.js 38 bytes [optional] [built] [code generated] [exports: default] [used exports unknown] - context element ./foo ./templates/ lazy ^\.\/.*$ namespace object ./foo - context element ./foo.js ./templates/ lazy ^\.\/.*$ namespace object ./foo.js -webpack 5.11.1 compiled successfully + import() context element ./foo ./templates/ lazy ^\.\/.*$ namespace object ./foo + import() context element ./foo.js ./templates/ lazy ^\.\/.*$ namespace object ./foo.js +webpack 5.78.0 compiled successfully ``` ## Production mode @@ -419,21 +415,21 @@ chunk (runtime: main) 398.output.js 38 bytes [rendered] > ./bar.js ./templates/ lazy ^\.\/.*$ namespace object ./bar.js ./templates/bar.js 38 bytes [optional] [built] [code generated] [exports: default] - context element ./bar ./templates/ lazy ^\.\/.*$ namespace object ./bar - context element ./bar.js ./templates/ lazy ^\.\/.*$ namespace object ./bar.js + import() context element ./bar ./templates/ lazy ^\.\/.*$ namespace object ./bar + import() context element ./bar.js ./templates/ lazy ^\.\/.*$ namespace object ./bar.js chunk (runtime: main) 544.output.js 38 bytes [rendered] > ./baz ./templates/ lazy ^\.\/.*$ namespace object ./baz > ./baz.js ./templates/ lazy ^\.\/.*$ namespace object ./baz.js ./templates/baz.js 38 bytes [optional] [built] [code generated] [exports: default] - context element ./baz ./templates/ lazy ^\.\/.*$ namespace object ./baz - context element ./baz.js ./templates/ lazy ^\.\/.*$ namespace object ./baz.js + import() context element ./baz ./templates/ lazy ^\.\/.*$ namespace object ./baz + import() context element ./baz.js ./templates/ lazy ^\.\/.*$ namespace object ./baz.js chunk (runtime: main) 718.output.js 38 bytes [rendered] > ./foo ./templates/ lazy ^\.\/.*$ namespace object ./foo > ./foo.js ./templates/ lazy ^\.\/.*$ namespace object ./foo.js ./templates/foo.js 38 bytes [optional] [built] [code generated] [exports: default] - context element ./foo ./templates/ lazy ^\.\/.*$ namespace object ./foo - context element ./foo.js ./templates/ lazy ^\.\/.*$ namespace object ./foo.js -webpack 5.11.1 compiled successfully + import() context element ./foo ./templates/ lazy ^\.\/.*$ namespace object ./foo + import() context element ./foo.js ./templates/ lazy ^\.\/.*$ namespace object ./foo.js +webpack 5.78.0 compiled successfully ``` diff --git a/examples/code-splitting-specify-chunk-name/README.md b/examples/code-splitting-specify-chunk-name/README.md index a14fb23cdc8..e8a17affc7d 100644 --- a/examples/code-splitting-specify-chunk-name/README.md +++ b/examples/code-splitting-specify-chunk-name/README.md @@ -79,7 +79,7 @@ function webpackAsyncContext(req) { return __webpack_require__(id); }); } -webpackAsyncContext.keys = () => Object.keys(map); +webpackAsyncContext.keys = () => (Object.keys(map)); webpackAsyncContext.id = 1; module.exports = webpackAsyncContext; @@ -97,8 +97,9 @@ module.exports = webpackAsyncContext; /******/ // The require function /******/ function __webpack_require__(moduleId) { /******/ // Check if module is in cache -/******/ if(__webpack_module_cache__[moduleId]) { -/******/ return __webpack_module_cache__[moduleId].exports; +/******/ var cachedModule = __webpack_module_cache__[moduleId]; +/******/ if (cachedModule !== undefined) { +/******/ return cachedModule.exports; /******/ } /******/ // Create a new module (and put it into the cache) /******/ var module = __webpack_module_cache__[moduleId] = { @@ -154,7 +155,7 @@ module.exports = webpackAsyncContext; /******/ /******/ /* webpack/runtime/hasOwnProperty shorthand */ /******/ (() => { -/******/ __webpack_require__.o = (obj, prop) => Object.prototype.hasOwnProperty.call(obj, prop) +/******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop)) /******/ })(); /******/ /******/ /* webpack/runtime/load script */ @@ -162,7 +163,7 @@ module.exports = webpackAsyncContext; /******/ var inProgress = {}; /******/ // data-webpack is not used as build has no uniqueName /******/ // loadScript function to load a script via script tag -/******/ __webpack_require__.l = (url, done, key) => { +/******/ __webpack_require__.l = (url, done, key, chunkId) => { /******/ if(inProgress[url]) { inProgress[url].push(done); return; } /******/ var script, needAttach; /******/ if(key !== undefined) { @@ -192,10 +193,9 @@ module.exports = webpackAsyncContext; /******/ var doneFns = inProgress[url]; /******/ delete inProgress[url]; /******/ script.parentNode && script.parentNode.removeChild(script); -/******/ doneFns && doneFns.forEach((fn) => fn(event)); +/******/ doneFns && doneFns.forEach((fn) => (fn(event))); /******/ if(prev) return prev(event); /******/ } -/******/ ; /******/ var timeout = setTimeout(onScriptComplete.bind(null, undefined, { type: 'timeout', target: script }), 120000); /******/ script.onerror = onScriptComplete.bind(null, script.onerror); /******/ script.onload = onScriptComplete.bind(null, script.onload); @@ -225,12 +225,11 @@ module.exports = webpackAsyncContext; /******/ /******/ // object to store loaded and loading chunks /******/ // undefined = chunk not loaded, null = chunk preloaded/prefetched -/******/ // Promise = chunk loading, 0 = chunk loaded +/******/ // [resolve, reject, Promise] = chunk loading, 0 = chunk loaded /******/ var installedChunks = { /******/ 179: 0 /******/ }; /******/ -/******/ /******/ __webpack_require__.f.j = (chunkId, promises) => { /******/ // JSONP chunk loading for javascript /******/ var installedChunkData = __webpack_require__.o(installedChunks, chunkId) ? installedChunks[chunkId] : undefined; @@ -242,9 +241,7 @@ module.exports = webpackAsyncContext; /******/ } else { /******/ if(true) { // all chunks have JS /******/ // setup Promise in chunk cache -/******/ var promise = new Promise((resolve, reject) => { -/******/ installedChunkData = installedChunks[chunkId] = [resolve, reject]; -/******/ }); +/******/ var promise = new Promise((resolve, reject) => (installedChunkData = installedChunks[chunkId] = [resolve, reject])); /******/ promises.push(installedChunkData[2] = promise); /******/ /******/ // start chunk loading @@ -266,7 +263,7 @@ module.exports = webpackAsyncContext; /******/ } /******/ } /******/ }; -/******/ __webpack_require__.l(url, loadingEnded, "chunk-" + chunkId); +/******/ __webpack_require__.l(url, loadingEnded, "chunk-" + chunkId, chunkId); /******/ } else installedChunks[chunkId] = 0; /******/ } /******/ } @@ -280,39 +277,36 @@ module.exports = webpackAsyncContext; /******/ /******/ // no HMR manifest /******/ -/******/ // no deferred startup +/******/ // no on chunks loaded /******/ /******/ // install a JSONP callback for chunk loading /******/ var webpackJsonpCallback = (parentChunkLoadingFunction, data) => { /******/ var [chunkIds, moreModules, runtime] = data; /******/ // add "moreModules" to the modules object, /******/ // then flag all "chunkIds" as loaded and fire callback -/******/ var moduleId, chunkId, i = 0, resolves = []; +/******/ var moduleId, chunkId, i = 0; +/******/ if(chunkIds.some((id) => (installedChunks[id] !== 0))) { +/******/ for(moduleId in moreModules) { +/******/ if(__webpack_require__.o(moreModules, moduleId)) { +/******/ __webpack_require__.m[moduleId] = moreModules[moduleId]; +/******/ } +/******/ } +/******/ if(runtime) var result = runtime(__webpack_require__); +/******/ } +/******/ if(parentChunkLoadingFunction) parentChunkLoadingFunction(data); /******/ for(;i < chunkIds.length; i++) { /******/ chunkId = chunkIds[i]; /******/ if(__webpack_require__.o(installedChunks, chunkId) && installedChunks[chunkId]) { -/******/ resolves.push(installedChunks[chunkId][0]); +/******/ installedChunks[chunkId][0](); /******/ } /******/ installedChunks[chunkId] = 0; /******/ } -/******/ for(moduleId in moreModules) { -/******/ if(__webpack_require__.o(moreModules, moduleId)) { -/******/ __webpack_require__.m[moduleId] = moreModules[moduleId]; -/******/ } -/******/ } -/******/ if(runtime) runtime(__webpack_require__); -/******/ if(parentChunkLoadingFunction) parentChunkLoadingFunction(data); -/******/ while(resolves.length) { -/******/ resolves.shift()(); -/******/ } /******/ /******/ } /******/ /******/ var chunkLoadingGlobal = self["webpackChunk"] = self["webpackChunk"] || []; /******/ chunkLoadingGlobal.forEach(webpackJsonpCallback.bind(null, 0)); /******/ chunkLoadingGlobal.push = webpackJsonpCallback.bind(null, chunkLoadingGlobal.push.bind(chunkLoadingGlobal)); -/******/ -/******/ // no deferred startup /******/ })(); /******/ /************************************************************************/ @@ -321,6 +315,8 @@ module.exports = webpackAsyncContext; ``` js +var __webpack_exports__ = {}; +// This entry need to be wrapped in an IIFE because it need to be isolated against other modules in the chunk. (() => { /*!********************!*\ !*** ./example.js ***! @@ -334,7 +330,7 @@ __webpack_require__.e(/*! import() | chunk-foo */ 930).then(__webpack_require__. __webpack_require__.e(/*! require.ensure | chunk-foo1 */ 930).then((function(require) { var foo = __webpack_require__(/*! ./templates/foo */ 2); console.log('foo:', foo); -}).bind(null, __webpack_require__)).catch(__webpack_require__.oe); +}).bind(null, __webpack_require__))['catch'](__webpack_require__.oe); var createContextVar = "r"; __webpack_require__(1)("./ba" + createContextVar).then(function(bar) { @@ -354,10 +350,10 @@ __webpack_require__(1)("./ba" + createContextVar).then(function(bar) { ## Unoptimized ``` -asset output.js 11.2 KiB [emitted] (name: main) -asset 548.output.js 856 bytes [emitted] (name: chunk-bar-baz2) -asset 791.output.js 856 bytes [emitted] (name: chunk-bar-baz0) -asset 930.output.js 856 bytes [emitted] (name: chunk-foo) +asset output.js 11.3 KiB [emitted] (name: main) +asset 548.output.js 858 bytes [emitted] (name: chunk-bar-baz2) +asset 791.output.js 858 bytes [emitted] (name: chunk-bar-baz0) +asset 930.output.js 858 bytes [emitted] (name: chunk-foo) chunk (runtime: main) output.js (main) 565 bytes (javascript) 5.54 KiB (runtime) [entry] [rendered] > ./example.js main runtime modules 5.54 KiB 8 modules @@ -371,16 +367,16 @@ chunk (runtime: main) 548.output.js (chunk-bar-baz2) 38 bytes [rendered] ./templates/baz.js 38 bytes [optional] [built] [code generated] [exports: default] [used exports unknown] - context element ./baz ./templates/ lazy ^\.\/ba.*$ chunkName: chunk-bar-baz namespace object ./baz - context element ./baz.js ./templates/ lazy ^\.\/ba.*$ chunkName: chunk-bar-baz namespace object ./baz.js + import() context element ./baz ./templates/ lazy ^\.\/ba.*$ chunkName: chunk-bar-baz namespace object ./baz + import() context element ./baz.js ./templates/ lazy ^\.\/ba.*$ chunkName: chunk-bar-baz namespace object ./baz.js chunk (runtime: main) 791.output.js (chunk-bar-baz0) 38 bytes [rendered] > ./bar ./templates/ lazy ^\.\/ba.*$ chunkName: chunk-bar-baz namespace object ./bar > ./bar.js ./templates/ lazy ^\.\/ba.*$ chunkName: chunk-bar-baz namespace object ./bar.js ./templates/bar.js 38 bytes [optional] [built] [code generated] [exports: default] [used exports unknown] - context element ./bar ./templates/ lazy ^\.\/ba.*$ chunkName: chunk-bar-baz namespace object ./bar - context element ./bar.js ./templates/ lazy ^\.\/ba.*$ chunkName: chunk-bar-baz namespace object ./bar.js + import() context element ./bar ./templates/ lazy ^\.\/ba.*$ chunkName: chunk-bar-baz namespace object ./bar + import() context element ./bar.js ./templates/ lazy ^\.\/ba.*$ chunkName: chunk-bar-baz namespace object ./bar.js chunk (runtime: main) 930.output.js (chunk-foo) 38 bytes [rendered] > ./templates/foo ./example.js 1:0-62 > ./example.js 5:0-8:16 @@ -389,13 +385,13 @@ chunk (runtime: main) 930.output.js (chunk-foo) 38 bytes [rendered] [used exports unknown] import() ./templates/foo ./example.js 1:0-62 cjs require ./templates/foo ./example.js 6:11-37 -webpack 5.11.1 compiled successfully +webpack 5.78.0 compiled successfully ``` ## Production mode ``` -asset output.js 2.44 KiB [emitted] [minimized] (name: main) +asset output.js 2.45 KiB [emitted] [minimized] (name: main) asset 548.output.js 130 bytes [emitted] [minimized] (name: chunk-bar-baz2) asset 791.output.js 130 bytes [emitted] [minimized] (name: chunk-bar-baz0) asset 930.output.js 130 bytes [emitted] [minimized] (name: chunk-foo) @@ -411,15 +407,15 @@ chunk (runtime: main) 548.output.js (chunk-bar-baz2) 38 bytes [rendered] > ./baz.js ./templates/ lazy ^\.\/ba.*$ chunkName: chunk-bar-baz namespace object ./baz.js ./templates/baz.js 38 bytes [optional] [built] [code generated] [exports: default] - context element ./baz ./templates/ lazy ^\.\/ba.*$ chunkName: chunk-bar-baz namespace object ./baz - context element ./baz.js ./templates/ lazy ^\.\/ba.*$ chunkName: chunk-bar-baz namespace object ./baz.js + import() context element ./baz ./templates/ lazy ^\.\/ba.*$ chunkName: chunk-bar-baz namespace object ./baz + import() context element ./baz.js ./templates/ lazy ^\.\/ba.*$ chunkName: chunk-bar-baz namespace object ./baz.js chunk (runtime: main) 791.output.js (chunk-bar-baz0) 38 bytes [rendered] > ./bar ./templates/ lazy ^\.\/ba.*$ chunkName: chunk-bar-baz namespace object ./bar > ./bar.js ./templates/ lazy ^\.\/ba.*$ chunkName: chunk-bar-baz namespace object ./bar.js ./templates/bar.js 38 bytes [optional] [built] [code generated] [exports: default] - context element ./bar ./templates/ lazy ^\.\/ba.*$ chunkName: chunk-bar-baz namespace object ./bar - context element ./bar.js ./templates/ lazy ^\.\/ba.*$ chunkName: chunk-bar-baz namespace object ./bar.js + import() context element ./bar ./templates/ lazy ^\.\/ba.*$ chunkName: chunk-bar-baz namespace object ./bar + import() context element ./bar.js ./templates/ lazy ^\.\/ba.*$ chunkName: chunk-bar-baz namespace object ./bar.js chunk (runtime: main) 930.output.js (chunk-foo) 38 bytes [rendered] > ./templates/foo ./example.js 1:0-62 > ./example.js 5:0-8:16 @@ -427,5 +423,5 @@ chunk (runtime: main) 930.output.js (chunk-foo) 38 bytes [rendered] [exports: default] import() ./templates/foo ./example.js 1:0-62 cjs require ./templates/foo ./example.js 6:11-37 -webpack 5.11.1 compiled successfully +webpack 5.78.0 compiled successfully ``` diff --git a/examples/code-splitting/README.md b/examples/code-splitting/README.md index d1391a9375b..1666ba4800b 100644 --- a/examples/code-splitting/README.md +++ b/examples/code-splitting/README.md @@ -75,8 +75,9 @@ require.ensure(["c"], function(require) { /******/ // The require function /******/ function __webpack_require__(moduleId) { /******/ // Check if module is in cache -/******/ if(__webpack_module_cache__[moduleId]) { -/******/ return __webpack_module_cache__[moduleId].exports; +/******/ var cachedModule = __webpack_module_cache__[moduleId]; +/******/ if (cachedModule !== undefined) { +/******/ return cachedModule.exports; /******/ } /******/ // Create a new module (and put it into the cache) /******/ var module = __webpack_module_cache__[moduleId] = { @@ -120,7 +121,7 @@ require.ensure(["c"], function(require) { /******/ /******/ /* webpack/runtime/hasOwnProperty shorthand */ /******/ (() => { -/******/ __webpack_require__.o = (obj, prop) => Object.prototype.hasOwnProperty.call(obj, prop) +/******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop)) /******/ })(); /******/ /******/ /* webpack/runtime/load script */ @@ -128,7 +129,7 @@ require.ensure(["c"], function(require) { /******/ var inProgress = {}; /******/ // data-webpack is not used as build has no uniqueName /******/ // loadScript function to load a script via script tag -/******/ __webpack_require__.l = (url, done, key) => { +/******/ __webpack_require__.l = (url, done, key, chunkId) => { /******/ if(inProgress[url]) { inProgress[url].push(done); return; } /******/ var script, needAttach; /******/ if(key !== undefined) { @@ -158,10 +159,9 @@ require.ensure(["c"], function(require) { /******/ var doneFns = inProgress[url]; /******/ delete inProgress[url]; /******/ script.parentNode && script.parentNode.removeChild(script); -/******/ doneFns && doneFns.forEach((fn) => fn(event)); +/******/ doneFns && doneFns.forEach((fn) => (fn(event))); /******/ if(prev) return prev(event); /******/ } -/******/ ; /******/ var timeout = setTimeout(onScriptComplete.bind(null, undefined, { type: 'timeout', target: script }), 120000); /******/ script.onerror = onScriptComplete.bind(null, script.onerror); /******/ script.onload = onScriptComplete.bind(null, script.onload); @@ -180,12 +180,11 @@ require.ensure(["c"], function(require) { /******/ /******/ // object to store loaded and loading chunks /******/ // undefined = chunk not loaded, null = chunk preloaded/prefetched -/******/ // Promise = chunk loading, 0 = chunk loaded +/******/ // [resolve, reject, Promise] = chunk loading, 0 = chunk loaded /******/ var installedChunks = { /******/ 179: 0 /******/ }; /******/ -/******/ /******/ __webpack_require__.f.j = (chunkId, promises) => { /******/ // JSONP chunk loading for javascript /******/ var installedChunkData = __webpack_require__.o(installedChunks, chunkId) ? installedChunks[chunkId] : undefined; @@ -197,9 +196,7 @@ require.ensure(["c"], function(require) { /******/ } else { /******/ if(true) { // all chunks have JS /******/ // setup Promise in chunk cache -/******/ var promise = new Promise((resolve, reject) => { -/******/ installedChunkData = installedChunks[chunkId] = [resolve, reject]; -/******/ }); +/******/ var promise = new Promise((resolve, reject) => (installedChunkData = installedChunks[chunkId] = [resolve, reject])); /******/ promises.push(installedChunkData[2] = promise); /******/ /******/ // start chunk loading @@ -221,7 +218,7 @@ require.ensure(["c"], function(require) { /******/ } /******/ } /******/ }; -/******/ __webpack_require__.l(url, loadingEnded, "chunk-" + chunkId); +/******/ __webpack_require__.l(url, loadingEnded, "chunk-" + chunkId, chunkId); /******/ } else installedChunks[chunkId] = 0; /******/ } /******/ } @@ -235,39 +232,36 @@ require.ensure(["c"], function(require) { /******/ /******/ // no HMR manifest /******/ -/******/ // no deferred startup +/******/ // no on chunks loaded /******/ /******/ // install a JSONP callback for chunk loading /******/ var webpackJsonpCallback = (parentChunkLoadingFunction, data) => { /******/ var [chunkIds, moreModules, runtime] = data; /******/ // add "moreModules" to the modules object, /******/ // then flag all "chunkIds" as loaded and fire callback -/******/ var moduleId, chunkId, i = 0, resolves = []; +/******/ var moduleId, chunkId, i = 0; +/******/ if(chunkIds.some((id) => (installedChunks[id] !== 0))) { +/******/ for(moduleId in moreModules) { +/******/ if(__webpack_require__.o(moreModules, moduleId)) { +/******/ __webpack_require__.m[moduleId] = moreModules[moduleId]; +/******/ } +/******/ } +/******/ if(runtime) var result = runtime(__webpack_require__); +/******/ } +/******/ if(parentChunkLoadingFunction) parentChunkLoadingFunction(data); /******/ for(;i < chunkIds.length; i++) { /******/ chunkId = chunkIds[i]; /******/ if(__webpack_require__.o(installedChunks, chunkId) && installedChunks[chunkId]) { -/******/ resolves.push(installedChunks[chunkId][0]); +/******/ installedChunks[chunkId][0](); /******/ } /******/ installedChunks[chunkId] = 0; /******/ } -/******/ for(moduleId in moreModules) { -/******/ if(__webpack_require__.o(moreModules, moduleId)) { -/******/ __webpack_require__.m[moduleId] = moreModules[moduleId]; -/******/ } -/******/ } -/******/ if(runtime) runtime(__webpack_require__); -/******/ if(parentChunkLoadingFunction) parentChunkLoadingFunction(data); -/******/ while(resolves.length) { -/******/ resolves.shift()(); -/******/ } /******/ /******/ } /******/ /******/ var chunkLoadingGlobal = self["webpackChunk"] = self["webpackChunk"] || []; /******/ chunkLoadingGlobal.forEach(webpackJsonpCallback.bind(null, 0)); /******/ chunkLoadingGlobal.push = webpackJsonpCallback.bind(null, chunkLoadingGlobal.push.bind(chunkLoadingGlobal)); -/******/ -/******/ // no deferred startup /******/ })(); /******/ /************************************************************************/ @@ -276,6 +270,8 @@ require.ensure(["c"], function(require) { ``` js +var __webpack_exports__ = {}; +// This entry need to be wrapped in an IIFE because it need to be isolated against other modules in the chunk. (() => { /*!********************!*\ !*** ./example.js ***! @@ -285,9 +281,9 @@ require.ensure(["c"], function(require) { var a = __webpack_require__(/*! a */ 1); var b = __webpack_require__(/*! b */ 2); __webpack_require__.e(/*! require.ensure */ 796).then((function(require) { - __webpack_require__(/*! b */ 2).xyz(); + (__webpack_require__(/*! b */ 2).xyz)(); var d = __webpack_require__(/*! d */ 4); -}).bind(null, __webpack_require__)).catch(__webpack_require__.oe); +}).bind(null, __webpack_require__))['catch'](__webpack_require__.oe); })(); /******/ })() @@ -337,7 +333,7 @@ Minimized ## Unoptimized ``` -asset output.js 9.37 KiB [emitted] (name: main) +asset output.js 9.47 KiB [emitted] (name: main) asset 796.output.js 528 bytes [emitted] chunk (runtime: main) output.js (main) 161 bytes (javascript) 4.97 KiB (runtime) [entry] [rendered] > ./example.js main @@ -354,7 +350,7 @@ chunk (runtime: main) 796.output.js 22 bytes [rendered] ./node_modules/d.js 11 bytes [built] [code generated] [used exports unknown] cjs require d ./example.js 5:12-24 -webpack 5.11.1 compiled successfully +webpack 5.78.0 compiled successfully ``` ## Production mode @@ -377,5 +373,5 @@ chunk (runtime: main) 796.output.js 22 bytes [rendered] ./node_modules/d.js 11 bytes [built] [code generated] [used exports unknown] cjs require d ./example.js 5:12-24 -webpack 5.11.1 compiled successfully +webpack 5.78.0 compiled successfully ``` diff --git a/examples/coffee-script/README.md b/examples/coffee-script/README.md index 270fea3e54c..b3f899c6f0b 100644 --- a/examples/coffee-script/README.md +++ b/examples/coffee-script/README.md @@ -74,8 +74,9 @@ module.exports = 42; /******/ // The require function /******/ function __webpack_require__(moduleId) { /******/ // Check if module is in cache -/******/ if(__webpack_module_cache__[moduleId]) { -/******/ return __webpack_module_cache__[moduleId].exports; +/******/ var cachedModule = __webpack_module_cache__[moduleId]; +/******/ if (cachedModule !== undefined) { +/******/ return cachedModule.exports; /******/ } /******/ // Create a new module (and put it into the cache) /******/ var module = __webpack_module_cache__[moduleId] = { @@ -97,6 +98,8 @@ module.exports = 42; ``` js +var __webpack_exports__ = {}; +// This entry need to be wrapped in an IIFE because it need to be isolated against other modules in the chunk. (() => { /*!********************!*\ !*** ./example.js ***! @@ -115,25 +118,25 @@ console.log(__webpack_require__(/*! ./cup1 */ 1)); ## Unoptimized ``` -asset output.js 2.09 KiB [emitted] (name: main) +asset output.js 2.27 KiB [emitted] (name: main) chunk (runtime: main) output.js (main) 206 bytes [entry] [rendered] > ./example.js main dependent modules 175 bytes [dependent] 2 modules ./example.js 31 bytes [built] [code generated] [used exports unknown] entry ./example.js main -webpack 5.11.1 compiled successfully +webpack 5.78.0 compiled successfully ``` ## Production mode ``` -asset output.js 280 bytes [emitted] [minimized] (name: main) +asset output.js 294 bytes [emitted] [minimized] (name: main) chunk (runtime: main) output.js (main) 206 bytes [entry] [rendered] > ./example.js main dependent modules 175 bytes [dependent] 2 modules ./example.js 31 bytes [built] [code generated] [no exports used] entry ./example.js main -webpack 5.11.1 compiled successfully +webpack 5.78.0 compiled successfully ``` diff --git a/examples/coffee-script/webpack.config.js b/examples/coffee-script/webpack.config.js index 845f9f4c190..91c59cf45a7 100644 --- a/examples/coffee-script/webpack.config.js +++ b/examples/coffee-script/webpack.config.js @@ -1,5 +1,5 @@ module.exports = { - // mode: "development || "production", + // mode: "development" || "production", module: { rules: [ { diff --git a/examples/common-chunk-and-vendor-chunk/README.md b/examples/common-chunk-and-vendor-chunk/README.md index 8434b15379f..8346e48a620 100644 --- a/examples/common-chunk-and-vendor-chunk/README.md +++ b/examples/common-chunk-and-vendor-chunk/README.md @@ -194,8 +194,9 @@ module.exports = "utility1"; /******/ // The require function /******/ function __webpack_require__(moduleId) { /******/ // Check if module is in cache -/******/ if(__webpack_module_cache__[moduleId]) { -/******/ return __webpack_module_cache__[moduleId].exports; +/******/ var cachedModule = __webpack_module_cache__[moduleId]; +/******/ if (cachedModule !== undefined) { +/******/ return cachedModule.exports; /******/ } /******/ // Create a new module (and put it into the cache) /******/ var module = __webpack_module_cache__[moduleId] = { @@ -214,13 +215,42 @@ module.exports = "utility1"; /******/ // expose the modules object (__webpack_modules__) /******/ __webpack_require__.m = __webpack_modules__; /******/ -/******/ // the startup function -/******/ // It's empty as some runtime module handles the default behavior -/******/ __webpack_require__.x = x => {} /************************************************************************/ +/******/ /* webpack/runtime/chunk loaded */ +/******/ (() => { +/******/ var deferred = []; +/******/ __webpack_require__.O = (result, chunkIds, fn, priority) => { +/******/ if(chunkIds) { +/******/ priority = priority || 0; +/******/ for(var i = deferred.length; i > 0 && deferred[i - 1][2] > priority; i--) deferred[i] = deferred[i - 1]; +/******/ deferred[i] = [chunkIds, fn, priority]; +/******/ return; +/******/ } +/******/ var notFulfilled = Infinity; +/******/ for (var i = 0; i < deferred.length; i++) { +/******/ var [chunkIds, fn, priority] = deferred[i]; +/******/ var fulfilled = true; +/******/ for (var j = 0; j < chunkIds.length; j++) { +/******/ if ((priority & 1 === 0 || notFulfilled >= priority) && Object.keys(__webpack_require__.O).every((key) => (__webpack_require__.O[key](chunkIds[j])))) { +/******/ chunkIds.splice(j--, 1); +/******/ } else { +/******/ fulfilled = false; +/******/ if(priority < notFulfilled) notFulfilled = priority; +/******/ } +/******/ } +/******/ if(fulfilled) { +/******/ deferred.splice(i--, 1) +/******/ var r = fn(); +/******/ if (r !== undefined) result = r; +/******/ } +/******/ } +/******/ return result; +/******/ }; +/******/ })(); +/******/ /******/ /* webpack/runtime/hasOwnProperty shorthand */ /******/ (() => { -/******/ __webpack_require__.o = (obj, prop) => Object.prototype.hasOwnProperty.call(obj, prop) +/******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop)) /******/ })(); /******/ /******/ /* webpack/runtime/jsonp chunk loading */ @@ -229,14 +259,11 @@ module.exports = "utility1"; /******/ /******/ // object to store loaded and loading chunks /******/ // undefined = chunk not loaded, null = chunk preloaded/prefetched -/******/ // Promise = chunk loading, 0 = chunk loaded +/******/ // [resolve, reject, Promise] = chunk loading, 0 = chunk loaded /******/ var installedChunks = { /******/ "pageA": 0 /******/ }; /******/ -/******/ var deferredModules = [ -/******/ [0,"vendor","commons-utility2_js"] -/******/ ]; /******/ // no chunk on demand loading /******/ /******/ // no prefetching @@ -247,69 +274,36 @@ module.exports = "utility1"; /******/ /******/ // no HMR manifest /******/ -/******/ var checkDeferredModules = x => {}; +/******/ __webpack_require__.O.j = (chunkId) => (installedChunks[chunkId] === 0); /******/ /******/ // install a JSONP callback for chunk loading /******/ var webpackJsonpCallback = (parentChunkLoadingFunction, data) => { -/******/ var [chunkIds, moreModules, runtime, executeModules] = data; +/******/ var [chunkIds, moreModules, runtime] = data; /******/ // add "moreModules" to the modules object, /******/ // then flag all "chunkIds" as loaded and fire callback -/******/ var moduleId, chunkId, i = 0, resolves = []; +/******/ var moduleId, chunkId, i = 0; +/******/ if(chunkIds.some((id) => (installedChunks[id] !== 0))) { +/******/ for(moduleId in moreModules) { +/******/ if(__webpack_require__.o(moreModules, moduleId)) { +/******/ __webpack_require__.m[moduleId] = moreModules[moduleId]; +/******/ } +/******/ } +/******/ if(runtime) var result = runtime(__webpack_require__); +/******/ } +/******/ if(parentChunkLoadingFunction) parentChunkLoadingFunction(data); /******/ for(;i < chunkIds.length; i++) { /******/ chunkId = chunkIds[i]; /******/ if(__webpack_require__.o(installedChunks, chunkId) && installedChunks[chunkId]) { -/******/ resolves.push(installedChunks[chunkId][0]); +/******/ installedChunks[chunkId][0](); /******/ } /******/ installedChunks[chunkId] = 0; /******/ } -/******/ for(moduleId in moreModules) { -/******/ if(__webpack_require__.o(moreModules, moduleId)) { -/******/ __webpack_require__.m[moduleId] = moreModules[moduleId]; -/******/ } -/******/ } -/******/ if(runtime) runtime(__webpack_require__); -/******/ if(parentChunkLoadingFunction) parentChunkLoadingFunction(data); -/******/ while(resolves.length) { -/******/ resolves.shift()(); -/******/ } -/******/ -/******/ // add entry modules from loaded chunk to deferred list -/******/ if(executeModules) deferredModules.push.apply(deferredModules, executeModules); -/******/ -/******/ // run deferred modules when all chunks ready -/******/ return checkDeferredModules(); +/******/ return __webpack_require__.O(result); /******/ } /******/ /******/ var chunkLoadingGlobal = self["webpackChunk"] = self["webpackChunk"] || []; /******/ chunkLoadingGlobal.forEach(webpackJsonpCallback.bind(null, 0)); /******/ chunkLoadingGlobal.push = webpackJsonpCallback.bind(null, chunkLoadingGlobal.push.bind(chunkLoadingGlobal)); -/******/ -/******/ function checkDeferredModulesImpl() { -/******/ var result; -/******/ for(var i = 0; i < deferredModules.length; i++) { -/******/ var deferredModule = deferredModules[i]; -/******/ var fulfilled = true; -/******/ for(var j = 1; j < deferredModule.length; j++) { -/******/ var depId = deferredModule[j]; -/******/ if(installedChunks[depId] !== 0) fulfilled = false; -/******/ } -/******/ if(fulfilled) { -/******/ deferredModules.splice(i--, 1); -/******/ result = __webpack_require__(__webpack_require__.s = deferredModule[0]); -/******/ } -/******/ } -/******/ if(deferredModules.length === 0) { -/******/ __webpack_require__.x(); -/******/ __webpack_require__.x = x => {}; -/******/ } -/******/ return result; -/******/ } -/******/ var startup = __webpack_require__.x; -/******/ __webpack_require__.x = () => { -/******/ // reset startup function so it can be called again when more startup code is added -/******/ __webpack_require__.x = startup || (x => {}); -/******/ return (checkDeferredModules = checkDeferredModulesImpl)(); -/******/ }; /******/ })(); /******/ /************************************************************************/ @@ -318,8 +312,13 @@ module.exports = "utility1"; ``` js -/******/ // run startup -/******/ return __webpack_require__.x(); +/******/ +/******/ // startup +/******/ // Load entry module and return exports +/******/ // This entry module depends on other loaded chunks and execution need to be delayed +/******/ var __webpack_exports__ = __webpack_require__.O(undefined, ["vendor","commons-utility2_js"], () => (__webpack_require__(0))) +/******/ __webpack_exports__ = __webpack_require__.O(__webpack_exports__); +/******/ /******/ })() ; ``` @@ -361,8 +360,9 @@ module.exports = "pageB"; /******/ // The require function /******/ function __webpack_require__(moduleId) { /******/ // Check if module is in cache -/******/ if(__webpack_module_cache__[moduleId]) { -/******/ return __webpack_module_cache__[moduleId].exports; +/******/ var cachedModule = __webpack_module_cache__[moduleId]; +/******/ if (cachedModule !== undefined) { +/******/ return cachedModule.exports; /******/ } /******/ // Create a new module (and put it into the cache) /******/ var module = __webpack_module_cache__[moduleId] = { @@ -381,13 +381,42 @@ module.exports = "pageB"; /******/ // expose the modules object (__webpack_modules__) /******/ __webpack_require__.m = __webpack_modules__; /******/ -/******/ // the startup function -/******/ // It's empty as some runtime module handles the default behavior -/******/ __webpack_require__.x = x => {} /************************************************************************/ +/******/ /* webpack/runtime/chunk loaded */ +/******/ (() => { +/******/ var deferred = []; +/******/ __webpack_require__.O = (result, chunkIds, fn, priority) => { +/******/ if(chunkIds) { +/******/ priority = priority || 0; +/******/ for(var i = deferred.length; i > 0 && deferred[i - 1][2] > priority; i--) deferred[i] = deferred[i - 1]; +/******/ deferred[i] = [chunkIds, fn, priority]; +/******/ return; +/******/ } +/******/ var notFulfilled = Infinity; +/******/ for (var i = 0; i < deferred.length; i++) { +/******/ var [chunkIds, fn, priority] = deferred[i]; +/******/ var fulfilled = true; +/******/ for (var j = 0; j < chunkIds.length; j++) { +/******/ if ((priority & 1 === 0 || notFulfilled >= priority) && Object.keys(__webpack_require__.O).every((key) => (__webpack_require__.O[key](chunkIds[j])))) { +/******/ chunkIds.splice(j--, 1); +/******/ } else { +/******/ fulfilled = false; +/******/ if(priority < notFulfilled) notFulfilled = priority; +/******/ } +/******/ } +/******/ if(fulfilled) { +/******/ deferred.splice(i--, 1) +/******/ var r = fn(); +/******/ if (r !== undefined) result = r; +/******/ } +/******/ } +/******/ return result; +/******/ }; +/******/ })(); +/******/ /******/ /* webpack/runtime/hasOwnProperty shorthand */ /******/ (() => { -/******/ __webpack_require__.o = (obj, prop) => Object.prototype.hasOwnProperty.call(obj, prop) +/******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop)) /******/ })(); /******/ /******/ /* webpack/runtime/jsonp chunk loading */ @@ -396,14 +425,11 @@ module.exports = "pageB"; /******/ /******/ // object to store loaded and loading chunks /******/ // undefined = chunk not loaded, null = chunk preloaded/prefetched -/******/ // Promise = chunk loading, 0 = chunk loaded +/******/ // [resolve, reject, Promise] = chunk loading, 0 = chunk loaded /******/ var installedChunks = { /******/ "pageB": 0 /******/ }; /******/ -/******/ var deferredModules = [ -/******/ [4,"vendor","commons-utility2_js","commons-utility3_js"] -/******/ ]; /******/ // no chunk on demand loading /******/ /******/ // no prefetching @@ -414,69 +440,36 @@ module.exports = "pageB"; /******/ /******/ // no HMR manifest /******/ -/******/ var checkDeferredModules = x => {}; +/******/ __webpack_require__.O.j = (chunkId) => (installedChunks[chunkId] === 0); /******/ /******/ // install a JSONP callback for chunk loading /******/ var webpackJsonpCallback = (parentChunkLoadingFunction, data) => { -/******/ var [chunkIds, moreModules, runtime, executeModules] = data; +/******/ var [chunkIds, moreModules, runtime] = data; /******/ // add "moreModules" to the modules object, /******/ // then flag all "chunkIds" as loaded and fire callback -/******/ var moduleId, chunkId, i = 0, resolves = []; +/******/ var moduleId, chunkId, i = 0; +/******/ if(chunkIds.some((id) => (installedChunks[id] !== 0))) { +/******/ for(moduleId in moreModules) { +/******/ if(__webpack_require__.o(moreModules, moduleId)) { +/******/ __webpack_require__.m[moduleId] = moreModules[moduleId]; +/******/ } +/******/ } +/******/ if(runtime) var result = runtime(__webpack_require__); +/******/ } +/******/ if(parentChunkLoadingFunction) parentChunkLoadingFunction(data); /******/ for(;i < chunkIds.length; i++) { /******/ chunkId = chunkIds[i]; /******/ if(__webpack_require__.o(installedChunks, chunkId) && installedChunks[chunkId]) { -/******/ resolves.push(installedChunks[chunkId][0]); +/******/ installedChunks[chunkId][0](); /******/ } /******/ installedChunks[chunkId] = 0; /******/ } -/******/ for(moduleId in moreModules) { -/******/ if(__webpack_require__.o(moreModules, moduleId)) { -/******/ __webpack_require__.m[moduleId] = moreModules[moduleId]; -/******/ } -/******/ } -/******/ if(runtime) runtime(__webpack_require__); -/******/ if(parentChunkLoadingFunction) parentChunkLoadingFunction(data); -/******/ while(resolves.length) { -/******/ resolves.shift()(); -/******/ } -/******/ -/******/ // add entry modules from loaded chunk to deferred list -/******/ if(executeModules) deferredModules.push.apply(deferredModules, executeModules); -/******/ -/******/ // run deferred modules when all chunks ready -/******/ return checkDeferredModules(); +/******/ return __webpack_require__.O(result); /******/ } /******/ /******/ var chunkLoadingGlobal = self["webpackChunk"] = self["webpackChunk"] || []; /******/ chunkLoadingGlobal.forEach(webpackJsonpCallback.bind(null, 0)); /******/ chunkLoadingGlobal.push = webpackJsonpCallback.bind(null, chunkLoadingGlobal.push.bind(chunkLoadingGlobal)); -/******/ -/******/ function checkDeferredModulesImpl() { -/******/ var result; -/******/ for(var i = 0; i < deferredModules.length; i++) { -/******/ var deferredModule = deferredModules[i]; -/******/ var fulfilled = true; -/******/ for(var j = 1; j < deferredModule.length; j++) { -/******/ var depId = deferredModule[j]; -/******/ if(installedChunks[depId] !== 0) fulfilled = false; -/******/ } -/******/ if(fulfilled) { -/******/ deferredModules.splice(i--, 1); -/******/ result = __webpack_require__(__webpack_require__.s = deferredModule[0]); -/******/ } -/******/ } -/******/ if(deferredModules.length === 0) { -/******/ __webpack_require__.x(); -/******/ __webpack_require__.x = x => {}; -/******/ } -/******/ return result; -/******/ } -/******/ var startup = __webpack_require__.x; -/******/ __webpack_require__.x = () => { -/******/ // reset startup function so it can be called again when more startup code is added -/******/ __webpack_require__.x = startup || (x => {}); -/******/ return (checkDeferredModules = checkDeferredModulesImpl)(); -/******/ }; /******/ })(); /******/ /************************************************************************/ @@ -485,8 +478,13 @@ module.exports = "pageB"; ``` js -/******/ // run startup -/******/ return __webpack_require__.x(); +/******/ +/******/ // startup +/******/ // Load entry module and return exports +/******/ // This entry module depends on other loaded chunks and execution need to be delayed +/******/ var __webpack_exports__ = __webpack_require__.O(undefined, ["vendor","commons-utility2_js","commons-utility3_js"], () => (__webpack_require__(4))) +/******/ __webpack_exports__ = __webpack_require__.O(__webpack_exports__); +/******/ /******/ })() ; ``` @@ -526,8 +524,9 @@ module.exports = "pageC"; /******/ // The require function /******/ function __webpack_require__(moduleId) { /******/ // Check if module is in cache -/******/ if(__webpack_module_cache__[moduleId]) { -/******/ return __webpack_module_cache__[moduleId].exports; +/******/ var cachedModule = __webpack_module_cache__[moduleId]; +/******/ if (cachedModule !== undefined) { +/******/ return cachedModule.exports; /******/ } /******/ // Create a new module (and put it into the cache) /******/ var module = __webpack_module_cache__[moduleId] = { @@ -546,13 +545,42 @@ module.exports = "pageC"; /******/ // expose the modules object (__webpack_modules__) /******/ __webpack_require__.m = __webpack_modules__; /******/ -/******/ // the startup function -/******/ // It's empty as some runtime module handles the default behavior -/******/ __webpack_require__.x = x => {} /************************************************************************/ +/******/ /* webpack/runtime/chunk loaded */ +/******/ (() => { +/******/ var deferred = []; +/******/ __webpack_require__.O = (result, chunkIds, fn, priority) => { +/******/ if(chunkIds) { +/******/ priority = priority || 0; +/******/ for(var i = deferred.length; i > 0 && deferred[i - 1][2] > priority; i--) deferred[i] = deferred[i - 1]; +/******/ deferred[i] = [chunkIds, fn, priority]; +/******/ return; +/******/ } +/******/ var notFulfilled = Infinity; +/******/ for (var i = 0; i < deferred.length; i++) { +/******/ var [chunkIds, fn, priority] = deferred[i]; +/******/ var fulfilled = true; +/******/ for (var j = 0; j < chunkIds.length; j++) { +/******/ if ((priority & 1 === 0 || notFulfilled >= priority) && Object.keys(__webpack_require__.O).every((key) => (__webpack_require__.O[key](chunkIds[j])))) { +/******/ chunkIds.splice(j--, 1); +/******/ } else { +/******/ fulfilled = false; +/******/ if(priority < notFulfilled) notFulfilled = priority; +/******/ } +/******/ } +/******/ if(fulfilled) { +/******/ deferred.splice(i--, 1) +/******/ var r = fn(); +/******/ if (r !== undefined) result = r; +/******/ } +/******/ } +/******/ return result; +/******/ }; +/******/ })(); +/******/ /******/ /* webpack/runtime/hasOwnProperty shorthand */ /******/ (() => { -/******/ __webpack_require__.o = (obj, prop) => Object.prototype.hasOwnProperty.call(obj, prop) +/******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop)) /******/ })(); /******/ /******/ /* webpack/runtime/jsonp chunk loading */ @@ -561,14 +589,11 @@ module.exports = "pageC"; /******/ /******/ // object to store loaded and loading chunks /******/ // undefined = chunk not loaded, null = chunk preloaded/prefetched -/******/ // Promise = chunk loading, 0 = chunk loaded +/******/ // [resolve, reject, Promise] = chunk loading, 0 = chunk loaded /******/ var installedChunks = { /******/ "pageC": 0 /******/ }; /******/ -/******/ var deferredModules = [ -/******/ [7,"commons-utility2_js","commons-utility3_js"] -/******/ ]; /******/ // no chunk on demand loading /******/ /******/ // no prefetching @@ -579,69 +604,36 @@ module.exports = "pageC"; /******/ /******/ // no HMR manifest /******/ -/******/ var checkDeferredModules = x => {}; +/******/ __webpack_require__.O.j = (chunkId) => (installedChunks[chunkId] === 0); /******/ /******/ // install a JSONP callback for chunk loading /******/ var webpackJsonpCallback = (parentChunkLoadingFunction, data) => { -/******/ var [chunkIds, moreModules, runtime, executeModules] = data; +/******/ var [chunkIds, moreModules, runtime] = data; /******/ // add "moreModules" to the modules object, /******/ // then flag all "chunkIds" as loaded and fire callback -/******/ var moduleId, chunkId, i = 0, resolves = []; +/******/ var moduleId, chunkId, i = 0; +/******/ if(chunkIds.some((id) => (installedChunks[id] !== 0))) { +/******/ for(moduleId in moreModules) { +/******/ if(__webpack_require__.o(moreModules, moduleId)) { +/******/ __webpack_require__.m[moduleId] = moreModules[moduleId]; +/******/ } +/******/ } +/******/ if(runtime) var result = runtime(__webpack_require__); +/******/ } +/******/ if(parentChunkLoadingFunction) parentChunkLoadingFunction(data); /******/ for(;i < chunkIds.length; i++) { /******/ chunkId = chunkIds[i]; /******/ if(__webpack_require__.o(installedChunks, chunkId) && installedChunks[chunkId]) { -/******/ resolves.push(installedChunks[chunkId][0]); +/******/ installedChunks[chunkId][0](); /******/ } /******/ installedChunks[chunkId] = 0; /******/ } -/******/ for(moduleId in moreModules) { -/******/ if(__webpack_require__.o(moreModules, moduleId)) { -/******/ __webpack_require__.m[moduleId] = moreModules[moduleId]; -/******/ } -/******/ } -/******/ if(runtime) runtime(__webpack_require__); -/******/ if(parentChunkLoadingFunction) parentChunkLoadingFunction(data); -/******/ while(resolves.length) { -/******/ resolves.shift()(); -/******/ } -/******/ -/******/ // add entry modules from loaded chunk to deferred list -/******/ if(executeModules) deferredModules.push.apply(deferredModules, executeModules); -/******/ -/******/ // run deferred modules when all chunks ready -/******/ return checkDeferredModules(); +/******/ return __webpack_require__.O(result); /******/ } /******/ /******/ var chunkLoadingGlobal = self["webpackChunk"] = self["webpackChunk"] || []; /******/ chunkLoadingGlobal.forEach(webpackJsonpCallback.bind(null, 0)); /******/ chunkLoadingGlobal.push = webpackJsonpCallback.bind(null, chunkLoadingGlobal.push.bind(chunkLoadingGlobal)); -/******/ -/******/ function checkDeferredModulesImpl() { -/******/ var result; -/******/ for(var i = 0; i < deferredModules.length; i++) { -/******/ var deferredModule = deferredModules[i]; -/******/ var fulfilled = true; -/******/ for(var j = 1; j < deferredModule.length; j++) { -/******/ var depId = deferredModule[j]; -/******/ if(installedChunks[depId] !== 0) fulfilled = false; -/******/ } -/******/ if(fulfilled) { -/******/ deferredModules.splice(i--, 1); -/******/ result = __webpack_require__(__webpack_require__.s = deferredModule[0]); -/******/ } -/******/ } -/******/ if(deferredModules.length === 0) { -/******/ __webpack_require__.x(); -/******/ __webpack_require__.x = x => {}; -/******/ } -/******/ return result; -/******/ } -/******/ var startup = __webpack_require__.x; -/******/ __webpack_require__.x = () => { -/******/ // reset startup function so it can be called again when more startup code is added -/******/ __webpack_require__.x = startup || (x => {}); -/******/ return (checkDeferredModules = checkDeferredModulesImpl)(); -/******/ }; /******/ })(); /******/ /************************************************************************/ @@ -650,8 +642,13 @@ module.exports = "pageC"; ``` js -/******/ // run startup -/******/ return __webpack_require__.x(); +/******/ +/******/ // startup +/******/ // Load entry module and return exports +/******/ // This entry module depends on other loaded chunks and execution need to be delayed +/******/ var __webpack_exports__ = __webpack_require__.O(undefined, ["commons-utility2_js","commons-utility3_js"], () => (__webpack_require__(7))) +/******/ __webpack_exports__ = __webpack_require__.O(__webpack_exports__); +/******/ /******/ })() ; ``` @@ -664,13 +661,13 @@ module.exports = "pageC"; assets by chunk 768 bytes (id hint: commons) asset commons-utility2_js.js 384 bytes [emitted] (id hint: commons) asset commons-utility3_js.js 384 bytes [emitted] (id hint: commons) -asset pageA.js 6 KiB [emitted] (name: pageA) -asset pageB.js 5.73 KiB [emitted] (name: pageB) -asset pageC.js 5.67 KiB [emitted] (name: pageC) +asset pageA.js 6.07 KiB [emitted] (name: pageA) +asset pageB.js 5.8 KiB [emitted] (name: pageB) +asset pageC.js 5.74 KiB [emitted] (name: pageC) asset vendor.js 737 bytes [emitted] (name: vendor) (id hint: vendor) -Entrypoint pageA 7.09 KiB = vendor.js 737 bytes commons-utility2_js.js 384 bytes pageA.js 6 KiB -Entrypoint pageB 7.2 KiB = vendor.js 737 bytes commons-utility2_js.js 384 bytes commons-utility3_js.js 384 bytes pageB.js 5.73 KiB -Entrypoint pageC 6.42 KiB = commons-utility2_js.js 384 bytes commons-utility3_js.js 384 bytes pageC.js 5.67 KiB +Entrypoint pageA 7.17 KiB = vendor.js 737 bytes commons-utility2_js.js 384 bytes pageA.js 6.07 KiB +Entrypoint pageB 7.27 KiB = vendor.js 737 bytes commons-utility2_js.js 384 bytes commons-utility3_js.js 384 bytes pageB.js 5.8 KiB +Entrypoint pageC 6.49 KiB = commons-utility2_js.js 384 bytes commons-utility3_js.js 384 bytes pageC.js 5.74 KiB chunk (runtime: pageA, pageB, pageC) commons-utility2_js.js (id hint: commons) 28 bytes [initial] [rendered] split chunk (cache group: commons) > ./pageA pageA > ./pageB pageB @@ -689,24 +686,24 @@ chunk (runtime: pageB, pageC) commons-utility3_js.js (id hint: commons) 28 bytes cjs require ./utility3 ./pageB.js 3:15-36 cjs require ./utility3 ./pageC.js 2:15-36 cjs self exports reference ./utility3.js 1:0-14 -chunk (runtime: pageA) pageA.js (pageA) 165 bytes (javascript) 2.6 KiB (runtime) [entry] [rendered] +chunk (runtime: pageA) pageA.js (pageA) 165 bytes (javascript) 2.46 KiB (runtime) [entry] [rendered] > ./pageA pageA - runtime modules 2.6 KiB 2 modules + runtime modules 2.46 KiB 3 modules dependent modules 28 bytes [dependent] 1 module ./pageA.js 137 bytes [built] [code generated] [used exports unknown] cjs self exports reference ./pageA.js 5:0-14 entry ./pageA pageA -chunk (runtime: pageB) pageB.js (pageB) 137 bytes (javascript) 2.62 KiB (runtime) [entry] [rendered] +chunk (runtime: pageB) pageB.js (pageB) 137 bytes (javascript) 2.46 KiB (runtime) [entry] [rendered] > ./pageB pageB - runtime modules 2.62 KiB 2 modules + runtime modules 2.46 KiB 3 modules ./pageB.js 137 bytes [built] [code generated] [used exports unknown] cjs self exports reference ./pageB.js 5:0-14 entry ./pageB pageB -chunk (runtime: pageC) pageC.js (pageC) 102 bytes (javascript) 2.61 KiB (runtime) [entry] [rendered] +chunk (runtime: pageC) pageC.js (pageC) 102 bytes (javascript) 2.46 KiB (runtime) [entry] [rendered] > ./pageC pageC - runtime modules 2.61 KiB 2 modules + runtime modules 2.46 KiB 3 modules ./pageC.js 102 bytes [built] [code generated] [used exports unknown] cjs self exports reference ./pageC.js 4:0-14 @@ -722,7 +719,7 @@ chunk (runtime: pageA, pageB) vendor.js (vendor) (id hint: vendor) 54 bytes [ini [used exports unknown] cjs self exports reference ./node_modules/vendor2.js 1:0-14 cjs require vendor2 ./pageB.js 1:14-32 -webpack 5.11.1 compiled successfully +webpack 5.78.0 compiled successfully ``` ## Production mode @@ -731,13 +728,13 @@ webpack 5.11.1 compiled successfully assets by chunk 212 bytes (id hint: commons) asset commons-utility2_js.js 106 bytes [emitted] [minimized] (id hint: commons) asset commons-utility3_js.js 106 bytes [emitted] [minimized] (id hint: commons) -asset pageA.js 907 bytes [emitted] [minimized] (name: pageA) -asset pageB.js 899 bytes [emitted] [minimized] (name: pageB) -asset pageC.js 883 bytes [emitted] [minimized] (name: pageC) +asset pageA.js 1 KiB [emitted] [minimized] (name: pageA) +asset pageB.js 1020 bytes [emitted] [minimized] (name: pageB) +asset pageC.js 1010 bytes [emitted] [minimized] (name: pageC) asset vendor.js 121 bytes [emitted] [minimized] (name: vendor) (id hint: vendor) -Entrypoint pageA 1.11 KiB = vendor.js 121 bytes commons-utility2_js.js 106 bytes pageA.js 907 bytes -Entrypoint pageB 1.2 KiB = vendor.js 121 bytes commons-utility2_js.js 106 bytes commons-utility3_js.js 106 bytes pageB.js 899 bytes -Entrypoint pageC 1.07 KiB = commons-utility2_js.js 106 bytes commons-utility3_js.js 106 bytes pageC.js 883 bytes +Entrypoint pageA 1.23 KiB = vendor.js 121 bytes commons-utility2_js.js 106 bytes pageA.js 1 KiB +Entrypoint pageB 1.32 KiB = vendor.js 121 bytes commons-utility2_js.js 106 bytes commons-utility3_js.js 106 bytes pageB.js 1020 bytes +Entrypoint pageC 1.19 KiB = commons-utility2_js.js 106 bytes commons-utility3_js.js 106 bytes pageC.js 1010 bytes chunk (runtime: pageA, pageB, pageC) commons-utility2_js.js (id hint: commons) 28 bytes [initial] [rendered] split chunk (cache group: commons) > ./pageA pageA > ./pageB pageB @@ -756,24 +753,24 @@ chunk (runtime: pageB, pageC) commons-utility3_js.js (id hint: commons) 28 bytes cjs require ./utility3 ./pageB.js 3:15-36 cjs require ./utility3 ./pageC.js 2:15-36 cjs self exports reference ./utility3.js 1:0-14 -chunk (runtime: pageA) pageA.js (pageA) 165 bytes (javascript) 2.6 KiB (runtime) [entry] [rendered] +chunk (runtime: pageA) pageA.js (pageA) 165 bytes (javascript) 2.46 KiB (runtime) [entry] [rendered] > ./pageA pageA - runtime modules 2.6 KiB 2 modules + runtime modules 2.46 KiB 3 modules dependent modules 28 bytes [dependent] 1 module ./pageA.js 137 bytes [built] [code generated] [used exports unknown] cjs self exports reference ./pageA.js 5:0-14 entry ./pageA pageA -chunk (runtime: pageB) pageB.js (pageB) 137 bytes (javascript) 2.63 KiB (runtime) [entry] [rendered] +chunk (runtime: pageB) pageB.js (pageB) 137 bytes (javascript) 2.46 KiB (runtime) [entry] [rendered] > ./pageB pageB - runtime modules 2.63 KiB 2 modules + runtime modules 2.46 KiB 3 modules ./pageB.js 137 bytes [built] [code generated] [used exports unknown] cjs self exports reference ./pageB.js 5:0-14 entry ./pageB pageB -chunk (runtime: pageC) pageC.js (pageC) 102 bytes (javascript) 2.62 KiB (runtime) [entry] [rendered] +chunk (runtime: pageC) pageC.js (pageC) 102 bytes (javascript) 2.46 KiB (runtime) [entry] [rendered] > ./pageC pageC - runtime modules 2.62 KiB 2 modules + runtime modules 2.46 KiB 3 modules ./pageC.js 102 bytes [built] [code generated] [used exports unknown] cjs self exports reference ./pageC.js 4:0-14 @@ -789,5 +786,5 @@ chunk (runtime: pageA, pageB) vendor.js (vendor) (id hint: vendor) 54 bytes [ini [used exports unknown] cjs self exports reference ./node_modules/vendor2.js 1:0-14 cjs require vendor2 ./pageB.js 1:14-32 -webpack 5.11.1 compiled successfully +webpack 5.78.0 compiled successfully ``` diff --git a/examples/common-chunk-and-vendor-chunk/webpack.config.js b/examples/common-chunk-and-vendor-chunk/webpack.config.js index 98d8fdec608..e28ea6b8f53 100644 --- a/examples/common-chunk-and-vendor-chunk/webpack.config.js +++ b/examples/common-chunk-and-vendor-chunk/webpack.config.js @@ -1,4 +1,4 @@ -var path = require("path"); +const path = require("path"); module.exports = { // mode: "development" || "production", diff --git a/examples/common-chunk-grandchildren/README.md b/examples/common-chunk-grandchildren/README.md index b4491f7dfcd..b2827e37830 100644 --- a/examples/common-chunk-grandchildren/README.md +++ b/examples/common-chunk-grandchildren/README.md @@ -86,7 +86,7 @@ module.exports = function() { const path = require("path"); module.exports = { - // mode: "development || "production", + // mode: "development" || "production", entry: { main: ["./example.js"] }, @@ -120,8 +120,9 @@ module.exports = { /******/ // The require function /******/ function __webpack_require__(moduleId) { /******/ // Check if module is in cache -/******/ if(__webpack_module_cache__[moduleId]) { -/******/ return __webpack_module_cache__[moduleId].exports; +/******/ var cachedModule = __webpack_module_cache__[moduleId]; +/******/ if (cachedModule !== undefined) { +/******/ return cachedModule.exports; /******/ } /******/ // Create a new module (and put it into the cache) /******/ var module = __webpack_module_cache__[moduleId] = { @@ -165,7 +166,7 @@ module.exports = { /******/ /******/ /* webpack/runtime/hasOwnProperty shorthand */ /******/ (() => { -/******/ __webpack_require__.o = (obj, prop) => Object.prototype.hasOwnProperty.call(obj, prop) +/******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop)) /******/ })(); /******/ /******/ /* webpack/runtime/load script */ @@ -173,7 +174,7 @@ module.exports = { /******/ var inProgress = {}; /******/ // data-webpack is not used as build has no uniqueName /******/ // loadScript function to load a script via script tag -/******/ __webpack_require__.l = (url, done, key) => { +/******/ __webpack_require__.l = (url, done, key, chunkId) => { /******/ if(inProgress[url]) { inProgress[url].push(done); return; } /******/ var script, needAttach; /******/ if(key !== undefined) { @@ -203,10 +204,9 @@ module.exports = { /******/ var doneFns = inProgress[url]; /******/ delete inProgress[url]; /******/ script.parentNode && script.parentNode.removeChild(script); -/******/ doneFns && doneFns.forEach((fn) => fn(event)); +/******/ doneFns && doneFns.forEach((fn) => (fn(event))); /******/ if(prev) return prev(event); /******/ } -/******/ ; /******/ var timeout = setTimeout(onScriptComplete.bind(null, undefined, { type: 'timeout', target: script }), 120000); /******/ script.onerror = onScriptComplete.bind(null, script.onerror); /******/ script.onload = onScriptComplete.bind(null, script.onload); @@ -225,12 +225,11 @@ module.exports = { /******/ /******/ // object to store loaded and loading chunks /******/ // undefined = chunk not loaded, null = chunk preloaded/prefetched -/******/ // Promise = chunk loading, 0 = chunk loaded +/******/ // [resolve, reject, Promise] = chunk loading, 0 = chunk loaded /******/ var installedChunks = { /******/ 179: 0 /******/ }; /******/ -/******/ /******/ __webpack_require__.f.j = (chunkId, promises) => { /******/ // JSONP chunk loading for javascript /******/ var installedChunkData = __webpack_require__.o(installedChunks, chunkId) ? installedChunks[chunkId] : undefined; @@ -242,9 +241,7 @@ module.exports = { /******/ } else { /******/ if(true) { // all chunks have JS /******/ // setup Promise in chunk cache -/******/ var promise = new Promise((resolve, reject) => { -/******/ installedChunkData = installedChunks[chunkId] = [resolve, reject]; -/******/ }); +/******/ var promise = new Promise((resolve, reject) => (installedChunkData = installedChunks[chunkId] = [resolve, reject])); /******/ promises.push(installedChunkData[2] = promise); /******/ /******/ // start chunk loading @@ -266,7 +263,7 @@ module.exports = { /******/ } /******/ } /******/ }; -/******/ __webpack_require__.l(url, loadingEnded, "chunk-" + chunkId); +/******/ __webpack_require__.l(url, loadingEnded, "chunk-" + chunkId, chunkId); /******/ } else installedChunks[chunkId] = 0; /******/ } /******/ } @@ -280,39 +277,36 @@ module.exports = { /******/ /******/ // no HMR manifest /******/ -/******/ // no deferred startup +/******/ // no on chunks loaded /******/ /******/ // install a JSONP callback for chunk loading /******/ var webpackJsonpCallback = (parentChunkLoadingFunction, data) => { /******/ var [chunkIds, moreModules, runtime] = data; /******/ // add "moreModules" to the modules object, /******/ // then flag all "chunkIds" as loaded and fire callback -/******/ var moduleId, chunkId, i = 0, resolves = []; +/******/ var moduleId, chunkId, i = 0; +/******/ if(chunkIds.some((id) => (installedChunks[id] !== 0))) { +/******/ for(moduleId in moreModules) { +/******/ if(__webpack_require__.o(moreModules, moduleId)) { +/******/ __webpack_require__.m[moduleId] = moreModules[moduleId]; +/******/ } +/******/ } +/******/ if(runtime) var result = runtime(__webpack_require__); +/******/ } +/******/ if(parentChunkLoadingFunction) parentChunkLoadingFunction(data); /******/ for(;i < chunkIds.length; i++) { /******/ chunkId = chunkIds[i]; /******/ if(__webpack_require__.o(installedChunks, chunkId) && installedChunks[chunkId]) { -/******/ resolves.push(installedChunks[chunkId][0]); +/******/ installedChunks[chunkId][0](); /******/ } /******/ installedChunks[chunkId] = 0; /******/ } -/******/ for(moduleId in moreModules) { -/******/ if(__webpack_require__.o(moreModules, moduleId)) { -/******/ __webpack_require__.m[moduleId] = moreModules[moduleId]; -/******/ } -/******/ } -/******/ if(runtime) runtime(__webpack_require__); -/******/ if(parentChunkLoadingFunction) parentChunkLoadingFunction(data); -/******/ while(resolves.length) { -/******/ resolves.shift()(); -/******/ } /******/ /******/ } /******/ /******/ var chunkLoadingGlobal = self["webpackChunk"] = self["webpackChunk"] || []; /******/ chunkLoadingGlobal.forEach(webpackJsonpCallback.bind(null, 0)); /******/ chunkLoadingGlobal.push = webpackJsonpCallback.bind(null, chunkLoadingGlobal.push.bind(chunkLoadingGlobal)); -/******/ -/******/ // no deferred startup /******/ })(); /******/ /************************************************************************/ @@ -321,6 +315,7 @@ module.exports = { ``` js +var __webpack_exports__ = {}; /*!********************!*\ !*** ./example.js ***! \********************/ @@ -331,11 +326,11 @@ var main = function() { Promise.all(/*! require.ensure */[__webpack_require__.e(421), __webpack_require__.e(366)]).then((() => { const page = __webpack_require__(/*! ./pageA */ 1); page(); - }).bind(null, __webpack_require__)).catch(__webpack_require__.oe); + }).bind(null, __webpack_require__))['catch'](__webpack_require__.oe); __webpack_require__.e(/*! require.ensure */ 588).then((() => { const page = __webpack_require__(/*! ./pageB */ 3); page(); - }).bind(null, __webpack_require__)).catch(__webpack_require__.oe); + }).bind(null, __webpack_require__))['catch'](__webpack_require__.oe); }; main(); @@ -389,7 +384,7 @@ module.exports = function() { Promise.all(/*! require.ensure */[__webpack_require__.e(421), __webpack_require__.e(145)]).then((()=>{ const page = __webpack_require__(/*! ./pageC */ 4); page(); - }).bind(null, __webpack_require__)).catch(__webpack_require__.oe); + }).bind(null, __webpack_require__))['catch'](__webpack_require__.oe); }; @@ -454,8 +449,8 @@ module.exports = function() { ## Unoptimized ``` -asset output.js 9.1 KiB [emitted] (name: main) -asset 588.output.js 736 bytes [emitted] +asset output.js 9.09 KiB [emitted] (name: main) +asset 588.output.js 739 bytes [emitted] asset 366.output.js 558 bytes [emitted] asset 145.output.js 552 bytes [emitted] asset 421.output.js 434 bytes [emitted] @@ -491,7 +486,7 @@ chunk (runtime: main) 588.output.js 133 bytes [rendered] [used exports unknown] cjs require ./pageB ./example.js 8:15-33 cjs self exports reference ./pageB.js 1:0-14 -webpack 5.11.1 compiled successfully +webpack 5.78.0 compiled successfully ``` ## Production mode @@ -534,5 +529,5 @@ chunk (runtime: main) 588.output.js 133 bytes [rendered] [used exports unknown] cjs require ./pageB ./example.js 8:15-33 cjs self exports reference ./pageB.js 1:0-14 -webpack 5.11.1 compiled successfully +webpack 5.78.0 compiled successfully ``` diff --git a/examples/common-chunk-grandchildren/webpack.config.js b/examples/common-chunk-grandchildren/webpack.config.js index e8c14e818d9..ea9fdf2323e 100644 --- a/examples/common-chunk-grandchildren/webpack.config.js +++ b/examples/common-chunk-grandchildren/webpack.config.js @@ -2,7 +2,7 @@ const path = require("path"); module.exports = { - // mode: "development || "production", + // mode: "development" || "production", entry: { main: ["./example.js"] }, diff --git a/examples/commonjs/README.md b/examples/commonjs/README.md index 06efad94f70..c5074df2659 100644 --- a/examples/commonjs/README.md +++ b/examples/commonjs/README.md @@ -51,7 +51,7 @@ exports.add = function() { /*! runtime requirements: __webpack_require__, __webpack_exports__ */ /***/ ((__unused_webpack_module, exports, __webpack_require__) => { -const add = __webpack_require__(/*! ./math */ 2).add; +const add = (__webpack_require__(/*! ./math */ 2).add); exports.increment = function(val) { return add(val, 1); }; @@ -90,8 +90,9 @@ exports.add = function() { /******/ // The require function /******/ function __webpack_require__(moduleId) { /******/ // Check if module is in cache -/******/ if(__webpack_module_cache__[moduleId]) { -/******/ return __webpack_module_cache__[moduleId].exports; +/******/ var cachedModule = __webpack_module_cache__[moduleId]; +/******/ if (cachedModule !== undefined) { +/******/ return cachedModule.exports; /******/ } /******/ // Create a new module (and put it into the cache) /******/ var module = __webpack_module_cache__[moduleId] = { @@ -113,13 +114,15 @@ exports.add = function() { ``` js +var __webpack_exports__ = {}; +// This entry need to be wrapped in an IIFE because it need to be isolated against other modules in the chunk. (() => { /*!********************!*\ !*** ./example.js ***! \********************/ /*! unknown exports (runtime-defined) */ /*! runtime requirements: __webpack_require__ */ -const inc = __webpack_require__(/*! ./increment */ 1).increment; +const inc = (__webpack_require__(/*! ./increment */ 1).increment); const a = 1; inc(a); // 2 @@ -134,25 +137,25 @@ inc(a); // 2 ## Unoptimized ``` -asset output.js 2.34 KiB [emitted] (name: main) +asset output.js 2.52 KiB [emitted] (name: main) chunk (runtime: main) output.js (main) 326 bytes [entry] [rendered] > ./example.js main dependent modules 254 bytes [dependent] 2 modules ./example.js 72 bytes [built] [code generated] [used exports unknown] entry ./example.js main -webpack 5.11.1 compiled successfully +webpack 5.78.0 compiled successfully ``` ## Production mode ``` -asset output.js 296 bytes [emitted] [minimized] (name: main) +asset output.js 310 bytes [emitted] [minimized] (name: main) chunk (runtime: main) output.js (main) 326 bytes [entry] [rendered] > ./example.js main dependent modules 254 bytes [dependent] 2 modules ./example.js 72 bytes [built] [code generated] [no exports used] entry ./example.js main -webpack 5.11.1 compiled successfully +webpack 5.78.0 compiled successfully ``` diff --git a/examples/css/README.md b/examples/css/README.md new file mode 100644 index 00000000000..0d2411cb7ae --- /dev/null +++ b/examples/css/README.md @@ -0,0 +1,559 @@ +# example.js + +```javascript +import "./style.css"; +import "./style2.css"; +import { main } from "./style.module.css"; +import("./lazy-style.css"); + +document.getElementsByTagName("main")[0].className = main; +``` + +# style.css + +```javascript +@import "style-imported.css"; +@import "https://fonts.googleapis.com/css?family=Open+Sans"; + +body { + background: green; + font-family: "Open Sans"; +} +``` + +# dist/output.js + +```javascript +/******/ (() => { // webpackBootstrap +/******/ "use strict"; +/******/ var __webpack_modules__ = ({ + +/***/ 3: +/*!*************************!*\ + !*** ./images/file.png ***! + \*************************/ +/*! default exports */ +/*! exports [not provided] [no usage info] */ +/*! runtime requirements: __webpack_require__.p, module, __webpack_require__.* */ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +module.exports = __webpack_require__.p + "89a353e9c515885abd8e.png"; + +/***/ }) + +/******/ }); +``` + +
/* webpack runtime code */ + +``` js +/************************************************************************/ +/******/ // The module cache +/******/ var __webpack_module_cache__ = {}; +/******/ +/******/ // The require function +/******/ function __webpack_require__(moduleId) { +/******/ // Check if module is in cache +/******/ var cachedModule = __webpack_module_cache__[moduleId]; +/******/ if (cachedModule !== undefined) { +/******/ return cachedModule.exports; +/******/ } +/******/ // Create a new module (and put it into the cache) +/******/ var module = __webpack_module_cache__[moduleId] = { +/******/ // no module.id needed +/******/ // no module.loaded needed +/******/ exports: {} +/******/ }; +/******/ +/******/ // Execute the module function +/******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__); +/******/ +/******/ // Return the exports of the module +/******/ return module.exports; +/******/ } +/******/ +/******/ // expose the modules object (__webpack_modules__) +/******/ __webpack_require__.m = __webpack_modules__; +/******/ +/************************************************************************/ +/******/ /* webpack/runtime/ensure chunk */ +/******/ (() => { +/******/ __webpack_require__.f = {}; +/******/ // This file contains only the entry chunk. +/******/ // The chunk loading function for additional chunks +/******/ __webpack_require__.e = (chunkId) => { +/******/ return Promise.all(Object.keys(__webpack_require__.f).reduce((promises, key) => { +/******/ __webpack_require__.f[key](chunkId, promises); +/******/ return promises; +/******/ }, [])); +/******/ }; +/******/ })(); +/******/ +/******/ /* webpack/runtime/get css chunk filename */ +/******/ (() => { +/******/ // This function allow to reference async chunks +/******/ __webpack_require__.k = (chunkId) => { +/******/ // return url for filenames based on template +/******/ return "" + chunkId + ".output.css"; +/******/ }; +/******/ })(); +/******/ +/******/ /* webpack/runtime/get javascript chunk filename */ +/******/ (() => { +/******/ // This function allow to reference async chunks +/******/ __webpack_require__.u = (chunkId) => { +/******/ // return url for filenames based on template +/******/ return "" + chunkId + ".output.js"; +/******/ }; +/******/ })(); +/******/ +/******/ /* webpack/runtime/hasOwnProperty shorthand */ +/******/ (() => { +/******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop)) +/******/ })(); +/******/ +/******/ /* webpack/runtime/load script */ +/******/ (() => { +/******/ var inProgress = {}; +/******/ var dataWebpackPrefix = "app:"; +/******/ // loadScript function to load a script via script tag +/******/ __webpack_require__.l = (url, done, key, chunkId) => { +/******/ if(inProgress[url]) { inProgress[url].push(done); return; } +/******/ var script, needAttach; +/******/ if(key !== undefined) { +/******/ var scripts = document.getElementsByTagName("script"); +/******/ for(var i = 0; i < scripts.length; i++) { +/******/ var s = scripts[i]; +/******/ if(s.getAttribute("src") == url || s.getAttribute("data-webpack") == dataWebpackPrefix + key) { script = s; break; } +/******/ } +/******/ } +/******/ if(!script) { +/******/ needAttach = true; +/******/ script = document.createElement('script'); +/******/ +/******/ script.charset = 'utf-8'; +/******/ script.timeout = 120; +/******/ if (__webpack_require__.nc) { +/******/ script.setAttribute("nonce", __webpack_require__.nc); +/******/ } +/******/ script.setAttribute("data-webpack", dataWebpackPrefix + key); +/******/ script.src = url; +/******/ } +/******/ inProgress[url] = [done]; +/******/ var onScriptComplete = (prev, event) => { +/******/ // avoid mem leaks in IE. +/******/ script.onerror = script.onload = null; +/******/ clearTimeout(timeout); +/******/ var doneFns = inProgress[url]; +/******/ delete inProgress[url]; +/******/ script.parentNode && script.parentNode.removeChild(script); +/******/ doneFns && doneFns.forEach((fn) => (fn(event))); +/******/ if(prev) return prev(event); +/******/ } +/******/ var timeout = setTimeout(onScriptComplete.bind(null, undefined, { type: 'timeout', target: script }), 120000); +/******/ script.onerror = onScriptComplete.bind(null, script.onerror); +/******/ script.onload = onScriptComplete.bind(null, script.onload); +/******/ needAttach && document.head.appendChild(script); +/******/ }; +/******/ })(); +/******/ +/******/ /* webpack/runtime/make namespace object */ +/******/ (() => { +/******/ // define __esModule on exports +/******/ __webpack_require__.r = (exports) => { +/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { +/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); +/******/ } +/******/ Object.defineProperty(exports, '__esModule', { value: true }); +/******/ }; +/******/ })(); +/******/ +/******/ /* webpack/runtime/publicPath */ +/******/ (() => { +/******/ __webpack_require__.p = "dist/"; +/******/ })(); +/******/ +/******/ /* webpack/runtime/css loading */ +/******/ (() => { +/******/ // object to store loaded and loading chunks +/******/ // undefined = chunk not loaded, null = chunk preloaded/prefetched +/******/ // [resolve, reject, Promise] = chunk loading, 0 = chunk loaded +/******/ var installedChunks = {}; +/******/ +/******/ var uniqueName = "app"; +/******/ var loadCssChunkData = (target, link, chunkId) => { +/******/ var data, token = "", token2, exports = {}, exportsWithId = [], exportsWithDashes = [], i = 0, cc = 1; +/******/ try { if(!link) link = loadStylesheet(chunkId); data = link.sheet.cssRules; data = data[data.length - 1].style; } catch(e) { data = getComputedStyle(document.head); } +/******/ data = data.getPropertyValue("--webpack-" + uniqueName + "-" + chunkId); +/******/ if(!data) return []; +/******/ for(; cc; i++) { +/******/ cc = data.charCodeAt(i); +/******/ if(cc == 40) { token2 = token; token = ""; } +/******/ else if(cc == 41) { exports[token2.replace(/^_/, "")] = token.replace(/^_/, ""); token = ""; } +/******/ else if(cc == 47 || cc == 37) { token = token.replace(/^_/, ""); exports[token] = token; exportsWithId.push(token); if(cc == 37) exportsWithDashes.push(token); token = ""; } +/******/ else if(!cc || cc == 44) { token = token.replace(/^_/, ""); exportsWithId.forEach((x) => (exports[x] = uniqueName + "-" + token + "-" + exports[x])); exportsWithDashes.forEach((x) => (exports[x] = "--" + exports[x])); __webpack_require__.r(exports); target[token] = ((exports, module) => { +/******/ module.exports = exports; +/******/ }).bind(null, exports); token = ""; exports = {}; exportsWithId.length = 0; } +/******/ else if(cc == 92) { token += data[++i] } +/******/ else { token += data[i]; } +/******/ } +/******/ installedChunks[chunkId] = 0; +/******/ +/******/ } +/******/ var loadingAttribute = "data-webpack-loading"; +/******/ var loadStylesheet = (chunkId, url, done) => { +/******/ var link, needAttach, key = "chunk-" + chunkId; +/******/ +/******/ var links = document.getElementsByTagName("link"); +/******/ for(var i = 0; i < links.length; i++) { +/******/ var l = links[i]; +/******/ if(l.rel == "stylesheet" && (l.href == url || l.getAttribute("href") == url || l.getAttribute("data-webpack") == uniqueName + ":" + key)) { link = l; break; } +/******/ } +/******/ if(!done) return link; +/******/ +/******/ if(!link) { +/******/ needAttach = true; +/******/ link = document.createElement('link'); +/******/ link.setAttribute("data-webpack", uniqueName + ":" + key); +/******/ link.setAttribute(loadingAttribute, 1); +/******/ link.rel = "stylesheet"; +/******/ link.href = url; +/******/ } +/******/ var onLinkComplete = (prev, event) => { +/******/ link.onerror = link.onload = null; +/******/ link.removeAttribute(loadingAttribute); +/******/ clearTimeout(timeout); +/******/ if(event && event.type != "load") link.parentNode.removeChild(link) +/******/ done(event); +/******/ if(prev) return prev(event); +/******/ }; +/******/ if(link.getAttribute(loadingAttribute)) { +/******/ var timeout = setTimeout(onLinkComplete.bind(null, undefined, { type: 'timeout', target: link }), 120000); +/******/ link.onerror = onLinkComplete.bind(null, link.onerror); +/******/ link.onload = onLinkComplete.bind(null, link.onload); +/******/ } else onLinkComplete(undefined, { type: 'load', target: link }); +/******/ +/******/ needAttach && document.head.appendChild(link); +/******/ return link; +/******/ }; +/******/ loadCssChunkData(__webpack_require__.m, 0, 0); +/******/ +/******/ __webpack_require__.f.css = (chunkId, promises) => { +/******/ // css chunk loading +/******/ var installedChunkData = __webpack_require__.o(installedChunks, chunkId) ? installedChunks[chunkId] : undefined; +/******/ if(installedChunkData !== 0) { // 0 means "already installed". +/******/ +/******/ // a Promise means "currently loading". +/******/ if(installedChunkData) { +/******/ promises.push(installedChunkData[2]); +/******/ } else { +/******/ if(true) { // all chunks have CSS +/******/ // setup Promise in chunk cache +/******/ var promise = new Promise((resolve, reject) => (installedChunkData = installedChunks[chunkId] = [resolve, reject])); +/******/ promises.push(installedChunkData[2] = promise); +/******/ +/******/ // start chunk loading +/******/ var url = __webpack_require__.p + __webpack_require__.k(chunkId); +/******/ // create error before stack unwound to get useful stacktrace later +/******/ var error = new Error(); +/******/ var loadingEnded = (event) => { +/******/ if(__webpack_require__.o(installedChunks, chunkId)) { +/******/ installedChunkData = installedChunks[chunkId]; +/******/ if(installedChunkData !== 0) installedChunks[chunkId] = undefined; +/******/ if(installedChunkData) { +/******/ if(event.type !== "load") { +/******/ var errorType = event && event.type; +/******/ var realSrc = event && event.target && event.target.src; +/******/ error.message = 'Loading css chunk ' + chunkId + ' failed.\n(' + errorType + ': ' + realSrc + ')'; +/******/ error.name = 'ChunkLoadError'; +/******/ error.type = errorType; +/******/ error.request = realSrc; +/******/ installedChunkData[1](error); +/******/ } else { +/******/ loadCssChunkData(__webpack_require__.m, link, chunkId); +/******/ installedChunkData[0](); +/******/ } +/******/ } +/******/ } +/******/ }; +/******/ var link = loadStylesheet(chunkId, url, loadingEnded); +/******/ } else installedChunks[chunkId] = 0; +/******/ } +/******/ } +/******/ }; +/******/ +/******/ // no hmr +/******/ })(); +/******/ +/******/ /* webpack/runtime/jsonp chunk loading */ +/******/ (() => { +/******/ // no baseURI +/******/ +/******/ // object to store loaded and loading chunks +/******/ // undefined = chunk not loaded, null = chunk preloaded/prefetched +/******/ // [resolve, reject, Promise] = chunk loading, 0 = chunk loaded +/******/ var installedChunks = { +/******/ 0: 0 +/******/ }; +/******/ +/******/ __webpack_require__.f.j = (chunkId, promises) => { +/******/ // JSONP chunk loading for javascript +/******/ var installedChunkData = __webpack_require__.o(installedChunks, chunkId) ? installedChunks[chunkId] : undefined; +/******/ if(installedChunkData !== 0) { // 0 means "already installed". +/******/ +/******/ // a Promise means "currently loading". +/******/ if(installedChunkData) { +/******/ promises.push(installedChunkData[2]); +/******/ } else { +/******/ if(0 == chunkId) { +/******/ // setup Promise in chunk cache +/******/ var promise = new Promise((resolve, reject) => (installedChunkData = installedChunks[chunkId] = [resolve, reject])); +/******/ promises.push(installedChunkData[2] = promise); +/******/ +/******/ // start chunk loading +/******/ var url = __webpack_require__.p + __webpack_require__.u(chunkId); +/******/ // create error before stack unwound to get useful stacktrace later +/******/ var error = new Error(); +/******/ var loadingEnded = (event) => { +/******/ if(__webpack_require__.o(installedChunks, chunkId)) { +/******/ installedChunkData = installedChunks[chunkId]; +/******/ if(installedChunkData !== 0) installedChunks[chunkId] = undefined; +/******/ if(installedChunkData) { +/******/ var errorType = event && (event.type === 'load' ? 'missing' : event.type); +/******/ var realSrc = event && event.target && event.target.src; +/******/ error.message = 'Loading chunk ' + chunkId + ' failed.\n(' + errorType + ': ' + realSrc + ')'; +/******/ error.name = 'ChunkLoadError'; +/******/ error.type = errorType; +/******/ error.request = realSrc; +/******/ installedChunkData[1](error); +/******/ } +/******/ } +/******/ }; +/******/ __webpack_require__.l(url, loadingEnded, "chunk-" + chunkId, chunkId); +/******/ } else installedChunks[chunkId] = 0; +/******/ } +/******/ } +/******/ }; +/******/ +/******/ // no prefetching +/******/ +/******/ // no preloaded +/******/ +/******/ // no HMR +/******/ +/******/ // no HMR manifest +/******/ +/******/ // no on chunks loaded +/******/ +/******/ // install a JSONP callback for chunk loading +/******/ var webpackJsonpCallback = (parentChunkLoadingFunction, data) => { +/******/ var [chunkIds, moreModules, runtime] = data; +/******/ // add "moreModules" to the modules object, +/******/ // then flag all "chunkIds" as loaded and fire callback +/******/ var moduleId, chunkId, i = 0; +/******/ if(chunkIds.some((id) => (installedChunks[id] !== 0))) { +/******/ for(moduleId in moreModules) { +/******/ if(__webpack_require__.o(moreModules, moduleId)) { +/******/ __webpack_require__.m[moduleId] = moreModules[moduleId]; +/******/ } +/******/ } +/******/ if(runtime) var result = runtime(__webpack_require__); +/******/ } +/******/ if(parentChunkLoadingFunction) parentChunkLoadingFunction(data); +/******/ for(;i < chunkIds.length; i++) { +/******/ chunkId = chunkIds[i]; +/******/ if(__webpack_require__.o(installedChunks, chunkId) && installedChunks[chunkId]) { +/******/ installedChunks[chunkId][0](); +/******/ } +/******/ installedChunks[chunkId] = 0; +/******/ } +/******/ +/******/ } +/******/ +/******/ var chunkLoadingGlobal = self["webpackChunkapp"] = self["webpackChunkapp"] || []; +/******/ chunkLoadingGlobal.forEach(webpackJsonpCallback.bind(null, 0)); +/******/ chunkLoadingGlobal.push = webpackJsonpCallback.bind(null, chunkLoadingGlobal.push.bind(chunkLoadingGlobal)); +/******/ })(); +/******/ +/************************************************************************/ +``` + +
+ +``` js +var __webpack_exports__ = {}; +// This entry need to be wrapped in an IIFE because it need to be isolated against other modules in the chunk. +(() => { +/*!********************!*\ + !*** ./example.js ***! + \********************/ +/*! namespace exports */ +/*! exports [not provided] [no usage info] */ +/*! runtime requirements: __webpack_require__, __webpack_require__.r, __webpack_exports__, __webpack_require__.e, __webpack_require__.* */ +__webpack_require__.r(__webpack_exports__); +/* harmony import */ var _style_css__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./style.css */ 1); +/* harmony import */ var _style2_css__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./style2.css */ 5); +/* harmony import */ var _style_module_css__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./style.module.css */ 6); + + + +__webpack_require__.e(/*! import() */ 1).then(__webpack_require__.bind(__webpack_require__, /*! ./lazy-style.css */ 7)); + +document.getElementsByTagName("main")[0].className = _style_module_css__WEBPACK_IMPORTED_MODULE_2__.main; + +})(); + +/******/ })() +; +``` + +# dist/output.css + +```javascript +@import url("https://fonts.googleapis.com/css?family=Open+Sans"); +.img { + width: 150px; + height: 150px; + background: url(89a353e9c515885abd8e.png); +} + + +body { + background: green; + font-family: "Open Sans"; +} + +body { + background: red; +} + +:root { + --app-6-large: 72px; +} + +.app-6-main { + font-size: var(--app-6-large); + color: darkblue; +} + +@media (min-width: 1024px) { + .app-6-main { + color: green; + } +} + +@supports (display: grid) { + .app-6-main { + display: grid + } +} + +head{--webpack-app-0:_4,_2,_1,_5,large%main/_6;} +``` + +## production + +```javascript +@import url("https://fonts.googleapis.com/css?family=Open+Sans"); +.img { + width: 150px; + height: 150px; + background: url(89a353e9c515885abd8e.png); +} + + +body { + background: green; + font-family: "Open Sans"; +} + +body { + background: red; +} + +:root { + --app-491-b: 72px; +} + +.app-491-D { + font-size: var(--app-491-b); + color: darkblue; +} + +@media (min-width: 1024px) { + .app-491-D { + color: green; + } +} + +@supports (display: grid) { + .app-491-D { + display: grid + } +} + +head{--webpack-app-179:_548,_431,_258,_268,b%D/_491;} +``` + +# dist/1.output.css + +```javascript +body { + color: blue; +} + +head{--webpack-app-1:_7;} +``` + +# Info + +## Unoptimized + +``` +assets by chunk 17 KiB (name: main) + asset output.js 16.5 KiB [emitted] (name: main) + asset output.css 516 bytes [emitted] (name: main) +asset 89a353e9c515885abd8e.png 14.6 KiB [emitted] [immutable] [from: images/file.png] (auxiliary name: main) +asset 1.output.css 49 bytes [emitted] +Entrypoint main 17 KiB (14.6 KiB) = output.js 16.5 KiB output.css 516 bytes 1 auxiliary asset +chunk (runtime: main) output.js, output.css (main) 218 bytes (javascript) 454 bytes (css) 14.6 KiB (asset) 42 bytes (css-import) 10 KiB (runtime) [entry] [rendered] + > ./example.js main + runtime modules 10 KiB 9 modules + dependent modules 42 bytes (javascript) 14.6 KiB (asset) 454 bytes (css) 42 bytes (css-import) [dependent] 6 modules + ./example.js 176 bytes [built] [code generated] + [no exports] + [used exports unknown] + entry ./example.js main +chunk (runtime: main) 1.output.css 23 bytes + > ./lazy-style.css ./example.js 4:0-26 + ./lazy-style.css 23 bytes [built] [code generated] + [no exports] + [used exports unknown] + import() ./lazy-style.css ./example.js 4:0-26 +webpack 5.78.0 compiled successfully +``` + +## Production mode + +``` +assets by chunk 4.38 KiB (name: main) + asset output.js 3.88 KiB [emitted] [minimized] (name: main) + asset output.css 514 bytes [emitted] (name: main) +asset 89a353e9c515885abd8e.png 14.6 KiB [emitted] [immutable] [from: images/file.png] (auxiliary name: main) +asset 159.output.css 53 bytes [emitted] +Entrypoint main 4.38 KiB (14.6 KiB) = output.js 3.88 KiB output.css 514 bytes 1 auxiliary asset +chunk (runtime: main) 159.output.css 23 bytes + > ./lazy-style.css ./example.js 4:0-26 + ./lazy-style.css 23 bytes [built] [code generated] + [no exports] + import() ./lazy-style.css ./example.js 4:0-26 +chunk (runtime: main) output.js, output.css (main) 218 bytes (javascript) 454 bytes (css) 14.6 KiB (asset) 42 bytes (css-import) 10 KiB (runtime) [entry] [rendered] + > ./example.js main + runtime modules 10 KiB 9 modules + dependent modules 42 bytes (javascript) 14.6 KiB (asset) 454 bytes (css) 42 bytes (css-import) [dependent] 6 modules + ./example.js 176 bytes [built] [code generated] + [no exports] + [no exports used] + entry ./example.js main +webpack 5.78.0 compiled successfully +``` diff --git a/examples/css/build.js b/examples/css/build.js new file mode 100644 index 00000000000..41c29c9d169 --- /dev/null +++ b/examples/css/build.js @@ -0,0 +1 @@ +require("../build-common"); \ No newline at end of file diff --git a/examples/css/example.js b/examples/css/example.js new file mode 100644 index 00000000000..b44731310a8 --- /dev/null +++ b/examples/css/example.js @@ -0,0 +1,6 @@ +import "./style.css"; +import "./style2.css"; +import { main } from "./style.module.css"; +import("./lazy-style.css"); + +document.getElementsByTagName("main")[0].className = main; diff --git a/examples/css/images/file.png b/examples/css/images/file.png new file mode 100644 index 00000000000..fb53b9dedd3 Binary files /dev/null and b/examples/css/images/file.png differ diff --git a/examples/css/index.html b/examples/css/index.html new file mode 100644 index 00000000000..9b3f06397ab --- /dev/null +++ b/examples/css/index.html @@ -0,0 +1,10 @@ + + + + + +
Hello World
+

+ + + diff --git a/examples/css/lazy-style.css b/examples/css/lazy-style.css new file mode 100644 index 00000000000..36505138bc9 --- /dev/null +++ b/examples/css/lazy-style.css @@ -0,0 +1,3 @@ +body { + color: blue; +} diff --git a/examples/css/style-imported.css b/examples/css/style-imported.css new file mode 100644 index 00000000000..83989315ce2 --- /dev/null +++ b/examples/css/style-imported.css @@ -0,0 +1,5 @@ +.img { + width: 150px; + height: 150px; + background: url("./images/file.png"); +} diff --git a/examples/css/style.css b/examples/css/style.css new file mode 100644 index 00000000000..8b855420284 --- /dev/null +++ b/examples/css/style.css @@ -0,0 +1,7 @@ +@import "style-imported.css"; +@import "https://fonts.googleapis.com/css?family=Open+Sans"; + +body { + background: green; + font-family: "Open Sans"; +} diff --git a/examples/css/style.module.css b/examples/css/style.module.css new file mode 100644 index 00000000000..a788746a1a3 --- /dev/null +++ b/examples/css/style.module.css @@ -0,0 +1,20 @@ +:root { + --large: 72px; +} + +.main { + font-size: var(--large); + color: darkblue; +} + +@media (min-width: 1024px) { + .main { + color: green; + } +} + +@supports (display: grid) { + .main { + display: grid + } +} diff --git a/examples/css/style2.css b/examples/css/style2.css new file mode 100644 index 00000000000..f0d5b13bffd --- /dev/null +++ b/examples/css/style2.css @@ -0,0 +1,3 @@ +body { + background: red; +} diff --git a/examples/css/template.md b/examples/css/template.md new file mode 100644 index 00000000000..6dea2beb4e5 --- /dev/null +++ b/examples/css/template.md @@ -0,0 +1,49 @@ +# example.js + +```javascript +_{{example.js}}_ +``` + +# style.css + +```javascript +_{{style.css}}_ +``` + +# dist/output.js + +```javascript +_{{dist/output.js}}_ +``` + +# dist/output.css + +```javascript +_{{dist/output.css}}_ +``` + +## production + +```javascript +_{{production:dist/output.css}}_ +``` + +# dist/1.output.css + +```javascript +_{{dist/1.output.css}}_ +``` + +# Info + +## Unoptimized + +``` +_{{stdout}}_ +``` + +## Production mode + +``` +_{{production:stdout}}_ +``` diff --git a/examples/css/webpack.config.js b/examples/css/webpack.config.js new file mode 100644 index 00000000000..93ef7f910e6 --- /dev/null +++ b/examples/css/webpack.config.js @@ -0,0 +1,8 @@ +module.exports = { + output: { + uniqueName: "app" + }, + experiments: { + css: true + } +}; diff --git a/examples/custom-json-modules/README.md b/examples/custom-json-modules/README.md index 113cb382c53..95a5e0e6b33 100644 --- a/examples/custom-json-modules/README.md +++ b/examples/custom-json-modules/README.md @@ -101,33 +101,7 @@ module.exports = { /******/ (() => { // webpackBootstrap /******/ "use strict"; /******/ var __webpack_modules__ = ([ -/* 0 */ -/*!********************!*\ - !*** ./example.js ***! - \********************/ -/*! namespace exports */ -/*! exports [not provided] [no usage info] */ -/*! runtime requirements: __webpack_require__, __webpack_require__.r, __webpack_exports__, __webpack_require__.* */ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -__webpack_require__.r(__webpack_exports__); -/* harmony import */ var _data_toml__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./data.toml */ 1); -/* harmony import */ var _data_yaml__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./data.yaml */ 2); -/* harmony import */ var _data_json5__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./data.json5 */ 3); - - - - -document.querySelector('#app').innerHTML = [_data_toml__WEBPACK_IMPORTED_MODULE_0__, _data_yaml__WEBPACK_IMPORTED_MODULE_1__, _data_json5__WEBPACK_IMPORTED_MODULE_2__].map(data => ` -

${data.title}

-
${data.owner.name}
-
${data.owner.organization}
-
${data.owner.bio}
-
${data.owner.dob}
-`).join('

'); - - -/***/ }), +/* 0 */, /* 1 */ /*!*******************!*\ !*** ./data.toml ***! @@ -145,7 +119,7 @@ document.querySelector('#app').innerHTML = [_data_toml__WEBPACK_IMPORTED_MODULE_ /*! runtime requirements: module */ /***/ ((module) => { -module.exports = JSON.parse("{\"title\":\"TOML Example\",\"owner\":{\"name\":\"Tom Preston-Werner\",\"organization\":\"GitHub\",\"bio\":\"GitHub Cofounder & CEO\\nLikes tater tots and beer.\",\"dob\":\"1979-05-27T07:32:00.000Z\"}}"); +module.exports = JSON.parse('{"title":"TOML Example","owner":{"name":"Tom Preston-Werner","organization":"GitHub","bio":"GitHub Cofounder & CEO\\nLikes tater tots and beer.","dob":"1979-05-27T07:32:00.000Z"}}'); /***/ }), /* 2 */ @@ -165,7 +139,7 @@ module.exports = JSON.parse("{\"title\":\"TOML Example\",\"owner\":{\"name\":\"T /*! runtime requirements: module */ /***/ ((module) => { -module.exports = JSON.parse("{\"title\":\"YAML Example\",\"owner\":{\"name\":\"Tom Preston-Werner\",\"organization\":\"GitHub\",\"bio\":\"GitHub Cofounder & CEO\\nLikes tater tots and beer.\",\"dob\":\"1979-05-27T07:32:00.000Z\"}}"); +module.exports = JSON.parse('{"title":"YAML Example","owner":{"name":"Tom Preston-Werner","organization":"GitHub","bio":"GitHub Cofounder & CEO\\nLikes tater tots and beer.","dob":"1979-05-27T07:32:00.000Z"}}'); /***/ }), /* 3 */ @@ -184,7 +158,7 @@ module.exports = JSON.parse("{\"title\":\"YAML Example\",\"owner\":{\"name\":\"T /*! runtime requirements: module */ /***/ ((module) => { -module.exports = JSON.parse("{\"title\":\"JSON5 Example\",\"owner\":{\"name\":\"Tom Preston-Werner\",\"organization\":\"GitHub\",\"bio\":\"GitHub Cofounder & CEO\\nLikes tater tots and beer.\",\"dob\":\"1979-05-27T07:32:00.000Z\"}}"); +module.exports = JSON.parse('{"title":"JSON5 Example","owner":{"name":"Tom Preston-Werner","organization":"GitHub","bio":"GitHub Cofounder & CEO\\nLikes tater tots and beer.","dob":"1979-05-27T07:32:00.000Z"}}'); /***/ }) /******/ ]); @@ -200,8 +174,9 @@ module.exports = JSON.parse("{\"title\":\"JSON5 Example\",\"owner\":{\"name\":\" /******/ // The require function /******/ function __webpack_require__(moduleId) { /******/ // Check if module is in cache -/******/ if(__webpack_module_cache__[moduleId]) { -/******/ return __webpack_module_cache__[moduleId].exports; +/******/ var cachedModule = __webpack_module_cache__[moduleId]; +/******/ if (cachedModule !== undefined) { +/******/ return cachedModule.exports; /******/ } /******/ // Create a new module (and put it into the cache) /******/ var module = __webpack_module_cache__[moduleId] = { @@ -235,10 +210,33 @@ module.exports = JSON.parse("{\"title\":\"JSON5 Example\",\"owner\":{\"name\":\" ``` js -/******/ // startup -/******/ // Load entry module -/******/ __webpack_require__(0); -/******/ // This entry module used 'exports' so it can't be inlined +var __webpack_exports__ = {}; +// This entry need to be wrapped in an IIFE because it need to be isolated against other modules in the chunk. +(() => { +/*!********************!*\ + !*** ./example.js ***! + \********************/ +/*! namespace exports */ +/*! exports [not provided] [no usage info] */ +/*! runtime requirements: __webpack_require__, __webpack_require__.r, __webpack_exports__, __webpack_require__.* */ +__webpack_require__.r(__webpack_exports__); +/* harmony import */ var _data_toml__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./data.toml */ 1); +/* harmony import */ var _data_yaml__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./data.yaml */ 2); +/* harmony import */ var _data_json5__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./data.json5 */ 3); + + + + +document.querySelector('#app').innerHTML = [_data_toml__WEBPACK_IMPORTED_MODULE_0__, _data_yaml__WEBPACK_IMPORTED_MODULE_1__, _data_json5__WEBPACK_IMPORTED_MODULE_2__].map(data => ` +

${data.title}

+
${data.owner.name}
+
${data.owner.organization}
+
${data.owner.bio}
+
${data.owner.dob}
+`).join('

'); + +})(); + /******/ })() ; ``` @@ -248,7 +246,7 @@ module.exports = JSON.parse("{\"title\":\"JSON5 Example\",\"owner\":{\"name\":\" ## webpack output ``` -asset output.js 5.98 KiB [emitted] (name: main) +asset output.js 5.87 KiB [emitted] (name: main) chunk (runtime: main) output.js (main) 919 bytes (javascript) 274 bytes (runtime) [entry] [rendered] > ./example.js main dependent modules 565 bytes [dependent] 3 modules @@ -257,5 +255,5 @@ chunk (runtime: main) output.js (main) 919 bytes (javascript) 274 bytes (runtime [no exports] [used exports unknown] entry ./example.js main -webpack 5.11.1 compiled successfully +webpack 5.78.0 compiled successfully ``` diff --git a/examples/dll-app-and-vendor/0-vendor/README.md b/examples/dll-app-and-vendor/0-vendor/README.md index 1e2b1100f7e..58dff010f6e 100644 --- a/examples/dll-app-and-vendor/0-vendor/README.md +++ b/examples/dll-app-and-vendor/0-vendor/README.md @@ -13,7 +13,7 @@ var path = require("path"); var webpack = require("../../../"); module.exports = { - // mode: "development || "production", + // mode: "development" || "production", context: __dirname, entry: ["example-vendor"], output: { @@ -41,7 +41,7 @@ export function square(n) { # dist/vendor.js ```javascript -var vendor_lib_d696c7b4f72a4a70f39b;vendor_lib_d696c7b4f72a4a70f39b = +var vendor_lib_bef1463383efb1c65306; /******/ (() => { // webpackBootstrap /******/ var __webpack_modules__ = ([ /* 0 */ @@ -68,7 +68,7 @@ module.exports = __webpack_require__; "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "square": () => /* binding */ square +/* harmony export */ "square": () => (/* binding */ square) /* harmony export */ }); function square(n) { return n * n; @@ -89,8 +89,9 @@ function square(n) { /******/ // The require function /******/ function __webpack_require__(moduleId) { /******/ // Check if module is in cache -/******/ if(__webpack_module_cache__[moduleId]) { -/******/ return __webpack_module_cache__[moduleId].exports; +/******/ var cachedModule = __webpack_module_cache__[moduleId]; +/******/ if (cachedModule !== undefined) { +/******/ return cachedModule.exports; /******/ } /******/ // Create a new module (and put it into the cache) /******/ var module = __webpack_module_cache__[moduleId] = { @@ -121,7 +122,7 @@ function square(n) { /******/ /******/ /* webpack/runtime/hasOwnProperty shorthand */ /******/ (() => { -/******/ __webpack_require__.o = (obj, prop) => Object.prototype.hasOwnProperty.call(obj, prop) +/******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop)) /******/ })(); /******/ /******/ /* webpack/runtime/make namespace object */ @@ -141,10 +142,13 @@ function square(n) { ``` js -/******/ // module exports must be returned from runtime so entry inlining is disabled +/******/ /******/ // startup /******/ // Load entry module and return exports -/******/ return __webpack_require__(0); +/******/ // This entry module doesn't tell about it's top-level declarations so it can't be inlined +/******/ var __webpack_exports__ = __webpack_require__(0); +/******/ vendor_lib_bef1463383efb1c65306 = __webpack_exports__; +/******/ /******/ })() ; ``` @@ -152,7 +156,7 @@ function square(n) { # dist/vendor-manifest.json ```javascript -{"name":"vendor_lib_d696c7b4f72a4a70f39b","content":{"../node_modules/example-vendor.js":{"id":1,"buildMeta":{"exportsType":"namespace"},"exports":["square"]}}} +{"name":"vendor_lib_bef1463383efb1c65306","content":{"../node_modules/example-vendor.js":{"id":1,"buildMeta":{"exportsType":"namespace"},"exports":["square"]}}} ``` # Info @@ -160,28 +164,28 @@ function square(n) { ## Unoptimized ``` -asset vendor.js 3.56 KiB [emitted] (name: main) -chunk (runtime: main) vendor.js (main) 57 bytes (javascript) 668 bytes (runtime) [entry] [rendered] +asset vendor.js 3.68 KiB [emitted] (name: main) +chunk (runtime: main) vendor.js (main) 57 bytes (javascript) 670 bytes (runtime) [entry] [rendered] > main - runtime modules 668 bytes 3 modules + runtime modules 670 bytes 3 modules dependent modules 45 bytes [dependent] 1 module dll main 12 bytes [built] [code generated] [used exports unknown] dll entry used as library export -webpack 5.11.1 compiled successfully +webpack 5.78.0 compiled successfully ``` ## Production mode ``` -asset vendor.js 638 bytes [emitted] [minimized] (name: main) -chunk (runtime: main) vendor.js (main) 57 bytes (javascript) 668 bytes (runtime) [entry] [rendered] +asset vendor.js 653 bytes [emitted] [minimized] (name: main) +chunk (runtime: main) vendor.js (main) 57 bytes (javascript) 670 bytes (runtime) [entry] [rendered] > main - runtime modules 668 bytes 3 modules + runtime modules 670 bytes 3 modules dependent modules 45 bytes [dependent] 1 module dll main 12 bytes [built] [code generated] dll entry used as library export -webpack 5.11.1 compiled successfully +webpack 5.78.0 compiled successfully ``` diff --git a/examples/dll-app-and-vendor/0-vendor/webpack.config.js b/examples/dll-app-and-vendor/0-vendor/webpack.config.js index 3572be39ce8..5a9099cdb5c 100644 --- a/examples/dll-app-and-vendor/0-vendor/webpack.config.js +++ b/examples/dll-app-and-vendor/0-vendor/webpack.config.js @@ -2,7 +2,7 @@ var path = require("path"); var webpack = require("../../../"); module.exports = { - // mode: "development || "production", + // mode: "development" || "production", context: __dirname, entry: ["example-vendor"], output: { diff --git a/examples/dll-app-and-vendor/1-app/README.md b/examples/dll-app-and-vendor/1-app/README.md index 83238a34185..2bc772a62dc 100644 --- a/examples/dll-app-and-vendor/1-app/README.md +++ b/examples/dll-app-and-vendor/1-app/README.md @@ -50,28 +50,10 @@ console.log(new square(7)); ```javascript /******/ (() => { // webpackBootstrap /******/ var __webpack_modules__ = ([ -/* 0 */ -/*!************************!*\ - !*** ./example-app.js ***! - \************************/ -/*! namespace exports */ -/*! exports [not provided] [no usage info] */ -/*! runtime requirements: __webpack_require__, __webpack_require__.r, __webpack_exports__, __webpack_require__.* */ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony import */ var example_vendor__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! example-vendor */ 1); - - -console.log((0,example_vendor__WEBPACK_IMPORTED_MODULE_0__.square)(7)); -console.log(new example_vendor__WEBPACK_IMPORTED_MODULE_0__.square(7)); - - -/***/ }), +/* 0 */, /* 1 */ /*!******************************************************************************************************!*\ - !*** delegated ../node_modules/example-vendor.js from dll-reference vendor_lib_d696c7b4f72a4a70f39b ***! + !*** delegated ../node_modules/example-vendor.js from dll-reference vendor_lib_bef1463383efb1c65306 ***! \******************************************************************************************************/ /*! namespace exports */ /*! export square [provided] [no usage info] [provision prevents renaming (no use info)] */ @@ -79,12 +61,12 @@ console.log(new example_vendor__WEBPACK_IMPORTED_MODULE_0__.square(7)); /*! runtime requirements: module, __webpack_require__ */ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { -module.exports = (__webpack_require__(/*! dll-reference vendor_lib_d696c7b4f72a4a70f39b */ 2))(1); +module.exports = (__webpack_require__(/*! dll-reference vendor_lib_bef1463383efb1c65306 */ 2))(1); /***/ }), /* 2 */ /*!**************************************************!*\ - !*** external "vendor_lib_d696c7b4f72a4a70f39b" ***! + !*** external "vendor_lib_bef1463383efb1c65306" ***! \**************************************************/ /*! dynamic exports */ /*! exports [maybe provided (runtime-defined)] [no usage info] */ @@ -92,7 +74,7 @@ module.exports = (__webpack_require__(/*! dll-reference vendor_lib_d696c7b4f72a4 /***/ ((module) => { "use strict"; -module.exports = vendor_lib_d696c7b4f72a4a70f39b; +module.exports = vendor_lib_bef1463383efb1c65306; /***/ }) /******/ ]); @@ -108,8 +90,9 @@ module.exports = vendor_lib_d696c7b4f72a4a70f39b; /******/ // The require function /******/ function __webpack_require__(moduleId) { /******/ // Check if module is in cache -/******/ if(__webpack_module_cache__[moduleId]) { -/******/ return __webpack_module_cache__[moduleId].exports; +/******/ var cachedModule = __webpack_module_cache__[moduleId]; +/******/ if (cachedModule !== undefined) { +/******/ return cachedModule.exports; /******/ } /******/ // Create a new module (and put it into the cache) /******/ var module = __webpack_module_cache__[moduleId] = { @@ -143,10 +126,25 @@ module.exports = vendor_lib_d696c7b4f72a4a70f39b; ``` js -/******/ // startup -/******/ // Load entry module -/******/ __webpack_require__(0); -/******/ // This entry module used 'exports' so it can't be inlined +var __webpack_exports__ = {}; +// This entry need to be wrapped in an IIFE because it need to be in strict mode. +(() => { +"use strict"; +/*!************************!*\ + !*** ./example-app.js ***! + \************************/ +/*! namespace exports */ +/*! exports [not provided] [no usage info] */ +/*! runtime requirements: __webpack_require__, __webpack_require__.r, __webpack_exports__, __webpack_require__.* */ +__webpack_require__.r(__webpack_exports__); +/* harmony import */ var example_vendor__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! example-vendor */ 1); + + +console.log((0,example_vendor__WEBPACK_IMPORTED_MODULE_0__.square)(7)); +console.log(new example_vendor__WEBPACK_IMPORTED_MODULE_0__.square(7)); + +})(); + /******/ })() ; ``` @@ -156,7 +154,7 @@ module.exports = vendor_lib_d696c7b4f72a4a70f39b; ## Unoptimized ``` -asset app.js 3.52 KiB [emitted] (name: main) +asset app.js 3.44 KiB [emitted] (name: main) chunk (runtime: main) app.js (main) 178 bytes (javascript) 274 bytes (runtime) [entry] [rendered] > ./example-app main dependent modules 84 bytes [dependent] 2 modules @@ -165,13 +163,13 @@ chunk (runtime: main) app.js (main) 178 bytes (javascript) 274 bytes (runtime) [ [no exports] [used exports unknown] entry ./example-app main -webpack 5.11.1 compiled successfully +webpack 5.78.0 compiled successfully ``` ## Production mode ``` -asset app.js 319 bytes [emitted] [minimized] (name: main) +asset app.js 333 bytes [emitted] [minimized] (name: main) chunk (runtime: main) app.js (main) 178 bytes [entry] [rendered] > ./example-app main dependent modules 84 bytes [dependent] 2 modules @@ -179,7 +177,7 @@ chunk (runtime: main) app.js (main) 178 bytes [entry] [rendered] [no exports] [no exports used] entry ./example-app main -webpack 5.11.1 compiled successfully +webpack 5.78.0 compiled successfully ```
- + @@ -335,57 +335,81 @@ export default Component; /******/ (() => { // webpackBootstrap /******/ var __webpack_modules__ = ({ -/***/ 12: +/***/ 0: +/*!**********************!*\ + !*** ./src/index.js ***! + \**********************/ +/*! unknown exports (runtime-defined) */ +/*! runtime requirements: __webpack_require__.e, __webpack_require__, __webpack_require__.* */ +/***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => { + +// Sharing modules requires that all remotes are initialized +// and can provide shared modules to the common scope +// As this is an async operation we need an async boundary (import()) + +// Using modules from remotes is also an async operation +// as chunks need to be loaded for the code of the remote module +// This also requires an async boundary (import()) + +// At this point shared modules initialized and remote modules are loaded +Promise.all(/*! import() */[__webpack_require__.e("vendors-node_modules_date-fns_esm_locale_de_index_js-node_modules_react-dom_index_js"), __webpack_require__.e("src_bootstrap_js")]).then(__webpack_require__.bind(__webpack_require__, /*! ./bootstrap */ 2)); + +// It's possible to place more code here to do stuff on page init +// but it can't use any of the shared modules or remote modules. + +/***/ }), + +/***/ 10: /*!*********************************************!*\ !*** external "mfeBBB@/dist/bbb/mfeBBB.js" ***! \*********************************************/ /*! dynamic exports */ /*! exports [maybe provided (runtime-defined)] [no usage info] */ -/*! runtime requirements: module, __webpack_require__.l, __webpack_require__.* */ +/*! runtime requirements: __webpack_require__.l, module, __webpack_require__.* */ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { "use strict"; -var error = new Error(); +var __webpack_error__ = new Error(); module.exports = new Promise((resolve, reject) => { if(typeof mfeBBB !== "undefined") return resolve(); __webpack_require__.l("/dist/bbb/mfeBBB.js", (event) => { if(typeof mfeBBB !== "undefined") return resolve(); var errorType = event && (event.type === 'load' ? 'missing' : event.type); var realSrc = event && event.target && event.target.src; - error.message = 'Loading script failed.\n(' + errorType + ': ' + realSrc + ')'; - error.name = 'ScriptExternalLoadError'; - error.type = errorType; - error.request = realSrc; - reject(error); + __webpack_error__.message = 'Loading script failed.\n(' + errorType + ': ' + realSrc + ')'; + __webpack_error__.name = 'ScriptExternalLoadError'; + __webpack_error__.type = errorType; + __webpack_error__.request = realSrc; + reject(__webpack_error__); }, "mfeBBB"); -}).then(() => mfeBBB); +}).then(() => (mfeBBB)); /***/ }), -/***/ 14: +/***/ 12: /*!*********************************************!*\ !*** external "mfeCCC@/dist/ccc/mfeCCC.js" ***! \*********************************************/ /*! dynamic exports */ /*! exports [maybe provided (runtime-defined)] [no usage info] */ -/*! runtime requirements: module, __webpack_require__.l, __webpack_require__.* */ +/*! runtime requirements: __webpack_require__.l, module, __webpack_require__.* */ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { "use strict"; -var error = new Error(); +var __webpack_error__ = new Error(); module.exports = new Promise((resolve, reject) => { if(typeof mfeCCC !== "undefined") return resolve(); __webpack_require__.l("/dist/ccc/mfeCCC.js", (event) => { if(typeof mfeCCC !== "undefined") return resolve(); var errorType = event && (event.type === 'load' ? 'missing' : event.type); var realSrc = event && event.target && event.target.src; - error.message = 'Loading script failed.\n(' + errorType + ': ' + realSrc + ')'; - error.name = 'ScriptExternalLoadError'; - error.type = errorType; - error.request = realSrc; - reject(error); + __webpack_error__.message = 'Loading script failed.\n(' + errorType + ': ' + realSrc + ')'; + __webpack_error__.name = 'ScriptExternalLoadError'; + __webpack_error__.type = errorType; + __webpack_error__.request = realSrc; + reject(__webpack_error__); }, "mfeCCC"); -}).then(() => mfeCCC); +}).then(() => (mfeCCC)); /***/ }) @@ -402,8 +426,9 @@ module.exports = new Promise((resolve, reject) => { /******/ // The require function /******/ function __webpack_require__(moduleId) { /******/ // Check if module is in cache -/******/ if(__webpack_module_cache__[moduleId]) { -/******/ return __webpack_module_cache__[moduleId].exports; +/******/ var cachedModule = __webpack_module_cache__[moduleId]; +/******/ if (cachedModule !== undefined) { +/******/ return cachedModule.exports; /******/ } /******/ // Create a new module (and put it into the cache) /******/ var module = __webpack_module_cache__[moduleId] = { @@ -422,14 +447,17 @@ module.exports = new Promise((resolve, reject) => { /******/ // expose the modules object (__webpack_modules__) /******/ __webpack_require__.m = __webpack_modules__; /******/ +/******/ // expose the module cache +/******/ __webpack_require__.c = __webpack_module_cache__; +/******/ /************************************************************************/ /******/ /* webpack/runtime/compat get default export */ /******/ (() => { /******/ // getDefaultExport function for compatibility with non-harmony modules /******/ __webpack_require__.n = (module) => { /******/ var getter = module && module.__esModule ? -/******/ () => module['default'] : -/******/ () => module; +/******/ () => (module['default']) : +/******/ () => (module); /******/ __webpack_require__.d(getter, { a: getter }); /******/ return getter; /******/ }; @@ -437,7 +465,7 @@ module.exports = new Promise((resolve, reject) => { /******/ /******/ /* webpack/runtime/create fake namespace object */ /******/ (() => { -/******/ var getProto = Object.getPrototypeOf ? (obj) => Object.getPrototypeOf(obj) : (obj) => obj.__proto__; +/******/ var getProto = Object.getPrototypeOf ? (obj) => (Object.getPrototypeOf(obj)) : (obj) => (obj.__proto__); /******/ var leafPrototypes; /******/ // create a fake namespace object /******/ // mode & 1: value is a module id, require it @@ -457,9 +485,9 @@ module.exports = new Promise((resolve, reject) => { /******/ var def = {}; /******/ leafPrototypes = leafPrototypes || [null, getProto({}), getProto([]), getProto(getProto)]; /******/ for(var current = mode & 2 && value; typeof current == 'object' && !~leafPrototypes.indexOf(current); current = getProto(current)) { -/******/ Object.getOwnPropertyNames(current).forEach(key => def[key] = () => value[key]); +/******/ Object.getOwnPropertyNames(current).forEach((key) => (def[key] = () => (value[key]))); /******/ } -/******/ def['default'] = () => value; +/******/ def['default'] = () => (value); /******/ __webpack_require__.d(ns, def); /******/ return ns; /******/ }; @@ -501,7 +529,7 @@ module.exports = new Promise((resolve, reject) => { /******/ /******/ /* webpack/runtime/hasOwnProperty shorthand */ /******/ (() => { -/******/ __webpack_require__.o = (obj, prop) => Object.prototype.hasOwnProperty.call(obj, prop) +/******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop)) /******/ })(); /******/ /******/ /* webpack/runtime/load script */ @@ -509,7 +537,7 @@ module.exports = new Promise((resolve, reject) => { /******/ var inProgress = {}; /******/ var dataWebpackPrefix = "module-federation-aaa:"; /******/ // loadScript function to load a script via script tag -/******/ __webpack_require__.l = (url, done, key) => { +/******/ __webpack_require__.l = (url, done, key, chunkId) => { /******/ if(inProgress[url]) { inProgress[url].push(done); return; } /******/ var script, needAttach; /******/ if(key !== undefined) { @@ -539,10 +567,9 @@ module.exports = new Promise((resolve, reject) => { /******/ var doneFns = inProgress[url]; /******/ delete inProgress[url]; /******/ script.parentNode && script.parentNode.removeChild(script); -/******/ doneFns && doneFns.forEach((fn) => fn(event)); +/******/ doneFns && doneFns.forEach((fn) => (fn(event))); /******/ if(prev) return prev(event); /******/ } -/******/ ; /******/ var timeout = setTimeout(onScriptComplete.bind(null, undefined, { type: 'timeout', target: script }), 120000); /******/ script.onerror = onScriptComplete.bind(null, script.onerror); /******/ script.onload = onScriptComplete.bind(null, script.onload); @@ -564,29 +591,29 @@ module.exports = new Promise((resolve, reject) => { /******/ /* webpack/runtime/remotes loading */ /******/ (() => { /******/ var chunkMapping = { -/******/ "src_bootstrap_js-webpack_sharing_consume_default_react_react": [ -/******/ 11, -/******/ 13 +/******/ "src_bootstrap_js": [ +/******/ 9, +/******/ 11 /******/ ], /******/ "webpack_container_remote_mfe-c_Component2": [ -/******/ 27 +/******/ 25 /******/ ] /******/ }; /******/ var idToExternalAndNameMapping = { -/******/ "11": [ +/******/ "9": [ /******/ "default", /******/ "./Component", -/******/ 12 +/******/ 10 /******/ ], -/******/ "13": [ +/******/ "11": [ /******/ "default", /******/ "./Component", -/******/ 14 +/******/ 12 /******/ ], -/******/ "27": [ +/******/ "25": [ /******/ "default", /******/ "./Component2", -/******/ 14 +/******/ 12 /******/ ] /******/ }; /******/ __webpack_require__.f.remotes = (chunkId, promises) => { @@ -602,7 +629,7 @@ module.exports = new Promise((resolve, reject) => { /******/ if(!error) error = new Error("Container missing"); /******/ if(typeof error.message === "string") /******/ error.message += '\nwhile loading "' + data[1] + '" from ' + data[2]; -/******/ __webpack_modules__[id] = () => { +/******/ __webpack_require__.m[id] = () => { /******/ throw error; /******/ } /******/ data.p = 0; @@ -611,7 +638,7 @@ module.exports = new Promise((resolve, reject) => { /******/ try { /******/ var promise = fn(arg1, arg2); /******/ if(promise && promise.then) { -/******/ var p = promise.then((result) => next(result, d), onError); +/******/ var p = promise.then((result) => (next(result, d)), onError); /******/ if(first) promises.push(data.p = p); else return p; /******/ } else { /******/ return next(promise, d, first); @@ -620,11 +647,11 @@ module.exports = new Promise((resolve, reject) => { /******/ onError(error); /******/ } /******/ } -/******/ var onExternal = (external, _, first) => external ? handleFunction(__webpack_require__.I, data[0], 0, external, onInitialized, first) : onError(); -/******/ var onInitialized = (_, external, first) => handleFunction(external.get, data[1], getScope, 0, onFactory, first); +/******/ var onExternal = (external, _, first) => (external ? handleFunction(__webpack_require__.I, data[0], 0, external, onInitialized, first) : onError()); +/******/ var onInitialized = (_, external, first) => (handleFunction(external.get, data[1], getScope, 0, onFactory, first)); /******/ var onFactory = (factory) => { /******/ data.p = 1; -/******/ __webpack_modules__[id] = (module) => { +/******/ __webpack_require__.m[id] = (module) => { /******/ module.exports = factory(); /******/ } /******/ }; @@ -652,35 +679,39 @@ module.exports = new Promise((resolve, reject) => { /******/ if(!__webpack_require__.o(__webpack_require__.S, name)) __webpack_require__.S[name] = {}; /******/ // runs all init snippets from all modules reachable /******/ var scope = __webpack_require__.S[name]; -/******/ var warn = (msg) => typeof console !== "undefined" && console.warn && console.warn(msg);; +/******/ var warn = (msg) => { +/******/ typeof console !== "undefined" && console.warn ? console.warn(msg) : (() => { +/******/ +/******/ })() +/******/ }; /******/ var uniqueName = "module-federation-aaa"; -/******/ var register = (name, version, factory) => { +/******/ var register = (name, version, factory, eager) => { /******/ var versions = scope[name] = scope[name] || {}; /******/ var activeVersion = versions[version]; -/******/ if(!activeVersion || !activeVersion.loaded && uniqueName > activeVersion.from) versions[version] = { get: factory, from: uniqueName }; +/******/ if(!activeVersion || (!activeVersion.loaded && (!eager != !activeVersion.eager ? eager : uniqueName > activeVersion.from))) versions[version] = { get: factory, from: uniqueName, eager: !!eager }; /******/ }; /******/ var initExternal = (id) => { -/******/ var handleError = (err) => warn("Initialization of sharing external failed: " + err); +/******/ var handleError = (err) => (warn("Initialization of sharing external failed: " + err)); /******/ try { /******/ var module = __webpack_require__(id); /******/ if(!module) return; -/******/ var initFn = (module) => module && module.init && module.init(__webpack_require__.S[name], initScope) +/******/ var initFn = (module) => (module && module.init && module.init(__webpack_require__.S[name], initScope)) /******/ if(module.then) return promises.push(module.then(initFn, handleError)); /******/ var initResult = initFn(module); -/******/ if(initResult && initResult.then) return promises.push(initResult.catch(handleError)); +/******/ if(initResult && initResult.then) return promises.push(initResult['catch'](handleError)); /******/ } catch(err) { handleError(err); } /******/ } /******/ var promises = []; /******/ switch(name) { /******/ case "default": { -/******/ register("react", "17.0.1", () => __webpack_require__.e("node_modules_react_index_js-_11190").then(() => () => __webpack_require__(/*! ../../node_modules/react/index.js */ 25))); +/******/ register("react", "18.2.0", () => (__webpack_require__.e("node_modules_react_index_js").then(() => (() => (__webpack_require__(/*! ../../node_modules/react/index.js */ 23)))))); +/******/ initExternal(10); /******/ initExternal(12); -/******/ initExternal(14); /******/ } /******/ break; /******/ } /******/ if(!promises.length) return initPromises[name] = 1; -/******/ return initPromises[name] = Promise.all(promises).then(() => initPromises[name] = 1); +/******/ return initPromises[name] = Promise.all(promises).then(() => (initPromises[name] = 1)); /******/ }; /******/ })(); /******/ @@ -701,7 +732,7 @@ module.exports = new Promise((resolve, reject) => { /******/ } /******/ var rangeToString = (range) => { /******/ // see webpack/lib/util/semver.js for original code -/******/ if(1===range.length)return"*";if(0 in range){var r="",n=range[0];r+=0==n?">=":-1==n?"<":1==n?"^":2==n?"~":n>0?"=":"!=";for(var e=1,a=1;a0?".":"")+(e=2,t)}return r}var g=[];for(a=1;a=":-1==r?"<":1==r?"^":2==r?"~":r>0?"=":"!=";for(var e=1,a=1;a0?".":"")+(e=2,t)}return n}var g=[];for(a=1;a { /******/ // see webpack/lib/util/semver.js for original code @@ -725,17 +756,21 @@ module.exports = new Promise((resolve, reject) => { /******/ return !a || (!versions[a].loaded && versionLt(a, b)) ? b : a; /******/ }, 0); /******/ }; -/******/ var getInvalidSingletonVersionMessage = (key, version, requiredVersion) => { -/******/ return "Unsatisfied version " + version + " of shared singleton module " + key + " (required " + rangeToString(requiredVersion) + ")" +/******/ var getInvalidSingletonVersionMessage = (scope, key, version, requiredVersion) => { +/******/ return "Unsatisfied version " + version + " from " + (version && scope[key][version].from) + " of shared singleton module " + key + " (required " + rangeToString(requiredVersion) + ")" +/******/ }; +/******/ var getSingleton = (scope, scopeName, key, requiredVersion) => { +/******/ var version = findSingletonVersionKey(scope, key); +/******/ return get(scope[key][version]); /******/ }; /******/ var getSingletonVersion = (scope, scopeName, key, requiredVersion) => { /******/ var version = findSingletonVersionKey(scope, key); -/******/ if (!satisfy(requiredVersion, version)) typeof console !== "undefined" && console.warn && console.warn(getInvalidSingletonVersionMessage(key, version, requiredVersion)); +/******/ if (!satisfy(requiredVersion, version)) typeof console !== "undefined" && console.warn && console.warn(getInvalidSingletonVersionMessage(scope, key, version, requiredVersion)); /******/ return get(scope[key][version]); /******/ }; /******/ var getStrictSingletonVersion = (scope, scopeName, key, requiredVersion) => { /******/ var version = findSingletonVersionKey(scope, key); -/******/ if (!satisfy(requiredVersion, version)) throw new Error(getInvalidSingletonVersionMessage(key, version, requiredVersion)); +/******/ if (!satisfy(requiredVersion, version)) throw new Error(getInvalidSingletonVersionMessage(scope, key, version, requiredVersion)); /******/ return get(scope[key][version]); /******/ }; /******/ var findValidVersion = (scope, key, requiredVersion) => { @@ -758,18 +793,23 @@ module.exports = new Promise((resolve, reject) => { /******/ if(entry) return get(entry); /******/ throw new Error(getInvalidVersionMessage(scope, scopeName, key, requiredVersion)); /******/ }; +/******/ var warn = (msg) => { +/******/ typeof console !== "undefined" && console.warn ? console.warn(msg) : (() => { +/******/ +/******/ })() +/******/ }; /******/ var warnInvalidVersion = (scope, scopeName, key, requiredVersion) => { -/******/ typeof console !== "undefined" && console.warn && console.warn(getInvalidVersionMessage(scope, scopeName, key, requiredVersion)); +/******/ warn(getInvalidVersionMessage(scope, scopeName, key, requiredVersion)); /******/ }; /******/ var get = (entry) => { /******/ entry.loaded = 1; /******/ return entry.get() /******/ }; -/******/ var init = (fn) => function(scopeName, a, b, c) { +/******/ var init = (fn) => (function(scopeName, a, b, c) { /******/ var promise = __webpack_require__.I(scopeName); /******/ if (promise && promise.then) return promise.then(fn.bind(fn, scopeName, __webpack_require__.S[scopeName], a, b, c)); /******/ return fn(scopeName, __webpack_require__.S[scopeName], a, b, c); -/******/ }; +/******/ }); /******/ /******/ var load = /*#__PURE__*/ init((scopeName, scope, key) => { /******/ ensureExistence(scopeName, key); @@ -782,6 +822,10 @@ module.exports = new Promise((resolve, reject) => { /******/ ensureExistence(scopeName, key); /******/ return get(findValidVersion(scope, key, version) || warnInvalidVersion(scope, scopeName, key, version) || findVersion(scope, key)); /******/ }); +/******/ var loadSingleton = /*#__PURE__*/ init((scopeName, scope, key) => { +/******/ ensureExistence(scopeName, key); +/******/ return getSingleton(scope, scopeName, key); +/******/ }); /******/ var loadSingletonVersionCheck = /*#__PURE__*/ init((scopeName, scope, key, version) => { /******/ ensureExistence(scopeName, key); /******/ return getSingletonVersion(scope, scopeName, key, version); @@ -798,6 +842,10 @@ module.exports = new Promise((resolve, reject) => { /******/ if(!scope || !__webpack_require__.o(scope, key)) return fallback(); /******/ return get(findValidVersion(scope, key, version) || warnInvalidVersion(scope, scopeName, key, version) || findVersion(scope, key)); /******/ }); +/******/ var loadSingletonFallback = /*#__PURE__*/ init((scopeName, scope, key, fallback) => { +/******/ if(!scope || !__webpack_require__.o(scope, key)) return fallback(); +/******/ return getSingleton(scope, scopeName, key); +/******/ }); /******/ var loadSingletonVersionCheckFallback = /*#__PURE__*/ init((scopeName, scope, key, version, fallback) => { /******/ if(!scope || !__webpack_require__.o(scope, key)) return fallback(); /******/ return getSingletonVersion(scope, scopeName, key, version); @@ -812,14 +860,12 @@ module.exports = new Promise((resolve, reject) => { /******/ }); /******/ var installedModules = {}; /******/ var moduleToHandlerMapping = { -/******/ 5: () => loadSingletonVersionCheckFallback("default", "react", [4,17,0,1], () => __webpack_require__.e("node_modules_react_index_js-_11191").then(() => () => __webpack_require__(/*! react */ 25))), -/******/ 9: () => loadSingletonVersionCheckFallback("default", "react", [1,17,0,1], () => __webpack_require__.e("node_modules_react_index_js-_11191").then(() => () => __webpack_require__(/*! react */ 25))) +/******/ 5: () => (loadSingletonVersionCheckFallback("default", "react", [1,18,2,0], () => (__webpack_require__.e("node_modules_react_index_js").then(() => (() => (__webpack_require__(/*! react */ 23))))))) /******/ }; /******/ // no consumes in initial chunks /******/ var chunkMapping = { -/******/ "src_bootstrap_js-webpack_sharing_consume_default_react_react": [ -/******/ 5, -/******/ 9 +/******/ "src_bootstrap_js": [ +/******/ 5 /******/ ] /******/ }; /******/ __webpack_require__.f.consumes = (chunkId, promises) => { @@ -828,22 +874,22 @@ module.exports = new Promise((resolve, reject) => { /******/ if(__webpack_require__.o(installedModules, id)) return promises.push(installedModules[id]); /******/ var onFactory = (factory) => { /******/ installedModules[id] = 0; -/******/ __webpack_modules__[id] = (module) => { -/******/ delete __webpack_module_cache__[id]; +/******/ __webpack_require__.m[id] = (module) => { +/******/ delete __webpack_require__.c[id]; /******/ module.exports = factory(); /******/ } /******/ }; /******/ var onError = (error) => { /******/ delete installedModules[id]; -/******/ __webpack_modules__[id] = (module) => { -/******/ delete __webpack_module_cache__[id]; +/******/ __webpack_require__.m[id] = (module) => { +/******/ delete __webpack_require__.c[id]; /******/ throw error; /******/ } /******/ }; /******/ try { /******/ var promise = moduleToHandlerMapping[id](); /******/ if(promise.then) { -/******/ promises.push(installedModules[id] = promise.then(onFactory).catch(onError)); +/******/ promises.push(installedModules[id] = promise.then(onFactory)['catch'](onError)); /******/ } else onFactory(promise); /******/ } catch(e) { onError(e); } /******/ }); @@ -857,12 +903,11 @@ module.exports = new Promise((resolve, reject) => { /******/ /******/ // object to store loaded and loading chunks /******/ // undefined = chunk not loaded, null = chunk preloaded/prefetched -/******/ // Promise = chunk loading, 0 = chunk loaded +/******/ // [resolve, reject, Promise] = chunk loading, 0 = chunk loaded /******/ var installedChunks = { /******/ "app": 0 /******/ }; /******/ -/******/ /******/ __webpack_require__.f.j = (chunkId, promises) => { /******/ // JSONP chunk loading for javascript /******/ var installedChunkData = __webpack_require__.o(installedChunks, chunkId) ? installedChunks[chunkId] : undefined; @@ -874,9 +919,7 @@ module.exports = new Promise((resolve, reject) => { /******/ } else { /******/ if("webpack_container_remote_mfe-c_Component2" != chunkId) { /******/ // setup Promise in chunk cache -/******/ var promise = new Promise((resolve, reject) => { -/******/ installedChunkData = installedChunks[chunkId] = [resolve, reject]; -/******/ }); +/******/ var promise = new Promise((resolve, reject) => (installedChunkData = installedChunks[chunkId] = [resolve, reject])); /******/ promises.push(installedChunkData[2] = promise); /******/ /******/ // start chunk loading @@ -898,7 +941,7 @@ module.exports = new Promise((resolve, reject) => { /******/ } /******/ } /******/ }; -/******/ __webpack_require__.l(url, loadingEnded, "chunk-" + chunkId); +/******/ __webpack_require__.l(url, loadingEnded, "chunk-" + chunkId, chunkId); /******/ } else installedChunks[chunkId] = 0; /******/ } /******/ } @@ -912,39 +955,36 @@ module.exports = new Promise((resolve, reject) => { /******/ /******/ // no HMR manifest /******/ -/******/ // no deferred startup +/******/ // no on chunks loaded /******/ /******/ // install a JSONP callback for chunk loading /******/ var webpackJsonpCallback = (parentChunkLoadingFunction, data) => { /******/ var [chunkIds, moreModules, runtime] = data; /******/ // add "moreModules" to the modules object, /******/ // then flag all "chunkIds" as loaded and fire callback -/******/ var moduleId, chunkId, i = 0, resolves = []; +/******/ var moduleId, chunkId, i = 0; +/******/ if(chunkIds.some((id) => (installedChunks[id] !== 0))) { +/******/ for(moduleId in moreModules) { +/******/ if(__webpack_require__.o(moreModules, moduleId)) { +/******/ __webpack_require__.m[moduleId] = moreModules[moduleId]; +/******/ } +/******/ } +/******/ if(runtime) var result = runtime(__webpack_require__); +/******/ } +/******/ if(parentChunkLoadingFunction) parentChunkLoadingFunction(data); /******/ for(;i < chunkIds.length; i++) { /******/ chunkId = chunkIds[i]; /******/ if(__webpack_require__.o(installedChunks, chunkId) && installedChunks[chunkId]) { -/******/ resolves.push(installedChunks[chunkId][0]); +/******/ installedChunks[chunkId][0](); /******/ } /******/ installedChunks[chunkId] = 0; /******/ } -/******/ for(moduleId in moreModules) { -/******/ if(__webpack_require__.o(moreModules, moduleId)) { -/******/ __webpack_require__.m[moduleId] = moreModules[moduleId]; -/******/ } -/******/ } -/******/ if(runtime) runtime(__webpack_require__); -/******/ if(parentChunkLoadingFunction) parentChunkLoadingFunction(data); -/******/ while(resolves.length) { -/******/ resolves.shift()(); -/******/ } /******/ /******/ } /******/ /******/ var chunkLoadingGlobal = self["webpackChunkmodule_federation_aaa"] = self["webpackChunkmodule_federation_aaa"] || []; /******/ chunkLoadingGlobal.forEach(webpackJsonpCallback.bind(null, 0)); /******/ chunkLoadingGlobal.push = webpackJsonpCallback.bind(null, chunkLoadingGlobal.push.bind(chunkLoadingGlobal)); -/******/ -/******/ // no deferred startup /******/ })(); /******/ /************************************************************************/ @@ -953,23 +993,12 @@ module.exports = new Promise((resolve, reject) => { ``` js -(() => { -/*!**********************!*\ - !*** ./src/index.js ***! - \**********************/ -/*! unknown exports (runtime-defined) */ -/*! runtime requirements: __webpack_require__.e, __webpack_require__, __webpack_require__.* */ -// Sharing modules requires that all remotes are initialized -// and can provide shared modules to the common scope -// As this is an async operation we need an async boundary (import()) -// Using modules from remotes is also an async operation -// as chunks need to be loaded for the code of the remote module -// This also requires an async boundary (import()) -// At this point shared modules initialized and remote modules are loaded -Promise.all(/*! import() */[__webpack_require__.e("vendors-node_modules_date-fns_esm_locale_de_index_js-node_modules_react-dom_index_js"), __webpack_require__.e("src_bootstrap_js-webpack_sharing_consume_default_react_react")]).then(__webpack_require__.bind(__webpack_require__, /*! ./bootstrap */ 2)); // It's possible to place more code here to do stuff on page init -// but it can't use any of the shared modules or remote modules. -})(); - +/******/ +/******/ // module cache are used so entry inlining is disabled +/******/ // startup +/******/ // Load entry module and return exports +/******/ var __webpack_exports__ = __webpack_require__(0); +/******/ /******/ })() ; ``` @@ -977,7 +1006,7 @@ Promise.all(/*! import() */[__webpack_require__.e("vendors-node_modules_date-fns # dist/bbb/mfeBBB.js ```javascript -var mfeBBB;mfeBBB = +var mfeBBB; /******/ (() => { // webpackBootstrap /******/ "use strict"; /******/ var __webpack_modules__ = ([ @@ -985,13 +1014,16 @@ var mfeBBB;mfeBBB = /*!***********************!*\ !*** container entry ***! \***********************/ -/*! unknown exports (runtime-defined) */ +/*! namespace exports */ +/*! export get [provided] [maybe used in mfeBBB (runtime-defined)] [usage and provision prevents renaming] */ +/*! export init [provided] [maybe used in mfeBBB (runtime-defined)] [usage and provision prevents renaming] */ +/*! other exports [not provided] [maybe used in mfeBBB (runtime-defined)] */ /*! runtime requirements: __webpack_require__.d, __webpack_require__.o, __webpack_exports__, __webpack_require__.e, __webpack_require__, __webpack_require__.* */ /***/ ((__unused_webpack_module, exports, __webpack_require__) => { var moduleMap = { "./Component": () => { - return __webpack_require__.e("src-b_Component_js").then(() => () => (__webpack_require__(/*! ./src-b/Component */ 3))); + return __webpack_require__.e("src-b_Component_js").then(() => (() => ((__webpack_require__(/*! ./src-b/Component */ 3))))); } }; var get = (module, getScope) => { @@ -1008,8 +1040,8 @@ var get = (module, getScope) => { }; var init = (shareScope, initScope) => { if (!__webpack_require__.S) return; - var oldScope = __webpack_require__.S["default"]; var name = "default" + var oldScope = __webpack_require__.S[name]; if(oldScope && oldScope !== shareScope) throw new Error("Container initialization failed as it has already been initialized with a different share scope"); __webpack_require__.S[name] = shareScope; return __webpack_require__.I(name, initScope); @@ -1017,8 +1049,8 @@ var init = (shareScope, initScope) => { // This exports getters to disallow modifications __webpack_require__.d(exports, { - get: () => get, - init: () => init + get: () => (get), + init: () => (init) }); /***/ }) @@ -1035,8 +1067,9 @@ __webpack_require__.d(exports, { /******/ // The require function /******/ function __webpack_require__(moduleId) { /******/ // Check if module is in cache -/******/ if(__webpack_module_cache__[moduleId]) { -/******/ return __webpack_module_cache__[moduleId].exports; +/******/ var cachedModule = __webpack_module_cache__[moduleId]; +/******/ if (cachedModule !== undefined) { +/******/ return cachedModule.exports; /******/ } /******/ // Create a new module (and put it into the cache) /******/ var module = __webpack_module_cache__[moduleId] = { @@ -1055,14 +1088,17 @@ __webpack_require__.d(exports, { /******/ // expose the modules object (__webpack_modules__) /******/ __webpack_require__.m = __webpack_modules__; /******/ +/******/ // expose the module cache +/******/ __webpack_require__.c = __webpack_module_cache__; +/******/ /************************************************************************/ /******/ /* webpack/runtime/compat get default export */ /******/ (() => { /******/ // getDefaultExport function for compatibility with non-harmony modules /******/ __webpack_require__.n = (module) => { /******/ var getter = module && module.__esModule ? -/******/ () => module['default'] : -/******/ () => module; +/******/ () => (module['default']) : +/******/ () => (module); /******/ __webpack_require__.d(getter, { a: getter }); /******/ return getter; /******/ }; @@ -1104,7 +1140,7 @@ __webpack_require__.d(exports, { /******/ /******/ /* webpack/runtime/hasOwnProperty shorthand */ /******/ (() => { -/******/ __webpack_require__.o = (obj, prop) => Object.prototype.hasOwnProperty.call(obj, prop) +/******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop)) /******/ })(); /******/ /******/ /* webpack/runtime/load script */ @@ -1112,7 +1148,7 @@ __webpack_require__.d(exports, { /******/ var inProgress = {}; /******/ var dataWebpackPrefix = "module-federation-bbb:"; /******/ // loadScript function to load a script via script tag -/******/ __webpack_require__.l = (url, done, key) => { +/******/ __webpack_require__.l = (url, done, key, chunkId) => { /******/ if(inProgress[url]) { inProgress[url].push(done); return; } /******/ var script, needAttach; /******/ if(key !== undefined) { @@ -1142,10 +1178,9 @@ __webpack_require__.d(exports, { /******/ var doneFns = inProgress[url]; /******/ delete inProgress[url]; /******/ script.parentNode && script.parentNode.removeChild(script); -/******/ doneFns && doneFns.forEach((fn) => fn(event)); +/******/ doneFns && doneFns.forEach((fn) => (fn(event))); /******/ if(prev) return prev(event); /******/ } -/******/ ; /******/ var timeout = setTimeout(onScriptComplete.bind(null, undefined, { type: 'timeout', target: script }), 120000); /******/ script.onerror = onScriptComplete.bind(null, script.onerror); /******/ script.onload = onScriptComplete.bind(null, script.onload); @@ -1182,34 +1217,38 @@ __webpack_require__.d(exports, { /******/ if(!__webpack_require__.o(__webpack_require__.S, name)) __webpack_require__.S[name] = {}; /******/ // runs all init snippets from all modules reachable /******/ var scope = __webpack_require__.S[name]; -/******/ var warn = (msg) => typeof console !== "undefined" && console.warn && console.warn(msg);; +/******/ var warn = (msg) => { +/******/ typeof console !== "undefined" && console.warn ? console.warn(msg) : (() => { +/******/ +/******/ })() +/******/ }; /******/ var uniqueName = "module-federation-bbb"; -/******/ var register = (name, version, factory) => { +/******/ var register = (name, version, factory, eager) => { /******/ var versions = scope[name] = scope[name] || {}; /******/ var activeVersion = versions[version]; -/******/ if(!activeVersion || !activeVersion.loaded && uniqueName > activeVersion.from) versions[version] = { get: factory, from: uniqueName }; +/******/ if(!activeVersion || (!activeVersion.loaded && (!eager != !activeVersion.eager ? eager : uniqueName > activeVersion.from))) versions[version] = { get: factory, from: uniqueName, eager: !!eager }; /******/ }; /******/ var initExternal = (id) => { -/******/ var handleError = (err) => warn("Initialization of sharing external failed: " + err); +/******/ var handleError = (err) => (warn("Initialization of sharing external failed: " + err)); /******/ try { /******/ var module = __webpack_require__(id); /******/ if(!module) return; -/******/ var initFn = (module) => module && module.init && module.init(__webpack_require__.S[name], initScope) +/******/ var initFn = (module) => (module && module.init && module.init(__webpack_require__.S[name], initScope)) /******/ if(module.then) return promises.push(module.then(initFn, handleError)); /******/ var initResult = initFn(module); -/******/ if(initResult && initResult.then) return promises.push(initResult.catch(handleError)); +/******/ if(initResult && initResult.then) return promises.push(initResult['catch'](handleError)); /******/ } catch(err) { handleError(err); } /******/ } /******/ var promises = []; /******/ switch(name) { /******/ case "default": { -/******/ register("date-fns", "2.16.1", () => __webpack_require__.e("vendors-node_modules_date-fns_esm_index_js").then(() => () => __webpack_require__(/*! ../../node_modules/date-fns/esm/index.js */ 6))); -/******/ register("react", "17.0.1", () => __webpack_require__.e("node_modules_react_index_js").then(() => () => __webpack_require__(/*! ../../node_modules/react/index.js */ 238))); +/******/ register("date-fns", "2.29.3", () => (__webpack_require__.e("vendors-node_modules_date-fns_esm_index_js").then(() => (() => (__webpack_require__(/*! ../../node_modules/date-fns/esm/index.js */ 6)))))); +/******/ register("react", "18.2.0", () => (__webpack_require__.e("node_modules_react_index_js").then(() => (() => (__webpack_require__(/*! ../../node_modules/react/index.js */ 319)))))); /******/ } /******/ break; /******/ } /******/ if(!promises.length) return initPromises[name] = 1; -/******/ return initPromises[name] = Promise.all(promises).then(() => initPromises[name] = 1); +/******/ return initPromises[name] = Promise.all(promises).then(() => (initPromises[name] = 1)); /******/ }; /******/ })(); /******/ @@ -1230,7 +1269,7 @@ __webpack_require__.d(exports, { /******/ } /******/ var rangeToString = (range) => { /******/ // see webpack/lib/util/semver.js for original code -/******/ if(1===range.length)return"*";if(0 in range){var r="",n=range[0];r+=0==n?">=":-1==n?"<":1==n?"^":2==n?"~":n>0?"=":"!=";for(var e=1,a=1;a0?".":"")+(e=2,t)}return r}var g=[];for(a=1;a=":-1==r?"<":1==r?"^":2==r?"~":r>0?"=":"!=";for(var e=1,a=1;a0?".":"")+(e=2,t)}return n}var g=[];for(a=1;a { /******/ // see webpack/lib/util/semver.js for original code @@ -1254,17 +1293,21 @@ __webpack_require__.d(exports, { /******/ return !a || (!versions[a].loaded && versionLt(a, b)) ? b : a; /******/ }, 0); /******/ }; -/******/ var getInvalidSingletonVersionMessage = (key, version, requiredVersion) => { -/******/ return "Unsatisfied version " + version + " of shared singleton module " + key + " (required " + rangeToString(requiredVersion) + ")" +/******/ var getInvalidSingletonVersionMessage = (scope, key, version, requiredVersion) => { +/******/ return "Unsatisfied version " + version + " from " + (version && scope[key][version].from) + " of shared singleton module " + key + " (required " + rangeToString(requiredVersion) + ")" +/******/ }; +/******/ var getSingleton = (scope, scopeName, key, requiredVersion) => { +/******/ var version = findSingletonVersionKey(scope, key); +/******/ return get(scope[key][version]); /******/ }; /******/ var getSingletonVersion = (scope, scopeName, key, requiredVersion) => { /******/ var version = findSingletonVersionKey(scope, key); -/******/ if (!satisfy(requiredVersion, version)) typeof console !== "undefined" && console.warn && console.warn(getInvalidSingletonVersionMessage(key, version, requiredVersion)); +/******/ if (!satisfy(requiredVersion, version)) warn(getInvalidSingletonVersionMessage(scope, key, version, requiredVersion)); /******/ return get(scope[key][version]); /******/ }; /******/ var getStrictSingletonVersion = (scope, scopeName, key, requiredVersion) => { /******/ var version = findSingletonVersionKey(scope, key); -/******/ if (!satisfy(requiredVersion, version)) throw new Error(getInvalidSingletonVersionMessage(key, version, requiredVersion)); +/******/ if (!satisfy(requiredVersion, version)) throw new Error(getInvalidSingletonVersionMessage(scope, key, version, requiredVersion)); /******/ return get(scope[key][version]); /******/ }; /******/ var findValidVersion = (scope, key, requiredVersion) => { @@ -1287,18 +1330,23 @@ __webpack_require__.d(exports, { /******/ if(entry) return get(entry); /******/ throw new Error(getInvalidVersionMessage(scope, scopeName, key, requiredVersion)); /******/ }; +/******/ var warn = (msg) => { +/******/ typeof console !== "undefined" && console.warn ? console.warn(msg) : (() => { +/******/ +/******/ })() +/******/ }; /******/ var warnInvalidVersion = (scope, scopeName, key, requiredVersion) => { -/******/ typeof console !== "undefined" && console.warn && console.warn(getInvalidVersionMessage(scope, scopeName, key, requiredVersion)); +/******/ warn(getInvalidVersionMessage(scope, scopeName, key, requiredVersion)); /******/ }; /******/ var get = (entry) => { /******/ entry.loaded = 1; /******/ return entry.get() /******/ }; -/******/ var init = (fn) => function(scopeName, a, b, c) { +/******/ var init = (fn) => (function(scopeName, a, b, c) { /******/ var promise = __webpack_require__.I(scopeName); /******/ if (promise && promise.then) return promise.then(fn.bind(fn, scopeName, __webpack_require__.S[scopeName], a, b, c)); /******/ return fn(scopeName, __webpack_require__.S[scopeName], a, b, c); -/******/ }; +/******/ }); /******/ /******/ var load = /*#__PURE__*/ init((scopeName, scope, key) => { /******/ ensureExistence(scopeName, key); @@ -1311,6 +1359,10 @@ __webpack_require__.d(exports, { /******/ ensureExistence(scopeName, key); /******/ return get(findValidVersion(scope, key, version) || warnInvalidVersion(scope, scopeName, key, version) || findVersion(scope, key)); /******/ }); +/******/ var loadSingleton = /*#__PURE__*/ init((scopeName, scope, key) => { +/******/ ensureExistence(scopeName, key); +/******/ return getSingleton(scope, scopeName, key); +/******/ }); /******/ var loadSingletonVersionCheck = /*#__PURE__*/ init((scopeName, scope, key, version) => { /******/ ensureExistence(scopeName, key); /******/ return getSingletonVersion(scope, scopeName, key, version); @@ -1327,6 +1379,10 @@ __webpack_require__.d(exports, { /******/ if(!scope || !__webpack_require__.o(scope, key)) return fallback(); /******/ return get(findValidVersion(scope, key, version) || warnInvalidVersion(scope, scopeName, key, version) || findVersion(scope, key)); /******/ }); +/******/ var loadSingletonFallback = /*#__PURE__*/ init((scopeName, scope, key, fallback) => { +/******/ if(!scope || !__webpack_require__.o(scope, key)) return fallback(); +/******/ return getSingleton(scope, scopeName, key); +/******/ }); /******/ var loadSingletonVersionCheckFallback = /*#__PURE__*/ init((scopeName, scope, key, version, fallback) => { /******/ if(!scope || !__webpack_require__.o(scope, key)) return fallback(); /******/ return getSingletonVersion(scope, scopeName, key, version); @@ -1341,8 +1397,8 @@ __webpack_require__.d(exports, { /******/ }); /******/ var installedModules = {}; /******/ var moduleToHandlerMapping = { -/******/ 4: () => loadSingletonVersionCheckFallback("default", "react", [1,17,0,1], () => __webpack_require__.e("node_modules_react_index_js").then(() => () => __webpack_require__(/*! react */ 238))), -/******/ 5: () => loadStrictVersionCheckFallback("default", "date-fns", [1,2,15,0], () => __webpack_require__.e("vendors-node_modules_date-fns_esm_index_js").then(() => () => __webpack_require__(/*! date-fns */ 6))) +/******/ 4: () => (loadSingletonVersionCheckFallback("default", "react", [1,18,2,0], () => (__webpack_require__.e("node_modules_react_index_js").then(() => (() => (__webpack_require__(/*! react */ 319))))))), +/******/ 5: () => (loadStrictVersionCheckFallback("default", "date-fns", [1,2,15,0], () => (__webpack_require__.e("vendors-node_modules_date-fns_esm_index_js").then(() => (() => (__webpack_require__(/*! date-fns */ 6))))))) /******/ }; /******/ // no consumes in initial chunks /******/ var chunkMapping = { @@ -1357,22 +1413,22 @@ __webpack_require__.d(exports, { /******/ if(__webpack_require__.o(installedModules, id)) return promises.push(installedModules[id]); /******/ var onFactory = (factory) => { /******/ installedModules[id] = 0; -/******/ __webpack_modules__[id] = (module) => { -/******/ delete __webpack_module_cache__[id]; +/******/ __webpack_require__.m[id] = (module) => { +/******/ delete __webpack_require__.c[id]; /******/ module.exports = factory(); /******/ } /******/ }; /******/ var onError = (error) => { /******/ delete installedModules[id]; -/******/ __webpack_modules__[id] = (module) => { -/******/ delete __webpack_module_cache__[id]; +/******/ __webpack_require__.m[id] = (module) => { +/******/ delete __webpack_require__.c[id]; /******/ throw error; /******/ } /******/ }; /******/ try { /******/ var promise = moduleToHandlerMapping[id](); /******/ if(promise.then) { -/******/ promises.push(installedModules[id] = promise.then(onFactory).catch(onError)); +/******/ promises.push(installedModules[id] = promise.then(onFactory)['catch'](onError)); /******/ } else onFactory(promise); /******/ } catch(e) { onError(e); } /******/ }); @@ -1386,12 +1442,11 @@ __webpack_require__.d(exports, { /******/ /******/ // object to store loaded and loading chunks /******/ // undefined = chunk not loaded, null = chunk preloaded/prefetched -/******/ // Promise = chunk loading, 0 = chunk loaded +/******/ // [resolve, reject, Promise] = chunk loading, 0 = chunk loaded /******/ var installedChunks = { /******/ "mfeBBB": 0 /******/ }; /******/ -/******/ /******/ __webpack_require__.f.j = (chunkId, promises) => { /******/ // JSONP chunk loading for javascript /******/ var installedChunkData = __webpack_require__.o(installedChunks, chunkId) ? installedChunks[chunkId] : undefined; @@ -1403,9 +1458,7 @@ __webpack_require__.d(exports, { /******/ } else { /******/ if(true) { // all chunks have JS /******/ // setup Promise in chunk cache -/******/ var promise = new Promise((resolve, reject) => { -/******/ installedChunkData = installedChunks[chunkId] = [resolve, reject]; -/******/ }); +/******/ var promise = new Promise((resolve, reject) => (installedChunkData = installedChunks[chunkId] = [resolve, reject])); /******/ promises.push(installedChunkData[2] = promise); /******/ /******/ // start chunk loading @@ -1427,7 +1480,7 @@ __webpack_require__.d(exports, { /******/ } /******/ } /******/ }; -/******/ __webpack_require__.l(url, loadingEnded, "chunk-" + chunkId); +/******/ __webpack_require__.l(url, loadingEnded, "chunk-" + chunkId, chunkId); /******/ } else installedChunks[chunkId] = 0; /******/ } /******/ } @@ -1441,39 +1494,36 @@ __webpack_require__.d(exports, { /******/ /******/ // no HMR manifest /******/ -/******/ // no deferred startup +/******/ // no on chunks loaded /******/ /******/ // install a JSONP callback for chunk loading /******/ var webpackJsonpCallback = (parentChunkLoadingFunction, data) => { /******/ var [chunkIds, moreModules, runtime] = data; /******/ // add "moreModules" to the modules object, /******/ // then flag all "chunkIds" as loaded and fire callback -/******/ var moduleId, chunkId, i = 0, resolves = []; +/******/ var moduleId, chunkId, i = 0; +/******/ if(chunkIds.some((id) => (installedChunks[id] !== 0))) { +/******/ for(moduleId in moreModules) { +/******/ if(__webpack_require__.o(moreModules, moduleId)) { +/******/ __webpack_require__.m[moduleId] = moreModules[moduleId]; +/******/ } +/******/ } +/******/ if(runtime) var result = runtime(__webpack_require__); +/******/ } +/******/ if(parentChunkLoadingFunction) parentChunkLoadingFunction(data); /******/ for(;i < chunkIds.length; i++) { /******/ chunkId = chunkIds[i]; /******/ if(__webpack_require__.o(installedChunks, chunkId) && installedChunks[chunkId]) { -/******/ resolves.push(installedChunks[chunkId][0]); +/******/ installedChunks[chunkId][0](); /******/ } /******/ installedChunks[chunkId] = 0; /******/ } -/******/ for(moduleId in moreModules) { -/******/ if(__webpack_require__.o(moreModules, moduleId)) { -/******/ __webpack_require__.m[moduleId] = moreModules[moduleId]; -/******/ } -/******/ } -/******/ if(runtime) runtime(__webpack_require__); -/******/ if(parentChunkLoadingFunction) parentChunkLoadingFunction(data); -/******/ while(resolves.length) { -/******/ resolves.shift()(); -/******/ } /******/ /******/ } /******/ /******/ var chunkLoadingGlobal = self["webpackChunkmodule_federation_bbb"] = self["webpackChunkmodule_federation_bbb"] || []; /******/ chunkLoadingGlobal.forEach(webpackJsonpCallback.bind(null, 0)); /******/ chunkLoadingGlobal.push = webpackJsonpCallback.bind(null, chunkLoadingGlobal.push.bind(chunkLoadingGlobal)); -/******/ -/******/ // no deferred startup /******/ })(); /******/ /************************************************************************/ @@ -1482,10 +1532,13 @@ __webpack_require__.d(exports, { ``` js -/******/ // module exports must be returned from runtime so entry inlining is disabled +/******/ +/******/ // module cache are used so entry inlining is disabled /******/ // startup /******/ // Load entry module and return exports -/******/ return __webpack_require__(0); +/******/ var __webpack_exports__ = __webpack_require__(0); +/******/ mfeBBB = __webpack_exports__; +/******/ /******/ })() ; ``` @@ -1493,7 +1546,7 @@ __webpack_require__.d(exports, { # dist/ccc/mfeCCC.js ```javascript -var mfeCCC;mfeCCC = +var mfeCCC; /******/ (() => { // webpackBootstrap /******/ "use strict"; /******/ var __webpack_modules__ = ([ @@ -1501,16 +1554,19 @@ var mfeCCC;mfeCCC = /*!***********************!*\ !*** container entry ***! \***********************/ -/*! unknown exports (runtime-defined) */ +/*! namespace exports */ +/*! export get [provided] [maybe used in mfeCCC (runtime-defined)] [usage and provision prevents renaming] */ +/*! export init [provided] [maybe used in mfeCCC (runtime-defined)] [usage and provision prevents renaming] */ +/*! other exports [not provided] [maybe used in mfeCCC (runtime-defined)] */ /*! runtime requirements: __webpack_require__.d, __webpack_require__.o, __webpack_exports__, __webpack_require__.e, __webpack_require__, __webpack_require__.* */ /***/ ((__unused_webpack_module, exports, __webpack_require__) => { var moduleMap = { "./Component": () => { - return Promise.all([__webpack_require__.e("webpack_sharing_consume_default_react"), __webpack_require__.e("src-c_Component_js")]).then(() => () => (__webpack_require__(/*! ./src-c/Component */ 3))); + return Promise.all([__webpack_require__.e("webpack_sharing_consume_default_react"), __webpack_require__.e("src-c_Component_js")]).then(() => (() => ((__webpack_require__(/*! ./src-c/Component */ 3))))); }, "./Component2": () => { - return Promise.all([__webpack_require__.e("webpack_sharing_consume_default_react"), __webpack_require__.e("src-c_LazyComponent_js")]).then(() => () => (__webpack_require__(/*! ./src-c/LazyComponent */ 6))); + return Promise.all([__webpack_require__.e("webpack_sharing_consume_default_react"), __webpack_require__.e("src-c_LazyComponent_js")]).then(() => (() => ((__webpack_require__(/*! ./src-c/LazyComponent */ 6))))); } }; var get = (module, getScope) => { @@ -1527,8 +1583,8 @@ var get = (module, getScope) => { }; var init = (shareScope, initScope) => { if (!__webpack_require__.S) return; - var oldScope = __webpack_require__.S["default"]; var name = "default" + var oldScope = __webpack_require__.S[name]; if(oldScope && oldScope !== shareScope) throw new Error("Container initialization failed as it has already been initialized with a different share scope"); __webpack_require__.S[name] = shareScope; return __webpack_require__.I(name, initScope); @@ -1536,8 +1592,8 @@ var init = (shareScope, initScope) => { // This exports getters to disallow modifications __webpack_require__.d(exports, { - get: () => get, - init: () => init + get: () => (get), + init: () => (init) }); /***/ }) @@ -1554,8 +1610,9 @@ __webpack_require__.d(exports, { /******/ // The require function /******/ function __webpack_require__(moduleId) { /******/ // Check if module is in cache -/******/ if(__webpack_module_cache__[moduleId]) { -/******/ return __webpack_module_cache__[moduleId].exports; +/******/ var cachedModule = __webpack_module_cache__[moduleId]; +/******/ if (cachedModule !== undefined) { +/******/ return cachedModule.exports; /******/ } /******/ // Create a new module (and put it into the cache) /******/ var module = __webpack_module_cache__[moduleId] = { @@ -1574,14 +1631,17 @@ __webpack_require__.d(exports, { /******/ // expose the modules object (__webpack_modules__) /******/ __webpack_require__.m = __webpack_modules__; /******/ +/******/ // expose the module cache +/******/ __webpack_require__.c = __webpack_module_cache__; +/******/ /************************************************************************/ /******/ /* webpack/runtime/compat get default export */ /******/ (() => { /******/ // getDefaultExport function for compatibility with non-harmony modules /******/ __webpack_require__.n = (module) => { /******/ var getter = module && module.__esModule ? -/******/ () => module['default'] : -/******/ () => module; +/******/ () => (module['default']) : +/******/ () => (module); /******/ __webpack_require__.d(getter, { a: getter }); /******/ return getter; /******/ }; @@ -1635,7 +1695,7 @@ __webpack_require__.d(exports, { /******/ /******/ /* webpack/runtime/hasOwnProperty shorthand */ /******/ (() => { -/******/ __webpack_require__.o = (obj, prop) => Object.prototype.hasOwnProperty.call(obj, prop) +/******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop)) /******/ })(); /******/ /******/ /* webpack/runtime/load script */ @@ -1643,7 +1703,7 @@ __webpack_require__.d(exports, { /******/ var inProgress = {}; /******/ var dataWebpackPrefix = "module-federation-ccc:"; /******/ // loadScript function to load a script via script tag -/******/ __webpack_require__.l = (url, done, key) => { +/******/ __webpack_require__.l = (url, done, key, chunkId) => { /******/ if(inProgress[url]) { inProgress[url].push(done); return; } /******/ var script, needAttach; /******/ if(key !== undefined) { @@ -1673,10 +1733,9 @@ __webpack_require__.d(exports, { /******/ var doneFns = inProgress[url]; /******/ delete inProgress[url]; /******/ script.parentNode && script.parentNode.removeChild(script); -/******/ doneFns && doneFns.forEach((fn) => fn(event)); +/******/ doneFns && doneFns.forEach((fn) => (fn(event))); /******/ if(prev) return prev(event); /******/ } -/******/ ; /******/ var timeout = setTimeout(onScriptComplete.bind(null, undefined, { type: 'timeout', target: script }), 120000); /******/ script.onerror = onScriptComplete.bind(null, script.onerror); /******/ script.onload = onScriptComplete.bind(null, script.onload); @@ -1713,34 +1772,38 @@ __webpack_require__.d(exports, { /******/ if(!__webpack_require__.o(__webpack_require__.S, name)) __webpack_require__.S[name] = {}; /******/ // runs all init snippets from all modules reachable /******/ var scope = __webpack_require__.S[name]; -/******/ var warn = (msg) => typeof console !== "undefined" && console.warn && console.warn(msg);; +/******/ var warn = (msg) => { +/******/ typeof console !== "undefined" && console.warn ? console.warn(msg) : (() => { +/******/ +/******/ })() +/******/ }; /******/ var uniqueName = "module-federation-ccc"; -/******/ var register = (name, version, factory) => { +/******/ var register = (name, version, factory, eager) => { /******/ var versions = scope[name] = scope[name] || {}; /******/ var activeVersion = versions[version]; -/******/ if(!activeVersion || !activeVersion.loaded && uniqueName > activeVersion.from) versions[version] = { get: factory, from: uniqueName }; +/******/ if(!activeVersion || (!activeVersion.loaded && (!eager != !activeVersion.eager ? eager : uniqueName > activeVersion.from))) versions[version] = { get: factory, from: uniqueName, eager: !!eager }; /******/ }; /******/ var initExternal = (id) => { -/******/ var handleError = (err) => warn("Initialization of sharing external failed: " + err); +/******/ var handleError = (err) => (warn("Initialization of sharing external failed: " + err)); /******/ try { /******/ var module = __webpack_require__(id); /******/ if(!module) return; -/******/ var initFn = (module) => module && module.init && module.init(__webpack_require__.S[name], initScope) +/******/ var initFn = (module) => (module && module.init && module.init(__webpack_require__.S[name], initScope)) /******/ if(module.then) return promises.push(module.then(initFn, handleError)); /******/ var initResult = initFn(module); -/******/ if(initResult && initResult.then) return promises.push(initResult.catch(handleError)); +/******/ if(initResult && initResult.then) return promises.push(initResult['catch'](handleError)); /******/ } catch(err) { handleError(err); } /******/ } /******/ var promises = []; /******/ switch(name) { /******/ case "default": { -/******/ register("date-fns", "2.16.1", () => __webpack_require__.e("vendors-node_modules_date-fns_esm_index_js").then(() => () => __webpack_require__(/*! ../../node_modules/date-fns/esm/index.js */ 8))); -/******/ register("lodash/random", "4.17.20", () => __webpack_require__.e("vendors-node_modules_lodash_random_js").then(() => () => __webpack_require__(/*! ../../node_modules/lodash/random.js */ 240))); +/******/ register("date-fns", "2.29.3", () => (__webpack_require__.e("vendors-node_modules_date-fns_esm_index_js").then(() => (() => (__webpack_require__(/*! ../../node_modules/date-fns/esm/index.js */ 8)))))); +/******/ register("lodash/random", "4.17.21", () => (__webpack_require__.e("vendors-node_modules_lodash_random_js").then(() => (() => (__webpack_require__(/*! ../../node_modules/lodash/random.js */ 321)))))); /******/ } /******/ break; /******/ } /******/ if(!promises.length) return initPromises[name] = 1; -/******/ return initPromises[name] = Promise.all(promises).then(() => initPromises[name] = 1); +/******/ return initPromises[name] = Promise.all(promises).then(() => (initPromises[name] = 1)); /******/ }; /******/ })(); /******/ @@ -1761,7 +1824,7 @@ __webpack_require__.d(exports, { /******/ } /******/ var rangeToString = (range) => { /******/ // see webpack/lib/util/semver.js for original code -/******/ if(1===range.length)return"*";if(0 in range){var r="",n=range[0];r+=0==n?">=":-1==n?"<":1==n?"^":2==n?"~":n>0?"=":"!=";for(var e=1,a=1;a0?".":"")+(e=2,t)}return r}var g=[];for(a=1;a=":-1==r?"<":1==r?"^":2==r?"~":r>0?"=":"!=";for(var e=1,a=1;a0?".":"")+(e=2,t)}return n}var g=[];for(a=1;a { /******/ // see webpack/lib/util/semver.js for original code @@ -1785,17 +1848,21 @@ __webpack_require__.d(exports, { /******/ return !a || (!versions[a].loaded && versionLt(a, b)) ? b : a; /******/ }, 0); /******/ }; -/******/ var getInvalidSingletonVersionMessage = (key, version, requiredVersion) => { -/******/ return "Unsatisfied version " + version + " of shared singleton module " + key + " (required " + rangeToString(requiredVersion) + ")" +/******/ var getInvalidSingletonVersionMessage = (scope, key, version, requiredVersion) => { +/******/ return "Unsatisfied version " + version + " from " + (version && scope[key][version].from) + " of shared singleton module " + key + " (required " + rangeToString(requiredVersion) + ")" +/******/ }; +/******/ var getSingleton = (scope, scopeName, key, requiredVersion) => { +/******/ var version = findSingletonVersionKey(scope, key); +/******/ return get(scope[key][version]); /******/ }; /******/ var getSingletonVersion = (scope, scopeName, key, requiredVersion) => { /******/ var version = findSingletonVersionKey(scope, key); -/******/ if (!satisfy(requiredVersion, version)) typeof console !== "undefined" && console.warn && console.warn(getInvalidSingletonVersionMessage(key, version, requiredVersion)); +/******/ if (!satisfy(requiredVersion, version)) warn(getInvalidSingletonVersionMessage(scope, key, version, requiredVersion)); /******/ return get(scope[key][version]); /******/ }; /******/ var getStrictSingletonVersion = (scope, scopeName, key, requiredVersion) => { /******/ var version = findSingletonVersionKey(scope, key); -/******/ if (!satisfy(requiredVersion, version)) throw new Error(getInvalidSingletonVersionMessage(key, version, requiredVersion)); +/******/ if (!satisfy(requiredVersion, version)) throw new Error(getInvalidSingletonVersionMessage(scope, key, version, requiredVersion)); /******/ return get(scope[key][version]); /******/ }; /******/ var findValidVersion = (scope, key, requiredVersion) => { @@ -1818,18 +1885,23 @@ __webpack_require__.d(exports, { /******/ if(entry) return get(entry); /******/ throw new Error(getInvalidVersionMessage(scope, scopeName, key, requiredVersion)); /******/ }; +/******/ var warn = (msg) => { +/******/ typeof console !== "undefined" && console.warn ? console.warn(msg) : (() => { +/******/ +/******/ })() +/******/ }; /******/ var warnInvalidVersion = (scope, scopeName, key, requiredVersion) => { -/******/ typeof console !== "undefined" && console.warn && console.warn(getInvalidVersionMessage(scope, scopeName, key, requiredVersion)); +/******/ warn(getInvalidVersionMessage(scope, scopeName, key, requiredVersion)); /******/ }; /******/ var get = (entry) => { /******/ entry.loaded = 1; /******/ return entry.get() /******/ }; -/******/ var init = (fn) => function(scopeName, a, b, c) { +/******/ var init = (fn) => (function(scopeName, a, b, c) { /******/ var promise = __webpack_require__.I(scopeName); /******/ if (promise && promise.then) return promise.then(fn.bind(fn, scopeName, __webpack_require__.S[scopeName], a, b, c)); /******/ return fn(scopeName, __webpack_require__.S[scopeName], a, b, c); -/******/ }; +/******/ }); /******/ /******/ var load = /*#__PURE__*/ init((scopeName, scope, key) => { /******/ ensureExistence(scopeName, key); @@ -1842,6 +1914,10 @@ __webpack_require__.d(exports, { /******/ ensureExistence(scopeName, key); /******/ return get(findValidVersion(scope, key, version) || warnInvalidVersion(scope, scopeName, key, version) || findVersion(scope, key)); /******/ }); +/******/ var loadSingleton = /*#__PURE__*/ init((scopeName, scope, key) => { +/******/ ensureExistence(scopeName, key); +/******/ return getSingleton(scope, scopeName, key); +/******/ }); /******/ var loadSingletonVersionCheck = /*#__PURE__*/ init((scopeName, scope, key, version) => { /******/ ensureExistence(scopeName, key); /******/ return getSingletonVersion(scope, scopeName, key, version); @@ -1858,6 +1934,10 @@ __webpack_require__.d(exports, { /******/ if(!scope || !__webpack_require__.o(scope, key)) return fallback(); /******/ return get(findValidVersion(scope, key, version) || warnInvalidVersion(scope, scopeName, key, version) || findVersion(scope, key)); /******/ }); +/******/ var loadSingletonFallback = /*#__PURE__*/ init((scopeName, scope, key, fallback) => { +/******/ if(!scope || !__webpack_require__.o(scope, key)) return fallback(); +/******/ return getSingleton(scope, scopeName, key); +/******/ }); /******/ var loadSingletonVersionCheckFallback = /*#__PURE__*/ init((scopeName, scope, key, version, fallback) => { /******/ if(!scope || !__webpack_require__.o(scope, key)) return fallback(); /******/ return getSingletonVersion(scope, scopeName, key, version); @@ -1872,9 +1952,9 @@ __webpack_require__.d(exports, { /******/ }); /******/ var installedModules = {}; /******/ var moduleToHandlerMapping = { -/******/ 4: () => loadSingletonVersionCheck("default", "react", [1,17,0,1]), -/******/ 5: () => loadStrictVersionCheckFallback("default", "date-fns", [1,2,15,0], () => __webpack_require__.e("vendors-node_modules_date-fns_esm_index_js").then(() => () => __webpack_require__(/*! date-fns */ 8))), -/******/ 7: () => loadStrictVersionCheckFallback("default", "lodash/random", [1,4,17,19], () => __webpack_require__.e("vendors-node_modules_lodash_random_js").then(() => () => __webpack_require__(/*! lodash/random */ 240))) +/******/ 4: () => (loadSingletonVersionCheck("default", "react", [1,18,2,0])), +/******/ 5: () => (loadStrictVersionCheckFallback("default", "date-fns", [1,2,15,0], () => (__webpack_require__.e("vendors-node_modules_date-fns_esm_index_js").then(() => (() => (__webpack_require__(/*! date-fns */ 8))))))), +/******/ 7: () => (loadStrictVersionCheckFallback("default", "lodash/random", [1,4,17,19], () => (__webpack_require__.e("vendors-node_modules_lodash_random_js").then(() => (() => (__webpack_require__(/*! lodash/random */ 321))))))) /******/ }; /******/ // no consumes in initial chunks /******/ var chunkMapping = { @@ -1894,22 +1974,22 @@ __webpack_require__.d(exports, { /******/ if(__webpack_require__.o(installedModules, id)) return promises.push(installedModules[id]); /******/ var onFactory = (factory) => { /******/ installedModules[id] = 0; -/******/ __webpack_modules__[id] = (module) => { -/******/ delete __webpack_module_cache__[id]; +/******/ __webpack_require__.m[id] = (module) => { +/******/ delete __webpack_require__.c[id]; /******/ module.exports = factory(); /******/ } /******/ }; /******/ var onError = (error) => { /******/ delete installedModules[id]; -/******/ __webpack_modules__[id] = (module) => { -/******/ delete __webpack_module_cache__[id]; +/******/ __webpack_require__.m[id] = (module) => { +/******/ delete __webpack_require__.c[id]; /******/ throw error; /******/ } /******/ }; /******/ try { /******/ var promise = moduleToHandlerMapping[id](); /******/ if(promise.then) { -/******/ promises.push(installedModules[id] = promise.then(onFactory).catch(onError)); +/******/ promises.push(installedModules[id] = promise.then(onFactory)['catch'](onError)); /******/ } else onFactory(promise); /******/ } catch(e) { onError(e); } /******/ }); @@ -1923,12 +2003,11 @@ __webpack_require__.d(exports, { /******/ /******/ // object to store loaded and loading chunks /******/ // undefined = chunk not loaded, null = chunk preloaded/prefetched -/******/ // Promise = chunk loading, 0 = chunk loaded +/******/ // [resolve, reject, Promise] = chunk loading, 0 = chunk loaded /******/ var installedChunks = { /******/ "mfeCCC": 0 /******/ }; /******/ -/******/ /******/ __webpack_require__.f.j = (chunkId, promises) => { /******/ // JSONP chunk loading for javascript /******/ var installedChunkData = __webpack_require__.o(installedChunks, chunkId) ? installedChunks[chunkId] : undefined; @@ -1940,9 +2019,7 @@ __webpack_require__.d(exports, { /******/ } else { /******/ if("webpack_sharing_consume_default_react" != chunkId) { /******/ // setup Promise in chunk cache -/******/ var promise = new Promise((resolve, reject) => { -/******/ installedChunkData = installedChunks[chunkId] = [resolve, reject]; -/******/ }); +/******/ var promise = new Promise((resolve, reject) => (installedChunkData = installedChunks[chunkId] = [resolve, reject])); /******/ promises.push(installedChunkData[2] = promise); /******/ /******/ // start chunk loading @@ -1964,7 +2041,7 @@ __webpack_require__.d(exports, { /******/ } /******/ } /******/ }; -/******/ __webpack_require__.l(url, loadingEnded, "chunk-" + chunkId); +/******/ __webpack_require__.l(url, loadingEnded, "chunk-" + chunkId, chunkId); /******/ } else installedChunks[chunkId] = 0; /******/ } /******/ } @@ -1978,39 +2055,36 @@ __webpack_require__.d(exports, { /******/ /******/ // no HMR manifest /******/ -/******/ // no deferred startup +/******/ // no on chunks loaded /******/ /******/ // install a JSONP callback for chunk loading /******/ var webpackJsonpCallback = (parentChunkLoadingFunction, data) => { /******/ var [chunkIds, moreModules, runtime] = data; /******/ // add "moreModules" to the modules object, /******/ // then flag all "chunkIds" as loaded and fire callback -/******/ var moduleId, chunkId, i = 0, resolves = []; +/******/ var moduleId, chunkId, i = 0; +/******/ if(chunkIds.some((id) => (installedChunks[id] !== 0))) { +/******/ for(moduleId in moreModules) { +/******/ if(__webpack_require__.o(moreModules, moduleId)) { +/******/ __webpack_require__.m[moduleId] = moreModules[moduleId]; +/******/ } +/******/ } +/******/ if(runtime) var result = runtime(__webpack_require__); +/******/ } +/******/ if(parentChunkLoadingFunction) parentChunkLoadingFunction(data); /******/ for(;i < chunkIds.length; i++) { /******/ chunkId = chunkIds[i]; /******/ if(__webpack_require__.o(installedChunks, chunkId) && installedChunks[chunkId]) { -/******/ resolves.push(installedChunks[chunkId][0]); +/******/ installedChunks[chunkId][0](); /******/ } /******/ installedChunks[chunkId] = 0; /******/ } -/******/ for(moduleId in moreModules) { -/******/ if(__webpack_require__.o(moreModules, moduleId)) { -/******/ __webpack_require__.m[moduleId] = moreModules[moduleId]; -/******/ } -/******/ } -/******/ if(runtime) runtime(__webpack_require__); -/******/ if(parentChunkLoadingFunction) parentChunkLoadingFunction(data); -/******/ while(resolves.length) { -/******/ resolves.shift()(); -/******/ } /******/ /******/ } /******/ /******/ var chunkLoadingGlobal = self["webpackChunkmodule_federation_ccc"] = self["webpackChunkmodule_federation_ccc"] || []; /******/ chunkLoadingGlobal.forEach(webpackJsonpCallback.bind(null, 0)); /******/ chunkLoadingGlobal.push = webpackJsonpCallback.bind(null, chunkLoadingGlobal.push.bind(chunkLoadingGlobal)); -/******/ -/******/ // no deferred startup /******/ })(); /******/ /************************************************************************/ @@ -2019,10 +2093,13 @@ __webpack_require__.d(exports, { ``` js -/******/ // module exports must be returned from runtime so entry inlining is disabled +/******/ +/******/ // module cache are used so entry inlining is disabled /******/ // startup /******/ // Load entry module and return exports -/******/ return __webpack_require__(0); +/******/ var __webpack_exports__ = __webpack_require__(0); +/******/ mfeCCC = __webpack_exports__; +/******/ /******/ })() ; ``` @@ -2033,215 +2110,201 @@ __webpack_require__.d(exports, { ``` app: - asset vendors-node_modules_date-fns_esm_locale_de_index_js-node_modules_react-dom_index_js.js 163 KiB [emitted] (id hint: vendors) - asset app.js 29.9 KiB [emitted] (name: app) - asset node_modules_react_index_js-_11190.js 16.9 KiB [emitted] - asset node_modules_react_index_js-_11191.js 14.4 KiB [emitted] - asset src_bootstrap_js-webpack_sharing_consume_default_react_react.js 5.03 KiB [emitted] - chunk (runtime: app) app.js (app) 669 bytes (javascript) 42 bytes (share-init) 19.2 KiB (runtime) [entry] [rendered] + asset vendors-node_modules_date-fns_esm_locale_de_index_js-node_modules_react-dom_index_js.js 171 KiB [emitted] (id hint: vendors) + asset app.js 30.8 KiB [emitted] (name: app) + asset node_modules_react_index_js.js 16.6 KiB [emitted] + asset src_bootstrap_js.js 4.98 KiB [emitted] + chunk (runtime: app) app.js (app) 672 bytes (javascript) 42 bytes (share-init) 19.6 KiB (runtime) [entry] [rendered] > ./src/index.js app - runtime modules 19.2 KiB 13 modules - built modules 669 bytes (javascript) 42 bytes (share-init) [built] - ./src/index.js 585 bytes [built] [code generated] + runtime modules 19.6 KiB 13 modules + built modules 672 bytes (javascript) 42 bytes (share-init) [built] + ./src/index.js 588 bytes [built] [code generated] external "mfeBBB@/dist/bbb/mfeBBB.js" 42 bytes [built] [code generated] external "mfeCCC@/dist/ccc/mfeCCC.js" 42 bytes [built] [code generated] - provide shared module (default) react@17.0.1 = ../../node_modules/react/index.js 42 bytes [built] [code generated] - chunk (runtime: app) node_modules_react_index_js-_11190.js 8.54 KiB [rendered] - > provide shared module (default) react@17.0.1 = ../../node_modules/react/index.js - dependent modules 8.36 KiB [dependent] 2 modules - ../../node_modules/react/index.js 190 bytes [built] [code generated] - chunk (runtime: app) node_modules_react_index_js-_11191.js 6.48 KiB [rendered] - > consume shared module (default) react@=17.0.1 (singleton) (fallback: ../../node_modules/react/index.js) - > consume shared module (default) react@^17.0.1 (singleton) (fallback: ../../node_modules/react/index.js) - dependent modules 6.3 KiB [dependent] 1 module + provide shared module (default) react@18.2.0 = ../../node_modules/react/index.js 42 bytes [built] [code generated] + chunk (runtime: app) node_modules_react_index_js.js 6.94 KiB [rendered] + > provide shared module (default) react@18.2.0 = ../../node_modules/react/index.js + > consume shared module (default) react@^18.2.0 (singleton) (fallback: ../../node_modules/react/index.js) + dependent modules 6.75 KiB [dependent] 1 module ../../node_modules/react/index.js 190 bytes [built] [code generated] - chunk (runtime: app) src_bootstrap_js-webpack_sharing_consume_default_react_react.js 1.56 KiB (javascript) 84 bytes (consume-shared) 12 bytes (remote) 12 bytes (share-init) [rendered] - > ./bootstrap ./src/index.js 8:0-21 - dependent modules 1.19 KiB (javascript) 42 bytes (consume-shared) 12 bytes (remote) 12 bytes (share-init) [dependent] 4 modules - built modules 382 bytes (javascript) 42 bytes (consume-shared) [built] - ./src/bootstrap.js 382 bytes [built] [code generated] - consume shared module (default) react@=17.0.1 (singleton) (fallback: ../../node_modules/react/index.js) 42 bytes [built] [code generated] - chunk (runtime: app) vendors-node_modules_date-fns_esm_locale_de_index_js-node_modules_react-dom_index_js.js (id hint: vendors) 142 KiB [rendered] split chunk (cache group: defaultVendors) - > ./bootstrap ./src/index.js 8:0-21 - dependent modules 139 KiB [dependent] 13 modules + chunk (runtime: app) src_bootstrap_js.js 1.56 KiB (javascript) 42 bytes (consume-shared) 12 bytes (remote) 12 bytes (share-init) [rendered] + > ./bootstrap ./src/index.js 10:0-21 + dependent modules 1.18 KiB (javascript) 42 bytes (consume-shared) 12 bytes (remote) 12 bytes (share-init) [dependent] 4 modules + ./src/bootstrap.js 381 bytes [built] [code generated] + chunk (runtime: app) vendors-node_modules_date-fns_esm_locale_de_index_js-node_modules_react-dom_index_js.js (id hint: vendors) 151 KiB [rendered] split chunk (cache group: defaultVendors) + > ./bootstrap ./src/index.js 10:0-21 + dependent modules 148 KiB [dependent] 12 modules cacheable modules 2.3 KiB ../../node_modules/date-fns/esm/locale/de/index.js 995 bytes [built] [code generated] ../../node_modules/react-dom/index.js 1.33 KiB [built] [code generated] chunk (runtime: app) 6 bytes (remote) 6 bytes (share-init) - > mfe-c/Component2 ./src/App.js 8:49-75 + > mfe-c/Component2 ./src/App.js 7:49-75 remote mfe-c/Component2 6 bytes (remote) 6 bytes (share-init) [built] [code generated] - app (webpack 5.11.1) compiled successfully + app (webpack 5.78.0) compiled successfully mfe-b: - asset vendors-node_modules_date-fns_esm_index_js.js 857 KiB [emitted] (id hint: vendors) - asset mfeBBB.js 24.3 KiB [emitted] (name: mfeBBB) - asset node_modules_react_index_js.js 16.9 KiB [emitted] - asset src-b_Component_js.js 2.24 KiB [emitted] - chunk (runtime: mfeBBB) mfeBBB.js (mfeBBB) 42 bytes (javascript) 84 bytes (share-init) 16.4 KiB (runtime) [entry] [rendered] + asset vendors-node_modules_date-fns_esm_index_js.js 1.12 MiB [emitted] (id hint: vendors) + asset mfeBBB.js 25.5 KiB [emitted] (name: mfeBBB) + asset node_modules_react_index_js.js 16.7 KiB [emitted] + asset src-b_Component_js.js 2.25 KiB [emitted] + chunk (runtime: mfeBBB) mfeBBB.js (mfeBBB) 42 bytes (javascript) 84 bytes (share-init) 17 KiB (runtime) [entry] [rendered] > mfeBBB - runtime modules 16.4 KiB 11 modules + runtime modules 17 KiB 11 modules built modules 42 bytes (javascript) 84 bytes (share-init) [built] container entry 42 bytes [built] [code generated] - provide shared module (default) date-fns@2.16.1 = ../../node_modules/date-fns/esm/index.js 42 bytes [built] [code generated] - provide shared module (default) react@17.0.1 = ../../node_modules/react/index.js 42 bytes [built] [code generated] - chunk (runtime: mfeBBB) node_modules_react_index_js.js 8.54 KiB [rendered] - > provide shared module (default) react@17.0.1 = ../../node_modules/react/index.js - > consume shared module (default) react@^17.0.1 (singleton) (fallback: ../../node_modules/react/index.js) - dependent modules 8.36 KiB [dependent] 2 modules + provide shared module (default) date-fns@2.29.3 = ../../node_modules/date-fns/esm/index.js 42 bytes [built] [code generated] + provide shared module (default) react@18.2.0 = ../../node_modules/react/index.js 42 bytes [built] [code generated] + chunk (runtime: mfeBBB) node_modules_react_index_js.js 6.94 KiB [rendered] + > provide shared module (default) react@18.2.0 = ../../node_modules/react/index.js + > consume shared module (default) react@^18.2.0 (singleton) (fallback: ../../node_modules/react/index.js) + dependent modules 6.75 KiB [dependent] 1 module ../../node_modules/react/index.js 190 bytes [built] [code generated] - chunk (runtime: mfeBBB) src-b_Component_js.js 753 bytes (javascript) 84 bytes (consume-shared) [rendered] + chunk (runtime: mfeBBB) src-b_Component_js.js 752 bytes (javascript) 84 bytes (consume-shared) [rendered] > ./src-b/Component container entry ./Component dependent modules 84 bytes [dependent] 2 modules - ./src-b/Component.js 753 bytes [built] [code generated] - chunk (runtime: mfeBBB) vendors-node_modules_date-fns_esm_index_js.js (id hint: vendors) 509 KiB [rendered] reused as split chunk (cache group: defaultVendors) - > provide shared module (default) date-fns@2.16.1 = ../../node_modules/date-fns/esm/index.js + ./src-b/Component.js 752 bytes [built] [code generated] + chunk (runtime: mfeBBB) vendors-node_modules_date-fns_esm_index_js.js (id hint: vendors) 679 KiB [rendered] reused as split chunk (cache group: defaultVendors) + > provide shared module (default) date-fns@2.29.3 = ../../node_modules/date-fns/esm/index.js > consume shared module (default) date-fns@^2.15.0 (strict) (fallback: ../../node_modules/date-fns/esm/index.js) - dependent modules 496 KiB [dependent] 231 modules - ../../node_modules/date-fns/esm/index.js 13.2 KiB [built] [code generated] - mfe-b (webpack 5.11.1) compiled successfully + dependent modules 663 KiB [dependent] 312 modules + ../../node_modules/date-fns/esm/index.js 16.2 KiB [built] [code generated] + mfe-b (webpack 5.78.0) compiled successfully mfe-c: - assets by chunk 880 KiB (id hint: vendors) - asset vendors-node_modules_date-fns_esm_index_js.js 857 KiB [emitted] (id hint: vendors) - asset vendors-node_modules_lodash_random_js.js 23.1 KiB [emitted] (id hint: vendors) - asset mfeCCC.js 25.3 KiB [emitted] (name: mfeCCC) + assets by chunk 1.15 MiB (id hint: vendors) + asset vendors-node_modules_date-fns_esm_index_js.js 1.12 MiB [emitted] (id hint: vendors) + asset vendors-node_modules_lodash_random_js.js 24.8 KiB [emitted] (id hint: vendors) + asset mfeCCC.js 26.5 KiB [emitted] (name: mfeCCC) asset src-c_LazyComponent_js.js 2.05 KiB [emitted] asset src-c_Component_js.js 1.97 KiB [emitted] - chunk (runtime: mfeCCC) mfeCCC.js (mfeCCC) 42 bytes (javascript) 84 bytes (share-init) 16.8 KiB (runtime) [entry] [rendered] + chunk (runtime: mfeCCC) mfeCCC.js (mfeCCC) 42 bytes (javascript) 84 bytes (share-init) 17.5 KiB (runtime) [entry] [rendered] > mfeCCC - runtime modules 16.8 KiB 12 modules + runtime modules 17.5 KiB 12 modules built modules 42 bytes (javascript) 84 bytes (share-init) [built] container entry 42 bytes [built] [code generated] - provide shared module (default) date-fns@2.16.1 = ../../node_modules/date-fns/esm/index.js 42 bytes [built] [code generated] - provide shared module (default) lodash/random@4.17.20 = ../../node_modules/lodash/random.js 42 bytes [built] [code generated] - chunk (runtime: mfeCCC) src-c_Component_js.js 469 bytes (javascript) 42 bytes (consume-shared) [rendered] + provide shared module (default) date-fns@2.29.3 = ../../node_modules/date-fns/esm/index.js 42 bytes [built] [code generated] + provide shared module (default) lodash/random@4.17.21 = ../../node_modules/lodash/random.js 42 bytes [built] [code generated] + chunk (runtime: mfeCCC) src-c_Component_js.js 467 bytes (javascript) 42 bytes (consume-shared) [rendered] > ./src-c/Component container entry ./Component dependent modules 42 bytes [dependent] 1 module - ./src-c/Component.js 469 bytes [built] [code generated] - chunk (runtime: mfeCCC) src-c_LazyComponent_js.js 506 bytes (javascript) 42 bytes (consume-shared) [rendered] + ./src-c/Component.js 467 bytes [built] [code generated] + chunk (runtime: mfeCCC) src-c_LazyComponent_js.js 504 bytes (javascript) 42 bytes (consume-shared) [rendered] > ./src-c/LazyComponent container entry ./Component2 dependent modules 42 bytes [dependent] 1 module - ./src-c/LazyComponent.js 506 bytes [built] [code generated] - chunk (runtime: mfeCCC) vendors-node_modules_date-fns_esm_index_js.js (id hint: vendors) 509 KiB [rendered] reused as split chunk (cache group: defaultVendors) - > provide shared module (default) date-fns@2.16.1 = ../../node_modules/date-fns/esm/index.js + ./src-c/LazyComponent.js 504 bytes [built] [code generated] + chunk (runtime: mfeCCC) vendors-node_modules_date-fns_esm_index_js.js (id hint: vendors) 679 KiB [rendered] reused as split chunk (cache group: defaultVendors) + > provide shared module (default) date-fns@2.29.3 = ../../node_modules/date-fns/esm/index.js > consume shared module (default) date-fns@^2.15.0 (strict) (fallback: ../../node_modules/date-fns/esm/index.js) - dependent modules 496 KiB [dependent] 231 modules - ../../node_modules/date-fns/esm/index.js 13.2 KiB [built] [code generated] - chunk (runtime: mfeCCC) vendors-node_modules_lodash_random_js.js (id hint: vendors) 15.2 KiB [rendered] reused as split chunk (cache group: defaultVendors) - > provide shared module (default) lodash/random@4.17.20 = ../../node_modules/lodash/random.js + dependent modules 663 KiB [dependent] 312 modules + ../../node_modules/date-fns/esm/index.js 16.2 KiB [built] [code generated] + chunk (runtime: mfeCCC) vendors-node_modules_lodash_random_js.js (id hint: vendors) 16 KiB [rendered] reused as split chunk (cache group: defaultVendors) + > provide shared module (default) lodash/random@4.17.21 = ../../node_modules/lodash/random.js > consume shared module (default) lodash/random@^4.17.19 (strict) (fallback: ../../node_modules/lodash/random.js) - dependent modules 12.8 KiB [dependent] 18 modules + dependent modules 13.7 KiB [dependent] 20 modules ../../node_modules/lodash/random.js 2.32 KiB [built] [code generated] chunk (runtime: mfeCCC) 42 bytes split chunk (cache group: default) > ./src-c/Component container entry ./Component > ./src-c/LazyComponent container entry ./Component2 - consume shared module (default) react@^17.0.1 (singleton) 42 bytes [built] [code generated] - mfe-c (webpack 5.11.1) compiled successfully + consume shared module (default) react@^18.2.0 (singleton) 42 bytes [built] [code generated] + mfe-c (webpack 5.78.0) compiled successfully ``` ## Production mode ``` app: - asset vendors-node_modules_date-fns_esm_locale_de_index_js-node_modules_react-dom_index_js.js 128 KiB [emitted] [minimized] (id hint: vendors) 1 related asset - asset app.js 7.57 KiB [emitted] [minimized] (name: app) - asset node_modules_react_index_js-_11190.js 7.02 KiB [emitted] [minimized] 1 related asset - asset node_modules_react_index_js-_11191.js 6.07 KiB [emitted] [minimized] 1 related asset - asset src_bootstrap_js-webpack_sharing_consume_default_react_react.js 1.08 KiB [emitted] [minimized] - chunk (runtime: app) app.js (app) 669 bytes (javascript) 42 bytes (share-init) 19.2 KiB (runtime) [entry] [rendered] + asset vendors-node_modules_date-fns_esm_locale_de_index_js-node_modules_react-dom_index_js.js 139 KiB [emitted] [minimized] (id hint: vendors) 1 related asset + asset app.js 7.42 KiB [emitted] [minimized] (name: app) + asset node_modules_react_index_js.js 6.5 KiB [emitted] [minimized] 1 related asset + asset src_bootstrap_js.js 1.04 KiB [emitted] [minimized] + chunk (runtime: app) app.js (app) 672 bytes (javascript) 42 bytes (share-init) 19.5 KiB (runtime) [entry] [rendered] > ./src/index.js app - runtime modules 19.2 KiB 13 modules - built modules 669 bytes (javascript) 42 bytes (share-init) [built] - ./src/index.js 585 bytes [built] [code generated] + runtime modules 19.5 KiB 13 modules + built modules 672 bytes (javascript) 42 bytes (share-init) [built] + ./src/index.js 588 bytes [built] [code generated] external "mfeBBB@/dist/bbb/mfeBBB.js" 42 bytes [built] [code generated] external "mfeCCC@/dist/ccc/mfeCCC.js" 42 bytes [built] [code generated] - provide shared module (default) react@17.0.1 = ../../node_modules/react/index.js 42 bytes [built] [code generated] - chunk (runtime: app) node_modules_react_index_js-_11190.js 8.54 KiB [rendered] - > provide shared module (default) react@17.0.1 = ../../node_modules/react/index.js - dependent modules 8.36 KiB [dependent] 2 modules - ../../node_modules/react/index.js 190 bytes [built] [code generated] - chunk (runtime: app) node_modules_react_index_js-_11191.js 6.48 KiB [rendered] - > consume shared module (default) react@=17.0.1 (singleton) (fallback: ../../node_modules/react/index.js) - > consume shared module (default) react@^17.0.1 (singleton) (fallback: ../../node_modules/react/index.js) - dependent modules 6.3 KiB [dependent] 1 module + provide shared module (default) react@18.2.0 = ../../node_modules/react/index.js 42 bytes [built] [code generated] + chunk (runtime: app) node_modules_react_index_js.js 6.94 KiB [rendered] + > provide shared module (default) react@18.2.0 = ../../node_modules/react/index.js + > consume shared module (default) react@^18.2.0 (singleton) (fallback: ../../node_modules/react/index.js) + dependent modules 6.75 KiB [dependent] 1 module ../../node_modules/react/index.js 190 bytes [built] [code generated] - chunk (runtime: app) src_bootstrap_js-webpack_sharing_consume_default_react_react.js 84 bytes (consume-shared) 12 bytes (remote) 12 bytes (share-init) 1.56 KiB (javascript) [rendered] - > ./bootstrap ./src/index.js 8:0-21 + chunk (runtime: app) src_bootstrap_js.js 42 bytes (consume-shared) 12 bytes (remote) 12 bytes (share-init) 1.56 KiB (javascript) [rendered] + > ./bootstrap ./src/index.js 10:0-21 dependent modules 42 bytes (consume-shared) 12 bytes (remote) 12 bytes (share-init) [dependent] 3 modules - built modules 1.56 KiB (javascript) 42 bytes (consume-shared) [built] - ./src/bootstrap.js + 1 modules 1.56 KiB [built] [code generated] - consume shared module (default) react@=17.0.1 (singleton) (fallback: ../../node_modules/react/index.js) 42 bytes [built] [code generated] - chunk (runtime: app) vendors-node_modules_date-fns_esm_locale_de_index_js-node_modules_react-dom_index_js.js (id hint: vendors) 142 KiB [rendered] split chunk (cache group: defaultVendors) - > ./bootstrap ./src/index.js 8:0-21 - dependent modules 125 KiB [dependent] 4 modules - cacheable modules 16.9 KiB - ../../node_modules/date-fns/esm/locale/de/index.js + 9 modules 15.6 KiB [built] [code generated] + ./src/bootstrap.js + 1 modules 1.56 KiB [built] [code generated] + chunk (runtime: app) vendors-node_modules_date-fns_esm_locale_de_index_js-node_modules_react-dom_index_js.js (id hint: vendors) 151 KiB [rendered] split chunk (cache group: defaultVendors) + > ./bootstrap ./src/index.js 10:0-21 + dependent modules 133 KiB [dependent] 3 modules + cacheable modules 17.5 KiB + ../../node_modules/date-fns/esm/locale/de/index.js + 9 modules 16.2 KiB [built] [code generated] ../../node_modules/react-dom/index.js 1.33 KiB [built] [code generated] chunk (runtime: app) 6 bytes (remote) 6 bytes (share-init) - > mfe-c/Component2 ./src/App.js 8:49-75 + > mfe-c/Component2 ./src/App.js 7:49-75 remote mfe-c/Component2 6 bytes (remote) 6 bytes (share-init) [built] [code generated] - app (webpack 5.11.1) compiled successfully + app (webpack 5.78.0) compiled successfully mfe-b: - asset vendors-node_modules_date-fns_esm_index_js.js 78 KiB [emitted] [minimized] (id hint: vendors) - asset node_modules_react_index_js.js 6.97 KiB [emitted] [minimized] 1 related asset - asset mfeBBB.js 5.76 KiB [emitted] [minimized] (name: mfeBBB) + asset vendors-node_modules_date-fns_esm_index_js.js 154 KiB [emitted] [minimized] (id hint: vendors) + asset node_modules_react_index_js.js 6.5 KiB [emitted] [minimized] 1 related asset + asset mfeBBB.js 5.82 KiB [emitted] [minimized] (name: mfeBBB) asset src-b_Component_js.js 489 bytes [emitted] [minimized] - chunk (runtime: mfeBBB) mfeBBB.js (mfeBBB) 42 bytes (javascript) 84 bytes (share-init) 16.3 KiB (runtime) [entry] [rendered] + chunk (runtime: mfeBBB) mfeBBB.js (mfeBBB) 42 bytes (javascript) 84 bytes (share-init) 16.9 KiB (runtime) [entry] [rendered] > mfeBBB - runtime modules 16.3 KiB 11 modules + runtime modules 16.9 KiB 11 modules built modules 42 bytes (javascript) 84 bytes (share-init) [built] container entry 42 bytes [built] [code generated] - provide shared module (default) date-fns@2.16.1 = ../../node_modules/date-fns/esm/index.js 42 bytes [built] [code generated] - provide shared module (default) react@17.0.1 = ../../node_modules/react/index.js 42 bytes [built] [code generated] - chunk (runtime: mfeBBB) node_modules_react_index_js.js 8.54 KiB [rendered] - > provide shared module (default) react@17.0.1 = ../../node_modules/react/index.js - > consume shared module (default) react@^17.0.1 (singleton) (fallback: ../../node_modules/react/index.js) - dependent modules 8.36 KiB [dependent] 2 modules + provide shared module (default) date-fns@2.29.3 = ../../node_modules/date-fns/esm/index.js 42 bytes [built] [code generated] + provide shared module (default) react@18.2.0 = ../../node_modules/react/index.js 42 bytes [built] [code generated] + chunk (runtime: mfeBBB) node_modules_react_index_js.js 6.94 KiB [rendered] + > provide shared module (default) react@18.2.0 = ../../node_modules/react/index.js + > consume shared module (default) react@^18.2.0 (singleton) (fallback: ../../node_modules/react/index.js) + dependent modules 6.75 KiB [dependent] 1 module ../../node_modules/react/index.js 190 bytes [built] [code generated] - chunk (runtime: mfeBBB) src-b_Component_js.js 753 bytes (javascript) 84 bytes (consume-shared) [rendered] + chunk (runtime: mfeBBB) src-b_Component_js.js 752 bytes (javascript) 84 bytes (consume-shared) [rendered] > ./src-b/Component container entry ./Component dependent modules 84 bytes [dependent] 2 modules - ./src-b/Component.js 753 bytes [built] [code generated] - chunk (runtime: mfeBBB) vendors-node_modules_date-fns_esm_index_js.js (id hint: vendors) 509 KiB [rendered] reused as split chunk (cache group: defaultVendors) + ./src-b/Component.js 752 bytes [built] [code generated] + chunk (runtime: mfeBBB) vendors-node_modules_date-fns_esm_index_js.js (id hint: vendors) 679 KiB [rendered] reused as split chunk (cache group: defaultVendors) + > provide shared module (default) date-fns@2.29.3 = ../../node_modules/date-fns/esm/index.js > consume shared module (default) date-fns@^2.15.0 (strict) (fallback: ../../node_modules/date-fns/esm/index.js) - > provide shared module (default) date-fns@2.16.1 = ../../node_modules/date-fns/esm/index.js - ../../node_modules/date-fns/esm/index.js + 231 modules 509 KiB [built] [code generated] - mfe-b (webpack 5.11.1) compiled successfully + ../../node_modules/date-fns/esm/index.js + 312 modules 679 KiB [built] [code generated] + mfe-b (webpack 5.78.0) compiled successfully mfe-c: - asset vendors-node_modules_date-fns_esm_index_js.js 78 KiB [emitted] [minimized] (id hint: vendors) - asset mfeCCC.js 6.41 KiB [emitted] [minimized] (name: mfeCCC) - asset node_modules_lodash_random_js.js 2.95 KiB [emitted] [minimized] - asset src-c_LazyComponent_js.js 533 bytes [emitted] [minimized] - asset src-c_Component_js.js 489 bytes [emitted] [minimized] - chunk (runtime: mfeCCC) mfeCCC.js (mfeCCC) 42 bytes (javascript) 84 bytes (share-init) 16.7 KiB (runtime) [entry] [rendered] + asset vendors-node_modules_date-fns_esm_index_js.js 154 KiB [emitted] [minimized] (id hint: vendors) + asset mfeCCC.js 6.47 KiB [emitted] [minimized] (name: mfeCCC) + asset node_modules_lodash_random_js.js 3.13 KiB [emitted] [minimized] + asset src-c_LazyComponent_js.js 532 bytes [emitted] [minimized] + asset src-c_Component_js.js 488 bytes [emitted] [minimized] + chunk (runtime: mfeCCC) mfeCCC.js (mfeCCC) 42 bytes (javascript) 84 bytes (share-init) 17.3 KiB (runtime) [entry] [rendered] > mfeCCC - runtime modules 16.7 KiB 12 modules + runtime modules 17.3 KiB 12 modules built modules 42 bytes (javascript) 84 bytes (share-init) [built] container entry 42 bytes [built] [code generated] - provide shared module (default) date-fns@2.16.1 = ../../node_modules/date-fns/esm/index.js 42 bytes [built] [code generated] - provide shared module (default) lodash/random@4.17.20 = ../../node_modules/lodash/random.js 42 bytes [built] [code generated] - chunk (runtime: mfeCCC) node_modules_lodash_random_js.js 15.2 KiB [rendered] - > provide shared module (default) lodash/random@4.17.20 = ../../node_modules/lodash/random.js + provide shared module (default) date-fns@2.29.3 = ../../node_modules/date-fns/esm/index.js 42 bytes [built] [code generated] + provide shared module (default) lodash/random@4.17.21 = ../../node_modules/lodash/random.js 42 bytes [built] [code generated] + chunk (runtime: mfeCCC) node_modules_lodash_random_js.js 16 KiB [rendered] + > provide shared module (default) lodash/random@4.17.21 = ../../node_modules/lodash/random.js > consume shared module (default) lodash/random@^4.17.19 (strict) (fallback: ../../node_modules/lodash/random.js) - dependent modules 12.8 KiB [dependent] 18 modules + dependent modules 13.7 KiB [dependent] 20 modules ../../node_modules/lodash/random.js 2.32 KiB [built] [code generated] - chunk (runtime: mfeCCC) src-c_Component_js.js 469 bytes (javascript) 42 bytes (consume-shared) [rendered] + chunk (runtime: mfeCCC) src-c_Component_js.js 467 bytes (javascript) 42 bytes (consume-shared) [rendered] > ./src-c/Component container entry ./Component dependent modules 42 bytes [dependent] 1 module - ./src-c/Component.js 469 bytes [built] [code generated] - chunk (runtime: mfeCCC) src-c_LazyComponent_js.js 506 bytes (javascript) 42 bytes (consume-shared) [rendered] + ./src-c/Component.js 467 bytes [built] [code generated] + chunk (runtime: mfeCCC) src-c_LazyComponent_js.js 504 bytes (javascript) 42 bytes (consume-shared) [rendered] > ./src-c/LazyComponent container entry ./Component2 dependent modules 42 bytes [dependent] 1 module - ./src-c/LazyComponent.js 506 bytes [built] [code generated] - chunk (runtime: mfeCCC) vendors-node_modules_date-fns_esm_index_js.js (id hint: vendors) 509 KiB [rendered] reused as split chunk (cache group: defaultVendors) + ./src-c/LazyComponent.js 504 bytes [built] [code generated] + chunk (runtime: mfeCCC) vendors-node_modules_date-fns_esm_index_js.js (id hint: vendors) 679 KiB [rendered] reused as split chunk (cache group: defaultVendors) + > provide shared module (default) date-fns@2.29.3 = ../../node_modules/date-fns/esm/index.js > consume shared module (default) date-fns@^2.15.0 (strict) (fallback: ../../node_modules/date-fns/esm/index.js) - > provide shared module (default) date-fns@2.16.1 = ../../node_modules/date-fns/esm/index.js - ../../node_modules/date-fns/esm/index.js + 231 modules 509 KiB [built] [code generated] + ../../node_modules/date-fns/esm/index.js + 312 modules 679 KiB [built] [code generated] chunk (runtime: mfeCCC) 42 bytes split chunk (cache group: default) > ./src-c/Component container entry ./Component > ./src-c/LazyComponent container entry ./Component2 - consume shared module (default) react@^17.0.1 (singleton) 42 bytes [built] [code generated] - mfe-c (webpack 5.11.1) compiled successfully + consume shared module (default) react@^18.2.0 (singleton) 42 bytes [built] [code generated] + mfe-c (webpack 5.78.0) compiled successfully ``` diff --git a/examples/module-federation/index.html b/examples/module-federation/index.html index 3bb627ed79c..f5a0a1ec244 100644 --- a/examples/module-federation/index.html +++ b/examples/module-federation/index.html @@ -67,7 +67,7 @@
- + diff --git a/examples/module-library/README.md b/examples/module-library/README.md new file mode 100644 index 00000000000..ceea855eef9 --- /dev/null +++ b/examples/module-library/README.md @@ -0,0 +1,169 @@ +# example.js + +```javascript +export * from "./counter"; +export * from "./methods"; +``` + +# methods.js + +```javascript +export { reset as resetCounter } from "./counter"; + +export const print = value => console.log(value); +``` + +# counter.js + +```javascript +export let value = 0; +export function increment() { + value++; +} +export function decrement() { + value--; +} +export function reset() { + value = 0; +} +``` + +# dist/output.js + +```javascript +/******/ // The require scope +/******/ var __webpack_require__ = {}; +/******/ +``` + +
/* webpack runtime code */ + +``` js +/************************************************************************/ +/******/ /* webpack/runtime/define property getters */ +/******/ (() => { +/******/ // define getter functions for harmony exports +/******/ __webpack_require__.d = (exports, definition) => { +/******/ for(var key in definition) { +/******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) { +/******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] }); +/******/ } +/******/ } +/******/ }; +/******/ })(); +/******/ +/******/ /* webpack/runtime/hasOwnProperty shorthand */ +/******/ (() => { +/******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop)) +/******/ })(); +/******/ +/******/ /* webpack/runtime/make namespace object */ +/******/ (() => { +/******/ // define __esModule on exports +/******/ __webpack_require__.r = (exports) => { +/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { +/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); +/******/ } +/******/ Object.defineProperty(exports, '__esModule', { value: true }); +/******/ }; +/******/ })(); +/******/ +/************************************************************************/ +``` + +
+ +``` js +var __webpack_exports__ = {}; +/*!********************************!*\ + !*** ./example.js + 2 modules ***! + \********************************/ +/*! namespace exports */ +/*! export decrement [provided] [used in main] [missing usage info prevents renaming] -> ./counter.js .decrement */ +/*! export increment [provided] [used in main] [missing usage info prevents renaming] -> ./counter.js .increment */ +/*! export print [provided] [used in main] [missing usage info prevents renaming] -> ./methods.js .print */ +/*! export reset [provided] [used in main] [missing usage info prevents renaming] -> ./counter.js .reset */ +/*! export resetCounter [provided] [used in main] [missing usage info prevents renaming] -> ./counter.js .reset */ +/*! export value [provided] [used in main] [missing usage info prevents renaming] -> ./counter.js .value */ +/*! other exports [not provided] [no usage info] */ +/*! runtime requirements: __webpack_require__.r, __webpack_exports__, __webpack_require__.d, __webpack_require__.* */ +// ESM COMPAT FLAG +__webpack_require__.r(__webpack_exports__); + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + "decrement": () => (/* reexport */ decrement), + "increment": () => (/* reexport */ increment), + "print": () => (/* reexport */ print), + "reset": () => (/* reexport */ counter_reset), + "resetCounter": () => (/* reexport */ counter_reset), + "value": () => (/* reexport */ value) +}); + +;// CONCATENATED MODULE: ./counter.js +let value = 0; +function increment() { + value++; +} +function decrement() { + value--; +} +function counter_reset() { + value = 0; +} + +;// CONCATENATED MODULE: ./methods.js + + +const print = value => console.log(value); + +;// CONCATENATED MODULE: ./example.js + + + +var __webpack_exports__decrement = __webpack_exports__.decrement; +var __webpack_exports__increment = __webpack_exports__.increment; +var __webpack_exports__print = __webpack_exports__.print; +var __webpack_exports__reset = __webpack_exports__.reset; +var __webpack_exports__resetCounter = __webpack_exports__.resetCounter; +var __webpack_exports__value = __webpack_exports__.value; +export { __webpack_exports__decrement as decrement, __webpack_exports__increment as increment, __webpack_exports__print as print, __webpack_exports__reset as reset, __webpack_exports__resetCounter as resetCounter, __webpack_exports__value as value }; +``` + +# dist/output.js (production) + +```javascript +var e={d:(n,t)=>{for(var o in t)e.o(t,o)&&!e.o(n,o)&&Object.defineProperty(n,o,{enumerable:!0,get:t[o]})},o:(e,n)=>Object.prototype.hasOwnProperty.call(e,n)},n={};e.d(n,{Mj:()=>r,nP:()=>o,S0:()=>c,mc:()=>a,Uh:()=>a,S3:()=>t});let t=0;function o(){t++}function r(){t--}function a(){t=0}const c=e=>console.log(e);var s=n.Mj,i=n.nP,l=n.S0,p=n.mc,u=n.Uh,f=n.S3;export{s as decrement,i as increment,l as print,p as reset,u as resetCounter,f as value}; +``` + +# Info + +## Unoptimized + +``` +asset output.js 3.61 KiB [emitted] [javascript module] (name: main) +chunk (runtime: main) output.js (main) 302 bytes (javascript) 670 bytes (runtime) [entry] [rendered] + > ./example.js main + runtime modules 670 bytes 3 modules + ./example.js + 2 modules 302 bytes [built] [code generated] + [exports: decrement, increment, print, reset, resetCounter, value] + [used exports unknown] + entry ./example.js main + used as library export +webpack 5.78.0 compiled successfully +``` + +## Production mode + +``` +asset output.js 446 bytes [emitted] [javascript module] [minimized] (name: main) +chunk (runtime: main) output.js (main) 302 bytes (javascript) 396 bytes (runtime) [entry] [rendered] + > ./example.js main + runtime modules 396 bytes 2 modules + ./example.js + 2 modules 302 bytes [built] [code generated] + [exports: decrement, increment, print, reset, resetCounter, value] + [all exports used] + entry ./example.js main + used as library export +webpack 5.78.0 compiled successfully +``` diff --git a/examples/module-library/build.js b/examples/module-library/build.js new file mode 100644 index 00000000000..41c29c9d169 --- /dev/null +++ b/examples/module-library/build.js @@ -0,0 +1 @@ +require("../build-common"); \ No newline at end of file diff --git a/examples/module-library/counter.js b/examples/module-library/counter.js new file mode 100644 index 00000000000..7009896e282 --- /dev/null +++ b/examples/module-library/counter.js @@ -0,0 +1,10 @@ +export let value = 0; +export function increment() { + value++; +} +export function decrement() { + value--; +} +export function reset() { + value = 0; +} diff --git a/examples/module-library/example.js b/examples/module-library/example.js new file mode 100644 index 00000000000..ef58a21ffa1 --- /dev/null +++ b/examples/module-library/example.js @@ -0,0 +1,2 @@ +export * from "./counter"; +export * from "./methods"; diff --git a/examples/module-library/methods.js b/examples/module-library/methods.js new file mode 100644 index 00000000000..4be8f10f704 --- /dev/null +++ b/examples/module-library/methods.js @@ -0,0 +1,3 @@ +export { reset as resetCounter } from "./counter"; + +export const print = value => console.log(value); diff --git a/examples/module-library/template.md b/examples/module-library/template.md new file mode 100644 index 00000000000..98d06e62ec9 --- /dev/null +++ b/examples/module-library/template.md @@ -0,0 +1,43 @@ +# example.js + +```javascript +_{{example.js}}_ +``` + +# methods.js + +```javascript +_{{methods.js}}_ +``` + +# counter.js + +```javascript +_{{counter.js}}_ +``` + +# dist/output.js + +```javascript +_{{dist/output.js}}_ +``` + +# dist/output.js (production) + +```javascript +_{{production:dist/output.js}}_ +``` + +# Info + +## Unoptimized + +``` +_{{stdout}}_ +``` + +## Production mode + +``` +_{{production:stdout}}_ +``` diff --git a/examples/module-library/webpack.config.js b/examples/module-library/webpack.config.js new file mode 100644 index 00000000000..d7f45aa6917 --- /dev/null +++ b/examples/module-library/webpack.config.js @@ -0,0 +1,14 @@ +module.exports = { + output: { + module: true, + library: { + type: "module" + } + }, + optimization: { + concatenateModules: true + }, + experiments: { + outputModule: true + } +}; diff --git a/examples/module-worker/README.md b/examples/module-worker/README.md new file mode 100644 index 00000000000..3ec3b5f1452 --- /dev/null +++ b/examples/module-worker/README.md @@ -0,0 +1,896 @@ +# example.js + +```javascript +document.body.innerHTML = ` +

+	
+ + +
+

Computing fibonacci without worker:

+ +

+	

Computing fibonacci with worker:

+ +

+`;
+
+const history = document.getElementById("history");
+const message = document.getElementById("message");
+const send = document.getElementById("send");
+const fib1 = document.getElementById("fib1");
+const output1 = document.getElementById("output1");
+const fib2 = document.getElementById("fib2");
+const output2 = document.getElementById("output2");
+
+/// CHAT with shared worker ///
+
+const chatWorker = new SharedWorker(
+	new URL("./chat-worker.js", import.meta.url),
+	{
+		name: "chat",
+		type: "module"
+	}
+);
+
+let historyTimeout;
+const scheduleUpdateHistory = () => {
+	clearTimeout(historyTimeout);
+	historyTimeout = setTimeout(() => {
+		chatWorker.port.postMessage({ type: "history" });
+	}, 1000);
+};
+scheduleUpdateHistory();
+
+const from = `User ${Math.floor(Math.random() * 10000)}`;
+
+send.addEventListener("click", e => {
+	chatWorker.port.postMessage({
+		type: "message",
+		content: message.value,
+		from
+	});
+	message.value = "";
+	message.focus();
+	e.preventDefault();
+});
+
+chatWorker.port.onmessage = event => {
+	const msg = event.data;
+	switch (msg.type) {
+		case "history":
+			history.innerText = msg.history.join("\n");
+			scheduleUpdateHistory();
+			break;
+	}
+};
+
+/// FIBONACCI without worker ///
+
+fib1.addEventListener("change", async () => {
+	try {
+		const value = parseInt(fib1.value, 10);
+		const { fibonacci } = await import("./fibonacci");
+		const result = fibonacci(value);
+		output1.innerText = `fib(${value}) = ${result}`;
+	} catch (e) {
+		output1.innerText = e.message;
+	}
+});
+
+/// FIBONACCI with worker ///
+
+const fibWorker = new Worker(new URL("./fib-worker.js", import.meta.url), {
+	name: "fibonacci",
+	type: "module"
+	/* webpackEntryOptions: { filename: "workers/[name].js" } */
+});
+
+fib2.addEventListener("change", () => {
+	try {
+		const value = parseInt(fib2.value, 10);
+		fibWorker.postMessage(`${value}`);
+	} catch (e) {
+		output2.innerText = e.message;
+	}
+});
+
+fibWorker.onmessage = event => {
+	output2.innerText = event.data;
+};
+```
+
+# fib-worker.js
+
+```javascript
+onmessage = async event => {
+	const { fibonacci } = await import("./fibonacci");
+	const value = JSON.parse(event.data);
+	postMessage(`fib(${value}) = ${fibonacci(value)}`);
+};
+```
+
+# fibonacci.js
+
+```javascript
+export function fibonacci(n) {
+	return n < 1 ? 0 : n <= 2 ? 1 : fibonacci(n - 1) + fibonacci(n - 2);
+}
+```
+
+# chat-worker.js
+
+```javascript
+onconnect = function (e) {
+	for (const port of e.ports) {
+		port.onmessage = async event => {
+			const msg = event.data;
+			switch (msg.type) {
+				case "message":
+					const { add } = await import("./chat-module");
+					add(msg.content, msg.from);
+				// fallthrough
+				case "history":
+					const { history } = await import("./chat-module");
+					port.postMessage({
+						type: "history",
+						history
+					});
+					break;
+			}
+		};
+	}
+};
+```
+
+# chat-module.js
+
+```javascript
+export const history = [];
+
+export const add = (content, from) => {
+	if (history.length > 10) history.shift();
+	history.push(`${from}: ${content}`);
+};
+```
+
+# dist/main.js
+
+```javascript
+/******/ var __webpack_modules__ = ({});
+```
+
+
/* webpack runtime code */ + +``` js +/************************************************************************/ +/******/ // The module cache +/******/ var __webpack_module_cache__ = {}; +/******/ +/******/ // The require function +/******/ function __webpack_require__(moduleId) { +/******/ // Check if module is in cache +/******/ var cachedModule = __webpack_module_cache__[moduleId]; +/******/ if (cachedModule !== undefined) { +/******/ return cachedModule.exports; +/******/ } +/******/ // Create a new module (and put it into the cache) +/******/ var module = __webpack_module_cache__[moduleId] = { +/******/ // no module.id needed +/******/ // no module.loaded needed +/******/ exports: {} +/******/ }; +/******/ +/******/ // Execute the module function +/******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__); +/******/ +/******/ // Return the exports of the module +/******/ return module.exports; +/******/ } +/******/ +/******/ // expose the modules object (__webpack_modules__) +/******/ __webpack_require__.m = __webpack_modules__; +/******/ +/************************************************************************/ +/******/ /* webpack/runtime/define property getters */ +/******/ (() => { +/******/ // define getter functions for harmony exports +/******/ __webpack_require__.d = (exports, definition) => { +/******/ for(var key in definition) { +/******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) { +/******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] }); +/******/ } +/******/ } +/******/ }; +/******/ })(); +/******/ +/******/ /* webpack/runtime/ensure chunk */ +/******/ (() => { +/******/ __webpack_require__.f = {}; +/******/ // This file contains only the entry chunk. +/******/ // The chunk loading function for additional chunks +/******/ __webpack_require__.e = (chunkId) => { +/******/ return Promise.all(Object.keys(__webpack_require__.f).reduce((promises, key) => { +/******/ __webpack_require__.f[key](chunkId, promises); +/******/ return promises; +/******/ }, [])); +/******/ }; +/******/ })(); +/******/ +/******/ /* webpack/runtime/get javascript chunk filename */ +/******/ (() => { +/******/ // This function allow to reference async chunks +/******/ __webpack_require__.u = (chunkId) => { +/******/ // return url for filenames not based on template +/******/ if (chunkId === 631) return "workers/fibonacci.js"; +/******/ // return url for filenames based on template +/******/ return "" + (chunkId === 348 ? "chat" : chunkId) + ".js"; +/******/ }; +/******/ })(); +/******/ +/******/ /* webpack/runtime/hasOwnProperty shorthand */ +/******/ (() => { +/******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop)) +/******/ })(); +/******/ +/******/ /* webpack/runtime/make namespace object */ +/******/ (() => { +/******/ // define __esModule on exports +/******/ __webpack_require__.r = (exports) => { +/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { +/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); +/******/ } +/******/ Object.defineProperty(exports, '__esModule', { value: true }); +/******/ }; +/******/ })(); +/******/ +/******/ /* webpack/runtime/publicPath */ +/******/ (() => { +/******/ __webpack_require__.p = "/dist/"; +/******/ })(); +/******/ +/******/ /* webpack/runtime/import chunk loading */ +/******/ (() => { +/******/ __webpack_require__.b = new URL("./", import.meta.url); +/******/ +/******/ // object to store loaded and loading chunks +/******/ // undefined = chunk not loaded, null = chunk preloaded/prefetched +/******/ // [resolve, reject, Promise] = chunk loading, 0 = chunk loaded +/******/ var installedChunks = { +/******/ 179: 0 +/******/ }; +/******/ +/******/ var installChunk = (data) => { +/******/ var {ids, modules, runtime} = data; +/******/ // add "modules" to the modules object, +/******/ // then flag all "ids" as loaded and fire callback +/******/ var moduleId, chunkId, i = 0; +/******/ for(moduleId in modules) { +/******/ if(__webpack_require__.o(modules, moduleId)) { +/******/ __webpack_require__.m[moduleId] = modules[moduleId]; +/******/ } +/******/ } +/******/ if(runtime) runtime(__webpack_require__); +/******/ for(;i < ids.length; i++) { +/******/ chunkId = ids[i]; +/******/ if(__webpack_require__.o(installedChunks, chunkId) && installedChunks[chunkId]) { +/******/ installedChunks[chunkId][0](); +/******/ } +/******/ installedChunks[ids[i]] = 0; +/******/ } +/******/ +/******/ } +/******/ +/******/ __webpack_require__.f.j = (chunkId, promises) => { +/******/ // import() chunk loading for javascript +/******/ var installedChunkData = __webpack_require__.o(installedChunks, chunkId) ? installedChunks[chunkId] : undefined; +/******/ if(installedChunkData !== 0) { // 0 means "already installed". +/******/ +/******/ // a Promise means "currently loading". +/******/ if(installedChunkData) { +/******/ promises.push(installedChunkData[1]); +/******/ } else { +/******/ if(true) { // all chunks have JS +/******/ // setup Promise in chunk cache +/******/ var promise = import("./" + __webpack_require__.u(chunkId)).then(installChunk, (e) => { +/******/ if(installedChunks[chunkId] !== 0) installedChunks[chunkId] = undefined; +/******/ throw e; +/******/ }); +/******/ var promise = Promise.race([promise, new Promise((resolve) => (installedChunkData = installedChunks[chunkId] = [resolve]))]) +/******/ promises.push(installedChunkData[1] = promise); +/******/ } else installedChunks[chunkId] = 0; +/******/ } +/******/ } +/******/ }; +/******/ +/******/ // no external install chunk +/******/ +/******/ // no on chunks loaded +/******/ })(); +/******/ +/************************************************************************/ +``` + +
+ +``` js +var __webpack_exports__ = {}; +/*!********************!*\ + !*** ./example.js ***! + \********************/ +/*! unknown exports (runtime-defined) */ +/*! runtime requirements: __webpack_require__.p, __webpack_require__.b, __webpack_require__.u, __webpack_require__.e, __webpack_require__, __webpack_require__.* */ +document.body.innerHTML = ` +

+	
+ + +
+

Computing fibonacci without worker:

+ +

+	

Computing fibonacci with worker:

+ +

+`;
+
+const history = document.getElementById("history");
+const message = document.getElementById("message");
+const send = document.getElementById("send");
+const fib1 = document.getElementById("fib1");
+const output1 = document.getElementById("output1");
+const fib2 = document.getElementById("fib2");
+const output2 = document.getElementById("output2");
+
+/// CHAT with shared worker ///
+
+const chatWorker = new SharedWorker(
+	new URL(/* worker import */ __webpack_require__.p + __webpack_require__.u(348), __webpack_require__.b),
+	{
+		name: "chat",
+		type: "module"
+	}
+);
+
+let historyTimeout;
+const scheduleUpdateHistory = () => {
+	clearTimeout(historyTimeout);
+	historyTimeout = setTimeout(() => {
+		chatWorker.port.postMessage({ type: "history" });
+	}, 1000);
+};
+scheduleUpdateHistory();
+
+const from = `User ${Math.floor(Math.random() * 10000)}`;
+
+send.addEventListener("click", e => {
+	chatWorker.port.postMessage({
+		type: "message",
+		content: message.value,
+		from
+	});
+	message.value = "";
+	message.focus();
+	e.preventDefault();
+});
+
+chatWorker.port.onmessage = event => {
+	const msg = event.data;
+	switch (msg.type) {
+		case "history":
+			history.innerText = msg.history.join("\n");
+			scheduleUpdateHistory();
+			break;
+	}
+};
+
+/// FIBONACCI without worker ///
+
+fib1.addEventListener("change", async () => {
+	try {
+		const value = parseInt(fib1.value, 10);
+		const { fibonacci } = await __webpack_require__.e(/*! import() */ 129).then(__webpack_require__.bind(__webpack_require__, /*! ./fibonacci */ 2));
+		const result = fibonacci(value);
+		output1.innerText = `fib(${value}) = ${result}`;
+	} catch (e) {
+		output1.innerText = e.message;
+	}
+});
+
+/// FIBONACCI with worker ///
+
+const fibWorker = new Worker(new URL(/* worker import */ __webpack_require__.p + __webpack_require__.u(631), __webpack_require__.b), {
+	name: "fibonacci",
+	type: "module"
+	/* webpackEntryOptions: { filename: "workers/[name].js" } */
+});
+
+fib2.addEventListener("change", () => {
+	try {
+		const value = parseInt(fib2.value, 10);
+		fibWorker.postMessage(`${value}`);
+	} catch (e) {
+		output2.innerText = e.message;
+	}
+});
+
+fibWorker.onmessage = event => {
+	output2.innerText = event.data;
+};
+```
+
+# dist/chat.js
+
+```javascript
+/******/ var __webpack_modules__ = ({});
+```
+
+
/* webpack runtime code */ + +``` js +/************************************************************************/ +/******/ // The module cache +/******/ var __webpack_module_cache__ = {}; +/******/ +/******/ // The require function +/******/ function __webpack_require__(moduleId) { +/******/ // Check if module is in cache +/******/ var cachedModule = __webpack_module_cache__[moduleId]; +/******/ if (cachedModule !== undefined) { +/******/ return cachedModule.exports; +/******/ } +/******/ // Create a new module (and put it into the cache) +/******/ var module = __webpack_module_cache__[moduleId] = { +/******/ // no module.id needed +/******/ // no module.loaded needed +/******/ exports: {} +/******/ }; +/******/ +/******/ // Execute the module function +/******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__); +/******/ +/******/ // Return the exports of the module +/******/ return module.exports; +/******/ } +/******/ +/******/ // expose the modules object (__webpack_modules__) +/******/ __webpack_require__.m = __webpack_modules__; +/******/ +/************************************************************************/ +/******/ /* webpack/runtime/define property getters */ +/******/ (() => { +/******/ // define getter functions for harmony exports +/******/ __webpack_require__.d = (exports, definition) => { +/******/ for(var key in definition) { +/******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) { +/******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] }); +/******/ } +/******/ } +/******/ }; +/******/ })(); +/******/ +/******/ /* webpack/runtime/ensure chunk */ +/******/ (() => { +/******/ __webpack_require__.f = {}; +/******/ // This file contains only the entry chunk. +/******/ // The chunk loading function for additional chunks +/******/ __webpack_require__.e = (chunkId) => { +/******/ return Promise.all(Object.keys(__webpack_require__.f).reduce((promises, key) => { +/******/ __webpack_require__.f[key](chunkId, promises); +/******/ return promises; +/******/ }, [])); +/******/ }; +/******/ })(); +/******/ +/******/ /* webpack/runtime/get javascript chunk filename */ +/******/ (() => { +/******/ // This function allow to reference async chunks +/******/ __webpack_require__.u = (chunkId) => { +/******/ // return url for filenames based on template +/******/ return "" + chunkId + ".js"; +/******/ }; +/******/ })(); +/******/ +/******/ /* webpack/runtime/hasOwnProperty shorthand */ +/******/ (() => { +/******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop)) +/******/ })(); +/******/ +/******/ /* webpack/runtime/make namespace object */ +/******/ (() => { +/******/ // define __esModule on exports +/******/ __webpack_require__.r = (exports) => { +/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { +/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); +/******/ } +/******/ Object.defineProperty(exports, '__esModule', { value: true }); +/******/ }; +/******/ })(); +/******/ +/******/ /* webpack/runtime/import chunk loading */ +/******/ (() => { +/******/ // no baseURI +/******/ +/******/ // object to store loaded and loading chunks +/******/ // undefined = chunk not loaded, null = chunk preloaded/prefetched +/******/ // [resolve, reject, Promise] = chunk loading, 0 = chunk loaded +/******/ var installedChunks = { +/******/ 348: 0 +/******/ }; +/******/ +/******/ var installChunk = (data) => { +/******/ var {ids, modules, runtime} = data; +/******/ // add "modules" to the modules object, +/******/ // then flag all "ids" as loaded and fire callback +/******/ var moduleId, chunkId, i = 0; +/******/ for(moduleId in modules) { +/******/ if(__webpack_require__.o(modules, moduleId)) { +/******/ __webpack_require__.m[moduleId] = modules[moduleId]; +/******/ } +/******/ } +/******/ if(runtime) runtime(__webpack_require__); +/******/ for(;i < ids.length; i++) { +/******/ chunkId = ids[i]; +/******/ if(__webpack_require__.o(installedChunks, chunkId) && installedChunks[chunkId]) { +/******/ installedChunks[chunkId][0](); +/******/ } +/******/ installedChunks[ids[i]] = 0; +/******/ } +/******/ +/******/ } +/******/ +/******/ __webpack_require__.f.j = (chunkId, promises) => { +/******/ // import() chunk loading for javascript +/******/ var installedChunkData = __webpack_require__.o(installedChunks, chunkId) ? installedChunks[chunkId] : undefined; +/******/ if(installedChunkData !== 0) { // 0 means "already installed". +/******/ +/******/ // a Promise means "currently loading". +/******/ if(installedChunkData) { +/******/ promises.push(installedChunkData[1]); +/******/ } else { +/******/ if(true) { // all chunks have JS +/******/ // setup Promise in chunk cache +/******/ var promise = import("./" + __webpack_require__.u(chunkId)).then(installChunk, (e) => { +/******/ if(installedChunks[chunkId] !== 0) installedChunks[chunkId] = undefined; +/******/ throw e; +/******/ }); +/******/ var promise = Promise.race([promise, new Promise((resolve) => (installedChunkData = installedChunks[chunkId] = [resolve]))]) +/******/ promises.push(installedChunkData[1] = promise); +/******/ } else installedChunks[chunkId] = 0; +/******/ } +/******/ } +/******/ }; +/******/ +/******/ // no external install chunk +/******/ +/******/ // no on chunks loaded +/******/ })(); +/******/ +/************************************************************************/ +``` + +
+ +``` js +var __webpack_exports__ = {}; +/*!************************!*\ + !*** ./chat-worker.js ***! + \************************/ +/*! unknown exports (runtime-defined) */ +/*! runtime requirements: __webpack_require__.e, __webpack_require__, __webpack_require__.* */ +onconnect = function (e) { + for (const port of e.ports) { + port.onmessage = async event => { + const msg = event.data; + switch (msg.type) { + case "message": + const { add } = await __webpack_require__.e(/*! import() */ 192).then(__webpack_require__.bind(__webpack_require__, /*! ./chat-module */ 4)); + add(msg.content, msg.from); + // fallthrough + case "history": + const { history } = await __webpack_require__.e(/*! import() */ 192).then(__webpack_require__.bind(__webpack_require__, /*! ./chat-module */ 4)); + port.postMessage({ + type: "history", + history + }); + break; + } + }; + } +}; +``` + +```javascript +var e,o,t={},r={};function n(e){var o=r[e];if(void 0!==o)return o.exports;var s=r[e]={exports:{}};return t[e](s,s.exports,n),s.exports}n.m=t,n.d=(e,o)=>{for(var t in o)n.o(o,t)&&!n.o(e,t)&&Object.defineProperty(e,t,{enumerable:!0,get:o[t]})},n.f={},n.e=e=>Promise.all(Object.keys(n.f).reduce(((o,t)=>(n.f[t](e,o),o)),[])),n.u=e=>e+".js",n.o=(e,o)=>Object.prototype.hasOwnProperty.call(e,o),n.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},e={348:0},o=o=>{var t,r,{ids:s,modules:i,runtime:a}=o,c=0;for(t in i)n.o(i,t)&&(n.m[t]=i[t]);for(a&&a(n);c{var s=n.o(e,t)?e[t]:void 0;if(0!==s)if(s)r.push(s[1]);else{var i=import("./"+n.u(t)).then(o,(o=>{throw 0!==e[t]&&(e[t]=void 0),o}));i=Promise.race([i,new Promise((o=>s=e[t]=[o]))]),r.push(s[1]=i)}},onconnect=function(e){for(const o of e.ports)o.onmessage=async e=>{const t=e.data;switch(t.type){case"message":const{add:e}=await n.e(192).then(n.bind(n,192));e(t.content,t.from);case"history":const{history:r}=await n.e(192).then(n.bind(n,192));o.postMessage({type:"history",history:r})}}}; +``` + +# dist/workers/fibonacci.js + +```javascript +/******/ var __webpack_modules__ = ({}); +``` + +
/* webpack runtime code */ + +``` js +/************************************************************************/ +/******/ // The module cache +/******/ var __webpack_module_cache__ = {}; +/******/ +/******/ // The require function +/******/ function __webpack_require__(moduleId) { +/******/ // Check if module is in cache +/******/ var cachedModule = __webpack_module_cache__[moduleId]; +/******/ if (cachedModule !== undefined) { +/******/ return cachedModule.exports; +/******/ } +/******/ // Create a new module (and put it into the cache) +/******/ var module = __webpack_module_cache__[moduleId] = { +/******/ // no module.id needed +/******/ // no module.loaded needed +/******/ exports: {} +/******/ }; +/******/ +/******/ // Execute the module function +/******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__); +/******/ +/******/ // Return the exports of the module +/******/ return module.exports; +/******/ } +/******/ +/******/ // expose the modules object (__webpack_modules__) +/******/ __webpack_require__.m = __webpack_modules__; +/******/ +/************************************************************************/ +/******/ /* webpack/runtime/define property getters */ +/******/ (() => { +/******/ // define getter functions for harmony exports +/******/ __webpack_require__.d = (exports, definition) => { +/******/ for(var key in definition) { +/******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) { +/******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] }); +/******/ } +/******/ } +/******/ }; +/******/ })(); +/******/ +/******/ /* webpack/runtime/ensure chunk */ +/******/ (() => { +/******/ __webpack_require__.f = {}; +/******/ // This file contains only the entry chunk. +/******/ // The chunk loading function for additional chunks +/******/ __webpack_require__.e = (chunkId) => { +/******/ return Promise.all(Object.keys(__webpack_require__.f).reduce((promises, key) => { +/******/ __webpack_require__.f[key](chunkId, promises); +/******/ return promises; +/******/ }, [])); +/******/ }; +/******/ })(); +/******/ +/******/ /* webpack/runtime/get javascript chunk filename */ +/******/ (() => { +/******/ // This function allow to reference async chunks +/******/ __webpack_require__.u = (chunkId) => { +/******/ // return url for filenames based on template +/******/ return "" + chunkId + ".js"; +/******/ }; +/******/ })(); +/******/ +/******/ /* webpack/runtime/hasOwnProperty shorthand */ +/******/ (() => { +/******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop)) +/******/ })(); +/******/ +/******/ /* webpack/runtime/make namespace object */ +/******/ (() => { +/******/ // define __esModule on exports +/******/ __webpack_require__.r = (exports) => { +/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { +/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); +/******/ } +/******/ Object.defineProperty(exports, '__esModule', { value: true }); +/******/ }; +/******/ })(); +/******/ +/******/ /* webpack/runtime/import chunk loading */ +/******/ (() => { +/******/ // no baseURI +/******/ +/******/ // object to store loaded and loading chunks +/******/ // undefined = chunk not loaded, null = chunk preloaded/prefetched +/******/ // [resolve, reject, Promise] = chunk loading, 0 = chunk loaded +/******/ var installedChunks = { +/******/ 631: 0 +/******/ }; +/******/ +/******/ var installChunk = (data) => { +/******/ var {ids, modules, runtime} = data; +/******/ // add "modules" to the modules object, +/******/ // then flag all "ids" as loaded and fire callback +/******/ var moduleId, chunkId, i = 0; +/******/ for(moduleId in modules) { +/******/ if(__webpack_require__.o(modules, moduleId)) { +/******/ __webpack_require__.m[moduleId] = modules[moduleId]; +/******/ } +/******/ } +/******/ if(runtime) runtime(__webpack_require__); +/******/ for(;i < ids.length; i++) { +/******/ chunkId = ids[i]; +/******/ if(__webpack_require__.o(installedChunks, chunkId) && installedChunks[chunkId]) { +/******/ installedChunks[chunkId][0](); +/******/ } +/******/ installedChunks[ids[i]] = 0; +/******/ } +/******/ +/******/ } +/******/ +/******/ __webpack_require__.f.j = (chunkId, promises) => { +/******/ // import() chunk loading for javascript +/******/ var installedChunkData = __webpack_require__.o(installedChunks, chunkId) ? installedChunks[chunkId] : undefined; +/******/ if(installedChunkData !== 0) { // 0 means "already installed". +/******/ +/******/ // a Promise means "currently loading". +/******/ if(installedChunkData) { +/******/ promises.push(installedChunkData[1]); +/******/ } else { +/******/ if(true) { // all chunks have JS +/******/ // setup Promise in chunk cache +/******/ var promise = import("../" + __webpack_require__.u(chunkId)).then(installChunk, (e) => { +/******/ if(installedChunks[chunkId] !== 0) installedChunks[chunkId] = undefined; +/******/ throw e; +/******/ }); +/******/ var promise = Promise.race([promise, new Promise((resolve) => (installedChunkData = installedChunks[chunkId] = [resolve]))]) +/******/ promises.push(installedChunkData[1] = promise); +/******/ } else installedChunks[chunkId] = 0; +/******/ } +/******/ } +/******/ }; +/******/ +/******/ // no external install chunk +/******/ +/******/ // no on chunks loaded +/******/ })(); +/******/ +/************************************************************************/ +``` + +
+ +``` js +var __webpack_exports__ = {}; +/*!***********************!*\ + !*** ./fib-worker.js ***! + \***********************/ +/*! unknown exports (runtime-defined) */ +/*! runtime requirements: __webpack_require__.e, __webpack_require__, __webpack_require__.* */ +onmessage = async event => { + const { fibonacci } = await __webpack_require__.e(/*! import() */ 129).then(__webpack_require__.bind(__webpack_require__, /*! ./fibonacci */ 2)); + const value = JSON.parse(event.data); + postMessage(`fib(${value}) = ${fibonacci(value)}`); +}; +``` + +```javascript +var e,o,r={},t={};function i(e){var o=t[e];if(void 0!==o)return o.exports;var a=t[e]={exports:{}};return r[e](a,a.exports,i),a.exports}i.m=r,i.d=(e,o)=>{for(var r in o)i.o(o,r)&&!i.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:o[r]})},i.f={},i.e=e=>Promise.all(Object.keys(i.f).reduce(((o,r)=>(i.f[r](e,o),o)),[])),i.u=e=>e+".js",i.o=(e,o)=>Object.prototype.hasOwnProperty.call(e,o),i.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},e={631:0},o=o=>{var r,t,{ids:a,modules:n,runtime:s}=o,f=0;for(r in n)i.o(n,r)&&(i.m[r]=n[r]);for(s&&s(i);f{var a=i.o(e,r)?e[r]:void 0;if(0!==a)if(a)t.push(a[1]);else{var n=import("../"+i.u(r)).then(o,(o=>{throw 0!==e[r]&&(e[r]=void 0),o}));n=Promise.race([n,new Promise((o=>a=e[r]=[o]))]),t.push(a[1]=n)}},onmessage=async e=>{const{fibonacci:o}=await i.e(129).then(i.bind(i,129)),r=JSON.parse(e.data);postMessage(`fib(${r}) = ${o(r)}`)}; +``` + +# dist/129.js + +```javascript +export const id = 129; +export const ids = [129]; +export const modules = { + +/***/ 2: +/*!**********************!*\ + !*** ./fibonacci.js ***! + \**********************/ +/*! namespace exports */ +/*! export fibonacci [provided] [no usage info] [missing usage info prevents renaming] */ +/*! other exports [not provided] [no usage info] */ +/*! runtime requirements: __webpack_require__.r, __webpack_exports__, __webpack_require__.d, __webpack_require__.* */ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "fibonacci": () => (/* binding */ fibonacci) +/* harmony export */ }); +function fibonacci(n) { + return n < 1 ? 0 : n <= 2 ? 1 : fibonacci(n - 1) + fibonacci(n - 2); +} + + +/***/ }) + +}; +``` + +# Info + +## Unoptimized + +``` +asset main.js 8.56 KiB [emitted] [javascript module] (name: main) +asset chat.js 6.34 KiB [emitted] [javascript module] (name: chat) +asset workers/fibonacci.js 5.99 KiB [emitted] [javascript module] (name: fibonacci) +asset 192.js 1.01 KiB [emitted] [javascript module] +asset 129.js 847 bytes [emitted] [javascript module] +chunk (runtime: 9a81d90cfd0dfd13d748, main) 129.js 103 bytes [rendered] + > ./fibonacci ./example.js 70:30-51 + > ./fibonacci ./fib-worker.js 2:29-50 + ./fibonacci.js 103 bytes [built] [code generated] + [exports: fibonacci] + [used exports unknown] + import() ./fibonacci ./example.js 70:30-51 + import() ./fibonacci ./fib-worker.js 2:29-50 +chunk (runtime: main) main.js (main) 2.25 KiB (javascript) 3.07 KiB (runtime) [entry] [rendered] + > ./example.js main + runtime modules 3.07 KiB 7 modules + ./example.js 2.25 KiB [built] [code generated] + [used exports unknown] + entry ./example.js main +chunk (runtime: 1fad8bf8de78b0a77bfd) 192.js 152 bytes [rendered] + > ./chat-module ./chat-worker.js 11:31-54 + > ./chat-module ./chat-worker.js 7:27-50 + ./chat-module.js 152 bytes [built] [code generated] + [exports: add, history] + [used exports unknown] + import() ./chat-module ./chat-worker.js 7:27-50 + import() ./chat-module ./chat-worker.js 11:31-54 +chunk (runtime: 1fad8bf8de78b0a77bfd) chat.js (chat) 442 bytes (javascript) 2.86 KiB (runtime) [entry] [rendered] + > ./example.js 25:19-31:1 + runtime modules 2.86 KiB 6 modules + ./chat-worker.js 442 bytes [built] [code generated] + [used exports unknown] + new Worker() ./chat-worker.js ./example.js 25:19-31:1 +chunk (runtime: 9a81d90cfd0dfd13d748) workers/fibonacci.js (fibonacci) 176 bytes (javascript) 2.87 KiB (runtime) [entry] [rendered] + > ./example.js 80:18-84:2 + runtime modules 2.87 KiB 6 modules + ./fib-worker.js 176 bytes [built] [code generated] + [used exports unknown] + new Worker() ./fib-worker.js ./example.js 80:18-84:2 +webpack 5.78.0 compiled successfully +``` + +## Production mode + +``` +asset main.js 2.5 KiB [emitted] [javascript module] [minimized] (name: main) +asset chat.js 1.19 KiB [emitted] [javascript module] [minimized] (name: chat) +asset workers/fibonacci.js 1.04 KiB [emitted] [javascript module] [minimized] (name: fibonacci) +asset 192.js 187 bytes [emitted] [javascript module] [minimized] +asset 129.js 161 bytes [emitted] [javascript module] [minimized] +chunk (runtime: 9a81d90cfd0dfd13d748, main) 129.js 103 bytes [rendered] + > ./fibonacci ./example.js 70:30-51 + > ./fibonacci ./fib-worker.js 2:29-50 + ./fibonacci.js 103 bytes [built] [code generated] + [exports: fibonacci] + import() ./fibonacci ./example.js 70:30-51 + import() ./fibonacci ./fib-worker.js 2:29-50 +chunk (runtime: main) main.js (main) 2.25 KiB (javascript) 3.07 KiB (runtime) [entry] [rendered] + > ./example.js main + runtime modules 3.07 KiB 7 modules + ./example.js 2.25 KiB [built] [code generated] + [no exports used] + entry ./example.js main +chunk (runtime: 1fad8bf8de78b0a77bfd) 192.js 152 bytes [rendered] + > ./chat-module ./chat-worker.js 11:31-54 + > ./chat-module ./chat-worker.js 7:27-50 + ./chat-module.js 152 bytes [built] [code generated] + [exports: add, history] + import() ./chat-module ./chat-worker.js 7:27-50 + import() ./chat-module ./chat-worker.js 11:31-54 +chunk (runtime: 1fad8bf8de78b0a77bfd) chat.js (chat) 442 bytes (javascript) 2.86 KiB (runtime) [entry] [rendered] + > ./example.js 25:19-31:1 + runtime modules 2.86 KiB 6 modules + ./chat-worker.js 442 bytes [built] [code generated] + [no exports used] + new Worker() ./chat-worker.js ./example.js 25:19-31:1 +chunk (runtime: 9a81d90cfd0dfd13d748) workers/fibonacci.js (fibonacci) 176 bytes (javascript) 2.87 KiB (runtime) [entry] [rendered] + > ./example.js 80:18-84:2 + runtime modules 2.87 KiB 6 modules + ./fib-worker.js 176 bytes [built] [code generated] + [no exports used] + new Worker() ./fib-worker.js ./example.js 80:18-84:2 +webpack 5.78.0 compiled successfully +``` diff --git a/examples/module-worker/build.js b/examples/module-worker/build.js new file mode 100644 index 00000000000..5768b058787 --- /dev/null +++ b/examples/module-worker/build.js @@ -0,0 +1,3 @@ +global.NO_TARGET_ARGS = true; +global.NO_PUBLIC_PATH = true; +require("../build-common"); diff --git a/examples/module-worker/chat-module.js b/examples/module-worker/chat-module.js new file mode 100644 index 00000000000..716a104a9dc --- /dev/null +++ b/examples/module-worker/chat-module.js @@ -0,0 +1,6 @@ +export const history = []; + +export const add = (content, from) => { + if (history.length > 10) history.shift(); + history.push(`${from}: ${content}`); +}; diff --git a/examples/module-worker/chat-worker.js b/examples/module-worker/chat-worker.js new file mode 100644 index 00000000000..1a8bcb81ea0 --- /dev/null +++ b/examples/module-worker/chat-worker.js @@ -0,0 +1,20 @@ +onconnect = function (e) { + for (const port of e.ports) { + port.onmessage = async event => { + const msg = event.data; + switch (msg.type) { + case "message": + const { add } = await import("./chat-module"); + add(msg.content, msg.from); + // fallthrough + case "history": + const { history } = await import("./chat-module"); + port.postMessage({ + type: "history", + history + }); + break; + } + }; + } +}; diff --git a/examples/module-worker/example.js b/examples/module-worker/example.js new file mode 100644 index 00000000000..fcbe23f092f --- /dev/null +++ b/examples/module-worker/example.js @@ -0,0 +1,97 @@ +document.body.innerHTML = ` +

+	
+ + +
+

Computing fibonacci without worker:

+ +

+	

Computing fibonacci with worker:

+ +

+`;
+
+const history = document.getElementById("history");
+const message = document.getElementById("message");
+const send = document.getElementById("send");
+const fib1 = document.getElementById("fib1");
+const output1 = document.getElementById("output1");
+const fib2 = document.getElementById("fib2");
+const output2 = document.getElementById("output2");
+
+/// CHAT with shared worker ///
+
+const chatWorker = new SharedWorker(
+	new URL("./chat-worker.js", import.meta.url),
+	{
+		name: "chat",
+		type: "module"
+	}
+);
+
+let historyTimeout;
+const scheduleUpdateHistory = () => {
+	clearTimeout(historyTimeout);
+	historyTimeout = setTimeout(() => {
+		chatWorker.port.postMessage({ type: "history" });
+	}, 1000);
+};
+scheduleUpdateHistory();
+
+const from = `User ${Math.floor(Math.random() * 10000)}`;
+
+send.addEventListener("click", e => {
+	chatWorker.port.postMessage({
+		type: "message",
+		content: message.value,
+		from
+	});
+	message.value = "";
+	message.focus();
+	e.preventDefault();
+});
+
+chatWorker.port.onmessage = event => {
+	const msg = event.data;
+	switch (msg.type) {
+		case "history":
+			history.innerText = msg.history.join("\n");
+			scheduleUpdateHistory();
+			break;
+	}
+};
+
+/// FIBONACCI without worker ///
+
+fib1.addEventListener("change", async () => {
+	try {
+		const value = parseInt(fib1.value, 10);
+		const { fibonacci } = await import("./fibonacci");
+		const result = fibonacci(value);
+		output1.innerText = `fib(${value}) = ${result}`;
+	} catch (e) {
+		output1.innerText = e.message;
+	}
+});
+
+/// FIBONACCI with worker ///
+
+const fibWorker = new Worker(new URL("./fib-worker.js", import.meta.url), {
+	name: "fibonacci",
+	type: "module"
+	/* webpackEntryOptions: { filename: "workers/[name].js" } */
+});
+
+fib2.addEventListener("change", () => {
+	try {
+		const value = parseInt(fib2.value, 10);
+		fibWorker.postMessage(`${value}`);
+	} catch (e) {
+		output2.innerText = e.message;
+	}
+});
+
+fibWorker.onmessage = event => {
+	output2.innerText = event.data;
+};
diff --git a/examples/module-worker/fib-worker.js b/examples/module-worker/fib-worker.js
new file mode 100644
index 00000000000..42efa83cf4e
--- /dev/null
+++ b/examples/module-worker/fib-worker.js
@@ -0,0 +1,5 @@
+onmessage = async event => {
+	const { fibonacci } = await import("./fibonacci");
+	const value = JSON.parse(event.data);
+	postMessage(`fib(${value}) = ${fibonacci(value)}`);
+};
diff --git a/examples/module-worker/fibonacci.js b/examples/module-worker/fibonacci.js
new file mode 100644
index 00000000000..282fcec2fca
--- /dev/null
+++ b/examples/module-worker/fibonacci.js
@@ -0,0 +1,3 @@
+export function fibonacci(n) {
+	return n < 1 ? 0 : n <= 2 ? 1 : fibonacci(n - 1) + fibonacci(n - 2);
+}
diff --git a/examples/module-worker/index.html b/examples/module-worker/index.html
new file mode 100644
index 00000000000..e3b460bdf15
--- /dev/null
+++ b/examples/module-worker/index.html
@@ -0,0 +1,10 @@
+
+
+	
+		
+		Worker example
+	
+	
+		
+	
+
diff --git a/examples/module-worker/template.md b/examples/module-worker/template.md
new file mode 100644
index 00000000000..6a93ddfd9b5
--- /dev/null
+++ b/examples/module-worker/template.md
@@ -0,0 +1,75 @@
+# example.js
+
+```javascript
+_{{example.js}}_
+```
+
+# fib-worker.js
+
+```javascript
+_{{fib-worker.js}}_
+```
+
+# fibonacci.js
+
+```javascript
+_{{fibonacci.js}}_
+```
+
+# chat-worker.js
+
+```javascript
+_{{chat-worker.js}}_
+```
+
+# chat-module.js
+
+```javascript
+_{{chat-module.js}}_
+```
+
+# dist/main.js
+
+```javascript
+_{{dist/main.js}}_
+```
+
+# dist/chat.js
+
+```javascript
+_{{dist/chat.js}}_
+```
+
+```javascript
+_{{production:dist/chat.js}}_
+```
+
+# dist/workers/fibonacci.js
+
+```javascript
+_{{dist/workers/fibonacci.js}}_
+```
+
+```javascript
+_{{production:dist/workers/fibonacci.js}}_
+```
+
+# dist/129.js
+
+```javascript
+_{{dist/129.js}}_
+```
+
+# Info
+
+## Unoptimized
+
+```
+_{{stdout}}_
+```
+
+## Production mode
+
+```
+_{{production:stdout}}_
+```
diff --git a/examples/module-worker/webpack.config.js b/examples/module-worker/webpack.config.js
new file mode 100644
index 00000000000..7787a5113be
--- /dev/null
+++ b/examples/module-worker/webpack.config.js
@@ -0,0 +1,18 @@
+const path = require("path");
+
+module.exports = {
+	entry: "./example.js",
+	output: {
+		path: path.join(__dirname, "dist"),
+		filename: "[name].js",
+		chunkFilename: "[name].js",
+		publicPath: "/dist/"
+	},
+	optimization: {
+		chunkIds: "deterministic" // To keep filename consistent between different modes (for example building only)
+	},
+	target: "browserslist: last 2 Chrome versions",
+	experiments: {
+		outputModule: true
+	}
+};
diff --git a/examples/module/README.md b/examples/module/README.md
index 1070ace1342..4f366c2fb6d 100644
--- a/examples/module/README.md
+++ b/examples/module/README.md
@@ -40,7 +40,6 @@ export function reset() {
 # dist/output.js
 
 ```javascript
-/******/ "use strict";
 /******/ // The require scope
 /******/ var __webpack_require__ = {};
 /******/ 
@@ -134,7 +133,7 @@ var e={d:(o,r)=>{for(var t in r)e.o(r,t)&&!e.o(o,t)&&Object.defineProperty(o,t,{
 ## Unoptimized
 
 ```
-asset output.js 2.05 KiB [emitted] [javascript module] (name: main)
+asset output.js 2.03 KiB [emitted] [javascript module] (name: main)
 chunk (runtime: main) output.js (main) 453 bytes (javascript) 396 bytes (runtime) [entry] [rendered]
   > ./example.js main
   runtime modules 396 bytes 2 modules
@@ -143,7 +142,7 @@ chunk (runtime: main) output.js (main) 453 bytes (javascript) 396 bytes (runtime
     [all exports used]
     entry ./example.js main
     used as library export
-webpack 5.20.2 compiled successfully
+webpack 5.78.0 compiled successfully
 ```
 
 ## Production mode
@@ -158,5 +157,5 @@ chunk (runtime: main) output.js (main) 453 bytes (javascript) 396 bytes (runtime
     [all exports used]
     entry ./example.js main
     used as library export
-webpack 5.20.2 compiled successfully
+webpack 5.78.0 compiled successfully
 ```
diff --git a/examples/multi-compiler/README.md b/examples/multi-compiler/README.md
index 3c87432245e..e781ad0894f 100644
--- a/examples/multi-compiler/README.md
+++ b/examples/multi-compiler/README.md
@@ -15,7 +15,7 @@ var webpack = require("../../");
 module.exports = [
 	{
 		name: "mobile",
-		// mode: "development || "production",
+		// mode: "development" || "production",
 		entry: "./example",
 		output: {
 			path: path.join(__dirname, "dist"),
@@ -30,7 +30,7 @@ module.exports = [
 
 	{
 		name: "desktop",
-		// mode: "development || "production",
+		// mode: "development" || "production",
 		entry: "./example",
 		output: {
 			path: path.join(__dirname, "dist"),
@@ -49,6 +49,7 @@ module.exports = [
 
 ```javascript
 /******/ (() => { // webpackBootstrap
+var __webpack_exports__ = {};
 /*!********************!*\
   !*** ./example.js ***!
   \********************/
@@ -90,8 +91,9 @@ console.log("Running " + "desktop" + " build");
 /******/ 	// The require function
 /******/ 	function __webpack_require__(moduleId) {
 /******/ 		// Check if module is in cache
-/******/ 		if(__webpack_module_cache__[moduleId]) {
-/******/ 			return __webpack_module_cache__[moduleId].exports;
+/******/ 		var cachedModule = __webpack_module_cache__[moduleId];
+/******/ 		if (cachedModule !== undefined) {
+/******/ 			return cachedModule.exports;
 /******/ 		}
 /******/ 		// Create a new module (and put it into the cache)
 /******/ 		var module = __webpack_module_cache__[moduleId] = {
@@ -113,6 +115,8 @@ console.log("Running " + "desktop" + " build");
 
 
 ``` js
+var __webpack_exports__ = {};
+// This entry need to be wrapped in an IIFE because it need to be isolated against other modules in the chunk.
 (() => {
 /*!********************!*\
   !*** ./example.js ***!
@@ -135,37 +139,37 @@ console.log("Running " + "mobile" + " build");
 
 ```
 mobile:
-  asset mobile.js 1.57 KiB [emitted] (name: main)
+  asset mobile.js 1.74 KiB [emitted] (name: main)
   chunk (runtime: main) mobile.js (main) 114 bytes [entry] [rendered]
     > ./example main
     dependent modules 20 bytes [dependent] 1 module
     ./example.js 94 bytes [built] [code generated]
       [used exports unknown]
       entry ./example main
-  mobile (webpack 5.11.1) compiled successfully
+  mobile (webpack 5.78.0) compiled successfully
 
 desktop:
-  asset desktop.js 262 bytes [emitted] (name: main)
+  asset desktop.js 292 bytes [emitted] (name: main)
   chunk (runtime: main) desktop.js (main) 94 bytes [entry] [rendered]
     > ./example main
     ./example.js 94 bytes [built] [code generated]
       [used exports unknown]
       entry ./example main
-  desktop (webpack 5.11.1) compiled successfully
+  desktop (webpack 5.78.0) compiled successfully
 ```
 
 ## Production mode
 
 ```
 mobile:
-  asset mobile.js 181 bytes [emitted] [minimized] (name: main)
+  asset mobile.js 195 bytes [emitted] [minimized] (name: main)
   chunk (runtime: main) mobile.js (main) 114 bytes [entry] [rendered]
     > ./example main
     dependent modules 20 bytes [dependent] 1 module
     ./example.js 94 bytes [built] [code generated]
       [no exports used]
       entry ./example main
-  mobile (webpack 5.11.1) compiled successfully
+  mobile (webpack 5.78.0) compiled successfully
 
 desktop:
   asset desktop.js 37 bytes [emitted] [minimized] (name: main)
@@ -174,5 +178,5 @@ desktop:
     ./example.js 94 bytes [built] [code generated]
       [no exports used]
       entry ./example main
-  desktop (webpack 5.11.1) compiled successfully
+  desktop (webpack 5.78.0) compiled successfully
 ```
diff --git a/examples/multi-compiler/webpack.config.js b/examples/multi-compiler/webpack.config.js
index 4fc3088639a..e7b01428c58 100644
--- a/examples/multi-compiler/webpack.config.js
+++ b/examples/multi-compiler/webpack.config.js
@@ -1,9 +1,10 @@
-var path = require("path");
-var webpack = require("../../");
+const path = require("path");
+const webpack = require("../../");
+
 module.exports = [
 	{
 		name: "mobile",
-		// mode: "development || "production",
+		// mode: "development" || "production",
 		entry: "./example",
 		output: {
 			path: path.join(__dirname, "dist"),
@@ -18,7 +19,7 @@ module.exports = [
 
 	{
 		name: "desktop",
-		// mode: "development || "production",
+		// mode: "development" || "production",
 		entry: "./example",
 		output: {
 			path: path.join(__dirname, "dist"),
diff --git a/examples/multi-part-library/README.md b/examples/multi-part-library/README.md
index cd49bab36d9..d1e6870efb0 100644
--- a/examples/multi-part-library/README.md
+++ b/examples/multi-part-library/README.md
@@ -10,14 +10,14 @@ You can see that webpack automatically wraps your module so that it is consumabl
 
 Note: You can also use the `library` and `libraryTarget` options without multiple entry points. Then you don't need `[name]`.
 
-Note: When your library has dependencies that should not be included in the compiled version, you can use the `externals` option. See [externals example](https://github.com/webpack/webpack/tree/master/examples/externals).
+Note: When your library has dependencies that should not be included in the compiled version, you can use the `externals` option. See [externals example](https://github.com/webpack/webpack/tree/main/examples/externals).
 
 # webpack.config.js
 
 ```javascript
 var path = require("path");
 module.exports = {
-	// mode: "development || "production",
+	// mode: "development" || "production",
 	entry: {
 		alpha: "./alpha",
 		beta: "./beta"
@@ -43,7 +43,7 @@ module.exports = {
 		exports["MyLibrary"] = factory();
 	else
 		root["MyLibrary"] = root["MyLibrary"] || {}, root["MyLibrary"]["alpha"] = factory();
-})(self, function() {
+})(self, () => {
 return /******/ (() => { // webpackBootstrap
 /******/ 	var __webpack_modules__ = ([
 /* 0 */
@@ -71,8 +71,9 @@ module.exports = "alpha";
 /******/ 	// The require function
 /******/ 	function __webpack_require__(moduleId) {
 /******/ 		// Check if module is in cache
-/******/ 		if(__webpack_module_cache__[moduleId]) {
-/******/ 			return __webpack_module_cache__[moduleId].exports;
+/******/ 		var cachedModule = __webpack_module_cache__[moduleId];
+/******/ 		if (cachedModule !== undefined) {
+/******/ 			return cachedModule.exports;
 /******/ 		}
 /******/ 		// Create a new module (and put it into the cache)
 /******/ 		var module = __webpack_module_cache__[moduleId] = {
@@ -94,10 +95,13 @@ module.exports = "alpha";
 
 
 ``` js
-/******/ 	// module exports must be returned from runtime so entry inlining is disabled
+/******/ 	
 /******/ 	// startup
 /******/ 	// Load entry module and return exports
-/******/ 	return __webpack_require__(0);
+/******/ 	// This entry module is referenced by other modules so it can't be inlined
+/******/ 	var __webpack_exports__ = __webpack_require__(0);
+/******/ 	
+/******/ 	return __webpack_exports__;
 /******/ })()
 ;
 });
@@ -115,7 +119,7 @@ module.exports = "alpha";
 		exports["MyLibrary"] = factory();
 	else
 		root["MyLibrary"] = root["MyLibrary"] || {}, root["MyLibrary"]["beta"] = factory();
-})(self, function() {
+})(self, () => {
 return /******/ (() => { // webpackBootstrap
 /******/ 	var __webpack_modules__ = ([
 /* 0 */,
@@ -144,8 +148,9 @@ module.exports = "beta";
 /******/ 	// The require function
 /******/ 	function __webpack_require__(moduleId) {
 /******/ 		// Check if module is in cache
-/******/ 		if(__webpack_module_cache__[moduleId]) {
-/******/ 			return __webpack_module_cache__[moduleId].exports;
+/******/ 		var cachedModule = __webpack_module_cache__[moduleId];
+/******/ 		if (cachedModule !== undefined) {
+/******/ 			return cachedModule.exports;
 /******/ 		}
 /******/ 		// Create a new module (and put it into the cache)
 /******/ 		var module = __webpack_module_cache__[moduleId] = {
@@ -167,10 +172,13 @@ module.exports = "beta";
 
 
 ``` js
-/******/ 	// module exports must be returned from runtime so entry inlining is disabled
+/******/ 	
 /******/ 	// startup
 /******/ 	// Load entry module and return exports
-/******/ 	return __webpack_require__(1);
+/******/ 	// This entry module is referenced by other modules so it can't be inlined
+/******/ 	var __webpack_exports__ = __webpack_require__(1);
+/******/ 	
+/******/ 	return __webpack_exports__;
 /******/ })()
 ;
 });
@@ -181,8 +189,8 @@ module.exports = "beta";
 ## Unoptimized
 
 ```
-asset MyLibrary.beta.js 1.96 KiB [emitted] (name: beta)
-asset MyLibrary.alpha.js 1.95 KiB [emitted] (name: alpha)
+asset MyLibrary.beta.js 2.06 KiB [emitted] (name: beta)
+asset MyLibrary.alpha.js 2.06 KiB [emitted] (name: alpha)
 chunk (runtime: alpha) MyLibrary.alpha.js (alpha) 25 bytes [entry] [rendered]
   > ./alpha alpha
   ./alpha.js 25 bytes [built] [code generated]
@@ -197,14 +205,14 @@ chunk (runtime: beta) MyLibrary.beta.js (beta) 24 bytes [entry] [rendered]
     cjs self exports reference ./beta.js 1:0-14
     entry ./beta beta
     used as library export
-webpack 5.11.1 compiled successfully
+webpack 5.78.0 compiled successfully
 ```
 
 ## Production mode
 
 ```
-asset MyLibrary.alpha.js 415 bytes [emitted] [minimized] (name: alpha)
-asset MyLibrary.beta.js 411 bytes [emitted] [minimized] (name: beta)
+asset MyLibrary.alpha.js 423 bytes [emitted] [minimized] (name: alpha)
+asset MyLibrary.beta.js 419 bytes [emitted] [minimized] (name: beta)
 chunk (runtime: alpha) MyLibrary.alpha.js (alpha) 25 bytes [entry] [rendered]
   > ./alpha alpha
   ./alpha.js 25 bytes [built] [code generated]
@@ -219,5 +227,5 @@ chunk (runtime: beta) MyLibrary.beta.js (beta) 24 bytes [entry] [rendered]
     cjs self exports reference ./beta.js 1:0-14
     entry ./beta beta
     used as library export
-webpack 5.11.1 compiled successfully
+webpack 5.78.0 compiled successfully
 ```
diff --git a/examples/multi-part-library/template.md b/examples/multi-part-library/template.md
index f1083c20440..6237b338ecb 100644
--- a/examples/multi-part-library/template.md
+++ b/examples/multi-part-library/template.md
@@ -10,7 +10,7 @@ You can see that webpack automatically wraps your module so that it is consumabl
 
 Note: You can also use the `library` and `libraryTarget` options without multiple entry points. Then you don't need `[name]`.
 
-Note: When your library has dependencies that should not be included in the compiled version, you can use the `externals` option. See [externals example](https://github.com/webpack/webpack/tree/master/examples/externals).
+Note: When your library has dependencies that should not be included in the compiled version, you can use the `externals` option. See [externals example](https://github.com/webpack/webpack/tree/main/examples/externals).
 
 # webpack.config.js
 
diff --git a/examples/multi-part-library/webpack.config.js b/examples/multi-part-library/webpack.config.js
index f79be11fe71..2d829643bcc 100644
--- a/examples/multi-part-library/webpack.config.js
+++ b/examples/multi-part-library/webpack.config.js
@@ -1,6 +1,7 @@
-var path = require("path");
+const path = require("path");
+
 module.exports = {
-	// mode: "development || "production",
+	// mode: "development" || "production",
 	entry: {
 		alpha: "./alpha",
 		beta: "./beta"
diff --git a/examples/multiple-entry-points/README.md b/examples/multiple-entry-points/README.md
index 2cc3461ee83..3378e9c728c 100644
--- a/examples/multiple-entry-points/README.md
+++ b/examples/multiple-entry-points/README.md
@@ -51,7 +51,7 @@ require.ensure(["./shared"], function(require) {
 
 ```javascript
 module.exports = {
-	// mode: "development || "production",
+	// mode: "development" || "production",
 	entry: {
 		pageA: "./pageA",
 		pageB: "./pageB"
@@ -120,7 +120,7 @@ module.exports = "Common";
 var common = __webpack_require__(/*! ./common */ 1);
 __webpack_require__.e(/*! AMD require */ 52).then(function() { var __WEBPACK_AMD_REQUIRE_ARRAY__ = [__webpack_require__(/*! ./shared */ 3)]; (function(shared) {
 	shared("This is page A");
-}).apply(null, __WEBPACK_AMD_REQUIRE_ARRAY__);}).catch(__webpack_require__.oe);
+}).apply(null, __WEBPACK_AMD_REQUIRE_ARRAY__);})['catch'](__webpack_require__.oe);
 
 /***/ })
 /******/ 	]);
@@ -136,8 +136,9 @@ __webpack_require__.e(/*! AMD require */ 52).then(function() { var __WEBPACK_AMD
 /******/ 	// The require function
 /******/ 	function __webpack_require__(moduleId) {
 /******/ 		// Check if module is in cache
-/******/ 		if(__webpack_module_cache__[moduleId]) {
-/******/ 			return __webpack_module_cache__[moduleId].exports;
+/******/ 		var cachedModule = __webpack_module_cache__[moduleId];
+/******/ 		if (cachedModule !== undefined) {
+/******/ 			return cachedModule.exports;
 /******/ 		}
 /******/ 		// Create a new module (and put it into the cache)
 /******/ 		var module = __webpack_module_cache__[moduleId] = {
@@ -156,10 +157,39 @@ __webpack_require__.e(/*! AMD require */ 52).then(function() { var __WEBPACK_AMD
 /******/ 	// expose the modules object (__webpack_modules__)
 /******/ 	__webpack_require__.m = __webpack_modules__;
 /******/ 	
-/******/ 	// the startup function
-/******/ 	// It's empty as some runtime module handles the default behavior
-/******/ 	__webpack_require__.x = x => {}
 /************************************************************************/
+/******/ 	/* webpack/runtime/chunk loaded */
+/******/ 	(() => {
+/******/ 		var deferred = [];
+/******/ 		__webpack_require__.O = (result, chunkIds, fn, priority) => {
+/******/ 			if(chunkIds) {
+/******/ 				priority = priority || 0;
+/******/ 				for(var i = deferred.length; i > 0 && deferred[i - 1][2] > priority; i--) deferred[i] = deferred[i - 1];
+/******/ 				deferred[i] = [chunkIds, fn, priority];
+/******/ 				return;
+/******/ 			}
+/******/ 			var notFulfilled = Infinity;
+/******/ 			for (var i = 0; i < deferred.length; i++) {
+/******/ 				var [chunkIds, fn, priority] = deferred[i];
+/******/ 				var fulfilled = true;
+/******/ 				for (var j = 0; j < chunkIds.length; j++) {
+/******/ 					if ((priority & 1 === 0 || notFulfilled >= priority) && Object.keys(__webpack_require__.O).every((key) => (__webpack_require__.O[key](chunkIds[j])))) {
+/******/ 						chunkIds.splice(j--, 1);
+/******/ 					} else {
+/******/ 						fulfilled = false;
+/******/ 						if(priority < notFulfilled) notFulfilled = priority;
+/******/ 					}
+/******/ 				}
+/******/ 				if(fulfilled) {
+/******/ 					deferred.splice(i--, 1)
+/******/ 					var r = fn();
+/******/ 					if (r !== undefined) result = r;
+/******/ 				}
+/******/ 			}
+/******/ 			return result;
+/******/ 		};
+/******/ 	})();
+/******/ 	
 /******/ 	/* webpack/runtime/ensure chunk */
 /******/ 	(() => {
 /******/ 		__webpack_require__.f = {};
@@ -184,7 +214,7 @@ __webpack_require__.e(/*! AMD require */ 52).then(function() { var __WEBPACK_AMD
 /******/ 	
 /******/ 	/* webpack/runtime/hasOwnProperty shorthand */
 /******/ 	(() => {
-/******/ 		__webpack_require__.o = (obj, prop) => Object.prototype.hasOwnProperty.call(obj, prop)
+/******/ 		__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
 /******/ 	})();
 /******/ 	
 /******/ 	/* webpack/runtime/load script */
@@ -192,7 +222,7 @@ __webpack_require__.e(/*! AMD require */ 52).then(function() { var __WEBPACK_AMD
 /******/ 		var inProgress = {};
 /******/ 		// data-webpack is not used as build has no uniqueName
 /******/ 		// loadScript function to load a script via script tag
-/******/ 		__webpack_require__.l = (url, done, key) => {
+/******/ 		__webpack_require__.l = (url, done, key, chunkId) => {
 /******/ 			if(inProgress[url]) { inProgress[url].push(done); return; }
 /******/ 			var script, needAttach;
 /******/ 			if(key !== undefined) {
@@ -222,10 +252,9 @@ __webpack_require__.e(/*! AMD require */ 52).then(function() { var __WEBPACK_AMD
 /******/ 				var doneFns = inProgress[url];
 /******/ 				delete inProgress[url];
 /******/ 				script.parentNode && script.parentNode.removeChild(script);
-/******/ 				doneFns && doneFns.forEach((fn) => fn(event));
+/******/ 				doneFns && doneFns.forEach((fn) => (fn(event)));
 /******/ 				if(prev) return prev(event);
 /******/ 			}
-/******/ 			;
 /******/ 			var timeout = setTimeout(onScriptComplete.bind(null, undefined, { type: 'timeout', target: script }), 120000);
 /******/ 			script.onerror = onScriptComplete.bind(null, script.onerror);
 /******/ 			script.onload = onScriptComplete.bind(null, script.onload);
@@ -244,14 +273,11 @@ __webpack_require__.e(/*! AMD require */ 52).then(function() { var __WEBPACK_AMD
 /******/ 		
 /******/ 		// object to store loaded and loading chunks
 /******/ 		// undefined = chunk not loaded, null = chunk preloaded/prefetched
-/******/ 		// Promise = chunk loading, 0 = chunk loaded
+/******/ 		// [resolve, reject, Promise] = chunk loading, 0 = chunk loaded
 /******/ 		var installedChunks = {
 /******/ 			424: 0
 /******/ 		};
 /******/ 		
-/******/ 		var deferredModules = [
-/******/ 			[0,351]
-/******/ 		];
 /******/ 		__webpack_require__.f.j = (chunkId, promises) => {
 /******/ 				// JSONP chunk loading for javascript
 /******/ 				var installedChunkData = __webpack_require__.o(installedChunks, chunkId) ? installedChunks[chunkId] : undefined;
@@ -263,9 +289,7 @@ __webpack_require__.e(/*! AMD require */ 52).then(function() { var __WEBPACK_AMD
 /******/ 					} else {
 /******/ 						if(true) { // all chunks have JS
 /******/ 							// setup Promise in chunk cache
-/******/ 							var promise = new Promise((resolve, reject) => {
-/******/ 								installedChunkData = installedChunks[chunkId] = [resolve, reject];
-/******/ 							});
+/******/ 							var promise = new Promise((resolve, reject) => (installedChunkData = installedChunks[chunkId] = [resolve, reject]));
 /******/ 							promises.push(installedChunkData[2] = promise);
 /******/ 		
 /******/ 							// start chunk loading
@@ -287,7 +311,7 @@ __webpack_require__.e(/*! AMD require */ 52).then(function() { var __WEBPACK_AMD
 /******/ 									}
 /******/ 								}
 /******/ 							};
-/******/ 							__webpack_require__.l(url, loadingEnded, "chunk-" + chunkId);
+/******/ 							__webpack_require__.l(url, loadingEnded, "chunk-" + chunkId, chunkId);
 /******/ 						} else installedChunks[chunkId] = 0;
 /******/ 					}
 /******/ 				}
@@ -301,69 +325,36 @@ __webpack_require__.e(/*! AMD require */ 52).then(function() { var __WEBPACK_AMD
 /******/ 		
 /******/ 		// no HMR manifest
 /******/ 		
-/******/ 		var checkDeferredModules = x => {};
+/******/ 		__webpack_require__.O.j = (chunkId) => (installedChunks[chunkId] === 0);
 /******/ 		
 /******/ 		// install a JSONP callback for chunk loading
 /******/ 		var webpackJsonpCallback = (parentChunkLoadingFunction, data) => {
-/******/ 			var [chunkIds, moreModules, runtime, executeModules] = data;
+/******/ 			var [chunkIds, moreModules, runtime] = data;
 /******/ 			// add "moreModules" to the modules object,
 /******/ 			// then flag all "chunkIds" as loaded and fire callback
-/******/ 			var moduleId, chunkId, i = 0, resolves = [];
+/******/ 			var moduleId, chunkId, i = 0;
+/******/ 			if(chunkIds.some((id) => (installedChunks[id] !== 0))) {
+/******/ 				for(moduleId in moreModules) {
+/******/ 					if(__webpack_require__.o(moreModules, moduleId)) {
+/******/ 						__webpack_require__.m[moduleId] = moreModules[moduleId];
+/******/ 					}
+/******/ 				}
+/******/ 				if(runtime) var result = runtime(__webpack_require__);
+/******/ 			}
+/******/ 			if(parentChunkLoadingFunction) parentChunkLoadingFunction(data);
 /******/ 			for(;i < chunkIds.length; i++) {
 /******/ 				chunkId = chunkIds[i];
 /******/ 				if(__webpack_require__.o(installedChunks, chunkId) && installedChunks[chunkId]) {
-/******/ 					resolves.push(installedChunks[chunkId][0]);
+/******/ 					installedChunks[chunkId][0]();
 /******/ 				}
 /******/ 				installedChunks[chunkId] = 0;
 /******/ 			}
-/******/ 			for(moduleId in moreModules) {
-/******/ 				if(__webpack_require__.o(moreModules, moduleId)) {
-/******/ 					__webpack_require__.m[moduleId] = moreModules[moduleId];
-/******/ 				}
-/******/ 			}
-/******/ 			if(runtime) runtime(__webpack_require__);
-/******/ 			if(parentChunkLoadingFunction) parentChunkLoadingFunction(data);
-/******/ 			while(resolves.length) {
-/******/ 				resolves.shift()();
-/******/ 			}
-/******/ 		
-/******/ 			// add entry modules from loaded chunk to deferred list
-/******/ 			if(executeModules) deferredModules.push.apply(deferredModules, executeModules);
-/******/ 		
-/******/ 			// run deferred modules when all chunks ready
-/******/ 			return checkDeferredModules();
+/******/ 			return __webpack_require__.O(result);
 /******/ 		}
 /******/ 		
 /******/ 		var chunkLoadingGlobal = self["webpackChunk"] = self["webpackChunk"] || [];
 /******/ 		chunkLoadingGlobal.forEach(webpackJsonpCallback.bind(null, 0));
 /******/ 		chunkLoadingGlobal.push = webpackJsonpCallback.bind(null, chunkLoadingGlobal.push.bind(chunkLoadingGlobal));
-/******/ 		
-/******/ 		function checkDeferredModulesImpl() {
-/******/ 			var result;
-/******/ 			for(var i = 0; i < deferredModules.length; i++) {
-/******/ 				var deferredModule = deferredModules[i];
-/******/ 				var fulfilled = true;
-/******/ 				for(var j = 1; j < deferredModule.length; j++) {
-/******/ 					var depId = deferredModule[j];
-/******/ 					if(installedChunks[depId] !== 0) fulfilled = false;
-/******/ 				}
-/******/ 				if(fulfilled) {
-/******/ 					deferredModules.splice(i--, 1);
-/******/ 					result = __webpack_require__(__webpack_require__.s = deferredModule[0]);
-/******/ 				}
-/******/ 			}
-/******/ 			if(deferredModules.length === 0) {
-/******/ 				__webpack_require__.x();
-/******/ 				__webpack_require__.x = x => {};
-/******/ 			}
-/******/ 			return result;
-/******/ 		}
-/******/ 		var startup = __webpack_require__.x;
-/******/ 		__webpack_require__.x = () => {
-/******/ 			// reset startup function so it can be called again when more startup code is added
-/******/ 			__webpack_require__.x = startup || (x => {});
-/******/ 			return (checkDeferredModules = checkDeferredModulesImpl)();
-/******/ 		};
 /******/ 	})();
 /******/ 	
 /************************************************************************/
@@ -372,8 +363,13 @@ __webpack_require__.e(/*! AMD require */ 52).then(function() { var __WEBPACK_AMD
 
 
 ``` js
-/******/ 	// run startup
-/******/ 	return __webpack_require__.x();
+/******/ 	
+/******/ 	// startup
+/******/ 	// Load entry module and return exports
+/******/ 	// This entry module depends on other loaded chunks and execution need to be delayed
+/******/ 	var __webpack_exports__ = __webpack_require__.O(undefined, [351], () => (__webpack_require__(0)))
+/******/ 	__webpack_exports__ = __webpack_require__.O(__webpack_exports__);
+/******/ 	
 /******/ })()
 ;
 ```
@@ -396,7 +392,7 @@ var common = __webpack_require__(/*! ./common */ 1);
 __webpack_require__.e(/*! require.ensure */ 52).then((function(require) {
 	var shared = __webpack_require__(/*! ./shared */ 3);
 	shared("This is page B");
-}).bind(null, __webpack_require__)).catch(__webpack_require__.oe);
+}).bind(null, __webpack_require__))['catch'](__webpack_require__.oe);
 
 /***/ })
 
@@ -413,8 +409,9 @@ __webpack_require__.e(/*! require.ensure */ 52).then((function(require) {
 /******/ 	// The require function
 /******/ 	function __webpack_require__(moduleId) {
 /******/ 		// Check if module is in cache
-/******/ 		if(__webpack_module_cache__[moduleId]) {
-/******/ 			return __webpack_module_cache__[moduleId].exports;
+/******/ 		var cachedModule = __webpack_module_cache__[moduleId];
+/******/ 		if (cachedModule !== undefined) {
+/******/ 			return cachedModule.exports;
 /******/ 		}
 /******/ 		// Create a new module (and put it into the cache)
 /******/ 		var module = __webpack_module_cache__[moduleId] = {
@@ -433,10 +430,39 @@ __webpack_require__.e(/*! require.ensure */ 52).then((function(require) {
 /******/ 	// expose the modules object (__webpack_modules__)
 /******/ 	__webpack_require__.m = __webpack_modules__;
 /******/ 	
-/******/ 	// the startup function
-/******/ 	// It's empty as some runtime module handles the default behavior
-/******/ 	__webpack_require__.x = x => {}
 /************************************************************************/
+/******/ 	/* webpack/runtime/chunk loaded */
+/******/ 	(() => {
+/******/ 		var deferred = [];
+/******/ 		__webpack_require__.O = (result, chunkIds, fn, priority) => {
+/******/ 			if(chunkIds) {
+/******/ 				priority = priority || 0;
+/******/ 				for(var i = deferred.length; i > 0 && deferred[i - 1][2] > priority; i--) deferred[i] = deferred[i - 1];
+/******/ 				deferred[i] = [chunkIds, fn, priority];
+/******/ 				return;
+/******/ 			}
+/******/ 			var notFulfilled = Infinity;
+/******/ 			for (var i = 0; i < deferred.length; i++) {
+/******/ 				var [chunkIds, fn, priority] = deferred[i];
+/******/ 				var fulfilled = true;
+/******/ 				for (var j = 0; j < chunkIds.length; j++) {
+/******/ 					if ((priority & 1 === 0 || notFulfilled >= priority) && Object.keys(__webpack_require__.O).every((key) => (__webpack_require__.O[key](chunkIds[j])))) {
+/******/ 						chunkIds.splice(j--, 1);
+/******/ 					} else {
+/******/ 						fulfilled = false;
+/******/ 						if(priority < notFulfilled) notFulfilled = priority;
+/******/ 					}
+/******/ 				}
+/******/ 				if(fulfilled) {
+/******/ 					deferred.splice(i--, 1)
+/******/ 					var r = fn();
+/******/ 					if (r !== undefined) result = r;
+/******/ 				}
+/******/ 			}
+/******/ 			return result;
+/******/ 		};
+/******/ 	})();
+/******/ 	
 /******/ 	/* webpack/runtime/ensure chunk */
 /******/ 	(() => {
 /******/ 		__webpack_require__.f = {};
@@ -461,7 +487,7 @@ __webpack_require__.e(/*! require.ensure */ 52).then((function(require) {
 /******/ 	
 /******/ 	/* webpack/runtime/hasOwnProperty shorthand */
 /******/ 	(() => {
-/******/ 		__webpack_require__.o = (obj, prop) => Object.prototype.hasOwnProperty.call(obj, prop)
+/******/ 		__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
 /******/ 	})();
 /******/ 	
 /******/ 	/* webpack/runtime/load script */
@@ -469,7 +495,7 @@ __webpack_require__.e(/*! require.ensure */ 52).then((function(require) {
 /******/ 		var inProgress = {};
 /******/ 		// data-webpack is not used as build has no uniqueName
 /******/ 		// loadScript function to load a script via script tag
-/******/ 		__webpack_require__.l = (url, done, key) => {
+/******/ 		__webpack_require__.l = (url, done, key, chunkId) => {
 /******/ 			if(inProgress[url]) { inProgress[url].push(done); return; }
 /******/ 			var script, needAttach;
 /******/ 			if(key !== undefined) {
@@ -499,10 +525,9 @@ __webpack_require__.e(/*! require.ensure */ 52).then((function(require) {
 /******/ 				var doneFns = inProgress[url];
 /******/ 				delete inProgress[url];
 /******/ 				script.parentNode && script.parentNode.removeChild(script);
-/******/ 				doneFns && doneFns.forEach((fn) => fn(event));
+/******/ 				doneFns && doneFns.forEach((fn) => (fn(event)));
 /******/ 				if(prev) return prev(event);
 /******/ 			}
-/******/ 			;
 /******/ 			var timeout = setTimeout(onScriptComplete.bind(null, undefined, { type: 'timeout', target: script }), 120000);
 /******/ 			script.onerror = onScriptComplete.bind(null, script.onerror);
 /******/ 			script.onload = onScriptComplete.bind(null, script.onload);
@@ -521,14 +546,11 @@ __webpack_require__.e(/*! require.ensure */ 52).then((function(require) {
 /******/ 		
 /******/ 		// object to store loaded and loading chunks
 /******/ 		// undefined = chunk not loaded, null = chunk preloaded/prefetched
-/******/ 		// Promise = chunk loading, 0 = chunk loaded
+/******/ 		// [resolve, reject, Promise] = chunk loading, 0 = chunk loaded
 /******/ 		var installedChunks = {
 /******/ 			121: 0
 /******/ 		};
 /******/ 		
-/******/ 		var deferredModules = [
-/******/ 			[2,351]
-/******/ 		];
 /******/ 		__webpack_require__.f.j = (chunkId, promises) => {
 /******/ 				// JSONP chunk loading for javascript
 /******/ 				var installedChunkData = __webpack_require__.o(installedChunks, chunkId) ? installedChunks[chunkId] : undefined;
@@ -540,9 +562,7 @@ __webpack_require__.e(/*! require.ensure */ 52).then((function(require) {
 /******/ 					} else {
 /******/ 						if(true) { // all chunks have JS
 /******/ 							// setup Promise in chunk cache
-/******/ 							var promise = new Promise((resolve, reject) => {
-/******/ 								installedChunkData = installedChunks[chunkId] = [resolve, reject];
-/******/ 							});
+/******/ 							var promise = new Promise((resolve, reject) => (installedChunkData = installedChunks[chunkId] = [resolve, reject]));
 /******/ 							promises.push(installedChunkData[2] = promise);
 /******/ 		
 /******/ 							// start chunk loading
@@ -564,7 +584,7 @@ __webpack_require__.e(/*! require.ensure */ 52).then((function(require) {
 /******/ 									}
 /******/ 								}
 /******/ 							};
-/******/ 							__webpack_require__.l(url, loadingEnded, "chunk-" + chunkId);
+/******/ 							__webpack_require__.l(url, loadingEnded, "chunk-" + chunkId, chunkId);
 /******/ 						} else installedChunks[chunkId] = 0;
 /******/ 					}
 /******/ 				}
@@ -578,69 +598,36 @@ __webpack_require__.e(/*! require.ensure */ 52).then((function(require) {
 /******/ 		
 /******/ 		// no HMR manifest
 /******/ 		
-/******/ 		var checkDeferredModules = x => {};
+/******/ 		__webpack_require__.O.j = (chunkId) => (installedChunks[chunkId] === 0);
 /******/ 		
 /******/ 		// install a JSONP callback for chunk loading
 /******/ 		var webpackJsonpCallback = (parentChunkLoadingFunction, data) => {
-/******/ 			var [chunkIds, moreModules, runtime, executeModules] = data;
+/******/ 			var [chunkIds, moreModules, runtime] = data;
 /******/ 			// add "moreModules" to the modules object,
 /******/ 			// then flag all "chunkIds" as loaded and fire callback
-/******/ 			var moduleId, chunkId, i = 0, resolves = [];
+/******/ 			var moduleId, chunkId, i = 0;
+/******/ 			if(chunkIds.some((id) => (installedChunks[id] !== 0))) {
+/******/ 				for(moduleId in moreModules) {
+/******/ 					if(__webpack_require__.o(moreModules, moduleId)) {
+/******/ 						__webpack_require__.m[moduleId] = moreModules[moduleId];
+/******/ 					}
+/******/ 				}
+/******/ 				if(runtime) var result = runtime(__webpack_require__);
+/******/ 			}
+/******/ 			if(parentChunkLoadingFunction) parentChunkLoadingFunction(data);
 /******/ 			for(;i < chunkIds.length; i++) {
 /******/ 				chunkId = chunkIds[i];
 /******/ 				if(__webpack_require__.o(installedChunks, chunkId) && installedChunks[chunkId]) {
-/******/ 					resolves.push(installedChunks[chunkId][0]);
+/******/ 					installedChunks[chunkId][0]();
 /******/ 				}
 /******/ 				installedChunks[chunkId] = 0;
 /******/ 			}
-/******/ 			for(moduleId in moreModules) {
-/******/ 				if(__webpack_require__.o(moreModules, moduleId)) {
-/******/ 					__webpack_require__.m[moduleId] = moreModules[moduleId];
-/******/ 				}
-/******/ 			}
-/******/ 			if(runtime) runtime(__webpack_require__);
-/******/ 			if(parentChunkLoadingFunction) parentChunkLoadingFunction(data);
-/******/ 			while(resolves.length) {
-/******/ 				resolves.shift()();
-/******/ 			}
-/******/ 		
-/******/ 			// add entry modules from loaded chunk to deferred list
-/******/ 			if(executeModules) deferredModules.push.apply(deferredModules, executeModules);
-/******/ 		
-/******/ 			// run deferred modules when all chunks ready
-/******/ 			return checkDeferredModules();
+/******/ 			return __webpack_require__.O(result);
 /******/ 		}
 /******/ 		
 /******/ 		var chunkLoadingGlobal = self["webpackChunk"] = self["webpackChunk"] || [];
 /******/ 		chunkLoadingGlobal.forEach(webpackJsonpCallback.bind(null, 0));
 /******/ 		chunkLoadingGlobal.push = webpackJsonpCallback.bind(null, chunkLoadingGlobal.push.bind(chunkLoadingGlobal));
-/******/ 		
-/******/ 		function checkDeferredModulesImpl() {
-/******/ 			var result;
-/******/ 			for(var i = 0; i < deferredModules.length; i++) {
-/******/ 				var deferredModule = deferredModules[i];
-/******/ 				var fulfilled = true;
-/******/ 				for(var j = 1; j < deferredModule.length; j++) {
-/******/ 					var depId = deferredModule[j];
-/******/ 					if(installedChunks[depId] !== 0) fulfilled = false;
-/******/ 				}
-/******/ 				if(fulfilled) {
-/******/ 					deferredModules.splice(i--, 1);
-/******/ 					result = __webpack_require__(__webpack_require__.s = deferredModule[0]);
-/******/ 				}
-/******/ 			}
-/******/ 			if(deferredModules.length === 0) {
-/******/ 				__webpack_require__.x();
-/******/ 				__webpack_require__.x = x => {};
-/******/ 			}
-/******/ 			return result;
-/******/ 		}
-/******/ 		var startup = __webpack_require__.x;
-/******/ 		__webpack_require__.x = () => {
-/******/ 			// reset startup function so it can be called again when more startup code is added
-/******/ 			__webpack_require__.x = startup || (x => {});
-/******/ 			return (checkDeferredModules = checkDeferredModulesImpl)();
-/******/ 		};
 /******/ 	})();
 /******/ 	
 /************************************************************************/
@@ -649,8 +636,13 @@ __webpack_require__.e(/*! require.ensure */ 52).then((function(require) {
 
 
 ``` js
-/******/ 	// run startup
-/******/ 	return __webpack_require__.x();
+/******/ 	
+/******/ 	// startup
+/******/ 	// Load entry module and return exports
+/******/ 	// This entry module depends on other loaded chunks and execution need to be delayed
+/******/ 	var __webpack_exports__ = __webpack_require__.O(undefined, [351], () => (__webpack_require__(2)))
+/******/ 	__webpack_exports__ = __webpack_require__.O(__webpack_exports__);
+/******/ 	
 /******/ })()
 ;
 ```
@@ -685,23 +677,24 @@ module.exports = function(msg) {
 
 ```
 asset pageA.js 10.7 KiB [emitted] (name: pageA)
-asset pageB.js 10.6 KiB [emitted] (name: pageB)
+asset pageB.js 10.7 KiB [emitted] (name: pageB)
 asset 52.js 506 bytes [emitted]
 asset commons.js 364 bytes [emitted] (name: commons) (id hint: commons)
-Entrypoint pageA 11 KiB = commons.js 364 bytes pageA.js 10.7 KiB
-Entrypoint pageB 11 KiB = commons.js 364 bytes pageB.js 10.6 KiB
+Entrypoint pageA 11.1 KiB = commons.js 364 bytes pageA.js 10.7 KiB
+Entrypoint pageB 11 KiB = commons.js 364 bytes pageB.js 10.7 KiB
 chunk (runtime: pageA, pageB) 52.js 88 bytes [rendered]
   > ./shared ./pageA.js 2:0-4:2
   > ./pageB.js 2:0-5:2
   ./shared.js 88 bytes [built] [code generated]
     [used exports unknown]
+    from origin ./pageB.js
+      require.ensure item ./shared ./pageB.js 2:0-5:2
+      cjs require ./shared ./pageB.js 3:14-33
     amd require ./shared ./pageA.js 2:0-4:2
-    require.ensure item ./shared ./pageB.js 2:0-5:2
-    cjs require ./shared ./pageB.js 3:14-33
     cjs self exports reference ./shared.js 2:0-14
-chunk (runtime: pageB) pageB.js (pageB) 148 bytes (javascript) 6.03 KiB (runtime) [entry] [rendered]
+chunk (runtime: pageB) pageB.js (pageB) 148 bytes (javascript) 5.91 KiB (runtime) [entry] [rendered]
   > ./pageB pageB
-  runtime modules 6.03 KiB 6 modules
+  runtime modules 5.91 KiB 7 modules
   ./pageB.js 148 bytes [built] [code generated]
     [used exports unknown]
     entry ./pageB pageB
@@ -714,36 +707,37 @@ chunk (runtime: pageA, pageB) commons.js (commons) (id hint: commons) 26 bytes [
     cjs require ./common ./pageA.js 1:13-32
     cjs require ./common ./pageB.js 1:13-32
     cjs require ./common ./shared.js 1:13-32
-chunk (runtime: pageA) pageA.js (pageA) 105 bytes (javascript) 6.03 KiB (runtime) [entry] [rendered]
+chunk (runtime: pageA) pageA.js (pageA) 105 bytes (javascript) 5.91 KiB (runtime) [entry] [rendered]
   > ./pageA pageA
-  runtime modules 6.03 KiB 6 modules
+  runtime modules 5.91 KiB 7 modules
   ./pageA.js 105 bytes [built] [code generated]
     [used exports unknown]
     entry ./pageA pageA
-webpack 5.11.1 compiled successfully
+webpack 5.78.0 compiled successfully
 ```
 
 ## Production mode
 
 ```
-asset pageA.js 2.04 KiB [emitted] [minimized] (name: pageA)
-asset pageB.js 2.01 KiB [emitted] [minimized] (name: pageB)
+asset pageA.js 2.16 KiB [emitted] [minimized] (name: pageA)
+asset pageB.js 2.13 KiB [emitted] [minimized] (name: pageB)
 asset 52.js 116 bytes [emitted] [minimized]
 asset commons.js 86 bytes [emitted] [minimized] (name: commons) (id hint: commons)
-Entrypoint pageA 2.12 KiB = commons.js 86 bytes pageA.js 2.04 KiB
-Entrypoint pageB 2.1 KiB = commons.js 86 bytes pageB.js 2.01 KiB
+Entrypoint pageA 2.24 KiB = commons.js 86 bytes pageA.js 2.16 KiB
+Entrypoint pageB 2.21 KiB = commons.js 86 bytes pageB.js 2.13 KiB
 chunk (runtime: pageA, pageB) 52.js 88 bytes [rendered]
   > ./shared ./pageA.js 2:0-4:2
   > ./pageB.js 2:0-5:2
   ./shared.js 88 bytes [built] [code generated]
     [used exports unknown]
+    from origin ./pageB.js
+      require.ensure item ./shared ./pageB.js 2:0-5:2
+      cjs require ./shared ./pageB.js 3:14-33
     amd require ./shared ./pageA.js 2:0-4:2
-    require.ensure item ./shared ./pageB.js 2:0-5:2
-    cjs require ./shared ./pageB.js 3:14-33
     cjs self exports reference ./shared.js 2:0-14
-chunk (runtime: pageB) pageB.js (pageB) 148 bytes (javascript) 6.03 KiB (runtime) [entry] [rendered]
+chunk (runtime: pageB) pageB.js (pageB) 148 bytes (javascript) 5.91 KiB (runtime) [entry] [rendered]
   > ./pageB pageB
-  runtime modules 6.03 KiB 6 modules
+  runtime modules 5.91 KiB 7 modules
   ./pageB.js 148 bytes [built] [code generated]
     [no exports used]
     entry ./pageB pageB
@@ -756,11 +750,11 @@ chunk (runtime: pageA, pageB) commons.js (commons) (id hint: commons) 26 bytes [
     cjs require ./common ./pageA.js 1:13-32
     cjs require ./common ./pageB.js 1:13-32
     cjs require ./common ./shared.js 1:13-32
-chunk (runtime: pageA) pageA.js (pageA) 105 bytes (javascript) 6.03 KiB (runtime) [entry] [rendered]
+chunk (runtime: pageA) pageA.js (pageA) 105 bytes (javascript) 5.91 KiB (runtime) [entry] [rendered]
   > ./pageA pageA
-  runtime modules 6.03 KiB 6 modules
+  runtime modules 5.91 KiB 7 modules
   ./pageA.js 105 bytes [built] [code generated]
     [no exports used]
     entry ./pageA pageA
-webpack 5.11.1 compiled successfully
+webpack 5.78.0 compiled successfully
 ```
diff --git a/examples/multiple-entry-points/webpack.config.js b/examples/multiple-entry-points/webpack.config.js
index 4df8e07d565..a4fdc01c909 100644
--- a/examples/multiple-entry-points/webpack.config.js
+++ b/examples/multiple-entry-points/webpack.config.js
@@ -1,5 +1,5 @@
 module.exports = {
-	// mode: "development || "production",
+	// mode: "development" || "production",
 	entry: {
 		pageA: "./pageA",
 		pageB: "./pageB"
diff --git a/examples/named-chunks/README.md b/examples/named-chunks/README.md
index f0b41b963fd..f2410692722 100644
--- a/examples/named-chunks/README.md
+++ b/examples/named-chunks/README.md
@@ -53,8 +53,9 @@ require.ensure(["b"], function(require) {
 /******/ 	// The require function
 /******/ 	function __webpack_require__(moduleId) {
 /******/ 		// Check if module is in cache
-/******/ 		if(__webpack_module_cache__[moduleId]) {
-/******/ 			return __webpack_module_cache__[moduleId].exports;
+/******/ 		var cachedModule = __webpack_module_cache__[moduleId];
+/******/ 		if (cachedModule !== undefined) {
+/******/ 			return cachedModule.exports;
 /******/ 		}
 /******/ 		// Create a new module (and put it into the cache)
 /******/ 		var module = __webpack_module_cache__[moduleId] = {
@@ -98,7 +99,7 @@ require.ensure(["b"], function(require) {
 /******/ 	
 /******/ 	/* webpack/runtime/hasOwnProperty shorthand */
 /******/ 	(() => {
-/******/ 		__webpack_require__.o = (obj, prop) => Object.prototype.hasOwnProperty.call(obj, prop)
+/******/ 		__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
 /******/ 	})();
 /******/ 	
 /******/ 	/* webpack/runtime/load script */
@@ -106,7 +107,7 @@ require.ensure(["b"], function(require) {
 /******/ 		var inProgress = {};
 /******/ 		// data-webpack is not used as build has no uniqueName
 /******/ 		// loadScript function to load a script via script tag
-/******/ 		__webpack_require__.l = (url, done, key) => {
+/******/ 		__webpack_require__.l = (url, done, key, chunkId) => {
 /******/ 			if(inProgress[url]) { inProgress[url].push(done); return; }
 /******/ 			var script, needAttach;
 /******/ 			if(key !== undefined) {
@@ -136,10 +137,9 @@ require.ensure(["b"], function(require) {
 /******/ 				var doneFns = inProgress[url];
 /******/ 				delete inProgress[url];
 /******/ 				script.parentNode && script.parentNode.removeChild(script);
-/******/ 				doneFns && doneFns.forEach((fn) => fn(event));
+/******/ 				doneFns && doneFns.forEach((fn) => (fn(event)));
 /******/ 				if(prev) return prev(event);
 /******/ 			}
-/******/ 			;
 /******/ 			var timeout = setTimeout(onScriptComplete.bind(null, undefined, { type: 'timeout', target: script }), 120000);
 /******/ 			script.onerror = onScriptComplete.bind(null, script.onerror);
 /******/ 			script.onload = onScriptComplete.bind(null, script.onload);
@@ -158,12 +158,11 @@ require.ensure(["b"], function(require) {
 /******/ 		
 /******/ 		// object to store loaded and loading chunks
 /******/ 		// undefined = chunk not loaded, null = chunk preloaded/prefetched
-/******/ 		// Promise = chunk loading, 0 = chunk loaded
+/******/ 		// [resolve, reject, Promise] = chunk loading, 0 = chunk loaded
 /******/ 		var installedChunks = {
 /******/ 			179: 0
 /******/ 		};
 /******/ 		
-/******/ 		
 /******/ 		__webpack_require__.f.j = (chunkId, promises) => {
 /******/ 				// JSONP chunk loading for javascript
 /******/ 				var installedChunkData = __webpack_require__.o(installedChunks, chunkId) ? installedChunks[chunkId] : undefined;
@@ -175,9 +174,7 @@ require.ensure(["b"], function(require) {
 /******/ 					} else {
 /******/ 						if(true) { // all chunks have JS
 /******/ 							// setup Promise in chunk cache
-/******/ 							var promise = new Promise((resolve, reject) => {
-/******/ 								installedChunkData = installedChunks[chunkId] = [resolve, reject];
-/******/ 							});
+/******/ 							var promise = new Promise((resolve, reject) => (installedChunkData = installedChunks[chunkId] = [resolve, reject]));
 /******/ 							promises.push(installedChunkData[2] = promise);
 /******/ 		
 /******/ 							// start chunk loading
@@ -199,7 +196,7 @@ require.ensure(["b"], function(require) {
 /******/ 									}
 /******/ 								}
 /******/ 							};
-/******/ 							__webpack_require__.l(url, loadingEnded, "chunk-" + chunkId);
+/******/ 							__webpack_require__.l(url, loadingEnded, "chunk-" + chunkId, chunkId);
 /******/ 						} else installedChunks[chunkId] = 0;
 /******/ 					}
 /******/ 				}
@@ -213,39 +210,36 @@ require.ensure(["b"], function(require) {
 /******/ 		
 /******/ 		// no HMR manifest
 /******/ 		
-/******/ 		// no deferred startup
+/******/ 		// no on chunks loaded
 /******/ 		
 /******/ 		// install a JSONP callback for chunk loading
 /******/ 		var webpackJsonpCallback = (parentChunkLoadingFunction, data) => {
 /******/ 			var [chunkIds, moreModules, runtime] = data;
 /******/ 			// add "moreModules" to the modules object,
 /******/ 			// then flag all "chunkIds" as loaded and fire callback
-/******/ 			var moduleId, chunkId, i = 0, resolves = [];
+/******/ 			var moduleId, chunkId, i = 0;
+/******/ 			if(chunkIds.some((id) => (installedChunks[id] !== 0))) {
+/******/ 				for(moduleId in moreModules) {
+/******/ 					if(__webpack_require__.o(moreModules, moduleId)) {
+/******/ 						__webpack_require__.m[moduleId] = moreModules[moduleId];
+/******/ 					}
+/******/ 				}
+/******/ 				if(runtime) var result = runtime(__webpack_require__);
+/******/ 			}
+/******/ 			if(parentChunkLoadingFunction) parentChunkLoadingFunction(data);
 /******/ 			for(;i < chunkIds.length; i++) {
 /******/ 				chunkId = chunkIds[i];
 /******/ 				if(__webpack_require__.o(installedChunks, chunkId) && installedChunks[chunkId]) {
-/******/ 					resolves.push(installedChunks[chunkId][0]);
+/******/ 					installedChunks[chunkId][0]();
 /******/ 				}
 /******/ 				installedChunks[chunkId] = 0;
 /******/ 			}
-/******/ 			for(moduleId in moreModules) {
-/******/ 				if(__webpack_require__.o(moreModules, moduleId)) {
-/******/ 					__webpack_require__.m[moduleId] = moreModules[moduleId];
-/******/ 				}
-/******/ 			}
-/******/ 			if(runtime) runtime(__webpack_require__);
-/******/ 			if(parentChunkLoadingFunction) parentChunkLoadingFunction(data);
-/******/ 			while(resolves.length) {
-/******/ 				resolves.shift()();
-/******/ 			}
 /******/ 		
 /******/ 		}
 /******/ 		
 /******/ 		var chunkLoadingGlobal = self["webpackChunk"] = self["webpackChunk"] || [];
 /******/ 		chunkLoadingGlobal.forEach(webpackJsonpCallback.bind(null, 0));
 /******/ 		chunkLoadingGlobal.push = webpackJsonpCallback.bind(null, chunkLoadingGlobal.push.bind(chunkLoadingGlobal));
-/******/ 		
-/******/ 		// no deferred startup
 /******/ 	})();
 /******/ 	
 /************************************************************************/
@@ -254,6 +248,8 @@ require.ensure(["b"], function(require) {
 
 
 ``` js
+var __webpack_exports__ = {};
+// This entry need to be wrapped in an IIFE because it need to be isolated against other modules in the chunk.
 (() => {
 /*!********************!*\
   !*** ./example.js ***!
@@ -265,21 +261,21 @@ var a = __webpack_require__(/*! a */ 1);
 __webpack_require__.e(/*! require.ensure | my own chunk */ 666).then((function(require) {
 	// a named chunk
 	var c = __webpack_require__(/*! c */ 3);
-}).bind(null, __webpack_require__)).catch(__webpack_require__.oe);
+}).bind(null, __webpack_require__))['catch'](__webpack_require__.oe);
 
 __webpack_require__.e(/*! require.ensure | my own chunk */ 666).then((function(require) {
 	// another chunk with the same name
 	var d = __webpack_require__(/*! d */ 4);
-}).bind(null, __webpack_require__)).catch(__webpack_require__.oe);
+}).bind(null, __webpack_require__))['catch'](__webpack_require__.oe);
 
 __webpack_require__.e(/*! require.ensure | my own chunk */ 666).then((function(require) {
 	// the same again
-}).bind(null, __webpack_require__)).catch(__webpack_require__.oe);
+}).bind(null, __webpack_require__))['catch'](__webpack_require__.oe);
 
 __webpack_require__.e(/*! require.ensure */ 885).then((function(require) {
 	// chunk without name
 	var d = __webpack_require__(/*! d */ 4);
-}).bind(null, __webpack_require__)).catch(__webpack_require__.oe);
+}).bind(null, __webpack_require__))['catch'](__webpack_require__.oe);
 
 })();
 
@@ -366,7 +362,7 @@ __webpack_require__.e(/*! require.ensure */ 885).then((function(require) {
 ## Unoptimized
 
 ```
-asset output.js 9.72 KiB [emitted] (name: main)
+asset output.js 9.83 KiB [emitted] (name: main)
 asset 666.output.js 735 bytes [emitted] (name: my own chunk)
 asset 885.output.js 528 bytes [emitted]
 chunk (runtime: main) output.js (main) 432 bytes (javascript) 4.97 KiB (runtime) [entry] [rendered]
@@ -403,7 +399,7 @@ chunk (runtime: main) 885.output.js 22 bytes [rendered]
     [used exports unknown]
     cjs require d ./example.js 10:9-21
     cjs require d ./example.js 19:9-21
-webpack 5.11.1 compiled successfully
+webpack 5.78.0 compiled successfully
 ```
 
 ## Production mode
@@ -446,5 +442,5 @@ chunk (runtime: main) 885.output.js 22 bytes [rendered]
     [used exports unknown]
     cjs require d ./example.js 10:9-21
     cjs require d ./example.js 19:9-21
-webpack 5.11.1 compiled successfully
+webpack 5.78.0 compiled successfully
 ```
diff --git a/examples/node_modules/module.js b/examples/node_modules/module.js
index f23403c2c0f..d6df8480e22 100644
--- a/examples/node_modules/module.js
+++ b/examples/node_modules/module.js
@@ -1 +1 @@
-module.exports = "module";
\ No newline at end of file
+module.exports = "module";
diff --git a/examples/persistent-caching/README.md b/examples/persistent-caching/README.md
index c7ba3a570b6..f8dd47f36b6 100644
--- a/examples/persistent-caching/README.md
+++ b/examples/persistent-caching/README.md
@@ -55,34 +55,34 @@ module.exports = (env = "development") => ({
 ## Unoptimized
 
 ```
-asset output.js 3.99 MiB [emitted] (name: main)
-chunk (runtime: main) output.js (main) 2.86 MiB (javascript) 1.58 KiB (runtime) [entry]
+asset output.js 4.52 MiB [emitted] (name: main)
+chunk (runtime: main) output.js (main) 3.26 MiB (javascript) 1.29 KiB (runtime) [entry]
   > ./example.js main
-  cached modules 2.86 MiB (javascript) 1.58 KiB (runtime) [cached] 1210 modules
-webpack 5.11.1 compiled successfully
+  cached modules 3.26 MiB (javascript) 1.29 KiB (runtime) [cached] 1415 modules
+webpack 5.78.0 compiled successfully
 ```
 
 ## Production mode
 
 ```
-asset output.js 551 KiB [emitted] [minimized] [big] (name: main) 1 related asset
-chunk (runtime: main) output.js (main) 1.91 MiB (javascript) 1.58 KiB (runtime) [entry]
+asset output.js 630 KiB [emitted] [minimized] [big] (name: main) 1 related asset
+chunk (runtime: main) output.js (main) 2.18 MiB (javascript) 1.29 KiB (runtime) [entry]
   > ./example.js main
-  cached modules 1.91 MiB (javascript) 1.58 KiB (runtime) [cached] 591 modules
+  cached modules 2.18 MiB (javascript) 1.29 KiB (runtime) [cached] 791 modules
 
 WARNING in asset size limit: The following asset(s) exceed the recommended size limit (244 KiB).
 This can impact web performance.
 Assets: 
-  output.js (551 KiB)
+  output.js (630 KiB)
 
 WARNING in entrypoint size limit: The following entrypoint(s) combined asset size exceeds the recommended limit (244 KiB). This can impact web performance.
 Entrypoints:
-  main (551 KiB)
+  main (630 KiB)
       output.js
 
 WARNING in webpack performance recommendations: 
 You can limit the size of your bundles by using import() or require.ensure to lazy load some parts of your application.
 For more info visit https://webpack.js.org/guides/code-splitting/
 
-webpack 5.11.1 compiled with 3 warnings
+webpack 5.78.0 compiled with 3 warnings
 ```
diff --git a/examples/reexport-components/README.md b/examples/reexport-components/README.md
index 0668a0b8538..6664b1ec603 100644
--- a/examples/reexport-components/README.md
+++ b/examples/reexport-components/README.md
@@ -49,6 +49,7 @@ export { DialogInline } from "./DialogInline";
 # dist/pages_Dashboard_js.output.js
 
 ```javascript
+"use strict";
 (self["webpackChunk"] = self["webpackChunk"] || []).push([["pages_Dashboard_js"],{
 
 /***/ "./components/Button.js":
@@ -60,16 +61,14 @@ export { DialogInline } from "./DialogInline";
 /*! runtime requirements: __webpack_exports__, __webpack_require__.d, __webpack_require__.* */
 /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
 
-"use strict";
 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
-/* harmony export */   "default": () => /* binding */ Button
+/* harmony export */   "default": () => (/* binding */ Button)
 /* harmony export */ });
 const Button = () => {
   return /*#__PURE__*/React.createElement("button", null);
 };
 
 
-
 /***/ }),
 
 /***/ "./components/Checkbox.js":
@@ -81,9 +80,8 @@ const Button = () => {
 /*! runtime requirements: __webpack_exports__, __webpack_require__.d, __webpack_require__.* */
 /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
 
-"use strict";
 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
-/* harmony export */   "Checkbox": () => /* binding */ Checkbox
+/* harmony export */   "Checkbox": () => (/* binding */ Checkbox)
 /* harmony export */ });
 const Checkbox = () => {
   return /*#__PURE__*/React.createElement("input", {
@@ -92,7 +90,6 @@ const Checkbox = () => {
 };
 
 
-
 /***/ }),
 
 /***/ "./pages/Dashboard.js":
@@ -105,19 +102,16 @@ const Checkbox = () => {
 /*! runtime requirements: __webpack_require__, __webpack_exports__, __webpack_require__.r, __webpack_require__.d, __webpack_require__.* */
 /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
 
-"use strict";
 __webpack_require__.r(__webpack_exports__);
 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
-/* harmony export */   "default": () => __WEBPACK_DEFAULT_EXPORT__
+/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
 /* harmony export */ });
 /* harmony import */ var _components__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../components */ "./components/Button.js");
 /* harmony import */ var _components__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../components */ "./components/Checkbox.js");
 
-
 const Dashboard = () => {
-  return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(_components__WEBPACK_IMPORTED_MODULE_0__.default, null), /*#__PURE__*/React.createElement(_components__WEBPACK_IMPORTED_MODULE_1__.Checkbox, null));
+  return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(_components__WEBPACK_IMPORTED_MODULE_0__["default"], null), /*#__PURE__*/React.createElement(_components__WEBPACK_IMPORTED_MODULE_1__.Checkbox, null));
 };
-
 /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (Dashboard);
 
 /***/ })
@@ -128,6 +122,7 @@ const Dashboard = () => {
 # dist/pages_Login_js.output.js
 
 ```javascript
+"use strict";
 (self["webpackChunk"] = self["webpackChunk"] || []).push([["pages_Login_js"],{
 
 /***/ "./components/Button.js":
@@ -139,16 +134,14 @@ const Dashboard = () => {
 /*! runtime requirements: __webpack_exports__, __webpack_require__.d, __webpack_require__.* */
 /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
 
-"use strict";
 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
-/* harmony export */   "default": () => /* binding */ Button
+/* harmony export */   "default": () => (/* binding */ Button)
 /* harmony export */ });
 const Button = () => {
   return /*#__PURE__*/React.createElement("button", null);
 };
 
 
-
 /***/ }),
 
 /***/ "./components/Dialog.js":
@@ -160,16 +153,14 @@ const Button = () => {
 /*! runtime requirements: __webpack_exports__, __webpack_require__.d, __webpack_require__.* */
 /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
 
-"use strict";
 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
-/* harmony export */   "default": () => __WEBPACK_DEFAULT_EXPORT__
+/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
 /* harmony export */ });
 const Dialog = ({
   children
 }) => {
   return /*#__PURE__*/React.createElement("dialog", null, children);
 };
-
 /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (Dialog);
 
 /***/ }),
@@ -184,19 +175,16 @@ const Dialog = ({
 /*! runtime requirements: __webpack_require__, __webpack_exports__, __webpack_require__.r, __webpack_require__.d, __webpack_require__.* */
 /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
 
-"use strict";
 __webpack_require__.r(__webpack_exports__);
 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
-/* harmony export */   "default": () => __WEBPACK_DEFAULT_EXPORT__
+/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
 /* harmony export */ });
 /* harmony import */ var _components__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../components */ "./components/Button.js");
 /* harmony import */ var _components__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../components */ "./components/Dialog.js");
 
-
 const Login = () => {
-  return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(_components__WEBPACK_IMPORTED_MODULE_0__.default, null), /*#__PURE__*/React.createElement(_components__WEBPACK_IMPORTED_MODULE_1__.default, null));
+  return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(_components__WEBPACK_IMPORTED_MODULE_0__["default"], null), /*#__PURE__*/React.createElement(_components__WEBPACK_IMPORTED_MODULE_1__["default"], null));
 };
-
 /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (Login);
 
 /***/ })
@@ -205,7 +193,7 @@ const Login = () => {
 ```
 
 ```javascript
-(self.webpackChunk=self.webpackChunk||[]).push([["pages_Login_js"],{"./components/Button.js":(e,t,n)=>{"use strict";n.d(t,{Z:()=>c});const c=()=>React.createElement("button",null)},"./pages/Login.js":(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>a});const c=({children:e})=>React.createElement("dialog",null,e);var l=n("./components/Button.js");const a=()=>React.createElement(React.Fragment,null,React.createElement(l.Z,null),React.createElement(c,null))}}]);
+"use strict";(self.webpackChunk=self.webpackChunk||[]).push([["pages_Login_js"],{"./components/Button.js":(e,t,n)=>{n.d(t,{Z:()=>l});const l=()=>React.createElement("button",null)},"./pages/Login.js":(e,t,n)=>{n.r(t),n.d(t,{default:()=>c});var l=n("./components/Button.js");const a=({children:e})=>React.createElement("dialog",null,e),c=()=>React.createElement(React.Fragment,null,React.createElement(l.Z,null),React.createElement(a,null))}}]);
 ```
 
 # Info
@@ -213,9 +201,9 @@ const Login = () => {
 ## Unoptimized
 
 ```
-asset output.js 10.9 KiB [emitted] (name: main)
-asset pages_Login_js.output.js 2.84 KiB [emitted]
-asset pages_Dashboard_js.output.js 2.8 KiB [emitted]
+asset output.js 11 KiB [emitted] (name: main)
+asset pages_Login_js.output.js 2.82 KiB [emitted]
+asset pages_Dashboard_js.output.js 2.78 KiB [emitted]
 chunk (runtime: main) output.js (main) 208 bytes (javascript) 5.54 KiB (runtime) [entry] [rendered]
   > ./example.js main
   runtime modules 5.54 KiB 8 modules
@@ -223,31 +211,31 @@ chunk (runtime: main) output.js (main) 208 bytes (javascript) 5.54 KiB (runtime)
   ./example.js 48 bytes [built] [code generated]
     [no exports used]
     entry ./example.js main
-chunk (runtime: main) pages_Dashboard_js.output.js 513 bytes [rendered]
+chunk (runtime: main) pages_Dashboard_js.output.js 509 bytes [rendered]
   > ./Dashboard ./pages/ lazy ^\.\/.*$ namespace object ./Dashboard
   > ./Dashboard.js ./pages/ lazy ^\.\/.*$ namespace object ./Dashboard.js
-  dependent modules 244 bytes [dependent] 2 modules
-  ./pages/Dashboard.js 269 bytes [optional] [built] [code generated]
+  dependent modules 242 bytes [dependent] 2 modules
+  ./pages/Dashboard.js 267 bytes [optional] [built] [code generated]
     [exports: default]
-    context element ./Dashboard ./pages/ lazy ^\.\/.*$ namespace object ./Dashboard
-    context element ./Dashboard.js ./pages/ lazy ^\.\/.*$ namespace object ./Dashboard.js
-chunk (runtime: main) pages_Login_js.output.js 504 bytes [rendered]
+    import() context element ./Dashboard ./pages/ lazy ^\.\/.*$ namespace object ./Dashboard
+    import() context element ./Dashboard.js ./pages/ lazy ^\.\/.*$ namespace object ./Dashboard.js
+chunk (runtime: main) pages_Login_js.output.js 500 bytes [rendered]
   > ./Login ./pages/ lazy ^\.\/.*$ namespace object ./Login
   > ./Login.js ./pages/ lazy ^\.\/.*$ namespace object ./Login.js
-  dependent modules 247 bytes [dependent] 2 modules
-  ./pages/Login.js 257 bytes [optional] [built] [code generated]
+  dependent modules 245 bytes [dependent] 2 modules
+  ./pages/Login.js 255 bytes [optional] [built] [code generated]
     [exports: default]
-    context element ./Login ./pages/ lazy ^\.\/.*$ namespace object ./Login
-    context element ./Login.js ./pages/ lazy ^\.\/.*$ namespace object ./Login.js
-webpack 5.11.1 compiled successfully
+    import() context element ./Login ./pages/ lazy ^\.\/.*$ namespace object ./Login
+    import() context element ./Login.js ./pages/ lazy ^\.\/.*$ namespace object ./Login.js
+webpack 5.78.0 compiled successfully
 ```
 
 ## Production mode
 
 ```
-asset output.js 2.48 KiB [emitted] [minimized] (name: main)
-asset pages_Dashboard_js.output.js 469 bytes [emitted] [minimized]
-asset pages_Login_js.output.js 463 bytes [emitted] [minimized]
+asset output.js 2.49 KiB [emitted] [minimized] (name: main)
+asset pages_Dashboard_js.output.js 450 bytes [emitted] [minimized]
+asset pages_Login_js.output.js 444 bytes [emitted] [minimized]
 chunk (runtime: main) output.js (main) 208 bytes (javascript) 5.54 KiB (runtime) [entry] [rendered]
   > ./example.js main
   runtime modules 5.54 KiB 8 modules
@@ -255,21 +243,21 @@ chunk (runtime: main) output.js (main) 208 bytes (javascript) 5.54 KiB (runtime)
   ./example.js 48 bytes [built] [code generated]
     [no exports used]
     entry ./example.js main
-chunk (runtime: main) pages_Dashboard_js.output.js 513 bytes [rendered]
+chunk (runtime: main) pages_Dashboard_js.output.js 509 bytes [rendered]
   > ./Dashboard ./pages/ lazy ^\.\/.*$ namespace object ./Dashboard
   > ./Dashboard.js ./pages/ lazy ^\.\/.*$ namespace object ./Dashboard.js
-  dependent modules 115 bytes [dependent] 1 module
-  ./pages/Dashboard.js + 1 modules 398 bytes [optional] [built] [code generated]
+  dependent modules 114 bytes [dependent] 1 module
+  ./pages/Dashboard.js + 1 modules 395 bytes [optional] [built] [code generated]
     [exports: default]
-    context element ./Dashboard ./pages/ lazy ^\.\/.*$ namespace object ./Dashboard
-    context element ./Dashboard.js ./pages/ lazy ^\.\/.*$ namespace object ./Dashboard.js
-chunk (runtime: main) pages_Login_js.output.js 504 bytes [rendered]
+    import() context element ./Dashboard ./pages/ lazy ^\.\/.*$ namespace object ./Dashboard
+    import() context element ./Dashboard.js ./pages/ lazy ^\.\/.*$ namespace object ./Dashboard.js
+chunk (runtime: main) pages_Login_js.output.js 500 bytes [rendered]
   > ./Login ./pages/ lazy ^\.\/.*$ namespace object ./Login
   > ./Login.js ./pages/ lazy ^\.\/.*$ namespace object ./Login.js
-  dependent modules 115 bytes [dependent] 1 module
-  ./pages/Login.js + 1 modules 389 bytes [optional] [built] [code generated]
+  dependent modules 114 bytes [dependent] 1 module
+  ./pages/Login.js + 1 modules 386 bytes [optional] [built] [code generated]
     [exports: default]
-    context element ./Login ./pages/ lazy ^\.\/.*$ namespace object ./Login
-    context element ./Login.js ./pages/ lazy ^\.\/.*$ namespace object ./Login.js
-webpack 5.11.1 compiled successfully
+    import() context element ./Login ./pages/ lazy ^\.\/.*$ namespace object ./Login
+    import() context element ./Login.js ./pages/ lazy ^\.\/.*$ namespace object ./Login.js
+webpack 5.78.0 compiled successfully
 ```
diff --git a/examples/require.context/README.md b/examples/require.context/README.md
index 321edb576fa..237b4d49e12 100644
--- a/examples/require.context/README.md
+++ b/examples/require.context/README.md
@@ -122,8 +122,9 @@ module.exports = function() {
 /******/ 	// The require function
 /******/ 	function __webpack_require__(moduleId) {
 /******/ 		// Check if module is in cache
-/******/ 		if(__webpack_module_cache__[moduleId]) {
-/******/ 			return __webpack_module_cache__[moduleId].exports;
+/******/ 		var cachedModule = __webpack_module_cache__[moduleId];
+/******/ 		if (cachedModule !== undefined) {
+/******/ 			return cachedModule.exports;
 /******/ 		}
 /******/ 		// Create a new module (and put it into the cache)
 /******/ 		var module = __webpack_module_cache__[moduleId] = {
@@ -142,7 +143,7 @@ module.exports = function() {
 /************************************************************************/
 /******/ 	/* webpack/runtime/hasOwnProperty shorthand */
 /******/ 	(() => {
-/******/ 		__webpack_require__.o = (obj, prop) => Object.prototype.hasOwnProperty.call(obj, prop)
+/******/ 		__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
 /******/ 	})();
 /******/ 	
 /************************************************************************/
@@ -151,6 +152,8 @@ module.exports = function() {
 
 
 ``` js
+var __webpack_exports__ = {};
+// This entry need to be wrapped in an IIFE because it need to be isolated against other modules in the chunk.
 (() => {
 /*!********************!*\
   !*** ./example.js ***!
@@ -173,29 +176,29 @@ console.log(getTemplate("b"));
 ## Unoptimized
 
 ```
-asset output.js 3.62 KiB [emitted] (name: main)
-chunk (runtime: main) output.js (main) 603 bytes (javascript) 86 bytes (runtime) [entry] [rendered]
+asset output.js 3.8 KiB [emitted] (name: main)
+chunk (runtime: main) output.js (main) 603 bytes (javascript) 88 bytes (runtime) [entry] [rendered]
   > ./example.js main
   dependent modules 457 bytes [dependent] 4 modules
-  runtime modules 86 bytes 1 module
+  runtime modules 88 bytes 1 module
   ./example.js 146 bytes [built] [code generated]
     [used exports unknown]
     entry ./example.js main
-webpack 5.11.1 compiled successfully
+webpack 5.78.0 compiled successfully
 ```
 
 ## Production mode
 
 ```
-asset output.js 819 bytes [emitted] [minimized] (name: main)
-chunk (runtime: main) output.js (main) 603 bytes (javascript) 86 bytes (runtime) [entry] [rendered]
+asset output.js 833 bytes [emitted] [minimized] (name: main)
+chunk (runtime: main) output.js (main) 603 bytes (javascript) 88 bytes (runtime) [entry] [rendered]
   > ./example.js main
   dependent modules 457 bytes [dependent] 4 modules
-  runtime modules 86 bytes 1 module
+  runtime modules 88 bytes 1 module
   ./example.js 146 bytes [built] [code generated]
     [no exports used]
     entry ./example.js main
-webpack 5.11.1 compiled successfully
+webpack 5.78.0 compiled successfully
 ```
 
 # Code Splitting
diff --git a/examples/require.resolve/README.md b/examples/require.resolve/README.md
index 10ec3ef667c..d78646e8e4a 100644
--- a/examples/require.resolve/README.md
+++ b/examples/require.resolve/README.md
@@ -76,8 +76,9 @@ module.exports = Math.random();
 /******/ 	// The require function
 /******/ 	function __webpack_require__(moduleId) {
 /******/ 		// Check if module is in cache
-/******/ 		if(__webpack_module_cache__[moduleId]) {
-/******/ 			return __webpack_module_cache__[moduleId].exports;
+/******/ 		var cachedModule = __webpack_module_cache__[moduleId];
+/******/ 		if (cachedModule !== undefined) {
+/******/ 			return cachedModule.exports;
 /******/ 		}
 /******/ 		// Create a new module (and put it into the cache)
 /******/ 		var module = __webpack_module_cache__[moduleId] = {
@@ -105,10 +106,12 @@ module.exports = Math.random();
 
 
 ``` js
+/******/ 	
 /******/ 	// module cache are used so entry inlining is disabled
 /******/ 	// startup
-/******/ 	// Load entry module
-/******/ 	__webpack_require__(0);
+/******/ 	// Load entry module and return exports
+/******/ 	var __webpack_exports__ = __webpack_require__(0);
+/******/ 	
 /******/ })()
 ;
 ```
@@ -118,25 +121,25 @@ module.exports = Math.random();
 ## Unoptimized
 
 ```
-asset output.js 2.31 KiB [emitted] (name: main)
+asset output.js 2.41 KiB [emitted] (name: main)
 chunk (runtime: main) output.js (main) 313 bytes [entry] [rendered]
   > ./example.js main
   dependent modules 31 bytes [dependent] 1 module
   ./example.js 282 bytes [built] [code generated]
     [used exports unknown]
     entry ./example.js main
-webpack 5.11.1 compiled successfully
+webpack 5.78.0 compiled successfully
 ```
 
 ## Production mode
 
 ```
-asset output.js 297 bytes [emitted] [minimized] (name: main)
+asset output.js 311 bytes [emitted] [minimized] (name: main)
 chunk (runtime: main) output.js (main) 313 bytes [entry] [rendered]
   > ./example.js main
   dependent modules 31 bytes [dependent] 1 module
   ./example.js 282 bytes [built] [code generated]
     [no exports used]
     entry ./example.js main
-webpack 5.11.1 compiled successfully
+webpack 5.78.0 compiled successfully
 ```
diff --git a/examples/scope-hoisting/README.md b/examples/scope-hoisting/README.md
index 500f7173a9f..6bf03433229 100644
--- a/examples/scope-hoisting/README.md
+++ b/examples/scope-hoisting/README.md
@@ -4,17 +4,17 @@ This is the dependency graph for the example: (solid lines express sync imports,
 
 ![](graph.png)
 
-All modules except `cjs` are EcmaScript modules. `cjs` is a CommonJs module.
+All modules except `cjs` are EcmaScript modules. `cjs` is a CommonJS module.
 
-The interesting thing here is that putting all modules in single scope won't work, because of multiple reasons:
+The interesting thing here is that putting all modules in a single scope won't work, because of multiple reasons:
 
 - Modules `lazy`, `c`, `d` and `cjs` need to be in a separate chunk
 - Module `shared` is accessed by two chunks (different scopes)
-- Module `cjs` is a CommonJs module
+- Module `cjs` is a CommonJS module
 
 ![](graph2.png)
 
-webpack therefore uses a approach called **"Partial Scope Hoisting"** or "Module concatenation", which chooses the largest possible subsets of ES modules which can be scope hoisted and combines them with the default webpack primitives.
+Webpack, therefore, uses an approach called **"Partial Scope Hoisting"** or "Module concatenation", which chooses the largest possible subsets of ES modules which can be scope hoisted and combines them with the default webpack primitives.
 
 ![](graph3.png)
 
@@ -129,8 +129,8 @@ module.exports = {
 
 // EXPORTS
 __webpack_require__.d(__webpack_exports__, {
-  "x": () => /* binding */ x,
-  "y": () => /* reexport */ y
+  "x": () => (/* binding */ x),
+  "y": () => (/* reexport */ y)
 });
 
 ;// CONCATENATED MODULE: ./node_modules/shared2.js
@@ -157,8 +157,9 @@ var x = "x";
 /******/ 	// The require function
 /******/ 	function __webpack_require__(moduleId) {
 /******/ 		// Check if module is in cache
-/******/ 		if(__webpack_module_cache__[moduleId]) {
-/******/ 			return __webpack_module_cache__[moduleId].exports;
+/******/ 		var cachedModule = __webpack_module_cache__[moduleId];
+/******/ 		if (cachedModule !== undefined) {
+/******/ 			return cachedModule.exports;
 /******/ 		}
 /******/ 		// Create a new module (and put it into the cache)
 /******/ 		var module = __webpack_module_cache__[moduleId] = {
@@ -214,7 +215,7 @@ var x = "x";
 /******/ 	
 /******/ 	/* webpack/runtime/hasOwnProperty shorthand */
 /******/ 	(() => {
-/******/ 		__webpack_require__.o = (obj, prop) => Object.prototype.hasOwnProperty.call(obj, prop)
+/******/ 		__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
 /******/ 	})();
 /******/ 	
 /******/ 	/* webpack/runtime/load script */
@@ -222,7 +223,7 @@ var x = "x";
 /******/ 		var inProgress = {};
 /******/ 		// data-webpack is not used as build has no uniqueName
 /******/ 		// loadScript function to load a script via script tag
-/******/ 		__webpack_require__.l = (url, done, key) => {
+/******/ 		__webpack_require__.l = (url, done, key, chunkId) => {
 /******/ 			if(inProgress[url]) { inProgress[url].push(done); return; }
 /******/ 			var script, needAttach;
 /******/ 			if(key !== undefined) {
@@ -252,10 +253,9 @@ var x = "x";
 /******/ 				var doneFns = inProgress[url];
 /******/ 				delete inProgress[url];
 /******/ 				script.parentNode && script.parentNode.removeChild(script);
-/******/ 				doneFns && doneFns.forEach((fn) => fn(event));
+/******/ 				doneFns && doneFns.forEach((fn) => (fn(event)));
 /******/ 				if(prev) return prev(event);
 /******/ 			}
-/******/ 			;
 /******/ 			var timeout = setTimeout(onScriptComplete.bind(null, undefined, { type: 'timeout', target: script }), 120000);
 /******/ 			script.onerror = onScriptComplete.bind(null, script.onerror);
 /******/ 			script.onload = onScriptComplete.bind(null, script.onload);
@@ -285,12 +285,11 @@ var x = "x";
 /******/ 		
 /******/ 		// object to store loaded and loading chunks
 /******/ 		// undefined = chunk not loaded, null = chunk preloaded/prefetched
-/******/ 		// Promise = chunk loading, 0 = chunk loaded
+/******/ 		// [resolve, reject, Promise] = chunk loading, 0 = chunk loaded
 /******/ 		var installedChunks = {
 /******/ 			179: 0
 /******/ 		};
 /******/ 		
-/******/ 		
 /******/ 		__webpack_require__.f.j = (chunkId, promises) => {
 /******/ 				// JSONP chunk loading for javascript
 /******/ 				var installedChunkData = __webpack_require__.o(installedChunks, chunkId) ? installedChunks[chunkId] : undefined;
@@ -302,9 +301,7 @@ var x = "x";
 /******/ 					} else {
 /******/ 						if(true) { // all chunks have JS
 /******/ 							// setup Promise in chunk cache
-/******/ 							var promise = new Promise((resolve, reject) => {
-/******/ 								installedChunkData = installedChunks[chunkId] = [resolve, reject];
-/******/ 							});
+/******/ 							var promise = new Promise((resolve, reject) => (installedChunkData = installedChunks[chunkId] = [resolve, reject]));
 /******/ 							promises.push(installedChunkData[2] = promise);
 /******/ 		
 /******/ 							// start chunk loading
@@ -326,7 +323,7 @@ var x = "x";
 /******/ 									}
 /******/ 								}
 /******/ 							};
-/******/ 							__webpack_require__.l(url, loadingEnded, "chunk-" + chunkId);
+/******/ 							__webpack_require__.l(url, loadingEnded, "chunk-" + chunkId, chunkId);
 /******/ 						} else installedChunks[chunkId] = 0;
 /******/ 					}
 /******/ 				}
@@ -340,39 +337,36 @@ var x = "x";
 /******/ 		
 /******/ 		// no HMR manifest
 /******/ 		
-/******/ 		// no deferred startup
+/******/ 		// no on chunks loaded
 /******/ 		
 /******/ 		// install a JSONP callback for chunk loading
 /******/ 		var webpackJsonpCallback = (parentChunkLoadingFunction, data) => {
 /******/ 			var [chunkIds, moreModules, runtime] = data;
 /******/ 			// add "moreModules" to the modules object,
 /******/ 			// then flag all "chunkIds" as loaded and fire callback
-/******/ 			var moduleId, chunkId, i = 0, resolves = [];
+/******/ 			var moduleId, chunkId, i = 0;
+/******/ 			if(chunkIds.some((id) => (installedChunks[id] !== 0))) {
+/******/ 				for(moduleId in moreModules) {
+/******/ 					if(__webpack_require__.o(moreModules, moduleId)) {
+/******/ 						__webpack_require__.m[moduleId] = moreModules[moduleId];
+/******/ 					}
+/******/ 				}
+/******/ 				if(runtime) var result = runtime(__webpack_require__);
+/******/ 			}
+/******/ 			if(parentChunkLoadingFunction) parentChunkLoadingFunction(data);
 /******/ 			for(;i < chunkIds.length; i++) {
 /******/ 				chunkId = chunkIds[i];
 /******/ 				if(__webpack_require__.o(installedChunks, chunkId) && installedChunks[chunkId]) {
-/******/ 					resolves.push(installedChunks[chunkId][0]);
+/******/ 					installedChunks[chunkId][0]();
 /******/ 				}
 /******/ 				installedChunks[chunkId] = 0;
 /******/ 			}
-/******/ 			for(moduleId in moreModules) {
-/******/ 				if(__webpack_require__.o(moreModules, moduleId)) {
-/******/ 					__webpack_require__.m[moduleId] = moreModules[moduleId];
-/******/ 				}
-/******/ 			}
-/******/ 			if(runtime) runtime(__webpack_require__);
-/******/ 			if(parentChunkLoadingFunction) parentChunkLoadingFunction(data);
-/******/ 			while(resolves.length) {
-/******/ 				resolves.shift()();
-/******/ 			}
 /******/ 		
 /******/ 		}
 /******/ 		
 /******/ 		var chunkLoadingGlobal = self["webpackChunk"] = self["webpackChunk"] || [];
 /******/ 		chunkLoadingGlobal.forEach(webpackJsonpCallback.bind(null, 0));
 /******/ 		chunkLoadingGlobal.push = webpackJsonpCallback.bind(null, chunkLoadingGlobal.push.bind(chunkLoadingGlobal));
-/******/ 		
-/******/ 		// no deferred startup
 /******/ 	})();
 /******/ 	
 /************************************************************************/
@@ -381,6 +375,8 @@ var x = "x";
 
 
 ``` js
+var __webpack_exports__ = {};
+// This entry need to be wrapped in an IIFE because it need to be isolated against other modules in the chunk.
 (() => {
 /*!********************************!*\
   !*** ./example.js + 2 modules ***!
@@ -436,7 +432,7 @@ __webpack_require__.e(/*! import() */ 872).then(__webpack_require__.bind(__webpa
 /*! other exports [not provided] [maybe used in main (runtime-defined)] */
 /*! runtime requirements: __webpack_require__.r, __webpack_exports__, __webpack_require__.d, __webpack_require__, __webpack_require__.* */
 /*! ModuleConcatenation bailout: Cannot concat with ./node_modules/cjs.js: Module is not an ECMAScript module */
-/*! ModuleConcatenation bailout: Cannot concat with ./node_modules/shared.js: Module ./node_modules/shared.js is not in the same chunk(s) (expected in chunk(s) unnamed chunk(s), module is in chunk(s) main) */
+/*! ModuleConcatenation bailout: Cannot concat with ./node_modules/shared.js: Module ./node_modules/shared.js is not in the same chunk(s) (expected in chunk(s) unnamed chunk(s), module is in chunk(s) ) */
 /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
 
 "use strict";
@@ -445,17 +441,17 @@ __webpack_require__.r(__webpack_exports__);
 
 // EXPORTS
 __webpack_require__.d(__webpack_exports__, {
-  "c": () => /* reexport */ c,
-  "d": () => /* reexport */ d_namespaceObject,
-  "x": () => /* reexport */ shared.x,
-  "y": () => /* reexport */ shared.y
+  "c": () => (/* reexport */ c),
+  "d": () => (/* reexport */ d_namespaceObject),
+  "x": () => (/* reexport */ shared.x),
+  "y": () => (/* reexport */ shared.y)
 });
 
 // NAMESPACE OBJECT: ./node_modules/d.js
 var d_namespaceObject = {};
 __webpack_require__.r(d_namespaceObject);
 __webpack_require__.d(d_namespaceObject, {
-  "a": () => a
+  "a": () => (a)
 });
 
 // EXTERNAL MODULE: ./node_modules/cjs.js
@@ -510,8 +506,8 @@ Minimized
 ## Unoptimized
 
 ```
-asset output.js 11.1 KiB [emitted] (name: main)
-asset 872.output.js 2.73 KiB [emitted]
+asset output.js 11.2 KiB [emitted] (name: main)
+asset 872.output.js 2.74 KiB [emitted]
 chunk (runtime: main) output.js (main) 367 bytes (javascript) 5.54 KiB (runtime) [entry] [rendered]
   > ./example.js main
   runtime modules 5.54 KiB 8 modules
@@ -526,13 +522,13 @@ chunk (runtime: main) 872.output.js 263 bytes [rendered]
   ./lazy.js + 2 modules 221 bytes [built] [code generated]
     [exports: c, d, x, y]
     import() ./lazy ./example.js + 2 modules ./example.js 4:0-16
-webpack 5.11.1 compiled successfully
+webpack 5.78.0 compiled successfully
 ```
 
 ## Production mode
 
 ```
-asset output.js 2.1 KiB [emitted] [minimized] (name: main)
+asset output.js 2.11 KiB [emitted] [minimized] (name: main)
 asset 872.output.js 270 bytes [emitted] [minimized]
 chunk (runtime: main) output.js (main) 367 bytes (javascript) 5.54 KiB (runtime) [entry] [rendered]
   > ./example.js main
@@ -548,5 +544,5 @@ chunk (runtime: main) 872.output.js 263 bytes [rendered]
   ./lazy.js + 2 modules 221 bytes [built] [code generated]
     [exports: c, d, x, y]
     import() ./lazy ./example.js + 2 modules ./example.js 4:0-16
-webpack 5.11.1 compiled successfully
+webpack 5.78.0 compiled successfully
 ```
diff --git a/examples/scope-hoisting/template.md b/examples/scope-hoisting/template.md
index 7cb3b37bc4c..601a518e47c 100644
--- a/examples/scope-hoisting/template.md
+++ b/examples/scope-hoisting/template.md
@@ -4,9 +4,9 @@ This is the dependency graph for the example: (solid lines express sync imports,
 
 ![](graph.png)
 
-All modules except `cjs` are EcmaScript modules. `cjs` is a CommonJs module.
+All modules except `cjs` are EcmaScript modules. `cjs` is a CommonJS module.
 
-The interesting thing here is that putting all modules in single scope won't work, because of multiple reasons:
+The interesting thing here is that putting all modules in a single scope won't work, because of multiple reasons:
 
 - Modules `lazy`, `c`, `d` and `cjs` need to be in a separate chunk
 - Module `shared` is accessed by two chunks (different scopes)
@@ -14,7 +14,7 @@ The interesting thing here is that putting all modules in single scope won't wor
 
 ![](graph2.png)
 
-webpack therefore uses a approach called **"Partial Scope Hoisting"** or "Module concatenation", which chooses the largest possible subsets of ES modules which can be scope hoisted and combines them with the default webpack primitives.
+Webpack, therefore, uses a approach called **"Partial Scope Hoisting"** or "Module concatenation", which chooses the largest possible subsets of ES modules which can be scope hoisted and combines them with the default webpack primitives.
 
 ![](graph3.png)
 
diff --git a/examples/side-effects/README.md b/examples/side-effects/README.md
index e8beb2156a6..e2804cf9c23 100644
--- a/examples/side-effects/README.md
+++ b/examples/side-effects/README.md
@@ -1,4 +1,4 @@
-This example shows how the `sideEffects` flag for library authors works.
+This example shows how the `sideEffects` flag works for library authors.
 
 The example contains a large library, `big-module`. `big-module` contains multiple child modules: `a`, `b` and `c`. The exports from the child modules are re-exported in the entry module (`index.js`) of the library. A consumer uses **some** of the exports, importing them from the library via `import { a, b } from "big-module"`. According to the EcmaScript spec, all child modules _must_ be evaluated because they could contain side effects.
 
@@ -60,32 +60,7 @@ console.log("side effect");
 /******/ (() => { // webpackBootstrap
 /******/ 	"use strict";
 /******/ 	var __webpack_modules__ = ([
-/* 0 */
-/*!********************!*\
-  !*** ./example.js ***!
-  \********************/
-/*! namespace exports */
-/*! exports [not provided] [no usage info] */
-/*! runtime requirements: __webpack_require__, __webpack_require__.r, __webpack_exports__, __webpack_require__.* */
-/*! Statement (ExpressionStatement) with side effects in source code at 4:0-9:2 */
-/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
-
-__webpack_require__.r(__webpack_exports__);
-/* harmony import */ var big_module__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! big-module */ 1);
-/* harmony import */ var big_module_with_flag__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! big-module-with-flag */ 5);
-/* harmony import */ var big_module_with_flag__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! big-module-with-flag */ 6);
-
-
-
-console.log(
-	big_module__WEBPACK_IMPORTED_MODULE_0__.a,
-	big_module__WEBPACK_IMPORTED_MODULE_0__.b,
-	big_module_with_flag__WEBPACK_IMPORTED_MODULE_1__.a,
-	big_module_with_flag__WEBPACK_IMPORTED_MODULE_2__.b
-);
-
-
-/***/ }),
+/* 0 */,
 /* 1 */
 /*!******************************************!*\
   !*** ./node_modules/big-module/index.js ***!
@@ -101,9 +76,9 @@ console.log(
 
 __webpack_require__.r(__webpack_exports__);
 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
-/* harmony export */   "a": () => /* reexport safe */ _a__WEBPACK_IMPORTED_MODULE_0__.a,
-/* harmony export */   "b": () => /* reexport safe */ _b__WEBPACK_IMPORTED_MODULE_1__.b,
-/* harmony export */   "c": () => /* reexport safe */ _c__WEBPACK_IMPORTED_MODULE_2__.c
+/* harmony export */   "a": () => (/* reexport safe */ _a__WEBPACK_IMPORTED_MODULE_0__.a),
+/* harmony export */   "b": () => (/* reexport safe */ _b__WEBPACK_IMPORTED_MODULE_1__.b),
+/* harmony export */   "c": () => (/* reexport safe */ _c__WEBPACK_IMPORTED_MODULE_2__.c)
 /* harmony export */ });
 /* harmony import */ var _a__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./a */ 2);
 /* harmony import */ var _b__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./b */ 3);
@@ -128,7 +103,7 @@ console.log("side effect");
 
 __webpack_require__.r(__webpack_exports__);
 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
-/* harmony export */   "a": () => /* binding */ a
+/* harmony export */   "a": () => (/* binding */ a)
 /* harmony export */ });
 const a = "a";
 
@@ -146,7 +121,7 @@ const a = "a";
 
 __webpack_require__.r(__webpack_exports__);
 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
-/* harmony export */   "b": () => /* binding */ b
+/* harmony export */   "b": () => (/* binding */ b)
 /* harmony export */ });
 const b = "b";
 
@@ -164,7 +139,7 @@ const b = "b";
 
 __webpack_require__.r(__webpack_exports__);
 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
-/* harmony export */   "c": () => /* binding */ c
+/* harmony export */   "c": () => (/* binding */ c)
 /* harmony export */ });
 const c = "c";
 
@@ -182,7 +157,7 @@ const c = "c";
 
 __webpack_require__.r(__webpack_exports__);
 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
-/* harmony export */   "a": () => /* binding */ a
+/* harmony export */   "a": () => (/* binding */ a)
 /* harmony export */ });
 const a = "a";
 
@@ -200,7 +175,7 @@ const a = "a";
 
 __webpack_require__.r(__webpack_exports__);
 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
-/* harmony export */   "b": () => /* binding */ b
+/* harmony export */   "b": () => (/* binding */ b)
 /* harmony export */ });
 const b = "b";
 
@@ -219,8 +194,9 @@ const b = "b";
 /******/ 	// The require function
 /******/ 	function __webpack_require__(moduleId) {
 /******/ 		// Check if module is in cache
-/******/ 		if(__webpack_module_cache__[moduleId]) {
-/******/ 			return __webpack_module_cache__[moduleId].exports;
+/******/ 		var cachedModule = __webpack_module_cache__[moduleId];
+/******/ 		if (cachedModule !== undefined) {
+/******/ 			return cachedModule.exports;
 /******/ 		}
 /******/ 		// Create a new module (and put it into the cache)
 /******/ 		var module = __webpack_module_cache__[moduleId] = {
@@ -251,7 +227,7 @@ const b = "b";
 /******/ 	
 /******/ 	/* webpack/runtime/hasOwnProperty shorthand */
 /******/ 	(() => {
-/******/ 		__webpack_require__.o = (obj, prop) => Object.prototype.hasOwnProperty.call(obj, prop)
+/******/ 		__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
 /******/ 	})();
 /******/ 	
 /******/ 	/* webpack/runtime/make namespace object */
@@ -271,10 +247,32 @@ const b = "b";
 
 
 ``` js
-/******/ 	// startup
-/******/ 	// Load entry module
-/******/ 	__webpack_require__(0);
-/******/ 	// This entry module used 'exports' so it can't be inlined
+var __webpack_exports__ = {};
+// This entry need to be wrapped in an IIFE because it need to be isolated against other modules in the chunk.
+(() => {
+/*!********************!*\
+  !*** ./example.js ***!
+  \********************/
+/*! namespace exports */
+/*! exports [not provided] [no usage info] */
+/*! runtime requirements: __webpack_require__, __webpack_require__.r, __webpack_exports__, __webpack_require__.* */
+/*! Statement (ExpressionStatement) with side effects in source code at 4:0-9:2 */
+__webpack_require__.r(__webpack_exports__);
+/* harmony import */ var big_module__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! big-module */ 1);
+/* harmony import */ var big_module_with_flag__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! big-module-with-flag */ 5);
+/* harmony import */ var big_module_with_flag__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! big-module-with-flag */ 6);
+
+
+
+console.log(
+	big_module__WEBPACK_IMPORTED_MODULE_0__.a,
+	big_module__WEBPACK_IMPORTED_MODULE_0__.b,
+	big_module_with_flag__WEBPACK_IMPORTED_MODULE_1__.a,
+	big_module_with_flag__WEBPACK_IMPORTED_MODULE_2__.b
+);
+
+})();
+
 /******/ })()
 ;
 ```
@@ -284,16 +282,16 @@ const b = "b";
 ## Unoptimized
 
 ```
-asset output.js 8.58 KiB [emitted] (name: main)
-chunk (runtime: main) output.js (main) 354 bytes (javascript) 668 bytes (runtime) [entry] [rendered]
+asset output.js 8.55 KiB [emitted] (name: main)
+chunk (runtime: main) output.js (main) 354 bytes (javascript) 670 bytes (runtime) [entry] [rendered]
   > ./example.js main
   dependent modules 214 bytes [dependent] 6 modules
-  runtime modules 668 bytes 3 modules
+  runtime modules 670 bytes 3 modules
   ./example.js 140 bytes [built] [code generated]
     [no exports]
     [used exports unknown]
     entry ./example.js main
-webpack 5.11.1 compiled successfully
+webpack 5.78.0 compiled successfully
 ```
 
 ## Production mode
@@ -306,5 +304,5 @@ chunk (runtime: main) output.js (main) 332 bytes [entry] [rendered]
     [no exports]
     [no exports used]
     entry ./example.js main
-webpack 5.11.1 compiled successfully
+webpack 5.78.0 compiled successfully
 ```
diff --git a/examples/side-effects/template.md b/examples/side-effects/template.md
index 258a491cb26..a8ae4f7281c 100644
--- a/examples/side-effects/template.md
+++ b/examples/side-effects/template.md
@@ -1,4 +1,4 @@
-This example shows how the `sideEffects` flag for library authors works.
+This example shows how the `sideEffects` flag works for library authors.
 
 The example contains a large library, `big-module`. `big-module` contains multiple child modules: `a`, `b` and `c`. The exports from the child modules are re-exported in the entry module (`index.js`) of the library. A consumer uses **some** of the exports, importing them from the library via `import { a, b } from "big-module"`. According to the EcmaScript spec, all child modules _must_ be evaluated because they could contain side effects.
 
diff --git a/examples/source-map/README.md b/examples/source-map/README.md
index e3e21023943..ec7b610b8eb 100644
--- a/examples/source-map/README.md
+++ b/examples/source-map/README.md
@@ -85,12 +85,16 @@ race = function(winner, ...runners) {
 
 /***/ })
 ],
-0,[[0,1]]]);
+/******/ __webpack_require__ => { // webpackRuntimeModules
+/******/ var __webpack_exec__ = (moduleId) => (__webpack_require__(__webpack_require__.s = moduleId))
+/******/ var __webpack_exports__ = (__webpack_exec__(0));
+/******/ }
+]);
 //# sourceMappingURL=bundle-source-map.js.map
 ```
 
 ```json
-{"version":3,"sources":["webpack:///./example.coffee"],"names":[],"mappings":";;;;;;;;;AAEU;;;AAAA;;AACV,OACE;EAAA,MAAQ,IAAI,CAAC,IAAb;EACA,QAAQ,MADR;EAEA,MAAQ,SAAC,CAAD;WAAO,IAAI,OAAO,CAAP;EAAX;AAFR,EAFQ;;;AAOV,OAAO,SAAC,MAAD,KAAS,OAAT;SACL,MAAM,MAAN,EAAc,OAAd;AADK","file":"./bundle-source-map.js","sourcesContent":["# Taken from http://coffeescript.org/\n\n# Objects:\nmath =\n  root:   Math.sqrt\n  square: square\n  cube:   (x) -> x * square x\n\n# Splats:\nrace = (winner, runners...) ->\n  print winner, runners\n"],"sourceRoot":""}
+{"version":3,"file":"./bundle-source-map.js","mappings":";;;;;;;;;AAEU;;;AAAA;;AACV,OACE;EAAA,MAAQ,IAAI,CAAC,IAAb;EACA,QAAQ,MADR;EAEA,MAAQ,SAAC,CAAD;WAAO,IAAI,OAAO,CAAP;EAAX;AAFR,EAFQ;;;AAOV,OAAO,SAAC,MAAD,KAAS,OAAT;SACL,MAAM,MAAN,EAAc,OAAd;AADK","sources":["webpack:///./example.coffee"],"sourcesContent":["# Taken from http://coffeescript.org/\n\n# Objects:\nmath =\n  root:   Math.sqrt\n  square: square\n  cube:   (x) -> x * square x\n\n# Splats:\nrace = (winner, runners...) ->\n  print winner, runners\n"],"names":[],"sourceRoot":""}
 ```
 
 ## hidden-source-map.js and hidden-source-map.js.map
@@ -126,11 +130,15 @@ race = function(winner, ...runners) {
 
 /***/ })
 ],
-0,[[0,1]]]);
+/******/ __webpack_require__ => { // webpackRuntimeModules
+/******/ var __webpack_exec__ = (moduleId) => (__webpack_require__(__webpack_require__.s = moduleId))
+/******/ var __webpack_exports__ = (__webpack_exec__(0));
+/******/ }
+]);
 ```
 
 ```json
-{"version":3,"sources":["webpack:///./example.coffee"],"names":[],"mappings":";;;;;;;;;AAEU;;;AAAA;;AACV,OACE;EAAA,MAAQ,IAAI,CAAC,IAAb;EACA,QAAQ,MADR;EAEA,MAAQ,SAAC,CAAD;WAAO,IAAI,OAAO,CAAP;EAAX;AAFR,EAFQ;;;AAOV,OAAO,SAAC,MAAD,KAAS,OAAT;SACL,MAAM,MAAN,EAAc,OAAd;AADK","file":"./bundle-hidden-source-map.js","sourcesContent":["# Taken from http://coffeescript.org/\n\n# Objects:\nmath =\n  root:   Math.sqrt\n  square: square\n  cube:   (x) -> x * square x\n\n# Splats:\nrace = (winner, runners...) ->\n  print winner, runners\n"],"sourceRoot":""}
+{"version":3,"file":"./bundle-hidden-source-map.js","mappings":";;;;;;;;;AAEU;;;AAAA;;AACV,OACE;EAAA,MAAQ,IAAI,CAAC,IAAb;EACA,QAAQ,MADR;EAEA,MAAQ,SAAC,CAAD;WAAO,IAAI,OAAO,CAAP;EAAX;AAFR,EAFQ;;;AAOV,OAAO,SAAC,MAAD,KAAS,OAAT;SACL,MAAM,MAAN,EAAc,OAAd;AADK","sources":["webpack:///./example.coffee"],"sourcesContent":["# Taken from http://coffeescript.org/\n\n# Objects:\nmath =\n  root:   Math.sqrt\n  square: square\n  cube:   (x) -> x * square x\n\n# Splats:\nrace = (winner, runners...) ->\n  print winner, runners\n"],"names":[],"sourceRoot":""}
 ```
 
 ## inline-source-map.js
@@ -166,14 +174,18 @@ race = function(winner, ...runners) {
 
 /***/ })
 ],
-0,[[0,1]]]);
-//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9leGFtcGxlLmNvZmZlZSJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7QUFFVTs7O0FBQUE7O0FBQ1YsT0FDRTtFQUFBLE1BQVEsSUFBSSxDQUFDLElBQWI7RUFDQSxRQUFRLE1BRFI7RUFFQSxNQUFRLFNBQUMsQ0FBRDtXQUFPLElBQUksT0FBTyxDQUFQO0VBQVg7QUFGUixFQUZROzs7QUFPVixPQUFPLFNBQUMsTUFBRCxLQUFTLE9BQVQ7U0FDTCxNQUFNLE1BQU4sRUFBYyxPQUFkO0FBREsiLCJmaWxlIjoiLi9idW5kbGUtaW5saW5lLXNvdXJjZS1tYXAuanMiLCJzb3VyY2VzQ29udGVudCI6WyIjIFRha2VuIGZyb20gaHR0cDovL2NvZmZlZXNjcmlwdC5vcmcvXG5cbiMgT2JqZWN0czpcbm1hdGggPVxuICByb290OiAgIE1hdGguc3FydFxuICBzcXVhcmU6IHNxdWFyZVxuICBjdWJlOiAgICh4KSAtPiB4ICogc3F1YXJlIHhcblxuIyBTcGxhdHM6XG5yYWNlID0gKHdpbm5lciwgcnVubmVycy4uLikgLT5cbiAgcHJpbnQgd2lubmVyLCBydW5uZXJzXG4iXSwic291cmNlUm9vdCI6IiJ9
+/******/ __webpack_require__ => { // webpackRuntimeModules
+/******/ var __webpack_exec__ = (moduleId) => (__webpack_require__(__webpack_require__.s = moduleId))
+/******/ var __webpack_exports__ = (__webpack_exec__(0));
+/******/ }
+]);
+//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9idW5kbGUtaW5saW5lLXNvdXJjZS1tYXAuanMiLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7O0FBRVU7OztBQUFBOztBQUNWLE9BQ0U7RUFBQSxNQUFRLElBQUksQ0FBQyxJQUFiO0VBQ0EsUUFBUSxNQURSO0VBRUEsTUFBUSxTQUFDLENBQUQ7V0FBTyxJQUFJLE9BQU8sQ0FBUDtFQUFYO0FBRlIsRUFGUTs7O0FBT1YsT0FBTyxTQUFDLE1BQUQsS0FBUyxPQUFUO1NBQ0wsTUFBTSxNQUFOLEVBQWMsT0FBZDtBQURLIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vLy4vZXhhbXBsZS5jb2ZmZWUiXSwic291cmNlc0NvbnRlbnQiOlsiIyBUYWtlbiBmcm9tIGh0dHA6Ly9jb2ZmZWVzY3JpcHQub3JnL1xuXG4jIE9iamVjdHM6XG5tYXRoID1cbiAgcm9vdDogICBNYXRoLnNxcnRcbiAgc3F1YXJlOiBzcXVhcmVcbiAgY3ViZTogICAoeCkgLT4geCAqIHNxdWFyZSB4XG5cbiMgU3BsYXRzOlxucmFjZSA9ICh3aW5uZXIsIHJ1bm5lcnMuLi4pIC0+XG4gIHByaW50IHdpbm5lciwgcnVubmVyc1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9
 ```
 
 ## nosources-source-map.js.map
 
 ```json
-{"version":3,"sources":["webpack:///./example.coffee"],"names":[],"mappings":";;;;;;;;;AAEU;;;AAAA;;AACV,OACE;EAAA,MAAQ,IAAI,CAAC,IAAb;EACA,QAAQ,MADR;EAEA,MAAQ,SAAC,CAAD;WAAO,IAAI,OAAO,CAAP;EAAX;AAFR,EAFQ;;;AAOV,OAAO,SAAC,MAAD,KAAS,OAAT;SACL,MAAM,MAAN,EAAc,OAAd;AADK","file":"./bundle-nosources-source-map.js","sourceRoot":""}
+{"version":3,"file":"./bundle-nosources-source-map.js","mappings":";;;;;;;;;AAEU;;;AAAA;;AACV,OACE;EAAA,MAAQ,IAAI,CAAC,IAAb;EACA,QAAQ,MADR;EAEA,MAAQ,SAAC,CAAD;WAAO,IAAI,OAAO,CAAP;EAAX;AAFR,EAFQ;;;AAOV,OAAO,SAAC,MAAD,KAAS,OAAT;SACL,MAAM,MAAN,EAAc,OAAd;AADK","sources":["webpack:///./example.coffee"],"names":[],"sourceRoot":""}
 ```
 
 ## eval-source-map.js
@@ -200,7 +212,11 @@ eval("// Taken from http://coffeescript.org/\n\n// Objects:\nvar math, race;\n\n
 
 /***/ })
 ],
-0,[[0,1]]]);
+/******/ __webpack_require__ => { // webpackRuntimeModules
+/******/ var __webpack_exec__ = (moduleId) => (__webpack_require__(__webpack_require__.s = moduleId))
+/******/ var __webpack_exports__ = (__webpack_exec__(0));
+/******/ }
+]);
 ```
 
 ## eval.js
@@ -227,7 +243,11 @@ eval("// Taken from http://coffeescript.org/\n\n// Objects:\nvar math, race;\n\n
 
 /***/ })
 ],
-0,[[0,1]]]);
+/******/ __webpack_require__ => { // webpackRuntimeModules
+/******/ var __webpack_exec__ = (moduleId) => (__webpack_require__(__webpack_require__.s = moduleId))
+/******/ var __webpack_exports__ = (__webpack_exec__(0));
+/******/ }
+]);
 ```
 
 ## eval-cheap-source-map.js
@@ -250,11 +270,15 @@ eval("// Taken from http://coffeescript.org/\n\n// Objects:\nvar math, race;\n\n
 /*! runtime requirements:  */
 /***/ (() => {
 
-eval("// Taken from http://coffeescript.org/\n\n// Objects:\nvar math, race;\n\nmath = {\n  root: Math.sqrt,\n  square: square,\n  cube: function(x) {\n    return x * square(x);\n  }\n};\n\n// Splats:\nrace = function(winner, ...runners) {\n  return print(winner, runners);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMC5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL2V4YW1wbGUuY29mZmVlP2VlNTgiXSwic291cmNlc0NvbnRlbnQiOlsiLy8gVGFrZW4gZnJvbSBodHRwOi8vY29mZmVlc2NyaXB0Lm9yZy9cblxuLy8gT2JqZWN0czpcbnZhciBtYXRoLCByYWNlO1xuXG5tYXRoID0ge1xuICByb290OiBNYXRoLnNxcnQsXG4gIHNxdWFyZTogc3F1YXJlLFxuICBjdWJlOiBmdW5jdGlvbih4KSB7XG4gICAgcmV0dXJuIHggKiBzcXVhcmUoeCk7XG4gIH1cbn07XG5cbi8vIFNwbGF0czpcbnJhY2UgPSBmdW5jdGlvbih3aW5uZXIsIC4uLnJ1bm5lcnMpIHtcbiAgcmV0dXJuIHByaW50KHdpbm5lciwgcnVubmVycyk7XG59O1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOyIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///0\n");
+eval("// Taken from http://coffeescript.org/\n\n// Objects:\nvar math, race;\n\nmath = {\n  root: Math.sqrt,\n  square: square,\n  cube: function(x) {\n    return x * square(x);\n  }\n};\n\n// Splats:\nrace = function(winner, ...runners) {\n  return print(winner, runners);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMC5qcyIsIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vLy4vZXhhbXBsZS5jb2ZmZWU/ZWU1OCJdLCJzb3VyY2VzQ29udGVudCI6WyIvLyBUYWtlbiBmcm9tIGh0dHA6Ly9jb2ZmZWVzY3JpcHQub3JnL1xuXG4vLyBPYmplY3RzOlxudmFyIG1hdGgsIHJhY2U7XG5cbm1hdGggPSB7XG4gIHJvb3Q6IE1hdGguc3FydCxcbiAgc3F1YXJlOiBzcXVhcmUsXG4gIGN1YmU6IGZ1bmN0aW9uKHgpIHtcbiAgICByZXR1cm4geCAqIHNxdWFyZSh4KTtcbiAgfVxufTtcblxuLy8gU3BsYXRzOlxucmFjZSA9IGZ1bmN0aW9uKHdpbm5lciwgLi4ucnVubmVycykge1xuICByZXR1cm4gcHJpbnQod2lubmVyLCBydW5uZXJzKTtcbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///0\n");
 
 /***/ })
 ],
-0,[[0,1]]]);
+/******/ __webpack_require__ => { // webpackRuntimeModules
+/******/ var __webpack_exec__ = (moduleId) => (__webpack_require__(__webpack_require__.s = moduleId))
+/******/ var __webpack_exports__ = (__webpack_exec__(0));
+/******/ }
+]);
 ```
 
 ## eval-cheap-module-source-map.js
@@ -281,177 +305,181 @@ eval("// Taken from http://coffeescript.org/\n\n// Objects:\nvar math, race;\n\n
 
 /***/ })
 ],
-0,[[0,1]]]);
+/******/ __webpack_require__ => { // webpackRuntimeModules
+/******/ var __webpack_exec__ = (moduleId) => (__webpack_require__(__webpack_require__.s = moduleId))
+/******/ var __webpack_exports__ = (__webpack_exec__(0));
+/******/ }
+]);
 ```
 
 ## cheap-module-source-map.js.map
 
 ```json
-{"version":3,"file":"./bundle-cheap-module-source-map.js","sources":["webpack:///./example.coffee"],"sourcesContent":["# Taken from http://coffeescript.org/\n\n# Objects:\nmath =\n  root:   Math.sqrt\n  square: square\n  cube:   (x) -> x * square x\n\n# Splats:\nrace = (winner, runners...) ->\n  print winner, runners\n"],"mappings":";;;;;;;;;AAEA;AACA;;AADA;AACA;AAAA;AACA;AACA;AACA;AAAA;AAAA;AAFA;AACA;;AAIA;AACA;AADA;AACA;AACA;A;;A","sourceRoot":""}
+{"version":3,"file":"./bundle-cheap-module-source-map.js","mappings":";;;;;;;;;AAEA;;;AAAA;;AACA;AACA;AACA;AACA;AAAA;AAAA;AAFA;;;AAKA;AACA;AADA","sources":["webpack:///./example.coffee"],"sourcesContent":["# Taken from http://coffeescript.org/\n\n# Objects:\nmath =\n  root:   Math.sqrt\n  square: square\n  cube:   (x) -> x * square x\n\n# Splats:\nrace = (winner, runners...) ->\n  print winner, runners\n"],"names":[],"sourceRoot":""}
 ```
 
 ## cheap-source-map.js.map
 
 ```json
-{"version":3,"file":"./bundle-cheap-source-map.js","sources":["webpack:///./example.coffee"],"sourcesContent":["// Taken from http://coffeescript.org/\n\n// Objects:\nvar math, race;\n\nmath = {\n  root: Math.sqrt,\n  square: square,\n  cube: function(x) {\n    return x * square(x);\n  }\n};\n\n// Splats:\nrace = function(winner, ...runners) {\n  return print(winner, runners);\n};\n"],"mappings":";;;;;;;;;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;A;;A","sourceRoot":""}
+{"version":3,"file":"./bundle-cheap-source-map.js","mappings":";;;;;;;;;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA","sources":["webpack:///./example.coffee"],"sourcesContent":["// Taken from http://coffeescript.org/\n\n// Objects:\nvar math, race;\n\nmath = {\n  root: Math.sqrt,\n  square: square,\n  cube: function(x) {\n    return x * square(x);\n  }\n};\n\n// Splats:\nrace = function(winner, ...runners) {\n  return print(winner, runners);\n};\n"],"names":[],"sourceRoot":""}
 ```
 
 # webpack output
 
 ```
-asset ./runtime~bundle-eval.js 5.72 KiB [emitted] (name: runtime~bundle)
-asset ./bundle-eval.js 1.32 KiB [emitted] (name: bundle)
-Entrypoint bundle 7.04 KiB = ./runtime~bundle-eval.js 5.72 KiB ./bundle-eval.js 1.32 KiB
+asset ./runtime~bundle-eval.js 5.46 KiB [emitted] (name: runtime~bundle)
+asset ./bundle-eval.js 1.53 KiB [emitted] (name: bundle)
+Entrypoint bundle 6.99 KiB = ./runtime~bundle-eval.js 5.46 KiB ./bundle-eval.js 1.53 KiB
 chunk (runtime: runtime~bundle) ./bundle-eval.js (bundle) 256 bytes [initial] [rendered]
   > coffee-loader!./example.coffee bundle
   ../../node_modules/coffee-loader/dist/cjs.js!./example.coffee 256 bytes [built] [code generated]
     [used exports unknown]
     entry coffee-loader!./example.coffee bundle
-chunk (runtime: runtime~bundle) ./runtime~bundle-eval.js (runtime~bundle) 2.56 KiB [entry] [rendered]
+chunk (runtime: runtime~bundle) ./runtime~bundle-eval.js (runtime~bundle) 2.45 KiB [entry] [rendered]
   > coffee-loader!./example.coffee bundle
-  runtime modules 2.56 KiB 2 modules
-webpack 5.11.1 compiled successfully
+  runtime modules 2.45 KiB 3 modules
+webpack 5.78.0 compiled successfully
 
-asset ./runtime~bundle-eval-cheap-source-map.js 5.72 KiB [emitted] (name: runtime~bundle)
-asset ./bundle-eval-cheap-source-map.js 1.98 KiB [emitted] (name: bundle)
-Entrypoint bundle 7.7 KiB = ./runtime~bundle-eval-cheap-source-map.js 5.72 KiB ./bundle-eval-cheap-source-map.js 1.98 KiB
+asset ./runtime~bundle-eval-cheap-source-map.js 5.45 KiB [emitted] (name: runtime~bundle)
+asset ./bundle-eval-cheap-source-map.js 2.2 KiB [emitted] (name: bundle)
+Entrypoint bundle 7.65 KiB = ./runtime~bundle-eval-cheap-source-map.js 5.45 KiB ./bundle-eval-cheap-source-map.js 2.2 KiB
 chunk (runtime: runtime~bundle) ./bundle-eval-cheap-source-map.js (bundle) 256 bytes [initial] [rendered]
   > coffee-loader!./example.coffee bundle
   ../../node_modules/coffee-loader/dist/cjs.js!./example.coffee 256 bytes [built] [code generated]
     [used exports unknown]
     entry coffee-loader!./example.coffee bundle
-chunk (runtime: runtime~bundle) ./runtime~bundle-eval-cheap-source-map.js (runtime~bundle) 2.56 KiB [entry] [rendered]
+chunk (runtime: runtime~bundle) ./runtime~bundle-eval-cheap-source-map.js (runtime~bundle) 2.45 KiB [entry] [rendered]
   > coffee-loader!./example.coffee bundle
-  runtime modules 2.56 KiB 2 modules
-webpack 5.11.1 compiled successfully
+  runtime modules 2.45 KiB 3 modules
+webpack 5.78.0 compiled successfully
 
-asset ./runtime~bundle-eval-cheap-module-source-map.js 5.72 KiB [emitted] (name: runtime~bundle)
-asset ./bundle-eval-cheap-module-source-map.js 2.12 KiB [emitted] (name: bundle)
-Entrypoint bundle 7.84 KiB = ./runtime~bundle-eval-cheap-module-source-map.js 5.72 KiB ./bundle-eval-cheap-module-source-map.js 2.12 KiB
+asset ./runtime~bundle-eval-cheap-module-source-map.js 5.45 KiB [emitted] (name: runtime~bundle)
+asset ./bundle-eval-cheap-module-source-map.js 2.33 KiB [emitted] (name: bundle)
+Entrypoint bundle 7.79 KiB = ./runtime~bundle-eval-cheap-module-source-map.js 5.45 KiB ./bundle-eval-cheap-module-source-map.js 2.33 KiB
 chunk (runtime: runtime~bundle) ./bundle-eval-cheap-module-source-map.js (bundle) 256 bytes [initial] [rendered]
   > coffee-loader!./example.coffee bundle
   ../../node_modules/coffee-loader/dist/cjs.js!./example.coffee 256 bytes [built] [code generated]
     [used exports unknown]
     entry coffee-loader!./example.coffee bundle
-chunk (runtime: runtime~bundle) ./runtime~bundle-eval-cheap-module-source-map.js (runtime~bundle) 2.56 KiB [entry] [rendered]
+chunk (runtime: runtime~bundle) ./runtime~bundle-eval-cheap-module-source-map.js (runtime~bundle) 2.45 KiB [entry] [rendered]
   > coffee-loader!./example.coffee bundle
-  runtime modules 2.56 KiB 2 modules
-webpack 5.11.1 compiled successfully
+  runtime modules 2.45 KiB 3 modules
+webpack 5.78.0 compiled successfully
 
-asset ./runtime~bundle-eval-source-map.js 5.72 KiB [emitted] (name: runtime~bundle)
-asset ./bundle-eval-source-map.js 2.12 KiB [emitted] (name: bundle)
-Entrypoint bundle 7.84 KiB = ./runtime~bundle-eval-source-map.js 5.72 KiB ./bundle-eval-source-map.js 2.12 KiB
+asset ./runtime~bundle-eval-source-map.js 5.45 KiB [emitted] (name: runtime~bundle)
+asset ./bundle-eval-source-map.js 2.33 KiB [emitted] (name: bundle)
+Entrypoint bundle 7.79 KiB = ./runtime~bundle-eval-source-map.js 5.45 KiB ./bundle-eval-source-map.js 2.33 KiB
 chunk (runtime: runtime~bundle) ./bundle-eval-source-map.js (bundle) 256 bytes [initial] [rendered]
   > coffee-loader!./example.coffee bundle
   ../../node_modules/coffee-loader/dist/cjs.js!./example.coffee 256 bytes [built] [code generated]
     [used exports unknown]
     entry coffee-loader!./example.coffee bundle
-chunk (runtime: runtime~bundle) ./runtime~bundle-eval-source-map.js (runtime~bundle) 2.56 KiB [entry] [rendered]
+chunk (runtime: runtime~bundle) ./runtime~bundle-eval-source-map.js (runtime~bundle) 2.45 KiB [entry] [rendered]
   > coffee-loader!./example.coffee bundle
-  runtime modules 2.56 KiB 2 modules
-webpack 5.11.1 compiled successfully
+  runtime modules 2.45 KiB 3 modules
+webpack 5.78.0 compiled successfully
 
-asset ./runtime~bundle-cheap-source-map.js 5.23 KiB [emitted] (name: runtime~bundle) 1 related asset
-asset ./bundle-cheap-source-map.js 717 bytes [emitted] (name: bundle) 1 related asset
-Entrypoint bundle 5.93 KiB (5.01 KiB) = ./runtime~bundle-cheap-source-map.js 5.23 KiB ./bundle-cheap-source-map.js 717 bytes 2 auxiliary assets
+asset ./runtime~bundle-cheap-source-map.js 4.97 KiB [emitted] (name: runtime~bundle) 1 related asset
+asset ./bundle-cheap-source-map.js 938 bytes [emitted] (name: bundle) 1 related asset
+Entrypoint bundle 5.88 KiB (4.83 KiB) = ./runtime~bundle-cheap-source-map.js 4.97 KiB ./bundle-cheap-source-map.js 938 bytes 2 auxiliary assets
 chunk (runtime: runtime~bundle) ./bundle-cheap-source-map.js (bundle) 256 bytes [initial] [rendered]
   > coffee-loader!./example.coffee bundle
   ../../node_modules/coffee-loader/dist/cjs.js!./example.coffee 256 bytes [built] [code generated]
     [used exports unknown]
     entry coffee-loader!./example.coffee bundle
-chunk (runtime: runtime~bundle) ./runtime~bundle-cheap-source-map.js (runtime~bundle) 2.56 KiB [entry] [rendered]
+chunk (runtime: runtime~bundle) ./runtime~bundle-cheap-source-map.js (runtime~bundle) 2.45 KiB [entry] [rendered]
   > coffee-loader!./example.coffee bundle
-  runtime modules 2.56 KiB 2 modules
-webpack 5.11.1 compiled successfully
+  runtime modules 2.45 KiB 3 modules
+webpack 5.78.0 compiled successfully
 
-asset ./runtime~bundle-cheap-module-source-map.js 5.24 KiB [emitted] (name: runtime~bundle) 1 related asset
-asset ./bundle-cheap-module-source-map.js 724 bytes [emitted] (name: bundle) 1 related asset
-Entrypoint bundle 5.94 KiB (4.95 KiB) = ./runtime~bundle-cheap-module-source-map.js 5.24 KiB ./bundle-cheap-module-source-map.js 724 bytes 2 auxiliary assets
+asset ./runtime~bundle-cheap-module-source-map.js 4.97 KiB [emitted] (name: runtime~bundle) 1 related asset
+asset ./bundle-cheap-module-source-map.js 945 bytes [emitted] (name: bundle) 1 related asset
+Entrypoint bundle 5.9 KiB (4.76 KiB) = ./runtime~bundle-cheap-module-source-map.js 4.97 KiB ./bundle-cheap-module-source-map.js 945 bytes 2 auxiliary assets
 chunk (runtime: runtime~bundle) ./bundle-cheap-module-source-map.js (bundle) 256 bytes [initial] [rendered]
   > coffee-loader!./example.coffee bundle
   ../../node_modules/coffee-loader/dist/cjs.js!./example.coffee 256 bytes [built] [code generated]
     [used exports unknown]
     entry coffee-loader!./example.coffee bundle
-chunk (runtime: runtime~bundle) ./runtime~bundle-cheap-module-source-map.js (runtime~bundle) 2.56 KiB [entry] [rendered]
+chunk (runtime: runtime~bundle) ./runtime~bundle-cheap-module-source-map.js (runtime~bundle) 2.45 KiB [entry] [rendered]
   > coffee-loader!./example.coffee bundle
-  runtime modules 2.56 KiB 2 modules
-webpack 5.11.1 compiled successfully
+  runtime modules 2.45 KiB 3 modules
+webpack 5.78.0 compiled successfully
 
-asset ./runtime~bundle-inline-cheap-source-map.js 11.2 KiB [emitted] (name: runtime~bundle)
-asset ./bundle-inline-cheap-source-map.js 1.41 KiB [emitted] (name: bundle)
-Entrypoint bundle 12.7 KiB = ./runtime~bundle-inline-cheap-source-map.js 11.2 KiB ./bundle-inline-cheap-source-map.js 1.41 KiB
+asset ./runtime~bundle-inline-cheap-source-map.js 10.7 KiB [emitted] (name: runtime~bundle)
+asset ./bundle-inline-cheap-source-map.js 1.62 KiB [emitted] (name: bundle)
+Entrypoint bundle 12.4 KiB = ./runtime~bundle-inline-cheap-source-map.js 10.7 KiB ./bundle-inline-cheap-source-map.js 1.62 KiB
 chunk (runtime: runtime~bundle) ./bundle-inline-cheap-source-map.js (bundle) 256 bytes [initial] [rendered]
   > coffee-loader!./example.coffee bundle
   ../../node_modules/coffee-loader/dist/cjs.js!./example.coffee 256 bytes [built] [code generated]
     [used exports unknown]
     entry coffee-loader!./example.coffee bundle
-chunk (runtime: runtime~bundle) ./runtime~bundle-inline-cheap-source-map.js (runtime~bundle) 2.56 KiB [entry] [rendered]
+chunk (runtime: runtime~bundle) ./runtime~bundle-inline-cheap-source-map.js (runtime~bundle) 2.45 KiB [entry] [rendered]
   > coffee-loader!./example.coffee bundle
-  runtime modules 2.56 KiB 2 modules
-webpack 5.11.1 compiled successfully
+  runtime modules 2.45 KiB 3 modules
+webpack 5.78.0 compiled successfully
 
-asset ./runtime~bundle-inline-cheap-module-source-map.js 11.3 KiB [emitted] (name: runtime~bundle)
-asset ./bundle-inline-cheap-module-source-map.js 1.31 KiB [emitted] (name: bundle)
-Entrypoint bundle 12.6 KiB = ./runtime~bundle-inline-cheap-module-source-map.js 11.3 KiB ./bundle-inline-cheap-module-source-map.js 1.31 KiB
+asset ./runtime~bundle-inline-cheap-module-source-map.js 10.8 KiB [emitted] (name: runtime~bundle)
+asset ./bundle-inline-cheap-module-source-map.js 1.51 KiB [emitted] (name: bundle)
+Entrypoint bundle 12.3 KiB = ./runtime~bundle-inline-cheap-module-source-map.js 10.8 KiB ./bundle-inline-cheap-module-source-map.js 1.51 KiB
 chunk (runtime: runtime~bundle) ./bundle-inline-cheap-module-source-map.js (bundle) 256 bytes [initial] [rendered]
   > coffee-loader!./example.coffee bundle
   ../../node_modules/coffee-loader/dist/cjs.js!./example.coffee 256 bytes [built] [code generated]
     [used exports unknown]
     entry coffee-loader!./example.coffee bundle
-chunk (runtime: runtime~bundle) ./runtime~bundle-inline-cheap-module-source-map.js (runtime~bundle) 2.56 KiB [entry] [rendered]
+chunk (runtime: runtime~bundle) ./runtime~bundle-inline-cheap-module-source-map.js (runtime~bundle) 2.45 KiB [entry] [rendered]
   > coffee-loader!./example.coffee bundle
-  runtime modules 2.56 KiB 2 modules
-webpack 5.11.1 compiled successfully
+  runtime modules 2.45 KiB 3 modules
+webpack 5.78.0 compiled successfully
 
-asset ./runtime~bundle-source-map.js 5.22 KiB [emitted] (name: runtime~bundle) 1 related asset
-asset ./bundle-source-map.js 711 bytes [emitted] (name: bundle) 1 related asset
-Entrypoint bundle 5.92 KiB (5.01 KiB) = ./runtime~bundle-source-map.js 5.22 KiB ./bundle-source-map.js 711 bytes 2 auxiliary assets
+asset ./runtime~bundle-source-map.js 4.96 KiB [emitted] (name: runtime~bundle) 1 related asset
+asset ./bundle-source-map.js 932 bytes [emitted] (name: bundle) 1 related asset
+Entrypoint bundle 5.87 KiB (4.85 KiB) = ./runtime~bundle-source-map.js 4.96 KiB ./bundle-source-map.js 932 bytes 2 auxiliary assets
 chunk (runtime: runtime~bundle) ./bundle-source-map.js (bundle) 256 bytes [initial] [rendered]
   > coffee-loader!./example.coffee bundle
   ../../node_modules/coffee-loader/dist/cjs.js!./example.coffee 256 bytes [built] [code generated]
     [used exports unknown]
     entry coffee-loader!./example.coffee bundle
-chunk (runtime: runtime~bundle) ./runtime~bundle-source-map.js (runtime~bundle) 2.56 KiB [entry] [rendered]
+chunk (runtime: runtime~bundle) ./runtime~bundle-source-map.js (runtime~bundle) 2.45 KiB [entry] [rendered]
   > coffee-loader!./example.coffee bundle
-  runtime modules 2.56 KiB 2 modules
-webpack 5.11.1 compiled successfully
+  runtime modules 2.45 KiB 3 modules
+webpack 5.78.0 compiled successfully
 
-asset ./runtime~bundle-inline-source-map.js 11.2 KiB [emitted] (name: runtime~bundle)
-asset ./bundle-inline-source-map.js 1.42 KiB [emitted] (name: bundle)
-Entrypoint bundle 12.6 KiB = ./runtime~bundle-inline-source-map.js 11.2 KiB ./bundle-inline-source-map.js 1.42 KiB
+asset ./runtime~bundle-inline-source-map.js 10.7 KiB [emitted] (name: runtime~bundle)
+asset ./bundle-inline-source-map.js 1.64 KiB [emitted] (name: bundle)
+Entrypoint bundle 12.4 KiB = ./runtime~bundle-inline-source-map.js 10.7 KiB ./bundle-inline-source-map.js 1.64 KiB
 chunk (runtime: runtime~bundle) ./bundle-inline-source-map.js (bundle) 256 bytes [initial] [rendered]
   > coffee-loader!./example.coffee bundle
   ../../node_modules/coffee-loader/dist/cjs.js!./example.coffee 256 bytes [built] [code generated]
     [used exports unknown]
     entry coffee-loader!./example.coffee bundle
-chunk (runtime: runtime~bundle) ./runtime~bundle-inline-source-map.js (runtime~bundle) 2.56 KiB [entry] [rendered]
+chunk (runtime: runtime~bundle) ./runtime~bundle-inline-source-map.js (runtime~bundle) 2.45 KiB [entry] [rendered]
   > coffee-loader!./example.coffee bundle
-  runtime modules 2.56 KiB 2 modules
-webpack 5.11.1 compiled successfully
+  runtime modules 2.45 KiB 3 modules
+webpack 5.78.0 compiled successfully
 
-asset ./runtime~bundle-hidden-source-map.js 5.17 KiB [emitted] (name: runtime~bundle) 1 related asset
-asset ./bundle-hidden-source-map.js 665 bytes [emitted] (name: bundle) 1 related asset
-Entrypoint bundle 5.82 KiB (5.02 KiB) = ./runtime~bundle-hidden-source-map.js 5.17 KiB ./bundle-hidden-source-map.js 665 bytes 2 auxiliary assets
+asset ./runtime~bundle-hidden-source-map.js 4.91 KiB [emitted] (name: runtime~bundle) 1 related asset
+asset ./bundle-hidden-source-map.js 886 bytes [emitted] (name: bundle) 1 related asset
+Entrypoint bundle 5.77 KiB (4.87 KiB) = ./runtime~bundle-hidden-source-map.js 4.91 KiB ./bundle-hidden-source-map.js 886 bytes 2 auxiliary assets
 chunk (runtime: runtime~bundle) ./bundle-hidden-source-map.js (bundle) 256 bytes [initial] [rendered]
   > coffee-loader!./example.coffee bundle
   ../../node_modules/coffee-loader/dist/cjs.js!./example.coffee 256 bytes [built] [code generated]
     [used exports unknown]
     entry coffee-loader!./example.coffee bundle
-chunk (runtime: runtime~bundle) ./runtime~bundle-hidden-source-map.js (runtime~bundle) 2.56 KiB [entry] [rendered]
+chunk (runtime: runtime~bundle) ./runtime~bundle-hidden-source-map.js (runtime~bundle) 2.45 KiB [entry] [rendered]
   > coffee-loader!./example.coffee bundle
-  runtime modules 2.56 KiB 2 modules
-webpack 5.11.1 compiled successfully
+  runtime modules 2.45 KiB 3 modules
+webpack 5.78.0 compiled successfully
 
-asset ./runtime~bundle-nosources-source-map.js 5.23 KiB [emitted] (name: runtime~bundle) 1 related asset
-asset ./bundle-nosources-source-map.js 721 bytes [emitted] (name: bundle) 1 related asset
-Entrypoint bundle 5.94 KiB (1.16 KiB) = ./runtime~bundle-nosources-source-map.js 5.23 KiB ./bundle-nosources-source-map.js 721 bytes 2 auxiliary assets
+asset ./runtime~bundle-nosources-source-map.js 4.97 KiB [emitted] (name: runtime~bundle) 1 related asset
+asset ./bundle-nosources-source-map.js 942 bytes [emitted] (name: bundle) 1 related asset
+Entrypoint bundle 5.89 KiB (1.24 KiB) = ./runtime~bundle-nosources-source-map.js 4.97 KiB ./bundle-nosources-source-map.js 942 bytes 2 auxiliary assets
 chunk (runtime: runtime~bundle) ./bundle-nosources-source-map.js (bundle) 256 bytes [initial] [rendered]
   > coffee-loader!./example.coffee bundle
   ../../node_modules/coffee-loader/dist/cjs.js!./example.coffee 256 bytes [built] [code generated]
     [used exports unknown]
     entry coffee-loader!./example.coffee bundle
-chunk (runtime: runtime~bundle) ./runtime~bundle-nosources-source-map.js (runtime~bundle) 2.56 KiB [entry] [rendered]
+chunk (runtime: runtime~bundle) ./runtime~bundle-nosources-source-map.js (runtime~bundle) 2.45 KiB [entry] [rendered]
   > coffee-loader!./example.coffee bundle
-  runtime modules 2.56 KiB 2 modules
-webpack 5.11.1 compiled successfully
+  runtime modules 2.45 KiB 3 modules
+webpack 5.78.0 compiled successfully
 ```
diff --git a/examples/source-map/webpack.config.js b/examples/source-map/webpack.config.js
index 27496c2df62..effd0892118 100644
--- a/examples/source-map/webpack.config.js
+++ b/examples/source-map/webpack.config.js
@@ -1,4 +1,4 @@
-var path = require("path");
+const path = require("path");
 
 module.exports = [
 	"eval",
diff --git a/examples/stats-detailed/README.md b/examples/stats-detailed/README.md
new file mode 100644
index 00000000000..18e05d2780f
--- /dev/null
+++ b/examples/stats-detailed/README.md
@@ -0,0 +1,83 @@
+This configuration will enable the detailed output for the stats report.
+
+You see that everything is working nicely together.
+
+# example.js
+
+```javascript
+console.log("Hello World!");
+```
+
+# webpack.config.js
+
+```javascript
+const path = require("path");
+
+module.exports = {
+    output: {
+		path: path.join(__dirname, "dist"),
+		filename: "output.js"
+	},
+	stats: "detailed"
+};
+```
+
+# dist/output.js
+
+```javascript
+/******/ (() => { // webpackBootstrap
+var __webpack_exports__ = {};
+/*!********************!*\
+  !*** ./example.js ***!
+  \********************/
+/*! unknown exports (runtime-defined) */
+/*! runtime requirements:  */
+console.log("Hello World!");
+
+/******/ })()
+;
+```
+
+# Info
+
+## Production mode
+
+```
+PublicPath: dist/
+asset output.js 28 bytes {179} [emitted] [minimized] (name: main)
+Entrypoint main 28 bytes = output.js
+chunk {179} (runtime: main) output.js (main) 29 bytes [entry] [rendered]
+  > ./example.js main
+./example.js [144] 29 bytes {179} [depth 0] [built] [code generated]
+  [no exports used]
+  Statement (ExpressionStatement) with side effects in source code at 1:0-28
+  ModuleConcatenation bailout: Module is not an ECMAScript module
+
+LOG from webpack.Compilation
+    1 modules hashed, 0 from cache (1 variants per module in average)
+    100% code generated (1 generated, 0 from cache)
++ 24 hidden lines
+
+LOG from webpack.FlagDependencyExportsPlugin
+    0% of exports of modules have been determined (1 no declared exports, 0 not cached, 0 flagged uncacheable, 0 from cache, 0 from mem cache, 0 additional calculations due to dependencies)
++ 3 hidden lines
+
+LOG from webpack.buildChunkGraph
+    2 queue items processed (1 blocks)
+    0 chunk groups connected
+    0 chunk groups processed for merging (0 module sets, 0 forked, 0 + 0 modules forked, 0 + 0 modules merged into fork, 0 resulting modules)
+    0 chunk group info updated (0 already connected chunk groups reconnected)
++ 5 hidden lines
+
+LOG from webpack.FileSystemInfo
+    1 new snapshots created
+    0% root snapshot uncached (0 / 0)
+    0% children snapshot uncached (0 / 0)
+    0 entries tested
+    File info in cache: 1 timestamps 1 hashes 1 timestamp hash combinations
+    File timestamp hash combination snapshot optimization: 0% (0/1) entries shared via 0 shared snapshots (0 times referenced)
+    Directory info in cache: 0 timestamps 0 hashes 0 timestamp hash combinations
+    Managed items info in cache: 0 items
+
+2023-06-23 22:57:08: webpack 5.88.0 compiled successfully (208f5e6e78a48d3e157f)
+```
diff --git a/examples/stats-detailed/build.js b/examples/stats-detailed/build.js
new file mode 100644
index 00000000000..6da1216015d
--- /dev/null
+++ b/examples/stats-detailed/build.js
@@ -0,0 +1,4 @@
+global.NO_REASONS = true;
+global.NO_STATS_OPTIONS = true;
+global.STATS_COLORS = true;
+require("../build-common");
diff --git a/examples/stats-detailed/example.js b/examples/stats-detailed/example.js
new file mode 100644
index 00000000000..019c0f4bc8e
--- /dev/null
+++ b/examples/stats-detailed/example.js
@@ -0,0 +1 @@
+console.log("Hello World!");
diff --git a/examples/stats-detailed/template.md b/examples/stats-detailed/template.md
new file mode 100644
index 00000000000..d475f06a46f
--- /dev/null
+++ b/examples/stats-detailed/template.md
@@ -0,0 +1,29 @@
+This configuration will enable the detailed output for the stats report.
+
+You see that everything is working nicely together.
+
+# example.js
+
+```javascript
+_{{example.js}}_
+```
+
+# webpack.config.js
+
+```javascript
+_{{webpack.config.js}}_
+```
+
+# dist/output.js
+
+```javascript
+_{{dist/output.js}}_
+```
+
+# Info
+
+## Production mode
+
+```
+_{{production:stdout}}_
+```
diff --git a/examples/stats-detailed/webpack.config.js b/examples/stats-detailed/webpack.config.js
new file mode 100644
index 00000000000..a237a81fc37
--- /dev/null
+++ b/examples/stats-detailed/webpack.config.js
@@ -0,0 +1,9 @@
+const path = require("path");
+
+module.exports = {
+    output: {
+		path: path.join(__dirname, "dist"),
+		filename: "output.js"
+	},
+	stats: "detailed"
+};
diff --git a/examples/stats-minimal/README.md b/examples/stats-minimal/README.md
new file mode 100644
index 00000000000..a0cfb112a38
--- /dev/null
+++ b/examples/stats-minimal/README.md
@@ -0,0 +1,49 @@
+This configuration will enable the minimal output for the stats report.
+
+You see that everything is working nicely together.
+
+# example.js
+
+```javascript
+console.log("Hello World!");
+```
+
+# webpack.config.js
+
+```javascript
+const path = require("path");
+
+module.exports = {
+	output: {
+		path: path.join(__dirname, "dist"),
+		filename: "output.js"
+	},
+	stats: "minimal"
+};
+```
+
+# dist/output.js
+
+```javascript
+/******/ (() => { // webpackBootstrap
+var __webpack_exports__ = {};
+/*!********************!*\
+  !*** ./example.js ***!
+  \********************/
+/*! unknown exports (runtime-defined) */
+/*! runtime requirements:  */
+console.log("Hello World!");
+
+/******/ })()
+;
+```
+
+# Info
+
+## Production mode
+
+```
+1 asset
+1 module
+webpack 5.87.0 compiled successfully
+```
\ No newline at end of file
diff --git a/examples/stats-minimal/build.js b/examples/stats-minimal/build.js
new file mode 100644
index 00000000000..6da1216015d
--- /dev/null
+++ b/examples/stats-minimal/build.js
@@ -0,0 +1,4 @@
+global.NO_REASONS = true;
+global.NO_STATS_OPTIONS = true;
+global.STATS_COLORS = true;
+require("../build-common");
diff --git a/examples/stats-minimal/example.js b/examples/stats-minimal/example.js
new file mode 100644
index 00000000000..019c0f4bc8e
--- /dev/null
+++ b/examples/stats-minimal/example.js
@@ -0,0 +1 @@
+console.log("Hello World!");
diff --git a/examples/stats-minimal/template.md b/examples/stats-minimal/template.md
new file mode 100644
index 00000000000..24ffaaa57df
--- /dev/null
+++ b/examples/stats-minimal/template.md
@@ -0,0 +1,29 @@
+This configuration will enable the minimal output for the stats report.
+
+You see that everything is working nicely together.
+
+# example.js
+
+```javascript
+_{{example.js}}_
+```
+
+# webpack.config.js
+
+```javascript
+_{{webpack.config.js}}_
+```
+
+# dist/output.js
+
+```javascript
+_{{dist/output.js}}_
+```
+
+# Info
+
+## Production mode
+
+```
+_{{production:stdout}}_
+```
\ No newline at end of file
diff --git a/examples/stats-minimal/webpack.config.js b/examples/stats-minimal/webpack.config.js
new file mode 100644
index 00000000000..22fbf8330b2
--- /dev/null
+++ b/examples/stats-minimal/webpack.config.js
@@ -0,0 +1,9 @@
+const path = require("path");
+
+module.exports = {
+    output: {
+		path: path.join(__dirname, "dist"),
+		filename: "output.js"
+	},
+	stats: "minimal"
+};
diff --git a/examples/stats-none/README.md b/examples/stats-none/README.md
new file mode 100644
index 00000000000..b1fe4195d04
--- /dev/null
+++ b/examples/stats-none/README.md
@@ -0,0 +1,47 @@
+This configuration will enable the none output for the stats report.
+
+You see that everything is working nicely together.
+
+# example.js
+
+```javascript
+console.log("Hello World!");
+```
+
+# webpack.config.js
+
+```javascript
+const path = require("path");
+
+module.exports = {
+    output: {
+		path: path.join(__dirname, "dist"),
+		filename: "output.js"
+	},
+	stats: "none"
+};
+```
+
+# dist/output.js
+
+```javascript
+/******/ (() => { // webpackBootstrap
+var __webpack_exports__ = {};
+/*!********************!*\
+  !*** ./example.js ***!
+  \********************/
+/*! unknown exports (runtime-defined) */
+/*! runtime requirements:  */
+console.log("Hello World!");
+
+/******/ })()
+;
+```
+
+# Info
+
+## Production mode
+
+```
+
+```
diff --git a/examples/stats-none/build.js b/examples/stats-none/build.js
new file mode 100644
index 00000000000..6da1216015d
--- /dev/null
+++ b/examples/stats-none/build.js
@@ -0,0 +1,4 @@
+global.NO_REASONS = true;
+global.NO_STATS_OPTIONS = true;
+global.STATS_COLORS = true;
+require("../build-common");
diff --git a/examples/stats-none/example.js b/examples/stats-none/example.js
new file mode 100644
index 00000000000..019c0f4bc8e
--- /dev/null
+++ b/examples/stats-none/example.js
@@ -0,0 +1 @@
+console.log("Hello World!");
diff --git a/examples/stats-none/template.md b/examples/stats-none/template.md
new file mode 100644
index 00000000000..b60135662a4
--- /dev/null
+++ b/examples/stats-none/template.md
@@ -0,0 +1,29 @@
+This configuration will enable the none output for the stats report.
+
+You see that everything is working nicely together.
+
+# example.js
+
+```javascript
+_{{example.js}}_
+```
+
+# webpack.config.js
+
+```javascript
+_{{webpack.config.js}}_
+```
+
+# dist/output.js
+
+```javascript
+_{{dist/output.js}}_
+```
+
+# Info
+
+## Production mode
+
+```
+_{{production:stdout}}_
+```
diff --git a/examples/stats-none/webpack.config.js b/examples/stats-none/webpack.config.js
new file mode 100644
index 00000000000..8a687239693
--- /dev/null
+++ b/examples/stats-none/webpack.config.js
@@ -0,0 +1,9 @@
+const path = require("path");
+
+module.exports = {
+    output: {
+		path: path.join(__dirname, "dist"),
+		filename: "output.js"
+	},
+	stats: "none"
+};
diff --git a/examples/stats-normal/README.md b/examples/stats-normal/README.md
new file mode 100644
index 00000000000..becfd3e06c1
--- /dev/null
+++ b/examples/stats-normal/README.md
@@ -0,0 +1,49 @@
+This configuration will enable the normal output for the stats report.
+
+You see that everything is working nicely together.
+
+# example.js
+
+```javascript
+console.log("Hello World!");
+```
+
+# webpack.config.js
+
+```javascript
+const path = require("path");
+
+module.exports = {
+    output: {
+		path: path.join(__dirname, "dist"),
+		filename: "output.js"
+	},
+	stats: "normal"
+};
+```
+
+# dist/output.js
+
+```javascript
+/******/ (() => { // webpackBootstrap
+var __webpack_exports__ = {};
+/*!********************!*\
+  !*** ./example.js ***!
+  \********************/
+/*! unknown exports (runtime-defined) */
+/*! runtime requirements:  */
+console.log("Hello World!");
+
+/******/ })()
+;
+```
+
+# Info
+
+## Production mode
+
+```
+asset output.js 28 bytes [emitted] [minimized] (name: main)
+./example.js 29 bytes [built] [code generated]
+webpack 5.88.0 compiled successfully
+```
\ No newline at end of file
diff --git a/examples/stats-normal/build.js b/examples/stats-normal/build.js
new file mode 100644
index 00000000000..6da1216015d
--- /dev/null
+++ b/examples/stats-normal/build.js
@@ -0,0 +1,4 @@
+global.NO_REASONS = true;
+global.NO_STATS_OPTIONS = true;
+global.STATS_COLORS = true;
+require("../build-common");
diff --git a/examples/stats-normal/example.js b/examples/stats-normal/example.js
new file mode 100644
index 00000000000..019c0f4bc8e
--- /dev/null
+++ b/examples/stats-normal/example.js
@@ -0,0 +1 @@
+console.log("Hello World!");
diff --git a/examples/stats-normal/template.md b/examples/stats-normal/template.md
new file mode 100644
index 00000000000..ed4c81681b5
--- /dev/null
+++ b/examples/stats-normal/template.md
@@ -0,0 +1,29 @@
+This configuration will enable the normal output for the stats report.
+
+You see that everything is working nicely together.
+
+# example.js
+
+```javascript
+_{{example.js}}_
+```
+
+# webpack.config.js
+
+```javascript
+_{{webpack.config.js}}_
+```
+
+# dist/output.js
+
+```javascript
+_{{dist/output.js}}_
+```
+
+# Info
+
+## Production mode
+
+```
+_{{production:stdout}}_
+```
\ No newline at end of file
diff --git a/examples/stats-normal/webpack.config.js b/examples/stats-normal/webpack.config.js
new file mode 100644
index 00000000000..e741993c8d9
--- /dev/null
+++ b/examples/stats-normal/webpack.config.js
@@ -0,0 +1,9 @@
+const path = require("path");
+
+module.exports = {
+    output: {
+		path: path.join(__dirname, "dist"),
+		filename: "output.js"
+	},
+	stats: "normal"
+};
diff --git a/examples/stats-summary/README.md b/examples/stats-summary/README.md
new file mode 100644
index 00000000000..7ebee7c56d0
--- /dev/null
+++ b/examples/stats-summary/README.md
@@ -0,0 +1,47 @@
+This configuration will enable the summary output for the stats report.
+
+You see that everything is working nicely together.
+
+# example.js
+
+```javascript
+console.log("Hello World!");
+```
+
+# webpack.config.js
+
+```javascript
+const path = require("path");
+
+module.exports = {
+    output: {
+		path: path.join(__dirname, "dist"),
+		filename: "output.js"
+	},
+	stats: "summary"
+};
+```
+
+# dist/output.js
+
+```javascript
+/******/ (() => { // webpackBootstrap
+var __webpack_exports__ = {};
+/*!********************!*\
+  !*** ./example.js ***!
+  \********************/
+/*! unknown exports (runtime-defined) */
+/*! runtime requirements:  */
+console.log("Hello World!");
+
+/******/ })()
+;
+```
+
+# Info
+
+## Production mode
+
+```
+webpack 5.88.0 compiled successfully
+```
diff --git a/examples/stats-summary/build.js b/examples/stats-summary/build.js
new file mode 100644
index 00000000000..6da1216015d
--- /dev/null
+++ b/examples/stats-summary/build.js
@@ -0,0 +1,4 @@
+global.NO_REASONS = true;
+global.NO_STATS_OPTIONS = true;
+global.STATS_COLORS = true;
+require("../build-common");
diff --git a/examples/stats-summary/example.js b/examples/stats-summary/example.js
new file mode 100644
index 00000000000..019c0f4bc8e
--- /dev/null
+++ b/examples/stats-summary/example.js
@@ -0,0 +1 @@
+console.log("Hello World!");
diff --git a/examples/stats-summary/template.md b/examples/stats-summary/template.md
new file mode 100644
index 00000000000..087cfc32b5f
--- /dev/null
+++ b/examples/stats-summary/template.md
@@ -0,0 +1,29 @@
+This configuration will enable the summary output for the stats report.
+
+You see that everything is working nicely together.
+
+# example.js
+
+```javascript
+_{{example.js}}_
+```
+
+# webpack.config.js
+
+```javascript
+_{{webpack.config.js}}_
+```
+
+# dist/output.js
+
+```javascript
+_{{dist/output.js}}_
+```
+
+# Info
+
+## Production mode
+
+```
+_{{production:stdout}}_
+```
diff --git a/examples/stats-summary/webpack.config.js b/examples/stats-summary/webpack.config.js
new file mode 100644
index 00000000000..94e9a0f0b2d
--- /dev/null
+++ b/examples/stats-summary/webpack.config.js
@@ -0,0 +1,9 @@
+const path = require("path");
+
+module.exports = {
+    output: {
+		path: path.join(__dirname, "dist"),
+		filename: "output.js"
+	},
+	stats: "summary"
+};
diff --git a/examples/template-common.js b/examples/template-common.js
index c68c5ac1d0f..2e5a9db18f5 100644
--- a/examples/template-common.js
+++ b/examples/template-common.js
@@ -60,7 +60,7 @@ exports.replaceResults = (template, baseDir, stdout, prefix) => {
 	const regexp = new RegExp("_\\{\\{" + (prefix ? prefix + ":" : "") + "([^:\\}]+)\\}\\}_", "g");
 
 	return template.replace(regexp, function(match) {
-		match = match.substr(3 + (prefix ? prefix.length + 1 : 0), match.length - 6 - (prefix ? prefix.length + 1 : 0));
+		match = match.slice(3 + (prefix ? prefix.length + 1 : 0), -3);
 		if(match === "stdout")
 			return stdout;
 		try {
diff --git a/examples/top-level-await/README.md b/examples/top-level-await/README.md
index 882e3285cf5..5e8cddc5b07 100644
--- a/examples/top-level-await/README.md
+++ b/examples/top-level-await/README.md
@@ -119,25 +119,7 @@ When compiling for other targets like node.js, electron or WebWorkers, it may be
 /******/ (() => { // webpackBootstrap
 /******/ 	"use strict";
 /******/ 	var __webpack_modules__ = ([
-/* 0 */
-/*!********************!*\
-  !*** ./example.js ***!
-  \********************/
-/*! namespace exports */
-/*! exports [not provided] [no usage info] */
-/*! runtime requirements: __webpack_require__, __webpack_require__.r, __webpack_exports__, __webpack_require__.* */
-/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
-
-__webpack_require__.r(__webpack_exports__);
-/* harmony import */ var _Actions_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./Actions.js */ 1);
-
-
-(async ()=> {
-	await (0,_Actions_js__WEBPACK_IMPORTED_MODULE_0__.CreateUserAction)("John");
-})();
-
-
-/***/ }),
+/* 0 */,
 /* 1 */
 /*!********************!*\
   !*** ./Actions.js ***!
@@ -151,8 +133,8 @@ __webpack_require__.r(__webpack_exports__);
 
 __webpack_require__.r(__webpack_exports__);
 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
-/* harmony export */   "CreateUserAction": () => /* binding */ CreateUserAction,
-/* harmony export */   "AlternativeCreateUserAction": () => /* binding */ AlternativeCreateUserAction
+/* harmony export */   "AlternativeCreateUserAction": () => (/* binding */ AlternativeCreateUserAction),
+/* harmony export */   "CreateUserAction": () => (/* binding */ CreateUserAction)
 /* harmony export */ });
 // import() doesn't care about whether a module is an async module or not
 const UserApi = __webpack_require__.e(/*! import() */ 497).then(__webpack_require__.bind(__webpack_require__, /*! ./UserApi.js */ 2));
@@ -197,8 +179,9 @@ const AlternativeCreateUserAction = async name => {
 /******/ 	// The require function
 /******/ 	function __webpack_require__(moduleId) {
 /******/ 		// Check if module is in cache
-/******/ 		if(__webpack_module_cache__[moduleId]) {
-/******/ 			return __webpack_module_cache__[moduleId].exports;
+/******/ 		var cachedModule = __webpack_module_cache__[moduleId];
+/******/ 		if (cachedModule !== undefined) {
+/******/ 			return cachedModule.exports;
 /******/ 		}
 /******/ 		// Create a new module (and put it into the cache)
 /******/ 		var module = __webpack_module_cache__[moduleId] = {
@@ -218,6 +201,75 @@ const AlternativeCreateUserAction = async name => {
 /******/ 	__webpack_require__.m = __webpack_modules__;
 /******/ 	
 /************************************************************************/
+/******/ 	/* webpack/runtime/async module */
+/******/ 	(() => {
+/******/ 		var webpackQueues = typeof Symbol === "function" ? Symbol("webpack queues") : "__webpack_queues__";
+/******/ 		var webpackExports = typeof Symbol === "function" ? Symbol("webpack exports") : "__webpack_exports__";
+/******/ 		var webpackError = typeof Symbol === "function" ? Symbol("webpack error") : "__webpack_error__";
+/******/ 		var resolveQueue = (queue) => {
+/******/ 			if(queue && !queue.d) {
+/******/ 				queue.d = 1;
+/******/ 				queue.forEach((fn) => (fn.r--));
+/******/ 				queue.forEach((fn) => (fn.r-- ? fn.r++ : fn()));
+/******/ 			}
+/******/ 		}
+/******/ 		var wrapDeps = (deps) => (deps.map((dep) => {
+/******/ 			if(dep !== null && typeof dep === "object") {
+/******/ 				if(dep[webpackQueues]) return dep;
+/******/ 				if(dep.then) {
+/******/ 					var queue = [];
+/******/ 					queue.d = 0;
+/******/ 					dep.then((r) => {
+/******/ 						obj[webpackExports] = r;
+/******/ 						resolveQueue(queue);
+/******/ 					}, (e) => {
+/******/ 						obj[webpackError] = e;
+/******/ 						resolveQueue(queue);
+/******/ 					});
+/******/ 					var obj = {};
+/******/ 					obj[webpackQueues] = (fn) => (fn(queue));
+/******/ 					return obj;
+/******/ 				}
+/******/ 			}
+/******/ 			var ret = {};
+/******/ 			ret[webpackQueues] = x => {};
+/******/ 			ret[webpackExports] = dep;
+/******/ 			return ret;
+/******/ 		}));
+/******/ 		__webpack_require__.a = (module, body, hasAwait) => {
+/******/ 			var queue;
+/******/ 			hasAwait && ((queue = []).d = 1);
+/******/ 			var depQueues = new Set();
+/******/ 			var exports = module.exports;
+/******/ 			var currentDeps;
+/******/ 			var outerResolve;
+/******/ 			var reject;
+/******/ 			var promise = new Promise((resolve, rej) => {
+/******/ 				reject = rej;
+/******/ 				outerResolve = resolve;
+/******/ 			});
+/******/ 			promise[webpackExports] = exports;
+/******/ 			promise[webpackQueues] = (fn) => (queue && fn(queue), depQueues.forEach(fn), promise["catch"](x => {}));
+/******/ 			module.exports = promise;
+/******/ 			body((deps) => {
+/******/ 				currentDeps = wrapDeps(deps);
+/******/ 				var fn;
+/******/ 				var getResult = () => (currentDeps.map((d) => {
+/******/ 					if(d[webpackError]) throw d[webpackError];
+/******/ 					return d[webpackExports];
+/******/ 				}))
+/******/ 				var promise = new Promise((resolve) => {
+/******/ 					fn = () => (resolve(getResult));
+/******/ 					fn.r = 0;
+/******/ 					var fnQueue = (q) => (q !== queue && !depQueues.has(q) && (depQueues.add(q), q && !q.d && (fn.r++, q.push(fn))));
+/******/ 					currentDeps.map((dep) => (dep[webpackQueues](fnQueue)));
+/******/ 				});
+/******/ 				return fn.r ? promise : getResult();
+/******/ 			}, (err) => ((err ? reject(promise[webpackError] = err) : outerResolve(exports)), resolveQueue(queue)));
+/******/ 			queue && (queue.d = 0);
+/******/ 		};
+/******/ 	})();
+/******/ 	
 /******/ 	/* webpack/runtime/define property getters */
 /******/ 	(() => {
 /******/ 		// define getter functions for harmony exports
@@ -254,7 +306,7 @@ const AlternativeCreateUserAction = async name => {
 /******/ 	
 /******/ 	/* webpack/runtime/hasOwnProperty shorthand */
 /******/ 	(() => {
-/******/ 		__webpack_require__.o = (obj, prop) => Object.prototype.hasOwnProperty.call(obj, prop)
+/******/ 		__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
 /******/ 	})();
 /******/ 	
 /******/ 	/* webpack/runtime/load script */
@@ -262,7 +314,7 @@ const AlternativeCreateUserAction = async name => {
 /******/ 		var inProgress = {};
 /******/ 		// data-webpack is not used as build has no uniqueName
 /******/ 		// loadScript function to load a script via script tag
-/******/ 		__webpack_require__.l = (url, done, key) => {
+/******/ 		__webpack_require__.l = (url, done, key, chunkId) => {
 /******/ 			if(inProgress[url]) { inProgress[url].push(done); return; }
 /******/ 			var script, needAttach;
 /******/ 			if(key !== undefined) {
@@ -292,10 +344,9 @@ const AlternativeCreateUserAction = async name => {
 /******/ 				var doneFns = inProgress[url];
 /******/ 				delete inProgress[url];
 /******/ 				script.parentNode && script.parentNode.removeChild(script);
-/******/ 				doneFns && doneFns.forEach((fn) => fn(event));
+/******/ 				doneFns && doneFns.forEach((fn) => (fn(event)));
 /******/ 				if(prev) return prev(event);
 /******/ 			}
-/******/ 			;
 /******/ 			var timeout = setTimeout(onScriptComplete.bind(null, undefined, { type: 'timeout', target: script }), 120000);
 /******/ 			script.onerror = onScriptComplete.bind(null, script.onerror);
 /******/ 			script.onload = onScriptComplete.bind(null, script.onload);
@@ -325,12 +376,11 @@ const AlternativeCreateUserAction = async name => {
 /******/ 		
 /******/ 		// object to store loaded and loading chunks
 /******/ 		// undefined = chunk not loaded, null = chunk preloaded/prefetched
-/******/ 		// Promise = chunk loading, 0 = chunk loaded
+/******/ 		// [resolve, reject, Promise] = chunk loading, 0 = chunk loaded
 /******/ 		var installedChunks = {
 /******/ 			179: 0
 /******/ 		};
 /******/ 		
-/******/ 		
 /******/ 		__webpack_require__.f.j = (chunkId, promises) => {
 /******/ 				// JSONP chunk loading for javascript
 /******/ 				var installedChunkData = __webpack_require__.o(installedChunks, chunkId) ? installedChunks[chunkId] : undefined;
@@ -342,9 +392,7 @@ const AlternativeCreateUserAction = async name => {
 /******/ 					} else {
 /******/ 						if(true) { // all chunks have JS
 /******/ 							// setup Promise in chunk cache
-/******/ 							var promise = new Promise((resolve, reject) => {
-/******/ 								installedChunkData = installedChunks[chunkId] = [resolve, reject];
-/******/ 							});
+/******/ 							var promise = new Promise((resolve, reject) => (installedChunkData = installedChunks[chunkId] = [resolve, reject]));
 /******/ 							promises.push(installedChunkData[2] = promise);
 /******/ 		
 /******/ 							// start chunk loading
@@ -366,7 +414,7 @@ const AlternativeCreateUserAction = async name => {
 /******/ 									}
 /******/ 								}
 /******/ 							};
-/******/ 							__webpack_require__.l(url, loadingEnded, "chunk-" + chunkId);
+/******/ 							__webpack_require__.l(url, loadingEnded, "chunk-" + chunkId, chunkId);
 /******/ 						} else installedChunks[chunkId] = 0;
 /******/ 					}
 /******/ 				}
@@ -380,39 +428,36 @@ const AlternativeCreateUserAction = async name => {
 /******/ 		
 /******/ 		// no HMR manifest
 /******/ 		
-/******/ 		// no deferred startup
+/******/ 		// no on chunks loaded
 /******/ 		
 /******/ 		// install a JSONP callback for chunk loading
 /******/ 		var webpackJsonpCallback = (parentChunkLoadingFunction, data) => {
 /******/ 			var [chunkIds, moreModules, runtime] = data;
 /******/ 			// add "moreModules" to the modules object,
 /******/ 			// then flag all "chunkIds" as loaded and fire callback
-/******/ 			var moduleId, chunkId, i = 0, resolves = [];
+/******/ 			var moduleId, chunkId, i = 0;
+/******/ 			if(chunkIds.some((id) => (installedChunks[id] !== 0))) {
+/******/ 				for(moduleId in moreModules) {
+/******/ 					if(__webpack_require__.o(moreModules, moduleId)) {
+/******/ 						__webpack_require__.m[moduleId] = moreModules[moduleId];
+/******/ 					}
+/******/ 				}
+/******/ 				if(runtime) var result = runtime(__webpack_require__);
+/******/ 			}
+/******/ 			if(parentChunkLoadingFunction) parentChunkLoadingFunction(data);
 /******/ 			for(;i < chunkIds.length; i++) {
 /******/ 				chunkId = chunkIds[i];
 /******/ 				if(__webpack_require__.o(installedChunks, chunkId) && installedChunks[chunkId]) {
-/******/ 					resolves.push(installedChunks[chunkId][0]);
+/******/ 					installedChunks[chunkId][0]();
 /******/ 				}
 /******/ 				installedChunks[chunkId] = 0;
 /******/ 			}
-/******/ 			for(moduleId in moreModules) {
-/******/ 				if(__webpack_require__.o(moreModules, moduleId)) {
-/******/ 					__webpack_require__.m[moduleId] = moreModules[moduleId];
-/******/ 				}
-/******/ 			}
-/******/ 			if(runtime) runtime(__webpack_require__);
-/******/ 			if(parentChunkLoadingFunction) parentChunkLoadingFunction(data);
-/******/ 			while(resolves.length) {
-/******/ 				resolves.shift()();
-/******/ 			}
 /******/ 		
 /******/ 		}
 /******/ 		
 /******/ 		var chunkLoadingGlobal = self["webpackChunk"] = self["webpackChunk"] || [];
 /******/ 		chunkLoadingGlobal.forEach(webpackJsonpCallback.bind(null, 0));
 /******/ 		chunkLoadingGlobal.push = webpackJsonpCallback.bind(null, chunkLoadingGlobal.push.bind(chunkLoadingGlobal));
-/******/ 		
-/******/ 		// no deferred startup
 /******/ 	})();
 /******/ 	
 /************************************************************************/
@@ -421,10 +466,25 @@ const AlternativeCreateUserAction = async name => {
 
 
 ``` js
-/******/ 	// startup
-/******/ 	// Load entry module
-/******/ 	__webpack_require__(0);
-/******/ 	// This entry module used 'exports' so it can't be inlined
+var __webpack_exports__ = {};
+// This entry need to be wrapped in an IIFE because it need to be isolated against other modules in the chunk.
+(() => {
+/*!********************!*\
+  !*** ./example.js ***!
+  \********************/
+/*! namespace exports */
+/*! exports [not provided] [no usage info] */
+/*! runtime requirements: __webpack_require__, __webpack_require__.r, __webpack_exports__, __webpack_require__.* */
+__webpack_require__.r(__webpack_exports__);
+/* harmony import */ var _Actions_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./Actions.js */ 1);
+
+
+(async ()=> {
+	await (0,_Actions_js__WEBPACK_IMPORTED_MODULE_0__.CreateUserAction)("John");
+})();
+
+})();
+
 /******/ })()
 ;
 ```
@@ -432,6 +492,7 @@ const AlternativeCreateUserAction = async name => {
 # dist/497.output.js
 
 ```javascript
+"use strict";
 (self["webpackChunk"] = self["webpackChunk"] || []).push([[497],[
 /* 0 */,
 /* 1 */,
@@ -442,17 +503,17 @@ const AlternativeCreateUserAction = async name => {
 /*! namespace exports */
 /*! export createUser [provided] [no usage info] [missing usage info prevents renaming] */
 /*! other exports [not provided] [no usage info] */
-/*! runtime requirements: __webpack_require__, __webpack_require__.r, __webpack_exports__, module, __webpack_require__.d, __webpack_require__.* */
+/*! runtime requirements: __webpack_require__, __webpack_require__.r, __webpack_exports__, module, __webpack_require__.a, __webpack_require__.d, __webpack_require__.* */
 /***/ ((module, __webpack_exports__, __webpack_require__) => {
 
-"use strict";
-module.exports = (async () => {
+__webpack_require__.a(module, async (__webpack_handle_async_dependencies__, __webpack_async_result__) => { try {
 __webpack_require__.r(__webpack_exports__);
 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
-/* harmony export */   "createUser": () => /* binding */ createUser
+/* harmony export */   "createUser": () => (/* binding */ createUser)
 /* harmony export */ });
 /* harmony import */ var _db_connection_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./db-connection.js */ 3);
-_db_connection_js__WEBPACK_IMPORTED_MODULE_0__ = await Promise.resolve(_db_connection_js__WEBPACK_IMPORTED_MODULE_0__);
+var __webpack_async_dependencies__ = __webpack_handle_async_dependencies__([_db_connection_js__WEBPACK_IMPORTED_MODULE_0__]);
+_db_connection_js__WEBPACK_IMPORTED_MODULE_0__ = (__webpack_async_dependencies__.then ? (await __webpack_async_dependencies__)() : __webpack_async_dependencies__)[0];
 
 
 const createUser = async name => {
@@ -461,8 +522,8 @@ const createUser = async name => {
 	await (0,_db_connection_js__WEBPACK_IMPORTED_MODULE_0__.dbCall)({ command });
 };
 
-return __webpack_exports__;
-})();
+__webpack_async_result__();
+} catch(e) { __webpack_async_result__(e); } });
 
 /***/ }),
 /* 3 */
@@ -473,15 +534,14 @@ return __webpack_exports__;
 /*! export close [provided] [no usage info] [missing usage info prevents renaming] */
 /*! export dbCall [provided] [no usage info] [missing usage info prevents renaming] */
 /*! other exports [not provided] [no usage info] */
-/*! runtime requirements: __webpack_require__.r, __webpack_exports__, module, __webpack_require__.d, __webpack_require__.* */
+/*! runtime requirements: __webpack_require__.r, __webpack_exports__, module, __webpack_require__.a, __webpack_require__.d, __webpack_require__.* */
 /***/ ((module, __webpack_exports__, __webpack_require__) => {
 
-"use strict";
-module.exports = (async () => {
+__webpack_require__.a(module, async (__webpack_handle_async_dependencies__, __webpack_async_result__) => { try {
 __webpack_require__.r(__webpack_exports__);
 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
-/* harmony export */   "dbCall": () => /* binding */ dbCall,
-/* harmony export */   "close": () => /* binding */ close
+/* harmony export */   "close": () => (/* binding */ close),
+/* harmony export */   "dbCall": () => (/* binding */ dbCall)
 /* harmony export */ });
 const connectToDB = async url => {
 	await new Promise(r => setTimeout(r, 1000));
@@ -500,8 +560,8 @@ const close = () => {
 	console.log("closes the DB connection");
 };
 
-return __webpack_exports__;
-})();
+__webpack_async_result__();
+} catch(e) { __webpack_async_result__(e); } }, 1);
 
 /***/ })
 ]]);
@@ -510,7 +570,7 @@ return __webpack_exports__;
 ## in production mode:
 
 ```javascript
-(self.webpackChunk=self.webpackChunk||[]).push([[497],{497:(e,a,s)=>{"use strict";e.exports=(async()=>{s.r(a),s.d(a,{createUser:()=>t});var e=s(447);e=await Promise.resolve(e);const t=async a=>{command=`CREATE USER ${a}`,await(0,e.j)({command})};return a})()},447:(e,a,s)=>{"use strict";e.exports=(async()=>{s.d(a,{j:()=>e}),await(async e=>{await new Promise((e=>setTimeout(e,1e3)))})();const e=async e=>(await new Promise((e=>setTimeout(e,100))),"fake data");return a})()}}]);
+"use strict";(self.webpackChunk=self.webpackChunk||[]).push([[497],{497:(a,e,t)=>{t.a(a,(async(a,c)=>{try{t.r(e),t.d(e,{createUser:()=>m});var s=t(447),n=a([s]);s=(n.then?(await n)():n)[0];const m=async a=>{command=`CREATE USER ${a}`,await(0,s.j)({command})};c()}catch(a){c(a)}}))},447:(a,e,t)=>{t.a(a,(async(a,c)=>{try{t.d(e,{j:()=>s});const a=async a=>{await new Promise((a=>setTimeout(a,1e3)))};await a("my-sql://example.com");const s=async a=>(await new Promise((a=>setTimeout(a,100))),"fake data");c()}catch(a){c(a)}}),1)}}]);
 ```
 
 # Info
@@ -518,11 +578,11 @@ return __webpack_exports__;
 ## Unoptimized
 
 ```
-asset output.js 12.3 KiB [emitted] (name: main)
-asset 497.output.js 2.52 KiB [emitted]
-chunk (runtime: main) output.js (main) 1.19 KiB (javascript) 5.54 KiB (runtime) [entry] [rendered]
+asset output.js 15 KiB [emitted] (name: main)
+asset 497.output.js 2.97 KiB [emitted]
+chunk (runtime: main) output.js (main) 1.19 KiB (javascript) 7.57 KiB (runtime) [entry] [rendered]
   > ./example.js main
-  runtime modules 5.54 KiB 8 modules
+  runtime modules 7.57 KiB 9 modules
   dependent modules 1.09 KiB [dependent] 1 module
   ./example.js 103 bytes [built] [code generated]
     [no exports]
@@ -537,17 +597,17 @@ chunk (runtime: main) 497.output.js 617 bytes [rendered]
     [used exports unknown]
     import() ./UserApi.js ./Actions.js 2:16-38
     import() ./UserApi.js ./Actions.js 22:30-52
-webpack 5.11.1 compiled successfully
+webpack 5.78.0 compiled successfully
 ```
 
 ## Production mode
 
 ```
-asset output.js 2.02 KiB [emitted] [minimized] (name: main)
-asset 497.output.js 477 bytes [emitted] [minimized]
-chunk (runtime: main) output.js (main) 1.19 KiB (javascript) 5.54 KiB (runtime) [entry] [rendered]
+asset output.js 2.94 KiB [emitted] [minimized] (name: main)
+asset 497.output.js 531 bytes [emitted] [minimized]
+chunk (runtime: main) output.js (main) 1.19 KiB (javascript) 7.57 KiB (runtime) [entry] [rendered]
   > ./example.js main
-  runtime modules 5.54 KiB 8 modules
+  runtime modules 7.57 KiB 9 modules
   ./example.js + 1 modules 1.19 KiB [built] [code generated]
     [no exports]
     [no exports used]
@@ -560,5 +620,5 @@ chunk (runtime: main) 497.output.js 617 bytes [rendered]
     [exports: createUser]
     import() ./UserApi.js ./example.js + 1 modules ./Actions.js 2:16-38
     import() ./UserApi.js ./example.js + 1 modules ./Actions.js 22:30-52
-webpack 5.11.1 compiled successfully
+webpack 5.78.0 compiled successfully
 ```
diff --git a/examples/two-explicit-vendor-chunks/README.md b/examples/two-explicit-vendor-chunks/README.md
index 50706b0679c..7b1fa8a7a48 100644
--- a/examples/two-explicit-vendor-chunks/README.md
+++ b/examples/two-explicit-vendor-chunks/README.md
@@ -3,7 +3,7 @@
 ```javascript
 var path = require("path");
 module.exports = {
-	// mode: "development || "production",
+	// mode: "development" || "production",
 	entry: {
 		vendor1: ["./vendor1"],
 		vendor2: ["./vendor2"],
@@ -64,8 +64,9 @@ module.exports = "Vendor1";
 /******/ 	// The require function
 /******/ 	function __webpack_require__(moduleId) {
 /******/ 		// Check if module is in cache
-/******/ 		if(__webpack_module_cache__[moduleId]) {
-/******/ 			return __webpack_module_cache__[moduleId].exports;
+/******/ 		var cachedModule = __webpack_module_cache__[moduleId];
+/******/ 		if (cachedModule !== undefined) {
+/******/ 			return cachedModule.exports;
 /******/ 		}
 /******/ 		// Create a new module (and put it into the cache)
 /******/ 		var module = __webpack_module_cache__[moduleId] = {
@@ -87,10 +88,12 @@ module.exports = "Vendor1";
 
 
 ``` js
+/******/ 	
 /******/ 	// startup
-/******/ 	// Load entry module
+/******/ 	// Load entry module and return exports
 /******/ 	// This entry module is referenced by other modules so it can't be inlined
-/******/ 	__webpack_require__(0);
+/******/ 	var __webpack_exports__ = __webpack_require__(0);
+/******/ 	
 /******/ })()
 ;
 ```
@@ -139,8 +142,9 @@ __webpack_require__(/*! ./vendor1 */ 0);
 /******/ 	// The require function
 /******/ 	function __webpack_require__(moduleId) {
 /******/ 		// Check if module is in cache
-/******/ 		if(__webpack_module_cache__[moduleId]) {
-/******/ 			return __webpack_module_cache__[moduleId].exports;
+/******/ 		var cachedModule = __webpack_module_cache__[moduleId];
+/******/ 		if (cachedModule !== undefined) {
+/******/ 			return cachedModule.exports;
 /******/ 		}
 /******/ 		// Create a new module (and put it into the cache)
 /******/ 		var module = __webpack_module_cache__[moduleId] = {
@@ -162,10 +166,12 @@ __webpack_require__(/*! ./vendor1 */ 0);
 
 
 ``` js
+/******/ 	
 /******/ 	// startup
-/******/ 	// Load entry module
+/******/ 	// Load entry module and return exports
 /******/ 	// This entry module is referenced by other modules so it can't be inlined
-/******/ 	__webpack_require__(1);
+/******/ 	var __webpack_exports__ = __webpack_require__(1);
+/******/ 	
 /******/ })()
 ;
 ```
@@ -229,8 +235,9 @@ __webpack_require__(/*! ./vendor2 */ 1);
 /******/ 	// The require function
 /******/ 	function __webpack_require__(moduleId) {
 /******/ 		// Check if module is in cache
-/******/ 		if(__webpack_module_cache__[moduleId]) {
-/******/ 			return __webpack_module_cache__[moduleId].exports;
+/******/ 		var cachedModule = __webpack_module_cache__[moduleId];
+/******/ 		if (cachedModule !== undefined) {
+/******/ 			return cachedModule.exports;
 /******/ 		}
 /******/ 		// Create a new module (and put it into the cache)
 /******/ 		var module = __webpack_module_cache__[moduleId] = {
@@ -252,10 +259,12 @@ __webpack_require__(/*! ./vendor2 */ 1);
 
 
 ``` js
+/******/ 	
 /******/ 	// startup
-/******/ 	// Load entry module
+/******/ 	// Load entry module and return exports
 /******/ 	// This entry module is referenced by other modules so it can't be inlined
-/******/ 	__webpack_require__(2);
+/******/ 	var __webpack_exports__ = __webpack_require__(2);
+/******/ 	
 /******/ })()
 ;
 ```
@@ -265,11 +274,11 @@ __webpack_require__(/*! ./vendor2 */ 1);
 ## Unoptimized
 
 ```
-asset pageA.js 2.33 KiB [emitted] (name: pageA)
-asset vendor2.js 1.9 KiB [emitted] (name: vendor2)
-asset vendor1.js 1.51 KiB [emitted] (name: vendor1)
-asset pageB.js 1.51 KiB [emitted] (name: pageB)
-asset pageC.js 1.51 KiB [emitted] (name: pageC)
+asset pageA.js 2.43 KiB [emitted] (name: pageA)
+asset vendor2.js 2 KiB [emitted] (name: vendor2)
+asset vendor1.js 1.61 KiB [emitted] (name: vendor1)
+asset pageB.js 1.61 KiB [emitted] (name: pageB)
+asset pageC.js 1.61 KiB [emitted] (name: pageC)
 chunk (runtime: pageA) pageA.js (pageA) 147 bytes [entry] [rendered]
   > ./pageA pageA
   dependent modules 77 bytes [dependent] 2 modules
@@ -305,17 +314,17 @@ chunk (runtime: vendor2) vendor2.js (vendor2) 77 bytes [entry] [rendered]
     cjs require ./vendor2 ./pageA.js 3:0-20
     cjs self exports reference ./vendor2.js 1:0-14
     entry ./vendor2 vendor2
-webpack 5.11.1 compiled successfully
+webpack 5.78.0 compiled successfully
 ```
 
 ## Production mode
 
 ```
-asset pageA.js 251 bytes [emitted] [minimized] (name: pageA)
-asset vendor2.js 204 bytes [emitted] [minimized] (name: vendor2)
-asset vendor1.js 162 bytes [emitted] [minimized] (name: vendor1)
-asset pageB.js 160 bytes [emitted] [minimized] (name: pageB)
-asset pageC.js 160 bytes [emitted] [minimized] (name: pageC)
+asset pageA.js 265 bytes [emitted] [minimized] (name: pageA)
+asset vendor2.js 218 bytes [emitted] [minimized] (name: vendor2)
+asset vendor1.js 176 bytes [emitted] [minimized] (name: vendor1)
+asset pageB.js 174 bytes [emitted] [minimized] (name: pageB)
+asset pageC.js 174 bytes [emitted] [minimized] (name: pageC)
 chunk (runtime: pageB) pageB.js (pageB) 25 bytes [entry] [rendered]
   > ./pageB pageB
   ./pageB.js 25 bytes [built] [code generated]
@@ -351,5 +360,5 @@ chunk (runtime: vendor1) vendor1.js (vendor1) 27 bytes [entry] [rendered]
     cjs self exports reference ./vendor1.js 1:0-14
     cjs require ./vendor1 ./vendor2.js 2:0-20
     entry ./vendor1 vendor1
-webpack 5.11.1 compiled successfully
+webpack 5.78.0 compiled successfully
 ```
diff --git a/examples/two-explicit-vendor-chunks/webpack.config.js b/examples/two-explicit-vendor-chunks/webpack.config.js
index 582fdd0dbb2..f1c79238e54 100644
--- a/examples/two-explicit-vendor-chunks/webpack.config.js
+++ b/examples/two-explicit-vendor-chunks/webpack.config.js
@@ -1,6 +1,7 @@
-var path = require("path");
+const path = require("path");
+
 module.exports = {
-	// mode: "development || "production",
+	// mode: "development" || "production",
 	entry: {
 		vendor1: ["./vendor1"],
 		vendor2: ["./vendor2"],
diff --git a/examples/typescript/README.md b/examples/typescript/README.md
index 4ea49b86dea..3412b1b9728 100644
--- a/examples/typescript/README.md
+++ b/examples/typescript/README.md
@@ -25,9 +25,6 @@ const ForkTsCheckerWebpackPlugin = require("fork-ts-checker-webpack-plugin");
 
 module.exports = (env = "development") => ({
 	mode: env,
-	entry: {
-		output: "./index.ts"
-	},
 	module: {
 		rules: [
 			{
@@ -58,15 +55,17 @@ module.exports = (env = "development") => ({
   \******************/
 /*! unknown exports (runtime-defined) */
 /*! runtime requirements: top-level-this-exports */
-/*! CommonJS bailout: this is used directly at 1:22-26 */
+/*! CommonJS bailout: this is used directly at 1:21-25 */
 /***/ (function() {
 
-var __spreadArrays = (this && this.__spreadArrays) || function () {
-    for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;
-    for (var r = Array(s), k = 0, i = 0; i < il; i++)
-        for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)
-            r[k] = a[j];
-    return r;
+var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
+    if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
+        if (ar || !(i in from)) {
+            if (!ar) ar = Array.prototype.slice.call(from, 0, i);
+            ar[i] = from[i];
+        }
+    }
+    return to.concat(ar || Array.prototype.slice.call(from));
 };
 var myName = "Junya";
 var age = 22;
@@ -75,7 +74,7 @@ function getArray() {
     for (var _i = 0; _i < arguments.length; _i++) {
         args[_i] = arguments[_i];
     }
-    return __spreadArrays(args);
+    return __spreadArray([], args, true);
 }
 console.log(getArray("foo", "bar"));
 console.log(getArray(1, 2, 3));
@@ -95,8 +94,9 @@ console.log(getArray(1, 2, 3));
 /******/ 	// The require function
 /******/ 	function __webpack_require__(moduleId) {
 /******/ 		// Check if module is in cache
-/******/ 		if(__webpack_module_cache__[moduleId]) {
-/******/ 			return __webpack_module_cache__[moduleId].exports;
+/******/ 		var cachedModule = __webpack_module_cache__[moduleId];
+/******/ 		if (cachedModule !== undefined) {
+/******/ 			return cachedModule.exports;
 /******/ 		}
 /******/ 		// Create a new module (and put it into the cache)
 /******/ 		var module = __webpack_module_cache__[moduleId] = {
@@ -118,6 +118,8 @@ console.log(getArray(1, 2, 3));
 
 
 ``` js
+var __webpack_exports__ = {};
+// This entry need to be wrapped in an IIFE because it need to be isolated against other modules in the chunk.
 (() => {
 /*!********************!*\
   !*** ./example.js ***!
@@ -137,25 +139,25 @@ console.log(__webpack_require__(/*! ./index */ 1));
 ## Unoptimized
 
 ```
-asset output.js 2.18 KiB [emitted] (name: main)
-chunk (runtime: main) output.js (main) 652 bytes [entry] [rendered]
+asset output.js 2.4 KiB [emitted] (name: main)
+chunk (runtime: main) output.js (main) 696 bytes [entry] [rendered]
   > ./example.js main
-  dependent modules 619 bytes [dependent] 1 module
+  dependent modules 663 bytes [dependent] 1 module
   ./example.js 33 bytes [built] [code generated]
     [used exports unknown]
     entry ./example.js main
-webpack 5.11.1 compiled successfully
+webpack 5.78.0 compiled successfully
 ```
 
 ## Production mode
 
 ```
-asset output.js 524 bytes [emitted] [minimized] (name: main)
-chunk (runtime: main) output.js (main) 652 bytes [entry] [rendered]
+asset output.js 553 bytes [emitted] [minimized] (name: main)
+chunk (runtime: main) output.js (main) 696 bytes [entry] [rendered]
   > ./example.js main
-  dependent modules 619 bytes [dependent] 1 module
+  dependent modules 663 bytes [dependent] 1 module
   ./example.js 33 bytes [built] [code generated]
     [no exports used]
     entry ./example.js main
-webpack 5.11.1 compiled successfully
+webpack 5.78.0 compiled successfully
 ```
diff --git a/examples/typescript/test.filter.js b/examples/typescript/test.filter.js
new file mode 100644
index 00000000000..41a5d11e5c6
--- /dev/null
+++ b/examples/typescript/test.filter.js
@@ -0,0 +1,5 @@
+var supportsOptionalChaining = require("../../test/helpers/supportsOptionalChaining");
+
+module.exports = function (config) {
+	return supportsOptionalChaining();
+};
diff --git a/examples/typescript/webpack.config.js b/examples/typescript/webpack.config.js
index e3d8ac4432d..b33a1ed24e6 100644
--- a/examples/typescript/webpack.config.js
+++ b/examples/typescript/webpack.config.js
@@ -2,9 +2,6 @@ const ForkTsCheckerWebpackPlugin = require("fork-ts-checker-webpack-plugin");
 
 module.exports = (env = "development") => ({
 	mode: env,
-	entry: {
-		output: "./index.ts"
-	},
 	module: {
 		rules: [
 			{
diff --git a/examples/wasm-bindgen-esm/README.md b/examples/wasm-bindgen-esm/README.md
new file mode 100644
index 00000000000..8d5e4c44a8a
--- /dev/null
+++ b/examples/wasm-bindgen-esm/README.md
@@ -0,0 +1,396 @@
+This is a simple example that shows the usage of an ES module packaging around a Rust module, built by wasm-pack.
+
+The ES module can be imported like other async modules with `import` or `import()`.
+When importing, the underlying WebAssembly module is downloaded and instantiated in a streaming way.
+
+# example.js
+
+```javascript
+import { greeting } from "./pkg";
+
+document.write(greeting('Bob'));
+```
+
+# dist/output.js
+
+```javascript
+/******/ (() => { // webpackBootstrap
+/******/ 	"use strict";
+/******/ 	var __webpack_modules__ = ([
+/* 0 */
+/*!********************!*\
+  !*** ./example.js ***!
+  \********************/
+/*! namespace exports */
+/*! exports [not provided] [no usage info] */
+/*! runtime requirements: __webpack_require__, __webpack_require__.r, __webpack_exports__, module, __webpack_require__.a, __webpack_require__.* */
+/***/ ((module, __webpack_exports__, __webpack_require__) => {
+
+__webpack_require__.a(module, async (__webpack_handle_async_dependencies__, __webpack_async_result__) => { try {
+__webpack_require__.r(__webpack_exports__);
+/* harmony import */ var _pkg__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./pkg */ 1);
+var __webpack_async_dependencies__ = __webpack_handle_async_dependencies__([_pkg__WEBPACK_IMPORTED_MODULE_0__]);
+_pkg__WEBPACK_IMPORTED_MODULE_0__ = (__webpack_async_dependencies__.then ? (await __webpack_async_dependencies__)() : __webpack_async_dependencies__)[0];
+
+
+document.write((0,_pkg__WEBPACK_IMPORTED_MODULE_0__.greeting)('Bob'));
+
+
+__webpack_async_result__();
+} catch(e) { __webpack_async_result__(e); } });
+
+/***/ }),
+/* 1 */
+/*!***************************!*\
+  !*** ./pkg/hi_wasm_bg.js ***!
+  \***************************/
+/*! namespace exports */
+/*! export greeting [provided] [no usage info] [missing usage info prevents renaming] */
+/*! other exports [not provided] [no usage info] */
+/*! runtime requirements: __webpack_require__, __webpack_require__.r, __webpack_exports__, module, __webpack_require__.a, __webpack_require__.d, __webpack_require__.* */
+/***/ ((__webpack_module__, __webpack_exports__, __webpack_require__) => {
+
+__webpack_require__.a(__webpack_module__, async (__webpack_handle_async_dependencies__, __webpack_async_result__) => { try {
+__webpack_require__.r(__webpack_exports__);
+/* harmony export */ __webpack_require__.d(__webpack_exports__, {
+/* harmony export */   greeting: () => (/* binding */ greeting)
+/* harmony export */ });
+/* harmony import */ var _hi_wasm_bg_wasm__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./hi_wasm_bg.wasm */ 2);
+var __webpack_async_dependencies__ = __webpack_handle_async_dependencies__([_hi_wasm_bg_wasm__WEBPACK_IMPORTED_MODULE_0__]);
+_hi_wasm_bg_wasm__WEBPACK_IMPORTED_MODULE_0__ = (__webpack_async_dependencies__.then ? (await __webpack_async_dependencies__)() : __webpack_async_dependencies__)[0];
+
+
+let WASM_VECTOR_LEN = 0;
+
+let cachegetUint8Memory0 = null;
+function getUint8Memory0() {
+    if (cachegetUint8Memory0 === null || cachegetUint8Memory0.buffer !== _hi_wasm_bg_wasm__WEBPACK_IMPORTED_MODULE_0__.memory.buffer) {
+        cachegetUint8Memory0 = new Uint8Array(_hi_wasm_bg_wasm__WEBPACK_IMPORTED_MODULE_0__.memory.buffer);
+    }
+    return cachegetUint8Memory0;
+}
+
+const lTextEncoder = typeof TextEncoder === 'undefined' ? (0, module.require)('util').TextEncoder : TextEncoder;
+
+let cachedTextEncoder = new lTextEncoder('utf-8');
+
+const encodeString = (typeof cachedTextEncoder.encodeInto === 'function'
+    ? function (arg, view) {
+    return cachedTextEncoder.encodeInto(arg, view);
+}
+    : function (arg, view) {
+    const buf = cachedTextEncoder.encode(arg);
+    view.set(buf);
+    return {
+        read: arg.length,
+        written: buf.length
+    };
+});
+
+function passStringToWasm0(arg, malloc, realloc) {
+
+    if (realloc === undefined) {
+        const buf = cachedTextEncoder.encode(arg);
+        const ptr = malloc(buf.length);
+        getUint8Memory0().subarray(ptr, ptr + buf.length).set(buf);
+        WASM_VECTOR_LEN = buf.length;
+        return ptr;
+    }
+
+    let len = arg.length;
+    let ptr = malloc(len);
+
+    const mem = getUint8Memory0();
+
+    let offset = 0;
+
+    for (; offset < len; offset++) {
+        const code = arg.charCodeAt(offset);
+        if (code > 0x7F) break;
+        mem[ptr + offset] = code;
+    }
+
+    if (offset !== len) {
+        if (offset !== 0) {
+            arg = arg.slice(offset);
+        }
+        ptr = realloc(ptr, len, len = offset + arg.length * 3);
+        const view = getUint8Memory0().subarray(ptr + offset, ptr + len);
+        const ret = encodeString(arg, view);
+
+        offset += ret.written;
+    }
+
+    WASM_VECTOR_LEN = offset;
+    return ptr;
+}
+
+let cachegetInt32Memory0 = null;
+function getInt32Memory0() {
+    if (cachegetInt32Memory0 === null || cachegetInt32Memory0.buffer !== _hi_wasm_bg_wasm__WEBPACK_IMPORTED_MODULE_0__.memory.buffer) {
+        cachegetInt32Memory0 = new Int32Array(_hi_wasm_bg_wasm__WEBPACK_IMPORTED_MODULE_0__.memory.buffer);
+    }
+    return cachegetInt32Memory0;
+}
+
+const lTextDecoder = typeof TextDecoder === 'undefined' ? (0, module.require)('util').TextDecoder : TextDecoder;
+
+let cachedTextDecoder = new lTextDecoder('utf-8', { ignoreBOM: true, fatal: true });
+
+cachedTextDecoder.decode();
+
+function getStringFromWasm0(ptr, len) {
+    return cachedTextDecoder.decode(getUint8Memory0().subarray(ptr, ptr + len));
+}
+/**
+* @param {string} name
+* @returns {string}
+*/
+function greeting(name) {
+    try {
+        const retptr = _hi_wasm_bg_wasm__WEBPACK_IMPORTED_MODULE_0__.__wbindgen_add_to_stack_pointer(-16);
+        var ptr0 = passStringToWasm0(name, _hi_wasm_bg_wasm__WEBPACK_IMPORTED_MODULE_0__.__wbindgen_malloc, _hi_wasm_bg_wasm__WEBPACK_IMPORTED_MODULE_0__.__wbindgen_realloc);
+        var len0 = WASM_VECTOR_LEN;
+        _hi_wasm_bg_wasm__WEBPACK_IMPORTED_MODULE_0__.greeting(retptr, ptr0, len0);
+        var r0 = getInt32Memory0()[retptr / 4 + 0];
+        var r1 = getInt32Memory0()[retptr / 4 + 1];
+        return getStringFromWasm0(r0, r1);
+    } finally {
+        _hi_wasm_bg_wasm__WEBPACK_IMPORTED_MODULE_0__.__wbindgen_add_to_stack_pointer(16);
+        _hi_wasm_bg_wasm__WEBPACK_IMPORTED_MODULE_0__.__wbindgen_free(r0, r1);
+    }
+}
+
+
+__webpack_async_result__();
+} catch(e) { __webpack_async_result__(e); } });
+
+/***/ }),
+/* 2 */
+/*!*****************************!*\
+  !*** ./pkg/hi_wasm_bg.wasm ***!
+  \*****************************/
+/*! namespace exports */
+/*! export __wbindgen_add_to_stack_pointer [provided] [no usage info] [provision prevents renaming (no use info)] */
+/*! export __wbindgen_free [provided] [no usage info] [provision prevents renaming (no use info)] */
+/*! export __wbindgen_malloc [provided] [no usage info] [provision prevents renaming (no use info)] */
+/*! export __wbindgen_realloc [provided] [no usage info] [provision prevents renaming (no use info)] */
+/*! export greeting [provided] [no usage info] [provision prevents renaming (no use info)] */
+/*! export memory [provided] [no usage info] [provision prevents renaming (no use info)] */
+/*! other exports [not provided] [no usage info] */
+/*! runtime requirements: module, module.id, __webpack_exports__, __webpack_require__.v, __webpack_require__.* */
+/***/ ((module, exports, __webpack_require__) => {
+
+module.exports = __webpack_require__.v(exports, module.id, "ffe21e855d11d22ab54f");
+
+/***/ })
+/******/ 	]);
+```
+
+
/* webpack runtime code */ + +``` js +/************************************************************************/ +/******/ // The module cache +/******/ var __webpack_module_cache__ = {}; +/******/ +/******/ // The require function +/******/ function __webpack_require__(moduleId) { +/******/ // Check if module is in cache +/******/ var cachedModule = __webpack_module_cache__[moduleId]; +/******/ if (cachedModule !== undefined) { +/******/ return cachedModule.exports; +/******/ } +/******/ // Create a new module (and put it into the cache) +/******/ var module = __webpack_module_cache__[moduleId] = { +/******/ id: moduleId, +/******/ // no module.loaded needed +/******/ exports: {} +/******/ }; +/******/ +/******/ // Execute the module function +/******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__); +/******/ +/******/ // Return the exports of the module +/******/ return module.exports; +/******/ } +/******/ +/************************************************************************/ +/******/ /* webpack/runtime/async module */ +/******/ (() => { +/******/ var webpackQueues = typeof Symbol === "function" ? Symbol("webpack queues") : "__webpack_queues__"; +/******/ var webpackExports = typeof Symbol === "function" ? Symbol("webpack exports") : "__webpack_exports__"; +/******/ var webpackError = typeof Symbol === "function" ? Symbol("webpack error") : "__webpack_error__"; +/******/ var resolveQueue = (queue) => { +/******/ if(queue && queue.d < 1) { +/******/ queue.d = 1; +/******/ queue.forEach((fn) => (fn.r--)); +/******/ queue.forEach((fn) => (fn.r-- ? fn.r++ : fn())); +/******/ } +/******/ } +/******/ var wrapDeps = (deps) => (deps.map((dep) => { +/******/ if(dep !== null && typeof dep === "object") { +/******/ if(dep[webpackQueues]) return dep; +/******/ if(dep.then) { +/******/ var queue = []; +/******/ queue.d = 0; +/******/ dep.then((r) => { +/******/ obj[webpackExports] = r; +/******/ resolveQueue(queue); +/******/ }, (e) => { +/******/ obj[webpackError] = e; +/******/ resolveQueue(queue); +/******/ }); +/******/ var obj = {}; +/******/ obj[webpackQueues] = (fn) => (fn(queue)); +/******/ return obj; +/******/ } +/******/ } +/******/ var ret = {}; +/******/ ret[webpackQueues] = x => {}; +/******/ ret[webpackExports] = dep; +/******/ return ret; +/******/ })); +/******/ __webpack_require__.a = (module, body, hasAwait) => { +/******/ var queue; +/******/ hasAwait && ((queue = []).d = -1); +/******/ var depQueues = new Set(); +/******/ var exports = module.exports; +/******/ var currentDeps; +/******/ var outerResolve; +/******/ var reject; +/******/ var promise = new Promise((resolve, rej) => { +/******/ reject = rej; +/******/ outerResolve = resolve; +/******/ }); +/******/ promise[webpackExports] = exports; +/******/ promise[webpackQueues] = (fn) => (queue && fn(queue), depQueues.forEach(fn), promise["catch"](x => {})); +/******/ module.exports = promise; +/******/ body((deps) => { +/******/ currentDeps = wrapDeps(deps); +/******/ var fn; +/******/ var getResult = () => (currentDeps.map((d) => { +/******/ if(d[webpackError]) throw d[webpackError]; +/******/ return d[webpackExports]; +/******/ })) +/******/ var promise = new Promise((resolve) => { +/******/ fn = () => (resolve(getResult)); +/******/ fn.r = 0; +/******/ var fnQueue = (q) => (q !== queue && !depQueues.has(q) && (depQueues.add(q), q && !q.d && (fn.r++, q.push(fn)))); +/******/ currentDeps.map((dep) => (dep[webpackQueues](fnQueue))); +/******/ }); +/******/ return fn.r ? promise : getResult(); +/******/ }, (err) => ((err ? reject(promise[webpackError] = err) : outerResolve(exports)), resolveQueue(queue))); +/******/ queue && queue.d < 0 && (queue.d = 0); +/******/ }; +/******/ })(); +/******/ +/******/ /* webpack/runtime/define property getters */ +/******/ (() => { +/******/ // define getter functions for harmony exports +/******/ __webpack_require__.d = (exports, definition) => { +/******/ for(var key in definition) { +/******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) { +/******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] }); +/******/ } +/******/ } +/******/ }; +/******/ })(); +/******/ +/******/ /* webpack/runtime/hasOwnProperty shorthand */ +/******/ (() => { +/******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop)) +/******/ })(); +/******/ +/******/ /* webpack/runtime/make namespace object */ +/******/ (() => { +/******/ // define __esModule on exports +/******/ __webpack_require__.r = (exports) => { +/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { +/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); +/******/ } +/******/ Object.defineProperty(exports, '__esModule', { value: true }); +/******/ }; +/******/ })(); +/******/ +/******/ /* webpack/runtime/wasm loading */ +/******/ (() => { +/******/ __webpack_require__.v = (exports, wasmModuleId, wasmModuleHash, importsObj) => { +/******/ var req = fetch(__webpack_require__.p + "" + wasmModuleHash + ".wasm"); +/******/ var fallback = () => (req +/******/ .then((x) => (x.arrayBuffer())) +/******/ .then((bytes) => (WebAssembly.instantiate(bytes, importsObj))) +/******/ .then((res) => (Object.assign(exports, res.instance.exports)))); +/******/ return req.then((res) => { +/******/ if (typeof WebAssembly.instantiateStreaming === "function") { +/******/ return WebAssembly.instantiateStreaming(res, importsObj) +/******/ .then( +/******/ (res) => (Object.assign(exports, res.instance.exports)), +/******/ (e) => { +/******/ if(res.headers.get("Content-Type") !== "application/wasm") { +/******/ console.warn("`WebAssembly.instantiateStreaming` failed because your server does not serve wasm with `application/wasm` MIME type. Falling back to `WebAssembly.instantiate` which is slower. Original error:\n", e); +/******/ return fallback(); +/******/ } +/******/ throw e; +/******/ } +/******/ ); +/******/ } +/******/ return fallback(); +/******/ }); +/******/ }; +/******/ })(); +/******/ +/******/ /* webpack/runtime/publicPath */ +/******/ (() => { +/******/ __webpack_require__.p = "dist/"; +/******/ })(); +/******/ +/************************************************************************/ +``` + +
+ +``` js +/******/ +/******/ // startup +/******/ // Load entry module and return exports +/******/ // This entry module used 'module' so it can't be inlined +/******/ var __webpack_exports__ = __webpack_require__(0); +/******/ +/******/ })() +; +``` + +# Info + +## Unoptimized + +``` +asset ffe21e855d11d22ab54f.wasm 14.8 KiB [emitted] [immutable] (auxiliary name: main) +asset output.js 13.4 KiB [emitted] (name: main) +chunk (runtime: main) output.js (main) 3.03 KiB (javascript) 14.8 KiB (webassembly) 3.68 KiB (runtime) [entry] [rendered] + > ./example.js main + runtime modules 3.68 KiB 6 modules + dependent modules 2.97 KiB (javascript) 14.8 KiB (webassembly) [dependent] 2 modules + ./example.js 69 bytes [built] [code generated] + [no exports] + [used exports unknown] + entry ./example.js main +webpack 5.90.0 compiled successfully +``` + +## Production mode + +``` +asset f7199313c1125f249cd6.wasm 14.8 KiB [emitted] [immutable] (auxiliary name: main) +asset output.js 3.41 KiB [emitted] [minimized] (name: main) +chunk (runtime: main) output.js (main) 3.03 KiB (javascript) 14.8 KiB (webassembly) 3.42 KiB (runtime) [entry] [rendered] + > ./example.js main + runtime modules 3.42 KiB 5 modules + dependent modules 2.97 KiB (javascript) 14.8 KiB (webassembly) [dependent] 2 modules + ./example.js 69 bytes [built] [code generated] + [no exports] + [no exports used] + entry ./example.js main +webpack 5.90.0 compiled successfully +``` diff --git a/examples/wasm-bindgen-esm/build.js b/examples/wasm-bindgen-esm/build.js new file mode 100644 index 00000000000..41c29c9d169 --- /dev/null +++ b/examples/wasm-bindgen-esm/build.js @@ -0,0 +1 @@ +require("../build-common"); \ No newline at end of file diff --git a/examples/wasm-bindgen-esm/example.js b/examples/wasm-bindgen-esm/example.js new file mode 100644 index 00000000000..f823d275465 --- /dev/null +++ b/examples/wasm-bindgen-esm/example.js @@ -0,0 +1,4 @@ +import { greeting } from "./pkg"; + +document.write(greeting('Bob')); + diff --git a/examples/wasm-bindgen-esm/index.html b/examples/wasm-bindgen-esm/index.html new file mode 100644 index 00000000000..d1fb49339c9 --- /dev/null +++ b/examples/wasm-bindgen-esm/index.html @@ -0,0 +1,5 @@ + + + + + diff --git a/examples/wasm-bindgen-esm/pkg/hi_wasm.d.ts b/examples/wasm-bindgen-esm/pkg/hi_wasm.d.ts new file mode 100644 index 00000000000..51bb2718d6d --- /dev/null +++ b/examples/wasm-bindgen-esm/pkg/hi_wasm.d.ts @@ -0,0 +1,7 @@ +/* tslint:disable */ +/* eslint-disable */ +/** +* @param {string} name +* @returns {string} +*/ +export function greeting(name: string): string; diff --git a/examples/wasm-bindgen-esm/pkg/hi_wasm.js b/examples/wasm-bindgen-esm/pkg/hi_wasm.js new file mode 100644 index 00000000000..ae789f18707 --- /dev/null +++ b/examples/wasm-bindgen-esm/pkg/hi_wasm.js @@ -0,0 +1,2 @@ +import * as wasm from "./hi_wasm_bg.wasm"; +export * from "./hi_wasm_bg.js"; \ No newline at end of file diff --git a/examples/wasm-bindgen-esm/pkg/hi_wasm_bg.js b/examples/wasm-bindgen-esm/pkg/hi_wasm_bg.js new file mode 100644 index 00000000000..71aef983bfc --- /dev/null +++ b/examples/wasm-bindgen-esm/pkg/hi_wasm_bg.js @@ -0,0 +1,103 @@ +import * as wasm from './hi_wasm_bg.wasm'; + +let WASM_VECTOR_LEN = 0; + +let cachegetUint8Memory0 = null; +function getUint8Memory0() { + if (cachegetUint8Memory0 === null || cachegetUint8Memory0.buffer !== wasm.memory.buffer) { + cachegetUint8Memory0 = new Uint8Array(wasm.memory.buffer); + } + return cachegetUint8Memory0; +} + +const lTextEncoder = typeof TextEncoder === 'undefined' ? (0, module.require)('util').TextEncoder : TextEncoder; + +let cachedTextEncoder = new lTextEncoder('utf-8'); + +const encodeString = (typeof cachedTextEncoder.encodeInto === 'function' + ? function (arg, view) { + return cachedTextEncoder.encodeInto(arg, view); +} + : function (arg, view) { + const buf = cachedTextEncoder.encode(arg); + view.set(buf); + return { + read: arg.length, + written: buf.length + }; +}); + +function passStringToWasm0(arg, malloc, realloc) { + + if (realloc === undefined) { + const buf = cachedTextEncoder.encode(arg); + const ptr = malloc(buf.length); + getUint8Memory0().subarray(ptr, ptr + buf.length).set(buf); + WASM_VECTOR_LEN = buf.length; + return ptr; + } + + let len = arg.length; + let ptr = malloc(len); + + const mem = getUint8Memory0(); + + let offset = 0; + + for (; offset < len; offset++) { + const code = arg.charCodeAt(offset); + if (code > 0x7F) break; + mem[ptr + offset] = code; + } + + if (offset !== len) { + if (offset !== 0) { + arg = arg.slice(offset); + } + ptr = realloc(ptr, len, len = offset + arg.length * 3); + const view = getUint8Memory0().subarray(ptr + offset, ptr + len); + const ret = encodeString(arg, view); + + offset += ret.written; + } + + WASM_VECTOR_LEN = offset; + return ptr; +} + +let cachegetInt32Memory0 = null; +function getInt32Memory0() { + if (cachegetInt32Memory0 === null || cachegetInt32Memory0.buffer !== wasm.memory.buffer) { + cachegetInt32Memory0 = new Int32Array(wasm.memory.buffer); + } + return cachegetInt32Memory0; +} + +const lTextDecoder = typeof TextDecoder === 'undefined' ? (0, module.require)('util').TextDecoder : TextDecoder; + +let cachedTextDecoder = new lTextDecoder('utf-8', { ignoreBOM: true, fatal: true }); + +cachedTextDecoder.decode(); + +function getStringFromWasm0(ptr, len) { + return cachedTextDecoder.decode(getUint8Memory0().subarray(ptr, ptr + len)); +} +/** +* @param {string} name +* @returns {string} +*/ +export function greeting(name) { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + var ptr0 = passStringToWasm0(name, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); + var len0 = WASM_VECTOR_LEN; + wasm.greeting(retptr, ptr0, len0); + var r0 = getInt32Memory0()[retptr / 4 + 0]; + var r1 = getInt32Memory0()[retptr / 4 + 1]; + return getStringFromWasm0(r0, r1); + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + wasm.__wbindgen_free(r0, r1); + } +} + diff --git a/examples/wasm-bindgen-esm/pkg/hi_wasm_bg.wasm b/examples/wasm-bindgen-esm/pkg/hi_wasm_bg.wasm new file mode 100644 index 00000000000..8f5af1057b5 Binary files /dev/null and b/examples/wasm-bindgen-esm/pkg/hi_wasm_bg.wasm differ diff --git a/examples/wasm-bindgen-esm/pkg/hi_wasm_bg.wasm.d.ts b/examples/wasm-bindgen-esm/pkg/hi_wasm_bg.wasm.d.ts new file mode 100644 index 00000000000..d430adaa653 --- /dev/null +++ b/examples/wasm-bindgen-esm/pkg/hi_wasm_bg.wasm.d.ts @@ -0,0 +1,8 @@ +/* tslint:disable */ +/* eslint-disable */ +export const memory: WebAssembly.Memory; +export function greeting(a: number, b: number, c: number): void; +export function __wbindgen_add_to_stack_pointer(a: number): number; +export function __wbindgen_malloc(a: number): number; +export function __wbindgen_realloc(a: number, b: number, c: number): number; +export function __wbindgen_free(a: number, b: number): void; diff --git a/examples/wasm-bindgen-esm/pkg/package.json b/examples/wasm-bindgen-esm/pkg/package.json new file mode 100644 index 00000000000..abdb287b0be --- /dev/null +++ b/examples/wasm-bindgen-esm/pkg/package.json @@ -0,0 +1,14 @@ +{ + "name": "hi-wasm", + "type": "module", + "version": "0.1.0", + "files": [ + "hi_wasm_bg.wasm", + "hi_wasm.js", + "hi_wasm_bg.js", + "hi_wasm.d.ts" + ], + "main": "hi_wasm.js", + "types": "hi_wasm.d.ts", + "sideEffects": false +} diff --git a/examples/wasm-bindgen-esm/template.md b/examples/wasm-bindgen-esm/template.md new file mode 100644 index 00000000000..3b1314621b1 --- /dev/null +++ b/examples/wasm-bindgen-esm/template.md @@ -0,0 +1,30 @@ +This is a simple example that shows the usage of an ES module packaging around a Rust module, built by wasm-pack. + +The ES module can be imported like other async modules with `import` or `import()`. +When importing, the underlying WebAssembly module is downloaded and instantiated in a streaming way. + +# example.js + +```javascript +_{{example.js}}_ +``` + +# dist/output.js + +```javascript +_{{dist/output.js}}_ +``` + +# Info + +## Unoptimized + +``` +_{{stdout}}_ +``` + +## Production mode + +``` +_{{production:stdout}}_ +``` diff --git a/examples/wasm-bindgen-esm/test.filter.js b/examples/wasm-bindgen-esm/test.filter.js new file mode 100644 index 00000000000..9872d9c87dd --- /dev/null +++ b/examples/wasm-bindgen-esm/test.filter.js @@ -0,0 +1,5 @@ +var supportsWebAssembly = require("../../test/helpers/supportsWebAssembly"); + +module.exports = function(config) { + return supportsWebAssembly(); +}; diff --git a/examples/wasm-bindgen-esm/webpack.config.js b/examples/wasm-bindgen-esm/webpack.config.js new file mode 100644 index 00000000000..70ba131d8c3 --- /dev/null +++ b/examples/wasm-bindgen-esm/webpack.config.js @@ -0,0 +1,21 @@ +module.exports = { + // mode: "development || "production", + output: { + webassemblyModuleFilename: "[hash].wasm", + publicPath: "dist/" + }, + module: { + rules: [ + { + test: /\.wasm$/, + type: "webassembly/async" + } + ] + }, + optimization: { + chunkIds: "deterministic" // To keep filename consistent between different modes (for example building only) + }, + experiments: { + asyncWebAssembly: true + } +}; diff --git a/examples/wasm-complex/README.md b/examples/wasm-complex/README.md index c492fa4d248..1ee4a1db3d9 100644 --- a/examples/wasm-complex/README.md +++ b/examples/wasm-complex/README.md @@ -79,13 +79,14 @@ export const memory = await getMemoryFromParentInWorker(); \********************/ /*! namespace exports */ /*! exports [not provided] [no usage info] */ -/*! runtime requirements: __webpack_require__, __webpack_require__.r, __webpack_exports__, module, __webpack_require__.* */ +/*! runtime requirements: __webpack_require__, __webpack_require__.r, __webpack_exports__, module, __webpack_require__.a, __webpack_require__.* */ /***/ ((module, __webpack_exports__, __webpack_require__) => { -module.exports = (async () => { +__webpack_require__.a(module, async (__webpack_handle_async_dependencies__, __webpack_async_result__) => { try { __webpack_require__.r(__webpack_exports__); /* harmony import */ var _magic_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./magic.js */ 1); -_magic_js__WEBPACK_IMPORTED_MODULE_0__ = await Promise.resolve(_magic_js__WEBPACK_IMPORTED_MODULE_0__); +var __webpack_async_dependencies__ = __webpack_handle_async_dependencies__([_magic_js__WEBPACK_IMPORTED_MODULE_0__]); +_magic_js__WEBPACK_IMPORTED_MODULE_0__ = (__webpack_async_dependencies__.then ? (await __webpack_async_dependencies__)() : __webpack_async_dependencies__)[0]; // accessing memory @@ -100,8 +101,8 @@ console.log((0,_magic_js__WEBPACK_IMPORTED_MODULE_0__.getNumber)()); console.log((0,_magic_js__WEBPACK_IMPORTED_MODULE_0__.getNumber)()); console.log((0,_magic_js__WEBPACK_IMPORTED_MODULE_0__.getNumber)()); -return __webpack_exports__; -})(); +__webpack_async_result__(); +} catch(e) { __webpack_async_result__(e); } }); /***/ }), /* 1 */ @@ -113,23 +114,24 @@ return __webpack_exports__; /*! export getNumber [provided] [no usage info] [missing usage info prevents renaming] -> ./magic.wat .getNumber */ /*! export set [provided] [no usage info] [missing usage info prevents renaming] -> ./magic.wat .set */ /*! other exports [not provided] [no usage info] */ -/*! runtime requirements: __webpack_require__, __webpack_exports__, __webpack_require__.d, __webpack_require__.r, module, __webpack_require__.* */ +/*! runtime requirements: __webpack_require__, __webpack_exports__, __webpack_require__.d, __webpack_require__.r, module, __webpack_require__.a, __webpack_require__.* */ /***/ ((module, __webpack_exports__, __webpack_require__) => { -module.exports = (async () => { +__webpack_require__.a(module, async (__webpack_handle_async_dependencies__, __webpack_async_result__) => { try { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "get": () => /* reexport safe */ _magic_wat__WEBPACK_IMPORTED_MODULE_0__.get, -/* harmony export */ "getNumber": () => /* reexport safe */ _magic_wat__WEBPACK_IMPORTED_MODULE_0__.getNumber, -/* harmony export */ "set": () => /* reexport safe */ _magic_wat__WEBPACK_IMPORTED_MODULE_0__.set +/* harmony export */ get: () => (/* reexport safe */ _magic_wat__WEBPACK_IMPORTED_MODULE_0__.get), +/* harmony export */ getNumber: () => (/* reexport safe */ _magic_wat__WEBPACK_IMPORTED_MODULE_0__.getNumber), +/* harmony export */ set: () => (/* reexport safe */ _magic_wat__WEBPACK_IMPORTED_MODULE_0__.set) /* harmony export */ }); /* harmony import */ var _magic_wat__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./magic.wat */ 2); -_magic_wat__WEBPACK_IMPORTED_MODULE_0__ = await Promise.resolve(_magic_wat__WEBPACK_IMPORTED_MODULE_0__); +var __webpack_async_dependencies__ = __webpack_handle_async_dependencies__([_magic_wat__WEBPACK_IMPORTED_MODULE_0__]); +_magic_wat__WEBPACK_IMPORTED_MODULE_0__ = (__webpack_async_dependencies__.then ? (await __webpack_async_dependencies__)() : __webpack_async_dependencies__)[0]; // reexporting -return __webpack_exports__; -})(); +__webpack_async_result__(); +} catch(e) { __webpack_async_result__(e); } }); /***/ }), /* 2 */ @@ -141,13 +143,11 @@ return __webpack_exports__; /*! export getNumber [provided] [no usage info] [provision prevents renaming (no use info)] */ /*! export set [provided] [no usage info] [provision prevents renaming (no use info)] */ /*! other exports [not provided] [no usage info] */ -/*! runtime requirements: module, module.id, __webpack_exports__, __webpack_require__.v, __webpack_require__, __webpack_require__.* */ +/*! runtime requirements: module, module.id, __webpack_exports__, __webpack_require__.v, __webpack_require__, __webpack_require__.a, __webpack_require__.* */ /***/ ((module, exports, __webpack_require__) => { -/* harmony import */ var WEBPACK_IMPORTED_MODULE_0 = __webpack_require__(/*! ./memory.js */ 3); -/* harmony import */ var WEBPACK_IMPORTED_MODULE_1 = __webpack_require__(/*! ./magic-number.js */ 4); -module.exports = Promise.resolve(WEBPACK_IMPORTED_MODULE_0).then((WEBPACK_IMPORTED_MODULE_0) => { - return __webpack_require__.v(exports, module.id, "1b1e6d7ce8287ca318ae", { +var __webpack_instantiate__ = ([WEBPACK_IMPORTED_MODULE_0]) => { + return __webpack_require__.v(exports, module.id, "daa529a2a650ee3943a9", { "./memory.js": { "memory": WEBPACK_IMPORTED_MODULE_0.memory }, @@ -155,7 +155,24 @@ module.exports = Promise.resolve(WEBPACK_IMPORTED_MODULE_0).then((WEBPACK_IMPORT "getRandomNumber": WEBPACK_IMPORTED_MODULE_1.getRandomNumber } }); -}) +} +__webpack_require__.a(module, async (__webpack_handle_async_dependencies__, __webpack_async_result__) => { + try { + /* harmony import */ var WEBPACK_IMPORTED_MODULE_0 = __webpack_require__(/*! ./memory.js */ 3); + /* harmony import */ var WEBPACK_IMPORTED_MODULE_1 = __webpack_require__(/*! ./magic-number.js */ 4); + var __webpack_async_dependencies__ = __webpack_handle_async_dependencies__([WEBPACK_IMPORTED_MODULE_0]); + var [WEBPACK_IMPORTED_MODULE_0] = __webpack_async_dependencies__.then ? (await __webpack_async_dependencies__)() : __webpack_async_dependencies__; + await __webpack_require__.v(exports, module.id, "daa529a2a650ee3943a9", { + "./memory.js": { + "memory": WEBPACK_IMPORTED_MODULE_0.memory + }, + "./magic-number.js": { + "getRandomNumber": WEBPACK_IMPORTED_MODULE_1.getRandomNumber + } + }); + __webpack_async_result__(); + } catch(e) { __webpack_async_result__(e); } +}, 1); /***/ }), /* 3 */ @@ -165,13 +182,13 @@ module.exports = Promise.resolve(WEBPACK_IMPORTED_MODULE_0).then((WEBPACK_IMPORT /*! namespace exports */ /*! export memory [provided] [no usage info] [missing usage info prevents renaming] */ /*! other exports [not provided] [no usage info] */ -/*! runtime requirements: __webpack_require__.r, __webpack_exports__, module, __webpack_require__.d, __webpack_require__.* */ +/*! runtime requirements: __webpack_require__.r, __webpack_exports__, module, __webpack_require__.a, __webpack_require__.d, __webpack_require__.* */ /***/ ((module, __webpack_exports__, __webpack_require__) => { -module.exports = (async () => { +__webpack_require__.a(module, async (__webpack_handle_async_dependencies__, __webpack_async_result__) => { try { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "memory": () => /* binding */ memory +/* harmony export */ memory: () => (/* binding */ memory) /* harmony export */ }); async function getMemoryFromParentInWorker() { await new Promise(r => setTimeout(r, 200)); @@ -181,8 +198,8 @@ async function getMemoryFromParentInWorker() { const memory = await getMemoryFromParentInWorker(); -return __webpack_exports__; -})(); +__webpack_async_result__(); +} catch(e) { __webpack_async_result__(e); } }, 1); /***/ }), /* 4 */ @@ -198,8 +215,8 @@ return __webpack_exports__; __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "getNumber": () => /* binding */ getNumber, -/* harmony export */ "getRandomNumber": () => /* binding */ getRandomNumber +/* harmony export */ getNumber: () => (/* binding */ getNumber), +/* harmony export */ getRandomNumber: () => (/* binding */ getRandomNumber) /* harmony export */ }); function getNumber() { return 42; @@ -224,8 +241,9 @@ function getRandomNumber() { /******/ // The require function /******/ function __webpack_require__(moduleId) { /******/ // Check if module is in cache -/******/ if(__webpack_module_cache__[moduleId]) { -/******/ return __webpack_module_cache__[moduleId].exports; +/******/ var cachedModule = __webpack_module_cache__[moduleId]; +/******/ if (cachedModule !== undefined) { +/******/ return cachedModule.exports; /******/ } /******/ // Create a new module (and put it into the cache) /******/ var module = __webpack_module_cache__[moduleId] = { @@ -242,6 +260,75 @@ function getRandomNumber() { /******/ } /******/ /************************************************************************/ +/******/ /* webpack/runtime/async module */ +/******/ (() => { +/******/ var webpackQueues = typeof Symbol === "function" ? Symbol("webpack queues") : "__webpack_queues__"; +/******/ var webpackExports = typeof Symbol === "function" ? Symbol("webpack exports") : "__webpack_exports__"; +/******/ var webpackError = typeof Symbol === "function" ? Symbol("webpack error") : "__webpack_error__"; +/******/ var resolveQueue = (queue) => { +/******/ if(queue && queue.d < 1) { +/******/ queue.d = 1; +/******/ queue.forEach((fn) => (fn.r--)); +/******/ queue.forEach((fn) => (fn.r-- ? fn.r++ : fn())); +/******/ } +/******/ } +/******/ var wrapDeps = (deps) => (deps.map((dep) => { +/******/ if(dep !== null && typeof dep === "object") { +/******/ if(dep[webpackQueues]) return dep; +/******/ if(dep.then) { +/******/ var queue = []; +/******/ queue.d = 0; +/******/ dep.then((r) => { +/******/ obj[webpackExports] = r; +/******/ resolveQueue(queue); +/******/ }, (e) => { +/******/ obj[webpackError] = e; +/******/ resolveQueue(queue); +/******/ }); +/******/ var obj = {}; +/******/ obj[webpackQueues] = (fn) => (fn(queue)); +/******/ return obj; +/******/ } +/******/ } +/******/ var ret = {}; +/******/ ret[webpackQueues] = x => {}; +/******/ ret[webpackExports] = dep; +/******/ return ret; +/******/ })); +/******/ __webpack_require__.a = (module, body, hasAwait) => { +/******/ var queue; +/******/ hasAwait && ((queue = []).d = -1); +/******/ var depQueues = new Set(); +/******/ var exports = module.exports; +/******/ var currentDeps; +/******/ var outerResolve; +/******/ var reject; +/******/ var promise = new Promise((resolve, rej) => { +/******/ reject = rej; +/******/ outerResolve = resolve; +/******/ }); +/******/ promise[webpackExports] = exports; +/******/ promise[webpackQueues] = (fn) => (queue && fn(queue), depQueues.forEach(fn), promise["catch"](x => {})); +/******/ module.exports = promise; +/******/ body((deps) => { +/******/ currentDeps = wrapDeps(deps); +/******/ var fn; +/******/ var getResult = () => (currentDeps.map((d) => { +/******/ if(d[webpackError]) throw d[webpackError]; +/******/ return d[webpackExports]; +/******/ })) +/******/ var promise = new Promise((resolve) => { +/******/ fn = () => (resolve(getResult)); +/******/ fn.r = 0; +/******/ var fnQueue = (q) => (q !== queue && !depQueues.has(q) && (depQueues.add(q), q && !q.d && (fn.r++, q.push(fn)))); +/******/ currentDeps.map((dep) => (dep[webpackQueues](fnQueue))); +/******/ }); +/******/ return fn.r ? promise : getResult(); +/******/ }, (err) => ((err ? reject(promise[webpackError] = err) : outerResolve(exports)), resolveQueue(queue))); +/******/ queue && queue.d < 0 && (queue.d = 0); +/******/ }; +/******/ })(); +/******/ /******/ /* webpack/runtime/define property getters */ /******/ (() => { /******/ // define getter functions for harmony exports @@ -256,7 +343,7 @@ function getRandomNumber() { /******/ /******/ /* webpack/runtime/hasOwnProperty shorthand */ /******/ (() => { -/******/ __webpack_require__.o = (obj, prop) => Object.prototype.hasOwnProperty.call(obj, prop) +/******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop)) /******/ })(); /******/ /******/ /* webpack/runtime/make namespace object */ @@ -270,36 +357,50 @@ function getRandomNumber() { /******/ }; /******/ })(); /******/ -/******/ /* webpack/runtime/publicPath */ -/******/ (() => { -/******/ __webpack_require__.p = "dist/"; -/******/ })(); -/******/ -/******/ /* webpack/runtime/wasm chunk loading */ +/******/ /* webpack/runtime/wasm loading */ /******/ (() => { /******/ __webpack_require__.v = (exports, wasmModuleId, wasmModuleHash, importsObj) => { /******/ var req = fetch(__webpack_require__.p + "" + wasmModuleHash + ".module.wasm"); -/******/ if (typeof WebAssembly.instantiateStreaming === 'function') { -/******/ return WebAssembly.instantiateStreaming(req, importsObj) -/******/ .then((res) => Object.assign(exports, res.instance.exports)); -/******/ } -/******/ return req -/******/ .then((x) => x.arrayBuffer()) -/******/ .then((bytes) => WebAssembly.instantiate(bytes, importsObj)) -/******/ .then((res) => Object.assign(exports, res.instance.exports)); +/******/ var fallback = () => (req +/******/ .then((x) => (x.arrayBuffer())) +/******/ .then((bytes) => (WebAssembly.instantiate(bytes, importsObj))) +/******/ .then((res) => (Object.assign(exports, res.instance.exports)))); +/******/ return req.then((res) => { +/******/ if (typeof WebAssembly.instantiateStreaming === "function") { +/******/ return WebAssembly.instantiateStreaming(res, importsObj) +/******/ .then( +/******/ (res) => (Object.assign(exports, res.instance.exports)), +/******/ (e) => { +/******/ if(res.headers.get("Content-Type") !== "application/wasm") { +/******/ console.warn("`WebAssembly.instantiateStreaming` failed because your server does not serve wasm with `application/wasm` MIME type. Falling back to `WebAssembly.instantiate` which is slower. Original error:\n", e); +/******/ return fallback(); +/******/ } +/******/ throw e; +/******/ } +/******/ ); +/******/ } +/******/ return fallback(); +/******/ }); /******/ }; /******/ })(); /******/ +/******/ /* webpack/runtime/publicPath */ +/******/ (() => { +/******/ __webpack_require__.p = "dist/"; +/******/ })(); +/******/ /************************************************************************/ ``` ``` js +/******/ /******/ // startup -/******/ // Load entry module -/******/ __webpack_require__(0); +/******/ // Load entry module and return exports /******/ // This entry module used 'module' so it can't be inlined +/******/ var __webpack_exports__ = __webpack_require__(0); +/******/ /******/ })() ; ``` @@ -309,31 +410,31 @@ function getRandomNumber() { ## Unoptimized ``` -asset output.js 8.87 KiB [emitted] (name: main) -asset 1b1e6d7ce8287ca318ae.module.wasm 139 bytes [emitted] [immutable] (auxiliary name: main) -chunk (runtime: main) output.js (main) 696 bytes (javascript) 139 bytes (webassembly) 1.2 KiB (runtime) [entry] [rendered] +asset output.js 13.8 KiB [emitted] (name: main) +asset daa529a2a650ee3943a9.module.wasm 139 bytes [emitted] [immutable] (auxiliary name: main) +chunk (runtime: main) output.js (main) 696 bytes (javascript) 139 bytes (webassembly) 3.69 KiB (runtime) [entry] [rendered] > ./example.js main - runtime modules 1.2 KiB 5 modules + runtime modules 3.69 KiB 6 modules dependent modules 449 bytes (javascript) 139 bytes (webassembly) [dependent] 4 modules ./example.js 247 bytes [built] [code generated] [no exports] [used exports unknown] entry ./example.js main -webpack 5.11.1 compiled successfully +webpack 5.90.0 compiled successfully ``` ## Production mode ``` -asset output.js 1.44 KiB [emitted] [minimized] (name: main) -asset f5764885c32853f144a2.module.wasm 139 bytes [emitted] [immutable] (auxiliary name: main) -chunk (runtime: main) output.js (main) 696 bytes (javascript) 139 bytes (webassembly) 950 bytes (runtime) [entry] [rendered] +asset output.js 2.81 KiB [emitted] [minimized] (name: main) +asset 05aa07f6a3836ded50d1.module.wasm 139 bytes [emitted] [immutable] (auxiliary name: main) +chunk (runtime: main) output.js (main) 696 bytes (javascript) 139 bytes (webassembly) 3.42 KiB (runtime) [entry] [rendered] > ./example.js main + runtime modules 3.42 KiB 5 modules dependent modules 449 bytes (javascript) 139 bytes (webassembly) [dependent] 4 modules - runtime modules 950 bytes 4 modules ./example.js 247 bytes [built] [code generated] [no exports] [no exports used] entry ./example.js main -webpack 5.11.1 compiled successfully +webpack 5.90.0 compiled successfully ``` diff --git a/examples/wasm-complex/webpack.config.js b/examples/wasm-complex/webpack.config.js index ee188b60683..13de5cdac2f 100644 --- a/examples/wasm-complex/webpack.config.js +++ b/examples/wasm-complex/webpack.config.js @@ -1,5 +1,5 @@ module.exports = { - // mode: "development || "production", + // mode: "development" || "production", output: { publicPath: "dist/" }, diff --git a/examples/wasm-simple/README.md b/examples/wasm-simple/README.md index f373060b254..38a49528e1f 100644 --- a/examples/wasm-simple/README.md +++ b/examples/wasm-simple/README.md @@ -68,14 +68,15 @@ export function fibonacciJavascript(i) { \********************/ /*! namespace exports */ /*! exports [not provided] [no usage info] */ -/*! runtime requirements: __webpack_require__, __webpack_require__.r, __webpack_exports__, module, __webpack_require__.* */ +/*! runtime requirements: __webpack_require__, __webpack_require__.r, __webpack_exports__, module, __webpack_require__.a, __webpack_require__.* */ /***/ ((module, __webpack_exports__, __webpack_require__) => { -module.exports = (async () => { +__webpack_require__.a(module, async (__webpack_handle_async_dependencies__, __webpack_async_result__) => { try { __webpack_require__.r(__webpack_exports__); /* harmony import */ var _add_wasm__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./add.wasm */ 1); /* harmony import */ var _math__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./math */ 2); -([_math__WEBPACK_IMPORTED_MODULE_1__, _add_wasm__WEBPACK_IMPORTED_MODULE_0__] = await Promise.all([_math__WEBPACK_IMPORTED_MODULE_1__, _add_wasm__WEBPACK_IMPORTED_MODULE_0__])); +var __webpack_async_dependencies__ = __webpack_handle_async_dependencies__([_add_wasm__WEBPACK_IMPORTED_MODULE_0__, _math__WEBPACK_IMPORTED_MODULE_1__]); +([_add_wasm__WEBPACK_IMPORTED_MODULE_0__, _math__WEBPACK_IMPORTED_MODULE_1__] = __webpack_async_dependencies__.then ? (await __webpack_async_dependencies__)() : __webpack_async_dependencies__); @@ -99,8 +100,8 @@ function timed(name, fn) { console.timeEnd(name); } -return __webpack_exports__; -})(); +__webpack_async_result__(); +} catch(e) { __webpack_async_result__(e); } }); /***/ }), /* 1 */ @@ -113,7 +114,7 @@ return __webpack_exports__; /*! runtime requirements: module, module.id, __webpack_exports__, __webpack_require__.v, __webpack_require__.* */ /***/ ((module, exports, __webpack_require__) => { -module.exports = __webpack_require__.v(exports, module.id, "a7a690138d8dd16930b3") +module.exports = __webpack_require__.v(exports, module.id, "0eaeab8b9fa3cef100d1"); /***/ }), /* 2 */ @@ -127,22 +128,23 @@ module.exports = __webpack_require__.v(exports, module.id, "a7a690138d8dd16930b3 /*! export fibonacci [provided] [no usage info] [missing usage info prevents renaming] -> ./fibonacci.wasm .fibonacci */ /*! export fibonacciJavascript [provided] [no usage info] [missing usage info prevents renaming] */ /*! other exports [not provided] [no usage info] */ -/*! runtime requirements: __webpack_require__, __webpack_exports__, __webpack_require__.d, __webpack_require__.r, module, __webpack_require__.* */ +/*! runtime requirements: __webpack_require__, __webpack_exports__, __webpack_require__.d, __webpack_require__.r, module, __webpack_require__.a, __webpack_require__.* */ /***/ ((module, __webpack_exports__, __webpack_require__) => { -module.exports = (async () => { +__webpack_require__.a(module, async (__webpack_handle_async_dependencies__, __webpack_async_result__) => { try { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "add": () => /* reexport safe */ _add_wasm__WEBPACK_IMPORTED_MODULE_0__.add, -/* harmony export */ "factorial": () => /* reexport safe */ _factorial_wasm__WEBPACK_IMPORTED_MODULE_1__.factorial, -/* harmony export */ "fibonacci": () => /* reexport safe */ _fibonacci_wasm__WEBPACK_IMPORTED_MODULE_2__.fibonacci, -/* harmony export */ "factorialJavascript": () => /* binding */ factorialJavascript, -/* harmony export */ "fibonacciJavascript": () => /* binding */ fibonacciJavascript +/* harmony export */ add: () => (/* reexport safe */ _add_wasm__WEBPACK_IMPORTED_MODULE_0__.add), +/* harmony export */ factorial: () => (/* reexport safe */ _factorial_wasm__WEBPACK_IMPORTED_MODULE_1__.factorial), +/* harmony export */ factorialJavascript: () => (/* binding */ factorialJavascript), +/* harmony export */ fibonacci: () => (/* reexport safe */ _fibonacci_wasm__WEBPACK_IMPORTED_MODULE_2__.fibonacci), +/* harmony export */ fibonacciJavascript: () => (/* binding */ fibonacciJavascript) /* harmony export */ }); /* harmony import */ var _add_wasm__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./add.wasm */ 1); /* harmony import */ var _factorial_wasm__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./factorial.wasm */ 3); /* harmony import */ var _fibonacci_wasm__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./fibonacci.wasm */ 4); -([_fibonacci_wasm__WEBPACK_IMPORTED_MODULE_2__, _factorial_wasm__WEBPACK_IMPORTED_MODULE_1__, _add_wasm__WEBPACK_IMPORTED_MODULE_0__] = await Promise.all([_fibonacci_wasm__WEBPACK_IMPORTED_MODULE_2__, _factorial_wasm__WEBPACK_IMPORTED_MODULE_1__, _add_wasm__WEBPACK_IMPORTED_MODULE_0__])); +var __webpack_async_dependencies__ = __webpack_handle_async_dependencies__([_add_wasm__WEBPACK_IMPORTED_MODULE_0__, _factorial_wasm__WEBPACK_IMPORTED_MODULE_1__, _fibonacci_wasm__WEBPACK_IMPORTED_MODULE_2__]); +([_add_wasm__WEBPACK_IMPORTED_MODULE_0__, _factorial_wasm__WEBPACK_IMPORTED_MODULE_1__, _fibonacci_wasm__WEBPACK_IMPORTED_MODULE_2__] = __webpack_async_dependencies__.then ? (await __webpack_async_dependencies__)() : __webpack_async_dependencies__); @@ -159,8 +161,8 @@ function fibonacciJavascript(i) { return fibonacciJavascript(i - 1) + fibonacciJavascript(i - 2); } -return __webpack_exports__; -})(); +__webpack_async_result__(); +} catch(e) { __webpack_async_result__(e); } }); /***/ }), /* 3 */ @@ -173,7 +175,7 @@ return __webpack_exports__; /*! runtime requirements: module, module.id, __webpack_exports__, __webpack_require__.v, __webpack_require__.* */ /***/ ((module, exports, __webpack_require__) => { -module.exports = __webpack_require__.v(exports, module.id, "9d2b0c46ef31acbcf414") +module.exports = __webpack_require__.v(exports, module.id, "35a58b7c95860d720a3c"); /***/ }), /* 4 */ @@ -186,7 +188,7 @@ module.exports = __webpack_require__.v(exports, module.id, "9d2b0c46ef31acbcf414 /*! runtime requirements: module, module.id, __webpack_exports__, __webpack_require__.v, __webpack_require__.* */ /***/ ((module, exports, __webpack_require__) => { -module.exports = __webpack_require__.v(exports, module.id, "0925a077f3cf38995044") +module.exports = __webpack_require__.v(exports, module.id, "5a6637e8d63cdf9c72da"); /***/ }) /******/ ]); @@ -202,8 +204,9 @@ module.exports = __webpack_require__.v(exports, module.id, "0925a077f3cf38995044 /******/ // The require function /******/ function __webpack_require__(moduleId) { /******/ // Check if module is in cache -/******/ if(__webpack_module_cache__[moduleId]) { -/******/ return __webpack_module_cache__[moduleId].exports; +/******/ var cachedModule = __webpack_module_cache__[moduleId]; +/******/ if (cachedModule !== undefined) { +/******/ return cachedModule.exports; /******/ } /******/ // Create a new module (and put it into the cache) /******/ var module = __webpack_module_cache__[moduleId] = { @@ -220,6 +223,75 @@ module.exports = __webpack_require__.v(exports, module.id, "0925a077f3cf38995044 /******/ } /******/ /************************************************************************/ +/******/ /* webpack/runtime/async module */ +/******/ (() => { +/******/ var webpackQueues = typeof Symbol === "function" ? Symbol("webpack queues") : "__webpack_queues__"; +/******/ var webpackExports = typeof Symbol === "function" ? Symbol("webpack exports") : "__webpack_exports__"; +/******/ var webpackError = typeof Symbol === "function" ? Symbol("webpack error") : "__webpack_error__"; +/******/ var resolveQueue = (queue) => { +/******/ if(queue && queue.d < 1) { +/******/ queue.d = 1; +/******/ queue.forEach((fn) => (fn.r--)); +/******/ queue.forEach((fn) => (fn.r-- ? fn.r++ : fn())); +/******/ } +/******/ } +/******/ var wrapDeps = (deps) => (deps.map((dep) => { +/******/ if(dep !== null && typeof dep === "object") { +/******/ if(dep[webpackQueues]) return dep; +/******/ if(dep.then) { +/******/ var queue = []; +/******/ queue.d = 0; +/******/ dep.then((r) => { +/******/ obj[webpackExports] = r; +/******/ resolveQueue(queue); +/******/ }, (e) => { +/******/ obj[webpackError] = e; +/******/ resolveQueue(queue); +/******/ }); +/******/ var obj = {}; +/******/ obj[webpackQueues] = (fn) => (fn(queue)); +/******/ return obj; +/******/ } +/******/ } +/******/ var ret = {}; +/******/ ret[webpackQueues] = x => {}; +/******/ ret[webpackExports] = dep; +/******/ return ret; +/******/ })); +/******/ __webpack_require__.a = (module, body, hasAwait) => { +/******/ var queue; +/******/ hasAwait && ((queue = []).d = -1); +/******/ var depQueues = new Set(); +/******/ var exports = module.exports; +/******/ var currentDeps; +/******/ var outerResolve; +/******/ var reject; +/******/ var promise = new Promise((resolve, rej) => { +/******/ reject = rej; +/******/ outerResolve = resolve; +/******/ }); +/******/ promise[webpackExports] = exports; +/******/ promise[webpackQueues] = (fn) => (queue && fn(queue), depQueues.forEach(fn), promise["catch"](x => {})); +/******/ module.exports = promise; +/******/ body((deps) => { +/******/ currentDeps = wrapDeps(deps); +/******/ var fn; +/******/ var getResult = () => (currentDeps.map((d) => { +/******/ if(d[webpackError]) throw d[webpackError]; +/******/ return d[webpackExports]; +/******/ })) +/******/ var promise = new Promise((resolve) => { +/******/ fn = () => (resolve(getResult)); +/******/ fn.r = 0; +/******/ var fnQueue = (q) => (q !== queue && !depQueues.has(q) && (depQueues.add(q), q && !q.d && (fn.r++, q.push(fn)))); +/******/ currentDeps.map((dep) => (dep[webpackQueues](fnQueue))); +/******/ }); +/******/ return fn.r ? promise : getResult(); +/******/ }, (err) => ((err ? reject(promise[webpackError] = err) : outerResolve(exports)), resolveQueue(queue))); +/******/ queue && queue.d < 0 && (queue.d = 0); +/******/ }; +/******/ })(); +/******/ /******/ /* webpack/runtime/define property getters */ /******/ (() => { /******/ // define getter functions for harmony exports @@ -234,7 +306,7 @@ module.exports = __webpack_require__.v(exports, module.id, "0925a077f3cf38995044 /******/ /******/ /* webpack/runtime/hasOwnProperty shorthand */ /******/ (() => { -/******/ __webpack_require__.o = (obj, prop) => Object.prototype.hasOwnProperty.call(obj, prop) +/******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop)) /******/ })(); /******/ /******/ /* webpack/runtime/make namespace object */ @@ -248,36 +320,50 @@ module.exports = __webpack_require__.v(exports, module.id, "0925a077f3cf38995044 /******/ }; /******/ })(); /******/ -/******/ /* webpack/runtime/publicPath */ -/******/ (() => { -/******/ __webpack_require__.p = "dist/"; -/******/ })(); -/******/ -/******/ /* webpack/runtime/wasm chunk loading */ +/******/ /* webpack/runtime/wasm loading */ /******/ (() => { /******/ __webpack_require__.v = (exports, wasmModuleId, wasmModuleHash, importsObj) => { /******/ var req = fetch(__webpack_require__.p + "" + wasmModuleHash + ".wasm"); -/******/ if (typeof WebAssembly.instantiateStreaming === 'function') { -/******/ return WebAssembly.instantiateStreaming(req, importsObj) -/******/ .then((res) => Object.assign(exports, res.instance.exports)); -/******/ } -/******/ return req -/******/ .then((x) => x.arrayBuffer()) -/******/ .then((bytes) => WebAssembly.instantiate(bytes, importsObj)) -/******/ .then((res) => Object.assign(exports, res.instance.exports)); +/******/ var fallback = () => (req +/******/ .then((x) => (x.arrayBuffer())) +/******/ .then((bytes) => (WebAssembly.instantiate(bytes, importsObj))) +/******/ .then((res) => (Object.assign(exports, res.instance.exports)))); +/******/ return req.then((res) => { +/******/ if (typeof WebAssembly.instantiateStreaming === "function") { +/******/ return WebAssembly.instantiateStreaming(res, importsObj) +/******/ .then( +/******/ (res) => (Object.assign(exports, res.instance.exports)), +/******/ (e) => { +/******/ if(res.headers.get("Content-Type") !== "application/wasm") { +/******/ console.warn("`WebAssembly.instantiateStreaming` failed because your server does not serve wasm with `application/wasm` MIME type. Falling back to `WebAssembly.instantiate` which is slower. Original error:\n", e); +/******/ return fallback(); +/******/ } +/******/ throw e; +/******/ } +/******/ ); +/******/ } +/******/ return fallback(); +/******/ }); /******/ }; /******/ })(); /******/ +/******/ /* webpack/runtime/publicPath */ +/******/ (() => { +/******/ __webpack_require__.p = "dist/"; +/******/ })(); +/******/ /************************************************************************/ ``` ``` js +/******/ /******/ // startup -/******/ // Load entry module -/******/ __webpack_require__(0); +/******/ // Load entry module and return exports /******/ // This entry module used 'module' so it can't be inlined +/******/ var __webpack_exports__ = __webpack_require__(0); +/******/ /******/ })() ; ``` @@ -287,35 +373,35 @@ module.exports = __webpack_require__.v(exports, module.id, "0925a077f3cf38995044 ## Unoptimized ``` -asset output.js 9.05 KiB [emitted] (name: main) -asset 0925a077f3cf38995044.wasm 67 bytes [emitted] [immutable] (auxiliary name: main) -asset 9d2b0c46ef31acbcf414.wasm 62 bytes [emitted] [immutable] (auxiliary name: main) -asset a7a690138d8dd16930b3.wasm 41 bytes [emitted] [immutable] (auxiliary name: main) -chunk (runtime: main) output.js (main) 1.27 KiB (javascript) 170 bytes (webassembly) 1.19 KiB (runtime) [entry] [rendered] +asset output.js 13.2 KiB [emitted] (name: main) +asset 5a6637e8d63cdf9c72da.wasm 67 bytes [emitted] [immutable] (auxiliary name: main) +asset 35a58b7c95860d720a3c.wasm 62 bytes [emitted] [immutable] (auxiliary name: main) +asset 0eaeab8b9fa3cef100d1.wasm 41 bytes [emitted] [immutable] (auxiliary name: main) +chunk (runtime: main) output.js (main) 1.27 KiB (javascript) 170 bytes (webassembly) 3.68 KiB (runtime) [entry] [rendered] > ./example.js main - runtime modules 1.19 KiB 5 modules + runtime modules 3.68 KiB 6 modules dependent modules 552 bytes (javascript) 170 bytes (webassembly) [dependent] 4 modules ./example.js 753 bytes [built] [code generated] [no exports] [used exports unknown] entry ./example.js main -webpack 5.11.1 compiled successfully +webpack 5.90.0 compiled successfully ``` ## Production mode ``` -asset output.js 1.59 KiB [emitted] [minimized] (name: main) -asset 908ca2d722f446ec8201.wasm 67 bytes [emitted] [immutable] (auxiliary name: main) -asset ea4e26db3d258a94d99d.wasm 62 bytes [emitted] [immutable] (auxiliary name: main) -asset f4c0bab8e2d961142f75.wasm 41 bytes [emitted] [immutable] (auxiliary name: main) -chunk (runtime: main) output.js (main) 1.27 KiB (javascript) 170 bytes (webassembly) 943 bytes (runtime) [entry] [rendered] +asset output.js 2.89 KiB [emitted] [minimized] (name: main) +asset 67aca7a09456080b5120.wasm 67 bytes [emitted] [immutable] (auxiliary name: main) +asset 36825f9224dde8d88de0.wasm 62 bytes [emitted] [immutable] (auxiliary name: main) +asset 10cff76bc58b7aa8f9cb.wasm 41 bytes [emitted] [immutable] (auxiliary name: main) +chunk (runtime: main) output.js (main) 1.27 KiB (javascript) 170 bytes (webassembly) 3.42 KiB (runtime) [entry] [rendered] > ./example.js main + runtime modules 3.42 KiB 5 modules dependent modules 552 bytes (javascript) 170 bytes (webassembly) [dependent] 4 modules - runtime modules 943 bytes 4 modules ./example.js 753 bytes [built] [code generated] [no exports] [no exports used] entry ./example.js main -webpack 5.11.1 compiled successfully +webpack 5.90.0 compiled successfully ``` diff --git a/examples/wasm-simple/webpack.config.js b/examples/wasm-simple/webpack.config.js index 70ba131d8c3..990ea91fc6f 100644 --- a/examples/wasm-simple/webpack.config.js +++ b/examples/wasm-simple/webpack.config.js @@ -1,5 +1,5 @@ module.exports = { - // mode: "development || "production", + // mode: "development" || "production", output: { webassemblyModuleFilename: "[hash].wasm", publicPath: "dist/" diff --git a/examples/worker/README.md b/examples/worker/README.md index 64be9aa6829..73b7e3633ec 100644 --- a/examples/worker/README.md +++ b/examples/worker/README.md @@ -272,7 +272,6 @@ export const add = (content, from) => { /******/ doneFns && doneFns.forEach((fn) => (fn(event))); /******/ if(prev) return prev(event); /******/ } -/******/ ; /******/ var timeout = setTimeout(onScriptComplete.bind(null, undefined, { type: 'timeout', target: script }), 120000); /******/ script.onerror = onScriptComplete.bind(null, script.onerror); /******/ script.onload = onScriptComplete.bind(null, script.onload); @@ -362,19 +361,21 @@ export const add = (content, from) => { /******/ // add "moreModules" to the modules object, /******/ // then flag all "chunkIds" as loaded and fire callback /******/ var moduleId, chunkId, i = 0; -/******/ for(moduleId in moreModules) { -/******/ if(__webpack_require__.o(moreModules, moduleId)) { -/******/ __webpack_require__.m[moduleId] = moreModules[moduleId]; +/******/ if(chunkIds.some((id) => (installedChunks[id] !== 0))) { +/******/ for(moduleId in moreModules) { +/******/ if(__webpack_require__.o(moreModules, moduleId)) { +/******/ __webpack_require__.m[moduleId] = moreModules[moduleId]; +/******/ } /******/ } +/******/ if(runtime) var result = runtime(__webpack_require__); /******/ } -/******/ if(runtime) runtime(__webpack_require__); /******/ if(parentChunkLoadingFunction) parentChunkLoadingFunction(data); /******/ for(;i < chunkIds.length; i++) { /******/ chunkId = chunkIds[i]; /******/ if(__webpack_require__.o(installedChunks, chunkId) && installedChunks[chunkId]) { /******/ installedChunks[chunkId][0](); /******/ } -/******/ installedChunks[chunkIds[i]] = 0; +/******/ installedChunks[chunkId] = 0; /******/ } /******/ /******/ } @@ -714,6 +715,7 @@ onmessage = async event => { # dist/129.js ```javascript +"use strict"; (self["webpackChunk"] = self["webpackChunk"] || []).push([[129],{ /***/ 2: @@ -721,12 +723,11 @@ onmessage = async event => { !*** ./fibonacci.js ***! \**********************/ /*! namespace exports */ -/*! export fibonacci [provided] [maybe used in main, ./example.js|80:18-84:2 (runtime-defined)] [usage prevents renaming] */ -/*! other exports [not provided] [maybe used in main, ./example.js|80:18-84:2 (runtime-defined)] */ +/*! export fibonacci [provided] [maybe used in main, 9a81d90cfd0dfd13d748 (runtime-defined)] [usage prevents renaming] */ +/*! other exports [not provided] [maybe used in main, 9a81d90cfd0dfd13d748 (runtime-defined)] */ /*! runtime requirements: __webpack_require__.r, __webpack_exports__, __webpack_require__.d, __webpack_require__.* */ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { -"use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "fibonacci": () => (/* binding */ fibonacci) @@ -746,69 +747,69 @@ function fibonacci(n) { ## Unoptimized ``` -asset main.js 12.2 KiB [emitted] (name: main) +asset main.js 12.3 KiB [emitted] (name: main) asset workers/fibonacci.js 5.43 KiB [emitted] (name: fibonacci) -asset 129.js 937 bytes [emitted] +asset 129.js 931 bytes [emitted] asset chat.js 911 bytes [emitted] (name: chat) -chunk (runtime: ./example.js|80:18-84:2, main) 129.js 103 bytes [rendered] +chunk (runtime: 9a81d90cfd0dfd13d748, main) 129.js 103 bytes [rendered] > ./fibonacci ./example.js 70:30-51 > ./fibonacci ./fib-worker.js 2:29-50 ./fibonacci.js 103 bytes [built] [code generated] [exports: fibonacci] import() ./fibonacci ./example.js 70:30-51 import() ./fibonacci ./fib-worker.js 2:29-50 -chunk (runtime: main) main.js (main) 2.25 KiB (javascript) 5.64 KiB (runtime) [entry] [rendered] +chunk (runtime: main) main.js (main) 2.25 KiB (javascript) 5.71 KiB (runtime) [entry] [rendered] > ./example.js main - runtime modules 5.64 KiB 8 modules + runtime modules 5.71 KiB 8 modules ./example.js 2.25 KiB [built] [code generated] [no exports used] entry ./example.js main -chunk (runtime: ./example.js|25:19-31:1) chat.js (chat) 527 bytes [entry] [rendered] +chunk (runtime: 1fad8bf8de78b0a77bfd) chat.js (chat) 527 bytes [entry] [rendered] > ./example.js 25:19-31:1 ./chat-worker.js + 1 modules 527 bytes [built] [code generated] [no exports] [no exports used] new Worker() ./chat-worker.js ./example.js 25:19-31:1 -chunk (runtime: ./example.js|80:18-84:2) workers/fibonacci.js (fibonacci) 176 bytes (javascript) 2.14 KiB (runtime) [entry] [rendered] +chunk (runtime: 9a81d90cfd0dfd13d748) workers/fibonacci.js (fibonacci) 176 bytes (javascript) 2.14 KiB (runtime) [entry] [rendered] > ./example.js 80:18-84:2 runtime modules 2.14 KiB 7 modules ./fib-worker.js 176 bytes [built] [code generated] [no exports used] new Worker() ./fib-worker.js ./example.js 80:18-84:2 -webpack 5.27.2 compiled successfully +webpack 5.78.0 compiled successfully ``` ## Production mode ``` -asset main.js 3.44 KiB [emitted] [minimized] (name: main) +asset main.js 3.46 KiB [emitted] [minimized] (name: main) asset workers/fibonacci.js 945 bytes [emitted] [minimized] (name: fibonacci) asset chat.js 270 bytes [emitted] [minimized] (name: chat) asset 129.js 166 bytes [emitted] [minimized] -chunk (runtime: ./example.js|80:18-84:2, main) 129.js 103 bytes [rendered] +chunk (runtime: 9a81d90cfd0dfd13d748, main) 129.js 103 bytes [rendered] > ./fibonacci ./example.js 70:30-51 > ./fibonacci ./fib-worker.js 2:29-50 ./fibonacci.js 103 bytes [built] [code generated] [exports: fibonacci] import() ./fibonacci ./example.js 70:30-51 import() ./fibonacci ./fib-worker.js 2:29-50 -chunk (runtime: main) main.js (main) 2.25 KiB (javascript) 5.64 KiB (runtime) [entry] [rendered] +chunk (runtime: main) main.js (main) 2.25 KiB (javascript) 5.71 KiB (runtime) [entry] [rendered] > ./example.js main - runtime modules 5.64 KiB 8 modules + runtime modules 5.71 KiB 8 modules ./example.js 2.25 KiB [built] [code generated] [no exports used] entry ./example.js main -chunk (runtime: ./example.js|25:19-31:1) chat.js (chat) 527 bytes [entry] [rendered] +chunk (runtime: 1fad8bf8de78b0a77bfd) chat.js (chat) 527 bytes [entry] [rendered] > ./example.js 25:19-31:1 ./chat-worker.js + 1 modules 527 bytes [built] [code generated] [no exports] [no exports used] new Worker() ./chat-worker.js ./example.js 25:19-31:1 -chunk (runtime: ./example.js|80:18-84:2) workers/fibonacci.js (fibonacci) 176 bytes (javascript) 2.14 KiB (runtime) [entry] [rendered] +chunk (runtime: 9a81d90cfd0dfd13d748) workers/fibonacci.js (fibonacci) 176 bytes (javascript) 2.14 KiB (runtime) [entry] [rendered] > ./example.js 80:18-84:2 runtime modules 2.14 KiB 7 modules ./fib-worker.js 176 bytes [built] [code generated] [no exports used] new Worker() ./fib-worker.js ./example.js 80:18-84:2 -webpack 5.27.2 compiled successfully +webpack 5.78.0 compiled successfully ``` diff --git a/examples/worker/webpack.config.js b/examples/worker/webpack.config.js index fe0e0804386..40032472184 100644 --- a/examples/worker/webpack.config.js +++ b/examples/worker/webpack.config.js @@ -1,4 +1,4 @@ -var path = require("path"); +const path = require("path"); module.exports = { entry: "./example.js", diff --git a/generate-types-config.js b/generate-types-config.js index 59d8b78920c..b1a47a8285e 100644 --- a/generate-types-config.js +++ b/generate-types-config.js @@ -1,7 +1,9 @@ module.exports = { nameMapping: { FsStats: /^Stats Import fs/, + validateFunction: /^validate Import/, Configuration: /^WebpackOptions / }, - exclude: [/^devServer in WebpackOptions /] + exclude: [/^devServer in WebpackOptions /], + include: [/^(_module|_compilation|_compiler) in NormalModuleLoaderContext /] }; diff --git a/hot/dev-server.js b/hot/dev-server.js index a93ab3700ba..4812864a128 100644 --- a/hot/dev-server.js +++ b/hot/dev-server.js @@ -4,9 +4,10 @@ */ /* globals __webpack_hash__ */ if (module.hot) { + /** @type {undefined|string} */ var lastHash; var upToDate = function upToDate() { - return lastHash.indexOf(__webpack_hash__) >= 0; + return /** @type {string} */ (lastHash).indexOf(__webpack_hash__) >= 0; }; var log = require("./log"); var check = function check() { @@ -14,12 +15,20 @@ if (module.hot) { .check(true) .then(function (updatedModules) { if (!updatedModules) { - log("warning", "[HMR] Cannot find update. Need to do a full reload!"); + log( + "warning", + "[HMR] Cannot find update. " + + (typeof window !== "undefined" + ? "Need to do a full reload!" + : "Please reload manually!") + ); log( "warning", "[HMR] (Probably because of restarting the webpack-dev-server)" ); - window.location.reload(); + if (typeof window !== "undefined") { + window.location.reload(); + } return; } @@ -38,10 +47,15 @@ if (module.hot) { if (["abort", "fail"].indexOf(status) >= 0) { log( "warning", - "[HMR] Cannot apply update. Need to do a full reload!" + "[HMR] Cannot apply update. " + + (typeof window !== "undefined" + ? "Need to do a full reload!" + : "Please reload manually!") ); log("warning", "[HMR] " + log.formatError(err)); - window.location.reload(); + if (typeof window !== "undefined") { + window.location.reload(); + } } else { log("warning", "[HMR] Update failed: " + log.formatError(err)); } diff --git a/hot/lazy-compilation-node.js b/hot/lazy-compilation-node.js index 5ec254db312..da4058583b1 100644 --- a/hot/lazy-compilation-node.js +++ b/hot/lazy-compilation-node.js @@ -3,13 +3,21 @@ "use strict"; var urlBase = decodeURIComponent(__resourceQuery.slice(1)); + +/** + * @param {{ data: string, onError: (err: Error) => void, active: boolean, module: module }} options options + * @returns {() => void} function to destroy response + */ exports.keepAlive = function (options) { var data = options.data; var onError = options.onError; var active = options.active; var module = options.module; + /** @type {import("http").IncomingMessage} */ var response; - var request = require("http").request( + var request = ( + urlBase.startsWith("https") ? require("https") : require("http") + ).request( urlBase + data, { agent: false, @@ -25,6 +33,10 @@ exports.keepAlive = function (options) { } } ); + + /** + * @param {Error} err error + */ function errorHandler(err) { err.message = "Problem communicating active modules to the server: " + err.message; diff --git a/hot/lazy-compilation-web.js b/hot/lazy-compilation-web.js index 62d955c5a22..ec8253f0a3c 100644 --- a/hot/lazy-compilation-web.js +++ b/hot/lazy-compilation-web.js @@ -9,6 +9,7 @@ if (typeof EventSource !== "function") { } var urlBase = decodeURIComponent(__resourceQuery.slice(1)); +/** @type {EventSource | undefined} */ var activeEventSource; var activeKeys = new Map(); var errorHandlers = new Set(); @@ -19,6 +20,10 @@ var updateEventSource = function updateEventSource() { activeEventSource = new EventSource( urlBase + Array.from(activeKeys.keys()).join("@") ); + /** + * @this {EventSource} + * @param {Event & { message?: string, filename?: string, lineno?: number, colno?: number, error?: Error }} event event + */ activeEventSource.onerror = function (event) { errorHandlers.forEach(function (onError) { onError( @@ -42,6 +47,10 @@ var updateEventSource = function updateEventSource() { } }; +/** + * @param {{ data: string, onError: (err: Error) => void, active: boolean, module: module }} options options + * @returns {() => void} function to destroy response + */ exports.keepAlive = function (options) { var data = options.data; var onError = options.onError; diff --git a/hot/log-apply-result.js b/hot/log-apply-result.js index d4452f9308c..cb46366dd44 100644 --- a/hot/log-apply-result.js +++ b/hot/log-apply-result.js @@ -2,6 +2,11 @@ MIT License http://www.opensource.org/licenses/mit-license.php Author Tobias Koppers @sokra */ + +/** + * @param {(string | number)[]} updatedModules updated modules + * @param {(string | number)[] | null} renewedModules renewed modules + */ module.exports = function (updatedModules, renewedModules) { var unacceptedModules = updatedModules.filter(function (moduleId) { return renewedModules && renewedModules.indexOf(moduleId) < 0; diff --git a/hot/log.js b/hot/log.js index 483ab4080b0..63758822ae6 100644 --- a/hot/log.js +++ b/hot/log.js @@ -1,7 +1,14 @@ +/** @typedef {"info" | "warning" | "error"} LogLevel */ + +/** @type {LogLevel} */ var logLevel = "info"; function dummy() {} +/** + * @param {LogLevel} level log level + * @returns {boolean} true, if should log + */ function shouldLog(level) { var shouldLog = (logLevel === "info" && level === "info") || @@ -10,6 +17,10 @@ function shouldLog(level) { return shouldLog; } +/** + * @param {(msg?: string) => void} logFn log function + * @returns {(level: LogLevel, msg?: string) => void} function that logs when log level is sufficient + */ function logGroup(logFn) { return function (level, msg) { if (shouldLog(level)) { @@ -18,6 +29,10 @@ function logGroup(logFn) { }; } +/** + * @param {LogLevel} level log level + * @param {string|Error} msg message + */ module.exports = function (level, msg) { if (shouldLog(level)) { if (level === "info") { @@ -30,11 +45,9 @@ module.exports = function (level, msg) { } }; -/* eslint-disable node/no-unsupported-features/node-builtins */ var group = console.group || dummy; var groupCollapsed = console.groupCollapsed || dummy; var groupEnd = console.groupEnd || dummy; -/* eslint-enable node/no-unsupported-features/node-builtins */ module.exports.group = logGroup(group); @@ -42,10 +55,17 @@ module.exports.groupCollapsed = logGroup(groupCollapsed); module.exports.groupEnd = logGroup(groupEnd); +/** + * @param {LogLevel} level log level + */ module.exports.setLogLevel = function (level) { logLevel = level; }; +/** + * @param {Error} err error + * @returns {string} formatted error + */ module.exports.formatError = function (err) { var message = err.message; var stack = err.stack; @@ -53,7 +73,6 @@ module.exports.formatError = function (err) { return message; } else if (stack.indexOf(message) < 0) { return message + "\n" + stack; - } else { - return stack; } + return stack; }; diff --git a/hot/only-dev-server.js b/hot/only-dev-server.js index 7312beb82d6..5979ab54353 100644 --- a/hot/only-dev-server.js +++ b/hot/only-dev-server.js @@ -2,11 +2,12 @@ MIT License http://www.opensource.org/licenses/mit-license.php Author Tobias Koppers @sokra */ -/*globals __webpack_hash__ */ +/* globals __webpack_hash__ */ if (module.hot) { + /** @type {undefined|string} */ var lastHash; var upToDate = function upToDate() { - return lastHash.indexOf(__webpack_hash__) >= 0; + return /** @type {string} */ (lastHash).indexOf(__webpack_hash__) >= 0; }; var log = require("./log"); var check = function check() { diff --git a/hot/poll.js b/hot/poll.js index dab215a426a..b87c2525944 100644 --- a/hot/poll.js +++ b/hot/poll.js @@ -2,11 +2,14 @@ MIT License http://www.opensource.org/licenses/mit-license.php Author Tobias Koppers @sokra */ -/*globals __resourceQuery */ +/* globals __resourceQuery */ if (module.hot) { - var hotPollInterval = +__resourceQuery.substr(1) || 10 * 60 * 1000; + var hotPollInterval = +__resourceQuery.slice(1) || 10 * 60 * 1000; var log = require("./log"); + /** + * @param {boolean=} fromUpdate true when called from update + */ var checkForUpdate = function checkForUpdate(fromUpdate) { if (module.hot.status() === "idle") { module.hot diff --git a/hot/signal.js b/hot/signal.js index ef949521f15..36a0cbe38c7 100644 --- a/hot/signal.js +++ b/hot/signal.js @@ -2,9 +2,13 @@ MIT License http://www.opensource.org/licenses/mit-license.php Author Tobias Koppers @sokra */ -/*globals __resourceQuery */ +/* globals __resourceQuery */ if (module.hot) { var log = require("./log"); + + /** + * @param {boolean=} fromUpdate true when called from update + */ var checkForUpdate = function checkForUpdate(fromUpdate) { module.hot .check() @@ -45,7 +49,7 @@ if (module.hot) { }); }; - process.on(__resourceQuery.substr(1) || "SIGUSR2", function () { + process.on(__resourceQuery.slice(1) || "SIGUSR2", function () { if (module.hot.status() !== "idle") { log( "warning", diff --git a/jest.config.js b/jest.config.js new file mode 100644 index 00000000000..2cc6d151b2e --- /dev/null +++ b/jest.config.js @@ -0,0 +1,54 @@ +/** @type {import('jest').Config} */ +const config = { + prettierPath: require.resolve("prettier-2"), + forceExit: true, + setupFilesAfterEnv: ["/test/setupTestFramework.js"], + testMatch: [ + "/test/*.test.js", + "/test/*.basictest.js", + "/test/*.longtest.js", + "/test/*.unittest.js" + ], + watchPathIgnorePatterns: [ + "/.git", + "/node_modules", + "/test/js", + "/test/browsertest/js", + "/test/fixtures/temp-cache-fixture", + "/test/fixtures/temp-", + "/benchmark", + "/assembly", + "/tooling", + "/examples/*/dist", + "/coverage", + "/.eslintcache" + ], + modulePathIgnorePatterns: [ + "/.git", + "/node_modules/webpack/node_modules", + "/test/js", + "/test/browsertest/js", + "/test/fixtures/temp-cache-fixture", + "/test/fixtures/temp-", + "/benchmark", + "/examples/*/dist", + "/coverage", + "/.eslintcache" + ], + transformIgnorePatterns: [""], + coverageDirectory: "/coverage", + coveragePathIgnorePatterns: [ + "\\.runtime\\.js$", + "/test", + "/schemas", + "/node_modules" + ], + testEnvironment: "./test/patch-node-env.js", + coverageReporters: ["json"], + snapshotFormat: { + escapeString: true, + printBasicPrototype: true + } +}; + +module.exports = config; diff --git a/lib/APIPlugin.js b/lib/APIPlugin.js index d42aedec399..a36422ed250 100644 --- a/lib/APIPlugin.js +++ b/lib/APIPlugin.js @@ -5,10 +5,17 @@ "use strict"; +const InitFragment = require("./InitFragment"); +const { + JAVASCRIPT_MODULE_TYPE_AUTO, + JAVASCRIPT_MODULE_TYPE_DYNAMIC, + JAVASCRIPT_MODULE_TYPE_ESM +} = require("./ModuleTypeConstants"); const RuntimeGlobals = require("./RuntimeGlobals"); const WebpackError = require("./WebpackError"); const ConstDependency = require("./dependencies/ConstDependency"); const BasicEvaluatedExpression = require("./javascript/BasicEvaluatedExpression"); +const JavascriptModulesPlugin = require("./javascript/JavascriptModulesPlugin"); const { toConstantDependency, evaluateToString @@ -17,103 +24,127 @@ const ChunkNameRuntimeModule = require("./runtime/ChunkNameRuntimeModule"); const GetFullHashRuntimeModule = require("./runtime/GetFullHashRuntimeModule"); /** @typedef {import("./Compiler")} Compiler */ +/** @typedef {import("./Dependency").DependencyLocation} DependencyLocation */ +/** @typedef {import("./Module").BuildInfo} BuildInfo */ /** @typedef {import("./javascript/JavascriptParser")} JavascriptParser */ +/** @typedef {import("./javascript/JavascriptParser").Range} Range */ -/* eslint-disable camelcase */ -const REPLACEMENTS = { - __webpack_require__: { - expr: RuntimeGlobals.require, - req: [RuntimeGlobals.require], - type: "function", - assign: false - }, - __webpack_public_path__: { - expr: RuntimeGlobals.publicPath, - req: [RuntimeGlobals.publicPath], - type: "string", - assign: true - }, - __webpack_base_uri__: { - expr: RuntimeGlobals.baseURI, - req: [RuntimeGlobals.baseURI], - type: "string", - assign: true - }, - __webpack_modules__: { - expr: RuntimeGlobals.moduleFactories, - req: [RuntimeGlobals.moduleFactories], - type: "object", - assign: false - }, - __webpack_chunk_load__: { - expr: RuntimeGlobals.ensureChunk, - req: [RuntimeGlobals.ensureChunk], - type: "function", - assign: true - }, - __non_webpack_require__: { - expr: "require", - req: null, - type: undefined, // type is not known, depends on environment - assign: true - }, - __webpack_nonce__: { - expr: RuntimeGlobals.scriptNonce, - req: [RuntimeGlobals.scriptNonce], - type: "string", - assign: true - }, - __webpack_hash__: { - expr: `${RuntimeGlobals.getFullHash}()`, - req: [RuntimeGlobals.getFullHash], - type: "string", - assign: false - }, - __webpack_chunkname__: { - expr: RuntimeGlobals.chunkName, - req: [RuntimeGlobals.chunkName], - type: "string", - assign: false - }, - __webpack_get_script_filename__: { - expr: RuntimeGlobals.getChunkScriptFilename, - req: [RuntimeGlobals.getChunkScriptFilename], - type: "function", - assign: true - }, - __webpack_runtime_id__: { - expr: RuntimeGlobals.runtimeId, - req: [RuntimeGlobals.runtimeId], - assign: false - }, - "require.onError": { - expr: RuntimeGlobals.uncaughtErrorHandler, - req: [RuntimeGlobals.uncaughtErrorHandler], - type: undefined, // type is not known, could be function or undefined - assign: true // is never a pattern - }, - __system_context__: { - expr: RuntimeGlobals.systemContext, - req: [RuntimeGlobals.systemContext], - type: "object", - assign: false - }, - __webpack_share_scopes__: { - expr: RuntimeGlobals.shareScopeMap, - req: [RuntimeGlobals.shareScopeMap], - type: "object", - assign: false - }, - __webpack_init_sharing__: { - expr: RuntimeGlobals.initializeSharing, - req: [RuntimeGlobals.initializeSharing], - type: "function", - assign: true - } -}; -/* eslint-enable camelcase */ +/** + * @param {boolean | undefined} module true if ES module + * @param {string} importMetaName `import.meta` name + * @returns {Record} replacements + */ +function getReplacements(module, importMetaName) { + return { + __webpack_require__: { + expr: RuntimeGlobals.require, + req: [RuntimeGlobals.require], + type: "function", + assign: false + }, + __webpack_public_path__: { + expr: RuntimeGlobals.publicPath, + req: [RuntimeGlobals.publicPath], + type: "string", + assign: true + }, + __webpack_base_uri__: { + expr: RuntimeGlobals.baseURI, + req: [RuntimeGlobals.baseURI], + type: "string", + assign: true + }, + __webpack_modules__: { + expr: RuntimeGlobals.moduleFactories, + req: [RuntimeGlobals.moduleFactories], + type: "object", + assign: false + }, + __webpack_chunk_load__: { + expr: RuntimeGlobals.ensureChunk, + req: [RuntimeGlobals.ensureChunk], + type: "function", + assign: true + }, + __non_webpack_require__: { + expr: module + ? `__WEBPACK_EXTERNAL_createRequire(${importMetaName}.url)` + : "require", + req: null, + type: undefined, // type is not known, depends on environment + assign: true + }, + __webpack_nonce__: { + expr: RuntimeGlobals.scriptNonce, + req: [RuntimeGlobals.scriptNonce], + type: "string", + assign: true + }, + __webpack_hash__: { + expr: `${RuntimeGlobals.getFullHash}()`, + req: [RuntimeGlobals.getFullHash], + type: "string", + assign: false + }, + __webpack_chunkname__: { + expr: RuntimeGlobals.chunkName, + req: [RuntimeGlobals.chunkName], + type: "string", + assign: false + }, + __webpack_get_script_filename__: { + expr: RuntimeGlobals.getChunkScriptFilename, + req: [RuntimeGlobals.getChunkScriptFilename], + type: "function", + assign: true + }, + __webpack_runtime_id__: { + expr: RuntimeGlobals.runtimeId, + req: [RuntimeGlobals.runtimeId], + assign: false + }, + "require.onError": { + expr: RuntimeGlobals.uncaughtErrorHandler, + req: [RuntimeGlobals.uncaughtErrorHandler], + type: undefined, // type is not known, could be function or undefined + assign: true // is never a pattern + }, + __system_context__: { + expr: RuntimeGlobals.systemContext, + req: [RuntimeGlobals.systemContext], + type: "object", + assign: false + }, + __webpack_share_scopes__: { + expr: RuntimeGlobals.shareScopeMap, + req: [RuntimeGlobals.shareScopeMap], + type: "object", + assign: false + }, + __webpack_init_sharing__: { + expr: RuntimeGlobals.initializeSharing, + req: [RuntimeGlobals.initializeSharing], + type: "function", + assign: true + } + }; +} + +const PLUGIN_NAME = "APIPlugin"; + +/** + * @typedef {object} APIPluginOptions + * @property {boolean} [module] the output filename + */ class APIPlugin { + /** + * @param {APIPluginOptions} [options] options + */ + constructor(options = {}) { + this.options = options; + } + /** * Apply the plugin * @param {Compiler} compiler the compiler instance @@ -121,8 +152,16 @@ class APIPlugin { */ apply(compiler) { compiler.hooks.compilation.tap( - "APIPlugin", + PLUGIN_NAME, (compilation, { normalModuleFactory }) => { + const importMetaName = /** @type {string} */ ( + compilation.outputOptions.importMetaName + ); + const REPLACEMENTS = getReplacements( + this.options.module, + importMetaName + ); + compilation.dependencyTemplates.set( ConstDependency, new ConstDependency.Template() @@ -130,88 +169,153 @@ class APIPlugin { compilation.hooks.runtimeRequirementInTree .for(RuntimeGlobals.chunkName) - .tap("APIPlugin", chunk => { + .tap(PLUGIN_NAME, chunk => { compilation.addRuntimeModule( chunk, - new ChunkNameRuntimeModule(chunk.name) + new ChunkNameRuntimeModule(/** @type {string} */ (chunk.name)) ); return true; }); compilation.hooks.runtimeRequirementInTree .for(RuntimeGlobals.getFullHash) - .tap("APIPlugin", (chunk, set) => { + .tap(PLUGIN_NAME, (chunk, set) => { compilation.addRuntimeModule(chunk, new GetFullHashRuntimeModule()); return true; }); + const hooks = JavascriptModulesPlugin.getCompilationHooks(compilation); + + hooks.renderModuleContent.tap( + PLUGIN_NAME, + (source, module, renderContext) => { + if (/** @type {BuildInfo} */ (module.buildInfo).needCreateRequire) { + const needPrefix = + renderContext.runtimeTemplate.supportNodePrefixForCoreModules(); + const chunkInitFragments = [ + new InitFragment( + `import { createRequire as __WEBPACK_EXTERNAL_createRequire } from "${ + needPrefix ? "node:" : "" + }module";\n`, + InitFragment.STAGE_HARMONY_IMPORTS, + 0, + "external module node-commonjs" + ) + ]; + + renderContext.chunkInitFragments.push(...chunkInitFragments); + } + + return source; + } + ); + /** * @param {JavascriptParser} parser the parser */ const handler = parser => { - Object.keys(REPLACEMENTS).forEach(key => { + for (const key of Object.keys(REPLACEMENTS)) { const info = REPLACEMENTS[key]; - parser.hooks.expression - .for(key) - .tap( - "APIPlugin", - toConstantDependency(parser, info.expr, info.req) - ); + parser.hooks.expression.for(key).tap(PLUGIN_NAME, expression => { + const dep = toConstantDependency(parser, info.expr, info.req); + + if (key === "__non_webpack_require__" && this.options.module) { + /** @type {BuildInfo} */ + (parser.state.module.buildInfo).needCreateRequire = true; + } + + return dep(expression); + }); if (info.assign === false) { - parser.hooks.assign.for(key).tap("APIPlugin", expr => { + parser.hooks.assign.for(key).tap(PLUGIN_NAME, expr => { const err = new WebpackError(`${key} must not be assigned`); - err.loc = expr.loc; + err.loc = /** @type {DependencyLocation} */ (expr.loc); throw err; }); } if (info.type) { parser.hooks.evaluateTypeof .for(key) - .tap("APIPlugin", evaluateToString(info.type)); + .tap(PLUGIN_NAME, evaluateToString(info.type)); } - }); + } parser.hooks.expression .for("__webpack_layer__") - .tap("APIPlugin", expr => { + .tap(PLUGIN_NAME, expr => { const dep = new ConstDependency( JSON.stringify(parser.state.module.layer), - expr.range + /** @type {Range} */ (expr.range) ); - dep.loc = expr.loc; + dep.loc = /** @type {DependencyLocation} */ (expr.loc); parser.state.module.addPresentationalDependency(dep); return true; }); parser.hooks.evaluateIdentifier .for("__webpack_layer__") - .tap("APIPlugin", expr => + .tap(PLUGIN_NAME, expr => (parser.state.module.layer === null ? new BasicEvaluatedExpression().setNull() : new BasicEvaluatedExpression().setString( parser.state.module.layer - ) - ).setRange(expr.range) + ) + ).setRange(/** @type {Range} */ (expr.range)) ); parser.hooks.evaluateTypeof .for("__webpack_layer__") - .tap("APIPlugin", expr => + .tap(PLUGIN_NAME, expr => new BasicEvaluatedExpression() .setString( parser.state.module.layer === null ? "object" : "string" ) - .setRange(expr.range) + .setRange(/** @type {Range} */ (expr.range)) ); + + parser.hooks.expression + .for("__webpack_module__.id") + .tap(PLUGIN_NAME, expr => { + /** @type {BuildInfo} */ + (parser.state.module.buildInfo).moduleConcatenationBailout = + "__webpack_module__.id"; + const dep = new ConstDependency( + `${parser.state.module.moduleArgument}.id`, + /** @type {Range} */ (expr.range), + [RuntimeGlobals.moduleId] + ); + dep.loc = /** @type {DependencyLocation} */ (expr.loc); + parser.state.module.addPresentationalDependency(dep); + return true; + }); + + parser.hooks.expression + .for("__webpack_module__") + .tap(PLUGIN_NAME, expr => { + /** @type {BuildInfo} */ + (parser.state.module.buildInfo).moduleConcatenationBailout = + "__webpack_module__"; + const dep = new ConstDependency( + parser.state.module.moduleArgument, + /** @type {Range} */ (expr.range), + [RuntimeGlobals.module] + ); + dep.loc = /** @type {DependencyLocation} */ (expr.loc); + parser.state.module.addPresentationalDependency(dep); + return true; + }); + parser.hooks.evaluateTypeof + .for("__webpack_module__") + .tap(PLUGIN_NAME, evaluateToString("object")); }; normalModuleFactory.hooks.parser - .for("javascript/auto") - .tap("APIPlugin", handler); + .for(JAVASCRIPT_MODULE_TYPE_AUTO) + .tap(PLUGIN_NAME, handler); normalModuleFactory.hooks.parser - .for("javascript/dynamic") - .tap("APIPlugin", handler); + .for(JAVASCRIPT_MODULE_TYPE_DYNAMIC) + .tap(PLUGIN_NAME, handler); normalModuleFactory.hooks.parser - .for("javascript/esm") - .tap("APIPlugin", handler); + .for(JAVASCRIPT_MODULE_TYPE_ESM) + .tap(PLUGIN_NAME, handler); } ); } diff --git a/lib/AbstractMethodError.js b/lib/AbstractMethodError.js index bbf2d08a6c7..7a9d2f992b4 100644 --- a/lib/AbstractMethodError.js +++ b/lib/AbstractMethodError.js @@ -13,18 +13,22 @@ const CURRENT_METHOD_REGEXP = /at ([a-zA-Z0-9_.]*)/; * @returns {string} message */ function createMessage(method) { - return `Abstract method${method ? " " + method : ""}. Must be overridden.`; + return `Abstract method${method ? ` ${method}` : ""}. Must be overridden.`; } /** * @constructor */ function Message() { - /** @type {string} */ + /** @type {string | undefined} */ this.stack = undefined; Error.captureStackTrace(this); - /** @type {RegExpMatchArray} */ - const match = this.stack.split("\n")[3].match(CURRENT_METHOD_REGEXP); + /** @type {RegExpMatchArray | null} */ + const match = + /** @type {string} */ + (/** @type {unknown} */ (this.stack)) + .split("\n")[3] + .match(CURRENT_METHOD_REGEXP); this.message = match && match[1] ? createMessage(match[1]) : createMessage(); } @@ -32,12 +36,13 @@ function Message() { /** * Error for abstract method * @example + * ```js * class FooClass { * abstractMethod() { * throw new AbstractMethodError(); // error message: Abstract method FooClass.abstractMethod. Must be overridden. * } * } - * + * ``` */ class AbstractMethodError extends WebpackError { constructor() { diff --git a/lib/AsyncDependenciesBlock.js b/lib/AsyncDependenciesBlock.js index d85b9b5e600..539c20cb35d 100644 --- a/lib/AsyncDependenciesBlock.js +++ b/lib/AsyncDependenciesBlock.js @@ -15,13 +15,15 @@ const makeSerializable = require("./util/makeSerializable"); /** @typedef {import("./Dependency").UpdateHashContext} UpdateHashContext */ /** @typedef {import("./Entrypoint").EntryOptions} EntryOptions */ /** @typedef {import("./Module")} Module */ +/** @typedef {import("./serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */ +/** @typedef {import("./serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */ /** @typedef {import("./util/Hash")} Hash */ class AsyncDependenciesBlock extends DependenciesBlock { /** - * @param {ChunkGroupOptions & { entryOptions?: EntryOptions }} groupOptions options for the group - * @param {DependencyLocation=} loc the line of code - * @param {string=} request the request + * @param {(ChunkGroupOptions & { entryOptions?: EntryOptions }) | null} groupOptions options for the group + * @param {(DependencyLocation | null)=} loc the line of code + * @param {(string | null)=} request the request */ constructor(groupOptions, loc, request) { super(); @@ -33,23 +35,25 @@ class AsyncDependenciesBlock extends DependenciesBlock { this.groupOptions = groupOptions; this.loc = loc; this.request = request; - /** @type {DependenciesBlock} */ - this.parent = undefined; + this._stringifiedGroupOptions = undefined; } /** - * @returns {string} The name of the chunk + * @returns {string | undefined} The name of the chunk */ get chunkName() { return this.groupOptions.name; } /** - * @param {string} value The new chunk name + * @param {string | undefined} value The new chunk name * @returns {void} */ set chunkName(value) { - this.groupOptions.name = value; + if (this.groupOptions.name !== value) { + this.groupOptions.name = value; + this._stringifiedGroupOptions = undefined; + } } /** @@ -59,12 +63,19 @@ class AsyncDependenciesBlock extends DependenciesBlock { */ updateHash(hash, context) { const { chunkGraph } = context; - hash.update(JSON.stringify(this.groupOptions)); + if (this._stringifiedGroupOptions === undefined) { + this._stringifiedGroupOptions = JSON.stringify(this.groupOptions); + } const chunkGroup = chunkGraph.getBlockChunkGroup(this); - hash.update(chunkGroup ? chunkGroup.id : ""); + hash.update( + `${this._stringifiedGroupOptions}${chunkGroup ? chunkGroup.id : ""}` + ); super.updateHash(hash, context); } + /** + * @param {ObjectSerializerContext} context context + */ serialize(context) { const { write } = context; write(this.groupOptions); @@ -73,6 +84,9 @@ class AsyncDependenciesBlock extends DependenciesBlock { super.serialize(context); } + /** + * @param {ObjectDeserializerContext} context context + */ deserialize(context) { const { read } = context; this.groupOptions = read(); diff --git a/lib/AsyncDependencyToInitialChunkError.js b/lib/AsyncDependencyToInitialChunkError.js index 570eb51cd17..75888f869a3 100644 --- a/lib/AsyncDependencyToInitialChunkError.js +++ b/lib/AsyncDependencyToInitialChunkError.js @@ -25,8 +25,6 @@ class AsyncDependencyToInitialChunkError extends WebpackError { this.name = "AsyncDependencyToInitialChunkError"; this.module = module; this.loc = loc; - - Error.captureStackTrace(this, this.constructor); } } diff --git a/lib/AutomaticPrefetchPlugin.js b/lib/AutomaticPrefetchPlugin.js index 5152574e33a..991ffc91732 100644 --- a/lib/AutomaticPrefetchPlugin.js +++ b/lib/AutomaticPrefetchPlugin.js @@ -27,6 +27,7 @@ class AutomaticPrefetchPlugin { ); } ); + /** @type {{context: string | null, request: string}[] | null} */ let lastModules = null; compiler.hooks.afterCompile.tap("AutomaticPrefetchPlugin", compilation => { lastModules = []; @@ -44,7 +45,7 @@ class AutomaticPrefetchPlugin { "AutomaticPrefetchPlugin", (compilation, callback) => { if (!lastModules) return callback(); - asyncLib.forEach( + asyncLib.each( lastModules, (m, callback) => { compilation.addModuleChain( diff --git a/lib/BannerPlugin.js b/lib/BannerPlugin.js index 32df12b90ac..4793a77cbcb 100644 --- a/lib/BannerPlugin.js +++ b/lib/BannerPlugin.js @@ -5,18 +5,32 @@ "use strict"; -const { validate } = require("schema-utils"); const { ConcatSource } = require("webpack-sources"); const Compilation = require("./Compilation"); const ModuleFilenameHelpers = require("./ModuleFilenameHelpers"); const Template = require("./Template"); +const createSchemaValidation = require("./util/create-schema-validation"); -const schema = require("../schemas/plugins/BannerPlugin.json"); - +/** @typedef {import("../declarations/plugins/BannerPlugin").BannerFunction} BannerFunction */ /** @typedef {import("../declarations/plugins/BannerPlugin").BannerPluginArgument} BannerPluginArgument */ /** @typedef {import("../declarations/plugins/BannerPlugin").BannerPluginOptions} BannerPluginOptions */ +/** @typedef {import("./Compilation").PathData} PathData */ /** @typedef {import("./Compiler")} Compiler */ +/** @typedef {import("./TemplatedPathPlugin").TemplatePath} TemplatePath */ + +const validate = createSchemaValidation( + require("../schemas/plugins/BannerPlugin.check.js"), + () => require("../schemas/plugins/BannerPlugin.json"), + { + name: "Banner Plugin", + baseDataPath: "options" + } +); +/** + * @param {string} str string to wrap + * @returns {string} wrapped string + */ const wrapComment = str => { if (!str.includes("\n")) { return Template.toComment(str); @@ -26,7 +40,7 @@ const wrapComment = str => { .split("\n") .join("\n * ") .replace(/\s+\n/g, "\n") - .trimRight()}\n */`; + .trimEnd()}\n */`; }; class BannerPlugin { @@ -40,23 +54,22 @@ class BannerPlugin { }; } - validate(schema, options, { - name: "Banner Plugin", - baseDataPath: "options" - }); + validate(options); this.options = options; const bannerOption = options.banner; if (typeof bannerOption === "function") { const getBanner = bannerOption; + /** @type {BannerFunction} */ this.banner = this.options.raw ? getBanner - : data => wrapComment(getBanner(data)); + : /** @type {BannerFunction} */ data => wrapComment(getBanner(data)); } else { const banner = this.options.raw ? bannerOption : wrapComment(bannerOption); + /** @type {BannerFunction} */ this.banner = () => banner; } } @@ -73,12 +86,15 @@ class BannerPlugin { undefined, options ); + const cache = new WeakMap(); + const stage = + this.options.stage || Compilation.PROCESS_ASSETS_STAGE_ADDITIONS; compiler.hooks.compilation.tap("BannerPlugin", compilation => { compilation.hooks.processAssets.tap( { name: "BannerPlugin", - stage: Compilation.PROCESS_ASSETS_STAGE_ADDITIONS + stage }, () => { for (const chunk of compilation.chunks) { @@ -91,17 +107,26 @@ class BannerPlugin { continue; } - const data = { - chunk, - filename: file - }; + /** @type {PathData} */ + const data = { chunk, filename: file }; - const comment = compilation.getPath(banner, data); - - compilation.updateAsset( - file, - old => new ConcatSource(comment, "\n", old) + const comment = compilation.getPath( + /** @type {TemplatePath} */ + (banner), + data ); + + compilation.updateAsset(file, old => { + const cached = cache.get(old); + if (!cached || cached.comment !== comment) { + const source = options.footer + ? new ConcatSource(old, "\n", comment) + : new ConcatSource(comment, "\n", old); + cache.set(old, { source, comment }); + return source; + } + return cached.source; + }); } } } diff --git a/lib/Cache.js b/lib/Cache.js index 2f553bef93c..055ad6d225a 100644 --- a/lib/Cache.js +++ b/lib/Cache.js @@ -14,14 +14,14 @@ const { /** @typedef {import("./WebpackError")} WebpackError */ /** - * @typedef {Object} Etag + * @typedef {object} Etag * @property {function(): string} toString */ /** * @template T * @callback CallbackCache - * @param {WebpackError=} err + * @param {WebpackError | null} err * @param {T=} result * @returns {void} */ @@ -33,16 +33,19 @@ const { * @returns {void} */ -const needCalls = (times, callback) => { - return err => { - if (--times === 0) { - return callback(err); - } - if (err && times > 0) { - times = 0; - return callback(err); - } - }; +/** + * @param {number} times times + * @param {function(Error=): void} callback callback + * @returns {function(Error=): void} callback + */ +const needCalls = (times, callback) => err => { + if (--times === 0) { + return callback(err); + } + if (err && times > 0) { + times = 0; + return callback(err); + } }; class Cache { @@ -71,6 +74,7 @@ class Cache { * @returns {void} */ get(identifier, etag, callback) { + /** @type {GotHandler[]} */ const gotHandlers = []; this.hooks.get.callAsync(identifier, etag, gotHandlers, (err, result) => { if (err) { diff --git a/lib/CacheFacade.js b/lib/CacheFacade.js index c8d1e9b8d28..eece9631735 100644 --- a/lib/CacheFacade.js +++ b/lib/CacheFacade.js @@ -5,6 +5,7 @@ "use strict"; +const { forEachBail } = require("enhanced-resolve"); const asyncLib = require("neo-async"); const getLazyHashedEtag = require("./cache/getLazyHashedEtag"); const mergeEtags = require("./cache/mergeEtags"); @@ -13,19 +14,20 @@ const mergeEtags = require("./cache/mergeEtags"); /** @typedef {import("./Cache").Etag} Etag */ /** @typedef {import("./WebpackError")} WebpackError */ /** @typedef {import("./cache/getLazyHashedEtag").HashableObject} HashableObject */ +/** @typedef {typeof import("./util/Hash")} HashConstructor */ /** * @template T * @callback CallbackCache - * @param {WebpackError=} err - * @param {T=} result + * @param {(Error | null)=} err + * @param {(T | null)=} result * @returns {void} */ /** * @template T * @callback CallbackNormalErrorCache - * @param {Error=} err + * @param {(Error | null)=} err * @param {T=} result * @returns {void} */ @@ -36,6 +38,7 @@ class MultiItemCache { */ constructor(items) { this._items = items; + // eslint-disable-next-line no-constructor-return if (items.length === 1) return /** @type {any} */ (items[0]); } @@ -45,15 +48,7 @@ class MultiItemCache { * @returns {void} */ get(callback) { - const next = i => { - this._items[i].get((err, result) => { - if (err) return callback(err); - if (result !== undefined) return callback(null, result); - if (++i >= this._items.length) return callback(); - next(i); - }); - }; - next(0); + forEachBail(this._items, (item, callback) => item.get(callback), callback); } /** @@ -61,12 +56,15 @@ class MultiItemCache { * @returns {Promise} promise with the data */ getPromise() { - const next = i => { - return this._items[i].getPromise().then(result => { + /** + * @param {number} i index + * @returns {Promise} promise with the data + */ + const next = i => + this._items[i].getPromise().then(result => { if (result !== undefined) return result; if (++i < this._items.length) return next(i); }); - }; return next(0); } @@ -90,9 +88,9 @@ class MultiItemCache { * @returns {Promise} promise signals when the value is stored */ storePromise(data) { - return Promise.all( - this._items.map(item => item.storePromise(data)) - ).then(() => {}); + return Promise.all(this._items.map(item => item.storePromise(data))).then( + () => {} + ); } } @@ -198,10 +196,12 @@ class CacheFacade { /** * @param {Cache} cache the root cache * @param {string} name the child cache name + * @param {(string | HashConstructor)=} hashFunction the hash function to use */ - constructor(cache, name) { + constructor(cache, name, hashFunction) { this._cache = cache; this._name = name; + this._hashFunction = hashFunction; } /** @@ -209,7 +209,11 @@ class CacheFacade { * @returns {CacheFacade} child cache */ getChildCache(name) { - return new CacheFacade(this._cache, `${this._name}|${name}`); + return new CacheFacade( + this._cache, + `${this._name}|${name}`, + this._hashFunction + ); } /** @@ -230,7 +234,7 @@ class CacheFacade { * @returns {Etag} an etag that is lazy hashed */ getLazyHashedEtag(obj) { - return getLazyHashedEtag(obj); + return getLazyHashedEtag(obj, this._hashFunction); } /** diff --git a/lib/CaseSensitiveModulesWarning.js b/lib/CaseSensitiveModulesWarning.js index 65898f4d830..58a38e5506e 100644 --- a/lib/CaseSensitiveModulesWarning.js +++ b/lib/CaseSensitiveModulesWarning.js @@ -14,8 +14,8 @@ const WebpackError = require("./WebpackError"); * @param {Module[]} modules the modules to be sorted * @returns {Module[]} sorted version of original modules */ -const sortModules = modules => { - return modules.slice().sort((a, b) => { +const sortModules = modules => + modules.sort((a, b) => { const aIdent = a.identifier(); const bIdent = b.identifier(); /* istanbul ignore next */ @@ -25,38 +25,38 @@ const sortModules = modules => { /* istanbul ignore next */ return 0; }); -}; /** * @param {Module[]} modules each module from throw * @param {ModuleGraph} moduleGraph the module graph * @returns {string} each message from provided modules */ -const createModulesListMessage = (modules, moduleGraph) => { - return modules +const createModulesListMessage = (modules, moduleGraph) => + modules .map(m => { let message = `* ${m.identifier()}`; const validReasons = Array.from( moduleGraph.getIncomingConnectionsByOriginModule(m).keys() - ).filter(x => x); + ).filter(Boolean); if (validReasons.length > 0) { message += `\n Used by ${validReasons.length} module(s), i. e.`; - message += `\n ${validReasons[0].identifier()}`; + message += `\n ${ + /** @type {Module[]} */ (validReasons)[0].identifier() + }`; } return message; }) .join("\n"); -}; class CaseSensitiveModulesWarning extends WebpackError { /** * Creates an instance of CaseSensitiveModulesWarning. - * @param {Module[]} modules modules that were detected + * @param {Iterable} modules modules that were detected * @param {ModuleGraph} moduleGraph the module graph */ constructor(modules, moduleGraph) { - const sortedModules = sortModules(modules); + const sortedModules = sortModules(Array.from(modules)); const modulesList = createModulesListMessage(sortedModules, moduleGraph); super(`There are multiple modules with names that only differ in casing. This can lead to unexpected behavior when compiling on a filesystem with other case-semantic. @@ -65,8 +65,6 @@ ${modulesList}`); this.name = "CaseSensitiveModulesWarning"; this.module = sortedModules[0]; - - Error.captureStackTrace(this, this.constructor); } } diff --git a/lib/Chunk.js b/lib/Chunk.js index ae8ac32a37f..3b1b93c00b2 100644 --- a/lib/Chunk.js +++ b/lib/Chunk.js @@ -22,26 +22,30 @@ const { mergeRuntime } = require("./util/runtime"); /** @typedef {import("./ChunkGraph").ChunkFilterPredicate} ChunkFilterPredicate */ /** @typedef {import("./ChunkGraph").ChunkSizeOptions} ChunkSizeOptions */ /** @typedef {import("./ChunkGraph").ModuleFilterPredicate} ModuleFilterPredicate */ +/** @typedef {import("./ChunkGraph").ModuleId} ModuleId */ /** @typedef {import("./ChunkGroup")} ChunkGroup */ +/** @typedef {import("./ChunkGroup").ChunkGroupOptions} ChunkGroupOptions */ /** @typedef {import("./Compilation")} Compilation */ /** @typedef {import("./Compilation").AssetInfo} AssetInfo */ -/** @typedef {import("./Compilation").PathData} PathData */ /** @typedef {import("./Entrypoint").EntryOptions} EntryOptions */ /** @typedef {import("./Module")} Module */ /** @typedef {import("./ModuleGraph")} ModuleGraph */ +/** @typedef {import("./TemplatedPathPlugin").TemplatePath} TemplatePath */ /** @typedef {import("./util/Hash")} Hash */ /** @typedef {import("./util/runtime").RuntimeSpec} RuntimeSpec */ +/** @typedef {number | string} ChunkId */ + const ChunkFilesSet = createArrayToSetDeprecationSet("chunk.files"); /** - * @typedef {Object} WithId an object who has an id property * + * @typedef {object} WithId an object who has an id property * * @property {string | number} id the id of the object */ /** * @deprecated - * @typedef {Object} ChunkMaps + * @typedef {object} ChunkMaps * @property {Record} hash * @property {Record>} contentHash * @property {Record} name @@ -49,7 +53,7 @@ const ChunkFilesSet = createArrayToSetDeprecationSet("chunk.files"); /** * @deprecated - * @typedef {Object} ChunkModuleMaps + * @typedef {object} ChunkModuleMaps * @property {Record} id * @property {Record} hash */ @@ -63,28 +67,34 @@ let debugId = 1000; class Chunk { /** * @param {string=} name of chunk being created, is optional (for subclasses) + * @param {boolean} backCompat enable backward-compatibility */ - constructor(name) { - /** @type {number | string | null} */ + constructor(name, backCompat = true) { + /** @type {ChunkId | null} */ this.id = null; - /** @type {(number|string)[] | null} */ + /** @type {ChunkId[] | null} */ this.ids = null; /** @type {number} */ this.debugId = debugId++; - /** @type {string} */ + /** @type {string | undefined} */ this.name = name; /** @type {SortableSet} */ this.idNameHints = new SortableSet(); /** @type {boolean} */ this.preventIntegration = false; - /** @type {(string | function(PathData, AssetInfo=): string)?} */ + /** @type {TemplatePath | undefined} */ this.filenameTemplate = undefined; - /** @private @type {SortableSet} */ + /** @type {TemplatePath | undefined} */ + this.cssFilenameTemplate = undefined; + /** + * @private + * @type {SortableSet} + */ this._groups = new SortableSet(undefined, compareChunkGroupsByIndex); /** @type {RuntimeSpec} */ this.runtime = undefined; /** @type {Set} */ - this.files = new ChunkFilesSet(); + this.files = backCompat ? new ChunkFilesSet() : new Set(); /** @type {Set} */ this.auxiliaryFiles = new Set(); /** @type {boolean} */ @@ -115,11 +125,11 @@ class Chunk { return undefined; } else if (entryModules.length === 1) { return entryModules[0]; - } else { - throw new Error( - "Module.entryModule: Multiple entry modules are not supported by the deprecated API (Use the new ChunkGroup API)" - ); } + + throw new Error( + "Module.entryModule: Multiple entry modules are not supported by the deprecated API (Use the new ChunkGroup API)" + ); } /** @@ -262,9 +272,9 @@ class Chunk { if (chunkGraph.canChunksBeIntegrated(this, otherChunk)) { chunkGraph.integrateChunks(this, otherChunk); return true; - } else { - return false; } + + return false; } /** @@ -347,7 +357,7 @@ class Chunk { const chunkModuleHashMap = Object.create(null); for (const asyncChunk of this.getAllAsyncChunks()) { - /** @type {(string|number)[]} */ + /** @type {ChunkId[] | undefined} */ let array; for (const module of chunkGraph.getOrderedChunkModulesIterable( asyncChunk, @@ -356,9 +366,11 @@ class Chunk { if (filterFn(module)) { if (array === undefined) { array = []; - chunkModuleIdMap[asyncChunk.id] = array; + chunkModuleIdMap[/** @type {ChunkId} */ (asyncChunk.id)] = array; } - const moduleId = chunkGraph.getModuleId(module); + const moduleId = + /** @type {ModuleId} */ + (chunkGraph.getModuleId(module)); array.push(moduleId); chunkModuleHashMap[moduleId] = chunkGraph.getRenderedModuleHash( module, @@ -402,15 +414,18 @@ class Chunk { const chunkNameMap = Object.create(null); for (const chunk of this.getAllAsyncChunks()) { - chunkHashMap[chunk.id] = realHash ? chunk.hash : chunk.renderedHash; + const id = /** @type {ChunkId} */ (chunk.id); + chunkHashMap[id] = + /** @type {string} */ + (realHash ? chunk.hash : chunk.renderedHash); for (const key of Object.keys(chunk.contentHash)) { if (!chunkContentHashMap[key]) { chunkContentHashMap[key] = Object.create(null); } - chunkContentHashMap[key][chunk.id] = chunk.contentHash[key]; + chunkContentHashMap[key][id] = chunk.contentHash[key]; } if (chunk.name) { - chunkNameMap[chunk.id] = chunk.name; + chunkNameMap[id] = chunk.name; } } @@ -502,7 +517,7 @@ class Chunk { } /** - * @returns {Iterable} the chunkGroups that the said chunk is referenced in + * @returns {SortableSet} the chunkGroups that the said chunk is referenced in */ get groupsIterable() { this._groups.sort(); @@ -539,21 +554,22 @@ class Chunk { * @returns {void} */ updateHash(hash, chunkGraph) { - hash.update(`${this.id} `); - hash.update(this.ids ? this.ids.join(",") : ""); - hash.update(`${this.name || ""} `); + hash.update( + `${this.id} ${this.ids ? this.ids.join() : ""} ${this.name || ""} ` + ); const xor = new StringXor(); for (const m of chunkGraph.getChunkModulesIterable(this)) { xor.add(chunkGraph.getModuleHash(m, this.runtime)); } xor.updateHash(hash); - const entryModules = chunkGraph.getChunkEntryModulesWithChunkGroupIterable( - this - ); + const entryModules = + chunkGraph.getChunkEntryModulesWithChunkGroupIterable(this); for (const [m, chunkGroup] of entryModules) { - hash.update("entry"); - hash.update(`${chunkGraph.getModuleId(m)}`); - hash.update(chunkGroup.id); + hash.update( + `entry${chunkGraph.getModuleId(m)}${ + /** @type {ChunkGroup} */ (chunkGroup).id + }` + ); } } @@ -568,9 +584,15 @@ class Chunk { Array.from(this.groupsIterable, g => new Set(g.chunks)) ); - for (const chunkGroup of this.groupsIterable) { + const initialQueue = new Set(this.groupsIterable); + + for (const chunkGroup of initialQueue) { for (const child of chunkGroup.childrenIterable) { - queue.add(child); + if (child instanceof Entrypoint) { + initialQueue.add(child); + } else { + queue.add(child); + } } } @@ -593,8 +615,12 @@ class Chunk { */ getAllInitialChunks() { const chunks = new Set(); - for (const group of this.groupsIterable) { - for (const c of group.chunks) chunks.add(c); + const queue = new Set(this.groupsIterable); + for (const group of queue) { + if (group.isInitial()) { + for (const c of group.chunks) chunks.add(c); + for (const g of group.childrenIterable) queue.add(g); + } } return chunks; } @@ -680,14 +706,20 @@ class Chunk { for (const childGroup of group.childrenIterable) { for (const key of Object.keys(childGroup.options)) { if (key.endsWith("Order")) { - const name = key.substr(0, key.length - "Order".length); + const name = key.slice(0, key.length - "Order".length); let list = lists.get(name); if (list === undefined) { list = []; lists.set(name, list); } list.push({ - order: childGroup.options[key], + order: + /** @type {number} */ + ( + childGroup.options[ + /** @type {keyof ChunkGroupOptions} */ (key) + ] + ), group: childGroup }); } @@ -708,7 +740,7 @@ class Chunk { for (const item of list) { for (const chunk of item.group.chunks) { if (filterFn && !filterFn(chunk, chunkGraph)) continue; - chunkIdSet.add(chunk.id); + chunkIdSet.add(/** @type {ChunkId} */ (chunk.id)); } } if (chunkIdSet.size > 0) { @@ -721,13 +753,14 @@ class Chunk { /** * @param {ChunkGraph} chunkGraph the chunk graph * @param {string} type option name - * @returns {{ onChunks: Chunk[], chunks: Set }[]} referenced chunks for a specific type + * @returns {{ onChunks: Chunk[], chunks: Set }[] | undefined} referenced chunks for a specific type */ getChildrenOfTypeInOrder(chunkGraph, type) { const list = []; for (const group of this.groupsIterable) { for (const childGroup of group.childrenIterable) { - const order = childGroup.options[type]; + const order = + childGroup.options[/** @type {keyof ChunkGroupOptions} */ (type)]; if (order === undefined) continue; list.push({ order, @@ -736,9 +769,10 @@ class Chunk { }); } } - if (list.length === 0) return undefined; + if (list.length === 0) return; list.sort((a, b) => { - const cmp = b.order - a.order; + const cmp = + /** @type {number} */ (b.order) - /** @type {number} */ (a.order); if (cmp !== 0) return cmp; return a.group.compareTo(chunkGraph, b.group); }); @@ -782,7 +816,7 @@ class Chunk { if (chunkMap === undefined) { chunkMaps[key] = chunkMap = Object.create(null); } - chunkMap[chunk.id] = data[key]; + chunkMap[/** @type {ChunkId} */ (chunk.id)] = data[key]; } }; diff --git a/lib/ChunkGraph.js b/lib/ChunkGraph.js index b9db3f832e9..462ec9f38af 100644 --- a/lib/ChunkGraph.js +++ b/lib/ChunkGraph.js @@ -6,10 +6,10 @@ "use strict"; const util = require("util"); +const Entrypoint = require("./Entrypoint"); const ModuleGraphConnection = require("./ModuleGraphConnection"); const { first } = require("./util/SetHelpers"); const SortableSet = require("./util/SortableSet"); -const StringXor = require("./util/StringXor"); const { compareModulesById, compareIterables, @@ -30,28 +30,37 @@ const { /** @typedef {import("./AsyncDependenciesBlock")} AsyncDependenciesBlock */ /** @typedef {import("./Chunk")} Chunk */ +/** @typedef {import("./Chunk").ChunkId} ChunkId */ /** @typedef {import("./ChunkGroup")} ChunkGroup */ -/** @typedef {import("./Entrypoint")} Entrypoint */ /** @typedef {import("./Module")} Module */ /** @typedef {import("./ModuleGraph")} ModuleGraph */ +/** @typedef {import("./ModuleGraphConnection").ConnectionState} ConnectionState */ /** @typedef {import("./RuntimeModule")} RuntimeModule */ +/** @typedef {typeof import("./util/Hash")} Hash */ /** @typedef {import("./util/runtime").RuntimeSpec} RuntimeSpec */ /** @type {ReadonlySet} */ const EMPTY_SET = new Set(); +const ZERO_BIG_INT = BigInt(0); + const compareModuleIterables = compareIterables(compareModulesByIdentifier); /** @typedef {(c: Chunk, chunkGraph: ChunkGraph) => boolean} ChunkFilterPredicate */ /** @typedef {(m: Module) => boolean} ModuleFilterPredicate */ +/** @typedef {[Module, Entrypoint | undefined]} EntryModuleWithChunkGroup */ /** - * @typedef {Object} ChunkSizeOptions + * @typedef {object} ChunkSizeOptions * @property {number=} chunkOverhead constant overhead for a chunk * @property {number=} entryChunkMultiplicator multiplicator for initial chunks */ class ModuleHashInfo { + /** + * @param {string} hash hash + * @param {string} renderedHash rendered hash + */ constructor(hash, renderedHash) { this.hash = hash; this.renderedHash = renderedHash; @@ -65,9 +74,7 @@ class ModuleHashInfo { * @param {SortableSet} set the set * @returns {T[]} set as array */ -const getArray = set => { - return Array.from(set); -}; +const getArray = set => Array.from(set); /** * @param {SortableSet} chunks the chunks @@ -82,14 +89,17 @@ const getModuleRuntimes = chunks => { }; /** - * @param {SortableSet} set the set - * @returns {Map>} modules by source type + * @param {WeakMap> | undefined} sourceTypesByModule sourceTypesByModule + * @returns {function (SortableSet): Map>} modules by source type */ -const modulesBySourceType = set => { +const modulesBySourceType = sourceTypesByModule => set => { /** @type {Map>} */ const map = new Map(); for (const module of set) { - for (const sourceType of module.getSourceTypes()) { + const sourceTypes = + (sourceTypesByModule && sourceTypesByModule.get(module)) || + module.getSourceTypes(); + for (const sourceType of sourceTypes) { let innerSet = map.get(sourceType); if (innerSet === undefined) { innerSet = new SortableSet(); @@ -107,6 +117,7 @@ const modulesBySourceType = set => { } return map; }; +const defaultModulesBySourceType = modulesBySourceType(undefined); /** @type {WeakMap} */ const createOrderedArrayFunctionMap = new WeakMap(); @@ -147,7 +158,7 @@ const getModulesSize = modules => { * @returns {Record} the sizes of the modules */ const getModulesSizes = modules => { - let sizes = Object.create(null); + const sizes = Object.create(null); for (const module of modules) { for (const type of module.getSourceTypes()) { sizes[type] = (sizes[type] || 0) + module.size(type); @@ -173,23 +184,27 @@ const isAvailableChunk = (a, b) => { return true; }; +/** @typedef {Set} EntryInChunks */ +/** @typedef {Set} RuntimeInChunks */ +/** @typedef {string | number} ModuleId */ + class ChunkGraphModule { constructor() { /** @type {SortableSet} */ this.chunks = new SortableSet(); - /** @type {Set | undefined} */ + /** @type {EntryInChunks | undefined} */ this.entryInChunks = undefined; - /** @type {Set | undefined} */ + /** @type {RuntimeInChunks | undefined} */ this.runtimeInChunks = undefined; - /** @type {RuntimeSpecMap} */ + /** @type {RuntimeSpecMap | undefined} */ this.hashes = undefined; - /** @type {string | number} */ + /** @type {ModuleId | null} */ this.id = null; /** @type {RuntimeSpecMap> | undefined} */ this.runtimeRequirements = undefined; - /** @type {RuntimeSpecMap} */ + /** @type {RuntimeSpecMap | undefined} */ this.graphHashes = undefined; - /** @type {RuntimeSpecMap} */ + /** @type {RuntimeSpecMap | undefined} */ this.graphHashesWithConnections = undefined; } } @@ -198,46 +213,57 @@ class ChunkGraphChunk { constructor() { /** @type {SortableSet} */ this.modules = new SortableSet(); + /** @type {WeakMap> | undefined} */ + this.sourceTypesByModule = undefined; /** @type {Map} */ this.entryModules = new Map(); /** @type {SortableSet} */ this.runtimeModules = new SortableSet(); /** @type {Set | undefined} */ this.fullHashModules = undefined; + /** @type {Set | undefined} */ + this.dependentHashModules = undefined; /** @type {Set | undefined} */ this.runtimeRequirements = undefined; /** @type {Set} */ this.runtimeRequirementsInTree = new Set(); + + this._modulesBySourceType = defaultModulesBySourceType; } } class ChunkGraph { /** * @param {ModuleGraph} moduleGraph the module graph + * @param {string | Hash} hashFunction the hash function to use */ - constructor(moduleGraph) { - /** @private @type {WeakMap} */ + constructor(moduleGraph, hashFunction = "md4") { + /** + * @private + * @type {WeakMap} + */ this._modules = new WeakMap(); - /** @private @type {WeakMap} */ + /** + * @private + * @type {WeakMap} + */ this._chunks = new WeakMap(); - /** @private @type {WeakMap} */ + /** + * @private + * @type {WeakMap} + */ this._blockChunkGroups = new WeakMap(); - /** @private @type {Map} */ + /** + * @private + * @type {Map} + */ this._runtimeIds = new Map(); /** @type {ModuleGraph} */ this.moduleGraph = moduleGraph; - this._getGraphRoots = this._getGraphRoots.bind(this); + this._hashFunction = hashFunction; - // Caching - this._cacheChunkGraphModuleKey1 = undefined; - this._cacheChunkGraphModuleValue1 = undefined; - this._cacheChunkGraphModuleKey2 = undefined; - this._cacheChunkGraphModuleValue2 = undefined; - this._cacheChunkGraphChunkKey1 = undefined; - this._cacheChunkGraphChunkValue1 = undefined; - this._cacheChunkGraphChunkKey2 = undefined; - this._cacheChunkGraphChunkValue2 = undefined; + this._getGraphRoots = this._getGraphRoots.bind(this); } /** @@ -246,19 +272,11 @@ class ChunkGraph { * @returns {ChunkGraphModule} internal module */ _getChunkGraphModule(module) { - if (this._cacheChunkGraphModuleKey1 === module) - return this._cacheChunkGraphModuleValue1; - if (this._cacheChunkGraphModuleKey2 === module) - return this._cacheChunkGraphModuleValue2; let cgm = this._modules.get(module); if (cgm === undefined) { cgm = new ChunkGraphModule(); this._modules.set(module, cgm); } - this._cacheChunkGraphModuleKey2 = this._cacheChunkGraphModuleKey1; - this._cacheChunkGraphModuleValue2 = this._cacheChunkGraphModuleValue1; - this._cacheChunkGraphModuleKey1 = module; - this._cacheChunkGraphModuleValue1 = cgm; return cgm; } @@ -268,19 +286,11 @@ class ChunkGraph { * @returns {ChunkGraphChunk} internal chunk */ _getChunkGraphChunk(chunk) { - if (this._cacheChunkGraphChunkKey1 === chunk) - return this._cacheChunkGraphChunkValue1; - if (this._cacheChunkGraphChunkKey2 === chunk) - return this._cacheChunkGraphChunkValue2; let cgc = this._chunks.get(chunk); if (cgc === undefined) { cgc = new ChunkGraphChunk(); this._chunks.set(chunk, cgc); } - this._cacheChunkGraphChunkKey2 = this._cacheChunkGraphChunkKey1; - this._cacheChunkGraphChunkValue2 = this._cacheChunkGraphChunkValue1; - this._cacheChunkGraphChunkKey1 = chunk; - this._cacheChunkGraphChunkValue1 = cgc; return cgc; } @@ -294,6 +304,9 @@ class ChunkGraph { findGraphRoots(set, module => { /** @type {Set} */ const set = new Set(); + /** + * @param {Module} module module + */ const addDependencies = module => { for (const connection of moduleGraph.getOutgoingConnections(module)) { if (!connection.module) continue; @@ -333,6 +346,8 @@ class ChunkGraph { const cgm = this._getChunkGraphModule(module); const cgc = this._getChunkGraphChunk(chunk); cgc.modules.delete(module); + // No need to invalidate cgc._modulesBySourceType because we modified cgc.modules anyway + if (cgc.sourceTypesByModule) cgc.sourceTypesByModule.delete(module); cgm.chunks.delete(chunk); } @@ -388,6 +403,20 @@ class ChunkGraph { } } + /** + * @param {Chunk} chunk the chunk + * @param {Iterable} modules the modules that require a full hash + * @returns {void} + */ + attachDependentHashModules(chunk, modules) { + const cgc = this._getChunkGraphChunk(chunk); + if (cgc.dependentHashModules === undefined) + cgc.dependentHashModules = new Set(); + for (const module of modules) { + cgc.dependentHashModules.add(module); + } + } + /** * @param {Module} oldModule the replaced module * @param {Module} newModule the replacing module @@ -411,7 +440,7 @@ class ChunkGraph { } for (const chunk of oldCgm.entryInChunks) { const cgc = this._getChunkGraphChunk(chunk); - const old = cgc.entryModules.get(oldModule); + const old = /** @type {Entrypoint} */ (cgc.entryModules.get(oldModule)); /** @type {Map} */ const newEntryModules = new Map(); for (const [m, cg] of cgc.entryModules) { @@ -443,6 +472,17 @@ class ChunkGraph { cgc.fullHashModules.delete(/** @type {RuntimeModule} */ (oldModule)); cgc.fullHashModules.add(/** @type {RuntimeModule} */ (newModule)); } + if ( + cgc.dependentHashModules !== undefined && + cgc.dependentHashModules.has(/** @type {RuntimeModule} */ (oldModule)) + ) { + cgc.dependentHashModules.delete( + /** @type {RuntimeModule} */ (oldModule) + ); + cgc.dependentHashModules.add( + /** @type {RuntimeModule} */ (newModule) + ); + } } oldCgm.runtimeInChunks = undefined; } @@ -528,13 +568,22 @@ class ChunkGraph { /** * @param {Chunk} chunk the chunk - * @returns {number} the number of module which are contained in this chunk + * @returns {number} the number of modules which are contained in this chunk */ getNumberOfChunkModules(chunk) { const cgc = this._getChunkGraphChunk(chunk); return cgc.modules.size; } + /** + * @param {Chunk} chunk the chunk + * @returns {number} the number of full hash modules which are contained in this chunk + */ + getNumberOfChunkFullHashModules(chunk) { + const cgc = this._getChunkGraphChunk(chunk); + return cgc.fullHashModules === undefined ? 0 : cgc.fullHashModules.size; + } + /** * @param {Chunk} chunk the chunk * @returns {Iterable} return the modules for this chunk @@ -552,11 +601,84 @@ class ChunkGraph { getChunkModulesIterableBySourceType(chunk, sourceType) { const cgc = this._getChunkGraphChunk(chunk); const modulesWithSourceType = cgc.modules - .getFromUnorderedCache(modulesBySourceType) + .getFromUnorderedCache(cgc._modulesBySourceType) .get(sourceType); return modulesWithSourceType; } + /** + * @param {Chunk} chunk chunk + * @param {Module} module chunk module + * @param {Set} sourceTypes source types + */ + setChunkModuleSourceTypes(chunk, module, sourceTypes) { + const cgc = this._getChunkGraphChunk(chunk); + if (cgc.sourceTypesByModule === undefined) { + cgc.sourceTypesByModule = new WeakMap(); + } + cgc.sourceTypesByModule.set(module, sourceTypes); + // Update cgc._modulesBySourceType to invalidate the cache + cgc._modulesBySourceType = modulesBySourceType(cgc.sourceTypesByModule); + } + + /** + * @param {Chunk} chunk chunk + * @param {Module} module chunk module + * @returns {Set} source types + */ + getChunkModuleSourceTypes(chunk, module) { + const cgc = this._getChunkGraphChunk(chunk); + if (cgc.sourceTypesByModule === undefined) { + return module.getSourceTypes(); + } + return cgc.sourceTypesByModule.get(module) || module.getSourceTypes(); + } + + /** + * @param {Module} module module + * @returns {Set} source types + */ + getModuleSourceTypes(module) { + return ( + this._getOverwrittenModuleSourceTypes(module) || module.getSourceTypes() + ); + } + + /** + * @param {Module} module module + * @returns {Set | undefined} source types + */ + _getOverwrittenModuleSourceTypes(module) { + let newSet = false; + let sourceTypes; + for (const chunk of this.getModuleChunksIterable(module)) { + const cgc = this._getChunkGraphChunk(chunk); + if (cgc.sourceTypesByModule === undefined) return; + const st = cgc.sourceTypesByModule.get(module); + if (st === undefined) return; + if (!sourceTypes) { + sourceTypes = st; + continue; + } else if (!newSet) { + for (const type of st) { + if (!newSet) { + if (!sourceTypes.has(type)) { + newSet = true; + sourceTypes = new Set(sourceTypes); + sourceTypes.add(type); + } + } else { + sourceTypes.add(type); + } + } + } else { + for (const type of st) sourceTypes.add(type); + } + } + + return sourceTypes; + } + /** * @param {Chunk} chunk the chunk * @param {function(Module, Module): -1|0|1} comparator comparator function @@ -577,9 +699,9 @@ class ChunkGraph { getOrderedChunkModulesIterableBySourceType(chunk, sourceType, comparator) { const cgc = this._getChunkGraphChunk(chunk); const modulesWithSourceType = cgc.modules - .getFromUnorderedCache(modulesBySourceType) + .getFromUnorderedCache(cgc._modulesBySourceType) .get(sourceType); - if (modulesWithSourceType === undefined) return undefined; + if (modulesWithSourceType === undefined) return; modulesWithSourceType.sortWith(comparator); return modulesWithSourceType; } @@ -617,7 +739,7 @@ class ChunkGraph { for (const asyncChunk of includeAllChunks ? chunk.getAllReferencedChunks() : chunk.getAllAsyncChunks()) { - /** @type {(string|number)[]} */ + /** @type {(string | number)[] | undefined} */ let array; for (const module of this.getOrderedChunkModulesIterable( asyncChunk, @@ -626,9 +748,9 @@ class ChunkGraph { if (filterFn(module)) { if (array === undefined) { array = []; - chunkModuleIdMap[asyncChunk.id] = array; + chunkModuleIdMap[/** @type {ChunkId} */ (asyncChunk.id)] = array; } - const moduleId = this.getModuleId(module); + const moduleId = /** @type {ModuleId} */ (this.getModuleId(module)); array.push(moduleId); } } @@ -650,13 +772,15 @@ class ChunkGraph { hashLength = 0, includeAllChunks = false ) { - /** @type {Record>} */ + /** @type {Record>} */ const chunkModuleHashMap = Object.create(null); + /** @typedef {Record} IdToHashMap */ + for (const asyncChunk of includeAllChunks ? chunk.getAllReferencedChunks() : chunk.getAllAsyncChunks()) { - /** @type {Record} */ + /** @type {IdToHashMap | undefined} */ let idToHashMap; for (const module of this.getOrderedChunkModulesIterable( asyncChunk, @@ -665,11 +789,15 @@ class ChunkGraph { if (filterFn(module)) { if (idToHashMap === undefined) { idToHashMap = Object.create(null); - chunkModuleHashMap[asyncChunk.id] = idToHashMap; + chunkModuleHashMap[/** @type {ChunkId} */ (asyncChunk.id)] = + /** @type {IdToHashMap} */ (idToHashMap); } const moduleId = this.getModuleId(module); const hash = this.getRenderedModuleHash(module, asyncChunk.runtime); - idToHashMap[moduleId] = hashLength ? hash.slice(0, hashLength) : hash; + /** @type {IdToHashMap} */ + (idToHashMap)[/** @type {ModuleId} */ (moduleId)] = hashLength + ? hash.slice(0, hashLength) + : hash; } } } @@ -685,7 +813,7 @@ class ChunkGraph { getChunkConditionMap(chunk, filterFn) { const map = Object.create(null); for (const c of chunk.getAllReferencedChunks()) { - map[c.id] = filterFn(c, this); + map[/** @type {ChunkId} */ (c.id)] = filterFn(c, this); } return map; } @@ -793,7 +921,7 @@ class ChunkGraph { const cgcB = this._getChunkGraphChunk(chunkB); const allModules = new Set(cgcA.modules); for (const m of cgcB.modules) allModules.add(m); - let modulesSize = getModulesSize(allModules); + const modulesSize = getModulesSize(allModules); const chunkOverhead = typeof options.chunkOverhead === "number" ? options.chunkOverhead : 10000; const entryChunkMultiplicator = @@ -827,9 +955,9 @@ class ChunkGraph { return isAvailableChunk(chunkA, chunkB); } else if (hasRuntimeB) { return isAvailableChunk(chunkB, chunkA); - } else { - return false; } + + return false; } if ( @@ -888,7 +1016,12 @@ class ChunkGraph { this.getChunkEntryModulesWithChunkGroupIterable(chunkB) )) { this.disconnectChunkAndEntryModule(chunkB, module); - this.connectChunkAndEntryModule(chunkA, module, chunkGroup); + this.connectChunkAndEntryModule( + chunkA, + module, + /** @type {Entrypoint} */ + (chunkGroup) + ); } for (const chunkGroup of chunkB.groupsIterable) { @@ -899,6 +1032,23 @@ class ChunkGraph { ChunkGraph.clearChunkGraphForChunk(chunkB); } + /** + * @param {Chunk} chunk the chunk to upgrade + * @returns {void} + */ + upgradeDependentToFullHashModules(chunk) { + const cgc = this._getChunkGraphChunk(chunk); + if (cgc.dependentHashModules === undefined) return; + if (cgc.fullHashModules === undefined) { + cgc.fullHashModules = cgc.dependentHashModules; + } else { + for (const m of cgc.dependentHashModules) { + cgc.fullHashModules.add(m); + } + cgc.dependentHashModules = undefined; + } + } + /** * @param {Module} module the checked module * @param {Chunk} chunk the checked chunk @@ -912,7 +1062,7 @@ class ChunkGraph { /** * @param {Chunk} chunk the new chunk * @param {Module} module the entry module - * @param {Entrypoint=} entrypoint the chunk group which must be loaded before the module is executed + * @param {Entrypoint} entrypoint the chunk group which must be loaded before the module is executed * @returns {void} */ connectChunkAndEntryModule(chunk, module, entrypoint) { @@ -951,6 +1101,18 @@ class ChunkGraph { cgc.fullHashModules.add(module); } + /** + * @param {Chunk} chunk the new chunk + * @param {RuntimeModule} module the module that require a full hash + * @returns {void} + */ + addDependentHashModuleToChunk(chunk, module) { + const cgc = this._getChunkGraphChunk(chunk); + if (cgc.dependentHashModules === undefined) + cgc.dependentHashModules = new Set(); + cgc.dependentHashModules.add(module); + } + /** * @param {Chunk} chunk the new chunk * @param {Module} module the entry module @@ -959,8 +1121,9 @@ class ChunkGraph { disconnectChunkAndEntryModule(chunk, module) { const cgm = this._getChunkGraphModule(module); const cgc = this._getChunkGraphChunk(chunk); - cgm.entryInChunks.delete(chunk); - if (cgm.entryInChunks.size === 0) { + /** @type {EntryInChunks} */ + (cgm.entryInChunks).delete(chunk); + if (/** @type {EntryInChunks} */ (cgm.entryInChunks).size === 0) { cgm.entryInChunks = undefined; } cgc.entryModules.delete(module); @@ -974,8 +1137,9 @@ class ChunkGraph { disconnectChunkAndRuntimeModule(chunk, module) { const cgm = this._getChunkGraphModule(module); const cgc = this._getChunkGraphChunk(chunk); - cgm.runtimeInChunks.delete(chunk); - if (cgm.runtimeInChunks.size === 0) { + /** @type {RuntimeInChunks} */ + (cgm.runtimeInChunks).delete(chunk); + if (/** @type {RuntimeInChunks} */ (cgm.runtimeInChunks).size === 0) { cgm.runtimeInChunks = undefined; } cgc.runtimeModules.delete(module); @@ -987,7 +1151,7 @@ class ChunkGraph { */ disconnectEntryModule(module) { const cgm = this._getChunkGraphModule(module); - for (const chunk of cgm.entryInChunks) { + for (const chunk of /** @type {EntryInChunks} */ (cgm.entryInChunks)) { const cgc = this._getChunkGraphChunk(chunk); cgc.entryModules.delete(module); } @@ -1002,8 +1166,9 @@ class ChunkGraph { const cgc = this._getChunkGraphChunk(chunk); for (const module of cgc.entryModules.keys()) { const cgm = this._getChunkGraphModule(module); - cgm.entryInChunks.delete(chunk); - if (cgm.entryInChunks.size === 0) { + /** @type {EntryInChunks} */ + (cgm.entryInChunks).delete(chunk); + if (/** @type {EntryInChunks} */ (cgm.entryInChunks).size === 0) { cgm.entryInChunks = undefined; } } @@ -1042,16 +1207,22 @@ class ChunkGraph { * @returns {Iterable} iterable of chunks */ getChunkEntryDependentChunksIterable(chunk) { - const cgc = this._getChunkGraphChunk(chunk); /** @type {Set} */ const set = new Set(); - for (const chunkGroup of cgc.entryModules.values()) { - for (const c of chunkGroup.chunks) { - if (c !== chunk && !c.hasRuntime()) { - set.add(c); + for (const chunkGroup of chunk.groupsIterable) { + if (chunkGroup instanceof Entrypoint) { + const entrypointChunk = chunkGroup.getEntrypointChunk(); + const cgc = this._getChunkGraphChunk(entrypointChunk); + for (const chunkGroup of cgc.entryModules.values()) { + for (const c of chunkGroup.chunks) { + if (c !== chunk && c !== entrypointChunk && !c.hasRuntime()) { + set.add(c); + } + } } } } + return set; } @@ -1089,14 +1260,7 @@ class ChunkGraph { const array = Array.from(cgc.runtimeModules); array.sort( concatComparators( - compareSelect( - /** - * @param {RuntimeModule} r runtime module - * @returns {number=} stage - */ - r => r.stage, - compareIds - ), + compareSelect(r => /** @type {RuntimeModule} */ (r).stage, compareIds), compareModulesByIdentifier ) ); @@ -1121,7 +1285,14 @@ class ChunkGraph { return cgc.fullHashModules; } - /** @typedef {[Module, Entrypoint | undefined]} EntryModuleWithChunkGroup */ + /** + * @param {Chunk} chunk the chunk + * @returns {Iterable | undefined} iterable of modules (do not modify) + */ + getChunkDependentHashModulesIterable(chunk) { + const cgc = this._getChunkGraphChunk(chunk); + return cgc.dependentHashModules; + } /** * @param {Chunk} chunk the chunk @@ -1134,7 +1305,7 @@ class ChunkGraph { /** * @param {AsyncDependenciesBlock} depBlock the async block - * @returns {ChunkGroup} the chunk group + * @returns {ChunkGroup | undefined} the chunk group */ getBlockChunkGroup(depBlock) { return this._blockChunkGroups.get(depBlock); @@ -1164,7 +1335,7 @@ class ChunkGraph { /** * @param {Module} module the module - * @returns {string | number} the id of the module + * @returns {ModuleId | null} the id of the module */ getModuleId(module) { const cgm = this._getChunkGraphModule(module); @@ -1173,7 +1344,7 @@ class ChunkGraph { /** * @param {Module} module the module - * @param {string | number} id the id of the module + * @param {ModuleId} id the id of the module * @returns {void} */ setModuleId(module, id) { @@ -1186,7 +1357,7 @@ class ChunkGraph { * @returns {string | number} the id of the runtime */ getRuntimeId(runtime) { - return this._runtimeIds.get(runtime); + return /** @type {string | number} */ (this._runtimeIds.get(runtime)); } /** @@ -1223,7 +1394,7 @@ class ChunkGraph { Caller might not support runtime-dependent code generation (opt-out via optimization.usedExports: "global").` ); } - return first(hashInfoItems); + return /** @type {T} */ (first(hashInfoItems)); } else { const hashInfo = hashes.get(runtime); if (!hashInfo) { @@ -1247,7 +1418,7 @@ Caller might not support runtime-dependent code generation (opt-out via optimiza */ hasModuleHashes(module, runtime) { const cgm = this._getChunkGraphModule(module); - const hashes = cgm.hashes; + const hashes = /** @type {RuntimeSpecMap} */ (cgm.hashes); return hashes && hashes.has(runtime); } @@ -1258,7 +1429,7 @@ Caller might not support runtime-dependent code generation (opt-out via optimiza */ getModuleHash(module, runtime) { const cgm = this._getChunkGraphModule(module); - const hashes = cgm.hashes; + const hashes = /** @type {RuntimeSpecMap} */ (cgm.hashes); return this._getModuleHashInfo(module, hashes, runtime).hash; } @@ -1269,7 +1440,7 @@ Caller might not support runtime-dependent code generation (opt-out via optimiza */ getRenderedModuleHash(module, runtime) { const cgm = this._getChunkGraphModule(module); - const hashes = cgm.hashes; + const hashes = /** @type {RuntimeSpecMap} */ (cgm.hashes); return this._getModuleHashInfo(module, hashes, runtime).renderedHash; } @@ -1291,28 +1462,35 @@ Caller might not support runtime-dependent code generation (opt-out via optimiza /** * @param {Module} module the module * @param {RuntimeSpec} runtime the runtime - * @param {Set} items runtime requirements to be added (ownership of this Set is given to ChunkGraph) + * @param {Set} items runtime requirements to be added (ownership of this Set is given to ChunkGraph when transferOwnership not false) + * @param {boolean} transferOwnership true: transfer ownership of the items object, false: items is immutable and shared and won't be modified * @returns {void} */ - addModuleRuntimeRequirements(module, runtime, items) { + addModuleRuntimeRequirements( + module, + runtime, + items, + transferOwnership = true + ) { const cgm = this._getChunkGraphModule(module); const runtimeRequirementsMap = cgm.runtimeRequirements; if (runtimeRequirementsMap === undefined) { const map = new RuntimeSpecMap(); - map.set(runtime, items); + // TODO avoid cloning item and track ownership instead + map.set(runtime, transferOwnership ? items : new Set(items)); cgm.runtimeRequirements = map; return; } runtimeRequirementsMap.update(runtime, runtimeRequirements => { if (runtimeRequirements === undefined) { - return items; - } else if (runtimeRequirements.size >= items.size) { + return transferOwnership ? items : new Set(items); + } else if (!transferOwnership || runtimeRequirements.size >= items.size) { for (const item of items) runtimeRequirements.add(item); return runtimeRequirements; - } else { - for (const item of runtimeRequirements) items.add(item); - return items; } + + for (const item of runtimeRequirements) items.add(item); + return items; }); } @@ -1367,48 +1545,127 @@ Caller might not support runtime-dependent code generation (opt-out via optimiza return runtimeRequirements === undefined ? EMPTY_SET : runtimeRequirements; } + /** + * @param {Module} module the module + * @param {RuntimeSpec} runtime the runtime + * @param {boolean} withConnections include connections + * @returns {string} hash + */ getModuleGraphHash(module, runtime, withConnections = true) { const cgm = this._getChunkGraphModule(module); + return withConnections + ? this._getModuleGraphHashWithConnections(cgm, module, runtime) + : this._getModuleGraphHashBigInt(cgm, module, runtime).toString(16); + } + + /** + * @param {Module} module the module + * @param {RuntimeSpec} runtime the runtime + * @param {boolean} withConnections include connections + * @returns {bigint} hash + */ + getModuleGraphHashBigInt(module, runtime, withConnections = true) { + const cgm = this._getChunkGraphModule(module); + return withConnections + ? BigInt( + `0x${this._getModuleGraphHashWithConnections(cgm, module, runtime)}` + ) + : this._getModuleGraphHashBigInt(cgm, module, runtime); + } + + /** + * @param {ChunkGraphModule} cgm the ChunkGraphModule + * @param {Module} module the module + * @param {RuntimeSpec} runtime the runtime + * @returns {bigint} hash as big int + */ + _getModuleGraphHashBigInt(cgm, module, runtime) { if (cgm.graphHashes === undefined) { cgm.graphHashes = new RuntimeSpecMap(); } const graphHash = cgm.graphHashes.provide(runtime, () => { - const hash = createHash("md4"); - hash.update(`${cgm.id}`); - hash.update(`${this.moduleGraph.isAsync(module)}`); + const hash = createHash(this._hashFunction); + hash.update(`${cgm.id}${this.moduleGraph.isAsync(module)}`); + const sourceTypes = this._getOverwrittenModuleSourceTypes(module); + if (sourceTypes !== undefined) { + for (const type of sourceTypes) hash.update(type); + } this.moduleGraph.getExportsInfo(module).updateHash(hash, runtime); - return /** @type {string} */ (hash.digest("hex")); + return BigInt(`0x${/** @type {string} */ (hash.digest("hex"))}`); }); - if (!withConnections) return graphHash; + return graphHash; + } + + /** + * @param {ChunkGraphModule} cgm the ChunkGraphModule + * @param {Module} module the module + * @param {RuntimeSpec} runtime the runtime + * @returns {string} hash + */ + _getModuleGraphHashWithConnections(cgm, module, runtime) { if (cgm.graphHashesWithConnections === undefined) { cgm.graphHashesWithConnections = new RuntimeSpecMap(); } + + /** + * @param {ConnectionState} state state + * @returns {"F" | "T" | "O"} result + */ const activeStateToString = state => { - if (state === false) return "false"; - if (state === true) return "true"; - if (state === ModuleGraphConnection.TRANSITIVE_ONLY) return "transitive"; + if (state === false) return "F"; + if (state === true) return "T"; + if (state === ModuleGraphConnection.TRANSITIVE_ONLY) return "O"; throw new Error("Not implemented active state"); }; const strict = module.buildMeta && module.buildMeta.strictHarmonyModule; return cgm.graphHashesWithConnections.provide(runtime, () => { + const graphHash = this._getModuleGraphHashBigInt( + cgm, + module, + runtime + ).toString(16); const connections = this.moduleGraph.getOutgoingConnections(module); + /** @type {Set} */ + const activeNamespaceModules = new Set(); /** @type {Map>} */ const connectedModules = new Map(); - for (const connection of connections) { - let stateInfo; - if (typeof runtime === "string") { + /** + * @param {ModuleGraphConnection} connection connection + * @param {string} stateInfo state info + */ + const processConnection = (connection, stateInfo) => { + const module = connection.module; + stateInfo += module.getExportsType(this.moduleGraph, strict); + // cspell:word Tnamespace + if (stateInfo === "Tnamespace") activeNamespaceModules.add(module); + else { + const oldModule = connectedModules.get(stateInfo); + if (oldModule === undefined) { + connectedModules.set(stateInfo, module); + } else if (oldModule instanceof Set) { + oldModule.add(module); + } else if (oldModule !== module) { + connectedModules.set(stateInfo, new Set([oldModule, module])); + } + } + }; + if (runtime === undefined || typeof runtime === "string") { + for (const connection of connections) { const state = connection.getActiveState(runtime); if (state === false) continue; - stateInfo = activeStateToString(state); - } else { + processConnection(connection, state === true ? "T" : "O"); + } + } else { + // cspell:word Tnamespace + for (const connection of connections) { const states = new Set(); - stateInfo = ""; + let stateInfo = ""; forEachRuntime( runtime, runtime => { const state = connection.getActiveState(runtime); states.add(state); - stateInfo += runtime + activeStateToString(state); + stateInfo += activeStateToString(state) + runtime; }, true ); @@ -1417,34 +1674,57 @@ Caller might not support runtime-dependent code generation (opt-out via optimiza if (state === false) continue; stateInfo = activeStateToString(state); } - } - const module = connection.module; - stateInfo += module.getExportsType(this.moduleGraph, strict); - const oldModule = connectedModules.get(stateInfo); - if (oldModule === undefined) { - connectedModules.set(stateInfo, module); - } else if (oldModule instanceof Set) { - oldModule.add(module); - } else if (oldModule !== module) { - connectedModules.set(stateInfo, new Set([oldModule, module])); + processConnection(connection, stateInfo); } } - if (connectedModules.size === 0) return graphHash; + // cspell:word Tnamespace + if (activeNamespaceModules.size === 0 && connectedModules.size === 0) + return graphHash; const connectedModulesInOrder = connectedModules.size > 1 ? Array.from(connectedModules).sort(([a], [b]) => (a < b ? -1 : 1)) : connectedModules; - const hash = createHash("md4"); + const hash = createHash(this._hashFunction); + /** + * @param {Module} module module + */ + const addModuleToHash = module => { + hash.update( + this._getModuleGraphHashBigInt( + this._getChunkGraphModule(module), + module, + runtime + ).toString(16) + ); + }; + /** + * @param {Set} modules modules + */ + const addModulesToHash = modules => { + let xor = ZERO_BIG_INT; + for (const m of modules) { + xor = + xor ^ + this._getModuleGraphHashBigInt( + this._getChunkGraphModule(m), + m, + runtime + ); + } + hash.update(xor.toString(16)); + }; + if (activeNamespaceModules.size === 1) + addModuleToHash( + /** @type {Module} */ (activeNamespaceModules.values().next().value) + ); + else if (activeNamespaceModules.size > 1) + addModulesToHash(activeNamespaceModules); for (const [stateInfo, modules] of connectedModulesInOrder) { hash.update(stateInfo); if (modules instanceof Set) { - const xor = new StringXor(); - for (const m of modules) { - xor.add(this.getModuleGraphHash(m, runtime, false)); - } - xor.updateHash(hash); + addModulesToHash(modules); } else { - hash.update(this.getModuleGraphHash(modules, runtime, false)); + addModuleToHash(modules); } } hash.update(graphHash); @@ -1480,12 +1760,13 @@ Caller might not support runtime-dependent code generation (opt-out via optimiza const chunkGraph = chunkGraphForModuleMap.get(module); if (!chunkGraph) throw new Error( - deprecateMessage + - ": There was no ChunkGraph assigned to the Module for backward-compat (Use the new API)" + `${ + deprecateMessage + }: There was no ChunkGraph assigned to the Module for backward-compat (Use the new API)` ); return chunkGraph; }, - deprecateMessage + ": Use new ChunkGraph API", + `${deprecateMessage}: Use new ChunkGraph API`, deprecationCode ); deprecateGetChunkGraphForModuleMap.set(deprecateMessage, newFn); @@ -1530,12 +1811,13 @@ Caller might not support runtime-dependent code generation (opt-out via optimiza const chunkGraph = chunkGraphForChunkMap.get(chunk); if (!chunkGraph) throw new Error( - deprecateMessage + - "There was no ChunkGraph assigned to the Chunk for backward-compat (Use the new API)" + `${ + deprecateMessage + }There was no ChunkGraph assigned to the Chunk for backward-compat (Use the new API)` ); return chunkGraph; }, - deprecateMessage + ": Use new ChunkGraph API", + `${deprecateMessage}: Use new ChunkGraph API`, deprecationCode ); deprecateGetChunkGraphForChunkMap.set(deprecateMessage, newFn); diff --git a/lib/ChunkGroup.js b/lib/ChunkGroup.js index 69b2128a316..9b899dd214f 100644 --- a/lib/ChunkGroup.js +++ b/lib/ChunkGroup.js @@ -22,12 +22,13 @@ const { /** @typedef {import("./ModuleGraph")} ModuleGraph */ /** @typedef {{id: number}} HasId */ -/** @typedef {{module: Module, loc: DependencyLocation, request: string}} OriginRecord */ +/** @typedef {{module: Module | null, loc: DependencyLocation, request: string}} OriginRecord */ /** - * @typedef {Object} RawChunkGroupOptions + * @typedef {object} RawChunkGroupOptions * @property {number=} preloadOrder * @property {number=} prefetchOrder + * @property {("low" | "high" | "auto")=} fetchPriority */ /** @typedef {RawChunkGroupOptions & { name?: string }} ChunkGroupOptions */ @@ -69,7 +70,7 @@ const sortOrigin = (a, b) => { class ChunkGroup { /** * Creates an instance of ChunkGroup. - * @param {string|ChunkGroupOptions=} options chunk group options passed to chunkGroup + * @param {string | ChunkGroupOptions=} options chunk group options passed to chunkGroup */ constructor(options) { if (typeof options === "string") { @@ -79,7 +80,7 @@ class ChunkGroup { } /** @type {number} */ this.groupDebugId = debugId++; - this.options = options; + this.options = /** @type {ChunkGroupOptions} */ (options); /** @type {SortableSet} */ this._children = new SortableSet(undefined, sortById); /** @type {SortableSet} */ @@ -92,12 +93,18 @@ class ChunkGroup { /** @type {OriginRecord[]} */ this.origins = []; /** Indices in top-down order */ - /** @private @type {Map} */ + /** + * @private + * @type {Map} + */ this._modulePreOrderIndices = new Map(); /** Indices in bottom-up order */ - /** @private @type {Map} */ + /** + * @private + * @type {Map} + */ this._modulePostOrderIndices = new Map(); - /** @type {number} */ + /** @type {number | undefined} */ this.index = undefined; } @@ -107,12 +114,18 @@ class ChunkGroup { * @returns {void} */ addOptions(options) { - for (const key of Object.keys(options)) { + for (const _key of Object.keys(options)) { + const key = /** @type {keyof ChunkGroupOptions} */ (_key); if (this.options[key] === undefined) { - this.options[key] = options[key]; + /** @type {TODO} */ + (this.options)[key] = options[key]; } else if (this.options[key] !== options[key]) { if (key.endsWith("Order")) { - this.options[key] = Math.max(this.options[key], options[key]); + /** @type {TODO} */ + (this.options)[key] = Math.max( + /** @type {number} */ (this.options[key]), + /** @type {number} */ (options[key]) + ); } else { throw new Error( `ChunkGroup.addOptions: No option merge strategy for ${key}` @@ -124,7 +137,7 @@ class ChunkGroup { /** * returns the name of current ChunkGroup - * @returns {string|undefined} returns the ChunkGroup name + * @returns {string | undefined} returns the ChunkGroup name */ get name() { return this.options.name; @@ -132,7 +145,7 @@ class ChunkGroup { /** * sets a new name for current ChunkGroup - * @param {string} value the new name for ChunkGroup + * @param {string | undefined} value the new name for ChunkGroup * @returns {void} */ set name(value) { @@ -212,7 +225,7 @@ class ChunkGroup { /** * @param {Chunk} oldChunk chunk to be replaced * @param {Chunk} newChunk New chunk that will be replaced with - * @returns {boolean} returns true if the replacement was successful + * @returns {boolean | undefined} returns true if the replacement was successful */ replaceChunk(oldChunk, newChunk) { const oldIdx = this.chunks.indexOf(oldChunk); @@ -353,7 +366,7 @@ class ChunkGroup { } /** - * @returns {Array} an array containing the blocks + * @returns {Array} an array containing the blocks */ getBlocks() { return this._blocks.getFromCache(getArray); @@ -363,6 +376,10 @@ class ChunkGroup { return this._blocks.size; } + /** + * @param {AsyncDependenciesBlock} block block + * @returns {boolean} true, if block exists + */ hasBlock(block) { return this._blocks.has(block); } @@ -387,7 +404,7 @@ class ChunkGroup { } /** - * @param {Module} module origin module + * @param {Module | null} module origin module * @param {DependencyLocation} loc location of the reference in the origin module * @param {string} request request name of the reference * @returns {void} @@ -461,7 +478,6 @@ class ChunkGroup { /** * Sorting predicate which allows current ChunkGroup to be compared against another. * Sorting values are based off of number of chunks in ChunkGroup. - * * @param {ChunkGraph} chunkGraph the chunk graph * @param {ChunkGroup} otherGroup the chunkGroup to compare this against * @returns {-1|0|1} sort position for comparison @@ -486,13 +502,17 @@ class ChunkGroup { for (const childGroup of this._children) { for (const key of Object.keys(childGroup.options)) { if (key.endsWith("Order")) { - const name = key.substr(0, key.length - "Order".length); + const name = key.slice(0, key.length - "Order".length); let list = lists.get(name); if (list === undefined) { lists.set(name, (list = [])); } list.push({ - order: childGroup.options[key], + order: + /** @type {number} */ + ( + childGroup.options[/** @type {keyof ChunkGroupOptions} */ (key)] + ), group: childGroup }); } @@ -524,7 +544,7 @@ class ChunkGroup { /** * Gets the top-down index of a module in this ChunkGroup * @param {Module} module the module - * @returns {number} index + * @returns {number | undefined} index */ getModulePreOrderIndex(module) { return this._modulePreOrderIndices.get(module); @@ -543,7 +563,7 @@ class ChunkGroup { /** * Gets the bottom-up index of a module in this ChunkGroup * @param {Module} module the module - * @returns {number} index + * @returns {number | undefined} index */ getModulePostOrderIndex(module) { return this._modulePostOrderIndices.get(module); diff --git a/lib/ChunkRenderError.js b/lib/ChunkRenderError.js index d7e03714fc5..fce913f171a 100644 --- a/lib/ChunkRenderError.js +++ b/lib/ChunkRenderError.js @@ -25,8 +25,6 @@ class ChunkRenderError extends WebpackError { this.details = error.stack; this.file = file; this.chunk = chunk; - - Error.captureStackTrace(this, this.constructor); } } diff --git a/lib/ChunkTemplate.js b/lib/ChunkTemplate.js index e98280f594b..238144a30ac 100644 --- a/lib/ChunkTemplate.js +++ b/lib/ChunkTemplate.js @@ -8,8 +8,21 @@ const util = require("util"); const memoize = require("./util/memoize"); +/** @typedef {import("tapable").Tap} Tap */ /** @typedef {import("../declarations/WebpackOptions").Output} OutputOptions */ +/** @typedef {import("./Chunk")} Chunk */ /** @typedef {import("./Compilation")} Compilation */ +/** @typedef {import("./Compilation").ChunkHashContext} ChunkHashContext */ +/** @typedef {import("./Compilation").Hash} Hash */ +/** @typedef {import("./Compilation").RenderManifestEntry} RenderManifestEntry */ +/** @typedef {import("./Compilation").RenderManifestOptions} RenderManifestOptions */ +/** @typedef {import("./Compilation").Source} Source */ +/** @typedef {import("./ModuleTemplate")} ModuleTemplate */ +/** @typedef {import("./javascript/JavascriptModulesPlugin").RenderContext} RenderContext */ +/** + * @template T + * @typedef {import("tapable").IfSet} IfSet + */ const getJavascriptModulesPlugin = memoize(() => require("./javascript/JavascriptModulesPlugin") @@ -26,6 +39,11 @@ class ChunkTemplate { this.hooks = Object.freeze({ renderManifest: { tap: util.deprecate( + /** + * @template AdditionalOptions + * @param {string | Tap & IfSet} options options + * @param {function(RenderManifestEntry[], RenderManifestOptions): RenderManifestEntry[]} fn function + */ (options, fn) => { compilation.hooks.renderManifest.tap( options, @@ -41,6 +59,11 @@ class ChunkTemplate { }, modules: { tap: util.deprecate( + /** + * @template AdditionalOptions + * @param {string | Tap & IfSet} options options + * @param {function(Source, ModuleTemplate, RenderContext): Source} fn function + */ (options, fn) => { getJavascriptModulesPlugin() .getCompilationHooks(compilation) @@ -58,6 +81,11 @@ class ChunkTemplate { }, render: { tap: util.deprecate( + /** + * @template AdditionalOptions + * @param {string | Tap & IfSet} options options + * @param {function(Source, ModuleTemplate, RenderContext): Source} fn function + */ (options, fn) => { getJavascriptModulesPlugin() .getCompilationHooks(compilation) @@ -75,6 +103,11 @@ class ChunkTemplate { }, renderWithEntry: { tap: util.deprecate( + /** + * @template AdditionalOptions + * @param {string | Tap & IfSet} options options + * @param {function(Source, Chunk): Source} fn function + */ (options, fn) => { getJavascriptModulesPlugin() .getCompilationHooks(compilation) @@ -96,6 +129,11 @@ class ChunkTemplate { }, hash: { tap: util.deprecate( + /** + * @template AdditionalOptions + * @param {string | Tap & IfSet} options options + * @param {function(Hash): void} fn function + */ (options, fn) => { compilation.hooks.fullHash.tap(options, fn); }, @@ -105,6 +143,11 @@ class ChunkTemplate { }, hashForChunk: { tap: util.deprecate( + /** + * @template AdditionalOptions + * @param {string | Tap & IfSet} options options + * @param {function(Hash, Chunk, ChunkHashContext): void} fn function + */ (options, fn) => { getJavascriptModulesPlugin() .getCompilationHooks(compilation) diff --git a/lib/CleanPlugin.js b/lib/CleanPlugin.js index f796e317afc..5c15b328218 100644 --- a/lib/CleanPlugin.js +++ b/lib/CleanPlugin.js @@ -6,45 +6,74 @@ "use strict"; const asyncLib = require("neo-async"); -const { validate } = require("schema-utils"); const { SyncBailHook } = require("tapable"); -const Compilation = require("../lib/Compilation"); +const Compilation = require("./Compilation"); +const createSchemaValidation = require("./util/create-schema-validation"); const { join } = require("./util/fs"); -const memoize = require("./util/memoize"); const processAsyncTree = require("./util/processAsyncTree"); /** @typedef {import("../declarations/WebpackOptions").CleanOptions} CleanOptions */ /** @typedef {import("./Compiler")} Compiler */ /** @typedef {import("./logging/Logger").Logger} Logger */ +/** @typedef {import("./util/fs").IStats} IStats */ /** @typedef {import("./util/fs").OutputFileSystem} OutputFileSystem */ +/** @typedef {import("./util/fs").StatsCallback} StatsCallback */ /** @typedef {(function(string):boolean)|RegExp} IgnoreItem */ +/** @typedef {Map} Assets */ /** @typedef {function(IgnoreItem): void} AddToIgnoreCallback */ /** - * @typedef {Object} CleanPluginCompilationHooks + * @typedef {object} CleanPluginCompilationHooks * @property {SyncBailHook<[string], boolean>} keep when returning true the file/directory will be kept during cleaning, returning false will clean it and ignore the following plugins and config */ -const getSchema = memoize(() => { - const { definitions } = require("../schemas/WebpackOptions.json"); - return { - definitions, - oneOf: [{ $ref: "#/definitions/CleanOptions" }] - }; -}); +/** + * @callback KeepFn + * @param {string} path path + * @returns {boolean} true, if the path should be kept + */ + +const validate = createSchemaValidation( + undefined, + () => { + const { definitions } = require("../schemas/WebpackOptions.json"); + return { + definitions, + oneOf: [{ $ref: "#/definitions/CleanOptions" }] + }; + }, + { + name: "Clean Plugin", + baseDataPath: "options" + } +); +const _10sec = 10 * 1000; + +/** + * marge assets map 2 into map 1 + * @param {Assets} as1 assets + * @param {Assets} as2 assets + * @returns {void} + */ +const mergeAssets = (as1, as2) => { + for (const [key, value1] of as2) { + const value2 = as1.get(key); + if (!value2 || value1 > value2) as1.set(key, value1); + } +}; /** * @param {OutputFileSystem} fs filesystem * @param {string} outputPath output path - * @param {Set} currentAssets filename of the current assets (must not start with .. or ., must only use / as path separator) - * @param {function(Error=, Set=): void} callback returns the filenames of the assets that shouldn't be there + * @param {Map} currentAssets filename of the current assets (must not start with .. or ., must only use / as path separator) + * @param {function((Error | null)=, Set=): void} callback returns the filenames of the assets that shouldn't be there * @returns {void} */ const getDiffToFs = (fs, outputPath, currentAssets, callback) => { const directories = new Set(); // get directories of assets - for (const asset of currentAssets) { + for (const [asset] of currentAssets) { directories.add(asset.replace(/(^|\/)[^/]*$/, "")); } // and all parent directories @@ -56,7 +85,8 @@ const getDiffToFs = (fs, outputPath, currentAssets, callback) => { directories, 10, (directory, callback) => { - fs.readdir(join(fs, outputPath, directory), (err, entries) => { + /** @type {NonNullable} */ + (fs.readdir)(join(fs, outputPath, directory), (err, entries) => { if (err) { if (err.code === "ENOENT") return callback(); if (err.code === "ENOTDIR") { @@ -65,8 +95,8 @@ const getDiffToFs = (fs, outputPath, currentAssets, callback) => { } return callback(err); } - for (const entry of entries) { - const file = /** @type {string} */ (entry); + for (const entry of /** @type {string[]} */ (entries)) { + const file = entry; const filename = directory ? `${directory}/${file}` : file; if (!directories.has(filename) && !currentAssets.has(filename)) { diff.add(filename); @@ -84,18 +114,35 @@ const getDiffToFs = (fs, outputPath, currentAssets, callback) => { }; /** - * @param {Set} currentAssets assets list - * @param {Set} oldAssets old assets list + * @param {Assets} currentAssets assets list + * @param {Assets} oldAssets old assets list * @returns {Set} diff */ const getDiffToOldAssets = (currentAssets, oldAssets) => { const diff = new Set(); - for (const asset of oldAssets) { + const now = Date.now(); + for (const [asset, ts] of oldAssets) { + if (ts >= now) continue; if (!currentAssets.has(asset)) diff.add(asset); } return diff; }; +/** + * @param {OutputFileSystem} fs filesystem + * @param {string} filename path to file + * @param {StatsCallback} callback callback for provided filename + * @returns {void} + */ +const doStat = (fs, filename, callback) => { + if ("lstat" in fs) { + /** @type {NonNullable} */ + (fs.lstat)(filename, callback); + } else { + fs.stat(filename, callback); + } +}; + /** * @param {OutputFileSystem} fs filesystem * @param {string} outputPath output path @@ -103,10 +150,13 @@ const getDiffToOldAssets = (currentAssets, oldAssets) => { * @param {Logger} logger logger * @param {Set} diff filenames of the assets that shouldn't be there * @param {function(string): boolean} isKept check if the entry is ignored - * @param {function(Error=): void} callback callback + * @param {function(Error=, Assets=): void} callback callback * @returns {void} */ const applyDiff = (fs, outputPath, dry, logger, diff, isKept, callback) => { + /** + * @param {string} msg message + */ const log = msg => { if (dry) { logger.info(msg); @@ -116,15 +166,21 @@ const applyDiff = (fs, outputPath, dry, logger, diff, isKept, callback) => { }; /** @typedef {{ type: "check" | "unlink" | "rmdir", filename: string, parent: { remaining: number, job: Job } | undefined }} Job */ /** @type {Job[]} */ - const jobs = Array.from(diff, filename => ({ + const jobs = Array.from(diff.keys(), filename => ({ type: "check", filename, parent: undefined })); + /** @type {Assets} */ + const keptAssets = new Map(); processAsyncTree( jobs, 10, ({ type, filename, parent }, push, callback) => { + /** + * @param {Error & { code?: string }} err error + * @returns {void} + */ const handleError = err => { if (err.code === "ENOENT") { log(`${filename} was removed during cleaning by something else`); @@ -140,13 +196,14 @@ const applyDiff = (fs, outputPath, dry, logger, diff, isKept, callback) => { switch (type) { case "check": if (isKept(filename)) { + keptAssets.set(filename, 0); // do not decrement parent entry as we don't want to delete the parent log(`${filename} will be kept`); return process.nextTick(callback); } - fs.stat(path, (err, stats) => { + doStat(fs, path, (err, stats) => { if (err) return handleError(err); - if (!stats.isDirectory()) { + if (!(/** @type {IStats} */ (stats).isDirectory())) { push({ type: "unlink", filename, @@ -154,7 +211,9 @@ const applyDiff = (fs, outputPath, dry, logger, diff, isKept, callback) => { }); return callback(); } - fs.readdir(path, (err, entries) => { + + /** @type {NonNullable} */ + (fs.readdir)(path, (err, _entries) => { if (err) return handleError(err); /** @type {Job} */ const deleteJob = { @@ -162,6 +221,7 @@ const applyDiff = (fs, outputPath, dry, logger, diff, isKept, callback) => { filename, parent }; + const entries = /** @type {string[]} */ (_entries); if (entries.length === 0) { push(deleteJob); } else { @@ -226,7 +286,10 @@ const applyDiff = (fs, outputPath, dry, logger, diff, isKept, callback) => { break; } }, - callback + err => { + if (err) return callback(err); + callback(undefined, keptAssets); + } ); }; @@ -255,13 +318,9 @@ class CleanPlugin { return hooks; } - /** @param {CleanOptions} [options] options */ + /** @param {CleanOptions} options options */ constructor(options = {}) { - validate(getSchema(), options, { - name: "Clean Plugin", - baseDataPath: "options" - }); - + validate(options); this.options = { dry: false, ...options }; } @@ -273,18 +332,20 @@ class CleanPlugin { apply(compiler) { const { dry, keep } = this.options; + /** @type {KeepFn} */ const keepFn = typeof keep === "function" ? keep : typeof keep === "string" - ? path => path.startsWith(keep) - : typeof keep === "object" && keep.test - ? path => keep.test(path) - : () => false; + ? path => path.startsWith(keep) + : typeof keep === "object" && keep.test + ? path => keep.test(path) + : () => false; // We assume that no external modification happens while the compiler is active // So we can store the old assets and only diff to them to avoid fs access on // incremental builds + /** @type {undefined|Assets} */ let oldAssets; compiler.hooks.emit.tapAsync( @@ -295,7 +356,7 @@ class CleanPlugin { (compilation, callback) => { const hooks = CleanPlugin.getCompilationHooks(compilation); const logger = compilation.getLogger("webpack.CleanPlugin"); - const fs = compiler.outputFileSystem; + const fs = /** @type {OutputFileSystem} */ (compiler.outputFileSystem); if (!fs.readdir) { return callback( @@ -305,7 +366,9 @@ class CleanPlugin { ); } - const currentAssets = new Set(); + /** @type {Assets} */ + const currentAssets = new Map(); + const now = Date.now(); for (const asset of Object.keys(compilation.assets)) { if (/^[A-Za-z]:\\|^\/|^\\\\/.test(asset)) continue; let normalizedAsset; @@ -318,30 +381,54 @@ class CleanPlugin { ); } while (newNormalizedAsset !== normalizedAsset); if (normalizedAsset.startsWith("../")) continue; - currentAssets.add(normalizedAsset); + const assetInfo = compilation.assetsInfo.get(asset); + if (assetInfo && assetInfo.hotModuleReplacement) { + currentAssets.set(normalizedAsset, now + _10sec); + } else { + currentAssets.set(normalizedAsset, 0); + } } const outputPath = compilation.getPath(compiler.outputPath, {}); + /** + * @param {string} path path + * @returns {boolean} true, if needs to be kept + */ const isKept = path => { const result = hooks.keep.call(path); if (result !== undefined) return result; return keepFn(path); }; + /** + * @param {(Error | null)=} err err + * @param {Set=} diff diff + */ const diffCallback = (err, diff) => { if (err) { oldAssets = undefined; - return callback(err); + callback(err); + return; } - applyDiff(fs, outputPath, dry, logger, diff, isKept, err => { - if (err) { - oldAssets = undefined; - } else { - oldAssets = currentAssets; + applyDiff( + fs, + outputPath, + dry, + logger, + /** @type {Set} */ (diff), + isKept, + (err, keptAssets) => { + if (err) { + oldAssets = undefined; + } else { + if (oldAssets) mergeAssets(currentAssets, oldAssets); + oldAssets = currentAssets; + if (keptAssets) mergeAssets(oldAssets, keptAssets); + } + callback(err); } - callback(err); - }); + ); }; if (oldAssets) { diff --git a/lib/CodeGenerationError.js b/lib/CodeGenerationError.js index 144afe0eed1..b1cf51d744e 100644 --- a/lib/CodeGenerationError.js +++ b/lib/CodeGenerationError.js @@ -23,8 +23,6 @@ class CodeGenerationError extends WebpackError { this.message = error.message; this.details = error.stack; this.module = module; - - Error.captureStackTrace(this, this.constructor); } } diff --git a/lib/CodeGenerationResults.js b/lib/CodeGenerationResults.js index 2de8455a847..f0759985e76 100644 --- a/lib/CodeGenerationResults.js +++ b/lib/CodeGenerationResults.js @@ -5,7 +5,7 @@ "use strict"; -const { provide } = require("./util/MapHelpers"); +const { getOrInsert } = require("./util/MapHelpers"); const { first } = require("./util/SetHelpers"); const createHash = require("./util/createHash"); const { runtimeToString, RuntimeSpecMap } = require("./util/runtime"); @@ -13,12 +13,17 @@ const { runtimeToString, RuntimeSpecMap } = require("./util/runtime"); /** @typedef {import("webpack-sources").Source} Source */ /** @typedef {import("./Module")} Module */ /** @typedef {import("./Module").CodeGenerationResult} CodeGenerationResult */ +/** @typedef {typeof import("./util/Hash")} Hash */ /** @typedef {import("./util/runtime").RuntimeSpec} RuntimeSpec */ class CodeGenerationResults { - constructor() { + /** + * @param {string | Hash} hashFunction the hash function to use + */ + constructor(hashFunction = "md4") { /** @type {Map>} */ this.map = new Map(); + this._hashFunction = hashFunction; } /** @@ -37,7 +42,9 @@ class CodeGenerationResults { ); } if (runtime === undefined) { - if (entry.size > 1) { + if ( + /** @type {RuntimeSpecMap} */ (entry).size > 1 + ) { const results = new Set(entry.values()); if (results.size !== 1) { throw new Error( @@ -48,9 +55,9 @@ class CodeGenerationResults { Caller might not support runtime-dependent code generation (opt-out via optimization.usedExports: "global").` ); } - return first(results); + return /** @type {CodeGenerationResult} */ (first(results)); } - return entry.values().next().value; + return /** @type {CodeGenerationResult} */ (entry.values().next().value); } const result = entry.get(runtime); if (result === undefined) { @@ -81,9 +88,8 @@ Caller might not support runtime-dependent code generation (opt-out via optimiza } else if (entry.size > 1) { const results = new Set(entry.values()); return results.size === 1; - } else { - return entry.size === 1; } + return entry.size === 1; } /** @@ -124,7 +130,7 @@ Caller might not support runtime-dependent code generation (opt-out via optimiza getHash(module, runtime) { const info = this.get(module, runtime); if (info.hash !== undefined) return info.hash; - const hash = createHash("md4"); + const hash = createHash(this._hashFunction); for (const [type, source] of info.sources) { hash.update(type); source.updateHash(hash); @@ -142,7 +148,7 @@ Caller might not support runtime-dependent code generation (opt-out via optimiza * @returns {void} */ add(module, runtime, result) { - const map = provide(this.map, module, () => new RuntimeSpecMap()); + const map = getOrInsert(this.map, module, () => new RuntimeSpecMap()); map.set(runtime, result); } } diff --git a/lib/CommentCompilationWarning.js b/lib/CommentCompilationWarning.js index 7aa47c763b8..99cd0fbdada 100644 --- a/lib/CommentCompilationWarning.js +++ b/lib/CommentCompilationWarning.js @@ -12,7 +12,6 @@ const makeSerializable = require("./util/makeSerializable"); class CommentCompilationWarning extends WebpackError { /** - * * @param {string} message warning message * @param {DependencyLocation} loc affected lines of code */ @@ -22,8 +21,6 @@ class CommentCompilationWarning extends WebpackError { this.name = "CommentCompilationWarning"; this.loc = loc; - - Error.captureStackTrace(this, this.constructor); } } diff --git a/lib/CompatibilityPlugin.js b/lib/CompatibilityPlugin.js index b86a64ea54c..46ddd7e802e 100644 --- a/lib/CompatibilityPlugin.js +++ b/lib/CompatibilityPlugin.js @@ -5,12 +5,22 @@ "use strict"; +const { + JAVASCRIPT_MODULE_TYPE_AUTO, + JAVASCRIPT_MODULE_TYPE_DYNAMIC, + JAVASCRIPT_MODULE_TYPE_ESM +} = require("./ModuleTypeConstants"); +const RuntimeGlobals = require("./RuntimeGlobals"); const ConstDependency = require("./dependencies/ConstDependency"); +/** @typedef {import("estree").CallExpression} CallExpression */ /** @typedef {import("./Compiler")} Compiler */ +/** @typedef {import("./Dependency").DependencyLocation} DependencyLocation */ /** @typedef {import("./javascript/JavascriptParser")} JavascriptParser */ +/** @typedef {import("./javascript/JavascriptParser").Range} Range */ -const nestedWebpackRequireTag = Symbol("nested __webpack_require__"); +const nestedWebpackIdentifierTag = Symbol("nested webpack identifier"); +const PLUGIN_NAME = "CompatibilityPlugin"; class CompatibilityPlugin { /** @@ -20,7 +30,7 @@ class CompatibilityPlugin { */ apply(compiler) { compiler.hooks.compilation.tap( - "CompatibilityPlugin", + PLUGIN_NAME, (compilation, { normalModuleFactory }) => { compilation.dependencyTemplates.set( ConstDependency, @@ -28,24 +38,31 @@ class CompatibilityPlugin { ); normalModuleFactory.hooks.parser - .for("javascript/auto") - .tap("CompatibilityPlugin", (parser, parserOptions) => { + .for(JAVASCRIPT_MODULE_TYPE_AUTO) + .tap(PLUGIN_NAME, (parser, parserOptions) => { if ( parserOptions.browserify !== undefined && !parserOptions.browserify ) return; - parser.hooks.call - .for("require") - .tap("CompatibilityPlugin", expr => { + parser.hooks.call.for("require").tap( + PLUGIN_NAME, + /** + * @param {CallExpression} expr call expression + * @returns {boolean | void} true when need to handle + */ + expr => { // support for browserify style require delegator: "require(o, !0)" if (expr.arguments.length !== 2) return; const second = parser.evaluateExpression(expr.arguments[1]); if (!second.isBoolean()) return; if (second.asBool() !== true) return; - const dep = new ConstDependency("require", expr.callee.range); - dep.loc = expr.loc; + const dep = new ConstDependency( + "require", + /** @type {Range} */ (expr.callee.range) + ); + dep.loc = /** @type {DependencyLocation} */ (expr.loc); if (parser.state.current.dependencies.length > 0) { const last = parser.state.current.dependencies[ @@ -62,38 +79,61 @@ class CompatibilityPlugin { } parser.state.module.addPresentationalDependency(dep); return true; - }); + } + ); }); /** * @param {JavascriptParser} parser the parser * @returns {void} */ - const nestedWebpackRequireHandler = parser => { - parser.hooks.preStatement.tap("CompatibilityPlugin", statement => { + const handler = parser => { + // Handle nested requires + parser.hooks.preStatement.tap(PLUGIN_NAME, statement => { if ( statement.type === "FunctionDeclaration" && statement.id && - statement.id.name === "__webpack_require__" + statement.id.name === RuntimeGlobals.require ) { - const newName = `__nested_webpack_require_${statement.range[0]}__`; - parser.tagVariable(statement.id.name, nestedWebpackRequireTag, { + const newName = `__nested_webpack_require_${ + /** @type {Range} */ (statement.range)[0] + }__`; + parser.tagVariable( + statement.id.name, + nestedWebpackIdentifierTag, + { + name: newName, + declaration: { + updated: false, + loc: statement.id.loc, + range: statement.id.range + } + } + ); + return true; + } + }); + parser.hooks.pattern + .for(RuntimeGlobals.require) + .tap(PLUGIN_NAME, pattern => { + const newName = `__nested_webpack_require_${ + /** @type {Range} */ (pattern.range)[0] + }__`; + parser.tagVariable(pattern.name, nestedWebpackIdentifierTag, { name: newName, declaration: { updated: false, - loc: statement.id.loc, - range: statement.id.range + loc: pattern.loc, + range: pattern.range } }); return true; - } - }); + }); parser.hooks.pattern - .for("__webpack_require__") - .tap("CompatibilityPlugin", pattern => { - const newName = `__nested_webpack_require_${pattern.range[0]}__`; - parser.tagVariable(pattern.name, nestedWebpackRequireTag, { - name: newName, + .for(RuntimeGlobals.exports) + .tap(PLUGIN_NAME, pattern => { + parser.tagVariable(pattern.name, nestedWebpackIdentifierTag, { + name: "__nested_webpack_exports__", declaration: { updated: false, loc: pattern.loc, @@ -103,8 +143,8 @@ class CompatibilityPlugin { return true; }); parser.hooks.expression - .for(nestedWebpackRequireTag) - .tap("CompatibilityPlugin", expr => { + .for(nestedWebpackIdentifierTag) + .tap(PLUGIN_NAME, expr => { const { name, declaration } = parser.currentTagData; if (!declaration.updated) { const dep = new ConstDependency(name, declaration.range); @@ -112,22 +152,38 @@ class CompatibilityPlugin { parser.state.module.addPresentationalDependency(dep); declaration.updated = true; } - const dep = new ConstDependency(name, expr.range); - dep.loc = expr.loc; + const dep = new ConstDependency( + name, + /** @type {Range} */ (expr.range) + ); + dep.loc = /** @type {DependencyLocation} */ (expr.loc); parser.state.module.addPresentationalDependency(dep); return true; }); + + // Handle hashbang + parser.hooks.program.tap(PLUGIN_NAME, (program, comments) => { + if (comments.length === 0) return; + const c = comments[0]; + if (c.type === "Line" && /** @type {Range} */ (c.range)[0] === 0) { + if (parser.state.source.slice(0, 2).toString() !== "#!") return; + // this is a hashbang comment + const dep = new ConstDependency("//", 0); + dep.loc = /** @type {DependencyLocation} */ (c.loc); + parser.state.module.addPresentationalDependency(dep); + } + }); }; normalModuleFactory.hooks.parser - .for("javascript/auto") - .tap("CompatibilityPlugin", nestedWebpackRequireHandler); + .for(JAVASCRIPT_MODULE_TYPE_AUTO) + .tap(PLUGIN_NAME, handler); normalModuleFactory.hooks.parser - .for("javascript/dynamic") - .tap("CompatibilityPlugin", nestedWebpackRequireHandler); + .for(JAVASCRIPT_MODULE_TYPE_DYNAMIC) + .tap(PLUGIN_NAME, handler); normalModuleFactory.hooks.parser - .for("javascript/esm") - .tap("CompatibilityPlugin", nestedWebpackRequireHandler); + .for(JAVASCRIPT_MODULE_TYPE_ESM) + .tap(PLUGIN_NAME, handler); } ); } diff --git a/lib/Compilation.js b/lib/Compilation.js index 5a458df260a..124974b0366 100644 --- a/lib/Compilation.js +++ b/lib/Compilation.js @@ -12,7 +12,8 @@ const { SyncBailHook, SyncWaterfallHook, AsyncSeriesHook, - AsyncSeriesBailHook + AsyncSeriesBailHook, + AsyncParallelHook } = require("tapable"); const util = require("util"); const { CachedSource } = require("webpack-sources"); @@ -24,6 +25,7 @@ const ChunkRenderError = require("./ChunkRenderError"); const ChunkTemplate = require("./ChunkTemplate"); const CodeGenerationError = require("./CodeGenerationError"); const CodeGenerationResults = require("./CodeGenerationResults"); +const Dependency = require("./Dependency"); const DependencyTemplates = require("./DependencyTemplates"); const Entrypoint = require("./Entrypoint"); const ErrorHelpers = require("./ErrorHelpers"); @@ -32,17 +34,22 @@ const { connectChunkGroupAndChunk, connectChunkGroupParentAndChild } = require("./GraphHelpers"); -const { makeWebpackError } = require("./HookWebpackError"); +const { + makeWebpackError, + tryRunOrWebpackError +} = require("./HookWebpackError"); const MainTemplate = require("./MainTemplate"); const Module = require("./Module"); const ModuleDependencyError = require("./ModuleDependencyError"); const ModuleDependencyWarning = require("./ModuleDependencyWarning"); const ModuleGraph = require("./ModuleGraph"); +const ModuleHashingError = require("./ModuleHashingError"); const ModuleNotFoundError = require("./ModuleNotFoundError"); const ModuleProfile = require("./ModuleProfile"); const ModuleRestoreError = require("./ModuleRestoreError"); const ModuleStoreError = require("./ModuleStoreError"); const ModuleTemplate = require("./ModuleTemplate"); +const { WEBPACK_MODULE_TYPE_RUNTIME } = require("./ModuleTypeConstants"); const RuntimeGlobals = require("./RuntimeGlobals"); const RuntimeTemplate = require("./RuntimeTemplate"); const Stats = require("./Stats"); @@ -55,7 +62,8 @@ const StatsPrinter = require("./stats/StatsPrinter"); const { equals: arrayEquals } = require("./util/ArrayHelpers"); const AsyncQueue = require("./util/AsyncQueue"); const LazySet = require("./util/LazySet"); -const { provide } = require("./util/MapHelpers"); +const { getOrInsert } = require("./util/MapHelpers"); +const WeakTupleMap = require("./util/WeakTupleMap"); const { cachedCleverMerge } = require("./util/cleverMerge"); const { compareLocations, @@ -71,6 +79,7 @@ const { soonFrozenObjectDeprecation, createFakeHook } = require("./util/deprecation"); +const processAsyncTree = require("./util/processAsyncTree"); const { getRuntimeKey } = require("./util/runtime"); const { isSourceEqual } = require("./util/source"); @@ -79,22 +88,28 @@ const { isSourceEqual } = require("./util/source"); /** @typedef {import("../declarations/WebpackOptions").EntryDescriptionNormalized} EntryDescription */ /** @typedef {import("../declarations/WebpackOptions").OutputNormalized} OutputOptions */ /** @typedef {import("../declarations/WebpackOptions").StatsOptions} StatsOptions */ +/** @typedef {import("../declarations/WebpackOptions").WebpackOptionsNormalized} WebpackOptions */ /** @typedef {import("../declarations/WebpackOptions").WebpackPluginFunction} WebpackPluginFunction */ /** @typedef {import("../declarations/WebpackOptions").WebpackPluginInstance} WebpackPluginInstance */ /** @typedef {import("./AsyncDependenciesBlock")} AsyncDependenciesBlock */ /** @typedef {import("./Cache")} Cache */ /** @typedef {import("./CacheFacade")} CacheFacade */ +/** @typedef {import("./Chunk").ChunkId} ChunkId */ /** @typedef {import("./ChunkGroup").ChunkGroupOptions} ChunkGroupOptions */ /** @typedef {import("./Compiler")} Compiler */ +/** @typedef {import("./Compiler").CompilationParams} CompilationParams */ /** @typedef {import("./DependenciesBlock")} DependenciesBlock */ -/** @typedef {import("./Dependency")} Dependency */ /** @typedef {import("./Dependency").DependencyLocation} DependencyLocation */ /** @typedef {import("./Dependency").ReferencedExport} ReferencedExport */ /** @typedef {import("./DependencyTemplate")} DependencyTemplate */ /** @typedef {import("./Entrypoint").EntryOptions} EntryOptions */ +/** @typedef {import("./Module").BuildInfo} BuildInfo */ +/** @typedef {import("./NormalModule").NormalModuleCompilationHooks} NormalModuleCompilationHooks */ /** @typedef {import("./Module").CodeGenerationResult} CodeGenerationResult */ /** @typedef {import("./ModuleFactory")} ModuleFactory */ +/** @typedef {import("./ModuleGraphConnection")} ModuleGraphConnection */ /** @typedef {import("./ModuleFactory").ModuleFactoryCreateDataContextInfo} ModuleFactoryCreateDataContextInfo */ +/** @typedef {import("./ModuleFactory").ModuleFactoryResult} ModuleFactoryResult */ /** @typedef {import("./RequestShortener")} RequestShortener */ /** @typedef {import("./RuntimeModule")} RuntimeModule */ /** @typedef {import("./Template").RenderManifestEntry} RenderManifestEntry */ @@ -102,20 +117,46 @@ const { isSourceEqual } = require("./util/source"); /** @typedef {import("./stats/DefaultStatsFactoryPlugin").StatsAsset} StatsAsset */ /** @typedef {import("./stats/DefaultStatsFactoryPlugin").StatsError} StatsError */ /** @typedef {import("./stats/DefaultStatsFactoryPlugin").StatsModule} StatsModule */ +/** @typedef {import("./TemplatedPathPlugin").TemplatePath} TemplatePath */ /** @typedef {import("./util/Hash")} Hash */ -/** @template T @typedef {import("./util/deprecation").FakeHook} FakeHook */ +/** + * @template T + * @typedef {import("./util/deprecation").FakeHook} FakeHook + */ /** @typedef {import("./util/runtime").RuntimeSpec} RuntimeSpec */ - +/** @typedef {WeakMap} References */ +/** @typedef {import("./util/fs").InputFileSystem} InputFileSystem */ /** * @callback Callback - * @param {WebpackError=} err + * @param {(WebpackError | null)=} err * @returns {void} */ /** * @callback ModuleCallback - * @param {WebpackError=} err - * @param {Module=} result + * @param {(WebpackError | null)=} err + * @param {(Module | null)=} result + * @returns {void} + */ + +/** + * @callback ModuleFactoryResultCallback + * @param {(WebpackError | null)=} err + * @param {ModuleFactoryResult=} result + * @returns {void} + */ + +/** + * @callback ModuleOrFactoryResultCallback + * @param {(WebpackError | null)=} err + * @param {Module | ModuleFactoryResult=} result + * @returns {void} + */ + +/** + * @callback ExecuteModuleCallback + * @param {WebpackError | null} err + * @param {ExecuteModuleResult=} result * @returns {void} */ @@ -129,20 +170,20 @@ const { isSourceEqual } = require("./util/source"); /** @typedef {Record} CompilationAssets */ /** - * @typedef {Object} AvailableModulesChunkGroupMapping + * @typedef {object} AvailableModulesChunkGroupMapping * @property {ChunkGroup} chunkGroup * @property {Set} availableModules * @property {boolean} needCopy */ /** - * @typedef {Object} DependenciesBlockLike + * @typedef {object} DependenciesBlockLike * @property {Dependency[]} dependencies * @property {AsyncDependenciesBlock[]} blocks */ /** - * @typedef {Object} ChunkPathData + * @typedef {object} ChunkPathData * @property {string|number} id * @property {string=} name * @property {string} hash @@ -152,29 +193,68 @@ const { isSourceEqual } = require("./util/source"); */ /** - * @typedef {Object} ChunkHashContext + * @typedef {object} ChunkHashContext + * @property {CodeGenerationResults} codeGenerationResults results of code generation * @property {RuntimeTemplate} runtimeTemplate the runtime template * @property {ModuleGraph} moduleGraph the module graph * @property {ChunkGraph} chunkGraph the chunk graph */ /** - * @typedef {Object} EntryData + * @typedef {object} RuntimeRequirementsContext + * @property {ChunkGraph} chunkGraph the chunk graph + * @property {CodeGenerationResults} codeGenerationResults the code generation results + */ + +/** + * @typedef {object} ExecuteModuleOptions + * @property {EntryOptions=} entryOptions + */ + +/** + * @typedef {object} ExecuteModuleResult + * @property {any} exports + * @property {boolean} cacheable + * @property {Map} assets + * @property {LazySet} fileDependencies + * @property {LazySet} contextDependencies + * @property {LazySet} missingDependencies + * @property {LazySet} buildDependencies + */ + +/** + * @typedef {object} ExecuteModuleArgument + * @property {Module} module + * @property {{ id: string, exports: any, loaded: boolean }=} moduleObject + * @property {any} preparedInfo + * @property {CodeGenerationResult} codeGenerationResult + */ + +/** + * @typedef {object} ExecuteModuleContext + * @property {Map} assets + * @property {Chunk} chunk + * @property {ChunkGraph} chunkGraph + * @property {function(string): any=} __webpack_require__ + */ + +/** + * @typedef {object} EntryData * @property {Dependency[]} dependencies dependencies of the entrypoint that should be evaluated at startup * @property {Dependency[]} includeDependencies dependencies of the entrypoint that should be included but not evaluated * @property {EntryOptions} options options of the entrypoint */ /** - * @typedef {Object} LogEntry + * @typedef {object} LogEntry * @property {string} type - * @property {any[]} args + * @property {any[]=} args * @property {number} time * @property {string[]=} trace */ /** - * @typedef {Object} KnownAssetInfo + * @typedef {object} KnownAssetInfo * @property {boolean=} immutable true, if the asset can be long term cached forever (contains a hash) * @property {boolean=} minimized whether the asset is minimized * @property {string | string[]=} fullhash the value(s) of the full hash used for this asset @@ -191,22 +271,24 @@ const { isSourceEqual } = require("./util/source"); /** @typedef {KnownAssetInfo & Record} AssetInfo */ +/** @typedef {{ path: string, info: AssetInfo }} InterpolatedPathAndAssetInfo */ + /** - * @typedef {Object} Asset + * @typedef {object} Asset * @property {string} name the filename of the asset * @property {Source} source source of the asset * @property {AssetInfo} info info about the asset */ /** - * @typedef {Object} ModulePathData + * @typedef {object} ModulePathData * @property {string|number} id * @property {string} hash * @property {function(number): string=} hashWithLength */ /** - * @typedef {Object} PathData + * @typedef {object} PathData * @property {ChunkGraph=} chunkGraph * @property {string=} hash * @property {function(number): string=} hashWithLength @@ -224,7 +306,7 @@ const { isSourceEqual } = require("./util/source"); */ /** - * @typedef {Object} KnownNormalizedStatsOptions + * @typedef {object} KnownNormalizedStatsOptions * @property {string} context * @property {RequestShortener} requestShortener * @property {string} chunksSort @@ -268,49 +350,70 @@ const { isSourceEqual } = require("./util/source"); /** @typedef {KnownNormalizedStatsOptions & Omit & Record} NormalizedStatsOptions */ /** - * @typedef {Object} KnownCreateStatsOptionsContext + * @typedef {object} KnownCreateStatsOptionsContext * @property {boolean=} forToString */ -/** @typedef {KnownCreateStatsOptionsContext & Record} CreateStatsOptionsContext */ +/** @typedef {Record & KnownCreateStatsOptionsContext} CreateStatsOptionsContext */ + +/** @typedef {{module: Module, hash: string, runtime: RuntimeSpec, runtimes: RuntimeSpec[]}[]} CodeGenerationJobs */ + +/** @typedef {{javascript: ModuleTemplate}} ModuleTemplates */ + +/** @typedef {Set} NotCodeGeneratedModules */ + +/** @typedef {string | Set | undefined} ValueCacheVersion */ /** @type {AssetInfo} */ const EMPTY_ASSET_INFO = Object.freeze({}); const esmDependencyCategory = "esm"; + // TODO webpack 6: remove const deprecatedNormalModuleLoaderHook = util.deprecate( - compilation => { - return require("./NormalModule").getCompilationHooks(compilation).loader; - }, + /** + * @param {Compilation} compilation compilation + * @returns {NormalModuleCompilationHooks["loader"]} hooks + */ + compilation => + require("./NormalModule").getCompilationHooks(compilation).loader, "Compilation.hooks.normalModuleLoader was moved to NormalModule.getCompilationHooks(compilation).loader", "DEP_WEBPACK_COMPILATION_NORMAL_MODULE_LOADER_HOOK" ); -const byId = compareSelect( - /** - * @param {Chunk} c chunk - * @returns {number | string} id - */ c => c.id, - compareIds -); +// TODO webpack 6: remove +/** + * @param {ModuleTemplates | undefined} moduleTemplates module templates + */ +const defineRemovedModuleTemplates = moduleTemplates => { + Object.defineProperties(moduleTemplates, { + asset: { + enumerable: false, + configurable: false, + get: () => { + throw new WebpackError( + "Compilation.moduleTemplates.asset has been removed" + ); + } + }, + webassembly: { + enumerable: false, + configurable: false, + get: () => { + throw new WebpackError( + "Compilation.moduleTemplates.webassembly has been removed" + ); + } + } + }); + moduleTemplates = undefined; +}; + +const byId = compareSelect(c => c.id, compareIds); const byNameOrHash = concatComparators( - compareSelect( - /** - * @param {Compilation} c compilation - * @returns {string} name - */ - c => c.name, - compareIds - ), - compareSelect( - /** - * @param {Compilation} c compilation - * @returns {string} hash - */ c => c.fullHash, - compareIds - ) + compareSelect(c => c.name, compareIds), + compareSelect(c => c.fullHash, compareIds) ); const byMessage = compareSelect(err => `${err.message}`, compareStringsNumeric); @@ -324,20 +427,33 @@ const byLocation = compareSelect(err => err.loc, compareLocations); const compareErrors = concatComparators(byModule, byLocation, byMessage); +/** @type {WeakMap} */ +const unsafeCacheDependencies = new WeakMap(); + +/** @type {WeakMap} */ +const unsafeCacheData = new WeakMap(); + class Compilation { /** * Creates an instance of Compilation. * @param {Compiler} compiler the compiler which created the compilation + * @param {CompilationParams} params the compilation parameters */ - constructor(compiler) { + constructor(compiler, params) { + this._backCompat = compiler._backCompat; + const getNormalModuleLoader = () => deprecatedNormalModuleLoaderHook(this); /** @typedef {{ additionalAssets?: true | Function }} ProcessAssetsAdditionalOptions */ /** @type {AsyncSeriesHook<[CompilationAssets], ProcessAssetsAdditionalOptions>} */ const processAssetsHook = new AsyncSeriesHook(["assets"]); let savedAssets = new Set(); + /** + * @param {CompilationAssets} assets assets + * @returns {CompilationAssets} new assets + */ const popNewAssets = assets => { - let newAssets = undefined; + let newAssets; for (const file of Object.keys(assets)) { if (savedAssets.has(file)) continue; if (newAssets === undefined) { @@ -358,12 +474,13 @@ class Compilation { const { fn, additionalAssets, ...remainingTap } = tap; const additionalAssetsFn = additionalAssets === true ? fn : additionalAssets; - let processedAssets = undefined; + const processedAssets = additionalAssetsFn ? new WeakSet() : undefined; switch (type) { case "sync": if (additionalAssetsFn) { this.hooks.processAdditionalAssets.tap(name, assets => { - if (processedAssets === this.assets) additionalAssetsFn(assets); + if (processedAssets.has(this.assets)) + additionalAssetsFn(assets); }); } return { @@ -372,10 +489,11 @@ class Compilation { fn: (assets, callback) => { try { fn(assets); - } catch (e) { - return callback(e); + } catch (err) { + return callback(err); } - processedAssets = this.assets; + if (processedAssets !== undefined) + processedAssets.add(this.assets); const newAssets = popNewAssets(assets); if (newAssets !== undefined) { this.hooks.processAdditionalAssets.callAsync( @@ -392,7 +510,7 @@ class Compilation { this.hooks.processAdditionalAssets.tapAsync( name, (assets, callback) => { - if (processedAssets === this.assets) + if (processedAssets.has(this.assets)) return additionalAssetsFn(assets, callback); callback(); } @@ -403,7 +521,8 @@ class Compilation { fn: (assets, callback) => { fn(assets, err => { if (err) return callback(err); - processedAssets = this.assets; + if (processedAssets !== undefined) + processedAssets.add(this.assets); const newAssets = popNewAssets(assets); if (newAssets !== undefined) { this.hooks.processAdditionalAssets.callAsync( @@ -419,7 +538,7 @@ class Compilation { case "promise": if (additionalAssetsFn) { this.hooks.processAdditionalAssets.tapPromise(name, assets => { - if (processedAssets === this.assets) + if (processedAssets.has(this.assets)) return additionalAssetsFn(assets); return Promise.resolve(); }); @@ -430,7 +549,8 @@ class Compilation { const p = fn(assets); if (!p || !p.then) return p; return p.then(() => { - processedAssets = this.assets; + if (processedAssets !== undefined) + processedAssets.add(this.assets); const newAssets = popNewAssets(assets); if (newAssets !== undefined) { return this.hooks.processAdditionalAssets.promise( @@ -456,14 +576,20 @@ class Compilation { * @returns {FakeHook, "tap" | "tapAsync" | "tapPromise" | "name">>} fake hook which redirects */ const createProcessAssetsHook = (name, stage, getArgs, code) => { - const errorMessage = reason => `Can't automatically convert plugin using Compilation.hooks.${name} to Compilation.hooks.processAssets because ${reason}. + if (!this._backCompat && code) return; + /** + * @param {string} reason reason + * @returns {string} error message + */ + const errorMessage = + reason => `Can't automatically convert plugin using Compilation.hooks.${name} to Compilation.hooks.processAssets because ${reason}. BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a single Compilation.hooks.processAssets hook.`; const getOptions = options => { if (typeof options === "string") options = { name: options }; if (options.stage) { throw new Error(errorMessage("it's using the 'stage' option")); } - return { ...options, stage: stage }; + return { ...options, stage }; }; return createFakeHook( { @@ -521,6 +647,11 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si "runtime" ]), + /** @type {SyncHook<[ExecuteModuleArgument, ExecuteModuleContext]>} */ + executeModule: new SyncHook(["options", "context"]), + /** @type {AsyncParallelHook<[ExecuteModuleArgument, ExecuteModuleContext]>} */ + prepareModuleExecution: new AsyncParallelHook(["options", "context"]), + /** @type {AsyncSeriesHook<[Iterable]>} */ finishModules: new AsyncSeriesHook(["modules"]), /** @type {AsyncSeriesHook<[Module]>} */ @@ -532,22 +663,27 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si /** @type {SyncHook<[]>} */ beforeChunks: new SyncHook([]), - /** @type {SyncHook<[Iterable]>} */ + /** + * The `afterChunks` hook is called directly after the chunks and module graph have + * been created and before the chunks and modules have been optimized. This hook is useful to + * inspect, analyze, and/or modify the chunk graph. + * @type {SyncHook<[Iterable]>} + */ afterChunks: new SyncHook(["chunks"]), - /** @type {SyncBailHook<[Iterable]>} */ + /** @type {SyncBailHook<[Iterable], boolean | void>} */ optimizeDependencies: new SyncBailHook(["modules"]), /** @type {SyncHook<[Iterable]>} */ afterOptimizeDependencies: new SyncHook(["modules"]), /** @type {SyncHook<[]>} */ optimize: new SyncHook([]), - /** @type {SyncBailHook<[Iterable]>} */ + /** @type {SyncBailHook<[Iterable], boolean | void>} */ optimizeModules: new SyncBailHook(["modules"]), /** @type {SyncHook<[Iterable]>} */ afterOptimizeModules: new SyncHook(["modules"]), - /** @type {SyncBailHook<[Iterable, ChunkGroup[]]>} */ + /** @type {SyncBailHook<[Iterable, ChunkGroup[]], boolean | void>} */ optimizeChunks: new SyncBailHook(["chunks", "chunkGroups"]), /** @type {SyncHook<[Iterable, ChunkGroup[]]>} */ afterOptimizeChunks: new SyncHook(["chunks", "chunkGroups"]), @@ -557,39 +693,42 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si /** @type {SyncHook<[Iterable, Iterable]>} */ afterOptimizeTree: new SyncHook(["chunks", "modules"]), - /** @type {AsyncSeriesBailHook<[Iterable, Iterable]>} */ + /** @type {AsyncSeriesBailHook<[Iterable, Iterable], void>} */ optimizeChunkModules: new AsyncSeriesBailHook(["chunks", "modules"]), /** @type {SyncHook<[Iterable, Iterable]>} */ afterOptimizeChunkModules: new SyncHook(["chunks", "modules"]), - /** @type {SyncBailHook<[], boolean>} */ + /** @type {SyncBailHook<[], boolean | undefined>} */ shouldRecord: new SyncBailHook([]), - /** @type {SyncHook<[Chunk, Set]>} */ + /** @type {SyncHook<[Chunk, Set, RuntimeRequirementsContext]>} */ additionalChunkRuntimeRequirements: new SyncHook([ "chunk", - "runtimeRequirements" + "runtimeRequirements", + "context" ]), - /** @type {HookMap]>>} */ + /** @type {HookMap, RuntimeRequirementsContext], void>>} */ runtimeRequirementInChunk: new HookMap( - () => new SyncBailHook(["chunk", "runtimeRequirements"]) + () => new SyncBailHook(["chunk", "runtimeRequirements", "context"]) ), - /** @type {SyncHook<[Module, Set]>} */ + /** @type {SyncHook<[Module, Set, RuntimeRequirementsContext]>} */ additionalModuleRuntimeRequirements: new SyncHook([ "module", - "runtimeRequirements" + "runtimeRequirements", + "context" ]), - /** @type {HookMap]>>} */ + /** @type {HookMap, RuntimeRequirementsContext], void>>} */ runtimeRequirementInModule: new HookMap( - () => new SyncBailHook(["module", "runtimeRequirements"]) + () => new SyncBailHook(["module", "runtimeRequirements", "context"]) ), - /** @type {SyncHook<[Chunk, Set]>} */ + /** @type {SyncHook<[Chunk, Set, RuntimeRequirementsContext]>} */ additionalTreeRuntimeRequirements: new SyncHook([ "chunk", - "runtimeRequirements" + "runtimeRequirements", + "context" ]), - /** @type {HookMap]>>} */ + /** @type {HookMap, RuntimeRequirementsContext], void>>} */ runtimeRequirementInTree: new HookMap( - () => new SyncBailHook(["chunk", "runtimeRequirements"]) + () => new SyncBailHook(["chunk", "runtimeRequirements", "context"]) ), /** @type {SyncHook<[RuntimeModule, Chunk]>} */ @@ -701,7 +840,7 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si /** @type {AsyncSeriesHook<[CompilationAssets]>} */ processAdditionalAssets: new AsyncSeriesHook(["assets"]), - /** @type {SyncBailHook<[], boolean>} */ + /** @type {SyncBailHook<[], boolean | undefined>} */ needAdditionalSeal: new SyncBailHook([]), /** @type {AsyncSeriesHook<[]>} */ afterSeal: new AsyncSeriesHook([]), @@ -719,7 +858,7 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si /** @type {SyncHook<[Chunk, string]>} */ chunkAsset: new SyncHook(["chunk", "filename"]), - /** @type {SyncWaterfallHook<[string, object, AssetInfo]>} */ + /** @type {SyncWaterfallHook<[string, object, AssetInfo | undefined]>} */ assetPath: new SyncWaterfallHook(["path", "options", "assetInfo"]), /** @type {SyncBailHook<[], boolean>} */ @@ -755,31 +894,41 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si }); /** @type {string=} */ this.name = undefined; + /** @type {number | undefined} */ this.startTime = undefined; + /** @type {number | undefined} */ this.endTime = undefined; /** @type {Compiler} */ this.compiler = compiler; this.resolverFactory = compiler.resolverFactory; - this.inputFileSystem = compiler.inputFileSystem; + /** @type {InputFileSystem} */ + this.inputFileSystem = + /** @type {InputFileSystem} */ + (compiler.inputFileSystem); this.fileSystemInfo = new FileSystemInfo(this.inputFileSystem, { + unmanagedPaths: compiler.unmanagedPaths, managedPaths: compiler.managedPaths, immutablePaths: compiler.immutablePaths, - logger: this.getLogger("webpack.FileSystemInfo") + logger: this.getLogger("webpack.FileSystemInfo"), + hashFunction: compiler.options.output.hashFunction }); if (compiler.fileTimestamps) { - this.fileSystemInfo.addFileTimestamps(compiler.fileTimestamps); + this.fileSystemInfo.addFileTimestamps(compiler.fileTimestamps, true); } if (compiler.contextTimestamps) { - this.fileSystemInfo.addContextTimestamps(compiler.contextTimestamps); + this.fileSystemInfo.addContextTimestamps( + compiler.contextTimestamps, + true + ); } - /** @type {Map} */ + /** @type {Map} */ this.valueCacheVersions = new Map(); this.requestShortener = compiler.requestShortener; this.compilerPath = compiler.compilerPath; this.logger = this.getLogger("webpack.Compilation"); - const options = compiler.options; + const options = /** @type {WebpackOptions} */ (compiler.options); this.options = options; this.outputOptions = options && options.output; /** @type {boolean} */ @@ -787,6 +936,7 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si /** @type {boolean} */ this.profile = (options && options.profile) || false; + this.params = params; this.mainTemplate = new MainTemplate(this.outputOptions, this); this.chunkTemplate = new ChunkTemplate(this.outputOptions, this); this.runtimeTemplate = new RuntimeTemplate( @@ -794,32 +944,18 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si this.outputOptions, this.requestShortener ); - /** @type {{javascript: ModuleTemplate}} */ + /** @type {ModuleTemplates} */ this.moduleTemplates = { javascript: new ModuleTemplate(this.runtimeTemplate, this) }; - Object.defineProperties(this.moduleTemplates, { - asset: { - enumerable: false, - configurable: false, - get() { - throw new WebpackError( - "Compilation.moduleTemplates.asset has been removed" - ); - } - }, - webassembly: { - enumerable: false, - configurable: false, - get() { - throw new WebpackError( - "Compilation.moduleTemplates.webassembly has been removed" - ); - } - } - }); + defineRemovedModuleTemplates(this.moduleTemplates); + /** @type {Map> | undefined} */ + this.moduleMemCaches = undefined; + /** @type {Map> | undefined} */ + this.moduleMemCaches2 = undefined; this.moduleGraph = new ModuleGraph(); + /** @type {ChunkGraph} */ this.chunkGraph = undefined; /** @type {CodeGenerationResults} */ this.codeGenerationResults = undefined; @@ -837,7 +973,7 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si getKey: module => module.identifier(), processor: this._addModule.bind(this) }); - /** @type {AsyncQueue} */ + /** @type {AsyncQueue} */ this.factorizeQueue = new AsyncQueue({ name: "factorize", parent: this.addModuleQueue, @@ -880,7 +1016,6 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si this.asyncEntrypoints = []; /** @type {Set} */ this.chunks = new Set(); - arrayToSetDeprecation(this.chunks, "Compilation.chunks"); /** @type {ChunkGroup[]} */ this.chunkGroups = []; /** @type {Map} */ @@ -889,8 +1024,14 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si this.namedChunks = new Map(); /** @type {Set} */ this.modules = new Set(); - arrayToSetDeprecation(this.modules, "Compilation.modules"); - /** @private @type {Map} */ + if (this._backCompat) { + arrayToSetDeprecation(this.chunks, "Compilation.chunks"); + arrayToSetDeprecation(this.modules, "Compilation.modules"); + } + /** + * @private + * @type {Map} + */ this._modules = new Map(); this.records = null; /** @type {string[]} */ @@ -912,7 +1053,10 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si /** @type {Map} */ this.dependencyFactories = new Map(); /** @type {DependencyTemplates} */ - this.dependencyTemplates = new DependencyTemplates(); + this.dependencyTemplates = new DependencyTemplates( + this.outputOptions.hashFunction + ); + /** @type {Record} */ this.childrenCounters = {}; /** @type {Set} */ this.usedChunkIds = null; @@ -920,11 +1064,20 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si this.usedModuleIds = null; /** @type {boolean} */ this.needAdditionalPass = false; + /** @type {Set} */ + this._restoredUnsafeCacheModuleEntries = new Set(); + /** @type {Map} */ + this._restoredUnsafeCacheEntries = new Map(); /** @type {WeakSet} */ this.builtModules = new WeakSet(); /** @type {WeakSet} */ this.codeGeneratedModules = new WeakSet(); - /** @private @type {Map} */ + /** @type {WeakSet} */ + this.buildTimeExecutedModules = new WeakSet(); + /** + * @private + * @type {Map} + */ this._rebuildingModules = new Map(); /** @type {Set} */ this.emittedAssets = new Set(); @@ -941,6 +1094,10 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si // TODO webpack 6 remove this.compilationDependencies = { add: util.deprecate( + /** + * @param {string} item item + * @returns {LazySet} file dependencies + */ item => this.fileDependencies.add(item), "Compilation.compilationDependencies is deprecated (used Compilation.fileDependencies instead)", "DEP_WEBPACK_COMPILATION_COMPILATION_DEPENDENCIES" @@ -950,6 +1107,11 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si this._modulesCache = this.getCache("Compilation/modules"); this._assetsCache = this.getCache("Compilation/assets"); this._codeGenerationCache = this.getCache("Compilation/codeGeneration"); + + const unsafeCache = options.module.unsafeCache; + this._unsafeCache = Boolean(unsafeCache); + this._unsafeCachePredicate = + typeof unsafeCache === "function" ? unsafeCache : () => true; } getStats() { @@ -957,15 +1119,16 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si } /** - * @param {StatsOptions | string} optionsOrPreset stats option value - * @param {CreateStatsOptionsContext} context context + * @param {string | boolean | StatsOptions | undefined} optionsOrPreset stats option value + * @param {CreateStatsOptionsContext=} context context * @returns {NormalizedStatsOptions} normalized options */ createStatsOptions(optionsOrPreset, context = {}) { - if ( - typeof optionsOrPreset === "boolean" || - typeof optionsOrPreset === "string" - ) { + if (typeof optionsOrPreset === "boolean") { + optionsOrPreset = { + preset: optionsOrPreset === false ? "none" : "normal" + }; + } else if (typeof optionsOrPreset === "string") { optionsOrPreset = { preset: optionsOrPreset }; } if (typeof optionsOrPreset === "object" && optionsOrPreset !== null) { @@ -973,28 +1136,36 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si // properties in the prototype chain /** @type {Partial} */ const options = {}; + // eslint-disable-next-line guard-for-in for (const key in optionsOrPreset) { - options[key] = optionsOrPreset[key]; + options[key] = optionsOrPreset[/** @type {keyof StatsOptions} */ (key)]; } if (options.preset !== undefined) { this.hooks.statsPreset.for(options.preset).call(options, context); } this.hooks.statsNormalize.call(options, context); return /** @type {NormalizedStatsOptions} */ (options); - } else { - /** @type {Partial} */ - const options = {}; - this.hooks.statsNormalize.call(options, context); - return /** @type {NormalizedStatsOptions} */ (options); } + /** @type {Partial} */ + const options = {}; + this.hooks.statsNormalize.call(options, context); + return /** @type {NormalizedStatsOptions} */ (options); } + /** + * @param {NormalizedStatsOptions} options options + * @returns {StatsFactory} the stats factory + */ createStatsFactory(options) { const statsFactory = new StatsFactory(); this.hooks.statsFactory.call(statsFactory, options); return statsFactory; } + /** + * @param {NormalizedStatsOptions} options options + * @returns {StatsPrinter} the stats printer + */ createStatsPrinter(options) { const statsPrinter = new StatsPrinter(); this.hooks.statsPrinter.call(statsPrinter, options); @@ -1034,7 +1205,9 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si case LogType.warn: case LogType.error: case LogType.trace: - trace = ErrorHelpers.cutOffLoaderExecution(new Error("Trace").stack) + trace = ErrorHelpers.cutOffLoaderExecution( + /** @type {string} */ (new Error("Trace").stack) + ) .split("\n") .slice(3); break; @@ -1047,12 +1220,13 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si trace }; if (this.hooks.log.call(name, logEntry) === undefined) { - if (logEntry.type === LogType.profileEnd) { - // eslint-disable-next-line node/no-unsupported-features/node-builtins - if (typeof console.profileEnd === "function") { - // eslint-disable-next-line node/no-unsupported-features/node-builtins - console.profileEnd(`[${name}] ${logEntry.args[0]}`); - } + if ( + logEntry.type === LogType.profileEnd && + typeof console.profileEnd === "function" + ) { + console.profileEnd( + `[${name}] ${/** @type {NonNullable} */ (logEntry.args)[0]}` + ); } if (logEntries === undefined) { logEntries = this.logging.get(name); @@ -1062,12 +1236,13 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si } } logEntries.push(logEntry); - if (logEntry.type === LogType.profile) { - // eslint-disable-next-line node/no-unsupported-features/node-builtins - if (typeof console.profile === "function") { - // eslint-disable-next-line node/no-unsupported-features/node-builtins - console.profile(`[${name}] ${logEntry.args[0]}`); - } + if ( + logEntry.type === LogType.profile && + typeof console.profile === "function" + ) { + console.profile( + `[${name}] ${/** @type {NonNullable} */ (logEntry.args)[0]}` + ); } } }, @@ -1093,36 +1268,33 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si } return `${name}/${childName}`; }); - } else { - return this.getLogger(() => { - if (typeof name === "function") { - name = name(); - if (!name) { - throw new TypeError( - "Compilation.getLogger(name) called with a function not returning a name" - ); - } - } - return `${name}/${childName}`; - }); } - } else { - if (typeof childName === "function") { - return this.getLogger(() => { - if (typeof childName === "function") { - childName = childName(); - if (!childName) { - throw new TypeError( - "Logger.getChildLogger(name) called with a function not returning a name" - ); - } + return this.getLogger(() => { + if (typeof name === "function") { + name = name(); + if (!name) { + throw new TypeError( + "Compilation.getLogger(name) called with a function not returning a name" + ); } - return `${name}/${childName}`; - }); - } else { - return this.getLogger(`${name}/${childName}`); - } + } + return `${name}/${childName}`; + }); } + if (typeof childName === "function") { + return this.getLogger(() => { + if (typeof childName === "function") { + childName = childName(); + if (!childName) { + throw new TypeError( + "Logger.getChildLogger(name) called with a function not returning a name" + ); + } + } + return `${name}/${childName}`; + }); + } + return this.getLogger(`${name}/${childName}`); } ); } @@ -1172,7 +1344,8 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si } this._modules.set(identifier, module); this.modules.add(module); - ModuleGraph.setModuleGraphForModule(module, this.moduleGraph); + if (this._backCompat) + ModuleGraph.setModuleGraphForModule(module, this.moduleGraph); if (currentProfile !== undefined) { currentProfile.markIntegrationEnd(); } @@ -1187,7 +1360,7 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si */ getModule(module) { const identifier = module.identifier(); - return this._modules.get(identifier); + return /** @type {Module} */ (this._modules.get(identifier)); } /** @@ -1201,7 +1374,6 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si /** * Schedules a build of the module object - * * @param {Module} module module to be built * @param {ModuleCallback} callback the callback * @returns {void} @@ -1212,7 +1384,6 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si /** * Builds the module object - * * @param {Module} module module to be built * @param {ModuleCallback} callback the callback * @returns {void} @@ -1227,6 +1398,7 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si module.needBuild( { + compilation: this, fileSystemInfo: this.fileSystemInfo, valueCacheVersions: this.valueCacheVersions }, @@ -1247,7 +1419,7 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si this.options, this, this.resolverFactory.get("normal", module.resolveOptions), - this.inputFileSystem, + /** @type {InputFileSystem} */ (this.inputFileSystem), err => { if (currentProfile !== undefined) { currentProfile.markBuildingEnd(); @@ -1264,7 +1436,10 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si currentProfile.markStoringEnd(); } if (err) { - this.hooks.failedModule.call(module, err); + this.hooks.failedModule.call( + module, + /** @type {WebpackError} */ (err) + ); return callback(new ModuleStoreError(module, err)); } this.hooks.succeedModule.call(module); @@ -1290,10 +1465,14 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si * @returns {void} */ processModuleDependenciesNonRecursive(module) { + /** + * @param {DependenciesBlock} block block + */ const processDependenciesBlock = block => { if (block.dependencies) { + let i = 0; for (const dep of block.dependencies) { - this.moduleGraph.setParents(dep, block, module); + this.moduleGraph.setParents(dep, block, module, i++); } } if (block.blocks) { @@ -1310,127 +1489,332 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si * @returns {void} */ _processModuleDependencies(module, callback) { - const dependencies = new Map(); - - /** - * @type {Array<{factory: ModuleFactory, dependencies: Dependency[], originModule: Module|null}>} - */ + /** @type {Array<{factory: ModuleFactory, dependencies: Dependency[], context: string|undefined, originModule: Module|null}>} */ const sortedDependencies = []; - let currentBlock = module; + /** @type {DependenciesBlock} */ + let currentBlock; + /** @type {Map>} */ + let dependencies; + /** @type {DepConstructor} */ let factoryCacheKey; + /** @type {ModuleFactory} */ + let factoryCacheKey2; + /** @type {Map} */ let factoryCacheValue; - let factoryCacheValue2; - let listCacheKey; + /** @type {string} */ + let listCacheKey1; + /** @type {string} */ + let listCacheKey2; + /** @type {Dependency[]} */ let listCacheValue; - const processDependency = dep => { - this.moduleGraph.setParents(dep, currentBlock, module); + let inProgressSorting = 1; + let inProgressTransitive = 1; + + /** + * @param {WebpackError=} err error + * @returns {void} + */ + const onDependenciesSorted = err => { + if (err) return callback(err); + + // early exit without changing parallelism back and forth + if (sortedDependencies.length === 0 && inProgressTransitive === 1) { + return callback(); + } + + // This is nested so we need to allow one additional task + this.processDependenciesQueue.increaseParallelism(); + + for (const item of sortedDependencies) { + inProgressTransitive++; + // eslint-disable-next-line no-loop-func + this.handleModuleCreation(item, err => { + // In V8, the Error objects keep a reference to the functions on the stack. These warnings & + // errors are created inside closures that keep a reference to the Compilation, so errors are + // leaking the Compilation object. + if (err && this.bail) { + if (inProgressTransitive <= 0) return; + inProgressTransitive = -1; + // eslint-disable-next-line no-self-assign + err.stack = err.stack; + onTransitiveTasksFinished(err); + return; + } + if (--inProgressTransitive === 0) onTransitiveTasksFinished(); + }); + } + if (--inProgressTransitive === 0) onTransitiveTasksFinished(); + }; + + /** + * @param {WebpackError=} err error + * @returns {void} + */ + const onTransitiveTasksFinished = err => { + if (err) return callback(err); + this.processDependenciesQueue.decreaseParallelism(); + + return callback(); + }; + + /** + * @param {Dependency} dep dependency + * @param {number} index index in block + * @returns {void} + */ + const processDependency = (dep, index) => { + this.moduleGraph.setParents(dep, currentBlock, module, index); + if (this._unsafeCache) { + try { + const unsafeCachedModule = unsafeCacheDependencies.get(dep); + if (unsafeCachedModule === null) return; + if (unsafeCachedModule !== undefined) { + if ( + this._restoredUnsafeCacheModuleEntries.has(unsafeCachedModule) + ) { + this._handleExistingModuleFromUnsafeCache( + module, + dep, + unsafeCachedModule + ); + return; + } + const identifier = unsafeCachedModule.identifier(); + const cachedModule = + this._restoredUnsafeCacheEntries.get(identifier); + if (cachedModule !== undefined) { + // update unsafe cache to new module + unsafeCacheDependencies.set(dep, cachedModule); + this._handleExistingModuleFromUnsafeCache( + module, + dep, + cachedModule + ); + return; + } + inProgressSorting++; + this._modulesCache.get(identifier, null, (err, cachedModule) => { + if (err) { + if (inProgressSorting <= 0) return; + inProgressSorting = -1; + onDependenciesSorted(/** @type {WebpackError} */ (err)); + return; + } + try { + if (!this._restoredUnsafeCacheEntries.has(identifier)) { + const data = unsafeCacheData.get(cachedModule); + if (data === undefined) { + processDependencyForResolving(dep); + if (--inProgressSorting === 0) onDependenciesSorted(); + return; + } + if (cachedModule !== unsafeCachedModule) { + unsafeCacheDependencies.set(dep, cachedModule); + } + cachedModule.restoreFromUnsafeCache( + data, + this.params.normalModuleFactory, + this.params + ); + this._restoredUnsafeCacheEntries.set( + identifier, + cachedModule + ); + this._restoredUnsafeCacheModuleEntries.add(cachedModule); + if (!this.modules.has(cachedModule)) { + inProgressTransitive++; + this._handleNewModuleFromUnsafeCache( + module, + dep, + cachedModule, + err => { + if (err) { + if (inProgressTransitive <= 0) return; + inProgressTransitive = -1; + onTransitiveTasksFinished(err); + } + if (--inProgressTransitive === 0) + return onTransitiveTasksFinished(); + } + ); + if (--inProgressSorting === 0) onDependenciesSorted(); + return; + } + } + if (unsafeCachedModule !== cachedModule) { + unsafeCacheDependencies.set(dep, cachedModule); + } + this._handleExistingModuleFromUnsafeCache( + module, + dep, + cachedModule + ); // a3 + } catch (err) { + if (inProgressSorting <= 0) return; + inProgressSorting = -1; + onDependenciesSorted(/** @type {WebpackError} */ (err)); + return; + } + if (--inProgressSorting === 0) onDependenciesSorted(); + }); + return; + } + } catch (err) { + console.error(err); + } + } + processDependencyForResolving(dep); + }; + + /** + * @param {Dependency} dep dependency + * @returns {void} + */ + const processDependencyForResolving = dep => { const resourceIdent = dep.getResourceIdentifier(); - if (resourceIdent) { - // Here webpack is using heuristic that assumes - // mostly esm dependencies would be used - // so we don't allocate extra string for them + if (resourceIdent !== undefined && resourceIdent !== null) { const category = dep.category; - const cacheKey = - category === esmDependencyCategory - ? resourceIdent - : `${category}${resourceIdent}`; - const constructor = dep.constructor; - let innerMap; - let factory; + const constructor = /** @type {DepConstructor} */ (dep.constructor); if (factoryCacheKey === constructor) { - innerMap = factoryCacheValue; - if (listCacheKey === cacheKey) { + // Fast path 1: same constructor as prev item + if (listCacheKey1 === category && listCacheKey2 === resourceIdent) { + // Super fast path 1: also same resource listCacheValue.push(dep); return; } } else { - factory = this.dependencyFactories.get(dep.constructor); + const factory = this.dependencyFactories.get(constructor); if (factory === undefined) { throw new Error( - `No module factory available for dependency type: ${dep.constructor.name}` + `No module factory available for dependency type: ${constructor.name}` ); } - innerMap = dependencies.get(factory); - if (innerMap === undefined) { - dependencies.set(factory, (innerMap = new Map())); + if (factoryCacheKey2 === factory) { + // Fast path 2: same factory as prev item + factoryCacheKey = constructor; + if (listCacheKey1 === category && listCacheKey2 === resourceIdent) { + // Super fast path 2: also same resource + listCacheValue.push(dep); + return; + } + } else { + // Slow path + if (factoryCacheKey2 !== undefined) { + // Archive last cache entry + if (dependencies === undefined) dependencies = new Map(); + dependencies.set(factoryCacheKey2, factoryCacheValue); + factoryCacheValue = dependencies.get(factory); + if (factoryCacheValue === undefined) { + factoryCacheValue = new Map(); + } + } else { + factoryCacheValue = new Map(); + } + factoryCacheKey = constructor; + factoryCacheKey2 = factory; } - factoryCacheKey = constructor; - factoryCacheValue = innerMap; - factoryCacheValue2 = factory; } - let list = innerMap.get(cacheKey); + // Here webpack is using heuristic that assumes + // mostly esm dependencies would be used + // so we don't allocate extra string for them + const cacheKey = + category === esmDependencyCategory + ? resourceIdent + : `${category}${resourceIdent}`; + let list = factoryCacheValue.get(cacheKey); if (list === undefined) { - innerMap.set(cacheKey, (list = [])); + factoryCacheValue.set(cacheKey, (list = [])); sortedDependencies.push({ - factory: factoryCacheValue2, + factory: factoryCacheKey2, dependencies: list, + context: dep.getContext(), originModule: module }); } list.push(dep); - listCacheKey = cacheKey; + listCacheKey1 = category; + listCacheKey2 = resourceIdent; listCacheValue = list; } }; - const processDependenciesBlock = block => { - if (block.dependencies) { - currentBlock = block; - for (const dep of block.dependencies) processDependency(dep); - } - if (block.blocks) { - for (const b of block.blocks) processDependenciesBlock(b); - } - }; - try { - processDependenciesBlock(module); - } catch (e) { - return callback(e); + /** @type {DependenciesBlock[]} */ + const queue = [module]; + do { + const block = /** @type {DependenciesBlock} */ (queue.pop()); + if (block.dependencies) { + currentBlock = block; + let i = 0; + for (const dep of block.dependencies) processDependency(dep, i++); + } + if (block.blocks) { + for (const b of block.blocks) queue.push(b); + } + } while (queue.length !== 0); + } catch (err) { + return callback(err); } - if (sortedDependencies.length === 0) { - callback(); - return; - } + if (--inProgressSorting === 0) onDependenciesSorted(); + } - // This is nested so we need to allow one additional task - this.processDependenciesQueue.increaseParallelism(); + /** + * @private + * @param {Module} originModule original module + * @param {Dependency} dependency dependency + * @param {Module} module cached module + * @param {Callback} callback callback + */ + _handleNewModuleFromUnsafeCache(originModule, dependency, module, callback) { + const moduleGraph = this.moduleGraph; - asyncLib.forEach( - sortedDependencies, - (item, callback) => { - this.handleModuleCreation(item, err => { - // In V8, the Error objects keep a reference to the functions on the stack. These warnings & - // errors are created inside closures that keep a reference to the Compilation, so errors are - // leaking the Compilation object. - if (err && this.bail) { - // eslint-disable-next-line no-self-assign - err.stack = err.stack; - return callback(err); - } - callback(); - }); - }, - err => { - this.processDependenciesQueue.decreaseParallelism(); + moduleGraph.setResolvedModule(originModule, dependency, module); - return callback(err); - } + moduleGraph.setIssuerIfUnset( + module, + originModule !== undefined ? originModule : null ); + + this._modules.set(module.identifier(), module); + this.modules.add(module); + if (this._backCompat) + ModuleGraph.setModuleGraphForModule(module, this.moduleGraph); + + this._handleModuleBuildAndDependencies( + originModule, + module, + true, + false, + callback + ); + } + + /** + * @private + * @param {Module} originModule original modules + * @param {Dependency} dependency dependency + * @param {Module} module cached module + */ + _handleExistingModuleFromUnsafeCache(originModule, dependency, module) { + const moduleGraph = this.moduleGraph; + + moduleGraph.setResolvedModule(originModule, dependency, module); } /** - * @typedef {Object} HandleModuleCreationOptions + * @typedef {object} HandleModuleCreationOptions * @property {ModuleFactory} factory * @property {Dependency[]} dependencies * @property {Module | null} originModule * @property {Partial=} contextInfo * @property {string=} context * @property {boolean=} recursive recurse into dependencies of the created module + * @property {boolean=} connectOrigin connect the resolved module with the origin module + * @property {boolean=} checkCycle check the cycle dependencies of the created module */ /** @@ -1445,7 +1829,9 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si originModule, contextInfo, context, - recursive = true + recursive = true, + connectOrigin = recursive, + checkCycle = !recursive }, callback ) { @@ -1458,21 +1844,39 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si currentProfile, factory, dependencies, + factoryResult: true, originModule, contextInfo, context }, - (err, newModule) => { + (err, factoryResult) => { + const applyFactoryResultDependencies = () => { + const { fileDependencies, contextDependencies, missingDependencies } = + factoryResult; + if (fileDependencies) { + this.fileDependencies.addAll(fileDependencies); + } + if (contextDependencies) { + this.contextDependencies.addAll(contextDependencies); + } + if (missingDependencies) { + this.missingDependencies.addAll(missingDependencies); + } + }; if (err) { + if (factoryResult) applyFactoryResultDependencies(); if (dependencies.every(d => d.optional)) { this.warnings.push(err); - } else { - this.errors.push(err); + return callback(); } + this.errors.push(err); return callback(err); } + const newModule = factoryResult.module; + if (!newModule) { + applyFactoryResultDependencies(); return callback(); } @@ -1480,134 +1884,170 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si moduleGraph.setProfile(newModule, currentProfile); } - this.addModule(newModule, (err, module) => { + this.addModule(newModule, (err, _module) => { if (err) { + applyFactoryResultDependencies(); if (!err.module) { - err.module = module; + err.module = _module; } this.errors.push(err); return callback(err); } - for (let i = 0; i < dependencies.length; i++) { - const dependency = dependencies[i]; - moduleGraph.setResolvedModule( - recursive ? originModule : null, - dependency, - module - ); + const module = + /** @type {Module & { restoreFromUnsafeCache?: Function }} */ + (_module); + + if ( + this._unsafeCache && + factoryResult.cacheable !== false && + module.restoreFromUnsafeCache && + this._unsafeCachePredicate(module) + ) { + const unsafeCacheableModule = + /** @type {Module & { restoreFromUnsafeCache: Function }} */ + (module); + for (let i = 0; i < dependencies.length; i++) { + const dependency = dependencies[i]; + moduleGraph.setResolvedModule( + connectOrigin ? originModule : null, + dependency, + unsafeCacheableModule + ); + unsafeCacheDependencies.set(dependency, unsafeCacheableModule); + } + if (!unsafeCacheData.has(unsafeCacheableModule)) { + unsafeCacheData.set( + unsafeCacheableModule, + unsafeCacheableModule.getUnsafeCacheData() + ); + } + } else { + applyFactoryResultDependencies(); + for (let i = 0; i < dependencies.length; i++) { + const dependency = dependencies[i]; + moduleGraph.setResolvedModule( + connectOrigin ? originModule : null, + dependency, + module + ); + } } moduleGraph.setIssuerIfUnset( module, originModule !== undefined ? originModule : null ); - if (module !== newModule) { - if (currentProfile !== undefined) { - const otherProfile = moduleGraph.getProfile(module); - if (otherProfile !== undefined) { - currentProfile.mergeInto(otherProfile); - } else { - moduleGraph.setProfile(module, currentProfile); - } - } - } - - // Check for cycles when build is trigger inside another build - let creatingModuleDuringBuildSet = undefined; - if (!recursive && this.buildQueue.isProcessing(originModule)) { - // Track build dependency - creatingModuleDuringBuildSet = this.creatingModuleDuringBuild.get( - originModule - ); - if (creatingModuleDuringBuildSet === undefined) { - creatingModuleDuringBuildSet = new Set(); - this.creatingModuleDuringBuild.set( - originModule, - creatingModuleDuringBuildSet - ); - } - creatingModuleDuringBuildSet.add(originModule); - - // When building is blocked by another module - // search for a cycle, cancel the cycle by throwing - // an error (otherwise this would deadlock) - const blockReasons = this.creatingModuleDuringBuild.get(module); - if (blockReasons !== undefined) { - const set = new Set(blockReasons); - for (const item of set) { - const blockReasons = this.creatingModuleDuringBuild.get(item); - if (blockReasons !== undefined) { - for (const m of blockReasons) { - if (m === module) { - return callback(new BuildCycleError(module)); - } - set.add(m); - } - } - } + if (module !== newModule && currentProfile !== undefined) { + const otherProfile = moduleGraph.getProfile(module); + if (otherProfile !== undefined) { + currentProfile.mergeInto(otherProfile); + } else { + moduleGraph.setProfile(module, currentProfile); } } - this.buildModule(module, err => { - if (creatingModuleDuringBuildSet !== undefined) { - creatingModuleDuringBuildSet.delete(module); - } - if (err) { - if (!err.module) { - err.module = module; - } - this.errors.push(err); - - return callback(err); - } - - if (!recursive) { - this.processModuleDependenciesNonRecursive(module); - callback(null, module); - return; - } - - // This avoids deadlocks for circular dependencies - if (this.processDependenciesQueue.isProcessing(module)) { - return callback(); - } - - this.processModuleDependencies(module, err => { - if (err) { - return callback(err); - } - callback(null, module); - }); - }); + this._handleModuleBuildAndDependencies( + originModule, + module, + recursive, + checkCycle, + callback + ); }); } ); } /** - * @typedef {Object} FactorizeModuleOptions - * @property {ModuleProfile} currentProfile - * @property {ModuleFactory} factory - * @property {Dependency[]} dependencies - * @property {Module | null} originModule - * @property {Partial=} contextInfo - * @property {string=} context - */ - - /** - * @param {FactorizeModuleOptions} options options object + * @private + * @param {Module} originModule original module + * @param {Module} module module + * @param {boolean} recursive true if make it recursive, otherwise false + * @param {boolean} checkCycle true if need to check cycle, otherwise false * @param {ModuleCallback} callback callback * @returns {void} */ - factorizeModule(options, callback) { - this.factorizeQueue.add(options, callback); + _handleModuleBuildAndDependencies( + originModule, + module, + recursive, + checkCycle, + callback + ) { + // Check for cycles when build is trigger inside another build + /** @type {Set | undefined} */ + let creatingModuleDuringBuildSet; + if (checkCycle && this.buildQueue.isProcessing(originModule)) { + // Track build dependency + creatingModuleDuringBuildSet = + this.creatingModuleDuringBuild.get(originModule); + if (creatingModuleDuringBuildSet === undefined) { + creatingModuleDuringBuildSet = new Set(); + this.creatingModuleDuringBuild.set( + originModule, + creatingModuleDuringBuildSet + ); + } + creatingModuleDuringBuildSet.add(module); + + // When building is blocked by another module + // search for a cycle, cancel the cycle by throwing + // an error (otherwise this would deadlock) + const blockReasons = this.creatingModuleDuringBuild.get(module); + if (blockReasons !== undefined) { + const set = new Set(blockReasons); + for (const item of set) { + const blockReasons = this.creatingModuleDuringBuild.get(item); + if (blockReasons !== undefined) { + for (const m of blockReasons) { + if (m === module) { + return callback(new BuildCycleError(module)); + } + set.add(m); + } + } + } + } + } + + this.buildModule(module, err => { + if (creatingModuleDuringBuildSet !== undefined) { + creatingModuleDuringBuildSet.delete(module); + } + if (err) { + if (!err.module) { + err.module = module; + } + this.errors.push(err); + + return callback(err); + } + + if (!recursive) { + this.processModuleDependenciesNonRecursive(module); + callback(null, module); + return; + } + + // This avoids deadlocks for circular dependencies + if (this.processDependenciesQueue.isProcessing(module)) { + return callback(null, module); + } + + this.processModuleDependencies(module, err => { + if (err) { + return callback(err); + } + callback(null, module); + }); + }); } /** * @param {FactorizeModuleOptions} options options object - * @param {ModuleCallback} callback callback + * @param {ModuleOrFactoryResultCallback} callback callback * @returns {void} */ _factorizeModule( @@ -1616,6 +2056,7 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si factory, dependencies, originModule, + factoryResult, contextInfo, context }, @@ -1633,12 +2074,10 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si ...contextInfo }, resolveOptions: originModule ? originModule.resolveOptions : undefined, - context: context - ? context - : originModule - ? originModule.context - : this.compiler.context, - dependencies: dependencies + context: + context || + (originModule ? originModule.context : this.compiler.context), + dependencies }, (err, result) => { if (result) { @@ -1649,41 +2088,40 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si module: result }; } - const { - fileDependencies, - contextDependencies, - missingDependencies - } = result; - if (fileDependencies) { - this.fileDependencies.addAll(fileDependencies); - } - if (contextDependencies) { - this.contextDependencies.addAll(contextDependencies); - } - if (missingDependencies) { - this.missingDependencies.addAll(missingDependencies); + if (!factoryResult) { + const { + fileDependencies, + contextDependencies, + missingDependencies + } = result; + if (fileDependencies) { + this.fileDependencies.addAll(fileDependencies); + } + if (contextDependencies) { + this.contextDependencies.addAll(contextDependencies); + } + if (missingDependencies) { + this.missingDependencies.addAll(missingDependencies); + } } } if (err) { const notFoundError = new ModuleNotFoundError( originModule, err, - dependencies.map(d => d.loc).filter(Boolean)[0] + dependencies.map(d => d.loc).find(Boolean) ); - return callback(notFoundError); + return callback(notFoundError, factoryResult ? result : undefined); } if (!result) { return callback(); } - const newModule = result.module; - if (!newModule) { - return callback(); - } + if (currentProfile !== undefined) { currentProfile.markFactoryEnd(); } - callback(null, newModule); + callback(null, factoryResult ? result : result.module); } ); } @@ -1699,7 +2137,7 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si } /** - * @param {Object} options options + * @param {object} options options * @param {string} options.context context string path * @param {Dependency} options.dependency dependency used to create Module chain * @param {Partial=} options.contextInfo additional context info for the root module @@ -1734,13 +2172,15 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si contextInfo, context }, - err => { + (err, result) => { if (err && this.bail) { callback(err); this.buildQueue.stop(); this.rebuildQueue.stop(); this.processDependenciesQueue.stop(); this.factorizeQueue.stop(); + } else if (!err && result) { + callback(null, result); } else { callback(); } @@ -1804,7 +2244,10 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si } }; entryData[target].push(entry); - this.entries.set(name, entryData); + this.entries.set( + /** @type {NonNullable} */ (name), + entryData + ); } else { entryData[target].push(entry); for (const key of Object.keys(options)) { @@ -1844,7 +2287,11 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si this.hooks.failedEntry.call(entry, options, err); return callback(err); } - this.hooks.succeedEntry.call(entry, options, module); + this.hooks.succeedEntry.call( + entry, + options, + /** @type {Module} */ (module) + ); return callback(null, module); } ); @@ -1884,6 +2331,7 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si } this.processDependenciesQueue.invalidate(module); + this.moduleGraph.unfreeze(); this.processModuleDependencies(module, err => { if (err) return callback(err); this.removeReasonsOfDependencyBlock(module, { @@ -1903,12 +2351,306 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si }); } + /** + * @private + * @param {Set} modules modules + */ + _computeAffectedModules(modules) { + const moduleMemCacheCache = this.compiler.moduleMemCaches; + if (!moduleMemCacheCache) return; + if (!this.moduleMemCaches) { + this.moduleMemCaches = new Map(); + this.moduleGraph.setModuleMemCaches(this.moduleMemCaches); + } + const { moduleGraph, moduleMemCaches } = this; + const affectedModules = new Set(); + const infectedModules = new Set(); + let statNew = 0; + let statChanged = 0; + let statUnchanged = 0; + let statReferencesChanged = 0; + let statWithoutBuild = 0; + + /** + * @param {Module} module module + * @returns {References | undefined} references + */ + const computeReferences = module => { + /** @type {References | undefined} */ + let references; + for (const connection of moduleGraph.getOutgoingConnections(module)) { + const d = connection.dependency; + const m = connection.module; + if (!d || !m || unsafeCacheDependencies.has(d)) continue; + if (references === undefined) references = new WeakMap(); + references.set(d, m); + } + return references; + }; + + /** + * @param {Module} module the module + * @param {References | undefined} references references + * @returns {boolean} true, when the references differ + */ + const compareReferences = (module, references) => { + if (references === undefined) return true; + for (const connection of moduleGraph.getOutgoingConnections(module)) { + const d = connection.dependency; + if (!d) continue; + const entry = references.get(d); + if (entry === undefined) continue; + if (entry !== connection.module) return false; + } + return true; + }; + + const modulesWithoutCache = new Set(modules); + for (const [module, cachedMemCache] of moduleMemCacheCache) { + if (modulesWithoutCache.has(module)) { + const buildInfo = module.buildInfo; + if (buildInfo) { + if (cachedMemCache.buildInfo !== buildInfo) { + // use a new one + const memCache = new WeakTupleMap(); + moduleMemCaches.set(module, memCache); + affectedModules.add(module); + cachedMemCache.buildInfo = buildInfo; + cachedMemCache.references = computeReferences(module); + cachedMemCache.memCache = memCache; + statChanged++; + } else if (!compareReferences(module, cachedMemCache.references)) { + // use a new one + const memCache = new WeakTupleMap(); + moduleMemCaches.set(module, memCache); + affectedModules.add(module); + cachedMemCache.references = computeReferences(module); + cachedMemCache.memCache = memCache; + statReferencesChanged++; + } else { + // keep the old mem cache + moduleMemCaches.set(module, cachedMemCache.memCache); + statUnchanged++; + } + } else { + infectedModules.add(module); + moduleMemCacheCache.delete(module); + statWithoutBuild++; + } + modulesWithoutCache.delete(module); + } else { + moduleMemCacheCache.delete(module); + } + } + + for (const module of modulesWithoutCache) { + const buildInfo = module.buildInfo; + if (buildInfo) { + // create a new entry + const memCache = new WeakTupleMap(); + moduleMemCacheCache.set(module, { + buildInfo, + references: computeReferences(module), + memCache + }); + moduleMemCaches.set(module, memCache); + affectedModules.add(module); + statNew++; + } else { + infectedModules.add(module); + statWithoutBuild++; + } + } + + /** + * @param {readonly ModuleGraphConnection[]} connections connections + * @returns {symbol|boolean} result + */ + const reduceAffectType = connections => { + let affected = false; + for (const { dependency } of connections) { + if (!dependency) continue; + const type = dependency.couldAffectReferencingModule(); + if (type === Dependency.TRANSITIVE) return Dependency.TRANSITIVE; + if (type === false) continue; + affected = true; + } + return affected; + }; + const directOnlyInfectedModules = new Set(); + for (const module of infectedModules) { + for (const [ + referencingModule, + connections + ] of moduleGraph.getIncomingConnectionsByOriginModule(module)) { + if (!referencingModule) continue; + if (infectedModules.has(referencingModule)) continue; + const type = reduceAffectType(connections); + if (!type) continue; + if (type === true) { + directOnlyInfectedModules.add(referencingModule); + } else { + infectedModules.add(referencingModule); + } + } + } + for (const module of directOnlyInfectedModules) infectedModules.add(module); + const directOnlyAffectModules = new Set(); + for (const module of affectedModules) { + for (const [ + referencingModule, + connections + ] of moduleGraph.getIncomingConnectionsByOriginModule(module)) { + if (!referencingModule) continue; + if (infectedModules.has(referencingModule)) continue; + if (affectedModules.has(referencingModule)) continue; + const type = reduceAffectType(connections); + if (!type) continue; + if (type === true) { + directOnlyAffectModules.add(referencingModule); + } else { + affectedModules.add(referencingModule); + } + const memCache = new WeakTupleMap(); + const cache = moduleMemCacheCache.get(referencingModule); + cache.memCache = memCache; + moduleMemCaches.set(referencingModule, memCache); + } + } + for (const module of directOnlyAffectModules) affectedModules.add(module); + this.logger.log( + `${Math.round( + (100 * (affectedModules.size + infectedModules.size)) / + this.modules.size + )}% (${affectedModules.size} affected + ${ + infectedModules.size + } infected of ${ + this.modules.size + }) modules flagged as affected (${statNew} new modules, ${statChanged} changed, ${statReferencesChanged} references changed, ${statUnchanged} unchanged, ${statWithoutBuild} were not built)` + ); + } + + _computeAffectedModulesWithChunkGraph() { + const { moduleMemCaches } = this; + if (!moduleMemCaches) return; + const moduleMemCaches2 = (this.moduleMemCaches2 = new Map()); + const { moduleGraph, chunkGraph } = this; + const key = "memCache2"; + let statUnchanged = 0; + let statChanged = 0; + let statNew = 0; + /** + * @param {Module} module module + * @returns {{ id: string | number, modules?: Map, blocks?: (string | number | null)[] }} references + */ + const computeReferences = module => { + const id = chunkGraph.getModuleId(module); + /** @type {Map | undefined} */ + let modules; + /** @type {(string | number | null)[] | undefined} */ + let blocks; + const outgoing = moduleGraph.getOutgoingConnectionsByModule(module); + if (outgoing !== undefined) { + for (const m of outgoing.keys()) { + if (!m) continue; + if (modules === undefined) modules = new Map(); + modules.set(m, chunkGraph.getModuleId(m)); + } + } + if (module.blocks.length > 0) { + blocks = []; + const queue = Array.from(module.blocks); + for (const block of queue) { + const chunkGroup = chunkGraph.getBlockChunkGroup(block); + if (chunkGroup) { + for (const chunk of chunkGroup.chunks) { + blocks.push(chunk.id); + } + } else { + blocks.push(null); + } + // eslint-disable-next-line prefer-spread + queue.push.apply(queue, block.blocks); + } + } + return { id, modules, blocks }; + }; + /** + * @param {Module} module module + * @param {object} references references + * @param {string | number} references.id id + * @param {Map=} references.modules modules + * @param {(string | number | null)[]=} references.blocks blocks + * @returns {boolean} ok? + */ + const compareReferences = (module, { id, modules, blocks }) => { + if (id !== chunkGraph.getModuleId(module)) return false; + if (modules !== undefined) { + for (const [module, id] of modules) { + if (chunkGraph.getModuleId(module) !== id) return false; + } + } + if (blocks !== undefined) { + const queue = Array.from(module.blocks); + let i = 0; + for (const block of queue) { + const chunkGroup = chunkGraph.getBlockChunkGroup(block); + if (chunkGroup) { + for (const chunk of chunkGroup.chunks) { + if (i >= blocks.length || blocks[i++] !== chunk.id) return false; + } + } else if (i >= blocks.length || blocks[i++] !== null) { + return false; + } + // eslint-disable-next-line prefer-spread + queue.push.apply(queue, block.blocks); + } + if (i !== blocks.length) return false; + } + return true; + }; + + for (const [module, memCache] of moduleMemCaches) { + /** @type {{ references: { id: string | number, modules?: Map, blocks?: (string | number | null)[]}, memCache: WeakTupleMap }} */ + const cache = memCache.get(key); + if (cache === undefined) { + const memCache2 = new WeakTupleMap(); + memCache.set(key, { + references: computeReferences(module), + memCache: memCache2 + }); + moduleMemCaches2.set(module, memCache2); + statNew++; + } else if (!compareReferences(module, cache.references)) { + const memCache = new WeakTupleMap(); + cache.references = computeReferences(module); + cache.memCache = memCache; + moduleMemCaches2.set(module, memCache); + statChanged++; + } else { + moduleMemCaches2.set(module, cache.memCache); + statUnchanged++; + } + } + + this.logger.log( + `${Math.round( + (100 * statChanged) / (statNew + statChanged + statUnchanged) + )}% modules flagged as affected by chunk graph (${statNew} new modules, ${statChanged} changed, ${statUnchanged} unchanged)` + ); + } + + /** + * @param {Callback} callback callback + */ finish(callback) { + this.factorizeQueue.clear(); if (this.profile) { this.logger.time("finish module profiles"); const ParallelismFactorCalculator = require("./util/ParallelismFactorCalculator"); const p = new ParallelismFactorCalculator(); const moduleGraph = this.moduleGraph; + /** @type {Map} */ const modulesWithProfiles = new Map(); for (const module of this.modules) { const profile = moduleGraph.getProfile(module); @@ -1954,6 +2696,12 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si p.calculate(); const logger = this.getLogger("webpack.Compilation.ModuleProfile"); + // Avoid coverage problems due indirect changes + /** + * @param {number} value value + * @param {string} msg message + */ + /* istanbul ignore next */ const logByValue = (value, msg) => { if (value > 1000) { logger.error(msg); @@ -1967,6 +2715,11 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si logger.debug(msg); } }; + /** + * @param {string} category a category + * @param {(profile: ModuleProfile) => number} getDuration get duration callback + * @param {(profile: ModuleProfile) => number} getParallelism get parallelism callback + */ const logNormalSummary = (category, getDuration, getParallelism) => { let sum = 0; let max = 0; @@ -1991,12 +2744,17 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si `${Math.round(sum)} ms ${category}` ); }; + /** + * @param {string} category a category + * @param {(profile: ModuleProfile) => number} getDuration get duration callback + * @param {(profile: ModuleProfile) => number} getParallelism get parallelism callback + */ const logByLoadersSummary = (category, getDuration, getParallelism) => { const map = new Map(); for (const [module, profile] of modulesWithProfiles) { - const list = provide( + const list = getOrInsert( map, - module.type + "!" + module.identifier().replace(/(!|^)[^!]*$/, ""), + `${module.type}!${module.identifier().replace(/(!|^)[^!]*$/, "")}`, () => [] ); list.push({ module, profile }); @@ -2036,9 +2794,9 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si loaders ? `${ modules.length - } x ${moduleType} with ${this.requestShortener.shorten( + } x ${moduleType} with ${this.requestShortener.shorten( loaders - )}` + )}` : `${modules.length} x ${moduleType}` }` ); @@ -2082,16 +2840,29 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si ); this.logger.timeEnd("finish module profiles"); } + this.logger.time("compute affected modules"); + this._computeAffectedModules(this.modules); + this.logger.timeEnd("compute affected modules"); this.logger.time("finish modules"); - const { modules } = this; + const { modules, moduleMemCaches } = this; this.hooks.finishModules.callAsync(modules, err => { this.logger.timeEnd("finish modules"); - if (err) return callback(err); + if (err) return callback(/** @type {WebpackError} */ (err)); // extract warnings and errors from modules + this.moduleGraph.freeze("dependency errors"); + // TODO keep a cacheToken (= {}) for each module in the graph + // create a new one per compilation and flag all updated files + // and parents with it this.logger.time("report dependency errors and warnings"); for (const module of modules) { - this.reportDependencyErrorsAndWarnings(module, [module]); + // TODO only run for modules with changed cacheToken + // global WeakMap> to keep modules without errors/warnings + const memCache = moduleMemCaches && moduleMemCaches.get(module); + if (memCache && memCache.get("noWarningsOrErrors")) continue; + let hasProblems = this.reportDependencyErrorsAndWarnings(module, [ + module + ]); const errors = module.getErrors(); if (errors !== undefined) { for (const error of errors) { @@ -2099,6 +2870,7 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si error.module = module; } this.errors.push(error); + hasProblems = true; } } const warnings = module.getWarnings(); @@ -2108,9 +2880,12 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si warning.module = module; } this.warnings.push(warning); + hasProblems = true; } } + if (!hasProblems && memCache) memCache.set("noWarningsOrErrors", true); } + this.moduleGraph.unfreeze(); this.logger.timeEnd("report dependency errors and warnings"); callback(); @@ -2128,6 +2903,8 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si this.assets = {}; this.assetsInfo.clear(); this.moduleGraph.removeAllModuleAttributes(); + this.moduleGraph.unfreeze(); + this.moduleMemCaches2 = undefined; } /** @@ -2135,11 +2912,28 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si * @returns {void} */ seal(callback) { - const chunkGraph = new ChunkGraph(this.moduleGraph); + /** + * @param {WebpackError=} err err + * @returns {void} + */ + const finalCallback = err => { + this.factorizeQueue.clear(); + this.buildQueue.clear(); + this.rebuildQueue.clear(); + this.processDependenciesQueue.clear(); + this.addModuleQueue.clear(); + return callback(err); + }; + const chunkGraph = new ChunkGraph( + this.moduleGraph, + this.outputOptions.hashFunction + ); this.chunkGraph = chunkGraph; - for (const module of this.modules) { - ChunkGraph.setChunkGraphForModule(module, chunkGraph); + if (this._backCompat) { + for (const module of this.modules) { + ChunkGraph.setChunkGraphForModule(module, chunkGraph); + } } this.hooks.seal.call(); @@ -2153,6 +2947,7 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si this.logger.time("create chunks"); this.hooks.beforeChunks.call(); + this.moduleGraph.freeze("seal"); /** @type {Map} */ const chunkGraphInit = new Map(); for (const [name, { dependencies, includeDependencies, options }] of this @@ -2171,13 +2966,14 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si this.chunkGroups.push(entrypoint); connectChunkGroupAndChunk(entrypoint, chunk); + const entryModules = new Set(); for (const dep of [...this.globalEntry.dependencies, ...dependencies]) { entrypoint.addOrigin(null, { name }, /** @type {any} */ (dep).request); const module = this.moduleGraph.getModule(dep); if (module) { chunkGraph.connectChunkAndEntryModule(chunk, module, entrypoint); - this.assignDepth(module); + entryModules.add(module); const modulesList = chunkGraphInit.get(entrypoint); if (modulesList === undefined) { chunkGraphInit.set(entrypoint, [module]); @@ -2187,11 +2983,17 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si } } + this.assignDepths(entryModules); + + /** + * @param {Dependency[]} deps deps + * @returns {Module[]} sorted deps + */ const mapAndSort = deps => - deps - .map(dep => this.moduleGraph.getModule(dep)) - .filter(Boolean) - .sort(compareModulesByIdentifier); + /** @type {Module[]} */ + (deps.map(dep => this.moduleGraph.getModule(dep)).filter(Boolean)).sort( + compareModulesByIdentifier + ); const includedModules = [ ...mapAndSort(this.globalEntry.includeDependencies), ...mapAndSort(includeDependencies) @@ -2214,16 +3016,17 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si } ] of this.entries) { if (dependOn && runtime) { - const err = new WebpackError(`Entrypoint '${name}' has 'dependOn' and 'runtime' specified. This is not valid. + const err = + new WebpackError(`Entrypoint '${name}' has 'dependOn' and 'runtime' specified. This is not valid. Entrypoints that depend on other entrypoints do not have their own runtime. They will use the runtime(s) from referenced entrypoints instead. Remove the 'runtime' option from the entrypoint.`); - const entry = this.entrypoints.get(name); + const entry = /** @type {Entrypoint} */ (this.entrypoints.get(name)); err.chunk = entry.getEntrypointChunk(); this.errors.push(err); } if (dependOn) { - const entry = this.entrypoints.get(name); + const entry = /** @type {Entrypoint} */ (this.entrypoints.get(name)); const referencedChunks = entry .getEntrypointChunk() .getAllReferencedChunks(); @@ -2251,17 +3054,20 @@ Remove the 'runtime' option from the entrypoint.`); connectChunkGroupParentAndChild(dependency, entry); } } else if (runtime) { - const entry = this.entrypoints.get(name); + const entry = /** @type {Entrypoint} */ (this.entrypoints.get(name)); let chunk = this.namedChunks.get(runtime); if (chunk) { if (!runtimeChunks.has(chunk)) { - const err = new WebpackError(`Entrypoint '${name}' has a 'runtime' option which points to another entrypoint named '${runtime}'. + const err = + new WebpackError(`Entrypoint '${name}' has a 'runtime' option which points to another entrypoint named '${runtime}'. It's not valid to use other entrypoints as runtime chunk. Did you mean to use 'dependOn: ${JSON.stringify( - runtime - )}' instead to allow using entrypoint '${name}' within the runtime of entrypoint '${runtime}'? For this '${runtime}' must always be loaded when '${name}' is used. + runtime + )}' instead to allow using entrypoint '${name}' within the runtime of entrypoint '${runtime}'? For this '${runtime}' must always be loaded when '${name}' is used. Or do you want to use the entrypoints '${name}' and '${runtime}' independently on the same page with a shared runtime? In this case give them both the same value for the 'runtime' option. It must be a name not already used by an entrypoint.`); - const entryChunk = entry.getEntrypointChunk(); + const entryChunk = + /** @type {Chunk} */ + (entry.getEntrypointChunk()); err.chunk = entryChunk; this.errors.push(err); entry.setRuntimeChunk(entryChunk); @@ -2296,7 +3102,7 @@ Or do you want to use the entrypoints '${name}' and '${runtime}' independently o this.hooks.optimizeTree.callAsync(this.chunks, this.modules, err => { if (err) { - return callback( + return finalCallback( makeWebpackError(err, "Compilation.hooks.optimizeTree") ); } @@ -2308,7 +3114,7 @@ Or do you want to use the entrypoints '${name}' and '${runtime}' independently o this.modules, err => { if (err) { - return callback( + return finalCallback( makeWebpackError(err, "Compilation.hooks.optimizeChunkModules") ); } @@ -2331,6 +3137,10 @@ Or do you want to use the entrypoints '${name}' and '${runtime}' independently o this.assignRuntimeIds(); + this.logger.time("compute affected modules with chunk graph"); + this._computeAffectedModulesWithChunkGraph(); + this.logger.timeEnd("compute affected modules with chunk graph"); + this.sortItemsWithChunkIds(); if (shouldRecord) { @@ -2351,7 +3161,7 @@ Or do you want to use the entrypoints '${name}' and '${runtime}' independently o this.hooks.beforeCodeGeneration.call(); this.codeGeneration(err => { if (err) { - return callback(err); + return finalCallback(err); } this.hooks.afterCodeGeneration.call(); this.logger.timeEnd("code generation"); @@ -2370,7 +3180,7 @@ Or do you want to use the entrypoints '${name}' and '${runtime}' independently o this._runCodeGenerationJobs(codeGenerationJobs, err => { if (err) { - return callback(err); + return finalCallback(err); } if (shouldRecord) { @@ -2390,19 +3200,23 @@ Or do you want to use the entrypoints '${name}' and '${runtime}' independently o this.logger.time("process assets"); this.hooks.processAssets.callAsync(this.assets, err => { if (err) { - return callback( + return finalCallback( makeWebpackError(err, "Compilation.hooks.processAssets") ); } this.hooks.afterProcessAssets.call(this.assets); this.logger.timeEnd("process assets"); - this.assets = soonFrozenObjectDeprecation( - this.assets, - "Compilation.assets", - "DEP_WEBPACK_COMPILATION_ASSETS", - `BREAKING CHANGE: No more changes should happen to Compilation.assets after sealing the Compilation. + this.assets = /** @type {CompilationAssets} */ ( + this._backCompat + ? soonFrozenObjectDeprecation( + this.assets, + "Compilation.assets", + "DEP_WEBPACK_COMPILATION_ASSETS", + `BREAKING CHANGE: No more changes should happen to Compilation.assets after sealing the Compilation. Do changes to assets earlier, e. g. in Compilation.hooks.processAssets. Make sure to select an appropriate stage from Compilation.PROCESS_ASSETS_STAGE_*.` + ) + : Object.freeze(this.assets) ); this.summarizeDependencies(); @@ -2416,12 +3230,12 @@ Or do you want to use the entrypoints '${name}' and '${runtime}' independently o } return this.hooks.afterSeal.callAsync(err => { if (err) { - return callback( + return finalCallback( makeWebpackError(err, "Compilation.hooks.afterSeal") ); } this.fileSystemInfo.logStatistics(); - callback(); + finalCallback(); }); }); }; @@ -2432,7 +3246,7 @@ Or do you want to use the entrypoints '${name}' and '${runtime}' independently o this.createChunkAssets(err => { this.logger.timeEnd("create chunk assets"); if (err) { - return callback(err); + return finalCallback(err); } cont(); }); @@ -2450,9 +3264,10 @@ Or do you want to use the entrypoints '${name}' and '${runtime}' independently o /** * @param {Module} module module to report from * @param {DependenciesBlock[]} blocks blocks to report from - * @returns {void} + * @returns {boolean} true, when it has warnings or errors */ reportDependencyErrorsAndWarnings(module, blocks) { + let hasProblems = false; for (let indexBlock = 0; indexBlock < blocks.length; indexBlock++) { const block = blocks[indexBlock]; const dependencies = block.dependencies; @@ -2467,6 +3282,7 @@ Or do you want to use the entrypoints '${name}' and '${runtime}' independently o const warning = new ModuleDependencyWarning(module, w, d.loc); this.warnings.push(warning); + hasProblems = true; } } const errors = d.getErrors(this.moduleGraph); @@ -2476,18 +3292,26 @@ Or do you want to use the entrypoints '${name}' and '${runtime}' independently o const error = new ModuleDependencyError(module, e, d.loc); this.errors.push(error); + hasProblems = true; } } } - this.reportDependencyErrorsAndWarnings(module, block.blocks); + if (this.reportDependencyErrorsAndWarnings(module, block.blocks)) + hasProblems = true; } + return hasProblems; } + /** + * @param {Callback} callback callback + */ codeGeneration(callback) { const { chunkGraph } = this; - this.codeGenerationResults = new CodeGenerationResults(); - /** @type {{module: Module, hash: string, runtime: RuntimeSpec, runtimes: RuntimeSpec[]}[]} */ + this.codeGenerationResults = new CodeGenerationResults( + this.outputOptions.hashFunction + ); + /** @type {CodeGenerationJobs} */ const jobs = []; for (const module of this.modules) { const runtimes = chunkGraph.getModuleRuntimes(module); @@ -2516,58 +3340,111 @@ Or do you want to use the entrypoints '${name}' and '${runtime}' independently o this._runCodeGenerationJobs(jobs, callback); } + /** + * @private + * @param {CodeGenerationJobs} jobs code generation jobs + * @param {Callback} callback callback + * @returns {void} + */ _runCodeGenerationJobs(jobs, callback) { + if (jobs.length === 0) { + return callback(); + } let statModulesFromCache = 0; let statModulesGenerated = 0; - const { - chunkGraph, - moduleGraph, - dependencyTemplates, - runtimeTemplate - } = this; + const { chunkGraph, moduleGraph, dependencyTemplates, runtimeTemplate } = + this; const results = this.codeGenerationResults; + /** @type {WebpackError[]} */ const errors = []; - asyncLib.eachLimit( - jobs, - this.options.parallelism, - ({ module, hash, runtime, runtimes }, callback) => { - this._codeGenerationModule( - module, - runtime, - runtimes, - hash, - dependencyTemplates, - chunkGraph, - moduleGraph, - runtimeTemplate, - errors, - results, - (err, codeGenerated) => { - if (codeGenerated) statModulesGenerated++; - else statModulesFromCache++; - callback(err); + /** @type {NotCodeGeneratedModules | undefined} */ + let notCodeGeneratedModules; + const runIteration = () => { + /** @type {CodeGenerationJobs} */ + let delayedJobs = []; + let delayedModules = new Set(); + asyncLib.eachLimit( + jobs, + /** @type {number} */ + (this.options.parallelism), + (job, callback) => { + const { module } = job; + const { codeGenerationDependencies } = module; + if ( + codeGenerationDependencies !== undefined && + (notCodeGeneratedModules === undefined || + codeGenerationDependencies.some(dep => { + const referencedModule = /** @type {Module} */ ( + moduleGraph.getModule(dep) + ); + return /** @type {NotCodeGeneratedModules} */ ( + notCodeGeneratedModules + ).has(referencedModule); + })) + ) { + delayedJobs.push(job); + delayedModules.add(module); + return callback(); } - ); - }, - err => { - if (err) return callback(err); - if (errors.length > 0) { - errors.sort( - compareSelect(err => err.module, compareModulesByIdentifier) + const { hash, runtime, runtimes } = job; + this._codeGenerationModule( + module, + runtime, + runtimes, + hash, + dependencyTemplates, + chunkGraph, + moduleGraph, + runtimeTemplate, + errors, + results, + (err, codeGenerated) => { + if (codeGenerated) statModulesGenerated++; + else statModulesFromCache++; + callback(err); + } ); - for (const error of errors) { - this.errors.push(error); + }, + err => { + if (err) return callback(err); + if (delayedJobs.length > 0) { + if (delayedJobs.length === jobs.length) { + return callback( + /** @type {WebpackError} */ ( + new Error( + `Unable to make progress during code generation because of circular code generation dependency: ${Array.from( + delayedModules, + m => m.identifier() + ).join(", ")}` + ) + ) + ); + } + jobs = delayedJobs; + delayedJobs = []; + notCodeGeneratedModules = delayedModules; + delayedModules = new Set(); + return runIteration(); + } + if (errors.length > 0) { + errors.sort( + compareSelect(err => err.module, compareModulesByIdentifier) + ); + for (const error of errors) { + this.errors.push(error); + } } + this.logger.log( + `${Math.round( + (100 * statModulesGenerated) / + (statModulesGenerated + statModulesFromCache) + )}% code generated (${statModulesGenerated} generated, ${statModulesFromCache} from cache)` + ); + callback(); } - this.logger.log( - `${Math.round( - (100 * statModulesGenerated) / - (statModulesGenerated + statModulesFromCache) - )}% code generated (${statModulesGenerated} generated, ${statModulesFromCache} from cache)` - ); - callback(); - } - ); + ); + }; + runIteration(); } /** @@ -2581,7 +3458,7 @@ Or do you want to use the entrypoints '${name}' and '${runtime}' independently o * @param {RuntimeTemplate} runtimeTemplate runtimeTemplate * @param {WebpackError[]} errors errors * @param {CodeGenerationResults} results results - * @param {function(WebpackError=, boolean=): void} callback callback + * @param {function((WebpackError | null)=, boolean=): void} callback callback */ _codeGenerationModule( module, @@ -2606,7 +3483,7 @@ Or do you want to use the entrypoints '${name}' and '${runtime}' independently o ) ); cache.get((err, cachedResult) => { - if (err) return callback(err); + if (err) return callback(/** @type {WebpackError} */ (err)); let result; if (!cachedResult) { try { @@ -2617,10 +3494,14 @@ Or do you want to use the entrypoints '${name}' and '${runtime}' independently o moduleGraph, dependencyTemplates, runtimeTemplate, - runtime + runtime, + codeGenerationResults: results, + compilation: this }); } catch (err) { - errors.push(new CodeGenerationError(module, err)); + errors.push( + new CodeGenerationError(module, /** @type {Error} */ (err)) + ); result = cachedResult = { sources: new Map(), runtimeRequirements: null @@ -2633,49 +3514,121 @@ Or do you want to use the entrypoints '${name}' and '${runtime}' independently o results.add(module, runtime, result); } if (!cachedResult) { - cache.store(result, err => callback(err, codeGenerated)); + cache.store(result, err => + callback(/** @type {WebpackError} */ (err), codeGenerated) + ); } else { callback(null, codeGenerated); } }); } + _getChunkGraphEntries() { + /** @type {Set} */ + const treeEntries = new Set(); + for (const ep of this.entrypoints.values()) { + const chunk = ep.getRuntimeChunk(); + if (chunk) treeEntries.add(chunk); + } + for (const ep of this.asyncEntrypoints) { + const chunk = ep.getRuntimeChunk(); + if (chunk) treeEntries.add(chunk); + } + return treeEntries; + } + /** + * @param {object} options options + * @param {ChunkGraph=} options.chunkGraph the chunk graph + * @param {Iterable=} options.modules modules + * @param {Iterable=} options.chunks chunks + * @param {CodeGenerationResults=} options.codeGenerationResults codeGenerationResults + * @param {Iterable=} options.chunkGraphEntries chunkGraphEntries * @returns {void} */ - processRuntimeRequirements() { - const { chunkGraph } = this; - - const additionalModuleRuntimeRequirements = this.hooks - .additionalModuleRuntimeRequirements; + processRuntimeRequirements({ + chunkGraph = this.chunkGraph, + modules = this.modules, + chunks = this.chunks, + codeGenerationResults = this.codeGenerationResults, + chunkGraphEntries = this._getChunkGraphEntries() + } = {}) { + const context = { chunkGraph, codeGenerationResults }; + const { moduleMemCaches2 } = this; + this.logger.time("runtime requirements.modules"); + const additionalModuleRuntimeRequirements = + this.hooks.additionalModuleRuntimeRequirements; const runtimeRequirementInModule = this.hooks.runtimeRequirementInModule; - for (const module of this.modules) { + for (const module of modules) { if (chunkGraph.getNumberOfModuleChunks(module) > 0) { + const memCache = moduleMemCaches2 && moduleMemCaches2.get(module); for (const runtime of chunkGraph.getModuleRuntimes(module)) { + if (memCache) { + const cached = memCache.get( + `moduleRuntimeRequirements-${getRuntimeKey(runtime)}` + ); + if (cached !== undefined) { + if (cached !== null) { + chunkGraph.addModuleRuntimeRequirements( + module, + runtime, + cached, + false + ); + } + continue; + } + } let set; - const runtimeRequirements = this.codeGenerationResults.getRuntimeRequirements( - module, - runtime - ); + const runtimeRequirements = + codeGenerationResults.getRuntimeRequirements(module, runtime); if (runtimeRequirements && runtimeRequirements.size > 0) { set = new Set(runtimeRequirements); } else if (additionalModuleRuntimeRequirements.isUsed()) { set = new Set(); } else { + if (memCache) { + memCache.set( + `moduleRuntimeRequirements-${getRuntimeKey(runtime)}`, + null + ); + } continue; } - additionalModuleRuntimeRequirements.call(module, set); + additionalModuleRuntimeRequirements.call(module, set, context); for (const r of set) { const hook = runtimeRequirementInModule.get(r); - if (hook !== undefined) hook.call(module, set); + if (hook !== undefined) hook.call(module, set, context); + } + if (set.size === 0) { + if (memCache) { + memCache.set( + `moduleRuntimeRequirements-${getRuntimeKey(runtime)}`, + null + ); + } + } else if (memCache) { + memCache.set( + `moduleRuntimeRequirements-${getRuntimeKey(runtime)}`, + set + ); + chunkGraph.addModuleRuntimeRequirements( + module, + runtime, + set, + false + ); + } else { + chunkGraph.addModuleRuntimeRequirements(module, runtime, set); } - chunkGraph.addModuleRuntimeRequirements(module, runtime, set); } } } + this.logger.timeEnd("runtime requirements.modules"); - for (const chunk of this.chunks) { + this.logger.time("runtime requirements.chunks"); + for (const chunk of chunks) { const set = new Set(); for (const module of chunkGraph.getChunkModulesIterable(chunk)) { const runtimeRequirements = chunkGraph.getModuleRuntimeRequirements( @@ -2684,67 +3637,69 @@ Or do you want to use the entrypoints '${name}' and '${runtime}' independently o ); for (const r of runtimeRequirements) set.add(r); } - this.hooks.additionalChunkRuntimeRequirements.call(chunk, set); + this.hooks.additionalChunkRuntimeRequirements.call(chunk, set, context); for (const r of set) { - this.hooks.runtimeRequirementInChunk.for(r).call(chunk, set); + this.hooks.runtimeRequirementInChunk.for(r).call(chunk, set, context); } chunkGraph.addChunkRuntimeRequirements(chunk, set); } + this.logger.timeEnd("runtime requirements.chunks"); - /** @type {Set} */ - const treeEntries = new Set(); - for (const ep of this.entrypoints.values()) { - const chunk = ep.getRuntimeChunk(); - if (chunk) treeEntries.add(chunk); - } - for (const ep of this.asyncEntrypoints) { - const chunk = ep.getRuntimeChunk(); - if (chunk) treeEntries.add(chunk); - } - - for (const treeEntry of treeEntries) { + this.logger.time("runtime requirements.entries"); + for (const treeEntry of chunkGraphEntries) { const set = new Set(); for (const chunk of treeEntry.getAllReferencedChunks()) { - const runtimeRequirements = chunkGraph.getChunkRuntimeRequirements( - chunk - ); + const runtimeRequirements = + chunkGraph.getChunkRuntimeRequirements(chunk); for (const r of runtimeRequirements) set.add(r); } - this.hooks.additionalTreeRuntimeRequirements.call(treeEntry, set); + this.hooks.additionalTreeRuntimeRequirements.call( + treeEntry, + set, + context + ); for (const r of set) { - this.hooks.runtimeRequirementInTree.for(r).call(treeEntry, set); + this.hooks.runtimeRequirementInTree + .for(r) + .call(treeEntry, set, context); } chunkGraph.addTreeRuntimeRequirements(treeEntry, set); } + this.logger.timeEnd("runtime requirements.entries"); } + // TODO webpack 6 make chunkGraph argument non-optional /** * @param {Chunk} chunk target chunk * @param {RuntimeModule} module runtime module + * @param {ChunkGraph} chunkGraph the chunk graph * @returns {void} */ - addRuntimeModule(chunk, module) { + addRuntimeModule(chunk, module, chunkGraph = this.chunkGraph) { // Deprecated ModuleGraph association - ModuleGraph.setModuleGraphForModule(module, this.moduleGraph); + if (this._backCompat) + ModuleGraph.setModuleGraphForModule(module, this.moduleGraph); // add it to the list this.modules.add(module); this._modules.set(module.identifier(), module); // connect to the chunk graph - this.chunkGraph.connectChunkAndModule(chunk, module); - this.chunkGraph.connectChunkAndRuntimeModule(chunk, module); + chunkGraph.connectChunkAndModule(chunk, module); + chunkGraph.connectChunkAndRuntimeModule(chunk, module); if (module.fullHash) { - this.chunkGraph.addFullHashModuleToChunk(chunk, module); + chunkGraph.addFullHashModuleToChunk(chunk, module); + } else if (module.dependentHash) { + chunkGraph.addDependentHashModuleToChunk(chunk, module); } // attach runtime module - module.attach(this, chunk); + module.attach(this, chunk, chunkGraph); // Setup internals const exportsInfo = this.moduleGraph.getExportsInfo(module); @@ -2758,24 +3713,25 @@ Or do you want to use the entrypoints '${name}' and '${runtime}' independently o exportsInfo.setUsedForSideEffectsOnly(runtime); } } - this.chunkGraph.addModuleRuntimeRequirements( + chunkGraph.addModuleRuntimeRequirements( module, chunk.runtime, new Set([RuntimeGlobals.requireScope]) ); // runtime modules don't need ids - this.chunkGraph.setModuleId(module, ""); + chunkGraph.setModuleId(module, ""); // Call hook this.hooks.runtimeModule.call(module, chunk); } /** + * If `module` is passed, `loc` and `request` must also be passed. * @param {string | ChunkGroupOptions} groupOptions options for the chunk group - * @param {Module} module the module the references the chunk group - * @param {DependencyLocation} loc the location from with the chunk group is referenced (inside of module) - * @param {string} request the request from which the the chunk group is referenced + * @param {Module=} module the module the references the chunk group + * @param {DependencyLocation=} loc the location from with the chunk group is referenced (inside of module) + * @param {string=} request the request from which the the chunk group is referenced * @returns {ChunkGroup} the new or existing chunk group */ addChunkInGroup(groupOptions, module, loc, request) { @@ -2789,13 +3745,24 @@ Or do you want to use the entrypoints '${name}' and '${runtime}' independently o if (chunkGroup !== undefined) { chunkGroup.addOptions(groupOptions); if (module) { - chunkGroup.addOrigin(module, loc, request); + chunkGroup.addOrigin( + module, + /** @type {DependencyLocation} */ + (loc), + request + ); } return chunkGroup; } } const chunkGroup = new ChunkGroup(groupOptions); - if (module) chunkGroup.addOrigin(module, loc, request); + if (module) + chunkGroup.addOrigin( + module, + /** @type {DependencyLocation} */ + (loc), + request + ); const chunk = this.addChunk(name); connectChunkGroupAndChunk(chunkGroup, chunk); @@ -2853,7 +3820,6 @@ Or do you want to use the entrypoints '${name}' and '${runtime}' independently o /** * This method first looks to see if a name is provided for a new chunk, * and first looks to see if any named chunks already exist and reuse that chunk instead. - * * @param {string=} name optional chunk name to be provided * @returns {Chunk} create a chunk (invoked during seal event) */ @@ -2864,9 +3830,10 @@ Or do you want to use the entrypoints '${name}' and '${runtime}' independently o return chunk; } } - const chunk = new Chunk(name); + const chunk = new Chunk(name, this._backCompat); this.chunks.add(chunk); - ChunkGraph.setChunkGraphForChunk(chunk, this.chunkGraph); + if (this._backCompat) + ChunkGraph.setChunkGraphForChunk(chunk, this.chunkGraph); if (name) { this.namedChunks.set(name, chunk); } @@ -2874,6 +3841,7 @@ Or do you want to use the entrypoints '${name}' and '${runtime}' independently o } /** + * @deprecated * @param {Module} module module to assign depth * @returns {void} */ @@ -2881,6 +3849,7 @@ Or do you want to use the entrypoints '${name}' and '${runtime}' independently o const moduleGraph = this.moduleGraph; const queue = new Set([module]); + /** @type {number} */ let depth; moduleGraph.setDepth(module, 0); @@ -2896,7 +3865,7 @@ Or do you want to use the entrypoints '${name}' and '${runtime}' independently o for (module of queue) { queue.delete(module); - depth = moduleGraph.getDepth(module) + 1; + depth = /** @type {number} */ (moduleGraph.getDepth(module)) + 1; for (const connection of moduleGraph.getOutgoingConnections(module)) { const refModule = connection.module; @@ -2907,6 +3876,38 @@ Or do you want to use the entrypoints '${name}' and '${runtime}' independently o } } + /** + * @param {Set} modules module to assign depth + * @returns {void} + */ + assignDepths(modules) { + const moduleGraph = this.moduleGraph; + + /** @type {Set} */ + const queue = new Set(modules); + queue.add(1); + let depth = 0; + + let i = 0; + for (const module of queue) { + i++; + if (typeof module === "number") { + depth = module; + if (queue.size === i) return; + queue.add(depth + 1); + } else { + moduleGraph.setDepth(module, depth); + for (const { module: refModule } of moduleGraph.getOutgoingConnections( + module + )) { + if (refModule) { + queue.add(refModule); + } + } + } + } + } + /** * @param {Dependency} dependency the dependency * @param {RuntimeSpec} runtime the runtime @@ -2925,7 +3926,6 @@ Or do you want to use the entrypoints '${name}' and '${runtime}' independently o } /** - * * @param {Module} module module relationship for removal * @param {DependenciesBlockLike} block //TODO: good description * @returns {void} @@ -2964,16 +3964,16 @@ Or do you want to use the entrypoints '${name}' and '${runtime}' independently o if (!module.hasReasons(this.moduleGraph, chunk.runtime)) { this.removeReasonsOfDependencyBlock(module, module); } - if (!module.hasReasonForChunk(chunk, this.moduleGraph, this.chunkGraph)) { - if (this.chunkGraph.isModuleInChunk(module, chunk)) { - this.chunkGraph.disconnectChunkAndModule(chunk, module); - this.removeChunkFromDependencies(module, chunk); - } + if ( + !module.hasReasonForChunk(chunk, this.moduleGraph, this.chunkGraph) && + this.chunkGraph.isModuleInChunk(module, chunk) + ) { + this.chunkGraph.disconnectChunkAndModule(chunk, module); + this.removeChunkFromDependencies(module, chunk); } } /** - * * @param {DependenciesBlock} block block tie for Chunk * @param {Chunk} chunk chunk to remove from dep * @returns {void} @@ -2993,7 +3993,9 @@ Or do you want to use the entrypoints '${name}' and '${runtime}' independently o const blocks = block.blocks; for (let indexBlock = 0; indexBlock < blocks.length; indexBlock++) { const asyncBlock = blocks[indexBlock]; - const chunkGroup = this.chunkGraph.getBlockChunkGroup(asyncBlock); + const chunkGroup = + /** @type {ChunkGroup} */ + (this.chunkGraph.getBlockChunkGroup(asyncBlock)); // Grab all chunks from the first Block's AsyncDepBlock const chunks = chunkGroup.chunks; // For each chunk in chunkGroup @@ -3061,29 +4063,70 @@ Or do you want to use the entrypoints '${name}' and '${runtime}' independently o createModuleHashes() { let statModulesHashed = 0; - const { chunkGraph, runtimeTemplate } = this; + let statModulesFromCache = 0; + const { chunkGraph, runtimeTemplate, moduleMemCaches2 } = this; const { hashFunction, hashDigest, hashDigestLength } = this.outputOptions; + /** @type {WebpackError[]} */ + const errors = []; for (const module of this.modules) { + const memCache = moduleMemCaches2 && moduleMemCaches2.get(module); for (const runtime of chunkGraph.getModuleRuntimes(module)) { + if (memCache) { + const digest = memCache.get(`moduleHash-${getRuntimeKey(runtime)}`); + if (digest !== undefined) { + chunkGraph.setModuleHashes( + module, + runtime, + digest, + digest.slice(0, hashDigestLength) + ); + statModulesFromCache++; + continue; + } + } statModulesHashed++; - this._createModuleHash( + const digest = this._createModuleHash( module, chunkGraph, runtime, hashFunction, runtimeTemplate, hashDigest, - hashDigestLength + hashDigestLength, + errors ); + if (memCache) { + memCache.set(`moduleHash-${getRuntimeKey(runtime)}`, digest); + } + } + } + if (errors.length > 0) { + errors.sort(compareSelect(err => err.module, compareModulesByIdentifier)); + for (const error of errors) { + this.errors.push(error); } } this.logger.log( - `${statModulesHashed} modules hashed (${ - Math.round((100 * statModulesHashed) / this.modules.size) / 100 + `${statModulesHashed} modules hashed, ${statModulesFromCache} from cache (${ + Math.round( + (100 * (statModulesHashed + statModulesFromCache)) / this.modules.size + ) / 100 } variants per module in average)` ); } + /** + * @private + * @param {Module} module module + * @param {ChunkGraph} chunkGraph the chunk graph + * @param {RuntimeSpec} runtime runtime + * @param {OutputOptions["hashFunction"]} hashFunction hash function + * @param {RuntimeTemplate} runtimeTemplate runtime template + * @param {OutputOptions["hashDigest"]} hashDigest hash digest + * @param {OutputOptions["hashDigestLength"]} hashDigestLength hash digest length + * @param {WebpackError[]} errors errors + * @returns {string} module hash digest + */ _createModuleHash( module, chunkGraph, @@ -3091,29 +4134,34 @@ Or do you want to use the entrypoints '${name}' and '${runtime}' independently o hashFunction, runtimeTemplate, hashDigest, - hashDigestLength + hashDigestLength, + errors ) { - const moduleHash = createHash(hashFunction); - module.updateHash(moduleHash, { - chunkGraph, - runtime, - runtimeTemplate - }); - const moduleHashDigest = /** @type {string} */ (moduleHash.digest( - hashDigest - )); + let moduleHashDigest; + try { + const moduleHash = createHash(hashFunction); + module.updateHash(moduleHash, { + chunkGraph, + runtime, + runtimeTemplate + }); + moduleHashDigest = /** @type {string} */ (moduleHash.digest(hashDigest)); + } catch (err) { + errors.push(new ModuleHashingError(module, /** @type {Error} */ (err))); + moduleHashDigest = "XXXXXX"; + } chunkGraph.setModuleHashes( module, runtime, moduleHashDigest, - moduleHashDigest.substr(0, hashDigestLength) + moduleHashDigest.slice(0, hashDigestLength) ); return moduleHashDigest; } createHash() { this.logger.time("hashing: initialize hash"); - const chunkGraph = this.chunkGraph; + const chunkGraph = /** @type {ChunkGraph} */ (this.chunkGraph); const runtimeTemplate = this.runtimeTemplate; const outputOptions = this.outputOptions; const hashFunction = outputOptions.hashFunction; @@ -3206,8 +4254,15 @@ Or do you want to use the entrypoints '${name}' and '${runtime}' independently o if (remaining > 0) { const readyChunks = []; for (const chunk of runtimeChunks) { - const info = runtimeChunksMap.get(chunk); + const hasFullHashModules = + chunkGraph.getNumberOfChunkFullHashModules(chunk) !== 0; + const info = + /** @type {RuntimeChunkInfo} */ + (runtimeChunksMap.get(chunk)); for (const otherInfo of info.referencedBy) { + if (hasFullHashModules) { + chunkGraph.upgradeDependentToFullHashModules(otherInfo.chunk); + } remaining--; if (--otherInfo.remaining === 0) { readyChunks.push(otherInfo.chunk); @@ -3223,17 +4278,18 @@ Or do you want to use the entrypoints '${name}' and '${runtime}' independently o } // If there are still remaining references we have cycles and want to create a warning if (remaining > 0) { - let circularRuntimeChunkInfo = []; + const circularRuntimeChunkInfo = []; for (const info of runtimeChunksMap.values()) { if (info.remaining !== 0) { circularRuntimeChunkInfo.push(info); } } circularRuntimeChunkInfo.sort(compareSelect(i => i.chunk, byId)); - const err = new WebpackError(`Circular dependency between chunks with runtime (${Array.from( - circularRuntimeChunkInfo, - c => c.chunk.name || c.chunk.id - ).join(", ")}) + const err = + new WebpackError(`Circular dependency between chunks with runtime (${Array.from( + circularRuntimeChunkInfo, + c => c.chunk.name || c.chunk.id + ).join(", ")}) This prevents using hashes of each other and should be avoided.`); err.chunk = circularRuntimeChunkInfo[0].chunk; this.warnings.push(err); @@ -3246,7 +4302,12 @@ This prevents using hashes of each other and should be avoided.`); const codeGenerationJobs = []; /** @type {Map>} */ const codeGenerationJobsMap = new Map(); + /** @type {WebpackError[]} */ + const errors = []; + /** + * @param {Chunk} chunk chunk + */ const processChunk = chunk => { // Last minute module hash generation for modules that depend on chunk hashes this.logger.time("hashing: hash runtime modules"); @@ -3260,7 +4321,8 @@ This prevents using hashes of each other and should be avoided.`); hashFunction, runtimeTemplate, hashDigest, - hashDigestLength + hashDigestLength, + errors ); let hashMap = codeGenerationJobsMap.get(hash); if (hashMap) { @@ -3284,77 +4346,87 @@ This prevents using hashes of each other and should be avoided.`); } } this.logger.timeAggregate("hashing: hash runtime modules"); - this.logger.time("hashing: hash chunks"); - const chunkHash = createHash(hashFunction); try { + this.logger.time("hashing: hash chunks"); + const chunkHash = createHash(hashFunction); if (outputOptions.hashSalt) { chunkHash.update(outputOptions.hashSalt); } chunk.updateHash(chunkHash, chunkGraph); this.hooks.chunkHash.call(chunk, chunkHash, { chunkGraph, + codeGenerationResults: this.codeGenerationResults, moduleGraph: this.moduleGraph, runtimeTemplate: this.runtimeTemplate }); - const chunkHashDigest = /** @type {string} */ (chunkHash.digest( - hashDigest - )); + const chunkHashDigest = /** @type {string} */ ( + chunkHash.digest(hashDigest) + ); hash.update(chunkHashDigest); chunk.hash = chunkHashDigest; - chunk.renderedHash = chunk.hash.substr(0, hashDigestLength); - const fullHashModules = chunkGraph.getChunkFullHashModulesIterable( - chunk - ); + chunk.renderedHash = chunk.hash.slice(0, hashDigestLength); + const fullHashModules = + chunkGraph.getChunkFullHashModulesIterable(chunk); if (fullHashModules) { fullHashChunks.add(chunk); } else { this.hooks.contentHash.call(chunk); } } catch (err) { - this.errors.push(new ChunkRenderError(chunk, "", err)); + this.errors.push( + new ChunkRenderError(chunk, "", /** @type {Error} */ (err)) + ); } this.logger.timeAggregate("hashing: hash chunks"); }; - otherChunks.forEach(processChunk); + for (const chunk of otherChunks) processChunk(chunk); for (const chunk of runtimeChunks) processChunk(chunk); + if (errors.length > 0) { + errors.sort(compareSelect(err => err.module, compareModulesByIdentifier)); + for (const error of errors) { + this.errors.push(error); + } + } this.logger.timeAggregateEnd("hashing: hash runtime modules"); this.logger.timeAggregateEnd("hashing: hash chunks"); this.logger.time("hashing: hash digest"); this.hooks.fullHash.call(hash); this.fullHash = /** @type {string} */ (hash.digest(hashDigest)); - this.hash = this.fullHash.substr(0, hashDigestLength); + this.hash = this.fullHash.slice(0, hashDigestLength); this.logger.timeEnd("hashing: hash digest"); this.logger.time("hashing: process full hash modules"); for (const chunk of fullHashChunks) { - for (const module of chunkGraph.getChunkFullHashModulesIterable(chunk)) { + for (const module of /** @type {Iterable} */ ( + chunkGraph.getChunkFullHashModulesIterable(chunk) + )) { const moduleHash = createHash(hashFunction); module.updateHash(moduleHash, { chunkGraph, runtime: chunk.runtime, runtimeTemplate }); - const moduleHashDigest = /** @type {string} */ (moduleHash.digest( - hashDigest - )); + const moduleHashDigest = /** @type {string} */ ( + moduleHash.digest(hashDigest) + ); const oldHash = chunkGraph.getModuleHash(module, chunk.runtime); chunkGraph.setModuleHashes( module, chunk.runtime, moduleHashDigest, - moduleHashDigest.substr(0, hashDigestLength) + moduleHashDigest.slice(0, hashDigestLength) ); codeGenerationJobsMap.get(oldHash).get(module).hash = moduleHashDigest; } const chunkHash = createHash(hashFunction); chunkHash.update(chunk.hash); chunkHash.update(this.hash); - const chunkHashDigest = /** @type {string} */ (chunkHash.digest( - hashDigest - )); + const chunkHashDigest = + /** @type {string} */ + (chunkHash.digest(hashDigest)); chunk.hash = chunkHashDigest; - chunk.renderedHash = chunk.hash.substr(0, hashDigestLength); + chunk.renderedHash = chunk.hash.slice(0, hashDigestLength); this.hooks.contentHash.call(chunk); } this.logger.timeEnd("hashing: process full hash modules"); @@ -3372,7 +4444,11 @@ This prevents using hashes of each other and should be avoided.`); if (!isSourceEqual(this.assets[file], source)) { this.errors.push( new WebpackError( - `Conflict: Multiple assets emit different content to the same filename ${file}` + `Conflict: Multiple assets emit different content to the same filename ${file}${ + assetInfo.sourceFilename + ? `. Original source ${assetInfo.sourceFilename}` + : "" + }` ) ); this.assets[file] = source; @@ -3380,7 +4456,7 @@ This prevents using hashes of each other and should be avoided.`); return; } const oldInfo = this.assetsInfo.get(file); - const newInfo = Object.assign({}, oldInfo, assetInfo); + const newInfo = { ...oldInfo, ...assetInfo }; this._setAssetInfo(file, newInfo, oldInfo); return; } @@ -3398,6 +4474,9 @@ This prevents using hashes of each other and should be avoided.`); const newRelated = newInfo && newInfo.related; if (oldRelated) { for (const key of Object.keys(oldRelated)) { + /** + * @param {string} name name + */ const remove = name => { const relatedIn = this._assetsRelatedIn.get(name); if (relatedIn === undefined) return; @@ -3410,7 +4489,9 @@ This prevents using hashes of each other and should be avoided.`); }; const entry = oldRelated[key]; if (Array.isArray(entry)) { - entry.forEach(remove); + for (const name of entry) { + remove(name); + } } else if (entry) { remove(entry); } @@ -3418,6 +4499,9 @@ This prevents using hashes of each other and should be avoided.`); } if (newRelated) { for (const key of Object.keys(newRelated)) { + /** + * @param {string} name name + */ const add = name => { let relatedIn = this._assetsRelatedIn.get(name); if (relatedIn === undefined) { @@ -3431,7 +4515,9 @@ This prevents using hashes of each other and should be avoided.`); }; const entry = newRelated[key]; if (Array.isArray(entry)) { - entry.forEach(add); + for (const name of entry) { + add(name); + } } else if (entry) { add(entry); } @@ -3442,7 +4528,7 @@ This prevents using hashes of each other and should be avoided.`); /** * @param {string} file file name * @param {Source | function(Source): Source} newSourceOrFunction new asset source or function converting old to new - * @param {AssetInfo | function(AssetInfo | undefined): AssetInfo} assetInfoUpdateOrFunction new asset info or function converting old to new + * @param {(AssetInfo | function(AssetInfo | undefined): AssetInfo) | undefined} assetInfoUpdateOrFunction new asset info or function converting old to new */ updateAsset( file, @@ -3454,11 +4540,10 @@ This prevents using hashes of each other and should be avoided.`); `Called Compilation.updateAsset for not existing filename ${file}` ); } - if (typeof newSourceOrFunction === "function") { - this.assets[file] = newSourceOrFunction(this.assets[file]); - } else { - this.assets[file] = newSourceOrFunction; - } + this.assets[file] = + typeof newSourceOrFunction === "function" + ? newSourceOrFunction(this.assets[file]) + : newSourceOrFunction; if (assetInfoUpdateOrFunction !== undefined) { const oldInfo = this.assetsInfo.get(file) || EMPTY_ASSET_INFO; if (typeof assetInfoUpdateOrFunction === "function") { @@ -3473,6 +4558,10 @@ This prevents using hashes of each other and should be avoided.`); } } + /** + * @param {string} file file name + * @param {string} newFile the new name of file + */ renameAsset(file, newFile) { const source = this.assets[file]; if (!source) { @@ -3480,14 +4569,12 @@ This prevents using hashes of each other and should be avoided.`); `Called Compilation.renameAsset for not existing filename ${file}` ); } - if (this.assets[newFile]) { - if (!isSourceEqual(this.assets[file], source)) { - this.errors.push( - new WebpackError( - `Conflict: Called Compilation.renameAsset for already existing filename ${newFile} with different content` - ) - ); - } + if (this.assets[newFile] && !isSourceEqual(this.assets[file], source)) { + this.errors.push( + new WebpackError( + `Conflict: Called Compilation.renameAsset for already existing filename ${newFile} with different content` + ) + ); } const assetInfo = this.assetsInfo.get(file); // Update related in all other assets @@ -3551,6 +4638,9 @@ This prevents using hashes of each other and should be avoided.`); const related = assetInfo && assetInfo.related; if (related) { for (const key of Object.keys(related)) { + /** + * @param {string} file file + */ const checkUsedAndDelete = file => { if (!this._assetsRelatedIn.has(file)) { this.deleteAsset(file); @@ -3558,7 +4648,9 @@ This prevents using hashes of each other and should be avoided.`); }; const items = related[key]; if (Array.isArray(items)) { - items.forEach(checkUsedAndDelete); + for (const file of items) { + checkUsedAndDelete(file); + } } else if (items) { checkUsedAndDelete(items); } @@ -3592,8 +4684,7 @@ This prevents using hashes of each other and should be avoided.`); * @returns {Readonly | undefined} the asset or undefined when not found */ getAsset(name) { - if (!Object.prototype.hasOwnProperty.call(this.assets, name)) - return undefined; + if (!Object.prototype.hasOwnProperty.call(this.assets, name)) return; return { name, source: this.assets[name], @@ -3611,9 +4702,10 @@ This prevents using hashes of each other and should be avoided.`); createModuleAssets() { const { chunkGraph } = this; for (const module of this.modules) { - if (module.buildInfo.assets) { - const assetsInfo = module.buildInfo.assetsInfo; - for (const assetName of Object.keys(module.buildInfo.assets)) { + const buildInfo = /** @type {BuildInfo} */ (module.buildInfo); + if (buildInfo.assets) { + const assetsInfo = buildInfo.assetsInfo; + for (const assetName of Object.keys(buildInfo.assets)) { const fileName = this.getPath(assetName, { chunkGraph: this.chunkGraph, module @@ -3623,7 +4715,7 @@ This prevents using hashes of each other and should be avoided.`); } this.emitAsset( fileName, - module.buildInfo.assets[assetName], + buildInfo.assets[assetName], assetsInfo ? assetsInfo.get(assetName) : undefined ); this.hooks.moduleAsset.call(module, fileName); @@ -3650,8 +4742,9 @@ This prevents using hashes of each other and should be avoided.`); /** @type {Map} */ const alreadyWrittenFiles = new Map(); - asyncLib.forEach( + asyncLib.forEachLimit( this.chunks, + 15, (chunk, callback) => { /** @type {RenderManifestEntry[]} */ let manifest; @@ -3669,10 +4762,12 @@ This prevents using hashes of each other and should be avoided.`); runtimeTemplate: this.runtimeTemplate }); } catch (err) { - this.errors.push(new ChunkRenderError(chunk, "", err)); + this.errors.push( + new ChunkRenderError(chunk, "", /** @type {Error} */ (err)) + ); return callback(); } - asyncLib.forEach( + asyncLib.each( manifest, (fileManifest, callback) => { const ident = fileManifest.identifier; @@ -3684,7 +4779,7 @@ This prevents using hashes of each other and should be avoided.`); ); assetCacheItem.get((err, sourceFromCache) => { - /** @type {string | function(PathData, AssetInfo=): string} */ + /** @type {TemplatePath} */ let filenameTemplate; /** @type {string} */ let file; @@ -3692,14 +4787,18 @@ This prevents using hashes of each other and should be avoided.`); let assetInfo; let inTry = true; + /** + * @param {Error} err error + * @returns {void} + */ const errorAndCallback = err => { const filename = file || (typeof file === "string" ? file : typeof filenameTemplate === "string" - ? filenameTemplate - : ""); + ? filenameTemplate + : ""); this.errors.push(new ChunkRenderError(chunk, filename, err)); inTry = false; @@ -3721,7 +4820,7 @@ This prevents using hashes of each other and should be avoided.`); ? { ...pathAndInfo.info, ...fileManifest.info - } + } : pathAndInfo.info; } @@ -3742,9 +4841,8 @@ This prevents using hashes of each other and should be avoided.`); ` (chunks ${alreadyWritten.chunk.id} and ${chunk.id})` ) ); - } else { - source = alreadyWritten.source; } + source = alreadyWritten.source; } else if (!source) { // render the asset source = fileManifest.render(); @@ -3785,7 +4883,7 @@ This prevents using hashes of each other and should be avoided.`); } } catch (err) { if (!inTry) throw err; - errorAndCallback(err); + errorAndCallback(/** @type {Error} */ (err)); } }); }, @@ -3797,7 +4895,7 @@ This prevents using hashes of each other and should be avoided.`); } /** - * @param {string | function(PathData, AssetInfo=): string} filename used to get asset path with hash + * @param {TemplatePath} filename used to get asset path with hash * @param {PathData} data context data * @returns {string} interpolated path */ @@ -3812,9 +4910,9 @@ This prevents using hashes of each other and should be avoided.`); } /** - * @param {string | function(PathData, AssetInfo=): string} filename used to get asset path with hash + * @param {TemplatePath} filename used to get asset path with hash * @param {PathData} data context data - * @returns {{ path: string, info: AssetInfo }} interpolated path and asset info + * @returns {InterpolatedPathAndAssetInfo} interpolated path and asset info */ getPathWithInfo(filename, data = {}) { if (!data.hash) { @@ -3827,7 +4925,7 @@ This prevents using hashes of each other and should be avoided.`); } /** - * @param {string | function(PathData, AssetInfo=): string} filename used to get asset path with hash + * @param {TemplatePath} filename used to get asset path with hash * @param {PathData} data context data * @returns {string} interpolated path */ @@ -3840,9 +4938,9 @@ This prevents using hashes of each other and should be avoided.`); } /** - * @param {string | function(PathData, AssetInfo=): string} filename used to get asset path with hash + * @param {TemplatePath} filename used to get asset path with hash * @param {PathData} data context data - * @returns {{ path: string, info: AssetInfo }} interpolated path and asset info + * @returns {InterpolatedPathAndAssetInfo} interpolated path and asset info */ getAssetPathWithInfo(filename, data) { const assetInfo = {}; @@ -3867,10 +4965,9 @@ This prevents using hashes of each other and should be avoided.`); * This function allows you to run another instance of webpack inside of webpack however as * a child with different settings and configurations (if desired) applied. It copies all hooks, plugins * from parent (or top level compiler) and creates a child Compilation - * * @param {string} name name of the child compiler - * @param {OutputOptions} outputOptions // Need to convert config schema to types for this - * @param {Array} plugins webpack plugins that will be applied + * @param {OutputOptions=} outputOptions // Need to convert config schema to types for this + * @param {Array=} plugins webpack plugins that will be applied * @returns {Compiler} creates a child Compiler instance */ createChildCompiler(name, outputOptions, plugins) { @@ -3885,6 +4982,355 @@ This prevents using hashes of each other and should be avoided.`); ); } + /** + * @param {Module} module the module + * @param {ExecuteModuleOptions} options options + * @param {ExecuteModuleCallback} callback callback + */ + executeModule(module, options, callback) { + // Aggregate all referenced modules and ensure they are ready + const modules = new Set([module]); + processAsyncTree( + modules, + 10, + (module, push, callback) => { + this.buildQueue.waitFor(module, err => { + if (err) return callback(err); + this.processDependenciesQueue.waitFor(module, err => { + if (err) return callback(err); + for (const { module: m } of this.moduleGraph.getOutgoingConnections( + module + )) { + const size = modules.size; + modules.add(m); + if (modules.size !== size) push(m); + } + callback(); + }); + }); + }, + err => { + if (err) return callback(/** @type {WebpackError} */ (err)); + + // Create new chunk graph, chunk and entrypoint for the build time execution + const chunkGraph = new ChunkGraph( + this.moduleGraph, + this.outputOptions.hashFunction + ); + const runtime = "build time"; + const { hashFunction, hashDigest, hashDigestLength } = + this.outputOptions; + const runtimeTemplate = this.runtimeTemplate; + + const chunk = new Chunk("build time chunk", this._backCompat); + chunk.id = /** @type {ChunkId} */ (chunk.name); + chunk.ids = [chunk.id]; + chunk.runtime = runtime; + + const entrypoint = new Entrypoint({ + runtime, + chunkLoading: false, + ...options.entryOptions + }); + chunkGraph.connectChunkAndEntryModule(chunk, module, entrypoint); + connectChunkGroupAndChunk(entrypoint, chunk); + entrypoint.setRuntimeChunk(chunk); + entrypoint.setEntrypointChunk(chunk); + + const chunks = new Set([chunk]); + + // Assign ids to modules and modules to the chunk + for (const module of modules) { + const id = module.identifier(); + chunkGraph.setModuleId(module, id); + chunkGraph.connectChunkAndModule(chunk, module); + } + + /** @type {WebpackError[]} */ + const errors = []; + + // Hash modules + for (const module of modules) { + this._createModuleHash( + module, + chunkGraph, + runtime, + hashFunction, + runtimeTemplate, + hashDigest, + hashDigestLength, + errors + ); + } + + const codeGenerationResults = new CodeGenerationResults( + this.outputOptions.hashFunction + ); + /** + * @param {Module} module the module + * @param {Callback} callback callback + * @returns {void} + */ + const codeGen = (module, callback) => { + this._codeGenerationModule( + module, + runtime, + [runtime], + chunkGraph.getModuleHash(module, runtime), + this.dependencyTemplates, + chunkGraph, + this.moduleGraph, + runtimeTemplate, + errors, + codeGenerationResults, + (err, codeGenerated) => { + callback(err); + } + ); + }; + + const reportErrors = () => { + if (errors.length > 0) { + errors.sort( + compareSelect(err => err.module, compareModulesByIdentifier) + ); + for (const error of errors) { + this.errors.push(error); + } + errors.length = 0; + } + }; + + // Generate code for all aggregated modules + asyncLib.eachLimit(modules, 10, codeGen, err => { + if (err) return callback(err); + reportErrors(); + + // for backward-compat temporary set the chunk graph + // TODO webpack 6 + const old = this.chunkGraph; + this.chunkGraph = chunkGraph; + this.processRuntimeRequirements({ + chunkGraph, + modules, + chunks, + codeGenerationResults, + chunkGraphEntries: chunks + }); + this.chunkGraph = old; + + const runtimeModules = + chunkGraph.getChunkRuntimeModulesIterable(chunk); + + // Hash runtime modules + for (const module of runtimeModules) { + modules.add(module); + this._createModuleHash( + module, + chunkGraph, + runtime, + hashFunction, + runtimeTemplate, + hashDigest, + hashDigestLength, + errors + ); + } + + // Generate code for all runtime modules + asyncLib.eachLimit(runtimeModules, 10, codeGen, err => { + if (err) return callback(err); + reportErrors(); + + /** @type {Map} */ + const moduleArgumentsMap = new Map(); + /** @type {Map} */ + const moduleArgumentsById = new Map(); + + /** @type {ExecuteModuleResult["fileDependencies"]} */ + const fileDependencies = new LazySet(); + /** @type {ExecuteModuleResult["contextDependencies"]} */ + const contextDependencies = new LazySet(); + /** @type {ExecuteModuleResult["missingDependencies"]} */ + const missingDependencies = new LazySet(); + /** @type {ExecuteModuleResult["buildDependencies"]} */ + const buildDependencies = new LazySet(); + + /** @type {ExecuteModuleResult["assets"]} */ + const assets = new Map(); + + let cacheable = true; + + /** @type {ExecuteModuleContext} */ + const context = { + assets, + __webpack_require__: undefined, + chunk, + chunkGraph + }; + + // Prepare execution + asyncLib.eachLimit( + modules, + 10, + (module, callback) => { + const codeGenerationResult = codeGenerationResults.get( + module, + runtime + ); + /** @type {ExecuteModuleArgument} */ + const moduleArgument = { + module, + codeGenerationResult, + preparedInfo: undefined, + moduleObject: undefined + }; + moduleArgumentsMap.set(module, moduleArgument); + moduleArgumentsById.set(module.identifier(), moduleArgument); + module.addCacheDependencies( + fileDependencies, + contextDependencies, + missingDependencies, + buildDependencies + ); + if ( + /** @type {BuildInfo} */ (module.buildInfo).cacheable === + false + ) { + cacheable = false; + } + if (module.buildInfo && module.buildInfo.assets) { + const { assets: moduleAssets, assetsInfo } = module.buildInfo; + for (const assetName of Object.keys(moduleAssets)) { + assets.set(assetName, { + source: moduleAssets[assetName], + info: assetsInfo ? assetsInfo.get(assetName) : undefined + }); + } + } + this.hooks.prepareModuleExecution.callAsync( + moduleArgument, + context, + callback + ); + }, + err => { + if (err) return callback(err); + + let exports; + try { + const { + strictModuleErrorHandling, + strictModuleExceptionHandling + } = this.outputOptions; + const __webpack_require__ = id => { + const cached = moduleCache[id]; + if (cached !== undefined) { + if (cached.error) throw cached.error; + return cached.exports; + } + const moduleArgument = moduleArgumentsById.get(id); + return __webpack_require_module__(moduleArgument, id); + }; + const interceptModuleExecution = (__webpack_require__[ + RuntimeGlobals.interceptModuleExecution.replace( + `${RuntimeGlobals.require}.`, + "" + ) + ] = []); + const moduleCache = (__webpack_require__[ + RuntimeGlobals.moduleCache.replace( + `${RuntimeGlobals.require}.`, + "" + ) + ] = {}); + + context.__webpack_require__ = __webpack_require__; + + /** + * @param {ExecuteModuleArgument} moduleArgument the module argument + * @param {string=} id id + * @returns {any} exports + */ + const __webpack_require_module__ = (moduleArgument, id) => { + const execOptions = { + id, + module: { + id, + exports: {}, + loaded: false, + error: undefined + }, + require: __webpack_require__ + }; + for (const handler of interceptModuleExecution) { + handler(execOptions); + } + const module = moduleArgument.module; + this.buildTimeExecutedModules.add(module); + const moduleObject = execOptions.module; + moduleArgument.moduleObject = moduleObject; + try { + if (id) moduleCache[id] = moduleObject; + + tryRunOrWebpackError( + () => + this.hooks.executeModule.call( + moduleArgument, + context + ), + "Compilation.hooks.executeModule" + ); + moduleObject.loaded = true; + return moduleObject.exports; + } catch (execErr) { + if (strictModuleExceptionHandling) { + if (id) delete moduleCache[id]; + } else if (strictModuleErrorHandling) { + moduleObject.error = execErr; + } + if (!execErr.module) execErr.module = module; + throw execErr; + } + }; + + for (const runtimeModule of chunkGraph.getChunkRuntimeModulesInOrder( + chunk + )) { + __webpack_require_module__( + /** @type {ExecuteModuleArgument} */ + (moduleArgumentsMap.get(runtimeModule)) + ); + } + exports = __webpack_require__(module.identifier()); + } catch (execErr) { + const err = new WebpackError( + `Execution of module code from module graph (${module.readableIdentifier( + this.requestShortener + )}) failed: ${execErr.message}` + ); + err.stack = execErr.stack; + err.module = execErr.module; + return callback(err); + } + + callback(null, { + exports, + assets, + cacheable, + fileDependencies, + contextDependencies, + missingDependencies, + buildDependencies + }); + } + ); + }); + }); + } + ); + } + checkConstraints() { const chunkGraph = this.chunkGraph; @@ -3892,7 +5338,7 @@ This prevents using hashes of each other and should be avoided.`); const usedIds = new Set(); for (const module of this.modules) { - if (module.type === "runtime") continue; + if (module.type === WEBPACK_MODULE_TYPE_RUNTIME) continue; const moduleId = chunkGraph.getModuleId(module); if (moduleId === null) continue; if (usedIds.has(moduleId)) { @@ -3926,6 +5372,36 @@ This prevents using hashes of each other and should be avoided.`); } } +/** + * @typedef {object} FactorizeModuleOptions + * @property {ModuleProfile} currentProfile + * @property {ModuleFactory} factory + * @property {Dependency[]} dependencies + * @property {boolean=} factoryResult return full ModuleFactoryResult instead of only module + * @property {Module | null} originModule + * @property {Partial=} contextInfo + * @property {string=} context + */ + +/** + * @param {FactorizeModuleOptions} options options object + * @param {ModuleCallback | ModuleFactoryResultCallback} callback callback + * @returns {void} + */ + +// Workaround for typescript as it doesn't support function overloading in jsdoc within a class +/* eslint-disable jsdoc/require-asterisk-prefix */ +Compilation.prototype.factorizeModule = /** + @type {{ + (options: FactorizeModuleOptions & { factoryResult?: false }, callback: ModuleCallback): void; + (options: FactorizeModuleOptions & { factoryResult: true }, callback: ModuleFactoryResultCallback): void; +}} */ ( + function (options, callback) { + this.factorizeQueue.add(options, callback); + } +); +/* eslint-enable jsdoc/require-asterisk-prefix */ + // Hide from typescript const compilationPrototype = Compilation.prototype; @@ -3957,6 +5433,9 @@ Object.defineProperty(compilationPrototype, "cache", { "DEP_WEBPACK_COMPILATION_CACHE" ), set: util.deprecate( + /** + * @param {any} v value + */ v => {}, "Compilation.cache was removed in favor of Compilation.getCache()", "DEP_WEBPACK_COMPILATION_CACHE" diff --git a/lib/Compiler.js b/lib/Compiler.js index cbd7792f5dd..f1472544bca 100644 --- a/lib/Compiler.js +++ b/lib/Compiler.js @@ -5,7 +5,7 @@ "use strict"; -const parseJson = require("json-parse-better-errors"); +const parseJson = require("json-parse-even-better-errors"); const asyncLib = require("neo-async"); const { SyncHook, @@ -14,7 +14,7 @@ const { AsyncSeriesHook } = require("tapable"); const { SizeOnlySource } = require("webpack-sources"); -const webpack = require("./"); +const webpack = require("."); const Cache = require("./Cache"); const CacheFacade = require("./CacheFacade"); const ChunkGraph = require("./ChunkGraph"); @@ -40,35 +40,54 @@ const { isSourceEqual } = require("./util/source"); /** @typedef {import("../declarations/WebpackOptions").WebpackOptionsNormalized} WebpackOptions */ /** @typedef {import("../declarations/WebpackOptions").WebpackPluginInstance} WebpackPluginInstance */ /** @typedef {import("./Chunk")} Chunk */ +/** @typedef {import("./Compilation").References} References */ +/** @typedef {import("./Dependency")} Dependency */ /** @typedef {import("./FileSystemInfo").FileSystemInfoEntry} FileSystemInfoEntry */ /** @typedef {import("./Module")} Module */ +/** @typedef {import("./Module").BuildInfo} BuildInfo */ +/** @typedef {import("./config/target").PlatformTargetProperties} PlatformTargetProperties */ +/** @typedef {import("./logging/createConsoleLogger").LoggingFunction} LoggingFunction */ +/** @typedef {import("./util/fs").IStats} IStats */ /** @typedef {import("./util/fs").InputFileSystem} InputFileSystem */ /** @typedef {import("./util/fs").IntermediateFileSystem} IntermediateFileSystem */ /** @typedef {import("./util/fs").OutputFileSystem} OutputFileSystem */ /** @typedef {import("./util/fs").WatchFileSystem} WatchFileSystem */ /** - * @typedef {Object} CompilationParams + * @template {any[]} T + * @template V + * @typedef {import("./util/WeakTupleMap")} WeakTupleMap + */ + +/** + * @typedef {object} CompilationParams * @property {NormalModuleFactory} normalModuleFactory * @property {ContextModuleFactory} contextModuleFactory */ +/** + * @template T + * @callback RunCallback + * @param {Error | null} err + * @param {T=} result + */ + /** * @template T * @callback Callback - * @param {Error=} err + * @param {(Error | null)=} err * @param {T=} result */ /** * @callback RunAsChildCallback - * @param {Error=} err + * @param {Error | null} err * @param {Chunk[]=} entries * @param {Compilation=} compilation */ /** - * @typedef {Object} AssetEmittedInfo + * @typedef {object} AssetEmittedInfo * @property {Buffer} content * @property {Source} source * @property {Compilation} compilation @@ -76,6 +95,9 @@ const { isSourceEqual } = require("./util/source"); * @property {string} targetPath */ +/** @typedef {{ sizeOnlySource: SizeOnlySource | undefined, writtenTo: Map }} CacheEntry */ +/** @typedef {{ path: string, source: Source, size: number | undefined, waiting: ({ cacheEntry: any, file: string }[] | undefined) }} SimilarEntry */ + /** * @param {string[]} array an array * @returns {boolean} true, if the array is sorted @@ -88,11 +110,12 @@ const isSorted = array => { }; /** - * @param {Object} obj an object + * @param {{[key: string]: any}} obj an object * @param {string[]} keys the keys of the object - * @returns {Object} the object with properties sorted by property name + * @returns {{[key: string]: any}} the object with properties sorted by property name */ const sortObject = (obj, keys) => { + /** @type {{[key: string]: any}} */ const o = {}; for (const k of keys.sort()) { o[k] = obj[k]; @@ -109,21 +132,21 @@ const includesHash = (filename, hashes) => { if (!hashes) return false; if (Array.isArray(hashes)) { return hashes.some(hash => filename.includes(hash)); - } else { - return filename.includes(hashes); } + return filename.includes(hashes); }; class Compiler { /** * @param {string} context the compilation path + * @param {WebpackOptions} options options */ - constructor(context) { + constructor(context, options = /** @type {WebpackOptions} */ ({})) { this.hooks = Object.freeze({ /** @type {SyncHook<[]>} */ initialize: new SyncHook([]), - /** @type {SyncBailHook<[Compilation], boolean>} */ + /** @type {SyncBailHook<[Compilation], boolean | undefined>} */ shouldEmit: new SyncBailHook(["compilation"]), /** @type {AsyncSeriesHook<[Stats]>} */ done: new AsyncSeriesHook(["stats"]), @@ -162,6 +185,11 @@ class Compiler { /** @type {AsyncSeriesHook<[Compilation]>} */ afterCompile: new AsyncSeriesHook(["compilation"]), + /** @type {AsyncSeriesHook<[]>} */ + readRecords: new AsyncSeriesHook([]), + /** @type {AsyncSeriesHook<[]>} */ + emitRecords: new AsyncSeriesHook([]), + /** @type {AsyncSeriesHook<[Compiler]>} */ watchRun: new AsyncSeriesHook(["compiler"]), /** @type {SyncHook<[Error]>} */ @@ -173,7 +201,7 @@ class Compiler { /** @type {AsyncSeriesHook<[]>} */ shutdown: new AsyncSeriesHook([]), - /** @type {SyncBailHook<[string, string, any[]], true>} */ + /** @type {SyncBailHook<[string, string, any[] | undefined], true>} */ infrastructureLog: new SyncBailHook(["origin", "type", "args"]), // TODO the following hooks are weirdly located here @@ -192,52 +220,67 @@ class Compiler { this.webpack = webpack; - /** @type {string=} */ + /** @type {string | undefined} */ this.name = undefined; - /** @type {Compilation=} */ + /** @type {Compilation | undefined} */ this.parentCompilation = undefined; /** @type {Compiler} */ this.root = this; /** @type {string} */ this.outputPath = ""; - /** @type {Watching} */ + /** @type {Watching | undefined} */ this.watching = undefined; - /** @type {OutputFileSystem} */ + /** @type {OutputFileSystem | null} */ this.outputFileSystem = null; - /** @type {IntermediateFileSystem} */ + /** @type {IntermediateFileSystem | null} */ this.intermediateFileSystem = null; - /** @type {InputFileSystem} */ + /** @type {InputFileSystem | null} */ this.inputFileSystem = null; - /** @type {WatchFileSystem} */ + /** @type {WatchFileSystem | null} */ this.watchFileSystem = null; /** @type {string|null} */ this.recordsInputPath = null; /** @type {string|null} */ this.recordsOutputPath = null; + /** @type {Record} */ this.records = {}; - /** @type {Set} */ + /** @type {Set} */ this.managedPaths = new Set(); - /** @type {Set} */ + /** @type {Set} */ + this.unmanagedPaths = new Set(); + /** @type {Set} */ this.immutablePaths = new Set(); - /** @type {Set} */ + /** @type {ReadonlySet | undefined} */ this.modifiedFiles = undefined; - /** @type {Set} */ + /** @type {ReadonlySet | undefined} */ this.removedFiles = undefined; - /** @type {Map} */ + /** @type {ReadonlyMap | undefined} */ this.fileTimestamps = undefined; - /** @type {Map} */ + /** @type {ReadonlyMap | undefined} */ this.contextTimestamps = undefined; + /** @type {number | undefined} */ + this.fsStartTime = undefined; /** @type {ResolverFactory} */ this.resolverFactory = new ResolverFactory(); + /** @type {LoggingFunction | undefined} */ this.infrastructureLogger = undefined; - /** @type {WebpackOptions} */ - this.options = /** @type {WebpackOptions} */ ({}); + /** @type {Readonly} */ + this.platform = { + web: null, + browser: null, + webworker: null, + node: null, + nwjs: null, + electron: null + }; + + this.options = options; this.context = context; @@ -245,6 +288,9 @@ class Compiler { this.cache = new Cache(); + /** @type {Map }> | undefined} */ + this.moduleMemCaches = undefined; + this.compilerPath = ""; /** @type {boolean} */ @@ -256,13 +302,28 @@ class Compiler { /** @type {boolean} */ this.watchMode = false; - /** @type {Compilation} */ + this._backCompat = this.options.experiments.backCompat !== false; + + /** @type {Compilation | undefined} */ this._lastCompilation = undefined; + /** @type {NormalModuleFactory | undefined} */ + this._lastNormalModuleFactory = undefined; - /** @private @type {WeakMap }>} */ + /** + * @private + * @type {WeakMap} + */ this._assetEmittingSourceCache = new WeakMap(); - /** @private @type {Map} */ + /** + * @private + * @type {Map} + */ this._assetEmittingWrittenFiles = new Map(); + /** + * @private + * @type {Set} + */ + this._assetEmittingPreviousFiles = new Set(); } /** @@ -270,7 +331,11 @@ class Compiler { * @returns {CacheFacade} the cache facade instance */ getCache(name) { - return new CacheFacade(this.cache, `${this.compilerPath}${name}`); + return new CacheFacade( + this.cache, + `${this.compilerPath}${name}`, + this.options.output.hashFunction + ); } /** @@ -293,10 +358,11 @@ class Compiler { ); } } - if (this.hooks.infrastructureLog.call(name, type, args) === undefined) { - if (this.infrastructureLogger !== undefined) { - this.infrastructureLogger(name, type, args); - } + if ( + this.hooks.infrastructureLog.call(name, type, args) === undefined && + this.infrastructureLogger !== undefined + ) { + this.infrastructureLogger(name, type, args); } }, childName => { @@ -321,36 +387,33 @@ class Compiler { } return `${name}/${childName}`; }); - } else { - return this.getInfrastructureLogger(() => { - if (typeof name === "function") { - name = name(); - if (!name) { - throw new TypeError( - "Compiler.getInfrastructureLogger(name) called with a function not returning a name" - ); - } - } - return `${name}/${childName}`; - }); } - } else { - if (typeof childName === "function") { - return this.getInfrastructureLogger(() => { - if (typeof childName === "function") { - childName = childName(); - if (!childName) { - throw new TypeError( - "Logger.getChildLogger(name) called with a function not returning a name" - ); - } + return this.getInfrastructureLogger(() => { + if (typeof name === "function") { + name = name(); + if (!name) { + throw new TypeError( + "Compiler.getInfrastructureLogger(name) called with a function not returning a name" + ); } - return `${name}/${childName}`; - }); - } else { - return this.getInfrastructureLogger(`${name}/${childName}`); - } + } + return `${name}/${childName}`; + }); } + if (typeof childName === "function") { + return this.getInfrastructureLogger(() => { + if (typeof childName === "function") { + childName = childName(); + if (!childName) { + throw new TypeError( + "Logger.getChildLogger(name) called with a function not returning a name" + ); + } + } + return `${name}/${childName}`; + }); + } + return this.getInfrastructureLogger(`${name}/${childName}`); } ); } @@ -359,6 +422,17 @@ class Compiler { // e.g. move compilation specific info from Modules into ModuleGraph _cleanupLastCompilation() { if (this._lastCompilation !== undefined) { + for (const childCompilation of this._lastCompilation.children) { + for (const module of childCompilation.modules) { + ChunkGraph.clearChunkGraphForModule(module); + ModuleGraph.clearModuleGraphForModule(module); + module.cleanupForCache(); + } + for (const chunk of childCompilation.chunks) { + ChunkGraph.clearChunkGraphForChunk(chunk); + } + } + for (const module of this._lastCompilation.modules) { ChunkGraph.clearChunkGraphForModule(module); ModuleGraph.clearModuleGraphForModule(module); @@ -371,9 +445,17 @@ class Compiler { } } + // TODO webpack 6: solve this in a better way + _cleanupLastNormalModuleFactory() { + if (this._lastNormalModuleFactory !== undefined) { + this._lastNormalModuleFactory.cleanupForCache(); + this._lastNormalModuleFactory = undefined; + } + } + /** * @param {WatchOptions} watchOptions the watcher's options - * @param {Callback} handler signals when the call finishes + * @param {RunCallback} handler signals when the call finishes * @returns {Watching} a compiler watcher */ watch(watchOptions, handler) { @@ -388,7 +470,7 @@ class Compiler { } /** - * @param {Callback} callback signals when the call finishes + * @param {RunCallback} callback signals when the call finishes * @returns {void} */ run(callback) { @@ -396,8 +478,13 @@ class Compiler { return callback(new ConcurrentCompilationError()); } + /** @type {Logger | undefined} */ let logger; + /** + * @param {Error | null} err error + * @param {Stats=} stats stats + */ const finalCallback = (err, stats) => { if (logger) logger.time("beginIdle"); this.idle = true; @@ -409,16 +496,23 @@ class Compiler { this.hooks.failed.call(err); } if (callback !== undefined) callback(err, stats); - this.hooks.afterDone.call(stats); + this.hooks.afterDone.call(/** @type {Stats} */ (stats)); }; const startTime = Date.now(); this.running = true; - const onCompiled = (err, compilation) => { + /** + * @param {Error | null} err error + * @param {Compilation=} _compilation compilation + * @returns {void} + */ + const onCompiled = (err, _compilation) => { if (err) return finalCallback(err); + const compilation = /** @type {Compilation} */ (_compilation); + if (this.hooks.shouldEmit.call(compilation) === false) { compilation.startTime = startTime; compilation.endTime = Date.now(); @@ -434,7 +528,8 @@ class Compiler { logger = compilation.getLogger("webpack.Compiler"); logger.time("emitAssets"); this.emitAssets(compilation, err => { - logger.timeEnd("emitAssets"); + /** @type {Logger} */ + (logger).timeEnd("emitAssets"); if (err) return finalCallback(err); if (compilation.hooks.needAdditionalPass.call()) { @@ -442,10 +537,12 @@ class Compiler { compilation.startTime = startTime; compilation.endTime = Date.now(); - logger.time("done hook"); + /** @type {Logger} */ + (logger).time("done hook"); const stats = new Stats(compilation); this.hooks.done.callAsync(stats, err => { - logger.timeEnd("done hook"); + /** @type {Logger} */ + (logger).timeEnd("done hook"); if (err) return finalCallback(err); this.hooks.additionalPass.callAsync(err => { @@ -456,17 +553,21 @@ class Compiler { return; } - logger.time("emitRecords"); + /** @type {Logger} */ + (logger).time("emitRecords"); this.emitRecords(err => { - logger.timeEnd("emitRecords"); + /** @type {Logger} */ + (logger).timeEnd("emitRecords"); if (err) return finalCallback(err); compilation.startTime = startTime; compilation.endTime = Date.now(); - logger.time("done hook"); + /** @type {Logger} */ + (logger).time("done hook"); const stats = new Stats(compilation); this.hooks.done.callAsync(stats, err => { - logger.timeEnd("done hook"); + /** @type {Logger} */ + (logger).timeEnd("done hook"); if (err) return finalCallback(err); this.cache.storeBuildDependencies( compilation.buildDependencies, @@ -515,15 +616,42 @@ class Compiler { */ runAsChild(callback) { const startTime = Date.now(); - this.compile((err, compilation) => { - if (err) return callback(err); - this.parentCompilation.children.push(compilation); + /** + * @param {Error | null} err error + * @param {Chunk[]=} entries entries + * @param {Compilation=} compilation compilation + */ + const finalCallback = (err, entries, compilation) => { + try { + callback(err, entries, compilation); + } catch (runAsChildErr) { + const err = new WebpackError( + `compiler.runAsChild callback error: ${runAsChildErr}` + ); + err.details = /** @type {Error} */ (runAsChildErr).stack; + /** @type {Compilation} */ + (this.parentCompilation).errors.push(err); + } + }; + + this.compile((err, _compilation) => { + if (err) return finalCallback(err); + + const compilation = /** @type {Compilation} */ (_compilation); + const parentCompilation = /** @type {Compilation} */ ( + this.parentCompilation + ); + + parentCompilation.children.push(compilation); + for (const { name, source, info } of compilation.getAssets()) { - this.parentCompilation.emitAsset(name, source, info); + parentCompilation.emitAsset(name, source, info); } + /** @type {Chunk[]} */ const entries = []; + for (const ep of compilation.entrypoints.values()) { entries.push(...ep.chunks); } @@ -531,7 +659,7 @@ class Compiler { compilation.startTime = startTime; compilation.endTime = Date.now(); - return callback(null, entries, compilation); + return finalCallback(null, entries, compilation); }); } @@ -547,15 +675,22 @@ class Compiler { * @returns {void} */ emitAssets(compilation, callback) { + /** @type {string} */ let outputPath; + /** + * @param {Error=} err error + * @returns {void} + */ const emitFiles = err => { if (err) return callback(err); const assets = compilation.getAssets(); compilation.assets = { ...compilation.assets }; - /** @type {Map} */ + /** @type {Map} */ const caseInsensitiveMap = new Map(); + /** @type {Set} */ + const allTargetPaths = new Set(); asyncLib.forEachLimit( assets, 15, @@ -564,7 +699,7 @@ class Compiler { let immutable = info.immutable; const queryStringIdx = targetFile.indexOf("?"); if (queryStringIdx >= 0) { - targetFile = targetFile.substr(0, queryStringIdx); + targetFile = targetFile.slice(0, queryStringIdx); // We may remove the hash, which is in the query string // So we recheck if the file is immutable // This doesn't cover all cases, but immutable is only a performance optimization anyway @@ -576,18 +711,23 @@ class Compiler { includesHash(targetFile, info.fullhash)); } + /** + * @param {Error=} err error + * @returns {void} + */ const writeOut = err => { if (err) return callback(err); const targetPath = join( - this.outputFileSystem, + /** @type {OutputFileSystem} */ + (this.outputFileSystem), outputPath, targetFile ); + allTargetPaths.add(targetPath); // check if the target file has already been written by this Compiler - const targetFileGeneration = this._assetEmittingWrittenFiles.get( - targetPath - ); + const targetFileGeneration = + this._assetEmittingWrittenFiles.get(targetPath); // create an cache entry for this Source if not already existing let cacheEntry = this._assetEmittingSourceCache.get(source); @@ -599,6 +739,7 @@ class Compiler { this._assetEmittingSourceCache.set(source, cacheEntry); } + /** @type {SimilarEntry | undefined} */ let similarEntry; const checkSimilarFile = () => { @@ -617,7 +758,8 @@ class Compiler { } alreadyWritten(); } else { - const err = new WebpackError(`Prevent writing to file that only differs in casing or query string from already written file. + const err = + new WebpackError(`Prevent writing to file that only differs in casing or query string from already written file. This will lead to a race-condition and corrupted files on case-insensitive file systems. ${targetPath} ${other}`); @@ -625,18 +767,17 @@ ${other}`); callback(err); } return true; - } else { - caseInsensitiveMap.set( - caseInsensitiveTargetPath, - (similarEntry = { - path: targetPath, - source, - size: undefined, - waiting: undefined - }) - ); - return false; } + caseInsensitiveMap.set( + caseInsensitiveTargetPath, + (similarEntry = /** @type {SimilarEntry} */ ({ + path: targetPath, + source, + size: undefined, + waiting: undefined + })) + ); + return false; }; /** @@ -646,14 +787,12 @@ ${other}`); const getContent = () => { if (typeof source.buffer === "function") { return source.buffer(); - } else { - const bufferOrString = source.source(); - if (Buffer.isBuffer(bufferOrString)) { - return bufferOrString; - } else { - return Buffer.from(bufferOrString, "utf8"); - } } + const bufferOrString = source.source(); + if (Buffer.isBuffer(bufferOrString)) { + return bufferOrString; + } + return Buffer.from(bufferOrString, "utf8"); }; const alreadyWritten = () => { @@ -661,9 +800,11 @@ ${other}`); if (targetFileGeneration === undefined) { const newGeneration = 1; this._assetEmittingWrittenFiles.set(targetPath, newGeneration); - cacheEntry.writtenTo.set(targetPath, newGeneration); + /** @type {CacheEntry} */ + (cacheEntry).writtenTo.set(targetPath, newGeneration); } else { - cacheEntry.writtenTo.set(targetPath, targetFileGeneration); + /** @type {CacheEntry} */ + (cacheEntry).writtenTo.set(targetPath, targetFileGeneration); } callback(); }; @@ -674,7 +815,8 @@ ${other}`); * @returns {void} */ const doWrite = content => { - this.outputFileSystem.writeFile(targetPath, content, err => { + /** @type {OutputFileSystem} */ + (this.outputFileSystem).writeFile(targetPath, content, err => { if (err) return callback(err); // information marker that the asset has been emitted @@ -685,7 +827,8 @@ ${other}`); targetFileGeneration === undefined ? 1 : targetFileGeneration + 1; - cacheEntry.writtenTo.set(targetPath, newGeneration); + /** @type {CacheEntry} */ + (cacheEntry).writtenTo.set(targetPath, newGeneration); this._assetEmittingWrittenFiles.set(targetPath, newGeneration); this.hooks.assetEmitted.callAsync( file, @@ -701,16 +844,33 @@ ${other}`); }); }; + /** + * @param {number} size size + */ const updateWithReplacementSource = size => { - updateFileWithReplacementSource(file, cacheEntry, size); - similarEntry.size = size; - if (similarEntry.waiting !== undefined) { - for (const { file, cacheEntry } of similarEntry.waiting) { + updateFileWithReplacementSource( + file, + /** @type {CacheEntry} */ (cacheEntry), + size + ); + /** @type {SimilarEntry} */ + (similarEntry).size = size; + if ( + /** @type {SimilarEntry} */ (similarEntry).waiting !== undefined + ) { + for (const { file, cacheEntry } of /** @type {SimilarEntry} */ ( + similarEntry + ).waiting) { updateFileWithReplacementSource(file, cacheEntry, size); } } }; + /** + * @param {string} file file + * @param {CacheEntry} cacheEntry cache entry + * @param {number} size size + */ const updateFileWithReplacementSource = ( file, cacheEntry, @@ -727,10 +887,14 @@ ${other}`); }); }; + /** + * @param {IStats} stats stats + * @returns {void} + */ const processExistingFile = stats => { // skip emitting if it's already there and an immutable file if (immutable) { - updateWithReplacementSource(stats.size); + updateWithReplacementSource(/** @type {number} */ (stats.size)); return alreadyWritten(); } @@ -744,19 +908,17 @@ ${other}`); // for a fast negative match file size is compared first if (content.length === stats.size) { compilation.comparedForEmitAssets.add(file); - return this.outputFileSystem.readFile( - targetPath, - (err, existingContent) => { - if ( - err || - !content.equals(/** @type {Buffer} */ (existingContent)) - ) { - return doWrite(content); - } else { - return alreadyWritten(); - } + return /** @type {OutputFileSystem} */ ( + this.outputFileSystem + ).readFile(targetPath, (err, existingContent) => { + if ( + err || + !content.equals(/** @type {Buffer} */ (existingContent)) + ) { + return doWrite(content); } - ); + return alreadyWritten(); + }); } return doWrite(content); @@ -773,20 +935,29 @@ ${other}`); // if the target file has already been written if (targetFileGeneration !== undefined) { // check if the Source has been written to this target file - const writtenGeneration = cacheEntry.writtenTo.get(targetPath); + const writtenGeneration = /** @type {CacheEntry} */ ( + cacheEntry + ).writtenTo.get(targetPath); if (writtenGeneration === targetFileGeneration) { - // if yes, we skip writing the file - // as it's already there - // (we assume one doesn't remove files while the Compiler is running) + // if yes, we may skip writing the file + // if it's already there + // (we assume one doesn't modify files while the Compiler is running, other then removing them) - compilation.updateAsset(file, cacheEntry.sizeOnlySource, { - size: cacheEntry.sizeOnlySource.size() - }); + if (this._assetEmittingPreviousFiles.has(targetPath)) { + const sizeOnlySource = /** @type {SizeOnlySource} */ ( + /** @type {CacheEntry} */ (cacheEntry).sizeOnlySource + ); - return callback(); - } + // We assume that assets from the last compilation say intact on disk (they are not removed) + compilation.updateAsset(file, sizeOnlySource, { + size: sizeOnlySource.size() + }); - if (!immutable) { + return callback(); + } + // Settings immutable will make it accept file content without comparing when file exist + immutable = true; + } else if (!immutable) { if (checkSimilarFile()) return; // We wrote to this file before which has very likely a different content // skip comparing and assume content is different for performance @@ -797,11 +968,12 @@ ${other}`); if (checkSimilarFile()) return; if (this.options.output.compareBeforeEmit) { - this.outputFileSystem.stat(targetPath, (err, stats) => { - const exists = !err && stats.isFile(); + /** @type {OutputFileSystem} */ + (this.outputFileSystem).stat(targetPath, (err, stats) => { + const exists = !err && /** @type {IStats} */ (stats).isFile(); if (exists) { - processExistingFile(stats); + processExistingFile(/** @type {IStats} */ (stats)); } else { processMissingFile(); } @@ -811,8 +983,8 @@ ${other}`); } }; - if (targetFile.match(/\/|\\/)) { - const fs = this.outputFileSystem; + if (/\/|\\/.test(targetFile)) { + const fs = /** @type {OutputFileSystem} */ (this.outputFileSystem); const dir = dirname(fs, join(fs, outputPath, targetFile)); mkdirp(fs, dir, writeOut); } else { @@ -820,7 +992,14 @@ ${other}`); } }, err => { - if (err) return callback(err); + // Clear map to free up memory + caseInsensitiveMap.clear(); + if (err) { + this._assetEmittingPreviousFiles.clear(); + return callback(err); + } + + this._assetEmittingPreviousFiles = allTargetPaths; this.hooks.afterEmit.callAsync(compilation, err => { if (err) return callback(err); @@ -834,7 +1013,11 @@ ${other}`); this.hooks.emit.callAsync(compilation, err => { if (err) return callback(err); outputPath = compilation.getPath(this.outputPath, {}); - mkdirp(this.outputFileSystem, outputPath, emitFiles); + mkdirp( + /** @type {OutputFileSystem} */ (this.outputFileSystem), + outputPath, + emitFiles + ); }); } @@ -843,11 +1026,34 @@ ${other}`); * @returns {void} */ emitRecords(callback) { - if (!this.recordsOutputPath) return callback(); + if (this.hooks.emitRecords.isUsed()) { + if (this.recordsOutputPath) { + asyncLib.parallel( + [ + cb => this.hooks.emitRecords.callAsync(cb), + this._emitRecords.bind(this) + ], + err => callback(err) + ); + } else { + this.hooks.emitRecords.callAsync(callback); + } + } else if (this.recordsOutputPath) { + this._emitRecords(callback); + } else { + callback(); + } + } + /** + * @param {Callback} callback signals when the call finishes + * @returns {void} + */ + _emitRecords(callback) { const writeFile = () => { - this.outputFileSystem.writeFile( - this.recordsOutputPath, + /** @type {OutputFileSystem} */ + (this.outputFileSystem).writeFile( + /** @type {string} */ (this.recordsOutputPath), JSON.stringify( this.records, (n, value) => { @@ -870,16 +1076,20 @@ ${other}`); }; const recordsOutputPathDirectory = dirname( - this.outputFileSystem, - this.recordsOutputPath + /** @type {OutputFileSystem} */ (this.outputFileSystem), + /** @type {string} */ (this.recordsOutputPath) ); if (!recordsOutputPathDirectory) { return writeFile(); } - mkdirp(this.outputFileSystem, recordsOutputPathDirectory, err => { - if (err) return callback(err); - writeFile(); - }); + mkdirp( + /** @type {OutputFileSystem} */ (this.outputFileSystem), + recordsOutputPathDirectory, + err => { + if (err) return callback(err); + writeFile(); + } + ); } /** @@ -887,27 +1097,63 @@ ${other}`); * @returns {void} */ readRecords(callback) { + if (this.hooks.readRecords.isUsed()) { + if (this.recordsInputPath) { + asyncLib.parallel( + [ + cb => this.hooks.readRecords.callAsync(cb), + this._readRecords.bind(this) + ], + err => callback(err) + ); + } else { + this.records = {}; + this.hooks.readRecords.callAsync(callback); + } + } else if (this.recordsInputPath) { + this._readRecords(callback); + } else { + this.records = {}; + callback(); + } + } + + /** + * @param {Callback} callback signals when the call finishes + * @returns {void} + */ + _readRecords(callback) { if (!this.recordsInputPath) { this.records = {}; return callback(); } - this.inputFileSystem.stat(this.recordsInputPath, err => { + /** @type {InputFileSystem} */ + (this.inputFileSystem).stat(this.recordsInputPath, err => { // It doesn't exist // We can ignore this. if (err) return callback(); - this.inputFileSystem.readFile(this.recordsInputPath, (err, content) => { - if (err) return callback(err); + /** @type {InputFileSystem} */ + (this.inputFileSystem).readFile( + /** @type {string} */ (this.recordsInputPath), + (err, content) => { + if (err) return callback(err); - try { - this.records = parseJson(content.toString("utf-8")); - } catch (e) { - e.message = "Cannot parse records: " + e.message; - return callback(e); - } + try { + this.records = parseJson( + /** @type {Buffer} */ (content).toString("utf-8") + ); + } catch (parseErr) { + return callback( + new Error( + `Cannot parse records: ${/** @type {Error} */ (parseErr).message}` + ) + ); + } - return callback(); - }); + return callback(); + } + ); }); } @@ -915,8 +1161,8 @@ ${other}`); * @param {Compilation} compilation the compilation * @param {string} compilerName the compiler's name * @param {number} compilerIndex the compiler's index - * @param {OutputOptions} outputOptions the output options - * @param {WebpackPluginInstance[]} plugins the plugins to apply + * @param {OutputOptions=} outputOptions the output options + * @param {WebpackPluginInstance[]=} plugins the plugins to apply * @returns {Compiler} a child compiler */ createChildCompiler( @@ -926,7 +1172,13 @@ ${other}`); outputOptions, plugins ) { - const childCompiler = new Compiler(this.context); + const childCompiler = new Compiler(this.context, { + ...this.options, + output: { + ...this.options.output, + ...outputOptions + } + }); childCompiler.name = compilerName; childCompiler.outputPath = this.outputPath; childCompiler.inputFileSystem = this.inputFileSystem; @@ -936,8 +1188,10 @@ ${other}`); childCompiler.removedFiles = this.removedFiles; childCompiler.fileTimestamps = this.fileTimestamps; childCompiler.contextTimestamps = this.contextTimestamps; + childCompiler.fsStartTime = this.fsStartTime; childCompiler.cache = this.cache; childCompiler.compilerPath = `${this.compilerPath}${compilerName}|${compilerIndex}|`; + childCompiler._backCompat = this._backCompat; const relativeCompilerName = makePathsRelative( this.context, @@ -953,18 +1207,13 @@ ${other}`); this.records[relativeCompilerName].push((childCompiler.records = {})); } - childCompiler.options = { - ...this.options, - output: { - ...this.options.output, - ...outputOptions - } - }; childCompiler.parentCompilation = compilation; childCompiler.root = this.root; if (Array.isArray(plugins)) { for (const plugin of plugins) { - plugin.apply(childCompiler); + if (plugin) { + plugin.apply(childCompiler); + } } } for (const name in this.hooks) { @@ -977,11 +1226,17 @@ ${other}`); "invalid", "done", "thisCompilation" - ].includes(name) + ].includes(name) && + childCompiler.hooks[/** @type {keyof Compiler["hooks"]} */ (name)] ) { - if (childCompiler.hooks[name]) { - childCompiler.hooks[name].taps = this.hooks[name].taps.slice(); - } + childCompiler.hooks[ + /** @type {keyof Compiler["hooks"]} */ + (name) + ].taps = + this.hooks[ + /** @type {keyof Compiler["hooks"]} */ + (name) + ].taps.slice(); } } @@ -995,12 +1250,16 @@ ${other}`); } isChild() { - return !!this.parentCompilation; + return Boolean(this.parentCompilation); } - createCompilation() { + /** + * @param {CompilationParams} params the compilation parameters + * @returns {Compilation} compilation + */ + createCompilation(params) { this._cleanupLastCompilation(); - return (this._lastCompilation = new Compilation(this)); + return (this._lastCompilation = new Compilation(this, params)); } /** @@ -1008,7 +1267,7 @@ ${other}`); * @returns {Compilation} the created compilation */ newCompilation(params) { - const compilation = this.createCompilation(); + const compilation = this.createCompilation(params); compilation.name = this.name; compilation.records = this.records; this.hooks.thisCompilation.call(compilation, params); @@ -1017,14 +1276,16 @@ ${other}`); } createNormalModuleFactory() { + this._cleanupLastNormalModuleFactory(); const normalModuleFactory = new NormalModuleFactory({ context: this.options.context, - fs: this.inputFileSystem, + fs: /** @type {InputFileSystem} */ (this.inputFileSystem), resolverFactory: this.resolverFactory, options: this.options.module, associatedObjectForCache: this.root, layers: this.options.experiments.layers }); + this._lastNormalModuleFactory = normalModuleFactory; this.hooks.normalModuleFactory.call(normalModuleFactory); return normalModuleFactory; } @@ -1044,7 +1305,7 @@ ${other}`); } /** - * @param {Callback} callback signals when the compilation finishes + * @param {RunCallback} callback signals when the compilation finishes * @returns {void} */ compile(callback) { @@ -1095,12 +1356,24 @@ ${other}`); } /** - * @param {Callback} callback signals when the compiler closes + * @param {RunCallback} callback signals when the compiler closes * @returns {void} */ close(callback) { + if (this.watching) { + // When there is still an active watching, close this first + this.watching.close(err => { + this.close(callback); + }); + return; + } this.hooks.shutdown.callAsync(err => { if (err) return callback(err); + // Get rid of reference to last compilation to avoid leaking memory + // We can't run this._cleanupLastCompilation() as the Stats to this compilation + // might be still in use. We try to get rid of the reference to the cache instead. + this._lastCompilation = undefined; + this._lastNormalModuleFactory = undefined; this.cache.shutdown(callback); }); } diff --git a/lib/ConcatenationScope.js b/lib/ConcatenationScope.js index 66515947b26..59e70b49c49 100644 --- a/lib/ConcatenationScope.js +++ b/lib/ConcatenationScope.js @@ -7,19 +7,20 @@ /** @typedef {import("./Module")} Module */ -const MODULE_REFERENCE_REGEXP = /^__WEBPACK_MODULE_REFERENCE__(\d+)_([\da-f]+|ns)(_call)?(_directImport)?(?:_asiSafe(\d))?__$/; +const MODULE_REFERENCE_REGEXP = + /^__WEBPACK_MODULE_REFERENCE__(\d+)_([\da-f]+|ns)(_call)?(_directImport)?(?:_asiSafe(\d))?__$/; const DEFAULT_EXPORT = "__WEBPACK_DEFAULT_EXPORT__"; const NAMESPACE_OBJECT_EXPORT = "__WEBPACK_NAMESPACE_OBJECT__"; /** - * @typedef {Object} ExternalModuleInfo + * @typedef {object} ExternalModuleInfo * @property {number} index * @property {Module} module */ /** - * @typedef {Object} ConcatenatedModuleInfo + * @typedef {object} ConcatenatedModuleInfo * @property {number} index * @property {Module} module * @property {Map} exportMap mapping from export name to symbol @@ -30,7 +31,7 @@ const NAMESPACE_OBJECT_EXPORT = "__WEBPACK_NAMESPACE_OBJECT__"; /** @typedef {ConcatenatedModuleInfo | ExternalModuleInfo} ModuleInfo */ /** - * @typedef {Object} ModuleReferenceOptions + * @typedef {object} ModuleReferenceOptions * @property {string[]} ids the properties/exports of the module * @property {boolean} call true, when this referenced export is called * @property {boolean} directImport true, when this referenced export is directly imported (not via property access) @@ -63,7 +64,6 @@ class ConcatenationScope { } /** - * * @param {string} exportName name of the export * @param {string} symbol identifier of the export in source code */ @@ -77,7 +77,6 @@ class ConcatenationScope { } /** - * * @param {string} exportName name of the export * @param {string} expression expression to be used */ @@ -98,7 +97,6 @@ class ConcatenationScope { } /** - * * @param {Module} module the referenced module * @param {Partial} options options * @returns {string} the reference as identifier @@ -107,14 +105,14 @@ class ConcatenationScope { module, { ids = undefined, call = false, directImport = false, asiSafe = false } ) { - const info = this._modulesMap.get(module); + const info = /** @type {ModuleInfo} */ (this._modulesMap.get(module)); const callFlag = call ? "_call" : ""; const directImportFlag = directImport ? "_directImport" : ""; const asiSafeFlag = asiSafe ? "_asiSafe1" : asiSafe === false - ? "_asiSafe0" - : ""; + ? "_asiSafe0" + : ""; const exportData = ids ? Buffer.from(JSON.stringify(ids), "utf-8").toString("hex") : "ns"; @@ -132,12 +130,12 @@ class ConcatenationScope { /** * @param {string} name the identifier - * @returns {ModuleReferenceOptions & { index: number }} parsed options and index + * @returns {ModuleReferenceOptions & { index: number } | null} parsed options and index */ static matchModuleReference(name) { const match = MODULE_REFERENCE_REGEXP.exec(name); if (!match) return null; - const index = +match[1]; + const index = Number(match[1]); const asiSafe = match[5]; return { index, @@ -145,8 +143,8 @@ class ConcatenationScope { match[2] === "ns" ? [] : JSON.parse(Buffer.from(match[2], "hex").toString("utf-8")), - call: !!match[3], - directImport: !!match[4], + call: Boolean(match[3]), + directImport: Boolean(match[4]), asiSafe: asiSafe ? asiSafe === "1" : undefined }; } diff --git a/lib/ConcurrentCompilationError.js b/lib/ConcurrentCompilationError.js index ccb28516d2e..3643553f050 100644 --- a/lib/ConcurrentCompilationError.js +++ b/lib/ConcurrentCompilationError.js @@ -14,7 +14,5 @@ module.exports = class ConcurrentCompilationError extends WebpackError { this.name = "ConcurrentCompilationError"; this.message = "You ran Webpack twice. Each instance only supports a single concurrent compilation at a time."; - - Error.captureStackTrace(this, this.constructor); } }; diff --git a/lib/ConditionalInitFragment.js b/lib/ConditionalInitFragment.js index 422b447ef74..67351383d95 100644 --- a/lib/ConditionalInitFragment.js +++ b/lib/ConditionalInitFragment.js @@ -14,6 +14,11 @@ const { mergeRuntime } = require("./util/runtime"); /** @typedef {import("./Generator").GenerateContext} GenerateContext */ /** @typedef {import("./util/runtime").RuntimeSpec} RuntimeSpec */ +/** + * @param {string} condition condition + * @param {string | Source} source source + * @returns {string | Source} wrapped source + */ const wrapInCondition = (condition, source) => { if (typeof source === "string") { return Template.asString([ @@ -22,23 +27,25 @@ const wrapInCondition = (condition, source) => { "}", "" ]); - } else { - return new ConcatSource( - `if (${condition}) {\n`, - new PrefixSource("\t", source), - "}\n" - ); } + return new ConcatSource( + `if (${condition}) {\n`, + new PrefixSource("\t", source), + "}\n" + ); }; +/** + * @extends {InitFragment} + */ class ConditionalInitFragment extends InitFragment { /** - * @param {string|Source} content the source code that will be included as initialization code + * @param {string | Source | undefined} content the source code that will be included as initialization code * @param {number} stage category of initialization code (contribute to order) * @param {number} position position in the category (contribute to order) - * @param {string} key unique key to avoid emitting the same initialization code twice + * @param {string | undefined} key unique key to avoid emitting the same initialization code twice * @param {RuntimeSpec | boolean} runtimeCondition in which runtime this fragment should be executed - * @param {string|Source=} endContent the source code that will be included at the end of the module + * @param {string | Source=} endContent the source code that will be included at the end of the module */ constructor( content, @@ -46,23 +53,23 @@ class ConditionalInitFragment extends InitFragment { position, key, runtimeCondition = true, - endContent + endContent = undefined ) { super(content, stage, position, key, endContent); this.runtimeCondition = runtimeCondition; } /** - * @param {GenerateContext} generateContext context for generate - * @returns {string|Source} the source code that will be included as initialization code + * @param {GenerateContext} context context + * @returns {string | Source | undefined} the source code that will be included as initialization code */ - getContent(generateContext) { + getContent(context) { if (this.runtimeCondition === false || !this.content) return ""; if (this.runtimeCondition === true) return this.content; - const expr = generateContext.runtimeTemplate.runtimeConditionExpression({ - chunkGraph: generateContext.chunkGraph, - runtimeRequirements: generateContext.runtimeRequirements, - runtime: generateContext.runtime, + const expr = context.runtimeTemplate.runtimeConditionExpression({ + chunkGraph: context.chunkGraph, + runtimeRequirements: context.runtimeRequirements, + runtime: context.runtime, runtimeCondition: this.runtimeCondition }); if (expr === "true") return this.content; @@ -70,22 +77,26 @@ class ConditionalInitFragment extends InitFragment { } /** - * @param {GenerateContext} generateContext context for generate + * @param {GenerateContext} context context * @returns {string|Source=} the source code that will be included at the end of the module */ - getEndContent(generateContext) { + getEndContent(context) { if (this.runtimeCondition === false || !this.endContent) return ""; if (this.runtimeCondition === true) return this.endContent; - const expr = generateContext.runtimeTemplate.runtimeConditionExpression({ - chunkGraph: generateContext.chunkGraph, - runtimeRequirements: generateContext.runtimeRequirements, - runtime: generateContext.runtime, + const expr = context.runtimeTemplate.runtimeConditionExpression({ + chunkGraph: context.chunkGraph, + runtimeRequirements: context.runtimeRequirements, + runtime: context.runtime, runtimeCondition: this.runtimeCondition }); if (expr === "true") return this.endContent; return wrapInCondition(expr, this.endContent); } + /** + * @param {ConditionalInitFragment} other fragment to merge with + * @returns {ConditionalInitFragment} merged fragment + */ merge(other) { if (this.runtimeCondition === true) return this; if (other.runtimeCondition === true) return other; diff --git a/lib/ConstPlugin.js b/lib/ConstPlugin.js index 844da0c6fa3..63ed2622de6 100644 --- a/lib/ConstPlugin.js +++ b/lib/ConstPlugin.js @@ -5,19 +5,36 @@ "use strict"; +const { + JAVASCRIPT_MODULE_TYPE_AUTO, + JAVASCRIPT_MODULE_TYPE_DYNAMIC, + JAVASCRIPT_MODULE_TYPE_ESM +} = require("./ModuleTypeConstants"); const CachedConstDependency = require("./dependencies/CachedConstDependency"); const ConstDependency = require("./dependencies/ConstDependency"); const { evaluateToString } = require("./javascript/JavascriptParserHelpers"); const { parseResource } = require("./util/identifier"); -/** @typedef {import("estree").Expression} ExpressionNode */ -/** @typedef {import("estree").Super} SuperNode */ +/** @typedef {import("estree").AssignmentProperty} AssignmentProperty */ +/** @typedef {import("estree").Expression} Expression */ +/** @typedef {import("estree").Identifier} Identifier */ +/** @typedef {import("estree").Pattern} Pattern */ +/** @typedef {import("estree").SourceLocation} SourceLocation */ +/** @typedef {import("estree").Statement} Statement */ +/** @typedef {import("estree").Super} Super */ /** @typedef {import("./Compiler")} Compiler */ +/** @typedef {import("./javascript/BasicEvaluatedExpression")} BasicEvaluatedExpression */ +/** @typedef {import("./javascript/JavascriptParser")} JavascriptParser */ +/** @typedef {import("./javascript/JavascriptParser").Range} Range */ +/** + * @param {Set} declarations set of declarations + * @param {Identifier | Pattern} pattern pattern to collect declarations from + */ const collectDeclaration = (declarations, pattern) => { const stack = [pattern]; while (stack.length > 0) { - const node = stack.pop(); + const node = /** @type {Pattern} */ (stack.pop()); switch (node.type) { case "Identifier": declarations.add(node.name); @@ -34,7 +51,7 @@ const collectDeclaration = (declarations, pattern) => { break; case "ObjectPattern": for (const property of node.properties) { - stack.push(property.value); + stack.push(/** @type {AssignmentProperty} */ (property).value); } break; case "RestElement": @@ -44,8 +61,14 @@ const collectDeclaration = (declarations, pattern) => { } }; +/** + * @param {Statement} branch branch to get hoisted declarations from + * @param {boolean} includeFunctionDeclarations whether to include function declarations + * @returns {Array} hoisted declarations + */ const getHoistedDeclarations = (branch, includeFunctionDeclarations) => { const declarations = new Set(); + /** @type {Array} */ const stack = [branch]; while (stack.length > 0) { const node = stack.pop(); @@ -93,7 +116,7 @@ const getHoistedDeclarations = (branch, includeFunctionDeclarations) => { break; case "FunctionDeclaration": if (includeFunctionDeclarations) { - collectDeclaration(declarations, node.id); + collectDeclaration(declarations, /** @type {Identifier} */ (node.id)); } break; case "VariableDeclaration": @@ -108,6 +131,8 @@ const getHoistedDeclarations = (branch, includeFunctionDeclarations) => { return Array.from(declarations); }; +const PLUGIN_NAME = "ConstPlugin"; + class ConstPlugin { /** * Apply the plugin @@ -117,7 +142,7 @@ class ConstPlugin { apply(compiler) { const cachedParseResource = parseResource.bindCache(compiler.root); compiler.hooks.compilation.tap( - "ConstPlugin", + PLUGIN_NAME, (compilation, { normalModuleFactory }) => { compilation.dependencyTemplates.set( ConstDependency, @@ -129,15 +154,21 @@ class ConstPlugin { new CachedConstDependency.Template() ); + /** + * @param {JavascriptParser} parser the parser + */ const handler = parser => { - parser.hooks.statementIf.tap("ConstPlugin", statement => { + parser.hooks.statementIf.tap(PLUGIN_NAME, statement => { if (parser.scope.isAsmJs) return; const param = parser.evaluateExpression(statement.test); const bool = param.asBool(); if (typeof bool === "boolean") { if (!param.couldHaveSideEffects()) { - const dep = new ConstDependency(`${bool}`, param.range); - dep.loc = statement.loc; + const dep = new ConstDependency( + `${bool}`, + /** @type {Range} */ (param.range) + ); + dep.loc = /** @type {SourceLocation} */ (statement.loc); parser.state.module.addPresentationalDependency(dep); } else { parser.walkExpression(statement.test); @@ -176,41 +207,36 @@ class ConstPlugin { // NOTE: When code runs in strict mode, `var` declarations // are hoisted but `function` declarations don't. // - let declarations; - if (parser.scope.isStrict) { - // If the code runs in strict mode, variable declarations - // using `var` must be hoisted. - declarations = getHoistedDeclarations(branchToRemove, false); - } else { - // Otherwise, collect all hoisted declaration. - declarations = getHoistedDeclarations(branchToRemove, true); - } - let replacement; - if (declarations.length > 0) { - replacement = `{ var ${declarations.join(", ")}; }`; - } else { - replacement = "{}"; - } + const declarations = parser.scope.isStrict + ? getHoistedDeclarations(branchToRemove, false) + : getHoistedDeclarations(branchToRemove, true); + const replacement = + declarations.length > 0 + ? `{ var ${declarations.join(", ")}; }` + : "{}"; const dep = new ConstDependency( replacement, - branchToRemove.range + /** @type {Range} */ (branchToRemove.range) ); - dep.loc = branchToRemove.loc; + dep.loc = /** @type {SourceLocation} */ (branchToRemove.loc); parser.state.module.addPresentationalDependency(dep); } return bool; } }); parser.hooks.expressionConditionalOperator.tap( - "ConstPlugin", + PLUGIN_NAME, expression => { if (parser.scope.isAsmJs) return; const param = parser.evaluateExpression(expression.test); const bool = param.asBool(); if (typeof bool === "boolean") { if (!param.couldHaveSideEffects()) { - const dep = new ConstDependency(` ${bool}`, param.range); - dep.loc = expression.loc; + const dep = new ConstDependency( + ` ${bool}`, + /** @type {Range} */ (param.range) + ); + dep.loc = /** @type {SourceLocation} */ (expression.loc); parser.state.module.addPresentationalDependency(dep); } else { parser.walkExpression(expression.test); @@ -229,15 +255,18 @@ class ConstPlugin { const branchToRemove = bool ? expression.alternate : expression.consequent; - const dep = new ConstDependency("0", branchToRemove.range); - dep.loc = branchToRemove.loc; + const dep = new ConstDependency( + "0", + /** @type {Range} */ (branchToRemove.range) + ); + dep.loc = /** @type {SourceLocation} */ (branchToRemove.loc); parser.state.module.addPresentationalDependency(dep); return bool; } } ); parser.hooks.expressionLogicalOperator.tap( - "ConstPlugin", + PLUGIN_NAME, expression => { if (parser.scope.isAsmJs) return; if ( @@ -306,8 +335,11 @@ class ConstPlugin { // // returnfalse&&'foo' // - const dep = new ConstDependency(` ${bool}`, param.range); - dep.loc = expression.loc; + const dep = new ConstDependency( + ` ${bool}`, + /** @type {Range} */ (param.range) + ); + dep.loc = /** @type {SourceLocation} */ (expression.loc); parser.state.module.addPresentationalDependency(dep); } else { parser.walkExpression(expression.left); @@ -315,16 +347,16 @@ class ConstPlugin { if (!keepRight) { const dep = new ConstDependency( "0", - expression.right.range + /** @type {Range} */ (expression.right.range) ); - dep.loc = expression.loc; + dep.loc = /** @type {SourceLocation} */ (expression.loc); parser.state.module.addPresentationalDependency(dep); } return keepRight; } } else if (expression.operator === "??") { const param = parser.evaluateExpression(expression.left); - const keepRight = param && param.asNullish(); + const keepRight = param.asNullish(); if (typeof keepRight === "boolean") { // ------------------------------------------ // @@ -356,15 +388,18 @@ class ConstPlugin { // // returnnull??'foo' // - const dep = new ConstDependency(" null", param.range); - dep.loc = expression.loc; + const dep = new ConstDependency( + " null", + /** @type {Range} */ (param.range) + ); + dep.loc = /** @type {SourceLocation} */ (expression.loc); parser.state.module.addPresentationalDependency(dep); } else { const dep = new ConstDependency( "0", - expression.right.range + /** @type {Range} */ (expression.right.range) ); - dep.loc = expression.loc; + dep.loc = /** @type {SourceLocation} */ (expression.loc); parser.state.module.addPresentationalDependency(dep); parser.walkExpression(expression.left); } @@ -374,10 +409,10 @@ class ConstPlugin { } } ); - parser.hooks.optionalChaining.tap("ConstPlugin", expr => { - /** @type {ExpressionNode[]} */ + parser.hooks.optionalChaining.tap(PLUGIN_NAME, expr => { + /** @type {Expression[]} */ const optionalExpressionsStack = []; - /** @type {ExpressionNode|SuperNode} */ + /** @type {Expression | Super} */ let next = expr.expression; while ( @@ -388,7 +423,7 @@ class ConstPlugin { if (next.optional) { // SuperNode can not be optional optionalExpressionsStack.push( - /** @type {ExpressionNode} */ (next.object) + /** @type {Expression} */ (next.object) ); } next = next.object; @@ -396,7 +431,7 @@ class ConstPlugin { if (next.optional) { // SuperNode can not be optional optionalExpressionsStack.push( - /** @type {ExpressionNode} */ (next.callee) + /** @type {Expression} */ (next.callee) ); } next = next.callee; @@ -405,9 +440,11 @@ class ConstPlugin { while (optionalExpressionsStack.length) { const expression = optionalExpressionsStack.pop(); - const evaluated = parser.evaluateExpression(expression); + const evaluated = parser.evaluateExpression( + /** @type {Expression} */ (expression) + ); - if (evaluated && evaluated.asNullish()) { + if (evaluated.asNullish()) { // ------------------------------------------ // // Given the following code: @@ -420,8 +457,11 @@ class ConstPlugin { // // ------------------------------------------ // - const dep = new ConstDependency(" undefined", expr.range); - dep.loc = expr.loc; + const dep = new ConstDependency( + " undefined", + /** @type {Range} */ (expr.range) + ); + dep.loc = /** @type {SourceLocation} */ (expr.loc); parser.state.module.addPresentationalDependency(dep); return true; } @@ -429,7 +469,7 @@ class ConstPlugin { }); parser.hooks.evaluateIdentifier .for("__resourceQuery") - .tap("ConstPlugin", expr => { + .tap(PLUGIN_NAME, expr => { if (parser.scope.isAsmJs) return; if (!parser.state.module) return; return evaluateToString( @@ -438,24 +478,24 @@ class ConstPlugin { }); parser.hooks.expression .for("__resourceQuery") - .tap("ConstPlugin", expr => { + .tap(PLUGIN_NAME, expr => { if (parser.scope.isAsmJs) return; if (!parser.state.module) return; const dep = new CachedConstDependency( JSON.stringify( cachedParseResource(parser.state.module.resource).query ), - expr.range, + /** @type {Range} */ (expr.range), "__resourceQuery" ); - dep.loc = expr.loc; + dep.loc = /** @type {SourceLocation} */ (expr.loc); parser.state.module.addPresentationalDependency(dep); return true; }); parser.hooks.evaluateIdentifier .for("__resourceFragment") - .tap("ConstPlugin", expr => { + .tap(PLUGIN_NAME, expr => { if (parser.scope.isAsmJs) return; if (!parser.state.module) return; return evaluateToString( @@ -464,31 +504,31 @@ class ConstPlugin { }); parser.hooks.expression .for("__resourceFragment") - .tap("ConstPlugin", expr => { + .tap(PLUGIN_NAME, expr => { if (parser.scope.isAsmJs) return; if (!parser.state.module) return; const dep = new CachedConstDependency( JSON.stringify( cachedParseResource(parser.state.module.resource).fragment ), - expr.range, + /** @type {Range} */ (expr.range), "__resourceFragment" ); - dep.loc = expr.loc; + dep.loc = /** @type {SourceLocation} */ (expr.loc); parser.state.module.addPresentationalDependency(dep); return true; }); }; normalModuleFactory.hooks.parser - .for("javascript/auto") - .tap("ConstPlugin", handler); + .for(JAVASCRIPT_MODULE_TYPE_AUTO) + .tap(PLUGIN_NAME, handler); normalModuleFactory.hooks.parser - .for("javascript/dynamic") - .tap("ConstPlugin", handler); + .for(JAVASCRIPT_MODULE_TYPE_DYNAMIC) + .tap(PLUGIN_NAME, handler); normalModuleFactory.hooks.parser - .for("javascript/esm") - .tap("ConstPlugin", handler); + .for(JAVASCRIPT_MODULE_TYPE_ESM) + .tap(PLUGIN_NAME, handler); } ); } diff --git a/lib/ContextExclusionPlugin.js b/lib/ContextExclusionPlugin.js index da51e30b2d1..8b291072c2b 100644 --- a/lib/ContextExclusionPlugin.js +++ b/lib/ContextExclusionPlugin.js @@ -22,9 +22,9 @@ class ContextExclusionPlugin { */ apply(compiler) { compiler.hooks.contextModuleFactory.tap("ContextExclusionPlugin", cmf => { - cmf.hooks.contextModuleFiles.tap("ContextExclusionPlugin", files => { - return files.filter(filePath => !this.negativeMatcher.test(filePath)); - }); + cmf.hooks.contextModuleFiles.tap("ContextExclusionPlugin", files => + files.filter(filePath => !this.negativeMatcher.test(filePath)) + ); }); } } diff --git a/lib/ContextModule.js b/lib/ContextModule.js index a6f6ed41cd9..91a5b1bf3e5 100644 --- a/lib/ContextModule.js +++ b/lib/ContextModule.js @@ -9,6 +9,7 @@ const { OriginalSource, RawSource } = require("webpack-sources"); const AsyncDependenciesBlock = require("./AsyncDependenciesBlock"); const { makeWebpackError } = require("./HookWebpackError"); const Module = require("./Module"); +const { JAVASCRIPT_MODULE_TYPE_DYNAMIC } = require("./ModuleTypeConstants"); const RuntimeGlobals = require("./RuntimeGlobals"); const Template = require("./Template"); const WebpackError = require("./WebpackError"); @@ -19,32 +20,45 @@ const { keepOriginalOrder, compareModulesById } = require("./util/comparators"); -const { contextify, parseResource } = require("./util/identifier"); +const { + contextify, + parseResource, + makePathsRelative +} = require("./util/identifier"); const makeSerializable = require("./util/makeSerializable"); /** @typedef {import("webpack-sources").Source} Source */ /** @typedef {import("../declarations/WebpackOptions").WebpackOptionsNormalized} WebpackOptions */ +/** @typedef {import("./Chunk")} Chunk */ +/** @typedef {import("./Chunk").ChunkId} ChunkId */ /** @typedef {import("./ChunkGraph")} ChunkGraph */ +/** @typedef {import("./ChunkGraph").ModuleId} ModuleId */ /** @typedef {import("./ChunkGroup").RawChunkGroupOptions} RawChunkGroupOptions */ /** @typedef {import("./Compilation")} Compilation */ +/** @typedef {import("./Dependency")} Dependency */ /** @typedef {import("./DependencyTemplates")} DependencyTemplates */ +/** @typedef {import("./Module").BuildInfo} BuildInfo */ /** @typedef {import("./Module").BuildMeta} BuildMeta */ /** @typedef {import("./Module").CodeGenerationContext} CodeGenerationContext */ /** @typedef {import("./Module").CodeGenerationResult} CodeGenerationResult */ /** @typedef {import("./Module").LibIdentOptions} LibIdentOptions */ /** @typedef {import("./Module").NeedBuildContext} NeedBuildContext */ +/** @typedef {import("./Module").SourceTypes} SourceTypes */ /** @typedef {import("./ModuleGraph")} ModuleGraph */ /** @typedef {import("./RequestShortener")} RequestShortener */ /** @typedef {import("./ResolverFactory").ResolverWithOptions} ResolverWithOptions */ /** @typedef {import("./RuntimeTemplate")} RuntimeTemplate */ /** @typedef {import("./dependencies/ContextElementDependency")} ContextElementDependency */ +/** @typedef {import("./javascript/JavascriptParser").ImportAttributes} ImportAttributes */ +/** @typedef {import("./serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */ +/** @typedef {import("./serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */ /** @template T @typedef {import("./util/LazySet")} LazySet */ /** @typedef {import("./util/fs").InputFileSystem} InputFileSystem */ /** @typedef {"sync" | "eager" | "weak" | "async-weak" | "lazy" | "lazy-once"} ContextMode Context mode */ /** - * @typedef {Object} ContextOptions + * @typedef {object} ContextOptions * @property {ContextMode} mode * @property {boolean} recursive * @property {RegExp} regExp @@ -54,13 +68,16 @@ const makeSerializable = require("./util/makeSerializable"); * @property {RegExp=} include * @property {RegExp=} exclude * @property {RawChunkGroupOptions=} groupOptions + * @property {string=} typePrefix * @property {string=} category - * @property {string[][]=} referencedExports exports referenced from modules (won't be mangled) + * @property {(string[][] | null)=} referencedExports exports referenced from modules (won't be mangled) + * @property {string=} layer + * @property {ImportAttributes=} attributes */ /** - * @typedef {Object} ContextModuleOptionsExtras - * @property {string} resource + * @typedef {object} ContextModuleOptionsExtras + * @property {false|string|string[]} resource * @property {string=} resourceQuery * @property {string=} resourceFragment * @property {TODO} resolveOptions @@ -70,7 +87,7 @@ const makeSerializable = require("./util/makeSerializable"); /** * @callback ResolveDependenciesCallback - * @param {Error=} err + * @param {Error | null} err * @param {ContextElementDependency[]=} dependencies */ @@ -81,6 +98,10 @@ const makeSerializable = require("./util/makeSerializable"); * @param {ResolveDependenciesCallback} callback */ +/** @typedef {1 | 3 | 7 | 9} FakeMapType */ + +/** @typedef {Record} FakeMap */ + const SNAPSHOT_OPTIONS = { timestamp: true }; const TYPES = new Set(["javascript"]); @@ -91,23 +112,38 @@ class ContextModule extends Module { * @param {ContextModuleOptions} options options object */ constructor(resolveDependencies, options) { - const parsed = parseResource(options ? options.resource : ""); - const resource = parsed.path; - const resourceQuery = (options && options.resourceQuery) || parsed.query; - const resourceFragment = - (options && options.resourceFragment) || parsed.fragment; - - super("javascript/dynamic", resource); + if (!options || typeof options.resource === "string") { + const parsed = parseResource( + options ? /** @type {string} */ (options.resource) : "" + ); + const resource = parsed.path; + const resourceQuery = (options && options.resourceQuery) || parsed.query; + const resourceFragment = + (options && options.resourceFragment) || parsed.fragment; + const layer = options && options.layer; + + super(JAVASCRIPT_MODULE_TYPE_DYNAMIC, resource, layer); + /** @type {ContextModuleOptions} */ + this.options = { + ...options, + resource, + resourceQuery, + resourceFragment + }; + } else { + super(JAVASCRIPT_MODULE_TYPE_DYNAMIC, undefined, options.layer); + /** @type {ContextModuleOptions} */ + this.options = { + ...options, + resource: options.resource, + resourceQuery: options.resourceQuery || "", + resourceFragment: options.resourceFragment || "" + }; + } // Info from Factory + /** @type {ResolveDependencies | undefined} */ this.resolveDependencies = resolveDependencies; - /** @type {ContextModuleOptions} */ - this.options = { - ...options, - resource, - resourceQuery, - resourceFragment - }; if (options && options.resolveOptions !== undefined) { this.resolveOptions = options.resolveOptions; } @@ -121,7 +157,7 @@ class ContextModule extends Module { } /** - * @returns {Set} types available (do not mutate) + * @returns {SourceTypes} types available (do not mutate) */ getSourceTypes() { return TYPES; @@ -148,16 +184,26 @@ class ContextModule extends Module { this.resolveDependencies = undefined; } - prettyRegExp(regexString) { - // remove the "/" at the front and the beginning - // "/foo/" -> "foo" - return regexString - .substring(1, regexString.length - 1) - .replace(/!/g, "%21"); + /** + * @private + * @param {RegExp} regexString RegExp as a string + * @param {boolean=} stripSlash do we need to strip a slsh + * @returns {string} pretty RegExp + */ + _prettyRegExp(regexString, stripSlash = true) { + const str = stripSlash + ? regexString.source + regexString.flags + : `${regexString}`; + return str.replace(/!/g, "%21").replace(/\|/g, "%7C"); } _createIdentifier() { - let identifier = this.context; + let identifier = + this.context || + (typeof this.options.resource === "string" || + this.options.resource === false + ? `${this.options.resource}` + : this.options.resource.join("|")); if (this.options.resourceQuery) { identifier += `|${this.options.resourceQuery}`; } @@ -174,13 +220,19 @@ class ContextModule extends Module { identifier += `|${this.options.addon}`; } if (this.options.regExp) { - identifier += `|${this.options.regExp}`; + identifier += `|${this._prettyRegExp(this.options.regExp, false)}`; } if (this.options.include) { - identifier += `|include: ${this.options.include}`; + identifier += `|include: ${this._prettyRegExp( + this.options.include, + false + )}`; } if (this.options.exclude) { - identifier += `|exclude: ${this.options.exclude}`; + identifier += `|exclude: ${this._prettyRegExp( + this.options.exclude, + false + )}`; } if (this.options.referencedExports) { identifier += `|referencedExports: ${JSON.stringify( @@ -200,6 +252,9 @@ class ContextModule extends Module { } else if (this.options.namespaceObject) { identifier += "|namespace object"; } + if (this.layer) { + identifier += `|layer: ${this.layer}`; + } return identifier; } @@ -216,7 +271,19 @@ class ContextModule extends Module { * @returns {string} a user readable identifier of the module */ readableIdentifier(requestShortener) { - let identifier = requestShortener.shorten(this.context) + "/"; + let identifier; + if (this.context) { + identifier = `${requestShortener.shorten(this.context)}/`; + } else if ( + typeof this.options.resource === "string" || + this.options.resource === false + ) { + identifier = `${requestShortener.shorten(`${this.options.resource}`)}/`; + } else { + identifier = this.options.resource + .map(r => `${requestShortener.shorten(r)}/`) + .join(" "); + } if (this.options.resourceQuery) { identifier += ` ${this.options.resourceQuery}`; } @@ -230,13 +297,13 @@ class ContextModule extends Module { identifier += ` ${requestShortener.shorten(this.options.addon)}`; } if (this.options.regExp) { - identifier += ` ${this.prettyRegExp(this.options.regExp + "")}`; + identifier += ` ${this._prettyRegExp(this.options.regExp)}`; } if (this.options.include) { - identifier += ` include: ${this.prettyRegExp(this.options.include + "")}`; + identifier += ` include: ${this._prettyRegExp(this.options.include)}`; } if (this.options.exclude) { - identifier += ` exclude: ${this.prettyRegExp(this.options.exclude + "")}`; + identifier += ` exclude: ${this._prettyRegExp(this.options.exclude)}`; } if (this.options.referencedExports) { identifier += ` referencedExports: ${this.options.referencedExports @@ -249,7 +316,9 @@ class ContextModule extends Module { if (this.options.groupOptions) { const groupOptions = this.options.groupOptions; for (const key of Object.keys(groupOptions)) { - identifier += ` ${key}: ${groupOptions[key]}`; + identifier += ` ${key}: ${ + groupOptions[/** @type {keyof RawChunkGroupOptions} */ (key)] + }`; } } if (this.options.namespaceObject === "strict") { @@ -266,11 +335,31 @@ class ContextModule extends Module { * @returns {string | null} an identifier for library inclusion */ libIdent(options) { - let identifier = contextify( - options.context, - this.context, - options.associatedObjectForCache - ); + let identifier; + + if (this.context) { + identifier = contextify( + options.context, + this.context, + options.associatedObjectForCache + ); + } else if (typeof this.options.resource === "string") { + identifier = contextify( + options.context, + this.options.resource, + options.associatedObjectForCache + ); + } else if (this.options.resource === false) { + identifier = "false"; + } else { + identifier = this.options.resource + .map(res => + contextify(options.context, res, options.associatedObjectForCache) + ) + .join(" "); + } + + if (this.layer) identifier = `(${this.layer})/${identifier}`; if (this.options.mode) { identifier += ` ${this.options.mode}`; } @@ -285,13 +374,13 @@ class ContextModule extends Module { )}`; } if (this.options.regExp) { - identifier += ` ${this.prettyRegExp(this.options.regExp + "")}`; + identifier += ` ${this._prettyRegExp(this.options.regExp)}`; } if (this.options.include) { - identifier += ` include: ${this.prettyRegExp(this.options.include + "")}`; + identifier += ` include: ${this._prettyRegExp(this.options.include)}`; } if (this.options.exclude) { - identifier += ` exclude: ${this.prettyRegExp(this.options.exclude + "")}`; + identifier += ` exclude: ${this._prettyRegExp(this.options.exclude)}`; } if (this.options.referencedExports) { identifier += ` referencedExports: ${this.options.referencedExports @@ -311,17 +400,20 @@ class ContextModule extends Module { /** * @param {NeedBuildContext} context context info - * @param {function(WebpackError=, boolean=): void} callback callback function, returns true, if the module needs a rebuild + * @param {function((WebpackError | null)=, boolean=): void} callback callback function, returns true, if the module needs a rebuild * @returns {void} */ needBuild({ fileSystemInfo }, callback) { // build if enforced if (this._forceBuild) return callback(null, true); - // always build when we have no snapshot - if (!this.buildInfo.snapshot) return callback(null, true); + const buildInfo = /** @type {BuildInfo} */ (this.buildInfo); + + // always build when we have no snapshot and context + if (!buildInfo.snapshot) + return callback(null, Boolean(this.context || this.options.resource)); - fileSystemInfo.checkSnapshotValid(this.buildInfo.snapshot, (err, valid) => { + fileSystemInfo.checkSnapshotValid(buildInfo.snapshot, (err, valid) => { callback(err, !valid); }); } @@ -347,7 +439,8 @@ class ContextModule extends Module { this.dependencies.length = 0; this.blocks.length = 0; const startTime = Date.now(); - this.resolveDependencies(fs, this.options, (err, dependencies) => { + /** @type {ResolveDependencies} */ + (this.resolveDependencies)(fs, this.options, (err, dependencies) => { if (err) { return callback( makeWebpackError(err, "ContextModule.resolveDependencies") @@ -434,15 +527,22 @@ class ContextModule extends Module { ); return; } + if (!this.context && !this.options.resource) return callback(); + compilation.fileSystemInfo.createSnapshot( startTime, null, - [this.context], + this.context + ? [this.context] + : typeof this.options.resource === "string" + ? [this.options.resource] + : /** @type {string[]} */ (this.options.resource), null, SNAPSHOT_OPTIONS, (err, snapshot) => { if (err) return callback(err); - this.buildInfo.snapshot = snapshot; + /** @type {BuildInfo} */ + (this.buildInfo).snapshot = snapshot; callback(); } ); @@ -461,39 +561,49 @@ class ContextModule extends Module { missingDependencies, buildDependencies ) { - contextDependencies.add(this.context); + if (this.context) { + contextDependencies.add(this.context); + } else if (typeof this.options.resource === "string") { + contextDependencies.add(this.options.resource); + } else if (this.options.resource === false) { + // Do nothing + } else { + for (const res of this.options.resource) contextDependencies.add(res); + } } /** - * @param {ContextElementDependency[]} dependencies all dependencies + * @param {Dependency[]} dependencies all dependencies * @param {ChunkGraph} chunkGraph chunk graph - * @returns {TODO} TODO + * @returns {Map} map with user requests */ getUserRequestMap(dependencies, chunkGraph) { const moduleGraph = chunkGraph.moduleGraph; // if we filter first we get a new array // therefore we don't need to create a clone of dependencies explicitly // therefore the order of this is !important! - const sortedDependencies = dependencies - .filter(dependency => moduleGraph.getModule(dependency)) - .sort((a, b) => { - if (a.userRequest === b.userRequest) { - return 0; - } - return a.userRequest < b.userRequest ? -1 : 1; - }); + const sortedDependencies = + /** @type {ContextElementDependency[]} */ + (dependencies) + .filter(dependency => moduleGraph.getModule(dependency)) + .sort((a, b) => { + if (a.userRequest === b.userRequest) { + return 0; + } + return a.userRequest < b.userRequest ? -1 : 1; + }); const map = Object.create(null); for (const dep of sortedDependencies) { - const module = moduleGraph.getModule(dep); + const module = /** @type {Module} */ (moduleGraph.getModule(dep)); map[dep.userRequest] = chunkGraph.getModuleId(module); } return map; } /** - * @param {ContextElementDependency[]} dependencies all dependencies + * @param {Dependency[]} dependencies all dependencies * @param {ChunkGraph} chunkGraph chunk graph - * @returns {TODO} TODO + * @returns {FakeMap | FakeMapType} fake map */ getFakeMap(dependencies, chunkGraph) { if (!this.options.namespaceObject) { @@ -507,16 +617,19 @@ class ContextModule extends Module { // therefore we don't need to create a clone of dependencies explicitly // therefore the order of this is !important! const sortedModules = dependencies - .map(dependency => moduleGraph.getModule(dependency)) + .map( + dependency => /** @type {Module} */ (moduleGraph.getModule(dependency)) + ) .filter(Boolean) .sort(comparator); + /** @type {FakeMap} */ const fakeMap = Object.create(null); for (const module of sortedModules) { const exportsType = module.getExportsType( moduleGraph, this.options.namespaceObject === "strict" ); - const id = chunkGraph.getModuleId(module); + const id = /** @type {ModuleId} */ (chunkGraph.getModuleId(module)); switch (exportsType) { case "namespace": fakeMap[id] = 9; @@ -556,28 +669,43 @@ class ContextModule extends Module { return fakeMap; } + /** + * @param {FakeMap | FakeMapType} fakeMap fake map + * @returns {string} fake map init statement + */ getFakeMapInitStatement(fakeMap) { return typeof fakeMap === "object" ? `var fakeMap = ${JSON.stringify(fakeMap, null, "\t")};` : ""; } + /** + * @param {FakeMapType} type type + * @param {boolean=} asyncModule is async module + * @returns {string} return result + */ getReturn(type, asyncModule) { if (type === 9) { - return "__webpack_require__(id)"; + return `${RuntimeGlobals.require}(id)`; } return `${RuntimeGlobals.createFakeNamespaceObject}(id, ${type}${ asyncModule ? " | 16" : "" })`; } + /** + * @param {FakeMap | FakeMapType} fakeMap fake map + * @param {boolean=} asyncModule us async module + * @param {string=} fakeMapDataExpression fake map data expression + * @returns {string} module object source + */ getReturnModuleObjectSource( fakeMap, asyncModule, fakeMapDataExpression = "fakeMap[id]" ) { if (typeof fakeMap === "number") { - return `return ${this.getReturn(fakeMap)};`; + return `return ${this.getReturn(fakeMap, asyncModule)};`; } return `return ${ RuntimeGlobals.createFakeNamespaceObject @@ -585,8 +713,8 @@ class ContextModule extends Module { } /** - * @param {TODO} dependencies TODO - * @param {TODO} id TODO + * @param {Dependency[]} dependencies dependencies + * @param {ModuleId} id module id * @param {ChunkGraph} chunkGraph the chunk graph * @returns {string} source code */ @@ -619,8 +747,8 @@ webpackContext.id = ${JSON.stringify(id)};`; } /** - * @param {TODO} dependencies TODO - * @param {TODO} id TODO + * @param {Dependency[]} dependencies dependencies + * @param {ModuleId} id module id * @param {ChunkGraph} chunkGraph the chunk graph * @returns {string} source code */ @@ -658,9 +786,9 @@ module.exports = webpackContext;`; } /** - * @param {TODO} dependencies TODO - * @param {TODO} id TODO - * @param {Object} context context + * @param {Dependency[]} dependencies dependencies + * @param {ModuleId} id module id + * @param {object} context context * @param {ChunkGraph} context.chunkGraph the chunk graph * @param {RuntimeTemplate} context.runtimeTemplate the chunk graph * @returns {string} source code @@ -707,9 +835,9 @@ module.exports = webpackAsyncContext;`; } /** - * @param {TODO} dependencies TODO - * @param {TODO} id TODO - * @param {Object} context context + * @param {Dependency[]} dependencies dependencies + * @param {ModuleId} id module id + * @param {object} context context * @param {ChunkGraph} context.chunkGraph the chunk graph * @param {RuntimeTemplate} context.runtimeTemplate the chunk graph * @returns {string} source code @@ -721,9 +849,9 @@ module.exports = webpackAsyncContext;`; const thenFunction = fakeMap !== 9 ? `${arrow ? "id =>" : "function(id)"} { - ${this.getReturnModuleObjectSource(fakeMap)} + ${this.getReturnModuleObjectSource(fakeMap, true)} }` - : "__webpack_require__"; + : RuntimeGlobals.require; return `var map = ${JSON.stringify(map, null, "\t")}; ${this.getFakeMapInitStatement(fakeMap)} @@ -751,10 +879,10 @@ module.exports = webpackAsyncContext;`; } /** - * @param {TODO} block TODO - * @param {TODO} dependencies TODO - * @param {TODO} id TODO - * @param {Object} options options object + * @param {AsyncDependenciesBlock} block block + * @param {Dependency[]} dependencies dependencies + * @param {ModuleId} id module id + * @param {object} options options object * @param {RuntimeTemplate} options.runtimeTemplate the runtime template * @param {ChunkGraph} options.chunkGraph the chunk graph * @returns {string} source code @@ -774,7 +902,7 @@ module.exports = webpackAsyncContext;`; ? `${arrow ? "id =>" : "function(id)"} { ${this.getReturnModuleObjectSource(fakeMap, true)}; }` - : "__webpack_require__"; + : RuntimeGlobals.require; return `var map = ${JSON.stringify(map, null, "\t")}; ${this.getFakeMapInitStatement(fakeMap)} @@ -801,9 +929,9 @@ module.exports = webpackAsyncContext;`; } /** - * @param {TODO} blocks TODO - * @param {TODO} id TODO - * @param {Object} context context + * @param {AsyncDependenciesBlock[]} blocks blocks + * @param {ModuleId} id module id + * @param {object} context context * @param {ChunkGraph} context.chunkGraph the chunk graph * @param {RuntimeTemplate} context.runtimeTemplate the chunk graph * @returns {string} source code @@ -818,13 +946,19 @@ module.exports = webpackAsyncContext;`; chunkGraph ); const hasFakeMap = typeof fakeMap === "object"; + /** @typedef {{userRequest: string, dependency: ContextElementDependency, chunks: undefined | Chunk[], module: Module, block: AsyncDependenciesBlock}} Item */ + /** + * @type {Item[]} + */ const items = blocks .map(block => { - const dependency = block.dependencies[0]; + const dependency = + /** @type {ContextElementDependency} */ + (block.dependencies[0]); return { - dependency: dependency, - module: moduleGraph.getModule(dependency), - block: block, + dependency, + module: /** @type {Module} */ (moduleGraph.getModule(dependency)), + block, userRequest: dependency.userRequest, chunks: undefined }; @@ -846,18 +980,23 @@ module.exports = webpackAsyncContext;`; if (a.userRequest === b.userRequest) return 0; return a.userRequest < b.userRequest ? -1 : 1; }); + /** @type {Record} */ const map = Object.create(null); for (const item of sortedItems) { - const moduleId = chunkGraph.getModuleId(item.module); + const moduleId = + /** @type {ModuleId} */ + (chunkGraph.getModuleId(item.module)); if (shortMode) { map[item.userRequest] = moduleId; } else { + /** @type {(ModuleId | ChunkId)[]} */ const arrayStart = [moduleId]; if (hasFakeMap) { arrayStart.push(fakeMap[moduleId]); } map[item.userRequest] = arrayStart.concat( - item.chunks.map(chunk => chunk.id) + /** @type {Chunk[]} */ + (item.chunks).map(chunk => /** @type {ChunkId} */ (chunk.id)) ); } } @@ -866,8 +1005,8 @@ module.exports = webpackAsyncContext;`; const requestPrefix = hasNoChunk ? "Promise.resolve()" : hasMultipleOrNoChunks - ? `Promise.all(ids.slice(${chunksStartPosition}).map(${RuntimeGlobals.ensureChunk}))` - : `${RuntimeGlobals.ensureChunk}(ids[${chunksStartPosition}])`; + ? `Promise.all(ids.slice(${chunksStartPosition}).map(${RuntimeGlobals.ensureChunk}))` + : `${RuntimeGlobals.ensureChunk}(ids[${chunksStartPosition}])`; const returnModuleObject = this.getReturnModuleObjectSource( fakeMap, true, @@ -913,6 +1052,11 @@ webpackAsyncContext.id = ${JSON.stringify(id)}; module.exports = webpackAsyncContext;`; } + /** + * @param {ModuleId} id module id + * @param {RuntimeTemplate} runtimeTemplate runtime template + * @returns {string} source for empty async context + */ getSourceForEmptyContext(id, runtimeTemplate) { return `function webpackEmptyContext(req) { var e = new Error("Cannot find module '" + req + "'"); @@ -925,6 +1069,11 @@ webpackEmptyContext.id = ${JSON.stringify(id)}; module.exports = webpackEmptyContext;`; } + /** + * @param {ModuleId} id module id + * @param {RuntimeTemplate} runtimeTemplate runtime template + * @returns {string} source for empty async context + */ getSourceForEmptyAsyncContext(id, runtimeTemplate) { const arrow = runtimeTemplate.supportsArrowFunction(); return `function webpackEmptyAsyncContext(req) { @@ -948,7 +1097,7 @@ module.exports = webpackEmptyAsyncContext;`; * @returns {string} the source code */ getSourceString(asyncMode, { runtimeTemplate, chunkGraph }) { - const id = chunkGraph.getModuleId(this); + const id = /** @type {ModuleId} */ (chunkGraph.getModuleId(this)); if (asyncMode === "lazy") { if (this.blocks && this.blocks.length > 0) { return this.getLazySource(this.blocks, id, { @@ -986,10 +1135,12 @@ module.exports = webpackEmptyAsyncContext;`; } return this.getSourceForEmptyAsyncContext(id, runtimeTemplate); } - if (asyncMode === "weak") { - if (this.dependencies && this.dependencies.length > 0) { - return this.getWeakSyncSource(this.dependencies, id, chunkGraph); - } + if ( + asyncMode === "weak" && + this.dependencies && + this.dependencies.length > 0 + ) { + return this.getWeakSyncSource(this.dependencies, id, chunkGraph); } if (this.dependencies && this.dependencies.length > 0) { return this.getSyncSource(this.dependencies, id, chunkGraph); @@ -997,9 +1148,21 @@ module.exports = webpackEmptyAsyncContext;`; return this.getSourceForEmptyContext(id, runtimeTemplate); } - getSource(sourceString) { + /** + * @param {string} sourceString source content + * @param {Compilation=} compilation the compilation + * @returns {Source} generated source + */ + getSource(sourceString, compilation) { if (this.useSourceMap || this.useSimpleSourceMap) { - return new OriginalSource(sourceString, this.identifier()); + return new OriginalSource( + sourceString, + `webpack://${makePathsRelative( + (compilation && compilation.compiler.context) || "", + this.identifier(), + compilation && compilation.compiler.root + )}` + ); } return new RawSource(sourceString); } @@ -1009,16 +1172,23 @@ module.exports = webpackEmptyAsyncContext;`; * @returns {CodeGenerationResult} result */ codeGeneration(context) { - const { chunkGraph } = context; + const { chunkGraph, compilation } = context; const sources = new Map(); sources.set( "javascript", - this.getSource(this.getSourceString(this.options.mode, context)) + this.getSource( + this.getSourceString(this.options.mode, context), + compilation + ) ); const set = new Set(); - const allDeps = /** @type {ContextElementDependency[]} */ (this.dependencies.concat( - this.blocks.map(b => b.dependencies[0]) - )); + const allDeps = + this.dependencies.length > 0 + ? /** @type {ContextElementDependency[]} */ (this.dependencies).slice() + : []; + for (const block of this.blocks) + for (const dep of block.dependencies) + allDeps.push(/** @type {ContextElementDependency} */ (dep)); set.add(RuntimeGlobals.module); set.add(RuntimeGlobals.hasOwnProperty); if (allDeps.length > 0) { @@ -1058,6 +1228,9 @@ module.exports = webpackEmptyAsyncContext;`; return size; } + /** + * @param {ObjectSerializerContext} context context + */ serialize(context) { const { write } = context; write(this._identifier); @@ -1065,6 +1238,9 @@ module.exports = webpackEmptyAsyncContext;`; super.serialize(context); } + /** + * @param {ObjectDeserializerContext} context context + */ deserialize(context) { const { read } = context; this._identifier = read(); diff --git a/lib/ContextModuleFactory.js b/lib/ContextModuleFactory.js index 24c99d87c77..23da02663e2 100644 --- a/lib/ContextModuleFactory.js +++ b/lib/ContextModuleFactory.js @@ -10,6 +10,7 @@ const { AsyncSeriesWaterfallHook, SyncWaterfallHook } = require("tapable"); const ContextModule = require("./ContextModule"); const ModuleFactory = require("./ModuleFactory"); const ContextElementDependency = require("./dependencies/ContextElementDependency"); +const LazySet = require("./util/LazySet"); const { cachedSetProperty } = require("./util/cleverMerge"); const { createFakeHook } = require("./util/deprecation"); const { join } = require("./util/fs"); @@ -21,8 +22,14 @@ const { join } = require("./util/fs"); /** @typedef {import("./ModuleFactory").ModuleFactoryResult} ModuleFactoryResult */ /** @typedef {import("./ResolverFactory")} ResolverFactory */ /** @typedef {import("./dependencies/ContextDependency")} ContextDependency */ -/** @template T @typedef {import("./util/deprecation").FakeHook} FakeHook */ +/** @typedef {import("enhanced-resolve").ResolveRequest} ResolveRequest */ +/** + * @template T + * @typedef {import("./util/deprecation").FakeHook} FakeHook + */ +/** @typedef {import("./util/fs").IStats} IStats */ /** @typedef {import("./util/fs").InputFileSystem} InputFileSystem */ +/** @typedef {{ context: string, request: string }} ContextAlternativeRequest */ const EMPTY_RESOLVE_OPTIONS = {}; @@ -32,7 +39,7 @@ module.exports = class ContextModuleFactory extends ModuleFactory { */ constructor(resolverFactory) { super(); - /** @type {AsyncSeriesWaterfallHook<[TODO[], ContextModuleOptions]>} */ + /** @type {AsyncSeriesWaterfallHook<[ContextAlternativeRequest[], ContextModuleOptions]>} */ const alternativeRequests = new AsyncSeriesWaterfallHook([ "modules", "options" @@ -44,27 +51,27 @@ module.exports = class ContextModuleFactory extends ModuleFactory { afterResolve: new AsyncSeriesWaterfallHook(["data"]), /** @type {SyncWaterfallHook<[string[]]>} */ contextModuleFiles: new SyncWaterfallHook(["files"]), - /** @type {FakeHook, "tap" | "tapAsync" | "tapPromise" | "name">>} */ + /** @type {FakeHook, "tap" | "tapAsync" | "tapPromise" | "name">>} */ alternatives: createFakeHook( { name: "alternatives", - /** @type {AsyncSeriesWaterfallHook<[TODO[]]>["intercept"]} */ + /** @type {AsyncSeriesWaterfallHook<[ContextAlternativeRequest[]]>["intercept"]} */ intercept: interceptor => { throw new Error( "Intercepting fake hook ContextModuleFactory.hooks.alternatives is not possible, use ContextModuleFactory.hooks.alternativeRequests instead" ); }, - /** @type {AsyncSeriesWaterfallHook<[TODO[]]>["tap"]} */ + /** @type {AsyncSeriesWaterfallHook<[ContextAlternativeRequest[]]>["tap"]} */ tap: (options, fn) => { alternativeRequests.tap(options, fn); }, - /** @type {AsyncSeriesWaterfallHook<[TODO[]]>["tapAsync"]} */ + /** @type {AsyncSeriesWaterfallHook<[ContextAlternativeRequest[]]>["tapAsync"]} */ tapAsync: (options, fn) => { alternativeRequests.tapAsync(options, (items, _options, callback) => fn(items, callback) ); }, - /** @type {AsyncSeriesWaterfallHook<[TODO[]]>["tapPromise"]} */ + /** @type {AsyncSeriesWaterfallHook<[ContextAlternativeRequest[]]>["tapPromise"]} */ tapPromise: (options, fn) => { alternativeRequests.tapPromise(options, fn); } @@ -79,7 +86,7 @@ module.exports = class ContextModuleFactory extends ModuleFactory { /** * @param {ModuleFactoryCreateData} data data object - * @param {function(Error=, ModuleFactoryResult=): void} callback callback + * @param {function((Error | null)=, ModuleFactoryResult=): void} callback callback * @returns {void} */ create(data, callback) { @@ -87,13 +94,14 @@ module.exports = class ContextModuleFactory extends ModuleFactory { const dependencies = data.dependencies; const resolveOptions = data.resolveOptions; const dependency = /** @type {ContextDependency} */ (dependencies[0]); - const fileDependencies = new Set(); - const missingDependencies = new Set(); - const contextDependencies = new Set(); + const fileDependencies = new LazySet(); + const missingDependencies = new LazySet(); + const contextDependencies = new LazySet(); this.hooks.beforeResolve.callAsync( { - context: context, - dependencies: dependencies, + context, + dependencies, + layer: data.contextInfo.issuerLayer, resolveOptions, fileDependencies, missingDependencies, @@ -122,12 +130,12 @@ module.exports = class ContextModuleFactory extends ModuleFactory { const request = beforeResolveResult.request; const resolveOptions = beforeResolveResult.resolveOptions; - let loaders, - resource, - loadersPrefix = ""; + let loaders; + let resource; + let loadersPrefix = ""; const idx = request.lastIndexOf("!"); if (idx >= 0) { - let loadersRequest = request.substr(0, idx + 1); + let loadersRequest = request.slice(0, idx + 1); let i; for ( i = 0; @@ -137,15 +145,11 @@ module.exports = class ContextModuleFactory extends ModuleFactory { loadersPrefix += "!"; } loadersRequest = loadersRequest - .substr(i) + .slice(i) .replace(/!+$/, "") .replace(/!!+/g, "!"); - if (loadersRequest === "") { - loaders = []; - } else { - loaders = loadersRequest.split("!"); - } - resource = request.substr(idx + 1); + loaders = loadersRequest === "" ? [] : loadersRequest.split("!"); + resource = request.slice(idx + 1); } else { loaders = []; resource = request; @@ -158,7 +162,7 @@ module.exports = class ContextModuleFactory extends ModuleFactory { resolveOptions || EMPTY_RESOLVE_OPTIONS, "dependencyType", dependencies[0].category - ) + ) : resolveOptions ); const loaderResolver = this.resolverFactory.get("loader"); @@ -166,6 +170,15 @@ module.exports = class ContextModuleFactory extends ModuleFactory { asyncLib.parallel( [ callback => { + const results = /** @type ResolveRequest[] */ ([]); + /** + * @param {ResolveRequest} obj obj + * @returns {void} + */ + const yield_ = obj => { + results.push(obj); + }; + contextResolver.resolve( {}, context, @@ -173,11 +186,12 @@ module.exports = class ContextModuleFactory extends ModuleFactory { { fileDependencies, missingDependencies, - contextDependencies + contextDependencies, + yield: yield_ }, - (err, result) => { + err => { if (err) return callback(err); - callback(null, result); + callback(null, results); } ); }, @@ -196,7 +210,7 @@ module.exports = class ContextModuleFactory extends ModuleFactory { }, (err, result) => { if (err) return callback(err); - callback(null, result); + callback(null, /** @type {string} */ (result)); } ); }, @@ -212,15 +226,26 @@ module.exports = class ContextModuleFactory extends ModuleFactory { contextDependencies }); } - + let [contextResult, loaderResult] = + /** @type {[ResolveRequest[], string[]]} */ (result); + if (contextResult.length > 1) { + const first = contextResult[0]; + contextResult = contextResult.filter(r => r.path); + if (contextResult.length === 0) contextResult.push(first); + } this.hooks.afterResolve.callAsync( { addon: loadersPrefix + - result[1].join("!") + - (result[1].length > 0 ? "!" : ""), - resource: result[0], + loaderResult.join("!") + + (loaderResult.length > 0 ? "!" : ""), + resource: + contextResult.length > 1 + ? contextResult.map(r => r.path) + : contextResult[0].path, resolveDependencies: this.resolveDependencies.bind(this), + resourceQuery: contextResult[0].query, + resourceFragment: contextResult[0].fragment, ...beforeResolveResult }, (err, result) => { @@ -272,30 +297,48 @@ module.exports = class ContextModuleFactory extends ModuleFactory { include, exclude, referencedExports, - category + category, + typePrefix, + attributes } = options; if (!regExp || !resource) return callback(null, []); - const addDirectoryChecked = (directory, visited, callback) => { - fs.realpath(directory, (err, realPath) => { + /** + * @param {string} ctx context + * @param {string} directory directory + * @param {Set} visited visited + * @param {ResolveDependenciesCallback} callback callback + */ + const addDirectoryChecked = (ctx, directory, visited, callback) => { + /** @type {NonNullable} */ + (fs.realpath)(directory, (err, _realPath) => { if (err) return callback(err); + const realPath = /** @type {string} */ (_realPath); if (visited.has(realPath)) return callback(null, []); + /** @type {Set | undefined} */ let recursionStack; addDirectory( + ctx, directory, - (dir, callback) => { + (_, dir, callback) => { if (recursionStack === undefined) { recursionStack = new Set(visited); recursionStack.add(realPath); } - addDirectoryChecked(dir, recursionStack, callback); + addDirectoryChecked(ctx, dir, recursionStack, callback); }, callback ); }); }; - const addDirectory = (directory, addSubDirectory, callback) => { + /** + * @param {string} ctx context + * @param {string} directory directory + * @param {function(string, string, function(): void): void} addSubDirectory addSubDirectoryFn + * @param {ResolveDependenciesCallback} callback callback + */ + const addDirectory = (ctx, directory, addSubDirectory, callback) => { fs.readdir(directory, (err, files) => { if (err) return callback(err); const processedFiles = cmf.hooks.contextModuleFiles.call( @@ -309,29 +352,29 @@ module.exports = class ContextModuleFactory extends ModuleFactory { const subResource = join(fs, directory, segment); if (!exclude || !subResource.match(exclude)) { - fs.stat(subResource, (err, stat) => { + fs.stat(subResource, (err, _stat) => { if (err) { if (err.code === "ENOENT") { // ENOENT is ok here because the file may have been deleted between // the readdir and stat calls. return callback(); - } else { - return callback(err); } + return callback(err); } + const stat = /** @type {IStats} */ (_stat); + if (stat.isDirectory()) { if (!recursive) return callback(); - addSubDirectory(subResource, callback); + addSubDirectory(ctx, subResource, callback); } else if ( stat.isFile() && (!include || subResource.match(include)) ) { + /** @type {{ context: string, request: string }} */ const obj = { - context: resource, - request: - "." + - subResource.substr(resource.length).replace(/\\/g, "/") + context: ctx, + request: `.${subResource.slice(ctx.length).replace(/\\/g, "/")}` }; this.hooks.alternativeRequests.callAsync( @@ -339,19 +382,29 @@ module.exports = class ContextModuleFactory extends ModuleFactory { options, (err, alternatives) => { if (err) return callback(err); - alternatives = alternatives - .filter(obj => regExp.test(obj.request)) - .map(obj => { - const dep = new ContextElementDependency( - obj.request + resourceQuery + resourceFragment, - obj.request, - category, - referencedExports - ); - dep.optional = true; - return dep; - }); - callback(null, alternatives); + callback( + null, + /** @type {ContextAlternativeRequest[]} */ + (alternatives) + .filter(obj => + regExp.test(/** @type {string} */ (obj.request)) + ) + .map(obj => { + const dep = new ContextElementDependency( + `${obj.request}${resourceQuery}${resourceFragment}`, + obj.request, + typePrefix, + /** @type {string} */ + (category), + referencedExports, + /** @type {TODO} */ + (obj.context), + attributes + ); + dep.optional = true; + return dep; + }) + ); } ); } else { @@ -379,12 +432,50 @@ module.exports = class ContextModuleFactory extends ModuleFactory { }); }; - if (typeof fs.realpath === "function") { - addDirectoryChecked(resource, new Set(), callback); + /** + * @param {string} ctx context + * @param {string} dir dir + * @param {ResolveDependenciesCallback} callback callback + * @returns {void} + */ + const addSubDirectory = (ctx, dir, callback) => + addDirectory(ctx, dir, addSubDirectory, callback); + + /** + * @param {string} resource resource + * @param {ResolveDependenciesCallback} callback callback + */ + const visitResource = (resource, callback) => { + if (typeof fs.realpath === "function") { + addDirectoryChecked(resource, resource, new Set(), callback); + } else { + addDirectory(resource, resource, addSubDirectory, callback); + } + }; + + if (typeof resource === "string") { + visitResource(resource, callback); } else { - const addSubDirectory = (dir, callback) => - addDirectory(dir, addSubDirectory, callback); - addDirectory(resource, addSubDirectory, callback); + asyncLib.map(resource, visitResource, (err, _result) => { + if (err) return callback(err); + const result = /** @type {ContextElementDependency[][]} */ (_result); + + // result dependencies should have unique userRequest + // ordered by resolve result + /** @type {Set} */ + const temp = new Set(); + /** @type {ContextElementDependency[]} */ + const res = []; + for (let i = 0; i < result.length; i++) { + const inner = result[i]; + for (const el of inner) { + if (temp.has(el.userRequest)) continue; + res.push(el); + temp.add(el.userRequest); + } + } + callback(null, res); + }); } } }; diff --git a/lib/ContextReplacementPlugin.js b/lib/ContextReplacementPlugin.js index 1beeb109ad7..ac425f31321 100644 --- a/lib/ContextReplacementPlugin.js +++ b/lib/ContextReplacementPlugin.js @@ -8,7 +8,16 @@ const ContextElementDependency = require("./dependencies/ContextElementDependency"); const { join } = require("./util/fs"); +/** @typedef {import("./Compiler")} Compiler */ +/** @typedef {import("./util/fs").InputFileSystem} InputFileSystem */ + class ContextReplacementPlugin { + /** + * @param {RegExp} resourceRegExp A regular expression that determines which files will be selected + * @param {TODO=} newContentResource A new resource to replace the match + * @param {TODO=} newContentRecursive If true, all subdirectories are searched for matches + * @param {RegExp=} newContentRegExp A regular expression that determines which files will be selected + */ constructor( resourceRegExp, newContentResource, @@ -49,6 +58,11 @@ class ContextReplacementPlugin { } } + /** + * Apply the plugin + * @param {Compiler} compiler the compiler instance + * @returns {void} + */ apply(compiler) { const resourceRegExp = this.resourceRegExp; const newContentCallback = this.newContentCallback; @@ -91,7 +105,7 @@ class ContextReplacementPlugin { result.resource = newContentResource; } else { result.resource = join( - compiler.inputFileSystem, + /** @type {InputFileSystem} */ (compiler.inputFileSystem), result.resource, newContentResource ); @@ -104,9 +118,10 @@ class ContextReplacementPlugin { result.regExp = newContentRegExp; } if (typeof newContentCreateContextMap === "function") { - result.resolveDependencies = createResolveDependenciesFromContextMap( - newContentCreateContextMap - ); + result.resolveDependencies = + createResolveDependenciesFromContextMap( + newContentCreateContextMap + ); } if (typeof newContentCallback === "function") { const origResource = result.resource; @@ -118,7 +133,7 @@ class ContextReplacementPlugin { ) { // When the function changed it to an relative path result.resource = join( - compiler.inputFileSystem, + /** @type {InputFileSystem} */ (compiler.inputFileSystem), origResource, result.resource ); @@ -139,14 +154,15 @@ const createResolveDependenciesFromContextMap = createContextMap => { const resolveDependenciesFromContextMap = (fs, options, callback) => { createContextMap(fs, (err, map) => { if (err) return callback(err); - const dependencies = Object.keys(map).map(key => { - return new ContextElementDependency( - map[key] + options.resourceQuery + options.resourceFragment, - key, - options.category, - options.referencedExports - ); - }); + const dependencies = Object.keys(map).map( + key => + new ContextElementDependency( + map[key] + options.resourceQuery + options.resourceFragment, + key, + options.category, + options.referencedExports + ) + ); callback(null, dependencies); }); }; diff --git a/lib/CssModule.js b/lib/CssModule.js new file mode 100644 index 00000000000..53a9129a2e2 --- /dev/null +++ b/lib/CssModule.js @@ -0,0 +1,166 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Alexander Krasnoyarov @alexander-akait +*/ + +"use strict"; + +const NormalModule = require("./NormalModule"); +const makeSerializable = require("./util/makeSerializable"); + +/** @typedef {import("./Module")} Module */ +/** @typedef {import("./NormalModule").NormalModuleCreateData} NormalModuleCreateData */ +/** @typedef {import("./RequestShortener")} RequestShortener */ +/** @typedef {import("./serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */ +/** @typedef {import("./serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */ + +/** @typedef {string|undefined} CssLayer */ +/** @typedef {string|undefined} Supports */ +/** @typedef {string|undefined} Media */ +/** @typedef {[CssLayer?, Supports?, Media?]} InheritanceItem */ +/** @typedef {Array} Inheritance */ + +/** @typedef {NormalModuleCreateData & { cssLayer: CssLayer|null, supports: Supports|null, media: Media|null, inheritance: Inheritance|null }} CSSModuleCreateData */ + +class CssModule extends NormalModule { + /** + * @param {CSSModuleCreateData} options options object + */ + constructor(options) { + super(options); + + // Avoid override `layer` for `Module` class, because it is a feature to run module in specific layer + this.cssLayer = options.cssLayer; + this.supports = options.supports; + this.media = options.media; + this.inheritance = options.inheritance; + } + + /** + * @returns {string} a unique identifier of the module + */ + identifier() { + let identifier = super.identifier(); + + if (this.cssLayer) { + identifier += `|${this.cssLayer}`; + } + + if (this.supports) { + identifier += `|${this.supports}`; + } + + if (this.media) { + identifier += `|${this.media}`; + } + + if (this.inheritance) { + const inheritance = this.inheritance.map( + (item, index) => + `inheritance_${index}|${item[0] || ""}|${item[1] || ""}|${ + item[2] || "" + }` + ); + + identifier += `|${inheritance.join("|")}`; + } + + return identifier; + } + + /** + * @param {RequestShortener} requestShortener the request shortener + * @returns {string} a user readable identifier of the module + */ + readableIdentifier(requestShortener) { + const readableIdentifier = super.readableIdentifier(requestShortener); + + let identifier = `css ${readableIdentifier}`; + + if (this.cssLayer) { + identifier += ` (layer: ${this.cssLayer})`; + } + + if (this.supports) { + identifier += ` (supports: ${this.supports})`; + } + + if (this.media) { + identifier += ` (media: ${this.media})`; + } + + return identifier; + } + + /** + * Assuming this module is in the cache. Update the (cached) module with + * the fresh module from the factory. Usually updates internal references + * and properties. + * @param {Module} module fresh module + * @returns {void} + */ + updateCacheModule(module) { + super.updateCacheModule(module); + const m = /** @type {CssModule} */ (module); + this.cssLayer = m.cssLayer; + this.supports = m.supports; + this.media = m.media; + this.inheritance = m.inheritance; + } + + /** + * @param {ObjectSerializerContext} context context + */ + serialize(context) { + const { write } = context; + write(this.cssLayer); + write(this.supports); + write(this.media); + write(this.inheritance); + super.serialize(context); + } + + /** + * @param {ObjectDeserializerContext} context context + * @returns {CssModule} the deserialized object + */ + static deserialize(context) { + const obj = new CssModule({ + // will be deserialized by Module + layer: null, + type: "", + // will be filled by updateCacheModule + resource: "", + context: "", + request: null, + userRequest: null, + rawRequest: null, + loaders: null, + matchResource: null, + parser: null, + parserOptions: null, + generator: null, + generatorOptions: null, + resolveOptions: null, + cssLayer: null, + supports: null, + media: null, + inheritance: null + }); + obj.deserialize(context); + return obj; + } + + deserialize(context) { + const { read } = context; + this.cssLayer = read(); + this.supports = read(); + this.media = read(); + this.inheritance = read(); + super.deserialize(context); + } +} + +makeSerializable(CssModule, "webpack/lib/CssModule"); + +module.exports = CssModule; diff --git a/lib/DefinePlugin.js b/lib/DefinePlugin.js index 71188c8be5f..574d8ca5e28 100644 --- a/lib/DefinePlugin.js +++ b/lib/DefinePlugin.js @@ -5,26 +5,39 @@ "use strict"; +const { + JAVASCRIPT_MODULE_TYPE_AUTO, + JAVASCRIPT_MODULE_TYPE_ESM, + JAVASCRIPT_MODULE_TYPE_DYNAMIC +} = require("./ModuleTypeConstants"); const RuntimeGlobals = require("./RuntimeGlobals"); const WebpackError = require("./WebpackError"); const ConstDependency = require("./dependencies/ConstDependency"); const BasicEvaluatedExpression = require("./javascript/BasicEvaluatedExpression"); + const { evaluateToString, toConstantDependency } = require("./javascript/JavascriptParserHelpers"); +const createHash = require("./util/createHash"); /** @typedef {import("estree").Expression} Expression */ +/** @typedef {import("./Compilation").ValueCacheVersion} ValueCacheVersion */ /** @typedef {import("./Compiler")} Compiler */ +/** @typedef {import("./Module").BuildInfo} BuildInfo */ /** @typedef {import("./NormalModule")} NormalModule */ /** @typedef {import("./RuntimeTemplate")} RuntimeTemplate */ /** @typedef {import("./javascript/JavascriptParser")} JavascriptParser */ +/** @typedef {import("./javascript/JavascriptParser").DestructuringAssignmentProperty} DestructuringAssignmentProperty */ +/** @typedef {import("./javascript/JavascriptParser").Range} Range */ +/** @typedef {import("./logging/Logger").Logger} Logger */ +/** @typedef {import("./util/createHash").Algorithm} Algorithm */ /** @typedef {null|undefined|RegExp|Function|string|number|boolean|bigint|undefined} CodeValuePrimitive */ /** @typedef {RecursiveArrayOrRecord} CodeValue */ /** - * @typedef {Object} RuntimeValueOptions + * @typedef {object} RuntimeValueOptions * @property {string[]=} fileDependencies * @property {string[]=} contextDependencies * @property {string[]=} missingDependencies @@ -32,9 +45,11 @@ const { * @property {string|function(): string=} version */ +/** @typedef {function({ module: NormalModule, key: string, readonly version: ValueCacheVersion }): CodeValuePrimitive} GeneratorFn */ + class RuntimeValue { /** - * @param {function({ module: NormalModule, key: string, readonly version: string | undefined }): CodeValuePrimitive} fn generator function + * @param {GeneratorFn} fn generator function * @param {true | string[] | RuntimeValueOptions=} options options */ constructor(fn, options) { @@ -53,33 +68,37 @@ class RuntimeValue { /** * @param {JavascriptParser} parser the parser - * @param {Map} valueCacheVersions valueCacheVersions + * @param {Map} valueCacheVersions valueCacheVersions * @param {string} key the defined key * @returns {CodeValuePrimitive} code */ exec(parser, valueCacheVersions, key) { - const buildInfo = parser.state.module.buildInfo; + const buildInfo = /** @type {BuildInfo} */ (parser.state.module.buildInfo); if (this.options === true) { buildInfo.cacheable = false; } else { if (this.options.fileDependencies) { for (const dep of this.options.fileDependencies) { - buildInfo.fileDependencies.add(dep); + /** @type {NonNullable} */ + (buildInfo.fileDependencies).add(dep); } } if (this.options.contextDependencies) { for (const dep of this.options.contextDependencies) { - buildInfo.contextDependencies.add(dep); + /** @type {NonNullable} */ + (buildInfo.contextDependencies).add(dep); } } if (this.options.missingDependencies) { for (const dep of this.options.missingDependencies) { - buildInfo.missingDependencies.add(dep); + /** @type {NonNullable} */ + (buildInfo.missingDependencies).add(dep); } } if (this.options.buildDependencies) { for (const dep of this.options.buildDependencies) { - buildInfo.buildDependencies.add(dep); + /** @type {NonNullable} */ + (buildInfo.buildDependencies).add(dep); } } } @@ -102,13 +121,27 @@ class RuntimeValue { } } +/** + * @param {Set | undefined} properties properties + * @returns {Set | undefined} used keys + */ +function getObjKeys(properties) { + if (!properties) return; + return new Set([...properties].map(p => p.id)); +} + +/** @typedef {Set | null} ObjKeys */ +/** @typedef {boolean | undefined | null} AsiSafe */ + /** * @param {any[]|{[k: string]: any}} obj obj * @param {JavascriptParser} parser Parser - * @param {Map} valueCacheVersions valueCacheVersions + * @param {Map} valueCacheVersions valueCacheVersions * @param {string} key the defined key * @param {RuntimeTemplate} runtimeTemplate the runtime template - * @param {boolean|undefined|null=} asiSafe asi safe (undefined: unknown, null: unneeded) + * @param {Logger} logger the logger object + * @param {AsiSafe=} asiSafe asi safe (undefined: unknown, null: unneeded) + * @param {ObjKeys=} objKeys used keys * @returns {string} code converted to string that evaluates */ const stringifyObj = ( @@ -117,25 +150,45 @@ const stringifyObj = ( valueCacheVersions, key, runtimeTemplate, - asiSafe + logger, + asiSafe, + objKeys ) => { let code; - let arr = Array.isArray(obj); + const arr = Array.isArray(obj); if (arr) { - code = `[${obj - .map(code => - toCode(code, parser, valueCacheVersions, key, runtimeTemplate, null) - ) - .join(",")}]`; + code = `[${ + /** @type {any[]} */ (obj) + .map(code => + toCode( + code, + parser, + valueCacheVersions, + key, + runtimeTemplate, + logger, + null + ) + ) + .join(",") + }]`; } else { - code = `{${Object.keys(obj) + let keys = Object.keys(obj); + if (objKeys) { + keys = objKeys.size === 0 ? [] : keys.filter(k => objKeys.has(k)); + } + code = `{${keys .map(key => { - const code = obj[key]; - return ( - JSON.stringify(key) + - ":" + - toCode(code, parser, valueCacheVersions, key, runtimeTemplate, null) - ); + const code = /** @type {{[k: string]: any}} */ (obj)[key]; + return `${JSON.stringify(key)}:${toCode( + code, + parser, + valueCacheVersions, + key, + runtimeTemplate, + logger, + null + )}`; }) .join(",")}}`; } @@ -148,7 +201,7 @@ const stringifyObj = ( case false: return arr ? `;${code}` : `;(${code})`; default: - return `Object(${code})`; + return `/*#__PURE__*/Object(${code})`; } }; @@ -156,10 +209,12 @@ const stringifyObj = ( * Convert code to a string that evaluates * @param {CodeValue} code Code to evaluate * @param {JavascriptParser} parser Parser - * @param {Map} valueCacheVersions valueCacheVersions + * @param {Map} valueCacheVersions valueCacheVersions * @param {string} key the defined key * @param {RuntimeTemplate} runtimeTemplate the runtime template - * @param {boolean|undefined|null=} asiSafe asi safe (undefined: unknown, null: unneeded) + * @param {Logger} logger the logger object + * @param {boolean | undefined | null=} asiSafe asi safe (undefined: unknown, null: unneeded) + * @param {ObjKeys=} objKeys used keys * @returns {string} code converted to string that evaluates */ const toCode = ( @@ -168,51 +223,68 @@ const toCode = ( valueCacheVersions, key, runtimeTemplate, - asiSafe + logger, + asiSafe, + objKeys ) => { - if (code === null) { - return "null"; - } - if (code === undefined) { - return "undefined"; - } - if (Object.is(code, -0)) { - return "-0"; - } - if (code instanceof RuntimeValue) { - return toCode( - code.exec(parser, valueCacheVersions, key), - parser, - valueCacheVersions, - key, - runtimeTemplate, - asiSafe - ); - } - if (code instanceof RegExp && code.toString) { - return code.toString(); - } - if (typeof code === "function" && code.toString) { - return "(" + code.toString() + ")"; - } - if (typeof code === "object") { - return stringifyObj( - code, - parser, - valueCacheVersions, - key, - runtimeTemplate, - asiSafe - ); - } - if (typeof code === "bigint") { - return runtimeTemplate.supportsBigIntLiteral() - ? `${code}n` - : `BigInt("${code}")`; - } - return code + ""; + const transformToCode = () => { + if (code === null) { + return "null"; + } + if (code === undefined) { + return "undefined"; + } + if (Object.is(code, -0)) { + return "-0"; + } + if (code instanceof RuntimeValue) { + return toCode( + code.exec(parser, valueCacheVersions, key), + parser, + valueCacheVersions, + key, + runtimeTemplate, + logger, + asiSafe + ); + } + if (code instanceof RegExp && code.toString) { + return code.toString(); + } + if (typeof code === "function" && code.toString) { + return `(${code.toString()})`; + } + if (typeof code === "object") { + return stringifyObj( + code, + parser, + valueCacheVersions, + key, + runtimeTemplate, + logger, + asiSafe, + objKeys + ); + } + if (typeof code === "bigint") { + return runtimeTemplate.supportsBigIntLiteral() + ? `${code}n` + : `BigInt("${code}")`; + } + return `${code}`; + }; + + const strCode = transformToCode(); + + logger.debug(`Replaced "${key}" with "${strCode}"`); + + return strCode; }; +/** + * @param {CodeValue} code code + * @returns {string | undefined} result + */ const toCacheVersion = code => { if (code === null) { return "null"; @@ -230,23 +302,30 @@ const toCacheVersion = code => { return code.toString(); } if (typeof code === "function" && code.toString) { - return "(" + code.toString() + ")"; + return `(${code.toString()})`; } if (typeof code === "object") { const items = Object.keys(code).map(key => ({ key, - value: toCacheVersion(code[key]) + value: toCacheVersion(/** @type {Record} */ (code)[key]) })); - if (items.some(({ value }) => value === undefined)) return undefined; + if (items.some(({ value }) => value === undefined)) return; return `{${items.map(({ key, value }) => `${key}: ${value}`).join(", ")}}`; } if (typeof code === "bigint") { return `${code}n`; } - return code + ""; + return `${code}`; }; -const VALUE_DEP_PREFIX = "webpack/DefinePlugin "; +const PLUGIN_NAME = "DefinePlugin"; +const VALUE_DEP_PREFIX = `webpack/${PLUGIN_NAME} `; +const VALUE_DEP_MAIN = `webpack/${PLUGIN_NAME}_hash`; +const TYPEOF_OPERATOR_REGEXP = /^typeof\s+/; +const WEBPACK_REQUIRE_FUNCTION_REGEXP = new RegExp( + `${RuntimeGlobals.require}\\s*(!?\\.)` +); +const WEBPACK_REQUIRE_IDENTIFIER_REGEXP = new RegExp(RuntimeGlobals.require); class DefinePlugin { /** @@ -258,7 +337,7 @@ class DefinePlugin { } /** - * @param {function({ module: NormalModule, key: string, readonly version: string | undefined }): CodeValuePrimitive} fn generator function + * @param {GeneratorFn} fn generator function * @param {true | string[] | RuntimeValueOptions=} options options * @returns {RuntimeValue} runtime value */ @@ -274,43 +353,75 @@ class DefinePlugin { apply(compiler) { const definitions = this.definitions; compiler.hooks.compilation.tap( - "DefinePlugin", + PLUGIN_NAME, (compilation, { normalModuleFactory }) => { + const logger = compilation.getLogger("webpack.DefinePlugin"); compilation.dependencyTemplates.set( ConstDependency, new ConstDependency.Template() ); const { runtimeTemplate } = compilation; + const mainHash = createHash( + /** @type {Algorithm} */ + (compilation.outputOptions.hashFunction) + ); + mainHash.update( + /** @type {string} */ + (compilation.valueCacheVersions.get(VALUE_DEP_MAIN)) || "" + ); + /** * Handler * @param {JavascriptParser} parser Parser * @returns {void} */ const handler = parser => { - const addValueDependency = key => { - const { buildInfo } = parser.state.module; + const mainValue = compilation.valueCacheVersions.get(VALUE_DEP_MAIN); + parser.hooks.program.tap(PLUGIN_NAME, () => { + const buildInfo = /** @type {BuildInfo} */ ( + parser.state.module.buildInfo + ); if (!buildInfo.valueDependencies) buildInfo.valueDependencies = new Map(); - buildInfo.valueDependencies.set( + buildInfo.valueDependencies.set(VALUE_DEP_MAIN, mainValue); + }); + + /** + * @param {string} key key + */ + const addValueDependency = key => { + const buildInfo = + /** @type {BuildInfo} */ + (parser.state.module.buildInfo); + /** @type {NonNullable} */ + (buildInfo.valueDependencies).set( VALUE_DEP_PREFIX + key, compilation.valueCacheVersions.get(VALUE_DEP_PREFIX + key) ); }; - const withValueDependency = (key, fn) => (...args) => { - addValueDependency(key); - return fn(...args); - }; + /** + * @template {Function} T + * @param {string} key key + * @param {T} fn fn + * @returns {function(TODO): TODO} result + */ + const withValueDependency = + (key, fn) => + (...args) => { + addValueDependency(key); + return fn(...args); + }; /** * Walk definitions - * @param {Object} definitions Definitions map + * @param {Record} definitions Definitions map * @param {string} prefix Prefix string * @returns {void} */ const walkDefinitions = (definitions, prefix) => { - Object.keys(definitions).forEach(key => { + for (const key of Object.keys(definitions)) { const code = definitions[key]; if ( code && @@ -318,13 +429,16 @@ class DefinePlugin { !(code instanceof RuntimeValue) && !(code instanceof RegExp) ) { - walkDefinitions(code, prefix + key + "."); + walkDefinitions( + /** @type {Record} */ (code), + `${prefix + key}.` + ); applyObjectDefine(prefix + key, code); - return; + continue; } applyDefineKey(prefix, key); applyDefine(prefix + key, code); - }); + } }; /** @@ -335,13 +449,13 @@ class DefinePlugin { */ const applyDefineKey = (prefix, key) => { const splittedKey = key.split("."); - splittedKey.slice(1).forEach((_, i) => { + for (const [i, _] of splittedKey.slice(1).entries()) { const fullKey = prefix + splittedKey.slice(0, i + 1).join("."); - parser.hooks.canRename.for(fullKey).tap("DefinePlugin", () => { + parser.hooks.canRename.for(fullKey).tap(PLUGIN_NAME, () => { addValueDependency(key); return true; }); - }); + } }; /** @@ -352,18 +466,18 @@ class DefinePlugin { */ const applyDefine = (key, code) => { const originalKey = key; - const isTypeof = /^typeof\s+/.test(key); - if (isTypeof) key = key.replace(/^typeof\s+/, ""); + const isTypeof = TYPEOF_OPERATOR_REGEXP.test(key); + if (isTypeof) key = key.replace(TYPEOF_OPERATOR_REGEXP, ""); let recurse = false; let recurseTypeof = false; if (!isTypeof) { - parser.hooks.canRename.for(key).tap("DefinePlugin", () => { + parser.hooks.canRename.for(key).tap(PLUGIN_NAME, () => { addValueDependency(originalKey); return true; }); parser.hooks.evaluateIdentifier .for(key) - .tap("DefinePlugin", expr => { + .tap(PLUGIN_NAME, expr => { /** * this is needed in case there is a recursion in the DefinePlugin * to prevent an endless recursion @@ -382,37 +496,44 @@ class DefinePlugin { compilation.valueCacheVersions, key, runtimeTemplate, + logger, null ) ); recurse = false; - res.setRange(expr.range); + res.setRange(/** @type {Range} */ (expr.range)); return res; }); - parser.hooks.expression.for(key).tap("DefinePlugin", expr => { + parser.hooks.expression.for(key).tap(PLUGIN_NAME, expr => { addValueDependency(originalKey); - const strCode = toCode( + let strCode = toCode( code, parser, compilation.valueCacheVersions, originalKey, runtimeTemplate, - !parser.isAsiPosition(expr.range[0]) + logger, + !parser.isAsiPosition(/** @type {Range} */ (expr.range)[0]), + null ); - if (/__webpack_require__\s*(!?\.)/.test(strCode)) { + + if (parser.scope.inShorthand) { + strCode = `${parser.scope.inShorthand}:${strCode}`; + } + + if (WEBPACK_REQUIRE_FUNCTION_REGEXP.test(strCode)) { return toConstantDependency(parser, strCode, [ RuntimeGlobals.require ])(expr); - } else if (/__webpack_require__/.test(strCode)) { + } else if (WEBPACK_REQUIRE_IDENTIFIER_REGEXP.test(strCode)) { return toConstantDependency(parser, strCode, [ RuntimeGlobals.requireScope ])(expr); - } else { - return toConstantDependency(parser, strCode)(expr); } + return toConstantDependency(parser, strCode)(expr); }); } - parser.hooks.evaluateTypeof.for(key).tap("DefinePlugin", expr => { + parser.hooks.evaluateTypeof.for(key).tap(PLUGIN_NAME, expr => { /** * this is needed in case there is a recursion in the DefinePlugin * to prevent an endless recursion @@ -430,17 +551,16 @@ class DefinePlugin { compilation.valueCacheVersions, originalKey, runtimeTemplate, + logger, null ); - const typeofCode = isTypeof - ? codeCode - : "typeof (" + codeCode + ")"; + const typeofCode = isTypeof ? codeCode : `typeof (${codeCode})`; const res = parser.evaluate(typeofCode); recurseTypeof = false; - res.setRange(expr.range); + res.setRange(/** @type {Range} */ (expr.range)); return res; }); - parser.hooks.typeof.for(key).tap("DefinePlugin", expr => { + parser.hooks.typeof.for(key).tap(PLUGIN_NAME, expr => { addValueDependency(originalKey); const codeCode = toCode( code, @@ -448,11 +568,10 @@ class DefinePlugin { compilation.valueCacheVersions, originalKey, runtimeTemplate, + logger, null ); - const typeofCode = isTypeof - ? codeCode - : "typeof (" + codeCode + ")"; + const typeofCode = isTypeof ? codeCode : `typeof (${codeCode})`; const res = parser.evaluate(typeofCode); if (!res.isString()) return; return toConstantDependency( @@ -465,56 +584,59 @@ class DefinePlugin { /** * Apply Object * @param {string} key Key - * @param {Object} obj Object + * @param {object} obj Object * @returns {void} */ const applyObjectDefine = (key, obj) => { - parser.hooks.canRename.for(key).tap("DefinePlugin", () => { + parser.hooks.canRename.for(key).tap(PLUGIN_NAME, () => { addValueDependency(key); return true; }); - parser.hooks.evaluateIdentifier - .for(key) - .tap("DefinePlugin", expr => { - addValueDependency(key); - return new BasicEvaluatedExpression() - .setTruthy() - .setSideEffects(false) - .setRange(expr.range); - }); + parser.hooks.evaluateIdentifier.for(key).tap(PLUGIN_NAME, expr => { + addValueDependency(key); + return new BasicEvaluatedExpression() + .setTruthy() + .setSideEffects(false) + .setRange(/** @type {Range} */ (expr.range)); + }); parser.hooks.evaluateTypeof .for(key) .tap( - "DefinePlugin", + PLUGIN_NAME, withValueDependency(key, evaluateToString("object")) ); - parser.hooks.expression.for(key).tap("DefinePlugin", expr => { + parser.hooks.expression.for(key).tap(PLUGIN_NAME, expr => { addValueDependency(key); - const strCode = stringifyObj( + let strCode = stringifyObj( obj, parser, compilation.valueCacheVersions, key, runtimeTemplate, - !parser.isAsiPosition(expr.range[0]) + logger, + !parser.isAsiPosition(/** @type {Range} */ (expr.range)[0]), + getObjKeys(parser.destructuringAssignmentPropertiesFor(expr)) ); - if (/__webpack_require__\s*(!?\.)/.test(strCode)) { + if (parser.scope.inShorthand) { + strCode = `${parser.scope.inShorthand}:${strCode}`; + } + + if (WEBPACK_REQUIRE_FUNCTION_REGEXP.test(strCode)) { return toConstantDependency(parser, strCode, [ RuntimeGlobals.require ])(expr); - } else if (/__webpack_require__/.test(strCode)) { + } else if (WEBPACK_REQUIRE_IDENTIFIER_REGEXP.test(strCode)) { return toConstantDependency(parser, strCode, [ RuntimeGlobals.requireScope ])(expr); - } else { - return toConstantDependency(parser, strCode)(expr); } + return toConstantDependency(parser, strCode)(expr); }); parser.hooks.typeof .for(key) .tap( - "DefinePlugin", + PLUGIN_NAME, withValueDependency( key, toConstantDependency(parser, JSON.stringify("object")) @@ -526,32 +648,33 @@ class DefinePlugin { }; normalModuleFactory.hooks.parser - .for("javascript/auto") - .tap("DefinePlugin", handler); + .for(JAVASCRIPT_MODULE_TYPE_AUTO) + .tap(PLUGIN_NAME, handler); normalModuleFactory.hooks.parser - .for("javascript/dynamic") - .tap("DefinePlugin", handler); + .for(JAVASCRIPT_MODULE_TYPE_DYNAMIC) + .tap(PLUGIN_NAME, handler); normalModuleFactory.hooks.parser - .for("javascript/esm") - .tap("DefinePlugin", handler); + .for(JAVASCRIPT_MODULE_TYPE_ESM) + .tap(PLUGIN_NAME, handler); /** * Walk definitions - * @param {Object} definitions Definitions map + * @param {Record} definitions Definitions map * @param {string} prefix Prefix string * @returns {void} */ const walkDefinitionsForValues = (definitions, prefix) => { - Object.keys(definitions).forEach(key => { + for (const key of Object.keys(definitions)) { const code = definitions[key]; const version = toCacheVersion(code); const name = VALUE_DEP_PREFIX + prefix + key; + mainHash.update(`|${prefix}${key}`); const oldVersion = compilation.valueCacheVersions.get(name); if (oldVersion === undefined) { compilation.valueCacheVersions.set(name, version); } else if (oldVersion !== version) { const warning = new WebpackError( - `DefinePlugin\nConflicting values for '${prefix + key}'` + `${PLUGIN_NAME}\nConflicting values for '${prefix + key}'` ); warning.details = `'${oldVersion}' !== '${version}'`; warning.hideStack = true; @@ -563,12 +686,20 @@ class DefinePlugin { !(code instanceof RuntimeValue) && !(code instanceof RegExp) ) { - walkDefinitionsForValues(code, prefix + key + "."); + walkDefinitionsForValues( + /** @type {Record} */ (code), + `${prefix + key}.` + ); } - }); + } }; walkDefinitionsForValues(definitions, ""); + + compilation.valueCacheVersions.set( + VALUE_DEP_MAIN, + /** @type {string} */ (mainHash.digest("hex").slice(0, 8)) + ); } ); } diff --git a/lib/DelegatedModule.js b/lib/DelegatedModule.js index 98e0ca8f46d..dc4d2bc3ae2 100644 --- a/lib/DelegatedModule.js +++ b/lib/DelegatedModule.js @@ -7,6 +7,7 @@ const { OriginalSource, RawSource } = require("webpack-sources"); const Module = require("./Module"); +const { JAVASCRIPT_MODULE_TYPE_DYNAMIC } = require("./ModuleTypeConstants"); const RuntimeGlobals = require("./RuntimeGlobals"); const DelegatedSourceDependency = require("./dependencies/DelegatedSourceDependency"); const StaticExportsDependency = require("./dependencies/StaticExportsDependency"); @@ -24,14 +25,21 @@ const makeSerializable = require("./util/makeSerializable"); /** @typedef {import("./Module").LibIdentOptions} LibIdentOptions */ /** @typedef {import("./Module").NeedBuildContext} NeedBuildContext */ /** @typedef {import("./Module").SourceContext} SourceContext */ +/** @typedef {import("./Module").SourceTypes} SourceTypes */ /** @typedef {import("./RequestShortener")} RequestShortener */ /** @typedef {import("./ResolverFactory").ResolverWithOptions} ResolverWithOptions */ /** @typedef {import("./RuntimeTemplate")} RuntimeTemplate */ /** @typedef {import("./WebpackError")} WebpackError */ /** @typedef {import("./dependencies/ModuleDependency")} ModuleDependency */ +/** @typedef {import("./serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */ +/** @typedef {import("./serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */ /** @typedef {import("./util/Hash")} Hash */ /** @typedef {import("./util/fs").InputFileSystem} InputFileSystem */ +/** @typedef {string} SourceRequest */ +/** @typedef {"require" | "object"} Type */ +/** @typedef {TODO} Data */ + const TYPES = new Set(["javascript"]); const RUNTIME_REQUIREMENTS = new Set([ RuntimeGlobals.module, @@ -39,8 +47,15 @@ const RUNTIME_REQUIREMENTS = new Set([ ]); class DelegatedModule extends Module { + /** + * @param {SourceRequest} sourceRequest source request + * @param {Data} data data + * @param {Type} type type + * @param {string} userRequest user request + * @param {string | Module} originalRequest original request + */ constructor(sourceRequest, data, type, userRequest, originalRequest) { - super("javascript/dynamic", null); + super(JAVASCRIPT_MODULE_TYPE_DYNAMIC, null); // Info from Factory this.sourceRequest = sourceRequest; @@ -48,7 +63,7 @@ class DelegatedModule extends Module { this.delegationType = type; this.userRequest = userRequest; this.originalRequest = originalRequest; - /** @type {ManifestModuleData} */ + /** @type {ManifestModuleData | undefined} */ this.delegateData = data; // Build info @@ -56,7 +71,7 @@ class DelegatedModule extends Module { } /** - * @returns {Set} types available (do not mutate) + * @returns {SourceTypes} types available (do not mutate) */ getSourceTypes() { return TYPES; @@ -91,7 +106,7 @@ class DelegatedModule extends Module { /** * @param {NeedBuildContext} context context info - * @param {function(WebpackError=, boolean=): void} callback callback function, returns true, if the module needs a rebuild + * @param {function((WebpackError | null)=, boolean=): void} callback callback function, returns true, if the module needs a rebuild * @returns {void} */ needBuild(context, callback) { @@ -107,7 +122,8 @@ class DelegatedModule extends Module { * @returns {void} */ build(options, compilation, resolver, fs, callback) { - this.buildMeta = { ...this.delegateData.buildMeta }; + const delegateData = /** @type {ManifestModuleData} */ (this.delegateData); + this.buildMeta = { ...delegateData.buildMeta }; this.buildInfo = {}; this.dependencies.length = 0; this.delegatedSourceDependency = new DelegatedSourceDependency( @@ -115,7 +131,7 @@ class DelegatedModule extends Module { ); this.addDependency(this.delegatedSourceDependency); this.addDependency( - new StaticExportsDependency(this.delegateData.exports || true, false) + new StaticExportsDependency(delegateData.exports || true, false) ); callback(); } @@ -185,6 +201,9 @@ class DelegatedModule extends Module { super.updateHash(hash, context); } + /** + * @param {ObjectSerializerContext} context context + */ serialize(context) { const { write } = context; // constructor @@ -196,6 +215,10 @@ class DelegatedModule extends Module { super.serialize(context); } + /** + * @param {ObjectDeserializerContext} context context\ + * @returns {DelegatedModule} DelegatedModule + */ static deserialize(context) { const { read } = context; const obj = new DelegatedModule( diff --git a/lib/DelegatedModuleFactoryPlugin.js b/lib/DelegatedModuleFactoryPlugin.js index 1614c74ae27..ae9b79aaed7 100644 --- a/lib/DelegatedModuleFactoryPlugin.js +++ b/lib/DelegatedModuleFactoryPlugin.js @@ -7,19 +7,38 @@ const DelegatedModule = require("./DelegatedModule"); -// options.source -// options.type -// options.context -// options.scope -// options.content -// options.associatedObjectForCache +/** @typedef {import("../declarations/plugins/DllReferencePlugin").DllReferencePluginOptions} DllReferencePluginOptions */ +/** @typedef {import("../declarations/plugins/DllReferencePlugin").DllReferencePluginOptionsContent} DllReferencePluginOptionsContent */ +/** @typedef {import("./DelegatedModule").Data} Data */ +/** @typedef {import("./DelegatedModule").SourceRequest} SourceRequest */ +/** @typedef {import("./DelegatedModule").Type} Type */ +/** @typedef {import("./NormalModuleFactory")} NormalModuleFactory */ + +/** + * @typedef {object} Options + * @property {SourceRequest} source source + * @property {NonNullable} context absolute context path to which lib ident is relative to + * @property {DllReferencePluginOptionsContent} content content + * @property {DllReferencePluginOptions["type"]} type type + * @property {DllReferencePluginOptions["extensions"]} extensions extensions + * @property {DllReferencePluginOptions["scope"]} scope scope + * @property {object=} associatedObjectForCache object for caching + */ + class DelegatedModuleFactoryPlugin { + /** + * @param {Options} options options + */ constructor(options) { this.options = options; options.type = options.type || "require"; options.extensions = options.extensions || ["", ".js", ".json", ".wasm"]; } + /** + * @param {NormalModuleFactory} normalModuleFactory the normal module factory + * @returns {void} + */ apply(normalModuleFactory) { const scope = this.options.scope; if (scope) { @@ -29,7 +48,7 @@ class DelegatedModuleFactoryPlugin { const [dependency] = data.dependencies; const { request } = dependency; if (request && request.startsWith(`${scope}/`)) { - const innerRequest = "." + request.substr(scope.length); + const innerRequest = `.${request.slice(scope.length)}`; let resolved; if (innerRequest in this.options.content) { resolved = this.options.content[innerRequest]; @@ -38,14 +57,17 @@ class DelegatedModuleFactoryPlugin { new DelegatedModule( this.options.source, resolved, - this.options.type, + /** @type {Type} */ (this.options.type), innerRequest, request ) ); } - for (let i = 0; i < this.options.extensions.length; i++) { - const extension = this.options.extensions[i]; + const extensions = + /** @type {string[]} */ + (this.options.extensions); + for (let i = 0; i < extensions.length; i++) { + const extension = extensions[i]; const requestPlusExt = innerRequest + extension; if (requestPlusExt in this.options.content) { resolved = this.options.content[requestPlusExt]; @@ -54,7 +76,7 @@ class DelegatedModuleFactoryPlugin { new DelegatedModule( this.options.source, resolved, - this.options.type, + /** @type {Type} */ (this.options.type), requestPlusExt, request + extension ) @@ -70,17 +92,15 @@ class DelegatedModuleFactoryPlugin { "DelegatedModuleFactoryPlugin", module => { const request = module.libIdent(this.options); - if (request) { - if (request in this.options.content) { - const resolved = this.options.content[request]; - return new DelegatedModule( - this.options.source, - resolved, - this.options.type, - request, - module - ); - } + if (request && request in this.options.content) { + const resolved = this.options.content[request]; + return new DelegatedModule( + this.options.source, + resolved, + /** @type {Type} */ (this.options.type), + request, + module + ); } return module; } diff --git a/lib/DelegatedPlugin.js b/lib/DelegatedPlugin.js index ffcc489c2cf..735e2f083e2 100644 --- a/lib/DelegatedPlugin.js +++ b/lib/DelegatedPlugin.js @@ -9,8 +9,12 @@ const DelegatedModuleFactoryPlugin = require("./DelegatedModuleFactoryPlugin"); const DelegatedSourceDependency = require("./dependencies/DelegatedSourceDependency"); /** @typedef {import("./Compiler")} Compiler */ +/** @typedef {import("./DelegatedModuleFactoryPlugin").Options} Options */ class DelegatedPlugin { + /** + * @param {Options} options options + */ constructor(options) { this.options = options; } diff --git a/lib/DependenciesBlock.js b/lib/DependenciesBlock.js index f1ab9cd58fd..a952b643b56 100644 --- a/lib/DependenciesBlock.js +++ b/lib/DependenciesBlock.js @@ -12,22 +12,40 @@ const makeSerializable = require("./util/makeSerializable"); /** @typedef {import("./ChunkGroup")} ChunkGroup */ /** @typedef {import("./Dependency")} Dependency */ /** @typedef {import("./Dependency").UpdateHashContext} UpdateHashContext */ +/** @typedef {import("./serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */ +/** @typedef {import("./serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */ /** @typedef {import("./util/Hash")} Hash */ /** @typedef {(d: Dependency) => boolean} DependencyFilterFunction */ +/** + * DependenciesBlock is the base class for all Module classes in webpack. It describes a + * "block" of dependencies which are pointers to other DependenciesBlock instances. For example + * when a Module has a CommonJs require statement, the DependencyBlock for the CommonJs module + * would be added as a dependency to the Module. DependenciesBlock is inherited by two types of classes: + * Module subclasses and AsyncDependenciesBlock subclasses. The only difference between the two is that + * AsyncDependenciesBlock subclasses are used for code-splitting (async boundary) and Module subclasses are not. + */ class DependenciesBlock { constructor() { /** @type {Dependency[]} */ this.dependencies = []; /** @type {AsyncDependenciesBlock[]} */ this.blocks = []; + /** @type {DependenciesBlock | undefined} */ + this.parent = undefined; + } + + getRootBlock() { + /** @type {DependenciesBlock} */ + let current = this; + while (current.parent) current = current.parent; + return current; } /** * Adds a DependencyBlock to DependencyBlock relationship. * This is used for when a Module has a AsyncDependencyBlock tie (for code-splitting) - * * @param {AsyncDependenciesBlock} block block being added * @returns {void} */ @@ -79,11 +97,17 @@ class DependenciesBlock { } } + /** + * @param {ObjectSerializerContext} context context + */ serialize({ write }) { write(this.dependencies); write(this.blocks); } + /** + * @param {ObjectDeserializerContext} context context + */ deserialize({ read }) { this.dependencies = read(); this.blocks = read(); diff --git a/lib/Dependency.js b/lib/Dependency.js index 6ff5ebe2520..a18f7365444 100644 --- a/lib/Dependency.js +++ b/lib/Dependency.js @@ -5,10 +5,12 @@ "use strict"; +const RawModule = require("./RawModule"); const memoize = require("./util/memoize"); /** @typedef {import("webpack-sources").Source} Source */ /** @typedef {import("./ChunkGraph")} ChunkGraph */ +/** @typedef {import("./DependenciesBlock")} DependenciesBlock */ /** @typedef {import("./DependencyTemplates")} DependencyTemplates */ /** @typedef {import("./Module")} Module */ /** @typedef {import("./ModuleGraph")} ModuleGraph */ @@ -16,80 +18,98 @@ const memoize = require("./util/memoize"); /** @typedef {import("./ModuleGraphConnection").ConnectionState} ConnectionState */ /** @typedef {import("./RuntimeTemplate")} RuntimeTemplate */ /** @typedef {import("./WebpackError")} WebpackError */ +/** @typedef {import("./serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */ +/** @typedef {import("./serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */ /** @typedef {import("./util/Hash")} Hash */ /** @typedef {import("./util/runtime").RuntimeSpec} RuntimeSpec */ /** - * @typedef {Object} UpdateHashContext + * @typedef {object} UpdateHashContext * @property {ChunkGraph} chunkGraph * @property {RuntimeSpec} runtime * @property {RuntimeTemplate=} runtimeTemplate */ /** - * @typedef {Object} SourcePosition + * @typedef {object} SourcePosition * @property {number} line * @property {number=} column */ /** - * @typedef {Object} RealDependencyLocation + * @typedef {object} RealDependencyLocation * @property {SourcePosition} start * @property {SourcePosition=} end * @property {number=} index */ /** - * @typedef {Object} SyntheticDependencyLocation + * @typedef {object} SyntheticDependencyLocation * @property {string} name * @property {number=} index */ -/** @typedef {SyntheticDependencyLocation|RealDependencyLocation} DependencyLocation */ +/** @typedef {SyntheticDependencyLocation | RealDependencyLocation} DependencyLocation */ /** - * @typedef {Object} ExportSpec + * @typedef {object} ExportSpec * @property {string} name the name of the export * @property {boolean=} canMangle can the export be renamed (defaults to true) * @property {boolean=} terminalBinding is the export a terminal binding that should be checked for export star conflicts * @property {(string | ExportSpec)[]=} exports nested exports * @property {ModuleGraphConnection=} from when reexported: from which module * @property {string[] | null=} export when reexported: from which export + * @property {number=} priority when reexported: with which priority * @property {boolean=} hidden export is not visible, because another export blends over it */ /** - * @typedef {Object} ExportsSpec + * @typedef {object} ExportsSpec * @property {(string | ExportSpec)[] | true | null} exports exported names, true for unknown exports or null for no exports * @property {Set=} excludeExports when exports = true, list of unaffected exports - * @property {Set=} hideExports list of maybe prior exposed, but now hidden exports + * @property {(Set | null)=} hideExports list of maybe prior exposed, but now hidden exports * @property {ModuleGraphConnection=} from when reexported: from which module + * @property {number=} priority when reexported: with which priority * @property {boolean=} canMangle can the export be renamed (defaults to true) * @property {boolean=} terminalBinding are the exports terminal bindings that should be checked for export star conflicts * @property {Module[]=} dependencies module on which the result depends on */ /** - * @typedef {Object} ReferencedExport + * @typedef {object} ReferencedExport * @property {string[]} name name of the referenced export * @property {boolean=} canMangle when false, referenced export can not be mangled, defaults to true */ -const getIgnoredModule = memoize(() => { - const RawModule = require("./RawModule"); - return new RawModule("/* (ignored) */", `ignored`, `(ignored)`); -}); +/** @typedef {function(ModuleGraphConnection, RuntimeSpec): ConnectionState} GetConditionFn */ + +const TRANSITIVE = Symbol("transitive"); + +const getIgnoredModule = memoize( + () => new RawModule("/* (ignored) */", "ignored", "(ignored)") +); class Dependency { constructor() { + /** @type {Module | undefined} */ + this._parentModule = undefined; + /** @type {DependenciesBlock | undefined} */ + this._parentDependenciesBlock = undefined; + /** @type {number} */ + this._parentDependenciesBlockIndex = -1; // TODO check if this can be moved into ModuleDependency /** @type {boolean} */ this.weak = false; // TODO check if this can be moved into ModuleDependency /** @type {boolean} */ this.optional = false; - /** @type {DependencyLocation} */ - this.loc = undefined; + this._locSL = 0; + this._locSC = 0; + this._locEL = 0; + this._locEC = 0; + this._locI = undefined; + this._locN = undefined; + this._loc = undefined; } /** @@ -106,6 +126,71 @@ class Dependency { return "unknown"; } + /** + * @returns {DependencyLocation} location + */ + get loc() { + if (this._loc !== undefined) return this._loc; + /** @type {SyntheticDependencyLocation & RealDependencyLocation} */ + const loc = {}; + if (this._locSL > 0) { + loc.start = { line: this._locSL, column: this._locSC }; + } + if (this._locEL > 0) { + loc.end = { line: this._locEL, column: this._locEC }; + } + if (this._locN !== undefined) { + loc.name = this._locN; + } + if (this._locI !== undefined) { + loc.index = this._locI; + } + return (this._loc = loc); + } + + set loc(loc) { + if ("start" in loc && typeof loc.start === "object") { + this._locSL = loc.start.line || 0; + this._locSC = loc.start.column || 0; + } else { + this._locSL = 0; + this._locSC = 0; + } + if ("end" in loc && typeof loc.end === "object") { + this._locEL = loc.end.line || 0; + this._locEC = loc.end.column || 0; + } else { + this._locEL = 0; + this._locEC = 0; + } + this._locI = "index" in loc ? loc.index : undefined; + this._locN = "name" in loc ? loc.name : undefined; + this._loc = loc; + } + + /** + * @param {number} startLine start line + * @param {number} startColumn start column + * @param {number} endLine end line + * @param {number} endColumn end column + */ + setLoc(startLine, startColumn, endLine, endColumn) { + this._locSL = startLine; + this._locSC = startColumn; + this._locEL = endLine; + this._locEC = endColumn; + this._locI = undefined; + this._locN = undefined; + this._loc = undefined; + } + + /** + * @returns {string | undefined} a request context + */ + getContext() { + return undefined; + } + /** * @returns {string | null} an identifier to merge equal requests */ @@ -113,6 +198,13 @@ class Dependency { return null; } + /** + * @returns {boolean | TRANSITIVE} true, when changes to the referenced module could affect the referencing module; TRANSITIVE, when changes to the referenced module could affect referencing modules of the referencing module + */ + couldAffectReferencingModule() { + return TRANSITIVE; + } + /** * Returns the referenced module and export * @deprecated @@ -137,7 +229,7 @@ class Dependency { /** * @param {ModuleGraph} moduleGraph module graph - * @returns {null | false | function(ModuleGraphConnection, RuntimeSpec): ConnectionState} function to determine if the connection is active + * @returns {null | false | GetConditionFn} function to determine if the connection is active */ getCondition(moduleGraph) { return null; @@ -155,7 +247,7 @@ class Dependency { /** * Returns warnings * @param {ModuleGraph} moduleGraph module graph - * @returns {WebpackError[]} warnings + * @returns {WebpackError[] | null | undefined} warnings */ getWarnings(moduleGraph) { return null; @@ -164,7 +256,7 @@ class Dependency { /** * Returns errors * @param {ModuleGraph} moduleGraph module graph - * @returns {WebpackError[]} errors + * @returns {WebpackError[] | null | undefined} errors */ getErrors(moduleGraph) { return null; @@ -196,28 +288,48 @@ class Dependency { /** * @param {string} context context directory - * @returns {Module} a module + * @returns {Module | null} a module */ createIgnoredModule(context) { return getIgnoredModule(); } + /** + * @param {ObjectSerializerContext} context context + */ serialize({ write }) { write(this.weak); write(this.optional); - write(this.loc); + write(this._locSL); + write(this._locSC); + write(this._locEL); + write(this._locEC); + write(this._locI); + write(this._locN); } + /** + * @param {ObjectDeserializerContext} context context + */ deserialize({ read }) { this.weak = read(); this.optional = read(); - this.loc = read(); + this._locSL = read(); + this._locSC = read(); + this._locEL = read(); + this._locEC = read(); + this._locI = read(); + this._locN = read(); } } +/** @type {string[][]} */ Dependency.NO_EXPORTS_REFERENCED = []; +/** @type {string[][]} */ Dependency.EXPORTS_OBJECT_REFERENCED = [[]]; +// eslint-disable-next-line no-warning-comments +// @ts-ignore https://github.com/microsoft/TypeScript/issues/42919 Object.defineProperty(Dependency.prototype, "module", { /** * @deprecated @@ -240,6 +352,8 @@ Object.defineProperty(Dependency.prototype, "module", { } }); +// eslint-disable-next-line no-warning-comments +// @ts-ignore https://github.com/microsoft/TypeScript/issues/42919 Object.defineProperty(Dependency.prototype, "disconnect", { get() { throw new Error( @@ -248,4 +362,6 @@ Object.defineProperty(Dependency.prototype, "disconnect", { } }); +Dependency.TRANSITIVE = TRANSITIVE; + module.exports = Dependency; diff --git a/lib/DependencyTemplate.js b/lib/DependencyTemplate.js index 37da12d131c..84d9d7cda7e 100644 --- a/lib/DependencyTemplate.js +++ b/lib/DependencyTemplate.js @@ -7,28 +7,50 @@ /** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */ /** @typedef {import("./ChunkGraph")} ChunkGraph */ +/** @typedef {import("./CodeGenerationResults")} CodeGenerationResults */ /** @typedef {import("./ConcatenationScope")} ConcatenationScope */ /** @typedef {import("./Dependency")} Dependency */ /** @typedef {import("./Dependency").RuntimeSpec} RuntimeSpec */ /** @typedef {import("./DependencyTemplates")} DependencyTemplates */ -/** @typedef {import("./InitFragment")} InitFragment */ +/** @typedef {import("./Generator").GenerateContext} GenerateContext */ /** @typedef {import("./Module")} Module */ +/** @typedef {import("./Module").RuntimeRequirements} RuntimeRequirements */ /** @typedef {import("./ModuleGraph")} ModuleGraph */ /** @typedef {import("./RuntimeTemplate")} RuntimeTemplate */ /** - * @typedef {Object} DependencyTemplateContext + * @template T + * @typedef {import("./InitFragment")} InitFragment + */ + +/** + * @typedef {object} DependencyTemplateContext * @property {RuntimeTemplate} runtimeTemplate the runtime template * @property {DependencyTemplates} dependencyTemplates the dependency templates * @property {ModuleGraph} moduleGraph the module graph * @property {ChunkGraph} chunkGraph the chunk graph - * @property {Set} runtimeRequirements the requirements for runtime + * @property {RuntimeRequirements} runtimeRequirements the requirements for runtime * @property {Module} module current module * @property {RuntimeSpec} runtime current runtimes, for which code is generated - * @property {InitFragment[]} initFragments mutable array of init fragments for the current module + * @property {InitFragment[]} initFragments mutable array of init fragments for the current module * @property {ConcatenationScope=} concatenationScope when in a concatenated module, information about other concatenated modules + * @property {CodeGenerationResults} codeGenerationResults the code generation results + * @property {InitFragment[]} chunkInitFragments chunkInitFragments + */ + +/** + * @typedef {object} CssDependencyTemplateContextExtras + * @property {CssExportsData} cssExportsData the css exports data */ +/** + * @typedef {object} CssExportsData + * @property {boolean} esModule whether export __esModule + * @property {Map} exports the css exports + */ + +/** @typedef {DependencyTemplateContext & CssDependencyTemplateContextExtras} CssDependencyTemplateContext */ + class DependencyTemplate { /* istanbul ignore next */ /** diff --git a/lib/DependencyTemplates.js b/lib/DependencyTemplates.js index 117c05af0e6..3b553dae4cb 100644 --- a/lib/DependencyTemplates.js +++ b/lib/DependencyTemplates.js @@ -9,19 +9,25 @@ const createHash = require("./util/createHash"); /** @typedef {import("./Dependency")} Dependency */ /** @typedef {import("./DependencyTemplate")} DependencyTemplate */ +/** @typedef {typeof import("./util/Hash")} Hash */ + /** @typedef {new (...args: any[]) => Dependency} DependencyConstructor */ class DependencyTemplates { - constructor() { + /** + * @param {string | Hash} hashFunction the hash function to use + */ + constructor(hashFunction = "md4") { /** @type {Map} */ this._map = new Map(); /** @type {string} */ this._hash = "31d6cfe0d16ae931b73c59d7e0c089c0"; + this._hashFunction = hashFunction; } /** * @param {DependencyConstructor} dependency Constructor of Dependency - * @returns {DependencyTemplate} template for this dependency + * @returns {DependencyTemplate | undefined} template for this dependency */ get(dependency) { return this._map.get(dependency); @@ -41,9 +47,8 @@ class DependencyTemplates { * @returns {void} */ updateHash(part) { - const hash = createHash("md4"); - hash.update(this._hash); - hash.update(part); + const hash = createHash(this._hashFunction); + hash.update(`${this._hash}${part}`); this._hash = /** @type {string} */ (hash.digest("hex")); } @@ -52,7 +57,7 @@ class DependencyTemplates { } clone() { - const newInstance = new DependencyTemplates(); + const newInstance = new DependencyTemplates(this._hashFunction); newInstance._map = new Map(this._map); newInstance._hash = this._hash; return newInstance; diff --git a/lib/DllEntryPlugin.js b/lib/DllEntryPlugin.js index 529eb0de9e2..de849fa5376 100644 --- a/lib/DllEntryPlugin.js +++ b/lib/DllEntryPlugin.js @@ -9,13 +9,27 @@ const DllModuleFactory = require("./DllModuleFactory"); const DllEntryDependency = require("./dependencies/DllEntryDependency"); const EntryDependency = require("./dependencies/EntryDependency"); +/** @typedef {import("./Compiler")} Compiler */ +/** @typedef {string[]} Entries */ +/** @typedef {{ name: string, filename: TODO }} Options */ + class DllEntryPlugin { + /** + * @param {string} context context + * @param {Entries} entries entry names + * @param {Options} options options + */ constructor(context, entries, options) { this.context = context; this.entries = entries; this.options = options; } + /** + * Apply the plugin + * @param {Compiler} compiler the compiler instance + * @returns {void} + */ apply(compiler) { compiler.hooks.compilation.tap( "DllEntryPlugin", @@ -46,7 +60,10 @@ class DllEntryPlugin { this.options.name ), this.options, - callback + error => { + if (error) return callback(error); + callback(); + } ); }); } diff --git a/lib/DllModule.js b/lib/DllModule.js index ce124e72bb3..be17eded399 100644 --- a/lib/DllModule.js +++ b/lib/DllModule.js @@ -7,6 +7,7 @@ const { RawSource } = require("webpack-sources"); const Module = require("./Module"); +const { JAVASCRIPT_MODULE_TYPE_DYNAMIC } = require("./ModuleTypeConstants"); const RuntimeGlobals = require("./RuntimeGlobals"); const makeSerializable = require("./util/makeSerializable"); @@ -14,16 +15,20 @@ const makeSerializable = require("./util/makeSerializable"); /** @typedef {import("../declarations/WebpackOptions").WebpackOptionsNormalized} WebpackOptions */ /** @typedef {import("./ChunkGraph")} ChunkGraph */ /** @typedef {import("./Compilation")} Compilation */ +/** @typedef {import("./Dependency")} Dependency */ /** @typedef {import("./Dependency").UpdateHashContext} UpdateHashContext */ /** @typedef {import("./DependencyTemplates")} DependencyTemplates */ /** @typedef {import("./Module").CodeGenerationContext} CodeGenerationContext */ /** @typedef {import("./Module").CodeGenerationResult} CodeGenerationResult */ /** @typedef {import("./Module").NeedBuildContext} NeedBuildContext */ /** @typedef {import("./Module").SourceContext} SourceContext */ +/** @typedef {import("./Module").SourceTypes} SourceTypes */ /** @typedef {import("./RequestShortener")} RequestShortener */ /** @typedef {import("./ResolverFactory").ResolverWithOptions} ResolverWithOptions */ /** @typedef {import("./RuntimeTemplate")} RuntimeTemplate */ /** @typedef {import("./WebpackError")} WebpackError */ +/** @typedef {import("./serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */ +/** @typedef {import("./serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */ /** @typedef {import("./util/Hash")} Hash */ /** @typedef {import("./util/fs").InputFileSystem} InputFileSystem */ @@ -34,16 +39,22 @@ const RUNTIME_REQUIREMENTS = new Set([ ]); class DllModule extends Module { + /** + * @param {string} context context path + * @param {Dependency[]} dependencies dependencies + * @param {string} name name + */ constructor(context, dependencies, name) { - super("javascript/dynamic", context); + super(JAVASCRIPT_MODULE_TYPE_DYNAMIC, context); // Info from Factory + /** @type {Dependency[]} */ this.dependencies = dependencies; this.name = name; } /** - * @returns {Set} types available (do not mutate) + * @returns {SourceTypes} types available (do not mutate) */ getSourceTypes() { return TYPES; @@ -86,7 +97,7 @@ class DllModule extends Module { const sources = new Map(); sources.set( "javascript", - new RawSource("module.exports = __webpack_require__;") + new RawSource(`module.exports = ${RuntimeGlobals.require};`) ); return { sources, @@ -96,7 +107,7 @@ class DllModule extends Module { /** * @param {NeedBuildContext} context context info - * @param {function(WebpackError=, boolean=): void} callback callback function, returns true, if the module needs a rebuild + * @param {function((WebpackError | null)=, boolean=): void} callback callback function, returns true, if the module needs a rebuild * @returns {void} */ needBuild(context, callback) { @@ -117,16 +128,21 @@ class DllModule extends Module { * @returns {void} */ updateHash(hash, context) { - hash.update("dll module"); - hash.update(this.name || ""); + hash.update(`dll module${this.name || ""}`); super.updateHash(hash, context); } + /** + * @param {ObjectSerializerContext} context context + */ serialize(context) { context.write(this.name); super.serialize(context); } + /** + * @param {ObjectDeserializerContext} context context + */ deserialize(context) { this.name = context.read(); super.deserialize(context); diff --git a/lib/DllModuleFactory.js b/lib/DllModuleFactory.js index dc59d517a8a..d8800353da9 100644 --- a/lib/DllModuleFactory.js +++ b/lib/DllModuleFactory.js @@ -17,9 +17,10 @@ class DllModuleFactory extends ModuleFactory { super(); this.hooks = Object.freeze({}); } + /** * @param {ModuleFactoryCreateData} data data object - * @param {function(Error=, ModuleFactoryResult=): void} callback callback + * @param {function((Error | null)=, ModuleFactoryResult=): void} callback callback * @returns {void} */ create(data, callback) { diff --git a/lib/DllPlugin.js b/lib/DllPlugin.js index a618f2ea828..25440df04ee 100644 --- a/lib/DllPlugin.js +++ b/lib/DllPlugin.js @@ -8,22 +8,28 @@ const DllEntryPlugin = require("./DllEntryPlugin"); const FlagAllModulesAsUsedPlugin = require("./FlagAllModulesAsUsedPlugin"); const LibManifestPlugin = require("./LibManifestPlugin"); - -const { validate } = require("schema-utils"); -const schema = require("../schemas/plugins/DllPlugin.json"); +const createSchemaValidation = require("./util/create-schema-validation"); /** @typedef {import("../declarations/plugins/DllPlugin").DllPluginOptions} DllPluginOptions */ /** @typedef {import("./Compiler")} Compiler */ +/** @typedef {import("./DllEntryPlugin").Entries} Entries */ +/** @typedef {import("./DllEntryPlugin").Options} Options */ + +const validate = createSchemaValidation( + require("../schemas/plugins/DllPlugin.check.js"), + () => require("../schemas/plugins/DllPlugin.json"), + { + name: "Dll Plugin", + baseDataPath: "options" + } +); class DllPlugin { /** * @param {DllPluginOptions} options options object */ constructor(options) { - validate(schema, options, { - name: "Dll Plugin", - baseDataPath: "options" - }); + validate(options); this.options = { ...options, entryOnly: options.entryOnly !== false @@ -39,13 +45,13 @@ class DllPlugin { compiler.hooks.entryOption.tap("DllPlugin", (context, entry) => { if (typeof entry !== "function") { for (const name of Object.keys(entry)) { - const options = { - name, - filename: entry.filename - }; - new DllEntryPlugin(context, entry[name].import, options).apply( - compiler - ); + /** @type {Options} */ + const options = { name, filename: entry.filename }; + new DllEntryPlugin( + context, + /** @type {Entries} */ (entry[name].import), + options + ).apply(compiler); } } else { throw new Error( diff --git a/lib/DllReferencePlugin.js b/lib/DllReferencePlugin.js index 11bb25046f4..50b2c541021 100644 --- a/lib/DllReferencePlugin.js +++ b/lib/DllReferencePlugin.js @@ -5,34 +5,48 @@ "use strict"; -const parseJson = require("json-parse-better-errors"); +const parseJson = require("json-parse-even-better-errors"); const DelegatedModuleFactoryPlugin = require("./DelegatedModuleFactoryPlugin"); const ExternalModuleFactoryPlugin = require("./ExternalModuleFactoryPlugin"); const WebpackError = require("./WebpackError"); const DelegatedSourceDependency = require("./dependencies/DelegatedSourceDependency"); +const createSchemaValidation = require("./util/create-schema-validation"); const makePathsRelative = require("./util/identifier").makePathsRelative; -const { validate } = require("schema-utils"); -const schema = require("../schemas/plugins/DllReferencePlugin.json"); - /** @typedef {import("../declarations/WebpackOptions").Externals} Externals */ /** @typedef {import("../declarations/plugins/DllReferencePlugin").DllReferencePluginOptions} DllReferencePluginOptions */ +/** @typedef {import("../declarations/plugins/DllReferencePlugin").DllReferencePluginOptionsContent} DllReferencePluginOptionsContent */ /** @typedef {import("../declarations/plugins/DllReferencePlugin").DllReferencePluginOptionsManifest} DllReferencePluginOptionsManifest */ +/** @typedef {import("./Compiler")} Compiler */ +/** @typedef {import("./util/fs").InputFileSystem} InputFileSystem */ + +const validate = createSchemaValidation( + require("../schemas/plugins/DllReferencePlugin.check.js"), + () => require("../schemas/plugins/DllReferencePlugin.json"), + { + name: "Dll Reference Plugin", + baseDataPath: "options" + } +); + +/** @typedef {{ path: string, data: DllReferencePluginOptionsManifest | undefined, error: Error | undefined }} CompilationDataItem */ class DllReferencePlugin { /** * @param {DllReferencePluginOptions} options options object */ constructor(options) { - validate(schema, options, { - name: "Dll Reference Plugin", - baseDataPath: "options" - }); + validate(options); this.options = options; - /** @type {WeakMap} */ + /** @type {WeakMap} */ this._compilationData = new WeakMap(); } + /** + * Apply the plugin + * @param {Compiler} compiler the compiler instance + * @returns {void} + */ apply(compiler) { compiler.hooks.compilation.tap( "DllReferencePlugin", @@ -50,8 +64,10 @@ class DllReferencePlugin { if ("manifest" in this.options) { const manifest = this.options.manifest; if (typeof manifest === "string") { - compiler.inputFileSystem.readFile(manifest, (err, result) => { + /** @type {InputFileSystem} */ + (compiler.inputFileSystem).readFile(manifest, (err, result) => { if (err) return callback(err); + /** @type {CompilationDataItem} */ const data = { path: manifest, data: undefined, @@ -60,16 +76,21 @@ class DllReferencePlugin { // Catch errors parsing the manifest so that blank // or malformed manifest files don't kill the process. try { - data.data = parseJson(result.toString("utf-8")); - } catch (e) { + data.data = parseJson( + /** @type {Buffer} */ (result).toString("utf-8") + ); + } catch (parseErr) { // Store the error in the params so that it can // be added as a compilation error later on. const manifestPath = makePathsRelative( - compiler.options.context, + /** @type {string} */ (compiler.options.context), manifest, compiler.root ); - data.error = new DllManifestError(manifestPath, e.message); + data.error = new DllManifestError( + manifestPath, + /** @type {Error} */ (parseErr).message + ); } this._compilationData.set(params, data); return callback(); @@ -84,13 +105,15 @@ class DllReferencePlugin { compiler.hooks.compile.tap("DllReferencePlugin", params => { let name = this.options.name; let sourceType = this.options.sourceType; - let content = + let resolvedContent = "content" in this.options ? this.options.content : undefined; if ("manifest" in this.options) { - let manifestParameter = this.options.manifest; + const manifestParameter = this.options.manifest; let manifest; if (typeof manifestParameter === "string") { - const data = this._compilationData.get(params); + const data = + /** @type {CompilationDataItem} */ + (this._compilationData.get(params)); // If there was an error parsing the manifest // file, exit now because the error will be added // as a compilation error in the "compilation" hook. @@ -104,23 +127,27 @@ class DllReferencePlugin { if (manifest) { if (!name) name = manifest.name; if (!sourceType) sourceType = manifest.type; - if (!content) content = manifest.content; + if (!resolvedContent) resolvedContent = manifest.content; } } /** @type {Externals} */ const externals = {}; - const source = "dll-reference " + name; - externals[source] = name; + const source = `dll-reference ${name}`; + externals[source] = /** @type {string} */ (name); const normalModuleFactory = params.normalModuleFactory; new ExternalModuleFactoryPlugin(sourceType || "var", externals).apply( normalModuleFactory ); new DelegatedModuleFactoryPlugin({ - source: source, + source, type: this.options.type, scope: this.options.scope, - context: this.options.context || compiler.options.context, - content, + context: + /** @type {string} */ + (this.options.context || compiler.options.context), + content: + /** @type {DllReferencePluginOptionsContent} */ + (resolvedContent), extensions: this.options.extensions, associatedObjectForCache: compiler.root }).apply(normalModuleFactory); @@ -130,13 +157,17 @@ class DllReferencePlugin { "DllReferencePlugin", (compilation, params) => { if ("manifest" in this.options) { - let manifest = this.options.manifest; + const manifest = this.options.manifest; if (typeof manifest === "string") { - const data = this._compilationData.get(params); + const data = /** @type {CompilationDataItem} */ ( + this._compilationData.get(params) + ); // If there was an error parsing the manifest file, add the // error as a compilation error to make the compilation fail. if (data.error) { - compilation.errors.push(data.error); + compilation.errors.push( + /** @type {DllManifestError} */ (data.error) + ); } compilation.fileDependencies.add(manifest); } @@ -147,13 +178,15 @@ class DllReferencePlugin { } class DllManifestError extends WebpackError { + /** + * @param {string} filename filename of the manifest + * @param {string} message error message + */ constructor(filename, message) { super(); this.name = "DllManifestError"; this.message = `Dll manifest ${filename}\n${message}`; - - Error.captureStackTrace(this, this.constructor); } } diff --git a/lib/EntryOptionPlugin.js b/lib/EntryOptionPlugin.js index 8291b14fbeb..3e290c186f2 100644 --- a/lib/EntryOptionPlugin.js +++ b/lib/EntryOptionPlugin.js @@ -41,7 +41,10 @@ class EntryOptionPlugin { name, desc ); - for (const entry of desc.import) { + const descImport = + /** @type {Exclude} */ + (desc.import); + for (const entry of descImport) { new EntryPlugin(context, entry, options).apply(compiler); } } @@ -62,7 +65,10 @@ class EntryOptionPlugin { runtime: desc.runtime, layer: desc.layer, dependOn: desc.dependOn, + baseUri: desc.baseUri, + publicPath: desc.publicPath, chunkLoading: desc.chunkLoading, + asyncChunks: desc.asyncChunks, wasmLoading: desc.wasmLoading, library: desc.library }; diff --git a/lib/EntryPlugin.js b/lib/EntryPlugin.js index 61c57daf4b3..77c879705e8 100644 --- a/lib/EntryPlugin.js +++ b/lib/EntryPlugin.js @@ -12,12 +12,10 @@ const EntryDependency = require("./dependencies/EntryDependency"); class EntryPlugin { /** - * An entry plugin which will handle - * creation of the EntryDependency - * + * An entry plugin which will handle creation of the EntryDependency * @param {string} context context path * @param {string} entry entry path - * @param {EntryOptions | string} options entry options (passing a string is deprecated) + * @param {EntryOptions | string=} options entry options (passing a string is deprecated) */ constructor(context, entry, options) { this.context = context; @@ -41,10 +39,10 @@ class EntryPlugin { } ); - compiler.hooks.make.tapAsync("EntryPlugin", (compilation, callback) => { - const { entry, options, context } = this; + const { entry, options, context } = this; + const dep = EntryPlugin.createDependency(entry, options); - const dep = EntryPlugin.createDependency(entry, options); + compiler.hooks.make.tapAsync("EntryPlugin", (compilation, callback) => { compilation.addEntry(context, dep, options, err => { callback(err); }); @@ -59,7 +57,12 @@ class EntryPlugin { static createDependency(entry, options) { const dep = new EntryDependency(entry); // TODO webpack 6 remove string option - dep.loc = { name: typeof options === "object" ? options.name : options }; + dep.loc = { + name: + typeof options === "object" + ? /** @type {string} */ (options.name) + : options + }; return dep; } } diff --git a/lib/Entrypoint.js b/lib/Entrypoint.js index e1ab20050c6..7aa019e4d28 100644 --- a/lib/Entrypoint.js +++ b/lib/Entrypoint.js @@ -83,13 +83,13 @@ class Entrypoint extends ChunkGroup { * @returns {Chunk} chunk */ getEntrypointChunk() { - return this._entrypointChunk; + return /** @type {Chunk} */ (this._entrypointChunk); } /** * @param {Chunk} oldChunk chunk to be replaced * @param {Chunk} newChunk New chunk that will be replaced with - * @returns {boolean} returns true if the replacement was successful + * @returns {boolean | undefined} returns true if the replacement was successful */ replaceChunk(oldChunk, newChunk) { if (this._runtimeChunk === oldChunk) this._runtimeChunk = newChunk; diff --git a/lib/EnvironmentNotSupportAsyncWarning.js b/lib/EnvironmentNotSupportAsyncWarning.js new file mode 100644 index 00000000000..1a1ea9ece66 --- /dev/null +++ b/lib/EnvironmentNotSupportAsyncWarning.js @@ -0,0 +1,52 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Gengkun He @ahabhgk +*/ + +"use strict"; + +const WebpackError = require("./WebpackError"); +const makeSerializable = require("./util/makeSerializable"); + +/** @typedef {import("./Module")} Module */ +/** @typedef {import("./Compilation")} Compilation */ +/** @typedef {import("./RuntimeTemplate")} RuntimeTemplate */ +/** @typedef {import("./serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */ +/** @typedef {import("./serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */ +/** @typedef {"asyncWebAssembly" | "topLevelAwait" | "external promise" | "external script" | "external import" | "external module"} Feature */ + +class EnvironmentNotSupportAsyncWarning extends WebpackError { + /** + * Creates an instance of EnvironmentNotSupportAsyncWarning. + * @param {Module} module module + * @param {Feature} feature feature + */ + constructor(module, feature) { + const message = `The generated code contains 'async/await' because this module is using "${feature}". +However, your target environment does not appear to support 'async/await'. +As a result, the code may not run as expected or may cause runtime errors.`; + super(message); + + this.name = "EnvironmentNotSupportAsyncWarning"; + this.module = module; + } + + /** + * Creates an instance of EnvironmentNotSupportAsyncWarning. + * @param {Module} module module + * @param {RuntimeTemplate} runtimeTemplate compilation + * @param {Feature} feature feature + */ + static check(module, runtimeTemplate, feature) { + if (!runtimeTemplate.supportsAsyncFunction()) { + module.addWarning(new EnvironmentNotSupportAsyncWarning(module, feature)); + } + } +} + +makeSerializable( + EnvironmentNotSupportAsyncWarning, + "webpack/lib/EnvironmentNotSupportAsyncWarning" +); + +module.exports = EnvironmentNotSupportAsyncWarning; diff --git a/lib/EnvironmentPlugin.js b/lib/EnvironmentPlugin.js index 3a8d9dcdde8..93292cc566c 100644 --- a/lib/EnvironmentPlugin.js +++ b/lib/EnvironmentPlugin.js @@ -12,15 +12,18 @@ const WebpackError = require("./WebpackError"); /** @typedef {import("./DefinePlugin").CodeValue} CodeValue */ class EnvironmentPlugin { + /** + * @param {(string | string[] | Record)[]} keys keys + */ constructor(...keys) { if (keys.length === 1 && Array.isArray(keys[0])) { this.keys = keys[0]; this.defaultValues = {}; } else if (keys.length === 1 && keys[0] && typeof keys[0] === "object") { this.keys = Object.keys(keys[0]); - this.defaultValues = keys[0]; + this.defaultValues = /** @type {Record} */ (keys[0]); } else { - this.keys = keys; + this.keys = /** @type {string[]} */ (keys); this.defaultValues = {}; } } diff --git a/lib/ErrorHelpers.js b/lib/ErrorHelpers.js index 7851bdc8eb0..58c11554193 100644 --- a/lib/ErrorHelpers.js +++ b/lib/ErrorHelpers.js @@ -9,53 +9,92 @@ const loaderFlag = "LOADER_EXECUTION"; const webpackOptionsFlag = "WEBPACK_OPTIONS"; -exports.cutOffByFlag = (stack, flag) => { - stack = stack.split("\n"); - for (let i = 0; i < stack.length; i++) { - if (stack[i].includes(flag)) { - stack.length = i; +/** + * @param {string} stack stack trace + * @param {string} flag flag to cut off + * @returns {string} stack trace without the specified flag included + */ +const cutOffByFlag = (stack, flag) => { + const errorStack = stack.split("\n"); + for (let i = 0; i < errorStack.length; i++) { + if (errorStack[i].includes(flag)) { + errorStack.length = i; } } - return stack.join("\n"); + return errorStack.join("\n"); }; -exports.cutOffLoaderExecution = stack => - exports.cutOffByFlag(stack, loaderFlag); +/** + * @param {string} stack stack trace + * @returns {string} stack trace without the loader execution flag included + */ +const cutOffLoaderExecution = stack => cutOffByFlag(stack, loaderFlag); -exports.cutOffWebpackOptions = stack => - exports.cutOffByFlag(stack, webpackOptionsFlag); +/** + * @param {string} stack stack trace + * @returns {string} stack trace without the webpack options flag included + */ +const cutOffWebpackOptions = stack => cutOffByFlag(stack, webpackOptionsFlag); -exports.cutOffMultilineMessage = (stack, message) => { - stack = stack.split("\n"); - message = message.split("\n"); +/** + * @param {string} stack stack trace + * @param {string} message error message + * @returns {string} stack trace without the message included + */ +const cutOffMultilineMessage = (stack, message) => { + const stackSplitByLines = stack.split("\n"); + const messageSplitByLines = message.split("\n"); + /** @type {string[]} */ const result = []; - stack.forEach((line, idx) => { - if (!line.includes(message[idx])) result.push(line); - }); + for (const [idx, line] of stackSplitByLines.entries()) { + if (!line.includes(messageSplitByLines[idx])) result.push(line); + } return result.join("\n"); }; -exports.cutOffMessage = (stack, message) => { +/** + * @param {string} stack stack trace + * @param {string} message error message + * @returns {string} stack trace without the message included + */ +const cutOffMessage = (stack, message) => { const nextLine = stack.indexOf("\n"); if (nextLine === -1) { return stack === message ? "" : stack; - } else { - const firstLine = stack.substr(0, nextLine); - return firstLine === message ? stack.substr(nextLine + 1) : stack; } + const firstLine = stack.slice(0, nextLine); + return firstLine === message ? stack.slice(nextLine + 1) : stack; }; -exports.cleanUp = (stack, message) => { - stack = exports.cutOffLoaderExecution(stack); - stack = exports.cutOffMessage(stack, message); +/** + * @param {string} stack stack trace + * @param {string} message error message + * @returns {string} stack trace without the loader execution flag and message included + */ +const cleanUp = (stack, message) => { + stack = cutOffLoaderExecution(stack); + stack = cutOffMessage(stack, message); return stack; }; -exports.cleanUpWebpackOptions = (stack, message) => { - stack = exports.cutOffWebpackOptions(stack); - stack = exports.cutOffMultilineMessage(stack, message); +/** + * @param {string} stack stack trace + * @param {string} message error message + * @returns {string} stack trace without the webpack options flag and message included + */ +const cleanUpWebpackOptions = (stack, message) => { + stack = cutOffWebpackOptions(stack); + stack = cutOffMultilineMessage(stack, message); return stack; }; + +module.exports.cutOffByFlag = cutOffByFlag; +module.exports.cutOffLoaderExecution = cutOffLoaderExecution; +module.exports.cutOffWebpackOptions = cutOffWebpackOptions; +module.exports.cutOffMultilineMessage = cutOffMultilineMessage; +module.exports.cutOffMessage = cutOffMessage; +module.exports.cleanUp = cleanUp; +module.exports.cleanUpWebpackOptions = cleanUpWebpackOptions; diff --git a/lib/EvalDevToolModulePlugin.js b/lib/EvalDevToolModulePlugin.js index 59c80a00449..ba2e5b6acec 100644 --- a/lib/EvalDevToolModulePlugin.js +++ b/lib/EvalDevToolModulePlugin.js @@ -8,9 +8,11 @@ const { ConcatSource, RawSource } = require("webpack-sources"); const ExternalModule = require("./ExternalModule"); const ModuleFilenameHelpers = require("./ModuleFilenameHelpers"); +const RuntimeGlobals = require("./RuntimeGlobals"); const JavascriptModulesPlugin = require("./javascript/JavascriptModulesPlugin"); /** @typedef {import("webpack-sources").Source} Source */ +/** @typedef {import("../declarations/WebpackOptions").OutputNormalized} OutputOptions */ /** @typedef {import("./Compiler")} Compiler */ /** @type {WeakMap} */ @@ -26,8 +28,18 @@ const devtoolWarning = new RawSource(`/* */ `); +/** + * @typedef {object} EvalDevToolModulePluginOptions + * @property {OutputOptions["devtoolNamespace"]=} namespace namespace + * @property {string=} sourceUrlComment source url comment + * @property {OutputOptions["devtoolModuleFilenameTemplate"]=} moduleFilenameTemplate module filename template + */ + class EvalDevToolModulePlugin { - constructor(options) { + /** + * @param {EvalDevToolModulePluginOptions=} options options + */ + constructor(options = {}) { this.namespace = options.namespace || ""; this.sourceUrlComment = options.sourceUrlComment || "\n//# sourceURL=[url]"; this.moduleFilenameTemplate = @@ -61,22 +73,27 @@ class EvalDevToolModulePlugin { }, { requestShortener: runtimeTemplate.requestShortener, - chunkGraph + chunkGraph, + hashFunction: compilation.outputOptions.hashFunction } ); - const footer = - "\n" + - this.sourceUrlComment.replace( - /\[url\]/g, - encodeURI(str) - .replace(/%2F/g, "/") - .replace(/%20/g, "_") - .replace(/%5E/g, "^") - .replace(/%5C/g, "\\") - .replace(/^\//, "") - ); + const footer = `\n${this.sourceUrlComment.replace( + /\[url\]/g, + encodeURI(str) + .replace(/%2F/g, "/") + .replace(/%20/g, "_") + .replace(/%5E/g, "^") + .replace(/%5C/g, "\\") + .replace(/^\//, "") + )}`; const result = new RawSource( - `eval(${JSON.stringify(content + footer)});` + `eval(${ + compilation.outputOptions.trustedTypes + ? `${RuntimeGlobals.createScript}(${JSON.stringify( + content + footer + )})` + : JSON.stringify(content + footer) + });` ); cache.set(source, result); return result; @@ -94,6 +111,14 @@ class EvalDevToolModulePlugin { hash.update("EvalDevToolModulePlugin"); hash.update("2"); }); + if (compilation.outputOptions.trustedTypes) { + compilation.hooks.additionalModuleRuntimeRequirements.tap( + "EvalDevToolModulePlugin", + (module, set, context) => { + set.add(RuntimeGlobals.createScript); + } + ); + } }); } } diff --git a/lib/EvalSourceMapDevToolPlugin.js b/lib/EvalSourceMapDevToolPlugin.js index 38ab57b489e..9619211cc19 100644 --- a/lib/EvalSourceMapDevToolPlugin.js +++ b/lib/EvalSourceMapDevToolPlugin.js @@ -8,15 +8,18 @@ const { ConcatSource, RawSource } = require("webpack-sources"); const ModuleFilenameHelpers = require("./ModuleFilenameHelpers"); const NormalModule = require("./NormalModule"); +const RuntimeGlobals = require("./RuntimeGlobals"); const SourceMapDevToolModuleOptionsPlugin = require("./SourceMapDevToolModuleOptionsPlugin"); const JavascriptModulesPlugin = require("./javascript/JavascriptModulesPlugin"); const ConcatenatedModule = require("./optimize/ConcatenatedModule"); -const { absolutify } = require("./util/identifier"); +const { makePathsAbsolute } = require("./util/identifier"); /** @typedef {import("webpack-sources").Source} Source */ /** @typedef {import("../declarations/WebpackOptions").DevTool} DevToolOptions */ /** @typedef {import("../declarations/plugins/SourceMapDevToolPlugin").SourceMapDevToolPluginOptions} SourceMapDevToolPluginOptions */ +/** @typedef {import("./ChunkGraph").ModuleId} ModuleId */ /** @typedef {import("./Compiler")} Compiler */ +/** @typedef {import("./NormalModule").SourceMap} SourceMap */ /** @type {WeakMap} */ const cache = new WeakMap(); @@ -46,7 +49,9 @@ class EvalSourceMapDevToolPlugin { options = inputOptions; } this.sourceMapComment = - options.append || "//# sourceURL=[module]\n//# sourceMappingURL=[url]"; + options.append && typeof options.append !== "function" + ? options.append + : "//# sourceURL=[module]\n//# sourceMappingURL=[url]"; this.moduleFilenameTemplate = options.moduleFilenameTemplate || "webpack://[namespace]/[resource-path]?[hash]"; @@ -78,6 +83,10 @@ class EvalSourceMapDevToolPlugin { return cachedSource; } + /** + * @param {Source} r result + * @returns {Source} result + */ const result = r => { cache.set(source, r); return r; @@ -91,7 +100,9 @@ class EvalSourceMapDevToolPlugin { } else if (m instanceof ConcatenatedModule) { const concatModule = /** @type {ConcatenatedModule} */ (m); if (concatModule.rootModule instanceof NormalModule) { - const module = /** @type {NormalModule} */ (concatModule.rootModule); + const module = /** @type {NormalModule} */ ( + concatModule.rootModule + ); if (!matchModule(module.resource)) { return result(source); } @@ -102,15 +113,15 @@ class EvalSourceMapDevToolPlugin { return result(source); } - /** @type {{ [key: string]: TODO; }} */ + /** @type {SourceMap} */ let sourceMap; let content; if (source.sourceAndMap) { const sourceAndMap = source.sourceAndMap(options); - sourceMap = sourceAndMap.map; + sourceMap = /** @type {SourceMap} */ (sourceAndMap.map); content = sourceAndMap.source; } else { - sourceMap = source.map(options); + sourceMap = /** @type {SourceMap} */ (source.map(options)); content = source.source(); } if (!sourceMap) { @@ -119,16 +130,16 @@ class EvalSourceMapDevToolPlugin { // Clone (flat) the sourcemap to ensure that the mutations below do not persist. sourceMap = { ...sourceMap }; - const context = compiler.options.context; + const context = /** @type {string} */ (compiler.options.context); const root = compiler.root; const modules = sourceMap.sources.map(source => { if (!source.startsWith("webpack://")) return source; - source = absolutify(context, source.slice(10), root); + source = makePathsAbsolute(context, source.slice(10), root); const module = compilation.findModule(source); return module || source; }); - let moduleFilenames = modules.map(module => { - return ModuleFilenameHelpers.createFilename( + let moduleFilenames = modules.map(module => + ModuleFilenameHelpers.createFilename( module, { moduleFilenameTemplate: this.moduleFilenameTemplate, @@ -136,10 +147,11 @@ class EvalSourceMapDevToolPlugin { }, { requestShortener: runtimeTemplate.requestShortener, - chunkGraph + chunkGraph, + hashFunction: compilation.outputOptions.hashFunction } - ); - }); + ) + ); moduleFilenames = ModuleFilenameHelpers.replaceDuplicates( moduleFilenames, (filename, i, n) => { @@ -148,21 +160,34 @@ class EvalSourceMapDevToolPlugin { } ); sourceMap.sources = moduleFilenames; + if (options.noSources) { + sourceMap.sourcesContent = undefined; + } sourceMap.sourceRoot = options.sourceRoot || ""; - const moduleId = chunkGraph.getModuleId(m); - sourceMap.file = `${moduleId}.js`; + const moduleId = + /** @type {ModuleId} */ + (chunkGraph.getModuleId(m)); + sourceMap.file = + typeof moduleId === "number" ? `${moduleId}.js` : moduleId; - const footer = - this.sourceMapComment.replace( - /\[url\]/g, - `data:application/json;charset=utf-8;base64,${Buffer.from( - JSON.stringify(sourceMap), - "utf8" - ).toString("base64")}` - ) + `\n//# sourceURL=webpack-internal:///${moduleId}\n`; // workaround for chrome bug + const footer = `${this.sourceMapComment.replace( + /\[url\]/g, + `data:application/json;charset=utf-8;base64,${Buffer.from( + JSON.stringify(sourceMap), + "utf8" + ).toString("base64")}` + )}\n//# sourceURL=webpack-internal:///${moduleId}\n`; // workaround for chrome bug return result( - new RawSource(`eval(${JSON.stringify(content + footer)});`) + new RawSource( + `eval(${ + compilation.outputOptions.trustedTypes + ? `${RuntimeGlobals.createScript}(${JSON.stringify( + content + footer + )})` + : JSON.stringify(content + footer) + });` + ) ); } ); @@ -178,6 +203,14 @@ class EvalSourceMapDevToolPlugin { hash.update("EvalSourceMapDevToolPlugin"); hash.update("2"); }); + if (compilation.outputOptions.trustedTypes) { + compilation.hooks.additionalModuleRuntimeRequirements.tap( + "EvalSourceMapDevToolPlugin", + (module, set, context) => { + set.add(RuntimeGlobals.createScript); + } + ); + } } ); } diff --git a/lib/ExportsInfo.js b/lib/ExportsInfo.js index a4b0cbea45c..f55dcf2d92d 100644 --- a/lib/ExportsInfo.js +++ b/lib/ExportsInfo.js @@ -14,6 +14,8 @@ const { forEachRuntime } = require("./util/runtime"); /** @typedef {import("./Module")} Module */ /** @typedef {import("./ModuleGraph")} ModuleGraph */ /** @typedef {import("./ModuleGraphConnection")} ModuleGraphConnection */ +/** @typedef {import("./serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */ +/** @typedef {import("./serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */ /** @typedef {import("./util/Hash")} Hash */ /** @typedef {typeof UsageState.OnlyPropertiesUsed | typeof UsageState.NoInfo | typeof UsageState.Unknown | typeof UsageState.Used} RuntimeUsageStateType */ @@ -44,6 +46,9 @@ class RestoreProvidedData { this.otherTerminalBinding = otherTerminalBinding; } + /** + * @param {ObjectSerializerContext} context context + */ serialize({ write }) { write(this.exports); write(this.otherProvided); @@ -51,6 +56,10 @@ class RestoreProvidedData { write(this.otherTerminalBinding); } + /** + * @param {ObjectDeserializerContext} context context + * @returns {RestoreProvidedData} RestoreProvidedData + */ static deserialize({ read }) { return new RestoreProvidedData(read(), read(), read(), read()); } @@ -62,9 +71,12 @@ makeSerializable( "RestoreProvidedData" ); +/** @typedef {Map} Exports */ +/** @typedef {string | string[] | false} UsedName */ + class ExportsInfo { constructor() { - /** @type {Map} */ + /** @type {Exports} */ this._exports = new Map(); this._otherExportsInfo = new ExportInfo(null); this._sideEffectsOnlyInfo = new ExportInfo("*side effects only*"); @@ -135,20 +147,28 @@ class ExportsInfo { return this._otherExportsInfo; } + /** + * @param {Exports} exports exports + * @private + */ _sortExportsMap(exports) { if (exports.size > 1) { - const entriesInOrder = Array.from(exports.values()); - if ( - entriesInOrder.length !== 2 || - entriesInOrder[0].name > entriesInOrder[1].name - ) { - entriesInOrder.sort((a, b) => { - return a.name < b.name ? -1 : 1; - }); - exports.clear(); - for (const entry of entriesInOrder) { - exports.set(entry.name, entry); - } + const namesInOrder = []; + for (const entry of exports.values()) { + namesInOrder.push(entry.name); + } + namesInOrder.sort(); + let i = 0; + for (const entry of exports.values()) { + const name = namesInOrder[i]; + if (entry.name !== name) break; + i++; + } + for (; i < namesInOrder.length; i++) { + const name = namesInOrder[i]; + const correctEntry = /** @type {ExportInfo} */ (exports.get(name)); + exports.delete(name); + exports.set(name, correctEntry); } } } @@ -158,6 +178,10 @@ class ExportsInfo { this._exportsAreOrdered = true; } + /** + * @param {ExportsInfo | undefined} exportsInfo exports info + * @returns {boolean} result + */ setRedirectNamedTo(exportsInfo) { if (this._redirectTo === exportsInfo) return false; this._redirectTo = exportsInfo; @@ -194,9 +218,6 @@ class ExportsInfo { this._redirectTo.setHasUseInfo(); } else { this._otherExportsInfo.setHasUseInfo(); - if (this._otherExportsInfo.canMangleUse === undefined) { - this._otherExportsInfo.canMangleUse = true; - } } } @@ -247,7 +268,7 @@ class ExportsInfo { getReadOnlyExportInfoRecursive(name) { const exportInfo = this.getReadOnlyExportInfo(name[0]); if (name.length === 1) return exportInfo; - if (!exportInfo.exportsInfo) return undefined; + if (!exportInfo.exportsInfo) return; return exportInfo.exportsInfo.getReadOnlyExportInfoRecursive(name.slice(1)); } @@ -258,7 +279,7 @@ class ExportsInfo { getNestedExportsInfo(name) { if (Array.isArray(name) && name.length > 0) { const info = this.getReadOnlyExportInfo(name[0]); - if (!info.exportsInfo) return undefined; + if (!info.exportsInfo) return; return info.exportsInfo.getNestedExportsInfo(name.slice(1)); } return this; @@ -269,13 +290,15 @@ class ExportsInfo { * @param {Set=} excludeExports list of unaffected exports * @param {any=} targetKey use this as key for the target * @param {ModuleGraphConnection=} targetModule set this module as target + * @param {number=} priority priority * @returns {boolean} true, if this call changed something */ setUnknownExportsProvided( canMangle, excludeExports, targetKey, - targetModule + targetModule, + priority ) { let changed = false; if (excludeExports) { @@ -285,17 +308,22 @@ class ExportsInfo { } } for (const exportInfo of this._exports.values()) { + if (!canMangle && exportInfo.canMangleProvide !== false) { + exportInfo.canMangleProvide = false; + changed = true; + } if (excludeExports && excludeExports.has(exportInfo.name)) continue; if (exportInfo.provided !== true && exportInfo.provided !== null) { exportInfo.provided = null; changed = true; } - if (!canMangle && exportInfo.canMangleProvide !== false) { - exportInfo.canMangleProvide = false; - changed = true; - } if (targetKey) { - exportInfo.setTarget(targetKey, targetModule, [exportInfo.name]); + exportInfo.setTarget( + targetKey, + /** @type {ModuleGraphConnection} */ (targetModule), + [exportInfo.name], + -1 + ); } } if (this._redirectTo !== undefined) { @@ -304,7 +332,8 @@ class ExportsInfo { canMangle, excludeExports, targetKey, - targetModule + targetModule, + priority ) ) { changed = true; @@ -322,7 +351,12 @@ class ExportsInfo { changed = true; } if (targetKey) { - this._otherExportsInfo.setTarget(targetKey, targetModule, undefined); + this._otherExportsInfo.setTarget( + targetKey, + /** @type {ModuleGraphConnection} */ (targetModule), + undefined, + priority + ); } } return changed; @@ -424,10 +458,8 @@ class ExportsInfo { if (this._redirectTo.isUsed(runtime)) { return true; } - } else { - if (this._otherExportsInfo.getUsed(runtime) !== UsageState.Unused) { - return true; - } + } else if (this._otherExportsInfo.getUsed(runtime) !== UsageState.Unused) { + return true; } for (const exportInfo of this._exports.values()) { if (exportInfo.getUsed(runtime) !== UsageState.Unused) { @@ -453,6 +485,7 @@ class ExportsInfo { * @returns {SortableSet | boolean | null} set of used exports, or true (when namespace object is used), or false (when unused), or null (when unknown) */ getUsedExports(runtime) { + // eslint-disable-next-line no-constant-binary-expression if (!this._redirectTo !== undefined) { switch (this._otherExportsInfo.getUsed(runtime)) { case UsageState.NoInfo: @@ -494,13 +527,14 @@ class ExportsInfo { return false; } } - return new SortableSet(array); + return /** @type {SortableSet} */ (new SortableSet(array)); } /** * @returns {null | true | string[]} list of exports when known */ getProvidedExports() { + // eslint-disable-next-line no-constant-binary-expression if (!this._redirectTo !== undefined) { switch (this._otherExportsInfo.provided) { case undefined: @@ -572,7 +606,7 @@ class ExportsInfo { if (info.exportsInfo && name.length > 1) { return info.exportsInfo.isExportProvided(name.slice(1)); } - return info.provided; + return info.provided ? name.length === 1 || undefined : info.provided; } const info = this.getReadOnlyExportInfo(name); return info.provided; @@ -604,13 +638,11 @@ class ExportsInfo { isEquallyUsed(runtimeA, runtimeB) { if (this._redirectTo !== undefined) { if (!this._redirectTo.isEquallyUsed(runtimeA, runtimeB)) return false; - } else { - if ( - this._otherExportsInfo.getUsed(runtimeA) !== - this._otherExportsInfo.getUsed(runtimeB) - ) { - return false; - } + } else if ( + this._otherExportsInfo.getUsed(runtimeA) !== + this._otherExportsInfo.getUsed(runtimeB) + ) { + return false; } if ( this._sideEffectsOnlyInfo.getUsed(runtimeA) !== @@ -633,20 +665,20 @@ class ExportsInfo { getUsed(name, runtime) { if (Array.isArray(name)) { if (name.length === 0) return this.otherExportsInfo.getUsed(runtime); - let info = this.getReadOnlyExportInfo(name[0]); + const info = this.getReadOnlyExportInfo(name[0]); if (info.exportsInfo && name.length > 1) { return info.exportsInfo.getUsed(name.slice(1), runtime); } return info.getUsed(runtime); } - let info = this.getReadOnlyExportInfo(name); + const info = this.getReadOnlyExportInfo(name); return info.getUsed(runtime); } /** * @param {string | string[]} name the export name * @param {RuntimeSpec} runtime check usage for this runtime only - * @returns {string | string[] | false} the used name + * @returns {UsedName} the used name */ getUsedName(name, runtime) { if (Array.isArray(name)) { @@ -655,10 +687,12 @@ class ExportsInfo { if (!this.isUsed(runtime)) return false; return name; } - let info = this.getReadOnlyExportInfo(name[0]); + const info = this.getReadOnlyExportInfo(name[0]); const x = info.getUsedName(name[0], runtime); if (x === false) return false; - const arr = x === name[0] && name.length === 1 ? name : [x]; + const arr = + /** @type {string[]} */ + (x === name[0] && name.length === 1 ? name : [x]); if (name.length === 1) { return arr; } @@ -669,14 +703,12 @@ class ExportsInfo { const nested = info.exportsInfo.getUsedName(name.slice(1), runtime); if (!nested) return false; return arr.concat(nested); - } else { - return arr.concat(name.slice(1)); } - } else { - let info = this.getReadOnlyExportInfo(name); - const usedName = info.getUsedName(name, runtime); - return usedName; + return arr.concat(name.slice(1)); } + const info = this.getReadOnlyExportInfo(name); + const usedName = info.getUsedName(name, runtime); + return usedName; } /** @@ -709,12 +741,15 @@ class ExportsInfo { } } + /** + * @returns {RestoreProvidedData} restore provided data + */ getRestoreProvidedData() { const otherProvided = this._otherExportsInfo.provided; const otherCanMangleProvide = this._otherExportsInfo.canMangleProvide; const otherTerminalBinding = this._otherExportsInfo.terminalBinding; const exports = []; - for (const exportInfo of this._exports.values()) { + for (const exportInfo of this.orderedExports) { if ( exportInfo.provided !== otherProvided || exportInfo.canMangleProvide !== otherCanMangleProvide || @@ -727,7 +762,8 @@ class ExportsInfo { canMangleProvide: exportInfo.canMangleProvide, terminalBinding: exportInfo.terminalBinding, exportsInfo: exportInfo.exportsInfoOwned - ? exportInfo.exportsInfo.getRestoreProvidedData() + ? /** @type {NonNullable} */ + (exportInfo.exportsInfo).getRestoreProvidedData() : undefined }); } @@ -740,13 +776,18 @@ class ExportsInfo { ); } + /** + * @param {{ otherProvided: any, otherCanMangleProvide: any, otherTerminalBinding: any, exports: any }} data data + */ restoreProvided({ otherProvided, otherCanMangleProvide, otherTerminalBinding, exports }) { + let wasEmpty = true; for (const exportInfo of this._exports.values()) { + wasEmpty = false; exportInfo.provided = otherProvided; exportInfo.canMangleProvide = otherCanMangleProvide; exportInfo.terminalBinding = otherTerminalBinding; @@ -764,9 +805,14 @@ class ExportsInfo { exportsInfo.restoreProvided(exp.exportsInfo); } } + if (wasEmpty) this._exportsAreOrdered = true; } } +/** @typedef {{ module: Module, export: string[] }} TargetItemWithoutConnection */ +/** @typedef {{ module: Module, connection: ModuleGraphConnection, export: string[] | undefined }} TargetItem */ +/** @typedef {Map} Target */ + class ExportInfo { /** * @param {string} name the original name of the export @@ -775,16 +821,28 @@ class ExportInfo { constructor(name, initFrom) { /** @type {string} */ this.name = name; - /** @private @type {string | null} */ + /** + * @private + * @type {string | null} + */ this._usedName = initFrom ? initFrom._usedName : null; - /** @private @type {UsageStateType} */ + /** + * @private + * @type {UsageStateType | undefined} + */ this._globalUsed = initFrom ? initFrom._globalUsed : undefined; - /** @private @type {Map} */ + /** + * @private + * @type {Map} + */ this._usedInRuntime = initFrom && initFrom._usedInRuntime ? new Map(initFrom._usedInRuntime) : undefined; - /** @private @type {boolean} */ + /** + * @private + * @type {boolean} + */ this._hasUseInRuntimeInfo = initFrom ? initFrom._hasUseInRuntimeInfo : false; @@ -817,30 +875,25 @@ class ExportInfo { this.canMangleUse = initFrom ? initFrom.canMangleUse : undefined; /** @type {boolean} */ this.exportsInfoOwned = false; - /** @type {ExportsInfo=} */ + /** @type {ExportsInfo | undefined} */ this.exportsInfo = undefined; - /** @type {Map=} */ + /** @type {Target | undefined} */ this._target = undefined; if (initFrom && initFrom._target) { this._target = new Map(); for (const [key, value] of initFrom._target) { - this._target.set( - key, - value ? { connection: value.connection, export: [name] } : null - ); + this._target.set(key, { + connection: value.connection, + export: value.export || [name], + priority: value.priority + }); } } + /** @type {Target | undefined} */ + this._maxTarget = undefined; } // TODO webpack 5 remove - /** @private */ - get used() { - throw new Error("REMOVED"); - } - /** @private */ - get usedName() { - throw new Error("REMOVED"); - } /** * @private * @param {*} v v @@ -848,6 +901,14 @@ class ExportInfo { set used(v) { throw new Error("REMOVED"); } + + // TODO webpack 5 remove + /** @private */ + get used() { + throw new Error("REMOVED"); + } + + // TODO webpack 5 remove /** * @private * @param {*} v v @@ -856,6 +917,12 @@ class ExportInfo { throw new Error("REMOVED"); } + // TODO webpack 5 remove + /** @private */ + get usedName() { + throw new Error("REMOVED"); + } + get canMangle() { switch (this.canMangleProvide) { case undefined: @@ -923,7 +990,8 @@ class ExportInfo { this.canMangleUse = true; } if (this.exportsInfoOwned) { - this.exportsInfo.setHasUseInfo(); + /** @type {ExportsInfo} */ + (this.exportsInfo).setHasUseInfo(); } } @@ -938,25 +1006,26 @@ class ExportInfo { if (this._globalUsed === undefined) { this._globalUsed = newValue; return true; - } else { - if (this._globalUsed !== newValue && condition(this._globalUsed)) { - this._globalUsed = newValue; - return true; - } + } + if (this._globalUsed !== newValue && condition(this._globalUsed)) { + this._globalUsed = newValue; + return true; } } else if (this._usedInRuntime === undefined) { if (newValue !== UsageState.Unused && condition(UsageState.Unused)) { this._usedInRuntime = new Map(); forEachRuntime(runtime, runtime => - this._usedInRuntime.set(runtime, newValue) + this._usedInRuntime.set(/** @type {string} */ (runtime), newValue) ); return true; } } else { let changed = false; - forEachRuntime(runtime, runtime => { - /** @type {UsageStateType} */ - let oldValue = this._usedInRuntime.get(runtime); + forEachRuntime(runtime, _runtime => { + const runtime = /** @type {string} */ (_runtime); + let oldValue = + /** @type {UsageStateType} */ + (this._usedInRuntime.get(runtime)); if (oldValue === undefined) oldValue = UsageState.Unused; if (newValue !== oldValue && condition(oldValue)) { if (newValue === UsageState.Unused) { @@ -990,15 +1059,17 @@ class ExportInfo { if (newValue !== UsageState.Unused) { this._usedInRuntime = new Map(); forEachRuntime(runtime, runtime => - this._usedInRuntime.set(runtime, newValue) + this._usedInRuntime.set(/** @type {string} */ (runtime), newValue) ); return true; } } else { let changed = false; - forEachRuntime(runtime, runtime => { - /** @type {UsageStateType} */ - let oldValue = this._usedInRuntime.get(runtime); + forEachRuntime(runtime, _runtime => { + const runtime = /** @type {string} */ (_runtime); + let oldValue = + /** @type {UsageStateType} */ + (this._usedInRuntime.get(runtime)); if (oldValue === undefined) oldValue = UsageState.Unused; if (newValue !== oldValue) { if (newValue === UsageState.Unused) { @@ -1023,46 +1094,53 @@ class ExportInfo { */ unsetTarget(key) { if (!this._target) return false; - return this._target.delete(key); + if (this._target.delete(key)) { + this._maxTarget = undefined; + return true; + } + return false; } /** * @param {any} key the key - * @param {ModuleGraphConnection=} connection the target module if a single one - * @param {string[]=} exportName the exported name + * @param {ModuleGraphConnection} connection the target module if a single one + * @param {(string[] | null)=} exportName the exported name + * @param {number=} priority priority * @returns {boolean} true, if something has changed */ - setTarget(key, connection, exportName) { + setTarget(key, connection, exportName, priority = 0) { if (exportName) exportName = [...exportName]; if (!this._target) { this._target = new Map(); - this._target.set( - key, - connection ? { connection, export: exportName } : null - ); + this._target.set(key, { + connection, + export: /** @type {string[]} */ (exportName), + priority + }); return true; } const oldTarget = this._target.get(key); if (!oldTarget) { if (oldTarget === null && !connection) return false; - this._target.set( - key, - connection ? { connection, export: exportName } : null - ); - return true; - } - if (!connection) { - this._target.set(key, null); + this._target.set(key, { + connection, + export: /** @type {string[]} */ (exportName), + priority + }); + this._maxTarget = undefined; return true; } if ( oldTarget.connection !== connection || + oldTarget.priority !== priority || (exportName ? !oldTarget.export || !equals(oldTarget.export, exportName) : oldTarget.export) ) { oldTarget.connection = connection; - oldTarget.export = exportName; + oldTarget.export = /** @type {string[]} */ (exportName); + oldTarget.priority = priority; + this._maxTarget = undefined; return true; } return false; @@ -1090,20 +1168,20 @@ class ExportInfo { if (max < value) max = value; } return max; - } else { - /** @type {UsageStateType} */ - let max = UsageState.Unused; - for (const item of runtime) { - const value = this._usedInRuntime.get(item); - if (value !== undefined) { - if (value === UsageState.Used) { - return UsageState.Used; - } - if (max < value) max = value; + } + + /** @type {UsageStateType} */ + let max = UsageState.Unused; + for (const item of runtime) { + const value = this._usedInRuntime.get(item); + if (value !== undefined) { + if (value === UsageState.Used) { + return UsageState.Used; } + if (max < value) max = value; } - return max; } + return max; } /** @@ -1122,19 +1200,18 @@ class ExportInfo { if (!this._usedInRuntime.has(runtime)) { return false; } - } else if (runtime !== undefined) { - if ( - Array.from(runtime).every( - runtime => !this._usedInRuntime.has(runtime) - ) - ) { - return false; - } + } else if ( + runtime !== undefined && + Array.from(runtime).every( + runtime => !this._usedInRuntime.has(runtime) + ) + ) { + return false; } } } if (this._usedName !== null) return this._usedName; - return this.name || fallbackName; + return /** @type {string | false} */ (this.name || fallbackName); } /** @@ -1155,13 +1232,13 @@ class ExportInfo { /** * @param {ModuleGraph} moduleGraph the module graph - * @param {function({ module: Module, export: string[] | undefined }): boolean} resolveTargetFilter filter function to further resolve target + * @param {function(TargetItem): boolean} resolveTargetFilter filter function to further resolve target * @returns {ExportInfo | ExportsInfo | undefined} the terminal binding export(s) info if known */ getTerminalBinding(moduleGraph, resolveTargetFilter = RETURNS_TRUE) { if (this.terminalBinding) return this; const target = this.getTarget(moduleGraph, resolveTargetFilter); - if (!target) return undefined; + if (!target) return; const exportsInfo = moduleGraph.getExportsInfo(target.module); if (!target.export) return exportsInfo; return exportsInfo.getReadOnlyExportInfoRecursive(target.export); @@ -1171,10 +1248,34 @@ class ExportInfo { return !this.terminalBinding && this._target && this._target.size > 0; } + _getMaxTarget() { + if (this._maxTarget !== undefined) return this._maxTarget; + if (/** @type {Target} */ (this._target).size <= 1) + return (this._maxTarget = this._target); + let maxPriority = -Infinity; + let minPriority = Infinity; + for (const { priority } of /** @type {Target} */ (this._target).values()) { + if (maxPriority < priority) maxPriority = priority; + if (minPriority > priority) minPriority = priority; + } + // This should be very common + if (maxPriority === minPriority) return (this._maxTarget = this._target); + + // This is an edge case + const map = new Map(); + for (const [key, value] of /** @type {Target} */ (this._target)) { + if (maxPriority === value.priority) { + map.set(key, value); + } + } + this._maxTarget = map; + return map; + } + /** * @param {ModuleGraph} moduleGraph the module graph * @param {function(Module): boolean} validTargetModuleFilter a valid target module - * @returns {{ module: Module, export: string[] | undefined } | undefined | false} the target, undefined when there is no target, false when no target is valid + * @returns {TargetItemWithoutConnection | null | undefined | false} the target, undefined when there is no target, false when no target is valid */ findTarget(moduleGraph, validTargetModuleFilter) { return this._findTarget(moduleGraph, validTargetModuleFilter, new Set()); @@ -1183,14 +1284,16 @@ class ExportInfo { /** * @param {ModuleGraph} moduleGraph the module graph * @param {function(Module): boolean} validTargetModuleFilter a valid target module - * @param {Set | undefined} alreadyVisited set of already visited export info to avoid circular references - * @returns {{ module: Module, export: string[] | undefined } | undefined | false} the target, undefined when there is no target, false when no target is valid + * @param {Set} alreadyVisited set of already visited export info to avoid circular references + * @returns {TargetItemWithoutConnection | null | undefined | false} the target, undefined when there is no target, false when no target is valid */ _findTarget(moduleGraph, validTargetModuleFilter, alreadyVisited) { - if (!this._target || this._target.size === 0) return undefined; - let rawTarget = this._target.values().next().value; - if (!rawTarget) return undefined; - /** @type {{ module: Module, export: string[] | undefined }} */ + if (!this._target || this._target.size === 0) return; + const rawTarget = + /** @type {Target} */ + (this._getMaxTarget()).values().next().value; + if (!rawTarget) return; + /** @type {TargetItemWithoutConnection} */ let target = { module: rawTarget.connection.module, export: rawTarget.export @@ -1221,26 +1324,26 @@ class ExportInfo { /** * @param {ModuleGraph} moduleGraph the module graph - * @param {function({ module: Module, export: string[] | undefined }): boolean} resolveTargetFilter filter function to further resolve target - * @returns {{ module: Module, export: string[] | undefined } | undefined} the target + * @param {function(TargetItem): boolean} resolveTargetFilter filter function to further resolve target + * @returns {TargetItem | undefined} the target */ getTarget(moduleGraph, resolveTargetFilter = RETURNS_TRUE) { const result = this._getTarget(moduleGraph, resolveTargetFilter, undefined); - if (result === CIRCULAR) return undefined; + if (result === CIRCULAR) return; return result; } /** * @param {ModuleGraph} moduleGraph the module graph - * @param {function({ module: Module, connection: ModuleGraphConnection, export: string[] | undefined }): boolean} resolveTargetFilter filter function to further resolve target + * @param {function(TargetItem): boolean} resolveTargetFilter filter function to further resolve target * @param {Set | undefined} alreadyVisited set of already visited export info to avoid circular references - * @returns {{ module: Module, connection: ModuleGraphConnection, export: string[] | undefined } | CIRCULAR | undefined} the target + * @returns {TargetItem | CIRCULAR | undefined} the target */ _getTarget(moduleGraph, resolveTargetFilter, alreadyVisited) { /** - * @param {{ connection: ModuleGraphConnection, export: string[] | undefined } | null} inputTarget unresolved target + * @param {TargetItem | null} inputTarget unresolved target * @param {Set} alreadyVisited set of already visited export info to avoid circular references - * @returns {{ module: Module, connection: ModuleGraphConnection, export: string[] | undefined } | CIRCULAR | null} resolved target + * @returns {TargetItem | CIRCULAR | null} resolved target */ const resolveTarget = (inputTarget, alreadyVisited) => { if (!inputTarget) return null; @@ -1251,7 +1354,7 @@ class ExportInfo { export: undefined }; } - /** @type {{ module: Module, connection: ModuleGraphConnection, export: string[] | undefined }} */ + /** @type {TargetItem} */ let target = { module: inputTarget.connection.module, connection: inputTarget.connection, @@ -1261,7 +1364,10 @@ class ExportInfo { let alreadyVisitedOwned = false; for (;;) { const exportsInfo = moduleGraph.getExportsInfo(target.module); - const exportInfo = exportsInfo.getExportInfo(target.export[0]); + const exportInfo = exportsInfo.getExportInfo( + /** @type {NonNullable} */ + (target.export)[0] + ); if (!exportInfo) return target; if (alreadyVisited.has(exportInfo)) return CIRCULAR; const newTarget = exportInfo._getTarget( @@ -1271,7 +1377,10 @@ class ExportInfo { ); if (newTarget === CIRCULAR) return CIRCULAR; if (!newTarget) return target; - if (target.export.length === 1) { + if ( + /** @type {NonNullable} */ + (target.export).length === 1 + ) { target = newTarget; if (!target.export) return target; } else { @@ -1279,8 +1388,12 @@ class ExportInfo { module: newTarget.module, connection: newTarget.connection, export: newTarget.export - ? newTarget.export.concat(target.export.slice(1)) - : target.export.slice(1) + ? newTarget.export.concat( + /** @type {NonNullable} */ + (target.export).slice(1) + ) + : /** @type {NonNullable} */ + (target.export).slice(1) }; } if (!resolveTargetFilter(target)) return target; @@ -1292,22 +1405,26 @@ class ExportInfo { } }; - if (!this._target || this._target.size === 0) return undefined; + if (!this._target || this._target.size === 0) return; if (alreadyVisited && alreadyVisited.has(this)) return CIRCULAR; const newAlreadyVisited = new Set(alreadyVisited); newAlreadyVisited.add(this); - const values = this._target.values(); + const values = /** @type {Target} */ (this._getMaxTarget()).values(); const target = resolveTarget(values.next().value, newAlreadyVisited); if (target === CIRCULAR) return CIRCULAR; - if (target === null) return undefined; + if (target === null) return; let result = values.next(); while (!result.done) { const t = resolveTarget(result.value, newAlreadyVisited); if (t === CIRCULAR) return CIRCULAR; - if (t === null) return undefined; - if (t.module !== target.module) return undefined; - if (!t.export !== !target.export) return undefined; - if (target.export && !equals(t.export, target.export)) return undefined; + if (t === null) return; + if (t.module !== target.module) return; + if (!t.export !== !target.export) return; + if ( + target.export && + !equals(/** @type {ArrayLike} */ (t.export), target.export) + ) + return; result = values.next(); } return target; @@ -1316,33 +1433,42 @@ class ExportInfo { /** * Move the target forward as long resolveTargetFilter is fulfilled * @param {ModuleGraph} moduleGraph the module graph - * @param {function({ module: Module, export: string[] | undefined }): boolean} resolveTargetFilter filter function to further resolve target - * @param {function({ module: Module, export: string[] | undefined }): ModuleGraphConnection=} updateOriginalConnection updates the original connection instead of using the target connection - * @returns {{ module: Module, export: string[] | undefined } | undefined} the resolved target when moved + * @param {function(TargetItem): boolean} resolveTargetFilter filter function to further resolve target + * @param {function(TargetItem): ModuleGraphConnection=} updateOriginalConnection updates the original connection instead of using the target connection + * @returns {TargetItem | undefined} the resolved target when moved */ moveTarget(moduleGraph, resolveTargetFilter, updateOriginalConnection) { const target = this._getTarget(moduleGraph, resolveTargetFilter, undefined); - if (target === CIRCULAR) return undefined; - if (!target) return undefined; - const originalTarget = this._target.values().next().value; + if (target === CIRCULAR) return; + if (!target) return; + const originalTarget = + /** @type {Target} */ + (this._getMaxTarget()).values().next().value; if ( originalTarget.connection === target.connection && originalTarget.export === target.export ) { - return undefined; + return; } - this._target.clear(); - this._target.set(undefined, { + /** @type {Target} */ + (this._target).clear(); + /** @type {Target} */ + (this._target).set(undefined, { connection: updateOriginalConnection ? updateOriginalConnection(target) : target.connection, - export: target.export + export: /** @type {NonNullable} */ (target.export), + priority: 0 }); return target; } + /** + * @returns {ExportsInfo} an exports info + */ createNestedExportsInfo() { - if (this.exportsInfoOwned) return this.exportsInfo; + if (this.exportsInfoOwned) + return /** @type {ExportsInfo} */ (this.exportsInfo); this.exportsInfoOwned = true; const oldExportsInfo = this.exportsInfo; this.exportsInfo = new ExportsInfo(); @@ -1357,6 +1483,11 @@ class ExportInfo { return this.exportsInfo; } + /** + * @param {ExportInfo} baseInfo base info + * @param {RuntimeSpec} runtime runtime + * @returns {boolean} true when has info, otherwise false + */ hasInfo(baseInfo, runtime) { return ( (this._usedName && this._usedName !== this.name) || @@ -1366,15 +1497,26 @@ class ExportInfo { ); } + /** + * @param {Hash} hash the hash + * @param {RuntimeSpec} runtime the runtime + * @returns {void} + */ updateHash(hash, runtime) { this._updateHash(hash, runtime, new Set()); } + /** + * @param {Hash} hash the hash + * @param {RuntimeSpec} runtime the runtime + * @param {Set} alreadyVisitedExportsInfo for circular references + */ _updateHash(hash, runtime, alreadyVisitedExportsInfo) { - hash.update(`${this._usedName || this.name}`); - hash.update(`${this.getUsed(runtime)}`); - hash.update(`${this.provided}`); - hash.update(`${this.terminalBinding}`); + hash.update( + `${this._usedName || this.name}${this.getUsed(runtime)}${this.provided}${ + this.terminalBinding + }` + ); if (this.exportsInfo && !alreadyVisitedExportsInfo.has(this.exportsInfo)) { this.exportsInfo._updateHash(hash, runtime, alreadyVisitedExportsInfo); } @@ -1402,6 +1544,7 @@ class ExportInfo { if (list !== undefined) list.push(runtime); else map.set(used, [runtime]); } + // eslint-disable-next-line array-callback-return const specificInfo = Array.from(map, ([used, runtimes]) => { switch (used) { case UsageState.NoInfo: diff --git a/lib/ExportsInfoApiPlugin.js b/lib/ExportsInfoApiPlugin.js index 76827ef8475..faf4594bbd0 100644 --- a/lib/ExportsInfoApiPlugin.js +++ b/lib/ExportsInfoApiPlugin.js @@ -5,11 +5,20 @@ "use strict"; +const { + JAVASCRIPT_MODULE_TYPE_AUTO, + JAVASCRIPT_MODULE_TYPE_DYNAMIC, + JAVASCRIPT_MODULE_TYPE_ESM +} = require("./ModuleTypeConstants"); const ConstDependency = require("./dependencies/ConstDependency"); const ExportsInfoDependency = require("./dependencies/ExportsInfoDependency"); /** @typedef {import("./Compiler")} Compiler */ +/** @typedef {import("./Dependency").DependencyLocation} DependencyLocation */ /** @typedef {import("./javascript/JavascriptParser")} JavascriptParser */ +/** @typedef {import("./javascript/JavascriptParser").Range} Range */ + +const PLUGIN_NAME = "ExportsInfoApiPlugin"; class ExportsInfoApiPlugin { /** @@ -19,7 +28,7 @@ class ExportsInfoApiPlugin { */ apply(compiler) { compiler.hooks.compilation.tap( - "ExportsInfoApiPlugin", + PLUGIN_NAME, (compilation, { normalModuleFactory }) => { compilation.dependencyTemplates.set( ExportsInfoDependency, @@ -32,37 +41,44 @@ class ExportsInfoApiPlugin { const handler = parser => { parser.hooks.expressionMemberChain .for("__webpack_exports_info__") - .tap("ExportsInfoApiPlugin", (expr, members) => { + .tap(PLUGIN_NAME, (expr, members) => { const dep = members.length >= 2 ? new ExportsInfoDependency( - expr.range, + /** @type {Range} */ (expr.range), members.slice(0, -1), members[members.length - 1] - ) - : new ExportsInfoDependency(expr.range, null, members[0]); - dep.loc = expr.loc; + ) + : new ExportsInfoDependency( + /** @type {Range} */ (expr.range), + null, + members[0] + ); + dep.loc = /** @type {DependencyLocation} */ (expr.loc); parser.state.module.addDependency(dep); return true; }); parser.hooks.expression .for("__webpack_exports_info__") - .tap("ExportsInfoApiPlugin", expr => { - const dep = new ConstDependency("true", expr.range); - dep.loc = expr.loc; + .tap(PLUGIN_NAME, expr => { + const dep = new ConstDependency( + "true", + /** @type {Range} */ (expr.range) + ); + dep.loc = /** @type {DependencyLocation} */ (expr.loc); parser.state.module.addPresentationalDependency(dep); return true; }); }; normalModuleFactory.hooks.parser - .for("javascript/auto") - .tap("ExportsInfoApiPlugin", handler); + .for(JAVASCRIPT_MODULE_TYPE_AUTO) + .tap(PLUGIN_NAME, handler); normalModuleFactory.hooks.parser - .for("javascript/dynamic") - .tap("ExportsInfoApiPlugin", handler); + .for(JAVASCRIPT_MODULE_TYPE_DYNAMIC) + .tap(PLUGIN_NAME, handler); normalModuleFactory.hooks.parser - .for("javascript/esm") - .tap("ExportsInfoApiPlugin", handler); + .for(JAVASCRIPT_MODULE_TYPE_ESM) + .tap(PLUGIN_NAME, handler); } ); } diff --git a/lib/ExternalModule.js b/lib/ExternalModule.js index e4deb807bc0..cf22c0ca5a7 100644 --- a/lib/ExternalModule.js +++ b/lib/ExternalModule.js @@ -7,13 +7,19 @@ const { OriginalSource, RawSource } = require("webpack-sources"); const ConcatenationScope = require("./ConcatenationScope"); +const EnvironmentNotSupportAsyncWarning = require("./EnvironmentNotSupportAsyncWarning"); +const { UsageState } = require("./ExportsInfo"); +const InitFragment = require("./InitFragment"); const Module = require("./Module"); +const { JAVASCRIPT_MODULE_TYPE_DYNAMIC } = require("./ModuleTypeConstants"); const RuntimeGlobals = require("./RuntimeGlobals"); const Template = require("./Template"); const StaticExportsDependency = require("./dependencies/StaticExportsDependency"); +const createHash = require("./util/createHash"); const extractUrlAndGlobal = require("./util/extractUrlAndGlobal"); const makeSerializable = require("./util/makeSerializable"); const propertyAccess = require("./util/propertyAccess"); +const { register } = require("./util/serialization"); /** @typedef {import("webpack-sources").Source} Source */ /** @typedef {import("../declarations/WebpackOptions").WebpackOptionsNormalized} WebpackOptions */ @@ -22,25 +28,54 @@ const propertyAccess = require("./util/propertyAccess"); /** @typedef {import("./Compilation")} Compilation */ /** @typedef {import("./Dependency").UpdateHashContext} UpdateHashContext */ /** @typedef {import("./DependencyTemplates")} DependencyTemplates */ +/** @typedef {import("./ExportsInfo")} ExportsInfo */ +/** @typedef {import("./Generator").GenerateContext} GenerateContext */ +/** @typedef {import("./Module").BuildInfo} BuildInfo */ /** @typedef {import("./Module").CodeGenerationContext} CodeGenerationContext */ /** @typedef {import("./Module").CodeGenerationResult} CodeGenerationResult */ /** @typedef {import("./Module").ConcatenationBailoutReasonContext} ConcatenationBailoutReasonContext */ /** @typedef {import("./Module").LibIdentOptions} LibIdentOptions */ /** @typedef {import("./Module").NeedBuildContext} NeedBuildContext */ +/** @typedef {import("./Module").ReadOnlyRuntimeRequirements} ReadOnlyRuntimeRequirements */ +/** @typedef {import("./Module").SourceTypes} SourceTypes */ +/** @typedef {import("./ModuleGraph")} ModuleGraph */ +/** @typedef {import("./NormalModuleFactory")} NormalModuleFactory */ /** @typedef {import("./RequestShortener")} RequestShortener */ /** @typedef {import("./ResolverFactory").ResolverWithOptions} ResolverWithOptions */ /** @typedef {import("./RuntimeTemplate")} RuntimeTemplate */ /** @typedef {import("./WebpackError")} WebpackError */ +/** @typedef {import("./javascript/JavascriptModulesPlugin").ChunkRenderContext} ChunkRenderContext */ +/** @typedef {import("./javascript/JavascriptParser").ImportAttributes} ImportAttributes */ +/** @typedef {import("./serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */ +/** @typedef {import("./serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */ /** @typedef {import("./util/Hash")} Hash */ +/** @typedef {typeof import("./util/Hash")} HashConstructor */ /** @typedef {import("./util/fs").InputFileSystem} InputFileSystem */ +/** @typedef {import("./util/runtime").RuntimeSpec} RuntimeSpec */ + +/** @typedef {{ attributes?: ImportAttributes, externalType: "import" | "module" | undefined }} ImportDependencyMeta */ +/** @typedef {{ layer?: string, supports?: string, media?: string }} CssImportDependencyMeta */ + +/** @typedef {ImportDependencyMeta | CssImportDependencyMeta} DependencyMeta */ /** - * @typedef {Object} SourceData + * @typedef {object} SourceData * @property {boolean=} iife * @property {string=} init * @property {string} expression + * @property {InitFragment[]=} chunkInitFragments + * @property {ReadOnlyRuntimeRequirements=} runtimeRequirements */ +const TYPES = new Set(["javascript"]); +const CSS_TYPES = new Set(["css-import"]); +const RUNTIME_REQUIREMENTS = new Set([RuntimeGlobals.module]); +const RUNTIME_REQUIREMENTS_FOR_SCRIPT = new Set([RuntimeGlobals.loadScript]); +const RUNTIME_REQUIREMENTS_FOR_MODULE = new Set([ + RuntimeGlobals.definePropertyGetters +]); +const EMPTY_RUNTIME_REQUIREMENTS = new Set([]); + /** * @param {string|string[]} variableName the variable name or path * @param {string} type the module system @@ -67,7 +102,7 @@ const getSourceForGlobalVariableExternal = (variableName, type) => { const getSourceForCommonJsExternal = moduleAndSpecifiers => { if (!Array.isArray(moduleAndSpecifiers)) { return { - expression: `require(${JSON.stringify(moduleAndSpecifiers)});` + expression: `require(${JSON.stringify(moduleAndSpecifiers)})` }; } const moduleName = moduleAndSpecifiers[0]; @@ -75,43 +110,271 @@ const getSourceForCommonJsExternal = moduleAndSpecifiers => { expression: `require(${JSON.stringify(moduleName)})${propertyAccess( moduleAndSpecifiers, 1 - )};` + )}` + }; +}; + +/** + * @param {string|string[]} moduleAndSpecifiers the module request + * @param {string} importMetaName import.meta name + * @param {boolean} needPrefix need to use `node:` prefix for `module` import + * @returns {SourceData} the generated source + */ +const getSourceForCommonJsExternalInNodeModule = ( + moduleAndSpecifiers, + importMetaName, + needPrefix +) => { + const chunkInitFragments = [ + new InitFragment( + `import { createRequire as __WEBPACK_EXTERNAL_createRequire } from "${ + needPrefix ? "node:" : "" + }module";\n`, + InitFragment.STAGE_HARMONY_IMPORTS, + 0, + "external module node-commonjs" + ) + ]; + if (!Array.isArray(moduleAndSpecifiers)) { + return { + chunkInitFragments, + expression: `__WEBPACK_EXTERNAL_createRequire(${importMetaName}.url)(${JSON.stringify( + moduleAndSpecifiers + )})` + }; + } + const moduleName = moduleAndSpecifiers[0]; + return { + chunkInitFragments, + expression: `__WEBPACK_EXTERNAL_createRequire(${importMetaName}.url)(${JSON.stringify( + moduleName + )})${propertyAccess(moduleAndSpecifiers, 1)}` }; }; /** * @param {string|string[]} moduleAndSpecifiers the module request * @param {RuntimeTemplate} runtimeTemplate the runtime template + * @param {ImportDependencyMeta=} dependencyMeta the dependency meta * @returns {SourceData} the generated source */ -const getSourceForImportExternal = (moduleAndSpecifiers, runtimeTemplate) => { +const getSourceForImportExternal = ( + moduleAndSpecifiers, + runtimeTemplate, + dependencyMeta +) => { const importName = runtimeTemplate.outputOptions.importFunctionName; - if (!runtimeTemplate.supportsDynamicImport() && importName === "import") { + if ( + !runtimeTemplate.supportsDynamicImport() && + (importName === "import" || importName === "module-import") + ) { throw new Error( "The target environment doesn't support 'import()' so it's not possible to use external type 'import'" ); } + const attributes = + dependencyMeta && dependencyMeta.attributes + ? dependencyMeta.attributes._isLegacyAssert + ? `, { assert: ${JSON.stringify( + dependencyMeta.attributes, + importAssertionReplacer + )} }` + : `, { with: ${JSON.stringify(dependencyMeta.attributes)} }` + : ""; if (!Array.isArray(moduleAndSpecifiers)) { return { - expression: `${importName}(${JSON.stringify(moduleAndSpecifiers)});` + expression: `${importName}(${JSON.stringify( + moduleAndSpecifiers + )}${attributes});` }; } if (moduleAndSpecifiers.length === 1) { return { - expression: `${importName}(${JSON.stringify(moduleAndSpecifiers[0])});` + expression: `${importName}(${JSON.stringify( + moduleAndSpecifiers[0] + )}${attributes});` }; } const moduleName = moduleAndSpecifiers[0]; return { expression: `${importName}(${JSON.stringify( moduleName - )}).then(${runtimeTemplate.returningFunction( + )}${attributes}).then(${runtimeTemplate.returningFunction( `module${propertyAccess(moduleAndSpecifiers, 1)}`, "module" )});` }; }; +/** + * @param {string} key key + * @param {any | undefined} value value + * @returns {undefined | string} replaced value + */ +const importAssertionReplacer = (key, value) => { + if (key === "_isLegacyAssert") { + return; + } + + return value; +}; + +/** + * @extends {InitFragment} + */ +class ModuleExternalInitFragment extends InitFragment { + /** + * @param {string} request import source + * @param {string=} ident recomputed ident + * @param {ImportDependencyMeta=} dependencyMeta the dependency meta + * @param {string | HashConstructor=} hashFunction the hash function to use + */ + constructor(request, ident, dependencyMeta, hashFunction = "md4") { + if (ident === undefined) { + ident = Template.toIdentifier(request); + if (ident !== request) { + ident += `_${createHash(hashFunction) + .update(request) + .digest("hex") + .slice(0, 8)}`; + } + } + const identifier = `__WEBPACK_EXTERNAL_MODULE_${ident}__`; + super( + `import * as ${identifier} from ${JSON.stringify(request)}${ + dependencyMeta && dependencyMeta.attributes + ? dependencyMeta.attributes._isLegacyAssert + ? ` assert ${JSON.stringify( + dependencyMeta.attributes, + importAssertionReplacer + )}` + : ` with ${JSON.stringify(dependencyMeta.attributes)}` + : "" + };\n`, + InitFragment.STAGE_HARMONY_IMPORTS, + 0, + `external module import ${ident}` + ); + this._ident = ident; + this._request = request; + this._dependencyMeta = request; + this._identifier = identifier; + } + + getNamespaceIdentifier() { + return this._identifier; + } +} + +register( + ModuleExternalInitFragment, + "webpack/lib/ExternalModule", + "ModuleExternalInitFragment", + { + serialize(obj, { write }) { + write(obj._request); + write(obj._ident); + write(obj._dependencyMeta); + }, + deserialize({ read }) { + return new ModuleExternalInitFragment(read(), read(), read()); + } + } +); + +/** + * @param {string} input input + * @param {ExportsInfo} exportsInfo the exports info + * @param {RuntimeSpec=} runtime the runtime + * @param {RuntimeTemplate=} runtimeTemplate the runtime template + * @returns {string | undefined} the module remapping + */ +const generateModuleRemapping = ( + input, + exportsInfo, + runtime, + runtimeTemplate +) => { + if (exportsInfo.otherExportsInfo.getUsed(runtime) === UsageState.Unused) { + const properties = []; + for (const exportInfo of exportsInfo.orderedExports) { + const used = exportInfo.getUsedName(exportInfo.name, runtime); + if (!used) continue; + const nestedInfo = exportInfo.getNestedExportsInfo(); + if (nestedInfo) { + const nestedExpr = generateModuleRemapping( + `${input}${propertyAccess([exportInfo.name])}`, + nestedInfo + ); + if (nestedExpr) { + properties.push(`[${JSON.stringify(used)}]: y(${nestedExpr})`); + continue; + } + } + properties.push( + `[${JSON.stringify(used)}]: ${ + /** @type {RuntimeTemplate} */ (runtimeTemplate).returningFunction( + `${input}${propertyAccess([exportInfo.name])}` + ) + }` + ); + } + return `x({ ${properties.join(", ")} })`; + } +}; + +/** + * @param {string|string[]} moduleAndSpecifiers the module request + * @param {ExportsInfo} exportsInfo exports info of this module + * @param {RuntimeSpec} runtime the runtime + * @param {RuntimeTemplate} runtimeTemplate the runtime template + * @param {ImportDependencyMeta} dependencyMeta the dependency meta + * @returns {SourceData} the generated source + */ +const getSourceForModuleExternal = ( + moduleAndSpecifiers, + exportsInfo, + runtime, + runtimeTemplate, + dependencyMeta +) => { + if (!Array.isArray(moduleAndSpecifiers)) + moduleAndSpecifiers = [moduleAndSpecifiers]; + const initFragment = new ModuleExternalInitFragment( + moduleAndSpecifiers[0], + undefined, + dependencyMeta, + runtimeTemplate.outputOptions.hashFunction + ); + const baseAccess = `${initFragment.getNamespaceIdentifier()}${propertyAccess( + moduleAndSpecifiers, + 1 + )}`; + const moduleRemapping = generateModuleRemapping( + baseAccess, + exportsInfo, + runtime, + runtimeTemplate + ); + const expression = moduleRemapping || baseAccess; + return { + expression, + init: moduleRemapping + ? `var x = ${runtimeTemplate.basicFunction( + "y", + `var x = {}; ${RuntimeGlobals.definePropertyGetters}(x, y); return x` + )} \nvar y = ${runtimeTemplate.returningFunction( + runtimeTemplate.returningFunction("x"), + "x" + )}` + : undefined, + runtimeRequirements: moduleRemapping + ? RUNTIME_REQUIREMENTS_FOR_MODULE + : undefined, + chunkInitFragments: [initFragment] + }; +}; + /** * @param {string|string[]} urlAndGlobal the script request * @param {RuntimeTemplate} runtimeTemplate the runtime template @@ -144,7 +407,8 @@ const getSourceForScriptExternal = (urlAndGlobal, runtimeTemplate) => { ] )}).then(${runtimeTemplate.returningFunction( `${globalName}${propertyAccess(urlAndGlobal, 2)}` - )})` + )})`, + runtimeRequirements: RUNTIME_REQUIREMENTS_FOR_SCRIPT }; }; @@ -154,11 +418,10 @@ const getSourceForScriptExternal = (urlAndGlobal, runtimeTemplate) => { * @param {RuntimeTemplate} runtimeTemplate the runtime template * @returns {string} the generated source */ -const checkExternalVariable = (variableName, request, runtimeTemplate) => { - return `if(typeof ${variableName} === 'undefined') { ${runtimeTemplate.throwMissingModuleErrorBlock( +const checkExternalVariable = (variableName, request, runtimeTemplate) => + `if(typeof ${variableName} === 'undefined') { ${runtimeTemplate.throwMissingModuleErrorBlock( { request } )} }\n`; -}; /** * @param {string|number} id the module id @@ -182,7 +445,7 @@ const getSourceForAmdOrUmdExternal = ( externalVariable, Array.isArray(request) ? request.join(".") : request, runtimeTemplate - ) + ) : undefined, expression: externalVariable }; @@ -210,17 +473,17 @@ const getSourceForDefaultCase = (optional, request, runtimeTemplate) => { }; }; -const TYPES = new Set(["javascript"]); -const RUNTIME_REQUIREMENTS = new Set([RuntimeGlobals.module]); -const RUNTIME_REQUIREMENTS_FOR_SCRIPT = new Set([ - RuntimeGlobals.module, - RuntimeGlobals.loadScript -]); -const RUNTIME_REQUIREMENTS_CONCATENATED = new Set([]); +/** @typedef {Record} RequestRecord */ class ExternalModule extends Module { - constructor(request, type, userRequest) { - super("javascript/dynamic", null); + /** + * @param {string | string[] | RequestRecord} request request + * @param {string} type type + * @param {string} userRequest user request + * @param {DependencyMeta=} dependencyMeta dependency meta + */ + constructor(request, type, userRequest, dependencyMeta) { + super(JAVASCRIPT_MODULE_TYPE_DYNAMIC, null); // Info from Factory /** @type {string | string[] | Record} */ @@ -229,13 +492,15 @@ class ExternalModule extends Module { this.externalType = type; /** @type {string} */ this.userRequest = userRequest; + /** @type {DependencyMeta=} */ + this.dependencyMeta = dependencyMeta; } /** - * @returns {Set} types available (do not mutate) + * @returns {SourceTypes} types available (do not mutate) */ getSourceTypes() { - return TYPES; + return this.externalType === "css-import" ? CSS_TYPES : TYPES; } /** @@ -252,14 +517,16 @@ class ExternalModule extends Module { * @returns {boolean} true, if the chunk is ok for the module */ chunkCondition(chunk, { chunkGraph }) { - return chunkGraph.getNumberOfEntryModules(chunk) > 0; + return this.externalType === "css-import" + ? true + : chunkGraph.getNumberOfEntryModules(chunk) > 0; } /** * @returns {string} a unique identifier of the module */ identifier() { - return "external " + JSON.stringify(this.request); + return `external ${this.externalType} ${JSON.stringify(this.request)}`; } /** @@ -267,18 +534,37 @@ class ExternalModule extends Module { * @returns {string} a user readable identifier of the module */ readableIdentifier(requestShortener) { - return "external " + JSON.stringify(this.request); + return `external ${JSON.stringify(this.request)}`; } /** * @param {NeedBuildContext} context context info - * @param {function(WebpackError=, boolean=): void} callback callback function, returns true, if the module needs a rebuild + * @param {function((WebpackError | null)=, boolean=): void} callback callback function, returns true, if the module needs a rebuild * @returns {void} */ needBuild(context, callback) { return callback(null, !this.buildMeta); } + /** + * @param {string} externalType raw external type + * @returns {string} resolved external type + */ + getModuleImportType(externalType) { + if (externalType === "module-import") { + if ( + this.dependencyMeta && + /** @type {ImportDependencyMeta} */ (this.dependencyMeta).externalType + ) { + return /** @type {ImportDependencyMeta} */ (this.dependencyMeta) + .externalType; + } + return "module"; + } + + return externalType; + } + /** * @param {WebpackOptions} options webpack options * @param {Compilation} compilation the compilation @@ -293,37 +579,93 @@ class ExternalModule extends Module { exportsType: undefined }; this.buildInfo = { - strict: this.externalType !== "this", - topLevelDeclarations: new Set() + strict: true, + topLevelDeclarations: new Set(), + module: compilation.outputOptions.module }; + const { request, externalType } = this._getRequestAndExternalType(); this.buildMeta.exportsType = "dynamic"; let canMangle = false; this.clearDependenciesAndBlocks(); - switch (this.externalType) { + switch (externalType) { + case "this": + this.buildInfo.strict = false; + break; case "system": - if (!Array.isArray(this.request) || this.request.length === 1) { + if (!Array.isArray(request) || request.length === 1) { this.buildMeta.exportsType = "namespace"; canMangle = true; } break; + case "script": + this.buildMeta.async = true; + EnvironmentNotSupportAsyncWarning.check( + this, + compilation.runtimeTemplate, + "external script" + ); + break; case "promise": this.buildMeta.async = true; + EnvironmentNotSupportAsyncWarning.check( + this, + compilation.runtimeTemplate, + "external promise" + ); break; + case "module": case "import": - this.buildMeta.async = true; - if (!Array.isArray(this.request) || this.request.length === 1) { - this.buildMeta.exportsType = "namespace"; - canMangle = false; + case "module-import": { + const type = this.getModuleImportType(externalType); + if (type === "module") { + if (this.buildInfo.module) { + if (!Array.isArray(request) || request.length === 1) { + this.buildMeta.exportsType = "namespace"; + canMangle = true; + } + } else { + this.buildMeta.async = true; + EnvironmentNotSupportAsyncWarning.check( + this, + compilation.runtimeTemplate, + "external module" + ); + if (!Array.isArray(request) || request.length === 1) { + this.buildMeta.exportsType = "namespace"; + canMangle = false; + } + } } + + if (type === "import") { + this.buildMeta.async = true; + EnvironmentNotSupportAsyncWarning.check( + this, + compilation.runtimeTemplate, + "external import" + ); + if (!Array.isArray(request) || request.length === 1) { + this.buildMeta.exportsType = "namespace"; + canMangle = false; + } + } + break; - case "script": - this.buildMeta.async = true; - break; + } } this.addDependency(new StaticExportsDependency(true, canMangle)); callback(); } + /** + * restore unsafe cache data + * @param {object} unsafeCacheData data from getUnsafeCacheData + * @param {NormalModuleFactory} normalModuleFactory the normal module factory handling the unsafe caching + */ + restoreFromUnsafeCache(unsafeCacheData, normalModuleFactory) { + this._restoreFromUnsafeCache(unsafeCacheData, normalModuleFactory); + } + /** * @param {ConcatenationBailoutReasonContext} context context * @returns {string | undefined} reason why this module can't be concatenated, undefined when it can be concatenated @@ -341,12 +683,34 @@ class ExternalModule extends Module { return undefined; } - getSourceData(runtimeTemplate, moduleGraph, chunkGraph) { - const request = - typeof this.request === "object" && !Array.isArray(this.request) - ? this.request[this.externalType] - : this.request; - switch (this.externalType) { + _getRequestAndExternalType() { + let { request, externalType } = this; + if (typeof request === "object" && !Array.isArray(request)) + request = request[externalType]; + return { request, externalType }; + } + + /** + * @private + * @param {string | string[]} request request + * @param {string} externalType the external type + * @param {RuntimeTemplate} runtimeTemplate the runtime template + * @param {ModuleGraph} moduleGraph the module graph + * @param {ChunkGraph} chunkGraph the chunk graph + * @param {RuntimeSpec} runtime the runtime + * @param {DependencyMeta | undefined} dependencyMeta the dependency meta + * @returns {SourceData} the source data + */ + _getSourceData( + request, + externalType, + runtimeTemplate, + moduleGraph, + chunkGraph, + runtime, + dependencyMeta + ) { + switch (externalType) { case "this": case "window": case "self": @@ -354,35 +718,84 @@ class ExternalModule extends Module { case "global": return getSourceForGlobalVariableExternal( request, - runtimeTemplate.outputOptions.globalObject + runtimeTemplate.globalObject ); case "commonjs": case "commonjs2": case "commonjs-module": + case "commonjs-static": return getSourceForCommonJsExternal(request); + case "node-commonjs": + return /** @type {BuildInfo} */ (this.buildInfo).module + ? getSourceForCommonJsExternalInNodeModule( + request, + /** @type {string} */ + (runtimeTemplate.outputOptions.importMetaName), + /** @type {boolean} */ + (runtimeTemplate.supportNodePrefixForCoreModules()) + ) + : getSourceForCommonJsExternal(request); case "amd": case "amd-require": case "umd": case "umd2": case "system": - case "jsonp": + case "jsonp": { + const id = chunkGraph.getModuleId(this); return getSourceForAmdOrUmdExternal( - chunkGraph.getModuleId(this), + id !== null ? id : this.identifier(), this.isOptional(moduleGraph), request, runtimeTemplate ); - case "import": - return getSourceForImportExternal(request, runtimeTemplate); + } case "script": return getSourceForScriptExternal(request, runtimeTemplate); case "module": - if (!runtimeTemplate.supportsEcmaScriptModuleSyntax()) { - throw new Error( - "The target environment doesn't support EcmaScriptModule syntax so it's not possible to use external type 'module'" + case "import": + case "module-import": { + const type = this.getModuleImportType(externalType); + if (type === "import") { + return getSourceForImportExternal( + request, + runtimeTemplate, + /** @type {ImportDependencyMeta} */ (dependencyMeta) ); } - throw new Error("Module external type is not implemented yet"); + + if (type === "module") { + if (!(/** @type {BuildInfo} */ (this.buildInfo).module)) { + if (!runtimeTemplate.supportsDynamicImport()) { + throw new Error( + `The target environment doesn't support dynamic import() syntax so it's not possible to use external type 'module' within a script${ + runtimeTemplate.supportsEcmaScriptModuleSyntax() + ? "\nDid you mean to build a EcmaScript Module ('output.module: true')?" + : "" + }` + ); + } + return getSourceForImportExternal( + request, + runtimeTemplate, + /** @type {ImportDependencyMeta} */ (dependencyMeta) + ); + } + if (!runtimeTemplate.supportsEcmaScriptModuleSyntax()) { + throw new Error( + "The target environment doesn't support EcmaScriptModule syntax so it's not possible to use external type 'module'" + ); + } + return getSourceForModuleExternal( + request, + moduleGraph.getExportsInfo(this), + runtime, + runtimeTemplate, + /** @type {ImportDependencyMeta} */ (dependencyMeta) + ); + } + + break; + } case "var": case "promise": case "const": @@ -405,47 +818,109 @@ class ExternalModule extends Module { runtimeTemplate, moduleGraph, chunkGraph, + runtime, concatenationScope }) { - const sourceData = this.getSourceData( - runtimeTemplate, - moduleGraph, - chunkGraph - ); + const { request, externalType } = this._getRequestAndExternalType(); + switch (externalType) { + case "asset": { + const sources = new Map(); + sources.set( + "javascript", + new RawSource(`module.exports = ${JSON.stringify(request)};`) + ); + const data = new Map(); + data.set("url", request); + return { sources, runtimeRequirements: RUNTIME_REQUIREMENTS, data }; + } + case "css-import": { + const sources = new Map(); + const dependencyMeta = /** @type {CssImportDependencyMeta} */ ( + this.dependencyMeta + ); + const layer = + dependencyMeta.layer !== undefined + ? ` layer(${dependencyMeta.layer})` + : ""; + const supports = dependencyMeta.supports + ? ` supports(${dependencyMeta.supports})` + : ""; + const media = dependencyMeta.media ? ` ${dependencyMeta.media}` : ""; + sources.set( + "css-import", + new RawSource( + `@import url(${JSON.stringify( + request + )})${layer}${supports}${media};` + ) + ); + return { + sources, + runtimeRequirements: EMPTY_RUNTIME_REQUIREMENTS + }; + } + default: { + const sourceData = this._getSourceData( + request, + externalType, + runtimeTemplate, + moduleGraph, + chunkGraph, + runtime, + this.dependencyMeta + ); - let sourceString = sourceData.expression; - if (sourceData.iife) - sourceString = `(function() { return ${sourceString}; }())`; - if (concatenationScope) { - sourceString = `${runtimeTemplate.supportsConst() ? "const" : "var"} ${ - ConcatenationScope.NAMESPACE_OBJECT_EXPORT - } = ${sourceString};`; - concatenationScope.registerNamespaceExport( - ConcatenationScope.NAMESPACE_OBJECT_EXPORT - ); - } else { - sourceString = `module.exports = ${sourceString};`; - } - if (sourceData.init) sourceString = `${sourceData.init}\n${sourceString}`; + let sourceString = sourceData.expression; + if (sourceData.iife) + sourceString = `(function() { return ${sourceString}; }())`; + if (concatenationScope) { + sourceString = `${ + runtimeTemplate.supportsConst() ? "const" : "var" + } ${ConcatenationScope.NAMESPACE_OBJECT_EXPORT} = ${sourceString};`; + concatenationScope.registerNamespaceExport( + ConcatenationScope.NAMESPACE_OBJECT_EXPORT + ); + } else { + sourceString = `module.exports = ${sourceString};`; + } + if (sourceData.init) + sourceString = `${sourceData.init}\n${sourceString}`; - const sources = new Map(); - if (this.useSourceMap || this.useSimpleSourceMap) { - sources.set( - "javascript", - new OriginalSource(sourceString, this.identifier()) - ); - } else { - sources.set("javascript", new RawSource(sourceString)); - } + let data; + if (sourceData.chunkInitFragments) { + data = new Map(); + data.set("chunkInitFragments", sourceData.chunkInitFragments); + } - return { - sources, - runtimeRequirements: concatenationScope - ? RUNTIME_REQUIREMENTS_CONCATENATED - : this.externalType === "script" - ? RUNTIME_REQUIREMENTS_FOR_SCRIPT - : RUNTIME_REQUIREMENTS - }; + const sources = new Map(); + if (this.useSourceMap || this.useSimpleSourceMap) { + sources.set( + "javascript", + new OriginalSource(sourceString, this.identifier()) + ); + } else { + sources.set("javascript", new RawSource(sourceString)); + } + + let runtimeRequirements = sourceData.runtimeRequirements; + if (!concatenationScope) { + if (!runtimeRequirements) { + runtimeRequirements = RUNTIME_REQUIREMENTS; + } else { + const set = new Set(runtimeRequirements); + set.add(RuntimeGlobals.module); + runtimeRequirements = set; + } + } + + return { + sources, + runtimeRequirements: + runtimeRequirements || EMPTY_RUNTIME_REQUIREMENTS, + data + }; + } + } } /** @@ -463,30 +938,38 @@ class ExternalModule extends Module { */ updateHash(hash, context) { const { chunkGraph } = context; - hash.update(this.externalType); - hash.update(JSON.stringify(this.request)); hash.update( - JSON.stringify(Boolean(this.isOptional(chunkGraph.moduleGraph))) + `${this.externalType}${JSON.stringify(this.request)}${this.isOptional( + chunkGraph.moduleGraph + )}` ); super.updateHash(hash, context); } + /** + * @param {ObjectSerializerContext} context context + */ serialize(context) { const { write } = context; write(this.request); write(this.externalType); write(this.userRequest); + write(this.dependencyMeta); super.serialize(context); } + /** + * @param {ObjectDeserializerContext} context context + */ deserialize(context) { const { read } = context; this.request = read(); this.externalType = read(); this.userRequest = read(); + this.dependencyMeta = read(); super.deserialize(context); } diff --git a/lib/ExternalModuleFactoryPlugin.js b/lib/ExternalModuleFactoryPlugin.js index 0a89a3f5982..9bde3629dae 100644 --- a/lib/ExternalModuleFactoryPlugin.js +++ b/lib/ExternalModuleFactoryPlugin.js @@ -7,17 +7,25 @@ const util = require("util"); const ExternalModule = require("./ExternalModule"); +const ContextElementDependency = require("./dependencies/ContextElementDependency"); +const CssImportDependency = require("./dependencies/CssImportDependency"); +const HarmonyImportDependency = require("./dependencies/HarmonyImportDependency"); +const ImportDependency = require("./dependencies/ImportDependency"); const { resolveByProperty, cachedSetProperty } = require("./util/cleverMerge"); /** @typedef {import("../declarations/WebpackOptions").Externals} Externals */ +/** @typedef {import("./Compilation").DepConstructor} DepConstructor */ +/** @typedef {import("./ExternalModule").DependencyMeta} DependencyMeta */ +/** @typedef {import("./Module")} Module */ /** @typedef {import("./NormalModuleFactory")} NormalModuleFactory */ -const UNSPECIFIED_EXTERNAL_TYPE_REGEXP = /^[a-z0-9]+ /; +const UNSPECIFIED_EXTERNAL_TYPE_REGEXP = /^[a-z0-9-]+ /; const EMPTY_RESOLVE_OPTIONS = {}; // TODO webpack 6 remove this const callDeprecatedExternals = util.deprecate( (externalsFunction, context, request, cb) => { + // eslint-disable-next-line no-useless-call externalsFunction.call(null, context, request, cb); }, "The externals-function should be defined like ({context, request}, cb) => { ... }", @@ -26,6 +34,11 @@ const callDeprecatedExternals = util.deprecate( const cache = new WeakMap(); +/** + * @param {object} obj obj + * @param {TODO} layer layer + * @returns {object} result + */ const resolveLayer = (obj, layer) => { let map = cache.get(obj); if (map === undefined) { @@ -40,6 +53,9 @@ const resolveLayer = (obj, layer) => { return result; }; +/** @typedef {string|string[]|boolean|Record} ExternalValue */ +/** @typedef {string|undefined} ExternalType */ + class ExternalModuleFactoryPlugin { /** * @param {string | undefined} type default external type @@ -62,11 +78,12 @@ class ExternalModuleFactoryPlugin { const context = data.context; const contextInfo = data.contextInfo; const dependency = data.dependencies[0]; + const dependencyType = data.dependencyType; /** - * @param {string|string[]|boolean|Record} value the external config - * @param {string|undefined} type type of external - * @param {function(Error=, ExternalModule=): void} callback callback + * @param {ExternalValue} value the external config + * @param {ExternalType | undefined} type type of external + * @param {function((Error | null)=, ExternalModule=): void} callback callback * @returns {void} */ const handleExternal = (value, type, callback) => { @@ -75,12 +92,7 @@ class ExternalModuleFactoryPlugin { return callback(); } /** @type {string | string[] | Record} */ - let externalConfig; - if (value === true) { - externalConfig = dependency.request; - } else { - externalConfig = value; - } + let externalConfig = value === true ? dependency.request : value; // When no explicit type is specified, extract it from the externalConfig if (type === undefined) { if ( @@ -88,8 +100,8 @@ class ExternalModuleFactoryPlugin { UNSPECIFIED_EXTERNAL_TYPE_REGEXP.test(externalConfig) ) { const idx = externalConfig.indexOf(" "); - type = externalConfig.substr(0, idx); - externalConfig = externalConfig.substr(idx + 1); + type = externalConfig.slice(0, idx); + externalConfig = externalConfig.slice(idx + 1); } else if ( Array.isArray(externalConfig) && externalConfig.length > 0 && @@ -97,26 +109,57 @@ class ExternalModuleFactoryPlugin { ) { const firstItem = externalConfig[0]; const idx = firstItem.indexOf(" "); - type = firstItem.substr(0, idx); + type = firstItem.slice(0, idx); externalConfig = [ - firstItem.substr(idx + 1), + firstItem.slice(idx + 1), ...externalConfig.slice(1) ]; } } + + // TODO make it pluggable/add hooks to `ExternalModule` to allow output modules own externals? + /** @type {DependencyMeta | undefined} */ + let dependencyMeta; + + if ( + dependency instanceof HarmonyImportDependency || + dependency instanceof ImportDependency || + dependency instanceof ContextElementDependency + ) { + const externalType = + dependency instanceof HarmonyImportDependency + ? "module" + : dependency instanceof ImportDependency + ? "import" + : undefined; + + dependencyMeta = { + attributes: dependency.assertions, + externalType + }; + } else if (dependency instanceof CssImportDependency) { + dependencyMeta = { + layer: dependency.layer, + supports: dependency.supports, + media: dependency.media + }; + } + callback( null, new ExternalModule( externalConfig, - type || globalType, - dependency.request + /** @type {string} */ + (type || globalType), + dependency.request, + dependencyMeta ) ); }; /** * @param {Externals} externals externals config - * @param {function(Error=, ExternalModule=): void} callback callback + * @param {function((Error | null)=, ExternalModule=): void} callback callback * @returns {void} */ const handleExternals = (externals, callback) => { @@ -127,7 +170,13 @@ class ExternalModuleFactoryPlugin { } else if (Array.isArray(externals)) { let i = 0; const next = () => { + /** @type {boolean | undefined} */ let asyncFlag; + /** + * @param {(Error | null)=} err err + * @param {ExternalModule=} module module + * @returns {void} + */ const handleExternalsAndCallback = (err, module) => { if (err) return callback(err); if (!module) { @@ -176,9 +225,9 @@ class ExternalModuleFactoryPlugin { { context, request: dependency.request, + dependencyType, contextInfo, getResolve: options => (context, request, callback) => { - const dependencyType = dependency.category || ""; const resolveContext = { fileDependencies: data.fileDependencies, missingDependencies: data.missingDependencies, @@ -191,7 +240,7 @@ class ExternalModuleFactoryPlugin { data.resolveOptions || EMPTY_RESOLVE_OPTIONS, "dependencyType", dependencyType - ) + ) : data.resolveOptions ); if (options) resolver = resolver.withOptions(options); diff --git a/lib/FileSystemInfo.js b/lib/FileSystemInfo.js index b0e819ded8f..9112ca07b9b 100644 --- a/lib/FileSystemInfo.js +++ b/lib/FileSystemInfo.js @@ -6,18 +6,41 @@ "use strict"; const { create: createResolver } = require("enhanced-resolve"); +const nodeModule = require("module"); const asyncLib = require("neo-async"); +const { isAbsolute } = require("path"); const AsyncQueue = require("./util/AsyncQueue"); +const StackedCacheMap = require("./util/StackedCacheMap"); const createHash = require("./util/createHash"); -const { join, dirname, relative } = require("./util/fs"); +const { join, dirname, relative, lstatReadlinkAbsolute } = require("./util/fs"); const makeSerializable = require("./util/makeSerializable"); const processAsyncTree = require("./util/processAsyncTree"); +/** @typedef {import("enhanced-resolve").Resolver} Resolver */ +/** @typedef {import("enhanced-resolve").ResolveRequest} ResolveRequest */ +/** @typedef {import("enhanced-resolve").ResolveFunctionAsync} ResolveFunctionAsync */ /** @typedef {import("./WebpackError")} WebpackError */ /** @typedef {import("./logging/Logger").Logger} Logger */ +/** @typedef {import("./serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */ +/** @typedef {import("./serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */ +/** @typedef {typeof import("./util/Hash")} Hash */ +/** @typedef {import("./util/fs").IStats} IStats */ /** @typedef {import("./util/fs").InputFileSystem} InputFileSystem */ +/** @typedef {import("./util/fs").PathLike} PathLike */ +/** @typedef {import("./util/fs").StringCallback} StringCallback */ +/** + * @template T + * @typedef {import("./util/AsyncQueue").Callback} ProcessorCallback + */ +/** + * @template T, R + * @typedef {import("./util/AsyncQueue").Processor} Processor + */ + +const supportsEsm = Number(process.versions.modules) >= 83; -const supportsEsm = +process.versions.modules >= 83; +/** @type {Set} */ +const builtinModules = new Set(nodeModule.builtinModules); let FS_ACCURACY = 2000; @@ -27,83 +50,248 @@ const RBDT_RESOLVE_CJS = 0; const RBDT_RESOLVE_ESM = 1; const RBDT_RESOLVE_DIRECTORY = 2; const RBDT_RESOLVE_CJS_FILE = 3; -const RBDT_RESOLVE_ESM_FILE = 4; -const RBDT_DIRECTORY = 5; -const RBDT_FILE = 6; -const RBDT_DIRECTORY_DEPENDENCIES = 7; -const RBDT_FILE_DEPENDENCIES = 8; +const RBDT_RESOLVE_CJS_FILE_AS_CHILD = 4; +const RBDT_RESOLVE_ESM_FILE = 5; +const RBDT_DIRECTORY = 6; +const RBDT_FILE = 7; +const RBDT_DIRECTORY_DEPENDENCIES = 8; +const RBDT_FILE_DEPENDENCIES = 9; + +/** @typedef {RBDT_RESOLVE_CJS | RBDT_RESOLVE_ESM | RBDT_RESOLVE_DIRECTORY | RBDT_RESOLVE_CJS_FILE | RBDT_RESOLVE_CJS_FILE_AS_CHILD | RBDT_RESOLVE_ESM_FILE | RBDT_DIRECTORY | RBDT_FILE | RBDT_DIRECTORY_DEPENDENCIES | RBDT_FILE_DEPENDENCIES} JobType */ const INVALID = Symbol("invalid"); /** - * @typedef {Object} FileSystemInfoEntry + * @typedef {object} FileSystemInfoEntry * @property {number} safeTime * @property {number=} timestamp + */ + +/** + * @typedef {object} ResolvedContextFileSystemInfoEntry + * @property {number} safeTime + * @property {string=} timestampHash + */ + +/** + * @typedef {object} ContextFileSystemInfoEntry + * @property {number} safeTime * @property {string=} timestampHash + * @property {ResolvedContextFileSystemInfoEntry=} resolved + * @property {Set=} symlinks */ /** - * @typedef {Object} TimestampAndHash + * @typedef {object} TimestampAndHash * @property {number} safeTime * @property {number=} timestamp + * @property {string} hash + */ + +/** + * @typedef {object} ResolvedContextTimestampAndHash + * @property {number} safeTime + * @property {string=} timestampHash + * @property {string} hash + */ + +/** @typedef {Set} Symlinks */ + +/** + * @typedef {object} ContextTimestampAndHash + * @property {number} safeTime * @property {string=} timestampHash * @property {string} hash + * @property {ResolvedContextTimestampAndHash=} resolved + * @property {Symlinks=} symlinks + */ + +/** + * @typedef {object} ContextHash + * @property {string} hash + * @property {string=} resolved + * @property {Symlinks=} symlinks */ +/** @typedef {Set} SnapshotContent */ + /** - * @typedef {Object} SnapshotOptimizationEntry + * @typedef {object} SnapshotOptimizationEntry * @property {Snapshot} snapshot * @property {number} shared - * @property {Set} snapshotContent - * @property {Set} children + * @property {SnapshotContent | undefined} snapshotContent + * @property {Set | undefined} children */ /** - * @typedef {Object} ResolveBuildDependenciesResult + * @typedef {object} ResolveBuildDependenciesResult * @property {Set} files list of files * @property {Set} directories list of directories * @property {Set} missing list of missing entries - * @property {Map} resolveResults stored resolve results - * @property {Object} resolveDependencies dependencies of the resolving + * @property {Map} resolveResults stored resolve results + * @property {object} resolveDependencies dependencies of the resolving * @property {Set} resolveDependencies.files list of files * @property {Set} resolveDependencies.directories list of directories * @property {Set} resolveDependencies.missing list of missing entries */ +/** + * @typedef {object} SnapshotOptions + * @property {boolean=} hash should use hash to snapshot + * @property {boolean=} timestamp should use timestamp to snapshot + */ + const DONE_ITERATOR_RESULT = new Set().keys().next(); // cspell:word tshs // Tsh = Timestamp + Hash // Tshs = Timestamp + Hash combinations +class SnapshotIterator { + /** + * @param {() => IteratorResult} next next + */ + constructor(next) { + this.next = next; + } +} + +/** + * @typedef {(snapshot: Snapshot) => (Map | Set | undefined)[]} GetMapsFunction + */ + +class SnapshotIterable { + /** + * @param {Snapshot} snapshot snapshot + * @param {GetMapsFunction} getMaps get maps function + */ + constructor(snapshot, getMaps) { + this.snapshot = snapshot; + this.getMaps = getMaps; + } + + [Symbol.iterator]() { + let state = 0; + /** @type {IterableIterator} */ + let it; + /** @type {(snapshot: Snapshot) => (Map | Set | undefined)[]} */ + let getMaps; + /** @type {(Map | Set | undefined)[]} */ + let maps; + /** @type {Snapshot} */ + let snapshot; + /** @type {Snapshot[] | undefined} */ + let queue; + return new SnapshotIterator(() => { + for (;;) { + switch (state) { + case 0: + snapshot = this.snapshot; + getMaps = this.getMaps; + maps = getMaps(snapshot); + state = 1; + /* falls through */ + case 1: + if (maps.length > 0) { + const map = maps.pop(); + if (map !== undefined) { + it = map.keys(); + state = 2; + } else { + break; + } + } else { + state = 3; + break; + } + /* falls through */ + case 2: { + const result = it.next(); + if (!result.done) return result; + state = 1; + break; + } + case 3: { + const children = snapshot.children; + if (children !== undefined) { + if (children.size === 1) { + // shortcut for a single child + // avoids allocation of queue + for (const child of children) snapshot = child; + maps = getMaps(snapshot); + state = 1; + break; + } + if (queue === undefined) queue = []; + for (const child of children) { + queue.push(child); + } + } + if (queue !== undefined && queue.length > 0) { + snapshot = /** @type {Snapshot} */ (queue.pop()); + maps = getMaps(snapshot); + state = 1; + break; + } else { + state = 4; + } + } + /* falls through */ + case 4: + return DONE_ITERATOR_RESULT; + } + } + }); + } +} + +/** @typedef {Map} FileTimestamps */ +/** @typedef {Map} FileHashes */ +/** @typedef {Map} FileTshs */ +/** @typedef {Map} ContextTimestamps */ +/** @typedef {Map} ContextHashes */ +/** @typedef {Map} ContextTshs */ +/** @typedef {Map} MissingExistence */ +/** @typedef {Map} ManagedItemInfo */ +/** @typedef {Set} ManagedFiles */ +/** @typedef {Set} ManagedContexts */ +/** @typedef {Set} ManagedMissing */ +/** @typedef {Set} Children */ + class Snapshot { constructor() { this._flags = 0; + /** @type {Iterable | undefined} */ + this._cachedFileIterable = undefined; + /** @type {Iterable | undefined} */ + this._cachedContextIterable = undefined; + /** @type {Iterable | undefined} */ + this._cachedMissingIterable = undefined; /** @type {number | undefined} */ this.startTime = undefined; - /** @type {Map | undefined} */ + /** @type {FileTimestamps | undefined} */ this.fileTimestamps = undefined; - /** @type {Map | undefined} */ + /** @type {FileHashes | undefined} */ this.fileHashes = undefined; - /** @type {Map | undefined} */ + /** @type {FileTshs | undefined} */ this.fileTshs = undefined; - /** @type {Map | undefined} */ + /** @type {ContextTimestamps | undefined} */ this.contextTimestamps = undefined; - /** @type {Map | undefined} */ + /** @type {ContextHashes | undefined} */ this.contextHashes = undefined; - /** @type {Map | undefined} */ + /** @type {ContextTshs | undefined} */ this.contextTshs = undefined; - /** @type {Map | undefined} */ + /** @type {MissingExistence | undefined} */ this.missingExistence = undefined; - /** @type {Map | undefined} */ + /** @type {ManagedItemInfo | undefined} */ this.managedItemInfo = undefined; - /** @type {Set | undefined} */ + /** @type {ManagedFiles | undefined} */ this.managedFiles = undefined; - /** @type {Set | undefined} */ + /** @type {ManagedContexts | undefined} */ this.managedContexts = undefined; - /** @type {Set | undefined} */ + /** @type {ManagedMissing | undefined} */ this.managedMissing = undefined; - /** @type {Set | undefined} */ + /** @type {Children | undefined} */ this.children = undefined; } @@ -111,20 +299,36 @@ class Snapshot { return (this._flags & 1) !== 0; } + /** + * @param {number} value start value + */ setStartTime(value) { this._flags = this._flags | 1; this.startTime = value; } + /** + * @param {number | undefined} value value + * @param {Snapshot} snapshot snapshot + */ setMergedStartTime(value, snapshot) { if (value) { if (snapshot.hasStartTime()) { - this.setStartTime(Math.min(value, snapshot.startTime)); + this.setStartTime( + Math.min( + value, + /** @type {NonNullable} */ + (snapshot.startTime) + ) + ); } else { this.setStartTime(value); } - } else { - if (snapshot.hasStartTime()) this.setStartTime(snapshot.startTime); + } else if (snapshot.hasStartTime()) { + this.setStartTime( + /** @type {NonNullable} */ + (snapshot.startTime) + ); } } @@ -132,6 +336,9 @@ class Snapshot { return (this._flags & 2) !== 0; } + /** + * @param {FileTimestamps} value file timestamps + */ setFileTimestamps(value) { this._flags = this._flags | 2; this.fileTimestamps = value; @@ -141,6 +348,9 @@ class Snapshot { return (this._flags & 4) !== 0; } + /** + * @param {FileHashes} value file hashes + */ setFileHashes(value) { this._flags = this._flags | 4; this.fileHashes = value; @@ -150,6 +360,9 @@ class Snapshot { return (this._flags & 8) !== 0; } + /** + * @param {FileTshs} value file tshs + */ setFileTshs(value) { this._flags = this._flags | 8; this.fileTshs = value; @@ -159,6 +372,9 @@ class Snapshot { return (this._flags & 0x10) !== 0; } + /** + * @param {ContextTimestamps} value context timestamps + */ setContextTimestamps(value) { this._flags = this._flags | 0x10; this.contextTimestamps = value; @@ -168,6 +384,9 @@ class Snapshot { return (this._flags & 0x20) !== 0; } + /** + * @param {ContextHashes} value context hashes + */ setContextHashes(value) { this._flags = this._flags | 0x20; this.contextHashes = value; @@ -177,6 +396,9 @@ class Snapshot { return (this._flags & 0x40) !== 0; } + /** + * @param {ContextTshs} value context tshs + */ setContextTshs(value) { this._flags = this._flags | 0x40; this.contextTshs = value; @@ -186,6 +408,9 @@ class Snapshot { return (this._flags & 0x80) !== 0; } + /** + * @param {MissingExistence} value context tshs + */ setMissingExistence(value) { this._flags = this._flags | 0x80; this.missingExistence = value; @@ -195,6 +420,9 @@ class Snapshot { return (this._flags & 0x100) !== 0; } + /** + * @param {ManagedItemInfo} value managed item info + */ setManagedItemInfo(value) { this._flags = this._flags | 0x100; this.managedItemInfo = value; @@ -204,6 +432,9 @@ class Snapshot { return (this._flags & 0x200) !== 0; } + /** + * @param {ManagedFiles} value managed files + */ setManagedFiles(value) { this._flags = this._flags | 0x200; this.managedFiles = value; @@ -213,6 +444,9 @@ class Snapshot { return (this._flags & 0x400) !== 0; } + /** + * @param {ManagedContexts} value managed contexts + */ setManagedContexts(value) { this._flags = this._flags | 0x400; this.managedContexts = value; @@ -222,6 +456,9 @@ class Snapshot { return (this._flags & 0x800) !== 0; } + /** + * @param {ManagedMissing} value managed missing + */ setManagedMissing(value) { this._flags = this._flags | 0x800; this.managedMissing = value; @@ -231,18 +468,28 @@ class Snapshot { return (this._flags & 0x1000) !== 0; } + /** + * @param {Children} value children + */ setChildren(value) { this._flags = this._flags | 0x1000; this.children = value; } + /** + * @param {Snapshot} child children + */ addChild(child) { if (!this.hasChildren()) { this.setChildren(new Set()); } - this.children.add(child); + /** @type {Children} */ + (this.children).add(child); } + /** + * @param {ObjectSerializerContext} context context + */ serialize({ write }) { write(this._flags); if (this.hasStartTime()) write(this.startTime); @@ -260,6 +507,9 @@ class Snapshot { if (this.hasChildren()) write(this.children); } + /** + * @param {ObjectDeserializerContext} context context + */ deserialize({ read }) { this._flags = read(); if (this.hasStartTime()) this.startTime = read(); @@ -278,98 +528,54 @@ class Snapshot { } /** - * @param {function(Snapshot): (Map | Set)[]} getMaps first + * @param {GetMapsFunction} getMaps first * @returns {Iterable} iterable */ _createIterable(getMaps) { - let snapshot = this; - return { - [Symbol.iterator]() { - let state = 0; - /** @type {IterableIterator} */ - let it; - let maps = getMaps(snapshot); - const queue = []; - return { - next() { - for (;;) { - switch (state) { - case 0: - if (maps.length > 0) { - const map = maps.pop(); - if (map !== undefined) { - it = map.keys(); - state = 1; - } else { - break; - } - } else { - state = 2; - break; - } - /* falls through */ - case 1: { - const result = it.next(); - if (!result.done) return result; - state = 0; - break; - } - case 2: { - const children = snapshot.children; - if (children !== undefined) { - for (const child of children) { - queue.push(child); - } - } - if (queue.length > 0) { - snapshot = queue.pop(); - maps = getMaps(snapshot); - state = 0; - break; - } else { - state = 3; - } - } - /* falls through */ - case 3: - return DONE_ITERATOR_RESULT; - } - } - } - }; - } - }; + return new SnapshotIterable(this, getMaps); } /** * @returns {Iterable} iterable */ getFileIterable() { - return this._createIterable(s => [ - s.fileTimestamps, - s.fileHashes, - s.fileTshs, - s.managedFiles - ]); + if (this._cachedFileIterable === undefined) { + this._cachedFileIterable = this._createIterable(s => [ + s.fileTimestamps, + s.fileHashes, + s.fileTshs, + s.managedFiles + ]); + } + return this._cachedFileIterable; } /** * @returns {Iterable} iterable */ getContextIterable() { - return this._createIterable(s => [ - s.contextTimestamps, - s.contextHashes, - s.contextTshs, - s.managedContexts - ]); + if (this._cachedContextIterable === undefined) { + this._cachedContextIterable = this._createIterable(s => [ + s.contextTimestamps, + s.contextHashes, + s.contextTshs, + s.managedContexts + ]); + } + return this._cachedContextIterable; } /** * @returns {Iterable} iterable */ getMissingIterable() { - return this._createIterable(s => [s.missingExistence, s.managedMissing]); + if (this._cachedMissingIterable === undefined) { + this._cachedMissingIterable = this._createIterable(s => [ + s.missingExistence, + s.managedMissing + ]); + } + return this._cachedMissingIterable; } } @@ -377,20 +583,35 @@ makeSerializable(Snapshot, "webpack/lib/FileSystemInfo", "Snapshot"); const MIN_COMMON_SNAPSHOT_SIZE = 3; +/** + * @template U, T + * @typedef {U extends true ? Set : Map} SnapshotOptimizationValue + */ + /** * @template T + * @template {boolean} [U=false] */ class SnapshotOptimization { /** * @param {function(Snapshot): boolean} has has value - * @param {function(Snapshot): Map | Set} get get value - * @param {function(Snapshot, Map | Set): void} set set value - * @param {boolean=} isSet value is an Set instead of a Map + * @param {function(Snapshot): SnapshotOptimizationValue | undefined} get get value + * @param {function(Snapshot, SnapshotOptimizationValue): void} set set value + * @param {boolean=} useStartTime use the start time of snapshots + * @param {U=} isSet value is an Set instead of a Map */ - constructor(has, get, set, isSet = false) { + constructor( + has, + get, + set, + useStartTime = true, + isSet = /** @type {U} */ (false) + ) { this._has = has; this._get = get; this._set = set; + this._useStartTime = useStartTime; + /** @type {U} */ this._isSet = isSet; /** @type {Map} */ this._map = new Map(); @@ -402,7 +623,7 @@ class SnapshotOptimization { getStatisticMessage() { const total = this._statItemsShared + this._statItemsUnshared; - if (total === 0) return undefined; + if (total === 0) return; return `${ this._statItemsShared && Math.round((this._statItemsShared * 100) / total) }% (${this._statItemsShared}/${total}) entries shared via ${ @@ -412,31 +633,29 @@ class SnapshotOptimization { } times referenced)`; } - storeUnsharedSnapshot(snapshot, locations) { - if (locations === undefined) return; - const optimizationEntry = { - snapshot, - shared: 0, - snapshotContent: undefined, - children: undefined - }; - for (const path of locations) { - this._map.set(path, optimizationEntry); - } + clear() { + this._map.clear(); + this._statItemsShared = 0; + this._statItemsUnshared = 0; + this._statSharedSnapshots = 0; + this._statReusedSharedSnapshots = 0; } - optimize(capturedFiles, startTime, children) { - /** @type {Set} */ - const unsetOptimizationEntries = new Set(); - /** @type {Set} */ - const checkedOptimizationEntries = new Set(); + /** + * @param {Snapshot} newSnapshot snapshot + * @param {Set} capturedFiles files to snapshot/share + * @returns {void} + */ + optimize(newSnapshot, capturedFiles) { /** * @param {SnapshotOptimizationEntry} entry optimization entry * @returns {void} */ const increaseSharedAndStoreOptimizationEntry = entry => { if (entry.children !== undefined) { - entry.children.forEach(increaseSharedAndStoreOptimizationEntry); + for (const child of entry.children) { + increaseSharedAndStoreOptimizationEntry(child); + } } entry.shared++; storeOptimizationEntry(entry); @@ -446,43 +665,71 @@ class SnapshotOptimization { * @returns {void} */ const storeOptimizationEntry = entry => { - for (const path of entry.snapshotContent) { - const old = this._map.get(path); + for (const path of /** @type {SnapshotContent} */ ( + entry.snapshotContent + )) { + const old = + /** @type {SnapshotOptimizationEntry} */ + (this._map.get(path)); if (old.shared < entry.shared) { this._map.set(path, entry); } capturedFiles.delete(path); } }; + + /** @type {SnapshotOptimizationEntry | undefined} */ + let newOptimizationEntry; + const capturedFilesSize = capturedFiles.size; - capturedFiles: for (const path of capturedFiles) { + + /** @type {Set | undefined} */ + const optimizationEntries = new Set(); + + for (const path of capturedFiles) { const optimizationEntry = this._map.get(path); if (optimizationEntry === undefined) { - unsetOptimizationEntries.add(path); + if (newOptimizationEntry === undefined) { + newOptimizationEntry = { + snapshot: newSnapshot, + shared: 0, + snapshotContent: undefined, + children: undefined + }; + } + this._map.set(path, newOptimizationEntry); continue; + } else { + optimizationEntries.add(optimizationEntry); } - if (checkedOptimizationEntries.has(optimizationEntry)) continue; + } + + optimizationEntriesLabel: for (const optimizationEntry of optimizationEntries) { const snapshot = optimizationEntry.snapshot; if (optimizationEntry.shared > 0) { // It's a shared snapshot // We can't change it, so we can only use it when all files match // and startTime is compatible if ( - startTime && - (!snapshot.startTime || snapshot.startTime > startTime) + this._useStartTime && + newSnapshot.startTime && + (!snapshot.startTime || snapshot.startTime > newSnapshot.startTime) ) { continue; } const nonSharedFiles = new Set(); - const snapshotContent = optimizationEntry.snapshotContent; - const snapshotEntries = this._get(snapshot); + const snapshotContent = + /** @type {NonNullable} */ + (optimizationEntry.snapshotContent); + const snapshotEntries = + /** @type {SnapshotOptimizationValue} */ + (this._get(snapshot)); for (const path of snapshotContent) { if (!capturedFiles.has(path)) { if (!snapshotEntries.has(path)) { // File is not shared and can't be removed from the snapshot // because it's in a child of the snapshot - checkedOptimizationEntries.add(optimizationEntry); - continue capturedFiles; + continue optimizationEntriesLabel; } nonSharedFiles.add(path); continue; @@ -491,7 +738,7 @@ class SnapshotOptimization { if (nonSharedFiles.size === 0) { // The complete snapshot is shared // add it as child - children.add(snapshot); + newSnapshot.addChild(snapshot); increaseSharedAndStoreOptimizationEntry(optimizationEntry); this._statReusedSharedSnapshots++; } else { @@ -499,8 +746,7 @@ class SnapshotOptimization { const sharedCount = snapshotContent.size - nonSharedFiles.size; if (sharedCount < MIN_COMMON_SNAPSHOT_SIZE) { // Common part it too small - checkedOptimizationEntries.add(optimizationEntry); - continue capturedFiles; + continue; } // Extract common timestamps from both snapshots let commonMap; @@ -522,9 +768,14 @@ class SnapshotOptimization { } // Create and attach snapshot const commonSnapshot = new Snapshot(); - commonSnapshot.setMergedStartTime(startTime, snapshot); - this._set(commonSnapshot, commonMap); - children.add(commonSnapshot); + if (this._useStartTime) { + commonSnapshot.setMergedStartTime(newSnapshot.startTime, snapshot); + } + this._set( + commonSnapshot, + /** @type {SnapshotOptimizationValue} */ (commonMap) + ); + newSnapshot.addChild(commonSnapshot); snapshot.addChild(commonSnapshot); // Create optimization entry const newEntry = { @@ -544,6 +795,10 @@ class SnapshotOptimization { // We can extract a common shared snapshot // with all common files const snapshotEntries = this._get(snapshot); + if (snapshotEntries === undefined) { + // Incomplete snapshot, that can't be used + continue; + } let commonMap; if (this._isSet) { commonMap = new Set(); @@ -569,14 +824,19 @@ class SnapshotOptimization { if (commonMap.size < MIN_COMMON_SNAPSHOT_SIZE) { // Common part it too small - checkedOptimizationEntries.add(optimizationEntry); - continue capturedFiles; + continue; } // Create and attach snapshot const commonSnapshot = new Snapshot(); - commonSnapshot.setMergedStartTime(startTime, snapshot); - this._set(commonSnapshot, commonMap); - children.add(commonSnapshot); + if (this._useStartTime) { + commonSnapshot.setMergedStartTime(newSnapshot.startTime, snapshot); + } + this._set( + commonSnapshot, + /** @type {SnapshotOptimizationValue} */ + (commonMap) + ); + newSnapshot.addChild(commonSnapshot); snapshot.addChild(commonSnapshot); // Remove files from snapshot for (const path of commonMap.keys()) snapshotEntries.delete(path); @@ -592,15 +852,23 @@ class SnapshotOptimization { }); this._statSharedSnapshots++; } - checkedOptimizationEntries.add(optimizationEntry); } const unshared = capturedFiles.size; this._statItemsUnshared += unshared; this._statItemsShared += capturedFilesSize - unshared; - return unsetOptimizationEntries; } } +/** + * @param {string} str input + * @returns {string} result + */ +const parseString = str => { + if (str[0] === "'" || str[0] === "`") + str = `"${str.slice(1, -1).replace(/"/g, '\\"')}"`; + return JSON.parse(str); +}; + /* istanbul ignore next */ /** * @param {number} mtime mtime @@ -615,13 +883,14 @@ const applyMtime = mtime => { /** * @template T * @template K - * @param {Map} a source map - * @param {Map} b joining map + * @param {Map | undefined} a source map + * @param {Map | undefined} b joining map * @returns {Map} joined map */ const mergeMaps = (a, b) => { - if (!b || b.size === 0) return a; - if (!a || a.size === 0) return b; + if (!b || b.size === 0) return /** @type {Map} */ (a); + if (!a || a.size === 0) return /** @type {Map} */ (b); + /** @type {Map} */ const map = new Map(a); for (const [key, value] of b) { map.set(key, value); @@ -631,14 +900,14 @@ const mergeMaps = (a, b) => { /** * @template T - * @template K - * @param {Set} a source map - * @param {Set} b joining map - * @returns {Set} joined map + * @param {Set | undefined} a source map + * @param {Set | undefined} b joining map + * @returns {Set} joined map */ const mergeSets = (a, b) => { - if (!b || b.size === 0) return a; - if (!a || a.size === 0) return b; + if (!b || b.size === 0) return /** @type {Set} */ (a); + if (!a || a.size === 0) return /** @type {Set} */ (b); + /** @type {Set} */ const map = new Set(a); for (const item of b) { map.add(item); @@ -731,30 +1000,67 @@ const getManagedItem = (managedPath, path) => { }; /** - * @param {FileSystemInfoEntry} entry file system info entry - * @returns {boolean} existence flag + * @template {ContextFileSystemInfoEntry | ContextTimestampAndHash} T + * @param {T | null} entry entry + * @returns {T["resolved"] | null | undefined} the resolved entry + */ +const getResolvedTimestamp = entry => { + if (entry === null) return null; + if (entry.resolved !== undefined) return entry.resolved; + return entry.symlinks === undefined ? entry : undefined; +}; + +/** + * @param {ContextHash | null} entry entry + * @returns {string | null | undefined} the resolved entry + */ +const getResolvedHash = entry => { + if (entry === null) return null; + if (entry.resolved !== undefined) return entry.resolved; + return entry.symlinks === undefined ? entry.hash : undefined; +}; + +/** + * @template T + * @param {Set} source source + * @param {Set} target target */ -const toExistence = entry => { - return Boolean(entry); +const addAll = (source, target) => { + for (const key of source) target.add(key); }; +/** @typedef {Set} LoggedPaths */ + /** * Used to access information about the filesystem in a cached way */ class FileSystemInfo { /** * @param {InputFileSystem} fs file system - * @param {Object} options options - * @param {Iterable=} options.managedPaths paths that are only managed by a package manager - * @param {Iterable=} options.immutablePaths paths that are immutable + * @param {object} options options + * @param {Iterable=} options.unmanagedPaths paths that are not managed by a package manager and the contents are subject to change + * @param {Iterable=} options.managedPaths paths that are only managed by a package manager + * @param {Iterable=} options.immutablePaths paths that are immutable * @param {Logger=} options.logger logger used to log invalid snapshots + * @param {string | Hash=} options.hashFunction the hash function to use */ - constructor(fs, { managedPaths = [], immutablePaths = [], logger } = {}) { + constructor( + fs, + { + unmanagedPaths = [], + managedPaths = [], + immutablePaths = [], + logger, + hashFunction = "md4" + } = {} + ) { this.fs = fs; this.logger = logger; this._remainingLogs = logger ? 40 : 0; + /** @type {LoggedPaths | undefined} */ this._loggedPaths = logger ? new Set() : undefined; - /** @type {WeakMap} */ + this._hashFunction = hashFunction; + /** @type {WeakMap} */ this._snapshotCache = new WeakMap(); this._fileTimestampsOptimization = new SnapshotOptimization( s => s.hasFileTimestamps(), @@ -764,7 +1070,8 @@ class FileSystemInfo { this._fileHashesOptimization = new SnapshotOptimization( s => s.hasFileHashes(), s => s.fileHashes, - (s, v) => s.setFileHashes(v) + (s, v) => s.setFileHashes(v), + false ); this._fileTshsOptimization = new SnapshotOptimization( s => s.hasFileTshs(), @@ -779,7 +1086,8 @@ class FileSystemInfo { this._contextHashesOptimization = new SnapshotOptimization( s => s.hasContextHashes(), s => s.contextHashes, - (s, v) => s.setContextHashes(v) + (s, v) => s.setContextHashes(v), + false ); this._contextTshsOptimization = new SnapshotOptimization( s => s.hasContextTshs(), @@ -789,70 +1097,81 @@ class FileSystemInfo { this._missingExistenceOptimization = new SnapshotOptimization( s => s.hasMissingExistence(), s => s.missingExistence, - (s, v) => s.setMissingExistence(v) + (s, v) => s.setMissingExistence(v), + false ); this._managedItemInfoOptimization = new SnapshotOptimization( s => s.hasManagedItemInfo(), s => s.managedItemInfo, - (s, v) => s.setManagedItemInfo(v) + (s, v) => s.setManagedItemInfo(v), + false ); this._managedFilesOptimization = new SnapshotOptimization( s => s.hasManagedFiles(), s => s.managedFiles, (s, v) => s.setManagedFiles(v), + false, true ); this._managedContextsOptimization = new SnapshotOptimization( s => s.hasManagedContexts(), s => s.managedContexts, (s, v) => s.setManagedContexts(v), + false, true ); this._managedMissingOptimization = new SnapshotOptimization( s => s.hasManagedMissing(), s => s.managedMissing, (s, v) => s.setManagedMissing(v), + false, true ); - /** @type {Map} */ - this._fileTimestamps = new Map(); - /** @type {Map} */ + /** @type {StackedCacheMap} */ + this._fileTimestamps = new StackedCacheMap(); + /** @type {Map} */ this._fileHashes = new Map(); /** @type {Map} */ this._fileTshs = new Map(); - /** @type {Map} */ - this._contextTimestamps = new Map(); - /** @type {Map} */ + /** @type {StackedCacheMap} */ + this._contextTimestamps = new StackedCacheMap(); + /** @type {Map} */ this._contextHashes = new Map(); - /** @type {Map} */ + /** @type {Map} */ this._contextTshs = new Map(); /** @type {Map} */ this._managedItems = new Map(); - /** @type {AsyncQueue} */ + /** @type {AsyncQueue} */ this.fileTimestampQueue = new AsyncQueue({ name: "file timestamp", parallelism: 30, processor: this._readFileTimestamp.bind(this) }); - /** @type {AsyncQueue} */ + /** @type {AsyncQueue} */ this.fileHashQueue = new AsyncQueue({ name: "file hash", parallelism: 10, processor: this._readFileHash.bind(this) }); - /** @type {AsyncQueue} */ + /** @type {AsyncQueue} */ this.contextTimestampQueue = new AsyncQueue({ name: "context timestamp", parallelism: 2, processor: this._readContextTimestamp.bind(this) }); - /** @type {AsyncQueue} */ + /** @type {AsyncQueue} */ this.contextHashQueue = new AsyncQueue({ name: "context hash", parallelism: 2, processor: this._readContextHash.bind(this) }); - /** @type {AsyncQueue} */ + /** @type {AsyncQueue} */ + this.contextTshQueue = new AsyncQueue({ + name: "context hash and timestamp", + parallelism: 2, + processor: this._readContextTimestampAndHash.bind(this) + }); + /** @type {AsyncQueue} */ this.managedItemQueue = new AsyncQueue({ name: "managed item info", parallelism: 10, @@ -864,13 +1183,28 @@ class FileSystemInfo { parallelism: 10, processor: this._getManagedItemDirectoryInfo.bind(this) }); + const _unmanagedPaths = Array.from(unmanagedPaths); + this.unmanagedPathsWithSlash = /** @type {string[]} */ ( + _unmanagedPaths.filter(p => typeof p === "string") + ).map(p => join(fs, p, "_").slice(0, -1)); + this.unmanagedPathsRegExps = /** @type {RegExp[]} */ ( + _unmanagedPaths.filter(p => typeof p !== "string") + ); + this.managedPaths = Array.from(managedPaths); - this.managedPathsWithSlash = this.managedPaths.map(p => - join(fs, p, "_").slice(0, -1) + this.managedPathsWithSlash = /** @type {string[]} */ ( + this.managedPaths.filter(p => typeof p === "string") + ).map(p => join(fs, p, "_").slice(0, -1)); + + this.managedPathsRegExps = /** @type {RegExp[]} */ ( + this.managedPaths.filter(p => typeof p !== "string") ); this.immutablePaths = Array.from(immutablePaths); - this.immutablePathsWithSlash = this.immutablePaths.map(p => - join(fs, p, "_").slice(0, -1) + this.immutablePathsWithSlash = /** @type {string[]} */ ( + this.immutablePaths.filter(p => typeof p === "string") + ).map(p => join(fs, p, "_").slice(0, -1)); + this.immutablePathsRegExps = /** @type {RegExp[]} */ ( + this.immutablePaths.filter(p => typeof p !== "string") ); this._cachedDeprecatedFileTimestamps = undefined; @@ -887,13 +1221,18 @@ class FileSystemInfo { } logStatistics() { + const logger = /** @type {Logger} */ (this.logger); + /** + * @param {string} header header + * @param {string | undefined} message message + */ const logWhenMessage = (header, message) => { if (message) { - this.logger.log(`${header}: ${message}`); + logger.log(`${header}: ${message}`); } }; - this.logger.log(`${this._statCreatedSnapshots} new snapshots created`); - this.logger.log( + logger.log(`${this._statCreatedSnapshots} new snapshots created`); + logger.log( `${ this._statTestedSnapshotsNotCached && Math.round( @@ -905,7 +1244,7 @@ class FileSystemInfo { this._statTestedSnapshotsCached + this._statTestedSnapshotsNotCached })` ); - this.logger.log( + logger.log( `${ this._statTestedChildrenNotCached && Math.round( @@ -916,99 +1255,139 @@ class FileSystemInfo { this._statTestedChildrenCached + this._statTestedChildrenNotCached })` ); - this.logger.log(`${this._statTestedEntries} entries tested`); - this.logger.log( + logger.log(`${this._statTestedEntries} entries tested`); + logger.log( `File info in cache: ${this._fileTimestamps.size} timestamps ${this._fileHashes.size} hashes ${this._fileTshs.size} timestamp hash combinations` ); logWhenMessage( - `File timestamp snapshot optimization`, + "File timestamp snapshot optimization", this._fileTimestampsOptimization.getStatisticMessage() ); logWhenMessage( - `File hash snapshot optimization`, + "File hash snapshot optimization", this._fileHashesOptimization.getStatisticMessage() ); logWhenMessage( - `File timestamp hash combination snapshot optimization`, + "File timestamp hash combination snapshot optimization", this._fileTshsOptimization.getStatisticMessage() ); - this.logger.log( + logger.log( `Directory info in cache: ${this._contextTimestamps.size} timestamps ${this._contextHashes.size} hashes ${this._contextTshs.size} timestamp hash combinations` ); logWhenMessage( - `Directory timestamp snapshot optimization`, + "Directory timestamp snapshot optimization", this._contextTimestampsOptimization.getStatisticMessage() ); logWhenMessage( - `Directory hash snapshot optimization`, + "Directory hash snapshot optimization", this._contextHashesOptimization.getStatisticMessage() ); logWhenMessage( - `Directory timestamp hash combination snapshot optimization`, + "Directory timestamp hash combination snapshot optimization", this._contextTshsOptimization.getStatisticMessage() ); logWhenMessage( - `Missing items snapshot optimization`, + "Missing items snapshot optimization", this._missingExistenceOptimization.getStatisticMessage() ); - this.logger.log( - `Managed items info in cache: ${this._managedItems.size} items` - ); + logger.log(`Managed items info in cache: ${this._managedItems.size} items`); logWhenMessage( - `Managed items snapshot optimization`, + "Managed items snapshot optimization", this._managedItemInfoOptimization.getStatisticMessage() ); logWhenMessage( - `Managed files snapshot optimization`, + "Managed files snapshot optimization", this._managedFilesOptimization.getStatisticMessage() ); logWhenMessage( - `Managed contexts snapshot optimization`, + "Managed contexts snapshot optimization", this._managedContextsOptimization.getStatisticMessage() ); logWhenMessage( - `Managed missing snapshot optimization`, + "Managed missing snapshot optimization", this._managedMissingOptimization.getStatisticMessage() ); } + /** + * @param {string} path path + * @param {string} reason reason + * @param {any[]} args arguments + */ _log(path, reason, ...args) { const key = path + reason; - if (this._loggedPaths.has(key)) return; - this._loggedPaths.add(key); - this.logger.debug(`${path} invalidated because ${reason}`, ...args); + const loggedPaths = /** @type {LoggedPaths} */ (this._loggedPaths); + if (loggedPaths.has(key)) return; + loggedPaths.add(key); + /** @type {Logger} */ + (this.logger).debug(`${path} invalidated because ${reason}`, ...args); if (--this._remainingLogs === 0) { - this.logger.debug( + /** @type {Logger} */ + (this.logger).debug( "Logging limit has been reached and no further logging will be emitted by FileSystemInfo" ); } } + clear() { + this._remainingLogs = this.logger ? 40 : 0; + if (this._loggedPaths !== undefined) this._loggedPaths.clear(); + + this._snapshotCache = new WeakMap(); + this._fileTimestampsOptimization.clear(); + this._fileHashesOptimization.clear(); + this._fileTshsOptimization.clear(); + this._contextTimestampsOptimization.clear(); + this._contextHashesOptimization.clear(); + this._contextTshsOptimization.clear(); + this._missingExistenceOptimization.clear(); + this._managedItemInfoOptimization.clear(); + this._managedFilesOptimization.clear(); + this._managedContextsOptimization.clear(); + this._managedMissingOptimization.clear(); + this._fileTimestamps.clear(); + this._fileHashes.clear(); + this._fileTshs.clear(); + this._contextTimestamps.clear(); + this._contextHashes.clear(); + this._contextTshs.clear(); + this._managedItems.clear(); + this._managedItems.clear(); + + this._cachedDeprecatedFileTimestamps = undefined; + this._cachedDeprecatedContextTimestamps = undefined; + + this._statCreatedSnapshots = 0; + this._statTestedSnapshotsCached = 0; + this._statTestedSnapshotsNotCached = 0; + this._statTestedChildrenCached = 0; + this._statTestedChildrenNotCached = 0; + this._statTestedEntries = 0; + } + /** - * @param {Map} map timestamps + * @param {ReadonlyMap} map timestamps + * @param {boolean=} immutable if 'map' is immutable and FileSystemInfo can keep referencing it * @returns {void} */ - addFileTimestamps(map) { - for (const [path, ts] of map) { - this._fileTimestamps.set(path, ts); - } + addFileTimestamps(map, immutable) { + this._fileTimestamps.addAll(map, immutable); this._cachedDeprecatedFileTimestamps = undefined; } /** - * @param {Map} map timestamps + * @param {ReadonlyMap} map timestamps + * @param {boolean=} immutable if 'map' is immutable and FileSystemInfo can keep referencing it * @returns {void} */ - addContextTimestamps(map) { - for (const [path, ts] of map) { - this._contextTimestamps.set(path, ts); - } + addContextTimestamps(map, immutable) { + this._contextTimestamps.addAll(map, immutable); this._cachedDeprecatedContextTimestamps = undefined; } /** * @param {string} path file path - * @param {function(WebpackError=, (FileSystemInfoEntry | "ignore" | null)=): void} callback callback function + * @param {function((WebpackError | null)=, (FileSystemInfoEntry | "ignore" | null)=): void} callback callback function * @returns {void} */ getFileTimestamp(path, callback) { @@ -1019,10 +1398,36 @@ class FileSystemInfo { /** * @param {string} path context path - * @param {function(WebpackError=, (FileSystemInfoEntry | "ignore" | null)=): void} callback callback function + * @param {function((WebpackError | null)=, (ResolvedContextFileSystemInfoEntry | "ignore" | null)=): void} callback callback function * @returns {void} */ getContextTimestamp(path, callback) { + const cache = this._contextTimestamps.get(path); + if (cache !== undefined) { + if (cache === "ignore") return callback(null, "ignore"); + const resolved = getResolvedTimestamp(cache); + if (resolved !== undefined) return callback(null, resolved); + return this._resolveContextTimestamp( + /** @type {ResolvedContextFileSystemInfoEntry} */ + (cache), + callback + ); + } + this.contextTimestampQueue.add(path, (err, _entry) => { + if (err) return callback(err); + const entry = /** @type {ContextFileSystemInfoEntry} */ (_entry); + const resolved = getResolvedTimestamp(entry); + if (resolved !== undefined) return callback(null, resolved); + this._resolveContextTimestamp(entry, callback); + }); + } + + /** + * @param {string} path context path + * @param {function((WebpackError | null)=, (ContextFileSystemInfoEntry | "ignore" | null)=): void} callback callback function + * @returns {void} + */ + _getUnresolvedContextTimestamp(path, callback) { const cache = this._contextTimestamps.get(path); if (cache !== undefined) return callback(null, cache); this.contextTimestampQueue.add(path, callback); @@ -1030,7 +1435,7 @@ class FileSystemInfo { /** * @param {string} path file path - * @param {function(WebpackError=, string=): void} callback callback function + * @param {function((WebpackError | null)=, (string | null)=): void} callback callback function * @returns {void} */ getFileHash(path, callback) { @@ -1041,15 +1446,70 @@ class FileSystemInfo { /** * @param {string} path context path - * @param {function(WebpackError=, string=): void} callback callback function + * @param {function((WebpackError | null)=, string=): void} callback callback function * @returns {void} */ getContextHash(path, callback) { + const cache = this._contextHashes.get(path); + if (cache !== undefined) { + const resolved = getResolvedHash(cache); + if (resolved !== undefined) + return callback(null, /** @type {string} */ (resolved)); + return this._resolveContextHash(cache, callback); + } + this.contextHashQueue.add(path, (err, _entry) => { + if (err) return callback(err); + const entry = /** @type {ContextHash} */ (_entry); + const resolved = getResolvedHash(entry); + if (resolved !== undefined) + return callback(null, /** @type {string} */ (resolved)); + this._resolveContextHash(entry, callback); + }); + } + + /** + * @param {string} path context path + * @param {function((WebpackError | null)=, (ContextHash | null)=): void} callback callback function + * @returns {void} + */ + _getUnresolvedContextHash(path, callback) { const cache = this._contextHashes.get(path); if (cache !== undefined) return callback(null, cache); this.contextHashQueue.add(path, callback); } + /** + * @param {string} path context path + * @param {function((WebpackError | null)=, (ResolvedContextTimestampAndHash | null)=): void} callback callback function + * @returns {void} + */ + getContextTsh(path, callback) { + const cache = this._contextTshs.get(path); + if (cache !== undefined) { + const resolved = getResolvedTimestamp(cache); + if (resolved !== undefined) return callback(null, resolved); + return this._resolveContextTsh(cache, callback); + } + this.contextTshQueue.add(path, (err, _entry) => { + if (err) return callback(err); + const entry = /** @type {ContextTimestampAndHash} */ (_entry); + const resolved = getResolvedTimestamp(entry); + if (resolved !== undefined) return callback(null, resolved); + this._resolveContextTsh(entry, callback); + }); + } + + /** + * @param {string} path context path + * @param {function((WebpackError | null)=, (ContextTimestampAndHash | null)=): void} callback callback function + * @returns {void} + */ + _getUnresolvedContextTsh(path, callback) { + const cache = this._contextTshs.get(path); + if (cache !== undefined) return callback(null, cache); + this.contextTshQueue.add(path, callback); + } + _createBuildDependenciesResolvers() { const resolveContext = createResolver({ resolveToContext: true, @@ -1059,29 +1519,34 @@ class FileSystemInfo { const resolveCjs = createResolver({ extensions: [".js", ".json", ".node"], conditionNames: ["require", "node"], + exportsFields: ["exports"], + fileSystem: this.fs + }); + const resolveCjsAsChild = createResolver({ + extensions: [".js", ".json", ".node"], + conditionNames: ["require", "node"], + exportsFields: [], fileSystem: this.fs }); const resolveEsm = createResolver({ extensions: [".js", ".json", ".node"], fullySpecified: true, conditionNames: ["import", "node"], + exportsFields: ["exports"], fileSystem: this.fs }); - return { resolveContext, resolveEsm, resolveCjs }; + return { resolveContext, resolveEsm, resolveCjs, resolveCjsAsChild }; } /** * @param {string} context context directory * @param {Iterable} deps dependencies - * @param {function(Error=, ResolveBuildDependenciesResult=): void} callback callback function + * @param {function((Error | null)=, ResolveBuildDependenciesResult=): void} callback callback function * @returns {void} */ resolveBuildDependencies(context, deps, callback) { - const { - resolveContext, - resolveEsm, - resolveCjs - } = this._createBuildDependenciesResolvers(); + const { resolveContext, resolveEsm, resolveCjs, resolveCjsAsChild } = + this._createBuildDependenciesResolvers(); /** @type {Set} */ const files = new Set(); @@ -1099,7 +1564,7 @@ class FileSystemInfo { const resolveDirectories = new Set(); /** @type {Set} */ const resolveMissing = new Set(); - /** @type {Map} */ + /** @type {Map} */ const resolveResults = new Map(); const invalidResolveResults = new Set(); const resolverContext = { @@ -1107,87 +1572,176 @@ class FileSystemInfo { contextDependencies: resolveDirectories, missingDependencies: resolveMissing }; + /** + * @param {undefined | boolean | string} expected expected result + * @returns {string} expected result + */ + const expectedToString = expected => + expected ? ` (expected ${expected})` : ""; + /** @typedef {{ type: JobType, context: string | undefined, path: string, issuer: Job | undefined, expected: undefined | boolean | string }} Job */ + + /** + * @param {Job} job job + * @returns {`resolve commonjs file ${string}${string}`|`resolve esm file ${string}${string}`|`resolve esm ${string}${string}`|`resolve directory ${string}`|`file ${string}`|`unknown ${string} ${string}`|`resolve commonjs ${string}${string}`|`directory ${string}`|`file dependencies ${string}`|`directory dependencies ${string}`} result + */ + const jobToString = job => { + switch (job.type) { + case RBDT_RESOLVE_CJS: + return `resolve commonjs ${job.path}${expectedToString( + job.expected + )}`; + case RBDT_RESOLVE_ESM: + return `resolve esm ${job.path}${expectedToString(job.expected)}`; + case RBDT_RESOLVE_DIRECTORY: + return `resolve directory ${job.path}`; + case RBDT_RESOLVE_CJS_FILE: + return `resolve commonjs file ${job.path}${expectedToString( + job.expected + )}`; + case RBDT_RESOLVE_ESM_FILE: + return `resolve esm file ${job.path}${expectedToString( + job.expected + )}`; + case RBDT_DIRECTORY: + return `directory ${job.path}`; + case RBDT_FILE: + return `file ${job.path}`; + case RBDT_DIRECTORY_DEPENDENCIES: + return `directory dependencies ${job.path}`; + case RBDT_FILE_DEPENDENCIES: + return `file dependencies ${job.path}`; + } + return `unknown ${job.type} ${job.path}`; + }; + /** + * @param {Job} job job + * @returns {string} string value + */ + const pathToString = job => { + let result = ` at ${jobToString(job)}`; + /** @type {Job | undefined} */ + (job) = job.issuer; + while (job !== undefined) { + result += `\n at ${jobToString(job)}`; + job = /** @type {Job} */ (job.issuer); + } + return result; + }; + const logger = /** @type {Logger} */ (this.logger); processAsyncTree( - Array.from(deps, dep => ({ - type: RBDT_RESOLVE_CJS, - context, - path: dep, - expected: undefined - })), + Array.from( + deps, + dep => + /** @type {Job} */ ({ + type: RBDT_RESOLVE_CJS, + context, + path: dep, + expected: undefined, + issuer: undefined + }) + ), 20, - ({ type, context, path, expected }, push, callback) => { + (job, push, callback) => { + const { type, context, path, expected } = job; + /** + * @param {string} path path + * @returns {void} + */ const resolveDirectory = path => { const key = `d\n${context}\n${path}`; if (resolveResults.has(key)) { return callback(); } resolveResults.set(key, undefined); - resolveContext(context, path, resolverContext, (err, result) => { - if (err) { - invalidResolveResults.add(key); - if ( - err.code === "ENOENT" || - err.code === "UNDECLARED_DEPENDENCY" - ) { - return callback(); + resolveContext( + /** @type {string} */ (context), + path, + resolverContext, + (err, _, result) => { + if (err) { + if (expected === false) { + resolveResults.set(key, false); + return callback(); + } + invalidResolveResults.add(key); + err.message += `\nwhile resolving '${path}' in ${context} to a directory`; + return callback(err); } - err.message += `\nwhile resolving '${path}' in ${context} to a directory`; - return callback(err); + const resultPath = /** @type {ResolveRequest} */ (result).path; + resolveResults.set(key, resultPath); + push({ + type: RBDT_DIRECTORY, + context: undefined, + path: /** @type {string} */ (resultPath), + expected: undefined, + issuer: job + }); + callback(); } - resolveResults.set(key, result); - push({ - type: RBDT_DIRECTORY, - context: undefined, - path: result, - expected: undefined - }); - callback(); - }); + ); }; + /** + * @param {string} path path + * @param {("f" | "c" | "e")=} symbol symbol + * @param {(ResolveFunctionAsync)=} resolve resolve fn + * @returns {void} + */ const resolveFile = (path, symbol, resolve) => { const key = `${symbol}\n${context}\n${path}`; if (resolveResults.has(key)) { return callback(); } resolveResults.set(key, undefined); - resolve(context, path, resolverContext, (err, result) => { - if (expected) { - if (result === expected) { - resolveResults.set(key, result); + /** @type {ResolveFunctionAsync} */ + (resolve)( + /** @type {string} */ (context), + path, + resolverContext, + (err, _, result) => { + if (typeof expected === "string") { + if (!err && result && result.path === expected) { + resolveResults.set(key, result.path); + } else { + invalidResolveResults.add(key); + logger.warn( + `Resolving '${path}' in ${context} for build dependencies doesn't lead to expected result '${expected}', but to '${ + err || (result && result.path) + }' instead. Resolving dependencies are ignored for this path.\n${pathToString( + job + )}` + ); + } } else { - invalidResolveResults.add(key); - this.logger.debug( - `Resolving '${path}' in ${context} for build dependencies doesn't lead to expected result '${expected}', but to '${result}' instead. Resolving dependencies are ignored for this path.` - ); - } - } else { - if (err) { - invalidResolveResults.add(key); - if ( - err.code === "ENOENT" || - err.code === "UNDECLARED_DEPENDENCY" - ) { - return callback(); + if (err) { + if (expected === false) { + resolveResults.set(key, false); + return callback(); + } + invalidResolveResults.add(key); + err.message += `\nwhile resolving '${path}' in ${context} as file\n${pathToString( + job + )}`; + return callback(err); } - err.message += `\nwhile resolving '${path}' in ${context} as file`; - return callback(err); + const resultPath = /** @type {ResolveRequest} */ (result).path; + resolveResults.set(key, resultPath); + push({ + type: RBDT_FILE, + context: undefined, + path: /** @type {string} */ (resultPath), + expected: undefined, + issuer: job + }); } - resolveResults.set(key, result); - push({ - type: RBDT_FILE, - context: undefined, - path: result, - expected: undefined - }); + callback(); } - callback(); - }); + ); }; switch (type) { case RBDT_RESOLVE_CJS: { const isDirectory = /[\\/]$/.test(path); if (isDirectory) { - resolveDirectory(path.slice(0, path.length - 1)); + resolveDirectory(path.slice(0, -1)); } else { resolveFile(path, "f", resolveCjs); } @@ -1196,7 +1750,7 @@ class FileSystemInfo { case RBDT_RESOLVE_ESM: { const isDirectory = /[\\/]$/.test(path); if (isDirectory) { - resolveDirectory(path.slice(0, path.length - 1)); + resolveDirectory(path.slice(0, -1)); } else { resolveFile(path); } @@ -1210,6 +1764,10 @@ class FileSystemInfo { resolveFile(path, "f", resolveCjs); break; } + case RBDT_RESOLVE_CJS_FILE_AS_CHILD: { + resolveFile(path, "c", resolveCjsAsChild); + break; + } case RBDT_RESOLVE_ESM_FILE: { resolveFile(path, "e", resolveEsm); break; @@ -1220,7 +1778,8 @@ class FileSystemInfo { break; } files.add(path); - this.fs.realpath(path, (err, _realPath) => { + /** @type {NonNullable} */ + (this.fs.realpath)(path, (err, _realPath) => { if (err) return callback(err); const realPath = /** @type {string} */ (_realPath); if (realPath !== path) { @@ -1233,7 +1792,8 @@ class FileSystemInfo { type: RBDT_FILE_DEPENDENCIES, context: undefined, path: realPath, - expected: undefined + expected: undefined, + issuer: job }); callback(); }); @@ -1245,7 +1805,8 @@ class FileSystemInfo { break; } directories.add(path); - this.fs.realpath(path, (err, _realPath) => { + /** @type {NonNullable} */ + (this.fs.realpath)(path, (err, _realPath) => { if (err) return callback(err); const realPath = /** @type {string} */ (_realPath); if (realPath !== path) { @@ -1258,7 +1819,8 @@ class FileSystemInfo { type: RBDT_DIRECTORY_DEPENDENCIES, context: undefined, path: realPath, - expected: undefined + expected: undefined, + issuer: job }); callback(); }); @@ -1271,29 +1833,49 @@ class FileSystemInfo { break; } // Check commonjs cache for the module - /** @type {NodeModule} */ + /** @type {NodeModule | undefined} */ const module = require.cache[path]; if (module && Array.isArray(module.children)) { children: for (const child of module.children) { - let childPath = child.filename; + const childPath = child.filename; if (childPath) { push({ type: RBDT_FILE, context: undefined, path: childPath, - expected: undefined + expected: undefined, + issuer: job }); const context = dirname(this.fs, path); for (const modulePath of module.paths) { if (childPath.startsWith(modulePath)) { - let request = childPath.slice(modulePath.length + 1); + const subPath = childPath.slice(modulePath.length + 1); + const packageMatch = /^(@[^\\/]+[\\/])[^\\/]+/.exec( + subPath + ); + if (packageMatch) { + push({ + type: RBDT_FILE, + context: undefined, + path: `${ + modulePath + + childPath[modulePath.length] + + packageMatch[0] + + childPath[modulePath.length] + }package.json`, + expected: false, + issuer: job + }); + } + let request = subPath.replace(/\\/g, "/"); if (request.endsWith(".js")) request = request.slice(0, -3); push({ - type: RBDT_RESOLVE_CJS_FILE, + type: RBDT_RESOLVE_CJS_FILE_AS_CHILD, context, path: request, - expected: child.filename + expected: child.filename, + issuer: job }); continue children; } @@ -1301,18 +1883,21 @@ class FileSystemInfo { let request = relative(this.fs, context, childPath); if (request.endsWith(".js")) request = request.slice(0, -3); request = request.replace(/\\/g, "/"); - if (!request.startsWith("../")) request = `./${request}`; + if (!request.startsWith("../") && !isAbsolute(request)) { + request = `./${request}`; + } push({ type: RBDT_RESOLVE_CJS_FILE, context, path: request, - expected: child.filename + expected: child.filename, + issuer: job }); } } } else if (supportsEsm && /\.m?js$/.test(path)) { if (!this._warnAboutExperimentalEsmTracking) { - this.logger.info( + logger.log( "Node.js doesn't offer a (nice) way to introspect the ESM dependency graph yet.\n" + "Until a full solution is available webpack uses an experimental ESM tracking based on parsing.\n" + "As best effort webpack parses the ESM files to guess dependencies. But this can lead to expensive and incorrect tracking." @@ -1325,67 +1910,71 @@ class FileSystemInfo { if (err) return callback(err); try { const context = dirname(this.fs, path); - const source = content.toString(); + const source = /** @type {Buffer} */ (content).toString(); const [imports] = lexer.parse(source); for (const imp of imports) { try { let dependency; if (imp.d === -1) { // import ... from "..." - dependency = JSON.parse( + dependency = parseString( source.substring(imp.s - 1, imp.e + 1) ); } else if (imp.d > -1) { // import() - let expr = source.substring(imp.s, imp.e).trim(); - if (expr[0] === "'") - expr = `"${expr - .slice(1, -1) - .replace(/"/g, '\\"')}"`; - dependency = JSON.parse(expr); + const expr = source.substring(imp.s, imp.e).trim(); + dependency = parseString(expr); } else { // e.g. import.meta continue; } + + // we should not track Node.js build dependencies + if (dependency.startsWith("node:")) continue; + if (builtinModules.has(dependency)) continue; + push({ type: RBDT_RESOLVE_ESM_FILE, context, path: dependency, - expected: undefined + expected: imp.d > -1 ? false : undefined, + issuer: job }); - } catch (e) { - this.logger.warn( + } catch (err1) { + logger.warn( `Parsing of ${path} for build dependencies failed at 'import(${source.substring( imp.s, imp.e )})'.\n` + "Build dependencies behind this expression are ignored and might cause incorrect cache invalidation." ); - this.logger.debug(e.stack); + logger.debug(pathToString(job)); + logger.debug(/** @type {Error} */ (err1).stack); } } - } catch (e) { - this.logger.warn( + } catch (err2) { + logger.warn( `Parsing of ${path} for build dependencies failed and all dependencies of this file are ignored, which might cause incorrect cache invalidation..` ); - this.logger.debug(e.stack); + logger.debug(pathToString(job)); + logger.debug(/** @type {Error} */ (err2).stack); } process.nextTick(callback); }); }, callback); break; } else { - this.logger.log( + logger.log( `Assuming ${path} has no dependencies as we were unable to assign it to any module system.` ); + logger.debug(pathToString(job)); } process.nextTick(callback); break; } case RBDT_DIRECTORY_DEPENDENCIES: { - const match = /(^.+[\\/]node_modules[\\/](?:@[^\\/]+[\\/])?[^\\/]+)/.exec( - path - ); + const match = + /(^.+[\\/]node_modules[\\/](?:@[^\\/]+[\\/])?[^\\/]+)/.exec(path); const packagePath = match ? match[1] : path; const packageJson = join(this.fs, packagePath, "package.json"); this.fs.readFile(packageJson, (err, content) => { @@ -1398,7 +1987,8 @@ class FileSystemInfo { type: RBDT_DIRECTORY_DEPENDENCIES, context: undefined, path: parent, - expected: undefined + expected: undefined, + issuer: job }); } callback(); @@ -1409,21 +1999,39 @@ class FileSystemInfo { resolveFiles.add(packageJson); let packageData; try { - packageData = JSON.parse(content.toString("utf-8")); - } catch (e) { - return callback(e); + packageData = JSON.parse( + /** @type {Buffer} */ (content).toString("utf-8") + ); + } catch (parseErr) { + return callback(/** @type {Error} */ (parseErr)); } const depsObject = packageData.dependencies; + const optionalDepsObject = packageData.optionalDependencies; + const allDeps = new Set(); + const optionalDeps = new Set(); if (typeof depsObject === "object" && depsObject) { for (const dep of Object.keys(depsObject)) { - push({ - type: RBDT_RESOLVE_DIRECTORY, - context: packagePath, - path: dep, - expected: undefined - }); + allDeps.add(dep); + } + } + if ( + typeof optionalDepsObject === "object" && + optionalDepsObject + ) { + for (const dep of Object.keys(optionalDepsObject)) { + allDeps.add(dep); + optionalDeps.add(dep); } } + for (const dep of allDeps) { + push({ + type: RBDT_RESOLVE_DIRECTORY, + context: packagePath, + path: dep, + expected: !optionalDeps.has(dep), + issuer: job + }); + } callback(); }); break; @@ -1451,16 +2059,13 @@ class FileSystemInfo { } /** - * @param {Map} resolveResults results from resolving - * @param {function(Error=, boolean=): void} callback callback with true when resolveResults resolve the same way + * @param {Map} resolveResults results from resolving + * @param {function((Error | null)=, boolean=): void} callback callback with true when resolveResults resolve the same way * @returns {void} */ checkResolveResultsValid(resolveResults, callback) { - const { - resolveCjs, - resolveEsm, - resolveContext - } = this._createBuildDependenciesResolvers(); + const { resolveCjs, resolveCjsAsChild, resolveEsm, resolveContext } = + this._createBuildDependenciesResolvers(); asyncLib.eachLimit( resolveResults, 20, @@ -1468,23 +2073,42 @@ class FileSystemInfo { const [type, context, path] = key.split("\n"); switch (type) { case "d": - resolveContext(context, path, {}, (err, result) => { + resolveContext(context, path, {}, (err, _, result) => { + if (expectedResult === false) + return callback(err ? undefined : INVALID); if (err) return callback(err); - if (result !== expectedResult) return callback(INVALID); + const resultPath = /** @type {ResolveRequest} */ (result).path; + if (resultPath !== expectedResult) return callback(INVALID); callback(); }); break; case "f": - resolveCjs(context, path, {}, (err, result) => { + resolveCjs(context, path, {}, (err, _, result) => { + if (expectedResult === false) + return callback(err ? undefined : INVALID); if (err) return callback(err); - if (result !== expectedResult) return callback(INVALID); + const resultPath = /** @type {ResolveRequest} */ (result).path; + if (resultPath !== expectedResult) return callback(INVALID); + callback(); + }); + break; + case "c": + resolveCjsAsChild(context, path, {}, (err, _, result) => { + if (expectedResult === false) + return callback(err ? undefined : INVALID); + if (err) return callback(err); + const resultPath = /** @type {ResolveRequest} */ (result).path; + if (resultPath !== expectedResult) return callback(INVALID); callback(); }); break; case "e": - resolveEsm(context, path, {}, (err, result) => { + resolveEsm(context, path, {}, (err, _, result) => { + if (expectedResult === false) + return callback(err ? undefined : INVALID); if (err) return callback(err); - if (result !== expectedResult) return callback(INVALID); + const resultPath = /** @type {ResolveRequest} */ (result).path; + if (resultPath !== expectedResult) return callback(INVALID); callback(); }); break; @@ -1510,59 +2134,42 @@ class FileSystemInfo { } /** - * - * @param {number} startTime when processing the files has started - * @param {Iterable} files all files - * @param {Iterable} directories all directories - * @param {Iterable} missing all missing files or directories - * @param {Object} options options object (for future extensions) - * @param {boolean=} options.hash should use hash to snapshot - * @param {boolean=} options.timestamp should use timestamp to snapshot - * @param {function(WebpackError=, Snapshot=): void} callback callback function + * @param {number | null | undefined} startTime when processing the files has started + * @param {Iterable | null} files all files + * @param {Iterable | null} directories all directories + * @param {Iterable | null} missing all missing files or directories + * @param {SnapshotOptions | null | undefined} options options object (for future extensions) + * @param {function(WebpackError | null, Snapshot | null): void} callback callback function * @returns {void} */ createSnapshot(startTime, files, directories, missing, options, callback) { - /** @type {Map} */ + /** @type {FileTimestamps} */ const fileTimestamps = new Map(); - /** @type {Map} */ + /** @type {FileHashes} */ const fileHashes = new Map(); - /** @type {Map} */ + /** @type {FileTshs} */ const fileTshs = new Map(); - /** @type {Map} */ + /** @type {ContextTimestamps} */ const contextTimestamps = new Map(); - /** @type {Map} */ + /** @type {ContextHashes} */ const contextHashes = new Map(); - /** @type {Map} */ + /** @type {ContextTshs} */ const contextTshs = new Map(); - /** @type {Map} */ + /** @type {MissingExistence} */ const missingExistence = new Map(); - /** @type {Map} */ + /** @type {ManagedItemInfo} */ const managedItemInfo = new Map(); - /** @type {Set} */ + /** @type {ManagedFiles} */ const managedFiles = new Set(); - /** @type {Set} */ + /** @type {ManagedContexts} */ const managedContexts = new Set(); - /** @type {Set} */ + /** @type {ManagedMissing} */ const managedMissing = new Set(); - /** @type {Set} */ + /** @type {Children} */ const children = new Set(); - /** @type {Set} */ - let unsharedFileTimestamps; - /** @type {Set} */ - let unsharedFileHashes; - /** @type {Set} */ - let unsharedFileTshs; - /** @type {Set} */ - let unsharedContextTimestamps; - /** @type {Set} */ - let unsharedContextHashes; - /** @type {Set} */ - let unsharedContextTshs; - /** @type {Set} */ - let unsharedMissingExistence; - /** @type {Set} */ - let unsharedManagedItemInfo; + const snapshot = new Snapshot(); + if (startTime) snapshot.setStartTime(startTime); /** @type {Set} */ const managedItems = new Set(); @@ -1573,99 +2180,41 @@ class FileSystemInfo { let jobs = 1; const jobDone = () => { if (--jobs === 0) { - const snapshot = new Snapshot(); - if (startTime) snapshot.setStartTime(startTime); if (fileTimestamps.size !== 0) { snapshot.setFileTimestamps(fileTimestamps); - this._fileTimestampsOptimization.storeUnsharedSnapshot( - snapshot, - unsharedFileTimestamps - ); } if (fileHashes.size !== 0) { snapshot.setFileHashes(fileHashes); - this._fileHashesOptimization.storeUnsharedSnapshot( - snapshot, - unsharedFileHashes - ); } if (fileTshs.size !== 0) { snapshot.setFileTshs(fileTshs); - this._fileTshsOptimization.storeUnsharedSnapshot( - snapshot, - unsharedFileTshs - ); } if (contextTimestamps.size !== 0) { snapshot.setContextTimestamps(contextTimestamps); - this._contextTimestampsOptimization.storeUnsharedSnapshot( - snapshot, - unsharedContextTimestamps - ); } if (contextHashes.size !== 0) { snapshot.setContextHashes(contextHashes); - this._contextHashesOptimization.storeUnsharedSnapshot( - snapshot, - unsharedContextHashes - ); } if (contextTshs.size !== 0) { snapshot.setContextTshs(contextTshs); - this._contextTshsOptimization.storeUnsharedSnapshot( - snapshot, - unsharedContextTshs - ); } if (missingExistence.size !== 0) { snapshot.setMissingExistence(missingExistence); - this._missingExistenceOptimization.storeUnsharedSnapshot( - snapshot, - unsharedMissingExistence - ); } if (managedItemInfo.size !== 0) { snapshot.setManagedItemInfo(managedItemInfo); - this._managedItemInfoOptimization.storeUnsharedSnapshot( - snapshot, - unsharedManagedItemInfo - ); } - const unsharedManagedFiles = this._managedFilesOptimization.optimize( - managedFiles, - undefined, - children - ); + this._managedFilesOptimization.optimize(snapshot, managedFiles); if (managedFiles.size !== 0) { snapshot.setManagedFiles(managedFiles); - this._managedFilesOptimization.storeUnsharedSnapshot( - snapshot, - unsharedManagedFiles - ); } - const unsharedManagedContexts = this._managedContextsOptimization.optimize( - managedContexts, - undefined, - children - ); + this._managedContextsOptimization.optimize(snapshot, managedContexts); if (managedContexts.size !== 0) { snapshot.setManagedContexts(managedContexts); - this._managedContextsOptimization.storeUnsharedSnapshot( - snapshot, - unsharedManagedContexts - ); } - const unsharedManagedMissing = this._managedMissingOptimization.optimize( - managedMissing, - undefined, - children - ); + this._managedMissingOptimization.optimize(snapshot, managedMissing); if (managedMissing.size !== 0) { snapshot.setManagedMissing(managedMissing); - this._managedMissingOptimization.storeUnsharedSnapshot( - snapshot, - unsharedManagedMissing - ); } if (children.size !== 0) { snapshot.setChildren(children); @@ -1683,13 +2232,41 @@ class FileSystemInfo { callback(null, null); } }; + /** + * @param {string} path path + * @param {Set} managedSet managed set + * @returns {boolean} true when managed + */ const checkManaged = (path, managedSet) => { + for (const unmanagedPath of this.unmanagedPathsRegExps) { + if (unmanagedPath.test(path)) return false; + } + for (const unmanagedPath of this.unmanagedPathsWithSlash) { + if (path.startsWith(unmanagedPath)) return false; + } + for (const immutablePath of this.immutablePathsRegExps) { + if (immutablePath.test(path)) { + managedSet.add(path); + return true; + } + } for (const immutablePath of this.immutablePathsWithSlash) { if (path.startsWith(immutablePath)) { managedSet.add(path); return true; } } + for (const managedPath of this.managedPathsRegExps) { + const match = managedPath.exec(path); + if (match) { + const managedItem = getManagedItem(match[1], path); + if (managedItem) { + managedItems.add(managedItem); + managedSet.add(path); + return true; + } + } + } for (const managedPath of this.managedPathsWithSlash) { if (path.startsWith(managedPath)) { const managedItem = getManagedItem(managedPath, path); @@ -1702,6 +2279,11 @@ class FileSystemInfo { } return false; }; + /** + * @param {Iterable} items items + * @param {Set} managedSet managed set + * @returns {Set} result + */ const captureNonManaged = (items, managedSet) => { const capturedItems = new Set(); for (const path of items) { @@ -1709,15 +2291,13 @@ class FileSystemInfo { } return capturedItems; }; - if (files) { - const capturedFiles = captureNonManaged(files, managedFiles); + /** + * @param {Set} capturedFiles captured files + */ + const processCapturedFiles = capturedFiles => { switch (mode) { case 3: - unsharedFileTshs = this._fileTshsOptimization.optimize( - capturedFiles, - undefined, - children - ); + this._fileTshsOptimization.optimize(snapshot, capturedFiles); for (const path of capturedFiles) { const cache = this._fileTshs.get(path); if (cache !== undefined) { @@ -1733,7 +2313,7 @@ class FileSystemInfo { } jobError(); } else { - fileTshs.set(path, entry); + fileTshs.set(path, /** @type {TimestampAndHash} */ (entry)); jobDone(); } }); @@ -1741,11 +2321,7 @@ class FileSystemInfo { } break; case 2: - unsharedFileHashes = this._fileHashesOptimization.optimize( - capturedFiles, - undefined, - children - ); + this._fileHashesOptimization.optimize(snapshot, capturedFiles); for (const path of capturedFiles) { const cache = this._fileHashes.get(path); if (cache !== undefined) { @@ -1761,7 +2337,7 @@ class FileSystemInfo { } jobError(); } else { - fileHashes.set(path, entry); + fileHashes.set(path, /** @type {string} */ (entry)); jobDone(); } }); @@ -1769,11 +2345,7 @@ class FileSystemInfo { } break; case 1: - unsharedFileTimestamps = this._fileTimestampsOptimization.optimize( - capturedFiles, - startTime, - children - ); + this._fileTimestampsOptimization.optimize(snapshot, capturedFiles); for (const path of capturedFiles) { const cache = this._fileTimestamps.get(path); if (cache !== undefined) { @@ -1791,7 +2363,11 @@ class FileSystemInfo { } jobError(); } else { - fileTimestamps.set(path, entry); + fileTimestamps.set( + path, + /** @type {FileSystemInfoEntry} */ + (entry) + ); jobDone(); } }); @@ -1799,26 +2375,34 @@ class FileSystemInfo { } break; } + }; + if (files) { + processCapturedFiles(captureNonManaged(files, managedFiles)); } - if (directories) { - const capturedDirectories = captureNonManaged( - directories, - managedContexts - ); + /** + * @param {Set} capturedDirectories captured directories + */ + const processCapturedDirectories = capturedDirectories => { switch (mode) { case 3: - unsharedContextTshs = this._contextTshsOptimization.optimize( - capturedDirectories, - undefined, - children - ); + this._contextTshsOptimization.optimize(snapshot, capturedDirectories); for (const path of capturedDirectories) { const cache = this._contextTshs.get(path); - if (cache !== undefined) { - contextTshs.set(path, cache); + /** @type {ResolvedContextTimestampAndHash | null | undefined} */ + let resolved; + if ( + cache !== undefined && + (resolved = getResolvedTimestamp(cache)) !== undefined + ) { + contextTshs.set(path, resolved); } else { jobs++; - this._getContextTimestampAndHash(path, (err, entry) => { + /** + * @param {(WebpackError | null)=} err error + * @param {(ResolvedContextTimestampAndHash | null)=} entry entry + * @returns {void} + */ + const callback = (err, entry) => { if (err) { if (this.logger) { this.logger.debug( @@ -1827,26 +2411,42 @@ class FileSystemInfo { } jobError(); } else { - contextTshs.set(path, entry); + contextTshs.set( + path, + /** @type {ResolvedContextTimestampAndHash | null} */ + (entry) + ); jobDone(); } - }); + }; + if (cache !== undefined) { + this._resolveContextTsh(cache, callback); + } else { + this.getContextTsh(path, callback); + } } } break; case 2: - unsharedContextHashes = this._contextHashesOptimization.optimize( - capturedDirectories, - undefined, - children + this._contextHashesOptimization.optimize( + snapshot, + capturedDirectories ); for (const path of capturedDirectories) { const cache = this._contextHashes.get(path); - if (cache !== undefined) { - contextHashes.set(path, cache); + let resolved; + if ( + cache !== undefined && + (resolved = getResolvedHash(cache)) !== undefined + ) { + contextHashes.set(path, resolved); } else { jobs++; - this.contextHashQueue.add(path, (err, entry) => { + /** + * @param {(WebpackError | null)=} err err + * @param {string=} entry entry + */ + const callback = (err, entry) => { if (err) { if (this.logger) { this.logger.debug( @@ -1855,28 +2455,40 @@ class FileSystemInfo { } jobError(); } else { - contextHashes.set(path, entry); + contextHashes.set(path, /** @type {string} */ (entry)); jobDone(); } - }); + }; + if (cache !== undefined) { + this._resolveContextHash(cache, callback); + } else { + this.getContextHash(path, callback); + } } } break; case 1: - unsharedContextTimestamps = this._contextTimestampsOptimization.optimize( - capturedDirectories, - startTime, - children + this._contextTimestampsOptimization.optimize( + snapshot, + capturedDirectories ); for (const path of capturedDirectories) { const cache = this._contextTimestamps.get(path); - if (cache !== undefined) { - if (cache !== "ignore") { - contextTimestamps.set(path, cache); - } + if (cache === "ignore") continue; + let resolved; + if ( + cache !== undefined && + (resolved = getResolvedTimestamp(cache)) !== undefined + ) { + contextTimestamps.set(path, resolved); } else { jobs++; - this.contextTimestampQueue.add(path, (err, entry) => { + /** + * @param {(Error | null)=} err error + * @param {(FileSystemInfoEntry | "ignore" | null)=} entry entry + * @returns {void} + */ + const callback = (err, entry) => { if (err) { if (this.logger) { this.logger.debug( @@ -1885,27 +2497,43 @@ class FileSystemInfo { } jobError(); } else { - contextTimestamps.set(path, entry); + contextTimestamps.set( + path, + /** @type {FileSystemInfoEntry | null} */ + (entry) + ); jobDone(); } - }); + }; + if (cache !== undefined) { + this._resolveContextTimestamp( + /** @type {ContextFileSystemInfoEntry} */ + (cache), + callback + ); + } else { + this.getContextTimestamp(path, callback); + } } } break; } - } - if (missing) { - const capturedMissing = captureNonManaged(missing, managedMissing); - unsharedMissingExistence = this._missingExistenceOptimization.optimize( - capturedMissing, - startTime, - children + }; + if (directories) { + processCapturedDirectories( + captureNonManaged(directories, managedContexts) ); + } + /** + * @param {Set} capturedMissing captured missing + */ + const processCapturedMissing = capturedMissing => { + this._missingExistenceOptimization.optimize(snapshot, capturedMissing); for (const path of capturedMissing) { const cache = this._fileTimestamps.get(path); if (cache !== undefined) { if (cache !== "ignore") { - missingExistence.set(path, toExistence(cache)); + missingExistence.set(path, Boolean(cache)); } } else { jobs++; @@ -1918,21 +2546,25 @@ class FileSystemInfo { } jobError(); } else { - missingExistence.set(path, toExistence(entry)); + missingExistence.set(path, Boolean(entry)); jobDone(); } }); } } + }; + if (missing) { + processCapturedMissing(captureNonManaged(missing, managedMissing)); } - unsharedManagedItemInfo = this._managedItemInfoOptimization.optimize( - managedItems, - undefined, - children - ); + this._managedItemInfoOptimization.optimize(snapshot, managedItems); for (const path of managedItems) { const cache = this._managedItems.get(path); if (cache !== undefined) { + if (!cache.startsWith("*")) { + managedFiles.add(join(this.fs, path, "package.json")); + } else if (cache === "*nested") { + managedMissing.add(join(this.fs, path, "package.json")); + } managedItemInfo.set(path, cache); } else { jobs++; @@ -1944,9 +2576,32 @@ class FileSystemInfo { ); } jobError(); - } else { + } else if (entry) { + if (!entry.startsWith("*")) { + managedFiles.add(join(this.fs, path, "package.json")); + } else if (cache === "*nested") { + managedMissing.add(join(this.fs, path, "package.json")); + } managedItemInfo.set(path, entry); jobDone(); + } else { + // Fallback to normal snapshotting + /** + * @param {Set} set set + * @param {function(Set): void} fn fn + */ + const process = (set, fn) => { + if (set.size === 0) return; + const captured = new Set(); + for (const file of set) { + if (file.startsWith(path)) captured.add(file); + } + if (captured.size > 0) fn(captured); + }; + process(managedFiles, processCapturedFiles); + process(managedContexts, processCapturedDirectories); + process(managedMissing, processCapturedMissing); + jobDone(); } }); } @@ -1961,10 +2616,20 @@ class FileSystemInfo { */ mergeSnapshots(snapshot1, snapshot2) { const snapshot = new Snapshot(); - if (snapshot1.hasStartTime() && snapshot2.hasStartTime()) - snapshot.setStartTime(Math.min(snapshot1.startTime, snapshot2.startTime)); - else if (snapshot2.hasStartTime()) snapshot.startTime = snapshot2.startTime; - else if (snapshot1.hasStartTime()) snapshot.startTime = snapshot1.startTime; + if (snapshot1.hasStartTime() && snapshot2.hasStartTime()) { + snapshot.setStartTime( + Math.min( + /** @type {NonNullable} */ + (snapshot1.startTime), + /** @type {NonNullable} */ + (snapshot2.startTime) + ) + ); + } else if (snapshot2.hasStartTime()) { + snapshot.startTime = snapshot2.startTime; + } else if (snapshot1.hasStartTime()) { + snapshot.startTime = snapshot1.startTime; + } if (snapshot1.hasFileTimestamps() || snapshot2.hasFileTimestamps()) { snapshot.setFileTimestamps( mergeMaps(snapshot1.fileTimestamps, snapshot2.fileTimestamps) @@ -2032,7 +2697,7 @@ class FileSystemInfo { /** * @param {Snapshot} snapshot the snapshot made - * @param {function(WebpackError=, boolean=): void} callback callback function + * @param {function((WebpackError | null)=, boolean=): void} callback callback function * @returns {void} */ checkSnapshotValid(snapshot, callback) { @@ -2052,12 +2717,12 @@ class FileSystemInfo { /** * @param {Snapshot} snapshot the snapshot made - * @param {function(WebpackError=, boolean=): void} callback callback function + * @param {function((WebpackError | null)=, boolean=): void} callback callback function * @returns {void} */ _checkSnapshotValidNoCache(snapshot, callback) { /** @type {number | undefined} */ - let startTime = undefined; + let startTime; if (snapshot.hasStartTime()) { startTime = snapshot.startTime; } @@ -2076,23 +2741,27 @@ class FileSystemInfo { callback(null, false); } }; + /** + * @param {string} path path + * @param {WebpackError} err err + */ const invalidWithError = (path, err) => { if (this._remainingLogs > 0) { - this._log(path, `error occurred: %s`, err); + this._log(path, "error occurred: %s", err); } invalid(); }; /** * @param {string} path file path - * @param {string} current current hash - * @param {string} snap snapshot hash + * @param {string | null} current current hash + * @param {string | null} snap snapshot hash * @returns {boolean} true, if ok */ const checkHash = (path, current, snap) => { if (current !== snap) { // If hash differ it's invalid if (this._remainingLogs > 0) { - this._log(path, `hashes differ (%s != %s)`, current, snap); + this._log(path, "hashes differ (%s != %s)", current, snap); } return false; } @@ -2120,66 +2789,83 @@ class FileSystemInfo { }; /** * @param {string} path file path - * @param {FileSystemInfoEntry} current current entry - * @param {FileSystemInfoEntry} snap entry from snapshot + * @param {FileSystemInfoEntry | null} c current entry + * @param {FileSystemInfoEntry | null} s entry from snapshot * @param {boolean} log log reason * @returns {boolean} true, if ok */ - const checkFile = (path, current, snap, log = true) => { - if (current === snap) return true; - if (!current !== !snap) { - // If existence of item differs - // it's invalid - if (log && this._remainingLogs > 0) { - this._log( - path, - current ? "it didn't exist before" : "it does no longer exist" - ); - } - return false; - } - if (current) { + const checkFile = (path, c, s, log = true) => { + if (c === s) return true; + if (!checkExistence(path, Boolean(c), Boolean(s))) return false; + if (c) { // For existing items only - if (typeof startTime === "number" && current.safeTime > startTime) { + if (typeof startTime === "number" && c.safeTime > startTime) { // If a change happened after starting reading the item // this may no longer be valid if (log && this._remainingLogs > 0) { this._log( path, - `it may have changed (%d) after the start time of the snapshot (%d)`, - current.safeTime, + "it may have changed (%d) after the start time of the snapshot (%d)", + c.safeTime, startTime ); } return false; } - if ( - snap.timestamp !== undefined && - current.timestamp !== snap.timestamp - ) { + const snap = /** @type {FileSystemInfoEntry} */ (s); + if (snap.timestamp !== undefined && c.timestamp !== snap.timestamp) { // If we have a timestamp (it was a file or symlink) and it differs from current timestamp // it's invalid if (log && this._remainingLogs > 0) { this._log( path, - `timestamps differ (%d != %d)`, - current.timestamp, + "timestamps differ (%d != %d)", + c.timestamp, snap.timestamp ); } return false; } + } + return true; + }; + /** + * @param {string} path file path + * @param {ResolvedContextFileSystemInfoEntry | null} c current entry + * @param {ResolvedContextFileSystemInfoEntry | null} s entry from snapshot + * @param {boolean} log log reason + * @returns {boolean} true, if ok + */ + const checkContext = (path, c, s, log = true) => { + if (c === s) return true; + if (!checkExistence(path, Boolean(c), Boolean(s))) return false; + if (c) { + // For existing items only + if (typeof startTime === "number" && c.safeTime > startTime) { + // If a change happened after starting reading the item + // this may no longer be valid + if (log && this._remainingLogs > 0) { + this._log( + path, + "it may have changed (%d) after the start time of the snapshot (%d)", + c.safeTime, + startTime + ); + } + return false; + } + const snap = /** @type {ResolvedContextFileSystemInfoEntry} */ (s); if ( snap.timestampHash !== undefined && - current.timestampHash !== snap.timestampHash + c.timestampHash !== snap.timestampHash ) { // If we have a timestampHash (it was a directory) and it differs from current timestampHash // it's invalid if (log && this._remainingLogs > 0) { this._log( path, - `timestamps hashes differ (%s != %s)`, - current.timestampHash, + "timestamps hashes differ (%s != %s)", + c.timestampHash, snap.timestampHash ); } @@ -2189,11 +2875,16 @@ class FileSystemInfo { return true; }; if (snapshot.hasChildren()) { + /** + * @param {(WebpackError | null)=} err err + * @param {boolean=} result result + * @returns {void} + */ const childCallback = (err, result) => { if (err || !result) return invalid(); - else jobDone(); + jobDone(); }; - for (const child of snapshot.children) { + for (const child of /** @type {Children} */ (snapshot.children)) { const cache = this._snapshotCache.get(child); if (cache !== undefined) { this._statTestedChildrenCached++; @@ -2215,7 +2906,9 @@ class FileSystemInfo { } } if (snapshot.hasFileTimestamps()) { - const { fileTimestamps } = snapshot; + const fileTimestamps = + /** @type {FileTimestamps} */ + (snapshot.fileTimestamps); this._statTestedEntries += fileTimestamps.size; for (const [path, ts] of fileTimestamps) { const cache = this._fileTimestamps.get(path); @@ -2228,7 +2921,13 @@ class FileSystemInfo { jobs++; this.fileTimestampQueue.add(path, (err, entry) => { if (err) return invalidWithError(path, err); - if (!checkFile(path, entry, ts)) { + if ( + !checkFile( + path, + /** @type {FileSystemInfoEntry | null} */ (entry), + ts + ) + ) { invalid(); } else { jobDone(); @@ -2237,18 +2936,21 @@ class FileSystemInfo { } } } + /** + * @param {string} path file path + * @param {string | null} hash hash + */ const processFileHashSnapshot = (path, hash) => { const cache = this._fileHashes.get(path); if (cache !== undefined) { if (cache !== "ignore" && !checkHash(path, cache, hash)) { invalid(); - return; } } else { jobs++; this.fileHashQueue.add(path, (err, entry) => { if (err) return invalidWithError(path, err); - if (!checkHash(path, entry, hash)) { + if (!checkHash(path, /** @type {string} */ (entry), hash)) { invalid(); } else { jobDone(); @@ -2257,14 +2959,14 @@ class FileSystemInfo { } }; if (snapshot.hasFileHashes()) { - const { fileHashes } = snapshot; + const fileHashes = /** @type {FileHashes} */ (snapshot.fileHashes); this._statTestedEntries += fileHashes.size; for (const [path, hash] of fileHashes) { processFileHashSnapshot(path, hash); } } if (snapshot.hasFileTshs()) { - const { fileTshs } = snapshot; + const fileTshs = /** @type {FileTshs} */ (snapshot.fileTshs); this._statTestedEntries += fileTshs.size; for (const [path, tsh] of fileTshs) { if (typeof tsh === "string") { @@ -2273,14 +2975,22 @@ class FileSystemInfo { const cache = this._fileTimestamps.get(path); if (cache !== undefined) { if (cache === "ignore" || !checkFile(path, cache, tsh, false)) { - processFileHashSnapshot(path, tsh.hash); + processFileHashSnapshot(path, tsh && tsh.hash); } } else { jobs++; this.fileTimestampQueue.add(path, (err, entry) => { if (err) return invalidWithError(path, err); - if (!checkFile(path, entry, tsh, false)) { - processFileHashSnapshot(path, tsh.hash); + if ( + !checkFile( + path, + /** @type {FileSystemInfoEntry | null} */ + (entry), + tsh, + false + ) + ) { + processFileHashSnapshot(path, tsh && tsh.hash); } jobDone(); }); @@ -2289,88 +2999,173 @@ class FileSystemInfo { } } if (snapshot.hasContextTimestamps()) { - const { contextTimestamps } = snapshot; + const contextTimestamps = + /** @type {ContextTimestamps} */ + (snapshot.contextTimestamps); this._statTestedEntries += contextTimestamps.size; for (const [path, ts] of contextTimestamps) { const cache = this._contextTimestamps.get(path); - if (cache !== undefined) { - if (cache !== "ignore" && !checkFile(path, cache, ts)) { + if (cache === "ignore") continue; + let resolved; + if ( + cache !== undefined && + (resolved = getResolvedTimestamp(cache)) !== undefined + ) { + if (!checkContext(path, resolved, ts)) { invalid(); return; } } else { jobs++; - this.contextTimestampQueue.add(path, (err, entry) => { + /** + * @param {(WebpackError | null)=} err error + * @param {(ResolvedContextFileSystemInfoEntry | "ignore" | null)=} entry entry + * @returns {void} + */ + const callback = (err, entry) => { if (err) return invalidWithError(path, err); - if (!checkFile(path, entry, ts)) { + if ( + !checkContext( + path, + /** @type {ResolvedContextFileSystemInfoEntry | null} */ + (entry), + ts + ) + ) { invalid(); } else { jobDone(); } - }); + }; + if (cache !== undefined) { + this._resolveContextTimestamp( + /** @type {ContextFileSystemInfoEntry} */ + (cache), + callback + ); + } else { + this.getContextTimestamp(path, callback); + } } } } + /** + * @param {string} path path + * @param {string | null} hash hash + */ const processContextHashSnapshot = (path, hash) => { const cache = this._contextHashes.get(path); - if (cache !== undefined) { - if (cache !== "ignore" && !checkHash(path, cache, hash)) { + let resolved; + if ( + cache !== undefined && + (resolved = getResolvedHash(cache)) !== undefined + ) { + if (!checkHash(path, resolved, hash)) { invalid(); - return; } } else { jobs++; - this.contextHashQueue.add(path, (err, entry) => { + /** + * @param {(WebpackError | null)=} err err + * @param {string=} entry entry + * @returns {void} + */ + const callback = (err, entry) => { if (err) return invalidWithError(path, err); - if (!checkHash(path, entry, hash)) { + if (!checkHash(path, /** @type {string} */ (entry), hash)) { invalid(); } else { jobDone(); } - }); + }; + if (cache !== undefined) { + this._resolveContextHash(cache, callback); + } else { + this.getContextHash(path, callback); + } } }; if (snapshot.hasContextHashes()) { - const { contextHashes } = snapshot; + const contextHashes = + /** @type {ContextHashes} */ + (snapshot.contextHashes); this._statTestedEntries += contextHashes.size; for (const [path, hash] of contextHashes) { processContextHashSnapshot(path, hash); } } if (snapshot.hasContextTshs()) { - const { contextTshs } = snapshot; + const contextTshs = /** @type {ContextTshs} */ (snapshot.contextTshs); this._statTestedEntries += contextTshs.size; for (const [path, tsh] of contextTshs) { if (typeof tsh === "string") { processContextHashSnapshot(path, tsh); } else { const cache = this._contextTimestamps.get(path); - if (cache !== undefined) { - if (cache === "ignore" || !checkFile(path, cache, tsh, false)) { - processContextHashSnapshot(path, tsh.hash); + if (cache === "ignore") continue; + let resolved; + if ( + cache !== undefined && + (resolved = getResolvedTimestamp(cache)) !== undefined + ) { + if ( + !checkContext( + path, + /** @type {ResolvedContextFileSystemInfoEntry | null} */ + (resolved), + tsh, + false + ) + ) { + processContextHashSnapshot(path, tsh && tsh.hash); } } else { jobs++; - this.contextTimestampQueue.add(path, (err, entry) => { + /** + * @param {(WebpackError | null)=} err error + * @param {(ResolvedContextFileSystemInfoEntry | "ignore" | null)=} entry entry + * @returns {void} + */ + const callback = (err, entry) => { if (err) return invalidWithError(path, err); - if (!checkFile(path, entry, tsh, false)) { - processContextHashSnapshot(path, tsh.hash); + if ( + !checkContext( + path, + // TODO: test with `"ignore"` + /** @type {ResolvedContextFileSystemInfoEntry | null} */ + (entry), + tsh, + false + ) + ) { + processContextHashSnapshot(path, tsh && tsh.hash); } jobDone(); - }); + }; + if (cache !== undefined) { + this._resolveContextTimestamp( + /** @type {ContextFileSystemInfoEntry} */ + (cache), + callback + ); + } else { + this.getContextTimestamp(path, callback); + } } } } } if (snapshot.hasMissingExistence()) { - const { missingExistence } = snapshot; + const missingExistence = + /** @type {MissingExistence} */ + (snapshot.missingExistence); this._statTestedEntries += missingExistence.size; for (const [path, existence] of missingExistence) { const cache = this._fileTimestamps.get(path); if (cache !== undefined) { if ( cache !== "ignore" && - !checkExistence(path, toExistence(cache), existence) + !checkExistence(path, Boolean(cache), Boolean(existence)) ) { invalid(); return; @@ -2379,7 +3174,7 @@ class FileSystemInfo { jobs++; this.fileTimestampQueue.add(path, (err, entry) => { if (err) return invalidWithError(path, err); - if (!checkExistence(path, toExistence(entry), existence)) { + if (!checkExistence(path, Boolean(entry), Boolean(existence))) { invalid(); } else { jobDone(); @@ -2389,7 +3184,9 @@ class FileSystemInfo { } } if (snapshot.hasManagedItemInfo()) { - const { managedItemInfo } = snapshot; + const managedItemInfo = + /** @type {ManagedItemInfo} */ + (snapshot.managedItemInfo); this._statTestedEntries += managedItemInfo.size; for (const [path, info] of managedItemInfo) { const cache = this._managedItems.get(path); @@ -2402,7 +3199,7 @@ class FileSystemInfo { jobs++; this.managedItemQueue.add(path, (err, entry) => { if (err) return invalidWithError(path, err); - if (!checkHash(path, entry, info)) { + if (!checkHash(path, /** @type {string} */ (entry), info)) { invalid(); } else { jobDone(); @@ -2424,17 +3221,21 @@ class FileSystemInfo { } } + /** + * @type {Processor} + * @private + */ _readFileTimestamp(path, callback) { - this.fs.stat(path, (err, stat) => { + this.fs.stat(path, (err, _stat) => { if (err) { if (err.code === "ENOENT") { this._fileTimestamps.set(path, null); this._cachedDeprecatedFileTimestamps = undefined; return callback(null, null); } - return callback(err); + return callback(/** @type {WebpackError} */ (err)); } - + const stat = /** @type {IStats} */ (_stat); let ts; if (stat.isDirectory()) { ts = { @@ -2442,7 +3243,7 @@ class FileSystemInfo { timestamp: undefined }; } else { - const mtime = +stat.mtime; + const mtime = Number(stat.mtime); if (mtime) applyMtime(mtime); @@ -2459,6 +3260,10 @@ class FileSystemInfo { }); } + /** + * @type {Processor} + * @private + */ _readFileHash(path, callback) { this.fs.readFile(path, (err, content) => { if (err) { @@ -2471,16 +3276,17 @@ class FileSystemInfo { return callback(null, null); } if (err.code === "ERR_FS_FILE_TOO_LARGE") { - this.logger.warn(`Ignoring ${path} for hashing as it's very large`); + /** @type {Logger} */ + (this.logger).warn(`Ignoring ${path} for hashing as it's very large`); this._fileHashes.set(path, "too large"); return callback(null, "too large"); } - return callback(err); + return callback(/** @type {WebpackError} */ (err)); } - const hash = createHash("md4"); + const hash = createHash(this._hashFunction); - hash.update(content); + hash.update(/** @type {string | Buffer} */ (content)); const digest = /** @type {string} */ (hash.digest("hex")); @@ -2490,55 +3296,86 @@ class FileSystemInfo { }); } + /** + * @param {string} path path + * @param {function(WebpackError | null, TimestampAndHash=) : void} callback callback + * @private + */ _getFileTimestampAndHash(path, callback) { + /** + * @param {string} hash hash + * @returns {void} + */ const continueWithHash = hash => { const cache = this._fileTimestamps.get(path); if (cache !== undefined) { if (cache !== "ignore") { + /** @type {TimestampAndHash} */ const result = { - ...cache, + .../** @type {FileSystemInfoEntry} */ (cache), hash }; this._fileTshs.set(path, result); return callback(null, result); - } else { - this._fileTshs.set(path, hash); - return callback(null, hash); } - } else { - this.fileTimestampQueue.add(path, (err, entry) => { - if (err) { - return callback(err); - } - const result = { - ...entry, - hash - }; - this._fileTshs.set(path, result); - return callback(null, result); - }); + this._fileTshs.set(path, hash); + return callback(null, /** @type {TODO} */ (hash)); } + this.fileTimestampQueue.add(path, (err, entry) => { + if (err) { + return callback(err); + } + /** @type {TimestampAndHash} */ + const result = { + .../** @type {FileSystemInfoEntry} */ (entry), + hash + }; + this._fileTshs.set(path, result); + return callback(null, result); + }); }; const cache = this._fileHashes.get(path); if (cache !== undefined) { - continueWithHash(cache); + continueWithHash(/** @type {string} */ (cache)); } else { this.fileHashQueue.add(path, (err, entry) => { if (err) { return callback(err); } - continueWithHash(entry); + continueWithHash(/** @type {string} */ (entry)); }); } } - _readContextTimestamp(path, callback) { + /** + * @template T + * @template ItemType + * @param {object} options options + * @param {string} options.path path + * @param {function(string): ItemType} options.fromImmutablePath called when context item is an immutable path + * @param {function(string): ItemType} options.fromManagedItem called when context item is a managed path + * @param {function(string, string, function((WebpackError | null)=, ItemType=): void): void} options.fromSymlink called when context item is a symlink + * @param {function(string, IStats, function((WebpackError | null)=, (ItemType | null)=): void): void} options.fromFile called when context item is a file + * @param {function(string, IStats, function((WebpackError | null)=, ItemType=): void): void} options.fromDirectory called when context item is a directory + * @param {function(string[], ItemType[]): T} options.reduce called from all context items + * @param {function((Error | null)=, (T | null)=): void} callback callback + */ + _readContext( + { + path, + fromImmutablePath, + fromManagedItem, + fromSymlink, + fromFile, + fromDirectory, + reduce + }, + callback + ) { this.fs.readdir(path, (err, _files) => { if (err) { if (err.code === "ENOENT") { - this._contextTimestamps.set(path, null); - this._cachedDeprecatedContextTimestamps = undefined; return callback(null, null); } return callback(err); @@ -2551,62 +3388,166 @@ class FileSystemInfo { files, (file, callback) => { const child = join(this.fs, path, file); - this.fs.stat(child, (err, stat) => { - if (err) return callback(err); - - for (const immutablePath of this.immutablePathsWithSlash) { - if (path.startsWith(immutablePath)) { - // ignore any immutable path for timestamping - return callback(null, null); + for (const immutablePath of this.immutablePathsRegExps) { + if (immutablePath.test(path)) { + // ignore any immutable path for timestamping + return callback(null, fromImmutablePath(path)); + } + } + for (const immutablePath of this.immutablePathsWithSlash) { + if (path.startsWith(immutablePath)) { + // ignore any immutable path for timestamping + return callback(null, fromImmutablePath(path)); + } + } + for (const managedPath of this.managedPathsRegExps) { + const match = managedPath.exec(path); + if (match) { + const managedItem = getManagedItem(match[1], path); + if (managedItem) { + // construct timestampHash from managed info + return this.managedItemQueue.add(managedItem, (err, info) => { + if (err) return callback(err); + return callback( + null, + fromManagedItem(/** @type {string} */ (info)) + ); + }); } } - for (const managedPath of this.managedPathsWithSlash) { - if (path.startsWith(managedPath)) { - const managedItem = getManagedItem(managedPath, child); - if (managedItem) { - // construct timestampHash from managed info - return this.managedItemQueue.add(managedItem, (err, info) => { - if (err) return callback(err); - return callback(null, { - safeTime: 0, - timestampHash: info - }); - }); - } + } + for (const managedPath of this.managedPathsWithSlash) { + if (path.startsWith(managedPath)) { + const managedItem = getManagedItem(managedPath, child); + if (managedItem) { + // construct timestampHash from managed info + return this.managedItemQueue.add(managedItem, (err, info) => { + if (err) return callback(err); + return callback( + null, + fromManagedItem(/** @type {string} */ (info)) + ); + }); } } + } + + lstatReadlinkAbsolute(this.fs, child, (err, _stat) => { + if (err) return callback(err); + + const stat = /** @type {IStats | string} */ (_stat); + + if (typeof stat === "string") { + return fromSymlink(child, stat, callback); + } if (stat.isFile()) { - return this.getFileTimestamp(child, callback); + return fromFile(child, stat, callback); } if (stat.isDirectory()) { - this.contextTimestampQueue.increaseParallelism(); - this.getContextTimestamp(child, (err, tsEntry) => { - this.contextTimestampQueue.decreaseParallelism(); - callback(err, tsEntry); - }); - return; + return fromDirectory(child, stat, callback); } callback(null, null); }); }, - (err, tsEntries) => { + (err, results) => { if (err) return callback(err); - const hash = createHash("md4"); + const result = reduce(files, /** @type {ItemType[]} */ (results)); + callback(null, result); + } + ); + }); + } + + /** + * @type {Processor} + * @private + */ + _readContextTimestamp(path, callback) { + this._readContext( + { + path, + fromImmutablePath: () => + /** @type {ContextFileSystemInfoEntry | FileSystemInfoEntry | "ignore" | null} */ + (null), + fromManagedItem: info => ({ + safeTime: 0, + timestampHash: info + }), + fromSymlink: (file, target, callback) => { + callback( + null, + /** @type {ContextFileSystemInfoEntry} */ + ({ + timestampHash: target, + symlinks: new Set([target]) + }) + ); + }, + fromFile: (file, stat, callback) => { + // Prefer the cached value over our new stat to report consistent results + const cache = this._fileTimestamps.get(file); + if (cache !== undefined) + return callback(null, cache === "ignore" ? null : cache); + + const mtime = Number(stat.mtime); + + if (mtime) applyMtime(mtime); + + /** @type {FileSystemInfoEntry} */ + const ts = { + safeTime: mtime ? mtime + FS_ACCURACY : Infinity, + timestamp: mtime + }; + + this._fileTimestamps.set(file, ts); + this._cachedDeprecatedFileTimestamps = undefined; + callback(null, ts); + }, + fromDirectory: (directory, stat, callback) => { + this.contextTimestampQueue.increaseParallelism(); + this._getUnresolvedContextTimestamp(directory, (err, tsEntry) => { + this.contextTimestampQueue.decreaseParallelism(); + callback(err, tsEntry); + }); + }, + reduce: (files, tsEntries) => { + let symlinks; + + const hash = createHash(this._hashFunction); for (const file of files) hash.update(file); let safeTime = 0; - for (const entry of tsEntries) { - if (!entry) { + for (const _e of tsEntries) { + if (!_e) { hash.update("n"); continue; } - if (entry.timestamp) { + const entry = + /** @type {FileSystemInfoEntry | ContextFileSystemInfoEntry} */ + (_e); + if (/** @type {FileSystemInfoEntry} */ (entry).timestamp) { hash.update("f"); - hash.update(`${entry.timestamp}`); - } else if (entry.timestampHash) { + hash.update( + `${/** @type {FileSystemInfoEntry} */ (entry).timestamp}` + ); + } else if ( + /** @type {ContextFileSystemInfoEntry} */ (entry).timestampHash + ) { hash.update("d"); - hash.update(`${entry.timestampHash}`); + hash.update( + `${/** @type {ContextFileSystemInfoEntry} */ (entry).timestampHash}` + ); + } + if ( + /** @type {ContextFileSystemInfoEntry} */ + (entry).symlinks !== undefined + ) { + if (symlinks === undefined) symlinks = new Set(); + addAll( + /** @type {ContextFileSystemInfoEntry} */ (entry).symlinks, + symlinks + ); } if (entry.safeTime) { safeTime = Math.max(safeTime, entry.safeTime); @@ -2614,143 +3555,380 @@ class FileSystemInfo { } const digest = /** @type {string} */ (hash.digest("hex")); - + /** @type {ContextFileSystemInfoEntry} */ const result = { safeTime, timestampHash: digest }; - - this._contextTimestamps.set(path, result); - this._cachedDeprecatedContextTimestamps = undefined; - - callback(null, result); + if (symlinks) result.symlinks = symlinks; + return result; } - ); - }); - } + }, + (err, result) => { + if (err) return callback(/** @type {WebpackError} */ (err)); + this._contextTimestamps.set(path, result); + this._cachedDeprecatedContextTimestamps = undefined; - _readContextHash(path, callback) { - this.fs.readdir(path, (err, _files) => { - if (err) { - if (err.code === "ENOENT") { - this._contextHashes.set(path, null); - return callback(null, null); - } - return callback(err); + callback(null, result); } - const files = /** @type {string[]} */ (_files) - .map(file => file.normalize("NFC")) - .filter(file => !/^\./.test(file)) - .sort(); - asyncLib.map( - files, - (file, callback) => { - const child = join(this.fs, path, file); - this.fs.stat(child, (err, stat) => { - if (err) return callback(err); + ); + } - for (const immutablePath of this.immutablePathsWithSlash) { - if (path.startsWith(immutablePath)) { - // ignore any immutable path for hashing - return callback(null, ""); - } + /** + * @param {ContextFileSystemInfoEntry} entry entry + * @param {function((WebpackError | null)=, (ResolvedContextFileSystemInfoEntry | "ignore" | null)=): void} callback callback + * @returns {void} + */ + _resolveContextTimestamp(entry, callback) { + /** @type {string[]} */ + const hashes = []; + let safeTime = 0; + processAsyncTree( + /** @type {NonNullable} */ (entry.symlinks), + 10, + (target, push, callback) => { + this._getUnresolvedContextTimestamp(target, (err, entry) => { + if (err) return callback(err); + if (entry && entry !== "ignore") { + hashes.push(/** @type {string} */ (entry.timestampHash)); + if (entry.safeTime) { + safeTime = Math.max(safeTime, entry.safeTime); } - for (const managedPath of this.managedPathsWithSlash) { - if (path.startsWith(managedPath)) { - const managedItem = getManagedItem(managedPath, child); - if (managedItem) { - // construct hash from managed info - return this.managedItemQueue.add(managedItem, (err, info) => { - if (err) return callback(err); - callback(null, info || ""); - }); - } - } + if (entry.symlinks !== undefined) { + for (const target of entry.symlinks) push(target); } + } + callback(); + }); + }, + err => { + if (err) return callback(/** @type {WebpackError} */ (err)); + const hash = createHash(this._hashFunction); + hash.update(/** @type {string} */ (entry.timestampHash)); + if (entry.safeTime) { + safeTime = Math.max(safeTime, entry.safeTime); + } + hashes.sort(); + for (const h of hashes) { + hash.update(h); + } + callback( + null, + (entry.resolved = { + safeTime, + timestampHash: /** @type {string} */ (hash.digest("hex")) + }) + ); + } + ); + } - if (stat.isFile()) { - return this.getFileHash(child, (err, hash) => { - callback(err, hash || ""); - }); - } - if (stat.isDirectory()) { - this.contextHashQueue.increaseParallelism(); - this.getContextHash(child, (err, hash) => { - this.contextHashQueue.decreaseParallelism(); - callback(err, hash || ""); - }); - return; - } - callback(null, ""); + /** + * @type {Processor} + * @private + */ + _readContextHash(path, callback) { + this._readContext( + { + path, + fromImmutablePath: () => + /** @type {ContextHash} */ (/** @type {unknown} */ ("")), + fromManagedItem: info => info || "", + fromSymlink: (file, target, callback) => { + callback( + null, + /** @type {ContextHash} */ + ({ + hash: target, + symlinks: new Set([target]) + }) + ); + }, + fromFile: (file, stat, callback) => + this.getFileHash(file, (err, hash) => { + callback(err, hash || ""); + }), + fromDirectory: (directory, stat, callback) => { + this.contextHashQueue.increaseParallelism(); + this._getUnresolvedContextHash(directory, (err, hash) => { + this.contextHashQueue.decreaseParallelism(); + callback(err, hash || ""); }); }, - (err, fileHashes) => { - if (err) return callback(err); - const hash = createHash("md4"); + /** + * @param {string[]} files files + * @param {(string | ContextHash)[]} fileHashes hashes + * @returns {ContextHash} reduced hash + */ + reduce: (files, fileHashes) => { + let symlinks; + const hash = createHash(this._hashFunction); for (const file of files) hash.update(file); - for (const h of fileHashes) hash.update(h); - - const digest = /** @type {string} */ (hash.digest("hex")); - - this._contextHashes.set(path, digest); + for (const entry of fileHashes) { + if (typeof entry === "string") { + hash.update(entry); + } else { + hash.update(entry.hash); + if (entry.symlinks) { + if (symlinks === undefined) symlinks = new Set(); + addAll(entry.symlinks, symlinks); + } + } + } - callback(null, digest); + /** @type {ContextHash} */ + const result = { + hash: /** @type {string} */ (hash.digest("hex")) + }; + if (symlinks) result.symlinks = symlinks; + return result; } - ); - }); + }, + (err, _result) => { + if (err) return callback(/** @type {WebpackError} */ (err)); + const result = /** @type {ContextHash} */ (_result); + this._contextHashes.set(path, result); + return callback(null, result); + } + ); } - _getContextTimestampAndHash(path, callback) { - const continueWithHash = hash => { - const cache = this._contextTimestamps.get(path); - if (cache !== undefined) { - if (cache !== "ignore") { - const result = { - ...cache, - hash - }; - this._contextTshs.set(path, result); - return callback(null, result); - } else { - this._contextTshs.set(path, hash); - return callback(null, hash); + /** + * @param {ContextHash} entry context hash + * @param {function(WebpackError | null, string=): void} callback callback + * @returns {void} + */ + _resolveContextHash(entry, callback) { + /** @type {string[]} */ + const hashes = []; + processAsyncTree( + /** @type {NonNullable} */ (entry.symlinks), + 10, + (target, push, callback) => { + this._getUnresolvedContextHash(target, (err, hash) => { + if (err) return callback(err); + if (hash) { + hashes.push(hash.hash); + if (hash.symlinks !== undefined) { + for (const target of hash.symlinks) push(target); + } + } + callback(); + }); + }, + err => { + if (err) return callback(/** @type {WebpackError} */ (err)); + const hash = createHash(this._hashFunction); + hash.update(entry.hash); + hashes.sort(); + for (const h of hashes) { + hash.update(h); } + callback( + null, + (entry.resolved = /** @type {string} */ (hash.digest("hex"))) + ); + } + ); + } + + /** + * @type {Processor} + * @private + */ + _readContextTimestampAndHash(path, callback) { + /** + * @param {ContextFileSystemInfoEntry | "ignore" | null} timestamp timestamp + * @param {ContextHash} hash hash + */ + const finalize = (timestamp, hash) => { + const result = + /** @type {ContextTimestampAndHash} */ + (timestamp === "ignore" ? hash : { ...timestamp, ...hash }); + this._contextTshs.set(path, result); + callback(null, result); + }; + const cachedHash = this._contextHashes.get(path); + const cachedTimestamp = this._contextTimestamps.get(path); + if (cachedHash !== undefined) { + if (cachedTimestamp !== undefined) { + finalize(cachedTimestamp, cachedHash); } else { this.contextTimestampQueue.add(path, (err, entry) => { - if (err) { - return callback(err); - } - const result = { - ...entry, - hash - }; - this._contextTshs.set(path, result); - return callback(null, result); + if (err) return callback(err); + finalize( + /** @type {ContextFileSystemInfoEntry} */ + (entry), + cachedHash + ); }); } - }; - - const cache = this._contextHashes.get(path); - if (cache !== undefined) { - continueWithHash(cache); - } else { + } else if (cachedTimestamp !== undefined) { this.contextHashQueue.add(path, (err, entry) => { - if (err) { - return callback(err); - } - continueWithHash(entry); + if (err) return callback(err); + finalize(cachedTimestamp, /** @type {ContextHash} */ (entry)); }); + } else { + this._readContext( + { + path, + fromImmutablePath: () => null, + fromManagedItem: info => ({ + safeTime: 0, + timestampHash: info, + hash: info || "" + }), + fromSymlink: (file, target, callback) => { + callback(null, { + timestampHash: target, + hash: target, + symlinks: new Set([target]) + }); + }, + fromFile: (file, stat, callback) => { + this._getFileTimestampAndHash(file, callback); + }, + fromDirectory: (directory, stat, callback) => { + this.contextTshQueue.increaseParallelism(); + this.contextTshQueue.add(directory, (err, result) => { + this.contextTshQueue.decreaseParallelism(); + callback(err, result); + }); + }, + /** + * @param {string[]} files files + * @param {(Partial & Partial | string | null)[]} results results + * @returns {ContextTimestampAndHash} tsh + */ + reduce: (files, results) => { + let symlinks; + + const tsHash = createHash(this._hashFunction); + const hash = createHash(this._hashFunction); + + for (const file of files) { + tsHash.update(file); + hash.update(file); + } + let safeTime = 0; + for (const entry of results) { + if (!entry) { + tsHash.update("n"); + continue; + } + if (typeof entry === "string") { + tsHash.update("n"); + hash.update(entry); + continue; + } + if (entry.timestamp) { + tsHash.update("f"); + tsHash.update(`${entry.timestamp}`); + } else if (entry.timestampHash) { + tsHash.update("d"); + tsHash.update(`${entry.timestampHash}`); + } + if (entry.symlinks !== undefined) { + if (symlinks === undefined) symlinks = new Set(); + addAll(entry.symlinks, symlinks); + } + if (entry.safeTime) { + safeTime = Math.max(safeTime, entry.safeTime); + } + hash.update(/** @type {string} */ (entry.hash)); + } + + /** @type {ContextTimestampAndHash} */ + const result = { + safeTime, + timestampHash: /** @type {string} */ (tsHash.digest("hex")), + hash: /** @type {string} */ (hash.digest("hex")) + }; + if (symlinks) result.symlinks = symlinks; + return result; + } + }, + (err, _result) => { + if (err) return callback(/** @type {WebpackError} */ (err)); + const result = /** @type {ContextTimestampAndHash} */ (_result); + this._contextTshs.set(path, result); + return callback(null, result); + } + ); } } + /** + * @param {ContextTimestampAndHash} entry entry + * @param {ProcessorCallback} callback callback + * @returns {void} + */ + _resolveContextTsh(entry, callback) { + /** @type {string[]} */ + const hashes = []; + /** @type {string[]} */ + const tsHashes = []; + let safeTime = 0; + processAsyncTree( + /** @type {NonNullable} */ (entry.symlinks), + 10, + (target, push, callback) => { + this._getUnresolvedContextTsh(target, (err, entry) => { + if (err) return callback(err); + if (entry) { + hashes.push(entry.hash); + if (entry.timestampHash) tsHashes.push(entry.timestampHash); + if (entry.safeTime) { + safeTime = Math.max(safeTime, entry.safeTime); + } + if (entry.symlinks !== undefined) { + for (const target of entry.symlinks) push(target); + } + } + callback(); + }); + }, + err => { + if (err) return callback(/** @type {WebpackError} */ (err)); + const hash = createHash(this._hashFunction); + const tsHash = createHash(this._hashFunction); + hash.update(entry.hash); + if (entry.timestampHash) tsHash.update(entry.timestampHash); + if (entry.safeTime) { + safeTime = Math.max(safeTime, entry.safeTime); + } + hashes.sort(); + for (const h of hashes) { + hash.update(h); + } + tsHashes.sort(); + for (const h of tsHashes) { + tsHash.update(h); + } + callback( + null, + (entry.resolved = { + safeTime, + timestampHash: /** @type {string} */ (tsHash.digest("hex")), + hash: /** @type {string} */ (hash.digest("hex")) + }) + ); + } + ); + } + + /** + * @type {Processor>} + * @private + */ _getManagedItemDirectoryInfo(path, callback) { this.fs.readdir(path, (err, elements) => { if (err) { if (err.code === "ENOENT" || err.code === "ENOTDIR") { return callback(null, EMPTY_SET); } - return callback(err); + return callback(/** @type {WebpackError} */ (err)); } const set = new Set( /** @type {string[]} */ (elements).map(element => @@ -2761,16 +3939,20 @@ class FileSystemInfo { }); } + /** + * @type {Processor} + * @private + */ _getManagedItemInfo(path, callback) { const dir = dirname(this.fs, path); this.managedItemDirectoryQueue.add(dir, (err, elements) => { if (err) { return callback(err); } - if (!elements.has(path)) { + if (!(/** @type {Set} */ (elements).has(path))) { // file or directory doesn't exist - this._managedItems.set(path, "missing"); - return callback(null, "missing"); + this._managedItems.set(path, "*missing"); + return callback(null, "*missing"); } // something exists // it may be a file or directory @@ -2779,8 +3961,8 @@ class FileSystemInfo { (path.endsWith("/node_modules") || path.endsWith("\\node_modules")) ) { // we are only interested in existence of this special directory - this._managedItems.set(path, "exists"); - return callback(null, "exists"); + this._managedItems.set(path, "*node_modules"); + return callback(null, "*node_modules"); } // we assume it's a directory, as files shouldn't occur in managed paths @@ -2792,27 +3974,36 @@ class FileSystemInfo { this.fs.readdir(path, (err, elements) => { if ( !err && - elements.length === 1 && - elements[0] === "node_modules" + /** @type {string[]} */ (elements).length === 1 && + /** @type {string[]} */ (elements)[0] === "node_modules" ) { - // This is only a grouping folder e. g. used by yarn + // This is only a grouping folder e.g. used by yarn // we are only interested in existence of this special directory - this._managedItems.set(path, "nested"); - return callback(null, "nested"); + this._managedItems.set(path, "*nested"); + return callback(null, "*nested"); } - const problem = `Managed item ${path} isn't a directory or doesn't contain a package.json`; - this.logger.warn(problem); - return callback(new Error(problem)); + /** @type {Logger} */ + (this.logger).warn( + `Managed item ${path} isn't a directory or doesn't contain a package.json (see snapshot.managedPaths option)` + ); + return callback(); }); return; } - return callback(err); + return callback(/** @type {WebpackError} */ (err)); } let data; try { - data = JSON.parse(content.toString("utf-8")); - } catch (e) { - return callback(e); + data = JSON.parse(/** @type {Buffer} */ (content).toString("utf-8")); + } catch (parseErr) { + return callback(/** @type {WebpackError} */ (parseErr)); + } + if (!data.name) { + /** @type {Logger} */ + (this.logger).warn( + `${packageJsonPath} doesn't contain a "name" property (see snapshot.managedPaths option)` + ); + return callback(); } const info = `${data.name || ""}@${data.version || ""}`; this._managedItems.set(path, info); diff --git a/lib/FlagAllModulesAsUsedPlugin.js b/lib/FlagAllModulesAsUsedPlugin.js index c84ed38aaca..eb3ee4cf43d 100644 --- a/lib/FlagAllModulesAsUsedPlugin.js +++ b/lib/FlagAllModulesAsUsedPlugin.js @@ -8,9 +8,14 @@ const { getEntryRuntime, mergeRuntimeOwned } = require("./util/runtime"); /** @typedef {import("./Compiler")} Compiler */ +/** @typedef {import("./Module").FactoryMeta} FactoryMeta */ /** @typedef {import("./util/runtime").RuntimeSpec} RuntimeSpec */ +const PLUGIN_NAME = "FlagAllModulesAsUsedPlugin"; class FlagAllModulesAsUsedPlugin { + /** + * @param {string} explanation explanation + */ constructor(explanation) { this.explanation = explanation; } @@ -21,34 +26,29 @@ class FlagAllModulesAsUsedPlugin { * @returns {void} */ apply(compiler) { - compiler.hooks.compilation.tap( - "FlagAllModulesAsUsedPlugin", - compilation => { - const moduleGraph = compilation.moduleGraph; - compilation.hooks.optimizeDependencies.tap( - "FlagAllModulesAsUsedPlugin", - modules => { - /** @type {RuntimeSpec} */ - let runtime = undefined; - for (const [name, { options }] of compilation.entries) { - runtime = mergeRuntimeOwned( - runtime, - getEntryRuntime(compilation, name, options) - ); - } - for (const module of modules) { - const exportsInfo = moduleGraph.getExportsInfo(module); - exportsInfo.setUsedInUnknownWay(runtime); - moduleGraph.addExtraReason(module, this.explanation); - if (module.factoryMeta === undefined) { - module.factoryMeta = {}; - } - module.factoryMeta.sideEffectFree = false; - } + compiler.hooks.compilation.tap(PLUGIN_NAME, compilation => { + const moduleGraph = compilation.moduleGraph; + compilation.hooks.optimizeDependencies.tap(PLUGIN_NAME, modules => { + /** @type {RuntimeSpec} */ + let runtime; + for (const [name, { options }] of compilation.entries) { + runtime = mergeRuntimeOwned( + runtime, + getEntryRuntime(compilation, name, options) + ); + } + for (const module of modules) { + const exportsInfo = moduleGraph.getExportsInfo(module); + exportsInfo.setUsedInUnknownWay(runtime); + moduleGraph.addExtraReason(module, this.explanation); + if (module.factoryMeta === undefined) { + module.factoryMeta = {}; } - ); - } - ); + /** @type {FactoryMeta} */ + (module.factoryMeta).sideEffectFree = false; + } + }); + }); } } diff --git a/lib/FlagDependencyExportsPlugin.js b/lib/FlagDependencyExportsPlugin.js index 872e9976299..aacbb3d2789 100644 --- a/lib/FlagDependencyExportsPlugin.js +++ b/lib/FlagDependencyExportsPlugin.js @@ -12,8 +12,13 @@ const Queue = require("./util/Queue"); /** @typedef {import("./DependenciesBlock")} DependenciesBlock */ /** @typedef {import("./Dependency")} Dependency */ /** @typedef {import("./Dependency").ExportSpec} ExportSpec */ +/** @typedef {import("./Dependency").ExportsSpec} ExportsSpec */ /** @typedef {import("./ExportsInfo")} ExportsInfo */ /** @typedef {import("./Module")} Module */ +/** @typedef {import("./Module").BuildInfo} BuildInfo */ + +const PLUGIN_NAME = "FlagDependencyExportsPlugin"; +const PLUGIN_LOGGER_NAME = `webpack.${PLUGIN_NAME}`; class FlagDependencyExportsPlugin { /** @@ -22,353 +27,393 @@ class FlagDependencyExportsPlugin { * @returns {void} */ apply(compiler) { - compiler.hooks.compilation.tap( - "FlagDependencyExportsPlugin", - compilation => { - const moduleGraph = compilation.moduleGraph; - const cache = compilation.getCache("FlagDependencyExportsPlugin"); - compilation.hooks.finishModules.tapAsync( - "FlagDependencyExportsPlugin", - (modules, callback) => { - const logger = compilation.getLogger( - "webpack.FlagDependencyExportsPlugin" - ); - let statRestoredFromCache = 0; - let statFlaggedUncached = 0; - let statNotCached = 0; - let statQueueItemsProcessed = 0; - - /** @type {Queue} */ - const queue = new Queue(); - - // Step 1: Try to restore cached provided export info from cache - logger.time("restore cached provided exports"); - asyncLib.each( - modules, - (module, callback) => { - if ( - module.buildInfo.cacheable !== true || - typeof module.buildInfo.hash !== "string" - ) { - statFlaggedUncached++; - // Enqueue uncacheable module for determining the exports - queue.enqueue(module); - moduleGraph.getExportsInfo(module).setHasProvideInfo(); - return callback(); - } - cache.get( - module.identifier(), - module.buildInfo.hash, - (err, result) => { - if (err) return callback(err); - - if (result !== undefined) { - statRestoredFromCache++; - moduleGraph - .getExportsInfo(module) - .restoreProvided(result); - } else { - statNotCached++; - // Without cached info enqueue module for determining the exports - queue.enqueue(module); - moduleGraph.getExportsInfo(module).setHasProvideInfo(); - } - callback(); + compiler.hooks.compilation.tap(PLUGIN_NAME, compilation => { + const moduleGraph = compilation.moduleGraph; + const cache = compilation.getCache(PLUGIN_NAME); + compilation.hooks.finishModules.tapAsync( + PLUGIN_NAME, + (modules, callback) => { + const logger = compilation.getLogger(PLUGIN_LOGGER_NAME); + let statRestoredFromMemCache = 0; + let statRestoredFromCache = 0; + let statNoExports = 0; + let statFlaggedUncached = 0; + let statNotCached = 0; + let statQueueItemsProcessed = 0; + + const { moduleMemCaches } = compilation; + + /** @type {Queue} */ + const queue = new Queue(); + + // Step 1: Try to restore cached provided export info from cache + logger.time("restore cached provided exports"); + asyncLib.each( + modules, + (module, callback) => { + const exportsInfo = moduleGraph.getExportsInfo(module); + // If the module doesn't have an exportsType, it's a module + // without declared exports. + if ( + (!module.buildMeta || !module.buildMeta.exportsType) && + exportsInfo.otherExportsInfo.provided !== null + ) { + // It's a module without declared exports + statNoExports++; + exportsInfo.setHasProvideInfo(); + exportsInfo.setUnknownExportsProvided(); + return callback(); + } + // If the module has no hash, it's uncacheable + if ( + typeof (/** @type {BuildInfo} */ (module.buildInfo).hash) !== + "string" + ) { + statFlaggedUncached++; + // Enqueue uncacheable module for determining the exports + queue.enqueue(module); + exportsInfo.setHasProvideInfo(); + return callback(); + } + const memCache = moduleMemCaches && moduleMemCaches.get(module); + const memCacheValue = memCache && memCache.get(this); + if (memCacheValue !== undefined) { + statRestoredFromMemCache++; + exportsInfo.restoreProvided(memCacheValue); + return callback(); + } + cache.get( + module.identifier(), + /** @type {BuildInfo} */ + (module.buildInfo).hash, + (err, result) => { + if (err) return callback(err); + + if (result !== undefined) { + statRestoredFromCache++; + exportsInfo.restoreProvided(result); + } else { + statNotCached++; + // Without cached info enqueue module for determining the exports + queue.enqueue(module); + exportsInfo.setHasProvideInfo(); } - ); - }, - err => { - logger.timeEnd("restore cached provided exports"); - if (err) return callback(err); - - /** @type {Set} */ - const modulesToStore = new Set(); - - /** @type {Map>} */ - const dependencies = new Map(); - - /** @type {Module} */ - let module; - - /** @type {ExportsInfo} */ - let exportsInfo; - - let cacheable = true; - let changed = false; - - /** - * @param {DependenciesBlock} depBlock the dependencies block - * @returns {void} - */ - const processDependenciesBlock = depBlock => { - for (const dep of depBlock.dependencies) { - processDependency(dep); + callback(); + } + ); + }, + err => { + logger.timeEnd("restore cached provided exports"); + if (err) return callback(err); + + /** @type {Set} */ + const modulesToStore = new Set(); + + /** @type {Map>} */ + const dependencies = new Map(); + + /** @type {Module} */ + let module; + + /** @type {ExportsInfo} */ + let exportsInfo; + + /** @type {Map} */ + const exportsSpecsFromDependencies = new Map(); + + let cacheable = true; + let changed = false; + + /** + * @param {DependenciesBlock} depBlock the dependencies block + * @returns {void} + */ + const processDependenciesBlock = depBlock => { + for (const dep of depBlock.dependencies) { + processDependency(dep); + } + for (const block of depBlock.blocks) { + processDependenciesBlock(block); + } + }; + + /** + * @param {Dependency} dep the dependency + * @returns {void} + */ + const processDependency = dep => { + const exportDesc = dep.getExports(moduleGraph); + if (!exportDesc) return; + exportsSpecsFromDependencies.set(dep, exportDesc); + }; + + /** + * @param {Dependency} dep dependency + * @param {ExportsSpec} exportDesc info + * @returns {void} + */ + const processExportsSpec = (dep, exportDesc) => { + const exports = exportDesc.exports; + const globalCanMangle = exportDesc.canMangle; + const globalFrom = exportDesc.from; + const globalPriority = exportDesc.priority; + const globalTerminalBinding = + exportDesc.terminalBinding || false; + const exportDeps = exportDesc.dependencies; + if (exportDesc.hideExports) { + for (const name of exportDesc.hideExports) { + const exportInfo = exportsInfo.getExportInfo(name); + exportInfo.unsetTarget(dep); } - for (const block of depBlock.blocks) { - processDependenciesBlock(block); + } + if (exports === true) { + // unknown exports + if ( + exportsInfo.setUnknownExportsProvided( + globalCanMangle, + exportDesc.excludeExports, + globalFrom && dep, + globalFrom, + globalPriority + ) + ) { + changed = true; } - }; - - /** - * @param {Dependency} dep the dependency - * @returns {void} - */ - const processDependency = dep => { - const exportDesc = dep.getExports(moduleGraph); - if (!exportDesc) return; - const exports = exportDesc.exports; - const globalCanMangle = exportDesc.canMangle; - const globalFrom = exportDesc.from; - const globalTerminalBinding = - exportDesc.terminalBinding || false; - const exportDeps = exportDesc.dependencies; - if (exportDesc.hideExports) { - for (const name of exportDesc.hideExports) { + } else if (Array.isArray(exports)) { + /** + * merge in new exports + * @param {ExportsInfo} exportsInfo own exports info + * @param {(ExportSpec | string)[]} exports list of exports + */ + const mergeExports = (exportsInfo, exports) => { + for (const exportNameOrSpec of exports) { + let name; + let canMangle = globalCanMangle; + let terminalBinding = globalTerminalBinding; + let exports; + let from = globalFrom; + let fromExport; + let priority = globalPriority; + let hidden = false; + if (typeof exportNameOrSpec === "string") { + name = exportNameOrSpec; + } else { + name = exportNameOrSpec.name; + if (exportNameOrSpec.canMangle !== undefined) + canMangle = exportNameOrSpec.canMangle; + if (exportNameOrSpec.export !== undefined) + fromExport = exportNameOrSpec.export; + if (exportNameOrSpec.exports !== undefined) + exports = exportNameOrSpec.exports; + if (exportNameOrSpec.from !== undefined) + from = exportNameOrSpec.from; + if (exportNameOrSpec.priority !== undefined) + priority = exportNameOrSpec.priority; + if (exportNameOrSpec.terminalBinding !== undefined) + terminalBinding = exportNameOrSpec.terminalBinding; + if (exportNameOrSpec.hidden !== undefined) + hidden = exportNameOrSpec.hidden; + } const exportInfo = exportsInfo.getExportInfo(name); - exportInfo.unsetTarget(dep); - } - } - if (exports === true) { - // unknown exports - if ( - exportsInfo.setUnknownExportsProvided( - globalCanMangle, - exportDesc.excludeExports, - globalFrom && dep, - globalFrom - ) - ) { - changed = true; - } - } else if (Array.isArray(exports)) { - /** - * merge in new exports - * @param {ExportsInfo} exportsInfo own exports info - * @param {(ExportSpec | string)[]} exports list of exports - */ - const mergeExports = (exportsInfo, exports) => { - for (const exportNameOrSpec of exports) { - let name; - let canMangle = globalCanMangle; - let terminalBinding = globalTerminalBinding; - let exports = undefined; - let from = globalFrom; - let fromExport = undefined; - let hidden = false; - if (typeof exportNameOrSpec === "string") { - name = exportNameOrSpec; - } else { - name = exportNameOrSpec.name; - if (exportNameOrSpec.canMangle !== undefined) - canMangle = exportNameOrSpec.canMangle; - if (exportNameOrSpec.export !== undefined) - fromExport = exportNameOrSpec.export; - if (exportNameOrSpec.exports !== undefined) - exports = exportNameOrSpec.exports; - if (exportNameOrSpec.from !== undefined) - from = exportNameOrSpec.from; - if (exportNameOrSpec.terminalBinding !== undefined) - terminalBinding = exportNameOrSpec.terminalBinding; - if (exportNameOrSpec.hidden !== undefined) - hidden = exportNameOrSpec.hidden; - } - const exportInfo = exportsInfo.getExportInfo(name); - if (exportInfo.provided === false) { - exportInfo.provided = true; - changed = true; - } + if ( + exportInfo.provided === false || + exportInfo.provided === null + ) { + exportInfo.provided = true; + changed = true; + } - if ( - exportInfo.canMangleProvide !== false && - canMangle === false - ) { - exportInfo.canMangleProvide = false; - changed = true; - } + if ( + exportInfo.canMangleProvide !== false && + canMangle === false + ) { + exportInfo.canMangleProvide = false; + changed = true; + } - if (terminalBinding && !exportInfo.terminalBinding) { - exportInfo.terminalBinding = true; - changed = true; - } + if (terminalBinding && !exportInfo.terminalBinding) { + exportInfo.terminalBinding = true; + changed = true; + } - if (exports) { - const nestedExportsInfo = exportInfo.createNestedExportsInfo(); - mergeExports(nestedExportsInfo, exports); - } + if (exports) { + const nestedExportsInfo = + exportInfo.createNestedExportsInfo(); + mergeExports( + /** @type {ExportsInfo} */ (nestedExportsInfo), + exports + ); + } - if ( - from && - (hidden - ? exportInfo.unsetTarget(dep) - : exportInfo.setTarget( - dep, - from, - fromExport === undefined ? [name] : fromExport - )) - ) { - changed = true; - } + if ( + from && + (hidden + ? exportInfo.unsetTarget(dep) + : exportInfo.setTarget( + dep, + from, + fromExport === undefined ? [name] : fromExport, + priority + )) + ) { + changed = true; + } - // Recalculate target exportsInfo - const target = exportInfo.getTarget(moduleGraph); - let targetExportsInfo = undefined; - if (target) { - const targetModuleExportsInfo = moduleGraph.getExportsInfo( - target.module - ); - targetExportsInfo = targetModuleExportsInfo.getNestedExportsInfo( + // Recalculate target exportsInfo + const target = exportInfo.getTarget(moduleGraph); + let targetExportsInfo; + if (target) { + const targetModuleExportsInfo = + moduleGraph.getExportsInfo(target.module); + targetExportsInfo = + targetModuleExportsInfo.getNestedExportsInfo( target.export ); - // add dependency for this module - const set = dependencies.get(target.module); - if (set === undefined) { - dependencies.set(target.module, new Set([module])); - } else { - set.add(module); - } + // add dependency for this module + const set = dependencies.get(target.module); + if (set === undefined) { + dependencies.set(target.module, new Set([module])); + } else { + set.add(module); } + } - if (exportInfo.exportsInfoOwned) { - if ( - exportInfo.exportsInfo.setRedirectNamedTo( - targetExportsInfo - ) - ) { - changed = true; - } - } else if ( - exportInfo.exportsInfo !== targetExportsInfo + if (exportInfo.exportsInfoOwned) { + if ( + /** @type {ExportsInfo} */ + (exportInfo.exportsInfo).setRedirectNamedTo( + targetExportsInfo + ) ) { - exportInfo.exportsInfo = targetExportsInfo; changed = true; } + } else if (exportInfo.exportsInfo !== targetExportsInfo) { + exportInfo.exportsInfo = targetExportsInfo; + changed = true; } - }; - mergeExports(exportsInfo, exports); - } - // store dependencies - if (exportDeps) { - cacheable = false; - for (const exportDependency of exportDeps) { - // add dependency for this module - const set = dependencies.get(exportDependency); - if (set === undefined) { - dependencies.set(exportDependency, new Set([module])); - } else { - set.add(module); - } + } + }; + mergeExports(exportsInfo, exports); + } + // store dependencies + if (exportDeps) { + cacheable = false; + for (const exportDependency of exportDeps) { + // add dependency for this module + const set = dependencies.get(exportDependency); + if (set === undefined) { + dependencies.set(exportDependency, new Set([module])); + } else { + set.add(module); } } - }; + } + }; - const notifyDependencies = () => { - const deps = dependencies.get(module); - if (deps !== undefined) { - for (const dep of deps) { - queue.enqueue(dep); - } + const notifyDependencies = () => { + const deps = dependencies.get(module); + if (deps !== undefined) { + for (const dep of deps) { + queue.enqueue(dep); } - }; + } + }; - logger.time("figure out provided exports"); - while (queue.length > 0) { - module = queue.dequeue(); + logger.time("figure out provided exports"); + while (queue.length > 0) { + module = /** @type {Module} */ (queue.dequeue()); - statQueueItemsProcessed++; + statQueueItemsProcessed++; - exportsInfo = moduleGraph.getExportsInfo(module); - if (!module.buildMeta || !module.buildMeta.exportsType) { - if (exportsInfo.otherExportsInfo.provided !== null) { - // It's a module without declared exports - exportsInfo.setUnknownExportsProvided(); - modulesToStore.add(module); - notifyDependencies(); - } - } else { - // It's a module with declared exports + exportsInfo = moduleGraph.getExportsInfo(module); - cacheable = true; - changed = false; + cacheable = true; + changed = false; - processDependenciesBlock(module); + exportsSpecsFromDependencies.clear(); + moduleGraph.freeze(); + processDependenciesBlock(module); + moduleGraph.unfreeze(); + for (const [dep, exportsSpec] of exportsSpecsFromDependencies) { + processExportsSpec(dep, exportsSpec); + } - if (cacheable) { - modulesToStore.add(module); - } + if (cacheable) { + modulesToStore.add(module); + } - if (changed) { - notifyDependencies(); - } - } + if (changed) { + notifyDependencies(); } - logger.timeEnd("figure out provided exports"); - - logger.log( - `${Math.round( - 100 - - (100 * statRestoredFromCache) / - (statRestoredFromCache + - statNotCached + - statFlaggedUncached) - )}% of exports of modules have been determined (${statNotCached} not cached, ${statFlaggedUncached} flagged uncacheable, ${statRestoredFromCache} from cache, ${ - statQueueItemsProcessed - - statNotCached - - statFlaggedUncached - } additional calculations due to dependencies)` - ); - - logger.time("store provided exports into cache"); - asyncLib.each( - modulesToStore, - (module, callback) => { - if ( - module.buildInfo.cacheable !== true || - typeof module.buildInfo.hash !== "string" - ) { - // not cacheable - return callback(); - } - cache.store( - module.identifier(), - module.buildInfo.hash, - moduleGraph - .getExportsInfo(module) - .getRestoreProvidedData(), - callback - ); - }, - err => { - logger.timeEnd("store provided exports into cache"); - callback(err); - } - ); } - ); - } - ); - - /** @type {WeakMap} */ - const providedExportsCache = new WeakMap(); - compilation.hooks.rebuildModule.tap( - "FlagDependencyExportsPlugin", - module => { - providedExportsCache.set( - module, - moduleGraph.getExportsInfo(module).getRestoreProvidedData() - ); - } - ); - compilation.hooks.finishRebuildingModule.tap( - "FlagDependencyExportsPlugin", - module => { - moduleGraph - .getExportsInfo(module) - .restoreProvided(providedExportsCache.get(module)); - } + logger.timeEnd("figure out provided exports"); + + logger.log( + `${Math.round( + (100 * (statFlaggedUncached + statNotCached)) / + (statRestoredFromMemCache + + statRestoredFromCache + + statNotCached + + statFlaggedUncached + + statNoExports) + )}% of exports of modules have been determined (${statNoExports} no declared exports, ${statNotCached} not cached, ${statFlaggedUncached} flagged uncacheable, ${statRestoredFromCache} from cache, ${statRestoredFromMemCache} from mem cache, ${ + statQueueItemsProcessed - statNotCached - statFlaggedUncached + } additional calculations due to dependencies)` + ); + + logger.time("store provided exports into cache"); + asyncLib.each( + modulesToStore, + (module, callback) => { + if ( + typeof ( + /** @type {BuildInfo} */ (module.buildInfo).hash + ) !== "string" + ) { + // not cacheable + return callback(); + } + const cachedData = moduleGraph + .getExportsInfo(module) + .getRestoreProvidedData(); + const memCache = + moduleMemCaches && moduleMemCaches.get(module); + if (memCache) { + memCache.set(this, cachedData); + } + cache.store( + module.identifier(), + /** @type {BuildInfo} */ + (module.buildInfo).hash, + cachedData, + callback + ); + }, + err => { + logger.timeEnd("store provided exports into cache"); + callback(err); + } + ); + } + ); + } + ); + + /** @type {WeakMap} */ + const providedExportsCache = new WeakMap(); + compilation.hooks.rebuildModule.tap(PLUGIN_NAME, module => { + providedExportsCache.set( + module, + moduleGraph.getExportsInfo(module).getRestoreProvidedData() ); - } - ); + }); + compilation.hooks.finishRebuildingModule.tap(PLUGIN_NAME, module => { + moduleGraph + .getExportsInfo(module) + .restoreProvided(providedExportsCache.get(module)); + }); + }); } } diff --git a/lib/FlagDependencyUsagePlugin.js b/lib/FlagDependencyUsagePlugin.js index dfe0759bec3..247dbf90528 100644 --- a/lib/FlagDependencyUsagePlugin.js +++ b/lib/FlagDependencyUsagePlugin.js @@ -24,6 +24,9 @@ const { getEntryRuntime, mergeRuntimeOwned } = require("./util/runtime"); const { NO_EXPORTS_REFERENCED, EXPORTS_OBJECT_REFERENCED } = Dependency; +const PLUGIN_NAME = "FlagDependencyUsagePlugin"; +const PLUGIN_LOGGER_NAME = `webpack.${PLUGIN_NAME}`; + class FlagDependencyUsagePlugin { /** * @param {boolean} global do a global analysis instead of per runtime @@ -38,18 +41,18 @@ class FlagDependencyUsagePlugin { * @returns {void} */ apply(compiler) { - compiler.hooks.compilation.tap("FlagDependencyUsagePlugin", compilation => { + compiler.hooks.compilation.tap(PLUGIN_NAME, compilation => { const moduleGraph = compilation.moduleGraph; compilation.hooks.optimizeDependencies.tap( - { - name: "FlagDependencyUsagePlugin", - stage: STAGE_DEFAULT - }, + { name: PLUGIN_NAME, stage: STAGE_DEFAULT }, modules => { - const logger = compilation.getLogger( - "webpack.FlagDependencyUsagePlugin" - ); + if (compilation.moduleMemCaches) { + throw new Error( + "optimization.usedExports can't be used with cacheUnaffected as export usage is a global effect" + ); + } + const logger = compilation.getLogger(PLUGIN_LOGGER_NAME); /** @type {Map} */ const exportInfoToModuleMap = new Map(); @@ -180,7 +183,11 @@ class FlagDependencyUsagePlugin { b.groupOptions && b.groupOptions.entryOptions ) { - processModule(b, b.groupOptions.entryOptions.runtime, true); + processModule( + b, + b.groupOptions.entryOptions.runtime || undefined, + true + ); } else { queue.enqueue(b); } @@ -201,10 +208,8 @@ class FlagDependencyUsagePlugin { if (oldReferencedExports === EXPORTS_OBJECT_REFERENCED) { continue; } - const referencedExports = compilation.getDependencyReferencedExports( - dep, - runtime - ); + const referencedExports = + compilation.getDependencyReferencedExports(dep, runtime); if ( oldReferencedExports === undefined || oldReferencedExports === NO_EXPORTS_REFERENCED || @@ -303,7 +308,7 @@ class FlagDependencyUsagePlugin { } }; /** @type {RuntimeSpec} */ - let globalRuntime = undefined; + let globalRuntime; for (const [ entryName, { dependencies: deps, includeDependencies: includeDeps, options } @@ -327,7 +332,9 @@ class FlagDependencyUsagePlugin { } while (queue.length) { - const [module, runtime] = queue.dequeue(); + const [module, runtime] = /** @type {[Module, RuntimeSpec]} */ ( + queue.dequeue() + ); processModule(module, runtime, false); } logger.timeEnd("trace exports usage in graph"); diff --git a/lib/FlagEntryExportAsUsedPlugin.js b/lib/FlagEntryExportAsUsedPlugin.js index db636160972..d2826d12fb2 100644 --- a/lib/FlagEntryExportAsUsedPlugin.js +++ b/lib/FlagEntryExportAsUsedPlugin.js @@ -9,7 +9,13 @@ const { getEntryRuntime } = require("./util/runtime"); /** @typedef {import("./Compiler")} Compiler */ +const PLUGIN_NAME = "FlagEntryExportAsUsedPlugin"; + class FlagEntryExportAsUsedPlugin { + /** + * @param {boolean} nsObjectUsed true, if the ns object is used + * @param {string} explanation explanation for the reason + */ constructor(nsObjectUsed, explanation) { this.nsObjectUsed = nsObjectUsed; this.explanation = explanation; @@ -21,32 +27,29 @@ class FlagEntryExportAsUsedPlugin { * @returns {void} */ apply(compiler) { - compiler.hooks.thisCompilation.tap( - "FlagEntryExportAsUsedPlugin", - compilation => { - const moduleGraph = compilation.moduleGraph; - compilation.hooks.seal.tap("FlagEntryExportAsUsedPlugin", () => { - for (const [ - entryName, - { dependencies: deps, options } - ] of compilation.entries) { - const runtime = getEntryRuntime(compilation, entryName, options); - for (const dep of deps) { - const module = moduleGraph.getModule(dep); - if (module) { - const exportsInfo = moduleGraph.getExportsInfo(module); - if (this.nsObjectUsed) { - exportsInfo.setUsedInUnknownWay(runtime); - } else { - exportsInfo.setAllKnownExportsUsed(runtime); - } - moduleGraph.addExtraReason(module, this.explanation); + compiler.hooks.thisCompilation.tap(PLUGIN_NAME, compilation => { + const moduleGraph = compilation.moduleGraph; + compilation.hooks.seal.tap(PLUGIN_NAME, () => { + for (const [ + entryName, + { dependencies: deps, options } + ] of compilation.entries) { + const runtime = getEntryRuntime(compilation, entryName, options); + for (const dep of deps) { + const module = moduleGraph.getModule(dep); + if (module) { + const exportsInfo = moduleGraph.getExportsInfo(module); + if (this.nsObjectUsed) { + exportsInfo.setUsedInUnknownWay(runtime); + } else { + exportsInfo.setAllKnownExportsUsed(runtime); } + moduleGraph.addExtraReason(module, this.explanation); } } - }); - } - ); + } + }); + }); } } diff --git a/lib/Generator.js b/lib/Generator.js index 68477d322bf..f97a6955fe7 100644 --- a/lib/Generator.js +++ b/lib/Generator.js @@ -7,11 +7,13 @@ /** @typedef {import("webpack-sources").Source} Source */ /** @typedef {import("./ChunkGraph")} ChunkGraph */ +/** @typedef {import("./CodeGenerationResults")} CodeGenerationResults */ /** @typedef {import("./Compilation")} Compilation */ /** @typedef {import("./ConcatenationScope")} ConcatenationScope */ /** @typedef {import("./DependencyTemplate")} DependencyTemplate */ /** @typedef {import("./DependencyTemplates")} DependencyTemplates */ /** @typedef {import("./Module").ConcatenationBailoutReasonContext} ConcatenationBailoutReasonContext */ +/** @typedef {import("./Module").RuntimeRequirements} RuntimeRequirements */ /** @typedef {import("./ModuleGraph")} ModuleGraph */ /** @typedef {import("./NormalModule")} NormalModule */ /** @typedef {import("./RuntimeTemplate")} RuntimeTemplate */ @@ -19,29 +21,32 @@ /** @typedef {import("./util/runtime").RuntimeSpec} RuntimeSpec */ /** - * @typedef {Object} GenerateContext + * @typedef {object} GenerateContext * @property {DependencyTemplates} dependencyTemplates mapping from dependencies to templates * @property {RuntimeTemplate} runtimeTemplate the runtime template * @property {ModuleGraph} moduleGraph the module graph * @property {ChunkGraph} chunkGraph the chunk graph - * @property {Set} runtimeRequirements the requirements for runtime + * @property {RuntimeRequirements} runtimeRequirements the requirements for runtime * @property {RuntimeSpec} runtime the runtime * @property {ConcatenationScope=} concatenationScope when in concatenated module, information about other concatenated modules + * @property {CodeGenerationResults=} codeGenerationResults code generation results of other modules (need to have a codeGenerationDependency to use that) * @property {string} type which kind of code should be generated * @property {function(): Map=} getData get access to the code generation data */ /** - * @typedef {Object} UpdateHashContext + * @typedef {object} UpdateHashContext * @property {NormalModule} module the module * @property {ChunkGraph} chunkGraph * @property {RuntimeSpec} runtime + * @property {RuntimeTemplate=} runtimeTemplate */ -/** - * - */ class Generator { + /** + * @param {Record} map map of types + * @returns {ByTypeGenerator} generator by type + */ static byType(map) { return new ByTypeGenerator(map); } @@ -103,6 +108,9 @@ class Generator { } class ByTypeGenerator extends Generator { + /** + * @param {Record} map map of types + */ constructor(map) { super(); this.map = map; @@ -122,8 +130,8 @@ class ByTypeGenerator extends Generator { * @param {string=} type source type * @returns {number} estimate size of the module */ - getSize(module, type) { - const t = type || "javascript"; + getSize(module, type = "javascript") { + const t = type; const generator = this.map[t]; return generator ? generator.getSize(module, t) : 0; } diff --git a/lib/GraphHelpers.js b/lib/GraphHelpers.js index 2925ad7f503..65d7087281d 100644 --- a/lib/GraphHelpers.js +++ b/lib/GraphHelpers.js @@ -33,5 +33,6 @@ const connectChunkGroupParentAndChild = (parent, child) => { } }; -exports.connectChunkGroupAndChunk = connectChunkGroupAndChunk; -exports.connectChunkGroupParentAndChild = connectChunkGroupParentAndChild; +module.exports.connectChunkGroupAndChunk = connectChunkGroupAndChunk; +module.exports.connectChunkGroupParentAndChild = + connectChunkGroupParentAndChild; diff --git a/lib/HarmonyLinkingError.js b/lib/HarmonyLinkingError.js index 0d6d08310b2..8259beca634 100644 --- a/lib/HarmonyLinkingError.js +++ b/lib/HarmonyLinkingError.js @@ -12,7 +12,5 @@ module.exports = class HarmonyLinkingError extends WebpackError { super(message); this.name = "HarmonyLinkingError"; this.hideStack = true; - - Error.captureStackTrace(this, this.constructor); } }; diff --git a/lib/HookWebpackError.js b/lib/HookWebpackError.js index 0dce256f9cb..84702401a37 100644 --- a/lib/HookWebpackError.js +++ b/lib/HookWebpackError.js @@ -12,7 +12,7 @@ const WebpackError = require("./WebpackError"); /** * @template T * @callback Callback - * @param {Error=} err + * @param {Error | null} err * @param {T=} stats * @returns {void} */ @@ -32,7 +32,6 @@ class HookWebpackError extends WebpackError { this.hideStack = true; this.details = `caused by plugins in ${hook}\n${error.stack}`; - Error.captureStackTrace(this, this.constructor); this.stack += `\n-- inner error --\n${error.stack}`; } } @@ -52,22 +51,20 @@ module.exports.makeWebpackError = makeWebpackError; /** * @template T - * @param {function(WebpackError=, T=): void} callback webpack error callback + * @param {function(WebpackError | null, T=): void} callback webpack error callback * @param {string} hook name of hook * @returns {Callback} generic callback */ -const makeWebpackErrorCallback = (callback, hook) => { - return (err, result) => { - if (err) { - if (err instanceof WebpackError) { - callback(err); - return; - } - callback(new HookWebpackError(err, hook)); +const makeWebpackErrorCallback = (callback, hook) => (err, result) => { + if (err) { + if (err instanceof WebpackError) { + callback(err); return; } - callback(null, result); - }; + callback(new HookWebpackError(err, hook)); + return; + } + callback(null, result); }; module.exports.makeWebpackErrorCallback = makeWebpackErrorCallback; @@ -86,7 +83,7 @@ const tryRunOrWebpackError = (fn, hook) => { if (err instanceof WebpackError) { throw err; } - throw new HookWebpackError(err, hook); + throw new HookWebpackError(/** @type {Error} */ (err), hook); } return r; }; diff --git a/lib/HotModuleReplacementPlugin.js b/lib/HotModuleReplacementPlugin.js index be1f999d8d3..d339298140c 100644 --- a/lib/HotModuleReplacementPlugin.js +++ b/lib/HotModuleReplacementPlugin.js @@ -31,25 +31,47 @@ const { keyToRuntime, forEachRuntime, mergeRuntimeOwned, - subtractRuntime + subtractRuntime, + intersectRuntime } = require("./util/runtime"); +const { + JAVASCRIPT_MODULE_TYPE_AUTO, + JAVASCRIPT_MODULE_TYPE_DYNAMIC, + JAVASCRIPT_MODULE_TYPE_ESM, + WEBPACK_MODULE_TYPE_RUNTIME +} = require("./ModuleTypeConstants"); + +/** @typedef {import("estree").CallExpression} CallExpression */ +/** @typedef {import("estree").Expression} Expression */ +/** @typedef {import("../declarations/WebpackOptions").OutputNormalized} OutputNormalized */ /** @typedef {import("./Chunk")} Chunk */ +/** @typedef {import("./Chunk").ChunkId} ChunkId */ +/** @typedef {import("./ChunkGraph").ModuleId} ModuleId */ /** @typedef {import("./Compilation").AssetInfo} AssetInfo */ /** @typedef {import("./Compiler")} Compiler */ +/** @typedef {import("./Dependency").DependencyLocation} DependencyLocation */ /** @typedef {import("./Module")} Module */ +/** @typedef {import("./Module").BuildInfo} BuildInfo */ /** @typedef {import("./RuntimeModule")} RuntimeModule */ +/** @typedef {import("./javascript/BasicEvaluatedExpression")} BasicEvaluatedExpression */ +/** @typedef {import("./javascript/JavascriptParserHelpers").Range} Range */ /** @typedef {import("./util/runtime").RuntimeSpec} RuntimeSpec */ /** - * @typedef {Object} HMRJavascriptParserHooks + * @typedef {object} HMRJavascriptParserHooks * @property {SyncBailHook<[TODO, string[]], void>} hotAcceptCallback * @property {SyncBailHook<[TODO, string[]], void>} hotAcceptWithoutCallback */ +/** @typedef {{ updatedChunkIds: Set, removedChunkIds: Set, removedModules: Set, filename: string, assetInfo: AssetInfo }} HotUpdateMainContentByRuntimeItem */ +/** @typedef {Map} HotUpdateMainContentByRuntime */ + /** @type {WeakMap} */ const parserHooksMap = new WeakMap(); +const PLUGIN_NAME = "HotModuleReplacementPlugin"; + class HotModuleReplacementPlugin { /** * @param {JavascriptParser} parser the parser @@ -72,6 +94,9 @@ class HotModuleReplacementPlugin { return hooks; } + /** + * @param {object=} options options + */ constructor(options) { this.options = options || {}; } @@ -82,55 +107,71 @@ class HotModuleReplacementPlugin { * @returns {void} */ apply(compiler) { + const { _backCompat: backCompat } = compiler; if (compiler.options.output.strictModuleErrorHandling === undefined) compiler.options.output.strictModuleErrorHandling = true; const runtimeRequirements = [RuntimeGlobals.module]; + /** + * @param {JavascriptParser} parser the parser + * @param {typeof ModuleHotAcceptDependency} ParamDependency dependency + * @returns {(expr: CallExpression) => boolean | undefined} callback + */ const createAcceptHandler = (parser, ParamDependency) => { - const { - hotAcceptCallback, - hotAcceptWithoutCallback - } = HotModuleReplacementPlugin.getParserHooks(parser); + const { hotAcceptCallback, hotAcceptWithoutCallback } = + HotModuleReplacementPlugin.getParserHooks(parser); return expr => { const module = parser.state.module; const dep = new ConstDependency( `${module.moduleArgument}.hot.accept`, - expr.callee.range, + /** @type {Range} */ (expr.callee.range), runtimeRequirements ); - dep.loc = expr.loc; + dep.loc = /** @type {DependencyLocation} */ (expr.loc); module.addPresentationalDependency(dep); - module.buildInfo.moduleConcatenationBailout = "Hot Module Replacement"; + /** @type {BuildInfo} */ + (module.buildInfo).moduleConcatenationBailout = + "Hot Module Replacement"; if (expr.arguments.length >= 1) { - const arg = parser.evaluateExpression(expr.arguments[0]); + const arg = parser.evaluateExpression( + /** @type {Expression} */ (expr.arguments[0]) + ); + /** @type {BasicEvaluatedExpression[]} */ let params = []; - let requests = []; if (arg.isString()) { params = [arg]; } else if (arg.isArray()) { - params = arg.items.filter(param => param.isString()); + params = + /** @type {BasicEvaluatedExpression[]} */ + (arg.items).filter(param => param.isString()); } + /** @type {string[]} */ + const requests = []; if (params.length > 0) { - params.forEach((param, idx) => { - const request = param.string; - const dep = new ParamDependency(request, param.range); + for (const [idx, param] of params.entries()) { + const request = /** @type {string} */ (param.string); + const dep = new ParamDependency( + request, + /** @type {Range} */ (param.range) + ); dep.optional = true; - dep.loc = Object.create(expr.loc); + dep.loc = Object.create( + /** @type {DependencyLocation} */ (expr.loc) + ); dep.loc.index = idx; module.addDependency(dep); requests.push(request); - }); + } if (expr.arguments.length > 1) { hotAcceptCallback.call(expr.arguments[1], requests); for (let i = 1; i < expr.arguments.length; i++) { parser.walkExpression(expr.arguments[i]); } return true; - } else { - hotAcceptWithoutCallback.call(expr, requests); - return true; } + hotAcceptWithoutCallback.call(expr, requests); + return true; } } parser.walkExpressions(expr.arguments); @@ -138,116 +179,140 @@ class HotModuleReplacementPlugin { }; }; + /** + * @param {JavascriptParser} parser the parser + * @param {typeof ModuleHotDeclineDependency} ParamDependency dependency + * @returns {(expr: CallExpression) => boolean | undefined} callback + */ const createDeclineHandler = (parser, ParamDependency) => expr => { const module = parser.state.module; const dep = new ConstDependency( `${module.moduleArgument}.hot.decline`, - expr.callee.range, + /** @type {Range} */ (expr.callee.range), runtimeRequirements ); - dep.loc = expr.loc; + dep.loc = /** @type {DependencyLocation} */ (expr.loc); module.addPresentationalDependency(dep); - module.buildInfo.moduleConcatenationBailout = "Hot Module Replacement"; + /** @type {BuildInfo} */ + (module.buildInfo).moduleConcatenationBailout = "Hot Module Replacement"; if (expr.arguments.length === 1) { const arg = parser.evaluateExpression(expr.arguments[0]); + /** @type {BasicEvaluatedExpression[]} */ let params = []; if (arg.isString()) { params = [arg]; } else if (arg.isArray()) { - params = arg.items.filter(param => param.isString()); + params = + /** @type {BasicEvaluatedExpression[]} */ + (arg.items).filter(param => param.isString()); } - params.forEach((param, idx) => { - const dep = new ParamDependency(param.string, param.range); + for (const [idx, param] of params.entries()) { + const dep = new ParamDependency( + /** @type {string} */ (param.string), + /** @type {Range} */ (param.range) + ); dep.optional = true; - dep.loc = Object.create(expr.loc); + dep.loc = Object.create(/** @type {DependencyLocation} */ (expr.loc)); dep.loc.index = idx; module.addDependency(dep); - }); + } } return true; }; + /** + * @param {JavascriptParser} parser the parser + * @returns {(expr: Expression) => boolean | undefined} callback + */ const createHMRExpressionHandler = parser => expr => { const module = parser.state.module; const dep = new ConstDependency( `${module.moduleArgument}.hot`, - expr.range, + /** @type {Range} */ (expr.range), runtimeRequirements ); - dep.loc = expr.loc; + dep.loc = /** @type {DependencyLocation} */ (expr.loc); module.addPresentationalDependency(dep); - module.buildInfo.moduleConcatenationBailout = "Hot Module Replacement"; + /** @type {BuildInfo} */ + (module.buildInfo).moduleConcatenationBailout = "Hot Module Replacement"; return true; }; + /** + * @param {JavascriptParser} parser the parser + * @returns {void} + */ const applyModuleHot = parser => { parser.hooks.evaluateIdentifier.for("module.hot").tap( { - name: "HotModuleReplacementPlugin", + name: PLUGIN_NAME, before: "NodeStuffPlugin" }, - expr => { - return evaluateToIdentifier( + expr => + evaluateToIdentifier( "module.hot", "module", () => ["hot"], true - )(expr); - } + )(expr) ); parser.hooks.call .for("module.hot.accept") .tap( - "HotModuleReplacementPlugin", + PLUGIN_NAME, createAcceptHandler(parser, ModuleHotAcceptDependency) ); parser.hooks.call .for("module.hot.decline") .tap( - "HotModuleReplacementPlugin", + PLUGIN_NAME, createDeclineHandler(parser, ModuleHotDeclineDependency) ); parser.hooks.expression .for("module.hot") - .tap("HotModuleReplacementPlugin", createHMRExpressionHandler(parser)); + .tap(PLUGIN_NAME, createHMRExpressionHandler(parser)); }; + /** + * @param {JavascriptParser} parser the parser + * @returns {void} + */ const applyImportMetaHot = parser => { parser.hooks.evaluateIdentifier .for("import.meta.webpackHot") - .tap("HotModuleReplacementPlugin", expr => { - return evaluateToIdentifier( + .tap(PLUGIN_NAME, expr => + evaluateToIdentifier( "import.meta.webpackHot", "import.meta", () => ["webpackHot"], true - )(expr); - }); + )(expr) + ); parser.hooks.call .for("import.meta.webpackHot.accept") .tap( - "HotModuleReplacementPlugin", + PLUGIN_NAME, createAcceptHandler(parser, ImportMetaHotAcceptDependency) ); parser.hooks.call .for("import.meta.webpackHot.decline") .tap( - "HotModuleReplacementPlugin", + PLUGIN_NAME, createDeclineHandler(parser, ImportMetaHotDeclineDependency) ); parser.hooks.expression .for("import.meta.webpackHot") - .tap("HotModuleReplacementPlugin", createHMRExpressionHandler(parser)); + .tap(PLUGIN_NAME, createHMRExpressionHandler(parser)); }; compiler.hooks.compilation.tap( - "HotModuleReplacementPlugin", + PLUGIN_NAME, (compilation, { normalModuleFactory }) => { // This applies the HMR plugin only to the targeted compiler // It should not affect child compilations if (compilation.compiler !== compiler) return; - //#region module.hot.* API + // #region module.hot.* API compilation.dependencyFactories.set( ModuleHotAcceptDependency, normalModuleFactory @@ -264,9 +329,9 @@ class HotModuleReplacementPlugin { ModuleHotDeclineDependency, new ModuleHotDeclineDependency.Template() ); - //#endregion + // #endregion - //#region import.meta.webpackHot.* API + // #region import.meta.webpackHot.* API compilation.dependencyFactories.set( ImportMetaHotAcceptDependency, normalModuleFactory @@ -283,51 +348,54 @@ class HotModuleReplacementPlugin { ImportMetaHotDeclineDependency, new ImportMetaHotDeclineDependency.Template() ); - //#endregion + // #endregion let hotIndex = 0; + /** @type {Record} */ const fullHashChunkModuleHashes = {}; + /** @type {Record} */ const chunkModuleHashes = {}; - compilation.hooks.record.tap( - "HotModuleReplacementPlugin", - (compilation, records) => { - if (records.hash === compilation.hash) return; - const chunkGraph = compilation.chunkGraph; - records.hash = compilation.hash; - records.hotIndex = hotIndex; - records.fullHashChunkModuleHashes = fullHashChunkModuleHashes; - records.chunkModuleHashes = chunkModuleHashes; - records.chunkHashs = {}; - records.chunkRuntime = {}; - for (const chunk of compilation.chunks) { - records.chunkHashs[chunk.id] = chunk.hash; - records.chunkRuntime[chunk.id] = getRuntimeKey(chunk.runtime); - } - records.chunkModuleIds = {}; - for (const chunk of compilation.chunks) { - records.chunkModuleIds[ - chunk.id - ] = Array.from( + compilation.hooks.record.tap(PLUGIN_NAME, (compilation, records) => { + if (records.hash === compilation.hash) return; + const chunkGraph = compilation.chunkGraph; + records.hash = compilation.hash; + records.hotIndex = hotIndex; + records.fullHashChunkModuleHashes = fullHashChunkModuleHashes; + records.chunkModuleHashes = chunkModuleHashes; + records.chunkHashes = {}; + records.chunkRuntime = {}; + for (const chunk of compilation.chunks) { + const chunkId = /** @type {ChunkId} */ (chunk.id); + records.chunkHashes[chunkId] = chunk.hash; + records.chunkRuntime[chunkId] = getRuntimeKey(chunk.runtime); + } + records.chunkModuleIds = {}; + for (const chunk of compilation.chunks) { + records.chunkModuleIds[/** @type {ChunkId} */ (chunk.id)] = + Array.from( chunkGraph.getOrderedChunkModulesIterable( chunk, compareModulesById(chunkGraph) ), m => chunkGraph.getModuleId(m) ); - } } - ); + }); /** @type {TupleSet<[Module, Chunk]>} */ const updatedModules = new TupleSet(); /** @type {TupleSet<[Module, Chunk]>} */ const fullHashModules = new TupleSet(); /** @type {TupleSet<[Module, RuntimeSpec]>} */ const nonCodeGeneratedModules = new TupleSet(); - compilation.hooks.fullHash.tap("HotModuleReplacementPlugin", hash => { + compilation.hooks.fullHash.tap(PLUGIN_NAME, hash => { const chunkGraph = compilation.chunkGraph; const records = compilation.records; for (const chunk of compilation.chunks) { + /** + * @param {Module} module module + * @returns {string} module hash + */ const getModuleHash = module => { if ( compilation.codeGenerationResults.has(module, chunk.runtime) @@ -336,14 +404,12 @@ class HotModuleReplacementPlugin { module, chunk.runtime ); - } else { - nonCodeGeneratedModules.add(module, chunk.runtime); - return chunkGraph.getModuleHash(module, chunk.runtime); } + nonCodeGeneratedModules.add(module, chunk.runtime); + return chunkGraph.getModuleHash(module, chunk.runtime); }; - const fullHashModulesInThisChunk = chunkGraph.getChunkFullHashModulesSet( - chunk - ); + const fullHashModulesInThisChunk = + chunkGraph.getChunkFullHashModulesSet(chunk); if (fullHashModulesInThisChunk !== undefined) { for (const module of fullHashModulesInThisChunk) { fullHashModules.add(module, chunk); @@ -382,28 +448,26 @@ class HotModuleReplacementPlugin { chunkModuleHashes[key] = hash; } } - } else { - if (fullHashModulesInThisChunk !== undefined) { - for (const module of modules) { - const key = `${chunk.id}|${module.identifier()}`; - const hash = getModuleHash(module); - if ( - fullHashModulesInThisChunk.has( - /** @type {RuntimeModule} */ (module) - ) - ) { - fullHashChunkModuleHashes[key] = hash; - } else { - chunkModuleHashes[key] = hash; - } - } - } else { - for (const module of modules) { - const key = `${chunk.id}|${module.identifier()}`; - const hash = getModuleHash(module); + } else if (fullHashModulesInThisChunk !== undefined) { + for (const module of modules) { + const key = `${chunk.id}|${module.identifier()}`; + const hash = getModuleHash(module); + if ( + fullHashModulesInThisChunk.has( + /** @type {RuntimeModule} */ (module) + ) + ) { + fullHashChunkModuleHashes[key] = hash; + } else { chunkModuleHashes[key] = hash; } } + } else { + for (const module of modules) { + const key = `${chunk.id}|${module.identifier()}`; + const hash = getModuleHash(module); + chunkModuleHashes[key] = hash; + } } } } @@ -415,7 +479,7 @@ class HotModuleReplacementPlugin { }); compilation.hooks.processAssets.tap( { - name: "HotModuleReplacementPlugin", + name: PLUGIN_NAME, stage: Compilation.PROCESS_ASSETS_STAGE_ADDITIONAL }, () => { @@ -424,7 +488,7 @@ class HotModuleReplacementPlugin { if (records.hash === compilation.hash) return; if ( !records.chunkModuleHashes || - !records.chunkHashs || + !records.chunkHashes || !records.chunkModuleIds ) { return; @@ -436,14 +500,14 @@ class HotModuleReplacementPlugin { : compilation.codeGenerationResults.getHash( module, chunk.runtime - ); + ); if (records.chunkModuleHashes[key] !== hash) { updatedModules.add(module, chunk); } chunkModuleHashes[key] = hash; } - /** @type {Map, removedChunkIds: Set, removedModules: Set, filename: string, assetInfo: AssetInfo }>} */ + /** @type {HotUpdateMainContentByRuntime} */ const hotUpdateMainContentByRuntime = new Map(); let allOldRuntime; for (const key of Object.keys(records.chunkRuntime)) { @@ -451,23 +515,25 @@ class HotModuleReplacementPlugin { allOldRuntime = mergeRuntimeOwned(allOldRuntime, runtime); } forEachRuntime(allOldRuntime, runtime => { - const { - path: filename, - info: assetInfo - } = compilation.getPathWithInfo( - compilation.outputOptions.hotUpdateMainFilename, + const { path: filename, info: assetInfo } = + compilation.getPathWithInfo( + /** @type {NonNullable} */ + (compilation.outputOptions.hotUpdateMainFilename), + { + hash: records.hash, + runtime + } + ); + hotUpdateMainContentByRuntime.set( + /** @type {string} */ (runtime), { - hash: records.hash, - runtime + updatedChunkIds: new Set(), + removedChunkIds: new Set(), + removedModules: new Set(), + filename, + assetInfo } ); - hotUpdateMainContentByRuntime.set(runtime, { - updatedChunkIds: new Set(), - removedChunkIds: new Set(), - removedModules: new Set(), - filename, - assetInfo - }); }); if (hotUpdateMainContentByRuntime.size === 0) return; @@ -475,7 +541,9 @@ class HotModuleReplacementPlugin { /** @type {Map} */ const allModules = new Map(); for (const module of compilation.modules) { - const id = chunkGraph.getModuleId(module); + const id = + /** @type {ModuleId} */ + (chunkGraph.getModuleId(module)); allModules.set(id, module); } @@ -483,7 +551,7 @@ class HotModuleReplacementPlugin { /** @type {Set} */ const completelyRemovedModules = new Set(); - for (const key of Object.keys(records.chunkHashs)) { + for (const key of Object.keys(records.chunkHashes)) { const oldRuntime = keyToRuntime(records.chunkRuntime[key]); /** @type {Module[]} */ const remainingModules = []; @@ -497,10 +565,12 @@ class HotModuleReplacementPlugin { } } + /** @type {ChunkId | null} */ let chunkId; let newModules; let newRuntimeModules; let newFullHashModules; + let newDependentHashModules; let newRuntime; let removedFromRuntime; const currentChunk = find( @@ -509,34 +579,49 @@ class HotModuleReplacementPlugin { ); if (currentChunk) { chunkId = currentChunk.id; - newRuntime = currentChunk.runtime; + newRuntime = intersectRuntime( + currentChunk.runtime, + allOldRuntime + ); + if (newRuntime === undefined) continue; newModules = chunkGraph .getChunkModules(currentChunk) .filter(module => updatedModules.has(module, currentChunk)); newRuntimeModules = Array.from( chunkGraph.getChunkRuntimeModulesIterable(currentChunk) ).filter(module => updatedModules.has(module, currentChunk)); - const fullHashModules = chunkGraph.getChunkFullHashModulesIterable( - currentChunk - ); + const fullHashModules = + chunkGraph.getChunkFullHashModulesIterable(currentChunk); newFullHashModules = fullHashModules && Array.from(fullHashModules).filter(module => updatedModules.has(module, currentChunk) ); + const dependentHashModules = + chunkGraph.getChunkDependentHashModulesIterable(currentChunk); + newDependentHashModules = + dependentHashModules && + Array.from(dependentHashModules).filter(module => + updatedModules.has(module, currentChunk) + ); removedFromRuntime = subtractRuntime(oldRuntime, newRuntime); } else { // chunk has completely removed - chunkId = `${+key}` === key ? +key : key; + chunkId = `${Number(key)}` === key ? Number(key) : key; removedFromRuntime = oldRuntime; newRuntime = oldRuntime; } if (removedFromRuntime) { // chunk was removed from some runtimes forEachRuntime(removedFromRuntime, runtime => { - hotUpdateMainContentByRuntime - .get(runtime) - .removedChunkIds.add(chunkId); + const item = + /** @type {HotUpdateMainContentByRuntimeItem} */ + ( + hotUpdateMainContentByRuntime.get( + /** @type {string} */ (runtime) + ) + ); + item.removedChunkIds.add(/** @type {ChunkId} */ (chunkId)); }); // dispose modules from the chunk in these runtimes // where they are no longer in this runtime @@ -551,9 +636,9 @@ class HotModuleReplacementPlugin { : compilation.codeGenerationResults.getHash( module, newRuntime - ); + ); if (hash !== oldHash) { - if (module.type === "runtime") { + if (module.type === WEBPACK_MODULE_TYPE_RUNTIME) { newRuntimeModules = newRuntimeModules || []; newRuntimeModules.push( /** @type {RuntimeModule} */ (module) @@ -576,13 +661,19 @@ class HotModuleReplacementPlugin { for (const moduleRuntime of runtimes) { if (typeof moduleRuntime === "string") { if (moduleRuntime === runtime) return; - } else if (moduleRuntime !== undefined) { - if (moduleRuntime.has(runtime)) return; - } + } else if ( + moduleRuntime !== undefined && + moduleRuntime.has(/** @type {string} */ (runtime)) + ) + return; } - hotUpdateMainContentByRuntime - .get(runtime) - .removedModules.add(module); + const item = + /** @type {HotUpdateMainContentByRuntimeItem} */ ( + hotUpdateMainContentByRuntime.get( + /** @type {string} */ (runtime) + ) + ); + item.removedModules.add(module); }); } } @@ -592,7 +683,8 @@ class HotModuleReplacementPlugin { (newRuntimeModules && newRuntimeModules.length > 0) ) { const hotUpdateChunk = new HotUpdateChunk(); - ChunkGraph.setChunkGraphForChunk(hotUpdateChunk, chunkGraph); + if (backCompat) + ChunkGraph.setChunkGraphForChunk(hotUpdateChunk, chunkGraph); hotUpdateChunk.id = chunkId; hotUpdateChunk.runtime = newRuntime; if (currentChunk) { @@ -610,6 +702,12 @@ class HotModuleReplacementPlugin { newFullHashModules ); } + if (newDependentHashModules) { + chunkGraph.attachDependentHashModules( + hotUpdateChunk, + newDependentHashModules + ); + } const renderManifest = compilation.getRenderManifest({ chunk: hotUpdateChunk, hash: records.hash, @@ -631,13 +729,11 @@ class HotModuleReplacementPlugin { filename = entry.filename; assetInfo = entry.info; } else { - ({ - path: filename, - info: assetInfo - } = compilation.getPathWithInfo( - entry.filenameTemplate, - entry.pathOptions - )); + ({ path: filename, info: assetInfo } = + compilation.getPathWithInfo( + entry.filenameTemplate, + entry.pathOptions + )); } const source = entry.render(); compilation.additionalChunkAssets.push(filename); @@ -651,9 +747,13 @@ class HotModuleReplacementPlugin { } } forEachRuntime(newRuntime, runtime => { - hotUpdateMainContentByRuntime - .get(runtime) - .updatedChunkIds.add(chunkId); + const item = + /** @type {HotUpdateMainContentByRuntimeItem} */ ( + hotUpdateMainContentByRuntime.get( + /** @type {string} */ (runtime) + ) + ); + item.updatedChunkIds.add(/** @type {ChunkId} */ (chunkId)); }); } } @@ -707,10 +807,12 @@ To fix this, make sure to include [runtime] in the output.hotUpdateMainFilename removedModules.size === 0 ? completelyRemovedModulesArray : completelyRemovedModulesArray.concat( - Array.from(removedModules, m => - chunkGraph.getModuleId(m) + Array.from( + removedModules, + m => + /** @type {ModuleId} */ (chunkGraph.getModuleId(m)) ) - ) + ) }; const source = new RawSource(JSON.stringify(hotUpdateMainJson)); @@ -723,7 +825,7 @@ To fix this, make sure to include [runtime] in the output.hotUpdateMainFilename ); compilation.hooks.additionalTreeRuntimeRequirements.tap( - "HotModuleReplacementPlugin", + PLUGIN_NAME, (chunk, runtimeRequirements) => { runtimeRequirements.add(RuntimeGlobals.hmrDownloadManifest); runtimeRequirements.add(RuntimeGlobals.hmrDownloadUpdateHandlers); @@ -737,24 +839,24 @@ To fix this, make sure to include [runtime] in the output.hotUpdateMainFilename ); normalModuleFactory.hooks.parser - .for("javascript/auto") - .tap("HotModuleReplacementPlugin", parser => { + .for(JAVASCRIPT_MODULE_TYPE_AUTO) + .tap(PLUGIN_NAME, parser => { applyModuleHot(parser); applyImportMetaHot(parser); }); normalModuleFactory.hooks.parser - .for("javascript/dynamic") - .tap("HotModuleReplacementPlugin", parser => { + .for(JAVASCRIPT_MODULE_TYPE_DYNAMIC) + .tap(PLUGIN_NAME, parser => { applyModuleHot(parser); }); normalModuleFactory.hooks.parser - .for("javascript/esm") - .tap("HotModuleReplacementPlugin", parser => { + .for(JAVASCRIPT_MODULE_TYPE_ESM) + .tap(PLUGIN_NAME, parser => { applyImportMetaHot(parser); }); NormalModule.getCompilationHooks(compilation).loader.tap( - "HotModuleReplacementPlugin", + PLUGIN_NAME, context => { context.hot = true; } diff --git a/lib/IgnoreErrorModuleFactory.js b/lib/IgnoreErrorModuleFactory.js index ceae85f6209..4fd73e7fa8b 100644 --- a/lib/IgnoreErrorModuleFactory.js +++ b/lib/IgnoreErrorModuleFactory.js @@ -26,13 +26,13 @@ class IgnoreErrorModuleFactory extends ModuleFactory { /** * @param {ModuleFactoryCreateData} data data object - * @param {function(Error=, ModuleFactoryResult=): void} callback callback + * @param {function((Error | null)=, ModuleFactoryResult=): void} callback callback * @returns {void} */ create(data, callback) { - this.normalModuleFactory.create(data, (err, result) => { - return callback(null, result); - }); + this.normalModuleFactory.create(data, (err, result) => + callback(null, result) + ); } } diff --git a/lib/IgnorePlugin.js b/lib/IgnorePlugin.js index 39eb7ecbc86..8d6bb619edb 100644 --- a/lib/IgnorePlugin.js +++ b/lib/IgnorePlugin.js @@ -5,32 +5,38 @@ "use strict"; -const { validate } = require("schema-utils"); -const schema = require("../schemas/plugins/IgnorePlugin.json"); +const createSchemaValidation = require("./util/create-schema-validation"); /** @typedef {import("../declarations/plugins/IgnorePlugin").IgnorePluginOptions} IgnorePluginOptions */ /** @typedef {import("./Compiler")} Compiler */ /** @typedef {import("./NormalModuleFactory").ResolveData} ResolveData */ +const validate = createSchemaValidation( + require("../schemas/plugins/IgnorePlugin.check.js"), + () => require("../schemas/plugins/IgnorePlugin.json"), + { + name: "Ignore Plugin", + baseDataPath: "options" + } +); + class IgnorePlugin { /** * @param {IgnorePluginOptions} options IgnorePlugin options */ constructor(options) { - validate(schema, options, { - name: "Ignore Plugin", - baseDataPath: "options" - }); + validate(options); this.options = options; - /** @private @type {Function} */ + /** + * @private + * @type {Function} + */ this.checkIgnore = this.checkIgnore.bind(this); } /** - * Note that if "contextRegExp" is given, both the "resourceRegExp" - * and "contextRegExp" have to match. - * + * Note that if "contextRegExp" is given, both the "resourceRegExp" and "contextRegExp" have to match. * @param {ResolveData} resolveData resolve data * @returns {false|undefined} returns false when the request should be ignored, otherwise undefined */ diff --git a/lib/IgnoreWarningsPlugin.js b/lib/IgnoreWarningsPlugin.js index 7b5c6cb1adb..e844a8369e4 100644 --- a/lib/IgnoreWarningsPlugin.js +++ b/lib/IgnoreWarningsPlugin.js @@ -15,6 +15,7 @@ class IgnoreWarningsPlugin { constructor(ignoreWarnings) { this._ignoreWarnings = ignoreWarnings; } + /** * Apply the plugin * @param {Compiler} compiler the compiler instance @@ -22,15 +23,11 @@ class IgnoreWarningsPlugin { */ apply(compiler) { compiler.hooks.compilation.tap("IgnoreWarningsPlugin", compilation => { - compilation.hooks.processWarnings.tap( - "IgnoreWarningsPlugin", - warnings => { - return warnings.filter(warning => { - return !this._ignoreWarnings.some(ignore => - ignore(warning, compilation) - ); - }); - } + compilation.hooks.processWarnings.tap("IgnoreWarningsPlugin", warnings => + warnings.filter( + warning => + !this._ignoreWarnings.some(ignore => ignore(warning, compilation)) + ) ); }); } diff --git a/lib/InitFragment.js b/lib/InitFragment.js index ea97de43777..7a5d9630771 100644 --- a/lib/InitFragment.js +++ b/lib/InitFragment.js @@ -6,20 +6,25 @@ "use strict"; const { ConcatSource } = require("webpack-sources"); +const makeSerializable = require("./util/makeSerializable"); /** @typedef {import("webpack-sources").Source} Source */ /** @typedef {import("./Generator").GenerateContext} GenerateContext */ +/** @typedef {import("./serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */ +/** @typedef {import("./serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */ /** - * @param {InitFragment} fragment the init fragment + * @template T + * @param {InitFragment} fragment the init fragment * @param {number} index index - * @returns {[InitFragment, number]} tuple with both + * @returns {[InitFragment, number]} tuple with both */ const extractFragmentIndex = (fragment, index) => [fragment, index]; /** - * @param {[InitFragment, number]} a first pair - * @param {[InitFragment, number]} b second pair + * @template T + * @param {[InitFragment, number]} a first pair + * @param {[InitFragment, number]} b second pair * @returns {number} sort value */ const sortFragmentWithIndex = ([a, i], [b, j]) => { @@ -30,13 +35,16 @@ const sortFragmentWithIndex = ([a, i], [b, j]) => { return i - j; }; +/** + * @template GenerateContext + */ class InitFragment { /** - * @param {string|Source} content the source code that will be included as initialization code + * @param {string | Source | undefined} content the source code that will be included as initialization code * @param {number} stage category of initialization code (contribute to order) * @param {number} position position in the category (contribute to order) * @param {string=} key unique key to avoid emitting the same initialization code twice - * @param {string|Source=} endContent the source code that will be included at the end of the module + * @param {string | Source=} endContent the source code that will be included at the end of the module */ constructor(content, stage, position, key, endContent) { this.content = content; @@ -47,22 +55,30 @@ class InitFragment { } /** - * @param {GenerateContext} generateContext context for generate - * @returns {string|Source} the source code that will be included as initialization code + * @param {GenerateContext} context context + * @returns {string | Source | undefined} the source code that will be included as initialization code */ - getContent(generateContext) { + getContent(context) { return this.content; } /** - * @param {GenerateContext} generateContext context for generate + * @param {GenerateContext} context context * @returns {string|Source=} the source code that will be included at the end of the module */ - getEndContent(generateContext) { + getEndContent(context) { return this.endContent; } - static addToSource(source, initFragments, generateContext) { + /** + * @template Context + * @template T + * @param {Source} source sources + * @param {InitFragment[]} initFragments init fragments + * @param {Context} context context + * @returns {Source} source + */ + static addToSource(source, initFragments, context) { if (initFragments.length > 0) { // Sort fragments by position. If 2 fragments have the same position, // use their index. @@ -73,24 +89,44 @@ class InitFragment { // Deduplicate fragments. If a fragment has no key, it is always included. const keyedFragments = new Map(); for (const [fragment] of sortedFragments) { - if (typeof fragment.merge === "function") { + if ( + typeof ( + /** @type {InitFragment & { mergeAll?: (fragments: InitFragment[]) => InitFragment[] }} */ + (fragment).mergeAll + ) === "function" + ) { + if (!fragment.key) { + throw new Error( + `InitFragment with mergeAll function must have a valid key: ${fragment.constructor.name}` + ); + } + const oldValue = keyedFragments.get(fragment.key); + if (oldValue === undefined) { + keyedFragments.set(fragment.key, fragment); + } else if (Array.isArray(oldValue)) { + oldValue.push(fragment); + } else { + keyedFragments.set(fragment.key, [oldValue, fragment]); + } + continue; + } else if (typeof fragment.merge === "function") { const oldValue = keyedFragments.get(fragment.key); if (oldValue !== undefined) { - keyedFragments.set( - fragment.key || Symbol(), - fragment.merge(oldValue) - ); + keyedFragments.set(fragment.key, fragment.merge(oldValue)); continue; } } - keyedFragments.set(fragment.key || Symbol(), fragment); + keyedFragments.set(fragment.key || Symbol("fragment key"), fragment); } const concatSource = new ConcatSource(); const endContents = []; - for (const fragment of keyedFragments.values()) { - concatSource.add(fragment.getContent(generateContext)); - const endContent = fragment.getEndContent(generateContext); + for (let fragment of keyedFragments.values()) { + if (Array.isArray(fragment)) { + fragment = fragment[0].mergeAll(fragment); + } + concatSource.add(fragment.getContent(context)); + const endContent = fragment.getEndContent(context); if (endContent) { endContents.push(endContent); } @@ -101,13 +137,42 @@ class InitFragment { concatSource.add(content); } return concatSource; - } else { - return source; } + return source; + } + + /** + * @param {ObjectSerializerContext} context context + */ + serialize(context) { + const { write } = context; + + write(this.content); + write(this.stage); + write(this.position); + write(this.key); + write(this.endContent); + } + + /** + * @param {ObjectDeserializerContext} context context + */ + deserialize(context) { + const { read } = context; + + this.content = read(); + this.stage = read(); + this.position = read(); + this.key = read(); + this.endContent = read(); } } -InitFragment.prototype.merge = undefined; +makeSerializable(InitFragment, "webpack/lib/InitFragment"); + +InitFragment.prototype.merge = + /** @type {TODO} */ + (undefined); InitFragment.STAGE_CONSTANTS = 10; InitFragment.STAGE_ASYNC_BOUNDARY = 20; diff --git a/lib/InvalidDependenciesModuleWarning.js b/lib/InvalidDependenciesModuleWarning.js index 74a4e2ea63d..a69eed58d92 100644 --- a/lib/InvalidDependenciesModuleWarning.js +++ b/lib/InvalidDependenciesModuleWarning.js @@ -33,8 +33,6 @@ ${depsList.slice(0, 3).join("\n")}${ this.name = "InvalidDependenciesModuleWarning"; this.details = depsList.slice(3).join("\n"); this.module = module; - - Error.captureStackTrace(this, this.constructor); } } diff --git a/lib/JavascriptMetaInfoPlugin.js b/lib/JavascriptMetaInfoPlugin.js index a696fbdbb5e..b8f77bea369 100644 --- a/lib/JavascriptMetaInfoPlugin.js +++ b/lib/JavascriptMetaInfoPlugin.js @@ -5,11 +5,19 @@ "use strict"; +const { + JAVASCRIPT_MODULE_TYPE_AUTO, + JAVASCRIPT_MODULE_TYPE_DYNAMIC, + JAVASCRIPT_MODULE_TYPE_ESM +} = require("./ModuleTypeConstants"); const InnerGraph = require("./optimize/InnerGraph"); /** @typedef {import("./Compiler")} Compiler */ +/** @typedef {import("./Module").BuildInfo} BuildInfo */ /** @typedef {import("./javascript/JavascriptParser")} JavascriptParser */ +const PLUGIN_NAME = "JavascriptMetaInfoPlugin"; + class JavascriptMetaInfoPlugin { /** * Apply the plugin @@ -18,23 +26,33 @@ class JavascriptMetaInfoPlugin { */ apply(compiler) { compiler.hooks.compilation.tap( - "JavascriptMetaInfoPlugin", + PLUGIN_NAME, (compilation, { normalModuleFactory }) => { /** * @param {JavascriptParser} parser the parser * @returns {void} */ const handler = parser => { - parser.hooks.call.for("eval").tap("JavascriptMetaInfoPlugin", () => { - parser.state.module.buildInfo.moduleConcatenationBailout = "eval()"; - parser.state.module.buildInfo.usingEval = true; - InnerGraph.bailout(parser.state); + parser.hooks.call.for("eval").tap(PLUGIN_NAME, () => { + const buildInfo = + /** @type {BuildInfo} */ + (parser.state.module.buildInfo); + buildInfo.moduleConcatenationBailout = "eval()"; + buildInfo.usingEval = true; + const currentSymbol = InnerGraph.getTopLevelSymbol(parser.state); + if (currentSymbol) { + InnerGraph.addUsage(parser.state, null, currentSymbol); + } else { + InnerGraph.bailout(parser.state); + } }); - parser.hooks.finish.tap("JavascriptMetaInfoPlugin", () => { - let topLevelDeclarations = - parser.state.module.buildInfo.topLevelDeclarations; + parser.hooks.finish.tap(PLUGIN_NAME, () => { + const buildInfo = + /** @type {BuildInfo} */ + (parser.state.module.buildInfo); + let topLevelDeclarations = buildInfo.topLevelDeclarations; if (topLevelDeclarations === undefined) { - topLevelDeclarations = parser.state.module.buildInfo.topLevelDeclarations = new Set(); + topLevelDeclarations = buildInfo.topLevelDeclarations = new Set(); } for (const name of parser.scope.definitions.asSet()) { const freeInfo = parser.getFreeInfoFromVariable(name); @@ -46,14 +64,14 @@ class JavascriptMetaInfoPlugin { }; normalModuleFactory.hooks.parser - .for("javascript/auto") - .tap("JavascriptMetaInfoPlugin", handler); + .for(JAVASCRIPT_MODULE_TYPE_AUTO) + .tap(PLUGIN_NAME, handler); normalModuleFactory.hooks.parser - .for("javascript/dynamic") - .tap("JavascriptMetaInfoPlugin", handler); + .for(JAVASCRIPT_MODULE_TYPE_DYNAMIC) + .tap(PLUGIN_NAME, handler); normalModuleFactory.hooks.parser - .for("javascript/esm") - .tap("JavascriptMetaInfoPlugin", handler); + .for(JAVASCRIPT_MODULE_TYPE_ESM) + .tap(PLUGIN_NAME, handler); } ); } diff --git a/lib/LibManifestPlugin.js b/lib/LibManifestPlugin.js index 398e2261205..ab9d2fc57d8 100644 --- a/lib/LibManifestPlugin.js +++ b/lib/LibManifestPlugin.js @@ -11,16 +11,32 @@ const { someInIterable } = require("./util/IterableHelpers"); const { compareModulesById } = require("./util/comparators"); const { dirname, mkdirp } = require("./util/fs"); +/** @typedef {import("./ChunkGraph").ModuleId} ModuleId */ /** @typedef {import("./Compiler")} Compiler */ +/** @typedef {import("./Compiler").IntermediateFileSystem} IntermediateFileSystem */ +/** @typedef {import("./Module").BuildMeta} BuildMeta */ /** - * @typedef {Object} ManifestModuleData + * @typedef {object} ManifestModuleData * @property {string | number} id - * @property {Object} buildMeta - * @property {boolean | string[]} exports + * @property {BuildMeta} buildMeta + * @property {boolean | string[] | undefined} exports + */ + +/** + * @typedef {object} LibManifestPluginOptions + * @property {string=} context Context of requests in the manifest file (defaults to the webpack context). + * @property {boolean=} entryOnly If true, only entry points will be exposed (default: true). + * @property {boolean=} format If true, manifest json file (output) will be formatted. + * @property {string=} name Name of the exposed dll function (external name, use value of 'output.library'). + * @property {string} path Absolute path to the manifest json file (output). + * @property {string=} type Type of the dll bundle (external type, use value of 'output.libraryTarget'). */ class LibManifestPlugin { + /** + * @param {LibManifestPluginOptions} options the options + */ constructor(options) { this.options = options; } @@ -32,10 +48,15 @@ class LibManifestPlugin { */ apply(compiler) { compiler.hooks.emit.tapAsync( - "LibManifestPlugin", + { + name: "LibManifestPlugin", + stage: 110 + }, (compilation, callback) => { const moduleGraph = compilation.moduleGraph; - asyncLib.forEach( + // store used paths to detect issue and output an error. #18200 + const usedPaths = new Set(); + asyncLib.each( Array.from(compilation.chunks), (chunk, callback) => { if (!chunk.canBeInitial()) { @@ -46,10 +67,16 @@ class LibManifestPlugin { const targetPath = compilation.getPath(this.options.path, { chunk }); + if (usedPaths.has(targetPath)) { + callback(new Error("each chunk must have a unique path")); + return; + } + usedPaths.add(targetPath); const name = this.options.name && compilation.getPath(this.options.name, { - chunk + chunk, + contentHashType: "javascript" }); const content = Object.create(null); for (const module of chunkGraph.getOrderedChunkModulesIterable( @@ -66,7 +93,9 @@ class LibManifestPlugin { continue; } const ident = module.libIdent({ - context: this.options.context || compiler.options.context, + context: + this.options.context || + /** @type {string} */ (compiler.options.context), associatedObjectForCache: compiler.root }); if (ident) { @@ -74,8 +103,8 @@ class LibManifestPlugin { const providedExports = exportsInfo.getProvidedExports(); /** @type {ManifestModuleData} */ const data = { - id: chunkGraph.getModuleId(module), - buildMeta: module.buildMeta, + id: /** @type {ModuleId} */ (chunkGraph.getModuleId(module)), + buildMeta: /** @type {BuildMeta} */ (module.buildMeta), exports: Array.isArray(providedExports) ? providedExports : undefined @@ -93,16 +122,16 @@ class LibManifestPlugin { ? JSON.stringify(manifest, null, 2) : JSON.stringify(manifest); const buffer = Buffer.from(manifestContent, "utf8"); + const intermediateFileSystem = + /** @type {IntermediateFileSystem} */ ( + compiler.intermediateFileSystem + ); mkdirp( - compiler.intermediateFileSystem, - dirname(compiler.intermediateFileSystem, targetPath), + intermediateFileSystem, + dirname(intermediateFileSystem, targetPath), err => { if (err) return callback(err); - compiler.intermediateFileSystem.writeFile( - targetPath, - buffer, - callback - ); + intermediateFileSystem.writeFile(targetPath, buffer, callback); } ); }, diff --git a/lib/LoaderOptionsPlugin.js b/lib/LoaderOptionsPlugin.js index 69b659fd475..dec3bcae0a6 100644 --- a/lib/LoaderOptionsPlugin.js +++ b/lib/LoaderOptionsPlugin.js @@ -7,27 +7,40 @@ const ModuleFilenameHelpers = require("./ModuleFilenameHelpers"); const NormalModule = require("./NormalModule"); - -const { validate } = require("schema-utils"); -const schema = require("../schemas/plugins/LoaderOptionsPlugin.json"); +const createSchemaValidation = require("./util/create-schema-validation"); /** @typedef {import("../declarations/plugins/LoaderOptionsPlugin").LoaderOptionsPluginOptions} LoaderOptionsPluginOptions */ /** @typedef {import("./Compiler")} Compiler */ +/** @typedef {import("./ModuleFilenameHelpers").MatchObject} MatchObject */ + +const validate = createSchemaValidation( + require("../schemas/plugins/LoaderOptionsPlugin.check.js"), + () => require("../schemas/plugins/LoaderOptionsPlugin.json"), + { + name: "Loader Options Plugin", + baseDataPath: "options" + } +); class LoaderOptionsPlugin { /** - * @param {LoaderOptionsPluginOptions} options options object + * @param {LoaderOptionsPluginOptions & MatchObject} options options object */ constructor(options = {}) { - validate(schema, options, { - name: "Loader Options Plugin", - baseDataPath: "options" - }); + validate(options); + // If no options are set then generate empty options object if (typeof options !== "object") options = {}; if (!options.test) { - options.test = { + // This is mocking a RegExp object which always returns true + // TODO: Figure out how to do `as unknown as RegExp` for this line + // in JSDoc equivalent + /** @type {any} */ + const defaultTrueMockRegExp = { test: () => true }; + + /** @type {RegExp} */ + options.test = defaultTrueMockRegExp; } this.options = options; } @@ -49,7 +62,7 @@ class LoaderOptionsPlugin { if ( ModuleFilenameHelpers.matchObject( options, - i < 0 ? resource : resource.substr(0, i) + i < 0 ? resource : resource.slice(0, i) ) ) { for (const key of Object.keys(options)) { diff --git a/lib/MainTemplate.js b/lib/MainTemplate.js index fd6a8d4d483..d05ebad2bf9 100644 --- a/lib/MainTemplate.js +++ b/lib/MainTemplate.js @@ -10,6 +10,7 @@ const util = require("util"); const RuntimeGlobals = require("./RuntimeGlobals"); const memoize = require("./util/memoize"); +/** @typedef {import("tapable").Tap} Tap */ /** @typedef {import("webpack-sources").ConcatSource} ConcatSource */ /** @typedef {import("webpack-sources").Source} Source */ /** @typedef {import("../declarations/WebpackOptions").Output} OutputOptions */ @@ -17,15 +18,24 @@ const memoize = require("./util/memoize"); /** @typedef {import("./Chunk")} Chunk */ /** @typedef {import("./Compilation")} Compilation */ /** @typedef {import("./Compilation").AssetInfo} AssetInfo */ +/** @typedef {import("./Compilation").InterpolatedPathAndAssetInfo} InterpolatedPathAndAssetInfo */ /** @typedef {import("./Module")} Module} */ /** @typedef {import("./util/Hash")} Hash} */ /** @typedef {import("./DependencyTemplates")} DependencyTemplates} */ -/** @typedef {import("./ModuleTemplate").RenderContext} RenderContext} */ +/** @typedef {import("./javascript/JavascriptModulesPlugin").RenderContext} RenderContext} */ +/** @typedef {import("./javascript/JavascriptModulesPlugin").RenderBootstrapContext} RenderBootstrapContext} */ +/** @typedef {import("./javascript/JavascriptModulesPlugin").ChunkHashContext} ChunkHashContext} */ /** @typedef {import("./RuntimeTemplate")} RuntimeTemplate} */ /** @typedef {import("./ModuleGraph")} ModuleGraph} */ /** @typedef {import("./ChunkGraph")} ChunkGraph} */ /** @typedef {import("./Template").RenderManifestOptions} RenderManifestOptions} */ /** @typedef {import("./Template").RenderManifestEntry} RenderManifestEntry} */ +/** @typedef {import("./TemplatedPathPlugin").TemplatePath} TemplatePath} */ +/** @typedef {import("./TemplatedPathPlugin").PathData} PathData} */ +/** + * @template T + * @typedef {import("tapable").IfSet} IfSet + */ const getJavascriptModulesPlugin = memoize(() => require("./javascript/JavascriptModulesPlugin") @@ -40,7 +50,6 @@ const getLoadScriptRuntimeModule = memoize(() => // TODO webpack 6 remove this class class MainTemplate { /** - * * @param {OutputOptions} outputOptions output options for the MainTemplate * @param {Compilation} compilation the compilation */ @@ -50,6 +59,11 @@ class MainTemplate { this.hooks = Object.freeze({ renderManifest: { tap: util.deprecate( + /** + * @template AdditionalOptions + * @param {string | Tap & IfSet} options options + * @param {function(RenderManifestEntry[], RenderManifestOptions): RenderManifestEntry[]} fn fn + */ (options, fn) => { compilation.hooks.renderManifest.tap( options, @@ -79,6 +93,11 @@ class MainTemplate { }, require: { tap: util.deprecate( + /** + * @template AdditionalOptions + * @param {string | Tap & IfSet} options options + * @param {function(string, RenderBootstrapContext): string} fn fn + */ (options, fn) => { getJavascriptModulesPlugin() .getCompilationHooks(compilation) @@ -111,6 +130,11 @@ class MainTemplate { }, render: { tap: util.deprecate( + /** + * @template AdditionalOptions + * @param {string | Tap & IfSet} options options + * @param {function(Source, Chunk, string | undefined, ModuleTemplate, DependencyTemplates): Source} fn fn + */ (options, fn) => { getJavascriptModulesPlugin() .getCompilationHooks(compilation) @@ -138,6 +162,11 @@ class MainTemplate { }, renderWithEntry: { tap: util.deprecate( + /** + * @template AdditionalOptions + * @param {string | Tap & IfSet} options options + * @param {function(Source, Chunk, string | undefined): Source} fn fn + */ (options, fn) => { getJavascriptModulesPlugin() .getCompilationHooks(compilation) @@ -159,6 +188,11 @@ class MainTemplate { }, assetPath: { tap: util.deprecate( + /** + * @template AdditionalOptions + * @param {string | Tap & IfSet} options options + * @param {function(string, object, AssetInfo | undefined): string} fn fn + */ (options, fn) => { compilation.hooks.assetPath.tap(options, fn); }, @@ -166,15 +200,23 @@ class MainTemplate { "DEP_WEBPACK_MAIN_TEMPLATE_ASSET_PATH" ), call: util.deprecate( - (filename, options) => { - return compilation.getAssetPath(filename, options); - }, + /** + * @param {TemplatePath} filename used to get asset path with hash + * @param {PathData} options context data + * @returns {string} interpolated path + */ + (filename, options) => compilation.getAssetPath(filename, options), "MainTemplate.hooks.assetPath is deprecated (use Compilation.hooks.assetPath instead)", "DEP_WEBPACK_MAIN_TEMPLATE_ASSET_PATH" ) }, hash: { tap: util.deprecate( + /** + * @template AdditionalOptions + * @param {string | Tap & IfSet} options options + * @param {function(Hash): void} fn fn + */ (options, fn) => { compilation.hooks.fullHash.tap(options, fn); }, @@ -184,6 +226,11 @@ class MainTemplate { }, hashForChunk: { tap: util.deprecate( + /** + * @template AdditionalOptions + * @param {string | Tap & IfSet} options options + * @param {function(Hash, Chunk): void} fn fn + */ (options, fn) => { getJavascriptModulesPlugin() .getCompilationHooks(compilation) @@ -239,9 +286,8 @@ class MainTemplate { "chunkIdExpression" ]), get jsonpScript() { - const hooks = getLoadScriptRuntimeModule().getCompilationHooks( - compilation - ); + const hooks = + getLoadScriptRuntimeModule().getCompilationHooks(compilation); return hooks.createScript; }, get linkPrefetch() { @@ -260,7 +306,8 @@ class MainTemplate { * @param {string} hash the hash * @param {number=} length length of the hash * @returns {string} generated code - */ (hash, length) => { + */ + (hash, length) => { if (length) { return `${RuntimeGlobals.getFullHash} ? ${ RuntimeGlobals.getFullHash @@ -274,31 +321,36 @@ class MainTemplate { this.getPublicPath = util.deprecate( /** - * - * @param {object} options get public path options - * @returns {string} hook call - */ options => { - return compilation.getAssetPath( - compilation.outputOptions.publicPath, + * @param {PathData} options context data + * @returns {string} interpolated path + */ options => + compilation.getAssetPath( + /** @type {string} */ + (compilation.outputOptions.publicPath), options - ); - }, + ), "MainTemplate.getPublicPath is deprecated (use Compilation.getAssetPath(compilation.outputOptions.publicPath, options) instead)", "DEP_WEBPACK_MAIN_TEMPLATE_GET_PUBLIC_PATH" ); this.getAssetPath = util.deprecate( - (path, options) => { - return compilation.getAssetPath(path, options); - }, + /** + * @param {TemplatePath} path used to get asset path with hash + * @param {PathData} options context data + * @returns {string} interpolated path + */ + (path, options) => compilation.getAssetPath(path, options), "MainTemplate.getAssetPath is deprecated (use Compilation.getAssetPath instead)", "DEP_WEBPACK_MAIN_TEMPLATE_GET_ASSET_PATH" ); this.getAssetPathWithInfo = util.deprecate( - (path, options) => { - return compilation.getAssetPathWithInfo(path, options); - }, + /** + * @param {TemplatePath} path used to get asset path with hash + * @param {PathData} options context data + * @returns {InterpolatedPathAndAssetInfo} interpolated path and asset info + */ + (path, options) => compilation.getAssetPathWithInfo(path, options), "MainTemplate.getAssetPathWithInfo is deprecated (use Compilation.getAssetPath instead)", "DEP_WEBPACK_MAIN_TEMPLATE_GET_ASSET_PATH_WITH_INFO" ); @@ -307,8 +359,8 @@ class MainTemplate { Object.defineProperty(MainTemplate.prototype, "requireFn", { get: util.deprecate( - () => "__webpack_require__", - 'MainTemplate.requireFn is deprecated (use "__webpack_require__")', + () => RuntimeGlobals.require, + `MainTemplate.requireFn is deprecated (use "${RuntimeGlobals.require}")`, "DEP_WEBPACK_MAIN_TEMPLATE_REQUIRE_FN" ) }); diff --git a/lib/Module.js b/lib/Module.js index aaf21208921..467158eebfa 100644 --- a/lib/Module.js +++ b/lib/Module.js @@ -18,20 +18,28 @@ const makeSerializable = require("./util/makeSerializable"); /** @typedef {import("../declarations/WebpackOptions").ResolveOptions} ResolveOptions */ /** @typedef {import("../declarations/WebpackOptions").WebpackOptionsNormalized} WebpackOptions */ /** @typedef {import("./Chunk")} Chunk */ +/** @typedef {import("./ChunkGraph").ModuleId} ModuleId */ /** @typedef {import("./ChunkGroup")} ChunkGroup */ +/** @typedef {import("./CodeGenerationResults")} CodeGenerationResults */ /** @typedef {import("./Compilation")} Compilation */ +/** @typedef {import("./Compilation").AssetInfo} AssetInfo */ +/** @typedef {import("./Compilation").ValueCacheVersion} ValueCacheVersion */ /** @typedef {import("./ConcatenationScope")} ConcatenationScope */ /** @typedef {import("./Dependency")} Dependency */ /** @typedef {import("./Dependency").UpdateHashContext} UpdateHashContext */ /** @typedef {import("./DependencyTemplates")} DependencyTemplates */ /** @typedef {import("./ExportsInfo").UsageStateType} UsageStateType */ /** @typedef {import("./FileSystemInfo")} FileSystemInfo */ +/** @typedef {import("./FileSystemInfo").Snapshot} Snapshot */ /** @typedef {import("./ModuleGraphConnection").ConnectionState} ConnectionState */ +/** @typedef {import("./ModuleTypeConstants").ModuleTypes} ModuleTypes */ /** @typedef {import("./NormalModuleFactory")} NormalModuleFactory */ /** @typedef {import("./RequestShortener")} RequestShortener */ /** @typedef {import("./ResolverFactory").ResolverWithOptions} ResolverWithOptions */ /** @typedef {import("./RuntimeTemplate")} RuntimeTemplate */ /** @typedef {import("./WebpackError")} WebpackError */ +/** @typedef {import("./serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */ +/** @typedef {import("./serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */ /** @typedef {import("./util/Hash")} Hash */ /** @template T @typedef {import("./util/LazySet")} LazySet */ /** @template T @typedef {import("./util/SortableSet")} SortableSet */ @@ -39,7 +47,7 @@ const makeSerializable = require("./util/makeSerializable"); /** @typedef {import("./util/runtime").RuntimeSpec} RuntimeSpec */ /** - * @typedef {Object} SourceContext + * @typedef {object} SourceContext * @property {DependencyTemplates} dependencyTemplates the dependency templates * @property {RuntimeTemplate} runtimeTemplate the runtime template * @property {ModuleGraph} moduleGraph the module graph @@ -48,38 +56,45 @@ const makeSerializable = require("./util/makeSerializable"); * @property {string=} type the type of source that should be generated */ +// TODO webpack 6: compilation will be required in CodeGenerationContext /** - * @typedef {Object} CodeGenerationContext + * @typedef {object} CodeGenerationContext * @property {DependencyTemplates} dependencyTemplates the dependency templates * @property {RuntimeTemplate} runtimeTemplate the runtime template * @property {ModuleGraph} moduleGraph the module graph * @property {ChunkGraph} chunkGraph the chunk graph * @property {RuntimeSpec} runtime the runtimes code should be generated for * @property {ConcatenationScope=} concatenationScope when in concatenated module, information about other concatenated modules + * @property {CodeGenerationResults | undefined} codeGenerationResults code generation results of other modules (need to have a codeGenerationDependency to use that) + * @property {Compilation=} compilation the compilation + * @property {ReadonlySet=} sourceTypes source types */ /** - * @typedef {Object} ConcatenationBailoutReasonContext + * @typedef {object} ConcatenationBailoutReasonContext * @property {ModuleGraph} moduleGraph the module graph * @property {ChunkGraph} chunkGraph the chunk graph */ +/** @typedef {Set} RuntimeRequirements */ +/** @typedef {ReadonlySet} ReadOnlyRuntimeRequirements */ + /** - * @typedef {Object} CodeGenerationResult + * @typedef {object} CodeGenerationResult * @property {Map} sources the resulting sources for all source types * @property {Map=} data the resulting data for all source types - * @property {ReadonlySet} runtimeRequirements the runtime requirements + * @property {ReadOnlyRuntimeRequirements | null} runtimeRequirements the runtime requirements * @property {string=} hash a hash of the code generation result (will be automatically calculated from sources and runtimeRequirements if not provided) */ /** - * @typedef {Object} LibIdentOptions + * @typedef {object} LibIdentOptions * @property {string} context absolute context path to which lib ident is relative to - * @property {Object=} associatedObjectForCache object for caching + * @property {object=} associatedObjectForCache object for caching */ /** - * @typedef {Object} KnownBuildMeta + * @typedef {object} KnownBuildMeta * @property {string=} moduleArgument * @property {string=} exportsArgument * @property {boolean=} strict @@ -92,12 +107,38 @@ const makeSerializable = require("./util/makeSerializable"); */ /** - * @typedef {Object} NeedBuildContext + * @typedef {object} KnownBuildInfo + * @property {boolean=} cacheable + * @property {boolean=} parsed + * @property {LazySet=} fileDependencies + * @property {LazySet=} contextDependencies + * @property {LazySet=} missingDependencies + * @property {LazySet=} buildDependencies + * @property {(Map)=} valueDependencies + * @property {TODO=} hash + * @property {Record=} assets + * @property {Map=} assetsInfo + * @property {(Snapshot | null)=} snapshot + */ + +/** + * @typedef {object} NeedBuildContext + * @property {Compilation} compilation * @property {FileSystemInfo} fileSystemInfo - * @property {Map} valueCacheVersions + * @property {Map>} valueCacheVersions */ /** @typedef {KnownBuildMeta & Record} BuildMeta */ +/** @typedef {KnownBuildInfo & Record} BuildInfo */ + +/** + * @typedef {object} FactoryMeta + * @property {boolean=} sideEffectFree + */ + +/** @typedef {Set} SourceTypes */ + +/** @typedef {{ factoryMeta: FactoryMeta | undefined, resolveOptions: ResolveOptions | undefined }} UnsafeCacheData */ const EMPTY_RESOLVE_OPTIONS = {}; @@ -107,12 +148,16 @@ const DEFAULT_TYPES_UNKNOWN = new Set(["unknown"]); const DEFAULT_TYPES_JS = new Set(["javascript"]); const deprecatedNeedRebuild = util.deprecate( - (module, context) => { - return module.needRebuild( + /** + * @param {Module} module the module + * @param {NeedBuildContext} context context info + * @returns {boolean} true, when rebuild is needed + */ + (module, context) => + module.needRebuild( context.fileSystemInfo.getDeprecatedFileTimestamps(), context.fileSystemInfo.getDeprecatedContextTimestamps() - ); - }, + ), "Module.needRebuild is deprecated in favor of Module.needBuild", "DEP_WEBPACK_MODULE_NEED_REBUILD" ); @@ -121,14 +166,14 @@ const deprecatedNeedRebuild = util.deprecate( class Module extends DependenciesBlock { /** - * @param {string} type the module type - * @param {string=} context an optional context - * @param {string=} layer an optional layer in which the module is + * @param {ModuleTypes | ""} type the module type, when deserializing the type is not known and is an empty string + * @param {(string | null)=} context an optional context + * @param {(string | null)=} layer an optional layer in which the module is */ constructor(type, context = null, layer = null) { super(); - /** @type {string} */ + /** @type {ModuleTypes} */ this.type = type; /** @type {string | null} */ this.context = context; @@ -142,9 +187,9 @@ class Module extends DependenciesBlock { this.debugId = debugId++; // Info from Factory - /** @type {ResolveOptions} */ + /** @type {ResolveOptions | undefined} */ this.resolveOptions = EMPTY_RESOLVE_OPTIONS; - /** @type {object | undefined} */ + /** @type {FactoryMeta | undefined} */ this.factoryMeta = undefined; // TODO refactor this -> options object filled from Factory // TODO webpack 6: use an enum @@ -158,16 +203,21 @@ class Module extends DependenciesBlock { this._warnings = undefined; /** @type {WebpackError[] | undefined} */ this._errors = undefined; - /** @type {BuildMeta} */ + /** @type {BuildMeta | undefined} */ this.buildMeta = undefined; - /** @type {Record} */ + /** @type {BuildInfo | undefined} */ this.buildInfo = undefined; /** @type {Dependency[] | undefined} */ this.presentationalDependencies = undefined; + /** @type {Dependency[] | undefined} */ + this.codeGenerationDependencies = undefined; } // TODO remove in webpack 6 // BACKWARD-COMPAT START + /** + * @returns {ModuleId | null} module id + */ get id() { return ChunkGraph.getChunkGraphForModule( this, @@ -176,6 +226,9 @@ class Module extends DependenciesBlock { ).getModuleId(this); } + /** + * @param {ModuleId} value value + */ set id(value) { if (value === "") { this.needId = false; @@ -226,6 +279,9 @@ class Module extends DependenciesBlock { ).setProfile(this, value); } + /** + * @returns {number | null} the pre order index + */ get index() { return ModuleGraph.getModuleGraphForModule( this, @@ -234,6 +290,9 @@ class Module extends DependenciesBlock { ).getPreOrderIndex(this); } + /** + * @param {number} value the pre order index + */ set index(value) { ModuleGraph.getModuleGraphForModule( this, @@ -242,6 +301,9 @@ class Module extends DependenciesBlock { ).setPreOrderIndex(this, value); } + /** + * @returns {number | null} the post order index + */ get index2() { return ModuleGraph.getModuleGraphForModule( this, @@ -250,6 +312,9 @@ class Module extends DependenciesBlock { ).getPostOrderIndex(this); } + /** + * @param {number} value the post order index + */ set index2(value) { ModuleGraph.getModuleGraphForModule( this, @@ -258,6 +323,9 @@ class Module extends DependenciesBlock { ).setPostOrderIndex(this, value); } + /** + * @returns {number | null} the depth + */ get depth() { return ModuleGraph.getModuleGraphForModule( this, @@ -266,6 +334,9 @@ class Module extends DependenciesBlock { ).getDepth(this); } + /** + * @param {number} value the depth + */ set depth(value) { ModuleGraph.getModuleGraphForModule( this, @@ -274,6 +345,9 @@ class Module extends DependenciesBlock { ).setDepth(this, value); } + /** + * @returns {Module | null | undefined} issuer + */ get issuer() { return ModuleGraph.getModuleGraphForModule( this, @@ -282,6 +356,9 @@ class Module extends DependenciesBlock { ).getIssuer(this); } + /** + * @param {Module | null} value issuer + */ set issuer(value) { ModuleGraph.getModuleGraphForModule( this, @@ -320,6 +397,10 @@ class Module extends DependenciesBlock { ); } + /** + * @param {Chunk} chunk the chunk + * @returns {boolean} true, when the module was added + */ addChunk(chunk) { const chunkGraph = ChunkGraph.getChunkGraphForModule( this, @@ -331,6 +412,10 @@ class Module extends DependenciesBlock { return true; } + /** + * @param {Chunk} chunk the chunk + * @returns {void} + */ removeChunk(chunk) { return ChunkGraph.getChunkGraphForModule( this, @@ -339,6 +424,10 @@ class Module extends DependenciesBlock { ).disconnectChunkAndModule(chunk, this); } + /** + * @param {Chunk} chunk the chunk + * @returns {boolean} true, when the module is in the chunk + */ isInChunk(chunk) { return ChunkGraph.getChunkGraphForModule( this, @@ -395,7 +484,6 @@ class Module extends DependenciesBlock { // BACKWARD-COMPAT END /** - * @deprecated moved to .buildInfo.exportsArgument * @returns {string} name of the exports argument */ get exportsArgument() { @@ -403,7 +491,6 @@ class Module extends DependenciesBlock { } /** - * @deprecated moved to .buildInfo.moduleArgument * @returns {string} name of the module argument */ get moduleArgument() { @@ -412,7 +499,7 @@ class Module extends DependenciesBlock { /** * @param {ModuleGraph} moduleGraph the module graph - * @param {boolean} strict the importing module is strict + * @param {boolean | undefined} strict the importing module is strict * @returns {"namespace" | "default-only" | "default-with-named" | "dynamic"} export type * "namespace": Exports is already a namespace object. namespace = exports. * "dynamic": Check at runtime if __esModule is set. When set: namespace = { ...exports, default: exports }. When not set: namespace = { default: exports }. @@ -426,7 +513,7 @@ class Module extends DependenciesBlock { case "namespace": return "namespace"; case "default": - switch (this.buildMeta.defaultObject) { + switch (/** @type {BuildMeta} */ (this.buildMeta).defaultObject) { case "redirect": return "default-with-named"; case "redirect-warn": @@ -438,7 +525,7 @@ class Module extends DependenciesBlock { if (strict) return "default-with-named"; // Try to figure out value of __esModule by following reexports const handleDefault = () => { - switch (this.buildMeta.defaultObject) { + switch (/** @type {BuildMeta} */ (this.buildMeta).defaultObject) { case "redirect": case "redirect-warn": return "default-with-named"; @@ -492,6 +579,19 @@ class Module extends DependenciesBlock { this.presentationalDependencies.push(presentationalDependency); } + /** + * @param {Dependency} codeGenerationDependency dependency being tied to module. + * This is a Dependency where the code generation result of the referenced module is needed during code generation. + * The Dependency should also be added to normal dependencies via addDependency. + * @returns {void} + */ + addCodeGenerationDependency(codeGenerationDependency) { + if (this.codeGenerationDependencies === undefined) { + this.codeGenerationDependencies = []; + } + this.codeGenerationDependencies.push(codeGenerationDependency); + } + /** * Removes all dependencies and blocks * @returns {void} @@ -500,6 +600,9 @@ class Module extends DependenciesBlock { if (this.presentationalDependencies !== undefined) { this.presentationalDependencies.length = 0; } + if (this.codeGenerationDependencies !== undefined) { + this.codeGenerationDependencies.length = 0; + } super.clearDependenciesAndBlocks(); } @@ -639,7 +742,7 @@ class Module extends DependenciesBlock { ] of moduleGraph.getIncomingConnectionsByOriginModule(this)) { if (!connections.some(c => c.isTargetActive(chunk.runtime))) continue; for (const originChunk of chunkGraph.getModuleChunksIterable( - fromModule + /** @type {Module} */ (fromModule) )) { // return true if module this is not reachable from originChunk when ignoring chunk if (!this.isAccessibleInChunk(chunkGraph, originChunk, chunk)) @@ -670,7 +773,7 @@ class Module extends DependenciesBlock { /** * @param {NeedBuildContext} context context info - * @param {function(WebpackError=, boolean=): void} callback callback function, returns true, if the module needs a rebuild + * @param {function((WebpackError | null)=, boolean=): void} callback callback function, returns true, if the module needs a rebuild * @returns {void} */ needBuild(context, callback) { @@ -763,15 +866,14 @@ class Module extends DependenciesBlock { /** * @abstract - * @returns {Set} types available (do not mutate) + * @returns {SourceTypes} types available (do not mutate) */ getSourceTypes() { // Better override this method to return the correct types if (this.source === Module.prototype.source) { return DEFAULT_TYPES_UNKNOWN; - } else { - return DEFAULT_TYPES_JS; } + return DEFAULT_TYPES_JS; } /** @@ -798,10 +900,16 @@ class Module extends DependenciesBlock { runtimeTemplate, moduleGraph: chunkGraph.moduleGraph, chunkGraph, - runtime: undefined + runtime: undefined, + codeGenerationResults: undefined }; const sources = this.codeGeneration(codeGenContext).sources; - return type ? sources.get(type) : sources.get(first(this.getSourceTypes())); + + return /** @type {Source} */ ( + type + ? sources.get(type) + : sources.get(/** @type {string} */ (first(this.getSourceTypes()))) + ); } /* istanbul ignore next */ @@ -884,6 +992,10 @@ class Module extends DependenciesBlock { return true; } + hasChunkCondition() { + return this.chunkCondition !== Module.prototype.chunkCondition; + } + /** * Assuming this module is in the cache. Update the (cached) module with * the fresh module from the factory. Usually updates internal references @@ -902,7 +1014,7 @@ class Module extends DependenciesBlock { /** * Module should be unsafe cached. Get data that's needed for that. * This data will be passed to restoreFromUnsafeCache later. - * @returns {object} cached data + * @returns {UnsafeCacheData} cached data */ getUnsafeCacheData() { return { @@ -949,6 +1061,9 @@ class Module extends DependenciesBlock { buildDependencies ) {} + /** + * @param {ObjectSerializerContext} context context + */ serialize(context) { const { write } = context; write(this.type); @@ -971,9 +1086,13 @@ class Module extends DependenciesBlock { write(this.buildMeta); write(this.buildInfo); write(this.presentationalDependencies); + write(this.codeGenerationDependencies); super.serialize(context); } + /** + * @param {ObjectDeserializerContext} context context + */ deserialize(context) { const { read } = context; this.type = read(); @@ -988,6 +1107,7 @@ class Module extends DependenciesBlock { this.buildMeta = read(); this.buildInfo = read(); this.presentationalDependencies = read(); + this.codeGenerationDependencies = read(); super.deserialize(context); } } @@ -995,6 +1115,8 @@ class Module extends DependenciesBlock { makeSerializable(Module, "webpack/lib/Module"); // TODO remove in webpack 6 +// eslint-disable-next-line no-warning-comments +// @ts-ignore https://github.com/microsoft/TypeScript/issues/42919 Object.defineProperty(Module.prototype, "hasEqualsChunks", { get() { throw new Error( @@ -1004,6 +1126,8 @@ Object.defineProperty(Module.prototype, "hasEqualsChunks", { }); // TODO remove in webpack 6 +// eslint-disable-next-line no-warning-comments +// @ts-ignore https://github.com/microsoft/TypeScript/issues/42919 Object.defineProperty(Module.prototype, "isUsed", { get() { throw new Error( @@ -1049,6 +1173,8 @@ Object.defineProperty(Module.prototype, "warnings", { }); // TODO remove in webpack 6 +// eslint-disable-next-line no-warning-comments +// @ts-ignore https://github.com/microsoft/TypeScript/issues/42919 Object.defineProperty(Module.prototype, "used", { get() { throw new Error( diff --git a/lib/ModuleBuildError.js b/lib/ModuleBuildError.js index 887db5950c5..b97daa14a18 100644 --- a/lib/ModuleBuildError.js +++ b/lib/ModuleBuildError.js @@ -9,6 +9,9 @@ const { cutOffLoaderExecution } = require("./ErrorHelpers"); const WebpackError = require("./WebpackError"); const makeSerializable = require("./util/makeSerializable"); +/** @typedef {import("./serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */ +/** @typedef {import("./serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */ + class ModuleBuildError extends WebpackError { /** * @param {string | Error&any} err error thrown @@ -16,13 +19,9 @@ class ModuleBuildError extends WebpackError { */ constructor(err, { from = null } = {}) { let message = "Module build failed"; - let details = undefined; + let details; - if (from) { - message += ` (from ${from}):\n`; - } else { - message += ": "; - } + message += from ? ` (from ${from}):\n` : ": "; if (err !== null && typeof err === "object") { if (typeof err.stack === "string" && err.stack) { @@ -33,11 +32,8 @@ class ModuleBuildError extends WebpackError { } else { details = stack; - if (typeof err.message === "string" && err.message) { - message += err.message; - } else { - message += err; - } + message += + typeof err.message === "string" && err.message ? err.message : err; } } else if (typeof err.message === "string" && err.message) { message += err.message; @@ -53,10 +49,11 @@ class ModuleBuildError extends WebpackError { this.name = "ModuleBuildError"; this.details = details; this.error = err; - - Error.captureStackTrace(this, this.constructor); } + /** + * @param {ObjectSerializerContext} context context + */ serialize(context) { const { write } = context; @@ -65,6 +62,9 @@ class ModuleBuildError extends WebpackError { super.serialize(context); } + /** + * @param {ObjectDeserializerContext} context context + */ deserialize(context) { const { read } = context; diff --git a/lib/ModuleDependencyError.js b/lib/ModuleDependencyError.js index aeeeb859dc1..bb7341db762 100644 --- a/lib/ModuleDependencyError.js +++ b/lib/ModuleDependencyError.js @@ -23,18 +23,18 @@ class ModuleDependencyError extends WebpackError { this.name = "ModuleDependencyError"; this.details = err && !(/** @type {any} */ (err).hideStack) - ? err.stack.split("\n").slice(1).join("\n") + ? /** @type {string} */ (err.stack).split("\n").slice(1).join("\n") : undefined; this.module = module; this.loc = loc; /** error is not (de)serialized, so it might be undefined after deserialization */ this.error = err; - Error.captureStackTrace(this, this.constructor); - - if (err && /** @type {any} */ (err).hideStack) { - this.stack = - err.stack.split("\n").slice(1).join("\n") + "\n\n" + this.stack; + if (err && /** @type {any} */ (err).hideStack && err.stack) { + this.stack = /** @type {string} */ `${err.stack + .split("\n") + .slice(1) + .join("\n")}\n\n${this.stack}`; } } } diff --git a/lib/ModuleDependencyWarning.js b/lib/ModuleDependencyWarning.js index 9246cfe0258..2fc403b9d66 100644 --- a/lib/ModuleDependencyWarning.js +++ b/lib/ModuleDependencyWarning.js @@ -23,18 +23,18 @@ class ModuleDependencyWarning extends WebpackError { this.name = "ModuleDependencyWarning"; this.details = err && !(/** @type {any} */ (err).hideStack) - ? err.stack.split("\n").slice(1).join("\n") + ? /** @type {string} */ (err.stack).split("\n").slice(1).join("\n") : undefined; this.module = module; this.loc = loc; /** error is not (de)serialized, so it might be undefined after deserialization */ this.error = err; - Error.captureStackTrace(this, this.constructor); - - if (err && /** @type {any} */ (err).hideStack) { - this.stack = - err.stack.split("\n").slice(1).join("\n") + "\n\n" + this.stack; + if (err && /** @type {any} */ (err).hideStack && err.stack) { + this.stack = /** @type {string} */ `${err.stack + .split("\n") + .slice(1) + .join("\n")}\n\n${this.stack}`; } } } diff --git a/lib/ModuleError.js b/lib/ModuleError.js index 7da05d316b2..f8227a8fc48 100644 --- a/lib/ModuleError.js +++ b/lib/ModuleError.js @@ -9,6 +9,9 @@ const { cleanUp } = require("./ErrorHelpers"); const WebpackError = require("./WebpackError"); const makeSerializable = require("./util/makeSerializable"); +/** @typedef {import("./serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */ +/** @typedef {import("./serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */ + class ModuleError extends WebpackError { /** * @param {Error} err error thrown @@ -17,11 +20,7 @@ class ModuleError extends WebpackError { constructor(err, { from = null } = {}) { let message = "Module Error"; - if (from) { - message += ` (from ${from}):\n`; - } else { - message += ": "; - } + message += from ? ` (from ${from}):\n` : ": "; if (err && typeof err === "object" && err.message) { message += err.message; @@ -37,10 +36,11 @@ class ModuleError extends WebpackError { err && typeof err === "object" && err.stack ? cleanUp(err.stack, this.message) : undefined; - - Error.captureStackTrace(this, this.constructor); } + /** + * @param {ObjectSerializerContext} context context + */ serialize(context) { const { write } = context; @@ -49,6 +49,9 @@ class ModuleError extends WebpackError { super.serialize(context); } + /** + * @param {ObjectDeserializerContext} context context + */ deserialize(context) { const { read } = context; diff --git a/lib/ModuleFactory.js b/lib/ModuleFactory.js index dab8811d7e6..7b08be28be5 100644 --- a/lib/ModuleFactory.js +++ b/lib/ModuleFactory.js @@ -10,22 +10,23 @@ /** @typedef {import("./Module")} Module */ /** - * @typedef {Object} ModuleFactoryResult + * @typedef {object} ModuleFactoryResult * @property {Module=} module the created module or unset if no module was created * @property {Set=} fileDependencies * @property {Set=} contextDependencies * @property {Set=} missingDependencies + * @property {boolean=} cacheable allow to use the unsafe cache */ /** - * @typedef {Object} ModuleFactoryCreateDataContextInfo + * @typedef {object} ModuleFactoryCreateDataContextInfo * @property {string} issuer * @property {string | null=} issuerLayer * @property {string} compiler */ /** - * @typedef {Object} ModuleFactoryCreateData + * @typedef {object} ModuleFactoryCreateData * @property {ModuleFactoryCreateDataContextInfo} contextInfo * @property {ResolveOptions=} resolveOptions * @property {string} context @@ -37,7 +38,7 @@ class ModuleFactory { /** * @abstract * @param {ModuleFactoryCreateData} data data object - * @param {function(Error=, ModuleFactoryResult=): void} callback callback + * @param {function((Error | null)=, ModuleFactoryResult=): void} callback callback * @returns {void} */ create(data, callback) { diff --git a/lib/ModuleFilenameHelpers.js b/lib/ModuleFilenameHelpers.js index 506a333ce6c..afe3d345338 100644 --- a/lib/ModuleFilenameHelpers.js +++ b/lib/ModuleFilenameHelpers.js @@ -5,21 +5,32 @@ "use strict"; +const NormalModule = require("./NormalModule"); const createHash = require("./util/createHash"); const memoize = require("./util/memoize"); -const ModuleFilenameHelpers = exports; +/** @typedef {import("./ChunkGraph")} ChunkGraph */ +/** @typedef {import("./Module")} Module */ +/** @typedef {import("./RequestShortener")} RequestShortener */ +/** @typedef {typeof import("./util/Hash")} Hash */ + +/** @typedef {string | RegExp | (string | RegExp)[]} Matcher */ +/** @typedef {{test?: Matcher, include?: Matcher, exclude?: Matcher }} MatchObject */ + +const ModuleFilenameHelpers = module.exports; // TODO webpack 6: consider removing these ModuleFilenameHelpers.ALL_LOADERS_RESOURCE = "[all-loaders][resource]"; -ModuleFilenameHelpers.REGEXP_ALL_LOADERS_RESOURCE = /\[all-?loaders\]\[resource\]/gi; +ModuleFilenameHelpers.REGEXP_ALL_LOADERS_RESOURCE = + /\[all-?loaders\]\[resource\]/gi; ModuleFilenameHelpers.LOADERS_RESOURCE = "[loaders][resource]"; ModuleFilenameHelpers.REGEXP_LOADERS_RESOURCE = /\[loaders\]\[resource\]/gi; ModuleFilenameHelpers.RESOURCE = "[resource]"; ModuleFilenameHelpers.REGEXP_RESOURCE = /\[resource\]/gi; ModuleFilenameHelpers.ABSOLUTE_RESOURCE_PATH = "[absolute-resource-path]"; // cSpell:words olute -ModuleFilenameHelpers.REGEXP_ABSOLUTE_RESOURCE_PATH = /\[abs(olute)?-?resource-?path\]/gi; +ModuleFilenameHelpers.REGEXP_ABSOLUTE_RESOURCE_PATH = + /\[abs(olute)?-?resource-?path\]/gi; ModuleFilenameHelpers.RESOURCE_PATH = "[resource-path]"; ModuleFilenameHelpers.REGEXP_RESOURCE_PATH = /\[resource-?path\]/gi; ModuleFilenameHelpers.ALL_LOADERS = "[all-loaders]"; @@ -35,38 +46,76 @@ ModuleFilenameHelpers.REGEXP_HASH = /\[hash\]/gi; ModuleFilenameHelpers.NAMESPACE = "[namespace]"; ModuleFilenameHelpers.REGEXP_NAMESPACE = /\[namespace\]/gi; -const getAfter = (strFn, token) => { - return () => { - const str = strFn(); - const idx = str.indexOf(token); - return idx < 0 ? "" : str.substr(idx); - }; +/** @typedef {() => string} ReturnStringCallback */ + +/** + * Returns a function that returns the part of the string after the token + * @param {ReturnStringCallback} strFn the function to get the string + * @param {string} token the token to search for + * @returns {ReturnStringCallback} a function that returns the part of the string after the token + */ +const getAfter = (strFn, token) => () => { + const str = strFn(); + const idx = str.indexOf(token); + return idx < 0 ? "" : str.slice(idx); }; -const getBefore = (strFn, token) => { - return () => { - const str = strFn(); - const idx = str.lastIndexOf(token); - return idx < 0 ? "" : str.substr(0, idx); - }; +/** + * Returns a function that returns the part of the string before the token + * @param {ReturnStringCallback} strFn the function to get the string + * @param {string} token the token to search for + * @returns {ReturnStringCallback} a function that returns the part of the string before the token + */ +const getBefore = (strFn, token) => () => { + const str = strFn(); + const idx = str.lastIndexOf(token); + return idx < 0 ? "" : str.slice(0, idx); }; -const getHash = strFn => { - return () => { - const hash = createHash("md4"); +/** + * Returns a function that returns a hash of the string + * @param {ReturnStringCallback} strFn the function to get the string + * @param {string | Hash=} hashFunction the hash function to use + * @returns {ReturnStringCallback} a function that returns the hash of the string + */ +const getHash = + (strFn, hashFunction = "md4") => + () => { + const hash = createHash(hashFunction); hash.update(strFn()); const digest = /** @type {string} */ (hash.digest("hex")); - return digest.substr(0, 4); + return digest.slice(0, 4); }; -}; +/** + * Returns a function that returns the string with the token replaced with the replacement + * @param {string|RegExp} test A regular expression string or Regular Expression object + * @returns {RegExp} A regular expression object + * @example + * ```js + * const test = asRegExp("test"); + * test.test("test"); // true + * + * const test2 = asRegExp(/test/); + * test2.test("test"); // true + * ``` + */ const asRegExp = test => { if (typeof test === "string") { - test = new RegExp("^" + test.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&")); + // Escape special characters in the string to prevent them from being interpreted as special characters in a regular expression. Do this by + // adding a backslash before each special character + test = new RegExp(`^${test.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&")}`); } return test; }; +/** + * @template T + * Returns a lazy object. The object is lazy in the sense that the properties are + * only evaluated when they are accessed. This is only obtained by setting a function as the value for each key. + * @param {Record T>} obj the object to convert to a lazy access object + * @returns {object} the lazy access object + */ const lazyObject = obj => { const newObj = {}; for (const key of Object.keys(obj)) { @@ -87,12 +136,22 @@ const lazyObject = obj => { return newObj; }; -const REGEXP = /\[\\*([\w-]+)\\*\]/gi; +const SQUARE_BRACKET_TAG_REGEXP = /\[\\*([\w-]+)\\*\]/gi; +/** + * @param {Module | string} module the module + * @param {TODO} options options + * @param {object} contextInfo context info + * @param {RequestShortener} contextInfo.requestShortener requestShortener + * @param {ChunkGraph} contextInfo.chunkGraph chunk graph + * @param {string | Hash=} contextInfo.hashFunction the hash function to use + * @returns {string} the filename + */ ModuleFilenameHelpers.createFilename = ( - module, + // eslint-disable-next-line default-param-last + module = "", options, - { requestShortener, chunkGraph } + { requestShortener, chunkGraph, hashFunction = "md4" } ) => { const opts = { namespace: "", @@ -101,31 +160,44 @@ ModuleFilenameHelpers.createFilename = ( ? options : { moduleFilenameTemplate: options - }) + }) }; let absoluteResourcePath; let hash; + /** @type {ReturnStringCallback} */ let identifier; + /** @type {ReturnStringCallback} */ let moduleId; + /** @type {ReturnStringCallback} */ let shortIdentifier; - if (module === undefined) module = ""; if (typeof module === "string") { - shortIdentifier = memoize(() => requestShortener.shorten(module)); + shortIdentifier = + /** @type {ReturnStringCallback} */ + (memoize(() => requestShortener.shorten(module))); identifier = shortIdentifier; moduleId = () => ""; absoluteResourcePath = () => module.split("!").pop(); - hash = getHash(identifier); + hash = getHash(identifier, hashFunction); } else { shortIdentifier = memoize(() => module.readableIdentifier(requestShortener) ); - identifier = memoize(() => requestShortener.shorten(module.identifier())); - moduleId = () => chunkGraph.getModuleId(module); - absoluteResourcePath = () => module.identifier().split("!").pop(); - hash = getHash(identifier); + identifier = + /** @type {ReturnStringCallback} */ + (memoize(() => requestShortener.shorten(module.identifier()))); + moduleId = + /** @type {ReturnStringCallback} */ + (() => chunkGraph.getModuleId(module)); + absoluteResourcePath = () => + module instanceof NormalModule + ? module.resource + : module.identifier().split("!").pop(); + hash = getHash(identifier, hashFunction); } - const resource = memoize(() => shortIdentifier().split("!").pop()); + const resource = + /** @type {ReturnStringCallback} */ + (memoize(() => shortIdentifier().split("!").pop())); const loaders = getBefore(shortIdentifier, "!"); const allLoaders = getBefore(identifier, "!"); @@ -137,11 +209,12 @@ ModuleFilenameHelpers.createFilename = ( if (typeof opts.moduleFilenameTemplate === "function") { return opts.moduleFilenameTemplate( lazyObject({ - identifier: identifier, - shortIdentifier: shortIdentifier, - resource: resource, + identifier, + shortIdentifier, + resource, resourcePath: memoize(resourcePath), absoluteResourcePath: memoize(absoluteResourcePath), + loaders: memoize(loaders), allLoaders: memoize(allLoaders), query: memoize(query), moduleId: memoize(moduleId), @@ -185,13 +258,13 @@ ModuleFilenameHelpers.createFilename = ( ]); // TODO webpack 6: consider removing weird double placeholders - return opts.moduleFilenameTemplate + return /** @type {string} */ (opts.moduleFilenameTemplate) .replace(ModuleFilenameHelpers.REGEXP_ALL_LOADERS_RESOURCE, "[identifier]") .replace( ModuleFilenameHelpers.REGEXP_LOADERS_RESOURCE, "[short-identifier]" ) - .replace(REGEXP, (match, content) => { + .replace(SQUARE_BRACKET_TAG_REGEXP, (match, content) => { if (content.length + 2 === match.length) { const replacement = replacements.get(content.toLowerCase()); if (replacement !== undefined) { @@ -204,54 +277,107 @@ ModuleFilenameHelpers.createFilename = ( }); }; +/** + * Replaces duplicate items in an array with new values generated by a callback function. + * The callback function is called with the duplicate item, the index of the duplicate item, and the number of times the item has been replaced. + * The callback function should return the new value for the duplicate item. + * @template T + * @param {T[]} array the array with duplicates to be replaced + * @param {(duplicateItem: T, duplicateItemIndex: number, numberOfTimesReplaced: number) => T} fn callback function to generate new values for the duplicate items + * @param {(firstElement:T, nextElement:T) => -1 | 0 | 1} [comparator] optional comparator function to sort the duplicate items + * @returns {T[]} the array with duplicates replaced + * @example + * ```js + * const array = ["a", "b", "c", "a", "b", "a"]; + * const result = ModuleFilenameHelpers.replaceDuplicates(array, (item, index, count) => `${item}-${count}`); + * // result: ["a-1", "b-1", "c", "a-2", "b-2", "a-3"] + * ``` + */ ModuleFilenameHelpers.replaceDuplicates = (array, fn, comparator) => { const countMap = Object.create(null); const posMap = Object.create(null); - array.forEach((item, idx) => { + + for (const [idx, item] of array.entries()) { countMap[item] = countMap[item] || []; countMap[item].push(idx); posMap[item] = 0; - }); + } if (comparator) { - Object.keys(countMap).forEach(item => { + for (const item of Object.keys(countMap)) { countMap[item].sort(comparator); - }); + } } return array.map((item, i) => { if (countMap[item].length > 1) { if (comparator && countMap[item][0] === i) return item; return fn(item, i, posMap[item]++); - } else { - return item; } + return item; }); }; +/** + * Tests if a string matches a RegExp or an array of RegExp. + * @param {string} str string to test + * @param {Matcher} test value which will be used to match against the string + * @returns {boolean} true, when the RegExp matches + * @example + * ```js + * ModuleFilenameHelpers.matchPart("foo.js", "foo"); // true + * ModuleFilenameHelpers.matchPart("foo.js", "foo.js"); // true + * ModuleFilenameHelpers.matchPart("foo.js", "foo."); // false + * ModuleFilenameHelpers.matchPart("foo.js", "foo*"); // false + * ModuleFilenameHelpers.matchPart("foo.js", "foo.*"); // true + * ModuleFilenameHelpers.matchPart("foo.js", /^foo/); // true + * ModuleFilenameHelpers.matchPart("foo.js", [/^foo/, "bar"]); // true + * ModuleFilenameHelpers.matchPart("foo.js", [/^foo/, "bar"]); // true + * ModuleFilenameHelpers.matchPart("foo.js", [/^foo/, /^bar/]); // true + * ModuleFilenameHelpers.matchPart("foo.js", [/^baz/, /^bar/]); // false + * ``` + */ ModuleFilenameHelpers.matchPart = (str, test) => { if (!test) return true; - test = asRegExp(test); + if (Array.isArray(test)) { return test.map(asRegExp).some(regExp => regExp.test(str)); - } else { - return test.test(str); } + return asRegExp(test).test(str); }; +/** + * Tests if a string matches a match object. The match object can have the following properties: + * - `test`: a RegExp or an array of RegExp + * - `include`: a RegExp or an array of RegExp + * - `exclude`: a RegExp or an array of RegExp + * + * The `test` property is tested first, then `include` and then `exclude`. + * @param {MatchObject} obj a match object to test against the string + * @param {string} str string to test against the matching object + * @returns {boolean} true, when the object matches + * @example + * ```js + * ModuleFilenameHelpers.matchObject({ test: "foo.js" }, "foo.js"); // true + * ModuleFilenameHelpers.matchObject({ test: /^foo/ }, "foo.js"); // true + * ModuleFilenameHelpers.matchObject({ test: [/^foo/, "bar"] }, "foo.js"); // true + * ModuleFilenameHelpers.matchObject({ test: [/^foo/, "bar"] }, "baz.js"); // false + * ModuleFilenameHelpers.matchObject({ include: "foo.js" }, "foo.js"); // true + * ModuleFilenameHelpers.matchObject({ include: "foo.js" }, "bar.js"); // false + * ModuleFilenameHelpers.matchObject({ include: /^foo/ }, "foo.js"); // true + * ModuleFilenameHelpers.matchObject({ include: [/^foo/, "bar"] }, "foo.js"); // true + * ModuleFilenameHelpers.matchObject({ include: [/^foo/, "bar"] }, "baz.js"); // false + * ModuleFilenameHelpers.matchObject({ exclude: "foo.js" }, "foo.js"); // false + * ModuleFilenameHelpers.matchObject({ exclude: [/^foo/, "bar"] }, "foo.js"); // false + * ``` + */ ModuleFilenameHelpers.matchObject = (obj, str) => { - if (obj.test) { - if (!ModuleFilenameHelpers.matchPart(str, obj.test)) { - return false; - } + if (obj.test && !ModuleFilenameHelpers.matchPart(str, obj.test)) { + return false; } - if (obj.include) { - if (!ModuleFilenameHelpers.matchPart(str, obj.include)) { - return false; - } + if (obj.include && !ModuleFilenameHelpers.matchPart(str, obj.include)) { + return false; } - if (obj.exclude) { - if (ModuleFilenameHelpers.matchPart(str, obj.exclude)) { - return false; - } + if (obj.exclude && ModuleFilenameHelpers.matchPart(str, obj.exclude)) { + return false; } return true; }; diff --git a/lib/ModuleGraph.js b/lib/ModuleGraph.js index 8e2e42d2783..783c6e414d6 100644 --- a/lib/ModuleGraph.js +++ b/lib/ModuleGraph.js @@ -9,6 +9,7 @@ const util = require("util"); const ExportsInfo = require("./ExportsInfo"); const ModuleGraphConnection = require("./ModuleGraphConnection"); const SortableSet = require("./util/SortableSet"); +const WeakTupleMap = require("./util/WeakTupleMap"); /** @typedef {import("./DependenciesBlock")} DependenciesBlock */ /** @typedef {import("./Dependency")} Dependency */ @@ -24,24 +25,25 @@ const SortableSet = require("./util/SortableSet"); * @returns {string} */ -const EMPTY_ARRAY = []; +const EMPTY_SET = new Set(); /** * @param {SortableSet} set input - * @returns {readonly Map} mapped by origin module + * @returns {readonly Map} mapped by origin module */ const getConnectionsByOriginModule = set => { const map = new Map(); /** @type {Module | 0} */ let lastModule = 0; - /** @type {ModuleGraphConnection[]} */ - let lastList = undefined; + /** @type {ModuleGraphConnection[] | undefined} */ + let lastList; for (const connection of set) { const { originModule } = connection; if (lastModule === originModule) { - lastList.push(connection); + /** @type {ModuleGraphConnection[]} */ + (lastList).push(connection); } else { - lastModule = originModule; + lastModule = /** @type {Module} */ (originModule); const list = map.get(originModule); if (list !== undefined) { lastList = list; @@ -56,60 +58,100 @@ const getConnectionsByOriginModule = set => { return map; }; +/** + * @param {SortableSet} set input + * @returns {readonly Map} mapped by module + */ +const getConnectionsByModule = set => { + const map = new Map(); + /** @type {Module | 0} */ + let lastModule = 0; + /** @type {ModuleGraphConnection[] | undefined} */ + let lastList; + for (const connection of set) { + const { module } = connection; + if (lastModule === module) { + /** @type {ModuleGraphConnection[]} */ + (lastList).push(connection); + } else { + lastModule = module; + const list = map.get(module); + if (list !== undefined) { + lastList = list; + list.push(connection); + } else { + const list = [connection]; + lastList = list; + map.set(module, list); + } + } + } + return map; +}; + +/** @typedef {SortableSet} IncomingConnections */ +/** @typedef {SortableSet} OutgoingConnections */ + class ModuleGraphModule { constructor() { - /** @type {SortableSet} */ + /** @type {IncomingConnections} */ this.incomingConnections = new SortableSet(); - /** @type {Set | undefined} */ + /** @type {OutgoingConnections | undefined} */ this.outgoingConnections = undefined; - /** @type {Module | null} */ + /** @type {Module | null | undefined} */ this.issuer = undefined; /** @type {(string | OptimizationBailoutFunction)[]} */ this.optimizationBailout = []; /** @type {ExportsInfo} */ this.exports = new ExportsInfo(); - /** @type {number} */ + /** @type {number | null} */ this.preOrderIndex = null; - /** @type {number} */ + /** @type {number | null} */ this.postOrderIndex = null; - /** @type {number} */ + /** @type {number | null} */ this.depth = null; - /** @type {ModuleProfile} */ + /** @type {ModuleProfile | undefined} */ this.profile = undefined; /** @type {boolean} */ this.async = false; - } -} - -class ModuleGraphDependency { - constructor() { - /** @type {ModuleGraphConnection} */ - this.connection = undefined; - /** @type {Module} */ - this.parentModule = undefined; - /** @type {DependenciesBlock} */ - this.parentBlock = undefined; + /** @type {ModuleGraphConnection[] | undefined} */ + this._unassignedConnections = undefined; } } class ModuleGraph { constructor() { - /** @type {Map} */ - this._dependencyMap = new Map(); - /** @type {Map} */ + /** + * @type {WeakMap} + * @private + */ + this._dependencyMap = new WeakMap(); + /** + * @type {Map} + * @private + */ this._moduleMap = new Map(); - /** @type {Map>} */ - this._originMap = new Map(); - /** @type {Map} */ - this._metaMap = new Map(); - - // Caching - this._cacheModuleGraphModuleKey1 = undefined; - this._cacheModuleGraphModuleValue1 = undefined; - this._cacheModuleGraphModuleKey2 = undefined; - this._cacheModuleGraphModuleValue2 = undefined; - this._cacheModuleGraphDependencyKey = undefined; - this._cacheModuleGraphDependencyValue = undefined; + /** + * @type {WeakMap} + * @private + */ + this._metaMap = new WeakMap(); + /** + * @type {WeakTupleMap | undefined} + * @private + */ + this._cache = undefined; + /** + * @type {Map> | undefined} + * @private + */ + this._moduleMemCaches = undefined; + + /** + * @type {string | undefined} + * @private + */ + this._cacheStage = undefined; } /** @@ -117,71 +159,53 @@ class ModuleGraph { * @returns {ModuleGraphModule} the internal module */ _getModuleGraphModule(module) { - if (this._cacheModuleGraphModuleKey1 === module) - return this._cacheModuleGraphModuleValue1; - if (this._cacheModuleGraphModuleKey2 === module) - return this._cacheModuleGraphModuleValue2; let mgm = this._moduleMap.get(module); if (mgm === undefined) { mgm = new ModuleGraphModule(); this._moduleMap.set(module, mgm); } - this._cacheModuleGraphModuleKey2 = this._cacheModuleGraphModuleKey1; - this._cacheModuleGraphModuleValue2 = this._cacheModuleGraphModuleValue1; - this._cacheModuleGraphModuleKey1 = module; - this._cacheModuleGraphModuleValue1 = mgm; return mgm; } - /** - * @param {Dependency} dependency the dependency - * @returns {ModuleGraphDependency} the internal dependency - */ - _getModuleGraphDependency(dependency) { - if (this._cacheModuleGraphDependencyKey === dependency) - return this._cacheModuleGraphDependencyValue; - let mgd = this._dependencyMap.get(dependency); - if (mgd === undefined) { - mgd = new ModuleGraphDependency(); - this._dependencyMap.set(dependency, mgd); - } - this._cacheModuleGraphDependencyKey = dependency; - this._cacheModuleGraphDependencyValue = mgd; - return mgd; - } - /** * @param {Dependency} dependency the dependency * @param {DependenciesBlock} block parent block * @param {Module} module parent module + * @param {number=} indexInBlock position in block * @returns {void} */ - setParents(dependency, block, module) { - const mgd = this._getModuleGraphDependency(dependency); - mgd.parentBlock = block; - mgd.parentModule = module; + setParents(dependency, block, module, indexInBlock = -1) { + dependency._parentDependenciesBlockIndex = indexInBlock; + dependency._parentDependenciesBlock = block; + dependency._parentModule = module; } /** * @param {Dependency} dependency the dependency - * @returns {Module} parent module + * @returns {Module | undefined} parent module */ getParentModule(dependency) { - const mgd = this._getModuleGraphDependency(dependency); - return mgd.parentModule; + return dependency._parentModule; } /** * @param {Dependency} dependency the dependency - * @returns {DependenciesBlock} parent block + * @returns {DependenciesBlock | undefined} parent block */ getParentBlock(dependency) { - const mgd = this._getModuleGraphDependency(dependency); - return mgd.parentBlock; + return dependency._parentDependenciesBlock; } /** - * @param {Module} originModule the referencing module + * @param {Dependency} dependency the dependency + * @returns {number} index + */ + getParentBlockIndex(dependency) { + return dependency._parentDependenciesBlockIndex; + } + + /** + * @param {Module | null} originModule the referencing module * @param {Dependency} dependency the referencing dependency * @param {Module} module the referenced module * @returns {void} @@ -195,15 +219,21 @@ class ModuleGraph { dependency.weak, dependency.getCondition(this) ); - const mgd = this._getModuleGraphDependency(dependency); - mgd.connection = connection; const connections = this._getModuleGraphModule(module).incomingConnections; connections.add(connection); - const mgm = this._getModuleGraphModule(originModule); - if (mgm.outgoingConnections === undefined) { - mgm.outgoingConnections = new Set(); + if (originModule) { + const mgm = this._getModuleGraphModule(originModule); + if (mgm._unassignedConnections === undefined) { + mgm._unassignedConnections = []; + } + mgm._unassignedConnections.push(connection); + if (mgm.outgoingConnections === undefined) { + mgm.outgoingConnections = new SortableSet(); + } + mgm.outgoingConnections.add(connection); + } else { + this._dependencyMap.set(dependency, connection); } - mgm.outgoingConnections.add(connection); } /** @@ -212,15 +242,19 @@ class ModuleGraph { * @returns {void} */ updateModule(dependency, module) { - const mgd = this._getModuleGraphDependency(dependency); - if (mgd.connection.module === module) return; - const { connection } = mgd; + const connection = + /** @type {ModuleGraphConnection} */ + (this.getConnection(dependency)); + if (connection.module === module) return; const newConnection = connection.clone(); newConnection.module = module; - mgd.connection = newConnection; + this._dependencyMap.set(dependency, newConnection); connection.setActive(false); - const originMgm = this._getModuleGraphModule(connection.originModule); - originMgm.outgoingConnections.add(newConnection); + const originMgm = this._getModuleGraphModule( + /** @type {Module} */ (connection.originModule) + ); + /** @type {OutgoingConnections} */ + (originMgm.outgoingConnections).add(newConnection); const targetMgm = this._getModuleGraphModule(module); targetMgm.incomingConnections.add(newConnection); } @@ -230,13 +264,17 @@ class ModuleGraph { * @returns {void} */ removeConnection(dependency) { - const mgd = this._getModuleGraphDependency(dependency); - const { connection } = mgd; + const connection = + /** @type {ModuleGraphConnection} */ + (this.getConnection(dependency)); const targetMgm = this._getModuleGraphModule(connection.module); targetMgm.incomingConnections.delete(connection); - const originMgm = this._getModuleGraphModule(connection.originModule); - originMgm.outgoingConnections.delete(connection); - mgd.connection = undefined; + const originMgm = this._getModuleGraphModule( + /** @type {Module} */ (connection.originModule) + ); + /** @type {OutgoingConnections} */ + (originMgm.outgoingConnections).delete(connection); + this._dependencyMap.set(dependency, null); } /** @@ -245,7 +283,9 @@ class ModuleGraph { * @returns {void} */ addExplanation(dependency, explanation) { - const { connection } = this._getModuleGraphDependency(dependency); + const connection = + /** @type {ModuleGraphConnection} */ + (this.getConnection(dependency)); connection.addExplanation(explanation); } @@ -302,7 +342,7 @@ class ModuleGraph { const oldConnections = oldMgm.outgoingConnections; if (oldConnections !== undefined) { if (newMgm.outgoingConnections === undefined) { - newMgm.outgoingConnections = new Set(); + newMgm.outgoingConnections = new SortableSet(); } const newConnections = newMgm.outgoingConnections; for (const connection of oldConnections) { @@ -339,7 +379,7 @@ class ModuleGraph { const oldConnections = oldMgm.outgoingConnections; if (oldConnections !== undefined) { if (newMgm.outgoingConnections === undefined) { - newMgm.outgoingConnections = new Set(); + newMgm.outgoingConnections = new SortableSet(); } const newConnections = newMgm.outgoingConnections; for (const connection of oldConnections) { @@ -368,10 +408,10 @@ class ModuleGraph { /** * @param {Dependency} dependency the dependency to look for a referenced module - * @returns {Module} the referenced module + * @returns {Module | null} the referenced module */ getResolvedModule(dependency) { - const { connection } = this._getModuleGraphDependency(dependency); + const connection = this.getConnection(dependency); return connection !== undefined ? connection.resolvedModule : null; } @@ -380,34 +420,60 @@ class ModuleGraph { * @returns {ModuleGraphConnection | undefined} the connection */ getConnection(dependency) { - const { connection } = this._getModuleGraphDependency(dependency); - return connection; + const connection = this._dependencyMap.get(dependency); + if (connection === undefined) { + const module = this.getParentModule(dependency); + if (module !== undefined) { + const mgm = this._getModuleGraphModule(module); + if ( + mgm._unassignedConnections && + mgm._unassignedConnections.length !== 0 + ) { + let foundConnection; + for (const connection of mgm._unassignedConnections) { + this._dependencyMap.set( + /** @type {Dependency} */ (connection.dependency), + connection + ); + if (connection.dependency === dependency) + foundConnection = connection; + } + mgm._unassignedConnections.length = 0; + if (foundConnection !== undefined) { + return foundConnection; + } + } + } + this._dependencyMap.set(dependency, null); + return; + } + return connection === null ? undefined : connection; } /** * @param {Dependency} dependency the dependency to look for a referenced module - * @returns {Module} the referenced module + * @returns {Module | null} the referenced module */ getModule(dependency) { - const { connection } = this._getModuleGraphDependency(dependency); + const connection = this.getConnection(dependency); return connection !== undefined ? connection.module : null; } /** * @param {Dependency} dependency the dependency to look for a referencing module - * @returns {Module} the referencing module + * @returns {Module | null} the referencing module */ getOrigin(dependency) { - const { connection } = this._getModuleGraphDependency(dependency); + const connection = this.getConnection(dependency); return connection !== undefined ? connection.originModule : null; } /** * @param {Dependency} dependency the dependency to look for a referencing module - * @returns {Module} the original referencing module + * @returns {Module | null} the original referencing module */ getResolvedOrigin(dependency) { - const { connection } = this._getModuleGraphDependency(dependency); + const connection = this.getConnection(dependency); return connection !== undefined ? connection.resolvedOriginModule : null; } @@ -426,12 +492,12 @@ class ModuleGraph { */ getOutgoingConnections(module) { const connections = this._getModuleGraphModule(module).outgoingConnections; - return connections === undefined ? EMPTY_ARRAY : connections; + return connections === undefined ? EMPTY_SET : connections; } /** * @param {Module} module the module - * @returns {readonly Map} reasons why a module is included, in a map by source module + * @returns {readonly Map} reasons why a module is included, in a map by source module */ getIncomingConnectionsByOriginModule(module) { const connections = this._getModuleGraphModule(module).incomingConnections; @@ -440,7 +506,18 @@ class ModuleGraph { /** * @param {Module} module the module - * @returns {ModuleProfile | null} the module profile + * @returns {readonly Map | undefined} connections to modules, in a map by module + */ + getOutgoingConnectionsByModule(module) { + const connections = this._getModuleGraphModule(module).outgoingConnections; + return connections === undefined + ? undefined + : connections.getFromUnorderedCache(getConnectionsByModule); + } + + /** + * @param {Module} module the module + * @returns {ModuleProfile | undefined} the module profile */ getProfile(module) { const mgm = this._getModuleGraphModule(module); @@ -449,7 +526,7 @@ class ModuleGraph { /** * @param {Module} module the module - * @param {ModuleProfile | null} profile the module profile + * @param {ModuleProfile | undefined} profile the module profile * @returns {void} */ setProfile(module, profile) { @@ -459,7 +536,7 @@ class ModuleGraph { /** * @param {Module} module the module - * @returns {Module | null} the issuer module + * @returns {Module | null | undefined} the issuer module */ getIssuer(module) { const mgm = this._getModuleGraphModule(module); @@ -563,7 +640,7 @@ class ModuleGraph { /** * @param {Module} module the module - * @returns {number} the index of the module + * @returns {number | null} the index of the module */ getPreOrderIndex(module) { const mgm = this._getModuleGraphModule(module); @@ -572,7 +649,7 @@ class ModuleGraph { /** * @param {Module} module the module - * @returns {number} the index of the module + * @returns {number | null} the index of the module */ getPostOrderIndex(module) { const mgm = this._getModuleGraphModule(module); @@ -629,7 +706,7 @@ class ModuleGraph { /** * @param {Module} module the module - * @returns {number} the depth of the module + * @returns {number | null} the depth of the module */ getDepth(module) { const mgm = this._getModuleGraphModule(module); @@ -680,25 +757,81 @@ class ModuleGraph { /** * @param {any} thing any thing - * @returns {Object} metadata + * @returns {object} metadata */ getMeta(thing) { let meta = this._metaMap.get(thing); if (meta === undefined) { meta = Object.create(null); - this._metaMap.set(thing, meta); + this._metaMap.set(thing, /** @type {object} */ (meta)); } - return meta; + return /** @type {object} */ (meta); } /** * @param {any} thing any thing - * @returns {Object} metadata + * @returns {object | undefined} metadata */ getMetaIfExisting(thing) { return this._metaMap.get(thing); } + /** + * @param {string=} cacheStage a persistent stage name for caching + */ + freeze(cacheStage) { + this._cache = new WeakTupleMap(); + this._cacheStage = cacheStage; + } + + unfreeze() { + this._cache = undefined; + this._cacheStage = undefined; + } + + /** + * @template {any[]} T + * @template V + * @param {(moduleGraph: ModuleGraph, ...args: T) => V} fn computer + * @param {T} args arguments + * @returns {V} computed value or cached + */ + cached(fn, ...args) { + if (this._cache === undefined) return fn(this, ...args); + return this._cache.provide(fn, ...args, () => fn(this, ...args)); + } + + /** + * @param {Map>} moduleMemCaches mem caches for modules for better caching + */ + setModuleMemCaches(moduleMemCaches) { + this._moduleMemCaches = moduleMemCaches; + } + + /** + * @param {Dependency} dependency dependency + * @param {...any} args arguments, last argument is a function called with moduleGraph, dependency, ...args + * @returns {any} computed value or cached + */ + dependencyCacheProvide(dependency, ...args) { + /** @type {(moduleGraph: ModuleGraph, dependency: Dependency, ...args: any[]) => any} */ + const fn = args.pop(); + if (this._moduleMemCaches && this._cacheStage) { + const memCache = this._moduleMemCaches.get( + /** @type {Module} */ (this.getParentModule(dependency)) + ); + if (memCache !== undefined) { + return memCache.provide(dependency, this._cacheStage, ...args, () => + fn(this, dependency, ...args) + ); + } + } + if (this._cache === undefined) return fn(this, dependency, ...args); + return this._cache.provide(dependency, ...args, () => + fn(this, dependency, ...args) + ); + } + // TODO remove in webpack 6 /** * @param {Module} module the module @@ -718,12 +851,13 @@ class ModuleGraph { const moduleGraph = moduleGraphForModuleMap.get(module); if (!moduleGraph) throw new Error( - deprecateMessage + - "There was no ModuleGraph assigned to the Module for backward-compat (Use the new API)" + `${ + deprecateMessage + }There was no ModuleGraph assigned to the Module for backward-compat (Use the new API)` ); return moduleGraph; }, - deprecateMessage + ": Use new ModuleGraph API", + `${deprecateMessage}: Use new ModuleGraph API`, deprecationCode ); deprecateMap.set(deprecateMessage, newFn); diff --git a/lib/ModuleGraphConnection.js b/lib/ModuleGraphConnection.js index 94f971953e8..1f12ac9e5cc 100644 --- a/lib/ModuleGraphConnection.js +++ b/lib/ModuleGraphConnection.js @@ -6,6 +6,7 @@ "use strict"; /** @typedef {import("./Dependency")} Dependency */ +/** @typedef {import("./Dependency").GetConditionFn} GetConditionFn */ /** @typedef {import("./Module")} Module */ /** @typedef {import("./util/runtime").RuntimeSpec} RuntimeSpec */ @@ -56,7 +57,7 @@ class ModuleGraphConnection { * @param {Module} module the referenced module * @param {string=} explanation some extra detail * @param {boolean=} weak the reference is weak - * @param {false | function(ModuleGraphConnection, RuntimeSpec): ConnectionState=} condition condition for the connection + * @param {false | null | GetConditionFn | undefined} condition condition for the connection */ constructor( originModule, @@ -72,11 +73,11 @@ class ModuleGraphConnection { this.resolvedModule = module; this.module = module; this.weak = weak; - this.conditional = !!condition; + this.conditional = Boolean(condition); this._active = condition !== false; - /** @type {function(ModuleGraphConnection, RuntimeSpec): ConnectionState} */ + /** @type {(function(ModuleGraphConnection, RuntimeSpec): ConnectionState) | undefined} */ this.condition = condition || undefined; - /** @type {Set} */ + /** @type {Set | undefined} */ this.explanations = undefined; if (explanation) { this.explanations = new Set(); @@ -107,7 +108,9 @@ class ModuleGraphConnection { */ addCondition(condition) { if (this.conditional) { - const old = this.condition; + const old = + /** @type {(function(ModuleGraphConnection, RuntimeSpec): ConnectionState)} */ + (this.condition); this.condition = (c, r) => intersectConnectionStates(old(c, r), condition(c, r)); } else if (this._active) { @@ -132,18 +135,18 @@ class ModuleGraphConnection { return Array.from(this.explanations).join(" "); } - // TODO webpack 5 remove - get active() { - throw new Error("Use getActiveState instead"); - } - /** * @param {RuntimeSpec} runtime the runtime * @returns {boolean} true, if the connection is active */ isActive(runtime) { if (!this.conditional) return this._active; - return this.condition(this, runtime) !== false; + + return ( + /** @type {(function(ModuleGraphConnection, RuntimeSpec): ConnectionState)} */ ( + this.condition + )(this, runtime) !== false + ); } /** @@ -152,7 +155,11 @@ class ModuleGraphConnection { */ isTargetActive(runtime) { if (!this.conditional) return this._active; - return this.condition(this, runtime) === true; + return ( + /** @type {(function(ModuleGraphConnection, RuntimeSpec): ConnectionState)} */ ( + this.condition + )(this, runtime) === true + ); } /** @@ -161,7 +168,9 @@ class ModuleGraphConnection { */ getActiveState(runtime) { if (!this.conditional) return this._active; - return this.condition(this, runtime); + return /** @type {(function(ModuleGraphConnection, RuntimeSpec): ConnectionState)} */ ( + this.condition + )(this, runtime); } /** @@ -173,6 +182,11 @@ class ModuleGraphConnection { this._active = value; } + // TODO webpack 5 remove + get active() { + throw new Error("Use getActiveState instead"); + } + set active(value) { throw new Error("Use setActive instead"); } @@ -183,5 +197,9 @@ class ModuleGraphConnection { module.exports = ModuleGraphConnection; module.exports.addConnectionStates = addConnectionStates; -module.exports.TRANSITIVE_ONLY = /** @type {typeof TRANSITIVE_ONLY} */ (TRANSITIVE_ONLY); -module.exports.CIRCULAR_CONNECTION = /** @type {typeof CIRCULAR_CONNECTION} */ (CIRCULAR_CONNECTION); +module.exports.TRANSITIVE_ONLY = /** @type {typeof TRANSITIVE_ONLY} */ ( + TRANSITIVE_ONLY +); +module.exports.CIRCULAR_CONNECTION = /** @type {typeof CIRCULAR_CONNECTION} */ ( + CIRCULAR_CONNECTION +); diff --git a/lib/ModuleHashingError.js b/lib/ModuleHashingError.js new file mode 100644 index 00000000000..77c8f415aff --- /dev/null +++ b/lib/ModuleHashingError.js @@ -0,0 +1,29 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ + +"use strict"; + +const WebpackError = require("./WebpackError"); + +/** @typedef {import("./Module")} Module */ + +class ModuleHashingError extends WebpackError { + /** + * Create a new ModuleHashingError + * @param {Module} module related module + * @param {Error} error Original error + */ + constructor(module, error) { + super(); + + this.name = "ModuleHashingError"; + this.error = error; + this.message = error.message; + this.details = error.stack; + this.module = module; + } +} + +module.exports = ModuleHashingError; diff --git a/lib/ModuleInfoHeaderPlugin.js b/lib/ModuleInfoHeaderPlugin.js index ea73f71d09f..994bfed88cb 100644 --- a/lib/ModuleInfoHeaderPlugin.js +++ b/lib/ModuleInfoHeaderPlugin.js @@ -8,6 +8,7 @@ const { ConcatSource, RawSource, CachedSource } = require("webpack-sources"); const { UsageState } = require("./ExportsInfo"); const Template = require("./Template"); +const CssModulesPlugin = require("./css/CssModulesPlugin"); const JavascriptModulesPlugin = require("./javascript/JavascriptModulesPlugin"); /** @typedef {import("webpack-sources").Source} Source */ @@ -15,10 +16,16 @@ const JavascriptModulesPlugin = require("./javascript/JavascriptModulesPlugin"); /** @typedef {import("./ExportsInfo")} ExportsInfo */ /** @typedef {import("./ExportsInfo").ExportInfo} ExportInfo */ /** @typedef {import("./Module")} Module */ +/** @typedef {import("./Module").BuildMeta} BuildMeta */ /** @typedef {import("./ModuleGraph")} ModuleGraph */ /** @typedef {import("./ModuleTemplate")} ModuleTemplate */ /** @typedef {import("./RequestShortener")} RequestShortener */ +/** + * @template T + * @param {Iterable} iterable iterable + * @returns {string} joined with comma + */ const joinIterableWithComma = iterable => { // This is more performant than Array.from().join(", ") // as it doesn't create an array @@ -78,7 +85,7 @@ const printExportsInfoToSource = ( for (const exportInfo of printedExports) { const target = exportInfo.getTarget(moduleGraph); source.add( - Template.toComment( + `${Template.toComment( `${indent}export ${JSON.stringify(exportInfo.name).slice( 1, -1 @@ -90,15 +97,15 @@ const printExportsInfoToSource = ( .map(e => JSON.stringify(e).slice(1, -1)) .join(".")}` : "" - }` + }` : "" }` - ) + "\n" + )}\n` ); if (exportInfo.exportsInfo) { printExportsInfoToSource( source, - indent + " ", + `${indent} `, exportInfo.exportsInfo, moduleGraph, requestShortener, @@ -109,9 +116,9 @@ const printExportsInfoToSource = ( if (alreadyPrintedExports) { source.add( - Template.toComment( + `${Template.toComment( `${indent}... (${alreadyPrintedExports} already listed exports)` - ) + "\n" + )}\n` ); } @@ -127,19 +134,19 @@ const printExportsInfoToSource = ( ? "other exports" : "exports"; source.add( - Template.toComment( + `${Template.toComment( `${indent}${title} [${otherExportsInfo.getProvidedInfo()}] [${otherExportsInfo.getUsedInfo()}]${ target ? ` -> ${target.module.readableIdentifier(requestShortener)}` : "" }` - ) + "\n" + )}\n` ); } } }; -/** @type {WeakMap }>>} */ +/** @type {WeakMap }>>} */ const caches = new WeakMap(); class ModuleInfoHeaderPlugin { @@ -149,6 +156,7 @@ class ModuleInfoHeaderPlugin { constructor(verbose = true) { this._verbose = verbose; } + /** * @param {Compiler} compiler the compiler * @returns {void} @@ -156,8 +164,9 @@ class ModuleInfoHeaderPlugin { apply(compiler) { const { _verbose: verbose } = this; compiler.hooks.compilation.tap("ModuleInfoHeaderPlugin", compilation => { - const hooks = JavascriptModulesPlugin.getCompilationHooks(compilation); - hooks.renderModulePackage.tap( + const javascriptHooks = + JavascriptModulesPlugin.getCompilationHooks(compilation); + javascriptHooks.renderModulePackage.tap( "ModuleInfoHeaderPlugin", ( moduleSource, @@ -188,22 +197,19 @@ class ModuleInfoHeaderPlugin { const source = new ConcatSource(); let header = cacheEntry.header; if (header === undefined) { - const req = module.readableIdentifier(requestShortener); - const reqStr = req.replace(/\*\//g, "*_/"); - const reqStrStar = "*".repeat(reqStr.length); - const headerStr = `/*!****${reqStrStar}****!*\\\n !*** ${reqStr} ***!\n \\****${reqStrStar}****/\n`; - header = new RawSource(headerStr); + header = this.generateHeader(module, requestShortener); cacheEntry.header = header; } source.add(header); if (verbose) { - const exportsType = module.buildMeta.exportsType; + const exportsType = /** @type {BuildMeta} */ (module.buildMeta) + .exportsType; source.add( - Template.toComment( + `${Template.toComment( exportsType ? `${exportsType} exports` : "unknown exports (runtime-defined)" - ) + "\n" + )}\n` ); if (exportsType) { const exportsInfo = moduleGraph.getExportsInfo(module); @@ -216,41 +222,93 @@ class ModuleInfoHeaderPlugin { ); } source.add( - Template.toComment( + `${Template.toComment( `runtime requirements: ${joinIterableWithComma( chunkGraph.getModuleRuntimeRequirements(module, chunk.runtime) )}` - ) + "\n" - ); - const optimizationBailout = moduleGraph.getOptimizationBailout( - module + )}\n` ); + const optimizationBailout = + moduleGraph.getOptimizationBailout(module); if (optimizationBailout) { for (const text of optimizationBailout) { - let code; - if (typeof text === "function") { - code = text(requestShortener); - } else { - code = text; - } - source.add(Template.toComment(`${code}`) + "\n"); + const code = + typeof text === "function" ? text(requestShortener) : text; + source.add(`${Template.toComment(`${code}`)}\n`); } } source.add(moduleSource); return source; + } + source.add(moduleSource); + const cachedSource = new CachedSource(source); + cacheEntry.full.set(moduleSource, cachedSource); + return cachedSource; + } + ); + javascriptHooks.chunkHash.tap( + "ModuleInfoHeaderPlugin", + (_chunk, hash) => { + hash.update("ModuleInfoHeaderPlugin"); + hash.update("1"); + } + ); + const cssHooks = CssModulesPlugin.getCompilationHooks(compilation); + cssHooks.renderModulePackage.tap( + "ModuleInfoHeaderPlugin", + (moduleSource, module, { runtimeTemplate }) => { + const { requestShortener } = runtimeTemplate; + let cacheEntry; + let cache = caches.get(requestShortener); + if (cache === undefined) { + caches.set(requestShortener, (cache = new WeakMap())); + cache.set( + module, + (cacheEntry = { header: undefined, full: new WeakMap() }) + ); } else { - source.add(moduleSource); - const cachedSource = new CachedSource(source); - cacheEntry.full.set(moduleSource, cachedSource); - return cachedSource; + cacheEntry = cache.get(module); + if (cacheEntry === undefined) { + cache.set( + module, + (cacheEntry = { header: undefined, full: new WeakMap() }) + ); + } else if (!verbose) { + const cachedSource = cacheEntry.full.get(moduleSource); + if (cachedSource !== undefined) return cachedSource; + } } + const source = new ConcatSource(); + let header = cacheEntry.header; + if (header === undefined) { + header = this.generateHeader(module, requestShortener); + cacheEntry.header = header; + } + source.add(header); + source.add(moduleSource); + const cachedSource = new CachedSource(source); + cacheEntry.full.set(moduleSource, cachedSource); + return cachedSource; } ); - hooks.chunkHash.tap("ModuleInfoHeaderPlugin", (chunk, hash) => { + cssHooks.chunkHash.tap("ModuleInfoHeaderPlugin", (_chunk, hash) => { hash.update("ModuleInfoHeaderPlugin"); hash.update("1"); }); }); } + + /** + * @param {Module} module the module + * @param {RequestShortener} requestShortener request shortener + * @returns {RawSource} the header + */ + generateHeader(module, requestShortener) { + const req = module.readableIdentifier(requestShortener); + const reqStr = req.replace(/\*\//g, "*_/"); + const reqStrStar = "*".repeat(reqStr.length); + const headerStr = `/*!****${reqStrStar}****!*\\\n !*** ${reqStr} ***!\n \\****${reqStrStar}****/\n`; + return new RawSource(headerStr); + } } module.exports = ModuleInfoHeaderPlugin; diff --git a/lib/ModuleNotFoundError.js b/lib/ModuleNotFoundError.js index 1daf31dcd5c..6fdf241dee8 100644 --- a/lib/ModuleNotFoundError.js +++ b/lib/ModuleNotFoundError.js @@ -43,7 +43,7 @@ const previouslyPolyfilledBuiltinModules = { class ModuleNotFoundError extends WebpackError { /** - * @param {Module} module module tied to dependency + * @param {Module | null} module module tied to dependency * @param {Error&any} err error thrown * @param {DependencyLocation} loc location of dependency */ @@ -54,7 +54,10 @@ class ModuleNotFoundError extends WebpackError { const match = err.message.match(/Can't resolve '([^']+)'/); if (match) { const request = match[1]; - const alias = previouslyPolyfilledBuiltinModules[request]; + const alias = + previouslyPolyfilledBuiltinModules[ + /** @type {keyof previouslyPolyfilledBuiltinModules} */ (request) + ]; if (alias) { const pathIndex = alias.indexOf("/"); const dependency = pathIndex > 0 ? alias.slice(0, pathIndex) : alias; @@ -80,8 +83,6 @@ class ModuleNotFoundError extends WebpackError { this.module = module; this.error = err; this.loc = loc; - - Error.captureStackTrace(this, this.constructor); } } diff --git a/lib/ModuleParseError.js b/lib/ModuleParseError.js index 8743b101f9a..d14c763aec8 100644 --- a/lib/ModuleParseError.js +++ b/lib/ModuleParseError.js @@ -8,18 +8,21 @@ const WebpackError = require("./WebpackError"); const makeSerializable = require("./util/makeSerializable"); +/** @typedef {import("./serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */ +/** @typedef {import("./serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */ + const WASM_HEADER = Buffer.from([0x00, 0x61, 0x73, 0x6d]); class ModuleParseError extends WebpackError { /** * @param {string | Buffer} source source code - * @param {Error&any} err the parse error + * @param {Error & any} err the parse error * @param {string[]} loaders the loaders used * @param {string} type module type */ constructor(source, err, loaders, type) { - let message = "Module parse failed: " + (err && err.message); - let loc = undefined; + let message = `Module parse failed: ${err && err.message}`; + let loc; if ( ((Buffer.isBuffer(source) && source.slice(0, 4).equals(WASM_HEADER)) || @@ -54,7 +57,7 @@ class ModuleParseError extends WebpackError { typeof err.loc === "object" && typeof err.loc.line === "number" ) { - var lineNumber = err.loc.line; + const lineNumber = err.loc.line; if ( Buffer.isBuffer(source) || @@ -69,15 +72,14 @@ class ModuleParseError extends WebpackError { const theLine = sourceLines[lineNumber - 1]; const linesAfter = sourceLines.slice(lineNumber, lineNumber + 2); - message += - linesBefore.map(l => `\n| ${l}`).join("") + - `\n> ${theLine}` + - linesAfter.map(l => `\n| ${l}`).join(""); + message += `${linesBefore + .map(l => `\n| ${l}`) + .join("")}\n> ${theLine}${linesAfter.map(l => `\n| ${l}`).join("")}`; } loc = { start: err.loc }; } else if (err && err.stack) { - message += "\n" + err.stack; + message += `\n${err.stack}`; } super(message); @@ -85,10 +87,11 @@ class ModuleParseError extends WebpackError { this.name = "ModuleParseError"; this.loc = loc; this.error = err; - - Error.captureStackTrace(this, this.constructor); } + /** + * @param {ObjectSerializerContext} context context + */ serialize(context) { const { write } = context; @@ -97,6 +100,9 @@ class ModuleParseError extends WebpackError { super.serialize(context); } + /** + * @param {ObjectDeserializerContext} context context + */ deserialize(context) { const { read } = context; diff --git a/lib/ModuleProfile.js b/lib/ModuleProfile.js index e0c2b733d4b..360991ab005 100644 --- a/lib/ModuleProfile.js +++ b/lib/ModuleProfile.js @@ -34,6 +34,7 @@ class ModuleProfile { this.storing = 0; this.storingParallelismFactor = 0; + /** @type {{ start: number, end: number }[] | undefined } */ this.additionalFactoryTimes = undefined; this.additionalFactories = 0; this.additionalFactoriesParallelismFactor = 0; diff --git a/lib/ModuleRestoreError.js b/lib/ModuleRestoreError.js index e42591e49ab..2570862d421 100644 --- a/lib/ModuleRestoreError.js +++ b/lib/ModuleRestoreError.js @@ -16,7 +16,8 @@ class ModuleRestoreError extends WebpackError { */ constructor(module, err) { let message = "Module restore failed: "; - let details = undefined; + /** @type {string | undefined} */ + const details = undefined; if (err !== null && typeof err === "object") { if (typeof err.stack === "string" && err.stack) { const stack = err.stack; @@ -33,11 +34,10 @@ class ModuleRestoreError extends WebpackError { super(message); this.name = "ModuleRestoreError"; + /** @type {string | undefined} */ this.details = details; this.module = module; this.error = err; - - Error.captureStackTrace(this, this.constructor); } } diff --git a/lib/ModuleStoreError.js b/lib/ModuleStoreError.js index 6d81e22b74f..26ca0c8b5d7 100644 --- a/lib/ModuleStoreError.js +++ b/lib/ModuleStoreError.js @@ -16,7 +16,8 @@ class ModuleStoreError extends WebpackError { */ constructor(module, err) { let message = "Module storing failed: "; - let details = undefined; + /** @type {string | undefined} */ + const details = undefined; if (err !== null && typeof err === "object") { if (typeof err.stack === "string" && err.stack) { const stack = err.stack; @@ -33,11 +34,9 @@ class ModuleStoreError extends WebpackError { super(message); this.name = "ModuleStoreError"; - this.details = details; + this.details = /** @type {string | undefined} */ (details); this.module = module; this.error = err; - - Error.captureStackTrace(this, this.constructor); } } diff --git a/lib/ModuleTemplate.js b/lib/ModuleTemplate.js index f859758a5ea..799037710d7 100644 --- a/lib/ModuleTemplate.js +++ b/lib/ModuleTemplate.js @@ -8,6 +8,7 @@ const util = require("util"); const memoize = require("./util/memoize"); +/** @typedef {import("tapable").Tap} Tap */ /** @typedef {import("webpack-sources").Source} Source */ /** @typedef {import("./Chunk")} Chunk */ /** @typedef {import("./ChunkGraph")} ChunkGraph */ @@ -16,21 +17,18 @@ const memoize = require("./util/memoize"); /** @typedef {import("./Module")} Module */ /** @typedef {import("./ModuleGraph")} ModuleGraph */ /** @typedef {import("./RuntimeTemplate")} RuntimeTemplate */ +/** @typedef {import("./javascript/JavascriptModulesPlugin").ChunkRenderContext} ChunkRenderContext */ /** @typedef {import("./util/Hash")} Hash */ +/** + * @template T + * @typedef {import("tapable").IfSet} IfSet + */ + const getJavascriptModulesPlugin = memoize(() => require("./javascript/JavascriptModulesPlugin") ); -/** - * @typedef {Object} RenderContext - * @property {Chunk} chunk the chunk - * @property {DependencyTemplates} dependencyTemplates the dependency templates - * @property {RuntimeTemplate} runtimeTemplate the runtime template - * @property {ModuleGraph} moduleGraph the module graph - * @property {ChunkGraph} chunkGraph the chunk graph - */ - // TODO webpack 6: remove this class class ModuleTemplate { /** @@ -43,6 +41,11 @@ class ModuleTemplate { this.hooks = Object.freeze({ content: { tap: util.deprecate( + /** + * @template AdditionalOptions + * @param {string | Tap & IfSet} options options + * @param {function(Source, Module, ChunkRenderContext, DependencyTemplates): Source} fn fn + */ (options, fn) => { getJavascriptModulesPlugin() .getCompilationHooks(compilation) @@ -63,6 +66,11 @@ class ModuleTemplate { }, module: { tap: util.deprecate( + /** + * @template AdditionalOptions + * @param {string | Tap & IfSet} options options + * @param {function(Source, Module, ChunkRenderContext, DependencyTemplates): Source} fn fn + */ (options, fn) => { getJavascriptModulesPlugin() .getCompilationHooks(compilation) @@ -83,6 +91,11 @@ class ModuleTemplate { }, render: { tap: util.deprecate( + /** + * @template AdditionalOptions + * @param {string | Tap & IfSet} options options + * @param {function(Source, Module, ChunkRenderContext, DependencyTemplates): Source} fn fn + */ (options, fn) => { getJavascriptModulesPlugin() .getCompilationHooks(compilation) @@ -103,6 +116,11 @@ class ModuleTemplate { }, package: { tap: util.deprecate( + /** + * @template AdditionalOptions + * @param {string | Tap & IfSet} options options + * @param {function(Source, Module, ChunkRenderContext, DependencyTemplates): Source} fn fn + */ (options, fn) => { getJavascriptModulesPlugin() .getCompilationHooks(compilation) @@ -123,6 +141,11 @@ class ModuleTemplate { }, hash: { tap: util.deprecate( + /** + * @template AdditionalOptions + * @param {string | Tap & IfSet} options options + * @param {function(Hash): void} fn fn + */ (options, fn) => { compilation.hooks.fullHash.tap(options, fn); }, @@ -138,7 +161,7 @@ Object.defineProperty(ModuleTemplate.prototype, "runtimeTemplate", { get: util.deprecate( /** * @this {ModuleTemplate} - * @returns {TODO} output options + * @returns {RuntimeTemplate} output options */ function () { return this._runtimeTemplate; diff --git a/lib/ModuleTypeConstants.js b/lib/ModuleTypeConstants.js new file mode 100644 index 00000000000..dee3ae9f001 --- /dev/null +++ b/lib/ModuleTypeConstants.js @@ -0,0 +1,168 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Sean Larkin @TheLarkInn +*/ + +"use strict"; + +/** + * @type {Readonly<"javascript/auto">} + */ +const JAVASCRIPT_MODULE_TYPE_AUTO = "javascript/auto"; + +/** + * @type {Readonly<"javascript/dynamic">} + */ +const JAVASCRIPT_MODULE_TYPE_DYNAMIC = "javascript/dynamic"; + +/** + * @type {Readonly<"javascript/esm">} + * This is the module type used for _strict_ ES Module syntax. This means that all legacy formats + * that webpack supports (CommonJS, AMD, SystemJS) are not supported. + */ +const JAVASCRIPT_MODULE_TYPE_ESM = "javascript/esm"; + +/** + * @type {Readonly<"json">} + * This is the module type used for JSON files. JSON files are always parsed as ES Module. + */ +const JSON_MODULE_TYPE = "json"; + +/** + * @type {Readonly<"webassembly/async">} + * This is the module type used for WebAssembly modules. In webpack 5 they are always treated as async modules. + */ +const WEBASSEMBLY_MODULE_TYPE_ASYNC = "webassembly/async"; + +/** + * @type {Readonly<"webassembly/sync">} + * This is the module type used for WebAssembly modules. In webpack 4 they are always treated as sync modules. + * There is a legacy option to support this usage in webpack 5 and up. + */ +const WEBASSEMBLY_MODULE_TYPE_SYNC = "webassembly/sync"; + +/** + * @type {Readonly<"css">} + * This is the module type used for CSS files. + */ +const CSS_MODULE_TYPE = "css"; + +/** + * @type {Readonly<"css/global">} + * This is the module type used for CSS modules files where you need to use `:local` in selector list to hash classes. + */ +const CSS_MODULE_TYPE_GLOBAL = "css/global"; + +/** + * @type {Readonly<"css/module">} + * This is the module type used for CSS modules files, by default all classes are hashed. + */ +const CSS_MODULE_TYPE_MODULE = "css/module"; + +/** + * @type {Readonly<"css/auto">} + * This is the module type used for CSS files, the module will be parsed as CSS modules if it's filename contains `.module.` or `.modules.`. + */ +const CSS_MODULE_TYPE_AUTO = "css/auto"; + +/** + * @type {Readonly<"asset">} + * This is the module type used for automatically choosing between `asset/inline`, `asset/resource` based on asset size limit (8096). + */ +const ASSET_MODULE_TYPE = "asset"; + +/** + * @type {Readonly<"asset/inline">} + * This is the module type used for assets that are inlined as a data URI. This is the equivalent of `url-loader`. + */ +const ASSET_MODULE_TYPE_INLINE = "asset/inline"; + +/** + * @type {Readonly<"asset/resource">} + * This is the module type used for assets that are copied to the output directory. This is the equivalent of `file-loader`. + */ +const ASSET_MODULE_TYPE_RESOURCE = "asset/resource"; + +/** + * @type {Readonly<"asset/source">} + * This is the module type used for assets that are imported as source code. This is the equivalent of `raw-loader`. + */ +const ASSET_MODULE_TYPE_SOURCE = "asset/source"; + +/** + * @type {Readonly<"asset/raw-data-url">} + * TODO: Document what this asset type is for. See css-loader tests for its usage. + */ +const ASSET_MODULE_TYPE_RAW_DATA_URL = "asset/raw-data-url"; + +/** + * @type {Readonly<"runtime">} + * This is the module type used for the webpack runtime abstractions. + */ +const WEBPACK_MODULE_TYPE_RUNTIME = "runtime"; + +/** + * @type {Readonly<"fallback-module">} + * This is the module type used for the ModuleFederation feature's FallbackModule class. + * TODO: Document this better. + */ +const WEBPACK_MODULE_TYPE_FALLBACK = "fallback-module"; + +/** + * @type {Readonly<"remote-module">} + * This is the module type used for the ModuleFederation feature's RemoteModule class. + * TODO: Document this better. + */ +const WEBPACK_MODULE_TYPE_REMOTE = "remote-module"; + +/** + * @type {Readonly<"provide-module">} + * This is the module type used for the ModuleFederation feature's ProvideModule class. + * TODO: Document this better. + */ +const WEBPACK_MODULE_TYPE_PROVIDE = "provide-module"; + +/** + * @type {Readonly<"consume-shared-module">} + * This is the module type used for the ModuleFederation feature's ConsumeSharedModule class. + */ +const WEBPACK_MODULE_TYPE_CONSUME_SHARED_MODULE = "consume-shared-module"; + +/** + * @type {Readonly<"lazy-compilation-proxy">} + * Module type used for `experiments.lazyCompilation` feature. See `LazyCompilationPlugin` for more information. + */ +const WEBPACK_MODULE_TYPE_LAZY_COMPILATION_PROXY = "lazy-compilation-proxy"; + +/** @typedef {"javascript/auto" | "javascript/dynamic" | "javascript/esm"} JavaScriptModuleTypes */ +/** @typedef {"json"} JSONModuleType */ +/** @typedef {"webassembly/async" | "webassembly/sync"} WebAssemblyModuleTypes */ +/** @typedef {"css" | "css/global" | "css/module"} CSSModuleTypes */ +/** @typedef {"asset" | "asset/inline" | "asset/resource" | "asset/source" | "asset/raw-data-url"} AssetModuleTypes */ +/** @typedef {"runtime" | "fallback-module" | "remote-module" | "provide-module" | "consume-shared-module" | "lazy-compilation-proxy"} WebpackModuleTypes */ +/** @typedef {string} UnknownModuleTypes */ +/** @typedef {JavaScriptModuleTypes | JSONModuleType | WebAssemblyModuleTypes | CSSModuleTypes | AssetModuleTypes | WebpackModuleTypes | UnknownModuleTypes} ModuleTypes */ + +module.exports.ASSET_MODULE_TYPE = ASSET_MODULE_TYPE; +module.exports.ASSET_MODULE_TYPE_RAW_DATA_URL = ASSET_MODULE_TYPE_RAW_DATA_URL; +module.exports.ASSET_MODULE_TYPE_SOURCE = ASSET_MODULE_TYPE_SOURCE; +module.exports.ASSET_MODULE_TYPE_RESOURCE = ASSET_MODULE_TYPE_RESOURCE; +module.exports.ASSET_MODULE_TYPE_INLINE = ASSET_MODULE_TYPE_INLINE; +module.exports.JAVASCRIPT_MODULE_TYPE_AUTO = JAVASCRIPT_MODULE_TYPE_AUTO; +module.exports.JAVASCRIPT_MODULE_TYPE_DYNAMIC = JAVASCRIPT_MODULE_TYPE_DYNAMIC; +module.exports.JAVASCRIPT_MODULE_TYPE_ESM = JAVASCRIPT_MODULE_TYPE_ESM; +module.exports.JSON_MODULE_TYPE = JSON_MODULE_TYPE; +module.exports.WEBASSEMBLY_MODULE_TYPE_ASYNC = WEBASSEMBLY_MODULE_TYPE_ASYNC; +module.exports.WEBASSEMBLY_MODULE_TYPE_SYNC = WEBASSEMBLY_MODULE_TYPE_SYNC; +module.exports.CSS_MODULE_TYPE = CSS_MODULE_TYPE; +module.exports.CSS_MODULE_TYPE_GLOBAL = CSS_MODULE_TYPE_GLOBAL; +module.exports.CSS_MODULE_TYPE_MODULE = CSS_MODULE_TYPE_MODULE; +module.exports.CSS_MODULE_TYPE_AUTO = CSS_MODULE_TYPE_AUTO; +module.exports.WEBPACK_MODULE_TYPE_RUNTIME = WEBPACK_MODULE_TYPE_RUNTIME; +module.exports.WEBPACK_MODULE_TYPE_FALLBACK = WEBPACK_MODULE_TYPE_FALLBACK; +module.exports.WEBPACK_MODULE_TYPE_REMOTE = WEBPACK_MODULE_TYPE_REMOTE; +module.exports.WEBPACK_MODULE_TYPE_PROVIDE = WEBPACK_MODULE_TYPE_PROVIDE; +module.exports.WEBPACK_MODULE_TYPE_CONSUME_SHARED_MODULE = + WEBPACK_MODULE_TYPE_CONSUME_SHARED_MODULE; +module.exports.WEBPACK_MODULE_TYPE_LAZY_COMPILATION_PROXY = + WEBPACK_MODULE_TYPE_LAZY_COMPILATION_PROXY; diff --git a/lib/ModuleWarning.js b/lib/ModuleWarning.js index a663d638153..9b45a9afdd0 100644 --- a/lib/ModuleWarning.js +++ b/lib/ModuleWarning.js @@ -9,6 +9,9 @@ const { cleanUp } = require("./ErrorHelpers"); const WebpackError = require("./WebpackError"); const makeSerializable = require("./util/makeSerializable"); +/** @typedef {import("./serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */ +/** @typedef {import("./serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */ + class ModuleWarning extends WebpackError { /** * @param {Error} warning error thrown @@ -17,11 +20,7 @@ class ModuleWarning extends WebpackError { constructor(warning, { from = null } = {}) { let message = "Module Warning"; - if (from) { - message += ` (from ${from}):\n`; - } else { - message += ": "; - } + message += from ? ` (from ${from}):\n` : ": "; if (warning && typeof warning === "object" && warning.message) { message += warning.message; @@ -37,10 +36,11 @@ class ModuleWarning extends WebpackError { warning && typeof warning === "object" && warning.stack ? cleanUp(warning.stack, this.message) : undefined; - - Error.captureStackTrace(this, this.constructor); } + /** + * @param {ObjectSerializerContext} context context + */ serialize(context) { const { write } = context; @@ -49,6 +49,9 @@ class ModuleWarning extends WebpackError { super.serialize(context); } + /** + * @param {ObjectDeserializerContext} context context + */ deserialize(context) { const { read } = context; diff --git a/lib/MultiCompiler.js b/lib/MultiCompiler.js index 99b67e04fb6..8c72da319d9 100644 --- a/lib/MultiCompiler.js +++ b/lib/MultiCompiler.js @@ -11,6 +11,7 @@ const { SyncHook, MultiHook } = require("tapable"); const ConcurrentCompilationError = require("./ConcurrentCompilationError"); const MultiStats = require("./MultiStats"); const MultiWatching = require("./MultiWatching"); +const WebpackError = require("./WebpackError"); const ArrayQueue = require("./util/ArrayQueue"); /** @template T @typedef {import("tapable").AsyncSeriesHook} AsyncSeriesHook */ @@ -19,6 +20,7 @@ const ArrayQueue = require("./util/ArrayQueue"); /** @typedef {import("./Compiler")} Compiler */ /** @typedef {import("./Stats")} Stats */ /** @typedef {import("./Watching")} Watching */ +/** @typedef {import("./logging/Logger").Logger} Logger */ /** @typedef {import("./util/fs").InputFileSystem} InputFileSystem */ /** @typedef {import("./util/fs").IntermediateFileSystem} IntermediateFileSystem */ /** @typedef {import("./util/fs").OutputFileSystem} OutputFileSystem */ @@ -27,7 +29,7 @@ const ArrayQueue = require("./util/ArrayQueue"); /** * @template T * @callback Callback - * @param {Error=} err + * @param {Error | null} err * @param {T=} result */ @@ -38,7 +40,7 @@ const ArrayQueue = require("./util/ArrayQueue"); */ /** - * @typedef {Object} MultiCompilerOptions + * @typedef {object} MultiCompilerOptions * @property {number=} parallelism how many Compilers are allows to run at the same time in parallel */ @@ -49,9 +51,11 @@ module.exports = class MultiCompiler { */ constructor(compilers, options) { if (!Array.isArray(compilers)) { + /** @type {Compiler[]} */ compilers = Object.keys(compilers).map(name => { - compilers[name].name = name; - return compilers[name]; + /** @type {Record} */ + (compilers)[name].name = name; + return /** @type {Record} */ (compilers)[name]; }); } @@ -80,7 +84,7 @@ module.exports = class MultiCompiler { this.dependencies = new WeakMap(); this.running = false; - /** @type {Stats[]} */ + /** @type {(Stats | null)[]} */ const compilerStats = this.compilers.map(() => null); let doneCompilers = 0; for (let index = 0; index < this.compilers.length; index++) { @@ -95,7 +99,9 @@ module.exports = class MultiCompiler { } compilerStats[compilerIndex] = stats; if (doneCompilers === this.compilers.length) { - this.hooks.done.call(new MultiStats(compilerStats)); + this.hooks.done.call( + new MultiStats(/** @type {Stats[]} */ (compilerStats)) + ); } }); // eslint-disable-next-line no-loop-func @@ -106,6 +112,40 @@ module.exports = class MultiCompiler { } }); } + this._validateCompilersOptions(); + } + + _validateCompilersOptions() { + if (this.compilers.length < 2) return; + /** + * @param {Compiler} compiler compiler + * @param {WebpackError} warning warning + */ + const addWarning = (compiler, warning) => { + compiler.hooks.thisCompilation.tap("MultiCompiler", compilation => { + compilation.warnings.push(warning); + }); + }; + const cacheNames = new Set(); + for (const compiler of this.compilers) { + if (compiler.options.cache && "name" in compiler.options.cache) { + const name = compiler.options.cache.name; + if (cacheNames.has(name)) { + addWarning( + compiler, + new WebpackError( + `${ + compiler.name + ? `Compiler with name "${compiler.name}" doesn't use unique cache name. ` + : "" + }Please set unique "cache.name" option. Name "${name}" already used.` + ) + ); + } else { + cacheNames.add(name); + } + } + } } get options() { @@ -134,18 +174,6 @@ module.exports = class MultiCompiler { throw new Error("Cannot read inputFileSystem of a MultiCompiler"); } - get outputFileSystem() { - throw new Error("Cannot read outputFileSystem of a MultiCompiler"); - } - - get watchFileSystem() { - throw new Error("Cannot read watchFileSystem of a MultiCompiler"); - } - - get intermediateFileSystem() { - throw new Error("Cannot read outputFileSystem of a MultiCompiler"); - } - /** * @param {InputFileSystem} value the new input file system */ @@ -155,6 +183,10 @@ module.exports = class MultiCompiler { } } + get outputFileSystem() { + throw new Error("Cannot read outputFileSystem of a MultiCompiler"); + } + /** * @param {OutputFileSystem} value the new output file system */ @@ -164,6 +196,10 @@ module.exports = class MultiCompiler { } } + get watchFileSystem() { + throw new Error("Cannot read watchFileSystem of a MultiCompiler"); + } + /** * @param {WatchFileSystem} value the new watch file system */ @@ -182,6 +218,14 @@ module.exports = class MultiCompiler { } } + get intermediateFileSystem() { + throw new Error("Cannot read outputFileSystem of a MultiCompiler"); + } + + /** + * @param {string | (function(): string)} name name of the logger, or function called once to get the logger name + * @returns {Logger} a logger with that name + */ getInfrastructureLogger(name) { return this.compilers[0].getInfrastructureLogger(name); } @@ -204,6 +248,10 @@ module.exports = class MultiCompiler { const edges = new Set(); /** @type {string[]} */ const missing = []; + /** + * @param {Compiler} compiler compiler + * @returns {boolean} target was found + */ const targetFound = compiler => { for (const edge of edges) { if (edge.target === compiler) { @@ -212,12 +260,16 @@ module.exports = class MultiCompiler { } return false; }; - const sortEdges = (e1, e2) => { - return ( - e1.source.name.localeCompare(e2.source.name) || - e1.target.name.localeCompare(e2.target.name) - ); - }; + /** + * @param {{source: Compiler, target: Compiler}} e1 edge 1 + * @param {{source: Compiler, target: Compiler}} e2 edge 2 + * @returns {number} result + */ + const sortEdges = (e1, e2) => + /** @type {string} */ + (e1.source.name).localeCompare(/** @type {string} */ (e2.source.name)) || + /** @type {string} */ + (e1.target.name).localeCompare(/** @type {string} */ (e2.target.name)); for (const source of this.compilers) { const dependencies = this.dependencies.get(source); if (dependencies) { @@ -276,10 +328,17 @@ module.exports = class MultiCompiler { runWithDependencies(compilers, fn, callback) { const fulfilledNames = new Set(); let remainingCompilers = compilers; + /** + * @param {string} d dependency + * @returns {boolean} when dependency was fulfilled + */ const isDependencyFulfilled = d => fulfilledNames.has(d); + /** + * @returns {Compiler[]} compilers + */ const getReadyCompilers = () => { - let readyCompilers = []; - let list = remainingCompilers; + const readyCompilers = []; + const list = remainingCompilers; remainingCompilers = []; for (const c of list) { const dependencies = this.dependencies.get(c); @@ -293,8 +352,12 @@ module.exports = class MultiCompiler { } return readyCompilers; }; + /** + * @param {Callback} callback callback + * @returns {void} + */ const runCompilers = callback => { - if (remainingCompilers.length === 0) return callback(); + if (remainingCompilers.length === 0) return callback(null); asyncLib.map( getReadyCompilers(), (compiler, callback) => { @@ -304,7 +367,9 @@ module.exports = class MultiCompiler { runCompilers(callback); }); }, - callback + (err, results) => { + callback(err, /** @type {TODO} */ (results)); + } ); }; runCompilers(callback); @@ -313,27 +378,29 @@ module.exports = class MultiCompiler { /** * @template SetupResult * @param {function(Compiler, number, Callback, function(): boolean, function(): void, function(): void): SetupResult} setup setup a single compiler - * @param {function(Compiler, Callback): void} run run/continue a single compiler + * @param {function(Compiler, SetupResult, Callback): void} run run/continue a single compiler * @param {Callback} callback callback when all compilers are done, result includes Stats of all changed compilers * @returns {SetupResult[]} result of setup */ _runGraph(setup, run, callback) { - /** @typedef {{ compiler: Compiler, result: Stats, state: "pending" | "blocked" | "queued" | "running" | "running-outdated" | "done", children: Node[], parents: Node[] }} Node */ + /** @typedef {{ compiler: Compiler, setupResult: undefined | SetupResult, result: undefined | Stats, state: "pending" | "blocked" | "queued" | "starting" | "running" | "running-outdated" | "done", children: Node[], parents: Node[] }} Node */ // State transitions for nodes: // -> blocked (initial) - // blocked -> queued [add to queue] (when all parents done) - // queued -> running [running++] (when processing the queue) + // blocked -> starting [running++] (when all parents done) + // queued -> starting [running++] (when processing the queue) + // starting -> running (when run has been called) // running -> done [running--] (when compilation is done) // done -> pending (when invalidated from file change) - // pending -> blocked (when invalidated from aggregated changes) - // done -> blocked (when invalidated, from parent invalidation) + // pending -> blocked [add to queue] (when invalidated from aggregated changes) + // done -> blocked [add to queue] (when invalidated, from parent invalidation) // running -> running-outdated (when invalidated, either from change or parent invalidation) // running-outdated -> blocked [running--] (when compilation is done) /** @type {Node[]} */ const nodes = this.compilers.map(compiler => ({ compiler, + setupResult: undefined, result: undefined, state: "blocked", children: [], @@ -341,16 +408,19 @@ module.exports = class MultiCompiler { })); /** @type {Map} */ const compilerToNode = new Map(); - for (const node of nodes) compilerToNode.set(node.compiler.name, node); + for (const node of nodes) { + compilerToNode.set(/** @type {string} */ (node.compiler.name), node); + } for (const node of nodes) { const dependencies = this.dependencies.get(node.compiler); if (!dependencies) continue; for (const dep of dependencies) { - const parent = compilerToNode.get(dep); + const parent = /** @type {Node} */ (compilerToNode.get(dep)); node.parents.push(parent); parent.children.push(node); } } + /** @type {ArrayQueue} */ const queue = new ArrayQueue(); for (const node of nodes) { if (node.parents.length === 0) { @@ -360,10 +430,10 @@ module.exports = class MultiCompiler { } let errored = false; let running = 0; - const parallelism = this._options.parallelism; + const parallelism = /** @type {number} */ (this._options.parallelism); /** * @param {Node} node node - * @param {Error=} err error + * @param {(Error | null)=} err error * @param {Stats=} stats result * @returns {void} */ @@ -388,13 +458,13 @@ module.exports = class MultiCompiler { if (node.state === "running") { node.state = "done"; for (const child of node.children) { - checkUnblocked(child); + if (child.state === "blocked") queue.enqueue(child); } } else if (node.state === "running-outdated") { node.state = "blocked"; - checkUnblocked(node); + queue.enqueue(node); } - process.nextTick(processQueue); + processQueue(); }; /** * @param {Node} node node @@ -433,44 +503,52 @@ module.exports = class MultiCompiler { if (node.state === "pending") { node.state = "blocked"; } - checkUnblocked(node); - processQueue(); - }; - /** - * @param {Node} node node - * @returns {void} - */ - const checkUnblocked = node => { - if ( - node.state === "blocked" && - node.parents.every(p => p.state === "done") - ) { - node.state = "queued"; + if (node.state === "blocked") { queue.enqueue(node); + processQueue(); } }; + /** @type {SetupResult[]} */ const setupResults = []; - nodes.forEach((node, i) => { + for (const [i, node] of nodes.entries()) { setupResults.push( - setup( + (node.setupResult = setup( node.compiler, i, nodeDone.bind(null, node), - () => node.state !== "done" && node.state !== "running", + () => node.state !== "starting" && node.state !== "running", () => nodeChange(node), () => nodeInvalid(node) - ) + )) ); - }); + } + let processing = true; const processQueue = () => { + if (processing) return; + processing = true; + process.nextTick(processQueueWorker); + }; + const processQueueWorker = () => { + // eslint-disable-next-line no-unmodified-loop-condition while (running < parallelism && queue.length > 0 && !errored) { - const node = queue.dequeue(); - if (node.state !== "queued") continue; - running++; - node.state = "running"; - run(node.compiler, nodeDone.bind(null, node)); + const node = /** @type {Node} */ (queue.dequeue()); + if ( + node.state === "queued" || + (node.state === "blocked" && + node.parents.every(p => p.state === "done")) + ) { + running++; + node.state = "starting"; + run( + node.compiler, + /** @type {SetupResult} */ (node.setupResult), + nodeDone.bind(null, node) + ); + node.state = "running"; + } } + processing = false; if ( !errored && running === 0 && @@ -489,7 +567,7 @@ module.exports = class MultiCompiler { } } }; - processQueue(); + processQueueWorker(); return setupResults; } @@ -518,8 +596,9 @@ module.exports = class MultiCompiler { } return watching; }, - (compiler, initial, callback) => { - if (!compiler.watching.running) compiler.watching.invalidate(); + (compiler, watching, callback) => { + if (compiler.watching !== watching) return; + if (!watching.running) watching.invalidate(); }, handler ); @@ -542,7 +621,7 @@ module.exports = class MultiCompiler { if (this.validateDependencies(callback)) { this._runGraph( () => {}, - (compiler, callback) => compiler.run(callback), + (compiler, setupResult, callback) => compiler.run(callback), (err, stats) => { this.running = false; @@ -572,7 +651,9 @@ module.exports = class MultiCompiler { (compiler, callback) => { compiler.close(callback); }, - callback + error => { + callback(error); + } ); } }; diff --git a/lib/MultiStats.js b/lib/MultiStats.js index d236aef43f4..bf4771a5fef 100644 --- a/lib/MultiStats.js +++ b/lib/MultiStats.js @@ -8,15 +8,25 @@ const identifierUtils = require("./util/identifier"); /** @typedef {import("../declarations/WebpackOptions").StatsOptions} StatsOptions */ +/** @typedef {import("./Compilation").CreateStatsOptionsContext} CreateStatsOptionsContext */ +/** @typedef {import("./Compilation").NormalizedStatsOptions} NormalizedStatsOptions */ /** @typedef {import("./Stats")} Stats */ /** @typedef {import("./stats/DefaultStatsFactoryPlugin").KnownStatsCompilation} KnownStatsCompilation */ /** @typedef {import("./stats/DefaultStatsFactoryPlugin").StatsCompilation} StatsCompilation */ +/** @typedef {import("./stats/DefaultStatsFactoryPlugin").StatsError} StatsError */ +/** + * @param {string} str string + * @param {string} prefix pref + * @returns {string} indent + */ const indent = (str, prefix) => { - const rem = str.replace(/\n([^\n])/g, "\n" + prefix + "$1"); + const rem = str.replace(/\n([^\n])/g, `\n${prefix}$1`); return prefix + rem; }; +/** @typedef {{ version: boolean, hash: boolean, errorsCount: boolean, warningsCount: boolean, errors: boolean, warnings: boolean, children: NormalizedStatsOptions[] }} ChildOptions */ + class MultiStats { /** * @param {Stats[]} stats the child stats @@ -43,13 +53,30 @@ class MultiStats { return this.stats.some(stat => stat.hasWarnings()); } + /** + * @param {string | boolean | StatsOptions | undefined} options stats options + * @param {CreateStatsOptionsContext} context context + * @returns {ChildOptions} context context + */ _createChildOptions(options, context) { - if (!options) { - options = {}; - } - const { children: childrenOptions = undefined, ...baseOptions } = - typeof options === "string" ? { preset: options } : options; + const getCreateStatsOptions = () => { + if (!options) { + options = {}; + } + + const { children: childrenOptions = undefined, ...baseOptions } = + typeof options === "string" + ? { preset: options } + : /** @type {StatsOptions} */ (options); + + return { childrenOptions, baseOptions }; + }; + const children = this.stats.map((stat, idx) => { + if (typeof options === "boolean") { + return stat.compilation.createStatsOptions(options, context); + } + const { childrenOptions, baseOptions } = getCreateStatsOptions(); const childOptions = Array.isArray(childrenOptions) ? childrenOptions[idx] : childrenOptions; @@ -59,8 +86,8 @@ class MultiStats { ...(typeof childOptions === "string" ? { preset: childOptions } : childOptions && typeof childOptions === "object" - ? childOptions - : undefined) + ? childOptions + : undefined) }, context ); @@ -77,81 +104,96 @@ class MultiStats { } /** - * @param {any} options stats options + * @param {(string | boolean | StatsOptions)=} options stats options * @returns {StatsCompilation} json output */ toJson(options) { - options = this._createChildOptions(options, { forToString: false }); + const childOptions = this._createChildOptions(options, { + forToString: false + }); /** @type {KnownStatsCompilation} */ const obj = {}; obj.children = this.stats.map((stat, idx) => { - const obj = stat.toJson(options.children[idx]); + const obj = stat.toJson(childOptions.children[idx]); const compilationName = stat.compilation.name; const name = compilationName && identifierUtils.makePathsRelative( - options.context, + stat.compilation.compiler.context, compilationName, stat.compilation.compiler.root ); obj.name = name; return obj; }); - if (options.version) { + if (childOptions.version) { obj.version = obj.children[0].version; } - if (options.hash) { + if (childOptions.hash) { obj.hash = obj.children.map(j => j.hash).join(""); } - const mapError = (j, obj) => { - return { - ...obj, - compilerPath: obj.compilerPath - ? `${j.name}.${obj.compilerPath}` - : j.name - }; - }; - if (options.errors) { + /** + * @param {StatsCompilation} j stats error + * @param {StatsError} obj Stats error + * @returns {TODO} result + */ + const mapError = (j, obj) => ({ + ...obj, + compilerPath: obj.compilerPath ? `${j.name}.${obj.compilerPath}` : j.name + }); + if (childOptions.errors) { obj.errors = []; for (const j of obj.children) { - for (const i of j.errors) { + const errors = + /** @type {NonNullable} */ + (j.errors); + for (const i of errors) { obj.errors.push(mapError(j, i)); } } } - if (options.warnings) { + if (childOptions.warnings) { obj.warnings = []; for (const j of obj.children) { - for (const i of j.warnings) { + const warnings = + /** @type {NonNullable} */ + (j.warnings); + for (const i of warnings) { obj.warnings.push(mapError(j, i)); } } } - if (options.errorsCount) { + if (childOptions.errorsCount) { obj.errorsCount = 0; for (const j of obj.children) { - obj.errorsCount += j.errorsCount; + obj.errorsCount += /** @type {number} */ (j.errorsCount); } } - if (options.warningsCount) { + if (childOptions.warningsCount) { obj.warningsCount = 0; for (const j of obj.children) { - obj.warningsCount += j.warningsCount; + obj.warningsCount += /** @type {number} */ (j.warningsCount); } } return obj; } + /** + * @param {(string | boolean | StatsOptions)=} options stats options + * @returns {string} string output + */ toString(options) { - options = this._createChildOptions(options, { forToString: true }); + const childOptions = this._createChildOptions(options, { + forToString: true + }); const results = this.stats.map((stat, idx) => { - const str = stat.toString(options.children[idx]); + const str = stat.toString(childOptions.children[idx]); const compilationName = stat.compilation.name; const name = compilationName && identifierUtils .makePathsRelative( - options.context, + stat.compilation.compiler.context, compilationName, stat.compilation.compiler.root ) diff --git a/lib/MultiWatching.js b/lib/MultiWatching.js index 5314569c2c3..cfe95f17b28 100644 --- a/lib/MultiWatching.js +++ b/lib/MultiWatching.js @@ -13,7 +13,7 @@ const asyncLib = require("neo-async"); /** * @template T * @callback Callback - * @param {Error=} err + * @param {(Error | null)=} err * @param {T=} result */ @@ -27,6 +27,10 @@ class MultiWatching { this.compiler = compiler; } + /** + * @param {Callback=} callback signals when the build has completed again + * @returns {void} + */ invalidate(callback) { if (callback) { asyncLib.each( @@ -58,7 +62,7 @@ class MultiWatching { * @returns {void} */ close(callback) { - asyncLib.forEach( + asyncLib.each( this.watchings, (watching, finishedCallback) => { watching.close(finishedCallback); diff --git a/lib/NoModeWarning.js b/lib/NoModeWarning.js index 8a82f72f70e..fdd3fadf9c6 100644 --- a/lib/NoModeWarning.js +++ b/lib/NoModeWarning.js @@ -18,7 +18,5 @@ module.exports = class NoModeWarning extends WebpackError { "Set 'mode' option to 'development' or 'production' to enable defaults for each environment.\n" + "You can also set it to 'none' to disable any default behavior. " + "Learn more: https://webpack.js.org/configuration/mode/"; - - Error.captureStackTrace(this, this.constructor); } }; diff --git a/lib/NodeStuffInWebError.js b/lib/NodeStuffInWebError.js new file mode 100644 index 00000000000..02b048ec4fd --- /dev/null +++ b/lib/NodeStuffInWebError.js @@ -0,0 +1,34 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Ivan Kopeykin @vankop +*/ + +"use strict"; + +const WebpackError = require("./WebpackError"); +const makeSerializable = require("./util/makeSerializable"); + +/** @typedef {import("./Dependency").DependencyLocation} DependencyLocation */ + +class NodeStuffInWebError extends WebpackError { + /** + * @param {DependencyLocation} loc loc + * @param {string} expression expression + * @param {string} description description + */ + constructor(loc, expression, description) { + super( + `${JSON.stringify( + expression + )} has been used, it will be undefined in next major version. +${description}` + ); + + this.name = "NodeStuffInWebError"; + this.loc = loc; + } +} + +makeSerializable(NodeStuffInWebError, "webpack/lib/NodeStuffInWebError"); + +module.exports = NodeStuffInWebError; diff --git a/lib/NodeStuffPlugin.js b/lib/NodeStuffPlugin.js index 838b8ae4f9f..87a5cd61405 100644 --- a/lib/NodeStuffPlugin.js +++ b/lib/NodeStuffPlugin.js @@ -5,9 +5,15 @@ "use strict"; +const { + JAVASCRIPT_MODULE_TYPE_AUTO, + JAVASCRIPT_MODULE_TYPE_DYNAMIC +} = require("./ModuleTypeConstants"); +const NodeStuffInWebError = require("./NodeStuffInWebError"); const RuntimeGlobals = require("./RuntimeGlobals"); const CachedConstDependency = require("./dependencies/CachedConstDependency"); const ConstDependency = require("./dependencies/ConstDependency"); +const ExternalModuleDependency = require("./dependencies/ExternalModuleDependency"); const { evaluateToString, expressionIsUnsupported @@ -16,12 +22,24 @@ const { relative } = require("./util/fs"); const { parseResource } = require("./util/identifier"); /** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */ +/** @typedef {import("../declarations/WebpackOptions").JavascriptParserOptions} JavascriptParserOptions */ +/** @typedef {import("../declarations/WebpackOptions").NodeOptions} NodeOptions */ /** @typedef {import("./Compiler")} Compiler */ /** @typedef {import("./Dependency")} Dependency */ +/** @typedef {import("./Dependency").DependencyLocation} DependencyLocation */ /** @typedef {import("./DependencyTemplates")} DependencyTemplates */ +/** @typedef {import("./NormalModule")} NormalModule */ /** @typedef {import("./RuntimeTemplate")} RuntimeTemplate */ +/** @typedef {import("./javascript/JavascriptParser")} JavascriptParser */ +/** @typedef {import("./javascript/JavascriptParser").Range} Range */ +/** @typedef {import("./util/fs").InputFileSystem} InputFileSystem */ + +const PLUGIN_NAME = "NodeStuffPlugin"; class NodeStuffPlugin { + /** + * @param {NodeOptions} options options + */ constructor(options) { this.options = options; } @@ -34,8 +52,18 @@ class NodeStuffPlugin { apply(compiler) { const options = this.options; compiler.hooks.compilation.tap( - "NodeStuffPlugin", + PLUGIN_NAME, (compilation, { normalModuleFactory }) => { + compilation.dependencyTemplates.set( + ExternalModuleDependency, + new ExternalModuleDependency.Template() + ); + + /** + * @param {JavascriptParser} parser the parser + * @param {JavascriptParserOptions} parserOptions options + * @returns {void} + */ const handler = (parser, parserOptions) => { if (parserOptions.node === false) return; @@ -44,74 +72,188 @@ class NodeStuffPlugin { localOptions = { ...localOptions, ...parserOptions.node }; } - if (localOptions.global) { - parser.hooks.expression - .for("global") - .tap("NodeStuffPlugin", expr => { - const dep = new ConstDependency( - RuntimeGlobals.global, - expr.range, - [RuntimeGlobals.global] + if (localOptions.global !== false) { + const withWarning = localOptions.global === "warn"; + parser.hooks.expression.for("global").tap(PLUGIN_NAME, expr => { + const dep = new ConstDependency( + RuntimeGlobals.global, + /** @type {Range} */ (expr.range), + [RuntimeGlobals.global] + ); + dep.loc = /** @type {DependencyLocation} */ (expr.loc); + parser.state.module.addPresentationalDependency(dep); + + // TODO webpack 6 remove + if (withWarning) { + parser.state.module.addWarning( + new NodeStuffInWebError( + dep.loc, + "global", + "The global namespace object is a Node.js feature and isn't available in browsers." + ) ); - dep.loc = expr.loc; - parser.state.module.addPresentationalDependency(dep); - }); + } + }); + parser.hooks.rename.for("global").tap(PLUGIN_NAME, expr => { + const dep = new ConstDependency( + RuntimeGlobals.global, + /** @type {Range} */ (expr.range), + [RuntimeGlobals.global] + ); + dep.loc = /** @type {DependencyLocation} */ (expr.loc); + parser.state.module.addPresentationalDependency(dep); + return false; + }); } - const setModuleConstant = (expressionName, fn) => { + /** + * @param {string} expressionName expression name + * @param {(module: NormalModule) => string} fn function + * @param {string=} warning warning + * @returns {void} + */ + const setModuleConstant = (expressionName, fn, warning) => { parser.hooks.expression .for(expressionName) - .tap("NodeStuffPlugin", expr => { + .tap(PLUGIN_NAME, expr => { const dep = new CachedConstDependency( JSON.stringify(fn(parser.state.module)), - expr.range, + /** @type {Range} */ (expr.range), expressionName ); - dep.loc = expr.loc; + dep.loc = /** @type {DependencyLocation} */ (expr.loc); parser.state.module.addPresentationalDependency(dep); + + // TODO webpack 6 remove + if (warning) { + parser.state.module.addWarning( + new NodeStuffInWebError(dep.loc, expressionName, warning) + ); + } + return true; }); }; - const setConstant = (expressionName, value) => - setModuleConstant(expressionName, () => value); + /** + * @param {string} expressionName expression name + * @param {(value: string) => string} fn function + * @returns {void} + */ + const setUrlModuleConstant = (expressionName, fn) => { + parser.hooks.expression + .for(expressionName) + .tap(PLUGIN_NAME, expr => { + const dep = new ExternalModuleDependency( + "url", + [ + { + name: "fileURLToPath", + value: "__webpack_fileURLToPath__" + } + ], + undefined, + fn("__webpack_fileURLToPath__"), + /** @type {Range} */ (expr.range), + expressionName + ); + dep.loc = /** @type {DependencyLocation} */ (expr.loc); + parser.state.module.addPresentationalDependency(dep); + + return true; + }); + }; + + /** + * @param {string} expressionName expression name + * @param {string} value value + * @param {string=} warning warning + * @returns {void} + */ + const setConstant = (expressionName, value, warning) => + setModuleConstant(expressionName, () => value, warning); const context = compiler.context; if (localOptions.__filename) { - if (localOptions.__filename === "mock") { - setConstant("__filename", "/index.js"); - } else if (localOptions.__filename === true) { - setModuleConstant("__filename", module => - relative(compiler.inputFileSystem, context, module.resource) - ); + switch (localOptions.__filename) { + case "mock": + setConstant("__filename", "/index.js"); + break; + case "warn-mock": + setConstant( + "__filename", + "/index.js", + "__filename is a Node.js feature and isn't available in browsers." + ); + break; + case "node-module": + setUrlModuleConstant( + "__filename", + functionName => `${functionName}(import.meta.url)` + ); + break; + case true: + setModuleConstant("__filename", module => + relative( + /** @type {InputFileSystem} */ (compiler.inputFileSystem), + context, + module.resource + ) + ); + break; } + parser.hooks.evaluateIdentifier .for("__filename") - .tap("NodeStuffPlugin", expr => { + .tap(PLUGIN_NAME, expr => { if (!parser.state.module) return; const resource = parseResource(parser.state.module.resource); return evaluateToString(resource.path)(expr); }); } if (localOptions.__dirname) { - if (localOptions.__dirname === "mock") { - setConstant("__dirname", "/"); - } else if (localOptions.__dirname === true) { - setModuleConstant("__dirname", module => - relative(compiler.inputFileSystem, context, module.context) - ); + switch (localOptions.__dirname) { + case "mock": + setConstant("__dirname", "/"); + break; + case "warn-mock": + setConstant( + "__dirname", + "/", + "__dirname is a Node.js feature and isn't available in browsers." + ); + break; + case "node-module": + setUrlModuleConstant( + "__dirname", + functionName => + `${functionName}(import.meta.url + "/..").slice(0, -1)` + ); + break; + case true: + setModuleConstant("__dirname", module => + relative( + /** @type {InputFileSystem} */ (compiler.inputFileSystem), + context, + /** @type {string} */ (module.context) + ) + ); + break; } + parser.hooks.evaluateIdentifier .for("__dirname") - .tap("NodeStuffPlugin", expr => { + .tap(PLUGIN_NAME, expr => { if (!parser.state.module) return; - return evaluateToString(parser.state.module.context)(expr); + return evaluateToString( + /** @type {string} */ (parser.state.module.context) + )(expr); }); } parser.hooks.expression .for("require.extensions") .tap( - "NodeStuffPlugin", + PLUGIN_NAME, expressionIsUnsupported( parser, "require.extensions is not supported by webpack. Use a loader instead." @@ -120,11 +262,11 @@ class NodeStuffPlugin { }; normalModuleFactory.hooks.parser - .for("javascript/auto") - .tap("NodeStuffPlugin", handler); + .for(JAVASCRIPT_MODULE_TYPE_AUTO) + .tap(PLUGIN_NAME, handler); normalModuleFactory.hooks.parser - .for("javascript/dynamic") - .tap("NodeStuffPlugin", handler); + .for(JAVASCRIPT_MODULE_TYPE_DYNAMIC) + .tap(PLUGIN_NAME, handler); } ); } diff --git a/lib/NormalModule.js b/lib/NormalModule.js index 767637596c7..eea12c9359d 100644 --- a/lib/NormalModule.js +++ b/lib/NormalModule.js @@ -5,10 +5,9 @@ "use strict"; -const parseJson = require("json-parse-better-errors"); +const parseJson = require("json-parse-even-better-errors"); const { getContext, runLoaders } = require("loader-runner"); const querystring = require("querystring"); -const { validate } = require("schema-utils"); const { HookMap, SyncHook, AsyncSeriesBailHook } = require("tapable"); const { CachedSource, @@ -17,17 +16,20 @@ const { SourceMapSource } = require("webpack-sources"); const Compilation = require("./Compilation"); +const HookWebpackError = require("./HookWebpackError"); const Module = require("./Module"); const ModuleBuildError = require("./ModuleBuildError"); const ModuleError = require("./ModuleError"); const ModuleGraphConnection = require("./ModuleGraphConnection"); const ModuleParseError = require("./ModuleParseError"); +const { JAVASCRIPT_MODULE_TYPE_AUTO } = require("./ModuleTypeConstants"); const ModuleWarning = require("./ModuleWarning"); const RuntimeGlobals = require("./RuntimeGlobals"); const UnhandledSchemeError = require("./UnhandledSchemeError"); const WebpackError = require("./WebpackError"); const formatLocation = require("./formatLocation"); const LazySet = require("./util/LazySet"); +const { isSubset } = require("./util/SetHelpers"); const { getScheme } = require("./util/URLAbsoluteSpecifier"); const { compareLocations, @@ -36,42 +38,91 @@ const { keepOriginalOrder } = require("./util/comparators"); const createHash = require("./util/createHash"); +const { createFakeHook } = require("./util/deprecation"); const { join } = require("./util/fs"); -const { contextify, absolutify } = require("./util/identifier"); +const { + contextify, + absolutify, + makePathsRelative +} = require("./util/identifier"); const makeSerializable = require("./util/makeSerializable"); const memoize = require("./util/memoize"); -/** @typedef {import("source-map").RawSourceMap} SourceMap */ /** @typedef {import("webpack-sources").Source} Source */ +/** @typedef {import("../declarations/WebpackOptions").Mode} Mode */ +/** @typedef {import("../declarations/WebpackOptions").ResolveOptions} ResolveOptions */ /** @typedef {import("../declarations/WebpackOptions").WebpackOptionsNormalized} WebpackOptions */ /** @typedef {import("./ChunkGraph")} ChunkGraph */ +/** @typedef {import("./Compiler")} Compiler */ /** @typedef {import("./Dependency").UpdateHashContext} UpdateHashContext */ /** @typedef {import("./DependencyTemplates")} DependencyTemplates */ /** @typedef {import("./Generator")} Generator */ +/** @typedef {import("./Module").BuildInfo} BuildInfo */ +/** @typedef {import("./Module").BuildMeta} BuildMeta */ /** @typedef {import("./Module").CodeGenerationContext} CodeGenerationContext */ /** @typedef {import("./Module").CodeGenerationResult} CodeGenerationResult */ /** @typedef {import("./Module").ConcatenationBailoutReasonContext} ConcatenationBailoutReasonContext */ +/** @typedef {import("./Module").KnownBuildInfo} KnownBuildInfo */ /** @typedef {import("./Module").LibIdentOptions} LibIdentOptions */ /** @typedef {import("./Module").NeedBuildContext} NeedBuildContext */ +/** @typedef {import("./Module").SourceTypes} SourceTypes */ +/** @typedef {import("./Module").UnsafeCacheData} UnsafeCacheData */ /** @typedef {import("./ModuleGraph")} ModuleGraph */ /** @typedef {import("./ModuleGraphConnection").ConnectionState} ConnectionState */ +/** @typedef {import("./ModuleTypeConstants").JavaScriptModuleTypes} JavaScriptModuleTypes */ /** @typedef {import("./NormalModuleFactory")} NormalModuleFactory */ /** @typedef {import("./Parser")} Parser */ /** @typedef {import("./RequestShortener")} RequestShortener */ +/** @typedef {import("./ResolverFactory").ResolveContext} ResolveContext */ /** @typedef {import("./ResolverFactory").ResolverWithOptions} ResolverWithOptions */ /** @typedef {import("./RuntimeTemplate")} RuntimeTemplate */ +/** @typedef {import("./logging/Logger").Logger} WebpackLogger */ +/** @typedef {import("./serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */ +/** @typedef {import("./serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */ /** @typedef {import("./util/Hash")} Hash */ /** @typedef {import("./util/fs").InputFileSystem} InputFileSystem */ /** @typedef {import("./util/runtime").RuntimeSpec} RuntimeSpec */ +/** @typedef {import("./util/createHash").Algorithm} Algorithm */ +/** + * @template T + * @typedef {import("./util/deprecation").FakeHook} FakeHook + */ + +/** @typedef {{[k: string]: any}} ParserOptions */ +/** @typedef {{[k: string]: any}} GeneratorOptions */ + +/** @typedef {UnsafeCacheData & { parser: undefined | Parser, parserOptions: undefined | ParserOptions, generator: undefined | Generator, generatorOptions: undefined | GeneratorOptions }} NormalModuleUnsafeCacheData */ + +/** + * @template T + * @typedef {import("../declarations/LoaderContext").LoaderContext} LoaderContext + */ + +/** + * @template T + * @typedef {import("../declarations/LoaderContext").NormalModuleLoaderContext} NormalModuleLoaderContext + */ + +/** + * @typedef {object} SourceMap + * @property {number} version + * @property {string[]} sources + * @property {string} mappings + * @property {string=} file + * @property {string=} sourceRoot + * @property {string[]=} sourcesContent + * @property {string[]=} names + */ const getInvalidDependenciesModuleWarning = memoize(() => require("./InvalidDependenciesModuleWarning") ); +const getValidate = memoize(() => require("schema-utils").validate); const ABSOLUTE_PATH_REGEX = /^([a-zA-Z]:\\|\\\\|\/)/; /** - * @typedef {Object} LoaderItem + * @typedef {object} LoaderItem * @property {string} loader * @property {any} options * @property {string?} ident @@ -81,18 +132,22 @@ const ABSOLUTE_PATH_REGEX = /^([a-zA-Z]:\\|\\\\|\/)/; /** * @param {string} context absolute context path * @param {string} source a source path - * @param {Object=} associatedObjectForCache an object to which the cache will be attached + * @param {object=} associatedObjectForCache an object to which the cache will be attached * @returns {string} new source path */ const contextifySourceUrl = (context, source, associatedObjectForCache) => { if (source.startsWith("webpack://")) return source; - return `webpack://${contextify(context, source, associatedObjectForCache)}`; + return `webpack://${makePathsRelative( + context, + source, + associatedObjectForCache + )}`; }; /** * @param {string} context absolute context path * @param {SourceMap} sourceMap a source map - * @param {Object=} associatedObjectForCache an object to which the cache will be attached + * @param {object=} associatedObjectForCache an object to which the cache will be attached * @returns {SourceMap} new source map */ const contextifySourceMap = (context, sourceMap, associatedObjectForCache) => { @@ -102,14 +157,14 @@ const contextifySourceMap = (context, sourceMap, associatedObjectForCache) => { const mapper = !sourceRoot ? source => source : sourceRoot.endsWith("/") - ? source => - source.startsWith("/") - ? `${sourceRoot.slice(0, -1)}${source}` - : `${sourceRoot}${source}` - : source => - source.startsWith("/") - ? `${sourceRoot}${source}` - : `${sourceRoot}/${source}`; + ? source => + source.startsWith("/") + ? `${sourceRoot.slice(0, -1)}${source}` + : `${sourceRoot}${source}` + : source => + source.startsWith("/") + ? `${sourceRoot}${source}` + : `${sourceRoot}/${source}`; const newSources = sourceMap.sources.map(source => contextifySourceUrl(context, mapper(source), associatedObjectForCache) ); @@ -144,13 +199,14 @@ const asBuffer = input => { }; class NonErrorEmittedError extends WebpackError { + /** + * @param {any} error value which is not an instance of Error + */ constructor(error) { super(); this.name = "NonErrorEmittedError"; - this.message = "(Emitted value instead of an instance of Error) " + error; - - Error.captureStackTrace(this, this.constructor); + this.message = `(Emitted value instead of an instance of Error) ${error}`; } } @@ -161,10 +217,33 @@ makeSerializable( ); /** - * @typedef {Object} NormalModuleCompilationHooks - * @property {SyncHook<[object, NormalModule]>} loader - * @property {SyncHook<[LoaderItem[], NormalModule, object]>} beforeLoaders - * @property {HookMap>} readResourceForScheme + * @typedef {object} NormalModuleCompilationHooks + * @property {SyncHook<[LoaderContext, NormalModule]>} loader + * @property {SyncHook<[LoaderItem[], NormalModule, LoaderContext]>} beforeLoaders + * @property {SyncHook<[NormalModule]>} beforeParse + * @property {SyncHook<[NormalModule]>} beforeSnapshot + * @property {HookMap>>} readResourceForScheme + * @property {HookMap], string | Buffer | null>>} readResource + * @property {AsyncSeriesBailHook<[NormalModule, NeedBuildContext], boolean>} needBuild + */ + +/** + * @typedef {object} NormalModuleCreateData + * @property {string=} layer an optional layer in which the module is + * @property {JavaScriptModuleTypes | ""} type module type. When deserializing, this is set to an empty string "". + * @property {string} request request string + * @property {string} userRequest request intended by user (without loaders from config) + * @property {string} rawRequest request without resolving + * @property {LoaderItem[]} loaders list of loaders + * @property {string} resource path + query of the real resource + * @property {Record=} resourceResolveData resource resolve data + * @property {string} context context directory for resolving + * @property {string=} matchResource path + query of the matched resource (virtual) + * @property {Parser} parser the parser used + * @property {ParserOptions=} parserOptions the options of the parser used + * @property {Generator} generator the generator used + * @property {GeneratorOptions=} generatorOptions the options of the generator used + * @property {ResolveOptions=} resolveOptions options used for resolving requests from this module */ /** @type {WeakMap} */ @@ -186,30 +265,55 @@ class NormalModule extends Module { hooks = { loader: new SyncHook(["loaderContext", "module"]), beforeLoaders: new SyncHook(["loaders", "module", "loaderContext"]), - readResourceForScheme: new HookMap( - () => new AsyncSeriesBailHook(["resource", "module"]) - ) + beforeParse: new SyncHook(["module"]), + beforeSnapshot: new SyncHook(["module"]), + // TODO webpack 6 deprecate + readResourceForScheme: new HookMap(scheme => { + const hook = + /** @type {NormalModuleCompilationHooks} */ + (hooks).readResource.for(scheme); + return createFakeHook( + /** @type {AsyncSeriesBailHook<[string, NormalModule], string | Buffer | null>} */ ({ + tap: (options, fn) => + hook.tap(options, loaderContext => + fn( + loaderContext.resource, + /** @type {NormalModule} */ (loaderContext._module) + ) + ), + tapAsync: (options, fn) => + hook.tapAsync(options, (loaderContext, callback) => + fn( + loaderContext.resource, + /** @type {NormalModule} */ (loaderContext._module), + callback + ) + ), + tapPromise: (options, fn) => + hook.tapPromise(options, loaderContext => + fn( + loaderContext.resource, + /** @type {NormalModule} */ (loaderContext._module) + ) + ) + }) + ); + }), + readResource: new HookMap( + () => new AsyncSeriesBailHook(["loaderContext"]) + ), + needBuild: new AsyncSeriesBailHook(["module", "context"]) }; - compilationHooksMap.set(compilation, hooks); + compilationHooksMap.set( + compilation, + /** @type {NormalModuleCompilationHooks} */ (hooks) + ); } - return hooks; + return /** @type {NormalModuleCompilationHooks} */ (hooks); } /** - * @param {Object} options options object - * @param {string=} options.layer an optional layer in which the module is - * @param {string} options.type module type - * @param {string} options.request request string - * @param {string} options.userRequest request intended by user (without loaders from config) - * @param {string} options.rawRequest request without resolving - * @param {LoaderItem[]} options.loaders list of loaders - * @param {string} options.resource path + query of the real resource - * @param {string | undefined} options.matchResource path + query of the matched resource (virtual) - * @param {Parser} options.parser the parser used - * @param {object} options.parserOptions the options of the parser used - * @param {Generator} options.generator the generator used - * @param {object} options.generatorOptions the options of the generator used - * @param {Object} options.resolveOptions options used for resolving requests from this module + * @param {NormalModuleCreateData} options options object */ constructor({ layer, @@ -219,6 +323,8 @@ class NormalModule extends Module { rawRequest, loaders, resource, + resourceResolveData, + context, matchResource, parser, parserOptions, @@ -226,7 +332,7 @@ class NormalModule extends Module { generatorOptions, resolveOptions }) { - super(type, getContext(resource), layer); + super(type, context || getContext(resource), layer); // Info from Factory /** @type {string} */ @@ -237,14 +343,17 @@ class NormalModule extends Module { this.rawRequest = rawRequest; /** @type {boolean} */ this.binary = /^(asset|webassembly)\b/.test(type); - /** @type {Parser} */ + /** @type {undefined | Parser} */ this.parser = parser; + /** @type {undefined | ParserOptions} */ this.parserOptions = parserOptions; - /** @type {Generator} */ + /** @type {undefined | Generator} */ this.generator = generator; + /** @type {undefined | GeneratorOptions} */ this.generatorOptions = generatorOptions; /** @type {string} */ this.resource = resource; + this.resourceResolveData = resourceResolveData; /** @type {string | undefined} */ this.matchResource = matchResource; /** @type {LoaderItem[]} */ @@ -255,12 +364,23 @@ class NormalModule extends Module { } // Info from Build - /** @type {WebpackError=} */ + /** @type {WebpackError | null} */ this.error = null; - /** @private @type {Source=} */ + /** + * @private + * @type {Source | null} + */ this._source = null; - /** @private @type {Map | undefined} **/ + /** + * @private + * @type {Map | undefined} + */ this._sourceSizes = undefined; + /** + * @private + * @type {undefined | SourceTypes} + */ + this._sourceTypes = undefined; // Cache this._lastSuccessfulBuildMeta = {}; @@ -268,6 +388,8 @@ class NormalModule extends Module { this._isEvaluatingSideEffects = false; /** @type {WeakSet | undefined} */ this._addedSideEffectsBailout = undefined; + /** @type {Map} */ + this._codeGeneratorData = new Map(); } /** @@ -275,10 +397,12 @@ class NormalModule extends Module { */ identifier() { if (this.layer === null) { - return this.request; - } else { - return `${this.request}|${this.layer}`; + if (this.type === JAVASCRIPT_MODULE_TYPE_AUTO) { + return this.request; + } + return `${this.type}|${this.request}`; } + return `${this.type}|${this.request}|${this.layer}`; } /** @@ -286,7 +410,7 @@ class NormalModule extends Module { * @returns {string} a user readable identifier of the module */ readableIdentifier(requestShortener) { - return requestShortener.shorten(this.userRequest); + return /** @type {string} */ (requestShortener.shorten(this.userRequest)); } /** @@ -294,11 +418,13 @@ class NormalModule extends Module { * @returns {string | null} an identifier for library inclusion */ libIdent(options) { - return contextify( + let ident = contextify( options.context, this.userRequest, options.associatedObjectForCache ); + if (this.layer) ident = `(${this.layer})/${ident}`; + return ident; } /** @@ -307,7 +433,7 @@ class NormalModule extends Module { nameForCondition() { const resource = this.matchResource || this.resource; const idx = resource.indexOf("?"); - if (idx >= 0) return resource.substr(0, idx); + if (idx >= 0) return resource.slice(0, idx); return resource; } @@ -330,6 +456,8 @@ class NormalModule extends Module { this.generator = m.generator; this.generatorOptions = m.generatorOptions; this.resource = m.resource; + this.resourceResolveData = m.resourceResolveData; + this.context = m.context; this.matchResource = m.matchResource; this.loaders = m.loaders; } @@ -338,6 +466,15 @@ class NormalModule extends Module { * Assuming this module is in the cache. Remove internal references to allow freeing some memory. */ cleanupForCache() { + // Make sure to cache types and sizes before cleanup when this module has been built + // They are accessed by the stats and we don't want them to crash after cleanup + // TODO reconsider this for webpack 6 + if (this.buildInfo) { + if (this._sourceTypes === undefined) this.getSourceTypes(); + for (const type of /** @type {SourceTypes} */ (this._sourceTypes)) { + this.size(type); + } + } super.cleanupForCache(); this.parser = undefined; this.parserOptions = undefined; @@ -348,15 +485,22 @@ class NormalModule extends Module { /** * Module should be unsafe cached. Get data that's needed for that. * This data will be passed to restoreFromUnsafeCache later. - * @returns {object} cached data + * @returns {UnsafeCacheData} cached data */ getUnsafeCacheData() { - const data = super.getUnsafeCacheData(); + const data = + /** @type {NormalModuleUnsafeCacheData} */ + (super.getUnsafeCacheData()); data.parserOptions = this.parserOptions; data.generatorOptions = this.generatorOptions; return data; } + /** + * restore unsafe cache data + * @param {NormalModuleUnsafeCacheData} unsafeCacheData data from getUnsafeCacheData + * @param {NormalModuleFactory} normalModuleFactory the normal module factory handling the unsafe caching + */ restoreFromUnsafeCache(unsafeCacheData, normalModuleFactory) { this._restoreFromUnsafeCache(unsafeCacheData, normalModuleFactory); } @@ -367,6 +511,7 @@ class NormalModule extends Module { * @param {NormalModuleFactory} normalModuleFactory the normal module factory handling the unsafe caching */ _restoreFromUnsafeCache(unsafeCacheData, normalModuleFactory) { + super._restoreFromUnsafeCache(unsafeCacheData, normalModuleFactory); this.parserOptions = unsafeCacheData.parserOptions; this.parser = normalModuleFactory.getParser(this.type, this.parserOptions); this.generatorOptions = unsafeCacheData.generatorOptions; @@ -374,14 +519,15 @@ class NormalModule extends Module { this.type, this.generatorOptions ); + // we assume the generator behaves identically and keep cached sourceTypes/Sizes } /** * @param {string} context the compilation context * @param {string} name the asset name - * @param {string} content the content - * @param {string | TODO} sourceMap an optional source map - * @param {Object=} associatedObjectForCache object for caching + * @param {string | Buffer} content the content + * @param {(string | SourceMap)=} sourceMap an optional source map + * @param {object=} associatedObjectForCache object for caching * @returns {Source} the created source */ createSourceForAsset( @@ -406,7 +552,11 @@ class NormalModule extends Module { return new SourceMapSource( content, name, - contextifySourceMap(context, sourceMap, associatedObjectForCache) + contextifySourceMap( + context, + /** @type {SourceMap} */ (sourceMap), + associatedObjectForCache + ) ); } } @@ -415,69 +565,102 @@ class NormalModule extends Module { } /** + * @private + * @template T * @param {ResolverWithOptions} resolver a resolver * @param {WebpackOptions} options webpack options * @param {Compilation} compilation the compilation * @param {InputFileSystem} fs file system from reading - * @returns {any} loader context + * @param {NormalModuleCompilationHooks} hooks the hooks + * @returns {import("../declarations/LoaderContext").NormalModuleLoaderContext} loader context */ - createLoaderContext(resolver, options, compilation, fs) { + _createLoaderContext(resolver, options, compilation, fs, hooks) { const { requestShortener } = compilation.runtimeTemplate; const getCurrentLoaderName = () => { const currentLoader = this.getCurrentLoader(loaderContext); if (!currentLoader) return "(not in loader scope)"; return requestShortener.shorten(currentLoader.loader); }; - const getResolveContext = () => { - return { - fileDependencies: { - add: d => loaderContext.addDependency(d) - }, - contextDependencies: { - add: d => loaderContext.addContextDependency(d) - }, - missingDependencies: { - add: d => loaderContext.addMissingDependency(d) - } - }; - }; + /** + * @returns {ResolveContext} resolve context + */ + const getResolveContext = () => ({ + fileDependencies: { + add: d => /** @type {TODO} */ (loaderContext).addDependency(d) + }, + contextDependencies: { + add: d => /** @type {TODO} */ (loaderContext).addContextDependency(d) + }, + missingDependencies: { + add: d => /** @type {TODO} */ (loaderContext).addMissingDependency(d) + } + }); const getAbsolutify = memoize(() => absolutify.bindCache(compilation.compiler.root) ); const getAbsolutifyInContext = memoize(() => - absolutify.bindContextCache(this.context, compilation.compiler.root) + absolutify.bindContextCache( + /** @type {string} */ + (this.context), + compilation.compiler.root + ) ); const getContextify = memoize(() => contextify.bindCache(compilation.compiler.root) ); const getContextifyInContext = memoize(() => - contextify.bindContextCache(this.context, compilation.compiler.root) + contextify.bindContextCache( + /** @type {string} */ + (this.context), + compilation.compiler.root + ) ); const utils = { - absolutify: (context, request) => { - return context === this.context + /** + * @param {string} context context + * @param {string} request request + * @returns {string} result + */ + absolutify: (context, request) => + context === this.context ? getAbsolutifyInContext()(request) - : getAbsolutify()(context, request); - }, - contextify: (context, request) => { - return context === this.context + : getAbsolutify()(context, request), + /** + * @param {string} context context + * @param {string} request request + * @returns {string} result + */ + contextify: (context, request) => + context === this.context ? getContextifyInContext()(request) - : getContextify()(context, request); - } + : getContextify()(context, request), + /** + * @param {(string | typeof import("./util/Hash"))=} type type + * @returns {Hash} hash + */ + createHash: type => + createHash( + type || + /** @type {Algorithm} */ + (compilation.outputOptions.hashFunction) + ) }; + /** @type {import("../declarations/LoaderContext").NormalModuleLoaderContext} */ const loaderContext = { version: 2, getOptions: schema => { const loader = this.getCurrentLoader(loaderContext); - let { options } = loader; + let { options } = /** @type {LoaderItem} */ (loader); if (typeof options === "string") { - if (options.substr(0, 1) === "{" && options.substr(-1) === "}") { + if (options.startsWith("{") && options.endsWith("}")) { try { options = parseJson(options); - } catch (e) { - throw new Error(`Cannot parse string options: ${e.message}`); + } catch (err) { + throw new Error( + `Cannot parse string options: ${/** @type {Error} */ (err).message}` + ); } } else { options = querystring.parse(options, "&", "=", { @@ -497,7 +680,7 @@ class NormalModule extends Module { if (schema.title && (match = /^(.+) (.+)$/.exec(schema.title))) { [, name, baseDataPath] = match; } - validate(schema, options, { + getValidate()(schema, options, { name, baseDataPath }); @@ -558,46 +741,61 @@ class NormalModule extends Module { }; }, emitFile: (name, content, sourceMap, assetInfo) => { - if (!this.buildInfo.assets) { - this.buildInfo.assets = Object.create(null); - this.buildInfo.assetsInfo = new Map(); + const buildInfo = /** @type {BuildInfo} */ (this.buildInfo); + + if (!buildInfo.assets) { + buildInfo.assets = Object.create(null); + buildInfo.assetsInfo = new Map(); } - this.buildInfo.assets[name] = this.createSourceForAsset( - options.context, + + const assets = + /** @type {NonNullable} */ + (buildInfo.assets); + const assetsInfo = + /** @type {NonNullable} */ + (buildInfo.assetsInfo); + + assets[name] = this.createSourceForAsset( + /** @type {string} */ (options.context), name, content, sourceMap, compilation.compiler.root ); - this.buildInfo.assetsInfo.set(name, assetInfo); + assetsInfo.set(name, assetInfo); }, addBuildDependency: dep => { - if (this.buildInfo.buildDependencies === undefined) { - this.buildInfo.buildDependencies = new LazySet(); + const buildInfo = /** @type {BuildInfo} */ (this.buildInfo); + + if (buildInfo.buildDependencies === undefined) { + buildInfo.buildDependencies = new LazySet(); } - this.buildInfo.buildDependencies.add(dep); + buildInfo.buildDependencies.add(dep); }, utils, - rootContext: options.context, + rootContext: /** @type {string} */ (options.context), webpack: true, - sourceMap: !!this.useSourceMap, + sourceMap: Boolean(this.useSourceMap), mode: options.mode || "production", _module: this, _compilation: compilation, _compiler: compilation.compiler, - fs: fs + fs }; Object.assign(loaderContext, options.loader); - NormalModule.getCompilationHooks(compilation).loader.call( - loaderContext, - this - ); + hooks.loader.call(/** @type {LoaderContext} */ (loaderContext), this); return loaderContext; } + // TODO remove `loaderContext` in webpack@6 + /** + * @param {TODO} loaderContext loader context + * @param {number} index index + * @returns {LoaderItem | null} loader + */ getCurrentLoader(loaderContext, index = loaderContext.loaderIndex) { if ( this.loaders && @@ -614,8 +812,8 @@ class NormalModule extends Module { /** * @param {string} context the compilation context * @param {string | Buffer} content the content - * @param {string | TODO} sourceMap an optional source map - * @param {Object=} associatedObjectForCache object for caching + * @param {(string | SourceMapSource | null)=} sourceMap an optional source map + * @param {object=} associatedObjectForCache object for caching * @returns {Source} the created source */ createSource(context, content, sourceMap, associatedObjectForCache) { @@ -635,7 +833,11 @@ class NormalModule extends Module { return new SourceMapSource( content, contextifySourceUrl(context, identifier, associatedObjectForCache), - contextifySourceMap(context, sourceMap, associatedObjectForCache) + contextifySourceMap( + context, + /** @type {TODO} */ (sourceMap), + associatedObjectForCache + ) ); } @@ -654,18 +856,27 @@ class NormalModule extends Module { * @param {Compilation} compilation the compilation * @param {ResolverWithOptions} resolver the resolver * @param {InputFileSystem} fs the file system - * @param {function(WebpackError=): void} callback callback function + * @param {NormalModuleCompilationHooks} hooks the hooks + * @param {function((WebpackError | null)=): void} callback callback function * @returns {void} */ - doBuild(options, compilation, resolver, fs, callback) { - const loaderContext = this.createLoaderContext( + _doBuild(options, compilation, resolver, fs, hooks, callback) { + const loaderContext = this._createLoaderContext( resolver, options, compilation, - fs + fs, + hooks ); - const processResult = (err, result) => { + /** @typedef {[string | Buffer, string | SourceMapSource, Record]} Result */ + + /** + * @param {Error | null} err err + * @param {(Result | null)=} _result result + * @returns {void} + */ + const processResult = (err, _result) => { if (err) { if (!(err instanceof Error)) { err = new NonErrorEmittedError(err); @@ -681,6 +892,7 @@ class NormalModule extends Module { return callback(error); } + const result = /** @type {Result} */ (_result); const source = result[0]; const sourceMap = result.length >= 1 ? result[1] : null; const extraInfo = result.length >= 2 ? result[2] : null; @@ -692,7 +904,7 @@ class NormalModule extends Module { currentLoader ? compilation.runtimeTemplate.requestShortener.shorten( currentLoader.loader - ) + ) : "unknown" }) didn't return a Buffer or String` ); @@ -700,9 +912,14 @@ class NormalModule extends Module { return callback(error); } + const isBinaryModule = + this.generatorOptions && this.generatorOptions.binary !== undefined + ? this.generatorOptions.binary + : this.binary; + this._source = this.createSource( - options.context, - this.binary ? asBuffer(source) : asString(source), + /** @type {string} */ (options.context), + isBinaryModule ? asBuffer(source) : asString(source), sourceMap, compilation.compiler.root ); @@ -716,60 +933,96 @@ class NormalModule extends Module { return callback(); }; - const hooks = NormalModule.getCompilationHooks(compilation); + const buildInfo = /** @type {BuildInfo} */ (this.buildInfo); + + buildInfo.fileDependencies = new LazySet(); + buildInfo.contextDependencies = new LazySet(); + buildInfo.missingDependencies = new LazySet(); + buildInfo.cacheable = true; try { - hooks.beforeLoaders.call(this.loaders, this, loaderContext); + hooks.beforeLoaders.call( + this.loaders, + this, + /** @type {LoaderContext} */ (loaderContext) + ); } catch (err) { processResult(err); return; } + + if (this.loaders.length > 0) { + /** @type {BuildInfo} */ + (this.buildInfo).buildDependencies = new LazySet(); + } + runLoaders( { resource: this.resource, loaders: this.loaders, context: loaderContext, - processResource: (loaderContext, resource, callback) => { + processResource: (loaderContext, resourcePath, callback) => { + const resource = loaderContext.resource; const scheme = getScheme(resource); - if (scheme) { - hooks.readResourceForScheme - .for(scheme) - .callAsync(resource, this, (err, result) => { - if (err) return callback(err); - if (typeof result !== "string" && !result) { - return callback(new UnhandledSchemeError(scheme, resource)); - } - return callback(null, result); - }); - } else { - loaderContext.addDependency(resource); - fs.readFile(resource, callback); - } + hooks.readResource + .for(scheme) + .callAsync(loaderContext, (err, result) => { + if (err) return callback(err); + if (typeof result !== "string" && !result) { + return callback( + new UnhandledSchemeError( + /** @type {string} */ + (scheme), + resource + ) + ); + } + return callback(null, result); + }); } }, (err, result) => { + // Cleanup loaderContext to avoid leaking memory in ICs + loaderContext._compilation = + loaderContext._compiler = + loaderContext._module = + // eslint-disable-next-line no-warning-comments + // @ts-ignore + loaderContext.fs = + undefined; + if (!result) { + /** @type {BuildInfo} */ + (this.buildInfo).cacheable = false; return processResult( err || new Error("No result from loader-runner processing"), null ); } - this.buildInfo.fileDependencies = new LazySet(); - this.buildInfo.fileDependencies.addAll(result.fileDependencies); - this.buildInfo.contextDependencies = new LazySet(); - this.buildInfo.contextDependencies.addAll(result.contextDependencies); - this.buildInfo.missingDependencies = new LazySet(); - this.buildInfo.missingDependencies.addAll(result.missingDependencies); - if ( - this.loaders.length > 0 && - this.buildInfo.buildDependencies === undefined - ) { - this.buildInfo.buildDependencies = new LazySet(); - } + + const buildInfo = /** @type {BuildInfo} */ (this.buildInfo); + + const fileDependencies = + /** @type {NonNullable} */ + (buildInfo.fileDependencies); + const contextDependencies = + /** @type {NonNullable} */ + (buildInfo.contextDependencies); + const missingDependencies = + /** @type {NonNullable} */ + (buildInfo.missingDependencies); + + fileDependencies.addAll(result.fileDependencies); + contextDependencies.addAll(result.contextDependencies); + missingDependencies.addAll(result.missingDependencies); for (const loader of this.loaders) { - this.buildInfo.buildDependencies.add(loader.loader); + const buildDependencies = + /** @type {NonNullable} */ + (buildInfo.buildDependencies); + + buildDependencies.add(loader.loader); } - this.buildInfo.cacheable = result.cacheable; + buildInfo.cacheable = buildInfo.cacheable && result.cacheable; processResult(err, result.result); } ); @@ -786,6 +1039,11 @@ class NormalModule extends Module { this.addError(error); } + /** + * @param {TODO} rule rule + * @param {string} content content + * @returns {boolean} result + */ applyNoParseRule(rule, content) { // must start with "rule" if rule is a string if (typeof rule === "string") { @@ -799,9 +1057,11 @@ class NormalModule extends Module { return rule.test(content); } - // check if module should not be parsed - // returns "true" if the module should !not! be parsed - // returns "false" if the module !must! be parsed + /** + * @param {TODO} noParseRule no parse rule + * @param {string} request request + * @returns {boolean} check if module should not be parsed, returns "true" if the module should !not! be parsed, returns "false" if the module !must! be parsed + */ shouldPreventParsing(noParseRule, request) { // if no noParseRule exists, return false // the module !must! be parsed. @@ -827,15 +1087,23 @@ class NormalModule extends Module { return false; } + /** + * @param {Compilation} compilation compilation + * @private + */ _initBuildHash(compilation) { - const hash = createHash(compilation.outputOptions.hashFunction); + const hash = createHash( + /** @type {Algorithm} */ + (compilation.outputOptions.hashFunction) + ); if (this._source) { hash.update("source"); this._source.updateHash(hash); } hash.update("meta"); hash.update(JSON.stringify(this.buildMeta)); - this.buildInfo.hash = /** @type {string} */ (hash.digest("hex")); + /** @type {BuildInfo} */ + (this.buildInfo).hash = /** @type {string} */ (hash.digest("hex")); } /** @@ -850,6 +1118,7 @@ class NormalModule extends Module { this._forceBuild = false; this._source = null; if (this._sourceSizes !== undefined) this._sourceSizes.clear(); + this._sourceTypes = undefined; this._ast = null; this.error = null; this.clearWarningsAndErrors(); @@ -868,9 +1137,11 @@ class NormalModule extends Module { assetsInfo: undefined }; - const startTime = Date.now(); + const startTime = compilation.compiler.fsStartTime || Date.now(); + + const hooks = NormalModule.getCompilationHooks(compilation); - return this.doBuild(options, compilation, resolver, fs, err => { + return this._doBuild(options, compilation, resolver, fs, hooks, err => { // if we have an error mark module as failed and exit if (err) { this.markModuleAsErrored(err); @@ -878,10 +1149,18 @@ class NormalModule extends Module { return callback(); } + /** + * @param {Error} e error + * @returns {void} + */ const handleParseError = e => { - const source = this._source.source(); + const source = /** @type {Source} */ (this._source).source(); const loaders = this.loaders.map(item => - contextify(options.context, item.loader, compilation.compiler.root) + contextify( + /** @type {string} */ (options.context), + item.loader, + compilation.compiler.root + ) ); const error = new ModuleParseError(source, e, loaders, this.type); this.markModuleAsErrored(error); @@ -889,7 +1168,7 @@ class NormalModule extends Module { return callback(); }; - const handleParseResult = result => { + const handleParseResult = () => { this.dependencies.sort( concatComparators( compareSelect(a => a.loc, compareLocations), @@ -897,18 +1176,32 @@ class NormalModule extends Module { ) ); this._initBuildHash(compilation); - this._lastSuccessfulBuildMeta = this.buildMeta; + this._lastSuccessfulBuildMeta = + /** @type {BuildMeta} */ + (this.buildMeta); return handleBuildDone(); }; const handleBuildDone = () => { + try { + hooks.beforeSnapshot.call(this); + } catch (err) { + this.markModuleAsErrored(/** @type {WebpackError} */ (err)); + return callback(); + } + const snapshotOptions = compilation.options.snapshot.module; - if (!this.buildInfo.cacheable || !snapshotOptions) { + const { cacheable } = /** @type {BuildInfo} */ (this.buildInfo); + if (!cacheable || !snapshotOptions) { return callback(); } // add warning for all non-absolute paths in fileDependencies, etc // This makes it easier to find problems with watching and/or caching - let nonAbsoluteDependencies = undefined; + /** @type {undefined | Set} */ + let nonAbsoluteDependencies; + /** + * @param {LazySet} deps deps + */ const checkDependencies = deps => { for (const dep of deps) { if (!ABSOLUTE_PATH_REGEX.test(dep)) { @@ -920,26 +1213,42 @@ class NormalModule extends Module { const depWithoutGlob = dep.replace(/[\\/]?\*.*$/, ""); const absolute = join( compilation.fileSystemInfo.fs, - this.context, + /** @type {string} */ + (this.context), depWithoutGlob ); if (absolute !== dep && ABSOLUTE_PATH_REGEX.test(absolute)) { (depWithoutGlob !== dep - ? this.buildInfo.contextDependencies + ? /** @type {NonNullable} */ + ( + /** @type {BuildInfo} */ (this.buildInfo) + .contextDependencies + ) : deps ).add(absolute); } - } catch (e) { + } catch (_err) { // ignore } } } }; - checkDependencies(this.buildInfo.fileDependencies); - checkDependencies(this.buildInfo.missingDependencies); - checkDependencies(this.buildInfo.contextDependencies); + const buildInfo = /** @type {BuildInfo} */ (this.buildInfo); + const fileDependencies = + /** @type {NonNullable} */ + (buildInfo.fileDependencies); + const contextDependencies = + /** @type {NonNullable} */ + (buildInfo.contextDependencies); + const missingDependencies = + /** @type {NonNullable} */ + (buildInfo.missingDependencies); + checkDependencies(fileDependencies); + checkDependencies(missingDependencies); + checkDependencies(contextDependencies); if (nonAbsoluteDependencies !== undefined) { - const InvalidDependenciesModuleWarning = getInvalidDependenciesModuleWarning(); + const InvalidDependenciesModuleWarning = + getInvalidDependenciesModuleWarning(); this.addWarning( new InvalidDependenciesModuleWarning(this, nonAbsoluteDependencies) ); @@ -947,47 +1256,58 @@ class NormalModule extends Module { // convert file/context/missingDependencies into filesystem snapshot compilation.fileSystemInfo.createSnapshot( startTime, - this.buildInfo.fileDependencies, - this.buildInfo.contextDependencies, - this.buildInfo.missingDependencies, + fileDependencies, + contextDependencies, + missingDependencies, snapshotOptions, (err, snapshot) => { if (err) { this.markModuleAsErrored(err); return; } - this.buildInfo.fileDependencies = undefined; - this.buildInfo.contextDependencies = undefined; - this.buildInfo.missingDependencies = undefined; - this.buildInfo.snapshot = snapshot; + buildInfo.fileDependencies = undefined; + buildInfo.contextDependencies = undefined; + buildInfo.missingDependencies = undefined; + buildInfo.snapshot = snapshot; return callback(); } ); }; + try { + hooks.beforeParse.call(this); + } catch (err) { + this.markModuleAsErrored(/** @type {WebpackError} */ (err)); + this._initBuildHash(compilation); + return callback(); + } + // check if this module should !not! be parsed. // if so, exit here; const noParseRule = options.module && options.module.noParse; if (this.shouldPreventParsing(noParseRule, this.request)) { // We assume that we need module and exports - this.buildInfo.parsed = false; + /** @type {BuildInfo} */ + (this.buildInfo).parsed = false; this._initBuildHash(compilation); return handleBuildDone(); } - let result; try { - result = this.parser.parse(this._ast || this._source.source(), { + const source = /** @type {Source} */ (this._source).source(); + /** @type {Parser} */ + (this.parser).parse(this._ast || source, { + source, current: this, module: this, - compilation: compilation, - options: options + compilation, + options }); - } catch (e) { - handleParseError(e); + } catch (parseErr) { + handleParseError(/** @type {Error} */ (parseErr)); return; } - handleParseResult(result); + handleParseResult(); }); } @@ -996,7 +1316,9 @@ class NormalModule extends Module { * @returns {string | undefined} reason why this module can't be concatenated, undefined when it can be concatenated */ getConcatenationBailoutReason(context) { - return this.generator.getConcatenationBailoutReason(this, context); + return /** @type {Generator} */ ( + this.generator + ).getConcatenationBailoutReason(this, context); } /** @@ -1042,16 +1364,20 @@ class NormalModule extends Module { // When caching is implemented here, make sure to not cache when // at least one circular connection was in the loop above return current; - } else { - return true; } + return true; } /** - * @returns {Set} types available (do not mutate) + * @returns {SourceTypes} types available (do not mutate) */ getSourceTypes() { - return this.generator.getTypes(this); + if (this._sourceTypes === undefined) { + this._sourceTypes = /** @type {Generator} */ (this.generator).getTypes( + this + ); + } + return this._sourceTypes; } /** @@ -1064,31 +1390,31 @@ class NormalModule extends Module { moduleGraph, chunkGraph, runtime, - concatenationScope + concatenationScope, + codeGenerationResults, + sourceTypes }) { /** @type {Set} */ const runtimeRequirements = new Set(); - if (!this.buildInfo.parsed) { + const { parsed } = /** @type {BuildInfo} */ (this.buildInfo); + + if (!parsed) { runtimeRequirements.add(RuntimeGlobals.module); runtimeRequirements.add(RuntimeGlobals.exports); runtimeRequirements.add(RuntimeGlobals.thisAsExports); } - /** @type {Map} */ - let data; - const getData = () => { - if (data === undefined) data = new Map(); - return data; - }; + /** @type {function(): Map} */ + const getData = () => this._codeGeneratorData; const sources = new Map(); - for (const type of this.generator.getTypes(this)) { + for (const type of sourceTypes || chunkGraph.getModuleSourceTypes(this)) { const source = this.error ? new RawSource( - "throw new Error(" + JSON.stringify(this.error.message) + ");" - ) - : this.generator.generate(this, { + `throw new Error(${JSON.stringify(this.error.message)});` + ) + : /** @type {Generator} */ (this.generator).generate(this, { dependencyTemplates, runtimeTemplate, moduleGraph, @@ -1096,9 +1422,10 @@ class NormalModule extends Module { runtimeRequirements, runtime, concatenationScope, + codeGenerationResults, getData, type - }); + }); if (source) { sources.set(type, new CachedSource(source)); @@ -1109,7 +1436,7 @@ class NormalModule extends Module { const resultEntry = { sources, runtimeRequirements, - data + data: this._codeGeneratorData }; return resultEntry; } @@ -1130,35 +1457,60 @@ class NormalModule extends Module { /** * @param {NeedBuildContext} context context info - * @param {function(WebpackError=, boolean=): void} callback callback function, returns true, if the module needs a rebuild + * @param {function((WebpackError | null)=, boolean=): void} callback callback function, returns true, if the module needs a rebuild * @returns {void} */ - needBuild({ fileSystemInfo, valueCacheVersions }, callback) { + needBuild(context, callback) { + const { fileSystemInfo, compilation, valueCacheVersions } = context; // build if enforced if (this._forceBuild) return callback(null, true); // always try to build in case of an error if (this.error) return callback(null, true); + const { cacheable, snapshot, valueDependencies } = + /** @type {BuildInfo} */ (this.buildInfo); + // always build when module is not cacheable - if (!this.buildInfo.cacheable) return callback(null, true); + if (!cacheable) return callback(null, true); // build when there is no snapshot to check - if (!this.buildInfo.snapshot) return callback(null, true); + if (!snapshot) return callback(null, true); // build when valueDependencies have changed - if (this.buildInfo.valueDependencies) { + if (valueDependencies) { if (!valueCacheVersions) return callback(null, true); - for (const [key, value] of this.buildInfo.valueDependencies) { + for (const [key, value] of valueDependencies) { if (value === undefined) return callback(null, true); const current = valueCacheVersions.get(key); - if (value !== current) return callback(null, true); + if ( + value !== current && + (typeof value === "string" || + typeof current === "string" || + current === undefined || + !isSubset(value, current)) + ) { + return callback(null, true); + } } } // check snapshot for validity - fileSystemInfo.checkSnapshotValid(this.buildInfo.snapshot, (err, valid) => { - callback(err, !valid); + fileSystemInfo.checkSnapshotValid(snapshot, (err, valid) => { + if (err) return callback(err); + if (!valid) return callback(null, true); + const hooks = NormalModule.getCompilationHooks(compilation); + hooks.needBuild.callAsync(this, context, (err, needBuild) => { + if (err) { + return callback( + HookWebpackError.makeWebpackError( + err, + "NormalModule.getCompilationHooks().needBuild" + ) + ); + } + callback(null, Boolean(needBuild)); + }); }); } @@ -1172,7 +1524,10 @@ class NormalModule extends Module { if (cachedSize !== undefined) { return cachedSize; } - const size = Math.max(1, this.generator.getSize(this, type)); + const size = Math.max( + 1, + /** @type {Generator} */ (this.generator).getSize(this, type) + ); if (this._sourceSizes === undefined) { this._sourceSizes = new Map(); } @@ -1192,7 +1547,8 @@ class NormalModule extends Module { missingDependencies, buildDependencies ) { - const { snapshot, buildDependencies: buildDeps } = this.buildInfo; + const { snapshot, buildDependencies: buildDeps } = + /** @type {BuildInfo} */ (this.buildInfo); if (snapshot) { fileDependencies.addAll(snapshot.getFileIterable()); contextDependencies.addAll(snapshot.getContextIterable()); @@ -1202,7 +1558,7 @@ class NormalModule extends Module { fileDependencies: fileDeps, contextDependencies: contextDeps, missingDependencies: missingDeps - } = this.buildInfo; + } = /** @type {BuildInfo} */ (this.buildInfo); if (fileDeps !== undefined) fileDependencies.addAll(fileDeps); if (contextDeps !== undefined) contextDependencies.addAll(contextDeps); if (missingDeps !== undefined) missingDependencies.addAll(missingDeps); @@ -1218,22 +1574,26 @@ class NormalModule extends Module { * @returns {void} */ updateHash(hash, context) { - hash.update(this.buildInfo.hash); - this.generator.updateHash(hash, { + hash.update(/** @type {BuildInfo} */ (this.buildInfo).hash); + /** @type {Generator} */ + (this.generator).updateHash(hash, { module: this, ...context }); super.updateHash(hash, context); } + /** + * @param {ObjectSerializerContext} context context + */ serialize(context) { const { write } = context; // deserialize write(this._source); - write(this._sourceSizes); write(this.error); write(this._lastSuccessfulBuildMeta); write(this._forceBuild); + write(this._codeGeneratorData); super.serialize(context); } @@ -1244,6 +1604,7 @@ class NormalModule extends Module { type: "", // will be filled by updateCacheModule resource: "", + context: "", request: null, userRequest: null, rawRequest: null, @@ -1259,13 +1620,16 @@ class NormalModule extends Module { return obj; } + /** + * @param {ObjectDeserializerContext} context context + */ deserialize(context) { const { read } = context; this._source = read(); - this._sourceSizes = read(); this.error = read(); this._lastSuccessfulBuildMeta = read(); this._forceBuild = read(); + this._codeGeneratorData = read(); super.deserialize(context); } } diff --git a/lib/NormalModuleFactory.js b/lib/NormalModuleFactory.js index 7815a2601e1..323aef7bb45 100644 --- a/lib/NormalModuleFactory.js +++ b/lib/NormalModuleFactory.js @@ -5,6 +5,7 @@ "use strict"; +const { getContext } = require("loader-runner"); const asyncLib = require("neo-async"); const { AsyncSeriesBailHook, @@ -13,37 +14,57 @@ const { SyncHook, HookMap } = require("tapable"); +const ChunkGraph = require("./ChunkGraph"); const Module = require("./Module"); const ModuleFactory = require("./ModuleFactory"); +const ModuleGraph = require("./ModuleGraph"); +const { JAVASCRIPT_MODULE_TYPE_AUTO } = require("./ModuleTypeConstants"); const NormalModule = require("./NormalModule"); const BasicEffectRulePlugin = require("./rules/BasicEffectRulePlugin"); const BasicMatcherRulePlugin = require("./rules/BasicMatcherRulePlugin"); -const DescriptionDataMatcherRulePlugin = require("./rules/DescriptionDataMatcherRulePlugin"); +const ObjectMatcherRulePlugin = require("./rules/ObjectMatcherRulePlugin"); const RuleSetCompiler = require("./rules/RuleSetCompiler"); const UseEffectRulePlugin = require("./rules/UseEffectRulePlugin"); const LazySet = require("./util/LazySet"); const { getScheme } = require("./util/URLAbsoluteSpecifier"); const { cachedCleverMerge, cachedSetProperty } = require("./util/cleverMerge"); const { join } = require("./util/fs"); -const { parseResource } = require("./util/identifier"); +const { + parseResource, + parseResourceWithoutFragment +} = require("./util/identifier"); /** @typedef {import("../declarations/WebpackOptions").ModuleOptionsNormalized} ModuleOptions */ +/** @typedef {import("../declarations/WebpackOptions").RuleSetRule} RuleSetRule */ /** @typedef {import("./Generator")} Generator */ /** @typedef {import("./ModuleFactory").ModuleFactoryCreateData} ModuleFactoryCreateData */ +/** @typedef {import("./ModuleFactory").ModuleFactoryCreateDataContextInfo} ModuleFactoryCreateDataContextInfo */ /** @typedef {import("./ModuleFactory").ModuleFactoryResult} ModuleFactoryResult */ +/** @typedef {import("./NormalModule").GeneratorOptions} GeneratorOptions */ +/** @typedef {import("./NormalModule").LoaderItem} LoaderItem */ +/** @typedef {import("./NormalModule").NormalModuleCreateData} NormalModuleCreateData */ +/** @typedef {import("./NormalModule").ParserOptions} ParserOptions */ /** @typedef {import("./Parser")} Parser */ /** @typedef {import("./ResolverFactory")} ResolverFactory */ +/** @typedef {import("./ResolverFactory").ResolveContext} ResolveContext */ +/** @typedef {import("./ResolverFactory").ResolveRequest} ResolveRequest */ +/** @typedef {import("./ResolverFactory").ResolverWithOptions} ResolverWithOptions */ /** @typedef {import("./dependencies/ModuleDependency")} ModuleDependency */ /** @typedef {import("./util/fs").InputFileSystem} InputFileSystem */ +/** @typedef {Pick} ModuleSettings */ +/** @typedef {Partial} CreateData */ + /** - * @typedef {Object} ResolveData + * @typedef {object} ResolveData * @property {ModuleFactoryCreateData["contextInfo"]} contextInfo * @property {ModuleFactoryCreateData["resolveOptions"]} resolveOptions * @property {string} context * @property {string} request + * @property {Record | undefined} assertions * @property {ModuleDependency[]} dependencies - * @property {Object} createData + * @property {string} dependencyType + * @property {CreateData} createData * @property {LazySet} fileDependencies * @property {LazySet} missingDependencies * @property {LazySet} contextDependencies @@ -51,78 +72,97 @@ const { parseResource } = require("./util/identifier"); */ /** - * @typedef {Object} ResourceData + * @typedef {object} ResourceData * @property {string} resource - * @property {string} path - * @property {string} query - * @property {string} fragment + * @property {string=} path + * @property {string=} query + * @property {string=} fragment + * @property {string=} context */ /** @typedef {ResourceData & { data: Record }} ResourceDataWithData */ +/** + * @typedef {object} ParsedLoaderRequest + * @property {string} loader loader + * @property {string|undefined} options options + */ + +/** + * @template T + * @callback Callback + * @param {(Error | null)=} err + * @param {T=} stats + * @returns {void} + */ + const EMPTY_RESOLVE_OPTIONS = {}; +/** @type {ParserOptions} */ const EMPTY_PARSER_OPTIONS = {}; +/** @type {GeneratorOptions} */ const EMPTY_GENERATOR_OPTIONS = {}; +/** @type {ParsedLoaderRequest[]} */ +const EMPTY_ELEMENTS = []; const MATCH_RESOURCE_REGEX = /^([^!]+)!=!/; +const LEADING_DOT_EXTENSION_REGEX = /^[^.]/; +/** + * @param {LoaderItem} data data + * @returns {string} ident + */ const loaderToIdent = data => { if (!data.options) { return data.loader; } if (typeof data.options === "string") { - return data.loader + "?" + data.options; + return `${data.loader}?${data.options}`; } if (typeof data.options !== "object") { throw new Error("loader options must be string or object"); } if (data.ident) { - return data.loader + "??" + data.ident; + return `${data.loader}??${data.ident}`; } - return data.loader + "?" + JSON.stringify(data.options); + return `${data.loader}?${JSON.stringify(data.options)}`; }; +/** + * @param {LoaderItem[]} loaders loaders + * @param {string} resource resource + * @returns {string} stringified loaders and resource + */ const stringifyLoadersAndResource = (loaders, resource) => { let str = ""; for (const loader of loaders) { - str += loaderToIdent(loader) + "!"; + str += `${loaderToIdent(loader)}!`; } return str + resource; }; /** - * @param {string} resultString resultString - * @returns {{loader: string, options: string|undefined}} parsed loader request + * @param {number} times times + * @param {(err?: null | Error) => void} callback callback + * @returns {(err?: null | Error) => void} callback */ -const identToLoaderRequest = resultString => { - const idx = resultString.indexOf("?"); - if (idx >= 0) { - const loader = resultString.substr(0, idx); - const options = resultString.substr(idx + 1); - return { - loader, - options - }; - } else { - return { - loader: resultString, - options: undefined - }; +const needCalls = (times, callback) => err => { + if (--times === 0) { + return callback(err); + } + if (err && times > 0) { + times = Number.NaN; + return callback(err); } }; -const needCalls = (times, callback) => { - return err => { - if (--times === 0) { - return callback(err); - } - if (err && times > 0) { - times = NaN; - return callback(err); - } - }; -}; - +/** + * @template T + * @template O + * @param {T} globalOptions global options + * @param {string} type type + * @param {O} localOptions local options + * @returns {T & O | T | O} result + */ const mergeGlobalOptions = (globalOptions, type, localOptions) => { const parts = type.split("/"); let result; @@ -131,26 +171,31 @@ const mergeGlobalOptions = (globalOptions, type, localOptions) => { current = current ? `${current}/${part}` : part; const options = globalOptions[current]; if (typeof options === "object") { - if (result === undefined) { - result = options; - } else { - result = cachedCleverMerge(result, options); - } + result = + result === undefined ? options : cachedCleverMerge(result, options); } } if (result === undefined) { return localOptions; - } else { - return cachedCleverMerge(result, localOptions); } + return cachedCleverMerge(result, localOptions); }; // TODO webpack 6 remove +/** + * @param {string} name name + * @param {TODO} hook hook + * @returns {string} result + */ const deprecationChangedHookMessage = (name, hook) => { const names = hook.taps - .map(tapped => { - return tapped.name; - }) + .map( + /** + * @param {TODO} tapped tapped + * @returns {string} name + */ + tapped => tapped.name + ) .join(", "); return ( @@ -160,14 +205,9 @@ const deprecationChangedHookMessage = (name, hook) => { ); }; -/** @type {WeakMap} */ -const unsafeCacheDependencies = new WeakMap(); - -/** @type {WeakMap} */ -const unsafeCacheData = new WeakMap(); - const ruleSetCompiler = new RuleSetCompiler([ new BasicMatcherRulePlugin("test", "resource"), + new BasicMatcherRulePlugin("scheme"), new BasicMatcherRulePlugin("mimetype"), new BasicMatcherRulePlugin("dependency"), new BasicMatcherRulePlugin("include", "resource"), @@ -179,7 +219,17 @@ const ruleSetCompiler = new RuleSetCompiler([ new BasicMatcherRulePlugin("issuer"), new BasicMatcherRulePlugin("compiler"), new BasicMatcherRulePlugin("issuerLayer"), - new DescriptionDataMatcherRulePlugin(), + new ObjectMatcherRulePlugin( + "assert", + "assertions", + value => value && /** @type {any} */ (value)._isLegacyAssert !== undefined + ), + new ObjectMatcherRulePlugin( + "with", + "assertions", + value => value && !(/** @type {any} */ (value)._isLegacyAssert) + ), + new ObjectMatcherRulePlugin("descriptionData"), new BasicEffectRulePlugin("type"), new BasicEffectRulePlugin("sideEffects"), new BasicEffectRulePlugin("parser"), @@ -191,12 +241,12 @@ const ruleSetCompiler = new RuleSetCompiler([ class NormalModuleFactory extends ModuleFactory { /** - * @param {Object} param params + * @param {object} param params * @param {string=} param.context context * @param {InputFileSystem} param.fs file system * @param {ResolverFactory} param.resolverFactory resolverFactory * @param {ModuleOptions} param.options options - * @param {Object=} param.associatedObjectForCache an object to which the cache will be attached + * @param {object=} param.associatedObjectForCache an object to which the cache will be attached * @param {boolean=} param.layers enable layers */ constructor({ @@ -209,29 +259,41 @@ class NormalModuleFactory extends ModuleFactory { }) { super(); this.hooks = Object.freeze({ - /** @type {AsyncSeriesBailHook<[ResolveData], TODO>} */ + /** @type {AsyncSeriesBailHook<[ResolveData], Module | false | void>} */ resolve: new AsyncSeriesBailHook(["resolveData"]), /** @type {HookMap>} */ resolveForScheme: new HookMap( () => new AsyncSeriesBailHook(["resourceData", "resolveData"]) ), - /** @type {AsyncSeriesBailHook<[ResolveData], TODO>} */ + /** @type {HookMap>} */ + resolveInScheme: new HookMap( + () => new AsyncSeriesBailHook(["resourceData", "resolveData"]) + ), + /** @type {AsyncSeriesBailHook<[ResolveData], Module | undefined>} */ factorize: new AsyncSeriesBailHook(["resolveData"]), - /** @type {AsyncSeriesBailHook<[ResolveData], TODO>} */ + /** @type {AsyncSeriesBailHook<[ResolveData], false | void>} */ beforeResolve: new AsyncSeriesBailHook(["resolveData"]), - /** @type {AsyncSeriesBailHook<[ResolveData], TODO>} */ + /** @type {AsyncSeriesBailHook<[ResolveData], false | void>} */ afterResolve: new AsyncSeriesBailHook(["resolveData"]), - /** @type {AsyncSeriesBailHook<[ResolveData["createData"], ResolveData], TODO>} */ + /** @type {AsyncSeriesBailHook<[ResolveData["createData"], ResolveData], Module | void>} */ createModule: new AsyncSeriesBailHook(["createData", "resolveData"]), - /** @type {SyncWaterfallHook<[Module, ResolveData["createData"], ResolveData], TODO>} */ + /** @type {SyncWaterfallHook<[Module, ResolveData["createData"], ResolveData], Module>} */ module: new SyncWaterfallHook(["module", "createData", "resolveData"]), + /** @type {HookMap>} */ createParser: new HookMap(() => new SyncBailHook(["parserOptions"])), + /** @type {HookMap>} */ parser: new HookMap(() => new SyncHook(["parser", "parserOptions"])), + /** @type {HookMap>} */ createGenerator: new HookMap( () => new SyncBailHook(["generatorOptions"]) ), + /** @type {HookMap>} */ generator: new HookMap( () => new SyncHook(["generator", "generatorOptions"]) + ), + /** @type {HookMap>} */ + createModuleClass: new HookMap( + () => new SyncBailHook(["createData", "resolveData"]) ) }); this.resolverFactory = resolverFactory; @@ -243,25 +305,23 @@ class NormalModuleFactory extends ModuleFactory { rules: options.rules } ]); - this.unsafeCache = !!options.unsafeCache; - this.cachePredicate = - typeof options.unsafeCache === "function" - ? options.unsafeCache - : () => true; this.context = context || ""; this.fs = fs; this._globalParserOptions = options.parser; this._globalGeneratorOptions = options.generator; - /** @type {Map>} */ + /** @type {Map>} */ this.parserCache = new Map(); - /** @type {Map>} */ + /** @type {Map>} */ this.generatorCache = new Map(); - /** @type {WeakSet} */ - this._restoredUnsafeCacheEntries = new WeakSet(); + /** @type {Set} */ + this._restoredUnsafeCacheEntries = new Set(); const cacheParseResource = parseResource.bindCache( associatedObjectForCache ); + const cachedParseResourceWithoutFragment = + parseResourceWithoutFragment.bindCache(associatedObjectForCache); + this._parseResourceWithoutFragment = cachedParseResourceWithoutFragment; this.hooks.factorize.tapAsync( { @@ -280,8 +340,10 @@ class NormalModuleFactory extends ModuleFactory { if (typeof result === "object") throw new Error( - deprecationChangedHookMessage("resolve", this.hooks.resolve) + - " Returning a Module object will result in this module used as result." + `${deprecationChangedHookMessage( + "resolve", + this.hooks.resolve + )} Returning a Module object will result in this module used as result.` ); this.hooks.afterResolve.callAsync(resolveData, (err, result) => { @@ -309,7 +371,20 @@ class NormalModuleFactory extends ModuleFactory { return callback(new Error("Empty dependency (no request)")); } - createdModule = new NormalModule(createData); + // TODO webpack 6 make it required and move javascript/wasm/asset properties to own module + createdModule = this.hooks.createModuleClass + .for( + /** @type {ModuleSettings} */ (createData.settings).type + ) + .call(createData, resolveData); + + if (!createdModule) { + createdModule = /** @type {Module} */ ( + new NormalModule( + /** @type {NormalModuleCreateData} */ (createData) + ) + ); + } } createdModule = this.hooks.module.call( @@ -335,56 +410,92 @@ class NormalModuleFactory extends ModuleFactory { contextInfo, context, dependencies, + dependencyType, request, + assertions, resolveOptions, fileDependencies, missingDependencies, contextDependencies } = data; - const dependencyType = - (dependencies.length > 0 && dependencies[0].category) || ""; const loaderResolver = this.getResolver("loader"); /** @type {ResourceData | undefined} */ - let matchResourceData = undefined; + let matchResourceData; /** @type {string} */ - let requestWithoutMatchResource = request; - const matchResourceMatch = MATCH_RESOURCE_REGEX.exec(request); - if (matchResourceMatch) { - let matchResource = matchResourceMatch[1]; - if (matchResource.charCodeAt(0) === 46) { - // 46 === ".", 47 === "/" - const secondChar = matchResource.charCodeAt(1); - if ( - secondChar === 47 || - (secondChar === 46 && matchResource.charCodeAt(2) === 47) - ) { - // if matchResources startsWith ../ or ./ - matchResource = join(this.fs, context, matchResource); + let unresolvedResource; + /** @type {ParsedLoaderRequest[]} */ + let elements; + let noPreAutoLoaders = false; + let noAutoLoaders = false; + let noPrePostAutoLoaders = false; + + const contextScheme = getScheme(context); + /** @type {string | undefined} */ + let scheme = getScheme(request); + + if (!scheme) { + /** @type {string} */ + let requestWithoutMatchResource = request; + const matchResourceMatch = MATCH_RESOURCE_REGEX.exec(request); + if (matchResourceMatch) { + let matchResource = matchResourceMatch[1]; + if (matchResource.charCodeAt(0) === 46) { + // 46 === ".", 47 === "/" + const secondChar = matchResource.charCodeAt(1); + if ( + secondChar === 47 || + (secondChar === 46 && matchResource.charCodeAt(2) === 47) + ) { + // if matchResources startsWith ../ or ./ + matchResource = join(this.fs, context, matchResource); + } } + matchResourceData = { + resource: matchResource, + ...cacheParseResource(matchResource) + }; + requestWithoutMatchResource = request.slice( + matchResourceMatch[0].length + ); } - matchResourceData = { - resource: matchResource, - ...cacheParseResource(matchResource) - }; - requestWithoutMatchResource = request.substr( - matchResourceMatch[0].length - ); - } - const firstChar = requestWithoutMatchResource.charCodeAt(0); - const secondChar = requestWithoutMatchResource.charCodeAt(1); - const noPreAutoLoaders = firstChar === 45 && secondChar === 33; // startsWith "-!" - const noAutoLoaders = noPreAutoLoaders || firstChar === 33; // startsWith "!" - const noPrePostAutoLoaders = firstChar === 33 && secondChar === 33; // startsWith "!!"; - const rawElements = requestWithoutMatchResource - .slice( - noPreAutoLoaders || noPrePostAutoLoaders ? 2 : noAutoLoaders ? 1 : 0 - ) - .split(/!+/); - const unresolvedResource = rawElements.pop(); - const elements = rawElements.map(identToLoaderRequest); + scheme = getScheme(requestWithoutMatchResource); + + if (!scheme && !contextScheme) { + const firstChar = requestWithoutMatchResource.charCodeAt(0); + const secondChar = requestWithoutMatchResource.charCodeAt(1); + noPreAutoLoaders = firstChar === 45 && secondChar === 33; // startsWith "-!" + noAutoLoaders = noPreAutoLoaders || firstChar === 33; // startsWith "!" + noPrePostAutoLoaders = firstChar === 33 && secondChar === 33; // startsWith "!!"; + const rawElements = requestWithoutMatchResource + .slice( + noPreAutoLoaders || noPrePostAutoLoaders + ? 2 + : noAutoLoaders + ? 1 + : 0 + ) + .split(/!+/); + unresolvedResource = /** @type {string} */ (rawElements.pop()); + elements = rawElements.map(el => { + const { path, query } = cachedParseResourceWithoutFragment(el); + return { + loader: path, + options: query ? query.slice(1) : undefined + }; + }); + scheme = getScheme(unresolvedResource); + } else { + unresolvedResource = requestWithoutMatchResource; + elements = EMPTY_ELEMENTS; + } + } else { + unresolvedResource = request; + elements = EMPTY_ELEMENTS; + } + /** @type {ResolveContext} */ const resolveContext = { fileDependencies, missingDependencies, @@ -393,9 +504,8 @@ class NormalModuleFactory extends ModuleFactory { /** @type {ResourceDataWithData} */ let resourceData; - /** @type {string | undefined} */ - const scheme = getScheme(unresolvedResource); + /** @type {undefined | LoaderItem[]} */ let loaders; const continueCallback = needCalls(2, err => { @@ -403,9 +513,9 @@ class NormalModuleFactory extends ModuleFactory { // translate option idents try { - for (const item of loaders) { + for (const item of /** @type {LoaderItem[]} */ (loaders)) { if (typeof item.options === "string" && item.options[0] === "?") { - const ident = item.options.substr(1); + const ident = item.options.slice(1); if (ident === "[[missing ident]]") { throw new Error( "No ident is provided by referenced loader. " + @@ -422,8 +532,8 @@ class NormalModuleFactory extends ModuleFactory { item.ident = ident; } } - } catch (e) { - return callback(e); + } catch (identErr) { + return callback(/** @type {Error} */ (identErr)); } if (!resourceData) { @@ -435,68 +545,113 @@ class NormalModuleFactory extends ModuleFactory { (matchResourceData !== undefined ? `${matchResourceData.resource}!=!` : "") + - stringifyLoadersAndResource(loaders, resourceData.resource); - - const resourceDataForRules = matchResourceData || resourceData; - const result = this.ruleSet.exec({ - resource: resourceDataForRules.path, - realResource: resourceData.path, - resourceQuery: resourceDataForRules.query, - resourceFragment: resourceDataForRules.fragment, - mimetype: matchResourceData ? "" : resourceData.data.mimetype || "", - dependency: dependencyType, - descriptionData: matchResourceData - ? undefined - : resourceData.data.descriptionFileData, - issuer: contextInfo.issuer, - compiler: contextInfo.compiler, - issuerLayer: contextInfo.issuerLayer || "" - }); + stringifyLoadersAndResource( + /** @type {LoaderItem[]} */ (loaders), + resourceData.resource + ); + + /** @type {ModuleSettings} */ const settings = {}; const useLoadersPost = []; const useLoaders = []; const useLoadersPre = []; - for (const r of result) { - if (r.type === "use") { - if (!noAutoLoaders && !noPrePostAutoLoaders) { - useLoaders.push(r.value); - } - } else if (r.type === "use-post") { - if (!noPrePostAutoLoaders) { - useLoadersPost.push(r.value); + + // handle .webpack[] suffix + let resource; + let match; + if ( + matchResourceData && + typeof (resource = matchResourceData.resource) === "string" && + (match = /\.webpack\[([^\]]+)\]$/.exec(resource)) + ) { + settings.type = match[1]; + matchResourceData.resource = matchResourceData.resource.slice( + 0, + -settings.type.length - 10 + ); + } else { + settings.type = JAVASCRIPT_MODULE_TYPE_AUTO; + const resourceDataForRules = matchResourceData || resourceData; + const result = this.ruleSet.exec({ + resource: resourceDataForRules.path, + realResource: resourceData.path, + resourceQuery: resourceDataForRules.query, + resourceFragment: resourceDataForRules.fragment, + scheme, + assertions, + mimetype: matchResourceData + ? "" + : resourceData.data.mimetype || "", + dependency: dependencyType, + descriptionData: matchResourceData + ? undefined + : resourceData.data.descriptionFileData, + issuer: contextInfo.issuer, + compiler: contextInfo.compiler, + issuerLayer: contextInfo.issuerLayer || "" + }); + for (const r of result) { + // https://github.com/webpack/webpack/issues/16466 + // if a request exists PrePostAutoLoaders, should disable modifying Rule.type + if (r.type === "type" && noPrePostAutoLoaders) { + continue; } - } else if (r.type === "use-pre") { - if (!noPreAutoLoaders && !noPrePostAutoLoaders) { - useLoadersPre.push(r.value); + if (r.type === "use") { + if (!noAutoLoaders && !noPrePostAutoLoaders) { + useLoaders.push(r.value); + } + } else if (r.type === "use-post") { + if (!noPrePostAutoLoaders) { + useLoadersPost.push(r.value); + } + } else if (r.type === "use-pre") { + if (!noPreAutoLoaders && !noPrePostAutoLoaders) { + useLoadersPre.push(r.value); + } + } else if ( + typeof r.value === "object" && + r.value !== null && + typeof settings[ + /** @type {keyof ModuleSettings} */ (r.type) + ] === "object" && + settings[/** @type {keyof ModuleSettings} */ (r.type)] !== null + ) { + settings[r.type] = cachedCleverMerge( + settings[/** @type {keyof ModuleSettings} */ (r.type)], + r.value + ); + } else { + settings[r.type] = r.value; } - } else if ( - typeof r.value === "object" && - r.value !== null && - typeof settings[r.type] === "object" && - settings[r.type] !== null - ) { - settings[r.type] = cachedCleverMerge(settings[r.type], r.value); - } else { - settings[r.type] = r.value; } } - let postLoaders, normalLoaders, preLoaders; + /** @type {undefined | LoaderItem[]} */ + let postLoaders; + /** @type {undefined | LoaderItem[]} */ + let normalLoaders; + /** @type {undefined | LoaderItem[]} */ + let preLoaders; const continueCallback = needCalls(3, err => { if (err) { return callback(err); } - const allLoaders = postLoaders; + const allLoaders = /** @type {LoaderItem[]} */ (postLoaders); if (matchResourceData === undefined) { - for (const loader of loaders) allLoaders.push(loader); - for (const loader of normalLoaders) allLoaders.push(loader); + for (const loader of /** @type {LoaderItem[]} */ (loaders)) + allLoaders.push(loader); + for (const loader of /** @type {LoaderItem[]} */ (normalLoaders)) + allLoaders.push(loader); } else { - for (const loader of normalLoaders) allLoaders.push(loader); - for (const loader of loaders) allLoaders.push(loader); + for (const loader of /** @type {LoaderItem[]} */ (normalLoaders)) + allLoaders.push(loader); + for (const loader of /** @type {LoaderItem[]} */ (loaders)) + allLoaders.push(loader); } - for (const loader of preLoaders) allLoaders.push(loader); - const type = settings.type; + for (const loader of /** @type {LoaderItem[]} */ (preLoaders)) + allLoaders.push(loader); + const type = /** @type {string} */ (settings.type); const resolveOptions = settings.resolve; const layer = settings.layer; if (layer !== undefined && !layers) { @@ -506,29 +661,35 @@ class NormalModuleFactory extends ModuleFactory { ) ); } - Object.assign(data.createData, { - layer: - layer === undefined ? contextInfo.issuerLayer || null : layer, - request: stringifyLoadersAndResource( - allLoaders, - resourceData.resource - ), - userRequest, - rawRequest: request, - loaders: allLoaders, - resource: resourceData.resource, - matchResource: matchResourceData - ? matchResourceData.resource - : undefined, - resourceResolveData: resourceData.data, - settings, - type, - parser: this.getParser(type, settings.parser), - parserOptions: settings.parser, - generator: this.getGenerator(type, settings.generator), - generatorOptions: settings.generator, - resolveOptions - }); + try { + Object.assign(data.createData, { + layer: + layer === undefined ? contextInfo.issuerLayer || null : layer, + request: stringifyLoadersAndResource( + allLoaders, + resourceData.resource + ), + userRequest, + rawRequest: request, + loaders: allLoaders, + resource: resourceData.resource, + context: + resourceData.context || getContext(resourceData.resource), + matchResource: matchResourceData + ? matchResourceData.resource + : undefined, + resourceResolveData: resourceData.data, + settings, + type, + parser: this.getParser(type, settings.parser), + parserOptions: settings.parser, + generator: this.getGenerator(type, settings.generator), + generatorOptions: settings.generator, + resolveOptions + }); + } catch (createDataErr) { + return callback(/** @type {Error} */ (createDataErr)); + } callback(); }); this.resolveRequestArray( @@ -568,8 +729,8 @@ class NormalModuleFactory extends ModuleFactory { this.resolveRequestArray( contextInfo, - context, - elements, + contextScheme ? this.context : context, + /** @type {LoaderItem[]} */ (elements), loaderResolver, resolveContext, (err, result) => { @@ -579,6 +740,57 @@ class NormalModuleFactory extends ModuleFactory { } ); + /** + * @param {string} context context + */ + const defaultResolve = context => { + if (/^($|\?)/.test(unresolvedResource)) { + resourceData = { + resource: unresolvedResource, + data: {}, + ...cacheParseResource(unresolvedResource) + }; + continueCallback(); + } + + // resource without scheme and with path + else { + const normalResolver = this.getResolver( + "normal", + dependencyType + ? cachedSetProperty( + resolveOptions || EMPTY_RESOLVE_OPTIONS, + "dependencyType", + dependencyType + ) + : resolveOptions + ); + this.resolveResource( + contextInfo, + context, + unresolvedResource, + normalResolver, + resolveContext, + (err, _resolvedResource, resolvedResourceResolveData) => { + if (err) return continueCallback(err); + if (_resolvedResource !== false) { + const resolvedResource = + /** @type {string} */ + (_resolvedResource); + resourceData = { + resource: resolvedResource, + data: + /** @type {ResolveRequest} */ + (resolvedResourceResolveData), + ...cacheParseResource(resolvedResource) + }; + } + continueCallback(); + } + ); + } + }; + // resource with scheme if (scheme) { resourceData = { @@ -586,7 +798,8 @@ class NormalModuleFactory extends ModuleFactory { data: {}, path: undefined, query: undefined, - fragment: undefined + fragment: undefined, + context: undefined }; this.hooks.resolveForScheme .for(scheme) @@ -596,85 +809,66 @@ class NormalModuleFactory extends ModuleFactory { }); } - // resource without scheme and without path - else if (/^($|\?)/.test(unresolvedResource)) { + // resource within scheme + else if (contextScheme) { resourceData = { resource: unresolvedResource, data: {}, - ...cacheParseResource(unresolvedResource) + path: undefined, + query: undefined, + fragment: undefined, + context: undefined }; - continueCallback(); - } - - // resource without scheme and with path - else { - const normalResolver = this.getResolver( - "normal", - dependencyType - ? cachedSetProperty( - resolveOptions || EMPTY_RESOLVE_OPTIONS, - "dependencyType", - dependencyType - ) - : resolveOptions - ); - this.resolveResource( - contextInfo, - context, - unresolvedResource, - normalResolver, - resolveContext, - (err, resolvedResource, resolvedResourceResolveData) => { + this.hooks.resolveInScheme + .for(contextScheme) + .callAsync(resourceData, data, (err, handled) => { if (err) return continueCallback(err); - if (resolvedResource !== false) { - resourceData = { - resource: resolvedResource, - data: resolvedResourceResolveData, - ...cacheParseResource(resolvedResource) - }; - } + if (!handled) return defaultResolve(this.context); continueCallback(); - } - ); + }); } + + // resource without scheme and without path + else defaultResolve(context); } ); } + cleanupForCache() { + for (const module of this._restoredUnsafeCacheEntries) { + ChunkGraph.clearChunkGraphForModule(module); + ModuleGraph.clearModuleGraphForModule(module); + module.cleanupForCache(); + } + } + /** * @param {ModuleFactoryCreateData} data data object - * @param {function(Error=, ModuleFactoryResult=): void} callback callback + * @param {function((Error | null)=, ModuleFactoryResult=): void} callback callback * @returns {void} */ create(data, callback) { const dependencies = /** @type {ModuleDependency[]} */ (data.dependencies); - if (this.unsafeCache) { - const cacheEntry = unsafeCacheDependencies.get(dependencies[0]); - if (cacheEntry) { - const { module } = cacheEntry; - if (!this._restoredUnsafeCacheEntries.has(module)) { - const data = unsafeCacheData.get(module); - module.restoreFromUnsafeCache(data, this); - this._restoredUnsafeCacheEntries.add(module); - } - return callback(null, cacheEntry); - } - } const context = data.context || this.context; const resolveOptions = data.resolveOptions || EMPTY_RESOLVE_OPTIONS; const dependency = dependencies[0]; const request = dependency.request; + const assertions = dependency.assertions; const contextInfo = data.contextInfo; const fileDependencies = new LazySet(); const missingDependencies = new LazySet(); const contextDependencies = new LazySet(); + const dependencyType = + (dependencies.length > 0 && dependencies[0].category) || ""; /** @type {ResolveData} */ const resolveData = { contextInfo, resolveOptions, context, request, + assertions, dependencies, + dependencyType, fileDependencies, missingDependencies, contextDependencies, @@ -686,7 +880,8 @@ class NormalModuleFactory extends ModuleFactory { return callback(err, { fileDependencies, missingDependencies, - contextDependencies + contextDependencies, + cacheable: false }); } @@ -695,7 +890,8 @@ class NormalModuleFactory extends ModuleFactory { return callback(null, { fileDependencies, missingDependencies, - contextDependencies + contextDependencies, + cacheable: resolveData.cacheable }); } @@ -712,7 +908,8 @@ class NormalModuleFactory extends ModuleFactory { return callback(err, { fileDependencies, missingDependencies, - contextDependencies + contextDependencies, + cacheable: false }); } @@ -720,29 +917,23 @@ class NormalModuleFactory extends ModuleFactory { module, fileDependencies, missingDependencies, - contextDependencies + contextDependencies, + cacheable: resolveData.cacheable }; - if ( - this.unsafeCache && - resolveData.cacheable && - module && - module.restoreFromUnsafeCache && - this.cachePredicate(module) - ) { - for (const d of dependencies) { - unsafeCacheDependencies.set(d, factoryResult); - } - if (!unsafeCacheData.has(module)) { - unsafeCacheData.set(module, module.getUnsafeCacheData()); - } - } - callback(null, factoryResult); }); }); } + /** + * @param {ModuleFactoryCreateDataContextInfo} contextInfo context info + * @param {string} context context + * @param {string} unresolvedResource unresolved resource + * @param {ResolverWithOptions} resolver resolver + * @param {ResolveContext} resolveContext resolver context + * @param {(err: null | Error, res?: string | false, req?: ResolveRequest) => void} callback callback + */ resolveResource( contextInfo, context, @@ -768,10 +959,10 @@ class NormalModuleFactory extends ModuleFactory { (err2, hints) => { if (err2) { err.message += ` -An fatal error happened during resolving additional hints for this error: ${err2.message}`; +A fatal error happened during resolving additional hints for this error: ${err2.message}`; err.stack += ` -An fatal error happened during resolving additional hints for this error: +A fatal error happened during resolving additional hints for this error: ${err2.stack}`; return callback(err); } @@ -779,6 +970,25 @@ ${err2.stack}`; err.message += ` ${hints.join("\n\n")}`; } + + // Check if the extension is missing a leading dot (e.g. "js" instead of ".js") + let appendResolveExtensionsHint = false; + const specifiedExtensions = Array.from( + resolver.options.extensions + ); + const expectedExtensions = specifiedExtensions.map(extension => { + if (LEADING_DOT_EXTENSION_REGEX.test(extension)) { + appendResolveExtensionsHint = true; + return `.${extension}`; + } + return extension; + }); + if (appendResolveExtensionsHint) { + err.message += `\nDid you miss the leading dot in 'resolve.extensions'? Did you mean '${JSON.stringify( + expectedExtensions + )}' instead of '${JSON.stringify(specifiedExtensions)}'?`; + } + callback(err); } ); @@ -788,6 +998,16 @@ ${hints.join("\n\n")}`; ); } + /** + * @param {Error} error error + * @param {ModuleFactoryCreateDataContextInfo} contextInfo context info + * @param {string} context context + * @param {string} unresolvedResource unresolved resource + * @param {ResolverWithOptions} resolver resolver + * @param {ResolveContext} resolveContext resolver context + * @param {Callback} callback callback + * @private + */ _resolveResourceErrorHints( error, contextInfo, @@ -820,7 +1040,7 @@ ${hints.join("\n\n")}`; null, `Did you mean '${resource}'? BREAKING CHANGE: The request '${unresolvedResource}' failed to resolve only because it was resolved as fully specified -(probably because the origin is a '*.mjs' file or a '*.js' file where the package.json contains '"type": "module"'). +(probably because the origin is strict EcmaScript Module, e. g. a module with javascript mimetype, a '*.mjs' file, or a '*.js' file where the package.json contains '"type": "module"'). The extension in the request is mandatory for it to be fully specified. Add the extension to the request.` ); @@ -850,13 +1070,12 @@ Add the extension to the request.` /(\.[^.]+)(\?|$)/, "$2" ); - if (resolver.options.extensions.has(match[1])) { - hint = `Did you mean '${fixedRequest}'?`; - } else { - hint = `Did you mean '${fixedRequest}'? Also note that '${match[1]}' is not in 'resolve.extensions' yet and need to be added for this to work?`; - } + hint = resolver.options.extensions.has(match[1]) + ? `Did you mean '${fixedRequest}'?` + : `Did you mean '${fixedRequest}'? Also note that '${match[1]}' is not in 'resolve.extensions' yet and need to be added for this to work?`; } else { - hint = `Did you mean to omit the extension or to remove 'resolve.enforceExtension'?`; + hint = + "Did you mean to omit the extension or to remove 'resolve.enforceExtension'?"; } return callback( null, @@ -899,11 +1118,20 @@ If changing the source code is not an option there is also a resolve options cal ], (err, hints) => { if (err) return callback(err); - callback(null, hints.filter(Boolean)); + callback(null, /** @type {string[]} */ (hints).filter(Boolean)); } ); } + /** + * @param {ModuleFactoryCreateDataContextInfo} contextInfo context info + * @param {string} context context + * @param {LoaderItem[]} array array + * @param {ResolverWithOptions} resolver resolver + * @param {ResolveContext} resolveContext resolve context + * @param {Callback} callback callback + * @returns {void} result + */ resolveRequestArray( contextInfo, context, @@ -912,6 +1140,7 @@ If changing the source code is not an option there is also a resolve options cal resolveContext, callback ) { + // LoaderItem if (array.length === 0) return callback(null, array); asyncLib.map( array, @@ -921,22 +1150,21 @@ If changing the source code is not an option there is also a resolve options cal context, item.loader, resolveContext, - (err, result) => { + (err, result, resolveRequest) => { if ( err && /^[^/]*$/.test(item.loader) && - !/-loader$/.test(item.loader) + !item.loader.endsWith("-loader") ) { return resolver.resolve( contextInfo, context, - item.loader + "-loader", + `${item.loader}-loader`, resolveContext, err2 => { if (!err2) { err.message = - err.message + - "\n" + + `${err.message}\n` + "BREAKING CHANGE: It's no longer allowed to omit the '-loader' suffix when using loaders.\n" + ` You need to specify '${item.loader}-loader' instead of '${item.loader}',\n` + " see https://webpack.js.org/migrate/3/#automatic-loader-module-name-extension-removed"; @@ -947,23 +1175,47 @@ If changing the source code is not an option there is also a resolve options cal } if (err) return callback(err); - const parsedResult = identToLoaderRequest(result); + const parsedResult = this._parseResourceWithoutFragment( + /** @type {string} */ (result) + ); + + const type = /\.mjs$/i.test(parsedResult.path) + ? "module" + : /\.cjs$/i.test(parsedResult.path) + ? "commonjs" + : /** @type {ResolveRequest} */ + (resolveRequest).descriptionFileData === undefined + ? undefined + : /** @type {ResolveRequest} */ + (resolveRequest).descriptionFileData.type; const resolved = { - loader: parsedResult.loader, + loader: parsedResult.path, + type, options: item.options === undefined - ? parsedResult.options + ? parsedResult.query + ? parsedResult.query.slice(1) + : undefined : item.options, - ident: item.options === undefined ? undefined : item.ident + ident: + item.options === undefined + ? undefined + : /** @type {string} */ (item.ident) }; - return callback(null, resolved); + + return callback(null, /** @type {LoaderItem} */ (resolved)); } ); }, - callback + /** @type {Callback} */ (callback) ); } + /** + * @param {string} type type + * @param {ParserOptions} parserOptions parser options + * @returns {Parser} parser + */ getParser(type, parserOptions = EMPTY_PARSER_OPTIONS) { let cache = this.parserCache.get(type); @@ -984,7 +1236,7 @@ If changing the source code is not an option there is also a resolve options cal /** * @param {string} type type - * @param {{[k: string]: any}} parserOptions parser options + * @param {ParserOptions} parserOptions parser options * @returns {Parser} parser */ createParser(type, parserOptions = {}) { @@ -1001,6 +1253,11 @@ If changing the source code is not an option there is also a resolve options cal return parser; } + /** + * @param {string} type type of generator + * @param {GeneratorOptions} generatorOptions generator options + * @returns {Generator} generator + */ getGenerator(type, generatorOptions = EMPTY_GENERATOR_OPTIONS) { let cache = this.generatorCache.get(type); @@ -1019,6 +1276,11 @@ If changing the source code is not an option there is also a resolve options cal return generator; } + /** + * @param {string} type type of generator + * @param {GeneratorOptions} generatorOptions generator options + * @returns {Generator} generator + */ createGenerator(type, generatorOptions = {}) { generatorOptions = mergeGlobalOptions( this._globalGeneratorOptions, @@ -1035,6 +1297,11 @@ If changing the source code is not an option there is also a resolve options cal return generator; } + /** + * @param {Parameters[0]} type type of resolver + * @param {Parameters[1]=} resolveOptions options + * @returns {ReturnType} the resolver + */ getResolver(type, resolveOptions) { return this.resolverFactory.get(type, resolveOptions); } diff --git a/lib/NormalModuleReplacementPlugin.js b/lib/NormalModuleReplacementPlugin.js index 121e8e03399..fb44e088db1 100644 --- a/lib/NormalModuleReplacementPlugin.js +++ b/lib/NormalModuleReplacementPlugin.js @@ -8,7 +8,9 @@ const { join, dirname } = require("./util/fs"); /** @typedef {import("./Compiler")} Compiler */ -/** @typedef {function(TODO): void} ModuleReplacer */ +/** @typedef {import("./util/fs").InputFileSystem} InputFileSystem */ + +/** @typedef {function(import("./NormalModuleFactory").ResolveData): void} ModuleReplacer */ class NormalModuleReplacementPlugin { /** @@ -43,11 +45,15 @@ class NormalModuleReplacementPlugin { }); nmf.hooks.afterResolve.tap("NormalModuleReplacementPlugin", result => { const createData = result.createData; - if (resourceRegExp.test(createData.resource)) { + if ( + resourceRegExp.test(/** @type {string} */ (createData.resource)) + ) { if (typeof newResource === "function") { newResource(result); } else { - const fs = compiler.inputFileSystem; + const fs = + /** @type {InputFileSystem} */ + (compiler.inputFileSystem); if ( newResource.startsWith("/") || (newResource.length > 1 && newResource[1] === ":") @@ -56,7 +62,7 @@ class NormalModuleReplacementPlugin { } else { createData.resource = join( fs, - dirname(fs, createData.resource), + dirname(fs, /** @type {string} */ (createData.resource)), newResource ); } diff --git a/lib/NullFactory.js b/lib/NullFactory.js index be86ccf85de..50f3471be46 100644 --- a/lib/NullFactory.js +++ b/lib/NullFactory.js @@ -13,7 +13,7 @@ const ModuleFactory = require("./ModuleFactory"); class NullFactory extends ModuleFactory { /** * @param {ModuleFactoryCreateData} data data object - * @param {function(Error=, ModuleFactoryResult=): void} callback callback + * @param {function((Error | null)=, ModuleFactoryResult=): void} callback callback * @returns {void} */ create(data, callback) { diff --git a/lib/OptimizationStages.js b/lib/OptimizationStages.js index 35988fb59e9..102d613c5aa 100644 --- a/lib/OptimizationStages.js +++ b/lib/OptimizationStages.js @@ -5,6 +5,6 @@ "use strict"; -exports.STAGE_BASIC = -10; -exports.STAGE_DEFAULT = 0; -exports.STAGE_ADVANCED = 10; +module.exports.STAGE_BASIC = -10; +module.exports.STAGE_DEFAULT = 0; +module.exports.STAGE_ADVANCED = 10; diff --git a/lib/Parser.js b/lib/Parser.js index f5921c229ba..892c5fcd329 100644 --- a/lib/Parser.js +++ b/lib/Parser.js @@ -11,7 +11,8 @@ /** @typedef {Record} PreparsedAst */ /** - * @typedef {Object} ParserStateBase + * @typedef {object} ParserStateBase + * @property {string | Buffer} source * @property {NormalModule} current * @property {NormalModule} module * @property {Compilation} compilation diff --git a/lib/PlatformPlugin.js b/lib/PlatformPlugin.js new file mode 100644 index 00000000000..ae601ae8b45 --- /dev/null +++ b/lib/PlatformPlugin.js @@ -0,0 +1,39 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Authors Ivan Kopeykin @vankop +*/ + +"use strict"; + +/** @typedef {import("./Compiler")} Compiler */ +/** @typedef {import("./config/target").PlatformTargetProperties} PlatformTargetProperties */ + +/** + * Should be used only for "target === false" or + * when you want to overwrite platform target properties + */ +class PlatformPlugin { + /** + * @param {Partial} platform target properties + */ + constructor(platform) { + /** @type {Partial} */ + this.platform = platform; + } + + /** + * Apply the plugin + * @param {Compiler} compiler the compiler instance + * @returns {void} + */ + apply(compiler) { + compiler.hooks.environment.tap("PlatformPlugin", () => { + compiler.platform = { + ...compiler.platform, + ...this.platform + }; + }); + } +} + +module.exports = PlatformPlugin; diff --git a/lib/PrefetchPlugin.js b/lib/PrefetchPlugin.js index fb1454cbe9c..4f09fc0c3dc 100644 --- a/lib/PrefetchPlugin.js +++ b/lib/PrefetchPlugin.js @@ -10,6 +10,10 @@ const PrefetchDependency = require("./dependencies/PrefetchDependency"); /** @typedef {import("./Compiler")} Compiler */ class PrefetchPlugin { + /** + * @param {string} context context or request if context is not set + * @param {string} [request] request + */ constructor(context, request) { if (request) { this.context = context; diff --git a/lib/ProgressPlugin.js b/lib/ProgressPlugin.js index b558d862b6f..adfc4ec7867 100644 --- a/lib/ProgressPlugin.js +++ b/lib/ProgressPlugin.js @@ -5,25 +5,58 @@ "use strict"; -const { validate } = require("schema-utils"); -const schema = require("../schemas/plugins/ProgressPlugin.json"); const Compiler = require("./Compiler"); const MultiCompiler = require("./MultiCompiler"); const NormalModule = require("./NormalModule"); +const createSchemaValidation = require("./util/create-schema-validation"); const { contextify } = require("./util/identifier"); +/** @typedef {import("tapable").Tap} Tap */ /** @typedef {import("../declarations/plugins/ProgressPlugin").HandlerFunction} HandlerFunction */ /** @typedef {import("../declarations/plugins/ProgressPlugin").ProgressPluginArgument} ProgressPluginArgument */ /** @typedef {import("../declarations/plugins/ProgressPlugin").ProgressPluginOptions} ProgressPluginOptions */ +/** @typedef {import("./Dependency")} Dependency */ +/** @typedef {import("./Entrypoint").EntryOptions} EntryOptions */ +/** @typedef {import("./Module")} Module */ +/** @typedef {import("./logging/Logger").Logger} Logger */ -const median3 = (a, b, c) => { - return a + b + c - Math.max(a, b, c) - Math.min(a, b, c); -}; +/** + * @typedef {object} CountsData + * @property {number} modulesCount modules count + * @property {number} dependenciesCount dependencies count + */ +const validate = createSchemaValidation( + require("../schemas/plugins/ProgressPlugin.check.js"), + () => require("../schemas/plugins/ProgressPlugin.json"), + { + name: "Progress Plugin", + baseDataPath: "options" + } +); + +/** + * @param {number} a a + * @param {number} b b + * @param {number} c c + * @returns {number} median + */ +const median3 = (a, b, c) => a + b + c - Math.max(a, b, c) - Math.min(a, b, c); + +/** + * @param {boolean | null | undefined} profile need profile + * @param {Logger} logger logger + * @returns {defaultHandler} default handler + */ const createDefaultHandler = (profile, logger) => { - /** @type {{ value: string, time: number }[]} */ + /** @type {{ value: string | undefined, time: number }[]} */ const lastStateInfo = []; + /** + * @param {number} percentage percentage + * @param {string} msg message + * @param {...string} args additional arguments + */ const defaultHandler = (percentage, msg, ...args) => { if (profile) { if (percentage === 0) { @@ -43,11 +76,12 @@ const createDefaultHandler = (profile, logger) => { if (lastStateItem.value) { let reportState = lastStateItem.value; if (i > 0) { - reportState = lastStateInfo[i - 1].value + " > " + reportState; + reportState = `${lastStateInfo[i - 1].value} > ${reportState}`; } const stateMsg = `${" | ".repeat(i)}${diff} ms ${reportState}`; const d = diff; // This depends on timing so we ignore it for coverage + /* eslint-disable no-lone-blocks */ /* istanbul ignore next */ { if (d > 10000) { @@ -62,6 +96,7 @@ const createDefaultHandler = (profile, logger) => { logger.debug(stateMsg); } } + /* eslint-enable no-lone-blocks */ } if (stateItem === undefined) { lastStateInfo.length = i; @@ -88,18 +123,18 @@ const createDefaultHandler = (profile, logger) => { /** * @callback ReportProgress - * @param {number} p - * @param {...string[]} [args] + * @param {number} p percentage + * @param {...string} args additional arguments * @returns {void} */ -/** @type {WeakMap} */ +/** @type {WeakMap} */ const progressReporters = new WeakMap(); class ProgressPlugin { /** * @param {Compiler} compiler the current compiler - * @returns {ReportProgress} a progress reporter, if any + * @returns {ReportProgress | undefined} a progress reporter, if any */ static getReporter(compiler) { return progressReporters.get(compiler); @@ -115,10 +150,7 @@ class ProgressPlugin { }; } - validate(schema, options, { - name: "Progress Plugin", - baseDataPath: "options" - }); + validate(options); options = { ...ProgressPlugin.defaultOptions, ...options }; this.profile = options.profile; @@ -159,14 +191,14 @@ class ProgressPlugin { const states = compiler.compilers.map( () => /** @type {[number, ...string[]]} */ ([0]) ); - compiler.compilers.forEach((compiler, idx) => { + for (const [idx, item] of compiler.compilers.entries()) { new ProgressPlugin((p, msg, ...args) => { states[idx] = [p, msg, ...args]; let sum = 0; for (const [p] of states) sum += p; handler(sum / states.length, `[${idx}] ${msg}`, ...args); - }).apply(compiler); - }); + }).apply(item); + } } /** @@ -284,6 +316,9 @@ class ProgressPlugin { }; // only used when showActiveModules is set + /** + * @param {Module} module the module + */ const moduleBuild = module => { const ident = module.identifier(); if (ident) { @@ -293,11 +328,18 @@ class ProgressPlugin { } }; + /** + * @param {Dependency} entry entry dependency + * @param {EntryOptions} options options object + */ const entryAdd = (entry, options) => { entriesCount++; if (entriesCount < 5 || entriesCount % 10 === 0) updateThrottled(); }; + /** + * @param {Module} module the module + */ const moduleDone = module => { doneModules++; if (showActiveModules) { @@ -317,6 +359,10 @@ class ProgressPlugin { if (doneModules < 50 || doneModules % 100 === 0) updateThrottled(); }; + /** + * @param {Dependency} entry entry dependency + * @param {EntryOptions} options options object + */ const entryDone = (entry, options) => { doneEntries++; update(); @@ -326,6 +372,7 @@ class ProgressPlugin { .getCache("ProgressPlugin") .getItemCache("counts", null); + /** @type {Promise | undefined} */ let cacheGetPromise; compiler.hooks.beforeCompile.tap("ProgressPlugin", () => { @@ -348,15 +395,17 @@ class ProgressPlugin { compiler.hooks.afterCompile.tapPromise("ProgressPlugin", compilation => { if (compilation.compiler.isChild()) return Promise.resolve(); - return cacheGetPromise.then(async oldData => { - if ( - !oldData || - oldData.modulesCount !== modulesCount || - oldData.dependenciesCount !== dependenciesCount - ) { - await cache.storePromise({ modulesCount, dependenciesCount }); + return /** @type {Promise} */ (cacheGetPromise).then( + async oldData => { + if ( + !oldData || + oldData.modulesCount !== modulesCount || + oldData.dependenciesCount !== dependenciesCount + ) { + await cache.storePromise({ modulesCount, dependenciesCount }); + } } - }); + ); }); compiler.hooks.compilation.tap("ProgressPlugin", compilation => { @@ -458,10 +507,10 @@ class ProgressPlugin { afterSeal: "after seal" }; const numberOfHooks = Object.keys(hooks).length; - Object.keys(hooks).forEach((name, idx) => { - const title = hooks[name]; + for (const [idx, name] of Object.keys(hooks).entries()) { + const title = hooks[/** @type {keyof typeof hooks} */ (name)]; const percentage = (idx / numberOfHooks) * 0.25 + 0.7; - compilation.hooks[name].intercept({ + compilation.hooks[/** @type {keyof typeof hooks} */ (name)].intercept({ name: "ProgressPlugin", call() { handler(percentage, "sealing", title); @@ -485,7 +534,7 @@ class ProgressPlugin { handler(percentage, "sealing", title, tap.name); } }); - }); + } }); compiler.hooks.make.intercept({ name: "ProgressPlugin", @@ -496,6 +545,12 @@ class ProgressPlugin { handler(0.65, "building"); } }); + /** + * @param {TODO} hook hook + * @param {number} progress progress from 0 to 1 + * @param {string} category category + * @param {string} name name + */ const interceptHook = (hook, progress, category, name) => { hook.intercept({ name: "ProgressPlugin", @@ -512,6 +567,9 @@ class ProgressPlugin { error() { handler(progress, category, name); }, + /** + * @param {Tap} tap tap + */ tap(tap) { progressReporters.set(compiler, (p, ...args) => { handler(progress, category, name, tap.name, ...args); @@ -527,15 +585,14 @@ class ProgressPlugin { } }); interceptHook(compiler.cache.hooks.endIdle, 0.01, "cache", "end idle"); - compiler.hooks.initialize.intercept({ + compiler.hooks.beforeRun.intercept({ name: "ProgressPlugin", call() { handler(0, ""); } }); - interceptHook(compiler.hooks.initialize, 0.01, "setup", "initialize"); - interceptHook(compiler.hooks.beforeRun, 0.02, "setup", "before run"); - interceptHook(compiler.hooks.run, 0.03, "setup", "run"); + interceptHook(compiler.hooks.beforeRun, 0.01, "setup", "before run"); + interceptHook(compiler.hooks.run, 0.02, "setup", "run"); interceptHook(compiler.hooks.watchRun, 0.03, "setup", "watch run"); interceptHook( compiler.hooks.normalModuleFactory, @@ -607,4 +664,6 @@ ProgressPlugin.defaultOptions = { entries: true }; +ProgressPlugin.createDefaultHandler = createDefaultHandler; + module.exports = ProgressPlugin; diff --git a/lib/ProvidePlugin.js b/lib/ProvidePlugin.js index 8373389eb54..28c3ce5d590 100644 --- a/lib/ProvidePlugin.js +++ b/lib/ProvidePlugin.js @@ -5,11 +5,22 @@ "use strict"; +const { + JAVASCRIPT_MODULE_TYPE_AUTO, + JAVASCRIPT_MODULE_TYPE_DYNAMIC, + JAVASCRIPT_MODULE_TYPE_ESM +} = require("./ModuleTypeConstants"); const ConstDependency = require("./dependencies/ConstDependency"); const ProvidedDependency = require("./dependencies/ProvidedDependency"); const { approve } = require("./javascript/JavascriptParserHelpers"); +/** @typedef {import("../declarations/WebpackOptions").JavascriptParserOptions} JavascriptParserOptions */ /** @typedef {import("./Compiler")} Compiler */ +/** @typedef {import("./Dependency").DependencyLocation} DependencyLocation */ +/** @typedef {import("./javascript/JavascriptParser")} JavascriptParser */ +/** @typedef {import("./javascript/JavascriptParser").Range} Range */ + +const PLUGIN_NAME = "ProvidePlugin"; class ProvidePlugin { /** @@ -27,7 +38,7 @@ class ProvidePlugin { apply(compiler) { const definitions = this.definitions; compiler.hooks.compilation.tap( - "ProvidePlugin", + PLUGIN_NAME, (compilation, { normalModuleFactory }) => { compilation.dependencyTemplates.set( ConstDependency, @@ -41,18 +52,25 @@ class ProvidePlugin { ProvidedDependency, new ProvidedDependency.Template() ); + /** + * @param {JavascriptParser} parser the parser + * @param {JavascriptParserOptions} parserOptions options + * @returns {void} + */ const handler = (parser, parserOptions) => { - Object.keys(definitions).forEach(name => { - const request = [].concat(definitions[name]); + for (const name of Object.keys(definitions)) { + const request = + /** @type {string[]} */ + ([]).concat(definitions[name]); const splittedName = name.split("."); if (splittedName.length > 0) { - splittedName.slice(1).forEach((_, i) => { + for (const [i, _] of splittedName.slice(1).entries()) { const name = splittedName.slice(0, i + 1).join("."); - parser.hooks.canRename.for(name).tap("ProvidePlugin", approve); - }); + parser.hooks.canRename.for(name).tap(PLUGIN_NAME, approve); + } } - parser.hooks.expression.for(name).tap("ProvidePlugin", expr => { + parser.hooks.expression.for(name).tap(PLUGIN_NAME, expr => { const nameIdentifier = name.includes(".") ? `__webpack_provided_${name.replace(/\./g, "_dot_")}` : name; @@ -60,14 +78,14 @@ class ProvidePlugin { request[0], nameIdentifier, request.slice(1), - expr.range + /** @type {Range} */ (expr.range) ); - dep.loc = expr.loc; + dep.loc = /** @type {DependencyLocation} */ (expr.loc); parser.state.module.addDependency(dep); return true; }); - parser.hooks.call.for(name).tap("ProvidePlugin", expr => { + parser.hooks.call.for(name).tap(PLUGIN_NAME, expr => { const nameIdentifier = name.includes(".") ? `__webpack_provided_${name.replace(/\./g, "_dot_")}` : name; @@ -75,24 +93,24 @@ class ProvidePlugin { request[0], nameIdentifier, request.slice(1), - expr.callee.range + /** @type {Range} */ (expr.callee.range) ); - dep.loc = expr.callee.loc; + dep.loc = /** @type {DependencyLocation} */ (expr.callee.loc); parser.state.module.addDependency(dep); parser.walkExpressions(expr.arguments); return true; }); - }); + } }; normalModuleFactory.hooks.parser - .for("javascript/auto") - .tap("ProvidePlugin", handler); + .for(JAVASCRIPT_MODULE_TYPE_AUTO) + .tap(PLUGIN_NAME, handler); normalModuleFactory.hooks.parser - .for("javascript/dynamic") - .tap("ProvidePlugin", handler); + .for(JAVASCRIPT_MODULE_TYPE_DYNAMIC) + .tap(PLUGIN_NAME, handler); normalModuleFactory.hooks.parser - .for("javascript/esm") - .tap("ProvidePlugin", handler); + .for(JAVASCRIPT_MODULE_TYPE_ESM) + .tap(PLUGIN_NAME, handler); } ); } diff --git a/lib/RawModule.js b/lib/RawModule.js index dc923ce17b2..7b59dbc9140 100644 --- a/lib/RawModule.js +++ b/lib/RawModule.js @@ -7,6 +7,7 @@ const { OriginalSource, RawSource } = require("webpack-sources"); const Module = require("./Module"); +const { JAVASCRIPT_MODULE_TYPE_DYNAMIC } = require("./ModuleTypeConstants"); const makeSerializable = require("./util/makeSerializable"); /** @typedef {import("webpack-sources").Source} Source */ @@ -18,10 +19,14 @@ const makeSerializable = require("./util/makeSerializable"); /** @typedef {import("./Module").CodeGenerationContext} CodeGenerationContext */ /** @typedef {import("./Module").CodeGenerationResult} CodeGenerationResult */ /** @typedef {import("./Module").NeedBuildContext} NeedBuildContext */ +/** @typedef {import("./Module").ReadOnlyRuntimeRequirements} ReadOnlyRuntimeRequirements */ +/** @typedef {import("./Module").SourceTypes} SourceTypes */ /** @typedef {import("./RequestShortener")} RequestShortener */ /** @typedef {import("./ResolverFactory").ResolverWithOptions} ResolverWithOptions */ /** @typedef {import("./RuntimeTemplate")} RuntimeTemplate */ /** @typedef {import("./WebpackError")} WebpackError */ +/** @typedef {import("./serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */ +/** @typedef {import("./serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */ /** @typedef {import("./util/Hash")} Hash */ /** @typedef {import("./util/fs").InputFileSystem} InputFileSystem */ @@ -32,10 +37,10 @@ class RawModule extends Module { * @param {string} source source code * @param {string} identifier unique identifier * @param {string=} readableIdentifier readable identifier - * @param {ReadonlySet=} runtimeRequirements runtime requirements needed for the source code + * @param {ReadOnlyRuntimeRequirements=} runtimeRequirements runtime requirements needed for the source code */ constructor(source, identifier, readableIdentifier, runtimeRequirements) { - super("javascript/dynamic", null); + super(JAVASCRIPT_MODULE_TYPE_DYNAMIC, null); this.sourceStr = source; this.identifierStr = identifier || this.sourceStr; this.readableIdentifierStr = readableIdentifier || this.identifierStr; @@ -43,7 +48,7 @@ class RawModule extends Module { } /** - * @returns {Set} types available (do not mutate) + * @returns {SourceTypes} types available (do not mutate) */ getSourceTypes() { return TYPES; @@ -69,12 +74,14 @@ class RawModule extends Module { * @returns {string} a user readable identifier of the module */ readableIdentifier(requestShortener) { - return requestShortener.shorten(this.readableIdentifierStr); + return /** @type {string} */ ( + requestShortener.shorten(this.readableIdentifierStr) + ); } /** * @param {NeedBuildContext} context context info - * @param {function(WebpackError=, boolean=): void} callback callback function, returns true, if the module needs a rebuild + * @param {function((WebpackError | null)=, boolean=): void} callback callback function, returns true, if the module needs a rebuild * @returns {void} */ needBuild(context, callback) { @@ -124,6 +131,9 @@ class RawModule extends Module { super.updateHash(hash, context); } + /** + * @param {ObjectSerializerContext} context context + */ serialize(context) { const { write } = context; @@ -135,6 +145,9 @@ class RawModule extends Module { super.serialize(context); } + /** + * @param {ObjectDeserializerContext} context context + */ deserialize(context) { const { read } = context; diff --git a/lib/RecordIdsPlugin.js b/lib/RecordIdsPlugin.js index 4db9ac36e93..aaace61c89a 100644 --- a/lib/RecordIdsPlugin.js +++ b/lib/RecordIdsPlugin.js @@ -13,28 +13,28 @@ const identifierUtils = require("./util/identifier"); /** @typedef {import("./Module")} Module */ /** - * @typedef {Object} RecordsChunks + * @typedef {object} RecordsChunks * @property {Record=} byName * @property {Record=} bySource * @property {number[]=} usedIds */ /** - * @typedef {Object} RecordsModules + * @typedef {object} RecordsModules * @property {Record=} byIdentifier * @property {Record=} bySource * @property {number[]=} usedIds */ /** - * @typedef {Object} Records + * @typedef {object} Records * @property {RecordsChunks=} chunks * @property {RecordsModules=} modules */ class RecordIdsPlugin { /** - * @param {Object} options Options object + * @param {object} options Options object * @param {boolean=} options.portableIds true, when ids need to be portable */ constructor(options) { @@ -48,10 +48,11 @@ class RecordIdsPlugin { apply(compiler) { const portableIds = this.options.portableIds; - const makePathsRelative = identifierUtils.makePathsRelative.bindContextCache( - compiler.context, - compiler.root - ); + const makePathsRelative = + identifierUtils.makePathsRelative.bindContextCache( + compiler.context, + compiler.root + ); /** * @param {Module} module the module @@ -68,7 +69,7 @@ class RecordIdsPlugin { compilation.hooks.recordModules.tap( "RecordIdsPlugin", /** - * @param {Module[]} modules the modules array + * @param {Iterable} modules the modules array * @param {Records} records the records object * @returns {void} */ @@ -91,7 +92,7 @@ class RecordIdsPlugin { compilation.hooks.reviveModules.tap( "RecordIdsPlugin", /** - * @param {Module[]} modules the modules array + * @param {Iterable} modules the modules array * @param {Records} records the records object * @returns {void} */ @@ -165,7 +166,7 @@ class RecordIdsPlugin { compilation.hooks.recordChunks.tap( "RecordIdsPlugin", /** - * @param {Chunk[]} chunks the chunks array + * @param {Iterable} chunks the chunks array * @param {Records} records the records object * @returns {void} */ @@ -191,7 +192,7 @@ class RecordIdsPlugin { compilation.hooks.reviveChunks.tap( "RecordIdsPlugin", /** - * @param {Chunk[]} chunks the chunks array + * @param {Iterable} chunks the chunks array * @param {Records} records the records object * @returns {void} */ diff --git a/lib/RequireJsStuffPlugin.js b/lib/RequireJsStuffPlugin.js index 959841bd4da..c9acc6643dd 100644 --- a/lib/RequireJsStuffPlugin.js +++ b/lib/RequireJsStuffPlugin.js @@ -5,13 +5,21 @@ "use strict"; +const { + JAVASCRIPT_MODULE_TYPE_AUTO, + JAVASCRIPT_MODULE_TYPE_DYNAMIC +} = require("./ModuleTypeConstants"); const RuntimeGlobals = require("./RuntimeGlobals"); const ConstDependency = require("./dependencies/ConstDependency"); const { toConstantDependency } = require("./javascript/JavascriptParserHelpers"); +/** @typedef {import("../declarations/WebpackOptions").JavascriptParserOptions} JavascriptParserOptions */ /** @typedef {import("./Compiler")} Compiler */ +/** @typedef {import("./javascript/JavascriptParser")} JavascriptParser */ + +const PLUGIN_NAME = "RequireJsStuffPlugin"; module.exports = class RequireJsStuffPlugin { /** @@ -21,12 +29,17 @@ module.exports = class RequireJsStuffPlugin { */ apply(compiler) { compiler.hooks.compilation.tap( - "RequireJsStuffPlugin", + PLUGIN_NAME, (compilation, { normalModuleFactory }) => { compilation.dependencyTemplates.set( ConstDependency, new ConstDependency.Template() ); + /** + * @param {JavascriptParser} parser the parser + * @param {JavascriptParserOptions} parserOptions options + * @returns {void} + */ const handler = (parser, parserOptions) => { if ( parserOptions.requireJs === undefined || @@ -37,27 +50,21 @@ module.exports = class RequireJsStuffPlugin { parser.hooks.call .for("require.config") - .tap( - "RequireJsStuffPlugin", - toConstantDependency(parser, "undefined") - ); + .tap(PLUGIN_NAME, toConstantDependency(parser, "undefined")); parser.hooks.call .for("requirejs.config") - .tap( - "RequireJsStuffPlugin", - toConstantDependency(parser, "undefined") - ); + .tap(PLUGIN_NAME, toConstantDependency(parser, "undefined")); parser.hooks.expression .for("require.version") .tap( - "RequireJsStuffPlugin", + PLUGIN_NAME, toConstantDependency(parser, JSON.stringify("0.0.0")) ); parser.hooks.expression .for("requirejs.onError") .tap( - "RequireJsStuffPlugin", + PLUGIN_NAME, toConstantDependency( parser, RuntimeGlobals.uncaughtErrorHandler, @@ -66,11 +73,11 @@ module.exports = class RequireJsStuffPlugin { ); }; normalModuleFactory.hooks.parser - .for("javascript/auto") - .tap("RequireJsStuffPlugin", handler); + .for(JAVASCRIPT_MODULE_TYPE_AUTO) + .tap(PLUGIN_NAME, handler); normalModuleFactory.hooks.parser - .for("javascript/dynamic") - .tap("RequireJsStuffPlugin", handler); + .for(JAVASCRIPT_MODULE_TYPE_DYNAMIC) + .tap(PLUGIN_NAME, handler); } ); } diff --git a/lib/ResolverFactory.js b/lib/ResolverFactory.js index f9a580927c4..9651c6a73e8 100644 --- a/lib/ResolverFactory.js +++ b/lib/ResolverFactory.js @@ -13,14 +13,16 @@ const { resolveByProperty } = require("./util/cleverMerge"); +/** @typedef {import("enhanced-resolve").ResolveContext} ResolveContext */ /** @typedef {import("enhanced-resolve").ResolveOptions} ResolveOptions */ +/** @typedef {import("enhanced-resolve").ResolveRequest} ResolveRequest */ /** @typedef {import("enhanced-resolve").Resolver} Resolver */ /** @typedef {import("../declarations/WebpackOptions").ResolveOptions} WebpackResolveOptions */ /** @typedef {import("../declarations/WebpackOptions").ResolvePluginInstance} ResolvePluginInstance */ /** @typedef {WebpackResolveOptions & {dependencyType?: string, resolveToContext?: boolean }} ResolveOptionsWithDependencyType */ /** - * @typedef {Object} WithOptions + * @typedef {object} WithOptions * @property {function(Partial): ResolverWithOptions} withOptions create a resolver with additional/different options */ @@ -42,9 +44,9 @@ const convertToResolveOptions = resolveOptionsWithDepType => { ...remaining, plugins: plugins && - /** @type {ResolvePluginInstance[]} */ (plugins.filter( - item => item !== "..." - )) + /** @type {ResolvePluginInstance[]} */ ( + plugins.filter(item => item !== "...") + ) }; if (!partialOptions.fileSystem) { @@ -53,16 +55,21 @@ const convertToResolveOptions = resolveOptionsWithDepType => { ); } // These weird types validate that we checked all non-optional properties - const options = /** @type {Partial & Pick} */ (partialOptions); + const options = + /** @type {Partial & Pick} */ ( + partialOptions + ); return removeOperations( - resolveByProperty(options, "byDependency", dependencyType) + resolveByProperty(options, "byDependency", dependencyType), + // Keep the `unsafeCache` because it can be a `Proxy` + ["unsafeCache"] ); }; /** - * @typedef {Object} ResolverCache - * @property {WeakMap} direct + * @typedef {object} ResolverCache + * @property {WeakMap} direct * @property {Map} stringified */ @@ -124,9 +131,9 @@ module.exports = class ResolverFactory { const resolveOptions = convertToResolveOptions( this.hooks.resolveOptions.for(type).call(resolveOptionsWithDepType) ); - const resolver = /** @type {ResolverWithOptions} */ (Factory.createResolver( - resolveOptions - )); + const resolver = /** @type {ResolverWithOptions} */ ( + Factory.createResolver(resolveOptions) + ); if (!resolver) { throw new Error("No resolver created"); } diff --git a/lib/RuntimeGlobals.js b/lib/RuntimeGlobals.js index 7eb35b68880..7d201f6267a 100644 --- a/lib/RuntimeGlobals.js +++ b/lib/RuntimeGlobals.js @@ -8,219 +8,260 @@ /** * the internal require function */ -exports.require = "__webpack_require__"; +module.exports.require = "__webpack_require__"; /** * access to properties of the internal require function/object */ -exports.requireScope = "__webpack_require__.*"; +module.exports.requireScope = "__webpack_require__.*"; /** * the internal exports object */ -exports.exports = "__webpack_exports__"; +module.exports.exports = "__webpack_exports__"; /** * top-level this need to be the exports object */ -exports.thisAsExports = "top-level-this-exports"; +module.exports.thisAsExports = "top-level-this-exports"; /** * runtime need to return the exports of the last entry module */ -exports.returnExportsFromRuntime = "return-exports-from-runtime"; +module.exports.returnExportsFromRuntime = "return-exports-from-runtime"; /** * the internal module object */ -exports.module = "module"; +module.exports.module = "module"; /** * the internal module object */ -exports.moduleId = "module.id"; +module.exports.moduleId = "module.id"; /** * the internal module object */ -exports.moduleLoaded = "module.loaded"; +module.exports.moduleLoaded = "module.loaded"; /** * the bundle public path */ -exports.publicPath = "__webpack_require__.p"; +module.exports.publicPath = "__webpack_require__.p"; /** * the module id of the entry point */ -exports.entryModuleId = "__webpack_require__.s"; +module.exports.entryModuleId = "__webpack_require__.s"; /** * the module cache */ -exports.moduleCache = "__webpack_require__.c"; +module.exports.moduleCache = "__webpack_require__.c"; /** * the module functions */ -exports.moduleFactories = "__webpack_require__.m"; +module.exports.moduleFactories = "__webpack_require__.m"; /** * the module functions, with only write access */ -exports.moduleFactoriesAddOnly = "__webpack_require__.m (add only)"; +module.exports.moduleFactoriesAddOnly = "__webpack_require__.m (add only)"; /** * the chunk ensure function */ -exports.ensureChunk = "__webpack_require__.e"; +module.exports.ensureChunk = "__webpack_require__.e"; /** * an object with handlers to ensure a chunk */ -exports.ensureChunkHandlers = "__webpack_require__.f"; +module.exports.ensureChunkHandlers = "__webpack_require__.f"; /** * a runtime requirement if ensureChunkHandlers should include loading of chunk needed for entries */ -exports.ensureChunkIncludeEntries = "__webpack_require__.f (include entries)"; +module.exports.ensureChunkIncludeEntries = + "__webpack_require__.f (include entries)"; /** * the chunk prefetch function */ -exports.prefetchChunk = "__webpack_require__.E"; +module.exports.prefetchChunk = "__webpack_require__.E"; /** * an object with handlers to prefetch a chunk */ -exports.prefetchChunkHandlers = "__webpack_require__.F"; +module.exports.prefetchChunkHandlers = "__webpack_require__.F"; /** * the chunk preload function */ -exports.preloadChunk = "__webpack_require__.G"; +module.exports.preloadChunk = "__webpack_require__.G"; /** * an object with handlers to preload a chunk */ -exports.preloadChunkHandlers = "__webpack_require__.H"; +module.exports.preloadChunkHandlers = "__webpack_require__.H"; /** * the exported property define getters function */ -exports.definePropertyGetters = "__webpack_require__.d"; +module.exports.definePropertyGetters = "__webpack_require__.d"; /** * define compatibility on export */ -exports.makeNamespaceObject = "__webpack_require__.r"; +module.exports.makeNamespaceObject = "__webpack_require__.r"; /** * create a fake namespace object */ -exports.createFakeNamespaceObject = "__webpack_require__.t"; +module.exports.createFakeNamespaceObject = "__webpack_require__.t"; /** * compatibility get default export */ -exports.compatGetDefaultExport = "__webpack_require__.n"; +module.exports.compatGetDefaultExport = "__webpack_require__.n"; /** * harmony module decorator */ -exports.harmonyModuleDecorator = "__webpack_require__.hmd"; +module.exports.harmonyModuleDecorator = "__webpack_require__.hmd"; /** * node.js module decorator */ -exports.nodeModuleDecorator = "__webpack_require__.nmd"; +module.exports.nodeModuleDecorator = "__webpack_require__.nmd"; /** * the webpack hash */ -exports.getFullHash = "__webpack_require__.h"; +module.exports.getFullHash = "__webpack_require__.h"; /** * an object containing all installed WebAssembly.Instance export objects keyed by module id */ -exports.wasmInstances = "__webpack_require__.w"; +module.exports.wasmInstances = "__webpack_require__.w"; /** * instantiate a wasm instance from module exports object, id, hash and importsObject */ -exports.instantiateWasm = "__webpack_require__.v"; +module.exports.instantiateWasm = "__webpack_require__.v"; /** * the uncaught error handler for the webpack runtime */ -exports.uncaughtErrorHandler = "__webpack_require__.oe"; +module.exports.uncaughtErrorHandler = "__webpack_require__.oe"; /** * the script nonce */ -exports.scriptNonce = "__webpack_require__.nc"; +module.exports.scriptNonce = "__webpack_require__.nc"; /** * function to load a script tag. * Arguments: (url: string, done: (event) => void), key?: string | number, chunkId?: string | number) => void * done function is called when loading has finished or timeout occurred. - * It will attach to existing script tags with data-webpack == key or src == url. + * It will attach to existing script tags with data-webpack == uniqueName + ":" + key or src == url. */ -exports.loadScript = "__webpack_require__.l"; +module.exports.loadScript = "__webpack_require__.l"; + +/** + * function to promote a string to a TrustedScript using webpack's Trusted + * Types policy + * Arguments: (script: string) => TrustedScript + */ +module.exports.createScript = "__webpack_require__.ts"; + +/** + * function to promote a string to a TrustedScriptURL using webpack's Trusted + * Types policy + * Arguments: (url: string) => TrustedScriptURL + */ +module.exports.createScriptUrl = "__webpack_require__.tu"; + +/** + * function to return webpack's Trusted Types policy + * Arguments: () => TrustedTypePolicy + */ +module.exports.getTrustedTypesPolicy = "__webpack_require__.tt"; + +/** + * a flag when a chunk has a fetch priority + */ +module.exports.hasFetchPriority = "has fetch priority"; /** * the chunk name of the chunk with the runtime */ -exports.chunkName = "__webpack_require__.cn"; +module.exports.chunkName = "__webpack_require__.cn"; /** * the runtime id of the current runtime */ -exports.runtimeId = "__webpack_require__.j"; +module.exports.runtimeId = "__webpack_require__.j"; /** * the filename of the script part of the chunk */ -exports.getChunkScriptFilename = "__webpack_require__.u"; +module.exports.getChunkScriptFilename = "__webpack_require__.u"; + +/** + * the filename of the css part of the chunk + */ +module.exports.getChunkCssFilename = "__webpack_require__.k"; + +/** + * a flag when a module/chunk/tree has css modules + */ +module.exports.hasCssModules = "has css modules"; /** * the filename of the script part of the hot update chunk */ -exports.getChunkUpdateScriptFilename = "__webpack_require__.hu"; +module.exports.getChunkUpdateScriptFilename = "__webpack_require__.hu"; + +/** + * the filename of the css part of the hot update chunk + */ +module.exports.getChunkUpdateCssFilename = "__webpack_require__.hk"; /** * startup signal from runtime * This will be called when the runtime chunk has been loaded. */ -exports.startup = "__webpack_require__.x"; +module.exports.startup = "__webpack_require__.x"; /** * @deprecated * creating a default startup function with the entry modules */ -exports.startupNoDefault = "__webpack_require__.x (no default handler)"; +module.exports.startupNoDefault = "__webpack_require__.x (no default handler)"; /** * startup signal from runtime but only used to add logic after the startup */ -exports.startupOnlyAfter = "__webpack_require__.x (only after)"; +module.exports.startupOnlyAfter = "__webpack_require__.x (only after)"; /** * startup signal from runtime but only used to add sync logic before the startup */ -exports.startupOnlyBefore = "__webpack_require__.x (only before)"; +module.exports.startupOnlyBefore = "__webpack_require__.x (only before)"; /** * global callback functions for installing chunks */ -exports.chunkCallback = "webpackChunk"; +module.exports.chunkCallback = "webpackChunk"; /** * method to startup an entrypoint with needed chunks. * Signature: (moduleId: Id, chunkIds: Id[]) => any. * Returns the exports of the module or a Promise */ -exports.startupEntrypoint = "__webpack_require__.X"; +module.exports.startupEntrypoint = "__webpack_require__.X"; /** * register deferred code, which will run when certain @@ -230,101 +271,106 @@ exports.startupEntrypoint = "__webpack_require__.X"; * When (priority & 1) it will wait for all other handlers with lower priority to * be executed before itself is executed */ -exports.onChunksLoaded = "__webpack_require__.O"; +module.exports.onChunksLoaded = "__webpack_require__.O"; /** * method to install a chunk that was loaded somehow * Signature: ({ id, ids, modules, runtime }) => void */ -exports.externalInstallChunk = "__webpack_require__.C"; +module.exports.externalInstallChunk = "__webpack_require__.C"; /** * interceptor for module executions */ -exports.interceptModuleExecution = "__webpack_require__.i"; +module.exports.interceptModuleExecution = "__webpack_require__.i"; /** * the global object */ -exports.global = "__webpack_require__.g"; +module.exports.global = "__webpack_require__.g"; /** * an object with all share scopes */ -exports.shareScopeMap = "__webpack_require__.S"; +module.exports.shareScopeMap = "__webpack_require__.S"; /** * The sharing init sequence function (only runs once per share scope). * Has one argument, the name of the share scope. * Creates a share scope if not existing */ -exports.initializeSharing = "__webpack_require__.I"; +module.exports.initializeSharing = "__webpack_require__.I"; /** * The current scope when getting a module from a remote */ -exports.currentRemoteGetScope = "__webpack_require__.R"; +module.exports.currentRemoteGetScope = "__webpack_require__.R"; /** * the filename of the HMR manifest */ -exports.getUpdateManifestFilename = "__webpack_require__.hmrF"; +module.exports.getUpdateManifestFilename = "__webpack_require__.hmrF"; /** * function downloading the update manifest */ -exports.hmrDownloadManifest = "__webpack_require__.hmrM"; +module.exports.hmrDownloadManifest = "__webpack_require__.hmrM"; /** * array with handler functions to download chunk updates */ -exports.hmrDownloadUpdateHandlers = "__webpack_require__.hmrC"; +module.exports.hmrDownloadUpdateHandlers = "__webpack_require__.hmrC"; /** * object with all hmr module data for all modules */ -exports.hmrModuleData = "__webpack_require__.hmrD"; +module.exports.hmrModuleData = "__webpack_require__.hmrD"; /** * array with handler functions when a module should be invalidated */ -exports.hmrInvalidateModuleHandlers = "__webpack_require__.hmrI"; +module.exports.hmrInvalidateModuleHandlers = "__webpack_require__.hmrI"; + +/** + * the prefix for storing state of runtime modules when hmr is enabled + */ +module.exports.hmrRuntimeStatePrefix = "__webpack_require__.hmrS"; /** * the AMD define function */ -exports.amdDefine = "__webpack_require__.amdD"; +module.exports.amdDefine = "__webpack_require__.amdD"; /** * the AMD options */ -exports.amdOptions = "__webpack_require__.amdO"; +module.exports.amdOptions = "__webpack_require__.amdO"; /** * the System polyfill object */ -exports.system = "__webpack_require__.System"; +module.exports.system = "__webpack_require__.System"; /** * the shorthand for Object.prototype.hasOwnProperty * using of it decreases the compiled bundle size */ -exports.hasOwnProperty = "__webpack_require__.o"; +module.exports.hasOwnProperty = "__webpack_require__.o"; /** * the System.register context object */ -exports.systemContext = "__webpack_require__.y"; +module.exports.systemContext = "__webpack_require__.y"; /** * the baseURI of current document */ -exports.baseURI = "__webpack_require__.b"; +module.exports.baseURI = "__webpack_require__.b"; /** * a RelativeURL class when relative URLs are used */ -exports.relativeUrl = "__webpack_require__.U"; +module.exports.relativeUrl = "__webpack_require__.U"; /** * Creates an async module. The body function must be a async function. @@ -338,4 +384,4 @@ exports.relativeUrl = "__webpack_require__.U"; * hasAwaitAfterDependencies?: boolean * ) => void */ -exports.asyncModule = "__webpack_require__.a"; +module.exports.asyncModule = "__webpack_require__.a"; diff --git a/lib/RuntimeModule.js b/lib/RuntimeModule.js index a0c21e287da..34ca2c19b88 100644 --- a/lib/RuntimeModule.js +++ b/lib/RuntimeModule.js @@ -8,6 +8,7 @@ const { RawSource } = require("webpack-sources"); const OriginalSource = require("webpack-sources").OriginalSource; const Module = require("./Module"); +const { WEBPACK_MODULE_TYPE_RUNTIME } = require("./ModuleTypeConstants"); /** @typedef {import("webpack-sources").Source} Source */ /** @typedef {import("../declarations/WebpackOptions").WebpackOptionsNormalized} WebpackOptions */ @@ -18,13 +19,14 @@ const Module = require("./Module"); /** @typedef {import("./Module").CodeGenerationContext} CodeGenerationContext */ /** @typedef {import("./Module").CodeGenerationResult} CodeGenerationResult */ /** @typedef {import("./Module").NeedBuildContext} NeedBuildContext */ +/** @typedef {import("./Module").SourceTypes} SourceTypes */ /** @typedef {import("./RequestShortener")} RequestShortener */ /** @typedef {import("./ResolverFactory").ResolverWithOptions} ResolverWithOptions */ /** @typedef {import("./WebpackError")} WebpackError */ /** @typedef {import("./util/Hash")} Hash */ /** @typedef {import("./util/fs").InputFileSystem} InputFileSystem */ -const TYPES = new Set(["runtime"]); +const TYPES = new Set([WEBPACK_MODULE_TYPE_RUNTIME]); class RuntimeModule extends Module { /** @@ -32,28 +34,33 @@ class RuntimeModule extends Module { * @param {number=} stage an optional stage */ constructor(name, stage = 0) { - super("runtime"); + super(WEBPACK_MODULE_TYPE_RUNTIME); this.name = name; this.stage = stage; this.buildMeta = {}; this.buildInfo = {}; - /** @type {Compilation} */ + /** @type {Compilation | undefined} */ this.compilation = undefined; - /** @type {Chunk} */ + /** @type {Chunk | undefined} */ this.chunk = undefined; + /** @type {ChunkGraph | undefined} */ + this.chunkGraph = undefined; this.fullHash = false; - /** @type {string} */ + this.dependentHash = false; + /** @type {string | undefined | null} */ this._cachedGeneratedCode = undefined; } /** * @param {Compilation} compilation the compilation * @param {Chunk} chunk the chunk + * @param {ChunkGraph} chunkGraph the chunk graph * @returns {void} */ - attach(compilation, chunk) { + attach(compilation, chunk, chunkGraph = compilation.chunkGraph) { this.compilation = compilation; this.chunk = chunk; + this.chunkGraph = chunkGraph; } /** @@ -73,7 +80,7 @@ class RuntimeModule extends Module { /** * @param {NeedBuildContext} context context info - * @param {function(WebpackError=, boolean=): void} callback callback function, returns true, if the module needs a rebuild + * @param {function((WebpackError | null)=, boolean=): void} callback callback function, returns true, if the module needs a rebuild * @returns {void} */ needBuild(context, callback) { @@ -103,21 +110,21 @@ class RuntimeModule extends Module { hash.update(this.name); hash.update(`${this.stage}`); try { - if (this.fullHash) { + if (this.fullHash || this.dependentHash) { // Do not use getGeneratedCode here, because i. e. compilation hash might be not // ready at this point. We will cache it later instead. - hash.update(this.generate()); + hash.update(/** @type {string} */ (this.generate())); } else { - hash.update(this.getGeneratedCode()); + hash.update(/** @type {string} */ (this.getGeneratedCode())); } } catch (err) { - hash.update(err.message); + hash.update(/** @type {Error} */ (err).message); } super.updateHash(hash, context); } /** - * @returns {Set} types available (do not mutate) + * @returns {SourceTypes} types available (do not mutate) */ getSourceTypes() { return TYPES; @@ -132,7 +139,7 @@ class RuntimeModule extends Module { const generatedCode = this.getGeneratedCode(); if (generatedCode) { sources.set( - "runtime", + WEBPACK_MODULE_TYPE_RUNTIME, this.useSourceMap || this.useSimpleSourceMap ? new OriginalSource(generatedCode, this.identifier()) : new RawSource(generatedCode) @@ -152,7 +159,7 @@ class RuntimeModule extends Module { try { const source = this.getGeneratedCode(); return source ? source.length : 0; - } catch (e) { + } catch (_err) { return 0; } } @@ -160,7 +167,7 @@ class RuntimeModule extends Module { /* istanbul ignore next */ /** * @abstract - * @returns {string} runtime code + * @returns {string | null} runtime code */ generate() { const AbstractMethodError = require("./AbstractMethodError"); @@ -168,7 +175,7 @@ class RuntimeModule extends Module { } /** - * @returns {string} runtime code + * @returns {string | null} runtime code */ getGeneratedCode() { if (this._cachedGeneratedCode) { diff --git a/lib/RuntimePlugin.js b/lib/RuntimePlugin.js index b358841e65b..5d9bcefff49 100644 --- a/lib/RuntimePlugin.js +++ b/lib/RuntimePlugin.js @@ -6,21 +6,27 @@ "use strict"; const RuntimeGlobals = require("./RuntimeGlobals"); +const { getChunkFilenameTemplate } = require("./css/CssModulesPlugin"); const RuntimeRequirementsDependency = require("./dependencies/RuntimeRequirementsDependency"); const JavascriptModulesPlugin = require("./javascript/JavascriptModulesPlugin"); const AsyncModuleRuntimeModule = require("./runtime/AsyncModuleRuntimeModule"); const AutoPublicPathRuntimeModule = require("./runtime/AutoPublicPathRuntimeModule"); +const BaseUriRuntimeModule = require("./runtime/BaseUriRuntimeModule"); const CompatGetDefaultExportRuntimeModule = require("./runtime/CompatGetDefaultExportRuntimeModule"); const CompatRuntimeModule = require("./runtime/CompatRuntimeModule"); const CreateFakeNamespaceObjectRuntimeModule = require("./runtime/CreateFakeNamespaceObjectRuntimeModule"); +const CreateScriptRuntimeModule = require("./runtime/CreateScriptRuntimeModule"); +const CreateScriptUrlRuntimeModule = require("./runtime/CreateScriptUrlRuntimeModule"); const DefinePropertyGettersRuntimeModule = require("./runtime/DefinePropertyGettersRuntimeModule"); const EnsureChunkRuntimeModule = require("./runtime/EnsureChunkRuntimeModule"); const GetChunkFilenameRuntimeModule = require("./runtime/GetChunkFilenameRuntimeModule"); const GetMainFilenameRuntimeModule = require("./runtime/GetMainFilenameRuntimeModule"); +const GetTrustedTypesPolicyRuntimeModule = require("./runtime/GetTrustedTypesPolicyRuntimeModule"); const GlobalRuntimeModule = require("./runtime/GlobalRuntimeModule"); const HasOwnPropertyRuntimeModule = require("./runtime/HasOwnPropertyRuntimeModule"); const LoadScriptRuntimeModule = require("./runtime/LoadScriptRuntimeModule"); const MakeNamespaceObjectRuntimeModule = require("./runtime/MakeNamespaceObjectRuntimeModule"); +const NonceRuntimeModule = require("./runtime/NonceRuntimeModule"); const OnChunksLoadedRuntimeModule = require("./runtime/OnChunksLoadedRuntimeModule"); const PublicPathRuntimeModule = require("./runtime/PublicPathRuntimeModule"); const RelativeUrlRuntimeModule = require("./runtime/RelativeUrlRuntimeModule"); @@ -29,15 +35,21 @@ const SystemContextRuntimeModule = require("./runtime/SystemContextRuntimeModule const ShareRuntimeModule = require("./sharing/ShareRuntimeModule"); const StringXor = require("./util/StringXor"); +/** @typedef {import("../declarations/WebpackOptions").LibraryOptions} LibraryOptions */ +/** @typedef {import("../declarations/WebpackOptions").OutputNormalized} OutputNormalized */ /** @typedef {import("./Chunk")} Chunk */ /** @typedef {import("./Compiler")} Compiler */ /** @typedef {import("./Module")} Module */ +/** @typedef {import("./TemplatedPathPlugin").TemplatePath} TemplatePath */ const GLOBALS_ON_REQUIRE = [ RuntimeGlobals.chunkName, RuntimeGlobals.runtimeId, RuntimeGlobals.compatGetDefaultExport, RuntimeGlobals.createFakeNamespaceObject, + RuntimeGlobals.createScript, + RuntimeGlobals.createScriptUrl, + RuntimeGlobals.getTrustedTypesPolicy, RuntimeGlobals.definePropertyGetters, RuntimeGlobals.ensureChunk, RuntimeGlobals.entryModuleId, @@ -51,6 +63,7 @@ const GLOBALS_ON_REQUIRE = [ RuntimeGlobals.publicPath, RuntimeGlobals.baseURI, RuntimeGlobals.relativeUrl, + // TODO webpack 6 - rename to nonce, because we use it for CSS too RuntimeGlobals.scriptNonce, RuntimeGlobals.uncaughtErrorHandler, RuntimeGlobals.asyncModule, @@ -89,6 +102,19 @@ class RuntimePlugin { */ apply(compiler) { compiler.hooks.compilation.tap("RuntimePlugin", compilation => { + const globalChunkLoading = compilation.outputOptions.chunkLoading; + /** + * @param {Chunk} chunk chunk + * @returns {boolean} true, when chunk loading is disabled for the chunk + */ + const isChunkLoadingDisabledForChunk = chunk => { + const options = chunk.getEntryOptions(); + const chunkLoading = + options && options.chunkLoading !== undefined + ? options.chunkLoading + : globalChunkLoading; + return chunkLoading === false; + }; compilation.dependencyTemplates.set( RuntimeRequirementsDependency, new RuntimeRequirementsDependency.Template() @@ -106,7 +132,8 @@ class RuntimePlugin { }); } for (const req of Object.keys(TREE_DEPENDENCIES)) { - const deps = TREE_DEPENDENCIES[req]; + const deps = + TREE_DEPENDENCIES[/** @type {keyof TREE_DEPENDENCIES} */ (req)]; compilation.hooks.runtimeRequirementInTree .for(req) .tap("RuntimePlugin", (chunk, set) => { @@ -114,7 +141,8 @@ class RuntimePlugin { }); } for (const req of Object.keys(MODULE_DEPENDENCIES)) { - const deps = MODULE_DEPENDENCIES[req]; + const deps = + MODULE_DEPENDENCIES[/** @type {keyof MODULE_DEPENDENCIES} */ (req)]; compilation.hooks.runtimeRequirementInModule .for(req) .tap("RuntimePlugin", (chunk, set) => { @@ -176,14 +204,19 @@ class RuntimePlugin { .for(RuntimeGlobals.publicPath) .tap("RuntimePlugin", (chunk, set) => { const { outputOptions } = compilation; - const { publicPath, scriptType } = outputOptions; + const { publicPath: globalPublicPath, scriptType } = outputOptions; + const entryOptions = chunk.getEntryOptions(); + const publicPath = + entryOptions && entryOptions.publicPath !== undefined + ? entryOptions.publicPath + : globalPublicPath; if (publicPath === "auto") { const module = new AutoPublicPathRuntimeModule(); if (scriptType !== "module") set.add(RuntimeGlobals.global); compilation.addRuntimeModule(chunk, module); } else { - const module = new PublicPathRuntimeModule(); + const module = new PublicPathRuntimeModule(publicPath); if ( typeof publicPath !== "string" || @@ -211,7 +244,14 @@ class RuntimePlugin { compilation.hooks.runtimeRequirementInTree .for(RuntimeGlobals.systemContext) .tap("RuntimePlugin", chunk => { - if (compilation.outputOptions.library.type === "system") { + const entryOptions = chunk.getEntryOptions(); + const libraryType = + entryOptions && entryOptions.library !== undefined + ? entryOptions.library.type + : /** @type {LibraryOptions} */ + (compilation.outputOptions.library).type; + + if (libraryType === "system") { compilation.addRuntimeModule( chunk, new SystemContextRuntimeModule() @@ -237,21 +277,49 @@ class RuntimePlugin { "javascript", RuntimeGlobals.getChunkScriptFilename, chunk => - chunk.filenameTemplate || - (chunk.canBeInitial() - ? compilation.outputOptions.filename - : compilation.outputOptions.chunkFilename), + /** @type {TemplatePath} */ + ( + chunk.filenameTemplate || + (chunk.canBeInitial() + ? compilation.outputOptions.filename + : compilation.outputOptions.chunkFilename) + ), false ) ); return true; }); + compilation.hooks.runtimeRequirementInTree + .for(RuntimeGlobals.getChunkCssFilename) + .tap("RuntimePlugin", (chunk, set) => { + if ( + typeof compilation.outputOptions.cssChunkFilename === "string" && + /\[(full)?hash(:\d+)?\]/.test( + compilation.outputOptions.cssChunkFilename + ) + ) { + set.add(RuntimeGlobals.getFullHash); + } + compilation.addRuntimeModule( + chunk, + new GetChunkFilenameRuntimeModule( + "css", + "css", + RuntimeGlobals.getChunkCssFilename, + chunk => + getChunkFilenameTemplate(chunk, compilation.outputOptions), + set.has(RuntimeGlobals.hmrDownloadUpdateHandlers) + ) + ); + return true; + }); compilation.hooks.runtimeRequirementInTree .for(RuntimeGlobals.getChunkUpdateScriptFilename) .tap("RuntimePlugin", (chunk, set) => { if ( /\[(full)?hash(:\d+)?\]/.test( - compilation.outputOptions.hotUpdateChunkFilename + /** @type {NonNullable} */ + (compilation.outputOptions.hotUpdateChunkFilename) ) ) set.add(RuntimeGlobals.getFullHash); @@ -261,7 +329,9 @@ class RuntimePlugin { "javascript", "javascript update", RuntimeGlobals.getChunkUpdateScriptFilename, - c => compilation.outputOptions.hotUpdateChunkFilename, + c => + /** @type {NonNullable} */ + (compilation.outputOptions.hotUpdateChunkFilename), true ) ); @@ -272,7 +342,8 @@ class RuntimePlugin { .tap("RuntimePlugin", (chunk, set) => { if ( /\[(full)?hash(:\d+)?\]/.test( - compilation.outputOptions.hotUpdateMainFilename + /** @type {NonNullable} */ + (compilation.outputOptions.hotUpdateMainFilename) ) ) { set.add(RuntimeGlobals.getFullHash); @@ -282,7 +353,8 @@ class RuntimePlugin { new GetMainFilenameRuntimeModule( "update manifest", RuntimeGlobals.getUpdateManifestFilename, - compilation.outputOptions.hotUpdateMainFilename + /** @type {NonNullable} */ + (compilation.outputOptions.hotUpdateMainFilename) ) ); return true; @@ -314,7 +386,47 @@ class RuntimePlugin { compilation.hooks.runtimeRequirementInTree .for(RuntimeGlobals.loadScript) .tap("RuntimePlugin", (chunk, set) => { - compilation.addRuntimeModule(chunk, new LoadScriptRuntimeModule()); + const withCreateScriptUrl = Boolean( + compilation.outputOptions.trustedTypes + ); + if (withCreateScriptUrl) { + set.add(RuntimeGlobals.createScriptUrl); + } + const withFetchPriority = set.has(RuntimeGlobals.hasFetchPriority); + compilation.addRuntimeModule( + chunk, + new LoadScriptRuntimeModule(withCreateScriptUrl, withFetchPriority) + ); + return true; + }); + compilation.hooks.runtimeRequirementInTree + .for(RuntimeGlobals.createScript) + .tap("RuntimePlugin", (chunk, set) => { + if (compilation.outputOptions.trustedTypes) { + set.add(RuntimeGlobals.getTrustedTypesPolicy); + } + compilation.addRuntimeModule(chunk, new CreateScriptRuntimeModule()); + return true; + }); + compilation.hooks.runtimeRequirementInTree + .for(RuntimeGlobals.createScriptUrl) + .tap("RuntimePlugin", (chunk, set) => { + if (compilation.outputOptions.trustedTypes) { + set.add(RuntimeGlobals.getTrustedTypesPolicy); + } + compilation.addRuntimeModule( + chunk, + new CreateScriptUrlRuntimeModule() + ); + return true; + }); + compilation.hooks.runtimeRequirementInTree + .for(RuntimeGlobals.getTrustedTypesPolicy) + .tap("RuntimePlugin", (chunk, set) => { + compilation.addRuntimeModule( + chunk, + new GetTrustedTypesPolicyRuntimeModule(set) + ); return true; }); compilation.hooks.runtimeRequirementInTree @@ -332,6 +444,20 @@ class RuntimePlugin { ); return true; }); + compilation.hooks.runtimeRequirementInTree + .for(RuntimeGlobals.baseURI) + .tap("RuntimePlugin", chunk => { + if (isChunkLoadingDisabledForChunk(chunk)) { + compilation.addRuntimeModule(chunk, new BaseUriRuntimeModule()); + return true; + } + }); + compilation.hooks.runtimeRequirementInTree + .for(RuntimeGlobals.scriptNonce) + .tap("RuntimePlugin", chunk => { + compilation.addRuntimeModule(chunk, new NonceRuntimeModule()); + return true; + }); // TODO webpack 6: remove CompatRuntimeModule compilation.hooks.additionalTreeRuntimeRequirements.tap( "RuntimePlugin", diff --git a/lib/RuntimeTemplate.js b/lib/RuntimeTemplate.js index 4199e9d05cb..e0861814621 100644 --- a/lib/RuntimeTemplate.js +++ b/lib/RuntimeTemplate.js @@ -13,12 +13,18 @@ const compileBooleanMatcher = require("./util/compileBooleanMatcher"); const propertyAccess = require("./util/propertyAccess"); const { forEachRuntime, subtractRuntime } = require("./util/runtime"); +/** @typedef {import("../declarations/WebpackOptions").Environment} Environment */ /** @typedef {import("../declarations/WebpackOptions").OutputNormalized} OutputOptions */ /** @typedef {import("./AsyncDependenciesBlock")} AsyncDependenciesBlock */ +/** @typedef {import("./Chunk")} Chunk */ /** @typedef {import("./ChunkGraph")} ChunkGraph */ +/** @typedef {import("./CodeGenerationResults")} CodeGenerationResults */ +/** @typedef {import("./CodeGenerationResults").CodeGenerationResult} CodeGenerationResult */ /** @typedef {import("./Compilation")} Compilation */ /** @typedef {import("./Dependency")} Dependency */ /** @typedef {import("./Module")} Module */ +/** @typedef {import("./Module").BuildMeta} BuildMeta */ +/** @typedef {import("./Module").RuntimeRequirements} RuntimeRequirements */ /** @typedef {import("./ModuleGraph")} ModuleGraph */ /** @typedef {import("./RequestShortener")} RequestShortener */ /** @typedef {import("./util/runtime").RuntimeSpec} RuntimeSpec */ @@ -28,27 +34,49 @@ const { forEachRuntime, subtractRuntime } = require("./util/runtime"); * @param {ChunkGraph} chunkGraph the chunk graph * @returns {string} error message */ -const noModuleIdErrorMessage = (module, chunkGraph) => { - return `Module ${module.identifier()} has no id assigned. +const noModuleIdErrorMessage = ( + module, + chunkGraph +) => `Module ${module.identifier()} has no id assigned. This should not happen. It's in these chunks: ${ - Array.from( - chunkGraph.getModuleChunksIterable(module), - c => c.name || c.id || c.debugId - ).join(", ") || "none" - } (If module is in no chunk this indicates a bug in some chunk/module optimization logic) + Array.from( + chunkGraph.getModuleChunksIterable(module), + c => c.name || c.id || c.debugId + ).join(", ") || "none" +} (If module is in no chunk this indicates a bug in some chunk/module optimization logic) Module has these incoming connections: ${Array.from( - chunkGraph.moduleGraph.getIncomingConnections(module), - connection => - `\n - ${ - connection.originModule && connection.originModule.identifier() - } ${connection.dependency && connection.dependency.type} ${ - (connection.explanations && - Array.from(connection.explanations).join(", ")) || - "" - }` - ).join("")}`; -}; + chunkGraph.moduleGraph.getIncomingConnections(module), + connection => + `\n - ${ + connection.originModule && connection.originModule.identifier() + } ${connection.dependency && connection.dependency.type} ${ + (connection.explanations && + Array.from(connection.explanations).join(", ")) || + "" + }` +).join("")}`; + +/** + * @param {string | undefined} definition global object definition + * @returns {string | undefined} save to use global object + */ +function getGlobalObject(definition) { + if (!definition) return definition; + const trimmed = definition.trim(); + + if ( + // identifier, we do not need real identifier regarding ECMAScript/Unicode + /^[_\p{L}][_0-9\p{L}]*$/iu.test(trimmed) || + // iife + // call expression + // expression in parentheses + /^([_\p{L}][_0-9\p{L}]*)?\(.*\)$/iu.test(trimmed) + ) + return trimmed; + + return `Object(${trimmed})`; +} class RuntimeTemplate { /** @@ -60,6 +88,13 @@ class RuntimeTemplate { this.compilation = compilation; this.outputOptions = outputOptions || {}; this.requestShortener = requestShortener; + this.globalObject = + /** @type {string} */ + (getGlobalObject(outputOptions.globalObject)); + this.contentHashReplacement = "X".repeat( + /** @type {NonNullable} */ + (outputOptions.hashDigestLength) + ); } isIIFE() { @@ -71,78 +106,209 @@ class RuntimeTemplate { } supportsConst() { - return this.outputOptions.environment.const; + return /** @type {Environment} */ (this.outputOptions.environment).const; } supportsArrowFunction() { - return this.outputOptions.environment.arrowFunction; + return /** @type {Environment} */ (this.outputOptions.environment) + .arrowFunction; + } + + supportsAsyncFunction() { + return /** @type {Environment} */ (this.outputOptions.environment) + .asyncFunction; + } + + supportsOptionalChaining() { + return /** @type {Environment} */ (this.outputOptions.environment) + .optionalChaining; } supportsForOf() { - return this.outputOptions.environment.forOf; + return /** @type {Environment} */ (this.outputOptions.environment).forOf; } supportsDestructuring() { - return this.outputOptions.environment.destructuring; + return /** @type {Environment} */ (this.outputOptions.environment) + .destructuring; } supportsBigIntLiteral() { - return this.outputOptions.environment.bigIntLiteral; + return /** @type {Environment} */ (this.outputOptions.environment) + .bigIntLiteral; } supportsDynamicImport() { - return this.outputOptions.environment.dynamicImport; + return /** @type {Environment} */ (this.outputOptions.environment) + .dynamicImport; } supportsEcmaScriptModuleSyntax() { - return this.outputOptions.environment.module; + return /** @type {Environment} */ (this.outputOptions.environment).module; } supportTemplateLiteral() { - // TODO - return false; + return /** @type {Environment} */ (this.outputOptions.environment) + .templateLiteral; + } + + supportNodePrefixForCoreModules() { + return /** @type {Environment} */ (this.outputOptions.environment) + .nodePrefixForCoreModules; } + /** + * @param {string} returnValue return value + * @param {string} args arguments + * @returns {string} returning function + */ returningFunction(returnValue, args = "") { return this.supportsArrowFunction() ? `(${args}) => (${returnValue})` : `function(${args}) { return ${returnValue}; }`; } + /** + * @param {string} args arguments + * @param {string | string[]} body body + * @returns {string} basic function + */ basicFunction(args, body) { return this.supportsArrowFunction() ? `(${args}) => {\n${Template.indent(body)}\n}` : `function(${args}) {\n${Template.indent(body)}\n}`; } + /** + * @param {Array} args args + * @returns {string} result expression + */ + concatenation(...args) { + const len = args.length; + + if (len === 2) return this._es5Concatenation(args); + if (len === 0) return '""'; + if (len === 1) { + return typeof args[0] === "string" + ? JSON.stringify(args[0]) + : `"" + ${args[0].expr}`; + } + if (!this.supportTemplateLiteral()) return this._es5Concatenation(args); + + // cost comparison between template literal and concatenation: + // both need equal surroundings: `xxx` vs "xxx" + // template literal has constant cost of 3 chars for each expression + // es5 concatenation has cost of 3 + n chars for n expressions in row + // when a es5 concatenation ends with an expression it reduces cost by 3 + // when a es5 concatenation starts with an single expression it reduces cost by 3 + // e. g. `${a}${b}${c}` (3*3 = 9) is longer than ""+a+b+c ((3+3)-3 = 3) + // e. g. `x${a}x${b}x${c}x` (3*3 = 9) is shorter than "x"+a+"x"+b+"x"+c+"x" (4+4+4 = 12) + + let templateCost = 0; + let concatenationCost = 0; + + let lastWasExpr = false; + for (const arg of args) { + const isExpr = typeof arg !== "string"; + if (isExpr) { + templateCost += 3; + concatenationCost += lastWasExpr ? 1 : 4; + } + lastWasExpr = isExpr; + } + if (lastWasExpr) concatenationCost -= 3; + if (typeof args[0] !== "string" && typeof args[1] === "string") + concatenationCost -= 3; + + if (concatenationCost <= templateCost) return this._es5Concatenation(args); + + return `\`${args + .map(arg => (typeof arg === "string" ? arg : `\${${arg.expr}}`)) + .join("")}\``; + } + + /** + * @param {Array} args args (len >= 2) + * @returns {string} result expression + * @private + */ + _es5Concatenation(args) { + const str = args + .map(arg => (typeof arg === "string" ? JSON.stringify(arg) : arg.expr)) + .join(" + "); + + // when the first two args are expression, we need to prepend "" + to force string + // concatenation instead of number addition. + return typeof args[0] !== "string" && typeof args[1] !== "string" + ? `"" + ${str}` + : str; + } + + /** + * @param {string} expression expression + * @param {string} args arguments + * @returns {string} expression function code + */ expressionFunction(expression, args = "") { return this.supportsArrowFunction() ? `(${args}) => (${expression})` : `function(${args}) { ${expression}; }`; } + /** + * @returns {string} empty function code + */ emptyFunction() { return this.supportsArrowFunction() ? "x => {}" : "function() {}"; } + /** + * @param {string[]} items items + * @param {string} value value + * @returns {string} destructure array code + */ destructureArray(items, value) { return this.supportsDestructuring() ? `var [${items.join(", ")}] = ${value};` : Template.asString( items.map((item, i) => `var ${item} = ${value}[${i}];`) - ); + ); } + /** + * @param {string[]} items items + * @param {string} value value + * @returns {string} destructure object code + */ + destructureObject(items, value) { + return this.supportsDestructuring() + ? `var {${items.join(", ")}} = ${value};` + : Template.asString( + items.map(item => `var ${item} = ${value}${propertyAccess([item])};`) + ); + } + + /** + * @param {string} args arguments + * @param {string} body body + * @returns {string} IIFE code + */ iife(args, body) { return `(${this.basicFunction(args, body)})()`; } + /** + * @param {string} variable variable + * @param {string} array array + * @param {string | string[]} body body + * @returns {string} for each code + */ forEach(variable, array, body) { return this.supportsForOf() ? `for(const ${variable} of ${array}) {\n${Template.indent(body)}\n}` : `${array}.forEach(function(${variable}) {\n${Template.indent( body - )}\n});`; + )}\n});`; } /** @@ -170,10 +336,9 @@ class RuntimeTemplate { } if (!content) return ""; if (this.outputOptions.pathinfo) { - return Template.toComment(content) + " "; - } else { - return Template.toNormalComment(content) + " "; + return `${Template.toComment(content)} `; } + return `${Template.toNormalComment(content)} `; } /** @@ -229,10 +394,10 @@ class RuntimeTemplate { } /** - * @param {Object} options options object + * @param {object} options options object * @param {ChunkGraph} options.chunkGraph the chunk graph * @param {Module} options.module the module - * @param {string} options.request the request that should be printed as comment + * @param {string=} options.request the request that should be printed as comment * @param {string=} options.idExpr expression to use as id expression * @param {"expression" | "promise" | "statements"} options.type which kind of code should be returned * @returns {string} the code @@ -243,15 +408,14 @@ class RuntimeTemplate { moduleId === null ? JSON.stringify("Module is not available (weak dependency)") : idExpr - ? `"Module '" + ${idExpr} + "' is not available (weak dependency)"` - : JSON.stringify( - `Module '${moduleId}' is not available (weak dependency)` - ); - const comment = request ? Template.toNormalComment(request) + " " : ""; - const errorStatements = - `var e = new Error(${errorMessage}); ` + - comment + - "e.code = 'MODULE_NOT_FOUND'; throw e;"; + ? `"Module '" + ${idExpr} + "' is not available (weak dependency)"` + : JSON.stringify( + `Module '${moduleId}' is not available (weak dependency)` + ); + const comment = request ? `${Template.toNormalComment(request)} ` : ""; + const errorStatements = `var e = new Error(${errorMessage}); ${ + comment + }e.code = 'MODULE_NOT_FOUND'; throw e;`; switch (type) { case "statements": return errorStatements; @@ -266,10 +430,10 @@ class RuntimeTemplate { } /** - * @param {Object} options options object + * @param {object} options options object * @param {Module} options.module the module * @param {ChunkGraph} options.chunkGraph the chunk graph - * @param {string} options.request the request that should be printed as comment + * @param {string=} options.request the request that should be printed as comment * @param {boolean=} options.weak if the dependency is weak (will create a nice error message) * @returns {string} the expression */ @@ -295,12 +459,12 @@ class RuntimeTemplate { } /** - * @param {Object} options options object - * @param {Module} options.module the module + * @param {object} options options object + * @param {Module | null} options.module the module * @param {ChunkGraph} options.chunkGraph the chunk graph - * @param {string} options.request the request that should be printed as comment + * @param {string=} options.request the request that should be printed as comment * @param {boolean=} options.weak if the dependency is weak (will create a nice error message) - * @param {Set} options.runtimeRequirements if set, will be filled with runtime requirements + * @param {RuntimeRequirements} options.runtimeRequirements if set, will be filled with runtime requirements * @returns {string} the expression */ moduleRaw({ module, chunkGraph, request, weak, runtimeRequirements }) { @@ -329,7 +493,7 @@ class RuntimeTemplate { ); } runtimeRequirements.add(RuntimeGlobals.require); - return `__webpack_require__(${this.moduleId({ + return `${RuntimeGlobals.require}(${this.moduleId({ module, chunkGraph, request, @@ -338,12 +502,12 @@ class RuntimeTemplate { } /** - * @param {Object} options options object - * @param {Module} options.module the module + * @param {object} options options object + * @param {Module | null} options.module the module * @param {ChunkGraph} options.chunkGraph the chunk graph * @param {string} options.request the request that should be printed as comment * @param {boolean=} options.weak if the dependency is weak (will create a nice error message) - * @param {Set} options.runtimeRequirements if set, will be filled with runtime requirements + * @param {RuntimeRequirements} options.runtimeRequirements if set, will be filled with runtime requirements * @returns {string} the expression */ moduleExports({ module, chunkGraph, request, weak, runtimeRequirements }) { @@ -357,13 +521,13 @@ class RuntimeTemplate { } /** - * @param {Object} options options object + * @param {object} options options object * @param {Module} options.module the module * @param {ChunkGraph} options.chunkGraph the chunk graph * @param {string} options.request the request that should be printed as comment * @param {boolean=} options.strict if the current module is in strict esm mode * @param {boolean=} options.weak if the dependency is weak (will create a nice error message) - * @param {Set} options.runtimeRequirements if set, will be filled with runtime requirements + * @param {RuntimeRequirements} options.runtimeRequirements if set, will be filled with runtime requirements * @returns {string} the expression */ moduleNamespace({ @@ -426,7 +590,7 @@ class RuntimeTemplate { } /** - * @param {Object} options options object + * @param {object} options options object * @param {ChunkGraph} options.chunkGraph the chunk graph * @param {AsyncDependenciesBlock=} options.block the current dependencies block * @param {Module} options.module the module @@ -434,7 +598,7 @@ class RuntimeTemplate { * @param {string} options.message a message for the comment * @param {boolean=} options.strict if the current module is in strict esm mode * @param {boolean=} options.weak if the dependency is weak (will create a nice error message) - * @param {Set} options.runtimeRequirements if set, will be filled with runtime requirements + * @param {RuntimeRequirements} options.runtimeRequirements if set, will be filled with runtime requirements * @returns {string} the promise expression */ moduleNamespacePromise({ @@ -525,7 +689,7 @@ class RuntimeTemplate { )})`; } else { runtimeRequirements.add(RuntimeGlobals.require); - appending = `.then(__webpack_require__.bind(__webpack_require__, ${comment}${idExpr}))`; + appending = `.then(${RuntimeGlobals.require}.bind(${RuntimeGlobals.require}, ${comment}${idExpr}))`; } break; case "dynamic": @@ -551,7 +715,7 @@ class RuntimeTemplate { )})`; } else { runtimeRequirements.add(RuntimeGlobals.require); - appending = `.then(__webpack_require__.bind(__webpack_require__, ${comment}${idExpr}))`; + appending = `.then(${RuntimeGlobals.require}.bind(${RuntimeGlobals.require}, ${comment}${idExpr}))`; } appending += `.then(${this.returningFunction( `${RuntimeGlobals.createFakeNamespaceObject}(m, ${fakeType})`, @@ -566,7 +730,7 @@ class RuntimeTemplate { `${header}return ${returnExpression};` )})`; } else { - appending = `.then(${RuntimeGlobals.createFakeNamespaceObject}.bind(__webpack_require__, ${comment}${idExpr}, ${fakeType}))`; + appending = `.then(${RuntimeGlobals.createFakeNamespaceObject}.bind(${RuntimeGlobals.require}, ${comment}${idExpr}, ${fakeType}))`; } } break; @@ -576,11 +740,11 @@ class RuntimeTemplate { } /** - * @param {Object} options options object + * @param {object} options options object * @param {ChunkGraph} options.chunkGraph the chunk graph * @param {RuntimeSpec=} options.runtime runtime for which this code will be generated * @param {RuntimeSpec | boolean=} options.runtimeCondition only execute the statement in some runtimes - * @param {Set} options.runtimeRequirements if set, will be filled with runtime requirements + * @param {RuntimeRequirements} options.runtimeRequirements if set, will be filled with runtime requirements * @returns {string} expression */ runtimeConditionExpression({ @@ -594,12 +758,16 @@ class RuntimeTemplate { /** @type {Set} */ const positiveRuntimeIds = new Set(); forEachRuntime(runtimeCondition, runtime => - positiveRuntimeIds.add(`${chunkGraph.getRuntimeId(runtime)}`) + positiveRuntimeIds.add( + `${chunkGraph.getRuntimeId(/** @type {string} */ (runtime))}` + ) ); /** @type {Set} */ const negativeRuntimeIds = new Set(); forEachRuntime(subtractRuntime(runtime, runtimeCondition), runtime => - negativeRuntimeIds.add(`${chunkGraph.getRuntimeId(runtime)}`) + negativeRuntimeIds.add( + `${chunkGraph.getRuntimeId(/** @type {string} */ (runtime))}` + ) ); runtimeRequirements.add(RuntimeGlobals.runtimeId); return compileBooleanMatcher.fromLists( @@ -609,8 +777,7 @@ class RuntimeTemplate { } /** - * - * @param {Object} options options object + * @param {object} options options object * @param {boolean=} options.update whether a new variable should be created or the existing one updated * @param {Module} options.module the module * @param {ChunkGraph} options.chunkGraph the chunk graph @@ -618,7 +785,7 @@ class RuntimeTemplate { * @param {string} options.importVar name of the import variable * @param {Module} options.originModule module in which the statement is emitted * @param {boolean=} options.weak true, if this is a weak dependency - * @param {Set} options.runtimeRequirements if set, will be filled with runtime requirements + * @param {RuntimeRequirements} options.runtimeRequirements if set, will be filled with runtime requirements * @returns {[string, string]} the import statement and the compat statement */ importStatement({ @@ -670,10 +837,11 @@ class RuntimeTemplate { const exportsType = module.getExportsType( chunkGraph.moduleGraph, - originModule.buildMeta.strictHarmonyModule + /** @type {BuildMeta} */ + (originModule.buildMeta).strictHarmonyModule ); runtimeRequirements.add(RuntimeGlobals.require); - const importContent = `/* harmony import */ ${optDeclaration}${importVar} = __webpack_require__(${moduleId});\n`; + const importContent = `/* harmony import */ ${optDeclaration}${importVar} = ${RuntimeGlobals.require}(${moduleId});\n`; if (exportsType === "dynamic") { runtimeRequirements.add(RuntimeGlobals.compatGetDefaultExport); @@ -686,7 +854,7 @@ class RuntimeTemplate { } /** - * @param {Object} options options + * @param {object} options options * @param {ModuleGraph} options.moduleGraph the module graph * @param {Module} options.module the module * @param {string} options.request the request @@ -694,12 +862,12 @@ class RuntimeTemplate { * @param {Module} options.originModule the origin module * @param {boolean|undefined} options.asiSafe true, if location is safe for ASI, a bracket can be emitted * @param {boolean} options.isCall true, if expression will be called - * @param {boolean} options.callContext when false, call context will not be preserved + * @param {boolean | null} options.callContext when false, call context will not be preserved * @param {boolean} options.defaultInterop when true and accessing the default exports, interop code will be generated * @param {string} options.importVar the identifier name of the import variable - * @param {InitFragment[]} options.initFragments init fragments will be added here + * @param {InitFragment[]} options.initFragments init fragments will be added here * @param {RuntimeSpec} options.runtime runtime for which this code will be generated - * @param {Set} options.runtimeRequirements if set, will be filled with runtime requirements + * @param {RuntimeRequirements} options.runtimeRequirements if set, will be filled with runtime requirements * @returns {string} expression */ exportFromImport({ @@ -727,7 +895,8 @@ class RuntimeTemplate { } const exportsType = module.getExportsType( moduleGraph, - originModule.buildMeta.strictHarmonyModule + /** @type {BuildMeta} */ + (originModule.buildMeta).strictHarmonyModule ); if (defaultInterop) { @@ -736,13 +905,13 @@ class RuntimeTemplate { case "dynamic": if (isCall) { return `${importVar}_default()${propertyAccess(exportName, 1)}`; - } else { - return asiSafe - ? `(${importVar}_default()${propertyAccess(exportName, 1)})` - : asiSafe === false + } + return asiSafe + ? `(${importVar}_default()${propertyAccess(exportName, 1)})` + : asiSafe === false ? `;(${importVar}_default()${propertyAccess(exportName, 1)})` : `${importVar}_default.a${propertyAccess(exportName, 1)}`; - } + case "default-only": case "default-with-named": exportName = exportName.slice(1); @@ -750,10 +919,10 @@ class RuntimeTemplate { } } else if (exportName.length > 0) { if (exportsType === "default-only") { - return ( - "/* non-default import from non-esm module */undefined" + - propertyAccess(exportName, 1) - ); + return `/* non-default import from non-esm module */undefined${propertyAccess( + exportName, + 1 + )}`; } else if ( exportsType !== "namespace" && exportName[0] === "__esModule" @@ -792,27 +961,26 @@ class RuntimeTemplate { } const comment = equals(used, exportName) ? "" - : Template.toNormalComment(propertyAccess(exportName)) + " "; + : `${Template.toNormalComment(propertyAccess(exportName))} `; const access = `${importVar}${comment}${propertyAccess(used)}`; if (isCall && callContext === false) { return asiSafe ? `(0,${access})` : asiSafe === false - ? `;(0,${access})` - : `Object(${access})`; + ? `;(0,${access})` + : `/*#__PURE__*/Object(${access})`; } return access; - } else { - return importVar; } + return importVar; } /** - * @param {Object} options options - * @param {AsyncDependenciesBlock} options.block the async block + * @param {object} options options + * @param {AsyncDependenciesBlock | undefined} options.block the async block * @param {string} options.message the message * @param {ChunkGraph} options.chunkGraph the chunk graph - * @param {Set} options.runtimeRequirements if set, will be filled with runtime requirements + * @param {RuntimeRequirements} options.runtimeRequirements if set, will be filled with runtime requirements * @returns {string} expression */ blockPromise({ block, message, chunkGraph, runtimeRequirements }) { @@ -839,24 +1007,45 @@ class RuntimeTemplate { if (chunks.length === 1) { const chunkId = JSON.stringify(chunks[0].id); runtimeRequirements.add(RuntimeGlobals.ensureChunk); - return `${RuntimeGlobals.ensureChunk}(${comment}${chunkId})`; + + const fetchPriority = chunkGroup.options.fetchPriority; + + if (fetchPriority) { + runtimeRequirements.add(RuntimeGlobals.hasFetchPriority); + } + + return `${RuntimeGlobals.ensureChunk}(${comment}${chunkId}${ + fetchPriority ? `, ${JSON.stringify(fetchPriority)}` : "" + })`; } else if (chunks.length > 0) { runtimeRequirements.add(RuntimeGlobals.ensureChunk); + + const fetchPriority = chunkGroup.options.fetchPriority; + + if (fetchPriority) { + runtimeRequirements.add(RuntimeGlobals.hasFetchPriority); + } + + /** + * @param {Chunk} chunk chunk + * @returns {string} require chunk id code + */ const requireChunkId = chunk => - `${RuntimeGlobals.ensureChunk}(${JSON.stringify(chunk.id)})`; + `${RuntimeGlobals.ensureChunk}(${JSON.stringify(chunk.id)}${ + fetchPriority ? `, ${JSON.stringify(fetchPriority)}` : "" + })`; return `Promise.all(${comment.trim()}[${chunks .map(requireChunkId) .join(", ")}])`; - } else { - return `Promise.resolve(${comment.trim()})`; } + return `Promise.resolve(${comment.trim()})`; } /** - * @param {Object} options options + * @param {object} options options * @param {AsyncDependenciesBlock} options.block the async block * @param {ChunkGraph} options.chunkGraph the chunk graph - * @param {Set} options.runtimeRequirements if set, will be filled with runtime requirements + * @param {RuntimeRequirements} options.runtimeRequirements if set, will be filled with runtime requirements * @param {string=} options.request request string used originally * @returns {string} expression */ @@ -885,10 +1074,10 @@ class RuntimeTemplate { } /** - * @param {Object} options options + * @param {object} options options * @param {Dependency} options.dependency the dependency * @param {ChunkGraph} options.chunkGraph the chunk graph - * @param {Set} options.runtimeRequirements if set, will be filled with runtime requirements + * @param {RuntimeRequirements} options.runtimeRequirements if set, will be filled with runtime requirements * @param {string=} options.request request string used originally * @returns {string} expression */ @@ -906,9 +1095,9 @@ class RuntimeTemplate { } /** - * @param {Object} options options + * @param {object} options options * @param {string} options.exportsArgument the name of the exports object - * @param {Set} options.runtimeRequirements if set, will be filled with runtime requirements + * @param {RuntimeRequirements} options.runtimeRequirements if set, will be filled with runtime requirements * @returns {string} statement */ defineEsModuleFlagStatement({ exportsArgument, runtimeRequirements }) { @@ -916,6 +1105,27 @@ class RuntimeTemplate { runtimeRequirements.add(RuntimeGlobals.exports); return `${RuntimeGlobals.makeNamespaceObject}(${exportsArgument});\n`; } + + /** + * @param {object} options options object + * @param {Module} options.module the module + * @param {RuntimeSpec=} options.runtime runtime + * @param {CodeGenerationResults} options.codeGenerationResults the code generation results + * @returns {string} the url of the asset + */ + assetUrl({ runtime, module, codeGenerationResults }) { + if (!module) { + return "data:,"; + } + const codeGen = codeGenerationResults.get(module, runtime); + const data = /** @type {NonNullable} */ ( + codeGen.data + ); + const url = data.get("url"); + if (url) return url.toString(); + const assetPath = data.get("assetPathForCss"); + return assetPath; + } } module.exports = RuntimeTemplate; diff --git a/lib/SelfModuleFactory.js b/lib/SelfModuleFactory.js index b2430a44097..3a10333e20c 100644 --- a/lib/SelfModuleFactory.js +++ b/lib/SelfModuleFactory.js @@ -5,11 +5,23 @@ "use strict"; +/** @typedef {import("./ModuleFactory").ModuleFactoryCreateData} ModuleFactoryCreateData */ +/** @typedef {import("./ModuleFactory").ModuleFactoryResult} ModuleFactoryResult */ +/** @typedef {import("./ModuleGraph")} ModuleGraph */ + class SelfModuleFactory { + /** + * @param {ModuleGraph} moduleGraph module graph + */ constructor(moduleGraph) { this.moduleGraph = moduleGraph; } + /** + * @param {ModuleFactoryCreateData} data data object + * @param {function((Error | null)=, ModuleFactoryResult=): void} callback callback + * @returns {void} + */ create(data, callback) { const module = this.moduleGraph.getParentModule(data.dependencies[0]); callback(null, { diff --git a/lib/SizeFormatHelpers.js b/lib/SizeFormatHelpers.js index 51dceeacda8..4c6a748f0eb 100644 --- a/lib/SizeFormatHelpers.js +++ b/lib/SizeFormatHelpers.js @@ -9,7 +9,7 @@ * @param {number} size the size in bytes * @returns {string} the formatted size */ -exports.formatSize = size => { +module.exports.formatSize = size => { if (typeof size !== "number" || Number.isNaN(size) === true) { return "unknown size"; } @@ -21,7 +21,5 @@ exports.formatSize = size => { const abbreviations = ["bytes", "KiB", "MiB", "GiB"]; const index = Math.floor(Math.log(size) / Math.log(1024)); - return `${+(size / Math.pow(1024, index)).toPrecision(3)} ${ - abbreviations[index] - }`; + return `${Number((size / 1024 ** index).toPrecision(3))} ${abbreviations[index]}`; }; diff --git a/lib/SourceMapDevToolModuleOptionsPlugin.js b/lib/SourceMapDevToolModuleOptionsPlugin.js index 616bb6f69d6..e7d722e12a8 100644 --- a/lib/SourceMapDevToolModuleOptionsPlugin.js +++ b/lib/SourceMapDevToolModuleOptionsPlugin.js @@ -7,9 +7,13 @@ const JavascriptModulesPlugin = require("./javascript/JavascriptModulesPlugin"); +/** @typedef {import("../declarations/plugins/SourceMapDevToolPlugin").SourceMapDevToolPluginOptions} SourceMapDevToolPluginOptions */ /** @typedef {import("./Compilation")} Compilation */ class SourceMapDevToolModuleOptionsPlugin { + /** + * @param {SourceMapDevToolPluginOptions} options options + */ constructor(options) { this.options = options; } diff --git a/lib/SourceMapDevToolPlugin.js b/lib/SourceMapDevToolPlugin.js index 4b26e1cb3e4..a9dd2f6ba66 100644 --- a/lib/SourceMapDevToolPlugin.js +++ b/lib/SourceMapDevToolPlugin.js @@ -6,30 +6,40 @@ "use strict"; const asyncLib = require("neo-async"); -const { validate } = require("schema-utils"); const { ConcatSource, RawSource } = require("webpack-sources"); const Compilation = require("./Compilation"); const ModuleFilenameHelpers = require("./ModuleFilenameHelpers"); const ProgressPlugin = require("./ProgressPlugin"); const SourceMapDevToolModuleOptionsPlugin = require("./SourceMapDevToolModuleOptionsPlugin"); +const createSchemaValidation = require("./util/create-schema-validation"); const createHash = require("./util/createHash"); const { relative, dirname } = require("./util/fs"); -const { absolutify } = require("./util/identifier"); +const { makePathsAbsolute } = require("./util/identifier"); -const schema = require("../schemas/plugins/SourceMapDevToolPlugin.json"); - -/** @typedef {import("source-map").RawSourceMap} SourceMap */ /** @typedef {import("webpack-sources").MapOptions} MapOptions */ /** @typedef {import("webpack-sources").Source} Source */ /** @typedef {import("../declarations/plugins/SourceMapDevToolPlugin").SourceMapDevToolPluginOptions} SourceMapDevToolPluginOptions */ /** @typedef {import("./Cache").Etag} Etag */ /** @typedef {import("./CacheFacade").ItemCacheFacade} ItemCacheFacade */ /** @typedef {import("./Chunk")} Chunk */ +/** @typedef {import("./Compilation").Asset} Asset */ /** @typedef {import("./Compilation").AssetInfo} AssetInfo */ /** @typedef {import("./Compiler")} Compiler */ /** @typedef {import("./Module")} Module */ +/** @typedef {import("./NormalModule").SourceMap} SourceMap */ +/** @typedef {import("./TemplatedPathPlugin").TemplatePath} TemplatePath */ /** @typedef {import("./util/Hash")} Hash */ - +/** @typedef {import("./util/createHash").Algorithm} Algorithm */ +/** @typedef {import("./util/fs").OutputFileSystem} OutputFileSystem */ + +const validate = createSchemaValidation( + require("../schemas/plugins/SourceMapDevToolPlugin.check.js"), + () => require("../schemas/plugins/SourceMapDevToolPlugin.json"), + { + name: "SourceMap DevTool Plugin", + baseDataPath: "options" + } +); /** * @typedef {object} SourceMapTask * @property {Source} asset @@ -41,14 +51,30 @@ const schema = require("../schemas/plugins/SourceMapDevToolPlugin.json"); * @property {ItemCacheFacade} cacheItem cache item */ +const METACHARACTERS_REGEXP = /[-[\]\\/{}()*+?.^$|]/g; +const CONTENT_HASH_DETECT_REGEXP = /\[contenthash(:\w+)?\]/; +const CSS_AND_JS_MODULE_EXTENSIONS_REGEXP = /\.((c|m)?js|css)($|\?)/i; +const CSS_EXTENSION_DETECT_REGEXP = /\.css($|\?)/i; +const MAP_URL_COMMENT_REGEXP = /\[map\]/g; +const URL_COMMENT_REGEXP = /\[url\]/g; +const URL_FORMATTING_REGEXP = /^\n\/\/(.*)$/; + +/** + * Reset's .lastIndex of stateful Regular Expressions + * For when `test` or `exec` is called on them + * @param {RegExp} regexp Stateful Regular Expression to be reset + * @returns {void} + */ +const resetRegexpState = regexp => { + regexp.lastIndex = -1; +}; + /** * Escapes regular expression metacharacters * @param {string} str String to quote * @returns {string} Escaped string */ -const quoteMeta = str => { - return str.replace(/[-[\]\\/{}()*+?.^$|]/g, "\\$&"); -}; +const quoteMeta = str => str.replace(METACHARACTERS_REGEXP, "\\$&"); /** * Creating {@link SourceMapTask} for given file @@ -83,9 +109,9 @@ const getTaskForFile = ( source = asset.source(); } if (!sourceMap || typeof source !== "string") return; - const context = compilation.options.context; + const context = /** @type {string} */ (compilation.options.context); const root = compilation.compiler.root; - const cachedAbsolutify = absolutify.bindContextCache(context, root); + const cachedAbsolutify = makePathsAbsolute.bindContextCache(context, root); const modules = sourceMap.sources.map(source => { if (!source.startsWith("webpack://")) return source; source = cachedAbsolutify(source.slice(10)); @@ -110,18 +136,15 @@ class SourceMapDevToolPlugin { * @throws {Error} throws error, if got more than 1 arguments */ constructor(options = {}) { - validate(schema, options, { - name: "SourceMap DevTool Plugin", - baseDataPath: "options" - }); + validate(options); - /** @type {string | false} */ - this.sourceMapFilename = options.filename; - /** @type {string | false} */ + this.sourceMapFilename = /** @type {string | false} */ (options.filename); + /** @type {false | TemplatePath}} */ this.sourceMappingURLComment = options.append === false ? false - : options.append || "\n//# source" + "MappingURL=[url]"; + : // eslint-disable-next-line no-useless-concat + options.append || "\n//# source" + "MappingURL=[url]"; /** @type {string | Function} */ this.moduleFilenameTemplate = options.moduleFilenameTemplate || "webpack://[namespace]/[resourcePath]"; @@ -141,7 +164,9 @@ class SourceMapDevToolPlugin { * @returns {void} */ apply(compiler) { - const outputFs = compiler.outputFileSystem; + const outputFs = /** @type {OutputFileSystem} */ ( + compiler.outputFileSystem + ); const sourceMapFilename = this.sourceMapFilename; const sourceMappingURLComment = this.sourceMappingURLComment; const moduleFilenameTemplate = this.moduleFilenameTemplate; @@ -149,7 +174,7 @@ class SourceMapDevToolPlugin { const fallbackModuleFilenameTemplate = this.fallbackModuleFilenameTemplate; const requestShortener = compiler.requestShortener; const options = this.options; - options.test = options.test || /\.(m?js|css)($|\?)/i; + options.test = options.test || CSS_AND_JS_MODULE_EXTENSIONS_REGEXP; const matchObject = ModuleFilenameHelpers.matchObject.bind( undefined, @@ -196,7 +221,7 @@ class SourceMapDevToolPlugin { } } - reportProgress(0.0); + reportProgress(0); /** @type {SourceMapTask[]} */ const tasks = []; let fileIndex = 0; @@ -204,7 +229,9 @@ class SourceMapDevToolPlugin { asyncLib.each( files, (file, callback) => { - const asset = compilation.getAsset(file); + const asset = + /** @type {Readonly} */ + (compilation.getAsset(file)); if (asset.info.related && asset.info.related.sourceMap) { fileIndex++; return callback(); @@ -283,18 +310,28 @@ class SourceMapDevToolPlugin { for (let idx = 0; idx < modules.length; idx++) { const module = modules[idx]; + + if ( + typeof module === "string" && + /^(data|https?):/.test(module) + ) { + moduleToSourceNameMapping.set(module, module); + continue; + } + if (!moduleToSourceNameMapping.get(module)) { moduleToSourceNameMapping.set( module, ModuleFilenameHelpers.createFilename( module, { - moduleFilenameTemplate: moduleFilenameTemplate, - namespace: namespace + moduleFilenameTemplate, + namespace }, { requestShortener, - chunkGraph + chunkGraph, + hashFunction: compilation.outputOptions.hashFunction } ) ); @@ -339,7 +376,9 @@ class SourceMapDevToolPlugin { // find modules with conflicting source names for (let idx = 0; idx < allModules.length; idx++) { const module = allModules[idx]; - let sourceName = moduleToSourceNameMapping.get(module); + let sourceName = + /** @type {string} */ + (moduleToSourceNameMapping.get(module)); let hasName = conflictDetectionSet.has(sourceName); if (!hasName) { conflictDetectionSet.add(sourceName); @@ -351,11 +390,12 @@ class SourceMapDevToolPlugin { module, { moduleFilenameTemplate: fallbackModuleFilenameTemplate, - namespace: namespace + namespace }, { requestShortener, - chunkGraph + chunkGraph, + hashFunction: compilation.outputOptions.hashFunction } ); hasName = usedNamesSet.has(sourceName); @@ -396,7 +436,7 @@ class SourceMapDevToolPlugin { const moduleFilenames = modules.map(m => moduleToSourceNameMapping.get(m) ); - sourceMap.sources = moduleFilenames; + sourceMap.sources = /** @type {string[]} */ (moduleFilenames); if (options.noSources) { sourceMap.sourcesContent = undefined; } @@ -404,42 +444,52 @@ class SourceMapDevToolPlugin { sourceMap.file = file; const usesContentHash = sourceMapFilename && - /\[contenthash(:\w+)?\]/.test(sourceMapFilename); + CONTENT_HASH_DETECT_REGEXP.test(sourceMapFilename); + + resetRegexpState(CONTENT_HASH_DETECT_REGEXP); // If SourceMap and asset uses contenthash, avoid a circular dependency by hiding hash in `file` if (usesContentHash && task.assetInfo.contenthash) { const contenthash = task.assetInfo.contenthash; - let pattern; - if (Array.isArray(contenthash)) { - pattern = contenthash.map(quoteMeta).join("|"); - } else { - pattern = quoteMeta(contenthash); - } + const pattern = Array.isArray(contenthash) + ? contenthash.map(quoteMeta).join("|") + : quoteMeta(contenthash); sourceMap.file = sourceMap.file.replace( new RegExp(pattern, "g"), m => "x".repeat(m.length) ); } - /** @type {string | false} */ + /** @type {false | TemplatePath} */ let currentSourceMappingURLComment = sourceMappingURLComment; + const cssExtensionDetected = + CSS_EXTENSION_DETECT_REGEXP.test(file); + resetRegexpState(CSS_EXTENSION_DETECT_REGEXP); if ( currentSourceMappingURLComment !== false && - /\.css($|\?)/i.test(file) + typeof currentSourceMappingURLComment !== "function" && + cssExtensionDetected ) { - currentSourceMappingURLComment = currentSourceMappingURLComment.replace( - /^\n\/\/(.*)$/, - "\n/*$1*/" - ); + currentSourceMappingURLComment = + currentSourceMappingURLComment.replace( + URL_FORMATTING_REGEXP, + "\n/*$1*/" + ); } const sourceMapString = JSON.stringify(sourceMap); if (sourceMapFilename) { - let filename = file; + const filename = file; const sourceMapContentHash = - usesContentHash && - /** @type {string} */ (createHash("md4") - .update(sourceMapString) - .digest("hex")); + /** @type {string} */ + ( + usesContentHash && + createHash( + /** @type {Algorithm} */ + (compilation.outputOptions.hashFunction) + ) + .update(sourceMapString) + .digest("hex") + ); const pathParams = { chunk, filename: options.fileContext @@ -447,34 +497,32 @@ class SourceMapDevToolPlugin { outputFs, `/${options.fileContext}`, `/${filename}` - ) + ) : filename, contentHash: sourceMapContentHash }; - const { - path: sourceMapFile, - info: sourceMapInfo - } = compilation.getPathWithInfo( - sourceMapFilename, - pathParams - ); + const { path: sourceMapFile, info: sourceMapInfo } = + compilation.getPathWithInfo( + sourceMapFilename, + pathParams + ); const sourceMapUrl = options.publicPath ? options.publicPath + sourceMapFile : relative( outputFs, dirname(outputFs, `/${file}`), `/${sourceMapFile}` - ); + ); /** @type {Source} */ let asset = new RawSource(source); if (currentSourceMappingURLComment !== false) { // Add source map url to compilation asset, if currentSourceMappingURLComment is set asset = new ConcatSource( asset, - compilation.getPath( - currentSourceMappingURLComment, - Object.assign({ url: sourceMapUrl }, pathParams) - ) + compilation.getPath(currentSourceMappingURLComment, { + url: sourceMapUrl, + ...pathParams + }) ); } const assetInfo = { @@ -504,15 +552,20 @@ class SourceMapDevToolPlugin { "SourceMapDevToolPlugin: append can't be false when no filename is provided" ); } + if (typeof currentSourceMappingURLComment === "function") { + throw new Error( + "SourceMapDevToolPlugin: append can't be a function when no filename is provided" + ); + } /** * Add source map as data url to asset */ const asset = new ConcatSource( new RawSource(source), currentSourceMappingURLComment - .replace(/\[map\]/g, () => sourceMapString) + .replace(MAP_URL_COMMENT_REGEXP, () => sourceMapString) .replace( - /\[url\]/g, + URL_COMMENT_REGEXP, () => `data:application/json;charset=utf-8;base64,${Buffer.from( sourceMapString, @@ -539,7 +592,7 @@ class SourceMapDevToolPlugin { }); }, err => { - reportProgress(1.0); + reportProgress(1); callback(err); } ); diff --git a/lib/Stats.js b/lib/Stats.js index 567683b7bd7..22a36632a97 100644 --- a/lib/Stats.js +++ b/lib/Stats.js @@ -7,6 +7,7 @@ /** @typedef {import("../declarations/WebpackOptions").StatsOptions} StatsOptions */ /** @typedef {import("./Compilation")} Compilation */ +/** @typedef {import("./Compilation").NormalizedStatsOptions} NormalizedStatsOptions */ /** @typedef {import("./stats/DefaultStatsFactoryPlugin").StatsCompilation} StatsCompilation */ class Stats { @@ -34,7 +35,7 @@ class Stats { */ hasWarnings() { return ( - this.compilation.warnings.length > 0 || + this.compilation.getWarnings().length > 0 || this.compilation.children.some(child => child.getStats().hasWarnings()) ); } @@ -50,28 +51,32 @@ class Stats { } /** - * @param {(string|StatsOptions)=} options stats options + * @param {(string | boolean | StatsOptions)=} options stats options * @returns {StatsCompilation} json output */ toJson(options) { - options = this.compilation.createStatsOptions(options, { + const normalizedOptions = this.compilation.createStatsOptions(options, { forToString: false }); - const statsFactory = this.compilation.createStatsFactory(options); + const statsFactory = this.compilation.createStatsFactory(normalizedOptions); return statsFactory.create("compilation", this.compilation, { compilation: this.compilation }); } + /** + * @param {(string | boolean | StatsOptions)=} options stats options + * @returns {string} string output + */ toString(options) { - options = this.compilation.createStatsOptions(options, { + const normalizedOptions = this.compilation.createStatsOptions(options, { forToString: true }); - const statsFactory = this.compilation.createStatsFactory(options); - const statsPrinter = this.compilation.createStatsPrinter(options); + const statsFactory = this.compilation.createStatsFactory(normalizedOptions); + const statsPrinter = this.compilation.createStatsPrinter(normalizedOptions); const data = statsFactory.create("compilation", this.compilation, { compilation: this.compilation diff --git a/lib/Template.js b/lib/Template.js index ac970ad0a4b..3b95cfc35b5 100644 --- a/lib/Template.js +++ b/lib/Template.js @@ -6,11 +6,14 @@ "use strict"; const { ConcatSource, PrefixSource } = require("webpack-sources"); +const { WEBPACK_MODULE_TYPE_RUNTIME } = require("./ModuleTypeConstants"); +const RuntimeGlobals = require("./RuntimeGlobals"); /** @typedef {import("webpack-sources").Source} Source */ /** @typedef {import("../declarations/WebpackOptions").Output} OutputOptions */ /** @typedef {import("./Chunk")} Chunk */ /** @typedef {import("./ChunkGraph")} ChunkGraph */ +/** @typedef {import("./ChunkGraph").ModuleId} ModuleId */ /** @typedef {import("./CodeGenerationResults")} CodeGenerationResults */ /** @typedef {import("./Compilation").AssetInfo} AssetInfo */ /** @typedef {import("./Compilation").PathData} PathData */ @@ -18,9 +21,11 @@ const { ConcatSource, PrefixSource } = require("webpack-sources"); /** @typedef {import("./Module")} Module */ /** @typedef {import("./ModuleGraph")} ModuleGraph */ /** @typedef {import("./ModuleTemplate")} ModuleTemplate */ -/** @typedef {import("./ModuleTemplate").RenderContext} RenderContext */ /** @typedef {import("./RuntimeModule")} RuntimeModule */ /** @typedef {import("./RuntimeTemplate")} RuntimeTemplate */ +/** @typedef {import("./TemplatedPathPlugin").TemplatePath} TemplatePath */ +/** @typedef {import("./javascript/JavascriptModulesPlugin").ChunkRenderContext} ChunkRenderContext */ +/** @typedef {import("./javascript/JavascriptModulesPlugin").RenderContext} RenderContext */ const START_LOWERCASE_ALPHABET_CODE = "a".charCodeAt(0); const START_UPPERCASE_ALPHABET_CODE = "A".charCodeAt(0); @@ -38,7 +43,7 @@ const PATH_NAME_NORMALIZE_REPLACE_REGEX = /[^a-zA-Z0-9_!ยง$()=\-^ยฐ]+/g; const MATCH_PADDED_HYPHENS_REPLACE_REGEX = /^-|-$/g; /** - * @typedef {Object} RenderManifestOptions + * @typedef {object} RenderManifestOptions * @property {Chunk} chunk the chunk used to render * @property {string} hash * @property {string} fullHash @@ -54,9 +59,9 @@ const MATCH_PADDED_HYPHENS_REPLACE_REGEX = /^-|-$/g; /** @typedef {RenderManifestEntryTemplated | RenderManifestEntryStatic} RenderManifestEntry */ /** - * @typedef {Object} RenderManifestEntryTemplated + * @typedef {object} RenderManifestEntryTemplated * @property {function(): Source} render - * @property {string | function(PathData, AssetInfo=): string} filenameTemplate + * @property {TemplatePath} filenameTemplate * @property {PathData=} pathOptions * @property {AssetInfo=} info * @property {string} identifier @@ -65,7 +70,7 @@ const MATCH_PADDED_HYPHENS_REPLACE_REGEX = /^-|-$/g; */ /** - * @typedef {Object} RenderManifestEntryStatic + * @typedef {object} RenderManifestEntryStatic * @property {function(): Source} render * @property {string} filename * @property {AssetInfo} info @@ -75,7 +80,7 @@ const MATCH_PADDED_HYPHENS_REPLACE_REGEX = /^-|-$/g; */ /** - * @typedef {Object} HasId + * @typedef {object} HasId * @property {number | string} id */ @@ -85,7 +90,6 @@ const MATCH_PADDED_HYPHENS_REPLACE_REGEX = /^-|-$/g; class Template { /** - * * @param {Function} fn a runtime function (.runtime.js) "template" * @returns {string} the updated and normalized function string */ @@ -107,8 +111,8 @@ class Template { .replace(IDENTIFIER_NAME_REPLACE_REGEX, "_$1") .replace(IDENTIFIER_ALPHA_NUMERIC_NAME_REPLACE_REGEX, "_"); } + /** - * * @param {string} str string to be converted to commented in bundle code * @returns {string} returns a commented version of string */ @@ -118,7 +122,6 @@ class Template { } /** - * * @param {string} str string to be converted to "normal comment" * @returns {string} returns a commented version of string */ @@ -208,23 +211,20 @@ class Template { } /** - * * @param {string | string[]} s string to convert to identity * @returns {string} converted identity */ static indent(s) { if (Array.isArray(s)) { return s.map(Template.indent).join("\n"); - } else { - const str = s.trimRight(); - if (!str) return ""; - const ind = str[0] === "\n" ? "" : "\t"; - return ind + str.replace(/\n([^\n])/g, "\n\t$1"); } + const str = s.trimEnd(); + if (!str) return ""; + const ind = str[0] === "\n" ? "" : "\t"; + return ind + str.replace(/\n([^\n])/g, "\n\t$1"); } /** - * * @param {string|string[]} s string to create prefix for * @param {string} prefix prefix to compose * @returns {string} returns new prefix string @@ -233,11 +233,10 @@ class Template { const str = Template.asString(s).trim(); if (!str) return ""; const ind = str[0] === "\n" ? "" : prefix; - return ind + str.replace(/\n([^\n])/g, "\n" + prefix + "$1"); + return ind + str.replace(/\n([^\n])/g, `\n${prefix}$1`); } /** - * * @param {string|string[]} str string or string collection * @returns {string} returns a single string from array */ @@ -249,7 +248,7 @@ class Template { } /** - * @typedef {Object} WithId + * @typedef {object} WithId * @property {string|number} id */ @@ -267,7 +266,7 @@ class Template { if (maxId < moduleId) maxId = moduleId; if (minId > moduleId) minId = moduleId; } - if (minId < 16 + ("" + minId).length) { + if (minId < 16 + String(minId).length) { // add minId x ',' instead of 'Array(minId).concat(โ€ฆ)' minId = 0; } @@ -283,25 +282,23 @@ class Template { } /** - * @param {RenderContext} renderContext render context + * @param {ChunkRenderContext} renderContext render context * @param {Module[]} modules modules to render (should be ordered by identifier) - * @param {function(Module): Source} renderModule function to render a module + * @param {function(Module): Source | null} renderModule function to render a module * @param {string=} prefix applying prefix strings - * @returns {Source} rendered chunk modules in a Source object + * @returns {Source | null} rendered chunk modules in a Source object or null if no modules */ static renderChunkModules(renderContext, modules, renderModule, prefix = "") { const { chunkGraph } = renderContext; - var source = new ConcatSource(); + const source = new ConcatSource(); if (modules.length === 0) { return null; } /** @type {{id: string|number, source: Source|string}[]} */ - const allModules = modules.map(module => { - return { - id: chunkGraph.getModuleId(module), - source: renderModule(module) || "false" - }; - }); + const allModules = modules.map(module => ({ + id: /** @type {ModuleId} */ (chunkGraph.getModuleId(module)), + source: renderModule(module) || "false" + })); const bounds = Template.getModulesArrayBounds(allModules); if (bounds) { // Render a spare array @@ -327,7 +324,7 @@ class Template { source.add(module.source); } } - source.add("\n" + prefix + "]"); + source.add(`\n${prefix}]`); if (minId !== 0) { source.add(")"); } @@ -349,7 +346,7 @@ class Template { /** * @param {RuntimeModule[]} runtimeModules array of runtime modules in order - * @param {RenderContext & { codeGenerationResults?: CodeGenerationResults, useStrict?: boolean }} renderContext render context + * @param {RenderContext & { codeGenerationResults?: CodeGenerationResults }} renderContext render context * @returns {Source} rendered runtime modules in a Source object */ static renderRuntimeModules(runtimeModules, renderContext) { @@ -361,7 +358,7 @@ class Template { runtimeSource = codeGenerationResults.getSource( module, renderContext.chunk.runtime, - "runtime" + WEBPACK_MODULE_TYPE_RUNTIME ); } else { const codeGenResult = module.codeGeneration({ @@ -369,23 +366,23 @@ class Template { dependencyTemplates: renderContext.dependencyTemplates, moduleGraph: renderContext.moduleGraph, runtimeTemplate: renderContext.runtimeTemplate, - runtime: renderContext.chunk.runtime + runtime: renderContext.chunk.runtime, + codeGenerationResults }); if (!codeGenResult) continue; runtimeSource = codeGenResult.sources.get("runtime"); } if (runtimeSource) { - source.add(Template.toNormalComment(module.identifier()) + "\n"); + source.add(`${Template.toNormalComment(module.identifier())}\n`); if (!module.shouldIsolate()) { source.add(runtimeSource); + source.add("\n\n"); } else if (renderContext.runtimeTemplate.supportsArrowFunction()) { source.add("(() => {\n"); - if (renderContext.useStrict) source.add('\t"use strict";\n'); source.add(new PrefixSource("\t", runtimeSource)); source.add("\n})();\n\n"); } else { source.add("!function() {\n"); - if (renderContext.useStrict) source.add('\t"use strict";\n'); source.add(new PrefixSource("\t", runtimeSource)); source.add("\n}();\n\n"); } @@ -403,8 +400,7 @@ class Template { return new PrefixSource( "/******/ ", new ConcatSource( - "function(__webpack_require__) { // webpackRuntimeModules\n", - '"use strict";\n\n', + `function(${RuntimeGlobals.require}) { // webpackRuntimeModules\n`, this.renderRuntimeModules(runtimeModules, renderContext), "}\n" ) @@ -413,5 +409,7 @@ class Template { } module.exports = Template; -module.exports.NUMBER_OF_IDENTIFIER_START_CHARS = NUMBER_OF_IDENTIFIER_START_CHARS; -module.exports.NUMBER_OF_IDENTIFIER_CONTINUATION_CHARS = NUMBER_OF_IDENTIFIER_CONTINUATION_CHARS; +module.exports.NUMBER_OF_IDENTIFIER_START_CHARS = + NUMBER_OF_IDENTIFIER_START_CHARS; +module.exports.NUMBER_OF_IDENTIFIER_CONTINUATION_CHARS = + NUMBER_OF_IDENTIFIER_CONTINUATION_CHARS; diff --git a/lib/TemplatedPathPlugin.js b/lib/TemplatedPathPlugin.js index 27d5faf316d..e68fbc79a01 100644 --- a/lib/TemplatedPathPlugin.js +++ b/lib/TemplatedPathPlugin.js @@ -5,34 +5,58 @@ "use strict"; +const mime = require("mime-types"); const { basename, extname } = require("path"); const util = require("util"); const Chunk = require("./Chunk"); const Module = require("./Module"); const { parseResource } = require("./util/identifier"); +/** @typedef {import("./ChunkGraph")} ChunkGraph */ +/** @typedef {import("./ChunkGraph").ModuleId} ModuleId */ /** @typedef {import("./Compilation").AssetInfo} AssetInfo */ /** @typedef {import("./Compilation").PathData} PathData */ /** @typedef {import("./Compiler")} Compiler */ const REGEXP = /\[\\*([\w:]+)\\*\]/gi; +/** + * @param {string | number} id id + * @returns {string | number} result + */ const prepareId = id => { if (typeof id !== "string") return id; if (/^"\s\+*.*\+\s*"$/.test(id)) { const match = /^"\s\+*\s*(.*)\s*\+\s*"$/.exec(id); - return `" + (${match[1]} + "").replace(/(^[.-]|[^a-zA-Z0-9_-])+/g, "_") + "`; + return `" + (${ + /** @type {string[]} */ (match)[1] + } + "").replace(/(^[.-]|[^a-zA-Z0-9_-])+/g, "_") + "`; } return id.replace(/(^[.-]|[^a-zA-Z0-9_-])+/g, "_"); }; +/** + * @callback ReplacerFunction + * @param {string} match + * @param {string | undefined} arg + * @param {string} input + */ + +/** + * @param {ReplacerFunction} replacer replacer + * @param {((arg0: number) => string) | undefined} handler handler + * @param {AssetInfo | undefined} assetInfo asset info + * @param {string} hashName hash name + * @returns {ReplacerFunction} hash replacer function + */ const hashLength = (replacer, handler, assetInfo, hashName) => { + /** @type {ReplacerFunction} */ const fn = (match, arg, input) => { let result; - const length = arg && parseInt(arg, 10); + const length = arg && Number.parseInt(arg, 10); if (length && handler) { result = handler(length); @@ -57,7 +81,15 @@ const hashLength = (replacer, handler, assetInfo, hashName) => { return fn; }; +/** @typedef {(match: string, arg?: string, input?: string) => string} Replacer */ + +/** + * @param {string | number | null | undefined | (() => string | number | null | undefined)} value value + * @param {boolean=} allowEmpty allow empty + * @returns {Replacer} replacer + */ const replacer = (value, allowEmpty) => { + /** @type {Replacer} */ const fn = (match, arg, input) => { if (typeof value === "function") { value = value(); @@ -70,9 +102,9 @@ const replacer = (value, allowEmpty) => { } return ""; - } else { - return `${value}`; } + + return `${value}`; }; return fn; @@ -80,6 +112,12 @@ const replacer = (value, allowEmpty) => { const deprecationCache = new Map(); const deprecatedFunction = (() => () => {})(); +/** + * @param {Function} fn function + * @param {string} message message + * @param {string} code code + * @returns {function(...any[]): void} function with deprecation output + */ const deprecated = (fn, message, code) => { let d = deprecationCache.get(message); if (d === undefined) { @@ -92,10 +130,12 @@ const deprecated = (fn, message, code) => { }; }; +/** @typedef {string | function(PathData, AssetInfo=): string} TemplatePath */ + /** - * @param {string | function(PathData, AssetInfo=): string} path the raw path + * @param {TemplatePath} path the raw path * @param {PathData} data context data - * @param {AssetInfo} assetInfo extra info about the asset (will be written to) + * @param {AssetInfo | undefined} assetInfo extra info about the asset (will be written to) * @returns {string} the interpolated path */ const replacePathVariables = (path, data, assetInfo) => { @@ -116,8 +156,30 @@ const replacePathVariables = (path, data, assetInfo) => { // [path] - /some/path/ // [name] - file // [ext] - .js - if (data.filename) { - if (typeof data.filename === "string") { + if (typeof data.filename === "string") { + // check that filename is data uri + const match = data.filename.match(/^data:([^;,]+)/); + if (match) { + const ext = mime.extension(match[1]); + const emptyReplacer = replacer("", true); + + replacements.set("file", emptyReplacer); + replacements.set("query", emptyReplacer); + replacements.set("fragment", emptyReplacer); + replacements.set("path", emptyReplacer); + replacements.set("base", emptyReplacer); + replacements.set("name", emptyReplacer); + replacements.set("ext", replacer(ext ? `.${ext}` : "", true)); + // Legacy + replacements.set( + "filebase", + deprecated( + emptyReplacer, + "[filebase] is now [base]", + "DEP_WEBPACK_TEMPLATE_PATH_PLUGIN_REPLACE_PATH_VARIABLES_FILENAME" + ) + ); + } else { const { path: file, query, fragment } = parseResource(data.filename); const ext = extname(file); @@ -204,7 +266,7 @@ const replacePathVariables = (path, data, assetInfo) => { ), data.contentHashWithLength || ("contentHashWithLength" in chunk && chunk.contentHashWithLength - ? chunk.contentHashWithLength[contentHashType] + ? chunk.contentHashWithLength[/** @type {string} */ (contentHashType)] : undefined), assetInfo, "contenthash" @@ -232,13 +294,17 @@ const replacePathVariables = (path, data, assetInfo) => { const idReplacer = replacer(() => prepareId( - module instanceof Module ? chunkGraph.getModuleId(module) : module.id + module instanceof Module + ? /** @type {ModuleId} */ + (/** @type {ChunkGraph} */ (chunkGraph).getModuleId(module)) + : module.id ) ); const moduleHashReplacer = hashLength( replacer(() => module instanceof Module - ? chunkGraph.getRenderedModuleHash(module, data.runtime) + ? /** @type {ChunkGraph} */ + (chunkGraph).getRenderedModuleHash(module, data.runtime) : module.hash ), "hashWithLength" in module ? module.hashWithLength : undefined, @@ -246,7 +312,7 @@ const replacePathVariables = (path, data, assetInfo) => { "modulehash" ); const contentHashReplacer = hashLength( - replacer(data.contentHash), + replacer(/** @type {string} */ (data.contentHash)), undefined, assetInfo, "contenthash" @@ -277,7 +343,7 @@ const replacePathVariables = (path, data, assetInfo) => { if (typeof data.runtime === "string") { replacements.set( "runtime", - replacer(() => prepareId(data.runtime)) + replacer(() => prepareId(/** @type {string} */ (data.runtime))) ); } else { replacements.set("runtime", replacer("_")); diff --git a/lib/UnsupportedFeatureWarning.js b/lib/UnsupportedFeatureWarning.js index 67f670dab1c..2c59f4a80a8 100644 --- a/lib/UnsupportedFeatureWarning.js +++ b/lib/UnsupportedFeatureWarning.js @@ -21,8 +21,6 @@ class UnsupportedFeatureWarning extends WebpackError { this.name = "UnsupportedFeatureWarning"; this.loc = loc; this.hideStack = true; - - Error.captureStackTrace(this, this.constructor); } } diff --git a/lib/UseStrictPlugin.js b/lib/UseStrictPlugin.js index eaac54ac5bc..3db3daa8f62 100644 --- a/lib/UseStrictPlugin.js +++ b/lib/UseStrictPlugin.js @@ -5,9 +5,21 @@ "use strict"; +const { + JAVASCRIPT_MODULE_TYPE_AUTO, + JAVASCRIPT_MODULE_TYPE_DYNAMIC, + JAVASCRIPT_MODULE_TYPE_ESM +} = require("./ModuleTypeConstants"); const ConstDependency = require("./dependencies/ConstDependency"); +/** @typedef {import("../declarations/WebpackOptions").JavascriptParserOptions} JavascriptParserOptions */ /** @typedef {import("./Compiler")} Compiler */ +/** @typedef {import("./Dependency").DependencyLocation} DependencyLocation */ +/** @typedef {import("./Module").BuildInfo} BuildInfo */ +/** @typedef {import("./javascript/JavascriptParser")} JavascriptParser */ +/** @typedef {import("./javascript/JavascriptParser").Range} Range */ + +const PLUGIN_NAME = "UseStrictPlugin"; class UseStrictPlugin { /** @@ -17,10 +29,14 @@ class UseStrictPlugin { */ apply(compiler) { compiler.hooks.compilation.tap( - "UseStrictPlugin", + PLUGIN_NAME, (compilation, { normalModuleFactory }) => { - const handler = parser => { - parser.hooks.program.tap("UseStrictPlugin", ast => { + /** + * @param {JavascriptParser} parser the parser + * @param {JavascriptParserOptions} parserOptions the javascript parser options + */ + const handler = (parser, parserOptions) => { + parser.hooks.program.tap(PLUGIN_NAME, ast => { const firstNode = ast.body[0]; if ( firstNode && @@ -31,23 +47,32 @@ class UseStrictPlugin { // Remove "use strict" expression. It will be added later by the renderer again. // This is necessary in order to not break the strict mode when webpack prepends code. // @see https://github.com/webpack/webpack/issues/1970 - const dep = new ConstDependency("", firstNode.range); - dep.loc = firstNode.loc; + const dep = new ConstDependency( + "", + /** @type {Range} */ (firstNode.range) + ); + dep.loc = /** @type {DependencyLocation} */ (firstNode.loc); parser.state.module.addPresentationalDependency(dep); - parser.state.module.buildInfo.strict = true; + /** @type {BuildInfo} */ + (parser.state.module.buildInfo).strict = true; + } + if (parserOptions.overrideStrict) { + /** @type {BuildInfo} */ + (parser.state.module.buildInfo).strict = + parserOptions.overrideStrict === "strict"; } }); }; normalModuleFactory.hooks.parser - .for("javascript/auto") - .tap("UseStrictPlugin", handler); + .for(JAVASCRIPT_MODULE_TYPE_AUTO) + .tap(PLUGIN_NAME, handler); normalModuleFactory.hooks.parser - .for("javascript/dynamic") - .tap("UseStrictPlugin", handler); + .for(JAVASCRIPT_MODULE_TYPE_DYNAMIC) + .tap(PLUGIN_NAME, handler); normalModuleFactory.hooks.parser - .for("javascript/esm") - .tap("UseStrictPlugin", handler); + .for(JAVASCRIPT_MODULE_TYPE_ESM) + .tap(PLUGIN_NAME, handler); } ); } diff --git a/lib/WarnCaseSensitiveModulesPlugin.js b/lib/WarnCaseSensitiveModulesPlugin.js index 0be4f258cca..11af42a590f 100644 --- a/lib/WarnCaseSensitiveModulesPlugin.js +++ b/lib/WarnCaseSensitiveModulesPlugin.js @@ -8,6 +8,8 @@ const CaseSensitiveModulesWarning = require("./CaseSensitiveModulesWarning"); /** @typedef {import("./Compiler")} Compiler */ +/** @typedef {import("./Module")} Module */ +/** @typedef {import("./NormalModule")} NormalModule */ class WarnCaseSensitiveModulesPlugin { /** @@ -20,21 +22,37 @@ class WarnCaseSensitiveModulesPlugin { "WarnCaseSensitiveModulesPlugin", compilation => { compilation.hooks.seal.tap("WarnCaseSensitiveModulesPlugin", () => { + /** @type {Map>} */ const moduleWithoutCase = new Map(); for (const module of compilation.modules) { - const identifier = module.identifier().toLowerCase(); - const array = moduleWithoutCase.get(identifier); - if (array) { - array.push(module); - } else { - moduleWithoutCase.set(identifier, [module]); + const identifier = module.identifier(); + + // Ignore `data:` URLs, because it's not a real path + if ( + /** @type {NormalModule} */ + (module).resourceResolveData !== undefined && + /** @type {NormalModule} */ + (module).resourceResolveData.encodedContent !== undefined + ) { + continue; + } + + const lowerIdentifier = identifier.toLowerCase(); + let map = moduleWithoutCase.get(lowerIdentifier); + if (map === undefined) { + map = new Map(); + moduleWithoutCase.set(lowerIdentifier, map); } + map.set(identifier, module); } for (const pair of moduleWithoutCase) { - const array = pair[1]; - if (array.length > 1) { + const map = pair[1]; + if (map.size > 1) { compilation.warnings.push( - new CaseSensitiveModulesWarning(array, compilation.moduleGraph) + new CaseSensitiveModulesWarning( + map.values(), + compilation.moduleGraph + ) ); } } diff --git a/lib/WarnDeprecatedOptionPlugin.js b/lib/WarnDeprecatedOptionPlugin.js index 518e33455b3..8cad0869908 100644 --- a/lib/WarnDeprecatedOptionPlugin.js +++ b/lib/WarnDeprecatedOptionPlugin.js @@ -40,6 +40,12 @@ class WarnDeprecatedOptionPlugin { } class DeprecatedOptionWarning extends WebpackError { + /** + * Create an instance deprecated option warning + * @param {string} option the target option + * @param {string | number} value the deprecated option value + * @param {string} suggestion the suggestion replacement + */ constructor(option, value, suggestion) { super(); @@ -48,8 +54,6 @@ class DeprecatedOptionWarning extends WebpackError { "configuration\n" + `The value '${value}' for option '${option}' is deprecated. ` + `Use '${suggestion}' instead.`; - - Error.captureStackTrace(this, this.constructor); } } diff --git a/lib/WatchIgnorePlugin.js b/lib/WatchIgnorePlugin.js index bedbbf57af0..a7471e9c347 100644 --- a/lib/WatchIgnorePlugin.js +++ b/lib/WatchIgnorePlugin.js @@ -5,56 +5,81 @@ "use strict"; -const { validate } = require("schema-utils"); -const schema = require("../schemas/plugins/WatchIgnorePlugin.json"); +const { groupBy } = require("./util/ArrayHelpers"); +const createSchemaValidation = require("./util/create-schema-validation"); /** @typedef {import("../declarations/plugins/WatchIgnorePlugin").WatchIgnorePluginOptions} WatchIgnorePluginOptions */ +/** @typedef {import("../declarations/WebpackOptions").WatchOptions} WatchOptions */ /** @typedef {import("./Compiler")} Compiler */ +/** @typedef {import("./util/fs").TimeInfoEntries} TimeInfoEntries */ /** @typedef {import("./util/fs").WatchFileSystem} WatchFileSystem */ +/** @typedef {import("./util/fs").WatchMethod} WatchMethod */ +/** @typedef {import("./util/fs").Watcher} Watcher */ +const validate = createSchemaValidation( + require("../schemas/plugins/WatchIgnorePlugin.check.js"), + () => require("../schemas/plugins/WatchIgnorePlugin.json"), + { + name: "Watch Ignore Plugin", + baseDataPath: "options" + } +); const IGNORE_TIME_ENTRY = "ignore"; class IgnoringWatchFileSystem { /** * @param {WatchFileSystem} wfs original file system - * @param {(string|RegExp)[]} paths ignored paths + * @param {WatchIgnorePluginOptions["paths"]} paths ignored paths */ constructor(wfs, paths) { this.wfs = wfs; this.paths = paths; } + /** @type {WatchMethod} */ watch(files, dirs, missing, startTime, options, callback, callbackUndelayed) { files = Array.from(files); dirs = Array.from(dirs); + /** + * @param {string} path path to check + * @returns {boolean} true, if path is ignored + */ const ignored = path => this.paths.some(p => p instanceof RegExp ? p.test(path) : path.indexOf(p) === 0 ); - const notIgnored = path => !ignored(path); - - const ignoredFiles = files.filter(ignored); - const ignoredDirs = dirs.filter(ignored); + const [ignoredFiles, notIgnoredFiles] = groupBy( + /** @type {Array} */ + (files), + ignored + ); + const [ignoredDirs, notIgnoredDirs] = groupBy( + /** @type {Array} */ + (dirs), + ignored + ); const watcher = this.wfs.watch( - files.filter(notIgnored), - dirs.filter(notIgnored), + notIgnoredFiles, + notIgnoredDirs, missing, startTime, options, (err, fileTimestamps, dirTimestamps, changedFiles, removedFiles) => { if (err) return callback(err); for (const path of ignoredFiles) { - fileTimestamps.set(path, IGNORE_TIME_ENTRY); + /** @type {TimeInfoEntries} */ + (fileTimestamps).set(path, IGNORE_TIME_ENTRY); } for (const path of ignoredDirs) { - dirTimestamps.set(path, IGNORE_TIME_ENTRY); + /** @type {TimeInfoEntries} */ + (dirTimestamps).set(path, IGNORE_TIME_ENTRY); } callback( - err, + null, fileTimestamps, dirTimestamps, changedFiles, @@ -80,7 +105,22 @@ class IgnoringWatchFileSystem { fileTimestamps.set(path, IGNORE_TIME_ENTRY); } return fileTimestamps; - } + }, + getInfo: + watcher.getInfo && + (() => { + const info = + /** @type {NonNullable} */ + (watcher.getInfo)(); + const { fileTimeInfoEntries, contextTimeInfoEntries } = info; + for (const path of ignoredFiles) { + fileTimeInfoEntries.set(path, IGNORE_TIME_ENTRY); + } + for (const path of ignoredDirs) { + contextTimeInfoEntries.set(path, IGNORE_TIME_ENTRY); + } + return info; + }) }; } } @@ -90,10 +130,7 @@ class WatchIgnorePlugin { * @param {WatchIgnorePluginOptions} options options */ constructor(options) { - validate(schema, options, { - name: "Watch Ignore Plugin", - baseDataPath: "options" - }); + validate(options); this.paths = options.paths; } @@ -105,7 +142,8 @@ class WatchIgnorePlugin { apply(compiler) { compiler.hooks.afterEnvironment.tap("WatchIgnorePlugin", () => { compiler.watchFileSystem = new IgnoringWatchFileSystem( - compiler.watchFileSystem, + /** @type {WatchFileSystem} */ + (compiler.watchFileSystem), this.paths ); }); diff --git a/lib/Watching.js b/lib/Watching.js index d3c513a401f..09ade746b32 100644 --- a/lib/Watching.js +++ b/lib/Watching.js @@ -10,11 +10,17 @@ const Stats = require("./Stats"); /** @typedef {import("../declarations/WebpackOptions").WatchOptions} WatchOptions */ /** @typedef {import("./Compilation")} Compilation */ /** @typedef {import("./Compiler")} Compiler */ +/** @typedef {import("./FileSystemInfo").FileSystemInfoEntry} FileSystemInfoEntry */ +/** @typedef {import("./WebpackError")} WebpackError */ +/** @typedef {import("./logging/Logger").Logger} Logger */ +/** @typedef {import("./util/fs").TimeInfoEntries} TimeInfoEntries */ +/** @typedef {import("./util/fs").WatchFileSystem} WatchFileSystem */ +/** @typedef {import("./util/fs").Watcher} Watcher */ /** * @template T * @callback Callback - * @param {Error=} err + * @param {Error | null} err * @param {T=} result */ @@ -39,33 +45,118 @@ class Watching { this._onChange = () => {}; this._onInvalid = () => {}; if (typeof watchOptions === "number") { + /** @type {WatchOptions} */ this.watchOptions = { aggregateTimeout: watchOptions }; } else if (watchOptions && typeof watchOptions === "object") { + /** @type {WatchOptions} */ this.watchOptions = { ...watchOptions }; } else { + /** @type {WatchOptions} */ this.watchOptions = {}; } if (typeof this.watchOptions.aggregateTimeout !== "number") { - this.watchOptions.aggregateTimeout = 200; + this.watchOptions.aggregateTimeout = 20; } this.compiler = compiler; this.running = false; this._initial = true; + this._invalidReported = true; this._needRecords = true; this.watcher = undefined; this.pausedWatcher = undefined; + /** @type {Set | undefined} */ + this._collectedChangedFiles = undefined; + /** @type {Set | undefined} */ + this._collectedRemovedFiles = undefined; this._done = this._done.bind(this); process.nextTick(() => { if (this._initial) this._invalidate(); }); } - _go() { + /** + * @param {ReadonlySet=} changedFiles changed files + * @param {ReadonlySet=} removedFiles removed files + */ + _mergeWithCollected(changedFiles, removedFiles) { + if (!changedFiles) return; + if (!this._collectedChangedFiles) { + this._collectedChangedFiles = new Set(changedFiles); + this._collectedRemovedFiles = new Set(removedFiles); + } else { + for (const file of changedFiles) { + this._collectedChangedFiles.add(file); + /** @type {Set} */ + (this._collectedRemovedFiles).delete(file); + } + for (const file of /** @type {ReadonlySet} */ (removedFiles)) { + this._collectedChangedFiles.delete(file); + /** @type {Set} */ + (this._collectedRemovedFiles).add(file); + } + } + } + + /** + * @param {TimeInfoEntries=} fileTimeInfoEntries info for files + * @param {TimeInfoEntries=} contextTimeInfoEntries info for directories + * @param {ReadonlySet=} changedFiles changed files + * @param {ReadonlySet=} removedFiles removed files + * @returns {void} + */ + _go(fileTimeInfoEntries, contextTimeInfoEntries, changedFiles, removedFiles) { this._initial = false; - this.startTime = Date.now(); + if (this.startTime === null) this.startTime = Date.now(); this.running = true; + if (this.watcher) { + this.pausedWatcher = this.watcher; + this.lastWatcherStartTime = Date.now(); + this.watcher.pause(); + this.watcher = null; + } else if (!this.lastWatcherStartTime) { + this.lastWatcherStartTime = Date.now(); + } + this.compiler.fsStartTime = Date.now(); + if ( + changedFiles && + removedFiles && + fileTimeInfoEntries && + contextTimeInfoEntries + ) { + this._mergeWithCollected(changedFiles, removedFiles); + this.compiler.fileTimestamps = fileTimeInfoEntries; + this.compiler.contextTimestamps = contextTimeInfoEntries; + } else if (this.pausedWatcher) { + if (this.pausedWatcher.getInfo) { + const { + changes, + removals, + fileTimeInfoEntries, + contextTimeInfoEntries + } = this.pausedWatcher.getInfo(); + this._mergeWithCollected(changes, removals); + this.compiler.fileTimestamps = fileTimeInfoEntries; + this.compiler.contextTimestamps = contextTimeInfoEntries; + } else { + this._mergeWithCollected( + this.pausedWatcher.getAggregatedChanges && + this.pausedWatcher.getAggregatedChanges(), + this.pausedWatcher.getAggregatedRemovals && + this.pausedWatcher.getAggregatedRemovals() + ); + this.compiler.fileTimestamps = + this.pausedWatcher.getFileTimeInfoEntries(); + this.compiler.contextTimestamps = + this.pausedWatcher.getContextTimeInfoEntries(); + } + } + this.compiler.modifiedFiles = this._collectedChangedFiles; + this._collectedChangedFiles = undefined; + this.compiler.removedFiles = this._collectedRemovedFiles; + this._collectedRemovedFiles = undefined; + const run = () => { if (this.compiler.idle) { return this.compiler.cache.endIdle(err => { @@ -83,10 +174,19 @@ class Watching { }); } this.invalid = false; + this._invalidReported = false; this.compiler.hooks.watchRun.callAsync(this.compiler, err => { if (err) return this._done(err); - const onCompiled = (err, compilation) => { - if (err) return this._done(err, compilation); + /** + * @param {Error | null} err error + * @param {Compilation=} _compilation compilation + * @returns {void} + */ + const onCompiled = (err, _compilation) => { + if (err) return this._done(err, _compilation); + + const compilation = /** @type {Compilation} */ (_compilation); + if (this.invalid) return this._done(null, compilation); if (this.compiler.hooks.shouldEmit.call(compilation) === false) { @@ -109,7 +209,9 @@ class Watching { if (compilation.hooks.needAdditionalPass.call()) { compilation.needAdditionalPass = true; - compilation.startTime = this.startTime; + compilation.startTime = /** @type {number} */ ( + this.startTime + ); compilation.endTime = Date.now(); logger.time("done hook"); const stats = new Stats(compilation); @@ -146,24 +248,34 @@ class Watching { } /** - * @param {Error=} err an optional error + * @param {(Error | null)=} err an optional error * @param {Compilation=} compilation the compilation * @returns {void} */ _done(err, compilation) { this.running = false; - const logger = compilation && compilation.getLogger("webpack.Watching"); + const logger = + /** @type {Logger} */ + (compilation && compilation.getLogger("webpack.Watching")); - let stats = null; + /** @type {Stats | undefined} */ + let stats; - const handleError = err => { + /** + * @param {Error} err error + * @param {Callback[]=} cbs callbacks + */ + const handleError = (err, cbs) => { this.compiler.hooks.failed.call(err); this.compiler.cache.beginIdle(); this.compiler.idle = true; - this.handler(err, stats); - for (const cb of this.callbacks) cb(); - this.callbacks.length = 0; + this.handler(err, /** @type {Stats} */ (stats)); + if (!cbs) { + cbs = this.callbacks; + this.callbacks = []; + } + for (const cb of cbs) cb(err); }; if ( @@ -189,23 +301,27 @@ class Watching { } if (compilation) { - compilation.startTime = this.startTime; + compilation.startTime = /** @type {number} */ (this.startTime); compilation.endTime = Date.now(); stats = new Stats(compilation); } + this.startTime = null; if (err) return handleError(err); + const cbs = this.callbacks; + this.callbacks = []; logger.time("done hook"); - this.compiler.hooks.done.callAsync(stats, err => { + this.compiler.hooks.done.callAsync(/** @type {Stats} */ (stats), err => { logger.timeEnd("done hook"); - if (err) return handleError(err); + if (err) return handleError(err, cbs); this.handler(null, stats); logger.time("storeBuildDependencies"); this.compiler.cache.storeBuildDependencies( - compilation.buildDependencies, + /** @type {Compilation} */ + (compilation).buildDependencies, err => { logger.timeEnd("storeBuildDependencies"); - if (err) return handleError(err); + if (err) return handleError(err, cbs); logger.time("beginIdle"); this.compiler.cache.beginIdle(); this.compiler.idle = true; @@ -213,15 +329,17 @@ class Watching { process.nextTick(() => { if (!this.closed) { this.watch( - compilation.fileDependencies, - compilation.contextDependencies, - compilation.missingDependencies + /** @type {Compilation} */ + (compilation).fileDependencies, + /** @type {Compilation} */ + (compilation).contextDependencies, + /** @type {Compilation} */ + (compilation).missingDependencies ); } }); - for (const cb of this.callbacks) cb(); - this.callbacks.length = 0; - this.compiler.hooks.afterDone.call(stats); + for (const cb of cbs) cb(null); + this.compiler.hooks.afterDone.call(/** @type {Stats} */ (stats)); } ); }); @@ -235,45 +353,45 @@ class Watching { */ watch(files, dirs, missing) { this.pausedWatcher = null; - this.watcher = this.compiler.watchFileSystem.watch( - files, - dirs, - missing, - this.startTime, - this.watchOptions, - ( - err, - fileTimeInfoEntries, - contextTimeInfoEntries, - changedFiles, - removedFiles - ) => { - this.pausedWatcher = this.watcher; - this.watcher = null; - if (err) { - this.compiler.modifiedFiles = undefined; - this.compiler.removedFiles = undefined; - this.compiler.fileTimestamps = undefined; - this.compiler.contextTimestamps = undefined; - return this.handler(err); - } - this.compiler.fileTimestamps = fileTimeInfoEntries; - this.compiler.contextTimestamps = contextTimeInfoEntries; - this.compiler.removedFiles = removedFiles; - this.compiler.modifiedFiles = changedFiles; - if (this.watcher) { - this.pausedWatcher = this.watcher; - this.watcher.pause(); - this.watcher = null; + this.watcher = + /** @type {WatchFileSystem} */ + (this.compiler.watchFileSystem).watch( + files, + dirs, + missing, + /** @type {number} */ (this.lastWatcherStartTime), + this.watchOptions, + ( + err, + fileTimeInfoEntries, + contextTimeInfoEntries, + changedFiles, + removedFiles + ) => { + if (err) { + this.compiler.modifiedFiles = undefined; + this.compiler.removedFiles = undefined; + this.compiler.fileTimestamps = undefined; + this.compiler.contextTimestamps = undefined; + this.compiler.fsStartTime = undefined; + return this.handler(err); + } + this._invalidate( + fileTimeInfoEntries, + contextTimeInfoEntries, + changedFiles, + removedFiles + ); + this._onChange(); + }, + (fileName, changeTime) => { + if (!this._invalidReported) { + this._invalidReported = true; + this.compiler.hooks.invalid.call(fileName, changeTime); + } + this._onInvalid(); } - this._invalidate(); - this._onChange(); - }, - (fileName, changeTime) => { - this.compiler.hooks.invalid.call(fileName, changeTime); - this._onInvalid(); - } - ); + ); } /** @@ -284,36 +402,42 @@ class Watching { if (callback) { this.callbacks.push(callback); } - if (!this._initial) { + if (!this._invalidReported) { + this._invalidReported = true; this.compiler.hooks.invalid.call(null, Date.now()); } + this._onChange(); this._invalidate(); } - _invalidate() { - if (this.suspended) return; - if (this._isBlocked()) { - this.blocked = true; + /** + * @param {TimeInfoEntries=} fileTimeInfoEntries info for files + * @param {TimeInfoEntries=} contextTimeInfoEntries info for directories + * @param {ReadonlySet=} changedFiles changed files + * @param {ReadonlySet=} removedFiles removed files + * @returns {void} + */ + _invalidate( + fileTimeInfoEntries, + contextTimeInfoEntries, + changedFiles, + removedFiles + ) { + if (this.suspended || (this._isBlocked() && (this.blocked = true))) { + this._mergeWithCollected(changedFiles, removedFiles); return; } - if (this.watcher) { - this.compiler.modifiedFiles = - this.watcher.getAggregatedChanges && - this.watcher.getAggregatedChanges(); - this.compiler.removedFiles = - this.watcher.getAggregatedRemovals && - this.watcher.getAggregatedRemovals(); - this.compiler.fileTimestamps = this.watcher.getFileTimeInfoEntries(); - this.compiler.contextTimestamps = this.watcher.getContextTimeInfoEntries(); - this.pausedWatcher = this.watcher; - this.watcher.pause(); - this.watcher = null; - } if (this.running) { + this._mergeWithCollected(changedFiles, removedFiles); this.invalid = true; } else { - this._go(); + this._go( + fileTimeInfoEntries, + contextTimeInfoEntries, + changedFiles, + removedFiles + ); } } @@ -328,14 +452,6 @@ class Watching { } } - _checkUnblocked() { - if (this.blocked && !this._isBlocked()) { - this.blocked = false; - this._needWatcherInfo = true; - this._invalidate(); - } - } - /** * @param {Callback} callback signals when the watcher is closed * @returns {void} @@ -347,6 +463,10 @@ class Watching { } return; } + /** + * @param {WebpackError | null} err error if any + * @param {Compilation=} compilation compilation if any + */ const finalCallback = (err, compilation) => { this.running = false; this.compiler.running = false; @@ -356,26 +476,30 @@ class Watching { this.compiler.removedFiles = undefined; this.compiler.fileTimestamps = undefined; this.compiler.contextTimestamps = undefined; - const shutdown = () => { - this.compiler.cache.shutdown(err => { - this.compiler.hooks.watchClose.call(); - const closeCallbacks = this._closeCallbacks; - this._closeCallbacks = undefined; - for (const cb of closeCallbacks) cb(err); - }); + this.compiler.fsStartTime = undefined; + /** + * @param {WebpackError | null} err error if any + */ + const shutdown = err => { + this.compiler.hooks.watchClose.call(); + const closeCallbacks = + /** @type {Callback[]} */ + (this._closeCallbacks); + this._closeCallbacks = undefined; + for (const cb of closeCallbacks) cb(err); }; if (compilation) { const logger = compilation.getLogger("webpack.Watching"); logger.time("storeBuildDependencies"); this.compiler.cache.storeBuildDependencies( compilation.buildDependencies, - err => { + err2 => { logger.timeEnd("storeBuildDependencies"); - shutdown(); + shutdown(err || err2); } ); } else { - shutdown(); + shutdown(err); } }; @@ -396,7 +520,7 @@ class Watching { this.invalid = true; this._done = finalCallback; } else { - finalCallback(); + finalCallback(null); } } } diff --git a/lib/WebpackError.js b/lib/WebpackError.js index 9b972e8f8f6..d20d816b246 100644 --- a/lib/WebpackError.js +++ b/lib/WebpackError.js @@ -11,6 +11,8 @@ const makeSerializable = require("./util/makeSerializable"); /** @typedef {import("./Chunk")} Chunk */ /** @typedef {import("./Dependency").DependencyLocation} DependencyLocation */ /** @typedef {import("./Module")} Module */ +/** @typedef {import("./serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */ +/** @typedef {import("./serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */ class WebpackError extends Error { /** @@ -20,25 +22,27 @@ class WebpackError extends Error { constructor(message) { super(message); + /** @type {string=} */ this.details = undefined; - /** @type {Module} */ + /** @type {(Module | null)=} */ this.module = undefined; - /** @type {DependencyLocation} */ + /** @type {DependencyLocation=} */ this.loc = undefined; - /** @type {boolean} */ + /** @type {boolean=} */ this.hideStack = undefined; - /** @type {Chunk} */ + /** @type {Chunk=} */ this.chunk = undefined; - /** @type {string} */ + /** @type {string=} */ this.file = undefined; - - Error.captureStackTrace(this, this.constructor); } [inspect]() { return this.stack + (this.details ? `\n${this.details}` : ""); } + /** + * @param {ObjectSerializerContext} context context + */ serialize({ write }) { write(this.name); write(this.message); @@ -48,6 +52,9 @@ class WebpackError extends Error { write(this.hideStack); } + /** + * @param {ObjectDeserializerContext} context context + */ deserialize({ read }) { this.name = read(); this.message = read(); diff --git a/lib/WebpackIsIncludedPlugin.js b/lib/WebpackIsIncludedPlugin.js index 93d44bb9dec..981cf8f6dff 100644 --- a/lib/WebpackIsIncludedPlugin.js +++ b/lib/WebpackIsIncludedPlugin.js @@ -6,15 +6,24 @@ "use strict"; const IgnoreErrorModuleFactory = require("./IgnoreErrorModuleFactory"); +const { + JAVASCRIPT_MODULE_TYPE_AUTO, + JAVASCRIPT_MODULE_TYPE_DYNAMIC, + JAVASCRIPT_MODULE_TYPE_ESM +} = require("./ModuleTypeConstants"); const WebpackIsIncludedDependency = require("./dependencies/WebpackIsIncludedDependency"); const { toConstantDependency } = require("./javascript/JavascriptParserHelpers"); -/** @typedef {import("enhanced-resolve/lib/Resolver")} Resolver */ +/** @typedef {import("enhanced-resolve").Resolver} Resolver */ /** @typedef {import("./Compiler")} Compiler */ +/** @typedef {import("./Dependency").DependencyLocation} DependencyLocation */ /** @typedef {import("./Module")} Module */ /** @typedef {import("./javascript/JavascriptParser")} JavascriptParser */ +/** @typedef {import("./javascript/JavascriptParser").Range} Range */ + +const PLUGIN_NAME = "WebpackIsIncludedPlugin"; class WebpackIsIncludedPlugin { /** @@ -23,7 +32,7 @@ class WebpackIsIncludedPlugin { */ apply(compiler) { compiler.hooks.compilation.tap( - "WebpackIsIncludedPlugin", + PLUGIN_NAME, (compilation, { normalModuleFactory }) => { compilation.dependencyFactories.set( WebpackIsIncludedDependency, @@ -41,7 +50,7 @@ class WebpackIsIncludedPlugin { const handler = parser => { parser.hooks.call .for("__webpack_is_included__") - .tap("WebpackIsIncludedPlugin", expr => { + .tap(PLUGIN_NAME, expr => { if ( expr.type !== "CallExpression" || expr.arguments.length !== 1 || @@ -54,29 +63,29 @@ class WebpackIsIncludedPlugin { if (!request.isString()) return; const dep = new WebpackIsIncludedDependency( - request.string, - expr.range + /** @type {string} */ (request.string), + /** @type {Range} */ (expr.range) ); - dep.loc = expr.loc; + dep.loc = /** @type {DependencyLocation} */ (expr.loc); parser.state.module.addDependency(dep); return true; }); parser.hooks.typeof .for("__webpack_is_included__") .tap( - "WebpackIsIncludedPlugin", + PLUGIN_NAME, toConstantDependency(parser, JSON.stringify("function")) ); }; normalModuleFactory.hooks.parser - .for("javascript/auto") - .tap("WebpackIsIncludedPlugin", handler); + .for(JAVASCRIPT_MODULE_TYPE_AUTO) + .tap(PLUGIN_NAME, handler); normalModuleFactory.hooks.parser - .for("javascript/dynamic") - .tap("WebpackIsIncludedPlugin", handler); + .for(JAVASCRIPT_MODULE_TYPE_DYNAMIC) + .tap(PLUGIN_NAME, handler); normalModuleFactory.hooks.parser - .for("javascript/esm") - .tap("WebpackIsIncludedPlugin", handler); + .for(JAVASCRIPT_MODULE_TYPE_ESM) + .tap(PLUGIN_NAME, handler); } ); } diff --git a/lib/WebpackOptionsApply.js b/lib/WebpackOptionsApply.js index ccbc817cc53..0521b8bfbf2 100644 --- a/lib/WebpackOptionsApply.js +++ b/lib/WebpackOptionsApply.js @@ -35,6 +35,7 @@ const ResolverCachePlugin = require("./cache/ResolverCachePlugin"); const CommonJsPlugin = require("./dependencies/CommonJsPlugin"); const HarmonyModulesPlugin = require("./dependencies/HarmonyModulesPlugin"); +const ImportMetaContextPlugin = require("./dependencies/ImportMetaContextPlugin"); const ImportMetaPlugin = require("./dependencies/ImportMetaPlugin"); const ImportPlugin = require("./dependencies/ImportPlugin"); const LoaderPlugin = require("./dependencies/LoaderPlugin"); @@ -56,6 +57,8 @@ const { cleverMerge } = require("./util/cleverMerge"); /** @typedef {import("../declarations/WebpackOptions").WebpackOptionsNormalized} WebpackOptions */ /** @typedef {import("./Compiler")} Compiler */ +/** @typedef {import("./util/fs").InputFileSystem} InputFileSystem */ +/** @typedef {import("./util/fs").IntermediateFileSystem} IntermediateFileSystem */ class WebpackOptionsApply extends OptionsApply { constructor() { @@ -68,13 +71,13 @@ class WebpackOptionsApply extends OptionsApply { * @returns {WebpackOptions} options object */ process(options, compiler) { - compiler.outputPath = options.output.path; + compiler.outputPath = /** @type {string} */ (options.output.path); compiler.recordsInputPath = options.recordsInputPath || null; compiler.recordsOutputPath = options.recordsOutputPath || null; compiler.name = options.name; if (options.externals) { - //@ts-expect-error https://github.com/microsoft/TypeScript/issues/41697 + // @ts-expect-error https://github.com/microsoft/TypeScript/issues/41697 const ExternalsPlugin = require("./ExternalsPlugin"); new ExternalsPlugin(options.externalsType, options.externals).apply( compiler @@ -86,17 +89,17 @@ class WebpackOptionsApply extends OptionsApply { new NodeTargetPlugin().apply(compiler); } if (options.externalsPresets.electronMain) { - //@ts-expect-error https://github.com/microsoft/TypeScript/issues/41697 + // @ts-expect-error https://github.com/microsoft/TypeScript/issues/41697 const ElectronTargetPlugin = require("./electron/ElectronTargetPlugin"); new ElectronTargetPlugin("main").apply(compiler); } if (options.externalsPresets.electronPreload) { - //@ts-expect-error https://github.com/microsoft/TypeScript/issues/41697 + // @ts-expect-error https://github.com/microsoft/TypeScript/issues/41697 const ElectronTargetPlugin = require("./electron/ElectronTargetPlugin"); new ElectronTargetPlugin("preload").apply(compiler); } if (options.externalsPresets.electronRenderer) { - //@ts-expect-error https://github.com/microsoft/TypeScript/issues/41697 + // @ts-expect-error https://github.com/microsoft/TypeScript/issues/41697 const ElectronTargetPlugin = require("./electron/ElectronTargetPlugin"); new ElectronTargetPlugin("renderer").apply(compiler); } @@ -106,23 +109,69 @@ class WebpackOptionsApply extends OptionsApply { !options.externalsPresets.electronPreload && !options.externalsPresets.electronRenderer ) { - //@ts-expect-error https://github.com/microsoft/TypeScript/issues/41697 + // @ts-expect-error https://github.com/microsoft/TypeScript/issues/41697 const ElectronTargetPlugin = require("./electron/ElectronTargetPlugin"); new ElectronTargetPlugin().apply(compiler); } if (options.externalsPresets.nwjs) { - //@ts-expect-error https://github.com/microsoft/TypeScript/issues/41697 + // @ts-expect-error https://github.com/microsoft/TypeScript/issues/41697 const ExternalsPlugin = require("./ExternalsPlugin"); - new ExternalsPlugin("commonjs", "nw.gui").apply(compiler); + new ExternalsPlugin("node-commonjs", "nw.gui").apply(compiler); } if (options.externalsPresets.webAsync) { - //@ts-expect-error https://github.com/microsoft/TypeScript/issues/41697 + // @ts-expect-error https://github.com/microsoft/TypeScript/issues/41697 const ExternalsPlugin = require("./ExternalsPlugin"); - new ExternalsPlugin("import", /^(https?:\/\/|std:)/).apply(compiler); + new ExternalsPlugin("import", ({ request, dependencyType }, callback) => { + if (dependencyType === "url") { + if (/^(\/\/|https?:\/\/|#)/.test(request)) + return callback(null, `asset ${request}`); + } else if (options.experiments.css && dependencyType === "css-import") { + if (/^(\/\/|https?:\/\/|#)/.test(request)) + return callback(null, `css-import ${request}`); + } else if ( + options.experiments.css && + /^(\/\/|https?:\/\/|std:)/.test(request) + ) { + if (/^\.css(\?|$)/.test(request)) + return callback(null, `css-import ${request}`); + return callback(null, `import ${request}`); + } + callback(); + }).apply(compiler); } else if (options.externalsPresets.web) { - //@ts-expect-error https://github.com/microsoft/TypeScript/issues/41697 + // @ts-expect-error https://github.com/microsoft/TypeScript/issues/41697 + const ExternalsPlugin = require("./ExternalsPlugin"); + new ExternalsPlugin("module", ({ request, dependencyType }, callback) => { + if (dependencyType === "url") { + if (/^(\/\/|https?:\/\/|#)/.test(request)) + return callback(null, `asset ${request}`); + } else if (options.experiments.css && dependencyType === "css-import") { + if (/^(\/\/|https?:\/\/|#)/.test(request)) + return callback(null, `css-import ${request}`); + } else if (/^(\/\/|https?:\/\/|std:)/.test(request)) { + if (options.experiments.css && /^\.css((\?)|$)/.test(request)) + return callback(null, `css-import ${request}`); + return callback(null, `module ${request}`); + } + callback(); + }).apply(compiler); + } else if (options.externalsPresets.node && options.experiments.css) { + // @ts-expect-error https://github.com/microsoft/TypeScript/issues/41697 const ExternalsPlugin = require("./ExternalsPlugin"); - new ExternalsPlugin("module", /^(https?:\/\/|std:)/).apply(compiler); + new ExternalsPlugin("module", ({ request, dependencyType }, callback) => { + if (dependencyType === "url") { + if (/^(\/\/|https?:\/\/|#)/.test(request)) + return callback(null, `asset ${request}`); + } else if (dependencyType === "css-import") { + if (/^(\/\/|https?:\/\/|#)/.test(request)) + return callback(null, `css-import ${request}`); + } else if (/^(\/\/|https?:\/\/|std:)/.test(request)) { + if (/^\.css(\?|$)/.test(request)) + return callback(null, `css-import ${request}`); + return callback(null, `module ${request}`); + } + callback(); + }).apply(compiler); } new ChunkPrefetchPreloadPlugin().apply(compiler); @@ -139,33 +188,46 @@ class WebpackOptionsApply extends OptionsApply { new CommonJsChunkFormatPlugin().apply(compiler); break; } - case "module": - throw new Error( - "EcmaScript Module Chunk Format is not implemented yet" - ); + case "module": { + const ModuleChunkFormatPlugin = require("./esm/ModuleChunkFormatPlugin"); + new ModuleChunkFormatPlugin().apply(compiler); + break; + } default: throw new Error( - "Unsupported chunk format '" + options.output.chunkFormat + "'." + `Unsupported chunk format '${options.output.chunkFormat}'.` ); } } - if (options.output.enabledChunkLoadingTypes.length > 0) { - for (const type of options.output.enabledChunkLoadingTypes) { + const enabledChunkLoadingTypes = + /** @type {NonNullable} */ + (options.output.enabledChunkLoadingTypes); + + if (enabledChunkLoadingTypes.length > 0) { + for (const type of enabledChunkLoadingTypes) { const EnableChunkLoadingPlugin = require("./javascript/EnableChunkLoadingPlugin"); new EnableChunkLoadingPlugin(type).apply(compiler); } } - if (options.output.enabledWasmLoadingTypes.length > 0) { - for (const type of options.output.enabledWasmLoadingTypes) { + const enabledWasmLoadingTypes = + /** @type {NonNullable} */ + (options.output.enabledWasmLoadingTypes); + + if (enabledWasmLoadingTypes.length > 0) { + for (const type of enabledWasmLoadingTypes) { const EnableWasmLoadingPlugin = require("./wasm/EnableWasmLoadingPlugin"); new EnableWasmLoadingPlugin(type).apply(compiler); } } - if (options.output.enabledLibraryTypes.length > 0) { - for (const type of options.output.enabledLibraryTypes) { + const enabledLibraryTypes = + /** @type {NonNullable} */ + (options.output.enabledLibraryTypes); + + if (enabledLibraryTypes.length > 0) { + for (const type of enabledLibraryTypes) { const EnableLibraryPlugin = require("./library/EnableLibraryPlugin"); new EnableLibraryPlugin(type).apply(compiler); } @@ -202,9 +264,9 @@ class WebpackOptionsApply extends OptionsApply { fallbackModuleFilenameTemplate: options.output.devtoolFallbackModuleFilenameTemplate, append: hidden ? false : undefined, - module: moduleMaps ? true : cheap ? false : true, - columns: cheap ? false : true, - noSources: noSources, + module: moduleMaps ? true : !cheap, + columns: !cheap, + noSources, namespace: options.output.devtoolNamespace }).apply(compiler); } else if (options.devtool.includes("eval")) { @@ -231,7 +293,15 @@ class WebpackOptionsApply extends OptionsApply { "library type \"module\" is only allowed when 'experiments.outputModule' is enabled" ); } - if (options.externalsType === "module") { + if (options.output.enabledLibraryTypes.includes("modern-module")) { + throw new Error( + "library type \"modern-module\" is only allowed when 'experiments.outputModule' is enabled" + ); + } + if ( + options.externalsType === "module" || + options.externalsType === "module-import" + ) { throw new Error( "'externalsType: \"module\"' is only allowed when 'experiments.outputModule' is enabled" ); @@ -252,31 +322,49 @@ class WebpackOptionsApply extends OptionsApply { }).apply(compiler); } + if (options.experiments.css) { + const CssModulesPlugin = require("./css/CssModulesPlugin"); + new CssModulesPlugin().apply(compiler); + } + if (options.experiments.lazyCompilation) { const LazyCompilationPlugin = require("./hmr/LazyCompilationPlugin"); const lazyOptions = typeof options.experiments.lazyCompilation === "object" ? options.experiments.lazyCompilation - : null; + : {}; new LazyCompilationPlugin({ backend: - (lazyOptions && lazyOptions.backend) || - require("./hmr/lazyCompilationBackend"), - client: - (lazyOptions && lazyOptions.client) || - require.resolve( - `../hot/lazy-compilation-${ - options.externalsPresets.node ? "node" : "web" - }.js` - ), + typeof lazyOptions.backend === "function" + ? lazyOptions.backend + : require("./hmr/lazyCompilationBackend")({ + ...lazyOptions.backend, + client: + (lazyOptions.backend && lazyOptions.backend.client) || + require.resolve( + `../hot/lazy-compilation-${ + options.externalsPresets.node ? "node" : "web" + }.js` + ) + }), entries: !lazyOptions || lazyOptions.entries !== false, imports: !lazyOptions || lazyOptions.imports !== false, test: (lazyOptions && lazyOptions.test) || undefined }).apply(compiler); } + if (options.experiments.buildHttp) { + const HttpUriPlugin = require("./schemes/HttpUriPlugin"); + const httpOptions = options.experiments.buildHttp; + new HttpUriPlugin(httpOptions).apply(compiler); + } + new EntryOptionPlugin().apply(compiler); - compiler.hooks.entryOption.call(options.context, options.entry); + compiler.hooks.entryOption.call( + /** @type {string} */ + (options.context), + options.entry + ); new RuntimePlugin().apply(compiler); @@ -296,12 +384,14 @@ class WebpackOptionsApply extends OptionsApply { new RequireJsStuffPlugin().apply(compiler); } new CommonJsPlugin().apply(compiler); - new LoaderPlugin().apply(compiler); + new LoaderPlugin({}).apply(compiler); if (options.node !== false) { const NodeStuffPlugin = require("./NodeStuffPlugin"); new NodeStuffPlugin(options.node).apply(compiler); } - new APIPlugin().apply(compiler); + new APIPlugin({ + module: options.output.module + }).apply(compiler); new ExportsInfoApiPlugin().apply(compiler); new WebpackIsIncludedPlugin().apply(compiler); new ConstPlugin().apply(compiler); @@ -310,12 +400,15 @@ class WebpackOptionsApply extends OptionsApply { new RequireEnsurePlugin().apply(compiler); new RequireContextPlugin().apply(compiler); new ImportPlugin().apply(compiler); + new ImportMetaContextPlugin().apply(compiler); new SystemPlugin().apply(compiler); new ImportMetaPlugin().apply(compiler); new URLPlugin().apply(compiler); new WorkerPlugin( options.output.workerChunkLoading, - options.output.workerWasmLoading + options.output.workerWasmLoading, + options.output.module, + options.output.workerPublicPath ).apply(compiler); new DefaultStatsFactoryPlugin().apply(compiler); @@ -383,7 +476,10 @@ class WebpackOptionsApply extends OptionsApply { } if (options.optimization.runtimeChunk) { const RuntimeChunkPlugin = require("./optimize/RuntimeChunkPlugin"); - new RuntimeChunkPlugin(options.optimization.runtimeChunk).apply(compiler); + new RuntimeChunkPlugin( + /** @type {{ name?: (entrypoint: { name: string }) => string }} */ + (options.optimization.runtimeChunk) + ).apply(compiler); } if (!options.optimization.emitOnErrors) { const NoEmitOnErrorsPlugin = require("./NoEmitOnErrorsPlugin"); @@ -421,7 +517,9 @@ class WebpackOptionsApply extends OptionsApply { "hashed", "deterministic" ).apply(compiler); - new HashedModuleIdsPlugin().apply(compiler); + new HashedModuleIdsPlugin({ + hashFunction: options.output.hashFunction + }).apply(compiler); break; } case "deterministic": { @@ -461,7 +559,7 @@ class WebpackOptionsApply extends OptionsApply { break; } case "size": { - //@ts-expect-error https://github.com/microsoft/TypeScript/issues/41697 + // @ts-expect-error https://github.com/microsoft/TypeScript/issues/41697 const OccurrenceChunkIdsPlugin = require("./ids/OccurrenceChunkIdsPlugin"); new OccurrenceChunkIdsPlugin({ prioritiseInitial: true @@ -469,7 +567,7 @@ class WebpackOptionsApply extends OptionsApply { break; } case "total-size": { - //@ts-expect-error https://github.com/microsoft/TypeScript/issues/41697 + // @ts-expect-error https://github.com/microsoft/TypeScript/issues/41697 const OccurrenceChunkIdsPlugin = require("./ids/OccurrenceChunkIdsPlugin"); new OccurrenceChunkIdsPlugin({ prioritiseInitial: false @@ -492,7 +590,7 @@ class WebpackOptionsApply extends OptionsApply { for (const minimizer of options.optimization.minimizer) { if (typeof minimizer === "function") { minimizer.call(compiler, compiler); - } else if (minimizer !== "...") { + } else if (minimizer !== "..." && minimizer) { minimizer.apply(compiler); } } @@ -513,28 +611,67 @@ class WebpackOptionsApply extends OptionsApply { const AddManagedPathsPlugin = require("./cache/AddManagedPathsPlugin"); new AddManagedPathsPlugin( - options.snapshot.managedPaths, - options.snapshot.immutablePaths + /** @type {NonNullable} */ + (options.snapshot.managedPaths), + /** @type {NonNullable} */ + (options.snapshot.immutablePaths), + /** @type {NonNullable} */ + (options.snapshot.unmanagedPaths) ).apply(compiler); if (options.cache && typeof options.cache === "object") { const cacheOptions = options.cache; switch (cacheOptions.type) { case "memory": { - //@ts-expect-error https://github.com/microsoft/TypeScript/issues/41697 - const MemoryCachePlugin = require("./cache/MemoryCachePlugin"); - new MemoryCachePlugin().apply(compiler); + if (Number.isFinite(cacheOptions.maxGenerations)) { + // @ts-expect-error https://github.com/microsoft/TypeScript/issues/41697 + const MemoryWithGcCachePlugin = require("./cache/MemoryWithGcCachePlugin"); + new MemoryWithGcCachePlugin({ + maxGenerations: + /** @type {number} */ + (cacheOptions.maxGenerations) + }).apply(compiler); + } else { + // @ts-expect-error https://github.com/microsoft/TypeScript/issues/41697 + const MemoryCachePlugin = require("./cache/MemoryCachePlugin"); + new MemoryCachePlugin().apply(compiler); + } + if (cacheOptions.cacheUnaffected) { + if (!options.experiments.cacheUnaffected) { + throw new Error( + "'cache.cacheUnaffected: true' is only allowed when 'experiments.cacheUnaffected' is enabled" + ); + } + compiler.moduleMemCaches = new Map(); + } break; } case "filesystem": { const AddBuildDependenciesPlugin = require("./cache/AddBuildDependenciesPlugin"); + // eslint-disable-next-line guard-for-in for (const key in cacheOptions.buildDependencies) { const list = cacheOptions.buildDependencies[key]; new AddBuildDependenciesPlugin(list).apply(compiler); } - //@ts-expect-error https://github.com/microsoft/TypeScript/issues/41697 - const MemoryCachePlugin = require("./cache/MemoryCachePlugin"); - new MemoryCachePlugin().apply(compiler); + if (!Number.isFinite(cacheOptions.maxMemoryGenerations)) { + // @ts-expect-error https://github.com/microsoft/TypeScript/issues/41697 + const MemoryCachePlugin = require("./cache/MemoryCachePlugin"); + new MemoryCachePlugin().apply(compiler); + } else if (cacheOptions.maxMemoryGenerations !== 0) { + // @ts-expect-error https://github.com/microsoft/TypeScript/issues/41697 + const MemoryWithGcCachePlugin = require("./cache/MemoryWithGcCachePlugin"); + new MemoryWithGcCachePlugin({ + maxGenerations: cacheOptions.maxMemoryGenerations + }).apply(compiler); + } + if (cacheOptions.memoryCacheUnaffected) { + if (!options.experiments.cacheUnaffected) { + throw new Error( + "'cache.memoryCacheUnaffected: true' is only allowed when 'experiments.cacheUnaffected' is enabled" + ); + } + compiler.moduleMemCaches = new Map(); + } switch (cacheOptions.store) { case "pack": { const IdleFileCachePlugin = require("./cache/IdleFileCachePlugin"); @@ -542,17 +679,27 @@ class WebpackOptionsApply extends OptionsApply { new IdleFileCachePlugin( new PackFileCacheStrategy({ compiler, - fs: compiler.intermediateFileSystem, - context: options.context, - cacheLocation: cacheOptions.cacheLocation, + fs: + /** @type {IntermediateFileSystem} */ + (compiler.intermediateFileSystem), + context: /** @type {string} */ (options.context), + cacheLocation: + /** @type {string} */ + (cacheOptions.cacheLocation), version: cacheOptions.version, logger: compiler.getInfrastructureLogger( "webpack.cache.PackFileCacheStrategy" ), - snapshot: options.snapshot + snapshot: options.snapshot, + maxAge: /** @type {number} */ (cacheOptions.maxAge), + profile: cacheOptions.profile, + allowCollectingMemory: cacheOptions.allowCollectingMemory, + compression: cacheOptions.compression, + readonly: cacheOptions.readonly }), cacheOptions.idleTimeout, - cacheOptions.idleTimeoutForInitialStore + cacheOptions.idleTimeoutForInitialStore, + cacheOptions.idleTimeoutAfterLargeChanges ).apply(compiler); break; } @@ -581,14 +728,18 @@ class WebpackOptionsApply extends OptionsApply { .for("normal") .tap("WebpackOptionsApply", resolveOptions => { resolveOptions = cleverMerge(options.resolve, resolveOptions); - resolveOptions.fileSystem = compiler.inputFileSystem; + resolveOptions.fileSystem = + /** @type {InputFileSystem} */ + (compiler.inputFileSystem); return resolveOptions; }); compiler.resolverFactory.hooks.resolveOptions .for("context") .tap("WebpackOptionsApply", resolveOptions => { resolveOptions = cleverMerge(options.resolve, resolveOptions); - resolveOptions.fileSystem = compiler.inputFileSystem; + resolveOptions.fileSystem = + /** @type {InputFileSystem} */ + (compiler.inputFileSystem); resolveOptions.resolveToContext = true; return resolveOptions; }); @@ -596,7 +747,9 @@ class WebpackOptionsApply extends OptionsApply { .for("loader") .tap("WebpackOptionsApply", resolveOptions => { resolveOptions = cleverMerge(options.resolveLoader, resolveOptions); - resolveOptions.fileSystem = compiler.inputFileSystem; + resolveOptions.fileSystem = + /** @type {InputFileSystem} */ + (compiler.inputFileSystem); return resolveOptions; }); compiler.hooks.afterResolvers.call(compiler); diff --git a/lib/WebpackOptionsDefaulter.js b/lib/WebpackOptionsDefaulter.js index dd12ddbb530..12fbe698d93 100644 --- a/lib/WebpackOptionsDefaulter.js +++ b/lib/WebpackOptionsDefaulter.js @@ -8,11 +8,18 @@ const { applyWebpackOptionsDefaults } = require("./config/defaults"); const { getNormalizedWebpackOptions } = require("./config/normalization"); +/** @typedef {import("./config/normalization").WebpackOptions} WebpackOptions */ +/** @typedef {import("./config/normalization").WebpackOptionsNormalized} WebpackOptionsNormalized */ + class WebpackOptionsDefaulter { + /** + * @param {WebpackOptions} options webpack options + * @returns {WebpackOptionsNormalized} normalized webpack options + */ process(options) { - options = getNormalizedWebpackOptions(options); - applyWebpackOptionsDefaults(options); - return options; + const normalizedOptions = getNormalizedWebpackOptions(options); + applyWebpackOptionsDefaults(normalizedOptions); + return normalizedOptions; } } diff --git a/lib/asset/AssetGenerator.js b/lib/asset/AssetGenerator.js index d71db6869a0..f5727490e7e 100644 --- a/lib/asset/AssetGenerator.js +++ b/lib/asset/AssetGenerator.js @@ -8,38 +8,257 @@ const mimeTypes = require("mime-types"); const path = require("path"); const { RawSource } = require("webpack-sources"); +const ConcatenationScope = require("../ConcatenationScope"); const Generator = require("../Generator"); +const { ASSET_MODULE_TYPE } = require("../ModuleTypeConstants"); const RuntimeGlobals = require("../RuntimeGlobals"); +const CssUrlDependency = require("../dependencies/CssUrlDependency"); const createHash = require("../util/createHash"); const { makePathsRelative } = require("../util/identifier"); +const nonNumericOnlyHash = require("../util/nonNumericOnlyHash"); /** @typedef {import("webpack-sources").Source} Source */ +/** @typedef {import("../../declarations/WebpackOptions").AssetGeneratorDataUrlOptions} AssetGeneratorDataUrlOptions */ /** @typedef {import("../../declarations/WebpackOptions").AssetGeneratorOptions} AssetGeneratorOptions */ +/** @typedef {import("../../declarations/WebpackOptions").AssetModuleFilename} AssetModuleFilename */ +/** @typedef {import("../../declarations/WebpackOptions").AssetModuleOutputPath} AssetModuleOutputPath */ +/** @typedef {import("../../declarations/WebpackOptions").RawPublicPath} RawPublicPath */ /** @typedef {import("../Compilation")} Compilation */ /** @typedef {import("../Compiler")} Compiler */ /** @typedef {import("../Generator").GenerateContext} GenerateContext */ /** @typedef {import("../Generator").UpdateHashContext} UpdateHashContext */ /** @typedef {import("../Module")} Module */ +/** @typedef {import("../Module").BuildInfo} BuildInfo */ +/** @typedef {import("../Module").ConcatenationBailoutReasonContext} ConcatenationBailoutReasonContext */ /** @typedef {import("../NormalModule")} NormalModule */ /** @typedef {import("../RuntimeTemplate")} RuntimeTemplate */ +/** @typedef {import("../TemplatedPathPlugin").TemplatePath} TemplatePath */ /** @typedef {import("../util/Hash")} Hash */ +/** @typedef {import("../util/createHash").Algorithm} Algorithm */ + +/** + * @template T + * @template U + * @param {Array | Set} a a + * @param {Array | Set} b b + * @returns {Array & Array} array + */ +const mergeMaybeArrays = (a, b) => { + const set = new Set(); + if (Array.isArray(a)) for (const item of a) set.add(item); + else set.add(a); + if (Array.isArray(b)) for (const item of b) set.add(item); + else set.add(b); + return Array.from(set); +}; + +/** + * @template {object} T + * @template {object} U + * @param {TODO} a a + * @param {TODO} b b + * @returns {T & U} object + */ +const mergeAssetInfo = (a, b) => { + const result = { ...a, ...b }; + for (const key of Object.keys(a)) { + if (key in b) { + if (a[key] === b[key]) continue; + switch (key) { + case "fullhash": + case "chunkhash": + case "modulehash": + case "contenthash": + result[key] = mergeMaybeArrays(a[key], b[key]); + break; + case "immutable": + case "development": + case "hotModuleReplacement": + case "javascriptModule": + result[key] = a[key] || b[key]; + break; + case "related": + result[key] = mergeRelatedInfo(a[key], b[key]); + break; + default: + throw new Error(`Can't handle conflicting asset info for ${key}`); + } + } + } + return result; +}; + +/** + * @template {object} T + * @template {object} U + * @param {TODO} a a + * @param {TODO} b b + * @returns {T & U} object + */ +const mergeRelatedInfo = (a, b) => { + const result = { ...a, ...b }; + for (const key of Object.keys(a)) { + if (key in b) { + if (a[key] === b[key]) continue; + result[key] = mergeMaybeArrays(a[key], b[key]); + } + } + return result; +}; + +/** + * @param {"base64" | false} encoding encoding + * @param {Source} source source + * @returns {string} encoded data + */ +const encodeDataUri = (encoding, source) => { + /** @type {string | undefined} */ + let encodedContent; + + switch (encoding) { + case "base64": { + encodedContent = source.buffer().toString("base64"); + break; + } + case false: { + const content = source.source(); + + if (typeof content !== "string") { + encodedContent = content.toString("utf-8"); + } + + encodedContent = encodeURIComponent( + /** @type {string} */ + (encodedContent) + ).replace( + /[!'()*]/g, + character => + `%${/** @type {number} */ (character.codePointAt(0)).toString(16)}` + ); + break; + } + default: + throw new Error(`Unsupported encoding '${encoding}'`); + } + + return encodedContent; +}; + +/** + * @param {string} encoding encoding + * @param {string} content content + * @returns {Buffer} decoded content + */ +const decodeDataUriContent = (encoding, content) => { + const isBase64 = encoding === "base64"; + + if (isBase64) { + return Buffer.from(content, "base64"); + } + + // If we can't decode return the original body + try { + return Buffer.from(decodeURIComponent(content), "ascii"); + } catch (_) { + return Buffer.from(content, "ascii"); + } +}; const JS_TYPES = new Set(["javascript"]); -const JS_AND_ASSET_TYPES = new Set(["javascript", "asset"]); +const JS_AND_ASSET_TYPES = new Set(["javascript", ASSET_MODULE_TYPE]); +const DEFAULT_ENCODING = "base64"; class AssetGenerator extends Generator { /** * @param {AssetGeneratorOptions["dataUrl"]=} dataUrlOptions the options for the data url - * @param {string=} filename override for output.assetModuleFilename + * @param {AssetModuleFilename=} filename override for output.assetModuleFilename + * @param {RawPublicPath=} publicPath override for output.assetModulePublicPath + * @param {AssetModuleOutputPath=} outputPath the output path for the emitted file which is not included in the runtime import * @param {boolean=} emit generate output asset */ - constructor(dataUrlOptions, filename, emit) { + constructor(dataUrlOptions, filename, publicPath, outputPath, emit) { super(); this.dataUrlOptions = dataUrlOptions; this.filename = filename; + this.publicPath = publicPath; + this.outputPath = outputPath; this.emit = emit; } + /** + * @param {NormalModule} module module + * @param {RuntimeTemplate} runtimeTemplate runtime template + * @returns {string} source file name + */ + getSourceFileName(module, runtimeTemplate) { + return makePathsRelative( + runtimeTemplate.compilation.compiler.context, + module.matchResource || module.resource, + runtimeTemplate.compilation.compiler.root + ).replace(/^\.\//, ""); + } + + /** + * @param {NormalModule} module module for which the bailout reason should be determined + * @param {ConcatenationBailoutReasonContext} context context + * @returns {string | undefined} reason why this module can't be concatenated, undefined when it can be concatenated + */ + getConcatenationBailoutReason(module, context) { + return undefined; + } + + /** + * @param {NormalModule} module module + * @returns {string} mime type + */ + getMimeType(module) { + if (typeof this.dataUrlOptions === "function") { + throw new Error( + "This method must not be called when dataUrlOptions is a function" + ); + } + + /** @type {string | boolean | undefined} */ + let mimeType = + /** @type {AssetGeneratorDataUrlOptions} */ + (this.dataUrlOptions).mimetype; + if (mimeType === undefined) { + const ext = path.extname( + /** @type {string} */ + (module.nameForCondition()) + ); + if ( + module.resourceResolveData && + module.resourceResolveData.mimetype !== undefined + ) { + mimeType = + module.resourceResolveData.mimetype + + module.resourceResolveData.parameters; + } else if (ext) { + mimeType = mimeTypes.lookup(ext); + + if (typeof mimeType !== "string") { + throw new Error( + "DataUrl can't be generated automatically, " + + `because there is no mimetype for "${ext}" in mimetype database. ` + + 'Either pass a mimetype via "generator.mimetype" or ' + + 'use type: "asset/resource" to create a resource file instead of a DataUrl' + ); + } + } + } + + if (typeof mimeType !== "string") { + throw new Error( + "DataUrl can't be generated automatically. " + + 'Either pass a mimetype via "generator.mimetype" or ' + + 'use type: "asset/resource" to create a resource file instead of a DataUrl' + ); + } + + return /** @type {string} */ (mimeType); + } + /** * @param {NormalModule} module module for which the code should be generated * @param {GenerateContext} generateContext context for generate @@ -47,16 +266,26 @@ class AssetGenerator extends Generator { */ generate( module, - { runtime, chunkGraph, runtimeTemplate, runtimeRequirements, type, getData } + { + runtime, + concatenationScope, + chunkGraph, + runtimeTemplate, + runtimeRequirements, + type, + getData + } ) { switch (type) { - case "asset": - return module.originalSource(); + case ASSET_MODULE_TYPE: + return /** @type {Source} */ (module.originalSource()); default: { - runtimeRequirements.add(RuntimeGlobals.module); - - const originalSource = module.originalSource(); - if (module.buildInfo.dataUrl) { + let content; + const originalSource = /** @type {Source} */ (module.originalSource()); + if ( + /** @type {BuildInfo} */ + (module.buildInfo).dataUrl + ) { let encodedSource; if (typeof this.dataUrlOptions === "function") { encodedSource = this.dataUrlOptions.call( @@ -68,87 +297,143 @@ class AssetGenerator extends Generator { } ); } else { - const encoding = this.dataUrlOptions.encoding; - const ext = path.extname(module.nameForCondition()); - const mimeType = - this.dataUrlOptions.mimetype || mimeTypes.lookup(ext); - - if (!mimeType) { - throw new Error( - "DataUrl can't be generated automatically, " + - `because there is no mimetype for "${ext}" in mimetype database. ` + - 'Either pass a mimetype via "generator.mimetype" or ' + - 'use type: "asset/resource" to create a resource file instead of a DataUrl' - ); + /** @type {"base64" | false | undefined} */ + let encoding = + /** @type {AssetGeneratorDataUrlOptions} */ + (this.dataUrlOptions).encoding; + if ( + encoding === undefined && + module.resourceResolveData && + module.resourceResolveData.encoding !== undefined + ) { + encoding = module.resourceResolveData.encoding; } + if (encoding === undefined) { + encoding = DEFAULT_ENCODING; + } + const mimeType = this.getMimeType(module); let encodedContent; - switch (encoding) { - case "base64": { - encodedContent = originalSource.buffer().toString("base64"); - break; - } - case false: { - const content = originalSource.source(); - if (typeof content === "string") { - encodedContent = encodeURI(content); - } else { - encodedContent = encodeURI(content.toString("utf-8")); - } - break; - } - default: - throw new Error(`Unsupported encoding '${encoding}'`); + + if ( + module.resourceResolveData && + module.resourceResolveData.encoding === encoding && + decodeDataUriContent( + module.resourceResolveData.encoding, + module.resourceResolveData.encodedContent + ).equals(originalSource.buffer()) + ) { + encodedContent = module.resourceResolveData.encodedContent; + } else { + encodedContent = encodeDataUri(encoding, originalSource); } encodedSource = `data:${mimeType}${ encoding ? `;${encoding}` : "" },${encodedContent}`; } - return new RawSource( - `${RuntimeGlobals.module}.exports = ${JSON.stringify( - encodedSource - )};` - ); + const data = + /** @type {NonNullable} */ + (getData)(); + data.set("url", Buffer.from(encodedSource)); + content = JSON.stringify(encodedSource); } else { const assetModuleFilename = - this.filename || runtimeTemplate.outputOptions.assetModuleFilename; - const hash = createHash(runtimeTemplate.outputOptions.hashFunction); + this.filename || + /** @type {AssetModuleFilename} */ + (runtimeTemplate.outputOptions.assetModuleFilename); + const hash = createHash( + /** @type {Algorithm} */ + (runtimeTemplate.outputOptions.hashFunction) + ); if (runtimeTemplate.outputOptions.hashSalt) { hash.update(runtimeTemplate.outputOptions.hashSalt); } hash.update(originalSource.buffer()); - const fullHash = /** @type {string} */ (hash.digest( - runtimeTemplate.outputOptions.hashDigest - )); - const contentHash = fullHash.slice( - 0, - runtimeTemplate.outputOptions.hashDigestLength + const fullHash = /** @type {string} */ ( + hash.digest(runtimeTemplate.outputOptions.hashDigest) ); - module.buildInfo.fullContentHash = fullHash; - const sourceFilename = makePathsRelative( - runtimeTemplate.compilation.compiler.context, - module.matchResource || module.resource, - runtimeTemplate.compilation.compiler.root - ).replace(/^\.\//, ""); - const { - path: filename, - info - } = runtimeTemplate.compilation.getAssetPathWithInfo( - assetModuleFilename, - { - module, - runtime, - filename: sourceFilename, - chunkGraph, - contentHash - } + const contentHash = nonNumericOnlyHash( + fullHash, + /** @type {number} */ + (runtimeTemplate.outputOptions.hashDigestLength) + ); + /** @type {BuildInfo} */ + (module.buildInfo).fullContentHash = fullHash; + const sourceFilename = this.getSourceFileName( + module, + runtimeTemplate ); - module.buildInfo.filename = filename; - module.buildInfo.assetInfo = { + let { path: filename, info: assetInfo } = + runtimeTemplate.compilation.getAssetPathWithInfo( + assetModuleFilename, + { + module, + runtime, + filename: sourceFilename, + chunkGraph, + contentHash + } + ); + let assetPath; + let assetPathForCss; + if (this.publicPath !== undefined) { + const { path, info } = + runtimeTemplate.compilation.getAssetPathWithInfo( + this.publicPath, + { + module, + runtime, + filename: sourceFilename, + chunkGraph, + contentHash + } + ); + assetInfo = mergeAssetInfo(assetInfo, info); + assetPath = JSON.stringify(path + filename); + assetPathForCss = path + filename; + } else { + runtimeRequirements.add(RuntimeGlobals.publicPath); // add __webpack_require__.p + assetPath = runtimeTemplate.concatenation( + { expr: RuntimeGlobals.publicPath }, + filename + ); + const compilation = runtimeTemplate.compilation; + const path = + compilation.outputOptions.publicPath === "auto" + ? CssUrlDependency.PUBLIC_PATH_AUTO + : compilation.getAssetPath( + /** @type {TemplatePath} */ + (compilation.outputOptions.publicPath), + { + hash: compilation.hash + } + ); + assetPathForCss = path + filename; + } + assetInfo = { sourceFilename, - ...info + ...assetInfo }; + if (this.outputPath) { + const { path: outputPath, info } = + runtimeTemplate.compilation.getAssetPathWithInfo( + this.outputPath, + { + module, + runtime, + filename: sourceFilename, + chunkGraph, + contentHash + } + ); + assetInfo = mergeAssetInfo(assetInfo, info); + filename = path.posix.join(outputPath, filename); + } + /** @type {BuildInfo} */ + (module.buildInfo).filename = filename; + /** @type {BuildInfo} */ + (module.buildInfo).assetInfo = assetInfo; if (getData) { // Due to code generation caching module.buildInfo.XXX can't used to store such information // It need to be stored in the code generation results instead, where it's cached too @@ -156,17 +441,24 @@ class AssetGenerator extends Generator { const data = getData(); data.set("fullContentHash", fullHash); data.set("filename", filename); - data.set("assetInfo", info); + data.set("assetInfo", assetInfo); + data.set("assetPathForCss", assetPathForCss); } + content = assetPath; + } - runtimeRequirements.add(RuntimeGlobals.publicPath); // add __webpack_require__.p - + if (concatenationScope) { + concatenationScope.registerNamespaceExport( + ConcatenationScope.NAMESPACE_OBJECT_EXPORT + ); return new RawSource( - `${RuntimeGlobals.module}.exports = ${ - RuntimeGlobals.publicPath - } + ${JSON.stringify(filename)};` + `${runtimeTemplate.supportsConst() ? "const" : "var"} ${ + ConcatenationScope.NAMESPACE_OBJECT_EXPORT + } = ${content};` ); } + runtimeRequirements.add(RuntimeGlobals.module); + return new RawSource(`${RuntimeGlobals.module}.exports = ${content};`); } } } @@ -176,11 +468,10 @@ class AssetGenerator extends Generator { * @returns {Set} available types (do not mutate) */ getTypes(module) { - if (module.buildInfo.dataUrl || this.emit === false) { + if ((module.buildInfo && module.buildInfo.dataUrl) || this.emit === false) { return JS_TYPES; - } else { - return JS_AND_ASSET_TYPES; } + return JS_AND_ASSET_TYPES; } /** @@ -190,7 +481,7 @@ class AssetGenerator extends Generator { */ getSize(module, type) { switch (type) { - case "asset": { + case ASSET_MODULE_TYPE: { const originalSource = module.originalSource(); if (!originalSource) { @@ -200,7 +491,7 @@ class AssetGenerator extends Generator { return originalSource.size(); } default: - if (module.buildInfo.dataUrl) { + if (module.buildInfo && module.buildInfo.dataUrl) { const originalSource = module.originalSource(); if (!originalSource) { @@ -212,11 +503,10 @@ class AssetGenerator extends Generator { // 4/3 = base64 encoding // 34 = ~ data url header + footer + rounding return originalSource.size() * 1.34 + 36; - } else { - // it's only estimated so this number is probably fine - // Example: m.exports=r.p+"0123456789012345678901.ext" - return 42; } + // it's only estimated so this number is probably fine + // Example: m.exports=r.p+"0123456789012345678901.ext" + return 42; } } @@ -224,8 +514,72 @@ class AssetGenerator extends Generator { * @param {Hash} hash hash that will be modified * @param {UpdateHashContext} updateHashContext context for updating hash */ - updateHash(hash, { module }) { - hash.update(module.buildInfo.dataUrl ? "data-url" : "resource"); + updateHash(hash, updateHashContext) { + const { module } = updateHashContext; + if ( + /** @type {BuildInfo} */ + (module.buildInfo).dataUrl + ) { + hash.update("data-url"); + // this.dataUrlOptions as function should be pure and only depend on input source and filename + // therefore it doesn't need to be hashed + if (typeof this.dataUrlOptions === "function") { + const ident = /** @type {{ ident?: string }} */ (this.dataUrlOptions) + .ident; + if (ident) hash.update(ident); + } else { + const dataUrlOptions = + /** @type {AssetGeneratorDataUrlOptions} */ + (this.dataUrlOptions); + if ( + dataUrlOptions.encoding && + dataUrlOptions.encoding !== DEFAULT_ENCODING + ) { + hash.update(dataUrlOptions.encoding); + } + if (dataUrlOptions.mimetype) hash.update(dataUrlOptions.mimetype); + // computed mimetype depends only on module filename which is already part of the hash + } + } else { + hash.update("resource"); + + const { module, chunkGraph, runtime } = updateHashContext; + const runtimeTemplate = + /** @type {NonNullable} */ + (updateHashContext.runtimeTemplate); + + const pathData = { + module, + runtime, + filename: this.getSourceFileName(module, runtimeTemplate), + chunkGraph, + contentHash: runtimeTemplate.contentHashReplacement + }; + + if (typeof this.publicPath === "function") { + hash.update("path"); + const assetInfo = {}; + hash.update(this.publicPath(pathData, assetInfo)); + hash.update(JSON.stringify(assetInfo)); + } else if (this.publicPath) { + hash.update("path"); + hash.update(this.publicPath); + } else { + hash.update("no-path"); + } + + const assetModuleFilename = + this.filename || + /** @type {AssetModuleFilename} */ + (runtimeTemplate.outputOptions.assetModuleFilename); + const { path: filename, info } = + runtimeTemplate.compilation.getAssetPathWithInfo( + assetModuleFilename, + pathData + ); + hash.update(filename); + hash.update(JSON.stringify(info)); + } } } diff --git a/lib/asset/AssetModulesPlugin.js b/lib/asset/AssetModulesPlugin.js index d3f6758bd07..490969b2d28 100644 --- a/lib/asset/AssetModulesPlugin.js +++ b/lib/asset/AssetModulesPlugin.js @@ -5,16 +5,29 @@ "use strict"; -const { validate } = require("schema-utils"); +const { + ASSET_MODULE_TYPE_RESOURCE, + ASSET_MODULE_TYPE_INLINE, + ASSET_MODULE_TYPE, + ASSET_MODULE_TYPE_SOURCE +} = require("../ModuleTypeConstants"); const { cleverMerge } = require("../util/cleverMerge"); const { compareModulesByIdentifier } = require("../util/comparators"); +const createSchemaValidation = require("../util/create-schema-validation"); const memoize = require("../util/memoize"); /** @typedef {import("webpack-sources").Source} Source */ +/** @typedef {import("../../declarations/WebpackOptions").AssetParserOptions} AssetParserOptions */ /** @typedef {import("../Chunk")} Chunk */ /** @typedef {import("../Compiler")} Compiler */ /** @typedef {import("../Module")} Module */ +/** @typedef {import("../Module").BuildInfo} BuildInfo */ +/** @typedef {import("../Module").CodeGenerationResult} CodeGenerationResult */ +/** + * @param {string} name name of definitions + * @returns {TODO} definition + */ const getSchema = name => { const { definitions } = require("../../schemas/WebpackOptions.json"); return { @@ -22,13 +35,38 @@ const getSchema = name => { oneOf: [{ $ref: `#/definitions/${name}` }] }; }; -const getGeneratorSchemaMap = { - asset: memoize(() => getSchema("AssetGeneratorOptions")), - "asset/resource": memoize(() => getSchema("AssetResourceGeneratorOptions")), - "asset/inline": memoize(() => getSchema("AssetInlineGeneratorOptions")) + +const generatorValidationOptions = { + name: "Asset Modules Plugin", + baseDataPath: "generator" +}; +const validateGeneratorOptions = { + asset: createSchemaValidation( + require("../../schemas/plugins/asset/AssetGeneratorOptions.check.js"), + () => getSchema("AssetGeneratorOptions"), + generatorValidationOptions + ), + "asset/resource": createSchemaValidation( + require("../../schemas/plugins/asset/AssetResourceGeneratorOptions.check.js"), + () => getSchema("AssetResourceGeneratorOptions"), + generatorValidationOptions + ), + "asset/inline": createSchemaValidation( + require("../../schemas/plugins/asset/AssetInlineGeneratorOptions.check.js"), + () => getSchema("AssetInlineGeneratorOptions"), + generatorValidationOptions + ) }; -const getParserSchema = memoize(() => getSchema("AssetParserOptions")); +const validateParserOptions = createSchemaValidation( + require("../../schemas/plugins/asset/AssetParserOptions.check.js"), + () => getSchema("AssetParserOptions"), + { + name: "Asset Modules Plugin", + baseDataPath: "parser" + } +); + const getAssetGenerator = memoize(() => require("./AssetGenerator")); const getAssetParser = memoize(() => require("./AssetParser")); const getAssetSourceParser = memoize(() => require("./AssetSourceParser")); @@ -36,7 +74,7 @@ const getAssetSourceGenerator = memoize(() => require("./AssetSourceGenerator") ); -const type = "asset"; +const type = ASSET_MODULE_TYPE; const plugin = "AssetModulesPlugin"; class AssetModulesPlugin { @@ -50,14 +88,12 @@ class AssetModulesPlugin { plugin, (compilation, { normalModuleFactory }) => { normalModuleFactory.hooks.createParser - .for("asset") + .for(ASSET_MODULE_TYPE) .tap(plugin, parserOptions => { - validate(getParserSchema(), parserOptions, { - name: "Asset Modules Plugin", - baseDataPath: "parser" - }); + validateParserOptions(parserOptions); parserOptions = cleverMerge( - compiler.options.module.parser.asset, + /** @type {AssetParserOptions} */ + (compiler.options.module.parser.asset), parserOptions ); @@ -74,52 +110,56 @@ class AssetModulesPlugin { return new AssetParser(dataUrlCondition); }); normalModuleFactory.hooks.createParser - .for("asset/inline") - .tap(plugin, parserOptions => { + .for(ASSET_MODULE_TYPE_INLINE) + .tap(plugin, _parserOptions => { const AssetParser = getAssetParser(); return new AssetParser(true); }); normalModuleFactory.hooks.createParser - .for("asset/resource") - .tap(plugin, parserOptions => { + .for(ASSET_MODULE_TYPE_RESOURCE) + .tap(plugin, _parserOptions => { const AssetParser = getAssetParser(); return new AssetParser(false); }); normalModuleFactory.hooks.createParser - .for("asset/source") - .tap(plugin, parserOptions => { + .for(ASSET_MODULE_TYPE_SOURCE) + .tap(plugin, _parserOptions => { const AssetSourceParser = getAssetSourceParser(); return new AssetSourceParser(); }); - for (const type of ["asset", "asset/inline", "asset/resource"]) { + for (const type of [ + ASSET_MODULE_TYPE, + ASSET_MODULE_TYPE_INLINE, + ASSET_MODULE_TYPE_RESOURCE + ]) { normalModuleFactory.hooks.createGenerator .for(type) - // eslint-disable-next-line no-loop-func .tap(plugin, generatorOptions => { - validate(getGeneratorSchemaMap[type](), generatorOptions, { - name: "Asset Modules Plugin", - baseDataPath: "generator" - }); + validateGeneratorOptions[type](generatorOptions); - let dataUrl = undefined; - if (type !== "asset/resource") { + let dataUrl; + if (type !== ASSET_MODULE_TYPE_RESOURCE) { dataUrl = generatorOptions.dataUrl; if (!dataUrl || typeof dataUrl === "object") { dataUrl = { - encoding: "base64", + encoding: undefined, mimetype: undefined, ...dataUrl }; } } - let filename = undefined; - if (type !== "asset/inline") { + let filename; + let publicPath; + let outputPath; + if (type !== ASSET_MODULE_TYPE_INLINE) { filename = generatorOptions.filename; + publicPath = generatorOptions.publicPath; + outputPath = generatorOptions.outputPath; } const AssetGenerator = getAssetGenerator(); @@ -127,12 +167,14 @@ class AssetModulesPlugin { return new AssetGenerator( dataUrl, filename, + publicPath, + outputPath, generatorOptions.emit !== false ); }); } normalModuleFactory.hooks.createGenerator - .for("asset/source") + .for(ASSET_MODULE_TYPE_SOURCE) .tap(plugin, () => { const AssetSourceGenerator = getAssetSourceGenerator(); @@ -145,34 +187,55 @@ class AssetModulesPlugin { const modules = chunkGraph.getOrderedChunkModulesIterableBySourceType( chunk, - "asset", + ASSET_MODULE_TYPE, compareModulesByIdentifier ); if (modules) { for (const module of modules) { - const codeGenResult = codeGenerationResults.get( - module, - chunk.runtime - ); - result.push({ - render: () => codeGenResult.sources.get(type), - filename: - module.buildInfo.filename || - codeGenResult.data.get("filename"), - info: - module.buildInfo.assetInfo || - codeGenResult.data.get("assetInfo"), - auxiliary: true, - identifier: `assetModule${chunkGraph.getModuleId(module)}`, - hash: - module.buildInfo.fullContentHash || - codeGenResult.data.get("fullContentHash") - }); + try { + const codeGenResult = codeGenerationResults.get( + module, + chunk.runtime + ); + const buildInfo = /** @type {BuildInfo} */ (module.buildInfo); + const data = + /** @type {NonNullable} */ + (codeGenResult.data); + result.push({ + render: () => + /** @type {Source} */ (codeGenResult.sources.get(type)), + filename: buildInfo.filename || data.get("filename"), + info: buildInfo.assetInfo || data.get("assetInfo"), + auxiliary: true, + identifier: `assetModule${chunkGraph.getModuleId(module)}`, + hash: buildInfo.fullContentHash || data.get("fullContentHash") + }); + } catch (err) { + /** @type {Error} */ (err).message += + `\nduring rendering of asset ${module.identifier()}`; + throw err; + } } } return result; }); + + compilation.hooks.prepareModuleExecution.tap( + "AssetModulesPlugin", + (options, context) => { + const { codeGenerationResult } = options; + const source = codeGenerationResult.sources.get(ASSET_MODULE_TYPE); + if (source === undefined) return; + const data = + /** @type {NonNullable} */ + (codeGenerationResult.data); + context.assets.set(data.get("filename"), { + source, + info: data.get("assetInfo") + }); + } + ); } ); } diff --git a/lib/asset/AssetParser.js b/lib/asset/AssetParser.js index 7a0a4e307f8..b4f1d534948 100644 --- a/lib/asset/AssetParser.js +++ b/lib/asset/AssetParser.js @@ -7,7 +7,10 @@ const Parser = require("../Parser"); +/** @typedef {import("../../declarations/WebpackOptions").AssetParserDataUrlOptions} AssetParserDataUrlOptions */ /** @typedef {import("../../declarations/WebpackOptions").AssetParserOptions} AssetParserOptions */ +/** @typedef {import("../Module").BuildInfo} BuildInfo */ +/** @typedef {import("../Module").BuildMeta} BuildMeta */ /** @typedef {import("../Parser").ParserState} ParserState */ /** @typedef {import("../Parser").PreparsedAst} PreparsedAst */ @@ -29,22 +32,28 @@ class AssetParser extends Parser { if (typeof source === "object" && !Buffer.isBuffer(source)) { throw new Error("AssetParser doesn't accept preparsed AST"); } - state.module.buildInfo.strict = true; - state.module.buildMeta.exportsType = "default"; + + const buildInfo = /** @type {BuildInfo} */ (state.module.buildInfo); + buildInfo.strict = true; + const buildMeta = /** @type {BuildMeta} */ (state.module.buildMeta); + buildMeta.exportsType = "default"; + buildMeta.defaultObject = false; if (typeof this.dataUrlCondition === "function") { - state.module.buildInfo.dataUrl = this.dataUrlCondition(source, { + buildInfo.dataUrl = this.dataUrlCondition(source, { filename: state.module.matchResource || state.module.resource, module: state.module }); } else if (typeof this.dataUrlCondition === "boolean") { - state.module.buildInfo.dataUrl = this.dataUrlCondition; + buildInfo.dataUrl = this.dataUrlCondition; } else if ( this.dataUrlCondition && typeof this.dataUrlCondition === "object" ) { - state.module.buildInfo.dataUrl = - Buffer.byteLength(source) <= this.dataUrlCondition.maxSize; + buildInfo.dataUrl = + Buffer.byteLength(source) <= + /** @type {NonNullable} */ + (this.dataUrlCondition.maxSize); } else { throw new Error("Unexpected dataUrlCondition type"); } diff --git a/lib/asset/AssetSourceGenerator.js b/lib/asset/AssetSourceGenerator.js index f8720a21b3b..6149a779d74 100644 --- a/lib/asset/AssetSourceGenerator.js +++ b/lib/asset/AssetSourceGenerator.js @@ -6,11 +6,13 @@ "use strict"; const { RawSource } = require("webpack-sources"); +const ConcatenationScope = require("../ConcatenationScope"); const Generator = require("../Generator"); const RuntimeGlobals = require("../RuntimeGlobals"); /** @typedef {import("webpack-sources").Source} Source */ /** @typedef {import("../Generator").GenerateContext} GenerateContext */ +/** @typedef {import("../Module").ConcatenationBailoutReasonContext} ConcatenationBailoutReasonContext */ /** @typedef {import("../NormalModule")} NormalModule */ const TYPES = new Set(["javascript"]); @@ -21,9 +23,10 @@ class AssetSourceGenerator extends Generator { * @param {GenerateContext} generateContext context for generate * @returns {Source} generated code */ - generate(module, { chunkGraph, runtimeTemplate, runtimeRequirements }) { - runtimeRequirements.add(RuntimeGlobals.module); - + generate( + module, + { concatenationScope, chunkGraph, runtimeTemplate, runtimeRequirements } + ) { const originalSource = module.originalSource(); if (!originalSource) { @@ -31,16 +34,33 @@ class AssetSourceGenerator extends Generator { } const content = originalSource.source(); + const encodedSource = + typeof content === "string" ? content : content.toString("utf-8"); - let encodedSource; - if (typeof content === "string") { - encodedSource = content; + let sourceContent; + if (concatenationScope) { + concatenationScope.registerNamespaceExport( + ConcatenationScope.NAMESPACE_OBJECT_EXPORT + ); + sourceContent = `${runtimeTemplate.supportsConst() ? "const" : "var"} ${ + ConcatenationScope.NAMESPACE_OBJECT_EXPORT + } = ${JSON.stringify(encodedSource)};`; } else { - encodedSource = content.toString("utf-8"); + runtimeRequirements.add(RuntimeGlobals.module); + sourceContent = `${RuntimeGlobals.module}.exports = ${JSON.stringify( + encodedSource + )};`; } - return new RawSource( - `${RuntimeGlobals.module}.exports = ${JSON.stringify(encodedSource)};` - ); + return new RawSource(sourceContent); + } + + /** + * @param {NormalModule} module module for which the bailout reason should be determined + * @param {ConcatenationBailoutReasonContext} context context + * @returns {string | undefined} reason why this module can't be concatenated, undefined when it can be concatenated + */ + getConcatenationBailoutReason(module, context) { + return undefined; } /** diff --git a/lib/asset/AssetSourceParser.js b/lib/asset/AssetSourceParser.js index 505c363e7fc..c122f0ea4e4 100644 --- a/lib/asset/AssetSourceParser.js +++ b/lib/asset/AssetSourceParser.js @@ -7,6 +7,8 @@ const Parser = require("../Parser"); +/** @typedef {import("../Module").BuildInfo} BuildInfo */ +/** @typedef {import("../Module").BuildMeta} BuildMeta */ /** @typedef {import("../Parser").ParserState} ParserState */ /** @typedef {import("../Parser").PreparsedAst} PreparsedAst */ @@ -21,8 +23,12 @@ class AssetSourceParser extends Parser { throw new Error("AssetSourceParser doesn't accept preparsed AST"); } const { module } = state; - module.buildInfo.strict = true; - module.buildMeta.exportsType = "default"; + /** @type {BuildInfo} */ + (module.buildInfo).strict = true; + /** @type {BuildMeta} */ + (module.buildMeta).exportsType = "default"; + /** @type {BuildMeta} */ + (state.module.buildMeta).defaultObject = false; return state; } diff --git a/lib/asset/RawDataUrlModule.js b/lib/asset/RawDataUrlModule.js new file mode 100644 index 00000000000..3098b9c200e --- /dev/null +++ b/lib/asset/RawDataUrlModule.js @@ -0,0 +1,162 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ + +"use strict"; + +const { RawSource } = require("webpack-sources"); +const Module = require("../Module"); +const { ASSET_MODULE_TYPE_RAW_DATA_URL } = require("../ModuleTypeConstants"); +const RuntimeGlobals = require("../RuntimeGlobals"); +const makeSerializable = require("../util/makeSerializable"); + +/** @typedef {import("../../declarations/WebpackOptions").WebpackOptionsNormalized} WebpackOptions */ +/** @typedef {import("../Compilation")} Compilation */ +/** @typedef {import("../Dependency").UpdateHashContext} UpdateHashContext */ +/** @typedef {import("../Module").CodeGenerationContext} CodeGenerationContext */ +/** @typedef {import("../Module").CodeGenerationResult} CodeGenerationResult */ +/** @typedef {import("../Module").NeedBuildContext} NeedBuildContext */ +/** @typedef {import("../Module").SourceTypes} SourceTypes */ +/** @typedef {import("../RequestShortener")} RequestShortener */ +/** @typedef {import("../ResolverFactory").ResolverWithOptions} ResolverWithOptions */ +/** @typedef {import("../WebpackError")} WebpackError */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */ +/** @typedef {import("../util/Hash")} Hash */ +/** @typedef {import("../util/fs").InputFileSystem} InputFileSystem */ + +const TYPES = new Set(["javascript"]); + +class RawDataUrlModule extends Module { + /** + * @param {string} url raw url + * @param {string} identifier unique identifier + * @param {string=} readableIdentifier readable identifier + */ + constructor(url, identifier, readableIdentifier) { + super(ASSET_MODULE_TYPE_RAW_DATA_URL, null); + this.url = url; + this.urlBuffer = url ? Buffer.from(url) : undefined; + this.identifierStr = identifier || this.url; + this.readableIdentifierStr = readableIdentifier || this.identifierStr; + } + + /** + * @returns {SourceTypes} types available (do not mutate) + */ + getSourceTypes() { + return TYPES; + } + + /** + * @returns {string} a unique identifier of the module + */ + identifier() { + return this.identifierStr; + } + + /** + * @param {string=} type the source type for which the size should be estimated + * @returns {number} the estimated size of the module (must be non-zero) + */ + size(type) { + if (this.url === undefined) + this.url = /** @type {Buffer} */ (this.urlBuffer).toString(); + return Math.max(1, this.url.length); + } + + /** + * @param {RequestShortener} requestShortener the request shortener + * @returns {string} a user readable identifier of the module + */ + readableIdentifier(requestShortener) { + return /** @type {string} */ ( + requestShortener.shorten(this.readableIdentifierStr) + ); + } + + /** + * @param {NeedBuildContext} context context info + * @param {function((WebpackError | null)=, boolean=): void} callback callback function, returns true, if the module needs a rebuild + * @returns {void} + */ + needBuild(context, callback) { + return callback(null, !this.buildMeta); + } + + /** + * @param {WebpackOptions} options webpack options + * @param {Compilation} compilation the compilation + * @param {ResolverWithOptions} resolver the resolver + * @param {InputFileSystem} fs the file system + * @param {function(WebpackError=): void} callback callback function + * @returns {void} + */ + build(options, compilation, resolver, fs, callback) { + this.buildMeta = {}; + this.buildInfo = { + cacheable: true + }; + callback(); + } + + /** + * @param {CodeGenerationContext} context context for code generation + * @returns {CodeGenerationResult} result + */ + codeGeneration(context) { + if (this.url === undefined) + this.url = /** @type {Buffer} */ (this.urlBuffer).toString(); + const sources = new Map(); + sources.set( + "javascript", + new RawSource(`module.exports = ${JSON.stringify(this.url)};`) + ); + const data = new Map(); + data.set("url", this.urlBuffer); + const runtimeRequirements = new Set(); + runtimeRequirements.add(RuntimeGlobals.module); + return { sources, runtimeRequirements, data }; + } + + /** + * @param {Hash} hash the hash used to track dependencies + * @param {UpdateHashContext} context context + * @returns {void} + */ + updateHash(hash, context) { + hash.update(/** @type {Buffer} */ (this.urlBuffer)); + super.updateHash(hash, context); + } + + /** + * @param {ObjectSerializerContext} context context + */ + serialize(context) { + const { write } = context; + + write(this.urlBuffer); + write(this.identifierStr); + write(this.readableIdentifierStr); + + super.serialize(context); + } + + /** + * @param {ObjectDeserializerContext} context context + */ + deserialize(context) { + const { read } = context; + + this.urlBuffer = read(); + this.identifierStr = read(); + this.readableIdentifierStr = read(); + + super.deserialize(context); + } +} + +makeSerializable(RawDataUrlModule, "webpack/lib/asset/RawDataUrlModule"); + +module.exports = RawDataUrlModule; diff --git a/lib/async-modules/AwaitDependenciesInitFragment.js b/lib/async-modules/AwaitDependenciesInitFragment.js index 239c4ee63ed..84abf28107d 100644 --- a/lib/async-modules/AwaitDependenciesInitFragment.js +++ b/lib/async-modules/AwaitDependenciesInitFragment.js @@ -12,6 +12,9 @@ const Template = require("../Template"); /** @typedef {import("webpack-sources").Source} Source */ /** @typedef {import("../Generator").GenerateContext} GenerateContext */ +/** + * @extends {InitFragment} + */ class AwaitDependenciesInitFragment extends InitFragment { /** * @param {Set} promises the promises that should be awaited @@ -26,17 +29,21 @@ class AwaitDependenciesInitFragment extends InitFragment { this.promises = promises; } + /** + * @param {AwaitDependenciesInitFragment} other other AwaitDependenciesInitFragment + * @returns {AwaitDependenciesInitFragment} AwaitDependenciesInitFragment + */ merge(other) { - const promises = new Set(this.promises); - for (const p of other.promises) { + const promises = new Set(other.promises); + for (const p of this.promises) { promises.add(p); } return new AwaitDependenciesInitFragment(promises); } /** - * @param {GenerateContext} generateContext context for generate - * @returns {string|Source} the source code that will be included as initialization code + * @param {GenerateContext} context context + * @returns {string | Source | undefined} the source code that will be included as initialization code */ getContent({ runtimeRequirements }) { runtimeRequirements.add(RuntimeGlobals.module); @@ -45,19 +52,18 @@ class AwaitDependenciesInitFragment extends InitFragment { return ""; } if (promises.size === 1) { - for (const p of promises) { - return Template.asString([ - `var __webpack_async_dependencies__ = __webpack_handle_async_dependencies__([${p}]);`, - `${p} = (__webpack_async_dependencies__.then ? await __webpack_async_dependencies__ : __webpack_async_dependencies__)[0];`, - "" - ]); - } + const [p] = promises; + return Template.asString([ + `var __webpack_async_dependencies__ = __webpack_handle_async_dependencies__([${p}]);`, + `${p} = (__webpack_async_dependencies__.then ? (await __webpack_async_dependencies__)() : __webpack_async_dependencies__)[0];`, + "" + ]); } const sepPromises = Array.from(promises).join(", "); // TODO check if destructuring is supported return Template.asString([ `var __webpack_async_dependencies__ = __webpack_handle_async_dependencies__([${sepPromises}]);`, - `([${sepPromises}] = __webpack_async_dependencies__.then ? await __webpack_async_dependencies__ : __webpack_async_dependencies__);`, + `([${sepPromises}] = __webpack_async_dependencies__.then ? (await __webpack_async_dependencies__)() : __webpack_async_dependencies__);`, "" ]); } diff --git a/lib/async-modules/InferAsyncModulesPlugin.js b/lib/async-modules/InferAsyncModulesPlugin.js index 9e64972e483..d395e30c474 100644 --- a/lib/async-modules/InferAsyncModulesPlugin.js +++ b/lib/async-modules/InferAsyncModulesPlugin.js @@ -42,7 +42,7 @@ class InferAsyncModulesPlugin { c.isTargetActive(undefined) ) ) { - queue.add(originModule); + queue.add(/** @type {Module} */ (originModule)); } } } diff --git a/lib/buildChunkGraph.js b/lib/buildChunkGraph.js index 768605010d2..8b4916bdbab 100644 --- a/lib/buildChunkGraph.js +++ b/lib/buildChunkGraph.js @@ -16,6 +16,7 @@ const { getEntryRuntime, mergeRuntime } = require("./util/runtime"); /** @typedef {import("./Compilation")} Compilation */ /** @typedef {import("./DependenciesBlock")} DependenciesBlock */ /** @typedef {import("./Dependency")} Dependency */ +/** @typedef {import("./Dependency").DependencyLocation} DependencyLocation */ /** @typedef {import("./Entrypoint")} Entrypoint */ /** @typedef {import("./Module")} Module */ /** @typedef {import("./ModuleGraph")} ModuleGraph */ @@ -24,7 +25,7 @@ const { getEntryRuntime, mergeRuntime } = require("./util/runtime"); /** @typedef {import("./util/runtime").RuntimeSpec} RuntimeSpec */ /** - * @typedef {Object} QueueItem + * @typedef {object} QueueItem * @property {number} action * @property {DependenciesBlock} block * @property {Module} module @@ -33,45 +34,52 @@ const { getEntryRuntime, mergeRuntime } = require("./util/runtime"); * @property {ChunkGroupInfo} chunkGroupInfo */ -/** @typedef {Set & { plus: Set }} ModuleSetPlus */ - /** - * @typedef {Object} ChunkGroupInfo + * @typedef {object} ChunkGroupInfo * @property {ChunkGroup} chunkGroup the chunk group * @property {RuntimeSpec} runtime the runtimes - * @property {ModuleSetPlus} minAvailableModules current minimal set of modules available at this point - * @property {boolean} minAvailableModulesOwned true, if minAvailableModules is owned and can be modified - * @property {ModuleSetPlus[]} availableModulesToBeMerged enqueued updates to the minimal set of available modules + * @property {bigint | undefined} minAvailableModules current minimal set of modules available at this point + * @property {bigint[]} availableModulesToBeMerged enqueued updates to the minimal set of available modules * @property {Set=} skippedItems modules that were skipped because module is already available in parent chunks (need to reconsider when minAvailableModules is shrinking) * @property {Set<[Module, ModuleGraphConnection[]]>=} skippedModuleConnections referenced modules that where skipped because they were not active in this runtime - * @property {ModuleSetPlus} resultingAvailableModules set of modules available including modules from this chunk group - * @property {Set} children set of children chunk groups, that will be revisited when availableModules shrink - * @property {Set} availableSources set of chunk groups that are the source for minAvailableModules - * @property {Set} availableChildren set of chunk groups which depend on the this chunk group as availableSource + * @property {bigint | undefined} resultingAvailableModules set of modules available including modules from this chunk group + * @property {Set | undefined} children set of children chunk groups, that will be revisited when availableModules shrink + * @property {Set | undefined} availableSources set of chunk groups that are the source for minAvailableModules + * @property {Set | undefined} availableChildren set of chunk groups which depend on the this chunk group as availableSource * @property {number} preOrderIndex next pre order index * @property {number} postOrderIndex next post order index + * @property {boolean} chunkLoading has a chunk loading mechanism + * @property {boolean} asyncChunks create async chunks */ /** - * @typedef {Object} BlockChunkGroupConnection + * @typedef {object} BlockChunkGroupConnection * @property {ChunkGroupInfo} originChunkGroupInfo origin chunk group * @property {ChunkGroup} chunkGroup referenced chunk group */ -const EMPTY_SET = /** @type {ModuleSetPlus} */ (new Set()); -EMPTY_SET.plus = EMPTY_SET; +/** @typedef {(Module | ConnectionState | ModuleGraphConnection)[]} BlockModulesInTuples */ +/** @typedef {(Module | ConnectionState | ModuleGraphConnection[])[]} BlockModulesInFlattenTuples */ +/** @typedef {Map} BlockModulesMap */ +/** @typedef {Map} MaskByChunk */ +/** @typedef {Set} BlocksWithNestedBlocks */ +/** @typedef {Map} BlockConnections */ +/** @typedef {Map} ChunkGroupInfoMap */ +/** @typedef {Set} AllCreatedChunkGroups */ +/** @typedef {Map} InputEntrypointsAndModules */ + +const ZERO_BIGINT = BigInt(0); +const ONE_BIGINT = BigInt(1); /** - * @param {ModuleSetPlus} a first set - * @param {ModuleSetPlus} b second set - * @returns {number} cmp + * @param {bigint} mask The mask to test + * @param {number} ordinal The ordinal of the bit to test + * @returns {boolean} If the ordinal-th bit is set in the mask */ -const bySetSize = (a, b) => { - return b.size + b.plus.size - a.size - a.plus.size; -}; +const isOrdinalSetInMask = (mask, ordinal) => + BigInt.asUintN(1, mask >> BigInt(ordinal)) !== ZERO_BIGINT; /** - * * @param {ModuleGraphConnection[]} connections list of connections * @param {RuntimeSpec} runtime for which runtime * @returns {ConnectionState} connection state @@ -91,87 +99,149 @@ const getActiveStateOfConnections = (connections, runtime) => { }; /** - * Extracts block to modules mapping from all modules - * @param {Compilation} compilation the compilation - * @returns {Map>} the mapping block to modules + * @param {Module} module module + * @param {ModuleGraph} moduleGraph module graph + * @param {RuntimeSpec} runtime runtime + * @param {BlockModulesMap} blockModulesMap block modules map */ -const extractBlockModulesMap = compilation => { - const { moduleGraph } = compilation; - - /** @type {Map>} */ - const blockModulesMap = new Map(); - - const blockQueue = new Set(); - - for (const module of compilation.modules) { - /** @type {WeakMap} */ - let moduleMap; - - for (const connection of moduleGraph.getOutgoingConnections(module)) { - const d = connection.dependency; - // We skip connections without dependency - if (!d) continue; - const m = connection.module; - // We skip connections without Module pointer - if (!m) continue; - // We skip weak connections - if (connection.weak) continue; - const state = connection.getActiveState(undefined); - // We skip inactive connections - if (state === false) continue; - // Store Dependency to Module mapping in local map - // to allow to access it faster compared to - // moduleGraph.getConnection() - if (moduleMap === undefined) { - moduleMap = new WeakMap(); - } - moduleMap.set(connection.dependency, connection); +const extractBlockModules = (module, moduleGraph, runtime, blockModulesMap) => { + /** @type {DependenciesBlock | undefined} */ + let blockCache; + /** @type {BlockModulesInTuples | undefined} */ + let modules; + + /** @type {BlockModulesInTuples[]} */ + const arrays = []; + + /** @type {DependenciesBlock[]} */ + const queue = [module]; + while (queue.length > 0) { + const block = /** @type {DependenciesBlock} */ (queue.pop()); + /** @type {Module[]} */ + const arr = []; + arrays.push(arr); + blockModulesMap.set(block, arr); + for (const b of block.blocks) { + queue.push(b); } + } - blockQueue.clear(); - blockQueue.add(module); - for (const block of blockQueue) { - let modules; - - if (moduleMap !== undefined && block.dependencies) { - for (const dep of block.dependencies) { - const connection = moduleMap.get(dep); - if (connection !== undefined) { - const { module } = connection; - if (modules === undefined) { - modules = new Map(); - blockModulesMap.set(block, modules); - } - const old = modules.get(module); - if (old !== undefined) { - old.push(connection); - } else { - modules.set(module, [connection]); - } + for (const connection of moduleGraph.getOutgoingConnections(module)) { + const d = connection.dependency; + // We skip connections without dependency + if (!d) continue; + const m = connection.module; + // We skip connections without Module pointer + if (!m) continue; + // We skip weak connections + if (connection.weak) continue; + + const block = moduleGraph.getParentBlock(d); + let index = moduleGraph.getParentBlockIndex(d); + + // deprecated fallback + if (index < 0) { + index = /** @type {DependenciesBlock} */ (block).dependencies.indexOf(d); + } + + if (blockCache !== block) { + modules = + /** @type {BlockModulesInTuples} */ + ( + blockModulesMap.get( + (blockCache = /** @type {DependenciesBlock} */ (block)) + ) + ); + } + + const i = index * 3; + /** @type {BlockModulesInTuples} */ + (modules)[i] = m; + /** @type {BlockModulesInTuples} */ + (modules)[i + 1] = connection.getActiveState(runtime); + /** @type {BlockModulesInTuples} */ + (modules)[i + 2] = connection; + } + + for (const modules of arrays) { + if (modules.length === 0) continue; + let indexMap; + let length = 0; + outer: for (let j = 0; j < modules.length; j += 3) { + const m = modules[j]; + if (m === undefined) continue; + const state = /** @type {ConnectionState} */ (modules[j + 1]); + const connection = /** @type {ModuleGraphConnection} */ (modules[j + 2]); + if (indexMap === undefined) { + let i = 0; + for (; i < length; i += 3) { + if (modules[i] === m) { + const merged = /** @type {ConnectionState} */ (modules[i + 1]); + /** @type {ModuleGraphConnection[]} */ + (/** @type {unknown} */ (modules[i + 2])).push(connection); + if (merged === true) continue outer; + modules[i + 1] = ModuleGraphConnection.addConnectionStates( + merged, + state + ); + continue outer; } } - } - - if (block.blocks) { - for (const b of block.blocks) { - blockQueue.add(b); + modules[length] = m; + length++; + modules[length] = state; + length++; + /** @type {ModuleGraphConnection[]} */ + (/** @type {unknown} */ (modules[length])) = [connection]; + length++; + if (length > 30) { + // To avoid worse case performance, we will use an index map for + // linear cost access, which allows to maintain O(n) complexity + // while keeping allocations down to a minimum + indexMap = new Map(); + for (let i = 0; i < length; i += 3) { + indexMap.set(modules[i], i + 1); + } + } + } else { + const idx = indexMap.get(m); + if (idx !== undefined) { + const merged = /** @type {ConnectionState} */ (modules[idx]); + /** @type {ModuleGraphConnection[]} */ + (/** @type {unknown} */ (modules[idx + 1])).push(connection); + if (merged === true) continue; + modules[idx] = ModuleGraphConnection.addConnectionStates( + merged, + state + ); + } else { + modules[length] = m; + length++; + modules[length] = state; + indexMap.set(m, length); + length++; + /** @type {ModuleGraphConnection[]} */ + ( + /** @type {unknown} */ + (modules[length]) + ) = [connection]; + length++; } } } + modules.length = length; } - - return blockModulesMap; }; /** - * * @param {Logger} logger a logger * @param {Compilation} compilation the compilation - * @param {Map} inputEntrypointsAndModules chunk groups which are processed with the modules - * @param {Map} chunkGroupInfoMap mapping from chunk group to available modules - * @param {Map} blockConnections connection for blocks - * @param {Set} blocksWithNestedBlocks flag for blocks that have nested blocks - * @param {Set} allCreatedChunkGroups filled with all chunk groups that are created here + * @param {InputEntrypointsAndModules} inputEntrypointsAndModules chunk groups which are processed with the modules + * @param {ChunkGroupInfoMap} chunkGroupInfoMap mapping from chunk group to available modules + * @param {BlockConnections} blockConnections connection for blocks + * @param {BlocksWithNestedBlocks} blocksWithNestedBlocks flag for blocks that have nested blocks + * @param {AllCreatedChunkGroups} allCreatedChunkGroups filled with all chunk groups that are created here + * @param {MaskByChunk} maskByChunk module content mask by chunk */ const visitModules = ( logger, @@ -180,24 +250,91 @@ const visitModules = ( chunkGroupInfoMap, blockConnections, blocksWithNestedBlocks, - allCreatedChunkGroups + allCreatedChunkGroups, + maskByChunk ) => { - const { moduleGraph, chunkGraph } = compilation; + const { moduleGraph, chunkGraph, moduleMemCaches } = compilation; + + const blockModulesRuntimeMap = new Map(); - logger.time("visitModules: prepare"); - const blockModulesMap = extractBlockModulesMap(compilation); + /** @type {BlockModulesMap | undefined} */ + let blockModulesMap; + + /** @type {Map} */ + const ordinalByModule = new Map(); + + /** + * @param {Module} module The module to look up + * @returns {number} The ordinal of the module in masks + */ + const getModuleOrdinal = module => { + let ordinal = ordinalByModule.get(module); + if (ordinal === undefined) { + ordinal = ordinalByModule.size; + ordinalByModule.set(module, ordinal); + } + return ordinal; + }; + + for (const chunk of compilation.chunks) { + let mask = ZERO_BIGINT; + for (const m of chunkGraph.getChunkModulesIterable(chunk)) { + mask |= ONE_BIGINT << BigInt(getModuleOrdinal(m)); + } + maskByChunk.set(chunk, mask); + } + + /** + * @param {DependenciesBlock} block block + * @param {RuntimeSpec} runtime runtime + * @returns {BlockModulesInFlattenTuples} block modules in flatten tuples + */ + const getBlockModules = (block, runtime) => { + blockModulesMap = blockModulesRuntimeMap.get(runtime); + if (blockModulesMap === undefined) { + blockModulesMap = new Map(); + blockModulesRuntimeMap.set(runtime, blockModulesMap); + } + let blockModules = blockModulesMap.get(block); + if (blockModules !== undefined) return blockModules; + const module = /** @type {Module} */ (block.getRootBlock()); + const memCache = moduleMemCaches && moduleMemCaches.get(module); + if (memCache !== undefined) { + const map = memCache.provide( + "bundleChunkGraph.blockModules", + runtime, + () => { + logger.time("visitModules: prepare"); + const map = new Map(); + extractBlockModules(module, moduleGraph, runtime, map); + logger.timeAggregate("visitModules: prepare"); + return map; + } + ); + for (const [block, blockModules] of map) + blockModulesMap.set(block, blockModules); + return map.get(block); + } + logger.time("visitModules: prepare"); + extractBlockModules(module, moduleGraph, runtime, blockModulesMap); + blockModules = + /** @type {BlockModulesInFlattenTuples} */ + (blockModulesMap.get(block)); + logger.timeAggregate("visitModules: prepare"); + return blockModules; + }; let statProcessedQueueItems = 0; let statProcessedBlocks = 0; let statConnectedChunkGroups = 0; let statProcessedChunkGroupsForMerging = 0; let statMergedAvailableModuleSets = 0; - let statForkedAvailableModules = 0; - let statForkedAvailableModulesCount = 0; - let statForkedAvailableModulesCountPlus = 0; - let statForkedMergedModulesCount = 0; - let statForkedMergedModulesCountPlus = 0; - let statForkedResultModulesCount = 0; + const statForkedAvailableModules = 0; + const statForkedAvailableModulesCount = 0; + const statForkedAvailableModulesCountPlus = 0; + const statForkedMergedModulesCount = 0; + const statForkedMergedModulesCountPlus = 0; + const statForkedResultModulesCount = 0; let statChunkGroupInfoUpdated = 0; let statChildChunkGroupsReconnected = 0; @@ -208,12 +345,18 @@ const visitModules = ( /** @type {Map} */ const blockChunkGroups = new Map(); + /** @type {Map} */ + const blockByChunkGroups = new Map(); + /** @type {Map} */ const namedChunkGroups = new Map(); /** @type {Map} */ const namedAsyncEntrypoints = new Map(); + /** @type {Set} */ + const outdatedOrderIndexChunkGroups = new Set(); + const ADD_AND_ENTER_ENTRY_MODULE = 0; const ADD_AND_ENTER_MODULE = 1; const ENTER_MODULE = 2; @@ -234,7 +377,7 @@ const visitModules = ( for (const [chunkGroup, modules] of inputEntrypointsAndModules) { const runtime = getEntryRuntime( compilation, - chunkGroup.name, + /** @type {string} */ (chunkGroup.name), chunkGroup.options ); /** @type {ChunkGroupInfo} */ @@ -242,7 +385,6 @@ const visitModules = ( chunkGroup, runtime, minAvailableModules: undefined, - minAvailableModulesOwned: false, availableModulesToBeMerged: [], skippedItems: undefined, resultingAvailableModules: undefined, @@ -250,22 +392,27 @@ const visitModules = ( availableSources: undefined, availableChildren: undefined, preOrderIndex: 0, - postOrderIndex: 0 + postOrderIndex: 0, + chunkLoading: + chunkGroup.options.chunkLoading !== undefined + ? chunkGroup.options.chunkLoading !== false + : compilation.outputOptions.chunkLoading !== false, + asyncChunks: + chunkGroup.options.asyncChunks !== undefined + ? chunkGroup.options.asyncChunks + : compilation.outputOptions.asyncChunks !== false }; chunkGroup.index = nextChunkGroupIndex++; if (chunkGroup.getNumberOfParents() > 0) { // minAvailableModules for child entrypoints are unknown yet, set to undefined. // This means no module is added until other sets are merged into // this minAvailableModules (by the parent entrypoints) - const skippedItems = new Set(); - for (const module of modules) { - skippedItems.add(module); - } + const skippedItems = new Set(modules); chunkGroupInfo.skippedItems = skippedItems; chunkGroupsForCombining.add(chunkGroupInfo); } else { // The application may start here: We start with an empty list of available modules - chunkGroupInfo.minAvailableModules = EMPTY_SET; + chunkGroupInfo.minAvailableModules = ZERO_BIGINT; const chunk = chunkGroup.getEntrypointChunk(); for (const module of modules) { queue.push({ @@ -288,7 +435,9 @@ const visitModules = ( const { chunkGroup } = chunkGroupInfo; chunkGroupInfo.availableSources = new Set(); for (const parent of chunkGroup.parentsIterable) { - const parentChunkGroupInfo = chunkGroupInfoMap.get(parent); + const parentChunkGroupInfo = + /** @type {ChunkGroupInfo} */ + (chunkGroupInfoMap.get(parent)); chunkGroupInfo.availableSources.add(parentChunkGroupInfo); if (parentChunkGroupInfo.availableChildren === undefined) { parentChunkGroupInfo.availableChildren = new Set(); @@ -308,8 +457,6 @@ const visitModules = ( /** @type {QueueItem[]} */ let queueDelayed = []; - logger.timeEnd("visitModules: prepare"); - /** @type {[Module, ModuleGraphConnection[]][]} */ const skipConnectionBuffer = []; /** @type {Module[]} */ @@ -336,29 +483,30 @@ const visitModules = ( const iteratorBlock = b => { // 1. We create a chunk group with single chunk in it for this Block // but only once (blockChunkGroups map) + /** @type {ChunkGroupInfo | undefined} */ let cgi = blockChunkGroups.get(b); - /** @type {ChunkGroup} */ + /** @type {ChunkGroup | undefined} */ let c; - /** @type {Entrypoint} */ + /** @type {Entrypoint | undefined} */ let entrypoint; const entryOptions = b.groupOptions && b.groupOptions.entryOptions; if (cgi === undefined) { const chunkName = (b.groupOptions && b.groupOptions.name) || b.chunkName; if (entryOptions) { - cgi = namedAsyncEntrypoints.get(chunkName); + cgi = namedAsyncEntrypoints.get(/** @type {string} */ (chunkName)); if (!cgi) { entrypoint = compilation.addAsyncEntrypoint( entryOptions, module, - b.loc, - b.request + /** @type {DependencyLocation} */ (b.loc), + /** @type {string} */ (b.request) ); + maskByChunk.set(entrypoint.chunks[0], ZERO_BIGINT); entrypoint.index = nextChunkGroupIndex++; cgi = { chunkGroup: entrypoint, runtime: entrypoint.options.runtime || entrypoint.name, - minAvailableModules: EMPTY_SET, - minAvailableModulesOwned: false, + minAvailableModules: ZERO_BIGINT, availableModulesToBeMerged: [], skippedItems: undefined, resultingAvailableModules: undefined, @@ -366,7 +514,15 @@ const visitModules = ( availableSources: undefined, availableChildren: undefined, preOrderIndex: 0, - postOrderIndex: 0 + postOrderIndex: 0, + chunkLoading: + entryOptions.chunkLoading !== undefined + ? entryOptions.chunkLoading !== false + : chunkGroupInfo.chunkLoading, + asyncChunks: + entryOptions.asyncChunks !== undefined + ? entryOptions.asyncChunks + : chunkGroupInfo.asyncChunks }; chunkGroupInfoMap.set(entrypoint, cgi); @@ -377,7 +533,11 @@ const visitModules = ( } else { entrypoint = /** @type {Entrypoint} */ (cgi.chunkGroup); // TODO merge entryOptions - entrypoint.addOrigin(module, b.loc, b.request); + entrypoint.addOrigin( + module, + /** @type {DependencyLocation} */ (b.loc), + /** @type {string} */ (b.request) + ); chunkGraph.connectBlockAndChunkGroup(b, entrypoint); } @@ -385,26 +545,36 @@ const visitModules = ( queueDelayed.push({ action: PROCESS_ENTRY_BLOCK, block: b, - module: module, + module, chunk: entrypoint.chunks[0], chunkGroup: entrypoint, chunkGroupInfo: cgi }); + } else if (!chunkGroupInfo.asyncChunks || !chunkGroupInfo.chunkLoading) { + // Just queue the block into the current chunk group + queue.push({ + action: PROCESS_BLOCK, + block: b, + module, + chunk, + chunkGroup, + chunkGroupInfo + }); } else { - cgi = namedChunkGroups.get(chunkName); + cgi = chunkName ? namedChunkGroups.get(chunkName) : undefined; if (!cgi) { c = compilation.addChunkInGroup( b.groupOptions || b.chunkName, module, - b.loc, - b.request + /** @type {DependencyLocation} */ (b.loc), + /** @type {string} */ (b.request) ); + maskByChunk.set(c.chunks[0], ZERO_BIGINT); c.index = nextChunkGroupIndex++; cgi = { chunkGroup: c, runtime: chunkGroupInfo.runtime, minAvailableModules: undefined, - minAvailableModulesOwned: undefined, availableModulesToBeMerged: [], skippedItems: undefined, resultingAvailableModules: undefined, @@ -412,7 +582,9 @@ const visitModules = ( availableSources: undefined, availableChildren: undefined, preOrderIndex: 0, - postOrderIndex: 0 + postOrderIndex: 0, + chunkLoading: chunkGroupInfo.chunkLoading, + asyncChunks: chunkGroupInfo.asyncChunks }; allCreatedChunkGroups.add(c); chunkGroupInfoMap.set(c, cgi); @@ -423,16 +595,26 @@ const visitModules = ( c = cgi.chunkGroup; if (c.isInitial()) { compilation.errors.push( - new AsyncDependencyToInitialChunkError(chunkName, module, b.loc) + new AsyncDependencyToInitialChunkError( + /** @type {string} */ (chunkName), + module, + /** @type {DependencyLocation} */ (b.loc) + ) ); c = chunkGroup; + } else { + c.addOptions(b.groupOptions); } - c.addOptions(b.groupOptions); - c.addOrigin(module, b.loc, b.request); + c.addOrigin( + module, + /** @type {DependencyLocation} */ (b.loc), + /** @type {string} */ (b.request) + ); } blockConnections.set(b, []); } - blockChunkGroups.set(b, cgi); + blockChunkGroups.set(b, /** @type {ChunkGroupInfo} */ (cgi)); + blockByChunkGroups.set(/** @type {ChunkGroupInfo} */ (cgi), b); } else if (entryOptions) { entrypoint = /** @type {Entrypoint} */ (cgi.chunkGroup); } else { @@ -442,7 +624,8 @@ const visitModules = ( if (c !== undefined) { // 2. We store the connection for the block // to connect it later if needed - blockConnections.get(b).push({ + /** @type {BlockChunkGroupConnection[]} */ + (blockConnections.get(b)).push({ originChunkGroupInfo: chunkGroupInfo, chunkGroup: c }); @@ -453,7 +636,7 @@ const visitModules = ( connectList = new Set(); queueConnect.set(chunkGroupInfo, connectList); } - connectList.add(cgi); + connectList.add(/** @type {ChunkGroupInfo} */ (cgi)); // TODO check if this really need to be done for each traversal // or if it is enough when it's queued when created @@ -461,12 +644,12 @@ const visitModules = ( queueDelayed.push({ action: PROCESS_BLOCK, block: b, - module: module, + module, chunk: c.chunks[0], chunkGroup: c, - chunkGroupInfo: cgi + chunkGroupInfo: /** @type {ChunkGroupInfo} */ (cgi) }); - } else { + } else if (entrypoint !== undefined) { chunkGroupInfo.chunkGroup.addAsyncEntrypoint(entrypoint); } }; @@ -478,28 +661,36 @@ const visitModules = ( const processBlock = block => { statProcessedBlocks++; // get prepared block info - const blockModules = blockModulesMap.get(block); + const blockModules = getBlockModules(block, chunkGroupInfo.runtime); if (blockModules !== undefined) { - const { minAvailableModules, runtime } = chunkGroupInfo; + const minAvailableModules = + /** @type {bigint} */ + (chunkGroupInfo.minAvailableModules); // Buffer items because order need to be reversed to get indices correct // Traverse all referenced modules - for (const entry of blockModules) { - const [refModule, connections] = entry; - if (chunkGraph.isModuleInChunk(refModule, chunk)) { + for (let i = 0, len = blockModules.length; i < len; i += 3) { + const refModule = /** @type {Module} */ (blockModules[i]); + // For single comparisons this might be cheaper + const isModuleInChunk = chunkGraph.isModuleInChunk(refModule, chunk); + + if (isModuleInChunk) { // skip early if already connected continue; } - const activeState = getActiveStateOfConnections(connections, runtime); + + const refOrdinal = /** @type {number} */ getModuleOrdinal(refModule); + const activeState = /** @type {ConnectionState} */ ( + blockModules[i + 1] + ); if (activeState !== true) { - skipConnectionBuffer.push(entry); + const connections = /** @type {ModuleGraphConnection[]} */ ( + blockModules[i + 2] + ); + skipConnectionBuffer.push([refModule, connections]); + // We skip inactive connections if (activeState === false) continue; - } - if ( - activeState === true && - (minAvailableModules.has(refModule) || - minAvailableModules.plus.has(refModule)) - ) { + } else if (isOrdinalSetInMask(minAvailableModules, refOrdinal)) { // already in parent chunks, skip it for now skipBuffer.push(refModule); continue; @@ -519,7 +710,8 @@ const visitModules = ( if (skipConnectionBuffer.length > 0) { let { skippedModuleConnections } = chunkGroupInfo; if (skippedModuleConnections === undefined) { - chunkGroupInfo.skippedModuleConnections = skippedModuleConnections = new Set(); + chunkGroupInfo.skippedModuleConnections = skippedModuleConnections = + new Set(); } for (let i = skipConnectionBuffer.length - 1; i >= 0; i--) { skippedModuleConnections.add(skipConnectionBuffer[i]); @@ -561,15 +753,18 @@ const visitModules = ( const processEntryBlock = block => { statProcessedBlocks++; // get prepared block info - const blockModules = blockModulesMap.get(block); + const blockModules = getBlockModules(block, chunkGroupInfo.runtime); if (blockModules !== undefined) { - // Traverse all referenced modules - for (const [refModule, connections] of blockModules) { - const activeState = getActiveStateOfConnections(connections, undefined); + // Traverse all referenced modules in reverse order + for (let i = blockModules.length - 3; i >= 0; i -= 3) { + const refModule = /** @type {Module} */ (blockModules[i]); + const activeState = /** @type {ConnectionState} */ ( + blockModules[i + 1] + ); // enqueue, then add and enter to be in the correct order // this is relevant with circular dependencies - queueBuffer.push({ + queue.push({ action: activeState === true ? ADD_AND_ENTER_ENTRY_MODULE : PROCESS_BLOCK, block: refModule, @@ -579,13 +774,6 @@ const visitModules = ( chunkGroupInfo }); } - // Add buffered items in reverse order - if (queueBuffer.length > 0) { - for (let i = queueBuffer.length - 1; i >= 0; i--) { - queue.push(queueBuffer[i]); - } - queueBuffer.length = 0; - } } // Traverse all Blocks @@ -601,7 +789,7 @@ const visitModules = ( const processQueue = () => { while (queue.length) { statProcessedQueueItems++; - const queueItem = queue.pop(); + const queueItem = /** @type {QueueItem} */ (queue.pop()); module = queueItem.module; block = queueItem.block; chunk = queueItem.chunk; @@ -617,12 +805,18 @@ const visitModules = ( ); // fallthrough case ADD_AND_ENTER_MODULE: { - if (chunkGraph.isModuleInChunk(module, chunk)) { + const isModuleInChunk = chunkGraph.isModuleInChunk(module, chunk); + + if (isModuleInChunk) { // already connected, skip it break; } // We connect Module and Chunk chunkGraph.connectChunkAndModule(chunk, module); + const moduleOrdinal = getModuleOrdinal(module); + let chunkMask = /** @type {bigint} */ (maskByChunk.get(chunk)); + chunkMask |= ONE_BIGINT << BigInt(moduleOrdinal); + maskByChunk.set(chunk, chunkMask); } // fallthrough case ENTER_MODULE: { @@ -679,43 +873,26 @@ const visitModules = ( } }; + /** + * @param {ChunkGroupInfo} chunkGroupInfo The info object for the chunk group + * @returns {bigint} The mask of available modules after the chunk group + */ const calculateResultingAvailableModules = chunkGroupInfo => { - if (chunkGroupInfo.resultingAvailableModules) + if (chunkGroupInfo.resultingAvailableModules !== undefined) return chunkGroupInfo.resultingAvailableModules; - const minAvailableModules = chunkGroupInfo.minAvailableModules; - - // Create a new Set of available modules at this point - // We want to be as lazy as possible. There are multiple ways doing this: - // Note that resultingAvailableModules is stored as "(a) + (b)" as it's a ModuleSetPlus - // - resultingAvailableModules = (modules of chunk) + (minAvailableModules + minAvailableModules.plus) - // - resultingAvailableModules = (minAvailableModules + modules of chunk) + (minAvailableModules.plus) - // We choose one depending on the size of minAvailableModules vs minAvailableModules.plus - - let resultingAvailableModules; - if (minAvailableModules.size > minAvailableModules.plus.size) { - // resultingAvailableModules = (modules of chunk) + (minAvailableModules + minAvailableModules.plus) - resultingAvailableModules = /** @type {Set & {plus: Set}} */ (new Set()); - for (const module of minAvailableModules.plus) - minAvailableModules.add(module); - minAvailableModules.plus = EMPTY_SET; - resultingAvailableModules.plus = minAvailableModules; - chunkGroupInfo.minAvailableModulesOwned = false; - } else { - // resultingAvailableModules = (minAvailableModules + modules of chunk) + (minAvailableModules.plus) - resultingAvailableModules = /** @type {Set & {plus: Set}} */ (new Set( - minAvailableModules - )); - resultingAvailableModules.plus = minAvailableModules.plus; - } + let resultingAvailableModules = /** @type {bigint} */ ( + chunkGroupInfo.minAvailableModules + ); // add the modules from the chunk group to the set for (const chunk of chunkGroupInfo.chunkGroup.chunks) { - for (const m of chunkGraph.getChunkModulesIterable(chunk)) { - resultingAvailableModules.add(m); - } + const mask = /** @type {bigint} */ (maskByChunk.get(chunk)); + resultingAvailableModules |= mask; } - return (chunkGroupInfo.resultingAvailableModules = resultingAvailableModules); + + return (chunkGroupInfo.resultingAvailableModules = + resultingAvailableModules); }; const processConnectQueue = () => { @@ -732,9 +909,8 @@ const visitModules = ( } // 2. Calculate resulting available modules - const resultingAvailableModules = calculateResultingAvailableModules( - chunkGroupInfo - ); + const resultingAvailableModules = + calculateResultingAvailableModules(chunkGroupInfo); const runtime = chunkGroupInfo.runtime; @@ -761,234 +937,24 @@ const visitModules = ( // Execute the merge for (const info of chunkGroupsForMerging) { const availableModulesToBeMerged = info.availableModulesToBeMerged; - let cachedMinAvailableModules = info.minAvailableModules; + const cachedMinAvailableModules = info.minAvailableModules; + let minAvailableModules = cachedMinAvailableModules; statMergedAvailableModuleSets += availableModulesToBeMerged.length; - // 1. Get minimal available modules - // It doesn't make sense to traverse a chunk again with more available modules. - // This step calculates the minimal available modules and skips traversal when - // the list didn't shrink. - if (availableModulesToBeMerged.length > 1) { - availableModulesToBeMerged.sort(bySetSize); - } - let changed = false; - merge: for (const availableModules of availableModulesToBeMerged) { - if (cachedMinAvailableModules === undefined) { - cachedMinAvailableModules = availableModules; - info.minAvailableModules = cachedMinAvailableModules; - info.minAvailableModulesOwned = false; - changed = true; + for (const availableModules of availableModulesToBeMerged) { + if (minAvailableModules === undefined) { + minAvailableModules = availableModules; } else { - if (info.minAvailableModulesOwned) { - // We own it and can modify it - if (cachedMinAvailableModules.plus === availableModules.plus) { - for (const m of cachedMinAvailableModules) { - if (!availableModules.has(m)) { - cachedMinAvailableModules.delete(m); - changed = true; - } - } - } else { - for (const m of cachedMinAvailableModules) { - if (!availableModules.has(m) && !availableModules.plus.has(m)) { - cachedMinAvailableModules.delete(m); - changed = true; - } - } - for (const m of cachedMinAvailableModules.plus) { - if (!availableModules.has(m) && !availableModules.plus.has(m)) { - // We can't remove modules from the plus part - // so we need to merge plus into the normal part to allow modifying it - const iterator = cachedMinAvailableModules.plus[ - Symbol.iterator - ](); - // fast forward add all modules until m - /** @type {IteratorResult} */ - let it; - while (!(it = iterator.next()).done) { - const module = it.value; - if (module === m) break; - cachedMinAvailableModules.add(module); - } - // check the remaining modules before adding - while (!(it = iterator.next()).done) { - const module = it.value; - if ( - availableModules.has(module) || - availableModules.plus.has(m) - ) { - cachedMinAvailableModules.add(module); - } - } - cachedMinAvailableModules.plus = EMPTY_SET; - changed = true; - continue merge; - } - } - } - } else if (cachedMinAvailableModules.plus === availableModules.plus) { - // Common and fast case when the plus part is shared - // We only need to care about the normal part - if (availableModules.size < cachedMinAvailableModules.size) { - // the new availableModules is smaller so it's faster to - // fork from the new availableModules - statForkedAvailableModules++; - statForkedAvailableModulesCount += availableModules.size; - statForkedMergedModulesCount += cachedMinAvailableModules.size; - // construct a new Set as intersection of cachedMinAvailableModules and availableModules - const newSet = /** @type {ModuleSetPlus} */ (new Set()); - newSet.plus = availableModules.plus; - for (const m of availableModules) { - if (cachedMinAvailableModules.has(m)) { - newSet.add(m); - } - } - statForkedResultModulesCount += newSet.size; - cachedMinAvailableModules = newSet; - info.minAvailableModulesOwned = true; - info.minAvailableModules = newSet; - changed = true; - continue merge; - } - for (const m of cachedMinAvailableModules) { - if (!availableModules.has(m)) { - // cachedMinAvailableModules need to be modified - // but we don't own it - statForkedAvailableModules++; - statForkedAvailableModulesCount += - cachedMinAvailableModules.size; - statForkedMergedModulesCount += availableModules.size; - // construct a new Set as intersection of cachedMinAvailableModules and availableModules - // as the plus part is equal we can just take over this one - const newSet = /** @type {ModuleSetPlus} */ (new Set()); - newSet.plus = availableModules.plus; - const iterator = cachedMinAvailableModules[Symbol.iterator](); - // fast forward add all modules until m - /** @type {IteratorResult} */ - let it; - while (!(it = iterator.next()).done) { - const module = it.value; - if (module === m) break; - newSet.add(module); - } - // check the remaining modules before adding - while (!(it = iterator.next()).done) { - const module = it.value; - if (availableModules.has(module)) { - newSet.add(module); - } - } - statForkedResultModulesCount += newSet.size; - cachedMinAvailableModules = newSet; - info.minAvailableModulesOwned = true; - info.minAvailableModules = newSet; - changed = true; - continue merge; - } - } - } else { - for (const m of cachedMinAvailableModules) { - if (!availableModules.has(m) && !availableModules.plus.has(m)) { - // cachedMinAvailableModules need to be modified - // but we don't own it - statForkedAvailableModules++; - statForkedAvailableModulesCount += - cachedMinAvailableModules.size; - statForkedAvailableModulesCountPlus += - cachedMinAvailableModules.plus.size; - statForkedMergedModulesCount += availableModules.size; - statForkedMergedModulesCountPlus += availableModules.plus.size; - // construct a new Set as intersection of cachedMinAvailableModules and availableModules - const newSet = /** @type {ModuleSetPlus} */ (new Set()); - newSet.plus = EMPTY_SET; - const iterator = cachedMinAvailableModules[Symbol.iterator](); - // fast forward add all modules until m - /** @type {IteratorResult} */ - let it; - while (!(it = iterator.next()).done) { - const module = it.value; - if (module === m) break; - newSet.add(module); - } - // check the remaining modules before adding - while (!(it = iterator.next()).done) { - const module = it.value; - if ( - availableModules.has(module) || - availableModules.plus.has(module) - ) { - newSet.add(module); - } - } - // also check all modules in cachedMinAvailableModules.plus - for (const module of cachedMinAvailableModules.plus) { - if ( - availableModules.has(module) || - availableModules.plus.has(module) - ) { - newSet.add(module); - } - } - statForkedResultModulesCount += newSet.size; - cachedMinAvailableModules = newSet; - info.minAvailableModulesOwned = true; - info.minAvailableModules = newSet; - changed = true; - continue merge; - } - } - for (const m of cachedMinAvailableModules.plus) { - if (!availableModules.has(m) && !availableModules.plus.has(m)) { - // cachedMinAvailableModules need to be modified - // but we don't own it - statForkedAvailableModules++; - statForkedAvailableModulesCount += - cachedMinAvailableModules.size; - statForkedAvailableModulesCountPlus += - cachedMinAvailableModules.plus.size; - statForkedMergedModulesCount += availableModules.size; - statForkedMergedModulesCountPlus += availableModules.plus.size; - // construct a new Set as intersection of cachedMinAvailableModules and availableModules - // we already know that all modules directly from cachedMinAvailableModules are in availableModules too - const newSet = /** @type {ModuleSetPlus} */ (new Set( - cachedMinAvailableModules - )); - newSet.plus = EMPTY_SET; - const iterator = cachedMinAvailableModules.plus[ - Symbol.iterator - ](); - // fast forward add all modules until m - /** @type {IteratorResult} */ - let it; - while (!(it = iterator.next()).done) { - const module = it.value; - if (module === m) break; - newSet.add(module); - } - // check the remaining modules before adding - while (!(it = iterator.next()).done) { - const module = it.value; - if ( - availableModules.has(module) || - availableModules.plus.has(module) - ) { - newSet.add(module); - } - } - statForkedResultModulesCount += newSet.size; - cachedMinAvailableModules = newSet; - info.minAvailableModulesOwned = true; - info.minAvailableModules = newSet; - changed = true; - continue merge; - } - } - } + minAvailableModules &= availableModules; } } + + const changed = minAvailableModules !== cachedMinAvailableModules; + availableModulesToBeMerged.length = 0; if (changed) { + info.minAvailableModules = minAvailableModules; info.resultingAvailableModules = undefined; outdatedChunkGroupInfo.add(info); } @@ -997,30 +963,28 @@ const visitModules = ( }; const processChunkGroupsForCombining = () => { - loop: for (const info of chunkGroupsForCombining) { - for (const source of info.availableSources) { - if (!source.minAvailableModules) continue loop; - } - const availableModules = /** @type {ModuleSetPlus} */ (new Set()); - availableModules.plus = EMPTY_SET; - const mergeSet = set => { - if (set.size > availableModules.plus.size) { - for (const item of availableModules.plus) availableModules.add(item); - availableModules.plus = set; - } else { - for (const item of set) availableModules.add(item); + for (const info of chunkGroupsForCombining) { + for (const source of /** @type {Set} */ ( + info.availableSources + )) { + if (source.minAvailableModules === undefined) { + chunkGroupsForCombining.delete(info); + break; } - }; + } + } + + for (const info of chunkGroupsForCombining) { + let availableModules = ZERO_BIGINT; // combine minAvailableModules from all resultingAvailableModules - for (const source of info.availableSources) { - const resultingAvailableModules = calculateResultingAvailableModules( - source - ); - mergeSet(resultingAvailableModules); - mergeSet(resultingAvailableModules.plus); + for (const source of /** @type {Set} */ ( + info.availableSources + )) { + const resultingAvailableModules = + calculateResultingAvailableModules(source); + availableModules |= resultingAvailableModules; } info.minAvailableModules = availableModules; - info.minAvailableModulesOwned = false; info.resultingAvailableModules = undefined; outdatedChunkGroupInfo.add(info); } @@ -1033,12 +997,12 @@ const visitModules = ( for (const info of outdatedChunkGroupInfo) { // 1. Reconsider skipped items if (info.skippedItems !== undefined) { - const { minAvailableModules } = info; + const minAvailableModules = + /** @type {bigint} */ + (info.minAvailableModules); for (const module of info.skippedItems) { - if ( - !minAvailableModules.has(module) && - !minAvailableModules.plus.has(module) - ) { + const ordinal = getModuleOrdinal(module); + if (!isOrdinalSetInMask(minAvailableModules, ordinal)) { queue.push({ action: ADD_AND_ENTER_MODULE, block: module, @@ -1054,21 +1018,24 @@ const visitModules = ( // 2. Reconsider skipped connections if (info.skippedModuleConnections !== undefined) { - const { minAvailableModules, runtime } = info; + const minAvailableModules = + /** @type {bigint} */ + (info.minAvailableModules); for (const entry of info.skippedModuleConnections) { const [module, connections] = entry; - const activeState = getActiveStateOfConnections(connections, runtime); + const activeState = getActiveStateOfConnections( + connections, + info.runtime + ); if (activeState === false) continue; if (activeState === true) { + const ordinal = getModuleOrdinal(module); info.skippedModuleConnections.delete(entry); - } - if ( - activeState === true && - (minAvailableModules.has(module) || - minAvailableModules.plus.has(module)) - ) { - info.skippedItems.add(module); - continue; + if (isOrdinalSetInMask(minAvailableModules, ordinal)) { + /** @type {NonNullable} */ + (info.skippedItems).add(module); + continue; + } } queue.push({ action: activeState === true ? ADD_AND_ENTER_MODULE : PROCESS_BLOCK, @@ -1100,6 +1067,7 @@ const visitModules = ( chunkGroupsForCombining.add(cgi); } } + outdatedOrderIndexChunkGroups.add(info); } outdatedChunkGroupInfo.clear(); }; @@ -1109,6 +1077,7 @@ const visitModules = ( while (queue.length || queueConnect.size) { logger.time("visitModules: visiting"); processQueue(); + logger.timeAggregateEnd("visitModules: prepare"); logger.timeEnd("visitModules: visiting"); if (chunkGroupsForCombining.size > 0) { @@ -1145,6 +1114,55 @@ const visitModules = ( } } + for (const info of outdatedOrderIndexChunkGroups) { + const { chunkGroup, runtime } = info; + + const block = blockByChunkGroups.get(info); + + if (!block) { + continue; + } + + let preOrderIndex = 0; + let postOrderIndex = 0; + + /** + * @param {DependenciesBlock} current current + * @param {BlocksWithNestedBlocks} visited visited dependencies blocks + */ + const process = (current, visited) => { + const blockModules = getBlockModules(current, runtime); + if (blockModules === undefined) { + return; + } + + for (let i = 0, len = blockModules.length; i < len; i += 3) { + const activeState = /** @type {ConnectionState} */ ( + blockModules[i + 1] + ); + if (activeState === false) { + continue; + } + const refModule = /** @type {Module} */ (blockModules[i]); + if (visited.has(refModule)) { + continue; + } + + visited.add(refModule); + + if (refModule) { + chunkGroup.setModulePreOrderIndex(refModule, preOrderIndex++); + process(refModule, visited); + chunkGroup.setModulePostOrderIndex(refModule, postOrderIndex++); + } + } + }; + + process(block, new Set()); + } + outdatedOrderIndexChunkGroups.clear(); + ordinalByModule.clear(); + logger.log( `${statProcessedQueueItems} queue items processed (${statProcessedBlocks} blocks)` ); @@ -1158,33 +1176,29 @@ const visitModules = ( }; /** - * * @param {Compilation} compilation the compilation - * @param {Set} blocksWithNestedBlocks flag for blocks that have nested blocks - * @param {Map} blockConnections connection for blocks - * @param {Map} chunkGroupInfoMap mapping from chunk group to available modules + * @param {BlocksWithNestedBlocks} blocksWithNestedBlocks flag for blocks that have nested blocks + * @param {BlockConnections} blockConnections connection for blocks + * @param {MaskByChunk} maskByChunk mapping from chunk to module mask */ const connectChunkGroups = ( compilation, blocksWithNestedBlocks, blockConnections, - chunkGroupInfoMap + maskByChunk ) => { const { chunkGraph } = compilation; /** * Helper function to check if all modules of a chunk are available - * * @param {ChunkGroup} chunkGroup the chunkGroup to scan - * @param {ModuleSetPlus} availableModules the comparator set + * @param {bigint} availableModules the comparator set * @returns {boolean} return true if all modules of a chunk are available */ const areModulesAvailable = (chunkGroup, availableModules) => { for (const chunk of chunkGroup.chunks) { - for (const module of chunkGraph.getChunkModulesIterable(chunk)) { - if (!availableModules.has(module) && !availableModules.plus.has(module)) - return false; - } + const chunkMask = /** @type {bigint} */ (maskByChunk.get(chunk)); + if ((chunkMask & availableModules) !== chunkMask) return false; } return true; }; @@ -1203,7 +1217,7 @@ const connectChunkGroups = ( connections.every(({ chunkGroup, originChunkGroupInfo }) => areModulesAvailable( chunkGroup, - originChunkGroupInfo.resultingAvailableModules + /** @type {bigint} */ (originChunkGroupInfo.resultingAvailableModules) ) ) ) { @@ -1249,7 +1263,7 @@ const cleanupUnconnectedGroups = (compilation, allCreatedChunkGroups) => { /** * This method creates the Chunk graph from the Module graph * @param {Compilation} compilation the compilation - * @param {Map} inputEntrypointsAndModules chunk groups which are processed with the modules + * @param {InputEntrypointsAndModules} inputEntrypointsAndModules chunk groups which are processed with the modules * @returns {void} */ const buildChunkGraph = (compilation, inputEntrypointsAndModules) => { @@ -1257,18 +1271,21 @@ const buildChunkGraph = (compilation, inputEntrypointsAndModules) => { // SHARED STATE - /** @type {Map} */ + /** @type {BlockConnections} */ const blockConnections = new Map(); - /** @type {Set} */ + /** @type {AllCreatedChunkGroups} */ const allCreatedChunkGroups = new Set(); - /** @type {Map} */ + /** @type {ChunkGroupInfoMap} */ const chunkGroupInfoMap = new Map(); - /** @type {Set} */ + /** @type {BlocksWithNestedBlocks} */ const blocksWithNestedBlocks = new Set(); + /** @type {MaskByChunk} */ + const maskByChunk = new Map(); + // PART ONE logger.time("visitModules"); @@ -1279,7 +1296,8 @@ const buildChunkGraph = (compilation, inputEntrypointsAndModules) => { chunkGroupInfoMap, blockConnections, blocksWithNestedBlocks, - allCreatedChunkGroups + allCreatedChunkGroups, + maskByChunk ); logger.timeEnd("visitModules"); @@ -1290,7 +1308,7 @@ const buildChunkGraph = (compilation, inputEntrypointsAndModules) => { compilation, blocksWithNestedBlocks, blockConnections, - chunkGroupInfoMap + maskByChunk ); logger.timeEnd("connectChunkGroups"); diff --git a/lib/cache/AddManagedPathsPlugin.js b/lib/cache/AddManagedPathsPlugin.js index 2afcc009c7c..d8e860f5272 100644 --- a/lib/cache/AddManagedPathsPlugin.js +++ b/lib/cache/AddManagedPathsPlugin.js @@ -9,12 +9,14 @@ class AddManagedPathsPlugin { /** - * @param {Iterable} managedPaths list of managed paths - * @param {Iterable} immutablePaths list of immutable paths + * @param {Iterable} managedPaths list of managed paths + * @param {Iterable} immutablePaths list of immutable paths + * @param {Iterable} unmanagedPaths list of unmanaged paths */ - constructor(managedPaths, immutablePaths) { + constructor(managedPaths, immutablePaths, unmanagedPaths) { this.managedPaths = new Set(managedPaths); this.immutablePaths = new Set(immutablePaths); + this.unmanagedPaths = new Set(unmanagedPaths); } /** @@ -29,6 +31,9 @@ class AddManagedPathsPlugin { for (const immutablePath of this.immutablePaths) { compiler.immutablePaths.add(immutablePath); } + for (const unmanagedPath of this.unmanagedPaths) { + compiler.unmanagedPaths.add(unmanagedPath); + } } } diff --git a/lib/cache/IdleFileCachePlugin.js b/lib/cache/IdleFileCachePlugin.js index eca5ec1bd1c..3ac59121baf 100644 --- a/lib/cache/IdleFileCachePlugin.js +++ b/lib/cache/IdleFileCachePlugin.js @@ -9,19 +9,27 @@ const Cache = require("../Cache"); const ProgressPlugin = require("../ProgressPlugin"); /** @typedef {import("../Compiler")} Compiler */ +/** @typedef {import("./PackFileCacheStrategy")} PackFileCacheStrategy */ -const BUILD_DEPENDENCIES_KEY = Symbol(); +const BUILD_DEPENDENCIES_KEY = Symbol("build dependencies key"); class IdleFileCachePlugin { /** - * @param {TODO} strategy cache strategy + * @param {PackFileCacheStrategy} strategy cache strategy * @param {number} idleTimeout timeout * @param {number} idleTimeoutForInitialStore initial timeout + * @param {number} idleTimeoutAfterLargeChanges timeout after changes */ - constructor(strategy, idleTimeout, idleTimeoutForInitialStore) { + constructor( + strategy, + idleTimeout, + idleTimeoutForInitialStore, + idleTimeoutAfterLargeChanges + ) { this.strategy = strategy; this.idleTimeout = idleTimeout; this.idleTimeoutForInitialStore = idleTimeoutForInitialStore; + this.idleTimeoutAfterLargeChanges = idleTimeoutAfterLargeChanges; } /** @@ -36,10 +44,14 @@ class IdleFileCachePlugin { idleTimeout, this.idleTimeoutForInitialStore ); - + const idleTimeoutAfterLargeChanges = this.idleTimeoutAfterLargeChanges; const resolvedPromise = Promise.resolve(); - /** @type {Map Promise>} */ + let timeSpendInBuild = 0; + let timeSpendInStore = 0; + let avgTimeSpendInStore = 0; + + /** @type {Map Promise>} */ const pendingIdleTasks = new Map(); compiler.cache.hooks.store.tap( @@ -54,20 +66,27 @@ class IdleFileCachePlugin { compiler.cache.hooks.get.tapPromise( { name: "IdleFileCachePlugin", stage: Cache.STAGE_DISK }, (identifier, etag, gotHandlers) => { - return strategy.restore(identifier, etag).then(cacheEntry => { - if (cacheEntry === undefined) { - gotHandlers.push((result, callback) => { - if (result !== undefined) { - pendingIdleTasks.set(identifier, () => - strategy.store(identifier, etag, result) - ); - } - callback(); - }); - } else { - return cacheEntry; - } - }); + const restore = () => + strategy.restore(identifier, etag).then(cacheEntry => { + if (cacheEntry === undefined) { + gotHandlers.push((result, callback) => { + if (result !== undefined) { + pendingIdleTasks.set(identifier, () => + strategy.store(identifier, etag, result) + ); + } + callback(); + }); + } else { + return cacheEntry; + } + }); + const pendingTask = pendingIdleTasks.get(identifier); + if (pendingTask !== undefined) { + pendingIdleTasks.delete(identifier); + return pendingTask().then(restore); + } + return restore(); } ); @@ -75,7 +94,9 @@ class IdleFileCachePlugin { { name: "IdleFileCachePlugin", stage: Cache.STAGE_DISK }, dependencies => { pendingIdleTasks.set(BUILD_DEPENDENCIES_KEY, () => - strategy.storeBuildDependencies(dependencies) + Promise.resolve().then(() => + strategy.storeBuildDependencies(dependencies) + ) ); } ); @@ -98,10 +119,13 @@ class IdleFileCachePlugin { currentIdlePromise = promise.then(() => strategy.afterAllStored()); if (reportProgress) { currentIdlePromise = currentIdlePromise.then(() => { - reportProgress(1, `stored`); + reportProgress(1, "stored"); }); } - return currentIdlePromise; + return currentIdlePromise.then(() => { + // Reset strategy + if (strategy.clear) strategy.clear(); + }); } ); @@ -111,9 +135,10 @@ class IdleFileCachePlugin { let isInitialStore = true; const processIdleTasks = () => { if (isIdle) { + const startTime = Date.now(); if (pendingIdleTasks.size > 0) { const promises = [currentIdlePromise]; - const maxTime = Date.now() + 100; + const maxTime = startTime + 100; let maxCount = 100; for (const [filename, factory] of pendingIdleTasks) { pendingIdleTasks.delete(filename); @@ -122,13 +147,23 @@ class IdleFileCachePlugin { } currentIdlePromise = Promise.all(promises); currentIdlePromise.then(() => { + timeSpendInStore += Date.now() - startTime; // Allow to exit the process between - setTimeout(processIdleTasks, 0).unref(); + idleTimer = setTimeout(processIdleTasks, 0); + idleTimer.unref(); }); return; } currentIdlePromise = currentIdlePromise - .then(() => strategy.afterAllStored()) + .then(async () => { + await strategy.afterAllStored(); + timeSpendInStore += Date.now() - startTime; + avgTimeSpendInStore = + Math.max(avgTimeSpendInStore, timeSpendInStore) * 0.9 + + timeSpendInStore * 0.1; + timeSpendInStore = 0; + timeSpendInBuild = 0; + }) .catch(err => { const logger = compiler.getInfrastructureLogger( "IdleFileCachePlugin" @@ -139,17 +174,45 @@ class IdleFileCachePlugin { isInitialStore = false; } }; - let idleTimer = undefined; + /** @type {ReturnType | undefined} */ + let idleTimer; compiler.cache.hooks.beginIdle.tap( { name: "IdleFileCachePlugin", stage: Cache.STAGE_DISK }, () => { + const isLargeChange = timeSpendInBuild > avgTimeSpendInStore * 2; + if (isInitialStore && idleTimeoutForInitialStore < idleTimeout) { + compiler + .getInfrastructureLogger("IdleFileCachePlugin") + .log( + `Initial cache was generated and cache will be persisted in ${ + idleTimeoutForInitialStore / 1000 + }s.` + ); + } else if ( + isLargeChange && + idleTimeoutAfterLargeChanges < idleTimeout + ) { + compiler + .getInfrastructureLogger("IdleFileCachePlugin") + .log( + `Spend ${Math.round(timeSpendInBuild) / 1000}s in build and ${ + Math.round(avgTimeSpendInStore) / 1000 + }s in average in cache store. This is considered as large change and cache will be persisted in ${ + idleTimeoutAfterLargeChanges / 1000 + }s.` + ); + } idleTimer = setTimeout( () => { idleTimer = undefined; isIdle = true; resolvedPromise.then(processIdleTasks); }, - isInitialStore ? idleTimeoutForInitialStore : idleTimeout + Math.min( + isInitialStore ? idleTimeoutForInitialStore : Infinity, + isLargeChange ? idleTimeoutAfterLargeChanges : Infinity, + idleTimeout + ) ); idleTimer.unref(); } @@ -164,6 +227,13 @@ class IdleFileCachePlugin { isIdle = false; } ); + compiler.hooks.done.tap("IdleFileCachePlugin", stats => { + // 10% build overhead is ignored, as it's not cacheable + timeSpendInBuild *= 0.9; + timeSpendInBuild += + /** @type {number} */ (stats.endTime) - + /** @type {number} */ (stats.startTime); + }); } } diff --git a/lib/cache/MemoryCachePlugin.js b/lib/cache/MemoryCachePlugin.js index 9b7b7f1b3ec..814f4cddae9 100644 --- a/lib/cache/MemoryCachePlugin.js +++ b/lib/cache/MemoryCachePlugin.js @@ -19,7 +19,7 @@ class MemoryCachePlugin { * @returns {void} */ apply(compiler) { - /** @type {Map} */ + /** @type {Map} */ const cache = new Map(); compiler.cache.hooks.store.tap( { name: "MemoryCachePlugin", stage: Cache.STAGE_MEMORY }, @@ -46,6 +46,12 @@ class MemoryCachePlugin { }); } ); + compiler.cache.hooks.shutdown.tap( + { name: "MemoryCachePlugin", stage: Cache.STAGE_MEMORY }, + () => { + cache.clear(); + } + ); } } module.exports = MemoryCachePlugin; diff --git a/lib/cache/MemoryWithGcCachePlugin.js b/lib/cache/MemoryWithGcCachePlugin.js new file mode 100644 index 00000000000..ddfb80b15f2 --- /dev/null +++ b/lib/cache/MemoryWithGcCachePlugin.js @@ -0,0 +1,135 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ + +"use strict"; + +const Cache = require("../Cache"); + +/** @typedef {import("webpack-sources").Source} Source */ +/** @typedef {import("../Cache").Etag} Etag */ +/** @typedef {import("../Compiler")} Compiler */ +/** @typedef {import("../Module")} Module */ + +class MemoryWithGcCachePlugin { + /** + * @param {object} options Options + * @param {number} options.maxGenerations max generations + */ + constructor({ maxGenerations }) { + this._maxGenerations = maxGenerations; + } + + /** + * Apply the plugin + * @param {Compiler} compiler the compiler instance + * @returns {void} + */ + apply(compiler) { + const maxGenerations = this._maxGenerations; + /** @type {Map} */ + const cache = new Map(); + /** @type {Map} */ + const oldCache = new Map(); + let generation = 0; + let cachePosition = 0; + const logger = compiler.getInfrastructureLogger("MemoryWithGcCachePlugin"); + compiler.hooks.afterDone.tap("MemoryWithGcCachePlugin", () => { + generation++; + let clearedEntries = 0; + let lastClearedIdentifier; + // Avoid coverage problems due indirect changes + /* istanbul ignore next */ + for (const [identifier, entry] of oldCache) { + if (entry.until > generation) break; + + oldCache.delete(identifier); + if (cache.get(identifier) === undefined) { + cache.delete(identifier); + clearedEntries++; + lastClearedIdentifier = identifier; + } + } + if (clearedEntries > 0 || oldCache.size > 0) { + logger.log( + `${cache.size - oldCache.size} active entries, ${ + oldCache.size + } recently unused cached entries${ + clearedEntries > 0 + ? `, ${clearedEntries} old unused cache entries removed e. g. ${lastClearedIdentifier}` + : "" + }` + ); + } + let i = (cache.size / maxGenerations) | 0; + let j = cachePosition >= cache.size ? 0 : cachePosition; + cachePosition = j + i; + for (const [identifier, entry] of cache) { + if (j !== 0) { + j--; + continue; + } + if (entry !== undefined) { + // We don't delete the cache entry, but set it to undefined instead + // This reserves the location in the data table and avoids rehashing + // when constantly adding and removing entries. + // It will be deleted when removed from oldCache. + cache.set(identifier, undefined); + oldCache.delete(identifier); + oldCache.set(identifier, { + entry, + until: generation + maxGenerations + }); + if (i-- === 0) break; + } + } + }); + compiler.cache.hooks.store.tap( + { name: "MemoryWithGcCachePlugin", stage: Cache.STAGE_MEMORY }, + (identifier, etag, data) => { + cache.set(identifier, { etag, data }); + } + ); + compiler.cache.hooks.get.tap( + { name: "MemoryWithGcCachePlugin", stage: Cache.STAGE_MEMORY }, + (identifier, etag, gotHandlers) => { + const cacheEntry = cache.get(identifier); + if (cacheEntry === null) { + return null; + } else if (cacheEntry !== undefined) { + return cacheEntry.etag === etag ? cacheEntry.data : null; + } + const oldCacheEntry = oldCache.get(identifier); + if (oldCacheEntry !== undefined) { + const cacheEntry = oldCacheEntry.entry; + if (cacheEntry === null) { + oldCache.delete(identifier); + cache.set(identifier, cacheEntry); + return null; + } + if (cacheEntry.etag !== etag) return null; + oldCache.delete(identifier); + cache.set(identifier, cacheEntry); + return cacheEntry.data; + } + gotHandlers.push((result, callback) => { + if (result === undefined) { + cache.set(identifier, null); + } else { + cache.set(identifier, { etag, data: result }); + } + return callback(); + }); + } + ); + compiler.cache.hooks.shutdown.tap( + { name: "MemoryWithGcCachePlugin", stage: Cache.STAGE_MEMORY }, + () => { + cache.clear(); + oldCache.clear(); + } + ); + } +} +module.exports = MemoryWithGcCachePlugin; diff --git a/lib/cache/PackFileCacheStrategy.js b/lib/cache/PackFileCacheStrategy.js index d41fd97fa84..3f340dbcb9d 100644 --- a/lib/cache/PackFileCacheStrategy.js +++ b/lib/cache/PackFileCacheStrategy.js @@ -8,6 +8,7 @@ const FileSystemInfo = require("../FileSystemInfo"); const ProgressPlugin = require("../ProgressPlugin"); const { formatSize } = require("../SizeFormatHelpers"); +const SerializerMiddleware = require("../serialization/SerializerMiddleware"); const LazySet = require("../util/LazySet"); const makeSerializable = require("../util/makeSerializable"); const memoize = require("../util/memoize"); @@ -19,17 +20,25 @@ const { /** @typedef {import("../../declarations/WebpackOptions").SnapshotOptions} SnapshotOptions */ /** @typedef {import("../Cache").Etag} Etag */ /** @typedef {import("../Compiler")} Compiler */ +/** @typedef {import("../FileSystemInfo").ResolveBuildDependenciesResult} ResolveBuildDependenciesResult */ /** @typedef {import("../FileSystemInfo").Snapshot} Snapshot */ /** @typedef {import("../logging/Logger").Logger} Logger */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */ /** @typedef {import("../util/fs").IntermediateFileSystem} IntermediateFileSystem */ +/** @typedef {Map} ResolveResults */ +/** @typedef {Set} Items */ +/** @typedef {Set} BuildDependencies */ +/** @typedef {Map} ItemInfo */ + class PackContainer { /** - * @param {Object} data stored data + * @param {object} data stored data * @param {string} version version identifier * @param {Snapshot} buildSnapshot snapshot of all build dependencies - * @param {Set} buildDependencies list of all unresolved build dependencies captured - * @param {Map} resolveResults result of the resolved build dependencies + * @param {BuildDependencies} buildDependencies list of all unresolved build dependencies captured + * @param {ResolveResults} resolveResults result of the resolved build dependencies * @param {Snapshot} resolveBuildDependenciesSnapshot snapshot of the dependencies of the build dependencies resolving */ constructor( @@ -48,15 +57,22 @@ class PackContainer { this.resolveBuildDependenciesSnapshot = resolveBuildDependenciesSnapshot; } + /** + * @param {ObjectSerializerContext} context context + */ serialize({ write, writeLazy }) { write(this.version); write(this.buildSnapshot); write(this.buildDependencies); write(this.resolveResults); write(this.resolveBuildDependenciesSnapshot); - writeLazy(this.data); + /** @type {NonNullable} */ + (writeLazy)(this.data); } + /** + * @param {ObjectDeserializerContext} context context + */ deserialize({ read }) { this.version = read(); this.buildSnapshot = read(); @@ -75,8 +91,9 @@ makeSerializable( const MIN_CONTENT_SIZE = 1024 * 1024; // 1 MB const CONTENT_COUNT_TO_MERGE = 10; -const MAX_AGE = 1000 * 60 * 60 * 24 * 60; // 1 month +const MIN_ITEMS_IN_FRESH_PACK = 100; const MAX_ITEMS_IN_FRESH_PACK = 50000; +const MAX_TIME_IN_FRESH_PACK = 1 * 60 * 1000; // 1 min class PackItemInfo { /** @@ -94,17 +111,44 @@ class PackItemInfo { } class Pack { - constructor(logger) { - /** @type {Map} */ + /** + * @param {Logger} logger a logger + * @param {number} maxAge max age of cache items + */ + constructor(logger, maxAge) { + /** @type {ItemInfo} */ this.itemInfo = new Map(); - /** @type {string[]} */ + /** @type {(string | undefined)[]} */ this.requests = []; - /** @type {Map} */ + this.requestsTimeout = undefined; + /** @type {ItemInfo} */ this.freshContent = new Map(); /** @type {(undefined | PackContent)[]} */ this.content = []; this.invalid = false; this.logger = logger; + this.maxAge = maxAge; + } + + /** + * @param {string} identifier identifier + */ + _addRequest(identifier) { + this.requests.push(identifier); + if (this.requestsTimeout === undefined) { + this.requestsTimeout = setTimeout(() => { + this.requests.push(undefined); + this.requestsTimeout = undefined; + }, MAX_TIME_IN_FRESH_PACK); + if (this.requestsTimeout.unref) this.requestsTimeout.unref(); + } + } + + stopCapturingRequests() { + if (this.requestsTimeout !== undefined) { + clearTimeout(this.requestsTimeout); + this.requestsTimeout = undefined; + } } /** @@ -114,21 +158,20 @@ class Pack { */ get(identifier, etag) { const info = this.itemInfo.get(identifier); - this.requests.push(identifier); + this._addRequest(identifier); if (info === undefined) { - return undefined; + return; } if (info.etag !== etag) return null; info.lastAccess = Date.now(); const loc = info.location; if (loc === -1) { return info.freshValue; - } else { - if (!this.content[loc]) { - return undefined; - } - return this.content[loc].get(identifier); } + if (!this.content[loc]) { + return; + } + return /** @type {PackContent} */ (this.content[loc]).get(identifier); } /** @@ -146,14 +189,14 @@ class Pack { if (info === undefined) { const newInfo = new PackItemInfo(identifier, etag, data); this.itemInfo.set(identifier, newInfo); - this.requests.push(identifier); + this._addRequest(identifier); this.freshContent.set(identifier, newInfo); } else { const loc = info.location; if (loc >= 0) { - this.requests.push(identifier); + this._addRequest(identifier); this.freshContent.set(identifier, info); - const content = this.content[loc]; + const content = /** @type {PackContent} */ (this.content[loc]); content.delete(identifier); if (content.items.size === 0) { this.content[loc] = undefined; @@ -167,6 +210,21 @@ class Pack { } } + getContentStats() { + let count = 0; + let size = 0; + for (const content of this.content) { + if (content !== undefined) { + count++; + const s = content.getSize(); + if (s > 0) { + size += s; + } + } + } + return { count, size }; + } + /** * @returns {number} new location of data entries */ @@ -176,13 +234,19 @@ class Pack { return i; } + /** + * @private + * @param {Items} items items + * @param {Items} usedItems used items + * @param {number} newLoc new location + */ _gcAndUpdateLocation(items, usedItems, newLoc) { let count = 0; let lastGC; const now = Date.now(); for (const identifier of items) { - const info = this.itemInfo.get(identifier); - if (now - info.lastAccess > MAX_AGE) { + const info = /** @type {PackItemInfo} */ (this.itemInfo.get(identifier)); + if (now - info.lastAccess > this.maxAge) { this.itemInfo.delete(identifier); items.delete(identifier); usedItems.delete(identifier); @@ -194,36 +258,49 @@ class Pack { } if (count > 0) { this.logger.log( - "Garbage Collected %d old items at pack %d e. g. %s", + "Garbage Collected %d old items at pack %d (%d items remaining) e. g. %s", count, newLoc, + items.size, lastGC ); } } _persistFreshContent() { - if (this.freshContent.size > 0) { - const packCount = Math.ceil( - this.freshContent.size / MAX_ITEMS_IN_FRESH_PACK - ); - const itemsPerPack = Math.ceil(this.freshContent.size / packCount); - this.logger.log(`${this.freshContent.size} fresh items in cache`); - const packs = Array.from({ length: packCount }, () => { + const itemsCount = this.freshContent.size; + if (itemsCount > 0) { + const packCount = Math.ceil(itemsCount / MAX_ITEMS_IN_FRESH_PACK); + const itemsPerPack = Math.ceil(itemsCount / packCount); + const packs = []; + let i = 0; + let ignoreNextTimeTick = false; + const createNextPack = () => { const loc = this._findLocation(); this.content[loc] = null; // reserve - return { - /** @type {Set} */ + const pack = { + /** @type {Items} */ items: new Set(), /** @type {Map} */ map: new Map(), loc }; - }); - let i = 0; - let pack = packs[0]; - let packIndex = 0; + packs.push(pack); + return pack; + }; + let pack = createNextPack(); + if (this.requestsTimeout !== undefined) + clearTimeout(this.requestsTimeout); for (const identifier of this.requests) { + if (identifier === undefined) { + if (ignoreNextTimeTick) { + ignoreNextTimeTick = false; + } else if (pack.items.size >= MIN_ITEMS_IN_FRESH_PACK) { + i = 0; + pack = createNextPack(); + } + continue; + } const info = this.freshContent.get(identifier); if (info === undefined) continue; pack.items.add(identifier); @@ -233,9 +310,11 @@ class Pack { this.freshContent.delete(identifier); if (++i > itemsPerPack) { i = 0; - pack = packs[++packIndex]; + pack = createNextPack(); + ignoreNextTimeTick = true; } } + this.requests.length = 0; for (const pack of packs) { this.content[pack.loc] = new PackContent( pack.items, @@ -243,6 +322,15 @@ class Pack { new PackContentItems(pack.map) ); } + this.logger.log( + `${itemsCount} fresh items in cache put into pack ${ + packs.length > 1 + ? packs + .map(pack => `${pack.loc} (${pack.items.size} items)`) + .join(", ") + : packs[0].loc + }` + ); } } @@ -290,32 +378,35 @@ class Pack { mergedIndices = smallUnusedContents; } else return; + /** @type {PackContent[] } */ const mergedContent = []; // 3. Remove old content entries for (const i of mergedIndices) { - mergedContent.push(this.content[i]); + mergedContent.push(/** @type {PackContent} */ (this.content[i])); this.content[i] = undefined; } // 4. Determine merged items - /** @type {Set} */ + /** @type {Items} */ const mergedItems = new Set(); - /** @type {Set} */ + /** @type {Items} */ const mergedUsedItems = new Set(); - /** @type {(function(Map): Promise)[]} */ + /** @type {(function(Map): Promise)[]} */ const addToMergedMap = []; for (const content of mergedContent) { for (const identifier of content.items) { mergedItems.add(identifier); } - for (const identifer of content.used) { - mergedUsedItems.add(identifer); + for (const identifier of content.used) { + mergedUsedItems.add(identifier); } addToMergedMap.push(async map => { // unpack existing content // after that values are accessible in .content - await content.unpack(); + await content.unpack( + "it should be merged with other small pack contents" + ); for (const [identifier, value] of content.content) { map.set(identifier, value); } @@ -375,7 +466,9 @@ class Pack { usedItems, new Set(usedItems), async () => { - await content.unpack(); + await content.unpack( + "it should be splitted into used and unused items" + ); const map = new Map(); for (const identifier of usedItems) { map.set(identifier, content.content.get(identifier)); @@ -400,7 +493,9 @@ class Pack { unusedItems, usedOfUnusedItems, async () => { - await content.unpack(); + await content.unpack( + "it should be splitted into used and unused items" + ); const map = new Map(); for (const identifier of unusedItems) { map.set(identifier, content.content.get(identifier)); @@ -426,10 +521,53 @@ class Pack { } } + /** + * Find the content with the oldest item and run GC on that. + * Only runs for one content to avoid large invalidation. + */ + _gcOldestContent() { + /** @type {PackItemInfo | undefined} */ + let oldest; + for (const info of this.itemInfo.values()) { + if (oldest === undefined || info.lastAccess < oldest.lastAccess) { + oldest = info; + } + } + if ( + Date.now() - /** @type {PackItemInfo} */ (oldest).lastAccess > + this.maxAge + ) { + const loc = /** @type {PackItemInfo} */ (oldest).location; + if (loc < 0) return; + const content = /** @type {PackContent} */ (this.content[loc]); + const items = new Set(content.items); + const usedItems = new Set(content.used); + this._gcAndUpdateLocation(items, usedItems, loc); + + this.content[loc] = + items.size > 0 + ? new PackContent(items, usedItems, async () => { + await content.unpack( + "it contains old items that should be garbage collected" + ); + const map = new Map(); + for (const identifier of items) { + map.set(identifier, content.content.get(identifier)); + } + return new PackContentItems(map); + }) + : undefined; + } + } + + /** + * @param {ObjectSerializerContext} context context + */ serialize({ write, writeSeparate }) { this._persistFreshContent(); this._optimizeSmallContent(); this._optimizeUnusedContent(); + this._gcOldestContent(); for (const identifier of this.itemInfo.keys()) { write(identifier); } @@ -444,7 +582,7 @@ class Pack { const content = this.content[i]; if (content !== undefined) { write(content.items); - writeSeparate(content.getLazyContentItems(), { name: `${i}` }); + content.writeLazy(lazy => writeSeparate(lazy, { name: `${i}` })); } else { write(undefined); // undefined marks an empty content slot } @@ -452,6 +590,9 @@ class Pack { write(null); // null as marker of the end of items } + /** + * @param {ObjectDeserializerContext & { logger: Logger }} context context + */ deserialize({ read, logger }) { this.logger = logger; { @@ -510,13 +651,53 @@ class PackContentItems { this.map = map; } - serialize({ write, snapshot, rollback, logger }) { + /** + * @param {ObjectSerializerContext & { snapshot: TODO, rollback: TODO, logger: Logger, profile: boolean | undefined }} context context + */ + serialize({ write, snapshot, rollback, logger, profile }) { + if (profile) { + write(false); + for (const [key, value] of this.map) { + const s = snapshot(); + try { + write(key); + const start = process.hrtime(); + write(value); + const durationHr = process.hrtime(start); + const duration = durationHr[0] * 1000 + durationHr[1] / 1e6; + if (duration > 1) { + if (duration > 500) + logger.error(`Serialization of '${key}': ${duration} ms`); + else if (duration > 50) + logger.warn(`Serialization of '${key}': ${duration} ms`); + else if (duration > 10) + logger.info(`Serialization of '${key}': ${duration} ms`); + else if (duration > 5) + logger.log(`Serialization of '${key}': ${duration} ms`); + else logger.debug(`Serialization of '${key}': ${duration} ms`); + } + } catch (err) { + rollback(s); + if (err === NOT_SERIALIZABLE) continue; + const msg = "Skipped not serializable cache item"; + if (err.message.includes("ModuleBuildError")) { + logger.log(`${msg} (in build error): ${err.message}`); + logger.debug(`${msg} '${key}' (in build error): ${err.stack}`); + } else { + logger.warn(`${msg}: ${err.message}`); + logger.debug(`${msg} '${key}': ${err.stack}`); + } + } + } + write(null); + return; + } // Try to serialize all at once const s = snapshot(); try { write(true); write(this.map); - } catch (e) { + } catch (_err) { rollback(s); // Try to serialize each item on it's own @@ -526,22 +707,48 @@ class PackContentItems { try { write(key); write(value); - } catch (e) { + } catch (err) { rollback(s); - if (e === NOT_SERIALIZABLE) continue; + if (err === NOT_SERIALIZABLE) continue; logger.warn( - `Skipped not serializable cache item '${key}': ${e.message}` + `Skipped not serializable cache item '${key}': ${err.message}` ); - logger.debug(e.stack); + logger.debug(err.stack); } } write(null); } } - deserialize({ read }) { + /** + * @param {ObjectDeserializerContext & { logger: Logger, profile: boolean | undefined }} context context + */ + deserialize({ read, logger, profile }) { if (read()) { this.map = read(); + } else if (profile) { + const map = new Map(); + let key = read(); + while (key !== null) { + const start = process.hrtime(); + const value = read(); + const durationHr = process.hrtime(start); + const duration = durationHr[0] * 1000 + durationHr[1] / 1e6; + if (duration > 1) { + if (duration > 100) + logger.error(`Deserialization of '${key}': ${duration} ms`); + else if (duration > 20) + logger.warn(`Deserialization of '${key}': ${duration} ms`); + else if (duration > 5) + logger.info(`Deserialization of '${key}': ${duration} ms`); + else if (duration > 2) + logger.log(`Deserialization of '${key}': ${duration} ms`); + else logger.debug(`Deserialization of '${key}': ${duration} ms`); + } + map.set(key, value); + key = read(); + } + this.map = map; } else { const map = new Map(); let key = read(); @@ -561,18 +768,37 @@ makeSerializable( ); class PackContent { + /* + This class can be in these states: + | this.lazy | this.content | this.outdated | state + A1 | undefined | Map | false | fresh content + A2 | undefined | Map | true | (will not happen) + B1 | lazy () => {} | undefined | false | not deserialized + B2 | lazy () => {} | undefined | true | not deserialized, but some items has been removed + C1 | lazy* () => {} | Map | false | deserialized + C2 | lazy* () => {} | Map | true | deserialized, and some items has been removed + + this.used is a subset of this.items. + this.items is a subset of this.content.keys() resp. this.lazy().map.keys() + When this.outdated === false, this.items === this.content.keys() resp. this.lazy().map.keys() + When this.outdated === true, this.items should be used to recreated this.lazy/this.content. + When this.lazy and this.content is set, they contain the same data. + this.get must only be called with a valid item from this.items. + In state C this.lazy is unMemoized + */ + /** - * @param {Set} items keys - * @param {Set} usedItems used keys + * @param {Items} items keys + * @param {Items} usedItems used keys * @param {PackContentItems | function(): Promise} dataOrFn sync or async content * @param {Logger=} logger logger for logging * @param {string=} lazyName name of dataOrFn for logging */ constructor(items, usedItems, dataOrFn, logger, lazyName) { this.items = items; - /** @type {function(): PackContentItems | Promise} */ + /** @type {(function(): Promise | PackContentItems) | undefined} */ this.lazy = typeof dataOrFn === "function" ? dataOrFn : undefined; - /** @type {Map} */ + /** @type {Map | undefined} */ this.content = typeof dataOrFn === "function" ? undefined : dataOrFn.map; this.outdated = false; this.used = usedItems; @@ -580,12 +806,20 @@ class PackContent { this.lazyName = lazyName; } + /** + * @param {string} identifier identifier + * @returns {string | Promise} result + */ get(identifier) { this.used.add(identifier); if (this.content) { return this.content.get(identifier); } + + const logger = /** @type {Logger} */ (this.logger); + // We are in state B const { lazyName } = this; + /** @type {string | undefined} */ let timeMessage; if (lazyName) { // only log once @@ -593,40 +827,49 @@ class PackContent { timeMessage = `restore cache content ${lazyName} (${formatSize( this.getSize() )})`; - this.logger.log( + logger.log( `starting to restore cache content ${lazyName} (${formatSize( this.getSize() )}) because of request to: ${identifier}` ); - this.logger.time(timeMessage); + logger.time(timeMessage); } const value = this.lazy(); - if (value instanceof Promise) { + if ("then" in value) { return value.then(data => { const map = data.map; if (timeMessage) { - this.logger.timeEnd(timeMessage); + logger.timeEnd(timeMessage); } + // Move to state C this.content = map; + this.lazy = SerializerMiddleware.unMemoizeLazy(this.lazy); return map.get(identifier); }); - } else { - const map = value.map; - if (timeMessage) { - this.logger.timeEnd(timeMessage); - } - this.content = map; - return map.get(identifier); } + + const map = value.map; + if (timeMessage) { + logger.timeEnd(timeMessage); + } + // Move to state C + this.content = map; + this.lazy = SerializerMiddleware.unMemoizeLazy(this.lazy); + return map.get(identifier); } /** - * @returns {void | Promise} maybe a promise if lazy + * @param {string} reason explanation why unpack is necessary + * @returns {void | Promise} maybe a promise if lazy */ - unpack() { + unpack(reason) { if (this.content) return; + + const logger = /** @type {Logger} */ (this.logger); + // Move from state B to C if (this.lazy) { const { lazyName } = this; + /** @type {string | undefined} */ let timeMessage; if (lazyName) { // only log once @@ -634,22 +877,26 @@ class PackContent { timeMessage = `unpack cache content ${lazyName} (${formatSize( this.getSize() )})`; - this.logger.time(timeMessage); + logger.log( + `starting to unpack cache content ${lazyName} (${formatSize( + this.getSize() + )}) because ${reason}` + ); + logger.time(timeMessage); } const value = this.lazy(); - if (value instanceof Promise) { + if ("then" in value) { return value.then(data => { if (timeMessage) { - this.logger.timeEnd(timeMessage); + logger.timeEnd(timeMessage); } this.content = data.map; }); - } else { - if (timeMessage) { - this.logger.timeEnd(timeMessage); - } - this.content = value.map; } + if (timeMessage) { + logger.timeEnd(timeMessage); + } + this.content = value.map; } } @@ -665,6 +912,9 @@ class PackContent { return size; } + /** + * @param {string} identifier identifier + */ delete(identifier) { this.items.delete(identifier); this.used.delete(identifier); @@ -672,54 +922,113 @@ class PackContent { } /** - * @returns {function(): PackContentItems | Promise} lazy content items + * @template T + * @param {function(any): function(): Promise | PackContentItems} write write function + * @returns {void} */ - getLazyContentItems() { - if (!this.outdated && this.lazy) return this.lazy; + writeLazy(write) { + if (!this.outdated && this.lazy) { + // State B1 or C1 + // this.lazy is still the valid deserialized version + write(this.lazy); + return; + } if (!this.outdated && this.content) { + // State A1 const map = new Map(this.content); - return (this.lazy = memoize(() => new PackContentItems(map))); + // Move to state C1 + this.lazy = SerializerMiddleware.unMemoizeLazy( + write(() => new PackContentItems(map)) + ); + return; } - this.outdated = false; if (this.content) { - return (this.lazy = memoize(() => { - /** @type {Map} */ - const map = new Map(); - for (const item of this.items) { - map.set(item, this.content.get(item)); - } - return new PackContentItems(map); - })); + // State A2 or C2 + /** @type {Map} */ + const map = new Map(); + for (const item of this.items) { + map.set(item, this.content.get(item)); + } + // Move to state C1 + this.outdated = false; + this.content = map; + this.lazy = SerializerMiddleware.unMemoizeLazy( + write(() => new PackContentItems(map)) + ); + return; } - const lazy = this.lazy; - return (this.lazy = () => { - const value = lazy(); - if (value instanceof Promise) { - return value.then(data => { + const logger = /** @type {Logger} */ (this.logger); + // State B2 + const { lazyName } = this; + /** @type {string | undefined} */ + let timeMessage; + if (lazyName) { + // only log once + this.lazyName = undefined; + timeMessage = `unpack cache content ${lazyName} (${formatSize( + this.getSize() + )})`; + logger.log( + `starting to unpack cache content ${lazyName} (${formatSize( + this.getSize() + )}) because it's outdated and need to be serialized` + ); + logger.time(timeMessage); + } + const value = this.lazy(); + this.outdated = false; + if ("then" in value) { + // Move to state B1 + this.lazy = write(() => + value.then(data => { + if (timeMessage) { + logger.timeEnd(timeMessage); + } const oldMap = data.map; /** @type {Map} */ const map = new Map(); for (const item of this.items) { map.set(item, oldMap.get(item)); } + // Move to state C1 (or maybe C2) + this.content = map; + this.lazy = SerializerMiddleware.unMemoizeLazy(this.lazy); + return new PackContentItems(map); - }); - } else { - const oldMap = value.map; - /** @type {Map} */ - const map = new Map(); - for (const item of this.items) { - map.set(item, oldMap.get(item)); - } - return new PackContentItems(map); + }) + ); + } else { + // Move to state C1 + if (timeMessage) { + logger.timeEnd(timeMessage); } - }); + const oldMap = value.map; + /** @type {Map} */ + const map = new Map(); + for (const item of this.items) { + map.set(item, oldMap.get(item)); + } + this.content = map; + this.lazy = write(() => new PackContentItems(map)); + } } } +/** + * @param {Buffer} buf buffer + * @returns {Buffer} buffer that can be collected + */ +const allowCollectingMemory = buf => { + const wasted = buf.buffer.byteLength - buf.byteLength; + if (wasted > 8192 && (wasted > 1048576 || wasted > buf.byteLength)) { + return Buffer.from(buf); + } + return buf; +}; + class PackFileCacheStrategy { /** - * @param {Object} options options + * @param {object} options options * @param {Compiler} options.compiler the compiler * @param {IntermediateFileSystem} options.fs the filesystem * @param {string} options.context the context directory @@ -727,6 +1036,11 @@ class PackFileCacheStrategy { * @param {string} options.version version identifier * @param {Logger} options.logger a logger * @param {SnapshotOptions} options.snapshot options regarding snapshotting + * @param {number} options.maxAge max age of cache items + * @param {boolean | undefined} options.profile track and log detailed timing information for individual cache items + * @param {boolean | undefined} options.allowCollectingMemory allow to collect unused memory created during deserialization + * @param {false | "gzip" | "brotli" | undefined} options.compression compression used + * @param {boolean | undefined} options.readonly disable storing cache into filesystem */ constructor({ compiler, @@ -735,82 +1049,119 @@ class PackFileCacheStrategy { cacheLocation, version, logger, - snapshot + snapshot, + maxAge, + profile, + allowCollectingMemory, + compression, + readonly }) { - this.fileSerializer = createFileSerializer(fs); + this.fileSerializer = createFileSerializer( + fs, + compiler.options.output.hashFunction + ); this.fileSystemInfo = new FileSystemInfo(fs, { managedPaths: snapshot.managedPaths, immutablePaths: snapshot.immutablePaths, - logger: logger.getChildLogger("webpack.FileSystemInfo") + logger: logger.getChildLogger("webpack.FileSystemInfo"), + hashFunction: compiler.options.output.hashFunction }); this.compiler = compiler; this.context = context; this.cacheLocation = cacheLocation; this.version = version; this.logger = logger; + this.maxAge = maxAge; + this.profile = profile; + this.readonly = readonly; + this.allowCollectingMemory = allowCollectingMemory; + this.compression = compression; + this._extension = + compression === "brotli" + ? ".pack.br" + : compression === "gzip" + ? ".pack.gz" + : ".pack"; this.snapshot = snapshot; - /** @type {Set} */ + /** @type {BuildDependencies} */ this.buildDependencies = new Set(); /** @type {LazySet} */ this.newBuildDependencies = new LazySet(); - /** @type {Snapshot} */ + /** @type {Snapshot | undefined} */ this.resolveBuildDependenciesSnapshot = undefined; - /** @type {Map} */ + /** @type {ResolveResults | undefined} */ this.resolveResults = undefined; - /** @type {Snapshot} */ + /** @type {Snapshot | undefined} */ this.buildSnapshot = undefined; - /** @type {Promise} */ + /** @type {Promise | undefined} */ this.packPromise = this._openPack(); + this.storePromise = Promise.resolve(); + } + + /** + * @returns {Promise} pack + */ + _getPack() { + if (this.packPromise === undefined) { + this.packPromise = this.storePromise.then(() => this._openPack()); + } + return this.packPromise; } /** * @returns {Promise} the pack */ _openPack() { - const { logger, cacheLocation, version } = this; + const { logger, profile, cacheLocation, version } = this; /** @type {Snapshot} */ let buildSnapshot; - /** @type {Set} */ + /** @type {BuildDependencies} */ let buildDependencies; - /** @type {Set} */ + /** @type {BuildDependencies} */ let newBuildDependencies; /** @type {Snapshot} */ let resolveBuildDependenciesSnapshot; - /** @type {Map} */ + /** @type {ResolveResults | undefined} */ let resolveResults; logger.time("restore cache container"); return this.fileSerializer .deserialize(null, { - filename: `${cacheLocation}/index.pack`, - extension: ".pack", - logger + filename: `${cacheLocation}/index${this._extension}`, + extension: `${this._extension}`, + logger, + profile, + retainedBuffer: this.allowCollectingMemory + ? allowCollectingMemory + : undefined }) .catch(err => { if (err.code !== "ENOENT") { logger.warn( - `Restoring pack failed from ${cacheLocation}.pack: ${err}` + `Restoring pack failed from ${cacheLocation}${this._extension}: ${err}` ); logger.debug(err.stack); } else { - logger.debug(`No pack exists at ${cacheLocation}.pack: ${err}`); + logger.debug( + `No pack exists at ${cacheLocation}${this._extension}: ${err}` + ); } return undefined; }) .then(packContainer => { logger.timeEnd("restore cache container"); - if (!packContainer) return undefined; + if (!packContainer) return; if (!(packContainer instanceof PackContainer)) { logger.warn( - `Restored pack from ${cacheLocation}.pack, but contained content is unexpected.`, + `Restored pack from ${cacheLocation}${this._extension}, but contained content is unexpected.`, packContainer ); - return undefined; + return; } if (packContainer.version !== version) { logger.log( - `Restored pack from ${cacheLocation}.pack, but version doesn't match.` + `Restored pack from ${cacheLocation}${this._extension}, but version doesn't match.` ); - return undefined; + return; } logger.time("check build dependencies"); return Promise.all([ @@ -820,14 +1171,14 @@ class PackFileCacheStrategy { (err, valid) => { if (err) { logger.log( - `Restored pack from ${cacheLocation}.pack, but checking snapshot of build dependencies errored: ${err}.` + `Restored pack from ${cacheLocation}${this._extension}, but checking snapshot of build dependencies errored: ${err}.` ); logger.debug(err.stack); return resolve(false); } if (!valid) { logger.log( - `Restored pack from ${cacheLocation}.pack, but build dependencies have changed.` + `Restored pack from ${cacheLocation}${this._extension}, but build dependencies have changed.` ); return resolve(false); } @@ -842,7 +1193,7 @@ class PackFileCacheStrategy { (err, valid) => { if (err) { logger.log( - `Restored pack from ${cacheLocation}.pack, but checking snapshot of resolving of build dependencies errored: ${err}.` + `Restored pack from ${cacheLocation}${this._extension}, but checking snapshot of resolving of build dependencies errored: ${err}.` ); logger.debug(err.stack); return resolve(false); @@ -862,7 +1213,7 @@ class PackFileCacheStrategy { (err, valid) => { if (err) { logger.log( - `Restored pack from ${cacheLocation}.pack, but resolving of build dependencies errored: ${err}.` + `Restored pack from ${cacheLocation}${this._extension}, but resolving of build dependencies errored: ${err}.` ); logger.debug(err.stack); return resolve(false); @@ -873,7 +1224,7 @@ class PackFileCacheStrategy { return resolve(true); } logger.log( - `Restored pack from ${cacheLocation}.pack, but build dependencies resolve to different locations.` + `Restored pack from ${cacheLocation}${this._extension}, but build dependencies resolve to different locations.` ); return resolve(false); } @@ -899,22 +1250,24 @@ class PackFileCacheStrategy { }) .then(pack => { if (pack) { + pack.maxAge = this.maxAge; this.buildSnapshot = buildSnapshot; if (buildDependencies) this.buildDependencies = buildDependencies; if (newBuildDependencies) this.newBuildDependencies.addAll(newBuildDependencies); this.resolveResults = resolveResults; - this.resolveBuildDependenciesSnapshot = resolveBuildDependenciesSnapshot; + this.resolveBuildDependenciesSnapshot = + resolveBuildDependenciesSnapshot; return pack; } - return new Pack(logger); + return new Pack(logger, this.maxAge); }) .catch(err => { this.logger.warn( - `Restoring pack from ${cacheLocation}.pack failed: ${err}` + `Restoring pack from ${cacheLocation}${this._extension} failed: ${err}` ); this.logger.debug(err.stack); - return new Pack(logger); + return new Pack(logger, this.maxAge); }); } @@ -925,7 +1278,9 @@ class PackFileCacheStrategy { * @returns {Promise} promise */ store(identifier, etag, data) { - return this.packPromise.then(pack => { + if (this.readonly) return Promise.resolve(); + + return this._getPack().then(pack => { pack.set(identifier, etag === null ? null : etag.toString(), data); }); } @@ -936,7 +1291,7 @@ class PackFileCacheStrategy { * @returns {Promise} promise to the cached content */ restore(identifier, etag) { - return this.packPromise + return this._getPack() .then(pack => pack.get(identifier, etag === null ? null : etag.toString()) ) @@ -950,16 +1305,24 @@ class PackFileCacheStrategy { }); } + /** + * @param {LazySet | Iterable} dependencies dependencies to store + */ storeBuildDependencies(dependencies) { + if (this.readonly) return; this.newBuildDependencies.addAll(dependencies); } afterAllStored() { + const packPromise = this.packPromise; + if (packPromise === undefined) return Promise.resolve(); const reportProgress = ProgressPlugin.getReporter(this.compiler); - return this.packPromise + return (this.storePromise = packPromise .then(pack => { + pack.stopCapturingRequests(); if (!pack.invalid) return; - this.logger.log(`Storing pack...`); + this.packPromise = undefined; + this.logger.log("Storing pack..."); let promise; const newBuildDependencies = new Set(); for (const dep of this.newBuildDependencies) { @@ -990,7 +1353,7 @@ class PackFileCacheStrategy { missing, resolveResults, resolveDependencies - } = result; + } = /** @type {ResolveBuildDependenciesResult} */ (result); if (this.resolveResults) { for (const [key, value] of resolveResults) { this.resolveResults.set(key, value); @@ -1023,10 +1386,11 @@ class PackFileCacheStrategy { ); } if (this.resolveBuildDependenciesSnapshot) { - this.resolveBuildDependenciesSnapshot = this.fileSystemInfo.mergeSnapshots( - this.resolveBuildDependenciesSnapshot, - snapshot - ); + this.resolveBuildDependenciesSnapshot = + this.fileSystemInfo.mergeSnapshots( + this.resolveBuildDependenciesSnapshot, + snapshot + ); } else { this.resolveBuildDependenciesSnapshot = snapshot; } @@ -1054,10 +1418,11 @@ class PackFileCacheStrategy { this.logger.debug("Captured build dependencies"); if (this.buildSnapshot) { - this.buildSnapshot = this.fileSystemInfo.mergeSnapshots( - this.buildSnapshot, - snapshot - ); + this.buildSnapshot = + this.fileSystemInfo.mergeSnapshots( + this.buildSnapshot, + snapshot + ); } else { this.buildSnapshot = snapshot; } @@ -1075,7 +1440,7 @@ class PackFileCacheStrategy { } return promise.then(() => { if (reportProgress) reportProgress(0.8, "serialize pack"); - this.logger.time(`store pack`); + this.logger.time("store pack"); const updatedBuildDependencies = new Set(this.buildDependencies); for (const dep of newBuildDependencies) { updatedBuildDependencies.add(dep); @@ -1083,27 +1448,34 @@ class PackFileCacheStrategy { const content = new PackContainer( pack, this.version, - this.buildSnapshot, + /** @type {Snapshot} */ (this.buildSnapshot), updatedBuildDependencies, this.resolveResults, this.resolveBuildDependenciesSnapshot ); return this.fileSerializer .serialize(content, { - filename: `${this.cacheLocation}/index.pack`, - extension: ".pack", - logger: this.logger + filename: `${this.cacheLocation}/index${this._extension}`, + extension: `${this._extension}`, + logger: this.logger, + profile: this.profile }) .then(() => { for (const dep of newBuildDependencies) { this.buildDependencies.add(dep); } this.newBuildDependencies.clear(); - this.logger.timeEnd(`store pack`); - this.logger.log(`Stored pack`); + this.logger.timeEnd("store pack"); + const stats = pack.getContentStats(); + this.logger.log( + "Stored pack (%d items, %d files, %d MiB)", + pack.itemInfo.size, + stats.count, + Math.round(stats.size / 1024 / 1024) + ); }) .catch(err => { - this.logger.timeEnd(`store pack`); + this.logger.timeEnd("store pack"); this.logger.warn(`Caching failed for pack: ${err}`); this.logger.debug(err.stack); }); @@ -1112,7 +1484,17 @@ class PackFileCacheStrategy { .catch(err => { this.logger.warn(`Caching failed for pack: ${err}`); this.logger.debug(err.stack); - }); + })); + } + + clear() { + this.fileSystemInfo.clear(); + this.buildDependencies.clear(); + this.newBuildDependencies.clear(); + this.resolveBuildDependenciesSnapshot = undefined; + this.resolveResults = undefined; + this.buildSnapshot = undefined; + this.packPromise = undefined; } } diff --git a/lib/cache/ResolverCachePlugin.js b/lib/cache/ResolverCachePlugin.js index 78d68ed7ad2..3096157f8ef 100644 --- a/lib/cache/ResolverCachePlugin.js +++ b/lib/cache/ResolverCachePlugin.js @@ -8,7 +8,7 @@ const LazySet = require("../util/LazySet"); const makeSerializable = require("../util/makeSerializable"); -/** @typedef {import("enhanced-resolve/lib/Resolver")} Resolver */ +/** @typedef {import("enhanced-resolve").Resolver} Resolver */ /** @typedef {import("../CacheFacade").ItemCacheFacade} ItemCacheFacade */ /** @typedef {import("../Compiler")} Compiler */ /** @typedef {import("../FileSystemInfo")} FileSystemInfo */ @@ -50,7 +50,7 @@ const addAllToSet = (set, otherSet) => { }; /** - * @param {Object} object an object + * @param {object} object an object * @param {boolean} excludeContext if true, context is not included in string * @returns {string} stringified version */ @@ -59,11 +59,10 @@ const objectToString = (object, excludeContext) => { for (const key in object) { if (excludeContext && key === "context") continue; const value = object[key]; - if (typeof value === "object" && value !== null) { - str += `|${key}=[${objectToString(value, false)}|]`; - } else { - str += `|${key}=|${value}`; - } + str += + typeof value === "object" && value !== null + ? `|${key}=[${objectToString(value, false)}|]` + : `|${key}=|${value}`; } return str; }; @@ -104,9 +103,9 @@ class ResolverCachePlugin { /** * @param {ItemCacheFacade} itemCache cache * @param {Resolver} resolver the resolver - * @param {Object} resolveContext context for resolving meta info - * @param {Object} request the request info object - * @param {function(Error=, Object=): void} callback callback function + * @param {object} resolveContext context for resolving meta info + * @param {object} request the request info object + * @param {function((Error | null)=, object=): void} callback callback function * @returns {void} */ const doRealResolve = ( @@ -124,10 +123,20 @@ class ResolverCachePlugin { const newResolveContext = { ...resolveContext, stack: new Set(), + /** @type {LazySet} */ missingDependencies: new LazySet(), + /** @type {LazySet} */ fileDependencies: new LazySet(), + /** @type {LazySet} */ contextDependencies: new LazySet() }; + let yieldResult; + let withYield = false; + if (typeof newResolveContext.yield === "function") { + yieldResult = []; + withYield = true; + newResolveContext.yield = obj => yieldResult.push(obj); + } const propagate = key => { if (resolveContext[key]) { addAllToSet(resolveContext[key], newResolveContext[key]); @@ -155,15 +164,22 @@ class ResolverCachePlugin { snapshotOptions, (err, snapshot) => { if (err) return callback(err); + const resolveResult = withYield ? yieldResult : result; + // since we intercept resolve hook + // we still can get result in callback + if (withYield && result) yieldResult.push(result); if (!snapshot) { - if (result) return callback(null, result); + if (resolveResult) return callback(null, resolveResult); return callback(); } - itemCache.store(new CacheEntry(result, snapshot), storeErr => { - if (storeErr) return callback(storeErr); - if (result) return callback(null, result); - callback(); - }); + itemCache.store( + new CacheEntry(resolveResult, snapshot), + storeErr => { + if (storeErr) return callback(storeErr); + if (resolveResult) return callback(null, resolveResult); + callback(); + } + ); } ); } @@ -171,14 +187,16 @@ class ResolverCachePlugin { }; compiler.resolverFactory.hooks.resolver.intercept({ factory(type, hook) { - /** @type {Map} */ + /** @type {Map} */ const activeRequests = new Map(); + /** @type {Map} */ + const activeRequestsWithYield = new Map(); hook.tap( "ResolverCachePlugin", /** * @param {Resolver} resolver the resolver - * @param {Object} options resolve options - * @param {Object} userOptions resolve options passed by the user + * @param {object} options resolve options + * @param {object} userOptions resolve options passed by the user * @returns {void} */ (resolver, options, userOptions) => { @@ -194,32 +212,76 @@ class ResolverCachePlugin { stage: -100 }, (request, resolveContext, callback) => { - if (request._ResolverCachePluginCacheMiss || !fileSystemInfo) { + if ( + /** @type {TODO} */ (request)._ResolverCachePluginCacheMiss || + !fileSystemInfo + ) { return callback(); } - const identifier = `${type}${optionsIdent}${objectToString( - request, - !cacheWithContext - )}`; - const activeRequest = activeRequests.get(identifier); - if (activeRequest) { - activeRequest.push(callback); - return; + const withYield = typeof resolveContext.yield === "function"; + const identifier = `${type}${ + withYield ? "|yield" : "|default" + }${optionsIdent}${objectToString(request, !cacheWithContext)}`; + + if (withYield) { + const activeRequest = activeRequestsWithYield.get(identifier); + if (activeRequest) { + activeRequest[0].push(callback); + activeRequest[1].push( + /** @type {TODO} */ (resolveContext.yield) + ); + return; + } + } else { + const activeRequest = activeRequests.get(identifier); + if (activeRequest) { + activeRequest.push(callback); + return; + } } const itemCache = cache.getItemCache(identifier, null); let callbacks; - const done = (err, result) => { - if (callbacks === undefined) { - callback(err, result); - callbacks = false; - } else { - for (const callback of callbacks) { - callback(err, result); + let yields; + const done = withYield + ? (err, result) => { + if (callbacks === undefined) { + if (err) { + callback(err); + } else { + if (result) + for (const r of result) resolveContext.yield(r); + callback(null, null); + } + yields = undefined; + callbacks = false; + } else { + if (err) { + for (const cb of callbacks) cb(err); + } else { + for (let i = 0; i < callbacks.length; i++) { + const cb = callbacks[i]; + const yield_ = yields[i]; + if (result) for (const r of result) yield_(r); + cb(null, null); + } + } + activeRequestsWithYield.delete(identifier); + yields = undefined; + callbacks = false; + } } - activeRequests.delete(identifier); - callbacks = false; - } - }; + : (err, result) => { + if (callbacks === undefined) { + callback(err, result); + callbacks = false; + } else { + for (const callback of callbacks) { + callback(err, result); + } + activeRequests.delete(identifier); + callbacks = false; + } + }; /** * @param {Error=} err error if any * @param {CacheEntry=} cacheEntry cache entry @@ -246,19 +308,22 @@ class ResolverCachePlugin { cachedResolves++; if (resolveContext.missingDependencies) { addAllToSet( - resolveContext.missingDependencies, + /** @type {LazySet} */ + (resolveContext.missingDependencies), snapshot.getMissingIterable() ); } if (resolveContext.fileDependencies) { addAllToSet( - resolveContext.fileDependencies, + /** @type {LazySet} */ + (resolveContext.fileDependencies), snapshot.getFileIterable() ); } if (resolveContext.contextDependencies) { addAllToSet( - resolveContext.contextDependencies, + /** @type {LazySet} */ + (resolveContext.contextDependencies), snapshot.getContextIterable() ); } @@ -276,7 +341,14 @@ class ResolverCachePlugin { } }; itemCache.get(processCacheResult); - if (callbacks === undefined) { + if (withYield && callbacks === undefined) { + callbacks = [callback]; + yields = [resolveContext.yield]; + activeRequestsWithYield.set( + identifier, + /** @type {[any, any]} */ ([callbacks, yields]) + ); + } else if (callbacks === undefined) { callbacks = [callback]; activeRequests.set(identifier, callbacks); } diff --git a/lib/cache/getLazyHashedEtag.js b/lib/cache/getLazyHashedEtag.js index 09cd9f0ec77..7fa918b4a19 100644 --- a/lib/cache/getLazyHashedEtag.js +++ b/lib/cache/getLazyHashedEtag.js @@ -8,19 +8,22 @@ const createHash = require("../util/createHash"); /** @typedef {import("../util/Hash")} Hash */ +/** @typedef {typeof import("../util/Hash")} HashConstructor */ /** - * @typedef {Object} HashableObject + * @typedef {object} HashableObject * @property {function(Hash): void} updateHash */ class LazyHashedEtag { /** * @param {HashableObject} obj object with updateHash method + * @param {string | HashConstructor} hashFunction the hash function to use */ - constructor(obj) { + constructor(obj, hashFunction = "md4") { this._obj = obj; this._hash = undefined; + this._hashFunction = hashFunction; } /** @@ -28,7 +31,7 @@ class LazyHashedEtag { */ toString() { if (this._hash === undefined) { - const hash = createHash("md4"); + const hash = createHash(this._hashFunction); this._obj.updateHash(hash); this._hash = /** @type {string} */ (hash.digest("base64")); } @@ -36,18 +39,42 @@ class LazyHashedEtag { } } -/** @type {WeakMap} */ -const map = new WeakMap(); +/** @type {Map>} */ +const mapStrings = new Map(); + +/** @type {WeakMap>} */ +const mapObjects = new WeakMap(); /** * @param {HashableObject} obj object with updateHash method + * @param {(string | HashConstructor)=} hashFunction the hash function to use * @returns {LazyHashedEtag} etag */ -const getter = obj => { - const hash = map.get(obj); +const getter = (obj, hashFunction = "md4") => { + let innerMap; + if (typeof hashFunction === "string") { + innerMap = mapStrings.get(hashFunction); + if (innerMap === undefined) { + const newHash = new LazyHashedEtag(obj, hashFunction); + innerMap = new WeakMap(); + innerMap.set(obj, newHash); + mapStrings.set(hashFunction, innerMap); + return newHash; + } + } else { + innerMap = mapObjects.get(hashFunction); + if (innerMap === undefined) { + const newHash = new LazyHashedEtag(obj, hashFunction); + innerMap = new WeakMap(); + innerMap.set(obj, newHash); + mapObjects.set(hashFunction, innerMap); + return newHash; + } + } + const hash = innerMap.get(obj); if (hash !== undefined) return hash; - const newHash = new LazyHashedEtag(obj); - map.set(obj, newHash); + const newHash = new LazyHashedEtag(obj, hashFunction); + innerMap.set(obj, newHash); return newHash; }; diff --git a/lib/cache/mergeEtags.js b/lib/cache/mergeEtags.js index 8c6af34a8ba..9a212f218a4 100644 --- a/lib/cache/mergeEtags.js +++ b/lib/cache/mergeEtags.js @@ -34,27 +34,23 @@ const mergeEtags = (a, b) => { if (typeof a === "string") { if (typeof b === "string") { return `${a}|${b}`; - } else { - const temp = b; - b = a; - a = temp; } - } else { - if (typeof b !== "string") { - // both a and b are objects - let map = dualObjectMap.get(a); - if (map === undefined) { - dualObjectMap.set(a, (map = new WeakMap())); - } - const mergedEtag = map.get(b); - if (mergedEtag === undefined) { - const newMergedEtag = new MergedEtag(a, b); - map.set(b, newMergedEtag); - return newMergedEtag; - } else { - return mergedEtag; - } + const temp = b; + b = a; + a = temp; + } else if (typeof b !== "string") { + // both a and b are objects + let map = dualObjectMap.get(a); + if (map === undefined) { + dualObjectMap.set(a, (map = new WeakMap())); } + const mergedEtag = map.get(b); + if (mergedEtag === undefined) { + const newMergedEtag = new MergedEtag(a, b); + map.set(b, newMergedEtag); + return newMergedEtag; + } + return mergedEtag; } // a is object, b is string let map = objectStringMap.get(a); @@ -66,9 +62,8 @@ const mergeEtags = (a, b) => { const newMergedEtag = new MergedEtag(a, b); map.set(b, newMergedEtag); return newMergedEtag; - } else { - return mergedEtag; } + return mergedEtag; }; module.exports = mergeEtags; diff --git a/lib/cli.js b/lib/cli.js index eac723f5692..c7ff52bc311 100644 --- a/lib/cli.js +++ b/lib/cli.js @@ -8,9 +8,11 @@ const path = require("path"); const webpackSchema = require("../schemas/WebpackOptions.json"); +/** @typedef {TODO & { absolutePath: boolean, instanceof: string, cli: { helper?: boolean, exclude?: boolean } }} Schema */ + // TODO add originPath to PathItem for better errors /** - * @typedef {Object} PathItem + * @typedef {object} PathItem * @property {any} schema the part of the schema * @property {string} path the path in the config */ @@ -18,7 +20,7 @@ const webpackSchema = require("../schemas/WebpackOptions.json"); /** @typedef {"unknown-argument" | "unexpected-non-array-in-path" | "unexpected-non-object-in-path" | "multiple-values-unexpected" | "invalid-value"} ProblemType */ /** - * @typedef {Object} Problem + * @typedef {object} Problem * @property {ProblemType} type * @property {string} path * @property {string} argument @@ -28,39 +30,50 @@ const webpackSchema = require("../schemas/WebpackOptions.json"); */ /** - * @typedef {Object} LocalProblem + * @typedef {object} LocalProblem * @property {ProblemType} type * @property {string} path * @property {string=} expected */ /** - * @typedef {Object} ArgumentConfig - * @property {string} description + * @typedef {object} ArgumentConfig + * @property {string | undefined} description + * @property {string} [negatedDescription] * @property {string} path * @property {boolean} multiple * @property {"enum"|"string"|"path"|"number"|"boolean"|"RegExp"|"reset"} type * @property {any[]=} values */ +/** @typedef {"string" | "number" | "boolean"} SimpleType */ + /** - * @typedef {Object} Argument - * @property {string} description - * @property {"string"|"number"|"boolean"} simpleType + * @typedef {object} Argument + * @property {string | undefined} description + * @property {SimpleType} simpleType * @property {boolean} multiple * @property {ArgumentConfig[]} configs */ +/** @typedef {string | number | boolean | RegExp | (string | number | boolean | RegExp)} Value */ + +/** @typedef {Record} Flags */ + /** - * @param {any=} schema a json schema to create arguments for (by default webpack schema is used) - * @returns {Record} object of arguments + * @param {Schema=} schema a json schema to create arguments for (by default webpack schema is used) + * @returns {Flags} object of arguments */ const getArguments = (schema = webpackSchema) => { - /** @type {Record} */ + /** @type {Flags} */ const flags = {}; - const pathToArgumentName = input => { - return input + /** + * @param {string} input input + * @returns {string} result + */ + const pathToArgumentName = input => + input .replace(/\./g, "-") .replace(/\[\]/g, "") .replace( @@ -69,8 +82,11 @@ const getArguments = (schema = webpackSchema) => { ) .replace(/-?[^\p{Uppercase_Letter}\p{Lowercase_Letter}\d]+/gu, "-") .toLowerCase(); - }; + /** + * @param {string} path path + * @returns {Schema} schema part + */ const getSchemaPart = path => { const newPath = path.split("/"); @@ -90,21 +106,48 @@ const getArguments = (schema = webpackSchema) => { }; /** - * * @param {PathItem[]} path path in the schema * @returns {string | undefined} description */ const getDescription = path => { for (const { schema } of path) { - if (schema.cli && schema.cli.helper) continue; + if (schema.cli) { + if (schema.cli.helper) continue; + if (schema.cli.description) return schema.cli.description; + } if (schema.description) return schema.description; } }; /** - * - * @param {any} schemaPart schema - * @returns {Pick} partial argument config + * @param {PathItem[]} path path in the schema + * @returns {string | undefined} negative description + */ + const getNegatedDescription = path => { + for (const { schema } of path) { + if (schema.cli) { + if (schema.cli.helper) continue; + if (schema.cli.negatedDescription) return schema.cli.negatedDescription; + } + } + }; + + /** + * @param {PathItem[]} path path in the schema + * @returns {string | undefined} reset description + */ + const getResetDescription = path => { + for (const { schema } of path) { + if (schema.cli) { + if (schema.cli.helper) continue; + if (schema.cli.resetDescription) return schema.cli.resetDescription; + } + } + }; + + /** + * @param {Schema} schemaPart schema + * @returns {Pick | undefined} partial argument config */ const schemaToArgumentConfig = schemaPart => { if (schemaPart.enum) { @@ -142,19 +185,25 @@ const getArguments = (schema = webpackSchema) => { const addResetFlag = path => { const schemaPath = path[0].path; const name = pathToArgumentName(`${schemaPath}.reset`); - const description = getDescription(path); + const description = + getResetDescription(path) || + `Clear all items provided in '${schemaPath}' configuration. ${getDescription( + path + )}`; flags[name] = { configs: [ { type: "reset", multiple: false, - description: `Clear all items provided in configuration. ${description}`, + description, path: schemaPath } ], description: undefined, - simpleType: undefined, - multiple: undefined + simpleType: + /** @type {SimpleType} */ + (/** @type {unknown} */ (undefined)), + multiple: /** @type {boolean} */ (/** @type {unknown} */ (undefined)) }; }; @@ -167,6 +216,7 @@ const getArguments = (schema = webpackSchema) => { const argConfigBase = schemaToArgumentConfig(path[0].schema); if (!argConfigBase) return 0; + const negatedDescription = getNegatedDescription(path); const name = pathToArgumentName(path[0].path); /** @type {ArgumentConfig} */ const argConfig = { @@ -176,12 +226,18 @@ const getArguments = (schema = webpackSchema) => { path: path[0].path }; + if (negatedDescription) { + argConfig.negatedDescription = negatedDescription; + } + if (!flags[name]) { flags[name] = { configs: [], description: undefined, - simpleType: undefined, - multiple: undefined + simpleType: + /** @type {SimpleType} */ + (/** @type {unknown} */ (undefined)), + multiple: /** @type {boolean} */ (/** @type {unknown} */ (undefined)) }; } @@ -214,8 +270,7 @@ const getArguments = (schema = webpackSchema) => { // TODO support `not` and `if/then/else` // TODO support `const`, but we don't use it on our schema /** - * - * @param {object} schemaPart the current schema + * @param {Schema} schemaPart the current schema * @param {string} schemaPath the current path in the schema * @param {{schema: object, path: string}[]} path all previous visited schemaParts * @param {string | null} inArray if inside of an array, the path to the array @@ -240,13 +295,14 @@ const getArguments = (schema = webpackSchema) => { let addedArguments = 0; - addedArguments += addFlag(fullPath, !!inArray); + addedArguments += addFlag(fullPath, Boolean(inArray)); if (schemaPart.type === "object") { if (schemaPart.properties) { for (const property of Object.keys(schemaPart.properties)) { addedArguments += traverse( - schemaPart.properties[property], + /** @type {Schema} */ + (schemaPart.properties[property]), schemaPath ? `${schemaPath}.${property}` : property, fullPath, inArray @@ -262,10 +318,11 @@ const getArguments = (schema = webpackSchema) => { return 0; } if (Array.isArray(schemaPart.items)) { - let i = 0; + const i = 0; for (const item of schemaPart.items) { addedArguments += traverse( - item, + /** @type {Schema} */ + (item), `${schemaPath}.${i}`, fullPath, schemaPath @@ -276,7 +333,8 @@ const getArguments = (schema = webpackSchema) => { } addedArguments += traverse( - schemaPart.items, + /** @type {Schema} */ + (schemaPart.items), `${schemaPath}[]`, fullPath, schemaPath @@ -296,7 +354,13 @@ const getArguments = (schema = webpackSchema) => { const items = maybeOf; for (let i = 0; i < items.length; i++) { - addedArguments += traverse(items[i], schemaPath, fullPath, inArray); + addedArguments += traverse( + /** @type {Schema} */ + (items[i]), + schemaPath, + fullPath, + inArray + ); } return addedArguments; @@ -309,6 +373,7 @@ const getArguments = (schema = webpackSchema) => { // Summarize flags for (const name of Object.keys(flags)) { + /** @type {Argument} */ const argument = flags[name]; argument.description = argument.configs.reduce((desc, { description }) => { if (!desc) return description; @@ -316,27 +381,34 @@ const getArguments = (schema = webpackSchema) => { if (desc.includes(description)) return desc; return `${desc} ${description}`; }, /** @type {string | undefined} */ (undefined)); - argument.simpleType = argument.configs.reduce((t, argConfig) => { - /** @type {"string" | "number" | "boolean"} */ - let type = "string"; - switch (argConfig.type) { - case "number": - type = "number"; - break; - case "reset": - case "boolean": - type = "boolean"; - break; - case "enum": - if (argConfig.values.every(v => typeof v === "boolean")) - type = "boolean"; - if (argConfig.values.every(v => typeof v === "number")) - type = "number"; - break; - } - if (t === undefined) return type; - return t === type ? t : "string"; - }, /** @type {"string" | "number" | "boolean" | undefined} */ (undefined)); + argument.simpleType = + /** @type {SimpleType} */ + ( + argument.configs.reduce((t, argConfig) => { + /** @type {SimpleType} */ + let type = "string"; + switch (argConfig.type) { + case "number": + type = "number"; + break; + case "reset": + case "boolean": + type = "boolean"; + break; + case "enum": { + const values = + /** @type {NonNullable} */ + (argConfig.values); + + if (values.every(v => typeof v === "boolean")) type = "boolean"; + if (values.every(v => typeof v === "number")) type = "number"; + break; + } + } + if (t === undefined) return type; + return t === type ? t : "string"; + }, /** @type {SimpleType | undefined} */ (undefined)) + ); argument.multiple = argument.configs.some(c => c.multiple); } @@ -345,16 +417,18 @@ const getArguments = (schema = webpackSchema) => { const cliAddedItems = new WeakMap(); +/** @typedef {string | number} Property */ + /** - * @param {any} config configuration + * @param {Configuration} config configuration * @param {string} schemaPath path in the config * @param {number | undefined} index index of value when multiple values are provided, otherwise undefined - * @returns {{ problem?: LocalProblem, object?: any, property?: string | number, value?: any }} problem or object with property and value + * @returns {{ problem?: LocalProblem, object?: any, property?: Property, value?: any }} problem or object with property and value */ const getObjectAndProperty = (config, schemaPath, index = 0) => { if (!schemaPath) return { value: config }; const parts = schemaPath.split("."); - let property = parts.pop(); + const property = /** @type {string} */ (parts.pop()); let current = config; let i = 0; for (const part of parts) { @@ -393,22 +467,20 @@ const getObjectAndProperty = (config, schemaPath, index = 0) => { } value = value[x]; } - } else { - if (value === undefined) { - value = current[name] = {}; - } else if (value === null || typeof value !== "object") { - return { - problem: { - type: "unexpected-non-object-in-path", - path: parts.slice(0, i).join(".") - } - }; - } + } else if (value === undefined) { + value = current[name] = {}; + } else if (value === null || typeof value !== "object") { + return { + problem: { + type: "unexpected-non-object-in-path", + path: parts.slice(0, i).join(".") + } + }; } current = value; i++; } - let value = current[property]; + const value = current[property]; if (property.endsWith("[]")) { const name = property.slice(0, -2); const value = current[name]; @@ -420,36 +492,35 @@ const getObjectAndProperty = (config, schemaPath, index = 0) => { current[name] = [value, ...Array.from({ length: index }), undefined]; cliAddedItems.set(current[name], index + 1); return { object: current[name], property: index + 1, value: undefined }; - } else { - let addedItems = cliAddedItems.get(value) || 0; - while (addedItems <= index) { - value.push(undefined); - addedItems++; - } - cliAddedItems.set(value, addedItems); - const x = value.length - addedItems + index; - if (value[x] === undefined) { - value[x] = {}; - } else if (value[x] === null || typeof value[x] !== "object") { - return { - problem: { - type: "unexpected-non-object-in-path", - path: schemaPath - } - }; - } + } + let addedItems = cliAddedItems.get(value) || 0; + while (addedItems <= index) { + value.push(undefined); + addedItems++; + } + cliAddedItems.set(value, addedItems); + const x = value.length - addedItems + index; + if (value[x] === undefined) { + value[x] = {}; + } else if (value[x] === null || typeof value[x] !== "object") { return { - object: value, - property: x, - value: value[x] + problem: { + type: "unexpected-non-object-in-path", + path: schemaPath + } }; } + return { + object: value, + property: x, + value: value[x] + }; } return { object: current, property, value }; }; /** - * @param {any} config configuration + * @param {Configuration} config configuration * @param {string} schemaPath path in the config * @param {any} value parsed value * @param {number | undefined} index index of value when multiple values are provided, otherwise undefined @@ -462,14 +533,14 @@ const setValue = (config, schemaPath, value, index) => { index ); if (problem) return problem; - object[property] = value; + object[/** @type {Property} */ (property)] = value; return null; }; /** * @param {ArgumentConfig} argConfig processing instructions - * @param {any} config configuration - * @param {any} value the value + * @param {Configuration} config configuration + * @param {Value} value the value * @param {number | undefined} index the index if multiple values provided * @returns {LocalProblem | null} a problem if any */ @@ -499,22 +570,26 @@ const processArgumentConfig = (argConfig, config, value, index) => { */ const getExpectedValue = argConfig => { switch (argConfig.type) { - default: - return argConfig.type; case "boolean": return "true | false"; case "RegExp": return "regular expression (example: /ab?c*/)"; case "enum": - return argConfig.values.map(v => `${v}`).join(" | "); + return /** @type {NonNullable} */ ( + argConfig.values + ) + .map(v => `${v}`) + .join(" | "); case "reset": return "true (will reset the previous value to an empty array)"; + default: + return argConfig.type; } }; /** * @param {ArgumentConfig} argConfig processing instructions - * @param {any} value the value + * @param {Value} value the value * @returns {any | undefined} parsed value */ const parseValueForArgumentConfig = (argConfig, value) => { @@ -532,8 +607,8 @@ const parseValueForArgumentConfig = (argConfig, value) => { case "number": if (typeof value === "number") return value; if (typeof value === "string" && /^[+-]?\d*(\.\d*)[eE]\d+$/) { - const n = +value; - if (!isNaN(n)) return n; + const n = Number(value); + if (!Number.isNaN(n)) return n; } break; case "boolean": @@ -550,22 +625,28 @@ const parseValueForArgumentConfig = (argConfig, value) => { return new RegExp(match[1], match[2]); } break; - case "enum": - if (argConfig.values.includes(value)) return value; - for (const item of argConfig.values) { + case "enum": { + const values = + /** @type {NonNullable} */ + (argConfig.values); + if (values.includes(value)) return value; + for (const item of values) { if (`${item}` === value) return item; } break; + } case "reset": if (value === true) return []; break; } }; +/** @typedef {any} Configuration */ + /** - * @param {Record} args object of arguments - * @param {any} config configuration - * @param {Record} values object with values + * @param {Flags} args object of arguments + * @param {Configuration} config configuration + * @param {Record} values object with values * @returns {Problem[] | null} problems or null for success */ const processArguments = (args, config, values) => { @@ -581,6 +662,10 @@ const processArguments = (args, config, values) => { }); continue; } + /** + * @param {Value} value value + * @param {number | undefined} i index + */ const processValue = (value, i) => { const currentProblems = []; for (const argConfig of arg.configs) { @@ -591,13 +676,13 @@ const processArguments = (args, config, values) => { currentProblems.push({ ...problem, argument: key, - value: value, + value, index: i }); } problems.push(...currentProblems); }; - let value = values[key]; + const value = values[key]; if (Array.isArray(value)) { for (let i = 0; i < value.length; i++) { processValue(value[i], i); @@ -610,5 +695,5 @@ const processArguments = (args, config, values) => { return problems; }; -exports.getArguments = getArguments; -exports.processArguments = processArguments; +module.exports.getArguments = getArguments; +module.exports.processArguments = processArguments; diff --git a/lib/config/browserslistTargetHandler.js b/lib/config/browserslistTargetHandler.js index 09368b052be..51b0896ab0c 100644 --- a/lib/config/browserslistTargetHandler.js +++ b/lib/config/browserslistTargetHandler.js @@ -16,14 +16,14 @@ const path = require("path"); const inputRx = /^(?:((?:[A-Z]:)?[/\\].*?))?(?::(.+?))?$/i; /** - * @typedef {Object} BrowserslistHandlerConfig + * @typedef {object} BrowserslistHandlerConfig * @property {string=} configPath * @property {string=} env * @property {string=} query */ /** - * @param {string} input input string + * @param {string | null | undefined} input input string * @param {string} context the context directory * @returns {BrowserslistHandlerConfig} config */ @@ -47,7 +47,7 @@ const parse = (input, context) => { }; /** - * @param {string} input input string + * @param {string | null | undefined} input input string * @param {string} context the context directory * @returns {string[] | undefined} selected browsers */ @@ -57,16 +57,16 @@ const load = (input, context) => { // if a query is specified, then use it, else // if a path to a config is specified then load it, else // find a nearest config - const config = query - ? query - : configPath - ? browserslist.loadConfig({ - config: configPath, - env - }) - : browserslist.loadConfig({ path: context, env }); + const config = + query || + (configPath + ? browserslist.loadConfig({ + config: configPath, + env + }) + : browserslist.loadConfig({ path: context, env })); - if (!config) return null; + if (!config) return; return browserslist(config); }; @@ -80,8 +80,8 @@ const resolve = browsers => { * @param {Record} versions first supported version * @returns {boolean} true if supports */ - const rawChecker = versions => { - return browsers.every(v => { + const rawChecker = versions => + browsers.every(v => { const [name, parsedVersion] = v.split(" "); if (!name) return false; const requiredVersion = versions[name]; @@ -90,21 +90,23 @@ const resolve = browsers => { // safari TP supports all features for normal safari parsedVersion === "TP" ? [Infinity, Infinity] - : parsedVersion.split("."); + : parsedVersion.includes("-") + ? parsedVersion.split("-")[0].split(".") + : parsedVersion.split("."); if (typeof requiredVersion === "number") { - return +parsedMajor >= requiredVersion; + return Number(parsedMajor) >= requiredVersion; } - return requiredVersion[0] === +parsedMajor - ? +parserMinor >= requiredVersion[1] - : +parsedMajor > requiredVersion[0]; + return requiredVersion[0] === Number(parsedMajor) + ? Number(parserMinor) >= requiredVersion[1] + : Number(parsedMajor) > requiredVersion[0]; }); - }; - const anyNode = browsers.some(b => /^node /.test(b)); + const anyNode = browsers.some(b => b.startsWith("node ")); const anyBrowser = browsers.some(b => /^(?!node)/.test(b)); const browserProperty = !anyBrowser ? false : anyNode ? null : true; const nodeProperty = !anyNode ? false : anyBrowser ? null : true; // Internet Explorer Mobile, Blackberry browser and Opera Mini are very old browsers, they do not support new features const es6DynamicImport = rawChecker({ + /* eslint-disable camelcase */ chrome: 63, and_chr: 63, edge: 79, @@ -118,14 +120,15 @@ const resolve = browsers => { samsung: [8, 2], android: 63, and_qq: [10, 4], - // baidu: Not supported - // and_uc: Not supported - // kaios: Not supported - // Since Node.js 13.14.0 no warning about usage, but it was added 8.5.0 with some limitations and it was improved in 12.0.0 and 13.2.0 - node: [13, 14] + baidu: [13, 18], + and_uc: [15, 5], + kaios: [3, 0], + node: [12, 17] + /* eslint-enable camelcase */ }); return { + /* eslint-disable camelcase */ const: rawChecker({ chrome: 49, and_chr: 49, @@ -145,7 +148,7 @@ const resolve = browsers => { android: 37, and_qq: [10, 4], // Supported correctly in strict mode, otherwise supported without block scope - // baidu: Not supported + baidu: [13, 18], and_uc: [12, 12], kaios: [2, 5], node: [6, 0] @@ -188,7 +191,7 @@ const resolve = browsers => { // and_qq: Unknown support // baidu: Unknown support // and_uc: Unknown support - // kaios: Unknown support + kaios: [3, 0], node: [0, 12] }), destructuring: rawChecker({ @@ -207,7 +210,7 @@ const resolve = browsers => { // and_qq: Unknown support // baidu: Unknown support // and_uc: Unknown support - // kaios: Unknown support + kaios: [2, 5], node: [6, 0] }), bigIntLiteral: rawChecker({ @@ -223,10 +226,10 @@ const resolve = browsers => { ios_saf: 14, samsung: [9, 2], android: 67, - // and_qq: Not supported - // baidu: Not supported - // and_uc: Not supported - // kaios: Not supported + and_qq: [13, 1], + baidu: [13, 18], + and_uc: [15, 5], + kaios: [3, 0], node: [10, 4] }), // Support syntax `import` and `export` and no limitations and bugs on Node.js @@ -245,11 +248,10 @@ const resolve = browsers => { samsung: [8, 0], android: 61, and_qq: [10, 4], - // baidu: Not supported - // and_uc: Not supported - // kaios: Not supported - // Since Node.js 13.14.0 no warning about usage, but it was added 8.5.0 with some limitations and it was improved in 12.0.0 and 13.2.0 - node: [13, 14] + baidu: [13, 18], + and_uc: [15, 5], + kaios: [3, 0], + node: [12, 17] }), dynamicImport: es6DynamicImport, dynamicImportInWorker: es6DynamicImport && !anyNode, @@ -271,10 +273,67 @@ const resolve = browsers => { // and_qq: Unknown support // baidu: Unknown support // and_uc: Unknown support - // kaios: Unknown support - node: [12, 0] + kaios: [3, 0], + node: 12 }), - + optionalChaining: rawChecker({ + chrome: 80, + and_chr: 80, + edge: 80, + firefox: 74, + and_ff: 79, + // ie: Not supported, + opera: 67, + op_mob: 64, + safari: [13, 1], + ios_saf: [13, 4], + samsung: 13, + android: 80, + // and_qq: Not supported + // baidu: Not supported + // and_uc: Not supported + kaios: [3, 0], + node: 14 + }), + templateLiteral: rawChecker({ + chrome: 41, + and_chr: 41, + edge: 13, + firefox: 34, + and_ff: 34, + // ie: Not supported, + opera: 29, + op_mob: 64, + safari: [9, 1], + ios_saf: 9, + samsung: 4, + android: 41, + and_qq: [10, 4], + baidu: [7, 12], + and_uc: [12, 12], + kaios: [2, 5], + node: 4 + }), + asyncFunction: rawChecker({ + chrome: 55, + and_chr: 55, + edge: 15, + firefox: 52, + and_ff: 52, + // ie: Not supported, + opera: 42, + op_mob: 42, + safari: 11, + ios_saf: 11, + samsung: [6, 2], + android: 55, + and_qq: [13, 1], + baidu: [13, 18], + and_uc: [15, 5], + kaios: 3, + node: [7, 6] + }), + /* eslint-enable camelcase */ browser: browserProperty, electron: false, node: nodeProperty, @@ -288,6 +347,12 @@ const resolve = browsers => { importScripts: false, importScriptsInWorker: true, nodeBuiltins: nodeProperty, + nodePrefixForCoreModules: + nodeProperty && + !browsers.some(b => b.startsWith("node 15")) && + rawChecker({ + node: [14, 18] + }), require: nodeProperty }; }; diff --git a/lib/config/defaults.js b/lib/config/defaults.js index 672a97939fb..f3e21a5d3fe 100644 --- a/lib/config/defaults.js +++ b/lib/config/defaults.js @@ -7,6 +7,18 @@ const fs = require("fs"); const path = require("path"); +const { + JAVASCRIPT_MODULE_TYPE_AUTO, + JSON_MODULE_TYPE, + WEBASSEMBLY_MODULE_TYPE_ASYNC, + JAVASCRIPT_MODULE_TYPE_ESM, + JAVASCRIPT_MODULE_TYPE_DYNAMIC, + WEBASSEMBLY_MODULE_TYPE_SYNC, + ASSET_MODULE_TYPE, + CSS_MODULE_TYPE_AUTO, + CSS_MODULE_TYPE, + CSS_MODULE_TYPE_MODULE +} = require("../ModuleTypeConstants"); const Template = require("../Template"); const { cleverMerge } = require("../util/cleverMerge"); const { @@ -15,32 +27,54 @@ const { getDefaultTarget } = require("./target"); -/** @typedef {import("../../declarations/WebpackOptions").CacheOptionsNormalized} CacheOptions */ +/** @typedef {import("../../declarations/WebpackOptions").CacheOptions} CacheOptions */ +/** @typedef {import("../../declarations/WebpackOptions").CacheOptionsNormalized} CacheOptionsNormalized */ +/** @typedef {import("../../declarations/WebpackOptions").Context} Context */ +/** @typedef {import("../../declarations/WebpackOptions").CssGeneratorOptions} CssGeneratorOptions */ +/** @typedef {import("../../declarations/WebpackOptions").CssParserOptions} CssParserOptions */ /** @typedef {import("../../declarations/WebpackOptions").EntryDescription} EntryDescription */ /** @typedef {import("../../declarations/WebpackOptions").EntryNormalized} Entry */ +/** @typedef {import("../../declarations/WebpackOptions").EntryStaticNormalized} EntryStaticNormalized */ +/** @typedef {import("../../declarations/WebpackOptions").Environment} Environment */ /** @typedef {import("../../declarations/WebpackOptions").Experiments} Experiments */ +/** @typedef {import("../../declarations/WebpackOptions").ExperimentsNormalized} ExperimentsNormalized */ /** @typedef {import("../../declarations/WebpackOptions").ExternalsPresets} ExternalsPresets */ /** @typedef {import("../../declarations/WebpackOptions").ExternalsType} ExternalsType */ +/** @typedef {import("../../declarations/WebpackOptions").FileCacheOptions} FileCacheOptions */ +/** @typedef {import("../../declarations/WebpackOptions").GeneratorOptionsByModuleTypeKnown} GeneratorOptionsByModuleTypeKnown */ /** @typedef {import("../../declarations/WebpackOptions").InfrastructureLogging} InfrastructureLogging */ /** @typedef {import("../../declarations/WebpackOptions").JavascriptParserOptions} JavascriptParserOptions */ /** @typedef {import("../../declarations/WebpackOptions").Library} Library */ /** @typedef {import("../../declarations/WebpackOptions").LibraryName} LibraryName */ /** @typedef {import("../../declarations/WebpackOptions").LibraryOptions} LibraryOptions */ +/** @typedef {import("../../declarations/WebpackOptions").LibraryType} LibraryType */ /** @typedef {import("../../declarations/WebpackOptions").Loader} Loader */ /** @typedef {import("../../declarations/WebpackOptions").Mode} Mode */ /** @typedef {import("../../declarations/WebpackOptions").ModuleOptionsNormalized} ModuleOptions */ /** @typedef {import("../../declarations/WebpackOptions").Node} WebpackNode */ /** @typedef {import("../../declarations/WebpackOptions").Optimization} Optimization */ +/** @typedef {import("../../declarations/WebpackOptions").OptimizationSplitChunksOptions} OptimizationSplitChunksOptions */ /** @typedef {import("../../declarations/WebpackOptions").OutputNormalized} Output */ +/** @typedef {import("../../declarations/WebpackOptions").ParserOptionsByModuleTypeKnown} ParserOptionsByModuleTypeKnown */ /** @typedef {import("../../declarations/WebpackOptions").Performance} Performance */ /** @typedef {import("../../declarations/WebpackOptions").ResolveOptions} ResolveOptions */ /** @typedef {import("../../declarations/WebpackOptions").RuleSetRules} RuleSetRules */ /** @typedef {import("../../declarations/WebpackOptions").SnapshotOptions} SnapshotOptions */ /** @typedef {import("../../declarations/WebpackOptions").Target} Target */ -/** @typedef {import("../../declarations/WebpackOptions").WebpackOptionsNormalized} WebpackOptions */ +/** @typedef {import("../../declarations/WebpackOptions").WebpackOptions} WebpackOptions */ +/** @typedef {import("../../declarations/WebpackOptions").WebpackOptionsNormalized} WebpackOptionsNormalized */ +/** @typedef {import("../Compiler")} Compiler */ +/** @typedef {import("../Module")} Module */ +/** @typedef {import("./target").PlatformTargetProperties} PlatformTargetProperties */ /** @typedef {import("./target").TargetProperties} TargetProperties */ +/** + * @typedef {object} ResolvedOptions + * @property {PlatformTargetProperties | false} platform - platform target properties + */ + const NODE_MODULES_REGEXP = /[\\/]node_modules[\\/]/i; +const DEFAULT_CACHE_NAME = "default"; /** * Sets a constant default value when undefined @@ -89,8 +123,8 @@ const A = (obj, prop, factory) => { if (value === undefined) { obj[prop] = factory(); } else if (Array.isArray(value)) { - /** @type {any[]} */ - let newArray = undefined; + /** @type {any[] | undefined} */ + let newArray; for (let i = 0; i < value.length; i++) { const item = value[i]; if (item === "...") { @@ -112,31 +146,36 @@ const A = (obj, prop, factory) => { }; /** - * @param {WebpackOptions} options options to be modified + * @param {WebpackOptionsNormalized} options options to be modified * @returns {void} */ const applyWebpackOptionsBaseDefaults = options => { F(options, "context", () => process.cwd()); + applyInfrastructureLoggingDefaults(options.infrastructureLogging); }; /** - * @param {WebpackOptions} options options to be modified - * @returns {void} + * @param {WebpackOptionsNormalized} options options to be modified + * @param {number} [compilerIndex] index of compiler + * @returns {ResolvedOptions} Resolved options after apply defaults */ -const applyWebpackOptionsDefaults = options => { +const applyWebpackOptionsDefaults = (options, compilerIndex) => { F(options, "context", () => process.cwd()); - F(options, "target", () => { - return getDefaultTarget(options.context); - }); + F(options, "target", () => + getDefaultTarget(/** @type {string} */ (options.context)) + ); const { mode, name, target } = options; - let targetProperties = + const targetProperties = target === false ? /** @type {false} */ (false) : typeof target === "string" - ? getTargetProperties(target, options.context) - : getTargetsProperties(target, options.context); + ? getTargetProperties(target, /** @type {Context} */ (options.context)) + : getTargetsProperties( + /** @type {string[]} */ (target), + /** @type {Context} */ (options.context) + ); const development = mode === "development"; const production = mode === "production" || !mode; @@ -158,37 +197,76 @@ const applyWebpackOptionsDefaults = options => { D(options, "recordsInputPath", false); D(options, "recordsOutputPath", false); + applyExperimentsDefaults(options.experiments, { + production, + development, + targetProperties + }); + + const futureDefaults = + /** @type {NonNullable} */ + (options.experiments.futureDefaults); + F(options, "cache", () => development ? { type: /** @type {"memory"} */ ("memory") } : false ); applyCacheDefaults(options.cache, { - name: name || "default", - mode: mode || "production" + name: name || DEFAULT_CACHE_NAME, + mode: mode || "production", + development, + cacheUnaffected: options.experiments.cacheUnaffected, + compilerIndex }); - const cache = !!options.cache; - - applySnapshotDefaults(options.snapshot, { production }); + const cache = Boolean(options.cache); - applyExperimentsDefaults(options.experiments); + applySnapshotDefaults(options.snapshot, { + production, + futureDefaults + }); applyModuleDefaults(options.module, { cache, - syncWebAssembly: options.experiments.syncWebAssembly, - asyncWebAssembly: options.experiments.asyncWebAssembly + syncWebAssembly: + /** @type {NonNullable} */ + (options.experiments.syncWebAssembly), + asyncWebAssembly: + /** @type {NonNullable} */ + (options.experiments.asyncWebAssembly), + css: + /** @type {NonNullable} */ + (options.experiments.css), + futureDefaults, + isNode: targetProperties && targetProperties.node === true, + targetProperties }); applyOutputDefaults(options.output, { - context: options.context, + context: /** @type {Context} */ (options.context), targetProperties, - outputModule: options.experiments.outputModule, + isAffectedByBrowserslist: + target === undefined || + (typeof target === "string" && target.startsWith("browserslist")) || + (Array.isArray(target) && + target.some(target => target.startsWith("browserslist"))), + outputModule: + /** @type {NonNullable} */ + (options.experiments.outputModule), development, entry: options.entry, - module: options.module + futureDefaults }); - applyExternalsPresetsDefaults(options.externalsPresets, { targetProperties }); + applyExternalsPresetsDefaults(options.externalsPresets, { + targetProperties, + buildHttp: Boolean(options.experiments.buildHttp) + }); - applyLoaderDefaults(options.loader, { targetProperties }); + applyLoaderDefaults( + /** @type {NonNullable} */ ( + options.loader + ), + { targetProperties, environment: options.output.environment } + ); F(options, "externalsType", () => { const validExternalTypes = require("../../schemas/WebpackOptions.json") @@ -197,11 +275,17 @@ const applyWebpackOptionsDefaults = options => { validExternalTypes.includes(options.output.library.type) ? /** @type {ExternalsType} */ (options.output.library.type) : options.output.module - ? "module" - : "var"; + ? "module-import" + : "var"; }); - applyNodeDefaults(options.node, { targetProperties }); + applyNodeDefaults(options.node, { + futureDefaults: + /** @type {NonNullable} */ + (options.experiments.futureDefaults), + outputModule: options.output.module, + targetProperties + }); F(options, "performance", () => production && @@ -210,22 +294,32 @@ const applyWebpackOptionsDefaults = options => { ? {} : false ); - applyPerformanceDefaults(options.performance, { - production - }); + applyPerformanceDefaults( + /** @type {NonNullable} */ + (options.performance), + { + production + } + ); applyOptimizationDefaults(options.optimization, { development, production, - records: !!(options.recordsInputPath || options.recordsOutputPath) + css: + /** @type {NonNullable} */ + (options.experiments.css), + records: Boolean(options.recordsInputPath || options.recordsOutputPath) }); options.resolve = cleverMerge( getResolveDefaults({ cache, - context: options.context, + context: /** @type {Context} */ (options.context), targetProperties, - mode: options.mode + mode: /** @type {Mode} */ (options.mode), + css: + /** @type {NonNullable} */ + (options.experiments.css) }), options.resolve ); @@ -235,41 +329,89 @@ const applyWebpackOptionsDefaults = options => { options.resolveLoader ); - applyInfrastructureLoggingDefaults(options.infrastructureLogging); + return { + platform: + targetProperties === false + ? targetProperties + : { + web: targetProperties.web, + browser: targetProperties.browser, + webworker: targetProperties.webworker, + node: targetProperties.node, + nwjs: targetProperties.nwjs, + electron: targetProperties.electron + } + }; }; /** - * @param {Experiments} experiments options + * @param {ExperimentsNormalized} experiments options + * @param {object} options options + * @param {boolean} options.production is production + * @param {boolean} options.development is development mode + * @param {TargetProperties | false} options.targetProperties target properties * @returns {void} */ -const applyExperimentsDefaults = experiments => { - D(experiments, "topLevelAwait", false); +const applyExperimentsDefaults = ( + experiments, + { production, development, targetProperties } +) => { + D(experiments, "futureDefaults", false); + D(experiments, "backCompat", !experiments.futureDefaults); D(experiments, "syncWebAssembly", false); - D(experiments, "asyncWebAssembly", false); + D(experiments, "asyncWebAssembly", experiments.futureDefaults); D(experiments, "outputModule", false); + D(experiments, "layers", false); + D(experiments, "lazyCompilation", undefined); + D(experiments, "buildHttp", undefined); + D(experiments, "cacheUnaffected", experiments.futureDefaults); + F(experiments, "css", () => (experiments.futureDefaults ? true : undefined)); + + // TODO webpack 6: remove this. topLevelAwait should be enabled by default + let shouldEnableTopLevelAwait = true; + if (typeof experiments.topLevelAwait === "boolean") { + shouldEnableTopLevelAwait = experiments.topLevelAwait; + } + D(experiments, "topLevelAwait", shouldEnableTopLevelAwait); + + if (typeof experiments.buildHttp === "object") { + D(experiments.buildHttp, "frozen", production); + D(experiments.buildHttp, "upgrade", false); + } }; /** - * @param {CacheOptions} cache options - * @param {Object} options options + * @param {CacheOptionsNormalized} cache options + * @param {object} options options * @param {string} options.name name - * @param {string} options.mode mode + * @param {Mode} options.mode mode + * @param {boolean} options.development is development mode + * @param {number} [options.compilerIndex] index of compiler + * @param {Experiments["cacheUnaffected"]} options.cacheUnaffected the cacheUnaffected experiment is enabled * @returns {void} */ -const applyCacheDefaults = (cache, { name, mode }) => { +const applyCacheDefaults = ( + cache, + { name, mode, development, cacheUnaffected, compilerIndex } +) => { if (cache === false) return; switch (cache.type) { case "filesystem": - F(cache, "name", () => name + "-" + mode); + F(cache, "name", () => + compilerIndex !== undefined + ? `${`${name}-${mode}`}__compiler${compilerIndex + 1}__` + : `${name}-${mode}` + ); D(cache, "version", ""); F(cache, "cacheDirectory", () => { const cwd = process.cwd(); + /** @type {string | undefined} */ let dir = cwd; for (;;) { try { if (fs.statSync(path.join(dir, "package.json")).isFile()) break; // eslint-disable-next-line no-empty - } catch (e) {} + } catch (_err) {} const parent = path.dirname(dir); if (dir === parent) { dir = undefined; @@ -283,68 +425,105 @@ const applyCacheDefaults = (cache, { name, mode }) => { return path.resolve(dir, ".pnp/.cache/webpack"); } else if (process.versions.pnp === "3") { return path.resolve(dir, ".yarn/.cache/webpack"); - } else { - return path.resolve(dir, "node_modules/.cache/webpack"); } + return path.resolve(dir, "node_modules/.cache/webpack"); }); F(cache, "cacheLocation", () => - path.resolve(cache.cacheDirectory, cache.name) + path.resolve( + /** @type {NonNullable} */ + (cache.cacheDirectory), + /** @type {NonNullable} */ (cache.name) + ) ); D(cache, "hashAlgorithm", "md4"); D(cache, "store", "pack"); + D(cache, "compression", false); + D(cache, "profile", false); D(cache, "idleTimeout", 60000); - D(cache, "idleTimeoutForInitialStore", 0); - D(cache.buildDependencies, "defaultWebpack", [ - path.resolve(__dirname, "..") + path.sep - ]); + D(cache, "idleTimeoutForInitialStore", 5000); + D(cache, "idleTimeoutAfterLargeChanges", 1000); + D(cache, "maxMemoryGenerations", development ? 5 : Infinity); + D(cache, "maxAge", 1000 * 60 * 60 * 24 * 60); // 1 month + D(cache, "allowCollectingMemory", development); + D(cache, "memoryCacheUnaffected", development && cacheUnaffected); + D(cache, "readonly", false); + D( + /** @type {NonNullable} */ + (cache.buildDependencies), + "defaultWebpack", + [path.resolve(__dirname, "..") + path.sep] + ); + break; + case "memory": + D(cache, "maxGenerations", Infinity); + D(cache, "cacheUnaffected", development && cacheUnaffected); break; } }; /** * @param {SnapshotOptions} snapshot options - * @param {Object} options options + * @param {object} options options * @param {boolean} options.production is production + * @param {boolean} options.futureDefaults is future defaults enabled * @returns {void} */ -const applySnapshotDefaults = (snapshot, { production }) => { - A(snapshot, "managedPaths", () => { - if (process.versions.pnp === "3") { - const match = /^(.+?)[\\/]cache[\\/]watchpack-npm-[^\\/]+\.zip[\\/]node_modules[\\/]/.exec( - require.resolve("watchpack") - ); - if (match) { - return [path.resolve(match[1], "unplugged")]; - } - } else { - const match = /^(.+?[\\/]node_modules)[\\/]/.exec( - // eslint-disable-next-line node/no-extraneous-require - require.resolve("watchpack") - ); - if (match) { - return [match[1]]; - } - } - return []; - }); - A(snapshot, "immutablePaths", () => { - if (process.versions.pnp === "1") { - const match = /^(.+?[\\/]v4)[\\/]npm-watchpack-[^\\/]+-[\da-f]{40}[\\/]node_modules[\\/]/.exec( - require.resolve("watchpack") - ); - if (match) { - return [match[1]]; +const applySnapshotDefaults = (snapshot, { production, futureDefaults }) => { + if (futureDefaults) { + F(snapshot, "managedPaths", () => + process.versions.pnp === "3" + ? [ + /^(.+?(?:[\\/]\.yarn[\\/]unplugged[\\/][^\\/]+)?[\\/]node_modules[\\/])/ + ] + : [/^(.+?[\\/]node_modules[\\/])/] + ); + F(snapshot, "immutablePaths", () => + process.versions.pnp === "3" + ? [/^(.+?[\\/]cache[\\/][^\\/]+\.zip[\\/]node_modules[\\/])/] + : [] + ); + } else { + A(snapshot, "managedPaths", () => { + if (process.versions.pnp === "3") { + const match = + /^(.+?)[\\/]cache[\\/]watchpack-npm-[^\\/]+\.zip[\\/]node_modules[\\/]/.exec( + require.resolve("watchpack") + ); + if (match) { + return [path.resolve(match[1], "unplugged")]; + } + } else { + const match = /^(.+?[\\/]node_modules[\\/])/.exec( + require.resolve("watchpack") + ); + if (match) { + return [match[1]]; + } } - } else if (process.versions.pnp === "3") { - const match = /^(.+?)[\\/]watchpack-npm-[^\\/]+\.zip[\\/]node_modules[\\/]/.exec( - require.resolve("watchpack") - ); - if (match) { - return [match[1]]; + return []; + }); + A(snapshot, "immutablePaths", () => { + if (process.versions.pnp === "1") { + const match = + /^(.+?[\\/]v4)[\\/]npm-watchpack-[^\\/]+-[\da-f]{40}[\\/]node_modules[\\/]/.exec( + require.resolve("watchpack") + ); + if (match) { + return [match[1]]; + } + } else if (process.versions.pnp === "3") { + const match = + /^(.+?)[\\/]watchpack-npm-[^\\/]+\.zip[\\/]node_modules[\\/]/.exec( + require.resolve("watchpack") + ); + if (match) { + return [match[1]]; + } } - } - return []; - }); + return []; + }); + } + F(snapshot, "unmanagedPaths", () => []); F(snapshot, "resolveBuildDependencies", () => ({ timestamp: true, hash: true @@ -360,9 +539,15 @@ const applySnapshotDefaults = (snapshot, { production }) => { /** * @param {JavascriptParserOptions} parserOptions parser options + * @param {object} options options + * @param {boolean} options.futureDefaults is future defaults enabled + * @param {boolean} options.isNode is node target platform * @returns {void} */ -const applyJavascriptParserOptionsDefaults = parserOptions => { +const applyJavascriptParserOptionsDefaults = ( + parserOptions, + { futureDefaults, isNode } +) => { D(parserOptions, "unknownContextRequest", "."); D(parserOptions, "unknownContextRegExp", false); D(parserOptions, "unknownContextRecursive", true); @@ -374,44 +559,148 @@ const applyJavascriptParserOptionsDefaults = parserOptions => { D(parserOptions, "wrappedContextRegExp", /.*/); D(parserOptions, "wrappedContextRecursive", true); D(parserOptions, "wrappedContextCritical", false); - - D(parserOptions, "strictExportPresence", false); D(parserOptions, "strictThisContextOnImports", false); + D(parserOptions, "importMeta", true); + D(parserOptions, "dynamicImportMode", "lazy"); + D(parserOptions, "dynamicImportPrefetch", false); + D(parserOptions, "dynamicImportPreload", false); + D(parserOptions, "dynamicImportFetchPriority", false); + D(parserOptions, "createRequire", isNode); + if (futureDefaults) D(parserOptions, "exportsPresence", "error"); +}; + +/** + * @param {CssGeneratorOptions} generatorOptions generator options + * @param {object} options options + * @param {TargetProperties | false} options.targetProperties target properties + * @returns {void} + */ +const applyCssGeneratorOptionsDefaults = ( + generatorOptions, + { targetProperties } +) => { + D( + generatorOptions, + "exportsOnly", + !targetProperties || !targetProperties.document + ); + D(generatorOptions, "esModule", true); }; /** * @param {ModuleOptions} module options - * @param {Object} options options + * @param {object} options options * @param {boolean} options.cache is caching enabled * @param {boolean} options.syncWebAssembly is syncWebAssembly enabled * @param {boolean} options.asyncWebAssembly is asyncWebAssembly enabled + * @param {boolean} options.css is css enabled + * @param {boolean} options.futureDefaults is future defaults enabled + * @param {boolean} options.isNode is node target platform + * @param {TargetProperties | false} options.targetProperties target properties * @returns {void} */ const applyModuleDefaults = ( module, - { cache, syncWebAssembly, asyncWebAssembly } + { + cache, + syncWebAssembly, + asyncWebAssembly, + css, + futureDefaults, + isNode, + targetProperties + } ) => { if (cache) { - D(module, "unsafeCache", module => { - const name = module.nameForCondition(); - return name && NODE_MODULES_REGEXP.test(name); - }); + D( + module, + "unsafeCache", + /** + * @param {Module} module module + * @returns {boolean | null | string} true, if we want to cache the module + */ + module => { + const name = module.nameForCondition(); + return name && NODE_MODULES_REGEXP.test(name); + } + ); } else { D(module, "unsafeCache", false); } - F(module.parser, "asset", () => ({})); - F(module.parser.asset, "dataUrlCondition", () => ({})); - if (typeof module.parser.asset.dataUrlCondition === "object") { - D(module.parser.asset.dataUrlCondition, "maxSize", 8096); + F(module.parser, ASSET_MODULE_TYPE, () => ({})); + F( + /** @type {NonNullable} */ + (module.parser.asset), + "dataUrlCondition", + () => ({}) + ); + if ( + typeof ( + /** @type {NonNullable} */ + (module.parser.asset).dataUrlCondition + ) === "object" + ) { + D( + /** @type {NonNullable} */ + (module.parser.asset).dataUrlCondition, + "maxSize", + 8096 + ); } F(module.parser, "javascript", () => ({})); - applyJavascriptParserOptionsDefaults(module.parser.javascript); + + applyJavascriptParserOptionsDefaults( + /** @type {NonNullable} */ + (module.parser.javascript), + { + futureDefaults, + isNode + } + ); + + if (css) { + F(module.parser, "css", () => ({})); + + D(module.parser.css, "namedExports", true); + + F(module.generator, "css", () => ({})); + + applyCssGeneratorOptionsDefaults( + /** @type {NonNullable} */ + (module.generator.css), + { targetProperties } + ); + + F(module.generator, "css/auto", () => ({})); + D( + module.generator["css/auto"], + "localIdentName", + "[uniqueName]-[id]-[local]" + ); + D(module.generator["css/auto"], "exportsConvention", "as-is"); + + F(module.generator, "css/module", () => ({})); + D( + module.generator["css/module"], + "localIdentName", + "[uniqueName]-[id]-[local]" + ); + D(module.generator["css/module"], "exportsConvention", "as-is"); + + F(module.generator, "css/global", () => ({})); + D( + module.generator["css/global"], + "localIdentName", + "[uniqueName]-[id]-[local]" + ); + D(module.generator["css/global"], "exportsConvention", "as-is"); + } A(module, "defaultRules", () => { const esm = { - type: "javascript/esm", + type: JAVASCRIPT_MODULE_TYPE_ESM, resolve: { byDependency: { esm: { @@ -421,24 +710,21 @@ const applyModuleDefaults = ( } }; const commonjs = { - type: "javascript/dynamic" + type: JAVASCRIPT_MODULE_TYPE_DYNAMIC }; /** @type {RuleSetRules} */ const rules = [ - { - type: "javascript/auto" - }, { mimetype: "application/node", - type: "javascript/auto" + type: JAVASCRIPT_MODULE_TYPE_AUTO }, { test: /\.json$/i, - type: "json" + type: JSON_MODULE_TYPE }, { mimetype: "application/json", - type: "json" + type: JSON_MODULE_TYPE }, { test: /\.mjs$/i, @@ -467,15 +753,11 @@ const applyModuleDefaults = ( or: ["text/javascript", "application/javascript"] }, ...esm - }, - { - dependency: "url", - type: "asset/resource" } ]; if (asyncWebAssembly) { const wasm = { - type: "webassembly/async", + type: WEBASSEMBLY_MODULE_TYPE_ASYNC, rules: [ { descriptionData: { @@ -497,7 +779,7 @@ const applyModuleDefaults = ( }); } else if (syncWebAssembly) { const wasm = { - type: "webassembly/sync", + type: WEBASSEMBLY_MODULE_TYPE_SYNC, rules: [ { descriptionData: { @@ -518,24 +800,76 @@ const applyModuleDefaults = ( ...wasm }); } + if (css) { + const resolve = { + fullySpecified: true, + preferRelative: true + }; + rules.push({ + test: /\.css$/i, + type: CSS_MODULE_TYPE_AUTO, + resolve + }); + rules.push({ + mimetype: "text/css+module", + type: CSS_MODULE_TYPE_MODULE, + resolve + }); + rules.push({ + mimetype: "text/css", + type: CSS_MODULE_TYPE, + resolve + }); + } + rules.push( + { + dependency: "url", + oneOf: [ + { + scheme: /^data$/, + type: "asset/inline" + }, + { + type: "asset/resource" + } + ] + }, + { + assert: { type: "json" }, + type: JSON_MODULE_TYPE + }, + { + with: { type: "json" }, + type: JSON_MODULE_TYPE + } + ); return rules; }); }; /** * @param {Output} output options - * @param {Object} options options + * @param {object} options options * @param {string} options.context context * @param {TargetProperties | false} options.targetProperties target properties + * @param {boolean} options.isAffectedByBrowserslist is affected by browserslist * @param {boolean} options.outputModule is outputModule experiment enabled * @param {boolean} options.development is development mode * @param {Entry} options.entry entry option - * @param {ModuleOptions} options.module module option + * @param {boolean} options.futureDefaults is future defaults enabled * @returns {void} */ const applyOutputDefaults = ( output, - { context, targetProperties: tp, outputModule, development, entry, module } + { + context, + targetProperties: tp, + isAffectedByBrowserslist, + outputModule, + development, + entry, + futureDefaults + } ) => { /** * @param {Library=} library the library option @@ -548,7 +882,7 @@ const applyOutputDefaults = ( !Array.isArray(library) && "type" in library ? library.name - : /** @type {LibraryName=} */ (library); + : /** @type {LibraryName} */ (library); if (Array.isArray(libraryName)) { return libraryName.join("."); } else if (typeof libraryName === "object") { @@ -560,28 +894,40 @@ const applyOutputDefaults = ( }; F(output, "uniqueName", () => { - const libraryName = getLibraryName(output.library); + const libraryName = getLibraryName(output.library).replace( + /^\[(\\*[\w:]+\\*)\](\.)|(\.)\[(\\*[\w:]+\\*)\](?=\.|$)|\[(\\*[\w:]+\\*)\]/g, + (m, a, d1, d2, b, c) => { + const content = a || b || c; + return content.startsWith("\\") && content.endsWith("\\") + ? `${d2 || ""}[${content.slice(1, -1)}]${d1 || ""}` + : ""; + } + ); if (libraryName) return libraryName; const pkgPath = path.resolve(context, "package.json"); try { const packageInfo = JSON.parse(fs.readFileSync(pkgPath, "utf-8")); return packageInfo.name || ""; - } catch (e) { - if (e.code !== "ENOENT") { - e.message += `\nwhile determining default 'output.uniqueName' from 'name' in ${pkgPath}`; - throw e; + } catch (err) { + if (/** @type {Error & { code: string }} */ (err).code !== "ENOENT") { + /** @type {Error & { code: string }} */ + (err).message += + `\nwhile determining default 'output.uniqueName' from 'name' in ${pkgPath}`; + throw err; } return ""; } }); - D(output, "filename", "[name].js"); - F(output, "module", () => !!outputModule); + F(output, "module", () => Boolean(outputModule)); + D(output, "filename", output.module ? "[name].mjs" : "[name].js"); F(output, "iife", () => !output.module); D(output, "importFunctionName", "import"); D(output, "importMetaName", "import.meta"); F(output, "chunkFilename", () => { - const filename = output.filename; + const filename = + /** @type {NonNullable} */ + (output.filename); if (typeof filename !== "function") { const hasName = filename.includes("[name]"); const hasId = filename.includes("[id]"); @@ -592,22 +938,36 @@ const applyOutputDefaults = ( // Otherwise prefix "[id]." in front of the basename to make it changing return filename.replace(/(^|\/)([^/]*(?:\?|$))/, "$1[id].$2"); } - return "[id].js"; + return output.module ? "[id].mjs" : "[id].js"; + }); + F(output, "cssFilename", () => { + const filename = + /** @type {NonNullable} */ + (output.filename); + if (typeof filename !== "function") { + return filename.replace(/\.[mc]?js(\?|$)/, ".css$1"); + } + return "[id].css"; + }); + F(output, "cssChunkFilename", () => { + const chunkFilename = + /** @type {NonNullable} */ + (output.chunkFilename); + if (typeof chunkFilename !== "function") { + return chunkFilename.replace(/\.[mc]?js(\?|$)/, ".css$1"); + } + return "[id].css"; }); + D(output, "cssHeadDataCompression", !development); D(output, "assetModuleFilename", "[hash][ext][query]"); D(output, "webassemblyModuleFilename", "[hash].module.wasm"); D(output, "compareBeforeEmit", true); D(output, "charset", true); - F(output, "hotUpdateGlobal", () => - Template.toIdentifier( - "webpackHotUpdate" + Template.toIdentifier(output.uniqueName) - ) - ); - F(output, "chunkLoadingGlobal", () => - Template.toIdentifier( - "webpackChunk" + Template.toIdentifier(output.uniqueName) - ) + const uniqueNameId = Template.toIdentifier( + /** @type {NonNullable} */ (output.uniqueName) ); + F(output, "hotUpdateGlobal", () => `webpackHotUpdate${uniqueNameId}`); + F(output, "chunkLoadingGlobal", () => `webpackChunk${uniqueNameId}`); F(output, "globalObject", () => { if (tp) { if (tp.global) return "global"; @@ -617,14 +977,38 @@ const applyOutputDefaults = ( }); F(output, "chunkFormat", () => { if (tp) { - if (tp.document) return "array-push"; - if (tp.require) return "commonjs"; - if (tp.nodeBuiltins) return "commonjs"; - if (tp.importScripts) return "array-push"; - if (tp.dynamicImport && output.module) return "module"; + const helpMessage = isAffectedByBrowserslist + ? "Make sure that your 'browserslist' includes only platforms that support these features or select an appropriate 'target' to allow selecting a chunk format by default. Alternatively specify the 'output.chunkFormat' directly." + : "Select an appropriate 'target' to allow selecting one by default, or specify the 'output.chunkFormat' directly."; + if (output.module) { + if (tp.dynamicImport) return "module"; + if (tp.document) return "array-push"; + throw new Error( + "For the selected environment is no default ESM chunk format available:\n" + + "ESM exports can be chosen when 'import()' is available.\n" + + `JSONP Array push can be chosen when 'document' is available.\n${ + helpMessage + }` + ); + } else { + if (tp.document) return "array-push"; + if (tp.require) return "commonjs"; + if (tp.nodeBuiltins) return "commonjs"; + if (tp.importScripts) return "array-push"; + throw new Error( + "For the selected environment is no default script chunk format available:\n" + + "JSONP Array push can be chosen when 'document' or 'importScripts' is available.\n" + + `CommonJs exports can be chosen when 'require' or node builtins are available.\n${ + helpMessage + }` + ); + } } - return false; + throw new Error( + "Chunk format can't be selected by default when no target is specified" + ); }); + D(output, "asyncChunks", true); F(output, "chunkLoading", () => { if (tp) { switch (output.chunkFormat) { @@ -637,7 +1021,7 @@ const applyOutputDefaults = ( if (tp.nodeBuiltins) return "async-node"; break; case "module": - if (tp.dynamicImport) return "import"; + if (tp.dynamicImport || output.module) return "import"; break; } if ( @@ -662,7 +1046,7 @@ const applyOutputDefaults = ( if (tp.nodeBuiltins) return "async-node"; break; case "module": - if (tp.dynamicImportInWorker) return "import"; + if (tp.dynamicImportInWorker || output.module) return "import"; break; } if ( @@ -678,7 +1062,8 @@ const applyOutputDefaults = ( F(output, "wasmLoading", () => { if (tp) { if (tp.fetchWasm) return "fetch"; - if (tp.nodeBuiltins) return "async-node"; + if (tp.nodeBuiltins) + return output.module ? "async-node-module" : "async-node"; if (tp.nodeBuiltins === null || tp.fetchWasm === null) { return "universal"; } @@ -693,7 +1078,11 @@ const applyOutputDefaults = ( F(output, "path", () => path.join(process.cwd(), "dist")); F(output, "pathinfo", () => development); D(output, "sourceMapFilename", "[file].map[query]"); - D(output, "hotUpdateChunkFilename", "[id].[fullhash].hot-update.js"); + D( + output, + "hotUpdateChunkFilename", + `[id].[fullhash].hot-update.${output.module ? "mjs" : "js"}` + ); D(output, "hotUpdateMainFilename", "[runtime].[fullhash].hot-update.json"); D(output, "crossOriginLoading", false); F(output, "scriptType", () => (output.module ? "module" : false)); @@ -704,28 +1093,122 @@ const applyOutputDefaults = ( ? "auto" : "" ); + D(output, "workerPublicPath", ""); D(output, "chunkLoadTimeout", 120000); - D(output, "hashFunction", "md4"); + D(output, "hashFunction", futureDefaults ? "xxhash64" : "md4"); D(output, "hashDigest", "hex"); - D(output, "hashDigestLength", 20); + D(output, "hashDigestLength", futureDefaults ? 16 : 20); + D(output, "strictModuleErrorHandling", false); D(output, "strictModuleExceptionHandling", false); + const environment = /** @type {Environment} */ (output.environment); + /** + * @param {boolean | undefined} v value + * @returns {boolean} true, when v is truthy or undefined + */ const optimistic = v => v || v === undefined; + /** + * @param {boolean | undefined} v value + * @param {boolean | undefined} c condition + * @returns {boolean | undefined} true, when v is truthy or undefined, or c is truthy + */ + const conditionallyOptimistic = (v, c) => (v === undefined && c) || v; + + F( + environment, + "globalThis", + () => /** @type {boolean | undefined} */ (tp && tp.globalThis) + ); + F( + environment, + "bigIntLiteral", + () => + tp && optimistic(/** @type {boolean | undefined} */ (tp.bigIntLiteral)) + ); F( - output.environment, + environment, + "const", + () => tp && optimistic(/** @type {boolean | undefined} */ (tp.const)) + ); + F( + environment, "arrowFunction", - () => tp && optimistic(tp.arrowFunction) + () => + tp && optimistic(/** @type {boolean | undefined} */ (tp.arrowFunction)) ); - F(output.environment, "const", () => tp && optimistic(tp.const)); F( - output.environment, + environment, + "asyncFunction", + () => + tp && optimistic(/** @type {boolean | undefined} */ (tp.asyncFunction)) + ); + F( + environment, + "forOf", + () => tp && optimistic(/** @type {boolean | undefined} */ (tp.forOf)) + ); + F( + environment, "destructuring", - () => tp && optimistic(tp.destructuring) + () => + tp && optimistic(/** @type {boolean | undefined} */ (tp.destructuring)) + ); + F( + environment, + "optionalChaining", + () => + tp && optimistic(/** @type {boolean | undefined} */ (tp.optionalChaining)) + ); + F( + environment, + "nodePrefixForCoreModules", + () => + tp && + optimistic( + /** @type {boolean | undefined} */ (tp.nodePrefixForCoreModules) + ) + ); + F( + environment, + "templateLiteral", + () => + tp && optimistic(/** @type {boolean | undefined} */ (tp.templateLiteral)) + ); + F(environment, "dynamicImport", () => + conditionallyOptimistic( + /** @type {boolean | undefined} */ (tp && tp.dynamicImport), + output.module + ) + ); + F(environment, "dynamicImportInWorker", () => + conditionallyOptimistic( + /** @type {boolean | undefined} */ (tp && tp.dynamicImportInWorker), + output.module + ) + ); + F(environment, "module", () => + conditionallyOptimistic( + /** @type {boolean | undefined} */ (tp && tp.module), + output.module + ) ); - F(output.environment, "forOf", () => tp && optimistic(tp.forOf)); - F(output.environment, "bigIntLiteral", () => tp && tp.bigIntLiteral); - F(output.environment, "dynamicImport", () => tp && tp.dynamicImport); - F(output.environment, "module", () => tp && tp.module); + F( + environment, + "document", + () => tp && optimistic(/** @type {boolean | undefined} */ (tp.document)) + ); + + const { trustedTypes } = output; + if (trustedTypes) { + F( + trustedTypes, + "policyName", + () => + /** @type {NonNullable} */ + (output.uniqueName).replace(/[^a-zA-Z0-9\-#=_/@.%]+/g, "_") || "webpack" + ); + D(trustedTypes, "onPolicyCreationFailure", "stop"); + } /** * @param {function(EntryDescription): void} fn iterator @@ -733,10 +1216,11 @@ const applyOutputDefaults = ( */ const forEachEntry = fn => { for (const name of Object.keys(entry)) { - fn(entry[name]); + fn(/** @type {{[k: string] : EntryDescription}} */ (entry)[name]); } }; A(output, "enabledLibraryTypes", () => { + /** @type {LibraryType[]} */ const enabledLibraryTypes = []; if (output.library) { enabledLibraryTypes.push(output.library.type); @@ -784,52 +1268,79 @@ const applyOutputDefaults = ( /** * @param {ExternalsPresets} externalsPresets options - * @param {Object} options options + * @param {object} options options * @param {TargetProperties | false} options.targetProperties target properties + * @param {boolean} options.buildHttp buildHttp experiment enabled * @returns {void} */ const applyExternalsPresetsDefaults = ( externalsPresets, - { targetProperties } + { targetProperties, buildHttp } ) => { - D(externalsPresets, "web", targetProperties && targetProperties.web); - D(externalsPresets, "node", targetProperties && targetProperties.node); - D(externalsPresets, "nwjs", targetProperties && targetProperties.nwjs); + D( + externalsPresets, + "web", + /** @type {boolean | undefined} */ + (!buildHttp && targetProperties && targetProperties.web) + ); + D( + externalsPresets, + "node", + /** @type {boolean | undefined} */ + (targetProperties && targetProperties.node) + ); + D( + externalsPresets, + "nwjs", + /** @type {boolean | undefined} */ + (targetProperties && targetProperties.nwjs) + ); D( externalsPresets, "electron", - targetProperties && targetProperties.electron + /** @type {boolean | undefined} */ + (targetProperties && targetProperties.electron) ); D( externalsPresets, "electronMain", - targetProperties && - targetProperties.electron && - targetProperties.electronMain + /** @type {boolean | undefined} */ + ( + targetProperties && + targetProperties.electron && + targetProperties.electronMain + ) ); D( externalsPresets, "electronPreload", - targetProperties && - targetProperties.electron && - targetProperties.electronPreload + /** @type {boolean | undefined} */ + ( + targetProperties && + targetProperties.electron && + targetProperties.electronPreload + ) ); D( externalsPresets, "electronRenderer", - targetProperties && - targetProperties.electron && - targetProperties.electronRenderer + /** @type {boolean | undefined} */ + ( + targetProperties && + targetProperties.electron && + targetProperties.electronRenderer + ) ); }; /** * @param {Loader} loader options - * @param {Object} options options + * @param {object} options options * @param {TargetProperties | false} options.targetProperties target properties + * @param {Environment} options.environment environment * @returns {void} */ -const applyLoaderDefaults = (loader, { targetProperties }) => { +const applyLoaderDefaults = (loader, { targetProperties, environment }) => { F(loader, "target", () => { if (targetProperties) { if (targetProperties.electron) { @@ -843,33 +1354,43 @@ const applyLoaderDefaults = (loader, { targetProperties }) => { if (targetProperties.web) return "web"; } }); + D(loader, "environment", environment); }; /** * @param {WebpackNode} node options - * @param {Object} options options + * @param {object} options options * @param {TargetProperties | false} options.targetProperties target properties + * @param {boolean} options.futureDefaults is future defaults enabled + * @param {boolean} options.outputModule is output type is module * @returns {void} */ -const applyNodeDefaults = (node, { targetProperties }) => { +const applyNodeDefaults = ( + node, + { futureDefaults, outputModule, targetProperties } +) => { if (node === false) return; + F(node, "global", () => { if (targetProperties && targetProperties.global) return false; - return true; - }); - F(node, "__filename", () => { - if (targetProperties && targetProperties.node) return "eval-only"; - return "mock"; - }); - F(node, "__dirname", () => { - if (targetProperties && targetProperties.node) return "eval-only"; - return "mock"; + // TODO webpack 6 should always default to false + return futureDefaults ? "warn" : true; }); + + const handlerForNames = () => { + if (targetProperties && targetProperties.node) + return outputModule ? "node-module" : "eval-only"; + // TODO webpack 6 should always default to false + return futureDefaults ? "warn-mock" : "mock"; + }; + + F(node, "__filename", handlerForNames); + F(node, "__dirname", handlerForNames); }; /** * @param {Performance} performance options - * @param {Object} options options + * @param {object} options options * @param {boolean} options.production is production * @returns {void} */ @@ -882,15 +1403,16 @@ const applyPerformanceDefaults = (performance, { production }) => { /** * @param {Optimization} optimization options - * @param {Object} options options + * @param {object} options options * @param {boolean} options.production is production * @param {boolean} options.development is development + * @param {boolean} options.css is css enabled * @param {boolean} options.records using records * @returns {void} */ const applyOptimizationDefaults = ( optimization, - { production, development, records } + { production, development, css, records } ) => { D(optimization, "removeAvailableModules", false); D(optimization, "removeEmptyChunks", true); @@ -941,10 +1463,12 @@ const applyOptimizationDefaults = ( }); const { splitChunks } = optimization; if (splitChunks) { - A(splitChunks, "defaultSizeTypes", () => ["javascript", "unknown"]); + A(splitChunks, "defaultSizeTypes", () => + css ? ["javascript", "css", "unknown"] : ["javascript", "unknown"] + ); D(splitChunks, "hidePathInfo", production); D(splitChunks, "chunks", "async"); - D(splitChunks, "usedExports", true); + D(splitChunks, "usedExports", optimization.usedExports === true); D(splitChunks, "minChunks", 1); F(splitChunks, "minSize", () => (production ? 20000 : 10000)); F(splitChunks, "minRemainingSize", () => (development ? 0 : undefined)); @@ -952,7 +1476,9 @@ const applyOptimizationDefaults = ( F(splitChunks, "maxAsyncRequests", () => (production ? 30 : Infinity)); F(splitChunks, "maxInitialRequests", () => (production ? 30 : Infinity)); D(splitChunks, "automaticNameDelimiter", "-"); - const { cacheGroups } = splitChunks; + const cacheGroups = + /** @type {NonNullable} */ + (splitChunks.cacheGroups); F(cacheGroups, "default", () => ({ idHint: "", reuseExistingChunk: true, @@ -969,14 +1495,21 @@ const applyOptimizationDefaults = ( }; /** - * @param {Object} options options + * @param {object} options options * @param {boolean} options.cache is cache enable * @param {string} options.context build context * @param {TargetProperties | false} options.targetProperties target properties * @param {Mode} options.mode mode + * @param {boolean} options.css is css enabled * @returns {ResolveOptions} resolve options */ -const getResolveDefaults = ({ cache, context, targetProperties, mode }) => { +const getResolveDefaults = ({ + cache, + context, + targetProperties, + mode, + css +}) => { /** @type {string[]} */ const conditions = ["webpack"]; @@ -1022,9 +1555,11 @@ const getResolveDefaults = ({ cache, context, targetProperties, mode }) => { exportsFields: ["exports"], roots: [context], mainFields: ["main"], + importsFields: ["imports"], byDependency: { wasm: esmDeps(), esm: esmDeps(), + loaderImport: esmDeps(), url: { preferRelative: true }, @@ -1043,11 +1578,30 @@ const getResolveDefaults = ({ cache, context, targetProperties, mode }) => { } }; + if (css) { + const styleConditions = []; + + styleConditions.push("webpack"); + styleConditions.push(mode === "development" ? "development" : "production"); + styleConditions.push("style"); + + resolveOptions.byDependency["css-import"] = { + // We avoid using any main files because we have to be consistent with CSS `@import` + // and CSS `@import` does not handle `main` files in directories, + // you should always specify the full URL for styles + mainFiles: [], + mainFields: ["style", "..."], + conditionNames: styleConditions, + extensions: [".css"], + preferRelative: true + }; + } + return resolveOptions; }; /** - * @param {Object} options options + * @param {object} options options * @param {boolean} options.cache is cache enable * @returns {ResolveOptions} resolve options */ @@ -1070,9 +1624,16 @@ const getResolveLoaderDefaults = ({ cache }) => { * @returns {void} */ const applyInfrastructureLoggingDefaults = infrastructureLogging => { + F(infrastructureLogging, "stream", () => process.stderr); + const tty = + /** @type {any} */ (infrastructureLogging.stream).isTTY && + process.env.TERM !== "dumb"; D(infrastructureLogging, "level", "info"); D(infrastructureLogging, "debug", false); + D(infrastructureLogging, "colors", tty); + D(infrastructureLogging, "appendOnly", !tty); }; -exports.applyWebpackOptionsBaseDefaults = applyWebpackOptionsBaseDefaults; -exports.applyWebpackOptionsDefaults = applyWebpackOptionsDefaults; +module.exports.applyWebpackOptionsBaseDefaults = + applyWebpackOptionsBaseDefaults; +module.exports.applyWebpackOptionsDefaults = applyWebpackOptionsDefaults; diff --git a/lib/config/normalization.js b/lib/config/normalization.js index 625a1b45458..1fa5a3d1f3e 100644 --- a/lib/config/normalization.js +++ b/lib/config/normalization.js @@ -7,17 +7,28 @@ const util = require("util"); +/** @typedef {import("../../declarations/WebpackOptions").CacheOptionsNormalized} CacheOptions */ +/** @typedef {import("../../declarations/WebpackOptions").EntryDescriptionNormalized} EntryDescriptionNormalized */ /** @typedef {import("../../declarations/WebpackOptions").EntryStatic} EntryStatic */ /** @typedef {import("../../declarations/WebpackOptions").EntryStaticNormalized} EntryStaticNormalized */ +/** @typedef {import("../../declarations/WebpackOptions").Externals} Externals */ /** @typedef {import("../../declarations/WebpackOptions").LibraryName} LibraryName */ /** @typedef {import("../../declarations/WebpackOptions").LibraryOptions} LibraryOptions */ +/** @typedef {import("../../declarations/WebpackOptions").ModuleOptionsNormalized} ModuleOptionsNormalized */ /** @typedef {import("../../declarations/WebpackOptions").OptimizationRuntimeChunk} OptimizationRuntimeChunk */ /** @typedef {import("../../declarations/WebpackOptions").OptimizationRuntimeChunkNormalized} OptimizationRuntimeChunkNormalized */ /** @typedef {import("../../declarations/WebpackOptions").OutputNormalized} OutputNormalized */ +/** @typedef {import("../../declarations/WebpackOptions").Plugins} Plugins */ /** @typedef {import("../../declarations/WebpackOptions").WebpackOptions} WebpackOptions */ /** @typedef {import("../../declarations/WebpackOptions").WebpackOptionsNormalized} WebpackOptionsNormalized */ +/** @typedef {import("../Entrypoint")} Entrypoint */ const handledDeprecatedNoEmitOnErrors = util.deprecate( + /** + * @param {boolean} noEmitOnErrors no emit on errors + * @param {boolean | undefined} emitOnErrors emit on errors + * @returns {boolean} emit on errors + */ (noEmitOnErrors, emitOnErrors) => { if (emitOnErrors !== undefined && !noEmitOnErrors === !emitOnErrors) { throw new Error( @@ -45,10 +56,7 @@ const nestedConfig = (value, fn) => * @param {T|undefined} value value or not * @returns {T} result value */ -const cloneObject = value => { - return /** @type {T} */ ({ ...value }); -}; - +const cloneObject = value => /** @type {T} */ ({ ...value }); /** * @template T * @template R @@ -87,18 +95,20 @@ const optionalNestedArray = (value, fn) => * @returns {Record} result value */ const keyedNestedConfig = (value, fn, customKeys) => { + /* eslint-disable no-sequences */ const result = value === undefined ? {} : Object.keys(value).reduce( (obj, key) => ( - (obj[key] = (customKeys && key in customKeys - ? customKeys[key] - : fn)(value[key])), + (obj[key] = ( + customKeys && key in customKeys ? customKeys[key] : fn + )(value[key])), obj ), /** @type {Record} */ ({}) - ); + ); + /* eslint-enable no-sequences */ if (customKeys) { for (const key of Object.keys(customKeys)) { if (!(key in result)) { @@ -113,307 +123,349 @@ const keyedNestedConfig = (value, fn, customKeys) => { * @param {WebpackOptions} config input config * @returns {WebpackOptionsNormalized} normalized options */ -const getNormalizedWebpackOptions = config => { - return { - amd: config.amd, - bail: config.bail, - cache: optionalNestedConfig(config.cache, cache => { - if (cache === false) return false; - if (cache === true) { - return { - type: "memory" - }; - } - switch (cache.type) { - case "filesystem": - return { - type: "filesystem", - buildDependencies: cloneObject(cache.buildDependencies), - cacheDirectory: cache.cacheDirectory, - cacheLocation: cache.cacheLocation, - hashAlgorithm: cache.hashAlgorithm, - idleTimeout: cache.idleTimeout, - idleTimeoutForInitialStore: cache.idleTimeoutForInitialStore, - name: cache.name, - store: cache.store, - version: cache.version - }; - case undefined: - case "memory": +const getNormalizedWebpackOptions = config => ({ + amd: config.amd, + bail: config.bail, + cache: + /** @type {NonNullable} */ + ( + optionalNestedConfig(config.cache, cache => { + if (cache === false) return false; + if (cache === true) { return { - type: "memory" + type: "memory", + maxGenerations: undefined }; - default: - // @ts-expect-error Property 'type' does not exist on type 'never'. ts(2339) - throw new Error(`Not implemented cache.type ${cache.type}`); - } - }), - context: config.context, - dependencies: config.dependencies, - devServer: optionalNestedConfig(config.devServer, devServer => ({ - ...devServer - })), - devtool: config.devtool, - entry: - config.entry === undefined - ? { main: {} } - : typeof config.entry === "function" - ? (fn => () => - Promise.resolve().then(fn).then(getNormalizedEntryStatic))( - config.entry - ) + } + switch (cache.type) { + case "filesystem": + return { + type: "filesystem", + allowCollectingMemory: cache.allowCollectingMemory, + maxMemoryGenerations: cache.maxMemoryGenerations, + maxAge: cache.maxAge, + profile: cache.profile, + buildDependencies: cloneObject(cache.buildDependencies), + cacheDirectory: cache.cacheDirectory, + cacheLocation: cache.cacheLocation, + hashAlgorithm: cache.hashAlgorithm, + compression: cache.compression, + idleTimeout: cache.idleTimeout, + idleTimeoutForInitialStore: cache.idleTimeoutForInitialStore, + idleTimeoutAfterLargeChanges: cache.idleTimeoutAfterLargeChanges, + name: cache.name, + store: cache.store, + version: cache.version, + readonly: cache.readonly + }; + case undefined: + case "memory": + return { + type: "memory", + maxGenerations: cache.maxGenerations + }; + default: + // @ts-expect-error Property 'type' does not exist on type 'never'. ts(2339) + throw new Error(`Not implemented cache.type ${cache.type}`); + } + }) + ), + context: config.context, + dependencies: config.dependencies, + devServer: optionalNestedConfig(config.devServer, devServer => { + if (devServer === false) return false; + return { ...devServer }; + }), + devtool: config.devtool, + entry: + config.entry === undefined + ? { main: {} } + : typeof config.entry === "function" + ? ( + fn => () => + Promise.resolve().then(fn).then(getNormalizedEntryStatic) + )(config.entry) : getNormalizedEntryStatic(config.entry), - experiments: cloneObject(config.experiments), - externals: config.externals, - externalsPresets: cloneObject(config.externalsPresets), - externalsType: config.externalsType, - ignoreWarnings: config.ignoreWarnings - ? config.ignoreWarnings.map(ignore => { - if (typeof ignore === "function") return ignore; - const i = ignore instanceof RegExp ? { message: ignore } : ignore; - return (warning, { requestShortener }) => { - if (!i.message && !i.module && !i.file) return false; - if (i.message && !i.message.test(warning.message)) { - return false; - } - if ( - i.module && - (!warning.module || - !i.module.test( - warning.module.readableIdentifier(requestShortener) - )) - ) { - return false; - } - if (i.file && (!warning.file || !i.file.test(warning.file))) { - return false; - } - return true; - }; - }) - : undefined, - infrastructureLogging: cloneObject(config.infrastructureLogging), - loader: cloneObject(config.loader), - mode: config.mode, - module: nestedConfig(config.module, module => ({ - noParse: module.noParse, - unsafeCache: module.unsafeCache, - parser: keyedNestedConfig(module.parser, cloneObject, { - javascript: parserOptions => ({ - unknownContextRequest: module.unknownContextRequest, - unknownContextRegExp: module.unknownContextRegExp, - unknownContextRecursive: module.unknownContextRecursive, - unknownContextCritical: module.unknownContextCritical, - exprContextRequest: module.exprContextRequest, - exprContextRegExp: module.exprContextRegExp, - exprContextRecursive: module.exprContextRecursive, - exprContextCritical: module.exprContextCritical, - wrappedContextRegExp: module.wrappedContextRegExp, - wrappedContextRecursive: module.wrappedContextRecursive, - wrappedContextCritical: module.wrappedContextCritical, - strictExportPresence: module.strictExportPresence, - strictThisContextOnImports: module.strictThisContextOnImports, - ...parserOptions - }) - }), - generator: cloneObject(module.generator), - defaultRules: optionalNestedArray(module.defaultRules, r => [...r]), - rules: nestedArray(module.rules, r => [...r]) - })), - name: config.name, - node: nestedConfig( - config.node, - node => - node && { - ...node + experiments: nestedConfig(config.experiments, experiments => ({ + ...experiments, + buildHttp: optionalNestedConfig(experiments.buildHttp, options => + Array.isArray(options) ? { allowedUris: options } : options + ), + lazyCompilation: optionalNestedConfig( + experiments.lazyCompilation, + options => (options === true ? {} : options) + ) + })), + externals: /** @type {NonNullable} */ (config.externals), + externalsPresets: cloneObject(config.externalsPresets), + externalsType: config.externalsType, + ignoreWarnings: config.ignoreWarnings + ? config.ignoreWarnings.map(ignore => { + if (typeof ignore === "function") return ignore; + const i = ignore instanceof RegExp ? { message: ignore } : ignore; + return (warning, { requestShortener }) => { + if (!i.message && !i.module && !i.file) return false; + if (i.message && !i.message.test(warning.message)) { + return false; + } + if ( + i.module && + (!warning.module || + !i.module.test( + warning.module.readableIdentifier(requestShortener) + )) + ) { + return false; + } + if (i.file && (!warning.file || !i.file.test(warning.file))) { + return false; + } + return true; + }; + }) + : undefined, + infrastructureLogging: cloneObject(config.infrastructureLogging), + loader: cloneObject(config.loader), + mode: config.mode, + module: + /** @type {ModuleOptionsNormalized} */ + ( + nestedConfig(config.module, module => ({ + noParse: module.noParse, + unsafeCache: module.unsafeCache, + parser: keyedNestedConfig(module.parser, cloneObject, { + javascript: parserOptions => ({ + unknownContextRequest: module.unknownContextRequest, + unknownContextRegExp: module.unknownContextRegExp, + unknownContextRecursive: module.unknownContextRecursive, + unknownContextCritical: module.unknownContextCritical, + exprContextRequest: module.exprContextRequest, + exprContextRegExp: module.exprContextRegExp, + exprContextRecursive: module.exprContextRecursive, + exprContextCritical: module.exprContextCritical, + wrappedContextRegExp: module.wrappedContextRegExp, + wrappedContextRecursive: module.wrappedContextRecursive, + wrappedContextCritical: module.wrappedContextCritical, + // TODO webpack 6 remove + strictExportPresence: module.strictExportPresence, + strictThisContextOnImports: module.strictThisContextOnImports, + ...parserOptions + }) + }), + generator: cloneObject(module.generator), + defaultRules: optionalNestedArray(module.defaultRules, r => [...r]), + rules: nestedArray(module.rules, r => [...r]) + })) + ), + name: config.name, + node: nestedConfig( + config.node, + node => + node && { + ...node + } + ), + optimization: nestedConfig(config.optimization, optimization => ({ + ...optimization, + runtimeChunk: getNormalizedOptimizationRuntimeChunk( + optimization.runtimeChunk + ), + splitChunks: nestedConfig( + optimization.splitChunks, + splitChunks => + splitChunks && { + ...splitChunks, + defaultSizeTypes: splitChunks.defaultSizeTypes + ? [...splitChunks.defaultSizeTypes] + : ["..."], + cacheGroups: cloneObject(splitChunks.cacheGroups) } ), - optimization: nestedConfig(config.optimization, optimization => { - return { - ...optimization, - runtimeChunk: getNormalizedOptimizationRuntimeChunk( - optimization.runtimeChunk - ), - splitChunks: nestedConfig( - optimization.splitChunks, - splitChunks => - splitChunks && { - ...splitChunks, - defaultSizeTypes: splitChunks.defaultSizeTypes - ? [...splitChunks.defaultSizeTypes] - : ["..."], - cacheGroups: cloneObject(splitChunks.cacheGroups) - } - ), - emitOnErrors: - optimization.noEmitOnErrors !== undefined - ? handledDeprecatedNoEmitOnErrors( - optimization.noEmitOnErrors, - optimization.emitOnErrors - ) - : optimization.emitOnErrors - }; - }), - output: nestedConfig(config.output, output => { - const { library } = output; - const libraryAsName = /** @type {LibraryName} */ (library); - const libraryBase = - typeof library === "object" && - library && - !Array.isArray(library) && - "type" in library - ? library - : libraryAsName || output.libraryTarget + emitOnErrors: + optimization.noEmitOnErrors !== undefined + ? handledDeprecatedNoEmitOnErrors( + optimization.noEmitOnErrors, + optimization.emitOnErrors + ) + : optimization.emitOnErrors + })), + output: nestedConfig(config.output, output => { + const { library } = output; + const libraryAsName = /** @type {LibraryName} */ (library); + const libraryBase = + typeof library === "object" && + library && + !Array.isArray(library) && + "type" in library + ? library + : libraryAsName || output.libraryTarget ? /** @type {LibraryOptions} */ ({ name: libraryAsName - }) + }) : undefined; - /** @type {OutputNormalized} */ - const result = { - assetModuleFilename: output.assetModuleFilename, - charset: output.charset, - chunkFilename: output.chunkFilename, - chunkFormat: output.chunkFormat, - chunkLoading: output.chunkLoading, - chunkLoadingGlobal: output.chunkLoadingGlobal, - chunkLoadTimeout: output.chunkLoadTimeout, - clean: output.clean, - compareBeforeEmit: output.compareBeforeEmit, - crossOriginLoading: output.crossOriginLoading, - devtoolFallbackModuleFilenameTemplate: - output.devtoolFallbackModuleFilenameTemplate, - devtoolModuleFilenameTemplate: output.devtoolModuleFilenameTemplate, - devtoolNamespace: output.devtoolNamespace, - environment: cloneObject(output.environment), - enabledChunkLoadingTypes: output.enabledChunkLoadingTypes - ? [...output.enabledChunkLoadingTypes] - : ["..."], - enabledLibraryTypes: output.enabledLibraryTypes - ? [...output.enabledLibraryTypes] - : ["..."], - enabledWasmLoadingTypes: output.enabledWasmLoadingTypes - ? [...output.enabledWasmLoadingTypes] - : ["..."], - filename: output.filename, - globalObject: output.globalObject, - hashDigest: output.hashDigest, - hashDigestLength: output.hashDigestLength, - hashFunction: output.hashFunction, - hashSalt: output.hashSalt, - hotUpdateChunkFilename: output.hotUpdateChunkFilename, - hotUpdateGlobal: output.hotUpdateGlobal, - hotUpdateMainFilename: output.hotUpdateMainFilename, - iife: output.iife, - importFunctionName: output.importFunctionName, - importMetaName: output.importMetaName, - scriptType: output.scriptType, - library: libraryBase && { - type: - output.libraryTarget !== undefined - ? output.libraryTarget - : libraryBase.type, - auxiliaryComment: - output.auxiliaryComment !== undefined - ? output.auxiliaryComment - : libraryBase.auxiliaryComment, - export: - output.libraryExport !== undefined - ? output.libraryExport - : libraryBase.export, - name: libraryBase.name, - umdNamedDefine: - output.umdNamedDefine !== undefined - ? output.umdNamedDefine - : libraryBase.umdNamedDefine - }, - module: output.module, - path: output.path, - pathinfo: output.pathinfo, - publicPath: output.publicPath, - sourceMapFilename: output.sourceMapFilename, - sourcePrefix: output.sourcePrefix, - strictModuleExceptionHandling: output.strictModuleExceptionHandling, - uniqueName: output.uniqueName, - wasmLoading: output.wasmLoading, - webassemblyModuleFilename: output.webassemblyModuleFilename, - workerChunkLoading: output.workerChunkLoading, - workerWasmLoading: output.workerWasmLoading + /** @type {OutputNormalized} */ + const result = { + assetModuleFilename: output.assetModuleFilename, + asyncChunks: output.asyncChunks, + charset: output.charset, + chunkFilename: output.chunkFilename, + chunkFormat: output.chunkFormat, + chunkLoading: output.chunkLoading, + chunkLoadingGlobal: output.chunkLoadingGlobal, + chunkLoadTimeout: output.chunkLoadTimeout, + cssFilename: output.cssFilename, + cssChunkFilename: output.cssChunkFilename, + cssHeadDataCompression: output.cssHeadDataCompression, + clean: output.clean, + compareBeforeEmit: output.compareBeforeEmit, + crossOriginLoading: output.crossOriginLoading, + devtoolFallbackModuleFilenameTemplate: + output.devtoolFallbackModuleFilenameTemplate, + devtoolModuleFilenameTemplate: output.devtoolModuleFilenameTemplate, + devtoolNamespace: output.devtoolNamespace, + environment: cloneObject(output.environment), + enabledChunkLoadingTypes: output.enabledChunkLoadingTypes + ? [...output.enabledChunkLoadingTypes] + : ["..."], + enabledLibraryTypes: output.enabledLibraryTypes + ? [...output.enabledLibraryTypes] + : ["..."], + enabledWasmLoadingTypes: output.enabledWasmLoadingTypes + ? [...output.enabledWasmLoadingTypes] + : ["..."], + filename: output.filename, + globalObject: output.globalObject, + hashDigest: output.hashDigest, + hashDigestLength: output.hashDigestLength, + hashFunction: output.hashFunction, + hashSalt: output.hashSalt, + hotUpdateChunkFilename: output.hotUpdateChunkFilename, + hotUpdateGlobal: output.hotUpdateGlobal, + hotUpdateMainFilename: output.hotUpdateMainFilename, + ignoreBrowserWarnings: output.ignoreBrowserWarnings, + iife: output.iife, + importFunctionName: output.importFunctionName, + importMetaName: output.importMetaName, + scriptType: output.scriptType, + library: libraryBase && { + type: + output.libraryTarget !== undefined + ? output.libraryTarget + : libraryBase.type, + auxiliaryComment: + output.auxiliaryComment !== undefined + ? output.auxiliaryComment + : libraryBase.auxiliaryComment, + amdContainer: + output.amdContainer !== undefined + ? output.amdContainer + : libraryBase.amdContainer, + export: + output.libraryExport !== undefined + ? output.libraryExport + : libraryBase.export, + name: libraryBase.name, + umdNamedDefine: + output.umdNamedDefine !== undefined + ? output.umdNamedDefine + : libraryBase.umdNamedDefine + }, + module: output.module, + path: output.path, + pathinfo: output.pathinfo, + publicPath: output.publicPath, + sourceMapFilename: output.sourceMapFilename, + sourcePrefix: output.sourcePrefix, + strictModuleErrorHandling: output.strictModuleErrorHandling, + strictModuleExceptionHandling: output.strictModuleExceptionHandling, + trustedTypes: optionalNestedConfig(output.trustedTypes, trustedTypes => { + if (trustedTypes === true) return {}; + if (typeof trustedTypes === "string") + return { policyName: trustedTypes }; + return { ...trustedTypes }; + }), + uniqueName: output.uniqueName, + wasmLoading: output.wasmLoading, + webassemblyModuleFilename: output.webassemblyModuleFilename, + workerPublicPath: output.workerPublicPath, + workerChunkLoading: output.workerChunkLoading, + workerWasmLoading: output.workerWasmLoading + }; + return result; + }), + parallelism: config.parallelism, + performance: optionalNestedConfig(config.performance, performance => { + if (performance === false) return false; + return { + ...performance + }; + }), + plugins: /** @type {Plugins} */ (nestedArray(config.plugins, p => [...p])), + profile: config.profile, + recordsInputPath: + config.recordsInputPath !== undefined + ? config.recordsInputPath + : config.recordsPath, + recordsOutputPath: + config.recordsOutputPath !== undefined + ? config.recordsOutputPath + : config.recordsPath, + resolve: nestedConfig(config.resolve, resolve => ({ + ...resolve, + byDependency: keyedNestedConfig(resolve.byDependency, cloneObject) + })), + resolveLoader: cloneObject(config.resolveLoader), + snapshot: nestedConfig(config.snapshot, snapshot => ({ + resolveBuildDependencies: optionalNestedConfig( + snapshot.resolveBuildDependencies, + resolveBuildDependencies => ({ + timestamp: resolveBuildDependencies.timestamp, + hash: resolveBuildDependencies.hash + }) + ), + buildDependencies: optionalNestedConfig( + snapshot.buildDependencies, + buildDependencies => ({ + timestamp: buildDependencies.timestamp, + hash: buildDependencies.hash + }) + ), + resolve: optionalNestedConfig(snapshot.resolve, resolve => ({ + timestamp: resolve.timestamp, + hash: resolve.hash + })), + module: optionalNestedConfig(snapshot.module, module => ({ + timestamp: module.timestamp, + hash: module.hash + })), + immutablePaths: optionalNestedArray(snapshot.immutablePaths, p => [...p]), + managedPaths: optionalNestedArray(snapshot.managedPaths, p => [...p]), + unmanagedPaths: optionalNestedArray(snapshot.unmanagedPaths, p => [...p]) + })), + stats: nestedConfig(config.stats, stats => { + if (stats === false) { + return { + preset: "none" }; - return result; - }), - parallelism: config.parallelism, - performance: optionalNestedConfig(config.performance, performance => { - if (performance === false) return false; + } + if (stats === true) { return { - ...performance + preset: "normal" }; - }), - plugins: nestedArray(config.plugins, p => [...p]), - profile: config.profile, - recordsInputPath: - config.recordsInputPath !== undefined - ? config.recordsInputPath - : config.recordsPath, - recordsOutputPath: - config.recordsOutputPath !== undefined - ? config.recordsOutputPath - : config.recordsPath, - resolve: nestedConfig(config.resolve, resolve => ({ - ...resolve, - byDependency: keyedNestedConfig(resolve.byDependency, cloneObject) - })), - resolveLoader: cloneObject(config.resolveLoader), - snapshot: nestedConfig(config.snapshot, snapshot => ({ - resolveBuildDependencies: optionalNestedConfig( - snapshot.resolveBuildDependencies, - resolveBuildDependencies => ({ - timestamp: resolveBuildDependencies.timestamp, - hash: resolveBuildDependencies.hash - }) - ), - buildDependencies: optionalNestedConfig( - snapshot.buildDependencies, - buildDependencies => ({ - timestamp: buildDependencies.timestamp, - hash: buildDependencies.hash - }) - ), - resolve: optionalNestedConfig(snapshot.resolve, resolve => ({ - timestamp: resolve.timestamp, - hash: resolve.hash - })), - module: optionalNestedConfig(snapshot.module, module => ({ - timestamp: module.timestamp, - hash: module.hash - })), - immutablePaths: optionalNestedArray(snapshot.immutablePaths, p => [...p]), - managedPaths: optionalNestedArray(snapshot.managedPaths, p => [...p]) - })), - stats: nestedConfig(config.stats, stats => { - if (stats === false) { - return { - preset: "none" - }; - } - if (stats === true) { - return { - preset: "normal" - }; - } - if (typeof stats === "string") { - return { - preset: stats - }; - } + } + if (typeof stats === "string") { return { - ...stats + preset: stats }; - }), - target: config.target, - watch: config.watch, - watchOptions: cloneObject(config.watchOptions) - }; -}; + } + return { + ...stats + }; + }), + target: config.target, + watch: config.watch, + watchOptions: cloneObject(config.watchOptions) +}); /** * @param {EntryStatic} entry static entry options @@ -449,16 +501,27 @@ const getNormalizedEntryStatic = entry => { } else { result[key] = { import: - value.import && - (Array.isArray(value.import) ? value.import : [value.import]), + /** @type {EntryDescriptionNormalized["import"]} */ + ( + value.import && + (Array.isArray(value.import) ? value.import : [value.import]) + ), filename: value.filename, layer: value.layer, runtime: value.runtime, + baseUri: value.baseUri, + publicPath: value.publicPath, chunkLoading: value.chunkLoading, + asyncChunks: value.asyncChunks, wasmLoading: value.wasmLoading, dependOn: - value.dependOn && - (Array.isArray(value.dependOn) ? value.dependOn : [value.dependOn]), + /** @type {EntryDescriptionNormalized["dependOn"]} */ + ( + value.dependOn && + (Array.isArray(value.dependOn) + ? value.dependOn + : [value.dependOn]) + ), library: value.library }; } @@ -471,7 +534,7 @@ const getNormalizedEntryStatic = entry => { * @returns {OptimizationRuntimeChunkNormalized=} normalized runtimeChunk option */ const getNormalizedOptimizationRuntimeChunk = runtimeChunk => { - if (runtimeChunk === undefined) return undefined; + if (runtimeChunk === undefined) return; if (runtimeChunk === false) return false; if (runtimeChunk === "single") { return { @@ -480,6 +543,10 @@ const getNormalizedOptimizationRuntimeChunk = runtimeChunk => { } if (runtimeChunk === true || runtimeChunk === "multiple") { return { + /** + * @param {Entrypoint} entrypoint entrypoint + * @returns {string} runtime chunk name + */ name: entrypoint => `runtime~${entrypoint.name}` }; } @@ -489,4 +556,4 @@ const getNormalizedOptimizationRuntimeChunk = runtimeChunk => { }; }; -exports.getNormalizedWebpackOptions = getNormalizedWebpackOptions; +module.exports.getNormalizedWebpackOptions = getNormalizedWebpackOptions; diff --git a/lib/config/target.js b/lib/config/target.js index 60c543c602f..bd1de948ba2 100644 --- a/lib/config/target.js +++ b/lib/config/target.js @@ -5,19 +5,23 @@ "use strict"; -const browserslistTargetHandler = require("./browserslistTargetHandler"); +const memoize = require("../util/memoize"); + +const getBrowserslistTargetHandler = memoize(() => + require("./browserslistTargetHandler") +); /** * @param {string} context the context directory * @returns {string} default target */ const getDefaultTarget = context => { - const browsers = browserslistTargetHandler.load(null, context); + const browsers = getBrowserslistTargetHandler().load(null, context); return browsers ? "browserslist" : "web"; }; /** - * @typedef {Object} PlatformTargetProperties + * @typedef {object} PlatformTargetProperties * @property {boolean | null} web web platform, importing of http(s) and std: is available * @property {boolean | null} browser browser platform, running in a normal web browser * @property {boolean | null} webworker (Web)Worker platform, running in a web/shared/service worker @@ -27,16 +31,17 @@ const getDefaultTarget = context => { */ /** - * @typedef {Object} ElectronContextTargetProperties + * @typedef {object} ElectronContextTargetProperties * @property {boolean | null} electronMain in main context * @property {boolean | null} electronPreload in preload context * @property {boolean | null} electronRenderer in renderer context with node integration */ /** - * @typedef {Object} ApiTargetProperties + * @typedef {object} ApiTargetProperties * @property {boolean | null} require has require function available * @property {boolean | null} nodeBuiltins has node.js built-in modules available + * @property {boolean | null} nodePrefixForCoreModules node.js allows to use `node:` prefix for core modules * @property {boolean | null} document has document available (allows script tags) * @property {boolean | null} importScripts has importScripts available * @property {boolean | null} importScriptsInWorker has importScripts available when creating a worker @@ -45,7 +50,7 @@ const getDefaultTarget = context => { */ /** - * @typedef {Object} EcmaTargetProperties + * @typedef {object} EcmaTargetProperties * @property {boolean | null} globalThis has globalThis variable available * @property {boolean | null} bigIntLiteral big int literal syntax is available * @property {boolean | null} const const and let variable declarations are available @@ -55,29 +60,49 @@ const getDefaultTarget = context => { * @property {boolean | null} dynamicImport async import() is available * @property {boolean | null} dynamicImportInWorker async import() is available when creating a worker * @property {boolean | null} module ESM syntax is available (when in module) + * @property {boolean | null} optionalChaining optional chaining is available + * @property {boolean | null} templateLiteral template literal is available + * @property {boolean | null} asyncFunction async functions and await are available + */ + +/** + * @template T + * @typedef {{ [P in keyof T]?: never }} Never + */ + +/** + * @template A + * @template B + * @typedef {(A & Never) | (Never & B) | (A & B)} Mix */ -///** @typedef {PlatformTargetProperties | ApiTargetProperties | EcmaTargetProperties | PlatformTargetProperties & ApiTargetProperties | PlatformTargetProperties & EcmaTargetProperties | ApiTargetProperties & EcmaTargetProperties} TargetProperties */ -/** @template T @typedef {{ [P in keyof T]?: never }} Never */ -/** @template A @template B @typedef {(A & Never) | (Never & B) | (A & B)} Mix */ /** @typedef {Mix, Mix>} TargetProperties */ +/** + * @param {string} major major version + * @param {string | undefined} minor minor version + * @returns {(vMajor: number, vMinor?: number) => boolean | undefined} check if version is greater or equal + */ const versionDependent = (major, minor) => { - if (!major) return () => /** @type {undefined} */ (undefined); - major = +major; - minor = minor ? +minor : 0; - return (vMajor, vMinor = 0) => { - return major > vMajor || (major === vMajor && minor >= vMinor); - }; + if (!major) { + return () => /** @type {undefined} */ (undefined); + } + /** @type {number} */ + const nMajor = Number(major); + /** @type {number} */ + const nMinor = minor ? Number(minor) : 0; + return (vMajor, vMinor = 0) => + nMajor > vMajor || (nMajor === vMajor && nMinor >= vMinor); }; -/** @type {[string, string, RegExp, (...args: string[]) => TargetProperties | false][]} */ +/** @type {[string, string, RegExp, (...args: string[]) => Partial][]} */ const TARGETS = [ [ "browserslist / browserslist:env / browserslist:query / browserslist:path-to-config / browserslist:path-to-config:env", "Resolve features from browserslist. Will resolve browserslist config automatically. Only browser or node queries are supported (electron is not supported). Examples: 'browserslist:modern' to use 'modern' environment from browserslist config", /^browserslist(?::(.+))?$/, (rest, context) => { + const browserslistTargetHandler = getBrowserslistTargetHandler(); const browsers = browserslistTargetHandler.load( rest ? rest.trim() : null, context @@ -88,6 +113,7 @@ See https://github.com/browserslist/browserslist#queries for possible ways to pr The recommended way is to add a 'browserslist' key to your package.json and list supported browsers (resp. node.js versions). You can also more options via the 'target' option: 'browserslist' / 'browserslist:env' / 'browserslist:query' / 'browserslist:path-to-config' / 'browserslist:path-to-config:env'`); } + return browserslistTargetHandler.resolve(browsers); } ], @@ -95,53 +121,49 @@ You can also more options via the 'target' option: 'browserslist' / 'browserslis "web", "Web browser.", /^web$/, - () => { - return { - web: true, - browser: true, - webworker: null, - node: false, - electron: false, - nwjs: false, + () => ({ + web: true, + browser: true, + webworker: null, + node: false, + electron: false, + nwjs: false, - document: true, - importScriptsInWorker: true, - fetchWasm: true, - nodeBuiltins: false, - importScripts: false, - require: false, - global: false - }; - } + document: true, + importScriptsInWorker: true, + fetchWasm: true, + nodeBuiltins: false, + importScripts: false, + require: false, + global: false + }) ], [ "webworker", "Web Worker, SharedWorker or Service Worker.", /^webworker$/, - () => { - return { - web: true, - browser: true, - webworker: true, - node: false, - electron: false, - nwjs: false, + () => ({ + web: true, + browser: true, + webworker: true, + node: false, + electron: false, + nwjs: false, - importScripts: true, - importScriptsInWorker: true, - fetchWasm: true, - nodeBuiltins: false, - require: false, - document: false, - global: false - }; - } + importScripts: true, + importScriptsInWorker: true, + fetchWasm: true, + nodeBuiltins: false, + require: false, + document: false, + global: false + }) ], [ "[async-]node[X[.Y]]", "Node.js in version X.Y. The 'async-' prefix will load chunks asynchronously via 'fs' and 'vm' instead of 'require()'. Examples: node14.5, async-node10.", - /^(async-)?node(\d+(?:\.(\d+))?)?$/, - (asyncFlag, major, minor) => { + /^(async-)?node((\d+)(?:\.(\d+))?)?$/, + (asyncFlag, _, major, minor) => { const v = versionDependent(major, minor); // see https://node.green/ return { @@ -154,6 +176,8 @@ You can also more options via the 'target' option: 'browserslist' / 'browserslis require: !asyncFlag, nodeBuiltins: true, + // v16.0.0, v14.18.0 + nodePrefixForCoreModules: Number(major) < 15 ? v(14, 18) : v(16), global: true, document: false, fetchWasm: false, @@ -162,7 +186,10 @@ You can also more options via the 'target' option: 'browserslist' / 'browserslis globalThis: v(12), const: v(6), + templateLiteral: v(4), + optionalChaining: v(14), arrowFunction: v(6), + asyncFunction: v(7, 6), forOf: v(5), destructuring: v(6), bigIntLiteral: v(10, 4), @@ -175,8 +202,8 @@ You can also more options via the 'target' option: 'browserslist' / 'browserslis [ "electron[X[.Y]]-main/preload/renderer", "Electron in version X.Y. Script is running in main, preload resp. renderer context.", - /^electron(\d+(?:\.(\d+))?)?-(main|preload|renderer)$/, - (major, minor, context) => { + /^electron((\d+)(?:\.(\d+))?)?-(main|preload|renderer)$/, + (_, major, minor, context) => { const v = versionDependent(major, minor); // see https://node.green/ + https://github.com/electron/releases return { @@ -193,6 +220,10 @@ You can also more options via the 'target' option: 'browserslist' / 'browserslis global: true, nodeBuiltins: true, + // 15.0.0 - Node.js v16.5 + // 14.0.0 - Mode.js v14.17, but prefixes only since v14.18 + nodePrefixForCoreModules: v(15), + require: true, document: context === "renderer", fetchWasm: context === "renderer", @@ -201,7 +232,10 @@ You can also more options via the 'target' option: 'browserslist' / 'browserslis globalThis: v(5), const: v(1, 1), + templateLiteral: v(1, 1), + optionalChaining: v(8), arrowFunction: v(1, 1), + asyncFunction: v(1, 7), forOf: v(0, 36), destructuring: v(1, 1), bigIntLiteral: v(4), @@ -214,8 +248,8 @@ You can also more options via the 'target' option: 'browserslist' / 'browserslis [ "nwjs[X[.Y]] / node-webkit[X[.Y]]", "NW.js in version X.Y.", - /^(?:nwjs|node-webkit)(\d+(?:\.(\d+))?)?$/, - (major, minor) => { + /^(?:nwjs|node-webkit)((\d+)(?:\.(\d+))?)?$/, + (_, major, minor) => { const v = versionDependent(major, minor); // see https://node.green/ + https://github.com/nwjs/nw.js/blob/nw48/CHANGELOG.md return { @@ -236,7 +270,10 @@ You can also more options via the 'target' option: 'browserslist' / 'browserslis globalThis: v(0, 43), const: v(0, 15), + templateLiteral: v(0, 13), + optionalChaining: v(0, 44), arrowFunction: v(0, 15), + asyncFunction: v(0, 21), forOf: v(0, 13), destructuring: v(0, 15), bigIntLiteral: v(0, 32), @@ -251,14 +288,17 @@ You can also more options via the 'target' option: 'browserslist' / 'browserslis "EcmaScript in this version. Examples: es2020, es5.", /^es(\d+)$/, version => { - let v = +version; + let v = Number(version); if (v < 1000) v = v + 2009; return { const: v >= 2015, + templateLiteral: v >= 2015, + optionalChaining: v >= 2020, arrowFunction: v >= 2015, forOf: v >= 2015, destructuring: v >= 2015, module: v >= 2015, + asyncFunction: v >= 2017, globalThis: v >= 2020, bigIntLiteral: v >= 2020, dynamicImport: v >= 2020, @@ -279,7 +319,7 @@ const getTargetProperties = (target, context) => { if (match) { const [, ...args] = match; const result = handler(...args, context); - if (result) return result; + if (result) return /** @type {TargetProperties} */ (result); } } throw new Error( @@ -289,13 +329,19 @@ const getTargetProperties = (target, context) => { ); }; +/** + * @param {TargetProperties[]} targetProperties array of target properties + * @returns {TargetProperties} merged target properties + */ const mergeTargetProperties = targetProperties => { + /** @type {Set} */ const keys = new Set(); for (const tp of targetProperties) { for (const key of Object.keys(tp)) { - keys.add(key); + keys.add(/** @type {keyof TargetProperties} */ (key)); } } + /** @type {object} */ const result = {}; for (const key of keys) { let hasTrue = false; @@ -312,7 +358,8 @@ const mergeTargetProperties = targetProperties => { } } if (hasTrue || hasFalse) - result[key] = hasFalse && hasTrue ? null : hasTrue ? true : false; + /** @type {TargetProperties} */ + (result)[key] = hasFalse && hasTrue ? null : Boolean(hasTrue); } return /** @type {TargetProperties} */ (result); }; @@ -322,12 +369,9 @@ const mergeTargetProperties = targetProperties => { * @param {string} context the context directory * @returns {TargetProperties} target properties */ -const getTargetsProperties = (targets, context) => { - return mergeTargetProperties( - targets.map(t => getTargetProperties(t, context)) - ); -}; +const getTargetsProperties = (targets, context) => + mergeTargetProperties(targets.map(t => getTargetProperties(t, context))); -exports.getDefaultTarget = getDefaultTarget; -exports.getTargetProperties = getTargetProperties; -exports.getTargetsProperties = getTargetsProperties; +module.exports.getDefaultTarget = getDefaultTarget; +module.exports.getTargetProperties = getTargetProperties; +module.exports.getTargetsProperties = getTargetsProperties; diff --git a/lib/container/ContainerEntryDependency.js b/lib/container/ContainerEntryDependency.js index e8aad08b6c5..787d99cffac 100644 --- a/lib/container/ContainerEntryDependency.js +++ b/lib/container/ContainerEntryDependency.js @@ -9,11 +9,12 @@ const Dependency = require("../Dependency"); const makeSerializable = require("../util/makeSerializable"); /** @typedef {import("./ContainerEntryModule").ExposeOptions} ExposeOptions */ +/** @typedef {import("./ContainerEntryModule").ExposesList} ExposesList */ class ContainerEntryDependency extends Dependency { /** * @param {string} name entry name - * @param {[string, ExposeOptions][]} exposes list of exposed modules + * @param {ExposesList} exposes list of exposed modules * @param {string} shareScope name of the share scope */ constructor(name, exposes, shareScope) { diff --git a/lib/container/ContainerEntryModule.js b/lib/container/ContainerEntryModule.js index e592ce480e5..789abf29778 100644 --- a/lib/container/ContainerEntryModule.js +++ b/lib/container/ContainerEntryModule.js @@ -8,8 +8,10 @@ const { OriginalSource, RawSource } = require("webpack-sources"); const AsyncDependenciesBlock = require("../AsyncDependenciesBlock"); const Module = require("../Module"); +const { JAVASCRIPT_MODULE_TYPE_DYNAMIC } = require("../ModuleTypeConstants"); const RuntimeGlobals = require("../RuntimeGlobals"); const Template = require("../Template"); +const StaticExportsDependency = require("../dependencies/StaticExportsDependency"); const makeSerializable = require("../util/makeSerializable"); const ContainerExposedDependency = require("./ContainerExposedDependency"); @@ -21,36 +23,41 @@ const ContainerExposedDependency = require("./ContainerExposedDependency"); /** @typedef {import("../Module").CodeGenerationResult} CodeGenerationResult */ /** @typedef {import("../Module").LibIdentOptions} LibIdentOptions */ /** @typedef {import("../Module").NeedBuildContext} NeedBuildContext */ +/** @typedef {import("../Module").SourceTypes} SourceTypes */ /** @typedef {import("../RequestShortener")} RequestShortener */ /** @typedef {import("../ResolverFactory").ResolverWithOptions} ResolverWithOptions */ /** @typedef {import("../WebpackError")} WebpackError */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */ /** @typedef {import("../util/Hash")} Hash */ /** @typedef {import("../util/fs").InputFileSystem} InputFileSystem */ /** @typedef {import("./ContainerEntryDependency")} ContainerEntryDependency */ /** - * @typedef {Object} ExposeOptions + * @typedef {object} ExposeOptions * @property {string[]} import requests to exposed modules (last one is exported) * @property {string} name custom chunk name for the exposed module */ +/** @typedef {[string, ExposeOptions][]} ExposesList */ + const SOURCE_TYPES = new Set(["javascript"]); class ContainerEntryModule extends Module { /** * @param {string} name container entry name - * @param {[string, ExposeOptions][]} exposes list of exposed modules + * @param {ExposesList} exposes list of exposed modules * @param {string} shareScope name of the share scope */ constructor(name, exposes, shareScope) { - super("javascript/dynamic", null); + super(JAVASCRIPT_MODULE_TYPE_DYNAMIC, null); this._name = name; this._exposes = exposes; this._shareScope = shareScope; } /** - * @returns {Set} types available (do not mutate) + * @returns {SourceTypes} types available (do not mutate) */ getSourceTypes() { return SOURCE_TYPES; @@ -70,7 +77,7 @@ class ContainerEntryModule extends Module { * @returns {string} a user readable identifier of the module */ readableIdentifier(requestShortener) { - return `container entry`; + return "container entry"; } /** @@ -78,12 +85,14 @@ class ContainerEntryModule extends Module { * @returns {string | null} an identifier for library inclusion */ libIdent(options) { - return `webpack/container/entry/${this._name}`; + return `${this.layer ? `(${this.layer})/` : ""}webpack/container/entry/${ + this._name + }`; } /** * @param {NeedBuildContext} context context info - * @param {function(WebpackError=, boolean=): void} callback callback function, returns true, if the module needs a rebuild + * @param {function((WebpackError | null)=, boolean=): void} callback callback function, returns true, if the module needs a rebuild * @returns {void} */ needBuild(context, callback) { @@ -104,6 +113,7 @@ class ContainerEntryModule extends Module { strict: true, topLevelDeclarations: new Set(["moduleMap", "get", "init"]) }; + this.buildMeta.exportsType = "namespace"; this.clearDependenciesAndBlocks(); @@ -127,6 +137,7 @@ class ContainerEntryModule extends Module { } this.addBlock(block); } + this.addDependency(new StaticExportsDependency(["get", "init"], false)); callback(); } @@ -194,7 +205,7 @@ class ContainerEntryModule extends Module { } const source = Template.asString([ - `var moduleMap = {`, + "var moduleMap = {", Template.indent(getters.join(",\n")), "};", `var get = ${runtimeTemplate.basicFunction("module, getScope", [ @@ -217,10 +228,8 @@ class ContainerEntryModule extends Module { ])};`, `var init = ${runtimeTemplate.basicFunction("shareScope, initScope", [ `if (!${RuntimeGlobals.shareScopeMap}) return;`, - `var oldScope = ${RuntimeGlobals.shareScopeMap}[${JSON.stringify( - this._shareScope - )}];`, `var name = ${JSON.stringify(this._shareScope)}`, + `var oldScope = ${RuntimeGlobals.shareScopeMap}[name];`, `if(oldScope && oldScope !== shareScope) throw new Error("Container initialization failed as it has already been initialized with a different share scope");`, `${RuntimeGlobals.shareScopeMap}[name] = shareScope;`, `return ${RuntimeGlobals.initializeSharing}(name, initScope);` @@ -256,6 +265,9 @@ class ContainerEntryModule extends Module { return 42; } + /** + * @param {ObjectSerializerContext} context context + */ serialize(context) { const { write } = context; write(this._name); @@ -264,6 +276,10 @@ class ContainerEntryModule extends Module { super.serialize(context); } + /** + * @param {ObjectDeserializerContext} context context + * @returns {ContainerEntryModule} deserialized container entry module + */ static deserialize(context) { const { read } = context; const obj = new ContainerEntryModule(read(), read(), read()); diff --git a/lib/container/ContainerEntryModuleFactory.js b/lib/container/ContainerEntryModuleFactory.js index 1a1a7af894e..4febfebe059 100644 --- a/lib/container/ContainerEntryModuleFactory.js +++ b/lib/container/ContainerEntryModuleFactory.js @@ -15,7 +15,7 @@ const ContainerEntryModule = require("./ContainerEntryModule"); module.exports = class ContainerEntryModuleFactory extends ModuleFactory { /** * @param {ModuleFactoryCreateData} data data object - * @param {function(Error=, ModuleFactoryResult=): void} callback callback + * @param {function((Error | null)=, ModuleFactoryResult=): void} callback callback * @returns {void} */ create({ dependencies: [dependency] }, callback) { diff --git a/lib/container/ContainerExposedDependency.js b/lib/container/ContainerExposedDependency.js index 02b9eef3c9b..2cbf04a694d 100644 --- a/lib/container/ContainerExposedDependency.js +++ b/lib/container/ContainerExposedDependency.js @@ -8,6 +8,9 @@ const ModuleDependency = require("../dependencies/ModuleDependency"); const makeSerializable = require("../util/makeSerializable"); +/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */ + class ContainerExposedDependency extends ModuleDependency { /** * @param {string} exposedName public name @@ -33,11 +36,17 @@ class ContainerExposedDependency extends ModuleDependency { return `exposed dependency ${this.exposedName}=${this.request}`; } + /** + * @param {ObjectSerializerContext} context context + */ serialize(context) { context.write(this.exposedName); super.serialize(context); } + /** + * @param {ObjectDeserializerContext} context context + */ deserialize(context) { this.exposedName = context.read(); super.deserialize(context); diff --git a/lib/container/ContainerPlugin.js b/lib/container/ContainerPlugin.js index a9491f032c4..953e7c39290 100644 --- a/lib/container/ContainerPlugin.js +++ b/lib/container/ContainerPlugin.js @@ -5,8 +5,7 @@ "use strict"; -const { validate } = require("schema-utils"); -const schema = require("../../schemas/plugins/container/ContainerPlugin.json"); +const createSchemaValidation = require("../util/create-schema-validation"); const ContainerEntryDependency = require("./ContainerEntryDependency"); const ContainerEntryModuleFactory = require("./ContainerEntryModuleFactory"); const ContainerExposedDependency = require("./ContainerExposedDependency"); @@ -14,6 +13,17 @@ const { parseOptions } = require("./options"); /** @typedef {import("../../declarations/plugins/container/ContainerPlugin").ContainerPluginOptions} ContainerPluginOptions */ /** @typedef {import("../Compiler")} Compiler */ +/** @typedef {import("./ContainerEntryModule").ExposeOptions} ExposeOptions */ +/** @typedef {import("./ContainerEntryModule").ExposesList} ExposesList */ + +const validate = createSchemaValidation( + require("../../schemas/plugins/container/ContainerPlugin.check.js"), + () => require("../../schemas/plugins/container/ContainerPlugin.json"), + { + name: "Container Plugin", + baseDataPath: "options" + } +); const PLUGIN_NAME = "ContainerPlugin"; @@ -22,7 +32,7 @@ class ContainerPlugin { * @param {ContainerPluginOptions} options options */ constructor(options) { - validate(schema, options, { name: "Container Plugin" }); + validate(options); this._options = { name: options.name, @@ -31,17 +41,20 @@ class ContainerPlugin { type: "var", name: options.name }, + runtime: options.runtime, filename: options.filename || undefined, - exposes: parseOptions( - options.exposes, - item => ({ - import: Array.isArray(item) ? item : [item], - name: undefined - }), - item => ({ - import: Array.isArray(item.import) ? item.import : [item.import], - name: item.name || undefined - }) + exposes: /** @type {ExposesList} */ ( + parseOptions( + options.exposes, + item => ({ + import: Array.isArray(item) ? item : [item], + name: undefined + }), + item => ({ + import: Array.isArray(item.import) ? item.import : [item.import], + name: item.name || undefined + }) + ) ) }; } @@ -52,19 +65,23 @@ class ContainerPlugin { * @returns {void} */ apply(compiler) { - const { name, exposes, shareScope, filename, library } = this._options; + const { name, exposes, shareScope, filename, library, runtime } = + this._options; - compiler.options.output.enabledLibraryTypes.push(library.type); + if (!compiler.options.output.enabledLibraryTypes.includes(library.type)) { + compiler.options.output.enabledLibraryTypes.push(library.type); + } compiler.hooks.make.tapAsync(PLUGIN_NAME, (compilation, callback) => { const dep = new ContainerEntryDependency(name, exposes, shareScope); dep.loc = { name }; compilation.addEntry( - compilation.options.context, + /** @type {string} */ (compilation.options.context), dep, { name, filename, + runtime, library }, error => { diff --git a/lib/container/ContainerReferencePlugin.js b/lib/container/ContainerReferencePlugin.js index f82fb0b81f5..59657c1ffd7 100644 --- a/lib/container/ContainerReferencePlugin.js +++ b/lib/container/ContainerReferencePlugin.js @@ -5,10 +5,9 @@ "use strict"; -const { validate } = require("schema-utils"); -const schema = require("../../schemas/plugins/container/ContainerReferencePlugin.json"); const ExternalsPlugin = require("../ExternalsPlugin"); const RuntimeGlobals = require("../RuntimeGlobals"); +const createSchemaValidation = require("../util/create-schema-validation"); const FallbackDependency = require("./FallbackDependency"); const FallbackItemDependency = require("./FallbackItemDependency"); const FallbackModuleFactory = require("./FallbackModuleFactory"); @@ -21,6 +20,16 @@ const { parseOptions } = require("./options"); /** @typedef {import("../../declarations/plugins/container/ContainerReferencePlugin").RemotesConfig} RemotesConfig */ /** @typedef {import("../Compiler")} Compiler */ +const validate = createSchemaValidation( + require("../../schemas/plugins/container/ContainerReferencePlugin.check.js"), + () => + require("../../schemas/plugins/container/ContainerReferencePlugin.json"), + { + name: "Container Reference Plugin", + baseDataPath: "options" + } +); + const slashCode = "/".charCodeAt(0); class ContainerReferencePlugin { @@ -28,7 +37,7 @@ class ContainerReferencePlugin { * @param {ContainerReferencePluginOptions} options options */ constructor(options) { - validate(schema, options, { name: "Container Reference Plugin" }); + validate(options); this._remoteType = options.remoteType; this._remotes = parseOptions( @@ -104,7 +113,7 @@ class ContainerReferencePlugin { ? external.slice(9) : `webpack/container/reference/${key}${ i ? `/fallback-${i}` : "" - }` + }` ), `.${data.request.slice(key.length)}`, config.shareScope diff --git a/lib/container/FallbackDependency.js b/lib/container/FallbackDependency.js index dee28ab33fa..088720f5e32 100644 --- a/lib/container/FallbackDependency.js +++ b/lib/container/FallbackDependency.js @@ -8,7 +8,13 @@ const Dependency = require("../Dependency"); const makeSerializable = require("../util/makeSerializable"); +/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */ + class FallbackDependency extends Dependency { + /** + * @param {string[]} requests requests + */ constructor(requests) { super(); this.requests = requests; @@ -29,12 +35,19 @@ class FallbackDependency extends Dependency { return "esm"; } + /** + * @param {ObjectSerializerContext} context context + */ serialize(context) { const { write } = context; write(this.requests); super.serialize(context); } + /** + * @param {ObjectDeserializerContext} context context + * @returns {FallbackDependency} deserialize fallback dependency + */ static deserialize(context) { const { read } = context; const obj = new FallbackDependency(read()); diff --git a/lib/container/FallbackItemDependency.js b/lib/container/FallbackItemDependency.js index 3995a9e79ef..f09f8cf8c3c 100644 --- a/lib/container/FallbackItemDependency.js +++ b/lib/container/FallbackItemDependency.js @@ -9,6 +9,9 @@ const ModuleDependency = require("../dependencies/ModuleDependency"); const makeSerializable = require("../util/makeSerializable"); class FallbackItemDependency extends ModuleDependency { + /** + * @param {string} request request + */ constructor(request) { super(request); } diff --git a/lib/container/FallbackModule.js b/lib/container/FallbackModule.js index cc51cae27fa..59bf27c92ee 100644 --- a/lib/container/FallbackModule.js +++ b/lib/container/FallbackModule.js @@ -7,6 +7,7 @@ const { RawSource } = require("webpack-sources"); const Module = require("../Module"); +const { WEBPACK_MODULE_TYPE_FALLBACK } = require("../ModuleTypeConstants"); const RuntimeGlobals = require("../RuntimeGlobals"); const Template = require("../Template"); const makeSerializable = require("../util/makeSerializable"); @@ -21,9 +22,12 @@ const FallbackItemDependency = require("./FallbackItemDependency"); /** @typedef {import("../Module").CodeGenerationResult} CodeGenerationResult */ /** @typedef {import("../Module").LibIdentOptions} LibIdentOptions */ /** @typedef {import("../Module").NeedBuildContext} NeedBuildContext */ +/** @typedef {import("../Module").SourceTypes} SourceTypes */ /** @typedef {import("../RequestShortener")} RequestShortener */ /** @typedef {import("../ResolverFactory").ResolverWithOptions} ResolverWithOptions */ /** @typedef {import("../WebpackError")} WebpackError */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */ /** @typedef {import("../util/Hash")} Hash */ /** @typedef {import("../util/fs").InputFileSystem} InputFileSystem */ @@ -35,7 +39,7 @@ class FallbackModule extends Module { * @param {string[]} requests list of requests to choose one */ constructor(requests) { - super("fallback-module"); + super(WEBPACK_MODULE_TYPE_FALLBACK); this.requests = requests; this._identifier = `fallback ${this.requests.join(" ")}`; } @@ -60,9 +64,9 @@ class FallbackModule extends Module { * @returns {string | null} an identifier for library inclusion */ libIdent(options) { - return `webpack/container/fallback/${this.requests[0]}/and ${ - this.requests.length - 1 - } more`; + return `${this.layer ? `(${this.layer})/` : ""}webpack/container/fallback/${ + this.requests[0] + }/and ${this.requests.length - 1} more`; } /** @@ -76,7 +80,7 @@ class FallbackModule extends Module { /** * @param {NeedBuildContext} context context info - * @param {function(WebpackError=, boolean=): void} callback callback function, returns true, if the module needs a rebuild + * @param {function((WebpackError | null)=, boolean=): void} callback callback function, returns true, if the module needs a rebuild * @returns {void} */ needBuild(context, callback) { @@ -113,7 +117,7 @@ class FallbackModule extends Module { } /** - * @returns {Set} types available (do not mutate) + * @returns {SourceTypes} types available (do not mutate) */ getSourceTypes() { return TYPES; @@ -125,7 +129,7 @@ class FallbackModule extends Module { */ codeGeneration({ runtimeTemplate, moduleGraph, chunkGraph }) { const ids = this.dependencies.map(dep => - chunkGraph.getModuleId(moduleGraph.getModule(dep)) + chunkGraph.getModuleId(/** @type {Module} */ (moduleGraph.getModule(dep))) ); const code = Template.asString([ `var ids = ${JSON.stringify(ids)};`, @@ -133,7 +137,7 @@ class FallbackModule extends Module { `var loop = ${runtimeTemplate.basicFunction("next", [ "while(i < ids.length) {", Template.indent([ - "try { next = __webpack_require__(ids[i++]); } catch(e) { return handleError(e); }", + `try { next = ${RuntimeGlobals.require}(ids[i++]); } catch(e) { return handleError(e); }`, "if(next) return next.then ? next.then(handleResult, handleError) : handleResult(next);" ]), "}", @@ -154,12 +158,19 @@ class FallbackModule extends Module { return { sources, runtimeRequirements: RUNTIME_REQUIREMENTS }; } + /** + * @param {ObjectSerializerContext} context context + */ serialize(context) { const { write } = context; write(this.requests); super.serialize(context); } + /** + * @param {ObjectDeserializerContext} context context + * @returns {FallbackModule} deserialized fallback module + */ static deserialize(context) { const { read } = context; const obj = new FallbackModule(read()); diff --git a/lib/container/FallbackModuleFactory.js b/lib/container/FallbackModuleFactory.js index 350e910b9fe..6a9eaeca0ae 100644 --- a/lib/container/FallbackModuleFactory.js +++ b/lib/container/FallbackModuleFactory.js @@ -15,7 +15,7 @@ const FallbackModule = require("./FallbackModule"); module.exports = class FallbackModuleFactory extends ModuleFactory { /** * @param {ModuleFactoryCreateData} data data object - * @param {function(Error=, ModuleFactoryResult=): void} callback callback + * @param {function((Error | null)=, ModuleFactoryResult=): void} callback callback * @returns {void} */ create({ dependencies: [dependency] }, callback) { diff --git a/lib/container/ModuleFederationPlugin.js b/lib/container/ModuleFederationPlugin.js index 001e3ed04c6..3652bf58832 100644 --- a/lib/container/ModuleFederationPlugin.js +++ b/lib/container/ModuleFederationPlugin.js @@ -5,9 +5,9 @@ "use strict"; -const { validate } = require("schema-utils"); -const schema = require("../../schemas/plugins/container/ModuleFederationPlugin.json"); +const isValidExternalsType = require("../../schemas/plugins/container/ExternalsType.check.js"); const SharePlugin = require("../sharing/SharePlugin"); +const createSchemaValidation = require("../util/create-schema-validation"); const ContainerPlugin = require("./ContainerPlugin"); const ContainerReferencePlugin = require("./ContainerReferencePlugin"); @@ -16,12 +16,20 @@ const ContainerReferencePlugin = require("./ContainerReferencePlugin"); /** @typedef {import("../../declarations/plugins/container/ModuleFederationPlugin").Shared} Shared */ /** @typedef {import("../Compiler")} Compiler */ +const validate = createSchemaValidation( + require("../../schemas/plugins/container/ModuleFederationPlugin.check.js"), + () => require("../../schemas/plugins/container/ModuleFederationPlugin.json"), + { + name: "Module Federation Plugin", + baseDataPath: "options" + } +); class ModuleFederationPlugin { /** * @param {ModuleFederationPluginOptions} options options */ constructor(options) { - validate(schema, options, { name: "Module Federation Plugin" }); + validate(options); this._options = options; } @@ -36,8 +44,7 @@ class ModuleFederationPlugin { const library = options.library || { type: "var", name: options.name }; const remoteType = options.remoteType || - (options.library && - schema.definitions.ExternalsType.enum.includes(options.library.type) + (options.library && isValidExternalsType(options.library.type) ? /** @type {ExternalsType} */ (options.library.type) : "script"); if ( @@ -57,6 +64,8 @@ class ModuleFederationPlugin { name: options.name, library, filename: options.filename, + runtime: options.runtime, + shareScope: options.shareScope, exposes: options.exposes }).apply(compiler); } @@ -68,6 +77,7 @@ class ModuleFederationPlugin { ) { new ContainerReferencePlugin({ remoteType, + shareScope: options.shareScope, remotes: options.remotes }).apply(compiler); } diff --git a/lib/container/RemoteModule.js b/lib/container/RemoteModule.js index b2bea8e33af..86e4acc2b7e 100644 --- a/lib/container/RemoteModule.js +++ b/lib/container/RemoteModule.js @@ -7,6 +7,7 @@ const { RawSource } = require("webpack-sources"); const Module = require("../Module"); +const { WEBPACK_MODULE_TYPE_REMOTE } = require("../ModuleTypeConstants"); const RuntimeGlobals = require("../RuntimeGlobals"); const makeSerializable = require("../util/makeSerializable"); const FallbackDependency = require("./FallbackDependency"); @@ -20,9 +21,12 @@ const RemoteToExternalDependency = require("./RemoteToExternalDependency"); /** @typedef {import("../Module").CodeGenerationResult} CodeGenerationResult */ /** @typedef {import("../Module").LibIdentOptions} LibIdentOptions */ /** @typedef {import("../Module").NeedBuildContext} NeedBuildContext */ +/** @typedef {import("../Module").SourceTypes} SourceTypes */ /** @typedef {import("../RequestShortener")} RequestShortener */ /** @typedef {import("../ResolverFactory").ResolverWithOptions} ResolverWithOptions */ /** @typedef {import("../WebpackError")} WebpackError */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */ /** @typedef {import("../util/Hash")} Hash */ /** @typedef {import("../util/fs").InputFileSystem} InputFileSystem */ @@ -37,7 +41,7 @@ class RemoteModule extends Module { * @param {string} shareScope the used share scope name */ constructor(request, externalRequests, internalRequest, shareScope) { - super("remote-module"); + super(WEBPACK_MODULE_TYPE_REMOTE); this.request = request; this.externalRequests = externalRequests; this.internalRequest = internalRequest; @@ -67,12 +71,14 @@ class RemoteModule extends Module { * @returns {string | null} an identifier for library inclusion */ libIdent(options) { - return `webpack/container/remote/${this.request}`; + return `${this.layer ? `(${this.layer})/` : ""}webpack/container/remote/${ + this.request + }`; } /** * @param {NeedBuildContext} context context info - * @param {function(WebpackError=, boolean=): void} callback callback function, returns true, if the module needs a rebuild + * @param {function((WebpackError | null)=, boolean=): void} callback callback function, returns true, if the module needs a rebuild * @returns {void} */ needBuild(context, callback) { @@ -114,7 +120,7 @@ class RemoteModule extends Module { } /** - * @returns {Set} types available (do not mutate) + * @returns {SourceTypes} types available (do not mutate) */ getSourceTypes() { return TYPES; @@ -147,6 +153,9 @@ class RemoteModule extends Module { return { sources, data, runtimeRequirements: RUNTIME_REQUIREMENTS }; } + /** + * @param {ObjectSerializerContext} context context + */ serialize(context) { const { write } = context; write(this.request); @@ -156,6 +165,10 @@ class RemoteModule extends Module { super.serialize(context); } + /** + * @param {ObjectDeserializerContext} context context + * @returns {RemoteModule} deserialized module + */ static deserialize(context) { const { read } = context; const obj = new RemoteModule(read(), read(), read(), read()); diff --git a/lib/container/RemoteRuntimeModule.js b/lib/container/RemoteRuntimeModule.js index a1dc075439f..21370e304ae 100644 --- a/lib/container/RemoteRuntimeModule.js +++ b/lib/container/RemoteRuntimeModule.js @@ -9,6 +9,11 @@ const RuntimeGlobals = require("../RuntimeGlobals"); const RuntimeModule = require("../RuntimeModule"); const Template = require("../Template"); +/** @typedef {import("../Chunk")} Chunk */ +/** @typedef {import("../Chunk").ChunkId} ChunkId */ +/** @typedef {import("../ChunkGraph")} ChunkGraph */ +/** @typedef {import("../ChunkGraph").ModuleId} ModuleId */ +/** @typedef {import("../Compilation")} Compilation */ /** @typedef {import("./RemoteModule")} RemoteModule */ class RemoteRuntimeModule extends RuntimeModule { @@ -17,28 +22,37 @@ class RemoteRuntimeModule extends RuntimeModule { } /** - * @returns {string} runtime code + * @returns {string | null} runtime code */ generate() { - const { runtimeTemplate, chunkGraph, moduleGraph } = this.compilation; + const compilation = /** @type {Compilation} */ (this.compilation); + const chunkGraph = /** @type {ChunkGraph} */ (this.chunkGraph); + const { runtimeTemplate, moduleGraph } = compilation; + /** @type {Record} */ const chunkToRemotesMapping = {}; + /** @type {Record} */ const idToExternalAndNameMapping = {}; - for (const chunk of this.chunk.getAllAsyncChunks()) { + for (const chunk of /** @type {Chunk} */ (this.chunk).getAllAsyncChunks()) { const modules = chunkGraph.getChunkModulesIterableBySourceType( chunk, "remote" ); if (!modules) continue; - const remotes = (chunkToRemotesMapping[chunk.id] = []); + /** @type {ModuleId[]} */ + const remotes = (chunkToRemotesMapping[ + /** @type {ChunkId} */ + (chunk.id) + ] = []); for (const m of modules) { const module = /** @type {RemoteModule} */ (m); const name = module.internalRequest; - const id = chunkGraph.getModuleId(module); + const id = /** @type {ModuleId} */ (chunkGraph.getModuleId(module)); const shareScope = module.shareScope; const dep = module.dependencies[0]; const externalModule = moduleGraph.getModule(dep); const externalModuleId = - externalModule && chunkGraph.getModuleId(externalModule); + /** @type {ModuleId} */ + (externalModule && chunkGraph.getModuleId(externalModule)); remotes.push(id); idToExternalAndNameMapping[id] = [shareScope, name, externalModuleId]; } @@ -65,16 +79,16 @@ class RemoteRuntimeModule extends RuntimeModule { "var data = idToExternalAndNameMapping[id];", "if(getScope.indexOf(data) >= 0) return;", "getScope.push(data);", - `if(data.p) return promises.push(data.p);`, + "if(data.p) return promises.push(data.p);", `var onError = ${runtimeTemplate.basicFunction("error", [ 'if(!error) error = new Error("Container missing");', 'if(typeof error.message === "string")', Template.indent( `error.message += '\\nwhile loading "' + data[1] + '" from ' + data[2];` ), - `__webpack_modules__[id] = ${runtimeTemplate.basicFunction("", [ - "throw error;" - ])}`, + `${ + RuntimeGlobals.moduleFactories + }[id] = ${runtimeTemplate.basicFunction("", ["throw error;"])}`, "data.p = 0;" ])};`, `var handleFunction = ${runtimeTemplate.basicFunction( @@ -89,7 +103,7 @@ class RemoteRuntimeModule extends RuntimeModule { "next(result, d)", "result" )}, onError);`, - `if(first) promises.push(data.p = p); else return p;` + "if(first) promises.push(data.p = p); else return p;" ]), "} else {", Template.indent(["return next(promise, d, first);"]), @@ -105,17 +119,18 @@ class RemoteRuntimeModule extends RuntimeModule { "external, _, first" )};`, `var onInitialized = ${runtimeTemplate.returningFunction( - `handleFunction(external.get, data[1], getScope, 0, onFactory, first)`, + "handleFunction(external.get, data[1], getScope, 0, onFactory, first)", "_, external, first" )};`, `var onFactory = ${runtimeTemplate.basicFunction("factory", [ "data.p = 1;", - `__webpack_modules__[id] = ${runtimeTemplate.basicFunction( - "module", - ["module.exports = factory();"] - )}` + `${ + RuntimeGlobals.moduleFactories + }[id] = ${runtimeTemplate.basicFunction("module", [ + "module.exports = factory();" + ])}` ])};`, - "handleFunction(__webpack_require__, data[2], 0, 0, onExternal, 1);" + `handleFunction(${RuntimeGlobals.require}, data[2], 0, 0, onExternal, 1);` ])});` ]), "}" diff --git a/lib/container/RemoteToExternalDependency.js b/lib/container/RemoteToExternalDependency.js index 28a52f7715c..df7fd1f8158 100644 --- a/lib/container/RemoteToExternalDependency.js +++ b/lib/container/RemoteToExternalDependency.js @@ -9,6 +9,9 @@ const ModuleDependency = require("../dependencies/ModuleDependency"); const makeSerializable = require("../util/makeSerializable"); class RemoteToExternalDependency extends ModuleDependency { + /** + * @param {string} request request + */ constructor(request) { super(request); } diff --git a/lib/container/options.js b/lib/container/options.js index 8cd9698a0f3..cb7df0d55fb 100644 --- a/lib/container/options.js +++ b/lib/container/options.js @@ -5,7 +5,15 @@ "use strict"; -/** @template T @typedef {(string | Record)[] | Record} ContainerOptionsFormat */ +/** + * @template T + * @typedef {Record} Item + */ + +/** + * @template T + * @typedef {(string | Item)[] | Item} ContainerOptionsFormat + */ /** * @template T @@ -17,6 +25,9 @@ * @returns {void} */ const process = (options, normalizeSimple, normalizeOptions, fn) => { + /** + * @param {(string | Item)[]} items items + */ const array = items => { for (const item of items) { if (typeof item === "string") { @@ -28,6 +39,9 @@ const process = (options, normalizeSimple, normalizeOptions, fn) => { } } }; + /** + * @param {Item} obj an object + */ const object = obj => { for (const [key, value] of Object.entries(obj)) { if (typeof value === "string" || Array.isArray(value)) { @@ -38,7 +52,7 @@ const process = (options, normalizeSimple, normalizeOptions, fn) => { } }; if (!options) { - return; + // Do nothing } else if (Array.isArray(options)) { array(options); } else if (typeof options === "object") { @@ -87,5 +101,5 @@ const scope = (scope, options) => { return obj; }; -exports.parseOptions = parseOptions; -exports.scope = scope; +module.exports.parseOptions = parseOptions; +module.exports.scope = scope; diff --git a/lib/css/CssExportsGenerator.js b/lib/css/CssExportsGenerator.js new file mode 100644 index 00000000000..112aca22787 --- /dev/null +++ b/lib/css/CssExportsGenerator.js @@ -0,0 +1,203 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Sergey Melyukov @smelukov +*/ + +"use strict"; + +const { ReplaceSource, RawSource, ConcatSource } = require("webpack-sources"); +const { UsageState } = require("../ExportsInfo"); +const Generator = require("../Generator"); +const RuntimeGlobals = require("../RuntimeGlobals"); +const Template = require("../Template"); + +/** @typedef {import("webpack-sources").Source} Source */ +/** @typedef {import("../../declarations/WebpackOptions").CssGeneratorExportsConvention} CssGeneratorExportsConvention */ +/** @typedef {import("../../declarations/WebpackOptions").CssGeneratorLocalIdentName} CssGeneratorLocalIdentName */ +/** @typedef {import("../Dependency")} Dependency */ +/** @typedef {import("../DependencyTemplate").CssDependencyTemplateContext} DependencyTemplateContext */ +/** @typedef {import("../DependencyTemplate").CssExportsData} CssExportsData */ +/** @typedef {import("../Generator").GenerateContext} GenerateContext */ +/** @typedef {import("../Generator").UpdateHashContext} UpdateHashContext */ +/** @typedef {import("../Module").ConcatenationBailoutReasonContext} ConcatenationBailoutReasonContext */ +/** @typedef {import("../NormalModule")} NormalModule */ +/** @typedef {import("../util/Hash")} Hash */ + +/** + * @template T + * @typedef {import("../InitFragment")} InitFragment + */ + +const TYPES = new Set(["javascript"]); + +class CssExportsGenerator extends Generator { + /** + * @param {CssGeneratorExportsConvention | undefined} convention the convention of the exports name + * @param {CssGeneratorLocalIdentName | undefined} localIdentName css export local ident name + * @param {boolean} esModule whether to use ES modules syntax + */ + constructor(convention, localIdentName, esModule) { + super(); + /** @type {CssGeneratorExportsConvention | undefined} */ + this.convention = convention; + /** @type {CssGeneratorLocalIdentName | undefined} */ + this.localIdentName = localIdentName; + /** @type {boolean} */ + this.esModule = esModule; + } + + /** + * @param {NormalModule} module module for which the bailout reason should be determined + * @param {ConcatenationBailoutReasonContext} context context + * @returns {string | undefined} reason why this module can't be concatenated, undefined when it can be concatenated + */ + getConcatenationBailoutReason(module, context) { + if (!this.esModule) { + return "Module is not an ECMAScript module"; + } + // TODO webpack 6: remove /\[moduleid\]/.test + if ( + /\[id\]/.test(this.localIdentName) || + /\[moduleid\]/.test(this.localIdentName) + ) { + return "The localIdentName includes moduleId ([id] or [moduleid])"; + } + return undefined; + } + + /** + * @param {NormalModule} module module for which the code should be generated + * @param {GenerateContext} generateContext context for generate + * @returns {Source} generated code + */ + generate(module, generateContext) { + const source = new ReplaceSource(new RawSource("")); + /** @type {InitFragment[]} */ + const initFragments = []; + /** @type {CssExportsData} */ + const cssExportsData = { + esModule: this.esModule, + exports: new Map() + }; + + generateContext.runtimeRequirements.add(RuntimeGlobals.module); + + let chunkInitFragments; + const runtimeRequirements = new Set(); + + /** @type {DependencyTemplateContext} */ + const templateContext = { + runtimeTemplate: generateContext.runtimeTemplate, + dependencyTemplates: generateContext.dependencyTemplates, + moduleGraph: generateContext.moduleGraph, + chunkGraph: generateContext.chunkGraph, + module, + runtime: generateContext.runtime, + runtimeRequirements, + concatenationScope: generateContext.concatenationScope, + codeGenerationResults: generateContext.codeGenerationResults, + initFragments, + cssExportsData, + get chunkInitFragments() { + if (!chunkInitFragments) { + const data = generateContext.getData(); + chunkInitFragments = data.get("chunkInitFragments"); + if (!chunkInitFragments) { + chunkInitFragments = []; + data.set("chunkInitFragments", chunkInitFragments); + } + } + + return chunkInitFragments; + } + }; + + /** + * @param {Dependency} dependency the dependency + */ + const handleDependency = dependency => { + const constructor = /** @type {new (...args: any[]) => Dependency} */ ( + dependency.constructor + ); + const template = generateContext.dependencyTemplates.get(constructor); + if (!template) { + throw new Error( + `No template for dependency: ${dependency.constructor.name}` + ); + } + + template.apply(dependency, source, templateContext); + }; + + for (const dependency of module.dependencies) { + handleDependency(dependency); + } + + if (generateContext.concatenationScope) { + const source = new ConcatSource(); + const usedIdentifiers = new Set(); + for (const [name, v] of cssExportsData.exports) { + let identifier = Template.toIdentifier(name); + const i = 0; + while (usedIdentifiers.has(identifier)) { + identifier = Template.toIdentifier(name + i); + } + usedIdentifiers.add(identifier); + generateContext.concatenationScope.registerExport(name, identifier); + source.add( + `${ + generateContext.runtimeTemplate.supportsConst() ? "const" : "var" + } ${identifier} = ${JSON.stringify(v)};\n` + ); + } + return source; + } + const needNsObj = + this.esModule && + generateContext.moduleGraph + .getExportsInfo(module) + .otherExportsInfo.getUsed(generateContext.runtime) !== + UsageState.Unused; + if (needNsObj) { + generateContext.runtimeRequirements.add( + RuntimeGlobals.makeNamespaceObject + ); + } + const exports = []; + for (const [name, v] of cssExportsData.exports) { + exports.push(`\t${JSON.stringify(name)}: ${JSON.stringify(v)}`); + } + return new RawSource( + `${needNsObj ? `${RuntimeGlobals.makeNamespaceObject}(` : ""}${ + module.moduleArgument + }.exports = {\n${exports.join(",\n")}\n}${needNsObj ? ")" : ""};` + ); + } + + /** + * @param {NormalModule} module fresh module + * @returns {Set} available types (do not mutate) + */ + getTypes(module) { + return TYPES; + } + + /** + * @param {NormalModule} module the module + * @param {string=} type source type + * @returns {number} estimate size of the module + */ + getSize(module, type) { + return 42; + } + + /** + * @param {Hash} hash hash that will be modified + * @param {UpdateHashContext} updateHashContext context for updating hash + */ + updateHash(hash, { module }) { + hash.update(this.esModule.toString()); + } +} + +module.exports = CssExportsGenerator; diff --git a/lib/css/CssGenerator.js b/lib/css/CssGenerator.js new file mode 100644 index 00000000000..16f6ff16d96 --- /dev/null +++ b/lib/css/CssGenerator.js @@ -0,0 +1,151 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Sergey Melyukov @smelukov +*/ + +"use strict"; + +const { ReplaceSource } = require("webpack-sources"); +const Generator = require("../Generator"); +const InitFragment = require("../InitFragment"); +const RuntimeGlobals = require("../RuntimeGlobals"); + +/** @typedef {import("webpack-sources").Source} Source */ +/** @typedef {import("../../declarations/WebpackOptions").CssGeneratorExportsConvention} CssGeneratorExportsConvention */ +/** @typedef {import("../../declarations/WebpackOptions").CssGeneratorLocalIdentName} CssGeneratorLocalIdentName */ +/** @typedef {import("../Dependency")} Dependency */ +/** @typedef {import("../DependencyTemplate").CssDependencyTemplateContext} DependencyTemplateContext */ +/** @typedef {import("../DependencyTemplate").CssExportsData} CssExportsData */ +/** @typedef {import("../Generator").GenerateContext} GenerateContext */ +/** @typedef {import("../Generator").UpdateHashContext} UpdateHashContext */ +/** @typedef {import("../NormalModule")} NormalModule */ +/** @typedef {import("../util/Hash")} Hash */ + +const TYPES = new Set(["css"]); + +class CssGenerator extends Generator { + /** + * @param {CssGeneratorExportsConvention | undefined} convention the convention of the exports name + * @param {CssGeneratorLocalIdentName | undefined} localIdentName css export local ident name + * @param {boolean} esModule whether to use ES modules syntax + */ + constructor(convention, localIdentName, esModule) { + super(); + /** @type {CssGeneratorExportsConvention | undefined} */ + this.convention = convention; + /** @type {CssGeneratorLocalIdentName | undefined} */ + this.localIdentName = localIdentName; + /** @type {boolean} */ + this.esModule = esModule; + } + + /** + * @param {NormalModule} module module for which the code should be generated + * @param {GenerateContext} generateContext context for generate + * @returns {Source} generated code + */ + generate(module, generateContext) { + const originalSource = /** @type {Source} */ (module.originalSource()); + const source = new ReplaceSource(originalSource); + /** @type {InitFragment[]} */ + const initFragments = []; + /** @type {CssExportsData} */ + const cssExportsData = { + esModule: this.esModule, + exports: new Map() + }; + + generateContext.runtimeRequirements.add(RuntimeGlobals.hasCssModules); + + let chunkInitFragments; + /** @type {DependencyTemplateContext} */ + const templateContext = { + runtimeTemplate: generateContext.runtimeTemplate, + dependencyTemplates: generateContext.dependencyTemplates, + moduleGraph: generateContext.moduleGraph, + chunkGraph: generateContext.chunkGraph, + module, + runtime: generateContext.runtime, + runtimeRequirements: generateContext.runtimeRequirements, + concatenationScope: generateContext.concatenationScope, + codeGenerationResults: generateContext.codeGenerationResults, + initFragments, + cssExportsData, + get chunkInitFragments() { + if (!chunkInitFragments) { + const data = generateContext.getData(); + chunkInitFragments = data.get("chunkInitFragments"); + if (!chunkInitFragments) { + chunkInitFragments = []; + data.set("chunkInitFragments", chunkInitFragments); + } + } + + return chunkInitFragments; + } + }; + + /** + * @param {Dependency} dependency dependency + */ + const handleDependency = dependency => { + const constructor = /** @type {new (...args: any[]) => Dependency} */ ( + dependency.constructor + ); + const template = generateContext.dependencyTemplates.get(constructor); + if (!template) { + throw new Error( + `No template for dependency: ${dependency.constructor.name}` + ); + } + + template.apply(dependency, source, templateContext); + }; + for (const dependency of module.dependencies) { + handleDependency(dependency); + } + if (module.presentationalDependencies !== undefined) { + for (const dependency of module.presentationalDependencies) { + handleDependency(dependency); + } + } + + const data = generateContext.getData(); + data.set("css-exports", cssExportsData); + + return InitFragment.addToSource(source, initFragments, generateContext); + } + + /** + * @param {NormalModule} module fresh module + * @returns {Set} available types (do not mutate) + */ + getTypes(module) { + return TYPES; + } + + /** + * @param {NormalModule} module the module + * @param {string=} type source type + * @returns {number} estimate size of the module + */ + getSize(module, type) { + const originalSource = module.originalSource(); + + if (!originalSource) { + return 0; + } + + return originalSource.size(); + } + + /** + * @param {Hash} hash hash that will be modified + * @param {UpdateHashContext} updateHashContext context for updating hash + */ + updateHash(hash, { module }) { + hash.update(this.esModule.toString()); + } +} + +module.exports = CssGenerator; diff --git a/lib/css/CssLoadingRuntimeModule.js b/lib/css/CssLoadingRuntimeModule.js new file mode 100644 index 00000000000..b3e677caa63 --- /dev/null +++ b/lib/css/CssLoadingRuntimeModule.js @@ -0,0 +1,592 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ + +"use strict"; + +const { SyncWaterfallHook } = require("tapable"); +const Compilation = require("../Compilation"); +const RuntimeGlobals = require("../RuntimeGlobals"); +const RuntimeModule = require("../RuntimeModule"); +const Template = require("../Template"); +const compileBooleanMatcher = require("../util/compileBooleanMatcher"); +const { chunkHasCss } = require("./CssModulesPlugin"); + +/** @typedef {import("../Chunk")} Chunk */ +/** @typedef {import("../ChunkGraph")} ChunkGraph */ +/** @typedef {import("../Compilation").RuntimeRequirementsContext} RuntimeRequirementsContext */ +/** @typedef {import("../Module").ReadOnlyRuntimeRequirements} ReadOnlyRuntimeRequirements */ + +/** + * @typedef {object} CssLoadingRuntimeModulePluginHooks + * @property {SyncWaterfallHook<[string, Chunk]>} createStylesheet + * @property {SyncWaterfallHook<[string, Chunk]>} linkPreload + * @property {SyncWaterfallHook<[string, Chunk]>} linkPrefetch + */ + +/** @type {WeakMap} */ +const compilationHooksMap = new WeakMap(); + +class CssLoadingRuntimeModule extends RuntimeModule { + /** + * @param {Compilation} compilation the compilation + * @returns {CssLoadingRuntimeModulePluginHooks} hooks + */ + static getCompilationHooks(compilation) { + if (!(compilation instanceof Compilation)) { + throw new TypeError( + "The 'compilation' argument must be an instance of Compilation" + ); + } + let hooks = compilationHooksMap.get(compilation); + if (hooks === undefined) { + hooks = { + createStylesheet: new SyncWaterfallHook(["source", "chunk"]), + linkPreload: new SyncWaterfallHook(["source", "chunk"]), + linkPrefetch: new SyncWaterfallHook(["source", "chunk"]) + }; + compilationHooksMap.set(compilation, hooks); + } + return hooks; + } + + /** + * @param {ReadOnlyRuntimeRequirements} runtimeRequirements runtime requirements + */ + constructor(runtimeRequirements) { + super("css loading", 10); + + this._runtimeRequirements = runtimeRequirements; + } + + /** + * @returns {string | null} runtime code + */ + generate() { + const { _runtimeRequirements } = this; + const compilation = /** @type {Compilation} */ (this.compilation); + const chunk = /** @type {Chunk} */ (this.chunk); + const { + chunkGraph, + runtimeTemplate, + outputOptions: { + crossOriginLoading, + uniqueName, + chunkLoadTimeout: loadTimeout, + cssHeadDataCompression: withCompression + } + } = compilation; + const fn = RuntimeGlobals.ensureChunkHandlers; + const conditionMap = chunkGraph.getChunkConditionMap( + /** @type {Chunk} */ (chunk), + /** + * @param {Chunk} chunk the chunk + * @param {ChunkGraph} chunkGraph the chunk graph + * @returns {boolean} true, if the chunk has css + */ + (chunk, chunkGraph) => + Boolean(chunkGraph.getChunkModulesIterableBySourceType(chunk, "css")) + ); + const hasCssMatcher = compileBooleanMatcher(conditionMap); + + const withLoading = + _runtimeRequirements.has(RuntimeGlobals.ensureChunkHandlers) && + hasCssMatcher !== false; + const withPrefetch = this._runtimeRequirements.has( + RuntimeGlobals.prefetchChunkHandlers + ); + const withPreload = this._runtimeRequirements.has( + RuntimeGlobals.preloadChunkHandlers + ); + /** @type {boolean} */ + const withHmr = _runtimeRequirements.has( + RuntimeGlobals.hmrDownloadUpdateHandlers + ); + /** @type {Set} */ + const initialChunkIdsWithCss = new Set(); + /** @type {Set} */ + const initialChunkIdsWithoutCss = new Set(); + for (const c of /** @type {Chunk} */ (chunk).getAllInitialChunks()) { + (chunkHasCss(c, chunkGraph) + ? initialChunkIdsWithCss + : initialChunkIdsWithoutCss + ).add(c.id); + } + + if (!withLoading && !withHmr && initialChunkIdsWithCss.size === 0) { + return null; + } + + const { linkPreload, linkPrefetch } = + CssLoadingRuntimeModule.getCompilationHooks(compilation); + + const withFetchPriority = _runtimeRequirements.has( + RuntimeGlobals.hasFetchPriority + ); + + const { createStylesheet } = + CssLoadingRuntimeModule.getCompilationHooks(compilation); + + const stateExpression = withHmr + ? `${RuntimeGlobals.hmrRuntimeStatePrefix}_css` + : undefined; + + const code = Template.asString([ + "link = document.createElement('link');", + `if (${RuntimeGlobals.scriptNonce}) {`, + Template.indent( + `link.setAttribute("nonce", ${RuntimeGlobals.scriptNonce});` + ), + "}", + uniqueName + ? 'link.setAttribute("data-webpack", uniqueName + ":" + key);' + : "", + withFetchPriority + ? Template.asString([ + "if(fetchPriority) {", + Template.indent( + 'link.setAttribute("fetchpriority", fetchPriority);' + ), + "}" + ]) + : "", + "link.setAttribute(loadingAttribute, 1);", + 'link.rel = "stylesheet";', + "link.href = url;", + crossOriginLoading + ? crossOriginLoading === "use-credentials" + ? 'link.crossOrigin = "use-credentials";' + : Template.asString([ + "if (link.href.indexOf(window.location.origin + '/') !== 0) {", + Template.indent( + `link.crossOrigin = ${JSON.stringify(crossOriginLoading)};` + ), + "}" + ]) + : "" + ]); + + /** @type {(str: string) => number} */ + const cc = str => str.charCodeAt(0); + const name = uniqueName + ? runtimeTemplate.concatenation( + "--webpack-", + { expr: "uniqueName" }, + "-", + { expr: "chunkId" } + ) + : runtimeTemplate.concatenation("--webpack-", { expr: "chunkId" }); + + return Template.asString([ + "// object to store loaded and loading chunks", + "// undefined = chunk not loaded, null = chunk preloaded/prefetched", + "// [resolve, reject, Promise] = chunk loading, 0 = chunk loaded", + `var installedChunks = ${ + stateExpression ? `${stateExpression} = ${stateExpression} || ` : "" + }{${Array.from( + initialChunkIdsWithoutCss, + id => `${JSON.stringify(id)}:0` + ).join(",")}};`, + "", + uniqueName + ? `var uniqueName = ${JSON.stringify( + runtimeTemplate.outputOptions.uniqueName + )};` + : "// data-webpack is not used as build has no uniqueName", + `var loadCssChunkData = ${runtimeTemplate.basicFunction( + "target, link, chunkId", + [ + `var data, token = "", token2 = "", exports = {}, ${ + withHmr ? "moduleIds = [], " : "" + }name = ${name}, i, cc = 1;`, + "try {", + Template.indent([ + "if(!link) link = loadStylesheet(chunkId);", + // `link.sheet.rules` for legacy browsers + "var cssRules = link.sheet.cssRules || link.sheet.rules;", + "var j = cssRules.length - 1;", + "while(j > -1 && !data) {", + Template.indent([ + "var style = cssRules[j--].style;", + "if(!style) continue;", + "data = style.getPropertyValue(name);" + ]), + "}" + ]), + "}catch(e){}", + "if(!data) {", + Template.indent([ + "data = getComputedStyle(document.head).getPropertyValue(name);" + ]), + "}", + "if(!data) return [];", + withCompression + ? Template.asString([ + // LZW decode + `var map = {}, char = data[0], oldPhrase = char, decoded = char, code = 256, maxCode = ${"\uFFFF".charCodeAt( + 0 + )}, phrase;`, + "for (i = 1; i < data.length; i++) {", + Template.indent([ + "cc = data[i].charCodeAt(0);", + "if (cc < 256) phrase = data[i]; else phrase = map[cc] ? map[cc] : (oldPhrase + char);", + "decoded += phrase;", + "char = phrase.charAt(0);", + "map[code] = oldPhrase + char;", + "if (++code > maxCode) { code = 256; map = {}; }", + "oldPhrase = phrase;" + ]), + "}", + "data = decoded;" + ]) + : "// css head data compression is disabled", + "for(i = 0; cc; i++) {", + Template.indent([ + "cc = data.charCodeAt(i);", + `if(cc == ${cc(":")}) { token2 = token; token = ""; }`, + `else if(cc == ${cc( + "/" + )}) { token = token.replace(/^_/, ""); token2 = token2.replace(/^_/, ""); exports[token2] = token; token = ""; token2 = ""; }`, + `else if(cc == ${cc("&")}) { ${ + RuntimeGlobals.makeNamespaceObject + }(exports); }`, + `else if(!cc || cc == ${cc( + "," + )}) { token = token.replace(/^_/, ""); target[token] = (${runtimeTemplate.basicFunction( + "exports, module", + "module.exports = exports;" + )}).bind(null, exports); ${ + withHmr ? "moduleIds.push(token); " : "" + }token = ""; token2 = ""; exports = {}; }`, + `else if(cc == ${cc("\\")}) { token += data[++i] }`, + "else { token += data[i]; }" + ]), + "}", + `${ + withHmr ? `if(target == ${RuntimeGlobals.moduleFactories}) ` : "" + }installedChunks[chunkId] = 0;`, + withHmr ? "return moduleIds;" : "" + ] + )}`, + 'var loadingAttribute = "data-webpack-loading";', + `var loadStylesheet = ${runtimeTemplate.basicFunction( + `chunkId, url, done${withHmr ? ", hmr" : ""}${ + withFetchPriority ? ", fetchPriority" : "" + }`, + [ + 'var link, needAttach, key = "chunk-" + chunkId;', + withHmr ? "if(!hmr) {" : "", + 'var links = document.getElementsByTagName("link");', + "for(var i = 0; i < links.length; i++) {", + Template.indent([ + "var l = links[i];", + `if(l.rel == "stylesheet" && (${ + withHmr + ? 'l.href.startsWith(url) || l.getAttribute("href").startsWith(url)' + : 'l.href == url || l.getAttribute("href") == url' + }${ + uniqueName + ? ' || l.getAttribute("data-webpack") == uniqueName + ":" + key' + : "" + })) { link = l; break; }` + ]), + "}", + "if(!done) return link;", + withHmr ? "}" : "", + "if(!link) {", + Template.indent([ + "needAttach = true;", + createStylesheet.call(code, /** @type {Chunk} */ (this.chunk)) + ]), + "}", + `var onLinkComplete = ${runtimeTemplate.basicFunction( + "prev, event", + Template.asString([ + "link.onerror = link.onload = null;", + "link.removeAttribute(loadingAttribute);", + "clearTimeout(timeout);", + 'if(event && event.type != "load") link.parentNode.removeChild(link)', + "done(event);", + "if(prev) return prev(event);" + ]) + )};`, + "if(link.getAttribute(loadingAttribute)) {", + Template.indent([ + `var timeout = setTimeout(onLinkComplete.bind(null, undefined, { type: 'timeout', target: link }), ${loadTimeout});`, + "link.onerror = onLinkComplete.bind(null, link.onerror);", + "link.onload = onLinkComplete.bind(null, link.onload);" + ]), + "} else onLinkComplete(undefined, { type: 'load', target: link });", // We assume any existing stylesheet is render blocking + withHmr ? "hmr ? document.head.insertBefore(link, hmr) :" : "", + "needAttach && document.head.appendChild(link);", + "return link;" + ] + )};`, + initialChunkIdsWithCss.size > 2 + ? `${JSON.stringify( + Array.from(initialChunkIdsWithCss) + )}.forEach(loadCssChunkData.bind(null, ${ + RuntimeGlobals.moduleFactories + }, 0));` + : initialChunkIdsWithCss.size > 0 + ? `${Array.from( + initialChunkIdsWithCss, + id => + `loadCssChunkData(${ + RuntimeGlobals.moduleFactories + }, 0, ${JSON.stringify(id)});` + ).join("")}` + : "// no initial css", + "", + withLoading + ? Template.asString([ + `${fn}.css = ${runtimeTemplate.basicFunction( + `chunkId, promises${withFetchPriority ? " , fetchPriority" : ""}`, + [ + "// css chunk loading", + `var installedChunkData = ${RuntimeGlobals.hasOwnProperty}(installedChunks, chunkId) ? installedChunks[chunkId] : undefined;`, + 'if(installedChunkData !== 0) { // 0 means "already installed".', + Template.indent([ + "", + '// a Promise means "currently loading".', + "if(installedChunkData) {", + Template.indent(["promises.push(installedChunkData[2]);"]), + "} else {", + Template.indent([ + hasCssMatcher === true + ? "if(true) { // all chunks have CSS" + : `if(${hasCssMatcher("chunkId")}) {`, + Template.indent([ + "// setup Promise in chunk cache", + `var promise = new Promise(${runtimeTemplate.expressionFunction( + "installedChunkData = installedChunks[chunkId] = [resolve, reject]", + "resolve, reject" + )});`, + "promises.push(installedChunkData[2] = promise);", + "", + "// start chunk loading", + `var url = ${RuntimeGlobals.publicPath} + ${RuntimeGlobals.getChunkCssFilename}(chunkId);`, + "// create error before stack unwound to get useful stacktrace later", + "var error = new Error();", + `var loadingEnded = ${runtimeTemplate.basicFunction( + "event", + [ + `if(${RuntimeGlobals.hasOwnProperty}(installedChunks, chunkId)) {`, + Template.indent([ + "installedChunkData = installedChunks[chunkId];", + "if(installedChunkData !== 0) installedChunks[chunkId] = undefined;", + "if(installedChunkData) {", + Template.indent([ + 'if(event.type !== "load") {', + Template.indent([ + "var errorType = event && event.type;", + "var realHref = event && event.target && event.target.href;", + "error.message = 'Loading css chunk ' + chunkId + ' failed.\\n(' + errorType + ': ' + realHref + ')';", + "error.name = 'ChunkLoadError';", + "error.type = errorType;", + "error.request = realHref;", + "installedChunkData[1](error);" + ]), + "} else {", + Template.indent([ + `loadCssChunkData(${RuntimeGlobals.moduleFactories}, link, chunkId);`, + "installedChunkData[0]();" + ]), + "}" + ]), + "}" + ]), + "}" + ] + )};`, + `var link = loadStylesheet(chunkId, url, loadingEnded${ + withFetchPriority ? ", fetchPriority" : "" + });` + ]), + "} else installedChunks[chunkId] = 0;" + ]), + "}" + ]), + "}" + ] + )};` + ]) + : "// no chunk loading", + "", + withPrefetch && hasCssMatcher !== false + ? `${ + RuntimeGlobals.prefetchChunkHandlers + }.s = ${runtimeTemplate.basicFunction("chunkId", [ + `if((!${ + RuntimeGlobals.hasOwnProperty + }(installedChunks, chunkId) || installedChunks[chunkId] === undefined) && ${ + hasCssMatcher === true ? "true" : hasCssMatcher("chunkId") + }) {`, + Template.indent([ + "installedChunks[chunkId] = null;", + linkPrefetch.call( + Template.asString([ + "var link = document.createElement('link');", + crossOriginLoading + ? `link.crossOrigin = ${JSON.stringify( + crossOriginLoading + )};` + : "", + `if (${RuntimeGlobals.scriptNonce}) {`, + Template.indent( + `link.setAttribute("nonce", ${RuntimeGlobals.scriptNonce});` + ), + "}", + 'link.rel = "prefetch";', + 'link.as = "style";', + `link.href = ${RuntimeGlobals.publicPath} + ${RuntimeGlobals.getChunkCssFilename}(chunkId);` + ]), + chunk + ), + "document.head.appendChild(link);" + ]), + "}" + ])};` + : "// no prefetching", + "", + withPreload && hasCssMatcher !== false + ? `${ + RuntimeGlobals.preloadChunkHandlers + }.s = ${runtimeTemplate.basicFunction("chunkId", [ + `if((!${ + RuntimeGlobals.hasOwnProperty + }(installedChunks, chunkId) || installedChunks[chunkId] === undefined) && ${ + hasCssMatcher === true ? "true" : hasCssMatcher("chunkId") + }) {`, + Template.indent([ + "installedChunks[chunkId] = null;", + linkPreload.call( + Template.asString([ + "var link = document.createElement('link');", + "link.charset = 'utf-8';", + `if (${RuntimeGlobals.scriptNonce}) {`, + Template.indent( + `link.setAttribute("nonce", ${RuntimeGlobals.scriptNonce});` + ), + "}", + 'link.rel = "preload";', + 'link.as = "style";', + `link.href = ${RuntimeGlobals.publicPath} + ${RuntimeGlobals.getChunkCssFilename}(chunkId);`, + crossOriginLoading + ? crossOriginLoading === "use-credentials" + ? 'link.crossOrigin = "use-credentials";' + : Template.asString([ + "if (link.href.indexOf(window.location.origin + '/') !== 0) {", + Template.indent( + `link.crossOrigin = ${JSON.stringify( + crossOriginLoading + )};` + ), + "}" + ]) + : "" + ]), + chunk + ), + "document.head.appendChild(link);" + ]), + "}" + ])};` + : "// no preloaded", + withHmr + ? Template.asString([ + "var oldTags = [];", + "var newTags = [];", + `var applyHandler = ${runtimeTemplate.basicFunction("options", [ + `return { dispose: ${runtimeTemplate.basicFunction( + "", + [] + )}, apply: ${runtimeTemplate.basicFunction("", [ + "var moduleIds = [];", + `newTags.forEach(${runtimeTemplate.expressionFunction( + "info[1].sheet.disabled = false", + "info" + )});`, + "while(oldTags.length) {", + Template.indent([ + "var oldTag = oldTags.pop();", + "if(oldTag.parentNode) oldTag.parentNode.removeChild(oldTag);" + ]), + "}", + "while(newTags.length) {", + Template.indent([ + "var info = newTags.pop();", + `var chunkModuleIds = loadCssChunkData(${RuntimeGlobals.moduleFactories}, info[1], info[0]);`, + `chunkModuleIds.forEach(${runtimeTemplate.expressionFunction( + "moduleIds.push(id)", + "id" + )});` + ]), + "}", + "return moduleIds;" + ])} };` + ])}`, + `var cssTextKey = ${runtimeTemplate.returningFunction( + `Array.from(link.sheet.cssRules, ${runtimeTemplate.returningFunction( + "r.cssText", + "r" + )}).join()`, + "link" + )}`, + `${ + RuntimeGlobals.hmrDownloadUpdateHandlers + }.css = ${runtimeTemplate.basicFunction( + "chunkIds, removedChunks, removedModules, promises, applyHandlers, updatedModulesList", + [ + "applyHandlers.push(applyHandler);", + `chunkIds.forEach(${runtimeTemplate.basicFunction("chunkId", [ + `var filename = ${RuntimeGlobals.getChunkCssFilename}(chunkId);`, + `var url = ${RuntimeGlobals.publicPath} + filename;`, + "var oldTag = loadStylesheet(chunkId, url);", + "if(!oldTag) return;", + `promises.push(new Promise(${runtimeTemplate.basicFunction( + "resolve, reject", + [ + `var link = loadStylesheet(chunkId, url + (url.indexOf("?") < 0 ? "?" : "&") + "hmr=" + Date.now(), ${runtimeTemplate.basicFunction( + "event", + [ + 'if(event.type !== "load") {', + Template.indent([ + "var errorType = event && event.type;", + "var realHref = event && event.target && event.target.href;", + "error.message = 'Loading css hot update chunk ' + chunkId + ' failed.\\n(' + errorType + ': ' + realHref + ')';", + "error.name = 'ChunkLoadError';", + "error.type = errorType;", + "error.request = realHref;", + "reject(error);" + ]), + "} else {", + Template.indent([ + "try { if(cssTextKey(oldTag) == cssTextKey(link)) { if(link.parentNode) link.parentNode.removeChild(link); return resolve(); } } catch(e) {}", + "var factories = {};", + "loadCssChunkData(factories, link, chunkId);", + `Object.keys(factories).forEach(${runtimeTemplate.expressionFunction( + "updatedModulesList.push(id)", + "id" + )})`, + "link.sheet.disabled = true;", + "oldTags.push(oldTag);", + "newTags.push([chunkId, link]);", + "resolve();" + ]), + "}" + ] + )}, oldTag);` + ] + )}));` + ])});` + ] + )}` + ]) + : "// no hmr" + ]); + } +} + +module.exports = CssLoadingRuntimeModule; diff --git a/lib/css/CssModulesPlugin.js b/lib/css/CssModulesPlugin.js new file mode 100644 index 00000000000..213c2178492 --- /dev/null +++ b/lib/css/CssModulesPlugin.js @@ -0,0 +1,888 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ + +"use strict"; + +const { SyncWaterfallHook, SyncHook } = require("tapable"); +const { + ConcatSource, + PrefixSource, + ReplaceSource, + CachedSource +} = require("webpack-sources"); +const Compilation = require("../Compilation"); +const CssModule = require("../CssModule"); +const { tryRunOrWebpackError } = require("../HookWebpackError"); +const HotUpdateChunk = require("../HotUpdateChunk"); +const { + CSS_MODULE_TYPE, + CSS_MODULE_TYPE_GLOBAL, + CSS_MODULE_TYPE_MODULE, + CSS_MODULE_TYPE_AUTO +} = require("../ModuleTypeConstants"); +const RuntimeGlobals = require("../RuntimeGlobals"); +const SelfModuleFactory = require("../SelfModuleFactory"); +const WebpackError = require("../WebpackError"); +const CssExportDependency = require("../dependencies/CssExportDependency"); +const CssImportDependency = require("../dependencies/CssImportDependency"); +const CssLocalIdentifierDependency = require("../dependencies/CssLocalIdentifierDependency"); +const CssSelfLocalIdentifierDependency = require("../dependencies/CssSelfLocalIdentifierDependency"); +const CssUrlDependency = require("../dependencies/CssUrlDependency"); +const StaticExportsDependency = require("../dependencies/StaticExportsDependency"); +const { compareModulesByIdentifier } = require("../util/comparators"); +const createSchemaValidation = require("../util/create-schema-validation"); +const createHash = require("../util/createHash"); +const { getUndoPath } = require("../util/identifier"); +const memoize = require("../util/memoize"); +const nonNumericOnlyHash = require("../util/nonNumericOnlyHash"); +const CssExportsGenerator = require("./CssExportsGenerator"); +const CssGenerator = require("./CssGenerator"); +const CssParser = require("./CssParser"); + +/** @typedef {import("webpack-sources").Source} Source */ +/** @typedef {import("../../declarations/WebpackOptions").OutputNormalized} OutputOptions */ +/** @typedef {import("../Chunk")} Chunk */ +/** @typedef {import("../ChunkGraph")} ChunkGraph */ +/** @typedef {import("../CodeGenerationResults")} CodeGenerationResults */ +/** @typedef {import("../Compilation").ChunkHashContext} ChunkHashContext */ +/** @typedef {import("../Compiler")} Compiler */ +/** @typedef {import("../CssModule").Inheritance} Inheritance */ +/** @typedef {import("../DependencyTemplate").CssExportsData} CssExportsData */ +/** @typedef {import("../Module")} Module */ +/** @typedef {import("../Template").RuntimeTemplate} RuntimeTemplate */ +/** @typedef {import("../TemplatedPathPlugin").TemplatePath} TemplatePath */ +/** @typedef {import("../util/Hash")} Hash */ +/** @typedef {import("../util/memoize")} Memoize */ + +/** + * @typedef {object} ChunkRenderContext + * @property {RuntimeTemplate} runtimeTemplate runtime template + */ + +/** + * @typedef {object} CompilationHooks + * @property {SyncWaterfallHook<[Source, Module, ChunkRenderContext]>} renderModulePackage + * @property {SyncHook<[Chunk, Hash, ChunkHashContext]>} chunkHash + */ + +const getCssLoadingRuntimeModule = memoize(() => + require("./CssLoadingRuntimeModule") +); + +/** + * @param {string} name name + * @returns {{oneOf: [{$ref: string}], definitions: *}} schema + */ +const getSchema = name => { + const { definitions } = require("../../schemas/WebpackOptions.json"); + return { + definitions, + oneOf: [{ $ref: `#/definitions/${name}` }] + }; +}; + +const generatorValidationOptions = { + name: "Css Modules Plugin", + baseDataPath: "generator" +}; +const validateGeneratorOptions = { + css: createSchemaValidation( + require("../../schemas/plugins/css/CssGeneratorOptions.check.js"), + () => getSchema("CssGeneratorOptions"), + generatorValidationOptions + ), + "css/auto": createSchemaValidation( + require("../../schemas/plugins/css/CssAutoGeneratorOptions.check.js"), + () => getSchema("CssAutoGeneratorOptions"), + generatorValidationOptions + ), + "css/module": createSchemaValidation( + require("../../schemas/plugins/css/CssModuleGeneratorOptions.check.js"), + () => getSchema("CssModuleGeneratorOptions"), + generatorValidationOptions + ), + "css/global": createSchemaValidation( + require("../../schemas/plugins/css/CssGlobalGeneratorOptions.check.js"), + () => getSchema("CssGlobalGeneratorOptions"), + generatorValidationOptions + ) +}; + +const parserValidationOptions = { + name: "Css Modules Plugin", + baseDataPath: "parser" +}; +const validateParserOptions = { + css: createSchemaValidation( + require("../../schemas/plugins/css/CssParserOptions.check.js"), + () => getSchema("CssParserOptions"), + parserValidationOptions + ), + "css/auto": createSchemaValidation( + require("../../schemas/plugins/css/CssAutoParserOptions.check.js"), + () => getSchema("CssAutoParserOptions"), + parserValidationOptions + ), + "css/module": createSchemaValidation( + require("../../schemas/plugins/css/CssModuleParserOptions.check.js"), + () => getSchema("CssModuleParserOptions"), + parserValidationOptions + ), + "css/global": createSchemaValidation( + require("../../schemas/plugins/css/CssGlobalParserOptions.check.js"), + () => getSchema("CssGlobalParserOptions"), + parserValidationOptions + ) +}; + +/** @type {WeakMap} */ +const compilationHooksMap = new WeakMap(); + +/** + * @param {string} str string + * @param {boolean=} omitOptionalUnderscore if true, optional underscore is not added + * @returns {string} escaped string + */ +const escapeCss = (str, omitOptionalUnderscore) => { + const escaped = `${str}`.replace( + // cspell:word uffff + /[^a-zA-Z0-9_\u0081-\uFFFF-]/g, + s => `\\${s}` + ); + return !omitOptionalUnderscore && /^(?!--)[0-9_-]/.test(escaped) + ? `_${escaped}` + : escaped; +}; + +/** + * @param {string} str string + * @returns {string} encoded string + */ +const lzwEncode = str => { + /** @type {Map} */ + const map = new Map(); + let encoded = ""; + let phrase = str[0]; + let code = 256; + const maxCode = "\uFFFF".charCodeAt(0); + for (let i = 1; i < str.length; i++) { + const c = str[i]; + if (map.has(phrase + c)) { + phrase += c; + } else { + encoded += phrase.length > 1 ? map.get(phrase) : phrase; + map.set(phrase + c, String.fromCharCode(code)); + phrase = c; + if (++code > maxCode) { + code = 256; + map.clear(); + } + } + } + encoded += phrase.length > 1 ? map.get(phrase) : phrase; + return encoded; +}; + +const PLUGIN_NAME = "CssModulesPlugin"; + +class CssModulesPlugin { + /** + * @param {Compilation} compilation the compilation + * @returns {CompilationHooks} the attached hooks + */ + static getCompilationHooks(compilation) { + if (!(compilation instanceof Compilation)) { + throw new TypeError( + "The 'compilation' argument must be an instance of Compilation" + ); + } + let hooks = compilationHooksMap.get(compilation); + if (hooks === undefined) { + hooks = { + renderModulePackage: new SyncWaterfallHook([ + "source", + "module", + "renderContext" + ]), + chunkHash: new SyncHook(["chunk", "hash", "context"]) + }; + compilationHooksMap.set(compilation, hooks); + } + return hooks; + } + + constructor() { + /** @type {WeakMap} */ + this._moduleCache = new WeakMap(); + } + + /** + * Apply the plugin + * @param {Compiler} compiler the compiler instance + * @returns {void} + */ + apply(compiler) { + compiler.hooks.compilation.tap( + PLUGIN_NAME, + (compilation, { normalModuleFactory }) => { + const hooks = CssModulesPlugin.getCompilationHooks(compilation); + const selfFactory = new SelfModuleFactory(compilation.moduleGraph); + compilation.dependencyFactories.set( + CssUrlDependency, + normalModuleFactory + ); + compilation.dependencyTemplates.set( + CssUrlDependency, + new CssUrlDependency.Template() + ); + compilation.dependencyTemplates.set( + CssLocalIdentifierDependency, + new CssLocalIdentifierDependency.Template() + ); + compilation.dependencyFactories.set( + CssSelfLocalIdentifierDependency, + selfFactory + ); + compilation.dependencyTemplates.set( + CssSelfLocalIdentifierDependency, + new CssSelfLocalIdentifierDependency.Template() + ); + compilation.dependencyTemplates.set( + CssExportDependency, + new CssExportDependency.Template() + ); + compilation.dependencyFactories.set( + CssImportDependency, + normalModuleFactory + ); + compilation.dependencyTemplates.set( + CssImportDependency, + new CssImportDependency.Template() + ); + compilation.dependencyTemplates.set( + StaticExportsDependency, + new StaticExportsDependency.Template() + ); + for (const type of [ + CSS_MODULE_TYPE, + CSS_MODULE_TYPE_GLOBAL, + CSS_MODULE_TYPE_MODULE, + CSS_MODULE_TYPE_AUTO + ]) { + normalModuleFactory.hooks.createParser + .for(type) + .tap(PLUGIN_NAME, parserOptions => { + validateParserOptions[type](parserOptions); + const { namedExports } = parserOptions; + + switch (type) { + case CSS_MODULE_TYPE_GLOBAL: + case CSS_MODULE_TYPE_AUTO: + return new CssParser({ + namedExports + }); + case CSS_MODULE_TYPE: + return new CssParser({ + allowModeSwitch: false, + namedExports + }); + case CSS_MODULE_TYPE_MODULE: + return new CssParser({ + defaultMode: "local", + namedExports + }); + } + }); + normalModuleFactory.hooks.createGenerator + .for(type) + .tap(PLUGIN_NAME, generatorOptions => { + validateGeneratorOptions[type](generatorOptions); + + return generatorOptions.exportsOnly + ? new CssExportsGenerator( + generatorOptions.exportsConvention, + generatorOptions.localIdentName, + generatorOptions.esModule + ) + : new CssGenerator( + generatorOptions.exportsConvention, + generatorOptions.localIdentName, + generatorOptions.esModule + ); + }); + normalModuleFactory.hooks.createModuleClass + .for(type) + .tap(PLUGIN_NAME, (createData, resolveData) => { + if (resolveData.dependencies.length > 0) { + // When CSS is imported from CSS there is only one dependency + const dependency = resolveData.dependencies[0]; + + if (dependency instanceof CssImportDependency) { + const parent = + /** @type {CssModule} */ + (compilation.moduleGraph.getParentModule(dependency)); + + if (parent instanceof CssModule) { + /** @type {import("../CssModule").Inheritance | undefined} */ + let inheritance; + + if ( + (parent.cssLayer !== null && + parent.cssLayer !== undefined) || + parent.supports || + parent.media + ) { + if (!inheritance) { + inheritance = []; + } + + inheritance.push([ + parent.cssLayer, + parent.supports, + parent.media + ]); + } + + if (parent.inheritance) { + if (!inheritance) { + inheritance = []; + } + + inheritance.push(...parent.inheritance); + } + + return new CssModule({ + ...createData, + cssLayer: dependency.layer, + supports: dependency.supports, + media: dependency.media, + inheritance + }); + } + + return new CssModule({ + ...createData, + cssLayer: dependency.layer, + supports: dependency.supports, + media: dependency.media + }); + } + } + + return new CssModule(createData); + }); + } + const orderedCssModulesPerChunk = new WeakMap(); + compilation.hooks.afterCodeGeneration.tap("CssModulesPlugin", () => { + const { chunkGraph } = compilation; + for (const chunk of compilation.chunks) { + if (CssModulesPlugin.chunkHasCss(chunk, chunkGraph)) { + orderedCssModulesPerChunk.set( + chunk, + this.getOrderedChunkCssModules(chunk, chunkGraph, compilation) + ); + } + } + }); + compilation.hooks.chunkHash.tap( + "CssModulesPlugin", + (chunk, hash, context) => { + hooks.chunkHash.call(chunk, hash, context); + } + ); + compilation.hooks.contentHash.tap("CssModulesPlugin", chunk => { + const { + chunkGraph, + codeGenerationResults, + moduleGraph, + runtimeTemplate, + outputOptions: { + hashSalt, + hashDigest, + hashDigestLength, + hashFunction + } + } = compilation; + const hash = createHash(hashFunction); + if (hashSalt) hash.update(hashSalt); + hooks.chunkHash.call(chunk, hash, { + chunkGraph, + codeGenerationResults, + moduleGraph, + runtimeTemplate + }); + const modules = orderedCssModulesPerChunk.get(chunk); + if (modules) { + for (const module of modules) { + hash.update(chunkGraph.getModuleHash(module, chunk.runtime)); + } + } + const digest = /** @type {string} */ (hash.digest(hashDigest)); + chunk.contentHash.css = nonNumericOnlyHash(digest, hashDigestLength); + }); + compilation.hooks.renderManifest.tap(PLUGIN_NAME, (result, options) => { + const { chunkGraph } = compilation; + const { hash, chunk, codeGenerationResults, runtimeTemplate } = + options; + + if (chunk instanceof HotUpdateChunk) return result; + + /** @type {CssModule[] | undefined} */ + const modules = orderedCssModulesPerChunk.get(chunk); + if (modules !== undefined) { + const { path: filename, info } = compilation.getPathWithInfo( + CssModulesPlugin.getChunkFilenameTemplate( + chunk, + compilation.outputOptions + ), + { + hash, + runtime: chunk.runtime, + chunk, + contentHashType: "css" + } + ); + const undoPath = getUndoPath( + filename, + compilation.outputOptions.path, + false + ); + result.push({ + render: () => + this.renderChunk({ + chunk, + chunkGraph, + codeGenerationResults, + uniqueName: compilation.outputOptions.uniqueName, + cssHeadDataCompression: + compilation.outputOptions.cssHeadDataCompression, + undoPath, + modules, + runtimeTemplate, + hooks + }), + filename, + info, + identifier: `css${chunk.id}`, + hash: chunk.contentHash.css + }); + } + return result; + }); + const globalChunkLoading = compilation.outputOptions.chunkLoading; + /** + * @param {Chunk} chunk the chunk + * @returns {boolean} true, when enabled + */ + const isEnabledForChunk = chunk => { + const options = chunk.getEntryOptions(); + const chunkLoading = + options && options.chunkLoading !== undefined + ? options.chunkLoading + : globalChunkLoading; + return chunkLoading === "jsonp" || chunkLoading === "import"; + }; + const onceForChunkSet = new WeakSet(); + /** + * @param {Chunk} chunk chunk to check + * @param {Set} set runtime requirements + */ + const handler = (chunk, set) => { + if (onceForChunkSet.has(chunk)) return; + onceForChunkSet.add(chunk); + if (!isEnabledForChunk(chunk)) return; + + set.add(RuntimeGlobals.publicPath); + set.add(RuntimeGlobals.getChunkCssFilename); + set.add(RuntimeGlobals.hasOwnProperty); + set.add(RuntimeGlobals.moduleFactoriesAddOnly); + set.add(RuntimeGlobals.makeNamespaceObject); + + const CssLoadingRuntimeModule = getCssLoadingRuntimeModule(); + compilation.addRuntimeModule(chunk, new CssLoadingRuntimeModule(set)); + }; + compilation.hooks.runtimeRequirementInTree + .for(RuntimeGlobals.hasCssModules) + .tap(PLUGIN_NAME, handler); + compilation.hooks.runtimeRequirementInTree + .for(RuntimeGlobals.ensureChunkHandlers) + .tap(PLUGIN_NAME, handler); + compilation.hooks.runtimeRequirementInTree + .for(RuntimeGlobals.hmrDownloadUpdateHandlers) + .tap(PLUGIN_NAME, handler); + } + ); + } + + /** + * @param {Chunk} chunk chunk + * @param {Iterable} modules unordered modules + * @param {Compilation} compilation compilation + * @returns {Module[]} ordered modules + */ + getModulesInOrder(chunk, modules, compilation) { + if (!modules) return []; + + /** @type {Module[]} */ + const modulesList = [...modules]; + + // Get ordered list of modules per chunk group + // Lists are in reverse order to allow to use Array.pop() + const modulesByChunkGroup = Array.from(chunk.groupsIterable, chunkGroup => { + const sortedModules = modulesList + .map(module => ({ + module, + index: chunkGroup.getModulePostOrderIndex(module) + })) + .filter(item => item.index !== undefined) + .sort( + (a, b) => + /** @type {number} */ (b.index) - /** @type {number} */ (a.index) + ) + .map(item => item.module); + + return { list: sortedModules, set: new Set(sortedModules) }; + }); + + if (modulesByChunkGroup.length === 1) + return modulesByChunkGroup[0].list.reverse(); + + const compareModuleLists = ({ list: a }, { list: b }) => { + if (a.length === 0) { + return b.length === 0 ? 0 : 1; + } + if (b.length === 0) return -1; + return compareModulesByIdentifier(a[a.length - 1], b[b.length - 1]); + }; + + modulesByChunkGroup.sort(compareModuleLists); + + /** @type {Module[]} */ + const finalModules = []; + + for (;;) { + const failedModules = new Set(); + const list = modulesByChunkGroup[0].list; + if (list.length === 0) { + // done, everything empty + break; + } + /** @type {Module} */ + let selectedModule = list[list.length - 1]; + let hasFailed; + outer: for (;;) { + for (const { list, set } of modulesByChunkGroup) { + if (list.length === 0) continue; + const lastModule = list[list.length - 1]; + if (lastModule === selectedModule) continue; + if (!set.has(selectedModule)) continue; + failedModules.add(selectedModule); + if (failedModules.has(lastModule)) { + // There is a conflict, try other alternatives + hasFailed = lastModule; + continue; + } + selectedModule = lastModule; + hasFailed = false; + continue outer; // restart + } + break; + } + if (hasFailed) { + // There is a not resolve-able conflict with the selectedModule + // TODO print better warning + compilation.warnings.push( + new WebpackError( + `chunk ${chunk.name || chunk.id}\nConflicting order between ${ + /** @type {Module} */ + (hasFailed).readableIdentifier(compilation.requestShortener) + } and ${selectedModule.readableIdentifier( + compilation.requestShortener + )}` + ) + ); + selectedModule = /** @type {Module} */ (hasFailed); + } + // Insert the selected module into the final modules list + finalModules.push(selectedModule); + // Remove the selected module from all lists + for (const { list, set } of modulesByChunkGroup) { + const lastModule = list[list.length - 1]; + if (lastModule === selectedModule) list.pop(); + else if (hasFailed && set.has(selectedModule)) { + const idx = list.indexOf(selectedModule); + if (idx >= 0) list.splice(idx, 1); + } + } + modulesByChunkGroup.sort(compareModuleLists); + } + return finalModules; + } + + /** + * @param {Chunk} chunk chunk + * @param {ChunkGraph} chunkGraph chunk graph + * @param {Compilation} compilation compilation + * @returns {Module[]} ordered css modules + */ + getOrderedChunkCssModules(chunk, chunkGraph, compilation) { + return [ + ...this.getModulesInOrder( + chunk, + /** @type {Iterable} */ + ( + chunkGraph.getOrderedChunkModulesIterableBySourceType( + chunk, + "css-import", + compareModulesByIdentifier + ) + ), + compilation + ), + ...this.getModulesInOrder( + chunk, + /** @type {Iterable} */ + ( + chunkGraph.getOrderedChunkModulesIterableBySourceType( + chunk, + "css", + compareModulesByIdentifier + ) + ), + compilation + ) + ]; + } + + /** + * @param {object} options options + * @param {string[]} options.metaData meta data + * @param {string} options.undoPath undo path for public path auto + * @param {Chunk} options.chunk chunk + * @param {ChunkGraph} options.chunkGraph chunk graph + * @param {CodeGenerationResults} options.codeGenerationResults code generation results + * @param {CssModule} options.module css module + * @param {RuntimeTemplate} options.runtimeTemplate runtime template + * @param {CompilationHooks} options.hooks hooks + * @returns {Source} css module source + */ + renderModule({ + metaData, + undoPath, + chunk, + chunkGraph, + codeGenerationResults, + module, + hooks, + runtimeTemplate + }) { + const codeGenResult = codeGenerationResults.get(module, chunk.runtime); + const moduleSourceContent = + /** @type {Source} */ + ( + codeGenResult.sources.get("css") || + codeGenResult.sources.get("css-import") + ); + + const cacheEntry = this._moduleCache.get(moduleSourceContent); + + /** @type {Inheritance} */ + const inheritance = [[module.cssLayer, module.supports, module.media]]; + if (module.inheritance) { + inheritance.push(...module.inheritance); + } + + let source; + if ( + cacheEntry && + cacheEntry.undoPath === undoPath && + cacheEntry.inheritance.every(([layer, supports, media], i) => { + const item = inheritance[i]; + if (Array.isArray(item)) { + return layer === item[0] && supports === item[1] && media === item[2]; + } + return false; + }) + ) { + source = cacheEntry.source; + } else { + const moduleSourceCode = /** @type {string} */ ( + moduleSourceContent.source() + ); + const publicPathAutoRegex = new RegExp( + CssUrlDependency.PUBLIC_PATH_AUTO, + "g" + ); + /** @type {Source} */ + let moduleSource = new ReplaceSource(moduleSourceContent); + let match; + while ((match = publicPathAutoRegex.exec(moduleSourceCode))) { + /** @type {ReplaceSource} */ (moduleSource).replace( + match.index, + (match.index += match[0].length - 1), + undoPath + ); + } + + for (let i = 0; i < inheritance.length; i++) { + const layer = inheritance[i][0]; + const supports = inheritance[i][1]; + const media = inheritance[i][2]; + + if (media) { + moduleSource = new ConcatSource( + `@media ${media} {\n`, + new PrefixSource("\t", moduleSource), + "}\n" + ); + } + + if (supports) { + moduleSource = new ConcatSource( + `@supports (${supports}) {\n`, + new PrefixSource("\t", moduleSource), + "}\n" + ); + } + + // Layer can be anonymous + if (layer !== undefined && layer !== null) { + moduleSource = new ConcatSource( + `@layer${layer ? ` ${layer}` : ""} {\n`, + new PrefixSource("\t", moduleSource), + "}\n" + ); + } + } + + if (moduleSource) { + moduleSource = new ConcatSource(moduleSource, "\n"); + } + + source = new CachedSource(moduleSource); + this._moduleCache.set(moduleSourceContent, { + inheritance, + undoPath, + source + }); + } + /** @type {CssExportsData | undefined} */ + const cssExportsData = + codeGenResult.data && codeGenResult.data.get("css-exports"); + const exports = cssExportsData && cssExportsData.exports; + const esModule = cssExportsData && cssExportsData.esModule; + let moduleId = String(chunkGraph.getModuleId(module)); + + // When `optimization.moduleIds` is `named` the module id is a path, so we need to normalize it between platforms + if (typeof moduleId === "string") { + moduleId = moduleId.replace(/\\/g, "/"); + } + + metaData.push( + `${ + exports + ? Array.from( + exports, + ([n, v]) => `${escapeCss(n)}:${escapeCss(v)}/` + ).join("") + : "" + }${esModule ? "&" : ""}${escapeCss(moduleId)}` + ); + return tryRunOrWebpackError( + () => + hooks.renderModulePackage.call(source, module, { + runtimeTemplate + }), + "CssModulesPlugin.getCompilationHooks().renderModulePackage" + ); + } + + /** + * @param {object} options options + * @param {string | undefined} options.uniqueName unique name + * @param {boolean | undefined} options.cssHeadDataCompression compress css head data + * @param {string} options.undoPath undo path for public path auto + * @param {Chunk} options.chunk chunk + * @param {ChunkGraph} options.chunkGraph chunk graph + * @param {CodeGenerationResults} options.codeGenerationResults code generation results + * @param {CssModule[]} options.modules ordered css modules + * @param {RuntimeTemplate} options.runtimeTemplate runtime template + * @param {CompilationHooks} options.hooks hooks + * @returns {Source} generated source + */ + renderChunk({ + uniqueName, + cssHeadDataCompression, + undoPath, + chunk, + chunkGraph, + codeGenerationResults, + modules, + runtimeTemplate, + hooks + }) { + const source = new ConcatSource(); + /** @type {string[]} */ + const metaData = []; + for (const module of modules) { + try { + const moduleSource = this.renderModule({ + metaData, + undoPath, + chunk, + chunkGraph, + codeGenerationResults, + module, + runtimeTemplate, + hooks + }); + source.add(moduleSource); + } catch (err) { + /** @type {Error} */ + (err).message += `\nduring rendering of css ${module.identifier()}`; + throw err; + } + } + const metaDataStr = metaData.join(","); + source.add( + `head{--webpack-${escapeCss( + (uniqueName ? `${uniqueName}-` : "") + chunk.id, + true + )}:${cssHeadDataCompression ? lzwEncode(metaDataStr) : metaDataStr};}` + ); + chunk.rendered = true; + return source; + } + + /** + * @param {Chunk} chunk chunk + * @param {OutputOptions} outputOptions output options + * @returns {TemplatePath} used filename template + */ + static getChunkFilenameTemplate(chunk, outputOptions) { + if (chunk.cssFilenameTemplate) { + return chunk.cssFilenameTemplate; + } else if (chunk.canBeInitial()) { + return /** @type {TemplatePath} */ (outputOptions.cssFilename); + } + return /** @type {TemplatePath} */ (outputOptions.cssChunkFilename); + } + + /** + * @param {Chunk} chunk chunk + * @param {ChunkGraph} chunkGraph chunk graph + * @returns {boolean} true, when the chunk has css + */ + static chunkHasCss(chunk, chunkGraph) { + return ( + Boolean(chunkGraph.getChunkModulesIterableBySourceType(chunk, "css")) || + Boolean( + chunkGraph.getChunkModulesIterableBySourceType(chunk, "css-import") + ) + ); + } +} + +module.exports = CssModulesPlugin; diff --git a/lib/css/CssParser.js b/lib/css/CssParser.js new file mode 100644 index 00000000000..cf7633bf29b --- /dev/null +++ b/lib/css/CssParser.js @@ -0,0 +1,1049 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ + +"use strict"; + +const ModuleDependencyWarning = require("../ModuleDependencyWarning"); +const { CSS_MODULE_TYPE_AUTO } = require("../ModuleTypeConstants"); +const Parser = require("../Parser"); +const WebpackError = require("../WebpackError"); +const ConstDependency = require("../dependencies/ConstDependency"); +const CssExportDependency = require("../dependencies/CssExportDependency"); +const CssImportDependency = require("../dependencies/CssImportDependency"); +const CssLocalIdentifierDependency = require("../dependencies/CssLocalIdentifierDependency"); +const CssSelfLocalIdentifierDependency = require("../dependencies/CssSelfLocalIdentifierDependency"); +const CssUrlDependency = require("../dependencies/CssUrlDependency"); +const StaticExportsDependency = require("../dependencies/StaticExportsDependency"); +const { parseResource } = require("../util/identifier"); +const walkCssTokens = require("./walkCssTokens"); + +/** @typedef {import("../Parser").ParserState} ParserState */ +/** @typedef {import("../Parser").PreparsedAst} PreparsedAst */ +/** @typedef {[number, number]} Range */ + +const CC_LEFT_CURLY = "{".charCodeAt(0); +const CC_RIGHT_CURLY = "}".charCodeAt(0); +const CC_COLON = ":".charCodeAt(0); +const CC_SLASH = "/".charCodeAt(0); +const CC_SEMICOLON = ";".charCodeAt(0); + +// https://www.w3.org/TR/css-syntax-3/#newline +// We don't have `preprocessing` stage, so we need specify all of them +const STRING_MULTILINE = /\\[\n\r\f]/g; +// https://www.w3.org/TR/css-syntax-3/#whitespace +const TRIM_WHITE_SPACES = /(^[ \t\n\r\f]*|[ \t\n\r\f]*$)/g; +const UNESCAPE = /\\([0-9a-fA-F]{1,6}[ \t\n\r\f]?|[\s\S])/g; +const IMAGE_SET_FUNCTION = /^(-\w+-)?image-set$/i; +const OPTIONALLY_VENDOR_PREFIXED_KEYFRAMES_AT_RULE = /^@(-\w+-)?keyframes$/; +const OPTIONALLY_VENDOR_PREFIXED_ANIMATION_PROPERTY = + /^(-\w+-)?animation(-name)?$/i; +const IS_MODULES = /\.module(s)?\.[^.]+$/i; + +/** + * @param {string} str url string + * @param {boolean} isString is url wrapped in quotes + * @returns {string} normalized url + */ +const normalizeUrl = (str, isString) => { + // Remove extra spaces and newlines: + // `url("im\ + // g.png")` + if (isString) { + str = str.replace(STRING_MULTILINE, ""); + } + + str = str + // Remove unnecessary spaces from `url(" img.png ")` + .replace(TRIM_WHITE_SPACES, "") + // Unescape + .replace(UNESCAPE, match => { + if (match.length > 2) { + return String.fromCharCode(Number.parseInt(match.slice(1).trim(), 16)); + } + return match[1]; + }); + + if (/^data:/i.test(str)) { + return str; + } + + if (str.includes("%")) { + // Convert `url('%2E/img.png')` -> `url('./img.png')` + try { + str = decodeURIComponent(str); + } catch (_err) { + // Ignore + } + } + + return str; +}; + +class LocConverter { + /** + * @param {string} input input + */ + constructor(input) { + this._input = input; + this.line = 1; + this.column = 0; + this.pos = 0; + } + + /** + * @param {number} pos position + * @returns {LocConverter} location converter + */ + get(pos) { + if (this.pos !== pos) { + if (this.pos < pos) { + const str = this._input.slice(this.pos, pos); + let i = str.lastIndexOf("\n"); + if (i === -1) { + this.column += str.length; + } else { + this.column = str.length - i - 1; + this.line++; + while (i > 0 && (i = str.lastIndexOf("\n", i - 1)) !== -1) + this.line++; + } + } else { + let i = this._input.lastIndexOf("\n", this.pos); + while (i >= pos) { + this.line--; + i = i > 0 ? this._input.lastIndexOf("\n", i - 1) : -1; + } + this.column = pos - i; + } + this.pos = pos; + } + return this; + } +} + +const CSS_MODE_TOP_LEVEL = 0; +const CSS_MODE_IN_BLOCK = 1; +const CSS_MODE_IN_AT_IMPORT = 2; +const CSS_MODE_AT_IMPORT_INVALID = 3; +const CSS_MODE_AT_NAMESPACE_INVALID = 4; + +class CssParser extends Parser { + constructor({ + allowModeSwitch = true, + defaultMode = "global", + namedExports = true + } = {}) { + super(); + this.allowModeSwitch = allowModeSwitch; + this.defaultMode = defaultMode; + this.namedExports = namedExports; + } + + /** + * @param {ParserState} state parser state + * @param {string} message warning message + * @param {LocConverter} locConverter location converter + * @param {number} start start offset + * @param {number} end end offset + */ + _emitWarning(state, message, locConverter, start, end) { + const { line: sl, column: sc } = locConverter.get(start); + const { line: el, column: ec } = locConverter.get(end); + + state.current.addWarning( + new ModuleDependencyWarning(state.module, new WebpackError(message), { + start: { line: sl, column: sc }, + end: { line: el, column: ec } + }) + ); + } + + /** + * @param {string | Buffer | PreparsedAst} source the source to parse + * @param {ParserState} state the parser state + * @returns {ParserState} the parser state + */ + parse(source, state) { + if (Buffer.isBuffer(source)) { + source = source.toString("utf-8"); + } else if (typeof source === "object") { + throw new Error("webpackAst is unexpected for the CssParser"); + } + if (source[0] === "\uFEFF") { + source = source.slice(1); + } + + const module = state.module; + + /** @type {string | undefined} */ + let oldDefaultMode; + + if ( + module.type === CSS_MODULE_TYPE_AUTO && + IS_MODULES.test( + parseResource(module.matchResource || module.resource).path + ) + ) { + oldDefaultMode = this.defaultMode; + + this.defaultMode = "local"; + } + + const locConverter = new LocConverter(source); + /** @type {Set} */ + const declaredCssVariables = new Set(); + /** @type {number} */ + let scope = CSS_MODE_TOP_LEVEL; + /** @type {number} */ + let blockNestingLevel = 0; + /** @type {boolean} */ + let allowImportAtRule = true; + /** @type {"local" | "global" | undefined} */ + let modeData; + /** @type {[number, number] | undefined} */ + let lastIdentifier; + /** @type [string, number, number][] */ + const balanced = []; + /** @type {undefined | { start: number, url?: string, urlStart?: number, urlEnd?: number, layer?: string, layerStart?: number, layerEnd?: number, supports?: string, supportsStart?: number, supportsEnd?: number, inSupports?:boolean, media?: string }} */ + let importData; + /** @type {boolean} */ + let inAnimationProperty = false; + /** @type {boolean} */ + let isNextRulePrelude = true; + + /** + * @param {string} input input + * @param {number} pos position + * @returns {boolean} true, when next is nested syntax + */ + const isNextNestedSyntax = (input, pos) => { + pos = walkCssTokens.eatWhitespaceAndComments(input, pos); + + if (input[pos] === "}") { + return false; + } + + // According spec only identifier can be used as a property name + const isIdentifier = walkCssTokens.isIdentStartCodePoint( + input.charCodeAt(pos) + ); + + return !isIdentifier; + }; + /** + * @returns {boolean} true, when in local scope + */ + const isLocalMode = () => + modeData === "local" || + (this.defaultMode === "local" && modeData === undefined); + /** + * @param {string} chars characters + * @returns {(input: string, pos: number) => number} function to eat characters + */ + const eatUntil = chars => { + const charCodes = Array.from({ length: chars.length }, (_, i) => + chars.charCodeAt(i) + ); + const arr = Array.from( + { length: charCodes.reduce((a, b) => Math.max(a, b), 0) + 1 }, + () => false + ); + for (const cc of charCodes) { + arr[cc] = true; + } + return (input, pos) => { + for (;;) { + const cc = input.charCodeAt(pos); + if (cc < arr.length && arr[cc]) { + return pos; + } + pos++; + if (pos === input.length) return pos; + } + }; + }; + /** + * @param {string} input input + * @param {number} pos start position + * @param {(input: string, pos: number) => number} eater eater + * @returns {[number,string]} new position and text + */ + const eatText = (input, pos, eater) => { + let text = ""; + for (;;) { + if (input.charCodeAt(pos) === CC_SLASH) { + const newPos = walkCssTokens.eatComments(input, pos); + if (pos !== newPos) { + pos = newPos; + if (pos === input.length) break; + } else { + text += "/"; + pos++; + if (pos === input.length) break; + } + } + const newPos = eater(input, pos); + if (pos !== newPos) { + text += input.slice(pos, newPos); + pos = newPos; + } else { + break; + } + if (pos === input.length) break; + } + return [pos, text.trimEnd()]; + }; + const eatExportName = eatUntil(":};/"); + const eatExportValue = eatUntil("};/"); + /** + * @param {string} input input + * @param {number} pos start position + * @returns {number} position after parse + */ + const parseExports = (input, pos) => { + pos = walkCssTokens.eatWhitespaceAndComments(input, pos); + const cc = input.charCodeAt(pos); + if (cc !== CC_LEFT_CURLY) { + this._emitWarning( + state, + `Unexpected '${input[pos]}' at ${pos} during parsing of ':export' (expected '{')`, + locConverter, + pos, + pos + ); + return pos; + } + pos++; + pos = walkCssTokens.eatWhitespaceAndComments(input, pos); + for (;;) { + if (input.charCodeAt(pos) === CC_RIGHT_CURLY) break; + pos = walkCssTokens.eatWhitespaceAndComments(input, pos); + if (pos === input.length) return pos; + const start = pos; + let name; + [pos, name] = eatText(input, pos, eatExportName); + if (pos === input.length) return pos; + if (input.charCodeAt(pos) !== CC_COLON) { + this._emitWarning( + state, + `Unexpected '${input[pos]}' at ${pos} during parsing of export name in ':export' (expected ':')`, + locConverter, + start, + pos + ); + return pos; + } + pos++; + if (pos === input.length) return pos; + pos = walkCssTokens.eatWhitespaceAndComments(input, pos); + if (pos === input.length) return pos; + let value; + [pos, value] = eatText(input, pos, eatExportValue); + if (pos === input.length) return pos; + const cc = input.charCodeAt(pos); + if (cc === CC_SEMICOLON) { + pos++; + if (pos === input.length) return pos; + pos = walkCssTokens.eatWhitespaceAndComments(input, pos); + if (pos === input.length) return pos; + } else if (cc !== CC_RIGHT_CURLY) { + this._emitWarning( + state, + `Unexpected '${input[pos]}' at ${pos} during parsing of export value in ':export' (expected ';' or '}')`, + locConverter, + start, + pos + ); + return pos; + } + const dep = new CssExportDependency(name, value); + const { line: sl, column: sc } = locConverter.get(start); + const { line: el, column: ec } = locConverter.get(pos); + dep.setLoc(sl, sc, el, ec); + module.addDependency(dep); + } + pos++; + if (pos === input.length) return pos; + pos = walkCssTokens.eatWhiteLine(input, pos); + return pos; + }; + const eatPropertyName = eatUntil(":{};"); + /** + * @param {string} input input + * @param {number} pos name start position + * @param {number} end name end position + * @returns {number} position after handling + */ + const processLocalDeclaration = (input, pos, end) => { + modeData = undefined; + pos = walkCssTokens.eatWhitespaceAndComments(input, pos); + const propertyNameStart = pos; + const [propertyNameEnd, propertyName] = eatText( + input, + pos, + eatPropertyName + ); + if (input.charCodeAt(propertyNameEnd) !== CC_COLON) return end; + pos = propertyNameEnd + 1; + if (propertyName.startsWith("--")) { + // CSS Variable + const { line: sl, column: sc } = locConverter.get(propertyNameStart); + const { line: el, column: ec } = locConverter.get(propertyNameEnd); + const name = propertyName.slice(2); + const dep = new CssLocalIdentifierDependency( + name, + [propertyNameStart, propertyNameEnd], + "--" + ); + dep.setLoc(sl, sc, el, ec); + module.addDependency(dep); + declaredCssVariables.add(name); + } else if ( + !propertyName.startsWith("--") && + OPTIONALLY_VENDOR_PREFIXED_ANIMATION_PROPERTY.test(propertyName) + ) { + inAnimationProperty = true; + } + return pos; + }; + /** + * @param {string} input input + */ + const processDeclarationValueDone = input => { + if (inAnimationProperty && lastIdentifier) { + const { line: sl, column: sc } = locConverter.get(lastIdentifier[0]); + const { line: el, column: ec } = locConverter.get(lastIdentifier[1]); + const name = input.slice(lastIdentifier[0], lastIdentifier[1]); + const dep = new CssSelfLocalIdentifierDependency(name, lastIdentifier); + dep.setLoc(sl, sc, el, ec); + module.addDependency(dep); + lastIdentifier = undefined; + } + }; + const eatKeyframes = eatUntil("{};/"); + const eatNameInVar = eatUntil(",)};/"); + walkCssTokens(source, { + isSelector: () => isNextRulePrelude, + url: (input, start, end, contentStart, contentEnd) => { + const value = normalizeUrl( + input.slice(contentStart, contentEnd), + false + ); + + switch (scope) { + case CSS_MODE_IN_AT_IMPORT: { + // Do not parse URLs in `supports(...)` + if (importData.inSupports) { + break; + } + + if (importData.url) { + this._emitWarning( + state, + `Duplicate of 'url(...)' in '${input.slice( + importData.start, + end + )}'`, + locConverter, + start, + end + ); + + break; + } + + importData.url = value; + importData.urlStart = start; + importData.urlEnd = end; + break; + } + // Do not parse URLs in import between rules + case CSS_MODE_AT_NAMESPACE_INVALID: + case CSS_MODE_AT_IMPORT_INVALID: { + break; + } + case CSS_MODE_IN_BLOCK: { + // Ignore `url()`, `url('')` and `url("")`, they are valid by spec + if (value.length === 0) { + break; + } + + const dep = new CssUrlDependency(value, [start, end], "url"); + const { line: sl, column: sc } = locConverter.get(start); + const { line: el, column: ec } = locConverter.get(end); + dep.setLoc(sl, sc, el, ec); + module.addDependency(dep); + module.addCodeGenerationDependency(dep); + break; + } + } + return end; + }, + string: (input, start, end) => { + switch (scope) { + case CSS_MODE_IN_AT_IMPORT: { + const insideURLFunction = + balanced[balanced.length - 1] && + balanced[balanced.length - 1][0] === "url"; + + // Do not parse URLs in `supports(...)` and other strings if we already have a URL + if ( + importData.inSupports || + (!insideURLFunction && importData.url) + ) { + break; + } + + if (insideURLFunction && importData.url) { + this._emitWarning( + state, + `Duplicate of 'url(...)' in '${input.slice( + importData.start, + end + )}'`, + locConverter, + start, + end + ); + + break; + } + + importData.url = normalizeUrl( + input.slice(start + 1, end - 1), + true + ); + + if (!insideURLFunction) { + importData.urlStart = start; + importData.urlEnd = end; + } + + break; + } + case CSS_MODE_IN_BLOCK: { + // TODO move escaped parsing to tokenizer + const last = balanced[balanced.length - 1]; + + if ( + last && + (last[0].replace(/\\/g, "").toLowerCase() === "url" || + IMAGE_SET_FUNCTION.test(last[0].replace(/\\/g, ""))) + ) { + const value = normalizeUrl(input.slice(start + 1, end - 1), true); + + // Ignore `url()`, `url('')` and `url("")`, they are valid by spec + if (value.length === 0) { + break; + } + + const isUrl = last[0].replace(/\\/g, "").toLowerCase() === "url"; + const dep = new CssUrlDependency( + value, + [start, end], + isUrl ? "string" : "url" + ); + const { line: sl, column: sc } = locConverter.get(start); + const { line: el, column: ec } = locConverter.get(end); + dep.setLoc(sl, sc, el, ec); + module.addDependency(dep); + module.addCodeGenerationDependency(dep); + } + } + } + return end; + }, + atKeyword: (input, start, end) => { + const name = input.slice(start, end).toLowerCase(); + if (name === "@namespace") { + scope = CSS_MODE_AT_NAMESPACE_INVALID; + this._emitWarning( + state, + "'@namespace' is not supported in bundled CSS", + locConverter, + start, + end + ); + return end; + } else if (name === "@import") { + if (!allowImportAtRule) { + scope = CSS_MODE_AT_IMPORT_INVALID; + this._emitWarning( + state, + "Any '@import' rules must precede all other rules", + locConverter, + start, + end + ); + return end; + } + + scope = CSS_MODE_IN_AT_IMPORT; + importData = { start }; + } else if ( + this.allowModeSwitch && + OPTIONALLY_VENDOR_PREFIXED_KEYFRAMES_AT_RULE.test(name) + ) { + let pos = end; + pos = walkCssTokens.eatWhitespaceAndComments(input, pos); + if (pos === input.length) return pos; + const [newPos, name] = eatText(input, pos, eatKeyframes); + if (newPos === input.length) return newPos; + if (input.charCodeAt(newPos) !== CC_LEFT_CURLY) { + this._emitWarning( + state, + `Unexpected '${input[newPos]}' at ${newPos} during parsing of @keyframes (expected '{')`, + locConverter, + start, + end + ); + + return newPos; + } + if (isLocalMode()) { + const { line: sl, column: sc } = locConverter.get(pos); + const { line: el, column: ec } = locConverter.get(newPos); + const dep = new CssLocalIdentifierDependency(name, [pos, newPos]); + dep.setLoc(sl, sc, el, ec); + module.addDependency(dep); + } + pos = newPos; + return pos + 1; + } else if (this.allowModeSwitch && name === "@property") { + let pos = end; + pos = walkCssTokens.eatWhitespaceAndComments(input, pos); + if (pos === input.length) return pos; + const propertyNameStart = pos; + const [propertyNameEnd, propertyName] = eatText( + input, + pos, + eatKeyframes + ); + if (propertyNameEnd === input.length) return propertyNameEnd; + if (!propertyName.startsWith("--")) return propertyNameEnd; + if (input.charCodeAt(propertyNameEnd) !== CC_LEFT_CURLY) { + this._emitWarning( + state, + `Unexpected '${input[propertyNameEnd]}' at ${propertyNameEnd} during parsing of @property (expected '{')`, + locConverter, + start, + end + ); + + return propertyNameEnd; + } + const name = propertyName.slice(2); + declaredCssVariables.add(name); + if (isLocalMode()) { + const { line: sl, column: sc } = locConverter.get(pos); + const { line: el, column: ec } = locConverter.get(propertyNameEnd); + const dep = new CssLocalIdentifierDependency( + name, + [propertyNameStart, propertyNameEnd], + "--" + ); + dep.setLoc(sl, sc, el, ec); + module.addDependency(dep); + } + pos = propertyNameEnd; + return pos + 1; + } else if ( + name === "@media" || + name === "@supports" || + name === "@layer" || + name === "@container" + ) { + modeData = isLocalMode() ? "local" : "global"; + isNextRulePrelude = true; + return end; + } else if (this.allowModeSwitch) { + modeData = "global"; + isNextRulePrelude = false; + } + return end; + }, + semicolon: (input, start, end) => { + switch (scope) { + case CSS_MODE_IN_AT_IMPORT: { + const { start } = importData; + + if (importData.url === undefined) { + this._emitWarning( + state, + `Expected URL in '${input.slice(start, end)}'`, + locConverter, + start, + end + ); + importData = undefined; + scope = CSS_MODE_TOP_LEVEL; + return end; + } + if ( + importData.urlStart > importData.layerStart || + importData.urlStart > importData.supportsStart + ) { + this._emitWarning( + state, + `An URL in '${input.slice( + start, + end + )}' should be before 'layer(...)' or 'supports(...)'`, + locConverter, + start, + end + ); + importData = undefined; + scope = CSS_MODE_TOP_LEVEL; + return end; + } + if (importData.layerStart > importData.supportsStart) { + this._emitWarning( + state, + `The 'layer(...)' in '${input.slice( + start, + end + )}' should be before 'supports(...)'`, + locConverter, + start, + end + ); + importData = undefined; + scope = CSS_MODE_TOP_LEVEL; + return end; + } + + const semicolonPos = end; + end = walkCssTokens.eatWhiteLine(input, end); + const { line: sl, column: sc } = locConverter.get(start); + const { line: el, column: ec } = locConverter.get(end); + const lastEnd = + importData.supportsEnd || + importData.layerEnd || + importData.urlEnd || + start; + const pos = walkCssTokens.eatWhitespaceAndComments(input, lastEnd); + // Prevent to consider comments as a part of media query + if (pos !== semicolonPos - 1) { + importData.media = input.slice(lastEnd, semicolonPos - 1).trim(); + } + + const url = importData.url.trim(); + + if (url.length === 0) { + const dep = new ConstDependency("", [start, end]); + module.addPresentationalDependency(dep); + dep.setLoc(sl, sc, el, ec); + } else { + const dep = new CssImportDependency( + url, + [start, end], + importData.layer, + importData.supports, + importData.media && importData.media.length > 0 + ? importData.media + : undefined + ); + dep.setLoc(sl, sc, el, ec); + module.addDependency(dep); + } + + importData = undefined; + scope = CSS_MODE_TOP_LEVEL; + + break; + } + case CSS_MODE_AT_IMPORT_INVALID: + case CSS_MODE_AT_NAMESPACE_INVALID: { + scope = CSS_MODE_TOP_LEVEL; + + break; + } + case CSS_MODE_IN_BLOCK: { + if (this.allowModeSwitch) { + processDeclarationValueDone(input); + inAnimationProperty = false; + isNextRulePrelude = isNextNestedSyntax(input, end); + } + break; + } + } + return end; + }, + leftCurlyBracket: (input, start, end) => { + switch (scope) { + case CSS_MODE_TOP_LEVEL: { + allowImportAtRule = false; + scope = CSS_MODE_IN_BLOCK; + blockNestingLevel = 1; + + if (this.allowModeSwitch) { + isNextRulePrelude = isNextNestedSyntax(input, end); + } + + break; + } + case CSS_MODE_IN_BLOCK: { + blockNestingLevel++; + + if (this.allowModeSwitch) { + isNextRulePrelude = isNextNestedSyntax(input, end); + } + break; + } + } + return end; + }, + rightCurlyBracket: (input, start, end) => { + switch (scope) { + case CSS_MODE_IN_BLOCK: { + if (isLocalMode()) { + processDeclarationValueDone(input); + inAnimationProperty = false; + } + if (--blockNestingLevel === 0) { + scope = CSS_MODE_TOP_LEVEL; + + if (this.allowModeSwitch) { + isNextRulePrelude = true; + modeData = undefined; + } + } else if (this.allowModeSwitch) { + isNextRulePrelude = isNextNestedSyntax(input, end); + } + break; + } + } + return end; + }, + identifier: (input, start, end) => { + switch (scope) { + case CSS_MODE_IN_BLOCK: { + if (isLocalMode()) { + // Handle only top level values and not inside functions + if (inAnimationProperty && balanced.length === 0) { + lastIdentifier = [start, end]; + } else { + return processLocalDeclaration(input, start, end); + } + } + break; + } + case CSS_MODE_IN_AT_IMPORT: { + if (input.slice(start, end).toLowerCase() === "layer") { + importData.layer = ""; + importData.layerStart = start; + importData.layerEnd = end; + } + break; + } + } + return end; + }, + class: (input, start, end) => { + if (isLocalMode()) { + const name = input.slice(start + 1, end); + const dep = new CssLocalIdentifierDependency(name, [start + 1, end]); + const { line: sl, column: sc } = locConverter.get(start); + const { line: el, column: ec } = locConverter.get(end); + dep.setLoc(sl, sc, el, ec); + module.addDependency(dep); + } + + return end; + }, + id: (input, start, end) => { + if (isLocalMode()) { + const name = input.slice(start + 1, end); + const dep = new CssLocalIdentifierDependency(name, [start + 1, end]); + const { line: sl, column: sc } = locConverter.get(start); + const { line: el, column: ec } = locConverter.get(end); + dep.setLoc(sl, sc, el, ec); + module.addDependency(dep); + } + return end; + }, + function: (input, start, end) => { + let name = input.slice(start, end - 1); + + balanced.push([name, start, end]); + + if ( + scope === CSS_MODE_IN_AT_IMPORT && + name.toLowerCase() === "supports" + ) { + importData.inSupports = true; + } + + if (isLocalMode()) { + name = name.toLowerCase(); + + // Don't rename animation name when we have `var()` function + if (inAnimationProperty && balanced.length === 1) { + lastIdentifier = undefined; + } + + if (name === "var") { + const pos = walkCssTokens.eatWhitespaceAndComments(input, end); + if (pos === input.length) return pos; + const [newPos, name] = eatText(input, pos, eatNameInVar); + if (!name.startsWith("--")) return end; + const { line: sl, column: sc } = locConverter.get(pos); + const { line: el, column: ec } = locConverter.get(newPos); + const dep = new CssSelfLocalIdentifierDependency( + name.slice(2), + [pos, newPos], + "--", + declaredCssVariables + ); + dep.setLoc(sl, sc, el, ec); + module.addDependency(dep); + return newPos; + } + } + + return end; + }, + leftParenthesis: (input, start, end) => { + balanced.push(["(", start, end]); + + return end; + }, + rightParenthesis: (input, start, end) => { + const last = balanced[balanced.length - 1]; + const popped = balanced.pop(); + + if ( + this.allowModeSwitch && + popped && + (popped[0] === ":local" || popped[0] === ":global") + ) { + modeData = balanced[balanced.length - 1] + ? /** @type {"local" | "global"} */ + (balanced[balanced.length - 1][0]) + : undefined; + const dep = new ConstDependency("", [start, end]); + module.addPresentationalDependency(dep); + + return end; + } + + switch (scope) { + case CSS_MODE_IN_AT_IMPORT: { + if (last && last[0] === "url" && !importData.inSupports) { + importData.urlStart = last[1]; + importData.urlEnd = end; + } else if ( + last && + last[0].toLowerCase() === "layer" && + !importData.inSupports + ) { + importData.layer = input.slice(last[2], end - 1).trim(); + importData.layerStart = last[1]; + importData.layerEnd = end; + } else if (last && last[0].toLowerCase() === "supports") { + importData.supports = input.slice(last[2], end - 1).trim(); + importData.supportsStart = last[1]; + importData.supportsEnd = end; + importData.inSupports = false; + } + break; + } + } + + return end; + }, + pseudoClass: (input, start, end) => { + if (this.allowModeSwitch) { + const name = input.slice(start, end).toLowerCase(); + + if (name === ":global") { + modeData = "global"; + // Eat extra whitespace and comments + end = walkCssTokens.eatWhitespace(input, end); + const dep = new ConstDependency("", [start, end]); + module.addPresentationalDependency(dep); + return end; + } else if (name === ":local") { + modeData = "local"; + // Eat extra whitespace and comments + end = walkCssTokens.eatWhitespace(input, end); + const dep = new ConstDependency("", [start, end]); + module.addPresentationalDependency(dep); + return end; + } + + switch (scope) { + case CSS_MODE_TOP_LEVEL: { + if (name === ":export") { + const pos = parseExports(input, end); + const dep = new ConstDependency("", [start, pos]); + module.addPresentationalDependency(dep); + return pos; + } + break; + } + } + } + + return end; + }, + pseudoFunction: (input, start, end) => { + let name = input.slice(start, end - 1); + + balanced.push([name, start, end]); + + if (this.allowModeSwitch) { + name = name.toLowerCase(); + + if (name === ":global") { + modeData = "global"; + const dep = new ConstDependency("", [start, end]); + module.addPresentationalDependency(dep); + } else if (name === ":local") { + modeData = "local"; + const dep = new ConstDependency("", [start, end]); + module.addPresentationalDependency(dep); + } + } + + return end; + }, + comma: (input, start, end) => { + if (this.allowModeSwitch) { + // Reset stack for `:global .class :local .class-other` selector after + modeData = undefined; + + switch (scope) { + case CSS_MODE_IN_BLOCK: { + if (isLocalMode()) { + processDeclarationValueDone(input); + } + + break; + } + } + } + return end; + } + }); + + if (oldDefaultMode) { + this.defaultMode = oldDefaultMode; + } + + module.buildInfo.strict = true; + module.buildMeta.exportsType = this.namedExports ? "namespace" : "default"; + + if (!this.namedExports) { + module.buildMeta.defaultObject = "redirect"; + } + + module.addDependency(new StaticExportsDependency([], true)); + return state; + } +} + +module.exports = CssParser; diff --git a/lib/css/walkCssTokens.js b/lib/css/walkCssTokens.js new file mode 100644 index 00000000000..849515386e2 --- /dev/null +++ b/lib/css/walkCssTokens.js @@ -0,0 +1,775 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ + +"use strict"; + +/** + * @typedef {object} CssTokenCallbacks + * @property {function(string, number): boolean=} isSelector + * @property {function(string, number, number, number, number): number=} url + * @property {function(string, number, number): number=} string + * @property {function(string, number, number): number=} leftParenthesis + * @property {function(string, number, number): number=} rightParenthesis + * @property {function(string, number, number): number=} pseudoFunction + * @property {function(string, number, number): number=} function + * @property {function(string, number, number): number=} pseudoClass + * @property {function(string, number, number): number=} atKeyword + * @property {function(string, number, number): number=} class + * @property {function(string, number, number): number=} identifier + * @property {function(string, number, number): number=} id + * @property {function(string, number, number): number=} leftCurlyBracket + * @property {function(string, number, number): number=} rightCurlyBracket + * @property {function(string, number, number): number=} semicolon + * @property {function(string, number, number): number=} comma + */ + +/** @typedef {function(string, number, CssTokenCallbacks): number} CharHandler */ + +// spec: https://drafts.csswg.org/css-syntax/ + +const CC_LINE_FEED = "\n".charCodeAt(0); +const CC_CARRIAGE_RETURN = "\r".charCodeAt(0); +const CC_FORM_FEED = "\f".charCodeAt(0); + +const CC_TAB = "\t".charCodeAt(0); +const CC_SPACE = " ".charCodeAt(0); + +const CC_SOLIDUS = "/".charCodeAt(0); +const CC_REVERSE_SOLIDUS = "\\".charCodeAt(0); +const CC_ASTERISK = "*".charCodeAt(0); + +const CC_LEFT_PARENTHESIS = "(".charCodeAt(0); +const CC_RIGHT_PARENTHESIS = ")".charCodeAt(0); +const CC_LEFT_CURLY = "{".charCodeAt(0); +const CC_RIGHT_CURLY = "}".charCodeAt(0); +const CC_LEFT_SQUARE = "[".charCodeAt(0); +const CC_RIGHT_SQUARE = "]".charCodeAt(0); + +const CC_QUOTATION_MARK = '"'.charCodeAt(0); +const CC_APOSTROPHE = "'".charCodeAt(0); + +const CC_FULL_STOP = ".".charCodeAt(0); +const CC_COLON = ":".charCodeAt(0); +const CC_SEMICOLON = ";".charCodeAt(0); +const CC_COMMA = ",".charCodeAt(0); +const CC_PERCENTAGE = "%".charCodeAt(0); +const CC_AT_SIGN = "@".charCodeAt(0); + +const CC_LOW_LINE = "_".charCodeAt(0); +const CC_LOWER_A = "a".charCodeAt(0); +const CC_LOWER_U = "u".charCodeAt(0); +const CC_LOWER_E = "e".charCodeAt(0); +const CC_LOWER_Z = "z".charCodeAt(0); +const CC_UPPER_A = "A".charCodeAt(0); +const CC_UPPER_E = "E".charCodeAt(0); +const CC_UPPER_U = "U".charCodeAt(0); +const CC_UPPER_Z = "Z".charCodeAt(0); +const CC_0 = "0".charCodeAt(0); +const CC_9 = "9".charCodeAt(0); + +const CC_NUMBER_SIGN = "#".charCodeAt(0); +const CC_PLUS_SIGN = "+".charCodeAt(0); +const CC_HYPHEN_MINUS = "-".charCodeAt(0); + +const CC_LESS_THAN_SIGN = "<".charCodeAt(0); +const CC_GREATER_THAN_SIGN = ">".charCodeAt(0); + +/** + * @param {number} cc char code + * @returns {boolean} true, if cc is a newline + */ +const _isNewLine = cc => + cc === CC_LINE_FEED || cc === CC_CARRIAGE_RETURN || cc === CC_FORM_FEED; + +/** @type {CharHandler} */ +const consumeSpace = (input, pos, _callbacks) => { + /** @type {number} */ + let cc; + do { + pos++; + cc = input.charCodeAt(pos); + } while (_isWhiteSpace(cc)); + return pos; +}; + +/** + * @param {number} cc char code + * @returns {boolean} true, if cc is a newline + */ +const _isNewline = cc => + cc === CC_LINE_FEED || cc === CC_CARRIAGE_RETURN || cc === CC_FORM_FEED; + +/** + * @param {number} cc char code + * @returns {boolean} true, if cc is a space (U+0009 CHARACTER TABULATION or U+0020 SPACE) + */ +const _isSpace = cc => cc === CC_TAB || cc === CC_SPACE; + +/** + * @param {number} cc char code + * @returns {boolean} true, if cc is a whitespace + */ +const _isWhiteSpace = cc => _isNewline(cc) || _isSpace(cc); + +/** + * ident-start code point + * + * A letter, a non-ASCII code point, or U+005F LOW LINE (_). + * @param {number} cc char code + * @returns {boolean} true, if cc is a start code point of an identifier + */ +const isIdentStartCodePoint = cc => + (cc >= CC_LOWER_A && cc <= CC_LOWER_Z) || + (cc >= CC_UPPER_A && cc <= CC_UPPER_Z) || + cc === CC_LOW_LINE || + cc >= 0x80; + +/** @type {CharHandler} */ +const consumeDelimToken = (input, pos, _callbacks) => pos + 1; + +/** @type {CharHandler} */ +const consumeComments = (input, pos, _callbacks) => { + // If the next two input code point are U+002F SOLIDUS (/) followed by a U+002A + // ASTERISK (*), consume them and all following code points up to and including + // the first U+002A ASTERISK (*) followed by a U+002F SOLIDUS (/), or up to an + // EOF code point. Return to the start of this step. + // + // If the preceding paragraph ended by consuming an EOF code point, this is a parse error. + // But we are silent on errors. + if ( + input.charCodeAt(pos) === CC_SOLIDUS && + input.charCodeAt(pos + 1) === CC_ASTERISK + ) { + pos += 1; + while (pos < input.length) { + if ( + input.charCodeAt(pos) === CC_ASTERISK && + input.charCodeAt(pos + 1) === CC_SOLIDUS + ) { + pos += 2; + break; + } + pos++; + } + } + return pos; +}; + +/** @type {function(number): CharHandler} */ +const consumeString = quoteCc => (input, pos, callbacks) => { + const start = pos; + pos = _consumeString(input, pos, quoteCc); + if (callbacks.string !== undefined) { + pos = callbacks.string(input, start, pos); + } + return pos; +}; + +/** + * @param {string} input input + * @param {number} pos position + * @param {number} quoteCc quote char code + * @returns {number} new position + */ +const _consumeString = (input, pos, quoteCc) => { + pos++; + for (;;) { + if (pos === input.length) return pos; + const cc = input.charCodeAt(pos); + if (cc === quoteCc) return pos + 1; + if (_isNewLine(cc)) { + // bad string + return pos; + } + if (cc === CC_REVERSE_SOLIDUS) { + // we don't need to fully parse the escaped code point + // just skip over a potential new line + pos++; + if (pos === input.length) return pos; + pos++; + } else { + pos++; + } + } +}; + +/** + * @param {number} cc char code + * @returns {boolean} is identifier start code + */ +const _isIdentifierStartCode = cc => + cc === CC_LOW_LINE || + (cc >= CC_LOWER_A && cc <= CC_LOWER_Z) || + (cc >= CC_UPPER_A && cc <= CC_UPPER_Z) || + cc > 0x80; + +/** + * @param {number} first first code point + * @param {number} second second code point + * @returns {boolean} true if two code points are a valid escape + */ +const _isTwoCodePointsAreValidEscape = (first, second) => { + if (first !== CC_REVERSE_SOLIDUS) return false; + if (_isNewLine(second)) return false; + return true; +}; + +/** + * @param {number} cc char code + * @returns {boolean} is digit + */ +const _isDigit = cc => cc >= CC_0 && cc <= CC_9; + +/** + * @param {string} input input + * @param {number} pos position + * @returns {boolean} true, if input at pos starts an identifier + */ +const _startsIdentifier = (input, pos) => { + const cc = input.charCodeAt(pos); + if (cc === CC_HYPHEN_MINUS) { + if (pos === input.length) return false; + const cc = input.charCodeAt(pos + 1); + if (cc === CC_HYPHEN_MINUS) return true; + if (cc === CC_REVERSE_SOLIDUS) { + const cc = input.charCodeAt(pos + 2); + return !_isNewLine(cc); + } + return _isIdentifierStartCode(cc); + } + if (cc === CC_REVERSE_SOLIDUS) { + const cc = input.charCodeAt(pos + 1); + return !_isNewLine(cc); + } + return _isIdentifierStartCode(cc); +}; + +/** @type {CharHandler} */ +const consumeNumberSign = (input, pos, callbacks) => { + const start = pos; + pos++; + if (pos === input.length) return pos; + if ( + callbacks.isSelector && + callbacks.isSelector(input, pos) && + _startsIdentifier(input, pos) + ) { + pos = _consumeIdentifier(input, pos, callbacks); + if (callbacks.id !== undefined) { + return callbacks.id(input, start, pos); + } + } + return pos; +}; + +/** @type {CharHandler} */ +const consumeMinus = (input, pos, callbacks) => { + const start = pos; + pos++; + if (pos === input.length) return pos; + const cc = input.charCodeAt(pos); + // If the input stream starts with a number, reconsume the current input code point, consume a numeric token, and return it. + if (cc === CC_FULL_STOP || _isDigit(cc)) { + return consumeNumericToken(input, pos, callbacks); + } else if (cc === CC_HYPHEN_MINUS) { + pos++; + if (pos === input.length) return pos; + const cc = input.charCodeAt(pos); + if (cc === CC_GREATER_THAN_SIGN) { + return pos + 1; + } + pos = _consumeIdentifier(input, pos, callbacks); + if (callbacks.identifier !== undefined) { + return callbacks.identifier(input, start, pos); + } + } else if (cc === CC_REVERSE_SOLIDUS) { + if (pos + 1 === input.length) return pos; + const cc = input.charCodeAt(pos + 1); + if (_isNewLine(cc)) return pos; + pos = _consumeIdentifier(input, pos, callbacks); + if (callbacks.identifier !== undefined) { + return callbacks.identifier(input, start, pos); + } + } else if (_isIdentifierStartCode(cc)) { + pos = consumeOtherIdentifier(input, pos - 1, callbacks); + } + return pos; +}; + +/** @type {CharHandler} */ +const consumeDot = (input, pos, callbacks) => { + const start = pos; + pos++; + if (pos === input.length) return pos; + const cc = input.charCodeAt(pos); + if (_isDigit(cc)) return consumeNumericToken(input, pos - 2, callbacks); + if ( + (callbacks.isSelector && !callbacks.isSelector(input, pos)) || + !_startsIdentifier(input, pos) + ) + return pos; + pos = _consumeIdentifier(input, pos, callbacks); + if (callbacks.class !== undefined) return callbacks.class(input, start, pos); + return pos; +}; + +/** @type {CharHandler} */ +const consumeNumericToken = (input, pos, callbacks) => { + pos = _consumeNumber(input, pos, callbacks); + if (pos === input.length) return pos; + if (_startsIdentifier(input, pos)) + return _consumeIdentifier(input, pos, callbacks); + const cc = input.charCodeAt(pos); + if (cc === CC_PERCENTAGE) return pos + 1; + return pos; +}; + +/** @type {CharHandler} */ +const consumeOtherIdentifier = (input, pos, callbacks) => { + const start = pos; + pos = _consumeIdentifier(input, pos, callbacks); + if (pos !== input.length && input.charCodeAt(pos) === CC_LEFT_PARENTHESIS) { + pos++; + if (callbacks.function !== undefined) { + return callbacks.function(input, start, pos); + } + } else if (callbacks.identifier !== undefined) { + return callbacks.identifier(input, start, pos); + } + return pos; +}; + +/** @type {CharHandler} */ +const consumePotentialUrl = (input, pos, callbacks) => { + const start = pos; + pos = _consumeIdentifier(input, pos, callbacks); + const nextPos = pos + 1; + if ( + pos === start + 3 && + input.slice(start, nextPos).toLowerCase() === "url(" + ) { + pos++; + let cc = input.charCodeAt(pos); + while (_isWhiteSpace(cc)) { + pos++; + if (pos === input.length) return pos; + cc = input.charCodeAt(pos); + } + if (cc === CC_QUOTATION_MARK || cc === CC_APOSTROPHE) { + if (callbacks.function !== undefined) { + return callbacks.function(input, start, nextPos); + } + return nextPos; + } + const contentStart = pos; + /** @type {number} */ + let contentEnd; + for (;;) { + if (cc === CC_REVERSE_SOLIDUS) { + pos++; + if (pos === input.length) return pos; + pos++; + } else if (_isWhiteSpace(cc)) { + contentEnd = pos; + do { + pos++; + if (pos === input.length) return pos; + cc = input.charCodeAt(pos); + } while (_isWhiteSpace(cc)); + if (cc !== CC_RIGHT_PARENTHESIS) return pos; + pos++; + if (callbacks.url !== undefined) { + return callbacks.url(input, start, pos, contentStart, contentEnd); + } + return pos; + } else if (cc === CC_RIGHT_PARENTHESIS) { + contentEnd = pos; + pos++; + if (callbacks.url !== undefined) { + return callbacks.url(input, start, pos, contentStart, contentEnd); + } + return pos; + } else if (cc === CC_LEFT_PARENTHESIS) { + return pos; + } else { + pos++; + } + if (pos === input.length) return pos; + cc = input.charCodeAt(pos); + } + } else { + if (callbacks.identifier !== undefined) { + return callbacks.identifier(input, start, pos); + } + return pos; + } +}; + +/** @type {CharHandler} */ +const consumePotentialPseudo = (input, pos, callbacks) => { + const start = pos; + pos++; + if ( + (callbacks.isSelector && !callbacks.isSelector(input, pos)) || + !_startsIdentifier(input, pos) + ) + return pos; + pos = _consumeIdentifier(input, pos, callbacks); + const cc = input.charCodeAt(pos); + if (cc === CC_LEFT_PARENTHESIS) { + pos++; + if (callbacks.pseudoFunction !== undefined) { + return callbacks.pseudoFunction(input, start, pos); + } + return pos; + } + if (callbacks.pseudoClass !== undefined) { + return callbacks.pseudoClass(input, start, pos); + } + return pos; +}; + +/** @type {CharHandler} */ +const consumeLeftParenthesis = (input, pos, callbacks) => { + pos++; + if (callbacks.leftParenthesis !== undefined) { + return callbacks.leftParenthesis(input, pos - 1, pos); + } + return pos; +}; + +/** @type {CharHandler} */ +const consumeRightParenthesis = (input, pos, callbacks) => { + pos++; + if (callbacks.rightParenthesis !== undefined) { + return callbacks.rightParenthesis(input, pos - 1, pos); + } + return pos; +}; + +/** @type {CharHandler} */ +const consumeLeftCurlyBracket = (input, pos, callbacks) => { + pos++; + if (callbacks.leftCurlyBracket !== undefined) { + return callbacks.leftCurlyBracket(input, pos - 1, pos); + } + return pos; +}; + +/** @type {CharHandler} */ +const consumeRightCurlyBracket = (input, pos, callbacks) => { + pos++; + if (callbacks.rightCurlyBracket !== undefined) { + return callbacks.rightCurlyBracket(input, pos - 1, pos); + } + return pos; +}; + +/** @type {CharHandler} */ +const consumeSemicolon = (input, pos, callbacks) => { + pos++; + if (callbacks.semicolon !== undefined) { + return callbacks.semicolon(input, pos - 1, pos); + } + return pos; +}; + +/** @type {CharHandler} */ +const consumeComma = (input, pos, callbacks) => { + pos++; + if (callbacks.comma !== undefined) { + return callbacks.comma(input, pos - 1, pos); + } + return pos; +}; + +/** @type {CharHandler} */ +const _consumeIdentifier = (input, pos) => { + for (;;) { + const cc = input.charCodeAt(pos); + if (cc === CC_REVERSE_SOLIDUS) { + pos++; + if (pos === input.length) return pos; + pos++; + } else if ( + _isIdentifierStartCode(cc) || + _isDigit(cc) || + cc === CC_HYPHEN_MINUS + ) { + pos++; + } else { + return pos; + } + } +}; + +/** @type {CharHandler} */ +const _consumeNumber = (input, pos) => { + pos++; + if (pos === input.length) return pos; + let cc = input.charCodeAt(pos); + while (_isDigit(cc)) { + pos++; + if (pos === input.length) return pos; + cc = input.charCodeAt(pos); + } + if (cc === CC_FULL_STOP && pos + 1 !== input.length) { + const next = input.charCodeAt(pos + 1); + if (_isDigit(next)) { + pos += 2; + cc = input.charCodeAt(pos); + while (_isDigit(cc)) { + pos++; + if (pos === input.length) return pos; + cc = input.charCodeAt(pos); + } + } + } + if (cc === CC_LOWER_E || cc === CC_UPPER_E) { + if (pos + 1 !== input.length) { + const next = input.charCodeAt(pos + 2); + if (_isDigit(next)) { + pos += 2; + } else if ( + (next === CC_HYPHEN_MINUS || next === CC_PLUS_SIGN) && + pos + 2 !== input.length + ) { + const next = input.charCodeAt(pos + 2); + if (_isDigit(next)) { + pos += 3; + } else { + return pos; + } + } else { + return pos; + } + } + } else { + return pos; + } + cc = input.charCodeAt(pos); + while (_isDigit(cc)) { + pos++; + if (pos === input.length) return pos; + cc = input.charCodeAt(pos); + } + return pos; +}; + +/** @type {CharHandler} */ +const consumeLessThan = (input, pos, _callbacks) => { + if (input.slice(pos + 1, pos + 4) === "!--") return pos + 4; + return pos + 1; +}; + +/** @type {CharHandler} */ +const consumeAt = (input, pos, callbacks) => { + const start = pos; + pos++; + if (pos === input.length) return pos; + if (_startsIdentifier(input, pos)) { + pos = _consumeIdentifier(input, pos, callbacks); + if (callbacks.atKeyword !== undefined) { + pos = callbacks.atKeyword(input, start, pos); + } + } + return pos; +}; + +/** @type {CharHandler} */ +const consumeReverseSolidus = (input, pos, callbacks) => { + const start = pos; + pos++; + if (pos === input.length) return pos; + // If the input stream starts with a valid escape, reconsume the current input code point, consume an ident-like token, and return it. + if ( + _isTwoCodePointsAreValidEscape( + input.charCodeAt(start), + input.charCodeAt(pos) + ) + ) { + return consumeOtherIdentifier(input, pos - 1, callbacks); + } + // Otherwise, this is a parse error. Return a with its value set to the current input code point. + return pos; +}; + +const CHAR_MAP = Array.from({ length: 0x80 }, (_, cc) => { + // https://drafts.csswg.org/css-syntax/#consume-token + switch (cc) { + // whitespace + case CC_LINE_FEED: + case CC_CARRIAGE_RETURN: + case CC_FORM_FEED: + case CC_TAB: + case CC_SPACE: + return consumeSpace; + // U+0022 QUOTATION MARK (") + case CC_QUOTATION_MARK: + return consumeString(cc); + // U+0023 NUMBER SIGN (#) + case CC_NUMBER_SIGN: + return consumeNumberSign; + // U+0027 APOSTROPHE (') + case CC_APOSTROPHE: + return consumeString(cc); + // U+0028 LEFT PARENTHESIS (() + case CC_LEFT_PARENTHESIS: + return consumeLeftParenthesis; + // U+0029 RIGHT PARENTHESIS ()) + case CC_RIGHT_PARENTHESIS: + return consumeRightParenthesis; + // U+002B PLUS SIGN (+) + case CC_PLUS_SIGN: + return consumeNumericToken; + // U+002C COMMA (,) + case CC_COMMA: + return consumeComma; + // U+002D HYPHEN-MINUS (-) + case CC_HYPHEN_MINUS: + return consumeMinus; + // U+002E FULL STOP (.) + case CC_FULL_STOP: + return consumeDot; + // U+003A COLON (:) + case CC_COLON: + return consumePotentialPseudo; + // U+003B SEMICOLON (;) + case CC_SEMICOLON: + return consumeSemicolon; + // U+003C LESS-THAN SIGN (<) + case CC_LESS_THAN_SIGN: + return consumeLessThan; + // U+0040 COMMERCIAL AT (@) + case CC_AT_SIGN: + return consumeAt; + // U+005B LEFT SQUARE BRACKET ([) + case CC_LEFT_SQUARE: + return consumeDelimToken; + // U+005C REVERSE SOLIDUS (\) + case CC_REVERSE_SOLIDUS: + return consumeReverseSolidus; + // U+005D RIGHT SQUARE BRACKET (]) + case CC_RIGHT_SQUARE: + return consumeDelimToken; + // U+007B LEFT CURLY BRACKET ({) + case CC_LEFT_CURLY: + return consumeLeftCurlyBracket; + // U+007D RIGHT CURLY BRACKET (}) + case CC_RIGHT_CURLY: + return consumeRightCurlyBracket; + // Optimization + case CC_LOWER_U: + case CC_UPPER_U: + return consumePotentialUrl; + default: + // digit + if (_isDigit(cc)) return consumeNumericToken; + // ident-start code point + if (isIdentStartCodePoint(cc)) { + return consumeOtherIdentifier; + } + // EOF, but we don't have it + // anything else + return consumeDelimToken; + } +}); + +/** + * @param {string} input input css + * @param {CssTokenCallbacks} callbacks callbacks + * @returns {void} + */ +module.exports = (input, callbacks) => { + // This section describes how to consume a token from a stream of code points. It will return a single token of any type. + let pos = 0; + while (pos < input.length) { + // Consume comments. + pos = consumeComments(input, pos, callbacks); + + const cc = input.charCodeAt(pos); + + // Consume the next input code point. + if (cc < 0x80) { + pos = CHAR_MAP[cc](input, pos, callbacks); + } else { + pos++; + } + } +}; + +module.exports.isIdentStartCodePoint = isIdentStartCodePoint; + +/** + * @param {string} input input + * @param {number} pos position + * @returns {number} position after comments + */ +module.exports.eatComments = (input, pos) => { + for (;;) { + const originalPos = pos; + pos = consumeComments(input, pos, {}); + if (originalPos === pos) { + break; + } + } + + return pos; +}; + +/** + * @param {string} input input + * @param {number} pos position + * @returns {number} position after whitespace + */ +module.exports.eatWhitespace = (input, pos) => { + while (_isWhiteSpace(input.charCodeAt(pos))) { + pos++; + } + + return pos; +}; + +/** + * @param {string} input input + * @param {number} pos position + * @returns {number} position after whitespace and comments + */ +module.exports.eatWhitespaceAndComments = (input, pos) => { + for (;;) { + const originalPos = pos; + pos = consumeComments(input, pos, {}); + while (_isWhiteSpace(input.charCodeAt(pos))) { + pos++; + } + if (originalPos === pos) { + break; + } + } + + return pos; +}; + +/** + * @param {string} input input + * @param {number} pos position + * @returns {number} position after whitespace + */ +module.exports.eatWhiteLine = (input, pos) => { + for (;;) { + const cc = input.charCodeAt(pos); + if (_isSpace(cc)) { + pos++; + continue; + } + if (_isNewLine(cc)) pos++; + // For `\r\n` + if (cc === CC_CARRIAGE_RETURN && input.charCodeAt(pos + 1) === CC_LINE_FEED) + pos++; + break; + } + + return pos; +}; diff --git a/lib/debug/ProfilingPlugin.js b/lib/debug/ProfilingPlugin.js index ec7f53cf299..83e363fc17c 100644 --- a/lib/debug/ProfilingPlugin.js +++ b/lib/debug/ProfilingPlugin.js @@ -5,23 +5,50 @@ "use strict"; const { Tracer } = require("chrome-trace-event"); -const { validate } = require("schema-utils"); -const schema = require("../../schemas/plugins/debug/ProfilingPlugin.json"); +const { + JAVASCRIPT_MODULE_TYPE_AUTO, + JAVASCRIPT_MODULE_TYPE_DYNAMIC, + JAVASCRIPT_MODULE_TYPE_ESM, + WEBASSEMBLY_MODULE_TYPE_ASYNC, + WEBASSEMBLY_MODULE_TYPE_SYNC, + JSON_MODULE_TYPE +} = require("../ModuleTypeConstants"); +const createSchemaValidation = require("../util/create-schema-validation"); const { dirname, mkdirpSync } = require("../util/fs"); /** @typedef {import("../../declarations/plugins/debug/ProfilingPlugin").ProfilingPluginOptions} ProfilingPluginOptions */ +/** @typedef {import("../Compilation")} Compilation */ +/** @typedef {import("../Compiler")} Compiler */ +/** @typedef {import("../ContextModuleFactory")} ContextModuleFactory */ +/** @typedef {import("../ModuleFactory")} ModuleFactory */ +/** @typedef {import("../NormalModuleFactory")} NormalModuleFactory */ /** @typedef {import("../util/fs").IntermediateFileSystem} IntermediateFileSystem */ -let inspector = undefined; +/** @typedef {TODO} Inspector */ + +const validate = createSchemaValidation( + require("../../schemas/plugins/debug/ProfilingPlugin.check.js"), + () => require("../../schemas/plugins/debug/ProfilingPlugin.json"), + { + name: "Profiling Plugin", + baseDataPath: "options" + } +); + +/** @type {Inspector | undefined} */ +let inspector; try { - // eslint-disable-next-line node/no-unsupported-features/node-builtins + // eslint-disable-next-line n/no-unsupported-features/node-builtins inspector = require("inspector"); -} catch (e) { +} catch (_err) { console.log("Unable to CPU profile in < node 8.0"); } class Profiler { + /** + * @param {Inspector} inspector inspector + */ constructor(inspector) { this.session = undefined; this.inspector = inspector; @@ -57,10 +84,15 @@ class Profiler { ]); } + /** + * @param {string} method method name + * @param {object} [params] params + * @returns {Promise} Promise for the result + */ sendCommand(method, params) { if (this.hasSession()) { return new Promise((res, rej) => { - return this.session.post(method, params, (err, params) => { + this.session.post(method, params, (err, params) => { if (err !== null) { rej(err); } else { @@ -68,9 +100,8 @@ class Profiler { } }); }); - } else { - return Promise.resolve(); } + return Promise.resolve(); } destroy() { @@ -85,6 +116,8 @@ class Profiler { return this.sendCommand("Profiler.stop").then(({ profile }) => { const hrtime = process.hrtime(); const endTime = hrtime[0] * 1000000 + Math.round(hrtime[1] / 1000); + // Avoid coverage problems due indirect changes + /* istanbul ignore next */ if (profile.startTime < this._startTime || profile.endTime > endTime) { // In some cases timestamps mismatch and we need to adjust them // Both process.hrtime and the inspector timestamps claim to be relative @@ -103,7 +136,7 @@ class Profiler { /** * an object that wraps Tracer and Profiler with a counter - * @typedef {Object} Trace + * @typedef {object} Trace * @property {Tracer} trace instance of Tracer * @property {number} counter Counter * @property {Profiler} profiler instance of Profiler @@ -116,10 +149,8 @@ class Profiler { * @returns {Trace} The trace object */ const createTrace = (fs, outputPath) => { - const trace = new Tracer({ - noStream: true - }); - const profiler = new Profiler(inspector); + const trace = new Tracer(); + const profiler = new Profiler(/** @type {Inspector} */ (inspector)); if (/\/|\\/.test(outputPath)) { const dirPath = dirname(fs, outputPath); mkdirpSync(fs, dirPath); @@ -166,6 +197,7 @@ const createTrace = (fs, outputPath) => { counter, profiler, end: callback => { + trace.push("]"); // Wait until the write stream finishes. fsStream.on("close", () => { callback(); @@ -176,42 +208,48 @@ const createTrace = (fs, outputPath) => { }; }; -const pluginName = "ProfilingPlugin"; +const PLUGIN_NAME = "ProfilingPlugin"; class ProfilingPlugin { /** * @param {ProfilingPluginOptions=} options options object */ constructor(options = {}) { - validate(schema, options, { - name: "Profiling Plugin", - baseDataPath: "options" - }); + validate(options); this.outputPath = options.outputPath || "events.json"; } + /** + * Apply the plugin + * @param {Compiler} compiler the compiler instance + * @returns {void} + */ apply(compiler) { const tracer = createTrace( - compiler.intermediateFileSystem, + /** @type {IntermediateFileSystem} */ + (compiler.intermediateFileSystem), this.outputPath ); tracer.profiler.startProfiling(); // Compiler Hooks - Object.keys(compiler.hooks).forEach(hookName => { - compiler.hooks[hookName].intercept( - makeInterceptorFor("Compiler", tracer)(hookName) - ); - }); + for (const hookName of Object.keys(compiler.hooks)) { + const hook = + compiler.hooks[/** @type {keyof Compiler["hooks"]} */ (hookName)]; + if (hook) { + hook.intercept(makeInterceptorFor("Compiler", tracer)(hookName)); + } + } - Object.keys(compiler.resolverFactory.hooks).forEach(hookName => { - compiler.resolverFactory.hooks[hookName].intercept( - makeInterceptorFor("Resolver", tracer)(hookName) - ); - }); + for (const hookName of Object.keys(compiler.resolverFactory.hooks)) { + const hook = compiler.resolverFactory.hooks[hookName]; + if (hook) { + hook.intercept(makeInterceptorFor("Resolver", tracer)(hookName)); + } + } compiler.hooks.compilation.tap( - pluginName, + PLUGIN_NAME, (compilation, { normalModuleFactory, contextModuleFactory }) => { interceptAllHooksFor(compilation, tracer, "Compilation"); interceptAllHooksFor( @@ -232,14 +270,14 @@ class ProfilingPlugin { // We need to write out the CPU profile when we are all done. compiler.hooks.done.tapAsync( { - name: pluginName, + name: PLUGIN_NAME, stage: Infinity }, (stats, callback) => { + if (compiler.watchMode) return callback(); tracer.profiler.stopProfiling().then(parsedResults => { if (parsedResults === undefined) { tracer.profiler.destroy(); - tracer.trace.flush(); tracer.end(callback); return; } @@ -253,7 +291,9 @@ class ProfilingPlugin { cat: ["toplevel"], ts: cpuStartTime, args: { + // eslint-disable-next-line camelcase src_file: "../../ipc/ipc_moji_bootstrap.cc", + // eslint-disable-next-line camelcase src_func: "Accept" } }); @@ -287,7 +327,6 @@ class ProfilingPlugin { }); tracer.profiler.destroy(); - tracer.trace.flush(); tracer.end(callback); }); } @@ -295,42 +334,56 @@ class ProfilingPlugin { } } +/** + * @param {any} instance instance + * @param {Trace} tracer tracer + * @param {string} logLabel log label + */ const interceptAllHooksFor = (instance, tracer, logLabel) => { if (Reflect.has(instance, "hooks")) { - Object.keys(instance.hooks).forEach(hookName => { + for (const hookName of Object.keys(instance.hooks)) { const hook = instance.hooks[hookName]; - if (!hook._fakeHook) { + if (hook && !hook._fakeHook) { hook.intercept(makeInterceptorFor(logLabel, tracer)(hookName)); } - }); + } } }; +/** + * @param {NormalModuleFactory} moduleFactory normal module factory + * @param {Trace} tracer tracer + */ const interceptAllParserHooks = (moduleFactory, tracer) => { const moduleTypes = [ - "javascript/auto", - "javascript/dynamic", - "javascript/esm", - "json", - "webassembly/async", - "webassembly/sync" + JAVASCRIPT_MODULE_TYPE_AUTO, + JAVASCRIPT_MODULE_TYPE_DYNAMIC, + JAVASCRIPT_MODULE_TYPE_ESM, + JSON_MODULE_TYPE, + WEBASSEMBLY_MODULE_TYPE_ASYNC, + WEBASSEMBLY_MODULE_TYPE_SYNC ]; - moduleTypes.forEach(moduleType => { + for (const moduleType of moduleTypes) { moduleFactory.hooks.parser .for(moduleType) - .tap("ProfilingPlugin", (parser, parserOpts) => { + .tap(PLUGIN_NAME, (parser, parserOpts) => { interceptAllHooksFor(parser, tracer, "Parser"); }); - }); + } }; +/** + * @param {Compilation} compilation compilation + * @param {Trace} tracer tracer + */ const interceptAllJavascriptModulesPluginHooks = (compilation, tracer) => { interceptAllHooksFor( { - hooks: require("../javascript/JavascriptModulesPlugin").getCompilationHooks( - compilation - ) + hooks: + require("../javascript/JavascriptModulesPlugin").getCompilationHooks( + compilation + ) }, tracer, "JavascriptModulesPlugin" @@ -338,18 +391,18 @@ const interceptAllJavascriptModulesPluginHooks = (compilation, tracer) => { }; const makeInterceptorFor = (instance, tracer) => hookName => ({ - register: ({ name, type, context, fn }) => { - const newFn = makeNewProfiledTapFn(hookName, tracer, { - name, - type, - fn - }); - return { - name, - type, - context, - fn: newFn - }; + register: tapInfo => { + const { name, type, fn } = tapInfo; + const newFn = + // Don't tap our own hooks to ensure stream can close cleanly + name === PLUGIN_NAME + ? fn + : makeNewProfiledTapFn(hookName, tracer, { + name, + type, + fn + }); + return { ...tapInfo, fn: newFn }; } }); @@ -410,7 +463,7 @@ const makeNewProfiledTapFn = (hookName, tracer, { name, type, fn }) => { const id = ++tracer.counter; // Do not instrument ourself due to the CPU // profile needing to be the last event in the trace. - if (name === pluginName) { + if (name === PLUGIN_NAME) { return fn(...args); } @@ -422,13 +475,13 @@ const makeNewProfiledTapFn = (hookName, tracer, { name, type, fn }) => { let r; try { r = fn(...args); - } catch (error) { + } catch (err) { tracer.trace.end({ name, id, cat: defaultCategory }); - throw error; + throw err; } tracer.trace.end({ name, diff --git a/lib/dependencies/AMDDefineDependency.js b/lib/dependencies/AMDDefineDependency.js index 1a0816ae84f..4acb1525271 100644 --- a/lib/dependencies/AMDDefineDependency.js +++ b/lib/dependencies/AMDDefineDependency.js @@ -12,12 +12,15 @@ const NullDependency = require("./NullDependency"); /** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */ /** @typedef {import("../Dependency")} Dependency */ /** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */ +/** @typedef {import("../javascript/JavascriptParser").Range} Range */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */ /** @type {Record} */ const DEFINITIONS = { f: { definition: "var __WEBPACK_AMD_DEFINE_RESULT__;", - content: `!(__WEBPACK_AMD_DEFINE_RESULT__ = (#).call(exports, __webpack_require__, exports, module), + content: `!(__WEBPACK_AMD_DEFINE_RESULT__ = (#).call(exports, ${RuntimeGlobals.require}, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__))`, requests: [ RuntimeGlobals.require, @@ -35,7 +38,7 @@ const DEFINITIONS = { "var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_RESULT__;", content: `!(__WEBPACK_AMD_DEFINE_FACTORY__ = (#), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? - (__WEBPACK_AMD_DEFINE_FACTORY__.call(exports, __webpack_require__, exports, module)) : + (__WEBPACK_AMD_DEFINE_FACTORY__.call(exports, ${RuntimeGlobals.require}, exports, module)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__))`, requests: [ @@ -67,8 +70,7 @@ const DEFINITIONS = { }, lf: { definition: "var XXX, XXXmodule;", - content: - "!(XXXmodule = { id: YYY, exports: {}, loaded: false }, XXX = (#).call(XXXmodule.exports, __webpack_require__, XXXmodule.exports, XXXmodule), XXXmodule.loaded = true, XXX === undefined && (XXX = XXXmodule.exports))", + content: `!(XXXmodule = { id: YYY, exports: {}, loaded: false }, XXX = (#).call(XXXmodule.exports, ${RuntimeGlobals.require}, XXXmodule.exports, XXXmodule), XXXmodule.loaded = true, XXX === undefined && (XXX = XXXmodule.exports))`, requests: [RuntimeGlobals.require, RuntimeGlobals.module] }, lo: { @@ -78,8 +80,7 @@ const DEFINITIONS = { }, lof: { definition: "var XXX, XXXfactory, XXXmodule;", - content: - "!(XXXfactory = (#), (typeof XXXfactory === 'function' ? ((XXXmodule = { id: YYY, exports: {}, loaded: false }), (XXX = XXXfactory.call(XXXmodule.exports, __webpack_require__, XXXmodule.exports, XXXmodule)), (XXXmodule.loaded = true), XXX === undefined && (XXX = XXXmodule.exports)) : XXX = XXXfactory))", + content: `!(XXXfactory = (#), (typeof XXXfactory === 'function' ? ((XXXmodule = { id: YYY, exports: {}, loaded: false }), (XXX = XXXfactory.call(XXXmodule.exports, ${RuntimeGlobals.require}, XXXmodule.exports, XXXmodule)), (XXXmodule.loaded = true), XXX === undefined && (XXX = XXXmodule.exports)) : XXX = XXXfactory))`, requests: [RuntimeGlobals.require, RuntimeGlobals.module] }, laf: { @@ -105,6 +106,13 @@ const DEFINITIONS = { }; class AMDDefineDependency extends NullDependency { + /** + * @param {Range} range range + * @param {Range | null} arrayRange array range + * @param {Range | null} functionRange function range + * @param {Range | null} objectRange object range + * @param {string | null} namedModule true, when define is called with a name + */ constructor(range, arrayRange, functionRange, objectRange, namedModule) { super(); this.range = range; @@ -119,6 +127,9 @@ class AMDDefineDependency extends NullDependency { return "amd define"; } + /** + * @param {ObjectSerializerContext} context context + */ serialize(context) { const { write } = context; write(this.range); @@ -130,6 +141,9 @@ class AMDDefineDependency extends NullDependency { super.serialize(context); } + /** + * @param {ObjectDeserializerContext} context context + */ deserialize(context) { const { read } = context; this.range = read(); @@ -166,6 +180,10 @@ AMDDefineDependency.Template = class AMDDefineDependencyTemplate extends ( this.replace(dep, source, definition, content); } + /** + * @param {AMDDefineDependency} dependency dependency + * @returns {string} variable name + */ localModuleVar(dependency) { return ( dependency.localModule && @@ -174,6 +192,10 @@ AMDDefineDependency.Template = class AMDDefineDependencyTemplate extends ( ); } + /** + * @param {AMDDefineDependency} dependency dependency + * @returns {string} branch + */ branch(dependency) { const localModuleVar = this.localModuleVar(dependency) ? "l" : ""; const arrayRange = dependency.arrayRange ? "a" : ""; @@ -182,6 +204,12 @@ AMDDefineDependency.Template = class AMDDefineDependencyTemplate extends ( return localModuleVar + arrayRange + objectRange + functionRange; } + /** + * @param {AMDDefineDependency} dependency dependency + * @param {ReplaceSource} source source + * @param {string} definition definition + * @param {string} text text + */ replace(dependency, source, definition, text) { const localModuleVar = this.localModuleVar(dependency); if (localModuleVar) { @@ -202,18 +230,34 @@ AMDDefineDependency.Template = class AMDDefineDependencyTemplate extends ( let current = dependency.range[0]; if (dependency.arrayRange) { - source.replace(current, dependency.arrayRange[0] - 1, texts.shift()); + source.replace( + current, + dependency.arrayRange[0] - 1, + /** @type {string} */ (texts.shift()) + ); current = dependency.arrayRange[1]; } if (dependency.objectRange) { - source.replace(current, dependency.objectRange[0] - 1, texts.shift()); + source.replace( + current, + dependency.objectRange[0] - 1, + /** @type {string} */ (texts.shift()) + ); current = dependency.objectRange[1]; } else if (dependency.functionRange) { - source.replace(current, dependency.functionRange[0] - 1, texts.shift()); + source.replace( + current, + dependency.functionRange[0] - 1, + /** @type {string} */ (texts.shift()) + ); current = dependency.functionRange[1]; } - source.replace(current, dependency.range[1] - 1, texts.shift()); + source.replace( + current, + dependency.range[1] - 1, + /** @type {string} */ (texts.shift()) + ); if (texts.length > 0) throw new Error("Implementation error"); } }; diff --git a/lib/dependencies/AMDDefineDependencyParserPlugin.js b/lib/dependencies/AMDDefineDependencyParserPlugin.js index 7d1c7e9e041..14fbe4af218 100644 --- a/lib/dependencies/AMDDefineDependencyParserPlugin.js +++ b/lib/dependencies/AMDDefineDependencyParserPlugin.js @@ -16,6 +16,26 @@ const DynamicExports = require("./DynamicExports"); const LocalModuleDependency = require("./LocalModuleDependency"); const { addLocalModule, getLocalModule } = require("./LocalModulesHelpers"); +/** @typedef {import("estree").ArrowFunctionExpression} ArrowFunctionExpression */ +/** @typedef {import("estree").CallExpression} CallExpression */ +/** @typedef {import("estree").Expression} Expression */ +/** @typedef {import("estree").FunctionExpression} FunctionExpression */ +/** @typedef {import("estree").Identifier} Identifier */ +/** @typedef {import("estree").Literal} Literal */ +/** @typedef {import("estree").MemberExpression} MemberExpression */ +/** @typedef {import("estree").ObjectExpression} ObjectExpression */ +/** @typedef {import("estree").SimpleCallExpression} SimpleCallExpression */ +/** @typedef {import("estree").SpreadElement} SpreadElement */ +/** @typedef {import("../../declarations/WebpackOptions").JavascriptParserOptions} JavascriptParserOptions */ +/** @typedef {import("../Dependency").DependencyLocation} DependencyLocation */ +/** @typedef {import("../javascript/BasicEvaluatedExpression")} BasicEvaluatedExpression */ +/** @typedef {import("../javascript/JavascriptParser")} JavascriptParser */ +/** @typedef {import("../javascript/JavascriptParser").Range} Range */ + +/** + * @param {Expression | SpreadElement} expr expression + * @returns {expr is CallExpression} true if it's a bound function expression + */ const isBoundFunctionExpression = expr => { if (expr.type !== "CallExpression") return false; if (expr.callee.type !== "MemberExpression") return false; @@ -26,12 +46,22 @@ const isBoundFunctionExpression = expr => { return true; }; +/** @typedef {FunctionExpression | ArrowFunctionExpression} UnboundFunctionExpression */ + +/** + * @param {Expression | SpreadElement} expr expression + * @returns {expr is FunctionExpression | ArrowFunctionExpression} true when unbound function expression + */ const isUnboundFunctionExpression = expr => { if (expr.type === "FunctionExpression") return true; if (expr.type === "ArrowFunctionExpression") return true; return false; }; +/** + * @param {Expression | SpreadElement} expr expression + * @returns {expr is FunctionExpression | ArrowFunctionExpression | CallExpression} true when callable + */ const isCallable = expr => { if (isUnboundFunctionExpression(expr)) return true; if (isBoundFunctionExpression(expr)) return true; @@ -39,10 +69,17 @@ const isCallable = expr => { }; class AMDDefineDependencyParserPlugin { + /** + * @param {JavascriptParserOptions} options parserOptions + */ constructor(options) { this.options = options; } + /** + * @param {JavascriptParser} parser the parser + * @returns {void} + */ apply(parser) { parser.hooks.call .for("define") @@ -52,94 +89,144 @@ class AMDDefineDependencyParserPlugin { ); } + /** + * @param {JavascriptParser} parser the parser + * @param {CallExpression} expr call expression + * @param {BasicEvaluatedExpression} param param + * @param {Record} identifiers identifiers + * @param {string=} namedModule named module + * @returns {boolean | undefined} result + */ processArray(parser, expr, param, identifiers, namedModule) { if (param.isArray()) { - param.items.forEach((param, idx) => { + const items = /** @type {BasicEvaluatedExpression[]} */ (param.items); + for (const [idx, item] of items.entries()) { if ( - param.isString() && - ["require", "module", "exports"].includes(param.string) + item.isString() && + ["require", "module", "exports"].includes( + /** @type {string} */ (item.string) + ) ) - identifiers[idx] = param.string; - const result = this.processItem(parser, expr, param, namedModule); + identifiers[/** @type {number} */ (idx)] = /** @type {string} */ ( + item.string + ); + const result = this.processItem(parser, expr, item, namedModule); if (result === undefined) { - this.processContext(parser, expr, param); + this.processContext(parser, expr, item); } - }); + } return true; } else if (param.isConstArray()) { + /** @type {(string | LocalModuleDependency | AMDRequireItemDependency)[]} */ const deps = []; - param.array.forEach((request, idx) => { + const array = /** @type {string[]} */ (param.array); + for (const [idx, request] of array.entries()) { let dep; let localModule; if (request === "require") { identifiers[idx] = request; - dep = "__webpack_require__"; + dep = RuntimeGlobals.require; } else if (["exports", "module"].includes(request)) { identifiers[idx] = request; dep = request; } else if ((localModule = getLocalModule(parser.state, request))) { localModule.flagUsed(); dep = new LocalModuleDependency(localModule, undefined, false); - dep.loc = expr.loc; + dep.loc = /** @type {DependencyLocation} */ (expr.loc); parser.state.module.addPresentationalDependency(dep); } else { dep = this.newRequireItemDependency(request); - dep.loc = expr.loc; - dep.optional = !!parser.scope.inTry; + dep.loc = /** @type {DependencyLocation} */ (expr.loc); + dep.optional = Boolean(parser.scope.inTry); parser.state.current.addDependency(dep); } deps.push(dep); - }); - const dep = this.newRequireArrayDependency(deps, param.range); - dep.loc = expr.loc; - dep.optional = !!parser.scope.inTry; + } + const dep = this.newRequireArrayDependency( + deps, + /** @type {Range} */ (param.range) + ); + dep.loc = /** @type {DependencyLocation} */ (expr.loc); + dep.optional = Boolean(parser.scope.inTry); parser.state.module.addPresentationalDependency(dep); return true; } } + + /** + * @param {JavascriptParser} parser the parser + * @param {CallExpression} expr call expression + * @param {BasicEvaluatedExpression} param param + * @param {string=} namedModule named module + * @returns {boolean | undefined} result + */ processItem(parser, expr, param, namedModule) { if (param.isConditional()) { - param.options.forEach(param => { - const result = this.processItem(parser, expr, param); + const options = /** @type {BasicEvaluatedExpression[]} */ (param.options); + for (const item of options) { + const result = this.processItem(parser, expr, item); if (result === undefined) { - this.processContext(parser, expr, param); + this.processContext(parser, expr, item); } - }); + } + return true; } else if (param.isString()) { - let dep, localModule; + let dep; + let localModule; + if (param.string === "require") { - dep = new ConstDependency("__webpack_require__", param.range, [ - RuntimeGlobals.require - ]); + dep = new ConstDependency( + RuntimeGlobals.require, + /** @type {Range} */ (param.range), + [RuntimeGlobals.require] + ); } else if (param.string === "exports") { - dep = new ConstDependency("exports", param.range, [ - RuntimeGlobals.exports - ]); + dep = new ConstDependency( + "exports", + /** @type {Range} */ (param.range), + [RuntimeGlobals.exports] + ); } else if (param.string === "module") { - dep = new ConstDependency("module", param.range, [ - RuntimeGlobals.module - ]); + dep = new ConstDependency( + "module", + /** @type {Range} */ (param.range), + [RuntimeGlobals.module] + ); } else if ( - (localModule = getLocalModule(parser.state, param.string, namedModule)) + (localModule = getLocalModule( + parser.state, + /** @type {string} */ (param.string), + namedModule + )) ) { localModule.flagUsed(); dep = new LocalModuleDependency(localModule, param.range, false); } else { - dep = this.newRequireItemDependency(param.string, param.range); - dep.optional = !!parser.scope.inTry; + dep = this.newRequireItemDependency( + /** @type {string} */ (param.string), + param.range + ); + dep.optional = Boolean(parser.scope.inTry); parser.state.current.addDependency(dep); return true; } - dep.loc = expr.loc; + dep.loc = /** @type {DependencyLocation} */ (expr.loc); parser.state.module.addPresentationalDependency(dep); return true; } } + + /** + * @param {JavascriptParser} parser the parser + * @param {CallExpression} expr call expression + * @param {BasicEvaluatedExpression} param param + * @returns {boolean | undefined} result + */ processContext(parser, expr, param) { const dep = ContextDependencyHelpers.create( AMDRequireContextDependency, - param.range, + /** @type {Range} */ (param.range), param, expr, this.options, @@ -149,14 +236,26 @@ class AMDDefineDependencyParserPlugin { parser ); if (!dep) return; - dep.loc = expr.loc; - dep.optional = !!parser.scope.inTry; + dep.loc = /** @type {DependencyLocation} */ (expr.loc); + dep.optional = Boolean(parser.scope.inTry); parser.state.current.addDependency(dep); return true; } + /** + * @param {JavascriptParser} parser the parser + * @param {CallExpression} expr call expression + * @returns {boolean | undefined} result + */ processCallDefine(parser, expr) { - let array, fn, obj, namedModule; + /** @type {TODO} */ + let array; + /** @type {FunctionExpression | ArrowFunctionExpression | CallExpression | Identifier | undefined} */ + let fn; + /** @type {ObjectExpression | Identifier | undefined} */ + let obj; + /** @type {string | undefined} */ + let namedModule; switch (expr.arguments.length) { case 1: if (isCallable(expr.arguments[0])) { @@ -168,12 +267,12 @@ class AMDDefineDependencyParserPlugin { } else { // define(expr) // unclear if function or object - obj = fn = expr.arguments[0]; + obj = fn = /** @type {Identifier} */ (expr.arguments[0]); } break; case 2: if (expr.arguments[0].type === "Literal") { - namedModule = expr.arguments[0].value; + namedModule = /** @type {string} */ (expr.arguments[0].value); // define("โ€ฆ", โ€ฆ) if (isCallable(expr.arguments[1])) { // define("โ€ฆ", f() {โ€ฆ}) @@ -184,7 +283,7 @@ class AMDDefineDependencyParserPlugin { } else { // define("โ€ฆ", expr) // unclear if function or object - obj = fn = expr.arguments[1]; + obj = fn = /** @type {Identifier} */ (expr.arguments[1]); } } else { array = expr.arguments[0]; @@ -197,13 +296,18 @@ class AMDDefineDependencyParserPlugin { } else { // define([โ€ฆ], expr) // unclear if function or object - obj = fn = expr.arguments[1]; + obj = fn = /** @type {Identifier} */ (expr.arguments[1]); } } break; case 3: // define("โ€ฆ", [โ€ฆ], f() {โ€ฆ}) - namedModule = expr.arguments[0].value; + namedModule = + /** @type {string} */ + ( + /** @type {Literal} */ + (expr.arguments[0]).value + ); array = expr.arguments[1]; if (isCallable(expr.arguments[2])) { // define("โ€ฆ", [โ€ฆ], f() {}) @@ -214,28 +318,38 @@ class AMDDefineDependencyParserPlugin { } else { // define("โ€ฆ", [โ€ฆ], expr) // unclear if function or object - obj = fn = expr.arguments[2]; + obj = fn = /** @type {Identifier} */ (expr.arguments[2]); } break; default: return; } DynamicExports.bailout(parser.state); + /** @type {Identifier[] | null} */ let fnParams = null; let fnParamsOffset = 0; if (fn) { if (isUnboundFunctionExpression(fn)) { - fnParams = fn.params; + fnParams = + /** @type {Identifier[]} */ + (fn.params); } else if (isBoundFunctionExpression(fn)) { - fnParams = fn.callee.object.params; + const object = + /** @type {FunctionExpression} */ + (/** @type {MemberExpression} */ (fn.callee).object); + + fnParams = + /** @type {Identifier[]} */ + (object.params); fnParamsOffset = fn.arguments.length - 1; if (fnParamsOffset < 0) { fnParamsOffset = 0; } } } - let fnRenames = new Map(); + const fnRenames = new Map(); if (array) { + /** @type {Record} */ const identifiers = {}; const param = parser.evaluateExpression(array); const result = this.processArray( @@ -267,6 +381,7 @@ class AMDDefineDependencyParserPlugin { }); } } + /** @type {boolean | undefined} */ let inTry; if (fn && isUnboundFunctionExpression(fn)) { inTry = parser.scope.inTry; @@ -274,7 +389,7 @@ class AMDDefineDependencyParserPlugin { for (const [name, varInfo] of fnRenames) { parser.setVariable(name, varInfo); } - parser.scope.inTry = inTry; + parser.scope.inTry = /** @type {boolean} */ (inTry); if (fn.body.type === "BlockStatement") { parser.detectMode(fn.body.body); const prev = parser.prevStatement; @@ -287,23 +402,30 @@ class AMDDefineDependencyParserPlugin { }); } else if (fn && isBoundFunctionExpression(fn)) { inTry = parser.scope.inTry; + + const object = + /** @type {FunctionExpression} */ + (/** @type {MemberExpression} */ (fn.callee).object); + parser.inScope( - fn.callee.object.params.filter( + /** @type {Identifier[]} */ + (object.params).filter( i => !["require", "module", "exports"].includes(i.name) ), () => { for (const [name, varInfo] of fnRenames) { parser.setVariable(name, varInfo); } - parser.scope.inTry = inTry; - if (fn.callee.object.body.type === "BlockStatement") { - parser.detectMode(fn.callee.object.body.body); + parser.scope.inTry = /** @type {boolean} */ (inTry); + + if (object.body.type === "BlockStatement") { + parser.detectMode(object.body.body); const prev = parser.prevStatement; - parser.preWalkStatement(fn.callee.object.body); + parser.preWalkStatement(object.body); parser.prevStatement = prev; - parser.walkStatement(fn.callee.object.body); + parser.walkStatement(object.body); } else { - parser.walkExpression(fn.callee.object.body); + parser.walkExpression(object.body); } } ); @@ -315,13 +437,13 @@ class AMDDefineDependencyParserPlugin { } const dep = this.newDefineDependency( - expr.range, - array ? array.range : null, - fn ? fn.range : null, - obj ? obj.range : null, - namedModule ? namedModule : null + /** @type {Range} */ (expr.range), + array ? /** @type {Range} */ (array.range) : null, + fn ? /** @type {Range} */ (fn.range) : null, + obj ? /** @type {Range} */ (obj.range) : null, + namedModule || null ); - dep.loc = expr.loc; + dep.loc = /** @type {DependencyLocation} */ (expr.loc); if (namedModule) { dep.localModule = addLocalModule(parser.state, namedModule); } @@ -329,6 +451,14 @@ class AMDDefineDependencyParserPlugin { return true; } + /** + * @param {Range} range range + * @param {Range | null} arrayRange array range + * @param {Range | null} functionRange function range + * @param {Range | null} objectRange object range + * @param {string | null} namedModule true, when define is called with a name + * @returns {AMDDefineDependency} AMDDefineDependency + */ newDefineDependency( range, arrayRange, @@ -344,11 +474,24 @@ class AMDDefineDependencyParserPlugin { namedModule ); } + + /** + * @param {(string | LocalModuleDependency | AMDRequireItemDependency)[]} depsArray deps array + * @param {Range} range range + * @returns {AMDRequireArrayDependency} AMDRequireArrayDependency + */ newRequireArrayDependency(depsArray, range) { return new AMDRequireArrayDependency(depsArray, range); } + + /** + * @param {string} request request + * @param {Range=} range range + * @returns {AMDRequireItemDependency} AMDRequireItemDependency + */ newRequireItemDependency(request, range) { return new AMDRequireItemDependency(request, range); } } + module.exports = AMDDefineDependencyParserPlugin; diff --git a/lib/dependencies/AMDPlugin.js b/lib/dependencies/AMDPlugin.js index 57959e2d2cd..2ae03b78bc7 100644 --- a/lib/dependencies/AMDPlugin.js +++ b/lib/dependencies/AMDPlugin.js @@ -5,6 +5,10 @@ "use strict"; +const { + JAVASCRIPT_MODULE_TYPE_AUTO, + JAVASCRIPT_MODULE_TYPE_DYNAMIC +} = require("../ModuleTypeConstants"); const RuntimeGlobals = require("../RuntimeGlobals"); const { approve, @@ -28,8 +32,14 @@ const ConstDependency = require("./ConstDependency"); const LocalModuleDependency = require("./LocalModuleDependency"); const UnsupportedDependency = require("./UnsupportedDependency"); +/** @typedef {import("../../declarations/WebpackOptions").JavascriptParserOptions} JavascriptParserOptions */ /** @typedef {import("../../declarations/WebpackOptions").ModuleOptionsNormalized} ModuleOptions */ /** @typedef {import("../Compiler")} Compiler */ +/** @typedef {import("../Dependency").DependencyLocation} DependencyLocation */ +/** @typedef {import("../javascript/JavascriptParser")} Parser */ +/** @typedef {import("../javascript/JavascriptParser").Range} Range */ + +const PLUGIN_NAME = "AMDPlugin"; class AMDPlugin { /** @@ -47,7 +57,7 @@ class AMDPlugin { apply(compiler) { const amdOptions = this.amdOptions; compiler.hooks.compilation.tap( - "AMDPlugin", + PLUGIN_NAME, (compilation, { contextModuleFactory, normalModuleFactory }) => { compilation.dependencyTemplates.set( AMDRequireDependency, @@ -94,39 +104,49 @@ class AMDPlugin { compilation.hooks.runtimeRequirementInModule .for(RuntimeGlobals.amdDefine) - .tap("AMDPlugin", (module, set) => { + .tap(PLUGIN_NAME, (module, set) => { set.add(RuntimeGlobals.require); }); compilation.hooks.runtimeRequirementInModule .for(RuntimeGlobals.amdOptions) - .tap("AMDPlugin", (module, set) => { + .tap(PLUGIN_NAME, (module, set) => { set.add(RuntimeGlobals.requireScope); }); compilation.hooks.runtimeRequirementInTree .for(RuntimeGlobals.amdDefine) - .tap("AMDPlugin", (chunk, set) => { + .tap(PLUGIN_NAME, (chunk, set) => { compilation.addRuntimeModule(chunk, new AMDDefineRuntimeModule()); }); compilation.hooks.runtimeRequirementInTree .for(RuntimeGlobals.amdOptions) - .tap("AMDPlugin", (chunk, set) => { + .tap(PLUGIN_NAME, (chunk, set) => { compilation.addRuntimeModule( chunk, new AMDOptionsRuntimeModule(amdOptions) ); }); + /** + * @param {Parser} parser parser parser + * @param {JavascriptParserOptions} parserOptions parserOptions + * @returns {void} + */ const handler = (parser, parserOptions) => { if (parserOptions.amd !== undefined && !parserOptions.amd) return; + /** + * @param {string} optionExpr option expression + * @param {string} rootName root name + * @param {function(): TODO} getMembers callback + */ const tapOptionsHooks = (optionExpr, rootName, getMembers) => { parser.hooks.expression .for(optionExpr) .tap( - "AMDPlugin", + PLUGIN_NAME, toConstantDependency(parser, RuntimeGlobals.amdOptions, [ RuntimeGlobals.amdOptions ]) @@ -134,16 +154,16 @@ class AMDPlugin { parser.hooks.evaluateIdentifier .for(optionExpr) .tap( - "AMDPlugin", + PLUGIN_NAME, evaluateToIdentifier(optionExpr, rootName, getMembers, true) ); parser.hooks.evaluateTypeof .for(optionExpr) - .tap("AMDPlugin", evaluateToString("object")); + .tap(PLUGIN_NAME, evaluateToString("object")); parser.hooks.typeof .for(optionExpr) .tap( - "AMDPlugin", + PLUGIN_NAME, toConstantDependency(parser, JSON.stringify("object")) ); }; @@ -161,53 +181,53 @@ class AMDPlugin { () => [] ); - parser.hooks.expression.for("define").tap("AMDPlugin", expr => { + parser.hooks.expression.for("define").tap(PLUGIN_NAME, expr => { const dep = new ConstDependency( RuntimeGlobals.amdDefine, - expr.range, + /** @type {Range} */ (expr.range), [RuntimeGlobals.amdDefine] ); - dep.loc = expr.loc; + dep.loc = /** @type {DependencyLocation} */ (expr.loc); parser.state.module.addPresentationalDependency(dep); return true; }); parser.hooks.typeof .for("define") .tap( - "AMDPlugin", + PLUGIN_NAME, toConstantDependency(parser, JSON.stringify("function")) ); parser.hooks.evaluateTypeof .for("define") - .tap("AMDPlugin", evaluateToString("function")); - parser.hooks.canRename.for("define").tap("AMDPlugin", approve); - parser.hooks.rename.for("define").tap("AMDPlugin", expr => { + .tap(PLUGIN_NAME, evaluateToString("function")); + parser.hooks.canRename.for("define").tap(PLUGIN_NAME, approve); + parser.hooks.rename.for("define").tap(PLUGIN_NAME, expr => { const dep = new ConstDependency( RuntimeGlobals.amdDefine, - expr.range, + /** @type {Range} */ (expr.range), [RuntimeGlobals.amdDefine] ); - dep.loc = expr.loc; + dep.loc = /** @type {DependencyLocation} */ (expr.loc); parser.state.module.addPresentationalDependency(dep); return false; }); parser.hooks.typeof .for("require") .tap( - "AMDPlugin", + PLUGIN_NAME, toConstantDependency(parser, JSON.stringify("function")) ); parser.hooks.evaluateTypeof .for("require") - .tap("AMDPlugin", evaluateToString("function")); + .tap(PLUGIN_NAME, evaluateToString("function")); }; normalModuleFactory.hooks.parser - .for("javascript/auto") - .tap("AMDPlugin", handler); + .for(JAVASCRIPT_MODULE_TYPE_AUTO) + .tap(PLUGIN_NAME, handler); normalModuleFactory.hooks.parser - .for("javascript/dynamic") - .tap("AMDPlugin", handler); + .for(JAVASCRIPT_MODULE_TYPE_DYNAMIC) + .tap(PLUGIN_NAME, handler); } ); } diff --git a/lib/dependencies/AMDRequireArrayDependency.js b/lib/dependencies/AMDRequireArrayDependency.js index d62938d8e67..a182f6c230f 100644 --- a/lib/dependencies/AMDRequireArrayDependency.js +++ b/lib/dependencies/AMDRequireArrayDependency.js @@ -12,8 +12,17 @@ const NullDependency = require("./NullDependency"); /** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */ /** @typedef {import("../Dependency")} Dependency */ /** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */ +/** @typedef {import("../javascript/JavascriptParser").Range} Range */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */ +/** @typedef {import("./AMDRequireItemDependency")} AMDRequireItemDependency */ +/** @typedef {import("./LocalModuleDependency")} LocalModuleDependency */ class AMDRequireArrayDependency extends NullDependency { + /** + * @param {(string | LocalModuleDependency | AMDRequireItemDependency)[]} depsArray deps array + * @param {Range} range range + */ constructor(depsArray, range) { super(); @@ -29,6 +38,9 @@ class AMDRequireArrayDependency extends NullDependency { return "amd"; } + /** + * @param {ObjectSerializerContext} context context + */ serialize(context) { const { write } = context; @@ -38,6 +50,9 @@ class AMDRequireArrayDependency extends NullDependency { super.serialize(context); } + /** + * @param {ObjectDeserializerContext} context context + */ deserialize(context) { const { read } = context; @@ -68,13 +83,23 @@ AMDRequireArrayDependency.Template = class AMDRequireArrayDependencyTemplate ext source.replace(dep.range[0], dep.range[1] - 1, content); } + /** + * @param {AMDRequireArrayDependency} dep the dependency for which the template should be applied + * @param {DependencyTemplateContext} templateContext the context object + * @returns {string} content + */ getContent(dep, templateContext) { - const requires = dep.depsArray.map(dependency => { - return this.contentForDependency(dependency, templateContext); - }); + const requires = dep.depsArray.map(dependency => + this.contentForDependency(dependency, templateContext) + ); return `[${requires.join(", ")}]`; } + /** + * @param {TODO} dep the dependency for which the template should be applied + * @param {DependencyTemplateContext} templateContext the context object + * @returns {string} content + */ contentForDependency( dep, { runtimeTemplate, moduleGraph, chunkGraph, runtimeRequirements } @@ -85,14 +110,13 @@ AMDRequireArrayDependency.Template = class AMDRequireArrayDependencyTemplate ext if (dep.localModule) { return dep.localModule.variableName(); - } else { - return runtimeTemplate.moduleExports({ - module: moduleGraph.getModule(dep), - chunkGraph, - request: dep.request, - runtimeRequirements - }); } + return runtimeTemplate.moduleExports({ + module: moduleGraph.getModule(dep), + chunkGraph, + request: dep.request, + runtimeRequirements + }); } }; diff --git a/lib/dependencies/AMDRequireContextDependency.js b/lib/dependencies/AMDRequireContextDependency.js index 0d68a26e064..f040cb6e861 100644 --- a/lib/dependencies/AMDRequireContextDependency.js +++ b/lib/dependencies/AMDRequireContextDependency.js @@ -8,7 +8,16 @@ const makeSerializable = require("../util/makeSerializable"); const ContextDependency = require("./ContextDependency"); +/** @typedef {import("../javascript/JavascriptParser").Range} Range */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */ + class AMDRequireContextDependency extends ContextDependency { + /** + * @param {TODO} options options + * @param {Range} range range + * @param {Range} valueRange value range + */ constructor(options, range, valueRange) { super(options); @@ -24,6 +33,9 @@ class AMDRequireContextDependency extends ContextDependency { return "amd"; } + /** + * @param {ObjectSerializerContext} context context + */ serialize(context) { const { write } = context; @@ -33,6 +45,9 @@ class AMDRequireContextDependency extends ContextDependency { super.serialize(context); } + /** + * @param {ObjectDeserializerContext} context context + */ deserialize(context) { const { read } = context; diff --git a/lib/dependencies/AMDRequireDependenciesBlock.js b/lib/dependencies/AMDRequireDependenciesBlock.js index eebe0bce263..615660c3c9e 100644 --- a/lib/dependencies/AMDRequireDependenciesBlock.js +++ b/lib/dependencies/AMDRequireDependenciesBlock.js @@ -8,7 +8,13 @@ const AsyncDependenciesBlock = require("../AsyncDependenciesBlock"); const makeSerializable = require("../util/makeSerializable"); +/** @typedef {import("../Dependency").DependencyLocation} DependencyLocation */ + class AMDRequireDependenciesBlock extends AsyncDependenciesBlock { + /** + * @param {DependencyLocation} loc location info + * @param {string=} request request + */ constructor(loc, request) { super(null, loc, request); } diff --git a/lib/dependencies/AMDRequireDependenciesBlockParserPlugin.js b/lib/dependencies/AMDRequireDependenciesBlockParserPlugin.js index f49f55b4ff1..803ce398bee 100644 --- a/lib/dependencies/AMDRequireDependenciesBlockParserPlugin.js +++ b/lib/dependencies/AMDRequireDependenciesBlockParserPlugin.js @@ -19,19 +19,42 @@ const { getLocalModule } = require("./LocalModulesHelpers"); const UnsupportedDependency = require("./UnsupportedDependency"); const getFunctionExpression = require("./getFunctionExpression"); +/** @typedef {import("estree").CallExpression} CallExpression */ +/** @typedef {import("estree").Expression} Expression */ +/** @typedef {import("estree").Identifier} Identifier */ +/** @typedef {import("estree").SourceLocation} SourceLocation */ +/** @typedef {import("estree").SpreadElement} SpreadElement */ +/** @typedef {import("../../declarations/WebpackOptions").JavascriptParserOptions} JavascriptParserOptions */ +/** @typedef {import("../Dependency").DependencyLocation} DependencyLocation */ +/** @typedef {import("../Module").BuildInfo} BuildInfo */ +/** @typedef {import("../javascript/BasicEvaluatedExpression")} BasicEvaluatedExpression */ +/** @typedef {import("../javascript/JavascriptParser")} JavascriptParser */ +/** @typedef {import("../javascript/JavascriptParser").Range} Range */ + class AMDRequireDependenciesBlockParserPlugin { + /** + * @param {JavascriptParserOptions} options parserOptions + */ constructor(options) { this.options = options; } + /** + * @param {JavascriptParser} parser the parser + * @param {Expression | SpreadElement} expression expression + * @returns {boolean} need bind this + */ processFunctionArgument(parser, expression) { let bindThis = true; const fnData = getFunctionExpression(expression); if (fnData) { parser.inScope( - fnData.fn.params.filter(i => { - return !["require", "module", "exports"].includes(i.name); - }), + fnData.fn.params.filter( + i => + !["require", "module", "exports"].includes( + /** @type {Identifier} */ (i).name + ) + ), () => { if (fnData.fn.body.type === "BlockStatement") { parser.walkStatement(fnData.fn.body); @@ -50,6 +73,10 @@ class AMDRequireDependenciesBlockParserPlugin { return bindThis; } + /** + * @param {JavascriptParser} parser the parser + * @returns {void} + */ apply(parser) { parser.hooks.call .for("require") @@ -59,9 +86,15 @@ class AMDRequireDependenciesBlockParserPlugin { ); } + /** + * @param {JavascriptParser} parser the parser + * @param {CallExpression} expr call expression + * @param {BasicEvaluatedExpression} param param + * @returns {boolean | undefined} result + */ processArray(parser, expr, param) { if (param.isArray()) { - for (const p of param.items) { + for (const p of /** @type {BasicEvaluatedExpression[]} */ (param.items)) { const result = this.processItem(parser, expr, p); if (result === undefined) { this.processContext(parser, expr, p); @@ -69,36 +102,50 @@ class AMDRequireDependenciesBlockParserPlugin { } return true; } else if (param.isConstArray()) { + /** @type {(string | LocalModuleDependency | AMDRequireItemDependency)[]} */ const deps = []; - for (const request of param.array) { - let dep, localModule; + for (const request of /** @type {any[]} */ (param.array)) { + let dep; + let localModule; if (request === "require") { - dep = "__webpack_require__"; + dep = RuntimeGlobals.require; } else if (["exports", "module"].includes(request)) { dep = request; } else if ((localModule = getLocalModule(parser.state, request))) { localModule.flagUsed(); dep = new LocalModuleDependency(localModule, undefined, false); - dep.loc = expr.loc; + dep.loc = /** @type {DependencyLocation} */ (expr.loc); parser.state.module.addPresentationalDependency(dep); } else { dep = this.newRequireItemDependency(request); - dep.loc = expr.loc; - dep.optional = !!parser.scope.inTry; + dep.loc = /** @type {DependencyLocation} */ (expr.loc); + dep.optional = Boolean(parser.scope.inTry); parser.state.current.addDependency(dep); } deps.push(dep); } - const dep = this.newRequireArrayDependency(deps, param.range); - dep.loc = expr.loc; - dep.optional = !!parser.scope.inTry; + const dep = this.newRequireArrayDependency( + deps, + /** @type {Range} */ (param.range) + ); + dep.loc = /** @type {DependencyLocation} */ (expr.loc); + dep.optional = Boolean(parser.scope.inTry); parser.state.module.addPresentationalDependency(dep); return true; } } + + /** + * @param {JavascriptParser} parser the parser + * @param {CallExpression} expr call expression + * @param {BasicEvaluatedExpression} param param + * @returns {boolean | undefined} result + */ processItem(parser, expr, param) { if (param.isConditional()) { - for (const p of param.options) { + for (const p of /** @type {BasicEvaluatedExpression[]} */ ( + param.options + )) { const result = this.processItem(parser, expr, p); if (result === undefined) { this.processContext(parser, expr, p); @@ -106,42 +153,62 @@ class AMDRequireDependenciesBlockParserPlugin { } return true; } else if (param.isString()) { - let dep, localModule; + let dep; + let localModule; if (param.string === "require") { - dep = new ConstDependency("__webpack_require__", param.string, [ - RuntimeGlobals.require - ]); + dep = new ConstDependency( + RuntimeGlobals.require, + /** @type {TODO} */ (param.string), + [RuntimeGlobals.require] + ); } else if (param.string === "module") { dep = new ConstDependency( - parser.state.module.buildInfo.moduleArgument, - param.range, + /** @type {BuildInfo} */ + (parser.state.module.buildInfo).moduleArgument, + /** @type {Range} */ (param.range), [RuntimeGlobals.module] ); } else if (param.string === "exports") { dep = new ConstDependency( - parser.state.module.buildInfo.exportsArgument, - param.range, + /** @type {BuildInfo} */ + (parser.state.module.buildInfo).exportsArgument, + /** @type {Range} */ (param.range), [RuntimeGlobals.exports] ); - } else if ((localModule = getLocalModule(parser.state, param.string))) { + } else if ( + (localModule = getLocalModule( + parser.state, + /** @type {string} */ (param.string) + )) + ) { localModule.flagUsed(); dep = new LocalModuleDependency(localModule, param.range, false); } else { - dep = this.newRequireItemDependency(param.string, param.range); - dep.loc = expr.loc; - dep.optional = !!parser.scope.inTry; + dep = this.newRequireItemDependency( + /** @type {string} */ (param.string), + param.range + ); + dep.loc = /** @type {DependencyLocation} */ (expr.loc); + dep.optional = Boolean(parser.scope.inTry); parser.state.current.addDependency(dep); return true; } - dep.loc = expr.loc; + dep.loc = /** @type {DependencyLocation} */ (expr.loc); parser.state.module.addPresentationalDependency(dep); return true; } } + + /** + * @param {JavascriptParser} parser the parser + * @param {CallExpression} expr call expression + * @param {BasicEvaluatedExpression} param param + * @returns {boolean | undefined} result + */ processContext(parser, expr, param) { const dep = ContextDependencyHelpers.create( AMDRequireContextDependency, - param.range, + /** @type {Range} */ (param.range), param, expr, this.options, @@ -151,96 +218,135 @@ class AMDRequireDependenciesBlockParserPlugin { parser ); if (!dep) return; - dep.loc = expr.loc; - dep.optional = !!parser.scope.inTry; + dep.loc = /** @type {DependencyLocation} */ (expr.loc); + dep.optional = Boolean(parser.scope.inTry); parser.state.current.addDependency(dep); return true; } + /** + * @param {BasicEvaluatedExpression} param param + * @returns {string | undefined} result + */ processArrayForRequestString(param) { if (param.isArray()) { - const result = param.items.map(item => - this.processItemForRequestString(item) - ); + const result = + /** @type {BasicEvaluatedExpression[]} */ + (param.items).map(item => this.processItemForRequestString(item)); if (result.every(Boolean)) return result.join(" "); } else if (param.isConstArray()) { - return param.array.join(" "); + return /** @type {string[]} */ (param.array).join(" "); } } + /** + * @param {BasicEvaluatedExpression} param param + * @returns {string | undefined} result + */ processItemForRequestString(param) { if (param.isConditional()) { - const result = param.options.map(item => - this.processItemForRequestString(item) - ); + const result = + /** @type {BasicEvaluatedExpression[]} */ + (param.options).map(item => this.processItemForRequestString(item)); if (result.every(Boolean)) return result.join("|"); } else if (param.isString()) { return param.string; } } + /** + * @param {JavascriptParser} parser the parser + * @param {CallExpression} expr call expression + * @returns {boolean | undefined} result + */ processCallRequire(parser, expr) { + /** @type {BasicEvaluatedExpression | undefined} */ let param; + /** @type {AMDRequireDependenciesBlock | undefined | null} */ let depBlock; + /** @type {AMDRequireDependency | undefined} */ let dep; + /** @type {boolean | undefined} */ let result; const old = parser.state.current; if (expr.arguments.length >= 1) { - param = parser.evaluateExpression(expr.arguments[0]); + param = parser.evaluateExpression( + /** @type {Expression} */ (expr.arguments[0]) + ); depBlock = this.newRequireDependenciesBlock( - expr.loc, + /** @type {DependencyLocation} */ (expr.loc), this.processArrayForRequestString(param) ); dep = this.newRequireDependency( - expr.range, - param.range, - expr.arguments.length > 1 ? expr.arguments[1].range : null, - expr.arguments.length > 2 ? expr.arguments[2].range : null + /** @type {Range} */ (expr.range), + /** @type {Range} */ (param.range), + expr.arguments.length > 1 + ? /** @type {Range} */ (expr.arguments[1].range) + : null, + expr.arguments.length > 2 + ? /** @type {Range} */ (expr.arguments[2].range) + : null ); - dep.loc = expr.loc; + dep.loc = /** @type {DependencyLocation} */ (expr.loc); depBlock.addDependency(dep); - parser.state.current = depBlock; + parser.state.current = /** @type {TODO} */ (depBlock); } if (expr.arguments.length === 1) { parser.inScope([], () => { - result = this.processArray(parser, expr, param); + result = this.processArray( + parser, + expr, + /** @type {BasicEvaluatedExpression} */ (param) + ); }); parser.state.current = old; if (!result) return; - parser.state.current.addBlock(depBlock); + parser.state.current.addBlock( + /** @type {AMDRequireDependenciesBlock} */ (depBlock) + ); return true; } if (expr.arguments.length === 2 || expr.arguments.length === 3) { try { parser.inScope([], () => { - result = this.processArray(parser, expr, param); + result = this.processArray( + parser, + expr, + /** @type {BasicEvaluatedExpression} */ (param) + ); }); if (!result) { - const dep = new UnsupportedDependency("unsupported", expr.range); + const dep = new UnsupportedDependency( + "unsupported", + /** @type {Range} */ (expr.range) + ); old.addPresentationalDependency(dep); if (parser.state.module) { parser.state.module.addError( new UnsupportedFeatureWarning( - "Cannot statically analyse 'require(โ€ฆ, โ€ฆ)' in line " + - expr.loc.start.line, - expr.loc + `Cannot statically analyse 'require(โ€ฆ, โ€ฆ)' in line ${ + /** @type {SourceLocation} */ (expr.loc).start.line + }`, + /** @type {DependencyLocation} */ (expr.loc) ) ); } depBlock = null; return true; } - dep.functionBindThis = this.processFunctionArgument( + /** @type {AMDRequireDependency} */ + (dep).functionBindThis = this.processFunctionArgument( parser, expr.arguments[1] ); if (expr.arguments.length === 3) { - dep.errorCallbackBindThis = this.processFunctionArgument( + /** @type {AMDRequireDependency} */ + (dep).errorCallbackBindThis = this.processFunctionArgument( parser, expr.arguments[2] ); @@ -253,9 +359,22 @@ class AMDRequireDependenciesBlockParserPlugin { } } + /** + * @param {DependencyLocation} loc location + * @param {string=} request request + * @returns {AMDRequireDependenciesBlock} AMDRequireDependenciesBlock + */ newRequireDependenciesBlock(loc, request) { return new AMDRequireDependenciesBlock(loc, request); } + + /** + * @param {Range} outerRange outer range + * @param {Range} arrayRange array range + * @param {Range | null} functionRange function range + * @param {Range | null} errorCallbackRange error callback range + * @returns {AMDRequireDependency} dependency + */ newRequireDependency( outerRange, arrayRange, @@ -269,9 +388,21 @@ class AMDRequireDependenciesBlockParserPlugin { errorCallbackRange ); } + + /** + * @param {string} request request + * @param {Range=} range range + * @returns {AMDRequireItemDependency} AMDRequireItemDependency + */ newRequireItemDependency(request, range) { return new AMDRequireItemDependency(request, range); } + + /** + * @param {(string | LocalModuleDependency | AMDRequireItemDependency)[]} depsArray deps array + * @param {Range} range range + * @returns {AMDRequireArrayDependency} AMDRequireArrayDependency + */ newRequireArrayDependency(depsArray, range) { return new AMDRequireArrayDependency(depsArray, range); } diff --git a/lib/dependencies/AMDRequireDependency.js b/lib/dependencies/AMDRequireDependency.js index 7266390d130..930348fc948 100644 --- a/lib/dependencies/AMDRequireDependency.js +++ b/lib/dependencies/AMDRequireDependency.js @@ -13,8 +13,17 @@ const NullDependency = require("./NullDependency"); /** @typedef {import("../AsyncDependenciesBlock")} AsyncDependenciesBlock */ /** @typedef {import("../Dependency")} Dependency */ /** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */ +/** @typedef {import("../javascript/JavascriptParser").Range} Range */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */ class AMDRequireDependency extends NullDependency { + /** + * @param {Range} outerRange outer range + * @param {Range} arrayRange array range + * @param {Range | null} functionRange function range + * @param {Range | null} errorCallbackRange error callback range + */ constructor(outerRange, arrayRange, functionRange, errorCallbackRange) { super(); @@ -30,6 +39,9 @@ class AMDRequireDependency extends NullDependency { return "amd"; } + /** + * @param {ObjectSerializerContext} context context + */ serialize(context) { const { write } = context; @@ -43,6 +55,9 @@ class AMDRequireDependency extends NullDependency { super.serialize(context); } + /** + * @param {ObjectDeserializerContext} context context + */ deserialize(context) { const { read } = context; @@ -77,9 +92,9 @@ AMDRequireDependency.Template = class AMDRequireDependencyTemplate extends ( { runtimeTemplate, moduleGraph, chunkGraph, runtimeRequirements } ) { const dep = /** @type {AMDRequireDependency} */ (dependency); - const depBlock = /** @type {AsyncDependenciesBlock} */ (moduleGraph.getParentBlock( - dep - )); + const depBlock = /** @type {AsyncDependenciesBlock} */ ( + moduleGraph.getParentBlock(dep) + ); const promise = runtimeTemplate.blockPromise({ chunkGraph, block: depBlock, @@ -90,7 +105,7 @@ AMDRequireDependency.Template = class AMDRequireDependencyTemplate extends ( // has array range but no function range if (dep.arrayRange && !dep.functionRange) { const startBlock = `${promise}.then(function() {`; - const endBlock = `;}).catch(${RuntimeGlobals.uncaughtErrorHandler})`; + const endBlock = `;})['catch'](${RuntimeGlobals.uncaughtErrorHandler})`; runtimeRequirements.add(RuntimeGlobals.uncaughtErrorHandler); source.replace(dep.outerRange[0], dep.arrayRange[0] - 1, startBlock); @@ -103,7 +118,7 @@ AMDRequireDependency.Template = class AMDRequireDependencyTemplate extends ( // has function range but no array range if (dep.functionRange && !dep.arrayRange) { const startBlock = `${promise}.then((`; - const endBlock = `).bind(exports, __webpack_require__, exports, module)).catch(${RuntimeGlobals.uncaughtErrorHandler})`; + const endBlock = `).bind(exports, ${RuntimeGlobals.require}, exports, module))['catch'](${RuntimeGlobals.uncaughtErrorHandler})`; runtimeRequirements.add(RuntimeGlobals.uncaughtErrorHandler); source.replace(dep.outerRange[0], dep.functionRange[0] - 1, startBlock); @@ -118,15 +133,12 @@ AMDRequireDependency.Template = class AMDRequireDependencyTemplate extends ( const startBlock = `${promise}.then(function() { `; const errorRangeBlock = `}${ dep.functionBindThis ? ".bind(this)" : "" - }).catch(`; + })['catch'](`; const endBlock = `${dep.errorCallbackBindThis ? ".bind(this)" : ""})`; source.replace(dep.outerRange[0], dep.arrayRange[0] - 1, startBlock); - source.insert( - dep.arrayRange[0] + 0.9, - "var __WEBPACK_AMD_REQUIRE_ARRAY__ = " - ); + source.insert(dep.arrayRange[0], "var __WEBPACK_AMD_REQUIRE_ARRAY__ = "); source.replace(dep.arrayRange[1], dep.functionRange[0] - 1, "; ("); @@ -153,17 +165,14 @@ AMDRequireDependency.Template = class AMDRequireDependencyTemplate extends ( // has array range, function range, but no errorCallbackRange if (dep.arrayRange && dep.functionRange) { const startBlock = `${promise}.then(function() { `; - const endBlock = `}${dep.functionBindThis ? ".bind(this)" : ""}).catch(${ - RuntimeGlobals.uncaughtErrorHandler - })`; + const endBlock = `}${ + dep.functionBindThis ? ".bind(this)" : "" + })['catch'](${RuntimeGlobals.uncaughtErrorHandler})`; runtimeRequirements.add(RuntimeGlobals.uncaughtErrorHandler); source.replace(dep.outerRange[0], dep.arrayRange[0] - 1, startBlock); - source.insert( - dep.arrayRange[0] + 0.9, - "var __WEBPACK_AMD_REQUIRE_ARRAY__ = " - ); + source.insert(dep.arrayRange[0], "var __WEBPACK_AMD_REQUIRE_ARRAY__ = "); source.replace(dep.arrayRange[1], dep.functionRange[0] - 1, "; ("); diff --git a/lib/dependencies/AMDRequireItemDependency.js b/lib/dependencies/AMDRequireItemDependency.js index c21d87b641e..614633ad324 100644 --- a/lib/dependencies/AMDRequireItemDependency.js +++ b/lib/dependencies/AMDRequireItemDependency.js @@ -9,7 +9,13 @@ const makeSerializable = require("../util/makeSerializable"); const ModuleDependency = require("./ModuleDependency"); const ModuleDependencyTemplateAsRequireId = require("./ModuleDependencyTemplateAsRequireId"); +/** @typedef {import("../javascript/JavascriptParser").Range} Range */ + class AMDRequireItemDependency extends ModuleDependency { + /** + * @param {string} request the request string + * @param {Range=} range location in source code + */ constructor(request, range) { super(request); diff --git a/lib/dependencies/AMDRuntimeModules.js b/lib/dependencies/AMDRuntimeModules.js index b565e937a75..cec00bb8412 100644 --- a/lib/dependencies/AMDRuntimeModules.js +++ b/lib/dependencies/AMDRuntimeModules.js @@ -14,7 +14,7 @@ class AMDDefineRuntimeModule extends RuntimeModule { } /** - * @returns {string} runtime code + * @returns {string | null} runtime code */ generate() { return Template.asString([ @@ -35,7 +35,7 @@ class AMDOptionsRuntimeModule extends RuntimeModule { } /** - * @returns {string} runtime code + * @returns {string | null} runtime code */ generate() { return Template.asString([ @@ -44,5 +44,5 @@ class AMDOptionsRuntimeModule extends RuntimeModule { } } -exports.AMDDefineRuntimeModule = AMDDefineRuntimeModule; -exports.AMDOptionsRuntimeModule = AMDOptionsRuntimeModule; +module.exports.AMDDefineRuntimeModule = AMDDefineRuntimeModule; +module.exports.AMDOptionsRuntimeModule = AMDOptionsRuntimeModule; diff --git a/lib/dependencies/CachedConstDependency.js b/lib/dependencies/CachedConstDependency.js index 9d44954704e..60826f5a859 100644 --- a/lib/dependencies/CachedConstDependency.js +++ b/lib/dependencies/CachedConstDependency.js @@ -18,15 +18,31 @@ const NullDependency = require("./NullDependency"); /** @typedef {import("../DependencyTemplates")} DependencyTemplates */ /** @typedef {import("../ModuleGraph")} ModuleGraph */ /** @typedef {import("../RuntimeTemplate")} RuntimeTemplate */ +/** @typedef {import("../javascript/JavascriptParser").Range} Range */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */ /** @typedef {import("../util/Hash")} Hash */ class CachedConstDependency extends NullDependency { + /** + * @param {string} expression expression + * @param {Range} range range + * @param {string} identifier identifier + */ constructor(expression, range, identifier) { super(); this.expression = expression; this.range = range; this.identifier = identifier; + this._hashUpdate = undefined; + } + + /** + * @returns {string} hash update + */ + _createHashUpdate() { + return `${this.identifier}${this.range}${this.expression}`; } /** @@ -36,11 +52,14 @@ class CachedConstDependency extends NullDependency { * @returns {void} */ updateHash(hash, context) { - hash.update(this.identifier + ""); - hash.update(this.range + ""); - hash.update(this.expression + ""); + if (this._hashUpdate === undefined) + this._hashUpdate = this._createHashUpdate(); + hash.update(this._hashUpdate); } + /** + * @param {ObjectSerializerContext} context context + */ serialize(context) { const { write } = context; @@ -51,6 +70,9 @@ class CachedConstDependency extends NullDependency { super.serialize(context); } + /** + * @param {ObjectDeserializerContext} context context + */ deserialize(context) { const { read } = context; diff --git a/lib/dependencies/CommonJsDependencyHelpers.js b/lib/dependencies/CommonJsDependencyHelpers.js index e3955590215..0cd457ee73a 100644 --- a/lib/dependencies/CommonJsDependencyHelpers.js +++ b/lib/dependencies/CommonJsDependencyHelpers.js @@ -7,8 +7,22 @@ const RuntimeGlobals = require("../RuntimeGlobals"); -exports.handleDependencyBase = (depBase, module, runtimeRequirements) => { - let base = undefined; +/** @typedef {import("../Module")} Module */ +/** @typedef {import("../Module").RuntimeRequirements} RuntimeRequirements */ +/** @typedef {"exports" | "module.exports" | "this" | "Object.defineProperty(exports)" | "Object.defineProperty(module.exports)" | "Object.defineProperty(this)"} CommonJSDependencyBaseKeywords */ + +/** + * @param {CommonJSDependencyBaseKeywords} depBase commonjs dependency base + * @param {Module} module module + * @param {RuntimeRequirements} runtimeRequirements runtime requirements + * @returns {[string, string]} type and base + */ +module.exports.handleDependencyBase = ( + depBase, + module, + runtimeRequirements +) => { + let base; let type; switch (depBase) { case "exports": diff --git a/lib/dependencies/CommonJsExportRequireDependency.js b/lib/dependencies/CommonJsExportRequireDependency.js index 2f488f35540..d4f7a73c8fe 100644 --- a/lib/dependencies/CommonJsExportRequireDependency.js +++ b/lib/dependencies/CommonJsExportRequireDependency.js @@ -18,16 +18,32 @@ const processExportInfo = require("./processExportInfo"); /** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */ /** @typedef {import("../Dependency").ExportsSpec} ExportsSpec */ /** @typedef {import("../Dependency").ReferencedExport} ReferencedExport */ +/** @typedef {import("../Dependency").TRANSITIVE} TRANSITIVE */ /** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */ +/** @typedef {import("../ExportsInfo")} ExportsInfo */ +/** @typedef {import("../ExportsInfo").ExportInfo} ExportInfo */ /** @typedef {import("../Module")} Module */ /** @typedef {import("../ModuleGraph")} ModuleGraph */ +/** @typedef {import("../javascript/JavascriptParser").Range} Range */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */ /** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */ +/** @typedef {import("./CommonJsDependencyHelpers").CommonJSDependencyBaseKeywords} CommonJSDependencyBaseKeywords */ const idsSymbol = Symbol("CommonJsExportRequireDependency.ids"); const EMPTY_OBJECT = {}; class CommonJsExportRequireDependency extends ModuleDependency { + /** + * @param {Range} range range + * @param {Range | null} valueRange value range + * @param {CommonJSDependencyBaseKeywords} base base + * @param {string[]} names names + * @param {string} request request + * @param {string[]} ids ids + * @param {boolean} resultUsed true, when the result is used + */ constructor(range, valueRange, base, names, request, ids, resultUsed) { super(request); this.range = range; @@ -43,12 +59,21 @@ class CommonJsExportRequireDependency extends ModuleDependency { return "cjs export require"; } + /** + * @returns {boolean | TRANSITIVE} true, when changes to the referenced module could affect the referencing module; TRANSITIVE, when changes to the referenced module could affect referencing modules of the referencing module + */ + couldAffectReferencingModule() { + return Dependency.TRANSITIVE; + } + /** * @param {ModuleGraph} moduleGraph the module graph * @returns {string[]} the imported id */ getIds(moduleGraph) { - return moduleGraph.getMeta(this)[idsSymbol] || this.ids; + return ( + /** @type {TODO} */ (moduleGraph.getMeta(this))[idsSymbol] || this.ids + ); } /** @@ -57,7 +82,7 @@ class CommonJsExportRequireDependency extends ModuleDependency { * @returns {void} */ setIds(moduleGraph, ids) { - moduleGraph.getMeta(this)[idsSymbol] = ids; + /** @type {TODO} */ (moduleGraph.getMeta(this))[idsSymbol] = ids; } /** @@ -71,21 +96,23 @@ class CommonJsExportRequireDependency extends ModuleDependency { const getFullResult = () => { if (ids.length === 0) { return Dependency.EXPORTS_OBJECT_REFERENCED; - } else { - return [ - { - name: ids, - canMangle: false - } - ]; } + return [ + { + name: ids, + canMangle: false + } + ]; }; if (this.resultUsed) return getFullResult(); + /** @type {ExportsInfo | undefined} */ let exportsInfo = moduleGraph.getExportsInfo( - moduleGraph.getParentModule(this) + /** @type {Module} */ (moduleGraph.getParentModule(this)) ); for (const name of this.names) { - const exportInfo = exportsInfo.getReadOnlyExportInfo(name); + const exportInfo = /** @type {ExportInfo} */ ( + exportsInfo.getReadOnlyExportInfo(name) + ); const used = exportInfo.getUsed(runtime); if (used === UsageState.Unused) return Dependency.NO_EXPORTS_REFERENCED; if (used !== UsageState.OnlyPropertiesUsed) return getFullResult(); @@ -118,8 +145,8 @@ class CommonJsExportRequireDependency extends ModuleDependency { * @returns {ExportsSpec | undefined} export names */ getExports(moduleGraph) { - const ids = this.getIds(moduleGraph); if (this.names.length === 1) { + const ids = this.getIds(moduleGraph); const name = this.names[0]; const from = moduleGraph.getConnection(this); if (!from) return; @@ -151,55 +178,57 @@ class CommonJsExportRequireDependency extends ModuleDependency { ], dependencies: undefined }; - } else { - const from = moduleGraph.getConnection(this); - if (!from) return; - const reexportInfo = this.getStarReexports( - moduleGraph, - undefined, - from.module - ); - if (reexportInfo) { - return { - exports: Array.from(reexportInfo.exports, name => { - return { - name, - from, - export: ids.concat(name), - canMangle: !(name in EMPTY_OBJECT) && false - }; - }), - // TODO handle deep reexports - dependencies: [from.module] - }; - } else { - return { - exports: true, - from: ids.length === 0 ? from : undefined, - canMangle: false, - dependencies: [from.module] - }; - } } + const from = moduleGraph.getConnection(this); + if (!from) return; + const reexportInfo = this.getStarReexports( + moduleGraph, + undefined, + from.module + ); + const ids = this.getIds(moduleGraph); + if (reexportInfo) { + return { + exports: Array.from( + /** @type {TODO} */ (reexportInfo).exports, + name => ({ + name, + from, + export: ids.concat(name), + canMangle: !(name in EMPTY_OBJECT) && false + }) + ), + // TODO handle deep reexports + dependencies: [from.module] + }; + } + return { + exports: true, + from: ids.length === 0 ? from : undefined, + canMangle: false, + dependencies: [from.module] + }; } /** * @param {ModuleGraph} moduleGraph the module graph * @param {RuntimeSpec} runtime the runtime * @param {Module} importedModule the imported module (optional) - * @returns {{exports?: Set, checked?: Set}} information + * @returns {{exports?: Set, checked?: Set} | undefined} information */ getStarReexports( moduleGraph, runtime, - importedModule = moduleGraph.getModule(this) + importedModule = /** @type {Module} */ (moduleGraph.getModule(this)) ) { + /** @type {ExportsInfo | undefined} */ let importedExportsInfo = moduleGraph.getExportsInfo(importedModule); const ids = this.getIds(moduleGraph); if (ids.length > 0) importedExportsInfo = importedExportsInfo.getNestedExportsInfo(ids); + /** @type {ExportsInfo | undefined} */ let exportsInfo = moduleGraph.getExportsInfo( - moduleGraph.getParentModule(this) + /** @type {Module} */ (moduleGraph.getParentModule(this)) ); if (this.names.length > 0) exportsInfo = exportsInfo.getNestedExportsInfo(this.names); @@ -224,15 +253,15 @@ class CommonJsExportRequireDependency extends ModuleDependency { const checked = new Set(); if (noExtraImports) { - for (const exportInfo of exportsInfo.orderedExports) { + for (const exportInfo of /** @type {ExportsInfo} */ (exportsInfo) + .orderedExports) { const name = exportInfo.name; if (exportInfo.getUsed(runtime) === UsageState.Unused) continue; if (name === "__esModule" && isNamespaceImport) { exports.add(name); } else if (importedExportsInfo) { - const importedExportInfo = importedExportsInfo.getReadOnlyExportInfo( - name - ); + const importedExportInfo = + importedExportsInfo.getReadOnlyExportInfo(name); if (importedExportInfo.provided === false) continue; exports.add(name); if (importedExportInfo.provided === true) continue; @@ -243,7 +272,9 @@ class CommonJsExportRequireDependency extends ModuleDependency { } } } else if (noExtraExports) { - for (const importedExportInfo of importedExportsInfo.orderedExports) { + for (const importedExportInfo of /** @type {ExportsInfo} */ ( + importedExportsInfo + ).orderedExports) { const name = importedExportInfo.name; if (importedExportInfo.provided === false) continue; if (exportsInfo) { @@ -263,6 +294,9 @@ class CommonJsExportRequireDependency extends ModuleDependency { return { exports, checked }; } + /** + * @param {ObjectSerializerContext} context context + */ serialize(context) { const { write } = context; write(this.asiSafe); @@ -275,6 +309,9 @@ class CommonJsExportRequireDependency extends ModuleDependency { super.serialize(context); } + /** + * @param {ObjectDeserializerContext} context context + */ deserialize(context) { const { read } = context; this.asiSafe = read(); @@ -333,15 +370,17 @@ CommonJsExportRequireDependency.Template = class CommonJsExportRequireDependency weak: dep.weak, runtimeRequirements }); - const ids = dep.getIds(moduleGraph); - const usedImported = moduleGraph - .getExportsInfo(importedModule) - .getUsedName(ids, runtime); - if (usedImported) { - const comment = equals(usedImported, ids) - ? "" - : Template.toNormalComment(propertyAccess(ids)) + " "; - requireExpr += `${comment}${propertyAccess(usedImported)}`; + if (importedModule) { + const ids = dep.getIds(moduleGraph); + const usedImported = moduleGraph + .getExportsInfo(importedModule) + .getUsedName(ids, runtime); + if (usedImported) { + const comment = equals(usedImported, ids) + ? "" + : `${Template.toNormalComment(propertyAccess(ids))} `; + requireExpr += `${comment}${propertyAccess(usedImported)}`; + } } switch (type) { diff --git a/lib/dependencies/CommonJsExportsDependency.js b/lib/dependencies/CommonJsExportsDependency.js index 0715582edf9..93c831b5dfd 100644 --- a/lib/dependencies/CommonJsExportsDependency.js +++ b/lib/dependencies/CommonJsExportsDependency.js @@ -16,10 +16,20 @@ const NullDependency = require("./NullDependency"); /** @typedef {import("../Dependency").ExportsSpec} ExportsSpec */ /** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */ /** @typedef {import("../ModuleGraph")} ModuleGraph */ +/** @typedef {import("../javascript/JavascriptParser").Range} Range */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */ +/** @typedef {import("./CommonJsDependencyHelpers").CommonJSDependencyBaseKeywords} CommonJSDependencyBaseKeywords */ const EMPTY_OBJECT = {}; class CommonJsExportsDependency extends NullDependency { + /** + * @param {Range} range range + * @param {Range | null} valueRange value range + * @param {CommonJSDependencyBaseKeywords} base base + * @param {string[]} names names + */ constructor(range, valueRange, base, names) { super(); this.range = range; @@ -53,6 +63,9 @@ class CommonJsExportsDependency extends NullDependency { }; } + /** + * @param {ObjectSerializerContext} context context + */ serialize(context) { const { write } = context; write(this.range); @@ -62,6 +75,9 @@ class CommonJsExportsDependency extends NullDependency { super.serialize(context); } + /** + * @param {ObjectDeserializerContext} context context + */ deserialize(context) { const { read } = context; this.range = read(); @@ -138,21 +154,28 @@ CommonJsExportsDependency.Template = class CommonJsExportsDependencyTemplate ext ); source.replace( dep.range[0], - dep.valueRange[0] - 1, + /** @type {Range} */ (dep.valueRange)[0] - 1, "__webpack_unused_export__ = (" ); - source.replace(dep.valueRange[1], dep.range[1] - 1, ")"); + source.replace( + /** @type {Range} */ (dep.valueRange)[1], + dep.range[1] - 1, + ")" + ); return; } source.replace( dep.range[0], - dep.valueRange[0] - 1, + /** @type {Range} */ (dep.valueRange)[0] - 1, `Object.defineProperty(${base}${propertyAccess( used.slice(0, -1) )}, ${JSON.stringify(used[used.length - 1])}, (` ); - source.replace(dep.valueRange[1], dep.range[1] - 1, "))"); - return; + source.replace( + /** @type {Range} */ (dep.valueRange)[1], + dep.range[1] - 1, + "))" + ); } } }; diff --git a/lib/dependencies/CommonJsExportsParserPlugin.js b/lib/dependencies/CommonJsExportsParserPlugin.js index d528478ffdb..2e04a494314 100644 --- a/lib/dependencies/CommonJsExportsParserPlugin.js +++ b/lib/dependencies/CommonJsExportsParserPlugin.js @@ -16,11 +16,36 @@ const DynamicExports = require("./DynamicExports"); const HarmonyExports = require("./HarmonyExports"); const ModuleDecoratorDependency = require("./ModuleDecoratorDependency"); -/** @typedef {import("estree").Expression} ExpressionNode */ +/** @typedef {import("estree").AssignmentExpression} AssignmentExpression */ +/** @typedef {import("estree").CallExpression} CallExpression */ +/** @typedef {import("estree").Expression} Expression */ +/** @typedef {import("estree").Super} Super */ +/** @typedef {import("../Dependency").DependencyLocation} DependencyLocation */ +/** @typedef {import("../ModuleGraph")} ModuleGraph */ /** @typedef {import("../NormalModule")} NormalModule */ /** @typedef {import("../javascript/BasicEvaluatedExpression")} BasicEvaluatedExpression */ /** @typedef {import("../javascript/JavascriptParser")} JavascriptParser */ +/** @typedef {import("../javascript/JavascriptParser").Range} Range */ +/** @typedef {import("./CommonJsDependencyHelpers").CommonJSDependencyBaseKeywords} CommonJSDependencyBaseKeywords */ +/** + * This function takes a generic expression and detects whether it is an ObjectExpression. + * This is used in the context of parsing CommonJS exports to get the value of the property descriptor + * when the `exports` object is assigned to `Object.defineProperty`. + * + * In CommonJS modules, the `exports` object can be assigned to `Object.defineProperty` and therefore + * webpack has to detect this case and get the value key of the property descriptor. See the following example + * for more information: https://astexplorer.net/#/gist/83ce51a4e96e59d777df315a6d111da6/8058ead48a1bb53c097738225db0967ef7f70e57 + * + * This would be an example of a CommonJS module that exports an object with a property descriptor: + * ```js + * Object.defineProperty(exports, "__esModule", { value: true }); + * exports.foo = void 0; + * exports.foo = "bar"; + * ``` + * @param {TODO} expr expression + * @returns {Expression | undefined} returns the value of property descriptor + */ const getValueOfPropertyDescription = expr => { if (expr.type !== "ObjectExpression") return; for (const property of expr.properties) { @@ -31,16 +56,30 @@ const getValueOfPropertyDescription = expr => { } }; +/** + * The purpose of this function is to check whether an expression is a truthy literal or not. This is + * useful when parsing CommonJS exports, because CommonJS modules can export any value, including falsy + * values like `null` and `false`. However, exports should only be created if the exported value is truthy. + * @param {Expression} expr expression being checked + * @returns {boolean} true, when the expression is a truthy literal + */ const isTruthyLiteral = expr => { switch (expr.type) { case "Literal": - return !!expr.value; + return Boolean(expr.value); case "UnaryExpression": if (expr.operator === "!") return isFalsyLiteral(expr.argument); } return false; }; +/** + * The purpose of this function is to check whether an expression is a falsy literal or not. This is + * useful when parsing CommonJS exports, because CommonJS modules can export any value, including falsy + * values like `null` and `false`. However, exports should only be created if the exported value is truthy. + * @param {Expression} expr expression being checked + * @returns {boolean} true, when the expression is a falsy literal + */ const isFalsyLiteral = expr => { switch (expr.type) { case "Literal": @@ -53,7 +92,7 @@ const isFalsyLiteral = expr => { /** * @param {JavascriptParser} parser the parser - * @param {ExpressionNode} expr expression + * @param {Expression} expr expression * @returns {{ argument: BasicEvaluatedExpression, ids: string[] } | undefined} parsed call */ const parseRequireCall = (parser, expr) => { @@ -86,17 +125,28 @@ const parseRequireCall = (parser, expr) => { }; class CommonJsExportsParserPlugin { + /** + * @param {ModuleGraph} moduleGraph module graph + */ constructor(moduleGraph) { this.moduleGraph = moduleGraph; } /** * @param {JavascriptParser} parser the parser + * @returns {void} */ apply(parser) { const enableStructuredExports = () => { DynamicExports.enable(parser.state); }; + + /** + * @param {boolean} topLevel true, when the export is on top level + * @param {string[]} members members of the export + * @param {Expression | undefined} valueExpr expression for the value + * @returns {void} + */ const checkNamespace = (topLevel, members, valueExpr) => { if (!DynamicExports.isEnabled(parser.state)) return; if (members.length > 0 && members[0] === "__esModule") { @@ -107,10 +157,16 @@ class CommonJsExportsParserPlugin { } } }; + /** + * @param {string=} reason reason + */ const bailout = reason => { DynamicExports.bailout(parser.state); if (reason) bailoutHint(reason); }; + /** + * @param {string} reason reason + */ const bailoutHint = reason => { this.moduleGraph .getOptimizationBailout(parser.state.module) @@ -126,6 +182,13 @@ class CommonJsExportsParserPlugin { .tap("CommonJsPlugin", evaluateToString("object")); // exporting // + + /** + * @param {AssignmentExpression} expr expression + * @param {CommonJSDependencyBaseKeywords} base commonjs base keywords + * @param {string[]} members members of the export + * @returns {boolean | undefined} true, when the expression was handled + */ const handleAssignExport = (expr, base, members) => { if (HarmonyExports.isEnabled(parser.state)) return; // Handle reexporting @@ -139,16 +202,16 @@ class CommonJsExportsParserPlugin { // It's possible to reexport __esModule, so we must convert to a dynamic module if (members.length === 0) DynamicExports.setDynamic(parser.state); const dep = new CommonJsExportRequireDependency( - expr.range, + /** @type {Range} */ (expr.range), null, base, members, - requireCall.argument.string, + /** @type {string} */ (requireCall.argument.string), requireCall.ids, !parser.isStatementLevelExpression(expr) ); - dep.loc = expr.loc; - dep.optional = !!parser.scope.inTry; + dep.loc = /** @type {DependencyLocation} */ (expr.loc); + dep.optional = Boolean(parser.scope.inTry); parser.state.module.addDependency(dep); return true; } @@ -162,21 +225,21 @@ class CommonJsExportsParserPlugin { expr.right ); const dep = new CommonJsExportsDependency( - expr.left.range, + /** @type {Range} */ (expr.left.range), null, base, remainingMembers ); - dep.loc = expr.loc; + dep.loc = /** @type {DependencyLocation} */ (expr.loc); parser.state.module.addDependency(dep); parser.walkExpression(expr.right); return true; }; parser.hooks.assignMemberChain .for("exports") - .tap("CommonJsExportsParserPlugin", (expr, members) => { - return handleAssignExport(expr, "exports", members); - }); + .tap("CommonJsExportsParserPlugin", (expr, members) => + handleAssignExport(expr, "exports", members) + ); parser.hooks.assignMemberChain .for("this") .tap("CommonJsExportsParserPlugin", (expr, members) => { @@ -192,14 +255,14 @@ class CommonJsExportsParserPlugin { parser.hooks.call .for("Object.defineProperty") .tap("CommonJsExportsParserPlugin", expression => { - const expr = /** @type {import("estree").CallExpression} */ (expression); + const expr = /** @type {CallExpression} */ (expression); if (!parser.isStatementLevelExpression(expr)) return; if (expr.arguments.length !== 3) return; if (expr.arguments[0].type === "SpreadElement") return; if (expr.arguments[1].type === "SpreadElement") return; if (expr.arguments[2].type === "SpreadElement") return; const exportsArg = parser.evaluateExpression(expr.arguments[0]); - if (!exportsArg || !exportsArg.isIdentifier()) return; + if (!exportsArg.isIdentifier()) return; if ( exportsArg.identifier !== "exports" && exportsArg.identifier !== "module.exports" && @@ -208,7 +271,6 @@ class CommonJsExportsParserPlugin { return; } const propertyArg = parser.evaluateExpression(expr.arguments[1]); - if (!propertyArg) return; const property = propertyArg.asString(); if (typeof property !== "string") return; enableStructuredExports(); @@ -219,12 +281,12 @@ class CommonJsExportsParserPlugin { getValueOfPropertyDescription(descArg) ); const dep = new CommonJsExportsDependency( - expr.range, - expr.arguments[2].range, + /** @type {Range} */ (expr.range), + /** @type {Range} */ (expr.arguments[2].range), `Object.defineProperty(${exportsArg.identifier})`, [property] ); - dep.loc = expr.loc; + dep.loc = /** @type {DependencyLocation} */ (expr.loc); parser.state.module.addDependency(dep); parser.walkExpression(expr.arguments[2]); @@ -232,27 +294,39 @@ class CommonJsExportsParserPlugin { }); // Self reference // - const handleAccessExport = (expr, base, members, call = undefined) => { + + /** + * @param {Expression | Super} expr expression + * @param {CommonJSDependencyBaseKeywords} base commonjs base keywords + * @param {string[]} members members of the export + * @param {CallExpression=} call call expression + * @returns {boolean | void} true, when the expression was handled + */ + const handleAccessExport = (expr, base, members, call) => { if (HarmonyExports.isEnabled(parser.state)) return; if (members.length === 0) { - bailout(`${base} is used directly at ${formatLocation(expr.loc)}`); + bailout( + `${base} is used directly at ${formatLocation( + /** @type {DependencyLocation} */ (expr.loc) + )}` + ); } if (call && members.length === 1) { bailoutHint( `${base}${propertyAccess( members )}(...) prevents optimization as ${base} is passed as call context at ${formatLocation( - expr.loc + /** @type {DependencyLocation} */ (expr.loc) )}` ); } const dep = new CommonJsSelfReferenceDependency( - expr.range, + /** @type {Range} */ (expr.range), base, members, - !!call + Boolean(call) ); - dep.loc = expr.loc; + dep.loc = /** @type {DependencyLocation} */ (expr.loc); parser.state.module.addDependency(dep); if (call) { parser.walkExpressions(call.arguments); @@ -261,19 +335,19 @@ class CommonJsExportsParserPlugin { }; parser.hooks.callMemberChain .for("exports") - .tap("CommonJsExportsParserPlugin", (expr, members) => { - return handleAccessExport(expr.callee, "exports", members, expr); - }); + .tap("CommonJsExportsParserPlugin", (expr, members) => + handleAccessExport(expr.callee, "exports", members, expr) + ); parser.hooks.expressionMemberChain .for("exports") - .tap("CommonJsExportsParserPlugin", (expr, members) => { - return handleAccessExport(expr, "exports", members); - }); + .tap("CommonJsExportsParserPlugin", (expr, members) => + handleAccessExport(expr, "exports", members) + ); parser.hooks.expression .for("exports") - .tap("CommonJsExportsParserPlugin", expr => { - return handleAccessExport(expr, "exports", []); - }); + .tap("CommonJsExportsParserPlugin", expr => + handleAccessExport(expr, "exports", []) + ); parser.hooks.callMemberChain .for("module") .tap("CommonJsExportsParserPlugin", (expr, members) => { @@ -293,9 +367,9 @@ class CommonJsExportsParserPlugin { }); parser.hooks.expression .for("module.exports") - .tap("CommonJsExportsParserPlugin", expr => { - return handleAccessExport(expr, "module.exports", []); - }); + .tap("CommonJsExportsParserPlugin", expr => + handleAccessExport(expr, "module.exports", []) + ); parser.hooks.callMemberChain .for("this") .tap("CommonJsExportsParserPlugin", (expr, members) => { @@ -325,7 +399,7 @@ class CommonJsExportsParserPlugin { : RuntimeGlobals.nodeModuleDecorator, !isHarmony ); - dep.loc = expr.loc; + dep.loc = /** @type {DependencyLocation} */ (expr.loc); parser.state.module.addDependency(dep); return true; }); diff --git a/lib/dependencies/CommonJsFullRequireDependency.js b/lib/dependencies/CommonJsFullRequireDependency.js index 4c5e71d9384..1164eee150e 100644 --- a/lib/dependencies/CommonJsFullRequireDependency.js +++ b/lib/dependencies/CommonJsFullRequireDependency.js @@ -7,6 +7,7 @@ const Template = require("../Template"); const { equals } = require("../util/ArrayHelpers"); +const { getTrimmedIdsAndRange } = require("../util/chainedImports"); const makeSerializable = require("../util/makeSerializable"); const propertyAccess = require("../util/propertyAccess"); const ModuleDependency = require("./ModuleDependency"); @@ -16,18 +17,28 @@ const ModuleDependency = require("./ModuleDependency"); /** @typedef {import("../Dependency").ReferencedExport} ReferencedExport */ /** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */ /** @typedef {import("../ModuleGraph")} ModuleGraph */ +/** @typedef {import("../javascript/JavascriptParser").Range} Range */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */ /** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */ class CommonJsFullRequireDependency extends ModuleDependency { /** * @param {string} request the request string - * @param {[number, number]} range location in source code + * @param {Range} range location in source code * @param {string[]} names accessed properties on module + * @param {Range[]=} idRanges ranges for members of ids; the two arrays are right-aligned */ - constructor(request, range, names) { + constructor( + request, + range, + names, + idRanges /* TODO webpack 6 make this non-optional. It must always be set to properly trim ids. */ + ) { super(request); this.range = range; this.names = names; + this.idRanges = idRanges; this.call = false; this.asiSafe = undefined; } @@ -51,17 +62,25 @@ class CommonJsFullRequireDependency extends ModuleDependency { return [this.names]; } + /** + * @param {ObjectSerializerContext} context context + */ serialize(context) { const { write } = context; write(this.names); + write(this.idRanges); write(this.call); write(this.asiSafe); super.serialize(context); } + /** + * @param {ObjectDeserializerContext} context context + */ deserialize(context) { const { read } = context; this.names = read(); + this.idRanges = read(); this.call = read(); this.asiSafe = read(); super.deserialize(context); @@ -108,17 +127,34 @@ CommonJsFullRequireDependency.Template = class CommonJsFullRequireDependencyTemp weak: dep.weak, runtimeRequirements }); - const ids = dep.names; - const usedImported = moduleGraph - .getExportsInfo(importedModule) - .getUsedName(ids, runtime); - if (usedImported) { - const comment = equals(usedImported, ids) - ? "" - : Template.toNormalComment(propertyAccess(ids)) + " "; - requireExpr += `${comment}${propertyAccess(usedImported)}`; + + const { + trimmedRange: [trimmedRangeStart, trimmedRangeEnd], + trimmedIds + } = getTrimmedIdsAndRange( + dep.names, + dep.range, + dep.idRanges, + moduleGraph, + dep + ); + + if (importedModule) { + const usedImported = moduleGraph + .getExportsInfo(importedModule) + .getUsedName(trimmedIds, runtime); + if (usedImported) { + const comment = equals(usedImported, trimmedIds) + ? "" + : `${Template.toNormalComment(propertyAccess(trimmedIds))} `; + const access = `${comment}${propertyAccess(usedImported)}`; + requireExpr = + dep.asiSafe === true + ? `(${requireExpr}${access})` + : `${requireExpr}${access}`; + } } - source.replace(dep.range[0], dep.range[1] - 1, requireExpr); + source.replace(trimmedRangeStart, trimmedRangeEnd - 1, requireExpr); } }; diff --git a/lib/dependencies/CommonJsImportsParserPlugin.js b/lib/dependencies/CommonJsImportsParserPlugin.js index d23cc3e5591..5044bcedf45 100644 --- a/lib/dependencies/CommonJsImportsParserPlugin.js +++ b/lib/dependencies/CommonJsImportsParserPlugin.js @@ -5,9 +5,12 @@ "use strict"; +const { fileURLToPath } = require("url"); const CommentCompilationWarning = require("../CommentCompilationWarning"); const RuntimeGlobals = require("../RuntimeGlobals"); const UnsupportedFeatureWarning = require("../UnsupportedFeatureWarning"); +const WebpackError = require("../WebpackError"); +const BasicEvaluatedExpression = require("../javascript/BasicEvaluatedExpression"); const { evaluateToIdentifier, evaluateToString, @@ -26,7 +29,17 @@ const RequireResolveContextDependency = require("./RequireResolveContextDependen const RequireResolveDependency = require("./RequireResolveDependency"); const RequireResolveHeaderDependency = require("./RequireResolveHeaderDependency"); +/** @typedef {import("estree").CallExpression} CallExpression */ +/** @typedef {import("estree").Expression} Expression */ +/** @typedef {import("estree").NewExpression} NewExpression */ /** @typedef {import("../../declarations/WebpackOptions").JavascriptParserOptions} JavascriptParserOptions */ +/** @typedef {import("../Dependency").DependencyLocation} DependencyLocation */ +/** @typedef {import("../javascript/JavascriptParser")} JavascriptParser */ +/** @typedef {import("../javascript/JavascriptParser").ImportSource} ImportSource */ +/** @typedef {import("../javascript/JavascriptParser").Range} Range */ + +const createRequireSpecifierTag = Symbol("createRequire"); +const createdRequireIdentifierTag = Symbol("createRequire()"); class CommonJsImportsParserPlugin { /** @@ -36,54 +49,86 @@ class CommonJsImportsParserPlugin { this.options = options; } + /** + * @param {JavascriptParser} parser the parser + * @returns {void} + */ apply(parser) { const options = this.options; - // metadata // + const getContext = () => { + if (parser.currentTagData) { + const { context } = parser.currentTagData; + return context; + } + }; + + // #region metadata + /** + * @param {string} expression expression + * @param {() => string[]} getMembers get members + */ const tapRequireExpression = (expression, getMembers) => { parser.hooks.typeof .for(expression) .tap( - "CommonJsPlugin", + "CommonJsImportsParserPlugin", toConstantDependency(parser, JSON.stringify("function")) ); parser.hooks.evaluateTypeof .for(expression) - .tap("CommonJsPlugin", evaluateToString("function")); + .tap("CommonJsImportsParserPlugin", evaluateToString("function")); parser.hooks.evaluateIdentifier .for(expression) .tap( - "CommonJsPlugin", + "CommonJsImportsParserPlugin", evaluateToIdentifier(expression, "require", getMembers, true) ); }; + /** + * @param {string | symbol} tag tag + */ + const tapRequireExpressionTag = tag => { + parser.hooks.typeof + .for(tag) + .tap( + "CommonJsImportsParserPlugin", + toConstantDependency(parser, JSON.stringify("function")) + ); + parser.hooks.evaluateTypeof + .for(tag) + .tap("CommonJsImportsParserPlugin", evaluateToString("function")); + }; tapRequireExpression("require", () => []); tapRequireExpression("require.resolve", () => ["resolve"]); tapRequireExpression("require.resolveWeak", () => ["resolveWeak"]); + // #endregion // Weird stuff // - parser.hooks.assign.for("require").tap("CommonJsPlugin", expr => { - // to not leak to global "require", we need to define a local require here. - const dep = new ConstDependency("var require;", 0); - dep.loc = expr.loc; - parser.state.module.addPresentationalDependency(dep); - return true; - }); + parser.hooks.assign + .for("require") + .tap("CommonJsImportsParserPlugin", expr => { + // to not leak to global "require", we need to define a local require here. + const dep = new ConstDependency("var require;", 0); + dep.loc = /** @type {DependencyLocation} */ (expr.loc); + parser.state.module.addPresentationalDependency(dep); + return true; + }); - // Unsupported // + // #region Unsupported parser.hooks.expression - .for("require.main.require") + .for("require.main") .tap( - "CommonJsPlugin", + "CommonJsImportsParserPlugin", expressionIsUnsupported( parser, - "require.main.require is not supported by webpack." + "require.main is not supported by webpack." ) ); parser.hooks.call .for("require.main.require") .tap( - "CommonJsPlugin", + "CommonJsImportsParserPlugin", expressionIsUnsupported( parser, "require.main.require is not supported by webpack." @@ -92,7 +137,7 @@ class CommonJsImportsParserPlugin { parser.hooks.expression .for("module.parent.require") .tap( - "CommonJsPlugin", + "CommonJsImportsParserPlugin", expressionIsUnsupported( parser, "module.parent.require is not supported by webpack." @@ -101,91 +146,136 @@ class CommonJsImportsParserPlugin { parser.hooks.call .for("module.parent.require") .tap( - "CommonJsPlugin", + "CommonJsImportsParserPlugin", expressionIsUnsupported( parser, "module.parent.require is not supported by webpack." ) ); + // #endregion - // renaming // - parser.hooks.canRename.for("require").tap("CommonJsPlugin", () => true); - parser.hooks.rename.for("require").tap("CommonJsPlugin", expr => { + // #region Renaming + /** + * @param {Expression} expr expression + * @returns {boolean} true when set undefined + */ + const defineUndefined = expr => { // To avoid "not defined" error, replace the value with undefined - const dep = new ConstDependency("undefined", expr.range); - dep.loc = expr.loc; + const dep = new ConstDependency( + "undefined", + /** @type {Range} */ (expr.range) + ); + dep.loc = /** @type {DependencyLocation} */ (expr.loc); parser.state.module.addPresentationalDependency(dep); return false; - }); + }; + parser.hooks.canRename + .for("require") + .tap("CommonJsImportsParserPlugin", () => true); + parser.hooks.rename + .for("require") + .tap("CommonJsImportsParserPlugin", defineUndefined); + // #endregion + + // #region Inspection + const requireCache = toConstantDependency( + parser, + RuntimeGlobals.moduleCache, + [ + RuntimeGlobals.moduleCache, + RuntimeGlobals.moduleId, + RuntimeGlobals.moduleLoaded + ] + ); - // inspection // parser.hooks.expression .for("require.cache") - .tap( - "CommonJsImportsParserPlugin", - toConstantDependency(parser, RuntimeGlobals.moduleCache, [ - RuntimeGlobals.moduleCache, - RuntimeGlobals.moduleId, - RuntimeGlobals.moduleLoaded - ]) - ); + .tap("CommonJsImportsParserPlugin", requireCache); + // #endregion - // require as expression // + // #region Require as expression + /** + * @param {Expression} expr expression + * @returns {boolean} true when handled + */ + const requireAsExpressionHandler = expr => { + const dep = new CommonJsRequireContextDependency( + { + request: options.unknownContextRequest, + recursive: options.unknownContextRecursive, + regExp: options.unknownContextRegExp, + mode: "sync" + }, + /** @type {Range} */ (expr.range), + undefined, + parser.scope.inShorthand, + getContext() + ); + dep.critical = + options.unknownContextCritical && + "require function is used in a way in which dependencies cannot be statically extracted"; + dep.loc = /** @type {DependencyLocation} */ (expr.loc); + dep.optional = Boolean(parser.scope.inTry); + parser.state.current.addDependency(dep); + return true; + }; parser.hooks.expression .for("require") - .tap("CommonJsImportsParserPlugin", expr => { - const dep = new CommonJsRequireContextDependency( - { - request: options.unknownContextRequest, - recursive: options.unknownContextRecursive, - regExp: options.unknownContextRegExp, - mode: "sync" - }, - expr.range - ); - dep.critical = - options.unknownContextCritical && - "require function is used in a way in which dependencies cannot be statically extracted"; - dep.loc = expr.loc; - dep.optional = !!parser.scope.inTry; - parser.state.current.addDependency(dep); - return true; - }); + .tap("CommonJsImportsParserPlugin", requireAsExpressionHandler); + // #endregion - // require // + // #region Require + /** + * @param {CallExpression | NewExpression} expr expression + * @param {BasicEvaluatedExpression} param param + * @returns {boolean | void} true when handled + */ const processRequireItem = (expr, param) => { if (param.isString()) { - const dep = new CommonJsRequireDependency(param.string, param.range); - dep.loc = expr.loc; - dep.optional = !!parser.scope.inTry; + const dep = new CommonJsRequireDependency( + /** @type {string} */ (param.string), + /** @type {Range} */ (param.range), + getContext() + ); + dep.loc = /** @type {DependencyLocation} */ (expr.loc); + dep.optional = Boolean(parser.scope.inTry); parser.state.current.addDependency(dep); return true; } }; + /** + * @param {CallExpression | NewExpression} expr expression + * @param {BasicEvaluatedExpression} param param + * @returns {boolean | void} true when handled + */ const processRequireContext = (expr, param) => { const dep = ContextDependencyHelpers.create( CommonJsRequireContextDependency, - expr.range, + /** @type {Range} */ (expr.range), param, expr, options, { category: "commonjs" }, - parser + parser, + undefined, + getContext() ); if (!dep) return; - dep.loc = expr.loc; - dep.optional = !!parser.scope.inTry; + dep.loc = /** @type {DependencyLocation} */ (expr.loc); + dep.optional = Boolean(parser.scope.inTry); parser.state.current.addDependency(dep); return true; }; + /** + * @param {boolean} callNew true, when require is called with new + * @returns {(expr: CallExpression | NewExpression) => (boolean | void)} handler + */ const createRequireHandler = callNew => expr => { if (options.commonjsMagicComments) { - const { - options: requireOptions, - errors: commentErrors - } = parser.parseCommentOptions(expr.range); + const { options: requireOptions, errors: commentErrors } = + parser.parseCommentOptions(/** @type {Range} */ (expr.range)); if (commentErrors) { for (const e of commentErrors) { @@ -198,21 +288,17 @@ class CommonJsImportsParserPlugin { ); } } - if (requireOptions) { - if (requireOptions.webpackIgnore !== undefined) { - if (typeof requireOptions.webpackIgnore !== "boolean") { - parser.state.module.addWarning( - new UnsupportedFeatureWarning( - `\`webpackIgnore\` expected a boolean, but received: ${requireOptions.webpackIgnore}.`, - expr.loc - ) - ); - } else { - // Do not instrument `require()` if `webpackIgnore` is `true` - if (requireOptions.webpackIgnore) { - return true; - } - } + if (requireOptions && requireOptions.webpackIgnore !== undefined) { + if (typeof requireOptions.webpackIgnore !== "boolean") { + parser.state.module.addWarning( + new UnsupportedFeatureWarning( + `\`webpackIgnore\` expected a boolean, but received: ${requireOptions.webpackIgnore}.`, + /** @type {DependencyLocation} */ (expr.loc) + ) + ); + } else if (requireOptions.webpackIgnore) { + // Do not instrument `require()` if `webpackIgnore` is `true` + return true; } } } @@ -222,39 +308,51 @@ class CommonJsImportsParserPlugin { const param = parser.evaluateExpression(expr.arguments[0]); if (param.isConditional()) { let isExpression = false; - for (const p of param.options) { + for (const p of /** @type {BasicEvaluatedExpression[]} */ ( + param.options + )) { const result = processRequireItem(expr, p); if (result === undefined) { isExpression = true; } } if (!isExpression) { - const dep = new RequireHeaderDependency(expr.callee.range); - dep.loc = expr.loc; + const dep = new RequireHeaderDependency( + /** @type {Range} */ (expr.callee.range) + ); + dep.loc = /** @type {DependencyLocation} */ (expr.loc); parser.state.module.addPresentationalDependency(dep); return true; } } if ( param.isString() && - (localModule = getLocalModule(parser.state, param.string)) + (localModule = getLocalModule( + parser.state, + /** @type {string} */ (param.string) + )) ) { localModule.flagUsed(); - const dep = new LocalModuleDependency(localModule, expr.range, callNew); - dep.loc = expr.loc; + const dep = new LocalModuleDependency( + localModule, + /** @type {Range} */ (expr.range), + callNew + ); + dep.loc = /** @type {DependencyLocation} */ (expr.loc); parser.state.module.addPresentationalDependency(dep); - return true; } else { const result = processRequireItem(expr, param); if (result === undefined) { processRequireContext(expr, param); } else { - const dep = new RequireHeaderDependency(expr.callee.range); - dep.loc = expr.loc; + const dep = new RequireHeaderDependency( + /** @type {Range} */ (expr.callee.range) + ); + dep.loc = /** @type {DependencyLocation} */ (expr.loc); parser.state.module.addPresentationalDependency(dep); } - return true; } + return true; }; parser.hooks.call .for("require") @@ -268,38 +366,79 @@ class CommonJsImportsParserPlugin { parser.hooks.new .for("module.require") .tap("CommonJsImportsParserPlugin", createRequireHandler(true)); + // #endregion - // require with property access // - const chainHandler = (expr, calleeMembers, callExpr, members) => { + // #region Require with property access + /** + * @param {Expression} expr expression + * @param {string[]} calleeMembers callee members + * @param {CallExpression} callExpr call expression + * @param {string[]} members members + * @param {Range[]} memberRanges member ranges + * @returns {boolean | void} true when handled + */ + const chainHandler = ( + expr, + calleeMembers, + callExpr, + members, + memberRanges + ) => { if (callExpr.arguments.length !== 1) return; const param = parser.evaluateExpression(callExpr.arguments[0]); - if (param.isString() && !getLocalModule(parser.state, param.string)) { + if ( + param.isString() && + !getLocalModule(parser.state, /** @type {string} */ (param.string)) + ) { const dep = new CommonJsFullRequireDependency( - param.string, - expr.range, - members + /** @type {string} */ (param.string), + /** @type {Range} */ (expr.range), + members, + /** @type {Range[]} */ memberRanges + ); + dep.asiSafe = !parser.isAsiPosition( + /** @type {Range} */ (expr.range)[0] ); - dep.asiSafe = !parser.isAsiPosition(expr.range[0]); - dep.optional = !!parser.scope.inTry; - dep.loc = expr.loc; - parser.state.module.addDependency(dep); + dep.optional = Boolean(parser.scope.inTry); + dep.loc = /** @type {DependencyLocation} */ (expr.loc); + parser.state.current.addDependency(dep); return true; } }; - const callChainHandler = (expr, calleeMembers, callExpr, members) => { + /** + * @param {CallExpression} expr expression + * @param {string[]} calleeMembers callee members + * @param {CallExpression} callExpr call expression + * @param {string[]} members members + * @param {Range[]} memberRanges member ranges + * @returns {boolean | void} true when handled + */ + const callChainHandler = ( + expr, + calleeMembers, + callExpr, + members, + memberRanges + ) => { if (callExpr.arguments.length !== 1) return; const param = parser.evaluateExpression(callExpr.arguments[0]); - if (param.isString() && !getLocalModule(parser.state, param.string)) { + if ( + param.isString() && + !getLocalModule(parser.state, /** @type {string} */ (param.string)) + ) { const dep = new CommonJsFullRequireDependency( - param.string, - expr.callee.range, - members + /** @type {string} */ (param.string), + /** @type {Range} */ (expr.callee.range), + members, + /** @type {Range[]} */ memberRanges ); dep.call = true; - dep.asiSafe = !parser.isAsiPosition(expr.range[0]); - dep.optional = !!parser.scope.inTry; - dep.loc = expr.callee.loc; - parser.state.module.addDependency(dep); + dep.asiSafe = !parser.isAsiPosition( + /** @type {Range} */ (expr.range)[0] + ); + dep.optional = Boolean(parser.scope.inTry); + dep.loc = /** @type {DependencyLocation} */ (expr.callee.loc); + parser.state.current.addDependency(dep); parser.walkExpressions(expr.arguments); return true; } @@ -316,47 +455,74 @@ class CommonJsImportsParserPlugin { parser.hooks.callMemberChainOfCallMemberChain .for("module.require") .tap("CommonJsImportsParserPlugin", callChainHandler); + // #endregion - // require.resolve // + // #region Require.resolve + /** + * @param {CallExpression} expr call expression + * @param {boolean} weak weak + * @returns {boolean | void} true when handled + */ const processResolve = (expr, weak) => { if (expr.arguments.length !== 1) return; const param = parser.evaluateExpression(expr.arguments[0]); if (param.isConditional()) { - for (const option of param.options) { + for (const option of /** @type {BasicEvaluatedExpression[]} */ ( + param.options + )) { const result = processResolveItem(expr, option, weak); if (result === undefined) { processResolveContext(expr, option, weak); } } - const dep = new RequireResolveHeaderDependency(expr.callee.range); - dep.loc = expr.loc; - parser.state.module.addPresentationalDependency(dep); - return true; - } else { - const result = processResolveItem(expr, param, weak); - if (result === undefined) { - processResolveContext(expr, param, weak); - } - const dep = new RequireResolveHeaderDependency(expr.callee.range); - dep.loc = expr.loc; + const dep = new RequireResolveHeaderDependency( + /** @type {Range} */ (expr.callee.range) + ); + dep.loc = /** @type {DependencyLocation} */ (expr.loc); parser.state.module.addPresentationalDependency(dep); return true; } + const result = processResolveItem(expr, param, weak); + if (result === undefined) { + processResolveContext(expr, param, weak); + } + const dep = new RequireResolveHeaderDependency( + /** @type {Range} */ (expr.callee.range) + ); + dep.loc = /** @type {DependencyLocation} */ (expr.loc); + parser.state.module.addPresentationalDependency(dep); + return true; }; + /** + * @param {CallExpression} expr call expression + * @param {BasicEvaluatedExpression} param param + * @param {boolean} weak weak + * @returns {boolean | void} true when handled + */ const processResolveItem = (expr, param, weak) => { if (param.isString()) { - const dep = new RequireResolveDependency(param.string, param.range); - dep.loc = expr.loc; - dep.optional = !!parser.scope.inTry; + const dep = new RequireResolveDependency( + /** @type {string} */ (param.string), + /** @type {Range} */ (param.range), + getContext() + ); + dep.loc = /** @type {DependencyLocation} */ (expr.loc); + dep.optional = Boolean(parser.scope.inTry); dep.weak = weak; parser.state.current.addDependency(dep); return true; } }; + /** + * @param {CallExpression} expr call expression + * @param {BasicEvaluatedExpression} param param + * @param {boolean} weak weak + * @returns {boolean | void} true when handled + */ const processResolveContext = (expr, param, weak) => { const dep = ContextDependencyHelpers.create( RequireResolveContextDependency, - param.range, + /** @type {Range} */ (param.range), param, expr, options, @@ -364,25 +530,257 @@ class CommonJsImportsParserPlugin { category: "commonjs", mode: weak ? "weak" : "sync" }, - parser + parser, + getContext() ); if (!dep) return; - dep.loc = expr.loc; - dep.optional = !!parser.scope.inTry; + dep.loc = /** @type {DependencyLocation} */ (expr.loc); + dep.optional = Boolean(parser.scope.inTry); parser.state.current.addDependency(dep); return true; }; parser.hooks.call .for("require.resolve") - .tap("RequireResolveDependencyParserPlugin", expr => { - return processResolve(expr, false); - }); + .tap("CommonJsImportsParserPlugin", expr => processResolve(expr, false)); parser.hooks.call .for("require.resolveWeak") - .tap("RequireResolveDependencyParserPlugin", expr => { - return processResolve(expr, true); + .tap("CommonJsImportsParserPlugin", expr => processResolve(expr, true)); + // #endregion + + // #region Create require + + if (!options.createRequire) return; + + /** @type {ImportSource[]} */ + let moduleName = []; + /** @type {string | undefined} */ + let specifierName; + + if (options.createRequire === true) { + moduleName = ["module", "node:module"]; + specifierName = "createRequire"; + } else { + let moduleName; + const match = /^(.*) from (.*)$/.exec(options.createRequire); + if (match) { + [, specifierName, moduleName] = match; + } + if (!specifierName || !moduleName) { + const err = new WebpackError( + `Parsing javascript parser option "createRequire" failed, got ${JSON.stringify( + options.createRequire + )}` + ); + err.details = + 'Expected string in format "createRequire from module", where "createRequire" is specifier name and "module" name of the module'; + throw err; + } + } + + tapRequireExpressionTag(createdRequireIdentifierTag); + tapRequireExpressionTag(createRequireSpecifierTag); + parser.hooks.evaluateCallExpression + .for(createRequireSpecifierTag) + .tap("CommonJsImportsParserPlugin", expr => { + const context = parseCreateRequireArguments(expr); + if (context === undefined) return; + const ident = parser.evaluatedVariable({ + tag: createdRequireIdentifierTag, + data: { context }, + next: undefined + }); + return new BasicEvaluatedExpression() + .setIdentifier( + /** @type {TODO} */ (ident), + /** @type {TODO} */ (ident), + () => [] + ) + .setSideEffects(false) + .setRange(/** @type {Range} */ (expr.range)); + }); + parser.hooks.unhandledExpressionMemberChain + .for(createdRequireIdentifierTag) + .tap("CommonJsImportsParserPlugin", (expr, members) => + expressionIsUnsupported( + parser, + `createRequire().${members.join(".")} is not supported by webpack.` + )(expr) + ); + parser.hooks.canRename + .for(createdRequireIdentifierTag) + .tap("CommonJsImportsParserPlugin", () => true); + parser.hooks.canRename + .for(createRequireSpecifierTag) + .tap("CommonJsImportsParserPlugin", () => true); + parser.hooks.rename + .for(createRequireSpecifierTag) + .tap("CommonJsImportsParserPlugin", defineUndefined); + parser.hooks.expression + .for(createdRequireIdentifierTag) + .tap("CommonJsImportsParserPlugin", requireAsExpressionHandler); + parser.hooks.call + .for(createdRequireIdentifierTag) + .tap("CommonJsImportsParserPlugin", createRequireHandler(false)); + /** + * @param {CallExpression} expr call expression + * @returns {string | void} context + */ + const parseCreateRequireArguments = expr => { + const args = expr.arguments; + if (args.length !== 1) { + const err = new WebpackError( + "module.createRequire supports only one argument." + ); + err.loc = /** @type {DependencyLocation} */ (expr.loc); + parser.state.module.addWarning(err); + return; + } + const arg = args[0]; + const evaluated = parser.evaluateExpression(arg); + if (!evaluated.isString()) { + const err = new WebpackError( + "module.createRequire failed parsing argument." + ); + err.loc = /** @type {DependencyLocation} */ (arg.loc); + parser.state.module.addWarning(err); + return; + } + const ctx = /** @type {string} */ (evaluated.string).startsWith("file://") + ? fileURLToPath(/** @type {string} */ (evaluated.string)) + : /** @type {string} */ (evaluated.string); + // argument always should be a filename + return ctx.slice(0, ctx.lastIndexOf(ctx.startsWith("/") ? "/" : "\\")); + }; + + parser.hooks.import.tap( + { + name: "CommonJsImportsParserPlugin", + stage: -10 + }, + (statement, source) => { + if ( + !moduleName.includes(source) || + statement.specifiers.length !== 1 || + statement.specifiers[0].type !== "ImportSpecifier" || + statement.specifiers[0].imported.type !== "Identifier" || + statement.specifiers[0].imported.name !== specifierName + ) + return; + // clear for 'import { createRequire as x } from "module"' + // if any other specifier was used import module + const clearDep = new ConstDependency( + parser.isAsiPosition(/** @type {Range} */ (statement.range)[0]) + ? ";" + : "", + /** @type {Range} */ (statement.range) + ); + clearDep.loc = /** @type {DependencyLocation} */ (statement.loc); + parser.state.module.addPresentationalDependency(clearDep); + parser.unsetAsiPosition(/** @type {Range} */ (statement.range)[1]); + return true; + } + ); + parser.hooks.importSpecifier.tap( + { + name: "CommonJsImportsParserPlugin", + stage: -10 + }, + (statement, source, id, name) => { + if (!moduleName.includes(source) || id !== specifierName) return; + parser.tagVariable(name, createRequireSpecifierTag); + return true; + } + ); + parser.hooks.preDeclarator.tap( + "CommonJsImportsParserPlugin", + declarator => { + if ( + declarator.id.type !== "Identifier" || + !declarator.init || + declarator.init.type !== "CallExpression" || + declarator.init.callee.type !== "Identifier" + ) + return; + const variableInfo = + /** @type {TODO} */ + (parser.getVariableInfo(declarator.init.callee.name)); + if ( + variableInfo && + variableInfo.tagInfo && + variableInfo.tagInfo.tag === createRequireSpecifierTag + ) { + const context = parseCreateRequireArguments(declarator.init); + if (context === undefined) return; + parser.tagVariable(declarator.id.name, createdRequireIdentifierTag, { + name: declarator.id.name, + context + }); + return true; + } + } + ); + + parser.hooks.memberChainOfCallMemberChain + .for(createRequireSpecifierTag) + .tap( + "CommonJsImportsParserPlugin", + (expr, calleeMembers, callExpr, members) => { + if ( + calleeMembers.length !== 0 || + members.length !== 1 || + members[0] !== "cache" + ) + return; + // createRequire().cache + const context = parseCreateRequireArguments(callExpr); + if (context === undefined) return; + return requireCache(expr); + } + ); + parser.hooks.callMemberChainOfCallMemberChain + .for(createRequireSpecifierTag) + .tap( + "CommonJsImportsParserPlugin", + (expr, calleeMembers, innerCallExpression, members) => { + if ( + calleeMembers.length !== 0 || + members.length !== 1 || + members[0] !== "resolve" + ) + return; + // createRequire().resolve() + return processResolve(expr, false); + } + ); + parser.hooks.expressionMemberChain + .for(createdRequireIdentifierTag) + .tap("CommonJsImportsParserPlugin", (expr, members) => { + // require.cache + if (members.length === 1 && members[0] === "cache") { + return requireCache(expr); + } + }); + parser.hooks.callMemberChain + .for(createdRequireIdentifierTag) + .tap("CommonJsImportsParserPlugin", (expr, members) => { + // require.resolve() + if (members.length === 1 && members[0] === "resolve") { + return processResolve(expr, false); + } + }); + parser.hooks.call + .for(createRequireSpecifierTag) + .tap("CommonJsImportsParserPlugin", expr => { + const clearDep = new ConstDependency( + "/* createRequire() */ undefined", + /** @type {Range} */ (expr.range) + ); + clearDep.loc = /** @type {DependencyLocation} */ (expr.loc); + parser.state.module.addPresentationalDependency(clearDep); + return true; }); + // #endregion } } module.exports = CommonJsImportsParserPlugin; diff --git a/lib/dependencies/CommonJsPlugin.js b/lib/dependencies/CommonJsPlugin.js index 6d5c3e89c1a..b148b17b0b9 100644 --- a/lib/dependencies/CommonJsPlugin.js +++ b/lib/dependencies/CommonJsPlugin.js @@ -24,16 +24,34 @@ const RuntimeRequirementsDependency = require("./RuntimeRequirementsDependency") const CommonJsExportsParserPlugin = require("./CommonJsExportsParserPlugin"); const CommonJsImportsParserPlugin = require("./CommonJsImportsParserPlugin"); +const { + JAVASCRIPT_MODULE_TYPE_AUTO, + JAVASCRIPT_MODULE_TYPE_DYNAMIC +} = require("../ModuleTypeConstants"); const { evaluateToIdentifier, toConstantDependency } = require("../javascript/JavascriptParserHelpers"); const CommonJsExportRequireDependency = require("./CommonJsExportRequireDependency"); +/** @typedef {import("../../declarations/WebpackOptions").JavascriptParserOptions} JavascriptParserOptions */ +/** @typedef {import("../Compilation")} Compilation */ +/** @typedef {import("../Compiler")} Compiler */ +/** @typedef {import("../Dependency").DependencyLocation} DependencyLocation */ +/** @typedef {import("../Module").BuildInfo} BuildInfo */ +/** @typedef {import("../javascript/JavascriptParser")} Parser */ + +const PLUGIN_NAME = "CommonJsPlugin"; + class CommonJsPlugin { + /** + * Apply the plugin + * @param {Compiler} compiler the compiler instance + * @returns {void} + */ apply(compiler) { compiler.hooks.compilation.tap( - "CommonJsPlugin", + PLUGIN_NAME, (compilation, { contextModuleFactory, normalModuleFactory }) => { compilation.dependencyFactories.set( CommonJsRequireDependency, @@ -126,21 +144,21 @@ class CommonJsPlugin { compilation.hooks.runtimeRequirementInModule .for(RuntimeGlobals.harmonyModuleDecorator) - .tap("CommonJsPlugin", (module, set) => { + .tap(PLUGIN_NAME, (module, set) => { set.add(RuntimeGlobals.module); set.add(RuntimeGlobals.requireScope); }); compilation.hooks.runtimeRequirementInModule .for(RuntimeGlobals.nodeModuleDecorator) - .tap("CommonJsPlugin", (module, set) => { + .tap(PLUGIN_NAME, (module, set) => { set.add(RuntimeGlobals.module); set.add(RuntimeGlobals.requireScope); }); compilation.hooks.runtimeRequirementInTree .for(RuntimeGlobals.harmonyModuleDecorator) - .tap("CommonJsPlugin", (chunk, set) => { + .tap(PLUGIN_NAME, (chunk, set) => { compilation.addRuntimeModule( chunk, new HarmonyModuleDecoratorRuntimeModule() @@ -149,27 +167,32 @@ class CommonJsPlugin { compilation.hooks.runtimeRequirementInTree .for(RuntimeGlobals.nodeModuleDecorator) - .tap("CommonJsPlugin", (chunk, set) => { + .tap(PLUGIN_NAME, (chunk, set) => { compilation.addRuntimeModule( chunk, new NodeModuleDecoratorRuntimeModule() ); }); + /** + * @param {Parser} parser parser parser + * @param {JavascriptParserOptions} parserOptions parserOptions + * @returns {void} + */ const handler = (parser, parserOptions) => { if (parserOptions.commonjs !== undefined && !parserOptions.commonjs) return; parser.hooks.typeof .for("module") .tap( - "CommonJsPlugin", + PLUGIN_NAME, toConstantDependency(parser, JSON.stringify("object")) ); parser.hooks.expression .for("require.main") .tap( - "CommonJsPlugin", + PLUGIN_NAME, toConstantDependency( parser, `${RuntimeGlobals.moduleCache}[${RuntimeGlobals.entryModuleId}]`, @@ -177,33 +200,35 @@ class CommonJsPlugin { ) ); parser.hooks.expression - .for("module.loaded") - .tap("CommonJsPlugin", expr => { - parser.state.module.buildInfo.moduleConcatenationBailout = - "module.loaded"; + .for(RuntimeGlobals.moduleLoaded) + .tap(PLUGIN_NAME, expr => { + /** @type {BuildInfo} */ + (parser.state.module.buildInfo).moduleConcatenationBailout = + RuntimeGlobals.moduleLoaded; const dep = new RuntimeRequirementsDependency([ RuntimeGlobals.moduleLoaded ]); - dep.loc = expr.loc; + dep.loc = /** @type {DependencyLocation} */ (expr.loc); parser.state.module.addPresentationalDependency(dep); return true; }); parser.hooks.expression - .for("module.id") - .tap("CommonJsPlugin", expr => { - parser.state.module.buildInfo.moduleConcatenationBailout = - "module.id"; + .for(RuntimeGlobals.moduleId) + .tap(PLUGIN_NAME, expr => { + /** @type {BuildInfo} */ + (parser.state.module.buildInfo).moduleConcatenationBailout = + RuntimeGlobals.moduleId; const dep = new RuntimeRequirementsDependency([ RuntimeGlobals.moduleId ]); - dep.loc = expr.loc; + dep.loc = /** @type {DependencyLocation} */ (expr.loc); parser.state.module.addPresentationalDependency(dep); return true; }); parser.hooks.evaluateIdentifier.for("module.hot").tap( - "CommonJsPlugin", + PLUGIN_NAME, evaluateToIdentifier("module.hot", "module", () => ["hot"], null) ); @@ -214,11 +239,11 @@ class CommonJsPlugin { }; normalModuleFactory.hooks.parser - .for("javascript/auto") - .tap("CommonJsPlugin", handler); + .for(JAVASCRIPT_MODULE_TYPE_AUTO) + .tap(PLUGIN_NAME, handler); normalModuleFactory.hooks.parser - .for("javascript/dynamic") - .tap("CommonJsPlugin", handler); + .for(JAVASCRIPT_MODULE_TYPE_DYNAMIC) + .tap(PLUGIN_NAME, handler); } ); } @@ -230,10 +255,10 @@ class HarmonyModuleDecoratorRuntimeModule extends RuntimeModule { } /** - * @returns {string} runtime code + * @returns {string | null} runtime code */ generate() { - const { runtimeTemplate } = this.compilation; + const { runtimeTemplate } = /** @type {Compilation} */ (this.compilation); return Template.asString([ `${ RuntimeGlobals.harmonyModuleDecorator @@ -260,18 +285,19 @@ class NodeModuleDecoratorRuntimeModule extends RuntimeModule { } /** - * @returns {string} runtime code + * @returns {string | null} runtime code */ generate() { - const { runtimeTemplate } = this.compilation; + const { runtimeTemplate } = /** @type {Compilation} */ (this.compilation); return Template.asString([ - `${ - RuntimeGlobals.nodeModuleDecorator - } = ${runtimeTemplate.basicFunction("module", [ - "module.paths = [];", - "if (!module.children) module.children = [];", - "return module;" - ])};` + `${RuntimeGlobals.nodeModuleDecorator} = ${runtimeTemplate.basicFunction( + "module", + [ + "module.paths = [];", + "if (!module.children) module.children = [];", + "return module;" + ] + )};` ]); } } diff --git a/lib/dependencies/CommonJsRequireContextDependency.js b/lib/dependencies/CommonJsRequireContextDependency.js index 51227afdedc..14e64285d0d 100644 --- a/lib/dependencies/CommonJsRequireContextDependency.js +++ b/lib/dependencies/CommonJsRequireContextDependency.js @@ -9,32 +9,53 @@ const makeSerializable = require("../util/makeSerializable"); const ContextDependency = require("./ContextDependency"); const ContextDependencyTemplateAsRequireCall = require("./ContextDependencyTemplateAsRequireCall"); +/** @typedef {import("../javascript/JavascriptParser").Range} Range */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */ + class CommonJsRequireContextDependency extends ContextDependency { - constructor(options, range, valueRange) { - super(options); + /** + * @param {TODO} options options for the context module + * @param {Range} range location in source code + * @param {Range | undefined} valueRange location of the require call + * @param {boolean | string } inShorthand true or name + * @param {string} context context + */ + constructor(options, range, valueRange, inShorthand, context) { + super(options, context); this.range = range; this.valueRange = valueRange; + // inShorthand must be serialized by subclasses that use it + this.inShorthand = inShorthand; } get type() { return "cjs require context"; } + /** + * @param {ObjectSerializerContext} context context + */ serialize(context) { const { write } = context; write(this.range); write(this.valueRange); + write(this.inShorthand); super.serialize(context); } + /** + * @param {ObjectDeserializerContext} context context + */ deserialize(context) { const { read } = context; this.range = read(); this.valueRange = read(); + this.inShorthand = read(); super.deserialize(context); } @@ -45,6 +66,7 @@ makeSerializable( "webpack/lib/dependencies/CommonJsRequireContextDependency" ); -CommonJsRequireContextDependency.Template = ContextDependencyTemplateAsRequireCall; +CommonJsRequireContextDependency.Template = + ContextDependencyTemplateAsRequireCall; module.exports = CommonJsRequireContextDependency; diff --git a/lib/dependencies/CommonJsRequireDependency.js b/lib/dependencies/CommonJsRequireDependency.js index 3c711ff31b7..09545a86e5e 100644 --- a/lib/dependencies/CommonJsRequireDependency.js +++ b/lib/dependencies/CommonJsRequireDependency.js @@ -9,10 +9,18 @@ const makeSerializable = require("../util/makeSerializable"); const ModuleDependency = require("./ModuleDependency"); const ModuleDependencyTemplateAsId = require("./ModuleDependencyTemplateAsId"); +/** @typedef {import("../javascript/JavascriptParser").Range} Range */ + class CommonJsRequireDependency extends ModuleDependency { - constructor(request, range) { + /** + * @param {string} request request + * @param {Range=} range location in source code + * @param {string=} context request context + */ + constructor(request, range, context) { super(request); this.range = range; + this._context = context; } get type() { diff --git a/lib/dependencies/CommonJsSelfReferenceDependency.js b/lib/dependencies/CommonJsSelfReferenceDependency.js index 1c4af4867b5..b1b368ead67 100644 --- a/lib/dependencies/CommonJsSelfReferenceDependency.js +++ b/lib/dependencies/CommonJsSelfReferenceDependency.js @@ -17,9 +17,19 @@ const NullDependency = require("./NullDependency"); /** @typedef {import("../Dependency").ReferencedExport} ReferencedExport */ /** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */ /** @typedef {import("../ModuleGraph")} ModuleGraph */ +/** @typedef {import("../javascript/JavascriptParser").Range} Range */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */ /** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */ +/** @typedef {import("./CommonJsDependencyHelpers").CommonJSDependencyBaseKeywords} CommonJSDependencyBaseKeywords */ class CommonJsSelfReferenceDependency extends NullDependency { + /** + * @param {Range} range range + * @param {CommonJSDependencyBaseKeywords} base base + * @param {string[]} names names + * @param {boolean} call is a call + */ constructor(range, base, names, call) { super(); this.range = range; @@ -40,7 +50,7 @@ class CommonJsSelfReferenceDependency extends NullDependency { * @returns {string | null} an identifier to merge equal requests */ getResourceIdentifier() { - return `self`; + return "self"; } /** @@ -53,6 +63,9 @@ class CommonJsSelfReferenceDependency extends NullDependency { return [this.call ? this.names.slice(0, -1) : this.names]; } + /** + * @param {ObjectSerializerContext} context context + */ serialize(context) { const { write } = context; write(this.range); @@ -62,6 +75,9 @@ class CommonJsSelfReferenceDependency extends NullDependency { super.serialize(context); } + /** + * @param {ObjectDeserializerContext} context context + */ deserialize(context) { const { read } = context; this.range = read(); @@ -92,19 +108,17 @@ CommonJsSelfReferenceDependency.Template = class CommonJsSelfReferenceDependency { module, moduleGraph, runtime, runtimeRequirements } ) { const dep = /** @type {CommonJsSelfReferenceDependency} */ (dependency); - let used; - if (dep.names.length === 0) { - used = dep.names; - } else { - used = moduleGraph.getExportsInfo(module).getUsedName(dep.names, runtime); - } + const used = + dep.names.length === 0 + ? dep.names + : moduleGraph.getExportsInfo(module).getUsedName(dep.names, runtime); if (!used) { throw new Error( "Self-reference dependency has unused export name: This should not happen" ); } - let base = undefined; + let base; switch (dep.base) { case "exports": runtimeRequirements.add(RuntimeGlobals.exports); diff --git a/lib/dependencies/ConstDependency.js b/lib/dependencies/ConstDependency.js index 60a8185cefc..e41acef3acc 100644 --- a/lib/dependencies/ConstDependency.js +++ b/lib/dependencies/ConstDependency.js @@ -15,13 +15,16 @@ const NullDependency = require("./NullDependency"); /** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */ /** @typedef {import("../ModuleGraph")} ModuleGraph */ /** @typedef {import("../ModuleGraphConnection").ConnectionState} ConnectionState */ +/** @typedef {import("../javascript/JavascriptParser").Range} Range */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */ /** @typedef {import("../util/Hash")} Hash */ class ConstDependency extends NullDependency { /** * @param {string} expression the expression - * @param {number|[number, number]} range the source range - * @param {string[]=} runtimeRequirements runtime requirements + * @param {number | Range} range the source range + * @param {(string[] | null)=} runtimeRequirements runtime requirements */ constructor(expression, range, runtimeRequirements) { super(); @@ -30,6 +33,7 @@ class ConstDependency extends NullDependency { this.runtimeRequirements = runtimeRequirements ? new Set(runtimeRequirements) : null; + this._hashUpdate = undefined; } /** @@ -39,10 +43,17 @@ class ConstDependency extends NullDependency { * @returns {void} */ updateHash(hash, context) { - hash.update(this.range + ""); - hash.update(this.expression + ""); - if (this.runtimeRequirements) - hash.update(Array.from(this.runtimeRequirements).join() + ""); + if (this._hashUpdate === undefined) { + let hashUpdate = `${this.range}|${this.expression}`; + if (this.runtimeRequirements) { + for (const item of this.runtimeRequirements) { + hashUpdate += "|"; + hashUpdate += item; + } + } + this._hashUpdate = hashUpdate; + } + hash.update(this._hashUpdate); } /** @@ -53,6 +64,9 @@ class ConstDependency extends NullDependency { return false; } + /** + * @param {ObjectSerializerContext} context context + */ serialize(context) { const { write } = context; write(this.expression); @@ -61,6 +75,9 @@ class ConstDependency extends NullDependency { super.serialize(context); } + /** + * @param {ObjectDeserializerContext} context context + */ deserialize(context) { const { read } = context; this.expression = read(); diff --git a/lib/dependencies/ContextDependency.js b/lib/dependencies/ContextDependency.js index 52dae0b6b0e..fb12467db13 100644 --- a/lib/dependencies/ContextDependency.js +++ b/lib/dependencies/ContextDependency.js @@ -11,8 +11,11 @@ const makeSerializable = require("../util/makeSerializable"); const memoize = require("../util/memoize"); /** @typedef {import("../ContextModule").ContextOptions} ContextOptions */ +/** @typedef {import("../Dependency").TRANSITIVE} TRANSITIVE */ /** @typedef {import("../ModuleGraph")} ModuleGraph */ /** @typedef {import("../WebpackError")} WebpackError */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */ const getCriticalDependencyWarning = memoize(() => require("./CriticalDependencyWarning") @@ -20,18 +23,23 @@ const getCriticalDependencyWarning = memoize(() => /** @typedef {ContextOptions & { request: string }} ContextDependencyOptions */ -const regExpToString = r => (r ? r + "" : ""); +/** + * @param {RegExp | null | undefined} r regexp + * @returns {string} stringified regexp + */ +const regExpToString = r => (r ? String(r) : ""); class ContextDependency extends Dependency { /** * @param {ContextDependencyOptions} options options for the context module + * @param {string=} context request context */ - constructor(options) { + constructor(options, context) { super(); this.options = options; this.userRequest = this.options && this.options.request; - /** @type {false | string} */ + /** @type {false | undefined | string} */ this.critical = false; this.hadGlobalOrStickyRegExp = false; @@ -46,20 +54,39 @@ class ContextDependency extends Dependency { this.request = undefined; this.range = undefined; this.valueRange = undefined; + /** @type {boolean | string | undefined} */ + this.inShorthand = undefined; // TODO refactor this this.replaces = undefined; + this._requestContext = context; + } + + /** + * @returns {string | undefined} a request context + */ + getContext() { + return this._requestContext; } get category() { return "commonjs"; } + /** + * @returns {boolean | TRANSITIVE} true, when changes to the referenced module could affect the referencing module; TRANSITIVE, when changes to the referenced module could affect referencing modules of the referencing module + */ + couldAffectReferencingModule() { + return true; + } + /** * @returns {string | null} an identifier to merge equal requests */ getResourceIdentifier() { return ( - `context${this.options.request} ${this.options.recursive} ` + + `context${this._requestContext || ""}|ctx request${ + this.options.request + } ${this.options.recursive} ` + `${regExpToString(this.options.regExp)} ${regExpToString( this.options.include )} ${regExpToString(this.options.exclude)} ` + @@ -71,7 +98,7 @@ class ContextDependency extends Dependency { /** * Returns warnings * @param {ModuleGraph} moduleGraph module graph - * @returns {WebpackError[]} warnings + * @returns {WebpackError[] | null | undefined} warnings */ getWarnings(moduleGraph) { let warnings = super.getWarnings(moduleGraph); @@ -95,6 +122,9 @@ class ContextDependency extends Dependency { return warnings; } + /** + * @param {ObjectSerializerContext} context context + */ serialize(context) { const { write } = context; @@ -103,6 +133,7 @@ class ContextDependency extends Dependency { write(this.critical); write(this.hadGlobalOrStickyRegExp); write(this.request); + write(this._requestContext); write(this.range); write(this.valueRange); write(this.prepend); @@ -111,6 +142,9 @@ class ContextDependency extends Dependency { super.serialize(context); } + /** + * @param {ObjectDeserializerContext} context context + */ deserialize(context) { const { read } = context; @@ -119,6 +153,7 @@ class ContextDependency extends Dependency { this.critical = read(); this.hadGlobalOrStickyRegExp = read(); this.request = read(); + this._requestContext = read(); this.range = read(); this.valueRange = read(); this.prepend = read(); diff --git a/lib/dependencies/ContextDependencyHelpers.js b/lib/dependencies/ContextDependencyHelpers.js index e6b00a66283..ed635328202 100644 --- a/lib/dependencies/ContextDependencyHelpers.js +++ b/lib/dependencies/ContextDependencyHelpers.js @@ -10,8 +10,10 @@ const { parseResource } = require("../util/identifier"); /** @typedef {import("estree").Node} EsTreeNode */ /** @typedef {import("../../declarations/WebpackOptions").JavascriptParserOptions} JavascriptParserOptions */ /** @typedef {import("../../declarations/WebpackOptions").ModuleOptionsNormalized} ModuleOptions */ +/** @typedef {import("../Dependency").DependencyLocation} DependencyLocation */ /** @typedef {import("../javascript/BasicEvaluatedExpression")} BasicEvaluatedExpression */ /** @typedef {import("../javascript/JavascriptParser")} JavascriptParser */ +/** @typedef {import("../javascript/JavascriptParser").Range} Range */ /** @typedef {import("./ContextDependency")} ContextDependency */ /** @typedef {import("./ContextDependency").ContextDependencyOptions} ContextDependencyOptions */ @@ -20,16 +22,18 @@ const { parseResource } = require("../util/identifier"); * @param {string} str String to quote * @returns {string} Escaped string */ -const quoteMeta = str => { - return str.replace(/[-[\]\\/{}()*+?.^$|]/g, "\\$&"); -}; +const quoteMeta = str => str.replace(/[-[\]\\/{}()*+?.^$|]/g, "\\$&"); +/** + * @param {string} prefix prefix + * @returns {{prefix: string, context: string}} result + */ const splitContextFromPrefix = prefix => { const idx = prefix.lastIndexOf("/"); let context = "."; if (idx >= 0) { - context = prefix.substr(0, idx); - prefix = `.${prefix.substr(idx)}`; + context = prefix.slice(0, idx); + prefix = `.${prefix.slice(idx)}`; } return { context, @@ -37,42 +41,56 @@ const splitContextFromPrefix = prefix => { }; }; -/** @typedef {Partial>} PartialContextDependencyOptions */ - -/** @typedef {{ new(options: ContextDependencyOptions, range: [number, number], valueRange: [number, number]): ContextDependency }} ContextDependencyConstructor */ +/** @typedef {Partial>} PartialContextDependencyOptions */ +/** @typedef {{ new(options: ContextDependencyOptions, range: Range, valueRange: [number, number], ...args: any[]): ContextDependency }} ContextDependencyConstructor */ /** * @param {ContextDependencyConstructor} Dep the Dependency class - * @param {[number, number]} range source range + * @param {Range} range source range * @param {BasicEvaluatedExpression} param context param * @param {EsTreeNode} expr expr * @param {Pick} options options for context creation * @param {PartialContextDependencyOptions} contextOptions options for the ContextModule * @param {JavascriptParser} parser the parser + * @param {...any} depArgs depArgs * @returns {ContextDependency} the created Dependency */ -exports.create = (Dep, range, param, expr, options, contextOptions, parser) => { +module.exports.create = ( + Dep, + range, + param, + expr, + options, + contextOptions, + parser, + ...depArgs +) => { if (param.isTemplateString()) { - let prefixRaw = param.quasis[0].string; - let postfixRaw = - param.quasis.length > 1 - ? param.quasis[param.quasis.length - 1].string - : ""; + const quasis = /** @type {BasicEvaluatedExpression[]} */ (param.quasis); + const prefixRaw = /** @type {string} */ (quasis[0].string); + const postfixRaw = + /** @type {string} */ + (quasis.length > 1 ? quasis[quasis.length - 1].string : ""); - const valueRange = param.range; + const valueRange = /** @type {Range} */ (param.range); const { context, prefix } = splitContextFromPrefix(prefixRaw); - const { path: postfix, query, fragment } = parseResource( - postfixRaw, - parser - ); + const { + path: postfix, + query, + fragment + } = parseResource(postfixRaw, parser); // When there are more than two quasis, the generated RegExp can be more precise // We join the quasis with the expression regexp - const innerQuasis = param.quasis.slice(1, param.quasis.length - 1); + const innerQuasis = quasis.slice(1, -1); const innerRegExp = - options.wrappedContextRegExp.source + + /** @type {RegExp} */ (options.wrappedContextRegExp).source + innerQuasis - .map(q => quoteMeta(q.string) + options.wrappedContextRegExp.source) + .map( + q => + quoteMeta(/** @type {string} */ (q.string)) + + /** @type {RegExp} */ (options.wrappedContextRegExp).source + ) .join(""); // Example: `./context/pre${e}inner${e}inner2${e}post?query#frag` @@ -90,45 +108,55 @@ exports.create = (Dep, range, param, expr, options, contextOptions, parser) => { const dep = new Dep( { request: context + query + fragment, - recursive: options.wrappedContextRecursive, + recursive: /** @type {boolean} */ (options.wrappedContextRecursive), regExp, mode: "sync", ...contextOptions }, range, - valueRange + valueRange, + ...depArgs ); - dep.loc = expr.loc; + dep.loc = /** @type {DependencyLocation} */ (expr.loc); + + /** @type {{ value: string, range: Range }[]} */ const replaces = []; + const parts = /** @type {BasicEvaluatedExpression[]} */ (param.parts); - param.parts.forEach((part, i) => { + for (const [i, part] of parts.entries()) { if (i % 2 === 0) { // Quasis or merged quasi - let range = part.range; - let value = part.string; + let range = /** @type {Range} */ (part.range); + let value = /** @type {string} */ (part.string); if (param.templateStringKind === "cooked") { value = JSON.stringify(value); - value = value.slice(1, value.length - 1); + value = value.slice(1, -1); } if (i === 0) { // prefix value = prefix; - range = [param.range[0], part.range[1]]; + range = [ + /** @type {Range} */ (param.range)[0], + /** @type {Range} */ (part.range)[1] + ]; value = (param.templateStringKind === "cooked" ? "`" : "String.raw`") + value; - } else if (i === param.parts.length - 1) { + } else if (i === parts.length - 1) { // postfix value = postfix; - range = [part.range[0], param.range[1]]; - value = value + "`"; + range = [ + /** @type {Range} */ (part.range)[0], + /** @type {Range} */ (param.range)[1] + ]; + value = `${value}\``; } else if ( part.expression && part.expression.type === "TemplateElement" && part.expression.value.raw === value ) { // Shortcut when it's a single quasi and doesn't need to be replaced - return; + continue; } replaces.push({ range, @@ -138,7 +166,7 @@ exports.create = (Dep, range, param, expr, options, contextOptions, parser) => { // Expression parser.walkExpression(part.expression); } - }); + } dep.replaces = replaces; dep.critical = @@ -150,37 +178,41 @@ exports.create = (Dep, range, param, expr, options, contextOptions, parser) => { ((param.prefix && param.prefix.isString()) || (param.postfix && param.postfix.isString())) ) { - let prefixRaw = - param.prefix && param.prefix.isString() ? param.prefix.string : ""; - let postfixRaw = - param.postfix && param.postfix.isString() ? param.postfix.string : ""; + const prefixRaw = + /** @type {string} */ + (param.prefix && param.prefix.isString() ? param.prefix.string : ""); + const postfixRaw = + /** @type {string} */ + (param.postfix && param.postfix.isString() ? param.postfix.string : ""); const prefixRange = param.prefix && param.prefix.isString() ? param.prefix.range : null; const postfixRange = param.postfix && param.postfix.isString() ? param.postfix.range : null; - const valueRange = param.range; + const valueRange = /** @type {Range} */ (param.range); const { context, prefix } = splitContextFromPrefix(prefixRaw); - const { path: postfix, query, fragment } = parseResource( - postfixRaw, - parser - ); + const { + path: postfix, + query, + fragment + } = parseResource(postfixRaw, parser); const regExp = new RegExp( - `^${quoteMeta(prefix)}${options.wrappedContextRegExp.source}${quoteMeta( - postfix - )}$` + `^${quoteMeta(prefix)}${ + /** @type {RegExp} */ (options.wrappedContextRegExp).source + }${quoteMeta(postfix)}$` ); const dep = new Dep( { request: context + query + fragment, - recursive: options.wrappedContextRecursive, + recursive: /** @type {boolean} */ (options.wrappedContextRecursive), regExp, mode: "sync", ...contextOptions }, range, - valueRange + valueRange, + ...depArgs ); - dep.loc = expr.loc; + dep.loc = /** @type {DependencyLocation} */ (expr.loc); const replaces = []; if (prefixRange) { replaces.push({ @@ -206,25 +238,25 @@ exports.create = (Dep, range, param, expr, options, contextOptions, parser) => { } return dep; - } else { - const dep = new Dep( - { - request: options.exprContextRequest, - recursive: options.exprContextRecursive, - regExp: /** @type {RegExp} */ (options.exprContextRegExp), - mode: "sync", - ...contextOptions - }, - range, - param.range - ); - dep.loc = expr.loc; - dep.critical = - options.exprContextCritical && - "the request of a dependency is an expression"; + } + const dep = new Dep( + { + request: /** @type {string} */ (options.exprContextRequest), + recursive: /** @type {boolean} */ (options.exprContextRecursive), + regExp: /** @type {RegExp} */ (options.exprContextRegExp), + mode: "sync", + ...contextOptions + }, + range, + /** @type {Range} */ (param.range), + ...depArgs + ); + dep.loc = /** @type {DependencyLocation} */ (expr.loc); + dep.critical = + options.exprContextCritical && + "the request of a dependency is an expression"; - parser.walkExpression(param.expression); + parser.walkExpression(param.expression); - return dep; - } + return dep; }; diff --git a/lib/dependencies/ContextDependencyTemplateAsRequireCall.js b/lib/dependencies/ContextDependencyTemplateAsRequireCall.js index 9b73dcb3843..8907f9f55d8 100644 --- a/lib/dependencies/ContextDependencyTemplateAsRequireCall.js +++ b/lib/dependencies/ContextDependencyTemplateAsRequireCall.js @@ -24,13 +24,16 @@ class ContextDependencyTemplateAsRequireCall extends ContextDependency.Template { runtimeTemplate, moduleGraph, chunkGraph, runtimeRequirements } ) { const dep = /** @type {ContextDependency} */ (dependency); - const moduleExports = runtimeTemplate.moduleExports({ + let moduleExports = runtimeTemplate.moduleExports({ module: moduleGraph.getModule(dep), chunkGraph, request: dep.request, runtimeRequirements }); + if (dep.inShorthand) { + moduleExports = `${dep.inShorthand}: ${moduleExports}`; + } if (moduleGraph.getModule(dep)) { if (dep.valueRange) { if (Array.isArray(dep.replaces)) { diff --git a/lib/dependencies/ContextElementDependency.js b/lib/dependencies/ContextElementDependency.js index 6ac3a3ff2f3..448ef7c21ae 100644 --- a/lib/dependencies/ContextElementDependency.js +++ b/lib/dependencies/ContextElementDependency.js @@ -11,20 +11,48 @@ const ModuleDependency = require("./ModuleDependency"); /** @typedef {import("../Dependency").ReferencedExport} ReferencedExport */ /** @typedef {import("../ModuleGraph")} ModuleGraph */ +/** @typedef {import("../javascript/JavascriptParser").ImportAttributes} ImportAttributes */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */ /** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */ class ContextElementDependency extends ModuleDependency { - constructor(request, userRequest, category, referencedExports) { + /** + * @param {string} request request + * @param {string|undefined} userRequest user request + * @param {string | undefined} typePrefix type prefix + * @param {string} category category + * @param {(string[][] | null)=} referencedExports referenced exports + * @param {string=} context context + * @param {ImportAttributes=} attributes import assertions + */ + constructor( + request, + userRequest, + typePrefix, + category, + referencedExports, + context, + attributes + ) { super(request); this.referencedExports = referencedExports; + this._typePrefix = typePrefix; this._category = category; + this._context = context || undefined; if (userRequest) { this.userRequest = userRequest; } + + this.assertions = attributes; } get type() { + if (this._typePrefix) { + return `${this._typePrefix} context element`; + } + return "context element"; } @@ -43,17 +71,31 @@ class ContextElementDependency extends ModuleDependency { ? this.referencedExports.map(e => ({ name: e, canMangle: false - })) + })) : Dependency.EXPORTS_OBJECT_REFERENCED; } + /** + * @param {ObjectSerializerContext} context context + */ serialize(context) { - context.write(this.referencedExports); + const { write } = context; + write(this._typePrefix); + write(this._category); + write(this.referencedExports); + write(this.assertions); super.serialize(context); } + /** + * @param {ObjectDeserializerContext} context context + */ deserialize(context) { - this.referencedExports = context.read(); + const { read } = context; + this._typePrefix = read(); + this._category = read(); + this.referencedExports = read(); + this.assertions = read(); super.deserialize(context); } } diff --git a/lib/dependencies/CreateScriptUrlDependency.js b/lib/dependencies/CreateScriptUrlDependency.js new file mode 100644 index 00000000000..9abb5c50cf4 --- /dev/null +++ b/lib/dependencies/CreateScriptUrlDependency.js @@ -0,0 +1,75 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ + +"use strict"; + +const RuntimeGlobals = require("../RuntimeGlobals"); +const makeSerializable = require("../util/makeSerializable"); +const NullDependency = require("./NullDependency"); + +/** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */ +/** @typedef {import("../Dependency")} Dependency */ +/** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */ +/** @typedef {import("../javascript/JavascriptParser").Range} Range */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */ + +class CreateScriptUrlDependency extends NullDependency { + /** + * @param {Range} range range + */ + constructor(range) { + super(); + this.range = range; + } + + get type() { + return "create script url"; + } + + /** + * @param {ObjectSerializerContext} context context + */ + serialize(context) { + const { write } = context; + write(this.range); + super.serialize(context); + } + + /** + * @param {ObjectDeserializerContext} context context + */ + deserialize(context) { + const { read } = context; + this.range = read(); + super.deserialize(context); + } +} + +CreateScriptUrlDependency.Template = class CreateScriptUrlDependencyTemplate extends ( + NullDependency.Template +) { + /** + * @param {Dependency} dependency the dependency for which the template should be applied + * @param {ReplaceSource} source the current replace source which can be modified + * @param {DependencyTemplateContext} templateContext the context object + * @returns {void} + */ + apply(dependency, source, { runtimeRequirements }) { + const dep = /** @type {CreateScriptUrlDependency} */ (dependency); + + runtimeRequirements.add(RuntimeGlobals.createScriptUrl); + + source.insert(dep.range[0], `${RuntimeGlobals.createScriptUrl}(`); + source.insert(dep.range[1], ")"); + } +}; + +makeSerializable( + CreateScriptUrlDependency, + "webpack/lib/dependencies/CreateScriptUrlDependency" +); + +module.exports = CreateScriptUrlDependency; diff --git a/lib/dependencies/CriticalDependencyWarning.js b/lib/dependencies/CriticalDependencyWarning.js index e1026d9c1f4..3299150bd97 100644 --- a/lib/dependencies/CriticalDependencyWarning.js +++ b/lib/dependencies/CriticalDependencyWarning.js @@ -9,13 +9,14 @@ const WebpackError = require("../WebpackError"); const makeSerializable = require("../util/makeSerializable"); class CriticalDependencyWarning extends WebpackError { + /** + * @param {string} message message + */ constructor(message) { super(); this.name = "CriticalDependencyWarning"; - this.message = "Critical dependency: " + message; - - Error.captureStackTrace(this, this.constructor); + this.message = `Critical dependency: ${message}`; } } diff --git a/lib/dependencies/CssExportDependency.js b/lib/dependencies/CssExportDependency.js new file mode 100644 index 00000000000..a7cf6dbb843 --- /dev/null +++ b/lib/dependencies/CssExportDependency.js @@ -0,0 +1,156 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Ivan Kopeykin @vankop +*/ + +"use strict"; + +const { cssExportConvention } = require("../util/conventions"); +const makeSerializable = require("../util/makeSerializable"); +const NullDependency = require("./NullDependency"); + +/** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */ +/** @typedef {import("../../declarations/WebpackOptions").CssGeneratorExportsConvention} CssGeneratorExportsConvention */ +/** @typedef {import("../CssModule")} CssModule */ +/** @typedef {import("../Dependency")} Dependency */ +/** @typedef {import("../Dependency").ExportsSpec} ExportsSpec */ +/** @typedef {import("../Dependency").UpdateHashContext} UpdateHashContext */ +/** @typedef {import("../DependencyTemplate").CssDependencyTemplateContext} DependencyTemplateContext */ +/** @typedef {import("../ModuleGraph")} ModuleGraph */ +/** @typedef {import("../css/CssExportsGenerator")} CssExportsGenerator */ +/** @typedef {import("../css/CssGenerator")} CssGenerator */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */ +/** @typedef {import("../util/Hash")} Hash */ + +class CssExportDependency extends NullDependency { + /** + * @param {string} name name + * @param {string} value value + */ + constructor(name, value) { + super(); + this.name = name; + this.value = value; + } + + get type() { + return "css :export"; + } + + /** + * @param {string} name export name + * @param {CssGeneratorExportsConvention} convention convention of the export name + * @returns {string[]} convention results + */ + getExportsConventionNames(name, convention) { + if (this._conventionNames) { + return this._conventionNames; + } + this._conventionNames = cssExportConvention(name, convention); + return this._conventionNames; + } + + /** + * Returns the exported names + * @param {ModuleGraph} moduleGraph module graph + * @returns {ExportsSpec | undefined} export names + */ + getExports(moduleGraph) { + const module = /** @type {CssModule} */ (moduleGraph.getParentModule(this)); + const convention = + /** @type {CssGenerator | CssExportsGenerator} */ + (module.generator).convention; + const names = this.getExportsConventionNames(this.name, convention); + return { + exports: names.map(name => ({ + name, + canMangle: true + })), + dependencies: undefined + }; + } + + /** + * Update the hash + * @param {Hash} hash hash to be updated + * @param {UpdateHashContext} context context + * @returns {void} + */ + updateHash(hash, { chunkGraph }) { + const module = /** @type {CssModule} */ ( + chunkGraph.moduleGraph.getParentModule(this) + ); + const generator = + /** @type {CssGenerator | CssExportsGenerator} */ + (module.generator); + const names = this.getExportsConventionNames( + this.name, + generator.convention + ); + hash.update("exportsConvention"); + hash.update(JSON.stringify(names)); + } + + /** + * @param {ObjectSerializerContext} context context + */ + serialize(context) { + const { write } = context; + write(this.name); + write(this.value); + super.serialize(context); + } + + /** + * @param {ObjectDeserializerContext} context context + */ + deserialize(context) { + const { read } = context; + this.name = read(); + this.value = read(); + super.deserialize(context); + } +} + +CssExportDependency.Template = class CssExportDependencyTemplate extends ( + NullDependency.Template +) { + /** + * @param {Dependency} dependency the dependency for which the template should be applied + * @param {ReplaceSource} source the current replace source which can be modified + * @param {DependencyTemplateContext} templateContext the context object + * @returns {void} + */ + apply( + dependency, + source, + { cssExportsData, module: m, runtime, moduleGraph } + ) { + const dep = /** @type {CssExportDependency} */ (dependency); + const module = /** @type {CssModule} */ (m); + const convention = /** @type {CssGenerator | CssExportsGenerator} */ ( + module.generator + ).convention; + const names = dep.getExportsConventionNames(dep.name, convention); + const usedNames = /** @type {string[]} */ ( + names + .map(name => + moduleGraph.getExportInfo(module, name).getUsedName(name, runtime) + ) + .filter(Boolean) + ); + if (usedNames.length === 0) return; + + for (const used of usedNames) { + cssExportsData.exports.set(used, dep.value); + } + } +}; + +makeSerializable( + CssExportDependency, + "webpack/lib/dependencies/CssExportDependency" +); + +module.exports = CssExportDependency; diff --git a/lib/dependencies/CssImportDependency.js b/lib/dependencies/CssImportDependency.js new file mode 100644 index 00000000000..c235be412c1 --- /dev/null +++ b/lib/dependencies/CssImportDependency.js @@ -0,0 +1,125 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Ivan Kopeykin @vankop +*/ + +"use strict"; + +const makeSerializable = require("../util/makeSerializable"); +const ModuleDependency = require("./ModuleDependency"); + +/** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */ +/** @typedef {import("../ChunkGraph")} ChunkGraph */ +/** @typedef {import("../Dependency")} Dependency */ +/** @typedef {import("../Dependency").UpdateHashContext} UpdateHashContext */ +/** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */ +/** @typedef {import("../Module")} Module */ +/** @typedef {import("../ModuleGraph")} ModuleGraph */ +/** @typedef {import("../ModuleGraphConnection")} ModuleGraphConnection */ +/** @typedef {import("../ModuleGraphConnection").ConnectionState} ConnectionState */ +/** @typedef {import("../css/CssParser").Range} Range */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */ +/** @typedef {import("../util/Hash")} Hash */ +/** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */ + +class CssImportDependency extends ModuleDependency { + /** + * Example of dependency: + * \@import url("landscape.css") layer(forms) screen and (orientation: landscape) screen and (orientation: landscape); + * @param {string} request request + * @param {Range} range range of the argument + * @param {string | undefined} layer layer + * @param {string | undefined} supports list of supports conditions + * @param {string | undefined} media list of media conditions + */ + constructor(request, range, layer, supports, media) { + super(request); + this.range = range; + this.layer = layer; + this.supports = supports; + this.media = media; + } + + get type() { + return "css @import"; + } + + get category() { + return "css-import"; + } + + /** + * @returns {string | null} an identifier to merge equal requests + */ + getResourceIdentifier() { + let str = `context${this._context || ""}|module${this.request}`; + + if (this.layer) { + str += `|layer${this.layer}`; + } + + if (this.supports) { + str += `|supports${this.supports}`; + } + + if (this.media) { + str += `|media${this.media}`; + } + + return str; + } + + /** + * @param {string} context context directory + * @returns {Module | null} a module + */ + createIgnoredModule(context) { + return null; + } + + /** + * @param {ObjectSerializerContext} context context + */ + serialize(context) { + const { write } = context; + write(this.layer); + write(this.supports); + write(this.media); + super.serialize(context); + } + + /** + * @param {ObjectDeserializerContext} context context + */ + deserialize(context) { + const { read } = context; + this.layer = read(); + this.supports = read(); + this.media = read(); + super.deserialize(context); + } +} + +CssImportDependency.Template = class CssImportDependencyTemplate extends ( + ModuleDependency.Template +) { + /** + * @param {Dependency} dependency the dependency for which the template should be applied + * @param {ReplaceSource} source the current replace source which can be modified + * @param {DependencyTemplateContext} templateContext the context object + * @returns {void} + */ + apply(dependency, source, templateContext) { + const dep = /** @type {CssImportDependency} */ (dependency); + + source.replace(dep.range[0], dep.range[1] - 1, ""); + } +}; + +makeSerializable( + CssImportDependency, + "webpack/lib/dependencies/CssImportDependency" +); + +module.exports = CssImportDependency; diff --git a/lib/dependencies/CssLocalIdentifierDependency.js b/lib/dependencies/CssLocalIdentifierDependency.js new file mode 100644 index 00000000000..2b495dd8c3f --- /dev/null +++ b/lib/dependencies/CssLocalIdentifierDependency.js @@ -0,0 +1,245 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Ivan Kopeykin @vankop +*/ + +"use strict"; + +const { cssExportConvention } = require("../util/conventions"); +const createHash = require("../util/createHash"); +const { makePathsRelative } = require("../util/identifier"); +const makeSerializable = require("../util/makeSerializable"); +const NullDependency = require("./NullDependency"); + +/** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */ +/** @typedef {import("../../declarations/WebpackOptions").CssGeneratorExportsConvention} CssGeneratorExportsConvention */ +/** @typedef {import("../../declarations/WebpackOptions").CssGeneratorLocalIdentName} CssGeneratorLocalIdentName */ +/** @typedef {import("../ChunkGraph")} ChunkGraph */ +/** @typedef {import("../CssModule")} CssModule */ +/** @typedef {import("../Dependency")} Dependency */ +/** @typedef {import("../Dependency").ExportsSpec} ExportsSpec */ +/** @typedef {import("../Dependency").UpdateHashContext} UpdateHashContext */ +/** @typedef {import("../DependencyTemplate").CssDependencyTemplateContext} DependencyTemplateContext */ +/** @typedef {import("../ModuleGraph")} ModuleGraph */ +/** @typedef {import("../RuntimeTemplate")} RuntimeTemplate */ +/** @typedef {import("../css/CssExportsGenerator")} CssExportsGenerator */ +/** @typedef {import("../css/CssGenerator")} CssGenerator */ +/** @typedef {import("../css/CssParser").Range} Range */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */ +/** @typedef {import("../util/Hash")} Hash */ + +/** + * @param {string} local css local + * @param {CssModule} module module + * @param {ChunkGraph} chunkGraph chunk graph + * @param {RuntimeTemplate} runtimeTemplate runtime template + * @returns {string} local ident + */ +const getLocalIdent = (local, module, chunkGraph, runtimeTemplate) => { + const localIdentName = + /** @type {CssGenerator | CssExportsGenerator} */ + (module.generator).localIdentName; + const relativeResourcePath = makePathsRelative( + /** @type {string} */ (module.context), + module.resourceResolveData.path + ); + const { hashFunction, hashDigest, hashDigestLength, hashSalt, uniqueName } = + runtimeTemplate.outputOptions; + const hash = createHash(hashFunction); + if (hashSalt) { + hash.update(hashSalt); + } + hash.update(relativeResourcePath); + if (!/\[local\]/.test(localIdentName)) { + hash.update(local); + } + const localIdentHash = /** @type {string} */ (hash.digest(hashDigest)) + // Remove all leading digits + .replace(/^\d+/, "") + // Replace all slashes with underscores (same as in base64url) + .replace(/\//g, "_") + // Remove everything that is not an alphanumeric or underscore + .replace(/[^A-Za-z0-9_]+/g, "_") + .slice(0, hashDigestLength); + return runtimeTemplate.compilation + .getPath(localIdentName, { + filename: relativeResourcePath, + hash: localIdentHash, + contentHash: localIdentHash, + chunkGraph, + module + }) + .replace(/\[local\]/g, local) + .replace(/\[uniqueName\]/g, uniqueName); +}; + +class CssLocalIdentifierDependency extends NullDependency { + /** + * @param {string} name name + * @param {Range} range range + * @param {string=} prefix prefix + */ + constructor(name, range, prefix = "") { + super(); + this.name = name; + this.range = range; + this.prefix = prefix; + } + + get type() { + return "css local identifier"; + } + + /** + * @param {string} name export name + * @param {CssGeneratorExportsConvention} convention convention of the export name + * @returns {string[]} convention results + */ + getExportsConventionNames(name, convention) { + if (this._conventionNames) { + return this._conventionNames; + } + this._conventionNames = cssExportConvention(this.name, convention); + return this._conventionNames; + } + + /** + * Returns the exported names + * @param {ModuleGraph} moduleGraph module graph + * @returns {ExportsSpec | undefined} export names + */ + getExports(moduleGraph) { + const module = /** @type {CssModule} */ (moduleGraph.getParentModule(this)); + const convention = /** @type {CssGenerator | CssExportsGenerator} */ ( + module.generator + ).convention; + const names = this.getExportsConventionNames(this.name, convention); + return { + exports: names.map(name => ({ + name, + canMangle: true + })), + dependencies: undefined + }; + } + + /** + * Update the hash + * @param {Hash} hash hash to be updated + * @param {UpdateHashContext} context context + * @returns {void} + */ + updateHash(hash, { chunkGraph }) { + const module = /** @type {CssModule} */ ( + chunkGraph.moduleGraph.getParentModule(this) + ); + const generator = /** @type {CssGenerator | CssExportsGenerator} */ ( + module.generator + ); + const names = this.getExportsConventionNames( + this.name, + generator.convention + ); + hash.update("exportsConvention"); + hash.update(JSON.stringify(names)); + hash.update("localIdentName"); + hash.update(generator.localIdentName); + } + + /** + * @param {ObjectSerializerContext} context context + */ + serialize(context) { + const { write } = context; + write(this.name); + write(this.range); + write(this.prefix); + super.serialize(context); + } + + /** + * @param {ObjectDeserializerContext} context context + */ + deserialize(context) { + const { read } = context; + this.name = read(); + this.range = read(); + this.prefix = read(); + super.deserialize(context); + } +} + +/** + * @param {string} str string + * @param {string | boolean} omitUnderscore true if you need to omit underscore + * @returns {string} escaped css identifier + */ +const escapeCssIdentifier = (str, omitUnderscore) => { + const escaped = `${str}`.replace( + // cspell:word uffff + /[^a-zA-Z0-9_\u0081-\uFFFF-]/g, + s => `\\${s}` + ); + return !omitUnderscore && /^(?!--)[0-9-]/.test(escaped) + ? `_${escaped}` + : escaped; +}; + +CssLocalIdentifierDependency.Template = class CssLocalIdentifierDependencyTemplate extends ( + NullDependency.Template +) { + /** + * @param {Dependency} dependency the dependency for which the template should be applied + * @param {ReplaceSource} source the current replace source which can be modified + * @param {DependencyTemplateContext} templateContext the context object + * @returns {void} + */ + apply( + dependency, + source, + { + module: m, + moduleGraph, + chunkGraph, + runtime, + runtimeTemplate, + cssExportsData + } + ) { + const dep = /** @type {CssLocalIdentifierDependency} */ (dependency); + const module = /** @type {CssModule} */ (m); + const convention = /** @type {CssGenerator | CssExportsGenerator} */ ( + module.generator + ).convention; + const names = dep.getExportsConventionNames(dep.name, convention); + const usedNames = /** @type {string[]} */ ( + names + .map(name => + moduleGraph.getExportInfo(module, name).getUsedName(name, runtime) + ) + .filter(Boolean) + ); + if (usedNames.length === 0) return; + + // use the first usedName to generate localIdent, it's shorter when mangle exports enabled + const localIdent = + dep.prefix + + getLocalIdent(usedNames[0], module, chunkGraph, runtimeTemplate); + source.replace( + dep.range[0], + dep.range[1] - 1, + escapeCssIdentifier(localIdent, dep.prefix) + ); + for (const used of usedNames) { + cssExportsData.exports.set(used, localIdent); + } + } +}; + +makeSerializable( + CssLocalIdentifierDependency, + "webpack/lib/dependencies/CssLocalIdentifierDependency" +); + +module.exports = CssLocalIdentifierDependency; diff --git a/lib/dependencies/CssSelfLocalIdentifierDependency.js b/lib/dependencies/CssSelfLocalIdentifierDependency.js new file mode 100644 index 00000000000..b63ff53a74e --- /dev/null +++ b/lib/dependencies/CssSelfLocalIdentifierDependency.js @@ -0,0 +1,111 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Ivan Kopeykin @vankop +*/ + +"use strict"; + +const Dependency = require("../Dependency"); +const makeSerializable = require("../util/makeSerializable"); +const CssLocalIdentifierDependency = require("./CssLocalIdentifierDependency"); + +/** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */ +/** @typedef {import("../Dependency").ExportsSpec} ExportsSpec */ +/** @typedef {import("../Dependency").ReferencedExport} ReferencedExport */ +/** @typedef {import("../DependencyTemplate").CssDependencyTemplateContext} DependencyTemplateContext */ +/** @typedef {import("../ModuleGraph")} ModuleGraph */ +/** @typedef {import("../css/CssParser").Range} Range */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */ +/** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */ + +class CssSelfLocalIdentifierDependency extends CssLocalIdentifierDependency { + /** + * @param {string} name name + * @param {Range} range range + * @param {string=} prefix prefix + * @param {Set=} declaredSet set of declared names (will only be active when in declared set) + */ + constructor(name, range, prefix = "", declaredSet = undefined) { + super(name, range, prefix); + this.declaredSet = declaredSet; + } + + get type() { + return "css self local identifier"; + } + + get category() { + return "self"; + } + + /** + * @returns {string | null} an identifier to merge equal requests + */ + getResourceIdentifier() { + return "self"; + } + + /** + * Returns the exported names + * @param {ModuleGraph} moduleGraph module graph + * @returns {ExportsSpec | undefined} export names + */ + getExports(moduleGraph) { + if (this.declaredSet && !this.declaredSet.has(this.name)) return; + return super.getExports(moduleGraph); + } + + /** + * Returns list of exports referenced by this dependency + * @param {ModuleGraph} moduleGraph module graph + * @param {RuntimeSpec} runtime the runtime for which the module is analysed + * @returns {(string[] | ReferencedExport)[]} referenced exports + */ + getReferencedExports(moduleGraph, runtime) { + if (this.declaredSet && !this.declaredSet.has(this.name)) + return Dependency.NO_EXPORTS_REFERENCED; + return [[this.name]]; + } + + /** + * @param {ObjectSerializerContext} context context + */ + serialize(context) { + const { write } = context; + write(this.declaredSet); + super.serialize(context); + } + + /** + * @param {ObjectDeserializerContext} context context + */ + deserialize(context) { + const { read } = context; + this.declaredSet = read(); + super.deserialize(context); + } +} + +CssSelfLocalIdentifierDependency.Template = class CssSelfLocalIdentifierDependencyTemplate extends ( + CssLocalIdentifierDependency.Template +) { + /** + * @param {Dependency} dependency the dependency for which the template should be applied + * @param {ReplaceSource} source the current replace source which can be modified + * @param {DependencyTemplateContext} templateContext the context object + * @returns {void} + */ + apply(dependency, source, templateContext) { + const dep = /** @type {CssSelfLocalIdentifierDependency} */ (dependency); + if (dep.declaredSet && !dep.declaredSet.has(dep.name)) return; + super.apply(dependency, source, templateContext); + } +}; + +makeSerializable( + CssSelfLocalIdentifierDependency, + "webpack/lib/dependencies/CssSelfLocalIdentifierDependency" +); + +module.exports = CssSelfLocalIdentifierDependency; diff --git a/lib/dependencies/CssUrlDependency.js b/lib/dependencies/CssUrlDependency.js new file mode 100644 index 00000000000..15fc53aae8e --- /dev/null +++ b/lib/dependencies/CssUrlDependency.js @@ -0,0 +1,164 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Ivan Kopeykin @vankop +*/ + +"use strict"; + +const RawDataUrlModule = require("../asset/RawDataUrlModule"); +const makeSerializable = require("../util/makeSerializable"); +const memoize = require("../util/memoize"); +const ModuleDependency = require("./ModuleDependency"); + +/** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */ +/** @typedef {import("../ChunkGraph")} ChunkGraph */ +/** @typedef {import("../Dependency")} Dependency */ +/** @typedef {import("../Dependency").UpdateHashContext} UpdateHashContext */ +/** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */ +/** @typedef {import("../Module")} Module */ +/** @typedef {import("../ModuleGraph")} ModuleGraph */ +/** @typedef {import("../ModuleGraphConnection")} ModuleGraphConnection */ +/** @typedef {import("../ModuleGraphConnection").ConnectionState} ConnectionState */ +/** @typedef {import("../javascript/JavascriptParser").Range} Range */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */ +/** @typedef {import("../util/Hash")} Hash */ +/** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */ + +const getIgnoredRawDataUrlModule = memoize( + () => new RawDataUrlModule("data:,", "ignored-asset", "(ignored asset)") +); + +class CssUrlDependency extends ModuleDependency { + /** + * @param {string} request request + * @param {Range} range range of the argument + * @param {"string" | "url"} urlType dependency type e.g. url() or string + */ + constructor(request, range, urlType) { + super(request); + this.range = range; + this.urlType = urlType; + } + + get type() { + return "css url()"; + } + + get category() { + return "url"; + } + + /** + * @param {string} context context directory + * @returns {Module | null} a module + */ + createIgnoredModule(context) { + return getIgnoredRawDataUrlModule(); + } + + /** + * @param {ObjectSerializerContext} context context + */ + serialize(context) { + const { write } = context; + write(this.urlType); + super.serialize(context); + } + + /** + * @param {ObjectDeserializerContext} context context + */ + deserialize(context) { + const { read } = context; + this.urlType = read(); + super.deserialize(context); + } +} + +/** + * @param {string} str string + * @returns {string} string in quotes if needed + */ +const cssEscapeString = str => { + let countWhiteOrBracket = 0; + let countQuotation = 0; + let countApostrophe = 0; + for (let i = 0; i < str.length; i++) { + const cc = str.charCodeAt(i); + switch (cc) { + case 9: // tab + case 10: // nl + case 32: // space + case 40: // ( + case 41: // ) + countWhiteOrBracket++; + break; + case 34: + countQuotation++; + break; + case 39: + countApostrophe++; + break; + } + } + if (countWhiteOrBracket < 2) { + return str.replace(/[\n\t ()'"\\]/g, m => `\\${m}`); + } else if (countQuotation <= countApostrophe) { + return `"${str.replace(/[\n"\\]/g, m => `\\${m}`)}"`; + } + return `'${str.replace(/[\n'\\]/g, m => `\\${m}`)}'`; +}; + +CssUrlDependency.Template = class CssUrlDependencyTemplate extends ( + ModuleDependency.Template +) { + /** + * @param {Dependency} dependency the dependency for which the template should be applied + * @param {ReplaceSource} source the current replace source which can be modified + * @param {DependencyTemplateContext} templateContext the context object + * @returns {void} + */ + apply( + dependency, + source, + { moduleGraph, runtimeTemplate, codeGenerationResults } + ) { + const dep = /** @type {CssUrlDependency} */ (dependency); + const module = /** @type {Module} */ (moduleGraph.getModule(dep)); + + /** @type {string | undefined} */ + let newValue; + + switch (dep.urlType) { + case "string": + newValue = cssEscapeString( + runtimeTemplate.assetUrl({ + module, + codeGenerationResults + }) + ); + break; + case "url": + newValue = `url(${cssEscapeString( + runtimeTemplate.assetUrl({ + module, + codeGenerationResults + }) + )})`; + break; + } + + source.replace( + dep.range[0], + dep.range[1] - 1, + /** @type {string} */ (newValue) + ); + } +}; + +makeSerializable(CssUrlDependency, "webpack/lib/dependencies/CssUrlDependency"); + +CssUrlDependency.PUBLIC_PATH_AUTO = "__WEBPACK_CSS_PUBLIC_PATH_AUTO__"; + +module.exports = CssUrlDependency; diff --git a/lib/dependencies/DelegatedSourceDependency.js b/lib/dependencies/DelegatedSourceDependency.js index 238c62d00de..737f60e7727 100644 --- a/lib/dependencies/DelegatedSourceDependency.js +++ b/lib/dependencies/DelegatedSourceDependency.js @@ -9,6 +9,9 @@ const makeSerializable = require("../util/makeSerializable"); const ModuleDependency = require("./ModuleDependency"); class DelegatedSourceDependency extends ModuleDependency { + /** + * @param {string} request the request string + */ constructor(request) { super(request); } diff --git a/lib/dependencies/DllEntryDependency.js b/lib/dependencies/DllEntryDependency.js index 1c3feee83f8..74697042150 100644 --- a/lib/dependencies/DllEntryDependency.js +++ b/lib/dependencies/DllEntryDependency.js @@ -8,7 +8,15 @@ const Dependency = require("../Dependency"); const makeSerializable = require("../util/makeSerializable"); +/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */ +/** @typedef {import("./EntryDependency")} EntryDependency */ + class DllEntryDependency extends Dependency { + /** + * @param {EntryDependency[]} dependencies dependencies + * @param {string} name name + */ constructor(dependencies, name) { super(); @@ -20,6 +28,9 @@ class DllEntryDependency extends Dependency { return "dll entry"; } + /** + * @param {ObjectSerializerContext} context context + */ serialize(context) { const { write } = context; @@ -29,6 +40,9 @@ class DllEntryDependency extends Dependency { super.serialize(context); } + /** + * @param {ObjectDeserializerContext} context context + */ deserialize(context) { const { read } = context; diff --git a/lib/dependencies/DynamicExports.js b/lib/dependencies/DynamicExports.js index 7b3a827c1b8..cdc5e9c9820 100644 --- a/lib/dependencies/DynamicExports.js +++ b/lib/dependencies/DynamicExports.js @@ -5,6 +5,7 @@ "use strict"; +/** @typedef {import("../Module").BuildMeta} BuildMeta */ /** @typedef {import("../Parser").ParserState} ParserState */ /** @type {WeakMap} */ @@ -14,12 +15,13 @@ const parserStateExportsState = new WeakMap(); * @param {ParserState} parserState parser state * @returns {void} */ -exports.bailout = parserState => { +module.exports.bailout = parserState => { const value = parserStateExportsState.get(parserState); parserStateExportsState.set(parserState, false); if (value === true) { - parserState.module.buildMeta.exportsType = undefined; - parserState.module.buildMeta.defaultObject = false; + const buildMeta = /** @type {BuildMeta} */ (parserState.module.buildMeta); + buildMeta.exportsType = undefined; + buildMeta.defaultObject = false; } }; @@ -27,13 +29,14 @@ exports.bailout = parserState => { * @param {ParserState} parserState parser state * @returns {void} */ -exports.enable = parserState => { +module.exports.enable = parserState => { const value = parserStateExportsState.get(parserState); if (value === false) return; parserStateExportsState.set(parserState, true); if (value !== true) { - parserState.module.buildMeta.exportsType = "default"; - parserState.module.buildMeta.defaultObject = "redirect"; + const buildMeta = /** @type {BuildMeta} */ (parserState.module.buildMeta); + buildMeta.exportsType = "default"; + buildMeta.defaultObject = "redirect"; } }; @@ -41,10 +44,10 @@ exports.enable = parserState => { * @param {ParserState} parserState parser state * @returns {void} */ -exports.setFlagged = parserState => { +module.exports.setFlagged = parserState => { const value = parserStateExportsState.get(parserState); if (value !== true) return; - const buildMeta = parserState.module.buildMeta; + const buildMeta = /** @type {BuildMeta} */ (parserState.module.buildMeta); if (buildMeta.exportsType === "dynamic") return; buildMeta.exportsType = "flagged"; }; @@ -53,17 +56,18 @@ exports.setFlagged = parserState => { * @param {ParserState} parserState parser state * @returns {void} */ -exports.setDynamic = parserState => { +module.exports.setDynamic = parserState => { const value = parserStateExportsState.get(parserState); if (value !== true) return; - parserState.module.buildMeta.exportsType = "dynamic"; + /** @type {BuildMeta} */ + (parserState.module.buildMeta).exportsType = "dynamic"; }; /** * @param {ParserState} parserState parser state * @returns {boolean} true, when enabled */ -exports.isEnabled = parserState => { +module.exports.isEnabled = parserState => { const value = parserStateExportsState.get(parserState); return value === true; }; diff --git a/lib/dependencies/ExportsInfoDependency.js b/lib/dependencies/ExportsInfoDependency.js index 5aa28e5d4e8..70383e25d3a 100644 --- a/lib/dependencies/ExportsInfoDependency.js +++ b/lib/dependencies/ExportsInfoDependency.js @@ -16,19 +16,22 @@ const NullDependency = require("./NullDependency"); /** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */ /** @typedef {import("../Module")} Module */ /** @typedef {import("../ModuleGraph")} ModuleGraph */ +/** @typedef {import("../javascript/JavascriptParser").Range} Range */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */ /** @typedef {import("../util/Hash")} Hash */ /** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */ /** * @param {ModuleGraph} moduleGraph the module graph * @param {Module} module the module - * @param {string | null} exportName name of the export if any + * @param {string[] | null} _exportName name of the export if any * @param {string | null} property name of the requested property * @param {RuntimeSpec} runtime for which runtime * @returns {any} value of the property */ -const getProperty = (moduleGraph, module, exportName, property, runtime) => { - if (!exportName) { +const getProperty = (moduleGraph, module, _exportName, property, runtime) => { + if (!_exportName) { switch (property) { case "usedExports": { const usedExports = moduleGraph @@ -45,7 +48,14 @@ const getProperty = (moduleGraph, module, exportName, property, runtime) => { } } } + const exportName = /** @type {string[]} */ (_exportName); switch (property) { + case "canMangle": { + const exportsInfo = moduleGraph.getExportsInfo(module); + const exportInfo = exportsInfo.getReadOnlyExportInfoRecursive(exportName); + if (exportInfo) return exportInfo.canMangle; + return exportsInfo.otherExportsInfo.canMangle; + } case "used": return ( moduleGraph.getExportsInfo(module).getUsed(exportName, runtime) !== @@ -62,7 +72,7 @@ const getProperty = (moduleGraph, module, exportName, property, runtime) => { case UsageState.Unused: return false; case UsageState.NoInfo: - return undefined; + return; case UsageState.Unknown: return null; default: @@ -72,10 +82,14 @@ const getProperty = (moduleGraph, module, exportName, property, runtime) => { case "provideInfo": return moduleGraph.getExportsInfo(module).isExportProvided(exportName); } - return undefined; }; class ExportsInfoDependency extends NullDependency { + /** + * @param {Range} range range + * @param {string[] | null} exportName export name + * @param {string | null} property property + */ constructor(range, exportName, property) { super(); this.range = range; @@ -83,6 +97,9 @@ class ExportsInfoDependency extends NullDependency { this.property = property; } + /** + * @param {ObjectSerializerContext} context context + */ serialize(context) { const { write } = context; write(this.range); @@ -91,6 +108,10 @@ class ExportsInfoDependency extends NullDependency { super.serialize(context); } + /** + * @param {ObjectDeserializerContext} context context + * @returns {ExportsInfoDependency} ExportsInfoDependency + */ static deserialize(context) { const obj = new ExportsInfoDependency( context.read(), diff --git a/lib/dependencies/ExternalModuleDependency.js b/lib/dependencies/ExternalModuleDependency.js new file mode 100644 index 00000000000..ce3e3785846 --- /dev/null +++ b/lib/dependencies/ExternalModuleDependency.js @@ -0,0 +1,109 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Ivan Kopeykin @vankop +*/ + +"use strict"; + +const makeSerializable = require("../util/makeSerializable"); +const CachedConstDependency = require("./CachedConstDependency"); +const ExternalModuleInitFragment = require("./ExternalModuleInitFragment"); + +/** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */ +/** @typedef {import("../Dependency")} Dependency */ +/** @typedef {import("../Dependency").UpdateHashContext} UpdateHashContext */ +/** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */ +/** @typedef {import("../javascript/JavascriptModulesPlugin").ChunkRenderContext} ChunkRenderContext */ +/** @typedef {import("../javascript/JavascriptParser").Range} Range */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */ +/** @typedef {import("../util/Hash")} Hash */ + +class ExternalModuleDependency extends CachedConstDependency { + /** + * @param {string} module module + * @param {{ name: string, value: string }[]} importSpecifiers import specifiers + * @param {string | undefined} defaultImport default import + * @param {string} expression expression + * @param {Range} range range + * @param {string} identifier identifier + */ + constructor( + module, + importSpecifiers, + defaultImport, + expression, + range, + identifier + ) { + super(expression, range, identifier); + + this.importedModule = module; + this.specifiers = importSpecifiers; + this.default = defaultImport; + } + + /** + * @returns {string} hash update + */ + _createHashUpdate() { + return `${this.importedModule}${JSON.stringify(this.specifiers)}${ + this.default || "null" + }${super._createHashUpdate()}`; + } + + /** + * @param {ObjectSerializerContext} context context + */ + serialize(context) { + super.serialize(context); + const { write } = context; + write(this.importedModule); + write(this.specifiers); + write(this.default); + } + + /** + * @param {ObjectDeserializerContext} context context + */ + deserialize(context) { + super.deserialize(context); + const { read } = context; + this.importedModule = read(); + this.specifiers = read(); + this.default = read(); + } +} + +makeSerializable( + ExternalModuleDependency, + "webpack/lib/dependencies/ExternalModuleDependency" +); + +ExternalModuleDependency.Template = class ExternalModuleDependencyTemplate extends ( + CachedConstDependency.Template +) { + /** + * @param {Dependency} dependency the dependency for which the template should be applied + * @param {ReplaceSource} source the current replace source which can be modified + * @param {DependencyTemplateContext} templateContext the context object + * @returns {void} + */ + apply(dependency, source, templateContext) { + super.apply(dependency, source, templateContext); + const dep = /** @type {ExternalModuleDependency} */ (dependency); + const { chunkInitFragments, runtimeTemplate } = templateContext; + + chunkInitFragments.push( + new ExternalModuleInitFragment( + `${runtimeTemplate.supportNodePrefixForCoreModules() ? "node:" : ""}${ + dep.importedModule + }`, + dep.specifiers, + dep.default + ) + ); + } +}; + +module.exports = ExternalModuleDependency; diff --git a/lib/dependencies/ExternalModuleInitFragment.js b/lib/dependencies/ExternalModuleInitFragment.js new file mode 100644 index 00000000000..41bbe538e14 --- /dev/null +++ b/lib/dependencies/ExternalModuleInitFragment.js @@ -0,0 +1,133 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Ivan Kopeykin @vankop +*/ + +"use strict"; + +const InitFragment = require("../InitFragment"); +const makeSerializable = require("../util/makeSerializable"); + +/** @typedef {import("webpack-sources").Source} Source */ +/** @typedef {import("../Generator").GenerateContext} GenerateContext */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */ +/** @typedef {Map>} ImportSpecifiers */ + +/** + * @extends {InitFragment} + */ +class ExternalModuleInitFragment extends InitFragment { + /** + * @param {string} importedModule imported module + * @param {Array<{ name: string, value?: string }> | ImportSpecifiers} specifiers import specifiers + * @param {string=} defaultImport default import + */ + constructor(importedModule, specifiers, defaultImport) { + super( + undefined, + InitFragment.STAGE_CONSTANTS, + 0, + `external module imports|${importedModule}|${defaultImport || "null"}` + ); + this.importedModule = importedModule; + if (Array.isArray(specifiers)) { + /** @type {ImportSpecifiers} */ + this.specifiers = new Map(); + for (const { name, value } of specifiers) { + let specifiers = this.specifiers.get(name); + if (!specifiers) { + specifiers = new Set(); + this.specifiers.set(name, specifiers); + } + specifiers.add(value || name); + } + } else { + this.specifiers = specifiers; + } + this.defaultImport = defaultImport; + } + + /** + * @param {ExternalModuleInitFragment} other other + * @returns {ExternalModuleInitFragment} ExternalModuleInitFragment + */ + merge(other) { + const newSpecifiersMap = new Map(this.specifiers); + for (const [name, specifiers] of other.specifiers) { + if (newSpecifiersMap.has(name)) { + const currentSpecifiers = + /** @type {Set} */ + (newSpecifiersMap.get(name)); + for (const spec of specifiers) currentSpecifiers.add(spec); + } else { + newSpecifiersMap.set(name, specifiers); + } + } + return new ExternalModuleInitFragment( + this.importedModule, + newSpecifiersMap, + this.defaultImport + ); + } + + /** + * @param {GenerateContext} context context + * @returns {string | Source | undefined} the source code that will be included as initialization code + */ + getContent({ runtimeRequirements }) { + const namedImports = []; + + for (const [name, specifiers] of this.specifiers) { + for (const spec of specifiers) { + if (spec === name) { + namedImports.push(name); + } else { + namedImports.push(`${name} as ${spec}`); + } + } + } + + let importsString = + namedImports.length > 0 ? `{${namedImports.join(",")}}` : ""; + + if (this.defaultImport) { + importsString = `${this.defaultImport}${ + importsString ? `, ${importsString}` : "" + }`; + } + + return `import ${importsString} from ${JSON.stringify( + this.importedModule + )};`; + } + + /** + * @param {ObjectSerializerContext} context context + */ + serialize(context) { + super.serialize(context); + const { write } = context; + write(this.importedModule); + write(this.specifiers); + write(this.defaultImport); + } + + /** + * @param {ObjectDeserializerContext} context context + */ + deserialize(context) { + super.deserialize(context); + const { read } = context; + this.importedModule = read(); + this.specifiers = read(); + this.defaultImport = read(); + } +} + +makeSerializable( + ExternalModuleInitFragment, + "webpack/lib/dependencies/ExternalModuleInitFragment" +); + +module.exports = ExternalModuleInitFragment; diff --git a/lib/dependencies/HarmonyAcceptDependency.js b/lib/dependencies/HarmonyAcceptDependency.js index 560d9bb32ea..4817b722d7e 100644 --- a/lib/dependencies/HarmonyAcceptDependency.js +++ b/lib/dependencies/HarmonyAcceptDependency.js @@ -13,11 +13,14 @@ const NullDependency = require("./NullDependency"); /** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */ /** @typedef {import("../Dependency")} Dependency */ /** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */ +/** @typedef {import("../javascript/JavascriptParser").Range} Range */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */ /** @typedef {import("./HarmonyAcceptImportDependency")} HarmonyAcceptImportDependency */ class HarmonyAcceptDependency extends NullDependency { /** - * @param {[number, number]} range expression range + * @param {Range} range expression range * @param {HarmonyAcceptImportDependency[]} dependencies import dependencies * @param {boolean} hasCallback true, if the range wraps an existing callback */ @@ -32,6 +35,9 @@ class HarmonyAcceptDependency extends NullDependency { return "accepted harmony modules"; } + /** + * @param {ObjectSerializerContext} context context + */ serialize(context) { const { write } = context; write(this.range); @@ -40,6 +46,9 @@ class HarmonyAcceptDependency extends NullDependency { super.serialize(context); } + /** + * @param {ObjectDeserializerContext} context context + */ deserialize(context) { const { read } = context; this.range = read(); @@ -82,7 +91,7 @@ HarmonyAcceptDependency.Template = class HarmonyAcceptDependencyTemplate extends ? HarmonyImportDependency.Template.getImportEmittedRuntime( module, referencedModule - ) + ) : false }; }) diff --git a/lib/dependencies/HarmonyAcceptImportDependency.js b/lib/dependencies/HarmonyAcceptImportDependency.js index 12040a4ee02..03cb0002ddc 100644 --- a/lib/dependencies/HarmonyAcceptImportDependency.js +++ b/lib/dependencies/HarmonyAcceptImportDependency.js @@ -7,14 +7,18 @@ const makeSerializable = require("../util/makeSerializable"); const HarmonyImportDependency = require("./HarmonyImportDependency"); +const NullDependency = require("./NullDependency"); /** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */ /** @typedef {import("../Dependency")} Dependency */ /** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */ class HarmonyAcceptImportDependency extends HarmonyImportDependency { + /** + * @param {string} request the request string + */ constructor(request) { - super(request, NaN); + super(request, Number.NaN); this.weak = true; } @@ -28,8 +32,9 @@ makeSerializable( "webpack/lib/dependencies/HarmonyAcceptImportDependency" ); -HarmonyAcceptImportDependency.Template = class HarmonyAcceptImportDependencyTemplate extends ( - HarmonyImportDependency.Template -) {}; +HarmonyAcceptImportDependency.Template = + /** @type {typeof HarmonyImportDependency.Template} */ ( + NullDependency.Template + ); module.exports = HarmonyAcceptImportDependency; diff --git a/lib/dependencies/HarmonyCompatibilityDependency.js b/lib/dependencies/HarmonyCompatibilityDependency.js index 24508bb714e..5464f91b1f0 100644 --- a/lib/dependencies/HarmonyCompatibilityDependency.js +++ b/lib/dependencies/HarmonyCompatibilityDependency.js @@ -15,6 +15,7 @@ const NullDependency = require("./NullDependency"); /** @typedef {import("../Dependency")} Dependency */ /** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */ /** @typedef {import("../Module")} Module */ +/** @typedef {import("../Module").BuildMeta} BuildMeta */ class HarmonyCompatibilityDependency extends NullDependency { get type() { @@ -74,14 +75,14 @@ HarmonyCompatibilityDependency.Template = class HarmonyExportDependencyTemplate initFragments.push( new InitFragment( runtimeTemplate.supportsArrowFunction() - ? `${RuntimeGlobals.asyncModule}(${module.moduleArgument}, async (__webpack_handle_async_dependencies__) => {\n` - : `${RuntimeGlobals.asyncModule}(${module.moduleArgument}, async function (__webpack_handle_async_dependencies__) {\n`, + ? `${RuntimeGlobals.asyncModule}(${module.moduleArgument}, async (__webpack_handle_async_dependencies__, __webpack_async_result__) => { try {\n` + : `${RuntimeGlobals.asyncModule}(${module.moduleArgument}, async function (__webpack_handle_async_dependencies__, __webpack_async_result__) { try {\n`, InitFragment.STAGE_ASYNC_BOUNDARY, 0, undefined, - module.buildMeta.async - ? `\n__webpack_handle_async_dependencies__();\n}, 1);` - : "\n});" + `\n__webpack_async_result__();\n} catch(e) { __webpack_async_result__(e); } }${ + /** @type {BuildMeta} */ (module.buildMeta).async ? ", 1" : "" + });` ) ); } diff --git a/lib/dependencies/HarmonyDetectionParserPlugin.js b/lib/dependencies/HarmonyDetectionParserPlugin.js index a9ea918ea8c..4cf84fc1ec5 100644 --- a/lib/dependencies/HarmonyDetectionParserPlugin.js +++ b/lib/dependencies/HarmonyDetectionParserPlugin.js @@ -5,19 +5,33 @@ "use strict"; +const EnvironmentNotSupportAsyncWarning = require("../EnvironmentNotSupportAsyncWarning"); +const { JAVASCRIPT_MODULE_TYPE_ESM } = require("../ModuleTypeConstants"); const DynamicExports = require("./DynamicExports"); const HarmonyCompatibilityDependency = require("./HarmonyCompatibilityDependency"); const HarmonyExports = require("./HarmonyExports"); +/** @typedef {import("../Module").BuildMeta} BuildMeta */ +/** @typedef {import("../javascript/JavascriptParser")} JavascriptParser */ +/** @typedef {import("./HarmonyModulesPlugin").HarmonyModulesPluginOptions} HarmonyModulesPluginOptions */ + module.exports = class HarmonyDetectionParserPlugin { + /** + * @param {HarmonyModulesPluginOptions} options options + */ constructor(options) { const { topLevelAwait = false } = options || {}; this.topLevelAwait = topLevelAwait; } + /** + * @param {JavascriptParser} parser the parser + * @returns {void} + */ apply(parser) { parser.hooks.program.tap("HarmonyDetectionParserPlugin", ast => { - const isStrictHarmony = parser.state.module.type === "javascript/esm"; + const isStrictHarmony = + parser.state.module.type === JAVASCRIPT_MODULE_TYPE_ESM; const isHarmony = isStrictHarmony || ast.body.some( @@ -52,7 +66,7 @@ module.exports = class HarmonyDetectionParserPlugin { const module = parser.state.module; if (!this.topLevelAwait) { throw new Error( - "The top-level-await experiment is not enabled (set experiments.topLevelAwait: true to enabled it)" + "The top-level-await experiment is not enabled (set experiments.topLevelAwait: true to enable it)" ); } if (!HarmonyExports.isEnabled(parser.state)) { @@ -60,15 +74,27 @@ module.exports = class HarmonyDetectionParserPlugin { "Top-level-await is only supported in EcmaScript Modules" ); } - module.buildMeta.async = true; + /** @type {BuildMeta} */ + (module.buildMeta).async = true; + EnvironmentNotSupportAsyncWarning.check( + module, + parser.state.compilation.runtimeTemplate, + "topLevelAwait" + ); }); + /** + * @returns {boolean | undefined} true if in harmony + */ const skipInHarmony = () => { if (HarmonyExports.isEnabled(parser.state)) { return true; } }; + /** + * @returns {null | undefined} null if in harmony + */ const nullInHarmony = () => { if (HarmonyExports.isEnabled(parser.state)) { return null; diff --git a/lib/dependencies/HarmonyEvaluatedImportSpecifierDependency.js b/lib/dependencies/HarmonyEvaluatedImportSpecifierDependency.js new file mode 100644 index 00000000000..09ceb8e4aa0 --- /dev/null +++ b/lib/dependencies/HarmonyEvaluatedImportSpecifierDependency.js @@ -0,0 +1,152 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Ivan Kopeykin @vankop +*/ + +"use strict"; + +const makeSerializable = require("../util/makeSerializable"); +const HarmonyImportSpecifierDependency = require("./HarmonyImportSpecifierDependency"); + +/** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */ +/** @typedef {import("../ChunkGraph")} ChunkGraph */ +/** @typedef {import("../Dependency")} Dependency */ +/** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */ +/** @typedef {import("../Module").BuildMeta} BuildMeta */ +/** @typedef {import("../ModuleGraphConnection")} ModuleGraphConnection */ +/** @typedef {import("../javascript/JavascriptParser").ImportAttributes} ImportAttributes */ +/** @typedef {import("../javascript/JavascriptParser").Range} Range */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */ + +/** + * Dependency for static evaluating import specifier. e.g. + * @example + * import a from "a"; + * "x" in a; + * a.x !== undefined; // if x value statically analyzable + */ +class HarmonyEvaluatedImportSpecifierDependency extends HarmonyImportSpecifierDependency { + /** + * @param {string} request the request string + * @param {number} sourceOrder source order + * @param {TODO} ids ids + * @param {TODO} name name + * @param {Range} range location in source code + * @param {ImportAttributes} attributes import assertions + * @param {string} operator operator + */ + constructor(request, sourceOrder, ids, name, range, attributes, operator) { + super(request, sourceOrder, ids, name, range, false, attributes, []); + this.operator = operator; + } + + get type() { + return `evaluated X ${this.operator} harmony import specifier`; + } + + /** + * @param {ObjectSerializerContext} context context + */ + serialize(context) { + super.serialize(context); + const { write } = context; + write(this.operator); + } + + /** + * @param {ObjectDeserializerContext} context context + */ + deserialize(context) { + super.deserialize(context); + const { read } = context; + this.operator = read(); + } +} + +makeSerializable( + HarmonyEvaluatedImportSpecifierDependency, + "webpack/lib/dependencies/HarmonyEvaluatedImportSpecifierDependency" +); + +HarmonyEvaluatedImportSpecifierDependency.Template = class HarmonyEvaluatedImportSpecifierDependencyTemplate extends ( + HarmonyImportSpecifierDependency.Template +) { + /** + * @param {Dependency} dependency the dependency for which the template should be applied + * @param {ReplaceSource} source the current replace source which can be modified + * @param {DependencyTemplateContext} templateContext the context object + * @returns {void} + */ + apply(dependency, source, templateContext) { + const dep = /** @type {HarmonyEvaluatedImportSpecifierDependency} */ ( + dependency + ); + const { module, moduleGraph, runtime } = templateContext; + const connection = moduleGraph.getConnection(dep); + // Skip rendering depending when dependency is conditional + if (connection && !connection.isTargetActive(runtime)) return; + + const exportsInfo = moduleGraph.getExportsInfo( + /** @type {ModuleGraphConnection} */ (connection).module + ); + const ids = dep.getIds(moduleGraph); + + let value; + + const exportsType = + /** @type {ModuleGraphConnection} */ + (connection).module.getExportsType( + moduleGraph, + /** @type {BuildMeta} */ + (module.buildMeta).strictHarmonyModule + ); + switch (exportsType) { + case "default-with-named": { + if (ids[0] === "default") { + value = + ids.length === 1 || exportsInfo.isExportProvided(ids.slice(1)); + } else { + value = exportsInfo.isExportProvided(ids); + } + break; + } + case "namespace": { + value = + ids[0] === "__esModule" + ? ids.length === 1 || undefined + : exportsInfo.isExportProvided(ids); + break; + } + case "dynamic": { + if (ids[0] !== "default") { + value = exportsInfo.isExportProvided(ids); + } + break; + } + // default-only could lead to runtime error, when default value is primitive + } + + if (typeof value === "boolean") { + source.replace(dep.range[0], dep.range[1] - 1, ` ${value}`); + } else { + const usedName = exportsInfo.getUsedName(ids, runtime); + + const code = this._getCodeForIds( + dep, + source, + templateContext, + ids.slice(0, -1) + ); + source.replace( + dep.range[0], + dep.range[1] - 1, + `${ + usedName ? JSON.stringify(usedName[usedName.length - 1]) : '""' + } in ${code}` + ); + } + } +}; + +module.exports = HarmonyEvaluatedImportSpecifierDependency; diff --git a/lib/dependencies/HarmonyExportDependencyParserPlugin.js b/lib/dependencies/HarmonyExportDependencyParserPlugin.js index 2e9a4bd7b53..0978a5a242e 100644 --- a/lib/dependencies/HarmonyExportDependencyParserPlugin.js +++ b/lib/dependencies/HarmonyExportDependencyParserPlugin.js @@ -11,25 +11,53 @@ const HarmonyExportExpressionDependency = require("./HarmonyExportExpressionDepe const HarmonyExportHeaderDependency = require("./HarmonyExportHeaderDependency"); const HarmonyExportImportedSpecifierDependency = require("./HarmonyExportImportedSpecifierDependency"); const HarmonyExportSpecifierDependency = require("./HarmonyExportSpecifierDependency"); +const { ExportPresenceModes } = require("./HarmonyImportDependency"); const { - harmonySpecifierTag + harmonySpecifierTag, + getAttributes } = require("./HarmonyImportDependencyParserPlugin"); const HarmonyImportSideEffectDependency = require("./HarmonyImportSideEffectDependency"); +/** @typedef {import("../Dependency").DependencyLocation} DependencyLocation */ +/** @typedef {import("../javascript/JavascriptParser")} JavascriptParser */ +/** @typedef {import("../javascript/JavascriptParser").FunctionDeclaration} FunctionDeclaration */ +/** @typedef {import("../javascript/JavascriptParser").Range} Range */ + +const { HarmonyStarExportsList } = HarmonyExportImportedSpecifierDependency; + module.exports = class HarmonyExportDependencyParserPlugin { + /** + * @param {import("../../declarations/WebpackOptions").JavascriptParserOptions} options options + */ constructor(options) { - this.strictExportPresence = options.strictExportPresence; + this.exportPresenceMode = + options.reexportExportsPresence !== undefined + ? ExportPresenceModes.fromUserOption(options.reexportExportsPresence) + : options.exportsPresence !== undefined + ? ExportPresenceModes.fromUserOption(options.exportsPresence) + : options.strictExportPresence + ? ExportPresenceModes.ERROR + : ExportPresenceModes.AUTO; } + /** + * @param {JavascriptParser} parser the parser + * @returns {void} + */ apply(parser) { + const { exportPresenceMode } = this; parser.hooks.export.tap( "HarmonyExportDependencyParserPlugin", statement => { const dep = new HarmonyExportHeaderDependency( - statement.declaration && statement.declaration.range, - statement.range + /** @type {Range | false} */ ( + statement.declaration && statement.declaration.range + ), + /** @type {Range} */ (statement.range) + ); + dep.loc = Object.create( + /** @type {DependencyLocation} */ (statement.loc) ); - dep.loc = Object.create(statement.loc); dep.loc.index = -1; parser.state.module.addPresentationalDependency(dep); return true; @@ -40,15 +68,21 @@ module.exports = class HarmonyExportDependencyParserPlugin { (statement, source) => { parser.state.lastHarmonyImportOrder = (parser.state.lastHarmonyImportOrder || 0) + 1; - const clearDep = new ConstDependency("", statement.range); - clearDep.loc = Object.create(statement.loc); + const clearDep = new ConstDependency( + "", + /** @type {Range} */ (statement.range) + ); + clearDep.loc = /** @type {DependencyLocation} */ (statement.loc); clearDep.loc.index = -1; parser.state.module.addPresentationalDependency(clearDep); const sideEffectDep = new HarmonyImportSideEffectDependency( - source, - parser.state.lastHarmonyImportOrder + /** @type {string} */ (source), + parser.state.lastHarmonyImportOrder, + getAttributes(statement) + ); + sideEffectDep.loc = Object.create( + /** @type {DependencyLocation} */ (statement.loc) ); - sideEffectDep.loc = Object.create(statement.loc); sideEffectDep.loc.index = -1; parser.state.current.addDependency(sideEffectDep); return true; @@ -58,13 +92,12 @@ module.exports = class HarmonyExportDependencyParserPlugin { "HarmonyExportDependencyParserPlugin", (statement, expr) => { const isFunctionDeclaration = expr.type === "FunctionDeclaration"; - const comments = parser.getComments([ - statement.range[0], - expr.range[0] - ]); + const exprRange = /** @type {Range} */ (expr.range); + const statementRange = /** @type {Range} */ (statement.range); + const comments = parser.getComments([statementRange[0], exprRange[0]]); const dep = new HarmonyExportExpressionDependency( - expr.range, - statement.range, + exprRange, + statementRange, comments .map(c => { switch (c.type) { @@ -79,22 +112,23 @@ module.exports = class HarmonyExportDependencyParserPlugin { expr.type.endsWith("Declaration") && expr.id ? expr.id.name : isFunctionDeclaration - ? { - id: expr.id ? expr.id.name : undefined, - range: [ - expr.range[0], - expr.params.length > 0 - ? expr.params[0].range[0] - : expr.body.range[0] - ], - prefix: `${expr.async ? "async " : ""}function${ - expr.generator ? "*" : "" - } `, - suffix: `(${expr.params.length > 0 ? "" : ") "}` - } - : undefined + ? { + range: [ + exprRange[0], + expr.params.length > 0 + ? /** @type {Range} */ (expr.params[0].range)[0] + : /** @type {Range} */ (expr.body.range)[0] + ], + prefix: `${expr.async ? "async " : ""}function${ + expr.generator ? "*" : "" + } `, + suffix: `(${expr.params.length > 0 ? "" : ") "}` + } + : undefined + ); + dep.loc = Object.create( + /** @type {DependencyLocation} */ (statement.loc) ); - dep.loc = Object.create(statement.loc); dep.loc.index = -1; parser.state.current.addDependency(dep); InnerGraph.addVariableUsage( @@ -111,26 +145,34 @@ module.exports = class HarmonyExportDependencyParserPlugin { "HarmonyExportDependencyParserPlugin", (statement, id, name, idx) => { const settings = parser.getTagData(id, harmonySpecifierTag); - let dep; const harmonyNamedExports = (parser.state.harmonyNamedExports = parser.state.harmonyNamedExports || new Set()); harmonyNamedExports.add(name); InnerGraph.addVariableUsage(parser, id, name); - if (settings) { - dep = new HarmonyExportImportedSpecifierDependency( - settings.source, - settings.sourceOrder, - settings.ids, - name, - harmonyNamedExports, - null, - this.strictExportPresence - ); - } else { - dep = new HarmonyExportSpecifierDependency(id, name); - } - dep.loc = Object.create(statement.loc); + const dep = settings + ? new HarmonyExportImportedSpecifierDependency( + settings.source, + settings.sourceOrder, + settings.ids, + name, + harmonyNamedExports, + null, + exportPresenceMode, + null, + settings.assertions + ) + : new HarmonyExportSpecifierDependency(id, name); + dep.loc = Object.create( + /** @type {DependencyLocation} */ (statement.loc) + ); dep.loc.index = idx; + const isAsiSafe = !parser.isAsiPosition( + /** @type {Range} */ + (statement.range)[0] + ); + if (!isAsiSafe) { + parser.setAsiPosition(/** @type {Range} */ (statement.range)[1]); + } parser.state.current.addDependency(dep); return true; } @@ -145,22 +187,32 @@ module.exports = class HarmonyExportDependencyParserPlugin { harmonyNamedExports.add(name); } else { harmonyStarExports = parser.state.harmonyStarExports = - parser.state.harmonyStarExports || []; + parser.state.harmonyStarExports || new HarmonyStarExportsList(); } const dep = new HarmonyExportImportedSpecifierDependency( - source, + /** @type {string} */ (source), parser.state.lastHarmonyImportOrder, id ? [id] : [], name, harmonyNamedExports, harmonyStarExports && harmonyStarExports.slice(), - this.strictExportPresence + exportPresenceMode, + harmonyStarExports ); if (harmonyStarExports) { harmonyStarExports.push(dep); } - dep.loc = Object.create(statement.loc); + dep.loc = Object.create( + /** @type {DependencyLocation} */ (statement.loc) + ); dep.loc.index = idx; + const isAsiSafe = !parser.isAsiPosition( + /** @type {Range} */ + (statement.range)[0] + ); + if (!isAsiSafe) { + parser.setAsiPosition(/** @type {Range} */ (statement.range)[1]); + } parser.state.current.addDependency(dep); return true; } diff --git a/lib/dependencies/HarmonyExportExpressionDependency.js b/lib/dependencies/HarmonyExportExpressionDependency.js index 74e25bc257c..12481cf963c 100644 --- a/lib/dependencies/HarmonyExportExpressionDependency.js +++ b/lib/dependencies/HarmonyExportExpressionDependency.js @@ -8,6 +8,7 @@ const ConcatenationScope = require("../ConcatenationScope"); const RuntimeGlobals = require("../RuntimeGlobals"); const makeSerializable = require("../util/makeSerializable"); +const propertyAccess = require("../util/propertyAccess"); const HarmonyExportInitFragment = require("./HarmonyExportInitFragment"); const NullDependency = require("./NullDependency"); @@ -17,8 +18,17 @@ const NullDependency = require("./NullDependency"); /** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */ /** @typedef {import("../ModuleGraph")} ModuleGraph */ /** @typedef {import("../ModuleGraphConnection").ConnectionState} ConnectionState */ +/** @typedef {import("../javascript/JavascriptParser").Range} Range */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */ class HarmonyExportExpressionDependency extends NullDependency { + /** + * @param {Range} range range + * @param {Range} rangeStatement range statement + * @param {string} prefix prefix + * @param {string | { range: Range, prefix: string, suffix: string }} [declarationId] declaration id + */ constructor(range, rangeStatement, prefix, declarationId) { super(); this.range = range; @@ -39,6 +49,7 @@ class HarmonyExportExpressionDependency extends NullDependency { getExports(moduleGraph) { return { exports: ["default"], + priority: 1, terminalBinding: true, dependencies: undefined }; @@ -53,6 +64,9 @@ class HarmonyExportExpressionDependency extends NullDependency { return false; } + /** + * @param {ObjectSerializerContext} context context + */ serialize(context) { const { write } = context; write(this.range); @@ -62,6 +76,9 @@ class HarmonyExportExpressionDependency extends NullDependency { super.serialize(context); } + /** + * @param {ObjectDeserializerContext} context context + */ deserialize(context) { const { read } = context; this.range = read(); @@ -134,6 +151,7 @@ HarmonyExportExpressionDependency.Template = class HarmonyExportDependencyTempla `/* harmony default export */ ${dep.prefix}` ); } else { + /** @type {string} */ let content; const name = ConcatenationScope.DEFAULT_EXPORT; if (runtimeTemplate.supportsConst()) { @@ -163,9 +181,9 @@ HarmonyExportExpressionDependency.Template = class HarmonyExportDependencyTempla if (used) { runtimeRequirements.add(RuntimeGlobals.exports); // This is a little bit incorrect as TDZ is not correct, but we can't use const. - content = `/* harmony default export */ ${exportsName}[${JSON.stringify( - used - )}] = `; + content = `/* harmony default export */ ${exportsName}${propertyAccess( + typeof used === "string" ? [used] : used + )} = `; } else { content = `/* unused harmony default export */ var ${name} = `; } @@ -175,7 +193,7 @@ HarmonyExportExpressionDependency.Template = class HarmonyExportDependencyTempla source.replace( dep.rangeStatement[0], dep.range[0] - 1, - content + "(" + dep.prefix + `${content}(${dep.prefix}` ); source.replace(dep.range[1], dep.rangeStatement[1] - 0.5, ");"); return; diff --git a/lib/dependencies/HarmonyExportHeaderDependency.js b/lib/dependencies/HarmonyExportHeaderDependency.js index 7dacbecc8a3..ae649796686 100644 --- a/lib/dependencies/HarmonyExportHeaderDependency.js +++ b/lib/dependencies/HarmonyExportHeaderDependency.js @@ -11,8 +11,15 @@ const NullDependency = require("./NullDependency"); /** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */ /** @typedef {import("../Dependency")} Dependency */ /** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */ +/** @typedef {import("../javascript/JavascriptParser").Range} Range */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */ class HarmonyExportHeaderDependency extends NullDependency { + /** + * @param {Range | false} range range + * @param {Range} rangeStatement range statement + */ constructor(range, rangeStatement) { super(); this.range = range; @@ -23,6 +30,9 @@ class HarmonyExportHeaderDependency extends NullDependency { return "harmony export header"; } + /** + * @param {ObjectSerializerContext} context context + */ serialize(context) { const { write } = context; write(this.range); @@ -30,6 +40,9 @@ class HarmonyExportHeaderDependency extends NullDependency { super.serialize(context); } + /** + * @param {ObjectDeserializerContext} context context + */ deserialize(context) { const { read } = context; this.range = read(); diff --git a/lib/dependencies/HarmonyExportImportedSpecifierDependency.js b/lib/dependencies/HarmonyExportImportedSpecifierDependency.js index e3c9e758768..a423ad9763f 100644 --- a/lib/dependencies/HarmonyExportImportedSpecifierDependency.js +++ b/lib/dependencies/HarmonyExportImportedSpecifierDependency.js @@ -5,15 +5,23 @@ "use strict"; +const ConditionalInitFragment = require("../ConditionalInitFragment"); const Dependency = require("../Dependency"); const { UsageState } = require("../ExportsInfo"); const HarmonyLinkingError = require("../HarmonyLinkingError"); const InitFragment = require("../InitFragment"); const RuntimeGlobals = require("../RuntimeGlobals"); const Template = require("../Template"); +const { countIterable } = require("../util/IterableHelpers"); const { first, combine } = require("../util/SetHelpers"); const makeSerializable = require("../util/makeSerializable"); const propertyAccess = require("../util/propertyAccess"); +const { propertyName } = require("../util/propertyName"); +const { + getRuntimeKey, + keyToRuntime, + filterRuntime +} = require("../util/runtime"); const HarmonyExportInitFragment = require("./HarmonyExportInitFragment"); const HarmonyImportDependency = require("./HarmonyImportDependency"); const processExportInfo = require("./processExportInfo"); @@ -21,22 +29,34 @@ const processExportInfo = require("./processExportInfo"); /** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */ /** @typedef {import("../ChunkGraph")} ChunkGraph */ /** @typedef {import("../Dependency").ExportsSpec} ExportsSpec */ +/** @typedef {import("../Dependency").GetConditionFn} GetConditionFn */ /** @typedef {import("../Dependency").ReferencedExport} ReferencedExport */ +/** @typedef {import("../Dependency").TRANSITIVE} TRANSITIVE */ /** @typedef {import("../Dependency").UpdateHashContext} UpdateHashContext */ /** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */ /** @typedef {import("../ExportsInfo")} ExportsInfo */ /** @typedef {import("../ExportsInfo").ExportInfo} ExportInfo */ +/** @typedef {import("../ExportsInfo").UsedName} UsedName */ +/** @typedef {import("../Generator").GenerateContext} GenerateContext */ /** @typedef {import("../Module")} Module */ +/** @typedef {import("../Module").BuildMeta} BuildMeta */ +/** @typedef {import("../Module").RuntimeRequirements} RuntimeRequirements */ /** @typedef {import("../ModuleGraph")} ModuleGraph */ /** @typedef {import("../ModuleGraphConnection")} ModuleGraphConnection */ /** @typedef {import("../ModuleGraphConnection").ConnectionState} ConnectionState */ /** @typedef {import("../RuntimeTemplate")} RuntimeTemplate */ /** @typedef {import("../WebpackError")} WebpackError */ +/** @typedef {import("../javascript/JavascriptParser").ImportAttributes} ImportAttributes */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */ /** @typedef {import("../util/Hash")} Hash */ /** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */ +/** @typedef {import("./processExportInfo").ReferencedExports} ReferencedExports */ /** @typedef {"missing"|"unused"|"empty-star"|"reexport-dynamic-default"|"reexport-named-default"|"reexport-namespace-object"|"reexport-fake-namespace-object"|"reexport-undefined"|"normal-reexport"|"dynamic-reexport"} ExportModeType */ +const { ExportPresenceModes } = HarmonyImportDependency; + const idsSymbol = Symbol("HarmonyExportImportedSpecifierDependency.ids"); class NormalReexportItem { @@ -56,6 +76,9 @@ class NormalReexportItem { } } +/** @typedef {Set} ExportModeIgnored */ +/** @typedef {Set} ExportModeHidden */ + class ExportMode { /** * @param {ExportModeType} type type of the mode @@ -69,17 +92,17 @@ class ExportMode { this.items = null; // for "reexport-named-default" | "reexport-fake-namespace-object" | "reexport-namespace-object" - /** @type {string|null} */ + /** @type {string | null} */ this.name = null; /** @type {ExportInfo | null} */ this.partialNamespaceExportInfo = null; // for "dynamic-reexport": - /** @type {Set | null} */ + /** @type {ExportModeIgnored | null} */ this.ignored = null; // for "dynamic-reexport" | "empty-star": - /** @type {Set | null} */ + /** @type {ExportModeHidden | null} */ this.hidden = null; // for "missing": @@ -92,15 +115,246 @@ class ExportMode { } } +const determineExportAssignments = ( + moduleGraph, + dependencies, + additionalDependency +) => { + const names = new Set(); + const dependencyIndices = []; + + if (additionalDependency) { + dependencies = dependencies.concat(additionalDependency); + } + + for (const dep of dependencies) { + const i = dependencyIndices.length; + dependencyIndices[i] = names.size; + const otherImportedModule = moduleGraph.getModule(dep); + if (otherImportedModule) { + const exportsInfo = moduleGraph.getExportsInfo(otherImportedModule); + for (const exportInfo of exportsInfo.exports) { + if ( + exportInfo.provided === true && + exportInfo.name !== "default" && + !names.has(exportInfo.name) + ) { + names.add(exportInfo.name); + dependencyIndices[i] = names.size; + } + } + } + } + dependencyIndices.push(names.size); + + return { names: Array.from(names), dependencyIndices }; +}; + +const findDependencyForName = ( + { names, dependencyIndices }, + name, + dependencies +) => { + const dependenciesIt = dependencies[Symbol.iterator](); + const dependencyIndicesIt = dependencyIndices[Symbol.iterator](); + let dependenciesItResult = dependenciesIt.next(); + let dependencyIndicesItResult = dependencyIndicesIt.next(); + if (dependencyIndicesItResult.done) return; + for (let i = 0; i < names.length; i++) { + while (i >= dependencyIndicesItResult.value) { + dependenciesItResult = dependenciesIt.next(); + dependencyIndicesItResult = dependencyIndicesIt.next(); + if (dependencyIndicesItResult.done) return; + } + if (names[i] === name) return dependenciesItResult.value; + } + return undefined; +}; + +/** + * @param {ModuleGraph} moduleGraph the module graph + * @param {HarmonyExportImportedSpecifierDependency} dep the dependency + * @param {string} runtimeKey the runtime key + * @returns {ExportMode} the export mode + */ +const getMode = (moduleGraph, dep, runtimeKey) => { + const importedModule = moduleGraph.getModule(dep); + + if (!importedModule) { + const mode = new ExportMode("missing"); + + mode.userRequest = dep.userRequest; + + return mode; + } + + const name = dep.name; + const runtime = keyToRuntime(runtimeKey); + const parentModule = /** @type {Module} */ (moduleGraph.getParentModule(dep)); + const exportsInfo = moduleGraph.getExportsInfo(parentModule); + + if ( + name + ? exportsInfo.getUsed(name, runtime) === UsageState.Unused + : exportsInfo.isUsed(runtime) === false + ) { + const mode = new ExportMode("unused"); + + mode.name = name || "*"; + + return mode; + } + + const importedExportsType = importedModule.getExportsType( + moduleGraph, + /** @type {BuildMeta} */ (parentModule.buildMeta).strictHarmonyModule + ); + + const ids = dep.getIds(moduleGraph); + + // Special handling for reexporting the default export + // from non-namespace modules + if (name && ids.length > 0 && ids[0] === "default") { + switch (importedExportsType) { + case "dynamic": { + const mode = new ExportMode("reexport-dynamic-default"); + + mode.name = name; + + return mode; + } + case "default-only": + case "default-with-named": { + const exportInfo = exportsInfo.getReadOnlyExportInfo(name); + const mode = new ExportMode("reexport-named-default"); + + mode.name = name; + mode.partialNamespaceExportInfo = exportInfo; + + return mode; + } + } + } + + // reexporting with a fixed name + if (name) { + let mode; + const exportInfo = exportsInfo.getReadOnlyExportInfo(name); + + if (ids.length > 0) { + // export { name as name } + switch (importedExportsType) { + case "default-only": + mode = new ExportMode("reexport-undefined"); + mode.name = name; + break; + default: + mode = new ExportMode("normal-reexport"); + mode.items = [ + new NormalReexportItem(name, ids, exportInfo, false, false) + ]; + break; + } + } else { + // export * as name + switch (importedExportsType) { + case "default-only": + mode = new ExportMode("reexport-fake-namespace-object"); + mode.name = name; + mode.partialNamespaceExportInfo = exportInfo; + mode.fakeType = 0; + break; + case "default-with-named": + mode = new ExportMode("reexport-fake-namespace-object"); + mode.name = name; + mode.partialNamespaceExportInfo = exportInfo; + mode.fakeType = 2; + break; + case "dynamic": + default: + mode = new ExportMode("reexport-namespace-object"); + mode.name = name; + mode.partialNamespaceExportInfo = exportInfo; + } + } + + return mode; + } + + // Star reexporting + + const { ignoredExports, exports, checked, hidden } = dep.getStarReexports( + moduleGraph, + runtime, + exportsInfo, + importedModule + ); + if (!exports) { + // We have too few info about the modules + // Delegate the logic to the runtime code + + const mode = new ExportMode("dynamic-reexport"); + mode.ignored = ignoredExports; + mode.hidden = hidden; + + return mode; + } + + if (exports.size === 0) { + const mode = new ExportMode("empty-star"); + mode.hidden = hidden; + + return mode; + } + + const mode = new ExportMode("normal-reexport"); + + mode.items = Array.from( + exports, + exportName => + new NormalReexportItem( + exportName, + [exportName], + exportsInfo.getReadOnlyExportInfo(exportName), + /** @type {Set} */ + (checked).has(exportName), + false + ) + ); + if (hidden !== undefined) { + for (const exportName of hidden) { + mode.items.push( + new NormalReexportItem( + exportName, + [exportName], + exportsInfo.getReadOnlyExportInfo(exportName), + false, + true + ) + ); + } + } + + return mode; +}; + +/** @typedef {string[]} Ids */ +/** @typedef {Set} Exports */ +/** @typedef {Set} Checked */ +/** @typedef {Set} Hidden */ +/** @typedef {Set} IgnoredExports */ + class HarmonyExportImportedSpecifierDependency extends HarmonyImportDependency { /** * @param {string} request the request string * @param {number} sourceOrder the order in the original source file - * @param {string[]} ids the requested export name of the imported module + * @param {Ids} ids the requested export name of the imported module * @param {string | null} name the export name of for this module * @param {Set} activeExports other named exports in the module - * @param {Iterable} otherStarExports other star exports in the module - * @param {boolean} strictExportPresence when true, missing exports in the imported module lead to errors instead of warnings + * @param {ReadonlyArray | Iterable | null} otherStarExports other star exports in the module before this import + * @param {number} exportPresenceMode mode of checking export names + * @param {HarmonyStarExportsList | null} allStarExports all star exports in the module + * @param {ImportAttributes=} attributes import attributes */ constructor( request, @@ -109,15 +363,25 @@ class HarmonyExportImportedSpecifierDependency extends HarmonyImportDependency { name, activeExports, otherStarExports, - strictExportPresence + exportPresenceMode, + allStarExports, + attributes ) { - super(request, sourceOrder); + super(request, sourceOrder, attributes); this.ids = ids; this.name = name; this.activeExports = activeExports; this.otherStarExports = otherStarExports; - this.strictExportPresence = strictExportPresence; + this.exportPresenceMode = exportPresenceMode; + this.allStarExports = allStarExports; + } + + /** + * @returns {boolean | TRANSITIVE} true, when changes to the referenced module could affect the referencing module; TRANSITIVE, when changes to the referenced module could affect referencing modules of the referencing module + */ + couldAffectReferencingModule() { + return Dependency.TRANSITIVE; } // TODO webpack 6 remove @@ -141,7 +405,7 @@ class HarmonyExportImportedSpecifierDependency extends HarmonyImportDependency { /** * @param {ModuleGraph} moduleGraph the module graph - * @returns {string[]} the imported id + * @returns {Ids} the imported id */ getIds(moduleGraph) { return moduleGraph.getMeta(this)[idsSymbol] || this.ids; @@ -149,7 +413,7 @@ class HarmonyExportImportedSpecifierDependency extends HarmonyImportDependency { /** * @param {ModuleGraph} moduleGraph the module graph - * @param {string[]} ids the imported ids + * @param {Ids} ids the imported ids * @returns {void} */ setIds(moduleGraph, ids) { @@ -162,159 +426,11 @@ class HarmonyExportImportedSpecifierDependency extends HarmonyImportDependency { * @returns {ExportMode} the export mode */ getMode(moduleGraph, runtime) { - const name = this.name; - const ids = this.getIds(moduleGraph); - const parentModule = moduleGraph.getParentModule(this); - const importedModule = moduleGraph.getModule(this); - const exportsInfo = moduleGraph.getExportsInfo(parentModule); - - if (!importedModule) { - const mode = new ExportMode("missing"); - - mode.userRequest = this.userRequest; - - return mode; - } - - if ( - name - ? exportsInfo.getUsed(name, runtime) === UsageState.Unused - : exportsInfo.isUsed(runtime) === false - ) { - const mode = new ExportMode("unused"); - - mode.name = name || "*"; - - return mode; - } - - const importedExportsType = importedModule.getExportsType( - moduleGraph, - parentModule.buildMeta.strictHarmonyModule - ); - - // Special handling for reexporting the default export - // from non-namespace modules - if (name && ids.length > 0 && ids[0] === "default") { - switch (importedExportsType) { - case "dynamic": { - const mode = new ExportMode("reexport-dynamic-default"); - - mode.name = name; - - return mode; - } - case "default-only": - case "default-with-named": { - const exportInfo = exportsInfo.getReadOnlyExportInfo(name); - const mode = new ExportMode("reexport-named-default"); - - mode.name = name; - mode.partialNamespaceExportInfo = exportInfo; - - return mode; - } - } - } - - // reexporting with a fixed name - if (name) { - let mode; - const exportInfo = exportsInfo.getReadOnlyExportInfo(name); - - if (ids.length > 0) { - // export { name as name } - switch (importedExportsType) { - case "default-only": - mode = new ExportMode("reexport-undefined"); - mode.name = name; - break; - default: - mode = new ExportMode("normal-reexport"); - mode.items = [ - new NormalReexportItem(name, ids, exportInfo, false, false) - ]; - break; - } - } else { - // export * as name - switch (importedExportsType) { - case "default-only": - mode = new ExportMode("reexport-fake-namespace-object"); - mode.name = name; - mode.partialNamespaceExportInfo = exportInfo; - mode.fakeType = 0; - break; - case "default-with-named": - mode = new ExportMode("reexport-fake-namespace-object"); - mode.name = name; - mode.partialNamespaceExportInfo = exportInfo; - mode.fakeType = 2; - break; - case "dynamic": - default: - mode = new ExportMode("reexport-namespace-object"); - mode.name = name; - mode.partialNamespaceExportInfo = exportInfo; - } - } - - return mode; - } - - // Star reexporting - - const { ignoredExports, exports, checked, hidden } = this.getStarReexports( - moduleGraph, - runtime, - exportsInfo, - importedModule - ); - if (!exports) { - // We have too few info about the modules - // Delegate the logic to the runtime code - - const mode = new ExportMode("dynamic-reexport"); - mode.ignored = ignoredExports; - mode.hidden = hidden; - - return mode; - } - - if (exports.size === 0) { - const mode = new ExportMode("empty-star"); - mode.hidden = hidden; - - return mode; - } - - const mode = new ExportMode("normal-reexport"); - - mode.items = Array.from( - exports, - exportName => - new NormalReexportItem( - exportName, - [exportName], - exportsInfo.getReadOnlyExportInfo(exportName), - checked.has(exportName), - false - ) - ).concat( - Array.from( - hidden, - exportName => - new NormalReexportItem( - exportName, - [exportName], - exportsInfo.getReadOnlyExportInfo(exportName), - false, - true - ) - ) + return moduleGraph.dependencyCacheProvide( + this, + getRuntimeKey(runtime), + getMode ); - - return mode; } /** @@ -322,26 +438,34 @@ class HarmonyExportImportedSpecifierDependency extends HarmonyImportDependency { * @param {RuntimeSpec} runtime the runtime * @param {ExportsInfo} exportsInfo exports info about the current module (optional) * @param {Module} importedModule the imported module (optional) - * @returns {{exports?: Set, checked?: Set, ignoredExports: Set, hidden: Set}} information + * @returns {{exports?: Exports, checked?: Checked, ignoredExports: IgnoredExports, hidden?: Hidden}} information */ getStarReexports( moduleGraph, runtime, - exportsInfo = moduleGraph.getExportsInfo(moduleGraph.getParentModule(this)), - importedModule = moduleGraph.getModule(this) + exportsInfo = moduleGraph.getExportsInfo( + /** @type {Module} */ (moduleGraph.getParentModule(this)) + ), + importedModule = /** @type {Module} */ (moduleGraph.getModule(this)) ) { const importedExportsInfo = moduleGraph.getExportsInfo(importedModule); - const noExtraExports = importedExportsInfo.otherExportsInfo.provided === false; const noExtraImports = exportsInfo.otherExportsInfo.getUsed(runtime) === UsageState.Unused; const ignoredExports = new Set(["default", ...this.activeExports]); - const hiddenExports = new Set( - this._discoverActiveExportsFromOtherStarExports(moduleGraph).keys() - ); - for (const e of ignoredExports) hiddenExports.delete(e); + + let hiddenExports; + const otherStarExports = + this._discoverActiveExportsFromOtherStarExports(moduleGraph); + if (otherStarExports !== undefined) { + hiddenExports = new Set(); + for (let i = 0; i < otherStarExports.namesSlice; i++) { + hiddenExports.add(otherStarExports.names[i]); + } + for (const e of ignoredExports) hiddenExports.delete(e); + } if (!noExtraExports && !noExtraImports) { return { @@ -350,24 +474,24 @@ class HarmonyExportImportedSpecifierDependency extends HarmonyImportDependency { }; } - /** @type {Set} */ + /** @type {Exports} */ const exports = new Set(); - /** @type {Set} */ + /** @type {Checked} */ const checked = new Set(); - /** @type {Set} */ - const hidden = new Set(); + /** @type {Hidden | undefined} */ + const hidden = hiddenExports !== undefined ? new Set() : undefined; if (noExtraImports) { for (const exportInfo of exportsInfo.orderedExports) { const name = exportInfo.name; if (ignoredExports.has(name)) continue; if (exportInfo.getUsed(runtime) === UsageState.Unused) continue; - const importedExportInfo = importedExportsInfo.getReadOnlyExportInfo( - name - ); + const importedExportInfo = + importedExportsInfo.getReadOnlyExportInfo(name); if (importedExportInfo.provided === false) continue; - if (hiddenExports.has(name)) { - hidden.add(name); + if (hiddenExports !== undefined && hiddenExports.has(name)) { + /** @type {Set} */ + (hidden).add(name); continue; } exports.add(name); @@ -381,8 +505,9 @@ class HarmonyExportImportedSpecifierDependency extends HarmonyImportDependency { if (importedExportInfo.provided === false) continue; const exportInfo = exportsInfo.getReadOnlyExportInfo(name); if (exportInfo.getUsed(runtime) === UsageState.Unused) continue; - if (hiddenExports.has(name)) { - hidden.add(name); + if (hiddenExports !== undefined && hiddenExports.has(name)) { + /** @type {ExportModeHidden} */ + (hidden).add(name); continue; } exports.add(name); @@ -396,7 +521,7 @@ class HarmonyExportImportedSpecifierDependency extends HarmonyImportDependency { /** * @param {ModuleGraph} moduleGraph module graph - * @returns {null | false | function(ModuleGraphConnection, RuntimeSpec): ConnectionState} function to determine if the connection is active + * @returns {null | false | GetConditionFn} function to determine if the connection is active */ getCondition(moduleGraph) { return (connection, runtime) => { @@ -435,7 +560,7 @@ class HarmonyExportImportedSpecifierDependency extends HarmonyImportDependency { case "reexport-named-default": { if (!mode.partialNamespaceExportInfo) return Dependency.EXPORTS_OBJECT_REFERENCED; - /** @type {string[][]} */ + /** @type {ReferencedExports} */ const referencedExports = []; processExportInfo( runtime, @@ -450,7 +575,7 @@ class HarmonyExportImportedSpecifierDependency extends HarmonyImportDependency { case "reexport-fake-namespace-object": { if (!mode.partialNamespaceExportInfo) return Dependency.EXPORTS_OBJECT_REFERENCED; - /** @type {string[][]} */ + /** @type {ReferencedExports} */ const referencedExports = []; processExportInfo( runtime, @@ -466,6 +591,7 @@ class HarmonyExportImportedSpecifierDependency extends HarmonyImportDependency { return Dependency.EXPORTS_OBJECT_REFERENCED; case "normal-reexport": { + /** @type {ReferencedExports} */ const referencedExports = []; for (const { ids, exportInfo, hidden } of mode.items) { if (hidden) continue; @@ -481,28 +607,43 @@ class HarmonyExportImportedSpecifierDependency extends HarmonyImportDependency { /** * @param {ModuleGraph} moduleGraph the module graph - * @returns {Map} exported names and their origin dependency + * @returns {{ names: string[], namesSlice: number, dependencyIndices: number[], dependencyIndex: number } | undefined} exported names and their origin dependency */ _discoverActiveExportsFromOtherStarExports(moduleGraph) { - if (!this.otherStarExports) { - return new Map(); - } + if (!this.otherStarExports) return; + + const i = + "length" in this.otherStarExports + ? this.otherStarExports.length + : countIterable(this.otherStarExports); + if (i === 0) return; + + if (this.allStarExports) { + const { names, dependencyIndices } = moduleGraph.cached( + determineExportAssignments, + this.allStarExports.dependencies + ); - const result = new Map(); - // try to learn impossible exports from other star exports with provided exports - for (const otherStarExport of this.otherStarExports) { - const otherImportedModule = moduleGraph.getModule(otherStarExport); - if (otherImportedModule) { - const exportsInfo = moduleGraph.getExportsInfo(otherImportedModule); - for (const exportInfo of exportsInfo.exports) { - if (exportInfo.provided === true && !result.has(exportInfo.name)) { - result.set(exportInfo.name, otherStarExport); - } - } - } + return { + names, + namesSlice: dependencyIndices[i - 1], + dependencyIndices, + dependencyIndex: i + }; } - return result; + const { names, dependencyIndices } = moduleGraph.cached( + determineExportAssignments, + this.otherStarExports, + this + ); + + return { + names, + namesSlice: dependencyIndices[i - 1], + dependencyIndices, + dependencyIndex: i + }; } /** @@ -515,14 +656,21 @@ class HarmonyExportImportedSpecifierDependency extends HarmonyImportDependency { switch (mode.type) { case "missing": - return undefined; + return; case "dynamic-reexport": { - const from = moduleGraph.getConnection(this); + const from = + /** @type {ModuleGraphConnection} */ + (moduleGraph.getConnection(this)); return { exports: true, from, canMangle: false, - excludeExports: combine(mode.ignored, mode.hidden), + excludeExports: mode.hidden + ? combine( + /** @type {ExportModeIgnored} */ (mode.ignored), + mode.hidden + ) + : /** @type {ExportModeIgnored} */ (mode.ignored), hideExports: mode.hidden, dependencies: [from.module] }; @@ -531,11 +679,13 @@ class HarmonyExportImportedSpecifierDependency extends HarmonyImportDependency { return { exports: [], hideExports: mode.hidden, - dependencies: [moduleGraph.getModule(this)] + dependencies: [/** @type {Module} */ (moduleGraph.getModule(this))] }; // falls through case "normal-reexport": { - const from = moduleGraph.getConnection(this); + const from = + /** @type {ModuleGraphConnection} */ + (moduleGraph.getConnection(this)); return { exports: Array.from(mode.items, item => ({ name: item.name, @@ -543,35 +693,39 @@ class HarmonyExportImportedSpecifierDependency extends HarmonyImportDependency { export: item.ids, hidden: item.hidden })), + priority: 1, dependencies: [from.module] }; } case "reexport-dynamic-default": { - { - const from = moduleGraph.getConnection(this); - return { - exports: [ - { - name: mode.name, - from, - export: ["default"] - } - ], - dependencies: [from.module] - }; - } + const from = + /** @type {ModuleGraphConnection} */ + (moduleGraph.getConnection(this)); + return { + exports: [ + { + name: /** @type {string} */ (mode.name), + from, + export: ["default"] + } + ], + priority: 1, + dependencies: [from.module] + }; } case "reexport-undefined": return { - exports: [mode.name], - dependencies: [moduleGraph.getModule(this)] + exports: [/** @type {string} */ (mode.name)], + dependencies: [/** @type {Module} */ (moduleGraph.getModule(this))] }; case "reexport-fake-namespace-object": { - const from = moduleGraph.getConnection(this); + const from = + /** @type {ModuleGraphConnection} */ + (moduleGraph.getConnection(this)); return { exports: [ { - name: mode.name, + name: /** @type {string} */ (mode.name), from, export: null, exports: [ @@ -584,32 +738,39 @@ class HarmonyExportImportedSpecifierDependency extends HarmonyImportDependency { ] } ], + priority: 1, dependencies: [from.module] }; } case "reexport-namespace-object": { - const from = moduleGraph.getConnection(this); + const from = + /** @type {ModuleGraphConnection} */ + (moduleGraph.getConnection(this)); return { exports: [ { - name: mode.name, + name: /** @type {string} */ (mode.name), from, export: null } ], + priority: 1, dependencies: [from.module] }; } case "reexport-named-default": { - const from = moduleGraph.getConnection(this); + const from = + /** @type {ModuleGraphConnection} */ + (moduleGraph.getConnection(this)); return { exports: [ { - name: mode.name, + name: /** @type {string} */ (mode.name), from, export: ["default"] } ], + priority: 1, dependencies: [from.module] }; } @@ -618,35 +779,42 @@ class HarmonyExportImportedSpecifierDependency extends HarmonyImportDependency { } } + /** + * @param {ModuleGraph} moduleGraph module graph + * @returns {number} effective mode + */ + _getEffectiveExportPresenceLevel(moduleGraph) { + if (this.exportPresenceMode !== ExportPresenceModes.AUTO) + return this.exportPresenceMode; + const module = /** @type {Module} */ (moduleGraph.getParentModule(this)); + return /** @type {BuildMeta} */ (module.buildMeta).strictHarmonyModule + ? ExportPresenceModes.ERROR + : ExportPresenceModes.WARN; + } + /** * Returns warnings * @param {ModuleGraph} moduleGraph module graph - * @returns {WebpackError[]} warnings + * @returns {WebpackError[] | null | undefined} warnings */ getWarnings(moduleGraph) { - if ( - this.strictExportPresence || - moduleGraph.getParentModule(this).buildMeta.strictHarmonyModule - ) { - return null; + const exportsPresence = this._getEffectiveExportPresenceLevel(moduleGraph); + if (exportsPresence === ExportPresenceModes.WARN) { + return this._getErrors(moduleGraph); } - - return this._getErrors(moduleGraph); + return null; } /** * Returns errors * @param {ModuleGraph} moduleGraph module graph - * @returns {WebpackError[]} errors + * @returns {WebpackError[] | null | undefined} errors */ getErrors(moduleGraph) { - if ( - this.strictExportPresence || - moduleGraph.getParentModule(this).buildMeta.strictHarmonyModule - ) { + const exportsPresence = this._getEffectiveExportPresenceLevel(moduleGraph); + if (exportsPresence === ExportPresenceModes.ERROR) { return this._getErrors(moduleGraph); } - return null; } @@ -662,35 +830,47 @@ class HarmonyExportImportedSpecifierDependency extends HarmonyImportDependency { `(reexported as '${this.name}')` ); if (ids.length === 0 && this.name === null) { - const potentialConflicts = this._discoverActiveExportsFromOtherStarExports( - moduleGraph - ); - if (potentialConflicts.size > 0) { + const potentialConflicts = + this._discoverActiveExportsFromOtherStarExports(moduleGraph); + if (potentialConflicts && potentialConflicts.namesSlice > 0) { + const ownNames = new Set( + potentialConflicts.names.slice( + potentialConflicts.namesSlice, + potentialConflicts.dependencyIndices[ + potentialConflicts.dependencyIndex + ] + ) + ); const importedModule = moduleGraph.getModule(this); if (importedModule) { const exportsInfo = moduleGraph.getExportsInfo(importedModule); + /** @type {Map} */ const conflicts = new Map(); for (const exportInfo of exportsInfo.orderedExports) { if (exportInfo.provided !== true) continue; if (exportInfo.name === "default") continue; if (this.activeExports.has(exportInfo.name)) continue; - const conflictingDependency = potentialConflicts.get( - exportInfo.name + if (ownNames.has(exportInfo.name)) continue; + const conflictingDependency = findDependencyForName( + potentialConflicts, + exportInfo.name, + this.allStarExports + ? this.allStarExports.dependencies + : [...this.otherStarExports, this] ); if (!conflictingDependency) continue; const target = exportInfo.getTerminalBinding(moduleGraph); if (!target) continue; - const conflictingModule = moduleGraph.getModule( - conflictingDependency - ); + const conflictingModule = + /** @type {Module} */ + (moduleGraph.getModule(conflictingDependency)); if (conflictingModule === importedModule) continue; const conflictingExportInfo = moduleGraph.getExportInfo( conflictingModule, exportInfo.name ); - const conflictingTarget = conflictingExportInfo.getTerminalBinding( - moduleGraph - ); + const conflictingTarget = + conflictingExportInfo.getTerminalBinding(moduleGraph); if (!conflictingTarget) continue; if (target === conflictingTarget) continue; const list = conflicts.get(conflictingDependency.request); @@ -720,26 +900,36 @@ class HarmonyExportImportedSpecifierDependency extends HarmonyImportDependency { return errors; } + /** + * @param {ObjectSerializerContext} context context + */ serialize(context) { - const { write } = context; + const { write, setCircularReference } = context; + setCircularReference(this); write(this.ids); write(this.name); write(this.activeExports); write(this.otherStarExports); - write(this.strictExportPresence); + write(this.exportPresenceMode); + write(this.allStarExports); super.serialize(context); } + /** + * @param {ObjectDeserializerContext} context context + */ deserialize(context) { - const { read } = context; + const { read, setCircularReference } = context; + setCircularReference(this); this.ids = read(); this.name = read(); this.activeExports = read(); this.otherStarExports = read(); - this.strictExportPresence = read(); + this.exportPresenceMode = read(); + this.allStarExports = read(); super.deserialize(context); } @@ -764,7 +954,9 @@ HarmonyExportImportedSpecifierDependency.Template = class HarmonyExportImportedS apply(dependency, source, templateContext) { const { moduleGraph, runtime, concatenationScope } = templateContext; - const dep = /** @type {HarmonyExportImportedSpecifierDependency} */ (dependency); + const dep = /** @type {HarmonyExportImportedSpecifierDependency} */ ( + dependency + ); const mode = dep.getMode(moduleGraph, runtime); @@ -772,7 +964,7 @@ HarmonyExportImportedSpecifierDependency.Template = class HarmonyExportImportedS switch (mode.type) { case "reexport-undefined": concatenationScope.registerRawExport( - mode.name, + /** @type {NonNullable} */ (mode.name), "/* reexport non-default export from non-harmony */ undefined" ); } @@ -796,14 +988,14 @@ HarmonyExportImportedSpecifierDependency.Template = class HarmonyExportImportedS } /** - * @param {InitFragment[]} initFragments target array for init fragments + * @param {InitFragment[]} initFragments target array for init fragments * @param {HarmonyExportImportedSpecifierDependency} dep dependency * @param {ExportMode} mode the export mode * @param {Module} module the current module * @param {ModuleGraph} moduleGraph the module graph * @param {RuntimeSpec} runtime the runtime * @param {RuntimeTemplate} runtimeTemplate the runtime template - * @param {Set} runtimeRequirements runtime requirements + * @param {RuntimeRequirements} runtimeRequirements runtime requirements * @returns {void} */ _addExportFragments( @@ -816,7 +1008,7 @@ HarmonyExportImportedSpecifierDependency.Template = class HarmonyExportImportedS runtimeTemplate, runtimeRequirements ) { - const importedModule = moduleGraph.getModule(dep); + const importedModule = /** @type {Module} */ (moduleGraph.getModule(dep)); const importVar = dep.getImportVar(moduleGraph); switch (mode.type) { @@ -908,21 +1100,36 @@ HarmonyExportImportedSpecifierDependency.Template = class HarmonyExportImportedS break; case "normal-reexport": - for (const { name, ids, checked, hidden } of mode.items) { + for (const { + name, + ids, + checked, + hidden + } of /** @type {NormalReexportItem[]} */ (mode.items)) { if (hidden) continue; if (checked) { + const connection = moduleGraph.getConnection(dep); + const key = `harmony reexport (checked) ${importVar} ${name}`; + const runtimeCondition = dep.weak + ? false + : connection + ? filterRuntime(runtime, r => connection.isTargetActive(r)) + : true; initFragments.push( - new InitFragment( - "/* harmony reexport (checked) */ " + - this.getConditionalReexportStatement( - module, - name, - importVar, - ids, - runtimeRequirements - ), - InitFragment.STAGE_HARMONY_IMPORTS, - dep.sourceOrder + new ConditionalInitFragment( + `/* harmony reexport (checked) */ ${this.getConditionalReexportStatement( + module, + name, + importVar, + ids, + runtimeRequirements + )}`, + moduleGraph.isAsync(importedModule) + ? InitFragment.STAGE_ASYNC_HARMONY_IMPORTS + : InitFragment.STAGE_HARMONY_IMPORTS, + dep.sourceOrder, + key, + runtimeCondition ) ); } else { @@ -943,7 +1150,13 @@ HarmonyExportImportedSpecifierDependency.Template = class HarmonyExportImportedS break; case "dynamic-reexport": { - const ignored = combine(mode.ignored, mode.hidden); + const ignored = mode.hidden + ? combine( + /** @type {ExportModeIgnored} */ + (mode.ignored), + mode.hidden + ) + : /** @type {ExportModeIgnored} */ (mode.ignored); const modern = runtimeTemplate.supportsConst() && runtimeTemplate.supportsArrowFunction(); @@ -956,22 +1169,19 @@ HarmonyExportImportedSpecifierDependency.Template = class HarmonyExportImportedS // Filter out exports which are defined by other exports // and filter out default export because it cannot be reexported with * if (ignored.size > 1) { - content += - "if(" + - JSON.stringify(Array.from(ignored)) + - ".indexOf(__WEBPACK_IMPORT_KEY__) < 0) "; + content += `if(${JSON.stringify( + Array.from(ignored) + )}.indexOf(__WEBPACK_IMPORT_KEY__) < 0) `; } else if (ignored.size === 1) { content += `if(__WEBPACK_IMPORT_KEY__ !== ${JSON.stringify( first(ignored) )}) `; } - content += `__WEBPACK_REEXPORT_OBJECT__[__WEBPACK_IMPORT_KEY__] = `; - if (modern) { - content += `() => ${importVar}[__WEBPACK_IMPORT_KEY__]`; - } else { - content += `function(key) { return ${importVar}[key]; }.bind(0, __WEBPACK_IMPORT_KEY__)`; - } + content += "__WEBPACK_REEXPORT_OBJECT__[__WEBPACK_IMPORT_KEY__] = "; + content += modern + ? `() => ${importVar}[__WEBPACK_IMPORT_KEY__]` + : `function(key) { return ${importVar}[key]; }.bind(0, __WEBPACK_IMPORT_KEY__)`; runtimeRequirements.add(RuntimeGlobals.exports); runtimeRequirements.add(RuntimeGlobals.definePropertyGetters); @@ -980,7 +1190,9 @@ HarmonyExportImportedSpecifierDependency.Template = class HarmonyExportImportedS initFragments.push( new InitFragment( `${content}\n/* harmony reexport (unknown) */ ${RuntimeGlobals.definePropertyGetters}(${exportsName}, __WEBPACK_REEXPORT_OBJECT__);\n`, - InitFragment.STAGE_HARMONY_IMPORTS, + moduleGraph.isAsync(importedModule) + ? InitFragment.STAGE_ASYNC_HARMONY_IMPORTS + : InitFragment.STAGE_HARMONY_IMPORTS, dep.sourceOrder ) ); @@ -992,6 +1204,15 @@ HarmonyExportImportedSpecifierDependency.Template = class HarmonyExportImportedS } } + /** + * @param {Module} module the current module + * @param {string} comment comment + * @param {UsedName} key key + * @param {string} name name + * @param {string | string[] | null | false} valueKey value key + * @param {RuntimeRequirements} runtimeRequirements runtime requirements + * @returns {HarmonyExportInitFragment} harmony export init fragment + */ getReexportFragment( module, comment, @@ -1011,6 +1232,14 @@ HarmonyExportImportedSpecifierDependency.Template = class HarmonyExportImportedS return new HarmonyExportInitFragment(module.exportsArgument, map); } + /** + * @param {Module} module module + * @param {string | string[] | false} key key + * @param {string} name name + * @param {number} fakeType fake type + * @param {RuntimeRequirements} runtimeRequirements runtime requirements + * @returns {[InitFragment, HarmonyExportInitFragment]} init fragments + */ getReexportFakeNamespaceObjectFragments( module, key, @@ -1041,6 +1270,14 @@ HarmonyExportImportedSpecifierDependency.Template = class HarmonyExportImportedS ]; } + /** + * @param {Module} module module + * @param {string} key key + * @param {string} name name + * @param {string | string[] | false} valueKey value key + * @param {RuntimeRequirements} runtimeRequirements runtime requirements + * @returns {string} result + */ getConditionalReexportStatement( module, key, @@ -1063,11 +1300,16 @@ HarmonyExportImportedSpecifierDependency.Template = class HarmonyExportImportedS valueKey[0] )})) ${ RuntimeGlobals.definePropertyGetters - }(${exportsName}, { ${JSON.stringify( + }(${exportsName}, { ${propertyName( key )}: function() { return ${returnValue}; } });\n`; } + /** + * @param {string} name name + * @param {null | false | string | string[]} valueKey value key + * @returns {string | undefined} value + */ getReturnValue(name, valueKey) { if (valueKey === null) { return `${name}_default.a`; @@ -1084,3 +1326,46 @@ HarmonyExportImportedSpecifierDependency.Template = class HarmonyExportImportedS return `${name}${propertyAccess(valueKey)}`; } }; + +class HarmonyStarExportsList { + constructor() { + /** @type {HarmonyExportImportedSpecifierDependency[]} */ + this.dependencies = []; + } + + /** + * @param {HarmonyExportImportedSpecifierDependency} dep dependency + * @returns {void} + */ + push(dep) { + this.dependencies.push(dep); + } + + slice() { + return this.dependencies.slice(); + } + + /** + * @param {ObjectSerializerContext} context context + */ + serialize({ write, setCircularReference }) { + setCircularReference(this); + write(this.dependencies); + } + + /** + * @param {ObjectDeserializerContext} context context + */ + deserialize({ read, setCircularReference }) { + setCircularReference(this); + this.dependencies = read(); + } +} + +makeSerializable( + HarmonyStarExportsList, + "webpack/lib/dependencies/HarmonyExportImportedSpecifierDependency", + "HarmonyStarExportsList" +); + +module.exports.HarmonyStarExportsList = HarmonyStarExportsList; diff --git a/lib/dependencies/HarmonyExportInitFragment.js b/lib/dependencies/HarmonyExportInitFragment.js index 73484d268f2..8125cc2db8b 100644 --- a/lib/dependencies/HarmonyExportInitFragment.js +++ b/lib/dependencies/HarmonyExportInitFragment.js @@ -8,10 +8,15 @@ const InitFragment = require("../InitFragment"); const RuntimeGlobals = require("../RuntimeGlobals"); const { first } = require("../util/SetHelpers"); +const { propertyName } = require("../util/propertyName"); /** @typedef {import("webpack-sources").Source} Source */ /** @typedef {import("../Generator").GenerateContext} GenerateContext */ +/** + * @param {Iterable} iterable iterable strings + * @returns {string} result + */ const joinIterableWithComma = iterable => { // This is more performant than Array.from().join(", ") // as it doesn't create an array @@ -31,6 +36,9 @@ const joinIterableWithComma = iterable => { const EMPTY_MAP = new Map(); const EMPTY_SET = new Set(); +/** + * @extends {InitFragment} Context + */ class HarmonyExportInitFragment extends InitFragment { /** * @param {string} exportsArgument the exports identifier @@ -48,6 +56,57 @@ class HarmonyExportInitFragment extends InitFragment { this.unusedExports = unusedExports; } + /** + * @param {HarmonyExportInitFragment[]} fragments all fragments to merge + * @returns {HarmonyExportInitFragment} merged fragment + */ + mergeAll(fragments) { + let exportMap; + let exportMapOwned = false; + let unusedExports; + let unusedExportsOwned = false; + + for (const fragment of fragments) { + if (fragment.exportMap.size !== 0) { + if (exportMap === undefined) { + exportMap = fragment.exportMap; + exportMapOwned = false; + } else { + if (!exportMapOwned) { + exportMap = new Map(exportMap); + exportMapOwned = true; + } + for (const [key, value] of fragment.exportMap) { + if (!exportMap.has(key)) exportMap.set(key, value); + } + } + } + if (fragment.unusedExports.size !== 0) { + if (unusedExports === undefined) { + unusedExports = fragment.unusedExports; + unusedExportsOwned = false; + } else { + if (!unusedExportsOwned) { + unusedExports = new Set(unusedExports); + unusedExportsOwned = true; + } + for (const value of fragment.unusedExports) { + unusedExports.add(value); + } + } + } + } + return new HarmonyExportInitFragment( + this.exportsArgument, + exportMap, + unusedExports + ); + } + + /** + * @param {HarmonyExportInitFragment} other other + * @returns {HarmonyExportInitFragment} merged result + */ merge(other) { let exportMap; if (this.exportMap.size === 0) { @@ -79,8 +138,8 @@ class HarmonyExportInitFragment extends InitFragment { } /** - * @param {GenerateContext} generateContext context for generate - * @returns {string|Source} the source code that will be included as initialization code + * @param {GenerateContext} context context + * @returns {string | Source | undefined} the source code that will be included as initialization code */ getContent({ runtimeTemplate, runtimeRequirements }) { runtimeRequirements.add(RuntimeGlobals.exports); @@ -90,14 +149,17 @@ class HarmonyExportInitFragment extends InitFragment { this.unusedExports.size > 1 ? `/* unused harmony exports ${joinIterableWithComma( this.unusedExports - )} */\n` + )} */\n` : this.unusedExports.size > 0 - ? `/* unused harmony export ${first(this.unusedExports)} */\n` - : ""; + ? `/* unused harmony export ${first(this.unusedExports)} */\n` + : ""; const definitions = []; - for (const [key, value] of this.exportMap) { + const orderedExportMap = Array.from(this.exportMap).sort(([a], [b]) => + a < b ? -1 : 1 + ); + for (const [key, value] of orderedExportMap) { definitions.push( - `\n/* harmony export */ ${JSON.stringify( + `\n/* harmony export */ ${propertyName( key )}: ${runtimeTemplate.returningFunction(value)}` ); @@ -106,7 +168,7 @@ class HarmonyExportInitFragment extends InitFragment { this.exportMap.size > 0 ? `/* harmony export */ ${RuntimeGlobals.definePropertyGetters}(${ this.exportsArgument - }, {${definitions.join(",")}\n/* harmony export */ });\n` + }, {${definitions.join(",")}\n/* harmony export */ });\n` : ""; return `${definePart}${unusedPart}`; } diff --git a/lib/dependencies/HarmonyExportSpecifierDependency.js b/lib/dependencies/HarmonyExportSpecifierDependency.js index d3735c48b84..4e742935942 100644 --- a/lib/dependencies/HarmonyExportSpecifierDependency.js +++ b/lib/dependencies/HarmonyExportSpecifierDependency.js @@ -15,8 +15,14 @@ const NullDependency = require("./NullDependency"); /** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */ /** @typedef {import("../ModuleGraph")} ModuleGraph */ /** @typedef {import("../ModuleGraphConnection").ConnectionState} ConnectionState */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */ class HarmonyExportSpecifierDependency extends NullDependency { + /** + * @param {TODO} id id + * @param {TODO} name name + */ constructor(id, name) { super(); this.id = id; @@ -35,6 +41,7 @@ class HarmonyExportSpecifierDependency extends NullDependency { getExports(moduleGraph) { return { exports: [this.name], + priority: 1, terminalBinding: true, dependencies: undefined }; @@ -48,6 +55,9 @@ class HarmonyExportSpecifierDependency extends NullDependency { return false; } + /** + * @param {ObjectSerializerContext} context context + */ serialize(context) { const { write } = context; write(this.id); @@ -55,6 +65,9 @@ class HarmonyExportSpecifierDependency extends NullDependency { super.serialize(context); } + /** + * @param {ObjectDeserializerContext} context context + */ deserialize(context) { const { read } = context; this.id = read(); diff --git a/lib/dependencies/HarmonyExports.js b/lib/dependencies/HarmonyExports.js index 452865923f9..1f6e6d4acb9 100644 --- a/lib/dependencies/HarmonyExports.js +++ b/lib/dependencies/HarmonyExports.js @@ -5,6 +5,10 @@ "use strict"; +const RuntimeGlobals = require("../RuntimeGlobals"); + +/** @typedef {import("../Module").BuildInfo} BuildInfo */ +/** @typedef {import("../Module").BuildMeta} BuildMeta */ /** @typedef {import("../Parser").ParserState} ParserState */ /** @type {WeakMap} */ @@ -15,17 +19,19 @@ const parserStateExportsState = new WeakMap(); * @param {boolean} isStrictHarmony strict harmony mode should be enabled * @returns {void} */ -exports.enable = (parserState, isStrictHarmony) => { +module.exports.enable = (parserState, isStrictHarmony) => { const value = parserStateExportsState.get(parserState); if (value === false) return; parserStateExportsState.set(parserState, true); if (value !== true) { - parserState.module.buildMeta.exportsType = "namespace"; - parserState.module.buildInfo.strict = true; - parserState.module.buildInfo.exportsArgument = "__webpack_exports__"; + const buildMeta = /** @type {BuildMeta} */ (parserState.module.buildMeta); + buildMeta.exportsType = "namespace"; + const buildInfo = /** @type {BuildInfo} */ (parserState.module.buildInfo); + buildInfo.strict = true; + buildInfo.exportsArgument = RuntimeGlobals.exports; if (isStrictHarmony) { - parserState.module.buildMeta.strictHarmonyModule = true; - parserState.module.buildInfo.moduleArgument = "__webpack_module__"; + buildMeta.strictHarmonyModule = true; + buildInfo.moduleArgument = "__webpack_module__"; } } }; @@ -34,7 +40,7 @@ exports.enable = (parserState, isStrictHarmony) => { * @param {ParserState} parserState parser state * @returns {boolean} true, when enabled */ -exports.isEnabled = parserState => { +module.exports.isEnabled = parserState => { const value = parserStateExportsState.get(parserState); return value === true; }; diff --git a/lib/dependencies/HarmonyImportDependency.js b/lib/dependencies/HarmonyImportDependency.js index e7150f6494c..e9f26fc9459 100644 --- a/lib/dependencies/HarmonyImportDependency.js +++ b/lib/dependencies/HarmonyImportDependency.js @@ -20,22 +20,53 @@ const ModuleDependency = require("./ModuleDependency"); /** @typedef {import("../Dependency").ReferencedExport} ReferencedExport */ /** @typedef {import("../Dependency").UpdateHashContext} UpdateHashContext */ /** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */ +/** @typedef {import("../ExportsInfo")} ExportsInfo */ /** @typedef {import("../Module")} Module */ +/** @typedef {import("../Module").BuildMeta} BuildMeta */ /** @typedef {import("../ModuleGraph")} ModuleGraph */ /** @typedef {import("../RuntimeTemplate")} RuntimeTemplate */ /** @typedef {import("../WebpackError")} WebpackError */ +/** @typedef {import("../javascript/JavascriptParser").ImportAttributes} ImportAttributes */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */ /** @typedef {import("../util/Hash")} Hash */ /** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */ +const ExportPresenceModes = { + NONE: /** @type {0} */ (0), + WARN: /** @type {1} */ (1), + AUTO: /** @type {2} */ (2), + ERROR: /** @type {3} */ (3), + /** + * @param {string | false} str param + * @returns {0 | 1 | 2 | 3} result + */ + fromUserOption(str) { + switch (str) { + case "error": + return ExportPresenceModes.ERROR; + case "warn": + return ExportPresenceModes.WARN; + case "auto": + return ExportPresenceModes.AUTO; + case false: + return ExportPresenceModes.NONE; + default: + throw new Error(`Invalid export presence value ${str}`); + } + } +}; + class HarmonyImportDependency extends ModuleDependency { /** - * * @param {string} request request string * @param {number} sourceOrder source order + * @param {ImportAttributes=} attributes import attributes */ - constructor(request, sourceOrder) { + constructor(request, sourceOrder, attributes) { super(request); this.sourceOrder = sourceOrder; + this.assertions = attributes; } get category() { @@ -57,16 +88,21 @@ class HarmonyImportDependency extends ModuleDependency { * @returns {string} name of the variable for the import */ getImportVar(moduleGraph) { - const module = moduleGraph.getParentModule(this); - const meta = moduleGraph.getMeta(module); + const module = /** @type {Module} */ (moduleGraph.getParentModule(this)); + const meta = /** @type {TODO} */ (moduleGraph.getMeta(module)); let importVarMap = meta.importVarMap; if (!importVarMap) meta.importVarMap = importVarMap = new Map(); - let importVar = importVarMap.get(moduleGraph.getModule(this)); + let importVar = importVarMap.get( + /** @type {Module} */ (moduleGraph.getModule(this)) + ); if (importVar) return importVar; importVar = `${Template.toIdentifier( `${this.userRequest}` )}__WEBPACK_IMPORTED_MODULE_${importVarMap.size}__`; - importVarMap.set(moduleGraph.getModule(this), importVar); + importVarMap.set( + /** @type {Module} */ (moduleGraph.getModule(this)), + importVar + ); return importVar; } @@ -81,7 +117,7 @@ class HarmonyImportDependency extends ModuleDependency { ) { return runtimeTemplate.importStatement({ update, - module: moduleGraph.getModule(this), + module: /** @type {Module} */ (moduleGraph.getModule(this)), chunkGraph, importVar: this.getImportVar(moduleGraph), request: this.request, @@ -103,10 +139,12 @@ class HarmonyImportDependency extends ModuleDependency { return; } - const parentModule = moduleGraph.getParentModule(this); + const parentModule = + /** @type {Module} */ + (moduleGraph.getParentModule(this)); const exportsType = importedModule.getExportsType( moduleGraph, - parentModule.buildMeta.strictHarmonyModule + /** @type {BuildMeta} */ (parentModule.buildMeta).strictHarmonyModule ); if (exportsType === "namespace" || exportsType === "default-with-named") { if (ids.length === 0) { @@ -131,8 +169,8 @@ class HarmonyImportDependency extends ModuleDependency { const moreInfo = !Array.isArray(providedExports) ? " (possible exports unknown)" : providedExports.length === 0 - ? " (module has no exports)" - : ` (possible exports: ${providedExports.join(", ")})`; + ? " (module has no exports)" + : ` (possible exports: ${providedExports.join(", ")})`; return [ new HarmonyLinkingError( `export ${ids @@ -144,7 +182,9 @@ class HarmonyImportDependency extends ModuleDependency { ) ]; } - exportsInfo = exportInfo.getNestedExportsInfo(); + exportsInfo = + /** @type {ExportsInfo} */ + (exportInfo.getNestedExportsInfo()); } // General error message @@ -181,7 +221,8 @@ class HarmonyImportDependency extends ModuleDependency { if ( ids.length > 0 && ids[0] !== "default" && - importedModule.buildMeta.defaultObject === "redirect-warn" + /** @type {BuildMeta} */ + (importedModule.buildMeta).defaultObject === "redirect-warn" ) { // For these modules only the default export is supported return [ @@ -198,15 +239,23 @@ class HarmonyImportDependency extends ModuleDependency { } } + /** + * @param {ObjectSerializerContext} context context + */ serialize(context) { const { write } = context; write(this.sourceOrder); + write(this.assertions); super.serialize(context); } + /** + * @param {ObjectDeserializerContext} context context + */ deserialize(context) { const { read } = context; this.sourceOrder = read(); + this.assertions = read(); super.deserialize(context); } } @@ -253,8 +302,8 @@ HarmonyImportDependency.Template = class HarmonyImportDependencyTemplate extends const runtimeCondition = dep.weak ? false : connection - ? filterRuntime(runtime, r => connection.isTargetActive(r)) - : true; + ? filterRuntime(runtime, r => connection.isTargetActive(r)) + : true; if (module && referencedModule) { let emittedModules = importEmittedMap.get(module); @@ -278,7 +327,10 @@ HarmonyImportDependency.Template = class HarmonyImportDependencyTemplate extends } const importStatement = dep.getImportStatement(false, templateContext); - if (templateContext.moduleGraph.isAsync(referencedModule)) { + if ( + referencedModule && + templateContext.moduleGraph.isAsync(referencedModule) + ) { templateContext.initFragments.push( new ConditionalInitFragment( importStatement[0], @@ -298,7 +350,7 @@ HarmonyImportDependency.Template = class HarmonyImportDependencyTemplate extends importStatement[1], InitFragment.STAGE_ASYNC_HARMONY_IMPORTS, dep.sourceOrder, - key + " compat", + `${key} compat`, runtimeCondition ) ); @@ -316,7 +368,6 @@ HarmonyImportDependency.Template = class HarmonyImportDependencyTemplate extends } /** - * * @param {Module} module the module * @param {Module} referencedModule the referenced module * @returns {RuntimeSpec | boolean} runtimeCondition in which this import has been emitted @@ -327,3 +378,5 @@ HarmonyImportDependency.Template = class HarmonyImportDependencyTemplate extends return emittedModules.get(referencedModule) || false; } }; + +module.exports.ExportPresenceModes = ExportPresenceModes; diff --git a/lib/dependencies/HarmonyImportDependencyParserPlugin.js b/lib/dependencies/HarmonyImportDependencyParserPlugin.js index 457e92710cf..c5af07549ef 100644 --- a/lib/dependencies/HarmonyImportDependencyParserPlugin.js +++ b/lib/dependencies/HarmonyImportDependencyParserPlugin.js @@ -10,12 +10,28 @@ const InnerGraph = require("../optimize/InnerGraph"); const ConstDependency = require("./ConstDependency"); const HarmonyAcceptDependency = require("./HarmonyAcceptDependency"); const HarmonyAcceptImportDependency = require("./HarmonyAcceptImportDependency"); +const HarmonyEvaluatedImportSpecifierDependency = require("./HarmonyEvaluatedImportSpecifierDependency"); const HarmonyExports = require("./HarmonyExports"); +const { ExportPresenceModes } = require("./HarmonyImportDependency"); const HarmonyImportSideEffectDependency = require("./HarmonyImportSideEffectDependency"); const HarmonyImportSpecifierDependency = require("./HarmonyImportSpecifierDependency"); +/** @typedef {import("estree").ExportAllDeclaration} ExportAllDeclaration */ +/** @typedef {import("estree").ExportNamedDeclaration} ExportNamedDeclaration */ /** @typedef {import("estree").Identifier} Identifier */ +/** @typedef {import("estree").ImportDeclaration} ImportDeclaration */ +/** @typedef {import("estree").ImportExpression} ImportExpression */ +/** @typedef {import("estree").Literal} Literal */ +/** @typedef {import("estree").MemberExpression} MemberExpression */ +/** @typedef {import("estree").ObjectExpression} ObjectExpression */ +/** @typedef {import("estree").Property} Property */ +/** @typedef {import("../../declarations/WebpackOptions").JavascriptParserOptions} JavascriptParserOptions */ +/** @typedef {import("../Dependency").DependencyLocation} DependencyLocation */ +/** @typedef {import("../javascript/BasicEvaluatedExpression")} BasicEvaluatedExpression */ /** @typedef {import("../javascript/JavascriptParser")} JavascriptParser */ +/** @typedef {import("../javascript/JavascriptParser").DestructuringAssignmentProperty} DestructuringAssignmentProperty */ +/** @typedef {import("../javascript/JavascriptParser").ImportAttributes} ImportAttributes */ +/** @typedef {import("../javascript/JavascriptParser").Range} Range */ /** @typedef {import("../optimize/InnerGraph").InnerGraph} InnerGraph */ /** @typedef {import("../optimize/InnerGraph").TopLevelSymbol} TopLevelSymbol */ /** @typedef {import("./HarmonyImportDependency")} HarmonyImportDependency */ @@ -23,17 +39,95 @@ const HarmonyImportSpecifierDependency = require("./HarmonyImportSpecifierDepend const harmonySpecifierTag = Symbol("harmony import"); /** - * @typedef {Object} HarmonySettings + * @typedef {object} HarmonySettings * @property {string[]} ids * @property {string} source * @property {number} sourceOrder * @property {string} name * @property {boolean} await + * @property {Record | undefined} assertions */ +/** + * @param {ImportDeclaration | ExportNamedDeclaration | ExportAllDeclaration | (ImportExpression & { arguments?: ObjectExpression[] })} node node with assertions + * @returns {ImportAttributes | undefined} import attributes + */ +function getAttributes(node) { + if ( + node.type === "ImportExpression" && + node.arguments && + node.arguments[0] && + node.arguments[0].type === "ObjectExpression" && + node.arguments[0].properties[0] && + node.arguments[0].properties[0].type === "Property" && + node.arguments[0].properties[0].value.type === "ObjectExpression" && + node.arguments[0].properties[0].value.properties + ) { + const properties = + /** @type {Property[]} */ + (node.arguments[0].properties[0].value.properties); + const result = /** @type {ImportAttributes} */ ({}); + for (const property of properties) { + const key = + /** @type {string} */ + ( + property.key.type === "Identifier" + ? property.key.name + : /** @type {Literal} */ (property.key).value + ); + result[key] = + /** @type {string} */ + (/** @type {Literal} */ (property.value).value); + } + const key = + node.arguments[0].properties[0].key.type === "Identifier" + ? node.arguments[0].properties[0].key.name + : /** @type {Literal} */ (node.arguments[0].properties[0].key).value; + if (key === "assert") { + result._isLegacyAssert = true; + } + return result; + } + // TODO remove cast when @types/estree has been updated to import assertions + const isImportAssertion = + /** @type {{ assertions?: ImportAttributeNode[] }} */ (node).assertions !== + undefined; + const attributes = isImportAssertion + ? /** @type {{ assertions?: ImportAttributeNode[] }} */ (node).assertions + : /** @type {{ attributes?: ImportAttributeNode[] }} */ (node).attributes; + if (attributes === undefined) { + return; + } + const result = /** @type {ImportAttributes} */ ({}); + for (const attribute of attributes) { + const key = + /** @type {string} */ + ( + attribute.key.type === "Identifier" + ? attribute.key.name + : attribute.key.value + ); + result[key] = /** @type {string} */ (attribute.value.value); + } + if (isImportAssertion) { + result._isLegacyAssert = true; + } + return result; +} + module.exports = class HarmonyImportDependencyParserPlugin { + /** + * @param {JavascriptParserOptions} options options + */ constructor(options) { - this.strictExportPresence = options.strictExportPresence; + this.exportPresenceMode = + options.importExportsPresence !== undefined + ? ExportPresenceModes.fromUserOption(options.importExportsPresence) + : options.exportsPresence !== undefined + ? ExportPresenceModes.fromUserOption(options.exportsPresence) + : options.strictExportPresence + ? ExportPresenceModes.ERROR + : ExportPresenceModes.AUTO; this.strictThisContextOnImports = options.strictThisContextOnImports; } @@ -42,6 +136,29 @@ module.exports = class HarmonyImportDependencyParserPlugin { * @returns {void} */ apply(parser) { + const { exportPresenceMode } = this; + + /** + * @param {string[]} members members + * @param {boolean[]} membersOptionals members Optionals + * @returns {string[]} a non optional part + */ + function getNonOptionalPart(members, membersOptionals) { + let i = 0; + while (i < members.length && membersOptionals[i] === false) i++; + return i !== members.length ? members.slice(0, i) : members; + } + + /** + * @param {TODO} node member expression + * @param {number} count count + * @returns {TODO} member expression + */ + function getNonOptionalMemberChain(node, count) { + while (count--) node = node.object; + return node; + } + parser.hooks.isPure .for("Identifier") .tap("HarmonyImportDependencyParserPlugin", expression => { @@ -59,17 +176,21 @@ module.exports = class HarmonyImportDependencyParserPlugin { parser.state.lastHarmonyImportOrder = (parser.state.lastHarmonyImportOrder || 0) + 1; const clearDep = new ConstDependency( - parser.isAsiPosition(statement.range[0]) ? ";" : "", - statement.range + parser.isAsiPosition(/** @type {Range} */ (statement.range)[0]) + ? ";" + : "", + /** @type {Range} */ (statement.range) ); - clearDep.loc = statement.loc; + clearDep.loc = /** @type {DependencyLocation} */ (statement.loc); parser.state.module.addPresentationalDependency(clearDep); - parser.unsetAsiPosition(statement.range[1]); + parser.unsetAsiPosition(/** @type {Range} */ (statement.range)[1]); + const attributes = getAttributes(statement); const sideEffectDep = new HarmonyImportSideEffectDependency( - source, - parser.state.lastHarmonyImportOrder + /** @type {string} */ (source), + parser.state.lastHarmonyImportOrder, + attributes ); - sideEffectDep.loc = statement.loc; + sideEffectDep.loc = /** @type {DependencyLocation} */ (statement.loc); parser.state.module.addDependency(sideEffectDep); return true; } @@ -82,80 +203,183 @@ module.exports = class HarmonyImportDependencyParserPlugin { name, source, ids, - sourceOrder: parser.state.lastHarmonyImportOrder + sourceOrder: parser.state.lastHarmonyImportOrder, + assertions: getAttributes(statement) }); return true; } ); - parser.hooks.expression - .for(harmonySpecifierTag) - .tap("HarmonyImportDependencyParserPlugin", expr => { - const settings = /** @type {HarmonySettings} */ (parser.currentTagData); - const dep = new HarmonyImportSpecifierDependency( + parser.hooks.binaryExpression.tap( + "HarmonyImportDependencyParserPlugin", + expression => { + if (expression.operator !== "in") return; + + const leftPartEvaluated = parser.evaluateExpression(expression.left); + if (leftPartEvaluated.couldHaveSideEffects()) return; + const leftPart = leftPartEvaluated.asString(); + if (!leftPart) return; + + const rightPart = parser.evaluateExpression(expression.right); + if (!rightPart.isIdentifier()) return; + + const rootInfo = rightPart.rootInfo; + if ( + typeof rootInfo === "string" || + !rootInfo || + !rootInfo.tagInfo || + rootInfo.tagInfo.tag !== harmonySpecifierTag + ) + return; + const settings = rootInfo.tagInfo.data; + const members = + /** @type {(() => string[])} */ + (rightPart.getMembers)(); + const dep = new HarmonyEvaluatedImportSpecifierDependency( settings.source, settings.sourceOrder, - settings.ids, + settings.ids.concat(members).concat([leftPart]), settings.name, - expr.range, - this.strictExportPresence + /** @type {Range} */ (expression.range), + settings.assertions, + "in" ); - dep.shorthand = parser.scope.inShorthand; - dep.directImport = true; - dep.asiSafe = !parser.isAsiPosition(expr.range[0]); - dep.loc = expr.loc; + dep.directImport = members.length === 0; + dep.asiSafe = !parser.isAsiPosition( + /** @type {Range} */ (expression.range)[0] + ); + dep.loc = /** @type {DependencyLocation} */ (expression.loc); parser.state.module.addDependency(dep); InnerGraph.onUsage(parser.state, e => (dep.usedByExports = e)); return true; - }); - parser.hooks.expressionMemberChain + } + ); + parser.hooks.expression .for(harmonySpecifierTag) - .tap("HarmonyImportDependencyParserPlugin", (expr, members) => { + .tap("HarmonyImportDependencyParserPlugin", expr => { const settings = /** @type {HarmonySettings} */ (parser.currentTagData); - const ids = settings.ids.concat(members); const dep = new HarmonyImportSpecifierDependency( settings.source, settings.sourceOrder, - ids, + settings.ids, settings.name, - expr.range, - this.strictExportPresence + /** @type {Range} */ (expr.range), + exportPresenceMode, + settings.assertions, + [] + ); + dep.referencedPropertiesInDestructuring = + parser.destructuringAssignmentPropertiesFor(expr); + dep.shorthand = parser.scope.inShorthand; + dep.directImport = true; + dep.asiSafe = !parser.isAsiPosition( + /** @type {Range} */ (expr.range)[0] ); - dep.asiSafe = !parser.isAsiPosition(expr.range[0]); - dep.loc = expr.loc; + dep.loc = /** @type {DependencyLocation} */ (expr.loc); + dep.call = parser.scope.inTaggedTemplateTag; parser.state.module.addDependency(dep); InnerGraph.onUsage(parser.state, e => (dep.usedByExports = e)); return true; }); + parser.hooks.expressionMemberChain + .for(harmonySpecifierTag) + .tap( + "HarmonyImportDependencyParserPlugin", + (expression, members, membersOptionals, memberRanges) => { + const settings = /** @type {HarmonySettings} */ ( + parser.currentTagData + ); + const nonOptionalMembers = getNonOptionalPart( + members, + membersOptionals + ); + /** @type {Range[]} */ + const ranges = memberRanges.slice( + 0, + memberRanges.length - (members.length - nonOptionalMembers.length) + ); + const expr = + nonOptionalMembers !== members + ? getNonOptionalMemberChain( + expression, + members.length - nonOptionalMembers.length + ) + : expression; + const ids = settings.ids.concat(nonOptionalMembers); + const dep = new HarmonyImportSpecifierDependency( + settings.source, + settings.sourceOrder, + ids, + settings.name, + /** @type {Range} */ (expr.range), + exportPresenceMode, + settings.assertions, + ranges + ); + dep.referencedPropertiesInDestructuring = + parser.destructuringAssignmentPropertiesFor(expr); + dep.asiSafe = !parser.isAsiPosition( + /** @type {Range} */ (expr.range)[0] + ); + dep.loc = /** @type {DependencyLocation} */ (expr.loc); + parser.state.module.addDependency(dep); + InnerGraph.onUsage(parser.state, e => (dep.usedByExports = e)); + return true; + } + ); parser.hooks.callMemberChain .for(harmonySpecifierTag) - .tap("HarmonyImportDependencyParserPlugin", (expr, members) => { - const { arguments: args, callee } = expr; - const settings = /** @type {HarmonySettings} */ (parser.currentTagData); - const ids = settings.ids.concat(members); - const dep = new HarmonyImportSpecifierDependency( - settings.source, - settings.sourceOrder, - ids, - settings.name, - callee.range, - this.strictExportPresence - ); - dep.directImport = members.length === 0; - dep.call = true; - dep.asiSafe = !parser.isAsiPosition(callee.range[0]); - // only in case when we strictly follow the spec we need a special case here - dep.namespaceObjectAsContext = - members.length > 0 && this.strictThisContextOnImports; - dep.loc = callee.loc; - parser.state.module.addDependency(dep); - if (args) parser.walkExpressions(args); - InnerGraph.onUsage(parser.state, e => (dep.usedByExports = e)); - return true; - }); - const { - hotAcceptCallback, - hotAcceptWithoutCallback - } = HotModuleReplacementPlugin.getParserHooks(parser); + .tap( + "HarmonyImportDependencyParserPlugin", + (expression, members, membersOptionals, memberRanges) => { + const { arguments: args, callee } = expression; + const settings = /** @type {HarmonySettings} */ ( + parser.currentTagData + ); + const nonOptionalMembers = getNonOptionalPart( + members, + membersOptionals + ); + /** @type {Range[]} */ + const ranges = memberRanges.slice( + 0, + memberRanges.length - (members.length - nonOptionalMembers.length) + ); + const expr = + nonOptionalMembers !== members + ? getNonOptionalMemberChain( + callee, + members.length - nonOptionalMembers.length + ) + : callee; + const ids = settings.ids.concat(nonOptionalMembers); + const dep = new HarmonyImportSpecifierDependency( + settings.source, + settings.sourceOrder, + ids, + settings.name, + /** @type {Range} */ (expr.range), + exportPresenceMode, + settings.assertions, + ranges + ); + dep.directImport = members.length === 0; + dep.call = true; + dep.asiSafe = !parser.isAsiPosition( + /** @type {Range} */ (expr.range)[0] + ); + // only in case when we strictly follow the spec we need a special case here + dep.namespaceObjectAsContext = + members.length > 0 && + /** @type {boolean} */ (this.strictThisContextOnImports); + dep.loc = /** @type {DependencyLocation} */ (expr.loc); + parser.state.module.addDependency(dep); + if (args) parser.walkExpressions(args); + InnerGraph.onUsage(parser.state, e => (dep.usedByExports = e)); + return true; + } + ); + const { hotAcceptCallback, hotAcceptWithoutCallback } = + HotModuleReplacementPlugin.getParserHooks(parser); hotAcceptCallback.tap( "HarmonyImportDependencyParserPlugin", (expr, requests) => { @@ -208,3 +432,6 @@ module.exports = class HarmonyImportDependencyParserPlugin { }; module.exports.harmonySpecifierTag = harmonySpecifierTag; +// TODO remove it in webpack@6 in favor getAttributes +module.exports.getAssertions = getAttributes; +module.exports.getAttributes = getAttributes; diff --git a/lib/dependencies/HarmonyImportSideEffectDependency.js b/lib/dependencies/HarmonyImportSideEffectDependency.js index f5a3d7d990b..bf691745ed3 100644 --- a/lib/dependencies/HarmonyImportSideEffectDependency.js +++ b/lib/dependencies/HarmonyImportSideEffectDependency.js @@ -10,18 +10,24 @@ const HarmonyImportDependency = require("./HarmonyImportDependency"); /** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */ /** @typedef {import("../Dependency")} Dependency */ +/** @typedef {import("../Dependency").GetConditionFn} GetConditionFn */ /** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */ -/** @typedef {import("../InitFragment")} InitFragment */ /** @typedef {import("../Module")} Module */ /** @typedef {import("../ModuleGraph")} ModuleGraph */ /** @typedef {import("../ModuleGraphConnection")} ModuleGraphConnection */ /** @typedef {import("../ModuleGraphConnection").ConnectionState} ConnectionState */ +/** @typedef {import("../javascript/JavascriptParser").ImportAttributes} ImportAttributes */ /** @typedef {import("../util/Hash")} Hash */ /** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */ class HarmonyImportSideEffectDependency extends HarmonyImportDependency { - constructor(request, sourceOrder) { - super(request, sourceOrder); + /** + * @param {string} request the request string + * @param {number} sourceOrder source order + * @param {ImportAttributes=} attributes import attributes + */ + constructor(request, sourceOrder, attributes) { + super(request, sourceOrder, attributes); } get type() { @@ -30,7 +36,7 @@ class HarmonyImportSideEffectDependency extends HarmonyImportDependency { /** * @param {ModuleGraph} moduleGraph module graph - * @returns {null | false | function(ModuleGraphConnection, RuntimeSpec): ConnectionState} function to determine if the connection is active + * @returns {null | false | GetConditionFn} function to determine if the connection is active */ getCondition(moduleGraph) { return connection => { @@ -68,7 +74,7 @@ HarmonyImportSideEffectDependency.Template = class HarmonyImportSideEffectDepend apply(dependency, source, templateContext) { const { moduleGraph, concatenationScope } = templateContext; if (concatenationScope) { - const module = moduleGraph.getModule(dependency); + const module = /** @type {Module} */ (moduleGraph.getModule(dependency)); if (concatenationScope.isModuleInScope(module)) { return; } diff --git a/lib/dependencies/HarmonyImportSpecifierDependency.js b/lib/dependencies/HarmonyImportSpecifierDependency.js index 233ee546ee1..277624e7662 100644 --- a/lib/dependencies/HarmonyImportSpecifierDependency.js +++ b/lib/dependencies/HarmonyImportSpecifierDependency.js @@ -6,9 +6,11 @@ "use strict"; const Dependency = require("../Dependency"); +const Template = require("../Template"); const { getDependencyUsedByExportsCondition } = require("../optimize/InnerGraph"); +const { getTrimmedIdsAndRange } = require("../util/chainedImports"); const makeSerializable = require("../util/makeSerializable"); const propertyAccess = require("../util/propertyAccess"); const HarmonyImportDependency = require("./HarmonyImportDependency"); @@ -16,32 +18,64 @@ const HarmonyImportDependency = require("./HarmonyImportDependency"); /** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */ /** @typedef {import("../ChunkGraph")} ChunkGraph */ /** @typedef {import("../Dependency").ExportsSpec} ExportsSpec */ +/** @typedef {import("../Dependency").GetConditionFn} GetConditionFn */ /** @typedef {import("../Dependency").ReferencedExport} ReferencedExport */ /** @typedef {import("../Dependency").UpdateHashContext} UpdateHashContext */ /** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */ +/** @typedef {import("../Module")} Module */ +/** @typedef {import("../Module").BuildMeta} BuildMeta */ /** @typedef {import("../ModuleGraph")} ModuleGraph */ /** @typedef {import("../ModuleGraphConnection")} ModuleGraphConnection */ /** @typedef {import("../ModuleGraphConnection").ConnectionState} ConnectionState */ /** @typedef {import("../WebpackError")} WebpackError */ +/** @typedef {import("../javascript/JavascriptParser").DestructuringAssignmentProperty} DestructuringAssignmentProperty */ +/** @typedef {import("../javascript/JavascriptParser").ImportAttributes} ImportAttributes */ +/** @typedef {import("../javascript/JavascriptParser").Range} Range */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */ /** @typedef {import("../util/Hash")} Hash */ /** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */ const idsSymbol = Symbol("HarmonyImportSpecifierDependency.ids"); +const { ExportPresenceModes } = HarmonyImportDependency; + class HarmonyImportSpecifierDependency extends HarmonyImportDependency { - constructor(request, sourceOrder, ids, name, range, strictExportPresence) { - super(request, sourceOrder); + /** + * @param {string} request request + * @param {number} sourceOrder source order + * @param {string[]} ids ids + * @param {string} name name + * @param {Range} range range + * @param {TODO} exportPresenceMode export presence mode + * @param {ImportAttributes | undefined} attributes import attributes + * @param {Range[] | undefined} idRanges ranges for members of ids; the two arrays are right-aligned + */ + constructor( + request, + sourceOrder, + ids, + name, + range, + exportPresenceMode, + attributes, + idRanges // TODO webpack 6 make this non-optional. It must always be set to properly trim ids. + ) { + super(request, sourceOrder, attributes); this.ids = ids; this.name = name; this.range = range; - this.strictExportPresence = strictExportPresence; + this.idRanges = idRanges; + this.exportPresenceMode = exportPresenceMode; this.namespaceObjectAsContext = false; this.call = undefined; this.directImport = undefined; this.shorthand = undefined; this.asiSafe = undefined; - /** @type {Set | boolean} */ + /** @type {Set | boolean | undefined} */ this.usedByExports = undefined; + /** @type {Set | undefined} */ + this.referencedPropertiesInDestructuring = undefined; } // TODO webpack 6 remove @@ -70,7 +104,7 @@ class HarmonyImportSpecifierDependency extends HarmonyImportDependency { getIds(moduleGraph) { const meta = moduleGraph.getMetaIfExisting(this); if (meta === undefined) return this.ids; - const ids = meta[idsSymbol]; + const ids = meta[/** @type {keyof object} */ (idsSymbol)]; return ids !== undefined ? ids : this.ids; } @@ -85,7 +119,7 @@ class HarmonyImportSpecifierDependency extends HarmonyImportDependency { /** * @param {ModuleGraph} moduleGraph module graph - * @returns {null | false | function(ModuleGraphConnection, RuntimeSpec): ConnectionState} function to determine if the connection is active + * @returns {null | false | GetConditionFn} function to determine if the connection is active */ getCondition(moduleGraph) { return getDependencyUsedByExportsCondition( @@ -111,20 +145,26 @@ class HarmonyImportSpecifierDependency extends HarmonyImportDependency { */ getReferencedExports(moduleGraph, runtime) { let ids = this.getIds(moduleGraph); - if (ids.length === 0) return Dependency.EXPORTS_OBJECT_REFERENCED; + if (ids.length === 0) return this._getReferencedExportsInDestructuring(); let namespaceObjectAsContext = this.namespaceObjectAsContext; if (ids[0] === "default") { - const selfModule = moduleGraph.getParentModule(this); - const importedModule = moduleGraph.getModule(this); + const selfModule = + /** @type {Module} */ + (moduleGraph.getParentModule(this)); + const importedModule = + /** @type {Module} */ + (moduleGraph.getModule(this)); switch ( importedModule.getExportsType( moduleGraph, - selfModule.buildMeta.strictHarmonyModule + /** @type {BuildMeta} */ + (selfModule.buildMeta).strictHarmonyModule ) ) { case "default-only": case "default-with-named": - if (ids.length === 1) return Dependency.EXPORTS_OBJECT_REFERENCED; + if (ids.length === 1) + return this._getReferencedExportsInDestructuring(); ids = ids.slice(1); namespaceObjectAsContext = true; break; @@ -142,34 +182,64 @@ class HarmonyImportSpecifierDependency extends HarmonyImportDependency { ids = ids.slice(0, -1); } - return [ids]; + return this._getReferencedExportsInDestructuring(ids); + } + + /** + * @param {string[]=} ids ids + * @returns {string[][]} referenced exports + */ + _getReferencedExportsInDestructuring(ids) { + if (this.referencedPropertiesInDestructuring) { + /** @type {string[][]} */ + const refs = []; + for (const { id } of this.referencedPropertiesInDestructuring) { + refs.push(ids ? ids.concat([id]) : [id]); + } + return refs; + } + return ids ? [ids] : Dependency.EXPORTS_OBJECT_REFERENCED; + } + + /** + * @param {ModuleGraph} moduleGraph module graph + * @returns {number} effective mode + */ + _getEffectiveExportPresenceLevel(moduleGraph) { + if (this.exportPresenceMode !== ExportPresenceModes.AUTO) + return this.exportPresenceMode; + const buildMeta = + /** @type {BuildMeta} */ + ( + /** @type {Module} */ + (moduleGraph.getParentModule(this)).buildMeta + ); + return buildMeta.strictHarmonyModule + ? ExportPresenceModes.ERROR + : ExportPresenceModes.WARN; } /** * Returns warnings * @param {ModuleGraph} moduleGraph module graph - * @returns {WebpackError[]} warnings + * @returns {WebpackError[] | null | undefined} warnings */ getWarnings(moduleGraph) { - if ( - this.strictExportPresence || - moduleGraph.getParentModule(this).buildMeta.strictHarmonyModule - ) { - return null; + const exportsPresence = this._getEffectiveExportPresenceLevel(moduleGraph); + if (exportsPresence === ExportPresenceModes.WARN) { + return this._getErrors(moduleGraph); } - return this._getErrors(moduleGraph); + return null; } /** * Returns errors * @param {ModuleGraph} moduleGraph module graph - * @returns {WebpackError[]} errors + * @returns {WebpackError[] | null | undefined} errors */ getErrors(moduleGraph) { - if ( - this.strictExportPresence || - moduleGraph.getParentModule(this).buildMeta.strictHarmonyModule - ) { + const exportsPresence = this._getEffectiveExportPresenceLevel(moduleGraph); + if (exportsPresence === ExportPresenceModes.ERROR) { return this._getErrors(moduleGraph); } return null; @@ -196,33 +266,43 @@ class HarmonyImportSpecifierDependency extends HarmonyImportDependency { return 0; } + /** + * @param {ObjectSerializerContext} context context + */ serialize(context) { const { write } = context; write(this.ids); write(this.name); write(this.range); - write(this.strictExportPresence); + write(this.idRanges); + write(this.exportPresenceMode); write(this.namespaceObjectAsContext); write(this.call); write(this.directImport); write(this.shorthand); write(this.asiSafe); write(this.usedByExports); + write(this.referencedPropertiesInDestructuring); super.serialize(context); } + /** + * @param {ObjectDeserializerContext} context context + */ deserialize(context) { const { read } = context; this.ids = read(); this.name = read(); this.range = read(); - this.strictExportPresence = read(); + this.idRanges = read(); + this.exportPresenceMode = read(); this.namespaceObjectAsContext = read(); this.call = read(); this.directImport = read(); this.shorthand = read(); this.asiSafe = read(); this.usedByExports = read(); + this.referencedPropertiesInDestructuring = read(); super.deserialize(context); } } @@ -243,18 +323,90 @@ HarmonyImportSpecifierDependency.Template = class HarmonyImportSpecifierDependen */ apply(dependency, source, templateContext) { const dep = /** @type {HarmonyImportSpecifierDependency} */ (dependency); - const { - moduleGraph, - module, - runtime, - concatenationScope - } = templateContext; + const { moduleGraph, runtime } = templateContext; const connection = moduleGraph.getConnection(dep); // Skip rendering depending when dependency is conditional if (connection && !connection.isTargetActive(runtime)) return; const ids = dep.getIds(moduleGraph); + const { + trimmedRange: [trimmedRangeStart, trimmedRangeEnd], + trimmedIds + } = getTrimmedIdsAndRange(ids, dep.range, dep.idRanges, moduleGraph, dep); + + const exportExpr = this._getCodeForIds( + dep, + source, + templateContext, + trimmedIds + ); + if (dep.shorthand) { + source.insert(trimmedRangeEnd, `: ${exportExpr}`); + } else { + source.replace(trimmedRangeStart, trimmedRangeEnd - 1, exportExpr); + } + + if (dep.referencedPropertiesInDestructuring) { + let prefixedIds = ids; + if (ids[0] === "default") { + const selfModule = moduleGraph.getParentModule(dep); + const importedModule = + /** @type {Module} */ + (moduleGraph.getModule(dep)); + const exportsType = importedModule.getExportsType( + moduleGraph, + /** @type {BuildMeta} */ + (selfModule.buildMeta).strictHarmonyModule + ); + if ( + (exportsType === "default-only" || + exportsType === "default-with-named") && + ids.length >= 1 + ) { + prefixedIds = ids.slice(1); + } + } + + for (const { + id, + shorthand, + range + } of dep.referencedPropertiesInDestructuring) { + const concatedIds = prefixedIds.concat([id]); + const module = /** @type {Module} */ (moduleGraph.getModule(dep)); + const used = moduleGraph + .getExportsInfo(module) + .getUsedName(concatedIds, runtime); + if (!used) return; + const newName = used[used.length - 1]; + const name = concatedIds[concatedIds.length - 1]; + if (newName === name) continue; + + const comment = `${Template.toNormalComment(name)} `; + const key = comment + JSON.stringify(newName); + source.replace( + /** @type {Range} */ + (range)[0], + /** @type {Range} */ + (range)[1] - 1, + shorthand ? `${key}: ${name}` : `${key}` + ); + } + } + } + + /** + * @param {HarmonyImportSpecifierDependency} dep dependency + * @param {ReplaceSource} source source + * @param {DependencyTemplateContext} templateContext context + * @param {string[]} ids ids + * @returns {string} generated code + */ + _getCodeForIds(dep, source, templateContext, ids) { + const { moduleGraph, module, runtime, concatenationScope } = + templateContext; + const connection = moduleGraph.getConnection(dep); let exportExpr; if ( connection && @@ -285,17 +437,14 @@ HarmonyImportSpecifierDependency.Template = class HarmonyImportSpecifierDependen ); } } else { - super.apply(dependency, source, templateContext); + super.apply(dep, source, templateContext); - const { - runtimeTemplate, - initFragments, - runtimeRequirements - } = templateContext; + const { runtimeTemplate, initFragments, runtimeRequirements } = + templateContext; exportExpr = runtimeTemplate.exportFromImport({ moduleGraph, - module: moduleGraph.getModule(dep), + module: /** @type {Module} */ (moduleGraph.getModule(dep)), request: dep.request, exportName: ids, originModule: module, @@ -309,11 +458,7 @@ HarmonyImportSpecifierDependency.Template = class HarmonyImportSpecifierDependen runtimeRequirements }); } - if (dep.shorthand) { - source.insert(dep.range[1], `: ${exportExpr}`); - } else { - source.replace(dep.range[0], dep.range[1] - 1, exportExpr); - } + return exportExpr; } }; diff --git a/lib/dependencies/HarmonyModulesPlugin.js b/lib/dependencies/HarmonyModulesPlugin.js index c17b48d7ee3..a3bbd98de82 100644 --- a/lib/dependencies/HarmonyModulesPlugin.js +++ b/lib/dependencies/HarmonyModulesPlugin.js @@ -8,6 +8,7 @@ const HarmonyAcceptDependency = require("./HarmonyAcceptDependency"); const HarmonyAcceptImportDependency = require("./HarmonyAcceptImportDependency"); const HarmonyCompatibilityDependency = require("./HarmonyCompatibilityDependency"); +const HarmonyEvaluatedImportSpecifierDependency = require("./HarmonyEvaluatedImportSpecifierDependency"); const HarmonyExportExpressionDependency = require("./HarmonyExportExpressionDependency"); const HarmonyExportHeaderDependency = require("./HarmonyExportHeaderDependency"); const HarmonyExportImportedSpecifierDependency = require("./HarmonyExportImportedSpecifierDependency"); @@ -15,14 +16,27 @@ const HarmonyExportSpecifierDependency = require("./HarmonyExportSpecifierDepend const HarmonyImportSideEffectDependency = require("./HarmonyImportSideEffectDependency"); const HarmonyImportSpecifierDependency = require("./HarmonyImportSpecifierDependency"); +const { + JAVASCRIPT_MODULE_TYPE_AUTO, + JAVASCRIPT_MODULE_TYPE_ESM +} = require("../ModuleTypeConstants"); const HarmonyDetectionParserPlugin = require("./HarmonyDetectionParserPlugin"); const HarmonyExportDependencyParserPlugin = require("./HarmonyExportDependencyParserPlugin"); const HarmonyImportDependencyParserPlugin = require("./HarmonyImportDependencyParserPlugin"); const HarmonyTopLevelThisParserPlugin = require("./HarmonyTopLevelThisParserPlugin"); +/** @typedef {import("../../declarations/WebpackOptions").JavascriptParserOptions} JavascriptParserOptions */ /** @typedef {import("../Compiler")} Compiler */ +/** @typedef {import("../javascript/JavascriptParser")} Parser */ + +const PLUGIN_NAME = "HarmonyModulesPlugin"; + +/** @typedef {{ topLevelAwait?: boolean }} HarmonyModulesPluginOptions */ class HarmonyModulesPlugin { + /** + * @param {HarmonyModulesPluginOptions} options options + */ constructor(options) { this.options = options; } @@ -34,7 +48,7 @@ class HarmonyModulesPlugin { */ apply(compiler) { compiler.hooks.compilation.tap( - "HarmonyModulesPlugin", + PLUGIN_NAME, (compilation, { normalModuleFactory }) => { compilation.dependencyTemplates.set( HarmonyCompatibilityDependency, @@ -59,6 +73,15 @@ class HarmonyModulesPlugin { new HarmonyImportSpecifierDependency.Template() ); + compilation.dependencyFactories.set( + HarmonyEvaluatedImportSpecifierDependency, + normalModuleFactory + ); + compilation.dependencyTemplates.set( + HarmonyEvaluatedImportSpecifierDependency, + new HarmonyEvaluatedImportSpecifierDependency.Template() + ); + compilation.dependencyTemplates.set( HarmonyExportHeaderDependency, new HarmonyExportHeaderDependency.Template() @@ -97,6 +120,11 @@ class HarmonyModulesPlugin { new HarmonyAcceptImportDependency.Template() ); + /** + * @param {Parser} parser parser parser + * @param {JavascriptParserOptions} parserOptions parserOptions + * @returns {void} + */ const handler = (parser, parserOptions) => { // TODO webpack 6: rename harmony to esm or module if (parserOptions.harmony !== undefined && !parserOptions.harmony) @@ -109,11 +137,11 @@ class HarmonyModulesPlugin { }; normalModuleFactory.hooks.parser - .for("javascript/auto") - .tap("HarmonyModulesPlugin", handler); + .for(JAVASCRIPT_MODULE_TYPE_AUTO) + .tap(PLUGIN_NAME, handler); normalModuleFactory.hooks.parser - .for("javascript/esm") - .tap("HarmonyModulesPlugin", handler); + .for(JAVASCRIPT_MODULE_TYPE_ESM) + .tap(PLUGIN_NAME, handler); } ); } diff --git a/lib/dependencies/HarmonyTopLevelThisParserPlugin.js b/lib/dependencies/HarmonyTopLevelThisParserPlugin.js index 9981c10fd0c..b8ba1848649 100644 --- a/lib/dependencies/HarmonyTopLevelThisParserPlugin.js +++ b/lib/dependencies/HarmonyTopLevelThisParserPlugin.js @@ -8,17 +8,29 @@ const ConstDependency = require("./ConstDependency"); const HarmonyExports = require("./HarmonyExports"); +/** @typedef {import("../Dependency").DependencyLocation} DependencyLocation */ +/** @typedef {import("../javascript/JavascriptParser")} JavascriptParser */ +/** @typedef {import("../javascript/JavascriptParser").Range} Range */ + class HarmonyTopLevelThisParserPlugin { + /** + * @param {JavascriptParser} parser the parser + * @returns {void} + */ apply(parser) { parser.hooks.expression .for("this") .tap("HarmonyTopLevelThisParserPlugin", node => { if (!parser.scope.topLevelScope) return; if (HarmonyExports.isEnabled(parser.state)) { - const dep = new ConstDependency("undefined", node.range, null); - dep.loc = node.loc; + const dep = new ConstDependency( + "undefined", + /** @type {Range} */ (node.range), + null + ); + dep.loc = /** @type {DependencyLocation} */ (node.loc); parser.state.module.addPresentationalDependency(dep); - return this; + return true; } }); } diff --git a/lib/dependencies/ImportContextDependency.js b/lib/dependencies/ImportContextDependency.js index f7f5f89d2ba..a1811e722bc 100644 --- a/lib/dependencies/ImportContextDependency.js +++ b/lib/dependencies/ImportContextDependency.js @@ -9,7 +9,16 @@ const makeSerializable = require("../util/makeSerializable"); const ContextDependency = require("./ContextDependency"); const ContextDependencyTemplateAsRequireCall = require("./ContextDependencyTemplateAsRequireCall"); +/** @typedef {import("../javascript/JavascriptParser").Range} Range */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */ + class ImportContextDependency extends ContextDependency { + /** + * @param {TODO} options options + * @param {Range} range range + * @param {Range} valueRange value range + */ constructor(options, range, valueRange) { super(options); @@ -25,19 +34,23 @@ class ImportContextDependency extends ContextDependency { return "esm"; } + /** + * @param {ObjectSerializerContext} context context + */ serialize(context) { const { write } = context; - write(this.range); write(this.valueRange); super.serialize(context); } + /** + * @param {ObjectDeserializerContext} context context + */ deserialize(context) { const { read } = context; - this.range = read(); this.valueRange = read(); super.deserialize(context); diff --git a/lib/dependencies/ImportDependency.js b/lib/dependencies/ImportDependency.js index 4df2c622745..1368d405a10 100644 --- a/lib/dependencies/ImportDependency.js +++ b/lib/dependencies/ImportDependency.js @@ -13,19 +13,27 @@ const ModuleDependency = require("./ModuleDependency"); /** @typedef {import("../AsyncDependenciesBlock")} AsyncDependenciesBlock */ /** @typedef {import("../Dependency").ReferencedExport} ReferencedExport */ /** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */ +/** @typedef {import("../Module")} Module */ +/** @typedef {import("../Module").BuildMeta} BuildMeta */ /** @typedef {import("../ModuleGraph")} ModuleGraph */ +/** @typedef {import("../javascript/JavascriptParser").ImportAttributes} ImportAttributes */ +/** @typedef {import("../javascript/JavascriptParser").Range} Range */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */ /** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */ class ImportDependency extends ModuleDependency { /** * @param {string} request the request - * @param {[number, number]} range expression range - * @param {string[][]=} referencedExports list of referenced exports + * @param {Range} range expression range + * @param {(string[][] | null)=} referencedExports list of referenced exports + * @param {ImportAttributes=} attributes import attributes */ - constructor(request, range, referencedExports) { + constructor(request, range, referencedExports, attributes) { super(request); this.range = range; this.referencedExports = referencedExports; + this.assertions = attributes; } get type() { @@ -43,23 +51,53 @@ class ImportDependency extends ModuleDependency { * @returns {(string[] | ReferencedExport)[]} referenced exports */ getReferencedExports(moduleGraph, runtime) { - return this.referencedExports - ? this.referencedExports.map(e => ({ - name: e, - canMangle: false - })) - : Dependency.EXPORTS_OBJECT_REFERENCED; + if (!this.referencedExports) return Dependency.EXPORTS_OBJECT_REFERENCED; + const refs = []; + for (const referencedExport of this.referencedExports) { + if (referencedExport[0] === "default") { + const selfModule = + /** @type {Module} */ + (moduleGraph.getParentModule(this)); + const importedModule = + /** @type {Module} */ + (moduleGraph.getModule(this)); + const exportsType = importedModule.getExportsType( + moduleGraph, + /** @type {BuildMeta} */ + (selfModule.buildMeta).strictHarmonyModule + ); + if ( + exportsType === "default-only" || + exportsType === "default-with-named" + ) { + return Dependency.EXPORTS_OBJECT_REFERENCED; + } + } + refs.push({ + name: referencedExport, + canMangle: false + }); + } + return refs; } + /** + * @param {ObjectSerializerContext} context context + */ serialize(context) { context.write(this.range); context.write(this.referencedExports); + context.write(this.assertions); super.serialize(context); } + /** + * @param {ObjectDeserializerContext} context context + */ deserialize(context) { this.range = context.read(); this.referencedExports = context.read(); + this.assertions = context.read(); super.deserialize(context); } } @@ -81,15 +119,15 @@ ImportDependency.Template = class ImportDependencyTemplate extends ( { runtimeTemplate, module, moduleGraph, chunkGraph, runtimeRequirements } ) { const dep = /** @type {ImportDependency} */ (dependency); - const block = /** @type {AsyncDependenciesBlock} */ (moduleGraph.getParentBlock( - dep - )); + const block = /** @type {AsyncDependenciesBlock} */ ( + moduleGraph.getParentBlock(dep) + ); const content = runtimeTemplate.moduleNamespacePromise({ chunkGraph, - block: block, - module: moduleGraph.getModule(dep), + block, + module: /** @type {Module} */ (moduleGraph.getModule(dep)), request: dep.request, - strict: module.buildMeta.strictHarmonyModule, + strict: /** @type {BuildMeta} */ (module.buildMeta).strictHarmonyModule, message: "import()", runtimeRequirements }); diff --git a/lib/dependencies/ImportEagerDependency.js b/lib/dependencies/ImportEagerDependency.js index 2aa9a570385..dd607302029 100644 --- a/lib/dependencies/ImportEagerDependency.js +++ b/lib/dependencies/ImportEagerDependency.js @@ -12,16 +12,21 @@ const ImportDependency = require("./ImportDependency"); /** @typedef {import("../Dependency")} Dependency */ /** @typedef {import("../Dependency").ReferencedExport} ReferencedExport */ /** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */ +/** @typedef {import("../Module")} Module */ +/** @typedef {import("../Module").BuildMeta} BuildMeta */ /** @typedef {import("../ModuleGraph")} ModuleGraph */ +/** @typedef {import("../javascript/JavascriptParser").ImportAttributes} ImportAttributes */ +/** @typedef {import("../javascript/JavascriptParser").Range} Range */ class ImportEagerDependency extends ImportDependency { /** * @param {string} request the request - * @param {[number, number]} range expression range - * @param {string[][]=} referencedExports list of referenced exports + * @param {Range} range expression range + * @param {(string[][] | null)=} referencedExports list of referenced exports + * @param {ImportAttributes=} attributes import attributes */ - constructor(request, range, referencedExports) { - super(request, range, referencedExports); + constructor(request, range, referencedExports, attributes) { + super(request, range, referencedExports, attributes); } get type() { @@ -55,9 +60,9 @@ ImportEagerDependency.Template = class ImportEagerDependencyTemplate extends ( const dep = /** @type {ImportEagerDependency} */ (dependency); const content = runtimeTemplate.moduleNamespacePromise({ chunkGraph, - module: moduleGraph.getModule(dep), + module: /** @type {Module} */ (moduleGraph.getModule(dep)), request: dep.request, - strict: module.buildMeta.strictHarmonyModule, + strict: /** @type {BuildMeta} */ (module.buildMeta).strictHarmonyModule, message: "import() eager", runtimeRequirements }); diff --git a/lib/dependencies/ImportMetaContextDependency.js b/lib/dependencies/ImportMetaContextDependency.js new file mode 100644 index 00000000000..ee27ee1573f --- /dev/null +++ b/lib/dependencies/ImportMetaContextDependency.js @@ -0,0 +1,42 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Ivan Kopeykin @vankop +*/ + +"use strict"; + +const makeSerializable = require("../util/makeSerializable"); +const ContextDependency = require("./ContextDependency"); +const ModuleDependencyTemplateAsRequireId = require("./ModuleDependencyTemplateAsRequireId"); + +/** @typedef {import("../javascript/JavascriptParser").Range} Range */ +/** @typedef {import("./ContextDependency").ContextDependencyOptions} ContextDependencyOptions */ + +class ImportMetaContextDependency extends ContextDependency { + /** + * @param {ContextDependencyOptions} options options + * @param {Range} range range + */ + constructor(options, range) { + super(options); + + this.range = range; + } + + get category() { + return "esm"; + } + + get type() { + return `import.meta.webpackContext ${this.options.mode}`; + } +} + +makeSerializable( + ImportMetaContextDependency, + "webpack/lib/dependencies/ImportMetaContextDependency" +); + +ImportMetaContextDependency.Template = ModuleDependencyTemplateAsRequireId; + +module.exports = ImportMetaContextDependency; diff --git a/lib/dependencies/ImportMetaContextDependencyParserPlugin.js b/lib/dependencies/ImportMetaContextDependencyParserPlugin.js new file mode 100644 index 00000000000..753f0430e8d --- /dev/null +++ b/lib/dependencies/ImportMetaContextDependencyParserPlugin.js @@ -0,0 +1,301 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Ivan Kopeykin @vankop +*/ + +"use strict"; + +const WebpackError = require("../WebpackError"); +const { + evaluateToIdentifier +} = require("../javascript/JavascriptParserHelpers"); +const ImportMetaContextDependency = require("./ImportMetaContextDependency"); + +/** @typedef {import("estree").Expression} Expression */ +/** @typedef {import("estree").ObjectExpression} ObjectExpression */ +/** @typedef {import("estree").Property} Property */ +/** @typedef {import("estree").SourceLocation} SourceLocation */ +/** @typedef {import("../javascript/JavascriptParser")} JavascriptParser */ +/** @typedef {import("../javascript/JavascriptParser").Range} Range */ +/** @typedef {import("../ContextModule").ContextModuleOptions} ContextModuleOptions */ +/** @typedef {import("../ChunkGroup").RawChunkGroupOptions} RawChunkGroupOptions */ +/** @typedef {import("../Dependency").DependencyLocation} DependencyLocation */ +/** @typedef {import("../javascript/BasicEvaluatedExpression")} BasicEvaluatedExpression */ +/** @typedef {Pick&{groupOptions: RawChunkGroupOptions, exports?: ContextModuleOptions["referencedExports"]}} ImportMetaContextOptions */ + +/** + * @param {TODO} prop property + * @param {string} expect except message + * @returns {WebpackError} error + */ +function createPropertyParseError(prop, expect) { + return createError( + `Parsing import.meta.webpackContext options failed. Unknown value for property ${JSON.stringify( + prop.key.name + )}, expected type ${expect}.`, + prop.value.loc + ); +} + +/** + * @param {string} msg message + * @param {DependencyLocation} loc location + * @returns {WebpackError} error + */ +function createError(msg, loc) { + const error = new WebpackError(msg); + error.name = "ImportMetaContextError"; + error.loc = loc; + return error; +} + +module.exports = class ImportMetaContextDependencyParserPlugin { + /** + * @param {JavascriptParser} parser the parser + * @returns {void} + */ + apply(parser) { + parser.hooks.evaluateIdentifier + .for("import.meta.webpackContext") + .tap("ImportMetaContextDependencyParserPlugin", expr => + evaluateToIdentifier( + "import.meta.webpackContext", + "import.meta", + () => ["webpackContext"], + true + )(expr) + ); + parser.hooks.call + .for("import.meta.webpackContext") + .tap("ImportMetaContextDependencyParserPlugin", expr => { + if (expr.arguments.length < 1 || expr.arguments.length > 2) return; + const [directoryNode, optionsNode] = expr.arguments; + if (optionsNode && optionsNode.type !== "ObjectExpression") return; + const requestExpr = parser.evaluateExpression( + /** @type {Expression} */ (directoryNode) + ); + if (!requestExpr.isString()) return; + const request = /** @type {string} */ (requestExpr.string); + const errors = []; + let regExp = /^\.\/.*$/; + let recursive = true; + /** @type {ContextModuleOptions["mode"]} */ + let mode = "sync"; + /** @type {ContextModuleOptions["include"]} */ + let include; + /** @type {ContextModuleOptions["exclude"]} */ + let exclude; + /** @type {RawChunkGroupOptions} */ + const groupOptions = {}; + /** @type {ContextModuleOptions["chunkName"]} */ + let chunkName; + /** @type {ContextModuleOptions["referencedExports"]} */ + let exports; + if (optionsNode) { + for (const prop of /** @type {ObjectExpression} */ (optionsNode) + .properties) { + if (prop.type !== "Property" || prop.key.type !== "Identifier") { + errors.push( + createError( + "Parsing import.meta.webpackContext options failed.", + /** @type {DependencyLocation} */ (optionsNode.loc) + ) + ); + break; + } + switch (prop.key.name) { + case "regExp": { + const regExpExpr = parser.evaluateExpression( + /** @type {Expression} */ (prop.value) + ); + if (!regExpExpr.isRegExp()) { + errors.push(createPropertyParseError(prop, "RegExp")); + } else { + regExp = /** @type {RegExp} */ (regExpExpr.regExp); + } + break; + } + case "include": { + const regExpExpr = parser.evaluateExpression( + /** @type {Expression} */ (prop.value) + ); + if (!regExpExpr.isRegExp()) { + errors.push(createPropertyParseError(prop, "RegExp")); + } else { + include = regExpExpr.regExp; + } + break; + } + case "exclude": { + const regExpExpr = parser.evaluateExpression( + /** @type {Expression} */ (prop.value) + ); + if (!regExpExpr.isRegExp()) { + errors.push(createPropertyParseError(prop, "RegExp")); + } else { + exclude = regExpExpr.regExp; + } + break; + } + case "mode": { + const modeExpr = parser.evaluateExpression( + /** @type {Expression} */ (prop.value) + ); + if (!modeExpr.isString()) { + errors.push(createPropertyParseError(prop, "string")); + } else { + mode = /** @type {ContextModuleOptions["mode"]} */ ( + modeExpr.string + ); + } + break; + } + case "chunkName": { + const expr = parser.evaluateExpression( + /** @type {Expression} */ (prop.value) + ); + if (!expr.isString()) { + errors.push(createPropertyParseError(prop, "string")); + } else { + chunkName = expr.string; + } + break; + } + case "exports": { + const expr = parser.evaluateExpression( + /** @type {Expression} */ (prop.value) + ); + if (expr.isString()) { + exports = [[/** @type {string} */ (expr.string)]]; + } else if (expr.isArray()) { + const items = + /** @type {BasicEvaluatedExpression[]} */ + (expr.items); + if ( + items.every(i => { + if (!i.isArray()) return false; + const innerItems = + /** @type {BasicEvaluatedExpression[]} */ (i.items); + return innerItems.every(i => i.isString()); + }) + ) { + exports = []; + for (const i1 of items) { + /** @type {string[]} */ + const export_ = []; + for (const i2 of /** @type {BasicEvaluatedExpression[]} */ ( + i1.items + )) { + export_.push(/** @type {string} */ (i2.string)); + } + exports.push(export_); + } + } else { + errors.push( + createPropertyParseError(prop, "string|string[][]") + ); + } + } else { + errors.push( + createPropertyParseError(prop, "string|string[][]") + ); + } + break; + } + case "prefetch": { + const expr = parser.evaluateExpression( + /** @type {Expression} */ (prop.value) + ); + if (expr.isBoolean()) { + groupOptions.prefetchOrder = 0; + } else if (expr.isNumber()) { + groupOptions.prefetchOrder = expr.number; + } else { + errors.push(createPropertyParseError(prop, "boolean|number")); + } + break; + } + case "preload": { + const expr = parser.evaluateExpression( + /** @type {Expression} */ (prop.value) + ); + if (expr.isBoolean()) { + groupOptions.preloadOrder = 0; + } else if (expr.isNumber()) { + groupOptions.preloadOrder = expr.number; + } else { + errors.push(createPropertyParseError(prop, "boolean|number")); + } + break; + } + case "fetchPriority": { + const expr = parser.evaluateExpression( + /** @type {Expression} */ (prop.value) + ); + if ( + expr.isString() && + ["high", "low", "auto"].includes( + /** @type {string} */ (expr.string) + ) + ) { + groupOptions.fetchPriority = + /** @type {RawChunkGroupOptions["fetchPriority"]} */ ( + expr.string + ); + } else { + errors.push( + createPropertyParseError(prop, '"high"|"low"|"auto"') + ); + } + break; + } + case "recursive": { + const recursiveExpr = parser.evaluateExpression( + /** @type {Expression} */ (prop.value) + ); + if (!recursiveExpr.isBoolean()) { + errors.push(createPropertyParseError(prop, "boolean")); + } else { + recursive = /** @type {boolean} */ (recursiveExpr.bool); + } + break; + } + default: + errors.push( + createError( + `Parsing import.meta.webpackContext options failed. Unknown property ${JSON.stringify( + prop.key.name + )}.`, + /** @type {DependencyLocation} */ (optionsNode.loc) + ) + ); + } + } + } + if (errors.length) { + for (const error of errors) parser.state.current.addError(error); + return; + } + + const dep = new ImportMetaContextDependency( + { + request, + include, + exclude, + recursive, + regExp, + groupOptions, + chunkName, + referencedExports: exports, + mode, + category: "esm" + }, + /** @type {Range} */ (expr.range) + ); + dep.loc = /** @type {DependencyLocation} */ (expr.loc); + dep.optional = Boolean(parser.scope.inTry); + parser.state.current.addDependency(dep); + return true; + }); + } +}; diff --git a/lib/dependencies/ImportMetaContextPlugin.js b/lib/dependencies/ImportMetaContextPlugin.js new file mode 100644 index 00000000000..ed9ac05da53 --- /dev/null +++ b/lib/dependencies/ImportMetaContextPlugin.js @@ -0,0 +1,72 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Ivan Kopeykin @vankop +*/ + +"use strict"; + +const { + JAVASCRIPT_MODULE_TYPE_AUTO, + JAVASCRIPT_MODULE_TYPE_ESM +} = require("../ModuleTypeConstants"); +const ContextElementDependency = require("./ContextElementDependency"); +const ImportMetaContextDependency = require("./ImportMetaContextDependency"); +const ImportMetaContextDependencyParserPlugin = require("./ImportMetaContextDependencyParserPlugin"); + +/** @typedef {import("../../declarations/WebpackOptions").JavascriptParserOptions} JavascriptParserOptions */ +/** @typedef {import("../../declarations/WebpackOptions").ResolveOptions} ResolveOptions */ +/** @typedef {import("../Compiler")} Compiler */ +/** @typedef {import("../javascript/JavascriptParser")} Parser */ + +const PLUGIN_NAME = "ImportMetaContextPlugin"; + +class ImportMetaContextPlugin { + /** + * Apply the plugin + * @param {Compiler} compiler the compiler instance + * @returns {void} + */ + apply(compiler) { + compiler.hooks.compilation.tap( + PLUGIN_NAME, + (compilation, { contextModuleFactory, normalModuleFactory }) => { + compilation.dependencyFactories.set( + ImportMetaContextDependency, + contextModuleFactory + ); + compilation.dependencyTemplates.set( + ImportMetaContextDependency, + new ImportMetaContextDependency.Template() + ); + compilation.dependencyFactories.set( + ContextElementDependency, + normalModuleFactory + ); + + /** + * @param {Parser} parser parser parser + * @param {JavascriptParserOptions} parserOptions parserOptions + * @returns {void} + */ + const handler = (parser, parserOptions) => { + if ( + parserOptions.importMetaContext !== undefined && + !parserOptions.importMetaContext + ) + return; + + new ImportMetaContextDependencyParserPlugin().apply(parser); + }; + + normalModuleFactory.hooks.parser + .for(JAVASCRIPT_MODULE_TYPE_AUTO) + .tap(PLUGIN_NAME, handler); + normalModuleFactory.hooks.parser + .for(JAVASCRIPT_MODULE_TYPE_ESM) + .tap(PLUGIN_NAME, handler); + } + ); + } +} + +module.exports = ImportMetaContextPlugin; diff --git a/lib/dependencies/ImportMetaHotAcceptDependency.js b/lib/dependencies/ImportMetaHotAcceptDependency.js index 66329d7fcbb..70d8199338d 100644 --- a/lib/dependencies/ImportMetaHotAcceptDependency.js +++ b/lib/dependencies/ImportMetaHotAcceptDependency.js @@ -9,7 +9,13 @@ const makeSerializable = require("../util/makeSerializable"); const ModuleDependency = require("./ModuleDependency"); const ModuleDependencyTemplateAsId = require("./ModuleDependencyTemplateAsId"); +/** @typedef {import("../javascript/JavascriptParser").Range} Range */ + class ImportMetaHotAcceptDependency extends ModuleDependency { + /** + * @param {string} request the request string + * @param {Range} range location in source code + */ constructor(request, range) { super(request); this.range = range; diff --git a/lib/dependencies/ImportMetaHotDeclineDependency.js b/lib/dependencies/ImportMetaHotDeclineDependency.js index b9d1a5a57f5..c6c35a250ce 100644 --- a/lib/dependencies/ImportMetaHotDeclineDependency.js +++ b/lib/dependencies/ImportMetaHotDeclineDependency.js @@ -9,7 +9,13 @@ const makeSerializable = require("../util/makeSerializable"); const ModuleDependency = require("./ModuleDependency"); const ModuleDependencyTemplateAsId = require("./ModuleDependencyTemplateAsId"); +/** @typedef {import("../javascript/JavascriptParser").Range} Range */ + class ImportMetaHotDeclineDependency extends ModuleDependency { + /** + * @param {string} request the request string + * @param {Range} range location in source code + */ constructor(request, range) { super(request); diff --git a/lib/dependencies/ImportMetaPlugin.js b/lib/dependencies/ImportMetaPlugin.js index e5caed2c11d..ff9231d21d0 100644 --- a/lib/dependencies/ImportMetaPlugin.js +++ b/lib/dependencies/ImportMetaPlugin.js @@ -7,6 +7,10 @@ const { pathToFileURL } = require("url"); const ModuleDependencyWarning = require("../ModuleDependencyWarning"); +const { + JAVASCRIPT_MODULE_TYPE_AUTO, + JAVASCRIPT_MODULE_TYPE_ESM +} = require("../ModuleTypeConstants"); const Template = require("../Template"); const BasicEvaluatedExpression = require("../javascript/BasicEvaluatedExpression"); const { @@ -20,141 +24,206 @@ const propertyAccess = require("../util/propertyAccess"); const ConstDependency = require("./ConstDependency"); /** @typedef {import("estree").MemberExpression} MemberExpression */ +/** @typedef {import("../../declarations/WebpackOptions").JavascriptParserOptions} JavascriptParserOptions */ /** @typedef {import("../Compiler")} Compiler */ +/** @typedef {import("../Dependency").DependencyLocation} DependencyLocation */ /** @typedef {import("../NormalModule")} NormalModule */ /** @typedef {import("../javascript/JavascriptParser")} Parser */ +/** @typedef {import("../javascript/JavascriptParser").Range} Range */ const getCriticalDependencyWarning = memoize(() => require("./CriticalDependencyWarning") ); +const PLUGIN_NAME = "ImportMetaPlugin"; + class ImportMetaPlugin { /** * @param {Compiler} compiler compiler */ apply(compiler) { compiler.hooks.compilation.tap( - "ImportMetaPlugin", + PLUGIN_NAME, (compilation, { normalModuleFactory }) => { /** * @param {NormalModule} module module * @returns {string} file url */ - const getUrl = module => { - return pathToFileURL(module.resource).toString(); - }; + const getUrl = module => pathToFileURL(module.resource).toString(); /** - * @param {Parser} parser parser - * @param {Object} parserOptions parserOptions + * @param {Parser} parser parser parser + * @param {JavascriptParserOptions} parserOptions parserOptions * @returns {void} */ - const parserHandler = (parser, parserOptions) => { - /// import.meta direct /// + const parserHandler = (parser, { importMeta }) => { + if (importMeta === false) { + const { importMetaName } = compilation.outputOptions; + if (importMetaName === "import.meta") return; + + parser.hooks.expression + .for("import.meta") + .tap(PLUGIN_NAME, metaProperty => { + const dep = new ConstDependency( + /** @type {string} */ (importMetaName), + /** @type {Range} */ (metaProperty.range) + ); + dep.loc = /** @type {DependencyLocation} */ (metaProperty.loc); + parser.state.module.addPresentationalDependency(dep); + return true; + }); + return; + } + + // import.meta direct + const webpackVersion = Number.parseInt( + require("../../package.json").version, + 10 + ); + const importMetaUrl = () => + JSON.stringify(getUrl(parser.state.module)); + const importMetaWebpackVersion = () => JSON.stringify(webpackVersion); + /** + * @param {string[]} members members + * @returns {string} error message + */ + const importMetaUnknownProperty = members => + `${Template.toNormalComment( + `unsupported import.meta.${members.join(".")}` + )} undefined${propertyAccess(members, 1)}`; parser.hooks.typeof .for("import.meta") .tap( - "ImportMetaPlugin", + PLUGIN_NAME, toConstantDependency(parser, JSON.stringify("object")) ); parser.hooks.expression .for("import.meta") - .tap("ImportMetaPlugin", metaProperty => { - const CriticalDependencyWarning = getCriticalDependencyWarning(); - parser.state.module.addWarning( - new ModuleDependencyWarning( - parser.state.module, - new CriticalDependencyWarning( - "Accessing import.meta directly is unsupported (only property access is supported)" - ), - metaProperty.loc - ) - ); + .tap(PLUGIN_NAME, metaProperty => { + const referencedPropertiesInDestructuring = + parser.destructuringAssignmentPropertiesFor(metaProperty); + if (!referencedPropertiesInDestructuring) { + const CriticalDependencyWarning = + getCriticalDependencyWarning(); + parser.state.module.addWarning( + new ModuleDependencyWarning( + parser.state.module, + new CriticalDependencyWarning( + "Accessing import.meta directly is unsupported (only property access or destructuring is supported)" + ), + /** @type {DependencyLocation} */ (metaProperty.loc) + ) + ); + const dep = new ConstDependency( + `${ + parser.isAsiPosition( + /** @type {Range} */ (metaProperty.range)[0] + ) + ? ";" + : "" + }({})`, + /** @type {Range} */ (metaProperty.range) + ); + dep.loc = /** @type {DependencyLocation} */ (metaProperty.loc); + parser.state.module.addPresentationalDependency(dep); + return true; + } + + let str = ""; + for (const { id: prop } of referencedPropertiesInDestructuring) { + switch (prop) { + case "url": + str += `url: ${importMetaUrl()},`; + break; + case "webpack": + str += `webpack: ${importMetaWebpackVersion()},`; + break; + default: + str += `[${JSON.stringify( + prop + )}]: ${importMetaUnknownProperty([prop])},`; + break; + } + } const dep = new ConstDependency( - `${parser.isAsiPosition(metaProperty.range[0]) ? ";" : ""}({})`, - metaProperty.range + `({${str}})`, + /** @type {Range} */ (metaProperty.range) ); - dep.loc = metaProperty.loc; + dep.loc = /** @type {DependencyLocation} */ (metaProperty.loc); parser.state.module.addPresentationalDependency(dep); return true; }); parser.hooks.evaluateTypeof .for("import.meta") - .tap("ImportMetaPlugin", evaluateToString("object")); + .tap(PLUGIN_NAME, evaluateToString("object")); parser.hooks.evaluateIdentifier.for("import.meta").tap( - "ImportMetaPlugin", + PLUGIN_NAME, evaluateToIdentifier("import.meta", "import.meta", () => [], true) ); - /// import.meta.url /// + // import.meta.url parser.hooks.typeof .for("import.meta.url") .tap( - "ImportMetaPlugin", + PLUGIN_NAME, toConstantDependency(parser, JSON.stringify("string")) ); parser.hooks.expression .for("import.meta.url") - .tap("ImportMetaPlugin", expr => { + .tap(PLUGIN_NAME, expr => { const dep = new ConstDependency( - JSON.stringify(getUrl(parser.state.module)), - expr.range + importMetaUrl(), + /** @type {Range} */ (expr.range) ); - dep.loc = expr.loc; + dep.loc = /** @type {DependencyLocation} */ (expr.loc); parser.state.module.addPresentationalDependency(dep); return true; }); parser.hooks.evaluateTypeof .for("import.meta.url") - .tap("ImportMetaPlugin", evaluateToString("string")); + .tap(PLUGIN_NAME, evaluateToString("string")); parser.hooks.evaluateIdentifier .for("import.meta.url") - .tap("ImportMetaPlugin", expr => { - return new BasicEvaluatedExpression() + .tap(PLUGIN_NAME, expr => + new BasicEvaluatedExpression() .setString(getUrl(parser.state.module)) - .setRange(expr.range); - }); + .setRange(/** @type {Range} */ (expr.range)) + ); - /// import.meta.webpack /// - const webpackVersion = parseInt( - require("../../package.json").version, - 10 - ); + // import.meta.webpack parser.hooks.typeof .for("import.meta.webpack") .tap( - "ImportMetaPlugin", + PLUGIN_NAME, toConstantDependency(parser, JSON.stringify("number")) ); parser.hooks.expression .for("import.meta.webpack") .tap( - "ImportMetaPlugin", - toConstantDependency(parser, JSON.stringify(webpackVersion)) + PLUGIN_NAME, + toConstantDependency(parser, importMetaWebpackVersion()) ); parser.hooks.evaluateTypeof .for("import.meta.webpack") - .tap("ImportMetaPlugin", evaluateToString("number")); + .tap(PLUGIN_NAME, evaluateToString("number")); parser.hooks.evaluateIdentifier .for("import.meta.webpack") - .tap("ImportMetaPlugin", evaluateToNumber(webpackVersion)); + .tap(PLUGIN_NAME, evaluateToNumber(webpackVersion)); - /// Unknown properties /// + // Unknown properties parser.hooks.unhandledExpressionMemberChain .for("import.meta") - .tap("ImportMetaPlugin", (expr, members) => { + .tap(PLUGIN_NAME, (expr, members) => { const dep = new ConstDependency( - `${Template.toNormalComment( - "unsupported import.meta." + members.join(".") - )} undefined${propertyAccess(members, 1)}`, - expr.range + importMetaUnknownProperty(members), + /** @type {Range} */ (expr.range) ); - dep.loc = expr.loc; + dep.loc = /** @type {DependencyLocation} */ (expr.loc); parser.state.module.addPresentationalDependency(dep); return true; }); parser.hooks.evaluate .for("MemberExpression") - .tap("ImportMetaPlugin", expression => { + .tap(PLUGIN_NAME, expression => { const expr = /** @type {MemberExpression} */ (expression); if ( expr.object.type === "MetaProperty" && @@ -165,17 +234,17 @@ class ImportMetaPlugin { ) { return new BasicEvaluatedExpression() .setUndefined() - .setRange(expr.range); + .setRange(/** @type {Range} */ (expr.range)); } }); }; normalModuleFactory.hooks.parser - .for("javascript/auto") - .tap("ImportMetaPlugin", parserHandler); + .for(JAVASCRIPT_MODULE_TYPE_AUTO) + .tap(PLUGIN_NAME, parserHandler); normalModuleFactory.hooks.parser - .for("javascript/esm") - .tap("ImportMetaPlugin", parserHandler); + .for(JAVASCRIPT_MODULE_TYPE_ESM) + .tap(PLUGIN_NAME, parserHandler); } ); } diff --git a/lib/dependencies/ImportParserPlugin.js b/lib/dependencies/ImportParserPlugin.js index 17a46c826f4..0f92b5d1886 100644 --- a/lib/dependencies/ImportParserPlugin.js +++ b/lib/dependencies/ImportParserPlugin.js @@ -9,26 +9,46 @@ const AsyncDependenciesBlock = require("../AsyncDependenciesBlock"); const CommentCompilationWarning = require("../CommentCompilationWarning"); const UnsupportedFeatureWarning = require("../UnsupportedFeatureWarning"); const ContextDependencyHelpers = require("./ContextDependencyHelpers"); +const { getAttributes } = require("./HarmonyImportDependencyParserPlugin"); const ImportContextDependency = require("./ImportContextDependency"); const ImportDependency = require("./ImportDependency"); const ImportEagerDependency = require("./ImportEagerDependency"); const ImportWeakDependency = require("./ImportWeakDependency"); +/** @typedef {import("estree").ImportExpression} ImportExpression */ +/** @typedef {import("../../declarations/WebpackOptions").JavascriptParserOptions} JavascriptParserOptions */ /** @typedef {import("../ChunkGroup").RawChunkGroupOptions} RawChunkGroupOptions */ /** @typedef {import("../ContextModule").ContextMode} ContextMode */ +/** @typedef {import("../Dependency").DependencyLocation} DependencyLocation */ +/** @typedef {import("../Module").BuildMeta} BuildMeta */ +/** @typedef {import("../javascript/JavascriptParser")} JavascriptParser */ +/** @typedef {import("../javascript/JavascriptParser").Range} Range */ class ImportParserPlugin { + /** + * @param {JavascriptParserOptions} options options + */ constructor(options) { this.options = options; } + /** + * @param {JavascriptParser} parser the parser + * @returns {void} + */ apply(parser) { + /** + * @template T + * @param {Iterable} enumerable enumerable + * @returns {T[][]} array of array + */ + const exportsFromEnumerable = enumerable => + Array.from(enumerable, e => [e]); parser.hooks.importCall.tap("ImportParserPlugin", expr => { const param = parser.evaluateExpression(expr.source); let chunkName = null; - /** @type {ContextMode} */ - let mode = "lazy"; + let mode = /** @type {ContextMode} */ (this.options.dynamicImportMode); let include = null; let exclude = null; /** @type {string[][] | null} */ @@ -37,9 +57,27 @@ class ImportParserPlugin { const groupOptions = {}; const { - options: importOptions, - errors: commentErrors - } = parser.parseCommentOptions(expr.range); + dynamicImportPreload, + dynamicImportPrefetch, + dynamicImportFetchPriority + } = this.options; + if (dynamicImportPreload !== undefined && dynamicImportPreload !== false) + groupOptions.preloadOrder = + dynamicImportPreload === true ? 0 : dynamicImportPreload; + if ( + dynamicImportPrefetch !== undefined && + dynamicImportPrefetch !== false + ) + groupOptions.prefetchOrder = + dynamicImportPrefetch === true ? 0 : dynamicImportPrefetch; + if ( + dynamicImportFetchPriority !== undefined && + dynamicImportFetchPriority !== false + ) + groupOptions.fetchPriority = dynamicImportFetchPriority; + + const { options: importOptions, errors: commentErrors } = + parser.parseCommentOptions(/** @type {Range} */ (expr.range)); if (commentErrors) { for (const e of commentErrors) { @@ -59,14 +97,12 @@ class ImportParserPlugin { parser.state.module.addWarning( new UnsupportedFeatureWarning( `\`webpackIgnore\` expected a boolean, but received: ${importOptions.webpackIgnore}.`, - expr.loc + /** @type {DependencyLocation} */ (expr.loc) ) ); - } else { + } else if (importOptions.webpackIgnore) { // Do not instrument `import()` if `webpackIgnore` is `true` - if (importOptions.webpackIgnore) { - return false; - } + return false; } } if (importOptions.webpackChunkName !== undefined) { @@ -74,7 +110,7 @@ class ImportParserPlugin { parser.state.module.addWarning( new UnsupportedFeatureWarning( `\`webpackChunkName\` expected a string, but received: ${importOptions.webpackChunkName}.`, - expr.loc + /** @type {DependencyLocation} */ (expr.loc) ) ); } else { @@ -86,7 +122,7 @@ class ImportParserPlugin { parser.state.module.addWarning( new UnsupportedFeatureWarning( `\`webpackMode\` expected a string, but received: ${importOptions.webpackMode}.`, - expr.loc + /** @type {DependencyLocation} */ (expr.loc) ) ); } else { @@ -102,7 +138,7 @@ class ImportParserPlugin { parser.state.module.addWarning( new UnsupportedFeatureWarning( `\`webpackPrefetch\` expected true or a number, but received: ${importOptions.webpackPrefetch}.`, - expr.loc + /** @type {DependencyLocation} */ (expr.loc) ) ); } @@ -116,7 +152,22 @@ class ImportParserPlugin { parser.state.module.addWarning( new UnsupportedFeatureWarning( `\`webpackPreload\` expected true or a number, but received: ${importOptions.webpackPreload}.`, - expr.loc + /** @type {DependencyLocation} */ (expr.loc) + ) + ); + } + } + if (importOptions.webpackFetchPriority !== undefined) { + if ( + typeof importOptions.webpackFetchPriority === "string" && + ["high", "low", "auto"].includes(importOptions.webpackFetchPriority) + ) { + groupOptions.fetchPriority = importOptions.webpackFetchPriority; + } else { + parser.state.module.addWarning( + new UnsupportedFeatureWarning( + `\`webpackFetchPriority\` expected true or "low", "high" or "auto", but received: ${importOptions.webpackFetchPriority}.`, + /** @type {DependencyLocation} */ (expr.loc) ) ); } @@ -124,31 +175,31 @@ class ImportParserPlugin { if (importOptions.webpackInclude !== undefined) { if ( !importOptions.webpackInclude || - importOptions.webpackInclude.constructor.name !== "RegExp" + !(importOptions.webpackInclude instanceof RegExp) ) { parser.state.module.addWarning( new UnsupportedFeatureWarning( `\`webpackInclude\` expected a regular expression, but received: ${importOptions.webpackInclude}.`, - expr.loc + /** @type {DependencyLocation} */ (expr.loc) ) ); } else { - include = new RegExp(importOptions.webpackInclude); + include = importOptions.webpackInclude; } } if (importOptions.webpackExclude !== undefined) { if ( !importOptions.webpackExclude || - importOptions.webpackExclude.constructor.name !== "RegExp" + !(importOptions.webpackExclude instanceof RegExp) ) { parser.state.module.addWarning( new UnsupportedFeatureWarning( `\`webpackExclude\` expected a regular expression, but received: ${importOptions.webpackExclude}.`, - expr.loc + /** @type {DependencyLocation} */ (expr.loc) ) ); } else { - exclude = new RegExp(importOptions.webpackExclude); + exclude = importOptions.webpackExclude; } } if (importOptions.webpackExports !== undefined) { @@ -156,7 +207,7 @@ class ImportParserPlugin { !( typeof importOptions.webpackExports === "string" || (Array.isArray(importOptions.webpackExports) && - importOptions.webpackExports.every( + /** @type {string[]} */ (importOptions.webpackExports).every( item => typeof item === "string" )) ) @@ -164,41 +215,65 @@ class ImportParserPlugin { parser.state.module.addWarning( new UnsupportedFeatureWarning( `\`webpackExports\` expected a string or an array of strings, but received: ${importOptions.webpackExports}.`, - expr.loc + /** @type {DependencyLocation} */ (expr.loc) ) ); + } else if (typeof importOptions.webpackExports === "string") { + exports = [[importOptions.webpackExports]]; } else { - if (typeof importOptions.webpackExports === "string") { - exports = [[importOptions.webpackExports]]; - } else { - exports = Array.from(importOptions.webpackExports, e => [e]); - } + exports = exportsFromEnumerable(importOptions.webpackExports); } } } - if (param.isString()) { - if (mode !== "lazy" && mode !== "eager" && mode !== "weak") { + if ( + mode !== "lazy" && + mode !== "lazy-once" && + mode !== "eager" && + mode !== "weak" + ) { + parser.state.module.addWarning( + new UnsupportedFeatureWarning( + `\`webpackMode\` expected 'lazy', 'lazy-once', 'eager' or 'weak', but received: ${mode}.`, + /** @type {DependencyLocation} */ (expr.loc) + ) + ); + mode = "lazy"; + } + + const referencedPropertiesInDestructuring = + parser.destructuringAssignmentPropertiesFor(expr); + if (referencedPropertiesInDestructuring) { + if (exports) { parser.state.module.addWarning( new UnsupportedFeatureWarning( - `\`webpackMode\` expected 'lazy', 'eager' or 'weak', but received: ${mode}.`, - expr.loc + "`webpackExports` could not be used with destructuring assignment.", + /** @type {DependencyLocation} */ (expr.loc) ) ); } + exports = exportsFromEnumerable( + [...referencedPropertiesInDestructuring].map(({ id }) => id) + ); + } + + if (param.isString()) { + const attributes = getAttributes(expr); if (mode === "eager") { const dep = new ImportEagerDependency( - param.string, - expr.range, - exports + /** @type {string} */ (param.string), + /** @type {Range} */ (expr.range), + exports, + attributes ); parser.state.current.addDependency(dep); } else if (mode === "weak") { const dep = new ImportWeakDependency( - param.string, - expr.range, - exports + /** @type {string} */ (param.string), + /** @type {Range} */ (expr.range), + exports, + attributes ); parser.state.current.addDependency(dep); } else { @@ -207,60 +282,54 @@ class ImportParserPlugin { ...groupOptions, name: chunkName }, - expr.loc, + /** @type {DependencyLocation} */ (expr.loc), param.string ); - const dep = new ImportDependency(param.string, expr.range, exports); - dep.loc = expr.loc; + const dep = new ImportDependency( + /** @type {string} */ (param.string), + /** @type {Range} */ (expr.range), + exports, + attributes + ); + dep.loc = /** @type {DependencyLocation} */ (expr.loc); + dep.optional = Boolean(parser.scope.inTry); depBlock.addDependency(dep); parser.state.current.addBlock(depBlock); } return true; - } else { - if ( - mode !== "lazy" && - mode !== "lazy-once" && - mode !== "eager" && - mode !== "weak" - ) { - parser.state.module.addWarning( - new UnsupportedFeatureWarning( - `\`webpackMode\` expected 'lazy', 'lazy-once', 'eager' or 'weak', but received: ${mode}.`, - expr.loc - ) - ); - mode = "lazy"; - } - - if (mode === "weak") { - mode = "async-weak"; - } - const dep = ContextDependencyHelpers.create( - ImportContextDependency, - expr.range, - param, - expr, - this.options, - { - chunkName, - groupOptions, - include, - exclude, - mode, - namespaceObject: parser.state.module.buildMeta.strictHarmonyModule - ? "strict" - : true, - category: "esm", - referencedExports: exports - }, - parser - ); - if (!dep) return; - dep.loc = expr.loc; - dep.optional = !!parser.scope.inTry; - parser.state.current.addDependency(dep); - return true; } + if (mode === "weak") { + mode = "async-weak"; + } + const dep = ContextDependencyHelpers.create( + ImportContextDependency, + /** @type {Range} */ (expr.range), + param, + expr, + this.options, + { + chunkName, + groupOptions, + include, + exclude, + mode, + namespaceObject: /** @type {BuildMeta} */ ( + parser.state.module.buildMeta + ).strictHarmonyModule + ? "strict" + : true, + typePrefix: "import()", + category: "esm", + referencedExports: exports, + attributes: getAttributes(expr) + }, + parser + ); + if (!dep) return; + dep.loc = /** @type {DependencyLocation} */ (expr.loc); + dep.optional = Boolean(parser.scope.inTry); + parser.state.current.addDependency(dep); + return true; }); } } diff --git a/lib/dependencies/ImportPlugin.js b/lib/dependencies/ImportPlugin.js index d2628ef3ba0..4ee51a8f748 100644 --- a/lib/dependencies/ImportPlugin.js +++ b/lib/dependencies/ImportPlugin.js @@ -5,13 +5,22 @@ "use strict"; +const { + JAVASCRIPT_MODULE_TYPE_AUTO, + JAVASCRIPT_MODULE_TYPE_DYNAMIC, + JAVASCRIPT_MODULE_TYPE_ESM +} = require("../ModuleTypeConstants"); const ImportContextDependency = require("./ImportContextDependency"); const ImportDependency = require("./ImportDependency"); const ImportEagerDependency = require("./ImportEagerDependency"); const ImportParserPlugin = require("./ImportParserPlugin"); const ImportWeakDependency = require("./ImportWeakDependency"); +/** @typedef {import("../../declarations/WebpackOptions").JavascriptParserOptions} JavascriptParserOptions */ /** @typedef {import("../Compiler")} Compiler */ +/** @typedef {import("../javascript/JavascriptParser")} Parser */ + +const PLUGIN_NAME = "ImportPlugin"; class ImportPlugin { /** @@ -21,7 +30,7 @@ class ImportPlugin { */ apply(compiler) { compiler.hooks.compilation.tap( - "ImportPlugin", + PLUGIN_NAME, (compilation, { contextModuleFactory, normalModuleFactory }) => { compilation.dependencyFactories.set( ImportDependency, @@ -59,6 +68,11 @@ class ImportPlugin { new ImportContextDependency.Template() ); + /** + * @param {Parser} parser parser parser + * @param {JavascriptParserOptions} parserOptions parserOptions + * @returns {void} + */ const handler = (parser, parserOptions) => { if (parserOptions.import !== undefined && !parserOptions.import) return; @@ -67,14 +81,14 @@ class ImportPlugin { }; normalModuleFactory.hooks.parser - .for("javascript/auto") - .tap("ImportPlugin", handler); + .for(JAVASCRIPT_MODULE_TYPE_AUTO) + .tap(PLUGIN_NAME, handler); normalModuleFactory.hooks.parser - .for("javascript/dynamic") - .tap("ImportPlugin", handler); + .for(JAVASCRIPT_MODULE_TYPE_DYNAMIC) + .tap(PLUGIN_NAME, handler); normalModuleFactory.hooks.parser - .for("javascript/esm") - .tap("ImportPlugin", handler); + .for(JAVASCRIPT_MODULE_TYPE_ESM) + .tap(PLUGIN_NAME, handler); } ); } diff --git a/lib/dependencies/ImportWeakDependency.js b/lib/dependencies/ImportWeakDependency.js index fc141965488..0ed3b053f96 100644 --- a/lib/dependencies/ImportWeakDependency.js +++ b/lib/dependencies/ImportWeakDependency.js @@ -12,16 +12,21 @@ const ImportDependency = require("./ImportDependency"); /** @typedef {import("../Dependency")} Dependency */ /** @typedef {import("../Dependency").ReferencedExport} ReferencedExport */ /** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */ +/** @typedef {import("../Module")} Module */ +/** @typedef {import("../Module").BuildMeta} BuildMeta */ /** @typedef {import("../ModuleGraph")} ModuleGraph */ +/** @typedef {import("../javascript/JavascriptParser").ImportAttributes} ImportAttributes */ +/** @typedef {import("../javascript/JavascriptParser").Range} Range */ class ImportWeakDependency extends ImportDependency { /** * @param {string} request the request - * @param {[number, number]} range expression range - * @param {string[][]=} referencedExports list of referenced exports + * @param {Range} range expression range + * @param {(string[][] | null)=} referencedExports list of referenced exports + * @param {ImportAttributes=} attributes import attributes */ - constructor(request, range, referencedExports) { - super(request, range, referencedExports); + constructor(request, range, referencedExports, attributes) { + super(request, range, referencedExports, attributes); this.weak = true; } @@ -52,9 +57,9 @@ ImportWeakDependency.Template = class ImportDependencyTemplate extends ( const dep = /** @type {ImportWeakDependency} */ (dependency); const content = runtimeTemplate.moduleNamespacePromise({ chunkGraph, - module: moduleGraph.getModule(dep), + module: /** @type {Module} */ (moduleGraph.getModule(dep)), request: dep.request, - strict: module.buildMeta.strictHarmonyModule, + strict: /** @type {BuildMeta} */ (module.buildMeta).strictHarmonyModule, message: "import() weak", weak: true, runtimeRequirements diff --git a/lib/dependencies/JsonExportsDependency.js b/lib/dependencies/JsonExportsDependency.js index fbaf9dbeb04..39ce927eb45 100644 --- a/lib/dependencies/JsonExportsDependency.js +++ b/lib/dependencies/JsonExportsDependency.js @@ -13,40 +13,47 @@ const NullDependency = require("./NullDependency"); /** @typedef {import("../Dependency").ExportsSpec} ExportsSpec */ /** @typedef {import("../Dependency").UpdateHashContext} UpdateHashContext */ /** @typedef {import("../ModuleGraph")} ModuleGraph */ +/** @typedef {import("../json/JsonData")} JsonData */ +/** @typedef {import("../json/JsonData").RawJsonData} RawJsonData */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */ /** @typedef {import("../util/Hash")} Hash */ +/** + * @param {RawJsonData} data data + * @returns {TODO} value + */ const getExportsFromData = data => { if (data && typeof data === "object") { if (Array.isArray(data)) { - return data.map((item, idx) => { - return { - name: `${idx}`, - canMangle: true, - exports: getExportsFromData(item) - }; + return data.length < 100 + ? data.map((item, idx) => ({ + name: `${idx}`, + canMangle: true, + exports: getExportsFromData(item) + })) + : undefined; + } + const exports = []; + for (const key of Object.keys(data)) { + exports.push({ + name: key, + canMangle: true, + exports: getExportsFromData(data[key]) }); - } else { - const exports = []; - for (const key of Object.keys(data)) { - exports.push({ - name: key, - canMangle: true, - exports: getExportsFromData(data[key]) - }); - } - return exports; } + return exports; } return undefined; }; class JsonExportsDependency extends NullDependency { /** - * @param {(string | ExportSpec)[]} exports json exports + * @param {JsonData} data json data */ - constructor(exports) { + constructor(data) { super(); - this.exports = exports; + this.data = data; } get type() { @@ -60,7 +67,9 @@ class JsonExportsDependency extends NullDependency { */ getExports(moduleGraph) { return { - exports: this.exports, + exports: getExportsFromData( + this.data && /** @type {RawJsonData} */ (this.data.get()) + ), dependencies: undefined }; } @@ -72,18 +81,24 @@ class JsonExportsDependency extends NullDependency { * @returns {void} */ updateHash(hash, context) { - hash.update(this.exports ? JSON.stringify(this.exports) : "undefined"); + this.data.updateHash(hash); } + /** + * @param {ObjectSerializerContext} context context + */ serialize(context) { const { write } = context; - write(this.exports); + write(this.data); super.serialize(context); } + /** + * @param {ObjectDeserializerContext} context context + */ deserialize(context) { const { read } = context; - this.exports = read(); + this.data = read(); super.deserialize(context); } } @@ -94,4 +109,3 @@ makeSerializable( ); module.exports = JsonExportsDependency; -module.exports.getExportsFromData = getExportsFromData; diff --git a/lib/dependencies/LoaderDependency.js b/lib/dependencies/LoaderDependency.js index 472d68fe59c..7ae66b3d2b0 100644 --- a/lib/dependencies/LoaderDependency.js +++ b/lib/dependencies/LoaderDependency.js @@ -7,6 +7,12 @@ const ModuleDependency = require("./ModuleDependency"); +/** @typedef {import("../Dependency").GetConditionFn} GetConditionFn */ +/** @typedef {import("../ModuleGraph")} ModuleGraph */ +/** @typedef {import("../ModuleGraphConnection")} ModuleGraphConnection */ +/** @typedef {import("../ModuleGraphConnection").ConnectionState} ConnectionState */ +/** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */ + class LoaderDependency extends ModuleDependency { /** * @param {string} request request string @@ -22,6 +28,14 @@ class LoaderDependency extends ModuleDependency { get category() { return "loader"; } + + /** + * @param {ModuleGraph} moduleGraph module graph + * @returns {null | false | GetConditionFn} function to determine if the connection is active + */ + getCondition(moduleGraph) { + return false; + } } module.exports = LoaderDependency; diff --git a/lib/dependencies/LoaderImportDependency.js b/lib/dependencies/LoaderImportDependency.js new file mode 100644 index 00000000000..94937922d60 --- /dev/null +++ b/lib/dependencies/LoaderImportDependency.js @@ -0,0 +1,42 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ + +"use strict"; + +const ModuleDependency = require("./ModuleDependency"); + +/** @typedef {import("../Dependency").GetConditionFn} GetConditionFn */ +/** @typedef {import("../ModuleGraph")} ModuleGraph */ +/** @typedef {import("../ModuleGraphConnection")} ModuleGraphConnection */ +/** @typedef {import("../ModuleGraphConnection").ConnectionState} ConnectionState */ +/** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */ + +class LoaderImportDependency extends ModuleDependency { + /** + * @param {string} request request string + */ + constructor(request) { + super(request); + this.weak = true; + } + + get type() { + return "loader import"; + } + + get category() { + return "loaderImport"; + } + + /** + * @param {ModuleGraph} moduleGraph module graph + * @returns {null | false | GetConditionFn} function to determine if the connection is active + */ + getCondition(moduleGraph) { + return false; + } +} + +module.exports = LoaderImportDependency; diff --git a/lib/dependencies/LoaderPlugin.js b/lib/dependencies/LoaderPlugin.js index 1a82dba5dd9..1f42a482428 100644 --- a/lib/dependencies/LoaderPlugin.js +++ b/lib/dependencies/LoaderPlugin.js @@ -8,18 +8,39 @@ const NormalModule = require("../NormalModule"); const LazySet = require("../util/LazySet"); const LoaderDependency = require("./LoaderDependency"); +const LoaderImportDependency = require("./LoaderImportDependency"); +/** @typedef {import("../../declarations/LoaderContext").LoaderPluginLoaderContext} LoaderPluginLoaderContext */ +/** @typedef {import("../Compilation").DepConstructor} DepConstructor */ +/** @typedef {import("../Compilation").ExecuteModuleResult} ExecuteModuleResult */ +/** @typedef {import("../Compiler")} Compiler */ /** @typedef {import("../Module")} Module */ +/** @typedef {import("../Module").BuildInfo} BuildInfo */ /** - * @callback LoadModuleCallback - * @param {Error=} err error object - * @param {string=} source source code - * @param {object=} map source map - * @param {Module=} module loaded module if successful + * @callback ImportModuleCallback + * @param {(Error | null)=} err error object + * @param {any=} exports exports of the evaluated module + */ + +/** + * @typedef {object} ImportModuleOptions + * @property {string=} layer the target layer + * @property {string=} publicPath the target public path + * @property {string=} baseUri target base uri */ class LoaderPlugin { + /** + * @param {object} options options + */ + constructor(options = {}) {} + + /** + * Apply the plugin + * @param {Compiler} compiler the compiler instance + * @returns {void} + */ apply(compiler) { compiler.hooks.compilation.tap( "LoaderPlugin", @@ -28,6 +49,10 @@ class LoaderPlugin { LoaderDependency, normalModuleFactory ); + compilation.dependencyFactories.set( + LoaderImportDependency, + normalModuleFactory + ); } ); @@ -36,18 +61,13 @@ class LoaderPlugin { NormalModule.getCompilationHooks(compilation).loader.tap( "LoaderPlugin", loaderContext => { - /** - * @param {string} request the request string to load the module from - * @param {LoadModuleCallback} callback callback returning the loaded module or error - * @returns {void} - */ loaderContext.loadModule = (request, callback) => { const dep = new LoaderDependency(request); dep.loc = { name: request }; const factory = compilation.dependencyFactories.get( - dep.constructor + /** @type {DepConstructor} */ (dep.constructor) ); if (factory === undefined) { return callback( @@ -61,7 +81,9 @@ class LoaderPlugin { { factory, dependencies: [dep], - originModule: loaderContext._module, + originModule: + /** @type {NormalModule} */ + (loaderContext._module), context: loaderContext.context, recursive: false }, @@ -87,7 +109,8 @@ class LoaderPlugin { ) ); } - let source, map; + let map; + let source; if (moduleSource.sourceAndMap) { const sourceAndMap = moduleSource.sourceAndMap(); map = sourceAndMap.map; @@ -119,10 +142,129 @@ class LoaderPlugin { for (const d of buildDependencies) { loaderContext.addBuildDependency(d); } - return callback(null, source, map, referencedModule); + return callback( + null, + source, + /** @type {object | null} */ (map), + referencedModule + ); + } + ); + }; + + /** + * @param {string} request the request string to load the module from + * @param {ImportModuleOptions} options options + * @param {ImportModuleCallback} callback callback returning the exports + * @returns {void} + */ + const importModule = (request, options, callback) => { + const dep = new LoaderImportDependency(request); + dep.loc = { + name: request + }; + const factory = compilation.dependencyFactories.get( + /** @type {DepConstructor} */ (dep.constructor) + ); + if (factory === undefined) { + return callback( + new Error( + `No module factory available for dependency type: ${dep.constructor.name}` + ) + ); + } + compilation.buildQueue.increaseParallelism(); + compilation.handleModuleCreation( + { + factory, + dependencies: [dep], + originModule: + /** @type {NormalModule} */ + (loaderContext._module), + contextInfo: { + issuerLayer: options.layer + }, + context: loaderContext.context, + connectOrigin: false, + checkCycle: true + }, + err => { + compilation.buildQueue.decreaseParallelism(); + if (err) { + return callback(err); + } + const referencedModule = moduleGraph.getModule(dep); + if (!referencedModule) { + return callback(new Error("Cannot load the module")); + } + compilation.executeModule( + referencedModule, + { + entryOptions: { + baseUri: options.baseUri, + publicPath: options.publicPath + } + }, + (err, result) => { + if (err) return callback(err); + const { + fileDependencies, + contextDependencies, + missingDependencies, + buildDependencies, + cacheable, + assets, + exports + } = /** @type {ExecuteModuleResult} */ (result); + for (const d of fileDependencies) { + loaderContext.addDependency(d); + } + for (const d of contextDependencies) { + loaderContext.addContextDependency(d); + } + for (const d of missingDependencies) { + loaderContext.addMissingDependency(d); + } + for (const d of buildDependencies) { + loaderContext.addBuildDependency(d); + } + if (cacheable === false) loaderContext.cacheable(false); + for (const [name, { source, info }] of assets) { + const buildInfo = + /** @type {BuildInfo} */ + ( + /** @type {NormalModule} */ (loaderContext._module) + .buildInfo + ); + if (!buildInfo.assets) { + buildInfo.assets = Object.create(null); + buildInfo.assetsInfo = new Map(); + } + /** @type {NonNullable} */ + (buildInfo.assets)[name] = source; + /** @type {NonNullable} */ + (buildInfo.assetsInfo).set(name, info); + } + callback(null, exports); + } + ); } ); }; + + // eslint-disable-next-line no-warning-comments + // @ts-ignore Overloading doesn't work + loaderContext.importModule = (request, options, callback) => { + if (!callback) { + return new Promise((resolve, reject) => { + importModule(request, options || {}, (err, result) => { + if (err) reject(err); + else resolve(result); + }); + }); + } + return importModule(request, options || {}, callback); + }; } ); }); diff --git a/lib/dependencies/LocalModule.js b/lib/dependencies/LocalModule.js index 8516594b31c..7748a06ba6a 100644 --- a/lib/dependencies/LocalModule.js +++ b/lib/dependencies/LocalModule.js @@ -7,7 +7,14 @@ const makeSerializable = require("../util/makeSerializable"); +/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */ + class LocalModule { + /** + * @param {string} name name + * @param {number} idx index + */ constructor(name, idx) { this.name = name; this.idx = idx; @@ -18,10 +25,16 @@ class LocalModule { this.used = true; } + /** + * @returns {string} variable name + */ variableName() { - return "__WEBPACK_LOCAL_MODULE_" + this.idx + "__"; + return `__WEBPACK_LOCAL_MODULE_${this.idx}__`; } + /** + * @param {ObjectSerializerContext} context context + */ serialize(context) { const { write } = context; @@ -30,6 +43,9 @@ class LocalModule { write(this.used); } + /** + * @param {ObjectDeserializerContext} context context + */ deserialize(context) { const { read } = context; diff --git a/lib/dependencies/LocalModuleDependency.js b/lib/dependencies/LocalModuleDependency.js index 66395319a7c..2cde22fe145 100644 --- a/lib/dependencies/LocalModuleDependency.js +++ b/lib/dependencies/LocalModuleDependency.js @@ -11,8 +11,17 @@ const NullDependency = require("./NullDependency"); /** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */ /** @typedef {import("../Dependency")} Dependency */ /** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */ +/** @typedef {import("../javascript/JavascriptParser").Range} Range */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */ +/** @typedef {import("./LocalModule")} LocalModule */ class LocalModuleDependency extends NullDependency { + /** + * @param {LocalModule} localModule local module + * @param {Range | undefined} range range + * @param {boolean} callNew true, when the local module should be called with new + */ constructor(localModule, range, callNew) { super(); @@ -21,6 +30,9 @@ class LocalModuleDependency extends NullDependency { this.callNew = callNew; } + /** + * @param {ObjectSerializerContext} context context + */ serialize(context) { const { write } = context; @@ -31,6 +43,9 @@ class LocalModuleDependency extends NullDependency { super.serialize(context); } + /** + * @param {ObjectDeserializerContext} context context + */ deserialize(context) { const { read } = context; diff --git a/lib/dependencies/LocalModulesHelpers.js b/lib/dependencies/LocalModulesHelpers.js index bc2eb8a9d76..bcb947c2b02 100644 --- a/lib/dependencies/LocalModulesHelpers.js +++ b/lib/dependencies/LocalModulesHelpers.js @@ -7,11 +7,18 @@ const LocalModule = require("./LocalModule"); +/** @typedef {import("../javascript/JavascriptParser").ParserState} ParserState */ + +/** + * @param {string} parent parent module + * @param {string} mod module to resolve + * @returns {string} resolved module + */ const lookup = (parent, mod) => { if (mod.charAt(0) !== ".") return mod; - var path = parent.split("/"); - var segments = mod.split("/"); + const path = parent.split("/"); + const segments = mod.split("/"); path.pop(); for (let i = 0; i < segments.length; i++) { @@ -26,7 +33,12 @@ const lookup = (parent, mod) => { return path.join("/"); }; -exports.addLocalModule = (state, name) => { +/** + * @param {ParserState} state parser state + * @param {string} name name + * @returns {LocalModule} local module + */ +module.exports.addLocalModule = (state, name) => { if (!state.localModules) { state.localModules = []; } @@ -35,7 +47,13 @@ exports.addLocalModule = (state, name) => { return m; }; -exports.getLocalModule = (state, name, namedModule) => { +/** + * @param {ParserState} state parser state + * @param {string} name name + * @param {string} [namedModule] named module + * @returns {LocalModule | null} local module or null + */ +module.exports.getLocalModule = (state, name, namedModule) => { if (!state.localModules) return null; if (namedModule) { // resolve dependency name relative to the defining named module diff --git a/lib/dependencies/ModuleDecoratorDependency.js b/lib/dependencies/ModuleDecoratorDependency.js index cd0248437b3..fd2b3fe5f73 100644 --- a/lib/dependencies/ModuleDecoratorDependency.js +++ b/lib/dependencies/ModuleDecoratorDependency.js @@ -18,6 +18,8 @@ const NullDependency = require("./NullDependency"); /** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */ /** @typedef {import("../DependencyTemplates")} DependencyTemplates */ /** @typedef {import("../ModuleGraph")} ModuleGraph */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */ /** @typedef {import("../util/Hash")} Hash */ /** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */ @@ -30,6 +32,7 @@ class ModuleDecoratorDependency extends NullDependency { super(); this.decorator = decorator; this.allowExportsAccess = allowExportsAccess; + this._hashUpdate = undefined; } /** @@ -47,7 +50,7 @@ class ModuleDecoratorDependency extends NullDependency { * @returns {string | null} an identifier to merge equal requests */ getResourceIdentifier() { - return `self`; + return "self"; } /** @@ -69,10 +72,15 @@ class ModuleDecoratorDependency extends NullDependency { * @returns {void} */ updateHash(hash, context) { - hash.update(this.decorator); - hash.update(`${this.allowExportsAccess}`); + if (this._hashUpdate === undefined) { + this._hashUpdate = `${this.decorator}${this.allowExportsAccess}`; + } + hash.update(this._hashUpdate); } + /** + * @param {ObjectSerializerContext} context context + */ serialize(context) { const { write } = context; write(this.decorator); @@ -80,6 +88,9 @@ class ModuleDecoratorDependency extends NullDependency { super.serialize(context); } + /** + * @param {ObjectDeserializerContext} context context + */ deserialize(context) { const { read } = context; this.decorator = read(); diff --git a/lib/dependencies/ModuleDependency.js b/lib/dependencies/ModuleDependency.js index d53ea92d464..76b9d17484a 100644 --- a/lib/dependencies/ModuleDependency.js +++ b/lib/dependencies/ModuleDependency.js @@ -7,11 +7,13 @@ const Dependency = require("../Dependency"); const DependencyTemplate = require("../DependencyTemplate"); -const memoize = require("../util/memoize"); +const RawModule = require("../RawModule"); +/** @typedef {import("../Dependency").TRANSITIVE} TRANSITIVE */ /** @typedef {import("../Module")} Module */ - -const getRawModule = memoize(() => require("../RawModule")); +/** @typedef {import("../javascript/JavascriptParser").ImportAttributes} ImportAttributes */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */ class ModuleDependency extends Dependency { /** @@ -22,21 +24,43 @@ class ModuleDependency extends Dependency { this.request = request; this.userRequest = request; this.range = undefined; + // TODO move it to subclasses and rename + // assertions must be serialized by subclasses that use it + /** @type {ImportAttributes | undefined} */ + this.assertions = undefined; + this._context = undefined; + } + + /** + * @returns {string | undefined} a request context + */ + getContext() { + return this._context; } /** * @returns {string | null} an identifier to merge equal requests */ getResourceIdentifier() { - return `module${this.request}`; + let str = `context${this._context || ""}|module${this.request}`; + if (this.assertions !== undefined) { + str += JSON.stringify(this.assertions); + } + return str; + } + + /** + * @returns {boolean | TRANSITIVE} true, when changes to the referenced module could affect the referencing module; TRANSITIVE, when changes to the referenced module could affect referencing modules of the referencing module + */ + couldAffectReferencingModule() { + return true; } /** * @param {string} context context directory - * @returns {Module} a module + * @returns {Module | null} a module */ createIgnoredModule(context) { - const RawModule = getRawModule(); return new RawModule( "/* (ignored) */", `ignored|${context}|${this.request}`, @@ -44,18 +68,26 @@ class ModuleDependency extends Dependency { ); } + /** + * @param {ObjectSerializerContext} context context + */ serialize(context) { const { write } = context; write(this.request); write(this.userRequest); + write(this._context); write(this.range); super.serialize(context); } + /** + * @param {ObjectDeserializerContext} context context + */ deserialize(context) { const { read } = context; this.request = read(); this.userRequest = read(); + this._context = read(); this.range = read(); super.deserialize(context); } diff --git a/lib/dependencies/ModuleDependencyTemplateAsId.js b/lib/dependencies/ModuleDependencyTemplateAsId.js index edc9afcdf41..8086fc79717 100644 --- a/lib/dependencies/ModuleDependencyTemplateAsId.js +++ b/lib/dependencies/ModuleDependencyTemplateAsId.js @@ -10,6 +10,7 @@ const ModuleDependency = require("./ModuleDependency"); /** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */ /** @typedef {import("../Dependency")} Dependency */ /** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */ +/** @typedef {import("../Module")} Module */ class ModuleDependencyTemplateAsId extends ModuleDependency.Template { /** @@ -22,7 +23,7 @@ class ModuleDependencyTemplateAsId extends ModuleDependency.Template { const dep = /** @type {ModuleDependency} */ (dependency); if (!dep.range) return; const content = runtimeTemplate.moduleId({ - module: moduleGraph.getModule(dep), + module: /** @type {Module} */ (moduleGraph.getModule(dep)), chunkGraph, request: dep.request, weak: dep.weak diff --git a/lib/dependencies/ModuleHotAcceptDependency.js b/lib/dependencies/ModuleHotAcceptDependency.js index 9ccf8a3033b..1916a7e2563 100644 --- a/lib/dependencies/ModuleHotAcceptDependency.js +++ b/lib/dependencies/ModuleHotAcceptDependency.js @@ -9,7 +9,13 @@ const makeSerializable = require("../util/makeSerializable"); const ModuleDependency = require("./ModuleDependency"); const ModuleDependencyTemplateAsId = require("./ModuleDependencyTemplateAsId"); +/** @typedef {import("../javascript/JavascriptParser").Range} Range */ + class ModuleHotAcceptDependency extends ModuleDependency { + /** + * @param {string} request the request string + * @param {Range} range location in source code + */ constructor(request, range) { super(request); this.range = range; diff --git a/lib/dependencies/ModuleHotDeclineDependency.js b/lib/dependencies/ModuleHotDeclineDependency.js index c5edb770e7b..70423774b4e 100644 --- a/lib/dependencies/ModuleHotDeclineDependency.js +++ b/lib/dependencies/ModuleHotDeclineDependency.js @@ -9,7 +9,13 @@ const makeSerializable = require("../util/makeSerializable"); const ModuleDependency = require("./ModuleDependency"); const ModuleDependencyTemplateAsId = require("./ModuleDependencyTemplateAsId"); +/** @typedef {import("../javascript/JavascriptParser").Range} Range */ + class ModuleHotDeclineDependency extends ModuleDependency { + /** + * @param {string} request the request string + * @param {Range} range location in source code + */ constructor(request, range) { super(request); diff --git a/lib/dependencies/NullDependency.js b/lib/dependencies/NullDependency.js index a18c25d4fa7..c22cafc7c7a 100644 --- a/lib/dependencies/NullDependency.js +++ b/lib/dependencies/NullDependency.js @@ -9,23 +9,19 @@ const Dependency = require("../Dependency"); const DependencyTemplate = require("../DependencyTemplate"); /** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */ -/** @typedef {import("../ChunkGraph")} ChunkGraph */ -/** @typedef {import("../Dependency").UpdateHashContext} UpdateHashContext */ +/** @typedef {import("../Dependency").TRANSITIVE} TRANSITIVE */ /** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */ -/** @typedef {import("../ModuleGraph")} ModuleGraph */ -/** @typedef {import("../util/Hash")} Hash */ class NullDependency extends Dependency { get type() { return "null"; } - serialize({ write }) { - write(this.loc); - } - - deserialize({ read }) { - this.loc = read(); + /** + * @returns {boolean | TRANSITIVE} true, when changes to the referenced module could affect the referencing module; TRANSITIVE, when changes to the referenced module could affect referencing modules of the referencing module + */ + couldAffectReferencingModule() { + return false; } } diff --git a/lib/dependencies/PrefetchDependency.js b/lib/dependencies/PrefetchDependency.js index 3c19dae2efc..59e22c59a79 100644 --- a/lib/dependencies/PrefetchDependency.js +++ b/lib/dependencies/PrefetchDependency.js @@ -8,6 +8,9 @@ const ModuleDependency = require("./ModuleDependency"); class PrefetchDependency extends ModuleDependency { + /** + * @param {string} request the request string + */ constructor(request) { super(request); } diff --git a/lib/dependencies/ProvidedDependency.js b/lib/dependencies/ProvidedDependency.js index 2362e3a0df9..9f1d3f6e7dc 100644 --- a/lib/dependencies/ProvidedDependency.js +++ b/lib/dependencies/ProvidedDependency.js @@ -5,19 +5,25 @@ "use strict"; +const Dependency = require("../Dependency"); const InitFragment = require("../InitFragment"); const makeSerializable = require("../util/makeSerializable"); const ModuleDependency = require("./ModuleDependency"); /** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */ /** @typedef {import("../ChunkGraph")} ChunkGraph */ -/** @typedef {import("../Dependency")} Dependency */ +/** @typedef {import("../Dependency").ReferencedExport} ReferencedExport */ /** @typedef {import("../Dependency").UpdateHashContext} UpdateHashContext */ /** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */ /** @typedef {import("../DependencyTemplates")} DependencyTemplates */ /** @typedef {import("../ModuleGraph")} ModuleGraph */ +/** @typedef {import("../ModuleGraphConnection")} ModuleGraphConnection */ /** @typedef {import("../RuntimeTemplate")} RuntimeTemplate */ +/** @typedef {import("../javascript/JavascriptParser").Range} Range */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */ /** @typedef {import("../util/Hash")} Hash */ +/** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */ /** * @param {string[]|null} path the property path array @@ -29,11 +35,18 @@ const pathToString = path => : ""; class ProvidedDependency extends ModuleDependency { - constructor(request, identifier, path, range) { + /** + * @param {string} request request + * @param {string} identifier identifier + * @param {string[]} ids ids + * @param {Range} range range + */ + constructor(request, identifier, ids, range) { super(request); this.identifier = identifier; - this.path = path; + this.ids = ids; this.range = range; + this._hashUpdate = undefined; } get type() { @@ -44,6 +57,18 @@ class ProvidedDependency extends ModuleDependency { return "esm"; } + /** + * Returns list of exports referenced by this dependency + * @param {ModuleGraph} moduleGraph module graph + * @param {RuntimeSpec} runtime the runtime for which the module is analysed + * @returns {(string[] | ReferencedExport)[]} referenced exports + */ + getReferencedExports(moduleGraph, runtime) { + const ids = this.ids; + if (ids.length === 0) return Dependency.EXPORTS_OBJECT_REFERENCED; + return [ids]; + } + /** * Update the hash * @param {Hash} hash hash to be updated @@ -51,21 +76,29 @@ class ProvidedDependency extends ModuleDependency { * @returns {void} */ updateHash(hash, context) { - hash.update(this.identifier); - hash.update(this.path ? this.path.join(",") : "null"); + if (this._hashUpdate === undefined) { + this._hashUpdate = this.identifier + (this.ids ? this.ids.join(",") : ""); + } + hash.update(this._hashUpdate); } + /** + * @param {ObjectSerializerContext} context context + */ serialize(context) { const { write } = context; write(this.identifier); - write(this.path); + write(this.ids); super.serialize(context); } + /** + * @param {ObjectDeserializerContext} context context + */ deserialize(context) { const { read } = context; this.identifier = read(); - this.path = read(); + this.ids = read(); super.deserialize(context); } } @@ -86,6 +119,7 @@ class ProvidedDependencyTemplate extends ModuleDependency.Template { dependency, source, { + runtime, runtimeTemplate, moduleGraph, chunkGraph, @@ -94,6 +128,11 @@ class ProvidedDependencyTemplate extends ModuleDependency.Template { } ) { const dep = /** @type {ProvidedDependency} */ (dependency); + const connection = + /** @type {ModuleGraphConnection} */ + (moduleGraph.getConnection(dep)); + const exportsInfo = moduleGraph.getExportsInfo(connection.module); + const usedName = exportsInfo.getUsedName(dep.ids, runtime); initFragments.push( new InitFragment( `/* provided dependency */ var ${ @@ -103,7 +142,7 @@ class ProvidedDependencyTemplate extends ModuleDependency.Template { chunkGraph, request: dep.request, runtimeRequirements - })}${pathToString(dep.path)};\n`, + })}${pathToString(/** @type {string[]} */ (usedName))};\n`, InitFragment.STAGE_PROVIDES, 1, `provided ${dep.identifier}` diff --git a/lib/dependencies/PureExpressionDependency.js b/lib/dependencies/PureExpressionDependency.js index cea1834f5a2..3c4312c9847 100644 --- a/lib/dependencies/PureExpressionDependency.js +++ b/lib/dependencies/PureExpressionDependency.js @@ -7,21 +7,26 @@ const { UsageState } = require("../ExportsInfo"); const makeSerializable = require("../util/makeSerializable"); -const { filterRuntime } = require("../util/runtime"); +const { filterRuntime, runtimeToString } = require("../util/runtime"); const NullDependency = require("./NullDependency"); /** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */ /** @typedef {import("../ChunkGraph")} ChunkGraph */ /** @typedef {import("../Dependency")} Dependency */ +/** @typedef {import("../Dependency").RuntimeSpec} RuntimeSpec */ /** @typedef {import("../Dependency").UpdateHashContext} UpdateHashContext */ /** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */ +/** @typedef {import("../Module")} Module */ /** @typedef {import("../ModuleGraph")} ModuleGraph */ /** @typedef {import("../ModuleGraphConnection").ConnectionState} ConnectionState */ +/** @typedef {import("../javascript/JavascriptParser").Range} Range */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */ /** @typedef {import("../util/Hash")} Hash */ class PureExpressionDependency extends NullDependency { /** - * @param {[number, number]} range the source range + * @param {Range} range the source range */ constructor(range) { super(); @@ -30,6 +35,31 @@ class PureExpressionDependency extends NullDependency { this.usedByExports = false; } + /** + * @param {ModuleGraph} moduleGraph module graph + * @param {RuntimeSpec} runtime current runtimes + * @returns {boolean | RuntimeSpec} runtime condition + */ + _getRuntimeCondition(moduleGraph, runtime) { + const usedByExports = this.usedByExports; + if (usedByExports !== false) { + const selfModule = + /** @type {Module} */ + (moduleGraph.getParentModule(this)); + const exportsInfo = moduleGraph.getExportsInfo(selfModule); + const runtimeCondition = filterRuntime(runtime, runtime => { + for (const exportName of usedByExports) { + if (exportsInfo.getUsed(exportName, runtime) !== UsageState.Unused) { + return true; + } + } + return false; + }); + return runtimeCondition; + } + return false; + } + /** * Update the hash * @param {Hash} hash hash to be updated @@ -37,7 +67,22 @@ class PureExpressionDependency extends NullDependency { * @returns {void} */ updateHash(hash, context) { - hash.update(this.range + ""); + const runtimeCondition = this._getRuntimeCondition( + context.chunkGraph.moduleGraph, + context.runtime + ); + if (runtimeCondition === true) { + return; + } else if (runtimeCondition === false) { + hash.update("null"); + } else { + hash.update( + `${runtimeToString(runtimeCondition)}|${runtimeToString( + context.runtime + )}` + ); + } + hash.update(String(this.range)); } /** @@ -48,6 +93,9 @@ class PureExpressionDependency extends NullDependency { return false; } + /** + * @param {ObjectSerializerContext} context context + */ serialize(context) { const { write } = context; write(this.range); @@ -55,6 +103,9 @@ class PureExpressionDependency extends NullDependency { super.serialize(context); } + /** + * @param {ObjectDeserializerContext} context context + */ deserialize(context) { const { read } = context; this.range = read(); @@ -83,41 +134,28 @@ PureExpressionDependency.Template = class PureExpressionDependencyTemplate exten { chunkGraph, moduleGraph, runtime, runtimeTemplate, runtimeRequirements } ) { const dep = /** @type {PureExpressionDependency} */ (dependency); - - const usedByExports = dep.usedByExports; - if (usedByExports !== false) { - const selfModule = moduleGraph.getParentModule(dep); - const exportsInfo = moduleGraph.getExportsInfo(selfModule); - const runtimeCondition = filterRuntime(runtime, runtime => { - for (const exportName of usedByExports) { - if (exportsInfo.getUsed(exportName, runtime) !== UsageState.Unused) { - return true; - } - } - return false; + const runtimeCondition = dep._getRuntimeCondition(moduleGraph, runtime); + if (runtimeCondition === true) { + // Do nothing + } else if (runtimeCondition === false) { + source.insert( + dep.range[0], + "(/* unused pure expression or super */ null && (" + ); + source.insert(dep.range[1], "))"); + } else { + const condition = runtimeTemplate.runtimeConditionExpression({ + chunkGraph, + runtime, + runtimeCondition, + runtimeRequirements }); - if (runtimeCondition === true) return; - if (runtimeCondition !== false) { - const condition = runtimeTemplate.runtimeConditionExpression({ - chunkGraph, - runtime, - runtimeCondition, - runtimeRequirements - }); - source.insert( - dep.range[0], - `(/* runtime-dependent pure expression or super */ ${condition} ? (` - ); - source.insert(dep.range[1], ") : null)"); - return; - } + source.insert( + dep.range[0], + `(/* runtime-dependent pure expression or super */ ${condition} ? (` + ); + source.insert(dep.range[1], ") : null)"); } - - source.insert( - dep.range[0], - `(/* unused pure expression or super */ null && (` - ); - source.insert(dep.range[1], "))"); } }; diff --git a/lib/dependencies/RequireContextDependency.js b/lib/dependencies/RequireContextDependency.js index f0e90f53640..9aa883f2edb 100644 --- a/lib/dependencies/RequireContextDependency.js +++ b/lib/dependencies/RequireContextDependency.js @@ -9,7 +9,13 @@ const makeSerializable = require("../util/makeSerializable"); const ContextDependency = require("./ContextDependency"); const ModuleDependencyTemplateAsRequireId = require("./ModuleDependencyTemplateAsRequireId"); +/** @typedef {import("../javascript/JavascriptParser").Range} Range */ + class RequireContextDependency extends ContextDependency { + /** + * @param {TODO} options options + * @param {Range} range range + */ constructor(options, range) { super(options); @@ -19,22 +25,6 @@ class RequireContextDependency extends ContextDependency { get type() { return "require.context"; } - - serialize(context) { - const { write } = context; - - write(this.range); - - super.serialize(context); - } - - deserialize(context) { - const { read } = context; - - this.range = read(); - - super.deserialize(context); - } } makeSerializable( diff --git a/lib/dependencies/RequireContextDependencyParserPlugin.js b/lib/dependencies/RequireContextDependencyParserPlugin.js index 8504664597e..02ce1c1487e 100644 --- a/lib/dependencies/RequireContextDependencyParserPlugin.js +++ b/lib/dependencies/RequireContextDependencyParserPlugin.js @@ -7,7 +7,15 @@ const RequireContextDependency = require("./RequireContextDependency"); +/** @typedef {import("../Dependency").DependencyLocation} DependencyLocation */ +/** @typedef {import("../javascript/JavascriptParser")} JavascriptParser */ +/** @typedef {import("../javascript/JavascriptParser").Range} Range */ + module.exports = class RequireContextDependencyParserPlugin { + /** + * @param {JavascriptParser} parser the parser + * @returns {void} + */ apply(parser) { parser.hooks.call .for("require.context") @@ -19,19 +27,19 @@ module.exports = class RequireContextDependencyParserPlugin { case 4: { const modeExpr = parser.evaluateExpression(expr.arguments[3]); if (!modeExpr.isString()) return; - mode = modeExpr.string; + mode = /** @type {string} */ (modeExpr.string); } // falls through case 3: { const regExpExpr = parser.evaluateExpression(expr.arguments[2]); if (!regExpExpr.isRegExp()) return; - regExp = regExpExpr.regExp; + regExp = /** @type {RegExp} */ (regExpExpr.regExp); } // falls through case 2: { const recursiveExpr = parser.evaluateExpression(expr.arguments[1]); if (!recursiveExpr.isBoolean()) return; - recursive = recursiveExpr.bool; + recursive = /** @type {boolean} */ (recursiveExpr.bool); } // falls through case 1: { @@ -45,10 +53,10 @@ module.exports = class RequireContextDependencyParserPlugin { mode, category: "commonjs" }, - expr.range + /** @type {Range} */ (expr.range) ); - dep.loc = expr.loc; - dep.optional = !!parser.scope.inTry; + dep.loc = /** @type {DependencyLocation} */ (expr.loc); + dep.optional = Boolean(parser.scope.inTry); parser.state.current.addDependency(dep); return true; } diff --git a/lib/dependencies/RequireContextPlugin.js b/lib/dependencies/RequireContextPlugin.js index d34c85e452a..30e87fb9e8c 100644 --- a/lib/dependencies/RequireContextPlugin.js +++ b/lib/dependencies/RequireContextPlugin.js @@ -5,17 +5,25 @@ "use strict"; +const { + JAVASCRIPT_MODULE_TYPE_AUTO, + JAVASCRIPT_MODULE_TYPE_DYNAMIC +} = require("../ModuleTypeConstants"); const { cachedSetProperty } = require("../util/cleverMerge"); const ContextElementDependency = require("./ContextElementDependency"); const RequireContextDependency = require("./RequireContextDependency"); const RequireContextDependencyParserPlugin = require("./RequireContextDependencyParserPlugin"); +/** @typedef {import("../../declarations/WebpackOptions").JavascriptParserOptions} JavascriptParserOptions */ /** @typedef {import("../../declarations/WebpackOptions").ResolveOptions} ResolveOptions */ /** @typedef {import("../Compiler")} Compiler */ +/** @typedef {import("../javascript/JavascriptParser")} Parser */ /** @type {ResolveOptions} */ const EMPTY_RESOLVE_OPTIONS = {}; +const PLUGIN_NAME = "RequireContextPlugin"; + class RequireContextPlugin { /** * Apply the plugin @@ -24,7 +32,7 @@ class RequireContextPlugin { */ apply(compiler) { compiler.hooks.compilation.tap( - "RequireContextPlugin", + PLUGIN_NAME, (compilation, { contextModuleFactory, normalModuleFactory }) => { compilation.dependencyFactories.set( RequireContextDependency, @@ -40,6 +48,11 @@ class RequireContextPlugin { normalModuleFactory ); + /** + * @param {Parser} parser parser parser + * @param {JavascriptParserOptions} parserOptions parserOptions + * @returns {void} + */ const handler = (parser, parserOptions) => { if ( parserOptions.requireContext !== undefined && @@ -51,14 +64,14 @@ class RequireContextPlugin { }; normalModuleFactory.hooks.parser - .for("javascript/auto") - .tap("RequireContextPlugin", handler); + .for(JAVASCRIPT_MODULE_TYPE_AUTO) + .tap(PLUGIN_NAME, handler); normalModuleFactory.hooks.parser - .for("javascript/dynamic") - .tap("RequireContextPlugin", handler); + .for(JAVASCRIPT_MODULE_TYPE_DYNAMIC) + .tap(PLUGIN_NAME, handler); contextModuleFactory.hooks.alternativeRequests.tap( - "RequireContextPlugin", + PLUGIN_NAME, (items, options) => { if (items.length === 0) return items; @@ -67,7 +80,7 @@ class RequireContextPlugin { cachedSetProperty( options.resolveOptions || EMPTY_RESOLVE_OPTIONS, "dependencyType", - options.category + /** @type {string} */ (options.category) ) ).options; diff --git a/lib/dependencies/RequireEnsureDependenciesBlock.js b/lib/dependencies/RequireEnsureDependenciesBlock.js index 1928dbe0f94..6cf8294e5e7 100644 --- a/lib/dependencies/RequireEnsureDependenciesBlock.js +++ b/lib/dependencies/RequireEnsureDependenciesBlock.js @@ -8,7 +8,14 @@ const AsyncDependenciesBlock = require("../AsyncDependenciesBlock"); const makeSerializable = require("../util/makeSerializable"); +/** @typedef {import("../ChunkGroup").ChunkGroupOptions} ChunkGroupOptions */ +/** @typedef {import("../Dependency").DependencyLocation} DependencyLocation */ + class RequireEnsureDependenciesBlock extends AsyncDependenciesBlock { + /** + * @param {ChunkGroupOptions & { entryOptions?: TODO }} chunkName chunk name + * @param {DependencyLocation} loc location info + */ constructor(chunkName, loc) { super(chunkName, loc, null); } diff --git a/lib/dependencies/RequireEnsureDependenciesBlockParserPlugin.js b/lib/dependencies/RequireEnsureDependenciesBlockParserPlugin.js index ed0e81d31fd..c81fada8b49 100644 --- a/lib/dependencies/RequireEnsureDependenciesBlockParserPlugin.js +++ b/lib/dependencies/RequireEnsureDependenciesBlockParserPlugin.js @@ -10,7 +10,17 @@ const RequireEnsureDependency = require("./RequireEnsureDependency"); const RequireEnsureItemDependency = require("./RequireEnsureItemDependency"); const getFunctionExpression = require("./getFunctionExpression"); +/** @typedef {import("../ChunkGroup").ChunkGroupOptions} ChunkGroupOptions */ +/** @typedef {import("../Dependency").DependencyLocation} DependencyLocation */ +/** @typedef {import("../javascript/BasicEvaluatedExpression")} BasicEvaluatedExpression */ +/** @typedef {import("../javascript/JavascriptParser")} JavascriptParser */ +/** @typedef {import("../javascript/JavascriptParser").Range} Range */ + module.exports = class RequireEnsureDependenciesBlockParserPlugin { + /** + * @param {JavascriptParser} parser the parser + * @returns {void} + */ apply(parser) { parser.hooks.call .for("require.ensure") @@ -42,13 +52,15 @@ module.exports = class RequireEnsureDependenciesBlockParserPlugin { const dependenciesExpr = parser.evaluateExpression( expr.arguments[0] ); - const dependenciesItems = dependenciesExpr.isArray() - ? dependenciesExpr.items - : [dependenciesExpr]; + const dependenciesItems = + /** @type {BasicEvaluatedExpression[]} */ ( + dependenciesExpr.isArray() + ? dependenciesExpr.items + : [dependenciesExpr] + ); const successExpressionArg = expr.arguments[1]; - const successExpression = getFunctionExpression( - successExpressionArg - ); + const successExpression = + getFunctionExpression(successExpressionArg); if (successExpression) { parser.walkExpressions(successExpression.expressions); @@ -58,30 +70,34 @@ module.exports = class RequireEnsureDependenciesBlockParserPlugin { } const depBlock = new RequireEnsureDependenciesBlock( - chunkName, - expr.loc + /** @type {ChunkGroupOptions & { entryOptions?: TODO }} */ + (chunkName), + /** @type {DependencyLocation} */ (expr.loc) ); const errorCallbackExists = expr.arguments.length === 4 || (!chunkName && expr.arguments.length === 3); const dep = new RequireEnsureDependency( - expr.range, - expr.arguments[1].range, - errorCallbackExists && expr.arguments[2].range + /** @type {Range} */ (expr.range), + /** @type {Range} */ (expr.arguments[1].range), + errorCallbackExists && + /** @type {Range} */ (expr.arguments[2].range) ); - dep.loc = expr.loc; + dep.loc = /** @type {DependencyLocation} */ (expr.loc); depBlock.addDependency(dep); const old = parser.state.current; - parser.state.current = depBlock; + parser.state.current = /** @type {TODO} */ (depBlock); try { let failed = false; parser.inScope([], () => { for (const ee of dependenciesItems) { if (ee.isString()) { const ensureDependency = new RequireEnsureItemDependency( - ee.string + /** @type {string} */ (ee.string) ); - ensureDependency.loc = ee.loc || expr.loc; + ensureDependency.loc = + /** @type {DependencyLocation} */ + (expr.loc); depBlock.addDependency(ensureDependency); } else { failed = true; diff --git a/lib/dependencies/RequireEnsureDependency.js b/lib/dependencies/RequireEnsureDependency.js index ed6785134fc..4fcec7731ce 100644 --- a/lib/dependencies/RequireEnsureDependency.js +++ b/lib/dependencies/RequireEnsureDependency.js @@ -13,8 +13,16 @@ const NullDependency = require("./NullDependency"); /** @typedef {import("../AsyncDependenciesBlock")} AsyncDependenciesBlock */ /** @typedef {import("../Dependency")} Dependency */ /** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */ +/** @typedef {import("../javascript/JavascriptParser").Range} Range */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */ class RequireEnsureDependency extends NullDependency { + /** + * @param {Range} range range + * @param {Range} contentRange content range + * @param {Range | false} errorHandlerRange error handler range + */ constructor(range, contentRange, errorHandlerRange) { super(); @@ -27,6 +35,9 @@ class RequireEnsureDependency extends NullDependency { return "require.ensure"; } + /** + * @param {ObjectSerializerContext} context context + */ serialize(context) { const { write } = context; @@ -37,6 +48,9 @@ class RequireEnsureDependency extends NullDependency { super.serialize(context); } + /** + * @param {ObjectDeserializerContext} context context + */ deserialize(context) { const { read } = context; @@ -68,9 +82,9 @@ RequireEnsureDependency.Template = class RequireEnsureDependencyTemplate extends { runtimeTemplate, moduleGraph, chunkGraph, runtimeRequirements } ) { const dep = /** @type {RequireEnsureDependency} */ (dependency); - const depBlock = /** @type {AsyncDependenciesBlock} */ (moduleGraph.getParentBlock( - dep - )); + const depBlock = /** @type {AsyncDependenciesBlock} */ ( + moduleGraph.getParentBlock(dep) + ); const promise = runtimeTemplate.blockPromise({ chunkGraph, block: depBlock, @@ -85,14 +99,14 @@ RequireEnsureDependency.Template = class RequireEnsureDependencyTemplate extends source.replace( contentRange[1], errorHandlerRange[0] - 1, - ").bind(null, __webpack_require__)).catch(" + `).bind(null, ${RuntimeGlobals.require}))['catch'](` ); source.replace(errorHandlerRange[1], range[1] - 1, ")"); } else { source.replace( contentRange[1], range[1] - 1, - `).bind(null, __webpack_require__)).catch(${RuntimeGlobals.uncaughtErrorHandler})` + `).bind(null, ${RuntimeGlobals.require}))['catch'](${RuntimeGlobals.uncaughtErrorHandler})` ); } } diff --git a/lib/dependencies/RequireEnsureItemDependency.js b/lib/dependencies/RequireEnsureItemDependency.js index 70d2df1f0ed..f9a465a55c9 100644 --- a/lib/dependencies/RequireEnsureItemDependency.js +++ b/lib/dependencies/RequireEnsureItemDependency.js @@ -10,6 +10,9 @@ const ModuleDependency = require("./ModuleDependency"); const NullDependency = require("./NullDependency"); class RequireEnsureItemDependency extends ModuleDependency { + /** + * @param {string} request the request string + */ constructor(request) { super(request); } diff --git a/lib/dependencies/RequireEnsurePlugin.js b/lib/dependencies/RequireEnsurePlugin.js index e2aa1574e9c..5a1dc31dbdd 100644 --- a/lib/dependencies/RequireEnsurePlugin.js +++ b/lib/dependencies/RequireEnsurePlugin.js @@ -10,15 +10,30 @@ const RequireEnsureItemDependency = require("./RequireEnsureItemDependency"); const RequireEnsureDependenciesBlockParserPlugin = require("./RequireEnsureDependenciesBlockParserPlugin"); +const { + JAVASCRIPT_MODULE_TYPE_AUTO, + JAVASCRIPT_MODULE_TYPE_DYNAMIC +} = require("../ModuleTypeConstants"); const { evaluateToString, toConstantDependency } = require("../javascript/JavascriptParserHelpers"); +/** @typedef {import("../../declarations/WebpackOptions").JavascriptParserOptions} JavascriptParserOptions */ +/** @typedef {import("../Compiler")} Compiler */ +/** @typedef {import("../javascript/JavascriptParser")} Parser */ + +const PLUGIN_NAME = "RequireEnsurePlugin"; + class RequireEnsurePlugin { + /** + * Apply the plugin + * @param {Compiler} compiler the compiler instance + * @returns {void} + */ apply(compiler) { compiler.hooks.compilation.tap( - "RequireEnsurePlugin", + PLUGIN_NAME, (compilation, { normalModuleFactory }) => { compilation.dependencyFactories.set( RequireEnsureItemDependency, @@ -34,6 +49,11 @@ class RequireEnsurePlugin { new RequireEnsureDependency.Template() ); + /** + * @param {Parser} parser parser parser + * @param {JavascriptParserOptions} parserOptions parserOptions + * @returns {void} + */ const handler = (parser, parserOptions) => { if ( parserOptions.requireEnsure !== undefined && @@ -44,21 +64,21 @@ class RequireEnsurePlugin { new RequireEnsureDependenciesBlockParserPlugin().apply(parser); parser.hooks.evaluateTypeof .for("require.ensure") - .tap("RequireEnsurePlugin", evaluateToString("function")); + .tap(PLUGIN_NAME, evaluateToString("function")); parser.hooks.typeof .for("require.ensure") .tap( - "RequireEnsurePlugin", + PLUGIN_NAME, toConstantDependency(parser, JSON.stringify("function")) ); }; normalModuleFactory.hooks.parser - .for("javascript/auto") - .tap("RequireEnsurePlugin", handler); + .for(JAVASCRIPT_MODULE_TYPE_AUTO) + .tap(PLUGIN_NAME, handler); normalModuleFactory.hooks.parser - .for("javascript/dynamic") - .tap("RequireEnsurePlugin", handler); + .for(JAVASCRIPT_MODULE_TYPE_DYNAMIC) + .tap(PLUGIN_NAME, handler); } ); } diff --git a/lib/dependencies/RequireHeaderDependency.js b/lib/dependencies/RequireHeaderDependency.js index db76b5f4fc2..7bf75603593 100644 --- a/lib/dependencies/RequireHeaderDependency.js +++ b/lib/dependencies/RequireHeaderDependency.js @@ -12,20 +12,33 @@ const NullDependency = require("./NullDependency"); /** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */ /** @typedef {import("../Dependency")} Dependency */ /** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */ +/** @typedef {import("../javascript/JavascriptParser").Range} Range */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */ class RequireHeaderDependency extends NullDependency { + /** + * @param {Range} range range + */ constructor(range) { super(); if (!Array.isArray(range)) throw new Error("range must be valid"); this.range = range; } + /** + * @param {ObjectSerializerContext} context context + */ serialize(context) { const { write } = context; write(this.range); super.serialize(context); } + /** + * @param {ObjectDeserializerContext} context context + * @returns {RequireHeaderDependency} RequireHeaderDependency + */ static deserialize(context) { const obj = new RequireHeaderDependency(context.read()); obj.deserialize(context); @@ -50,7 +63,7 @@ RequireHeaderDependency.Template = class RequireHeaderDependencyTemplate extends apply(dependency, source, { runtimeRequirements }) { const dep = /** @type {RequireHeaderDependency} */ (dependency); runtimeRequirements.add(RuntimeGlobals.require); - source.replace(dep.range[0], dep.range[1] - 1, "__webpack_require__"); + source.replace(dep.range[0], dep.range[1] - 1, RuntimeGlobals.require); } }; diff --git a/lib/dependencies/RequireIncludeDependency.js b/lib/dependencies/RequireIncludeDependency.js index 35c0f45404c..3a25e84a8ff 100644 --- a/lib/dependencies/RequireIncludeDependency.js +++ b/lib/dependencies/RequireIncludeDependency.js @@ -14,9 +14,14 @@ const ModuleDependency = require("./ModuleDependency"); /** @typedef {import("../Dependency").ReferencedExport} ReferencedExport */ /** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */ /** @typedef {import("../ModuleGraph")} ModuleGraph */ +/** @typedef {import("../javascript/JavascriptParser").Range} Range */ /** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */ class RequireIncludeDependency extends ModuleDependency { + /** + * @param {string} request the request string + * @param {Range} range location in source code + */ constructor(request, range) { super(request); @@ -64,7 +69,7 @@ RequireIncludeDependency.Template = class RequireIncludeDependencyTemplate exten `require.include ${runtimeTemplate.requestShortener.shorten( dep.request )}` - ) + ) : ""; source.replace(dep.range[0], dep.range[1] - 1, `undefined${comment}`); diff --git a/lib/dependencies/RequireIncludeDependencyParserPlugin.js b/lib/dependencies/RequireIncludeDependencyParserPlugin.js index b33a8dfe289..7b9de2c9324 100644 --- a/lib/dependencies/RequireIncludeDependencyParserPlugin.js +++ b/lib/dependencies/RequireIncludeDependencyParserPlugin.js @@ -13,10 +13,22 @@ const { const makeSerializable = require("../util/makeSerializable"); const RequireIncludeDependency = require("./RequireIncludeDependency"); +/** @typedef {import("../Dependency").DependencyLocation} DependencyLocation */ +/** @typedef {import("../javascript/JavascriptParser")} JavascriptParser */ +/** @typedef {import("../javascript/JavascriptParser").Range} Range */ + module.exports = class RequireIncludeDependencyParserPlugin { + /** + * @param {boolean} warn true: warn about deprecation, false: don't warn + */ constructor(warn) { this.warn = warn; } + + /** + * @param {JavascriptParser} parser the parser + * @returns {void} + */ apply(parser) { const { warn } = this; parser.hooks.call @@ -28,12 +40,17 @@ module.exports = class RequireIncludeDependencyParserPlugin { if (warn) { parser.state.module.addWarning( - new RequireIncludeDeprecationWarning(expr.loc) + new RequireIncludeDeprecationWarning( + /** @type {DependencyLocation} */ (expr.loc) + ) ); } - const dep = new RequireIncludeDependency(param.string, expr.range); - dep.loc = expr.loc; + const dep = new RequireIncludeDependency( + /** @type {string} */ (param.string), + /** @type {Range} */ (expr.range) + ); + dep.loc = /** @type {DependencyLocation} */ (expr.loc); parser.state.current.addDependency(dep); return true; }); @@ -42,7 +59,9 @@ module.exports = class RequireIncludeDependencyParserPlugin { .tap("RequireIncludePlugin", expr => { if (warn) { parser.state.module.addWarning( - new RequireIncludeDeprecationWarning(expr.loc) + new RequireIncludeDeprecationWarning( + /** @type {DependencyLocation} */ (expr.loc) + ) ); } return evaluateToString("function")(expr); @@ -52,7 +71,9 @@ module.exports = class RequireIncludeDependencyParserPlugin { .tap("RequireIncludePlugin", expr => { if (warn) { parser.state.module.addWarning( - new RequireIncludeDeprecationWarning(expr.loc) + new RequireIncludeDeprecationWarning( + /** @type {DependencyLocation} */ (expr.loc) + ) ); } return toConstantDependency(parser, JSON.stringify("function"))(expr); @@ -61,14 +82,15 @@ module.exports = class RequireIncludeDependencyParserPlugin { }; class RequireIncludeDeprecationWarning extends WebpackError { + /** + * @param {DependencyLocation} loc location + */ constructor(loc) { super("require.include() is deprecated and will be removed soon."); this.name = "RequireIncludeDeprecationWarning"; this.loc = loc; - - Error.captureStackTrace(this, this.constructor); } } diff --git a/lib/dependencies/RequireIncludePlugin.js b/lib/dependencies/RequireIncludePlugin.js index 0dbc434fdb4..af5bd0215fd 100644 --- a/lib/dependencies/RequireIncludePlugin.js +++ b/lib/dependencies/RequireIncludePlugin.js @@ -5,13 +5,28 @@ "use strict"; +const { + JAVASCRIPT_MODULE_TYPE_AUTO, + JAVASCRIPT_MODULE_TYPE_DYNAMIC +} = require("../ModuleTypeConstants"); const RequireIncludeDependency = require("./RequireIncludeDependency"); const RequireIncludeDependencyParserPlugin = require("./RequireIncludeDependencyParserPlugin"); +/** @typedef {import("../../declarations/WebpackOptions").JavascriptParserOptions} JavascriptParserOptions */ +/** @typedef {import("../Compiler")} Compiler */ +/** @typedef {import("../javascript/JavascriptParser")} Parser */ + +const PLUGIN_NAME = "RequireIncludePlugin"; + class RequireIncludePlugin { + /** + * Apply the plugin + * @param {Compiler} compiler the compiler instance + * @returns {void} + */ apply(compiler) { compiler.hooks.compilation.tap( - "RequireIncludePlugin", + PLUGIN_NAME, (compilation, { normalModuleFactory }) => { compilation.dependencyFactories.set( RequireIncludeDependency, @@ -22,6 +37,11 @@ class RequireIncludePlugin { new RequireIncludeDependency.Template() ); + /** + * @param {Parser} parser parser parser + * @param {JavascriptParserOptions} parserOptions parserOptions + * @returns {void} + */ const handler = (parser, parserOptions) => { if (parserOptions.requireInclude === false) return; const warn = parserOptions.requireInclude === undefined; @@ -30,11 +50,11 @@ class RequireIncludePlugin { }; normalModuleFactory.hooks.parser - .for("javascript/auto") - .tap("RequireIncludePlugin", handler); + .for(JAVASCRIPT_MODULE_TYPE_AUTO) + .tap(PLUGIN_NAME, handler); normalModuleFactory.hooks.parser - .for("javascript/dynamic") - .tap("RequireIncludePlugin", handler); + .for(JAVASCRIPT_MODULE_TYPE_DYNAMIC) + .tap(PLUGIN_NAME, handler); } ); } diff --git a/lib/dependencies/RequireResolveContextDependency.js b/lib/dependencies/RequireResolveContextDependency.js index 4e998ec0f12..dd82e922094 100644 --- a/lib/dependencies/RequireResolveContextDependency.js +++ b/lib/dependencies/RequireResolveContextDependency.js @@ -9,9 +9,20 @@ const makeSerializable = require("../util/makeSerializable"); const ContextDependency = require("./ContextDependency"); const ContextDependencyTemplateAsId = require("./ContextDependencyTemplateAsId"); +/** @typedef {import("../javascript/JavascriptParser").Range} Range */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */ +/** @typedef {import("./ContextDependency").ContextDependencyOptions} ContextDependencyOptions */ + class RequireResolveContextDependency extends ContextDependency { - constructor(options, range, valueRange) { - super(options); + /** + * @param {ContextDependencyOptions} options options + * @param {Range} range range + * @param {Range} valueRange value range + * @param {TODO} context context + */ + constructor(options, range, valueRange, context) { + super(options, context); this.range = range; this.valueRange = valueRange; @@ -21,6 +32,9 @@ class RequireResolveContextDependency extends ContextDependency { return "amd require context"; } + /** + * @param {ObjectSerializerContext} context context + */ serialize(context) { const { write } = context; @@ -30,6 +44,9 @@ class RequireResolveContextDependency extends ContextDependency { super.serialize(context); } + /** + * @param {ObjectDeserializerContext} context context + */ deserialize(context) { const { read } = context; diff --git a/lib/dependencies/RequireResolveDependency.js b/lib/dependencies/RequireResolveDependency.js index 8d6ade3d110..da0bd319b9d 100644 --- a/lib/dependencies/RequireResolveDependency.js +++ b/lib/dependencies/RequireResolveDependency.js @@ -12,13 +12,20 @@ const ModuleDependencyAsId = require("./ModuleDependencyTemplateAsId"); /** @typedef {import("../Dependency").ReferencedExport} ReferencedExport */ /** @typedef {import("../ModuleGraph")} ModuleGraph */ +/** @typedef {import("../javascript/JavascriptParser").Range} Range */ /** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */ class RequireResolveDependency extends ModuleDependency { - constructor(request, range) { + /** + * @param {string} request the request string + * @param {Range} range location in source code + * @param {string} [context] context + */ + constructor(request, range, context) { super(request); this.range = range; + this._context = context; } get type() { diff --git a/lib/dependencies/RequireResolveHeaderDependency.js b/lib/dependencies/RequireResolveHeaderDependency.js index bc4e177951c..2c9524c98ee 100644 --- a/lib/dependencies/RequireResolveHeaderDependency.js +++ b/lib/dependencies/RequireResolveHeaderDependency.js @@ -11,8 +11,14 @@ const NullDependency = require("./NullDependency"); /** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */ /** @typedef {import("../Dependency")} Dependency */ /** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */ +/** @typedef {import("../javascript/JavascriptParser").Range} Range */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */ class RequireResolveHeaderDependency extends NullDependency { + /** + * @param {Range} range range + */ constructor(range) { super(); @@ -21,6 +27,9 @@ class RequireResolveHeaderDependency extends NullDependency { this.range = range; } + /** + * @param {ObjectSerializerContext} context context + */ serialize(context) { const { write } = context; @@ -29,6 +38,10 @@ class RequireResolveHeaderDependency extends NullDependency { super.serialize(context); } + /** + * @param {ObjectDeserializerContext} context context + * @returns {RequireResolveHeaderDependency} RequireResolveHeaderDependency + */ static deserialize(context) { const obj = new RequireResolveHeaderDependency(context.read()); obj.deserialize(context); @@ -55,6 +68,11 @@ RequireResolveHeaderDependency.Template = class RequireResolveHeaderDependencyTe source.replace(dep.range[0], dep.range[1] - 1, "/*require.resolve*/"); } + /** + * @param {string} name name + * @param {RequireResolveHeaderDependency} dep dependency + * @param {ReplaceSource} source source + */ applyAsTemplateArgument(name, dep, source) { source.replace(dep.range[0], dep.range[1] - 1, "/*require.resolve*/"); } diff --git a/lib/dependencies/RuntimeRequirementsDependency.js b/lib/dependencies/RuntimeRequirementsDependency.js index ab4214a08e1..714567b7140 100644 --- a/lib/dependencies/RuntimeRequirementsDependency.js +++ b/lib/dependencies/RuntimeRequirementsDependency.js @@ -14,6 +14,8 @@ const NullDependency = require("./NullDependency"); /** @typedef {import("../Dependency").UpdateHashContext} UpdateHashContext */ /** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */ /** @typedef {import("../ModuleGraph")} ModuleGraph */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */ /** @typedef {import("../util/Hash")} Hash */ class RuntimeRequirementsDependency extends NullDependency { @@ -23,6 +25,7 @@ class RuntimeRequirementsDependency extends NullDependency { constructor(runtimeRequirements) { super(); this.runtimeRequirements = new Set(runtimeRequirements); + this._hashUpdate = undefined; } /** @@ -32,15 +35,24 @@ class RuntimeRequirementsDependency extends NullDependency { * @returns {void} */ updateHash(hash, context) { - hash.update(Array.from(this.runtimeRequirements).join() + ""); + if (this._hashUpdate === undefined) { + this._hashUpdate = `${Array.from(this.runtimeRequirements).join()}`; + } + hash.update(this._hashUpdate); } + /** + * @param {ObjectSerializerContext} context context + */ serialize(context) { const { write } = context; write(this.runtimeRequirements); super.serialize(context); } + /** + * @param {ObjectDeserializerContext} context context + */ deserialize(context) { const { read } = context; this.runtimeRequirements = read(); diff --git a/lib/dependencies/StaticExportsDependency.js b/lib/dependencies/StaticExportsDependency.js index d58e3286de4..d91b5e43da5 100644 --- a/lib/dependencies/StaticExportsDependency.js +++ b/lib/dependencies/StaticExportsDependency.js @@ -13,6 +13,8 @@ const NullDependency = require("./NullDependency"); /** @typedef {import("../Dependency").ExportsSpec} ExportsSpec */ /** @typedef {import("../Dependency").UpdateHashContext} UpdateHashContext */ /** @typedef {import("../ModuleGraph")} ModuleGraph */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */ /** @typedef {import("../util/Hash")} Hash */ class StaticExportsDependency extends NullDependency { @@ -43,6 +45,9 @@ class StaticExportsDependency extends NullDependency { }; } + /** + * @param {ObjectSerializerContext} context context + */ serialize(context) { const { write } = context; write(this.exports); @@ -50,6 +55,9 @@ class StaticExportsDependency extends NullDependency { super.serialize(context); } + /** + * @param {ObjectDeserializerContext} context context + */ deserialize(context) { const { read } = context; this.exports = read(); diff --git a/lib/dependencies/SystemPlugin.js b/lib/dependencies/SystemPlugin.js index b3243968fa8..7eb1d1410ed 100644 --- a/lib/dependencies/SystemPlugin.js +++ b/lib/dependencies/SystemPlugin.js @@ -5,6 +5,10 @@ "use strict"; +const { + JAVASCRIPT_MODULE_TYPE_AUTO, + JAVASCRIPT_MODULE_TYPE_DYNAMIC +} = require("../ModuleTypeConstants"); const RuntimeGlobals = require("../RuntimeGlobals"); const WebpackError = require("../WebpackError"); const { @@ -16,7 +20,13 @@ const makeSerializable = require("../util/makeSerializable"); const ConstDependency = require("./ConstDependency"); const SystemRuntimeModule = require("./SystemRuntimeModule"); +/** @typedef {import("../../declarations/WebpackOptions").JavascriptParserOptions} JavascriptParserOptions */ /** @typedef {import("../Compiler")} Compiler */ +/** @typedef {import("../Dependency").DependencyLocation} DependencyLocation */ +/** @typedef {import("../javascript/JavascriptParser")} Parser */ +/** @typedef {import("../javascript/JavascriptParser").Range} Range */ + +const PLUGIN_NAME = "SystemPlugin"; class SystemPlugin { /** @@ -26,36 +36,44 @@ class SystemPlugin { */ apply(compiler) { compiler.hooks.compilation.tap( - "SystemPlugin", + PLUGIN_NAME, (compilation, { normalModuleFactory }) => { compilation.hooks.runtimeRequirementInModule .for(RuntimeGlobals.system) - .tap("SystemPlugin", (module, set) => { + .tap(PLUGIN_NAME, (module, set) => { set.add(RuntimeGlobals.requireScope); }); compilation.hooks.runtimeRequirementInTree .for(RuntimeGlobals.system) - .tap("SystemPlugin", (chunk, set) => { + .tap(PLUGIN_NAME, (chunk, set) => { compilation.addRuntimeModule(chunk, new SystemRuntimeModule()); }); + /** + * @param {Parser} parser parser parser + * @param {JavascriptParserOptions} parserOptions parserOptions + * @returns {void} + */ const handler = (parser, parserOptions) => { if (parserOptions.system === undefined || !parserOptions.system) { return; } + /** + * @param {string} name name + */ const setNotSupported = name => { parser.hooks.evaluateTypeof .for(name) - .tap("SystemPlugin", evaluateToString("undefined")); + .tap(PLUGIN_NAME, evaluateToString("undefined")); parser.hooks.expression .for(name) .tap( - "SystemPlugin", + PLUGIN_NAME, expressionIsUnsupported( parser, - name + " is not supported by webpack." + `${name} is not supported by webpack.` ) ); }; @@ -63,43 +81,49 @@ class SystemPlugin { parser.hooks.typeof .for("System.import") .tap( - "SystemPlugin", + PLUGIN_NAME, toConstantDependency(parser, JSON.stringify("function")) ); parser.hooks.evaluateTypeof .for("System.import") - .tap("SystemPlugin", evaluateToString("function")); + .tap(PLUGIN_NAME, evaluateToString("function")); parser.hooks.typeof .for("System") .tap( - "SystemPlugin", + PLUGIN_NAME, toConstantDependency(parser, JSON.stringify("object")) ); parser.hooks.evaluateTypeof .for("System") - .tap("SystemPlugin", evaluateToString("object")); + .tap(PLUGIN_NAME, evaluateToString("object")); setNotSupported("System.set"); setNotSupported("System.get"); setNotSupported("System.register"); - parser.hooks.expression.for("System").tap("SystemPlugin", expr => { - const dep = new ConstDependency(RuntimeGlobals.system, expr.range, [ - RuntimeGlobals.system - ]); - dep.loc = expr.loc; + parser.hooks.expression.for("System").tap(PLUGIN_NAME, expr => { + const dep = new ConstDependency( + RuntimeGlobals.system, + /** @type {Range} */ (expr.range), + [RuntimeGlobals.system] + ); + dep.loc = /** @type {DependencyLocation} */ (expr.loc); parser.state.module.addPresentationalDependency(dep); return true; }); - parser.hooks.call.for("System.import").tap("SystemPlugin", expr => { + parser.hooks.call.for("System.import").tap(PLUGIN_NAME, expr => { parser.state.module.addWarning( - new SystemImportDeprecationWarning(expr.loc) + new SystemImportDeprecationWarning( + /** @type {DependencyLocation} */ (expr.loc) + ) ); return parser.hooks.importCall.call({ type: "ImportExpression", - source: expr.arguments[0], + source: + /** @type {import("estree").Literal} */ + (expr.arguments[0]), loc: expr.loc, range: expr.range }); @@ -107,17 +131,20 @@ class SystemPlugin { }; normalModuleFactory.hooks.parser - .for("javascript/auto") - .tap("SystemPlugin", handler); + .for(JAVASCRIPT_MODULE_TYPE_AUTO) + .tap(PLUGIN_NAME, handler); normalModuleFactory.hooks.parser - .for("javascript/dynamic") - .tap("SystemPlugin", handler); + .for(JAVASCRIPT_MODULE_TYPE_DYNAMIC) + .tap(PLUGIN_NAME, handler); } ); } } class SystemImportDeprecationWarning extends WebpackError { + /** + * @param {DependencyLocation} loc location + */ constructor(loc) { super( "System.import() is deprecated and will be removed soon. Use import() instead.\n" + @@ -127,8 +154,6 @@ class SystemImportDeprecationWarning extends WebpackError { this.name = "SystemImportDeprecationWarning"; this.loc = loc; - - Error.captureStackTrace(this, this.constructor); } } diff --git a/lib/dependencies/SystemRuntimeModule.js b/lib/dependencies/SystemRuntimeModule.js index c61f0fc2ea0..a7c3fba72f9 100644 --- a/lib/dependencies/SystemRuntimeModule.js +++ b/lib/dependencies/SystemRuntimeModule.js @@ -15,7 +15,7 @@ class SystemRuntimeModule extends RuntimeModule { } /** - * @returns {string} runtime code + * @returns {string | null} runtime code */ generate() { return Template.asString([ diff --git a/lib/dependencies/URLDependency.js b/lib/dependencies/URLDependency.js index eb998ed3c7c..0d5b0a58bfe 100644 --- a/lib/dependencies/URLDependency.js +++ b/lib/dependencies/URLDependency.js @@ -6,6 +6,7 @@ "use strict"; const RuntimeGlobals = require("../RuntimeGlobals"); +const RawDataUrlModule = require("../asset/RawDataUrlModule"); const { getDependencyUsedByExportsCondition } = require("../optimize/InnerGraph"); @@ -16,22 +17,28 @@ const ModuleDependency = require("./ModuleDependency"); /** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */ /** @typedef {import("../ChunkGraph")} ChunkGraph */ /** @typedef {import("../Dependency")} Dependency */ +/** @typedef {import("../Dependency").GetConditionFn} GetConditionFn */ /** @typedef {import("../Dependency").UpdateHashContext} UpdateHashContext */ /** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */ /** @typedef {import("../Module")} Module */ /** @typedef {import("../ModuleGraph")} ModuleGraph */ /** @typedef {import("../ModuleGraphConnection")} ModuleGraphConnection */ /** @typedef {import("../ModuleGraphConnection").ConnectionState} ConnectionState */ +/** @typedef {import("../javascript/JavascriptParser").Range} Range */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */ /** @typedef {import("../util/Hash")} Hash */ /** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */ -const getRawModule = memoize(() => require("../RawModule")); +const getIgnoredRawDataUrlModule = memoize( + () => new RawDataUrlModule("data:,", "ignored-asset", "(ignored asset)") +); class URLDependency extends ModuleDependency { /** * @param {string} request request - * @param {[number, number]} range range of the arguments of new URL( |> ... <| ) - * @param {[number, number]} outerRange range of the full |> new URL(...) <| + * @param {Range} range range of the arguments of new URL( |> ... <| ) + * @param {Range} outerRange range of the full |> new URL(...) <| * @param {boolean=} relative use relative urls instead of absolute with base uri */ constructor(request, range, outerRange, relative) { @@ -39,7 +46,7 @@ class URLDependency extends ModuleDependency { this.range = range; this.outerRange = outerRange; this.relative = relative || false; - /** @type {Set | boolean} */ + /** @type {Set | boolean | undefined} */ this.usedByExports = undefined; } @@ -53,7 +60,7 @@ class URLDependency extends ModuleDependency { /** * @param {ModuleGraph} moduleGraph module graph - * @returns {null | false | function(ModuleGraphConnection, RuntimeSpec): ConnectionState} function to determine if the connection is active + * @returns {null | false | GetConditionFn} function to determine if the connection is active */ getCondition(moduleGraph) { return getDependencyUsedByExportsCondition( @@ -65,18 +72,15 @@ class URLDependency extends ModuleDependency { /** * @param {string} context context directory - * @returns {Module} a module + * @returns {Module | null} a module */ createIgnoredModule(context) { - const RawModule = getRawModule(); - return new RawModule( - 'module.exports = "data:,";', - `ignored-asset`, - `(ignored asset)`, - new Set([RuntimeGlobals.module]) - ); + return getIgnoredRawDataUrlModule(); } + /** + * @param {ObjectSerializerContext} context context + */ serialize(context) { const { write } = context; write(this.outerRange); @@ -85,6 +89,9 @@ class URLDependency extends ModuleDependency { super.serialize(context); } + /** + * @param {ObjectDeserializerContext} context context + */ deserialize(context) { const { read } = context; this.outerRange = read(); diff --git a/lib/dependencies/URLPlugin.js b/lib/dependencies/URLPlugin.js index 94c1912e648..abd345e8c09 100644 --- a/lib/dependencies/URLPlugin.js +++ b/lib/dependencies/URLPlugin.js @@ -5,13 +5,30 @@ "use strict"; +const { pathToFileURL } = require("url"); +const CommentCompilationWarning = require("../CommentCompilationWarning"); +const { + JAVASCRIPT_MODULE_TYPE_AUTO, + JAVASCRIPT_MODULE_TYPE_ESM +} = require("../ModuleTypeConstants"); +const RuntimeGlobals = require("../RuntimeGlobals"); +const UnsupportedFeatureWarning = require("../UnsupportedFeatureWarning"); +const BasicEvaluatedExpression = require("../javascript/BasicEvaluatedExpression"); const { approve } = require("../javascript/JavascriptParserHelpers"); const InnerGraph = require("../optimize/InnerGraph"); +const ConstDependency = require("./ConstDependency"); const URLDependency = require("./URLDependency"); /** @typedef {import("estree").NewExpression} NewExpressionNode */ +/** @typedef {import("../../declarations/WebpackOptions").JavascriptParserOptions} JavascriptParserOptions */ /** @typedef {import("../Compiler")} Compiler */ +/** @typedef {import("../Dependency").DependencyLocation} DependencyLocation */ +/** @typedef {import("../NormalModule")} NormalModule */ /** @typedef {import("../javascript/JavascriptParser")} JavascriptParser */ +/** @typedef {import("../javascript/JavascriptParser")} Parser */ +/** @typedef {import("../javascript/JavascriptParser").Range} Range */ + +const PLUGIN_NAME = "URLPlugin"; class URLPlugin { /** @@ -19,7 +36,7 @@ class URLPlugin { */ apply(compiler) { compiler.hooks.compilation.tap( - "URLPlugin", + PLUGIN_NAME, (compilation, { normalModuleFactory }) => { compilation.dependencyFactories.set(URLDependency, normalModuleFactory); compilation.dependencyTemplates.set( @@ -28,8 +45,30 @@ class URLPlugin { ); /** - * @param {JavascriptParser} parser parser - * @param {object} parserOptions options + * @param {NormalModule} module module + * @returns {URL} file url + */ + const getUrl = module => pathToFileURL(module.resource); + + const isMetaUrl = (parser, arg) => { + const chain = parser.extractMemberExpressionChain(arg); + + if ( + chain.members.length !== 1 || + chain.object.type !== "MetaProperty" || + chain.object.meta.name !== "import" || + chain.object.property.name !== "meta" || + chain.members[0] !== "url" + ) + return false; + + return true; + }; + + /** + * @param {Parser} parser parser parser + * @param {JavascriptParserOptions} parserOptions parserOptions + * @returns {void} */ const parserCallback = (parser, parserOptions) => { if (parserOptions.url === false) return; @@ -50,25 +89,71 @@ class URLPlugin { ) return; - const chain = parser.extractMemberExpressionChain(arg2); - - if ( - chain.members.length !== 1 || - chain.object.type !== "MetaProperty" || - chain.object.meta.name !== "import" || - chain.object.property.name !== "meta" || - chain.members[0] !== "url" - ) - return; - - const request = parser.evaluateExpression(arg1).asString(); + if (!isMetaUrl(parser, arg2)) return; - return request; + return parser.evaluateExpression(arg1).asString(); }; - parser.hooks.canRename.for("URL").tap("URLPlugin", approve); - parser.hooks.new.for("URL").tap("URLPlugin", _expr => { + parser.hooks.canRename.for("URL").tap(PLUGIN_NAME, approve); + parser.hooks.evaluateNewExpression + .for("URL") + .tap(PLUGIN_NAME, expr => { + const request = getUrlRequest(expr); + if (!request) return; + const url = new URL(request, getUrl(parser.state.module)); + + return new BasicEvaluatedExpression() + .setString(url.toString()) + .setRange(/** @type {Range} */ (expr.range)); + }); + parser.hooks.new.for("URL").tap(PLUGIN_NAME, _expr => { const expr = /** @type {NewExpressionNode} */ (_expr); + const { options: importOptions, errors: commentErrors } = + parser.parseCommentOptions(/** @type {Range} */ (expr.range)); + + if (commentErrors) { + for (const e of commentErrors) { + const { comment } = e; + parser.state.module.addWarning( + new CommentCompilationWarning( + `Compilation error while processing magic comment(-s): /*${comment.value}*/: ${e.message}`, + comment.loc + ) + ); + } + } + + if (importOptions && importOptions.webpackIgnore !== undefined) { + if (typeof importOptions.webpackIgnore !== "boolean") { + parser.state.module.addWarning( + new UnsupportedFeatureWarning( + `\`webpackIgnore\` expected a boolean, but received: ${importOptions.webpackIgnore}.`, + /** @type {DependencyLocation} */ (expr.loc) + ) + ); + return; + } else if (importOptions.webpackIgnore) { + if (expr.arguments.length !== 2) return; + + const [, arg2] = expr.arguments; + + if ( + arg2.type !== "MemberExpression" || + !isMetaUrl(parser, arg2) + ) + return; + + const dep = new ConstDependency( + RuntimeGlobals.baseURI, + /** @type {Range} */ (arg2.range), + [RuntimeGlobals.baseURI] + ); + dep.loc = /** @type {DependencyLocation} */ (expr.loc); + parser.state.module.addPresentationalDependency(dep); + + return true; + } + } const request = getUrlRequest(expr); @@ -77,16 +162,19 @@ class URLPlugin { const [arg1, arg2] = expr.arguments; const dep = new URLDependency( request, - [arg1.range[0], arg2.range[1]], - expr.range, + [ + /** @type {Range} */ (arg1.range)[0], + /** @type {Range} */ (arg2.range)[1] + ], + /** @type {Range} */ (expr.range), relative ); - dep.loc = expr.loc; - parser.state.module.addDependency(dep); + dep.loc = /** @type {DependencyLocation} */ (expr.loc); + parser.state.current.addDependency(dep); InnerGraph.onUsage(parser.state, e => (dep.usedByExports = e)); return true; }); - parser.hooks.isPure.for("NewExpression").tap("URLPlugin", _expr => { + parser.hooks.isPure.for("NewExpression").tap(PLUGIN_NAME, _expr => { const expr = /** @type {NewExpressionNode} */ (_expr); const { callee } = expr; if (callee.type !== "Identifier") return; @@ -100,12 +188,12 @@ class URLPlugin { }; normalModuleFactory.hooks.parser - .for("javascript/auto") - .tap("URLPlugin", parserCallback); + .for(JAVASCRIPT_MODULE_TYPE_AUTO) + .tap(PLUGIN_NAME, parserCallback); normalModuleFactory.hooks.parser - .for("javascript/esm") - .tap("URLPlugin", parserCallback); + .for(JAVASCRIPT_MODULE_TYPE_ESM) + .tap(PLUGIN_NAME, parserCallback); } ); } diff --git a/lib/dependencies/UnsupportedDependency.js b/lib/dependencies/UnsupportedDependency.js index b8624b8bb5e..6796634c9b4 100644 --- a/lib/dependencies/UnsupportedDependency.js +++ b/lib/dependencies/UnsupportedDependency.js @@ -11,8 +11,15 @@ const NullDependency = require("./NullDependency"); /** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */ /** @typedef {import("../Dependency")} Dependency */ /** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */ +/** @typedef {import("../javascript/JavascriptParser").Range} Range */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */ class UnsupportedDependency extends NullDependency { + /** + * @param {string} request the request string + * @param {Range} range location in source code + */ constructor(request, range) { super(); @@ -20,6 +27,9 @@ class UnsupportedDependency extends NullDependency { this.range = range; } + /** + * @param {ObjectSerializerContext} context context + */ serialize(context) { const { write } = context; @@ -29,6 +39,9 @@ class UnsupportedDependency extends NullDependency { super.serialize(context); } + /** + * @param {ObjectDeserializerContext} context context + */ deserialize(context) { const { read } = context; diff --git a/lib/dependencies/WebAssemblyExportImportedDependency.js b/lib/dependencies/WebAssemblyExportImportedDependency.js index bfa0d08b19f..c2452ecd1c6 100644 --- a/lib/dependencies/WebAssemblyExportImportedDependency.js +++ b/lib/dependencies/WebAssemblyExportImportedDependency.js @@ -5,14 +5,24 @@ "use strict"; +const Dependency = require("../Dependency"); const makeSerializable = require("../util/makeSerializable"); const ModuleDependency = require("./ModuleDependency"); /** @typedef {import("../Dependency").ReferencedExport} ReferencedExport */ +/** @typedef {import("../Dependency").TRANSITIVE} TRANSITIVE */ /** @typedef {import("../ModuleGraph")} ModuleGraph */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */ /** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */ class WebAssemblyExportImportedDependency extends ModuleDependency { + /** + * @param {string} exportName export name + * @param {string} request request + * @param {string} name name + * @param {TODO} valueType value type + */ constructor(exportName, request, name, valueType) { super(request); /** @type {string} */ @@ -23,6 +33,13 @@ class WebAssemblyExportImportedDependency extends ModuleDependency { this.valueType = valueType; } + /** + * @returns {boolean | TRANSITIVE} true, when changes to the referenced module could affect the referencing module; TRANSITIVE, when changes to the referenced module could affect referencing modules of the referencing module + */ + couldAffectReferencingModule() { + return Dependency.TRANSITIVE; + } + /** * Returns list of exports referenced by this dependency * @param {ModuleGraph} moduleGraph module graph @@ -41,6 +58,9 @@ class WebAssemblyExportImportedDependency extends ModuleDependency { return "wasm"; } + /** + * @param {ObjectSerializerContext} context context + */ serialize(context) { const { write } = context; @@ -51,6 +71,9 @@ class WebAssemblyExportImportedDependency extends ModuleDependency { super.serialize(context); } + /** + * @param {ObjectDeserializerContext} context context + */ deserialize(context) { const { read } = context; diff --git a/lib/dependencies/WebAssemblyImportDependency.js b/lib/dependencies/WebAssemblyImportDependency.js index 52c23280bc2..de23f76f19a 100644 --- a/lib/dependencies/WebAssemblyImportDependency.js +++ b/lib/dependencies/WebAssemblyImportDependency.js @@ -13,6 +13,8 @@ const ModuleDependency = require("./ModuleDependency"); /** @typedef {import("../Dependency").ReferencedExport} ReferencedExport */ /** @typedef {import("../ModuleGraph")} ModuleGraph */ /** @typedef {import("../WebpackError")} WebpackError */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */ /** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */ class WebAssemblyImportDependency extends ModuleDependency { @@ -53,7 +55,7 @@ class WebAssemblyImportDependency extends ModuleDependency { /** * Returns errors * @param {ModuleGraph} moduleGraph module graph - * @returns {WebpackError[]} errors + * @returns {WebpackError[] | null | undefined} errors */ getErrors(moduleGraph) { const module = moduleGraph.getModule(this); @@ -71,6 +73,9 @@ class WebAssemblyImportDependency extends ModuleDependency { } } + /** + * @param {ObjectSerializerContext} context context + */ serialize(context) { const { write } = context; @@ -81,6 +86,9 @@ class WebAssemblyImportDependency extends ModuleDependency { super.serialize(context); } + /** + * @param {ObjectDeserializerContext} context context + */ deserialize(context) { const { read } = context; diff --git a/lib/dependencies/WebpackIsIncludedDependency.js b/lib/dependencies/WebpackIsIncludedDependency.js index f3406ebd90d..0b308734ee7 100644 --- a/lib/dependencies/WebpackIsIncludedDependency.js +++ b/lib/dependencies/WebpackIsIncludedDependency.js @@ -15,9 +15,14 @@ const ModuleDependency = require("./ModuleDependency"); /** @typedef {import("../Dependency").ReferencedExport} ReferencedExport */ /** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */ /** @typedef {import("../ModuleGraph")} ModuleGraph */ +/** @typedef {import("../javascript/JavascriptParser").Range} Range */ /** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */ class WebpackIsIncludedDependency extends ModuleDependency { + /** + * @param {string} request the request string + * @param {Range} range location in source code + */ constructor(request, range) { super(request); @@ -66,7 +71,7 @@ WebpackIsIncludedDependency.Template = class WebpackIsIncludedDependencyTemplate `__webpack_is_included__ ${runtimeTemplate.requestShortener.shorten( dep.request )}` - ) + ) : ""; source.replace( diff --git a/lib/dependencies/WorkerDependency.js b/lib/dependencies/WorkerDependency.js index 21ffaecc32d..16693d1a4cb 100644 --- a/lib/dependencies/WorkerDependency.js +++ b/lib/dependencies/WorkerDependency.js @@ -18,17 +18,26 @@ const ModuleDependency = require("./ModuleDependency"); /** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */ /** @typedef {import("../Entrypoint")} Entrypoint */ /** @typedef {import("../ModuleGraph")} ModuleGraph */ +/** @typedef {import("../javascript/JavascriptParser").Range} Range */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */ /** @typedef {import("../util/Hash")} Hash */ /** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */ class WorkerDependency extends ModuleDependency { /** * @param {string} request request - * @param {[number, number]} range range + * @param {Range} range range + * @param {object} workerDependencyOptions options + * @param {string=} workerDependencyOptions.publicPath public path for the worker */ - constructor(request, range) { + constructor(request, range, workerDependencyOptions) { super(request); this.range = range; + // If options are updated, don't forget to update the hash and serialization functions + this.options = workerDependencyOptions; + /** Cache the hash */ + this._hashUpdate = undefined; } /** @@ -48,6 +57,37 @@ class WorkerDependency extends ModuleDependency { get category() { return "worker"; } + + /** + * Update the hash + * @param {Hash} hash hash to be updated + * @param {UpdateHashContext} context context + * @returns {void} + */ + updateHash(hash, context) { + if (this._hashUpdate === undefined) { + this._hashUpdate = JSON.stringify(this.options); + } + hash.update(this._hashUpdate); + } + + /** + * @param {ObjectSerializerContext} context context + */ + serialize(context) { + const { write } = context; + write(this.options); + super.serialize(context); + } + + /** + * @param {ObjectDeserializerContext} context context + */ + deserialize(context) { + const { read } = context; + this.options = read(); + super.deserialize(context); + } } WorkerDependency.Template = class WorkerDependencyTemplate extends ( @@ -62,13 +102,17 @@ WorkerDependency.Template = class WorkerDependencyTemplate extends ( apply(dependency, source, templateContext) { const { chunkGraph, moduleGraph, runtimeRequirements } = templateContext; const dep = /** @type {WorkerDependency} */ (dependency); - const block = /** @type {AsyncDependenciesBlock} */ (moduleGraph.getParentBlock( - dependency - )); - const entrypoint = /** @type {Entrypoint} */ (chunkGraph.getBlockChunkGroup( - block - )); + const block = /** @type {AsyncDependenciesBlock} */ ( + moduleGraph.getParentBlock(dependency) + ); + const entrypoint = /** @type {Entrypoint} */ ( + chunkGraph.getBlockChunkGroup(block) + ); const chunk = entrypoint.getEntrypointChunk(); + // We use the workerPublicPath option if provided, else we fallback to the RuntimeGlobal publicPath + const workerImportBaseUrl = dep.options.publicPath + ? `"${dep.options.publicPath}"` + : RuntimeGlobals.publicPath; runtimeRequirements.add(RuntimeGlobals.publicPath); runtimeRequirements.add(RuntimeGlobals.baseURI); @@ -77,7 +121,7 @@ WorkerDependency.Template = class WorkerDependencyTemplate extends ( source.replace( dep.range[0], dep.range[1] - 1, - `/* worker import */ ${RuntimeGlobals.publicPath} + ${ + `/* worker import */ ${workerImportBaseUrl} + ${ RuntimeGlobals.getChunkScriptFilename }(${JSON.stringify(chunk.id)}), ${RuntimeGlobals.baseURI}` ); diff --git a/lib/dependencies/WorkerPlugin.js b/lib/dependencies/WorkerPlugin.js index a52835d710c..aff03b843e1 100644 --- a/lib/dependencies/WorkerPlugin.js +++ b/lib/dependencies/WorkerPlugin.js @@ -8,32 +8,53 @@ const { pathToFileURL } = require("url"); const AsyncDependenciesBlock = require("../AsyncDependenciesBlock"); const CommentCompilationWarning = require("../CommentCompilationWarning"); +const { + JAVASCRIPT_MODULE_TYPE_AUTO, + JAVASCRIPT_MODULE_TYPE_ESM +} = require("../ModuleTypeConstants"); const UnsupportedFeatureWarning = require("../UnsupportedFeatureWarning"); -const formatLocation = require("../formatLocation"); const EnableChunkLoadingPlugin = require("../javascript/EnableChunkLoadingPlugin"); const { equals } = require("../util/ArrayHelpers"); +const createHash = require("../util/createHash"); const { contextify } = require("../util/identifier"); const EnableWasmLoadingPlugin = require("../wasm/EnableWasmLoadingPlugin"); const ConstDependency = require("./ConstDependency"); +const CreateScriptUrlDependency = require("./CreateScriptUrlDependency"); const { harmonySpecifierTag } = require("./HarmonyImportDependencyParserPlugin"); const WorkerDependency = require("./WorkerDependency"); +/** @typedef {import("estree").CallExpression} CallExpression */ /** @typedef {import("estree").Expression} Expression */ /** @typedef {import("estree").ObjectExpression} ObjectExpression */ /** @typedef {import("estree").Pattern} Pattern */ /** @typedef {import("estree").Property} Property */ /** @typedef {import("estree").SpreadElement} SpreadElement */ +/** @typedef {import("../../declarations/WebpackOptions").ChunkLoading} ChunkLoading */ +/** @typedef {import("../../declarations/WebpackOptions").JavascriptParserOptions} JavascriptParserOptions */ +/** @typedef {import("../../declarations/WebpackOptions").OutputModule} OutputModule */ +/** @typedef {import("../../declarations/WebpackOptions").WasmLoading} WasmLoading */ +/** @typedef {import("../../declarations/WebpackOptions").WorkerPublicPath} WorkerPublicPath */ /** @typedef {import("../Compiler")} Compiler */ +/** @typedef {import("../Dependency").DependencyLocation} DependencyLocation */ /** @typedef {import("../Entrypoint").EntryOptions} EntryOptions */ +/** @typedef {import("../NormalModule")} NormalModule */ +/** @typedef {import("../Parser").ParserState} ParserState */ /** @typedef {import("../javascript/BasicEvaluatedExpression")} BasicEvaluatedExpression */ /** @typedef {import("../javascript/JavascriptParser")} JavascriptParser */ +/** @typedef {import("../javascript/JavascriptParser")} Parser */ +/** @typedef {import("../javascript/JavascriptParser").Range} Range */ +/** @typedef {import("../util/createHash").Algorithm} Algorithm */ /** @typedef {import("./HarmonyImportDependencyParserPlugin").HarmonySettings} HarmonySettings */ -const getUrl = module => { - return pathToFileURL(module.resource).toString(); -}; +/** + * @param {NormalModule} module module + * @returns {string} url + */ +const getUrl = module => pathToFileURL(module.resource).toString(); + +const WorkerSpecifierTag = Symbol("worker specifier tag"); const DEFAULT_SYNTAX = [ "Worker", @@ -42,11 +63,25 @@ const DEFAULT_SYNTAX = [ "Worker from worker_threads" ]; +/** @type {WeakMap} */ +const workerIndexMap = new WeakMap(); + +const PLUGIN_NAME = "WorkerPlugin"; + class WorkerPlugin { - constructor(chunkLoading, wasmLoading) { + /** + * @param {ChunkLoading=} chunkLoading chunk loading + * @param {WasmLoading=} wasmLoading wasm loading + * @param {OutputModule=} module output module + * @param {WorkerPublicPath=} workerPublicPath worker public path + */ + constructor(chunkLoading, wasmLoading, module, workerPublicPath) { this._chunkLoading = chunkLoading; this._wasmLoading = wasmLoading; + this._module = module; + this._workerPublicPath = workerPublicPath; } + /** * Apply the plugin * @param {Compiler} compiler the compiler instance @@ -64,7 +99,7 @@ class WorkerPlugin { compiler.root ); compiler.hooks.thisCompilation.tap( - "WorkerPlugin", + PLUGIN_NAME, (compilation, { normalModuleFactory }) => { compilation.dependencyFactories.set( WorkerDependency, @@ -74,11 +109,15 @@ class WorkerPlugin { WorkerDependency, new WorkerDependency.Template() ); + compilation.dependencyTemplates.set( + CreateScriptUrlDependency, + new CreateScriptUrlDependency.Template() + ); /** * @param {JavascriptParser} parser the parser * @param {Expression} expr expression - * @returns {[BasicEvaluatedExpression, [number, number]]} parsed + * @returns {[BasicEvaluatedExpression, [number, number]] | void} parsed */ const parseModuleUrl = (parser, expr) => { if ( @@ -95,13 +134,19 @@ class WorkerPlugin { const arg2Value = parser.evaluateExpression(arg2); if ( !arg2Value.isString() || - !arg2Value.string.startsWith("file://") || + !(/** @type {string} */ (arg2Value.string).startsWith("file://")) || arg2Value.string !== getUrl(parser.state.module) ) { return; } const arg1Value = parser.evaluateExpression(arg1); - return [arg1Value, [arg1.range[0], arg2.range[1]]]; + return [ + arg1Value, + [ + /** @type {Range} */ (arg1.range)[0], + /** @type {Range} */ (arg2.range)[1] + ] + ]; }; /** @@ -139,8 +184,9 @@ class WorkerPlugin { } } const insertType = expr.properties.length > 0 ? "comma" : "single"; - const insertLocation = - expr.properties[expr.properties.length - 1].range[1]; + const insertLocation = /** @type {Range} */ ( + expr.properties[expr.properties.length - 1].range + )[1]; return { expressions, otherElements, @@ -152,14 +198,19 @@ class WorkerPlugin { }; /** - * @param {JavascriptParser} parser the parser - * @param {object} parserOptions options + * @param {Parser} parser parser parser + * @param {JavascriptParserOptions} parserOptions parserOptions + * @returns {void} */ const parserPlugin = (parser, parserOptions) => { if (parserOptions.worker === false) return; const options = !Array.isArray(parserOptions.worker) ? ["..."] : parserOptions.worker; + /** + * @param {CallExpression} expr expression + * @returns {boolean | void} true when handled + */ const handleNewWorker = expr => { if (expr.arguments.length === 0 || expr.arguments.length > 2) return; @@ -177,21 +228,22 @@ class WorkerPlugin { spread: hasSpreadInOptions, insertType, insertLocation - } = - arg2 && arg2.type === "ObjectExpression" - ? parseObjectExpression(parser, arg2) - : { - expressions: {}, - otherElements: [], - values: {}, - spread: false, - insertType: arg2 ? "spread" : "argument", - insertLocation: arg2 ? arg2.range : arg1.range[1] - }; - const { - options: importOptions, - errors: commentErrors - } = parser.parseCommentOptions(expr.range); + } = arg2 && arg2.type === "ObjectExpression" + ? parseObjectExpression(parser, arg2) + : { + /** @type {Record} */ + expressions: {}, + otherElements: [], + /** @type {Record} */ + values: {}, + spread: false, + insertType: arg2 ? "spread" : "argument", + insertLocation: arg2 + ? /** @type {Range} */ (arg2.range) + : /** @type {Range} */ (arg1.range)[1] + }; + const { options: importOptions, errors: commentErrors } = + parser.parseCommentOptions(/** @type {Range} */ (expr.range)); if (commentErrors) { for (const e of commentErrors) { @@ -206,7 +258,7 @@ class WorkerPlugin { } /** @type {EntryOptions} */ - let entryOptions = {}; + const entryOptions = {}; if (importOptions) { if (importOptions.webpackIgnore !== undefined) { @@ -214,13 +266,11 @@ class WorkerPlugin { parser.state.module.addWarning( new UnsupportedFeatureWarning( `\`webpackIgnore\` expected a boolean, but received: ${importOptions.webpackIgnore}.`, - expr.loc + /** @type {DependencyLocation} */ (expr.loc) ) ); - } else { - if (importOptions.webpackIgnore) { - return false; - } + } else if (importOptions.webpackIgnore) { + return false; } } if (importOptions.webpackEntryOptions !== undefined) { @@ -231,7 +281,7 @@ class WorkerPlugin { parser.state.module.addWarning( new UnsupportedFeatureWarning( `\`webpackEntryOptions\` expected a object, but received: ${importOptions.webpackEntryOptions}.`, - expr.loc + /** @type {DependencyLocation} */ (expr.loc) ) ); } else { @@ -246,7 +296,7 @@ class WorkerPlugin { parser.state.module.addWarning( new UnsupportedFeatureWarning( `\`webpackChunkName\` expected a string, but received: ${importOptions.webpackChunkName}.`, - expr.loc + /** @type {DependencyLocation} */ (expr.loc) ) ); } else { @@ -263,10 +313,24 @@ class WorkerPlugin { entryOptions.name = options.name; } - if (!entryOptions.runtime) { - entryOptions.runtime = `${cachedContextify( + if (entryOptions.runtime === undefined) { + const i = workerIndexMap.get(parser.state) || 0; + workerIndexMap.set(parser.state, i + 1); + const name = `${cachedContextify( parser.state.module.identifier() - )}|${formatLocation(expr.loc)}`; + )}|${i}`; + const hash = createHash( + /** @type {Algorithm} */ + (compilation.outputOptions.hashFunction) + ); + hash.update(name); + const digest = + /** @type {string} */ + (hash.digest(compilation.outputOptions.hashDigest)); + entryOptions.runtime = digest.slice( + 0, + compilation.outputOptions.hashDigestLength + ); } const block = new AsyncDependenciesBlock({ @@ -278,42 +342,69 @@ class WorkerPlugin { } }); block.loc = expr.loc; - const dep = new WorkerDependency(url.string, range); - dep.loc = expr.loc; + const dep = new WorkerDependency( + /** @type {string} */ (url.string), + range, + { + publicPath: this._workerPublicPath + } + ); + dep.loc = /** @type {DependencyLocation} */ (expr.loc); block.addDependency(dep); parser.state.module.addBlock(block); - parser.walkExpression(expr.callee); + + if (compilation.outputOptions.trustedTypes) { + const dep = new CreateScriptUrlDependency( + /** @type {Range} */ (expr.arguments[0].range) + ); + dep.loc = /** @type {DependencyLocation} */ (expr.loc); + parser.state.module.addDependency(dep); + } if (expressions.type) { const expr = expressions.type; if (options.type !== false) { - const dep = new ConstDependency("undefined", expr.range); - dep.loc = expr.loc; + const dep = new ConstDependency( + this._module ? '"module"' : "undefined", + /** @type {Range} */ (expr.range) + ); + dep.loc = /** @type {DependencyLocation} */ (expr.loc); + parser.state.module.addPresentationalDependency(dep); + /** @type {TODO} */ + (expressions).type = undefined; + } + } else if (insertType === "comma") { + if (this._module || hasSpreadInOptions) { + const dep = new ConstDependency( + `, type: ${this._module ? '"module"' : "undefined"}`, + insertLocation + ); + dep.loc = /** @type {DependencyLocation} */ (expr.loc); parser.state.module.addPresentationalDependency(dep); - expressions.type = undefined; } - } else if (hasSpreadInOptions && insertType === "comma") { - const dep = new ConstDependency( - ", type: undefined", - insertLocation - ); - dep.loc = expr.loc; - parser.state.module.addPresentationalDependency(dep); } else if (insertType === "spread") { const dep1 = new ConstDependency( "Object.assign({}, ", - insertLocation[0] + /** @type {Range} */ (insertLocation)[0] ); const dep2 = new ConstDependency( - ", { type: undefined })", - insertLocation[1] + `, { type: ${this._module ? '"module"' : "undefined"} })`, + /** @type {Range} */ (insertLocation)[1] ); - dep1.loc = expr.loc; - dep2.loc = expr.loc; + dep1.loc = /** @type {DependencyLocation} */ (expr.loc); + dep2.loc = /** @type {DependencyLocation} */ (expr.loc); parser.state.module.addPresentationalDependency(dep1); parser.state.module.addPresentationalDependency(dep2); + } else if (insertType === "argument" && this._module) { + const dep = new ConstDependency( + ', { type: "module" }', + insertLocation + ); + dep.loc = /** @type {DependencyLocation} */ (expr.loc); + parser.state.module.addPresentationalDependency(dep); } + parser.walkExpression(expr.callee); for (const key of Object.keys(expressions)) { if (expressions[key]) parser.walkExpression(expressions[key]); } @@ -326,11 +417,42 @@ class WorkerPlugin { return true; }; + /** + * @param {string} item item + */ const processItem = item => { - if (item.endsWith("()")) { + if ( + item.startsWith("*") && + item.includes(".") && + item.endsWith("()") + ) { + const firstDot = item.indexOf("."); + const pattern = item.slice(1, firstDot); + const itemMembers = item.slice(firstDot + 1, -2); + + parser.hooks.preDeclarator.tap(PLUGIN_NAME, (decl, statement) => { + if (decl.id.type === "Identifier" && decl.id.name === pattern) { + parser.tagVariable(decl.id.name, WorkerSpecifierTag); + return true; + } + }); + parser.hooks.pattern.for(pattern).tap(PLUGIN_NAME, pattern => { + parser.tagVariable(pattern.name, WorkerSpecifierTag); + return true; + }); + parser.hooks.callMemberChain + .for(WorkerSpecifierTag) + .tap(PLUGIN_NAME, (expression, members) => { + if (itemMembers !== members.join(".")) { + return; + } + + return handleNewWorker(expression); + }); + } else if (item.endsWith("()")) { parser.hooks.call .for(item.slice(0, -2)) - .tap("WorkerPlugin", handleNewWorker); + .tap(PLUGIN_NAME, handleNewWorker); } else { const match = /^(.+?)(\(\))?\s+from\s+(.+)$/.exec(item); if (match) { @@ -339,8 +461,10 @@ class WorkerPlugin { const source = match[3]; (call ? parser.hooks.call : parser.hooks.new) .for(harmonySpecifierTag) - .tap("WorkerPlugin", expr => { - const settings = /** @type {HarmonySettings} */ (parser.currentTagData); + .tap(PLUGIN_NAME, expr => { + const settings = /** @type {HarmonySettings} */ ( + parser.currentTagData + ); if ( !settings || settings.source !== source || @@ -351,22 +475,24 @@ class WorkerPlugin { return handleNewWorker(expr); }); } else { - parser.hooks.new.for(item).tap("WorkerPlugin", handleNewWorker); + parser.hooks.new.for(item).tap(PLUGIN_NAME, handleNewWorker); } } }; for (const item of options) { if (item === "...") { - DEFAULT_SYNTAX.forEach(processItem); + for (const itemFromDefault of DEFAULT_SYNTAX) { + processItem(itemFromDefault); + } } else processItem(item); } }; normalModuleFactory.hooks.parser - .for("javascript/auto") - .tap("WorkerPlugin", parserPlugin); + .for(JAVASCRIPT_MODULE_TYPE_AUTO) + .tap(PLUGIN_NAME, parserPlugin); normalModuleFactory.hooks.parser - .for("javascript/esm") - .tap("WorkerPlugin", parserPlugin); + .for(JAVASCRIPT_MODULE_TYPE_ESM) + .tap(PLUGIN_NAME, parserPlugin); } ); } diff --git a/lib/dependencies/getFunctionExpression.js b/lib/dependencies/getFunctionExpression.js index 14fd1396e60..f4495b500ff 100644 --- a/lib/dependencies/getFunctionExpression.js +++ b/lib/dependencies/getFunctionExpression.js @@ -5,6 +5,15 @@ "use strict"; +/** @typedef {import("estree").ArrowFunctionExpression} ArrowFunctionExpression */ +/** @typedef {import("estree").Expression} Expression */ +/** @typedef {import("estree").FunctionExpression} FunctionExpression */ +/** @typedef {import("estree").SpreadElement} SpreadElement */ + +/** + * @param {Expression | SpreadElement} expr expressions + * @returns {{fn: FunctionExpression | ArrowFunctionExpression, expressions: (Expression | SpreadElement)[], needThis: boolean | undefined } | undefined} function expression with additional information + */ module.exports = expr => { // if ( diff --git a/lib/dependencies/processExportInfo.js b/lib/dependencies/processExportInfo.js index 435c4ac986f..9bafcae635a 100644 --- a/lib/dependencies/processExportInfo.js +++ b/lib/dependencies/processExportInfo.js @@ -10,9 +10,11 @@ const { UsageState } = require("../ExportsInfo"); /** @typedef {import("../ExportsInfo").ExportInfo} ExportInfo */ /** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */ +/** @typedef {string[][]} ReferencedExports */ + /** * @param {RuntimeSpec} runtime the runtime - * @param {string[][]} referencedExports list of referenced exports, will be added to + * @param {ReferencedExports} referencedExports list of referenced exports, will be added to * @param {string[]} prefix export prefix * @param {ExportInfo=} exportInfo the export info * @param {boolean} defaultPointsToSelf when true, using default will reference itself diff --git a/lib/electron/ElectronTargetPlugin.js b/lib/electron/ElectronTargetPlugin.js index 256c4fb499e..e8c4e844a87 100644 --- a/lib/electron/ElectronTargetPlugin.js +++ b/lib/electron/ElectronTargetPlugin.js @@ -16,13 +16,14 @@ class ElectronTargetPlugin { constructor(context) { this._context = context; } + /** * Apply the plugin * @param {Compiler} compiler the compiler instance * @returns {void} */ apply(compiler) { - new ExternalsPlugin("commonjs", [ + new ExternalsPlugin("node-commonjs", [ "clipboard", "crash-reporter", "electron", @@ -34,7 +35,7 @@ class ElectronTargetPlugin { ]).apply(compiler); switch (this._context) { case "main": - new ExternalsPlugin("commonjs", [ + new ExternalsPlugin("node-commonjs", [ "app", "auto-updater", "browser-window", @@ -54,7 +55,7 @@ class ElectronTargetPlugin { break; case "preload": case "renderer": - new ExternalsPlugin("commonjs", [ + new ExternalsPlugin("node-commonjs", [ "desktop-capturer", "ipc-renderer", "remote", diff --git a/lib/errors/BuildCycleError.js b/lib/errors/BuildCycleError.js index 20203e5fcbf..a235fcebbe4 100644 --- a/lib/errors/BuildCycleError.js +++ b/lib/errors/BuildCycleError.js @@ -21,7 +21,6 @@ class BuildCycleError extends WebpackError { this.name = "BuildCycleError"; this.module = module; - Error.captureStackTrace(this, this.constructor); } } diff --git a/lib/esm/ExportWebpackRequireRuntimeModule.js b/lib/esm/ExportWebpackRequireRuntimeModule.js new file mode 100644 index 00000000000..30a275fa432 --- /dev/null +++ b/lib/esm/ExportWebpackRequireRuntimeModule.js @@ -0,0 +1,30 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php +*/ + +"use strict"; + +const RuntimeGlobals = require("../RuntimeGlobals"); +const RuntimeModule = require("../RuntimeModule"); + +class ExportWebpackRequireRuntimeModule extends RuntimeModule { + constructor() { + super("export webpack runtime", RuntimeModule.STAGE_ATTACH); + } + + /** + * @returns {boolean} true, if the runtime module should get it's own scope + */ + shouldIsolate() { + return false; + } + + /** + * @returns {string | null} runtime code + */ + generate() { + return `export default ${RuntimeGlobals.require};`; + } +} + +module.exports = ExportWebpackRequireRuntimeModule; diff --git a/lib/esm/ModuleChunkFormatPlugin.js b/lib/esm/ModuleChunkFormatPlugin.js new file mode 100644 index 00000000000..e6d11784600 --- /dev/null +++ b/lib/esm/ModuleChunkFormatPlugin.js @@ -0,0 +1,214 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ + +"use strict"; + +const { ConcatSource } = require("webpack-sources"); +const { RuntimeGlobals } = require(".."); +const HotUpdateChunk = require("../HotUpdateChunk"); +const Template = require("../Template"); +const { getAllChunks } = require("../javascript/ChunkHelpers"); +const { + chunkHasJs, + getCompilationHooks, + getChunkFilenameTemplate +} = require("../javascript/JavascriptModulesPlugin"); +const { updateHashForEntryStartup } = require("../javascript/StartupHelpers"); +const { getUndoPath } = require("../util/identifier"); + +/** @typedef {import("../Chunk")} Chunk */ +/** @typedef {import("../Compiler")} Compiler */ +/** @typedef {import("../Entrypoint")} Entrypoint */ + +class ModuleChunkFormatPlugin { + /** + * Apply the plugin + * @param {Compiler} compiler the compiler instance + * @returns {void} + */ + apply(compiler) { + compiler.hooks.thisCompilation.tap( + "ModuleChunkFormatPlugin", + compilation => { + compilation.hooks.additionalChunkRuntimeRequirements.tap( + "ModuleChunkFormatPlugin", + (chunk, set) => { + if (chunk.hasRuntime()) return; + if (compilation.chunkGraph.getNumberOfEntryModules(chunk) > 0) { + set.add(RuntimeGlobals.require); + set.add(RuntimeGlobals.startupEntrypoint); + set.add(RuntimeGlobals.externalInstallChunk); + } + } + ); + const hooks = getCompilationHooks(compilation); + hooks.renderChunk.tap( + "ModuleChunkFormatPlugin", + (modules, renderContext) => { + const { chunk, chunkGraph, runtimeTemplate } = renderContext; + const hotUpdateChunk = + chunk instanceof HotUpdateChunk ? chunk : null; + const source = new ConcatSource(); + if (hotUpdateChunk) { + throw new Error( + "HMR is not implemented for module chunk format yet" + ); + } else { + source.add(`export const id = ${JSON.stringify(chunk.id)};\n`); + source.add(`export const ids = ${JSON.stringify(chunk.ids)};\n`); + source.add("export const modules = "); + source.add(modules); + source.add(";\n"); + const runtimeModules = + chunkGraph.getChunkRuntimeModulesInOrder(chunk); + if (runtimeModules.length > 0) { + source.add("export const runtime =\n"); + source.add( + Template.renderChunkRuntimeModules( + runtimeModules, + renderContext + ) + ); + } + const entries = Array.from( + chunkGraph.getChunkEntryModulesWithChunkGroupIterable(chunk) + ); + if (entries.length > 0) { + const runtimeChunk = + /** @type {Entrypoint[][]} */ + (entries)[0][1].getRuntimeChunk(); + const currentOutputName = compilation + .getPath( + getChunkFilenameTemplate(chunk, compilation.outputOptions), + { + chunk, + contentHashType: "javascript" + } + ) + .replace(/^\/+/g, "") + .split("/"); + + /** + * @param {Chunk} chunk the chunk + * @returns {string} the relative path + */ + const getRelativePath = chunk => { + const baseOutputName = currentOutputName.slice(); + const chunkOutputName = compilation + .getPath( + getChunkFilenameTemplate( + chunk, + compilation.outputOptions + ), + { + chunk, + contentHashType: "javascript" + } + ) + .replace(/^\/+/g, "") + .split("/"); + + // remove common parts except filename + while ( + baseOutputName.length > 1 && + chunkOutputName.length > 1 && + baseOutputName[0] === chunkOutputName[0] + ) { + baseOutputName.shift(); + chunkOutputName.shift(); + } + const last = chunkOutputName.join("/"); + // create final path + return ( + getUndoPath(baseOutputName.join("/"), last, true) + last + ); + }; + + const entrySource = new ConcatSource(); + entrySource.add(source); + entrySource.add(";\n\n// load runtime\n"); + entrySource.add( + `import ${RuntimeGlobals.require} from ${JSON.stringify( + getRelativePath(/** @type {Chunk} */ (runtimeChunk)) + )};\n` + ); + + const startupSource = new ConcatSource(); + startupSource.add( + `var __webpack_exec__ = ${runtimeTemplate.returningFunction( + `${RuntimeGlobals.require}(${RuntimeGlobals.entryModuleId} = moduleId)`, + "moduleId" + )}\n` + ); + + const loadedChunks = new Set(); + let index = 0; + for (let i = 0; i < entries.length; i++) { + const [module, entrypoint] = entries[i]; + const final = i + 1 === entries.length; + const moduleId = chunkGraph.getModuleId(module); + const chunks = getAllChunks( + /** @type {Entrypoint} */ (entrypoint), + /** @type {Chunk} */ (runtimeChunk), + undefined + ); + for (const chunk of chunks) { + if ( + loadedChunks.has(chunk) || + !chunkHasJs(chunk, chunkGraph) + ) + continue; + loadedChunks.add(chunk); + startupSource.add( + `import * as __webpack_chunk_${index}__ from ${JSON.stringify( + getRelativePath(chunk) + )};\n` + ); + startupSource.add( + `${RuntimeGlobals.externalInstallChunk}(__webpack_chunk_${index}__);\n` + ); + index++; + } + startupSource.add( + `${ + final ? `var ${RuntimeGlobals.exports} = ` : "" + }__webpack_exec__(${JSON.stringify(moduleId)});\n` + ); + } + + entrySource.add( + hooks.renderStartup.call( + startupSource, + entries[entries.length - 1][0], + { + ...renderContext, + inlined: false + } + ) + ); + return entrySource; + } + } + return source; + } + ); + hooks.chunkHash.tap( + "ModuleChunkFormatPlugin", + (chunk, hash, { chunkGraph, runtimeTemplate }) => { + if (chunk.hasRuntime()) return; + hash.update("ModuleChunkFormatPlugin"); + hash.update("1"); + const entries = Array.from( + chunkGraph.getChunkEntryModulesWithChunkGroupIterable(chunk) + ); + updateHashForEntryStartup(hash, chunkGraph, entries, chunk); + } + ); + } + ); + } +} + +module.exports = ModuleChunkFormatPlugin; diff --git a/lib/esm/ModuleChunkLoadingPlugin.js b/lib/esm/ModuleChunkLoadingPlugin.js new file mode 100644 index 00000000000..b88533a8363 --- /dev/null +++ b/lib/esm/ModuleChunkLoadingPlugin.js @@ -0,0 +1,87 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ + +"use strict"; + +const RuntimeGlobals = require("../RuntimeGlobals"); +const ExportWebpackRequireRuntimeModule = require("./ExportWebpackRequireRuntimeModule"); +const ModuleChunkLoadingRuntimeModule = require("./ModuleChunkLoadingRuntimeModule"); + +/** @typedef {import("../Chunk")} Chunk */ +/** @typedef {import("../Compiler")} Compiler */ + +class ModuleChunkLoadingPlugin { + /** + * Apply the plugin + * @param {Compiler} compiler the compiler instance + * @returns {void} + */ + apply(compiler) { + compiler.hooks.thisCompilation.tap( + "ModuleChunkLoadingPlugin", + compilation => { + const globalChunkLoading = compilation.outputOptions.chunkLoading; + /** + * @param {Chunk} chunk chunk to check + * @returns {boolean} true, when the plugin is enabled for the chunk + */ + const isEnabledForChunk = chunk => { + const options = chunk.getEntryOptions(); + const chunkLoading = + options && options.chunkLoading !== undefined + ? options.chunkLoading + : globalChunkLoading; + return chunkLoading === "import"; + }; + const onceForChunkSet = new WeakSet(); + /** + * @param {Chunk} chunk chunk to check + * @param {Set} set runtime requirements + */ + const handler = (chunk, set) => { + if (onceForChunkSet.has(chunk)) return; + onceForChunkSet.add(chunk); + if (!isEnabledForChunk(chunk)) return; + set.add(RuntimeGlobals.moduleFactoriesAddOnly); + set.add(RuntimeGlobals.hasOwnProperty); + compilation.addRuntimeModule( + chunk, + new ModuleChunkLoadingRuntimeModule(set) + ); + }; + compilation.hooks.runtimeRequirementInTree + .for(RuntimeGlobals.ensureChunkHandlers) + .tap("ModuleChunkLoadingPlugin", handler); + compilation.hooks.runtimeRequirementInTree + .for(RuntimeGlobals.baseURI) + .tap("ModuleChunkLoadingPlugin", handler); + compilation.hooks.runtimeRequirementInTree + .for(RuntimeGlobals.externalInstallChunk) + .tap("ModuleChunkLoadingPlugin", handler); + compilation.hooks.runtimeRequirementInTree + .for(RuntimeGlobals.onChunksLoaded) + .tap("ModuleChunkLoadingPlugin", handler); + compilation.hooks.runtimeRequirementInTree + .for(RuntimeGlobals.externalInstallChunk) + .tap("ModuleChunkLoadingPlugin", (chunk, set) => { + if (!isEnabledForChunk(chunk)) return; + compilation.addRuntimeModule( + chunk, + new ExportWebpackRequireRuntimeModule() + ); + }); + + compilation.hooks.runtimeRequirementInTree + .for(RuntimeGlobals.ensureChunkHandlers) + .tap("ModuleChunkLoadingPlugin", (chunk, set) => { + if (!isEnabledForChunk(chunk)) return; + set.add(RuntimeGlobals.getChunkScriptFilename); + }); + } + ); + } +} + +module.exports = ModuleChunkLoadingPlugin; diff --git a/lib/esm/ModuleChunkLoadingRuntimeModule.js b/lib/esm/ModuleChunkLoadingRuntimeModule.js new file mode 100644 index 00000000000..829a3596591 --- /dev/null +++ b/lib/esm/ModuleChunkLoadingRuntimeModule.js @@ -0,0 +1,342 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php +*/ + +"use strict"; + +const { SyncWaterfallHook } = require("tapable"); +const Compilation = require("../Compilation"); +const RuntimeGlobals = require("../RuntimeGlobals"); +const RuntimeModule = require("../RuntimeModule"); +const Template = require("../Template"); +const { + getChunkFilenameTemplate, + chunkHasJs +} = require("../javascript/JavascriptModulesPlugin"); +const { getInitialChunkIds } = require("../javascript/StartupHelpers"); +const compileBooleanMatcher = require("../util/compileBooleanMatcher"); +const { getUndoPath } = require("../util/identifier"); + +/** @typedef {import("../../declarations/WebpackOptions").Environment} Environment */ +/** @typedef {import("../Chunk")} Chunk */ +/** @typedef {import("../ChunkGraph")} ChunkGraph */ +/** @typedef {import("../Module").ReadOnlyRuntimeRequirements} ReadOnlyRuntimeRequirements */ + +/** + * @typedef {object} JsonpCompilationPluginHooks + * @property {SyncWaterfallHook<[string, Chunk]>} linkPreload + * @property {SyncWaterfallHook<[string, Chunk]>} linkPrefetch + */ + +/** @type {WeakMap} */ +const compilationHooksMap = new WeakMap(); + +class ModuleChunkLoadingRuntimeModule extends RuntimeModule { + /** + * @param {Compilation} compilation the compilation + * @returns {JsonpCompilationPluginHooks} hooks + */ + static getCompilationHooks(compilation) { + if (!(compilation instanceof Compilation)) { + throw new TypeError( + "The 'compilation' argument must be an instance of Compilation" + ); + } + let hooks = compilationHooksMap.get(compilation); + if (hooks === undefined) { + hooks = { + linkPreload: new SyncWaterfallHook(["source", "chunk"]), + linkPrefetch: new SyncWaterfallHook(["source", "chunk"]) + }; + compilationHooksMap.set(compilation, hooks); + } + return hooks; + } + + /** + * @param {ReadOnlyRuntimeRequirements} runtimeRequirements runtime requirements + */ + constructor(runtimeRequirements) { + super("import chunk loading", RuntimeModule.STAGE_ATTACH); + this._runtimeRequirements = runtimeRequirements; + } + + /** + * @private + * @param {Chunk} chunk chunk + * @param {string} rootOutputDir root output directory + * @returns {string} generated code + */ + _generateBaseUri(chunk, rootOutputDir) { + const options = chunk.getEntryOptions(); + if (options && options.baseUri) { + return `${RuntimeGlobals.baseURI} = ${JSON.stringify(options.baseUri)};`; + } + const compilation = /** @type {Compilation} */ (this.compilation); + const { + outputOptions: { importMetaName } + } = compilation; + return `${RuntimeGlobals.baseURI} = new URL(${JSON.stringify( + rootOutputDir + )}, ${importMetaName}.url);`; + } + + /** + * @returns {string | null} runtime code + */ + generate() { + const compilation = /** @type {Compilation} */ (this.compilation); + const chunkGraph = /** @type {ChunkGraph} */ (this.chunkGraph); + const chunk = /** @type {Chunk} */ (this.chunk); + const environment = + /** @type {Environment} */ + (compilation.outputOptions.environment); + const { + runtimeTemplate, + outputOptions: { importFunctionName, crossOriginLoading } + } = compilation; + const fn = RuntimeGlobals.ensureChunkHandlers; + const withBaseURI = this._runtimeRequirements.has(RuntimeGlobals.baseURI); + const withExternalInstallChunk = this._runtimeRequirements.has( + RuntimeGlobals.externalInstallChunk + ); + const withLoading = this._runtimeRequirements.has( + RuntimeGlobals.ensureChunkHandlers + ); + const withOnChunkLoad = this._runtimeRequirements.has( + RuntimeGlobals.onChunksLoaded + ); + const withHmr = this._runtimeRequirements.has( + RuntimeGlobals.hmrDownloadUpdateHandlers + ); + const { linkPreload, linkPrefetch } = + ModuleChunkLoadingRuntimeModule.getCompilationHooks(compilation); + const withPrefetch = + environment.document && + this._runtimeRequirements.has(RuntimeGlobals.prefetchChunkHandlers); + const withPreload = + environment.document && + this._runtimeRequirements.has(RuntimeGlobals.preloadChunkHandlers); + const conditionMap = chunkGraph.getChunkConditionMap(chunk, chunkHasJs); + const hasJsMatcher = compileBooleanMatcher(conditionMap); + const initialChunkIds = getInitialChunkIds(chunk, chunkGraph, chunkHasJs); + + const outputName = compilation.getPath( + getChunkFilenameTemplate(chunk, compilation.outputOptions), + { + chunk, + contentHashType: "javascript" + } + ); + const rootOutputDir = getUndoPath( + outputName, + /** @type {string} */ (compilation.outputOptions.path), + true + ); + + const stateExpression = withHmr + ? `${RuntimeGlobals.hmrRuntimeStatePrefix}_module` + : undefined; + + return Template.asString([ + withBaseURI + ? this._generateBaseUri(chunk, rootOutputDir) + : "// no baseURI", + "", + "// object to store loaded and loading chunks", + "// undefined = chunk not loaded, null = chunk preloaded/prefetched", + "// [resolve, Promise] = chunk loading, 0 = chunk loaded", + `var installedChunks = ${ + stateExpression ? `${stateExpression} = ${stateExpression} || ` : "" + }{`, + Template.indent( + Array.from(initialChunkIds, id => `${JSON.stringify(id)}: 0`).join( + ",\n" + ) + ), + "};", + "", + withLoading || withExternalInstallChunk + ? `var installChunk = ${runtimeTemplate.basicFunction("data", [ + runtimeTemplate.destructureObject( + ["ids", "modules", "runtime"], + "data" + ), + '// add "modules" to the modules object,', + '// then flag all "ids" as loaded and fire callback', + "var moduleId, chunkId, i = 0;", + "for(moduleId in modules) {", + Template.indent([ + `if(${RuntimeGlobals.hasOwnProperty}(modules, moduleId)) {`, + Template.indent( + `${RuntimeGlobals.moduleFactories}[moduleId] = modules[moduleId];` + ), + "}" + ]), + "}", + `if(runtime) runtime(${RuntimeGlobals.require});`, + "for(;i < ids.length; i++) {", + Template.indent([ + "chunkId = ids[i];", + `if(${RuntimeGlobals.hasOwnProperty}(installedChunks, chunkId) && installedChunks[chunkId]) {`, + Template.indent("installedChunks[chunkId][0]();"), + "}", + "installedChunks[ids[i]] = 0;" + ]), + "}", + withOnChunkLoad ? `${RuntimeGlobals.onChunksLoaded}();` : "" + ])}` + : "// no install chunk", + "", + withLoading + ? Template.asString([ + `${fn}.j = ${runtimeTemplate.basicFunction( + "chunkId, promises", + hasJsMatcher !== false + ? Template.indent([ + "// import() chunk loading for javascript", + `var installedChunkData = ${RuntimeGlobals.hasOwnProperty}(installedChunks, chunkId) ? installedChunks[chunkId] : undefined;`, + 'if(installedChunkData !== 0) { // 0 means "already installed".', + Template.indent([ + "", + '// a Promise means "currently loading".', + "if(installedChunkData) {", + Template.indent([ + "promises.push(installedChunkData[1]);" + ]), + "} else {", + Template.indent([ + hasJsMatcher === true + ? "if(true) { // all chunks have JS" + : `if(${hasJsMatcher("chunkId")}) {`, + Template.indent([ + "// setup Promise in chunk cache", + `var promise = ${importFunctionName}(${JSON.stringify( + rootOutputDir + )} + ${ + RuntimeGlobals.getChunkScriptFilename + }(chunkId)).then(installChunk, ${runtimeTemplate.basicFunction( + "e", + [ + "if(installedChunks[chunkId] !== 0) installedChunks[chunkId] = undefined;", + "throw e;" + ] + )});`, + `var promise = Promise.race([promise, new Promise(${runtimeTemplate.expressionFunction( + "installedChunkData = installedChunks[chunkId] = [resolve]", + "resolve" + )})])`, + "promises.push(installedChunkData[1] = promise);" + ]), + hasJsMatcher === true + ? "}" + : "} else installedChunks[chunkId] = 0;" + ]), + "}" + ]), + "}" + ]) + : Template.indent(["installedChunks[chunkId] = 0;"]) + )};` + ]) + : "// no chunk on demand loading", + "", + withPrefetch && hasJsMatcher !== false + ? `${ + RuntimeGlobals.prefetchChunkHandlers + }.j = ${runtimeTemplate.basicFunction("chunkId", [ + `if((!${ + RuntimeGlobals.hasOwnProperty + }(installedChunks, chunkId) || installedChunks[chunkId] === undefined) && ${ + hasJsMatcher === true ? "true" : hasJsMatcher("chunkId") + }) {`, + Template.indent([ + "installedChunks[chunkId] = null;", + linkPrefetch.call( + Template.asString([ + "var link = document.createElement('link');", + crossOriginLoading + ? `link.crossOrigin = ${JSON.stringify( + crossOriginLoading + )};` + : "", + `if (${RuntimeGlobals.scriptNonce}) {`, + Template.indent( + `link.setAttribute("nonce", ${RuntimeGlobals.scriptNonce});` + ), + "}", + 'link.rel = "prefetch";', + 'link.as = "script";', + `link.href = ${RuntimeGlobals.publicPath} + ${RuntimeGlobals.getChunkScriptFilename}(chunkId);` + ]), + chunk + ), + "document.head.appendChild(link);" + ]), + "}" + ])};` + : "// no prefetching", + "", + withPreload && hasJsMatcher !== false + ? `${ + RuntimeGlobals.preloadChunkHandlers + }.j = ${runtimeTemplate.basicFunction("chunkId", [ + `if((!${ + RuntimeGlobals.hasOwnProperty + }(installedChunks, chunkId) || installedChunks[chunkId] === undefined) && ${ + hasJsMatcher === true ? "true" : hasJsMatcher("chunkId") + }) {`, + Template.indent([ + "installedChunks[chunkId] = null;", + linkPreload.call( + Template.asString([ + "var link = document.createElement('link');", + "link.charset = 'utf-8';", + `if (${RuntimeGlobals.scriptNonce}) {`, + Template.indent( + `link.setAttribute("nonce", ${RuntimeGlobals.scriptNonce});` + ), + "}", + 'link.rel = "modulepreload";', + `link.href = ${RuntimeGlobals.publicPath} + ${RuntimeGlobals.getChunkScriptFilename}(chunkId);`, + crossOriginLoading + ? crossOriginLoading === "use-credentials" + ? 'link.crossOrigin = "use-credentials";' + : Template.asString([ + "if (link.href.indexOf(window.location.origin + '/') !== 0) {", + Template.indent( + `link.crossOrigin = ${JSON.stringify( + crossOriginLoading + )};` + ), + "}" + ]) + : "" + ]), + chunk + ), + "document.head.appendChild(link);" + ]), + "}" + ])};` + : "// no preloaded", + "", + withExternalInstallChunk + ? Template.asString([ + `${RuntimeGlobals.externalInstallChunk} = installChunk;` + ]) + : "// no external install chunk", + "", + withOnChunkLoad + ? `${ + RuntimeGlobals.onChunksLoaded + }.j = ${runtimeTemplate.returningFunction( + "installedChunks[chunkId] === 0", + "chunkId" + )};` + : "// no on chunks loaded" + ]); + } +} + +module.exports = ModuleChunkLoadingRuntimeModule; diff --git a/lib/formatLocation.js b/lib/formatLocation.js index f42eea2ded2..780d4a475ca 100644 --- a/lib/formatLocation.js +++ b/lib/formatLocation.js @@ -48,9 +48,8 @@ const formatLocation = loc => { typeof loc.end.column !== "number" ) { return `${loc.start.line}-${loc.end.line}`; - } else { - return `${formatPosition(loc.start)}-${formatPosition(loc.end)}`; } + return `${formatPosition(loc.start)}-${formatPosition(loc.end)}`; } if ("start" in loc && loc.start) { return formatPosition(loc.start); diff --git a/lib/hmr/HotModuleReplacement.runtime.js b/lib/hmr/HotModuleReplacement.runtime.js index 1170c63aac4..0109b4929ed 100644 --- a/lib/hmr/HotModuleReplacement.runtime.js +++ b/lib/hmr/HotModuleReplacement.runtime.js @@ -9,6 +9,7 @@ var $interceptModuleExecution$ = undefined; var $moduleCache$ = undefined; // eslint-disable-next-line no-unused-vars var $hmrModuleData$ = undefined; +/** @type {() => Promise} */ var $hmrDownloadManifest$ = undefined; var $hmrDownloadUpdateHandlers$ = undefined; var $hmrInvalidateModuleHandlers$ = undefined; @@ -27,13 +28,13 @@ module.exports = function () { var currentStatus = "idle"; // while downloading - var blockingPromises; + var blockingPromises = 0; + var blockingPromisesWaiting = []; // The update info var currentUpdateApplyHandlers; var queuedInvalidatedModules; - // eslint-disable-next-line no-unused-vars $hmrModuleData$ = currentModuleData; $interceptModuleExecution$.push(function (options) { @@ -94,13 +95,14 @@ module.exports = function () { Object.defineProperty(fn, name, createPropertyDescriptor(name)); } } - fn.e = function (chunkId) { - return trackBlockingPromise(require.e(chunkId)); + fn.e = function (chunkId, fetchPriority) { + return trackBlockingPromise(require.e(chunkId, fetchPriority)); }; return fn; } function createModuleHotObject(moduleId, me) { + var _main = currentChildModule !== moduleId; var hot = { // private stuff _acceptedDependencies: {}, @@ -110,10 +112,10 @@ module.exports = function () { _selfDeclined: false, _selfInvalidated: false, _disposeHandlers: [], - _main: currentChildModule !== moduleId, + _main: _main, _requireSelf: function () { currentParents = me.parents.slice(); - currentChildModule = moduleId; + currentChildModule = _main ? undefined : moduleId; __webpack_require__(moduleId); }, @@ -199,7 +201,7 @@ module.exports = function () { if (idx >= 0) registeredStatusHandlers.splice(idx, 1); }, - //inherit from previous dispose call + // inherit from previous dispose call data: currentModuleData[moduleId] }; currentChildModule = undefined; @@ -208,21 +210,36 @@ module.exports = function () { function setStatus(newStatus) { currentStatus = newStatus; + var results = []; + for (var i = 0; i < registeredStatusHandlers.length; i++) - registeredStatusHandlers[i].call(null, newStatus); + results[i] = registeredStatusHandlers[i].call(null, newStatus); + + return Promise.all(results).then(function () {}); + } + + function unblock() { + if (--blockingPromises === 0) { + setStatus("ready").then(function () { + if (blockingPromises === 0) { + var list = blockingPromisesWaiting; + blockingPromisesWaiting = []; + for (var i = 0; i < list.length; i++) { + list[i](); + } + } + }); + } } function trackBlockingPromise(promise) { switch (currentStatus) { case "ready": setStatus("prepare"); - blockingPromises.push(promise); - waitForBlockingPromises(function () { - setStatus("ready"); - }); - return promise; + /* fallthrough */ case "prepare": - blockingPromises.push(promise); + blockingPromises++; + promise.then(unblock, unblock); return promise; default: return promise; @@ -230,11 +247,11 @@ module.exports = function () { } function waitForBlockingPromises(fn) { - if (blockingPromises.length === 0) return fn(); - var blocker = blockingPromises; - blockingPromises = []; - return Promise.all(blocker).then(function () { - return waitForBlockingPromises(fn); + if (blockingPromises === 0) return fn(); + return new Promise(function (resolve) { + blockingPromisesWaiting.push(function () { + resolve(fn()); + }); }); } @@ -242,53 +259,58 @@ module.exports = function () { if (currentStatus !== "idle") { throw new Error("check() is only allowed in idle status"); } - setStatus("check"); - return $hmrDownloadManifest$().then(function (update) { - if (!update) { - setStatus(applyInvalidatedModules() ? "ready" : "idle"); - return null; - } - - setStatus("prepare"); - - var updatedModules = []; - blockingPromises = []; - currentUpdateApplyHandlers = []; - - return Promise.all( - Object.keys($hmrDownloadUpdateHandlers$).reduce(function ( - promises, - key - ) { - $hmrDownloadUpdateHandlers$[key]( - update.c, - update.r, - update.m, - promises, - currentUpdateApplyHandlers, - updatedModules + return setStatus("check") + .then($hmrDownloadManifest$) + .then(function (update) { + if (!update) { + return setStatus(applyInvalidatedModules() ? "ready" : "idle").then( + function () { + return null; + } ); - return promises; - }, - []) - ).then(function () { - return waitForBlockingPromises(function () { - if (applyOnUpdate) { - return internalApply(applyOnUpdate); - } else { - setStatus("ready"); + } - return updatedModules; - } + return setStatus("prepare").then(function () { + var updatedModules = []; + currentUpdateApplyHandlers = []; + + return Promise.all( + Object.keys($hmrDownloadUpdateHandlers$).reduce(function ( + promises, + key + ) { + $hmrDownloadUpdateHandlers$[key]( + update.c, + update.r, + update.m, + promises, + currentUpdateApplyHandlers, + updatedModules + ); + return promises; + }, []) + ).then(function () { + return waitForBlockingPromises(function () { + if (applyOnUpdate) { + return internalApply(applyOnUpdate); + } + return setStatus("ready").then(function () { + return updatedModules; + }); + }); + }); }); }); - }); } function hotApply(options) { if (currentStatus !== "ready") { return Promise.resolve().then(function () { - throw new Error("apply() is only allowed in ready status"); + throw new Error( + "apply() is only allowed in ready status (state: " + + currentStatus + + ")" + ); }); } return internalApply(options); @@ -311,21 +333,20 @@ module.exports = function () { .filter(Boolean); if (errors.length > 0) { - setStatus("abort"); - return Promise.resolve().then(function () { + return setStatus("abort").then(function () { throw errors[0]; }); } // Now in "dispose" phase - setStatus("dispose"); + var disposePromise = setStatus("dispose"); results.forEach(function (result) { if (result.dispose) result.dispose(); }); // Now in "apply" phase - setStatus("apply"); + var applyPromise = setStatus("apply"); var error; var reportError = function (err) { @@ -344,25 +365,27 @@ module.exports = function () { } }); - // handle errors in accept handlers and self accepted module load - if (error) { - setStatus("fail"); - return Promise.resolve().then(function () { - throw error; - }); - } + return Promise.all([disposePromise, applyPromise]).then(function () { + // handle errors in accept handlers and self accepted module load + if (error) { + return setStatus("fail").then(function () { + throw error; + }); + } - if (queuedInvalidatedModules) { - return internalApply(options).then(function (list) { - outdatedModules.forEach(function (moduleId) { - if (list.indexOf(moduleId) < 0) list.push(moduleId); + if (queuedInvalidatedModules) { + return internalApply(options).then(function (list) { + outdatedModules.forEach(function (moduleId) { + if (list.indexOf(moduleId) < 0) list.push(moduleId); + }); + return list; }); - return list; - }); - } + } - setStatus("idle"); - return Promise.resolve(outdatedModules); + return setStatus("idle").then(function () { + return outdatedModules; + }); + }); } function applyInvalidatedModules() { diff --git a/lib/hmr/HotModuleReplacementRuntimeModule.js b/lib/hmr/HotModuleReplacementRuntimeModule.js index a92a97e9ea9..19d4984c5fa 100644 --- a/lib/hmr/HotModuleReplacementRuntimeModule.js +++ b/lib/hmr/HotModuleReplacementRuntimeModule.js @@ -13,8 +13,9 @@ class HotModuleReplacementRuntimeModule extends RuntimeModule { constructor() { super("hot module replacement", RuntimeModule.STAGE_BASIC); } + /** - * @returns {string} runtime code + * @returns {string | null} runtime code */ generate() { return Template.getFunctionContent( diff --git a/lib/hmr/JavascriptHotModuleReplacement.runtime.js b/lib/hmr/JavascriptHotModuleReplacement.runtime.js index 2006f153784..aab249abc71 100644 --- a/lib/hmr/JavascriptHotModuleReplacement.runtime.js +++ b/lib/hmr/JavascriptHotModuleReplacement.runtime.js @@ -117,15 +117,12 @@ module.exports = function () { if ($hasOwnProperty$(currentUpdate, moduleId)) { var newModuleFactory = currentUpdate[moduleId]; /** @type {TODO} */ - var result; - if (newModuleFactory) { - result = getAffectedModuleEffects(moduleId); - } else { - result = { - type: "disposed", - moduleId: moduleId - }; - } + var result = newModuleFactory + ? getAffectedModuleEffects(moduleId) + : { + type: "disposed", + moduleId: moduleId + }; /** @type {Error|false} */ var abortError = false; var doApply = false; @@ -207,7 +204,7 @@ module.exports = function () { var module = $moduleCache$[outdatedModuleId]; if ( module && - module.hot._selfAccepted && + (module.hot._selfAccepted || module.hot._main) && // removed self-accepted modules should not be required appliedUpdate[outdatedModuleId] !== warnUnexpectedRequire && // when called invalidate self-accepting is not possible @@ -376,17 +373,17 @@ module.exports = function () { moduleId: moduleId, module: $moduleCache$[moduleId] }); - } catch (err2) { + } catch (err1) { if (options.onErrored) { options.onErrored({ type: "self-accept-error-handler-errored", moduleId: moduleId, - error: err2, + error: err1, originalError: err }); } if (!options.ignoreErrored) { - reportError(err2); + reportError(err1); reportError(err); } } @@ -443,15 +440,16 @@ module.exports = function () { ) { promises.push($loadUpdateChunk$(chunkId, updatedModulesList)); currentUpdateChunks[chunkId] = true; + } else { + currentUpdateChunks[chunkId] = false; } }); if ($ensureChunkHandlers$) { $ensureChunkHandlers$.$key$Hmr = function (chunkId, promises) { if ( currentUpdateChunks && - !$hasOwnProperty$(currentUpdateChunks, chunkId) && - $hasOwnProperty$($installedChunks$, chunkId) && - $installedChunks$[chunkId] !== undefined + $hasOwnProperty$(currentUpdateChunks, chunkId) && + !currentUpdateChunks[chunkId] ) { promises.push($loadUpdateChunk$(chunkId)); currentUpdateChunks[chunkId] = true; diff --git a/lib/hmr/LazyCompilationPlugin.js b/lib/hmr/LazyCompilationPlugin.js index 6853e2d128d..4b2d5c29990 100644 --- a/lib/hmr/LazyCompilationPlugin.js +++ b/lib/hmr/LazyCompilationPlugin.js @@ -10,6 +10,9 @@ const AsyncDependenciesBlock = require("../AsyncDependenciesBlock"); const Dependency = require("../Dependency"); const Module = require("../Module"); const ModuleFactory = require("../ModuleFactory"); +const { + WEBPACK_MODULE_TYPE_LAZY_COMPILATION_PROXY +} = require("../ModuleTypeConstants"); const RuntimeGlobals = require("../RuntimeGlobals"); const Template = require("../Template"); const CommonJsRequireDependency = require("../dependencies/CommonJsRequireDependency"); @@ -24,15 +27,25 @@ const { registerNotSerializable } = require("../util/serialization"); /** @typedef {import("../Module").CodeGenerationResult} CodeGenerationResult */ /** @typedef {import("../Module").LibIdentOptions} LibIdentOptions */ /** @typedef {import("../Module").NeedBuildContext} NeedBuildContext */ +/** @typedef {import("../Module").SourceTypes} SourceTypes */ /** @typedef {import("../ModuleFactory").ModuleFactoryCreateData} ModuleFactoryCreateData */ /** @typedef {import("../ModuleFactory").ModuleFactoryResult} ModuleFactoryResult */ /** @typedef {import("../RequestShortener")} RequestShortener */ /** @typedef {import("../ResolverFactory").ResolverWithOptions} ResolverWithOptions */ /** @typedef {import("../WebpackError")} WebpackError */ +/** @typedef {import("../dependencies/HarmonyImportDependency")} HarmonyImportDependency */ /** @typedef {import("../util/Hash")} Hash */ /** @typedef {import("../util/fs").InputFileSystem} InputFileSystem */ -const IGNORED_DEPENDENCY_TYPES = new Set([ +/** @typedef {{ client: string, data: string, active: boolean }} ModuleResult */ + +/** + * @typedef {object} BackendApi + * @property {function(function((Error | null)=) : void): void} dispose + * @property {function(Module): ModuleResult} module + */ + +const HMR_DEPENDENCY_TYPES = new Set([ "import.meta.webpackHot.accept", "import.meta.webpackHot.decline", "module.hot.accept", @@ -42,7 +55,7 @@ const IGNORED_DEPENDENCY_TYPES = new Set([ /** * @param {undefined|string|RegExp|Function} test test option * @param {Module} module the module - * @returns {boolean} true, if the module should be selected + * @returns {boolean | null | string} true, if the module should be selected */ const checkTest = (test, module) => { if (test === undefined) return true; @@ -63,6 +76,9 @@ const checkTest = (test, module) => { const TYPES = new Set(["javascript"]); class LazyCompilationDependency extends Dependency { + /** + * @param {LazyCompilationProxyModule} proxyModule proxy module + */ constructor(proxyModule) { super(); this.proxyModule = proxyModule; @@ -87,8 +103,20 @@ class LazyCompilationDependency extends Dependency { registerNotSerializable(LazyCompilationDependency); class LazyCompilationProxyModule extends Module { + /** + * @param {string} context context + * @param {Module} originalModule an original module + * @param {string} request request + * @param {ModuleResult["client"]} client client + * @param {ModuleResult["data"]} data data + * @param {ModuleResult["active"]} active true when active, otherwise false + */ constructor(context, originalModule, request, client, data, active) { - super("lazy-compilation-proxy", context, originalModule.layer); + super( + WEBPACK_MODULE_TYPE_LAZY_COMPILATION_PROXY, + context, + originalModule.layer + ); this.originalModule = originalModule; this.request = request; this.client = client; @@ -100,7 +128,7 @@ class LazyCompilationProxyModule extends Module { * @returns {string} a unique identifier of the module */ identifier() { - return `lazy-compilation-proxy|${this.originalModule.identifier()}`; + return `${WEBPACK_MODULE_TYPE_LAZY_COMPILATION_PROXY}|${this.originalModule.identifier()}`; } /** @@ -108,7 +136,7 @@ class LazyCompilationProxyModule extends Module { * @returns {string} a user readable identifier of the module */ readableIdentifier(requestShortener) { - return `lazy-compilation-proxy ${this.originalModule.readableIdentifier( + return `${WEBPACK_MODULE_TYPE_LAZY_COMPILATION_PROXY} ${this.originalModule.readableIdentifier( requestShortener )}`; } @@ -135,12 +163,14 @@ class LazyCompilationProxyModule extends Module { * @returns {string | null} an identifier for library inclusion */ libIdent(options) { - return `${this.originalModule.libIdent(options)}!lazy-compilation-proxy`; + return `${this.originalModule.libIdent( + options + )}!${WEBPACK_MODULE_TYPE_LAZY_COMPILATION_PROXY}`; } /** * @param {NeedBuildContext} context context info - * @param {function(WebpackError=, boolean=): void} callback callback function, returns true, if the module needs a rebuild + * @param {function((WebpackError | null)=, boolean=): void} callback callback function, returns true, if the module needs a rebuild * @returns {void} */ needBuild(context, callback) { @@ -174,7 +204,7 @@ class LazyCompilationProxyModule extends Module { } /** - * @returns {Set} types available (do not mutate) + * @returns {SourceTypes} types available (do not mutate) */ getSourceTypes() { return TYPES; @@ -196,8 +226,9 @@ class LazyCompilationProxyModule extends Module { const sources = new Map(); const runtimeRequirements = new Set(); runtimeRequirements.add(RuntimeGlobals.module); - const clientDep = /** @type {CommonJsRequireDependency} */ (this - .dependencies[0]); + const clientDep = /** @type {CommonJsRequireDependency} */ ( + this.dependencies[0] + ); const clientModule = moduleGraph.getModule(clientDep); const block = this.blocks[0]; const client = Template.asString([ @@ -211,13 +242,13 @@ class LazyCompilationProxyModule extends Module { ]); const keepActive = Template.asString([ `var dispose = client.keepAlive({ data: data, active: ${JSON.stringify( - !!block + Boolean(block) )}, module: module, onError: onError });` ]); let source; if (block) { const dep = block.dependencies[0]; - const module = moduleGraph.getModule(dep); + const module = /** @type {Module} */ (moduleGraph.getModule(dep)); source = Template.asString([ client, `module.exports = ${runtimeTemplate.moduleNamespacePromise({ @@ -246,7 +277,7 @@ class LazyCompilationProxyModule extends Module { source = Template.asString([ client, "var resolveSelf, onError;", - `module.exports = new Promise(function(resolve, reject) { resolveSelf = resolve; onError = reject; });`, + "module.exports = new Promise(function(resolve, reject) { resolveSelf = resolve; onError = reject; });", "if (module.hot) {", Template.indent([ "module.hot.accept();", @@ -279,19 +310,19 @@ class LazyCompilationProxyModule extends Module { registerNotSerializable(LazyCompilationProxyModule); class LazyCompilationDependencyFactory extends ModuleFactory { - constructor(factory) { + constructor() { super(); - this._factory = factory; } /** * @param {ModuleFactoryCreateData} data data object - * @param {function(Error=, ModuleFactoryResult=): void} callback callback + * @param {function((Error | null)=, ModuleFactoryResult=): void} callback callback * @returns {void} */ create(data, callback) { - const dependency = /** @type {LazyCompilationDependency} */ (data - .dependencies[0]); + const dependency = /** @type {LazyCompilationDependency} */ ( + data.dependencies[0] + ); callback(null, { module: dependency.proxyModule.originalModule }); @@ -300,34 +331,34 @@ class LazyCompilationDependencyFactory extends ModuleFactory { class LazyCompilationPlugin { /** - * @param {Object} options options - * @param {(function(Compiler, string, function(Error?, any?): void): void) | function(Compiler, string): Promise} options.backend the backend - * @param {string} options.client the client reference + * @param {object} options options + * @param {(function(Compiler, function(Error=, BackendApi?): void): void) | function(Compiler): Promise} options.backend the backend * @param {boolean} options.entries true, when entries are lazy compiled * @param {boolean} options.imports true, when import() modules are lazy compiled - * @param {RegExp | string | (function(Module): boolean)} options.test additional filter for lazy compiled entrypoint modules + * @param {RegExp | string | (function(Module): boolean) | undefined} options.test additional filter for lazy compiled entrypoint modules */ - constructor({ backend, client, entries, imports, test }) { + constructor({ backend, entries, imports, test }) { this.backend = backend; - this.client = client; this.entries = entries; this.imports = imports; this.test = test; } + /** * Apply the plugin * @param {Compiler} compiler the compiler instance * @returns {void} */ apply(compiler) { + /** @type {BackendApi} */ let backend; compiler.hooks.beforeCompile.tapAsync( "LazyCompilationPlugin", (params, callback) => { if (backend !== undefined) return callback(); - const promise = this.backend(compiler, this.client, (err, result) => { + const promise = this.backend(compiler, (err, result) => { if (err) return callback(err); - backend = result; + backend = /** @type {BackendApi} */ (result); callback(); }); if (promise && promise.then) { @@ -345,30 +376,56 @@ class LazyCompilationPlugin { "LazyCompilationPlugin", (originalModule, createData, resolveData) => { if ( - resolveData.dependencies.every( + resolveData.dependencies.every(dep => + HMR_DEPENDENCY_TYPES.has(dep.type) + ) + ) { + // for HMR only resolving, try to determine if the HMR accept/decline refers to + // an import() or not + const hmrDep = resolveData.dependencies[0]; + const originModule = + /** @type {Module} */ + (compilation.moduleGraph.getParentModule(hmrDep)); + const isReferringToDynamicImport = originModule.blocks.some( + block => + block.dependencies.some( + dep => + dep.type === "import()" && + /** @type {HarmonyImportDependency} */ (dep).request === + hmrDep.request + ) + ); + if (!isReferringToDynamicImport) return; + } else if ( + !resolveData.dependencies.every( dep => - IGNORED_DEPENDENCY_TYPES.has(dep.type) || - (this.imports && dep.type === "import()") || + HMR_DEPENDENCY_TYPES.has(dep.type) || + (this.imports && + (dep.type === "import()" || + dep.type === "import() context element")) || (this.entries && dep.type === "entry") - ) && - !/webpack[/\\]hot[/\\]|webpack-dev-server[/\\]client/.test( + ) + ) + return; + if ( + /webpack[/\\]hot[/\\]|webpack-dev-server[/\\]client|webpack-hot-middleware[/\\]client/.test( resolveData.request - ) && - checkTest(this.test, originalModule) - ) { - const moduleInfo = backend.module(originalModule); - if (!moduleInfo) return; - const { client, data, active } = moduleInfo; + ) || + !checkTest(this.test, originalModule) + ) + return; + const moduleInfo = backend.module(originalModule); + if (!moduleInfo) return; + const { client, data, active } = moduleInfo; - return new LazyCompilationProxyModule( - compiler.context, - originalModule, - resolveData.request, - client, - data, - active - ); - } + return new LazyCompilationProxyModule( + compiler.context, + originalModule, + resolveData.request, + client, + data, + active + ); } ); compilation.dependencyFactories.set( diff --git a/lib/hmr/lazyCompilationBackend.js b/lib/hmr/lazyCompilationBackend.js index 990edd83d6b..9e21e6c6e42 100644 --- a/lib/hmr/lazyCompilationBackend.js +++ b/lib/hmr/lazyCompilationBackend.js @@ -5,22 +5,66 @@ "use strict"; -const http = require("http"); - +/** @typedef {import("http").IncomingMessage} IncomingMessage */ +/** @typedef {import("http").RequestListener} RequestListener */ +/** @typedef {import("http").ServerOptions} HttpServerOptions */ +/** @typedef {import("http").ServerResponse} ServerResponse */ +/** @typedef {import("https").ServerOptions} HttpsServerOptions */ +/** @typedef {import("net").AddressInfo} AddressInfo */ +/** @typedef {import("net").Server} Server */ +/** @typedef {import("../../declarations/WebpackOptions").LazyCompilationDefaultBackendOptions} LazyCompilationDefaultBackendOptions */ /** @typedef {import("../Compiler")} Compiler */ +/** @typedef {import("../Module")} Module */ +/** @typedef {import("./LazyCompilationPlugin").BackendApi} BackendApi */ /** + * @callback BackendHandler * @param {Compiler} compiler compiler - * @param {string} client client reference - * @param {function(Error?, any?): void} callback callback + * @param {function(Error | null, BackendApi=): void} callback callback * @returns {void} */ -module.exports = (compiler, client, callback) => { + +/** + * @param {Omit & { client: NonNullable}} options additional options for the backend + * @returns {BackendHandler} backend + */ +module.exports = options => (compiler, callback) => { const logger = compiler.getInfrastructureLogger("LazyCompilationBackend"); const activeModules = new Map(); const prefix = "/lazy-compilation-using-"; - const server = http.createServer((req, res) => { + const isHttps = + options.protocol === "https" || + (typeof options.server === "object" && + ("key" in options.server || "pfx" in options.server)); + + const createServer = + typeof options.server === "function" + ? options.server + : (() => { + const http = isHttps ? require("https") : require("http"); + return http.createServer.bind( + http, + /** @type {HttpServerOptions | HttpsServerOptions} */ + (options.server) + ); + })(); + /** @type {function(Server): void} */ + const listen = + typeof options.listen === "function" + ? options.listen + : server => { + let listen = options.listen; + if (typeof listen === "object" && !("port" in listen)) + listen = { ...listen, port: undefined }; + server.listen(listen); + }; + + const protocol = options.protocol || (isHttps ? "https" : "http"); + + /** @type {RequestListener} */ + const requestListener = (req, res) => { + if (req.url === undefined) return; const keys = req.url.slice(prefix.length).split("@"); req.socket.on("close", () => { setTimeout(() => { @@ -38,7 +82,9 @@ module.exports = (compiler, client, callback) => { req.socket.setNoDelay(true); res.writeHead(200, { "content-type": "text/event-stream", - "Access-Control-Allow-Origin": "*" + "Access-Control-Allow-Origin": "*", + "Access-Control-Allow-Methods": "*", + "Access-Control-Allow-Headers": "*" }); res.write("\n"); let moduleActivated = false; @@ -51,35 +97,71 @@ module.exports = (compiler, client, callback) => { } } if (moduleActivated && compiler.watching) compiler.watching.invalidate(); - }); - server.listen(err => { - if (err) return callback(err); - const addr = server.address(); - if (typeof addr === "string") throw new Error("addr must not be a string"); - const urlBase = - addr.address === "::" || addr.address === "0.0.0.0" - ? `http://localhost:${addr.port}` - : addr.family === "IPv6" - ? `http://[${addr.address}]:${addr.port}` - : `http://${addr.address}:${addr.port}`; - logger.log( - `Server-Sent-Events server for lazy compilation open at ${urlBase}.` - ); - callback(null, { - dispose(callback) { - server.close(callback); - }, - module(originalModule) { - const key = `${encodeURIComponent( - originalModule.identifier().replace(/\\/g, "/").replace(/@/g, "_") - ).replace(/%(2F|3A|24|26|2B|2C|3B|3D|3A)/g, decodeURIComponent)}`; - const active = activeModules.get(key) > 0; - return { - client: `${client}?${encodeURIComponent(urlBase + prefix)}`, - data: key, - active - }; - } + }; + + const server = /** @type {Server} */ (createServer()); + server.on("request", requestListener); + + let isClosing = false; + /** @type {Set} */ + const sockets = new Set(); + server.on("connection", socket => { + sockets.add(socket); + socket.on("close", () => { + sockets.delete(socket); }); + if (isClosing) socket.destroy(); + }); + server.on("clientError", e => { + if (e.message !== "Server is disposing") logger.warn(e); }); + + server.on( + "listening", + /** + * @param {Error} err error + * @returns {void} + */ + err => { + if (err) return callback(err); + const _addr = server.address(); + if (typeof _addr === "string") + throw new Error("addr must not be a string"); + const addr = /** @type {AddressInfo} */ (_addr); + const urlBase = + addr.address === "::" || addr.address === "0.0.0.0" + ? `${protocol}://localhost:${addr.port}` + : addr.family === "IPv6" + ? `${protocol}://[${addr.address}]:${addr.port}` + : `${protocol}://${addr.address}:${addr.port}`; + logger.log( + `Server-Sent-Events server for lazy compilation open at ${urlBase}.` + ); + callback(null, { + dispose(callback) { + isClosing = true; + // Removing the listener is a workaround for a memory leak in node.js + server.off("request", requestListener); + server.close(err => { + callback(err); + }); + for (const socket of sockets) { + socket.destroy(new Error("Server is disposing")); + } + }, + module(originalModule) { + const key = `${encodeURIComponent( + originalModule.identifier().replace(/\\/g, "/").replace(/@/g, "_") + ).replace(/%(2F|3A|24|26|2B|2C|3B|3D)/g, decodeURIComponent)}`; + const active = activeModules.get(key) > 0; + return { + client: `${options.client}?${encodeURIComponent(urlBase + prefix)}`, + data: key, + active + }; + } + }); + } + ); + listen(server); }; diff --git a/lib/ids/ChunkModuleIdRangePlugin.js b/lib/ids/ChunkModuleIdRangePlugin.js index 4040edc55cc..e0922b43be8 100644 --- a/lib/ids/ChunkModuleIdRangePlugin.js +++ b/lib/ids/ChunkModuleIdRangePlugin.js @@ -13,7 +13,18 @@ const { /** @typedef {import("../Compiler")} Compiler */ +/** + * @typedef {object} ChunkModuleIdRangePluginOptions + * @property {string} name the chunk name + * @property {("index" | "index2" | "preOrderIndex" | "postOrderIndex")=} order order + * @property {number=} start start id + * @property {number=} end end id + */ + class ChunkModuleIdRangePlugin { + /** + * @param {ChunkModuleIdRangePluginOptions} options options object + */ constructor(options) { this.options = options; } @@ -59,9 +70,7 @@ class ChunkModuleIdRangePlugin { chunkModules = chunkGraph.getOrderedChunkModules(chunk, cmpFn); } else { chunkModules = Array.from(modules) - .filter(m => { - return chunkGraph.isModuleInChunk(m, chunk); - }) + .filter(m => chunkGraph.isModuleInChunk(m, chunk)) .sort(compareModulesByPreOrderIndexOrIdentifier(moduleGraph)); } diff --git a/lib/ids/DeterministicChunkIdsPlugin.js b/lib/ids/DeterministicChunkIdsPlugin.js index d0788fff401..735bc5f166a 100644 --- a/lib/ids/DeterministicChunkIdsPlugin.js +++ b/lib/ids/DeterministicChunkIdsPlugin.js @@ -15,9 +15,18 @@ const { /** @typedef {import("../Compiler")} Compiler */ /** @typedef {import("../Module")} Module */ +/** + * @typedef {object} DeterministicChunkIdsPluginOptions + * @property {string=} context context for ids + * @property {number=} maxLength maximum length of ids + */ + class DeterministicChunkIdsPlugin { - constructor(options) { - this.options = options || {}; + /** + * @param {DeterministicChunkIdsPluginOptions} [options] options + */ + constructor(options = {}) { + this.options = options; } /** @@ -42,9 +51,7 @@ class DeterministicChunkIdsPlugin { const usedIds = getUsedChunkIds(compilation); assignDeterministicIds( - Array.from(chunks).filter(chunk => { - return chunk.id === null; - }), + Array.from(chunks).filter(chunk => chunk.id === null), chunk => getFullChunkName(chunk, chunkGraph, context, compiler.root), compareNatural, @@ -56,7 +63,7 @@ class DeterministicChunkIdsPlugin { chunk.ids = [id]; return true; }, - [Math.pow(10, maxLength)], + [10 ** maxLength], 10, usedIds.size ); diff --git a/lib/ids/DeterministicModuleIdsPlugin.js b/lib/ids/DeterministicModuleIdsPlugin.js index 6fff9421000..8cf07e082c3 100644 --- a/lib/ids/DeterministicModuleIdsPlugin.js +++ b/lib/ids/DeterministicModuleIdsPlugin.js @@ -9,7 +9,7 @@ const { compareModulesByPreOrderIndexOrIdentifier } = require("../util/comparators"); const { - getUsedModuleIds, + getUsedModuleIdsAndModules, getFullModuleName, assignDeterministicIds } = require("./IdHelpers"); @@ -17,9 +17,22 @@ const { /** @typedef {import("../Compiler")} Compiler */ /** @typedef {import("../Module")} Module */ +/** + * @typedef {object} DeterministicModuleIdsPluginOptions + * @property {string=} context context relative to which module identifiers are computed + * @property {function(Module): boolean=} test selector function for modules + * @property {number=} maxLength maximum id length in digits (used as starting point) + * @property {number=} salt hash salt for ids + * @property {boolean=} fixedLength do not increase the maxLength to find an optimal id space size + * @property {boolean=} failOnConflict throw an error when id conflicts occur (instead of rehashing) + */ + class DeterministicModuleIdsPlugin { - constructor(options) { - this.options = options || {}; + /** + * @param {DeterministicModuleIdsPluginOptions} [options] options + */ + constructor(options = {}) { + this.options = options; } /** @@ -31,40 +44,51 @@ class DeterministicModuleIdsPlugin { compiler.hooks.compilation.tap( "DeterministicModuleIdsPlugin", compilation => { - compilation.hooks.moduleIds.tap( - "DeterministicModuleIdsPlugin", - modules => { - const chunkGraph = compilation.chunkGraph; - const context = this.options.context - ? this.options.context - : compiler.context; - const maxLength = this.options.maxLength || 3; + compilation.hooks.moduleIds.tap("DeterministicModuleIdsPlugin", () => { + const chunkGraph = compilation.chunkGraph; + const context = this.options.context + ? this.options.context + : compiler.context; + const maxLength = this.options.maxLength || 3; + const failOnConflict = this.options.failOnConflict || false; + const fixedLength = this.options.fixedLength || false; + const salt = this.options.salt || 0; + let conflicts = 0; - const usedIds = getUsedModuleIds(compilation); - assignDeterministicIds( - Array.from(modules).filter(module => { - if (!module.needId) return false; - if (chunkGraph.getNumberOfModuleChunks(module) === 0) - return false; - return chunkGraph.getModuleId(module) === null; - }), - module => getFullModuleName(module, context, compiler.root), - compareModulesByPreOrderIndexOrIdentifier( - compilation.moduleGraph - ), - (module, id) => { - const size = usedIds.size; - usedIds.add(`${id}`); - if (size === usedIds.size) return false; - chunkGraph.setModuleId(module, id); - return true; - }, - [Math.pow(10, maxLength)], - 10, - usedIds.size + const [usedIds, modules] = getUsedModuleIdsAndModules( + compilation, + this.options.test + ); + assignDeterministicIds( + modules, + module => getFullModuleName(module, context, compiler.root), + failOnConflict + ? () => 0 + : compareModulesByPreOrderIndexOrIdentifier( + compilation.moduleGraph + ), + (module, id) => { + const size = usedIds.size; + usedIds.add(`${id}`); + if (size === usedIds.size) { + conflicts++; + return false; + } + chunkGraph.setModuleId(module, id); + return true; + }, + [10 ** maxLength], + fixedLength ? 0 : 10, + usedIds.size, + salt + ); + if (failOnConflict && conflicts) + throw new Error( + `Assigning deterministic module ids has lead to ${conflicts} conflict${ + conflicts > 1 ? "s" : "" + }.\nIncrease the 'maxLength' to increase the id space and make conflicts less likely (recommended when there are many conflicts or application is expected to grow), or add an 'salt' number to try another hash starting value in the same id space (recommended when there is only a single conflict).` ); - } - ); + }); } ); } diff --git a/lib/ids/HashedModuleIdsPlugin.js b/lib/ids/HashedModuleIdsPlugin.js index 896af939a2e..e3891a4699e 100644 --- a/lib/ids/HashedModuleIdsPlugin.js +++ b/lib/ids/HashedModuleIdsPlugin.js @@ -5,29 +5,38 @@ "use strict"; -const { validate } = require("schema-utils"); -const schema = require("../../schemas/plugins/HashedModuleIdsPlugin.json"); const { compareModulesByPreOrderIndexOrIdentifier } = require("../util/comparators"); +const createSchemaValidation = require("../util/create-schema-validation"); const createHash = require("../util/createHash"); -const { getUsedModuleIds, getFullModuleName } = require("./IdHelpers"); +const { + getUsedModuleIdsAndModules, + getFullModuleName +} = require("./IdHelpers"); /** @typedef {import("../../declarations/plugins/HashedModuleIdsPlugin").HashedModuleIdsPluginOptions} HashedModuleIdsPluginOptions */ +/** @typedef {import("../Compiler")} Compiler */ + +const validate = createSchemaValidation( + require("../../schemas/plugins/HashedModuleIdsPlugin.check.js"), + () => require("../../schemas/plugins/HashedModuleIdsPlugin.json"), + { + name: "Hashed Module Ids Plugin", + baseDataPath: "options" + } +); class HashedModuleIdsPlugin { /** * @param {HashedModuleIdsPluginOptions=} options options object */ constructor(options = {}) { - validate(schema, options, { - name: "Hashed Module Ids Plugin", - baseDataPath: "options" - }); + validate(options); /** @type {HashedModuleIdsPluginOptions} */ this.options = { - context: null, + context: undefined, hashFunction: "md4", hashDigest: "base64", hashDigestLength: 4, @@ -35,35 +44,39 @@ class HashedModuleIdsPlugin { }; } + /** + * Apply the plugin + * @param {Compiler} compiler the compiler instance + * @returns {void} + */ apply(compiler) { const options = this.options; compiler.hooks.compilation.tap("HashedModuleIdsPlugin", compilation => { - compilation.hooks.moduleIds.tap("HashedModuleIdsPlugin", modules => { + compilation.hooks.moduleIds.tap("HashedModuleIdsPlugin", () => { const chunkGraph = compilation.chunkGraph; const context = this.options.context ? this.options.context : compiler.context; - const usedIds = getUsedModuleIds(compilation); - const modulesInNaturalOrder = Array.from(modules) - .filter(m => { - if (!m.needId) return false; - if (chunkGraph.getNumberOfModuleChunks(m) === 0) return false; - return chunkGraph.getModuleId(module) === null; - }) - .sort( - compareModulesByPreOrderIndexOrIdentifier(compilation.moduleGraph) - ); + const [usedIds, modules] = getUsedModuleIdsAndModules(compilation); + const modulesInNaturalOrder = modules.sort( + compareModulesByPreOrderIndexOrIdentifier(compilation.moduleGraph) + ); for (const module of modulesInNaturalOrder) { const ident = getFullModuleName(module, context, compiler.root); - const hash = createHash(options.hashFunction); + const hash = createHash( + /** @type {NonNullable} */ ( + options.hashFunction + ) + ); hash.update(ident || ""); - const hashId = /** @type {string} */ (hash.digest( - options.hashDigest - )); + const hashId = /** @type {string} */ ( + hash.digest(options.hashDigest) + ); let len = options.hashDigestLength; - while (usedIds.has(hashId.substr(0, len))) len++; - const moduleId = hashId.substr(0, len); + while (usedIds.has(hashId.slice(0, len))) + /** @type {number} */ (len)++; + const moduleId = hashId.slice(0, len); chunkGraph.setModuleId(module, moduleId); usedIds.add(moduleId); } diff --git a/lib/ids/IdHelpers.js b/lib/ids/IdHelpers.js index e5e2be5f25d..78cdaef0508 100644 --- a/lib/ids/IdHelpers.js +++ b/lib/ids/IdHelpers.js @@ -13,17 +13,19 @@ const numberHash = require("../util/numberHash"); /** @typedef {import("../ChunkGraph")} ChunkGraph */ /** @typedef {import("../Compilation")} Compilation */ /** @typedef {import("../Module")} Module */ +/** @typedef {typeof import("../util/Hash")} Hash */ /** * @param {string} str string to hash * @param {number} len max length of the hash + * @param {string | Hash} hashFunction hash function to use * @returns {string} hash */ -const getHash = (str, len) => { - const hash = createHash("md4"); +const getHash = (str, len, hashFunction) => { + const hash = createHash(hashFunction); hash.update(str); const digest = /** @type {string} */ (hash.digest("hex")); - return digest.substr(0, len); + return digest.slice(0, len); }; /** @@ -41,7 +43,7 @@ const avoidNumber = str => { } else if (firstChar > 57) { return str; } - if (str === +str + "") { + if (str === String(Number(str))) { return `_${str}`; } return str; @@ -51,29 +53,29 @@ const avoidNumber = str => { * @param {string} request the request * @returns {string} id representation */ -const requestToId = request => { - return request - .replace(/^(\.\.?\/)+/, "") - .replace(/(^[.-]|[^a-zA-Z0-9_-])+/g, "_"); -}; -exports.requestToId = requestToId; +const requestToId = request => + request.replace(/^(\.\.?\/)+/, "").replace(/(^[.-]|[^a-zA-Z0-9_-])+/g, "_"); +module.exports.requestToId = requestToId; /** * @param {string} string the string * @param {string} delimiter separator for string and hash + * @param {string | Hash} hashFunction hash function to use * @returns {string} string with limited max length to 100 chars */ -const shortenLongString = (string, delimiter) => { +const shortenLongString = (string, delimiter, hashFunction) => { if (string.length < 100) return string; return ( - string.slice(0, 100 - 6 - delimiter.length) + delimiter + getHash(string, 6) + string.slice(0, 100 - 6 - delimiter.length) + + delimiter + + getHash(string, 6, hashFunction) ); }; /** * @param {Module} module the module * @param {string} context context directory - * @param {Object=} associatedObjectForCache an object to which the cache will be attached + * @param {object=} associatedObjectForCache an object to which the cache will be attached * @returns {string} short module name */ const getShortModuleName = (module, context, associatedObjectForCache) => { @@ -86,47 +88,45 @@ const getShortModuleName = (module, context, associatedObjectForCache) => { ); return ""; }; -exports.getShortModuleName = getShortModuleName; +module.exports.getShortModuleName = getShortModuleName; /** * @param {string} shortName the short name * @param {Module} module the module * @param {string} context context directory - * @param {Object=} associatedObjectForCache an object to which the cache will be attached + * @param {string | Hash} hashFunction hash function to use + * @param {object=} associatedObjectForCache an object to which the cache will be attached * @returns {string} long module name */ const getLongModuleName = ( shortName, module, context, + hashFunction, associatedObjectForCache ) => { const fullName = getFullModuleName(module, context, associatedObjectForCache); - return `${shortName}?${getHash(fullName, 4)}`; + return `${shortName}?${getHash(fullName, 4, hashFunction)}`; }; -exports.getLongModuleName = getLongModuleName; +module.exports.getLongModuleName = getLongModuleName; /** * @param {Module} module the module * @param {string} context context directory - * @param {Object=} associatedObjectForCache an object to which the cache will be attached + * @param {object=} associatedObjectForCache an object to which the cache will be attached * @returns {string} full module name */ -const getFullModuleName = (module, context, associatedObjectForCache) => { - return makePathsRelative( - context, - module.identifier(), - associatedObjectForCache - ); -}; -exports.getFullModuleName = getFullModuleName; +const getFullModuleName = (module, context, associatedObjectForCache) => + makePathsRelative(context, module.identifier(), associatedObjectForCache); +module.exports.getFullModuleName = getFullModuleName; /** * @param {Chunk} chunk the chunk * @param {ChunkGraph} chunkGraph the chunk graph * @param {string} context context directory * @param {string} delimiter delimiter for names - * @param {Object=} associatedObjectForCache an object to which the cache will be attached + * @param {string | Hash} hashFunction hash function to use + * @param {object=} associatedObjectForCache an object to which the cache will be attached * @returns {string} short chunk name */ const getShortChunkName = ( @@ -134,6 +134,7 @@ const getShortChunkName = ( chunkGraph, context, delimiter, + hashFunction, associatedObjectForCache ) => { const modules = chunkGraph.getChunkRootModules(chunk); @@ -145,16 +146,17 @@ const getShortChunkName = ( .concat(shortModuleNames) .filter(Boolean) .join(delimiter); - return shortenLongString(chunkName, delimiter); + return shortenLongString(chunkName, delimiter, hashFunction); }; -exports.getShortChunkName = getShortChunkName; +module.exports.getShortChunkName = getShortChunkName; /** * @param {Chunk} chunk the chunk * @param {ChunkGraph} chunkGraph the chunk graph * @param {string} context context directory * @param {string} delimiter delimiter for names - * @param {Object=} associatedObjectForCache an object to which the cache will be attached + * @param {string | Hash} hashFunction hash function to use + * @param {object=} associatedObjectForCache an object to which the cache will be attached * @returns {string} short chunk name */ const getLongChunkName = ( @@ -162,6 +164,7 @@ const getLongChunkName = ( chunkGraph, context, delimiter, + hashFunction, associatedObjectForCache ) => { const modules = chunkGraph.getChunkRootModules(chunk); @@ -169,22 +172,24 @@ const getLongChunkName = ( requestToId(getShortModuleName(m, context, associatedObjectForCache)) ); const longModuleNames = modules.map(m => - requestToId(getLongModuleName("", m, context, associatedObjectForCache)) + requestToId( + getLongModuleName("", m, context, hashFunction, associatedObjectForCache) + ) ); chunk.idNameHints.sort(); const chunkName = Array.from(chunk.idNameHints) .concat(shortModuleNames, longModuleNames) .filter(Boolean) .join(delimiter); - return shortenLongString(chunkName, delimiter); + return shortenLongString(chunkName, delimiter, hashFunction); }; -exports.getLongChunkName = getLongChunkName; +module.exports.getLongChunkName = getLongChunkName; /** * @param {Chunk} chunk the chunk * @param {ChunkGraph} chunkGraph the chunk graph * @param {string} context context directory - * @param {Object=} associatedObjectForCache an object to which the cache will be attached + * @param {object=} associatedObjectForCache an object to which the cache will be attached * @returns {string} full chunk name */ const getFullChunkName = ( @@ -200,7 +205,7 @@ const getFullChunkName = ( ); return fullModuleNames.join(); }; -exports.getFullChunkName = getFullChunkName; +module.exports.getFullChunkName = getFullChunkName; /** * @template K @@ -221,29 +226,38 @@ const addToMapOfItems = (map, key, value) => { /** * @param {Compilation} compilation the compilation - * @returns {Set} used module ids as strings + * @param {function(Module): boolean=} filter filter modules + * @returns {[Set, Module[]]} used module ids as strings and modules without id matching the filter */ -const getUsedModuleIds = compilation => { +const getUsedModuleIdsAndModules = (compilation, filter) => { const chunkGraph = compilation.chunkGraph; + const modules = []; + /** @type {Set} */ const usedIds = new Set(); if (compilation.usedModuleIds) { for (const id of compilation.usedModuleIds) { - usedIds.add(id + ""); + usedIds.add(String(id)); } } for (const module of compilation.modules) { + if (!module.needId) continue; const moduleId = chunkGraph.getModuleId(module); if (moduleId !== null) { - usedIds.add(moduleId + ""); + usedIds.add(String(moduleId)); + } else if ( + (!filter || filter(module)) && + chunkGraph.getNumberOfModuleChunks(module) !== 0 + ) { + modules.push(module); } } - return usedIds; + return [usedIds, modules]; }; -exports.getUsedModuleIds = getUsedModuleIds; +module.exports.getUsedModuleIdsAndModules = getUsedModuleIdsAndModules; /** * @param {Compilation} compilation the compilation @@ -254,20 +268,20 @@ const getUsedChunkIds = compilation => { const usedIds = new Set(); if (compilation.usedChunkIds) { for (const id of compilation.usedChunkIds) { - usedIds.add(id + ""); + usedIds.add(String(id)); } } for (const chunk of compilation.chunks) { const chunkId = chunk.id; if (chunkId !== null) { - usedIds.add(chunkId + ""); + usedIds.add(String(chunkId)); } } return usedIds; }; -exports.getUsedChunkIds = getUsedChunkIds; +module.exports.getUsedChunkIds = getUsedChunkIds; /** * @template T @@ -335,7 +349,7 @@ const assignNames = ( unnamedItems.sort(comparator); return unnamedItems; }; -exports.assignNames = assignNames; +module.exports.assignNames = assignNames; /** * @template T @@ -346,6 +360,7 @@ exports.assignNames = assignNames; * @param {number[]} ranges usable ranges for ids * @param {number} expandFactor factor to create more ranges * @param {number} extraSpace extra space to allocate, i. e. when some ids are already used + * @param {number} salt salting number to initialize hashing * @returns {void} */ const assignDeterministicIds = ( @@ -355,13 +370,14 @@ const assignDeterministicIds = ( assignId, ranges = [10], expandFactor = 10, - extraSpace = 0 + extraSpace = 0, + salt = 0 ) => { items.sort(comparator); // max 5% fill rate const optimalRange = Math.min( - Math.ceil(items.length * 20) + extraSpace, + items.length * 20 + extraSpace, Number.MAX_SAFE_INTEGER ); @@ -371,42 +387,49 @@ const assignDeterministicIds = ( i++; if (i < ranges.length) { range = Math.min(ranges[i], Number.MAX_SAFE_INTEGER); - } else { + } else if (expandFactor) { range = Math.min(range * expandFactor, Number.MAX_SAFE_INTEGER); + } else { + break; } } for (const item of items) { const ident = getName(item); let id; - let i = 0; + let i = salt; do { id = numberHash(ident + i++, range); } while (!assignId(item, id)); } }; -exports.assignDeterministicIds = assignDeterministicIds; +module.exports.assignDeterministicIds = assignDeterministicIds; /** + * @param {Set} usedIds used ids * @param {Iterable} modules the modules * @param {Compilation} compilation the compilation * @returns {void} */ -const assignAscendingModuleIds = (modules, compilation) => { +const assignAscendingModuleIds = (usedIds, modules, compilation) => { const chunkGraph = compilation.chunkGraph; - const usedIds = getUsedModuleIds(compilation); - let nextId = 0; let assignId; if (usedIds.size > 0) { + /** + * @param {Module} module the module + */ assignId = module => { if (chunkGraph.getModuleId(module) === null) { - while (usedIds.has(nextId + "")) nextId++; + while (usedIds.has(String(nextId))) nextId++; chunkGraph.setModuleId(module, nextId++); } }; } else { + /** + * @param {Module} module the module + */ assignId = module => { if (chunkGraph.getModuleId(module) === null) { chunkGraph.setModuleId(module, nextId++); @@ -417,7 +440,7 @@ const assignAscendingModuleIds = (modules, compilation) => { assignId(module); } }; -exports.assignAscendingModuleIds = assignAscendingModuleIds; +module.exports.assignAscendingModuleIds = assignAscendingModuleIds; /** * @param {Iterable} chunks the chunks @@ -431,7 +454,7 @@ const assignAscendingChunkIds = (chunks, compilation) => { if (usedIds.size > 0) { for (const chunk of chunks) { if (chunk.id === null) { - while (usedIds.has(nextId + "")) nextId++; + while (usedIds.has(String(nextId))) nextId++; chunk.id = nextId; chunk.ids = [nextId]; nextId++; @@ -447,4 +470,4 @@ const assignAscendingChunkIds = (chunks, compilation) => { } } }; -exports.assignAscendingChunkIds = assignAscendingChunkIds; +module.exports.assignAscendingChunkIds = assignAscendingChunkIds; diff --git a/lib/ids/NamedChunkIdsPlugin.js b/lib/ids/NamedChunkIdsPlugin.js index 5e31629f927..f55a5875a7f 100644 --- a/lib/ids/NamedChunkIdsPlugin.js +++ b/lib/ids/NamedChunkIdsPlugin.js @@ -14,11 +14,21 @@ const { assignAscendingChunkIds } = require("./IdHelpers"); +/** @typedef {import("../../declarations/WebpackOptions").OutputNormalized} Output */ /** @typedef {import("../Chunk")} Chunk */ /** @typedef {import("../Compiler")} Compiler */ /** @typedef {import("../Module")} Module */ +/** + * @typedef {object} NamedChunkIdsPluginOptions + * @property {string} [context] context + * @property {string} [delimiter] delimiter + */ + class NamedChunkIdsPlugin { + /** + * @param {NamedChunkIdsPluginOptions=} options options + */ constructor(options) { this.delimiter = (options && options.delimiter) || "-"; this.context = options && options.context; @@ -31,6 +41,9 @@ class NamedChunkIdsPlugin { */ apply(compiler) { compiler.hooks.compilation.tap("NamedChunkIdsPlugin", compilation => { + const hashFunction = + /** @type {NonNullable} */ + (compilation.outputOptions.hashFunction); compilation.hooks.chunkIds.tap("NamedChunkIdsPlugin", chunks => { const chunkGraph = compilation.chunkGraph; const context = this.context ? this.context : compiler.context; @@ -50,6 +63,7 @@ class NamedChunkIdsPlugin { chunkGraph, context, delimiter, + hashFunction, compiler.root ), chunk => @@ -58,6 +72,7 @@ class NamedChunkIdsPlugin { chunkGraph, context, delimiter, + hashFunction, compiler.root ), compareChunksNatural(chunkGraph), diff --git a/lib/ids/NamedModuleIdsPlugin.js b/lib/ids/NamedModuleIdsPlugin.js index 3329f45b9d0..9656b8d917e 100644 --- a/lib/ids/NamedModuleIdsPlugin.js +++ b/lib/ids/NamedModuleIdsPlugin.js @@ -10,16 +10,25 @@ const { getShortModuleName, getLongModuleName, assignNames, - getUsedModuleIds, + getUsedModuleIdsAndModules, assignAscendingModuleIds } = require("./IdHelpers"); +/** @typedef {import("../../declarations/WebpackOptions").OutputNormalized} Output */ /** @typedef {import("../Compiler")} Compiler */ /** @typedef {import("../Module")} Module */ +/** + * @typedef {object} NamedModuleIdsPluginOptions + * @property {string} [context] context + */ + class NamedModuleIdsPlugin { - constructor(options) { - this.options = options || {}; + /** + * @param {NamedModuleIdsPluginOptions} [options] options + */ + constructor(options = {}) { + this.options = options; } /** @@ -30,26 +39,27 @@ class NamedModuleIdsPlugin { apply(compiler) { const { root } = compiler; compiler.hooks.compilation.tap("NamedModuleIdsPlugin", compilation => { - compilation.hooks.moduleIds.tap("NamedModuleIdsPlugin", modules => { + const hashFunction = + /** @type {NonNullable} */ + (compilation.outputOptions.hashFunction); + compilation.hooks.moduleIds.tap("NamedModuleIdsPlugin", () => { const chunkGraph = compilation.chunkGraph; const context = this.options.context ? this.options.context : compiler.context; + const [usedIds, modules] = getUsedModuleIdsAndModules(compilation); const unnamedModules = assignNames( - Array.from(modules).filter(module => { - if (!module.needId) return false; - if (chunkGraph.getNumberOfModuleChunks(module) === 0) return false; - return chunkGraph.getModuleId(module) === null; - }), + modules, m => getShortModuleName(m, context, root), - (m, shortName) => getLongModuleName(shortName, m, context, root), + (m, shortName) => + getLongModuleName(shortName, m, context, hashFunction, root), compareModulesByIdentifier, - getUsedModuleIds(compilation), + usedIds, (m, name) => chunkGraph.setModuleId(m, name) ); if (unnamedModules.length > 0) { - assignAscendingModuleIds(unnamedModules, compilation); + assignAscendingModuleIds(usedIds, unnamedModules, compilation); } }); }); diff --git a/lib/ids/NaturalModuleIdsPlugin.js b/lib/ids/NaturalModuleIdsPlugin.js index a26e1e97dfc..962bcff38fd 100644 --- a/lib/ids/NaturalModuleIdsPlugin.js +++ b/lib/ids/NaturalModuleIdsPlugin.js @@ -8,7 +8,10 @@ const { compareModulesByPreOrderIndexOrIdentifier } = require("../util/comparators"); -const { assignAscendingModuleIds } = require("./IdHelpers"); +const { + assignAscendingModuleIds, + getUsedModuleIdsAndModules +} = require("./IdHelpers"); /** @typedef {import("../Compiler")} Compiler */ /** @typedef {import("../Module")} Module */ @@ -22,18 +25,12 @@ class NaturalModuleIdsPlugin { apply(compiler) { compiler.hooks.compilation.tap("NaturalModuleIdsPlugin", compilation => { compilation.hooks.moduleIds.tap("NaturalModuleIdsPlugin", modules => { - const chunkGraph = compilation.chunkGraph; - const modulesInNaturalOrder = Array.from(modules) - .filter( - m => - m.needId && - chunkGraph.getNumberOfModuleChunks(m) > 0 && - chunkGraph.getModuleId(m) === null - ) - .sort( - compareModulesByPreOrderIndexOrIdentifier(compilation.moduleGraph) - ); - assignAscendingModuleIds(modulesInNaturalOrder, compilation); + const [usedIds, modulesInNaturalOrder] = + getUsedModuleIdsAndModules(compilation); + modulesInNaturalOrder.sort( + compareModulesByPreOrderIndexOrIdentifier(compilation.moduleGraph) + ); + assignAscendingModuleIds(usedIds, modulesInNaturalOrder, compilation); }); }); } diff --git a/lib/ids/OccurrenceChunkIdsPlugin.js b/lib/ids/OccurrenceChunkIdsPlugin.js index 9ce13e01a82..b0acac363ec 100644 --- a/lib/ids/OccurrenceChunkIdsPlugin.js +++ b/lib/ids/OccurrenceChunkIdsPlugin.js @@ -5,9 +5,8 @@ "use strict"; -const { validate } = require("schema-utils"); -const schema = require("../../schemas/plugins/ids/OccurrenceChunkIdsPlugin.json"); const { compareChunksNatural } = require("../util/comparators"); +const createSchemaValidation = require("../util/create-schema-validation"); const { assignAscendingChunkIds } = require("./IdHelpers"); /** @typedef {import("../../declarations/plugins/ids/OccurrenceChunkIdsPlugin").OccurrenceChunkIdsPluginOptions} OccurrenceChunkIdsPluginOptions */ @@ -15,15 +14,21 @@ const { assignAscendingChunkIds } = require("./IdHelpers"); /** @typedef {import("../Compiler")} Compiler */ /** @typedef {import("../Module")} Module */ +const validate = createSchemaValidation( + require("../../schemas/plugins/ids/OccurrenceChunkIdsPlugin.check.js"), + () => require("../../schemas/plugins/ids/OccurrenceChunkIdsPlugin.json"), + { + name: "Occurrence Order Chunk Ids Plugin", + baseDataPath: "options" + } +); + class OccurrenceChunkIdsPlugin { /** * @param {OccurrenceChunkIdsPluginOptions=} options options object */ constructor(options = {}) { - validate(schema, options, { - name: "Occurrence Order Chunk Ids Plugin", - baseDataPath: "options" - }); + validate(options); this.options = options; } @@ -55,8 +60,12 @@ class OccurrenceChunkIdsPlugin { const chunksInOccurrenceOrder = Array.from(chunks).sort((a, b) => { if (prioritiseInitial) { - const aEntryOccurs = occursInInitialChunksMap.get(a); - const bEntryOccurs = occursInInitialChunksMap.get(b); + const aEntryOccurs = + /** @type {number} */ + (occursInInitialChunksMap.get(a)); + const bEntryOccurs = + /** @type {number} */ + (occursInInitialChunksMap.get(b)); if (aEntryOccurs > bEntryOccurs) return -1; if (aEntryOccurs < bEntryOccurs) return 1; } diff --git a/lib/ids/OccurrenceModuleIdsPlugin.js b/lib/ids/OccurrenceModuleIdsPlugin.js index 7bc4baaf82a..71fb2ce047a 100644 --- a/lib/ids/OccurrenceModuleIdsPlugin.js +++ b/lib/ids/OccurrenceModuleIdsPlugin.js @@ -5,27 +5,35 @@ "use strict"; -const { validate } = require("schema-utils"); -const schema = require("../../schemas/plugins/ids/OccurrenceModuleIdsPlugin.json"); const { compareModulesByPreOrderIndexOrIdentifier } = require("../util/comparators"); -const { assignAscendingModuleIds } = require("./IdHelpers"); +const createSchemaValidation = require("../util/create-schema-validation"); +const { + assignAscendingModuleIds, + getUsedModuleIdsAndModules +} = require("./IdHelpers"); /** @typedef {import("../../declarations/plugins/ids/OccurrenceModuleIdsPlugin").OccurrenceModuleIdsPluginOptions} OccurrenceModuleIdsPluginOptions */ /** @typedef {import("../Compiler")} Compiler */ /** @typedef {import("../Module")} Module */ /** @typedef {import("../ModuleGraphConnection")} ModuleGraphConnection */ +const validate = createSchemaValidation( + require("../../schemas/plugins/ids/OccurrenceModuleIdsPlugin.check.js"), + () => require("../../schemas/plugins/ids/OccurrenceModuleIdsPlugin.json"), + { + name: "Occurrence Order Module Ids Plugin", + baseDataPath: "options" + } +); + class OccurrenceModuleIdsPlugin { /** * @param {OccurrenceModuleIdsPluginOptions=} options options object */ constructor(options = {}) { - validate(schema, options, { - name: "Occurrence Order Module Ids Plugin", - baseDataPath: "options" - }); + validate(options); this.options = options; } @@ -39,15 +47,11 @@ class OccurrenceModuleIdsPlugin { compiler.hooks.compilation.tap("OccurrenceModuleIdsPlugin", compilation => { const moduleGraph = compilation.moduleGraph; - compilation.hooks.moduleIds.tap("OccurrenceModuleIdsPlugin", modules => { + compilation.hooks.moduleIds.tap("OccurrenceModuleIdsPlugin", () => { const chunkGraph = compilation.chunkGraph; - const modulesInOccurrenceOrder = Array.from(modules).filter( - m => - m.needId && - chunkGraph.getNumberOfModuleChunks(m) > 0 && - chunkGraph.getModuleId(m) === null - ); + const [usedIds, modulesInOccurrenceOrder] = + getUsedModuleIdsAndModules(compilation); const occursInInitialChunksMap = new Map(); const occursInAllChunksMap = new Map(); @@ -77,7 +81,7 @@ class OccurrenceModuleIdsPlugin { ] of moduleGraph.getIncomingConnectionsByOriginModule(module)) { if (!originModule) continue; if (!connections.some(c => c.isTargetActive(undefined))) continue; - sum += initialChunkChunkMap.get(originModule); + sum += initialChunkChunkMap.get(originModule) || 0; } return sum; }; @@ -93,9 +97,8 @@ class OccurrenceModuleIdsPlugin { connections ] of moduleGraph.getIncomingConnectionsByOriginModule(module)) { if (!originModule) continue; - const chunkModules = chunkGraph.getNumberOfModuleChunks( - originModule - ); + const chunkModules = + chunkGraph.getNumberOfModuleChunks(originModule); for (const c of connections) { if (!c.isTargetActive(undefined)) continue; if (!c.dependency) continue; @@ -117,7 +120,7 @@ class OccurrenceModuleIdsPlugin { } } - for (const m of modules) { + for (const m of modulesInOccurrenceOrder) { const result = countOccurs(m) + chunkGraph.getNumberOfModuleChunks(m) + @@ -143,7 +146,11 @@ class OccurrenceModuleIdsPlugin { return naturalCompare(a, b); }); - assignAscendingModuleIds(modulesInOccurrenceOrder, compilation); + assignAscendingModuleIds( + usedIds, + modulesInOccurrenceOrder, + compilation + ); }); }); } diff --git a/lib/ids/SyncModuleIdsPlugin.js b/lib/ids/SyncModuleIdsPlugin.js new file mode 100644 index 00000000000..aa837624e94 --- /dev/null +++ b/lib/ids/SyncModuleIdsPlugin.js @@ -0,0 +1,146 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ + +"use strict"; + +const { WebpackError } = require(".."); +const { getUsedModuleIdsAndModules } = require("./IdHelpers"); + +/** @typedef {import("../Compiler")} Compiler */ +/** @typedef {import("../Module")} Module */ +/** @typedef {import("../util/fs").IntermediateFileSystem} IntermediateFileSystem */ + +const plugin = "SyncModuleIdsPlugin"; + +class SyncModuleIdsPlugin { + /** + * @param {object} options options + * @param {string} options.path path to file + * @param {string=} options.context context for module names + * @param {function(Module): boolean} options.test selector for modules + * @param {"read" | "create" | "merge" | "update"=} options.mode operation mode (defaults to merge) + */ + constructor({ path, context, test, mode }) { + this._path = path; + this._context = context; + this._test = test || (() => true); + const readAndWrite = !mode || mode === "merge" || mode === "update"; + this._read = readAndWrite || mode === "read"; + this._write = readAndWrite || mode === "create"; + this._prune = mode === "update"; + } + + /** + * Apply the plugin + * @param {Compiler} compiler the compiler instance + * @returns {void} + */ + apply(compiler) { + /** @type {Map} */ + let data; + let dataChanged = false; + if (this._read) { + compiler.hooks.readRecords.tapAsync(plugin, callback => { + const fs = + /** @type {IntermediateFileSystem} */ + (compiler.intermediateFileSystem); + fs.readFile(this._path, (err, buffer) => { + if (err) { + if (err.code !== "ENOENT") { + return callback(err); + } + return callback(); + } + const json = JSON.parse(/** @type {Buffer} */ (buffer).toString()); + data = new Map(); + for (const key of Object.keys(json)) { + data.set(key, json[key]); + } + dataChanged = false; + return callback(); + }); + }); + } + if (this._write) { + compiler.hooks.emitRecords.tapAsync(plugin, callback => { + if (!data || !dataChanged) return callback(); + /** @type {{[key: string]: string | number}} */ + const json = {}; + const sorted = Array.from(data).sort(([a], [b]) => (a < b ? -1 : 1)); + for (const [key, value] of sorted) { + json[key] = value; + } + const fs = + /** @type {IntermediateFileSystem} */ + (compiler.intermediateFileSystem); + fs.writeFile(this._path, JSON.stringify(json), callback); + }); + } + compiler.hooks.thisCompilation.tap(plugin, compilation => { + const associatedObjectForCache = compiler.root; + const context = this._context || compiler.context; + if (this._read) { + compilation.hooks.reviveModules.tap(plugin, (_1, _2) => { + if (!data) return; + const { chunkGraph } = compilation; + const [usedIds, modules] = getUsedModuleIdsAndModules( + compilation, + this._test + ); + for (const module of modules) { + const name = module.libIdent({ + context, + associatedObjectForCache + }); + if (!name) continue; + const id = data.get(name); + const idAsString = `${id}`; + if (usedIds.has(idAsString)) { + const err = new WebpackError( + `SyncModuleIdsPlugin: Unable to restore id '${id}' from '${this._path}' as it's already used.` + ); + err.module = module; + compilation.errors.push(err); + } + chunkGraph.setModuleId(module, /** @type {string | number} */ (id)); + usedIds.add(idAsString); + } + }); + } + if (this._write) { + compilation.hooks.recordModules.tap(plugin, modules => { + const { chunkGraph } = compilation; + let oldData = data; + if (!oldData) { + oldData = data = new Map(); + } else if (this._prune) { + data = new Map(); + } + for (const module of modules) { + if (this._test(module)) { + const name = module.libIdent({ + context, + associatedObjectForCache + }); + if (!name) continue; + const id = chunkGraph.getModuleId(module); + if (id === null) continue; + const oldId = oldData.get(name); + if (oldId !== id) { + dataChanged = true; + } else if (data === oldData) { + continue; + } + data.set(name, id); + } + } + if (data.size !== oldData.size) dataChanged = true; + }); + } + }); + } +} + +module.exports = SyncModuleIdsPlugin; diff --git a/lib/index.js b/lib/index.js index 1c8fe1094b0..00e367a54b3 100644 --- a/lib/index.js +++ b/lib/index.js @@ -11,7 +11,14 @@ const memoize = require("./util/memoize"); /** @typedef {import("../declarations/WebpackOptions").Entry} Entry */ /** @typedef {import("../declarations/WebpackOptions").EntryNormalized} EntryNormalized */ /** @typedef {import("../declarations/WebpackOptions").EntryObject} EntryObject */ +/** @typedef {import("../declarations/WebpackOptions").ExternalItemFunctionData} ExternalItemFunctionData */ +/** @typedef {import("../declarations/WebpackOptions").ExternalItemObjectKnown} ExternalItemObjectKnown */ +/** @typedef {import("../declarations/WebpackOptions").ExternalItemObjectUnknown} ExternalItemObjectUnknown */ +/** @typedef {import("../declarations/WebpackOptions").ExternalItemValue} ExternalItemValue */ +/** @typedef {import("../declarations/WebpackOptions").Externals} Externals */ +/** @typedef {import("../declarations/WebpackOptions").FileCacheOptions} FileCacheOptions */ /** @typedef {import("../declarations/WebpackOptions").LibraryOptions} LibraryOptions */ +/** @typedef {import("../declarations/WebpackOptions").MemoryCacheOptions} MemoryCacheOptions */ /** @typedef {import("../declarations/WebpackOptions").ModuleOptions} ModuleOptions */ /** @typedef {import("../declarations/WebpackOptions").ResolveOptions} ResolveOptions */ /** @typedef {import("../declarations/WebpackOptions").RuleSetCondition} RuleSetCondition */ @@ -19,16 +26,42 @@ const memoize = require("./util/memoize"); /** @typedef {import("../declarations/WebpackOptions").RuleSetRule} RuleSetRule */ /** @typedef {import("../declarations/WebpackOptions").RuleSetUse} RuleSetUse */ /** @typedef {import("../declarations/WebpackOptions").RuleSetUseItem} RuleSetUseItem */ +/** @typedef {import("../declarations/WebpackOptions").StatsOptions} StatsOptions */ /** @typedef {import("../declarations/WebpackOptions").WebpackOptions} Configuration */ /** @typedef {import("../declarations/WebpackOptions").WebpackOptionsNormalized} WebpackOptionsNormalized */ /** @typedef {import("../declarations/WebpackOptions").WebpackPluginFunction} WebpackPluginFunction */ /** @typedef {import("../declarations/WebpackOptions").WebpackPluginInstance} WebpackPluginInstance */ +/** @typedef {import("./ChunkGroup")} ChunkGroup */ /** @typedef {import("./Compilation").Asset} Asset */ /** @typedef {import("./Compilation").AssetInfo} AssetInfo */ +/** @typedef {import("./Compilation").EntryOptions} EntryOptions */ +/** @typedef {import("./Compilation").PathData} PathData */ +/** @typedef {import("./Compiler").AssetEmittedInfo} AssetEmittedInfo */ +/** @typedef {import("./MultiCompiler").MultiCompilerOptions} MultiCompilerOptions */ /** @typedef {import("./MultiStats")} MultiStats */ +/** @typedef {import("./NormalModuleFactory").ResolveData} ResolveData */ /** @typedef {import("./Parser").ParserState} ParserState */ +/** @typedef {import("./ResolverFactory").ResolvePluginInstance} ResolvePluginInstance */ +/** @typedef {import("./ResolverFactory").Resolver} Resolver */ /** @typedef {import("./Watching")} Watching */ +/** @typedef {import("./cli").Argument} Argument */ +/** @typedef {import("./cli").Problem} Problem */ +/** @typedef {import("./stats/DefaultStatsFactoryPlugin").StatsAsset} StatsAsset */ +/** @typedef {import("./stats/DefaultStatsFactoryPlugin").StatsChunk} StatsChunk */ +/** @typedef {import("./stats/DefaultStatsFactoryPlugin").StatsChunkGroup} StatsChunkGroup */ +/** @typedef {import("./stats/DefaultStatsFactoryPlugin").StatsChunkOrigin} StatsChunkOrigin */ /** @typedef {import("./stats/DefaultStatsFactoryPlugin").StatsCompilation} StatsCompilation */ +/** @typedef {import("./stats/DefaultStatsFactoryPlugin").StatsError} StatsError */ +/** @typedef {import("./stats/DefaultStatsFactoryPlugin").StatsLogging} StatsLogging */ +/** @typedef {import("./stats/DefaultStatsFactoryPlugin").StatsLoggingEntry} StatsLoggingEntry */ +/** @typedef {import("./stats/DefaultStatsFactoryPlugin").StatsModule} StatsModule */ +/** @typedef {import("./stats/DefaultStatsFactoryPlugin").StatsModuleIssuer} StatsModuleIssuer */ +/** @typedef {import("./stats/DefaultStatsFactoryPlugin").StatsModuleReason} StatsModuleReason */ +/** @typedef {import("./stats/DefaultStatsFactoryPlugin").StatsModuleTraceDependency} StatsModuleTraceDependency */ +/** @typedef {import("./stats/DefaultStatsFactoryPlugin").StatsModuleTraceItem} StatsModuleTraceItem */ +/** @typedef {import("./stats/DefaultStatsFactoryPlugin").StatsProfile} StatsProfile */ +/** @typedef {import("./util/fs").InputFileSystem} InputFileSystem */ +/** @typedef {import("./util/fs").OutputFileSystem} OutputFileSystem */ /** * @template {Function} T @@ -37,9 +70,7 @@ const memoize = require("./util/memoize"); */ const lazyFunction = factory => { const fac = memoize(factory); - const f = /** @type {any} */ ((...args) => { - return fac()(...args); - }); + const f = /** @type {any} */ ((...args) => fac()(...args)); return /** @type {T} */ (f); }; @@ -83,9 +114,15 @@ module.exports = mergeExports(fn, { return require("./webpack"); }, get validate() { - const validateSchema = require("./validateSchema"); - const webpackOptionsSchema = require("../schemas/WebpackOptions.json"); - return options => validateSchema(webpackOptionsSchema, options); + const webpackOptionsSchemaCheck = require("../schemas/WebpackOptions.check.js"); + const getRealValidate = memoize(() => { + const validateSchema = require("./validateSchema"); + const webpackOptionsSchema = require("../schemas/WebpackOptions.json"); + return options => validateSchema(webpackOptionsSchema, options); + }); + return options => { + if (!webpackOptionsSchemaCheck(options)) getRealValidate()(options); + }; }, get validateSchema() { const validateSchema = require("./validateSchema"); @@ -101,6 +138,9 @@ module.exports = mergeExports(fn, { get AutomaticPrefetchPlugin() { return require("./AutomaticPrefetchPlugin"); }, + get AsyncDependenciesBlock() { + return require("./AsyncDependenciesBlock"); + }, get BannerPlugin() { return require("./BannerPlugin"); }, @@ -179,6 +219,9 @@ module.exports = mergeExports(fn, { get HotModuleReplacementPlugin() { return require("./HotModuleReplacementPlugin"); }, + get InitFragment() { + return require("./InitFragment"); + }, get IgnorePlugin() { return require("./IgnorePlugin"); }, @@ -229,9 +272,15 @@ module.exports = mergeExports(fn, { get MultiCompiler() { return require("./MultiCompiler"); }, + get OptimizationStages() { + return require("./OptimizationStages"); + }, get Parser() { return require("./Parser"); }, + get PlatformPlugin() { + return require("./PlatformPlugin"); + }, get PrefetchPlugin() { return require("./PrefetchPlugin"); }, @@ -305,6 +354,21 @@ module.exports = mergeExports(fn, { } }, + dependencies: { + get ModuleDependency() { + return require("./dependencies/ModuleDependency"); + }, + get HarmonyImportDependency() { + return require("./dependencies/HarmonyImportDependency"); + }, + get ConstDependency() { + return require("./dependencies/ConstDependency"); + }, + get NullDependency() { + return require("./dependencies/NullDependency"); + } + }, + ids: { get ChunkModuleIdRangePlugin() { return require("./ids/ChunkModuleIdRangePlugin"); @@ -358,6 +422,9 @@ module.exports = mergeExports(fn, { "DEP_WEBPACK_AGGRESSIVE_SPLITTING_PLUGIN" )(); }, + get InnerGraph() { + return require("./optimize/InnerGraph"); + }, get LimitChunkCountPlugin() { return require("./optimize/LimitChunkCountPlugin"); }, @@ -444,6 +511,9 @@ module.exports = mergeExports(fn, { wasm: { get AsyncWebAssemblyModulesPlugin() { return require("./wasm-async/AsyncWebAssemblyModulesPlugin"); + }, + get EnableWasmLoadingPlugin() { + return require("./wasm/EnableWasmLoadingPlugin"); } }, @@ -499,6 +569,9 @@ module.exports = mergeExports(fn, { get comparators() { return require("./util/comparators"); }, + get runtime() { + return require("./util/runtime"); + }, get serialization() { return require("./util/serialization"); }, @@ -507,6 +580,9 @@ module.exports = mergeExports(fn, { }, get LazySet() { return require("./util/LazySet"); + }, + get compileBooleanMatcher() { + return require("./util/compileBooleanMatcher"); } }, @@ -518,9 +594,11 @@ module.exports = mergeExports(fn, { schemes: { get HttpUriPlugin() { return require("./schemes/HttpUriPlugin"); - }, - get HttpsUriPlugin() { - return require("./schemes/HttpsUriPlugin"); + } + }, + ids: { + get SyncModuleIdsPlugin() { + return require("./ids/SyncModuleIdsPlugin"); } } } diff --git a/lib/javascript/ArrayPushCallbackChunkFormatPlugin.js b/lib/javascript/ArrayPushCallbackChunkFormatPlugin.js index 2d26438704e..1bb04abaffb 100644 --- a/lib/javascript/ArrayPushCallbackChunkFormatPlugin.js +++ b/lib/javascript/ArrayPushCallbackChunkFormatPlugin.js @@ -29,10 +29,11 @@ class ArrayPushCallbackChunkFormatPlugin { compilation => { compilation.hooks.additionalChunkRuntimeRequirements.tap( "ArrayPushCallbackChunkFormatPlugin", - (chunk, set) => { + (chunk, set, { chunkGraph }) => { if (chunk.hasRuntime()) return; - if (compilation.chunkGraph.getNumberOfEntryModules(chunk) > 0) { + if (chunkGraph.getNumberOfEntryModules(chunk) > 0) { set.add(RuntimeGlobals.onChunksLoaded); + set.add(RuntimeGlobals.exports); set.add(RuntimeGlobals.require); } set.add(RuntimeGlobals.chunkCallback); @@ -45,11 +46,10 @@ class ArrayPushCallbackChunkFormatPlugin { const { chunk, chunkGraph, runtimeTemplate } = renderContext; const hotUpdateChunk = chunk instanceof HotUpdateChunk ? chunk : null; - const globalObject = runtimeTemplate.outputOptions.globalObject; + const globalObject = runtimeTemplate.globalObject; const source = new ConcatSource(); - const runtimeModules = chunkGraph.getChunkRuntimeModulesInOrder( - chunk - ); + const runtimeModules = + chunkGraph.getChunkRuntimeModulesInOrder(chunk); if (hotUpdateChunk) { const hotUpdateGlobal = runtimeTemplate.outputOptions.hotUpdateGlobal; @@ -83,24 +83,18 @@ class ArrayPushCallbackChunkFormatPlugin { chunkGraph.getChunkEntryModulesWithChunkGroupIterable(chunk) ); if (runtimeModules.length > 0 || entries.length > 0) { - const strictBailout = hooks.strictRuntimeBailout.call( - renderContext - ); const runtime = new ConcatSource( - (runtimeTemplate.supportsArrowFunction() - ? "__webpack_require__ =>" - : "function(__webpack_require__)") + - " { // webpackRuntimeModules\n", - strictBailout - ? `// runtime can't be in strict mode because ${strictBailout}.\n\n` - : '"use strict";\n\n' + `${ + runtimeTemplate.supportsArrowFunction() + ? `${RuntimeGlobals.require} =>` + : `function(${RuntimeGlobals.require})` + } { // webpackRuntimeModules\n` ); if (runtimeModules.length > 0) { runtime.add( Template.renderRuntimeModules(runtimeModules, { ...renderContext, - codeGenerationResults: compilation.codeGenerationResults, - useStrict: !!strictBailout + codeGenerationResults: compilation.codeGenerationResults }) ); } @@ -124,6 +118,13 @@ class ArrayPushCallbackChunkFormatPlugin { } ) ); + if ( + chunkGraph + .getChunkRuntimeRequirements(chunk) + .has(RuntimeGlobals.returnExportsFromRuntime) + ) { + runtime.add(`return ${RuntimeGlobals.exports};\n`); + } } runtime.add("}\n"); source.add(",\n"); @@ -138,11 +139,9 @@ class ArrayPushCallbackChunkFormatPlugin { "ArrayPushCallbackChunkFormatPlugin", (chunk, hash, { chunkGraph, runtimeTemplate }) => { if (chunk.hasRuntime()) return; - hash.update("ArrayPushCallbackChunkFormatPlugin"); - hash.update("1"); - hash.update(`${runtimeTemplate.outputOptions.chunkLoadingGlobal}`); - hash.update(`${runtimeTemplate.outputOptions.hotUpdateGlobal}`); - hash.update(`${runtimeTemplate.outputOptions.globalObject}`); + hash.update( + `ArrayPushCallbackChunkFormatPlugin1${runtimeTemplate.outputOptions.chunkLoadingGlobal}${runtimeTemplate.outputOptions.hotUpdateGlobal}${runtimeTemplate.globalObject}` + ); const entries = Array.from( chunkGraph.getChunkEntryModulesWithChunkGroupIterable(chunk) ); diff --git a/lib/javascript/BasicEvaluatedExpression.js b/lib/javascript/BasicEvaluatedExpression.js index 6177a83a861..05dd14cd194 100644 --- a/lib/javascript/BasicEvaluatedExpression.js +++ b/lib/javascript/BasicEvaluatedExpression.js @@ -5,7 +5,8 @@ "use strict"; -/** @typedef {import("estree").Node} EsTreeNode */ +/** @typedef {import("estree").Node} Node */ +/** @typedef {import("./JavascriptParser").Range} Range */ /** @typedef {import("./JavascriptParser").VariableInfoInterface} VariableInfoInterface */ const TypeUnknown = 0; @@ -26,7 +27,7 @@ const TypeBigInt = 13; class BasicEvaluatedExpression { constructor() { this.type = TypeUnknown; - /** @type {[number, number]} */ + /** @type {Range | undefined} */ this.range = undefined; /** @type {boolean} */ this.falsy = false; @@ -56,18 +57,23 @@ class BasicEvaluatedExpression { this.items = undefined; /** @type {BasicEvaluatedExpression[] | undefined} */ this.options = undefined; - /** @type {BasicEvaluatedExpression | undefined} */ + /** @type {BasicEvaluatedExpression | undefined | null} */ this.prefix = undefined; - /** @type {BasicEvaluatedExpression | undefined} */ + /** @type {BasicEvaluatedExpression | undefined | null} */ this.postfix = undefined; + /** @type {BasicEvaluatedExpression[] | undefined} */ this.wrappedInnerExpressions = undefined; - /** @type {string | undefined} */ + /** @type {string | VariableInfoInterface | undefined} */ this.identifier = undefined; - /** @type {VariableInfoInterface} */ + /** @type {string | VariableInfoInterface | undefined} */ this.rootInfo = undefined; - /** @type {() => string[]} */ + /** @type {(() => string[]) | undefined} */ this.getMembers = undefined; - /** @type {EsTreeNode} */ + /** @type {(() => boolean[]) | undefined} */ + this.getMembersOptionals = undefined; + /** @type {(() => Range[]) | undefined} */ + this.getMemberRanges = undefined; + /** @type {Node | undefined} */ this.expression = undefined; } @@ -178,7 +184,7 @@ class BasicEvaluatedExpression { asCompileTimeValue() { switch (this.type) { case TypeUndefined: - return undefined; + return; case TypeNull: return null; case TypeString: @@ -220,6 +226,10 @@ class BasicEvaluatedExpression { return this.sideEffects; } + /** + * Creates a boolean representation of this evaluated expression. + * @returns {boolean | undefined} true: truthy, false: falsy, undefined: unknown + */ asBool() { if (this.truthy) return true; if (this.falsy || this.nullish) return false; @@ -242,9 +252,12 @@ class BasicEvaluatedExpression { const str = this.asString(); if (typeof str === "string") return str !== ""; } - return undefined; } + /** + * Creates a nullish coalescing representation of this evaluated expression. + * @returns {boolean | undefined} true: nullish, false: not nullish, undefined: unknown + */ asNullish() { const nullish = this.isNullish(); @@ -261,10 +274,12 @@ class BasicEvaluatedExpression { if (this.isConstArray()) return false; if (this.isTemplateString()) return false; if (this.isRegExp()) return false; - - return undefined; } + /** + * Creates a string representation of this evaluated expression. + * @returns {string | undefined} the string representation or undefined if not possible + */ asString() { if (this.isBoolean()) return `${this.bool}`; if (this.isNull()) return "null"; @@ -274,10 +289,12 @@ class BasicEvaluatedExpression { if (this.isBigInt()) return `${this.bigint}`; if (this.isRegExp()) return `${this.regExp}`; if (this.isArray()) { - let array = []; - for (const item of this.items) { + const array = []; + for (const item of /** @type {BasicEvaluatedExpression[]} */ ( + this.items + )) { const itemStr = item.asString(); - if (itemStr === undefined) return undefined; + if (itemStr === undefined) return; array.push(itemStr); } return `${array}`; @@ -285,16 +302,21 @@ class BasicEvaluatedExpression { if (this.isConstArray()) return `${this.array}`; if (this.isTemplateString()) { let str = ""; - for (const part of this.parts) { + for (const part of /** @type {BasicEvaluatedExpression[]} */ ( + this.parts + )) { const partStr = part.asString(); - if (partStr === undefined) return undefined; + if (partStr === undefined) return; str += partStr; } return str; } - return undefined; } + /** + * @param {string} string value + * @returns {BasicEvaluatedExpression} basic evaluated expression + */ setString(string) { this.type = TypeString; this.string = string; @@ -314,6 +336,11 @@ class BasicEvaluatedExpression { return this; } + /** + * Set's the value of this expression to a number + * @param {number} number number to set + * @returns {this} this + */ setNumber(number) { this.type = TypeNumber; this.number = number; @@ -321,6 +348,11 @@ class BasicEvaluatedExpression { return this; } + /** + * Set's the value of this expression to a BigInt + * @param {bigint} bigint bigint to set + * @returns {this} this + */ setBigInt(bigint) { this.type = TypeBigInt; this.bigint = bigint; @@ -328,6 +360,11 @@ class BasicEvaluatedExpression { return this; } + /** + * Set's the value of this expression to a boolean + * @param {boolean} bool boolean to set + * @returns {this} this + */ setBoolean(bool) { this.type = TypeBoolean; this.bool = bool; @@ -335,6 +372,11 @@ class BasicEvaluatedExpression { return this; } + /** + * Set's the value of this expression to a regular expression + * @param {RegExp} regExp regular expression to set + * @returns {this} this + */ setRegExp(regExp) { this.type = TypeRegExp; this.regExp = regExp; @@ -342,15 +384,39 @@ class BasicEvaluatedExpression { return this; } - setIdentifier(identifier, rootInfo, getMembers) { + /** + * Set's the value of this expression to a particular identifier and its members. + * @param {string | VariableInfoInterface} identifier identifier to set + * @param {string | VariableInfoInterface} rootInfo root info + * @param {() => string[]} getMembers members + * @param {() => boolean[]=} getMembersOptionals optional members + * @param {() => Range[]=} getMemberRanges ranges of progressively increasing sub-expressions + * @returns {this} this + */ + setIdentifier( + identifier, + rootInfo, + getMembers, + getMembersOptionals, + getMemberRanges + ) { this.type = TypeIdentifier; this.identifier = identifier; this.rootInfo = rootInfo; this.getMembers = getMembers; + this.getMembersOptionals = getMembersOptionals; + this.getMemberRanges = getMemberRanges; this.sideEffects = true; return this; } + /** + * Wraps an array of expressions with a prefix and postfix expression. + * @param {BasicEvaluatedExpression | null | undefined} prefix Expression to be added before the innerExpressions + * @param {BasicEvaluatedExpression | null | undefined} postfix Expression to be added after the innerExpressions + * @param {BasicEvaluatedExpression[] | undefined} innerExpressions Expressions to be wrapped + * @returns {this} this + */ setWrapped(prefix, postfix, innerExpressions) { this.type = TypeWrapped; this.prefix = prefix; @@ -360,6 +426,11 @@ class BasicEvaluatedExpression { return this; } + /** + * Stores the options of a conditional expression. + * @param {BasicEvaluatedExpression[]} options optional (consequent/alternate) expressions to be set + * @returns {this} this + */ setOptions(options) { this.type = TypeConditional; this.options = options; @@ -367,6 +438,11 @@ class BasicEvaluatedExpression { return this; } + /** + * Adds options to a conditional expression. + * @param {BasicEvaluatedExpression[]} options optional (consequent/alternate) expressions to be added + * @returns {this} this + */ addOptions(options) { if (!this.options) { this.type = TypeConditional; @@ -379,6 +455,11 @@ class BasicEvaluatedExpression { return this; } + /** + * Set's the value of this expression to an array of expressions. + * @param {BasicEvaluatedExpression[]} items expressions to set + * @returns {this} this + */ setItems(items) { this.type = TypeArray; this.items = items; @@ -386,6 +467,11 @@ class BasicEvaluatedExpression { return this; } + /** + * Set's the value of this expression to an array of strings. + * @param {string[]} array array to set + * @returns {this} this + */ setArray(array) { this.type = TypeConstArray; this.array = array; @@ -393,6 +479,14 @@ class BasicEvaluatedExpression { return this; } + /** + * Set's the value of this expression to a processed/unprocessed template string. Used + * for evaluating TemplateLiteral expressions in the JavaScript Parser. + * @param {BasicEvaluatedExpression[]} quasis template string quasis + * @param {BasicEvaluatedExpression[]} parts template string parts + * @param {"cooked" | "raw"} kind template string kind + * @returns {this} this + */ setTemplateString(quasis, parts, kind) { this.type = TypeTemplateString; this.quasis = quasis; @@ -415,21 +509,44 @@ class BasicEvaluatedExpression { return this; } + /** + * Set's the value of the expression to nullish. + * @param {boolean} value true, if the expression is nullish + * @returns {this} this + */ setNullish(value) { this.nullish = value; + + if (value) return this.setFalsy(); + return this; } + /** + * Set's the range for the expression. + * @param {[number, number]} range range to set + * @returns {this} this + */ setRange(range) { this.range = range; return this; } + /** + * Set whether or not the expression has side effects. + * @param {boolean} sideEffects true, if the expression has side effects + * @returns {this} this + */ setSideEffects(sideEffects = true) { this.sideEffects = sideEffects; return this; } + /** + * Set the expression node for the expression. + * @param {Node | undefined} expression expression + * @returns {this} this + */ setExpression(expression) { this.expression = expression; return this; diff --git a/lib/javascript/ChunkHelpers.js b/lib/javascript/ChunkHelpers.js new file mode 100644 index 00000000000..f2e8a12a996 --- /dev/null +++ b/lib/javascript/ChunkHelpers.js @@ -0,0 +1,33 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ + +"use strict"; + +const Entrypoint = require("../Entrypoint"); + +/** @typedef {import("../Chunk")} Chunk */ + +/** + * @param {Entrypoint} entrypoint a chunk group + * @param {(Chunk | null)=} excludedChunk1 current chunk which is excluded + * @param {(Chunk | null)=} excludedChunk2 runtime chunk which is excluded + * @returns {Set} chunks + */ +const getAllChunks = (entrypoint, excludedChunk1, excludedChunk2) => { + const queue = new Set([entrypoint]); + const chunks = new Set(); + for (const entrypoint of queue) { + for (const chunk of entrypoint.chunks) { + if (chunk === excludedChunk1) continue; + if (chunk === excludedChunk2) continue; + chunks.add(chunk); + } + for (const parent of entrypoint.parentsIterable) { + if (parent instanceof Entrypoint) queue.add(parent); + } + } + return chunks; +}; +module.exports.getAllChunks = getAllChunks; diff --git a/lib/javascript/CommonJsChunkFormatPlugin.js b/lib/javascript/CommonJsChunkFormatPlugin.js index e6a32a097b5..75384ab9a50 100644 --- a/lib/javascript/CommonJsChunkFormatPlugin.js +++ b/lib/javascript/CommonJsChunkFormatPlugin.js @@ -8,6 +8,7 @@ const { ConcatSource, RawSource } = require("webpack-sources"); const RuntimeGlobals = require("../RuntimeGlobals"); const Template = require("../Template"); +const { getUndoPath } = require("../util/identifier"); const { getChunkFilenameTemplate, getCompilationHooks @@ -17,7 +18,9 @@ const { updateHashForEntryStartup } = require("./StartupHelpers"); +/** @typedef {import("../Chunk")} Chunk */ /** @typedef {import("../Compiler")} Compiler */ +/** @typedef {import("../Entrypoint")} Entrypoint */ class CommonJsChunkFormatPlugin { /** @@ -30,10 +33,10 @@ class CommonJsChunkFormatPlugin { "CommonJsChunkFormatPlugin", compilation => { compilation.hooks.additionalChunkRuntimeRequirements.tap( - "CommonJsChunkLoadingPlugin", - (chunk, set) => { + "CommonJsChunkFormatPlugin", + (chunk, set, { chunkGraph }) => { if (chunk.hasRuntime()) return; - if (compilation.chunkGraph.getNumberOfEntryModules(chunk) > 0) { + if (chunkGraph.getNumberOfEntryModules(chunk) > 0) { set.add(RuntimeGlobals.require); set.add(RuntimeGlobals.startupEntrypoint); set.add(RuntimeGlobals.externalInstallChunk); @@ -48,12 +51,11 @@ class CommonJsChunkFormatPlugin { const source = new ConcatSource(); source.add(`exports.id = ${JSON.stringify(chunk.id)};\n`); source.add(`exports.ids = ${JSON.stringify(chunk.ids)};\n`); - source.add(`exports.modules = `); + source.add("exports.modules = "); source.add(modules); source.add(";\n"); - const runtimeModules = chunkGraph.getChunkRuntimeModulesInOrder( - chunk - ); + const runtimeModules = + chunkGraph.getChunkRuntimeModulesInOrder(chunk); if (runtimeModules.length > 0) { source.add("exports.runtime =\n"); source.add( @@ -67,7 +69,9 @@ class CommonJsChunkFormatPlugin { chunkGraph.getChunkEntryModulesWithChunkGroupIterable(chunk) ); if (entries.length > 0) { - const runtimeChunk = entries[0][1].getRuntimeChunk(); + const runtimeChunk = + /** @type {Entrypoint} */ + (entries[0][1]).getRuntimeChunk(); const currentOutputName = compilation .getPath( getChunkFilenameTemplate(chunk, compilation.outputOptions), @@ -76,38 +80,36 @@ class CommonJsChunkFormatPlugin { contentHashType: "javascript" } ) + .replace(/^\/+/g, "") .split("/"); const runtimeOutputName = compilation .getPath( getChunkFilenameTemplate( - runtimeChunk, + /** @type {Chunk} */ + (runtimeChunk), compilation.outputOptions ), { - chunk: runtimeChunk, + chunk: /** @type {Chunk} */ (runtimeChunk), contentHashType: "javascript" } ) + .replace(/^\/+/g, "") .split("/"); - // remove filename, we only need the directory - currentOutputName.pop(); - // remove common parts while ( - currentOutputName.length > 0 && - runtimeOutputName.length > 0 && + currentOutputName.length > 1 && + runtimeOutputName.length > 1 && currentOutputName[0] === runtimeOutputName[0] ) { currentOutputName.shift(); runtimeOutputName.shift(); } - + const last = runtimeOutputName.join("/"); // create final path const runtimePath = - (currentOutputName.length > 0 - ? "../".repeat(currentOutputName.length) - : "./") + runtimeOutputName.join("/"); + getUndoPath(currentOutputName.join("/"), last, true) + last; const entrySource = new ConcatSource(); entrySource.add( @@ -121,7 +123,7 @@ class CommonJsChunkFormatPlugin { entrySource.add(source); entrySource.add(";\n\n// load runtime\n"); entrySource.add( - `var __webpack_require__ = require(${JSON.stringify( + `var ${RuntimeGlobals.require} = require(${JSON.stringify( runtimePath )});\n` ); diff --git a/lib/javascript/EnableChunkLoadingPlugin.js b/lib/javascript/EnableChunkLoadingPlugin.js index b1e53df068c..0dc08a38099 100644 --- a/lib/javascript/EnableChunkLoadingPlugin.js +++ b/lib/javascript/EnableChunkLoadingPlugin.js @@ -11,6 +11,10 @@ /** @type {WeakMap>} */ const enabledTypes = new WeakMap(); +/** + * @param {Compiler} compiler compiler + * @returns {Set} enabled types + */ const getEnabledTypes = compiler => { let set = enabledTypes.get(compiler); if (set === undefined) { @@ -47,10 +51,11 @@ class EnableChunkLoadingPlugin { throw new Error( `Chunk loading type "${type}" is not enabled. ` + "EnableChunkLoadingPlugin need to be used to enable this type of chunk loading. " + - 'This usually happens through the "output.enabledChunkLoadingTypes" option. ' + - 'If you are using a function as entry which sets "chunkLoading", you need to add all potential chunk loading types to "output.enabledChunkLoadingTypes". ' + - "These types are enabled: " + - Array.from(getEnabledTypes(compiler)).join(", ") + `This usually happens through the "output.enabledChunkLoadingTypes" option. ` + + `If you are using a function as entry which sets "chunkLoading", you need to add all potential chunk loading types to "output.enabledChunkLoadingTypes". ` + + `These types are enabled: ${Array.from( + getEnabledTypes(compiler) + ).join(", ")}` ); } } @@ -81,7 +86,7 @@ class EnableChunkLoadingPlugin { break; } case "require": { - //@ts-expect-error https://github.com/microsoft/TypeScript/issues/41697 + // @ts-expect-error https://github.com/microsoft/TypeScript/issues/41697 const CommonJsChunkLoadingPlugin = require("../node/CommonJsChunkLoadingPlugin"); new CommonJsChunkLoadingPlugin({ asyncChunkLoading: false @@ -89,16 +94,18 @@ class EnableChunkLoadingPlugin { break; } case "async-node": { - //@ts-expect-error https://github.com/microsoft/TypeScript/issues/41697 + // @ts-expect-error https://github.com/microsoft/TypeScript/issues/41697 const CommonJsChunkLoadingPlugin = require("../node/CommonJsChunkLoadingPlugin"); new CommonJsChunkLoadingPlugin({ asyncChunkLoading: true }).apply(compiler); break; } - case "import": - // TODO implement import chunk loading - throw new Error("Chunk Loading via import() is not implemented yet"); + case "import": { + const ModuleChunkLoadingPlugin = require("../esm/ModuleChunkLoadingPlugin"); + new ModuleChunkLoadingPlugin().apply(compiler); + break; + } case "universal": // TODO implement universal chunk loading throw new Error("Universal Chunk Loading is not implemented yet"); diff --git a/lib/javascript/JavascriptGenerator.js b/lib/javascript/JavascriptGenerator.js index 8388b1ded15..b154a60b35c 100644 --- a/lib/javascript/JavascriptGenerator.js +++ b/lib/javascript/JavascriptGenerator.js @@ -14,6 +14,8 @@ const HarmonyCompatibilityDependency = require("../dependencies/HarmonyCompatibi /** @typedef {import("webpack-sources").Source} Source */ /** @typedef {import("../DependenciesBlock")} DependenciesBlock */ /** @typedef {import("../Dependency")} Dependency */ +/** @typedef {import("../DependencyTemplate")} DependencyTemplate */ +/** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */ /** @typedef {import("../DependencyTemplates")} DependencyTemplates */ /** @typedef {import("../Generator").GenerateContext} GenerateContext */ /** @typedef {import("../Module")} Module */ @@ -25,8 +27,15 @@ const HarmonyCompatibilityDependency = require("../dependencies/HarmonyCompatibi // replace with newer constructs const deprecatedGetInitFragments = util.deprecate( + /** + * @param {DependencyTemplate} template template + * @param {Dependency} dependency dependency + * @param {DependencyTemplateContext} templateContext template context + * @returns {InitFragment[]} init fragments + */ (template, dependency, templateContext) => - template.getInitFragments(dependency, templateContext), + /** @type {DependencyTemplate & { getInitFragments: function(Dependency, DependencyTemplateContext): InitFragment[] }} */ + (template).getInitFragments(dependency, templateContext), "DependencyTemplate.getInitFragment is deprecated (use apply(dep, source, { initFragments }) instead)", "DEP_WEBPACK_JAVASCRIPT_GENERATOR_GET_INIT_FRAGMENTS" ); @@ -93,6 +102,7 @@ class JavascriptGenerator extends Generator { } const source = new ReplaceSource(originalSource); + /** @type {InitFragment[]} */ const initFragments = []; this.sourceModule(module, initFragments, source, generateContext); @@ -102,7 +112,7 @@ class JavascriptGenerator extends Generator { /** * @param {Module} module the module to generate - * @param {InitFragment[]} initFragments mutable list of init fragments + * @param {InitFragment[]} initFragments mutable list of init fragments * @param {ReplaceSource} source the current replace source which can be modified * @param {GenerateContext} generateContext the generateContext * @returns {void} @@ -144,7 +154,7 @@ class JavascriptGenerator extends Generator { /** * @param {Module} module the module to generate * @param {DependenciesBlock} block the dependencies block which will be processed - * @param {InitFragment[]} initFragments mutable list of init fragments + * @param {InitFragment[]} initFragments mutable list of init fragments * @param {ReplaceSource} source the current replace source which can be modified * @param {GenerateContext} generateContext the generateContext * @returns {void} @@ -174,20 +184,26 @@ class JavascriptGenerator extends Generator { /** * @param {Module} module the current module * @param {Dependency} dependency the dependency to generate - * @param {InitFragment[]} initFragments mutable list of init fragments + * @param {InitFragment[]} initFragments mutable list of init fragments * @param {ReplaceSource} source the current replace source which can be modified * @param {GenerateContext} generateContext the render context * @returns {void} */ sourceDependency(module, dependency, initFragments, source, generateContext) { - const constructor = /** @type {new (...args: any[]) => Dependency} */ (dependency.constructor); + const constructor = /** @type {new (...args: any[]) => Dependency} */ ( + dependency.constructor + ); const template = generateContext.dependencyTemplates.get(constructor); if (!template) { throw new Error( - "No template for dependency: " + dependency.constructor.name + `No template for dependency: ${dependency.constructor.name}` ); } + /** @type {InitFragment[] | undefined} */ + let chunkInitFragments; + + /** @type {DependencyTemplateContext} */ const templateContext = { runtimeTemplate: generateContext.runtimeTemplate, dependencyTemplates: generateContext.dependencyTemplates, @@ -197,7 +213,24 @@ class JavascriptGenerator extends Generator { runtime: generateContext.runtime, runtimeRequirements: generateContext.runtimeRequirements, concatenationScope: generateContext.concatenationScope, - initFragments + codeGenerationResults: + /** @type {NonNullable} */ + (generateContext.codeGenerationResults), + initFragments, + get chunkInitFragments() { + if (!chunkInitFragments) { + const data = + /** @type {NonNullable} */ + (generateContext.getData)(); + chunkInitFragments = data.get("chunkInitFragments"); + if (!chunkInitFragments) { + chunkInitFragments = []; + data.set("chunkInitFragments", chunkInitFragments); + } + } + + return chunkInitFragments; + } }; template.apply(dependency, source, templateContext); diff --git a/lib/javascript/JavascriptModulesPlugin.js b/lib/javascript/JavascriptModulesPlugin.js index c26bd660440..da4a17bd118 100644 --- a/lib/javascript/JavascriptModulesPlugin.js +++ b/lib/javascript/JavascriptModulesPlugin.js @@ -5,37 +5,56 @@ "use strict"; +const eslintScope = require("eslint-scope"); const { SyncWaterfallHook, SyncHook, SyncBailHook } = require("tapable"); +const vm = require("vm"); const { ConcatSource, OriginalSource, PrefixSource, RawSource, - CachedSource + CachedSource, + ReplaceSource } = require("webpack-sources"); const Compilation = require("../Compilation"); const { tryRunOrWebpackError } = require("../HookWebpackError"); const HotUpdateChunk = require("../HotUpdateChunk"); +const InitFragment = require("../InitFragment"); +const { + JAVASCRIPT_MODULE_TYPE_AUTO, + JAVASCRIPT_MODULE_TYPE_DYNAMIC, + JAVASCRIPT_MODULE_TYPE_ESM, + WEBPACK_MODULE_TYPE_RUNTIME +} = require("../ModuleTypeConstants"); const RuntimeGlobals = require("../RuntimeGlobals"); const Template = require("../Template"); const { last, someInIterable } = require("../util/IterableHelpers"); const StringXor = require("../util/StringXor"); const { compareModulesByIdentifier } = require("../util/comparators"); const createHash = require("../util/createHash"); +const { getPathInAst, getAllReferences } = require("../util/mergeScope"); +const nonNumericOnlyHash = require("../util/nonNumericOnlyHash"); const { intersectRuntime } = require("../util/runtime"); const JavascriptGenerator = require("./JavascriptGenerator"); const JavascriptParser = require("./JavascriptParser"); +/** @typedef {import("eslint-scope").Scope} Scope */ +/** @typedef {import("eslint-scope").Variable} Variable */ /** @typedef {import("webpack-sources").Source} Source */ +/** @typedef {import("../../declarations/WebpackOptions").Output} OutputOptions */ /** @typedef {import("../Chunk")} Chunk */ /** @typedef {import("../ChunkGraph")} ChunkGraph */ /** @typedef {import("../CodeGenerationResults")} CodeGenerationResults */ /** @typedef {import("../Compilation").ChunkHashContext} ChunkHashContext */ /** @typedef {import("../Compiler")} Compiler */ /** @typedef {import("../DependencyTemplates")} DependencyTemplates */ +/** @typedef {import("../Entrypoint")} Entrypoint */ /** @typedef {import("../Module")} Module */ +/** @typedef {import("../Module").BuildInfo} BuildInfo */ /** @typedef {import("../ModuleGraph")} ModuleGraph */ /** @typedef {import("../RuntimeTemplate")} RuntimeTemplate */ +/** @typedef {import("../TemplatedPathPlugin").TemplatePath} TemplatePath */ +/** @typedef {import("../javascript/JavascriptParser").Range} Range */ /** @typedef {import("../util/Hash")} Hash */ /** @@ -46,23 +65,48 @@ const JavascriptParser = require("./JavascriptParser"); const chunkHasJs = (chunk, chunkGraph) => { if (chunkGraph.getNumberOfEntryModules(chunk) > 0) return true; - return chunkGraph.getChunkModulesIterableBySourceType(chunk, "javascript") - ? true - : false; + return Boolean( + chunkGraph.getChunkModulesIterableBySourceType(chunk, "javascript") + ); +}; + +/** + * @param {Module} module a module + * @param {string} code the code + * @returns {string} generated code for the stack + */ +const printGeneratedCodeForStack = (module, code) => { + const lines = code.split("\n"); + const n = `${lines.length}`.length; + return `\n\nGenerated code for ${module.identifier()}\n${lines + .map( + /** + * @param {string} line the line + * @param {number} i the index + * @param {string[]} lines the lines + * @returns {string} the line with line number + */ + (line, i, lines) => { + const iStr = `${i + 1}`; + return `${" ".repeat(n - iStr.length)}${iStr} | ${line}`; + } + ) + .join("\n")}`; }; /** - * @typedef {Object} RenderContext + * @typedef {object} RenderContext * @property {Chunk} chunk the chunk * @property {DependencyTemplates} dependencyTemplates the dependency templates * @property {RuntimeTemplate} runtimeTemplate the runtime template * @property {ModuleGraph} moduleGraph the module graph * @property {ChunkGraph} chunkGraph the chunk graph * @property {CodeGenerationResults} codeGenerationResults results of code generation + * @property {boolean | undefined} strictMode rendering in strict context */ /** - * @typedef {Object} MainRenderContext + * @typedef {object} MainRenderContext * @property {Chunk} chunk the chunk * @property {DependencyTemplates} dependencyTemplates the dependency templates * @property {RuntimeTemplate} runtimeTemplate the runtime template @@ -70,11 +114,25 @@ const chunkHasJs = (chunk, chunkGraph) => { * @property {ChunkGraph} chunkGraph the chunk graph * @property {CodeGenerationResults} codeGenerationResults results of code generation * @property {string} hash hash to be used for render call + * @property {boolean | undefined} strictMode rendering in strict context + */ + +/** + * @typedef {object} ChunkRenderContext + * @property {Chunk} chunk the chunk + * @property {DependencyTemplates} dependencyTemplates the dependency templates + * @property {RuntimeTemplate} runtimeTemplate the runtime template + * @property {ModuleGraph} moduleGraph the module graph + * @property {ChunkGraph} chunkGraph the chunk graph + * @property {CodeGenerationResults} codeGenerationResults results of code generation + * @property {InitFragment[]} chunkInitFragments init fragments for the chunk + * @property {boolean | undefined} strictMode rendering in strict context */ /** - * @typedef {Object} RenderBootstrapContext + * @typedef {object} RenderBootstrapContext * @property {Chunk} chunk the chunk + * @property {CodeGenerationResults} codeGenerationResults results of code generation * @property {RuntimeTemplate} runtimeTemplate the runtime template * @property {ModuleGraph} moduleGraph the module graph * @property {ChunkGraph} chunkGraph the chunk graph @@ -84,18 +142,19 @@ const chunkHasJs = (chunk, chunkGraph) => { /** @typedef {RenderContext & { inlined: boolean }} StartupRenderContext */ /** - * @typedef {Object} CompilationHooks - * @property {SyncWaterfallHook<[Source, Module, RenderContext]>} renderModuleContent - * @property {SyncWaterfallHook<[Source, Module, RenderContext]>} renderModuleContainer - * @property {SyncWaterfallHook<[Source, Module, RenderContext]>} renderModulePackage + * @typedef {object} CompilationHooks + * @property {SyncWaterfallHook<[Source, Module, ChunkRenderContext]>} renderModuleContent + * @property {SyncWaterfallHook<[Source, Module, ChunkRenderContext]>} renderModuleContainer + * @property {SyncWaterfallHook<[Source, Module, ChunkRenderContext]>} renderModulePackage * @property {SyncWaterfallHook<[Source, RenderContext]>} renderChunk * @property {SyncWaterfallHook<[Source, RenderContext]>} renderMain + * @property {SyncWaterfallHook<[Source, RenderContext]>} renderContent * @property {SyncWaterfallHook<[Source, RenderContext]>} render * @property {SyncWaterfallHook<[Source, Module, StartupRenderContext]>} renderStartup * @property {SyncWaterfallHook<[string, RenderBootstrapContext]>} renderRequire * @property {SyncBailHook<[Module, RenderBootstrapContext], string>} inlineInRuntimeBailout - * @property {SyncBailHook<[Module, RenderContext], string>} embedInRuntimeBailout - * @property {SyncBailHook<[RenderContext], string>} strictRuntimeBailout + * @property {SyncBailHook<[Module, RenderContext], string | void>} embedInRuntimeBailout + * @property {SyncBailHook<[RenderContext], string | void>} strictRuntimeBailout * @property {SyncHook<[Chunk, Hash, ChunkHashContext]>} chunkHash * @property {SyncBailHook<[Chunk, RenderContext], boolean>} useSourceMap */ @@ -103,6 +162,10 @@ const chunkHasJs = (chunk, chunkGraph) => { /** @type {WeakMap} */ const compilationHooksMap = new WeakMap(); +const PLUGIN_NAME = "JavascriptModulesPlugin"; + +/** @typedef {{ header: string[], beforeStartup: string[], startup: string[], afterStartup: string[], allowInlineStartup: boolean }} Bootstrap */ + class JavascriptModulesPlugin { /** * @param {Compilation} compilation the compilation @@ -133,6 +196,7 @@ class JavascriptModulesPlugin { "renderContext" ]), render: new SyncWaterfallHook(["source", "renderContext"]), + renderContent: new SyncWaterfallHook(["source", "renderContext"]), renderStartup: new SyncWaterfallHook([ "source", "module", @@ -165,151 +229,138 @@ class JavascriptModulesPlugin { */ apply(compiler) { compiler.hooks.compilation.tap( - "JavascriptModulesPlugin", + PLUGIN_NAME, (compilation, { normalModuleFactory }) => { const hooks = JavascriptModulesPlugin.getCompilationHooks(compilation); normalModuleFactory.hooks.createParser - .for("javascript/auto") - .tap("JavascriptModulesPlugin", options => { - return new JavascriptParser("auto"); - }); + .for(JAVASCRIPT_MODULE_TYPE_AUTO) + .tap(PLUGIN_NAME, options => new JavascriptParser("auto")); normalModuleFactory.hooks.createParser - .for("javascript/dynamic") - .tap("JavascriptModulesPlugin", options => { - return new JavascriptParser("script"); - }); + .for(JAVASCRIPT_MODULE_TYPE_DYNAMIC) + .tap(PLUGIN_NAME, options => new JavascriptParser("script")); normalModuleFactory.hooks.createParser - .for("javascript/esm") - .tap("JavascriptModulesPlugin", options => { - return new JavascriptParser("module"); - }); + .for(JAVASCRIPT_MODULE_TYPE_ESM) + .tap(PLUGIN_NAME, options => new JavascriptParser("module")); normalModuleFactory.hooks.createGenerator - .for("javascript/auto") - .tap("JavascriptModulesPlugin", () => { - return new JavascriptGenerator(); - }); + .for(JAVASCRIPT_MODULE_TYPE_AUTO) + .tap(PLUGIN_NAME, () => new JavascriptGenerator()); normalModuleFactory.hooks.createGenerator - .for("javascript/dynamic") - .tap("JavascriptModulesPlugin", () => { - return new JavascriptGenerator(); - }); + .for(JAVASCRIPT_MODULE_TYPE_DYNAMIC) + .tap(PLUGIN_NAME, () => new JavascriptGenerator()); normalModuleFactory.hooks.createGenerator - .for("javascript/esm") - .tap("JavascriptModulesPlugin", () => { - return new JavascriptGenerator(); - }); - compilation.hooks.renderManifest.tap( - "JavascriptModulesPlugin", - (result, options) => { - const { - hash, - chunk, - chunkGraph, - moduleGraph, - runtimeTemplate, - dependencyTemplates, - outputOptions, - codeGenerationResults - } = options; - - const hotUpdateChunk = - chunk instanceof HotUpdateChunk ? chunk : null; - - let render; - const filenameTemplate = JavascriptModulesPlugin.getChunkFilenameTemplate( + .for(JAVASCRIPT_MODULE_TYPE_ESM) + .tap(PLUGIN_NAME, () => new JavascriptGenerator()); + compilation.hooks.renderManifest.tap(PLUGIN_NAME, (result, options) => { + const { + hash, + chunk, + chunkGraph, + moduleGraph, + runtimeTemplate, + dependencyTemplates, + outputOptions, + codeGenerationResults + } = options; + + const hotUpdateChunk = chunk instanceof HotUpdateChunk ? chunk : null; + + let render; + const filenameTemplate = + JavascriptModulesPlugin.getChunkFilenameTemplate( chunk, outputOptions ); - if (hotUpdateChunk) { - render = () => - this.renderChunk( - { - chunk, - dependencyTemplates, - runtimeTemplate, - moduleGraph, - chunkGraph, - codeGenerationResults - }, - hooks - ); - } else if (chunk.hasRuntime()) { - render = () => - this.renderMain( - { - hash, - chunk, - dependencyTemplates, - runtimeTemplate, - moduleGraph, - chunkGraph, - codeGenerationResults - }, - hooks, - compilation - ); - } else { - if (!chunkHasJs(chunk, chunkGraph)) { - return result; - } - - render = () => - this.renderChunk( - { - chunk, - dependencyTemplates, - runtimeTemplate, - moduleGraph, - chunkGraph, - codeGenerationResults - }, - hooks - ); + if (hotUpdateChunk) { + render = () => + this.renderChunk( + { + chunk, + dependencyTemplates, + runtimeTemplate, + moduleGraph, + chunkGraph, + codeGenerationResults, + strictMode: runtimeTemplate.isModule() + }, + hooks + ); + } else if (chunk.hasRuntime()) { + render = () => + this.renderMain( + { + hash, + chunk, + dependencyTemplates, + runtimeTemplate, + moduleGraph, + chunkGraph, + codeGenerationResults, + strictMode: runtimeTemplate.isModule() + }, + hooks, + compilation + ); + } else { + if (!chunkHasJs(chunk, chunkGraph)) { + return result; } - result.push({ - render, - filenameTemplate, - pathOptions: { - hash, - runtime: chunk.runtime, - chunk, - contentHashType: "javascript" - }, - info: { - javascriptModule: compilation.runtimeTemplate.isModule() - }, - identifier: hotUpdateChunk - ? `hotupdatechunk${chunk.id}` - : `chunk${chunk.id}`, - hash: chunk.contentHash.javascript - }); - - return result; - } - ); - compilation.hooks.chunkHash.tap( - "JavascriptModulesPlugin", - (chunk, hash, context) => { - hooks.chunkHash.call(chunk, hash, context); - if (chunk.hasRuntime()) { - this.updateHashWithBootstrap( - hash, + render = () => + this.renderChunk( { - hash: "0000", chunk, - chunkGraph: context.chunkGraph, - moduleGraph: context.moduleGraph, - runtimeTemplate: context.runtimeTemplate + dependencyTemplates, + runtimeTemplate, + moduleGraph, + chunkGraph, + codeGenerationResults, + strictMode: runtimeTemplate.isModule() }, hooks ); - } } - ); - compilation.hooks.contentHash.tap("JavascriptModulesPlugin", chunk => { + + result.push({ + render, + filenameTemplate, + pathOptions: { + hash, + runtime: chunk.runtime, + chunk, + contentHashType: "javascript" + }, + info: { + javascriptModule: compilation.runtimeTemplate.isModule() + }, + identifier: hotUpdateChunk + ? `hotupdatechunk${chunk.id}` + : `chunk${chunk.id}`, + hash: chunk.contentHash.javascript + }); + + return result; + }); + compilation.hooks.chunkHash.tap(PLUGIN_NAME, (chunk, hash, context) => { + hooks.chunkHash.call(chunk, hash, context); + if (chunk.hasRuntime()) { + this.updateHashWithBootstrap( + hash, + { + hash: "0000", + chunk, + codeGenerationResults: context.codeGenerationResults, + chunkGraph: context.chunkGraph, + moduleGraph: context.moduleGraph, + runtimeTemplate: context.runtimeTemplate + }, + hooks + ); + } + }); + compilation.hooks.contentHash.tap(PLUGIN_NAME, chunk => { const { chunkGraph, + codeGenerationResults, moduleGraph, runtimeTemplate, outputOptions: { @@ -327,6 +378,7 @@ class JavascriptModulesPlugin { { hash: "0000", chunk, + codeGenerationResults, chunkGraph: compilation.chunkGraph, moduleGraph: compilation.moduleGraph, runtimeTemplate: compilation.runtimeTemplate @@ -339,6 +391,7 @@ class JavascriptModulesPlugin { } hooks.chunkHash.call(chunk, hash, { chunkGraph, + codeGenerationResults, moduleGraph, runtimeTemplate }); @@ -355,7 +408,7 @@ class JavascriptModulesPlugin { } const runtimeModules = chunkGraph.getChunkModulesIterableBySourceType( chunk, - "runtime" + WEBPACK_MODULE_TYPE_RUNTIME ); if (runtimeModules) { const xor = new StringXor(); @@ -365,57 +418,121 @@ class JavascriptModulesPlugin { xor.updateHash(hash); } const digest = /** @type {string} */ (hash.digest(hashDigest)); - chunk.contentHash.javascript = digest.substr(0, hashDigestLength); + chunk.contentHash.javascript = nonNumericOnlyHash( + digest, + hashDigestLength + ); }); compilation.hooks.additionalTreeRuntimeRequirements.tap( - "JavascriptModulesPlugin", - (chunk, set) => { + PLUGIN_NAME, + (chunk, set, { chunkGraph }) => { if ( !set.has(RuntimeGlobals.startupNoDefault) && - compilation.chunkGraph.hasChunkEntryDependentChunks(chunk) + chunkGraph.hasChunkEntryDependentChunks(chunk) ) { set.add(RuntimeGlobals.onChunksLoaded); + set.add(RuntimeGlobals.exports); set.add(RuntimeGlobals.require); } } ); + compilation.hooks.executeModule.tap(PLUGIN_NAME, (options, context) => { + const source = options.codeGenerationResult.sources.get("javascript"); + if (source === undefined) return; + const { module, moduleObject } = options; + const code = source.source(); + + const fn = vm.runInThisContext( + `(function(${module.moduleArgument}, ${module.exportsArgument}, ${RuntimeGlobals.require}) {\n${code}\n/**/})`, + { + filename: module.identifier(), + lineOffset: -1 + } + ); + try { + fn.call( + moduleObject.exports, + moduleObject, + moduleObject.exports, + context.__webpack_require__ + ); + } catch (err) { + /** @type {Error} */ + (err).stack += printGeneratedCodeForStack( + options.module, + /** @type {string} */ (code) + ); + throw err; + } + }); + compilation.hooks.executeModule.tap(PLUGIN_NAME, (options, context) => { + const source = options.codeGenerationResult.sources.get("runtime"); + if (source === undefined) return; + let code = source.source(); + if (typeof code !== "string") code = code.toString(); + + const fn = vm.runInThisContext( + `(function(${RuntimeGlobals.require}) {\n${code}\n/**/})`, + { + filename: options.module.identifier(), + lineOffset: -1 + } + ); + try { + // eslint-disable-next-line no-useless-call + fn.call(null, context.__webpack_require__); + } catch (err) { + /** @type {Error} */ + (err).stack += printGeneratedCodeForStack(options.module, code); + throw err; + } + }); } ); } + /** + * @param {Chunk} chunk chunk + * @param {OutputOptions} outputOptions output options + * @returns {TemplatePath} used filename template + */ static getChunkFilenameTemplate(chunk, outputOptions) { if (chunk.filenameTemplate) { return chunk.filenameTemplate; } else if (chunk instanceof HotUpdateChunk) { - return outputOptions.hotUpdateChunkFilename; + return /** @type {TemplatePath} */ (outputOptions.hotUpdateChunkFilename); } else if (chunk.canBeInitial()) { - return outputOptions.filename; - } else { - return outputOptions.chunkFilename; + return /** @type {TemplatePath} */ (outputOptions.filename); } + return /** @type {TemplatePath} */ (outputOptions.chunkFilename); } /** * @param {Module} module the rendered module - * @param {RenderContext} renderContext options object + * @param {ChunkRenderContext} renderContext options object * @param {CompilationHooks} hooks hooks - * @param {boolean | "strict"} factory true: renders as factory method, "strict": renders as factory method already in strict scope, false: pure module content - * @returns {Source} the newly generated source from rendering + * @param {boolean} factory true: renders as factory method, false: pure module content + * @returns {Source | null} the newly generated source from rendering */ renderModule(module, renderContext, hooks, factory) { const { chunk, chunkGraph, runtimeTemplate, - codeGenerationResults + codeGenerationResults, + strictMode } = renderContext; try { - const moduleSource = codeGenerationResults.getSource( - module, - chunk.runtime, - "javascript" - ); + const codeGenResult = codeGenerationResults.get(module, chunk.runtime); + const moduleSource = codeGenResult.sources.get("javascript"); if (!moduleSource) return null; + if (codeGenResult.data !== undefined) { + const chunkInitFragments = codeGenResult.data.get("chunkInitFragments"); + if (chunkInitFragments) { + for (const i of chunkInitFragments) + renderContext.chunkInitFragments.push(i); + } + } const moduleSourcePostContent = tryRunOrWebpackError( () => hooks.renderModuleContent.call(moduleSource, module, renderContext), @@ -435,7 +552,9 @@ class JavascriptModulesPlugin { const needThisAsExports = runtimeRequirements.has( RuntimeGlobals.thisAsExports ); - const needStrict = module.buildInfo.strict && factory !== "strict"; + const needStrict = + /** @type {BuildInfo} */ + (module.buildInfo).strict && !strictMode; const cacheEntry = this._moduleFactoryCache.get( moduleSourcePostContent ); @@ -456,19 +575,19 @@ class JavascriptModulesPlugin { args.push( needModule ? module.moduleArgument - : "__unused_webpack_" + module.moduleArgument + : `__unused_webpack_${module.moduleArgument}` ); if (needExports || needRequire) args.push( needExports ? module.exportsArgument - : "__unused_webpack_" + module.exportsArgument + : `__unused_webpack_${module.exportsArgument}` ); - if (needRequire) args.push("__webpack_require__"); + if (needRequire) args.push(RuntimeGlobals.require); if (!needThisAsExports && runtimeTemplate.supportsArrowFunction()) { - factorySource.add("/***/ ((" + args.join(", ") + ") => {\n\n"); + factorySource.add(`/***/ ((${args.join(", ")}) => {\n\n`); } else { - factorySource.add("/***/ (function(" + args.join(", ") + ") {\n\n"); + factorySource.add(`/***/ (function(${args.join(", ")}) {\n\n`); } if (needStrict) { factorySource.add('"use strict";\n'); @@ -501,9 +620,9 @@ class JavascriptModulesPlugin { ), "JavascriptModulesPlugin.getCompilationHooks().renderModulePackage" ); - } catch (e) { - e.module = module; - throw e; + } catch (err) { + err.module = module; + throw err; } } @@ -519,22 +638,62 @@ class JavascriptModulesPlugin { "javascript", compareModulesByIdentifier ); + const allModules = modules ? Array.from(modules) : []; + let strictHeader; + let allStrict = renderContext.strictMode; + if ( + !allStrict && + allModules.every(m => /** @type {BuildInfo} */ (m.buildInfo).strict) + ) { + const strictBailout = hooks.strictRuntimeBailout.call(renderContext); + strictHeader = strictBailout + ? `// runtime can't be in strict mode because ${strictBailout}.\n` + : '"use strict";\n'; + if (!strictBailout) allStrict = true; + } + /** @type {ChunkRenderContext} */ + const chunkRenderContext = { + ...renderContext, + chunkInitFragments: [], + strictMode: allStrict + }; const moduleSources = - Template.renderChunkModules( - renderContext, - modules ? Array.from(modules) : [], - module => this.renderModule(module, renderContext, hooks, true) + Template.renderChunkModules(chunkRenderContext, allModules, module => + this.renderModule(module, chunkRenderContext, hooks, true) ) || new RawSource("{}"); let source = tryRunOrWebpackError( - () => hooks.renderChunk.call(moduleSources, renderContext), + () => hooks.renderChunk.call(moduleSources, chunkRenderContext), "JavascriptModulesPlugin.getCompilationHooks().renderChunk" ); source = tryRunOrWebpackError( - () => hooks.render.call(source, renderContext), + () => hooks.renderContent.call(source, chunkRenderContext), + "JavascriptModulesPlugin.getCompilationHooks().renderContent" + ); + if (!source) { + throw new Error( + "JavascriptModulesPlugin error: JavascriptModulesPlugin.getCompilationHooks().renderContent plugins should return something" + ); + } + source = InitFragment.addToSource( + source, + chunkRenderContext.chunkInitFragments, + chunkRenderContext + ); + source = tryRunOrWebpackError( + () => hooks.render.call(source, chunkRenderContext), "JavascriptModulesPlugin.getCompilationHooks().render" ); + if (!source) { + throw new Error( + "JavascriptModulesPlugin error: JavascriptModulesPlugin.getCompilationHooks().render plugins should return something" + ); + } chunk.rendered = true; - return new ConcatSource(source, ";"); + return strictHeader + ? new ConcatSource(strictHeader, source, ";") + : renderContext.runtimeTemplate.isModule() + ? source + : new ConcatSource(source, ";"); } /** @@ -560,12 +719,14 @@ class JavascriptModulesPlugin { ) || [] ); + const hasEntryModules = chunkGraph.getNumberOfEntryModules(chunk) > 0; + /** @type {Set | undefined} */ let inlinedModules; - if (bootstrap.allowInlineStartup) { + if (bootstrap.allowInlineStartup && hasEntryModules) { inlinedModules = new Set(chunkGraph.getChunkEntryModulesIterable(chunk)); } - let source = new ConcatSource(); + const source = new ConcatSource(); let prefix; if (iife) { if (runtimeTemplate.supportsArrowFunction()) { @@ -577,40 +738,48 @@ class JavascriptModulesPlugin { } else { prefix = "/******/ "; } - let allStrict = false; - if (allModules.every(m => m.buildInfo.strict)) { + let allStrict = renderContext.strictMode; + if ( + !allStrict && + allModules.every(m => /** @type {BuildInfo} */ (m.buildInfo).strict) + ) { const strictBailout = hooks.strictRuntimeBailout.call(renderContext); if (strictBailout) { source.add( - prefix + - `// runtime can't be in strict mode because ${strictBailout}.\n` + `${ + prefix + }// runtime can't be in strict mode because ${strictBailout}.\n` ); } else { allStrict = true; - source.add(prefix + '"use strict";\n'); + source.add(`${prefix}"use strict";\n`); } } + /** @type {ChunkRenderContext} */ + const chunkRenderContext = { + ...renderContext, + chunkInitFragments: [], + strictMode: allStrict + }; + const chunkModules = Template.renderChunkModules( - renderContext, + chunkRenderContext, inlinedModules - ? allModules.filter(m => !inlinedModules.has(m)) + ? allModules.filter( + m => !(/** @type {Set} */ (inlinedModules).has(m)) + ) : allModules, - module => - this.renderModule( - module, - renderContext, - hooks, - allStrict ? "strict" : true - ), + module => this.renderModule(module, chunkRenderContext, hooks, true), prefix ); if ( chunkModules || runtimeRequirements.has(RuntimeGlobals.moduleFactories) || - runtimeRequirements.has(RuntimeGlobals.moduleFactoriesAddOnly) + runtimeRequirements.has(RuntimeGlobals.moduleFactoriesAddOnly) || + runtimeRequirements.has(RuntimeGlobals.require) ) { - source.add(prefix + "var __webpack_modules__ = ("); + source.add(`${prefix}var __webpack_modules__ = (`); source.add(chunkModules || "{}"); source.add(");\n"); source.add( @@ -619,7 +788,7 @@ class JavascriptModulesPlugin { } if (bootstrap.header.length > 0) { - const header = Template.asString(bootstrap.header) + "\n"; + const header = `${Template.asString(bootstrap.header)}\n`; source.add( new PrefixSource( prefix, @@ -633,15 +802,14 @@ class JavascriptModulesPlugin { ); } - const runtimeModules = renderContext.chunkGraph.getChunkRuntimeModulesInOrder( - chunk - ); + const runtimeModules = + renderContext.chunkGraph.getChunkRuntimeModulesInOrder(chunk); if (runtimeModules.length > 0) { source.add( new PrefixSource( prefix, - Template.renderRuntimeModules(runtimeModules, renderContext) + Template.renderRuntimeModules(runtimeModules, chunkRenderContext) ) ); source.add( @@ -654,7 +822,7 @@ class JavascriptModulesPlugin { } if (inlinedModules) { if (bootstrap.beforeStartup.length > 0) { - const beforeStartup = Template.asString(bootstrap.beforeStartup) + "\n"; + const beforeStartup = `${Template.asString(bootstrap.beforeStartup)}\n`; source.add( new PrefixSource( prefix, @@ -664,36 +832,45 @@ class JavascriptModulesPlugin { ) ); } - const lastInlinedModule = last(inlinedModules); + const lastInlinedModule = /** @type {Module} */ (last(inlinedModules)); const startupSource = new ConcatSource(); - startupSource.add(`var __webpack_exports__ = {};\n`); + + if (runtimeRequirements.has(RuntimeGlobals.exports)) { + startupSource.add(`var ${RuntimeGlobals.exports} = {};\n`); + } + + const renamedInlinedModule = this.renameInlineModule( + allModules, + renderContext, + inlinedModules, + chunkRenderContext, + hooks + ); + for (const m of inlinedModules) { - const renderedModule = this.renderModule( - m, - renderContext, - hooks, - false - ); + const renderedModule = + renamedInlinedModule.get(m) || + this.renderModule(m, chunkRenderContext, hooks, false); + if (renderedModule) { - const innerStrict = !allStrict && m.buildInfo.strict; + const innerStrict = + !allStrict && /** @type {BuildInfo} */ (m.buildInfo).strict; const runtimeRequirements = chunkGraph.getModuleRuntimeRequirements( m, chunk.runtime ); const exports = runtimeRequirements.has(RuntimeGlobals.exports); const webpackExports = - exports && m.exportsArgument === "__webpack_exports__"; - let iife = innerStrict + exports && m.exportsArgument === RuntimeGlobals.exports; + const iife = innerStrict ? "it need to be in strict mode." : inlinedModules.size > 1 - ? // TODO check globals and top-level declarations of other entries and chunk modules - // to make a better decision - "it need to be isolated against other entry modules." - : chunkModules - ? "it need to be isolated against other modules in the chunk." - : exports && !webpackExports - ? `it uses a non-standard name for the exports (${m.exportsArgument}).` - : hooks.embedInRuntimeBailout.call(m, renderContext); + ? // TODO check globals and top-level declarations of other entries and chunk modules + // to make a better decision + "it need to be isolated against other entry modules." + : exports && !webpackExports + ? `it uses a non-standard name for the exports (${m.exportsArgument}).` + : hooks.embedInRuntimeBailout.call(m, renderContext); let footer; if (iife !== undefined) { startupSource.add( @@ -714,9 +891,9 @@ class JavascriptModulesPlugin { if (exports) { if (m !== lastInlinedModule) startupSource.add(`var ${m.exportsArgument} = {};\n`); - else if (m.exportsArgument !== "__webpack_exports__") + else if (m.exportsArgument !== RuntimeGlobals.exports) startupSource.add( - `var ${m.exportsArgument} = __webpack_exports__;\n` + `var ${m.exportsArgument} = ${RuntimeGlobals.exports};\n` ); } startupSource.add(renderedModule); @@ -724,7 +901,9 @@ class JavascriptModulesPlugin { } } if (runtimeRequirements.has(RuntimeGlobals.onChunksLoaded)) { - startupSource.add(`${RuntimeGlobals.onChunksLoaded}();\n`); + startupSource.add( + `${RuntimeGlobals.exports} = ${RuntimeGlobals.onChunksLoaded}(${RuntimeGlobals.exports});\n` + ); } source.add( hooks.renderStartup.call(startupSource, lastInlinedModule, { @@ -733,7 +912,7 @@ class JavascriptModulesPlugin { }) ); if (bootstrap.afterStartup.length > 0) { - const afterStartup = Template.asString(bootstrap.afterStartup) + "\n"; + const afterStartup = `${Template.asString(bootstrap.afterStartup)}\n`; source.add( new PrefixSource( prefix, @@ -744,9 +923,10 @@ class JavascriptModulesPlugin { ); } } else { - const lastEntryModule = last( - chunkGraph.getChunkEntryModulesIterable(chunk) - ); + const lastEntryModule = + /** @type {Module} */ + (last(chunkGraph.getChunkEntryModulesIterable(chunk))); + /** @type {function(string[], string): Source} */ const toSource = useSourceMap ? (content, name) => new OriginalSource(Template.asString(content), name) @@ -771,8 +951,11 @@ class JavascriptModulesPlugin { ) ); } - if (runtimeRequirements.has(RuntimeGlobals.returnExportsFromRuntime)) { - source.add(`${prefix}return __webpack_exports__;\n`); + if ( + hasEntryModules && + runtimeRequirements.has(RuntimeGlobals.returnExportsFromRuntime) + ) { + source.add(`${prefix}return ${RuntimeGlobals.exports};\n`); } if (iife) { source.add("/******/ })()\n"); @@ -788,6 +971,21 @@ class JavascriptModulesPlugin { "JavascriptModulesPlugin error: JavascriptModulesPlugin.getCompilationHooks().renderMain plugins should return something" ); } + finalSource = tryRunOrWebpackError( + () => hooks.renderContent.call(finalSource, renderContext), + "JavascriptModulesPlugin.getCompilationHooks().renderContent" + ); + if (!finalSource) { + throw new Error( + "JavascriptModulesPlugin error: JavascriptModulesPlugin.getCompilationHooks().renderContent plugins should return something" + ); + } + + finalSource = InitFragment.addToSource( + finalSource, + chunkRenderContext.chunkInitFragments, + chunkRenderContext + ); finalSource = tryRunOrWebpackError( () => hooks.render.call(finalSource, renderContext), "JavascriptModulesPlugin.getCompilationHooks().render" @@ -808,7 +1006,8 @@ class JavascriptModulesPlugin { */ updateHashWithBootstrap(hash, renderContext, hooks) { const bootstrap = this.renderBootstrap(renderContext, hooks); - for (const key of Object.keys(bootstrap)) { + for (const _k of Object.keys(bootstrap)) { + const key = /** @type {keyof Bootstrap} */ (_k); hash.update(key); if (Array.isArray(bootstrap[key])) { for (const line of bootstrap[key]) { @@ -823,10 +1022,16 @@ class JavascriptModulesPlugin { /** * @param {RenderBootstrapContext} renderContext options object * @param {CompilationHooks} hooks hooks - * @returns {{ header: string[], beforeStartup: string[], startup: string[], afterStartup: string[], allowInlineStartup: boolean }} the generated source of the bootstrap code + * @returns {Bootstrap} the generated source of the bootstrap code */ renderBootstrap(renderContext, hooks) { - const { chunkGraph, moduleGraph, chunk, runtimeTemplate } = renderContext; + const { + chunkGraph, + codeGenerationResults, + moduleGraph, + chunk, + runtimeTemplate + } = renderContext; const runtimeRequirements = chunkGraph.getTreeRuntimeRequirements(chunk); @@ -846,6 +1051,9 @@ class JavascriptModulesPlugin { const useRequire = requireFunction || interceptModuleExecution || moduleUsed; + /** + * @type {{startup: string[], beforeStartup: string[], header: string[], afterStartup: string[], allowInlineStartup: boolean}} + */ const result = { header: [], beforeStartup: [], @@ -854,7 +1062,7 @@ class JavascriptModulesPlugin { allowInlineStartup: true }; - let { header: buf, startup, beforeStartup, afterStartup } = result; + const { header: buf, startup, beforeStartup, afterStartup } = result; if (result.allowInlineStartup && moduleFactories) { startup.push( @@ -881,13 +1089,13 @@ class JavascriptModulesPlugin { if (useRequire) { buf.push("// The require function"); - buf.push(`function __webpack_require__(moduleId) {`); + buf.push(`function ${RuntimeGlobals.require}(moduleId) {`); buf.push(Template.indent(this.renderRequire(renderContext, hooks))); buf.push("}"); buf.push(""); } else if (runtimeRequirements.has(RuntimeGlobals.requireScope)) { buf.push("// The require scope"); - buf.push("var __webpack_require__ = {};"); + buf.push(`var ${RuntimeGlobals.require} = {};`); buf.push(""); } @@ -916,16 +1124,17 @@ class JavascriptModulesPlugin { if (chunkGraph.getNumberOfEntryModules(chunk) > 0) { /** @type {string[]} */ const buf2 = []; - const runtimeRequirements = chunkGraph.getTreeRuntimeRequirements( - chunk - ); + const runtimeRequirements = + chunkGraph.getTreeRuntimeRequirements(chunk); buf2.push("// Load entry module and return exports"); let i = chunkGraph.getNumberOfEntryModules(chunk); for (const [ entryModule, entrypoint ] of chunkGraph.getChunkEntryModulesWithChunkGroupIterable(chunk)) { - const chunks = entrypoint.chunks.filter(c => c !== chunk); + const chunks = + /** @type {Entrypoint} */ + (entrypoint).chunks.filter(c => c !== chunk); if (result.allowInlineStartup && chunks.length > 0) { buf2.push( "// This entry module depends on other loaded chunks and execution need to be delayed" @@ -951,8 +1160,18 @@ class JavascriptModulesPlugin { ); result.allowInlineStartup = false; } + + let data; + if (codeGenerationResults.has(entryModule, chunk.runtime)) { + const result = codeGenerationResults.get( + entryModule, + chunk.runtime + ); + data = result.data; + } if ( result.allowInlineStartup && + (!data || !data.get("topLevelDeclarations")) && (!entryModule.buildInfo || !entryModule.buildInfo.topLevelDeclarations) ) { @@ -975,10 +1194,8 @@ class JavascriptModulesPlugin { } i--; const moduleId = chunkGraph.getModuleId(entryModule); - const entryRuntimeRequirements = chunkGraph.getModuleRuntimeRequirements( - entryModule, - chunk.runtime - ); + const entryRuntimeRequirements = + chunkGraph.getModuleRuntimeRequirements(entryModule, chunk.runtime); let moduleIdExpr = JSON.stringify(moduleId); if (runtimeRequirements.has(RuntimeGlobals.entryModuleId)) { moduleIdExpr = `${RuntimeGlobals.entryModuleId} = ${moduleIdExpr}`; @@ -994,32 +1211,32 @@ class JavascriptModulesPlugin { } if (chunks.length > 0) { buf2.push( - `${i === 0 ? "var __webpack_exports__ = " : ""}${ + `${i === 0 ? `var ${RuntimeGlobals.exports} = ` : ""}${ RuntimeGlobals.onChunksLoaded }(undefined, ${JSON.stringify( chunks.map(c => c.id) )}, ${runtimeTemplate.returningFunction( - `__webpack_require__(${moduleIdExpr})` + `${RuntimeGlobals.require}(${moduleIdExpr})` )})` ); } else if (useRequire) { buf2.push( - `${ - i === 0 ? "var __webpack_exports__ = " : "" - }__webpack_require__(${moduleIdExpr});` + `${i === 0 ? `var ${RuntimeGlobals.exports} = ` : ""}${ + RuntimeGlobals.require + }(${moduleIdExpr});` ); } else { - if (i === 0) buf2.push("var __webpack_exports__ = {};"); + if (i === 0) buf2.push(`var ${RuntimeGlobals.exports} = {};`); if (requireScopeUsed) { buf2.push( `__webpack_modules__[${moduleIdExpr}](0, ${ - i === 0 ? "__webpack_exports__" : "{}" - }, __webpack_require__);` + i === 0 ? RuntimeGlobals.exports : "{}" + }, ${RuntimeGlobals.require});` ); } else if (entryRuntimeRequirements.has(RuntimeGlobals.exports)) { buf2.push( `__webpack_modules__[${moduleIdExpr}](0, ${ - i === 0 ? "__webpack_exports__" : "{}" + i === 0 ? RuntimeGlobals.exports : "{}" });` ); } else { @@ -1029,7 +1246,7 @@ class JavascriptModulesPlugin { } if (runtimeRequirements.has(RuntimeGlobals.onChunksLoaded)) { buf2.push( - `__webpack_exports__ = ${RuntimeGlobals.onChunksLoaded}(__webpack_exports__);` + `${RuntimeGlobals.exports} = ${RuntimeGlobals.onChunksLoaded}(${RuntimeGlobals.exports});` ); } if ( @@ -1042,13 +1259,13 @@ class JavascriptModulesPlugin { buf.push( `${RuntimeGlobals.startup} = ${runtimeTemplate.basicFunction("", [ ...buf2, - "return __webpack_exports__;" + `return ${RuntimeGlobals.exports};` ])};` ); buf.push(""); startup.push("// run startup"); startup.push( - `var __webpack_exports__ = ${RuntimeGlobals.startup}();` + `var ${RuntimeGlobals.exports} = ${RuntimeGlobals.startup}();` ); } else if (runtimeRequirements.has(RuntimeGlobals.startupOnlyBefore)) { buf.push("// the startup function"); @@ -1096,7 +1313,9 @@ class JavascriptModulesPlugin { `${RuntimeGlobals.startup} = ${runtimeTemplate.emptyFunction()};` ); startup.push("// run startup"); - startup.push(`var __webpack_exports__ = ${RuntimeGlobals.startup}();`); + startup.push( + `var ${RuntimeGlobals.exports} = ${RuntimeGlobals.startup}();` + ); } return result; } @@ -1117,18 +1336,18 @@ class JavascriptModulesPlugin { RuntimeGlobals.interceptModuleExecution ) ? Template.asString([ - "var execOptions = { id: moduleId, module: module, factory: __webpack_modules__[moduleId], require: __webpack_require__ };", + `var execOptions = { id: moduleId, module: module, factory: __webpack_modules__[moduleId], require: ${RuntimeGlobals.require} };`, `${RuntimeGlobals.interceptModuleExecution}.forEach(function(handler) { handler(execOptions); });`, "module = execOptions.module;", "execOptions.factory.call(module.exports, module, module.exports, execOptions.require);" - ]) + ]) : runtimeRequirements.has(RuntimeGlobals.thisAsExports) - ? Template.asString([ - "__webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__);" - ]) - : Template.asString([ - "__webpack_modules__[moduleId](module, module.exports, __webpack_require__);" - ]); + ? Template.asString([ + `__webpack_modules__[moduleId].call(module.exports, module, module.exports, ${RuntimeGlobals.require});` + ]) + : Template.asString([ + `__webpack_modules__[moduleId](module, module.exports, ${RuntimeGlobals.require});` + ]); const needModuleId = runtimeRequirements.has(RuntimeGlobals.moduleId); const needModuleLoaded = runtimeRequirements.has( RuntimeGlobals.moduleLoaded @@ -1141,7 +1360,7 @@ class JavascriptModulesPlugin { ? Template.indent([ "if (cachedModule.error !== undefined) throw cachedModule.error;", "return cachedModule.exports;" - ]) + ]) : Template.indent("return cachedModule.exports;"), "}", "// Create a new module (and put it into the cache)", @@ -1164,27 +1383,27 @@ class JavascriptModulesPlugin { "if(threw) delete __webpack_module_cache__[moduleId];" ]), "}" - ]) + ]) : outputOptions.strictModuleErrorHandling - ? Template.asString([ - "// Execute the module function", - "try {", - Template.indent(moduleExecution), - "} catch(e) {", - Template.indent(["module.error = e;", "throw e;"]), - "}" - ]) - : Template.asString([ - "// Execute the module function", - moduleExecution - ]), + ? Template.asString([ + "// Execute the module function", + "try {", + Template.indent(moduleExecution), + "} catch(e) {", + Template.indent(["module.error = e;", "throw e;"]), + "}" + ]) + : Template.asString([ + "// Execute the module function", + moduleExecution + ]), needModuleLoaded ? Template.asString([ "", "// Flag the module as loaded", - "module.loaded = true;", + `${RuntimeGlobals.moduleLoaded} = true;`, "" - ]) + ]) : "", "// Return the exports of the module", "return module.exports;" @@ -1194,6 +1413,160 @@ class JavascriptModulesPlugin { "JavascriptModulesPlugin.getCompilationHooks().renderRequire" ); } + + /** + * @param {Module[]} allModules allModules + * @param {MainRenderContext} renderContext renderContext + * @param {Set} inlinedModules inlinedModules + * @param {ChunkRenderContext} chunkRenderContext chunkRenderContext + * @param {CompilationHooks} hooks hooks + * @returns {Map} renamed inlined modules + */ + renameInlineModule( + allModules, + renderContext, + inlinedModules, + chunkRenderContext, + hooks + ) { + const { runtimeTemplate } = renderContext; + + /** @typedef {{ source: Source, ast: any, variables: Set, usedInNonInlined: Set}} InlinedModulesInfo */ + + /** @type {Map} */ + const inlinedModulesToInfo = new Map(); + /** @type {Set} */ + const nonInlinedModuleThroughIdentifiers = new Set(); + /** @type {Map} */ + const renamedInlinedModules = new Map(); + + for (const m of allModules) { + const isInlinedModule = inlinedModules && inlinedModules.has(m); + const moduleSource = this.renderModule( + m, + chunkRenderContext, + hooks, + !isInlinedModule + ); + + if (!moduleSource) continue; + const code = /** @type {string} */ (moduleSource.source()); + const ast = JavascriptParser._parse(code, { + sourceType: "auto" + }); + + const scopeManager = eslintScope.analyze(ast, { + ecmaVersion: 6, + sourceType: "module", + optimistic: true, + ignoreEval: true + }); + + const globalScope = /** @type {Scope} */ (scopeManager.acquire(ast)); + if (inlinedModules && inlinedModules.has(m)) { + const moduleScope = globalScope.childScopes[0]; + inlinedModulesToInfo.set(m, { + source: moduleSource, + ast, + variables: new Set(moduleScope.variables), + usedInNonInlined: new Set() + }); + } else { + for (const ref of globalScope.through) { + nonInlinedModuleThroughIdentifiers.add(ref.identifier.name); + } + } + } + + for (const [, { variables, usedInNonInlined }] of inlinedModulesToInfo) { + for (const variable of variables) { + if (nonInlinedModuleThroughIdentifiers.has(variable.name)) { + usedInNonInlined.add(variable); + } + } + } + + for (const [m, moduleInfo] of inlinedModulesToInfo) { + const { ast, source: _source, usedInNonInlined } = moduleInfo; + const source = new ReplaceSource(_source); + if (usedInNonInlined.size === 0) { + renamedInlinedModules.set(m, source); + continue; + } + + const usedNames = new Set( + Array.from( + /** @type {InlinedModulesInfo} */ + (inlinedModulesToInfo.get(m)).variables + ).map(v => v.name) + ); + + for (const variable of usedInNonInlined) { + const references = getAllReferences(variable); + const allIdentifiers = new Set( + references.map(r => r.identifier).concat(variable.identifiers) + ); + + const newName = this.findNewName( + variable.name, + usedNames, + m.readableIdentifier(runtimeTemplate.requestShortener) + ); + usedNames.add(newName); + for (const identifier of allIdentifiers) { + const r = /** @type {Range} */ (identifier.range); + const path = getPathInAst(ast, identifier); + if (path && path.length > 1) { + const maybeProperty = + path[1].type === "AssignmentPattern" && path[1].left === path[0] + ? path[2] + : path[1]; + if (maybeProperty.type === "Property" && maybeProperty.shorthand) { + source.insert(r[1], `: ${newName}`); + continue; + } + } + source.replace(r[0], r[1] - 1, newName); + } + } + + renamedInlinedModules.set(m, source); + } + + return renamedInlinedModules; + } + + /** + * @param {string} oldName oldName + * @param {Set} usedName usedName + * @param {string} extraInfo extraInfo + * @returns {string} extraInfo + */ + findNewName(oldName, usedName, extraInfo) { + let name = oldName; + + // Remove uncool stuff + extraInfo = extraInfo.replace( + /\.+\/|(\/index)?\.([a-zA-Z0-9]{1,4})($|\s|\?)|\s*\+\s*\d+\s*modules/g, + "" + ); + const splittedInfo = extraInfo.split("/"); + while (splittedInfo.length) { + name = splittedInfo.pop() + (name ? `_${name}` : ""); + const nameIdent = Template.toIdentifier(name); + if (!usedName.has(nameIdent)) { + return nameIdent; + } + } + + let i = 0; + let nameWithNumber = Template.toIdentifier(`${name}_${i}`); + while (usedName.has(nameWithNumber)) { + i++; + nameWithNumber = Template.toIdentifier(`${name}_${i}`); + } + return nameWithNumber; + } } module.exports = JavascriptModulesPlugin; diff --git a/lib/javascript/JavascriptParser.js b/lib/javascript/JavascriptParser.js index d379c69d32e..94b67732ed3 100644 --- a/lib/javascript/JavascriptParser.js +++ b/lib/javascript/JavascriptParser.js @@ -6,6 +6,7 @@ "use strict"; const { Parser: AcornParser } = require("acorn"); +const { importAttributesOrAssertions } = require("acorn-import-attributes"); const { SyncBailHook, HookMap } = require("tapable"); const vm = require("vm"); const Parser = require("../Parser"); @@ -15,43 +16,92 @@ const memoize = require("../util/memoize"); const BasicEvaluatedExpression = require("./BasicEvaluatedExpression"); /** @typedef {import("acorn").Options} AcornOptions */ -/** @typedef {import("estree").ArrayExpression} ArrayExpressionNode */ -/** @typedef {import("estree").BinaryExpression} BinaryExpressionNode */ -/** @typedef {import("estree").BlockStatement} BlockStatementNode */ -/** @typedef {import("estree").SequenceExpression} SequenceExpressionNode */ -/** @typedef {import("estree").CallExpression} CallExpressionNode */ -/** @typedef {import("estree").ClassDeclaration} ClassDeclarationNode */ -/** @typedef {import("estree").ClassExpression} ClassExpressionNode */ -/** @typedef {import("estree").Comment} CommentNode */ -/** @typedef {import("estree").ConditionalExpression} ConditionalExpressionNode */ -/** @typedef {import("estree").Declaration} DeclarationNode */ -/** @typedef {import("estree").Expression} ExpressionNode */ -/** @typedef {import("estree").Identifier} IdentifierNode */ -/** @typedef {import("estree").IfStatement} IfStatementNode */ -/** @typedef {import("estree").LabeledStatement} LabeledStatementNode */ -/** @typedef {import("estree").Literal} LiteralNode */ -/** @typedef {import("estree").LogicalExpression} LogicalExpressionNode */ -/** @typedef {import("estree").ChainExpression} ChainExpressionNode */ -/** @typedef {import("estree").MemberExpression} MemberExpressionNode */ -/** @typedef {import("estree").MetaProperty} MetaPropertyNode */ -/** @typedef {import("estree").MethodDefinition} MethodDefinitionNode */ -/** @typedef {import("estree").ModuleDeclaration} ModuleDeclarationNode */ -/** @typedef {import("estree").NewExpression} NewExpressionNode */ +/** @typedef {import("estree").AssignmentExpression} AssignmentExpression */ +/** @typedef {import("estree").BinaryExpression} BinaryExpression */ +/** @typedef {import("estree").BlockStatement} BlockStatement */ +/** @typedef {import("estree").SequenceExpression} SequenceExpression */ +/** @typedef {import("estree").CallExpression} CallExpression */ +/** @typedef {import("estree").BaseCallExpression} BaseCallExpression */ +/** @typedef {import("estree").StaticBlock} StaticBlock */ +/** @typedef {import("estree").ImportExpression} ImportExpression */ +/** @typedef {import("estree").ClassDeclaration} ClassDeclaration */ +/** @typedef {import("estree").ForStatement} ForStatement */ +/** @typedef {import("estree").SwitchStatement} SwitchStatement */ +/** @typedef {import("estree").ExportNamedDeclaration} ExportNamedDeclaration */ +/** @typedef {import("estree").ClassExpression} ClassExpression */ +/** @typedef {import("estree").Comment} Comment */ +/** @typedef {import("estree").ConditionalExpression} ConditionalExpression */ +/** @typedef {import("estree").Declaration} Declaration */ +/** @typedef {import("estree").PrivateIdentifier} PrivateIdentifier */ +/** @typedef {import("estree").PropertyDefinition} PropertyDefinition */ +/** @typedef {import("estree").Expression} Expression */ +/** @typedef {import("estree").Identifier} Identifier */ +/** @typedef {import("estree").VariableDeclaration} VariableDeclaration */ +/** @typedef {import("estree").IfStatement} IfStatement */ +/** @typedef {import("estree").LabeledStatement} LabeledStatement */ +/** @typedef {import("estree").Literal} Literal */ +/** @typedef {import("estree").LogicalExpression} LogicalExpression */ +/** @typedef {import("estree").ChainExpression} ChainExpression */ +/** @typedef {import("estree").MemberExpression} MemberExpression */ +/** @typedef {import("estree").YieldExpression} YieldExpression */ +/** @typedef {import("estree").MetaProperty} MetaProperty */ +/** @typedef {import("estree").Property} Property */ +/** @typedef {import("estree").AssignmentPattern} AssignmentPattern */ +/** @typedef {import("estree").ChainElement} ChainElement */ +/** @typedef {import("estree").Pattern} Pattern */ +/** @typedef {import("estree").UpdateExpression} UpdateExpression */ +/** @typedef {import("estree").ObjectExpression} ObjectExpression */ +/** @typedef {import("estree").UnaryExpression} UnaryExpression */ +/** @typedef {import("estree").ArrayExpression} ArrayExpression */ +/** @typedef {import("estree").ArrayPattern} ArrayPattern */ +/** @typedef {import("estree").AwaitExpression} AwaitExpression */ +/** @typedef {import("estree").ThisExpression} ThisExpression */ +/** @typedef {import("estree").RestElement} RestElement */ +/** @typedef {import("estree").ObjectPattern} ObjectPattern */ +/** @typedef {import("estree").SwitchCase} SwitchCase */ +/** @typedef {import("estree").CatchClause} CatchClause */ +/** @typedef {import("estree").VariableDeclarator} VariableDeclarator */ +/** @typedef {import("estree").ForInStatement} ForInStatement */ +/** @typedef {import("estree").ForOfStatement} ForOfStatement */ +/** @typedef {import("estree").ReturnStatement} ReturnStatement */ +/** @typedef {import("estree").WithStatement} WithStatement */ +/** @typedef {import("estree").ThrowStatement} ThrowStatement */ +/** @typedef {import("estree").MethodDefinition} MethodDefinition */ +/** @typedef {import("estree").ModuleDeclaration} ModuleDeclaration */ +/** @typedef {import("estree").NewExpression} NewExpression */ +/** @typedef {import("estree").SpreadElement} SpreadElement */ +/** @typedef {import("estree").FunctionExpression} FunctionExpression */ +/** @typedef {import("estree").WhileStatement} WhileStatement */ +/** @typedef {import("estree").ArrowFunctionExpression} ArrowFunctionExpression */ +/** @typedef {import("estree").ExpressionStatement} ExpressionStatement */ +/** @typedef {import("estree").FunctionDeclaration} FunctionDeclaration */ +/** @typedef {import("estree").DoWhileStatement} DoWhileStatement */ +/** @typedef {import("estree").TryStatement} TryStatement */ /** @typedef {import("estree").Node} AnyNode */ -/** @typedef {import("estree").Program} ProgramNode */ -/** @typedef {import("estree").Statement} StatementNode */ -/** @typedef {import("estree").Super} SuperNode */ -/** @typedef {import("estree").TaggedTemplateExpression} TaggedTemplateExpressionNode */ -/** @typedef {import("estree").TemplateLiteral} TemplateLiteralNode */ -/** @typedef {import("estree").ThisExpression} ThisExpressionNode */ -/** @typedef {import("estree").UnaryExpression} UnaryExpressionNode */ -/** @typedef {import("estree").VariableDeclarator} VariableDeclaratorNode */ -/** @template T @typedef {import("tapable").AsArray} AsArray */ +/** @typedef {import("estree").Program} Program */ +/** @typedef {import("estree").Directive} Directive */ +/** @typedef {import("estree").Statement} Statement */ +/** @typedef {import("estree").ImportDeclaration} ImportDeclaration */ +/** @typedef {import("estree").ExportDefaultDeclaration} ExportDefaultDeclaration */ +/** @typedef {import("estree").ExportAllDeclaration} ExportAllDeclaration */ +/** @typedef {import("estree").Super} Super */ +/** @typedef {import("estree").TaggedTemplateExpression} TaggedTemplateExpression */ +/** @typedef {import("estree").TemplateLiteral} TemplateLiteral */ +/** @typedef {import("estree").AssignmentProperty} AssignmentProperty */ +/** + * @template T + * @typedef {import("tapable").AsArray} AsArray + */ /** @typedef {import("../Parser").ParserState} ParserState */ /** @typedef {import("../Parser").PreparsedAst} PreparsedAst */ /** @typedef {{declaredScope: ScopeInfo, freeName: string | true, tagInfo: TagInfo | undefined}} VariableInfoInterface */ -/** @typedef {{ name: string | VariableInfo, rootInfo: string | VariableInfo, getMembers: () => string[] }} GetInfoResult */ +/** @typedef {{ name: string | VariableInfo, rootInfo: string | VariableInfo, getMembers: () => string[], getMembersOptionals: () => boolean[], getMemberRanges: () => Range[] }} GetInfoResult */ +/** @typedef {Statement | ModuleDeclaration | Expression} StatementPathItem */ +/** @typedef {TODO} OnIdent */ +/** @typedef {Record & { _isLegacyAssert?: boolean }} ImportAttributes */ + +/** @type {string[]} */ const EMPTY_ARRAY = []; const ALLOWED_MEMBER_TYPES_CALL_EXPRESSION = 0b01; const ALLOWED_MEMBER_TYPES_EXPRESSION = 0b10; @@ -59,12 +109,12 @@ const ALLOWED_MEMBER_TYPES_ALL = 0b11; // Syntax: https://developer.mozilla.org/en/SpiderMonkey/Parser_API -const parser = AcornParser; +const parser = AcornParser.extend(importAttributesOrAssertions); class VariableInfo { /** * @param {ScopeInfo} declaredScope scope in which the variable is declared - * @param {string | true} freeName which free name the variable aliases, or true when none + * @param {string | true | undefined} freeName which free name the variable aliases, or true when none * @param {TagInfo | undefined} tagInfo info about tags */ constructor(declaredScope, freeName, tagInfo) { @@ -75,40 +125,88 @@ class VariableInfo { } /** @typedef {string | ScopeInfo | VariableInfo} ExportedVariableInfo */ -/** @typedef {LiteralNode | string | null | undefined} ImportSource */ +/** @typedef {Literal | string | null | undefined} ImportSource */ /** @typedef {Omit & { sourceType: "module" | "script" | "auto", ecmaVersion?: AcornOptions["ecmaVersion"] }} ParseOptions */ /** - * @typedef {Object} TagInfo + * @typedef {object} TagInfo * @property {any} tag * @property {any} data * @property {TagInfo | undefined} next */ /** - * @typedef {Object} ScopeInfo + * @typedef {object} ScopeInfo * @property {StackedMap} definitions * @property {boolean | "arrow"} topLevelScope - * @property {boolean} inShorthand + * @property {boolean | string} inShorthand + * @property {boolean} inTaggedTemplateTag + * @property {boolean} inTry * @property {boolean} isStrict * @property {boolean} isAsmJs - * @property {boolean} inTry */ +/** @typedef {[number, number]} Range */ + +/** + * @typedef {object} DestructuringAssignmentProperty + * @property {string} id + * @property {Range | undefined=} range + * @property {boolean | string} shorthand + */ + +/** + * Helper function for joining two ranges into a single range. This is useful + * when working with AST nodes, as it allows you to combine the ranges of child nodes + * to create the range of the _parent node_. + * @param {[number, number]} startRange start range to join + * @param {[number, number]} endRange end range to join + * @returns {[number, number]} joined range + * @example + * ```js + * const startRange = [0, 5]; + * const endRange = [10, 15]; + * const joinedRange = joinRanges(startRange, endRange); + * console.log(joinedRange); // [0, 15] + * ``` + */ const joinRanges = (startRange, endRange) => { if (!endRange) return startRange; if (!startRange) return endRange; return [startRange[0], endRange[1]]; }; +/** + * Helper function used to generate a string representation of a + * [member expression](https://github.com/estree/estree/blob/master/es5.md#memberexpression). + * @param {string} object object to name + * @param {string[]} membersReversed reversed list of members + * @returns {string} member expression as a string + * @example + * ```js + * const membersReversed = ["property1", "property2", "property3"]; // Members parsed from the AST + * const name = objectAndMembersToName("myObject", membersReversed); + * + * console.log(name); // "myObject.property1.property2.property3" + * ``` + */ const objectAndMembersToName = (object, membersReversed) => { let name = object; for (let i = membersReversed.length - 1; i >= 0; i--) { - name = name + "." + membersReversed[i]; + name = `${name}.${membersReversed[i]}`; } return name; }; +/** + * Grabs the name of a given expression and returns it as a string or undefined. Has particular + * handling for [Identifiers](https://github.com/estree/estree/blob/master/es5.md#identifier), + * [ThisExpressions](https://github.com/estree/estree/blob/master/es5.md#identifier), and + * [MetaProperties](https://github.com/estree/estree/blob/master/es2015.md#metaproperty) which is + * specifically for handling the `new.target` meta property. + * @param {Expression | SpreadElement | Super} expression expression + * @returns {string | "this" | undefined} name or variable info + */ const getRootName = expression => { switch (expression.type) { case "Identifier": @@ -128,7 +226,8 @@ const defaultParserOptions = { locations: true, ecmaVersion: "latest", sourceType: "module", - allowAwaitOutsideFunction: true, + // https://github.com/tc39/proposal-hashbang + allowHashBang: true, onComment: null }; @@ -147,64 +246,81 @@ class JavascriptParser extends Parser { constructor(sourceType = "auto") { super(); this.hooks = Object.freeze({ - /** @type {HookMap>} */ + /** @type {HookMap>} */ evaluateTypeof: new HookMap(() => new SyncBailHook(["expression"])), - /** @type {HookMap>} */ + /** @type {HookMap>} */ evaluate: new HookMap(() => new SyncBailHook(["expression"])), - /** @type {HookMap>} */ + /** @type {HookMap>} */ evaluateIdentifier: new HookMap(() => new SyncBailHook(["expression"])), - /** @type {HookMap>} */ + /** @type {HookMap>} */ evaluateDefinedIdentifier: new HookMap( () => new SyncBailHook(["expression"]) ), - /** @type {HookMap>} */ + /** @type {HookMap>} */ + evaluateNewExpression: new HookMap( + () => new SyncBailHook(["expression"]) + ), + /** @type {HookMap>} */ + evaluateCallExpression: new HookMap( + () => new SyncBailHook(["expression"]) + ), + /** @type {HookMap>} */ evaluateCallExpressionMember: new HookMap( () => new SyncBailHook(["expression", "param"]) ), - /** @type {HookMap>} */ + /** @type {HookMap>} */ isPure: new HookMap( () => new SyncBailHook(["expression", "commentsStartPosition"]) ), - /** @type {SyncBailHook<[StatementNode | ModuleDeclarationNode], boolean | void>} */ + /** @type {SyncBailHook<[Statement | ModuleDeclaration], boolean | void>} */ preStatement: new SyncBailHook(["statement"]), - /** @type {SyncBailHook<[StatementNode | ModuleDeclarationNode], boolean | void>} */ + /** @type {SyncBailHook<[Statement | ModuleDeclaration], boolean | void>} */ blockPreStatement: new SyncBailHook(["declaration"]), - /** @type {SyncBailHook<[StatementNode | ModuleDeclarationNode], boolean | void>} */ + /** @type {SyncBailHook<[Statement | ModuleDeclaration], boolean | void>} */ statement: new SyncBailHook(["statement"]), - /** @type {SyncBailHook<[IfStatementNode], boolean | void>} */ + /** @type {SyncBailHook<[IfStatement], boolean | void>} */ statementIf: new SyncBailHook(["statement"]), - /** @type {SyncBailHook<[ExpressionNode, ClassExpressionNode | ClassDeclarationNode], boolean | void>} */ - classExtendsExpression: new SyncBailHook(["expression", "statement"]), - /** @type {SyncBailHook<[MethodDefinitionNode, ClassExpressionNode | ClassDeclarationNode], boolean | void>} */ - classBodyElement: new SyncBailHook(["element", "statement"]), - /** @type {HookMap>} */ + /** @type {SyncBailHook<[Expression, ClassExpression | ClassDeclaration], boolean | void>} */ + classExtendsExpression: new SyncBailHook([ + "expression", + "classDefinition" + ]), + /** @type {SyncBailHook<[MethodDefinition | PropertyDefinition | StaticBlock, ClassExpression | ClassDeclaration], boolean | void>} */ + classBodyElement: new SyncBailHook(["element", "classDefinition"]), + /** @type {SyncBailHook<[Expression, MethodDefinition | PropertyDefinition, ClassExpression | ClassDeclaration], boolean | void>} */ + classBodyValue: new SyncBailHook([ + "expression", + "element", + "classDefinition" + ]), + /** @type {HookMap>} */ label: new HookMap(() => new SyncBailHook(["statement"])), - /** @type {SyncBailHook<[StatementNode, ImportSource], boolean | void>} */ + /** @type {SyncBailHook<[ImportDeclaration, ImportSource], boolean | void>} */ import: new SyncBailHook(["statement", "source"]), - /** @type {SyncBailHook<[StatementNode, ImportSource, string, string], boolean | void>} */ + /** @type {SyncBailHook<[ImportDeclaration, ImportSource, string, string], boolean | void>} */ importSpecifier: new SyncBailHook([ "statement", "source", "exportName", "identifierName" ]), - /** @type {SyncBailHook<[StatementNode], boolean | void>} */ + /** @type {SyncBailHook<[ExportDefaultDeclaration | ExportNamedDeclaration], boolean | void>} */ export: new SyncBailHook(["statement"]), - /** @type {SyncBailHook<[StatementNode, ImportSource], boolean | void>} */ + /** @type {SyncBailHook<[ExportNamedDeclaration | ExportAllDeclaration, ImportSource], boolean | void>} */ exportImport: new SyncBailHook(["statement", "source"]), - /** @type {SyncBailHook<[StatementNode, DeclarationNode], boolean | void>} */ + /** @type {SyncBailHook<[ExportDefaultDeclaration | ExportNamedDeclaration | ExportAllDeclaration, Declaration], boolean | void>} */ exportDeclaration: new SyncBailHook(["statement", "declaration"]), - /** @type {SyncBailHook<[StatementNode, DeclarationNode], boolean | void>} */ + /** @type {SyncBailHook<[ExportDefaultDeclaration, FunctionDeclaration | ClassDeclaration], boolean | void>} */ exportExpression: new SyncBailHook(["statement", "declaration"]), - /** @type {SyncBailHook<[StatementNode, string, string, number | undefined], boolean | void>} */ + /** @type {SyncBailHook<[ExportDefaultDeclaration | ExportNamedDeclaration | ExportAllDeclaration, string, string, number | undefined], boolean | void>} */ exportSpecifier: new SyncBailHook([ "statement", "identifierName", "exportName", "index" ]), - /** @type {SyncBailHook<[StatementNode, ImportSource, string, string, number | undefined], boolean | void>} */ + /** @type {SyncBailHook<[ExportNamedDeclaration | ExportAllDeclaration, ImportSource, string, string, number | undefined], boolean | void>} */ exportImportSpecifier: new SyncBailHook([ "statement", "source", @@ -212,86 +328,102 @@ class JavascriptParser extends Parser { "exportName", "index" ]), - /** @type {SyncBailHook<[VariableDeclaratorNode, StatementNode], boolean | void>} */ + /** @type {SyncBailHook<[VariableDeclarator, Statement], boolean | void>} */ preDeclarator: new SyncBailHook(["declarator", "statement"]), - /** @type {SyncBailHook<[VariableDeclaratorNode, StatementNode], boolean | void>} */ + /** @type {SyncBailHook<[VariableDeclarator, Statement], boolean | void>} */ declarator: new SyncBailHook(["declarator", "statement"]), - /** @type {HookMap>} */ + /** @type {HookMap>} */ varDeclaration: new HookMap(() => new SyncBailHook(["declaration"])), - /** @type {HookMap>} */ + /** @type {HookMap>} */ varDeclarationLet: new HookMap(() => new SyncBailHook(["declaration"])), - /** @type {HookMap>} */ + /** @type {HookMap>} */ varDeclarationConst: new HookMap(() => new SyncBailHook(["declaration"])), - /** @type {HookMap>} */ + /** @type {HookMap>} */ varDeclarationVar: new HookMap(() => new SyncBailHook(["declaration"])), - /** @type {HookMap>} */ + /** @type {HookMap>} */ pattern: new HookMap(() => new SyncBailHook(["pattern"])), - /** @type {HookMap>} */ + /** @type {HookMap>} */ canRename: new HookMap(() => new SyncBailHook(["initExpression"])), - /** @type {HookMap>} */ + /** @type {HookMap>} */ rename: new HookMap(() => new SyncBailHook(["initExpression"])), - /** @type {HookMap>} */ + /** @type {HookMap>} */ assign: new HookMap(() => new SyncBailHook(["expression"])), - /** @type {HookMap>} */ + /** @type {HookMap>} */ assignMemberChain: new HookMap( () => new SyncBailHook(["expression", "members"]) ), - /** @type {HookMap>} */ + /** @type {HookMap>} */ typeof: new HookMap(() => new SyncBailHook(["expression"])), - /** @type {SyncBailHook<[ExpressionNode], boolean | void>} */ + /** @type {SyncBailHook<[ImportExpression], boolean | void>} */ importCall: new SyncBailHook(["expression"]), - /** @type {SyncBailHook<[ExpressionNode], boolean | void>} */ + /** @type {SyncBailHook<[Expression | ForOfStatement], boolean | void>} */ topLevelAwait: new SyncBailHook(["expression"]), - /** @type {HookMap>} */ + /** @type {HookMap>} */ call: new HookMap(() => new SyncBailHook(["expression"])), /** Something like "a.b()" */ - /** @type {HookMap>} */ + /** @type {HookMap>} */ callMemberChain: new HookMap( - () => new SyncBailHook(["expression", "members"]) + () => + new SyncBailHook([ + "expression", + "members", + "membersOptionals", + "memberRanges" + ]) ), /** Something like "a.b().c.d" */ - /** @type {HookMap>} */ + /** @type {HookMap>} */ memberChainOfCallMemberChain: new HookMap( () => new SyncBailHook([ "expression", "calleeMembers", "callExpression", - "members" + "members", + "memberRanges" ]) ), /** Something like "a.b().c.d()"" */ - /** @type {HookMap>} */ + /** @type {HookMap>} */ callMemberChainOfCallMemberChain: new HookMap( () => new SyncBailHook([ "expression", "calleeMembers", "innerCallExpression", - "members" + "members", + "memberRanges" ]) ), - /** @type {SyncBailHook<[ChainExpressionNode], boolean | void>} */ + /** @type {SyncBailHook<[ChainExpression], boolean | void>} */ optionalChaining: new SyncBailHook(["optionalChaining"]), - /** @type {HookMap>} */ + /** @type {HookMap>} */ new: new HookMap(() => new SyncBailHook(["expression"])), - /** @type {HookMap>} */ + /** @type {SyncBailHook<[BinaryExpression], boolean | void>} */ + binaryExpression: new SyncBailHook(["binaryExpression"]), + /** @type {HookMap>} */ expression: new HookMap(() => new SyncBailHook(["expression"])), - /** @type {HookMap>} */ + /** @type {HookMap>} */ expressionMemberChain: new HookMap( - () => new SyncBailHook(["expression", "members"]) + () => + new SyncBailHook([ + "expression", + "members", + "membersOptionals", + "memberRanges" + ]) ), - /** @type {HookMap>} */ + /** @type {HookMap>} */ unhandledExpressionMemberChain: new HookMap( () => new SyncBailHook(["expression", "members"]) ), - /** @type {SyncBailHook<[ExpressionNode], boolean | void>} */ + /** @type {SyncBailHook<[ConditionalExpression], boolean | void>} */ expressionConditionalOperator: new SyncBailHook(["expression"]), - /** @type {SyncBailHook<[ExpressionNode], boolean | void>} */ + /** @type {SyncBailHook<[LogicalExpression], boolean | void>} */ expressionLogicalOperator: new SyncBailHook(["expression"]), - /** @type {SyncBailHook<[ProgramNode, CommentNode[]], boolean | void>} */ + /** @type {SyncBailHook<[Program, Comment[]], boolean | void>} */ program: new SyncBailHook(["ast", "comments"]), - /** @type {SyncBailHook<[ProgramNode, CommentNode[]], boolean | void>} */ + /** @type {SyncBailHook<[Program, Comment[]], boolean | void>} */ finish: new SyncBailHook(["ast", "comments"]) }); this.sourceType = sourceType; @@ -299,58 +431,74 @@ class JavascriptParser extends Parser { this.scope = undefined; /** @type {ParserState} */ this.state = undefined; + /** @type {Comment[] | undefined} */ this.comments = undefined; + /** @type {Set | undefined} */ this.semicolons = undefined; - /** @type {(StatementNode|ExpressionNode)[]} */ + /** @type {StatementPathItem[]} */ this.statementPath = undefined; + /** @type {Statement | ModuleDeclaration | Expression | undefined} */ this.prevStatement = undefined; + /** @type {WeakMap> | undefined} */ + this.destructuringAssignmentProperties = undefined; this.currentTagData = undefined; + this.magicCommentContext = vm.createContext(undefined, { + name: "Webpack Magic Comment Parser", + codeGeneration: { strings: false, wasm: false } + }); this._initializeEvaluating(); } _initializeEvaluating() { this.hooks.evaluate.for("Literal").tap("JavascriptParser", _expr => { - const expr = /** @type {LiteralNode} */ (_expr); + const expr = /** @type {Literal} */ (_expr); switch (typeof expr.value) { case "number": return new BasicEvaluatedExpression() .setNumber(expr.value) - .setRange(expr.range); + .setRange(/** @type {Range} */ (expr.range)); case "bigint": return new BasicEvaluatedExpression() .setBigInt(expr.value) - .setRange(expr.range); + .setRange(/** @type {Range} */ (expr.range)); case "string": return new BasicEvaluatedExpression() .setString(expr.value) - .setRange(expr.range); + .setRange(/** @type {Range} */ (expr.range)); case "boolean": return new BasicEvaluatedExpression() .setBoolean(expr.value) - .setRange(expr.range); + .setRange(/** @type {Range} */ (expr.range)); } if (expr.value === null) { - return new BasicEvaluatedExpression().setNull().setRange(expr.range); + return new BasicEvaluatedExpression() + .setNull() + .setRange(/** @type {Range} */ (expr.range)); } if (expr.value instanceof RegExp) { return new BasicEvaluatedExpression() .setRegExp(expr.value) - .setRange(expr.range); + .setRange(/** @type {Range} */ (expr.range)); } }); this.hooks.evaluate.for("NewExpression").tap("JavascriptParser", _expr => { - const expr = /** @type {NewExpressionNode} */ (_expr); + const expr = /** @type {NewExpression} */ (_expr); const callee = expr.callee; - if ( - callee.type !== "Identifier" || - callee.name !== "RegExp" || + if (callee.type !== "Identifier") return; + if (callee.name !== "RegExp") { + return this.callHooksForName( + this.hooks.evaluateNewExpression, + callee.name, + expr + ); + } else if ( expr.arguments.length > 2 || this.getVariableInfo("RegExp") !== "RegExp" ) return; - let regExp, flags; + let regExp; const arg1 = expr.arguments[0]; if (arg1) { @@ -364,11 +512,15 @@ class JavascriptParser extends Parser { if (!regExp) return; } else { - return new BasicEvaluatedExpression() - .setRegExp(new RegExp("")) - .setRange(expr.range); + return ( + new BasicEvaluatedExpression() + // eslint-disable-next-line prefer-regex-literals + .setRegExp(new RegExp("")) + .setRange(/** @type {Range} */ (expr.range)) + ); } + let flags; const arg2 = expr.arguments[1]; if (arg2) { @@ -391,72 +543,142 @@ class JavascriptParser extends Parser { return new BasicEvaluatedExpression() .setRegExp(flags ? new RegExp(regExp, flags) : new RegExp(regExp)) - .setRange(expr.range); + .setRange(/** @type {Range} */ (expr.range)); }); this.hooks.evaluate .for("LogicalExpression") .tap("JavascriptParser", _expr => { - const expr = /** @type {LogicalExpressionNode} */ (_expr); + const expr = /** @type {LogicalExpression} */ (_expr); const left = this.evaluateExpression(expr.left); - if (!left) return; + let returnRight = false; + /** @type {boolean|undefined} */ + let allowedRight; if (expr.operator === "&&") { const leftAsBool = left.asBool(); - if (leftAsBool === false) return left.setRange(expr.range); - if (leftAsBool !== true) return; + if (leftAsBool === false) + return left.setRange(/** @type {Range} */ (expr.range)); + returnRight = leftAsBool === true; + allowedRight = false; } else if (expr.operator === "||") { const leftAsBool = left.asBool(); - if (leftAsBool === true) return left.setRange(expr.range); - if (leftAsBool !== false) return; + if (leftAsBool === true) + return left.setRange(/** @type {Range} */ (expr.range)); + returnRight = leftAsBool === false; + allowedRight = true; } else if (expr.operator === "??") { const leftAsNullish = left.asNullish(); - if (leftAsNullish === false) return left.setRange(expr.range); + if (leftAsNullish === false) + return left.setRange(/** @type {Range} */ (expr.range)); if (leftAsNullish !== true) return; + returnRight = true; } else return; const right = this.evaluateExpression(expr.right); - if (!right) return; - if (left.couldHaveSideEffects()) right.setSideEffects(); - return right.setRange(expr.range); + if (returnRight) { + if (left.couldHaveSideEffects()) right.setSideEffects(); + return right.setRange(/** @type {Range} */ (expr.range)); + } + + const asBool = right.asBool(); + + if (allowedRight === true && asBool === true) { + return new BasicEvaluatedExpression() + .setRange(/** @type {Range} */ (expr.range)) + .setTruthy(); + } else if (allowedRight === false && asBool === false) { + return new BasicEvaluatedExpression() + .setRange(/** @type {Range} */ (expr.range)) + .setFalsy(); + } }); + /** + * In simple logical cases, we can use valueAsExpression to assist us in evaluating the expression on + * either side of a [BinaryExpression](https://github.com/estree/estree/blob/master/es5.md#binaryexpression). + * This supports scenarios in webpack like conditionally `import()`'ing modules based on some simple evaluation: + * + * ```js + * if (1 === 3) { + * import("./moduleA"); // webpack will auto evaluate this and not import the modules + * } + * ``` + * + * Additional scenarios include evaluation of strings inside of dynamic import statements: + * + * ```js + * const foo = "foo"; + * const bar = "bar"; + * + * import("./" + foo + bar); // webpack will auto evaluate this into import("./foobar") + * ``` + * @param {boolean | number | bigint | string} value the value to convert to an expression + * @param {BinaryExpression | UnaryExpression} expr the expression being evaluated + * @param {boolean} sideEffects whether the expression has side effects + * @returns {BasicEvaluatedExpression | undefined} the evaluated expression + * @example + * + * ```js + * const binaryExpr = new BinaryExpression("+", + * { type: "Literal", value: 2 }, + * { type: "Literal", value: 3 } + * ); + * + * const leftValue = 2; + * const rightValue = 3; + * + * const leftExpr = valueAsExpression(leftValue, binaryExpr.left, false); + * const rightExpr = valueAsExpression(rightValue, binaryExpr.right, false); + * const result = new BasicEvaluatedExpression() + * .setNumber(leftExpr.number + rightExpr.number) + * .setRange(binaryExpr.range); + * + * console.log(result.number); // Output: 5 + * ``` + */ const valueAsExpression = (value, expr, sideEffects) => { switch (typeof value) { case "boolean": return new BasicEvaluatedExpression() .setBoolean(value) .setSideEffects(sideEffects) - .setRange(expr.range); + .setRange(/** @type {Range} */ (expr.range)); case "number": return new BasicEvaluatedExpression() .setNumber(value) .setSideEffects(sideEffects) - .setRange(expr.range); + .setRange(/** @type {Range} */ (expr.range)); case "bigint": return new BasicEvaluatedExpression() .setBigInt(value) .setSideEffects(sideEffects) - .setRange(expr.range); + .setRange(/** @type {Range} */ (expr.range)); case "string": return new BasicEvaluatedExpression() .setString(value) .setSideEffects(sideEffects) - .setRange(expr.range); + .setRange(/** @type {Range} */ (expr.range)); } }; this.hooks.evaluate .for("BinaryExpression") .tap("JavascriptParser", _expr => { - const expr = /** @type {BinaryExpressionNode} */ (_expr); - - const handleConstOperation = fn => { + const expr = /** @type {BinaryExpression} */ (_expr); + + /** + * Evaluates a binary expression if and only if it is a const operation (e.g. 1 + 2, "a" + "b", etc.). + * @template T + * @param {(leftOperand: T, rightOperand: T) => boolean | number | bigint | string} operandHandler the handler for the operation (e.g. (a, b) => a + b) + * @returns {BasicEvaluatedExpression | undefined} the evaluated expression + */ + const handleConstOperation = operandHandler => { const left = this.evaluateExpression(expr.left); - if (!left || !left.isCompileTimeValue()) return; + if (!left.isCompileTimeValue()) return; const right = this.evaluateExpression(expr.right); - if (!right || !right.isCompileTimeValue()) return; + if (!right.isCompileTimeValue()) return; - const result = fn( + const result = operandHandler( left.asCompileTimeValue(), right.asCompileTimeValue() ); @@ -467,10 +689,28 @@ class JavascriptParser extends Parser { ); }; + /** + * Helper function to determine if two booleans are always different. This is used in `handleStrictEqualityComparison` + * to determine if an expressions boolean or nullish conversion is equal or not. + * @param {boolean} a first boolean to compare + * @param {boolean} b second boolean to compare + * @returns {boolean} true if the two booleans are always different, false otherwise + */ const isAlwaysDifferent = (a, b) => (a === true && b === false) || (a === false && b === true); + /** + * @param {BasicEvaluatedExpression} left left + * @param {BasicEvaluatedExpression} right right + * @param {BasicEvaluatedExpression} res res + * @param {boolean} eql true for "===" and false for "!==" + * @returns {BasicEvaluatedExpression | undefined} result + */ const handleTemplateStringCompare = (left, right, res, eql) => { + /** + * @param {BasicEvaluatedExpression[]} parts parts + * @returns {string} value + */ const getPrefix = parts => { let value = ""; for (const p of parts) { @@ -480,6 +720,10 @@ class JavascriptParser extends Parser { } return value; }; + /** + * @param {BasicEvaluatedExpression[]} parts parts + * @returns {string} value + */ const getSuffix = parts => { let value = ""; for (let i = parts.length - 1; i >= 0; i--) { @@ -489,17 +733,27 @@ class JavascriptParser extends Parser { } return value; }; - const leftPrefix = getPrefix(left.parts); - const rightPrefix = getPrefix(right.parts); - const leftSuffix = getSuffix(left.parts); - const rightSuffix = getSuffix(right.parts); + const leftPrefix = getPrefix( + /** @type {BasicEvaluatedExpression[]} */ (left.parts) + ); + const rightPrefix = getPrefix( + /** @type {BasicEvaluatedExpression[]} */ (right.parts) + ); + const leftSuffix = getSuffix( + /** @type {BasicEvaluatedExpression[]} */ (left.parts) + ); + const rightSuffix = getSuffix( + /** @type {BasicEvaluatedExpression[]} */ (right.parts) + ); const lenPrefix = Math.min(leftPrefix.length, rightPrefix.length); const lenSuffix = Math.min(leftSuffix.length, rightSuffix.length); - if ( - leftPrefix.slice(0, lenPrefix) !== - rightPrefix.slice(0, lenPrefix) || - leftSuffix.slice(-lenSuffix) !== rightSuffix.slice(-lenSuffix) - ) { + const prefixMismatch = + lenPrefix > 0 && + leftPrefix.slice(0, lenPrefix) !== rightPrefix.slice(0, lenPrefix); + const suffixMismatch = + lenSuffix > 0 && + leftSuffix.slice(-lenSuffix) !== rightSuffix.slice(-lenSuffix); + if (prefixMismatch || suffixMismatch) { return res .setBoolean(!eql) .setSideEffects( @@ -508,13 +762,16 @@ class JavascriptParser extends Parser { } }; + /** + * Helper function to handle BinaryExpressions using strict equality comparisons (e.g. "===" and "!=="). + * @param {boolean} eql true for "===" and false for "!==" + * @returns {BasicEvaluatedExpression | undefined} the evaluated expression + */ const handleStrictEqualityComparison = eql => { const left = this.evaluateExpression(expr.left); - if (!left) return; const right = this.evaluateExpression(expr.right); - if (!right) return; const res = new BasicEvaluatedExpression(); - res.setRange(expr.range); + res.setRange(/** @type {Range} */ (expr.range)); const leftConst = left.isCompileTimeValue(); const rightConst = right.isCompileTimeValue(); @@ -552,8 +809,14 @@ class JavascriptParser extends Parser { (rightPrimitive === false && (rightConst || leftPrimitive === true)) || // Different nullish or boolish status also means not equal - isAlwaysDifferent(left.asBool(), right.asBool()) || - isAlwaysDifferent(left.asNullish(), right.asNullish()) + isAlwaysDifferent( + /** @type {boolean} */ (left.asBool()), + /** @type {boolean} */ (right.asBool()) + ) || + isAlwaysDifferent( + /** @type {boolean} */ (left.asNullish()), + /** @type {boolean} */ (right.asNullish()) + ) ) { return res .setBoolean(!eql) @@ -563,13 +826,16 @@ class JavascriptParser extends Parser { } }; + /** + * Helper function to handle BinaryExpressions using abstract equality comparisons (e.g. "==" and "!="). + * @param {boolean} eql true for "==" and false for "!=" + * @returns {BasicEvaluatedExpression | undefined} the evaluated expression + */ const handleAbstractEqualityComparison = eql => { const left = this.evaluateExpression(expr.left); - if (!left) return; const right = this.evaluateExpression(expr.right); - if (!right) return; const res = new BasicEvaluatedExpression(); - res.setRange(expr.range); + res.setRange(/** @type {Range} */ (expr.range)); const leftConst = left.isCompileTimeValue(); const rightConst = right.isCompileTimeValue(); @@ -600,15 +866,16 @@ class JavascriptParser extends Parser { if (expr.operator === "+") { const left = this.evaluateExpression(expr.left); - if (!left) return; const right = this.evaluateExpression(expr.right); - if (!right) return; const res = new BasicEvaluatedExpression(); if (left.isString()) { if (right.isString()) { - res.setString(left.string + right.string); + res.setString( + /** @type {string} */ (left.string) + + /** @type {string} */ (right.string) + ); } else if (right.isNumber()) { - res.setString(left.string + right.number); + res.setString(/** @type {string} */ (left.string) + right.number); } else if ( right.isWrapped() && right.prefix && @@ -618,8 +885,16 @@ class JavascriptParser extends Parser { // => ("leftPrefix" + inner + "postfix") res.setWrapped( new BasicEvaluatedExpression() - .setString(left.string + right.prefix.string) - .setRange(joinRanges(left.range, right.prefix.range)), + .setString( + /** @type {string} */ (left.string) + + /** @type {string} */ (right.prefix.string) + ) + .setRange( + joinRanges( + /** @type {Range} */ (left.range), + /** @type {Range} */ (right.prefix.range) + ) + ), right.postfix, right.wrappedInnerExpressions ); @@ -638,15 +913,21 @@ class JavascriptParser extends Parser { } } else if (left.isNumber()) { if (right.isString()) { - res.setString(left.number + right.string); + res.setString(left.number + /** @type {string} */ (right.string)); } else if (right.isNumber()) { - res.setNumber(left.number + right.number); + res.setNumber( + /** @type {number} */ (left.number) + + /** @type {number} */ (right.number) + ); } else { return; } } else if (left.isBigInt()) { if (right.isBigInt()) { - res.setBigInt(left.bigint + right.bigint); + res.setBigInt( + /** @type {bigint} */ (left.bigint) + + /** @type {bigint} */ (right.bigint) + ); } } else if (left.isWrapped()) { if (left.postfix && left.postfix.isString() && right.isString()) { @@ -655,8 +936,16 @@ class JavascriptParser extends Parser { res.setWrapped( left.prefix, new BasicEvaluatedExpression() - .setString(left.postfix.string + right.string) - .setRange(joinRanges(left.postfix.range, right.range)), + .setString( + /** @type {string} */ (left.postfix.string) + + /** @type {string} */ (right.string) + ) + .setRange( + joinRanges( + /** @type {Range} */ (left.postfix.range), + /** @type {Range} */ (right.range) + ) + ), left.wrappedInnerExpressions ); } else if ( @@ -669,8 +958,16 @@ class JavascriptParser extends Parser { res.setWrapped( left.prefix, new BasicEvaluatedExpression() - .setString(left.postfix.string + right.number) - .setRange(joinRanges(left.postfix.range, right.range)), + .setString( + /** @type {string} */ (left.postfix.string) + + /** @type {number} */ (right.number) + ) + .setRange( + joinRanges( + /** @type {Range} */ (left.postfix.range), + /** @type {Range} */ (right.range) + ) + ), left.wrappedInnerExpressions ); } else if (right.isString()) { @@ -683,8 +980,8 @@ class JavascriptParser extends Parser { res.setWrapped( left.prefix, new BasicEvaluatedExpression() - .setString(right.number + "") - .setRange(right.range), + .setString(String(right.number)) + .setRange(/** @type {Range} */ (right.range)), left.wrappedInnerExpressions ); } else if (right.isWrapped()) { @@ -712,29 +1009,27 @@ class JavascriptParser extends Parser { ) ); } + } else if (right.isString()) { + // left + "right" + // => ([null] + left + "right") + res.setWrapped(null, right, [left]); + } else if (right.isWrapped()) { + // left + (prefix + inner + "postfix") + // => ([null] + left + prefix + inner + "postfix") + res.setWrapped( + null, + right.postfix, + right.wrappedInnerExpressions && + (right.prefix ? [left, right.prefix] : [left]).concat( + right.wrappedInnerExpressions + ) + ); } else { - if (right.isString()) { - // left + "right" - // => ([null] + left + "right") - res.setWrapped(null, right, [left]); - } else if (right.isWrapped()) { - // left + (prefix + inner + "postfix") - // => ([null] + left + prefix + inner + "postfix") - res.setWrapped( - null, - right.postfix, - right.wrappedInnerExpressions && - (right.prefix ? [left, right.prefix] : [left]).concat( - right.wrappedInnerExpressions - ) - ); - } else { - return; - } + return; } if (left.couldHaveSideEffects() || right.couldHaveSideEffects()) res.setSideEffects(); - res.setRange(expr.range); + res.setRange(/** @type {Range} */ (expr.range)); return res; } else if (expr.operator === "-") { return handleConstOperation((l, r) => l - r); @@ -777,12 +1072,18 @@ class JavascriptParser extends Parser { this.hooks.evaluate .for("UnaryExpression") .tap("JavascriptParser", _expr => { - const expr = /** @type {UnaryExpressionNode} */ (_expr); - - const handleConstOperation = fn => { + const expr = /** @type {UnaryExpression} */ (_expr); + + /** + * Evaluates a UnaryExpression if and only if it is a basic const operator (e.g. +a, -a, ~a). + * @template T + * @param {(operand: T) => boolean | number | bigint | string} operandHandler handler for the operand + * @returns {BasicEvaluatedExpression | undefined} evaluated expression + */ + const handleConstOperation = operandHandler => { const argument = this.evaluateExpression(expr.argument); - if (!argument || !argument.isCompileTimeValue()) return; - const result = fn(argument.asCompileTimeValue()); + if (!argument.isCompileTimeValue()) return; + const result = operandHandler(argument.asCompileTimeValue()); return valueAsExpression( result, expr, @@ -831,7 +1132,7 @@ class JavascriptParser extends Parser { case "FunctionExpression": { return new BasicEvaluatedExpression() .setString("function") - .setRange(expr.range); + .setRange(/** @type {Range} */ (expr.range)); } } const arg = this.evaluateExpression(expr.argument); @@ -839,79 +1140,88 @@ class JavascriptParser extends Parser { if (arg.isString()) { return new BasicEvaluatedExpression() .setString("string") - .setRange(expr.range); + .setRange(/** @type {Range} */ (expr.range)); } if (arg.isWrapped()) { return new BasicEvaluatedExpression() .setString("string") .setSideEffects() - .setRange(expr.range); + .setRange(/** @type {Range} */ (expr.range)); } if (arg.isUndefined()) { return new BasicEvaluatedExpression() .setString("undefined") - .setRange(expr.range); + .setRange(/** @type {Range} */ (expr.range)); } if (arg.isNumber()) { return new BasicEvaluatedExpression() .setString("number") - .setRange(expr.range); + .setRange(/** @type {Range} */ (expr.range)); } if (arg.isBigInt()) { return new BasicEvaluatedExpression() .setString("bigint") - .setRange(expr.range); + .setRange(/** @type {Range} */ (expr.range)); } if (arg.isBoolean()) { return new BasicEvaluatedExpression() .setString("boolean") - .setRange(expr.range); + .setRange(/** @type {Range} */ (expr.range)); } if (arg.isConstArray() || arg.isRegExp() || arg.isNull()) { return new BasicEvaluatedExpression() .setString("object") - .setRange(expr.range); + .setRange(/** @type {Range} */ (expr.range)); } if (arg.isArray()) { return new BasicEvaluatedExpression() .setString("object") .setSideEffects(arg.couldHaveSideEffects()) - .setRange(expr.range); + .setRange(/** @type {Range} */ (expr.range)); } } else if (expr.operator === "!") { const argument = this.evaluateExpression(expr.argument); - if (!argument) return; const bool = argument.asBool(); if (typeof bool !== "boolean") return; return new BasicEvaluatedExpression() .setBoolean(!bool) .setSideEffects(argument.couldHaveSideEffects()) - .setRange(expr.range); + .setRange(/** @type {Range} */ (expr.range)); } else if (expr.operator === "~") { return handleConstOperation(v => ~v); } else if (expr.operator === "+") { + // eslint-disable-next-line no-implicit-coercion return handleConstOperation(v => +v); } else if (expr.operator === "-") { return handleConstOperation(v => -v); } }); - this.hooks.evaluateTypeof.for("undefined").tap("JavascriptParser", expr => { - return new BasicEvaluatedExpression() - .setString("undefined") - .setRange(expr.range); + this.hooks.evaluateTypeof + .for("undefined") + .tap("JavascriptParser", expr => + new BasicEvaluatedExpression() + .setString("undefined") + .setRange(/** @type {Range} */ (expr.range)) + ); + this.hooks.evaluate.for("Identifier").tap("JavascriptParser", expr => { + if (/** @type {Identifier} */ (expr).name === "undefined") { + return new BasicEvaluatedExpression() + .setUndefined() + .setRange(/** @type {Range} */ (expr.range)); + } }); /** * @param {string} exprType expression type name - * @param {function(ExpressionNode): GetInfoResult | undefined} getInfo get info + * @param {function(Expression | SpreadElement): GetInfoResult | undefined} getInfo get info * @returns {void} */ const tapEvaluateWithVariableInfo = (exprType, getInfo) => { - /** @type {ExpressionNode | undefined} */ - let cachedExpression = undefined; + /** @type {Expression | undefined} */ + let cachedExpression; /** @type {GetInfoResult | undefined} */ - let cachedInfo = undefined; + let cachedInfo; this.hooks.evaluate.for(exprType).tap("JavascriptParser", expr => { - const expression = /** @type {MemberExpressionNode} */ (expr); + const expression = /** @type {MemberExpression} */ (expr); const info = getInfo(expr); if (info !== undefined) { @@ -938,20 +1248,34 @@ class JavascriptParser extends Parser { const info = cachedExpression === expr ? cachedInfo : getInfo(expr); if (info !== undefined) { return new BasicEvaluatedExpression() - .setIdentifier(info.name, info.rootInfo, info.getMembers) - .setRange(expr.range); + .setIdentifier( + info.name, + info.rootInfo, + info.getMembers, + info.getMembersOptionals, + info.getMemberRanges + ) + .setRange(/** @type {Range} */ (expr.range)); } }); + this.hooks.finish.tap("JavascriptParser", () => { + // Cleanup for GC + cachedExpression = cachedInfo = undefined; + }); }; tapEvaluateWithVariableInfo("Identifier", expr => { - const info = this.getVariableInfo( - /** @type {IdentifierNode} */ (expr).name - ); + const info = this.getVariableInfo(/** @type {Identifier} */ (expr).name); if ( typeof info === "string" || (info instanceof VariableInfo && typeof info.freeName === "string") ) { - return { name: info, rootInfo: info, getMembers: () => [] }; + return { + name: info, + rootInfo: info, + getMembers: () => [], + getMembersOptionals: () => [], + getMemberRanges: () => [] + }; } }); tapEvaluateWithVariableInfo("ThisExpression", expr => { @@ -960,11 +1284,17 @@ class JavascriptParser extends Parser { typeof info === "string" || (info instanceof VariableInfo && typeof info.freeName === "string") ) { - return { name: info, rootInfo: info, getMembers: () => [] }; + return { + name: info, + rootInfo: info, + getMembers: () => [], + getMembersOptionals: () => [], + getMemberRanges: () => [] + }; } }); this.hooks.evaluate.for("MetaProperty").tap("JavascriptParser", expr => { - const metaProperty = /** @type {MetaPropertyNode} */ (expr); + const metaProperty = /** @type {MetaProperty} */ (expr); return this.callHooksForName( this.hooks.evaluateIdentifier, @@ -974,33 +1304,36 @@ class JavascriptParser extends Parser { }); tapEvaluateWithVariableInfo("MemberExpression", expr => this.getMemberExpressionInfo( - /** @type {MemberExpressionNode} */ (expr), + /** @type {MemberExpression} */ (expr), ALLOWED_MEMBER_TYPES_EXPRESSION ) ); this.hooks.evaluate.for("CallExpression").tap("JavascriptParser", _expr => { - const expr = /** @type {CallExpressionNode} */ (_expr); + const expr = /** @type {CallExpression} */ (_expr); if ( - expr.callee.type !== "MemberExpression" || - expr.callee.property.type !== + expr.callee.type === "MemberExpression" && + expr.callee.property.type === (expr.callee.computed ? "Literal" : "Identifier") ) { - return; - } - - // type Super also possible here - const param = this.evaluateExpression( - /** @type {ExpressionNode} */ (expr.callee.object) - ); - if (!param) return; - const property = - expr.callee.property.type === "Literal" - ? `${expr.callee.property.value}` - : expr.callee.property.name; - const hook = this.hooks.evaluateCallExpressionMember.get(property); - if (hook !== undefined) { - return hook.call(expr, param); + // type Super also possible here + const param = this.evaluateExpression( + /** @type {Expression} */ (expr.callee.object) + ); + const property = + expr.callee.property.type === "Literal" + ? `${expr.callee.property.value}` + : expr.callee.property.name; + const hook = this.hooks.evaluateCallExpressionMember.get(property); + if (hook !== undefined) { + return hook.call(expr, param); + } + } else if (expr.callee.type === "Identifier") { + return this.callHooksForName( + this.hooks.evaluateCallExpression, + expr.callee.name, + expr + ); } }); this.hooks.evaluateCallExpressionMember @@ -1012,21 +1345,24 @@ class JavascriptParser extends Parser { if (arg1.type === "SpreadElement") return; const arg1Eval = this.evaluateExpression(arg1); if (!arg1Eval.isString()) return; - const arg1Value = arg1Eval.string; + const arg1Value = /** @type {string} */ (arg1Eval.string); let result; if (arg2) { if (arg2.type === "SpreadElement") return; const arg2Eval = this.evaluateExpression(arg2); if (!arg2Eval.isNumber()) return; - result = param.string.indexOf(arg1Value, arg2Eval.number); + result = /** @type {string} */ (param.string).indexOf( + arg1Value, + arg2Eval.number + ); } else { - result = param.string.indexOf(arg1Value); + result = /** @type {string} */ (param.string).indexOf(arg1Value); } return new BasicEvaluatedExpression() .setNumber(result) .setSideEffects(param.couldHaveSideEffects()) - .setRange(expr.range); + .setRange(/** @type {Range} */ (expr.range)); }); this.hooks.evaluateCallExpressionMember .for("replace") @@ -1035,31 +1371,37 @@ class JavascriptParser extends Parser { if (expr.arguments.length !== 2) return; if (expr.arguments[0].type === "SpreadElement") return; if (expr.arguments[1].type === "SpreadElement") return; - let arg1 = this.evaluateExpression(expr.arguments[0]); - let arg2 = this.evaluateExpression(expr.arguments[1]); + const arg1 = this.evaluateExpression(expr.arguments[0]); + const arg2 = this.evaluateExpression(expr.arguments[1]); if (!arg1.isString() && !arg1.isRegExp()) return; - const arg1Value = arg1.regExp || arg1.string; + const arg1Value = /** @type {string | RegExp} */ ( + arg1.regExp || arg1.string + ); if (!arg2.isString()) return; - const arg2Value = arg2.string; + const arg2Value = /** @type {string} */ (arg2.string); return new BasicEvaluatedExpression() - .setString(param.string.replace(arg1Value, arg2Value)) + .setString( + /** @type {string} */ (param.string).replace(arg1Value, arg2Value) + ) .setSideEffects(param.couldHaveSideEffects()) - .setRange(expr.range); + .setRange(/** @type {Range} */ (expr.range)); }); - ["substr", "substring", "slice"].forEach(fn => { + for (const fn of ["substr", "substring", "slice"]) { this.hooks.evaluateCallExpressionMember .for(fn) .tap("JavascriptParser", (expr, param) => { if (!param.isString()) return; let arg1; - let result, - str = param.string; + let result; + const str = /** @type {string} */ (param.string); switch (expr.arguments.length) { case 1: if (expr.arguments[0].type === "SpreadElement") return; arg1 = this.evaluateExpression(expr.arguments[0]); if (!arg1.isNumber()) return; - result = str[fn](arg1.number); + result = str[ + /** @type {"substr" | "substring" | "slice"} */ (fn) + ](/** @type {number} */ (arg1.number)); break; case 2: { if (expr.arguments[0].type === "SpreadElement") return; @@ -1068,7 +1410,12 @@ class JavascriptParser extends Parser { const arg2 = this.evaluateExpression(expr.arguments[1]); if (!arg1.isNumber()) return; if (!arg2.isNumber()) return; - result = str[fn](arg1.number, arg2.number); + result = str[ + /** @type {"substr" | "substring" | "slice"} */ (fn) + ]( + /** @type {number} */ (arg1.number), + /** @type {number} */ (arg2.number) + ); break; } default: @@ -1077,13 +1424,13 @@ class JavascriptParser extends Parser { return new BasicEvaluatedExpression() .setString(result) .setSideEffects(param.couldHaveSideEffects()) - .setRange(expr.range); + .setRange(/** @type {Range} */ (expr.range)); }); - }); + } /** * @param {"cooked" | "raw"} kind kind of values to get - * @param {TemplateLiteralNode} templateLiteralExpr TemplateLiteral expr + * @param {TemplateLiteral} templateLiteralExpr TemplateLiteral expr * @returns {{quasis: BasicEvaluatedExpression[], parts: BasicEvaluatedExpression[]}} Simplified template */ const getSimplifiedTemplateResult = (kind, templateLiteralExpr) => { @@ -1110,7 +1457,10 @@ class JavascriptParser extends Parser { // is a const string prevExpr.setString(prevExpr.string + exprAsString + quasi); - prevExpr.setRange([prevExpr.range[0], quasiExpr.range[1]]); + prevExpr.setRange([ + /** @type {Range} */ (prevExpr.range)[0], + /** @type {Range} */ (quasiExpr.range)[1] + ]); // We unset the expression as it doesn't match to a single expression prevExpr.setExpression(undefined); continue; @@ -1119,8 +1469,8 @@ class JavascriptParser extends Parser { } const part = new BasicEvaluatedExpression() - .setString(quasi) - .setRange(quasiExpr.range) + .setString(/** @type {string} */ (quasi)) + .setRange(/** @type {Range} */ (quasiExpr.range)) .setExpression(quasiExpr); quasis.push(part); parts.push(part); @@ -1134,37 +1484,37 @@ class JavascriptParser extends Parser { this.hooks.evaluate .for("TemplateLiteral") .tap("JavascriptParser", _node => { - const node = /** @type {TemplateLiteralNode} */ (_node); + const node = /** @type {TemplateLiteral} */ (_node); const { quasis, parts } = getSimplifiedTemplateResult("cooked", node); if (parts.length === 1) { - return parts[0].setRange(node.range); + return parts[0].setRange(/** @type {Range} */ (node.range)); } return new BasicEvaluatedExpression() .setTemplateString(quasis, parts, "cooked") - .setRange(node.range); + .setRange(/** @type {Range} */ (node.range)); }); this.hooks.evaluate .for("TaggedTemplateExpression") .tap("JavascriptParser", _node => { - const node = /** @type {TaggedTemplateExpressionNode} */ (_node); + const node = /** @type {TaggedTemplateExpression} */ (_node); const tag = this.evaluateExpression(node.tag); - if (tag.isIdentifier() && tag.identifier !== "String.raw") return; - const { quasis, parts } = getSimplifiedTemplateResult( - "raw", - node.quasi - ); - return new BasicEvaluatedExpression() - .setTemplateString(quasis, parts, "raw") - .setRange(node.range); + if (tag.isIdentifier() && tag.identifier === "String.raw") { + const { quasis, parts } = getSimplifiedTemplateResult( + "raw", + node.quasi + ); + return new BasicEvaluatedExpression() + .setTemplateString(quasis, parts, "raw") + .setRange(/** @type {Range} */ (node.range)); + } }); this.hooks.evaluateCallExpressionMember .for("concat") .tap("JavascriptParser", (expr, param) => { if (!param.isString() && !param.isWrapped()) return; - let stringSuffix = null; let hasUnknownParams = false; const innerExpressions = []; @@ -1181,15 +1531,17 @@ class JavascriptParser extends Parser { continue; } + /** @type {string} */ const value = argExpr.isString() - ? argExpr.string - : "" + argExpr.number; + ? /** @type {string} */ (argExpr.string) + : String(/** @type {number} */ (argExpr.number)); + /** @type {string} */ const newString = value + (stringSuffix ? stringSuffix.string : ""); - const newRange = [ - argExpr.range[0], - (stringSuffix || argExpr).range[1] - ]; + const newRange = /** @type {Range} */ ([ + /** @type {Range} */ (argExpr.range)[0], + /** @type {Range} */ ((stringSuffix || argExpr).range)[1] + ]); stringSuffix = new BasicEvaluatedExpression() .setString(newString) .setSideEffects( @@ -1207,7 +1559,7 @@ class JavascriptParser extends Parser { : innerExpressions.reverse(); return new BasicEvaluatedExpression() .setWrapped(prefix, stringSuffix, inner) - .setRange(expr.range); + .setRange(/** @type {Range} */ (expr.range)); } else if (param.isWrapped()) { const postfix = stringSuffix || param.postfix; const inner = param.wrappedInnerExpressions @@ -1215,18 +1567,18 @@ class JavascriptParser extends Parser { : innerExpressions.reverse(); return new BasicEvaluatedExpression() .setWrapped(param.prefix, postfix, inner) - .setRange(expr.range); - } else { - const newString = - param.string + (stringSuffix ? stringSuffix.string : ""); - return new BasicEvaluatedExpression() - .setString(newString) - .setSideEffects( - (stringSuffix && stringSuffix.couldHaveSideEffects()) || - param.couldHaveSideEffects() - ) - .setRange(expr.range); + .setRange(/** @type {Range} */ (expr.range)); } + const newString = + /** @type {string} */ (param.string) + + (stringSuffix ? stringSuffix.string : ""); + return new BasicEvaluatedExpression() + .setString(newString) + .setSideEffects( + (stringSuffix && stringSuffix.couldHaveSideEffects()) || + param.couldHaveSideEffects() + ) + .setRange(/** @type {Range} */ (expr.range)); }); this.hooks.evaluateCallExpressionMember .for("split") @@ -1237,21 +1589,25 @@ class JavascriptParser extends Parser { let result; const arg = this.evaluateExpression(expr.arguments[0]); if (arg.isString()) { - result = param.string.split(arg.string); + result = + /** @type {string} */ + (param.string).split(/** @type {string} */ (arg.string)); } else if (arg.isRegExp()) { - result = param.string.split(arg.regExp); + result = /** @type {string} */ (param.string).split( + /** @type {RegExp} */ (arg.regExp) + ); } else { return; } return new BasicEvaluatedExpression() .setArray(result) .setSideEffects(param.couldHaveSideEffects()) - .setRange(expr.range); + .setRange(/** @type {Range} */ (expr.range)); }); this.hooks.evaluate .for("ConditionalExpression") .tap("JavascriptParser", _expr => { - const expr = /** @type {ConditionalExpressionNode} */ (_expr); + const expr = /** @type {ConditionalExpression} */ (_expr); const condition = this.evaluateExpression(expr.test); const conditionValue = condition.asBool(); @@ -1259,15 +1615,18 @@ class JavascriptParser extends Parser { if (conditionValue === undefined) { const consequent = this.evaluateExpression(expr.consequent); const alternate = this.evaluateExpression(expr.alternate); - if (!consequent || !alternate) return; res = new BasicEvaluatedExpression(); if (consequent.isConditional()) { - res.setOptions(consequent.options); + res.setOptions( + /** @type {BasicEvaluatedExpression[]} */ (consequent.options) + ); } else { res.setOptions([consequent]); } if (alternate.isConditional()) { - res.addOptions(alternate.options); + res.addOptions( + /** @type {BasicEvaluatedExpression[]} */ (alternate.options) + ); } else { res.addOptions([alternate]); } @@ -1277,33 +1636,32 @@ class JavascriptParser extends Parser { ); if (condition.couldHaveSideEffects()) res.setSideEffects(); } - res.setRange(expr.range); + res.setRange(/** @type {Range} */ (expr.range)); return res; }); this.hooks.evaluate .for("ArrayExpression") .tap("JavascriptParser", _expr => { - const expr = /** @type {ArrayExpressionNode} */ (_expr); + const expr = /** @type {ArrayExpression} */ (_expr); - const items = expr.elements.map(element => { - return ( + const items = expr.elements.map( + element => element !== null && element.type !== "SpreadElement" && this.evaluateExpression(element) - ); - }); + ); if (!items.every(Boolean)) return; return new BasicEvaluatedExpression() - .setItems(items) - .setRange(expr.range); + .setItems(/** @type {BasicEvaluatedExpression[]} */ (items)) + .setRange(/** @type {Range} */ (expr.range)); }); this.hooks.evaluate .for("ChainExpression") .tap("JavascriptParser", _expr => { - const expr = /** @type {ChainExpressionNode} */ (_expr); - /** @type {ExpressionNode[]} */ + const expr = /** @type {ChainExpression} */ (_expr); + /** @type {Expression[]} */ const optionalExpressionsStack = []; - /** @type {ExpressionNode|SuperNode} */ + /** @type {Expression|Super} */ let next = expr.expression; while ( @@ -1314,7 +1672,7 @@ class JavascriptParser extends Parser { if (next.optional) { // SuperNode can not be optional optionalExpressionsStack.push( - /** @type {ExpressionNode} */ (next.object) + /** @type {Expression} */ (next.object) ); } next = next.object; @@ -1322,7 +1680,7 @@ class JavascriptParser extends Parser { if (next.optional) { // SuperNode can not be optional optionalExpressionsStack.push( - /** @type {ExpressionNode} */ (next.callee) + /** @type {Expression} */ (next.callee) ); } next = next.callee; @@ -1330,59 +1688,91 @@ class JavascriptParser extends Parser { } while (optionalExpressionsStack.length > 0) { - const expression = optionalExpressionsStack.pop(); + const expression = + /** @type {Expression} */ + (optionalExpressionsStack.pop()); const evaluated = this.evaluateExpression(expression); - if (evaluated && evaluated.asNullish()) { - return evaluated.setRange(_expr.range); + if (evaluated.asNullish()) { + return evaluated.setRange(/** @type {Range} */ (_expr.range)); } } return this.evaluateExpression(expr.expression); }); } + /** + * @param {Expression} node node + * @returns {Set | undefined} destructured identifiers + */ + destructuringAssignmentPropertiesFor(node) { + if (!this.destructuringAssignmentProperties) return; + return this.destructuringAssignmentProperties.get(node); + } + + /** + * @param {Expression} expr expression + * @returns {string | VariableInfoInterface | undefined} identifier + */ getRenameIdentifier(expr) { const result = this.evaluateExpression(expr); - if (result && result.isIdentifier()) { + if (result.isIdentifier()) { return result.identifier; } } /** - * @param {ClassExpressionNode | ClassDeclarationNode} classy a class node + * @param {ClassExpression | ClassDeclaration} classy a class node * @returns {void} */ walkClass(classy) { - if (classy.superClass) { - if (!this.hooks.classExtendsExpression.call(classy.superClass, classy)) { - this.walkExpression(classy.superClass); - } + if ( + classy.superClass && + !this.hooks.classExtendsExpression.call(classy.superClass, classy) + ) { + this.walkExpression(classy.superClass); } if (classy.body && classy.body.type === "ClassBody") { - const wasTopLevel = this.scope.topLevelScope; - for (const classElement of classy.body.body) { - if (!this.hooks.classBodyElement.call(classElement, classy)) { - if (classElement.type === "MethodDefinition") { - this.scope.topLevelScope = false; - this.walkMethodDefinition(classElement); - this.scope.topLevelScope = wasTopLevel; + const scopeParams = []; + // Add class name in scope for recursive calls + if (classy.id) { + scopeParams.push(classy.id); + } + this.inClassScope(true, scopeParams, () => { + for (const classElement of /** @type {TODO} */ (classy.body.body)) { + if (!this.hooks.classBodyElement.call(classElement, classy)) { + if (classElement.computed && classElement.key) { + this.walkExpression(classElement.key); + } + if (classElement.value) { + if ( + !this.hooks.classBodyValue.call( + classElement.value, + classElement, + classy + ) + ) { + const wasTopLevel = this.scope.topLevelScope; + this.scope.topLevelScope = false; + this.walkExpression(classElement.value); + this.scope.topLevelScope = wasTopLevel; + } + } else if (classElement.type === "StaticBlock") { + const wasTopLevel = this.scope.topLevelScope; + this.scope.topLevelScope = false; + this.walkBlockStatement(classElement); + this.scope.topLevelScope = wasTopLevel; + } } - // TODO add support for ClassProperty here once acorn supports it } - } - } - } - - walkMethodDefinition(methodDefinition) { - if (methodDefinition.computed && methodDefinition.key) { - this.walkExpression(methodDefinition.key); - } - if (methodDefinition.value) { - this.walkExpression(methodDefinition.value); + }); } } - // Pre walking iterates the scope for variable declarations + /** + * Pre walking iterates the scope for variable declarations + * @param {(Statement | ModuleDeclaration)[]} statements statements + */ preWalkStatements(statements) { for (let index = 0, len = statements.length; index < len; index++) { const statement = statements[index]; @@ -1390,7 +1780,10 @@ class JavascriptParser extends Parser { } } - // Block pre walking iterates the scope for block variable declarations + /** + * Block pre walking iterates the scope for block variable declarations + * @param {(Statement | ModuleDeclaration)[]} statements statements + */ blockPreWalkStatements(statements) { for (let index = 0, len = statements.length; index < len; index++) { const statement = statements[index]; @@ -1398,7 +1791,10 @@ class JavascriptParser extends Parser { } } - // Walking iterates the statements and expressions and processes them + /** + * Walking iterates the statements and expressions and processes them + * @param {(Statement | ModuleDeclaration)[]} statements statements + */ walkStatements(statements) { for (let index = 0, len = statements.length; index < len; index++) { const statement = statements[index]; @@ -1406,6 +1802,10 @@ class JavascriptParser extends Parser { } } + /** + * Walking iterates the statements and expressions and processes them + * @param {Statement | ModuleDeclaration} statement statement + */ preWalkStatement(statement) { this.statementPath.push(statement); if (this.hooks.preStatement.call(statement)) { @@ -1456,6 +1856,9 @@ class JavascriptParser extends Parser { this.prevStatement = this.statementPath.pop(); } + /** + * @param {Statement | ModuleDeclaration} statement statement + */ blockPreWalkStatement(statement) { this.statementPath.push(statement); if (this.hooks.blockPreStatement.call(statement)) { @@ -1481,10 +1884,15 @@ class JavascriptParser extends Parser { case "ClassDeclaration": this.blockPreWalkClassDeclaration(statement); break; + case "ExpressionStatement": + this.blockPreWalkExpressionStatement(statement); } this.prevStatement = this.statementPath.pop(); } + /** + * @param {Statement | ModuleDeclaration} statement statement + */ walkStatement(statement) { this.statementPath.push(statement); if (this.hooks.statement.call(statement) !== undefined) { @@ -1557,8 +1965,7 @@ class JavascriptParser extends Parser { * Walks a statements that is nested within a parent statement * and can potentially be a non-block statement. * This enforces the nested statement to never be in ASI position. - * @param {StatementNode} statement the nested statement - * @returns {void} + * @param {Statement} statement the nested statement */ walkNestedStatement(statement) { this.prevStatement = undefined; @@ -1566,10 +1973,16 @@ class JavascriptParser extends Parser { } // Real Statements + /** + * @param {BlockStatement} statement block statement + */ preWalkBlockStatement(statement) { this.preWalkStatements(statement.body); } + /** + * @param {BlockStatement} statement block statement + */ walkBlockStatement(statement) { this.inBlockScope(() => { const body = statement.body; @@ -1580,10 +1993,16 @@ class JavascriptParser extends Parser { }); } + /** + * @param {ExpressionStatement} statement expression statement + */ walkExpressionStatement(statement) { this.walkExpression(statement.expression); } + /** + * @param {IfStatement} statement if statement + */ preWalkIfStatement(statement) { this.preWalkStatement(statement.consequent); if (statement.alternate) { @@ -1591,6 +2010,9 @@ class JavascriptParser extends Parser { } } + /** + * @param {IfStatement} statement if statement + */ walkIfStatement(statement) { const result = this.hooks.statementIf.call(statement); if (result === undefined) { @@ -1599,19 +2021,23 @@ class JavascriptParser extends Parser { if (statement.alternate) { this.walkNestedStatement(statement.alternate); } - } else { - if (result) { - this.walkNestedStatement(statement.consequent); - } else if (statement.alternate) { - this.walkNestedStatement(statement.alternate); - } + } else if (result) { + this.walkNestedStatement(statement.consequent); + } else if (statement.alternate) { + this.walkNestedStatement(statement.alternate); } } + /** + * @param {LabeledStatement} statement with statement + */ preWalkLabeledStatement(statement) { this.preWalkStatement(statement.body); } + /** + * @param {LabeledStatement} statement with statement + */ walkLabeledStatement(statement) { const hook = this.hooks.label.get(statement.label.name); if (hook !== undefined) { @@ -1621,42 +2047,69 @@ class JavascriptParser extends Parser { this.walkNestedStatement(statement.body); } + /** + * @param {WithStatement} statement with statement + */ preWalkWithStatement(statement) { this.preWalkStatement(statement.body); } + /** + * @param {WithStatement} statement with statement + */ walkWithStatement(statement) { this.walkExpression(statement.object); this.walkNestedStatement(statement.body); } + /** + * @param {SwitchStatement} statement switch statement + */ preWalkSwitchStatement(statement) { this.preWalkSwitchCases(statement.cases); } + /** + * @param {SwitchStatement} statement switch statement + */ walkSwitchStatement(statement) { this.walkExpression(statement.discriminant); this.walkSwitchCases(statement.cases); } + /** + * @param {ReturnStatement | ThrowStatement} statement return or throw statement + */ walkTerminatingStatement(statement) { if (statement.argument) this.walkExpression(statement.argument); } + /** + * @param {ReturnStatement} statement return statement + */ walkReturnStatement(statement) { this.walkTerminatingStatement(statement); } + /** + * @param {ThrowStatement} statement return statement + */ walkThrowStatement(statement) { this.walkTerminatingStatement(statement); } + /** + * @param {TryStatement} statement try statement + */ preWalkTryStatement(statement) { this.preWalkStatement(statement.block); if (statement.handler) this.preWalkCatchClause(statement.handler); - if (statement.finializer) this.preWalkStatement(statement.finializer); + if (statement.finalizer) this.preWalkStatement(statement.finalizer); } + /** + * @param {TryStatement} statement try statement + */ walkTryStatement(statement) { if (this.scope.inTry) { this.walkStatement(statement.block); @@ -1669,33 +2122,49 @@ class JavascriptParser extends Parser { if (statement.finalizer) this.walkStatement(statement.finalizer); } + /** + * @param {WhileStatement} statement while statement + */ preWalkWhileStatement(statement) { this.preWalkStatement(statement.body); } + /** + * @param {WhileStatement} statement while statement + */ walkWhileStatement(statement) { this.walkExpression(statement.test); this.walkNestedStatement(statement.body); } + /** + * @param {DoWhileStatement} statement do while statement + */ preWalkDoWhileStatement(statement) { this.preWalkStatement(statement.body); } + /** + * @param {DoWhileStatement} statement do while statement + */ walkDoWhileStatement(statement) { this.walkNestedStatement(statement.body); this.walkExpression(statement.test); } + /** + * @param {ForStatement} statement for statement + */ preWalkForStatement(statement) { - if (statement.init) { - if (statement.init.type === "VariableDeclaration") { - this.preWalkStatement(statement.init); - } + if (statement.init && statement.init.type === "VariableDeclaration") { + this.preWalkStatement(statement.init); } this.preWalkStatement(statement.body); } + /** + * @param {ForStatement} statement for statement + */ walkForStatement(statement) { this.inBlockScope(() => { if (statement.init) { @@ -1726,6 +2195,9 @@ class JavascriptParser extends Parser { }); } + /** + * @param {ForInStatement} statement for statement + */ preWalkForInStatement(statement) { if (statement.left.type === "VariableDeclaration") { this.preWalkVariableDeclaration(statement.left); @@ -1733,6 +2205,9 @@ class JavascriptParser extends Parser { this.preWalkStatement(statement.body); } + /** + * @param {ForInStatement} statement for statement + */ walkForInStatement(statement) { this.inBlockScope(() => { if (statement.left.type === "VariableDeclaration") { @@ -1755,6 +2230,9 @@ class JavascriptParser extends Parser { }); } + /** + * @param {ForOfStatement} statement statement + */ preWalkForOfStatement(statement) { if (statement.await && this.scope.topLevelScope === true) { this.hooks.topLevelAwait.call(statement); @@ -1765,6 +2243,9 @@ class JavascriptParser extends Parser { this.preWalkStatement(statement.body); } + /** + * @param {ForOfStatement} statement for statement + */ walkForOfStatement(statement) { this.inBlockScope(() => { if (statement.left.type === "VariableDeclaration") { @@ -1787,13 +2268,18 @@ class JavascriptParser extends Parser { }); } - // Declarations + /** + * @param {FunctionDeclaration} statement function declaration + */ preWalkFunctionDeclaration(statement) { if (statement.id) { this.defineVariable(statement.id.name); } } + /** + * @param {FunctionDeclaration} statement function declaration + */ walkFunctionDeclaration(statement) { const wasTopLevel = this.scope.topLevelScope; this.scope.topLevelScope = false; @@ -1814,8 +2300,55 @@ class JavascriptParser extends Parser { this.scope.topLevelScope = wasTopLevel; } + /** + * @param {ExpressionStatement} statement expression statement + */ + blockPreWalkExpressionStatement(statement) { + const expression = statement.expression; + switch (expression.type) { + case "AssignmentExpression": + this.preWalkAssignmentExpression(expression); + } + } + + /** + * @param {AssignmentExpression} expression assignment expression + */ + preWalkAssignmentExpression(expression) { + if ( + expression.left.type !== "ObjectPattern" || + !this.destructuringAssignmentProperties + ) + return; + const keys = this._preWalkObjectPattern(expression.left); + if (!keys) return; + + // check multiple assignments + if (this.destructuringAssignmentProperties.has(expression)) { + const set = + /** @type {Set} */ + (this.destructuringAssignmentProperties.get(expression)); + this.destructuringAssignmentProperties.delete(expression); + for (const id of set) keys.add(id); + } + + this.destructuringAssignmentProperties.set( + expression.right.type === "AwaitExpression" + ? expression.right.argument + : expression.right, + keys + ); + + if (expression.right.type === "AssignmentExpression") { + this.preWalkAssignmentExpression(expression.right); + } + } + + /** + * @param {ImportDeclaration} statement statement + */ blockPreWalkImportDeclaration(statement) { - const source = statement.source.value; + const source = /** @type {ImportSource} */ (statement.source.value); this.hooks.import.call(statement, source); for (const specifier of statement.specifiers) { const name = specifier.local.name; @@ -1832,7 +2365,12 @@ class JavascriptParser extends Parser { !this.hooks.importSpecifier.call( statement, source, - specifier.imported.name, + specifier.imported.name || + // eslint-disable-next-line no-warning-comments + // @ts-ignore + // Old version of acorn used it + // TODO drop it in webpack@6 + specifier.imported.value, name ) ) { @@ -1850,6 +2388,10 @@ class JavascriptParser extends Parser { } } + /** + * @param {Declaration} declaration declaration + * @param {OnIdent} onIdent on ident callback + */ enterDeclaration(declaration, onIdent) { switch (declaration.type) { case "VariableDeclaration": @@ -1871,27 +2413,29 @@ class JavascriptParser extends Parser { } } + /** + * @param {ExportNamedDeclaration} statement statement + */ blockPreWalkExportNamedDeclaration(statement) { let source; if (statement.source) { - source = statement.source.value; + source = /** @type {ImportSource} */ (statement.source.value); this.hooks.exportImport.call(statement, source); } else { this.hooks.export.call(statement); } - if (statement.declaration) { - if ( - !this.hooks.exportDeclaration.call(statement, statement.declaration) - ) { - const prev = this.prevStatement; - this.preWalkStatement(statement.declaration); - this.prevStatement = prev; - this.blockPreWalkStatement(statement.declaration); - let index = 0; - this.enterDeclaration(statement.declaration, def => { - this.hooks.exportSpecifier.call(statement, def, def, index++); - }); - } + if ( + statement.declaration && + !this.hooks.exportDeclaration.call(statement, statement.declaration) + ) { + const prev = this.prevStatement; + this.preWalkStatement(statement.declaration); + this.prevStatement = prev; + this.blockPreWalkStatement(statement.declaration); + let index = 0; + this.enterDeclaration(statement.declaration, def => { + this.hooks.exportSpecifier.call(statement, def, def, index++); + }); } if (statement.specifiers) { for ( @@ -1902,7 +2446,13 @@ class JavascriptParser extends Parser { const specifier = statement.specifiers[specifierIndex]; switch (specifier.type) { case "ExportSpecifier": { - const name = specifier.exported.name; + const name = + specifier.exported.name || + // eslint-disable-next-line no-warning-comments + // @ts-ignore + // Old version of acorn used it + // TODO drop it in webpack@6 + specifier.exported.value; if (source) { this.hooks.exportImportSpecifier.call( statement, @@ -1926,42 +2476,59 @@ class JavascriptParser extends Parser { } } + /** + * @param {ExportNamedDeclaration} statement the statement + */ walkExportNamedDeclaration(statement) { if (statement.declaration) { this.walkStatement(statement.declaration); } } + /** + * @param {TODO} statement statement + */ blockPreWalkExportDefaultDeclaration(statement) { const prev = this.prevStatement; this.preWalkStatement(statement.declaration); this.prevStatement = prev; this.blockPreWalkStatement(statement.declaration); if ( - statement.declaration.id && + /** @type {FunctionDeclaration | ClassDeclaration} */ ( + statement.declaration + ).id && statement.declaration.type !== "FunctionExpression" && statement.declaration.type !== "ClassExpression" ) { + const declaration = + /** @type {FunctionDeclaration | ClassDeclaration} */ + (statement.declaration); this.hooks.exportSpecifier.call( statement, - statement.declaration.id.name, + declaration.id.name, "default", undefined ); } } - walkExportDefaultDeclaration(statement) { + /** + * @param {ExportDefaultDeclaration} statement statement + */ + walkExportDefaultDeclaration(statement) { this.hooks.export.call(statement); if ( - statement.declaration.id && + /** @type {FunctionDeclaration | ClassDeclaration} */ ( + statement.declaration + ).id && statement.declaration.type !== "FunctionExpression" && statement.declaration.type !== "ClassExpression" ) { - if ( - !this.hooks.exportDeclaration.call(statement, statement.declaration) - ) { - this.walkStatement(statement.declaration); + const declaration = + /** @type {FunctionDeclaration | ClassDeclaration} */ + (statement.declaration); + if (!this.hooks.exportDeclaration.call(statement, declaration)) { + this.walkStatement(declaration); } } else { // Acorn parses `export default function() {}` as `FunctionDeclaration` and @@ -1971,14 +2538,23 @@ class JavascriptParser extends Parser { statement.declaration.type === "FunctionDeclaration" || statement.declaration.type === "ClassDeclaration" ) { - this.walkStatement(statement.declaration); + this.walkStatement( + /** @type {FunctionDeclaration | ClassDeclaration} */ + (statement.declaration) + ); } else { this.walkExpression(statement.declaration); } - if (!this.hooks.exportExpression.call(statement, statement.declaration)) { + + if ( + !this.hooks.exportExpression.call( + statement, + /** @type {TODO} */ (statement).declaration + ) + ) { this.hooks.exportSpecifier.call( statement, - statement.declaration, + /** @type {TODO} */ (statement.declaration), "default", undefined ); @@ -1986,18 +2562,27 @@ class JavascriptParser extends Parser { } } + /** + * @param {ExportAllDeclaration} statement statement + */ blockPreWalkExportAllDeclaration(statement) { - const source = statement.source.value; + const source = /** @type {ImportSource} */ (statement.source.value); const name = statement.exported ? statement.exported.name : null; this.hooks.exportImport.call(statement, source); this.hooks.exportImportSpecifier.call(statement, source, null, name, 0); } + /** + * @param {VariableDeclaration} statement variable declaration + */ preWalkVariableDeclaration(statement) { if (statement.kind !== "var") return; this._preWalkVariableDeclaration(statement, this.hooks.varDeclarationVar); } + /** + * @param {VariableDeclaration} statement variable declaration + */ blockPreWalkVariableDeclaration(statement) { if (statement.kind === "var") return; const hookMap = @@ -2007,10 +2592,15 @@ class JavascriptParser extends Parser { this._preWalkVariableDeclaration(statement, hookMap); } + /** + * @param {VariableDeclaration} statement variable declaration + * @param {TODO} hookMap map of hooks + */ _preWalkVariableDeclaration(statement, hookMap) { for (const declarator of statement.declarations) { switch (declarator.type) { case "VariableDeclarator": { + this.preWalkVariableDeclarator(declarator); if (!this.hooks.preDeclarator.call(declarator, statement)) { this.enterPattern(declarator.id, (name, decl) => { let hook = hookMap.get(name); @@ -2028,6 +2618,75 @@ class JavascriptParser extends Parser { } } + /** + * @param {ObjectPattern} objectPattern object pattern + * @returns {Set | undefined} set of names or undefined if not all keys are identifiers + */ + _preWalkObjectPattern(objectPattern) { + /** @type {Set} */ + const props = new Set(); + const properties = objectPattern.properties; + for (let i = 0; i < properties.length; i++) { + const property = properties[i]; + if (property.type !== "Property") return; + if (property.shorthand && property.value.type === "Identifier") { + this.scope.inShorthand = property.value.name; + } + const key = property.key; + if (key.type === "Identifier") { + props.add({ + id: key.name, + range: key.range, + shorthand: this.scope.inShorthand + }); + } else { + const id = this.evaluateExpression(/** @type {TODO} */ (key)); + const str = id.asString(); + if (str) { + props.add({ + id: str, + range: key.range, + shorthand: this.scope.inShorthand + }); + } else { + // could not evaluate key + return; + } + } + this.scope.inShorthand = false; + } + + return props; + } + + /** + * @param {VariableDeclarator} declarator variable declarator + */ + preWalkVariableDeclarator(declarator) { + if ( + !declarator.init || + declarator.id.type !== "ObjectPattern" || + !this.destructuringAssignmentProperties + ) + return; + const keys = this._preWalkObjectPattern(declarator.id); + + if (!keys) return; + this.destructuringAssignmentProperties.set( + declarator.init.type === "AwaitExpression" + ? declarator.init.argument + : declarator.init, + keys + ); + + if (declarator.init.type === "AssignmentExpression") { + this.preWalkAssignmentExpression(declarator.init); + } + } + + /** + * @param {VariableDeclaration} statement variable declaration + */ walkVariableDeclaration(statement) { for (const declarator of statement.declarations) { switch (declarator.type) { @@ -2036,10 +2695,16 @@ class JavascriptParser extends Parser { declarator.init && this.getRenameIdentifier(declarator.init); if (renameIdentifier && declarator.id.type === "Identifier") { const hook = this.hooks.canRename.get(renameIdentifier); - if (hook !== undefined && hook.call(declarator.init)) { + if ( + hook !== undefined && + hook.call(/** @type {Expression} */ (declarator.init)) + ) { // renaming with "var a = b;" const hook = this.hooks.rename.get(renameIdentifier); - if (hook === undefined || !hook.call(declarator.init)) { + if ( + hook === undefined || + !hook.call(/** @type {Expression} */ (declarator.init)) + ) { this.setVariable(declarator.id.name, renameIdentifier); } break; @@ -2055,16 +2720,25 @@ class JavascriptParser extends Parser { } } + /** + * @param {ClassDeclaration} statement class declaration + */ blockPreWalkClassDeclaration(statement) { if (statement.id) { this.defineVariable(statement.id.name); } } + /** + * @param {ClassDeclaration} statement class declaration + */ walkClassDeclaration(statement) { this.walkClass(statement); } + /** + * @param {SwitchCase[]} switchCases switch statement + */ preWalkSwitchCases(switchCases) { for (let index = 0, len = switchCases.length; index < len; index++) { const switchCase = switchCases[index]; @@ -2072,6 +2746,9 @@ class JavascriptParser extends Parser { } } + /** + * @param {SwitchCase[]} switchCases switch statement + */ walkSwitchCases(switchCases) { this.inBlockScope(() => { const len = switchCases.length; @@ -2107,10 +2784,16 @@ class JavascriptParser extends Parser { }); } + /** + * @param {CatchClause} catchClause catch clause + */ preWalkCatchClause(catchClause) { this.preWalkStatement(catchClause.body); } + /** + * @param {CatchClause} catchClause catch clause + */ walkCatchClause(catchClause) { this.inBlockScope(() => { // Error binding is optional in catch clause since ECMAScript 2019 @@ -2127,6 +2810,9 @@ class JavascriptParser extends Parser { }); } + /** + * @param {Pattern} pattern pattern + */ walkPattern(pattern) { switch (pattern.type) { case "ArrayPattern": @@ -2147,21 +2833,33 @@ class JavascriptParser extends Parser { } } + /** + * @param {AssignmentPattern} pattern assignment pattern + */ walkAssignmentPattern(pattern) { this.walkExpression(pattern.right); this.walkPattern(pattern.left); } + /** + * @param {ObjectPattern} pattern pattern + */ walkObjectPattern(pattern) { for (let i = 0, len = pattern.properties.length; i < len; i++) { const prop = pattern.properties[i]; if (prop) { + if (prop.type === "RestElement") { + continue; + } if (prop.computed) this.walkExpression(prop.key); if (prop.value) this.walkPattern(prop.value); } } } + /** + * @param {ArrayPattern} pattern array pattern + */ walkArrayPattern(pattern) { for (let i = 0, len = pattern.elements.length; i < len; i++) { const element = pattern.elements[i]; @@ -2169,10 +2867,16 @@ class JavascriptParser extends Parser { } } + /** + * @param {RestElement} pattern rest element + */ walkRestElement(pattern) { this.walkPattern(pattern.argument); } + /** + * @param {(Expression | SpreadElement | null)[]} expressions expressions + */ walkExpressions(expressions) { for (const expression of expressions) { if (expression) { @@ -2181,6 +2885,9 @@ class JavascriptParser extends Parser { } } + /** + * @param {TODO} expression expression + */ walkExpression(expression) { switch (expression.type) { case "ArrayExpression": @@ -2261,24 +2968,36 @@ class JavascriptParser extends Parser { } } + /** + * @param {AwaitExpression} expression await expression + */ walkAwaitExpression(expression) { if (this.scope.topLevelScope === true) this.hooks.topLevelAwait.call(expression); this.walkExpression(expression.argument); } + /** + * @param {ArrayExpression} expression array expression + */ walkArrayExpression(expression) { if (expression.elements) { this.walkExpressions(expression.elements); } } + /** + * @param {SpreadElement} expression spread element + */ walkSpreadElement(expression) { if (expression.argument) { this.walkExpression(expression.argument); } } + /** + * @param {ObjectExpression} expression object expression + */ walkObjectExpression(expression) { for ( let propIndex = 0, len = expression.properties.length; @@ -2290,6 +3009,9 @@ class JavascriptParser extends Parser { } } + /** + * @param {Property | SpreadElement} prop property or spread element + */ walkProperty(prop) { if (prop.type === "SpreadElement") { this.walkExpression(prop.argument); @@ -2307,14 +3029,17 @@ class JavascriptParser extends Parser { } } + /** + * @param {FunctionExpression} expression arrow function expression + */ walkFunctionExpression(expression) { const wasTopLevel = this.scope.topLevelScope; this.scope.topLevelScope = false; - const scopeParams = expression.params; + const scopeParams = [...expression.params]; // Add function name in scope for recursive calls if (expression.id) { - scopeParams.push(expression.id.name); + scopeParams.push(expression.id); } this.inFunctionScope(true, scopeParams, () => { @@ -2334,6 +3059,9 @@ class JavascriptParser extends Parser { this.scope.topLevelScope = wasTopLevel; } + /** + * @param {ArrowFunctionExpression} expression arrow function expression + */ walkArrowFunctionExpression(expression) { const wasTopLevel = this.scope.topLevelScope; this.scope.topLevelScope = wasTopLevel ? "arrow" : false; @@ -2355,7 +3083,7 @@ class JavascriptParser extends Parser { } /** - * @param {SequenceExpressionNode} expression the sequence + * @param {SequenceExpression} expression the sequence */ walkSequenceExpression(expression) { if (!expression.expressions) return; @@ -2367,22 +3095,30 @@ class JavascriptParser extends Parser { (currentStatement.type === "ExpressionStatement" && currentStatement.expression === expression) ) { - const old = this.statementPath.pop(); + const old = /** @type {StatementPathItem} */ (this.statementPath.pop()); + const prev = this.prevStatement; for (const expr of expression.expressions) { this.statementPath.push(expr); this.walkExpression(expr); - this.statementPath.pop(); + this.prevStatement = this.statementPath.pop(); } + this.prevStatement = prev; this.statementPath.push(old); } else { this.walkExpressions(expression.expressions); } } + /** + * @param {UpdateExpression} expression the update expression + */ walkUpdateExpression(expression) { this.walkExpression(expression.argument); } + /** + * @param {UnaryExpression} expression the unary expression + */ walkUnaryExpression(expression) { if (expression.operator === "typeof") { const result = this.callHooksForExpression( @@ -2403,52 +3139,65 @@ class JavascriptParser extends Parser { this.walkExpression(expression.argument); } + /** + * @param {LogicalExpression | BinaryExpression} expression the expression + */ walkLeftRightExpression(expression) { this.walkExpression(expression.left); this.walkExpression(expression.right); } + /** + * @param {BinaryExpression} expression the binary expression + */ walkBinaryExpression(expression) { - this.walkLeftRightExpression(expression); + if (this.hooks.binaryExpression.call(expression) === undefined) { + this.walkLeftRightExpression(expression); + } } + /** + * @param {LogicalExpression} expression the logical expression + */ walkLogicalExpression(expression) { const result = this.hooks.expressionLogicalOperator.call(expression); if (result === undefined) { this.walkLeftRightExpression(expression); - } else { - if (result) { - this.walkExpression(expression.right); - } + } else if (result) { + this.walkExpression(expression.right); } } + /** + * @param {AssignmentExpression} expression assignment expression + */ walkAssignmentExpression(expression) { if (expression.left.type === "Identifier") { const renameIdentifier = this.getRenameIdentifier(expression.right); - if (renameIdentifier) { + if ( + renameIdentifier && + this.callHooksForInfo( + this.hooks.canRename, + renameIdentifier, + expression.right + ) + ) { + // renaming "a = b;" if ( - this.callHooksForInfo( - this.hooks.canRename, + !this.callHooksForInfo( + this.hooks.rename, renameIdentifier, expression.right ) ) { - // renaming "a = b;" - if ( - !this.callHooksForInfo( - this.hooks.rename, - renameIdentifier, - expression.right - ) - ) { - this.setVariable( - expression.left.name, - this.getVariableInfo(renameIdentifier) - ); - } - return; + this.setVariable( + expression.left.name, + typeof renameIdentifier === "string" + ? this.getVariableInfo(renameIdentifier) + : renameIdentifier + ); } + return; } this.walkExpression(expression.right); this.enterPattern(expression.left, (name, decl) => { @@ -2471,17 +3220,16 @@ class JavascriptParser extends Parser { expression.left, ALLOWED_MEMBER_TYPES_EXPRESSION ); - if (exprName) { - if ( - this.callHooksForInfo( - this.hooks.assignMemberChain, - exprName.rootInfo, - expression, - exprName.getMembers() - ) - ) { - return; - } + if ( + exprName && + this.callHooksForInfo( + this.hooks.assignMemberChain, + exprName.rootInfo, + expression, + exprName.getMembers() + ) + ) { + return; } this.walkExpression(expression.right); this.walkExpression(expression.left); @@ -2491,6 +3239,9 @@ class JavascriptParser extends Parser { } } + /** + * @param {ConditionalExpression} expression conditional expression + */ walkConditionalExpression(expression) { const result = this.hooks.expressionConditionalOperator.call(expression); if (result === undefined) { @@ -2499,15 +3250,16 @@ class JavascriptParser extends Parser { if (expression.alternate) { this.walkExpression(expression.alternate); } - } else { - if (result) { - this.walkExpression(expression.consequent); - } else if (expression.alternate) { - this.walkExpression(expression.alternate); - } + } else if (result) { + this.walkExpression(expression.consequent); + } else if (expression.alternate) { + this.walkExpression(expression.alternate); } } + /** + * @param {NewExpression} expression new expression + */ walkNewExpression(expression) { const result = this.callHooksForExpression( this.hooks.new, @@ -2521,33 +3273,47 @@ class JavascriptParser extends Parser { } } + /** + * @param {YieldExpression} expression yield expression + */ walkYieldExpression(expression) { if (expression.argument) { this.walkExpression(expression.argument); } } + /** + * @param {TemplateLiteral} expression template literal + */ walkTemplateLiteral(expression) { if (expression.expressions) { this.walkExpressions(expression.expressions); } } + /** + * @param {TaggedTemplateExpression} expression tagged template expression + */ walkTaggedTemplateExpression(expression) { if (expression.tag) { + this.scope.inTaggedTemplateTag = true; this.walkExpression(expression.tag); + this.scope.inTaggedTemplateTag = false; } if (expression.quasi && expression.quasi.expressions) { this.walkExpressions(expression.quasi.expressions); } } + /** + * @param {ClassExpression} expression the class expression + */ walkClassExpression(expression) { this.walkClass(expression); } /** - * @param {ChainExpressionNode} expression expression + * @param {ChainExpression} expression expression */ walkChainExpression(expression) { const result = this.hooks.optionalChaining.call(expression); @@ -2561,27 +3327,33 @@ class JavascriptParser extends Parser { } } + /** + * @private + * @param {FunctionExpression | ArrowFunctionExpression} functionExpression function expression + * @param {(Expression | SpreadElement)[]} options options + * @param {Expression | SpreadElement | null} currentThis current this + */ _walkIIFE(functionExpression, options, currentThis) { + /** + * @param {Expression | SpreadElement} argOrThis arg or this + * @returns {string | VariableInfoInterface | undefined} var info + */ const getVarInfo = argOrThis => { - const renameIdentifier = this.getRenameIdentifier(argOrThis); - if (renameIdentifier) { - if ( - this.callHooksForInfo( - this.hooks.canRename, - renameIdentifier, - argOrThis - ) - ) { - if ( - !this.callHooksForInfo( - this.hooks.rename, - renameIdentifier, - argOrThis - ) - ) { - return this.getVariableInfo(renameIdentifier); - } - } + const renameIdentifier = this.getRenameIdentifier( + /** @type {Expression} */ (argOrThis) + ); + if ( + renameIdentifier && + this.callHooksForInfo( + this.hooks.canRename, + renameIdentifier, + argOrThis + ) && + !this.callHooksForInfo(this.hooks.rename, renameIdentifier, argOrThis) + ) { + return typeof renameIdentifier === "string" + ? /** @type {string} */ (this.getVariableInfo(renameIdentifier)) + : renameIdentifier; } this.walkExpression(argOrThis); }; @@ -2591,12 +3363,15 @@ class JavascriptParser extends Parser { const varInfoForArgs = options.map(getVarInfo); const wasTopLevel = this.scope.topLevelScope; this.scope.topLevelScope = wasTopLevel && arrow ? "arrow" : false; - const scopeParams = params.filter( - (identifier, idx) => !varInfoForArgs[idx] - ); + const scopeParams = + /** @type {(Identifier | string)[]} */ + (params.filter((identifier, idx) => !varInfoForArgs[idx])); // Add function name in scope for recursive calls - if (functionExpression.id) { + if ( + functionExpression.type === "FunctionExpression" && + functionExpression.id + ) { scopeParams.push(functionExpression.id.name); } @@ -2608,7 +3383,7 @@ class JavascriptParser extends Parser { const varInfo = varInfoForArgs[i]; if (!varInfo) continue; if (!params[i] || params[i].type !== "Identifier") continue; - this.setVariable(params[i].name, varInfo); + this.setVariable(/** @type {Identifier} */ (params[i]).name, varInfo); } if (functionExpression.body.type === "BlockStatement") { this.detectMode(functionExpression.body.body); @@ -2623,29 +3398,40 @@ class JavascriptParser extends Parser { this.scope.topLevelScope = wasTopLevel; } + /** + * @param {ImportExpression} expression import expression + */ walkImportExpression(expression) { - let result = this.hooks.importCall.call(expression); + const result = this.hooks.importCall.call(expression); if (result === true) return; this.walkExpression(expression.source); } + /** + * @param {CallExpression} expression expression + */ walkCallExpression(expression) { - const isSimpleFunction = fn => { - return fn.params.every(p => p.type === "Identifier"); - }; + const isSimpleFunction = fn => + fn.params.every(p => p.type === "Identifier"); if ( expression.callee.type === "MemberExpression" && expression.callee.object.type.endsWith("FunctionExpression") && !expression.callee.computed && + // eslint-disable-next-line no-warning-comments + // @ts-ignore + // TODO check me and handle more cases (expression.callee.property.name === "call" || + // eslint-disable-next-line no-warning-comments + // @ts-ignore expression.callee.property.name === "bind") && expression.arguments.length > 0 && isSimpleFunction(expression.callee.object) ) { // (function(โ€ฆ) { }.call/bind(?, โ€ฆ)) this._walkIIFE( - expression.callee.object, + /** @type {FunctionExpression | ArrowFunctionExpression} */ + (expression.callee.object), expression.arguments.slice(1), expression.arguments[0] ); @@ -2654,7 +3440,12 @@ class JavascriptParser extends Parser { isSimpleFunction(expression.callee) ) { // (function(โ€ฆ) { }(โ€ฆ)) - this._walkIIFE(expression.callee, expression.arguments, null); + this._walkIIFE( + /** @type {FunctionExpression | ArrowFunctionExpression} */ + (expression.callee), + expression.arguments, + null + ); } else { if (expression.callee.type === "MemberExpression") { const exprInfo = this.getMemberExpressionInfo( @@ -2668,18 +3459,25 @@ class JavascriptParser extends Parser { expression, exprInfo.getCalleeMembers(), exprInfo.call, - exprInfo.getMembers() + exprInfo.getMembers(), + exprInfo.getMemberRanges() ); if (result === true) return; } } - const callee = this.evaluateExpression(expression.callee); + const callee = this.evaluateExpression( + /** @type {TODO} */ (expression.callee) + ); if (callee.isIdentifier()) { const result1 = this.callHooksForInfo( this.hooks.callMemberChain, callee.rootInfo, expression, - callee.getMembers() + callee.getMembers(), + callee.getMembersOptionals + ? callee.getMembersOptionals() + : callee.getMembers().map(() => false), + callee.getMemberRanges ? callee.getMemberRanges() : [] ); if (result1 === true) return; const result2 = this.callHooksForInfo( @@ -2704,6 +3502,9 @@ class JavascriptParser extends Parser { } } + /** + * @param {MemberExpression} expression member expression + */ walkMemberExpression(expression) { const exprInfo = this.getMemberExpressionInfo( expression, @@ -2719,11 +3520,15 @@ class JavascriptParser extends Parser { ); if (result1 === true) return; const members = exprInfo.getMembers(); + const membersOptionals = exprInfo.getMembersOptionals(); + const memberRanges = exprInfo.getMemberRanges(); const result2 = this.callHooksForInfo( this.hooks.expressionMemberChain, exprInfo.rootInfo, expression, - members + members, + membersOptionals, + memberRanges ); if (result2 === true) return; this.walkMemberExpressionWithExpressionName( @@ -2748,7 +3553,8 @@ class JavascriptParser extends Parser { expression, exprInfo.getCalleeMembers(), exprInfo.call, - exprInfo.getMembers() + exprInfo.getMembers(), + exprInfo.getMemberRanges() ); if (result === true) return; // Fast skip over the member chain as we already called memberChainOfCallMemberChain @@ -2762,6 +3568,13 @@ class JavascriptParser extends Parser { if (expression.computed === true) this.walkExpression(expression.property); } + /** + * @param {TODO} expression member expression + * @param {string} name name + * @param {string | VariableInfo} rootInfo root info + * @param {string[]} members members + * @param {TODO} onUnhandled on unhandled callback + */ walkMemberExpressionWithExpressionName( expression, name, @@ -2795,21 +3608,35 @@ class JavascriptParser extends Parser { if (expression.computed === true) this.walkExpression(expression.property); } + /** + * @param {ThisExpression} expression this expression + */ walkThisExpression(expression) { this.callHooksForName(this.hooks.expression, "this", expression); } + /** + * @param {Identifier} expression identifier + */ walkIdentifier(expression) { this.callHooksForName(this.hooks.expression, expression.name, expression); } /** - * @param {MetaPropertyNode} metaProperty meta property + * @param {MetaProperty} metaProperty meta property */ walkMetaProperty(metaProperty) { this.hooks.expression.for(getRootName(metaProperty)).call(metaProperty); } + /** + * @template T + * @template R + * @param {HookMap>} hookMap hooks the should be called + * @param {TODO} expr expression + * @param {AsArray} args args for the hook + * @returns {R | undefined} result of hook + */ callHooksForExpression(hookMap, expr, ...args) { return this.callHooksForExpressionWithFallback( hookMap, @@ -2824,11 +3651,11 @@ class JavascriptParser extends Parser { * @template T * @template R * @param {HookMap>} hookMap hooks the should be called - * @param {MemberExpressionNode} expr expression info - * @param {function(string, string | ScopeInfo | VariableInfo, function(): string[]): any} fallback callback when variable in not handled by hooks - * @param {function(string): any} defined callback when variable is defined + * @param {MemberExpression} expr expression info + * @param {(function(string, string | ScopeInfo | VariableInfo, function(): string[]): any) | undefined} fallback callback when variable in not handled by hooks + * @param {(function(string): any) | undefined} defined callback when variable is defined * @param {AsArray} args args for the hook - * @returns {R} result of hook + * @returns {R | undefined} result of hook */ callHooksForExpressionWithFallback( hookMap, @@ -2860,7 +3687,7 @@ class JavascriptParser extends Parser { * @param {HookMap>} hookMap hooks the should be called * @param {string} name key in map * @param {AsArray} args args for the hook - * @returns {R} result of hook + * @returns {R | undefined} result of hook */ callHooksForName(hookMap, name, ...args) { return this.callHooksForNameWithFallback( @@ -2878,7 +3705,7 @@ class JavascriptParser extends Parser { * @param {HookMap>} hookMap hooks that should be called * @param {ExportedVariableInfo} info variable info * @param {AsArray} args args for the hook - * @returns {R} result of hook + * @returns {R | undefined} result of hook */ callHooksForInfo(hookMap, info, ...args) { return this.callHooksForInfoWithFallback( @@ -2895,10 +3722,10 @@ class JavascriptParser extends Parser { * @template R * @param {HookMap>} hookMap hooks the should be called * @param {ExportedVariableInfo} info variable info - * @param {function(string): any} fallback callback when variable in not handled by hooks - * @param {function(): any} defined callback when variable is defined + * @param {(function(string): any) | undefined} fallback callback when variable in not handled by hooks + * @param {(function(): any) | undefined} defined callback when variable is defined * @param {AsArray} args args for the hook - * @returns {R} result of hook + * @returns {R | undefined} result of hook */ callHooksForInfoWithFallback(hookMap, info, fallback, defined, ...args) { let name; @@ -2945,10 +3772,10 @@ class JavascriptParser extends Parser { * @template R * @param {HookMap>} hookMap hooks the should be called * @param {string} name key in map - * @param {function(string): any} fallback callback when variable in not handled by hooks - * @param {function(): any} defined callback when variable is defined + * @param {(function(string): any) | undefined} fallback callback when variable in not handled by hooks + * @param {(function(): any) | undefined} defined callback when variable is defined * @param {AsArray} args args for the hook - * @returns {R} result of hook + * @returns {R | undefined} result of hook */ callHooksForNameWithFallback(hookMap, name, fallback, defined, ...args) { return this.callHooksForInfoWithFallback( @@ -2972,6 +3799,7 @@ class JavascriptParser extends Parser { topLevelScope: oldScope.topLevelScope, inTry: false, inShorthand: false, + inTaggedTemplateTag: false, isStrict: oldScope.isStrict, isAsmJs: oldScope.isAsmJs, definitions: oldScope.definitions.createChild() @@ -2988,12 +3816,50 @@ class JavascriptParser extends Parser { this.scope = oldScope; } + /** + * @param {boolean} hasThis true, when this is defined + * @param {any} params scope params + * @param {function(): void} fn inner function + * @returns {void} + */ + inClassScope(hasThis, params, fn) { + const oldScope = this.scope; + this.scope = { + topLevelScope: oldScope.topLevelScope, + inTry: false, + inShorthand: false, + inTaggedTemplateTag: false, + isStrict: oldScope.isStrict, + isAsmJs: oldScope.isAsmJs, + definitions: oldScope.definitions.createChild() + }; + + if (hasThis) { + this.undefineVariable("this"); + } + + this.enterPatterns(params, (ident, pattern) => { + this.defineVariable(ident); + }); + + fn(); + + this.scope = oldScope; + } + + /** + * @param {boolean} hasThis true, when this is defined + * @param {any} params scope params + * @param {function(): void} fn inner function + * @returns {void} + */ inFunctionScope(hasThis, params, fn) { const oldScope = this.scope; this.scope = { topLevelScope: oldScope.topLevelScope, inTry: false, inShorthand: false, + inTaggedTemplateTag: false, isStrict: oldScope.isStrict, isAsmJs: oldScope.isAsmJs, definitions: oldScope.definitions.createChild() @@ -3012,12 +3878,17 @@ class JavascriptParser extends Parser { this.scope = oldScope; } + /** + * @param {function(): void} fn inner function + * @returns {void} + */ inBlockScope(fn) { const oldScope = this.scope; this.scope = { topLevelScope: oldScope.topLevelScope, inTry: oldScope.inTry, inShorthand: false, + inTaggedTemplateTag: false, isStrict: oldScope.isStrict, isAsmJs: oldScope.isAsmJs, definitions: oldScope.definitions.createChild() @@ -3028,19 +3899,36 @@ class JavascriptParser extends Parser { this.scope = oldScope; } + /** + * @param {Array} statements statements + */ detectMode(statements) { const isLiteral = statements.length >= 1 && statements[0].type === "ExpressionStatement" && statements[0].expression.type === "Literal"; - if (isLiteral && statements[0].expression.value === "use strict") { + if ( + isLiteral && + /** @type {Literal} */ + (/** @type {ExpressionStatement} */ (statements[0]).expression).value === + "use strict" + ) { this.scope.isStrict = true; } - if (isLiteral && statements[0].expression.value === "use asm") { + if ( + isLiteral && + /** @type {Literal} */ + (/** @type {ExpressionStatement} */ (statements[0]).expression).value === + "use asm" + ) { this.scope.isAsmJs = true; } } + /** + * @param {(string | Pattern | Property)[]} patterns patterns + * @param {OnIdent} onIdent on ident callback + */ enterPatterns(patterns, onIdent) { for (const pattern of patterns) { if (typeof pattern !== "string") { @@ -3051,6 +3939,10 @@ class JavascriptParser extends Parser { } } + /** + * @param {Pattern | Property} pattern pattern + * @param {OnIdent} onIdent on ident callback + */ enterPattern(pattern, onIdent) { if (!pattern) return; switch (pattern.type) { @@ -3075,18 +3967,26 @@ class JavascriptParser extends Parser { this.enterIdentifier(pattern.value, onIdent); this.scope.inShorthand = false; } else { - this.enterPattern(pattern.value, onIdent); + this.enterPattern(/** @type {Identifier} */ (pattern.value), onIdent); } break; } } + /** + * @param {Identifier} pattern identifier pattern + * @param {OnIdent} onIdent callback + */ enterIdentifier(pattern, onIdent) { if (!this.callHooksForName(this.hooks.pattern, pattern.name, pattern)) { onIdent(pattern.name, pattern); } } + /** + * @param {ObjectPattern} pattern object pattern + * @param {OnIdent} onIdent callback + */ enterObjectPattern(pattern, onIdent) { for ( let propIndex = 0, len = pattern.properties.length; @@ -3098,6 +3998,10 @@ class JavascriptParser extends Parser { } } + /** + * @param {ArrayPattern} pattern object pattern + * @param {OnIdent} onIdent callback + */ enterArrayPattern(pattern, onIdent) { for ( let elementIndex = 0, len = pattern.elements.length; @@ -3105,43 +4009,56 @@ class JavascriptParser extends Parser { elementIndex++ ) { const element = pattern.elements[elementIndex]; - this.enterPattern(element, onIdent); + + if (element) { + this.enterPattern(element, onIdent); + } } } + /** + * @param {RestElement} pattern object pattern + * @param {OnIdent} onIdent callback + */ enterRestElement(pattern, onIdent) { this.enterPattern(pattern.argument, onIdent); } + /** + * @param {AssignmentPattern} pattern object pattern + * @param {OnIdent} onIdent callback + */ enterAssignmentPattern(pattern, onIdent) { this.enterPattern(pattern.left, onIdent); } /** - * @param {ExpressionNode} expression expression node - * @returns {BasicEvaluatedExpression | undefined} evaluation result + * @param {Expression | SpreadElement} expression expression node + * @returns {BasicEvaluatedExpression} evaluation result */ evaluateExpression(expression) { try { const hook = this.hooks.evaluate.get(expression.type); if (hook !== undefined) { const result = hook.call(expression); - if (result !== undefined) { - if (result) { - result.setExpression(expression); - } + if (result !== undefined && result !== null) { + result.setExpression(expression); return result; } } - } catch (e) { - console.warn(e); + } catch (err) { + console.warn(err); // ignore error } return new BasicEvaluatedExpression() - .setRange(expression.range) + .setRange(/** @type {Range} */ (expression.range)) .setExpression(expression); } + /** + * @param {Expression} expression expression + * @returns {string} parsed string + */ parseString(expression) { switch (expression.type) { case "BinaryExpression": @@ -3153,13 +4070,17 @@ class JavascriptParser extends Parser { } break; case "Literal": - return expression.value + ""; + return String(expression.value); } throw new Error( - expression.type + " is not supported as parameter for require" + `${expression.type} is not supported as parameter for require` ); } + /** + * @param {Expression} expression expression + * @returns {TODO} result + */ parseCalculatedString(expression) { switch (expression.type) { case "BinaryExpression": @@ -3183,14 +4104,13 @@ class JavascriptParser extends Parser { code: true, conditional: false }; - } else { - return { - range: [left.range[0], right.range[1]], - value: left.value + right.value, - code: false, - conditional: false - }; } + return { + range: [left.range[0], right.range[1]], + value: left.value + right.value, + code: false, + conditional: false + }; } break; case "ConditionalExpression": { @@ -3221,7 +4141,7 @@ class JavascriptParser extends Parser { case "Literal": return { range: expression.range, - value: expression.value + "", + value: String(expression.value), code: false, conditional: false }; @@ -3250,7 +4170,7 @@ class JavascriptParser extends Parser { source = source.toString("utf-8"); } if (typeof source === "object") { - ast = /** @type {ProgramNode} */ (source); + ast = /** @type {Program} */ (source); comments = source.comments; } else { comments = []; @@ -3271,6 +4191,7 @@ class JavascriptParser extends Parser { topLevelScope: true, inTry: false, inShorthand: false, + inTaggedTemplateTag: false, isStrict: false, isAsmJs: false, definitions: new StackedMap() @@ -3282,12 +4203,14 @@ class JavascriptParser extends Parser { this.statementPath = []; this.prevStatement = undefined; if (this.hooks.program.call(ast, comments) === undefined) { + this.destructuringAssignmentProperties = new WeakMap(); this.detectMode(ast.body); this.preWalkStatements(ast.body); this.prevStatement = undefined; this.blockPreWalkStatements(ast.body); this.prevStatement = undefined; this.walkStatements(ast.body); + this.destructuringAssignmentProperties = undefined; } this.hooks.finish.call(ast, comments); this.scope = oldScope; @@ -3300,8 +4223,12 @@ class JavascriptParser extends Parser { return state; } + /** + * @param {string} source source code + * @returns {BasicEvaluatedExpression} evaluation result + */ evaluate(source) { - const ast = JavascriptParser._parse("(" + source + ")", { + const ast = JavascriptParser._parse(`(${source})`, { sourceType: this.sourceType, locations: false }); @@ -3312,7 +4239,7 @@ class JavascriptParser extends Parser { } /** - * @param {ExpressionNode | DeclarationNode | null | undefined} expr an expression + * @param {Expression | Declaration | PrivateIdentifier | null | undefined} expr an expression * @param {number} commentsStartPos source position from which annotation comments are checked * @returns {boolean} true, when the expression is pure */ @@ -3323,63 +4250,113 @@ class JavascriptParser extends Parser { .call(expr, commentsStartPos); if (typeof result === "boolean") return result; switch (expr.type) { + // TODO handle more cases case "ClassDeclaration": - case "ClassExpression": + case "ClassExpression": { if (expr.body.type !== "ClassBody") return false; - if (expr.superClass && !this.isPure(expr.superClass, expr.range[0])) { + if ( + expr.superClass && + !this.isPure(expr.superClass, /** @type {Range} */ (expr.range)[0]) + ) { return false; } - return expr.body.body.every(item => { - switch (item.type) { - // @ts-expect-error not yet supported by acorn - case "ClassProperty": - // TODO add test case once acorn supports it - // Currently this is not parsable - if (item.static) return this.isPure(item.value, item.range[0]); - break; + const items = + /** @type {TODO[]} */ + (expr.body.body); + return items.every(item => { + if ( + item.computed && + item.key && + !this.isPure(item.key, item.range[0]) + ) { + return false; + } + + if ( + item.static && + item.value && + !this.isPure( + item.value, + item.key ? item.key.range[1] : item.range[0] + ) + ) { + return false; + } + + if (item.type === "StaticBlock") { + return false; + } + + if ( + expr.superClass && + item.type === "MethodDefinition" && + item.kind === "constructor" + ) { + return false; } + return true; }); + } case "FunctionDeclaration": case "FunctionExpression": case "ArrowFunctionExpression": + case "ThisExpression": case "Literal": + case "TemplateLiteral": + case "Identifier": + case "PrivateIdentifier": return true; case "VariableDeclaration": return expr.declarations.every(decl => - this.isPure(decl.init, decl.range[0]) + this.isPure(decl.init, /** @type {Range} */ (decl.range)[0]) ); case "ConditionalExpression": return ( this.isPure(expr.test, commentsStartPos) && - this.isPure(expr.consequent, expr.test.range[1]) && - this.isPure(expr.alternate, expr.consequent.range[1]) + this.isPure( + expr.consequent, + /** @type {Range} */ (expr.test.range)[1] + ) && + this.isPure( + expr.alternate, + /** @type {Range} */ (expr.consequent.range)[1] + ) + ); + + case "LogicalExpression": + return ( + this.isPure(expr.left, commentsStartPos) && + this.isPure(expr.right, /** @type {Range} */ (expr.left.range)[1]) ); case "SequenceExpression": return expr.expressions.every(expr => { const pureFlag = this.isPure(expr, commentsStartPos); - commentsStartPos = expr.range[1]; + commentsStartPos = /** @type {Range} */ (expr.range)[1]; return pureFlag; }); case "CallExpression": { const pureFlag = - expr.range[0] - commentsStartPos > 12 && - this.getComments([commentsStartPos, expr.range[0]]).some( + /** @type {Range} */ (expr.range)[0] - commentsStartPos > 12 && + this.getComments([ + commentsStartPos, + /** @type {Range} */ (expr.range)[0] + ]).some( comment => comment.type === "Block" && /^\s*(#|@)__PURE__\s*$/.test(comment.value) ); if (!pureFlag) return false; - commentsStartPos = expr.callee.range[1]; + commentsStartPos = /** @type {Range} */ (expr.callee.range)[1]; return expr.arguments.every(arg => { if (arg.type === "SpreadElement") return false; const pureFlag = this.isPure(arg, commentsStartPos); - commentsStartPos = arg.range[1]; + commentsStartPos = /** @type {Range} */ (arg.range)[1]; return pureFlag; }); } @@ -3388,13 +4365,28 @@ class JavascriptParser extends Parser { return !evaluated.couldHaveSideEffects(); } + /** + * @param {Range} range range + * @returns {Comment[]} comments in the range + */ getComments(range) { const [rangeStart, rangeEnd] = range; - const compare = (comment, needle) => comment.range[0] - needle; - let idx = binarySearchBounds.ge(this.comments, rangeStart, compare); - let commentsInRange = []; - while (this.comments[idx] && this.comments[idx].range[1] <= rangeEnd) { - commentsInRange.push(this.comments[idx]); + /** + * @param {Comment} comment comment + * @param {number} needle needle + * @returns {number} compared + */ + const compare = (comment, needle) => + /** @type {Range} */ (comment.range)[0] - needle; + const comments = /** @type {Comment[]} */ (this.comments); + let idx = binarySearchBounds.ge(comments, rangeStart, compare); + /** @type {Comment[]} */ + const commentsInRange = []; + while ( + comments[idx] && + /** @type {Range} */ (comments[idx].range)[1] <= rangeEnd + ) { + commentsInRange.push(comments[idx]); idx++; } @@ -3410,25 +4402,40 @@ class JavascriptParser extends Parser { if (currentStatement === undefined) throw new Error("Not in statement"); return ( // Either asking directly for the end position of the current statement - (currentStatement.range[1] === pos && this.semicolons.has(pos)) || + (currentStatement.range[1] === pos && + /** @type {Set} */ (this.semicolons).has(pos)) || // Or asking for the start position of the current statement, // here we have to check multiple things (currentStatement.range[0] === pos && // is there a previous statement which might be relevant? this.prevStatement !== undefined && // is the end position of the previous statement an ASI position? - this.semicolons.has(this.prevStatement.range[1])) + /** @type {Set} */ (this.semicolons).has( + this.prevStatement.range[1] + )) ); } + /** + * @param {number} pos source code position + * @returns {void} + */ + setAsiPosition(pos) { + /** @type {Set} */ (this.semicolons).add(pos); + } + /** * @param {number} pos source code position * @returns {void} */ unsetAsiPosition(pos) { - this.semicolons.delete(pos); + /** @type {Set} */ (this.semicolons).delete(pos); } + /** + * @param {Expression} expr expression + * @returns {boolean} true, when the expression is a statement level expression + */ isStatementLevelExpression(expr) { const currentStatement = this.statementPath[this.statementPath.length - 1]; return ( @@ -3438,6 +4445,11 @@ class JavascriptParser extends Parser { ); } + /** + * @param {string} name name + * @param {TODO} tag tag info + * @returns {TODO} tag data + */ getTagData(name, tag) { const info = this.scope.definitions.get(name); if (info instanceof VariableInfo) { @@ -3449,6 +4461,11 @@ class JavascriptParser extends Parser { } } + /** + * @param {string} name name + * @param {TODO} tag tag info + * @param {TODO=} data data + */ tagVariable(name, tag, data) { const oldInfo = this.scope.definitions.get(name); /** @type {VariableInfo} */ @@ -3475,6 +4492,9 @@ class JavascriptParser extends Parser { this.scope.definitions.set(name, newInfo); } + /** + * @param {string} name variable name + */ defineVariable(name) { const oldInfo = this.scope.definitions.get(name); // Don't redefine variable in same scope to keep existing tags @@ -3483,10 +4503,17 @@ class JavascriptParser extends Parser { this.scope.definitions.set(name, this.scope); } + /** + * @param {string} name variable name + */ undefineVariable(name) { this.scope.definitions.delete(name); } + /** + * @param {string} name variable name + * @returns {boolean} true, when variable is defined + */ isVariableDefined(name) { const info = this.scope.definitions.get(name); if (info === undefined) return false; @@ -3498,20 +4525,19 @@ class JavascriptParser extends Parser { /** * @param {string} name variable name - * @returns {ExportedVariableInfo} info for this variable + * @returns {string | ExportedVariableInfo} info for this variable */ getVariableInfo(name) { const value = this.scope.definitions.get(name); if (value === undefined) { return name; - } else { - return value; } + return value; } /** * @param {string} name variable name - * @param {ExportedVariableInfo} variableInfo new info for this variable + * @param {string | ExportedVariableInfo} variableInfo new info for this variable * @returns {void} */ setVariable(name, variableInfo) { @@ -3529,23 +4555,50 @@ class JavascriptParser extends Parser { } } + /** + * @param {TagInfo} tagInfo tag info + * @returns {VariableInfo} variable info + */ + evaluatedVariable(tagInfo) { + return new VariableInfo(this.scope, undefined, tagInfo); + } + + /** + * @param {Range} range range of the comment + * @returns {TODO} TODO + */ parseCommentOptions(range) { const comments = this.getComments(range); if (comments.length === 0) { return EMPTY_COMMENT_OPTIONS; } - let options = {}; - let errors = []; + const options = {}; + /** @type {unknown[]} */ + const errors = []; for (const comment of comments) { const { value } = comment; if (value && webpackCommentRegExp.test(value)) { // try compile only if webpack options comment is present try { - const val = vm.runInNewContext(`(function(){return {${value}};})()`); - Object.assign(options, val); - } catch (e) { - e.comment = comment; - errors.push(e); + for (let [key, val] of Object.entries( + vm.runInContext( + `(function(){return {${value}};})()`, + this.magicCommentContext + ) + )) { + if (typeof val === "object" && val !== null) { + val = + val.constructor.name === "RegExp" + ? new RegExp(val) + : JSON.parse(JSON.stringify(val)); + } + options[key] = val; + } + } catch (err) { + const newErr = new Error(String(err.message)); + newErr.stack = String(err.stack); + Object.assign(newErr, { comment }); + errors.push(newErr); } } } @@ -3553,73 +4606,79 @@ class JavascriptParser extends Parser { } /** - * @param {MemberExpressionNode} expression a member expression - * @returns {{ members: string[], object: ExpressionNode | SuperNode }} member names (reverse order) and remaining object + * @param {MemberExpression} expression a member expression + * @returns {{ members: string[], object: Expression | Super, membersOptionals: boolean[], memberRanges: Range[] }} member names (reverse order) and remaining object */ extractMemberExpressionChain(expression) { /** @type {AnyNode} */ let expr = expression; const members = []; + const membersOptionals = []; + const memberRanges = []; while (expr.type === "MemberExpression") { if (expr.computed) { if (expr.property.type !== "Literal") break; - members.push(`${expr.property.value}`); + members.push(`${expr.property.value}`); // the literal + memberRanges.push(/** @type {Range} */ (expr.object.range)); // the range of the expression fragment before the literal } else { if (expr.property.type !== "Identifier") break; - members.push(expr.property.name); + members.push(expr.property.name); // the identifier + memberRanges.push(/** @type {Range} */ (expr.object.range)); // the range of the expression fragment before the identifier } + membersOptionals.push(expr.optional); expr = expr.object; } + return { members, + membersOptionals, + memberRanges, object: expr }; } /** * @param {string} varName variable name - * @returns {{name: string, info: VariableInfo | string}} name of the free variable and variable info for that + * @returns {{name: string, info: VariableInfo | string} | undefined} name of the free variable and variable info for that */ getFreeInfoFromVariable(varName) { const info = this.getVariableInfo(varName); let name; if (info instanceof VariableInfo) { name = info.freeName; - if (typeof name !== "string") return undefined; + if (typeof name !== "string") return; } else if (typeof info !== "string") { - return undefined; + return; } else { name = info; } return { info, name }; } - /** @typedef {{ type: "call", call: CallExpressionNode, calleeName: string, rootInfo: string | VariableInfo, getCalleeMembers: () => string[], name: string, getMembers: () => string[]}} CallExpressionInfo */ - /** @typedef {{ type: "expression", rootInfo: string | VariableInfo, name: string, getMembers: () => string[]}} ExpressionExpressionInfo */ + /** @typedef {{ type: "call", call: CallExpression, calleeName: string, rootInfo: string | VariableInfo, getCalleeMembers: () => string[], name: string, getMembers: () => string[], getMembersOptionals: () => boolean[], getMemberRanges: () => Range[]}} CallExpressionInfo */ + /** @typedef {{ type: "expression", rootInfo: string | VariableInfo, name: string, getMembers: () => string[], getMembersOptionals: () => boolean[], getMemberRanges: () => Range[]}} ExpressionExpressionInfo */ /** - * @param {MemberExpressionNode} expression a member expression + * @param {MemberExpression} expression a member expression * @param {number} allowedTypes which types should be returned, presented in bit mask * @returns {CallExpressionInfo | ExpressionExpressionInfo | undefined} expression info */ getMemberExpressionInfo(expression, allowedTypes) { - const { object, members } = this.extractMemberExpressionChain(expression); + const { object, members, membersOptionals, memberRanges } = + this.extractMemberExpressionChain(expression); switch (object.type) { case "CallExpression": { - if ((allowedTypes & ALLOWED_MEMBER_TYPES_CALL_EXPRESSION) === 0) - return undefined; + if ((allowedTypes & ALLOWED_MEMBER_TYPES_CALL_EXPRESSION) === 0) return; let callee = object.callee; let rootMembers = EMPTY_ARRAY; if (callee.type === "MemberExpression") { - ({ - object: callee, - members: rootMembers - } = this.extractMemberExpressionChain(callee)); + ({ object: callee, members: rootMembers } = + this.extractMemberExpressionChain(callee)); } const rootName = getRootName(callee); - if (!rootName) return undefined; + if (!rootName) return; const result = this.getFreeInfoFromVariable(rootName); - if (!result) return undefined; + if (!result) return; const { info: rootInfo, name: resolvedRoot } = result; const calleeName = objectAndMembersToName(resolvedRoot, rootMembers); return { @@ -3629,33 +4688,36 @@ class JavascriptParser extends Parser { rootInfo, getCalleeMembers: memoize(() => rootMembers.reverse()), name: objectAndMembersToName(`${calleeName}()`, members), - getMembers: memoize(() => members.reverse()) + getMembers: memoize(() => members.reverse()), + getMembersOptionals: memoize(() => membersOptionals.reverse()), + getMemberRanges: memoize(() => memberRanges.reverse()) }; } case "Identifier": case "MetaProperty": case "ThisExpression": { - if ((allowedTypes & ALLOWED_MEMBER_TYPES_EXPRESSION) === 0) - return undefined; + if ((allowedTypes & ALLOWED_MEMBER_TYPES_EXPRESSION) === 0) return; const rootName = getRootName(object); - if (!rootName) return undefined; + if (!rootName) return; const result = this.getFreeInfoFromVariable(rootName); - if (!result) return undefined; + if (!result) return; const { info: rootInfo, name: resolvedRoot } = result; return { type: "expression", name: objectAndMembersToName(resolvedRoot, members), rootInfo, - getMembers: memoize(() => members.reverse()) + getMembers: memoize(() => members.reverse()), + getMembersOptionals: memoize(() => membersOptionals.reverse()), + getMemberRanges: memoize(() => memberRanges.reverse()) }; } } } /** - * @param {MemberExpressionNode} expression an expression - * @returns {{ name: string, rootInfo: ExportedVariableInfo, getMembers: () => string[]}} name info + * @param {MemberExpression} expression an expression + * @returns {{ name: string, rootInfo: ExportedVariableInfo, getMembers: () => string[]} | undefined} name info */ getNameForExpression(expression) { return this.getMemberExpressionInfo( @@ -3667,7 +4729,7 @@ class JavascriptParser extends Parser { /** * @param {string} code source code * @param {ParseOptions} options parsing options - * @returns {ProgramNode} parsed ast + * @returns {Program} parsed ast */ static _parse(code, options) { const type = options ? options.sourceType : "module"; @@ -3679,14 +4741,14 @@ class JavascriptParser extends Parser { sourceType: type === "auto" ? "module" : type }; - /** @type {AnyNode} */ + /** @type {AnyNode | undefined} */ let ast; let error; let threw = false; try { ast = /** @type {AnyNode} */ (parser.parse(code, parserOptions)); - } catch (e) { - error = e; + } catch (err) { + error = err; threw = true; } @@ -3701,7 +4763,7 @@ class JavascriptParser extends Parser { try { ast = /** @type {AnyNode} */ (parser.parse(code, parserOptions)); threw = false; - } catch (e) { + } catch (_err) { // we use the error from first parse try // so nothing to do here } @@ -3711,11 +4773,13 @@ class JavascriptParser extends Parser { throw error; } - return /** @type {ProgramNode} */ (ast); + return /** @type {Program} */ (ast); } } module.exports = JavascriptParser; module.exports.ALLOWED_MEMBER_TYPES_ALL = ALLOWED_MEMBER_TYPES_ALL; -module.exports.ALLOWED_MEMBER_TYPES_EXPRESSION = ALLOWED_MEMBER_TYPES_EXPRESSION; -module.exports.ALLOWED_MEMBER_TYPES_CALL_EXPRESSION = ALLOWED_MEMBER_TYPES_CALL_EXPRESSION; +module.exports.ALLOWED_MEMBER_TYPES_EXPRESSION = + ALLOWED_MEMBER_TYPES_EXPRESSION; +module.exports.ALLOWED_MEMBER_TYPES_CALL_EXPRESSION = + ALLOWED_MEMBER_TYPES_CALL_EXPRESSION; diff --git a/lib/javascript/JavascriptParserHelpers.js b/lib/javascript/JavascriptParserHelpers.js index 3a960d69c10..7028c4dd158 100644 --- a/lib/javascript/JavascriptParserHelpers.js +++ b/lib/javascript/JavascriptParserHelpers.js @@ -9,77 +9,86 @@ const UnsupportedFeatureWarning = require("../UnsupportedFeatureWarning"); const ConstDependency = require("../dependencies/ConstDependency"); const BasicEvaluatedExpression = require("./BasicEvaluatedExpression"); -/** @typedef {import("estree").Expression} ExpressionNode */ +/** @typedef {import("estree").Expression} Expression */ /** @typedef {import("estree").Node} Node */ +/** @typedef {import("estree").SourceLocation} SourceLocation */ /** @typedef {import("./JavascriptParser")} JavascriptParser */ +/** @typedef {import("./JavascriptParser").Range} Range */ /** * @param {JavascriptParser} parser the parser * @param {string} value the const value - * @param {string[]=} runtimeRequirements runtime requirements - * @returns {function(ExpressionNode): true} plugin function + * @param {(string[] | null)=} runtimeRequirements runtime requirements + * @returns {function(Expression): true} plugin function */ -exports.toConstantDependency = (parser, value, runtimeRequirements) => { - return function constDependency(expr) { - const dep = new ConstDependency(value, expr.range, runtimeRequirements); - dep.loc = expr.loc; +module.exports.toConstantDependency = (parser, value, runtimeRequirements) => + function constDependency(expr) { + const dep = new ConstDependency( + value, + /** @type {Range} */ (expr.range), + runtimeRequirements + ); + dep.loc = /** @type {SourceLocation} */ (expr.loc); parser.state.module.addPresentationalDependency(dep); return true; }; -}; /** * @param {string} value the string value - * @returns {function(ExpressionNode): BasicEvaluatedExpression} plugin function + * @returns {function(Expression): BasicEvaluatedExpression} plugin function */ -exports.evaluateToString = value => { - return function stringExpression(expr) { - return new BasicEvaluatedExpression().setString(value).setRange(expr.range); +module.exports.evaluateToString = value => + function stringExpression(expr) { + return new BasicEvaluatedExpression() + .setString(value) + .setRange(/** @type {Range} */ (expr.range)); }; -}; /** * @param {number} value the number value - * @returns {function(ExpressionNode): BasicEvaluatedExpression} plugin function + * @returns {function(Expression): BasicEvaluatedExpression} plugin function */ -exports.evaluateToNumber = value => { - return function stringExpression(expr) { - return new BasicEvaluatedExpression().setNumber(value).setRange(expr.range); +module.exports.evaluateToNumber = value => + function stringExpression(expr) { + return new BasicEvaluatedExpression() + .setNumber(value) + .setRange(/** @type {Range} */ (expr.range)); }; -}; /** * @param {boolean} value the boolean value - * @returns {function(ExpressionNode): BasicEvaluatedExpression} plugin function + * @returns {function(Expression): BasicEvaluatedExpression} plugin function */ -exports.evaluateToBoolean = value => { - return function booleanExpression(expr) { +module.exports.evaluateToBoolean = value => + function booleanExpression(expr) { return new BasicEvaluatedExpression() .setBoolean(value) - .setRange(expr.range); + .setRange(/** @type {Range} */ (expr.range)); }; -}; /** * @param {string} identifier identifier * @param {string} rootInfo rootInfo * @param {function(): string[]} getMembers getMembers * @param {boolean|null=} truthy is truthy, null if nullish - * @returns {function(ExpressionNode): BasicEvaluatedExpression} callback + * @returns {function(Expression): BasicEvaluatedExpression} callback */ -exports.evaluateToIdentifier = (identifier, rootInfo, getMembers, truthy) => { - return function identifierExpression(expr) { - let evaluatedExpression = new BasicEvaluatedExpression() +module.exports.evaluateToIdentifier = ( + identifier, + rootInfo, + getMembers, + truthy +) => + function identifierExpression(expr) { + const evaluatedExpression = new BasicEvaluatedExpression() .setIdentifier(identifier, rootInfo, getMembers) .setSideEffects(false) - .setRange(expr.range); + .setRange(/** @type {Range} */ (expr.range)); switch (truthy) { case true: evaluatedExpression.setTruthy(); - evaluatedExpression.setNullish(false); break; case null: - evaluatedExpression.setFalsy(); evaluatedExpression.setNullish(true); break; case false: @@ -89,21 +98,31 @@ exports.evaluateToIdentifier = (identifier, rootInfo, getMembers, truthy) => { return evaluatedExpression; }; -}; -exports.expressionIsUnsupported = (parser, message) => { - return function unsupportedExpression(expr) { - const dep = new ConstDependency("(void 0)", expr.range, null); - dep.loc = expr.loc; +/** + * @param {JavascriptParser} parser the parser + * @param {string} message the message + * @returns {function(Expression): boolean | undefined} callback to handle unsupported expression + */ +module.exports.expressionIsUnsupported = (parser, message) => + function unsupportedExpression(expr) { + const dep = new ConstDependency( + "(void 0)", + /** @type {Range} */ (expr.range), + null + ); + dep.loc = /** @type {SourceLocation} */ (expr.loc); parser.state.module.addPresentationalDependency(dep); if (!parser.state.module) return; parser.state.module.addWarning( - new UnsupportedFeatureWarning(message, expr.loc) + new UnsupportedFeatureWarning( + message, + /** @type {SourceLocation} */ (expr.loc) + ) ); return true; }; -}; -exports.skipTraversal = () => true; +module.exports.skipTraversal = () => true; -exports.approve = () => true; +module.exports.approve = () => true; diff --git a/lib/javascript/StartupHelpers.js b/lib/javascript/StartupHelpers.js index 3e6bdb5c4f9..f6f759d44bc 100644 --- a/lib/javascript/StartupHelpers.js +++ b/lib/javascript/StartupHelpers.js @@ -5,55 +5,37 @@ "use strict"; -const Entrypoint = require("../Entrypoint"); const RuntimeGlobals = require("../RuntimeGlobals"); const Template = require("../Template"); const { isSubset } = require("../util/SetHelpers"); -const { chunkHasJs } = require("./JavascriptModulesPlugin"); +const { getAllChunks } = require("./ChunkHelpers"); /** @typedef {import("../util/Hash")} Hash */ /** @typedef {import("../Chunk")} Chunk */ +/** @typedef {import("../Chunk").ChunkId} ChunkId */ /** @typedef {import("../Compilation")} Compilation */ /** @typedef {import("../ChunkGraph")} ChunkGraph */ +/** @typedef {import("../ChunkGraph").ModuleId} ModuleId */ +/** @typedef {import("../Entrypoint")} Entrypoint */ +/** @typedef {import("../ChunkGraph").EntryModuleWithChunkGroup} EntryModuleWithChunkGroup */ /** @typedef {import("../ChunkGroup")} ChunkGroup */ /** @typedef {import("../RuntimeTemplate")} RuntimeTemplate */ /** @typedef {(string|number)[]} EntryItem */ -// TODO move to this file to ../javascript/ChunkHelpers.js +const EXPORT_PREFIX = `var ${RuntimeGlobals.exports} = `; -/** - * @param {Entrypoint} entrypoint a chunk group - * @param {Chunk} excludedChunk1 current chunk which is excluded - * @param {Chunk} excludedChunk2 runtime chunk which is excluded - * @returns {Set} chunks - */ -const getAllChunks = (entrypoint, excludedChunk1, excludedChunk2) => { - const queue = new Set([entrypoint]); - const chunks = new Set(); - for (const entrypoint of queue) { - for (const chunk of entrypoint.chunks) { - if (chunk === excludedChunk1) continue; - if (chunk === excludedChunk2) continue; - chunks.add(chunk); - } - for (const parent of entrypoint.parentsIterable) { - if (parent instanceof Entrypoint) queue.add(parent); - } - } - return chunks; -}; - -const EXPORT_PREFIX = "var __webpack_exports__ = "; +/** @typedef {Set} Chunks */ +/** @typedef {ModuleId[]} ModuleIds */ /** * @param {ChunkGraph} chunkGraph chunkGraph * @param {RuntimeTemplate} runtimeTemplate runtimeTemplate - * @param {import("../ChunkGraph").EntryModuleWithChunkGroup[]} entries entries + * @param {EntryModuleWithChunkGroup[]} entries entries * @param {Chunk} chunk chunk * @param {boolean} passive true: passive startup with on chunks loaded * @returns {string} runtime code */ -exports.generateEntryStartup = ( +module.exports.generateEntryStartup = ( chunkGraph, runtimeTemplate, entries, @@ -63,14 +45,21 @@ exports.generateEntryStartup = ( /** @type {string[]} */ const runtime = [ `var __webpack_exec__ = ${runtimeTemplate.returningFunction( - `__webpack_require__(${RuntimeGlobals.entryModuleId} = moduleId)`, + `${RuntimeGlobals.require}(${RuntimeGlobals.entryModuleId} = moduleId)`, "moduleId" )}` ]; - const runModule = id => { - return `__webpack_exec__(${JSON.stringify(id)})`; - }; + /** + * @param {ModuleId} id id + * @returns {string} fn to execute + */ + const runModule = id => `__webpack_exec__(${JSON.stringify(id)})`; + /** + * @param {Chunks} chunks chunks + * @param {ModuleIds} moduleIds module ids + * @param {boolean=} final true when final, otherwise false + */ const outputCombination = (chunks, moduleIds, final) => { if (chunks.size === 0) { runtime.push( @@ -93,22 +82,35 @@ exports.generateEntryStartup = ( } }; - let currentChunks = undefined; - let currentModuleIds = undefined; + /** @type {Chunks | undefined} */ + let currentChunks; + /** @type {ModuleIds | undefined} */ + let currentModuleIds; for (const [module, entrypoint] of entries) { - const runtimeChunk = entrypoint.getRuntimeChunk(); - const moduleId = chunkGraph.getModuleId(module); - const chunks = getAllChunks(entrypoint, chunk, runtimeChunk); + const runtimeChunk = + /** @type {Entrypoint} */ + (entrypoint).getRuntimeChunk(); + const moduleId = /** @type {ModuleId} */ (chunkGraph.getModuleId(module)); + const chunks = getAllChunks( + /** @type {Entrypoint} */ + (entrypoint), + chunk, + runtimeChunk + ); if ( currentChunks && currentChunks.size === chunks.size && isSubset(currentChunks, chunks) ) { - currentModuleIds.push(moduleId); + /** @type {ModuleIds} */ + (currentModuleIds).push(moduleId); } else { if (currentChunks) { - outputCombination(currentChunks, currentModuleIds); + outputCombination( + currentChunks, + /** @type {ModuleIds} */ (currentModuleIds) + ); } currentChunks = chunks; currentModuleIds = [moduleId]; @@ -117,7 +119,12 @@ exports.generateEntryStartup = ( // output current modules with export prefix if (currentChunks) { - outputCombination(currentChunks, currentModuleIds, true); + outputCombination( + currentChunks, + /** @type {ModuleIds} */ + (currentModuleIds), + true + ); } runtime.push(""); return Template.asString(runtime); @@ -126,30 +133,45 @@ exports.generateEntryStartup = ( /** * @param {Hash} hash the hash to update * @param {ChunkGraph} chunkGraph chunkGraph - * @param {import("../ChunkGraph").EntryModuleWithChunkGroup[]} entries entries + * @param {EntryModuleWithChunkGroup[]} entries entries * @param {Chunk} chunk chunk * @returns {void} */ -exports.updateHashForEntryStartup = (hash, chunkGraph, entries, chunk) => { +module.exports.updateHashForEntryStartup = ( + hash, + chunkGraph, + entries, + chunk +) => { for (const [module, entrypoint] of entries) { - const runtimeChunk = entrypoint.getRuntimeChunk(); + const runtimeChunk = + /** @type {Entrypoint} */ + (entrypoint).getRuntimeChunk(); const moduleId = chunkGraph.getModuleId(module); hash.update(`${moduleId}`); - for (const c of getAllChunks(entrypoint, chunk, runtimeChunk)) + for (const c of getAllChunks( + /** @type {Entrypoint} */ (entrypoint), + chunk, + /** @type {Chunk} */ (runtimeChunk) + )) { hash.update(`${c.id}`); + } } }; /** * @param {Chunk} chunk the chunk * @param {ChunkGraph} chunkGraph the chunk graph + * @param {function(Chunk, ChunkGraph): boolean} filterFn filter function * @returns {Set} initially fulfilled chunk ids */ -exports.getInitialChunkIds = (chunk, chunkGraph) => { +module.exports.getInitialChunkIds = (chunk, chunkGraph, filterFn) => { const initialChunkIds = new Set(chunk.ids); for (const c of chunk.getAllInitialChunks()) { - if (c === chunk || chunkHasJs(c, chunkGraph)) continue; - for (const id of c.ids) initialChunkIds.add(id); + if (c === chunk || filterFn(c, chunkGraph)) continue; + for (const id of /** @type {ChunkId[]} */ (c.ids)) { + initialChunkIds.add(id); + } } return initialChunkIds; }; diff --git a/lib/json/JsonData.js b/lib/json/JsonData.js new file mode 100644 index 00000000000..cb39dfc011b --- /dev/null +++ b/lib/json/JsonData.js @@ -0,0 +1,74 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ + +"use strict"; + +const { register } = require("../util/serialization"); + +/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */ +/** @typedef {import("../util/Hash")} Hash */ +/** @typedef {import("./JsonModulesPlugin").RawJsonData} RawJsonData */ + +class JsonData { + /** + * @param {Buffer | RawJsonData} data JSON data + */ + constructor(data) { + /** @type {Buffer | undefined} */ + this._buffer = undefined; + /** @type {RawJsonData | undefined} */ + this._data = undefined; + if (Buffer.isBuffer(data)) { + this._buffer = data; + } else { + this._data = data; + } + } + + /** + * @returns {RawJsonData|undefined} Raw JSON data + */ + get() { + if (this._data === undefined && this._buffer !== undefined) { + this._data = JSON.parse(this._buffer.toString()); + } + return this._data; + } + + /** + * @param {Hash} hash hash to be updated + * @returns {void} the updated hash + */ + updateHash(hash) { + if (this._buffer === undefined && this._data !== undefined) { + this._buffer = Buffer.from(JSON.stringify(this._data)); + } + + if (this._buffer) hash.update(this._buffer); + } +} + +register(JsonData, "webpack/lib/json/JsonData", null, { + /** + * @param {JsonData} obj JSONData object + * @param {ObjectSerializerContext} context context + */ + serialize(obj, { write }) { + if (obj._buffer === undefined && obj._data !== undefined) { + obj._buffer = Buffer.from(JSON.stringify(obj._data)); + } + write(obj._buffer); + }, + /** + * @param {ObjectDeserializerContext} context context + * @returns {JsonData} deserialized JSON data + */ + deserialize({ read }) { + return new JsonData(read()); + } +}); + +module.exports = JsonData; diff --git a/lib/json/JsonGenerator.js b/lib/json/JsonGenerator.js index 724c2a57786..c643f5dc8a8 100644 --- a/lib/json/JsonGenerator.js +++ b/lib/json/JsonGenerator.js @@ -17,11 +17,17 @@ const RuntimeGlobals = require("../RuntimeGlobals"); /** @typedef {import("../Module").ConcatenationBailoutReasonContext} ConcatenationBailoutReasonContext */ /** @typedef {import("../NormalModule")} NormalModule */ /** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */ +/** @typedef {import("./JsonData")} JsonData */ +/** @typedef {import("./JsonModulesPlugin").RawJsonData} RawJsonData */ +/** + * @param {RawJsonData} data Raw JSON data + * @returns {undefined|string} stringified data + */ const stringifySafe = data => { const stringified = JSON.stringify(data); if (!stringified) { - return undefined; // Invalid JSON + return; // Invalid JSON } return stringified.replace(/\u2028|\u2029/g, str => @@ -30,36 +36,33 @@ const stringifySafe = data => { }; /** - * @param {Object} data data (always an object or array) + * @param {RawJsonData} data Raw JSON data (always an object or array) * @param {ExportsInfo} exportsInfo exports info * @param {RuntimeSpec} runtime the runtime - * @returns {Object} reduced data + * @returns {RawJsonData} reduced data */ const createObjectForExportsInfo = (data, exportsInfo, runtime) => { if (exportsInfo.otherExportsInfo.getUsed(runtime) !== UsageState.Unused) return data; const isArray = Array.isArray(data); + /** @type {RawJsonData} */ const reducedData = isArray ? [] : {}; for (const key of Object.keys(data)) { const exportInfo = exportsInfo.getReadOnlyExportInfo(key); const used = exportInfo.getUsed(runtime); if (used === UsageState.Unused) continue; - let value; - if (used === UsageState.OnlyPropertiesUsed && exportInfo.exportsInfo) { - value = createObjectForExportsInfo( - data[key], - exportInfo.exportsInfo, - runtime - ); - } else { - value = data[key]; - } - const name = exportInfo.getUsedName(key, runtime); - reducedData[name] = value; + /** @type {RawJsonData} */ + const value = + used === UsageState.OnlyPropertiesUsed && exportInfo.exportsInfo + ? createObjectForExportsInfo(data[key], exportInfo.exportsInfo, runtime) + : data[key]; + + const name = /** @type {string} */ (exportInfo.getUsedName(key, runtime)); + /** @type {Record} */ (reducedData)[name] = value; } if (isArray) { - let arrayLengthWhenUsed = + const arrayLengthWhenUsed = exportsInfo.getReadOnlyExportInfo("length").getUsed(runtime) !== UsageState.Unused ? data.length @@ -86,6 +89,7 @@ const createObjectForExportsInfo = (data, exportsInfo, runtime) => { : { length: arrayLengthWhenUsed }, reducedData ); + /** @type {number} */ const generatedLength = arrayLengthWhenUsed !== undefined ? Math.max(arrayLengthWhenUsed, reducedData.length) @@ -116,9 +120,13 @@ class JsonGenerator extends Generator { * @returns {number} estimate size of the module */ getSize(module, type) { - let data = module.buildInfo.jsonData; + /** @type {RawJsonData | undefined} */ + const data = + module.buildInfo && + module.buildInfo.jsonData && + module.buildInfo.jsonData.get(); if (!data) return 0; - return stringifySafe(data).length + 10; + return /** @type {string} */ (stringifySafe(data)).length + 10; } /** @@ -145,7 +153,11 @@ class JsonGenerator extends Generator { concatenationScope } ) { - const data = module.buildInfo.jsonData; + /** @type {RawJsonData | undefined} */ + const data = + module.buildInfo && + module.buildInfo.jsonData && + module.buildInfo.jsonData.get(); if (data === undefined) { return new RawSource( runtimeTemplate.missingModuleStatement({ @@ -154,18 +166,20 @@ class JsonGenerator extends Generator { ); } const exportsInfo = moduleGraph.getExportsInfo(module); - let finalJson = + /** @type {RawJsonData} */ + const finalJson = typeof data === "object" && data && exportsInfo.otherExportsInfo.getUsed(runtime) === UsageState.Unused ? createObjectForExportsInfo(data, exportsInfo, runtime) : data; // Use JSON because JSON.parse() is much faster than JavaScript evaluation - const jsonStr = stringifySafe(finalJson); + const jsonStr = /** @type {string} */ (stringifySafe(finalJson)); const jsonExpr = jsonStr.length > 20 && typeof finalJson === "object" - ? `JSON.parse('${jsonStr.replace(/[\\']/g, "\\$&")}')` + ? `/*#__PURE__*/JSON.parse('${jsonStr.replace(/[\\']/g, "\\$&")}')` : jsonStr; + /** @type {string} */ let content; if (concatenationScope) { content = `${runtimeTemplate.supportsConst() ? "const" : "var"} ${ diff --git a/lib/json/JsonModulesPlugin.js b/lib/json/JsonModulesPlugin.js index 8106b476ba0..b87fdc42e61 100644 --- a/lib/json/JsonModulesPlugin.js +++ b/lib/json/JsonModulesPlugin.js @@ -5,17 +5,29 @@ "use strict"; -const { validate } = require("schema-utils"); -const memoize = require("../util/memoize"); +const { JSON_MODULE_TYPE } = require("../ModuleTypeConstants"); +const createSchemaValidation = require("../util/create-schema-validation"); const JsonGenerator = require("./JsonGenerator"); const JsonParser = require("./JsonParser"); /** @typedef {import("../Compiler")} Compiler */ +/** @typedef {Record} RawJsonData */ -const getParserSchema = memoize(() => - require("../../schemas/plugins/JsonModulesPluginParser.json") +const validate = createSchemaValidation( + require("../../schemas/plugins/JsonModulesPluginParser.check.js"), + () => require("../../schemas/plugins/JsonModulesPluginParser.json"), + { + name: "Json Modules Plugin", + baseDataPath: "parser" + } ); +const PLUGIN_NAME = "JsonModulesPlugin"; + +/** + * The JsonModulesPlugin is the entrypoint plugin for the json modules feature. + * It adds the json module type to the compiler and registers the json parser and generator. + */ class JsonModulesPlugin { /** * Apply the plugin @@ -24,23 +36,18 @@ class JsonModulesPlugin { */ apply(compiler) { compiler.hooks.compilation.tap( - "JsonModulesPlugin", + PLUGIN_NAME, (compilation, { normalModuleFactory }) => { normalModuleFactory.hooks.createParser - .for("json") - .tap("JsonModulesPlugin", parserOptions => { - validate(getParserSchema(), parserOptions, { - name: "Json Modules Plugin", - baseDataPath: "parser" - }); + .for(JSON_MODULE_TYPE) + .tap(PLUGIN_NAME, parserOptions => { + validate(parserOptions); return new JsonParser(parserOptions); }); normalModuleFactory.hooks.createGenerator - .for("json") - .tap("JsonModulesPlugin", () => { - return new JsonGenerator(); - }); + .for(JSON_MODULE_TYPE) + .tap(PLUGIN_NAME, () => new JsonGenerator()); } ); } diff --git a/lib/json/JsonParser.js b/lib/json/JsonParser.js index b7032b4a9c2..77f9fb8f4c7 100644 --- a/lib/json/JsonParser.js +++ b/lib/json/JsonParser.js @@ -5,13 +5,19 @@ "use strict"; -const parseJson = require("json-parse-better-errors"); const Parser = require("../Parser"); const JsonExportsDependency = require("../dependencies/JsonExportsDependency"); +const memoize = require("../util/memoize"); +const JsonData = require("./JsonData"); /** @typedef {import("../../declarations/plugins/JsonModulesPluginParser").JsonModulesPluginParserOptions} JsonModulesPluginParserOptions */ +/** @typedef {import("../Module").BuildInfo} BuildInfo */ +/** @typedef {import("../Module").BuildMeta} BuildMeta */ /** @typedef {import("../Parser").ParserState} ParserState */ /** @typedef {import("../Parser").PreparsedAst} PreparsedAst */ +/** @typedef {import("./JsonModulesPlugin").RawJsonData} RawJsonData */ + +const getParseJson = memoize(() => require("json-parse-even-better-errors")); class JsonParser extends Parser { /** @@ -32,23 +38,32 @@ class JsonParser extends Parser { source = source.toString("utf-8"); } - /** @type {JsonModulesPluginParserOptions["parse"]} */ + /** @type {NonNullable} */ const parseFn = - typeof this.options.parse === "function" ? this.options.parse : parseJson; - - const data = - typeof source === "object" - ? source - : parseFn(source[0] === "\ufeff" ? source.slice(1) : source); - - state.module.buildInfo.jsonData = data; - state.module.buildInfo.strict = true; - state.module.buildMeta.exportsType = "default"; - state.module.buildMeta.defaultObject = + typeof this.options.parse === "function" + ? this.options.parse + : getParseJson(); + /** @type {Buffer | RawJsonData | undefined} */ + let data; + try { + data = + typeof source === "object" + ? source + : parseFn(source[0] === "\uFEFF" ? source.slice(1) : source); + } catch (err) { + throw new Error( + `Cannot parse JSON: ${/** @type {Error} */ (err).message}` + ); + } + const jsonData = new JsonData(/** @type {Buffer | RawJsonData} */ (data)); + const buildInfo = /** @type {BuildInfo} */ (state.module.buildInfo); + buildInfo.jsonData = jsonData; + buildInfo.strict = true; + const buildMeta = /** @type {BuildMeta} */ (state.module.buildMeta); + buildMeta.exportsType = "default"; + buildMeta.defaultObject = typeof data === "object" ? "redirect-warn" : false; - state.module.addDependency( - new JsonExportsDependency(JsonExportsDependency.getExportsFromData(data)) - ); + state.module.addDependency(new JsonExportsDependency(jsonData)); return state; } } diff --git a/lib/library/AbstractLibraryPlugin.js b/lib/library/AbstractLibraryPlugin.js index b8f0ab24f23..fbd88a4bb82 100644 --- a/lib/library/AbstractLibraryPlugin.js +++ b/lib/library/AbstractLibraryPlugin.js @@ -12,6 +12,7 @@ const JavascriptModulesPlugin = require("../javascript/JavascriptModulesPlugin") /** @typedef {import("../../declarations/WebpackOptions").LibraryOptions} LibraryOptions */ /** @typedef {import("../../declarations/WebpackOptions").LibraryType} LibraryType */ /** @typedef {import("../Chunk")} Chunk */ +/** @typedef {import("../ChunkGraph")} ChunkGraph */ /** @typedef {import("../Compilation")} Compilation */ /** @typedef {import("../Compilation").ChunkHashContext} ChunkHashContext */ /** @typedef {import("../Compiler")} Compiler */ @@ -25,8 +26,9 @@ const COMMON_LIBRARY_NAME_MESSAGE = /** * @template T - * @typedef {Object} LibraryContext + * @typedef {object} LibraryContext * @property {Compilation} compilation + * @property {ChunkGraph} chunkGraph * @property {T} options */ @@ -35,7 +37,7 @@ const COMMON_LIBRARY_NAME_MESSAGE = */ class AbstractLibraryPlugin { /** - * @param {Object} options options + * @param {object} options options * @param {string} options.pluginName name of the plugin * @param {LibraryType} options.type used library type */ @@ -75,7 +77,8 @@ class AbstractLibraryPlugin { if (module) { this.finishEntryModule(module, name, { options, - compilation + compilation, + chunkGraph: compilation.chunkGraph }); } } @@ -84,6 +87,10 @@ class AbstractLibraryPlugin { } ); + /** + * @param {Chunk} chunk chunk + * @returns {TODO} options for the chunk + */ const getOptionsForChunk = chunk => { if (compilation.chunkGraph.getNumberOfEntryModules(chunk) === 0) return false; @@ -101,10 +108,14 @@ class AbstractLibraryPlugin { ) { compilation.hooks.additionalChunkRuntimeRequirements.tap( _pluginName, - (chunk, set) => { + (chunk, set, { chunkGraph }) => { const options = getOptionsForChunk(chunk); if (options !== false) { - this.runtimeRequirements(chunk, set, { options, compilation }); + this.runtimeRequirements(chunk, set, { + options, + compilation, + chunkGraph + }); } } ); @@ -116,7 +127,11 @@ class AbstractLibraryPlugin { hooks.render.tap(_pluginName, (source, renderContext) => { const options = getOptionsForChunk(renderContext.chunk); if (options === false) return source; - return this.render(source, renderContext, { options, compilation }); + return this.render(source, renderContext, { + options, + compilation, + chunkGraph: compilation.chunkGraph + }); }); } @@ -131,7 +146,8 @@ class AbstractLibraryPlugin { if (options === false) return; return this.embedInRuntimeBailout(module, renderContext, { options, - compilation + compilation, + chunkGraph: compilation.chunkGraph }); } ); @@ -146,7 +162,8 @@ class AbstractLibraryPlugin { if (options === false) return; return this.strictRuntimeBailout(renderContext, { options, - compilation + compilation, + chunkGraph: compilation.chunkGraph }); }); } @@ -161,7 +178,8 @@ class AbstractLibraryPlugin { if (options === false) return source; return this.renderStartup(source, module, renderContext, { options, - compilation + compilation, + chunkGraph: compilation.chunkGraph }); } ); @@ -170,7 +188,11 @@ class AbstractLibraryPlugin { hooks.chunkHash.tap(_pluginName, (chunk, hash, context) => { const options = getOptionsForChunk(chunk); if (options === false) return; - this.chunkHash(chunk, hash, context, { options, compilation }); + this.chunkHash(chunk, hash, context, { + options, + compilation, + chunkGraph: compilation.chunkGraph + }); }); }); } diff --git a/lib/library/AmdLibraryPlugin.js b/lib/library/AmdLibraryPlugin.js index 0fd1b700c87..d604c036c77 100644 --- a/lib/library/AmdLibraryPlugin.js +++ b/lib/library/AmdLibraryPlugin.js @@ -21,14 +21,15 @@ const AbstractLibraryPlugin = require("./AbstractLibraryPlugin"); /** @template T @typedef {import("./AbstractLibraryPlugin").LibraryContext} LibraryContext */ /** - * @typedef {Object} AmdLibraryPluginOptions + * @typedef {object} AmdLibraryPluginOptions * @property {LibraryType} type * @property {boolean=} requireAsWrapper */ /** - * @typedef {Object} AmdLibraryPluginParsed + * @typedef {object} AmdLibraryPluginParsed * @property {string} name + * @property {string} amdContainer */ /** @@ -52,23 +53,21 @@ class AmdLibraryPlugin extends AbstractLibraryPlugin { * @returns {T | false} preprocess as needed by overriding */ parseOptions(library) { - const { name } = library; + const { name, amdContainer } = library; if (this.requireAsWrapper) { if (name) { throw new Error( `AMD library name must be unset. ${AbstractLibraryPlugin.COMMON_LIBRARY_NAME_MESSAGE}` ); } - } else { - if (name && typeof name !== "string") { - throw new Error( - `AMD library name must be a simple string or unset. ${AbstractLibraryPlugin.COMMON_LIBRARY_NAME_MESSAGE}` - ); - } + } else if (name && typeof name !== "string") { + throw new Error( + `AMD library name must be a simple string or unset. ${AbstractLibraryPlugin.COMMON_LIBRARY_NAME_MESSAGE}` + ); } - return { - name: /** @type {string=} */ (name) - }; + const _name = /** @type {string} */ (name); + const _amdContainer = /** @type {string} */ (amdContainer); + return { name: _name, amdContainer: _amdContainer }; } /** @@ -85,7 +84,11 @@ class AmdLibraryPlugin extends AbstractLibraryPlugin { const modern = runtimeTemplate.supportsArrowFunction(); const modules = chunkGraph .getChunkModules(chunk) - .filter(m => m instanceof ExternalModule); + .filter( + m => + m instanceof ExternalModule && + (m.externalType === "amd" || m.externalType === "amd-require") + ); const externals = /** @type {ExternalModule[]} */ (modules); const externalsDepsArray = JSON.stringify( externals.map(m => @@ -107,12 +110,18 @@ class AmdLibraryPlugin extends AbstractLibraryPlugin { const fnStart = (modern ? `(${externalsArguments}) => {` - : `function(${externalsArguments}) {`) + (iife ? " return " : "\n"); + : `function(${externalsArguments}) {`) + + (iife || !chunk.hasRuntime() ? " return " : "\n"); const fnEnd = iife ? ";\n}" : "\n}"; + let amdContainerPrefix = ""; + if (options.amdContainer) { + amdContainerPrefix = `${options.amdContainer}.`; + } + if (this.requireAsWrapper) { return new ConcatSource( - `require(${externalsDepsArray}, ${fnStart}`, + `${amdContainerPrefix}require(${externalsDepsArray}, ${fnStart}`, source, `${fnEnd});` ); @@ -122,19 +131,24 @@ class AmdLibraryPlugin extends AbstractLibraryPlugin { }); return new ConcatSource( - `define(${JSON.stringify(name)}, ${externalsDepsArray}, ${fnStart}`, + `${amdContainerPrefix}define(${JSON.stringify( + name + )}, ${externalsDepsArray}, ${fnStart}`, source, `${fnEnd});` ); } else if (externalsArguments) { return new ConcatSource( - `define(${externalsDepsArray}, ${fnStart}`, + `${amdContainerPrefix}define(${externalsDepsArray}, ${fnStart}`, source, `${fnEnd});` ); - } else { - return new ConcatSource(`define(${fnStart}`, source, `${fnEnd});`); } + return new ConcatSource( + `${amdContainerPrefix}define(${fnStart}`, + source, + `${fnEnd});` + ); } /** @@ -154,6 +168,9 @@ class AmdLibraryPlugin extends AbstractLibraryPlugin { chunk }); hash.update(name); + } else if (options.amdContainer) { + hash.update("amdContainer"); + hash.update(options.amdContainer); } } } diff --git a/lib/library/AssignLibraryPlugin.js b/lib/library/AssignLibraryPlugin.js index 64394b6192e..24859bcd73f 100644 --- a/lib/library/AssignLibraryPlugin.js +++ b/lib/library/AssignLibraryPlugin.js @@ -7,6 +7,7 @@ const { ConcatSource } = require("webpack-sources"); const { UsageState } = require("../ExportsInfo"); +const RuntimeGlobals = require("../RuntimeGlobals"); const Template = require("../Template"); const propertyAccess = require("../util/propertyAccess"); const { getEntryRuntime } = require("../util/runtime"); @@ -16,6 +17,7 @@ const AbstractLibraryPlugin = require("./AbstractLibraryPlugin"); /** @typedef {import("../../declarations/WebpackOptions").LibraryOptions} LibraryOptions */ /** @typedef {import("../../declarations/WebpackOptions").LibraryType} LibraryType */ /** @typedef {import("../Chunk")} Chunk */ +/** @typedef {import("../Compilation")} Compilation */ /** @typedef {import("../Compilation").ChunkHashContext} ChunkHashContext */ /** @typedef {import("../Compiler")} Compiler */ /** @typedef {import("../Module")} Module */ @@ -24,17 +26,18 @@ const AbstractLibraryPlugin = require("./AbstractLibraryPlugin"); /** @typedef {import("../util/Hash")} Hash */ /** @template T @typedef {import("./AbstractLibraryPlugin").LibraryContext} LibraryContext */ -const KEYWORD_REGEX = /^(await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|false|finally|for|function|if|implements|import|in|instanceof|interface|let|new|null|package|private|protected|public|return|super|switch|static|this|throw|try|true|typeof|var|void|while|with|yield)$/; -const IDENTIFIER_REGEX = /^[\p{L}\p{Nl}$_][\p{L}\p{Nl}$\p{Mn}\p{Mc}\p{Nd}\p{Pc}]*$/iu; +const KEYWORD_REGEX = + /^(await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|false|finally|for|function|if|implements|import|in|instanceof|interface|let|new|null|package|private|protected|public|return|super|switch|static|this|throw|try|true|typeof|var|void|while|with|yield)$/; +const IDENTIFIER_REGEX = + /^[\p{L}\p{Nl}$_][\p{L}\p{Nl}$\p{Mn}\p{Mc}\p{Nd}\p{Pc}]*$/iu; /** * Validates the library name by checking for keywords and valid characters * @param {string} name name to be validated * @returns {boolean} true, when valid */ -const isNameValid = name => { - return !KEYWORD_REGEX.test(name) && IDENTIFIER_REGEX.test(name); -}; +const isNameValid = name => + !KEYWORD_REGEX.test(name) && IDENTIFIER_REGEX.test(name); /** * @param {string[]} accessor variable plus properties @@ -56,6 +59,7 @@ const accessWithInit = (accessor, existingLength, initLast = false) => { let i = 1; // all properties printed so far (excluding base) + /** @type {string[] | undefined} */ let propsSoFar; // if there is existingLength, print all properties until this position as property access @@ -86,16 +90,16 @@ const accessWithInit = (accessor, existingLength, initLast = false) => { }; /** - * @typedef {Object} AssignLibraryPluginOptions + * @typedef {object} AssignLibraryPluginOptions * @property {LibraryType} type * @property {string[] | "global"} prefix name prefix * @property {string | false} declare declare name as variable - * @property {"error"|"copy"|"assign"} unnamed behavior for unnamed library name + * @property {"error"|"static"|"copy"|"assign"} unnamed behavior for unnamed library name * @property {"copy"|"assign"=} named behavior for named library name */ /** - * @typedef {Object} AssignLibraryPluginParsed + * @typedef {object} AssignLibraryPluginParsed * @property {string | string[]} name * @property {string | string[] | undefined} export */ @@ -131,15 +135,14 @@ class AssignLibraryPlugin extends AbstractLibraryPlugin { `Library name must be a string or string array. ${AbstractLibraryPlugin.COMMON_LIBRARY_NAME_MESSAGE}` ); } - } else { - if (name && typeof name !== "string" && !Array.isArray(name)) { - throw new Error( - `Library name must be a string, string array or unset. ${AbstractLibraryPlugin.COMMON_LIBRARY_NAME_MESSAGE}` - ); - } + } else if (name && typeof name !== "string" && !Array.isArray(name)) { + throw new Error( + `Library name must be a string, string array or unset. ${AbstractLibraryPlugin.COMMON_LIBRARY_NAME_MESSAGE}` + ); } + const _name = /** @type {string | string[]} */ (name); return { - name: /** @type {string|string[]=} */ (name), + name: _name, export: library.export }; } @@ -170,12 +173,22 @@ class AssignLibraryPlugin extends AbstractLibraryPlugin { moduleGraph.addExtraReason(module, "used as library export"); } + /** + * @param {Compilation} compilation the compilation + * @returns {string[]} the prefix + */ _getPrefix(compilation) { return this.prefix === "global" - ? [compilation.outputOptions.globalObject] + ? [compilation.runtimeTemplate.globalObject] : this.prefix; } + /** + * @param {AssignLibraryPluginParsed} options the library options + * @param {Chunk} chunk the chunk + * @param {Compilation} compilation the compilation + * @returns {Array} the resolved full name + */ _getResolvedFullName(options, chunk, compilation) { const prefix = this._getPrefix(compilation); const fullName = options.name ? prefix.concat(options.name) : prefix; @@ -220,9 +233,15 @@ class AssignLibraryPlugin extends AbstractLibraryPlugin { * @param {LibraryContext} libraryContext context * @returns {string | undefined} bailout reason */ - embedInRuntimeBailout(module, { chunk }, { options, compilation }) { + embedInRuntimeBailout( + module, + { chunk, codeGenerationResults }, + { options, compilation } + ) { + const { data } = codeGenerationResults.get(module, chunk.runtime); const topLevelDeclarations = - module.buildInfo && module.buildInfo.topLevelDeclarations; + (data && data.get("topLevelDeclarations")) || + (module.buildInfo && module.buildInfo.topLevelDeclarations); if (!topLevelDeclarations) return "it doesn't tell about top level declarations."; const fullNameResolved = this._getResolvedFullName( @@ -259,19 +278,42 @@ class AssignLibraryPlugin extends AbstractLibraryPlugin { * @param {LibraryContext} libraryContext context * @returns {Source} source with library export */ - renderStartup(source, module, { chunk }, { options, compilation }) { + renderStartup( + source, + module, + { moduleGraph, chunk }, + { options, compilation } + ) { const fullNameResolved = this._getResolvedFullName( options, chunk, compilation ); + const staticExports = this.unnamed === "static"; const exportAccess = options.export ? propertyAccess( Array.isArray(options.export) ? options.export : [options.export] - ) + ) : ""; const result = new ConcatSource(source); - if (options.name ? this.named === "copy" : this.unnamed === "copy") { + if (staticExports) { + const exportsInfo = moduleGraph.getExportsInfo(module); + const exportTarget = accessWithInit( + fullNameResolved, + this._getPrefix(compilation).length, + true + ); + for (const exportInfo of exportsInfo.orderedExports) { + if (!exportInfo.provided) continue; + const nameAccess = propertyAccess([exportInfo.name]); + result.add( + `${exportTarget}${nameAccess} = ${RuntimeGlobals.exports}${exportAccess}${nameAccess};\n` + ); + } + result.add( + `Object.defineProperty(${exportTarget}, "__esModule", { value: true });\n` + ); + } else if (options.name ? this.named === "copy" : this.unnamed === "copy") { result.add( `var __webpack_export_target__ = ${accessWithInit( fullNameResolved, @@ -279,10 +321,11 @@ class AssignLibraryPlugin extends AbstractLibraryPlugin { true )};\n` ); - let exports = "__webpack_exports__"; + /** @type {string} */ + let exports = RuntimeGlobals.exports; if (exportAccess) { result.add( - `var __webpack_exports_export__ = __webpack_exports__${exportAccess};\n` + `var __webpack_exports_export__ = ${RuntimeGlobals.exports}${exportAccess};\n` ); exports = "__webpack_exports_export__"; } @@ -298,7 +341,7 @@ class AssignLibraryPlugin extends AbstractLibraryPlugin { fullNameResolved, this._getPrefix(compilation).length, false - )} = __webpack_exports__${exportAccess};\n` + )} = ${RuntimeGlobals.exports}${exportAccess};\n` ); } return result; @@ -311,7 +354,7 @@ class AssignLibraryPlugin extends AbstractLibraryPlugin { * @returns {void} */ runtimeRequirements(chunk, set, libraryContext) { - // we don't need to return exports from runtime + set.add(RuntimeGlobals.exports); } /** @@ -323,15 +366,10 @@ class AssignLibraryPlugin extends AbstractLibraryPlugin { */ chunkHash(chunk, hash, chunkHashContext, { options, compilation }) { hash.update("AssignLibraryPlugin"); - const prefix = - this.prefix === "global" - ? [compilation.outputOptions.globalObject] - : this.prefix; - const fullName = options.name ? prefix.concat(options.name) : prefix; - const fullNameResolved = fullName.map(n => - compilation.getPath(n, { - chunk - }) + const fullNameResolved = this._getResolvedFullName( + options, + chunk, + compilation ); if (options.name ? this.named === "copy" : this.unnamed === "copy") { hash.update("copy"); diff --git a/lib/library/EnableLibraryPlugin.js b/lib/library/EnableLibraryPlugin.js index 9cfa8333ad2..bbca42cdb40 100644 --- a/lib/library/EnableLibraryPlugin.js +++ b/lib/library/EnableLibraryPlugin.js @@ -12,6 +12,10 @@ /** @type {WeakMap>} */ const enabledTypes = new WeakMap(); +/** + * @param {Compiler} compiler the compiler instance + * @returns {Set} enabled types + */ const getEnabledTypes = compiler => { let set = enabledTypes.get(compiler); if (set === undefined) { @@ -48,10 +52,11 @@ class EnableLibraryPlugin { throw new Error( `Library type "${type}" is not enabled. ` + "EnableLibraryPlugin need to be used to enable this type of library. " + - 'This usually happens through the "output.enabledLibraryTypes" option. ' + - 'If you are using a function as entry which sets "library", you need to add all potential library types to "output.enabledLibraryTypes". ' + - "These types are enabled: " + - Array.from(getEnabledTypes(compiler)).join(", ") + `This usually happens through the "output.enabledLibraryTypes" option. ` + + `If you are using a function as entry which sets "library", you need to add all potential library types to "output.enabledLibraryTypes". ` + + `These types are enabled: ${Array.from( + getEnabledTypes(compiler) + ).join(", ")}` ); } } @@ -74,12 +79,13 @@ class EnableLibraryPlugin { const ExportPropertyTemplatePlugin = require("./ExportPropertyLibraryPlugin"); new ExportPropertyTemplatePlugin({ type, - nsObjectUsed: type !== "module" + nsObjectUsed: !["module", "modern-module"].includes(type), + runtimeExportsUsed: type !== "modern-module" }).apply(compiler); }; switch (type) { case "var": { - //@ts-expect-error https://github.com/microsoft/TypeScript/issues/41697 + // @ts-expect-error https://github.com/microsoft/TypeScript/issues/41697 const AssignLibraryPlugin = require("./AssignLibraryPlugin"); new AssignLibraryPlugin({ type, @@ -90,7 +96,7 @@ class EnableLibraryPlugin { break; } case "assign-properties": { - //@ts-expect-error https://github.com/microsoft/TypeScript/issues/41697 + // @ts-expect-error https://github.com/microsoft/TypeScript/issues/41697 const AssignLibraryPlugin = require("./AssignLibraryPlugin"); new AssignLibraryPlugin({ type, @@ -102,7 +108,7 @@ class EnableLibraryPlugin { break; } case "assign": { - //@ts-expect-error https://github.com/microsoft/TypeScript/issues/41697 + // @ts-expect-error https://github.com/microsoft/TypeScript/issues/41697 const AssignLibraryPlugin = require("./AssignLibraryPlugin"); new AssignLibraryPlugin({ type, @@ -113,7 +119,7 @@ class EnableLibraryPlugin { break; } case "this": { - //@ts-expect-error https://github.com/microsoft/TypeScript/issues/41697 + // @ts-expect-error https://github.com/microsoft/TypeScript/issues/41697 const AssignLibraryPlugin = require("./AssignLibraryPlugin"); new AssignLibraryPlugin({ type, @@ -124,7 +130,7 @@ class EnableLibraryPlugin { break; } case "window": { - //@ts-expect-error https://github.com/microsoft/TypeScript/issues/41697 + // @ts-expect-error https://github.com/microsoft/TypeScript/issues/41697 const AssignLibraryPlugin = require("./AssignLibraryPlugin"); new AssignLibraryPlugin({ type, @@ -135,7 +141,7 @@ class EnableLibraryPlugin { break; } case "self": { - //@ts-expect-error https://github.com/microsoft/TypeScript/issues/41697 + // @ts-expect-error https://github.com/microsoft/TypeScript/issues/41697 const AssignLibraryPlugin = require("./AssignLibraryPlugin"); new AssignLibraryPlugin({ type, @@ -146,7 +152,7 @@ class EnableLibraryPlugin { break; } case "global": { - //@ts-expect-error https://github.com/microsoft/TypeScript/issues/41697 + // @ts-expect-error https://github.com/microsoft/TypeScript/issues/41697 const AssignLibraryPlugin = require("./AssignLibraryPlugin"); new AssignLibraryPlugin({ type, @@ -157,7 +163,7 @@ class EnableLibraryPlugin { break; } case "commonjs": { - //@ts-expect-error https://github.com/microsoft/TypeScript/issues/41697 + // @ts-expect-error https://github.com/microsoft/TypeScript/issues/41697 const AssignLibraryPlugin = require("./AssignLibraryPlugin"); new AssignLibraryPlugin({ type, @@ -167,9 +173,20 @@ class EnableLibraryPlugin { }).apply(compiler); break; } + case "commonjs-static": { + // @ts-expect-error https://github.com/microsoft/TypeScript/issues/41697 + const AssignLibraryPlugin = require("./AssignLibraryPlugin"); + new AssignLibraryPlugin({ + type, + prefix: ["exports"], + declare: false, + unnamed: "static" + }).apply(compiler); + break; + } case "commonjs2": case "commonjs-module": { - //@ts-expect-error https://github.com/microsoft/TypeScript/issues/41697 + // @ts-expect-error https://github.com/microsoft/TypeScript/issues/41697 const AssignLibraryPlugin = require("./AssignLibraryPlugin"); new AssignLibraryPlugin({ type, @@ -223,6 +240,14 @@ class EnableLibraryPlugin { }).apply(compiler); break; } + case "modern-module": { + enableExportProperty(); + const ModernModuleLibraryPlugin = require("./ModernModuleLibraryPlugin"); + new ModernModuleLibraryPlugin({ + type + }).apply(compiler); + break; + } default: throw new Error(`Unsupported library type ${type}. Plugins which provide custom library types must call EnableLibraryPlugin.setEnabled(compiler, type) to disable this error.`); diff --git a/lib/library/ExportPropertyLibraryPlugin.js b/lib/library/ExportPropertyLibraryPlugin.js index 4d95642356d..1fe8945bcc4 100644 --- a/lib/library/ExportPropertyLibraryPlugin.js +++ b/lib/library/ExportPropertyLibraryPlugin.js @@ -7,6 +7,7 @@ const { ConcatSource } = require("webpack-sources"); const { UsageState } = require("../ExportsInfo"); +const RuntimeGlobals = require("../RuntimeGlobals"); const propertyAccess = require("../util/propertyAccess"); const { getEntryRuntime } = require("../util/runtime"); const AbstractLibraryPlugin = require("./AbstractLibraryPlugin"); @@ -21,14 +22,15 @@ const AbstractLibraryPlugin = require("./AbstractLibraryPlugin"); /** @template T @typedef {import("./AbstractLibraryPlugin").LibraryContext} LibraryContext */ /** - * @typedef {Object} ExportPropertyLibraryPluginParsed + * @typedef {object} ExportPropertyLibraryPluginParsed * @property {string | string[]} export */ /** - * @typedef {Object} ExportPropertyLibraryPluginOptions + * @typedef {object} ExportPropertyLibraryPluginOptions * @property {LibraryType} type * @property {boolean} nsObjectUsed the namespace object is used + * @property {boolean} runtimeExportsUsed runtime exports are used */ /** * @typedef {ExportPropertyLibraryPluginParsed} T @@ -38,12 +40,13 @@ class ExportPropertyLibraryPlugin extends AbstractLibraryPlugin { /** * @param {ExportPropertyLibraryPluginOptions} options options */ - constructor({ type, nsObjectUsed }) { + constructor({ type, nsObjectUsed, runtimeExportsUsed }) { super({ pluginName: "ExportPropertyLibraryPlugin", type }); this.nsObjectUsed = nsObjectUsed; + this.runtimeExportsUsed = runtimeExportsUsed; } /** @@ -92,7 +95,11 @@ class ExportPropertyLibraryPlugin extends AbstractLibraryPlugin { * @param {LibraryContext} libraryContext context * @returns {void} */ - runtimeRequirements(chunk, set, libraryContext) {} + runtimeRequirements(chunk, set, libraryContext) { + if (this.runtimeExportsUsed) { + set.add(RuntimeGlobals.exports); + } + } /** * @param {Source} source source @@ -103,7 +110,9 @@ class ExportPropertyLibraryPlugin extends AbstractLibraryPlugin { */ renderStartup(source, module, renderContext, { options }) { if (!options.export) return source; - const postfix = `__webpack_exports__ = __webpack_exports__${propertyAccess( + const postfix = `${RuntimeGlobals.exports} = ${ + RuntimeGlobals.exports + }${propertyAccess( Array.isArray(options.export) ? options.export : [options.export] )};\n`; return new ConcatSource(source, postfix); diff --git a/lib/library/JsonpLibraryPlugin.js b/lib/library/JsonpLibraryPlugin.js index c9845f590c4..9757874232d 100644 --- a/lib/library/JsonpLibraryPlugin.js +++ b/lib/library/JsonpLibraryPlugin.js @@ -19,12 +19,12 @@ const AbstractLibraryPlugin = require("./AbstractLibraryPlugin"); /** @template T @typedef {import("./AbstractLibraryPlugin").LibraryContext} LibraryContext */ /** - * @typedef {Object} JsonpLibraryPluginOptions + * @typedef {object} JsonpLibraryPluginOptions * @property {LibraryType} type */ /** - * @typedef {Object} JsonpLibraryPluginParsed + * @typedef {object} JsonpLibraryPluginParsed * @property {string} name */ @@ -54,8 +54,9 @@ class JsonpLibraryPlugin extends AbstractLibraryPlugin { `Jsonp library name must be a simple string. ${AbstractLibraryPlugin.COMMON_LIBRARY_NAME_MESSAGE}` ); } + const _name = /** @type {string} */ (name); return { - name: /** @type {string} */ (name) + name: _name }; } diff --git a/lib/library/ModernModuleLibraryPlugin.js b/lib/library/ModernModuleLibraryPlugin.js new file mode 100644 index 00000000000..23a9510c211 --- /dev/null +++ b/lib/library/ModernModuleLibraryPlugin.js @@ -0,0 +1,144 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ + +"use strict"; + +const { ConcatSource } = require("webpack-sources"); +const ConcatenatedModule = require("../optimize/ConcatenatedModule"); +const AbstractLibraryPlugin = require("./AbstractLibraryPlugin"); + +/** @typedef {import("webpack-sources").Source} Source */ +/** @typedef {import("../../declarations/WebpackOptions").LibraryOptions} LibraryOptions */ +/** @typedef {import("../../declarations/WebpackOptions").LibraryType} LibraryType */ +/** @typedef {import("../Chunk")} Chunk */ +/** @typedef {import("../Compilation").ChunkHashContext} ChunkHashContext */ +/** @typedef {import("../Compiler")} Compiler */ +/** @typedef {import("../Module")} Module */ +/** @typedef {import("../Module").BuildMeta} BuildMeta */ +/** @typedef {import("../javascript/JavascriptModulesPlugin").StartupRenderContext} StartupRenderContext */ +/** @typedef {import("../util/Hash")} Hash */ +/** @template T @typedef {import("./AbstractLibraryPlugin").LibraryContext} LibraryContext */ + +/** + * @typedef {object} ModernModuleLibraryPluginOptions + * @property {LibraryType} type + */ + +/** + * @typedef {object} ModernModuleLibraryPluginParsed + * @property {string} name + */ + +/** + * @typedef {ModernModuleLibraryPluginParsed} T + * @extends {AbstractLibraryPlugin} + */ +class ModernModuleLibraryPlugin extends AbstractLibraryPlugin { + /** + * Apply the plugin + * @param {Compiler} compiler the compiler instance + * @returns {void} + */ + apply(compiler) { + super.apply(compiler); + + compiler.hooks.compilation.tap("ModernModuleLibraryPlugin", compilation => { + const { exportsDefinitions } = + ConcatenatedModule.getCompilationHooks(compilation); + exportsDefinitions.tap("ModernModuleLibraryPlugin", () => true); + }); + } + + /** + * @param {ModernModuleLibraryPluginOptions} options the plugin options + */ + constructor(options) { + super({ + pluginName: "ModernModuleLibraryPlugin", + type: options.type + }); + } + + /** + * @param {LibraryOptions} library normalized library option + * @returns {T | false} preprocess as needed by overriding + */ + parseOptions(library) { + const { name } = library; + if (name) { + throw new Error( + `Library name must be unset. ${AbstractLibraryPlugin.COMMON_LIBRARY_NAME_MESSAGE}` + ); + } + const _name = /** @type {string} */ (name); + return { + name: _name + }; + } + + /** + * @param {Source} source source + * @param {Module} module module + * @param {StartupRenderContext} renderContext render context + * @param {LibraryContext} libraryContext context + * @returns {Source} source with library export + */ + renderStartup( + source, + module, + { moduleGraph, chunk }, + { options, compilation } + ) { + const result = new ConcatSource(source); + const exportsInfo = moduleGraph.getExportsInfo(module); + const definitions = + /** @type {BuildMeta} */ + (module.buildMeta).exportsFinalName; + const exports = []; + + for (const exportInfo of exportsInfo.orderedExports) { + let shouldContinue = false; + const reexport = exportInfo.findTarget(moduleGraph, _m => true); + + if (reexport) { + const exp = moduleGraph.getExportsInfo(reexport.module); + + for (const reexportInfo of exp.orderedExports) { + if ( + !reexportInfo.provided && + reexportInfo.name === /** @type {string[]} */ (reexport.export)[0] + ) { + shouldContinue = true; + } + } + } + + if (shouldContinue) continue; + + const webpackExportsProperty = exportInfo.getUsedName( + exportInfo.name, + chunk.runtime + ); + const finalName = + definitions[ + /** @type {string} */ + (webpackExportsProperty) + ]; + exports.push( + finalName === exportInfo.name + ? finalName + : `${finalName} as ${exportInfo.name}` + ); + } + + if (exports.length > 0) { + result.add(`export { ${exports.join(", ")} };\n`); + } + + return result; + } +} + +module.exports = ModernModuleLibraryPlugin; diff --git a/lib/library/ModuleLibraryPlugin.js b/lib/library/ModuleLibraryPlugin.js index 08828583b1e..57afdc3e1a4 100644 --- a/lib/library/ModuleLibraryPlugin.js +++ b/lib/library/ModuleLibraryPlugin.js @@ -6,6 +6,7 @@ "use strict"; const { ConcatSource } = require("webpack-sources"); +const RuntimeGlobals = require("../RuntimeGlobals"); const Template = require("../Template"); const propertyAccess = require("../util/propertyAccess"); const AbstractLibraryPlugin = require("./AbstractLibraryPlugin"); @@ -22,12 +23,12 @@ const AbstractLibraryPlugin = require("./AbstractLibraryPlugin"); /** @template T @typedef {import("./AbstractLibraryPlugin").LibraryContext} LibraryContext */ /** - * @typedef {Object} ModuleLibraryPluginOptions + * @typedef {object} ModuleLibraryPluginOptions * @property {LibraryType} type */ /** - * @typedef {Object} ModuleLibraryPluginParsed + * @typedef {object} ModuleLibraryPluginParsed * @property {string} name */ @@ -57,8 +58,9 @@ class ModuleLibraryPlugin extends AbstractLibraryPlugin { `Library name must be unset. ${AbstractLibraryPlugin.COMMON_LIBRARY_NAME_MESSAGE}` ); } + const _name = /** @type {string} */ (name); return { - name: /** @type {string} */ (name) + name: _name }; } @@ -78,14 +80,21 @@ class ModuleLibraryPlugin extends AbstractLibraryPlugin { const result = new ConcatSource(source); const exportsInfo = moduleGraph.getExportsInfo(module); const exports = []; + const isAsync = moduleGraph.isAsync(module); + if (isAsync) { + result.add( + `${RuntimeGlobals.exports} = await ${RuntimeGlobals.exports};\n` + ); + } for (const exportInfo of exportsInfo.orderedExports) { if (!exportInfo.provided) continue; - const varName = `__webpack_exports__${Template.toIdentifier( + const varName = `${RuntimeGlobals.exports}${Template.toIdentifier( exportInfo.name )}`; result.add( - `var ${varName} = __webpack_exports__${propertyAccess([ - exportInfo.getUsedName(exportInfo.name, chunk.runtime) + `var ${varName} = ${RuntimeGlobals.exports}${propertyAccess([ + /** @type {string} */ + (exportInfo.getUsedName(exportInfo.name, chunk.runtime)) ])};\n` ); exports.push(`${varName} as ${exportInfo.name}`); diff --git a/lib/library/SystemLibraryPlugin.js b/lib/library/SystemLibraryPlugin.js index 0558f4c683f..701b870d5ea 100644 --- a/lib/library/SystemLibraryPlugin.js +++ b/lib/library/SystemLibraryPlugin.js @@ -23,12 +23,12 @@ const AbstractLibraryPlugin = require("./AbstractLibraryPlugin"); /** @template T @typedef {import("./AbstractLibraryPlugin").LibraryContext} LibraryContext */ /** - * @typedef {Object} SystemLibraryPluginOptions + * @typedef {object} SystemLibraryPluginOptions * @property {LibraryType} type */ /** - * @typedef {Object} SystemLibraryPluginParsed + * @typedef {object} SystemLibraryPluginParsed * @property {string} name */ @@ -58,8 +58,9 @@ class SystemLibraryPlugin extends AbstractLibraryPlugin { `System.js library name must be a simple string or unset. ${AbstractLibraryPlugin.COMMON_LIBRARY_NAME_MESSAGE}` ); } + const _name = /** @type {string} */ (name); return { - name: /** @type {string=} */ (name) + name: _name }; } @@ -72,7 +73,7 @@ class SystemLibraryPlugin extends AbstractLibraryPlugin { render(source, { chunkGraph, moduleGraph, chunk }, { options, compilation }) { const modules = chunkGraph .getChunkModules(chunk) - .filter(m => m instanceof ExternalModule); + .filter(m => m instanceof ExternalModule && m.externalType === "system"); const externals = /** @type {ExternalModule[]} */ (modules); // The name this bundle should be registered as with System @@ -106,6 +107,7 @@ class SystemLibraryPlugin extends AbstractLibraryPlugin { .join("\n"); // Define __esModule flag on all internal variables and helpers + /** @type {string[]} */ const externalVarInitialization = []; // The system.register format requires an array of setter functions for externals. @@ -186,7 +188,7 @@ class SystemLibraryPlugin extends AbstractLibraryPlugin { .join(",\n") ), "]," - ]); + ]); return new ConcatSource( Template.asString([ diff --git a/lib/library/UmdLibraryPlugin.js b/lib/library/UmdLibraryPlugin.js index b7013d70c59..4ec1b6911cf 100644 --- a/lib/library/UmdLibraryPlugin.js +++ b/lib/library/UmdLibraryPlugin.js @@ -18,16 +18,20 @@ const AbstractLibraryPlugin = require("./AbstractLibraryPlugin"); /** @typedef {import("../../declarations/WebpackOptions").LibraryType} LibraryType */ /** @typedef {import("../Compiler")} Compiler */ /** @typedef {import("../javascript/JavascriptModulesPlugin").RenderContext} RenderContext */ +/** @typedef {import("../ExternalModule").RequestRecord} RequestRecord */ /** @typedef {import("../util/Hash")} Hash */ -/** @template T @typedef {import("./AbstractLibraryPlugin").LibraryContext} LibraryContext */ +/** + * @template T + * @typedef {import("./AbstractLibraryPlugin").LibraryContext} + * LibraryContext + */ /** * @param {string[]} accessor the accessor to convert to path * @returns {string} the path */ -const accessorToObjectAccess = accessor => { - return accessor.map(a => `[${JSON.stringify(a)}]`).join(""); -}; +const accessorToObjectAccess = accessor => + accessor.map(a => `[${JSON.stringify(a)}]`).join(""); /** * @param {string|undefined} base the path prefix @@ -53,13 +57,13 @@ const accessorAccess = (base, accessor, joinWith = ", ") => { /** @typedef {string | string[] | LibraryCustomUmdObject} UmdLibraryPluginName */ /** - * @typedef {Object} UmdLibraryPluginOptions + * @typedef {object} UmdLibraryPluginOptions * @property {LibraryType} type * @property {boolean=} optionalAmdExternalAsGlobal */ /** - * @typedef {Object} UmdLibraryPluginParsed + * @typedef {object} UmdLibraryPluginParsed * @property {string | string[]} name * @property {LibraryCustomUmdObject} names * @property {string | LibraryCustomUmdCommentObject} auxiliaryComment @@ -148,57 +152,76 @@ class UmdLibraryPlugin extends AbstractLibraryPlugin { requiredExternals = externals; } - const replaceKeys = str => { - return compilation.getPath(str, { + /** + * @param {string} str the string to replace + * @returns {string} the replaced keys + */ + const replaceKeys = str => + compilation.getPath(str, { chunk }); - }; - const externalsDepsArray = modules => { - return `[${replaceKeys( + /** + * @param {ExternalModule[]} modules external modules + * @returns {string} result + */ + const externalsDepsArray = modules => + `[${replaceKeys( modules .map(m => JSON.stringify( - typeof m.request === "object" ? m.request.amd : m.request + typeof m.request === "object" + ? /** @type {RequestRecord} */ + (m.request).amd + : m.request ) ) .join(", ") )}]`; - }; - const externalsRootArray = modules => { - return replaceKeys( + /** + * @param {ExternalModule[]} modules external modules + * @returns {string} result + */ + const externalsRootArray = modules => + replaceKeys( modules .map(m => { let request = m.request; - if (typeof request === "object") request = request.root; + if (typeof request === "object") + request = + /** @type {RequestRecord} */ + (request).root; return `root${accessorToObjectAccess([].concat(request))}`; }) .join(", ") ); - }; - const externalsRequireArray = type => { - return replaceKeys( + /** + * @param {string} type the type + * @returns {string} external require array + */ + const externalsRequireArray = type => + replaceKeys( externals .map(m => { let expr; let request = m.request; if (typeof request === "object") { - request = request[type]; + request = + /** @type {RequestRecord} */ + (request)[type]; } if (request === undefined) { throw new Error( - "Missing external configuration for type:" + type + `Missing external configuration for type:${type}` ); } - if (Array.isArray(request)) { - expr = `require(${JSON.stringify( - request[0] - )})${accessorToObjectAccess(request.slice(1))}`; - } else { - expr = `require(${JSON.stringify(request)})`; - } + expr = Array.isArray(request) + ? `require(${JSON.stringify( + request[0] + )})${accessorToObjectAccess(request.slice(1))}` + : `require(${JSON.stringify(request)})`; if (m.isOptional(moduleGraph)) { expr = `(function webpackLoadOptionalExternalModule() { try { return ${expr}; } catch(e) {} }())`; } @@ -206,10 +229,13 @@ class UmdLibraryPlugin extends AbstractLibraryPlugin { }) .join(", ") ); - }; - const externalsArguments = modules => { - return modules + /** + * @param {ExternalModule[]} modules external modules + * @returns {string} arguments + */ + const externalsArguments = modules => + modules .map( m => `__WEBPACK_EXTERNAL_MODULE_${Template.toIdentifier( @@ -217,20 +243,24 @@ class UmdLibraryPlugin extends AbstractLibraryPlugin { )}__` ) .join(", "); - }; - const libraryName = library => { - return JSON.stringify(replaceKeys([].concat(library).pop())); - }; + /** + * @param {string| string[]} library library name + * @returns {string} stringified library name + */ + const libraryName = library => + JSON.stringify( + replaceKeys(/** @type {string[]} */ ([]).concat(library).pop()) + ); let amdFactory; if (optionalExternals.length > 0) { const wrapperArguments = externalsArguments(requiredExternals); const factoryArguments = requiredExternals.length > 0 - ? externalsArguments(requiredExternals) + - ", " + - externalsRootArray(optionalExternals) + ? `${externalsArguments(requiredExternals)}, ${externalsRootArray( + optionalExternals + )}` : externalsRootArray(optionalExternals); amdFactory = `function webpackLoadOptionalExternalModuleAmd(${wrapperArguments}) {\n` + @@ -242,77 +272,66 @@ class UmdLibraryPlugin extends AbstractLibraryPlugin { const { auxiliaryComment, namedDefine, names } = options; + /** + * @param {keyof LibraryCustomUmdCommentObject} type type + * @returns {string} comment + */ const getAuxiliaryComment = type => { if (auxiliaryComment) { if (typeof auxiliaryComment === "string") - return "\t//" + auxiliaryComment + "\n"; - if (auxiliaryComment[type]) - return "\t//" + auxiliaryComment[type] + "\n"; + return `\t//${auxiliaryComment}\n`; + if (auxiliaryComment[type]) return `\t//${auxiliaryComment[type]}\n`; } return ""; }; return new ConcatSource( new OriginalSource( - "(function webpackUniversalModuleDefinition(root, factory) {\n" + - getAuxiliaryComment("commonjs2") + - " if(typeof exports === 'object' && typeof module === 'object')\n" + - " module.exports = factory(" + - externalsRequireArray("commonjs2") + - ");\n" + - getAuxiliaryComment("amd") + - " else if(typeof define === 'function' && define.amd)\n" + - (requiredExternals.length > 0 - ? names.amd && namedDefine === true - ? " define(" + - libraryName(names.amd) + - ", " + - externalsDepsArray(requiredExternals) + - ", " + - amdFactory + - ");\n" - : " define(" + - externalsDepsArray(requiredExternals) + - ", " + - amdFactory + - ");\n" - : names.amd && namedDefine === true - ? " define(" + - libraryName(names.amd) + - ", [], " + - amdFactory + - ");\n" - : " define([], " + amdFactory + ");\n") + - (names.root || names.commonjs - ? getAuxiliaryComment("commonjs") + - " else if(typeof exports === 'object')\n" + - " exports[" + - libraryName(names.commonjs || names.root) + - "] = factory(" + - externalsRequireArray("commonjs") + - ");\n" + - getAuxiliaryComment("root") + - " else\n" + - " " + - replaceKeys( - accessorAccess("root", names.root || names.commonjs) - ) + - " = factory(" + - externalsRootArray(externals) + - ");\n" - : " else {\n" + - (externals.length > 0 - ? " var a = typeof exports === 'object' ? factory(" + - externalsRequireArray("commonjs") + - ") : factory(" + - externalsRootArray(externals) + - ");\n" - : " var a = factory();\n") + - " for(var i in a) (typeof exports === 'object' ? exports : root)[i] = a[i];\n" + - " }\n") + - `})(${ - runtimeTemplate.outputOptions.globalObject - }, function(${externalsArguments(externals)}) {\nreturn `, + `(function webpackUniversalModuleDefinition(root, factory) {\n${getAuxiliaryComment( + "commonjs2" + )} if(typeof exports === 'object' && typeof module === 'object')\n` + + ` module.exports = factory(${externalsRequireArray( + "commonjs2" + )});\n${getAuxiliaryComment( + "amd" + )} else if(typeof define === 'function' && define.amd)\n${ + requiredExternals.length > 0 + ? names.amd && namedDefine === true + ? ` define(${libraryName(names.amd)}, ${externalsDepsArray( + requiredExternals + )}, ${amdFactory});\n` + : ` define(${externalsDepsArray(requiredExternals)}, ${ + amdFactory + });\n` + : names.amd && namedDefine === true + ? ` define(${libraryName(names.amd)}, [], ${amdFactory});\n` + : ` define([], ${amdFactory});\n` + }${ + names.root || names.commonjs + ? `${getAuxiliaryComment( + "commonjs" + )} else if(typeof exports === 'object')\n` + + ` exports[${libraryName( + names.commonjs || names.root + )}] = factory(${externalsRequireArray( + "commonjs" + )});\n${getAuxiliaryComment("root")} else\n` + + ` ${replaceKeys( + accessorAccess("root", names.root || names.commonjs) + )} = factory(${externalsRootArray(externals)});\n` + : ` else {\n${ + externals.length > 0 + ? ` var a = typeof exports === 'object' ? factory(${externalsRequireArray( + "commonjs" + )}) : factory(${externalsRootArray(externals)});\n` + : " var a = factory();\n" + } for(var i in a) (typeof exports === 'object' ? exports : root)[i] = a[i];\n` + + " }\n" + }})(${runtimeTemplate.outputOptions.globalObject}, ${ + runtimeTemplate.supportsArrowFunction() + ? `(${externalsArguments(externals)}) =>` + : `function(${externalsArguments(externals)})` + } {\nreturn `, "webpack/universalModuleDefinition" ), source, diff --git a/lib/logging/Logger.js b/lib/logging/Logger.js index e096ddb3688..a19297d8822 100644 --- a/lib/logging/Logger.js +++ b/lib/logging/Logger.js @@ -27,7 +27,7 @@ const LogType = Object.freeze({ status: /** @type {"status"} */ ("status") // message, arguments }); -exports.LogType = LogType; +module.exports.LogType = LogType; /** @typedef {typeof LogType[keyof typeof LogType]} LogTypeEnum */ @@ -45,26 +45,45 @@ class WebpackLogger { this.getChildLogger = getChildLogger; } + /** + * @param {...any} args args + */ error(...args) { this[LOG_SYMBOL](LogType.error, args); } + /** + * @param {...any} args args + */ warn(...args) { this[LOG_SYMBOL](LogType.warn, args); } + /** + * @param {...any} args args + */ info(...args) { this[LOG_SYMBOL](LogType.info, args); } + /** + * @param {...any} args args + */ log(...args) { this[LOG_SYMBOL](LogType.log, args); } + /** + * @param {...any} args args + */ debug(...args) { this[LOG_SYMBOL](LogType.debug, args); } + /** + * @param {any} assertion assertion + * @param {...any} args args + */ assert(assertion, ...args) { if (!assertion) { this[LOG_SYMBOL](LogType.error, args); @@ -79,35 +98,57 @@ class WebpackLogger { this[LOG_SYMBOL](LogType.clear); } + /** + * @param {...any} args args + */ status(...args) { this[LOG_SYMBOL](LogType.status, args); } + /** + * @param {...any} args args + */ group(...args) { this[LOG_SYMBOL](LogType.group, args); } + /** + * @param {...any} args args + */ groupCollapsed(...args) { this[LOG_SYMBOL](LogType.groupCollapsed, args); } - groupEnd(...args) { - this[LOG_SYMBOL](LogType.groupEnd, args); + groupEnd() { + this[LOG_SYMBOL](LogType.groupEnd); } + /** + * @param {string=} label label + */ profile(label) { this[LOG_SYMBOL](LogType.profile, [label]); } + /** + * @param {string=} label label + */ profileEnd(label) { this[LOG_SYMBOL](LogType.profileEnd, [label]); } + /** + * @param {string} label label + */ time(label) { + /** @type {Map} */ this[TIMERS_SYMBOL] = this[TIMERS_SYMBOL] || new Map(); this[TIMERS_SYMBOL].set(label, process.hrtime()); } + /** + * @param {string=} label label + */ timeLog(label) { const prev = this[TIMERS_SYMBOL] && this[TIMERS_SYMBOL].get(label); if (!prev) { @@ -117,16 +158,23 @@ class WebpackLogger { this[LOG_SYMBOL](LogType.time, [label, ...time]); } + /** + * @param {string=} label label + */ timeEnd(label) { const prev = this[TIMERS_SYMBOL] && this[TIMERS_SYMBOL].get(label); if (!prev) { throw new Error(`No such label '${label}' for WebpackLogger.timeEnd()`); } const time = process.hrtime(prev); - this[TIMERS_SYMBOL].delete(label); + /** @type {Map} */ + (this[TIMERS_SYMBOL]).delete(label); this[LOG_SYMBOL](LogType.time, [label, ...time]); } + /** + * @param {string=} label label + */ timeAggregate(label) { const prev = this[TIMERS_SYMBOL] && this[TIMERS_SYMBOL].get(label); if (!prev) { @@ -135,7 +183,9 @@ class WebpackLogger { ); } const time = process.hrtime(prev); - this[TIMERS_SYMBOL].delete(label); + /** @type {Map} */ + (this[TIMERS_SYMBOL]).delete(label); + /** @type {Map} */ this[TIMERS_AGGREGATES_SYMBOL] = this[TIMERS_AGGREGATES_SYMBOL] || new Map(); const current = this[TIMERS_AGGREGATES_SYMBOL].get(label); @@ -151,12 +201,16 @@ class WebpackLogger { this[TIMERS_AGGREGATES_SYMBOL].set(label, time); } + /** + * @param {string=} label label + */ timeAggregateEnd(label) { if (this[TIMERS_AGGREGATES_SYMBOL] === undefined) return; const time = this[TIMERS_AGGREGATES_SYMBOL].get(label); if (time === undefined) return; + this[TIMERS_AGGREGATES_SYMBOL].delete(label); this[LOG_SYMBOL](LogType.time, [label, ...time]); } } -exports.Logger = WebpackLogger; +module.exports.Logger = WebpackLogger; diff --git a/lib/logging/createConsoleLogger.js b/lib/logging/createConsoleLogger.js index 8ea23f543ac..068e8057226 100644 --- a/lib/logging/createConsoleLogger.js +++ b/lib/logging/createConsoleLogger.js @@ -12,26 +12,41 @@ const { LogType } = require("./Logger"); /** @typedef {import("./Logger").LogTypeEnum} LogTypeEnum */ /** @typedef {function(string): boolean} FilterFunction */ +/** @typedef {function(string, LogTypeEnum, any[]=): void} LoggingFunction */ /** - * @typedef {Object} LoggerOptions + * @typedef {object} LoggerConsole + * @property {function(): void} clear + * @property {function(): void} trace + * @property {(...args: any[]) => void} info + * @property {(...args: any[]) => void} log + * @property {(...args: any[]) => void} warn + * @property {(...args: any[]) => void} error + * @property {(...args: any[]) => void=} debug + * @property {(...args: any[]) => void=} group + * @property {(...args: any[]) => void=} groupCollapsed + * @property {(...args: any[]) => void=} groupEnd + * @property {(...args: any[]) => void=} status + * @property {(...args: any[]) => void=} profile + * @property {(...args: any[]) => void=} profileEnd + * @property {(...args: any[]) => void=} logTime + */ + +/** + * @typedef {object} LoggerOptions * @property {false|true|"none"|"error"|"warn"|"info"|"log"|"verbose"} level loglevel * @property {FilterTypes|boolean} debug filter for debug logging - * @property {Console & { status?: Function, logTime?: Function }} console the console to log to + * @property {LoggerConsole} console the console to log to */ /** * @param {FilterItemTypes} item an input item - * @returns {FilterFunction} filter function + * @returns {FilterFunction | undefined} filter function */ const filterToFunction = item => { if (typeof item === "string") { const regExp = new RegExp( - `[\\\\/]${item.replace( - // eslint-disable-next-line no-useless-escape - /[-[\]{}()*+?.\\^$|]/g, - "\\$&" - )}([\\\\/]|$|!|\\?)` + `[\\\\/]${item.replace(/[-[\]{}()*+?.\\^$|]/g, "\\$&")}([\\\\/]|$|!|\\?)` ); return ident => regExp.test(ident); } @@ -62,22 +77,25 @@ const LogLevel = { /** * @param {LoggerOptions} options options object - * @returns {function(string, LogTypeEnum, any[]): void} logging function + * @returns {LoggingFunction} logging function */ module.exports = ({ level = "info", debug = false, console }) => { const debugFilters = - typeof debug === "boolean" - ? [() => debug] - : /** @type {FilterItemTypes[]} */ ([]) - .concat(debug) - .map(filterToFunction); + /** @type {FilterFunction[]} */ + ( + typeof debug === "boolean" + ? [() => debug] + : /** @type {FilterItemTypes[]} */ ([]) + .concat(debug) + .map(filterToFunction) + ); /** @type {number} */ const loglevel = LogLevel[`${level}`] || 0; /** * @param {string} name name of the logger * @param {LogTypeEnum} type type of the log entry - * @param {any[]} args arguments of the log entry + * @param {any[]=} args arguments of the log entry * @returns {void} */ const logger = (name, type, args) => { @@ -85,20 +103,16 @@ module.exports = ({ level = "info", debug = false, console }) => { if (Array.isArray(args)) { if (args.length > 0 && typeof args[0] === "string") { return [`[${name}] ${args[0]}`, ...args.slice(1)]; - } else { - return [`[${name}]`, ...args]; } - } else { - return []; + return [`[${name}]`, ...args]; } + return []; }; const debug = debugFilters.some(f => f(name)); switch (type) { case LogType.debug: if (!debug) return; - // eslint-disable-next-line node/no-unsupported-features/node-builtins if (typeof console.debug === "function") { - // eslint-disable-next-line node/no-unsupported-features/node-builtins console.debug(...labeledArgs()); } else { console.log(...labeledArgs()); @@ -127,9 +141,7 @@ module.exports = ({ level = "info", debug = false, console }) => { case LogType.groupCollapsed: if (!debug && loglevel > LogLevel.log) return; if (!debug && loglevel > LogLevel.verbose) { - // eslint-disable-next-line node/no-unsupported-features/node-builtins if (typeof console.groupCollapsed === "function") { - // eslint-disable-next-line node/no-unsupported-features/node-builtins console.groupCollapsed(...labeledArgs()); } else { console.log(...labeledArgs()); @@ -139,9 +151,7 @@ module.exports = ({ level = "info", debug = false, console }) => { // falls through case LogType.group: if (!debug && loglevel > LogLevel.log) return; - // eslint-disable-next-line node/no-unsupported-features/node-builtins if (typeof console.group === "function") { - // eslint-disable-next-line node/no-unsupported-features/node-builtins console.group(...labeledArgs()); } else { console.log(...labeledArgs()); @@ -149,16 +159,17 @@ module.exports = ({ level = "info", debug = false, console }) => { break; case LogType.groupEnd: if (!debug && loglevel > LogLevel.log) return; - // eslint-disable-next-line node/no-unsupported-features/node-builtins if (typeof console.groupEnd === "function") { - // eslint-disable-next-line node/no-unsupported-features/node-builtins console.groupEnd(); } break; case LogType.time: { if (!debug && loglevel > LogLevel.log) return; - const ms = args[1] * 1000 + args[2] / 1000000; - const msg = `[${name}] ${args[0]}: ${ms} ms`; + const [label, start, end] = + /** @type {[string, number, number]} */ + (args); + const ms = start * 1000 + end / 1000000; + const msg = `[${name}] ${label}: ${ms} ms`; if (typeof console.logTime === "function") { console.logTime(msg); } else { @@ -167,39 +178,31 @@ module.exports = ({ level = "info", debug = false, console }) => { break; } case LogType.profile: - // eslint-disable-next-line node/no-unsupported-features/node-builtins if (typeof console.profile === "function") { - // eslint-disable-next-line node/no-unsupported-features/node-builtins console.profile(...labeledArgs()); } break; case LogType.profileEnd: - // eslint-disable-next-line node/no-unsupported-features/node-builtins if (typeof console.profileEnd === "function") { - // eslint-disable-next-line node/no-unsupported-features/node-builtins console.profileEnd(...labeledArgs()); } break; case LogType.clear: if (!debug && loglevel > LogLevel.log) return; - // eslint-disable-next-line node/no-unsupported-features/node-builtins if (typeof console.clear === "function") { - // eslint-disable-next-line node/no-unsupported-features/node-builtins console.clear(); } break; case LogType.status: if (!debug && loglevel > LogLevel.info) return; if (typeof console.status === "function") { - if (args.length === 0) { + if (!args || args.length === 0) { console.status(); } else { console.status(...labeledArgs()); } - } else { - if (args.length !== 0) { - console.info(...labeledArgs()); - } + } else if (args && args.length !== 0) { + console.info(...labeledArgs()); } break; default: diff --git a/lib/logging/runtime.js b/lib/logging/runtime.js index 26422f27b19..b0c614081f0 100644 --- a/lib/logging/runtime.js +++ b/lib/logging/runtime.js @@ -5,12 +5,12 @@ "use strict"; -const SyncBailHook = require("tapable/lib/SyncBailHook"); +const { SyncBailHook } = require("tapable"); const { Logger } = require("./Logger"); const createConsoleLogger = require("./createConsoleLogger"); /** @type {createConsoleLogger.LoggerOptions} */ -let currentDefaultLoggerOptions = { +const currentDefaultLoggerOptions = { level: "info", debug: false, console @@ -21,26 +21,25 @@ let currentDefaultLogger = createConsoleLogger(currentDefaultLoggerOptions); * @param {string} name name of the logger * @returns {Logger} a logger */ -exports.getLogger = name => { - return new Logger( +module.exports.getLogger = name => + new Logger( (type, args) => { - if (exports.hooks.log.call(name, type, args) === undefined) { + if (module.exports.hooks.log.call(name, type, args) === undefined) { currentDefaultLogger(name, type, args); } }, - childName => exports.getLogger(`${name}/${childName}`) + childName => module.exports.getLogger(`${name}/${childName}`) ); -}; /** * @param {createConsoleLogger.LoggerOptions} options new options, merge with old options * @returns {void} */ -exports.configureDefaultLogger = options => { +module.exports.configureDefaultLogger = options => { Object.assign(currentDefaultLoggerOptions, options); currentDefaultLogger = createConsoleLogger(currentDefaultLoggerOptions); }; -exports.hooks = { +module.exports.hooks = { log: new SyncBailHook(["origin", "type", "args"]) }; diff --git a/lib/logging/truncateArgs.js b/lib/logging/truncateArgs.js index 6e20c8be5c6..d7f1dfbb559 100644 --- a/lib/logging/truncateArgs.js +++ b/lib/logging/truncateArgs.js @@ -5,6 +5,10 @@ "use strict"; +/** + * @param {Array} array array of numbers + * @returns {number} sum of all numbers in array + */ const arraySum = array => { let sum = 0; for (const item of array) sum += item; @@ -24,17 +28,15 @@ const truncateArgs = (args, maxLength) => { if (availableLength >= args[0].length) { return args; } else if (availableLength > 3) { - return ["..." + args[0].slice(-availableLength + 3)]; - } else { - return [args[0].slice(-availableLength)]; + return [`...${args[0].slice(-availableLength + 3)}`]; } + return [args[0].slice(-availableLength)]; } // Check if there is space for at least 4 chars per arg if (availableLength < arraySum(lengths.map(i => Math.min(i, 6)))) { // remove args - if (args.length > 1) - return truncateArgs(args.slice(0, args.length - 1), maxLength); + if (args.length > 1) return truncateArgs(args.slice(0, -1), maxLength); return []; } @@ -70,12 +72,11 @@ const truncateArgs = (args, maxLength) => { if (str.length === length) { return str; } else if (length > 5) { - return "..." + str.slice(-length + 3); + return `...${str.slice(-length + 3)}`; } else if (length > 0) { return str.slice(-length); - } else { - return ""; } + return ""; }); }; diff --git a/lib/node/CommonJsChunkLoadingPlugin.js b/lib/node/CommonJsChunkLoadingPlugin.js index c25f07b48db..cd7f787281a 100644 --- a/lib/node/CommonJsChunkLoadingPlugin.js +++ b/lib/node/CommonJsChunkLoadingPlugin.js @@ -8,11 +8,19 @@ const RuntimeGlobals = require("../RuntimeGlobals"); const StartupChunkDependenciesPlugin = require("../runtime/StartupChunkDependenciesPlugin"); +/** @typedef {import("../Chunk")} Chunk */ /** @typedef {import("../Compiler")} Compiler */ +/** + * @typedef {object} CommonJsChunkLoadingPluginOptions + * @property {boolean} [asyncChunkLoading] enable async chunk loading + */ + class CommonJsChunkLoadingPlugin { - constructor(options) { - options = options || {}; + /** + * @param {CommonJsChunkLoadingPluginOptions} [options] options + */ + constructor(options = {}) { this._asyncChunkLoading = options.asyncChunkLoading; } @@ -36,13 +44,23 @@ class CommonJsChunkLoadingPlugin { "CommonJsChunkLoadingPlugin", compilation => { const globalChunkLoading = compilation.outputOptions.chunkLoading; + /** + * @param {Chunk} chunk chunk + * @returns {boolean} true, if wasm loading is enabled for the chunk + */ const isEnabledForChunk = chunk => { const options = chunk.getEntryOptions(); const chunkLoading = - (options && options.chunkLoading) || globalChunkLoading; + options && options.chunkLoading !== undefined + ? options.chunkLoading + : globalChunkLoading; return chunkLoading === chunkLoadingValue; }; const onceForChunkSet = new WeakSet(); + /** + * @param {Chunk} chunk chunk + * @param {Set} set runtime requirements + */ const handler = (chunk, set) => { if (onceForChunkSet.has(chunk)) return; onceForChunkSet.add(chunk); diff --git a/lib/node/NodeEnvironmentPlugin.js b/lib/node/NodeEnvironmentPlugin.js index a40268f173f..221b1af0efa 100644 --- a/lib/node/NodeEnvironmentPlugin.js +++ b/lib/node/NodeEnvironmentPlugin.js @@ -5,17 +5,23 @@ "use strict"; -const CachedInputFileSystem = require("enhanced-resolve/lib/CachedInputFileSystem"); +const CachedInputFileSystem = require("enhanced-resolve").CachedInputFileSystem; const fs = require("graceful-fs"); const createConsoleLogger = require("../logging/createConsoleLogger"); const NodeWatchFileSystem = require("./NodeWatchFileSystem"); const nodeConsole = require("./nodeConsole"); +/** @typedef {import("../../declarations/WebpackOptions").InfrastructureLogging} InfrastructureLogging */ /** @typedef {import("../Compiler")} Compiler */ +/** @typedef {import("../util/fs").InputFileSystem} InputFileSystem */ class NodeEnvironmentPlugin { + /** + * @param {object} options options + * @param {InfrastructureLogging} options.infrastructureLogging infrastructure logging options + */ constructor(options) { - this.options = options || {}; + this.options = options; } /** @@ -24,25 +30,33 @@ class NodeEnvironmentPlugin { * @returns {void} */ apply(compiler) { - compiler.infrastructureLogger = createConsoleLogger( - Object.assign( - { - level: "info", - debug: false, - console: nodeConsole - }, - this.options.infrastructureLogging - ) - ); + const { infrastructureLogging } = this.options; + compiler.infrastructureLogger = createConsoleLogger({ + level: infrastructureLogging.level || "info", + debug: infrastructureLogging.debug || false, + console: + infrastructureLogging.console || + nodeConsole({ + colors: infrastructureLogging.colors, + appendOnly: infrastructureLogging.appendOnly, + stream: + /** @type {NodeJS.WritableStream} */ + (infrastructureLogging.stream) + }) + }); compiler.inputFileSystem = new CachedInputFileSystem(fs, 60000); - const inputFileSystem = compiler.inputFileSystem; + const inputFileSystem = + /** @type {InputFileSystem} */ + (compiler.inputFileSystem); compiler.outputFileSystem = fs; compiler.intermediateFileSystem = fs; - compiler.watchFileSystem = new NodeWatchFileSystem( - compiler.inputFileSystem - ); + compiler.watchFileSystem = new NodeWatchFileSystem(inputFileSystem); compiler.hooks.beforeRun.tap("NodeEnvironmentPlugin", compiler => { - if (compiler.inputFileSystem === inputFileSystem) { + if ( + compiler.inputFileSystem === inputFileSystem && + inputFileSystem.purge + ) { + compiler.fsStartTime = Date.now(); inputFileSystem.purge(); } }); diff --git a/lib/node/NodeTargetPlugin.js b/lib/node/NodeTargetPlugin.js index c5f7961c104..1cc01810daa 100644 --- a/lib/node/NodeTargetPlugin.js +++ b/lib/node/NodeTargetPlugin.js @@ -11,6 +11,7 @@ const ExternalsPlugin = require("../ExternalsPlugin"); const builtins = [ "assert", + "assert/strict", "async_hooks", "buffer", "child_process", @@ -19,6 +20,7 @@ const builtins = [ "constants", "crypto", "dgram", + "diagnostics_channel", "dns", "dns/promises", "domain", @@ -29,18 +31,24 @@ const builtins = [ "http2", "https", "inspector", + "inspector/promises", "module", "net", "os", "path", + "path/posix", + "path/win32", "perf_hooks", "process", "punycode", "querystring", "readline", + "readline/promises", "repl", "stream", + "stream/consumers", "stream/promises", + "stream/web", "string_decoder", "sys", "timers", @@ -50,11 +58,17 @@ const builtins = [ "tty", "url", "util", + "util/types", "v8", "vm", "wasi", "worker_threads", - "zlib" + "zlib", + /^node:/, + + // cspell:word pnpapi + // Yarn PnP adds pnpapi as "builtin" + "pnpapi" ]; class NodeTargetPlugin { @@ -64,7 +78,7 @@ class NodeTargetPlugin { * @returns {void} */ apply(compiler) { - new ExternalsPlugin("commonjs", builtins).apply(compiler); + new ExternalsPlugin("node-commonjs", builtins).apply(compiler); } } diff --git a/lib/node/NodeTemplatePlugin.js b/lib/node/NodeTemplatePlugin.js index cbe8c996198..c784368e373 100644 --- a/lib/node/NodeTemplatePlugin.js +++ b/lib/node/NodeTemplatePlugin.js @@ -10,9 +10,17 @@ const EnableChunkLoadingPlugin = require("../javascript/EnableChunkLoadingPlugin /** @typedef {import("../Compiler")} Compiler */ +/** + * @typedef {object} NodeTemplatePluginOptions + * @property {boolean} [asyncChunkLoading] enable async chunk loading + */ + class NodeTemplatePlugin { - constructor(options) { - this._options = options || {}; + /** + * @param {NodeTemplatePluginOptions} [options] options object + */ + constructor(options = {}) { + this._options = options; } /** diff --git a/lib/node/NodeWatchFileSystem.js b/lib/node/NodeWatchFileSystem.js index 5e2421bd964..d7b59f2c0e6 100644 --- a/lib/node/NodeWatchFileSystem.js +++ b/lib/node/NodeWatchFileSystem.js @@ -5,15 +5,18 @@ "use strict"; +const util = require("util"); const Watchpack = require("watchpack"); /** @typedef {import("../../declarations/WebpackOptions").WatchOptions} WatchOptions */ /** @typedef {import("../FileSystemInfo").FileSystemInfoEntry} FileSystemInfoEntry */ -/** @typedef {import("../util/fs").WatchFileSystem} WatchFileSystem */ +/** @typedef {import("../util/fs").InputFileSystem} InputFileSystem */ /** @typedef {import("../util/fs").WatchMethod} WatchMethod */ -/** @typedef {import("../util/fs").Watcher} Watcher */ class NodeWatchFileSystem { + /** + * @param {InputFileSystem} inputFileSystem input filesystem + */ constructor(inputFileSystem) { this.inputFileSystem = inputFileSystem; this.watcherOptions = { @@ -22,16 +25,7 @@ class NodeWatchFileSystem { this.watcher = new Watchpack(this.watcherOptions); } - /** - * @param {Iterable} files watched files - * @param {Iterable} directories watched directories - * @param {Iterable} missing watched exitance entries - * @param {number} startTime timestamp of start time - * @param {WatchOptions} options options object - * @param {function(Error=, Map, Map, Set, Set): void} callback aggregated callback - * @param {function(string, number): void} callbackUndelayed callback when the first change was detected - * @returns {Watcher} a watcher - */ + /** @type {WatchMethod} */ watch( files, directories, @@ -68,18 +62,47 @@ class NodeWatchFileSystem { if (callbackUndelayed) { this.watcher.once("change", callbackUndelayed); } - this.watcher.once("aggregated", (changes, removals) => { - if (this.inputFileSystem && this.inputFileSystem.purge) { - for (const item of changes) { - this.inputFileSystem.purge(item); - } - for (const item of removals) { - this.inputFileSystem.purge(item); + + const fetchTimeInfo = () => { + const fileTimeInfoEntries = new Map(); + const contextTimeInfoEntries = new Map(); + if (this.watcher) { + this.watcher.collectTimeInfoEntries( + fileTimeInfoEntries, + contextTimeInfoEntries + ); + } + return { fileTimeInfoEntries, contextTimeInfoEntries }; + }; + this.watcher.once( + "aggregated", + /** + * @param {Set} changes changes + * @param {Set} removals removals + */ + (changes, removals) => { + // pause emitting events (avoids clearing aggregated changes and removals on timeout) + this.watcher.pause(); + + const fs = this.inputFileSystem; + if (fs && fs.purge) { + for (const item of changes) { + fs.purge(item); + } + for (const item of removals) { + fs.purge(item); + } } + const { fileTimeInfoEntries, contextTimeInfoEntries } = fetchTimeInfo(); + callback( + null, + fileTimeInfoEntries, + contextTimeInfoEntries, + changes, + removals + ); } - const times = this.watcher.getTimeInfoEntries(); - callback(null, times, times, changes, removals); - }); + ); this.watcher.watch({ files, directories, missing, startTime }); @@ -98,25 +121,67 @@ class NodeWatchFileSystem { this.watcher.pause(); } }, - getAggregatedRemovals: () => { - return this.watcher && this.watcher.aggregatedRemovals; - }, - getAggregatedChanges: () => { - return this.watcher && this.watcher.aggregatedChanges; - }, - getFileTimeInfoEntries: () => { - if (this.watcher) { - return this.watcher.getTimeInfoEntries(); - } else { - return new Map(); - } - }, - getContextTimeInfoEntries: () => { - if (this.watcher) { - return this.watcher.getTimeInfoEntries(); - } else { - return new Map(); + getAggregatedRemovals: util.deprecate( + () => { + const items = this.watcher && this.watcher.aggregatedRemovals; + const fs = this.inputFileSystem; + if (items && fs && fs.purge) { + for (const item of items) { + fs.purge(item); + } + } + return items; + }, + "Watcher.getAggregatedRemovals is deprecated in favor of Watcher.getInfo since that's more performant.", + "DEP_WEBPACK_WATCHER_GET_AGGREGATED_REMOVALS" + ), + getAggregatedChanges: util.deprecate( + () => { + const items = this.watcher && this.watcher.aggregatedChanges; + const fs = this.inputFileSystem; + if (items && fs && fs.purge) { + for (const item of items) { + fs.purge(item); + } + } + return items; + }, + "Watcher.getAggregatedChanges is deprecated in favor of Watcher.getInfo since that's more performant.", + "DEP_WEBPACK_WATCHER_GET_AGGREGATED_CHANGES" + ), + getFileTimeInfoEntries: util.deprecate( + () => fetchTimeInfo().fileTimeInfoEntries, + "Watcher.getFileTimeInfoEntries is deprecated in favor of Watcher.getInfo since that's more performant.", + "DEP_WEBPACK_WATCHER_FILE_TIME_INFO_ENTRIES" + ), + getContextTimeInfoEntries: util.deprecate( + () => fetchTimeInfo().contextTimeInfoEntries, + "Watcher.getContextTimeInfoEntries is deprecated in favor of Watcher.getInfo since that's more performant.", + "DEP_WEBPACK_WATCHER_CONTEXT_TIME_INFO_ENTRIES" + ), + getInfo: () => { + const removals = this.watcher && this.watcher.aggregatedRemovals; + const changes = this.watcher && this.watcher.aggregatedChanges; + const fs = this.inputFileSystem; + if (fs && fs.purge) { + if (removals) { + for (const item of removals) { + fs.purge(item); + } + } + if (changes) { + for (const item of changes) { + fs.purge(item); + } + } } + const { fileTimeInfoEntries, contextTimeInfoEntries } = fetchTimeInfo(); + return { + changes, + removals, + fileTimeInfoEntries, + contextTimeInfoEntries + }; } }; } diff --git a/lib/node/ReadFileChunkLoadingRuntimeModule.js b/lib/node/ReadFileChunkLoadingRuntimeModule.js index 827b689248b..fd138b2e899 100644 --- a/lib/node/ReadFileChunkLoadingRuntimeModule.js +++ b/lib/node/ReadFileChunkLoadingRuntimeModule.js @@ -15,18 +15,47 @@ const { getInitialChunkIds } = require("../javascript/StartupHelpers"); const compileBooleanMatcher = require("../util/compileBooleanMatcher"); const { getUndoPath } = require("../util/identifier"); +/** @typedef {import("../Chunk")} Chunk */ +/** @typedef {import("../ChunkGraph")} ChunkGraph */ +/** @typedef {import("../Compilation")} Compilation */ +/** @typedef {import("../Module").ReadOnlyRuntimeRequirements} ReadOnlyRuntimeRequirements */ + class ReadFileChunkLoadingRuntimeModule extends RuntimeModule { + /** + * @param {ReadOnlyRuntimeRequirements} runtimeRequirements runtime requirements + */ constructor(runtimeRequirements) { super("readFile chunk loading", RuntimeModule.STAGE_ATTACH); this.runtimeRequirements = runtimeRequirements; } /** - * @returns {string} runtime code + * @private + * @param {Chunk} chunk chunk + * @param {string} rootOutputDir root output directory + * @returns {string} generated code + */ + _generateBaseUri(chunk, rootOutputDir) { + const options = chunk.getEntryOptions(); + if (options && options.baseUri) { + return `${RuntimeGlobals.baseURI} = ${JSON.stringify(options.baseUri)};`; + } + + return `${RuntimeGlobals.baseURI} = require("url").pathToFileURL(${ + rootOutputDir + ? `__dirname + ${JSON.stringify(`/${rootOutputDir}`)}` + : "__filename" + });`; + } + + /** + * @returns {string | null} runtime code */ generate() { - const { chunk } = this; - const { chunkGraph, runtimeTemplate } = this.compilation; + const compilation = /** @type {Compilation} */ (this.compilation); + const chunkGraph = /** @type {ChunkGraph} */ (this.chunkGraph); + const chunk = /** @type {Chunk} */ (this.chunk); + const { runtimeTemplate } = compilation; const fn = RuntimeGlobals.ensureChunkHandlers; const withBaseURI = this.runtimeRequirements.has(RuntimeGlobals.baseURI); const withExternalInstallChunk = this.runtimeRequirements.has( @@ -46,10 +75,10 @@ class ReadFileChunkLoadingRuntimeModule extends RuntimeModule { ); const conditionMap = chunkGraph.getChunkConditionMap(chunk, chunkHasJs); const hasJsMatcher = compileBooleanMatcher(conditionMap); - const initialChunkIds = getInitialChunkIds(chunk, chunkGraph); + const initialChunkIds = getInitialChunkIds(chunk, chunkGraph, chunkHasJs); - const outputName = this.compilation.getPath( - getChunkFilenameTemplate(chunk, this.compilation.outputOptions), + const outputName = compilation.getPath( + getChunkFilenameTemplate(chunk, compilation.outputOptions), { chunk, contentHashType: "javascript" @@ -57,24 +86,24 @@ class ReadFileChunkLoadingRuntimeModule extends RuntimeModule { ); const rootOutputDir = getUndoPath( outputName, - this.compilation.outputOptions.path, + /** @type {string} */ (compilation.outputOptions.path), false ); + const stateExpression = withHmr + ? `${RuntimeGlobals.hmrRuntimeStatePrefix}_readFileVm` + : undefined; + return Template.asString([ withBaseURI - ? Template.asString([ - `${RuntimeGlobals.baseURI} = require("url").pathToFileURL(${ - rootOutputDir - ? `__dirname + ${JSON.stringify("/" + rootOutputDir)}` - : "__filename" - });` - ]) + ? this._generateBaseUri(chunk, rootOutputDir) : "// no baseURI", "", "// object to store loaded chunks", '// "0" means "already loaded", Promise means loading', - "var installedChunks = {", + `var installedChunks = ${ + stateExpression ? `${stateExpression} = ${stateExpression} || ` : "" + }{`, Template.indent( Array.from(initialChunkIds, id => `${JSON.stringify(id)}: 0`).join( ",\n" @@ -85,10 +114,10 @@ class ReadFileChunkLoadingRuntimeModule extends RuntimeModule { withOnChunkLoad ? `${ RuntimeGlobals.onChunksLoaded - }.readFileVm = ${runtimeTemplate.returningFunction( + }.readFileVm = ${runtimeTemplate.returningFunction( "installedChunks[chunkId] === 0", "chunkId" - )};` + )};` : "// no on chunks loaded", "", withLoading || withExternalInstallChunk @@ -103,7 +132,7 @@ class ReadFileChunkLoadingRuntimeModule extends RuntimeModule { "}" ]), "}", - `if(runtime) runtime(__webpack_require__);`, + `if(runtime) runtime(${RuntimeGlobals.require});`, "for(var i = 0; i < chunkIds.length; i++) {", Template.indent([ "if(installedChunks[chunkIds[i]]) {", @@ -113,7 +142,7 @@ class ReadFileChunkLoadingRuntimeModule extends RuntimeModule { ]), "}", withOnChunkLoad ? `${RuntimeGlobals.onChunksLoaded}();` : "" - ])};` + ])};` : "// no chunk install function needed", "", withLoading @@ -157,22 +186,24 @@ class ReadFileChunkLoadingRuntimeModule extends RuntimeModule { "});", "promises.push(installedChunkData[2] = promise);" ]), - "} else installedChunks[chunkId] = 0;" + hasJsMatcher === true + ? "}" + : "} else installedChunks[chunkId] = 0;" ]), "}" ]), "}" - ]) + ]) : Template.indent(["installedChunks[chunkId] = 0;"]), "};" - ]) + ]) : "// no chunk loading", "", withExternalInstallChunk ? Template.asString([ - "module.exports = __webpack_require__;", + `module.exports = ${RuntimeGlobals.require};`, `${RuntimeGlobals.externalInstallChunk} = installChunk;` - ]) + ]) : "// no external install chunk", "", withHmr @@ -196,7 +227,7 @@ class ReadFileChunkLoadingRuntimeModule extends RuntimeModule { Template.indent([ `if(${RuntimeGlobals.hasOwnProperty}(updatedModules, moduleId)) {`, Template.indent([ - `currentUpdate[moduleId] = updatedModules[moduleId];`, + "currentUpdate[moduleId] = updatedModules[moduleId];", "if(updatedModulesList) updatedModulesList.push(moduleId);" ]), "}" @@ -233,7 +264,7 @@ class ReadFileChunkLoadingRuntimeModule extends RuntimeModule { /\$hmrInvalidateModuleHandlers\$/g, RuntimeGlobals.hmrInvalidateModuleHandlers ) - ]) + ]) : "// no HMR", "", withHmrManifest @@ -261,7 +292,7 @@ class ReadFileChunkLoadingRuntimeModule extends RuntimeModule { "});" ]), "}" - ]) + ]) : "// no HMR manifest" ]); } diff --git a/lib/node/ReadFileCompileAsyncWasmPlugin.js b/lib/node/ReadFileCompileAsyncWasmPlugin.js index c8967301598..61ab8ff0a19 100644 --- a/lib/node/ReadFileCompileAsyncWasmPlugin.js +++ b/lib/node/ReadFileCompileAsyncWasmPlugin.js @@ -5,13 +5,20 @@ "use strict"; +const { WEBASSEMBLY_MODULE_TYPE_ASYNC } = require("../ModuleTypeConstants"); const RuntimeGlobals = require("../RuntimeGlobals"); const Template = require("../Template"); -const AsyncWasmChunkLoadingRuntimeModule = require("../wasm-async/AsyncWasmChunkLoadingRuntimeModule"); +const AsyncWasmLoadingRuntimeModule = require("../wasm-async/AsyncWasmLoadingRuntimeModule"); +/** @typedef {import("../Chunk")} Chunk */ /** @typedef {import("../Compiler")} Compiler */ class ReadFileCompileAsyncWasmPlugin { + constructor({ type = "async-node", import: useImport = false } = {}) { + this._type = type; + this._import = useImport; + } + /** * Apply the plugin * @param {Compiler} compiler the compiler instance @@ -22,36 +29,64 @@ class ReadFileCompileAsyncWasmPlugin { "ReadFileCompileAsyncWasmPlugin", compilation => { const globalWasmLoading = compilation.outputOptions.wasmLoading; + /** + * @param {Chunk} chunk chunk + * @returns {boolean} true, if wasm loading is enabled for the chunk + */ const isEnabledForChunk = chunk => { const options = chunk.getEntryOptions(); const wasmLoading = - (options && options.wasmLoading) || globalWasmLoading; - return wasmLoading === "async-node"; + options && options.wasmLoading !== undefined + ? options.wasmLoading + : globalWasmLoading; + return wasmLoading === this._type; }; - const generateLoadBinaryCode = path => - Template.asString([ - "new Promise(function (resolve, reject) {", - Template.indent([ - "var { readFile } = require('fs');", - "var { join } = require('path');", - "", - "try {", - Template.indent([ - `readFile(join(__dirname, ${path}), function(err, buffer){`, + const { importMetaName } = compilation.outputOptions; + /** + * @type {(path: string) => string} + */ + const generateLoadBinaryCode = this._import + ? path => + Template.asString([ + "Promise.all([import('fs'), import('url')]).then(([{ readFile }, { URL }]) => new Promise((resolve, reject) => {", Template.indent([ - "if (err) return reject(err);", - "", - "// Fake fetch response", - "resolve({", - Template.indent(["arrayBuffer() { return buffer; }"]), + `readFile(new URL(${path}, ${importMetaName}.url), (err, buffer) => {`, + Template.indent([ + "if (err) return reject(err);", + "", + "// Fake fetch response", + "resolve({", + Template.indent(["arrayBuffer() { return buffer; }"]), + "});" + ]), "});" ]), - "});" - ]), - "} catch (err) { reject(err); }" - ]), - "})" - ]); + "}))" + ]) + : path => + Template.asString([ + "new Promise(function (resolve, reject) {", + Template.indent([ + "try {", + Template.indent([ + "var { readFile } = require('fs');", + "var { join } = require('path');", + "", + `readFile(join(__dirname, ${path}), function(err, buffer){`, + Template.indent([ + "if (err) return reject(err);", + "", + "// Fake fetch response", + "resolve({", + Template.indent(["arrayBuffer() { return buffer; }"]), + "});" + ]), + "});" + ]), + "} catch (err) { reject(err); }" + ]), + "})" + ]); compilation.hooks.runtimeRequirementInTree .for(RuntimeGlobals.instantiateWasm) @@ -61,7 +96,7 @@ class ReadFileCompileAsyncWasmPlugin { if ( !chunkGraph.hasModuleInGraph( chunk, - m => m.type === "webassembly/async" + m => m.type === WEBASSEMBLY_MODULE_TYPE_ASYNC ) ) { return; @@ -69,7 +104,7 @@ class ReadFileCompileAsyncWasmPlugin { set.add(RuntimeGlobals.publicPath); compilation.addRuntimeModule( chunk, - new AsyncWasmChunkLoadingRuntimeModule({ + new AsyncWasmLoadingRuntimeModule({ generateLoadBinaryCode, supportsStreaming: false }) diff --git a/lib/node/ReadFileCompileWasmPlugin.js b/lib/node/ReadFileCompileWasmPlugin.js index aceb8a0d462..0a463994419 100644 --- a/lib/node/ReadFileCompileWasmPlugin.js +++ b/lib/node/ReadFileCompileWasmPlugin.js @@ -5,17 +5,27 @@ "use strict"; +const { WEBASSEMBLY_MODULE_TYPE_SYNC } = require("../ModuleTypeConstants"); const RuntimeGlobals = require("../RuntimeGlobals"); const Template = require("../Template"); const WasmChunkLoadingRuntimeModule = require("../wasm-sync/WasmChunkLoadingRuntimeModule"); +/** @typedef {import("../Chunk")} Chunk */ /** @typedef {import("../Compiler")} Compiler */ +/** + * @typedef {object} ReadFileCompileWasmPluginOptions + * @property {boolean} [mangleImports] mangle imports + */ + // TODO webpack 6 remove class ReadFileCompileWasmPlugin { - constructor(options) { - this.options = options || {}; + /** + * @param {ReadFileCompileWasmPluginOptions} [options] options object + */ + constructor(options = {}) { + this.options = options; } /** @@ -28,12 +38,22 @@ class ReadFileCompileWasmPlugin { "ReadFileCompileWasmPlugin", compilation => { const globalWasmLoading = compilation.outputOptions.wasmLoading; + /** + * @param {Chunk} chunk chunk + * @returns {boolean} true, when wasm loading is enabled for the chunk + */ const isEnabledForChunk = chunk => { const options = chunk.getEntryOptions(); const wasmLoading = - (options && options.wasmLoading) || globalWasmLoading; + options && options.wasmLoading !== undefined + ? options.wasmLoading + : globalWasmLoading; return wasmLoading === "async-node"; }; + /** + * @param {string} path path to wasm file + * @returns {string} generated code to load the wasm file + */ const generateLoadBinaryCode = path => Template.asString([ "new Promise(function (resolve, reject) {", @@ -67,7 +87,7 @@ class ReadFileCompileWasmPlugin { if ( !chunkGraph.hasModuleInGraph( chunk, - m => m.type === "webassembly/sync" + m => m.type === WEBASSEMBLY_MODULE_TYPE_SYNC ) ) { return; @@ -78,7 +98,8 @@ class ReadFileCompileWasmPlugin { new WasmChunkLoadingRuntimeModule({ generateLoadBinaryCode, supportsStreaming: false, - mangleImports: this.options.mangleImports + mangleImports: this.options.mangleImports, + runtimeRequirements: set }) ); }); diff --git a/lib/node/RequireChunkLoadingRuntimeModule.js b/lib/node/RequireChunkLoadingRuntimeModule.js index 2e7ca9213f8..1d4959459d5 100644 --- a/lib/node/RequireChunkLoadingRuntimeModule.js +++ b/lib/node/RequireChunkLoadingRuntimeModule.js @@ -15,18 +15,47 @@ const { getInitialChunkIds } = require("../javascript/StartupHelpers"); const compileBooleanMatcher = require("../util/compileBooleanMatcher"); const { getUndoPath } = require("../util/identifier"); +/** @typedef {import("../Chunk")} Chunk */ +/** @typedef {import("../ChunkGraph")} ChunkGraph */ +/** @typedef {import("../Compilation")} Compilation */ +/** @typedef {import("../Module").ReadOnlyRuntimeRequirements} ReadOnlyRuntimeRequirements */ + class RequireChunkLoadingRuntimeModule extends RuntimeModule { + /** + * @param {ReadOnlyRuntimeRequirements} runtimeRequirements runtime requirements + */ constructor(runtimeRequirements) { super("require chunk loading", RuntimeModule.STAGE_ATTACH); this.runtimeRequirements = runtimeRequirements; } /** - * @returns {string} runtime code + * @private + * @param {Chunk} chunk chunk + * @param {string} rootOutputDir root output directory + * @returns {string} generated code + */ + _generateBaseUri(chunk, rootOutputDir) { + const options = chunk.getEntryOptions(); + if (options && options.baseUri) { + return `${RuntimeGlobals.baseURI} = ${JSON.stringify(options.baseUri)};`; + } + + return `${RuntimeGlobals.baseURI} = require("url").pathToFileURL(${ + rootOutputDir !== "./" + ? `__dirname + ${JSON.stringify(`/${rootOutputDir}`)}` + : "__filename" + });`; + } + + /** + * @returns {string | null} runtime code */ generate() { - const { chunk } = this; - const { chunkGraph, runtimeTemplate } = this.compilation; + const compilation = /** @type {Compilation} */ (this.compilation); + const chunkGraph = /** @type {ChunkGraph} */ (this.chunkGraph); + const chunk = /** @type {Chunk} */ (this.chunk); + const { runtimeTemplate } = compilation; const fn = RuntimeGlobals.ensureChunkHandlers; const withBaseURI = this.runtimeRequirements.has(RuntimeGlobals.baseURI); const withExternalInstallChunk = this.runtimeRequirements.has( @@ -46,10 +75,10 @@ class RequireChunkLoadingRuntimeModule extends RuntimeModule { ); const conditionMap = chunkGraph.getChunkConditionMap(chunk, chunkHasJs); const hasJsMatcher = compileBooleanMatcher(conditionMap); - const initialChunkIds = getInitialChunkIds(chunk, chunkGraph); + const initialChunkIds = getInitialChunkIds(chunk, chunkGraph, chunkHasJs); - const outputName = this.compilation.getPath( - getChunkFilenameTemplate(chunk, this.compilation.outputOptions), + const outputName = compilation.getPath( + getChunkFilenameTemplate(chunk, compilation.outputOptions), { chunk, contentHashType: "javascript" @@ -57,24 +86,24 @@ class RequireChunkLoadingRuntimeModule extends RuntimeModule { ); const rootOutputDir = getUndoPath( outputName, - this.compilation.outputOptions.path, + /** @type {string} */ (compilation.outputOptions.path), true ); + const stateExpression = withHmr + ? `${RuntimeGlobals.hmrRuntimeStatePrefix}_require` + : undefined; + return Template.asString([ withBaseURI - ? Template.asString([ - `${RuntimeGlobals.baseURI} = require("url").pathToFileURL(${ - rootOutputDir !== "./" - ? `__dirname + ${JSON.stringify("/" + rootOutputDir)}` - : "__filename" - });` - ]) + ? this._generateBaseUri(chunk, rootOutputDir) : "// no baseURI", "", "// object to store loaded chunks", '// "1" means "loaded", otherwise not loaded yet', - "var installedChunks = {", + `var installedChunks = ${ + stateExpression ? `${stateExpression} = ${stateExpression} || ` : "" + }{`, Template.indent( Array.from(initialChunkIds, id => `${JSON.stringify(id)}: 1`).join( ",\n" @@ -85,10 +114,10 @@ class RequireChunkLoadingRuntimeModule extends RuntimeModule { withOnChunkLoad ? `${ RuntimeGlobals.onChunksLoaded - }.require = ${runtimeTemplate.returningFunction( + }.require = ${runtimeTemplate.returningFunction( "installedChunks[chunkId]", "chunkId" - )};` + )};` : "// no on chunks loaded", "", withLoading || withExternalInstallChunk @@ -103,11 +132,11 @@ class RequireChunkLoadingRuntimeModule extends RuntimeModule { "}" ]), "}", - `if(runtime) runtime(__webpack_require__);`, + `if(runtime) runtime(${RuntimeGlobals.require});`, "for(var i = 0; i < chunkIds.length; i++)", Template.indent("installedChunks[chunkIds[i]] = 1;"), withOnChunkLoad ? `${RuntimeGlobals.onChunksLoaded}();` : "" - ])};` + ])};` : "// no chunk install function needed", "", withLoading @@ -134,17 +163,17 @@ class RequireChunkLoadingRuntimeModule extends RuntimeModule { "" ]), "}" - ] + ] : "installedChunks[chunkId] = 1;" )};` - ]) + ]) : "// no chunk loading", "", withExternalInstallChunk ? Template.asString([ - "module.exports = __webpack_require__;", + `module.exports = ${RuntimeGlobals.require};`, `${RuntimeGlobals.externalInstallChunk} = installChunk;` - ]) + ]) : "// no external install chunk", "", withHmr @@ -160,7 +189,7 @@ class RequireChunkLoadingRuntimeModule extends RuntimeModule { Template.indent([ `if(${RuntimeGlobals.hasOwnProperty}(updatedModules, moduleId)) {`, Template.indent([ - `currentUpdate[moduleId] = updatedModules[moduleId];`, + "currentUpdate[moduleId] = updatedModules[moduleId];", "if(updatedModulesList) updatedModulesList.push(moduleId);" ]), "}" @@ -192,7 +221,7 @@ class RequireChunkLoadingRuntimeModule extends RuntimeModule { /\$hmrInvalidateModuleHandlers\$/g, RuntimeGlobals.hmrInvalidateModuleHandlers ) - ]) + ]) : "// no HMR", "", withHmrManifest @@ -205,10 +234,10 @@ class RequireChunkLoadingRuntimeModule extends RuntimeModule { RuntimeGlobals.getUpdateManifestFilename }());` ]), - '}).catch(function(err) { if(err.code !== "MODULE_NOT_FOUND") throw err; });' + "})['catch'](function(err) { if(err.code !== 'MODULE_NOT_FOUND') throw err; });" ]), "}" - ]) + ]) : "// no HMR manifest" ]); } diff --git a/lib/node/nodeConsole.js b/lib/node/nodeConsole.js index 265a0ef47ec..5f3a162726a 100644 --- a/lib/node/nodeConsole.js +++ b/lib/node/nodeConsole.js @@ -8,127 +8,153 @@ const util = require("util"); const truncateArgs = require("../logging/truncateArgs"); -const tty = process.stderr.isTTY && process.env.TERM !== "dumb"; +/** @typedef {import("../logging/createConsoleLogger").LoggerConsole} LoggerConsole */ -let currentStatusMessage = undefined; -let hasStatusMessage = false; -let currentIndent = ""; -let currentCollapsed = 0; +/** + * @param {object} options options + * @param {boolean=} options.colors colors + * @param {boolean=} options.appendOnly append only + * @param {NodeJS.WritableStream} options.stream stream + * @returns {LoggerConsole} logger function + */ +module.exports = ({ colors, appendOnly, stream }) => { + /** @type {string[] | undefined} */ + let currentStatusMessage; + let hasStatusMessage = false; + let currentIndent = ""; + let currentCollapsed = 0; -const indent = (str, prefix, colorPrefix, colorSuffix) => { - if (str === "") return str; - prefix = currentIndent + prefix; - if (tty) { - return ( - prefix + - colorPrefix + - str.replace(/\n/g, colorSuffix + "\n" + prefix + colorPrefix) + - colorSuffix - ); - } else { - return prefix + str.replace(/\n/g, "\n" + prefix); - } -}; + /** + * @param {string} str string + * @param {string} prefix prefix + * @param {string} colorPrefix color prefix + * @param {string} colorSuffix color suffix + * @returns {string} indented string + */ + const indent = (str, prefix, colorPrefix, colorSuffix) => { + if (str === "") return str; + prefix = currentIndent + prefix; + if (colors) { + return ( + prefix + + colorPrefix + + str.replace(/\n/g, `${colorSuffix}\n${prefix}${colorPrefix}`) + + colorSuffix + ); + } -const clearStatusMessage = () => { - if (hasStatusMessage) { - process.stderr.write("\x1b[2K\r"); - hasStatusMessage = false; - } -}; + return prefix + str.replace(/\n/g, `\n${prefix}`); + }; -const writeStatusMessage = () => { - if (!currentStatusMessage) return; - const l = process.stderr.columns; - const args = l - ? truncateArgs(currentStatusMessage, l - 1) - : currentStatusMessage; - const str = args.join(" "); - const coloredStr = `\u001b[1m${str}\u001b[39m\u001b[22m`; - process.stderr.write(`\x1b[2K\r${coloredStr}`); - hasStatusMessage = true; -}; + const clearStatusMessage = () => { + if (hasStatusMessage) { + stream.write("\u001B[2K\r"); + hasStatusMessage = false; + } + }; -const writeColored = (prefix, colorPrefix, colorSuffix) => { - return (...args) => { - if (currentCollapsed > 0) return; - clearStatusMessage(); - const str = indent(util.format(...args), prefix, colorPrefix, colorSuffix); - process.stderr.write(str + "\n"); - writeStatusMessage(); + const writeStatusMessage = () => { + if (!currentStatusMessage) return; + const l = /** @type {TODO} */ (stream).columns || 40; + const args = truncateArgs(currentStatusMessage, l - 1); + const str = args.join(" "); + const coloredStr = `\u001B[1m${str}\u001B[39m\u001B[22m`; + stream.write(`\u001B[2K\r${coloredStr}`); + hasStatusMessage = true; }; -}; -const writeGroupMessage = writeColored( - "<-> ", - "\u001b[1m\u001b[36m", - "\u001b[39m\u001b[22m" -); + /** + * @param {string} prefix prefix + * @param {string} colorPrefix color prefix + * @param {string} colorSuffix color suffix + * @returns {(function(...any[]): void)} function to write with colors + */ + const writeColored = + (prefix, colorPrefix, colorSuffix) => + (...args) => { + if (currentCollapsed > 0) return; + clearStatusMessage(); + const str = indent( + util.format(...args), + prefix, + colorPrefix, + colorSuffix + ); + stream.write(`${str}\n`); + writeStatusMessage(); + }; -const writeGroupCollapsedMessage = writeColored( - "<+> ", - "\u001b[1m\u001b[36m", - "\u001b[39m\u001b[22m" -); + const writeGroupMessage = writeColored( + "<-> ", + "\u001B[1m\u001B[36m", + "\u001B[39m\u001B[22m" + ); -module.exports = { - log: writeColored(" ", "\u001b[1m", "\u001b[22m"), - debug: writeColored(" ", "", ""), - trace: writeColored(" ", "", ""), - info: writeColored(" ", "\u001b[1m\u001b[32m", "\u001b[39m\u001b[22m"), - warn: writeColored(" ", "\u001b[1m\u001b[33m", "\u001b[39m\u001b[22m"), - error: writeColored(" ", "\u001b[1m\u001b[31m", "\u001b[39m\u001b[22m"), - logTime: writeColored(" ", "\u001b[1m\u001b[35m", "\u001b[39m\u001b[22m"), - group: (...args) => { - writeGroupMessage(...args); - if (currentCollapsed > 0) { + const writeGroupCollapsedMessage = writeColored( + "<+> ", + "\u001B[1m\u001B[36m", + "\u001B[39m\u001B[22m" + ); + + return { + log: writeColored(" ", "\u001B[1m", "\u001B[22m"), + debug: writeColored(" ", "", ""), + trace: writeColored(" ", "", ""), + info: writeColored(" ", "\u001B[1m\u001B[32m", "\u001B[39m\u001B[22m"), + warn: writeColored(" ", "\u001B[1m\u001B[33m", "\u001B[39m\u001B[22m"), + error: writeColored(" ", "\u001B[1m\u001B[31m", "\u001B[39m\u001B[22m"), + logTime: writeColored( + " ", + "\u001B[1m\u001B[35m", + "\u001B[39m\u001B[22m" + ), + group: (...args) => { + writeGroupMessage(...args); + if (currentCollapsed > 0) { + currentCollapsed++; + } else { + currentIndent += " "; + } + }, + groupCollapsed: (...args) => { + writeGroupCollapsedMessage(...args); currentCollapsed++; - } else { - currentIndent += " "; - } - }, - groupCollapsed: (...args) => { - writeGroupCollapsedMessage(...args); - currentCollapsed++; - }, - groupEnd: () => { - if (currentCollapsed > 0) currentCollapsed--; - else if (currentIndent.length >= 2) - currentIndent = currentIndent.slice(0, currentIndent.length - 2); - }, - // eslint-disable-next-line node/no-unsupported-features/node-builtins - profile: console.profile && (name => console.profile(name)), - // eslint-disable-next-line node/no-unsupported-features/node-builtins - profileEnd: console.profileEnd && (name => console.profileEnd(name)), - clear: - tty && - // eslint-disable-next-line node/no-unsupported-features/node-builtins - console.clear && - (() => { - clearStatusMessage(); - // eslint-disable-next-line node/no-unsupported-features/node-builtins - console.clear(); - writeStatusMessage(); - }), - status: tty - ? (name, ...args) => { - args = args.filter(Boolean); - if (name === undefined && args.length === 0) { - clearStatusMessage(); - currentStatusMessage = undefined; - } else if ( - typeof name === "string" && - name.startsWith("[webpack.Progress] ") - ) { - currentStatusMessage = [name.slice(19), ...args]; - writeStatusMessage(); - } else if (name === "[webpack.Progress]") { - currentStatusMessage = [...args]; - writeStatusMessage(); - } else { - currentStatusMessage = [name, ...args]; - writeStatusMessage(); + }, + groupEnd: () => { + if (currentCollapsed > 0) currentCollapsed--; + else if (currentIndent.length >= 2) + currentIndent = currentIndent.slice(0, -2); + }, + profile: console.profile && (name => console.profile(name)), + profileEnd: console.profileEnd && (name => console.profileEnd(name)), + clear: + !appendOnly && + console.clear && + (() => { + clearStatusMessage(); + console.clear(); + writeStatusMessage(); + }), + status: appendOnly + ? writeColored(" ", "", "") + : (name, ...args) => { + args = args.filter(Boolean); + if (name === undefined && args.length === 0) { + clearStatusMessage(); + currentStatusMessage = undefined; + } else if ( + typeof name === "string" && + name.startsWith("[webpack.Progress] ") + ) { + currentStatusMessage = [name.slice(19), ...args]; + writeStatusMessage(); + } else if (name === "[webpack.Progress]") { + currentStatusMessage = [...args]; + writeStatusMessage(); + } else { + currentStatusMessage = [name, ...args]; + writeStatusMessage(); + } } - } - : writeColored(" ", "", "") + }; }; diff --git a/lib/optimize/AggressiveMergingPlugin.js b/lib/optimize/AggressiveMergingPlugin.js index bc1b37bf655..e0d766a7db0 100644 --- a/lib/optimize/AggressiveMergingPlugin.js +++ b/lib/optimize/AggressiveMergingPlugin.js @@ -10,7 +10,15 @@ const { STAGE_ADVANCED } = require("../OptimizationStages"); /** @typedef {import("../Chunk")} Chunk */ /** @typedef {import("../Compiler")} Compiler */ +/** + * @typedef {object} AggressiveMergingPluginOptions + * @property {number=} minSizeReduce minimal size reduction to trigger merging + */ + class AggressiveMergingPlugin { + /** + * @param {AggressiveMergingPluginOptions=} [options] options object + */ constructor(options) { if ( (options !== undefined && typeof options !== "object") || @@ -43,7 +51,7 @@ class AggressiveMergingPlugin { chunks => { const chunkGraph = compilation.chunkGraph; /** @type {{a: Chunk, b: Chunk, improvement: number}[]} */ - let combinations = []; + const combinations = []; for (const a of chunks) { if (a.canBeInitial()) continue; for (const b of chunks) { @@ -70,9 +78,7 @@ class AggressiveMergingPlugin { } } - combinations.sort((a, b) => { - return b.improvement - a.improvement; - }); + combinations.sort((a, b) => b.improvement - a.improvement); const pair = combinations[0]; diff --git a/lib/optimize/AggressiveSplittingPlugin.js b/lib/optimize/AggressiveSplittingPlugin.js index 54365986066..457f61d212a 100644 --- a/lib/optimize/AggressiveSplittingPlugin.js +++ b/lib/optimize/AggressiveSplittingPlugin.js @@ -5,14 +5,13 @@ "use strict"; -const { validate } = require("schema-utils"); -const schema = require("../../schemas/plugins/optimize/AggressiveSplittingPlugin.json"); const { STAGE_ADVANCED } = require("../OptimizationStages"); const { intersect } = require("../util/SetHelpers"); const { compareModulesByIdentifier, compareChunks } = require("../util/comparators"); +const createSchemaValidation = require("../util/create-schema-validation"); const identifierUtils = require("../util/identifier"); /** @typedef {import("../../declarations/plugins/optimize/AggressiveSplittingPlugin").AggressiveSplittingPluginOptions} AggressiveSplittingPluginOptions */ @@ -21,11 +20,25 @@ const identifierUtils = require("../util/identifier"); /** @typedef {import("../Compiler")} Compiler */ /** @typedef {import("../Module")} Module */ -const moveModuleBetween = (chunkGraph, oldChunk, newChunk) => { - return module => { - chunkGraph.disconnectChunkAndModule(oldChunk, module); - chunkGraph.connectChunkAndModule(newChunk, module); - }; +const validate = createSchemaValidation( + require("../../schemas/plugins/optimize/AggressiveSplittingPlugin.check.js"), + () => + require("../../schemas/plugins/optimize/AggressiveSplittingPlugin.json"), + { + name: "Aggressive Splitting Plugin", + baseDataPath: "options" + } +); + +/** + * @param {ChunkGraph} chunkGraph the chunk graph + * @param {Chunk} oldChunk the old chunk + * @param {Chunk} newChunk the new chunk + * @returns {(module: Module) => void} function to move module between chunks + */ +const moveModuleBetween = (chunkGraph, oldChunk, newChunk) => module => { + chunkGraph.disconnectChunkAndModule(oldChunk, module); + chunkGraph.connectChunkAndModule(newChunk, module); }; /** @@ -33,11 +46,8 @@ const moveModuleBetween = (chunkGraph, oldChunk, newChunk) => { * @param {Chunk} chunk the chunk * @returns {function(Module): boolean} filter for entry module */ -const isNotAEntryModule = (chunkGraph, chunk) => { - return module => { - return !chunkGraph.isEntryModuleInChunk(module, chunk); - }; -}; +const isNotAEntryModule = (chunkGraph, chunk) => module => + !chunkGraph.isEntryModuleInChunk(module, chunk); /** @type {WeakSet} */ const recordedChunks = new WeakSet(); @@ -47,10 +57,7 @@ class AggressiveSplittingPlugin { * @param {AggressiveSplittingPluginOptions=} options options object */ constructor(options = {}) { - validate(schema, options, { - name: "Aggressive Splitting Plugin", - baseDataPath: "options" - }); + validate(options); this.options = options; if (typeof this.options.minSize !== "number") { @@ -86,7 +93,9 @@ class AggressiveSplittingPlugin { compilation => { let needAdditionalSeal = false; let newSplits; + /** @type {Set} */ let fromAggressiveSplittingSet; + /** @type {Map} */ let chunkSplitDataMap; compilation.hooks.optimize.tap("AggressiveSplittingPlugin", () => { newSplits = []; @@ -103,10 +112,11 @@ class AggressiveSplittingPlugin { // Precompute stuff const nameToModuleMap = new Map(); const moduleToNameMap = new Map(); - const makePathsRelative = identifierUtils.makePathsRelative.bindContextCache( - compiler.context, - compiler.root - ); + const makePathsRelative = + identifierUtils.makePathsRelative.bindContextCache( + compiler.context, + compiler.root + ); for (const m of compilation.modules) { const name = makePathsRelative(m.identifier()); nameToModuleMap.set(name, m); @@ -126,8 +136,8 @@ class AggressiveSplittingPlugin { ? recordedSplits.concat(newSplits) : recordedSplits; - const minSize = this.options.minSize; - const maxSize = this.options.maxSize; + const minSize = /** @type {number} */ (this.options.minSize); + const maxSize = /** @type {number} */ (this.options.maxSize); const applySplit = splitData => { // Cannot split if id is already taken @@ -176,9 +186,9 @@ class AggressiveSplittingPlugin { const newChunk = compilation.addChunk(); newChunk.chunkReason = "aggressive splitted"; for (const chunk of selectedChunks) { - selectedModules.forEach( - moveModuleBetween(chunkGraph, chunk, newChunk) - ); + for (const module of selectedModules) { + moveModuleBetween(chunkGraph, chunk, newChunk)(module); + } chunk.split(newChunk); chunk.name = null; } @@ -262,12 +272,14 @@ class AggressiveSplittingPlugin { // We remove invalid splittings and try again for (const chunk of compilation.chunks) { const splitData = chunkSplitDataMap.get(chunk); - if (splitData !== undefined) { - if (splitData.hash && chunk.hash !== splitData.hash) { - // Split was successful, but hash doesn't equal - // We can throw away the split since it's useless now - invalidSplits.add(splitData); - } + if ( + splitData !== undefined && + splitData.hash && + chunk.hash !== splitData.hash + ) { + // Split was successful, but hash doesn't equal + // We can throw away the split since it's useless now + invalidSplits.add(splitData); } } diff --git a/lib/optimize/ConcatenatedModule.js b/lib/optimize/ConcatenatedModule.js index 5bda109e9a1..5321875cb58 100644 --- a/lib/optimize/ConcatenatedModule.js +++ b/lib/optimize/ConcatenatedModule.js @@ -6,6 +6,8 @@ "use strict"; const eslintScope = require("eslint-scope"); +const Referencer = require("eslint-scope/lib/referencer"); +const { SyncBailHook } = require("tapable"); const { CachedSource, ConcatSource, @@ -14,17 +16,20 @@ const { const ConcatenationScope = require("../ConcatenationScope"); const { UsageState } = require("../ExportsInfo"); const Module = require("../Module"); +const { JAVASCRIPT_MODULE_TYPE_ESM } = require("../ModuleTypeConstants"); const RuntimeGlobals = require("../RuntimeGlobals"); const Template = require("../Template"); const HarmonyImportDependency = require("../dependencies/HarmonyImportDependency"); const JavascriptParser = require("../javascript/JavascriptParser"); const { equals } = require("../util/ArrayHelpers"); const LazySet = require("../util/LazySet"); -const { concatComparators, keepOriginalOrder } = require("../util/comparators"); +const { concatComparators } = require("../util/comparators"); const createHash = require("../util/createHash"); -const contextify = require("../util/identifier").contextify; +const { makePathsRelative } = require("../util/identifier"); const makeSerializable = require("../util/makeSerializable"); +const { getAllReferences, getPathInAst } = require("../util/mergeScope"); const propertyAccess = require("../util/propertyAccess"); +const { propertyName } = require("../util/propertyName"); const { filterRuntime, intersectRuntime, @@ -34,32 +39,63 @@ const { subtractRuntimeCondition } = require("../util/runtime"); +/** @typedef {import("eslint-scope").Reference} Reference */ /** @typedef {import("eslint-scope").Scope} Scope */ +/** @typedef {import("eslint-scope").Variable} Variable */ /** @typedef {import("webpack-sources").Source} Source */ /** @typedef {import("../../declarations/WebpackOptions").WebpackOptionsNormalized} WebpackOptions */ /** @typedef {import("../ChunkGraph")} ChunkGraph */ +/** @typedef {import("../CodeGenerationResults")} CodeGenerationResults */ /** @typedef {import("../Compilation")} Compilation */ /** @typedef {import("../Dependency")} Dependency */ /** @typedef {import("../Dependency").UpdateHashContext} UpdateHashContext */ /** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */ /** @typedef {import("../DependencyTemplates")} DependencyTemplates */ /** @typedef {import("../ExportsInfo").ExportInfo} ExportInfo */ +/** @typedef {import("../Module").BuildInfo} BuildInfo */ +/** @typedef {import("../Module").BuildMeta} BuildMeta */ /** @typedef {import("../Module").CodeGenerationContext} CodeGenerationContext */ /** @typedef {import("../Module").CodeGenerationResult} CodeGenerationResult */ /** @typedef {import("../Module").LibIdentOptions} LibIdentOptions */ +/** @typedef {import("../Module").ReadOnlyRuntimeRequirements} ReadOnlyRuntimeRequirements */ +/** @typedef {import("../Module").SourceTypes} SourceTypes */ /** @typedef {import("../ModuleGraph")} ModuleGraph */ /** @typedef {import("../ModuleGraphConnection")} ModuleGraphConnection */ /** @typedef {import("../ModuleGraphConnection").ConnectionState} ConnectionState */ +/** @typedef {import("../ModuleParseError")} ModuleParseError */ /** @typedef {import("../RequestShortener")} RequestShortener */ /** @typedef {import("../ResolverFactory").ResolverWithOptions} ResolverWithOptions */ /** @typedef {import("../RuntimeTemplate")} RuntimeTemplate */ /** @typedef {import("../WebpackError")} WebpackError */ +/** @typedef {import("../javascript/JavascriptModulesPlugin").ChunkRenderContext} ChunkRenderContext */ +/** @typedef {import("../javascript/JavascriptParser").Program} Program */ +/** @typedef {import("../javascript/JavascriptParser").Range} Range */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */ /** @typedef {import("../util/Hash")} Hash */ +/** @typedef {typeof import("../util/Hash")} HashConstructor */ /** @typedef {import("../util/fs").InputFileSystem} InputFileSystem */ /** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */ /** - * @typedef {Object} ReexportInfo + * @template T + * @typedef {import("../InitFragment")} InitFragment + */ + +/** + * @template T + * @typedef {import("../util/comparators").Comparator} Comparator + */ + +// fix eslint-scope to support class properties correctly +// cspell:word Referencer +const ReferencerClass = /** @type {any} */ (Referencer); +if (!ReferencerClass.prototype.PropertyDefinition) { + ReferencerClass.prototype.PropertyDefinition = + ReferencerClass.prototype.Property; +} + +/** + * @typedef {object} ReexportInfo * @property {Module} module * @property {string[]} export */ @@ -67,7 +103,7 @@ const { /** @typedef {RawBinding | SymbolBinding} Binding */ /** - * @typedef {Object} RawBinding + * @typedef {object} RawBinding * @property {ModuleInfo} info * @property {string} rawName * @property {string=} comment @@ -76,7 +112,7 @@ const { */ /** - * @typedef {Object} SymbolBinding + * @typedef {object} SymbolBinding * @property {ConcatenatedModuleInfo} info * @property {string} name * @property {string=} comment @@ -88,51 +124,54 @@ const { /** @typedef {ConcatenatedModuleInfo | ExternalModuleInfo | ReferenceToModuleInfo } ModuleInfoOrReference */ /** - * @typedef {Object} ConcatenatedModuleInfo + * @typedef {object} ConcatenatedModuleInfo * @property {"concatenated"} type * @property {Module} module * @property {number} index - * @property {Object} ast - * @property {Source} internalSource + * @property {Program | undefined} ast + * @property {Source | undefined} internalSource * @property {ReplaceSource} source - * @property {Iterable} runtimeRequirements - * @property {Scope} globalScope - * @property {Scope} moduleScope + * @property {InitFragment[]=} chunkInitFragments + * @property {ReadOnlyRuntimeRequirements | undefined} runtimeRequirements + * @property {Scope | undefined} globalScope + * @property {Scope | undefined} moduleScope * @property {Map} internalNames - * @property {Map} exportMap - * @property {Map} rawExportMap + * @property {Map | undefined} exportMap + * @property {Map | undefined} rawExportMap * @property {string=} namespaceExportSymbol - * @property {string} namespaceObjectName + * @property {string | undefined} namespaceObjectName * @property {boolean} interopNamespaceObjectUsed - * @property {string} interopNamespaceObjectName + * @property {string | undefined} interopNamespaceObjectName * @property {boolean} interopNamespaceObject2Used - * @property {string} interopNamespaceObject2Name + * @property {string | undefined} interopNamespaceObject2Name * @property {boolean} interopDefaultAccessUsed - * @property {string} interopDefaultAccessName + * @property {string | undefined} interopDefaultAccessName */ /** - * @typedef {Object} ExternalModuleInfo + * @typedef {object} ExternalModuleInfo * @property {"external"} type * @property {Module} module * @property {RuntimeSpec | boolean} runtimeCondition * @property {number} index - * @property {string} name + * @property {string | undefined} name * @property {boolean} interopNamespaceObjectUsed - * @property {string} interopNamespaceObjectName + * @property {string | undefined} interopNamespaceObjectName * @property {boolean} interopNamespaceObject2Used - * @property {string} interopNamespaceObject2Name + * @property {string | undefined} interopNamespaceObject2Name * @property {boolean} interopDefaultAccessUsed - * @property {string} interopDefaultAccessName + * @property {string | undefined} interopDefaultAccessName */ /** - * @typedef {Object} ReferenceToModuleInfo + * @typedef {object} ReferenceToModuleInfo * @property {"reference"} type * @property {RuntimeSpec | boolean} runtimeCondition * @property {ConcatenatedModuleInfo | ExternalModuleInfo} target */ +/** @typedef {Set} UsedNames */ + const RESERVED_NAMES = new Set( [ // internal names (should always be renamed) @@ -171,24 +210,45 @@ const RESERVED_NAMES = new Set( .split(",") ); -const bySourceOrder = (a, b) => { - const aOrder = a.sourceOrder; - const bOrder = b.sourceOrder; - if (isNaN(aOrder)) { - if (!isNaN(bOrder)) { +/** + * @template T + * @param {string} property property + * @param {function(T[keyof T], T[keyof T]): 0 | 1 | -1} comparator comparator + * @returns {Comparator} comparator + */ +const createComparator = (property, comparator) => (a, b) => + comparator( + a[/** @type {keyof T} */ (property)], + b[/** @type {keyof T} */ (property)] + ); + +/** + * @param {number} a a + * @param {number} b b + * @returns {0 | 1 | -1} result + */ +const compareNumbers = (a, b) => { + if (Number.isNaN(a)) { + if (!Number.isNaN(b)) { return 1; } } else { - if (isNaN(bOrder)) { + if (Number.isNaN(b)) { return -1; } - if (aOrder !== bOrder) { - return aOrder < bOrder ? -1 : 1; + if (a !== b) { + return a < b ? -1 : 1; } } return 0; }; +const bySourceOrder = createComparator("sourceOrder", compareNumbers); +const byRangeStart = createComparator("rangeStart", compareNumbers); +/** + * @param {Iterable} iterable iterable object + * @returns {string} joined iterable object + */ const joinIterableWithComma = iterable => { // This is more performant than Array.from().join(", ") // as it doesn't create an array @@ -206,7 +266,7 @@ const joinIterableWithComma = iterable => { }; /** - * @typedef {Object} ConcatenationEntry + * @typedef {object} ConcatenationEntry * @property {"concatenated" | "external"} type * @property {Module} module * @property {RuntimeSpec | boolean} runtimeCondition @@ -222,7 +282,7 @@ const joinIterableWithComma = iterable => { * @param {RuntimeTemplate} runtimeTemplate the runtime template * @param {Set} neededNamespaceObjects modules for which a namespace object should be generated * @param {boolean} asCall asCall - * @param {boolean} strictHarmonyModule strictHarmonyModule + * @param {boolean | undefined} strictHarmonyModule strictHarmonyModule * @param {boolean | undefined} asiSafe asiSafe * @param {Set} alreadyVisited alreadyVisited * @returns {Binding} the final variable @@ -251,7 +311,7 @@ const getFinalBinding = ( info.interopNamespaceObject2Used = true; return { info, - rawName: info.interopNamespaceObject2Name, + rawName: /** @type {string} */ (info.interopNamespaceObject2Name), ids: exportName, exportName }; @@ -259,7 +319,7 @@ const getFinalBinding = ( info.interopNamespaceObjectUsed = true; return { info, - rawName: info.interopNamespaceObjectName, + rawName: /** @type {string} */ (info.interopNamespaceObjectName), ids: exportName, exportName }; @@ -317,10 +377,10 @@ const getFinalBinding = ( const defaultExport = asCall ? `${info.interopDefaultAccessName}()` : asiSafe - ? `(${info.interopDefaultAccessName}())` - : asiSafe === false - ? `;(${info.interopDefaultAccessName}())` - : `${info.interopDefaultAccessName}.a`; + ? `(${info.interopDefaultAccessName}())` + : asiSafe === false + ? `;(${info.interopDefaultAccessName}())` + : `${info.interopDefaultAccessName}.a`; return { info, rawName: defaultExport, @@ -347,12 +407,21 @@ const getFinalBinding = ( neededNamespaceObjects.add(info); return { info, - rawName: info.namespaceObjectName, + rawName: + /** @type {NonNullable} */ + (info.namespaceObjectName), ids: exportName, exportName }; case "external": - return { info, rawName: info.name, ids: exportName, exportName }; + return { + info, + rawName: + /** @type {NonNullable} */ + (info.name), + ids: exportName, + exportName + }; } } const exportsInfo = moduleGraph.getExportsInfo(info.module); @@ -374,17 +443,16 @@ const getFinalBinding = ( neededNamespaceObjects.add(info); return { info, - rawName: info.namespaceObjectName, + rawName: /** @type {string} */ (info.namespaceObjectName), ids: exportName, exportName }; } const directExport = info.exportMap && info.exportMap.get(exportId); if (directExport) { - const usedName = /** @type {string[]} */ (exportsInfo.getUsedName( - exportName, - runtime - )); + const usedName = /** @type {string[]} */ ( + exportsInfo.getUsedName(exportName, runtime) + ); if (!usedName) { return { info, @@ -427,7 +495,7 @@ const getFinalBinding = ( const refInfo = moduleToInfoMap.get(reexport.module); return getFinalBinding( moduleGraph, - refInfo, + /** @type {ModuleInfo} */ (refInfo), reexport.export ? [...reexport.export, ...exportName.slice(1)] : exportName.slice(1), @@ -437,19 +505,19 @@ const getFinalBinding = ( runtimeTemplate, neededNamespaceObjects, asCall, - info.module.buildMeta.strictHarmonyModule, + /** @type {BuildMeta} */ + (info.module.buildMeta).strictHarmonyModule, asiSafe, alreadyVisited ); } if (info.namespaceExportSymbol) { - const usedName = /** @type {string[]} */ (exportsInfo.getUsedName( - exportName, - runtime - )); + const usedName = /** @type {string[]} */ ( + exportsInfo.getUsedName(exportName, runtime) + ); return { info, - rawName: info.namespaceObjectName, + rawName: /** @type {string} */ (info.namespaceObjectName), ids: usedName, exportName }; @@ -462,10 +530,9 @@ const getFinalBinding = ( } case "external": { - const used = /** @type {string[]} */ (exportsInfo.getUsedName( - exportName, - runtime - )); + const used = /** @type {string[]} */ ( + exportsInfo.getUsedName(exportName, runtime) + ); if (!used) { return { info, @@ -492,8 +559,8 @@ const getFinalBinding = ( * @param {RuntimeTemplate} runtimeTemplate the runtime template * @param {Set} neededNamespaceObjects modules for which a namespace object should be generated * @param {boolean} asCall asCall - * @param {boolean} callContext callContext - * @param {boolean} strictHarmonyModule strictHarmonyModule + * @param {boolean | undefined} callContext callContext + * @param {boolean | undefined} strictHarmonyModule strictHarmonyModule * @param {boolean | undefined} asiSafe asiSafe * @returns {string} the final name */ @@ -553,13 +620,19 @@ const getFinalName = ( return asiSafe ? `(0,${reference})` : asiSafe === false - ? `;(0,${reference})` - : `Object(${reference})`; + ? `;(0,${reference})` + : `/*#__PURE__*/Object(${reference})`; } return reference; } }; +/** + * @param {Scope | null} s scope + * @param {UsedNames} nameSet name set + * @param {TODO} scopeSet1 scope set 1 + * @param {TODO} scopeSet2 scope set 2 + */ const addScopeSymbols = (s, nameSet, scopeSet1, scopeSet2) => { let scope = s; while (scope) { @@ -573,96 +646,74 @@ const addScopeSymbols = (s, nameSet, scopeSet1, scopeSet2) => { } }; -const getAllReferences = variable => { - let set = variable.references; - // Look for inner scope variables too (like in class Foo { t() { Foo } }) - const identifiers = new Set(variable.identifiers); - for (const scope of variable.scope.childScopes) { - for (const innerVar of scope.variables) { - if (innerVar.identifiers.some(id => identifiers.has(id))) { - set = set.concat(innerVar.references); - break; - } - } - } - return set; -}; - -const getPathInAst = (ast, node) => { - if (ast === node) { - return []; - } - - const nr = node.range; - - const enterNode = n => { - if (!n) return undefined; - const r = n.range; - if (r) { - if (r[0] <= nr[0] && r[1] >= nr[1]) { - const path = getPathInAst(n, node); - if (path) { - path.push(n); - return path; - } - } - } - return undefined; - }; +const TYPES = new Set(["javascript"]); - if (Array.isArray(ast)) { - for (let i = 0; i < ast.length; i++) { - const enterResult = enterNode(ast[i]); - if (enterResult !== undefined) return enterResult; - } - } else if (ast && typeof ast === "object") { - const keys = Object.keys(ast); - for (let i = 0; i < keys.length; i++) { - const value = ast[keys[i]]; - if (Array.isArray(value)) { - const pathResult = getPathInAst(value, node); - if (pathResult !== undefined) return pathResult; - } else if (value && typeof value === "object") { - const enterResult = enterNode(value); - if (enterResult !== undefined) return enterResult; - } - } - } -}; +/** + * @typedef {object} ConcatenateModuleHooks + * @property {SyncBailHook<[Record], boolean>} exportsDefinitions + */ -const TYPES = new Set(["javascript"]); +/** @type {WeakMap} */ +const compilationHooksMap = new WeakMap(); class ConcatenatedModule extends Module { /** * @param {Module} rootModule the root module of the concatenation * @param {Set} modules all modules in the concatenation (including the root module) * @param {RuntimeSpec} runtime the runtime - * @param {Object=} associatedObjectForCache object for caching + * @param {Compilation} compilation the compilation + * @param {object=} associatedObjectForCache object for caching + * @param {string | HashConstructor=} hashFunction hash function to use * @returns {ConcatenatedModule} the module */ - static create(rootModule, modules, runtime, associatedObjectForCache) { + static create( + rootModule, + modules, + runtime, + compilation, + associatedObjectForCache, + hashFunction = "md4" + ) { const identifier = ConcatenatedModule._createIdentifier( rootModule, modules, - associatedObjectForCache + associatedObjectForCache, + hashFunction ); return new ConcatenatedModule({ identifier, rootModule, modules, - runtime + runtime, + compilation }); } /** - * @param {Object} options options + * @param {Compilation} compilation the compilation + * @returns {ConcatenateModuleHooks} the attached hooks + */ + static getCompilationHooks(compilation) { + let hooks = compilationHooksMap.get(compilation); + if (hooks === undefined) { + hooks = { + exportsDefinitions: new SyncBailHook(["definitions"]) + }; + compilationHooksMap.set(compilation, hooks); + } + return hooks; + } + + /** + * @param {object} options options * @param {string} options.identifier the identifier of the module * @param {Module=} options.rootModule the root module of the concatenation * @param {RuntimeSpec} options.runtime the selected runtime * @param {Set=} options.modules all concatenated modules + * @param {Compilation} options.compilation the compilation */ - constructor({ identifier, rootModule, modules, runtime }) { - super("javascript/esm", null, rootModule && rootModule.layer); + constructor({ identifier, rootModule, modules, runtime, compilation }) { + super(JAVASCRIPT_MODULE_TYPE_ESM, null, rootModule && rootModule.layer); // Info from Factory /** @type {string} */ @@ -673,6 +724,8 @@ class ConcatenatedModule extends Module { this._modules = modules; this._runtime = runtime; this.factoryMeta = rootModule && rootModule.factoryMeta; + /** @type {Compilation | undefined} */ + this.compilation = compilation; } /** @@ -687,7 +740,7 @@ class ConcatenatedModule extends Module { } /** - * @returns {Set} types available (do not mutate) + * @returns {SourceTypes} types available (do not mutate) */ getSourceTypes() { return TYPES; @@ -709,10 +762,9 @@ class ConcatenatedModule extends Module { * @returns {string} a user readable identifier of the module */ readableIdentifier(requestShortener) { - return ( - this.rootModule.readableIdentifier(requestShortener) + - ` + ${this._modules.size - 1} modules` - ); + return `${this.rootModule.readableIdentifier( + requestShortener + )} + ${this._modules.size - 1} modules`; } /** @@ -748,11 +800,14 @@ class ConcatenatedModule extends Module { */ build(options, compilation, resolver, fs, callback) { const { rootModule } = this; + const { moduleArgument, exportsArgument } = + /** @type {BuildInfo} */ + (rootModule.buildInfo); this.buildInfo = { strict: true, cacheable: true, - moduleArgument: rootModule.buildInfo.moduleArgument, - exportsArgument: rootModule.buildInfo.exportsArgument, + moduleArgument, + exportsArgument, fileDependencies: new LazySet(), contextDependencies: new LazySet(), missingDependencies: new LazySet(), @@ -765,7 +820,7 @@ class ConcatenatedModule extends Module { for (const m of this._modules) { // populate cacheable - if (!m.buildInfo.cacheable) { + if (!(/** @type {BuildInfo} */ (m.buildInfo).cacheable)) { this.buildInfo.cacheable = false; } @@ -773,7 +828,9 @@ class ConcatenatedModule extends Module { for (const d of m.dependencies.filter( dep => !(dep instanceof HarmonyImportDependency) || - !this._modules.has(compilation.moduleGraph.getModule(dep)) + !this._modules.has( + /** @type {Module} */ (compilation.moduleGraph.getModule(dep)) + ) )) { this.dependencies.push(d); } @@ -798,15 +855,14 @@ class ConcatenatedModule extends Module { } } + const { assets, assetsInfo, topLevelDeclarations } = + /** @type {BuildInfo} */ (m.buildInfo); + // populate topLevelDeclarations - if (m.buildInfo.topLevelDeclarations) { + if (topLevelDeclarations) { const topLevelDeclarations = this.buildInfo.topLevelDeclarations; if (topLevelDeclarations !== undefined) { - for (const decl of m.buildInfo.topLevelDeclarations) { - // reserved names will always be renamed - if (RESERVED_NAMES.has(decl)) continue; - // TODO actually this is incorrect since with renaming there could be more - // We should do the renaming during build + for (const decl of topLevelDeclarations) { topLevelDeclarations.add(decl); } } @@ -815,17 +871,24 @@ class ConcatenatedModule extends Module { } // populate assets - if (m.buildInfo.assets) { + if (assets) { if (this.buildInfo.assets === undefined) { this.buildInfo.assets = Object.create(null); } - Object.assign(this.buildInfo.assets, m.buildInfo.assets); + Object.assign( + /** @type {NonNullable} */ + ( + /** @type {BuildInfo} */ + (this.buildInfo).assets + ), + assets + ); } - if (m.buildInfo.assetsInfo) { + if (assetsInfo) { if (this.buildInfo.assetsInfo === undefined) { this.buildInfo.assetsInfo = new Map(); } - for (const [key, value] of m.buildInfo.assetsInfo) { + for (const [key, value] of assetsInfo) { this.buildInfo.assetsInfo.set(key, value); } } @@ -865,11 +928,16 @@ class ConcatenatedModule extends Module { * @returns {Iterable<{ connection: ModuleGraphConnection, runtimeCondition: RuntimeSpec | true }>} imported modules in order */ const getConcatenatedImports = module => { - let connections = Array.from(moduleGraph.getOutgoingConnections(module)); + const connections = Array.from( + moduleGraph.getOutgoingConnections(module) + ); if (module === rootModule) { for (const c of moduleGraph.getOutgoingConnections(this)) connections.push(c); } + /** + * @type {Array<{ connection: ModuleGraphConnection, sourceOrder: number, rangeStart: number }>} + */ const references = connections .filter(connection => { if (!(connection.dependency instanceof HarmonyImportDependency)) @@ -881,14 +949,33 @@ class ConcatenatedModule extends Module { connection.isTargetActive(runtime) ); }) - .map(connection => ({ - connection, - sourceOrder: /** @type {HarmonyImportDependency} */ (connection.dependency) - .sourceOrder - })); - references.sort( - concatComparators(bySourceOrder, keepOriginalOrder(references)) - ); + .map(connection => { + const dep = /** @type {HarmonyImportDependency} */ ( + connection.dependency + ); + return { + connection, + sourceOrder: dep.sourceOrder, + rangeStart: dep.range && dep.range[0] + }; + }); + /** + * bySourceOrder + * @example + * import a from "a"; // sourceOrder=1 + * import b from "b"; // sourceOrder=2 + * + * byRangeStart + * @example + * import {a, b} from "a"; // sourceOrder=1 + * a.a(); // first range + * b.b(); // second range + * + * If there is no reexport, we have the same source. + * If there is reexport, but module has side effects, this will lead to reexport module only. + * If there is side-effects-free reexport, we can get simple deterministic result with range start comparison. + */ + references.sort(concatComparators(bySourceOrder, byRangeStart)); /** @type {Map} */ const referencesMap = new Map(); for (const { connection } of references) { @@ -1000,19 +1087,31 @@ class ConcatenatedModule extends Module { return list; } - static _createIdentifier(rootModule, modules, associatedObjectForCache) { - const cachedContextify = contextify.bindContextCache( - rootModule.context, + /** + * @param {Module} rootModule the root module of the concatenation + * @param {Set} modules all modules in the concatenation (including the root module) + * @param {object=} associatedObjectForCache object for caching + * @param {string | HashConstructor=} hashFunction hash function to use + * @returns {string} the identifier + */ + static _createIdentifier( + rootModule, + modules, + associatedObjectForCache, + hashFunction = "md4" + ) { + const cachedMakePathsRelative = makePathsRelative.bindContextCache( + /** @type {string} */ (rootModule.context), associatedObjectForCache ); - let identifiers = []; + const identifiers = []; for (const module of modules) { - identifiers.push(cachedContextify(module.identifier())); + identifiers.push(cachedMakePathsRelative(module.identifier())); } identifiers.sort(); - const hash = createHash("md4"); + const hash = createHash(hashFunction); hash.update(identifiers.join(" ")); - return rootModule.identifier() + "|" + hash.digest("hex"); + return `${rootModule.identifier()}|${hash.digest("hex")}`; } /** @@ -1046,7 +1145,8 @@ class ConcatenatedModule extends Module { runtimeTemplate, moduleGraph, chunkGraph, - runtime: generationRuntime + runtime: generationRuntime, + codeGenerationResults }) { /** @type {Set} */ const runtimeRequirements = new Set(); @@ -1073,20 +1173,23 @@ class ConcatenatedModule extends Module { runtimeTemplate, moduleGraph, chunkGraph, - runtime + runtime, + codeGenerationResults ); } // List of all used names to avoid conflicts const allUsedNames = new Set(RESERVED_NAMES); + // Updated Top level declarations are created by renaming + const topLevelDeclarations = new Set(); // List of additional names in scope for module references - /** @type {Map, alreadyCheckedScopes: Set }>} */ + /** @type {Map }>} */ const usedNamesInScopeInfo = new Map(); /** * @param {string} module module identifier * @param {string} id export id - * @returns {{ usedNames: Set, alreadyCheckedScopes: Set }} info + * @returns {{ usedNames: UsedNames, alreadyCheckedScopes: Set }} info */ const getUsedNamesInScopeInfo = (module, id) => { const key = `${module}-${id}`; @@ -1116,6 +1219,10 @@ class ConcatenatedModule extends Module { // We get ranges of all super class expressions to make // renaming to work correctly const superClassCache = new WeakMap(); + /** + * @param {Scope} scope scope + * @returns {TODO} result + */ const getSuperClassExpressions = scope => { const cacheEntry = superClassCache.get(scope); if (cacheEntry !== undefined) return cacheEntry; @@ -1158,21 +1265,22 @@ class ConcatenatedModule extends Module { runtimeTemplate, neededNamespaceObjects, false, - info.module.buildMeta.strictHarmonyModule, + /** @type {BuildMeta} */ + (info.module.buildMeta).strictHarmonyModule, true ); if (!binding.ids) continue; - const { - usedNames, - alreadyCheckedScopes - } = getUsedNamesInScopeInfo( - binding.info.module.identifier(), - "name" in binding ? binding.name : "" - ); + const { usedNames, alreadyCheckedScopes } = + getUsedNamesInScopeInfo( + binding.info.module.identifier(), + "name" in binding ? binding.name : "" + ); for (const expr of getSuperClassExpressions(reference.from)) { if ( - expr.range[0] <= reference.identifier.range[0] && - expr.range[1] >= reference.identifier.range[1] + expr.range[0] <= + /** @type {Range} */ (reference.identifier.range)[0] && + expr.range[1] >= + /** @type {Range} */ (reference.identifier.range)[1] ) { for (const variable of expr.variables) { usedNames.add(variable.name); @@ -1225,13 +1333,18 @@ class ConcatenatedModule extends Module { ); allUsedNames.add(newName); info.internalNames.set(name, newName); + topLevelDeclarations.add(newName); const source = info.source; const allIdentifiers = new Set( references.map(r => r.identifier).concat(variable.identifiers) ); for (const identifier of allIdentifiers) { - const r = identifier.range; - const path = getPathInAst(info.ast, identifier); + const r = /** @type {Range} */ (identifier.range); + const path = getPathInAst( + /** @type {NonNullable} */ + (info.ast), + identifier + ); if (path && path.length > 1) { const maybeProperty = path[1].type === "AssignmentPattern" && @@ -1251,6 +1364,7 @@ class ConcatenatedModule extends Module { } else { allUsedNames.add(name); info.internalNames.set(name, name); + topLevelDeclarations.add(name); } } let namespaceObjectName; @@ -1267,7 +1381,10 @@ class ConcatenatedModule extends Module { ); allUsedNames.add(namespaceObjectName); } - info.namespaceObjectName = namespaceObjectName; + info.namespaceObjectName = + /** @type {string} */ + (namespaceObjectName); + topLevelDeclarations.add(namespaceObjectName); break; } case "external": { @@ -1279,10 +1396,12 @@ class ConcatenatedModule extends Module { ); allUsedNames.add(externalName); info.name = externalName; + topLevelDeclarations.add(externalName); break; } } - if (info.module.buildMeta.exportsType !== "namespace") { + const buildMeta = /** @type {BuildMeta} */ (info.module.buildMeta); + if (buildMeta.exportsType !== "namespace") { const externalNameInterop = this.findNewName( "namespaceObject", allUsedNames, @@ -1291,10 +1410,11 @@ class ConcatenatedModule extends Module { ); allUsedNames.add(externalNameInterop); info.interopNamespaceObjectName = externalNameInterop; + topLevelDeclarations.add(externalNameInterop); } if ( - info.module.buildMeta.exportsType === "default" && - info.module.buildMeta.defaultObject !== "redirect" + buildMeta.exportsType === "default" && + buildMeta.defaultObject !== "redirect" ) { const externalNameInterop = this.findNewName( "namespaceObject2", @@ -1304,11 +1424,9 @@ class ConcatenatedModule extends Module { ); allUsedNames.add(externalNameInterop); info.interopNamespaceObject2Name = externalNameInterop; + topLevelDeclarations.add(externalNameInterop); } - if ( - info.module.buildMeta.exportsType === "dynamic" || - !info.module.buildMeta.exportsType - ) { + if (buildMeta.exportsType === "dynamic" || !buildMeta.exportsType) { const externalNameInterop = this.findNewName( "default", allUsedNames, @@ -1317,13 +1435,15 @@ class ConcatenatedModule extends Module { ); allUsedNames.add(externalNameInterop); info.interopDefaultAccessName = externalNameInterop; + topLevelDeclarations.add(externalNameInterop); } } // Find and replace references to modules for (const info of moduleToInfoMap.values()) { if (info.type === "concatenated") { - for (const reference of info.globalScope.through) { + const globalScope = /** @type {Scope} */ (info.globalScope); + for (const reference of globalScope.through) { const name = reference.identifier.name; const match = ConcatenationScope.matchModuleReference(name); if (match) { @@ -1341,10 +1461,11 @@ class ConcatenatedModule extends Module { neededNamespaceObjects, match.call, !match.directImport, - info.module.buildMeta.strictHarmonyModule, + /** @type {BuildMeta} */ + (info.module.buildMeta).strictHarmonyModule, match.asiSafe ); - const r = reference.identifier.range; + const r = /** @type {Range} */ (reference.identifier.range); const source = info.source; // range is extended by 2 chars to cover the appended "._" source.replace(r[0], r[1] + 1, finalName); @@ -1361,11 +1482,15 @@ class ConcatenatedModule extends Module { /** @type {Set} */ const unusedExports = new Set(); - const rootInfo = /** @type {ConcatenatedModuleInfo} */ (moduleToInfoMap.get( - this.rootModule - )); - const strictHarmonyModule = rootInfo.module.buildMeta.strictHarmonyModule; + const rootInfo = /** @type {ConcatenatedModuleInfo} */ ( + moduleToInfoMap.get(this.rootModule) + ); + const strictHarmonyModule = + /** @type {BuildMeta} */ + (rootInfo.module.buildMeta).strictHarmonyModule; const exportsInfo = moduleGraph.getExportsInfo(rootInfo.module); + /** @type {Record} */ + const exportsFinalName = {}; for (const exportInfo of exportsInfo.orderedExports) { const name = exportInfo.name; if (exportInfo.provided === false) continue; @@ -1390,12 +1515,15 @@ class ConcatenatedModule extends Module { strictHarmonyModule, true ); + exportsFinalName[used] = finalName; return `/* ${ exportInfo.isReexport() ? "reexport" : "binding" } */ ${finalName}`; - } catch (e) { - e.message += `\nwhile generating the root export '${name}' (used name: '${used}')`; - throw e; + } catch (err) { + /** @type {Error} */ + (err).message += + `\nwhile generating the root export '${name}' (used name: '${used}')`; + throw err; } }); } @@ -1403,37 +1531,55 @@ class ConcatenatedModule extends Module { const result = new ConcatSource(); // add harmony compatibility flag (must be first because of possible circular dependencies) + let shouldAddHarmonyFlag = false; if ( moduleGraph.getExportsInfo(this).otherExportsInfo.getUsed(runtime) !== UsageState.Unused ) { - result.add(`// ESM COMPAT FLAG\n`); - result.add( - runtimeTemplate.defineEsModuleFlagStatement({ - exportsArgument: this.exportsArgument, - runtimeRequirements - }) - ); + shouldAddHarmonyFlag = true; } // define exports if (exportsMap.size > 0) { - runtimeRequirements.add(RuntimeGlobals.exports); - runtimeRequirements.add(RuntimeGlobals.definePropertyGetters); + const { exportsDefinitions } = ConcatenatedModule.getCompilationHooks( + /** @type {Compilation} */ (this.compilation) + ); + const definitions = []; for (const [key, value] of exportsMap) { definitions.push( - `\n ${JSON.stringify(key)}: ${runtimeTemplate.returningFunction( + `\n ${propertyName(key)}: ${runtimeTemplate.returningFunction( value(requestShortener) )}` ); } - result.add(`\n// EXPORTS\n`); - result.add( - `${RuntimeGlobals.definePropertyGetters}(${ - this.exportsArgument - }, {${definitions.join(",")}\n});\n` - ); + const shouldSkipRenderDefinitions = + exportsDefinitions.call(exportsFinalName); + + if (!shouldSkipRenderDefinitions) { + runtimeRequirements.add(RuntimeGlobals.exports); + runtimeRequirements.add(RuntimeGlobals.definePropertyGetters); + + if (shouldAddHarmonyFlag) { + result.add("// ESM COMPAT FLAG\n"); + result.add( + runtimeTemplate.defineEsModuleFlagStatement({ + exportsArgument: this.exportsArgument, + runtimeRequirements + }) + ); + } + + result.add("\n// EXPORTS\n"); + result.add( + `${RuntimeGlobals.definePropertyGetters}(${ + this.exportsArgument + }, {${definitions.join(",")}\n});\n` + ); + } else { + /** @type {BuildMeta} */ + (this.buildMeta).exportsFinalName = exportsFinalName; + } } // list unused exports @@ -1464,13 +1610,14 @@ class ConcatenatedModule extends Module { neededNamespaceObjects, false, undefined, - info.module.buildMeta.strictHarmonyModule, + /** @type {BuildMeta} */ + (info.module.buildMeta).strictHarmonyModule, true ); nsObj.push( - `\n ${JSON.stringify( - usedName - )}: ${runtimeTemplate.returningFunction(finalName)}` + `\n ${propertyName(usedName)}: ${runtimeTemplate.returningFunction( + finalName + )}` ); } } @@ -1479,7 +1626,7 @@ class ConcatenatedModule extends Module { nsObj.length > 0 ? `${RuntimeGlobals.definePropertyGetters}(${name}, {${nsObj.join( "," - )}\n});\n` + )}\n});\n` : ""; if (nsObj.length > 0) runtimeRequirements.add(RuntimeGlobals.definePropertyGetters); @@ -1503,6 +1650,8 @@ ${defineGetters}` } } + const chunkInitFragments = []; + // evaluate modules in order for (const rawInfo of modulesWithInfo) { let name; @@ -1516,6 +1665,9 @@ ${defineGetters}` )}\n` ); result.add(info.source); + if (info.chunkInitFragments) { + for (const f of info.chunkInitFragments) chunkInitFragments.push(f); + } if (info.runtimeRequirements) { for (const r of info.runtimeRequirements) { runtimeRequirements.add(r); @@ -1531,9 +1683,8 @@ ${defineGetters}` )}\n` ); runtimeRequirements.add(RuntimeGlobals.require); - const { - runtimeCondition - } = /** @type {ExternalModuleInfo | ReferenceToModuleInfo} */ (rawInfo); + const { runtimeCondition } = + /** @type {ExternalModuleInfo | ReferenceToModuleInfo} */ (rawInfo); const condition = runtimeTemplate.runtimeConditionExpression({ chunkGraph, runtimeCondition, @@ -1545,7 +1696,7 @@ ${defineGetters}` result.add(`if (${condition}) {\n`); } result.add( - `var ${info.name} = __webpack_require__(${JSON.stringify( + `var ${info.name} = ${RuntimeGlobals.require}(${JSON.stringify( chunkGraph.getModuleId(info.module) )});` ); @@ -1579,9 +1730,15 @@ ${defineGetters}` } } + const data = new Map(); + if (chunkInitFragments.length > 0) + data.set("chunkInitFragments", chunkInitFragments); + data.set("topLevelDeclarations", topLevelDeclarations); + /** @type {CodeGenerationResult} */ const resultEntry = { sources: new Map([["javascript", new CachedSource(result)]]), + data, runtimeRequirements }; @@ -1596,6 +1753,7 @@ ${defineGetters}` * @param {ModuleGraph} moduleGraph moduleGraph * @param {ChunkGraph} chunkGraph chunkGraph * @param {RuntimeSpec} runtime runtime + * @param {CodeGenerationResults} codeGenerationResults codeGenerationResults */ _analyseModule( modulesMap, @@ -1604,7 +1762,8 @@ ${defineGetters}` runtimeTemplate, moduleGraph, chunkGraph, - runtime + runtime, + codeGenerationResults ) { if (info.type === "concatenated") { const m = info.module; @@ -1619,16 +1778,23 @@ ${defineGetters}` moduleGraph, chunkGraph, runtime, - concatenationScope + concatenationScope, + codeGenerationResults, + sourceTypes: TYPES }); - const source = codeGenResult.sources.get("javascript"); + const source = /** @type {Source} */ ( + codeGenResult.sources.get("javascript") + ); + const data = codeGenResult.data; + const chunkInitFragments = data && data.get("chunkInitFragments"); const code = source.source().toString(); let ast; try { ast = JavascriptParser._parse(code, { sourceType: "module" }); - } catch (err) { + } catch (_err) { + const err = /** @type {TODO} */ (_err); if ( err.loc && typeof err.loc === "object" && @@ -1636,11 +1802,9 @@ ${defineGetters}` ) { const lineNumber = err.loc.line; const lines = code.split("\n"); - err.message += - "\n| " + - lines - .slice(Math.max(0, lineNumber - 3), lineNumber + 2) - .join("\n| "); + err.message += `\n| ${lines + .slice(Math.max(0, lineNumber - 3), lineNumber + 2) + .join("\n| ")}`; } throw err; } @@ -1651,17 +1815,20 @@ ${defineGetters}` ignoreEval: true, impliedStrict: true }); - const globalScope = scopeManager.acquire(ast); + const globalScope = /** @type {Scope} */ (scopeManager.acquire(ast)); const moduleScope = globalScope.childScopes[0]; const resultSource = new ReplaceSource(source); info.runtimeRequirements = codeGenResult.runtimeRequirements; info.ast = ast; info.internalSource = source; info.source = resultSource; + info.chunkInitFragments = chunkInitFragments; info.globalScope = globalScope; info.moduleScope = moduleScope; } catch (err) { - err.message += `\nwhile analysing module ${m.identifier()} for concatenation`; + /** @type {Error} */ + (err).message += + `\nwhile analyzing module ${m.identifier()} for concatenation`; throw err; } } @@ -1729,21 +1896,30 @@ ${defineGetters}` `Unsupported concatenation entry type ${info.type}` ); } - map.set(item.module, item); - return item; - } else { - /** @type {ReferenceToModuleInfo} */ - const ref = { - type: "reference", - runtimeCondition: info.runtimeCondition, - target: item - }; - return ref; + map.set( + /** @type {ModuleInfo} */ (item).module, + /** @type {ModuleInfo} */ (item) + ); + return /** @type {ModuleInfo} */ (item); } + /** @type {ReferenceToModuleInfo} */ + const ref = { + type: "reference", + runtimeCondition: info.runtimeCondition, + target: item + }; + return ref; }); return [list, map]; } + /** + * @param {string} oldName old name + * @param {UsedNames} usedNamed1 used named 1 + * @param {UsedNames} usedNamed2 used named 2 + * @param {string} extraInfo extra info + * @returns {string} found new name + */ findNewName(oldName, usedNamed1, usedNamed2, extraInfo) { let name = oldName; @@ -1762,7 +1938,7 @@ ${defineGetters}` const splittedInfo = extraInfo.split("/"); while (splittedInfo.length) { - name = splittedInfo.pop() + (name ? "_" + name : ""); + name = splittedInfo.pop() + (name ? `_${name}` : ""); const nameIdent = Template.toIdentifier(name); if ( !usedNamed1.has(nameIdent) && @@ -1775,6 +1951,7 @@ ${defineGetters}` let nameWithNumber = Template.toIdentifier(`${name}_${i}`); while ( usedNamed1.has(nameWithNumber) || + // eslint-disable-next-line no-unmodified-loop-condition (usedNamed2 && usedNamed2.has(nameWithNumber)) ) { i++; @@ -1809,12 +1986,17 @@ ${defineGetters}` super.updateHash(hash, context); } + /** + * @param {ObjectDeserializerContext} context context + * @returns {ConcatenatedModule} ConcatenatedModule + */ static deserialize(context) { const obj = new ConcatenatedModule({ identifier: undefined, rootModule: undefined, modules: undefined, - runtime: undefined + runtime: undefined, + compilation: undefined }); obj.deserialize(context); return obj; diff --git a/lib/optimize/EnsureChunkConditionsPlugin.js b/lib/optimize/EnsureChunkConditionsPlugin.js index b7c1b9eb23b..0bc8a384bb6 100644 --- a/lib/optimize/EnsureChunkConditionsPlugin.js +++ b/lib/optimize/EnsureChunkConditionsPlugin.js @@ -21,6 +21,9 @@ class EnsureChunkConditionsPlugin { compiler.hooks.compilation.tap( "EnsureChunkConditionsPlugin", compilation => { + /** + * @param {Iterable} chunks the chunks + */ const handler = chunks => { const chunkGraph = compilation.chunkGraph; // These sets are hoisted here to save memory @@ -30,6 +33,7 @@ class EnsureChunkConditionsPlugin { /** @type {Set} */ const chunkGroups = new Set(); for (const module of compilation.modules) { + if (!module.hasChunkCondition()) continue; for (const chunk of chunkGraph.getModuleChunksIterable(module)) { if (!module.chunkCondition(chunk, compilation)) { sourceChunks.add(chunk); @@ -52,7 +56,7 @@ class EnsureChunkConditionsPlugin { // We reached the entrypoint: fail if (chunkGroup.isInitial()) { throw new Error( - "Cannot fullfil chunk condition of " + module.identifier() + `Cannot fulfil chunk condition of ${module.identifier()}` ); } // Try placing in all parents diff --git a/lib/optimize/FlagIncludedChunksPlugin.js b/lib/optimize/FlagIncludedChunksPlugin.js index f751a29f0fe..35d5d757de7 100644 --- a/lib/optimize/FlagIncludedChunksPlugin.js +++ b/lib/optimize/FlagIncludedChunksPlugin.js @@ -6,6 +6,7 @@ "use strict"; /** @typedef {import("../Chunk")} Chunk */ +/** @typedef {import("../Chunk").ChunkId} ChunkId */ /** @typedef {import("../Compiler")} Compiler */ /** @typedef {import("../Module")} Module */ @@ -38,10 +39,10 @@ class FlagIncludedChunksPlugin { const modulesCount = compilation.modules.size; // precalculate the modulo values for each bit - const modulo = 1 / Math.pow(1 / modulesCount, 1 / 31); + const modulo = 1 / (1 / modulesCount) ** (1 / 31); const modulos = Array.from( { length: 31 }, - (x, i) => Math.pow(modulo, i) | 0 + (x, i) => (modulo ** i) | 0 ); // iterate all modules to generate bit values @@ -61,18 +62,19 @@ class FlagIncludedChunksPlugin { for (const chunk of chunks) { let hash = 0; for (const module of chunkGraph.getChunkModulesIterable(chunk)) { - hash |= moduleBits.get(module); + hash |= /** @type {number} */ (moduleBits.get(module)); } chunkModulesHash.set(chunk, hash); } for (const chunkA of chunks) { - const chunkAHash = chunkModulesHash.get(chunkA); - const chunkAModulesCount = chunkGraph.getNumberOfChunkModules( - chunkA - ); + const chunkAHash = + /** @type {number} */ + (chunkModulesHash.get(chunkA)); + const chunkAModulesCount = + chunkGraph.getNumberOfChunkModules(chunkA); if (chunkAModulesCount === 0) continue; - let bestModule = undefined; + let bestModule; for (const module of chunkGraph.getChunkModulesIterable(chunkA)) { if ( bestModule === undefined || @@ -82,15 +84,14 @@ class FlagIncludedChunksPlugin { bestModule = module; } loopB: for (const chunkB of chunkGraph.getModuleChunksIterable( - bestModule + /** @type {Module} */ (bestModule) )) { // as we iterate the same iterables twice // skip if we find ourselves if (chunkA === chunkB) continue; - const chunkBModulesCount = chunkGraph.getNumberOfChunkModules( - chunkB - ); + const chunkBModulesCount = + chunkGraph.getNumberOfChunkModules(chunkB); // ids for empty chunks are not included if (chunkBModulesCount === 0) continue; @@ -102,14 +103,17 @@ class FlagIncludedChunksPlugin { // is chunkA in chunkB? // we do a cheap check for the hash value - const chunkBHash = chunkModulesHash.get(chunkB); + const chunkBHash = + /** @type {number} */ + (chunkModulesHash.get(chunkB)); if ((chunkBHash & chunkAHash) !== chunkAHash) continue; // compare all modules for (const m of chunkGraph.getChunkModulesIterable(chunkA)) { if (!chunkGraph.isModuleInChunk(m, chunkB)) continue loopB; } - chunkB.ids.push(chunkA.id); + /** @type {ChunkId[]} */ + (chunkB.ids).push(/** @type {ChunkId} */ (chunkA.id)); } } } diff --git a/lib/optimize/InnerGraph.js b/lib/optimize/InnerGraph.js index 064eb3a7cd6..099c5eb1847 100644 --- a/lib/optimize/InnerGraph.js +++ b/lib/optimize/InnerGraph.js @@ -9,6 +9,7 @@ const { UsageState } = require("../ExportsInfo"); /** @typedef {import("estree").Node} AnyNode */ /** @typedef {import("../Dependency")} Dependency */ +/** @typedef {import("../Module")} Module */ /** @typedef {import("../ModuleGraph")} ModuleGraph */ /** @typedef {import("../ModuleGraphConnection")} ModuleGraphConnection */ /** @typedef {import("../ModuleGraphConnection").ConnectionState} ConnectionState */ @@ -16,11 +17,11 @@ const { UsageState } = require("../ExportsInfo"); /** @typedef {import("../javascript/JavascriptParser")} JavascriptParser */ /** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */ -/** @typedef {Map | true>} InnerGraph */ +/** @typedef {Map | true | undefined>} InnerGraph */ /** @typedef {function(boolean | Set | undefined): void} UsageCallback */ /** - * @typedef {Object} StateObject + * @typedef {object} StateObject * @property {InnerGraph} innerGraph * @property {TopLevelSymbol=} currentTopLevelSymbol * @property {Map>} usageCallbackMap @@ -34,7 +35,7 @@ const topLevelSymbolTag = Symbol("top level symbol"); /** * @param {ParserState} parserState parser state - * @returns {State} state + * @returns {State | undefined} state */ function getState(parserState) { return parserStateMap.get(parserState); @@ -44,7 +45,7 @@ function getState(parserState) { * @param {ParserState} parserState parser state * @returns {void} */ -exports.bailout = parserState => { +module.exports.bailout = parserState => { parserStateMap.set(parserState, false); }; @@ -52,7 +53,7 @@ exports.bailout = parserState => { * @param {ParserState} parserState parser state * @returns {void} */ -exports.enable = parserState => { +module.exports.enable = parserState => { const state = parserStateMap.get(parserState); if (state === false) { return; @@ -68,18 +69,18 @@ exports.enable = parserState => { * @param {ParserState} parserState parser state * @returns {boolean} true, when enabled */ -exports.isEnabled = parserState => { +module.exports.isEnabled = parserState => { const state = parserStateMap.get(parserState); - return !!state; + return Boolean(state); }; /** * @param {ParserState} state parser state - * @param {TopLevelSymbol} symbol the symbol + * @param {TopLevelSymbol | null} symbol the symbol, or null for all symbols * @param {string | TopLevelSymbol | true} usage usage data * @returns {void} */ -exports.addUsage = (state, symbol, usage) => { +module.exports.addUsage = (state, symbol, usage) => { const innerGraphState = getState(state); if (innerGraphState) { @@ -101,14 +102,13 @@ exports.addUsage = (state, symbol, usage) => { * @param {string | TopLevelSymbol | true} usage usage data * @returns {void} */ -exports.addVariableUsage = (parser, name, usage) => { +module.exports.addVariableUsage = (parser, name, usage) => { const symbol = - /** @type {TopLevelSymbol} */ (parser.getTagData( - name, - topLevelSymbolTag - )) || exports.tagTopLevelSymbol(parser, name); + /** @type {TopLevelSymbol} */ ( + parser.getTagData(name, topLevelSymbolTag) + ) || module.exports.tagTopLevelSymbol(parser, name); if (symbol) { - exports.addUsage(parser.state, symbol, usage); + module.exports.addUsage(parser.state, symbol, usage); } }; @@ -116,7 +116,7 @@ exports.addVariableUsage = (parser, name, usage) => { * @param {ParserState} state parser state * @returns {void} */ -exports.inferDependencyUsage = state => { +module.exports.inferDependencyUsage = state => { const innerGraphState = getState(state); if (!innerGraphState) { @@ -173,15 +173,35 @@ exports.inferDependencyUsage = state => { } if (isTerminal) { nonTerminal.delete(key); + + // For the global key, merge with all other keys + if (key === null) { + const globalValue = innerGraph.get(null); + if (globalValue) { + for (const [key, value] of innerGraph) { + if (key !== null && value !== true) { + if (globalValue === true) { + innerGraph.set(key, true); + } else { + const newSet = new Set(value); + for (const item of globalValue) { + newSet.add(item); + } + innerGraph.set(key, newSet); + } + } + } + } + } } } } /** @type {Map>} */ for (const [symbol, callbacks] of usageCallbackMap) { - const usage = /** @type {true | Set | undefined} */ (innerGraph.get( - symbol - )); + const usage = /** @type {true | Set | undefined} */ ( + innerGraph.get(symbol) + ); for (const callback of callbacks) { callback(usage === undefined ? false : usage); } @@ -192,7 +212,7 @@ exports.inferDependencyUsage = state => { * @param {ParserState} state parser state * @param {UsageCallback} onUsageCallback on usage callback */ -exports.onUsage = (state, onUsageCallback) => { +module.exports.onUsage = (state, onUsageCallback) => { const innerGraphState = getState(state); if (innerGraphState) { @@ -216,9 +236,9 @@ exports.onUsage = (state, onUsageCallback) => { /** * @param {ParserState} state parser state - * @param {TopLevelSymbol} symbol the symbol + * @param {TopLevelSymbol | undefined} symbol the symbol */ -exports.setTopLevelSymbol = (state, symbol) => { +module.exports.setTopLevelSymbol = (state, symbol) => { const innerGraphState = getState(state); if (innerGraphState) { @@ -230,7 +250,7 @@ exports.setTopLevelSymbol = (state, symbol) => { * @param {ParserState} state parser state * @returns {TopLevelSymbol|void} usage data */ -exports.getTopLevelSymbol = state => { +module.exports.getTopLevelSymbol = state => { const innerGraphState = getState(state); if (innerGraphState) { @@ -241,18 +261,17 @@ exports.getTopLevelSymbol = state => { /** * @param {JavascriptParser} parser parser * @param {string} name name of variable - * @returns {TopLevelSymbol} symbol + * @returns {TopLevelSymbol | undefined} symbol */ -exports.tagTopLevelSymbol = (parser, name) => { +module.exports.tagTopLevelSymbol = (parser, name) => { const innerGraphState = getState(parser.state); if (!innerGraphState) return; parser.defineVariable(name); - const existingTag = /** @type {TopLevelSymbol} */ (parser.getTagData( - name, - topLevelSymbolTag - )); + const existingTag = /** @type {TopLevelSymbol} */ ( + parser.getTagData(name, topLevelSymbolTag) + ); if (existingTag) { return existingTag; } @@ -269,7 +288,7 @@ exports.tagTopLevelSymbol = (parser, name) => { * @param {RuntimeSpec} runtime runtime * @returns {boolean} false, when unused. Otherwise true */ -exports.isDependencyUsedByExports = ( +module.exports.isDependencyUsedByExports = ( dependency, usedByExports, moduleGraph, @@ -277,7 +296,9 @@ exports.isDependencyUsedByExports = ( ) => { if (usedByExports === false) return false; if (usedByExports !== true && usedByExports !== undefined) { - const selfModule = moduleGraph.getParentModule(dependency); + const selfModule = + /** @type {Module} */ + (moduleGraph.getParentModule(dependency)); const exportsInfo = moduleGraph.getExportsInfo(selfModule); let used = false; for (const exportName of usedByExports) { @@ -291,18 +312,20 @@ exports.isDependencyUsedByExports = ( /** * @param {Dependency} dependency the dependency - * @param {Set | boolean} usedByExports usedByExports info + * @param {Set | boolean | undefined} usedByExports usedByExports info * @param {ModuleGraph} moduleGraph moduleGraph * @returns {null | false | function(ModuleGraphConnection, RuntimeSpec): ConnectionState} function to determine if the connection is active */ -exports.getDependencyUsedByExportsCondition = ( +module.exports.getDependencyUsedByExportsCondition = ( dependency, usedByExports, moduleGraph ) => { if (usedByExports === false) return false; if (usedByExports !== true && usedByExports !== undefined) { - const selfModule = moduleGraph.getParentModule(dependency); + const selfModule = + /** @type {Module} */ + (moduleGraph.getParentModule(dependency)); const exportsInfo = moduleGraph.getExportsInfo(selfModule); return (connections, runtime) => { for (const exportName of usedByExports) { @@ -324,5 +347,5 @@ class TopLevelSymbol { } } -exports.TopLevelSymbol = TopLevelSymbol; -exports.topLevelSymbolTag = topLevelSymbolTag; +module.exports.TopLevelSymbol = TopLevelSymbol; +module.exports.topLevelSymbolTag = topLevelSymbolTag; diff --git a/lib/optimize/InnerGraphPlugin.js b/lib/optimize/InnerGraphPlugin.js index 3c50088f5be..9d24abe3b47 100644 --- a/lib/optimize/InnerGraphPlugin.js +++ b/lib/optimize/InnerGraphPlugin.js @@ -5,6 +5,10 @@ "use strict"; +const { + JAVASCRIPT_MODULE_TYPE_AUTO, + JAVASCRIPT_MODULE_TYPE_ESM +} = require("../ModuleTypeConstants"); const PureExpressionDependency = require("../dependencies/PureExpressionDependency"); const InnerGraph = require("./InnerGraph"); @@ -12,15 +16,20 @@ const InnerGraph = require("./InnerGraph"); /** @typedef {import("estree").ClassExpression} ClassExpressionNode */ /** @typedef {import("estree").Node} Node */ /** @typedef {import("estree").VariableDeclarator} VariableDeclaratorNode */ +/** @typedef {import("../../declarations/WebpackOptions").JavascriptParserOptions} JavascriptParserOptions */ /** @typedef {import("../Compiler")} Compiler */ /** @typedef {import("../Dependency")} Dependency */ +/** @typedef {import("../Dependency").DependencyLocation} DependencyLocation */ /** @typedef {import("../dependencies/HarmonyImportSpecifierDependency")} HarmonyImportSpecifierDependency */ /** @typedef {import("../javascript/JavascriptParser")} JavascriptParser */ +/** @typedef {import("../javascript/JavascriptParser").Range} Range */ /** @typedef {import("./InnerGraph").InnerGraph} InnerGraph */ /** @typedef {import("./InnerGraph").TopLevelSymbol} TopLevelSymbol */ const { topLevelSymbolTag } = InnerGraph; +const PLUGIN_NAME = "InnerGraphPlugin"; + class InnerGraphPlugin { /** * Apply the plugin @@ -29,7 +38,7 @@ class InnerGraphPlugin { */ apply(compiler) { compiler.hooks.compilation.tap( - "InnerGraphPlugin", + PLUGIN_NAME, (compilation, { normalModuleFactory }) => { const logger = compilation.getLogger("webpack.InnerGraphPlugin"); @@ -40,7 +49,7 @@ class InnerGraphPlugin { /** * @param {JavascriptParser} parser the parser - * @param {Object} parserOptions options + * @param {JavascriptParserOptions} parserOptions options * @returns {void} */ const handler = (parser, parserOptions) => { @@ -61,11 +70,11 @@ class InnerGraphPlugin { }); }; - parser.hooks.program.tap("InnerGraphPlugin", () => { + parser.hooks.program.tap(PLUGIN_NAME, () => { InnerGraph.enable(parser.state); }); - parser.hooks.finish.tap("InnerGraphPlugin", () => { + parser.hooks.finish.tap(PLUGIN_NAME, () => { if (!InnerGraph.isEnabled(parser.state)) return; logger.time("infer dependency usage"); @@ -97,24 +106,31 @@ class InnerGraphPlugin { // The following hooks are used during prewalking: - parser.hooks.preStatement.tap("InnerGraphPlugin", statement => { + parser.hooks.preStatement.tap(PLUGIN_NAME, statement => { if (!InnerGraph.isEnabled(parser.state)) return; - if (parser.scope.topLevelScope === true) { - if (statement.type === "FunctionDeclaration") { - const name = statement.id ? statement.id.name : "*default*"; - const fn = InnerGraph.tagTopLevelSymbol(parser, name); - statementWithTopLevelSymbol.set(statement, fn); - return true; - } + if ( + parser.scope.topLevelScope === true && + statement.type === "FunctionDeclaration" + ) { + const name = statement.id ? statement.id.name : "*default*"; + const fn = InnerGraph.tagTopLevelSymbol(parser, name); + statementWithTopLevelSymbol.set(statement, fn); + return true; } }); - parser.hooks.blockPreStatement.tap("InnerGraphPlugin", statement => { + parser.hooks.blockPreStatement.tap(PLUGIN_NAME, statement => { if (!InnerGraph.isEnabled(parser.state)) return; if (parser.scope.topLevelScope === true) { - if (statement.type === "ClassDeclaration") { + if ( + statement.type === "ClassDeclaration" && + parser.isPure( + statement, + /** @type {Range} */ (statement.range)[0] + ) + ) { const name = statement.id ? statement.id.name : "*default*"; const fn = InnerGraph.tagTopLevelSymbol(parser, name); classWithTopLevelSymbol.set(statement, fn); @@ -125,11 +141,14 @@ class InnerGraphPlugin { const fn = InnerGraph.tagTopLevelSymbol(parser, name); const decl = statement.declaration; if ( - decl.type === "ClassExpression" || - decl.type === "ClassDeclaration" + (decl.type === "ClassExpression" || + decl.type === "ClassDeclaration") && + parser.isPure(decl, /** @type {Range} */ (decl.range)[0]) ) { classWithTopLevelSymbol.set(decl, fn); - } else if (parser.isPure(decl, statement.range[0])) { + } else if ( + parser.isPure(decl, /** @type {Range} */ (statement.range)[0]) + ) { statementWithTopLevelSymbol.set(statement, fn); if ( !decl.type.endsWith("FunctionExpression") && @@ -143,33 +162,40 @@ class InnerGraphPlugin { } }); - parser.hooks.preDeclarator.tap( - "InnerGraphPlugin", - (decl, statement) => { - if (!InnerGraph.isEnabled(parser.state)) return; + parser.hooks.preDeclarator.tap(PLUGIN_NAME, (decl, statement) => { + if (!InnerGraph.isEnabled(parser.state)) return; + if ( + parser.scope.topLevelScope === true && + decl.init && + decl.id.type === "Identifier" + ) { + const name = decl.id.name; if ( - parser.scope.topLevelScope === true && - decl.init && - decl.id.type === "Identifier" + decl.init.type === "ClassExpression" && + parser.isPure( + decl.init, + /** @type {Range} */ (decl.id.range)[1] + ) ) { - const name = decl.id.name; - if (decl.init.type === "ClassExpression") { - const fn = InnerGraph.tagTopLevelSymbol(parser, name); - classWithTopLevelSymbol.set(decl.init, fn); - } else if (parser.isPure(decl.init, decl.id.range[1])) { - const fn = InnerGraph.tagTopLevelSymbol(parser, name); - declWithTopLevelSymbol.set(decl, fn); - if ( - !decl.init.type.endsWith("FunctionExpression") && - decl.init.type !== "Literal" - ) { - pureDeclarators.add(decl); - } - return true; + const fn = InnerGraph.tagTopLevelSymbol(parser, name); + classWithTopLevelSymbol.set(decl.init, fn); + } else if ( + parser.isPure( + decl.init, + /** @type {Range} */ (decl.id.range)[1] + ) + ) { + const fn = InnerGraph.tagTopLevelSymbol(parser, name); + declWithTopLevelSymbol.set(decl, fn); + if ( + !decl.init.type.endsWith("FunctionExpression") && + decl.init.type !== "Literal" + ) { + pureDeclarators.add(decl); } } } - ); + }); // During real walking we set the TopLevelSymbol state to the assigned // TopLevelSymbol by using the fill datastructures. @@ -187,7 +213,7 @@ class InnerGraphPlugin { // The following hooks are called during walking: - parser.hooks.statement.tap("InnerGraphPlugin", statement => { + parser.hooks.statement.tap(PLUGIN_NAME, statement => { if (!InnerGraph.isEnabled(parser.state)) return; if (parser.scope.topLevelScope === true) { InnerGraph.setTopLevelSymbol(parser.state, undefined); @@ -204,9 +230,11 @@ class InnerGraphPlugin { return; default: { const dep = new PureExpressionDependency( - purePart.range + /** @type {Range} */ (purePart.range) ); - dep.loc = statement.loc; + dep.loc = + /** @type {DependencyLocation} */ + (statement.loc); dep.usedByExports = usedByExports; parser.state.module.addDependency(dep); break; @@ -219,7 +247,7 @@ class InnerGraphPlugin { }); parser.hooks.classExtendsExpression.tap( - "InnerGraphPlugin", + PLUGIN_NAME, (expr, statement) => { if (!InnerGraph.isEnabled(parser.state)) return; if (parser.scope.topLevelScope === true) { @@ -228,7 +256,9 @@ class InnerGraphPlugin { fn && parser.isPure( expr, - statement.id ? statement.id.range[1] : statement.range[0] + statement.id + ? /** @type {Range} */ (statement.id.range)[1] + : /** @type {Range} */ (statement.range)[0] ) ) { InnerGraph.setTopLevelSymbol(parser.state, fn); @@ -239,21 +269,55 @@ class InnerGraphPlugin { ); parser.hooks.classBodyElement.tap( - "InnerGraphPlugin", - (element, statement) => { + PLUGIN_NAME, + (element, classDefinition) => { if (!InnerGraph.isEnabled(parser.state)) return; if (parser.scope.topLevelScope === true) { - const fn = classWithTopLevelSymbol.get(statement); + const fn = classWithTopLevelSymbol.get(classDefinition); if (fn) { - if (element.type === "MethodDefinition") { - InnerGraph.setTopLevelSymbol(parser.state, fn); - } else if ( - element.type === "ClassProperty" && - !element.static + InnerGraph.setTopLevelSymbol(parser.state, undefined); + } + } + } + ); + + parser.hooks.classBodyValue.tap( + PLUGIN_NAME, + (expression, element, classDefinition) => { + if (!InnerGraph.isEnabled(parser.state)) return; + if (parser.scope.topLevelScope === true) { + const fn = classWithTopLevelSymbol.get(classDefinition); + if (fn) { + if ( + !element.static || + parser.isPure( + expression, + element.key + ? /** @type {Range} */ (element.key.range)[1] + : /** @type {Range} */ (element.range)[0] + ) ) { - // TODO add test case once acorn supports it - // Currently this is not parsable InnerGraph.setTopLevelSymbol(parser.state, fn); + if (element.type !== "MethodDefinition" && element.static) { + InnerGraph.onUsage(parser.state, usedByExports => { + switch (usedByExports) { + case undefined: + case true: + return; + default: { + const dep = new PureExpressionDependency( + /** @type {Range} */ (expression.range) + ); + dep.loc = + /** @type {DependencyLocation} */ + (expression.loc); + dep.usedByExports = usedByExports; + parser.state.module.addDependency(dep); + break; + } + } + }); + } } else { InnerGraph.setTopLevelSymbol(parser.state, undefined); } @@ -262,7 +326,7 @@ class InnerGraphPlugin { } ); - parser.hooks.declarator.tap("InnerGraphPlugin", (decl, statement) => { + parser.hooks.declarator.tap(PLUGIN_NAME, (decl, statement) => { if (!InnerGraph.isEnabled(parser.state)) return; const fn = declWithTopLevelSymbol.get(decl); @@ -281,9 +345,9 @@ class InnerGraphPlugin { return; default: { const dep = new PureExpressionDependency( - decl.init.range + /** @type {Range} */ (decl.init.range) ); - dep.loc = decl.loc; + dep.loc = /** @type {DependencyLocation} */ (decl.loc); dep.usedByExports = usedByExports; parser.state.module.addDependency(dep); break; @@ -295,13 +359,24 @@ class InnerGraphPlugin { parser.walkExpression(decl.init); InnerGraph.setTopLevelSymbol(parser.state, undefined); return true; + } else if ( + decl.id.type === "Identifier" && + decl.init && + decl.init.type === "ClassExpression" && + classWithTopLevelSymbol.has(decl.init) + ) { + parser.walkExpression(decl.init); + InnerGraph.setTopLevelSymbol(parser.state, undefined); + return true; } }); parser.hooks.expression .for(topLevelSymbolTag) - .tap("InnerGraphPlugin", () => { - const topLevelSymbol = /** @type {TopLevelSymbol} */ (parser.currentTagData); + .tap(PLUGIN_NAME, () => { + const topLevelSymbol = /** @type {TopLevelSymbol} */ ( + parser.currentTagData + ); const currentTopLevelSymbol = InnerGraph.getTopLevelSymbol( parser.state ); @@ -311,21 +386,19 @@ class InnerGraphPlugin { currentTopLevelSymbol || true ); }); - parser.hooks.assign - .for(topLevelSymbolTag) - .tap("InnerGraphPlugin", expr => { - if (!InnerGraph.isEnabled(parser.state)) return; - if (expr.operator === "=") return true; - }); + parser.hooks.assign.for(topLevelSymbolTag).tap(PLUGIN_NAME, expr => { + if (!InnerGraph.isEnabled(parser.state)) return; + if (expr.operator === "=") return true; + }); }; normalModuleFactory.hooks.parser - .for("javascript/auto") - .tap("InnerGraphPlugin", handler); + .for(JAVASCRIPT_MODULE_TYPE_AUTO) + .tap(PLUGIN_NAME, handler); normalModuleFactory.hooks.parser - .for("javascript/esm") - .tap("InnerGraphPlugin", handler); + .for(JAVASCRIPT_MODULE_TYPE_ESM) + .tap(PLUGIN_NAME, handler); - compilation.hooks.finishModules.tap("InnerGraphPlugin", () => { + compilation.hooks.finishModules.tap(PLUGIN_NAME, () => { logger.timeAggregateEnd("infer dependency usage"); }); } diff --git a/lib/optimize/LimitChunkCountPlugin.js b/lib/optimize/LimitChunkCountPlugin.js index fef5c991e79..fc555e09aad 100644 --- a/lib/optimize/LimitChunkCountPlugin.js +++ b/lib/optimize/LimitChunkCountPlugin.js @@ -5,19 +5,26 @@ "use strict"; -const { validate } = require("schema-utils"); -const schema = require("../../schemas/plugins/optimize/LimitChunkCountPlugin.json"); const { STAGE_ADVANCED } = require("../OptimizationStages"); const LazyBucketSortedSet = require("../util/LazyBucketSortedSet"); const { compareChunks } = require("../util/comparators"); +const createSchemaValidation = require("../util/create-schema-validation"); +/** @typedef {import("../../declarations/plugins/optimize/LimitChunkCountPlugin").LimitChunkCountPluginOptions} LimitChunkCountPluginOptions */ /** @typedef {import("../Chunk")} Chunk */ /** @typedef {import("../Compiler")} Compiler */ -/** @typedef {import("../../declarations/plugins/optimize/LimitChunkCountPlugin").LimitChunkCountPluginOptions} LimitChunkCountPluginOptions */ +const validate = createSchemaValidation( + require("../../schemas/plugins/optimize/LimitChunkCountPlugin.check.js"), + () => require("../../schemas/plugins/optimize/LimitChunkCountPlugin.json"), + { + name: "Limit Chunk Count Plugin", + baseDataPath: "options" + } +); /** - * @typedef {Object} ChunkCombination + * @typedef {object} ChunkCombination * @property {boolean} deleted this is set to true when combination was removed * @property {number} sizeDiff * @property {number} integratedSize @@ -29,6 +36,12 @@ const { compareChunks } = require("../util/comparators"); * @property {number} bSize */ +/** + * @template K, V + * @param {Map>} map map + * @param {K} key key + * @param {V} value value + */ const addToSetMap = (map, key, value) => { const set = map.get(key); if (set === undefined) { @@ -43,10 +56,7 @@ class LimitChunkCountPlugin { * @param {LimitChunkCountPluginOptions=} options options object */ constructor(options) { - validate(schema, options, { - name: "Limit Chunk Count Plugin", - baseDataPath: "options" - }); + validate(options); this.options = options; } @@ -64,7 +74,9 @@ class LimitChunkCountPlugin { }, chunks => { const chunkGraph = compilation.chunkGraph; - const maxChunks = options.maxChunks; + const maxChunks = + /** @type {LimitChunkCountPluginOptions} */ + (options).maxChunks; if (!maxChunks) return; if (maxChunks < 1) return; if (compilation.chunks.size <= maxChunks) return; @@ -84,9 +96,17 @@ class LimitChunkCountPlugin { c => c.sizeDiff, (a, b) => b - a, // Layer 2: ordered by smallest combined size + /** + * @param {ChunkCombination} c combination + * @returns {number} integrated size + */ c => c.integratedSize, (a, b) => a - b, // Layer 3: ordered by position difference in orderedChunk (-> to be deterministic) + /** + * @param {ChunkCombination} c combination + * @returns {number} position difference + */ c => c.bIdx - c.aIdx, (a, b) => a - b, // Layer 4: ordered by position in orderedChunk (-> to be deterministic) @@ -99,7 +119,7 @@ class LimitChunkCountPlugin { /** @type {Map>} */ const combinationsByChunk = new Map(); - orderedChunks.forEach((b, bIdx) => { + for (const [bIdx, b] of orderedChunks.entries()) { // create combination pairs with size and integrated size for (let aIdx = 0; aIdx < bIdx; aIdx++) { const a = orderedChunks[aIdx]; @@ -129,8 +149,7 @@ class LimitChunkCountPlugin { addToSetMap(combinationsByChunk, a, c); addToSetMap(combinationsByChunk, b, c); } - return combinations; - }); + } // list of modified chunks during this run // combinations affected by this change are skipped to allow @@ -139,7 +158,6 @@ class LimitChunkCountPlugin { const modifiedChunks = new Set(); let changed = false; - // eslint-disable-next-line no-constant-condition loop: while (true) { const combination = combinations.popFirst(); if (combination === undefined) break; @@ -175,7 +193,8 @@ class LimitChunkCountPlugin { } // merge the chunks - if (a.integrate(b, "limit")) { + if (chunkGraph.canChunksBeIntegrated(a, b)) { + chunkGraph.integrateChunks(a, b); compilation.chunks.delete(b); // flag chunk a as modified as further optimization are possible for all children here @@ -188,14 +207,18 @@ class LimitChunkCountPlugin { // Update all affected combinations // delete all combination with the removed chunk // we will use combinations with the kept chunk instead - for (const combination of combinationsByChunk.get(a)) { + for (const combination of /** @type {Set} */ ( + combinationsByChunk.get(a) + )) { if (combination.deleted) continue; combination.deleted = true; combinations.delete(combination); } // Update combinations with the kept chunk with new sizes - for (const combination of combinationsByChunk.get(b)) { + for (const combination of /** @type {Set} */ ( + combinationsByChunk.get(b) + )) { if (combination.deleted) continue; if (combination.a === b) { if (!chunkGraph.canChunksBeIntegrated(a, combination.b)) { @@ -204,7 +227,8 @@ class LimitChunkCountPlugin { continue; } // Update size - const newIntegratedSize = a.integratedSize( + const newIntegratedSize = chunkGraph.getIntegratedChunksSize( + a, combination.b, options ); @@ -222,10 +246,12 @@ class LimitChunkCountPlugin { continue; } // Update size - const newIntegratedSize = combination.a.integratedSize( + const newIntegratedSize = chunkGraph.getIntegratedChunksSize( + combination.a, a, options ); + const finishUpdate = combinations.startUpdate(combination); combination.b = a; combination.integratedSize = newIntegratedSize; @@ -235,7 +261,12 @@ class LimitChunkCountPlugin { finishUpdate(); } } - combinationsByChunk.set(a, combinationsByChunk.get(b)); + combinationsByChunk.set( + a, + /** @type {Set} */ ( + combinationsByChunk.get(b) + ) + ); combinationsByChunk.delete(b); } } diff --git a/lib/optimize/MangleExportsPlugin.js b/lib/optimize/MangleExportsPlugin.js index 5cdc5679fa1..b1dbff26989 100644 --- a/lib/optimize/MangleExportsPlugin.js +++ b/lib/optimize/MangleExportsPlugin.js @@ -39,13 +39,28 @@ const comparator = compareSelect(e => e.name, compareStringsNumeric); /** * @param {boolean} deterministic use deterministic names * @param {ExportsInfo} exportsInfo exports info + * @param {boolean | undefined} isNamespace is namespace object * @returns {void} */ -const mangleExportsInfo = (deterministic, exportsInfo) => { +const mangleExportsInfo = (deterministic, exportsInfo, isNamespace) => { if (!canMangle(exportsInfo)) return; const usedNames = new Set(); /** @type {ExportInfo[]} */ const mangleableExports = []; + + // Avoid to renamed exports that are not provided when + // 1. it's not a namespace export: non-provided exports can be found in prototype chain + // 2. there are other provided exports and deterministic mode is chosen: + // non-provided exports would break the determinism + let avoidMangleNonProvided = !isNamespace; + if (!avoidMangleNonProvided && deterministic) { + for (const exportInfo of exportsInfo.ownedExports) { + if (exportInfo.provided !== false) { + avoidMangleNonProvided = true; + break; + } + } + } for (const exportInfo of exportsInfo.ownedExports) { const name = exportInfo.name; if (!exportInfo.hasUsedName()) { @@ -59,7 +74,7 @@ const mangleExportsInfo = (deterministic, exportsInfo) => { name.length === 2 && /^[a-zA-Z_$][a-zA-Z0-9_$]|^[1-9][0-9]/.test(name)) || // Don't rename exports that are not provided - exportInfo.provided !== true + (avoidMangleNonProvided && exportInfo.provided !== true) ) { exportInfo.setUsedName(name); usedNames.add(name); @@ -73,7 +88,11 @@ const mangleExportsInfo = (deterministic, exportsInfo) => { used === UsageState.OnlyPropertiesUsed || used === UsageState.Unused ) { - mangleExportsInfo(deterministic, exportInfo.exportsInfo); + mangleExportsInfo( + deterministic, + /** @type {ExportsInfo} */ (exportInfo.exportsInfo), + false + ); } } } @@ -130,6 +149,7 @@ class MangleExportsPlugin { constructor(deterministic) { this._deterministic = deterministic; } + /** * Apply the plugin * @param {Compiler} compiler the compiler instance @@ -142,9 +162,16 @@ class MangleExportsPlugin { compilation.hooks.optimizeCodeGeneration.tap( "MangleExportsPlugin", modules => { + if (compilation.moduleMemCaches) { + throw new Error( + "optimization.mangleExports can't be used with cacheUnaffected as export mangling is a global effect" + ); + } for (const module of modules) { + const isNamespace = + module.buildMeta && module.buildMeta.exportsType === "namespace"; const exportsInfo = moduleGraph.getExportsInfo(module); - mangleExportsInfo(deterministic, exportsInfo); + mangleExportsInfo(deterministic, exportsInfo, isNamespace); } } ); diff --git a/lib/optimize/MinChunkSizePlugin.js b/lib/optimize/MinChunkSizePlugin.js index a9feafecd53..b51164c27d9 100644 --- a/lib/optimize/MinChunkSizePlugin.js +++ b/lib/optimize/MinChunkSizePlugin.js @@ -5,24 +5,28 @@ "use strict"; -const { validate } = require("schema-utils"); -const schema = require("../../schemas/plugins/optimize/MinChunkSizePlugin.json"); const { STAGE_ADVANCED } = require("../OptimizationStages"); +const createSchemaValidation = require("../util/create-schema-validation"); +/** @typedef {import("../../declarations/plugins/optimize/MinChunkSizePlugin").MinChunkSizePluginOptions} MinChunkSizePluginOptions */ /** @typedef {import("../Chunk")} Chunk */ /** @typedef {import("../Compiler")} Compiler */ -/** @typedef {import("../../declarations/plugins/optimize/MinChunkSizePlugin").MinChunkSizePluginOptions} MinChunkSizePluginOptions */ +const validate = createSchemaValidation( + require("../../schemas/plugins/optimize/MinChunkSizePlugin.check.js"), + () => require("../../schemas/plugins/optimize/MinChunkSizePlugin.json"), + { + name: "Min Chunk Size Plugin", + baseDataPath: "options" + } +); class MinChunkSizePlugin { /** * @param {MinChunkSizePluginOptions} options options object */ constructor(options) { - validate(schema, options, { - name: "Min Chunk Size Plugin", - baseDataPath: "options" - }); + validate(options); this.options = options; } diff --git a/lib/optimize/MinMaxSizeWarning.js b/lib/optimize/MinMaxSizeWarning.js index 4be267059a7..2cc845eb9f0 100644 --- a/lib/optimize/MinMaxSizeWarning.js +++ b/lib/optimize/MinMaxSizeWarning.js @@ -9,6 +9,11 @@ const SizeFormatHelpers = require("../SizeFormatHelpers"); const WebpackError = require("../WebpackError"); class MinMaxSizeWarning extends WebpackError { + /** + * @param {string[] | undefined} keys keys + * @param {number} minSize minimum size + * @param {number} maxSize maximum size + */ constructor(keys, minSize, maxSize) { let keysMessage = "Fallback cache group"; if (keys) { @@ -18,7 +23,7 @@ class MinMaxSizeWarning extends WebpackError { : `Cache group ${keys[0]}`; } super( - `SplitChunksPlugin\n` + + "SplitChunksPlugin\n" + `${keysMessage}\n` + `Configured minSize (${SizeFormatHelpers.formatSize(minSize)}) is ` + `bigger than maxSize (${SizeFormatHelpers.formatSize(maxSize)}).\n` + diff --git a/lib/optimize/ModuleConcatenationPlugin.js b/lib/optimize/ModuleConcatenationPlugin.js index b3f87ee27a3..49c145c6e06 100644 --- a/lib/optimize/ModuleConcatenationPlugin.js +++ b/lib/optimize/ModuleConcatenationPlugin.js @@ -23,11 +23,12 @@ const ConcatenatedModule = require("./ConcatenatedModule"); /** @typedef {import("../Compilation")} Compilation */ /** @typedef {import("../Compiler")} Compiler */ /** @typedef {import("../Module")} Module */ +/** @typedef {import("../Module").BuildInfo} BuildInfo */ /** @typedef {import("../RequestShortener")} RequestShortener */ /** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */ /** - * @typedef {Object} Statistics + * @typedef {object} Statistics * @property {number} cached * @property {number} alreadyInConfig * @property {number} invalidModule @@ -40,26 +41,34 @@ const ConcatenatedModule = require("./ConcatenatedModule"); * @property {number} added */ -const formatBailoutReason = msg => { - return "ModuleConcatenation bailout: " + msg; -}; +/** + * @param {string} msg message + * @returns {string} formatted message + */ +const formatBailoutReason = msg => `ModuleConcatenation bailout: ${msg}`; class ModuleConcatenationPlugin { - constructor(options) { - if (typeof options !== "object") options = {}; - this.options = options; - } - /** * Apply the plugin * @param {Compiler} compiler the compiler instance * @returns {void} */ apply(compiler) { + const { _backCompat: backCompat } = compiler; compiler.hooks.compilation.tap("ModuleConcatenationPlugin", compilation => { + if (compilation.moduleMemCaches) { + throw new Error( + "optimization.concatenateModules can't be used with cacheUnaffected as module concatenation is a global effect" + ); + } const moduleGraph = compilation.moduleGraph; + /** @type {Map string)>} */ const bailoutReasonMap = new Map(); + /** + * @param {Module} module the module + * @param {string | ((requestShortener: RequestShortener) => string)} reason the reason + */ const setBailoutReason = (module, reason) => { setInnerBailoutReason(module, reason); moduleGraph @@ -71,16 +80,30 @@ class ModuleConcatenationPlugin { ); }; + /** + * @param {Module} module the module + * @param {string | ((requestShortener: RequestShortener) => string)} reason the reason + */ const setInnerBailoutReason = (module, reason) => { bailoutReasonMap.set(module, reason); }; + /** + * @param {Module} module the module + * @param {RequestShortener} requestShortener the request shortener + * @returns {string | ((requestShortener: RequestShortener) => string) | undefined} the reason + */ const getInnerBailoutReason = (module, requestShortener) => { const reason = bailoutReasonMap.get(module); if (typeof reason === "function") return reason(requestShortener); return reason; }; + /** + * @param {Module} module the module + * @param {Module | function(RequestShortener): string} problem the problem + * @returns {(requestShortener: RequestShortener) => string} the reason + */ const formatBailoutWarning = (module, problem) => requestShortener => { if (typeof problem === "function") { return formatBailoutReason( @@ -97,15 +120,14 @@ class ModuleConcatenationPlugin { requestShortener )}${reasonWithPrefix}` ); - } else { - return formatBailoutReason( - `Cannot concat with ${module.readableIdentifier( - requestShortener - )} because of ${problem.readableIdentifier( - requestShortener - )}${reasonWithPrefix}` - ); } + return formatBailoutReason( + `Cannot concat with ${module.readableIdentifier( + requestShortener + )} because of ${problem.readableIdentifier( + requestShortener + )}${reasonWithPrefix}` + ); }; compilation.hooks.optimizeChunkModules.tapAsync( @@ -137,13 +159,13 @@ class ModuleConcatenationPlugin { // Must not be an async module if (moduleGraph.isAsync(module)) { - setBailoutReason(module, `Module is async`); + setBailoutReason(module, "Module is async"); continue; } // Must be in strict mode - if (!module.buildInfo.strict) { - setBailoutReason(module, `Module is not in strict mode`); + if (!(/** @type {BuildInfo} */ (module.buildInfo).strict)) { + setBailoutReason(module, "Module is not in strict mode"); continue; } @@ -156,11 +178,10 @@ class ModuleConcatenationPlugin { // Exports must be known (and not dynamic) const exportsInfo = moduleGraph.getExportsInfo(module); const relevantExports = exportsInfo.getRelevantExports(undefined); - const unknownReexports = relevantExports.filter(exportInfo => { - return ( + const unknownReexports = relevantExports.filter( + exportInfo => exportInfo.isReexport() && !exportInfo.getTarget(moduleGraph) - ); - }); + ); if (unknownReexports.length > 0) { setBailoutReason( module, @@ -177,9 +198,7 @@ class ModuleConcatenationPlugin { // Root modules must have a static list of exports const unknownProvidedExports = relevantExports.filter( - exportInfo => { - return exportInfo.provided !== true; - } + exportInfo => exportInfo.provided !== true ); if (unknownProvidedExports.length > 0) { setBailoutReason( @@ -212,9 +231,11 @@ class ModuleConcatenationPlugin { // modules with lower depth are more likely suited as roots // this improves performance, because modules already selected as inner are skipped logger.time("sort relevant modules"); - relevantModules.sort((a, b) => { - return moduleGraph.getDepth(a) - moduleGraph.getDepth(b); - }); + relevantModules.sort( + (a, b) => + /** @type {number} */ (moduleGraph.getDepth(a)) - + /** @type {number} */ (moduleGraph.getDepth(b)) + ); logger.timeEnd("sort relevant modules"); /** @type {Statistics} */ @@ -243,7 +264,7 @@ class ModuleConcatenationPlugin { // TODO reconsider that when it's only used in a different runtime if (usedAsInner.has(currentRoot)) continue; - let chunkRuntime = undefined; + let chunkRuntime; for (const r of chunkGraph.getModuleRuntimes(currentRoot)) { chunkRuntime = mergeRuntimeOwned(chunkRuntime, r); } @@ -255,8 +276,8 @@ class ModuleConcatenationPlugin { filteredRuntime === true ? chunkRuntime : filteredRuntime === false - ? undefined - : filteredRuntime; + ? undefined + : filteredRuntime; // create a configuration with the root const currentConfiguration = new ConcatConfiguration( @@ -316,9 +337,8 @@ class ModuleConcatenationPlugin { } } else { statsEmptyConfigurations++; - const optimizationBailouts = moduleGraph.getOptimizationBailout( - currentRoot - ); + const optimizationBailouts = + moduleGraph.getOptimizationBailout(currentRoot); for (const warning of currentConfiguration.getWarningsSorted()) { optimizationBailouts.push( formatBailoutWarning(warning[0], warning[1]) @@ -341,11 +361,9 @@ class ModuleConcatenationPlugin { // to get the biggest groups possible. Used modules are marked with usedModules // TODO: Allow to reuse existing configuration while trying to add dependencies. // This would improve performance. O(n^2) -> O(n) - logger.time(`sort concat configurations`); - concatConfigurations.sort((a, b) => { - return b.modules.size - a.modules.size; - }); - logger.timeEnd(`sort concat configurations`); + logger.time("sort concat configurations"); + concatConfigurations.sort((a, b) => b.modules.size - a.modules.size); + logger.timeEnd("sort concat configurations"); const usedModules = new Set(); logger.time("create concatenated modules"); @@ -363,11 +381,14 @@ class ModuleConcatenationPlugin { } // Create a new ConcatenatedModule - let newModule = ConcatenatedModule.create( + ConcatenatedModule.getCompilationHooks(compilation); + const newModule = ConcatenatedModule.create( rootModule, modules, concatConfiguration.runtime, - compiler.root + compilation, + compiler.root, + compilation.outputOptions.hashFunction ); const build = () => { @@ -389,8 +410,10 @@ class ModuleConcatenationPlugin { }; const integrate = () => { - ChunkGraph.setChunkGraphForModule(newModule, chunkGraph); - ModuleGraph.setModuleGraphForModule(newModule, moduleGraph); + if (backCompat) { + ChunkGraph.setChunkGraphForModule(newModule, chunkGraph); + ModuleGraph.setModuleGraphForModule(newModule, moduleGraph); + } for (const warning of concatConfiguration.getWarningsSorted()) { moduleGraph @@ -408,21 +431,32 @@ class ModuleConcatenationPlugin { moduleGraph.copyOutgoingModuleConnections( m, newModule, - c => { - return ( - c.originModule === m && - !( - c.dependency instanceof HarmonyImportDependency && - modules.has(c.module) - ) - ); - } + c => + c.originModule === m && + !( + c.dependency instanceof HarmonyImportDependency && + modules.has(c.module) + ) ); // remove module from chunk for (const chunk of chunkGraph.getModuleChunksIterable( rootModule )) { - chunkGraph.disconnectChunkAndModule(chunk, m); + const sourceTypes = chunkGraph.getChunkModuleSourceTypes( + chunk, + m + ); + if (sourceTypes.size === 1) { + chunkGraph.disconnectChunkAndModule(chunk, m); + } else { + const newSourceTypes = new Set(sourceTypes); + newSourceTypes.delete("javascript"); + chunkGraph.setChunkModuleSourceTypes( + chunk, + m, + newSourceTypes + ); + } } } } @@ -438,7 +472,7 @@ class ModuleConcatenationPlugin { c.module === rootModule ? c.originModule : c.module; const innerConnection = c.dependency instanceof HarmonyImportDependency && - modules.has(otherModule); + modules.has(/** @type {Module} */ (otherModule)); return !innerConnection; }); // add concatenated module to the compilation @@ -451,7 +485,7 @@ class ModuleConcatenationPlugin { }, err => { logger.timeEnd("create concatenated modules"); - process.nextTick(() => callback(err)); + process.nextTick(callback.bind(null, err)); } ); } @@ -511,7 +545,7 @@ class ModuleConcatenationPlugin { * @param {ChunkGraph} chunkGraph the chunk graph * @param {boolean} avoidMutateOnFailure avoid mutating the config when adding fails * @param {Statistics} statistics gathering metrics - * @returns {Module | function(RequestShortener): string} the problematic module + * @returns {null | Module | function(RequestShortener): string} the problematic module */ _tryToAdd( compilation, @@ -550,6 +584,10 @@ class ModuleConcatenationPlugin { chunkGraph.getModuleChunksIterable(config.rootModule) ).filter(chunk => !chunkGraph.isModuleInChunk(module, chunk)); if (missingChunks.length > 0) { + /** + * @param {RequestShortener} requestShortener request shortener + * @returns {string} problem description + */ const problem = requestShortener => { const missingChunksList = Array.from( new Set(missingChunks.map(chunk => chunk.name || "unnamed chunk(s)")) @@ -574,21 +612,23 @@ class ModuleConcatenationPlugin { const moduleGraph = compilation.moduleGraph; - const incomingConnections = moduleGraph.getIncomingConnectionsByOriginModule( - module - ); + const incomingConnections = + moduleGraph.getIncomingConnectionsByOriginModule(module); const incomingConnectionsFromNonModules = incomingConnections.get(null) || incomingConnections.get(undefined); if (incomingConnectionsFromNonModules) { - const activeNonModulesConnections = incomingConnectionsFromNonModules.filter( - connection => { + const activeNonModulesConnections = + incomingConnectionsFromNonModules.filter(connection => // We are not interested in inactive connections // or connections without dependency - return connection.isActive(runtime) || connection.dependency; - } - ); + connection.isActive(runtime) + ); if (activeNonModulesConnections.length > 0) { + /** + * @param {RequestShortener} requestShortener request shortener + * @returns {string} problem description + */ const problem = requestShortener => { const importingExplanations = new Set( activeNonModulesConnections.map(c => c.explanation).filter(Boolean) @@ -616,7 +656,7 @@ class ModuleConcatenationPlugin { if (chunkGraph.getNumberOfModuleChunks(originModule) === 0) continue; // We don't care for connections from other runtimes - let originRuntime = undefined; + let originRuntime; for (const r of chunkGraph.getModuleRuntimes(originModule)) { originRuntime = mergeRuntimeOwned(originRuntime, r); } @@ -646,6 +686,10 @@ class ModuleConcatenationPlugin { return false; }); if (otherChunkModules.length > 0) { + /** + * @param {RequestShortener} requestShortener request shortener + * @returns {string} problem description + */ const problem = requestShortener => { const names = otherChunkModules .map(m => m.readableIdentifier(requestShortener)) @@ -673,21 +717,26 @@ class ModuleConcatenationPlugin { nonHarmonyConnections.set(originModule, connections); } if (nonHarmonyConnections.size > 0) { + /** + * @param {RequestShortener} requestShortener request shortener + * @returns {string} problem description + */ const problem = requestShortener => { const names = Array.from(nonHarmonyConnections) - .map(([originModule, connections]) => { - return `${originModule.readableIdentifier( - requestShortener - )} (referenced with ${Array.from( - new Set( - connections - .map(c => c.dependency && c.dependency.type) - .filter(Boolean) + .map( + ([originModule, connections]) => + `${originModule.readableIdentifier( + requestShortener + )} (referenced with ${Array.from( + new Set( + connections + .map(c => c.dependency && c.dependency.type) + .filter(Boolean) + ) ) - ) - .sort() - .join(", ")})`; - }) + .sort() + .join(", ")})` + ) .sort(); return `Module ${module.readableIdentifier( requestShortener @@ -711,19 +760,15 @@ class ModuleConcatenationPlugin { /** @type {false | RuntimeSpec} */ let currentRuntimeCondition = false; for (const connection of connections) { - const runtimeCondition = filterRuntime(runtime, runtime => { - return connection.isTargetActive(runtime); - }); + const runtimeCondition = filterRuntime(runtime, runtime => + connection.isTargetActive(runtime) + ); if (runtimeCondition === false) continue; if (runtimeCondition === true) continue outer; - if (currentRuntimeCondition !== false) { - currentRuntimeCondition = mergeRuntime( - currentRuntimeCondition, - runtimeCondition - ); - } else { - currentRuntimeCondition = runtimeCondition; - } + currentRuntimeCondition = + currentRuntimeCondition !== false + ? mergeRuntime(currentRuntimeCondition, runtimeCondition) + : runtimeCondition; } if (currentRuntimeCondition !== false) { otherRuntimeConnections.push({ @@ -733,8 +778,12 @@ class ModuleConcatenationPlugin { } } if (otherRuntimeConnections.length > 0) { - const problem = requestShortener => { - return `Module ${module.readableIdentifier( + /** + * @param {RequestShortener} requestShortener request shortener + * @returns {string} problem description + */ + const problem = requestShortener => + `Module ${module.readableIdentifier( requestShortener )} is runtime-dependent referenced by these modules: ${Array.from( otherRuntimeConnections, @@ -747,7 +796,6 @@ class ModuleConcatenationPlugin { /** @type {RuntimeSpec} */ (runtimeCondition) )})` ).join(", ")}`; - }; statistics.incorrectRuntimeCondition++; failureCache.set(module, problem); // cache failures for performance return problem; @@ -811,10 +859,17 @@ class ConcatConfiguration { this.warnings = new Map(); } + /** + * @param {Module} module the module + */ add(module) { this.modules.add(module); } + /** + * @param {Module} module the module + * @returns {boolean} true, when the module is in the module set + */ has(module) { return this.modules.has(module); } @@ -823,10 +878,17 @@ class ConcatConfiguration { return this.modules.size === 1; } + /** + * @param {Module} module the module + * @param {Module | function(RequestShortener): string} problem the problem + */ addWarning(module, problem) { this.warnings.set(module, problem); } + /** + * @returns {Map} warnings + */ getWarningsSorted() { return new Map( Array.from(this.warnings).sort((a, b) => { @@ -850,6 +912,9 @@ class ConcatConfiguration { return this.modules.size; } + /** + * @param {number} snapshot snapshot + */ rollback(snapshot) { const modules = this.modules; for (const m of modules) { diff --git a/lib/optimize/RealContentHashPlugin.js b/lib/optimize/RealContentHashPlugin.js index b9f26d5fef4..0cfd1c84f9f 100644 --- a/lib/optimize/RealContentHashPlugin.js +++ b/lib/optimize/RealContentHashPlugin.js @@ -13,11 +13,18 @@ const { compareSelect, compareStrings } = require("../util/comparators"); const createHash = require("../util/createHash"); /** @typedef {import("webpack-sources").Source} Source */ +/** @typedef {import("../Cache").Etag} Etag */ /** @typedef {import("../Compilation").AssetInfo} AssetInfo */ /** @typedef {import("../Compiler")} Compiler */ +/** @typedef {typeof import("../util/Hash")} Hash */ const EMPTY_SET = new Set(); +/** + * @template T + * @param {T | T[]} itemOrItems item or items + * @param {Set} list list + */ const addToList = (itemOrItems, list) => { if (Array.isArray(itemOrItems)) { for (const item of itemOrItems) { @@ -54,12 +61,14 @@ const mapAndDeduplicateBuffers = (input, fn) => { * @param {string} str String to quote * @returns {string} Escaped string */ -const quoteMeta = str => { - return str.replace(/[-[\]\\/{}()*+?.^$|]/g, "\\$&"); -}; +const quoteMeta = str => str.replace(/[-[\]\\/{}()*+?.^$|]/g, "\\$&"); const cachedSourceMap = new WeakMap(); +/** + * @param {Source} source source + * @returns {CachedSource} cached source + */ const toCachedSource = source => { if (source instanceof CachedSource) { return source; @@ -71,23 +80,27 @@ const toCachedSource = source => { return newSource; }; +/** @typedef {Set} OwnHashes */ +/** @typedef {Set} ReferencedHashes */ +/** @typedef {Set} Hashes */ + /** - * @typedef {Object} AssetInfoForRealContentHash + * @typedef {object} AssetInfoForRealContentHash * @property {string} name * @property {AssetInfo} info * @property {Source} source * @property {RawSource | undefined} newSource * @property {RawSource | undefined} newSourceWithoutOwn * @property {string} content - * @property {Set} ownHashes - * @property {Promise} contentComputePromise - * @property {Promise} contentComputeWithoutOwnPromise - * @property {Set} referencedHashes - * @property {Set} hashes + * @property {OwnHashes | undefined} ownHashes + * @property {Promise | undefined} contentComputePromise + * @property {Promise | undefined} contentComputeWithoutOwnPromise + * @property {ReferencedHashes | undefined} referencedHashes + * @property {Hashes} hashes */ /** - * @typedef {Object} CompilationHooks + * @typedef {object} CompilationHooks * @property {SyncBailHook<[Buffer[], string], string>} updateHash */ @@ -115,6 +128,11 @@ class RealContentHashPlugin { return hooks; } + /** + * @param {object} options options object + * @param {string | Hash} options.hashFunction the hash function to use + * @param {string} options.hashDigest the hash digest to use + */ constructor({ hashFunction, hashDigest }) { this._hashFunction = hashFunction; this._hashDigest = hashDigest; @@ -143,27 +161,25 @@ class RealContentHashPlugin { const assets = compilation.getAssets(); /** @type {AssetInfoForRealContentHash[]} */ const assetsWithInfo = []; + /** @type {Map} */ const hashToAssets = new Map(); for (const { source, info, name } of assets) { const cachedSource = toCachedSource(source); - const content = cachedSource.source(); - /** @type {Set} */ + const content = /** @type {string} */ (cachedSource.source()); + /** @type {Hashes} */ const hashes = new Set(); addToList(info.contenthash, hashes); + /** @type {AssetInfoForRealContentHash} */ const data = { name, info, source: cachedSource, - /** @type {RawSource | undefined} */ newSource: undefined, - /** @type {RawSource | undefined} */ newSourceWithoutOwn: undefined, content, - /** @type {Set} */ ownHashes: undefined, contentComputePromise: undefined, contentComputeWithoutOwnPromise: undefined, - /** @type {Set} */ referencedHashes: undefined, hashes }; @@ -194,31 +210,35 @@ class RealContentHashPlugin { cacheAnalyse.getLazyHashedEtag(source), Array.from(hashes).join("|") ); - [ - asset.referencedHashes, - asset.ownHashes - ] = await cacheAnalyse.providePromise(name, etag, () => { - const referencedHashes = new Set(); - let ownHashes = new Set(); - const inContent = content.match(hashRegExp); - if (inContent) { - for (const hash of inContent) { - if (hashes.has(hash)) { - ownHashes.add(hash); - continue; + [asset.referencedHashes, asset.ownHashes] = + await cacheAnalyse.providePromise(name, etag, () => { + const referencedHashes = new Set(); + const ownHashes = new Set(); + const inContent = content.match(hashRegExp); + if (inContent) { + for (const hash of inContent) { + if (hashes.has(hash)) { + ownHashes.add(hash); + continue; + } + referencedHashes.add(hash); } - referencedHashes.add(hash); } - } - return [referencedHashes, ownHashes]; - }); + return [referencedHashes, ownHashes]; + }); }) ); + /** + * @param {string} hash the hash + * @returns {undefined | ReferencedHashes} the referenced hashes + */ const getDependencies = hash => { const assets = hashToAssets.get(hash); if (!assets) { const referencingAssets = assetsWithInfo.filter(asset => - asset.referencedHashes.has(hash) + /** @type {ReferencedHashes} */ (asset.referencedHashes).has( + hash + ) ); const err = new WebpackError(`RealContentHashPlugin Some kind of unexpected caching problem occurred. @@ -234,27 +254,40 @@ ${referencingAssets }) .join("\n")}`); compilation.errors.push(err); - return undefined; + return; } const hashes = new Set(); for (const { referencedHashes, ownHashes } of assets) { - if (!ownHashes.has(hash)) { - for (const hash of ownHashes) { + if (!(/** @type {OwnHashes} */ (ownHashes).has(hash))) { + for (const hash of /** @type {OwnHashes} */ (ownHashes)) { hashes.add(hash); } } - for (const hash of referencedHashes) { + for (const hash of /** @type {ReferencedHashes} */ ( + referencedHashes + )) { hashes.add(hash); } } return hashes; }; + /** + * @param {string} hash the hash + * @returns {string} the hash info + */ const hashInfo = hash => { const assets = hashToAssets.get(hash); - return `${hash} (${Array.from(assets, a => a.name)})`; + return `${hash} (${Array.from( + /** @type {AssetInfoForRealContentHash[]} */ (assets), + a => a.name + )})`; }; const hashesInOrder = new Set(); for (const hash of hashToAssets.keys()) { + /** + * @param {string} hash the hash + * @param {Set} stack stack of hashes + */ const add = (hash, stack) => { const deps = getDependencies(hash); if (!deps) return; @@ -278,21 +311,31 @@ ${referencingAssets add(hash, new Set()); } const hashToNewHash = new Map(); + /** + * @param {AssetInfoForRealContentHash} asset asset info + * @returns {Etag} etag + */ const getEtag = asset => cacheGenerate.mergeEtags( cacheGenerate.getLazyHashedEtag(asset.source), - Array.from(asset.referencedHashes, hash => - hashToNewHash.get(hash) + Array.from( + /** @type {ReferencedHashes} */ (asset.referencedHashes), + hash => hashToNewHash.get(hash) ).join("|") ); + /** + * @param {AssetInfoForRealContentHash} asset asset info + * @returns {Promise} + */ const computeNewContent = asset => { if (asset.contentComputePromise) return asset.contentComputePromise; return (asset.contentComputePromise = (async () => { if ( - asset.ownHashes.size > 0 || - Array.from(asset.referencedHashes).some( - hash => hashToNewHash.get(hash) !== hash - ) + /** @type {OwnHashes} */ (asset.ownHashes).size > 0 || + Array.from( + /** @type {ReferencedHashes} */ + (asset.referencedHashes) + ).some(hash => hashToNewHash.get(hash) !== hash) ) { const identifier = asset.name; const etag = getEtag(asset); @@ -309,17 +352,22 @@ ${referencingAssets } })()); }; + /** + * @param {AssetInfoForRealContentHash} asset asset info + * @returns {Promise} + */ const computeNewContentWithoutOwn = asset => { if (asset.contentComputeWithoutOwnPromise) return asset.contentComputeWithoutOwnPromise; return (asset.contentComputeWithoutOwnPromise = (async () => { if ( - asset.ownHashes.size > 0 || - Array.from(asset.referencedHashes).some( - hash => hashToNewHash.get(hash) !== hash - ) + /** @type {OwnHashes} */ (asset.ownHashes).size > 0 || + Array.from( + /** @type {ReferencedHashes} */ + (asset.referencedHashes) + ).some(hash => hashToNewHash.get(hash) !== hash) ) { - const identifier = asset.name + "|without-own"; + const identifier = `${asset.name}|without-own`; const etag = getEtag(asset); asset.newSourceWithoutOwn = await cacheGenerate.providePromise( identifier, @@ -328,7 +376,9 @@ ${referencingAssets const newContent = asset.content.replace( hashRegExp, hash => { - if (asset.ownHashes.has(hash)) { + if ( + /** @type {OwnHashes} */ (asset.ownHashes).has(hash) + ) { return ""; } return hashToNewHash.get(hash); @@ -342,29 +392,33 @@ ${referencingAssets }; const comparator = compareSelect(a => a.name, compareStrings); for (const oldHash of hashesInOrder) { - const assets = hashToAssets.get(oldHash); + const assets = + /** @type {AssetInfoForRealContentHash[]} */ + (hashToAssets.get(oldHash)); assets.sort(comparator); - const hash = createHash(this._hashFunction); await Promise.all( assets.map(asset => - asset.ownHashes.has(oldHash) + /** @type {OwnHashes} */ (asset.ownHashes).has(oldHash) ? computeNewContentWithoutOwn(asset) : computeNewContent(asset) ) ); const assetsContent = mapAndDeduplicateBuffers(assets, asset => { - if (asset.ownHashes.has(oldHash)) { + if (/** @type {OwnHashes} */ (asset.ownHashes).has(oldHash)) { return asset.newSourceWithoutOwn ? asset.newSourceWithoutOwn.buffer() : asset.source.buffer(); - } else { - return asset.newSource - ? asset.newSource.buffer() - : asset.source.buffer(); } + return asset.newSource + ? asset.newSource.buffer() + : asset.source.buffer(); }); let newHash = hooks.updateHash.call(assetsContent, oldHash); if (!newHash) { + const hash = createHash(this._hashFunction); + if (compilation.outputOptions.hashSalt) { + hash.update(compilation.outputOptions.hashSalt); + } for (const content of assetsContent) { hash.update(content); } diff --git a/lib/optimize/RemoveParentModulesPlugin.js b/lib/optimize/RemoveParentModulesPlugin.js index 4e089d85b1f..8c244ec5077 100644 --- a/lib/optimize/RemoveParentModulesPlugin.js +++ b/lib/optimize/RemoveParentModulesPlugin.js @@ -6,10 +6,58 @@ "use strict"; const { STAGE_BASIC } = require("../OptimizationStages"); -const Queue = require("../util/Queue"); -const { intersect } = require("../util/SetHelpers"); +/** @typedef {import("../Chunk")} Chunk */ +/** @typedef {import("../ChunkGroup")} ChunkGroup */ /** @typedef {import("../Compiler")} Compiler */ +/** @typedef {import("../Module")} Module */ + +/** + * Intersects multiple masks represented as bigints + * @param {bigint[]} masks The module masks to intersect + * @returns {bigint} The intersection of all masks + */ +function intersectMasks(masks) { + let result = masks[0]; + for (let i = masks.length - 1; i >= 1; i--) { + result &= masks[i]; + } + return result; +} + +const ZERO_BIGINT = BigInt(0); +const ONE_BIGINT = BigInt(1); +const THIRTY_TWO_BIGINT = BigInt(32); + +/** + * Parses the module mask and returns the modules represented by it + * @param {bigint} mask the module mask + * @param {Module[]} ordinalModules the modules in the order they were added to the mask (LSB is index 0) + * @returns {Generator} the modules represented by the mask + */ +function* getModulesFromMask(mask, ordinalModules) { + let offset = 31; + while (mask !== ZERO_BIGINT) { + // Consider the last 32 bits, since that's what Math.clz32 can handle + let last32 = Number(BigInt.asUintN(32, mask)); + while (last32 > 0) { + const last = Math.clz32(last32); + // The number of trailing zeros is the number trimmed off the input mask + 31 - the number of leading zeros + // The 32 is baked into the initial value of offset + const moduleIndex = offset - last; + // The number of trailing zeros is the index into the array generated by getOrCreateModuleMask + const module = ordinalModules[moduleIndex]; + yield module; + // Remove the matched module from the mask + // Since we can only count leading zeros, not trailing, we can't just downshift the mask + last32 &= ~(1 << (31 - last)); + } + + // Remove the processed chunk from the mask + mask >>= THIRTY_TWO_BIGINT; + offset += 32; + } +} class RemoveParentModulesPlugin { /** @@ -18,94 +66,129 @@ class RemoveParentModulesPlugin { */ apply(compiler) { compiler.hooks.compilation.tap("RemoveParentModulesPlugin", compilation => { + /** + * @param {Iterable} chunks the chunks + * @param {ChunkGroup[]} chunkGroups the chunk groups + */ const handler = (chunks, chunkGroups) => { const chunkGraph = compilation.chunkGraph; - const queue = new Queue(); + const queue = new Set(); const availableModulesMap = new WeakMap(); + let nextModuleMask = ONE_BIGINT; + const maskByModule = new WeakMap(); + /** @type {Module[]} */ + const ordinalModules = []; + + /** + * Gets or creates a unique mask for a module + * @param {Module} mod the module to get the mask for + * @returns {bigint} the module mask to uniquely identify the module + */ + const getOrCreateModuleMask = mod => { + let id = maskByModule.get(mod); + if (id === undefined) { + id = nextModuleMask; + ordinalModules.push(mod); + maskByModule.set(mod, id); + nextModuleMask <<= ONE_BIGINT; + } + return id; + }; + + // Initialize masks by chunk and by chunk group for quicker comparisons + const chunkMasks = new WeakMap(); + for (const chunk of chunks) { + let mask = ZERO_BIGINT; + for (const m of chunkGraph.getChunkModulesIterable(chunk)) { + const id = getOrCreateModuleMask(m); + mask |= id; + } + chunkMasks.set(chunk, mask); + } + + const chunkGroupMasks = new WeakMap(); + for (const chunkGroup of chunkGroups) { + let mask = ZERO_BIGINT; + for (const chunk of chunkGroup.chunks) { + const chunkMask = chunkMasks.get(chunk); + if (chunkMask !== undefined) { + mask |= chunkMask; + } + } + chunkGroupMasks.set(chunkGroup, mask); + } + for (const chunkGroup of compilation.entrypoints.values()) { // initialize available modules for chunks without parents - availableModulesMap.set(chunkGroup, new Set()); + availableModulesMap.set(chunkGroup, ZERO_BIGINT); for (const child of chunkGroup.childrenIterable) { - queue.enqueue(child); + queue.add(child); } } for (const chunkGroup of compilation.asyncEntrypoints) { // initialize available modules for chunks without parents - availableModulesMap.set(chunkGroup, new Set()); + availableModulesMap.set(chunkGroup, ZERO_BIGINT); for (const child of chunkGroup.childrenIterable) { - queue.enqueue(child); + queue.add(child); } } - while (queue.length > 0) { - const chunkGroup = queue.dequeue(); - let availableModules = availableModulesMap.get(chunkGroup); + for (const chunkGroup of queue) { + let availableModulesMask = availableModulesMap.get(chunkGroup); let changed = false; for (const parent of chunkGroup.parentsIterable) { const availableModulesInParent = availableModulesMap.get(parent); if (availableModulesInParent !== undefined) { + const parentMask = + availableModulesInParent | chunkGroupMasks.get(parent); // If we know the available modules in parent: process these - if (availableModules === undefined) { + if (availableModulesMask === undefined) { // if we have not own info yet: create new entry - availableModules = new Set(availableModulesInParent); - for (const chunk of parent.chunks) { - for (const m of chunkGraph.getChunkModulesIterable(chunk)) { - availableModules.add(m); - } - } - availableModulesMap.set(chunkGroup, availableModules); + availableModulesMask = parentMask; changed = true; } else { - for (const m of availableModules) { - if ( - !chunkGraph.isModuleInChunkGroup(m, parent) && - !availableModulesInParent.has(m) - ) { - availableModules.delete(m); - changed = true; - } + const newMask = availableModulesMask & parentMask; + if (newMask !== availableModulesMask) { + changed = true; + availableModulesMask = newMask; } } } } + if (changed) { + availableModulesMap.set(chunkGroup, availableModulesMask); // if something changed: enqueue our children for (const child of chunkGroup.childrenIterable) { - queue.enqueue(child); + // Push the child to the end of the queue + queue.delete(child); + queue.add(child); } } } // now we have available modules for every chunk for (const chunk of chunks) { + const chunkMask = chunkMasks.get(chunk); + if (chunkMask === undefined) continue; // No info about this chunk + const availableModulesSets = Array.from( chunk.groupsIterable, chunkGroup => availableModulesMap.get(chunkGroup) ); - if (availableModulesSets.some(s => s === undefined)) continue; // No info about this chunk group - const availableModules = - availableModulesSets.length === 1 - ? availableModulesSets[0] - : intersect(availableModulesSets); - const numberOfModules = chunkGraph.getNumberOfChunkModules(chunk); - const toRemove = new Set(); - if (numberOfModules < availableModules.size) { - for (const m of chunkGraph.getChunkModulesIterable(chunk)) { - if (availableModules.has(m)) { - toRemove.add(m); - } - } - } else { - for (const m of availableModules) { - if (chunkGraph.isModuleInChunk(m, chunk)) { - toRemove.add(m); - } + if (availableModulesSets.includes(undefined)) continue; // No info about this chunk group + + const availableModulesMask = intersectMasks(availableModulesSets); + const toRemoveMask = chunkMask & availableModulesMask; + if (toRemoveMask !== ZERO_BIGINT) { + for (const module of getModulesFromMask( + toRemoveMask, + ordinalModules + )) { + chunkGraph.disconnectChunkAndModule(chunk, module); } } - for (const module of toRemove) { - chunkGraph.disconnectChunkAndModule(chunk, module); - } } }; compilation.hooks.optimizeChunks.tap( diff --git a/lib/optimize/RuntimeChunkPlugin.js b/lib/optimize/RuntimeChunkPlugin.js index c657f57322d..1923e468303 100644 --- a/lib/optimize/RuntimeChunkPlugin.js +++ b/lib/optimize/RuntimeChunkPlugin.js @@ -5,11 +5,20 @@ "use strict"; +/** @typedef {import("../Compilation").EntryData} EntryData */ /** @typedef {import("../Compiler")} Compiler */ +/** @typedef {import("../Entrypoint")} Entrypoint */ class RuntimeChunkPlugin { + /** + * @param {{ name?: (entrypoint: { name: string }) => string }} options options + */ constructor(options) { this.options = { + /** + * @param {Entrypoint} entrypoint entrypoint name + * @returns {string} runtime chunk name + */ name: entrypoint => `runtime~${entrypoint.name}`, ...options }; @@ -26,10 +35,14 @@ class RuntimeChunkPlugin { "RuntimeChunkPlugin", (_, { name: entryName }) => { if (entryName === undefined) return; - const data = compilation.entries.get(entryName); - if (!data.options.runtime && !data.options.dependOn) { + const data = + /** @type {EntryData} */ + (compilation.entries.get(entryName)); + if (data.options.runtime === undefined && !data.options.dependOn) { // Determine runtime chunk name - let name = this.options.name; + let name = + /** @type {string | ((entrypoint: { name: string }) => string)} */ + (this.options.name); if (typeof name === "function") { name = name({ name: entryName }); } diff --git a/lib/optimize/SideEffectsFlagPlugin.js b/lib/optimize/SideEffectsFlagPlugin.js index 5afb5bacf06..8bfb6a5502c 100644 --- a/lib/optimize/SideEffectsFlagPlugin.js +++ b/lib/optimize/SideEffectsFlagPlugin.js @@ -6,30 +6,43 @@ "use strict"; const glob2regexp = require("glob-to-regexp"); +const { + JAVASCRIPT_MODULE_TYPE_AUTO, + JAVASCRIPT_MODULE_TYPE_ESM, + JAVASCRIPT_MODULE_TYPE_DYNAMIC +} = require("../ModuleTypeConstants"); const { STAGE_DEFAULT } = require("../OptimizationStages"); const HarmonyExportImportedSpecifierDependency = require("../dependencies/HarmonyExportImportedSpecifierDependency"); const HarmonyImportSpecifierDependency = require("../dependencies/HarmonyImportSpecifierDependency"); const formatLocation = require("../formatLocation"); +/** @typedef {import("estree").ModuleDeclaration} ModuleDeclaration */ +/** @typedef {import("estree").Statement} Statement */ /** @typedef {import("../Compiler")} Compiler */ /** @typedef {import("../Dependency")} Dependency */ +/** @typedef {import("../Dependency").DependencyLocation} DependencyLocation */ /** @typedef {import("../Module")} Module */ +/** @typedef {import("../Module").BuildMeta} BuildMeta */ +/** @typedef {import("../ModuleGraphConnection")} ModuleGraphConnection */ /** @typedef {import("../javascript/JavascriptParser")} JavascriptParser */ +/** @typedef {import("../javascript/JavascriptParser").Range} Range */ /** - * @typedef {Object} ExportInModule + * @typedef {object} ExportInModule * @property {Module} module the module * @property {string} exportName the name of the export * @property {boolean} checked if the export is conditional */ /** - * @typedef {Object} ReexportInfo + * @typedef {object} ReexportInfo * @property {Map} static * @property {Map>} dynamic */ -/** @type {WeakMap>} */ +/** @typedef {Map} CacheItem */ + +/** @type {WeakMap} */ const globToRegexpCache = new WeakMap(); /** @@ -45,11 +58,13 @@ const globToRegexp = (glob, cache) => { } const baseRegexp = glob2regexp(glob, { globstar: true, extended: true }); const regexpSource = baseRegexp.source; - const regexp = new RegExp("^(\\./)?" + regexpSource.slice(1)); + const regexp = new RegExp(`^(\\./)?${regexpSource.slice(1)}`); cache.set(glob, regexp); return regexp; }; +const PLUGIN_NAME = "SideEffectsFlagPlugin"; + class SideEffectsFlagPlugin { /** * @param {boolean} analyseSource analyse source code for side effects @@ -57,6 +72,7 @@ class SideEffectsFlagPlugin { constructor(analyseSource = true) { this._analyseSource = analyseSource; } + /** * Apply the plugin * @param {Compiler} compiler the compiler instance @@ -69,66 +85,64 @@ class SideEffectsFlagPlugin { globToRegexpCache.set(compiler.root, cache); } compiler.hooks.compilation.tap( - "SideEffectsFlagPlugin", + PLUGIN_NAME, (compilation, { normalModuleFactory }) => { const moduleGraph = compilation.moduleGraph; - normalModuleFactory.hooks.module.tap( - "SideEffectsFlagPlugin", - (module, data) => { - const resolveData = data.resourceResolveData; - if ( - resolveData && - resolveData.descriptionFileData && - resolveData.relativePath - ) { - const sideEffects = resolveData.descriptionFileData.sideEffects; - if (sideEffects !== undefined) { - if (module.factoryMeta === undefined) { - module.factoryMeta = {}; - } - const hasSideEffects = SideEffectsFlagPlugin.moduleHasSideEffects( - resolveData.relativePath, - sideEffects, - cache - ); - module.factoryMeta.sideEffectFree = !hasSideEffects; - } - } - - return module; - } - ); - normalModuleFactory.hooks.module.tap( - "SideEffectsFlagPlugin", - (module, data) => { - if (typeof data.settings.sideEffects === "boolean") { + normalModuleFactory.hooks.module.tap(PLUGIN_NAME, (module, data) => { + const resolveData = data.resourceResolveData; + if ( + resolveData && + resolveData.descriptionFileData && + resolveData.relativePath + ) { + const sideEffects = resolveData.descriptionFileData.sideEffects; + if (sideEffects !== undefined) { if (module.factoryMeta === undefined) { module.factoryMeta = {}; } - module.factoryMeta.sideEffectFree = !data.settings.sideEffects; + const hasSideEffects = SideEffectsFlagPlugin.moduleHasSideEffects( + resolveData.relativePath, + sideEffects, + /** @type {CacheItem} */ (cache) + ); + module.factoryMeta.sideEffectFree = !hasSideEffects; } - return module; } - ); + + return module; + }); + normalModuleFactory.hooks.module.tap(PLUGIN_NAME, (module, data) => { + if (typeof data.settings.sideEffects === "boolean") { + if (module.factoryMeta === undefined) { + module.factoryMeta = {}; + } + module.factoryMeta.sideEffectFree = !data.settings.sideEffects; + } + return module; + }); if (this._analyseSource) { /** * @param {JavascriptParser} parser the parser * @returns {void} */ const parserHandler = parser => { + /** @type {undefined | Statement | ModuleDeclaration} */ let sideEffectsStatement; - parser.hooks.program.tap("SideEffectsFlagPlugin", () => { + parser.hooks.program.tap(PLUGIN_NAME, () => { sideEffectsStatement = undefined; }); parser.hooks.statement.tap( - { name: "SideEffectsFlagPlugin", stage: -100 }, + { name: PLUGIN_NAME, stage: -100 }, statement => { if (sideEffectsStatement) return; if (parser.scope.topLevelScope !== true) return; switch (statement.type) { case "ExpressionStatement": if ( - !parser.isPure(statement.expression, statement.range[0]) + !parser.isPure( + statement.expression, + /** @type {Range} */ (statement.range)[0] + ) ) { sideEffectsStatement = statement; } @@ -136,27 +150,35 @@ class SideEffectsFlagPlugin { case "IfStatement": case "WhileStatement": case "DoWhileStatement": - if (!parser.isPure(statement.test, statement.range[0])) { + if ( + !parser.isPure( + statement.test, + /** @type {Range} */ (statement.range)[0] + ) + ) { sideEffectsStatement = statement; } // statement hook will be called for child statements too break; case "ForStatement": if ( - !parser.isPure(statement.init, statement.range[0]) || + !parser.isPure( + statement.init, + /** @type {Range} */ (statement.range)[0] + ) || !parser.isPure( statement.test, statement.init - ? statement.init.range[1] - : statement.range[0] + ? /** @type {Range} */ (statement.init.range)[1] + : /** @type {Range} */ (statement.range)[0] ) || !parser.isPure( statement.update, statement.test - ? statement.test.range[1] + ? /** @type {Range} */ (statement.test.range)[1] : statement.init - ? statement.init.range[1] - : statement.range[0] + ? /** @type {Range} */ (statement.init.range)[1] + : /** @type {Range} */ (statement.range)[0] ) ) { sideEffectsStatement = statement; @@ -165,7 +187,10 @@ class SideEffectsFlagPlugin { break; case "SwitchStatement": if ( - !parser.isPure(statement.discriminant, statement.range[0]) + !parser.isPure( + statement.discriminant, + /** @type {Range} */ (statement.range)[0] + ) ) { sideEffectsStatement = statement; } @@ -174,14 +199,22 @@ class SideEffectsFlagPlugin { case "VariableDeclaration": case "ClassDeclaration": case "FunctionDeclaration": - if (!parser.isPure(statement, statement.range[0])) { + if ( + !parser.isPure( + statement, + /** @type {Range} */ (statement.range)[0] + ) + ) { sideEffectsStatement = statement; } break; case "ExportNamedDeclaration": case "ExportDefaultDeclaration": if ( - !parser.isPure(statement.declaration, statement.range[0]) + !parser.isPure( + statement.declaration, + /** @type {Range} */ (statement.range)[0] + ) ) { sideEffectsStatement = statement; } @@ -202,9 +235,10 @@ class SideEffectsFlagPlugin { } } ); - parser.hooks.finish.tap("SideEffectsFlagPlugin", () => { + parser.hooks.finish.tap(PLUGIN_NAME, () => { if (sideEffectsStatement === undefined) { - parser.state.module.buildMeta.sideEffectFree = true; + /** @type {BuildMeta} */ + (parser.state.module.buildMeta).sideEffectFree = true; } else { const { loc, type } = sideEffectsStatement; moduleGraph @@ -212,25 +246,25 @@ class SideEffectsFlagPlugin { .push( () => `Statement (${type}) with side effects in source code at ${formatLocation( - loc + /** @type {DependencyLocation} */ (loc) )}` ); } }); }; for (const key of [ - "javascript/auto", - "javascript/esm", - "javascript/dynamic" + JAVASCRIPT_MODULE_TYPE_AUTO, + JAVASCRIPT_MODULE_TYPE_ESM, + JAVASCRIPT_MODULE_TYPE_DYNAMIC ]) { normalModuleFactory.hooks.parser .for(key) - .tap("SideEffectsFlagPlugin", parserHandler); + .tap(PLUGIN_NAME, parserHandler); } } compilation.hooks.optimizeDependencies.tap( { - name: "SideEffectsFlagPlugin", + name: PLUGIN_NAME, stage: STAGE_DEFAULT }, modules => { @@ -239,7 +273,15 @@ class SideEffectsFlagPlugin { ); logger.time("update dependencies"); - for (const module of modules) { + + const optimizedModules = new Set(); + + /** + * @param {Module} module module + */ + const optimizeIncomingConnections = module => { + if (optimizedModules.has(module)) return; + optimizedModules.add(module); if (module.getSideEffectsConnectionState(moduleGraph) === false) { const exportsInfo = moduleGraph.getExportsInfo(module); for (const connection of moduleGraph.getIncomingConnections( @@ -254,10 +296,13 @@ class SideEffectsFlagPlugin { (dep instanceof HarmonyImportSpecifierDependency && !dep.namespaceObjectAsContext) ) { + if (connection.originModule !== null) { + optimizeIncomingConnections(connection.originModule); + } // TODO improve for export * if (isReexport && dep.name) { const exportInfo = moduleGraph.getExportInfo( - connection.originModule, + /** @type {Module} */ (connection.originModule), dep.name ); exportInfo.moveTarget( @@ -278,7 +323,9 @@ class SideEffectsFlagPlugin { ? [...exportName, ...ids.slice(1)] : ids.slice(1) ); - return moduleGraph.getConnection(dep); + return /** @type {ModuleGraphConnection} */ ( + moduleGraph.getConnection(dep) + ); } ); continue; @@ -310,6 +357,10 @@ class SideEffectsFlagPlugin { } } } + }; + + for (const module of modules) { + optimizeIncomingConnections(module); } logger.timeEnd("update dependencies"); } @@ -318,6 +369,12 @@ class SideEffectsFlagPlugin { ); } + /** + * @param {string} moduleName the module name + * @param {undefined | boolean | string | string[]} flagValue the flag value + * @param {Map} cache cache for glob to regexp + * @returns {boolean | undefined} true, when the module has side effects, undefined or false when not + */ static moduleHasSideEffects(moduleName, flagValue, cache) { switch (typeof flagValue) { case "undefined": diff --git a/lib/optimize/SplitChunksPlugin.js b/lib/optimize/SplitChunksPlugin.js index 95d2a773bfa..c37d200e5d4 100644 --- a/lib/optimize/SplitChunksPlugin.js +++ b/lib/optimize/SplitChunksPlugin.js @@ -17,7 +17,7 @@ const { } = require("../util/comparators"); const createHash = require("../util/createHash"); const deterministicGrouping = require("../util/deterministicGrouping"); -const contextify = require("../util/identifier").contextify; +const { makePathsRelative } = require("../util/identifier"); const memoize = require("../util/memoize"); const MinMaxSizeWarning = require("./MinMaxSizeWarning"); @@ -28,11 +28,10 @@ const MinMaxSizeWarning = require("./MinMaxSizeWarning"); /** @typedef {import("../../declarations/WebpackOptions").Output} OutputOptions */ /** @typedef {import("../ChunkGraph")} ChunkGraph */ /** @typedef {import("../ChunkGroup")} ChunkGroup */ -/** @typedef {import("../Compilation").AssetInfo} AssetInfo */ -/** @typedef {import("../Compilation").PathData} PathData */ /** @typedef {import("../Compiler")} Compiler */ /** @typedef {import("../Module")} Module */ /** @typedef {import("../ModuleGraph")} ModuleGraph */ +/** @typedef {import("../TemplatedPathPlugin").TemplatePath} TemplatePath */ /** @typedef {import("../util/deterministicGrouping").GroupedItems} DeterministicGroupingGroupedItemsForModule */ /** @typedef {import("../util/deterministicGrouping").Options} DeterministicGroupingOptionsForModule */ @@ -41,7 +40,7 @@ const MinMaxSizeWarning = require("./MinMaxSizeWarning"); /** * @callback ChunkFilterFunction * @param {Chunk} chunk - * @returns {boolean} + * @returns {boolean | undefined} */ /** @@ -52,13 +51,14 @@ const MinMaxSizeWarning = require("./MinMaxSizeWarning"); */ /** - * @typedef {Object} CacheGroupSource + * @typedef {object} CacheGroupSource * @property {string=} key * @property {number=} priority * @property {GetName=} getName * @property {ChunkFilterFunction=} chunksFilter * @property {boolean=} enforce * @property {SplitChunksSizes} minSize + * @property {SplitChunksSizes} minSizeReduction * @property {SplitChunksSizes} minRemainingSize * @property {SplitChunksSizes} enforceSizeThreshold * @property {SplitChunksSizes} maxAsyncSize @@ -66,20 +66,21 @@ const MinMaxSizeWarning = require("./MinMaxSizeWarning"); * @property {number=} minChunks * @property {number=} maxAsyncRequests * @property {number=} maxInitialRequests - * @property {(string | function(PathData, AssetInfo=): string)=} filename + * @property {TemplatePath=} filename * @property {string=} idHint - * @property {string} automaticNameDelimiter + * @property {string=} automaticNameDelimiter * @property {boolean=} reuseExistingChunk * @property {boolean=} usedExports */ /** - * @typedef {Object} CacheGroup + * @typedef {object} CacheGroup * @property {string} key * @property {number=} priority * @property {GetName=} getName * @property {ChunkFilterFunction=} chunksFilter * @property {SplitChunksSizes} minSize + * @property {SplitChunksSizes} minSizeReduction * @property {SplitChunksSizes} minRemainingSize * @property {SplitChunksSizes} enforceSizeThreshold * @property {SplitChunksSizes} maxAsyncSize @@ -87,7 +88,7 @@ const MinMaxSizeWarning = require("./MinMaxSizeWarning"); * @property {number=} minChunks * @property {number=} maxAsyncRequests * @property {number=} maxInitialRequests - * @property {(string | function(PathData, AssetInfo=): string)=} filename + * @property {TemplatePath=} filename * @property {string=} idHint * @property {string} automaticNameDelimiter * @property {boolean} reuseExistingChunk @@ -99,7 +100,8 @@ const MinMaxSizeWarning = require("./MinMaxSizeWarning"); */ /** - * @typedef {Object} FallbackCacheGroup + * @typedef {object} FallbackCacheGroup + * @property {ChunkFilterFunction} chunksFilter * @property {SplitChunksSizes} minSize * @property {SplitChunksSizes} maxAsyncSize * @property {SplitChunksSizes} maxInitialSize @@ -107,7 +109,7 @@ const MinMaxSizeWarning = require("./MinMaxSizeWarning"); */ /** - * @typedef {Object} CacheGroupsContext + * @typedef {object} CacheGroupsContext * @property {ModuleGraph} moduleGraph * @property {ChunkGraph} chunkGraph */ @@ -128,10 +130,11 @@ const MinMaxSizeWarning = require("./MinMaxSizeWarning"); */ /** - * @typedef {Object} SplitChunksOptions + * @typedef {object} SplitChunksOptions * @property {ChunkFilterFunction} chunksFilter * @property {string[]} defaultSizeTypes * @property {SplitChunksSizes} minSize + * @property {SplitChunksSizes} minSizeReduction * @property {SplitChunksSizes} minRemainingSize * @property {SplitChunksSizes} enforceSizeThreshold * @property {SplitChunksSizes} maxInitialSize @@ -140,7 +143,7 @@ const MinMaxSizeWarning = require("./MinMaxSizeWarning"); * @property {number} maxAsyncRequests * @property {number} maxInitialRequests * @property {boolean} hidePathInfo - * @property {string | function(PathData, AssetInfo=): string} filename + * @property {TemplatePath} filename * @property {string} automaticNameDelimiter * @property {GetCacheGroups} getCacheGroups * @property {GetName} getName @@ -149,20 +152,22 @@ const MinMaxSizeWarning = require("./MinMaxSizeWarning"); */ /** - * @typedef {Object} ChunksInfoItem + * @typedef {object} ChunksInfoItem * @property {SortableSet} modules * @property {CacheGroup} cacheGroup * @property {number} cacheGroupIndex * @property {string} name * @property {Record} sizes * @property {Set} chunks - * @property {Set} reuseableChunks + * @property {Set} reusableChunks * @property {Set} chunksKeys */ const defaultGetName = /** @type {GetName} */ (() => {}); -const deterministicGroupingForModules = /** @type {function(DeterministicGroupingOptionsForModule): DeterministicGroupingGroupedItemsForModule[]} */ (deterministicGrouping); +const deterministicGroupingForModules = + /** @type {function(DeterministicGroupingOptionsForModule): DeterministicGroupingGroupedItemsForModule[]} */ + (deterministicGrouping); /** @type {WeakMap} */ const getKeyCache = new WeakMap(); @@ -173,9 +178,13 @@ const getKeyCache = new WeakMap(); * @returns {string} hashed filename */ const hashFilename = (name, outputOptions) => { - const digest = /** @type {string} */ (createHash(outputOptions.hashFunction) - .update(name) - .digest(outputOptions.hashDigest)); + const digest = + /** @type {string} */ + ( + createHash(outputOptions.hashFunction) + .update(name) + .digest(outputOptions.hashDigest) + ); return digest.slice(0, 8); }; @@ -191,10 +200,21 @@ const getRequests = chunk => { return requests; }; +/** + * @template {object} T + * @template {object} R + * @param {T} obj obj an object + * @param {function(T[keyof T], keyof T): T[keyof T]} fn fn + * @returns {T} result + */ const mapObject = (obj, fn) => { const newObj = Object.create(null); for (const key of Object.keys(obj)) { - newObj[key] = fn(obj[key], key); + newObj[key] = fn( + obj[/** @type {keyof T} */ (key)], + /** @type {keyof T} */ + (key) + ); } return newObj; }; @@ -245,12 +265,24 @@ const compareEntries = (a, b) => { return compareModuleIterables(modulesA, modulesB); }; +/** + * @param {Chunk} chunk the chunk + * @returns {boolean} true, if the chunk is an entry chunk + */ const INITIAL_CHUNK_FILTER = chunk => chunk.canBeInitial(); +/** + * @param {Chunk} chunk the chunk + * @returns {boolean} true, if the chunk is an async chunk + */ const ASYNC_CHUNK_FILTER = chunk => !chunk.canBeInitial(); +/** + * @param {Chunk} chunk the chunk + * @returns {boolean} always true + */ const ALL_CHUNK_FILTER = chunk => true; /** - * @param {OptimizationSplitChunksSizes} value the sizes + * @param {OptimizationSplitChunksSizes | undefined} value the sizes * @param {string[]} defaultSizeTypes the default size types * @returns {SplitChunksSizes} normalized representation */ @@ -262,13 +294,12 @@ const normalizeSizes = (value, defaultSizeTypes) => { return o; } else if (typeof value === "object" && value !== null) { return { ...value }; - } else { - return {}; } + return {}; }; /** - * @param {...SplitChunksSizes} sizes the sizes + * @param {...(SplitChunksSizes | undefined)} sizes the sizes * @returns {SplitChunksSizes} the merged sizes */ const mergeSizes = (...sizes) => { @@ -303,11 +334,7 @@ const combineSizes = (a, b, combine) => { /** @type {SplitChunksSizes} */ const result = {}; for (const key of aKeys) { - if (bKeys.has(key)) { - result[key] = combine(a[key], b[key]); - } else { - result[key] = a[key]; - } + result[key] = bKeys.has(key) ? combine(a[key], b[key]) : a[key]; } for (const key of bKeys) { if (!aKeys.has(key)) { @@ -331,6 +358,21 @@ const checkMinSize = (sizes, minSize) => { return true; }; +/** + * @param {SplitChunksSizes} sizes the sizes + * @param {SplitChunksSizes} minSizeReduction the min sizes + * @param {number} chunkCount number of chunks + * @returns {boolean} true if there are sizes and all existing sizes are at least `minSizeReduction` + */ +const checkMinSizeReduction = (sizes, minSizeReduction, chunkCount) => { + for (const key of Object.keys(minSizeReduction)) { + const size = sizes[key]; + if (size === undefined || size === 0) continue; + if (size * chunkCount < minSizeReduction[key]) return false; + } + return true; +}; + /** * @param {SplitChunksSizes} sizes the sizes * @param {SplitChunksSizes} minSize the min sizes @@ -362,8 +404,8 @@ const totalSize = sizes => { }; /** - * @param {false|string|Function} name the chunk name - * @returns {GetName} a function to get the name of the chunk + * @param {false|string|Function|undefined} name the chunk name + * @returns {GetName | undefined} a function to get the name of the chunk */ const normalizeName = name => { if (typeof name === "string") { @@ -388,6 +430,9 @@ const normalizeChunksFilter = chunks => { if (chunks === "all") { return ALL_CHUNK_FILTER; } + if (chunks instanceof RegExp) { + return chunk => (chunk.name ? chunks.test(chunk.name) : false); + } if (typeof chunks === "function") { return chunks; } @@ -459,7 +504,7 @@ const normalizeCacheGroups = (cacheGroups, defaultSizeTypes) => { */ const fn = (module, context) => { /** @type {CacheGroupSource[]} */ - let results = []; + const results = []; for (const fn of handlers) { fn(module, context, results); } @@ -543,6 +588,10 @@ const checkModuleLayer = (test, module) => { */ const createCacheGroupSource = (options, key, defaultSizeTypes) => { const minSize = normalizeSizes(options.minSize, defaultSizeTypes); + const minSizeReduction = normalizeSizes( + options.minSizeReduction, + defaultSizeTypes + ); const maxSize = normalizeSizes(options.maxSize, defaultSizeTypes); return { key, @@ -551,6 +600,7 @@ const createCacheGroupSource = (options, key, defaultSizeTypes) => { chunksFilter: normalizeChunksFilter(options.chunks), enforce: options.enforce, minSize, + minSizeReduction, minRemainingSize: mergeSizes( normalizeSizes(options.minRemainingSize, defaultSizeTypes), minSize @@ -589,6 +639,10 @@ module.exports = class SplitChunksPlugin { ]; const fallbackCacheGroup = options.fallbackCacheGroup || {}; const minSize = normalizeSizes(options.minSize, defaultSizeTypes); + const minSizeReduction = normalizeSizes( + options.minSizeReduction, + defaultSizeTypes + ); const maxSize = normalizeSizes(options.maxSize, defaultSizeTypes); /** @type {SplitChunksOptions} */ @@ -596,6 +650,7 @@ module.exports = class SplitChunksPlugin { chunksFilter: normalizeChunksFilter(options.chunks || "all"), defaultSizeTypes, minSize, + minSizeReduction, minRemainingSize: mergeSizes( normalizeSizes(options.minRemainingSize, defaultSizeTypes), minSize @@ -625,6 +680,9 @@ module.exports = class SplitChunksPlugin { automaticNameDelimiter: options.automaticNameDelimiter, usedExports: options.usedExports, fallbackCacheGroup: { + chunksFilter: normalizeChunksFilter( + fallbackCacheGroup.chunks || options.chunks || "all" + ), minSize: mergeSizes( normalizeSizes(fallbackCacheGroup.minSize, defaultSizeTypes), minSize @@ -663,6 +721,10 @@ module.exports = class SplitChunksPlugin { cacheGroupSource.minSize, cacheGroupSource.enforce ? undefined : this.options.minSize ); + const minSizeReduction = mergeSizes( + cacheGroupSource.minSizeReduction, + cacheGroupSource.enforce ? undefined : this.options.minSizeReduction + ); const minRemainingSize = mergeSizes( cacheGroupSource.minRemainingSize, cacheGroupSource.enforce ? undefined : this.options.minRemainingSize @@ -676,6 +738,7 @@ module.exports = class SplitChunksPlugin { priority: cacheGroupSource.priority || 0, chunksFilter: cacheGroupSource.chunksFilter || this.options.chunksFilter, minSize, + minSizeReduction, minRemainingSize, enforceSizeThreshold, maxAsyncSize: mergeSizes( @@ -690,20 +753,20 @@ module.exports = class SplitChunksPlugin { cacheGroupSource.minChunks !== undefined ? cacheGroupSource.minChunks : cacheGroupSource.enforce - ? 1 - : this.options.minChunks, + ? 1 + : this.options.minChunks, maxAsyncRequests: cacheGroupSource.maxAsyncRequests !== undefined ? cacheGroupSource.maxAsyncRequests : cacheGroupSource.enforce - ? Infinity - : this.options.maxAsyncRequests, + ? Infinity + : this.options.maxAsyncRequests, maxInitialRequests: cacheGroupSource.maxInitialRequests !== undefined ? cacheGroupSource.maxInitialRequests : cacheGroupSource.enforce - ? Infinity - : this.options.maxInitialRequests, + ? Infinity + : this.options.maxInitialRequests, getName: cacheGroupSource.getName !== undefined ? cacheGroupSource.getName @@ -743,7 +806,7 @@ module.exports = class SplitChunksPlugin { * @returns {void} */ apply(compiler) { - const cachedContextify = contextify.bindContextCache( + const cachedMakePathsRelative = makePathsRelative.bindContextCache( compiler.context, compiler.root ); @@ -769,9 +832,13 @@ module.exports = class SplitChunksPlugin { const chunkIndexMap = new Map(); const ZERO = BigInt("0"); const ONE = BigInt("1"); - let index = ONE; + const START = ONE << BigInt("31"); + let index = START; for (const chunk of chunks) { - chunkIndexMap.set(chunk, index); + chunkIndexMap.set( + chunk, + index | BigInt((Math.random() * 0x7fffffff) | 0) + ); index = index << ONE; } /** @@ -788,10 +855,15 @@ module.exports = class SplitChunksPlugin { let key = chunkIndexMap.get(first) | chunkIndexMap.get(result.value); while (!(result = iterator.next()).done) { - key = key | chunkIndexMap.get(result.value); + const raw = chunkIndexMap.get(result.value); + key = key ^ raw; } return key; }; + /** + * @param {bigint | Chunk} key key of the chunks + * @returns {string} stringified key + */ const keyToString = key => { if (typeof key === "bigint") return key.toString(16); return chunkIndexMap.get(key).toString(16); @@ -863,6 +935,10 @@ module.exports = class SplitChunksPlugin { // group these set of chunks by count // to allow to check less sets via isSubset // (only smaller sets can be subset) + /** + * @param {IterableIterator>} chunkSets set of sets of chunks + * @returns {Map>>} map of sets of chunks by count + */ const groupChunkSetsByCount = chunkSets => { /** @type {Map>>} */ const chunkSetsByCount = new Map(); @@ -939,10 +1015,8 @@ module.exports = class SplitChunksPlugin { const getCombinations = key => getCombinationsFactory()(key); const getExportsCombinationsFactory = memoize(() => { - const { - chunkSetsInGraph, - singleChunkSets - } = getExportsChunkSetsInGraph(); + const { chunkSetsInGraph, singleChunkSets } = + getExportsChunkSetsInGraph(); return createGetCombinations( chunkSetsInGraph, singleChunkSets, @@ -953,7 +1027,7 @@ module.exports = class SplitChunksPlugin { getExportsCombinationsFactory()(key); /** - * @typedef {Object} SelectedChunksResult + * @typedef {object} SelectedChunksResult * @property {Chunk[]} chunks the list of chunks * @property {bigint | Chunk} key a key of the list */ @@ -974,8 +1048,9 @@ module.exports = class SplitChunksPlugin { entry = new WeakMap(); selectedChunksCacheByChunksSet.set(chunks, entry); } - /** @type {SelectedChunksResult} */ - let entry2 = entry.get(chunkFilter); + let entry2 = + /** @type {SelectedChunksResult} */ + (entry.get(chunkFilter)); if (entry2 === undefined) { /** @type {Chunk[]} */ const selectedChunks = []; @@ -1023,11 +1098,9 @@ module.exports = class SplitChunksPlugin { // Break if minimum number of chunks is not reached if (selectedChunks.length < cacheGroup.minChunks) return; // Determine name for split chunk - const name = cacheGroup.getName( - module, - selectedChunks, - cacheGroup.key - ); + const name = + /** @type {string} */ + (cacheGroup.getName(module, selectedChunks, cacheGroup.key)); // Check if the name is ok const existingChunk = compilation.namedChunks.get(name); if (existingChunk) { @@ -1070,7 +1143,7 @@ module.exports = class SplitChunksPlugin { "SplitChunksPlugin\n" + `Cache group "${cacheGroup.key}" conflicts with existing chunk.\n` + `Both have the same name "${name}" and existing chunk is not a parent of the selected modules.\n` + - "Use a different name for the cache group or make sure that the existing chunk is a parent (e. g. via dependsOn).\n" + + "Use a different name for the cache group or make sure that the existing chunk is a parent (e. g. via dependOn).\n" + 'HINT: You can omit "name" to automatically create a name.\n' + "BREAKING CHANGE: webpack < 5 used to allow to use an entrypoint as splitChunk. " + "This is no longer allowed when the entrypoint is not a parent of the selected modules.\n" + @@ -1094,7 +1167,7 @@ module.exports = class SplitChunksPlugin { ? ` name:${name}` : ` chunks:${keyToString(selectedChunksKey)}`); // Add module to maps - let info = chunksInfoMap.get(key); + let info = /** @type {ChunksInfoItem} */ (chunksInfoMap.get(key)); if (info === undefined) { chunksInfoMap.set( key, @@ -1108,7 +1181,7 @@ module.exports = class SplitChunksPlugin { name, sizes: {}, chunks: new Set(), - reuseableChunks: new Set(), + reusableChunks: new Set(), chunksKeys: new Set() }) ); @@ -1141,7 +1214,7 @@ module.exports = class SplitChunksPlugin { // Walk through all modules for (const module of compilation.modules) { // Get cache group - let cacheGroups = this.options.getCacheGroups(module, context); + const cacheGroups = this.options.getCacheGroups(module, context); if (!Array.isArray(cacheGroups) || cacheGroups.length === 0) { continue; } @@ -1159,7 +1232,9 @@ module.exports = class SplitChunksPlugin { getExportsChunkSetsInGraph(); /** @type {Set | Chunk>} */ const set = new Set(); - const groupedByUsedExports = groupedByExportsMap.get(module); + const groupedByUsedExports = + /** @type {Iterable} */ + (groupedByExportsMap.get(module)); for (const chunks of groupedByUsedExports) { const chunksKey = getKey(chunks); for (const comb of getExportsCombinations(chunksKey)) @@ -1182,13 +1257,11 @@ module.exports = class SplitChunksPlugin { chunkCombination instanceof Chunk ? 1 : chunkCombination.size; if (count < cacheGroup.minChunks) continue; // Select chunks by configuration - const { - chunks: selectedChunks, - key: selectedChunksKey - } = getSelectedChunks( - chunkCombination, - cacheGroup.chunksFilter - ); + const { chunks: selectedChunks, key: selectedChunksKey } = + getSelectedChunks( + chunkCombination, + /** @type {ChunkFilterFunction} */ (cacheGroup.chunksFilter) + ); addModuleToChunksInfoMap( cacheGroup, @@ -1241,11 +1314,19 @@ module.exports = class SplitChunksPlugin { for (const [key, info] of chunksInfoMap) { if (removeMinSizeViolatingModules(info)) { chunksInfoMap.delete(key); + } else if ( + !checkMinSizeReduction( + info.sizes, + info.cacheGroup.minSizeReduction, + info.chunks.size + ) + ) { + chunksInfoMap.delete(key); } } /** - * @typedef {Object} MaxSizeQueueItem + * @typedef {object} MaxSizeQueueItem * @property {SplitChunksSizes} minSize * @property {SplitChunksSizes} maxAsyncSize * @property {SplitChunksSizes} maxInitialSize @@ -1272,12 +1353,13 @@ module.exports = class SplitChunksPlugin { } } - const item = bestEntry; - chunksInfoMap.delete(bestEntryKey); + const item = /** @type {ChunksInfoItem} */ (bestEntry); + chunksInfoMap.delete(/** @type {string} */ (bestEntryKey)); + /** @type {Chunk["name"] | undefined} */ let chunkName = item.name; // Variable for the new chunk (lazy created) - /** @type {Chunk} */ + /** @type {Chunk | undefined} */ let newChunk; // When no chunk name, check if we can reuse a chunk instead of creating a new one let isExistingChunk = false; @@ -1346,16 +1428,20 @@ module.exports = class SplitChunksPlugin { ) { for (const chunk of usedChunks) { // respect max requests - const maxRequests = chunk.isOnlyInitial() - ? item.cacheGroup.maxInitialRequests - : chunk.canBeInitial() - ? Math.min( - item.cacheGroup.maxInitialRequests, - item.cacheGroup.maxAsyncRequests - ) - : item.cacheGroup.maxAsyncRequests; + const maxRequests = /** @type {number} */ ( + chunk.isOnlyInitial() + ? item.cacheGroup.maxInitialRequests + : chunk.canBeInitial() + ? Math.min( + /** @type {number} */ + (item.cacheGroup.maxInitialRequests), + /** @type {number} */ + (item.cacheGroup.maxAsyncRequests) + ) + : item.cacheGroup.maxAsyncRequests + ); if ( - isFinite(maxRequests) && + Number.isFinite(maxRequests) && getRequests(chunk) >= maxRequests ) { usedChunks.delete(chunk); @@ -1373,8 +1459,12 @@ module.exports = class SplitChunksPlugin { // Were some (invalid) chunks removed from usedChunks? // => readd all modules to the queue, as things could have been changed if (usedChunks.size < item.chunks.size) { - if (isExistingChunk) usedChunks.add(newChunk); - if (usedChunks.size >= item.cacheGroup.minChunks) { + if (isExistingChunk) + usedChunks.add(/** @type {Chunk} */ (newChunk)); + if ( + /** @type {number} */ (usedChunks.size) >= + /** @type {number} */ (item.cacheGroup.minChunks) + ) { const chunksArr = Array.from(usedChunks); for (const module of item.modules) { addModuleToChunksInfoMap( @@ -1396,7 +1486,7 @@ module.exports = class SplitChunksPlugin { usedChunks.size === 1 ) { const [chunk] = usedChunks; - let chunkSizes = Object.create(null); + const chunkSizes = Object.create(null); for (const module of chunkGraph.getChunkModulesIterable(chunk)) { if (!item.modules.has(module)) { for (const type of module.getSourceTypes()) { @@ -1418,7 +1508,7 @@ module.exports = class SplitChunksPlugin { ) { // queue this item again to be processed again // without violating modules - chunksInfoMap.set(bestEntryKey, item); + chunksInfoMap.set(/** @type {string} */ (bestEntryKey), item); } continue; } @@ -1436,7 +1526,7 @@ module.exports = class SplitChunksPlugin { // Add a note to the chunk newChunk.chunkReason = - (newChunk.chunkReason ? newChunk.chunkReason + ", " : "") + + (newChunk.chunkReason ? `${newChunk.chunkReason}, ` : "") + (isReusedWithAllModules ? "reused as split chunk" : "split chunk"); @@ -1483,21 +1573,21 @@ module.exports = class SplitChunksPlugin { oldMaxSizeSettings.minSize, item.cacheGroup._minSizeForMaxSize, Math.max - ) + ) : item.cacheGroup.minSize, maxAsyncSize: oldMaxSizeSettings ? combineSizes( oldMaxSizeSettings.maxAsyncSize, item.cacheGroup.maxAsyncSize, Math.min - ) + ) : item.cacheGroup.maxAsyncSize, maxInitialSize: oldMaxSizeSettings ? combineSizes( oldMaxSizeSettings.maxInitialSize, item.cacheGroup.maxInitialSize, Math.min - ) + ) : item.cacheGroup.maxInitialSize, automaticNameDelimiter: item.cacheGroup.automaticNameDelimiter, keys: oldMaxSizeSettings @@ -1528,7 +1618,14 @@ module.exports = class SplitChunksPlugin { chunksInfoMap.delete(key); continue; } - if (removeMinSizeViolatingModules(info)) { + if ( + removeMinSizeViolatingModules(info) || + !checkMinSizeReduction( + info.sizes, + info.cacheGroup.minSizeReduction, + info.chunks.size + ) + ) { chunksInfoMap.delete(key); continue; } @@ -1547,6 +1644,7 @@ module.exports = class SplitChunksPlugin { const { outputOptions } = compilation; // Make sure that maxSize is fulfilled + const { fallbackCacheGroup } = this.options; for (const chunk of Array.from(compilation.chunks)) { const chunkConfig = maxSizeQueueMap.get(chunk); const { @@ -1554,7 +1652,9 @@ module.exports = class SplitChunksPlugin { maxAsyncSize, maxInitialSize, automaticNameDelimiter - } = chunkConfig || this.options.fallbackCacheGroup; + } = chunkConfig || fallbackCacheGroup; + if (!chunkConfig && !fallbackCacheGroup.chunksFilter(chunk)) + continue; /** @type {SplitChunksSizes} */ let maxSize; if (chunk.isOnlyInitial()) { @@ -1598,11 +1698,11 @@ module.exports = class SplitChunksPlugin { getKey(module) { const cache = getKeyCache.get(module); if (cache !== undefined) return cache; - const ident = cachedContextify(module.identifier()); + const ident = cachedMakePathsRelative(module.identifier()); const nameForCondition = module.nameForCondition && module.nameForCondition(); const name = nameForCondition - ? cachedContextify(nameForCondition) + ? cachedMakePathsRelative(nameForCondition) : ident.replace(/^.*!|\?[^?!]*$/g, ""); const fullKey = name + @@ -1638,7 +1738,9 @@ module.exports = class SplitChunksPlugin { hashFilename(name, outputOptions); } if (i !== results.length - 1) { - const newPart = compilation.addChunk(name); + const newPart = compilation.addChunk( + /** @type {Chunk["name"]} */ (name) + ); chunk.split(newPart); newPart.chunkReason = chunk.chunkReason; // Add all modules to the new chunk @@ -1653,7 +1755,7 @@ module.exports = class SplitChunksPlugin { } } else { // change the chunk to be a part - chunk.name = name; + chunk.name = /** @type {Chunk["name"]} */ (name); } } } diff --git a/lib/performance/AssetsOverSizeLimitWarning.js b/lib/performance/AssetsOverSizeLimitWarning.js index bdce0692d04..5b414fc0dfd 100644 --- a/lib/performance/AssetsOverSizeLimitWarning.js +++ b/lib/performance/AssetsOverSizeLimitWarning.js @@ -28,7 +28,5 @@ Assets: ${assetLists}`); this.name = "AssetsOverSizeLimitWarning"; this.assets = assetsOverSizeLimit; - - Error.captureStackTrace(this, this.constructor); } }; diff --git a/lib/performance/EntrypointsOverSizeLimitWarning.js b/lib/performance/EntrypointsOverSizeLimitWarning.js index 93dd72e8edc..270e8aaa708 100644 --- a/lib/performance/EntrypointsOverSizeLimitWarning.js +++ b/lib/performance/EntrypointsOverSizeLimitWarning.js @@ -31,7 +31,5 @@ Entrypoints:${entrypointList}\n`); this.name = "EntrypointsOverSizeLimitWarning"; this.entrypoints = entrypoints; - - Error.captureStackTrace(this, this.constructor); } }; diff --git a/lib/performance/NoAsyncChunksWarning.js b/lib/performance/NoAsyncChunksWarning.js index 15ebc68006a..a7319d5950b 100644 --- a/lib/performance/NoAsyncChunksWarning.js +++ b/lib/performance/NoAsyncChunksWarning.js @@ -16,7 +16,5 @@ module.exports = class NoAsyncChunksWarning extends WebpackError { ); this.name = "NoAsyncChunksWarning"; - - Error.captureStackTrace(this, this.constructor); } }; diff --git a/lib/performance/SizeLimitsPlugin.js b/lib/performance/SizeLimitsPlugin.js index afbca68de79..b1371a231fc 100644 --- a/lib/performance/SizeLimitsPlugin.js +++ b/lib/performance/SizeLimitsPlugin.js @@ -13,18 +13,19 @@ const NoAsyncChunksWarning = require("./NoAsyncChunksWarning"); /** @typedef {import("webpack-sources").Source} Source */ /** @typedef {import("../../declarations/WebpackOptions").PerformanceOptions} PerformanceOptions */ /** @typedef {import("../ChunkGroup")} ChunkGroup */ +/** @typedef {import("../Compilation").Asset} Asset */ /** @typedef {import("../Compiler")} Compiler */ /** @typedef {import("../Entrypoint")} Entrypoint */ /** @typedef {import("../WebpackError")} WebpackError */ /** - * @typedef {Object} AssetDetails + * @typedef {object} AssetDetails * @property {string} name * @property {number} size */ /** - * @typedef {Object} EntrypointDetails + * @typedef {object} EntrypointDetails * @property {string} name * @property {number} size * @property {string[]} files @@ -32,6 +33,12 @@ const NoAsyncChunksWarning = require("./NoAsyncChunksWarning"); const isOverSizeLimitSet = new WeakSet(); +/** + * @param {Asset["name"]} name the name + * @param {Asset["source"]} source the source + * @param {Asset["info"]} info the info + * @returns {boolean} result + */ const excludeSourceMap = (name, source, info) => !info.development; module.exports = class SizeLimitsPlugin { @@ -95,7 +102,7 @@ module.exports = class SizeLimitsPlugin { } const size = info.size || source.size(); - if (size > assetSizeLimit) { + if (size > /** @type {number} */ (assetSizeLimit)) { assetsOverSizeLimit.push({ name, size @@ -104,6 +111,10 @@ module.exports = class SizeLimitsPlugin { } } + /** + * @param {Asset["name"]} name the name + * @returns {boolean | undefined} result + */ const fileFilter = name => { const asset = compilation.getAsset(name); return asset && assetFilter(asset.name, asset.source, asset.info); @@ -114,10 +125,10 @@ module.exports = class SizeLimitsPlugin { for (const [name, entry] of compilation.entrypoints) { const size = getEntrypointSize(entry); - if (size > entrypointSizeLimit) { + if (size > /** @type {number} */ (entrypointSizeLimit)) { entrypointsOverLimit.push({ - name: name, - size: size, + name, + size, files: entry.getFiles().filter(fileFilter) }); isOverSizeLimitSet.add(entry); @@ -131,14 +142,17 @@ module.exports = class SizeLimitsPlugin { // if !1, then 2, if !2 return if (assetsOverSizeLimit.length > 0) { warnings.push( - new AssetsOverSizeLimitWarning(assetsOverSizeLimit, assetSizeLimit) + new AssetsOverSizeLimitWarning( + assetsOverSizeLimit, + /** @type {number} */ (assetSizeLimit) + ) ); } if (entrypointsOverLimit.length > 0) { warnings.push( new EntrypointsOverSizeLimitWarning( entrypointsOverLimit, - entrypointSizeLimit + /** @type {number} */ (entrypointSizeLimit) ) ); } diff --git a/lib/prefetch/ChunkPrefetchFunctionRuntimeModule.js b/lib/prefetch/ChunkPrefetchFunctionRuntimeModule.js index 1924294bc6e..a330b4a4d73 100644 --- a/lib/prefetch/ChunkPrefetchFunctionRuntimeModule.js +++ b/lib/prefetch/ChunkPrefetchFunctionRuntimeModule.js @@ -7,6 +7,7 @@ const RuntimeModule = require("../RuntimeModule"); const Template = require("../Template"); +/** @typedef {import("../Compilation")} Compilation */ /** @typedef {import("../RuntimeTemplate")} RuntimeTemplate */ class ChunkPrefetchFunctionRuntimeModule extends RuntimeModule { @@ -23,11 +24,12 @@ class ChunkPrefetchFunctionRuntimeModule extends RuntimeModule { } /** - * @returns {string} runtime code + * @returns {string | null} runtime code */ generate() { const { runtimeFunction, runtimeHandlers } = this; - const { runtimeTemplate } = this.compilation; + const compilation = /** @type {Compilation} */ (this.compilation); + const { runtimeTemplate } = compilation; return Template.asString([ `${runtimeHandlers} = {};`, `${runtimeFunction} = ${runtimeTemplate.basicFunction("chunkId", [ diff --git a/lib/prefetch/ChunkPrefetchPreloadPlugin.js b/lib/prefetch/ChunkPrefetchPreloadPlugin.js index 181b6054535..08e78ef6b9f 100644 --- a/lib/prefetch/ChunkPrefetchPreloadPlugin.js +++ b/lib/prefetch/ChunkPrefetchPreloadPlugin.js @@ -11,6 +11,8 @@ const ChunkPrefetchStartupRuntimeModule = require("./ChunkPrefetchStartupRuntime const ChunkPrefetchTriggerRuntimeModule = require("./ChunkPrefetchTriggerRuntimeModule"); const ChunkPreloadTriggerRuntimeModule = require("./ChunkPreloadTriggerRuntimeModule"); +/** @typedef {import("../Chunk")} Chunk */ +/** @typedef {import("../ChunkGroup").RawChunkGroupOptions} RawChunkGroupOptions */ /** @typedef {import("../Compiler")} Compiler */ class ChunkPrefetchPreloadPlugin { @@ -24,8 +26,7 @@ class ChunkPrefetchPreloadPlugin { compilation => { compilation.hooks.additionalChunkRuntimeRequirements.tap( "ChunkPrefetchPreloadPlugin", - (chunk, set) => { - const { chunkGraph } = compilation; + (chunk, set, { chunkGraph }) => { if (chunkGraph.getNumberOfEntryModules(chunk) === 0) return; const startupChildChunks = chunk.getChildrenOfTypeInOrder( chunkGraph, @@ -34,6 +35,7 @@ class ChunkPrefetchPreloadPlugin { if (startupChildChunks) { set.add(RuntimeGlobals.prefetchChunk); set.add(RuntimeGlobals.onChunksLoaded); + set.add(RuntimeGlobals.exports); compilation.addRuntimeModule( chunk, new ChunkPrefetchStartupRuntimeModule(startupChildChunks) @@ -43,9 +45,8 @@ class ChunkPrefetchPreloadPlugin { ); compilation.hooks.additionalTreeRuntimeRequirements.tap( "ChunkPrefetchPreloadPlugin", - (chunk, set) => { - const { chunkGraph } = compilation; - const chunkMap = chunk.getChildIdsByOrdersMap(chunkGraph, false); + (chunk, set, { chunkGraph }) => { + const chunkMap = chunk.getChildIdsByOrdersMap(chunkGraph); if (chunkMap.prefetch) { set.add(RuntimeGlobals.prefetchChunk); diff --git a/lib/prefetch/ChunkPrefetchStartupRuntimeModule.js b/lib/prefetch/ChunkPrefetchStartupRuntimeModule.js index f5837e78ebb..740bbe8c3c1 100644 --- a/lib/prefetch/ChunkPrefetchStartupRuntimeModule.js +++ b/lib/prefetch/ChunkPrefetchStartupRuntimeModule.js @@ -9,6 +9,7 @@ const RuntimeModule = require("../RuntimeModule"); const Template = require("../Template"); /** @typedef {import("../Chunk")} Chunk */ +/** @typedef {import("../Compilation")} Compilation */ /** @typedef {import("../RuntimeTemplate")} RuntimeTemplate */ class ChunkPrefetchStartupRuntimeModule extends RuntimeModule { @@ -21,27 +22,30 @@ class ChunkPrefetchStartupRuntimeModule extends RuntimeModule { } /** - * @returns {string} runtime code + * @returns {string | null} runtime code */ generate() { - const { startupChunks, chunk } = this; - const { runtimeTemplate } = this.compilation; + const { startupChunks } = this; + const compilation = /** @type {Compilation} */ (this.compilation); + const chunk = /** @type {Chunk} */ (this.chunk); + const { runtimeTemplate } = compilation; return Template.asString( startupChunks.map( ({ onChunks, chunks }) => `${RuntimeGlobals.onChunksLoaded}(0, ${JSON.stringify( // This need to include itself to delay execution after this chunk has been fully loaded onChunks.filter(c => c === chunk).map(c => c.id) - )}, ${runtimeTemplate.expressionFunction( + )}, ${runtimeTemplate.basicFunction( + "", chunks.size < 3 ? Array.from( chunks, c => - `${RuntimeGlobals.prefetchChunk}(${JSON.stringify(c.id)})` - ).join(", ") + `${RuntimeGlobals.prefetchChunk}(${JSON.stringify(c.id)});` + ) : `${JSON.stringify(Array.from(chunks, c => c.id))}.map(${ RuntimeGlobals.prefetchChunk - })` + });` )}, 5);` ) ); diff --git a/lib/prefetch/ChunkPrefetchTriggerRuntimeModule.js b/lib/prefetch/ChunkPrefetchTriggerRuntimeModule.js index 8e68da61451..74eb2bc613f 100644 --- a/lib/prefetch/ChunkPrefetchTriggerRuntimeModule.js +++ b/lib/prefetch/ChunkPrefetchTriggerRuntimeModule.js @@ -8,6 +8,7 @@ const RuntimeGlobals = require("../RuntimeGlobals"); const RuntimeModule = require("../RuntimeModule"); const Template = require("../Template"); +/** @typedef {import("../Compilation")} Compilation */ /** @typedef {import("../RuntimeTemplate")} RuntimeTemplate */ class ChunkPrefetchTriggerRuntimeModule extends RuntimeModule { @@ -15,16 +16,17 @@ class ChunkPrefetchTriggerRuntimeModule extends RuntimeModule { * @param {Record} chunkMap map from chunk to */ constructor(chunkMap) { - super(`chunk prefetch trigger`, RuntimeModule.STAGE_TRIGGER); + super("chunk prefetch trigger", RuntimeModule.STAGE_TRIGGER); this.chunkMap = chunkMap; } /** - * @returns {string} runtime code + * @returns {string | null} runtime code */ generate() { const { chunkMap } = this; - const { runtimeTemplate } = this.compilation; + const compilation = /** @type {Compilation} */ (this.compilation); + const { runtimeTemplate } = compilation; const body = [ "var chunks = chunkToChildrenMap[chunkId];", `Array.isArray(chunks) && chunks.map(${RuntimeGlobals.prefetchChunk});` diff --git a/lib/prefetch/ChunkPreloadTriggerRuntimeModule.js b/lib/prefetch/ChunkPreloadTriggerRuntimeModule.js index bc5ec7530c1..8509def176d 100644 --- a/lib/prefetch/ChunkPreloadTriggerRuntimeModule.js +++ b/lib/prefetch/ChunkPreloadTriggerRuntimeModule.js @@ -8,6 +8,7 @@ const RuntimeGlobals = require("../RuntimeGlobals"); const RuntimeModule = require("../RuntimeModule"); const Template = require("../Template"); +/** @typedef {import("../Compilation")} Compilation */ /** @typedef {import("../RuntimeTemplate")} RuntimeTemplate */ class ChunkPreloadTriggerRuntimeModule extends RuntimeModule { @@ -15,16 +16,17 @@ class ChunkPreloadTriggerRuntimeModule extends RuntimeModule { * @param {Record} chunkMap map from chunk to chunks */ constructor(chunkMap) { - super(`chunk preload trigger`, RuntimeModule.STAGE_TRIGGER); + super("chunk preload trigger", RuntimeModule.STAGE_TRIGGER); this.chunkMap = chunkMap; } /** - * @returns {string} runtime code + * @returns {string | null} runtime code */ generate() { const { chunkMap } = this; - const { runtimeTemplate } = this.compilation; + const compilation = /** @type {Compilation} */ (this.compilation); + const { runtimeTemplate } = compilation; const body = [ "var chunks = chunkToChildrenMap[chunkId];", `Array.isArray(chunks) && chunks.map(${RuntimeGlobals.preloadChunk});` diff --git a/lib/rules/BasicEffectRulePlugin.js b/lib/rules/BasicEffectRulePlugin.js index f265b3b80cf..935716baad5 100644 --- a/lib/rules/BasicEffectRulePlugin.js +++ b/lib/rules/BasicEffectRulePlugin.js @@ -5,9 +5,14 @@ "use strict"; +/** @typedef {import("../../declarations/WebpackOptions").RuleSetRule} RuleSetRule */ /** @typedef {import("./RuleSetCompiler")} RuleSetCompiler */ class BasicEffectRulePlugin { + /** + * @param {string} ruleProperty the rule property + * @param {string=} effectType the effect type + */ constructor(ruleProperty, effectType) { this.ruleProperty = ruleProperty; this.effectType = effectType || ruleProperty; @@ -24,7 +29,8 @@ class BasicEffectRulePlugin { if (unhandledProperties.has(this.ruleProperty)) { unhandledProperties.delete(this.ruleProperty); - const value = rule[this.ruleProperty]; + const value = + rule[/** @type {keyof RuleSetRule} */ (this.ruleProperty)]; result.effects.push({ type: this.effectType, diff --git a/lib/rules/BasicMatcherRulePlugin.js b/lib/rules/BasicMatcherRulePlugin.js index 1c349436170..47ac214f624 100644 --- a/lib/rules/BasicMatcherRulePlugin.js +++ b/lib/rules/BasicMatcherRulePlugin.js @@ -5,10 +5,16 @@ "use strict"; +/** @typedef {import("../../declarations/WebpackOptions").RuleSetRule} RuleSetRule */ /** @typedef {import("./RuleSetCompiler")} RuleSetCompiler */ /** @typedef {import("./RuleSetCompiler").RuleCondition} RuleCondition */ class BasicMatcherRulePlugin { + /** + * @param {string} ruleProperty the rule property + * @param {string=} dataProperty the data property + * @param {boolean=} invert if true, inverts the condition + */ constructor(ruleProperty, dataProperty, invert) { this.ruleProperty = ruleProperty; this.dataProperty = dataProperty || ruleProperty; @@ -25,7 +31,8 @@ class BasicMatcherRulePlugin { (path, rule, unhandledProperties, result) => { if (unhandledProperties.has(this.ruleProperty)) { unhandledProperties.delete(this.ruleProperty); - const value = rule[this.ruleProperty]; + const value = + rule[/** @type {keyof RuleSetRule} */ (this.ruleProperty)]; const condition = ruleSetCompiler.compileCondition( `${path}.${this.ruleProperty}`, value diff --git a/lib/rules/DescriptionDataMatcherRulePlugin.js b/lib/rules/DescriptionDataMatcherRulePlugin.js deleted file mode 100644 index c4c703f86ee..00000000000 --- a/lib/rules/DescriptionDataMatcherRulePlugin.js +++ /dev/null @@ -1,43 +0,0 @@ -/* - MIT License http://www.opensource.org/licenses/mit-license.php - Author Tobias Koppers @sokra -*/ - -"use strict"; - -/** @typedef {import("./RuleSetCompiler")} RuleSetCompiler */ -/** @typedef {import("./RuleSetCompiler").RuleCondition} RuleCondition */ - -const RULE_PROPERTY = "descriptionData"; - -class DescriptionDataMatcherRulePlugin { - /** - * @param {RuleSetCompiler} ruleSetCompiler the rule set compiler - * @returns {void} - */ - apply(ruleSetCompiler) { - ruleSetCompiler.hooks.rule.tap( - "DescriptionDataMatcherRulePlugin", - (path, rule, unhandledProperties, result) => { - if (unhandledProperties.has(RULE_PROPERTY)) { - unhandledProperties.delete(RULE_PROPERTY); - const value = rule[RULE_PROPERTY]; - for (const property of Object.keys(value)) { - const dataProperty = property.split("."); - const condition = ruleSetCompiler.compileCondition( - `${path}.${RULE_PROPERTY}.${property}`, - value[property] - ); - result.conditions.push({ - property: ["descriptionData", ...dataProperty], - matchWhenEmpty: condition.matchWhenEmpty, - fn: condition.fn - }); - } - } - } - ); - } -} - -module.exports = DescriptionDataMatcherRulePlugin; diff --git a/lib/rules/ObjectMatcherRulePlugin.js b/lib/rules/ObjectMatcherRulePlugin.js new file mode 100644 index 00000000000..984e86f83fa --- /dev/null +++ b/lib/rules/ObjectMatcherRulePlugin.js @@ -0,0 +1,64 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ + +"use strict"; + +/** @typedef {import("../../declarations/WebpackOptions").RuleSetRule} RuleSetRule */ +/** @typedef {import("./RuleSetCompiler")} RuleSetCompiler */ +/** @typedef {import("./RuleSetCompiler").RuleCondition} RuleCondition */ +/** @typedef {import("./RuleSetCompiler").RuleConditionFunction} RuleConditionFunction */ + +class ObjectMatcherRulePlugin { + /** + * @param {string} ruleProperty the rule property + * @param {string=} dataProperty the data property + * @param {RuleConditionFunction=} additionalConditionFunction need to check + */ + constructor(ruleProperty, dataProperty, additionalConditionFunction) { + this.ruleProperty = ruleProperty; + this.dataProperty = dataProperty || ruleProperty; + this.additionalConditionFunction = additionalConditionFunction; + } + + /** + * @param {RuleSetCompiler} ruleSetCompiler the rule set compiler + * @returns {void} + */ + apply(ruleSetCompiler) { + const { ruleProperty, dataProperty } = this; + ruleSetCompiler.hooks.rule.tap( + "ObjectMatcherRulePlugin", + (path, rule, unhandledProperties, result) => { + if (unhandledProperties.has(ruleProperty)) { + unhandledProperties.delete(ruleProperty); + const value = + /** @type {Record} */ + (rule[/** @type {keyof RuleSetRule} */ (ruleProperty)]); + for (const property of Object.keys(value)) { + const nestedDataProperties = property.split("."); + const condition = ruleSetCompiler.compileCondition( + `${path}.${ruleProperty}.${property}`, + value[property] + ); + if (this.additionalConditionFunction) { + result.conditions.push({ + property: [dataProperty], + matchWhenEmpty: condition.matchWhenEmpty, + fn: this.additionalConditionFunction + }); + } + result.conditions.push({ + property: [dataProperty, ...nestedDataProperties], + matchWhenEmpty: condition.matchWhenEmpty, + fn: condition.fn + }); + } + } + } + ); + } +} + +module.exports = ObjectMatcherRulePlugin; diff --git a/lib/rules/RuleSetCompiler.js b/lib/rules/RuleSetCompiler.js index b22a6a9a65e..7674dd72779 100644 --- a/lib/rules/RuleSetCompiler.js +++ b/lib/rules/RuleSetCompiler.js @@ -7,43 +7,57 @@ const { SyncHook } = require("tapable"); +/** @typedef {import("../../declarations/WebpackOptions").RuleSetRule} RuleSetRule */ +/** @typedef {import("../../declarations/WebpackOptions").RuleSetRules} RuleSetRules */ + +/** @typedef {function(string): boolean} RuleConditionFunction */ + /** - * @typedef {Object} RuleCondition + * @typedef {object} RuleCondition * @property {string | string[]} property * @property {boolean} matchWhenEmpty - * @property {function(string): boolean} fn + * @property {RuleConditionFunction} fn */ /** - * @typedef {Object} Condition + * @typedef {object} Condition * @property {boolean} matchWhenEmpty - * @property {function(string): boolean} fn + * @property {RuleConditionFunction} fn + */ + +/** + * @typedef {Record} EffectData */ /** - * @typedef {Object} CompiledRule + * @typedef {object} CompiledRule * @property {RuleCondition[]} conditions - * @property {(Effect|function(object): Effect[])[]} effects + * @property {(Effect|function(EffectData): Effect[])[]} effects * @property {CompiledRule[]=} rules * @property {CompiledRule[]=} oneOf */ /** - * @typedef {Object} Effect + * @typedef {object} Effect * @property {string} type * @property {any} value */ /** - * @typedef {Object} RuleSet + * @typedef {object} RuleSet * @property {Map} references map of references in the rule set (may grow over time) - * @property {function(object): Effect[]} exec execute the rule set + * @property {function(EffectData): Effect[]} exec execute the rule set */ +/** @typedef {{ apply: (function(RuleSetCompiler): void) }} RuleSetPlugin */ + class RuleSetCompiler { + /** + * @param {RuleSetPlugin[]} plugins plugins + */ constructor(plugins) { this.hooks = Object.freeze({ - /** @type {SyncHook<[string, object, Set, CompiledRule, Map]>} */ + /** @type {SyncHook<[string, RuleSetRule, Set, CompiledRule, Map]>} */ rule: new SyncHook([ "path", "rule", @@ -60,7 +74,7 @@ class RuleSetCompiler { } /** - * @param {object[]} ruleSet raw user provided rules + * @param {TODO[]} ruleSet raw user provided rules * @returns {RuleSet} compiled RuleSet */ compile(ruleSet) { @@ -68,7 +82,7 @@ class RuleSetCompiler { const rules = this.compileRules("ruleSet", ruleSet, refs); /** - * @param {object} data data passed in + * @param {EffectData} data data passed in * @param {CompiledRule} rule the compiled rule * @param {Effect[]} effects an array where effects are pushed to * @returns {boolean} true, if the rule has matched @@ -77,6 +91,7 @@ class RuleSetCompiler { for (const condition of rule.conditions) { const p = condition.property; if (Array.isArray(p)) { + /** @type {EffectData | string | undefined} */ let current = data; for (const subProperty of p) { if ( @@ -91,7 +106,7 @@ class RuleSetCompiler { } } if (current !== undefined) { - if (!condition.fn(current)) return false; + if (!condition.fn(/** @type {string} */ (current))) return false; continue; } } else if (p in data) { @@ -145,25 +160,33 @@ class RuleSetCompiler { /** * @param {string} path current path - * @param {object[]} rules the raw rules provided by user + * @param {RuleSetRules} rules the raw rules provided by user * @param {Map} refs references * @returns {CompiledRule[]} rules */ compileRules(path, rules, refs) { - return rules.map((rule, i) => - this.compileRule(`${path}[${i}]`, rule, refs) - ); + return rules + .filter(Boolean) + .map((rule, i) => + this.compileRule( + `${path}[${i}]`, + /** @type {RuleSetRule} */ (rule), + refs + ) + ); } /** * @param {string} path current path - * @param {object} rule the raw rule provided by user + * @param {RuleSetRule} rule the raw rule provided by user * @param {Map} refs references * @returns {CompiledRule} normalized and compiled rule for processing */ compileRule(path, rule, refs) { const unhandledProperties = new Set( - Object.keys(rule).filter(key => rule[key] !== undefined) + Object.keys(rule).filter( + key => rule[/** @type {keyof RuleSetRule} */ (key)] !== undefined + ) ); /** @type {CompiledRule} */ @@ -225,7 +248,7 @@ class RuleSetCompiler { if (typeof condition === "string") { return { matchWhenEmpty: condition.length === 0, - fn: str => str.startsWith(condition) + fn: str => typeof str === "string" && str.startsWith(condition) }; } if (typeof condition === "function") { @@ -234,7 +257,7 @@ class RuleSetCompiler { matchWhenEmpty: condition(""), fn: condition }; - } catch (err) { + } catch (_err) { throw this.error( path, condition, @@ -245,7 +268,7 @@ class RuleSetCompiler { if (condition instanceof RegExp) { return { matchWhenEmpty: condition.test(""), - fn: v => condition.test(v) + fn: v => typeof v === "string" && condition.test(v) }; } if (Array.isArray(condition)) { @@ -272,7 +295,7 @@ class RuleSetCompiler { if (!Array.isArray(value)) { throw this.error( `${path}.or`, - condition.and, + condition.or, "Expected array of conditions" ); } @@ -301,7 +324,7 @@ class RuleSetCompiler { const fn = matcher.fn; conditions.push({ matchWhenEmpty: !matcher.matchWhenEmpty, - fn: v => !fn(v) + fn: /** @type {RuleConditionFunction} */ (v => !fn(v)) }); } break; @@ -335,12 +358,11 @@ class RuleSetCompiler { }; } else if (conditions.length === 1) { return conditions[0]; - } else { - return { - matchWhenEmpty: conditions.some(c => c.matchWhenEmpty), - fn: v => conditions.some(c => c.fn(v)) - }; } + return { + matchWhenEmpty: conditions.some(c => c.matchWhenEmpty), + fn: v => conditions.some(c => c.fn(v)) + }; } /** @@ -355,12 +377,11 @@ class RuleSetCompiler { }; } else if (conditions.length === 1) { return conditions[0]; - } else { - return { - matchWhenEmpty: conditions.every(c => c.matchWhenEmpty), - fn: v => conditions.every(c => c.fn(v)) - }; } + return { + matchWhenEmpty: conditions.every(c => c.matchWhenEmpty), + fn: v => conditions.every(c => c.fn(v)) + }; } /** diff --git a/lib/rules/UseEffectRulePlugin.js b/lib/rules/UseEffectRulePlugin.js index 58b1056e855..56f2423de62 100644 --- a/lib/rules/UseEffectRulePlugin.js +++ b/lib/rules/UseEffectRulePlugin.js @@ -7,6 +7,9 @@ const util = require("util"); +/** @typedef {import("../../declarations/WebpackOptions").RuleSetLoader} RuleSetLoader */ +/** @typedef {import("../../declarations/WebpackOptions").RuleSetLoaderOptions} RuleSetLoaderOptions */ +/** @typedef {import("../../declarations/WebpackOptions").RuleSetRule} RuleSetRule */ /** @typedef {import("./RuleSetCompiler")} RuleSetCompiler */ /** @typedef {import("./RuleSetCompiler").Effect} Effect */ @@ -19,6 +22,10 @@ class UseEffectRulePlugin { ruleSetCompiler.hooks.rule.tap( "UseEffectRulePlugin", (path, rule, unhandledProperties, result, references) => { + /** + * @param {keyof RuleSetRule} property property + * @param {string} correctProperty correct property + */ const conflictWith = (property, correctProperty) => { if (unhandledProperties.has(property)) { throw ruleSetCompiler.error( @@ -42,7 +49,6 @@ class UseEffectRulePlugin { const type = enforce ? `use-${enforce}` : "use"; /** - * * @param {string} path options path * @param {string} defaultIdent default ident when none is provided * @param {object} item user provided use value @@ -51,16 +57,14 @@ class UseEffectRulePlugin { const useToEffect = (path, defaultIdent, item) => { if (typeof item === "function") { return data => useToEffectsWithoutIdent(path, item(data)); - } else { - return useToEffectRaw(path, defaultIdent, item); } + return useToEffectRaw(path, defaultIdent, item); }; /** - * * @param {string} path options path * @param {string} defaultIdent default ident when none is provided - * @param {object} item user provided use value + * @param {{ ident?: string, loader?: RuleSetLoader, options?: RuleSetLoaderOptions }} item user provided use value * @returns {Effect} effect */ const useToEffectRaw = (path, defaultIdent, item) => { @@ -73,30 +77,29 @@ class UseEffectRulePlugin { ident: undefined } }; - } else { - const loader = item.loader; - const options = item.options; - let ident = item.ident; - if (options && typeof options === "object") { - if (!ident) ident = defaultIdent; - references.set(ident, options); - } - if (typeof options === "string") { - util.deprecate( - () => {}, - `Using a string as loader options is deprecated (${path}.options)`, - "DEP_WEBPACK_RULE_LOADER_OPTIONS_STRING" - )(); - } - return { - type: enforce ? `use-${enforce}` : "use", - value: { - loader, - options, - ident - } - }; } + const loader = item.loader; + const options = item.options; + let ident = item.ident; + if (options && typeof options === "object") { + if (!ident) ident = defaultIdent; + references.set(ident, options); + } + if (typeof options === "string") { + util.deprecate( + () => {}, + `Using a string as loader options is deprecated (${path}.options)`, + "DEP_WEBPACK_RULE_LOADER_OPTIONS_STRING" + )(); + } + return { + type: enforce ? `use-${enforce}` : "use", + value: { + loader, + options, + ident + } + }; }; /** @@ -106,9 +109,11 @@ class UseEffectRulePlugin { */ const useToEffectsWithoutIdent = (path, items) => { if (Array.isArray(items)) { - return items.map((item, idx) => - useToEffectRaw(`${path}[${idx}]`, "[[missing ident]]", item) - ); + return items + .filter(Boolean) + .map((item, idx) => + useToEffectRaw(`${path}[${idx}]`, "[[missing ident]]", item) + ); } return [useToEffectRaw(path, "[[missing ident]]", items)]; }; @@ -120,7 +125,7 @@ class UseEffectRulePlugin { */ const useToEffects = (path, items) => { if (Array.isArray(items)) { - return items.map((item, idx) => { + return items.filter(Boolean).map((item, idx) => { const subPath = `${path}[${idx}]`; return useToEffect(subPath, subPath, item); }); @@ -130,7 +135,10 @@ class UseEffectRulePlugin { if (typeof use === "function") { result.effects.push(data => - useToEffectsWithoutIdent(`${path}.use`, use(data)) + useToEffectsWithoutIdent( + `${path}.use`, + use(/** @type {TODO} */ (data)) + ) ); } else { for (const effect of useToEffects(`${path}.use`, use)) { @@ -144,7 +152,7 @@ class UseEffectRulePlugin { unhandledProperties.delete("options"); unhandledProperties.delete("enforce"); - const loader = rule.loader; + const loader = /** @type {RuleSetLoader} */ (rule.loader); const options = rule.options; const enforce = rule.enforce; @@ -187,8 +195,6 @@ class UseEffectRulePlugin { } ); } - - useItemToEffects(path, item) {} } module.exports = UseEffectRulePlugin; diff --git a/lib/runtime/AsyncModuleRuntimeModule.js b/lib/runtime/AsyncModuleRuntimeModule.js index e9be5b03183..79141c76f2e 100644 --- a/lib/runtime/AsyncModuleRuntimeModule.js +++ b/lib/runtime/AsyncModuleRuntimeModule.js @@ -8,23 +8,28 @@ const RuntimeGlobals = require("../RuntimeGlobals"); const Template = require("../Template"); const HelperRuntimeModule = require("./HelperRuntimeModule"); +/** @typedef {import("../Compilation")} Compilation */ + class AsyncModuleRuntimeModule extends HelperRuntimeModule { constructor() { super("async module"); } /** - * @returns {string} runtime code + * @returns {string | null} runtime code */ generate() { - const { runtimeTemplate } = this.compilation; + const compilation = /** @type {Compilation} */ (this.compilation); + const { runtimeTemplate } = compilation; const fn = RuntimeGlobals.asyncModule; return Template.asString([ - 'var webpackThen = typeof Symbol === "function" ? Symbol("webpack then") : "__webpack_then__";', - 'var webpackExports = typeof Symbol === "function" ? Symbol("webpack exports") : "__webpack_exports__";', - `var completeQueue = ${runtimeTemplate.basicFunction("queue", [ - "if(queue) {", + 'var webpackQueues = typeof Symbol === "function" ? Symbol("webpack queues") : "__webpack_queues__";', + `var webpackExports = typeof Symbol === "function" ? Symbol("webpack exports") : "${RuntimeGlobals.exports}";`, + 'var webpackError = typeof Symbol === "function" ? Symbol("webpack error") : "__webpack_error__";', + `var resolveQueue = ${runtimeTemplate.basicFunction("queue", [ + "if(queue && queue.d < 1) {", Template.indent([ + "queue.d = 1;", `queue.forEach(${runtimeTemplate.expressionFunction( "fn.r--", "fn" @@ -36,104 +41,90 @@ class AsyncModuleRuntimeModule extends HelperRuntimeModule { ]), "}" ])}`, - `var completeFunction = ${runtimeTemplate.expressionFunction( - "!--fn.r && fn()", - "fn" - )};`, - `var queueFunction = ${runtimeTemplate.expressionFunction( - "queue ? queue.push(fn) : completeFunction(fn)", - "queue, fn" - )};`, `var wrapDeps = ${runtimeTemplate.returningFunction( `deps.map(${runtimeTemplate.basicFunction("dep", [ 'if(dep !== null && typeof dep === "object") {', Template.indent([ - "if(dep[webpackThen]) return dep;", + "if(dep[webpackQueues]) return dep;", "if(dep.then) {", Template.indent([ "var queue = [];", + "queue.d = 0;", `dep.then(${runtimeTemplate.basicFunction("r", [ "obj[webpackExports] = r;", - "completeQueue(queue);", - "queue = 0;" + "resolveQueue(queue);" + ])}, ${runtimeTemplate.basicFunction("e", [ + "obj[webpackError] = e;", + "resolveQueue(queue);" ])});`, - `var obj = { [webpackThen]: ${runtimeTemplate.expressionFunction( - "queueFunction(queue, fn), dep.catch(reject)", - "fn, reject" - )} };`, + "var obj = {};", + `obj[webpackQueues] = ${runtimeTemplate.expressionFunction( + "fn(queue)", + "fn" + )};`, "return obj;" ]), "}" ]), "}", - `return { [webpackThen]: ${runtimeTemplate.expressionFunction( - "completeFunction(fn)", - "fn" - )}, [webpackExports]: dep };` + "var ret = {};", + `ret[webpackQueues] = ${runtimeTemplate.emptyFunction()};`, + "ret[webpackExports] = dep;", + "return ret;" ])})`, "deps" )};`, `${fn} = ${runtimeTemplate.basicFunction("module, body, hasAwait", [ - "var queue = hasAwait && [];", + "var queue;", + "hasAwait && ((queue = []).d = -1);", + "var depQueues = new Set();", "var exports = module.exports;", "var currentDeps;", "var outerResolve;", "var reject;", - "var isEvaluating = true;", - "var nested = false;", - `var whenAll = ${runtimeTemplate.basicFunction( - "deps, onResolve, onReject", - [ - "if (nested) return;", - "nested = true;", - "onResolve.r += deps.length;", - `deps.map(${runtimeTemplate.expressionFunction( - "dep[webpackThen](onResolve, onReject)", - "dep, i" - )});`, - "nested = false;" - ] - )};`, `var promise = new Promise(${runtimeTemplate.basicFunction( "resolve, rej", - [ - "reject = rej;", - `outerResolve = ${runtimeTemplate.expressionFunction( - "resolve(exports), completeQueue(queue), queue = 0" - )};` - ] + ["reject = rej;", "outerResolve = resolve;"] )});`, "promise[webpackExports] = exports;", - `promise[webpackThen] = ${runtimeTemplate.basicFunction( - "fn, rejectFn", - [ - "if (isEvaluating) { return completeFunction(fn); }", - "if (currentDeps) whenAll(currentDeps, fn, rejectFn);", - "queueFunction(queue, fn);", - "promise.catch(rejectFn);" - ] + `promise[webpackQueues] = ${runtimeTemplate.expressionFunction( + `queue && fn(queue), depQueues.forEach(fn), promise["catch"](${runtimeTemplate.emptyFunction()})`, + "fn" )};`, "module.exports = promise;", `body(${runtimeTemplate.basicFunction("deps", [ - "if(!deps) return outerResolve();", "currentDeps = wrapDeps(deps);", - "var fn, result;", + "var fn;", + `var getResult = ${runtimeTemplate.returningFunction( + `currentDeps.map(${runtimeTemplate.basicFunction("d", [ + "if(d[webpackError]) throw d[webpackError];", + "return d[webpackExports];" + ])})` + )}`, `var promise = new Promise(${runtimeTemplate.basicFunction( - "resolve, reject", + "resolve", [ `fn = ${runtimeTemplate.expressionFunction( - `resolve(result = currentDeps.map(${runtimeTemplate.returningFunction( - "d[webpackExports]", - "d" - )}))` + "resolve(getResult)", + "" )};`, "fn.r = 0;", - "whenAll(currentDeps, fn, reject);" + `var fnQueue = ${runtimeTemplate.expressionFunction( + "q !== queue && !depQueues.has(q) && (depQueues.add(q), q && !q.d && (fn.r++, q.push(fn)))", + "q" + )};`, + `currentDeps.map(${runtimeTemplate.expressionFunction( + "dep[webpackQueues](fnQueue)", + "dep" + )});` ] )});`, - "return fn.r ? promise : result;" - ])}).then(outerResolve, reject);`, - "isEvaluating = false;" + "return fn.r ? promise : getResult();" + ])}, ${runtimeTemplate.expressionFunction( + "(err ? reject(promise[webpackError] = err) : outerResolve(exports)), resolveQueue(queue)", + "err" + )});`, + "queue && queue.d < 0 && (queue.d = 0);" ])};` ]); } diff --git a/lib/runtime/AutoPublicPathRuntimeModule.js b/lib/runtime/AutoPublicPathRuntimeModule.js index a672408621a..74b40a1e883 100644 --- a/lib/runtime/AutoPublicPathRuntimeModule.js +++ b/lib/runtime/AutoPublicPathRuntimeModule.js @@ -10,20 +10,24 @@ const Template = require("../Template"); const JavascriptModulesPlugin = require("../javascript/JavascriptModulesPlugin"); const { getUndoPath } = require("../util/identifier"); +/** @typedef {import("../Chunk")} Chunk */ +/** @typedef {import("../Compilation")} Compilation */ + class AutoPublicPathRuntimeModule extends RuntimeModule { constructor() { super("publicPath", RuntimeModule.STAGE_BASIC); } /** - * @returns {string} runtime code + * @returns {string | null} runtime code */ generate() { - const { compilation } = this; + const compilation = /** @type {Compilation} */ (this.compilation); const { scriptType, importMetaName, path } = compilation.outputOptions; const chunkName = compilation.getPath( JavascriptModulesPlugin.getChunkFilenameTemplate( - this.chunk, + /** @type {Chunk} */ + (this.chunk), compilation.outputOptions ), { @@ -31,7 +35,11 @@ class AutoPublicPathRuntimeModule extends RuntimeModule { contentHashType: "javascript" } ); - const undoPath = getUndoPath(chunkName, path, false); + const undoPath = getUndoPath( + chunkName, + /** @type {string} */ (path), + false + ); return Template.asString([ "var scriptUrl;", @@ -42,17 +50,25 @@ class AutoPublicPathRuntimeModule extends RuntimeModule { `var document = ${RuntimeGlobals.global}.document;`, "if (!scriptUrl && document) {", Template.indent([ - `if (document.currentScript)`, - Template.indent(`scriptUrl = document.currentScript.src`), + // Technically we could use `document.currentScript instanceof window.HTMLScriptElement`, + // but an attacker could try to inject `` + // and use `` + "if (document.currentScript && document.currentScript.tagName.toUpperCase() === 'SCRIPT')", + Template.indent("scriptUrl = document.currentScript.src;"), "if (!scriptUrl) {", Template.indent([ 'var scripts = document.getElementsByTagName("script");', - "if(scripts.length) scriptUrl = scripts[scripts.length - 1].src" + "if(scripts.length) {", + Template.indent([ + "var i = scripts.length - 1;", + "while (i > -1 && (!scriptUrl || !/^http(s?):/.test(scriptUrl))) scriptUrl = scripts[i--].src;" + ]), + "}" ]), "}" ]), "}" - ]), + ]), "// When supporting browsers where an automatic publicPath is not supported you must specify an output.publicPath manually via configuration", '// or pass an empty string ("") and set the __webpack_public_path__ variable from your code to use your own logic.', 'if (!scriptUrl) throw new Error("Automatic publicPath is not supported in this browser");', @@ -61,7 +77,7 @@ class AutoPublicPathRuntimeModule extends RuntimeModule { ? `${RuntimeGlobals.publicPath} = scriptUrl;` : `${RuntimeGlobals.publicPath} = scriptUrl + ${JSON.stringify( undoPath - )};` + )};` ]); } } diff --git a/lib/runtime/BaseUriRuntimeModule.js b/lib/runtime/BaseUriRuntimeModule.js new file mode 100644 index 00000000000..99609b762bd --- /dev/null +++ b/lib/runtime/BaseUriRuntimeModule.js @@ -0,0 +1,35 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Ivan Kopeykin @vankop +*/ + +"use strict"; + +const RuntimeGlobals = require("../RuntimeGlobals"); +const RuntimeModule = require("../RuntimeModule"); + +/** @typedef {import("../../declarations/WebpackOptions").EntryDescriptionNormalized} EntryDescriptionNormalized */ +/** @typedef {import("../Chunk")} Chunk */ + +class BaseUriRuntimeModule extends RuntimeModule { + constructor() { + super("base uri", RuntimeModule.STAGE_ATTACH); + } + + /** + * @returns {string | null} runtime code + */ + generate() { + const chunk = /** @type {Chunk} */ (this.chunk); + const options = + /** @type {EntryDescriptionNormalized} */ + (chunk.getEntryOptions()); + return `${RuntimeGlobals.baseURI} = ${ + options.baseUri === undefined + ? "undefined" + : JSON.stringify(options.baseUri) + };`; + } +} + +module.exports = BaseUriRuntimeModule; diff --git a/lib/runtime/ChunkNameRuntimeModule.js b/lib/runtime/ChunkNameRuntimeModule.js index 2271b430aa2..22149767907 100644 --- a/lib/runtime/ChunkNameRuntimeModule.js +++ b/lib/runtime/ChunkNameRuntimeModule.js @@ -17,7 +17,7 @@ class ChunkNameRuntimeModule extends RuntimeModule { } /** - * @returns {string} runtime code + * @returns {string | null} runtime code */ generate() { return `${RuntimeGlobals.chunkName} = ${JSON.stringify(this.chunkName)};`; diff --git a/lib/runtime/CompatGetDefaultExportRuntimeModule.js b/lib/runtime/CompatGetDefaultExportRuntimeModule.js index 4947bcc62aa..1406e051fd9 100644 --- a/lib/runtime/CompatGetDefaultExportRuntimeModule.js +++ b/lib/runtime/CompatGetDefaultExportRuntimeModule.js @@ -8,16 +8,19 @@ const RuntimeGlobals = require("../RuntimeGlobals"); const Template = require("../Template"); const HelperRuntimeModule = require("./HelperRuntimeModule"); +/** @typedef {import("../Compilation")} Compilation */ + class CompatGetDefaultExportRuntimeModule extends HelperRuntimeModule { constructor() { super("compat get default export"); } /** - * @returns {string} runtime code + * @returns {string | null} runtime code */ generate() { - const { runtimeTemplate } = this.compilation; + const compilation = /** @type {Compilation} */ (this.compilation); + const { runtimeTemplate } = compilation; const fn = RuntimeGlobals.compatGetDefaultExport; return Template.asString([ "// getDefaultExport function for compatibility with non-harmony modules", diff --git a/lib/runtime/CompatRuntimeModule.js b/lib/runtime/CompatRuntimeModule.js index d4c627d1586..cf386c0886b 100644 --- a/lib/runtime/CompatRuntimeModule.js +++ b/lib/runtime/CompatRuntimeModule.js @@ -7,6 +7,9 @@ const RuntimeGlobals = require("../RuntimeGlobals"); const RuntimeModule = require("../RuntimeModule"); +/** @typedef {import("../Chunk")} Chunk */ +/** @typedef {import("../ChunkGraph")} ChunkGraph */ +/** @typedef {import("../Compilation")} Compilation */ /** @typedef {import("../MainTemplate")} MainTemplate */ class CompatRuntimeModule extends RuntimeModule { @@ -16,12 +19,13 @@ class CompatRuntimeModule extends RuntimeModule { } /** - * @returns {string} runtime code + * @returns {string | null} runtime code */ generate() { - const { chunk, compilation } = this; + const compilation = /** @type {Compilation} */ (this.compilation); + const chunkGraph = /** @type {ChunkGraph} */ (this.chunkGraph); + const chunk = /** @type {Chunk} */ (this.chunk); const { - chunkGraph, runtimeTemplate, mainTemplate, moduleTemplates, diff --git a/lib/runtime/CreateFakeNamespaceObjectRuntimeModule.js b/lib/runtime/CreateFakeNamespaceObjectRuntimeModule.js index 6c2157eed39..05b811b19b0 100644 --- a/lib/runtime/CreateFakeNamespaceObjectRuntimeModule.js +++ b/lib/runtime/CreateFakeNamespaceObjectRuntimeModule.js @@ -8,16 +8,19 @@ const RuntimeGlobals = require("../RuntimeGlobals"); const Template = require("../Template"); const HelperRuntimeModule = require("./HelperRuntimeModule"); +/** @typedef {import("../Compilation")} Compilation */ + class CreateFakeNamespaceObjectRuntimeModule extends HelperRuntimeModule { constructor() { super("create fake namespace object"); } /** - * @returns {string} runtime code + * @returns {string | null} runtime code */ generate() { - const { runtimeTemplate } = this.compilation; + const compilation = /** @type {Compilation} */ (this.compilation); + const { runtimeTemplate } = compilation; const fn = RuntimeGlobals.createFakeNamespaceObject; return Template.asString([ `var getProto = Object.getPrototypeOf ? ${runtimeTemplate.returningFunction( @@ -34,8 +37,8 @@ class CreateFakeNamespaceObjectRuntimeModule extends HelperRuntimeModule { // Note: must be a function (not arrow), because this is used in body! `${fn} = function(value, mode) {`, Template.indent([ - `if(mode & 1) value = this(value);`, - `if(mode & 8) return value;`, + "if(mode & 1) value = this(value);", + "if(mode & 8) return value;", "if(typeof value === 'object' && value) {", Template.indent([ "if((mode & 4) && value.__esModule) return value;", diff --git a/lib/runtime/CreateScriptRuntimeModule.js b/lib/runtime/CreateScriptRuntimeModule.js new file mode 100644 index 00000000000..7859e87d411 --- /dev/null +++ b/lib/runtime/CreateScriptRuntimeModule.js @@ -0,0 +1,38 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php +*/ + +"use strict"; + +const RuntimeGlobals = require("../RuntimeGlobals"); +const Template = require("../Template"); +const HelperRuntimeModule = require("./HelperRuntimeModule"); + +/** @typedef {import("../Compilation")} Compilation */ + +class CreateScriptRuntimeModule extends HelperRuntimeModule { + constructor() { + super("trusted types script"); + } + + /** + * @returns {string | null} runtime code + */ + generate() { + const compilation = /** @type {Compilation} */ (this.compilation); + const { runtimeTemplate, outputOptions } = compilation; + const { trustedTypes } = outputOptions; + const fn = RuntimeGlobals.createScript; + + return Template.asString( + `${fn} = ${runtimeTemplate.returningFunction( + trustedTypes + ? `${RuntimeGlobals.getTrustedTypesPolicy}().createScript(script)` + : "script", + "script" + )};` + ); + } +} + +module.exports = CreateScriptRuntimeModule; diff --git a/lib/runtime/CreateScriptUrlRuntimeModule.js b/lib/runtime/CreateScriptUrlRuntimeModule.js new file mode 100644 index 00000000000..4c8960024d9 --- /dev/null +++ b/lib/runtime/CreateScriptUrlRuntimeModule.js @@ -0,0 +1,38 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php +*/ + +"use strict"; + +const RuntimeGlobals = require("../RuntimeGlobals"); +const Template = require("../Template"); +const HelperRuntimeModule = require("./HelperRuntimeModule"); + +/** @typedef {import("../Compilation")} Compilation */ + +class CreateScriptUrlRuntimeModule extends HelperRuntimeModule { + constructor() { + super("trusted types script url"); + } + + /** + * @returns {string | null} runtime code + */ + generate() { + const compilation = /** @type {Compilation} */ (this.compilation); + const { runtimeTemplate, outputOptions } = compilation; + const { trustedTypes } = outputOptions; + const fn = RuntimeGlobals.createScriptUrl; + + return Template.asString( + `${fn} = ${runtimeTemplate.returningFunction( + trustedTypes + ? `${RuntimeGlobals.getTrustedTypesPolicy}().createScriptURL(url)` + : "url", + "url" + )};` + ); + } +} + +module.exports = CreateScriptUrlRuntimeModule; diff --git a/lib/runtime/DefinePropertyGettersRuntimeModule.js b/lib/runtime/DefinePropertyGettersRuntimeModule.js index 5fce2be9cc1..4dad207a935 100644 --- a/lib/runtime/DefinePropertyGettersRuntimeModule.js +++ b/lib/runtime/DefinePropertyGettersRuntimeModule.js @@ -8,21 +8,24 @@ const RuntimeGlobals = require("../RuntimeGlobals"); const Template = require("../Template"); const HelperRuntimeModule = require("./HelperRuntimeModule"); +/** @typedef {import("../Compilation")} Compilation */ + class DefinePropertyGettersRuntimeModule extends HelperRuntimeModule { constructor() { super("define property getters"); } /** - * @returns {string} runtime code + * @returns {string | null} runtime code */ generate() { - const { runtimeTemplate } = this.compilation; + const compilation = /** @type {Compilation} */ (this.compilation); + const { runtimeTemplate } = compilation; const fn = RuntimeGlobals.definePropertyGetters; return Template.asString([ "// define getter functions for harmony exports", `${fn} = ${runtimeTemplate.basicFunction("exports, definition", [ - `for(var key in definition) {`, + "for(var key in definition) {", Template.indent([ `if(${RuntimeGlobals.hasOwnProperty}(definition, key) && !${RuntimeGlobals.hasOwnProperty}(exports, key)) {`, Template.indent([ diff --git a/lib/runtime/EnsureChunkRuntimeModule.js b/lib/runtime/EnsureChunkRuntimeModule.js index f18836f2228..bc6c0ecbdf1 100644 --- a/lib/runtime/EnsureChunkRuntimeModule.js +++ b/lib/runtime/EnsureChunkRuntimeModule.js @@ -8,45 +8,60 @@ const RuntimeGlobals = require("../RuntimeGlobals"); const RuntimeModule = require("../RuntimeModule"); const Template = require("../Template"); +/** @typedef {import("../Compilation")} Compilation */ +/** @typedef {import("../Module").ReadOnlyRuntimeRequirements} ReadOnlyRuntimeRequirements */ + class EnsureChunkRuntimeModule extends RuntimeModule { + /** + * @param {ReadOnlyRuntimeRequirements} runtimeRequirements runtime requirements + */ constructor(runtimeRequirements) { super("ensure chunk"); this.runtimeRequirements = runtimeRequirements; } /** - * @returns {string} runtime code + * @returns {string | null} runtime code */ generate() { - const { runtimeTemplate } = this.compilation; + const compilation = /** @type {Compilation} */ (this.compilation); + const { runtimeTemplate } = compilation; // Check if there are non initial chunks which need to be imported using require-ensure if (this.runtimeRequirements.has(RuntimeGlobals.ensureChunkHandlers)) { + const withFetchPriority = this.runtimeRequirements.has( + RuntimeGlobals.hasFetchPriority + ); const handlers = RuntimeGlobals.ensureChunkHandlers; return Template.asString([ `${handlers} = {};`, "// This file contains only the entry chunk.", "// The chunk loading function for additional chunks", - `${ - RuntimeGlobals.ensureChunk - } = ${runtimeTemplate.basicFunction("chunkId", [ - `return Promise.all(Object.keys(${handlers}).reduce(${runtimeTemplate.basicFunction( - "promises, key", - [`${handlers}[key](chunkId, promises);`, "return promises;"] - )}, []));` - ])};` - ]); - } else { - // There ensureChunk is used somewhere in the tree, so we need an empty requireEnsure - // function. This can happen with multiple entrypoints. - return Template.asString([ - "// The chunk loading function for additional chunks", - "// Since all referenced chunks are already included", - "// in this file, this function is empty here.", - `${RuntimeGlobals.ensureChunk} = ${runtimeTemplate.returningFunction( - "Promise.resolve()" + `${RuntimeGlobals.ensureChunk} = ${runtimeTemplate.basicFunction( + `chunkId${withFetchPriority ? ", fetchPriority" : ""}`, + [ + `return Promise.all(Object.keys(${handlers}).reduce(${runtimeTemplate.basicFunction( + "promises, key", + [ + `${handlers}[key](chunkId, promises${ + withFetchPriority ? ", fetchPriority" : "" + });`, + "return promises;" + ] + )}, []));` + ] )};` ]); } + // There ensureChunk is used somewhere in the tree, so we need an empty requireEnsure + // function. This can happen with multiple entrypoints. + return Template.asString([ + "// The chunk loading function for additional chunks", + "// Since all referenced chunks are already included", + "// in this file, this function is empty here.", + `${RuntimeGlobals.ensureChunk} = ${runtimeTemplate.returningFunction( + "Promise.resolve()" + )};` + ]); } } diff --git a/lib/runtime/GetChunkFilenameRuntimeModule.js b/lib/runtime/GetChunkFilenameRuntimeModule.js index 203c296f2af..8ba563e9254 100644 --- a/lib/runtime/GetChunkFilenameRuntimeModule.js +++ b/lib/runtime/GetChunkFilenameRuntimeModule.js @@ -10,18 +10,17 @@ const Template = require("../Template"); const { first } = require("../util/SetHelpers"); /** @typedef {import("../Chunk")} Chunk */ +/** @typedef {import("../ChunkGraph")} ChunkGraph */ /** @typedef {import("../Compilation")} Compilation */ /** @typedef {import("../Compilation").AssetInfo} AssetInfo */ -/** @typedef {import("../Compilation").PathData} PathData */ - -/** @typedef {function(PathData, AssetInfo=): string} FilenameFunction */ +/** @typedef {import("../TemplatedPathPlugin").TemplatePath} TemplatePath */ class GetChunkFilenameRuntimeModule extends RuntimeModule { /** * @param {string} contentType the contentType to use the content hash for * @param {string} name kind of filename * @param {string} global function name to be assigned - * @param {function(Chunk): string | FilenameFunction} getFilenameForChunk functor to get the filename or function + * @param {function(Chunk): TemplatePath} getFilenameForChunk functor to get the filename or function * @param {boolean} allChunks when false, only async chunks are included */ constructor(contentType, name, global, getFilenameForChunk, allChunks) { @@ -30,26 +29,23 @@ class GetChunkFilenameRuntimeModule extends RuntimeModule { this.global = global; this.getFilenameForChunk = getFilenameForChunk; this.allChunks = allChunks; + this.dependentHash = true; } /** - * @returns {string} runtime code + * @returns {string | null} runtime code */ generate() { - const { - global, - chunk, - contentType, - getFilenameForChunk, - allChunks, - compilation - } = this; + const { global, contentType, getFilenameForChunk, allChunks } = this; + const compilation = /** @type {Compilation} */ (this.compilation); + const chunkGraph = /** @type {ChunkGraph} */ (this.chunkGraph); + const chunk = /** @type {Chunk} */ (this.chunk); const { runtimeTemplate } = compilation; - /** @type {Map>} */ + /** @type {Map>} */ const chunkFilenames = new Map(); let maxChunks = 0; - /** @type {string} */ + /** @type {string | undefined} */ let dynamicFilename; /** @@ -67,9 +63,19 @@ class GetChunkFilenameRuntimeModule extends RuntimeModule { if (typeof chunkFilename === "string") { if (set.size < maxChunks) return; if (set.size === maxChunks) { - if (chunkFilename.length < dynamicFilename.length) return; - if (chunkFilename.length === dynamicFilename.length) { - if (chunkFilename < dynamicFilename) return; + if ( + chunkFilename.length < + /** @type {string} */ (dynamicFilename).length + ) { + return; + } + + if ( + chunkFilename.length === + /** @type {string} */ (dynamicFilename).length && + chunkFilename < /** @type {string} */ (dynamicFilename) + ) { + return; } } maxChunks = set.size; @@ -90,12 +96,12 @@ class GetChunkFilenameRuntimeModule extends RuntimeModule { for (const c of chunk.getAllAsyncChunks()) { addChunk(c); } - const includeEntries = compilation.chunkGraph + const includeEntries = chunkGraph .getTreeRuntimeRequirements(chunk) .has(RuntimeGlobals.ensureChunkIncludeEntries); if (includeEntries) { includedChunksMessages.push("sibling chunks for the entrypoint"); - for (const c of compilation.chunkGraph.getChunkEntryDependentChunksIterable( + for (const c of chunkGraph.getChunkEntryDependentChunksIterable( chunk )) { addChunk(c); @@ -106,14 +112,14 @@ class GetChunkFilenameRuntimeModule extends RuntimeModule { addChunk(entrypoint.chunks[entrypoint.chunks.length - 1]); } - /** @type {Map>} */ + /** @type {Map>} */ const staticUrls = new Map(); /** @type {Set} */ const dynamicUrlChunks = new Set(); /** * @param {Chunk} c the chunk - * @param {string | FilenameFunction} chunkFilename the filename template for the chunk + * @param {string | TemplatePath} chunkFilename the filename template for the chunk * @returns {void} */ const addStaticUrl = (c, chunkFilename) => { @@ -128,8 +134,12 @@ class GetChunkFilenameRuntimeModule extends RuntimeModule { return '" + chunkId + "'; } const s = JSON.stringify(str); - return s.slice(1, s.length - 1); + return s.slice(1, -1); }; + /** + * @param {string} value string + * @returns {function(number): string} string to put in quotes with length + */ const unquotedStringifyWithLength = value => length => unquotedStringify(`${value}`.slice(0, length)); const chunkFilenameValue = @@ -139,17 +149,21 @@ class GetChunkFilenameRuntimeModule extends RuntimeModule { chunk: c, contentHashType: contentType }) - ) + ) : JSON.stringify(chunkFilename); const staticChunkFilename = compilation.getPath(chunkFilenameValue, { hash: `" + ${RuntimeGlobals.getFullHash}() + "`, hashWithLength: length => `" + ${RuntimeGlobals.getFullHash}().slice(0, ${length}) + "`, chunk: { - id: unquotedStringify(c.id), - hash: unquotedStringify(c.renderedHash), - hashWithLength: unquotedStringifyWithLength(c.renderedHash), - name: unquotedStringify(c.name || c.id), + id: unquotedStringify(/** @type {number | string} */ (c.id)), + hash: unquotedStringify(/** @type {string} */ (c.renderedHash)), + hashWithLength: unquotedStringifyWithLength( + /** @type {string} */ (c.renderedHash) + ), + name: unquotedStringify( + c.name || /** @type {number | string} */ (c.id) + ), contentHash: { [contentType]: unquotedStringify(c.contentHash[contentType]) }, @@ -181,8 +195,10 @@ class GetChunkFilenameRuntimeModule extends RuntimeModule { * @returns {string} code with static mapping of results of fn */ const createMap = fn => { + /** @type {Record} */ const obj = {}; let useId = false; + /** @type {number | string | undefined} */ let lastKey; let entries = 0; for (const c of dynamicUrlChunks) { @@ -190,8 +206,8 @@ class GetChunkFilenameRuntimeModule extends RuntimeModule { if (value === c.id) { useId = true; } else { - obj[c.id] = value; - lastKey = c.id; + obj[/** @type {number | string} */ (c.id)] = value; + lastKey = /** @type {number | string} */ (c.id); entries++; } } @@ -199,9 +215,9 @@ class GetChunkFilenameRuntimeModule extends RuntimeModule { if (entries === 1) { return useId ? `(chunkId === ${JSON.stringify(lastKey)} ? ${JSON.stringify( - obj[lastKey] - )} : chunkId)` - : JSON.stringify(obj[lastKey]); + obj[/** @type {number | string} */ (lastKey)] + )} : chunkId)` + : JSON.stringify(obj[/** @type {number | string} */ (lastKey)]); } return useId ? `(${JSON.stringify(obj)}[chunkId] || chunkId)` @@ -212,17 +228,14 @@ class GetChunkFilenameRuntimeModule extends RuntimeModule { * @param {function(Chunk): string | number} fn function from chunk to value * @returns {string} code with static mapping of results of fn for including in quoted string */ - const mapExpr = fn => { - return `" + ${createMap(fn)} + "`; - }; + const mapExpr = fn => `" + ${createMap(fn)} + "`; /** * @param {function(Chunk): string | number} fn function from chunk to value * @returns {function(number): string} function which generates code with static mapping of results of fn for including in quoted string for specific length */ - const mapExprWithLength = fn => length => { - return `" + ${createMap(c => `${fn(c)}`.slice(0, length))} + "`; - }; + const mapExprWithLength = fn => length => + `" + ${createMap(c => `${fn(c)}`.slice(0, length))} + "`; const url = dynamicFilename && @@ -232,9 +245,11 @@ class GetChunkFilenameRuntimeModule extends RuntimeModule { `" + ${RuntimeGlobals.getFullHash}().slice(0, ${length}) + "`, chunk: { id: `" + chunkId + "`, - hash: mapExpr(c => c.renderedHash), - hashWithLength: mapExprWithLength(c => c.renderedHash), - name: mapExpr(c => c.name || c.id), + hash: mapExpr(c => /** @type {string} */ (c.renderedHash)), + hashWithLength: mapExprWithLength( + c => /** @type {string} */ (c.renderedHash) + ), + name: mapExpr(c => c.name || /** @type {number | string} */ (c.id)), contentHash: { [contentType]: mapExpr(c => c.contentHash[contentType]) }, @@ -264,13 +279,13 @@ class GetChunkFilenameRuntimeModule extends RuntimeModule { : `{${Array.from( ids, id => `${JSON.stringify(id)}:1` - ).join(",")}}[chunkId]`; + ).join(",")}}[chunkId]`; return `if (${condition}) return ${url};`; }) ), "// return url for filenames based on template", `return ${url};` - ] + ] : ["// return url for filenames based on template", `return ${url};`] )};` ]); diff --git a/lib/runtime/GetFullHashRuntimeModule.js b/lib/runtime/GetFullHashRuntimeModule.js index fa2908443c4..cf9949394fb 100644 --- a/lib/runtime/GetFullHashRuntimeModule.js +++ b/lib/runtime/GetFullHashRuntimeModule.js @@ -16,12 +16,13 @@ class GetFullHashRuntimeModule extends RuntimeModule { } /** - * @returns {string} runtime code + * @returns {string | null} runtime code */ generate() { - const { runtimeTemplate } = this.compilation; + const compilation = /** @type {Compilation} */ (this.compilation); + const { runtimeTemplate } = compilation; return `${RuntimeGlobals.getFullHash} = ${runtimeTemplate.returningFunction( - JSON.stringify(this.compilation.hash || "XXXX") + JSON.stringify(compilation.hash || "XXXX") )}`; } } diff --git a/lib/runtime/GetMainFilenameRuntimeModule.js b/lib/runtime/GetMainFilenameRuntimeModule.js index cd9a6937b49..0a9fdf50bb8 100644 --- a/lib/runtime/GetMainFilenameRuntimeModule.js +++ b/lib/runtime/GetMainFilenameRuntimeModule.js @@ -8,6 +8,7 @@ const RuntimeGlobals = require("../RuntimeGlobals"); const RuntimeModule = require("../RuntimeModule"); const Template = require("../Template"); +/** @typedef {import("../Chunk")} Chunk */ /** @typedef {import("../Compilation")} Compilation */ class GetMainFilenameRuntimeModule extends RuntimeModule { @@ -23,10 +24,12 @@ class GetMainFilenameRuntimeModule extends RuntimeModule { } /** - * @returns {string} runtime code + * @returns {string | null} runtime code */ generate() { - const { global, filename, compilation, chunk } = this; + const { global, filename } = this; + const compilation = /** @type {Compilation} */ (this.compilation); + const chunk = /** @type {Chunk} */ (this.chunk); const { runtimeTemplate } = compilation; const url = compilation.getPath(JSON.stringify(filename), { hash: `" + ${RuntimeGlobals.getFullHash}() + "`, diff --git a/lib/runtime/GetTrustedTypesPolicyRuntimeModule.js b/lib/runtime/GetTrustedTypesPolicyRuntimeModule.js new file mode 100644 index 00000000000..e8342b3431c --- /dev/null +++ b/lib/runtime/GetTrustedTypesPolicyRuntimeModule.js @@ -0,0 +1,98 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php +*/ + +"use strict"; + +const RuntimeGlobals = require("../RuntimeGlobals"); +const Template = require("../Template"); +const HelperRuntimeModule = require("./HelperRuntimeModule"); + +/** @typedef {import("../Compilation")} Compilation */ +/** @typedef {import("../Module").ReadOnlyRuntimeRequirements} ReadOnlyRuntimeRequirements */ + +class GetTrustedTypesPolicyRuntimeModule extends HelperRuntimeModule { + /** + * @param {ReadOnlyRuntimeRequirements} runtimeRequirements runtime requirements + */ + constructor(runtimeRequirements) { + super("trusted types policy"); + this.runtimeRequirements = runtimeRequirements; + } + + /** + * @returns {string | null} runtime code + */ + generate() { + const compilation = /** @type {Compilation} */ (this.compilation); + const { runtimeTemplate, outputOptions } = compilation; + const { trustedTypes } = outputOptions; + const fn = RuntimeGlobals.getTrustedTypesPolicy; + const wrapPolicyCreationInTryCatch = trustedTypes + ? trustedTypes.onPolicyCreationFailure === "continue" + : false; + + return Template.asString([ + "var policy;", + `${fn} = ${runtimeTemplate.basicFunction("", [ + "// Create Trusted Type policy if Trusted Types are available and the policy doesn't exist yet.", + "if (policy === undefined) {", + Template.indent([ + "policy = {", + Template.indent( + [ + ...(this.runtimeRequirements.has(RuntimeGlobals.createScript) + ? [ + `createScript: ${runtimeTemplate.returningFunction( + "script", + "script" + )}` + ] + : []), + ...(this.runtimeRequirements.has(RuntimeGlobals.createScriptUrl) + ? [ + `createScriptURL: ${runtimeTemplate.returningFunction( + "url", + "url" + )}` + ] + : []) + ].join(",\n") + ), + "};", + ...(trustedTypes + ? [ + 'if (typeof trustedTypes !== "undefined" && trustedTypes.createPolicy) {', + Template.indent([ + ...(wrapPolicyCreationInTryCatch ? ["try {"] : []), + ...[ + `policy = trustedTypes.createPolicy(${JSON.stringify( + trustedTypes.policyName + )}, policy);` + ].map(line => + wrapPolicyCreationInTryCatch ? Template.indent(line) : line + ), + ...(wrapPolicyCreationInTryCatch + ? [ + "} catch (e) {", + Template.indent([ + `console.warn('Could not create trusted-types policy ${JSON.stringify( + trustedTypes.policyName + )}');` + ]), + "}" + ] + : []) + ]), + "}" + ] + : []) + ]), + "}", + "return policy;" + ])};` + ]); + } +} + +module.exports = GetTrustedTypesPolicyRuntimeModule; diff --git a/lib/runtime/GlobalRuntimeModule.js b/lib/runtime/GlobalRuntimeModule.js index 631521aa437..89e556c0858 100644 --- a/lib/runtime/GlobalRuntimeModule.js +++ b/lib/runtime/GlobalRuntimeModule.js @@ -14,7 +14,7 @@ class GlobalRuntimeModule extends RuntimeModule { } /** - * @returns {string} runtime code + * @returns {string | null} runtime code */ generate() { return Template.asString([ diff --git a/lib/runtime/HasOwnPropertyRuntimeModule.js b/lib/runtime/HasOwnPropertyRuntimeModule.js index 1971794609f..78bf3afeb95 100644 --- a/lib/runtime/HasOwnPropertyRuntimeModule.js +++ b/lib/runtime/HasOwnPropertyRuntimeModule.js @@ -9,16 +9,19 @@ const RuntimeGlobals = require("../RuntimeGlobals"); const RuntimeModule = require("../RuntimeModule"); const Template = require("../Template"); +/** @typedef {import("../Compilation")} Compilation */ + class HasOwnPropertyRuntimeModule extends RuntimeModule { constructor() { super("hasOwnProperty shorthand"); } /** - * @returns {string} runtime code + * @returns {string | null} runtime code */ generate() { - const { runtimeTemplate } = this.compilation; + const compilation = /** @type {Compilation} */ (this.compilation); + const { runtimeTemplate } = compilation; return Template.asString([ `${RuntimeGlobals.hasOwnProperty} = ${runtimeTemplate.returningFunction( diff --git a/lib/runtime/LoadScriptRuntimeModule.js b/lib/runtime/LoadScriptRuntimeModule.js index 83523981755..b6b2f3e381c 100644 --- a/lib/runtime/LoadScriptRuntimeModule.js +++ b/lib/runtime/LoadScriptRuntimeModule.js @@ -14,7 +14,7 @@ const HelperRuntimeModule = require("./HelperRuntimeModule"); /** @typedef {import("../Compiler")} Compiler */ /** - * @typedef {Object} LoadScriptCompilationHooks + * @typedef {object} LoadScriptCompilationHooks * @property {SyncWaterfallHook<[string, Chunk]>} createScript */ @@ -42,15 +42,21 @@ class LoadScriptRuntimeModule extends HelperRuntimeModule { return hooks; } - constructor() { + /** + * @param {boolean=} withCreateScriptUrl use create script url for trusted types + * @param {boolean=} withFetchPriority use `fetchPriority` attribute + */ + constructor(withCreateScriptUrl, withFetchPriority) { super("load script"); + this._withCreateScriptUrl = withCreateScriptUrl; + this._withFetchPriority = withFetchPriority; } /** - * @returns {string} runtime code + * @returns {string | null} runtime code */ generate() { - const { compilation } = this; + const compilation = /** @type {Compilation} */ (this.compilation); const { runtimeTemplate, outputOptions } = compilation; const { scriptType, @@ -61,15 +67,14 @@ class LoadScriptRuntimeModule extends HelperRuntimeModule { } = outputOptions; const fn = RuntimeGlobals.loadScript; - const { createScript } = LoadScriptRuntimeModule.getCompilationHooks( - compilation - ); + const { createScript } = + LoadScriptRuntimeModule.getCompilationHooks(compilation); const code = Template.asString([ "script = document.createElement('script');", scriptType ? `script.type = ${JSON.stringify(scriptType)};` : "", charset ? "script.charset = 'utf-8';" : "", - `script.timeout = ${loadTimeout / 1000};`, + `script.timeout = ${/** @type {number} */ (loadTimeout) / 1000};`, `if (${RuntimeGlobals.scriptNonce}) {`, Template.indent( `script.setAttribute("nonce", ${RuntimeGlobals.scriptNonce});` @@ -78,51 +83,69 @@ class LoadScriptRuntimeModule extends HelperRuntimeModule { uniqueName ? 'script.setAttribute("data-webpack", dataWebpackPrefix + key);' : "", - `script.src = url;`, - crossOriginLoading + this._withFetchPriority ? Template.asString([ - "if (script.src.indexOf(window.location.origin + '/') !== 0) {", + "if(fetchPriority) {", Template.indent( - `script.crossOrigin = ${JSON.stringify(crossOriginLoading)};` + 'script.setAttribute("fetchpriority", fetchPriority);' ), "}" - ]) + ]) + : "", + `script.src = ${ + this._withCreateScriptUrl + ? `${RuntimeGlobals.createScriptUrl}(url)` + : "url" + };`, + crossOriginLoading + ? crossOriginLoading === "use-credentials" + ? 'script.crossOrigin = "use-credentials";' + : Template.asString([ + "if (script.src.indexOf(window.location.origin + '/') !== 0) {", + Template.indent( + `script.crossOrigin = ${JSON.stringify(crossOriginLoading)};` + ), + "}" + ]) : "" ]); return Template.asString([ "var inProgress = {};", uniqueName - ? `var dataWebpackPrefix = ${JSON.stringify(uniqueName + ":")};` + ? `var dataWebpackPrefix = ${JSON.stringify(`${uniqueName}:`)};` : "// data-webpack is not used as build has no uniqueName", "// loadScript function to load a script via script tag", - `${fn} = ${runtimeTemplate.basicFunction("url, done, key, chunkId", [ - "if(inProgress[url]) { inProgress[url].push(done); return; }", - "var script, needAttach;", - "if(key !== undefined) {", - Template.indent([ - 'var scripts = document.getElementsByTagName("script");', - "for(var i = 0; i < scripts.length; i++) {", + `${fn} = ${runtimeTemplate.basicFunction( + `url, done, key, chunkId${ + this._withFetchPriority ? ", fetchPriority" : "" + }`, + [ + "if(inProgress[url]) { inProgress[url].push(done); return; }", + "var script, needAttach;", + "if(key !== undefined) {", + Template.indent([ + 'var scripts = document.getElementsByTagName("script");', + "for(var i = 0; i < scripts.length; i++) {", + Template.indent([ + "var s = scripts[i];", + `if(s.getAttribute("src") == url${ + uniqueName + ? ' || s.getAttribute("data-webpack") == dataWebpackPrefix + key' + : "" + }) { script = s; break; }` + ]), + "}" + ]), + "}", + "if(!script) {", Template.indent([ - "var s = scripts[i];", - `if(s.getAttribute("src") == url${ - uniqueName - ? ' || s.getAttribute("data-webpack") == dataWebpackPrefix + key' - : "" - }) { script = s; break; }` + "needAttach = true;", + createScript.call(code, /** @type {Chunk} */ (this.chunk)) ]), - "}" - ]), - "}", - "if(!script) {", - Template.indent([ - "needAttach = true;", - createScript.call(code, this.chunk) - ]), - "}", - "inProgress[url] = [done];", - "var onScriptComplete = " + - runtimeTemplate.basicFunction( + "}", + "inProgress[url] = [done];", + `var onScriptComplete = ${runtimeTemplate.basicFunction( "prev, event", Template.asString([ "// avoid mem leaks in IE.", @@ -137,13 +160,13 @@ class LoadScriptRuntimeModule extends HelperRuntimeModule { )});`, "if(prev) return prev(event);" ]) - ), - ";", - `var timeout = setTimeout(onScriptComplete.bind(null, undefined, { type: 'timeout', target: script }), ${loadTimeout});`, - "script.onerror = onScriptComplete.bind(null, script.onerror);", - "script.onload = onScriptComplete.bind(null, script.onload);", - "needAttach && document.head.appendChild(script);" - ])};` + )}`, + `var timeout = setTimeout(onScriptComplete.bind(null, undefined, { type: 'timeout', target: script }), ${loadTimeout});`, + "script.onerror = onScriptComplete.bind(null, script.onerror);", + "script.onload = onScriptComplete.bind(null, script.onload);", + "needAttach && document.head.appendChild(script);" + ] + )};` ]); } } diff --git a/lib/runtime/MakeNamespaceObjectRuntimeModule.js b/lib/runtime/MakeNamespaceObjectRuntimeModule.js index c08dcabbc79..7b43080d020 100644 --- a/lib/runtime/MakeNamespaceObjectRuntimeModule.js +++ b/lib/runtime/MakeNamespaceObjectRuntimeModule.js @@ -8,16 +8,19 @@ const RuntimeGlobals = require("../RuntimeGlobals"); const Template = require("../Template"); const HelperRuntimeModule = require("./HelperRuntimeModule"); +/** @typedef {import("../Compilation")} Compilation */ + class MakeNamespaceObjectRuntimeModule extends HelperRuntimeModule { constructor() { super("make namespace object"); } /** - * @returns {string} runtime code + * @returns {string | null} runtime code */ generate() { - const { runtimeTemplate } = this.compilation; + const compilation = /** @type {Compilation} */ (this.compilation); + const { runtimeTemplate } = compilation; const fn = RuntimeGlobals.makeNamespaceObject; return Template.asString([ "// define __esModule on exports", diff --git a/lib/runtime/NonceRuntimeModule.js b/lib/runtime/NonceRuntimeModule.js new file mode 100644 index 00000000000..238407c1ba6 --- /dev/null +++ b/lib/runtime/NonceRuntimeModule.js @@ -0,0 +1,24 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Ivan Kopeykin @vankop +*/ + +"use strict"; + +const RuntimeGlobals = require("../RuntimeGlobals"); +const RuntimeModule = require("../RuntimeModule"); + +class NonceRuntimeModule extends RuntimeModule { + constructor() { + super("nonce", RuntimeModule.STAGE_ATTACH); + } + + /** + * @returns {string | null} runtime code + */ + generate() { + return `${RuntimeGlobals.scriptNonce} = undefined;`; + } +} + +module.exports = NonceRuntimeModule; diff --git a/lib/runtime/OnChunksLoadedRuntimeModule.js b/lib/runtime/OnChunksLoadedRuntimeModule.js index d17bb7dd182..2224d02bb4a 100644 --- a/lib/runtime/OnChunksLoadedRuntimeModule.js +++ b/lib/runtime/OnChunksLoadedRuntimeModule.js @@ -8,62 +8,69 @@ const RuntimeGlobals = require("../RuntimeGlobals"); const RuntimeModule = require("../RuntimeModule"); const Template = require("../Template"); +/** @typedef {import("../Compilation")} Compilation */ + class OnChunksLoadedRuntimeModule extends RuntimeModule { constructor() { super("chunk loaded"); } /** - * @returns {string} runtime code + * @returns {string | null} runtime code */ generate() { - const { compilation } = this; + const compilation = /** @type {Compilation} */ (this.compilation); const { runtimeTemplate } = compilation; return Template.asString([ "var deferred = [];", - `${ - RuntimeGlobals.onChunksLoaded - } = ${runtimeTemplate.basicFunction("result, chunkIds, fn, priority", [ - "if(chunkIds) {", - Template.indent([ - "priority = priority || 0;", - "for(var i = deferred.length; i > 0 && deferred[i - 1][2] > priority; i--) deferred[i] = deferred[i - 1];", - "deferred[i] = [chunkIds, fn, priority];", - "return;" - ]), - "}", - "var notFulfilled = Infinity;", - "for (var i = 0; i < deferred.length; i++) {", - Template.indent([ - runtimeTemplate.destructureArray( - ["chunkIds", "fn", "priority"], - "deferred[i]" - ), - "var fulfilled = true;", - "for (var j = 0; j < chunkIds.length; j++) {", + `${RuntimeGlobals.onChunksLoaded} = ${runtimeTemplate.basicFunction( + "result, chunkIds, fn, priority", + [ + "if(chunkIds) {", + Template.indent([ + "priority = priority || 0;", + "for(var i = deferred.length; i > 0 && deferred[i - 1][2] > priority; i--) deferred[i] = deferred[i - 1];", + "deferred[i] = [chunkIds, fn, priority];", + "return;" + ]), + "}", + "var notFulfilled = Infinity;", + "for (var i = 0; i < deferred.length; i++) {", Template.indent([ - `if ((priority & 1 === 0 || notFulfilled >= priority) && Object.keys(${ - RuntimeGlobals.onChunksLoaded - }).every(${runtimeTemplate.returningFunction( - `${RuntimeGlobals.onChunksLoaded}[key](chunkIds[j])`, - "key" - )})) {`, - Template.indent(["chunkIds.splice(j--, 1);"]), - "} else {", + runtimeTemplate.destructureArray( + ["chunkIds", "fn", "priority"], + "deferred[i]" + ), + "var fulfilled = true;", + "for (var j = 0; j < chunkIds.length; j++) {", + Template.indent([ + `if ((priority & 1 === 0 || notFulfilled >= priority) && Object.keys(${ + RuntimeGlobals.onChunksLoaded + }).every(${runtimeTemplate.returningFunction( + `${RuntimeGlobals.onChunksLoaded}[key](chunkIds[j])`, + "key" + )})) {`, + Template.indent(["chunkIds.splice(j--, 1);"]), + "} else {", + Template.indent([ + "fulfilled = false;", + "if(priority < notFulfilled) notFulfilled = priority;" + ]), + "}" + ]), + "}", + "if(fulfilled) {", Template.indent([ - "fulfilled = false;", - "if(priority < notFulfilled) notFulfilled = priority;" + "deferred.splice(i--, 1)", + "var r = fn();", + "if (r !== undefined) result = r;" ]), "}" ]), "}", - "if(fulfilled) {", - Template.indent(["deferred.splice(i--, 1)", "result = fn();"]), - "}" - ]), - "}", - "return result;" - ])};` + "return result;" + ] + )};` ]); } } diff --git a/lib/runtime/PublicPathRuntimeModule.js b/lib/runtime/PublicPathRuntimeModule.js index 9a17bda3f78..7ea226161c9 100644 --- a/lib/runtime/PublicPathRuntimeModule.js +++ b/lib/runtime/PublicPathRuntimeModule.js @@ -7,21 +7,28 @@ const RuntimeGlobals = require("../RuntimeGlobals"); const RuntimeModule = require("../RuntimeModule"); +/** @typedef {import("../../declarations/WebpackOptions").OutputNormalized} OutputOptions */ +/** @typedef {import("../Compilation")} Compilation */ + class PublicPathRuntimeModule extends RuntimeModule { - constructor() { + /** + * @param {OutputOptions["publicPath"]} publicPath public path + */ + constructor(publicPath) { super("publicPath", RuntimeModule.STAGE_BASIC); + this.publicPath = publicPath; } /** - * @returns {string} runtime code + * @returns {string | null} runtime code */ generate() { - const { compilation } = this; - const { publicPath } = compilation.outputOptions; + const { publicPath } = this; + const compilation = /** @type {Compilation} */ (this.compilation); return `${RuntimeGlobals.publicPath} = ${JSON.stringify( - this.compilation.getPath(publicPath || "", { - hash: this.compilation.hash || "XXXX" + compilation.getPath(publicPath || "", { + hash: compilation.hash || "XXXX" }) )};`; } diff --git a/lib/runtime/RelativeUrlRuntimeModule.js b/lib/runtime/RelativeUrlRuntimeModule.js index c9251d95725..92e32daed98 100644 --- a/lib/runtime/RelativeUrlRuntimeModule.js +++ b/lib/runtime/RelativeUrlRuntimeModule.js @@ -8,16 +8,19 @@ const RuntimeGlobals = require("../RuntimeGlobals"); const Template = require("../Template"); const HelperRuntimeModule = require("./HelperRuntimeModule"); +/** @typedef {import("../Compilation")} Compilation */ + class RelativeUrlRuntimeModule extends HelperRuntimeModule { constructor() { super("relative url"); } /** - * @returns {string} runtime code + * @returns {string | null} runtime code */ generate() { - const { runtimeTemplate } = this.compilation; + const compilation = /** @type {Compilation} */ (this.compilation); + const { runtimeTemplate } = compilation; return Template.asString([ `${RuntimeGlobals.relativeUrl} = function RelativeURL(url) {`, Template.indent([ @@ -30,7 +33,7 @@ class RelativeUrlRuntimeModule extends HelperRuntimeModule { `values.toString = values.toJSON = ${runtimeTemplate.returningFunction( "url" )};`, - "for (var key in values) Object.defineProperty(this, key, Object.assign({ enumerable: true, configurable: true, value: values[key] }));" + "for (var key in values) Object.defineProperty(this, key, { enumerable: true, configurable: true, value: values[key] });" ]), "};", `${RuntimeGlobals.relativeUrl}.prototype = URL.prototype;` diff --git a/lib/runtime/RuntimeIdRuntimeModule.js b/lib/runtime/RuntimeIdRuntimeModule.js index 7e046eb6e8f..1923bafca7e 100644 --- a/lib/runtime/RuntimeIdRuntimeModule.js +++ b/lib/runtime/RuntimeIdRuntimeModule.js @@ -7,17 +7,20 @@ const RuntimeGlobals = require("../RuntimeGlobals"); const RuntimeModule = require("../RuntimeModule"); +/** @typedef {import("../Chunk")} Chunk */ +/** @typedef {import("../ChunkGraph")} ChunkGraph */ + class RuntimeIdRuntimeModule extends RuntimeModule { constructor() { super("runtimeId"); } /** - * @returns {string} runtime code + * @returns {string | null} runtime code */ generate() { - const { chunk, compilation } = this; - const { chunkGraph } = compilation; + const chunkGraph = /** @type {ChunkGraph} */ (this.chunkGraph); + const chunk = /** @type {Chunk} */ (this.chunk); const runtime = chunk.runtime; if (typeof runtime !== "string") throw new Error("RuntimeIdRuntimeModule must be in a single runtime"); diff --git a/lib/runtime/StartupChunkDependenciesPlugin.js b/lib/runtime/StartupChunkDependenciesPlugin.js index ff393471c09..6fc74cde8ce 100644 --- a/lib/runtime/StartupChunkDependenciesPlugin.js +++ b/lib/runtime/StartupChunkDependenciesPlugin.js @@ -8,9 +8,20 @@ const RuntimeGlobals = require("../RuntimeGlobals"); const StartupChunkDependenciesRuntimeModule = require("./StartupChunkDependenciesRuntimeModule"); const StartupEntrypointRuntimeModule = require("./StartupEntrypointRuntimeModule"); +/** @typedef {import("../../declarations/WebpackOptions").ChunkLoadingType} ChunkLoadingType */ +/** @typedef {import("../Chunk")} Chunk */ /** @typedef {import("../Compiler")} Compiler */ +/** + * @typedef {object} Options + * @property {ChunkLoadingType} chunkLoading + * @property {boolean=} asyncChunkLoading + */ + class StartupChunkDependenciesPlugin { + /** + * @param {Options} options options + */ constructor(options) { this.chunkLoading = options.chunkLoading; this.asyncChunkLoading = @@ -29,17 +40,23 @@ class StartupChunkDependenciesPlugin { "StartupChunkDependenciesPlugin", compilation => { const globalChunkLoading = compilation.outputOptions.chunkLoading; + /** + * @param {Chunk} chunk chunk to check + * @returns {boolean} true, when the plugin is enabled for the chunk + */ const isEnabledForChunk = chunk => { const options = chunk.getEntryOptions(); const chunkLoading = - (options && options.chunkLoading) || globalChunkLoading; + options && options.chunkLoading !== undefined + ? options.chunkLoading + : globalChunkLoading; return chunkLoading === this.chunkLoading; }; compilation.hooks.additionalTreeRuntimeRequirements.tap( "StartupChunkDependenciesPlugin", - (chunk, set) => { + (chunk, set, { chunkGraph }) => { if (!isEnabledForChunk(chunk)) return; - if (compilation.chunkGraph.hasChunkEntryDependentChunks(chunk)) { + if (chunkGraph.hasChunkEntryDependentChunks(chunk)) { set.add(RuntimeGlobals.startup); set.add(RuntimeGlobals.ensureChunk); set.add(RuntimeGlobals.ensureChunkIncludeEntries); diff --git a/lib/runtime/StartupChunkDependenciesRuntimeModule.js b/lib/runtime/StartupChunkDependenciesRuntimeModule.js index efcc1c22b33..da2ec7548eb 100644 --- a/lib/runtime/StartupChunkDependenciesRuntimeModule.js +++ b/lib/runtime/StartupChunkDependenciesRuntimeModule.js @@ -9,23 +9,30 @@ const RuntimeGlobals = require("../RuntimeGlobals"); const RuntimeModule = require("../RuntimeModule"); const Template = require("../Template"); +/** @typedef {import("../Chunk")} Chunk */ +/** @typedef {import("../ChunkGraph")} ChunkGraph */ +/** @typedef {import("../Compilation")} Compilation */ + class StartupChunkDependenciesRuntimeModule extends RuntimeModule { + /** + * @param {boolean} asyncChunkLoading use async chunk loading + */ constructor(asyncChunkLoading) { super("startup chunk dependencies", RuntimeModule.STAGE_TRIGGER); this.asyncChunkLoading = asyncChunkLoading; } /** - * @returns {string} runtime code + * @returns {string | null} runtime code */ generate() { - const { chunk, compilation } = this; - const { chunkGraph, runtimeTemplate } = compilation; + const chunkGraph = /** @type {ChunkGraph} */ (this.chunkGraph); + const chunk = /** @type {Chunk} */ (this.chunk); const chunkIds = Array.from( chunkGraph.getChunkEntryDependentChunksIterable(chunk) - ).map(chunk => { - return chunk.id; - }); + ).map(chunk => chunk.id); + const compilation = /** @type {Compilation} */ (this.compilation); + const { runtimeTemplate } = compilation; return Template.asString([ `var next = ${RuntimeGlobals.startup};`, `${RuntimeGlobals.startup} = ${runtimeTemplate.basicFunction( @@ -37,28 +44,29 @@ class StartupChunkDependenciesRuntimeModule extends RuntimeModule { ) .concat("return next();") : chunkIds.length === 1 - ? `return ${RuntimeGlobals.ensureChunk}(${JSON.stringify( - chunkIds[0] - )}).then(next);` - : chunkIds.length > 2 - ? [ - // using map is shorter for 3 or more chunks - `return Promise.all(${JSON.stringify(chunkIds)}.map(${ - RuntimeGlobals.ensureChunk - }, __webpack_require__)).then(next);` - ] - : [ - // calling ensureChunk directly is shorter for 0 - 2 chunks - "return Promise.all([", - Template.indent( - chunkIds - .map( - id => `${RuntimeGlobals.ensureChunk}(${JSON.stringify(id)})` - ) - .join(",\n") - ), - "]).then(next);" - ] + ? `return ${RuntimeGlobals.ensureChunk}(${JSON.stringify( + chunkIds[0] + )}).then(next);` + : chunkIds.length > 2 + ? [ + // using map is shorter for 3 or more chunks + `return Promise.all(${JSON.stringify(chunkIds)}.map(${ + RuntimeGlobals.ensureChunk + }, ${RuntimeGlobals.require})).then(next);` + ] + : [ + // calling ensureChunk directly is shorter for 0 - 2 chunks + "return Promise.all([", + Template.indent( + chunkIds + .map( + id => + `${RuntimeGlobals.ensureChunk}(${JSON.stringify(id)})` + ) + .join(",\n") + ), + "]).then(next);" + ] )};` ]); } diff --git a/lib/runtime/StartupEntrypointRuntimeModule.js b/lib/runtime/StartupEntrypointRuntimeModule.js index b5413bea160..5133767dab3 100644 --- a/lib/runtime/StartupEntrypointRuntimeModule.js +++ b/lib/runtime/StartupEntrypointRuntimeModule.js @@ -7,19 +7,23 @@ const RuntimeGlobals = require("../RuntimeGlobals"); const RuntimeModule = require("../RuntimeModule"); +/** @typedef {import("../Compilation")} Compilation */ /** @typedef {import("../MainTemplate")} MainTemplate */ class StartupEntrypointRuntimeModule extends RuntimeModule { + /** + * @param {boolean} asyncChunkLoading use async chunk loading + */ constructor(asyncChunkLoading) { super("startup entrypoint"); this.asyncChunkLoading = asyncChunkLoading; } /** - * @returns {string} runtime code + * @returns {string | null} runtime code */ generate() { - const { compilation } = this; + const compilation = /** @type {Compilation} */ (this.compilation); const { runtimeTemplate } = compilation; return `${ RuntimeGlobals.startupEntrypoint @@ -27,22 +31,22 @@ class StartupEntrypointRuntimeModule extends RuntimeModule { "// arguments: chunkIds, moduleId are deprecated", "var moduleId = chunkIds;", `if(!fn) chunkIds = result, fn = ${runtimeTemplate.returningFunction( - `__webpack_require__(${RuntimeGlobals.entryModuleId} = moduleId)` + `${RuntimeGlobals.require}(${RuntimeGlobals.entryModuleId} = moduleId)` )};`, ...(this.asyncChunkLoading ? [ - `return Promise.all(chunkIds.map(${ - RuntimeGlobals.ensureChunk - }, __webpack_require__)).then(${runtimeTemplate.basicFunction("", [ + `return Promise.all(chunkIds.map(${RuntimeGlobals.ensureChunk}, ${ + RuntimeGlobals.require + })).then(${runtimeTemplate.basicFunction("", [ "var r = fn();", "return r === undefined ? result : r;" ])})` - ] + ] : [ - `chunkIds.map(${RuntimeGlobals.ensureChunk}, __webpack_require__)`, + `chunkIds.map(${RuntimeGlobals.ensureChunk}, ${RuntimeGlobals.require})`, "var r = fn();", "return r === undefined ? result : r;" - ]) + ]) ])}`; } } diff --git a/lib/runtime/SystemContextRuntimeModule.js b/lib/runtime/SystemContextRuntimeModule.js index 141832990db..b7663ffde1c 100644 --- a/lib/runtime/SystemContextRuntimeModule.js +++ b/lib/runtime/SystemContextRuntimeModule.js @@ -15,7 +15,7 @@ class SystemContextRuntimeModule extends RuntimeModule { } /** - * @returns {string} runtime code + * @returns {string | null} runtime code */ generate() { return `${RuntimeGlobals.systemContext} = __system_context__;`; diff --git a/lib/schemes/DataUriPlugin.js b/lib/schemes/DataUriPlugin.js index fb132a7abf3..f5db88dc462 100644 --- a/lib/schemes/DataUriPlugin.js +++ b/lib/schemes/DataUriPlugin.js @@ -6,10 +6,37 @@ "use strict"; const NormalModule = require("../NormalModule"); -const { getMimetype, decodeDataURI } = require("../util/DataURI"); /** @typedef {import("../Compiler")} Compiler */ +// data URL scheme: "data:text/javascript;charset=utf-8;base64,some-string" +// http://www.ietf.org/rfc/rfc2397.txt +const URIRegEx = /^data:([^;,]+)?((?:;[^;,]+)*?)(?:;(base64))?,(.*)$/i; + +/** + * @param {string} uri data URI + * @returns {Buffer | null} decoded data + */ +const decodeDataURI = uri => { + const match = URIRegEx.exec(uri); + if (!match) return null; + + const isBase64 = match[3]; + const body = match[4]; + + if (isBase64) { + return Buffer.from(body, "base64"); + } + + // CSS allows to use `data:image/svg+xml;utf8,` + // so we return original body if we can't `decodeURIComponent` + try { + return Buffer.from(decodeURIComponent(body), "ascii"); + } catch (_) { + return Buffer.from(body, "ascii"); + } +}; + class DataUriPlugin { /** * Apply the plugin @@ -23,7 +50,13 @@ class DataUriPlugin { normalModuleFactory.hooks.resolveForScheme .for("data") .tap("DataUriPlugin", resourceData => { - resourceData.data.mimetype = getMimetype(resourceData.resource); + const match = URIRegEx.exec(resourceData.resource); + if (match) { + resourceData.data.mimetype = match[1] || ""; + resourceData.data.parameters = match[2] || ""; + resourceData.data.encoding = match[3] || false; + resourceData.data.encodedContent = match[4] || ""; + } }); NormalModule.getCompilationHooks(compilation) .readResourceForScheme.for("data") diff --git a/lib/schemes/FileUriPlugin.js b/lib/schemes/FileUriPlugin.js index 9ed1cb91485..453abbd3b13 100644 --- a/lib/schemes/FileUriPlugin.js +++ b/lib/schemes/FileUriPlugin.js @@ -6,6 +6,7 @@ "use strict"; const { URL, fileURLToPath } = require("url"); +const { NormalModule } = require(".."); /** @typedef {import("../Compiler")} Compiler */ @@ -32,6 +33,14 @@ class FileUriPlugin { resourceData.resource = path + query + fragment; return true; }); + const hooks = NormalModule.getCompilationHooks(compilation); + hooks.readResource + .for(undefined) + .tapAsync("FileUriPlugin", (loaderContext, callback) => { + const { resourcePath } = loaderContext; + loaderContext.addDependency(resourcePath); + loaderContext.fs.readFile(resourcePath, callback); + }); } ); } diff --git a/lib/schemes/HttpUriPlugin.js b/lib/schemes/HttpUriPlugin.js index 92985f9c69d..510b189f242 100644 --- a/lib/schemes/HttpUriPlugin.js +++ b/lib/schemes/HttpUriPlugin.js @@ -5,56 +5,1264 @@ "use strict"; +const EventEmitter = require("events"); +const { extname, basename } = require("path"); const { URL } = require("url"); +const { createGunzip, createBrotliDecompress, createInflate } = require("zlib"); const NormalModule = require("../NormalModule"); +const createSchemaValidation = require("../util/create-schema-validation"); +const createHash = require("../util/createHash"); +const { mkdirp, dirname, join } = require("../util/fs"); +const memoize = require("../util/memoize"); +/** @typedef {import("http").IncomingMessage} IncomingMessage */ +/** @typedef {import("http").RequestOptions} RequestOptions */ +/** @typedef {import("net").Socket} Socket */ +/** @typedef {import("stream").Readable} Readable */ +/** @typedef {import("../../declarations/plugins/schemes/HttpUriPlugin").HttpUriPluginOptions} HttpUriPluginOptions */ /** @typedef {import("../Compiler")} Compiler */ +/** @typedef {import("../FileSystemInfo").Snapshot} Snapshot */ +/** @typedef {import("../Module").BuildInfo} BuildInfo */ +/** @typedef {import("../NormalModuleFactory").ResourceDataWithData} ResourceDataWithData */ +/** @typedef {import("../util/fs").IntermediateFileSystem} IntermediateFileSystem */ + +const getHttp = memoize(() => require("http")); +const getHttps = memoize(() => require("https")); + +/** + * @param {typeof import("http") | typeof import("https")} request request + * @param {string | { toString: () => string } | undefined} proxy proxy + * @returns {function(URL, RequestOptions, function(IncomingMessage): void): EventEmitter} fn + */ +const proxyFetch = (request, proxy) => (url, options, callback) => { + const eventEmitter = new EventEmitter(); + + /** + * @param {Socket=} socket socket + * @returns {void} + */ + const doRequest = socket => { + request + .get(url, { ...options, ...(socket && { socket }) }, callback) + .on("error", eventEmitter.emit.bind(eventEmitter, "error")); + }; + + if (proxy) { + const { hostname: host, port } = new URL(proxy); + + getHttp() + .request({ + host, // IP address of proxy server + port, // port of proxy server + method: "CONNECT", + path: url.host + }) + .on("connect", (res, socket) => { + if (res.statusCode === 200) { + // connected to proxy server + doRequest(socket); + } + }) + .on("error", err => { + eventEmitter.emit( + "error", + new Error( + `Failed to connect to proxy server "${proxy}": ${err.message}` + ) + ); + }) + .end(); + } else { + doRequest(); + } + + return eventEmitter; +}; + +/** @typedef {() => void} InProgressWriteItem */ +/** @type {InProgressWriteItem[] | undefined} */ +let inProgressWrite; + +const validate = createSchemaValidation( + require("../../schemas/plugins/schemes/HttpUriPlugin.check.js"), + () => require("../../schemas/plugins/schemes/HttpUriPlugin.json"), + { + name: "Http Uri Plugin", + baseDataPath: "options" + } +); + +/** + * @param {string} str path + * @returns {string} safe path + */ +const toSafePath = str => + str + .replace(/^[^a-zA-Z0-9]+|[^a-zA-Z0-9]+$/g, "") + .replace(/[^a-zA-Z0-9._-]+/g, "_"); + +/** + * @param {Buffer} content content + * @returns {string} integrity + */ +const computeIntegrity = content => { + const hash = createHash("sha512"); + hash.update(content); + const integrity = `sha512-${hash.digest("base64")}`; + return integrity; +}; + +/** + * @param {Buffer} content content + * @param {string} integrity integrity + * @returns {boolean} true, if integrity matches + */ +const verifyIntegrity = (content, integrity) => { + if (integrity === "ignore") return true; + return computeIntegrity(content) === integrity; +}; + +/** + * @param {string} str input + * @returns {Record} parsed + */ +const parseKeyValuePairs = str => { + /** @type {Record} */ + const result = {}; + for (const item of str.split(",")) { + const i = item.indexOf("="); + if (i >= 0) { + const key = item.slice(0, i).trim(); + const value = item.slice(i + 1).trim(); + result[key] = value; + } else { + const key = item.trim(); + if (!key) continue; + result[key] = key; + } + } + return result; +}; + +/** + * @param {string | undefined} cacheControl Cache-Control header + * @param {number} requestTime timestamp of request + * @returns {{storeCache: boolean, storeLock: boolean, validUntil: number}} Logic for storing in cache and lockfile cache + */ +const parseCacheControl = (cacheControl, requestTime) => { + // When false resource is not stored in cache + let storeCache = true; + // When false resource is not stored in lockfile cache + let storeLock = true; + // Resource is only revalidated, after that timestamp and when upgrade is chosen + let validUntil = 0; + if (cacheControl) { + const parsed = parseKeyValuePairs(cacheControl); + if (parsed["no-cache"]) storeCache = storeLock = false; + if (parsed["max-age"] && !Number.isNaN(Number(parsed["max-age"]))) { + validUntil = requestTime + Number(parsed["max-age"]) * 1000; + } + if (parsed["must-revalidate"]) validUntil = 0; + } + return { + storeLock, + storeCache, + validUntil + }; +}; + +/** + * @typedef {object} LockfileEntry + * @property {string} resolved + * @property {string} integrity + * @property {string} contentType + */ + +/** + * @param {LockfileEntry} a first lockfile entry + * @param {LockfileEntry} b second lockfile entry + * @returns {boolean} true when equal, otherwise false + */ +const areLockfileEntriesEqual = (a, b) => + a.resolved === b.resolved && + a.integrity === b.integrity && + a.contentType === b.contentType; + +/** + * @param {LockfileEntry} entry lockfile entry + * @returns {`resolved: ${string}, integrity: ${string}, contentType: ${*}`} stringified entry + */ +const entryToString = entry => + `resolved: ${entry.resolved}, integrity: ${entry.integrity}, contentType: ${entry.contentType}`; + +class Lockfile { + constructor() { + this.version = 1; + /** @type {Map} */ + this.entries = new Map(); + } + + /** + * @param {string} content content of the lockfile + * @returns {Lockfile} lockfile + */ + static parse(content) { + // TODO handle merge conflicts + const data = JSON.parse(content); + if (data.version !== 1) + throw new Error(`Unsupported lockfile version ${data.version}`); + const lockfile = new Lockfile(); + for (const key of Object.keys(data)) { + if (key === "version") continue; + const entry = data[key]; + lockfile.entries.set( + key, + typeof entry === "string" + ? entry + : { + resolved: key, + ...entry + } + ); + } + return lockfile; + } + + /** + * @returns {string} stringified lockfile + */ + toString() { + let str = "{\n"; + const entries = Array.from(this.entries).sort(([a], [b]) => + a < b ? -1 : 1 + ); + for (const [key, entry] of entries) { + if (typeof entry === "string") { + str += ` ${JSON.stringify(key)}: ${JSON.stringify(entry)},\n`; + } else { + str += ` ${JSON.stringify(key)}: { `; + if (entry.resolved !== key) + str += `"resolved": ${JSON.stringify(entry.resolved)}, `; + str += `"integrity": ${JSON.stringify( + entry.integrity + )}, "contentType": ${JSON.stringify(entry.contentType)} },\n`; + } + } + str += ` "version": ${this.version}\n}\n`; + return str; + } +} + +/** + * @template R + * @param {function(function(Error | null, R=): void): void} fn function + * @returns {function(function(Error | null, R=): void): void} cached function + */ +const cachedWithoutKey = fn => { + let inFlight = false; + /** @type {Error | undefined} */ + let cachedError; + /** @type {R | undefined} */ + let cachedResult; + /** @type {(function(Error| null, R=): void)[] | undefined} */ + let cachedCallbacks; + return callback => { + if (inFlight) { + if (cachedResult !== undefined) return callback(null, cachedResult); + if (cachedError !== undefined) return callback(cachedError); + if (cachedCallbacks === undefined) cachedCallbacks = [callback]; + else cachedCallbacks.push(callback); + return; + } + inFlight = true; + fn((err, result) => { + if (err) cachedError = err; + else cachedResult = result; + const callbacks = cachedCallbacks; + cachedCallbacks = undefined; + callback(err, result); + if (callbacks !== undefined) for (const cb of callbacks) cb(err, result); + }); + }; +}; + +/** + * @template T + * @template R + * @param {function(T, function(Error | null, R=): void): void} fn function + * @param {function(T, function(Error | null, R=): void): void=} forceFn function for the second try + * @returns {(function(T, function(Error | null, R=): void): void) & { force: function(T, function(Error | null, R=): void): void }} cached function + */ +const cachedWithKey = (fn, forceFn = fn) => { + /** + * @template R + * @typedef {{ result?: R, error?: Error, callbacks?: (function(Error | null, R=): void)[], force?: true }} CacheEntry + */ + /** @type {Map>} */ + const cache = new Map(); + /** + * @param {T} arg arg + * @param {function(Error | null, R=): void} callback callback + * @returns {void} + */ + const resultFn = (arg, callback) => { + const cacheEntry = cache.get(arg); + if (cacheEntry !== undefined) { + if (cacheEntry.result !== undefined) + return callback(null, cacheEntry.result); + if (cacheEntry.error !== undefined) return callback(cacheEntry.error); + if (cacheEntry.callbacks === undefined) cacheEntry.callbacks = [callback]; + else cacheEntry.callbacks.push(callback); + return; + } + /** @type {CacheEntry} */ + const newCacheEntry = { + result: undefined, + error: undefined, + callbacks: undefined + }; + cache.set(arg, newCacheEntry); + fn(arg, (err, result) => { + if (err) newCacheEntry.error = err; + else newCacheEntry.result = result; + const callbacks = newCacheEntry.callbacks; + newCacheEntry.callbacks = undefined; + callback(err, result); + if (callbacks !== undefined) for (const cb of callbacks) cb(err, result); + }); + }; + /** + * @param {T} arg arg + * @param {function(Error | null, R=): void} callback callback + * @returns {void} + */ + resultFn.force = (arg, callback) => { + const cacheEntry = cache.get(arg); + if (cacheEntry !== undefined && cacheEntry.force) { + if (cacheEntry.result !== undefined) + return callback(null, cacheEntry.result); + if (cacheEntry.error !== undefined) return callback(cacheEntry.error); + if (cacheEntry.callbacks === undefined) cacheEntry.callbacks = [callback]; + else cacheEntry.callbacks.push(callback); + return; + } + /** @type {CacheEntry} */ + const newCacheEntry = { + result: undefined, + error: undefined, + callbacks: undefined, + force: true + }; + cache.set(arg, newCacheEntry); + forceFn(arg, (err, result) => { + if (err) newCacheEntry.error = err; + else newCacheEntry.result = result; + const callbacks = newCacheEntry.callbacks; + newCacheEntry.callbacks = undefined; + callback(err, result); + if (callbacks !== undefined) for (const cb of callbacks) cb(err, result); + }); + }; + return resultFn; +}; + +/** + * @typedef {object} LockfileCache + * @property {Lockfile} lockfile lockfile + * @property {Snapshot} snapshot snapshot + */ + +/** + * @typedef {object} ResolveContentResult + * @property {LockfileEntry} entry lockfile entry + * @property {Buffer} content content + * @property {boolean} storeLock need store lockfile + */ + +/** @typedef {{ storeCache: boolean, storeLock: boolean, validUntil: number, etag: string | undefined, fresh: boolean }} FetchResultMeta */ +/** @typedef {FetchResultMeta & { location: string }} RedirectFetchResult */ +/** @typedef {FetchResultMeta & { entry: LockfileEntry, content: Buffer }} ContentFetchResult */ +/** @typedef {RedirectFetchResult | ContentFetchResult} FetchResult */ class HttpUriPlugin { + /** + * @param {HttpUriPluginOptions} options options + */ + constructor(options) { + validate(options); + this._lockfileLocation = options.lockfileLocation; + this._cacheLocation = options.cacheLocation; + this._upgrade = options.upgrade; + this._frozen = options.frozen; + this._allowedUris = options.allowedUris; + this._proxy = options.proxy; + } + /** * Apply the plugin * @param {Compiler} compiler the compiler instance * @returns {void} */ apply(compiler) { + const proxy = + this._proxy || process.env.http_proxy || process.env.HTTP_PROXY; + const schemes = [ + { + scheme: "http", + fetch: proxyFetch(getHttp(), proxy) + }, + { + scheme: "https", + fetch: proxyFetch(getHttps(), proxy) + } + ]; + /** @type {LockfileCache} */ + let lockfileCache; compiler.hooks.compilation.tap( "HttpUriPlugin", (compilation, { normalModuleFactory }) => { - normalModuleFactory.hooks.resolveForScheme - .for("http") - .tap("HttpUriPlugin", resourceData => { - const url = new URL(resourceData.resource); - resourceData.path = url.origin + url.pathname; - resourceData.query = url.search; - resourceData.fragment = url.hash; - return /** @type {true} */ (true); - }); - NormalModule.getCompilationHooks(compilation) - .readResourceForScheme.for("http") - .tapAsync("HttpUriPlugin", (resource, module, callback) => { - return require("http").get(new URL(resource), res => { - if (res.statusCode !== 200) { - res.destroy(); - return callback( - new Error(`http request status code = ${res.statusCode}`) + const intermediateFs = + /** @type {IntermediateFileSystem} */ + (compiler.intermediateFileSystem); + const fs = compilation.inputFileSystem; + const cache = compilation.getCache("webpack.HttpUriPlugin"); + const logger = compilation.getLogger("webpack.HttpUriPlugin"); + /** @type {string} */ + const lockfileLocation = + this._lockfileLocation || + join( + intermediateFs, + compiler.context, + compiler.name + ? `${toSafePath(compiler.name)}.webpack.lock` + : "webpack.lock" + ); + /** @type {string | false} */ + const cacheLocation = + this._cacheLocation !== undefined + ? this._cacheLocation + : `${lockfileLocation}.data`; + const upgrade = this._upgrade || false; + const frozen = this._frozen || false; + const hashFunction = "sha512"; + const hashDigest = "hex"; + const hashDigestLength = 20; + const allowedUris = this._allowedUris; + + let warnedAboutEol = false; + + /** @type {Map} */ + const cacheKeyCache = new Map(); + /** + * @param {string} url the url + * @returns {string} the key + */ + const getCacheKey = url => { + const cachedResult = cacheKeyCache.get(url); + if (cachedResult !== undefined) return cachedResult; + const result = _getCacheKey(url); + cacheKeyCache.set(url, result); + return result; + }; + + /** + * @param {string} url the url + * @returns {string} the key + */ + const _getCacheKey = url => { + const parsedUrl = new URL(url); + const folder = toSafePath(parsedUrl.origin); + const name = toSafePath(parsedUrl.pathname); + const query = toSafePath(parsedUrl.search); + let ext = extname(name); + if (ext.length > 20) ext = ""; + const basename = ext ? name.slice(0, -ext.length) : name; + const hash = createHash(hashFunction); + hash.update(url); + const digest = hash.digest(hashDigest).slice(0, hashDigestLength); + return `${folder.slice(-50)}/${`${basename}${ + query ? `_${query}` : "" + }`.slice(0, 150)}_${digest}${ext}`; + }; + + const getLockfile = cachedWithoutKey( + /** + * @param {function(Error | null, Lockfile=): void} callback callback + * @returns {void} + */ + callback => { + const readLockfile = () => { + intermediateFs.readFile(lockfileLocation, (err, buffer) => { + if (err && err.code !== "ENOENT") { + compilation.missingDependencies.add(lockfileLocation); + return callback(err); + } + compilation.fileDependencies.add(lockfileLocation); + compilation.fileSystemInfo.createSnapshot( + compiler.fsStartTime, + buffer ? [lockfileLocation] : [], + [], + buffer ? [] : [lockfileLocation], + { timestamp: true }, + (err, s) => { + if (err) return callback(err); + const lockfile = buffer + ? Lockfile.parse(buffer.toString("utf-8")) + : new Lockfile(); + lockfileCache = { + lockfile, + snapshot: /** @type {Snapshot} */ (s) + }; + callback(null, lockfile); + } ); - } + }); + }; + if (lockfileCache) { + compilation.fileSystemInfo.checkSnapshotValid( + lockfileCache.snapshot, + (err, valid) => { + if (err) return callback(err); + if (!valid) return readLockfile(); + callback(null, lockfileCache.lockfile); + } + ); + } else { + readLockfile(); + } + } + ); + + /** @typedef {Map} LockfileUpdates */ + + /** @type {LockfileUpdates | undefined} */ + let lockfileUpdates; - const bufferArr = []; + /** + * @param {Lockfile} lockfile lockfile instance + * @param {string} url url to store + * @param {LockfileEntry | "ignore" | "no-cache"} entry lockfile entry + */ + const storeLockEntry = (lockfile, url, entry) => { + const oldEntry = lockfile.entries.get(url); + if (lockfileUpdates === undefined) lockfileUpdates = new Map(); + lockfileUpdates.set(url, entry); + lockfile.entries.set(url, entry); + if (!oldEntry) { + logger.log(`${url} added to lockfile`); + } else if (typeof oldEntry === "string") { + if (typeof entry === "string") { + logger.log(`${url} updated in lockfile: ${oldEntry} -> ${entry}`); + } else { + logger.log( + `${url} updated in lockfile: ${oldEntry} -> ${entry.resolved}` + ); + } + } else if (typeof entry === "string") { + logger.log( + `${url} updated in lockfile: ${oldEntry.resolved} -> ${entry}` + ); + } else if (oldEntry.resolved !== entry.resolved) { + logger.log( + `${url} updated in lockfile: ${oldEntry.resolved} -> ${entry.resolved}` + ); + } else if (oldEntry.integrity !== entry.integrity) { + logger.log(`${url} updated in lockfile: content changed`); + } else if (oldEntry.contentType !== entry.contentType) { + logger.log( + `${url} updated in lockfile: ${oldEntry.contentType} -> ${entry.contentType}` + ); + } else { + logger.log(`${url} updated in lockfile`); + } + }; - res.on("data", chunk => { - bufferArr.push(chunk); + /** + * @param {Lockfile} lockfile lockfile + * @param {string} url url + * @param {ResolveContentResult} result result + * @param {function(Error | null, ResolveContentResult=): void} callback callback + * @returns {void} + */ + const storeResult = (lockfile, url, result, callback) => { + if (result.storeLock) { + storeLockEntry(lockfile, url, result.entry); + if (!cacheLocation || !result.content) + return callback(null, result); + const key = getCacheKey(result.entry.resolved); + const filePath = join(intermediateFs, cacheLocation, key); + mkdirp(intermediateFs, dirname(intermediateFs, filePath), err => { + if (err) return callback(err); + intermediateFs.writeFile(filePath, result.content, err => { + if (err) return callback(err); + callback(null, result); }); + }); + } else { + storeLockEntry(lockfile, url, "no-cache"); + callback(null, result); + } + }; - res.on("end", () => { - if (!res.complete) { - return callback(new Error("http request was terminated")); + for (const { scheme, fetch } of schemes) { + /** + * @param {string} url URL + * @param {string | null} integrity integrity + * @param {function(Error | null, ResolveContentResult=): void} callback callback + */ + const resolveContent = (url, integrity, callback) => { + /** + * @param {Error | null} err error + * @param {TODO} result result result + * @returns {void} + */ + const handleResult = (err, result) => { + if (err) return callback(err); + if ("location" in result) { + return resolveContent( + result.location, + integrity, + (err, innerResult) => { + if (err) return callback(err); + const { entry, content, storeLock } = + /** @type {ResolveContentResult} */ (innerResult); + callback(null, { + entry, + content, + storeLock: storeLock && result.storeLock + }); + } + ); + } + if ( + !result.fresh && + integrity && + result.entry.integrity !== integrity && + !verifyIntegrity(result.content, integrity) + ) { + return fetchContent.force(url, handleResult); + } + return callback(null, { + entry: result.entry, + content: result.content, + storeLock: result.storeLock + }); + }; + fetchContent(url, handleResult); + }; + + /** + * @param {string} url URL + * @param {FetchResult | RedirectFetchResult | undefined} cachedResult result from cache + * @param {function(Error | null, FetchResult=): void} callback callback + * @returns {void} + */ + const fetchContentRaw = (url, cachedResult, callback) => { + const requestTime = Date.now(); + fetch( + new URL(url), + { + headers: { + "accept-encoding": "gzip, deflate, br", + "user-agent": "webpack", + "if-none-match": /** @type {TODO} */ ( + cachedResult ? cachedResult.etag || null : null + ) } + }, + res => { + const etag = res.headers.etag; + const location = res.headers.location; + const cacheControl = res.headers["cache-control"]; + const { storeLock, storeCache, validUntil } = parseCacheControl( + cacheControl, + requestTime + ); + /** + * @param {Partial> & (Pick | Pick)} partialResult result + * @returns {void} + */ + const finishWith = partialResult => { + if ("location" in partialResult) { + logger.debug( + `GET ${url} [${res.statusCode}] -> ${partialResult.location}` + ); + } else { + logger.debug( + `GET ${url} [${res.statusCode}] ${Math.ceil( + partialResult.content.length / 1024 + )} kB${!storeLock ? " no-cache" : ""}` + ); + } + const result = { + ...partialResult, + fresh: true, + storeLock, + storeCache, + validUntil, + etag + }; + if (!storeCache) { + logger.log( + `${url} can't be stored in cache, due to Cache-Control header: ${cacheControl}` + ); + return callback(null, result); + } + cache.store( + url, + null, + { + ...result, + fresh: false + }, + err => { + if (err) { + logger.warn( + `${url} can't be stored in cache: ${err.message}` + ); + logger.debug(err.stack); + } + callback(null, result); + } + ); + }; + if (res.statusCode === 304) { + const result = /** @type {FetchResult} */ (cachedResult); + if ( + result.validUntil < validUntil || + result.storeLock !== storeLock || + result.storeCache !== storeCache || + result.etag !== etag + ) { + return finishWith(result); + } + logger.debug(`GET ${url} [${res.statusCode}] (unchanged)`); + return callback(null, { ...result, fresh: true }); + } + if ( + location && + res.statusCode && + res.statusCode >= 301 && + res.statusCode <= 308 + ) { + const result = { + location: new URL(location, url).href + }; + if ( + !cachedResult || + !("location" in cachedResult) || + cachedResult.location !== result.location || + cachedResult.validUntil < validUntil || + cachedResult.storeLock !== storeLock || + cachedResult.storeCache !== storeCache || + cachedResult.etag !== etag + ) { + return finishWith(result); + } + logger.debug(`GET ${url} [${res.statusCode}] (unchanged)`); + return callback(null, { + ...result, + fresh: true, + storeLock, + storeCache, + validUntil, + etag + }); + } + const contentType = res.headers["content-type"] || ""; + /** @type {Buffer[]} */ + const bufferArr = []; + + const contentEncoding = res.headers["content-encoding"]; + /** @type {Readable} */ + let stream = res; + if (contentEncoding === "gzip") { + stream = stream.pipe(createGunzip()); + } else if (contentEncoding === "br") { + stream = stream.pipe(createBrotliDecompress()); + } else if (contentEncoding === "deflate") { + stream = stream.pipe(createInflate()); + } + + stream.on("data", chunk => { + bufferArr.push(chunk); + }); + + stream.on("end", () => { + if (!res.complete) { + logger.log(`GET ${url} [${res.statusCode}] (terminated)`); + return callback(new Error(`${url} request was terminated`)); + } + + const content = Buffer.concat(bufferArr); + + if (res.statusCode !== 200) { + logger.log(`GET ${url} [${res.statusCode}]`); + return callback( + new Error( + `${url} request status code = ${ + res.statusCode + }\n${content.toString("utf-8")}` + ) + ); + } + + const integrity = computeIntegrity(content); + const entry = { resolved: url, integrity, contentType }; - callback(null, Buffer.concat(bufferArr)); + finishWith({ + entry, + content + }); + }); + } + ).on("error", err => { + logger.log(`GET ${url} (error)`); + err.message += `\nwhile fetching ${url}`; + callback(err); + }); + }; + + const fetchContent = cachedWithKey( + /** + * @param {string} url URL + * @param {function(Error | null, { validUntil: number, etag?: string, entry: LockfileEntry, content: Buffer, fresh: boolean } | { validUntil: number, etag?: string, location: string, fresh: boolean }=): void} callback callback + * @returns {void} + */ + (url, callback) => { + cache.get(url, null, (err, cachedResult) => { + if (err) return callback(err); + if (cachedResult) { + const isValid = cachedResult.validUntil >= Date.now(); + if (isValid) return callback(null, cachedResult); + } + fetchContentRaw(url, cachedResult, callback); + }); + }, + (url, callback) => fetchContentRaw(url, undefined, callback) + ); + + /** + * @param {string} uri uri + * @returns {boolean} true when allowed, otherwise false + */ + const isAllowed = uri => { + for (const allowed of allowedUris) { + if (typeof allowed === "string") { + if (uri.startsWith(allowed)) return true; + } else if (typeof allowed === "function") { + if (allowed(uri)) return true; + } else if (allowed.test(uri)) { + return true; + } + } + return false; + }; + + /** @typedef {{ entry: LockfileEntry, content: Buffer }} Info */ + + const getInfo = cachedWithKey( + /** + * @param {string} url the url + * @param {function(Error | null, Info=): void} callback callback + * @returns {void} + */ + // eslint-disable-next-line no-loop-func + (url, callback) => { + if (!isAllowed(url)) { + return callback( + new Error( + `${url} doesn't match the allowedUris policy. These URIs are allowed:\n${allowedUris + .map(uri => ` - ${uri}`) + .join("\n")}` + ) + ); + } + getLockfile((err, _lockfile) => { + if (err) return callback(err); + const lockfile = /** @type {Lockfile} */ (_lockfile); + const entryOrString = lockfile.entries.get(url); + if (!entryOrString) { + if (frozen) { + return callback( + new Error( + `${url} has no lockfile entry and lockfile is frozen` + ) + ); + } + resolveContent(url, null, (err, result) => { + if (err) return callback(err); + storeResult( + /** @type {Lockfile} */ + (lockfile), + url, + /** @type {ResolveContentResult} */ + (result), + callback + ); + }); + return; + } + if (typeof entryOrString === "string") { + const entryTag = entryOrString; + resolveContent(url, null, (err, _result) => { + if (err) return callback(err); + const result = + /** @type {ResolveContentResult} */ + (_result); + if (!result.storeLock || entryTag === "ignore") + return callback(null, result); + if (frozen) { + return callback( + new Error( + `${url} used to have ${entryTag} lockfile entry and has content now, but lockfile is frozen` + ) + ); + } + if (!upgrade) { + return callback( + new Error( + `${url} used to have ${entryTag} lockfile entry and has content now. +This should be reflected in the lockfile, so this lockfile entry must be upgraded, but upgrading is not enabled. +Remove this line from the lockfile to force upgrading.` + ) + ); + } + storeResult(lockfile, url, result, callback); + }); + return; + } + let entry = entryOrString; + /** + * @param {Buffer=} lockedContent locked content + */ + const doFetch = lockedContent => { + resolveContent(url, entry.integrity, (err, _result) => { + if (err) { + if (lockedContent) { + logger.warn( + `Upgrade request to ${url} failed: ${err.message}` + ); + logger.debug(err.stack); + return callback(null, { + entry, + content: lockedContent + }); + } + return callback(err); + } + const result = + /** @type {ResolveContentResult} */ + (_result); + if (!result.storeLock) { + // When the lockfile entry should be no-cache + // we need to update the lockfile + if (frozen) { + return callback( + new Error( + `${url} has a lockfile entry and is no-cache now, but lockfile is frozen\nLockfile: ${entryToString( + entry + )}` + ) + ); + } + storeResult(lockfile, url, result, callback); + return; + } + if (!areLockfileEntriesEqual(result.entry, entry)) { + // When the lockfile entry is outdated + // we need to update the lockfile + if (frozen) { + return callback( + new Error( + `${url} has an outdated lockfile entry, but lockfile is frozen\nLockfile: ${entryToString( + entry + )}\nExpected: ${entryToString(result.entry)}` + ) + ); + } + storeResult(lockfile, url, result, callback); + return; + } + if (!lockedContent && cacheLocation) { + // When the lockfile cache content is missing + // we need to update the lockfile + if (frozen) { + return callback( + new Error( + `${url} is missing content in the lockfile cache, but lockfile is frozen\nLockfile: ${entryToString( + entry + )}` + ) + ); + } + storeResult(lockfile, url, result, callback); + return; + } + return callback(null, result); + }); + }; + if (cacheLocation) { + // When there is a lockfile cache + // we read the content from there + const key = getCacheKey(entry.resolved); + const filePath = join(intermediateFs, cacheLocation, key); + fs.readFile(filePath, (err, result) => { + if (err) { + if (err.code === "ENOENT") return doFetch(); + return callback(err); + } + const content = /** @type {Buffer} */ (result); + /** + * @param {Buffer | undefined} _result result + * @returns {void} + */ + const continueWithCachedContent = _result => { + if (!upgrade) { + // When not in upgrade mode, we accept the result from the lockfile cache + return callback(null, { entry, content }); + } + return doFetch(content); + }; + if (!verifyIntegrity(content, entry.integrity)) { + /** @type {Buffer | undefined} */ + let contentWithChangedEol; + let isEolChanged = false; + try { + contentWithChangedEol = Buffer.from( + content.toString("utf-8").replace(/\r\n/g, "\n") + ); + isEolChanged = verifyIntegrity( + contentWithChangedEol, + entry.integrity + ); + } catch (_err) { + // ignore + } + if (isEolChanged) { + if (!warnedAboutEol) { + const explainer = `Incorrect end of line sequence was detected in the lockfile cache. +The lockfile cache is protected by integrity checks, so any external modification will lead to a corrupted lockfile cache. +When using git make sure to configure .gitattributes correctly for the lockfile cache: + **/*webpack.lock.data/** -text +This will avoid that the end of line sequence is changed by git on Windows.`; + if (frozen) { + logger.error(explainer); + } else { + logger.warn(explainer); + logger.info( + "Lockfile cache will be automatically fixed now, but when lockfile is frozen this would result in an error." + ); + } + warnedAboutEol = true; + } + if (!frozen) { + // "fix" the end of line sequence of the lockfile content + logger.log( + `${filePath} fixed end of line sequence (\\r\\n instead of \\n).` + ); + intermediateFs.writeFile( + filePath, + /** @type {Buffer} */ + (contentWithChangedEol), + err => { + if (err) return callback(err); + continueWithCachedContent( + /** @type {Buffer} */ + (contentWithChangedEol) + ); + } + ); + return; + } + } + if (frozen) { + return callback( + new Error( + `${ + entry.resolved + } integrity mismatch, expected content with integrity ${ + entry.integrity + } but got ${computeIntegrity(content)}. +Lockfile corrupted (${ + isEolChanged + ? "end of line sequence was unexpectedly changed" + : "incorrectly merged? changed by other tools?" + }). +Run build with un-frozen lockfile to automatically fix lockfile.` + ) + ); + } + // "fix" the lockfile entry to the correct integrity + // the content has priority over the integrity value + entry = { + ...entry, + integrity: computeIntegrity(content) + }; + storeLockEntry(lockfile, url, entry); + } + continueWithCachedContent(result); + }); + } else { + doFetch(); + } }); + } + ); + + /** + * @param {URL} url url + * @param {ResourceDataWithData} resourceData resource data + * @param {function(Error | null, true | void): void} callback callback + */ + const respondWithUrlModule = (url, resourceData, callback) => { + getInfo(url.href, (err, _result) => { + if (err) return callback(err); + const result = /** @type {Info} */ (_result); + resourceData.resource = url.href; + resourceData.path = url.origin + url.pathname; + resourceData.query = url.search; + resourceData.fragment = url.hash; + resourceData.context = new URL( + ".", + result.entry.resolved + ).href.slice(0, -1); + resourceData.data.mimetype = result.entry.contentType; + callback(null, true); + }); + }; + normalModuleFactory.hooks.resolveForScheme + .for(scheme) + .tapAsync( + "HttpUriPlugin", + (resourceData, resolveData, callback) => { + respondWithUrlModule( + new URL(resourceData.resource), + resourceData, + callback + ); + } + ); + normalModuleFactory.hooks.resolveInScheme + .for(scheme) + .tapAsync("HttpUriPlugin", (resourceData, data, callback) => { + // Only handle relative urls (./xxx, ../xxx, /xxx, //xxx) + if ( + data.dependencyType !== "url" && + !/^\.{0,2}\//.test(resourceData.resource) + ) { + return callback(); + } + respondWithUrlModule( + new URL(resourceData.resource, `${data.context}/`), + resourceData, + callback + ); }); - }); + const hooks = NormalModule.getCompilationHooks(compilation); + hooks.readResourceForScheme + .for(scheme) + .tapAsync("HttpUriPlugin", (resource, module, callback) => + getInfo(resource, (err, _result) => { + if (err) return callback(err); + const result = /** @type {Info} */ (_result); + /** @type {BuildInfo} */ + (module.buildInfo).resourceIntegrity = result.entry.integrity; + callback(null, result.content); + }) + ); + hooks.needBuild.tapAsync( + "HttpUriPlugin", + (module, context, callback) => { + if ( + module.resource && + module.resource.startsWith(`${scheme}://`) + ) { + getInfo(module.resource, (err, _result) => { + if (err) return callback(err); + const result = /** @type {Info} */ (_result); + if ( + result.entry.integrity !== + /** @type {BuildInfo} */ + (module.buildInfo).resourceIntegrity + ) { + return callback(null, true); + } + callback(); + }); + } else { + return callback(); + } + } + ); + } + compilation.hooks.finishModules.tapAsync( + "HttpUriPlugin", + (modules, callback) => { + if (!lockfileUpdates) return callback(); + const ext = extname(lockfileLocation); + const tempFile = join( + intermediateFs, + dirname(intermediateFs, lockfileLocation), + `.${basename(lockfileLocation, ext)}.${ + (Math.random() * 10000) | 0 + }${ext}` + ); + + const writeDone = () => { + const nextOperation = + /** @type {InProgressWriteItem[]} */ + (inProgressWrite).shift(); + if (nextOperation) { + nextOperation(); + } else { + inProgressWrite = undefined; + } + }; + const runWrite = () => { + intermediateFs.readFile(lockfileLocation, (err, buffer) => { + if (err && err.code !== "ENOENT") { + writeDone(); + return callback(err); + } + const lockfile = buffer + ? Lockfile.parse(buffer.toString("utf-8")) + : new Lockfile(); + for (const [key, value] of /** @type {LockfileUpdates} */ ( + lockfileUpdates + )) { + lockfile.entries.set(key, value); + } + intermediateFs.writeFile(tempFile, lockfile.toString(), err => { + if (err) { + writeDone(); + return ( + /** @type {NonNullable} */ + (intermediateFs.unlink)(tempFile, () => callback(err)) + ); + } + intermediateFs.rename(tempFile, lockfileLocation, err => { + if (err) { + writeDone(); + return ( + /** @type {NonNullable} */ + (intermediateFs.unlink)(tempFile, () => callback(err)) + ); + } + writeDone(); + callback(); + }); + }); + }); + }; + if (inProgressWrite) { + inProgressWrite.push(runWrite); + } else { + inProgressWrite = []; + runWrite(); + } + } + ); } ); } diff --git a/lib/schemes/HttpsUriPlugin.js b/lib/schemes/HttpsUriPlugin.js deleted file mode 100644 index ced48b7b8e3..00000000000 --- a/lib/schemes/HttpsUriPlugin.js +++ /dev/null @@ -1,63 +0,0 @@ -/* - MIT License http://www.opensource.org/licenses/mit-license.php - Author Tobias Koppers @sokra -*/ - -"use strict"; - -const { URL } = require("url"); -const NormalModule = require("../NormalModule"); - -/** @typedef {import("../Compiler")} Compiler */ - -class HttpsUriPlugin { - /** - * Apply the plugin - * @param {Compiler} compiler the compiler instance - * @returns {void} - */ - apply(compiler) { - compiler.hooks.compilation.tap( - "HttpsUriPlugin", - (compilation, { normalModuleFactory }) => { - normalModuleFactory.hooks.resolveForScheme - .for("https") - .tap("HttpsUriPlugin", resourceData => { - const url = new URL(resourceData.resource); - resourceData.path = url.origin + url.pathname; - resourceData.query = url.search; - resourceData.fragment = url.hash; - return /** @type {true} */ (true); - }); - NormalModule.getCompilationHooks(compilation) - .readResourceForScheme.for("https") - .tapAsync("HttpsUriPlugin", (resource, module, callback) => { - return require("https").get(new URL(resource), res => { - if (res.statusCode !== 200) { - res.destroy(); - return callback( - new Error(`https request status code = ${res.statusCode}`) - ); - } - - const bufferArr = []; - - res.on("data", chunk => { - bufferArr.push(chunk); - }); - - res.on("end", () => { - if (!res.complete) { - return callback(new Error("https request was terminated")); - } - - callback(null, Buffer.concat(bufferArr)); - }); - }); - }); - } - ); - } -} - -module.exports = HttpsUriPlugin; diff --git a/lib/serialization/ArraySerializer.js b/lib/serialization/ArraySerializer.js index 9bb2d85cac1..021c82ca5d4 100644 --- a/lib/serialization/ArraySerializer.js +++ b/lib/serialization/ArraySerializer.js @@ -4,16 +4,32 @@ "use strict"; +/** @typedef {import("./ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */ +/** @typedef {import("./ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */ + class ArraySerializer { - serialize(array, { write }) { - write(array.length); - for (const item of array) write(item); + /** + * @template T + * @param {T[]} array array + * @param {ObjectSerializerContext} context context + */ + serialize(array, context) { + context.write(array.length); + for (const item of array) context.write(item); } - deserialize({ read }) { - const length = read(); + + /** + * @template T + * @param {ObjectDeserializerContext} context context + * @returns {T[]} array + */ + deserialize(context) { + /** @type {number} */ + const length = context.read(); + /** @type {T[]} */ const array = []; for (let i = 0; i < length; i++) { - array.push(read()); + array.push(context.read()); } return array; } diff --git a/lib/serialization/BinaryMiddleware.js b/lib/serialization/BinaryMiddleware.js index 652a491263b..89798e3095e 100644 --- a/lib/serialization/BinaryMiddleware.js +++ b/lib/serialization/BinaryMiddleware.js @@ -10,8 +10,6 @@ const SerializerMiddleware = require("./SerializerMiddleware"); /** @typedef {import("./types").BufferSerializableType} BufferSerializableType */ /** @typedef {import("./types").PrimitiveSerializableType} PrimitiveSerializableType */ -/* eslint-disable no-loop-func */ - /* Format: @@ -23,6 +21,9 @@ Section -> NullsSection | I32NumbersSection | I8NumbersSection | ShortStringSection | + BigIntSection | + I32BigIntSection | + I8BigIntSection StringSection | BufferSection | NopSection @@ -41,6 +42,9 @@ ShortStringSection -> ShortStringSectionHeaderByte ascii-byte* StringSection -> StringSectionHeaderByte i32:length utf8-byte* BufferSection -> BufferSectionHeaderByte i32:length byte* NopSection --> NopSectionHeaderByte +BigIntSection -> BigIntSectionHeaderByte i32:length ascii-byte* +I32BigIntSection -> I32BigIntSectionHeaderByte i32 +I8BigIntSection -> I8BigIntSectionHeaderByte i8 ShortStringSectionHeaderByte -> 0b1nnn_nnnn (n:length) @@ -60,6 +64,9 @@ BooleansCountAndBitsByte -> StringSectionHeaderByte -> 0b0000_1110 BufferSectionHeaderByte -> 0b0000_1111 NopSectionHeaderByte -> 0b0000_1011 +BigIntSectionHeaderByte -> 0b0001_1010 +I32BigIntSectionHeaderByte -> 0b0001_1100 +I8BigIntSectionHeaderByte -> 0b0001_1011 FalseHeaderByte -> 0b0000_1100 TrueHeaderByte -> 0b0000_1101 @@ -80,6 +87,9 @@ const NULL_AND_I8_HEADER = 0x15; const NULL_AND_I32_HEADER = 0x16; const NULL_AND_TRUE_HEADER = 0x17; const NULL_AND_FALSE_HEADER = 0x18; +const BIGINT_HEADER = 0x1a; +const BIGINT_I8_HEADER = 0x1b; +const BIGINT_I32_HEADER = 0x1c; const STRING_HEADER = 0x1e; const BUFFER_HEADER = 0x1f; const I8_HEADER = 0x60; @@ -88,7 +98,7 @@ const F64_HEADER = 0x20; const SHORT_STRING_HEADER = 0x80; /** Uplift high-order bits */ -const NUMBERS_HEADER_MASK = 0xe0; +const NUMBERS_HEADER_MASK = 0xe0; // 0b1010_0000 const NUMBERS_COUNT_MASK = 0x1f; // 0b0001_1111 const SHORT_STRING_LENGTH_MASK = 0x7f; // 0b0111_1111 @@ -100,6 +110,13 @@ const F64_SIZE = 8; const MEASURE_START_OPERATION = Symbol("MEASURE_START_OPERATION"); const MEASURE_END_OPERATION = Symbol("MEASURE_END_OPERATION"); +/** @typedef {typeof MEASURE_START_OPERATION} MEASURE_START_OPERATION_TYPE */ +/** @typedef {typeof MEASURE_END_OPERATION} MEASURE_END_OPERATION_TYPE */ + +/** + * @param {number} n number + * @returns {0 | 1 | 2} type of number for serialization + */ const identifyNumber = n => { if (n === (n | 0)) { if (n <= 127 && n >= -128) return 0; @@ -108,61 +125,72 @@ const identifyNumber = n => { return 2; }; +/** + * @param {bigint} n bigint + * @returns {0 | 1 | 2} type of bigint for serialization + */ +const identifyBigInt = n => { + if (n <= BigInt(127) && n >= BigInt(-128)) return 0; + if (n <= BigInt(2147483647) && n >= BigInt(-2147483648)) return 1; + return 2; +}; + /** * @typedef {PrimitiveSerializableType[]} DeserializedType * @typedef {BufferSerializableType[]} SerializedType * @extends {SerializerMiddleware} */ class BinaryMiddleware extends SerializerMiddleware { - static optimizeSerializedData(data) { - const result = []; - const temp = []; - const flush = () => { - if (temp.length > 0) { - if (temp.length === 1) { - result.push(temp[0]); - } else { - result.push(Buffer.concat(temp)); - } - temp.length = 0; - } - }; - for (const item of data) { - if (Buffer.isBuffer(item)) { - temp.push(item); - } else { - flush(); - result.push(item); - } - } - flush(); - return result; - } - /** * @param {DeserializedType} data data - * @param {Object} context context object + * @param {object} context context object * @returns {SerializedType|Promise} serialized data */ serialize(data, context) { return this._serialize(data, context); } + /** + * @param {function(): Promise | any} fn lazy function + * @param {object} context serialize function + * @returns {function(): Promise | any} new lazy + */ + _serializeLazy(fn, context) { + return SerializerMiddleware.serializeLazy(fn, data => + this._serialize(data, context) + ); + } + /** * @param {DeserializedType} data data - * @param {Object} context context object + * @param {object} context context object + * @param {{ leftOverBuffer: Buffer | null, allocationSize: number, increaseCounter: number }} allocationScope allocation scope * @returns {SerializedType} serialized data */ - _serialize(data, context) { - /** @type {Buffer} */ - let currentBuffer = null; - /** @type {Buffer} */ + _serialize( + data, + context, + allocationScope = { + allocationSize: 1024, + increaseCounter: 0, + leftOverBuffer: null + } + ) { + /** @type {Buffer | null} */ let leftOverBuffer = null; - let currentPosition = 0; /** @type {BufferSerializableType[]} */ - const buffers = []; - let buffersTotalLength = 0; - const allocate = (bytesNeeded, exact = false) => { + let buffers = []; + /** @type {Buffer | null} */ + let currentBuffer = allocationScope ? allocationScope.leftOverBuffer : null; + allocationScope.leftOverBuffer = null; + let currentPosition = 0; + if (currentBuffer === null) { + currentBuffer = Buffer.allocUnsafe(allocationScope.allocationSize); + } + /** + * @param {number} bytesNeeded bytes needed + */ + const allocate = bytesNeeded => { if (currentBuffer !== null) { if (currentBuffer.length - currentPosition >= bytesNeeded) return; flush(); @@ -172,273 +200,370 @@ class BinaryMiddleware extends SerializerMiddleware { leftOverBuffer = null; } else { currentBuffer = Buffer.allocUnsafe( - exact ? bytesNeeded : Math.max(bytesNeeded, buffersTotalLength, 1024) + Math.max(bytesNeeded, allocationScope.allocationSize) ); + if ( + !(allocationScope.increaseCounter = + (allocationScope.increaseCounter + 1) % 4) && + allocationScope.allocationSize < 16777216 + ) { + allocationScope.allocationSize = allocationScope.allocationSize << 1; + } } }; const flush = () => { if (currentBuffer !== null) { - buffers.push(currentBuffer.slice(0, currentPosition)); + if (currentPosition > 0) { + buffers.push( + Buffer.from( + currentBuffer.buffer, + currentBuffer.byteOffset, + currentPosition + ) + ); + } if ( !leftOverBuffer || leftOverBuffer.length < currentBuffer.length - currentPosition - ) - leftOverBuffer = currentBuffer.slice(currentPosition); + ) { + leftOverBuffer = Buffer.from( + currentBuffer.buffer, + currentBuffer.byteOffset + currentPosition, + currentBuffer.byteLength - currentPosition + ); + } + currentBuffer = null; - buffersTotalLength += currentPosition; currentPosition = 0; } }; + /** + * @param {number} byte byte + */ const writeU8 = byte => { - currentBuffer.writeUInt8(byte, currentPosition++); + /** @type {Buffer} */ + (currentBuffer).writeUInt8(byte, currentPosition++); }; + /** + * @param {number} ui32 ui32 + */ const writeU32 = ui32 => { - currentBuffer.writeUInt32LE(ui32, currentPosition); + /** @type {Buffer} */ + (currentBuffer).writeUInt32LE(ui32, currentPosition); currentPosition += 4; }; + /** @type {number[]} */ const measureStack = []; const measureStart = () => { measureStack.push(buffers.length, currentPosition); }; + /** + * @returns {number} size + */ const measureEnd = () => { - const oldPos = measureStack.pop(); - const buffersIndex = measureStack.pop(); + const oldPos = /** @type {number} */ (measureStack.pop()); + const buffersIndex = /** @type {number} */ (measureStack.pop()); let size = currentPosition - oldPos; for (let i = buffersIndex; i < buffers.length; i++) { size += buffers[i].length; } return size; }; - const serializeData = data => { - for (let i = 0; i < data.length; i++) { - const thing = data[i]; - switch (typeof thing) { - case "function": { - if (!SerializerMiddleware.isLazy(thing)) - throw new Error("Unexpected function " + thing); - /** @type {SerializedType | (() => SerializedType)} */ - let serializedData = SerializerMiddleware.getLazySerializedValue( - thing - ); - if (serializedData === undefined) { - if (SerializerMiddleware.isLazy(thing, this)) { - const data = this._serialize(thing(), context); - SerializerMiddleware.setLazySerializedValue(thing, data); - serializedData = data; - } else { - serializedData = SerializerMiddleware.serializeLazy( - thing, - data => this._serialize(data, context) + for (let i = 0; i < data.length; i++) { + const thing = data[i]; + switch (typeof thing) { + case "function": { + if (!SerializerMiddleware.isLazy(thing)) + throw new Error(`Unexpected function ${thing}`); + /** @type {SerializedType | (() => SerializedType)} */ + let serializedData = + SerializerMiddleware.getLazySerializedValue(thing); + if (serializedData === undefined) { + if (SerializerMiddleware.isLazy(thing, this)) { + flush(); + allocationScope.leftOverBuffer = leftOverBuffer; + const result = + /** @type {(Exclude>)[]} */ ( + thing() ); - } - } - if (typeof serializedData === "function") { + const data = this._serialize(result, context, allocationScope); + leftOverBuffer = allocationScope.leftOverBuffer; + allocationScope.leftOverBuffer = null; + SerializerMiddleware.setLazySerializedValue(thing, data); + serializedData = data; + } else { + serializedData = this._serializeLazy(thing, context); flush(); buffers.push(serializedData); - } else { - const lengths = []; - for (const item of serializedData) { - let last; - if (typeof item === "function") { - lengths.push(0); - } else if (item.length === 0) { - // ignore - } else if ( - lengths.length > 0 && - (last = lengths[lengths.length - 1]) !== 0 - ) { - const remaining = 0xffffffff - last; - if (remaining >= item.length) { - lengths[lengths.length - 1] += item.length; - } else { - lengths.push(item.length - remaining); - lengths[lengths.length - 2] = 0xffffffff; - } - } else { - lengths.push(item.length); - } - } - allocate(5 + lengths.length * 4); - writeU8(LAZY_HEADER); - writeU32(lengths.length); - for (const l of lengths) { - writeU32(l); - } - for (const item of serializedData) { - flush(); - buffers.push(item); - } + break; } + } else if (typeof serializedData === "function") { + flush(); + buffers.push(serializedData); break; } - case "string": { - const len = Buffer.byteLength(thing); - if (len >= 128 || len !== thing.length) { - allocate(len + HEADER_SIZE + I32_SIZE); - writeU8(STRING_HEADER); - writeU32(len); - currentBuffer.write(thing, currentPosition); + /** @type {number[]} */ + const lengths = []; + for (const item of serializedData) { + let last; + if (typeof item === "function") { + lengths.push(0); + } else if (item.length === 0) { + // ignore + } else if ( + lengths.length > 0 && + (last = lengths[lengths.length - 1]) !== 0 + ) { + const remaining = 0xffffffff - last; + if (remaining >= item.length) { + lengths[lengths.length - 1] += item.length; + } else { + lengths.push(item.length - remaining); + lengths[lengths.length - 2] = 0xffffffff; + } } else { - allocate(len + HEADER_SIZE); - writeU8(SHORT_STRING_HEADER | len); - currentBuffer.write(thing, currentPosition, "latin1"); + lengths.push(item.length); } + } + allocate(5 + lengths.length * 4); + writeU8(LAZY_HEADER); + writeU32(lengths.length); + for (const l of lengths) { + writeU32(l); + } + flush(); + for (const item of serializedData) { + buffers.push(item); + } + break; + } + case "string": { + const len = Buffer.byteLength(thing); + if (len >= 128 || len !== thing.length) { + allocate(len + HEADER_SIZE + I32_SIZE); + writeU8(STRING_HEADER); + writeU32(len); + currentBuffer.write(thing, currentPosition); + currentPosition += len; + } else if (len >= 70) { + allocate(len + HEADER_SIZE); + writeU8(SHORT_STRING_HEADER | len); + + currentBuffer.write(thing, currentPosition, "latin1"); currentPosition += len; + } else { + allocate(len + HEADER_SIZE); + writeU8(SHORT_STRING_HEADER | len); + + for (let i = 0; i < len; i++) { + currentBuffer[currentPosition++] = thing.charCodeAt(i); + } + } + break; + } + case "bigint": { + const type = identifyBigInt(thing); + if (type === 0 && thing >= 0 && thing <= BigInt(10)) { + // shortcut for very small bigints + allocate(HEADER_SIZE + I8_SIZE); + writeU8(BIGINT_I8_HEADER); + writeU8(Number(thing)); break; } - case "number": { - const type = identifyNumber(thing); - if (type === 0 && thing >= 0 && thing <= 10) { - // shortcut for very small numbers - allocate(I8_SIZE); - writeU8(thing); + + switch (type) { + case 0: { + let n = 1; + allocate(HEADER_SIZE + I8_SIZE * n); + writeU8(BIGINT_I8_HEADER | (n - 1)); + while (n > 0) { + currentBuffer.writeInt8( + Number(/** @type {bigint} */ (data[i])), + currentPosition + ); + currentPosition += I8_SIZE; + n--; + i++; + } + i--; break; } - /** - * amount of numbers to write - * @type {number} - */ - let n = 1; - for (; n < 32 && i + n < data.length; n++) { - const item = data[i + n]; - if (typeof item !== "number") break; - if (identifyNumber(item) !== type) break; + case 1: { + let n = 1; + allocate(HEADER_SIZE + I32_SIZE * n); + writeU8(BIGINT_I32_HEADER | (n - 1)); + while (n > 0) { + currentBuffer.writeInt32LE( + Number(/** @type {bigint} */ (data[i])), + currentPosition + ); + currentPosition += I32_SIZE; + n--; + i++; + } + i--; + break; } - switch (type) { - case 0: - allocate(HEADER_SIZE + I8_SIZE * n); - writeU8(I8_HEADER | (n - 1)); - while (n > 0) { - currentBuffer.writeInt8( - /** @type {number} */ (data[i]), - currentPosition - ); - currentPosition += I8_SIZE; - n--; - i++; - } - break; - case 1: - allocate(HEADER_SIZE + I32_SIZE * n); - writeU8(I32_HEADER | (n - 1)); - while (n > 0) { - currentBuffer.writeInt32LE( - /** @type {number} */ (data[i]), - currentPosition - ); - currentPosition += I32_SIZE; - n--; - i++; - } - break; - case 2: - allocate(HEADER_SIZE + F64_SIZE * n); - writeU8(F64_HEADER | (n - 1)); - while (n > 0) { - currentBuffer.writeDoubleLE( - /** @type {number} */ (data[i]), - currentPosition - ); - currentPosition += F64_SIZE; - n--; - i++; - } - break; + default: { + const value = thing.toString(); + const len = Buffer.byteLength(value); + allocate(len + HEADER_SIZE + I32_SIZE); + writeU8(BIGINT_HEADER); + writeU32(len); + currentBuffer.write(value, currentPosition); + currentPosition += len; + break; } - - i--; + } + break; + } + case "number": { + const type = identifyNumber(thing); + if (type === 0 && thing >= 0 && thing <= 10) { + // shortcut for very small numbers + allocate(I8_SIZE); + writeU8(thing); break; } - case "boolean": { - let lastByte = thing === true ? 1 : 0; - const bytes = []; - let count = 1; - let n; - for (n = 1; n < 0xffffffff && i + n < data.length; n++) { - const item = data[i + n]; - if (typeof item !== "boolean") break; - const pos = count & 0x7; - if (pos === 0) { - bytes.push(lastByte); - lastByte = item === true ? 1 : 0; - } else if (item === true) { - lastByte |= 1 << pos; + /** + * amount of numbers to write + * @type {number} + */ + let n = 1; + for (; n < 32 && i + n < data.length; n++) { + const item = data[i + n]; + if (typeof item !== "number") break; + if (identifyNumber(item) !== type) break; + } + switch (type) { + case 0: + allocate(HEADER_SIZE + I8_SIZE * n); + writeU8(I8_HEADER | (n - 1)); + while (n > 0) { + currentBuffer.writeInt8( + /** @type {number} */ (data[i]), + currentPosition + ); + currentPosition += I8_SIZE; + n--; + i++; } - count++; - } - i += count - 1; - if (count === 1) { - allocate(HEADER_SIZE); - writeU8(lastByte === 1 ? TRUE_HEADER : FALSE_HEADER); - } else if (count === 2) { - allocate(HEADER_SIZE * 2); - writeU8(lastByte & 1 ? TRUE_HEADER : FALSE_HEADER); - writeU8(lastByte & 2 ? TRUE_HEADER : FALSE_HEADER); - } else if (count <= 6) { - allocate(HEADER_SIZE + I8_SIZE); - writeU8(BOOLEANS_HEADER); - writeU8((1 << count) | lastByte); - } else if (count <= 133) { - allocate( - HEADER_SIZE + I8_SIZE + I8_SIZE * bytes.length + I8_SIZE - ); - writeU8(BOOLEANS_HEADER); - writeU8(0x80 | (count - 7)); - for (const byte of bytes) writeU8(byte); - writeU8(lastByte); - } else { - allocate( - HEADER_SIZE + - I8_SIZE + - I32_SIZE + - I8_SIZE * bytes.length + - I8_SIZE - ); - writeU8(BOOLEANS_HEADER); - writeU8(0xff); - writeU32(count); - for (const byte of bytes) writeU8(byte); - writeU8(lastByte); + break; + case 1: + allocate(HEADER_SIZE + I32_SIZE * n); + writeU8(I32_HEADER | (n - 1)); + while (n > 0) { + currentBuffer.writeInt32LE( + /** @type {number} */ (data[i]), + currentPosition + ); + currentPosition += I32_SIZE; + n--; + i++; + } + break; + case 2: + allocate(HEADER_SIZE + F64_SIZE * n); + writeU8(F64_HEADER | (n - 1)); + while (n > 0) { + currentBuffer.writeDoubleLE( + /** @type {number} */ (data[i]), + currentPosition + ); + currentPosition += F64_SIZE; + n--; + i++; + } + break; + } + + i--; + break; + } + case "boolean": { + let lastByte = thing === true ? 1 : 0; + const bytes = []; + let count = 1; + let n; + for (n = 1; n < 0xffffffff && i + n < data.length; n++) { + const item = data[i + n]; + if (typeof item !== "boolean") break; + const pos = count & 0x7; + if (pos === 0) { + bytes.push(lastByte); + lastByte = item === true ? 1 : 0; + } else if (item === true) { + lastByte |= 1 << pos; } - break; + count++; } - case "object": { - if (thing === null) { - let n; - for (n = 1; n < 0x100000104 && i + n < data.length; n++) { - const item = data[i + n]; - if (item !== null) break; - } - i += n - 1; - if (n === 1) { - if (i + 1 < data.length) { - const next = data[i + 1]; - if (next === true) { - allocate(HEADER_SIZE); - writeU8(NULL_AND_TRUE_HEADER); + i += count - 1; + if (count === 1) { + allocate(HEADER_SIZE); + writeU8(lastByte === 1 ? TRUE_HEADER : FALSE_HEADER); + } else if (count === 2) { + allocate(HEADER_SIZE * 2); + writeU8(lastByte & 1 ? TRUE_HEADER : FALSE_HEADER); + writeU8(lastByte & 2 ? TRUE_HEADER : FALSE_HEADER); + } else if (count <= 6) { + allocate(HEADER_SIZE + I8_SIZE); + writeU8(BOOLEANS_HEADER); + writeU8((1 << count) | lastByte); + } else if (count <= 133) { + allocate(HEADER_SIZE + I8_SIZE + I8_SIZE * bytes.length + I8_SIZE); + writeU8(BOOLEANS_HEADER); + writeU8(0x80 | (count - 7)); + for (const byte of bytes) writeU8(byte); + writeU8(lastByte); + } else { + allocate( + HEADER_SIZE + + I8_SIZE + + I32_SIZE + + I8_SIZE * bytes.length + + I8_SIZE + ); + writeU8(BOOLEANS_HEADER); + writeU8(0xff); + writeU32(count); + for (const byte of bytes) writeU8(byte); + writeU8(lastByte); + } + break; + } + case "object": { + if (thing === null) { + let n; + for (n = 1; n < 0x100000104 && i + n < data.length; n++) { + const item = data[i + n]; + if (item !== null) break; + } + i += n - 1; + if (n === 1) { + if (i + 1 < data.length) { + const next = data[i + 1]; + if (next === true) { + allocate(HEADER_SIZE); + writeU8(NULL_AND_TRUE_HEADER); + i++; + } else if (next === false) { + allocate(HEADER_SIZE); + writeU8(NULL_AND_FALSE_HEADER); + i++; + } else if (typeof next === "number") { + const type = identifyNumber(next); + if (type === 0) { + allocate(HEADER_SIZE + I8_SIZE); + writeU8(NULL_AND_I8_HEADER); + currentBuffer.writeInt8(next, currentPosition); + currentPosition += I8_SIZE; i++; - } else if (next === false) { - allocate(HEADER_SIZE); - writeU8(NULL_AND_FALSE_HEADER); + } else if (type === 1) { + allocate(HEADER_SIZE + I32_SIZE); + writeU8(NULL_AND_I32_HEADER); + currentBuffer.writeInt32LE(next, currentPosition); + currentPosition += I32_SIZE; i++; - } else if (typeof next === "number") { - const type = identifyNumber(next); - if (type === 0) { - allocate(HEADER_SIZE + I8_SIZE); - writeU8(NULL_AND_I8_HEADER); - currentBuffer.writeInt8(next, currentPosition); - currentPosition += I8_SIZE; - i++; - } else if (type === 1) { - allocate(HEADER_SIZE + I32_SIZE); - writeU8(NULL_AND_I32_HEADER); - currentBuffer.writeInt32LE(next, currentPosition); - currentPosition += I32_SIZE; - i++; - } else { - allocate(HEADER_SIZE); - writeU8(NULL_HEADER); - } } else { allocate(HEADER_SIZE); writeU8(NULL_HEADER); @@ -447,62 +572,101 @@ class BinaryMiddleware extends SerializerMiddleware { allocate(HEADER_SIZE); writeU8(NULL_HEADER); } - } else if (n === 2) { - allocate(HEADER_SIZE); - writeU8(NULL2_HEADER); - } else if (n === 3) { - allocate(HEADER_SIZE); - writeU8(NULL3_HEADER); - } else if (n < 260) { - allocate(HEADER_SIZE + I8_SIZE); - writeU8(NULLS8_HEADER); - writeU8(n - 4); } else { - allocate(HEADER_SIZE + I32_SIZE); - writeU8(NULLS32_HEADER); - writeU32(n - 260); + allocate(HEADER_SIZE); + writeU8(NULL_HEADER); } - } else if (Buffer.isBuffer(thing)) { - allocate(HEADER_SIZE + I32_SIZE, true); + } else if (n === 2) { + allocate(HEADER_SIZE); + writeU8(NULL2_HEADER); + } else if (n === 3) { + allocate(HEADER_SIZE); + writeU8(NULL3_HEADER); + } else if (n < 260) { + allocate(HEADER_SIZE + I8_SIZE); + writeU8(NULLS8_HEADER); + writeU8(n - 4); + } else { + allocate(HEADER_SIZE + I32_SIZE); + writeU8(NULLS32_HEADER); + writeU32(n - 260); + } + } else if (Buffer.isBuffer(thing)) { + if (thing.length < 8192) { + allocate(HEADER_SIZE + I32_SIZE + thing.length); + writeU8(BUFFER_HEADER); + writeU32(thing.length); + thing.copy(currentBuffer, currentPosition); + currentPosition += thing.length; + } else { + allocate(HEADER_SIZE + I32_SIZE); writeU8(BUFFER_HEADER); writeU32(thing.length); flush(); buffers.push(thing); } - break; } - case "symbol": { - if (thing === MEASURE_START_OPERATION) { - measureStart(); - } else if (thing === MEASURE_END_OPERATION) { - const size = measureEnd(); - allocate(HEADER_SIZE + I32_SIZE); - writeU8(I32_HEADER); - currentBuffer.writeInt32LE(size, currentPosition); - currentPosition += I32_SIZE; - } - break; + break; + } + case "symbol": { + if (thing === MEASURE_START_OPERATION) { + measureStart(); + } else if (thing === MEASURE_END_OPERATION) { + const size = measureEnd(); + allocate(HEADER_SIZE + I32_SIZE); + writeU8(I32_HEADER); + currentBuffer.writeInt32LE(size, currentPosition); + currentPosition += I32_SIZE; } + break; + } + default: { + throw new Error( + `Unknown typeof "${typeof thing}" in binary middleware` + ); } } - }; - serializeData(data); + } flush(); - return buffers; + + allocationScope.leftOverBuffer = leftOverBuffer; + + // avoid leaking memory + currentBuffer = null; + leftOverBuffer = null; + allocationScope = undefined; + const _buffers = buffers; + buffers = undefined; + return _buffers; } /** * @param {SerializedType} data data - * @param {Object} context context object + * @param {object} context context object * @returns {DeserializedType|Promise} deserialized data */ deserialize(data, context) { return this._deserialize(data, context); } + _createLazyDeserialized(content, context) { + return SerializerMiddleware.createLazy( + memoize(() => this._deserialize(content, context)), + this, + undefined, + content + ); + } + + _deserializeLazy(fn, context) { + return SerializerMiddleware.deserializeLazy(fn, data => + this._deserialize(data, context) + ); + } + /** * @param {SerializedType} data data - * @param {Object} context context object + * @param {object} context context object * @returns {DeserializedType} deserialized data */ _deserialize(data, context) { @@ -511,6 +675,8 @@ class BinaryMiddleware extends SerializerMiddleware { let currentIsBuffer = Buffer.isBuffer(currentBuffer); let currentPosition = 0; + const retainedBuffer = context.retainedBuffer || (x => x); + const checkOverflow = () => { if (currentPosition >= currentBuffer.length) { currentPosition = 0; @@ -520,15 +686,13 @@ class BinaryMiddleware extends SerializerMiddleware { currentIsBuffer = Buffer.isBuffer(currentBuffer); } }; - const isInCurrentBuffer = n => { - return currentIsBuffer && n + currentPosition <= currentBuffer.length; - }; /** - * Reads n bytes - * @param {number} n amount of bytes to read - * @returns {Buffer} buffer with bytes + * @param {number} n n + * @returns {boolean} true when in current buffer, otherwise false */ - const read = n => { + const isInCurrentBuffer = n => + currentIsBuffer && n + currentPosition <= currentBuffer.length; + const ensureBuffer = () => { if (!currentIsBuffer) { throw new Error( currentBuffer === null @@ -536,14 +700,34 @@ class BinaryMiddleware extends SerializerMiddleware { : "Unexpected lazy element in stream" ); } + }; + /** + * Reads n bytes + * @param {number} n amount of bytes to read + * @returns {Buffer} buffer with bytes + */ + const read = n => { + ensureBuffer(); const rem = currentBuffer.length - currentPosition; if (rem < n) { - return Buffer.concat([read(rem), read(n - rem)]); + const buffers = [read(rem)]; + n -= rem; + ensureBuffer(); + while (currentBuffer.length < n) { + const b = /** @type {Buffer} */ (currentBuffer); + buffers.push(b); + n -= b.length; + currentDataItem++; + currentBuffer = + currentDataItem < data.length ? data[currentDataItem] : null; + currentIsBuffer = Buffer.isBuffer(currentBuffer); + ensureBuffer(); + } + buffers.push(read(n)); + return Buffer.concat(buffers); } - const res = /** @type {Buffer} */ (currentBuffer).slice( - currentPosition, - currentPosition + n - ); + const b = /** @type {Buffer} */ (currentBuffer); + const res = Buffer.from(b.buffer, b.byteOffset + currentPosition, n); currentPosition += n; checkOverflow(); return res; @@ -554,47 +738,41 @@ class BinaryMiddleware extends SerializerMiddleware { * @returns {Buffer} buffer with bytes */ const readUpTo = n => { - if (!currentIsBuffer) { - throw new Error( - currentBuffer === null - ? "Unexpected end of stream" - : "Unexpected lazy element in stream" - ); - } + ensureBuffer(); const rem = currentBuffer.length - currentPosition; if (rem < n) { n = rem; } - const res = /** @type {Buffer} */ (currentBuffer).slice( - currentPosition, - currentPosition + n - ); + const b = /** @type {Buffer} */ (currentBuffer); + const res = Buffer.from(b.buffer, b.byteOffset + currentPosition, n); currentPosition += n; checkOverflow(); return res; }; + /** + * @returns {number} U8 + */ const readU8 = () => { - if (!currentIsBuffer) { - throw new Error( - currentBuffer === null - ? "Unexpected end of stream" - : "Unexpected lazy element in stream" - ); - } + ensureBuffer(); /** * There is no need to check remaining buffer size here * since {@link checkOverflow} guarantees at least one byte remaining */ - const byte = /** @type {Buffer} */ (currentBuffer).readUInt8( - currentPosition - ); + const byte = + /** @type {Buffer} */ + (currentBuffer).readUInt8(currentPosition); currentPosition += I8_SIZE; checkOverflow(); return byte; }; - const readU32 = () => { - return read(I32_SIZE).readUInt32LE(0); - }; + /** + * @returns {number} U32 + */ + const readU32 = () => read(I32_SIZE).readUInt32LE(0); + /** + * @param {number} data data + * @param {number} n n + */ const readBits = (data, n) => { let mask = 1; while (n !== 0) { @@ -624,23 +802,16 @@ class BinaryMiddleware extends SerializerMiddleware { do { const buf = readUpTo(l); l -= buf.length; - content.push(buf); + content.push(retainedBuffer(buf)); } while (l > 0); } } - result.push( - SerializerMiddleware.createLazy( - memoize(() => this._deserialize(content, context)), - this, - undefined, - content - ) - ); + result.push(this._createLazyDeserialized(content, context)); }; case BUFFER_HEADER: return () => { const len = readU32(); - result.push(read(len)); + result.push(retainedBuffer(read(len))); }; case TRUE_HEADER: return () => result.push(true); @@ -728,7 +899,7 @@ class BinaryMiddleware extends SerializerMiddleware { case STRING_HEADER: return () => { const len = readU32(); - if (isInCurrentBuffer(len)) { + if (isInCurrentBuffer(len) && currentPosition + len < 0x7fffffff) { result.push( currentBuffer.toString( undefined, @@ -746,7 +917,7 @@ class BinaryMiddleware extends SerializerMiddleware { return () => result.push(""); case SHORT_STRING_HEADER | 1: return () => { - if (currentIsBuffer) { + if (currentIsBuffer && currentPosition < 0x7ffffffe) { result.push( currentBuffer.toString( "latin1", @@ -772,13 +943,80 @@ class BinaryMiddleware extends SerializerMiddleware { result.push(read(1).readInt8(0)); } }; + case BIGINT_I8_HEADER: { + const len = 1; + return () => { + const need = I8_SIZE * len; + + if (isInCurrentBuffer(need)) { + for (let i = 0; i < len; i++) { + const value = + /** @type {Buffer} */ + (currentBuffer).readInt8(currentPosition); + result.push(BigInt(value)); + currentPosition += I8_SIZE; + } + checkOverflow(); + } else { + const buf = read(need); + for (let i = 0; i < len; i++) { + const value = buf.readInt8(i * I8_SIZE); + result.push(BigInt(value)); + } + } + }; + } + case BIGINT_I32_HEADER: { + const len = 1; + return () => { + const need = I32_SIZE * len; + if (isInCurrentBuffer(need)) { + for (let i = 0; i < len; i++) { + const value = /** @type {Buffer} */ (currentBuffer).readInt32LE( + currentPosition + ); + result.push(BigInt(value)); + currentPosition += I32_SIZE; + } + checkOverflow(); + } else { + const buf = read(need); + for (let i = 0; i < len; i++) { + const value = buf.readInt32LE(i * I32_SIZE); + result.push(BigInt(value)); + } + } + }; + } + case BIGINT_HEADER: { + return () => { + const len = readU32(); + if (isInCurrentBuffer(len) && currentPosition + len < 0x7fffffff) { + const value = currentBuffer.toString( + undefined, + currentPosition, + currentPosition + len + ); + + result.push(BigInt(value)); + currentPosition += len; + checkOverflow(); + } else { + const value = read(len).toString(); + result.push(BigInt(value)); + } + }; + } default: if (header <= 10) { return () => result.push(header); } else if ((header & SHORT_STRING_HEADER) === SHORT_STRING_HEADER) { const len = header & SHORT_STRING_LENGTH_MASK; return () => { - if (isInCurrentBuffer(len)) { + if ( + isInCurrentBuffer(len) && + currentPosition + len < 0x7fffffff + ) { result.push( currentBuffer.toString( "latin1", @@ -855,25 +1093,18 @@ class BinaryMiddleware extends SerializerMiddleware { } } }; - } else { - return () => { - throw new Error( - `Unexpected header byte 0x${header.toString(16)}` - ); - }; } + return () => { + throw new Error(`Unexpected header byte 0x${header.toString(16)}`); + }; } }); /** @type {DeserializedType} */ - const result = []; + let result = []; while (currentBuffer !== null) { if (typeof currentBuffer === "function") { - result.push( - SerializerMiddleware.deserializeLazy(currentBuffer, data => - this._deserialize(data, context) - ) - ); + result.push(this._deserializeLazy(currentBuffer, context)); currentDataItem++; currentBuffer = currentDataItem < data.length ? data[currentDataItem] : null; @@ -883,7 +1114,12 @@ class BinaryMiddleware extends SerializerMiddleware { dispatchTable[header](); } } - return result; + + // avoid leaking memory in context + // eslint-disable-next-line prefer-const + let _result = result; + result = undefined; + return _result; } } diff --git a/lib/serialization/DateObjectSerializer.js b/lib/serialization/DateObjectSerializer.js index 17418cd2b21..c69ccfe8c7c 100644 --- a/lib/serialization/DateObjectSerializer.js +++ b/lib/serialization/DateObjectSerializer.js @@ -4,12 +4,24 @@ "use strict"; +/** @typedef {import("./ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */ +/** @typedef {import("./ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */ + class DateObjectSerializer { - serialize(obj, { write }) { - write(obj.getTime()); + /** + * @param {Date} obj date + * @param {ObjectSerializerContext} context context + */ + serialize(obj, context) { + context.write(obj.getTime()); } - deserialize({ read }) { - return new Date(read()); + + /** + * @param {ObjectDeserializerContext} context context + * @returns {Date} date + */ + deserialize(context) { + return new Date(context.read()); } } diff --git a/lib/serialization/ErrorObjectSerializer.js b/lib/serialization/ErrorObjectSerializer.js index 0e168d5dbfa..b0869155ff4 100644 --- a/lib/serialization/ErrorObjectSerializer.js +++ b/lib/serialization/ErrorObjectSerializer.js @@ -4,21 +4,38 @@ "use strict"; +/** @typedef {import("./ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */ +/** @typedef {import("./ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */ + class ErrorObjectSerializer { + /** + * @param {ErrorConstructor | EvalErrorConstructor | RangeErrorConstructor | ReferenceErrorConstructor | SyntaxErrorConstructor | TypeErrorConstructor} Type error type + */ constructor(Type) { this.Type = Type; } - serialize(obj, { write }) { - write(obj.message); - write(obj.stack); + /** + * @param {Error | EvalError | RangeError | ReferenceError | SyntaxError | TypeError} obj error + * @param {ObjectSerializerContext} context context + */ + serialize(obj, context) { + context.write(obj.message); + context.write(obj.stack); + context.write(/** @type {Error & { cause: "unknown" }} */ (obj).cause); } - deserialize({ read }) { + /** + * @param {ObjectDeserializerContext} context context + * @returns {Error | EvalError | RangeError | ReferenceError | SyntaxError | TypeError} error + */ + deserialize(context) { const err = new this.Type(); - err.message = read(); - err.stack = read(); + err.message = context.read(); + err.stack = context.read(); + /** @type {Error & { cause: "unknown" }} */ + (err).cause = context.read(); return err; } diff --git a/lib/serialization/FileMiddleware.js b/lib/serialization/FileMiddleware.js index 00bf975841c..b8de8a958d9 100644 --- a/lib/serialization/FileMiddleware.js +++ b/lib/serialization/FileMiddleware.js @@ -5,11 +5,21 @@ "use strict"; const { constants } = require("buffer"); +const { pipeline } = require("stream"); +const { + createBrotliCompress, + createBrotliDecompress, + createGzip, + createGunzip, + constants: zConstants +} = require("zlib"); const createHash = require("../util/createHash"); const { dirname, join, mkdirp } = require("../util/fs"); const memoize = require("../util/memoize"); const SerializerMiddleware = require("./SerializerMiddleware"); +/** @typedef {typeof import("../util/Hash")} Hash */ +/** @typedef {import("../util/fs").IStats} IStats */ /** @typedef {import("../util/fs").IntermediateFileSystem} IntermediateFileSystem */ /** @typedef {import("./types").BufferSerializableType} BufferSerializableType */ @@ -31,54 +41,72 @@ Section -> Buffer // "wpc" + 1 in little-endian const VERSION = 0x01637077; -const hashForName = buffers => { - const hash = createHash("md4"); +const WRITE_LIMIT_TOTAL = 0x7fff0000; +const WRITE_LIMIT_CHUNK = 511 * 1024 * 1024; + +/** + * @param {Buffer[]} buffers buffers + * @param {string | Hash} hashFunction hash function to use + * @returns {string} hash + */ +const hashForName = (buffers, hashFunction) => { + const hash = createHash(hashFunction); for (const buf of buffers) hash.update(buf); return /** @type {string} */ (hash.digest("hex")); }; +const COMPRESSION_CHUNK_SIZE = 100 * 1024 * 1024; +const DECOMPRESSION_CHUNK_SIZE = 100 * 1024 * 1024; + +/** @type {function(Buffer, number, number): void} */ const writeUInt64LE = Buffer.prototype.writeBigUInt64LE ? (buf, value, offset) => { buf.writeBigUInt64LE(BigInt(value), offset); - } + } : (buf, value, offset) => { const low = value % 0x100000000; const high = (value - low) / 0x100000000; buf.writeUInt32LE(low, offset); buf.writeUInt32LE(high, offset + 4); - }; + }; +/** @type {function(Buffer, number): void} */ const readUInt64LE = Buffer.prototype.readBigUInt64LE - ? (buf, offset) => { - return Number(buf.readBigUInt64LE(offset)); - } + ? (buf, offset) => Number(buf.readBigUInt64LE(offset)) : (buf, offset) => { const low = buf.readUInt32LE(offset); const high = buf.readUInt32LE(offset + 4); return high * 0x100000000 + low; - }; + }; /** - * @typedef {Object} SerializeResult + * @typedef {object} SerializeResult * @property {string | false} name * @property {number} size - * @property {Promise=} backgroundJob + * @property {Promise=} backgroundJob */ /** * @param {FileMiddleware} middleware this * @param {BufferSerializableType[] | Promise} data data to be serialized * @param {string | boolean} name file base name - * @param {function(string | false, Buffer[]): Promise} writeFile writes a file + * @param {function(string | false, Buffer[], number): Promise} writeFile writes a file + * @param {string | Hash} hashFunction hash function to use * @returns {Promise} resulting file pointer and promise */ -const serialize = async (middleware, data, name, writeFile) => { +const serialize = async ( + middleware, + data, + name, + writeFile, + hashFunction = "md4" +) => { /** @type {(Buffer[] | Buffer | SerializeResult | Promise)[]} */ const processedData = []; /** @type {WeakMap>} */ const resultToLazy = new WeakMap(); - /** @type {Buffer[]} */ - let lastBuffers = undefined; + /** @type {Buffer[] | undefined} */ + let lastBuffers; for (const item of await data) { if (typeof item === "function") { if (!SerializerMiddleware.isLazy(item)) @@ -107,7 +135,8 @@ const serialize = async (middleware, data, name, writeFile) => { middleware, content, (options && options.name) || true, - writeFile + writeFile, + hashFunction ).then(result => { /** @type {any} */ (item).options.size = result.size; resultToLazy.set(result, item); @@ -135,7 +164,8 @@ const serialize = async (middleware, data, name, writeFile) => { const backgroundJobs = []; const resolvedData = ( await Promise.all( - /** @type {Promise[]} */ (processedData) + /** @type {Promise[]} */ + (processedData) ) ).map(item => { if (Array.isArray(item) || Buffer.isBuffer(item)) return item; @@ -151,6 +181,7 @@ const serialize = async (middleware, data, name, writeFile) => { SerializerMiddleware.setLazySerializedValue(lazy, buf); return buf; }); + /** @type {number[]} */ const lengths = []; for (const item of resolvedData) { if (Array.isArray(item)) { @@ -164,7 +195,7 @@ const serialize = async (middleware, data, name, writeFile) => { } else if (item) { lengths.push(-item.length); } else { - throw new Error("Unexpected falsy value in resolved data " + item); + throw new Error(`Unexpected falsy value in resolved data ${item}`); } } const header = Buffer.allocUnsafe(8 + lengths.length * 4); @@ -173,6 +204,7 @@ const serialize = async (middleware, data, name, writeFile) => { for (let i = 0; i < lengths.length; i++) { header.writeInt32LE(lengths[i], 8 + i * 4); } + /** @type {Buffer[]} */ const buf = [header]; for (const item of resolvedData) { if (Array.isArray(item)) { @@ -182,11 +214,11 @@ const serialize = async (middleware, data, name, writeFile) => { } } if (name === true) { - name = hashForName(buf); + name = hashForName(buf, hashFunction); } - backgroundJobs.push(writeFile(name, buf)); let size = 0; for (const b of buf) size += b.length; + backgroundJobs.push(writeFile(name, buf, size)); return { size, name, @@ -205,18 +237,21 @@ const serialize = async (middleware, data, name, writeFile) => { */ const deserialize = async (middleware, name, readFile) => { const contents = await readFile(name); - if (contents.length === 0) throw new Error("Empty file " + name); + if (contents.length === 0) throw new Error(`Empty file ${name}`); let contentsIndex = 0; let contentItem = contents[0]; let contentItemLength = contentItem.length; let contentPosition = 0; - if (contentItemLength === 0) throw new Error("Empty file " + name); + if (contentItemLength === 0) throw new Error(`Empty file ${name}`); const nextContent = () => { contentsIndex++; contentItem = contents[contentsIndex]; contentItemLength = contentItem.length; contentPosition = 0; }; + /** + * @param {number} n number of bytes to ensure + */ const ensureData = n => { if (contentPosition === contentItemLength) { nextContent(); @@ -244,18 +279,28 @@ const deserialize = async (middleware, name, readFile) => { contentPosition = 0; } }; + /** + * @returns {number} value value + */ const readUInt32LE = () => { ensureData(4); const value = contentItem.readUInt32LE(contentPosition); contentPosition += 4; return value; }; + /** + * @returns {number} value value + */ const readInt32LE = () => { ensureData(4); const value = contentItem.readInt32LE(contentPosition); contentPosition += 4; return value; }; + /** + * @param {number} l length + * @returns {Buffer} buffer + */ const readSlice = l => { ensureData(l); if (contentPosition === 0 && contentItemLength === l) { @@ -278,8 +323,16 @@ const deserialize = async (middleware, name, readFile) => { } const sectionCount = readUInt32LE(); const lengths = []; + let lastLengthPositive = false; for (let i = 0; i < sectionCount; i++) { - lengths.push(readInt32LE()); + const value = readInt32LE(); + const valuePositive = value >= 0; + if (lastLengthPositive && valuePositive) { + lengths[lengths.length - 1] += value; + } else { + lengths.push(value); + lastLengthPositive = valuePositive; + } } const result = []; for (let length of lengths) { @@ -305,25 +358,36 @@ const deserialize = async (middleware, name, readFile) => { } else if (contentPosition !== 0) { if (length <= contentItemLength - contentPosition) { result.push( - contentItem.slice(contentPosition, contentPosition + length) + Buffer.from( + contentItem.buffer, + contentItem.byteOffset + contentPosition, + length + ) ); contentPosition += length; length = 0; } else { - result.push(contentItem.slice(contentPosition)); - length -= contentItemLength - contentPosition; + const l = contentItemLength - contentPosition; + result.push( + Buffer.from( + contentItem.buffer, + contentItem.byteOffset + contentPosition, + l + ) + ); + length -= l; contentPosition = contentItemLength; } + } else if (length >= contentItemLength) { + result.push(contentItem); + length -= contentItemLength; + contentPosition = contentItemLength; } else { - if (length >= contentItemLength) { - result.push(contentItem); - length -= contentItemLength; - contentPosition = contentItemLength; - } else { - result.push(contentItem.slice(0, length)); - contentPosition += length; - length = 0; - } + result.push( + Buffer.from(contentItem.buffer, contentItem.byteOffset, length) + ); + contentPosition += length; + length = 0; } while (length > 0) { nextContent(); @@ -332,7 +396,9 @@ const deserialize = async (middleware, name, readFile) => { length -= contentItemLength; contentPosition = contentItemLength; } else { - result.push(contentItem.slice(0, length)); + result.push( + Buffer.from(contentItem.buffer, contentItem.byteOffset, length) + ); contentPosition += length; length = 0; } @@ -342,6 +408,8 @@ const deserialize = async (middleware, name, readFile) => { return result; }; +/** @typedef {{ filename: string, extension?: string }} FileMiddlewareContext */ + /** * @typedef {BufferSerializableType[]} DeserializedType * @typedef {true} SerializedType @@ -350,14 +418,17 @@ const deserialize = async (middleware, name, readFile) => { class FileMiddleware extends SerializerMiddleware { /** * @param {IntermediateFileSystem} fs filesystem + * @param {string | Hash} hashFunction hash function to use */ - constructor(fs) { + constructor(fs, hashFunction = "md4") { super(); this.fs = fs; + this._hashFunction = hashFunction; } + /** * @param {DeserializedType} data data - * @param {Object} context context object + * @param {object} context context object * @returns {SerializedType|Promise} serialized data */ serialize(data, context) { @@ -369,30 +440,110 @@ class FileMiddleware extends SerializerMiddleware { // It's important that we don't touch existing files during serialization // because serialize may read existing files (when deserializing) const allWrittenFiles = new Set(); - const writeFile = async (name, content) => { + /** + * @param {string | false} name name + * @param {Buffer[]} content content + * @param {number} size size + * @returns {Promise} + */ + const writeFile = async (name, content, size) => { const file = name ? join(this.fs, filename, `../${name}${extension}`) : filename; - await new Promise((resolve, reject) => { - const stream = this.fs.createWriteStream(file + "_"); - for (const b of content) stream.write(b); - stream.end(); - stream.on("error", err => reject(err)); - stream.on("finish", () => resolve()); - }); + await new Promise( + /** + * @param {(value?: undefined) => void} resolve resolve + * @param {(reason?: Error | null) => void} reject reject + */ + (resolve, reject) => { + let stream = this.fs.createWriteStream(`${file}_`); + let compression; + if (file.endsWith(".gz")) { + compression = createGzip({ + chunkSize: COMPRESSION_CHUNK_SIZE, + level: zConstants.Z_BEST_SPEED + }); + } else if (file.endsWith(".br")) { + compression = createBrotliCompress({ + chunkSize: COMPRESSION_CHUNK_SIZE, + params: { + [zConstants.BROTLI_PARAM_MODE]: zConstants.BROTLI_MODE_TEXT, + [zConstants.BROTLI_PARAM_QUALITY]: 2, + [zConstants.BROTLI_PARAM_DISABLE_LITERAL_CONTEXT_MODELING]: true, + [zConstants.BROTLI_PARAM_SIZE_HINT]: size + } + }); + } + if (compression) { + pipeline(compression, stream, reject); + stream = compression; + stream.on("finish", () => resolve()); + } else { + stream.on("error", err => reject(err)); + stream.on("finish", () => resolve()); + } + // split into chunks for WRITE_LIMIT_CHUNK size + /** @type {TODO[]} */ + const chunks = []; + for (const b of content) { + if (b.length < WRITE_LIMIT_CHUNK) { + chunks.push(b); + } else { + for (let i = 0; i < b.length; i += WRITE_LIMIT_CHUNK) { + chunks.push(b.slice(i, i + WRITE_LIMIT_CHUNK)); + } + } + } + + const len = chunks.length; + let i = 0; + /** + * @param {(Error | null)=} err err + */ + const batchWrite = err => { + // will be handled in "on" error handler + if (err) return; + + if (i === len) { + stream.end(); + return; + } + + // queue up a batch of chunks up to the write limit + // end is exclusive + let end = i; + let sum = chunks[end++].length; + while (end < len) { + sum += chunks[end].length; + if (sum > WRITE_LIMIT_TOTAL) break; + end++; + } + while (i < end - 1) { + stream.write(chunks[i++]); + } + stream.write(chunks[i++], batchWrite); + }; + batchWrite(); + } + ); if (name) allWrittenFiles.add(file); }; resolve( - serialize(this, data, false, writeFile).then( + serialize(this, data, false, writeFile, this._hashFunction).then( async ({ backgroundJob }) => { await backgroundJob; // Rename the index file to disallow access during inconsistent file state - await new Promise(resolve => - this.fs.rename(filename, filename + ".old", err => { - resolve(); - }) + await new Promise( + /** + * @param {(value?: undefined) => void} resolve resolve + */ + resolve => { + this.fs.rename(filename, `${filename}.old`, err => { + resolve(); + }); + } ); // update all written files @@ -400,22 +551,35 @@ class FileMiddleware extends SerializerMiddleware { Array.from( allWrittenFiles, file => - new Promise((resolve, reject) => { - this.fs.rename(file + "_", file, err => { - if (err) return reject(err); - resolve(); - }); - }) + new Promise( + /** + * @param {(value?: undefined) => void} resolve resolve + * @param {(reason?: Error | null) => void} reject reject + * @returns {void} + */ + (resolve, reject) => { + this.fs.rename(`${file}_`, file, err => { + if (err) return reject(err); + resolve(); + }); + } + ) ) ); // As final step automatically update the index file to have a consistent pack again - await new Promise(resolve => { - this.fs.rename(filename + "_", filename, err => { - if (err) return reject(err); - resolve(); - }); - }); + await new Promise( + /** + * @param {(value?: undefined) => void} resolve resolve + * @returns {void} + */ + resolve => { + this.fs.rename(`${filename}_`, filename, err => { + if (err) return reject(err); + resolve(); + }); + } + ); return /** @type {true} */ (true); } ) @@ -426,11 +590,15 @@ class FileMiddleware extends SerializerMiddleware { /** * @param {SerializedType} data data - * @param {Object} context context object + * @param {object} context context object * @returns {DeserializedType|Promise} deserialized data */ deserialize(data, context) { const { filename, extension = "" } = context; + /** + * @param {string | boolean} name name + * @returns {Promise} result + */ const readFile = name => new Promise((resolve, reject) => { const file = name @@ -441,25 +609,66 @@ class FileMiddleware extends SerializerMiddleware { reject(err); return; } - let remaining = /** @type {number} */ (stats.size); + let remaining = /** @type {IStats} */ (stats).size; + /** @type {Buffer | undefined} */ let currentBuffer; + /** @type {number | undefined} */ let currentBufferUsed; + /** @type {any[]} */ const buf = []; - this.fs.open(file, "r", (err, fd) => { + /** @type {import("zlib").Zlib & import("stream").Transform | undefined} */ + let decompression; + if (file.endsWith(".gz")) { + decompression = createGunzip({ + chunkSize: DECOMPRESSION_CHUNK_SIZE + }); + } else if (file.endsWith(".br")) { + decompression = createBrotliDecompress({ + chunkSize: DECOMPRESSION_CHUNK_SIZE + }); + } + if (decompression) { + let newResolve; + let newReject; + resolve( + Promise.all([ + new Promise((rs, rj) => { + newResolve = rs; + newReject = rj; + }), + new Promise((resolve, reject) => { + decompression.on("data", chunk => buf.push(chunk)); + decompression.on("end", () => resolve()); + decompression.on("error", err => reject(err)); + }) + ]).then(() => buf) + ); + resolve = newResolve; + reject = newReject; + } + this.fs.open(file, "r", (err, _fd) => { if (err) { reject(err); return; } + const fd = /** @type {number} */ (_fd); const read = () => { if (currentBuffer === undefined) { currentBuffer = Buffer.allocUnsafeSlow( - Math.min(constants.MAX_LENGTH, remaining) + Math.min( + constants.MAX_LENGTH, + remaining, + decompression ? DECOMPRESSION_CHUNK_SIZE : Infinity + ) ); currentBufferUsed = 0; } let readBuffer = currentBuffer; - let readOffset = currentBufferUsed; - let readLength = currentBuffer.length - currentBufferUsed; + let readOffset = /** @type {number} */ (currentBufferUsed); + let readLength = + currentBuffer.length - + /** @type {number} */ (currentBufferUsed); + // values passed to fs.read must be valid int32 values if (readOffset > 0x7fffffff) { readBuffer = currentBuffer.slice(readOffset); readOffset = 0; @@ -480,12 +689,23 @@ class FileMiddleware extends SerializerMiddleware { }); return; } - currentBufferUsed += bytesRead; + /** @type {number} */ + (currentBufferUsed) += bytesRead; remaining -= bytesRead; - if (currentBufferUsed === currentBuffer.length) { - buf.push(currentBuffer); + if ( + currentBufferUsed === + /** @type {Buffer} */ (currentBuffer).length + ) { + if (decompression) { + decompression.write(currentBuffer); + } else { + buf.push(currentBuffer); + } currentBuffer = undefined; if (remaining === 0) { + if (decompression) { + decompression.end(); + } this.fs.close(fd, err => { if (err) { reject(err); diff --git a/lib/serialization/MapObjectSerializer.js b/lib/serialization/MapObjectSerializer.js index 0718b710a76..0b1f4182b96 100644 --- a/lib/serialization/MapObjectSerializer.js +++ b/lib/serialization/MapObjectSerializer.js @@ -4,25 +4,42 @@ "use strict"; +/** @typedef {import("./ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */ +/** @typedef {import("./ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */ + class MapObjectSerializer { - serialize(obj, { write }) { - write(obj.size); + /** + * @template K, V + * @param {Map} obj map + * @param {ObjectSerializerContext} context context + */ + serialize(obj, context) { + context.write(obj.size); for (const key of obj.keys()) { - write(key); + context.write(key); } for (const value of obj.values()) { - write(value); + context.write(value); } } - deserialize({ read }) { - let size = read(); + + /** + * @template K, V + * @param {ObjectDeserializerContext} context context + * @returns {Map} map + */ + deserialize(context) { + /** @type {number} */ + const size = context.read(); + /** @type {Map} */ const map = new Map(); + /** @type {K[]} */ const keys = []; for (let i = 0; i < size; i++) { - keys.push(read()); + keys.push(context.read()); } for (let i = 0; i < size; i++) { - map.set(keys[i], read()); + map.set(keys[i], context.read()); } return map; } diff --git a/lib/serialization/NullPrototypeObjectSerializer.js b/lib/serialization/NullPrototypeObjectSerializer.js index 0321d62d7e5..32adaeaaede 100644 --- a/lib/serialization/NullPrototypeObjectSerializer.js +++ b/lib/serialization/NullPrototypeObjectSerializer.js @@ -4,27 +4,45 @@ "use strict"; +/** @typedef {import("./ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */ +/** @typedef {import("./ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */ + class NullPrototypeObjectSerializer { - serialize(obj, { write }) { + /** + * @template {object} T + * @param {T} obj null object + * @param {ObjectSerializerContext} context context + */ + serialize(obj, context) { + /** @type {string[]} */ const keys = Object.keys(obj); for (const key of keys) { - write(key); + context.write(key); } - write(null); + context.write(null); for (const key of keys) { - write(obj[key]); + context.write(obj[/** @type {keyof T} */ (key)]); } } - deserialize({ read }) { + + /** + * @template {object} T + * @param {ObjectDeserializerContext} context context + * @returns {T} null object + */ + deserialize(context) { + /** @type {T} */ const obj = Object.create(null); + /** @type {string[]} */ const keys = []; - let key = read(); + /** @type {string | null} */ + let key = context.read(); while (key !== null) { keys.push(key); - key = read(); + key = context.read(); } for (const key of keys) { - obj[key] = read(); + obj[/** @type {keyof T} */ (key)] = context.read(); } return obj; } diff --git a/lib/serialization/ObjectMiddleware.js b/lib/serialization/ObjectMiddleware.js index a03af5f6e6d..68f3cd5d12a 100644 --- a/lib/serialization/ObjectMiddleware.js +++ b/lib/serialization/ObjectMiddleware.js @@ -15,6 +15,7 @@ const RegExpObjectSerializer = require("./RegExpObjectSerializer"); const SerializerMiddleware = require("./SerializerMiddleware"); const SetObjectSerializer = require("./SetObjectSerializer"); +/** @typedef {typeof import("../util/Hash")} Hash */ /** @typedef {import("./types").ComplexSerializableType} ComplexSerializableType */ /** @typedef {import("./types").PrimitiveSerializableType} PrimitiveSerializableType */ @@ -43,21 +44,30 @@ Technically any value can be used. */ /** - * @typedef {Object} ObjectSerializerContext + * @typedef {object} ObjectSerializerContext * @property {function(any): void} write + * @property {(function(any): void)=} writeLazy + * @property {(function(any, object=): (() => Promise | any))=} writeSeparate + * @property {function(any): void} setCircularReference */ /** - * @typedef {Object} ObjectDeserializerContext + * @typedef {object} ObjectDeserializerContext * @property {function(): any} read + * @property {function(any): void} setCircularReference */ /** - * @typedef {Object} ObjectSerializer + * @typedef {object} ObjectSerializer * @property {function(any, ObjectSerializerContext): void} serialize * @property {function(ObjectDeserializerContext): any} deserialize */ +/** + * @template T + * @param {Set} set set + * @param {number} size count of items to keep + */ const setSetSize = (set, size) => { let i = 0; for (const item of set) { @@ -67,6 +77,11 @@ const setSetSize = (set, size) => { } }; +/** + * @template K, X + * @param {Map} map map + * @param {number} size count of items to keep + */ const setMapSize = (map, size) => { let i = 0; for (const item of map.keys()) { @@ -76,8 +91,13 @@ const setMapSize = (map, size) => { } }; -const toHash = buffer => { - const hash = createHash("md4"); +/** + * @param {Buffer} buffer buffer + * @param {string | Hash} hashFunction hash function to use + * @returns {string} hash + */ +const toHash = (buffer, hashFunction) => { + const hash = createHash(hashFunction); hash.update(buffer); return /** @type {string} */ (hash.digest("latin1")); }; @@ -89,9 +109,12 @@ const ESCAPE_UNDEFINED = false; const CURRENT_VERSION = 2; +/** @type {Map} */ const serializers = new Map(); +/** @type {Map} */ const serializerInversed = new Map(); +/** @type {Set} */ const loadedRequests = new Set(); const NOT_SERIALIZABLE = {}; @@ -114,7 +137,9 @@ jsTypes.set(TypeError, new ErrorObjectSerializer(TypeError)); // If in a sandboxed environment (e. g. jest), this escapes the sandbox and registers // real Object and Array types to. These types may occur in the wild too, e. g. when // using Structured Clone in postMessage. +// eslint-disable-next-line n/exports-style if (exports.constructor !== Object) { + // eslint-disable-next-line jsdoc/check-types, n/exports-style const Obj = /** @type {typeof Object} */ (exports.constructor); const Fn = /** @type {typeof Function} */ (Obj.constructor); for (const [type, config] of Array.from(jsTypes)) { @@ -137,7 +162,10 @@ if (exports.constructor !== Object) { } for (const { request, name, serializer } of serializers.values()) { - serializerInversed.set(`${request}/${name}`, serializer); + serializerInversed.set( + `${request}/${name}`, + /** @type {ObjectSerializer} */ (serializer) + ); } /** @type {Map boolean>} */ @@ -149,10 +177,16 @@ const loaders = new Map(); * @extends {SerializerMiddleware} */ class ObjectMiddleware extends SerializerMiddleware { - constructor(extendContext) { + /** + * @param {function(any): void} extendContext context extensions + * @param {string | Hash} hashFunction hash function to use + */ + constructor(extendContext, hashFunction = "md4") { super(); this.extendContext = extendContext; + this._hashFunction = hashFunction; } + /** * @param {RegExp} regExp RegExp for which the request is tested * @param {function(string): boolean} loader loader to load the request, returns true when successful @@ -165,12 +199,12 @@ class ObjectMiddleware extends SerializerMiddleware { /** * @param {Constructor} Constructor the constructor * @param {string} request the request which will be required when deserializing - * @param {string} name the name to make multiple serializer unique when sharing a request + * @param {string | null} name the name to make multiple serializer unique when sharing a request * @param {ObjectSerializer} serializer the serializer * @returns {void} */ static register(Constructor, request, name, serializer) { - const key = request + "/" + name; + const key = `${request}/${name}`; if (serializers.has(Constructor)) { throw new Error( @@ -229,8 +263,13 @@ class ObjectMiddleware extends SerializerMiddleware { return config; } + /** + * @param {string} request request + * @param {TODO} name name + * @returns {ObjectSerializer} serializer + */ static getDeserializerFor(request, name) { - const key = request + "/" + name; + const key = `${request}/${name}`; const serializer = serializerInversed.get(key); if (serializer === undefined) { @@ -240,26 +279,31 @@ class ObjectMiddleware extends SerializerMiddleware { return serializer; } + /** + * @param {string} request request + * @param {TODO} name name + * @returns {ObjectSerializer} serializer + */ static _getDeserializerForWithoutError(request, name) { - const key = request + "/" + name; + const key = `${request}/${name}`; const serializer = serializerInversed.get(key); return serializer; } /** * @param {DeserializedType} data data - * @param {Object} context context object + * @param {object} context context object * @returns {SerializedType|Promise} serialized data */ serialize(data, context) { /** @type {any[]} */ - const result = [CURRENT_VERSION]; + let result = [CURRENT_VERSION]; let currentPos = 0; - const referenceable = new Map(); + let referenceable = new Map(); const addReferenceable = item => { referenceable.set(item, currentPos++); }; - const bufferDedupeMap = new Map(); + let bufferDedupeMap = new Map(); const dedupeBuffer = buf => { const len = buf.length; const entry = bufferDedupeMap.get(len); @@ -274,17 +318,16 @@ class ObjectMiddleware extends SerializerMiddleware { } bufferDedupeMap.set(len, [entry, buf]); return buf; - } else { - const hash = toHash(entry); - const newMap = new Map(); - newMap.set(hash, entry); - bufferDedupeMap.set(len, newMap); - const hashBuf = toHash(buf); - if (hash === hashBuf) { - return entry; - } - return buf; } + const hash = toHash(entry, this._hashFunction); + const newMap = new Map(); + newMap.set(hash, entry); + bufferDedupeMap.set(len, newMap); + const hashBuf = toHash(buf, this._hashFunction); + if (hash === hashBuf) { + return entry; + } + return buf; } else if (Array.isArray(entry)) { if (entry.length < 16) { for (const item of entry) { @@ -294,35 +337,32 @@ class ObjectMiddleware extends SerializerMiddleware { } entry.push(buf); return buf; - } else { - const newMap = new Map(); - const hash = toHash(buf); - let found; - for (const item of entry) { - const itemHash = toHash(item); - newMap.set(itemHash, item); - if (found === undefined && itemHash === hash) found = item; - } - bufferDedupeMap.set(len, newMap); - if (found === undefined) { - newMap.set(hash, buf); - return buf; - } else { - return found; - } } - } else { - const hash = toHash(buf); - const item = entry.get(hash); - if (item !== undefined) { - return item; + const newMap = new Map(); + const hash = toHash(buf, this._hashFunction); + let found; + for (const item of entry) { + const itemHash = toHash(item, this._hashFunction); + newMap.set(itemHash, item); + if (found === undefined && itemHash === hash) found = item; } - entry.set(hash, buf); - return buf; + bufferDedupeMap.set(len, newMap); + if (found === undefined) { + newMap.set(hash, buf); + return buf; + } + return found; + } + const hash = toHash(buf, this._hashFunction); + const item = entry.get(hash); + if (item !== undefined) { + return item; } + entry.set(hash, buf); + return buf; }; let currentPosTypeLookup = 0; - const objectTypeLookup = new Map(); + let objectTypeLookup = new Map(); const cycleStack = new Set(); const stackToString = item => { const arr = Array.from(cycleStack); @@ -343,7 +383,7 @@ class ObjectMiddleware extends SerializerMiddleware { if (request) { return `${request}${name ? `.${name}` : ""}`; } - } catch (e) { + } catch (_err) { // ignore -> fallback } if (typeof item === "object" && item !== null) { @@ -361,31 +401,37 @@ class ObjectMiddleware extends SerializerMiddleware { ", " )} }`; } + if (typeof item === "bigint") { + return `BigInt ${item}n`; + } try { return `${item}`; - } catch (e) { - return `(${e.message})`; + } catch (err) { + return `(${err.message})`; } }) .join(" -> "); }; let hasDebugInfoAttached; - const ctx = { + let ctx = { write(value, key) { try { process(value); - } catch (e) { - if (e !== NOT_SERIALIZABLE) { + } catch (err) { + if (err !== NOT_SERIALIZABLE) { if (hasDebugInfoAttached === undefined) hasDebugInfoAttached = new WeakSet(); - if (!hasDebugInfoAttached.has(e)) { - e.message += `\nwhile serializing ${stackToString(value)}`; - hasDebugInfoAttached.add(e); + if (!hasDebugInfoAttached.has(err)) { + err.message += `\nwhile serializing ${stackToString(value)}`; + hasDebugInfoAttached.add(err); } } - throw e; + throw err; } }, + setCircularReference(ref) { + addReferenceable(ref); + }, snapshot() { return { length: result.length, @@ -408,16 +454,13 @@ class ObjectMiddleware extends SerializerMiddleware { }; this.extendContext(ctx); const process = item => { - // check if we can emit a reference - const ref = referenceable.get(item); - - if (ref !== undefined) { - result.push(ESCAPE, ref - currentPos); - - return; - } - if (Buffer.isBuffer(item)) { + // check if we can emit a reference + const ref = referenceable.get(item); + if (ref !== undefined) { + result.push(ESCAPE, ref - currentPos); + return; + } const alreadyUsedBuffer = dedupeBuffer(item); if (alreadyUsedBuffer !== item) { const ref = referenceable.get(alreadyUsedBuffer); @@ -431,14 +474,27 @@ class ObjectMiddleware extends SerializerMiddleware { addReferenceable(item); result.push(item); - } else if (typeof item === "object" && item !== null) { + } else if (item === ESCAPE) { + result.push(ESCAPE, ESCAPE_ESCAPE_VALUE); + } else if ( + typeof item === "object" + // We don't have to check for null as ESCAPE is null and this has been checked before + ) { + // check if we can emit a reference + const ref = referenceable.get(item); + if (ref !== undefined) { + result.push(ESCAPE, ref - currentPos); + return; + } + if (cycleStack.has(item)) { - throw new Error(`Circular references can't be serialized`); + throw new Error( + "This is a circular references. To serialize circular references use 'setCircularReference' somewhere in the circle during serialize and deserialize." + ); } - const { request, name, serializer } = ObjectMiddleware.getSerializerFor( - item - ); + const { request, name, serializer } = + ObjectMiddleware.getSerializerFor(item); const key = `${request}/${name}`; const lastIndex = objectTypeLookup.get(key); @@ -464,6 +520,12 @@ class ObjectMiddleware extends SerializerMiddleware { } else if (typeof item === "string") { if (item.length > 1) { // short strings are shorter when not emitting a reference (this saves 1 byte per empty string) + // check if we can emit a reference + const ref = referenceable.get(item); + if (ref !== undefined) { + result.push(ESCAPE, ref - currentPos); + return; + } addReferenceable(item); } @@ -476,15 +538,12 @@ class ObjectMiddleware extends SerializerMiddleware { } result.push(item); - } else if (item === ESCAPE) { - result.push(ESCAPE, ESCAPE_ESCAPE_VALUE); } else if (typeof item === "function") { if (!SerializerMiddleware.isLazy(item)) - throw new Error("Unexpected function " + item); + throw new Error(`Unexpected function ${item}`); /** @type {SerializedType} */ - const serializedData = SerializerMiddleware.getLazySerializedValue( - item - ); + const serializedData = + SerializerMiddleware.getLazySerializedValue(item); if (serializedData !== undefined) { if (typeof serializedData === "function") { result.push(serializedData); @@ -494,11 +553,11 @@ class ObjectMiddleware extends SerializerMiddleware { } else if (SerializerMiddleware.isLazy(item, this)) { throw new Error("Not implemented"); } else { - result.push( - SerializerMiddleware.serializeLazy(item, data => - this.serialize([data], context) - ) + const data = SerializerMiddleware.serializeLazy(item, data => + this.serialize([data], context) ); + SerializerMiddleware.setLazySerializedValue(item, data); + result.push(data); } } else if (item === undefined) { result.push(ESCAPE, ESCAPE_UNDEFINED); @@ -511,18 +570,29 @@ class ObjectMiddleware extends SerializerMiddleware { for (const item of data) { process(item); } - } catch (e) { - if (e === NOT_SERIALIZABLE) return null; - - throw e; + return result; + } catch (err) { + if (err === NOT_SERIALIZABLE) return null; + + throw err; + } finally { + // Get rid of these references to avoid leaking memory + // This happens because the optimized code v8 generates + // is optimized for our "ctx.write" method so it will reference + // it from e. g. Dependency.prototype.serialize -(IC)-> ctx.write + data = + result = + referenceable = + bufferDedupeMap = + objectTypeLookup = + ctx = + undefined; } - - return result; } /** * @param {SerializedType} data data - * @param {Object} context context object + * @param {object} context context object * @returns {DeserializedType|Promise} deserialized data */ deserialize(data, context) { @@ -545,11 +615,14 @@ class ObjectMiddleware extends SerializerMiddleware { }; let currentPosTypeLookup = 0; let objectTypeLookup = []; - const result = []; - const ctx = { + let result = []; + let ctx = { read() { return decodeValue(); }, + setCircularReference(ref) { + addReferenceable(ref); + }, ...context }; this.extendContext(ctx); @@ -562,19 +635,20 @@ class ObjectMiddleware extends SerializerMiddleware { if (nextItem === ESCAPE_ESCAPE_VALUE) { return ESCAPE; } else if (nextItem === ESCAPE_UNDEFINED) { - return undefined; + // Nothing } else if (nextItem === ESCAPE_END_OBJECT) { throw new Error( `Unexpected end of object at position ${currentDataPos - 1}` ); - } else if (typeof nextItem === "number" && nextItem < 0) { - // relative reference - return referenceable[currentPos + nextItem]; } else { const request = nextItem; let serializer; if (typeof request === "number") { + if (request < 0) { + // relative reference + return referenceable[currentPos + request]; + } serializer = objectTypeLookup[currentPosTypeLookup - request]; } else { if (typeof request !== "string") { @@ -594,11 +668,9 @@ class ObjectMiddleware extends SerializerMiddleware { if (request && !loadedRequests.has(request)) { let loaded = false; for (const [regExp, loader] of loaders) { - if (regExp.test(request)) { - if (loader(request)) { - loaded = true; - break; - } + if (regExp.test(request) && loader(request)) { + loaded = true; + break; } } if (!loaded) { @@ -645,10 +717,10 @@ class ObjectMiddleware extends SerializerMiddleware { const name = !serializerEntry ? "unknown" : !serializerEntry[1].request - ? serializerEntry[0].name - : serializerEntry[1].name - ? `${serializerEntry[1].request} ${serializerEntry[1].name}` - : serializerEntry[1].request; + ? serializerEntry[0].name + : serializerEntry[1].name + ? `${serializerEntry[1].request} ${serializerEntry[1].name}` + : serializerEntry[1].request; err.message += `\n(during deserialization of ${name})`; throw err; } @@ -673,16 +745,18 @@ class ObjectMiddleware extends SerializerMiddleware { } }; - while (currentDataPos < data.length) { - result.push(decodeValue()); + try { + while (currentDataPos < data.length) { + result.push(decodeValue()); + } + return result; + } finally { + // Get rid of these references to avoid leaking memory + // This happens because the optimized code v8 generates + // is optimized for our "ctx.read" method so it will reference + // it from e. g. Dependency.prototype.deserialize -(IC)-> ctx.read + result = referenceable = data = objectTypeLookup = ctx = undefined; } - - // Help the GC, as functions above might be cached in inline caches - referenceable = undefined; - objectTypeLookup = undefined; - data = undefined; - - return result; } } diff --git a/lib/serialization/PlainObjectSerializer.js b/lib/serialization/PlainObjectSerializer.js index 4d67b497be2..428825e388e 100644 --- a/lib/serialization/PlainObjectSerializer.js +++ b/lib/serialization/PlainObjectSerializer.js @@ -4,65 +4,111 @@ "use strict"; +/** @typedef {import("./ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */ +/** @typedef {import("./ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */ + +/** @typedef {(arg0?: any) => void} CacheAssoc */ + +/** + * @template T + * @typedef {WeakMap>} + */ const cache = new WeakMap(); +/** + * @template T + */ class ObjectStructure { - constructor(keys) { - this.keys = keys; - this.children = new Map(); + constructor() { + this.keys = undefined; + this.children = undefined; } - getKeys() { + /** + * @param {keyof T[]} keys keys + * @returns {keyof T[]} keys + */ + getKeys(keys) { + if (this.keys === undefined) this.keys = keys; return this.keys; } + /** + * @param {keyof T} key key + * @returns {ObjectStructure} object structure + */ key(key) { + if (this.children === undefined) this.children = new Map(); const child = this.children.get(key); if (child !== undefined) return child; - const newChild = new ObjectStructure(this.keys.concat(key)); + const newChild = new ObjectStructure(); this.children.set(key, newChild); return newChild; } } +/** + * @template T + * @param {(keyof T)[]} keys keys + * @param {CacheAssoc} cacheAssoc cache assoc fn + * @returns {(keyof T)[]} keys + */ const getCachedKeys = (keys, cacheAssoc) => { let root = cache.get(cacheAssoc); if (root === undefined) { - root = new ObjectStructure([]); + root = new ObjectStructure(); cache.set(cacheAssoc, root); } let current = root; for (const key of keys) { current = current.key(key); } - return current.getKeys(); + return current.getKeys(keys); }; class PlainObjectSerializer { - serialize(obj, { write }) { - const keys = Object.keys(obj); - if (keys.length > 1) { - write(getCachedKeys(keys, write)); + /** + * @template {object} T + * @param {T} obj plain object + * @param {ObjectSerializerContext} context context + */ + serialize(obj, context) { + const keys = /** @type {(keyof T)[]} */ (Object.keys(obj)); + if (keys.length > 128) { + // Objects with so many keys are unlikely to share structure + // with other objects + context.write(keys); for (const key of keys) { - write(obj[key]); + context.write(obj[key]); + } + } else if (keys.length > 1) { + context.write(getCachedKeys(keys, context.write)); + for (const key of keys) { + context.write(obj[key]); } } else if (keys.length === 1) { const key = keys[0]; - write(key); - write(obj[key]); + context.write(key); + context.write(obj[key]); } else { - write(null); + context.write(null); } } - deserialize({ read }) { - const keys = read(); - const obj = {}; + + /** + * @template {object} T + * @param {ObjectDeserializerContext} context context + * @returns {T} plain object + */ + deserialize(context) { + const keys = context.read(); + const obj = /** @type {T} */ ({}); if (Array.isArray(keys)) { for (const key of keys) { - obj[key] = read(); + obj[/** @type {keyof T} */ (key)] = context.read(); } } else if (keys !== null) { - obj[keys] = read(); + obj[/** @type {keyof T} */ (keys)] = context.read(); } return obj; } diff --git a/lib/serialization/RegExpObjectSerializer.js b/lib/serialization/RegExpObjectSerializer.js index 61ca881f3c6..5ac7eec5105 100644 --- a/lib/serialization/RegExpObjectSerializer.js +++ b/lib/serialization/RegExpObjectSerializer.js @@ -4,13 +4,25 @@ "use strict"; +/** @typedef {import("./ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */ +/** @typedef {import("./ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */ + class RegExpObjectSerializer { - serialize(obj, { write }) { - write(obj.source); - write(obj.flags); + /** + * @param {RegExp} obj regexp + * @param {ObjectSerializerContext} context context + */ + serialize(obj, context) { + context.write(obj.source); + context.write(obj.flags); } - deserialize({ read }) { - return new RegExp(read(), read()); + + /** + * @param {ObjectDeserializerContext} context context + * @returns {RegExp} regexp + */ + deserialize(context) { + return new RegExp(context.read(), context.read()); } } diff --git a/lib/serialization/Serializer.js b/lib/serialization/Serializer.js index 96ee3952539..ce241c67047 100644 --- a/lib/serialization/Serializer.js +++ b/lib/serialization/Serializer.js @@ -4,21 +4,33 @@ "use strict"; +/** + * @template T, K + * @typedef {import("./SerializerMiddleware")} SerializerMiddleware + */ + class Serializer { + /** + * @param {SerializerMiddleware[]} middlewares serializer middlewares + * @param {TODO=} context context + */ constructor(middlewares, context) { this.serializeMiddlewares = middlewares.slice(); this.deserializeMiddlewares = middlewares.slice().reverse(); this.context = context; } + /** + * @param {any} obj object + * @param {TODO} context content + * @returns {Promise} result + */ serialize(obj, context) { const ctx = { ...context, ...this.context }; let current = obj; for (const middleware of this.serializeMiddlewares) { - if (current instanceof Promise) { - current = current.then( - data => data && middleware.serialize(data, context) - ); + if (current && typeof current.then === "function") { + current = current.then(data => data && middleware.serialize(data, ctx)); } else if (current) { try { current = middleware.serialize(current, ctx); @@ -30,16 +42,20 @@ class Serializer { return current; } + /** + * @param {any} value value + * @param {TODO} context context + * @returns {Promise} result + */ deserialize(value, context) { const ctx = { ...context, ...this.context }; /** @type {any} */ let current = value; for (const middleware of this.deserializeMiddlewares) { - if (current instanceof Promise) { - current = current.then(data => middleware.deserialize(data, context)); - } else { - current = middleware.deserialize(current, ctx); - } + current = + current && typeof current.then === "function" + ? current.then(data => middleware.deserialize(data, ctx)) + : middleware.deserialize(current, ctx); } return current; } diff --git a/lib/serialization/SerializerMiddleware.js b/lib/serialization/SerializerMiddleware.js index f9d79ed833f..de56d29e0ab 100644 --- a/lib/serialization/SerializerMiddleware.js +++ b/lib/serialization/SerializerMiddleware.js @@ -18,7 +18,7 @@ class SerializerMiddleware { /** * @abstract * @param {DeserializedType} data data - * @param {Object} context context object + * @param {object} context context object * @returns {SerializedType|Promise} serialized data */ serialize(data, context) { @@ -30,7 +30,7 @@ class SerializerMiddleware { /** * @abstract * @param {SerializedType} data data - * @param {Object} context context object + * @param {object} context context object * @returns {DeserializedType|Promise} deserialized data */ deserialize(data, context) { @@ -45,7 +45,7 @@ class SerializerMiddleware { * @param {any=} serializedValue serialized value * @returns {function(): Promise | any} lazy function */ - static createLazy(value, target, options = {}, serializedValue) { + static createLazy(value, target, options = {}, serializedValue = undefined) { if (SerializerMiddleware.isLazy(value, target)) return value; const fn = typeof value === "function" ? value : () => value; fn[LAZY_TARGET] = target; @@ -62,24 +62,24 @@ class SerializerMiddleware { static isLazy(fn, target) { if (typeof fn !== "function") return false; const t = fn[LAZY_TARGET]; - return target ? t === target : !!t; + return target ? t === target : Boolean(t); } /** * @param {function(): Promise | any} fn lazy function - * @returns {object} options + * @returns {object | undefined} options */ static getLazyOptions(fn) { - if (typeof fn !== "function") return undefined; + if (typeof fn !== "function") return; return /** @type {any} */ (fn).options; } /** * @param {function(): Promise | any} fn lazy function - * @returns {any} serialized value + * @returns {any | undefined} serialized value */ static getLazySerializedValue(fn) { - if (typeof fn !== "function") return undefined; + if (typeof fn !== "function") return; return fn[LAZY_SERIALIZED_VALUE]; } @@ -100,9 +100,10 @@ class SerializerMiddleware { static serializeLazy(lazy, serialize) { const fn = memoize(() => { const r = lazy(); - if (r instanceof Promise) return r.then(data => data && serialize(data)); - if (r) return serialize(r); - return null; + if (r && typeof r.then === "function") { + return r.then(data => data && serialize(data)); + } + return serialize(r); }); fn[LAZY_TARGET] = lazy[LAZY_TARGET]; /** @type {any} */ (fn).options = /** @type {any} */ (lazy).options; @@ -118,7 +119,9 @@ class SerializerMiddleware { static deserializeLazy(lazy, deserialize) { const fn = memoize(() => { const r = lazy(); - if (r instanceof Promise) return r.then(data => deserialize(data)); + if (r && typeof r.then === "function") { + return r.then(data => deserialize(data)); + } return deserialize(r); }); fn[LAZY_TARGET] = lazy[LAZY_TARGET]; @@ -126,6 +129,25 @@ class SerializerMiddleware { fn[LAZY_SERIALIZED_VALUE] = lazy; return fn; } + + /** + * @param {function(): Promise | any} lazy lazy function + * @returns {function(): Promise | any} new lazy + */ + static unMemoizeLazy(lazy) { + if (!SerializerMiddleware.isLazy(lazy)) return lazy; + const fn = () => { + throw new Error( + "A lazy value that has been unmemorized can't be called again" + ); + }; + fn[LAZY_SERIALIZED_VALUE] = SerializerMiddleware.unMemoizeLazy( + lazy[LAZY_SERIALIZED_VALUE] + ); + fn[LAZY_TARGET] = lazy[LAZY_TARGET]; + fn.options = /** @type {any} */ (lazy).options; + return fn; + } } module.exports = SerializerMiddleware; diff --git a/lib/serialization/SetObjectSerializer.js b/lib/serialization/SetObjectSerializer.js index 71b3fcc0fa1..66811b87d16 100644 --- a/lib/serialization/SetObjectSerializer.js +++ b/lib/serialization/SetObjectSerializer.js @@ -4,18 +4,34 @@ "use strict"; +/** @typedef {import("./ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */ +/** @typedef {import("./ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */ + class SetObjectSerializer { - serialize(obj, { write }) { - write(obj.size); + /** + * @template T + * @param {Set} obj set + * @param {ObjectSerializerContext} context context + */ + serialize(obj, context) { + context.write(obj.size); for (const value of obj) { - write(value); + context.write(value); } } - deserialize({ read }) { - let size = read(); + + /** + * @template T + * @param {ObjectDeserializerContext} context context + * @returns {Set} date + */ + deserialize(context) { + /** @type {number} */ + const size = context.read(); + /** @type {Set} */ const set = new Set(); for (let i = 0; i < size; i++) { - set.add(read()); + set.add(context.read()); } return set; } diff --git a/lib/serialization/SingleItemMiddleware.js b/lib/serialization/SingleItemMiddleware.js index bc9ea094026..faf95de6a17 100644 --- a/lib/serialization/SingleItemMiddleware.js +++ b/lib/serialization/SingleItemMiddleware.js @@ -14,7 +14,7 @@ const SerializerMiddleware = require("./SerializerMiddleware"); class SingleItemMiddleware extends SerializerMiddleware { /** * @param {DeserializedType} data data - * @param {Object} context context object + * @param {object} context context object * @returns {SerializedType|Promise} serialized data */ serialize(data, context) { @@ -23,7 +23,7 @@ class SingleItemMiddleware extends SerializerMiddleware { /** * @param {SerializedType} data data - * @param {Object} context context object + * @param {object} context context object * @returns {DeserializedType|Promise} deserialized data */ deserialize(data, context) { diff --git a/lib/serialization/types.js b/lib/serialization/types.js index 04a91e5b6c0..5f0cfdbc804 100644 --- a/lib/serialization/types.js +++ b/lib/serialization/types.js @@ -4,9 +4,9 @@ "use strict"; -/** @typedef {undefined|null|number|string|boolean|Buffer|Object|(() => ComplexSerializableType[] | Promise)} ComplexSerializableType */ +/** @typedef {undefined | null | number | string | boolean | Buffer | object | (() => ComplexSerializableType[] | Promise)} ComplexSerializableType */ -/** @typedef {undefined|null|number|string|boolean|Buffer|(() => PrimitiveSerializableType[] | Promise)} PrimitiveSerializableType */ +/** @typedef {undefined|null|number|bigint|string|boolean|Buffer|(() => PrimitiveSerializableType[] | Promise)} PrimitiveSerializableType */ /** @typedef {Buffer|(() => BufferSerializableType[] | Promise)} BufferSerializableType */ diff --git a/lib/sharing/ConsumeSharedFallbackDependency.js b/lib/sharing/ConsumeSharedFallbackDependency.js index 126ba4ef410..bd6eefef13f 100644 --- a/lib/sharing/ConsumeSharedFallbackDependency.js +++ b/lib/sharing/ConsumeSharedFallbackDependency.js @@ -9,6 +9,9 @@ const ModuleDependency = require("../dependencies/ModuleDependency"); const makeSerializable = require("../util/makeSerializable"); class ConsumeSharedFallbackDependency extends ModuleDependency { + /** + * @param {string} request the request + */ constructor(request) { super(request); } diff --git a/lib/sharing/ConsumeSharedModule.js b/lib/sharing/ConsumeSharedModule.js index cb6881331b1..dcf40e7f9d7 100644 --- a/lib/sharing/ConsumeSharedModule.js +++ b/lib/sharing/ConsumeSharedModule.js @@ -8,6 +8,9 @@ const { RawSource } = require("webpack-sources"); const AsyncDependenciesBlock = require("../AsyncDependenciesBlock"); const Module = require("../Module"); +const { + WEBPACK_MODULE_TYPE_CONSUME_SHARED_MODULE +} = require("../ModuleTypeConstants"); const RuntimeGlobals = require("../RuntimeGlobals"); const makeSerializable = require("../util/makeSerializable"); const { rangeToString, stringifyHoley } = require("../util/semver"); @@ -22,21 +25,24 @@ const ConsumeSharedFallbackDependency = require("./ConsumeSharedFallbackDependen /** @typedef {import("../Module").CodeGenerationResult} CodeGenerationResult */ /** @typedef {import("../Module").LibIdentOptions} LibIdentOptions */ /** @typedef {import("../Module").NeedBuildContext} NeedBuildContext */ +/** @typedef {import("../Module").SourceTypes} SourceTypes */ /** @typedef {import("../RequestShortener")} RequestShortener */ /** @typedef {import("../ResolverFactory").ResolverWithOptions} ResolverWithOptions */ /** @typedef {import("../WebpackError")} WebpackError */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */ /** @typedef {import("../util/Hash")} Hash */ /** @typedef {import("../util/fs").InputFileSystem} InputFileSystem */ /** @typedef {import("../util/semver").SemVerRange} SemVerRange */ /** - * @typedef {Object} ConsumeOptions + * @typedef {object} ConsumeOptions * @property {string=} import fallback request * @property {string=} importResolved resolved fallback request * @property {string} shareKey global share key * @property {string} shareScope share scope * @property {SemVerRange | false | undefined} requiredVersion version requirement - * @property {string} packageName package name to determine required version automatically + * @property {string=} packageName package name to determine required version automatically * @property {boolean} strictVersion don't use shared version even if version isn't valid * @property {boolean} singleton use single global version * @property {boolean} eager include the fallback module in a sync way @@ -50,7 +56,7 @@ class ConsumeSharedModule extends Module { * @param {ConsumeOptions} options consume options */ constructor(context, options) { - super("consume-shared-module", context); + super(WEBPACK_MODULE_TYPE_CONSUME_SHARED_MODULE, context); this.options = options; } @@ -67,7 +73,7 @@ class ConsumeSharedModule extends Module { singleton, eager } = this.options; - return `consume-shared-module|${shareScope}|${shareKey}|${ + return `${WEBPACK_MODULE_TYPE_CONSUME_SHARED_MODULE}|${shareScope}|${shareKey}|${ requiredVersion && rangeToString(requiredVersion) }|${strictVersion}|${importResolved}|${singleton}|${eager}`; } @@ -101,14 +107,16 @@ class ConsumeSharedModule extends Module { */ libIdent(options) { const { shareKey, shareScope, import: request } = this.options; - return `webpack/sharing/consume/${shareScope}/${shareKey}${ + return `${ + this.layer ? `(${this.layer})/` : "" + }webpack/sharing/consume/${shareScope}/${shareKey}${ request ? `/${request}` : "" }`; } /** * @param {NeedBuildContext} context context info - * @param {function(WebpackError=, boolean=): void} callback callback function, returns true, if the module needs a rebuild + * @param {function((WebpackError | null)=, boolean=): void} callback callback function, returns true, if the module needs a rebuild * @returns {void} */ needBuild(context, callback) { @@ -140,7 +148,7 @@ class ConsumeSharedModule extends Module { } /** - * @returns {Set} types available (do not mutate) + * @returns {SourceTypes} types available (do not mutate) */ getSourceTypes() { return TYPES; @@ -199,22 +207,31 @@ class ConsumeSharedModule extends Module { }); } } - let fn = "load"; - const args = [JSON.stringify(shareScope), JSON.stringify(shareKey)]; + + const args = [ + JSON.stringify(shareScope), + JSON.stringify(shareKey), + JSON.stringify(eager) + ]; if (requiredVersion) { - if (strictVersion) { - fn += "Strict"; - } - if (singleton) { - fn += "Singleton"; - } args.push(stringifyHoley(requiredVersion)); - fn += "VersionCheck"; } if (fallbackCode) { - fn += "Fallback"; args.push(fallbackCode); } + + let fn; + + if (requiredVersion) { + if (strictVersion) { + fn = singleton ? "loadStrictSingletonVersion" : "loadStrictVersion"; + } else { + fn = singleton ? "loadSingletonVersion" : "loadVersion"; + } + } else { + fn = singleton ? "loadSingleton" : "load"; + } + const code = runtimeTemplate.returningFunction(`${fn}(${args.join(", ")})`); const sources = new Map(); sources.set("consume-shared", new RawSource(code)); @@ -224,12 +241,18 @@ class ConsumeSharedModule extends Module { }; } + /** + * @param {ObjectSerializerContext} context context + */ serialize(context) { const { write } = context; write(this.options); super.serialize(context); } + /** + * @param {ObjectDeserializerContext} context context + */ deserialize(context) { const { read } = context; this.options = read(); diff --git a/lib/sharing/ConsumeSharedPlugin.js b/lib/sharing/ConsumeSharedPlugin.js index 87215dac62a..efc5249061a 100644 --- a/lib/sharing/ConsumeSharedPlugin.js +++ b/lib/sharing/ConsumeSharedPlugin.js @@ -5,13 +5,12 @@ "use strict"; -const { validate } = require("schema-utils"); -const schema = require("../../schemas/plugins/sharing/ConsumeSharedPlugin.json"); const ModuleNotFoundError = require("../ModuleNotFoundError"); const RuntimeGlobals = require("../RuntimeGlobals"); const WebpackError = require("../WebpackError"); const { parseOptions } = require("../container/options"); const LazySet = require("../util/LazySet"); +const createSchemaValidation = require("../util/create-schema-validation"); const { parseRange } = require("../util/semver"); const ConsumeSharedFallbackDependency = require("./ConsumeSharedFallbackDependency"); const ConsumeSharedModule = require("./ConsumeSharedModule"); @@ -28,7 +27,18 @@ const { /** @typedef {import("../../declarations/plugins/sharing/ConsumeSharedPlugin").ConsumesConfig} ConsumesConfig */ /** @typedef {import("../Compiler")} Compiler */ /** @typedef {import("../ResolverFactory").ResolveOptionsWithDependencyType} ResolveOptionsWithDependencyType */ +/** @typedef {import("../util/semver").SemVerRange} SemVerRange */ /** @typedef {import("./ConsumeSharedModule").ConsumeOptions} ConsumeOptions */ +/** @typedef {import("./utils").DescriptionFile} DescriptionFile */ + +const validate = createSchemaValidation( + require("../../schemas/plugins/sharing/ConsumeSharedPlugin.check.js"), + () => require("../../schemas/plugins/sharing/ConsumeSharedPlugin.json"), + { + name: "Consume Shared Plugin", + baseDataPath: "options" + } +); /** @type {ResolveOptionsWithDependencyType} */ const RESOLVE_OPTIONS = { dependencyType: "esm" }; @@ -40,7 +50,7 @@ class ConsumeSharedPlugin { */ constructor(options) { if (typeof options !== "string") { - validate(schema, options, { name: "Consumes Shared Plugin" }); + validate(options); } /** @type {[string, ConsumeOptions][]} */ @@ -49,10 +59,10 @@ class ConsumeSharedPlugin { (item, key) => { if (Array.isArray(item)) throw new Error("Unexpected array in options"); /** @type {ConsumeOptions} */ - let result = + const result = item === key || !isRequiredVersion(item) ? // item is a request/key - { + { import: key, shareScope: options.shareScope || "default", shareKey: key, @@ -61,10 +71,10 @@ class ConsumeSharedPlugin { strictVersion: false, singleton: false, eager: false - } + } : // key is a request/key - // item is a version - { + // item is a version + { import: key, shareScope: options.shareScope || "default", shareKey: key, @@ -73,7 +83,7 @@ class ConsumeSharedPlugin { packageName: undefined, singleton: false, eager: false - }; + }; return result; }, (item, key) => ({ @@ -89,8 +99,8 @@ class ConsumeSharedPlugin { ? item.strictVersion : item.import !== false && !item.singleton, packageName: item.packageName, - singleton: !!item.singleton, - eager: !!item.eager + singleton: Boolean(item.singleton), + eager: Boolean(item.eager) }) ); } @@ -109,7 +119,12 @@ class ConsumeSharedPlugin { normalModuleFactory ); - let unresolvedConsumes, resolvedConsumes, prefixedConsumes; + /** @type {Map} */ + let unresolvedConsumes; + /** @type {Map} */ + let resolvedConsumes; + /** @type {Map} */ + let prefixedConsumes; const promise = resolveMatchedConfigs(compilation, this._consumes).then( ({ resolved, unresolved, prefixed }) => { resolvedConsumes = resolved; @@ -130,6 +145,9 @@ class ConsumeSharedPlugin { * @returns {Promise} create module */ const createConsumeSharedModule = (context, request, config) => { + /** + * @param {string} details details + */ const requiredVersionWarning = details => { const error = new WebpackError( `No required version specified and unable to automatically determine one. ${details}` @@ -141,106 +159,127 @@ class ConsumeSharedPlugin { config.import && /^(\.\.?(\/|$)|\/|[A-Za-z]:|\\\\)/.test(config.import); return Promise.all([ - new Promise(resolve => { - if (!config.import) return resolve(); - const resolveContext = { - /** @type {LazySet} */ - fileDependencies: new LazySet(), - /** @type {LazySet} */ - contextDependencies: new LazySet(), - /** @type {LazySet} */ - missingDependencies: new LazySet() - }; - resolver.resolve( - {}, - directFallback ? compiler.context : context, - config.import, - resolveContext, - (err, result) => { - compilation.contextDependencies.addAll( - resolveContext.contextDependencies - ); - compilation.fileDependencies.addAll( - resolveContext.fileDependencies - ); - compilation.missingDependencies.addAll( - resolveContext.missingDependencies - ); - if (err) { - compilation.errors.push( - new ModuleNotFoundError(null, err, { - name: `resolving fallback for shared module ${request}` - }) - ); - return resolve(); - } - resolve(result); - } - ); - }), - new Promise(resolve => { - if (config.requiredVersion !== undefined) - return resolve(config.requiredVersion); - let packageName = config.packageName; - if (packageName === undefined) { - if (/^(\/|[A-Za-z]:|\\\\)/.test(request)) { - // For relative or absolute requests we don't automatically use a packageName. - // If wished one can specify one with the packageName option. - return resolve(); - } - const match = /^((?:@[^\\/]+[\\/])?[^\\/]+)/.exec(request); - if (!match) { - requiredVersionWarning( - "Unable to extract the package name from request." - ); - return resolve(); + new Promise( + /** + * @param {(value?: string) => void} resolve resolve + */ + resolve => { + if (!config.import) { + resolve(); + return; } - packageName = match[0]; - } - - getDescriptionFile( - compilation.inputFileSystem, - context, - ["package.json"], - (err, result) => { - if (err) { - requiredVersionWarning( - `Unable to read description file: ${err}` + const resolveContext = { + /** @type {LazySet} */ + fileDependencies: new LazySet(), + /** @type {LazySet} */ + contextDependencies: new LazySet(), + /** @type {LazySet} */ + missingDependencies: new LazySet() + }; + resolver.resolve( + {}, + directFallback ? compiler.context : context, + config.import, + resolveContext, + (err, result) => { + compilation.contextDependencies.addAll( + resolveContext.contextDependencies ); - return resolve(); - } - const { data, path: descriptionPath } = result; - if (!data) { - requiredVersionWarning( - `Unable to find description file in ${context}.` + compilation.fileDependencies.addAll( + resolveContext.fileDependencies + ); + compilation.missingDependencies.addAll( + resolveContext.missingDependencies ); - return resolve(); + if (err) { + compilation.errors.push( + new ModuleNotFoundError(null, err, { + name: `resolving fallback for shared module ${request}` + }) + ); + return resolve(); + } + resolve(/** @type {string} */ (result)); } - const requiredVersion = getRequiredVersionFromDescriptionFile( - data, - packageName - ); - if (typeof requiredVersion !== "string") { + ); + } + ), + new Promise( + /** + * @param {(value?: SemVerRange) => void} resolve resolve + */ + resolve => { + if (config.requiredVersion !== undefined) { + resolve(/** @type {SemVerRange} */ (config.requiredVersion)); + return; + } + let packageName = config.packageName; + if (packageName === undefined) { + if (/^(\/|[A-Za-z]:|\\\\)/.test(request)) { + // For relative or absolute requests we don't automatically use a packageName. + // If wished one can specify one with the packageName option. + resolve(); + return; + } + const match = /^((?:@[^\\/]+[\\/])?[^\\/]+)/.exec(request); + if (!match) { requiredVersionWarning( - `Unable to find required version for "${packageName}" in description file (${descriptionPath}). It need to be in dependencies, devDependencies or peerDependencies.` + "Unable to extract the package name from request." ); - return resolve(); + resolve(); + return; } - resolve(parseRange(requiredVersion)); + packageName = match[0]; } - ); - }) - ]).then(([importResolved, requiredVersion]) => { - return new ConsumeSharedModule( - directFallback ? compiler.context : context, - { - ...config, - importResolved, - import: importResolved ? config.import : undefined, - requiredVersion + + getDescriptionFile( + compilation.inputFileSystem, + context, + ["package.json"], + (err, result) => { + if (err) { + requiredVersionWarning( + `Unable to read description file: ${err}` + ); + return resolve(); + } + const { data, path: descriptionPath } = + /** @type {DescriptionFile} */ (result); + if (!data) { + requiredVersionWarning( + `Unable to find description file in ${context}.` + ); + return resolve(); + } + if (data.name === packageName) { + // Package self-referencing + return resolve(); + } + const requiredVersion = + getRequiredVersionFromDescriptionFile(data, packageName); + if (typeof requiredVersion !== "string") { + requiredVersionWarning( + `Unable to find required version for "${packageName}" in description file (${descriptionPath}). It need to be in dependencies, devDependencies or peerDependencies.` + ); + return resolve(); + } + resolve(parseRange(requiredVersion)); + } + ); } - ); - }); + ) + ]).then( + ([importResolved, requiredVersion]) => + new ConsumeSharedModule( + directFallback ? compiler.context : context, + { + ...config, + importResolved, + import: importResolved ? config.import : undefined, + requiredVersion + } + ) + ); }; normalModuleFactory.hooks.factorize.tapPromise( @@ -281,9 +320,15 @@ class ConsumeSharedPlugin { ) { return Promise.resolve(); } - const options = resolvedConsumes.get(resource); + const options = resolvedConsumes.get( + /** @type {string} */ (resource) + ); if (options !== undefined) { - return createConsumeSharedModule(context, resource, options); + return createConsumeSharedModule( + context, + /** @type {string} */ (resource), + options + ); } return Promise.resolve(); } diff --git a/lib/sharing/ConsumeSharedRuntimeModule.js b/lib/sharing/ConsumeSharedRuntimeModule.js index 3dbf4f3f3e4..7dc3209b50f 100644 --- a/lib/sharing/ConsumeSharedRuntimeModule.js +++ b/lib/sharing/ConsumeSharedRuntimeModule.js @@ -17,38 +17,45 @@ const { /** @typedef {import("webpack-sources").Source} Source */ /** @typedef {import("../Chunk")} Chunk */ +/** @typedef {import("../Chunk").ChunkId} ChunkId */ +/** @typedef {import("../ChunkGraph")} ChunkGraph */ +/** @typedef {import("../ChunkGraph").ModuleId} ModuleId */ +/** @typedef {import("../Compilation")} Compilation */ /** @typedef {import("../Module")} Module */ +/** @typedef {import("../Module").ReadOnlyRuntimeRequirements} ReadOnlyRuntimeRequirements */ /** @typedef {import("./ConsumeSharedModule")} ConsumeSharedModule */ class ConsumeSharedRuntimeModule extends RuntimeModule { + /** + * @param {ReadOnlyRuntimeRequirements} runtimeRequirements runtime requirements + */ constructor(runtimeRequirements) { super("consumes", RuntimeModule.STAGE_ATTACH); this._runtimeRequirements = runtimeRequirements; } /** - * @returns {string} runtime code + * @returns {string | null} runtime code */ generate() { - const { - runtimeTemplate, - chunkGraph, - codeGenerationResults - } = this.compilation; + const compilation = /** @type {Compilation} */ (this.compilation); + const chunkGraph = /** @type {ChunkGraph} */ (this.chunkGraph); + const { runtimeTemplate, codeGenerationResults } = compilation; + /** @type {Record} */ const chunkToModuleMapping = {}; /** @type {Map} */ const moduleIdToSourceMapping = new Map(); + /** @type {(string | number)[]} */ const initialConsumes = []; /** - * * @param {Iterable} modules modules * @param {Chunk} chunk the chunk * @param {(string | number)[]} list list of ids */ const addModules = (modules, chunk, list) => { for (const m of modules) { - const module = /** @type {ConsumeSharedModule} */ (m); - const id = chunkGraph.getModuleId(module); + const module = m; + const id = /** @type {ModuleId} */ (chunkGraph.getModuleId(module)); list.push(id); moduleIdToSourceMapping.set( id, @@ -60,15 +67,21 @@ class ConsumeSharedRuntimeModule extends RuntimeModule { ); } }; - for (const chunk of this.chunk.getAllAsyncChunks()) { + for (const chunk of /** @type {Chunk} */ (this.chunk).getAllAsyncChunks()) { const modules = chunkGraph.getChunkModulesIterableBySourceType( chunk, "consume-shared" ); if (!modules) continue; - addModules(modules, chunk, (chunkToModuleMapping[chunk.id] = [])); + addModules( + modules, + chunk, + (chunkToModuleMapping[/** @type {ChunkId} */ (chunk.id)] = []) + ); } - for (const chunk of this.chunk.getAllInitialChunks()) { + for (const chunk of /** @type {Chunk} */ ( + this.chunk + ).getAllInitialChunks()) { const modules = chunkGraph.getChunkModulesIterableBySourceType( chunk, "consume-shared" @@ -82,57 +95,39 @@ class ConsumeSharedRuntimeModule extends RuntimeModule { versionLtRuntimeCode(runtimeTemplate), rangeToStringRuntimeCode(runtimeTemplate), satisfyRuntimeCode(runtimeTemplate), - `var ensureExistence = ${runtimeTemplate.basicFunction("scopeName, key", [ - `var scope = ${RuntimeGlobals.shareScopeMap}[scopeName];`, - `if(!scope || !${RuntimeGlobals.hasOwnProperty}(scope, key)) throw new Error("Shared module " + key + " doesn't exist in shared scope " + scopeName);`, - "return scope;" + `var exists = ${runtimeTemplate.basicFunction("scope, key", [ + `return scope && ${RuntimeGlobals.hasOwnProperty}(scope, key);` + ])}`, + `var get = ${runtimeTemplate.basicFunction("entry", [ + "entry.loaded = 1;", + "return entry.get()" ])};`, - `var findVersion = ${runtimeTemplate.basicFunction("scope, key", [ - "var versions = scope[key];", - `var key = Object.keys(versions).reduce(${runtimeTemplate.basicFunction( - "a, b", - ["return !a || versionLt(a, b) ? b : a;"] - )}, 0);`, - "return key && versions[key]" + `var eagerOnly = ${runtimeTemplate.basicFunction("versions", [ + `return Object.keys(versions).reduce(${runtimeTemplate.basicFunction( + "filtered, version", + Template.indent([ + "if (versions[version].eager) {", + Template.indent(["filtered[version] = versions[version];"]), + "}", + "return filtered;" + ]) + )}, {});` ])};`, - `var findSingletonVersionKey = ${runtimeTemplate.basicFunction( - "scope, key", + `var findLatestVersion = ${runtimeTemplate.basicFunction( + "scope, key, eager", [ - "var versions = scope[key];", - `return Object.keys(versions).reduce(${runtimeTemplate.basicFunction( + "var versions = eager ? eagerOnly(scope[key]) : scope[key];", + `var key = Object.keys(versions).reduce(${runtimeTemplate.basicFunction( "a, b", - ["return !a || (!versions[a].loaded && versionLt(a, b)) ? b : a;"] - )}, 0);` - ] - )};`, - `var getInvalidSingletonVersionMessage = ${runtimeTemplate.basicFunction( - "key, version, requiredVersion", - [ - `return "Unsatisfied version " + version + " of shared singleton module " + key + " (required " + rangeToString(requiredVersion) + ")"` - ] - )};`, - `var getSingletonVersion = ${runtimeTemplate.basicFunction( - "scope, scopeName, key, requiredVersion", - [ - "var version = findSingletonVersionKey(scope, key);", - "if (!satisfy(requiredVersion, version)) " + - 'typeof console !== "undefined" && console.warn && console.warn(getInvalidSingletonVersionMessage(key, version, requiredVersion));', - "return get(scope[key][version]);" - ] - )};`, - `var getStrictSingletonVersion = ${runtimeTemplate.basicFunction( - "scope, scopeName, key, requiredVersion", - [ - "var version = findSingletonVersionKey(scope, key);", - "if (!satisfy(requiredVersion, version)) " + - "throw new Error(getInvalidSingletonVersionMessage(key, version, requiredVersion));", - "return get(scope[key][version]);" + ["return !a || versionLt(a, b) ? b : a;"] + )}, 0);`, + "return key && versions[key];" ] )};`, - `var findValidVersion = ${runtimeTemplate.basicFunction( - "scope, key, requiredVersion", + `var findSatisfyingVersion = ${runtimeTemplate.basicFunction( + "scope, key, requiredVersion, eager", [ - "var versions = scope[key];", + "var versions = eager ? eagerOnly(scope[key]) : scope[key];", `var key = Object.keys(versions).reduce(${runtimeTemplate.basicFunction( "a, b", [ @@ -143,115 +138,127 @@ class ConsumeSharedRuntimeModule extends RuntimeModule { "return key && versions[key]" ] )};`, - `var getInvalidVersionMessage = ${runtimeTemplate.basicFunction( - "scope, scopeName, key, requiredVersion", + `var findSingletonVersionKey = ${runtimeTemplate.basicFunction( + "scope, key, eager", [ - "var versions = scope[key];", - 'return "No satisfying version (" + rangeToString(requiredVersion) + ") of shared module " + key + " found in shared scope " + scopeName + ".\\n" +', - `\t"Available versions: " + Object.keys(versions).map(${runtimeTemplate.basicFunction( - "key", - ['return key + " from " + versions[key].from;'] - )}).join(", ");` + "var versions = eager ? eagerOnly(scope[key]) : scope[key];", + `return Object.keys(versions).reduce(${runtimeTemplate.basicFunction( + "a, b", + ["return !a || (!versions[a].loaded && versionLt(a, b)) ? b : a;"] + )}, 0);` ] )};`, - `var getValidVersion = ${runtimeTemplate.basicFunction( - "scope, scopeName, key, requiredVersion", + `var getInvalidSingletonVersionMessage = ${runtimeTemplate.basicFunction( + "scope, key, version, requiredVersion", [ - "var entry = findValidVersion(scope, key, requiredVersion);", - "if(entry) return get(entry);", - "throw new Error(getInvalidVersionMessage(scope, scopeName, key, requiredVersion));" + 'return "Unsatisfied version " + version + " from " + (version && scope[key][version].from) + " of shared singleton module " + key + " (required " + rangeToString(requiredVersion) + ")"' ] )};`, - `var warnInvalidVersion = ${runtimeTemplate.basicFunction( - "scope, scopeName, key, requiredVersion", + `var getInvalidVersionMessage = ${runtimeTemplate.basicFunction( + "scope, scopeName, key, requiredVersion, eager", [ - 'typeof console !== "undefined" && console.warn && console.warn(getInvalidVersionMessage(scope, scopeName, key, requiredVersion));' + "var versions = scope[key];", + 'return "No satisfying version (" + rangeToString(requiredVersion) + ")" + (eager ? " for eager consumption" : "") + " of shared module " + key + " found in shared scope " + scopeName + ".\\n" +', + `\t"Available versions: " + Object.keys(versions).map(${runtimeTemplate.basicFunction( + "key", + ['return key + " from " + versions[key].from;'] + )}).join(", ");` ] )};`, - `var get = ${runtimeTemplate.basicFunction("entry", [ - "entry.loaded = 1;", - "return entry.get()" - ])};`, + `var fail = ${runtimeTemplate.basicFunction("msg", [ + "throw new Error(msg);" + ])}`, + `var failAsNotExist = ${runtimeTemplate.basicFunction("scopeName, key", [ + 'return fail("Shared module " + key + " doesn\'t exist in shared scope " + scopeName);' + ])}`, + `var warn = /*#__PURE__*/ ${ + compilation.outputOptions.ignoreBrowserWarnings + ? runtimeTemplate.basicFunction("", "") + : runtimeTemplate.basicFunction("msg", [ + 'if (typeof console !== "undefined" && console.warn) console.warn(msg);' + ]) + };`, `var init = ${runtimeTemplate.returningFunction( Template.asString([ - "function(scopeName, a, b, c) {", + "function(scopeName, key, eager, c, d) {", Template.indent([ `var promise = ${RuntimeGlobals.initializeSharing}(scopeName);`, - `if (promise && promise.then) return promise.then(fn.bind(fn, scopeName, ${RuntimeGlobals.shareScopeMap}[scopeName], a, b, c));`, - `return fn(scopeName, ${RuntimeGlobals.shareScopeMap}[scopeName], a, b, c);` + // if we require eager shared, we expect it to be already loaded before it requested, no need to wait the whole scope loaded. + "if (promise && promise.then && !eager) { ", + Template.indent([ + `return promise.then(fn.bind(fn, scopeName, ${RuntimeGlobals.shareScopeMap}[scopeName], key, false, c, d));` + ]), + "}", + `return fn(scopeName, ${RuntimeGlobals.shareScopeMap}[scopeName], key, eager, c, d);` ]), "}" ]), "fn" )};`, "", + `var useFallback = ${runtimeTemplate.basicFunction( + "scopeName, key, fallback", + ["return fallback ? fallback() : failAsNotExist(scopeName, key);"] + )}`, `var load = /*#__PURE__*/ init(${runtimeTemplate.basicFunction( - "scopeName, scope, key", - [ - "ensureExistence(scopeName, key);", - "return get(findVersion(scope, key));" - ] - )});`, - `var loadFallback = /*#__PURE__*/ init(${runtimeTemplate.basicFunction( - "scopeName, scope, key, fallback", + "scopeName, scope, key, eager, fallback", [ - `return scope && ${RuntimeGlobals.hasOwnProperty}(scope, key) ? get(findVersion(scope, key)) : fallback();` + "if (!exists(scope, key)) return useFallback(scopeName, key, fallback);", + "return get(findLatestVersion(scope, key, eager));" ] )});`, - `var loadVersionCheck = /*#__PURE__*/ init(${runtimeTemplate.basicFunction( - "scopeName, scope, key, version", + `var loadVersion = /*#__PURE__*/ init(${runtimeTemplate.basicFunction( + "scopeName, scope, key, eager, requiredVersion, fallback", [ - "ensureExistence(scopeName, key);", - "return get(findValidVersion(scope, key, version) || warnInvalidVersion(scope, scopeName, key, version) || findVersion(scope, key));" + "if (!exists(scope, key)) return useFallback(scopeName, key, fallback);", + "var satisfyingVersion = findSatisfyingVersion(scope, key, requiredVersion, eager);", + "if (satisfyingVersion) return get(satisfyingVersion);", + "warn(getInvalidVersionMessage(scope, scopeName, key, requiredVersion, eager))", + "return get(findLatestVersion(scope, key, eager));" ] )});`, - `var loadSingletonVersionCheck = /*#__PURE__*/ init(${runtimeTemplate.basicFunction( - "scopeName, scope, key, version", + `var loadStrictVersion = /*#__PURE__*/ init(${runtimeTemplate.basicFunction( + "scopeName, scope, key, eager, requiredVersion, fallback", [ - "ensureExistence(scopeName, key);", - "return getSingletonVersion(scope, scopeName, key, version);" + "if (!exists(scope, key)) return useFallback(scopeName, key, fallback);", + "var satisfyingVersion = findSatisfyingVersion(scope, key, requiredVersion, eager);", + "if (satisfyingVersion) return get(satisfyingVersion);", + "if (fallback) return fallback();", + "fail(getInvalidVersionMessage(scope, scopeName, key, requiredVersion, eager));" ] )});`, - `var loadStrictVersionCheck = /*#__PURE__*/ init(${runtimeTemplate.basicFunction( - "scopeName, scope, key, version", + `var loadSingleton = /*#__PURE__*/ init(${runtimeTemplate.basicFunction( + "scopeName, scope, key, eager, fallback", [ - "ensureExistence(scopeName, key);", - "return getValidVersion(scope, scopeName, key, version);" - ] - )});`, - `var loadStrictSingletonVersionCheck = /*#__PURE__*/ init(${runtimeTemplate.basicFunction( - "scopeName, scope, key, version", - [ - "ensureExistence(scopeName, key);", - "return getStrictSingletonVersion(scope, scopeName, key, version);" - ] - )});`, - `var loadVersionCheckFallback = /*#__PURE__*/ init(${runtimeTemplate.basicFunction( - "scopeName, scope, key, version, fallback", - [ - `if(!scope || !${RuntimeGlobals.hasOwnProperty}(scope, key)) return fallback();`, - "return get(findValidVersion(scope, key, version) || warnInvalidVersion(scope, scopeName, key, version) || findVersion(scope, key));" - ] - )});`, - `var loadSingletonVersionCheckFallback = /*#__PURE__*/ init(${runtimeTemplate.basicFunction( - "scopeName, scope, key, version, fallback", - [ - `if(!scope || !${RuntimeGlobals.hasOwnProperty}(scope, key)) return fallback();`, - "return getSingletonVersion(scope, scopeName, key, version);" + "if (!exists(scope, key)) return useFallback(scopeName, key, fallback);", + "var version = findSingletonVersionKey(scope, key, eager);", + "return get(scope[key][version]);" ] )});`, - `var loadStrictVersionCheckFallback = /*#__PURE__*/ init(${runtimeTemplate.basicFunction( - "scopeName, scope, key, version, fallback", + `var loadSingletonVersion = /*#__PURE__*/ init(${runtimeTemplate.basicFunction( + "scopeName, scope, key, eager, requiredVersion, fallback", [ - `var entry = scope && ${RuntimeGlobals.hasOwnProperty}(scope, key) && findValidVersion(scope, key, version);`, - `return entry ? get(entry) : fallback();` + "if (!exists(scope, key)) return useFallback(scopeName, key, fallback);", + "var version = findSingletonVersionKey(scope, key, eager);", + "if (!satisfy(requiredVersion, version)) {", + Template.indent([ + "warn(getInvalidSingletonVersionMessage(scope, key, version, requiredVersion));" + ]), + "}", + "return get(scope[key][version]);" ] )});`, - `var loadStrictSingletonVersionCheckFallback = /*#__PURE__*/ init(${runtimeTemplate.basicFunction( - "scopeName, scope, key, version, fallback", + `var loadStrictSingletonVersion = /*#__PURE__*/ init(${runtimeTemplate.basicFunction( + "scopeName, scope, key, eager, requiredVersion, fallback", [ - `if(!scope || !${RuntimeGlobals.hasOwnProperty}(scope, key)) return fallback();`, - "return getStrictSingletonVersion(scope, scopeName, key, version);" + "if (!exists(scope, key)) return useFallback(scopeName, key, fallback);", + "var version = findSingletonVersionKey(scope, key, eager);", + "if (!satisfy(requiredVersion, version)) {", + Template.indent([ + "fail(getInvalidSingletonVersionMessage(scope, key, version, requiredVersion));" + ]), + "}", + "return get(scope[key][version]);" ] )});`, "var installedModules = {};", @@ -276,10 +283,10 @@ class ConsumeSharedRuntimeModule extends RuntimeModule { `delete ${RuntimeGlobals.moduleCache}[id];`, "var factory = moduleToHandlerMapping[id]();", 'if(typeof factory !== "function") throw new Error("Shared module is not available for eager consumption: " + id);', - `module.exports = factory();` + "module.exports = factory();" ])}` ])});` - ]) + ]) : "// no consumes in initial chunks", this._runtimeRequirements.has(RuntimeGlobals.ensureChunkHandlers) ? Template.asString([ @@ -288,6 +295,7 @@ class ConsumeSharedRuntimeModule extends RuntimeModule { null, "\t" )};`, + "var startedInstallModules = {};", `${ RuntimeGlobals.ensureChunkHandlers }.consumes = ${runtimeTemplate.basicFunction("chunkId, promises", [ @@ -297,6 +305,7 @@ class ConsumeSharedRuntimeModule extends RuntimeModule { "id", [ `if(${RuntimeGlobals.hasOwnProperty}(installedModules, id)) return promises.push(installedModules[id]);`, + "if(!startedInstallModules[id]) {", `var onFactory = ${runtimeTemplate.basicFunction( "factory", [ @@ -309,6 +318,7 @@ class ConsumeSharedRuntimeModule extends RuntimeModule { ])}` ] )};`, + "startedInstallModules[id] = true;", `var onError = ${runtimeTemplate.basicFunction("error", [ "delete installedModules[id];", `${ @@ -323,17 +333,18 @@ class ConsumeSharedRuntimeModule extends RuntimeModule { "var promise = moduleToHandlerMapping[id]();", "if(promise.then) {", Template.indent( - `promises.push(installedModules[id] = promise.then(onFactory).catch(onError));` + "promises.push(installedModules[id] = promise.then(onFactory)['catch'](onError));" ), "} else onFactory(promise);" ]), - "} catch(e) { onError(e); }" + "} catch(e) { onError(e); }", + "}" ] )});` ]), "}" ])}` - ]) + ]) : "// no chunk loading of consumes" ]); } diff --git a/lib/sharing/ProvideForSharedDependency.js b/lib/sharing/ProvideForSharedDependency.js index 5177f613c21..4de679a6a74 100644 --- a/lib/sharing/ProvideForSharedDependency.js +++ b/lib/sharing/ProvideForSharedDependency.js @@ -10,7 +10,6 @@ const makeSerializable = require("../util/makeSerializable"); class ProvideForSharedDependency extends ModuleDependency { /** - * * @param {string} request request string */ constructor(request) { diff --git a/lib/sharing/ProvideSharedDependency.js b/lib/sharing/ProvideSharedDependency.js index fa243511067..2df18a618ed 100644 --- a/lib/sharing/ProvideSharedDependency.js +++ b/lib/sharing/ProvideSharedDependency.js @@ -8,7 +8,17 @@ const Dependency = require("../Dependency"); const makeSerializable = require("../util/makeSerializable"); +/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */ + class ProvideSharedDependency extends Dependency { + /** + * @param {string} shareScope share scope + * @param {string} name module name + * @param {string | false} version version + * @param {string} request request + * @param {boolean} eager true, if this is an eager dependency + */ constructor(shareScope, name, version, request, eager) { super(); this.shareScope = shareScope; @@ -31,6 +41,9 @@ class ProvideSharedDependency extends Dependency { } @ ${this.version}${this.eager ? " (eager)" : ""}`; } + /** + * @param {ObjectSerializerContext} context context + */ serialize(context) { context.write(this.shareScope); context.write(this.name); @@ -40,6 +53,10 @@ class ProvideSharedDependency extends Dependency { super.serialize(context); } + /** + * @param {ObjectDeserializerContext} context context + * @returns {ProvideSharedDependency} deserialize fallback dependency + */ static deserialize(context) { const { read } = context; const obj = new ProvideSharedDependency( diff --git a/lib/sharing/ProvideSharedModule.js b/lib/sharing/ProvideSharedModule.js index bbb71ce39e9..22848391eb2 100644 --- a/lib/sharing/ProvideSharedModule.js +++ b/lib/sharing/ProvideSharedModule.js @@ -7,6 +7,7 @@ const AsyncDependenciesBlock = require("../AsyncDependenciesBlock"); const Module = require("../Module"); +const { WEBPACK_MODULE_TYPE_PROVIDE } = require("../ModuleTypeConstants"); const RuntimeGlobals = require("../RuntimeGlobals"); const makeSerializable = require("../util/makeSerializable"); const ProvideForSharedDependency = require("./ProvideForSharedDependency"); @@ -20,9 +21,12 @@ const ProvideForSharedDependency = require("./ProvideForSharedDependency"); /** @typedef {import("../Module").CodeGenerationResult} CodeGenerationResult */ /** @typedef {import("../Module").LibIdentOptions} LibIdentOptions */ /** @typedef {import("../Module").NeedBuildContext} NeedBuildContext */ +/** @typedef {import("../Module").SourceTypes} SourceTypes */ /** @typedef {import("../RequestShortener")} RequestShortener */ /** @typedef {import("../ResolverFactory").ResolverWithOptions} ResolverWithOptions */ /** @typedef {import("../WebpackError")} WebpackError */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */ /** @typedef {import("../util/Hash")} Hash */ /** @typedef {import("../util/fs").InputFileSystem} InputFileSystem */ @@ -37,7 +41,7 @@ class ProvideSharedModule extends Module { * @param {boolean} eager include the module in sync way */ constructor(shareScope, name, version, request, eager) { - super("provide-module"); + super(WEBPACK_MODULE_TYPE_PROVIDE); this._shareScope = shareScope; this._name = name; this._version = version; @@ -67,12 +71,14 @@ class ProvideSharedModule extends Module { * @returns {string | null} an identifier for library inclusion */ libIdent(options) { - return `webpack/sharing/provide/${this._shareScope}/${this._name}`; + return `${this.layer ? `(${this.layer})/` : ""}webpack/sharing/provide/${ + this._shareScope + }/${this._name}`; } /** * @param {NeedBuildContext} context context info - * @param {function(WebpackError=, boolean=): void} callback callback function, returns true, if the module needs a rebuild + * @param {function((WebpackError | null)=, boolean=): void} callback callback function, returns true, if the module needs a rebuild * @returns {void} */ needBuild(context, callback) { @@ -115,7 +121,7 @@ class ProvideSharedModule extends Module { } /** - * @returns {Set} types available (do not mutate) + * @returns {SourceTypes} types available (do not mutate) */ getSourceTypes() { return TYPES; @@ -136,13 +142,13 @@ class ProvideSharedModule extends Module { chunkGraph, request: this._request, runtimeRequirements - }) + }) : runtimeTemplate.asyncModuleFactory({ block: this.blocks[0], chunkGraph, request: this._request, runtimeRequirements - }) + }) }${this._eager ? ", 1" : ""});`; const sources = new Map(); const data = new Map(); @@ -156,6 +162,9 @@ class ProvideSharedModule extends Module { return { sources, data, runtimeRequirements }; } + /** + * @param {ObjectSerializerContext} context context + */ serialize(context) { const { write } = context; write(this._shareScope); @@ -166,6 +175,10 @@ class ProvideSharedModule extends Module { super.serialize(context); } + /** + * @param {ObjectDeserializerContext} context context + * @returns {ProvideSharedModule} deserialize fallback dependency + */ static deserialize(context) { const { read } = context; const obj = new ProvideSharedModule(read(), read(), read(), read(), read()); diff --git a/lib/sharing/ProvideSharedModuleFactory.js b/lib/sharing/ProvideSharedModuleFactory.js index 2b3b19f8ff7..d5bcc829f99 100644 --- a/lib/sharing/ProvideSharedModuleFactory.js +++ b/lib/sharing/ProvideSharedModuleFactory.js @@ -15,7 +15,7 @@ const ProvideSharedModule = require("./ProvideSharedModule"); class ProvideSharedModuleFactory extends ModuleFactory { /** * @param {ModuleFactoryCreateData} data data object - * @param {function(Error=, ModuleFactoryResult=): void} callback callback + * @param {function((Error | null)=, ModuleFactoryResult=): void} callback callback * @returns {void} */ create(data, callback) { diff --git a/lib/sharing/ProvideSharedPlugin.js b/lib/sharing/ProvideSharedPlugin.js index 9030f6bcaf7..c57b76324ab 100644 --- a/lib/sharing/ProvideSharedPlugin.js +++ b/lib/sharing/ProvideSharedPlugin.js @@ -5,10 +5,9 @@ "use strict"; -const { validate } = require("schema-utils"); -const schema = require("../../schemas/plugins/sharing/ProvideSharedPlugin.json"); const WebpackError = require("../WebpackError"); const { parseOptions } = require("../container/options"); +const createSchemaValidation = require("../util/create-schema-validation"); const ProvideForSharedDependency = require("./ProvideForSharedDependency"); const ProvideSharedDependency = require("./ProvideSharedDependency"); const ProvideSharedModuleFactory = require("./ProvideSharedModuleFactory"); @@ -16,9 +15,19 @@ const ProvideSharedModuleFactory = require("./ProvideSharedModuleFactory"); /** @typedef {import("../../declarations/plugins/sharing/ProvideSharedPlugin").ProvideSharedPluginOptions} ProvideSharedPluginOptions */ /** @typedef {import("../Compilation")} Compilation */ /** @typedef {import("../Compiler")} Compiler */ +/** @typedef {import("../NormalModuleFactory").NormalModuleCreateData} NormalModuleCreateData */ + +const validate = createSchemaValidation( + require("../../schemas/plugins/sharing/ProvideSharedPlugin.check.js"), + () => require("../../schemas/plugins/sharing/ProvideSharedPlugin.json"), + { + name: "Provide Shared Plugin", + baseDataPath: "options" + } +); /** - * @typedef {Object} ProvideOptions + * @typedef {object} ProvideOptions * @property {string} shareKey * @property {string} shareScope * @property {string | undefined | false} version @@ -32,29 +41,30 @@ class ProvideSharedPlugin { * @param {ProvideSharedPluginOptions} options options */ constructor(options) { - validate(schema, options, { name: "Provide Shared Plugin" }); + validate(options); - /** @type {[string, ProvideOptions][]} */ - this._provides = parseOptions( - options.provides, - item => { - if (Array.isArray(item)) - throw new Error("Unexpected array of provides"); - /** @type {ProvideOptions} */ - const result = { - shareKey: item, - version: undefined, - shareScope: options.shareScope || "default", - eager: false - }; - return result; - }, - item => ({ - shareKey: item.shareKey, - version: item.version, - shareScope: item.shareScope || options.shareScope || "default", - eager: !!item.eager - }) + this._provides = /** @type {[string, ProvideOptions][]} */ ( + parseOptions( + options.provides, + item => { + if (Array.isArray(item)) + throw new Error("Unexpected array of provides"); + /** @type {ProvideOptions} */ + const result = { + shareKey: item, + version: undefined, + shareScope: options.shareScope || "default", + eager: false + }; + return result; + }, + item => ({ + shareKey: item.shareKey, + version: item.version, + shareScope: item.shareScope || options.shareScope || "default", + eager: Boolean(item.eager) + }) + ) ); this._provides.sort(([a], [b]) => { if (a < b) return -1; @@ -103,6 +113,12 @@ class ProvideSharedPlugin { } } compilationData.set(compilation, resolvedProvideMap); + /** + * @param {string} key key + * @param {ProvideOptions} config config + * @param {NormalModuleCreateData["resource"]} resource resource + * @param {NormalModuleCreateData["resourceResolveData"]} resourceResolveData resource resolve data + */ const provideSharedModule = ( key, config, @@ -113,7 +129,7 @@ class ProvideSharedPlugin { if (version === undefined) { let details = ""; if (!resourceResolveData) { - details = `No resolve data provided from resolver.`; + details = "No resolve data provided from resolver."; } else { const descriptionFileData = resourceResolveData.descriptionFileData; @@ -121,8 +137,7 @@ class ProvideSharedPlugin { details = "No description file (usually package.json) found. Add description file with name and version, or manually specify version in shared config."; } else if (!descriptionFileData.version) { - details = - "No version in description file (usually package.json). Add version to description file, or manually specify version in shared config."; + details = `No version in description file (usually package.json). Add version to description file ${resourceResolveData.descriptionFilePath}, or manually specify version in shared config.`; } else { version = descriptionFileData.version; } @@ -143,7 +158,7 @@ class ProvideSharedPlugin { normalModuleFactory.hooks.module.tap( "ProvideSharedPlugin", (module, { resource, resourceResolveData }, resolveData) => { - if (resolvedProvideMap.has(resource)) { + if (resolvedProvideMap.has(/** @type {string} */ (resource))) { return module; } const { request } = resolveData; @@ -153,7 +168,7 @@ class ProvideSharedPlugin { provideSharedModule( request, config, - resource, + /** @type {string} */ (resource), resourceResolveData ); resolveData.cacheable = false; @@ -163,12 +178,12 @@ class ProvideSharedPlugin { if (request.startsWith(prefix)) { const remainder = request.slice(prefix.length); provideSharedModule( - resource, + /** @type {string} */ (resource), { ...config, shareKey: config.shareKey + remainder }, - resource, + /** @type {string} */ (resource), resourceResolveData ); resolveData.cacheable = false; @@ -201,7 +216,7 @@ class ProvideSharedPlugin { }, err => { if (err) return reject(err); - resolve(); + resolve(null); } ); }) diff --git a/lib/sharing/SharePlugin.js b/lib/sharing/SharePlugin.js index ccbd9bbdde5..65935b30b99 100644 --- a/lib/sharing/SharePlugin.js +++ b/lib/sharing/SharePlugin.js @@ -34,11 +34,11 @@ class SharePlugin { item === key || !isRequiredVersion(item) ? { import: item - } + } : { import: key, requiredVersion: item - }; + }; return config; }, item => item diff --git a/lib/sharing/ShareRuntimeModule.js b/lib/sharing/ShareRuntimeModule.js index d5a36b5d338..0f63ef68d7d 100644 --- a/lib/sharing/ShareRuntimeModule.js +++ b/lib/sharing/ShareRuntimeModule.js @@ -13,24 +13,31 @@ const { compareStrings } = require("../util/comparators"); +/** @typedef {import("../Chunk")} Chunk */ +/** @typedef {import("../ChunkGraph")} ChunkGraph */ +/** @typedef {import("../Compilation")} Compilation */ + class ShareRuntimeModule extends RuntimeModule { constructor() { super("sharing"); } /** - * @returns {string} runtime code + * @returns {string | null} runtime code */ generate() { + const compilation = /** @type {Compilation} */ (this.compilation); const { runtimeTemplate, - chunkGraph, codeGenerationResults, - outputOptions: { uniqueName } - } = this.compilation; + outputOptions: { uniqueName, ignoreBrowserWarnings } + } = compilation; + const chunkGraph = /** @type {ChunkGraph} */ (this.chunkGraph); /** @type {Map>>} */ const initCodePerScope = new Map(); - for (const chunk of this.chunk.getAllReferencedChunks()) { + for (const chunk of /** @type {Chunk} */ ( + this.chunk + ).getAllReferencedChunks()) { const modules = chunkGraph.getOrderedChunkModulesIterableBySourceType( chunk, "share-init", @@ -77,10 +84,13 @@ class ShareRuntimeModule extends RuntimeModule { `if(!${RuntimeGlobals.hasOwnProperty}(${RuntimeGlobals.shareScopeMap}, name)) ${RuntimeGlobals.shareScopeMap}[name] = {};`, "// runs all init snippets from all modules reachable", `var scope = ${RuntimeGlobals.shareScopeMap}[name];`, - `var warn = ${runtimeTemplate.returningFunction( - 'typeof console !== "undefined" && console.warn && console.warn(msg)', - "msg" - )};`, + `var warn = ${ + ignoreBrowserWarnings + ? runtimeTemplate.basicFunction("", "") + : runtimeTemplate.basicFunction("msg", [ + 'if (typeof console !== "undefined" && console.warn) console.warn(msg);' + ]) + };`, `var uniqueName = ${JSON.stringify(uniqueName || undefined)};`, `var register = ${runtimeTemplate.basicFunction( "name, version, factory, eager", @@ -97,7 +107,7 @@ class ShareRuntimeModule extends RuntimeModule { )};`, "try {", Template.indent([ - "var module = __webpack_require__(id);", + `var module = ${RuntimeGlobals.require}(id);`, "if(!module) return;", `var initFn = ${runtimeTemplate.returningFunction( `module && module.init && module.init(${RuntimeGlobals.shareScopeMap}[name], initScope)`, @@ -105,7 +115,7 @@ class ShareRuntimeModule extends RuntimeModule { )}`, "if(module.then) return promises.push(module.then(initFn, handleError));", "var initResult = initFn(module);", - "if(initResult && initResult.then) return promises.push(initResult.catch(handleError));" + "if(initResult && initResult.then) return promises.push(initResult['catch'](handleError));" ]), "} catch(err) { handleError(err); }" ])}`, diff --git a/lib/sharing/resolveMatchedConfigs.js b/lib/sharing/resolveMatchedConfigs.js index 69f1d9633af..a54a76abb41 100644 --- a/lib/sharing/resolveMatchedConfigs.js +++ b/lib/sharing/resolveMatchedConfigs.js @@ -13,7 +13,7 @@ const LazySet = require("../util/LazySet"); /** * @template T - * @typedef {Object} MatchedConfigs + * @typedef {object} MatchedConfigs * @property {Map} resolved * @property {Map} unresolved * @property {Map} prefixed @@ -28,7 +28,7 @@ const RESOLVE_OPTIONS = { dependencyType: "esm" }; * @param {[string, T][]} configs to be processed configs * @returns {Promise>} resolved matchers */ -exports.resolveMatchedConfigs = (compilation, configs) => { +module.exports.resolveMatchedConfigs = (compilation, configs) => { /** @type {Map} */ const resolved = new Map(); /** @type {Map} */ @@ -47,6 +47,7 @@ exports.resolveMatchedConfigs = (compilation, configs) => { const context = compilation.compiler.context; return Promise.all( + // eslint-disable-next-line array-callback-return configs.map(([request, config]) => { if (/^\.\.?(\/|$)/.test(request)) { // relative request @@ -64,10 +65,10 @@ exports.resolveMatchedConfigs = (compilation, configs) => { name: `shared module ${request}` }) ); - return resolve(); + return resolve(null); } - resolved.set(result, config); - resolve(); + resolved.set(/** @type {string} */ (result), config); + resolve(null); } ); }); diff --git a/lib/sharing/utils.js b/lib/sharing/utils.js index 6f89da05385..29aa4d6ef1f 100644 --- a/lib/sharing/utils.js +++ b/lib/sharing/utils.js @@ -8,21 +8,325 @@ const { join, dirname, readJson } = require("../util/fs"); /** @typedef {import("../util/fs").InputFileSystem} InputFileSystem */ +/** @typedef {import("../util/fs").JsonObject} JsonObject */ +/** @typedef {import("../util/fs").JsonPrimitive} JsonPrimitive */ + +// Extreme shorthand only for github. eg: foo/bar +const RE_URL_GITHUB_EXTREME_SHORT = /^[^/@:.\s][^/@:\s]*\/[^@:\s]*[^/@:\s]#\S+/; + +// Short url with specific protocol. eg: github:foo/bar +const RE_GIT_URL_SHORT = /^(github|gitlab|bitbucket|gist):\/?[^/.]+\/?/i; + +// Currently supported protocols +const RE_PROTOCOL = + /^((git\+)?(ssh|https?|file)|git|github|gitlab|bitbucket|gist):$/i; + +// Has custom protocol +const RE_CUSTOM_PROTOCOL = /^((git\+)?(ssh|https?|file)|git):\/\//i; + +// Valid hash format for npm / yarn ... +const RE_URL_HASH_VERSION = /#(?:semver:)?(.+)/; + +// Simple hostname validate +const RE_HOSTNAME = /^(?:[^/.]+(\.[^/]+)+|localhost)$/; + +// For hostname with colon. eg: ssh://user@github.com:foo/bar +const RE_HOSTNAME_WITH_COLON = + /([^/@#:.]+(?:\.[^/@#:.]+)+|localhost):([^#/0-9]+)/; + +// Reg for url without protocol +const RE_NO_PROTOCOL = /^([^/@#:.]+(?:\.[^/@#:.]+)+)/; + +// RegExp for version string +const VERSION_PATTERN_REGEXP = /^([\d^=v<>~]|[*xX]$)/; + +// Specific protocol for short url without normal hostname +const PROTOCOLS_FOR_SHORT = [ + "github:", + "gitlab:", + "bitbucket:", + "gist:", + "file:" +]; + +// Default protocol for git url +const DEF_GIT_PROTOCOL = "git+ssh://"; + +// thanks to https://github.com/npm/hosted-git-info/blob/latest/git-host-info.js +const extractCommithashByDomain = { + /** + * @param {string} pathname pathname + * @param {string} hash hash + * @returns {string | undefined} hash + */ + "github.com": (pathname, hash) => { + let [, user, project, type, commithash] = pathname.split("/", 5); + if (type && type !== "tree") { + return; + } + + commithash = !type ? hash : `#${commithash}`; + + if (project && project.endsWith(".git")) { + project = project.slice(0, -4); + } + + if (!user || !project) { + return; + } + + return commithash; + }, + /** + * @param {string} pathname pathname + * @param {string} hash hash + * @returns {string | undefined} hash + */ + "gitlab.com": (pathname, hash) => { + const path = pathname.slice(1); + if (path.includes("/-/") || path.includes("/archive.tar.gz")) { + return; + } + + const segments = path.split("/"); + let project = /** @type {string} */ (segments.pop()); + if (project.endsWith(".git")) { + project = project.slice(0, -4); + } + + const user = segments.join("/"); + if (!user || !project) { + return; + } + + return hash; + }, + /** + * @param {string} pathname pathname + * @param {string} hash hash + * @returns {string | undefined} hash + */ + "bitbucket.org": (pathname, hash) => { + let [, user, project, aux] = pathname.split("/", 4); + if (["get"].includes(aux)) { + return; + } + + if (project && project.endsWith(".git")) { + project = project.slice(0, -4); + } + + if (!user || !project) { + return; + } + + return hash; + }, + /** + * @param {string} pathname pathname + * @param {string} hash hash + * @returns {string | undefined} hash + */ + "gist.github.com": (pathname, hash) => { + let [, user, project, aux] = pathname.split("/", 4); + if (aux === "raw") { + return; + } + + if (!project) { + if (!user) { + return; + } + + project = user; + } + + if (project.endsWith(".git")) { + project = project.slice(0, -4); + } + + return hash; + } +}; + +/** + * extract commit hash from parsed url + * @inner + * @param {URL} urlParsed parsed url + * @returns {string} commithash + */ +function getCommithash(urlParsed) { + let { hostname, pathname, hash } = urlParsed; + hostname = hostname.replace(/^www\./, ""); + + try { + hash = decodeURIComponent(hash); + // eslint-disable-next-line no-empty + } catch (_err) {} + + if ( + extractCommithashByDomain[ + /** @type {keyof extractCommithashByDomain} */ (hostname) + ] + ) { + return ( + extractCommithashByDomain[ + /** @type {keyof extractCommithashByDomain} */ (hostname) + ](pathname, hash) || "" + ); + } + + return hash; +} + +/** + * make url right for URL parse + * @inner + * @param {string} gitUrl git url + * @returns {string} fixed url + */ +function correctUrl(gitUrl) { + // like: + // proto://hostname.com:user/repo -> proto://hostname.com/user/repo + return gitUrl.replace(RE_HOSTNAME_WITH_COLON, "$1/$2"); +} + +/** + * make url protocol right for URL parse + * @inner + * @param {string} gitUrl git url + * @returns {string} fixed url + */ +function correctProtocol(gitUrl) { + // eg: github:foo/bar#v1.0. Should not add double slash, in case of error parsed `pathname` + if (RE_GIT_URL_SHORT.test(gitUrl)) { + return gitUrl; + } + + // eg: user@github.com:foo/bar + if (!RE_CUSTOM_PROTOCOL.test(gitUrl)) { + return `${DEF_GIT_PROTOCOL}${gitUrl}`; + } + + return gitUrl; +} + +/** + * extract git dep version from hash + * @inner + * @param {string} hash hash + * @returns {string} git dep version + */ +function getVersionFromHash(hash) { + const matched = hash.match(RE_URL_HASH_VERSION); + + return (matched && matched[1]) || ""; +} + +/** + * if string can be decoded + * @inner + * @param {string} str str to be checked + * @returns {boolean} if can be decoded + */ +function canBeDecoded(str) { + try { + decodeURIComponent(str); + } catch (_err) { + return false; + } + + return true; +} + +/** + * get right dep version from git url + * @inner + * @param {string} gitUrl git url + * @returns {string} dep version + */ +function getGitUrlVersion(gitUrl) { + const oriGitUrl = gitUrl; + // github extreme shorthand + gitUrl = RE_URL_GITHUB_EXTREME_SHORT.test(gitUrl) + ? `github:${gitUrl}` + : correctProtocol(gitUrl); + + gitUrl = correctUrl(gitUrl); + + let parsed; + try { + parsed = new URL(gitUrl); + // eslint-disable-next-line no-empty + } catch (_err) {} + + if (!parsed) { + return ""; + } + + const { protocol, hostname, pathname, username, password } = parsed; + if (!RE_PROTOCOL.test(protocol)) { + return ""; + } + + // pathname shouldn't be empty or URL malformed + if (!pathname || !canBeDecoded(pathname)) { + return ""; + } + + // without protocol, there should have auth info + if (RE_NO_PROTOCOL.test(oriGitUrl) && !username && !password) { + return ""; + } + + if (!PROTOCOLS_FOR_SHORT.includes(protocol.toLowerCase())) { + if (!RE_HOSTNAME.test(hostname)) { + return ""; + } + + const commithash = getCommithash(parsed); + return getVersionFromHash(commithash) || commithash; + } + + // for protocol short + return getVersionFromHash(gitUrl); +} /** * @param {string} str maybe required version * @returns {boolean} true, if it looks like a version */ -exports.isRequiredVersion = str => { - return /^([\d^=v<>~]|[*xX]$)/.test(str); -}; +function isRequiredVersion(str) { + return VERSION_PATTERN_REGEXP.test(str); +} + +module.exports.isRequiredVersion = isRequiredVersion; + +/** + * @see https://docs.npmjs.com/cli/v7/configuring-npm/package-json#urls-as-dependencies + * @param {string} versionDesc version to be normalized + * @returns {string} normalized version + */ +function normalizeVersion(versionDesc) { + versionDesc = (versionDesc && versionDesc.trim()) || ""; + + if (isRequiredVersion(versionDesc)) { + return versionDesc; + } + + // add handle for URL Dependencies + return getGitUrlVersion(versionDesc.toLowerCase()); +} + +module.exports.normalizeVersion = normalizeVersion; + +/** @typedef {{ data: JsonObject, path: string }} DescriptionFile */ /** - * * @param {InputFileSystem} fs file system * @param {string} directory directory to start looking into * @param {string[]} descriptionFiles possible description filenames - * @param {function(Error=, {data: object, path: string}=): void} callback callback + * @param {function((Error | null)=, DescriptionFile=): void} callback callback */ const getDescriptionFile = (fs, directory, descriptionFiles, callback) => { let i = 0; @@ -56,35 +360,35 @@ const getDescriptionFile = (fs, directory, descriptionFiles, callback) => { }; tryLoadCurrent(); }; -exports.getDescriptionFile = getDescriptionFile; +module.exports.getDescriptionFile = getDescriptionFile; -exports.getRequiredVersionFromDescriptionFile = (data, packageName) => { - if ( - data.optionalDependencies && - typeof data.optionalDependencies === "object" && - packageName in data.optionalDependencies - ) { - return data.optionalDependencies[packageName]; - } - if ( - data.dependencies && - typeof data.dependencies === "object" && - packageName in data.dependencies - ) { - return data.dependencies[packageName]; - } - if ( - data.peerDependencies && - typeof data.peerDependencies === "object" && - packageName in data.peerDependencies - ) { - return data.peerDependencies[packageName]; - } - if ( - data.devDependencies && - typeof data.devDependencies === "object" && - packageName in data.devDependencies - ) { - return data.devDependencies[packageName]; +/** + * @param {JsonObject} data description file data i.e.: package.json + * @param {string} packageName name of the dependency + * @returns {string | undefined} normalized version + */ +const getRequiredVersionFromDescriptionFile = (data, packageName) => { + const dependencyTypes = [ + "optionalDependencies", + "dependencies", + "peerDependencies", + "devDependencies" + ]; + + for (const dependencyType of dependencyTypes) { + const dependency = /** @type {JsonObject} */ (data[dependencyType]); + if ( + dependency && + typeof dependency === "object" && + packageName in dependency + ) { + return normalizeVersion( + /** @type {Exclude} */ ( + dependency[packageName] + ) + ); + } } }; +module.exports.getRequiredVersionFromDescriptionFile = + getRequiredVersionFromDescriptionFile; diff --git a/lib/stats/DefaultStatsFactoryPlugin.js b/lib/stats/DefaultStatsFactoryPlugin.js index 9090509ab87..c52a12d80e4 100644 --- a/lib/stats/DefaultStatsFactoryPlugin.js +++ b/lib/stats/DefaultStatsFactoryPlugin.js @@ -6,11 +6,11 @@ "use strict"; const util = require("util"); +const { WEBPACK_MODULE_TYPE_RUNTIME } = require("../ModuleTypeConstants"); const ModuleDependency = require("../dependencies/ModuleDependency"); const formatLocation = require("../formatLocation"); const { LogType } = require("../logging/Logger"); const AggressiveSplittingPlugin = require("../optimize/AggressiveSplittingPlugin"); -const ConcatenatedModule = require("../optimize/ConcatenatedModule"); const SizeLimitsPlugin = require("../performance/SizeLimitsPlugin"); const { countIterable } = require("../util/IterableHelpers"); const { @@ -26,6 +26,7 @@ const { makePathsRelative, parseResource } = require("../util/identifier"); /** @typedef {import("webpack-sources").Source} Source */ /** @typedef {import("../Chunk")} Chunk */ +/** @typedef {import("../Chunk").ChunkId} ChunkId */ /** @typedef {import("../ChunkGroup")} ChunkGroup */ /** @typedef {import("../ChunkGroup").OriginRecord} OriginRecord */ /** @typedef {import("../Compilation")} Compilation */ @@ -33,22 +34,30 @@ const { makePathsRelative, parseResource } = require("../util/identifier"); /** @typedef {import("../Compilation").AssetInfo} AssetInfo */ /** @typedef {import("../Compilation").NormalizedStatsOptions} NormalizedStatsOptions */ /** @typedef {import("../Compiler")} Compiler */ +/** @typedef {import("../ChunkGraph").ModuleId} ModuleId */ /** @typedef {import("../Dependency")} Dependency */ /** @typedef {import("../Dependency").DependencyLocation} DependencyLocation */ /** @typedef {import("../Module")} Module */ +/** @typedef {import("../Module").BuildInfo} BuildInfo */ /** @typedef {import("../ModuleGraphConnection")} ModuleGraphConnection */ /** @typedef {import("../ModuleProfile")} ModuleProfile */ /** @typedef {import("../RequestShortener")} RequestShortener */ /** @typedef {import("../WebpackError")} WebpackError */ -/** @template T @typedef {import("../util/comparators").Comparator} Comparator */ +/** @typedef {import("../TemplatedPathPlugin").TemplatePath} TemplatePath */ +/** + * @template T + * @typedef {import("../util/comparators").Comparator} Comparator + */ /** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */ -/** @typedef {import("../util/smartGrouping").GroupConfig} GroupConfig */ +/** + * @template T, R + * @typedef {import("../util/smartGrouping").GroupConfig} GroupConfig + */ /** @typedef {import("./StatsFactory")} StatsFactory */ /** @typedef {import("./StatsFactory").StatsFactoryContext} StatsFactoryContext */ - -/** @typedef {KnownStatsCompilation & Record} StatsCompilation */ +/** @typedef {Record & KnownStatsCompilation} StatsCompilation */ /** - * @typedef {Object} KnownStatsCompilation + * @typedef {object} KnownStatsCompilation * @property {any=} env * @property {string=} name * @property {string=} hash @@ -74,28 +83,28 @@ const { makePathsRelative, parseResource } = require("../util/identifier"); * @property {Record=} logging */ -/** @typedef {KnownStatsLogging & Record} StatsLogging */ +/** @typedef {Record & KnownStatsLogging} StatsLogging */ /** - * @typedef {Object} KnownStatsLogging + * @typedef {object} KnownStatsLogging * @property {StatsLoggingEntry[]} entries * @property {number} filteredEntries * @property {boolean} debug */ -/** @typedef {KnownStatsLoggingEntry & Record} StatsLoggingEntry */ +/** @typedef {Record & KnownStatsLoggingEntry} StatsLoggingEntry */ /** - * @typedef {Object} KnownStatsLoggingEntry + * @typedef {object} KnownStatsLoggingEntry * @property {string} type - * @property {string} message + * @property {string=} message * @property {string[]=} trace * @property {StatsLoggingEntry[]=} children * @property {any[]=} args * @property {number=} time */ -/** @typedef {KnownStatsAsset & Record} StatsAsset */ +/** @typedef {Record & KnownStatsAsset} StatsAsset */ /** - * @typedef {Object} KnownStatsAsset + * @typedef {object} KnownStatsAsset * @property {string} type * @property {string} name * @property {AssetInfo} info @@ -114,9 +123,9 @@ const { makePathsRelative, parseResource } = require("../util/identifier"); * @property {boolean=} isOverSizeLimit */ -/** @typedef {KnownStatsChunkGroup & Record} StatsChunkGroup */ +/** @typedef {Record & KnownStatsChunkGroup} StatsChunkGroup */ /** - * @typedef {Object} KnownStatsChunkGroup + * @typedef {object} KnownStatsChunkGroup * @property {string=} name * @property {(string|number)[]=} chunks * @property {({ name: string, size?: number })[]=} assets @@ -130,52 +139,53 @@ const { makePathsRelative, parseResource } = require("../util/identifier"); * @property {boolean=} isOverSizeLimit */ -/** @typedef {KnownStatsModule & Record} StatsModule */ +/** @typedef {Record & KnownStatsModule} StatsModule */ /** - * @typedef {Object} KnownStatsModule + * @typedef {object} KnownStatsModule * @property {string=} type * @property {string=} moduleType - * @property {string=} layer + * @property {(string | null)=} layer * @property {string=} identifier * @property {string=} name - * @property {string=} nameForCondition + * @property {(string | null)=} nameForCondition * @property {number=} index * @property {number=} preOrderIndex * @property {number=} index2 * @property {number=} postOrderIndex * @property {number=} size - * @property {{[x: string]: number}=} sizes + * @property {{ [x: string]: number }=} sizes * @property {boolean=} cacheable * @property {boolean=} built * @property {boolean=} codeGenerated + * @property {boolean=} buildTimeExecuted * @property {boolean=} cached * @property {boolean=} optional * @property {boolean=} orphan - * @property {string|number=} id - * @property {string|number=} issuerId - * @property {(string|number)[]=} chunks - * @property {(string|number)[]=} assets + * @property {string | number=} id + * @property {string | number | null=} issuerId + * @property {(string | number)[]=} chunks + * @property {(string | number)[]=} assets * @property {boolean=} dependent - * @property {string=} issuer - * @property {string=} issuerName + * @property {(string | null)=} issuer + * @property {(string | null)=} issuerName * @property {StatsModuleIssuer[]=} issuerPath * @property {boolean=} failed * @property {number=} errors * @property {number=} warnings * @property {StatsProfile=} profile * @property {StatsModuleReason[]=} reasons - * @property {(boolean | string[])=} usedExports - * @property {string[]=} providedExports + * @property {(boolean | null | string[])=} usedExports + * @property {(string[] | null)=} providedExports * @property {string[]=} optimizationBailout - * @property {number=} depth + * @property {(number | null)=} depth * @property {StatsModule[]=} modules * @property {number=} filteredModules * @property {ReturnType=} source */ -/** @typedef {KnownStatsProfile & Record} StatsProfile */ +/** @typedef {Record & KnownStatsProfile} StatsProfile */ /** - * @typedef {Object} KnownStatsProfile + * @typedef {object} KnownStatsProfile * @property {number} total * @property {number} resolving * @property {number} restoring @@ -188,49 +198,49 @@ const { makePathsRelative, parseResource } = require("../util/identifier"); * @property {number} dependencies */ -/** @typedef {KnownStatsModuleIssuer & Record} StatsModuleIssuer */ +/** @typedef {Record & KnownStatsModuleIssuer} StatsModuleIssuer */ /** - * @typedef {Object} KnownStatsModuleIssuer - * @property {string=} identifier - * @property {string=} name + * @typedef {object} KnownStatsModuleIssuer + * @property {string} identifier + * @property {string} name * @property {(string|number)=} id - * @property {StatsProfile=} profile + * @property {StatsProfile} profile */ -/** @typedef {KnownStatsModuleReason & Record} StatsModuleReason */ +/** @typedef {Record & KnownStatsModuleReason} StatsModuleReason */ /** - * @typedef {Object} KnownStatsModuleReason - * @property {string=} moduleIdentifier - * @property {string=} module - * @property {string=} moduleName - * @property {string=} resolvedModuleIdentifier - * @property {string=} resolvedModule - * @property {string=} type + * @typedef {object} KnownStatsModuleReason + * @property {string | null} moduleIdentifier + * @property {string | null} module + * @property {string | null} moduleName + * @property {string | null} resolvedModuleIdentifier + * @property {string | null} resolvedModule + * @property {string | null} type * @property {boolean} active - * @property {string=} explanation - * @property {string=} userRequest - * @property {string=} loc - * @property {(string|number)=} moduleId - * @property {(string|number)=} resolvedModuleId + * @property {string | null} explanation + * @property {string | null} userRequest + * @property {(string | null)=} loc + * @property {(string | number | null)=} moduleId + * @property {(string | number | null)=} resolvedModuleId */ -/** @typedef {KnownStatsChunk & Record} StatsChunk */ +/** @typedef {Record & KnownStatsChunk} StatsChunk */ /** - * @typedef {Object} KnownStatsChunk + * @typedef {object} KnownStatsChunk * @property {boolean} rendered * @property {boolean} initial * @property {boolean} entry * @property {boolean} recorded * @property {string=} reason * @property {number} size - * @property {Record=} sizes - * @property {string[]=} names - * @property {string[]=} idHints + * @property {Record} sizes + * @property {string[]} names + * @property {string[]} idHints * @property {string[]=} runtime - * @property {string[]=} files - * @property {string[]=} auxiliaryFiles + * @property {string[]} files + * @property {string[]} auxiliaryFiles * @property {string} hash - * @property {Record=} childrenByOrder + * @property {Record} childrenByOrder * @property {(string|number)=} id * @property {(string|number)[]=} siblings * @property {(string|number)[]=} parents @@ -240,20 +250,20 @@ const { makePathsRelative, parseResource } = require("../util/identifier"); * @property {StatsChunkOrigin[]=} origins */ -/** @typedef {KnownStatsChunkOrigin & Record} StatsChunkOrigin */ +/** @typedef {Record & KnownStatsChunkOrigin} StatsChunkOrigin */ /** - * @typedef {Object} KnownStatsChunkOrigin - * @property {string=} module - * @property {string=} moduleIdentifier - * @property {string=} moduleName - * @property {string=} loc - * @property {string=} request - * @property {(string|number)=} moduleId + * @typedef {object} KnownStatsChunkOrigin + * @property {string} module + * @property {string} moduleIdentifier + * @property {string} moduleName + * @property {string} loc + * @property {string} request + * @property {(string | number)=} moduleId */ -/** @typedef {KnownStatsModuleTraceItem & Record} StatsModuleTraceItem */ +/** @typedef { Record & KnownStatsModuleTraceItem} StatsModuleTraceItem */ /** - * @typedef {Object} KnownStatsModuleTraceItem + * @typedef {object} KnownStatsModuleTraceItem * @property {string=} originIdentifier * @property {string=} originName * @property {string=} moduleIdentifier @@ -263,15 +273,15 @@ const { makePathsRelative, parseResource } = require("../util/identifier"); * @property {(string|number)=} moduleId */ -/** @typedef {KnownStatsModuleTraceDependency & Record} StatsModuleTraceDependency */ +/** @typedef {Record & KnownStatsModuleTraceDependency} StatsModuleTraceDependency */ /** - * @typedef {Object} KnownStatsModuleTraceDependency + * @typedef {object} KnownStatsModuleTraceDependency * @property {string=} loc */ -/** @typedef {KnownStatsError & Record} StatsError */ +/** @typedef {Record & KnownStatsError} StatsError */ /** - * @typedef {Object} KnownStatsError + * @typedef {object} KnownStatsError * @property {string} message * @property {string=} chunkName * @property {boolean=} chunkEntry @@ -280,14 +290,14 @@ const { makePathsRelative, parseResource } = require("../util/identifier"); * @property {string=} moduleIdentifier * @property {string=} moduleName * @property {string=} loc - * @property {string|number=} chunkId + * @property {ChunkId=} chunkId * @property {string|number=} moduleId - * @property {any=} moduleTrace + * @property {StatsModuleTraceItem[]=} moduleTrace * @property {any=} details - * @property {any=} stack + * @property {string=} stack */ -/** @typedef {Asset & { type: string, related: PreprocessedAsset[] }} PreprocessedAsset */ +/** @typedef {Asset & { type: string, related: PreprocessedAsset[] | undefined }} PreprocessedAsset */ /** * @template T @@ -296,7 +306,7 @@ const { makePathsRelative, parseResource } = require("../util/identifier"); */ /** - * @typedef {Object} SimpleExtractors + * @typedef {object} SimpleExtractors * @property {ExtractorsByOption} compilation * @property {ExtractorsByOption} asset * @property {ExtractorsByOption} asset$visible @@ -340,15 +350,14 @@ const uniqueArray = (items, selector) => { * @param {Comparator} comparator comparator function * @returns {I[]} array of values */ -const uniqueOrderedArray = (items, selector, comparator) => { - return uniqueArray(items, selector).sort(comparator); -}; +const uniqueOrderedArray = (items, selector, comparator) => + uniqueArray(items, selector).sort(comparator); /** @template T @template R @typedef {{ [P in keyof T]: R }} MappedValues */ /** - * @template T - * @template R + * @template {object} T + * @template {object} R * @param {T} obj object to be mapped * @param {function(T[keyof T], keyof T): R} fn mapping function * @returns {MappedValues} mapped object @@ -356,7 +365,10 @@ const uniqueOrderedArray = (items, selector, comparator) => { const mapObject = (obj, fn) => { const newObj = Object.create(null); for (const key of Object.keys(obj)) { - newObj[key] = fn(obj[key], /** @type {keyof T} */ (key)); + newObj[key] = fn( + obj[/** @type {keyof T} */ (key)], + /** @type {keyof T} */ (key) + ); } return newObj; }; @@ -404,10 +416,12 @@ const EXTRACT_ERROR = { ids: (object, error, { compilation: { chunkGraph } }) => { if (typeof error !== "string") { if (error.chunk) { - object.chunkId = error.chunk.id; + object.chunkId = /** @type {ChunkId} */ (error.chunk.id); } if (error.module) { - object.moduleId = chunkGraph.getModuleId(error.module); + object.moduleId = + /** @type {ModuleId} */ + (chunkGraph.getModuleId(error.module)); } } }, @@ -469,25 +483,21 @@ const SIMPLE_EXTRACTORS = { } if (!context.cachedGetErrors) { const map = new WeakMap(); - context.cachedGetErrors = compilation => { - return ( - map.get(compilation) || - (errors => (map.set(compilation, errors), errors))( - compilation.getErrors() - ) + context.cachedGetErrors = compilation => + map.get(compilation) || + // eslint-disable-next-line no-sequences + (errors => (map.set(compilation, errors), errors))( + compilation.getErrors() ); - }; } if (!context.cachedGetWarnings) { const map = new WeakMap(); - context.cachedGetWarnings = compilation => { - return ( - map.get(compilation) || - (warnings => (map.set(compilation, warnings), warnings))( - compilation.getWarnings() - ) + context.cachedGetWarnings = compilation => + map.get(compilation) || + // eslint-disable-next-line no-sequences + (warnings => (map.set(compilation, warnings), warnings))( + compilation.getWarnings() ); - }; } if (compilation.name) { object.name = compilation.name; @@ -503,9 +513,6 @@ const SIMPLE_EXTRACTORS = { let acceptedTypes; let collapsedGroups = false; switch (logging) { - default: - acceptedTypes = new Set(); - break; case "error": acceptedTypes = new Set([LogType.error]); break; @@ -548,6 +555,9 @@ const SIMPLE_EXTRACTORS = { ]); collapsedGroups = true; break; + default: + acceptedTypes = new Set(); + break; } const cachedMakePathsRelative = makePathsRelative.bindContextCache( options.context, @@ -580,15 +590,16 @@ const SIMPLE_EXTRACTORS = { if (type === LogType.groupEnd) { groupStack.pop(); - if (groupStack.length > 0) { - currentList = groupStack[groupStack.length - 1].children; - } else { - currentList = rootList; - } + currentList = + groupStack.length > 0 + ? /** @type {KnownStatsLoggingEntry[]} */ ( + groupStack[groupStack.length - 1].children + ) + : rootList; if (depthInCollapsedGroup > 0) depthInCollapsedGroup--; continue; } - let message = undefined; + let message; if (entry.type === LogType.time) { message = `${entry.args[0]}: ${ entry.args[1] * 1000 + entry.args[2] / 1000000 @@ -635,7 +646,7 @@ const SIMPLE_EXTRACTORS = { } }, hash: (object, compilation) => { - object.hash = compilation.hash; + object.hash = /** @type {string} */ (compilation.hash); }, version: object => { object.version = require("../../package.json").version; @@ -644,18 +655,23 @@ const SIMPLE_EXTRACTORS = { object.env = _env; }, timings: (object, compilation) => { - object.time = compilation.endTime - compilation.startTime; + object.time = + /** @type {number} */ (compilation.endTime) - + /** @type {number} */ (compilation.startTime); }, builtAt: (object, compilation) => { - object.builtAt = compilation.endTime; + object.builtAt = /** @type {number} */ (compilation.endTime); }, publicPath: (object, compilation) => { object.publicPath = compilation.getPath( - compilation.outputOptions.publicPath + /** @type {TemplatePath} */ + (compilation.outputOptions.publicPath) ); }, outputPath: (object, compilation) => { - object.outputPath = compilation.outputOptions.path; + object.outputPath = /** @type {string} */ ( + compilation.outputOptions.path + ); }, assets: (object, compilation, context, options, factory) => { const { type } = context; @@ -740,7 +756,10 @@ const SIMPLE_EXTRACTORS = { compilationAuxiliaryFileToChunks } ); - const limited = spaceLimited(groupedAssets, options.assetsSpace); + const limited = spaceLimited( + groupedAssets, + /** @type {number} */ (options.assetsSpace) + ); object.assets = limited.children; object.filteredAssets = limited.filteredChildren; }, @@ -811,11 +830,33 @@ const SIMPLE_EXTRACTORS = { }, errors: (object, compilation, context, options, factory) => { const { type, cachedGetErrors } = context; - object.errors = factory.create( + const rawErrors = cachedGetErrors(compilation); + const factorizedErrors = factory.create( `${type}.errors`, cachedGetErrors(compilation), context ); + let filtered = 0; + if (options.errorDetails === "auto" && rawErrors.length >= 3) { + filtered = rawErrors + .map(e => typeof e !== "string" && e.details) + .filter(Boolean).length; + } + if ( + options.errorDetails === true || + !Number.isFinite(options.errorsSpace) + ) { + object.errors = factorizedErrors; + if (filtered) object.filteredErrorDetailsCount = filtered; + return; + } + const [errors, filteredBySpace] = errorsSpaceLimit( + factorizedErrors, + /** @type {number} */ + (options.errorsSpace) + ); + object.filteredErrorDetailsCount = filtered + filteredBySpace; + object.errors = errors; }, errorsCount: (object, compilation, { cachedGetErrors }) => { object.errorsCount = countWithChildren(compilation, c => @@ -824,11 +865,32 @@ const SIMPLE_EXTRACTORS = { }, warnings: (object, compilation, context, options, factory) => { const { type, cachedGetWarnings } = context; - object.warnings = factory.create( + const rawWarnings = factory.create( `${type}.warnings`, cachedGetWarnings(compilation), context ); + let filtered = 0; + if (options.errorDetails === "auto") { + filtered = cachedGetWarnings(compilation) + .map(e => typeof e !== "string" && e.details) + .filter(Boolean).length; + } + if ( + options.errorDetails === true || + !Number.isFinite(options.warningsSpace) + ) { + object.warnings = rawWarnings; + if (filtered) object.filteredWarningDetailsCount = filtered; + return; + } + const [warnings, filteredBySpace] = errorsSpaceLimit( + rawWarnings, + /** @type {number} */ + (options.warningsSpace) + ); + object.filteredWarningDetailsCount = filtered + filteredBySpace; + object.warnings = warnings; }, warningsCount: ( object, @@ -839,43 +901,33 @@ const SIMPLE_EXTRACTORS = { ) => { const { type, cachedGetWarnings } = context; object.warningsCount = countWithChildren(compilation, (c, childType) => { - if (!warningsFilter && warningsFilter.length === 0) + if ( + !warningsFilter && + /** @type {((warning: StatsError, textValue: string) => boolean)[]} */ + (warningsFilter).length === 0 + ) return cachedGetWarnings(c); return factory .create(`${type}${childType}.warnings`, cachedGetWarnings(c), context) - .filter(warning => { - const warningString = Object.keys(warning) - .map(key => `${warning[key]}`) - .join("\n"); - return !warningsFilter.some(filter => - filter(warning, warningString) - ); - }); + .filter( + /** + * @param {TODO} warning warning + * @returns {boolean} result + */ + warning => { + const warningString = Object.keys(warning) + .map( + key => + `${warning[/** @type {keyof KnownStatsError} */ (key)]}` + ) + .join("\n"); + return !warningsFilter.some(filter => + filter(warning, warningString) + ); + } + ); }); }, - errorDetails: ( - object, - compilation, - { cachedGetErrors, cachedGetWarnings }, - { errorDetails, errors, warnings } - ) => { - if (errorDetails === "auto") { - if (warnings) { - const warnings = cachedGetWarnings(compilation); - object.filteredWarningDetailsCount = warnings - .map(e => typeof e !== "string" && e.details) - .filter(Boolean).length; - } - if (errors) { - const errors = cachedGetErrors(compilation); - if (errors.length >= 3) { - object.filteredErrorDetailsCount = errors - .map(e => typeof e !== "string" && e.details) - .filter(Boolean).length; - } - } - } - }, children: (object, compilation, context, options, factory) => { const { type } = context; object.children = factory.create( @@ -941,11 +993,12 @@ const SIMPLE_EXTRACTORS = { const { type } = context; object.related = factory.create( `${type.slice(0, -8)}.related`, - asset.related, + asset.related || [], context ); object.filteredRelated = asset.related - ? asset.related.length - object.related.length + ? asset.related.length - + /** @type {StatsAsset[]} */ (object.related).length : undefined; }, ids: ( @@ -956,10 +1009,14 @@ const SIMPLE_EXTRACTORS = { const chunks = compilationFileToChunks.get(asset.name) || []; const auxiliaryChunks = compilationAuxiliaryFileToChunks.get(asset.name) || []; - object.chunks = uniqueOrderedArray(chunks, c => c.ids, compareIds); + object.chunks = uniqueOrderedArray( + chunks, + c => /** @type {ChunkId[]} */ (c.ids), + compareIds + ); object.auxiliaryChunks = uniqueOrderedArray( auxiliaryChunks, - c => c.ids, + c => /** @type {ChunkId[]} */ (c.ids), compareIds ); }, @@ -985,7 +1042,7 @@ const SIMPLE_EXTRACTORS = { const asset = compilation.getAsset(name); return { name, - size: asset ? asset.info.size : -1 + size: /** @type {number} */ (asset ? asset.info.size : -1) }; }; /** @type {(total: number, asset: { size: number }) => number} */ @@ -1001,7 +1058,9 @@ const SIMPLE_EXTRACTORS = { /** @type {KnownStatsChunkGroup} */ const statsChunkGroup = { name, - chunks: ids ? chunkGroup.chunks.map(c => c.id) : undefined, + chunks: ids + ? /** @type {ChunkId[]} */ (chunkGroup.chunks.map(c => c.id)) + : undefined, assets: assets.length <= chunkGroupMaxAssets ? assets : undefined, filteredAssets: assets.length <= chunkGroupMaxAssets ? 0 : assets.length, @@ -1030,7 +1089,10 @@ const SIMPLE_EXTRACTORS = { /** @type {KnownStatsChunkGroup} */ const childStatsChunkGroup = { name: group.name, - chunks: ids ? group.chunks.map(c => c.id) : undefined, + chunks: ids + ? /** @type {ChunkId[]} */ + (group.chunks.map(c => c.id)) + : undefined, assets: assets.length <= chunkGroupMaxAssets ? assets : undefined, filteredAssets: @@ -1049,7 +1111,7 @@ const SIMPLE_EXTRACTORS = { return childStatsChunkGroup; }) - ) + ) : undefined, childAssets: children ? mapObject(children, groups => { @@ -1063,7 +1125,7 @@ const SIMPLE_EXTRACTORS = { } } return Array.from(set); - }) + }) : undefined }; Object.assign(object, statsChunkGroup); @@ -1074,9 +1136,12 @@ const SIMPLE_EXTRACTORS = { }, module: { _: (object, module, context, options, factory) => { - const { compilation, type } = context; + const { type } = context; + const compilation = /** @type {Compilation} */ (context.compilation); const built = compilation.builtModules.has(module); const codeGenerated = compilation.codeGeneratedModules.has(module); + const buildTimeExecuted = + compilation.buildTimeExecutedModules.has(module); /** @type {{[x: string]: number}} */ const sizes = {}; for (const sourceType of module.getSourceTypes()) { @@ -1091,6 +1156,7 @@ const SIMPLE_EXTRACTORS = { sizes, built, codeGenerated, + buildTimeExecuted, cached: !built && !codeGenerated }; Object.assign(object, statsModule); @@ -1105,7 +1171,8 @@ const SIMPLE_EXTRACTORS = { }, module$visible: { _: (object, module, context, { requestShortener }, factory) => { - const { compilation, type, rootModules } = context; + const { type, rootModules } = context; + const compilation = /** @type {Compilation} */ (context.compilation); const { moduleGraph } = compilation; /** @type {Module[]} */ const path = []; @@ -1132,11 +1199,15 @@ const SIMPLE_EXTRACTORS = { identifier: module.identifier(), name: module.readableIdentifier(requestShortener), nameForCondition: module.nameForCondition(), - index: moduleGraph.getPreOrderIndex(module), - preOrderIndex: moduleGraph.getPreOrderIndex(module), - index2: moduleGraph.getPostOrderIndex(module), - postOrderIndex: moduleGraph.getPostOrderIndex(module), - cacheable: module.buildInfo.cacheable, + index: /** @type {number} */ (moduleGraph.getPreOrderIndex(module)), + preOrderIndex: /** @type {number} */ ( + moduleGraph.getPreOrderIndex(module) + ), + index2: /** @type {number} */ (moduleGraph.getPostOrderIndex(module)), + postOrderIndex: /** @type {number} */ ( + moduleGraph.getPostOrderIndex(module) + ), + cacheable: /** @type {BuildInfo} */ (module.buildInfo).cacheable, optional: module.isOptional(moduleGraph), orphan: !type.endsWith("module.modules[].module$visible") && @@ -1161,17 +1232,24 @@ const SIMPLE_EXTRACTORS = { } }, ids: (object, module, { compilation: { chunkGraph, moduleGraph } }) => { - object.id = chunkGraph.getModuleId(module); + object.id = /** @type {ModuleId} */ (chunkGraph.getModuleId(module)); const issuer = moduleGraph.getIssuer(module); object.issuerId = issuer && chunkGraph.getModuleId(issuer); - object.chunks = Array.from( - chunkGraph.getOrderedModuleChunksIterable(module, compareChunksById), - chunk => chunk.id - ); + object.chunks = + /** @type {ChunkId[]} */ + ( + Array.from( + chunkGraph.getOrderedModuleChunksIterable( + module, + compareChunksById + ), + chunk => chunk.id + ) + ); }, moduleAssets: (object, module) => { - object.assets = module.buildInfo.assets - ? Object.keys(module.buildInfo.assets) + object.assets = /** @type {BuildInfo} */ (module.buildInfo).assets + ? Object.keys(/** @type {BuildInfo} */ (module.buildInfo).assets) : []; }, reasons: (object, module, context, options, factory) => { @@ -1179,11 +1257,18 @@ const SIMPLE_EXTRACTORS = { type, compilation: { moduleGraph } } = context; - object.reasons = factory.create( + const groupsReasons = factory.create( `${type.slice(0, -8)}.reasons`, Array.from(moduleGraph.getIncomingConnections(module)), context ); + const limited = spaceLimited( + groupsReasons, + /** @type {number} */ + (options.reasonsSpace) + ); + object.reasons = limited.children; + object.filteredReasons = limited.filteredChildren; }, usedExports: ( object, @@ -1223,11 +1308,13 @@ const SIMPLE_EXTRACTORS = { }, nestedModules: (object, module, context, options, factory) => { const { type } = context; - if (module instanceof ConcatenatedModule) { - const modules = module.modules; + const innerModules = /** @type {Module & { modules?: Module[] }} */ ( + module + ).modules; + if (Array.isArray(innerModules)) { const groupedModules = factory.create( `${type.slice(0, -8)}.modules`, - modules, + innerModules, context ); const limited = spaceLimited( @@ -1272,10 +1359,11 @@ const SIMPLE_EXTRACTORS = { }, moduleIssuer: { _: (object, module, context, { requestShortener }, factory) => { - const { compilation, type } = context; + const { type } = context; + const compilation = /** @type {Compilation} */ (context.compilation); const { moduleGraph } = compilation; const profile = moduleGraph.getProfile(module); - /** @type {KnownStatsModuleIssuer} */ + /** @type {Partial} */ const statsModuleIssuer = { identifier: module.identifier(), name: module.readableIdentifier(requestShortener) @@ -1286,7 +1374,7 @@ const SIMPLE_EXTRACTORS = { } }, ids: (object, module, { compilation: { chunkGraph } }) => { - object.id = chunkGraph.getModuleId(module); + object.id = /** @type {ModuleId} */ (chunkGraph.getModuleId(module)); } }, moduleReason: { @@ -1352,17 +1440,17 @@ const SIMPLE_EXTRACTORS = { chunk.runtime === undefined ? undefined : typeof chunk.runtime === "string" - ? [makePathsRelative(chunk.runtime)] - : Array.from(chunk.runtime.sort(), makePathsRelative), + ? [makePathsRelative(chunk.runtime)] + : Array.from(chunk.runtime.sort(), makePathsRelative), files: Array.from(chunk.files), auxiliaryFiles: Array.from(chunk.auxiliaryFiles).sort(compareIds), - hash: chunk.renderedHash, + hash: /** @type {string} */ (chunk.renderedHash), childrenByOrder: childIdByOrder }; Object.assign(object, statsChunk); }, ids: (object, chunk) => { - object.id = chunk.id; + object.id = /** @type {ChunkId} */ (chunk.id); }, chunkRelations: (object, chunk, { compilation: { chunkGraph } }) => { /** @type {Set} */ @@ -1375,16 +1463,17 @@ const SIMPLE_EXTRACTORS = { for (const chunkGroup of chunk.groupsIterable) { for (const parentGroup of chunkGroup.parentsIterable) { for (const chunk of parentGroup.chunks) { - parents.add(chunk.id); + parents.add(/** @type {ChunkId} */ (chunk.id)); } } for (const childGroup of chunkGroup.childrenIterable) { for (const chunk of childGroup.chunks) { - children.add(chunk.id); + children.add(/** @type {ChunkId} */ (chunk.id)); } } for (const sibling of chunkGroup.chunks) { - if (sibling !== chunk) siblings.add(sibling.id); + if (sibling !== chunk) + siblings.add(/** @type {ChunkId} */ (sibling.id)); } } object.siblings = Array.from(siblings).sort(compareIds); @@ -1446,7 +1535,7 @@ const SIMPLE_EXTRACTORS = { }, ids: (object, origin, { compilation: { chunkGraph } }) => { object.moduleId = origin.module - ? chunkGraph.getModuleId(origin.module) + ? /** @type {ModuleId} */ (chunkGraph.getModuleId(origin.module)) : undefined; } }, @@ -1474,8 +1563,12 @@ const SIMPLE_EXTRACTORS = { ); }, ids: (object, { origin, module }, { compilation: { chunkGraph } }) => { - object.originId = chunkGraph.getModuleId(origin); - object.moduleId = chunkGraph.getModuleId(module); + object.originId = + /** @type {ModuleId} */ + (chunkGraph.getModuleId(origin)); + object.moduleId = + /** @type {ModuleId} */ + (chunkGraph.getModuleId(module)); } }, moduleTraceDependency: { @@ -1499,13 +1592,13 @@ const FILTER = { } }; -/** @type {Record boolean | undefined>>} */ +/** @type {Record boolean | undefined>>} */ const FILTER_RESULTS = { "compilation.warnings": { warningsFilter: util.deprecate( (warning, context, { warningsFilter }) => { const warningString = Object.keys(warning) - .map(key => `${warning[key]}`) + .map(key => `${warning[/** @type {keyof KnownStatsError} */ (key)]}`) .join("\n"); return !warningsFilter.some(filter => filter(warning, warningString)); }, @@ -1522,7 +1615,7 @@ const MODULES_SORTER = { compareSelect( /** * @param {Module} m module - * @returns {number} depth + * @returns {number | null} depth */ m => moduleGraph.getDepth(m), compareNumbers @@ -1530,7 +1623,7 @@ const MODULES_SORTER = { compareSelect( /** * @param {Module} m module - * @returns {number} index + * @returns {number | null} index */ m => moduleGraph.getPreOrderIndex(m), compareNumbers @@ -1599,17 +1692,31 @@ const SORTERS = { } }; -const getItemSize = item => { +/** + * @template T + * @typedef {T & { children: Children[] | undefined, filteredChildren?: number }} Children + */ + +/** + * @template T + * @param {Children} item item + * @returns {number} item size + */ +const getItemSize = item => // Each item takes 1 line // + the size of the children // + 1 extra line when it has children and filteredChildren - return !item.children + !item.children ? 1 : item.filteredChildren - ? 2 + getTotalSize(item.children) - : 1 + getTotalSize(item.children); -}; + ? 2 + getTotalSize(item.children) + : 1 + getTotalSize(item.children); +/** + * @template T + * @param {Children[]} children children + * @returns {number} total size + */ const getTotalSize = children => { let size = 0; for (const child of children) { @@ -1618,6 +1725,11 @@ const getTotalSize = children => { return size; }; +/** + * @template T + * @param {Children[]} children children + * @returns {number} total items + */ const getTotalItems = children => { let count = 0; for (const child of children) { @@ -1631,6 +1743,11 @@ const getTotalItems = children => { return count; }; +/** + * @template T + * @param {Children[]} children children + * @returns {Children[]} collapsed children + */ const collapse = children => { // After collapse each child must take exactly one line const newChildren = []; @@ -1650,102 +1767,217 @@ const collapse = children => { return newChildren; }; -const spaceLimited = (itemsAndGroups, max) => { - /** @type {any[] | undefined} */ - let children = undefined; +/** + * @template T + * @param {Children[]} itemsAndGroups item and groups + * @param {number} max max + * @param {boolean=} filteredChildrenLineReserved filtered children line reserved + * @returns {Children} result + */ +const spaceLimited = ( + itemsAndGroups, + max, + filteredChildrenLineReserved = false +) => { + if (max < 1) { + return /** @type {Children} */ ({ + children: undefined, + filteredChildren: getTotalItems(itemsAndGroups) + }); + } + /** @type {Children[] | undefined} */ + let children; /** @type {number | undefined} */ - let filteredChildren = undefined; + let filteredChildren; // This are the groups, which take 1+ lines each - const groups = itemsAndGroups.filter(c => c.children || c.filteredChildren); + /** @type {Children[] | undefined} */ + const groups = []; // The sizes of the groups are stored in groupSizes - const groupSizes = groups.map(g => getItemSize(g)); + /** @type {number[]} */ + const groupSizes = []; // This are the items, which take 1 line each - const items = itemsAndGroups.filter(c => !c.children && !c.filteredChildren); + const items = []; // The total of group sizes - let groupsSize = groupSizes.reduce((a, b) => a + b, 0); + let groupsSize = 0; + + for (const itemOrGroup of itemsAndGroups) { + // is item + if (!itemOrGroup.children && !itemOrGroup.filteredChildren) { + items.push(itemOrGroup); + } else { + groups.push(itemOrGroup); + const size = getItemSize(itemOrGroup); + groupSizes.push(size); + groupsSize += size; + } + } + if (groupsSize + items.length <= max) { // The total size in the current state fits into the max // keep all - children = groups.concat(items); - } else if ( - groups.length > 0 && - groups.length + Math.min(1, items.length) < max - ) { - // If each group would take 1 line the total would be below the maximum - // collapse some groups, keep items - while (groupsSize + items.length + (filteredChildren ? 1 : 0) > max) { + children = groups.length > 0 ? groups.concat(items) : items; + } else if (groups.length === 0) { + // slice items to max + // inner space marks that lines for filteredChildren already reserved + const limit = max - (filteredChildrenLineReserved ? 0 : 1); + filteredChildren = items.length - limit; + items.length = limit; + children = items; + } else { + // limit is the size when all groups are collapsed + const limit = + groups.length + + (filteredChildrenLineReserved || items.length === 0 ? 0 : 1); + if (limit < max) { // calculate how much we are over the size limit // this allows to approach the limit faster - // it's always > 1 - const oversize = - items.length + groupsSize + (filteredChildren ? 1 : 0) - max; - // Find the maximum group and process only this one - const maxGroupSize = Math.max(...groupSizes); - if (maxGroupSize < items.length) { - filteredChildren = items.length; - items.length = 0; - continue; + let oversize; + // If each group would take 1 line the total would be below the maximum + // collapse some groups, keep items + while ( + (oversize = + groupsSize + + items.length + + (filteredChildren && !filteredChildrenLineReserved ? 1 : 0) - + max) > 0 + ) { + // Find the maximum group and process only this one + const maxGroupSize = Math.max(...groupSizes); + if (maxGroupSize < items.length) { + filteredChildren = items.length; + items.length = 0; + continue; + } + for (let i = 0; i < groups.length; i++) { + if (groupSizes[i] === maxGroupSize) { + const group = groups[i]; + // run this algorithm recursively and limit the size of the children to + // current size - oversize / number of groups + // So it should always end up being smaller + const headerSize = group.filteredChildren ? 2 : 1; + const limited = spaceLimited( + /** @type {Children} */ (group.children), + maxGroupSize - + // we should use ceil to always feet in max + Math.ceil(oversize / groups.length) - + // we substitute size of group head + headerSize, + headerSize === 2 + ); + groups[i] = { + ...group, + children: limited.children, + filteredChildren: limited.filteredChildren + ? (group.filteredChildren || 0) + limited.filteredChildren + : group.filteredChildren + }; + const newSize = getItemSize(groups[i]); + groupsSize -= maxGroupSize - newSize; + groupSizes[i] = newSize; + break; + } + } } - for (let i = 0; i < groups.length; i++) { - if (groupSizes[i] === maxGroupSize) { - const group = groups[i]; - // run this algorithm recursively and limit the size of the children to - // current size - oversize / number of groups - // So it should always end up being smaller - const headerSize = !group.children - ? 0 - : group.filteredChildren - ? 2 - : 1; - const limited = spaceLimited( - group.children, - groupSizes[i] - headerSize - oversize / groups.length - ); - groups[i] = { - ...group, - children: limited.children, - filteredChildren: - (group.filteredChildren || 0) + limited.filteredChildren - }; - const newSize = getItemSize(groups[i]); - groupsSize -= groupSizes[i] - newSize; - groupSizes[i] = newSize; - break; + children = groups.concat(items); + } else if (limit === max) { + // If we have only enough space to show one line per group and one line for the filtered items + // collapse all groups and items + children = collapse(groups); + filteredChildren = items.length; + } else { + // If we have no space + // collapse complete group + filteredChildren = getTotalItems(itemsAndGroups); + } + } + + return /** @type {Children} */ ({ children, filteredChildren }); +}; + +/** + * @param {StatsError[]} errors errors + * @param {number} max max + * @returns {[StatsError[], number]} error space limit + */ +const errorsSpaceLimit = (errors, max) => { + let filtered = 0; + // Can not fit into limit + // print only messages + if (errors.length + 1 >= max) + return [ + errors.map(error => { + if (typeof error === "string" || !error.details) return error; + filtered++; + return { ...error, details: "" }; + }), + filtered + ]; + let fullLength = errors.length; + let result = errors; + + let i = 0; + for (; i < errors.length; i++) { + const error = errors[i]; + if (typeof error !== "string" && error.details) { + const splitted = error.details.split("\n"); + const len = splitted.length; + fullLength += len; + if (fullLength > max) { + result = i > 0 ? errors.slice(0, i) : []; + const overLimit = fullLength - max + 1; + const error = errors[i++]; + result.push({ + ...error, + details: error.details.split("\n").slice(0, -overLimit).join("\n"), + filteredDetails: overLimit + }); + filtered = errors.length - i; + for (; i < errors.length; i++) { + const error = errors[i]; + if (typeof error === "string" || !error.details) result.push(error); + result.push({ ...error, details: "" }); + } + break; + } else if (fullLength === max) { + result = errors.slice(0, ++i); + filtered = errors.length - i; + for (; i < errors.length; i++) { + const error = errors[i]; + if (typeof error === "string" || !error.details) result.push(error); + result.push({ ...error, details: "" }); } + break; } } - children = groups.concat(items); - } else if ( - groups.length > 0 && - groups.length + Math.min(1, items.length) <= max - ) { - // If we have only enough space to show one line per group and one line for the filtered items - // collapse all groups and items - children = groups.length ? collapse(groups) : undefined; - filteredChildren = items.length; - } else { - // If we have no space - // collapse complete group - filteredChildren = getTotalItems(itemsAndGroups); } - return { - children, - filteredChildren - }; + + return [result, filtered]; }; +/** + * @template {{ size: number }} T + * @template {{ size: number }} R + * @param {(R | T)[]} children children + * @param {T[]} assets assets + * @returns {{ size: number }} asset size + */ const assetGroup = (children, assets) => { let size = 0; for (const asset of children) { size += asset.size; } - return { - size - }; + return { size }; }; +/** + * @template {{ size: number, sizes: Record }} T + * @param {Children[]} children children + * @param {KnownStatsModule[]} modules modules + * @returns {{ size: number, sizes: Record}} size and sizes + */ const moduleGroup = (children, modules) => { let size = 0; + /** @type {Record} */ const sizes = {}; for (const module of children) { size += module.size; @@ -1759,35 +1991,55 @@ const moduleGroup = (children, modules) => { }; }; -/** @type {Record void>} */ +/** + * @template {{ active: boolean }} T + * @param {Children[]} children children + * @param {KnownStatsModuleReason[]} reasons reasons + * @returns {{ active: boolean }} reason group + */ +const reasonGroup = (children, reasons) => { + let active = false; + for (const reason of children) { + active = active || reason.active; + } + return { + active + }; +}; + +const GROUP_EXTENSION_REGEXP = /(\.[^.]+?)(?:\?|(?: \+ \d+ modules?)?$)/; +const GROUP_PATH_REGEXP = /(.+)[/\\][^/\\]+?(?:\?|(?: \+ \d+ modules?)?$)/; + +/** @typedef {Record[], context: StatsFactoryContext, options: NormalizedStatsOptions) => void>} AssetsGroupers */ + +/** @type {AssetsGroupers} */ const ASSETS_GROUPERS = { _: (groupConfigs, context, options) => { + /** + * @param {keyof KnownStatsAsset} name name + * @param {boolean=} exclude need exclude? + */ const groupByFlag = (name, exclude) => { groupConfigs.push({ - getKeys: asset => { - return asset[name] ? ["1"] : undefined; - }, - getOptions: () => { - return { - groupChildren: !exclude, - force: exclude - }; - }, - createGroup: (key, children, assets) => { - return exclude + getKeys: asset => (asset[name] ? ["1"] : undefined), + getOptions: () => ({ + groupChildren: !exclude, + force: exclude + }), + createGroup: (key, children, assets) => + exclude ? { type: "assets by status", - [name]: !!key, + [name]: Boolean(key), filteredChildren: assets.length, ...assetGroup(children, assets) - } + } : { type: "assets by status", - [name]: !!key, + [name]: Boolean(key), children, ...assetGroup(children, assets) - }; - } + } }); }; const { @@ -1807,10 +2059,10 @@ const ASSETS_GROUPERS = { groupConfigs.push({ getKeys: asset => { const extensionMatch = - groupAssetsByExtension && /(\.[^.]+)(?:\?.*|$)/.exec(asset.name); + groupAssetsByExtension && GROUP_EXTENSION_REGEXP.exec(asset.name); const extension = extensionMatch ? extensionMatch[1] : ""; const pathMatch = - groupAssetsByPath && /(.+)[/\\][^/\\]+(?:\?.*|$)/.exec(asset.name); + groupAssetsByPath && GROUP_PATH_REGEXP.exec(asset.name); const path = pathMatch ? pathMatch[1].split(/[/\\]/) : []; const keys = []; if (groupAssetsByPath) { @@ -1822,41 +2074,38 @@ const ASSETS_GROUPERS = { : `*${extension}` ); while (path.length > 0) { - keys.push(path.join("/") + "/"); + keys.push(`${path.join("/")}/`); path.pop(); } - } else { - if (extension) keys.push(`*${extension}`); + } else if (extension) { + keys.push(`*${extension}`); } return keys; }, - createGroup: (key, children, assets) => { - return { - type: groupAssetsByPath ? "assets by path" : "assets by extension", - name: key, - children, - ...assetGroup(children, assets) - }; - } + createGroup: (key, children, assets) => ({ + type: groupAssetsByPath ? "assets by path" : "assets by extension", + name: key, + children, + ...assetGroup(children, assets) + }) }); } }, groupAssetsByInfo: (groupConfigs, context, options) => { + /** + * @param {string} name name + */ const groupByAssetInfoFlag = name => { groupConfigs.push({ - getKeys: asset => { - return asset.info && asset.info[name] ? ["1"] : undefined; - }, - createGroup: (key, children, assets) => { - return { - type: "assets by info", - info: { - [name]: !!key - }, - children, - ...assetGroup(children, assets) - }; - } + getKeys: asset => (asset.info && asset.info[name] ? ["1"] : undefined), + createGroup: (key, children, assets) => ({ + type: "assets by info", + info: { + [name]: Boolean(key) + }, + children, + ...assetGroup(children, assets) + }) }); }; groupByAssetInfoFlag("immutable"); @@ -1864,19 +2113,18 @@ const ASSETS_GROUPERS = { groupByAssetInfoFlag("hotModuleReplacement"); }, groupAssetsByChunk: (groupConfigs, context, options) => { + /** + * @param {keyof KnownStatsAsset} name name + */ const groupByNames = name => { groupConfigs.push({ - getKeys: asset => { - return asset[name]; - }, - createGroup: (key, children, assets) => { - return { - type: "assets by chunk", - [name]: [key], - children, - ...assetGroup(children, assets) - }; - } + getKeys: asset => /** @type {string[]} */ (asset[name]), + createGroup: (key, children, assets) => ({ + type: "assets by chunk", + [name]: [key], + children, + ...assetGroup(children, assets) + }) }); }; groupByNames("chunkNames"); @@ -1904,28 +2152,29 @@ const ASSETS_GROUPERS = { } }; -/** @type {function("module" | "chunk" | "root-of-chunk" | "nested"): Record void>} */ +/** @typedef {Record[], context: StatsFactoryContext, options: NormalizedStatsOptions) => void>} ModulesGroupers */ + +/** @type {function("module" | "chunk" | "root-of-chunk" | "nested"): ModulesGroupers} */ const MODULES_GROUPERS = type => ({ _: (groupConfigs, context, options) => { + /** + * @param {keyof KnownStatsModule} name name + * @param {string} type type + * @param {boolean=} exclude need exclude? + */ const groupByFlag = (name, type, exclude) => { groupConfigs.push({ - getKeys: module => { - return module[name] ? ["1"] : undefined; - }, - getOptions: () => { - return { - groupChildren: !exclude, - force: exclude - }; - }, - createGroup: (key, children, modules) => { - return { - type, - [name]: !!key, - ...(exclude ? { filteredChildren: modules.length } : { children }), - ...moduleGroup(children, modules) - }; - } + getKeys: module => (module[name] ? ["1"] : undefined), + getOptions: () => ({ + groupChildren: !exclude, + force: exclude + }), + createGroup: (key, children, modules) => ({ + type, + [name]: Boolean(key), + ...(exclude ? { filteredChildren: modules.length } : { children }), + ...moduleGroup(children, modules) + }) }); }; const { @@ -1962,19 +2211,21 @@ const MODULES_GROUPERS = type => ({ if (!module.moduleType) return; if (groupModulesByType) { return [module.moduleType.split("/", 1)[0]]; - } else if (module.moduleType === "runtime") { - return ["runtime"]; + } else if (module.moduleType === WEBPACK_MODULE_TYPE_RUNTIME) { + return [WEBPACK_MODULE_TYPE_RUNTIME]; } }, getOptions: key => { - const exclude = key === "runtime" && !options.runtimeModules; + const exclude = + key === WEBPACK_MODULE_TYPE_RUNTIME && !options.runtimeModules; return { groupChildren: !exclude, force: exclude }; }, createGroup: (key, children, modules) => { - const exclude = key === "runtime" && !options.runtimeModules; + const exclude = + key === WEBPACK_MODULE_TYPE_RUNTIME && !options.runtimeModules; return { type: `${key} modules`, moduleType: key, @@ -1986,29 +2237,29 @@ const MODULES_GROUPERS = type => ({ } if (groupModulesByLayer) { groupConfigs.push({ - getKeys: module => { - return [module.layer]; - }, - createGroup: (key, children, modules) => { - return { - type: "modules by layer", - layer: key, - children, - ...moduleGroup(children, modules) - }; - } + getKeys: module => /** @type {string[]} */ ([module.layer]), + createGroup: (key, children, modules) => ({ + type: "modules by layer", + layer: key, + children, + ...moduleGroup(children, modules) + }) }); } if (groupModulesByPath || groupModulesByExtension) { groupConfigs.push({ getKeys: module => { if (!module.name) return; - const resource = parseResource(module.name.split("!").pop()).path; + const resource = parseResource( + /** @type {string} */ (module.name.split("!").pop()) + ).path; + const dataUrl = /^data:[^,;]+/.exec(resource); + if (dataUrl) return [dataUrl[0]]; const extensionMatch = - groupModulesByExtension && /(\.[^.]+)(?:\?.*|$)/.exec(resource); + groupModulesByExtension && GROUP_EXTENSION_REGEXP.exec(resource); const extension = extensionMatch ? extensionMatch[1] : ""; const pathMatch = - groupModulesByPath && /(.+)[/\\][^/\\]+(?:\?.*|$)/.exec(resource); + groupModulesByPath && GROUP_PATH_REGEXP.exec(resource); const path = pathMatch ? pathMatch[1].split(/[/\\]/) : []; const keys = []; if (groupModulesByPath) { @@ -2019,20 +2270,23 @@ const MODULES_GROUPERS = type => ({ : `*${extension}` ); while (path.length > 0) { - keys.push(path.join("/") + "/"); + keys.push(`${path.join("/")}/`); path.pop(); } - } else { - if (extension) keys.push(`*${extension}`); + } else if (extension) { + keys.push(`*${extension}`); } return keys; }, createGroup: (key, children, modules) => { + const isDataUrl = key.startsWith("data:"); return { - type: groupModulesByPath - ? "modules by path" - : "modules by extension", - name: key, + type: isDataUrl + ? "modules by mime type" + : groupModulesByPath + ? "modules by path" + : "modules by extension", + name: isDataUrl ? key.slice(/* 'data:'.length */ 5) : key, children, ...moduleGroup(children, modules) }; @@ -2062,25 +2316,51 @@ const MODULES_GROUPERS = type => ({ } }); -/** @type {Record void>>} */ +/** @typedef {Record[], context: StatsFactoryContext, options: NormalizedStatsOptions) => void>} ModuleReasonsGroupers */ + +/** @type {ModuleReasonsGroupers} */ +const MODULE_REASONS_GROUPERS = { + groupReasonsByOrigin: groupConfigs => { + groupConfigs.push({ + getKeys: reason => /** @type {string[]} */ ([reason.module]), + createGroup: (key, children, reasons) => ({ + type: "from origin", + module: key, + children, + ...reasonGroup(children, reasons) + }) + }); + } +}; + +/** @type {Record} */ const RESULT_GROUPERS = { "compilation.assets": ASSETS_GROUPERS, "asset.related": ASSETS_GROUPERS, "compilation.modules": MODULES_GROUPERS("module"), "chunk.modules": MODULES_GROUPERS("chunk"), "chunk.rootModules": MODULES_GROUPERS("root-of-chunk"), - "module.modules": MODULES_GROUPERS("nested") + "module.modules": MODULES_GROUPERS("nested"), + "module.reasons": MODULE_REASONS_GROUPERS }; // remove a prefixed "!" that can be specified to reverse sort order +/** + * @param {string} field a field name + * @returns {field} normalized field + */ const normalizeFieldKey = field => { if (field[0] === "!") { - return field.substr(1); + return field.slice(1); } return field; }; // if a field is prefixed by a "!" reverse sort order +/** + * @param {string} field a field name + * @returns {boolean} result + */ const sortOrderRegular = field => { if (field[0] === "!") { return false; @@ -2090,7 +2370,7 @@ const sortOrderRegular = field => { /** * @param {string} field field name - * @returns {function(Object, Object): number} comparators + * @returns {function(object, object): 0 | 1 | -1} comparators */ const sortByField = field => { if (!field) { @@ -2118,8 +2398,8 @@ const sortByField = field => { return sortFn; }; +/** @type {Record[], context: StatsFactoryContext, options: NormalizedStatsOptions) => void>} */ const ASSET_SORTERS = { - /** @type {(comparators: Function[], context: StatsFactoryContext, options: NormalizedStatsOptions) => void} */ assetsSort: (comparators, context, { assetsSort }) => { comparators.push(sortByField(assetsSort)); }, @@ -2128,7 +2408,7 @@ const ASSET_SORTERS = { } }; -/** @type {Record void>>} */ +/** @type {Record[], context: StatsFactoryContext, options: NormalizedStatsOptions) => void>>} */ const RESULT_SORTERS = { "compilation.chunks": { chunksSort: (comparators, context, { chunksSort }) => { @@ -2205,8 +2485,14 @@ const ITEM_NAMES = { }; /** - * @param {Object[]} items items to be merged - * @returns {Object} an object + * @template T + * @typedef {{ name: T }} NamedObject + */ + +/** + * @template {{ name: string }} T + * @param {T[]} items items to be merged + * @returns {NamedObject} an object */ const mergeToObject = items => { const obj = Object.create(null); @@ -2216,7 +2502,10 @@ const mergeToObject = items => { return obj; }; -/** @type {Record any>} */ +/** + * @template {{ name: string }} T + * @type {Record NamedObject>} + */ const MERGER = { "compilation.entrypoints": mergeToObject, "compilation.namedChunkGroups": mergeToObject @@ -2232,7 +2521,11 @@ class DefaultStatsFactoryPlugin { compiler.hooks.compilation.tap("DefaultStatsFactoryPlugin", compilation => { compilation.hooks.statsFactory.tap( "DefaultStatsFactoryPlugin", - (stats, options, context) => { + /** + * @param {StatsFactory} stats stats factory + * @param {NormalizedStatsOptions} options stats options + */ + (stats, options) => { iterateConfig(SIMPLE_EXTRACTORS, options, (hookFor, fn) => { stats.hooks.extract .for(hookFor) @@ -2289,25 +2582,31 @@ class DefaultStatsFactoryPlugin { if (Array.isArray(options.children)) { stats.hooks.getItemFactory .for("compilation.children[].compilation") - .tap("DefaultStatsFactoryPlugin", (comp, { _index: idx }) => { - if (idx < options.children.length) { - return compilation.createStatsFactory( - compilation.createStatsOptions( - options.children[idx], - context - ) - ); + .tap( + "DefaultStatsFactoryPlugin", + /** + * @param {Compilation} comp compilation + * @param {StatsFactoryContext} options options + * @returns {StatsFactory | undefined} stats factory + */ + (comp, { _index: idx }) => { + const children = + /** @type {TODO} */ + (options.children); + if (idx < children.length) { + return compilation.createStatsFactory( + compilation.createStatsOptions(children[idx]) + ); + } } - }); + ); } else if (options.children !== true) { const childFactory = compilation.createStatsFactory( - compilation.createStatsOptions(options.children, context) + compilation.createStatsOptions(options.children) ); stats.hooks.getItemFactory .for("compilation.children[].compilation") - .tap("DefaultStatsFactoryPlugin", () => { - return childFactory; - }); + .tap("DefaultStatsFactoryPlugin", () => childFactory); } } } diff --git a/lib/stats/DefaultStatsPresetPlugin.js b/lib/stats/DefaultStatsPresetPlugin.js index 1e5e056a17b..70e56b8cb3e 100644 --- a/lib/stats/DefaultStatsPresetPlugin.js +++ b/lib/stats/DefaultStatsPresetPlugin.js @@ -11,15 +11,24 @@ const RequestShortener = require("../RequestShortener"); /** @typedef {import("../Compilation")} Compilation */ /** @typedef {import("../Compilation").CreateStatsOptionsContext} CreateStatsOptionsContext */ /** @typedef {import("../Compiler")} Compiler */ +/** @typedef {import("./DefaultStatsFactoryPlugin").StatsError} StatsError */ +/** + * @param {StatsOptions} options options + * @param {StatsOptions} defaults default options + */ const applyDefaults = (options, defaults) => { - for (const key of Object.keys(defaults)) { + for (const _k of Object.keys(defaults)) { + const key = /** @type {keyof StatsOptions} */ (_k); if (typeof options[key] === "undefined") { - options[key] = defaults[key]; + /** @type {TODO} */ + (options)[key] = defaults[key]; } } }; +/** @typedef {Record} NamedPresets */ +/** @type {NamedPresets} */ const NAMED_PRESETS = { verbose: { hash: true, @@ -47,9 +56,12 @@ const NAMED_PRESETS = { orphanModules: true, runtimeModules: true, exclude: false, + errorsSpace: Infinity, + warningsSpace: Infinity, modulesSpace: Infinity, chunkModulesSpace: Infinity, assetsSpace: Infinity, + reasonsSpace: Infinity, children: true }, detailed: { @@ -72,14 +84,19 @@ const NAMED_PRESETS = { logging: true, runtimeModules: true, exclude: false, - modulesSpace: Infinity, - assetsSpace: Infinity + errorsSpace: 1000, + warningsSpace: 1000, + modulesSpace: 1000, + assetsSpace: 1000, + reasonsSpace: 1000 }, minimal: { all: false, version: true, timings: true, modules: true, + errorsSpace: 0, + warningsSpace: 0, modulesSpace: 0, assets: true, assetsSpace: 0, @@ -93,6 +110,7 @@ const NAMED_PRESETS = { all: false, errors: true, errorsCount: true, + errorsSpace: Infinity, moduleTrace: true, logging: "error" }, @@ -100,8 +118,10 @@ const NAMED_PRESETS = { all: false, errors: true, errorsCount: true, + errorsSpace: Infinity, warnings: true, warningsCount: true, + warningsSpace: Infinity, logging: "warn" }, summary: { @@ -115,12 +135,35 @@ const NAMED_PRESETS = { } }; +/** + * @param {StatsOptions} all stats option + * @returns {boolean} true when enabled, otherwise false + */ const NORMAL_ON = ({ all }) => all !== false; +/** + * @param {StatsOptions} all stats option + * @returns {boolean} true when enabled, otherwise false + */ const NORMAL_OFF = ({ all }) => all === true; +/** + * @param {StatsOptions} all stats option + * @param {CreateStatsOptionsContext} forToString stats options context + * @returns {boolean} true when enabled, otherwise false + */ const ON_FOR_TO_STRING = ({ all }, { forToString }) => forToString ? all !== false : all === true; +/** + * @param {StatsOptions} all stats option + * @param {CreateStatsOptionsContext} forToString stats options context + * @returns {boolean} true when enabled, otherwise false + */ const OFF_FOR_TO_STRING = ({ all }, { forToString }) => forToString ? all === true : all !== false; +/** + * @param {StatsOptions} all stats option + * @param {CreateStatsOptionsContext} forToString stats options context + * @returns {boolean | "auto"} true when enabled, otherwise false + */ const AUTO_FOR_TO_STRING = ({ all }, { forToString }) => { if (all === false) return false; if (all === true) return true; @@ -128,13 +171,19 @@ const AUTO_FOR_TO_STRING = ({ all }, { forToString }) => { return true; }; -/** @type {Record any>} */ +/** @typedef {Record StatsOptions[keyof StatsOptions] | RequestShortener>} Defaults */ + +/** @type {Defaults} */ const DEFAULTS = { context: (options, context, compilation) => compilation.compiler.context, requestShortener: (options, context, compilation) => compilation.compiler.context === options.context ? compilation.requestShortener - : new RequestShortener(options.context, compilation.compiler.root), + : new RequestShortener( + /** @type {string} */ + (options.context), + compilation.compiler.root + ), performance: NORMAL_ON, hash: OFF_FOR_TO_STRING, env: NORMAL_OFF, @@ -186,14 +235,16 @@ const DEFAULTS = { runtime !== undefined ? runtime : forToString - ? all === true - : all !== false, + ? all === true + : all !== false, cachedModules: ({ all, cached }, { forToString }) => cached !== undefined ? cached : forToString ? all === true : all !== false, moduleAssets: OFF_FOR_TO_STRING, depth: OFF_FOR_TO_STRING, cachedAssets: OFF_FOR_TO_STRING, reasons: OFF_FOR_TO_STRING, + reasonsSpace: (o, { forToString }) => (forToString ? 15 : Infinity), + groupReasonsByOrigin: ON_FOR_TO_STRING, usedExports: OFF_FOR_TO_STRING, providedExports: OFF_FOR_TO_STRING, optimizationBailout: OFF_FOR_TO_STRING, @@ -222,14 +273,14 @@ const DEFAULTS = { colors: () => false }; +/** + * @param {string | ({ test: function(string): boolean }) | (function(string): boolean) | boolean} item item to normalize + * @returns {(function(string): boolean) | undefined} normalize fn + */ const normalizeFilter = item => { if (typeof item === "string") { const regExp = new RegExp( - `[\\\\/]${item.replace( - // eslint-disable-next-line no-useless-escape - /[-[\]{}()*+?.\\^$|]/g, - "\\$&" - )}([\\\\/]|$|!|\\?)` + `[\\\\/]${item.replace(/[-[\]{}()*+?.\\^$|]/g, "\\$&")}([\\\\/]|$|!|\\?)` ); return ident => regExp.test(ident); } @@ -244,6 +295,7 @@ const normalizeFilter = item => { } }; +/** @type {Record} */ const NORMALIZER = { excludeModules: value => { if (!Array.isArray(value)) { @@ -261,20 +313,32 @@ const NORMALIZER = { if (!Array.isArray(value)) { value = value ? [value] : []; } - return value.map(filter => { - if (typeof filter === "string") { - return (warning, warningString) => warningString.includes(filter); - } - if (filter instanceof RegExp) { - return (warning, warningString) => filter.test(warningString); - } - if (typeof filter === "function") { - return filter; + /** + * @callback WarningFilterFn + * @param {StatsError} warning warning + * @param {string} warningString warning string + * @returns {boolean} result + */ + return value.map( + /** + * @param {StatsOptions["warningsFilter"]} filter a warning filter + * @returns {WarningFilterFn} result + */ + filter => { + if (typeof filter === "string") { + return (warning, warningString) => warningString.includes(filter); + } + if (filter instanceof RegExp) { + return (warning, warningString) => filter.test(warningString); + } + if (typeof filter === "function") { + return filter; + } + throw new Error( + `Can only filter warnings with Strings or RegExps. (Given: ${filter})` + ); } - throw new Error( - `Can only filter warnings with Strings or RegExps. (Given: ${filter})` - ); - }); + ); }, logging: value => { if (value === true) value = "log"; @@ -297,7 +361,7 @@ class DefaultStatsPresetPlugin { apply(compiler) { compiler.hooks.compilation.tap("DefaultStatsPresetPlugin", compilation => { for (const key of Object.keys(NAMED_PRESETS)) { - const defaults = NAMED_PRESETS[key]; + const defaults = NAMED_PRESETS[/** @type {keyof NamedPresets} */ (key)]; compilation.hooks.statsPreset .for(key) .tap("DefaultStatsPresetPlugin", (options, context) => { diff --git a/lib/stats/DefaultStatsPrinterPlugin.js b/lib/stats/DefaultStatsPrinterPlugin.js index 399bd1845ee..419311a72a5 100644 --- a/lib/stats/DefaultStatsPrinterPlugin.js +++ b/lib/stats/DefaultStatsPrinterPlugin.js @@ -6,16 +6,27 @@ "use strict"; /** @typedef {import("../Compiler")} Compiler */ +/** @typedef {import("./DefaultStatsFactoryPlugin").KnownStatsChunkGroup} KnownStatsChunkGroup */ /** @typedef {import("./StatsPrinter")} StatsPrinter */ +/** @typedef {import("./StatsPrinter").KnownStatsPrinterColorFn} KnownStatsPrinterColorFn */ +/** @typedef {import("./StatsPrinter").KnownStatsPrinterFormaters} KnownStatsPrinterFormaters */ /** @typedef {import("./StatsPrinter").StatsPrinterContext} StatsPrinterContext */ +const DATA_URI_CONTENT_LENGTH = 16; +const MAX_MODULE_IDENTIFIER_LENGTH = 80; + +/** + * @param {number} n a number + * @param {string} singular singular + * @param {string} plural plural + * @returns {string} if n is 1, singular, else plural + */ const plural = (n, singular, plural) => (n === 1 ? singular : plural); /** * @param {Record} sizes sizes by source type - * @param {Object} options options - * @param {(number) => string=} options.formatSize size formatter - * @returns {string} text + * @param {StatsPrinterContext} options options + * @returns {string | undefined} text */ const printSizes = (sizes, { formatSize = n => `${n}` }) => { const keys = Object.keys(sizes); @@ -26,6 +37,51 @@ const printSizes = (sizes, { formatSize = n => `${n}` }) => { } }; +/** + * @param {string} resource resource + * @returns {string} resource name for display + */ +const getResourceName = resource => { + const dataUrl = /^data:[^,]+,/.exec(resource); + if (!dataUrl) return resource; + + const len = dataUrl[0].length + DATA_URI_CONTENT_LENGTH; + if (resource.length < len) return resource; + return `${resource.slice( + 0, + Math.min(resource.length - /* '..'.length */ 2, len) + )}..`; +}; + +/** + * @param {string} name module name + * @returns {[string,string]} prefix and module name + */ +const getModuleName = name => { + const [, prefix, resource] = + /** @type {[any, string, string]} */ + (/** @type {unknown} */ (/^(.*!)?([^!]*)$/.exec(name))); + + if (resource.length > MAX_MODULE_IDENTIFIER_LENGTH) { + const truncatedResource = `${resource.slice( + 0, + Math.min( + resource.length - /* '...(truncated)'.length */ 14, + MAX_MODULE_IDENTIFIER_LENGTH + ) + )}...(truncated)`; + + return [prefix, getResourceName(truncatedResource)]; + } + + return [prefix, getResourceName(resource)]; +}; + +/** + * @param {string} str string + * @param {function(string): string} fn function to apply to each line + * @returns {string} joined string + */ const mapLines = (str, fn) => str.split("\n").map(fn).join("\n"); /** @@ -34,12 +90,29 @@ const mapLines = (str, fn) => str.split("\n").map(fn).join("\n"); */ const twoDigit = n => (n >= 10 ? `${n}` : `0${n}`); -const isValidId = id => { - return typeof id === "number" || id; -}; +/** + * @param {string | number} id an id + * @returns {boolean | string} is i + */ +const isValidId = id => typeof id === "number" || id; + +/** + * @template T + * @param {Array | undefined} list of items + * @param {number} count number of items to show + * @returns {string} string representation of list + */ +const moreCount = (list, count) => + list && list.length > 0 ? `+ ${count}` : `${count}`; + +/** + * @template T + * @template {keyof T} K + * @typedef {{ [P in K]-?: T[P] }} WithRequired + */ -/** @type {Record string | void>} */ -const SIMPLE_PRINTERS = { +/** @type {Record & Required & WithRequired, printer: StatsPrinter) => string | undefined>} */ +const COMPILATION_SIMPLE_PRINTERS = { "compilation.summary!": ( _, { @@ -63,14 +136,16 @@ const SIMPLE_PRINTERS = { ) => { const root = type === "compilation.summary!"; const warningsMessage = - warningsCount > 0 + /** @type {number} */ (warningsCount) > 0 ? yellow( - `${warningsCount} ${plural(warningsCount, "warning", "warnings")}` - ) + `${warningsCount} ${plural(/** @type {number} */ (warningsCount), "warning", "warnings")}` + ) : ""; const errorsMessage = - errorsCount > 0 - ? red(`${errorsCount} ${plural(errorsCount, "error", "errors")}`) + /** @type {number} */ (errorsCount) > 0 + ? red( + `${errorsCount} ${plural(/** @type {number} */ (errorsCount), "error", "errors")}` + ) : ""; const timeMessage = root && time ? ` in ${formatTime(time)}` : ""; const hashMessage = hash ? ` (${hash})` : ""; @@ -81,10 +156,10 @@ const SIMPLE_PRINTERS = { root && name ? bold(name) : name - ? `Child ${bold(name)}` - : root - ? "" - : "Child"; + ? `Child ${bold(name)}` + : root + ? "" + : "Child"; const subjectMessage = nameMessage && versionMessage ? `${nameMessage} (${versionMessage})` @@ -99,7 +174,7 @@ const SIMPLE_PRINTERS = { } else if (errorsCount === 0 && warningsCount === 0) { statusMessage = `compiled ${green("successfully")}`; } else { - statusMessage = `compiled`; + statusMessage = "compiled"; } if ( builtAtMessage || @@ -118,7 +193,7 @@ const SIMPLE_PRINTERS = { count, "warning has", "warnings have" - )} detailed information that is not shown.\nUse 'stats.errorDetails: true' resp. '--stats-error-details' to show it.` + )} detailed information that is not shown.\nUse 'stats.errorDetails: true' resp. '--stats-error-details' to show it.` : undefined, "compilation.filteredErrorDetailsCount": (count, { yellow }) => count @@ -128,7 +203,7 @@ const SIMPLE_PRINTERS = { "error has", "errors have" )} detailed information that is not shown.\nUse 'stats.errorDetails: true' resp. '--stats-error-details' to show it.` - ) + ) : undefined, "compilation.env": (env, { bold }) => env @@ -142,7 +217,7 @@ const SIMPLE_PRINTERS = { : printer.print(context.type, Object.values(entrypoints), { ...context, chunkGroupKind: "Entrypoint" - }), + }), "compilation.namedChunkGroups": (namedChunkGroups, context, printer) => { if (!Array.isArray(namedChunkGroups)) { const { @@ -163,13 +238,27 @@ const SIMPLE_PRINTERS = { }, "compilation.assetsByChunkName": () => "", - "compilation.filteredModules": filteredModules => + "compilation.filteredModules": ( + filteredModules, + { compilation: { modules } } + ) => filteredModules > 0 - ? `${filteredModules} ${plural(filteredModules, "module", "modules")}` + ? `${moreCount(modules, filteredModules)} ${plural( + filteredModules, + "module", + "modules" + )}` : undefined, - "compilation.filteredAssets": (filteredAssets, { compilation: { assets } }) => + "compilation.filteredAssets": ( + filteredAssets, + { compilation: { assets } } + ) => filteredAssets > 0 - ? `${filteredAssets} ${plural(filteredAssets, "asset", "assets")}` + ? `${moreCount(assets, filteredAssets)} ${plural( + filteredAssets, + "asset", + "assets" + )}` : undefined, "compilation.logging": (logging, context, printer) => Array.isArray(logging) @@ -178,15 +267,16 @@ const SIMPLE_PRINTERS = { context.type, Object.entries(logging).map(([name, value]) => ({ ...value, name })), context - ), + ), "compilation.warningsInChildren!": (_, { yellow, compilation }) => { if ( !compilation.children && - compilation.warningsCount > 0 && + /** @type {number} */ (compilation.warningsCount) > 0 && compilation.warnings ) { const childWarnings = - compilation.warningsCount - compilation.warnings.length; + /** @type {number} */ (compilation.warningsCount) - + compilation.warnings.length; if (childWarnings > 0) { return yellow( `${childWarnings} ${plural( @@ -205,10 +295,12 @@ const SIMPLE_PRINTERS = { "compilation.errorsInChildren!": (_, { red, compilation }) => { if ( !compilation.children && - compilation.errorsCount > 0 && + /** @type {number} */ (compilation.errorsCount) > 0 && compilation.errors ) { - const childErrors = compilation.errorsCount - compilation.errors.length; + const childErrors = + /** @type {number} */ (compilation.errorsCount) - + compilation.errors.length; if (childErrors > 0) { return red( `${childErrors} ${plural( @@ -223,15 +315,16 @@ const SIMPLE_PRINTERS = { ); } } - }, + } +}; +/** @type {Record & Required & WithRequired, printer: StatsPrinter) => string | undefined>} */ +const ASSET_SIMPLE_PRINTERS = { "asset.type": type => type, "asset.name": (name, { formatFilename, asset: { isOverSizeLimit } }) => formatFilename(name, isOverSizeLimit), - "asset.size": ( - size, - { asset: { isOverSizeLimit }, yellow, green, formatSize } - ) => (isOverSizeLimit ? yellow(formatSize(size)) : formatSize(size)), + "asset.size": (size, { asset: { isOverSizeLimit }, yellow, formatSize }) => + isOverSizeLimit ? yellow(formatSize(size)) : formatSize(size), "asset.emitted": (emitted, { green, formatFlag }) => emitted ? green(formatFlag("emitted")) : undefined, "asset.comparedForEmit": (comparedForEmit, { yellow, formatFlag }) => @@ -251,7 +344,7 @@ const SIMPLE_PRINTERS = { sourceFilename === true ? "from source file" : `from: ${sourceFilename}` - ) + ) : undefined, "asset.info.development": (development, { green, formatFlag }) => development ? green(formatFlag("dev")) : undefined, @@ -262,28 +355,35 @@ const SIMPLE_PRINTERS = { "asset.separator!": () => "\n", "asset.filteredRelated": (filteredRelated, { asset: { related } }) => filteredRelated > 0 - ? `${filteredRelated} related ${plural( + ? `${moreCount(related, filteredRelated)} related ${plural( filteredRelated, "asset", "assets" - )}` + )}` : undefined, - "asset.filteredChildren": filteredChildren => + "asset.filteredChildren": (filteredChildren, { asset: { children } }) => filteredChildren > 0 - ? `${filteredChildren} ${plural(filteredChildren, "asset", "assets")}` + ? `${moreCount(children, filteredChildren)} ${plural( + filteredChildren, + "asset", + "assets" + )}` : undefined, assetChunk: (id, { formatChunkId }) => formatChunkId(id), assetChunkName: name => name, - assetChunkIdHint: name => name, + assetChunkIdHint: name => name +}; +/** @type {Record & Required & WithRequired, printer: StatsPrinter) => string | undefined>} */ +const MODULE_SIMPLE_PRINTERS = { "module.type": type => (type !== "module" ? type : undefined), "module.id": (id, { formatModuleId }) => isValidId(id) ? formatModuleId(id) : undefined, "module.name": (name, { bold }) => { - const [, prefix, resource] = /^(.*!)?([^!]*)$/.exec(name); - return (prefix || "") + bold(resource); + const [prefix, resource] = getModuleName(name); + return `${prefix || ""}${bold(resource || "")}`; }, "module.identifier": identifier => undefined, "module.layer": (layer, { formatLayer }) => @@ -306,6 +406,8 @@ const SIMPLE_PRINTERS = { built ? yellow(formatFlag("built")) : undefined, "module.codeGenerated": (codeGenerated, { formatFlag, yellow }) => codeGenerated ? yellow(formatFlag("code generated")) : undefined, + "module.buildTimeExecuted": (buildTimeExecuted, { formatFlag, green }) => + buildTimeExecuted ? green(formatFlag("build time executed")) : undefined, "module.cached": (cached, { formatFlag, green }) => cached ? green(formatFlag("cached")) : undefined, "module.assets": (assets, { formatFlag, magenta }) => @@ -314,22 +416,22 @@ const SIMPLE_PRINTERS = { formatFlag( `${assets.length} ${plural(assets.length, "asset", "assets")}` ) - ) + ) : undefined, "module.warnings": (warnings, { formatFlag, yellow }) => warnings === true ? yellow(formatFlag("warnings")) : warnings - ? yellow( - formatFlag(`${warnings} ${plural(warnings, "warning", "warnings")}`) - ) - : undefined, + ? yellow( + formatFlag(`${warnings} ${plural(warnings, "warning", "warnings")}`) + ) + : undefined, "module.errors": (errors, { formatFlag, red }) => errors === true ? red(formatFlag("errors")) : errors - ? red(formatFlag(`${errors} ${plural(errors, "error", "errors")}`)) - : undefined, + ? red(formatFlag(`${errors} ${plural(errors, "error", "errors")}`)) + : undefined, "module.providedExports": (providedExports, { formatFlag, cyan }) => { if (Array.isArray(providedExports)) { if (providedExports.length === 0) return cyan(formatFlag("no exports")); @@ -351,11 +453,11 @@ const SIMPLE_PRINTERS = { providedExportsCount === usedExports.length ) { return cyan(formatFlag("all exports used")); - } else { - return cyan( - formatFlag(`only some exports used: ${usedExports.join(", ")}`) - ); } + + return cyan( + formatFlag(`only some exports used: ${usedExports.join(", ")}`) + ); } } }, @@ -364,25 +466,44 @@ const SIMPLE_PRINTERS = { "module.issuerPath": (issuerPath, { module }) => module.profile ? undefined : "", "module.profile": profile => undefined, - "module.filteredModules": filteredModules => + "module.filteredModules": (filteredModules, { module: { modules } }) => filteredModules > 0 - ? `${filteredModules} nested ${plural( + ? `${moreCount(modules, filteredModules)} nested ${plural( filteredModules, "module", "modules" - )}` + )}` + : undefined, + "module.filteredReasons": (filteredReasons, { module: { reasons } }) => + filteredReasons > 0 + ? `${moreCount(reasons, filteredReasons)} ${plural( + filteredReasons, + "reason", + "reasons" + )}` : undefined, - "module.filteredChildren": filteredChildren => + "module.filteredChildren": (filteredChildren, { module: { children } }) => filteredChildren > 0 - ? `${filteredChildren} ${plural(filteredChildren, "module", "modules")}` + ? `${moreCount(children, filteredChildren)} ${plural( + filteredChildren, + "module", + "modules" + )}` : undefined, - "module.separator!": () => "\n", + "module.separator!": () => "\n" +}; +/** @type {Record & Required & WithRequired, printer: StatsPrinter) => string | undefined>} */ +const MODULE_ISSUER_PRINTERS = { "moduleIssuer.id": (id, { formatModuleId }) => formatModuleId(id), - "moduleIssuer.profile.total": (value, { formatTime }) => formatTime(value), + "moduleIssuer.profile.total": (value, { formatTime }) => formatTime(value) +}; +/** @type {Record & Required & WithRequired, printer: StatsPrinter) => string | undefined>} */ +const MODULE_REASON_PRINTERS = { "moduleReason.type": type => type, - "moduleReason.userRequest": (userRequest, { cyan }) => cyan(userRequest), + "moduleReason.userRequest": (userRequest, { cyan }) => + cyan(getResourceName(userRequest)), "moduleReason.moduleId": (moduleId, { formatModuleId }) => isValidId(moduleId) ? formatModuleId(moduleId) : undefined, "moduleReason.module": (module, { magenta }) => magenta(module), @@ -391,7 +512,21 @@ const SIMPLE_PRINTERS = { "moduleReason.active": (active, { formatFlag }) => active ? undefined : formatFlag("inactive"), "moduleReason.resolvedModule": (module, { magenta }) => magenta(module), + "moduleReason.filteredChildren": ( + filteredChildren, + { moduleReason: { children } } + ) => + filteredChildren > 0 + ? `${moreCount(children, filteredChildren)} ${plural( + filteredChildren, + "reason", + "reasons" + )}` + : undefined +}; +/** @type {Record & Required & WithRequired, printer: StatsPrinter) => string | undefined>} */ +const MODULE_PROFILE_PRINTERS = { "module.profile.total": (value, { formatTime }) => formatTime(value), "module.profile.resolving": (value, { formatTime }) => `resolving: ${formatTime(value)}`, @@ -406,8 +541,11 @@ const SIMPLE_PRINTERS = { "module.profile.additionalResolving": (value, { formatTime }) => value ? `additional resolving: ${formatTime(value)}` : undefined, "module.profile.additionalIntegration": (value, { formatTime }) => - value ? `additional integration: ${formatTime(value)}` : undefined, + value ? `additional integration: ${formatTime(value)}` : undefined +}; +/** @type {Record & Required & WithRequired, printer: StatsPrinter) => string | undefined>} */ +const CHUNK_GROUP_PRINTERS = { "chunkGroup.kind!": (_, { chunkGroupKind }) => chunkGroupKind, "chunkGroup.separator!": () => "\n", "chunkGroup.name": (name, { bold }) => bold(name), @@ -417,17 +555,29 @@ const SIMPLE_PRINTERS = { size ? formatSize(size) : undefined, "chunkGroup.auxiliaryAssetsSize": (size, { formatSize }) => size ? `(${formatSize(size)})` : undefined, - "chunkGroup.filteredAssets": n => - n > 0 ? `${n} ${plural(n, "asset", "assets")}` : undefined, - "chunkGroup.filteredAuxiliaryAssets": n => - n > 0 ? `${n} auxiliary ${plural(n, "asset", "assets")}` : undefined, + "chunkGroup.filteredAssets": (n, { chunkGroup: { assets } }) => + n > 0 + ? `${moreCount(assets, n)} ${plural(n, "asset", "assets")}` + : undefined, + "chunkGroup.filteredAuxiliaryAssets": ( + n, + { chunkGroup: { auxiliaryAssets } } + ) => + n > 0 + ? `${moreCount(auxiliaryAssets, n)} auxiliary ${plural( + n, + "asset", + "assets" + )}` + : undefined, "chunkGroup.is!": () => "=", "chunkGroupAsset.name": (asset, { green }) => green(asset), "chunkGroupAsset.size": (size, { formatSize, chunkGroup }) => - chunkGroup.assets.length > 1 || + chunkGroup.assets && + (chunkGroup.assets.length > 1 || (chunkGroup.auxiliaryAssets && chunkGroup.auxiliaryAssets.length > 0) ? formatSize(size) - : undefined, + : undefined), "chunkGroup.children": (children, context, printer) => Array.isArray(children) ? undefined @@ -438,13 +588,16 @@ const SIMPLE_PRINTERS = { children: children[key] })), context - ), + ), "chunkGroupChildGroup.type": type => `${type}:`, "chunkGroupChild.assets[]": (file, { formatFilename }) => formatFilename(file), "chunkGroupChild.chunks[]": (id, { formatChunkId }) => formatChunkId(id), - "chunkGroupChild.name": name => (name ? `(name: ${name})` : undefined), + "chunkGroupChild.name": name => (name ? `(name: ${name})` : undefined) +}; +/** @type {Record & Required & WithRequired, printer: StatsPrinter) => string | undefined>} */ +const CHUNK_PRINTERS = { "chunk.id": (id, { formatChunkId }) => formatChunkId(id), "chunk.files[]": (file, { formatFilename }) => formatFilename(file), "chunk.names[]": name => name, @@ -467,7 +620,7 @@ const SIMPLE_PRINTERS = { children: childrenByOrder[key] })), context - ), + ), "chunk.childrenByOrder[].type": type => `${type}:`, "chunk.childrenByOrder[].children[]": (id, { formatChunkId }) => isValidId(id) ? formatChunkId(id) : undefined, @@ -480,13 +633,13 @@ const SIMPLE_PRINTERS = { "chunk.recorded": (recorded, { formatFlag, green }) => recorded ? green(formatFlag("recorded")) : undefined, "chunk.reason": (reason, { yellow }) => (reason ? yellow(reason) : undefined), - "chunk.filteredModules": filteredModules => + "chunk.filteredModules": (filteredModules, { chunk: { modules } }) => filteredModules > 0 - ? `${filteredModules} chunk ${plural( + ? `${moreCount(modules, filteredModules)} chunk ${plural( filteredModules, "module", "modules" - )}` + )}` : undefined, "chunk.separator!": () => "\n", @@ -494,8 +647,11 @@ const SIMPLE_PRINTERS = { "chunkOrigin.moduleId": (moduleId, { formatModuleId }) => isValidId(moduleId) ? formatModuleId(moduleId) : undefined, "chunkOrigin.moduleName": (moduleName, { bold }) => bold(moduleName), - "chunkOrigin.loc": loc => loc, + "chunkOrigin.loc": loc => loc +}; +/** @type {Record & Required & WithRequired, printer: StatsPrinter) => string | undefined>} */ +const ERROR_PRINTERS = { "error.compilerPath": (compilerPath, { bold }) => compilerPath ? bold(`(${compilerPath})`) : undefined, "error.chunkId": (chunkId, { formatChunkId }) => @@ -505,19 +661,23 @@ const SIMPLE_PRINTERS = { "error.chunkInitial": (chunkInitial, { formatFlag }) => chunkInitial ? formatFlag("initial") : undefined, "error.file": (file, { bold }) => bold(file), - "error.moduleName": (moduleName, { bold }) => { - return moduleName.includes("!") + "error.moduleName": (moduleName, { bold }) => + moduleName.includes("!") ? `${bold(moduleName.replace(/^(\s|\S)*!/, ""))} (${moduleName})` - : `${bold(moduleName)}`; - }, + : `${bold(moduleName)}`, "error.loc": (loc, { green }) => green(loc), "error.message": (message, { bold, formatError }) => - message.includes("\u001b[") ? message : bold(formatError(message)), + message.includes("\u001B[") ? message : bold(formatError(message)), "error.details": (details, { formatError }) => formatError(details), + "error.filteredDetails": filteredDetails => + filteredDetails ? `+ ${filteredDetails} hidden lines` : undefined, "error.stack": stack => stack, "error.moduleTrace": moduleTrace => undefined, - "error.separator!": () => "\n", + "error.separator!": () => "\n" +}; +/** @type {Record & Required & WithRequired, printer: StatsPrinter) => string | undefined>} */ +const LOG_ENTRY_PRINTERS = { "loggingEntry(error).loggingEntry.message": (message, { red }) => mapLines(message, x => ` ${red(x)}`), "loggingEntry(warn).loggingEntry.message": (message, { yellow }) => @@ -547,20 +707,26 @@ const SIMPLE_PRINTERS = { "loggingEntry.trace[]": trace => trace ? mapLines(trace, x => `| ${x}`) : undefined, - "moduleTraceItem.originName": originName => originName, - loggingGroup: loggingGroup => loggingGroup.entries.length === 0 ? "" : undefined, "loggingGroup.debug": (flag, { red }) => (flag ? red("DEBUG") : undefined), "loggingGroup.name": (name, { bold }) => bold(`LOG from ${name}`), "loggingGroup.separator!": () => "\n", "loggingGroup.filteredEntries": filteredEntries => - filteredEntries > 0 ? `+ ${filteredEntries} hidden lines` : undefined, + filteredEntries > 0 ? `+ ${filteredEntries} hidden lines` : undefined +}; +/** @type {Record & Required & WithRequired, printer: StatsPrinter) => string | undefined>} */ +const MODULE_TRACE_ITEM_PRINTERS = { + "moduleTraceItem.originName": originName => originName +}; + +/** @type {Record & Required & WithRequired, printer: StatsPrinter) => string | undefined>} */ +const MODULE_TRACE_DEPENDENCY_PRINTERS = { "moduleTraceDependency.loc": loc => loc }; -/** @type {Record} */ +/** @type {Record} */ const ITEM_NAMES = { "compilation.assets[]": "asset", "compilation.modules[]": "module", @@ -588,6 +754,7 @@ const ITEM_NAMES = { "module.modules[]": "module", "module.children[]": "module", "module.reasons[]": "moduleReason", + "moduleReason.children[]": "moduleReason", "module.issuerPath[]": "moduleIssuer", "chunk.origins[]": "chunkOrigin", "chunk.modules[]": "module", @@ -613,6 +780,8 @@ const ERROR_PREFERRED_ORDER = [ "separator!", "details", "separator!", + "filteredDetails", + "separator!", "stack", "separator!", "missing", @@ -719,6 +888,7 @@ const PREFERRED_ORDERS = { "usedExports", "optimizationBailout", "reasons", + "filteredReasons", "issuerPath", "profile", "modules", @@ -732,7 +902,9 @@ const PREFERRED_ORDERS = { "module", "resolvedModule", "loc", - "explanation" + "explanation", + "children", + "filteredChildren" ], "module.profile": [ "total", @@ -783,19 +955,27 @@ const PREFERRED_ORDERS = { loggingEntry: ["message", "trace", "children"] }; +/** @typedef {(items: string[]) => string | undefined} SimpleItemsJoiner */ + +/** @type {SimpleItemsJoiner} */ const itemsJoinOneLine = items => items.filter(Boolean).join(" "); +/** @type {SimpleItemsJoiner} */ const itemsJoinOneLineBrackets = items => items.length > 0 ? `(${items.filter(Boolean).join(" ")})` : undefined; +/** @type {SimpleItemsJoiner} */ const itemsJoinMoreSpacing = items => items.filter(Boolean).join("\n\n"); +/** @type {SimpleItemsJoiner} */ const itemsJoinComma = items => items.filter(Boolean).join(", "); +/** @type {SimpleItemsJoiner} */ const itemsJoinCommaBrackets = items => items.length > 0 ? `(${items.filter(Boolean).join(", ")})` : undefined; +/** @type {function(string): SimpleItemsJoiner} */ const itemsJoinCommaBracketsWithName = name => items => items.length > 0 ? `(${name}: ${items.filter(Boolean).join(", ")})` : undefined; -/** @type {Record string>} */ +/** @type {Record} */ const SIMPLE_ITEMS_JOINER = { "chunk.parents": itemsJoinOneLine, "chunk.siblings": itemsJoinOneLine, @@ -816,9 +996,8 @@ const SIMPLE_ITEMS_JOINER = { "asset.chunkNames": itemsJoinCommaBracketsWithName("name"), "asset.auxiliaryChunkNames": itemsJoinCommaBracketsWithName("auxiliary name"), "asset.chunkIdHints": itemsJoinCommaBracketsWithName("id hint"), - "asset.auxiliaryChunkIdHints": itemsJoinCommaBracketsWithName( - "auxiliary id hint" - ), + "asset.auxiliaryChunkIdHints": + itemsJoinCommaBracketsWithName("auxiliary id hint"), "module.chunks": itemsJoinOneLine, "module.issuerPath": items => items @@ -828,18 +1007,27 @@ const SIMPLE_ITEMS_JOINER = { "compilation.errors": itemsJoinMoreSpacing, "compilation.warnings": itemsJoinMoreSpacing, "compilation.logging": itemsJoinMoreSpacing, - "compilation.children": items => indent(itemsJoinMoreSpacing(items), " "), + "compilation.children": items => + indent(/** @type {string} */ (itemsJoinMoreSpacing(items)), " "), "moduleTraceItem.dependencies": itemsJoinOneLine, "loggingEntry.children": items => indent(items.filter(Boolean).join("\n"), " ", false) }; +/** + * @param {Item[]} items items + * @returns {string} result + */ const joinOneLine = items => items .map(item => item.content) .filter(Boolean) .join(" "); +/** + * @param {Item[]} items items + * @returns {string} result + */ const joinInBrackets = items => { const res = []; let mode = 0; @@ -882,13 +1070,24 @@ const joinInBrackets = items => { return res.join(""); }; +/** + * @param {string} str a string + * @param {string} prefix prefix + * @param {boolean=} noPrefixInFirstLine need prefix in the first line? + * @returns {string} result + */ const indent = (str, prefix, noPrefixInFirstLine) => { - const rem = str.replace(/\n([^\n])/g, "\n" + prefix + "$1"); + const rem = str.replace(/\n([^\n])/g, `\n${prefix}$1`); if (noPrefixInFirstLine) return rem; const ind = str[0] === "\n" ? "" : prefix; return ind + rem; }; +/** + * @param {(false | Item)[]} items items + * @param {string} indenter indenter + * @returns {string} result + */ const joinExplicitNewLine = (items, indenter) => { let firstInLine = true; let first = true; @@ -903,20 +1102,34 @@ const joinExplicitNewLine = (items, indenter) => { first = false; const noJoiner = firstInLine || content.startsWith("\n"); firstInLine = content.endsWith("\n"); - return noJoiner ? content : " " + content; + return noJoiner ? content : ` ${content}`; }) .filter(Boolean) .join("") .trim(); }; -const joinError = error => (items, { red, yellow }) => - `${error ? red("ERROR") : yellow("WARNING")} in ${joinExplicitNewLine( - items, - "" - )}`; +/** + * @param {boolean} error is an error + * @returns {SimpleElementJoiner} joiner + */ +const joinError = + error => + /** + * @param {Item[]} items items + * @param {Required} ctx context + * @returns {string} result + */ + (items, { red, yellow }) => + `${error ? red("ERROR") : yellow("WARNING")} in ${joinExplicitNewLine( + items, + "" + )}`; -/** @type {Record string>} */ +/** @typedef {{ element: string, content: string }} Item */ +/** @typedef {(items: Item[], context: Required) => string} SimpleElementJoiner */ + +/** @type {Record} */ const SIMPLE_ELEMENT_JOINERS = { compilation: items => { const result = []; @@ -993,33 +1206,52 @@ const SIMPLE_ELEMENT_JOINERS = { }, chunk: items => { let hasEntry = false; - return ( - "chunk " + - joinExplicitNewLine( - items.filter(item => { - switch (item.element) { - case "entry": - if (item.content) hasEntry = true; - break; - case "initial": - if (hasEntry) return false; - break; - } - return true; - }), - " " - ) - ); + return `chunk ${joinExplicitNewLine( + items.filter(item => { + switch (item.element) { + case "entry": + if (item.content) hasEntry = true; + break; + case "initial": + if (hasEntry) return false; + break; + } + return true; + }), + " " + )}`; }, "chunk.childrenByOrder[]": items => `(${joinOneLine(items)})`, chunkGroup: items => joinExplicitNewLine(items, " "), chunkGroupAsset: joinOneLine, chunkGroupChildGroup: joinOneLine, chunkGroupChild: joinOneLine, + // moduleReason: (items, { moduleReason }) => { + // let hasName = false; + // return joinOneLine( + // items.filter(item => { + // switch (item.element) { + // case "moduleId": + // if (moduleReason.moduleId === moduleReason.module && item.content) + // hasName = true; + // break; + // case "module": + // if (hasName) return false; + // break; + // case "resolvedModule": + // return ( + // moduleReason.module !== moduleReason.resolvedModule && + // item.content + // ); + // } + // return true; + // }) + // ); + // }, moduleReason: (items, { moduleReason }) => { let hasName = false; - return joinOneLine( - items.filter(item => { + return joinExplicitNewLine( + items.map(item => { switch (item.element) { case "moduleId": if (moduleReason.moduleId === moduleReason.module && item.content) @@ -1029,34 +1261,46 @@ const SIMPLE_ELEMENT_JOINERS = { if (hasName) return false; break; case "resolvedModule": - return ( - moduleReason.module !== moduleReason.resolvedModule && - item.content - ); + if (moduleReason.module === moduleReason.resolvedModule) + return false; + break; + case "children": + if (item.content) { + return { + ...item, + content: `\n${item.content}\n` + }; + } + break; } - return true; - }) + return item; + }), + " " ); }, "module.profile": joinInBrackets, moduleIssuer: joinOneLine, - chunkOrigin: items => "> " + joinOneLine(items), + chunkOrigin: items => `> ${joinOneLine(items)}`, "errors[].error": joinError(true), "warnings[].error": joinError(false), - loggingGroup: items => joinExplicitNewLine(items, "").trimRight(), - moduleTraceItem: items => " @ " + joinOneLine(items), + loggingGroup: items => joinExplicitNewLine(items, "").trimEnd(), + moduleTraceItem: items => ` @ ${joinOneLine(items)}`, moduleTraceDependency: joinOneLine }; +/** @typedef {"bold" | "yellow" | "red" | "green" | "cyan" | "magenta"} ColorNames */ + +/** @type {Record} */ const AVAILABLE_COLORS = { - bold: "\u001b[1m", - yellow: "\u001b[1m\u001b[33m", - red: "\u001b[1m\u001b[31m", - green: "\u001b[1m\u001b[32m", - cyan: "\u001b[1m\u001b[36m", - magenta: "\u001b[1m\u001b[35m" + bold: "\u001B[1m", + yellow: "\u001B[1m\u001B[33m", + red: "\u001B[1m\u001B[31m", + green: "\u001B[1m\u001B[32m", + cyan: "\u001B[1m\u001B[36m", + magenta: "\u001B[1m\u001B[35m" }; +/** @type {Record & StatsPrinterContext, ...any): string>} */ const AVAILABLE_FORMATS = { formatChunkId: (id, { yellow }, direction) => { switch (direction) { @@ -1100,13 +1344,12 @@ const AVAILABLE_FORMATS = { else if (time < times[2]) return bold(`${time}${unit}`); else if (time < times[1]) return green(`${time}${unit}`); else if (time < times[0]) return yellow(`${time}${unit}`); - else return red(`${time}${unit}`); - } else { - return `${boldQuantity ? bold(time) : time}${unit}`; + return red(`${time}${unit}`); } + return `${boldQuantity ? bold(time) : time}${unit}`; }, formatError: (message, { green, yellow, red }) => { - if (message.includes("\u001b[")) return message; + if (message.includes("\u001B[")) return message; const highlights = [ { regExp: /(Did you mean .+)/g, format: green }, { @@ -1115,7 +1358,7 @@ const AVAILABLE_FORMATS = { }, { regExp: /(\(module has no exports\))/g, format: red }, { regExp: /\(possible exports: (.+)\)/g, format: green }, - { regExp: /\s*(.+ doesn't exist)/g, format: red }, + { regExp: /(?:^|\n)(.* doesn't exist)/g, format: red }, { regExp: /('\w+' option has not been set)/g, format: red }, { regExp: /(Emitted value instead of an instance of Error)/g, @@ -1128,28 +1371,42 @@ const AVAILABLE_FORMATS = { format: red }, { - regExp: /\b(error|failed|unexpected|invalid|not found|not supported|not available|not possible|not implemented|doesn't support|conflict|conflicting|not existing|duplicate)\b/gi, + regExp: + /\b(error|failed|unexpected|invalid|not found|not supported|not available|not possible|not implemented|doesn't support|conflict|conflicting|not existing|duplicate)\b/gi, format: red } ]; for (const { regExp, format } of highlights) { - message = message.replace(regExp, (match, content) => { - return match.replace(content, format(content)); - }); + message = message.replace( + regExp, + /** + * @param {string} match match + * @param {string} content content + * @returns {string} result + */ + (match, content) => match.replace(content, format(content)) + ); } return message; } }; +/** @typedef {function(string): string} ResultModifierFn */ +/** @type {Record} */ const RESULT_MODIFIER = { - "module.modules": result => { - return indent(result, "| "); - } + "module.modules": result => indent(result, "| ") }; +/** + * @param {string[]} array array + * @param {string[]} preferredOrder preferred order + * @returns {string[]} result + */ const createOrder = (array, preferredOrder) => { const originalArray = array.slice(); + /** @type {Set} */ const set = new Set(array); + /** @type {Set} */ const usedSet = new Set(); array.length = 0; for (const element of preferredOrder) { @@ -1176,49 +1433,218 @@ class DefaultStatsPrinterPlugin { compiler.hooks.compilation.tap("DefaultStatsPrinterPlugin", compilation => { compilation.hooks.statsPrinter.tap( "DefaultStatsPrinterPlugin", - (stats, options, context) => { + (stats, options) => { // Put colors into context stats.hooks.print .for("compilation") .tap("DefaultStatsPrinterPlugin", (compilation, context) => { for (const color of Object.keys(AVAILABLE_COLORS)) { + const name = /** @type {ColorNames} */ (color); + /** @type {string | undefined} */ let start; if (options.colors) { if ( typeof options.colors === "object" && - typeof options.colors[color] === "string" + typeof options.colors[name] === "string" ) { - start = options.colors[color]; + start = options.colors[name]; } else { - start = AVAILABLE_COLORS[color]; + start = AVAILABLE_COLORS[name]; } } if (start) { + /** + * @param {string} str string + * @returns {string} string with color + */ context[color] = str => `${start}${ typeof str === "string" ? str.replace( - /((\u001b\[39m|\u001b\[22m|\u001b\[0m)+)/g, + /((\u001B\[39m|\u001B\[22m|\u001B\[0m)+)/g, `$1${start}` - ) + ) : str - }\u001b[39m\u001b[22m`; + }\u001B[39m\u001B[22m`; } else { + /** + * @param {string} str string + * @returns {string} str string + */ context[color] = str => str; } } for (const format of Object.keys(AVAILABLE_FORMATS)) { - context[format] = (content, ...args) => - AVAILABLE_FORMATS[format](content, context, ...args); + context[format] = + /** + * @param {string | number} content content + * @param {...TODO} args args + * @returns {string} result + */ + (content, ...args) => + AVAILABLE_FORMATS[format]( + content, + /** @type {Required & StatsPrinterContext} */ + (context), + ...args + ); } context.timeReference = compilation.time; }); - for (const key of Object.keys(SIMPLE_PRINTERS)) { + for (const key of Object.keys(COMPILATION_SIMPLE_PRINTERS)) { + stats.hooks.print + .for(key) + .tap("DefaultStatsPrinterPlugin", (obj, ctx) => + COMPILATION_SIMPLE_PRINTERS[key]( + obj, + /** @type {Required & Required & WithRequired} */ + (ctx), + stats + ) + ); + } + + for (const key of Object.keys(ASSET_SIMPLE_PRINTERS)) { + stats.hooks.print + .for(key) + .tap("DefaultStatsPrinterPlugin", (obj, ctx) => + ASSET_SIMPLE_PRINTERS[key]( + obj, + /** @type {Required & Required & WithRequired} */ + (ctx), + stats + ) + ); + } + + for (const key of Object.keys(MODULE_SIMPLE_PRINTERS)) { + stats.hooks.print + .for(key) + .tap("DefaultStatsPrinterPlugin", (obj, ctx) => + MODULE_SIMPLE_PRINTERS[key]( + obj, + /** @type {Required & Required & WithRequired} */ + (ctx), + stats + ) + ); + } + + for (const key of Object.keys(MODULE_ISSUER_PRINTERS)) { stats.hooks.print .for(key) .tap("DefaultStatsPrinterPlugin", (obj, ctx) => - SIMPLE_PRINTERS[key](obj, ctx, stats) + MODULE_ISSUER_PRINTERS[key]( + obj, + /** @type {Required & Required & WithRequired} */ + (ctx), + stats + ) + ); + } + + for (const key of Object.keys(MODULE_REASON_PRINTERS)) { + stats.hooks.print + .for(key) + .tap("DefaultStatsPrinterPlugin", (obj, ctx) => + MODULE_REASON_PRINTERS[key]( + obj, + /** @type {Required & Required & WithRequired} */ + (ctx), + stats + ) + ); + } + + for (const key of Object.keys(MODULE_PROFILE_PRINTERS)) { + stats.hooks.print + .for(key) + .tap("DefaultStatsPrinterPlugin", (obj, ctx) => + MODULE_PROFILE_PRINTERS[key]( + obj, + /** @type {Required & Required & WithRequired} */ + (ctx), + stats + ) + ); + } + + for (const key of Object.keys(CHUNK_GROUP_PRINTERS)) { + stats.hooks.print + .for(key) + .tap("DefaultStatsPrinterPlugin", (obj, ctx) => + CHUNK_GROUP_PRINTERS[key]( + obj, + /** @type {Required & Required & WithRequired} */ + (ctx), + stats + ) + ); + } + + for (const key of Object.keys(CHUNK_PRINTERS)) { + stats.hooks.print + .for(key) + .tap("DefaultStatsPrinterPlugin", (obj, ctx) => + CHUNK_PRINTERS[key]( + obj, + /** @type {Required & Required & WithRequired} */ + (ctx), + stats + ) + ); + } + + for (const key of Object.keys(ERROR_PRINTERS)) { + stats.hooks.print + .for(key) + .tap("DefaultStatsPrinterPlugin", (obj, ctx) => + ERROR_PRINTERS[key]( + obj, + /** @type {Required & Required & WithRequired} */ + (ctx), + stats + ) + ); + } + + for (const key of Object.keys(LOG_ENTRY_PRINTERS)) { + stats.hooks.print + .for(key) + .tap("DefaultStatsPrinterPlugin", (obj, ctx) => + LOG_ENTRY_PRINTERS[key]( + obj, + /** @type {Required & Required & WithRequired} */ + (ctx), + stats + ) + ); + } + + for (const key of Object.keys(MODULE_TRACE_DEPENDENCY_PRINTERS)) { + stats.hooks.print + .for(key) + .tap("DefaultStatsPrinterPlugin", (obj, ctx) => + MODULE_TRACE_DEPENDENCY_PRINTERS[key]( + obj, + /** @type {Required & Required & WithRequired} */ + (ctx), + stats + ) + ); + } + + for (const key of Object.keys(MODULE_TRACE_ITEM_PRINTERS)) { + stats.hooks.print + .for(key) + .tap("DefaultStatsPrinterPlugin", (obj, ctx) => + MODULE_TRACE_ITEM_PRINTERS[key]( + obj, + /** @type {Required & Required & WithRequired} */ + (ctx), + stats + ) ); } @@ -1252,7 +1678,7 @@ class DefaultStatsPrinterPlugin { const joiner = SIMPLE_ELEMENT_JOINERS[key]; stats.hooks.printElements .for(key) - .tap("DefaultStatsPrinterPlugin", joiner); + .tap("DefaultStatsPrinterPlugin", /** @type {TODO} */ (joiner)); } for (const key of Object.keys(RESULT_MODIFIER)) { diff --git a/lib/stats/StatsFactory.js b/lib/stats/StatsFactory.js index 11399d134da..18f21fb9df5 100644 --- a/lib/stats/StatsFactory.js +++ b/lib/stats/StatsFactory.js @@ -11,82 +11,108 @@ const smartGrouping = require("../util/smartGrouping"); /** @typedef {import("../Chunk")} Chunk */ /** @typedef {import("../Compilation")} Compilation */ +/** @typedef {import("../Compilation").NormalizedStatsOptions} NormalizedStatsOptions */ /** @typedef {import("../Module")} Module */ /** @typedef {import("../WebpackError")} WebpackError */ +/** @typedef {import("../util/comparators").Comparator} Comparator */ /** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */ - /** @typedef {import("../util/smartGrouping").GroupConfig} GroupConfig */ /** - * @typedef {Object} KnownStatsFactoryContext + * @typedef {object} KnownStatsFactoryContext * @property {string} type - * @property {function(string): string=} makePathsRelative - * @property {Compilation=} compilation - * @property {Set=} rootModules - * @property {Map=} compilationFileToChunks - * @property {Map=} compilationAuxiliaryFileToChunks - * @property {RuntimeSpec=} runtime - * @property {function(Compilation): WebpackError[]=} cachedGetErrors - * @property {function(Compilation): WebpackError[]=} cachedGetWarnings + * @property {function(string): string} makePathsRelative + * @property {Compilation} compilation + * @property {Set} rootModules + * @property {Map} compilationFileToChunks + * @property {Map} compilationAuxiliaryFileToChunks + * @property {RuntimeSpec} runtime + * @property {function(Compilation): WebpackError[]} cachedGetErrors + * @property {function(Compilation): WebpackError[]} cachedGetWarnings + */ + +/** @typedef {Record & KnownStatsFactoryContext} StatsFactoryContext */ + +/** @typedef {any} CreatedObject */ +/** @typedef {any} FactoryData */ +/** @typedef {any} FactoryDataItem */ +/** @typedef {any} Result */ +/** @typedef {Record} ObjectForExtract */ + +/** + * @typedef {object} StatsFactoryHooks + * @property {HookMap>} extract + * @property {HookMap>} filter + * @property {HookMap>} sort + * @property {HookMap>} filterSorted + * @property {HookMap>} groupResults + * @property {HookMap>} sortResults + * @property {HookMap>} filterResults + * @property {HookMap>} merge + * @property {HookMap>} result + * @property {HookMap>} getItemName + * @property {HookMap>} getItemFactory */ -/** @typedef {KnownStatsFactoryContext & Record} StatsFactoryContext */ +/** + * @template T + * @typedef {Map} Caches + */ class StatsFactory { constructor() { + /** @type {StatsFactoryHooks} */ this.hooks = Object.freeze({ - /** @type {HookMap>} */ extract: new HookMap( () => new SyncBailHook(["object", "data", "context"]) ), - /** @type {HookMap>} */ filter: new HookMap( () => new SyncBailHook(["item", "context", "index", "unfilteredIndex"]) ), - /** @type {HookMap>} */ sort: new HookMap(() => new SyncBailHook(["comparators", "context"])), - /** @type {HookMap>} */ filterSorted: new HookMap( () => new SyncBailHook(["item", "context", "index", "unfilteredIndex"]) ), - /** @type {HookMap>} */ groupResults: new HookMap( () => new SyncBailHook(["groupConfigs", "context"]) ), - /** @type {HookMap>} */ sortResults: new HookMap( () => new SyncBailHook(["comparators", "context"]) ), - /** @type {HookMap>} */ filterResults: new HookMap( () => new SyncBailHook(["item", "context", "index", "unfilteredIndex"]) ), - /** @type {HookMap>} */ merge: new HookMap(() => new SyncBailHook(["items", "context"])), - /** @type {HookMap>} */ result: new HookMap(() => new SyncWaterfallHook(["result", "context"])), - /** @type {HookMap>} */ getItemName: new HookMap(() => new SyncBailHook(["item", "context"])), - /** @type {HookMap>} */ getItemFactory: new HookMap(() => new SyncBailHook(["item", "context"])) }); const hooks = this.hooks; - this._caches = /** @type {Record[]>>} */ ({}); + this._caches = /** @type {TODO} */ ({}); for (const key of Object.keys(hooks)) { - this._caches[key] = new Map(); + this._caches[/** @type {keyof StatsFactoryHooks} */ (key)] = new Map(); } this._inCreate = false; } + /** + * @template {StatsFactoryHooks[keyof StatsFactoryHooks]} HM + * @template {HM extends HookMap ? H : never} H + * @param {HM} hookMap hook map + * @param {Caches} cache cache + * @param {string} type type + * @returns {H[]} hooks + * @private + */ _getAllLevelHooks(hookMap, cache, type) { const cacheEntry = cache.get(type); if (cacheEntry !== undefined) { return cacheEntry; } - const hooks = []; + const hooks = /** @type {H[]} */ ([]); const typeParts = type.split("."); for (let i = 0; i < typeParts.length; i++) { - const hook = hookMap.get(typeParts.slice(i).join(".")); + const hook = /** @type {H} */ (hookMap.get(typeParts.slice(i).join("."))); if (hook) { hooks.push(hook); } @@ -95,27 +121,62 @@ class StatsFactory { return hooks; } + /** + * @template {StatsFactoryHooks[keyof StatsFactoryHooks]} HM + * @template {HM extends HookMap ? H : never} H + * @template {H extends import("tapable").Hook ? R : never} R + * @param {HM} hookMap hook map + * @param {Caches} cache cache + * @param {string} type type + * @param {function(H): R | undefined} fn fn + * @returns {R | undefined} hook + * @private + */ _forEachLevel(hookMap, cache, type, fn) { for (const hook of this._getAllLevelHooks(hookMap, cache, type)) { - const result = fn(hook); + const result = fn(/** @type {H} */ (hook)); if (result !== undefined) return result; } } + /** + * @template {StatsFactoryHooks[keyof StatsFactoryHooks]} HM + * @template {HM extends HookMap ? H : never} H + * @param {HM} hookMap hook map + * @param {Caches} cache cache + * @param {string} type type + * @param {FactoryData} data data + * @param {function(H, FactoryData): FactoryData} fn fn + * @returns {FactoryData} data + * @private + */ _forEachLevelWaterfall(hookMap, cache, type, data, fn) { for (const hook of this._getAllLevelHooks(hookMap, cache, type)) { - data = fn(hook, data); + data = fn(/** @type {H} */ (hook), data); } return data; } + /** + * @template {StatsFactoryHooks[keyof StatsFactoryHooks]} T + * @template {T extends HookMap ? H : never} H + * @template {H extends import("tapable").Hook ? R : never} R + * @param {T} hookMap hook map + * @param {Caches} cache cache + * @param {string} type type + * @param {Array} items items + * @param {function(H, R, number, number): R | undefined} fn fn + * @param {boolean} forceClone force clone + * @returns {R[]} result for each level + * @private + */ _forEachLevelFilter(hookMap, cache, type, items, fn, forceClone) { const hooks = this._getAllLevelHooks(hookMap, cache, type); if (hooks.length === 0) return forceClone ? items.slice() : items; let i = 0; return items.filter((item, idx) => { for (const hook of hooks) { - const r = fn(hook, item, idx, i); + const r = fn(/** @type {H} */ (hook), item, idx, i); if (r !== undefined) { if (r) i++; return r; @@ -128,30 +189,37 @@ class StatsFactory { /** * @param {string} type type - * @param {any} data factory data + * @param {FactoryData} data factory data * @param {Omit} baseContext context used as base - * @returns {any} created object + * @returns {CreatedObject} created object */ create(type, data, baseContext) { if (this._inCreate) { return this._create(type, data, baseContext); - } else { - try { - this._inCreate = true; - return this._create(type, data, baseContext); - } finally { - for (const key of Object.keys(this._caches)) this._caches[key].clear(); - this._inCreate = false; - } + } + try { + this._inCreate = true; + return this._create(type, data, baseContext); + } finally { + for (const key of Object.keys(this._caches)) + this._caches[/** @type {keyof StatsFactoryHooks} */ (key)].clear(); + this._inCreate = false; } } + /** + * @param {string} type type + * @param {FactoryData} data factory data + * @param {Omit} baseContext context used as base + * @returns {CreatedObject} created object + * @private + */ _create(type, data, baseContext) { - const context = { + const context = /** @type {StatsFactoryContext} */ ({ ...baseContext, type, [type]: data - }; + }); if (Array.isArray(data)) { // run filter on unsorted items const items = this._forEachLevelFilter( @@ -164,6 +232,7 @@ class StatsFactory { ); // sort items + /** @type {Comparator[]} */ const comparators = []; this._forEachLevel(this.hooks.sort, this._caches.sort, type, h => h.call(comparators, context) @@ -187,6 +256,7 @@ class StatsFactory { // for each item let resultItems = items2.map((item, i) => { + /** @type {StatsFactoryContext} */ const itemContext = { ...context, _index: i @@ -216,6 +286,7 @@ class StatsFactory { }); // sort result items + /** @type {Comparator[]} */ const comparators2 = []; this._forEachLevel( this.hooks.sortResults, @@ -231,6 +302,7 @@ class StatsFactory { } // group result items + /** @type {GroupConfig[]} */ const groupConfigs = []; this._forEachLevel( this.hooks.groupResults, @@ -269,23 +341,23 @@ class StatsFactory { result, (h, r) => h.call(r, context) ); - } else { - const object = {}; + } + /** @type {ObjectForExtract} */ + const object = {}; - // run extract on value - this._forEachLevel(this.hooks.extract, this._caches.extract, type, h => - h.call(object, data, context) - ); + // run extract on value + this._forEachLevel(this.hooks.extract, this._caches.extract, type, h => + h.call(object, data, context) + ); - // run result on extracted object - return this._forEachLevelWaterfall( - this.hooks.result, - this._caches.result, - type, - object, - (h, r) => h.call(r, context) - ); - } + // run result on extracted object + return this._forEachLevelWaterfall( + this.hooks.result, + this._caches.result, + type, + object, + (h, r) => h.call(r, context) + ); } } module.exports = StatsFactory; diff --git a/lib/stats/StatsPrinter.js b/lib/stats/StatsPrinter.js index 705a91b7da6..f1e736de114 100644 --- a/lib/stats/StatsPrinter.js +++ b/lib/stats/StatsPrinter.js @@ -7,73 +7,102 @@ const { HookMap, SyncWaterfallHook, SyncBailHook } = require("tapable"); -/** @template T @typedef {import("tapable").AsArray} AsArray */ -/** @typedef {import("tapable").Hook} Hook */ /** @typedef {import("./DefaultStatsFactoryPlugin").StatsAsset} StatsAsset */ /** @typedef {import("./DefaultStatsFactoryPlugin").StatsChunk} StatsChunk */ /** @typedef {import("./DefaultStatsFactoryPlugin").StatsChunkGroup} StatsChunkGroup */ /** @typedef {import("./DefaultStatsFactoryPlugin").StatsCompilation} StatsCompilation */ +/** @typedef {import("./DefaultStatsFactoryPlugin").StatsError} StatsError */ +/** @typedef {import("./DefaultStatsFactoryPlugin").StatsLogging} StatsLogging */ /** @typedef {import("./DefaultStatsFactoryPlugin").StatsModule} StatsModule */ +/** @typedef {import("./DefaultStatsFactoryPlugin").StatsModuleIssuer} StatsModuleIssuer */ /** @typedef {import("./DefaultStatsFactoryPlugin").StatsModuleReason} StatsModuleReason */ +/** @typedef {import("./DefaultStatsFactoryPlugin").StatsModuleTraceDependency} StatsModuleTraceDependency */ +/** @typedef {import("./DefaultStatsFactoryPlugin").StatsModuleTraceItem} StatsModuleTraceItem */ +/** @typedef {import("./DefaultStatsFactoryPlugin").StatsProfile} StatsProfile */ /** - * @typedef {Object} PrintedElement + * @typedef {object} PrintedElement * @property {string} element * @property {string} content */ /** - * @typedef {Object} KnownStatsPrinterContext + * @typedef {object} KnownStatsPrinterContext * @property {string=} type * @property {StatsCompilation=} compilation * @property {StatsChunkGroup=} chunkGroup + * @property {string=} chunkGroupKind * @property {StatsAsset=} asset * @property {StatsModule=} module * @property {StatsChunk=} chunk * @property {StatsModuleReason=} moduleReason + * @property {StatsModuleIssuer=} moduleIssuer + * @property {StatsError=} error + * @property {StatsProfile=} profile + * @property {StatsLogging=} logging + * @property {StatsModuleTraceItem=} moduleTraceItem + * @property {StatsModuleTraceDependency=} moduleTraceDependency + */ + +/** + * @typedef {object} KnownStatsPrinterColorFn * @property {(str: string) => string=} bold * @property {(str: string) => string=} yellow * @property {(str: string) => string=} red * @property {(str: string) => string=} green * @property {(str: string) => string=} magenta * @property {(str: string) => string=} cyan + */ + +/** + * @typedef {object} KnownStatsPrinterFormaters * @property {(file: string, oversize?: boolean) => string=} formatFilename * @property {(id: string) => string=} formatModuleId * @property {(id: string, direction?: "parent"|"child"|"sibling") => string=} formatChunkId * @property {(size: number) => string=} formatSize + * @property {(size: string) => string=} formatLayer * @property {(dateTime: number) => string=} formatDateTime * @property {(flag: string) => string=} formatFlag * @property {(time: number, boldQuantity?: boolean) => string=} formatTime - * @property {string=} chunkGroupKind + * @property {(message: string) => string=} formatError */ -/** @typedef {KnownStatsPrinterContext & Record} StatsPrinterContext */ +/** @typedef {Record & KnownStatsPrinterColorFn & KnownStatsPrinterFormaters & KnownStatsPrinterContext} StatsPrinterContext */ +/** @typedef {any} PrintObject */ + +/** + * @typedef {object} StatsPrintHooks + * @property {HookMap>} sortElements + * @property {HookMap>} printElements + * @property {HookMap>} sortItems + * @property {HookMap>} getItemName + * @property {HookMap>} printItems + * @property {HookMap>} print + * @property {HookMap>} result + */ class StatsPrinter { constructor() { + /** @type {StatsPrintHooks} */ this.hooks = Object.freeze({ - /** @type {HookMap>} */ sortElements: new HookMap( () => new SyncBailHook(["elements", "context"]) ), - /** @type {HookMap>} */ printElements: new HookMap( () => new SyncBailHook(["printedElements", "context"]) ), - /** @type {HookMap>} */ sortItems: new HookMap(() => new SyncBailHook(["items", "context"])), - /** @type {HookMap>} */ getItemName: new HookMap(() => new SyncBailHook(["item", "context"])), - /** @type {HookMap>} */ printItems: new HookMap( () => new SyncBailHook(["printedItems", "context"]) ), - /** @type {HookMap>} */ print: new HookMap(() => new SyncBailHook(["object", "context"])), /** @type {HookMap>} */ result: new HookMap(() => new SyncWaterfallHook(["result", "context"])) }); - /** @type {Map, Map>} */ + /** + * @type {TODO} + */ this._levelHookCache = new Map(); this._inPrint = false; } @@ -81,15 +110,14 @@ class StatsPrinter { /** * get all level hooks * @private - * @template {Hook} T - * @param {HookMap} hookMap HookMap + * @template {StatsPrintHooks[keyof StatsPrintHooks]} HM + * @template {HM extends HookMap ? H : never} H + * @param {HM} hookMap hook map * @param {string} type type - * @returns {T[]} hooks + * @returns {H[]} hooks */ _getAllLevelHooks(hookMap, type) { - let cache = /** @type {Map} */ (this._levelHookCache.get( - hookMap - )); + let cache = this._levelHookCache.get(hookMap); if (cache === undefined) { cache = new Map(); this._levelHookCache.set(hookMap, cache); @@ -98,11 +126,11 @@ class StatsPrinter { if (cacheEntry !== undefined) { return cacheEntry; } - /** @type {T[]} */ + /** @type {H[]} */ const hooks = []; const typeParts = type.split("."); for (let i = 0; i < typeParts.length; i++) { - const hook = hookMap.get(typeParts.slice(i).join(".")); + const hook = /** @type {H} */ (hookMap.get(typeParts.slice(i).join("."))); if (hook) { hooks.push(hook); } @@ -114,16 +142,17 @@ class StatsPrinter { /** * Run `fn` for each level * @private - * @template T - * @template R - * @param {HookMap>} hookMap HookMap + * @template {StatsPrintHooks[keyof StatsPrintHooks]} HM + * @template {HM extends HookMap ? H : never} H + * @template {H extends import("tapable").Hook ? R : never} R + * @param {HM} hookMap hook map * @param {string} type type - * @param {(hook: SyncBailHook) => R} fn function - * @returns {R} result of `fn` + * @param {function(H): R | undefined} fn fn + * @returns {R | undefined} hook */ _forEachLevel(hookMap, type, fn) { for (const hook of this._getAllLevelHooks(hookMap, type)) { - const result = fn(hook); + const result = fn(/** @type {H} */ (hook)); if (result !== undefined) return result; } } @@ -131,48 +160,49 @@ class StatsPrinter { /** * Run `fn` for each level * @private - * @template T - * @param {HookMap>} hookMap HookMap + * @template {StatsPrintHooks[keyof StatsPrintHooks]} HM + * @template {HM extends HookMap ? H : never} H + * @param {HM} hookMap hook map * @param {string} type type - * @param {AsArray[0]} data data - * @param {(hook: SyncWaterfallHook, data: AsArray[0]) => AsArray[0]} fn function - * @returns {AsArray[0]} result of `fn` + * @param {string} data data + * @param {function(H, string): string} fn fn + * @returns {string} result of `fn` */ _forEachLevelWaterfall(hookMap, type, data, fn) { for (const hook of this._getAllLevelHooks(hookMap, type)) { - data = fn(hook, data); + data = fn(/** @type {H} */ (hook), data); } return data; } /** * @param {string} type The type - * @param {Object} object Object to print - * @param {Object=} baseContext The base context + * @param {PrintObject} object Object to print + * @param {StatsPrinterContext=} baseContext The base context * @returns {string} printed result */ print(type, object, baseContext) { if (this._inPrint) { return this._print(type, object, baseContext); - } else { - try { - this._inPrint = true; - return this._print(type, object, baseContext); - } finally { - this._levelHookCache.clear(); - this._inPrint = false; - } + } + try { + this._inPrint = true; + return this._print(type, object, baseContext); + } finally { + this._levelHookCache.clear(); + this._inPrint = false; } } /** * @private * @param {string} type type - * @param {Object} object object - * @param {Object=} baseContext context + * @param {PrintObject} object object + * @param {StatsPrinterContext=} baseContext context * @returns {string} printed result */ _print(type, object, baseContext) { + /** @type {StatsPrinterContext} */ const context = { ...baseContext, type, @@ -189,6 +219,7 @@ class StatsPrinter { h.call(sortedItems, context) ); const printedItems = sortedItems.map((item, i) => { + /** @type {StatsPrinterContext} */ const itemContext = { ...context, _index: i @@ -241,7 +272,7 @@ class StatsPrinter { return this._forEachLevelWaterfall( this.hooks.result, type, - printResult, + /** @type {string} */ (printResult), (h, r) => h.call(r, context) ); } diff --git a/lib/util/ArrayHelpers.js b/lib/util/ArrayHelpers.js index 7c684ee1b6e..ac32ce9f7a3 100644 --- a/lib/util/ArrayHelpers.js +++ b/lib/util/ArrayHelpers.js @@ -5,10 +5,44 @@ "use strict"; -exports.equals = (a, b) => { +/** + * Compare two arrays or strings by performing strict equality check for each value. + * @template T [T=any] + * @param {ArrayLike} a Array of values to be compared + * @param {ArrayLike} b Array of values to be compared + * @returns {boolean} returns true if all the elements of passed arrays are strictly equal. + */ + +module.exports.equals = (a, b) => { if (a.length !== b.length) return false; for (let i = 0; i < a.length; i++) { if (a[i] !== b[i]) return false; } return true; }; + +/** + * Partition an array by calling a predicate function on each value. + * @template T [T=any] + * @param {Array} arr Array of values to be partitioned + * @param {(value: T) => boolean} fn Partition function which partitions based on truthiness of result. + * @returns {[Array, Array]} returns the values of `arr` partitioned into two new arrays based on fn predicate. + */ + +module.exports.groupBy = ( + // eslint-disable-next-line default-param-last + arr = [], + fn +) => + arr.reduce( + /** + * @param {[Array, Array]} groups An accumulator storing already partitioned values returned from previous call. + * @param {T} value The value of the current element + * @returns {[Array, Array]} returns an array of partitioned groups accumulator resulting from calling a predicate on the current value. + */ + (groups, value) => { + groups[fn(value) ? 0 : 1].push(value); + return groups; + }, + [[], []] + ); diff --git a/lib/util/ArrayQueue.js b/lib/util/ArrayQueue.js index 60a20208f6b..522abf93de2 100644 --- a/lib/util/ArrayQueue.js +++ b/lib/util/ArrayQueue.js @@ -13,9 +13,15 @@ class ArrayQueue { * @param {Iterable=} items The initial elements. */ constructor(items) { - /** @private @type {T[]} */ + /** + * @private + * @type {T[]} + */ this._list = items ? Array.from(items) : []; - /** @private @type {T[]} */ + /** + * @private + * @type {T[]} + */ this._listReversed = []; } @@ -27,6 +33,14 @@ class ArrayQueue { return this._list.length + this._listReversed.length; } + /** + * Empties the queue. + */ + clear() { + this._list.length = 0; + this._listReversed.length = 0; + } + /** * Appends the specified element to this queue. * @param {T} item The element to add. @@ -42,7 +56,7 @@ class ArrayQueue { */ dequeue() { if (this._listReversed.length === 0) { - if (this._list.length === 0) return undefined; + if (this._list.length === 0) return; if (this._list.length === 1) return this._list.pop(); if (this._list.length < 16) return this._list.shift(); const temp = this._listReversed; @@ -69,31 +83,18 @@ class ArrayQueue { } [Symbol.iterator]() { - let i = -1; - let reversed = false; return { next: () => { - if (!reversed) { - i++; - if (i < this._list.length) { - return { - done: false, - value: this._list[i] - }; - } - reversed = true; - i = this._listReversed.length; - } - i--; - if (i < 0) { + const item = this.dequeue(); + if (item) { return { - done: true, - value: undefined + done: false, + value: item }; } return { - done: false, - value: this._listReversed[i] + done: true, + value: undefined }; } }; diff --git a/lib/util/AsyncQueue.js b/lib/util/AsyncQueue.js index f87031dd077..9a5a260c21b 100644 --- a/lib/util/AsyncQueue.js +++ b/lib/util/AsyncQueue.js @@ -6,6 +6,8 @@ "use strict"; const { SyncHook, AsyncSeriesHook } = require("tapable"); +const { makeWebpackError } = require("../HookWebpackError"); +const WebpackError = require("../WebpackError"); const ArrayQueue = require("./ArrayQueue"); const QUEUED_STATE = 0; @@ -17,8 +19,8 @@ let inHandleResult = 0; /** * @template T * @callback Callback - * @param {Error=} err - * @param {T=} result + * @param {(WebpackError | null)=} err + * @param {(T | null)=} result */ /** @@ -35,14 +37,27 @@ class AsyncQueueEntry { this.item = item; /** @type {typeof QUEUED_STATE | typeof PROCESSING_STATE | typeof DONE_STATE} */ this.state = QUEUED_STATE; + /** @type {Callback | undefined} */ this.callback = callback; /** @type {Callback[] | undefined} */ this.callbacks = undefined; + /** @type {R | null | undefined} */ this.result = undefined; + /** @type {WebpackError | null | undefined} */ this.error = undefined; } } +/** + * @template T, K + * @typedef {function(T): K} getKey + */ + +/** + * @template T, R + * @typedef {function(T, Callback): void} Processor + */ + /** * @template T * @template K @@ -50,29 +65,31 @@ class AsyncQueueEntry { */ class AsyncQueue { /** - * @param {Object} options options object + * @param {object} options options object * @param {string=} options.name name of the queue * @param {number=} options.parallelism how many items should be processed at once * @param {AsyncQueue=} options.parent parent queue, which will have priority over this queue and with shared parallelism - * @param {function(T): K=} options.getKey extract key from item - * @param {function(T, Callback): void} options.processor async function to process items + * @param {getKey=} options.getKey extract key from item + * @param {Processor} options.processor async function to process items */ constructor({ name, parallelism, parent, processor, getKey }) { this._name = name; this._parallelism = parallelism || 1; this._processor = processor; this._getKey = - getKey || /** @type {(T) => K} */ (item => /** @type {any} */ (item)); + getKey || + /** @type {getKey} */ (item => /** @type {T & K} */ (item)); /** @type {Map>} */ this._entries = new Map(); /** @type {ArrayQueue>} */ this._queued = new ArrayQueue(); - /** @type {AsyncQueue[]} */ + /** @type {AsyncQueue[] | undefined} */ this._children = undefined; this._activeTasks = 0; this._willEnsureProcessing = false; this._needProcessing = false; this._stopped = false; + /** @type {AsyncQueue} */ this._root = parent ? parent._root : this; if (parent) { if (this._root._children === undefined) { @@ -91,7 +108,7 @@ class AsyncQueue { beforeStart: new AsyncSeriesHook(["item"]), /** @type {SyncHook<[T]>} */ started: new SyncHook(["item"]), - /** @type {SyncHook<[T, Error, R]>} */ + /** @type {SyncHook<[T, WebpackError | null | undefined, R | null | undefined]>} */ result: new SyncHook(["item", "error", "result"]) }; @@ -99,22 +116,29 @@ class AsyncQueue { } /** - * @param {T} item a item + * @param {T} item an item * @param {Callback} callback callback function * @returns {void} */ add(item, callback) { - if (this._stopped) return callback(new Error("Queue was stopped")); + if (this._stopped) return callback(new WebpackError("Queue was stopped")); this.hooks.beforeAdd.callAsync(item, err => { if (err) { - callback(err); + callback( + makeWebpackError(err, `AsyncQueue(${this._name}).hooks.beforeAdd`) + ); return; } const key = this._getKey(item); const entry = this._entries.get(key); if (entry !== undefined) { if (entry.state === DONE_STATE) { - process.nextTick(() => callback(entry.error, entry.result)); + if (inHandleResult++ > 3) { + process.nextTick(() => callback(entry.error, entry.result)); + } else { + callback(entry.error, entry.result); + } + inHandleResult--; } else if (entry.callbacks === undefined) { entry.callbacks = [callback]; } else { @@ -127,7 +151,7 @@ class AsyncQueue { this.hooks.added.call(item); this._root._activeTasks++; process.nextTick(() => - this._handleResult(newEntry, new Error("Queue was stopped")) + this._handleResult(newEntry, new WebpackError("Queue was stopped")) ); } else { this._entries.set(key, newEntry); @@ -144,18 +168,45 @@ class AsyncQueue { } /** - * @param {T} item a item + * @param {T} item an item * @returns {void} */ invalidate(item) { const key = this._getKey(item); - const entry = this._entries.get(key); + const entry = + /** @type {AsyncQueueEntry} */ + (this._entries.get(key)); this._entries.delete(key); if (entry.state === QUEUED_STATE) { this._queued.delete(entry); } } + /** + * Waits for an already started item + * @param {T} item an item + * @param {Callback} callback callback function + * @returns {void} + */ + waitFor(item, callback) { + const key = this._getKey(item); + const entry = this._entries.get(key); + if (entry === undefined) { + return callback( + new WebpackError( + "waitFor can only be called for an already started item" + ) + ); + } + if (entry.state === DONE_STATE) { + process.nextTick(() => callback(entry.error, entry.result)); + } else if (entry.callbacks === undefined) { + entry.callbacks = [callback]; + } else { + entry.callbacks.push(callback); + } + } + /** * @returns {void} */ @@ -165,9 +216,14 @@ class AsyncQueue { this._queued = new ArrayQueue(); const root = this._root; for (const entry of queue) { - this._entries.delete(this._getKey(entry.item)); + this._entries.delete( + this._getKey(/** @type {AsyncQueueEntry} */ (entry).item) + ); root._activeTasks++; - this._handleResult(entry, new Error("Queue was stopped")); + this._handleResult( + /** @type {AsyncQueueEntry} */ (entry), + new WebpackError("Queue was stopped") + ); } } @@ -257,7 +313,10 @@ class AsyncQueue { _startProcessing(entry) { this.hooks.beforeStart.callAsync(entry.item, err => { if (err) { - this._handleResult(entry, err); + this._handleResult( + entry, + makeWebpackError(err, `AsyncQueue(${this._name}).hooks.beforeStart`) + ); return; } let inCallback = false; @@ -268,7 +327,7 @@ class AsyncQueue { }); } catch (err) { if (inCallback) throw err; - this._handleResult(entry, err, null); + this._handleResult(entry, /** @type {WebpackError} */ (err), null); } this.hooks.started.call(entry.item); }); @@ -276,15 +335,17 @@ class AsyncQueue { /** * @param {AsyncQueueEntry} entry the entry - * @param {Error=} err error, if any - * @param {R=} result result, if any + * @param {(WebpackError | null)=} err error, if any + * @param {(R | null)=} result result, if any * @returns {void} */ _handleResult(entry, err, result) { this.hooks.result.callAsync(entry.item, err, result, hookError => { - const error = hookError || err; + const error = hookError + ? makeWebpackError(hookError, `AsyncQueue(${this._name}).hooks.result`) + : err; - const callback = entry.callback; + const callback = /** @type {Callback} */ (entry.callback); const callbacks = entry.callbacks; entry.state = DONE_STATE; entry.callback = undefined; @@ -319,6 +380,15 @@ class AsyncQueue { inHandleResult--; }); } + + clear() { + this._entries.clear(); + this._queued.clear(); + this._activeTasks = 0; + this._willEnsureProcessing = false; + this._needProcessing = false; + this._stopped = false; + } } module.exports = AsyncQueue; diff --git a/lib/util/DataURI.js b/lib/util/DataURI.js deleted file mode 100644 index 13947c83917..00000000000 --- a/lib/util/DataURI.js +++ /dev/null @@ -1,32 +0,0 @@ -/* - MIT License http://www.opensource.org/licenses/mit-license.php -*/ - -"use strict"; - -// data URL scheme: "data:text/javascript;charset=utf-8;base64,some-string" -// http://www.ietf.org/rfc/rfc2397.txt -const URIRegEx = /^data:([^;,]+)?((?:;(?:[^;,]+))*?)(;base64)?,(.*)$/i; - -const decodeDataURI = uri => { - const match = URIRegEx.exec(uri); - if (!match) return null; - - const isBase64 = match[3]; - const body = match[4]; - return isBase64 - ? Buffer.from(body, "base64") - : Buffer.from(decodeURIComponent(body), "ascii"); -}; - -const getMimetype = uri => { - const match = URIRegEx.exec(uri); - if (!match) return ""; - - return match[1] || "text/plain"; -}; - -module.exports = { - decodeDataURI, - getMimetype -}; diff --git a/lib/util/IterableHelpers.js b/lib/util/IterableHelpers.js index beb98a55914..ccceb19d575 100644 --- a/lib/util/IterableHelpers.js +++ b/lib/util/IterableHelpers.js @@ -36,11 +36,10 @@ const someInIterable = (iterable, filter) => { */ const countIterable = iterable => { let i = 0; - // eslint-disable-next-line no-unused-vars for (const _ of iterable) i++; return i; }; -exports.last = last; -exports.someInIterable = someInIterable; -exports.countIterable = countIterable; +module.exports.last = last; +module.exports.someInIterable = someInIterable; +module.exports.countIterable = countIterable; diff --git a/lib/util/LazyBucketSortedSet.js b/lib/util/LazyBucketSortedSet.js index ce897eea563..5469010893d 100644 --- a/lib/util/LazyBucketSortedSet.js +++ b/lib/util/LazyBucketSortedSet.js @@ -8,6 +8,16 @@ const { first } = require("./SetHelpers"); const SortableSet = require("./SortableSet"); +/** + * @template T + * @typedef {LazyBucketSortedSet | SortableSet} Entry + */ + +/** + * @template T + * @typedef {(function(T): any) | (function(any, any): number)} Arg + */ + /** * Multi layer bucket sorted set: * Supports adding non-existing items (DO NOT ADD ITEM TWICE), @@ -24,14 +34,15 @@ class LazyBucketSortedSet { /** * @param {function(T): K} getKey function to get key from item * @param {function(K, K): number} comparator comparator to sort keys - * @param {...((function(T): any) | (function(any, any): number))} args more pairs of getKey and comparator plus optional final comparator for the last layer + * @param {...Arg} args more pairs of getKey and comparator plus optional final comparator for the last layer */ constructor(getKey, comparator, ...args) { this._getKey = getKey; + /** @type {Arg[]} */ this._innerArgs = args; this._leaf = args.length <= 1; this._keys = new SortableSet(undefined, comparator); - /** @type {Map | SortableSet>} */ + /** @type {Map>} */ this._map = new Map(); this._unsortedItems = new Set(); this.size = 0; @@ -54,13 +65,18 @@ class LazyBucketSortedSet { _addInternal(key, item) { let entry = this._map.get(key); if (entry === undefined) { - entry = this._leaf - ? new SortableSet(undefined, this._innerArgs[0]) - : new /** @type {any} */ (LazyBucketSortedSet)(...this._innerArgs); + entry = + /** @type {Entry} */ + ( + this._leaf + ? new SortableSet(undefined, this._innerArgs[0]) + : new /** @type {TODO} */ (LazyBucketSortedSet)(...this._innerArgs) + ); this._keys.add(key); this._map.set(key, entry); } - entry.add(item); + /** @type {Entry} */ + (entry).add(item); } /** @@ -74,7 +90,7 @@ class LazyBucketSortedSet { return; } const key = this._getKey(item); - const entry = this._map.get(key); + const entry = /** @type {Entry} */ (this._map.get(key)); entry.delete(item); if (entry.size === 0) { this._deleteKey(key); @@ -94,7 +110,7 @@ class LazyBucketSortedSet { * @returns {T | undefined} an item */ popFirst() { - if (this.size === 0) return undefined; + if (this.size === 0) return; this.size--; if (this._unsortedItems.size > 0) { for (const item of this._unsortedItems) { @@ -104,25 +120,24 @@ class LazyBucketSortedSet { this._unsortedItems.clear(); } this._keys.sort(); - const key = first(this._keys); + const key = /** @type {K} */ (first(this._keys)); const entry = this._map.get(key); if (this._leaf) { const leafEntry = /** @type {SortableSet} */ (entry); leafEntry.sort(); - const item = first(leafEntry); + const item = /** @type {T} */ (first(leafEntry)); leafEntry.delete(item); if (leafEntry.size === 0) { this._deleteKey(key); } return item; - } else { - const nodeEntry = /** @type {LazyBucketSortedSet} */ (entry); - const item = nodeEntry.popFirst(); - if (nodeEntry.size === 0) { - this._deleteKey(key); - } - return item; } + const nodeEntry = /** @type {LazyBucketSortedSet} */ (entry); + const item = nodeEntry.popFirst(); + if (nodeEntry.size === 0) { + this._deleteKey(key); + } + return item; } /** @@ -135,7 +150,6 @@ class LazyBucketSortedSet { if (remove) { this._unsortedItems.delete(item); this.size--; - return; } }; } @@ -163,32 +177,31 @@ class LazyBucketSortedSet { this._addInternal(newKey, item); } }; - } else { - const oldEntry = /** @type {LazyBucketSortedSet} */ (this._map.get( - key - )); - const finishUpdate = oldEntry.startUpdate(item); - return remove => { - if (remove) { - this.size--; - finishUpdate(true); - if (oldEntry.size === 0) { - this._deleteKey(key); - } - return; + } + const oldEntry = /** @type {LazyBucketSortedSet} */ ( + this._map.get(key) + ); + const finishUpdate = oldEntry.startUpdate(item); + return remove => { + if (remove) { + this.size--; + finishUpdate(true); + if (oldEntry.size === 0) { + this._deleteKey(key); } - const newKey = this._getKey(item); - if (key === newKey) { - finishUpdate(); - } else { - finishUpdate(true); - if (oldEntry.size === 0) { - this._deleteKey(key); - } - this._addInternal(newKey, item); + return; + } + const newKey = this._getKey(item); + if (key === newKey) { + finishUpdate(); + } else { + finishUpdate(true); + if (oldEntry.size === 0) { + this._deleteKey(key); } - }; - } + this._addInternal(newKey, item); + } + }; } /** @@ -215,16 +228,19 @@ class LazyBucketSortedSet { * @returns {Iterator} the iterator */ [Symbol.iterator]() { + /** @type {Iterator[]} */ const iterators = []; this._appendIterators(iterators); iterators.reverse(); - let currentIterator = iterators.pop(); + let currentIterator = + /** @type {Iterator} */ + (iterators.pop()); return { next: () => { const res = currentIterator.next(); if (res.done) { if (iterators.length === 0) return res; - currentIterator = iterators.pop(); + currentIterator = /** @type {Iterator} */ (iterators.pop()); return currentIterator.next(); } return res; diff --git a/lib/util/LazySet.js b/lib/util/LazySet.js index ec27cbe9feb..72f481a2468 100644 --- a/lib/util/LazySet.js +++ b/lib/util/LazySet.js @@ -24,21 +24,17 @@ const merge = (targetSet, toMerge) => { /** * @template T * @param {Set>} targetSet set where iterables should be added - * @param {Array | LazySet>} toDeepMerge iterables or lazy set to be flattened + * @param {Array>} toDeepMerge lazy sets to be flattened * @returns {void} */ const flatten = (targetSet, toDeepMerge) => { for (const set of toDeepMerge) { - if (set instanceof LazySet) { - if (set._set.size > 0) targetSet.add(set._set); - if (set._needMerge) { - for (const mergedSet of set._toMerge) { - targetSet.add(mergedSet); - } - flatten(targetSet, set._toDeepMerge); + if (set._set.size > 0) targetSet.add(set._set); + if (set._needMerge) { + for (const mergedSet of set._toMerge) { + targetSet.add(mergedSet); } - } else { - targetSet.add(set); + flatten(targetSet, set._toDeepMerge); } } }; @@ -58,7 +54,7 @@ class LazySet { this._set = new Set(iterable); /** @type {Set>} */ this._toMerge = new Set(); - /** @type {Array | LazySet>} */ + /** @type {Array>} */ this._toDeepMerge = []; this._needMerge = false; this._deopt = false; @@ -76,6 +72,14 @@ class LazySet { this._needMerge = false; } + _isEmpty() { + return ( + this._set.size === 0 && + this._toMerge.size === 0 && + this._toDeepMerge.length === 0 + ); + } + get size() { if (this._needMerge) this._merge(); return this._set.size; @@ -83,7 +87,7 @@ class LazySet { /** * @param {T} item an item - * @returns {this} itself + * @returns {LazySet} itself */ add(item) { this._set.add(item); @@ -92,7 +96,7 @@ class LazySet { /** * @param {Iterable | LazySet} iterable a immutable iterable or another immutable LazySet which will eventually be merged into the Set - * @returns {this} itself + * @returns {LazySet} itself */ addAll(iterable) { if (this._deopt) { @@ -101,13 +105,18 @@ class LazySet { _set.add(item); } } else { - this._toDeepMerge.push(iterable); - this._needMerge = true; - // Avoid being too memory hungry - if (this._toDeepMerge.length > 100000) { - this._flatten(); - if (this._toMerge.size > 100000) this._merge(); + if (iterable instanceof LazySet) { + if (iterable._isEmpty()) return this; + this._toDeepMerge.push(iterable); + this._needMerge = true; + if (this._toDeepMerge.length > 100000) { + this._flatten(); + } + } else { + this._toMerge.add(iterable); + this._needMerge = true; } + if (this._toMerge.size > 100000) this._merge(); } return this; } @@ -143,6 +152,7 @@ class LazySet { forEach(callbackFn, thisArg) { this._deopt = true; if (this._needMerge) this._merge(); + // eslint-disable-next-line unicorn/no-array-for-each this._set.forEach(callbackFn, thisArg); } @@ -178,12 +188,20 @@ class LazySet { return "LazySet"; } + /** + * @param {import("../serialization/ObjectMiddleware").ObjectSerializerContext} context context + */ serialize({ write }) { if (this._needMerge) this._merge(); write(this._set.size); for (const item of this._set) write(item); } + /** + * @template T + * @param {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} context context + * @returns {LazySet} lazy set + */ static deserialize({ read }) { const count = read(); const items = []; diff --git a/lib/util/MapHelpers.js b/lib/util/MapHelpers.js index c87b93b71ba..259f621d8e0 100644 --- a/lib/util/MapHelpers.js +++ b/lib/util/MapHelpers.js @@ -6,16 +6,28 @@ "use strict"; /** + * getOrInsert is a helper function for maps that allows you to get a value + * from a map if it exists, or insert a new value if it doesn't. If it value doesn't + * exist, it will be computed by the provided function. * @template K * @template V - * @param {Map} map a map - * @param {K} key the key - * @param {function(): V} computer compute value - * @returns {V} value + * @param {Map} map The map object to check + * @param {K} key The key to check + * @param {function(): V} computer function which will compute the value if it doesn't exist + * @returns {V} The value from the map, or the computed value + * @example + * ```js + * const map = new Map(); + * const value = getOrInsert(map, "key", () => "value"); + * console.log(value); // "value" + * ``` */ -exports.provide = (map, key, computer) => { +module.exports.getOrInsert = (map, key, computer) => { + // Grab key from map const value = map.get(key); + // If the value already exists, return it if (value !== undefined) return value; + // Otherwise compute the value, set it in the map, and return it const newValue = computer(); map.set(key, newValue); return newValue; diff --git a/lib/util/ParallelismFactorCalculator.js b/lib/util/ParallelismFactorCalculator.js index cbdda42f2ad..d7725b7bfd4 100644 --- a/lib/util/ParallelismFactorCalculator.js +++ b/lib/util/ParallelismFactorCalculator.js @@ -5,14 +5,24 @@ "use strict"; -const binarySearchBounds = require("../util/binarySearchBounds"); +const binarySearchBounds = require("./binarySearchBounds"); + +/** @typedef {function(number): void} Callback */ class ParallelismFactorCalculator { constructor() { + /** @type {number[]} */ this._rangePoints = []; + /** @type {Callback[]} */ this._rangeCallbacks = []; } + /** + * @param {number} start range start + * @param {number} end range end + * @param {Callback} callback callback + * @returns {void} + */ range(start, end, callback) { if (start === end) return callback(1); this._rangePoints.push(start); diff --git a/lib/util/Queue.js b/lib/util/Queue.js index 3b88ec3e684..3d0e79dbe6a 100644 --- a/lib/util/Queue.js +++ b/lib/util/Queue.js @@ -13,9 +13,15 @@ class Queue { * @param {Iterable=} items The initial elements. */ constructor(items) { - /** @private @type {Set} */ + /** + * @private + * @type {Set} + */ this._set = new Set(items); - /** @private @type {Iterator} */ + /** + * @private + * @type {Iterator} + */ this._iterator = this._set[Symbol.iterator](); } @@ -42,7 +48,7 @@ class Queue { */ dequeue() { const result = this._iterator.next(); - if (result.done) return undefined; + if (result.done) return; this._set.delete(result.value); return result.value; } diff --git a/lib/util/Semaphore.js b/lib/util/Semaphore.js index 52fdd30701c..5277fedb6c6 100644 --- a/lib/util/Semaphore.js +++ b/lib/util/Semaphore.js @@ -8,7 +8,6 @@ class Semaphore { /** * Creates an instance of Semaphore. - * * @param {number} available the amount available number of "tasks" * in the Semaphore */ @@ -41,12 +40,10 @@ class Semaphore { } _continue() { - if (this.available > 0) { - if (this.waiters.length > 0) { - this.available--; - const callback = this.waiters.pop(); - callback(); - } + if (this.available > 0 && this.waiters.length > 0) { + this.available--; + const callback = /** @type {(function(): void)} */ (this.waiters.pop()); + callback(); } } } diff --git a/lib/util/SetHelpers.js b/lib/util/SetHelpers.js index e102082e9ed..cb837429f0b 100644 --- a/lib/util/SetHelpers.js +++ b/lib/util/SetHelpers.js @@ -87,8 +87,8 @@ const combine = (a, b) => { return set; }; -exports.intersect = intersect; -exports.isSubset = isSubset; -exports.find = find; -exports.first = first; -exports.combine = combine; +module.exports.intersect = intersect; +module.exports.isSubset = isSubset; +module.exports.find = find; +module.exports.first = first; +module.exports.combine = combine; diff --git a/lib/util/SortableSet.js b/lib/util/SortableSet.js index 1010b441306..9260c163a0f 100644 --- a/lib/util/SortableSet.js +++ b/lib/util/SortableSet.js @@ -15,19 +15,32 @@ const NONE = Symbol("not sorted"); class SortableSet extends Set { /** * Create a new sortable set + * @template T * @param {Iterable=} initialIterable The initial iterable value * @typedef {function(T, T): number} SortFunction - * @param {SortFunction=} defaultSort Default sorting function + * @param {SortFunction=} defaultSort Default sorting function */ constructor(initialIterable, defaultSort) { super(initialIterable); - /** @private @type {undefined | function(T, T): number}} */ + /** + * @private + * @type {undefined | SortFunction} + */ this._sortFn = defaultSort; - /** @private @type {typeof NONE | undefined | function(T, T): number}} */ + /** + * @private + * @type {typeof NONE | undefined | function(T, T): number}} + */ this._lastActiveSortFn = NONE; - /** @private @type {Map | undefined} */ + /** + * @private + * @type {Map | undefined} + */ this._cache = undefined; - /** @private @type {Map | undefined} */ + /** + * @private + * @type {Map | undefined} + */ this._cacheOrderIndependent = undefined; } @@ -64,7 +77,7 @@ class SortableSet extends Set { /** * Sort with a comparer function - * @param {SortFunction} sortFn Sorting comparer function + * @param {SortFunction | undefined} sortFn Sorting comparer function * @returns {void} */ sortWith(sortFn) { diff --git a/lib/util/StackedCacheMap.js b/lib/util/StackedCacheMap.js new file mode 100644 index 00000000000..820f0d1b3d8 --- /dev/null +++ b/lib/util/StackedCacheMap.js @@ -0,0 +1,140 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ + +"use strict"; + +/** + * The StackedCacheMap is a data structure designed as an alternative to a Map + * in situations where you need to handle multiple item additions and + * frequently access the largest map. + * + * It is particularly optimized for efficiently adding multiple items + * at once, which can be achieved using the `addAll` method. + * + * It has a fallback Map that is used when the map to be added is mutable. + * + * Note: `delete` and `has` are not supported for performance reasons. + * @example + * ```js + * const map = new StackedCacheMap(); + * map.addAll(new Map([["a", 1], ["b", 2]]), true); + * map.addAll(new Map([["c", 3], ["d", 4]]), true); + * map.get("a"); // 1 + * map.get("d"); // 4 + * for (const [key, value] of map) { + * console.log(key, value); + * } + * ``` + * @template K + * @template V + */ +class StackedCacheMap { + constructor() { + /** @type {Map} */ + this.map = new Map(); + /** @type {ReadonlyMap[]} */ + this.stack = []; + } + + /** + * If `immutable` is true, the map can be referenced by the StackedCacheMap + * and should not be changed afterwards. If the map is mutable, all items + * are copied into a fallback Map. + * @param {ReadonlyMap} map map to add + * @param {boolean=} immutable if 'map' is immutable and StackedCacheMap can keep referencing it + */ + addAll(map, immutable) { + if (immutable) { + this.stack.push(map); + + // largest map should go first + for (let i = this.stack.length - 1; i > 0; i--) { + const beforeLast = this.stack[i - 1]; + if (beforeLast.size >= map.size) break; + this.stack[i] = beforeLast; + this.stack[i - 1] = map; + } + } else { + for (const [key, value] of map) { + this.map.set(key, value); + } + } + } + + /** + * @param {K} item the key of the element to add + * @param {V} value the value of the element to add + * @returns {void} + */ + set(item, value) { + this.map.set(item, value); + } + + /** + * @param {K} item the item to delete + * @returns {void} + */ + delete(item) { + throw new Error("Items can't be deleted from a StackedCacheMap"); + } + + /** + * @param {K} item the item to test + * @returns {boolean} true if the item exists in this set + */ + has(item) { + throw new Error( + "Checking StackedCacheMap.has before reading is inefficient, use StackedCacheMap.get and check for undefined" + ); + } + + /** + * @param {K} item the key of the element to return + * @returns {V | undefined} the value of the element + */ + get(item) { + for (const map of this.stack) { + const value = map.get(item); + if (value !== undefined) return value; + } + return this.map.get(item); + } + + clear() { + this.stack.length = 0; + this.map.clear(); + } + + /** + * @returns {number} size of the map + */ + get size() { + let size = this.map.size; + for (const map of this.stack) { + size += map.size; + } + return size; + } + + /** + * @returns {Iterator<[K, V]>} iterator + */ + [Symbol.iterator]() { + const iterators = this.stack.map(map => map[Symbol.iterator]()); + let current = this.map[Symbol.iterator](); + return { + next() { + let result = current.next(); + while (result.done && iterators.length > 0) { + current = /** @type {IterableIterator<[K, V]>} */ (iterators.pop()); + result = current.next(); + } + return result; + } + }; + } +} + +module.exports = StackedCacheMap; diff --git a/lib/util/StackedMap.js b/lib/util/StackedMap.js index bb5e776ccca..0f4011d0ce7 100644 --- a/lib/util/StackedMap.js +++ b/lib/util/StackedMap.js @@ -29,9 +29,8 @@ const extractPair = pair => { const val = pair[1]; if (val === UNDEFINED_MARKER || val === TOMBSTONE) { return [key, undefined]; - } else { - return /** @type {[K, Cell]} */ (pair); } + return /** @type {[K, Cell]} */ (pair); }; /** @@ -116,7 +115,6 @@ class StackedMap { } this.map.set(item, TOMBSTONE); } - return undefined; } _compress() { diff --git a/lib/util/StackedSetMap.js b/lib/util/StackedSetMap.js deleted file mode 100644 index bb5e776ccca..00000000000 --- a/lib/util/StackedSetMap.js +++ /dev/null @@ -1,166 +0,0 @@ -/* - MIT License http://www.opensource.org/licenses/mit-license.php - Author Tobias Koppers @sokra -*/ - -"use strict"; - -const TOMBSTONE = Symbol("tombstone"); -const UNDEFINED_MARKER = Symbol("undefined"); - -/** - * @template T - * @typedef {T | undefined} Cell - */ - -/** - * @template T - * @typedef {T | typeof TOMBSTONE | typeof UNDEFINED_MARKER} InternalCell - */ - -/** - * @template K - * @template V - * @param {[K, InternalCell]} pair the internal cell - * @returns {[K, Cell]} its โ€œsafeโ€ representation - */ -const extractPair = pair => { - const key = pair[0]; - const val = pair[1]; - if (val === UNDEFINED_MARKER || val === TOMBSTONE) { - return [key, undefined]; - } else { - return /** @type {[K, Cell]} */ (pair); - } -}; - -/** - * @template K - * @template V - */ -class StackedMap { - /** - * @param {Map>[]=} parentStack an optional parent - */ - constructor(parentStack) { - /** @type {Map>} */ - this.map = new Map(); - /** @type {Map>[]} */ - this.stack = parentStack === undefined ? [] : parentStack.slice(); - this.stack.push(this.map); - } - - /** - * @param {K} item the key of the element to add - * @param {V} value the value of the element to add - * @returns {void} - */ - set(item, value) { - this.map.set(item, value === undefined ? UNDEFINED_MARKER : value); - } - - /** - * @param {K} item the item to delete - * @returns {void} - */ - delete(item) { - if (this.stack.length > 1) { - this.map.set(item, TOMBSTONE); - } else { - this.map.delete(item); - } - } - - /** - * @param {K} item the item to test - * @returns {boolean} true if the item exists in this set - */ - has(item) { - const topValue = this.map.get(item); - if (topValue !== undefined) { - return topValue !== TOMBSTONE; - } - if (this.stack.length > 1) { - for (let i = this.stack.length - 2; i >= 0; i--) { - const value = this.stack[i].get(item); - if (value !== undefined) { - this.map.set(item, value); - return value !== TOMBSTONE; - } - } - this.map.set(item, TOMBSTONE); - } - return false; - } - - /** - * @param {K} item the key of the element to return - * @returns {Cell} the value of the element - */ - get(item) { - const topValue = this.map.get(item); - if (topValue !== undefined) { - return topValue === TOMBSTONE || topValue === UNDEFINED_MARKER - ? undefined - : topValue; - } - if (this.stack.length > 1) { - for (let i = this.stack.length - 2; i >= 0; i--) { - const value = this.stack[i].get(item); - if (value !== undefined) { - this.map.set(item, value); - return value === TOMBSTONE || value === UNDEFINED_MARKER - ? undefined - : value; - } - } - this.map.set(item, TOMBSTONE); - } - return undefined; - } - - _compress() { - if (this.stack.length === 1) return; - this.map = new Map(); - for (const data of this.stack) { - for (const pair of data) { - if (pair[1] === TOMBSTONE) { - this.map.delete(pair[0]); - } else { - this.map.set(pair[0], pair[1]); - } - } - } - this.stack = [this.map]; - } - - asArray() { - this._compress(); - return Array.from(this.map.keys()); - } - - asSet() { - this._compress(); - return new Set(this.map.keys()); - } - - asPairArray() { - this._compress(); - return Array.from(this.map.entries(), extractPair); - } - - asMap() { - return new Map(this.asPairArray()); - } - - get size() { - this._compress(); - return this.map.size; - } - - createChild() { - return new StackedMap(this.stack); - } -} - -module.exports = StackedMap; diff --git a/lib/util/StringXor.js b/lib/util/StringXor.js index 9f77c020bc4..ea5c8f83544 100644 --- a/lib/util/StringXor.js +++ b/lib/util/StringXor.js @@ -5,44 +5,96 @@ "use strict"; +/** @typedef {import("../util/Hash")} Hash */ + +/** + * StringXor class provides methods for performing + * [XOR operations](https://en.wikipedia.org/wiki/Exclusive_or) on strings. In this context + * we operating on the character codes of two strings, which are represented as + * [Buffer](https://nodejs.org/api/buffer.html) objects. + * + * We use [StringXor in webpack](https://github.com/webpack/webpack/commit/41a8e2ea483a544c4ccd3e6217bdfb80daffca39) + * to create a hash of the current state of the compilation. By XOR'ing the Module hashes, it + * doesn't matter if the Module hashes are sorted or not. This is useful because it allows us to avoid sorting the + * Module hashes. + * @example + * ```js + * const xor = new StringXor(); + * xor.add('hello'); + * xor.add('world'); + * console.log(xor.toString()); + * ``` + * @example + * ```js + * const xor = new StringXor(); + * xor.add('foo'); + * xor.add('bar'); + * const hash = createHash('sha256'); + * hash.update(xor.toString()); + * console.log(hash.digest('hex')); + * ``` + */ class StringXor { constructor() { + /** @type {Buffer|undefined} */ this._value = undefined; - this._buffer = undefined; } + /** + * Adds a string to the current StringXor object. + * @param {string} str string + * @returns {void} + */ add(str) { - let buf = this._buffer; - let value; - if (buf === undefined) { - buf = this._buffer = Buffer.from(str, "latin1"); - this._value = Buffer.from(buf); + const len = str.length; + const value = this._value; + if (value === undefined) { + /** + * We are choosing to use Buffer.allocUnsafe() because it is often faster than Buffer.alloc() because + * it allocates a new buffer of the specified size without initializing the memory. + */ + const newValue = (this._value = Buffer.allocUnsafe(len)); + for (let i = 0; i < len; i++) { + newValue[i] = str.charCodeAt(i); + } return; - } else if (buf.length !== str.length) { - value = this._value; - buf = this._buffer = Buffer.from(str, "latin1"); - if (value.length < buf.length) { - this._value = Buffer.allocUnsafe(buf.length); - value.copy(this._value); - this._value.fill(0, value.length); - value = this._value; + } + const valueLen = value.length; + if (valueLen < len) { + const newValue = (this._value = Buffer.allocUnsafe(len)); + let i; + for (i = 0; i < valueLen; i++) { + newValue[i] = value[i] ^ str.charCodeAt(i); + } + for (; i < len; i++) { + newValue[i] = str.charCodeAt(i); } } else { - value = this._value; - buf.write(str, "latin1"); - } - const len = buf.length; - for (let i = 0; i < len; i++) { - value[i] = value[i] ^ buf[i]; + for (let i = 0; i < len; i++) { + value[i] = value[i] ^ str.charCodeAt(i); + } } } + /** + * Returns a string that represents the current state of the StringXor object. We chose to use "latin1" encoding + * here because "latin1" encoding is a single-byte encoding that can represent all characters in the + * [ISO-8859-1 character set](https://en.wikipedia.org/wiki/ISO/IEC_8859-1). This is useful when working + * with binary data that needs to be represented as a string. + * @returns {string} Returns a string that represents the current state of the StringXor object. + */ toString() { - return this._value === undefined ? "" : this._value.toString("latin1"); + const value = this._value; + return value === undefined ? "" : value.toString("latin1"); } + /** + * Updates the hash with the current state of the StringXor object. + * @param {Hash} hash Hash instance + */ updateHash(hash) { - if (this._value !== undefined) hash.update(this._value); + const value = this._value; + if (value !== undefined) hash.update(value); } } diff --git a/lib/util/TupleQueue.js b/lib/util/TupleQueue.js index 625df7fedc6..6cdd7ea9f2b 100644 --- a/lib/util/TupleQueue.js +++ b/lib/util/TupleQueue.js @@ -15,9 +15,15 @@ class TupleQueue { * @param {Iterable=} items The initial elements. */ constructor(items) { - /** @private @type {TupleSet} */ + /** + * @private + * @type {TupleSet} + */ this._set = new TupleSet(items); - /** @private @type {Iterator} */ + /** + * @private + * @type {Iterator} + */ this._iterator = this._set[Symbol.iterator](); } @@ -51,7 +57,7 @@ class TupleQueue { this._set.delete(...value); return value; } - return undefined; + return; } this._set.delete(...result.value); return result.value; diff --git a/lib/util/TupleSet.js b/lib/util/TupleSet.js index fe33c364a58..803ae194ec7 100644 --- a/lib/util/TupleSet.js +++ b/lib/util/TupleSet.js @@ -9,7 +9,11 @@ * @template {any[]} T */ class TupleSet { + /** + * @param {Iterable=} init init + */ constructor(init) { + /** @type {Map} */ this._map = new Map(); this.size = 0; if (init) { @@ -62,7 +66,7 @@ class TupleSet { } const beforeLast = args[args.length - 2]; - let set = map.get(beforeLast); + const set = map.get(beforeLast); if (set === undefined) { return false; } @@ -86,7 +90,7 @@ class TupleSet { } const beforeLast = args[args.length - 2]; - let set = map.get(beforeLast); + const set = map.get(beforeLast); if (set === undefined) { return; } @@ -101,10 +105,17 @@ class TupleSet { * @returns {Iterator} iterator */ [Symbol.iterator]() { + /** @type {TODO[]} */ const iteratorStack = []; + /** @type {T[]} */ const tuple = []; - let currentSetIterator = undefined; + /** @type {Iterator | undefined} */ + let currentSetIterator; + /** + * @param {TODO} it iterator + * @returns {boolean} result + */ const next = it => { const result = it.next(); if (result.done) { @@ -118,9 +129,8 @@ class TupleSet { if (value instanceof Set) { currentSetIterator = value[Symbol.iterator](); return true; - } else { - return next(value[Symbol.iterator]()); } + return next(value[Symbol.iterator]()); }; next(this._map[Symbol.iterator]()); diff --git a/lib/util/URLAbsoluteSpecifier.js b/lib/util/URLAbsoluteSpecifier.js index f9fda91c40e..f5cec7e4be0 100644 --- a/lib/util/URLAbsoluteSpecifier.js +++ b/lib/util/URLAbsoluteSpecifier.js @@ -36,7 +36,7 @@ function getScheme(specifier) { (start < aLowerCaseCharCode || start > zLowerCaseCharCode) && (start < aUpperCaseCharCode || start > zUpperCaseCharCode) ) { - return undefined; + return; } let i = 1; @@ -49,12 +49,12 @@ function getScheme(specifier) { ch === plusCharCode || ch === hyphenCharCode ) { - if (++i === specifier.length) return undefined; + if (++i === specifier.length) return; ch = specifier.charCodeAt(i); } // Scheme must end with colon - if (ch !== colonCharCode) return undefined; + if (ch !== colonCharCode) return; // Check for Windows absolute path // https://url.spec.whatwg.org/#url-miscellaneous @@ -67,7 +67,7 @@ function getScheme(specifier) { nextChar === hashCharCode || nextChar === queryCharCode ) { - return undefined; + return; } } @@ -76,12 +76,12 @@ function getScheme(specifier) { /** * @param {string} specifier specifier - * @returns {string|null} protocol if absolute URL specifier provided + * @returns {string | null | undefined} protocol if absolute URL specifier provided */ function getProtocol(specifier) { const scheme = getScheme(specifier); - return scheme === undefined ? undefined : scheme + ":"; + return scheme === undefined ? undefined : `${scheme}:`; } -exports.getScheme = getScheme; -exports.getProtocol = getProtocol; +module.exports.getScheme = getScheme; +module.exports.getProtocol = getProtocol; diff --git a/lib/util/WeakTupleMap.js b/lib/util/WeakTupleMap.js new file mode 100644 index 00000000000..ac64e8695df --- /dev/null +++ b/lib/util/WeakTupleMap.js @@ -0,0 +1,213 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ + +"use strict"; + +/** + * @template {any[]} T + * @template V + * @typedef {Map>} M + */ +/** + * @template {any[]} T + * @template V + * @typedef {WeakMap>} W + */ + +/** + * @param {any} thing thing + * @returns {boolean} true if is weak + */ +const isWeakKey = thing => typeof thing === "object" && thing !== null; + +/** + * @template {any[]} T + * @template V + */ +class WeakTupleMap { + constructor() { + /** @private */ + this.f = 0; + /** + * @private + * @type {any} + */ + this.v = undefined; + /** + * @private + * @type {M | undefined} + */ + this.m = undefined; + /** + * @private + * @type {W | undefined} + */ + this.w = undefined; + } + + /** + * @param {[...T, V]} args tuple + * @returns {void} + */ + set(...args) { + /** @type {WeakTupleMap} */ + let node = this; + for (let i = 0; i < args.length - 1; i++) { + node = node._get(args[i]); + } + node._setValue(args[args.length - 1]); + } + + /** + * @param {T} args tuple + * @returns {boolean} true, if the tuple is in the Set + */ + has(...args) { + /** @type {WeakTupleMap | undefined} */ + let node = this; + for (let i = 0; i < args.length; i++) { + node = node._peek(args[i]); + if (node === undefined) return false; + } + return node._hasValue(); + } + + /** + * @param {T} args tuple + * @returns {V | undefined} the value + */ + get(...args) { + /** @type {WeakTupleMap | undefined} */ + let node = this; + for (let i = 0; i < args.length; i++) { + node = node._peek(args[i]); + if (node === undefined) return; + } + return node._getValue(); + } + + /** + * @param {[...T, function(): V]} args tuple + * @returns {V} the value + */ + provide(...args) { + /** @type {WeakTupleMap} */ + let node = this; + for (let i = 0; i < args.length - 1; i++) { + node = node._get(args[i]); + } + if (node._hasValue()) return node._getValue(); + const fn = args[args.length - 1]; + const newValue = fn(...args.slice(0, -1)); + node._setValue(newValue); + return newValue; + } + + /** + * @param {T} args tuple + * @returns {void} + */ + delete(...args) { + /** @type {WeakTupleMap | undefined} */ + let node = this; + for (let i = 0; i < args.length; i++) { + node = node._peek(args[i]); + if (node === undefined) return; + } + node._deleteValue(); + } + + /** + * @returns {void} + */ + clear() { + this.f = 0; + this.v = undefined; + this.w = undefined; + this.m = undefined; + } + + _getValue() { + return this.v; + } + + _hasValue() { + return (this.f & 1) === 1; + } + + /** + * @param {any} v value + * @private + */ + _setValue(v) { + this.f |= 1; + this.v = v; + } + + _deleteValue() { + this.f &= 6; + this.v = undefined; + } + + /** + * @param {any} thing thing + * @returns {WeakTupleMap | undefined} thing + * @private + */ + _peek(thing) { + if (isWeakKey(thing)) { + if ((this.f & 4) !== 4) return; + return /** @type {W} */ (this.w).get(thing); + } + if ((this.f & 2) !== 2) return; + return /** @type {M} */ (this.m).get(thing); + } + + /** + * @private + * @param {any} thing thing + * @returns {WeakTupleMap} value + */ + _get(thing) { + if (isWeakKey(thing)) { + if ((this.f & 4) !== 4) { + const newMap = new WeakMap(); + this.f |= 4; + const newNode = new WeakTupleMap(); + (this.w = newMap).set(thing, newNode); + return newNode; + } + const entry = + /** @type {W} */ + (this.w).get(thing); + if (entry !== undefined) { + return entry; + } + const newNode = new WeakTupleMap(); + /** @type {W} */ + (this.w).set(thing, newNode); + return newNode; + } + if ((this.f & 2) !== 2) { + const newMap = new Map(); + this.f |= 2; + const newNode = new WeakTupleMap(); + (this.m = newMap).set(thing, newNode); + return newNode; + } + const entry = + /** @type {M} */ + (this.m).get(thing); + if (entry !== undefined) { + return entry; + } + const newNode = new WeakTupleMap(); + /** @type {M} */ + (this.m).set(thing, newNode); + return newNode; + } +} + +module.exports = WeakTupleMap; diff --git a/lib/util/binarySearchBounds.js b/lib/util/binarySearchBounds.js index 5bc506af8af..c61623c1bf5 100644 --- a/lib/util/binarySearchBounds.js +++ b/lib/util/binarySearchBounds.js @@ -8,6 +8,27 @@ /* cspell:disable-next-line */ // Refactor: Peter Somogyvari @petermetz +/** @typedef {">=" | "<=" | "<" | ">" | "-" } BinarySearchPredicate */ +/** @typedef {"GE" | "GT" | "LT" | "LE" | "EQ" } SearchPredicateSuffix */ + +/** + * Helper function for compiling binary search functions. + * + * The generated code uses a while loop to repeatedly divide the search interval + * in half until the desired element is found, or the search interval is empty. + * + * The following is an example of a generated function for calling `compileSearch("P", "c(x,y)<=0", true, ["y", "c"], false)`: + * + * ```js + * function P(a,l,h,y,c){var i=l-1;while(l<=h){var m=(l+h)>>>1,x=a[m];if(c(x,y)<=0){i=m;l=m+1}else{h=m-1}}return i}; + * ``` + * @param {string} funcName The name of the function to be compiled. + * @param {string} predicate The predicate / comparison operator to be used in the binary search. + * @param {boolean} reversed Whether the search should be reversed. + * @param {string[]} extraArgs Extra arguments to be passed to the function. + * @param {boolean=} earlyOut Whether the search should return as soon as a match is found. + * @returns {string} The compiled binary search function. + */ const compileSearch = (funcName, predicate, reversed, extraArgs, earlyOut) => { const code = [ "function ", @@ -21,7 +42,7 @@ const compileSearch = (funcName, predicate, reversed, extraArgs, earlyOut) => { ]; if (earlyOut) { - if (predicate.indexOf("c") < 0) { + if (!predicate.includes("c")) { code.push(";if(x===y){return m}else if(x<=y){"); } else { code.push(";var p=c(x,y);if(p===0){return m}else if(p<=0){"); @@ -43,18 +64,23 @@ const compileSearch = (funcName, predicate, reversed, extraArgs, earlyOut) => { return code.join(""); }; +/** + * This helper functions generate code for two binary search functions: + * A(): Performs a binary search on an array using the comparison operator specified. + * P(): Performs a binary search on an array using a _custom comparison function_ + * `c(x,y)` **and** comparison operator specified by `predicate`. + * @param {BinarySearchPredicate} predicate The predicate / comparison operator to be used in the binary search. + * @param {boolean} reversed Whether the search should be reversed. + * @param {SearchPredicateSuffix} suffix The suffix to be used in the function name. + * @param {boolean=} earlyOut Whether the search should return as soon as a match is found. + * @returns {Function} The compiled binary search function. + */ const compileBoundsSearch = (predicate, reversed, suffix, earlyOut) => { - const arg1 = compileSearch( - "A", - "x" + predicate + "y", - reversed, - ["y"], - earlyOut - ); + const arg1 = compileSearch("A", `x${predicate}y`, reversed, ["y"], earlyOut); const arg2 = compileSearch( "P", - "c(x,y)" + predicate + "0", + `c(x,y)${predicate}0`, reversed, ["y", "c"], earlyOut @@ -63,6 +89,7 @@ const compileBoundsSearch = (predicate, reversed, suffix, earlyOut) => { const fnHeader = "function dispatchBinarySearch"; const fnBody = + // eslint-disable-next-line no-multi-str "(a,y,c,l,h){\ if(typeof(c)==='function'){\ return P(a,(l===void 0)?0:l|0,(h===void 0)?a.length-1:h|0,y,c)\ @@ -73,10 +100,25 @@ return dispatchBinarySearch"; const fnArgList = [arg1, arg2, fnHeader, suffix, fnBody, suffix]; const fnSource = fnArgList.join(""); + // eslint-disable-next-line no-new-func const result = new Function(fnSource); return result(); }; +/** + * These functions are used to perform binary searches on arrays. + * @example + * ```js + * const { gt, le} = require("./binarySearchBounds"); + * const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9]; + * + * // Find the index of the first element greater than 5 + * const index1 = gt(arr, 5); // index1 === 3 + * + * // Find the index of the first element less than or equal to 5 + * const index2 = le(arr, 5); // index2 === 4 + * ``` + */ module.exports = { ge: compileBoundsSearch(">=", false, "GE"), gt: compileBoundsSearch(">", false, "GT"), diff --git a/lib/util/chainedImports.js b/lib/util/chainedImports.js new file mode 100644 index 00000000000..295233b7d1c --- /dev/null +++ b/lib/util/chainedImports.js @@ -0,0 +1,97 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ + +"use strict"; + +/** @typedef {import("../Dependency")} Dependency */ +/** @typedef {import("../Module")} Module */ +/** @typedef {import("../ModuleGraph")} ModuleGraph */ +/** @typedef {import("../javascript/JavascriptParser").Range} Range */ + +/** + * @summary Get the subset of ids and their corresponding range in an id chain that should be re-rendered by webpack. + * Only those in the chain that are actually referring to namespaces or imports should be re-rendered. + * Deeper member accessors on the imported object should not be re-rendered. If deeper member accessors are re-rendered, + * there is a potential loss of meaning with rendering a quoted accessor as an unquoted accessor, or vice versa, + * because minifiers treat quoted accessors differently. e.g. import { a } from "./module"; a["b"] vs a.b + * @param {string[]} untrimmedIds chained ids + * @param {Range} untrimmedRange range encompassing allIds + * @param {Range[] | undefined} ranges cumulative range of ids for each of allIds + * @param {ModuleGraph} moduleGraph moduleGraph + * @param {Dependency} dependency dependency + * @returns {{trimmedIds: string[], trimmedRange: Range}} computed trimmed ids and cumulative range of those ids + */ +module.exports.getTrimmedIdsAndRange = ( + untrimmedIds, + untrimmedRange, + ranges, + moduleGraph, + dependency +) => { + let trimmedIds = trimIdsToThoseImported( + untrimmedIds, + moduleGraph, + dependency + ); + let trimmedRange = untrimmedRange; + if (trimmedIds.length !== untrimmedIds.length) { + // The array returned from dep.idRanges is right-aligned with the array returned from dep.names. + // Meaning, the two arrays may not always have the same number of elements, but the last element of + // dep.idRanges corresponds to [the expression fragment to the left of] the last element of dep.names. + // Use this to find the correct replacement range based on the number of ids that were trimmed. + const idx = + ranges === undefined + ? -1 /* trigger failure case below */ + : ranges.length + (trimmedIds.length - untrimmedIds.length); + if (idx < 0 || idx >= /** @type {Range[]} */ (ranges).length) { + // cspell:ignore minifiers + // Should not happen but we can't throw an error here because of backward compatibility with + // external plugins in wp5. Instead, we just disable trimming for now. This may break some minifiers. + trimmedIds = untrimmedIds; + // TODO webpack 6 remove the "trimmedIds = ids" above and uncomment the following line instead. + // throw new Error("Missing range starts data for id replacement trimming."); + } else { + trimmedRange = /** @type {Range[]} */ (ranges)[idx]; + } + } + + return { trimmedIds, trimmedRange }; +}; + +/** + * @summary Determine which IDs in the id chain are actually referring to namespaces or imports, + * and which are deeper member accessors on the imported object. + * @param {string[]} ids untrimmed ids + * @param {ModuleGraph} moduleGraph moduleGraph + * @param {Dependency} dependency dependency + * @returns {string[]} trimmed ids + */ +function trimIdsToThoseImported(ids, moduleGraph, dependency) { + /** @type {string[]} */ + let trimmedIds = []; + let currentExportsInfo = moduleGraph.getExportsInfo( + /** @type {Module} */ (moduleGraph.getModule(dependency)) + ); + for (let i = 0; i < ids.length; i++) { + if (i === 0 && ids[i] === "default") { + continue; // ExportInfo for the next level under default is still at the root ExportsInfo, so don't advance currentExportsInfo + } + const exportInfo = currentExportsInfo.getExportInfo(ids[i]); + if (exportInfo.provided === false) { + // json imports have nested ExportInfo for elements that things that are not actually exported, so check .provided + trimmedIds = ids.slice(0, i); + break; + } + const nestedInfo = exportInfo.getNestedExportsInfo(); + if (!nestedInfo) { + // once all nested exports are traversed, the next item is the actual import so stop there + trimmedIds = ids.slice(0, i + 1); + break; + } + currentExportsInfo = nestedInfo; + } + // Never trim to nothing. This can happen for invalid imports (e.g. import { notThere } from "./module", or import { anything } from "./missingModule") + return trimmedIds.length ? trimmedIds : ids; +} diff --git a/lib/util/cleverMerge.js b/lib/util/cleverMerge.js index f845dc75d72..67479a1e0c2 100644 --- a/lib/util/cleverMerge.js +++ b/lib/util/cleverMerge.js @@ -23,26 +23,28 @@ const DYNAMIC_INFO = Symbol("cleverMerge dynamic info"); * // when same arguments passed, gets the result from WeakMap and returns it. * cachedCleverMerge({a: 1}, {a: 2}) * {a: 2} - * @param {T} first first object - * @param {O} second second object + * @param {T | null | undefined} first first object + * @param {O | null | undefined} second second object * @returns {T & O | T | O} merged object of first and second object */ const cachedCleverMerge = (first, second) => { - if (second === undefined) return first; - if (first === undefined) return second; - if (typeof second !== "object" || second === null) return second; - if (typeof first !== "object" || first === null) return first; + if (second === undefined) return /** @type {T} */ (first); + if (first === undefined) return /** @type {O} */ (second); + if (typeof second !== "object" || second === null) + return /** @type {O} */ (second); + if (typeof first !== "object" || first === null) + return /** @type {T} */ (first); let innerCache = mergeCache.get(first); if (innerCache === undefined) { innerCache = new WeakMap(); mergeCache.set(first, innerCache); } - const prevMerge = innerCache.get(second); + const prevMerge = /** @type {T & O} */ (innerCache.get(second)); if (prevMerge !== undefined) return prevMerge; const newMerge = _cleverMerge(first, second, true); innerCache.set(second, newMerge); - return newMerge; + return /** @type {T & O} */ (newMerge); }; /** @@ -69,7 +71,7 @@ const cachedSetProperty = (obj, property, value) => { let result = mapByValue.get(value); - if (result) return result; + if (result) return /** @type {T} */ (result); result = { ...obj, @@ -77,18 +79,18 @@ const cachedSetProperty = (obj, property, value) => { }; mapByValue.set(value, result); - return result; + return /** @type {T} */ (result); }; /** - * @typedef {Object} ObjectParsedPropertyEntry + * @typedef {object} ObjectParsedPropertyEntry * @property {any | undefined} base base value * @property {string | undefined} byProperty the name of the selector property * @property {Map} byValues value depending on selector property, merged with base */ /** - * @typedef {Object} ParsedObject + * @typedef {object} ParsedObject * @property {Map} static static properties (key is property name) * @property {{ byProperty: string, fn: Function } | undefined} dynamic dynamic part */ @@ -229,7 +231,7 @@ const getValueType = value => { } else if (value === DELETE) { return VALUE_TYPE_DELETE; } else if (Array.isArray(value)) { - if (value.lastIndexOf("...") !== -1) return VALUE_TYPE_ARRAY_EXTEND; + if (value.includes("...")) return VALUE_TYPE_ARRAY_EXTEND; return VALUE_TYPE_ATOM; } else if ( typeof value === "object" && @@ -257,7 +259,7 @@ const cleverMerge = (first, second) => { if (typeof second !== "object" || second === null) return second; if (typeof first !== "object" || first === null) return first; - return _cleverMerge(first, second, false); + return /** @type {T & O} */ (_cleverMerge(first, second, false)); }; /** @@ -457,8 +459,8 @@ const mergeSingleValue = (a, b, internalCaching) => { return aType !== VALUE_TYPE_OBJECT ? b : internalCaching - ? cachedCleverMerge(a, b) - : cleverMerge(a, b); + ? cachedCleverMerge(a, b) + : cleverMerge(a, b); } case VALUE_TYPE_UNDEFINED: return a; @@ -467,8 +469,8 @@ const mergeSingleValue = (a, b, internalCaching) => { aType !== VALUE_TYPE_ATOM ? aType : Array.isArray(a) - ? VALUE_TYPE_ARRAY_EXTEND - : VALUE_TYPE_OBJECT + ? VALUE_TYPE_ARRAY_EXTEND + : VALUE_TYPE_OBJECT ) { case VALUE_TYPE_UNDEFINED: return b; @@ -498,27 +500,40 @@ const mergeSingleValue = (a, b, internalCaching) => { }; /** - * @template T + * @template {object} T * @param {T} obj the object + * @param {(keyof T)[]=} keysToKeepOriginalValue keys to keep original value * @returns {T} the object without operations like "..." or DELETE */ -const removeOperations = obj => { +const removeOperations = (obj, keysToKeepOriginalValue = []) => { const newObj = /** @type {T} */ ({}); for (const key of Object.keys(obj)) { - const value = obj[key]; + const value = obj[/** @type {keyof T} */ (key)]; const type = getValueType(value); + if ( + type === VALUE_TYPE_OBJECT && + keysToKeepOriginalValue.includes(/** @type {keyof T} */ (key)) + ) { + newObj[/** @type {keyof T} */ (key)] = value; + continue; + } switch (type) { case VALUE_TYPE_UNDEFINED: case VALUE_TYPE_DELETE: break; case VALUE_TYPE_OBJECT: - newObj[key] = removeOperations(value); + newObj[key] = removeOperations( + /** @type {TODO} */ (value), + keysToKeepOriginalValue + ); break; case VALUE_TYPE_ARRAY_EXTEND: - newObj[key] = value.filter(i => i !== "..."); + newObj[key] = + /** @type {any[]} */ + (value).filter(i => i !== "..."); break; default: - newObj[key] = value; + newObj[/** @type {keyof T} */ (key)] = value; break; } } @@ -537,19 +552,21 @@ const resolveByProperty = (obj, byProperty, ...values) => { if (typeof obj !== "object" || obj === null || !(byProperty in obj)) { return obj; } - const { [byProperty]: _byValue, ..._remaining } = /** @type {object} */ (obj); + const { [byProperty]: _byValue, ..._remaining } = obj; const remaining = /** @type {T} */ (_remaining); - const byValue = /** @type {Record | function(...any[]): T} */ (_byValue); + const byValue = + /** @type {Record | function(...any[]): T} */ + (_byValue); if (typeof byValue === "object") { const key = values[0]; if (key in byValue) { return cachedCleverMerge(remaining, byValue[key]); } else if ("default" in byValue) { return cachedCleverMerge(remaining, byValue.default); - } else { - return /** @type {T} */ (remaining); } + return remaining; } else if (typeof byValue === "function") { + // eslint-disable-next-line prefer-spread const result = byValue.apply(null, values); return cachedCleverMerge( remaining, @@ -558,9 +575,9 @@ const resolveByProperty = (obj, byProperty, ...values) => { } }; -exports.cachedSetProperty = cachedSetProperty; -exports.cachedCleverMerge = cachedCleverMerge; -exports.cleverMerge = cleverMerge; -exports.resolveByProperty = resolveByProperty; -exports.removeOperations = removeOperations; -exports.DELETE = DELETE; +module.exports.cachedSetProperty = cachedSetProperty; +module.exports.cachedCleverMerge = cachedCleverMerge; +module.exports.cleverMerge = cleverMerge; +module.exports.resolveByProperty = resolveByProperty; +module.exports.removeOperations = removeOperations; +module.exports.DELETE = DELETE; diff --git a/lib/util/comparators.js b/lib/util/comparators.js index ead1ceaeb2f..8d228026e4f 100644 --- a/lib/util/comparators.js +++ b/lib/util/comparators.js @@ -8,15 +8,28 @@ const { compareRuntime } = require("./runtime"); /** @typedef {import("../Chunk")} Chunk */ +/** @typedef {import("../Chunk").ChunkId} ChunkId */ /** @typedef {import("../ChunkGraph")} ChunkGraph */ +/** @typedef {import("../ChunkGraph").ModuleId} ModuleId */ /** @typedef {import("../ChunkGroup")} ChunkGroup */ /** @typedef {import("../Dependency").DependencyLocation} DependencyLocation */ /** @typedef {import("../Module")} Module */ /** @typedef {import("../ModuleGraph")} ModuleGraph */ -/** @template T @typedef {function(T, T): -1|0|1} Comparator */ -/** @template TArg @template T @typedef {function(TArg, T, T): -1|0|1} RawParameterizedComparator */ -/** @template TArg @template T @typedef {function(TArg): Comparator} ParameterizedComparator */ +/** + * @template T + * @typedef {function(T, T): -1|0|1} Comparator + */ +/** + * @template TArg + * @template T + * @typedef {function(TArg, T, T): -1|0|1} RawParameterizedComparator + */ +/** + * @template TArg + * @template T + * @typedef {function(TArg): Comparator} ParameterizedComparator + */ /** * @template T @@ -34,9 +47,7 @@ const createCachedParameterizedComparator = fn => { * @param {T} b second item * @returns {-1|0|1} compare result */ - const result = (a, b) => { - return fn(arg, a, b); - }; + const result = fn.bind(null, arg); map.set(arg, result); return result; }; @@ -47,18 +58,16 @@ const createCachedParameterizedComparator = fn => { * @param {Chunk} b chunk * @returns {-1|0|1} compare result */ -exports.compareChunksById = (a, b) => { - return compareIds(a.id, b.id); -}; +module.exports.compareChunksById = (a, b) => + compareIds(/** @type {ChunkId} */ (a.id), /** @type {ChunkId} */ (b.id)); /** * @param {Module} a module * @param {Module} b module * @returns {-1|0|1} compare result */ -exports.compareModulesByIdentifier = (a, b) => { - return compareIds(a.identifier(), b.identifier()); -}; +module.exports.compareModulesByIdentifier = (a, b) => + compareIds(a.identifier(), b.identifier()); /** * @param {ChunkGraph} chunkGraph the chunk graph @@ -66,13 +75,14 @@ exports.compareModulesByIdentifier = (a, b) => { * @param {Module} b module * @returns {-1|0|1} compare result */ -const compareModulesById = (chunkGraph, a, b) => { - return compareIds(chunkGraph.getModuleId(a), chunkGraph.getModuleId(b)); -}; +const compareModulesById = (chunkGraph, a, b) => + compareIds( + /** @type {ModuleId} */ (chunkGraph.getModuleId(a)), + /** @type {ModuleId} */ (chunkGraph.getModuleId(b)) + ); /** @type {ParameterizedComparator} */ -exports.compareModulesById = createCachedParameterizedComparator( - compareModulesById -); +module.exports.compareModulesById = + createCachedParameterizedComparator(compareModulesById); /** * @param {number} a number @@ -87,7 +97,7 @@ const compareNumbers = (a, b) => { if (a > b) return 1; return 0; }; -exports.compareNumbers = compareNumbers; +module.exports.compareNumbers = compareNumbers; /** * @param {string} a string @@ -95,35 +105,71 @@ exports.compareNumbers = compareNumbers; * @returns {-1|0|1} compare result */ const compareStringsNumeric = (a, b) => { - const partsA = a.split(/(\d+)/); - const partsB = b.split(/(\d+)/); - const len = Math.min(partsA.length, partsB.length); - for (let i = 0; i < len; i++) { - const pA = partsA[i]; - const pB = partsB[i]; - if (i % 2 === 0) { - if (pA.length > pB.length) { - if (pA.slice(0, pB.length) > pB) return 1; - return -1; - } else if (pB.length > pA.length) { - if (pB.slice(0, pA.length) > pA) return -1; - return 1; - } else { - if (pA < pB) return -1; - if (pA > pB) return 1; - } + const aLength = a.length; + const bLength = b.length; + + let aChar = 0; + let bChar = 0; + + let aIsDigit = false; + let bIsDigit = false; + let i = 0; + let j = 0; + while (i < aLength && j < bLength) { + aChar = a.charCodeAt(i); + bChar = b.charCodeAt(j); + + aIsDigit = aChar >= 48 && aChar <= 57; + bIsDigit = bChar >= 48 && bChar <= 57; + + if (!aIsDigit && !bIsDigit) { + if (aChar < bChar) return -1; + if (aChar > bChar) return 1; + i++; + j++; + } else if (aIsDigit && !bIsDigit) { + // This segment of a is shorter than in b + return 1; + } else if (!aIsDigit && bIsDigit) { + // This segment of b is shorter than in a + return -1; } else { - const nA = +pA; - const nB = +pB; - if (nA < nB) return -1; - if (nA > nB) return 1; + let aNumber = aChar - 48; + let bNumber = bChar - 48; + + while (++i < aLength) { + aChar = a.charCodeAt(i); + if (aChar < 48 || aChar > 57) break; + aNumber = aNumber * 10 + aChar - 48; + } + + while (++j < bLength) { + bChar = b.charCodeAt(j); + if (bChar < 48 || bChar > 57) break; + bNumber = bNumber * 10 + bChar - 48; + } + + if (aNumber < bNumber) return -1; + if (aNumber > bNumber) return 1; } } - if (partsB.length < partsA.length) return 1; - if (partsB.length > partsA.length) return -1; + + if (j < bLength) { + // a is shorter than b + bChar = b.charCodeAt(j); + bIsDigit = bChar >= 48 && bChar <= 57; + return bIsDigit ? -1 : 1; + } + if (i < aLength) { + // b is shorter than a + aChar = a.charCodeAt(i); + aIsDigit = aChar >= 48 && aChar <= 57; + return aIsDigit ? 1 : -1; + } + return 0; }; -exports.compareStringsNumeric = compareStringsNumeric; +module.exports.compareStringsNumeric = compareStringsNumeric; /** * @param {ModuleGraph} moduleGraph the module graph @@ -133,16 +179,17 @@ exports.compareStringsNumeric = compareStringsNumeric; */ const compareModulesByPostOrderIndexOrIdentifier = (moduleGraph, a, b) => { const cmp = compareNumbers( - moduleGraph.getPostOrderIndex(a), - moduleGraph.getPostOrderIndex(b) + /** @type {number} */ (moduleGraph.getPostOrderIndex(a)), + /** @type {number} */ (moduleGraph.getPostOrderIndex(b)) ); if (cmp !== 0) return cmp; return compareIds(a.identifier(), b.identifier()); }; /** @type {ParameterizedComparator} */ -exports.compareModulesByPostOrderIndexOrIdentifier = createCachedParameterizedComparator( - compareModulesByPostOrderIndexOrIdentifier -); +module.exports.compareModulesByPostOrderIndexOrIdentifier = + createCachedParameterizedComparator( + compareModulesByPostOrderIndexOrIdentifier + ); /** * @param {ModuleGraph} moduleGraph the module graph @@ -152,16 +199,17 @@ exports.compareModulesByPostOrderIndexOrIdentifier = createCachedParameterizedCo */ const compareModulesByPreOrderIndexOrIdentifier = (moduleGraph, a, b) => { const cmp = compareNumbers( - moduleGraph.getPreOrderIndex(a), - moduleGraph.getPreOrderIndex(b) + /** @type {number} */ (moduleGraph.getPreOrderIndex(a)), + /** @type {number} */ (moduleGraph.getPreOrderIndex(b)) ); if (cmp !== 0) return cmp; return compareIds(a.identifier(), b.identifier()); }; /** @type {ParameterizedComparator} */ -exports.compareModulesByPreOrderIndexOrIdentifier = createCachedParameterizedComparator( - compareModulesByPreOrderIndexOrIdentifier -); +module.exports.compareModulesByPreOrderIndexOrIdentifier = + createCachedParameterizedComparator( + compareModulesByPreOrderIndexOrIdentifier + ); /** * @param {ChunkGraph} chunkGraph the chunk graph @@ -170,14 +218,16 @@ exports.compareModulesByPreOrderIndexOrIdentifier = createCachedParameterizedCom * @returns {-1|0|1} compare result */ const compareModulesByIdOrIdentifier = (chunkGraph, a, b) => { - const cmp = compareIds(chunkGraph.getModuleId(a), chunkGraph.getModuleId(b)); + const cmp = compareIds( + /** @type {ModuleId} */ (chunkGraph.getModuleId(a)), + /** @type {ModuleId} */ (chunkGraph.getModuleId(b)) + ); if (cmp !== 0) return cmp; return compareIds(a.identifier(), b.identifier()); }; /** @type {ParameterizedComparator} */ -exports.compareModulesByIdOrIdentifier = createCachedParameterizedComparator( - compareModulesByIdOrIdentifier -); +module.exports.compareModulesByIdOrIdentifier = + createCachedParameterizedComparator(compareModulesByIdOrIdentifier); /** * @param {ChunkGraph} chunkGraph the chunk graph @@ -185,11 +235,10 @@ exports.compareModulesByIdOrIdentifier = createCachedParameterizedComparator( * @param {Chunk} b chunk * @returns {-1|0|1} compare result */ -const compareChunks = (chunkGraph, a, b) => { - return chunkGraph.compareChunks(a, b); -}; +const compareChunks = (chunkGraph, a, b) => chunkGraph.compareChunks(a, b); /** @type {ParameterizedComparator} */ -exports.compareChunks = createCachedParameterizedComparator(compareChunks); +module.exports.compareChunks = + createCachedParameterizedComparator(compareChunks); /** * @param {string|number} a first id @@ -205,7 +254,7 @@ const compareIds = (a, b) => { return 0; }; -exports.compareIds = compareIds; +module.exports.compareIds = compareIds; /** * @param {string} a first string @@ -218,18 +267,16 @@ const compareStrings = (a, b) => { return 0; }; -exports.compareStrings = compareStrings; +module.exports.compareStrings = compareStrings; /** * @param {ChunkGroup} a first chunk group * @param {ChunkGroup} b second chunk group * @returns {-1|0|1} compare result */ -const compareChunkGroupsByIndex = (a, b) => { - return a.index < b.index ? -1 : 1; -}; - -exports.compareChunkGroupsByIndex = compareChunkGroupsByIndex; +const compareChunkGroupsByIndex = (a, b) => + /** @type {number} */ (a.index) < /** @type {number} */ (b.index) ? -1 : 1; +module.exports.compareChunkGroupsByIndex = compareChunkGroupsByIndex; /** * @template K1 {Object} @@ -238,7 +285,10 @@ exports.compareChunkGroupsByIndex = compareChunkGroupsByIndex; */ class TwoKeyWeakMap { constructor() { - /** @private @type {WeakMap>} */ + /** + * @private + * @type {WeakMap>} + */ this._map = new WeakMap(); } @@ -250,7 +300,7 @@ class TwoKeyWeakMap { get(key1, key2) { const childMap = this._map.get(key1); if (childMap === undefined) { - return undefined; + return; } return childMap.get(key2); } @@ -286,10 +336,9 @@ const concatComparators = (c1, c2, ...cRest) => { const [c3, ...cRest2] = cRest; return concatComparators(c1, concatComparators(c2, c3, ...cRest2)); } - const cacheEntry = /** @type {Comparator} */ (concatComparatorsCache.get( - c1, - c2 - )); + const cacheEntry = /** @type {Comparator} */ ( + concatComparatorsCache.get(c1, c2) + ); if (cacheEntry !== undefined) return cacheEntry; /** * @param {T} a first value @@ -304,9 +353,12 @@ const concatComparators = (c1, c2, ...cRest) => { concatComparatorsCache.set(c1, c2, result); return result; }; -exports.concatComparators = concatComparators; +module.exports.concatComparators = concatComparators; -/** @template A, B @typedef {(input: A) => B} Selector */ +/** + * @template A, B + * @typedef {(input: A) => B | undefined | null} Selector + */ /** @type {TwoKeyWeakMap, Comparator, Comparator>}} */ const compareSelectCache = new TwoKeyWeakMap(); @@ -334,17 +386,16 @@ const compareSelect = (getter, comparator) => { return comparator(aValue, bValue); } return -1; - } else { - if (bValue !== undefined && bValue !== null) { - return 1; - } - return 0; } + if (bValue !== undefined && bValue !== null) { + return 1; + } + return 0; }; compareSelectCache.set(getter, comparator, result); return result; }; -exports.compareSelect = compareSelect; +module.exports.compareSelect = compareSelect; /** @type {WeakMap, Comparator>>} */ const compareIteratorsCache = new WeakMap(); @@ -365,7 +416,6 @@ const compareIterables = elementComparator => { const result = (a, b) => { const aI = a[Symbol.iterator](); const bI = b[Symbol.iterator](); - // eslint-disable-next-line no-constant-condition while (true) { const aItem = aI.next(); const bItem = bI.next(); @@ -381,7 +431,7 @@ const compareIterables = elementComparator => { compareIteratorsCache.set(elementComparator, result); return result; }; -exports.compareIterables = compareIterables; +module.exports.compareIterables = compareIterables; // TODO this is no longer needed when minimum node.js version is >= 12 // since these versions ship with a stable sort function @@ -390,25 +440,32 @@ exports.compareIterables = compareIterables; * @param {Iterable} iterable original ordered list * @returns {Comparator} comparator */ -exports.keepOriginalOrder = iterable => { +module.exports.keepOriginalOrder = iterable => { /** @type {Map} */ const map = new Map(); let i = 0; for (const item of iterable) { map.set(item, i++); } - return (a, b) => compareNumbers(map.get(a), map.get(b)); + return (a, b) => + compareNumbers( + /** @type {number} */ (map.get(a)), + /** @type {number} */ (map.get(b)) + ); }; /** * @param {ChunkGraph} chunkGraph the chunk graph * @returns {Comparator} comparator */ -exports.compareChunksNatural = chunkGraph => { - const cmpFn = exports.compareModulesById(chunkGraph); +module.exports.compareChunksNatural = chunkGraph => { + const cmpFn = module.exports.compareModulesById(chunkGraph); const cmpIterableFn = compareIterables(cmpFn); return concatComparators( - compareSelect(chunk => chunk.name, compareIds), + compareSelect( + chunk => /** @type {string|number} */ (chunk.name), + compareIds + ), compareSelect(chunk => chunk.runtime, compareRuntime), compareSelect( /** @@ -427,29 +484,39 @@ exports.compareChunksNatural = chunkGraph => { * @param {DependencyLocation} b A location node * @returns {-1|0|1} sorting comparator value */ -exports.compareLocations = (a, b) => { - let isObjectA = typeof a === "object" && a !== null; - let isObjectB = typeof b === "object" && b !== null; +module.exports.compareLocations = (a, b) => { + const isObjectA = typeof a === "object" && a !== null; + const isObjectB = typeof b === "object" && b !== null; if (!isObjectA || !isObjectB) { if (isObjectA) return 1; if (isObjectB) return -1; return 0; } - if ("start" in a && "start" in b) { - const ap = a.start; - const bp = b.start; - if (ap.line < bp.line) return -1; - if (ap.line > bp.line) return 1; - if (ap.column < bp.column) return -1; - if (ap.column > bp.column) return 1; - } - if ("name" in a && "name" in b) { - if (a.name < b.name) return -1; - if (a.name > b.name) return 1; - } - if ("index" in a && "index" in b) { - if (a.index < b.index) return -1; - if (a.index > b.index) return 1; - } + if ("start" in a) { + if ("start" in b) { + const ap = a.start; + const bp = b.start; + if (ap.line < bp.line) return -1; + if (ap.line > bp.line) return 1; + if (/** @type {number} */ (ap.column) < /** @type {number} */ (bp.column)) + return -1; + if (/** @type {number} */ (ap.column) > /** @type {number} */ (bp.column)) + return 1; + } else return -1; + } else if ("start" in b) return 1; + if ("name" in a) { + if ("name" in b) { + if (a.name < b.name) return -1; + if (a.name > b.name) return 1; + } else return -1; + } else if ("name" in b) return 1; + if ("index" in a) { + if ("index" in b) { + if (/** @type {number} */ (a.index) < /** @type {number} */ (b.index)) + return -1; + if (/** @type {number} */ (a.index) > /** @type {number} */ (b.index)) + return 1; + } else return -1; + } else if ("index" in b) return 1; return 0; }; diff --git a/lib/util/compileBooleanMatcher.js b/lib/util/compileBooleanMatcher.js index 49d5d6fa697..e388602f246 100644 --- a/lib/util/compileBooleanMatcher.js +++ b/lib/util/compileBooleanMatcher.js @@ -5,12 +5,18 @@ "use strict"; -const quoteMeta = str => { - return str.replace(/[-[\]\\/{}()*+?.^$|]/g, "\\$&"); -}; +/** + * @param {string} str string + * @returns {string} quoted meta + */ +const quoteMeta = str => str.replace(/[-[\]\\/{}()*+?.^$|]/g, "\\$&"); +/** + * @param {string} str string + * @returns {string} string + */ const toSimpleString = str => { - if (`${+str}` === str) { + if (`${Number(str)}` === str) { return str; } return JSON.stringify(str); @@ -18,7 +24,7 @@ const toSimpleString = str => { /** * @param {Record} map value map - * @returns {true|false|function(string): string} true/false, when unconditionally true/false, or a template function to determine the value at runtime + * @returns {boolean|(function(string): string)} true/false, when unconditionally true/false, or a template function to determine the value at runtime */ const compileBooleanMatcher = map => { const positiveItems = Object.keys(map).filter(i => map[i]); @@ -44,24 +50,32 @@ const compileBooleanMatcherFromLists = (positiveItems, negativeItems) => { const negativeRegexp = itemsToRegexp(negativeItems); if (positiveRegexp.length <= negativeRegexp.length) { return value => `/^${positiveRegexp}$/.test(${value})`; - } else { - return value => `!/^${negativeRegexp}$/.test(${value})`; } + return value => `!/^${negativeRegexp}$/.test(${value})`; }; +/** + * @param {Set} itemsSet items set + * @param {(str: string) => string | false} getKey get key function + * @param {(str: Array) => boolean} condition condition + * @returns {Array>} list of common items + */ const popCommonItems = (itemsSet, getKey, condition) => { + /** @type {Map>} */ const map = new Map(); for (const item of itemsSet) { const key = getKey(item); if (key) { let list = map.get(key); if (list === undefined) { + /** @type {Array} */ list = []; map.set(key, list); } list.push(item); } } + /** @type {Array>} */ const result = []; for (const list of map.values()) { if (condition(list)) { @@ -74,6 +88,10 @@ const popCommonItems = (itemsSet, getKey, condition) => { return result; }; +/** + * @param {Array} items items + * @returns {string} common prefix + */ const getCommonPrefix = items => { let prefix = items[0]; for (let i = 1; i < items.length; i++) { @@ -88,6 +106,10 @@ const getCommonPrefix = items => { return prefix; }; +/** + * @param {Array} items items + * @returns {string} common suffix + */ const getCommonSuffix = items => { let suffix = items[0]; for (let i = 1; i < items.length; i++) { @@ -102,10 +124,15 @@ const getCommonSuffix = items => { return suffix; }; +/** + * @param {Array} itemsArr array of items + * @returns {string} regexp + */ const itemsToRegexp = itemsArr => { if (itemsArr.length === 1) { return quoteMeta(itemsArr[0]); } + /** @type {Array} */ const finishedItems = []; // merge single char items: (a|b|c|d|ef) => ([abcd]|ef) @@ -146,6 +173,7 @@ const itemsToRegexp = itemsArr => { // special case for 2 items with common suffix if (finishedItems.length === 0 && items.size === 2) { + /** @type {Iterator} */ const it = items[Symbol.iterator](); const a = it.next().value; const b = it.next().value; diff --git a/lib/util/conventions.js b/lib/util/conventions.js new file mode 100644 index 00000000000..4f78df1c095 --- /dev/null +++ b/lib/util/conventions.js @@ -0,0 +1,126 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Gengkun He @ahabhgk +*/ + +"use strict"; + +/** @typedef {import("../../declarations/WebpackOptions").CssGeneratorExportsConvention} CssGeneratorExportsConvention */ + +/** + * @param {string} input input + * @param {CssGeneratorExportsConvention | undefined} convention convention + * @returns {string[]} results + */ +module.exports.cssExportConvention = (input, convention) => { + const set = new Set(); + if (typeof convention === "function") { + set.add(convention(input)); + } else { + switch (convention) { + case "camel-case": { + set.add(input); + set.add(module.exports.camelCase(input)); + break; + } + case "camel-case-only": { + set.add(module.exports.camelCase(input)); + break; + } + case "dashes": { + set.add(input); + set.add(module.exports.dashesCamelCase(input)); + break; + } + case "dashes-only": { + set.add(module.exports.dashesCamelCase(input)); + break; + } + case "as-is": { + set.add(input); + break; + } + } + } + return Array.from(set); +}; + +// Copy from css-loader +/** + * @param {string} input input + * @returns {string} result + */ +module.exports.dashesCamelCase = input => + input.replace(/-+(\w)/g, (match, firstLetter) => firstLetter.toUpperCase()); + +// Copy from css-loader +/** + * @param {string} input input + * @returns {string} result + */ +module.exports.camelCase = input => { + let result = input.trim(); + + if (result.length === 0) { + return ""; + } + + if (result.length === 1) { + return result.toLowerCase(); + } + + const hasUpperCase = result !== result.toLowerCase(); + + if (hasUpperCase) { + result = preserveCamelCase(result); + } + + return result + .replace(/^[_.\- ]+/, "") + .toLowerCase() + .replace(/[_.\- ]+([\p{Alpha}\p{N}_]|$)/gu, (_, p1) => p1.toUpperCase()) + .replace(/\d+([\p{Alpha}\p{N}_]|$)/gu, m => m.toUpperCase()); +}; + +// Copy from css-loader +/** + * @param {string} string string + * @returns {string} result + */ +const preserveCamelCase = string => { + let result = string; + let isLastCharLower = false; + let isLastCharUpper = false; + let isLastLastCharUpper = false; + + for (let i = 0; i < result.length; i++) { + const character = result[i]; + + if (isLastCharLower && /[\p{Lu}]/u.test(character)) { + result = `${result.slice(0, i)}-${result.slice(i)}`; + isLastCharLower = false; + isLastLastCharUpper = isLastCharUpper; + isLastCharUpper = true; + i += 1; + } else if ( + isLastCharUpper && + isLastLastCharUpper && + /[\p{Ll}]/u.test(character) + ) { + result = `${result.slice(0, i - 1)}-${result.slice(i - 1)}`; + isLastLastCharUpper = isLastCharUpper; + isLastCharUpper = false; + isLastCharLower = true; + } else { + isLastCharLower = + character.toLowerCase() === character && + character.toUpperCase() !== character; + isLastLastCharUpper = isLastCharUpper; + isLastCharUpper = + character.toUpperCase() === character && + character.toLowerCase() !== character; + } + } + + return result; +}; diff --git a/lib/util/create-schema-validation.js b/lib/util/create-schema-validation.js new file mode 100644 index 00000000000..290eaf47d65 --- /dev/null +++ b/lib/util/create-schema-validation.js @@ -0,0 +1,28 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ + +"use strict"; + +const memoize = require("./memoize"); + +const getValidate = memoize(() => require("schema-utils").validate); + +const createSchemaValidation = (check, getSchema, options) => { + getSchema = memoize(getSchema); + return value => { + if (check && !check(value)) { + getValidate()(getSchema(), value, options); + if (check) { + require("util").deprecate( + () => {}, + "webpack bug: Pre-compiled schema reports error while real schema is happy. This has performance drawbacks.", + "DEP_WEBPACK_PRE_COMPILED_SCHEMA_INVALID" + )(); + } + } + }; +}; + +module.exports = createSchemaValidation; diff --git a/lib/util/createHash.js b/lib/util/createHash.js index bbabc61306c..991a1a2dbd8 100644 --- a/lib/util/createHash.js +++ b/lib/util/createHash.js @@ -11,11 +11,14 @@ const BULK_SIZE = 2000; // We are using an object instead of a Map as this will stay static during the runtime // so access to it can be optimized by v8 +/** @type {{[key: string]: Map}} */ const digestCaches = {}; +/** @typedef {function(): Hash} HashFactory */ + class BulkUpdateDecorator extends Hash { /** - * @param {Hash | function(): Hash} hashOrFactory function to create a hash + * @param {Hash | HashFactory} hashOrFactory function to create a hash * @param {string=} hashKey key for caching */ constructor(hashOrFactory, hashKey) { @@ -43,7 +46,8 @@ class BulkUpdateDecorator extends Hash { typeof data !== "string" || data.length > BULK_SIZE ) { - if (this.hash === undefined) this.hash = this.hashFactory(); + if (this.hash === undefined) + this.hash = /** @type {HashFactory} */ (this.hashFactory)(); if (this.buffer.length > 0) { this.hash.update(this.buffer); this.buffer = ""; @@ -52,7 +56,8 @@ class BulkUpdateDecorator extends Hash { } else { this.buffer += data; if (this.buffer.length > BULK_SIZE) { - if (this.hash === undefined) this.hash = this.hashFactory(); + if (this.hash === undefined) + this.hash = /** @type {HashFactory} */ (this.hashFactory)(); this.hash.update(this.buffer); this.buffer = ""; } @@ -67,6 +72,7 @@ class BulkUpdateDecorator extends Hash { */ digest(encoding) { let digestCache; + const buffer = this.buffer; if (this.hash === undefined) { // short data for hash, we can use caching const cacheKey = `${this.hashKey}-${encoding}`; @@ -74,18 +80,18 @@ class BulkUpdateDecorator extends Hash { if (digestCache === undefined) { digestCache = digestCaches[cacheKey] = new Map(); } - const cacheEntry = digestCache.get(this.buffer); + const cacheEntry = digestCache.get(buffer); if (cacheEntry !== undefined) return cacheEntry; - this.hash = this.hashFactory(); + this.hash = /** @type {HashFactory} */ (this.hashFactory)(); } - if (this.buffer.length > 0) { - this.hash.update(this.buffer); + if (buffer.length > 0) { + this.hash.update(buffer); } const digestResult = this.hash.digest(encoding); const result = typeof digestResult === "string" ? digestResult : digestResult.toString(); if (digestCache !== undefined) { - digestCache.set(this.buffer, result); + digestCache.set(buffer, result); } return result; } @@ -106,10 +112,13 @@ class DebugHash extends Hash { */ update(data, inputEncoding) { if (typeof data !== "string") data = data.toString("utf-8"); - if (data.startsWith("debug-digest-")) { - data = Buffer.from(data.slice("debug-digest-".length), "hex").toString(); + const prefix = Buffer.from("@webpack-debug-digest@").toString("hex"); + if (data.startsWith(prefix)) { + data = Buffer.from(data.slice(prefix.length), "hex").toString(); } - this.string += `[${data}](${new Error().stack.split("\n", 3)[2]})\n`; + this.string += `[${data}](${ + /** @type {string} */ (new Error().stack).split("\n", 3)[2] + })\n`; return this; } @@ -119,29 +128,66 @@ class DebugHash extends Hash { * @returns {string|Buffer} digest */ digest(encoding) { - return "debug-digest-" + Buffer.from(this.string).toString("hex"); + return Buffer.from(`@webpack-debug-digest@${this.string}`).toString("hex"); } } -let crypto = undefined; +/** @type {typeof import("crypto") | undefined} */ +let crypto; +/** @type {typeof import("./hash/xxhash64") | undefined} */ +let createXXHash64; +/** @type {typeof import("./hash/md4") | undefined} */ +let createMd4; +/** @type {typeof import("./hash/BatchedHash") | undefined} */ +let BatchedHash; + +/** @typedef {string | typeof Hash} Algorithm */ /** * Creates a hash by name or function - * @param {string | typeof Hash} algorithm the algorithm name or a constructor creating a hash + * @param {Algorithm} algorithm the algorithm name or a constructor creating a hash * @returns {Hash} the hash */ module.exports = algorithm => { if (typeof algorithm === "function") { + // eslint-disable-next-line new-cap return new BulkUpdateDecorator(() => new algorithm()); } switch (algorithm) { // TODO add non-cryptographic algorithm here case "debug": return new DebugHash(); + case "xxhash64": + if (createXXHash64 === undefined) { + createXXHash64 = require("./hash/xxhash64"); + if (BatchedHash === undefined) { + BatchedHash = require("./hash/BatchedHash"); + } + } + return new /** @type {typeof import("./hash/BatchedHash")} */ ( + BatchedHash + )(createXXHash64()); + case "md4": + if (createMd4 === undefined) { + createMd4 = require("./hash/md4"); + if (BatchedHash === undefined) { + BatchedHash = require("./hash/BatchedHash"); + } + } + return new /** @type {typeof import("./hash/BatchedHash")} */ ( + BatchedHash + )(createMd4()); + case "native-md4": + if (crypto === undefined) crypto = require("crypto"); + return new BulkUpdateDecorator( + () => /** @type {typeof import("crypto")} */ (crypto).createHash("md4"), + "md4" + ); default: if (crypto === undefined) crypto = require("crypto"); return new BulkUpdateDecorator( - () => crypto.createHash(algorithm), + () => + /** @type {typeof import("crypto")} */ (crypto).createHash(algorithm), algorithm ); } diff --git a/lib/util/deprecation.js b/lib/util/deprecation.js index 224e5348248..35d694adc7d 100644 --- a/lib/util/deprecation.js +++ b/lib/util/deprecation.js @@ -11,11 +11,14 @@ const util = require("util"); const deprecationCache = new Map(); /** - * @typedef {Object} FakeHookMarker + * @typedef {object} FakeHookMarker * @property {true} _fakeHook it's a fake hook */ -/** @template T @typedef {T & FakeHookMarker} FakeHook */ +/** + * @template T + * @typedef {T & FakeHookMarker} FakeHook + */ /** * @param {string} message deprecation message @@ -28,7 +31,7 @@ const createDeprecation = (message, code) => { const fn = util.deprecate( () => {}, message, - "DEP_WEBPACK_DEPRECATION_" + code + `DEP_WEBPACK_DEPRECATION_${code}` ); deprecationCache.set(message, fn); return fn; @@ -69,7 +72,7 @@ const DISABLED_METHODS = [ * @param {string} name property name * @returns {void} */ -exports.arrayToSetDeprecation = (set, name) => { +module.exports.arrayToSetDeprecation = (set, name) => { for (const method of COPY_METHODS) { if (set[method]) continue; const d = createDeprecation( @@ -78,13 +81,17 @@ exports.arrayToSetDeprecation = (set, name) => { ); /** * @deprecated - * @this {Set} + * @this {Set} * @returns {number} count */ set[method] = function () { d(); const array = Array.from(this); - return Array.prototype[method].apply(array, arguments); + return Array.prototype[/** @type {keyof COPY_METHODS} */ (method)].apply( + array, + // eslint-disable-next-line prefer-rest-params + arguments + ); }; } const dPush = createDeprecation( @@ -101,11 +108,12 @@ exports.arrayToSetDeprecation = (set, name) => { ); /** * @deprecated - * @this {Set} + * @this {Set} * @returns {number} count */ set.push = function () { dPush(); + // eslint-disable-next-line prefer-rest-params for (const item of Array.from(arguments)) { this.add(item); } @@ -119,21 +127,28 @@ exports.arrayToSetDeprecation = (set, name) => { ); }; } + /** + * @param {number} index index + * @returns {any} value + */ const createIndexGetter = index => { /** - * @this {Set} a Set + * @this {Set} a Set * @returns {any} the value at this location */ + // eslint-disable-next-line func-style const fn = function () { dIndexer(); let i = 0; for (const item of this) { if (i++ === index) return item; } - return undefined; }; return fn; }; + /** + * @param {number} index index + */ const defineIndexGetter = index => { Object.defineProperty(set, index, { get: createIndexGetter(index), @@ -164,13 +179,31 @@ exports.arrayToSetDeprecation = (set, name) => { set[Symbol.isConcatSpreadable] = true; }; -exports.createArrayToSetDeprecationSet = name => { - class SetDeprecatedArray extends Set {} - exports.arrayToSetDeprecation(SetDeprecatedArray.prototype, name); +module.exports.createArrayToSetDeprecationSet = name => { + let initialized = false; + class SetDeprecatedArray extends Set { + constructor(items) { + super(items); + if (!initialized) { + initialized = true; + module.exports.arrayToSetDeprecation( + SetDeprecatedArray.prototype, + name + ); + } + } + } return SetDeprecatedArray; }; -exports.soonFrozenObjectDeprecation = (obj, name, code, note = "") => { +/** + * @param {object} obj object + * @param {string} name property name + * @param {string} code deprecation code + * @param {string} note additional note + * @returns {Proxy} frozen object with deprecation when modifying + */ +module.exports.soonFrozenObjectDeprecation = (obj, name, code, note = "") => { const message = `${name} will be frozen in future, all modifications are deprecated.${ note && `\n${note}` }`; @@ -237,7 +270,7 @@ const deprecateAllProperties = (obj, message, code) => { } return /** @type {T} */ (newObj); }; -exports.deprecateAllProperties = deprecateAllProperties; +module.exports.deprecateAllProperties = deprecateAllProperties; /** * @template T @@ -246,7 +279,7 @@ exports.deprecateAllProperties = deprecateAllProperties; * @param {string=} code deprecation code (not deprecated when unset) * @returns {FakeHook} fake hook which redirects */ -exports.createFakeHook = (fakeHook, message, code) => { +module.exports.createFakeHook = (fakeHook, message, code) => { if (message && code) { fakeHook = deprecateAllProperties(fakeHook, message, code); } diff --git a/lib/util/deterministicGrouping.js b/lib/util/deterministicGrouping.js index 5f6edcab842..b69be028899 100644 --- a/lib/util/deterministicGrouping.js +++ b/lib/util/deterministicGrouping.js @@ -25,7 +25,6 @@ // 3.2% that 5 or more groups are invalidated /** - * * @param {string} a key * @param {string} b key * @returns {number} the similarity as number @@ -94,7 +93,8 @@ const subtractSizeFrom = (total, size) => { }; /** - * @param {Iterable} nodes some nodes + * @template T + * @param {Iterable>} nodes some nodes * @returns {Record} total size */ const sumSize = nodes => { @@ -105,43 +105,58 @@ const sumSize = nodes => { return sum; }; +/** + * @param {Record} size size + * @param {Record} maxSize minimum size + * @returns {boolean} true, when size is too big + */ const isTooBig = (size, maxSize) => { for (const key of Object.keys(size)) { const s = size[key]; if (s === 0) continue; const maxSizeValue = maxSize[key]; - if (typeof maxSizeValue === "number") { - if (s > maxSizeValue) return true; - } + if (typeof maxSizeValue === "number" && s > maxSizeValue) return true; } return false; }; +/** + * @param {Record} size size + * @param {Record} minSize minimum size + * @returns {boolean} true, when size is too small + */ const isTooSmall = (size, minSize) => { for (const key of Object.keys(size)) { const s = size[key]; if (s === 0) continue; const minSizeValue = minSize[key]; - if (typeof minSizeValue === "number") { - if (s < minSizeValue) return true; - } + if (typeof minSizeValue === "number" && s < minSizeValue) return true; } return false; }; +/** + * @param {Record} size size + * @param {Record} minSize minimum size + * @returns {Set} set of types that are too small + */ const getTooSmallTypes = (size, minSize) => { const types = new Set(); for (const key of Object.keys(size)) { const s = size[key]; if (s === 0) continue; const minSizeValue = minSize[key]; - if (typeof minSizeValue === "number") { - if (s < minSizeValue) types.add(key); - } + if (typeof minSizeValue === "number" && s < minSizeValue) types.add(key); } return types; }; +/** + * @template T + * @param {TODO} size size + * @param {Set} types types + * @returns {number} number of matching size types + */ const getNumberOfMatchingSizeTypes = (size, types) => { let i = 0; for (const key of Object.keys(size)) { @@ -150,6 +165,11 @@ const getNumberOfMatchingSizeTypes = (size, types) => { return i; }; +/** + * @param {Record} size size + * @param {Set} types types + * @returns {number} selective size sum + */ const selectiveSizeSum = (size, types) => { let sum = 0; for (const key of Object.keys(size)) { @@ -180,20 +200,20 @@ class Node { class Group { /** * @param {Node[]} nodes nodes - * @param {number[]} similarities similarities between the nodes (length = nodes.length - 1) + * @param {number[] | null} similarities similarities between the nodes (length = nodes.length - 1) * @param {Record=} size size of the group */ constructor(nodes, similarities, size) { this.nodes = nodes; this.similarities = similarities; this.size = size || sumSize(nodes); - /** @type {string} */ + /** @type {string | undefined} */ this.key = undefined; } /** - * @param {function(Node): boolean} filter filter function - * @returns {Node[]} removed nodes + * @param {function(Node): boolean} filter filter function + * @returns {Node[] | undefined} removed nodes */ popNodes(filter) { const newNodes = []; @@ -208,14 +228,15 @@ class Group { if (newNodes.length > 0) { newSimilarities.push( lastNode === this.nodes[i - 1] - ? this.similarities[i - 1] - : similarity(lastNode.key, node.key) + ? /** @type {number[]} */ (this.similarities)[i - 1] + : similarity(/** @type {Node} */ (lastNode).key, node.key) ); } newNodes.push(node); lastNode = node; } } + if (resultNodes.length === this.nodes.length) return; this.nodes = newNodes; this.similarities = newSimilarities; this.size = sumSize(newNodes); @@ -224,14 +245,15 @@ class Group { } /** - * @param {Iterable} nodes nodes + * @template T + * @param {Iterable>} nodes nodes * @returns {number[]} similarities */ const getSimilarities = nodes => { // calculate similarities between lexically adjacent nodes /** @type {number[]} */ const similarities = []; - let last = undefined; + let last; for (const node of nodes) { if (last !== undefined) { similarities.push(similarity(last.key, node.key)); @@ -243,7 +265,7 @@ const getSimilarities = nodes => { /** * @template T - * @typedef {Object} GroupedItems + * @typedef {object} GroupedItems * @property {string} key * @property {T[]} items * @property {Record} size @@ -251,7 +273,7 @@ const getSimilarities = nodes => { /** * @template T - * @typedef {Object} Options + * @typedef {object} Options * @property {Record} maxSize maximum size of a group * @property {Record} minSize minimum size of a group (preferred over maximum size) * @property {Iterable} items a list of items @@ -296,14 +318,20 @@ module.exports = ({ maxSize, minSize, items, getSize, getKey }) => { if (initialNodes.length > 0) { const initialGroup = new Group(initialNodes, getSimilarities(initialNodes)); - const removeProblematicNodes = group => { - const problemTypes = getTooSmallTypes(group.size, minSize); + /** + * @param {Group} group group + * @param {Record} consideredSize size of the group to consider + * @returns {boolean} true, if the group was modified + */ + const removeProblematicNodes = (group, consideredSize = group.size) => { + const problemTypes = getTooSmallTypes(consideredSize, minSize); if (problemTypes.size > 0) { // We hit an edge case where the working set is already smaller than minSize // We merge problematic nodes with the smallest result node to keep minSize intact const problemNodes = group.popNodes( n => getNumberOfMatchingSizeTypes(n.size, problemTypes) > 0 ); + if (problemNodes === undefined) return false; // Only merge it with result nodes that have the problematic size type const possibleResultGroups = result.filter( n => getNumberOfMatchingSizeTypes(n.size, problemTypes) > 0 @@ -336,16 +364,15 @@ module.exports = ({ maxSize, minSize, items, getSize, getKey }) => { result.push(new Group(problemNodes, null)); } return true; - } else { - return false; } + return false; }; if (initialGroup.nodes.length > 0) { const queue = [initialGroup]; while (queue.length) { - const group = queue.pop(); + const group = /** @type {Group} */ (queue.pop()); // only groups bigger than maxSize need to be splitted if (!isTooBig(group.size, maxSize)) { result.push(group); @@ -363,21 +390,45 @@ module.exports = ({ maxSize, minSize, items, getSize, getKey }) => { // going minSize from left and right // at least one node need to be included otherwise we get stuck let left = 1; - let leftSize = Object.create(null); + const leftSize = Object.create(null); addSizeTo(leftSize, group.nodes[0].size); while (left < group.nodes.length && isTooSmall(leftSize, minSize)) { addSizeTo(leftSize, group.nodes[left].size); left++; } let right = group.nodes.length - 2; - let rightSize = Object.create(null); + const rightSize = Object.create(null); addSizeTo(rightSize, group.nodes[group.nodes.length - 1].size); while (right >= 0 && isTooSmall(rightSize, minSize)) { addSizeTo(rightSize, group.nodes[right].size); right--; } + // left v v right + // [ O O O ] O O O [ O O O ] + // ^^^^^^^^^ leftSize + // rightSize ^^^^^^^^^ + // leftSize > minSize + // rightSize > minSize + + // Perfect split: [ O O O ] [ O O O ] + // right === left - 1 + if (left - 1 > right) { + // We try to remove some problematic nodes to "fix" that + let prevSize; + if (right < group.nodes.length - left) { + subtractSizeFrom(rightSize, group.nodes[right + 1].size); + prevSize = rightSize; + } else { + subtractSizeFrom(leftSize, group.nodes[left - 1].size); + prevSize = leftSize; + } + if (removeProblematicNodes(group, prevSize)) { + // This changed something, so we try this group again + queue.push(group); + continue; + } // can't split group while holding minSize // because minSize is preferred of maxSize we return // the problematic nodes as result here even while it's too big @@ -394,9 +445,17 @@ module.exports = ({ maxSize, minSize, items, getSize, getKey }) => { let best = -1; let bestSimilarity = Infinity; let pos = left; - let rightSize = sumSize(group.nodes.slice(pos)); - while (pos <= right) { - const similarity = group.similarities[pos - 1]; + const rightSize = sumSize(group.nodes.slice(pos)); + + // pos v v right + // [ O O O ] O O O [ O O O ] + // ^^^^^^^^^ leftSize + // rightSize ^^^^^^^^^^^^^^^ + + while (pos <= right + 1) { + const similarity = /** @type {number[]} */ (group.similarities)[ + pos - 1 + ]; if ( similarity < bestSimilarity && !isTooSmall(leftSize, minSize) && @@ -410,7 +469,9 @@ module.exports = ({ maxSize, minSize, items, getSize, getKey }) => { pos++; } if (best < 0) { - // can't split group while holding minSize + // This can't happen + // but if that assumption is wrong + // fallback to a big group result.push(group); continue; } @@ -424,7 +485,9 @@ module.exports = ({ maxSize, minSize, items, getSize, getKey }) => { /** @type {number[]} */ const rightSimilarities = []; for (let i = right + 2; i < group.nodes.length; i++) { - rightSimilarities.push(group.similarities[i - 1]); + rightSimilarities.push( + /** @type {number[]} */ (group.similarities)[i - 1] + ); rightNodes.push(group.nodes[i]); } queue.push(new Group(rightNodes, rightSimilarities)); @@ -433,7 +496,9 @@ module.exports = ({ maxSize, minSize, items, getSize, getKey }) => { /** @type {number[]} */ const leftSimilarities = []; for (let i = 1; i < left; i++) { - leftSimilarities.push(group.similarities[i - 1]); + leftSimilarities.push( + /** @type {number[]} */ (group.similarities)[i - 1] + ); leftNodes.push(group.nodes[i]); } queue.push(new Group(leftNodes, leftSimilarities)); @@ -463,12 +528,13 @@ module.exports = ({ maxSize, minSize, items, getSize, getKey }) => { } // return the results - return result.map(group => { - /** @type {GroupedItems} */ - return { - key: group.key, - items: group.nodes.map(node => node.item), - size: group.size - }; - }); + return result.map( + group => + /** @type {GroupedItems} */ + ({ + key: group.key, + items: group.nodes.map(node => node.item), + size: group.size + }) + ); }; diff --git a/lib/util/extractUrlAndGlobal.js b/lib/util/extractUrlAndGlobal.js index 5d135db991d..ade0a7cf25c 100644 --- a/lib/util/extractUrlAndGlobal.js +++ b/lib/util/extractUrlAndGlobal.js @@ -11,5 +11,8 @@ */ module.exports = function extractUrlAndGlobal(urlAndGlobal) { const index = urlAndGlobal.indexOf("@"); + if (index <= 0 || index === urlAndGlobal.length - 1) { + throw new Error(`Invalid request "${urlAndGlobal}"`); + } return [urlAndGlobal.substring(index + 1), urlAndGlobal.substring(0, index)]; }; diff --git a/lib/util/findGraphRoots.js b/lib/util/findGraphRoots.js index 272bdf85d87..795f99055ff 100644 --- a/lib/util/findGraphRoots.js +++ b/lib/util/findGraphRoots.js @@ -41,7 +41,7 @@ class Cycle { /** * @template T - * @typedef {Object} StackEntry + * @typedef {object} StackEntry * @property {Node} node * @property {Node[]} openEdges */ @@ -109,7 +109,9 @@ module.exports = (items, getDependencies) => { // Are there still edges unprocessed in the current node? if (topOfStack.openEdges.length > 0) { // Process one dependency - const dependency = topOfStack.openEdges.pop(); + const dependency = + /** @type {Node} */ + (topOfStack.openEdges.pop()); switch (dependency.marker) { case NO_MARKER: // dependency has not be visited yet @@ -169,7 +171,7 @@ module.exports = (items, getDependencies) => { // so it's not really a root cycle // remove the cycle from the root cycles // and convert it to a normal node - rootCycles.delete(dependency.cycle); + rootCycles.delete(/** @type {Cycle} */ (dependency.cycle)); dependency.marker = DONE_MARKER; break; // DONE_MARKER: nothing to do, don't recurse into dependencies @@ -223,7 +225,7 @@ module.exports = (items, getDependencies) => { // When roots were found, return them if (roots.size > 0) { return Array.from(roots, r => r.item); - } else { - throw new Error("Implementation of findGraphRoots is broken"); } + + throw new Error("Implementation of findGraphRoots is broken"); }; diff --git a/lib/util/fs.js b/lib/util/fs.js index e2e1f0d6632..3a1c3ab8fc0 100644 --- a/lib/util/fs.js +++ b/lib/util/fs.js @@ -11,7 +11,8 @@ const path = require("path"); /** @typedef {import("../FileSystemInfo").FileSystemInfoEntry} FileSystemInfoEntry */ /** - * @typedef {Object} IStats + * @template T + * @typedef {object} IStatsBase * @property {() => boolean} isFile * @property {() => boolean} isDirectory * @property {() => boolean} isBlockDevice @@ -19,20 +20,20 @@ const path = require("path"); * @property {() => boolean} isSymbolicLink * @property {() => boolean} isFIFO * @property {() => boolean} isSocket - * @property {number | bigint} dev - * @property {number | bigint} ino - * @property {number | bigint} mode - * @property {number | bigint} nlink - * @property {number | bigint} uid - * @property {number | bigint} gid - * @property {number | bigint} rdev - * @property {number | bigint} size - * @property {number | bigint} blksize - * @property {number | bigint} blocks - * @property {number | bigint} atimeMs - * @property {number | bigint} mtimeMs - * @property {number | bigint} ctimeMs - * @property {number | bigint} birthtimeMs + * @property {T} dev + * @property {T} ino + * @property {T} mode + * @property {T} nlink + * @property {T} uid + * @property {T} gid + * @property {T} rdev + * @property {T} size + * @property {T} blksize + * @property {T} blocks + * @property {T} atimeMs + * @property {T} mtimeMs + * @property {T} ctimeMs + * @property {T} birthtimeMs * @property {Date} atime * @property {Date} mtime * @property {Date} ctime @@ -40,7 +41,15 @@ const path = require("path"); */ /** - * @typedef {Object} IDirent + * @typedef {IStatsBase} IStats + */ + +/** + * @typedef {IStatsBase & { atimeNs: bigint, mtimeNs: bigint, ctimeNs: bigint, birthtimeNs: bigint }} IBigIntStats + */ + +/** + * @typedef {object} Dirent * @property {() => boolean} isFile * @property {() => boolean} isDirectory * @property {() => boolean} isBlockDevice @@ -48,87 +57,405 @@ const path = require("path"); * @property {() => boolean} isSymbolicLink * @property {() => boolean} isFIFO * @property {() => boolean} isSocket - * @property {string | Buffer} name + * @property {string} name + * @property {string} path + */ + +/** @typedef {string | number | boolean | null} JsonPrimitive */ +/** @typedef {JsonValue[]} JsonArray */ +/** @typedef {JsonPrimitive | JsonObject | JsonArray} JsonValue */ +/** @typedef {{[Key in string]: JsonValue} & {[Key in string]?: JsonValue | undefined}} JsonObject */ + +/** @typedef {function(NodeJS.ErrnoException | null): void} NoParamCallback */ +/** @typedef {function(NodeJS.ErrnoException | null, string=): void} StringCallback */ +/** @typedef {function(NodeJS.ErrnoException | null, Buffer=): void} BufferCallback */ +/** @typedef {function(NodeJS.ErrnoException | null, (string | Buffer)=): void} StringOrBufferCallback */ +/** @typedef {function(NodeJS.ErrnoException | null, (string[])=): void} ReaddirStringCallback */ +/** @typedef {function(NodeJS.ErrnoException | null, (Buffer[])=): void} ReaddirBufferCallback */ +/** @typedef {function(NodeJS.ErrnoException | null, (string[] | Buffer[])=): void} ReaddirStringOrBufferCallback */ +/** @typedef {function(NodeJS.ErrnoException | null, (Dirent[])=): void} ReaddirDirentCallback */ +/** @typedef {function(NodeJS.ErrnoException | null, IStats=): void} StatsCallback */ +/** @typedef {function(NodeJS.ErrnoException | null, IBigIntStats=): void} BigIntStatsCallback */ +/** @typedef {function(NodeJS.ErrnoException | null, (IStats | IBigIntStats)=): void} StatsOrBigIntStatsCallback */ +/** @typedef {function(NodeJS.ErrnoException | null, number=): void} NumberCallback */ +/** @typedef {function(NodeJS.ErrnoException | Error | null, JsonObject=): void} ReadJsonCallback */ + +/** @typedef {Map} TimeInfoEntries */ + +/** + * @typedef {object} WatcherInfo + * @property {Set} changes get current aggregated changes that have not yet send to callback + * @property {Set} removals get current aggregated removals that have not yet send to callback + * @property {TimeInfoEntries} fileTimeInfoEntries get info about files + * @property {TimeInfoEntries} contextTimeInfoEntries get info about directories */ -/** @typedef {function(NodeJS.ErrnoException=): void} Callback */ -/** @typedef {function(NodeJS.ErrnoException=, Buffer=): void} BufferCallback */ -/** @typedef {function(NodeJS.ErrnoException=, Buffer|string=): void} BufferOrStringCallback */ -/** @typedef {function(NodeJS.ErrnoException=, (string | Buffer)[] | IDirent[]=): void} DirentArrayCallback */ -/** @typedef {function(NodeJS.ErrnoException=, string=): void} StringCallback */ -/** @typedef {function(NodeJS.ErrnoException=, number=): void} NumberCallback */ -/** @typedef {function(NodeJS.ErrnoException=, IStats=): void} StatsCallback */ -/** @typedef {function((NodeJS.ErrnoException | Error)=, any=): void} ReadJsonCallback */ +/** @typedef {Set} Changes */ +/** @typedef {Set} Removals */ +// TODO webpack 6 deprecate missing getInfo /** - * @typedef {Object} Watcher + * @typedef {object} Watcher * @property {function(): void} close closes the watcher and all underlying file watchers * @property {function(): void} pause closes the watcher, but keeps underlying file watchers alive until the next watch call - * @property {function(): Set=} getAggregatedChanges get current aggregated changes that have not yet send to callback - * @property {function(): Set=} getAggregatedRemovals get current aggregated removals that have not yet send to callback - * @property {function(): Map} getFileTimeInfoEntries get info about files - * @property {function(): Map} getContextTimeInfoEntries get info about directories + * @property {function(): Changes=} getAggregatedChanges get current aggregated changes that have not yet send to callback + * @property {function(): Removals=} getAggregatedRemovals get current aggregated removals that have not yet send to callback + * @property {function(): TimeInfoEntries} getFileTimeInfoEntries get info about files + * @property {function(): TimeInfoEntries} getContextTimeInfoEntries get info about directories + * @property {function(): WatcherInfo=} getInfo get info about timestamps and changes */ /** * @callback WatchMethod * @param {Iterable} files watched files * @param {Iterable} directories watched directories - * @param {Iterable} missing watched exitance entries + * @param {Iterable} missing watched existence entries * @param {number} startTime timestamp of start time * @param {WatchOptions} options options object - * @param {function(Error=, Map, Map, Set, Set): void} callback aggregated callback + * @param {function(Error | null, TimeInfoEntries=, TimeInfoEntries=, Changes=, Removals=): void} callback aggregated callback * @param {function(string, number): void} callbackUndelayed callback when the first change was detected * @returns {Watcher} a watcher */ +// TODO webpack 6 make optional methods required and avoid using non standard methods like `join`, `relative`, `dirname`, move IntermediateFileSystemExtras methods to InputFilesystem or OutputFilesystem + +/** + * @typedef {string | Buffer | URL} PathLike + */ + +/** + * @typedef {PathLike | number} PathOrFileDescriptor + */ + +/** + * @typedef {object} ObjectEncodingOptions + * @property {BufferEncoding | null | undefined} [encoding] + */ + +/** + * @typedef {{ + * (path: PathOrFileDescriptor, options: ({ encoding?: null | undefined, flag?: string | undefined } & import("events").Abortable) | undefined | null, callback: BufferCallback): void; + * (path: PathOrFileDescriptor, options: ({ encoding: BufferEncoding, flag?: string | undefined } & import("events").Abortable) | BufferEncoding, callback: StringCallback): void; + * (path: PathOrFileDescriptor, options: (ObjectEncodingOptions & { flag?: string | undefined } & import("events").Abortable) | BufferEncoding | undefined | null, callback: StringOrBufferCallback): void; + * (path: PathOrFileDescriptor, callback: BufferCallback): void; + * }} ReadFile + */ + +/** + * @typedef {{ + * (path: PathOrFileDescriptor, options?: { encoding?: null | undefined, flag?: string | undefined } | null): Buffer; + * (path: PathOrFileDescriptor, options: { encoding: BufferEncoding, flag?: string | undefined } | BufferEncoding): string; + * (path: PathOrFileDescriptor, options?: (ObjectEncodingOptions & { flag?: string | undefined }) | BufferEncoding | null): string | Buffer; + * }} ReadFileSync + */ + +/** + * @typedef {ObjectEncodingOptions | BufferEncoding | undefined | null} EncodingOption + */ + +/** + * @typedef {'buffer'| { encoding: 'buffer' }} BufferEncodingOption + */ + +/** + * @typedef {object} StatOptions + * @property {(boolean | undefined)=} bigint + */ + +/** + * @typedef {object} StatSyncOptions + * @property {(boolean | undefined)=} bigint + * @property {(boolean | undefined)=} throwIfNoEntry + */ + +/** + * @typedef {{ + * (path: PathLike, options: EncodingOption, callback: StringCallback): void; + * (path: PathLike, options: BufferEncodingOption, callback: BufferCallback): void; + * (path: PathLike, options: EncodingOption, callback: StringOrBufferCallback): void; + * (path: PathLike, callback: StringCallback): void; + * }} Readlink + */ + +/** + * @typedef {{ + * (path: PathLike, options?: EncodingOption): string; + * (path: PathLike, options: BufferEncodingOption): Buffer; + * (path: PathLike, options?: EncodingOption): string | Buffer; + * }} ReadlinkSync + */ + +/** + * @typedef {{ + * (path: PathLike, options: { encoding: BufferEncoding | null, withFileTypes?: false | undefined, recursive?: boolean | undefined } | BufferEncoding | undefined | null, callback: ReaddirStringCallback): void; + * (path: PathLike, options: { encoding: 'buffer', withFileTypes?: false | undefined, recursive?: boolean | undefined } | 'buffer', callback: ReaddirBufferCallback): void; + * (path: PathLike, callback: ReaddirStringCallback): void; + * (path: PathLike, options: (ObjectEncodingOptions & { withFileTypes?: false | undefined, recursive?: boolean | undefined }) | BufferEncoding | undefined | null, callback: ReaddirStringOrBufferCallback): void; + * (path: PathLike, options: ObjectEncodingOptions & { withFileTypes: true, recursive?: boolean | undefined }, callback: ReaddirDirentCallback): void; + * }} Readdir + */ + +/** + * @typedef {{ + * (path: PathLike, options?: { encoding: BufferEncoding | null, withFileTypes?: false | undefined, recursive?: boolean | undefined } | BufferEncoding | null): string[]; + * (path: PathLike, options: { encoding: 'buffer', withFileTypes?: false | undefined, recursive?: boolean | undefined } | 'buffer'): Buffer[]; + * (path: PathLike, options?: (ObjectEncodingOptions & { withFileTypes?: false | undefined, recursive?: boolean | undefined }) | BufferEncoding | null): string[] | Buffer[]; + * (path: PathLike, options: ObjectEncodingOptions & { withFileTypes: true, recursive?: boolean | undefined }): Dirent[]; + * }} ReaddirSync + */ + +/** + * @typedef {{ + * (path: PathLike, callback: StatsCallback): void; + * (path: PathLike, options: (StatOptions & { bigint?: false | undefined }) | undefined, callback: StatsCallback): void; + * (path: PathLike, options: StatOptions & { bigint: true }, callback: BigIntStatsCallback): void; + * (path: PathLike, options: StatOptions | undefined, callback: StatsOrBigIntStatsCallback): void; + * }} Stat + */ + +/** + * @typedef {{ + * (path: PathLike, options?: undefined): IStats; + * (path: PathLike, options?: StatSyncOptions & { bigint?: false | undefined, throwIfNoEntry: false }): IStats | undefined; + * (path: PathLike, options: StatSyncOptions & { bigint: true, throwIfNoEntry: false }): IBigIntStats | undefined; + * (path: PathLike, options?: StatSyncOptions & { bigint?: false | undefined }): IStats; + * (path: PathLike, options: StatSyncOptions & { bigint: true }): IBigIntStats; + * (path: PathLike, options: StatSyncOptions & { bigint: boolean, throwIfNoEntry?: false | undefined }): IStats | IBigIntStats; + * (path: PathLike, options?: StatSyncOptions): IStats | IBigIntStats | undefined; + * }} StatSync + */ + +/** + * @typedef {{ + * (path: PathLike, callback: StatsCallback): void; + * (path: PathLike, options: (StatOptions & { bigint?: false | undefined }) | undefined, callback: StatsCallback): void; + * (path: PathLike, options: StatOptions & { bigint: true }, callback: BigIntStatsCallback): void; + * (path: PathLike, options: StatOptions | undefined, callback: StatsOrBigIntStatsCallback): void; + * }} LStat + */ + +/** + * @typedef {{ + * (path: PathLike, options?: undefined): IStats; + * (path: PathLike, options?: StatSyncOptions & { bigint?: false | undefined, throwIfNoEntry: false }): IStats | undefined; + * (path: PathLike, options: StatSyncOptions & { bigint: true, throwIfNoEntry: false }): IBigIntStats | undefined; + * (path: PathLike, options?: StatSyncOptions & { bigint?: false | undefined }): IStats; + * (path: PathLike, options: StatSyncOptions & { bigint: true }): IBigIntStats; + * (path: PathLike, options: StatSyncOptions & { bigint: boolean, throwIfNoEntry?: false | undefined }): IStats | IBigIntStats; + * (path: PathLike, options?: StatSyncOptions): IStats | IBigIntStats | undefined; + * }} LStatSync + */ + +/** + * @typedef {{ + * (path: PathLike, options: EncodingOption, callback: StringCallback): void; + * (path: PathLike, options: BufferEncodingOption, callback: BufferCallback): void; + * (path: PathLike, options: EncodingOption, callback: StringOrBufferCallback): void; + * (path: PathLike, callback: StringCallback): void; + * }} RealPath + */ + +/** + * @typedef {{ + * (path: PathLike, options?: EncodingOption): string; + * (path: PathLike, options: BufferEncodingOption): Buffer; + * (path: PathLike, options?: EncodingOption): string | Buffer; + * }} RealPathSync + */ + +/** + * @typedef {function(PathOrFileDescriptor, ReadJsonCallback): void} ReadJson + */ + +/** + * @typedef {function(PathOrFileDescriptor): JsonObject} ReadJsonSync + */ + +/** + * @typedef {function((string | string[] | Set)=): void} Purge + */ + /** - * @typedef {Object} OutputFileSystem - * @property {function(string, Buffer|string, Callback): void} writeFile - * @property {function(string, Callback): void} mkdir - * @property {function(string, DirentArrayCallback): void=} readdir - * @property {function(string, Callback): void=} rmdir - * @property {function(string, Callback): void=} unlink - * @property {function(string, StatsCallback): void} stat - * @property {function(string, BufferOrStringCallback): void} readFile + * @typedef {object} InputFileSystem + * @property {ReadFile} readFile + * @property {ReadFileSync=} readFileSync + * @property {Readlink} readlink + * @property {ReadlinkSync=} readlinkSync + * @property {Readdir} readdir + * @property {ReaddirSync=} readdirSync + * @property {Stat} stat + * @property {StatSync=} statSync + * @property {LStat=} lstat + * @property {LStatSync=} lstatSync + * @property {RealPath=} realpath + * @property {RealPathSync=} realpathSync + * @property {ReadJson=} readJson + * @property {ReadJsonSync=} readJsonSync + * @property {Purge=} purge * @property {(function(string, string): string)=} join * @property {(function(string, string): string)=} relative * @property {(function(string): string)=} dirname */ /** - * @typedef {Object} InputFileSystem - * @property {function(string, BufferOrStringCallback): void} readFile - * @property {(function(string, ReadJsonCallback): void)=} readJson - * @property {function(string, BufferOrStringCallback): void} readlink - * @property {function(string, DirentArrayCallback): void} readdir - * @property {function(string, StatsCallback): void} stat - * @property {(function(string, BufferOrStringCallback): void)=} realpath - * @property {(function(string=): void)=} purge + * @typedef {number | string} Mode + */ + +/** + * @typedef {(ObjectEncodingOptions & import("events").Abortable & { mode?: Mode | undefined, flag?: string | undefined, flush?: boolean | undefined }) | BufferEncoding | null} WriteFileOptions + */ + +/** + * @typedef {{ + * (file: PathOrFileDescriptor, data: string | NodeJS.ArrayBufferView, options: WriteFileOptions, callback: NoParamCallback): void; + * (file: PathOrFileDescriptor, data: string | NodeJS.ArrayBufferView, callback: NoParamCallback): void; + * }} WriteFile + */ + +/** + * @typedef {{ recursive?: boolean | undefined, mode?: Mode | undefined }} MakeDirectoryOptions + */ + +/** + * @typedef {{ + * (file: PathLike, options: MakeDirectoryOptions & { recursive: true }, callback: StringCallback): void; + * (file: PathLike, options: Mode | (MakeDirectoryOptions & { recursive?: false | undefined; }) | null | undefined, callback: NoParamCallback): void; + * (file: PathLike, options: Mode | MakeDirectoryOptions | null | undefined, callback: StringCallback): void; + * (file: PathLike, callback: NoParamCallback): void; + * }} Mkdir + */ + +/** + * @typedef {{ maxRetries?: number | undefined, recursive?: boolean | undefined, retryDelay?: number | undefined }} RmDirOptions + */ + +/** + * @typedef {{ + * (file: PathLike, callback: NoParamCallback): void; + * (file: PathLike, options: RmDirOptions, callback: NoParamCallback): void; + * }} Rmdir + */ + +/** + * @typedef {function(PathLike, NoParamCallback): void} Unlink + */ + +/** + * @typedef {object} OutputFileSystem + * @property {WriteFile} writeFile + * @property {Mkdir} mkdir + * @property {Readdir=} readdir + * @property {Rmdir=} rmdir + * @property {Unlink=} unlink + * @property {Stat} stat + * @property {LStat=} lstat + * @property {ReadFile} readFile * @property {(function(string, string): string)=} join * @property {(function(string, string): string)=} relative * @property {(function(string): string)=} dirname */ /** - * @typedef {Object} WatchFileSystem + * @typedef {object} WatchFileSystem * @property {WatchMethod} watch */ /** - * @typedef {Object} IntermediateFileSystemExtras - * @property {function(string): void} mkdirSync - * @property {function(string): NodeJS.WritableStream} createWriteStream - * @property {function(string, string, NumberCallback): void} open - * @property {function(number, Buffer, number, number, number, NumberCallback): void} read - * @property {function(number, Callback): void} close - * @property {function(string, string, Callback): void} rename + * @typedef {{ + * (path: PathLike, options: MakeDirectoryOptions & { recursive: true }): string | undefined; + * (path: PathLike, options?: Mode | (MakeDirectoryOptions & { recursive?: false | undefined }) | null): void; + * (path: PathLike, options?: Mode | MakeDirectoryOptions | null): string | undefined; + * }} MkdirSync + */ + +/** + * @typedef {object} StreamOptions + * @property {(string | undefined)=} flags + * @property {(BufferEncoding | undefined)} encoding + * @property {(number | any | undefined)=} fd + * @property {(number | undefined)=} mode + * @property {(boolean | undefined)=} autoClose + * @property {(boolean | undefined)=} emitClose + * @property {(number | undefined)=} start + * @property {(AbortSignal | null | undefined)=} signal + */ + +/** + * @typedef {object} FSImplementation + * @property {((...args: any[]) => any)=} open + * @property {((...args: any[]) => any)=} close + */ + +/** + * @typedef {FSImplementation & { write: (...args: any[]) => any; close?: (...args: any[]) => any }} CreateWriteStreamFSImplementation + */ + +/** + * @typedef {StreamOptions & { fs?: CreateWriteStreamFSImplementation | null | undefined }} WriteStreamOptions + */ + +/** + * @typedef {function(PathLike, (BufferEncoding | WriteStreamOptions)=): NodeJS.WritableStream} CreateWriteStream + */ + +/** + * @typedef {number | string} OpenMode + */ + +/** + * @typedef {{ + * (file: PathLike, flags: OpenMode | undefined, mode: Mode | undefined | null, callback: NumberCallback): void; + * (file: PathLike, flags: OpenMode | undefined, callback: NumberCallback): void; + * (file: PathLike, callback: NumberCallback): void; + * }} Open + */ + +/** + * @typedef {number | bigint} ReadPosition + */ + +/** + * @typedef {object} ReadSyncOptions + * @property {(number | undefined)=} offset + * @property {(number | undefined)=} length + * @property {(ReadPosition | null | undefined)=} position + */ + +/** + * @template {NodeJS.ArrayBufferView} TBuffer + * @typedef {object} ReadAsyncOptions + * @property {(number | undefined)=} offset + * @property {(number | undefined)=} length + * @property {(ReadPosition | null | undefined)=} position + * @property {TBuffer=} buffer + */ + +/** + * @template {NodeJS.ArrayBufferView} [TBuffer=Buffer] + * @typedef {{ + * (fd: number, buffer: TBuffer, offset: number, length: number, position: ReadPosition | null, callback: (err: NodeJS.ErrnoException | null, bytesRead: number, buffer: TBuffer) => void): void; + * (fd: number, options: ReadAsyncOptions, callback: (err: NodeJS.ErrnoException | null, bytesRead: number, buffer: TBuffer) => void): void; + * (fd: number, callback: (err: NodeJS.ErrnoException | null, bytesRead: number, buffer: NodeJS.ArrayBufferView) => void): void; + * }} Read + */ + +/** @typedef {function(number, NoParamCallback): void} Close */ + +/** @typedef {function(PathLike, PathLike, NoParamCallback): void} Rename */ + +/** + * @typedef {object} IntermediateFileSystemExtras + * @property {MkdirSync} mkdirSync + * @property {CreateWriteStream} createWriteStream + * @property {Open} open + * @property {Read} read + * @property {Close} close + * @property {Rename} rename */ /** @typedef {InputFileSystem & OutputFileSystem & IntermediateFileSystemExtras} IntermediateFileSystem */ /** - * * @param {InputFileSystem|OutputFileSystem|undefined} fs a file system * @param {string} rootPath the root path * @param {string} targetPath the target path @@ -141,13 +468,12 @@ const relative = (fs, rootPath, targetPath) => { return path.posix.relative(rootPath, targetPath); } else if (path.win32.isAbsolute(rootPath)) { return path.win32.relative(rootPath, targetPath); - } else { - throw new Error( - `${rootPath} is neither a posix nor a windows path, and there is no 'relative' method defined in the file system` - ); } + throw new Error( + `${rootPath} is neither a posix nor a windows path, and there is no 'relative' method defined in the file system` + ); }; -exports.relative = relative; +module.exports.relative = relative; /** * @param {InputFileSystem|OutputFileSystem|undefined} fs a file system @@ -162,13 +488,12 @@ const join = (fs, rootPath, filename) => { return path.posix.join(rootPath, filename); } else if (path.win32.isAbsolute(rootPath)) { return path.win32.join(rootPath, filename); - } else { - throw new Error( - `${rootPath} is neither a posix nor a windows path, and there is no 'join' method defined in the file system` - ); } + throw new Error( + `${rootPath} is neither a posix nor a windows path, and there is no 'join' method defined in the file system` + ); }; -exports.join = join; +module.exports.join = join; /** * @param {InputFileSystem|OutputFileSystem|undefined} fs a file system @@ -182,13 +507,12 @@ const dirname = (fs, absPath) => { return path.posix.dirname(absPath); } else if (path.win32.isAbsolute(absPath)) { return path.win32.dirname(absPath); - } else { - throw new Error( - `${absPath} is neither a posix nor a windows path, and there is no 'dirname' method defined in the file system` - ); } + throw new Error( + `${absPath} is neither a posix nor a windows path, and there is no 'dirname' method defined in the file system` + ); }; -exports.dirname = dirname; +module.exports.dirname = dirname; /** * @param {OutputFileSystem} fs a file system @@ -233,7 +557,7 @@ const mkdirp = (fs, p, callback) => { callback(); }); }; -exports.mkdirp = mkdirp; +module.exports.mkdirp = mkdirp; /** * @param {IntermediateFileSystem} fs a file system @@ -245,7 +569,7 @@ const mkdirpSync = (fs, p) => { fs.mkdirSync(p); } catch (err) { if (err) { - if (err.code === "ENOENT") { + if (/** @type {NodeJS.ErrnoException} */ (err).code === "ENOENT") { const dir = dirname(fs, p); if (dir === p) { throw err; @@ -253,14 +577,14 @@ const mkdirpSync = (fs, p) => { mkdirpSync(fs, dir); fs.mkdirSync(p); return; - } else if (err.code === "EEXIST") { + } else if (/** @type {NodeJS.ErrnoException} */ (err).code === "EEXIST") { return; } throw err; } } }; -exports.mkdirpSync = mkdirpSync; +module.exports.mkdirpSync = mkdirpSync; /** * @param {InputFileSystem} fs a file system @@ -269,16 +593,59 @@ exports.mkdirpSync = mkdirpSync; * @returns {void} */ const readJson = (fs, p, callback) => { - if ("readJson" in fs) return fs.readJson(p, callback); + if ("readJson" in fs) + return /** @type {NonNullable} */ ( + fs.readJson + )(p, callback); fs.readFile(p, (err, buf) => { if (err) return callback(err); let data; try { - data = JSON.parse(buf.toString("utf-8")); - } catch (e) { - return callback(e); + data = JSON.parse(/** @type {Buffer} */ (buf).toString("utf-8")); + } catch (err1) { + return callback(/** @type {Error} */ (err1)); } return callback(null, data); }); }; -exports.readJson = readJson; +module.exports.readJson = readJson; + +/** + * @param {InputFileSystem} fs a file system + * @param {string} p an absolute path + * @param {function(NodeJS.ErrnoException | Error | null, (IStats | string)=): void} callback callback + * @returns {void} + */ +const lstatReadlinkAbsolute = (fs, p, callback) => { + let i = 3; + const doReadLink = () => { + fs.readlink(p, (err, target) => { + if (err && --i > 0) { + // It might was just changed from symlink to file + // we retry 2 times to catch this case before throwing the error + return doStat(); + } + if (err || !target) return doStat(); + const value = target.toString(); + callback(null, join(fs, dirname(fs, p), value)); + }); + }; + const doStat = () => { + if ("lstat" in fs) { + return /** @type {NonNullable} */ (fs.lstat)( + p, + (err, stats) => { + if (err) return callback(err); + if (/** @type {IStats} */ (stats).isSymbolicLink()) { + return doReadLink(); + } + callback(null, stats); + } + ); + } + return fs.stat(p, callback); + }; + if ("lstat" in fs) return doStat(); + doReadLink(); +}; +module.exports.lstatReadlinkAbsolute = lstatReadlinkAbsolute; diff --git a/lib/util/hash/BatchedHash.js b/lib/util/hash/BatchedHash.js new file mode 100644 index 00000000000..cc030f8bd7d --- /dev/null +++ b/lib/util/hash/BatchedHash.js @@ -0,0 +1,71 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ + +"use strict"; + +const Hash = require("../Hash"); +const MAX_SHORT_STRING = require("./wasm-hash").MAX_SHORT_STRING; + +class BatchedHash extends Hash { + /** + * @param {Hash} hash hash + */ + constructor(hash) { + super(); + this.string = undefined; + this.encoding = undefined; + this.hash = hash; + } + + /** + * Update hash {@link https://nodejs.org/api/crypto.html#crypto_hash_update_data_inputencoding} + * @param {string|Buffer} data data + * @param {string=} inputEncoding data encoding + * @returns {this} updated hash + */ + update(data, inputEncoding) { + if (this.string !== undefined) { + if ( + typeof data === "string" && + inputEncoding === this.encoding && + this.string.length + data.length < MAX_SHORT_STRING + ) { + this.string += data; + return this; + } + this.hash.update(this.string, this.encoding); + this.string = undefined; + } + if (typeof data === "string") { + if ( + data.length < MAX_SHORT_STRING && + // base64 encoding is not valid since it may contain padding chars + (!inputEncoding || !inputEncoding.startsWith("ba")) + ) { + this.string = data; + this.encoding = inputEncoding; + } else { + this.hash.update(data, inputEncoding); + } + } else { + this.hash.update(data); + } + return this; + } + + /** + * Calculates the digest {@link https://nodejs.org/api/crypto.html#crypto_hash_digest_encoding} + * @param {string=} encoding encoding of the return value + * @returns {string|Buffer} digest + */ + digest(encoding) { + if (this.string !== undefined) { + this.hash.update(this.string, this.encoding); + } + return this.hash.digest(encoding); + } +} + +module.exports = BatchedHash; diff --git a/lib/util/hash/md4.js b/lib/util/hash/md4.js new file mode 100644 index 00000000000..425edc3b9ba --- /dev/null +++ b/lib/util/hash/md4.js @@ -0,0 +1,20 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ + +"use strict"; + +const create = require("./wasm-hash"); + +// #region wasm code: md4 (../../../assembly/hash/md4.asm.ts) --initialMemory 1 +const md4 = new WebAssembly.Module( + Buffer.from( + // 2154 bytes + "AGFzbQEAAAABCAJgAX8AYAAAAwUEAQAAAAUDAQABBhoFfwFBAAt/AUEAC38BQQALfwFBAAt/AUEACwciBARpbml0AAAGdXBkYXRlAAIFZmluYWwAAwZtZW1vcnkCAAqJEAQmAEGBxpS6BiQBQYnXtv5+JAJB/rnrxXkkA0H2qMmBASQEQQAkAAvQCgEZfyMBIQUjAiECIwMhAyMEIQQDQCAAIAFLBEAgASgCBCIOIAQgAyABKAIAIg8gBSAEIAIgAyAEc3FzampBA3ciCCACIANzcXNqakEHdyEJIAEoAgwiBiACIAggASgCCCIQIAMgAiAJIAIgCHNxc2pqQQt3IgogCCAJc3FzampBE3chCyABKAIUIgcgCSAKIAEoAhAiESAIIAkgCyAJIApzcXNqakEDdyIMIAogC3Nxc2pqQQd3IQ0gASgCHCIJIAsgDCABKAIYIgggCiALIA0gCyAMc3FzampBC3ciEiAMIA1zcXNqakETdyETIAEoAiQiFCANIBIgASgCICIVIAwgDSATIA0gEnNxc2pqQQN3IgwgEiATc3FzampBB3chDSABKAIsIgsgEyAMIAEoAigiCiASIBMgDSAMIBNzcXNqakELdyISIAwgDXNxc2pqQRN3IRMgASgCNCIWIA0gEiABKAIwIhcgDCANIBMgDSASc3FzampBA3ciGCASIBNzcXNqakEHdyEZIBggASgCPCINIBMgGCABKAI4IgwgEiATIBkgEyAYc3FzampBC3ciEiAYIBlzcXNqakETdyITIBIgGXJxIBIgGXFyaiAPakGZ84nUBWpBA3ciGCATIBIgGSAYIBIgE3JxIBIgE3FyaiARakGZ84nUBWpBBXciEiATIBhycSATIBhxcmogFWpBmfOJ1AVqQQl3IhMgEiAYcnEgEiAYcXJqIBdqQZnzidQFakENdyIYIBIgE3JxIBIgE3FyaiAOakGZ84nUBWpBA3ciGSAYIBMgEiAZIBMgGHJxIBMgGHFyaiAHakGZ84nUBWpBBXciEiAYIBlycSAYIBlxcmogFGpBmfOJ1AVqQQl3IhMgEiAZcnEgEiAZcXJqIBZqQZnzidQFakENdyIYIBIgE3JxIBIgE3FyaiAQakGZ84nUBWpBA3ciGSAYIBMgEiAZIBMgGHJxIBMgGHFyaiAIakGZ84nUBWpBBXciEiAYIBlycSAYIBlxcmogCmpBmfOJ1AVqQQl3IhMgEiAZcnEgEiAZcXJqIAxqQZnzidQFakENdyIYIBIgE3JxIBIgE3FyaiAGakGZ84nUBWpBA3ciGSAYIBMgEiAZIBMgGHJxIBMgGHFyaiAJakGZ84nUBWpBBXciEiAYIBlycSAYIBlxcmogC2pBmfOJ1AVqQQl3IhMgEiAZcnEgEiAZcXJqIA1qQZnzidQFakENdyIYIBNzIBJzaiAPakGh1+f2BmpBA3ciDyAYIBMgEiAPIBhzIBNzaiAVakGh1+f2BmpBCXciEiAPcyAYc2ogEWpBodfn9gZqQQt3IhEgEnMgD3NqIBdqQaHX5/YGakEPdyIPIBFzIBJzaiAQakGh1+f2BmpBA3ciECAPIBEgEiAPIBBzIBFzaiAKakGh1+f2BmpBCXciCiAQcyAPc2ogCGpBodfn9gZqQQt3IgggCnMgEHNqIAxqQaHX5/YGakEPdyIMIAhzIApzaiAOakGh1+f2BmpBA3ciDiAMIAggCiAMIA5zIAhzaiAUakGh1+f2BmpBCXciCCAOcyAMc2ogB2pBodfn9gZqQQt3IgcgCHMgDnNqIBZqQaHX5/YGakEPdyIKIAdzIAhzaiAGakGh1+f2BmpBA3ciBiAFaiEFIAIgCiAHIAggBiAKcyAHc2ogC2pBodfn9gZqQQl3IgcgBnMgCnNqIAlqQaHX5/YGakELdyIIIAdzIAZzaiANakGh1+f2BmpBD3dqIQIgAyAIaiEDIAQgB2ohBCABQUBrIQEMAQsLIAUkASACJAIgAyQDIAQkBAsNACAAEAEjACAAaiQAC/8EAgN/AX4jACAAaq1CA4YhBCAAQcgAakFAcSICQQhrIQMgACIBQQFqIQAgAUGAAToAAANAIAAgAklBACAAQQdxGwRAIABBADoAACAAQQFqIQAMAQsLA0AgACACSQRAIABCADcDACAAQQhqIQAMAQsLIAMgBDcDACACEAFBACMBrSIEQv//A4MgBEKAgPz/D4NCEIaEIgRC/4GAgPAfgyAEQoD+g4CA4D+DQgiGhCIEQo+AvIDwgcAHg0IIhiAEQvCBwIeAnoD4AINCBIiEIgRChoyYsODAgYMGfEIEiEKBgoSIkKDAgAGDQid+IARCsODAgYOGjJgwhHw3AwBBCCMCrSIEQv//A4MgBEKAgPz/D4NCEIaEIgRC/4GAgPAfgyAEQoD+g4CA4D+DQgiGhCIEQo+AvIDwgcAHg0IIhiAEQvCBwIeAnoD4AINCBIiEIgRChoyYsODAgYMGfEIEiEKBgoSIkKDAgAGDQid+IARCsODAgYOGjJgwhHw3AwBBECMDrSIEQv//A4MgBEKAgPz/D4NCEIaEIgRC/4GAgPAfgyAEQoD+g4CA4D+DQgiGhCIEQo+AvIDwgcAHg0IIhiAEQvCBwIeAnoD4AINCBIiEIgRChoyYsODAgYMGfEIEiEKBgoSIkKDAgAGDQid+IARCsODAgYOGjJgwhHw3AwBBGCMErSIEQv//A4MgBEKAgPz/D4NCEIaEIgRC/4GAgPAfgyAEQoD+g4CA4D+DQgiGhCIEQo+AvIDwgcAHg0IIhiAEQvCBwIeAnoD4AINCBIiEIgRChoyYsODAgYMGfEIEiEKBgoSIkKDAgAGDQid+IARCsODAgYOGjJgwhHw3AwAL", + "base64" + ) +); +// #endregion + +module.exports = create.bind(null, md4, [], 64, 32); diff --git a/lib/util/hash/wasm-hash.js b/lib/util/hash/wasm-hash.js new file mode 100644 index 00000000000..8b5e1388e45 --- /dev/null +++ b/lib/util/hash/wasm-hash.js @@ -0,0 +1,163 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ + +"use strict"; + +// 65536 is the size of a wasm memory page +// 64 is the maximum chunk size for every possible wasm hash implementation +// 4 is the maximum number of bytes per char for string encoding (max is utf-8) +// ~3 makes sure that it's always a block of 4 chars, so avoid partially encoded bytes for base64 +const MAX_SHORT_STRING = Math.floor((65536 - 64) / 4) & ~3; + +class WasmHash { + /** + * @param {WebAssembly.Instance} instance wasm instance + * @param {WebAssembly.Instance[]} instancesPool pool of instances + * @param {number} chunkSize size of data chunks passed to wasm + * @param {number} digestSize size of digest returned by wasm + */ + constructor(instance, instancesPool, chunkSize, digestSize) { + const exports = /** @type {any} */ (instance.exports); + exports.init(); + this.exports = exports; + this.mem = Buffer.from(exports.memory.buffer, 0, 65536); + this.buffered = 0; + this.instancesPool = instancesPool; + this.chunkSize = chunkSize; + this.digestSize = digestSize; + } + + reset() { + this.buffered = 0; + this.exports.init(); + } + + /** + * @param {Buffer | string} data data + * @param {BufferEncoding=} encoding encoding + * @returns {this} itself + */ + update(data, encoding) { + if (typeof data === "string") { + while (data.length > MAX_SHORT_STRING) { + this._updateWithShortString(data.slice(0, MAX_SHORT_STRING), encoding); + data = data.slice(MAX_SHORT_STRING); + } + this._updateWithShortString(data, encoding); + return this; + } + this._updateWithBuffer(data); + return this; + } + + /** + * @param {string} data data + * @param {BufferEncoding=} encoding encoding + * @returns {void} + */ + _updateWithShortString(data, encoding) { + const { exports, buffered, mem, chunkSize } = this; + let endPos; + if (data.length < 70) { + if (!encoding || encoding === "utf-8" || encoding === "utf8") { + endPos = buffered; + for (let i = 0; i < data.length; i++) { + const cc = data.charCodeAt(i); + if (cc < 0x80) mem[endPos++] = cc; + else if (cc < 0x800) { + mem[endPos] = (cc >> 6) | 0xc0; + mem[endPos + 1] = (cc & 0x3f) | 0x80; + endPos += 2; + } else { + // bail-out for weird chars + endPos += mem.write(data.slice(i), endPos, encoding); + break; + } + } + } else if (encoding === "latin1") { + endPos = buffered; + for (let i = 0; i < data.length; i++) { + const cc = data.charCodeAt(i); + mem[endPos++] = cc; + } + } else { + endPos = buffered + mem.write(data, buffered, encoding); + } + } else { + endPos = buffered + mem.write(data, buffered, encoding); + } + if (endPos < chunkSize) { + this.buffered = endPos; + } else { + const l = endPos & ~(this.chunkSize - 1); + exports.update(l); + const newBuffered = endPos - l; + this.buffered = newBuffered; + if (newBuffered > 0) mem.copyWithin(0, l, endPos); + } + } + + /** + * @param {Buffer} data data + * @returns {void} + */ + _updateWithBuffer(data) { + const { exports, buffered, mem } = this; + const length = data.length; + if (buffered + length < this.chunkSize) { + data.copy(mem, buffered, 0, length); + this.buffered += length; + } else { + const l = (buffered + length) & ~(this.chunkSize - 1); + if (l > 65536) { + let i = 65536 - buffered; + data.copy(mem, buffered, 0, i); + exports.update(65536); + const stop = l - buffered - 65536; + while (i < stop) { + data.copy(mem, 0, i, i + 65536); + exports.update(65536); + i += 65536; + } + data.copy(mem, 0, i, l - buffered); + exports.update(l - buffered - i); + } else { + data.copy(mem, buffered, 0, l - buffered); + exports.update(l); + } + const newBuffered = length + buffered - l; + this.buffered = newBuffered; + if (newBuffered > 0) data.copy(mem, 0, length - newBuffered, length); + } + } + + digest(type) { + const { exports, buffered, mem, digestSize } = this; + exports.final(buffered); + this.instancesPool.push(this); + const hex = mem.toString("latin1", 0, digestSize); + if (type === "hex") return hex; + if (type === "binary" || !type) return Buffer.from(hex, "hex"); + return Buffer.from(hex, "hex").toString(type); + } +} + +const create = (wasmModule, instancesPool, chunkSize, digestSize) => { + if (instancesPool.length > 0) { + const old = instancesPool.pop(); + old.reset(); + return old; + } + + return new WasmHash( + new WebAssembly.Instance(wasmModule), + instancesPool, + chunkSize, + digestSize + ); +}; + +module.exports = create; +module.exports.MAX_SHORT_STRING = MAX_SHORT_STRING; diff --git a/lib/util/hash/xxhash64.js b/lib/util/hash/xxhash64.js new file mode 100644 index 00000000000..b9262b8753c --- /dev/null +++ b/lib/util/hash/xxhash64.js @@ -0,0 +1,20 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ + +"use strict"; + +const create = require("./wasm-hash"); + +// #region wasm code: xxhash64 (../../../assembly/hash/xxhash64.asm.ts) --initialMemory 1 +const xxhash64 = new WebAssembly.Module( + Buffer.from( + // 1160 bytes + "AGFzbQEAAAABCAJgAX8AYAAAAwQDAQAABQMBAAEGGgV+AUIAC34BQgALfgFCAAt+AUIAC34BQgALByIEBGluaXQAAAZ1cGRhdGUAAQVmaW5hbAACBm1lbW9yeQIACqgIAzAAQtbrgu7q/Yn14AAkAELP1tO+0ser2UIkAUIAJAJC+erQ0OfJoeThACQDQgAkBAvUAQIBfwR+IABFBEAPCyMEIACtfCQEIwAhAiMBIQMjAiEEIwMhBQNAIAIgASkDAELP1tO+0ser2UJ+fEIfiUKHla+vmLbem55/fiECIAMgASkDCELP1tO+0ser2UJ+fEIfiUKHla+vmLbem55/fiEDIAQgASkDEELP1tO+0ser2UJ+fEIfiUKHla+vmLbem55/fiEEIAUgASkDGELP1tO+0ser2UJ+fEIfiUKHla+vmLbem55/fiEFIAFBIGoiASAASQ0ACyACJAAgAyQBIAQkAiAFJAMLngYCAn8CfiMEQgBSBH4jAEIBiSMBQgeJfCMCQgyJfCMDQhKJfCMAQs/W077Sx6vZQn5CH4lCh5Wvr5i23puef36FQoeVr6+Ytt6bnn9+Qp2jteqDsY2K+gB9IwFCz9bTvtLHq9lCfkIfiUKHla+vmLbem55/foVCh5Wvr5i23puef35CnaO16oOxjYr6AH0jAkLP1tO+0ser2UJ+Qh+JQoeVr6+Ytt6bnn9+hUKHla+vmLbem55/fkKdo7Xqg7GNivoAfSMDQs/W077Sx6vZQn5CH4lCh5Wvr5i23puef36FQoeVr6+Ytt6bnn9+Qp2jteqDsY2K+gB9BULFz9my8eW66icLIwQgAK18fCEDA0AgAUEIaiICIABNBEAgAyABKQMAQs/W077Sx6vZQn5CH4lCh5Wvr5i23puef36FQhuJQoeVr6+Ytt6bnn9+Qp2jteqDsY2K+gB9IQMgAiEBDAELCyABQQRqIgIgAE0EQCADIAE1AgBCh5Wvr5i23puef36FQheJQs/W077Sx6vZQn5C+fPd8Zn2masWfCEDIAIhAQsDQCAAIAFHBEAgAyABMQAAQsXP2bLx5brqJ36FQguJQoeVr6+Ytt6bnn9+IQMgAUEBaiEBDAELC0EAIAMgA0IhiIVCz9bTvtLHq9lCfiIDQh2IIAOFQvnz3fGZ9pmrFn4iA0IgiCADhSIDQiCIIgRC//8Dg0IghiAEQoCA/P8Pg0IQiIQiBEL/gYCA8B+DQhCGIARCgP6DgIDgP4NCCIiEIgRCj4C8gPCBwAeDQgiGIARC8IHAh4CegPgAg0IEiIQiBEKGjJiw4MCBgwZ8QgSIQoGChIiQoMCAAYNCJ34gBEKw4MCBg4aMmDCEfDcDAEEIIANC/////w+DIgNC//8Dg0IghiADQoCA/P8Pg0IQiIQiA0L/gYCA8B+DQhCGIANCgP6DgIDgP4NCCIiEIgNCj4C8gPCBwAeDQgiGIANC8IHAh4CegPgAg0IEiIQiA0KGjJiw4MCBgwZ8QgSIQoGChIiQoMCAAYNCJ34gA0Kw4MCBg4aMmDCEfDcDAAs=", + "base64" + ) +); +// #endregion + +module.exports = create.bind(null, xxhash64, [], 32, 16); diff --git a/lib/util/identifier.js b/lib/util/identifier.js index 6e4c21f2746..e94a63b5034 100644 --- a/lib/util/identifier.js +++ b/lib/util/identifier.js @@ -11,10 +11,21 @@ const SEGMENTS_SPLIT_REGEXP = /([|!])/; const WINDOWS_PATH_SEPARATOR_REGEXP = /\\/g; /** - * @typedef {Object} MakeRelativePathsCache + * @typedef {object} MakeRelativePathsCache * @property {Map>=} relativePaths */ +/** + * @param {string} relativePath relative path + * @returns {string} request + */ +const relativePathToRequest = relativePath => { + if (relativePath === "") return "./."; + if (relativePath === "..") return "../."; + if (relativePath.startsWith("../")) return relativePath; + return `./${relativePath}`; +}; + /** * @param {string} context context for relative path * @param {string} maybeAbsolutePath path to make relative @@ -36,10 +47,7 @@ const absoluteToRequest = (context, maybeAbsolutePath) => { querySplitPos === -1 ? maybeAbsolutePath : maybeAbsolutePath.slice(0, querySplitPos); - resource = path.posix.relative(context, resource); - if (!resource.startsWith("../")) { - resource = "./" + resource; - } + resource = relativePathToRequest(path.posix.relative(context, resource)); return querySplitPos === -1 ? resource : resource + maybeAbsolutePath.slice(querySplitPos); @@ -53,10 +61,9 @@ const absoluteToRequest = (context, maybeAbsolutePath) => { : maybeAbsolutePath.slice(0, querySplitPos); resource = path.win32.relative(context, resource); if (!WINDOWS_ABS_PATH_REGEXP.test(resource)) { - resource = resource.replace(WINDOWS_PATH_SEPARATOR_REGEXP, "/"); - if (!resource.startsWith("../")) { - resource = "./" + resource; - } + resource = relativePathToRequest( + resource.replace(WINDOWS_PATH_SEPARATOR_REGEXP, "/") + ); } return querySplitPos === -1 ? resource @@ -78,16 +85,92 @@ const requestToAbsolute = (context, relativePath) => { return relativePath; }; -const makeCacheable = fn => { - /** @type {WeakMap>>} */ +/** + * @template T + * @typedef {function(string, object=): T} MakeCacheableResult + */ + +/** + * @template T + * @typedef {function(string): T} BindCacheResultFn + */ + +/** + * @template T + * @typedef {function(object): BindCacheResultFn} BindCache + */ + +/** + * @template T + * @param {(function(string): T)} realFn real function + * @returns {MakeCacheableResult & { bindCache: BindCache }} cacheable function + */ +const makeCacheable = realFn => { + /** + * @template T + * @typedef {Map} CacheItem + */ + /** @type {WeakMap>} */ const cache = new WeakMap(); /** - * @param {string} context context used to create relative path - * @param {string} identifier identifier used to create relative path - * @param {Object=} associatedObjectForCache an object to which the cache will be attached - * @returns {string} the returned relative path + * @param {object} associatedObjectForCache an object to which the cache will be attached + * @returns {CacheItem} cache item */ + const getCache = associatedObjectForCache => { + const entry = cache.get(associatedObjectForCache); + if (entry !== undefined) return entry; + /** @type {Map} */ + const map = new Map(); + cache.set(associatedObjectForCache, map); + return map; + }; + + /** @type {MakeCacheableResult & { bindCache: BindCache }} */ + const fn = (str, associatedObjectForCache) => { + if (!associatedObjectForCache) return realFn(str); + const cache = getCache(associatedObjectForCache); + const entry = cache.get(str); + if (entry !== undefined) return entry; + const result = realFn(str); + cache.set(str, result); + return result; + }; + + /** @type {BindCache} */ + fn.bindCache = associatedObjectForCache => { + const cache = getCache(associatedObjectForCache); + /** + * @param {string} str string + * @returns {T} value + */ + return str => { + const entry = cache.get(str); + if (entry !== undefined) return entry; + const result = realFn(str); + cache.set(str, result); + return result; + }; + }; + + return fn; +}; + +/** @typedef {function(string, string, object=): string} MakeCacheableWithContextResult */ +/** @typedef {function(string, string): string} BindCacheForContextResultFn */ +/** @typedef {function(string): string} BindContextCacheForContextResultFn */ +/** @typedef {function(object=): BindCacheForContextResultFn} BindCacheForContext */ +/** @typedef {function(string, object=): BindContextCacheForContextResultFn} BindContextCacheForContext */ + +/** + * @param {function(string, string): string} fn function + * @returns {MakeCacheableWithContextResult & { bindCache: BindCacheForContext, bindContextCache: BindContextCacheForContext }} cacheable function with context + */ +const makeCacheableWithContext = fn => { + /** @type {WeakMap>>} */ + const cache = new WeakMap(); + + /** @type {MakeCacheableWithContextResult & { bindCache: BindCacheForContext, bindContextCache: BindContextCacheForContext }} */ const cachedFn = (context, identifier, associatedObjectForCache) => { if (!associatedObjectForCache) return fn(context, identifier); @@ -107,17 +190,13 @@ const makeCacheable = fn => { if (cachedResult !== undefined) { return cachedResult; - } else { - const result = fn(context, identifier); - innerSubCache.set(identifier, result); - return result; } + const result = fn(context, identifier); + innerSubCache.set(identifier, result); + return result; }; - /** - * @param {Object=} associatedObjectForCache an object to which the cache will be attached - * @returns {function(string, string): string} cached function - */ + /** @type {BindCacheForContext} */ cachedFn.bindCache = associatedObjectForCache => { let innerCache; if (associatedObjectForCache) { @@ -146,21 +225,16 @@ const makeCacheable = fn => { if (cachedResult !== undefined) { return cachedResult; - } else { - const result = fn(context, identifier); - innerSubCache.set(identifier, result); - return result; } + const result = fn(context, identifier); + innerSubCache.set(identifier, result); + return result; }; return boundFn; }; - /** - * @param {string} context context used to create relative path - * @param {Object=} associatedObjectForCache an object to which the cache will be attached - * @returns {function(string): string} cached function - */ + /** @type {BindContextCacheForContext} */ cachedFn.bindContextCache = (context, associatedObjectForCache) => { let innerSubCache; if (associatedObjectForCache) { @@ -186,11 +260,10 @@ const makeCacheable = fn => { const cachedResult = innerSubCache.get(identifier); if (cachedResult !== undefined) { return cachedResult; - } else { - const result = fn(context, identifier); - innerSubCache.set(identifier, result); - return result; } + const result = fn(context, identifier); + innerSubCache.set(identifier, result); + return result; }; return boundFn; @@ -200,60 +273,74 @@ const makeCacheable = fn => { }; /** - * * @param {string} context context for relative path * @param {string} identifier identifier for path * @returns {string} a converted relative path */ -const _makePathsRelative = (context, identifier) => { - return identifier +const _makePathsRelative = (context, identifier) => + identifier .split(SEGMENTS_SPLIT_REGEXP) .map(str => absoluteToRequest(context, str)) .join(""); -}; -exports.makePathsRelative = makeCacheable(_makePathsRelative); +module.exports.makePathsRelative = makeCacheableWithContext(_makePathsRelative); + +/** + * @param {string} context context for relative path + * @param {string} identifier identifier for path + * @returns {string} a converted relative path + */ +const _makePathsAbsolute = (context, identifier) => + identifier + .split(SEGMENTS_SPLIT_REGEXP) + .map(str => requestToAbsolute(context, str)) + .join(""); + +module.exports.makePathsAbsolute = makeCacheableWithContext(_makePathsAbsolute); /** * @param {string} context absolute context path * @param {string} request any request string may containing absolute paths, query string, etc. * @returns {string} a new request string avoiding absolute paths when possible */ -const _contextify = (context, request) => { - return request +const _contextify = (context, request) => + request .split("!") .map(r => absoluteToRequest(context, r)) .join("!"); -}; -const contextify = makeCacheable(_contextify); -exports.contextify = contextify; +const contextify = makeCacheableWithContext(_contextify); +module.exports.contextify = contextify; /** * @param {string} context absolute context path * @param {string} request any request string * @returns {string} a new request string using absolute paths when possible */ -const _absolutify = (context, request) => { - return request +const _absolutify = (context, request) => + request .split("!") .map(r => requestToAbsolute(context, r)) .join("!"); -}; -const absolutify = makeCacheable(_absolutify); -exports.absolutify = absolutify; +const absolutify = makeCacheableWithContext(_absolutify); +module.exports.absolutify = absolutify; -const PATH_QUERY_FRAGMENT_REGEXP = /^((?:\0.|[^?#\0])*)(\?(?:\0.|[^#\0])*)?(#.*)?$/; +const PATH_QUERY_FRAGMENT_REGEXP = + /^((?:\0.|[^?#\0])*)(\?(?:\0.|[^#\0])*)?(#.*)?$/; +const PATH_QUERY_REGEXP = /^((?:\0.|[^?\0])*)(\?.*)?$/; /** @typedef {{ resource: string, path: string, query: string, fragment: string }} ParsedResource */ +/** @typedef {{ resource: string, path: string, query: string }} ParsedResourceWithoutFragment */ /** * @param {string} str the path with query and fragment * @returns {ParsedResource} parsed parts */ const _parseResource = str => { - const match = PATH_QUERY_FRAGMENT_REGEXP.exec(str); + const match = + /** @type {[string, string, string | undefined, string | undefined]} */ + (/** @type {unknown} */ (PATH_QUERY_FRAGMENT_REGEXP.exec(str))); return { resource: str, path: match[1].replace(/\0(.)/g, "$1"), @@ -261,47 +348,26 @@ const _parseResource = str => { fragment: match[3] || "" }; }; -exports.parseResource = (realFn => { - /** @type {WeakMap>} */ - const cache = new WeakMap(); - - const getCache = associatedObjectForCache => { - const entry = cache.get(associatedObjectForCache); - if (entry !== undefined) return entry; - /** @type {Map} */ - const map = new Map(); - cache.set(associatedObjectForCache, map); - return map; - }; - - /** - * @param {string} str the path with query and fragment - * @param {Object=} associatedObjectForCache an object to which the cache will be attached - * @returns {ParsedResource} parsed parts - */ - const fn = (str, associatedObjectForCache) => { - if (!associatedObjectForCache) return realFn(str); - const cache = getCache(associatedObjectForCache); - const entry = cache.get(str); - if (entry !== undefined) return entry; - const result = realFn(str); - cache.set(str, result); - return result; - }; +module.exports.parseResource = makeCacheable(_parseResource); - fn.bindCache = associatedObjectForCache => { - const cache = getCache(associatedObjectForCache); - return str => { - const entry = cache.get(str); - if (entry !== undefined) return entry; - const result = realFn(str); - cache.set(str, result); - return result; - }; +/** + * Parse resource, skips fragment part + * @param {string} str the path with query and fragment + * @returns {ParsedResourceWithoutFragment} parsed parts + */ +const _parseResourceWithoutFragment = str => { + const match = + /** @type {[string, string, string | undefined]} */ + (/** @type {unknown} */ (PATH_QUERY_REGEXP.exec(str))); + return { + resource: str, + path: match[1].replace(/\0(.)/g, "$1"), + query: match[2] ? match[2].replace(/\0(.)/g, "$1") : "" }; - - return fn; -})(_parseResource); +}; +module.exports.parseResourceWithoutFragment = makeCacheable( + _parseResourceWithoutFragment +); /** * @param {string} filename the filename which should be undone @@ -309,7 +375,7 @@ exports.parseResource = (realFn => { * @param {boolean} enforceRelative true returns ./ for empty paths * @returns {string} repeated ../ to leave the directory of the provided filename to be back on output dir */ -exports.getUndoPath = (filename, outputPath, enforceRelative) => { +module.exports.getUndoPath = (filename, outputPath, enforceRelative) => { let depth = -1; let append = ""; outputPath = outputPath.replace(/[\\/]$/, ""); @@ -321,8 +387,8 @@ exports.getUndoPath = (filename, outputPath, enforceRelative) => { const i = outputPath.lastIndexOf("/"); const j = outputPath.lastIndexOf("\\"); const pos = i < 0 ? j : j < 0 ? i : Math.max(i, j); - if (pos < 0) return outputPath + "/"; - append = outputPath.slice(pos + 1) + "/" + append; + if (pos < 0) return `${outputPath}/`; + append = `${outputPath.slice(pos + 1)}/${append}`; outputPath = outputPath.slice(0, pos); } } else if (part !== ".") { @@ -332,6 +398,6 @@ exports.getUndoPath = (filename, outputPath, enforceRelative) => { return depth > 0 ? `${"../".repeat(depth)}${append}` : enforceRelative - ? `./${append}` - : append; + ? `./${append}` + : append; }; diff --git a/lib/util/internalSerializables.js b/lib/util/internalSerializables.js index a8fe95c5af8..1cd63dbd5d5 100644 --- a/lib/util/internalSerializables.js +++ b/lib/util/internalSerializables.js @@ -45,6 +45,12 @@ module.exports = { require("../dependencies/AMDRequireItemDependency"), "dependencies/CachedConstDependency": () => require("../dependencies/CachedConstDependency"), + "dependencies/ExternalModuleDependency": () => + require("../dependencies/ExternalModuleDependency"), + "dependencies/ExternalModuleInitFragment": () => + require("../dependencies/ExternalModuleInitFragment"), + "dependencies/CreateScriptUrlDependency": () => + require("../dependencies/CreateScriptUrlDependency"), "dependencies/CommonJsRequireContextDependency": () => require("../dependencies/CommonJsRequireContextDependency"), "dependencies/CommonJsExportRequireDependency": () => @@ -65,6 +71,16 @@ module.exports = { require("../dependencies/ContextElementDependency"), "dependencies/CriticalDependencyWarning": () => require("../dependencies/CriticalDependencyWarning"), + "dependencies/CssImportDependency": () => + require("../dependencies/CssImportDependency"), + "dependencies/CssLocalIdentifierDependency": () => + require("../dependencies/CssLocalIdentifierDependency"), + "dependencies/CssSelfLocalIdentifierDependency": () => + require("../dependencies/CssSelfLocalIdentifierDependency"), + "dependencies/CssExportDependency": () => + require("../dependencies/CssExportDependency"), + "dependencies/CssUrlDependency": () => + require("../dependencies/CssUrlDependency"), "dependencies/DelegatedSourceDependency": () => require("../dependencies/DelegatedSourceDependency"), "dependencies/DllEntryDependency": () => @@ -91,6 +107,8 @@ module.exports = { require("../dependencies/HarmonyImportSideEffectDependency"), "dependencies/HarmonyImportSpecifierDependency": () => require("../dependencies/HarmonyImportSpecifierDependency"), + "dependencies/HarmonyEvaluatedImportSpecifierDependency": () => + require("../dependencies/HarmonyEvaluatedImportSpecifierDependency"), "dependencies/ImportContextDependency": () => require("../dependencies/ImportContextDependency"), "dependencies/ImportDependency": () => @@ -114,6 +132,8 @@ module.exports = { require("../dependencies/ImportMetaHotAcceptDependency"), "dependencies/ImportMetaHotDeclineDependency": () => require("../dependencies/ImportMetaHotDeclineDependency"), + "dependencies/ImportMetaContextDependency": () => + require("../dependencies/ImportMetaContextDependency"), "dependencies/ProvidedDependency": () => require("../dependencies/ProvidedDependency"), "dependencies/PureExpressionDependency": () => @@ -154,6 +174,7 @@ module.exports = { require("../dependencies/WebpackIsIncludedDependency"), "dependencies/WorkerDependency": () => require("../dependencies/WorkerDependency"), + "json/JsonData": () => require("../json/JsonData"), "optimize/ConcatenatedModule": () => require("../optimize/ConcatenatedModule"), DelegatedModule: () => require("../DelegatedModule"), @@ -161,6 +182,7 @@ module.exports = { DllModule: () => require("../DllModule"), ExternalModule: () => require("../ExternalModule"), FileSystemInfo: () => require("../FileSystemInfo"), + InitFragment: () => require("../InitFragment"), InvalidDependenciesModuleWarning: () => require("../InvalidDependenciesModuleWarning"), Module: () => require("../Module"), @@ -171,6 +193,8 @@ module.exports = { ModuleParseError: () => require("../ModuleParseError"), ModuleWarning: () => require("../ModuleWarning"), NormalModule: () => require("../NormalModule"), + CssModule: () => require("../CssModule"), + RawDataUrlModule: () => require("../asset/RawDataUrlModule"), RawModule: () => require("../RawModule"), "sharing/ConsumeSharedModule": () => require("../sharing/ConsumeSharedModule"), @@ -185,6 +209,9 @@ module.exports = { UnsupportedFeatureWarning: () => require("../UnsupportedFeatureWarning"), "util/LazySet": () => require("../util/LazySet"), UnhandledSchemeError: () => require("../UnhandledSchemeError"), + NodeStuffInWebError: () => require("../NodeStuffInWebError"), + EnvironmentNotSupportAsyncWarning: () => + require("../EnvironmentNotSupportAsyncWarning"), WebpackError: () => require("../WebpackError"), "util/registerExternalSerializer": () => { diff --git a/lib/util/makeSerializable.js b/lib/util/makeSerializable.js index 7c0d2e2b912..c1d777963ab 100644 --- a/lib/util/makeSerializable.js +++ b/lib/util/makeSerializable.js @@ -6,10 +6,11 @@ const { register } = require("./serialization"); +/** @typedef {import("../serialization/ObjectMiddleware").Constructor} Constructor */ + class ClassSerializer { constructor(Constructor) { this.Constructor = Constructor; - this.hash = null; } serialize(obj, context) { @@ -26,6 +27,11 @@ class ClassSerializer { } } +/** + * @param {Constructor} Constructor the constructor + * @param {string} request the request which will be required when deserializing + * @param {string | null} [name] the name to make multiple serializer unique when sharing a request + */ module.exports = (Constructor, request, name = null) => { register(Constructor, request, name, new ClassSerializer(Constructor)); }; diff --git a/lib/util/memoize.js b/lib/util/memoize.js index 981b5318882..c79d1fd8037 100644 --- a/lib/util/memoize.js +++ b/lib/util/memoize.js @@ -13,19 +13,19 @@ */ const memoize = fn => { let cache = false; - /** @type {T} */ - let result = undefined; + /** @type {T | undefined} */ + let result; return () => { if (cache) { - return result; - } else { - result = fn(); - cache = true; - // Allow to clean up memory for fn - // and all dependent resources - fn = undefined; - return result; + return /** @type {T} */ (result); } + + result = fn(); + cache = true; + // Allow to clean up memory for fn + // and all dependent resources + fn = undefined; + return /** @type {T} */ (result); }; }; diff --git a/lib/util/mergeScope.js b/lib/util/mergeScope.js new file mode 100644 index 00000000000..a1a1d2cc011 --- /dev/null +++ b/lib/util/mergeScope.js @@ -0,0 +1,76 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ + +"use strict"; + +/** @typedef {import("eslint-scope").Reference} Reference */ +/** @typedef {import("eslint-scope").Variable} Variable */ +/** @typedef {import("../javascript/JavascriptParser").AnyNode} AnyNode */ +/** @typedef {import("../javascript/JavascriptParser").Program} Program */ + +/** + * @param {Variable} variable variable + * @returns {Reference[]} references + */ +const getAllReferences = variable => { + let set = variable.references; + // Look for inner scope variables too (like in class Foo { t() { Foo } }) + const identifiers = new Set(variable.identifiers); + for (const scope of variable.scope.childScopes) { + for (const innerVar of scope.variables) { + if (innerVar.identifiers.some(id => identifiers.has(id))) { + set = set.concat(innerVar.references); + break; + } + } + } + return set; +}; + +/** + * @param {Program | Program[]} ast ast + * @param {AnyNode} node node + * @returns {undefined | AnyNode[]} result + */ +const getPathInAst = (ast, node) => { + if (ast === node) { + return []; + } + + const nr = node.range; + + const enterNode = n => { + if (!n) return; + const r = n.range; + if (r && r[0] <= nr[0] && r[1] >= nr[1]) { + const path = getPathInAst(n, node); + if (path) { + path.push(n); + return path; + } + } + }; + + if (Array.isArray(ast)) { + for (let i = 0; i < ast.length; i++) { + const enterResult = enterNode(ast[i]); + if (enterResult !== undefined) return enterResult; + } + } else if (ast && typeof ast === "object") { + const keys = Object.keys(ast); + for (let i = 0; i < keys.length; i++) { + const value = ast[keys[i]]; + if (Array.isArray(value)) { + const pathResult = getPathInAst(value, node); + if (pathResult !== undefined) return pathResult; + } else if (value && typeof value === "object") { + const enterResult = enterNode(value); + if (enterResult !== undefined) return enterResult; + } + } + } +}; + +module.exports = { getAllReferences, getPathInAst }; diff --git a/lib/util/nonNumericOnlyHash.js b/lib/util/nonNumericOnlyHash.js new file mode 100644 index 00000000000..ec8ca745ffc --- /dev/null +++ b/lib/util/nonNumericOnlyHash.js @@ -0,0 +1,22 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Ivan Kopeykin @vankop +*/ + +"use strict"; + +const A_CODE = "a".charCodeAt(0); + +/** + * @param {string} hash hash + * @param {number} hashLength hash length + * @returns {string} returns hash that has at least one non numeric char + */ +module.exports = (hash, hashLength) => { + if (hashLength < 1) return ""; + const slice = hash.slice(0, hashLength); + if (/[^\d]/.test(slice)) return slice; + return `${String.fromCharCode( + A_CODE + (Number.parseInt(hash[0], 10) % 6) + )}${slice.slice(1)}`; +}; diff --git a/lib/util/numberHash.js b/lib/util/numberHash.js index 219d1af94de..950d14bf8bb 100644 --- a/lib/util/numberHash.js +++ b/lib/util/numberHash.js @@ -5,41 +5,91 @@ "use strict"; -const SAFE_LIMIT = 0x80000000; -const SAFE_PART = SAFE_LIMIT - 1; -const COUNT = 4; -const arr = [0, 0, 0, 0, 0]; -const primes = [3, 7, 17, 19]; +/** + * Threshold for switching from 32-bit to 64-bit hashing. This is selected to ensure that the bias towards lower modulo results when using 32-bit hashing is <0.5%. + * @type {number} + */ +const FNV_64_THRESHOLD = 1 << 24; -module.exports = (str, range) => { - arr.fill(0); - for (let i = 0; i < str.length; i++) { - const c = str.charCodeAt(i); - for (let j = 0; j < COUNT; j++) { - const p = (j + COUNT - 1) % COUNT; - arr[j] = (arr[j] + c * primes[j] + arr[p]) & SAFE_PART; - } - for (let j = 0; j < COUNT; j++) { - const q = arr[j] % COUNT; - arr[j] = arr[j] ^ (arr[q] >> 1); - } +/** + * The FNV-1a offset basis for 32-bit hash values. + * @type {number} + */ +const FNV_OFFSET_32 = 2166136261; +/** + * The FNV-1a prime for 32-bit hash values. + * @type {number} + */ +const FNV_PRIME_32 = 16777619; +/** + * The mask for a positive 32-bit signed integer. + * @type {number} + */ +const MASK_31 = 0x7fffffff; + +/** + * The FNV-1a offset basis for 64-bit hash values. + * @type {bigint} + */ +const FNV_OFFSET_64 = BigInt("0xCBF29CE484222325"); +/** + * The FNV-1a prime for 64-bit hash values. + * @type {bigint} + */ +const FNV_PRIME_64 = BigInt("0x100000001B3"); + +/** + * Computes a 32-bit FNV-1a hash value for the given string. + * See https://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function + * @param {string} str The input string to hash + * @returns {number} - The computed hash value. + */ +function fnv1a32(str) { + let hash = FNV_OFFSET_32; + for (let i = 0, len = str.length; i < len; i++) { + hash ^= str.charCodeAt(i); + // Use Math.imul to do c-style 32-bit multiplication and keep only the 32 least significant bits + hash = Math.imul(hash, FNV_PRIME_32); } - if (range <= SAFE_PART) { - let sum = 0; - for (let j = 0; j < COUNT; j++) { - sum = (sum + arr[j]) % range; - } - return sum; - } else { - let sum1 = 0; - let sum2 = 0; - const rangeExt = Math.floor(range / SAFE_LIMIT); - for (let j = 0; j < COUNT; j += 2) { - sum1 = (sum1 + arr[j]) & SAFE_PART; - } - for (let j = 1; j < COUNT; j += 2) { - sum2 = (sum2 + arr[j]) % rangeExt; - } - return (sum2 * SAFE_LIMIT + sum1) % range; + // Force the result to be positive + return hash & MASK_31; +} + +/** + * Computes a 64-bit FNV-1a hash value for the given string. + * See https://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function + * @param {string} str The input string to hash + * @returns {bigint} - The computed hash value. + */ +function fnv1a64(str) { + let hash = FNV_OFFSET_64; + for (let i = 0, len = str.length; i < len; i++) { + hash ^= BigInt(str.charCodeAt(i)); + hash = BigInt.asUintN(64, hash * FNV_PRIME_64); + } + return hash; +} + +/** + * Computes a hash value for the given string and range. This hashing algorithm is a modified + * version of the [FNV-1a algorithm](https://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function). + * It is optimized for speed and does **not** generate a cryptographic hash value. + * + * We use `numberHash` in `lib/ids/IdHelpers.js` to generate hash values for the module identifier. The generated + * hash is used as a prefix for the module id's to avoid collisions with other modules. + * @param {string} str The input string to hash. + * @param {number} range The range of the hash value (0 to range-1). + * @returns {number} - The computed hash value. + * @example + * ```js + * const numberHash = require("webpack/lib/util/numberHash"); + * numberHash("hello", 1000); // 73 + * numberHash("hello world"); // 72 + * ``` + */ +module.exports = (str, range) => { + if (range < FNV_64_THRESHOLD) { + return fnv1a32(str) % range; } + return Number(fnv1a64(str) % BigInt(range)); }; diff --git a/lib/util/objectToMap.js b/lib/util/objectToMap.js index fbd9808c99f..19ce8e08f77 100644 --- a/lib/util/objectToMap.js +++ b/lib/util/objectToMap.js @@ -6,7 +6,6 @@ /** * Convert an object into an ES6 map - * * @param {object} obj any object type that works with Object.entries() * @returns {Map} an ES6 Map of KV pairs */ diff --git a/lib/util/processAsyncTree.js b/lib/util/processAsyncTree.js index 4d017991878..38253865231 100644 --- a/lib/util/processAsyncTree.js +++ b/lib/util/processAsyncTree.js @@ -7,10 +7,11 @@ /** * @template T + * @template {Error} E * @param {Iterable} items initial items * @param {number} concurrency number of items running in parallel - * @param {function(T, function(T): void, function(Error=): void): void} processor worker which pushes more items - * @param {function(Error=): void} callback all items processed + * @param {function(T, function(T): void, function(E=): void): void} processor worker which pushes more items + * @param {function(E=): void} callback all items processed * @returns {void} */ const processAsyncTree = (items, concurrency, processor, callback) => { @@ -20,6 +21,9 @@ const processAsyncTree = (items, concurrency, processor, callback) => { let finished = false; let processScheduled = true; + /** + * @param {T} item item + */ const push = item => { queue.push(item); if (!processScheduled && processing < concurrency) { @@ -28,6 +32,9 @@ const processAsyncTree = (items, concurrency, processor, callback) => { } }; + /** + * @param {E | null | undefined} err error + */ const processorCallback = err => { processing--; if (err && !finished) { @@ -45,7 +52,7 @@ const processAsyncTree = (items, concurrency, processor, callback) => { if (finished) return; while (processing < concurrency && queue.length > 0) { processing++; - const item = queue.pop(); + const item = /** @type {T} */ (queue.pop()); processor(item, push, processorCallback); } processScheduled = false; diff --git a/lib/util/propertyAccess.js b/lib/util/propertyAccess.js index 9a0b6344292..0cf647bd9e0 100644 --- a/lib/util/propertyAccess.js +++ b/lib/util/propertyAccess.js @@ -5,15 +5,20 @@ "use strict"; -const SAFE_IDENTIFIER = /^[_a-zA-Z$][_a-zA-Z$0-9]*$/; +const { SAFE_IDENTIFIER, RESERVED_IDENTIFIER } = require("./propertyName"); +/** + * @param {ArrayLike} properties properties + * @param {number} start start index + * @returns {string} chain of property accesses + */ const propertyAccess = (properties, start = 0) => { let str = ""; for (let i = start; i < properties.length; i++) { const p = properties[i]; - if (`${+p}` === p) { + if (`${Number(p)}` === p) { str += `[${p}]`; - } else if (SAFE_IDENTIFIER.test(p)) { + } else if (SAFE_IDENTIFIER.test(p) && !RESERVED_IDENTIFIER.has(p)) { str += `.${p}`; } else { str += `[${JSON.stringify(p)}]`; diff --git a/lib/util/propertyName.js b/lib/util/propertyName.js new file mode 100644 index 00000000000..4ee9e3f5485 --- /dev/null +++ b/lib/util/propertyName.js @@ -0,0 +1,77 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ + +"use strict"; + +const SAFE_IDENTIFIER = /^[_a-zA-Z$][_a-zA-Z$0-9]*$/; +const RESERVED_IDENTIFIER = new Set([ + "break", + "case", + "catch", + "class", + "const", + "continue", + "debugger", + "default", + "delete", + "do", + "else", + "export", + "extends", + "finally", + "for", + "function", + "if", + "import", + "in", + "instanceof", + "new", + "return", + "super", + "switch", + "this", + "throw", + "try", + "typeof", + "var", + "void", + "while", + "with", + "enum", + // strict mode + "implements", + "interface", + "let", + "package", + "private", + "protected", + "public", + "static", + "yield", + "yield", + // module code + "await", + // skip future reserved keywords defined under ES1 till ES3 + // additional + "null", + "true", + "false" +]); + +/** + * @summary Returns a valid JS property name for the given property. + * Certain strings like "default", "null", and names with whitespace are not + * valid JS property names, so they are returned as strings. + * @param {string} prop property name to analyze + * @returns {string} valid JS property name + */ +const propertyName = prop => { + if (SAFE_IDENTIFIER.test(prop) && !RESERVED_IDENTIFIER.has(prop)) { + return prop; + } + return JSON.stringify(prop); +}; + +module.exports = { SAFE_IDENTIFIER, RESERVED_IDENTIFIER, propertyName }; diff --git a/lib/util/registerExternalSerializer.js b/lib/util/registerExternalSerializer.js index 7bf3f9d13b2..711bcfa210a 100644 --- a/lib/util/registerExternalSerializer.js +++ b/lib/util/registerExternalSerializer.js @@ -9,7 +9,7 @@ const { register } = require("./serialization"); const Position = /** @type {TODO} */ (require("acorn")).Position; const SourceLocation = require("acorn").SourceLocation; -const { ValidationError } = require("schema-utils"); +const ValidationError = require("schema-utils").ValidationError; const { CachedSource, ConcatSource, @@ -26,7 +26,7 @@ const { /** @typedef {import("./serialization").ObjectDeserializerContext} ObjectDeserializerContext */ /** @typedef {import("./serialization").ObjectSerializerContext} ObjectSerializerContext */ -/** @typedef {ObjectSerializerContext & { writeLazy?: (any) => void }} WebpackObjectSerializerContext */ +/** @typedef {ObjectSerializerContext & { writeLazy?: (value: any) => void }} WebpackObjectSerializerContext */ const CURRENT_MODULE = "webpack/lib/util/registerExternalSerializer"; diff --git a/lib/util/runtime.js b/lib/util/runtime.js index 48af1c2167e..2b5dc4e3aaf 100644 --- a/lib/util/runtime.js +++ b/lib/util/runtime.js @@ -19,7 +19,7 @@ const SortableSet = require("./SortableSet"); * @param {EntryOptions=} options optionally already received entry options * @returns {RuntimeSpec} runtime */ -exports.getEntryRuntime = (compilation, name, options) => { +module.exports.getEntryRuntime = (compilation, name, options) => { let dependOn; let runtime; if (options) { @@ -31,7 +31,7 @@ exports.getEntryRuntime = (compilation, name, options) => { } if (dependOn) { /** @type {RuntimeSpec} */ - let result = undefined; + let result; const queue = new Set(dependOn); for (const name of queue) { const dep = compilation.entries.get(name); @@ -46,18 +46,17 @@ exports.getEntryRuntime = (compilation, name, options) => { } } return result || name; - } else { - return runtime || name; } + return runtime || name; }; /** * @param {RuntimeSpec} runtime runtime - * @param {function(string): void} fn functor + * @param {function(string | undefined): void} fn functor * @param {boolean} deterministicOrder enforce a deterministic order * @returns {void} */ -exports.forEachRuntime = (runtime, fn, deterministicOrder = false) => { +const forEachRuntime = (runtime, fn, deterministicOrder = false) => { if (runtime === undefined) { fn(undefined); } else if (typeof runtime === "string") { @@ -69,7 +68,13 @@ exports.forEachRuntime = (runtime, fn, deterministicOrder = false) => { } } }; +module.exports.forEachRuntime = forEachRuntime; +/** + * @template T + * @param {SortableSet} set set + * @returns {string} runtime key + */ const getRuntimesKey = set => { set.sort(); return Array.from(set).join("\n"); @@ -84,20 +89,25 @@ const getRuntimeKey = runtime => { if (typeof runtime === "string") return runtime; return runtime.getFromUnorderedCache(getRuntimesKey); }; -exports.getRuntimeKey = getRuntimeKey; +module.exports.getRuntimeKey = getRuntimeKey; /** * @param {string} key key of runtimes * @returns {RuntimeSpec} runtime(s) */ const keyToRuntime = key => { - if (key === "*") return undefined; + if (key === "*") return; const items = key.split("\n"); if (items.length === 1) return items[0]; return new SortableSet(items); }; -exports.keyToRuntime = keyToRuntime; +module.exports.keyToRuntime = keyToRuntime; +/** + * @template T + * @param {SortableSet} set set + * @returns {string} runtime string + */ const getRuntimesString = set => { set.sort(); return Array.from(set).join("+"); @@ -112,13 +122,13 @@ const runtimeToString = runtime => { if (typeof runtime === "string") return runtime; return runtime.getFromUnorderedCache(getRuntimesString); }; -exports.runtimeToString = runtimeToString; +module.exports.runtimeToString = runtimeToString; /** * @param {RuntimeCondition} runtimeCondition runtime condition * @returns {string} readable version */ -exports.runtimeConditionToString = runtimeCondition => { +module.exports.runtimeConditionToString = runtimeCondition => { if (runtimeCondition === true) return "true"; if (runtimeCondition === false) return "false"; return runtimeToString(runtimeCondition); @@ -141,40 +151,38 @@ const runtimeEqual = (a, b) => { return false; } else if (a.size !== b.size) { return false; - } else { - a.sort(); - b.sort(); - const aIt = a[Symbol.iterator](); - const bIt = b[Symbol.iterator](); - for (;;) { - const aV = aIt.next(); - if (aV.done) return true; - const bV = bIt.next(); - if (aV.value !== bV.value) return false; - } + } + a.sort(); + b.sort(); + const aIt = a[Symbol.iterator](); + const bIt = b[Symbol.iterator](); + for (;;) { + const aV = aIt.next(); + if (aV.done) return true; + const bV = bIt.next(); + if (aV.value !== bV.value) return false; } }; -exports.runtimeEqual = runtimeEqual; +module.exports.runtimeEqual = runtimeEqual; /** * @param {RuntimeSpec} a first * @param {RuntimeSpec} b second * @returns {-1|0|1} compare */ -exports.compareRuntime = (a, b) => { +module.exports.compareRuntime = (a, b) => { if (a === b) { return 0; } else if (a === undefined) { return -1; } else if (b === undefined) { return 1; - } else { - const aKey = getRuntimeKey(a); - const bKey = getRuntimeKey(b); - if (aKey < bKey) return -1; - if (aKey > bKey) return 1; - return 0; } + const aKey = getRuntimeKey(a); + const bKey = getRuntimeKey(b); + if (aKey < bKey) return -1; + if (aKey > bKey) return 1; + return 0; }; /** @@ -197,26 +205,23 @@ const mergeRuntime = (a, b) => { return set; } else if (b.has(a)) { return b; - } else { - const set = new SortableSet(b); - set.add(a); - return set; - } - } else { - if (typeof b === "string") { - if (a.has(b)) return a; - const set = new SortableSet(a); - set.add(b); - return set; - } else { - const set = new SortableSet(a); - for (const item of b) set.add(item); - if (set.size === a.size) return a; - return set; } + const set = new SortableSet(b); + set.add(a); + return set; + } + if (typeof b === "string") { + if (a.has(b)) return a; + const set = new SortableSet(a); + set.add(b); + return set; } + const set = new SortableSet(a); + for (const item of b) set.add(item); + if (set.size === a.size) return a; + return set; }; -exports.mergeRuntime = mergeRuntime; +module.exports.mergeRuntime = mergeRuntime; /** * @param {RuntimeCondition} a first @@ -224,12 +229,12 @@ exports.mergeRuntime = mergeRuntime; * @param {RuntimeSpec} runtime full runtime * @returns {RuntimeCondition} result */ -exports.mergeRuntimeCondition = (a, b, runtime) => { +module.exports.mergeRuntimeCondition = (a, b, runtime) => { if (a === false) return b; if (b === false) return a; if (a === true || b === true) return true; const merged = mergeRuntime(a, b); - if (merged === undefined) return undefined; + if (merged === undefined) return; if (typeof merged === "string") { if (typeof runtime === "string" && merged === runtime) return true; return merged; @@ -245,10 +250,10 @@ exports.mergeRuntimeCondition = (a, b, runtime) => { * @param {RuntimeSpec} runtime full runtime * @returns {RuntimeSpec | true} result */ -exports.mergeRuntimeConditionNonFalse = (a, b, runtime) => { +module.exports.mergeRuntimeConditionNonFalse = (a, b, runtime) => { if (a === true || b === true) return true; const merged = mergeRuntime(a, b); - if (merged === undefined) return undefined; + if (merged === undefined) return; if (typeof merged === "string") { if (typeof runtime === "string" && merged === runtime) return true; return merged; @@ -271,38 +276,34 @@ const mergeRuntimeOwned = (a, b) => { } else if (a === undefined) { if (typeof b === "string") { return b; - } else { - return new SortableSet(b); } + return new SortableSet(b); } else if (typeof a === "string") { if (typeof b === "string") { const set = new SortableSet(); set.add(a); set.add(b); return set; - } else { - const set = new SortableSet(b); - set.add(a); - return set; - } - } else { - if (typeof b === "string") { - a.add(b); - return a; - } else { - for (const item of b) a.add(item); - return a; } + const set = new SortableSet(b); + set.add(a); + return set; + } + if (typeof b === "string") { + a.add(b); + return a; } + for (const item of b) a.add(item); + return a; }; -exports.mergeRuntimeOwned = mergeRuntimeOwned; +module.exports.mergeRuntimeOwned = mergeRuntimeOwned; /** * @param {RuntimeSpec} a first * @param {RuntimeSpec} b second * @returns {RuntimeSpec} merged */ -exports.intersectRuntime = (a, b) => { +module.exports.intersectRuntime = (a, b) => { if (a === undefined) { return b; } else if (b === undefined) { @@ -311,26 +312,26 @@ exports.intersectRuntime = (a, b) => { return a; } else if (typeof a === "string") { if (typeof b === "string") { - return undefined; + return; } else if (b.has(a)) { return a; - } else { - return undefined; - } - } else { - if (typeof b === "string") { - if (a.has(b)) return b; - return undefined; - } else { - const set = new SortableSet(); - for (const item of b) { - if (a.has(item)) set.add(item); - } - if (set.size === 0) return undefined; - if (set.size === 1) for (const item of set) return item; - return set; } + return; + } + if (typeof b === "string") { + if (a.has(b)) return b; + return; + } + const set = new SortableSet(); + for (const item of b) { + if (a.has(item)) set.add(item); } + if (set.size === 0) return; + if (set.size === 1) { + const [item] = set; + return item; + } + return set; }; /** @@ -340,41 +341,42 @@ exports.intersectRuntime = (a, b) => { */ const subtractRuntime = (a, b) => { if (a === undefined) { - return undefined; + return; } else if (b === undefined) { return a; } else if (a === b) { - return undefined; + return; } else if (typeof a === "string") { if (typeof b === "string") { - return undefined; - } else if (b.has(a)) { - return undefined; - } else { return a; + } else if (b.has(a)) { + return; } - } else { - if (typeof b === "string") { - if (!a.has(b)) return a; - if (a.size === 2) { - for (const item of a) { - if (item !== b) return item; - } - } - const set = new SortableSet(a); - set.delete(b); - } else { - const set = new SortableSet(); + return a; + } + if (typeof b === "string") { + if (!a.has(b)) return a; + if (a.size === 2) { for (const item of a) { - if (!b.has(item)) set.add(item); + if (item !== b) return item; } - if (set.size === 0) return undefined; - if (set.size === 1) for (const item of set) return item; - return set; } + const set = new SortableSet(a); + set.delete(b); + return set; } + const set = new SortableSet(); + for (const item of a) { + if (!b.has(item)) set.add(item); + } + if (set.size === 0) return; + if (set.size === 1) { + const [item] = set; + return item; + } + return set; }; -exports.subtractRuntime = subtractRuntime; +module.exports.subtractRuntime = subtractRuntime; /** * @param {RuntimeCondition} a first @@ -382,7 +384,7 @@ exports.subtractRuntime = subtractRuntime; * @param {RuntimeSpec} runtime runtime * @returns {RuntimeCondition} result */ -exports.subtractRuntimeCondition = (a, b, runtime) => { +module.exports.subtractRuntimeCondition = (a, b, runtime) => { if (b === true) return false; if (b === false) return a; if (a === false) return false; @@ -392,15 +394,15 @@ exports.subtractRuntimeCondition = (a, b, runtime) => { /** * @param {RuntimeSpec} runtime runtime - * @param {function(RuntimeSpec): boolean} filter filter function + * @param {function(RuntimeSpec=): boolean} filter filter function * @returns {boolean | RuntimeSpec} true/false if filter is constant for all runtimes, otherwise runtimes that are active */ -exports.filterRuntime = (runtime, filter) => { - if (runtime === undefined) return filter(undefined); +module.exports.filterRuntime = (runtime, filter) => { + if (runtime === undefined) return filter(); if (typeof runtime === "string") return filter(runtime); let some = false; let every = true; - let result = undefined; + let result; for (const r of runtime) { const v = filter(r); if (v) { @@ -415,6 +417,11 @@ exports.filterRuntime = (runtime, filter) => { return result; }; +/** + * @template T + * @typedef {Map} RuntimeSpecMapInnerMap + */ + /** * @template T */ @@ -426,26 +433,28 @@ class RuntimeSpecMap { this._mode = clone ? clone._mode : 0; // 0 = empty, 1 = single entry, 2 = map /** @type {RuntimeSpec} */ this._singleRuntime = clone ? clone._singleRuntime : undefined; - /** @type {T} */ + /** @type {T | undefined} */ this._singleValue = clone ? clone._singleValue : undefined; - /** @type {Map | undefined} */ + /** @type {RuntimeSpecMapInnerMap | undefined} */ this._map = clone && clone._map ? new Map(clone._map) : undefined; } /** * @param {RuntimeSpec} runtime the runtimes - * @returns {T} value + * @returns {T | undefined} value */ get(runtime) { switch (this._mode) { case 0: - return undefined; + return; case 1: return runtimeEqual(this._singleRuntime, runtime) ? this._singleValue : undefined; default: - return this._map.get(getRuntimeKey(runtime)); + return /** @type {RuntimeSpecMapInnerMap} */ (this._map).get( + getRuntimeKey(runtime) + ); } } @@ -460,10 +469,16 @@ class RuntimeSpecMap { case 1: return runtimeEqual(this._singleRuntime, runtime); default: - return this._map.has(getRuntimeKey(runtime)); + return /** @type {RuntimeSpecMapInnerMap} */ (this._map).has( + getRuntimeKey(runtime) + ); } } + /** + * @param {RuntimeSpec} runtime the runtimes + * @param {T} value the value + */ set(runtime, value) { switch (this._mode) { case 0: @@ -478,15 +493,24 @@ class RuntimeSpecMap { } this._mode = 2; this._map = new Map(); - this._map.set(getRuntimeKey(this._singleRuntime), this._singleValue); + this._map.set( + getRuntimeKey(this._singleRuntime), + /** @type {T} */ (this._singleValue) + ); this._singleRuntime = undefined; this._singleValue = undefined; /* falls through */ default: - this._map.set(getRuntimeKey(runtime), value); + /** @type {RuntimeSpecMapInnerMap} */ + (this._map).set(getRuntimeKey(runtime), value); } } + /** + * @param {RuntimeSpec} runtime the runtimes + * @param {() => TODO} computer function to compute the value + * @returns {TODO} true, when the runtime was deleted + */ provide(runtime, computer) { switch (this._mode) { case 0: @@ -495,11 +519,14 @@ class RuntimeSpecMap { return (this._singleValue = computer()); case 1: { if (runtimeEqual(this._singleRuntime, runtime)) { - return this._singleValue; + return /** @type {T} */ (this._singleValue); } this._mode = 2; this._map = new Map(); - this._map.set(getRuntimeKey(this._singleRuntime), this._singleValue); + this._map.set( + getRuntimeKey(this._singleRuntime), + /** @type {T} */ (this._singleValue) + ); this._singleRuntime = undefined; this._singleValue = undefined; const newValue = computer(); @@ -508,15 +535,19 @@ class RuntimeSpecMap { } default: { const key = getRuntimeKey(runtime); - const value = this._map.get(key); + const value = /** @type {Map} */ (this._map).get(key); if (value !== undefined) return value; const newValue = computer(); - this._map.set(key, newValue); + /** @type {Map} */ + (this._map).set(key, newValue); return newValue; } } } + /** + * @param {RuntimeSpec} runtime the runtimes + */ delete(runtime) { switch (this._mode) { case 0: @@ -529,10 +560,15 @@ class RuntimeSpecMap { } return; default: - this._map.delete(getRuntimeKey(runtime)); + /** @type {RuntimeSpecMapInnerMap} */ + (this._map).delete(getRuntimeKey(runtime)); } } + /** + * @param {RuntimeSpec} runtime the runtimes + * @param {function(T | undefined): T} fn function to update the value + */ update(runtime, fn) { switch (this._mode) { case 0: @@ -546,7 +582,10 @@ class RuntimeSpecMap { if (newValue !== undefined) { this._mode = 2; this._map = new Map(); - this._map.set(getRuntimeKey(this._singleRuntime), this._singleValue); + this._map.set( + getRuntimeKey(this._singleRuntime), + /** @type {T} */ (this._singleValue) + ); this._singleRuntime = undefined; this._singleValue = undefined; this._map.set(getRuntimeKey(runtime), newValue); @@ -555,9 +594,11 @@ class RuntimeSpecMap { } default: { const key = getRuntimeKey(runtime); - const oldValue = this._map.get(key); + const oldValue = /** @type {Map} */ (this._map).get(key); const newValue = fn(oldValue); - if (newValue !== oldValue) this._map.set(key, newValue); + if (newValue !== oldValue) + /** @type {RuntimeSpecMapInnerMap} */ + (this._map).set(key, newValue); } } } @@ -569,7 +610,11 @@ class RuntimeSpecMap { case 1: return [this._singleRuntime]; default: - return Array.from(this._map.keys(), keyToRuntime); + return Array.from( + /** @type {RuntimeSpecMapInnerMap} */ + (this._map).keys(), + keyToRuntime + ); } } @@ -578,21 +623,24 @@ class RuntimeSpecMap { case 0: return [][Symbol.iterator](); case 1: - return [this._singleValue][Symbol.iterator](); + return [/** @type {T} */ (this._singleValue)][Symbol.iterator](); default: - return this._map.values(); + return /** @type {Map} */ (this._map).values(); } } get size() { - if (this._mode <= 1) return this._mode; - return this._map.size; + if (/** @type {number} */ (this._mode) <= 1) return this._mode; + return /** @type {Map} */ (this._map).size; } } -exports.RuntimeSpecMap = RuntimeSpecMap; +module.exports.RuntimeSpecMap = RuntimeSpecMap; class RuntimeSpecSet { + /** + * @param {Iterable=} iterable iterable + */ constructor(iterable) { /** @type {Map} */ this._map = new Map(); @@ -603,10 +651,17 @@ class RuntimeSpecSet { } } + /** + * @param {RuntimeSpec} runtime runtime + */ add(runtime) { this._map.set(getRuntimeKey(runtime), runtime); } + /** + * @param {RuntimeSpec} runtime runtime + * @returns {boolean} true, when the runtime exists + */ has(runtime) { return this._map.has(getRuntimeKey(runtime)); } @@ -620,4 +675,4 @@ class RuntimeSpecSet { } } -exports.RuntimeSpecSet = RuntimeSpecSet; +module.exports.RuntimeSpecSet = RuntimeSpecSet; diff --git a/lib/util/semver.js b/lib/util/semver.js index 4597d2bb523..8050c266601 100644 --- a/lib/util/semver.js +++ b/lib/util/semver.js @@ -5,6 +5,7 @@ "use strict"; +/** @typedef {import("../RuntimeTemplate")} RuntimeTemplate */ /** @typedef {(string|number|undefined|[])[]} SemVerRange */ /** @@ -31,7 +32,7 @@ const parseVersion = str => { } return ver; }; -exports.parseVersion = parseVersion; +module.exports.parseVersion = parseVersion; /* eslint-disable eqeqeq */ /** @@ -81,15 +82,17 @@ const versionLt = (a, b) => { } }; /* eslint-enable eqeqeq */ -exports.versionLt = versionLt; +module.exports.versionLt = versionLt; /** * @param {string} str range string * @returns {SemVerRange} parsed range */ -exports.parseRange = str => { +module.exports.parseRange = str => { const splitAndConvert = str => { - return str.split(".").map(item => (`${+item}` === item ? +item : item)); + return str + .split(".") + .map(item => (item !== "NaN" && `${+item}` === item ? +item : item)); }; // see https://docs.npmjs.com/misc/semver#range-grammar for grammar const parsePartial = str => { @@ -123,21 +126,23 @@ exports.parseRange = str => { } else if (range.length === 3) { // Special case for "1.2" is "1.2.x" instead of "=1.2" return [2, ...range.slice(1)]; - } else { - return [range.length, ...range.slice(1)]; } + + return [range.length, ...range.slice(1)]; }; const negate = range => { return [-range[0] - 1, ...range.slice(1)]; }; const parseSimple = str => { - // simple ::= primitive | partial | tilde | caret - // primitive ::= ( '<' | '>' | '>=' | '<=' | '=' ) partial - // tilde ::= '~' partial - // caret ::= '^' partial + // simple ::= primitive | partial | tilde | caret + // primitive ::= ( '<' | '>' | '>=' | '<=' | '=' | '!' ) ( ' ' ) * partial + // tilde ::= '~' ( ' ' ) * partial + // caret ::= '^' ( ' ' ) * partial const match = /^(\^|~|<=|<|>=|>|=|v|!)/.exec(str); const start = match ? match[0] : ""; - const remainder = parsePartial(str.slice(start.length)); + const remainder = parsePartial( + start.length ? str.slice(start.length).trim() : str.trim() + ); switch (start) { case "^": if (remainder.length > 1 && remainder[1] === 0) { @@ -148,6 +153,9 @@ exports.parseRange = str => { } return [1, ...remainder.slice(1)]; case "~": + if (remainder.length === 2 && remainder[0] === 0) { + return [1, ...remainder.slice(1)]; + } return [2, ...remainder.slice(1)]; case ">=": return remainder; @@ -191,11 +199,14 @@ exports.parseRange = str => { return [, ...arr, ...items.slice(1).map(() => fn)]; }; const parseRange = str => { - // range ::= hyphen | simple ( ' ' simple ) * | '' - // hyphen ::= partial ' - ' partial - const items = str.split(" - "); + // range ::= hyphen | simple ( ' ' ( ' ' ) * simple ) * | '' + // hyphen ::= partial ( ' ' ) * ' - ' ( ' ' ) * partial + const items = str.split(/\s+-\s+/); if (items.length === 1) { - const items = str.trim().split(/\s+/g).map(parseSimple); + const items = str + .trim() + .split(/(?<=[-0-9A-Za-z])\s+/g) + .map(parseSimple); return combine(items, 2); } const a = parsePartial(items[0]); @@ -224,16 +235,15 @@ const rangeToString = range => { fixCount == 0 ? ">=" : fixCount == -1 - ? "<" - : fixCount == 1 - ? "^" - : fixCount == 2 - ? "~" - : fixCount > 0 - ? "=" - : "!="; + ? "<" + : fixCount == 1 + ? "^" + : fixCount == 2 + ? "~" + : fixCount > 0 + ? "=" + : "!="; var needDot = 1; - // eslint-disable-next-line no-redeclare for (var i = 1; i < range.length; i++) { var item = range[i]; var t = (typeof item)[0]; @@ -241,35 +251,36 @@ const rangeToString = range => { str += t == "u" ? // undefined: prerelease marker, add an "-" - "-" + "-" : // number or string: add the item, set flag to add an "." between two of them - (needDot > 0 ? "." : "") + ((needDot = 2), item); + (needDot > 0 ? "." : "") + ((needDot = 2), item); } return str; - } else { - var stack = []; + } + /** @type {string[]} */ + var stack = []; + // eslint-disable-next-line no-redeclare + for (var i = 1; i < range.length; i++) { // eslint-disable-next-line no-redeclare - for (var i = 1; i < range.length; i++) { - // eslint-disable-next-line no-redeclare - var item = range[i]; - stack.push( - item === 0 - ? "not(" + pop() + ")" - : item === 1 + var item = range[i]; + stack.push( + item === 0 + ? "not(" + pop() + ")" + : item === 1 ? "(" + pop() + " || " + pop() + ")" : item === 2 - ? stack.pop() + " " + stack.pop() - : rangeToString(item) - ); - } - return pop(); + ? stack.pop() + " " + stack.pop() + : rangeToString(item) + ); } + return pop(); + function pop() { - return stack.pop().replace(/^\((.+)\)$/, "$1"); + return /** @type {string} */ (stack.pop()).replace(/^\((.+)\)$/, "$1"); } }; /* eslint-enable eqeqeq */ -exports.rangeToString = rangeToString; +module.exports.rangeToString = rangeToString; /* eslint-disable eqeqeq */ /** @@ -281,7 +292,7 @@ const satisfy = (range, version) => { if (0 in range) { // @ts-expect-error version = parseVersion(version); - var fixCount = range[0]; + var fixCount = /** @type {number} */ (range[0]); // when negated is set it swill set for < instead of >= var negated = fixCount < 0; if (negated) fixCount = -fixCount - 1; @@ -389,6 +400,7 @@ const satisfy = (range, version) => { } } else { // Handles all "next-ver" cases in the second table + // eslint-disable-next-line no-lonely-if if (rangeType != "s" && rangeType != "n") { isEqual = false; j--; @@ -408,18 +420,18 @@ const satisfy = (range, version) => { item == 1 ? p() | p() : item == 2 - ? p() & p() - : item - ? satisfy(item, version) - : !p() + ? p() & p() + : item + ? satisfy(item, version) + : !p() ); } return !!p(); }; /* eslint-enable eqeqeq */ -exports.satisfy = satisfy; +module.exports.satisfy = satisfy; -exports.stringifyHoley = json => { +module.exports.stringifyHoley = json => { switch (typeof json) { case "undefined": return ""; @@ -432,9 +444,9 @@ exports.stringifyHoley = json => { } str += "]"; return str; - } else { - return JSON.stringify(json); } + + return JSON.stringify(json); default: return JSON.stringify(json); } @@ -444,11 +456,7 @@ exports.stringifyHoley = json => { exports.parseVersionRuntimeCode = runtimeTemplate => `var parseVersion = ${runtimeTemplate.basicFunction("str", [ "// see webpack/lib/util/semver.js for original code", - `var p=${ - runtimeTemplate.supportsArrowFunction() ? "p=>" : "function(p)" - }{return p.split(".").map((${ - runtimeTemplate.supportsArrowFunction() ? "p=>" : "function(p)" - }{return+p==p?+p:p}))},n=/^([^-+]+)?(?:-([^+]+))?(?:\\+(.+))?$/.exec(str),r=n[1]?p(n[1]):[];return n[2]&&(r.length++,r.push.apply(r,p(n[2]))),n[3]&&(r.push([]),r.push.apply(r,p(n[3]))),r;` + `var p=${runtimeTemplate.supportsArrowFunction() ? "p=>" : "function(p)"}{return p.split(".").map((${runtimeTemplate.supportsArrowFunction() ? "p=>" : "function(p)"}{return+p==p?+p:p}))},n=/^([^-+]+)?(?:-([^+]+))?(?:\\+(.+))?$/.exec(str),r=n[1]?p(n[1]):[];return n[2]&&(r.length++,r.push.apply(r,p(n[2]))),n[3]&&(r.push([]),r.push.apply(r,p(n[3]))),r;` ])}`; //#endregion diff --git a/lib/util/serialization.js b/lib/util/serialization.js index ba34b3dd1c0..597f0390476 100644 --- a/lib/util/serialization.js +++ b/lib/util/serialization.js @@ -4,72 +4,150 @@ "use strict"; -const BinaryMiddleware = require("../serialization/BinaryMiddleware"); -const FileMiddleware = require("../serialization/FileMiddleware"); -const ObjectMiddleware = require("../serialization/ObjectMiddleware"); -const Serializer = require("../serialization/Serializer"); -const SerializerMiddleware = require("../serialization/SerializerMiddleware"); -const SingleItemMiddleware = require("../serialization/SingleItemMiddleware"); -const internalSerializables = require("./internalSerializables"); +const memoize = require("./memoize"); +/** @typedef {import("../serialization/BinaryMiddleware").MEASURE_END_OPERATION_TYPE} MEASURE_END_OPERATION */ +/** @typedef {import("../serialization/BinaryMiddleware").MEASURE_START_OPERATION_TYPE} MEASURE_START_OPERATION */ /** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */ /** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */ +/** @typedef {import("../serialization/Serializer")} Serializer */ +/** @typedef {typeof import("../util/Hash")} Hash */ +/** @typedef {import("../util/fs").IntermediateFileSystem} IntermediateFileSystem */ -const { register, registerLoader, registerNotSerializable } = ObjectMiddleware; +const getBinaryMiddleware = memoize(() => + require("../serialization/BinaryMiddleware") +); +const getObjectMiddleware = memoize(() => + require("../serialization/ObjectMiddleware") +); +const getSingleItemMiddleware = memoize(() => + require("../serialization/SingleItemMiddleware") +); +const getSerializer = memoize(() => require("../serialization/Serializer")); +const getSerializerMiddleware = memoize(() => + require("../serialization/SerializerMiddleware") +); -const binaryMiddleware = new BinaryMiddleware(); +const getBinaryMiddlewareInstance = memoize( + () => new (getBinaryMiddleware())() +); -// Expose serialization API -exports.register = register; -exports.registerLoader = registerLoader; -exports.registerNotSerializable = registerNotSerializable; -exports.NOT_SERIALIZABLE = ObjectMiddleware.NOT_SERIALIZABLE; -exports.MEASURE_START_OPERATION = BinaryMiddleware.MEASURE_START_OPERATION; -exports.MEASURE_END_OPERATION = BinaryMiddleware.MEASURE_END_OPERATION; -exports.buffersSerializer = new Serializer([ - new SingleItemMiddleware(), - new ObjectMiddleware(context => { - if (context.write) { - context.writeLazy = value => { - context.write(SerializerMiddleware.createLazy(value, binaryMiddleware)); - }; +const registerSerializers = memoize(() => { + require("./registerExternalSerializer"); + + // Load internal paths with a relative require + // This allows bundling all internal serializers + const internalSerializables = require("./internalSerializables"); + getObjectMiddleware().registerLoader(/^webpack\/lib\//, req => { + const loader = + internalSerializables[ + /** @type {keyof import("./internalSerializables")} */ + (req.slice("webpack/lib/".length)) + ]; + if (loader) { + loader(); + } else { + console.warn(`${req} not found in internalSerializables`); } - }), - binaryMiddleware -]); -exports.createFileSerializer = fs => { - const fileMiddleware = new FileMiddleware(fs); - return new Serializer([ - new SingleItemMiddleware(), - new ObjectMiddleware(context => { - if (context.write) { - context.writeLazy = value => { - context.write( - SerializerMiddleware.createLazy(value, binaryMiddleware) - ); - }; - context.writeSeparate = (value, options) => { - context.write( - SerializerMiddleware.createLazy(value, fileMiddleware, options) - ); - }; - } - }), - binaryMiddleware, - fileMiddleware - ]); -}; + return true; + }); +}); -require("./registerExternalSerializer"); +/** @type {Serializer} */ +let buffersSerializer; -// Load internal paths with a relative require -// This allows bundling all internal serializers -registerLoader(/^webpack\/lib\//, req => { - const loader = internalSerializables[req.slice("webpack/lib/".length)]; - if (loader) { - loader(); - } else { - console.warn(`${req} not found in internalSerializables`); +// Expose serialization API +module.exports = { + get register() { + return getObjectMiddleware().register; + }, + get registerLoader() { + return getObjectMiddleware().registerLoader; + }, + get registerNotSerializable() { + return getObjectMiddleware().registerNotSerializable; + }, + get NOT_SERIALIZABLE() { + return getObjectMiddleware().NOT_SERIALIZABLE; + }, + /** @type {MEASURE_START_OPERATION} */ + get MEASURE_START_OPERATION() { + return getBinaryMiddleware().MEASURE_START_OPERATION; + }, + /** @type {MEASURE_END_OPERATION} */ + get MEASURE_END_OPERATION() { + return getBinaryMiddleware().MEASURE_END_OPERATION; + }, + /** + * @returns {Serializer} buffer serializer + */ + get buffersSerializer() { + if (buffersSerializer !== undefined) return buffersSerializer; + registerSerializers(); + const Serializer = getSerializer(); + const binaryMiddleware = getBinaryMiddlewareInstance(); + const SerializerMiddleware = getSerializerMiddleware(); + const SingleItemMiddleware = getSingleItemMiddleware(); + return (buffersSerializer = new Serializer([ + new SingleItemMiddleware(), + new (getObjectMiddleware())(context => { + if (context.write) { + /** + * @param {any} value value + */ + context.writeLazy = value => { + context.write( + SerializerMiddleware.createLazy(value, binaryMiddleware) + ); + }; + } + }, "md4"), + binaryMiddleware + ])); + }, + /** + * @param {IntermediateFileSystem} fs filesystem + * @param {string | Hash} hashFunction hash function to use + * @returns {Serializer} file serializer + */ + createFileSerializer: (fs, hashFunction) => { + registerSerializers(); + const Serializer = getSerializer(); + const FileMiddleware = require("../serialization/FileMiddleware"); + const fileMiddleware = new FileMiddleware(fs, hashFunction); + const binaryMiddleware = getBinaryMiddlewareInstance(); + const SerializerMiddleware = getSerializerMiddleware(); + const SingleItemMiddleware = getSingleItemMiddleware(); + return new Serializer([ + new SingleItemMiddleware(), + new (getObjectMiddleware())(context => { + if (context.write) { + /** + * @param {any} value value + */ + context.writeLazy = value => { + context.write( + SerializerMiddleware.createLazy(value, binaryMiddleware) + ); + }; + /** + * @param {any} value value + * @param {object=} options lazy options + * @returns {function(): Promise | any} lazy function + */ + context.writeSeparate = (value, options) => { + const lazy = SerializerMiddleware.createLazy( + value, + fileMiddleware, + options + ); + context.write(lazy); + return lazy; + }; + } + }, hashFunction), + binaryMiddleware, + fileMiddleware + ]); } - return true; -}); +}; diff --git a/lib/util/smartGrouping.js b/lib/util/smartGrouping.js index f933a4e3a1c..f75648c45b8 100644 --- a/lib/util/smartGrouping.js +++ b/lib/util/smartGrouping.js @@ -6,7 +6,7 @@ "use strict"; /** - * @typedef {Object} GroupOptions + * @typedef {object} GroupOptions * @property {boolean=} groupChildren * @property {boolean=} force * @property {number=} targetGroupCount @@ -15,17 +15,24 @@ /** * @template T * @template R - * @typedef {Object} GroupConfig - * @property {function(T): string[]} getKeys + * @typedef {object} GroupConfig + * @property {function(T): string[] | undefined} getKeys * @property {function(string, (R | T)[], T[]): R} createGroup * @property {function(string, T[]): GroupOptions=} getOptions */ /** * @template T - * @typedef {Object} ItemWithGroups + * @template R + * @typedef {object} ItemWithGroups * @property {T} item - * @property {Set} groups + * @property {Set>} groups + */ + +/** + * @template T + * @template R + * @typedef {{ config: GroupConfig, name: string, alreadyGrouped: boolean, items: Set> | undefined }} Group */ /** @@ -36,22 +43,32 @@ * @returns {(R | T)[]} grouped items */ const smartGrouping = (items, groupConfigs) => { - /** @type {Set>} */ + /** @type {Set>} */ const itemsWithGroups = new Set(); - /** @type {Map, string]>} */ - const groupConfigMap = new Map(); + /** @type {Map>} */ + const allGroups = new Map(); for (const item of items) { + /** @type {Set>} */ const groups = new Set(); for (let i = 0; i < groupConfigs.length; i++) { const groupConfig = groupConfigs[i]; const keys = groupConfig.getKeys(item); if (keys) { - for (const group of keys) { - const fullGroup = `${i}:${group}`; - if (!groupConfigMap.has(fullGroup)) { - groupConfigMap.set(fullGroup, [groupConfig, group]); + for (const name of keys) { + const key = `${i}:${name}`; + let group = allGroups.get(key); + if (group === undefined) { + allGroups.set( + key, + (group = { + config: groupConfig, + name, + alreadyGrouped: false, + items: undefined + }) + ); } - groups.add(fullGroup); + groups.add(group); } } } @@ -60,61 +77,75 @@ const smartGrouping = (items, groupConfigs) => { groups }); } - const alreadyGrouped = new Set(); /** - * @param {Set>} itemsWithGroups input items with groups + * @param {Set>} itemsWithGroups input items with groups * @returns {(T | R)[]} groups items */ const runGrouping = itemsWithGroups => { const totalSize = itemsWithGroups.size; - /** @type {Map>>} */ - const groupMap = new Map(); for (const entry of itemsWithGroups) { for (const group of entry.groups) { - if (alreadyGrouped.has(group)) continue; - const list = groupMap.get(group); - if (list === undefined) { - groupMap.set(group, new Set([entry])); + if (group.alreadyGrouped) continue; + const items = group.items; + if (items === undefined) { + group.items = new Set([entry]); } else { - list.add(entry); + items.add(entry); } } } - /** @type {Set} */ - const usedGroups = new Set(); + /** @type {Map, { items: Set>, options: GroupOptions | false | undefined, used: boolean }>} */ + const groupMap = new Map(); + for (const group of allGroups.values()) { + if (group.items) { + const items = group.items; + group.items = undefined; + groupMap.set(group, { + items, + options: undefined, + used: false + }); + } + } /** @type {(T | R)[]} */ const results = []; for (;;) { - let bestGroup = undefined; + /** @type {Group | undefined} */ + let bestGroup; let bestGroupSize = -1; - let bestGroupItems = undefined; - let bestGroupOptions = undefined; - for (const [group, items] of groupMap) { - if (items.size === 0) continue; - const [groupConfig, groupKey] = groupConfigMap.get(group); - const options = - groupConfig.getOptions && - groupConfig.getOptions( - groupKey, - Array.from(items, ({ item }) => item) - ); + let bestGroupItems; + let bestGroupOptions; + for (const [group, state] of groupMap) { + const { items, used } = state; + let options = state.options; + if (options === undefined) { + const groupConfig = group.config; + state.options = options = + (groupConfig.getOptions && + groupConfig.getOptions( + group.name, + Array.from(items, ({ item }) => item) + )) || + false; + } + const force = options && options.force; if (!force) { if (bestGroupOptions && bestGroupOptions.force) continue; - if (usedGroups.has(group)) continue; + if (used) continue; if (items.size <= 1 || totalSize - items.size <= 1) { continue; } } const targetGroupCount = (options && options.targetGroupCount) || 4; - let sizeValue = force + const sizeValue = force ? items.size : Math.min( items.size, (totalSize * 2) / targetGroupCount + itemsWithGroups.size - items.size - ); + ); if ( sizeValue > bestGroupSize || (force && (!bestGroupOptions || !bestGroupOptions.force)) @@ -137,25 +168,30 @@ const smartGrouping = (items, groupConfigs) => { itemsWithGroups.delete(item); // Remove all groups that items have from the map to not select them again for (const group of item.groups) { - const list = groupMap.get(group); - if (list !== undefined) list.delete(item); - if (groupChildren) { - usedGroups.add(group); + const state = groupMap.get(group); + if (state !== undefined) { + state.items.delete(item); + if (state.items.size === 0) { + groupMap.delete(group); + } else { + state.options = undefined; + if (groupChildren) { + state.used = true; + } + } } } } groupMap.delete(bestGroup); - const idx = bestGroup.indexOf(":"); - const configKey = bestGroup.slice(0, idx); - const key = bestGroup.slice(idx + 1); - const groupConfig = groupConfigs[+configKey]; + const key = bestGroup.name; + const groupConfig = bestGroup.config; const allItems = Array.from(items, ({ item }) => item); - alreadyGrouped.add(bestGroup); + bestGroup.alreadyGrouped = true; const children = groupChildren ? runGrouping(items) : allItems; - alreadyGrouped.delete(bestGroup); + bestGroup.alreadyGrouped = false; results.push(groupConfig.createGroup(key, children, allItems)); } diff --git a/lib/util/source.js b/lib/util/source.js index 5f133471416..b9516786ba1 100644 --- a/lib/util/source.js +++ b/lib/util/source.js @@ -58,4 +58,4 @@ const isSourceEqual = (a, b) => { } return result; }; -exports.isSourceEqual = isSourceEqual; +module.exports.isSourceEqual = isSourceEqual; diff --git a/lib/validateSchema.js b/lib/validateSchema.js index 06a954a374d..fae211a358a 100644 --- a/lib/validateSchema.js +++ b/lib/validateSchema.js @@ -21,8 +21,7 @@ const DID_YOU_MEAN = { "output.environment (output.ecmaVersion was a temporary configuration option during webpack 5 beta)", ecmaversion: "output.environment (output.ecmaVersion was a temporary configuration option during webpack 5 beta)", - ecma: - "output.environment (output.ecmaVersion was a temporary configuration option during webpack 5 beta)", + ecma: "output.environment (output.ecmaVersion was a temporary configuration option during webpack 5 beta)", path: "output.path", pathinfo: "output.pathinfo", pathInfo: "output.pathinfo", @@ -109,7 +108,10 @@ const validateSchema = (schema, options, validationConfiguration) => { } if (error.keyword === "additionalProperties") { - const params = /** @type {import("ajv").AdditionalPropertiesParams} */ (error.params); + const params = + /** @type {import("ajv").AdditionalPropertiesParams} */ ( + error.params + ); if ( Object.prototype.hasOwnProperty.call( DID_YOU_MEAN, @@ -117,7 +119,9 @@ const validateSchema = (schema, options, validationConfiguration) => { ) ) { return `${formattedError}\nDid you mean ${ - DID_YOU_MEAN[params.additionalProperty] + DID_YOU_MEAN[ + /** @type {keyof DID_YOU_MEAN} */ (params.additionalProperty) + ] }?`; } @@ -127,7 +131,9 @@ const validateSchema = (schema, options, validationConfiguration) => { params.additionalProperty ) ) { - return `${formattedError}\n${REMOVED[params.additionalProperty]}?`; + return `${formattedError}\n${ + REMOVED[/** @type {keyof REMOVED} */ (params.additionalProperty)] + }?`; } if (!error.dataPath) { diff --git a/lib/wasm-async/AsyncWasmChunkLoadingRuntimeModule.js b/lib/wasm-async/AsyncWasmChunkLoadingRuntimeModule.js deleted file mode 100644 index 1781186ad08..00000000000 --- a/lib/wasm-async/AsyncWasmChunkLoadingRuntimeModule.js +++ /dev/null @@ -1,78 +0,0 @@ -/* - MIT License http://www.opensource.org/licenses/mit-license.php - Author Tobias Koppers @sokra -*/ - -"use strict"; - -const RuntimeGlobals = require("../RuntimeGlobals"); -const RuntimeModule = require("../RuntimeModule"); -const Template = require("../Template"); - -class AsyncWasmChunkLoadingRuntimeModule extends RuntimeModule { - constructor({ generateLoadBinaryCode, supportsStreaming }) { - super("wasm chunk loading", RuntimeModule.STAGE_ATTACH); - this.generateLoadBinaryCode = generateLoadBinaryCode; - this.supportsStreaming = supportsStreaming; - } - - /** - * @returns {string} runtime code - */ - generate() { - const { compilation, chunk } = this; - const { outputOptions, runtimeTemplate } = compilation; - const fn = RuntimeGlobals.instantiateWasm; - const wasmModuleSrcPath = compilation.getPath( - JSON.stringify(outputOptions.webassemblyModuleFilename), - { - hash: `" + ${RuntimeGlobals.getFullHash}() + "`, - hashWithLength: length => - `" + ${RuntimeGlobals.getFullHash}}().slice(0, ${length}) + "`, - module: { - id: '" + wasmModuleId + "', - hash: `" + wasmModuleHash + "`, - hashWithLength(length) { - return `" + wasmModuleHash.slice(0, ${length}) + "`; - } - }, - runtime: chunk.runtime - } - ); - return `${fn} = ${runtimeTemplate.basicFunction( - "exports, wasmModuleId, wasmModuleHash, importsObj", - [ - `var req = ${this.generateLoadBinaryCode(wasmModuleSrcPath)};`, - this.supportsStreaming - ? Template.asString([ - "if (typeof WebAssembly.instantiateStreaming === 'function') {", - Template.indent([ - "return WebAssembly.instantiateStreaming(req, importsObj)", - Template.indent([ - `.then(${runtimeTemplate.returningFunction( - "Object.assign(exports, res.instance.exports)", - "res" - )});` - ]) - ]), - "}" - ]) - : "// no support for streaming compilation", - "return req", - Template.indent([ - `.then(${runtimeTemplate.returningFunction("x.arrayBuffer()", "x")})`, - `.then(${runtimeTemplate.returningFunction( - "WebAssembly.instantiate(bytes, importsObj)", - "bytes" - )})`, - `.then(${runtimeTemplate.returningFunction( - "Object.assign(exports, res.instance.exports)", - "res" - )});` - ]) - ] - )};`; - } -} - -module.exports = AsyncWasmChunkLoadingRuntimeModule; diff --git a/lib/wasm-async/AsyncWasmLoadingRuntimeModule.js b/lib/wasm-async/AsyncWasmLoadingRuntimeModule.js new file mode 100644 index 00000000000..bf294381068 --- /dev/null +++ b/lib/wasm-async/AsyncWasmLoadingRuntimeModule.js @@ -0,0 +1,118 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ + +"use strict"; + +const RuntimeGlobals = require("../RuntimeGlobals"); +const RuntimeModule = require("../RuntimeModule"); +const Template = require("../Template"); + +/** @typedef {import("../Chunk")} Chunk */ +/** @typedef {import("../Compilation")} Compilation */ + +/** + * @typedef {object} AsyncWasmLoadingRuntimeModuleOptions + * @property {function(string): string} generateLoadBinaryCode + * @property {boolean} supportsStreaming + */ + +class AsyncWasmLoadingRuntimeModule extends RuntimeModule { + /** + * @param {AsyncWasmLoadingRuntimeModuleOptions} options options + */ + constructor({ generateLoadBinaryCode, supportsStreaming }) { + super("wasm loading", RuntimeModule.STAGE_NORMAL); + this.generateLoadBinaryCode = generateLoadBinaryCode; + this.supportsStreaming = supportsStreaming; + } + + /** + * @returns {string | null} runtime code + */ + generate() { + const compilation = /** @type {Compilation} */ (this.compilation); + const chunk = /** @type {Chunk} */ (this.chunk); + const { outputOptions, runtimeTemplate } = compilation; + const fn = RuntimeGlobals.instantiateWasm; + const wasmModuleSrcPath = compilation.getPath( + JSON.stringify(outputOptions.webassemblyModuleFilename), + { + hash: `" + ${RuntimeGlobals.getFullHash}() + "`, + hashWithLength: length => + `" + ${RuntimeGlobals.getFullHash}}().slice(0, ${length}) + "`, + module: { + id: '" + wasmModuleId + "', + hash: `" + wasmModuleHash + "`, + hashWithLength(length) { + return `" + wasmModuleHash.slice(0, ${length}) + "`; + } + }, + runtime: chunk.runtime + } + ); + + const loader = this.generateLoadBinaryCode(wasmModuleSrcPath); + const fallback = [ + `.then(${runtimeTemplate.returningFunction("x.arrayBuffer()", "x")})`, + `.then(${runtimeTemplate.returningFunction( + "WebAssembly.instantiate(bytes, importsObj)", + "bytes" + )})`, + `.then(${runtimeTemplate.returningFunction( + "Object.assign(exports, res.instance.exports)", + "res" + )})` + ]; + const getStreaming = () => { + const concat = (/** @type {string[]} */ ...text) => text.join(""); + return [ + `var req = ${loader};`, + `var fallback = ${runtimeTemplate.returningFunction( + Template.asString(["req", Template.indent(fallback)]) + )};`, + concat( + "return req.then(", + runtimeTemplate.basicFunction("res", [ + `if (typeof WebAssembly.instantiateStreaming === "function") {`, + Template.indent([ + "return WebAssembly.instantiateStreaming(res, importsObj)", + Template.indent([ + ".then(", + Template.indent([ + `${runtimeTemplate.returningFunction( + "Object.assign(exports, res.instance.exports)", + "res" + )},`, + runtimeTemplate.basicFunction("e", [ + `if(res.headers.get("Content-Type") !== "application/wasm") {`, + Template.indent([ + 'console.warn("`WebAssembly.instantiateStreaming` failed because your server does not serve wasm with `application/wasm` MIME type. Falling back to `WebAssembly.instantiate` which is slower. Original error:\\n", e);', + "return fallback();" + ]), + "}", + "throw e;" + ]) + ]), + ");" + ]) + ]), + "}", + "return fallback();" + ]), + ");" + ) + ]; + }; + + return `${fn} = ${runtimeTemplate.basicFunction( + "exports, wasmModuleId, wasmModuleHash, importsObj", + this.supportsStreaming + ? getStreaming() + : [`return ${loader}`, `${Template.indent(fallback)};`] + )};`; + } +} + +module.exports = AsyncWasmLoadingRuntimeModule; diff --git a/lib/wasm-async/AsyncWebAssemblyGenerator.js b/lib/wasm-async/AsyncWebAssemblyGenerator.js index 803f9010227..b29e8a00fb6 100644 --- a/lib/wasm-async/AsyncWebAssemblyGenerator.js +++ b/lib/wasm-async/AsyncWebAssemblyGenerator.js @@ -13,7 +13,15 @@ const Generator = require("../Generator"); const TYPES = new Set(["webassembly"]); +/** + * @typedef {object} AsyncWebAssemblyGeneratorOptions + * @property {boolean} [mangleImports] mangle imports + */ + class AsyncWebAssemblyGenerator extends Generator { + /** + * @param {AsyncWebAssemblyGeneratorOptions} options options + */ constructor(options) { super(); this.options = options; @@ -46,7 +54,7 @@ class AsyncWebAssemblyGenerator extends Generator { * @returns {Source} generated code */ generate(module, generateContext) { - return module.originalSource(); + return /** @type {Source} */ (module.originalSource()); } } diff --git a/lib/wasm-async/AsyncWebAssemblyJavascriptGenerator.js b/lib/wasm-async/AsyncWebAssemblyJavascriptGenerator.js index 90364d06e8b..f3f908f05b0 100644 --- a/lib/wasm-async/AsyncWebAssemblyJavascriptGenerator.js +++ b/lib/wasm-async/AsyncWebAssemblyJavascriptGenerator.js @@ -13,6 +13,7 @@ const Template = require("../Template"); const WebAssemblyImportDependency = require("../dependencies/WebAssemblyImportDependency"); /** @typedef {import("webpack-sources").Source} Source */ +/** @typedef {import("../../declarations/WebpackOptions").OutputNormalized} OutputOptions */ /** @typedef {import("../DependencyTemplates")} DependencyTemplates */ /** @typedef {import("../Generator").GenerateContext} GenerateContext */ /** @typedef {import("../Module")} Module */ @@ -21,7 +22,14 @@ const WebAssemblyImportDependency = require("../dependencies/WebAssemblyImportDe const TYPES = new Set(["webassembly"]); +/** + * @typedef {{ request: string, importVar: string }} ImportObjRequestItem + */ + class AsyncWebAssemblyJavascriptGenerator extends Generator { + /** + * @param {OutputOptions["webassemblyModuleFilename"]} filenameTemplate template for the WebAssembly module filename + */ constructor(filenameTemplate) { super(); this.filenameTemplate = filenameTemplate; @@ -61,15 +69,15 @@ class AsyncWebAssemblyJavascriptGenerator extends Generator { runtimeRequirements.add(RuntimeGlobals.moduleId); runtimeRequirements.add(RuntimeGlobals.exports); runtimeRequirements.add(RuntimeGlobals.instantiateWasm); - /** @type {InitFragment[]} */ + /** @type {InitFragment>[]} */ const initFragments = []; - /** @type {Map} */ + /** @type {Map} */ const depModules = new Map(); /** @type {Map} */ const wasmDepsByRequest = new Map(); for (const dep of module.dependencies) { if (dep instanceof WebAssemblyImportDependency) { - const module = moduleGraph.getModule(dep); + const module = /** @type {Module} */ (moduleGraph.getModule(dep)); if (!depModules.has(module)) { depModules.set(module, { request: dep.request, @@ -85,6 +93,7 @@ class AsyncWebAssemblyJavascriptGenerator extends Generator { } } + /** @type {Array} */ const promises = []; const importStatements = Array.from( @@ -111,8 +120,12 @@ class AsyncWebAssemblyJavascriptGenerator extends Generator { wasmDepsByRequest, ([request, deps]) => { const exportItems = deps.map(dep => { - const importedModule = moduleGraph.getModule(dep); - const importVar = depModules.get(importedModule).importVar; + const importedModule = + /** @type {Module} */ + (moduleGraph.getModule(dep)); + const importVar = + /** @type {ImportObjRequestItem} */ + (depModules.get(importedModule)).importVar; return `${JSON.stringify( dep.name )}: ${runtimeTemplate.exportFromImport({ @@ -145,15 +158,14 @@ class AsyncWebAssemblyJavascriptGenerator extends Generator { "{", Template.indent(importObjRequestItems.join(",\n")), "}" - ]) + ]) : undefined; - const instantiateCall = - `${RuntimeGlobals.instantiateWasm}(${module.exportsArgument}, ${ - module.moduleArgument - }.id, ${JSON.stringify( - chunkGraph.getRenderedModuleHash(module, runtime) - )}` + (importsObj ? `, ${importsObj})` : `)`); + const instantiateCall = `${RuntimeGlobals.instantiateWasm}(${module.exportsArgument}, ${ + module.moduleArgument + }.id, ${JSON.stringify( + chunkGraph.getRenderedModuleHash(module, runtime) + )}${importsObj ? `, ${importsObj})` : ")"}`; if (promises.length > 0) runtimeRequirements.add(RuntimeGlobals.asyncModule); @@ -167,17 +179,23 @@ class AsyncWebAssemblyJavascriptGenerator extends Generator { )}`, `${RuntimeGlobals.asyncModule}(${ module.moduleArgument - }, ${runtimeTemplate.basicFunction( - "__webpack_handle_async_dependencies__", + }, async ${runtimeTemplate.basicFunction( + "__webpack_handle_async_dependencies__, __webpack_async_result__", [ + "try {", importsCode, `var __webpack_async_dependencies__ = __webpack_handle_async_dependencies__([${promises.join( ", " )}]);`, - "return __webpack_async_dependencies__.then ? __webpack_async_dependencies__.then(__webpack_instantiate__) : __webpack_instantiate__(__webpack_async_dependencies__);" + `var [${promises.join( + ", " + )}] = __webpack_async_dependencies__.then ? (await __webpack_async_dependencies__)() : __webpack_async_dependencies__;`, + `${importsCompatCode}await ${instantiateCall};`, + "__webpack_async_result__();", + "} catch(e) { __webpack_async_result__(e); }" ] )}, 1);` - ]) + ]) : `${importsCode}${importsCompatCode}module.exports = ${instantiateCall};` ); diff --git a/lib/wasm-async/AsyncWebAssemblyModulesPlugin.js b/lib/wasm-async/AsyncWebAssemblyModulesPlugin.js index 5c26098e5bf..74a612757e9 100644 --- a/lib/wasm-async/AsyncWebAssemblyModulesPlugin.js +++ b/lib/wasm-async/AsyncWebAssemblyModulesPlugin.js @@ -9,11 +9,13 @@ const { SyncWaterfallHook } = require("tapable"); const Compilation = require("../Compilation"); const Generator = require("../Generator"); const { tryRunOrWebpackError } = require("../HookWebpackError"); +const { WEBASSEMBLY_MODULE_TYPE_ASYNC } = require("../ModuleTypeConstants"); const WebAssemblyImportDependency = require("../dependencies/WebAssemblyImportDependency"); const { compareModulesByIdentifier } = require("../util/comparators"); const memoize = require("../util/memoize"); /** @typedef {import("webpack-sources").Source} Source */ +/** @typedef {import("../../declarations/WebpackOptions").OutputNormalized} OutputOptions */ /** @typedef {import("../Chunk")} Chunk */ /** @typedef {import("../ChunkGraph")} ChunkGraph */ /** @typedef {import("../CodeGenerationResults")} CodeGenerationResults */ @@ -24,6 +26,7 @@ const memoize = require("../util/memoize"); /** @typedef {import("../RuntimeTemplate")} RuntimeTemplate */ /** @typedef {import("../Template").RenderManifestEntry} RenderManifestEntry */ /** @typedef {import("../Template").RenderManifestOptions} RenderManifestOptions */ +/** @typedef {import("../WebpackError")} WebpackError */ const getAsyncWebAssemblyGenerator = memoize(() => require("./AsyncWebAssemblyGenerator") @@ -36,7 +39,7 @@ const getAsyncWebAssemblyParser = memoize(() => ); /** - * @typedef {Object} RenderContext + * @typedef {object} WebAssemblyRenderContext * @property {Chunk} chunk the chunk * @property {DependencyTemplates} dependencyTemplates the dependency templates * @property {RuntimeTemplate} runtimeTemplate the runtime template @@ -46,13 +49,20 @@ const getAsyncWebAssemblyParser = memoize(() => */ /** - * @typedef {Object} CompilationHooks - * @property {SyncWaterfallHook<[Source, Module, RenderContext]>} renderModuleContent + * @typedef {object} CompilationHooks + * @property {SyncWaterfallHook<[Source, Module, WebAssemblyRenderContext]>} renderModuleContent + */ + +/** + * @typedef {object} AsyncWebAssemblyModulesPluginOptions + * @property {boolean} [mangleImports] mangle imports */ /** @type {WeakMap} */ const compilationHooksMap = new WeakMap(); +const PLUGIN_NAME = "AsyncWebAssemblyModulesPlugin"; + class AsyncWebAssemblyModulesPlugin { /** * @param {Compilation} compilation the compilation @@ -78,6 +88,9 @@ class AsyncWebAssemblyModulesPlugin { return hooks; } + /** + * @param {AsyncWebAssemblyModulesPluginOptions} options options + */ constructor(options) { this.options = options; } @@ -89,27 +102,27 @@ class AsyncWebAssemblyModulesPlugin { */ apply(compiler) { compiler.hooks.compilation.tap( - "AsyncWebAssemblyModulesPlugin", + PLUGIN_NAME, (compilation, { normalModuleFactory }) => { - const hooks = AsyncWebAssemblyModulesPlugin.getCompilationHooks( - compilation - ); + const hooks = + AsyncWebAssemblyModulesPlugin.getCompilationHooks(compilation); compilation.dependencyFactories.set( WebAssemblyImportDependency, normalModuleFactory ); normalModuleFactory.hooks.createParser - .for("webassembly/async") - .tap("AsyncWebAssemblyModulesPlugin", () => { + .for(WEBASSEMBLY_MODULE_TYPE_ASYNC) + .tap(PLUGIN_NAME, () => { const AsyncWebAssemblyParser = getAsyncWebAssemblyParser(); return new AsyncWebAssemblyParser(); }); normalModuleFactory.hooks.createGenerator - .for("webassembly/async") - .tap("AsyncWebAssemblyModulesPlugin", () => { - const AsyncWebAssemblyJavascriptGenerator = getAsyncWebAssemblyJavascriptGenerator(); + .for(WEBASSEMBLY_MODULE_TYPE_ASYNC) + .tap(PLUGIN_NAME, () => { + const AsyncWebAssemblyJavascriptGenerator = + getAsyncWebAssemblyJavascriptGenerator(); const AsyncWebAssemblyGenerator = getAsyncWebAssemblyGenerator(); return Generator.byType({ @@ -135,9 +148,10 @@ class AsyncWebAssemblyModulesPlugin { chunk, compareModulesByIdentifier )) { - if (module.type === "webassembly/async") { + if (module.type === WEBASSEMBLY_MODULE_TYPE_ASYNC) { const filenameTemplate = - outputOptions.webassemblyModuleFilename; + /** @type {NonNullable} */ + (outputOptions.webassemblyModuleFilename); result.push({ render: () => @@ -175,6 +189,12 @@ class AsyncWebAssemblyModulesPlugin { ); } + /** + * @param {Module} module the rendered module + * @param {WebAssemblyRenderContext} renderContext options object + * @param {CompilationHooks} hooks hooks + * @returns {Source} the newly generated source from rendering + */ renderModule(module, renderContext, hooks) { const { codeGenerationResults, chunk } = renderContext; try { @@ -188,9 +208,9 @@ class AsyncWebAssemblyModulesPlugin { hooks.renderModuleContent.call(moduleSource, module, renderContext), "AsyncWebAssemblyModulesPlugin.getCompilationHooks().renderModuleContent" ); - } catch (e) { - e.module = module; - throw e; + } catch (err) { + /** @type {WebpackError} */ (err).module = module; + throw err; } } } diff --git a/lib/wasm-async/AsyncWebAssemblyParser.js b/lib/wasm-async/AsyncWebAssemblyParser.js index e784ba71826..40f1c79eacc 100644 --- a/lib/wasm-async/AsyncWebAssemblyParser.js +++ b/lib/wasm-async/AsyncWebAssemblyParser.js @@ -7,10 +7,13 @@ const t = require("@webassemblyjs/ast"); const { decode } = require("@webassemblyjs/wasm-parser"); +const EnvironmentNotSupportAsyncWarning = require("../EnvironmentNotSupportAsyncWarning"); const Parser = require("../Parser"); const StaticExportsDependency = require("../dependencies/StaticExportsDependency"); const WebAssemblyImportDependency = require("../dependencies/WebAssemblyImportDependency"); +/** @typedef {import("../Module").BuildInfo} BuildInfo */ +/** @typedef {import("../Module").BuildMeta} BuildMeta */ /** @typedef {import("../Parser").ParserState} ParserState */ /** @typedef {import("../Parser").PreparsedAst} PreparsedAst */ @@ -23,6 +26,9 @@ const decoderOpts = { }; class WebAssemblyParser extends Parser { + /** + * @param {{}=} options parser options + */ constructor(options) { super(); this.hooks = Object.freeze({}); @@ -40,14 +46,21 @@ class WebAssemblyParser extends Parser { } // flag it as async module - state.module.buildInfo.strict = true; - state.module.buildMeta.exportsType = "namespace"; - state.module.buildMeta.async = true; + const buildInfo = /** @type {BuildInfo} */ (state.module.buildInfo); + buildInfo.strict = true; + const BuildMeta = /** @type {BuildMeta} */ (state.module.buildMeta); + BuildMeta.exportsType = "namespace"; + BuildMeta.async = true; + EnvironmentNotSupportAsyncWarning.check( + state.module, + state.compilation.runtimeTemplate, + "asyncWebAssembly" + ); // parse it const program = decode(source, decoderOpts); const module = program.body[0]; - + /** @type {Array} */ const exports = []; t.traverse(module, { ModuleExport({ node }) { diff --git a/lib/wasm-sync/UnsupportedWebAssemblyFeatureError.js b/lib/wasm-sync/UnsupportedWebAssemblyFeatureError.js index 9a4076aa70d..5174862ca5c 100644 --- a/lib/wasm-sync/UnsupportedWebAssemblyFeatureError.js +++ b/lib/wasm-sync/UnsupportedWebAssemblyFeatureError.js @@ -12,7 +12,5 @@ module.exports = class UnsupportedWebAssemblyFeatureError extends WebpackError { super(message); this.name = "UnsupportedWebAssemblyFeatureError"; this.hideStack = true; - - Error.captureStackTrace(this, this.constructor); } }; diff --git a/lib/wasm-sync/WasmChunkLoadingRuntimeModule.js b/lib/wasm-sync/WasmChunkLoadingRuntimeModule.js index f55f917f47c..654a6204f63 100644 --- a/lib/wasm-sync/WasmChunkLoadingRuntimeModule.js +++ b/lib/wasm-sync/WasmChunkLoadingRuntimeModule.js @@ -10,14 +10,25 @@ const Template = require("../Template"); const { compareModulesByIdentifier } = require("../util/comparators"); const WebAssemblyUtils = require("./WebAssemblyUtils"); +/** @typedef {import("@webassemblyjs/ast").Signature} Signature */ +/** @typedef {import("../Chunk")} Chunk */ /** @typedef {import("../ChunkGraph")} ChunkGraph */ +/** @typedef {import("../ChunkGraph").ModuleId} ModuleId */ /** @typedef {import("../Compilation")} Compilation */ /** @typedef {import("../Module")} Module */ +/** @typedef {import("../Module").ReadOnlyRuntimeRequirements} ReadOnlyRuntimeRequirements */ +/** @typedef {import("../ModuleGraph")} ModuleGraph */ /** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */ // TODO webpack 6 remove the whole folder // Get all wasm modules +/** + * @param {ModuleGraph} moduleGraph the module graph + * @param {ChunkGraph} chunkGraph the chunk graph + * @param {Chunk} chunk the chunk + * @returns {Module[]} all wasm modules + */ const getAllWasmModules = (moduleGraph, chunkGraph, chunk) => { const wasmModules = chunk.getAllAsyncChunks(); const array = []; @@ -39,7 +50,7 @@ const getAllWasmModules = (moduleGraph, chunkGraph, chunk) => { * generates the import object function for a module * @param {ChunkGraph} chunkGraph the chunk graph * @param {Module} module the module - * @param {boolean} mangle mangle imports + * @param {boolean | undefined} mangle mangle imports * @param {string[]} declarations array where declarations are pushed to * @param {RuntimeSpec} runtime the runtime * @returns {string} source code @@ -52,6 +63,7 @@ const generateImportObject = ( runtime ) => { const moduleGraph = chunkGraph.moduleGraph; + /** @type {Map} */ const waitForInstances = new Map(); const properties = []; const usedWasmDependencies = WebAssemblyUtils.getUsedDependencies( @@ -76,32 +88,42 @@ const generateImportObject = ( if (direct) { const instanceVar = `m${waitForInstances.size}`; - waitForInstances.set(instanceVar, chunkGraph.getModuleId(importedModule)); + waitForInstances.set( + instanceVar, + /** @type {ModuleId} */ + (chunkGraph.getModuleId(/** @type {Module} */ (importedModule))) + ); properties.push({ module, name, value: `${instanceVar}[${JSON.stringify(usedName)}]` }); } else { - const params = description.signature.params.map( - (param, k) => "p" + k + param.valtype - ); + const params = + /** @type {Signature} */ + (description.signature).params.map( + (param, k) => `p${k}${param.valtype}` + ); const mod = `${RuntimeGlobals.moduleCache}[${JSON.stringify( - chunkGraph.getModuleId(importedModule) + chunkGraph.getModuleId(/** @type {Module} */ (importedModule)) )}]`; const modExports = `${mod}.exports`; const cache = `wasmImportedFuncCache${declarations.length}`; declarations.push(`var ${cache};`); + const modCode = + /** @type {Module} */ + (importedModule).type.startsWith("webassembly") + ? `${mod} ? ${modExports}[${JSON.stringify(usedName)}] : ` + : ""; + properties.push({ module, name, value: Template.asString([ - (importedModule.type.startsWith("webassembly") - ? `${mod} ? ${modExports}[${JSON.stringify(usedName)}] : ` - : "") + `function(${params}) {`, + `${modCode}function(${params}) {`, Template.indent([ `if(${cache} === undefined) ${cache} = ${modExports};`, `return ${cache}[${JSON.stringify(usedName)}](${params});` @@ -122,6 +144,7 @@ const generateImportObject = ( "};" ]; } else { + /** @type {Map>} */ const propertiesByModule = new Map(); for (const p of properties) { let list = propertiesByModule.get(p.module); @@ -133,15 +156,15 @@ const generateImportObject = ( importObject = [ "return {", Template.indent([ - Array.from(propertiesByModule, ([module, list]) => { - return Template.asString([ + Array.from(propertiesByModule, ([module, list]) => + Template.asString([ `${JSON.stringify(module)}: {`, Template.indent([ list.map(p => `${JSON.stringify(p.name)}: ${p.value}`).join(",\n") ]), "}" - ]); - }).join(",\n") + ]) + ).join(",\n") ]), "};" ]; @@ -179,44 +202,71 @@ const generateImportObject = ( ]), "}," ]); - } else { - return Template.asString([ - `${moduleIdStringified}: function() {`, - Template.indent(importObject), - "}," - ]); } + return Template.asString([ + `${moduleIdStringified}: function() {`, + Template.indent(importObject), + "}," + ]); }; +/** + * @typedef {object} WasmChunkLoadingRuntimeModuleOptions + * @property {(path: string) => string} generateLoadBinaryCode + * @property {boolean} [supportsStreaming] + * @property {boolean} [mangleImports] + * @property {ReadOnlyRuntimeRequirements} runtimeRequirements + */ + class WasmChunkLoadingRuntimeModule extends RuntimeModule { - constructor({ generateLoadBinaryCode, supportsStreaming, mangleImports }) { + /** + * @param {WasmChunkLoadingRuntimeModuleOptions} options options + */ + constructor({ + generateLoadBinaryCode, + supportsStreaming, + mangleImports, + runtimeRequirements + }) { super("wasm chunk loading", RuntimeModule.STAGE_ATTACH); this.generateLoadBinaryCode = generateLoadBinaryCode; this.supportsStreaming = supportsStreaming; this.mangleImports = mangleImports; + this._runtimeRequirements = runtimeRequirements; } /** - * @returns {string} runtime code + * @returns {string | null} runtime code */ generate() { - const { compilation, chunk, mangleImports } = this; - const { chunkGraph, moduleGraph, outputOptions } = compilation; const fn = RuntimeGlobals.ensureChunkHandlers; + const withHmr = this._runtimeRequirements.has( + RuntimeGlobals.hmrDownloadUpdateHandlers + ); + const compilation = /** @type {Compilation} */ (this.compilation); + const { moduleGraph, outputOptions } = compilation; + const chunkGraph = /** @type {ChunkGraph} */ (this.chunkGraph); + const chunk = /** @type {Chunk} */ (this.chunk); const wasmModules = getAllWasmModules(moduleGraph, chunkGraph, chunk); + const { mangleImports } = this; + /** @type {string[]} */ const declarations = []; - const importObjects = wasmModules.map(module => { - return generateImportObject( + const importObjects = wasmModules.map(module => + generateImportObject( chunkGraph, module, - this.mangleImports, + mangleImports, declarations, chunk.runtime - ); - }); + ) + ); const chunkModuleIdMap = chunkGraph.getChunkModuleIdMap(chunk, m => m.type.startsWith("webassembly") ); + /** + * @param {string} content content + * @returns {string} created import object + */ const createImportObject = content => mangleImports ? `{ ${JSON.stringify(WebAssemblyUtils.MANGLED_MODULE)}: ${content} }` @@ -247,9 +297,16 @@ class WasmChunkLoadingRuntimeModule extends RuntimeModule { runtime: chunk.runtime } ); + + const stateExpression = withHmr + ? `${RuntimeGlobals.hmrRuntimeStatePrefix}_wasm` + : undefined; + return Template.asString([ "// object to store loaded and loading wasm modules", - "var installedWasmModules = {};", + `var installedWasmModules = ${ + stateExpression ? `${stateExpression} = ${stateExpression} || ` : "" + }{};`, "", // This function is used to delay reading the installed wasm module promises // by a microtask. Sorting them doesn't help because there are edge cases where @@ -275,7 +332,7 @@ class WasmChunkLoadingRuntimeModule extends RuntimeModule { `${fn}.wasm = function(chunkId, promises) {`, Template.indent([ "", - `var wasmModules = wasmModuleMap[chunkId] || [];`, + "var wasmModules = wasmModuleMap[chunkId] || [];", "", "wasmModules.forEach(function(wasmModuleId, idx) {", Template.indent([ @@ -286,12 +343,12 @@ class WasmChunkLoadingRuntimeModule extends RuntimeModule { Template.indent(["promises.push(installedWasmModuleData);"]), "else {", Template.indent([ - `var importObject = wasmImportObjects[wasmModuleId]();`, + "var importObject = wasmImportObjects[wasmModuleId]();", `var req = ${this.generateLoadBinaryCode(wasmModuleSrcPath)};`, "var promise;", this.supportsStreaming ? Template.asString([ - "if(importObject instanceof Promise && typeof WebAssembly.compileStreaming === 'function') {", + "if(importObject && typeof importObject.then === 'function' && typeof WebAssembly.compileStreaming === 'function') {", Template.indent([ "promise = Promise.all([WebAssembly.compileStreaming(req), importObject]).then(function(items) {", Template.indent([ @@ -307,9 +364,9 @@ class WasmChunkLoadingRuntimeModule extends RuntimeModule { "importObject" )});` ]) - ]) + ]) : Template.asString([ - "if(importObject instanceof Promise) {", + "if(importObject && typeof importObject.then === 'function') {", Template.indent([ "var bytesPromise = req.then(function(x) { return x.arrayBuffer(); });", "promise = Promise.all([", @@ -325,7 +382,7 @@ class WasmChunkLoadingRuntimeModule extends RuntimeModule { ]), "});" ]) - ]), + ]), "} else {", Template.indent([ "var bytesPromise = req.then(function(x) { return x.arrayBuffer(); });", diff --git a/lib/wasm-sync/WasmFinalizeExportsPlugin.js b/lib/wasm-sync/WasmFinalizeExportsPlugin.js index 540edf8fb1a..7e5668798be 100644 --- a/lib/wasm-sync/WasmFinalizeExportsPlugin.js +++ b/lib/wasm-sync/WasmFinalizeExportsPlugin.js @@ -9,6 +9,9 @@ const formatLocation = require("../formatLocation"); const UnsupportedWebAssemblyFeatureError = require("./UnsupportedWebAssemblyFeatureError"); /** @typedef {import("../Compiler")} Compiler */ +/** @typedef {import("../Dependency")} Dependency */ +/** @typedef {import("../Module")} Module */ +/** @typedef {import("../Module").BuildMeta} BuildMeta */ class WasmFinalizeExportsPlugin { /** @@ -25,7 +28,8 @@ class WasmFinalizeExportsPlugin { // 1. if a WebAssembly module if (module.type.startsWith("webassembly") === true) { const jsIncompatibleExports = - module.buildMeta.jsIncompatibleExports; + /** @type {BuildMeta} */ + (module.buildMeta).jsIncompatibleExports; if (jsIncompatibleExports === undefined) { continue; @@ -37,13 +41,15 @@ class WasmFinalizeExportsPlugin { // 2. is active and referenced by a non-WebAssembly module if ( connection.isTargetActive(undefined) && - connection.originModule.type.startsWith("webassembly") === + /** @type {Module} */ + (connection.originModule).type.startsWith("webassembly") === false ) { - const referencedExports = compilation.getDependencyReferencedExports( - connection.dependency, - undefined - ); + const referencedExports = + compilation.getDependencyReferencedExports( + /** @type {Dependency} */ (connection.dependency), + undefined + ); for (const info of referencedExports) { const names = Array.isArray(info) ? info : info.name; @@ -60,9 +66,15 @@ class WasmFinalizeExportsPlugin { // 4. error const error = new UnsupportedWebAssemblyFeatureError( `Export "${name}" with ${jsIncompatibleExports[name]} can only be used for direct wasm to wasm dependencies\n` + - `It's used from ${connection.originModule.readableIdentifier( - compilation.requestShortener - )} at ${formatLocation(connection.dependency.loc)}.` + `It's used from ${ + /** @type {Module} */ + (connection.originModule).readableIdentifier( + compilation.requestShortener + ) + } at ${formatLocation( + /** @type {Dependency} */ (connection.dependency) + .loc + )}.` ); error.module = module; compilation.errors.push(error); diff --git a/lib/wasm-sync/WebAssemblyGenerator.js b/lib/wasm-sync/WebAssemblyGenerator.js index 5f5c33185fb..dee5a2b14a6 100644 --- a/lib/wasm-sync/WebAssemblyGenerator.js +++ b/lib/wasm-sync/WebAssemblyGenerator.js @@ -25,46 +25,50 @@ const WebAssemblyExportImportedDependency = require("../dependencies/WebAssembly /** @typedef {import("../RuntimeTemplate")} RuntimeTemplate */ /** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */ /** @typedef {import("./WebAssemblyUtils").UsedWasmDependency} UsedWasmDependency */ +/** @typedef {import("@webassemblyjs/ast").Instruction} Instruction */ +/** @typedef {import("@webassemblyjs/ast").ModuleImport} ModuleImport */ +/** @typedef {import("@webassemblyjs/ast").ModuleExport} ModuleExport */ +/** @typedef {import("@webassemblyjs/ast").Global} Global */ +/** + * @template T + * @typedef {import("@webassemblyjs/ast").NodePath} NodePath + */ /** - * @typedef {(ArrayBuffer) => ArrayBuffer} ArrayBufferTransform + * @typedef {(buf: ArrayBuffer) => ArrayBuffer} ArrayBufferTransform */ /** * @template T - * @param {Function[]} fns transforms + * @param {((prev: ArrayBuffer) => ArrayBuffer)[]} fns transforms * @returns {Function} composed transform */ -const compose = (...fns) => { - return fns.reduce( - (prevFn, nextFn) => { - return value => nextFn(prevFn(value)); - }, +const compose = (...fns) => + fns.reduce( + (prevFn, nextFn) => value => nextFn(prevFn(value)), value => value ); -}; /** * Removes the start instruction - * - * @param {Object} state unused state + * @param {object} state state + * @param {object} state.ast Module's ast * @returns {ArrayBufferTransform} transform */ -const removeStartFunc = state => bin => { - return editWithAST(state.ast, bin, { +const removeStartFunc = state => bin => + editWithAST(state.ast, bin, { Start(path) { path.remove(); } }); -}; /** * Get imported globals - * - * @param {Object} ast Module's AST - * @returns {Array} - nodes + * @param {object} ast Module's AST + * @returns {t.ModuleImport[]} - nodes */ const getImportedGlobals = ast => { + /** @type {t.ModuleImport[]} */ const importedGlobals = []; t.traverse(ast, { @@ -80,9 +84,8 @@ const getImportedGlobals = ast => { /** * Get the count for imported func - * - * @param {Object} ast Module's AST - * @returns {Number} - count + * @param {object} ast Module's AST + * @returns {number} - count */ const getCountImportedFunc = ast => { let count = 0; @@ -100,8 +103,7 @@ const getCountImportedFunc = ast => { /** * Get next type index - * - * @param {Object} ast Module's AST + * @param {object} ast Module's AST * @returns {t.Index} - index */ const getNextTypeIndex = ast => { @@ -116,13 +118,11 @@ const getNextTypeIndex = ast => { /** * Get next func index - * - * The Func section metadata provide informations for implemented funcs + * The Func section metadata provide information for implemented funcs * in order to have the correct index we shift the index by number of external * functions. - * - * @param {Object} ast Module's AST - * @param {Number} countImportedFunc number of imported funcs + * @param {object} ast Module's AST + * @param {number} countImportedFunc number of imported funcs * @returns {t.Index} - index */ const getNextFuncIndex = (ast, countImportedFunc) => { @@ -153,9 +153,8 @@ const createDefaultInitForGlobal = globalType => { return t.objectInstruction("const", globalType.valtype, [ t.floatLiteral(66, false, false, "66") ]); - } else { - throw new Error("unknown type: " + globalType.valtype); } + throw new Error(`unknown type: ${globalType.valtype}`); }; /** @@ -167,18 +166,20 @@ const createDefaultInitForGlobal = globalType => { * indices will be preserved. * * Note that globals will become mutable. - * - * @param {Object} state unused state + * @param {object} state transformation state + * @param {object} state.ast Module's ast + * @param {t.Instruction[]} state.additionalInitCode list of addition instructions for the init function * @returns {ArrayBufferTransform} transform */ const rewriteImportedGlobals = state => bin => { const additionalInitCode = state.additionalInitCode; + /** @type {Array} */ const newGlobals = []; bin = editWithAST(state.ast, bin, { ModuleImport(path) { if (t.isGlobalType(path.node.descr)) { - const globalType = path.node.descr; + const globalType = /** @type {TODO} */ (path.node.descr); globalType.mutability = "var"; @@ -195,6 +196,9 @@ const rewriteImportedGlobals = state => bin => { // in order to preserve non-imported global's order we need to re-inject // those as well + /** + * @param {NodePath} path path + */ Global(path) { const { node } = path; const [init] = node.init; @@ -232,69 +236,70 @@ const rewriteImportedGlobals = state => bin => { /** * Rewrite the export names - * @param {Object} state state - * @param {Object} state.ast Module's ast + * @param {object} state state + * @param {object} state.ast Module's ast * @param {Module} state.module Module * @param {ModuleGraph} state.moduleGraph module graph * @param {Set} state.externalExports Module * @param {RuntimeSpec} state.runtime runtime * @returns {ArrayBufferTransform} transform */ -const rewriteExportNames = ({ - ast, - moduleGraph, - module, - externalExports, - runtime -}) => bin => { - return editWithAST(ast, bin, { - ModuleExport(path) { - const isExternal = externalExports.has(path.node.name); - if (isExternal) { - path.remove(); - return; - } - const usedName = moduleGraph - .getExportsInfo(module) - .getUsedName(path.node.name, runtime); - if (!usedName) { - path.remove(); - return; +const rewriteExportNames = + ({ ast, moduleGraph, module, externalExports, runtime }) => + bin => + editWithAST(ast, bin, { + /** + * @param {NodePath} path path + */ + ModuleExport(path) { + const isExternal = externalExports.has(path.node.name); + if (isExternal) { + path.remove(); + return; + } + const usedName = moduleGraph + .getExportsInfo(module) + .getUsedName(path.node.name, runtime); + if (!usedName) { + path.remove(); + return; + } + path.node.name = /** @type {string} */ (usedName); } - path.node.name = usedName; - } - }); -}; + }); /** * Mangle import names and modules - * @param {Object} state state - * @param {Object} state.ast Module's ast + * @param {object} state state + * @param {object} state.ast Module's ast * @param {Map} state.usedDependencyMap mappings to mangle names * @returns {ArrayBufferTransform} transform */ -const rewriteImports = ({ ast, usedDependencyMap }) => bin => { - return editWithAST(ast, bin, { - ModuleImport(path) { - const result = usedDependencyMap.get( - path.node.module + ":" + path.node.name - ); +const rewriteImports = + ({ ast, usedDependencyMap }) => + bin => + editWithAST(ast, bin, { + /** + * @param {NodePath} path path + */ + ModuleImport(path) { + const result = usedDependencyMap.get( + `${path.node.module}:${path.node.name}` + ); - if (result !== undefined) { - path.node.module = result.module; - path.node.name = result.name; + if (result !== undefined) { + path.node.module = result.module; + path.node.name = result.name; + } } - } - }); -}; + }); /** * Add an init function. * * The init function fills the globals given input arguments. - * - * @param {Object} state transformation state - * @param {Object} state.ast Module's ast + * @param {object} state transformation state + * @param {object} state.ast Module's ast * @param {t.Identifier} state.initFuncId identifier of the init function * @param {t.Index} state.startAtFuncOffset index of the start function * @param {t.ModuleImport[]} state.importedGlobals list of imported globals @@ -303,69 +308,80 @@ const rewriteImports = ({ ast, usedDependencyMap }) => bin => { * @param {t.Index} state.nextTypeIndex index of the next type * @returns {ArrayBufferTransform} transform */ -const addInitFunction = ({ - ast, - initFuncId, - startAtFuncOffset, - importedGlobals, - additionalInitCode, - nextFuncIndex, - nextTypeIndex -}) => bin => { - const funcParams = importedGlobals.map(importedGlobal => { - // used for debugging - const id = t.identifier(`${importedGlobal.module}.${importedGlobal.name}`); - - return t.funcParam(importedGlobal.descr.valtype, id); - }); +const addInitFunction = + ({ + ast, + initFuncId, + startAtFuncOffset, + importedGlobals, + additionalInitCode, + nextFuncIndex, + nextTypeIndex + }) => + bin => { + const funcParams = importedGlobals.map(importedGlobal => { + // used for debugging + const id = t.identifier( + `${importedGlobal.module}.${importedGlobal.name}` + ); - const funcBody = []; - importedGlobals.forEach((importedGlobal, index) => { - const args = [t.indexLiteral(index)]; - const body = [ - t.instruction("get_local", args), - t.instruction("set_global", args) - ]; + return t.funcParam( + /** @type {string} */ (importedGlobal.descr.valtype), + id + ); + }); - funcBody.push(...body); - }); + /** @type {Instruction[]} */ + const funcBody = []; + for (const [index, _importedGlobal] of importedGlobals.entries()) { + const args = [t.indexLiteral(index)]; + const body = [ + t.instruction("get_local", args), + t.instruction("set_global", args) + ]; - if (typeof startAtFuncOffset === "number") { - funcBody.push(t.callInstruction(t.numberLiteralFromRaw(startAtFuncOffset))); - } + funcBody.push(...body); + } - for (const instr of additionalInitCode) { - funcBody.push(instr); - } + if (typeof startAtFuncOffset === "number") { + funcBody.push( + t.callInstruction(t.numberLiteralFromRaw(startAtFuncOffset)) + ); + } - funcBody.push(t.instruction("end")); + for (const instr of additionalInitCode) { + funcBody.push(instr); + } - const funcResults = []; + funcBody.push(t.instruction("end")); - // Code section - const funcSignature = t.signature(funcParams, funcResults); - const func = t.func(initFuncId, funcSignature, funcBody); + /** @type {string[]} */ + const funcResults = []; - // Type section - const functype = t.typeInstruction(undefined, funcSignature); + // Code section + const funcSignature = t.signature(funcParams, funcResults); + const func = t.func(initFuncId, funcSignature, funcBody); - // Func section - const funcindex = t.indexInFuncSection(nextTypeIndex); + // Type section + const functype = t.typeInstruction(undefined, funcSignature); - // Export section - const moduleExport = t.moduleExport( - initFuncId.value, - t.moduleExportDescr("Func", nextFuncIndex) - ); + // Func section + const funcindex = t.indexInFuncSection(nextTypeIndex); - return addWithAST(ast, bin, [func, moduleExport, funcindex, functype]); -}; + // Export section + const moduleExport = t.moduleExport( + initFuncId.value, + t.moduleExportDescr("Func", nextFuncIndex) + ); + + return addWithAST(ast, bin, [func, moduleExport, funcindex, functype]); + }; /** * Extract mangle mappings from module * @param {ModuleGraph} moduleGraph module graph * @param {Module} module current module - * @param {boolean} mangle mangle imports + * @param {boolean | undefined} mangle mangle imports * @returns {Map} mappings to mangled names */ const getUsedDependencyMap = (moduleGraph, module, mangle) => { @@ -379,14 +395,22 @@ const getUsedDependencyMap = (moduleGraph, module, mangle) => { const dep = usedDep.dependency; const request = dep.request; const exportName = dep.name; - map.set(request + ":" + exportName, usedDep); + map.set(`${request}:${exportName}`, usedDep); } return map; }; const TYPES = new Set(["webassembly"]); +/** + * @typedef {object} WebAssemblyGeneratorOptions + * @property {boolean} [mangleImports] mangle imports + */ + class WebAssemblyGenerator extends Generator { + /** + * @param {WebAssemblyGeneratorOptions} options options + */ constructor(options) { super(); this.options = options; @@ -419,7 +443,7 @@ class WebAssemblyGenerator extends Generator { * @returns {Source} generated code */ generate(module, { moduleGraph, runtime }) { - const bin = module.originalSource().source(); + const bin = /** @type {Source} */ (module.originalSource()).source(); const initFuncId = t.identifier(""); @@ -447,7 +471,9 @@ class WebAssemblyGenerator extends Generator { module.dependencies .filter(d => d instanceof WebAssemblyExportImportedDependency) .map(d => { - const wasmDep = /** @type {WebAssemblyExportImportedDependency} */ (d); + const wasmDep = /** @type {WebAssemblyExportImportedDependency} */ ( + d + ); return wasmDep.exportName; }) ); diff --git a/lib/wasm-sync/WebAssemblyInInitialChunkError.js b/lib/wasm-sync/WebAssemblyInInitialChunkError.js index 106b5dfb16c..9d78ed205f4 100644 --- a/lib/wasm-sync/WebAssemblyInInitialChunkError.js +++ b/lib/wasm-sync/WebAssemblyInInitialChunkError.js @@ -102,7 +102,5 @@ ${moduleChains.map(s => `* ${s}`).join("\n")}`; this.name = "WebAssemblyInInitialChunkError"; this.hideStack = true; this.module = module; - - Error.captureStackTrace(this, this.constructor); } }; diff --git a/lib/wasm-sync/WebAssemblyJavascriptGenerator.js b/lib/wasm-sync/WebAssemblyJavascriptGenerator.js index 9fa2b2f7f53..e5d53f86068 100644 --- a/lib/wasm-sync/WebAssemblyJavascriptGenerator.js +++ b/lib/wasm-sync/WebAssemblyJavascriptGenerator.js @@ -19,6 +19,7 @@ const WebAssemblyImportDependency = require("../dependencies/WebAssemblyImportDe /** @typedef {import("../Dependency")} Dependency */ /** @typedef {import("../DependencyTemplates")} DependencyTemplates */ /** @typedef {import("../Generator").GenerateContext} GenerateContext */ +/** @typedef {import("../Module")} Module */ /** @typedef {import("../NormalModule")} NormalModule */ /** @typedef {import("../RuntimeTemplate")} RuntimeTemplate */ @@ -55,7 +56,7 @@ class WebAssemblyJavascriptGenerator extends Generator { runtimeRequirements, runtime } = generateContext; - /** @type {InitFragment[]} */ + /** @type {InitFragment>[]} */ const initFragments = []; const exportsInfo = moduleGraph.getExportsInfo(module); @@ -127,7 +128,7 @@ class WebAssemblyJavascriptGenerator extends Generator { const defineStatement = Template.asString([ `${exportProp} = ${runtimeTemplate.exportFromImport({ moduleGraph, - module: moduleGraph.getModule(dep), + module: /** @type {Module} */ (moduleGraph.getModule(dep)), request: dep.request, importVar: importData.importVar, originModule: module, @@ -200,8 +201,8 @@ class WebAssemblyJavascriptGenerator extends Generator { copyAllExports ? `${module.moduleArgument}.exports = wasmExports;` : "for(var name in wasmExports) " + - `if(name) ` + - `${module.exportsArgument}[name] = wasmExports[name];`, + "if(name) " + + `${module.exportsArgument}[name] = wasmExports[name];`, "// exec imports from WebAssembly module (for esm order)", importsCode, "", diff --git a/lib/wasm-sync/WebAssemblyModulesPlugin.js b/lib/wasm-sync/WebAssemblyModulesPlugin.js index 76d71e8f434..dc3ff32ef5f 100644 --- a/lib/wasm-sync/WebAssemblyModulesPlugin.js +++ b/lib/wasm-sync/WebAssemblyModulesPlugin.js @@ -6,6 +6,7 @@ "use strict"; const Generator = require("../Generator"); +const { WEBASSEMBLY_MODULE_TYPE_SYNC } = require("../ModuleTypeConstants"); const WebAssemblyExportImportedDependency = require("../dependencies/WebAssemblyExportImportedDependency"); const WebAssemblyImportDependency = require("../dependencies/WebAssemblyImportDependency"); const { compareModulesByIdentifier } = require("../util/comparators"); @@ -13,10 +14,11 @@ const memoize = require("../util/memoize"); const WebAssemblyInInitialChunkError = require("./WebAssemblyInInitialChunkError"); /** @typedef {import("webpack-sources").Source} Source */ +/** @typedef {import("../../declarations/WebpackOptions").OutputNormalized} OutputOptions */ /** @typedef {import("../Compiler")} Compiler */ /** @typedef {import("../Module")} Module */ /** @typedef {import("../ModuleTemplate")} ModuleTemplate */ -/** @typedef {import("../ModuleTemplate").RenderContext} RenderContext */ +/** @typedef {import("../javascript/JavascriptModulesPlugin").RenderContext} RenderContext */ const getWebAssemblyGenerator = memoize(() => require("./WebAssemblyGenerator") @@ -26,7 +28,17 @@ const getWebAssemblyJavascriptGenerator = memoize(() => ); const getWebAssemblyParser = memoize(() => require("./WebAssemblyParser")); +const PLUGIN_NAME = "WebAssemblyModulesPlugin"; + +/** + * @typedef {object} WebAssemblyModulesPluginOptions + * @property {boolean} [mangleImports] mangle imports + */ + class WebAssemblyModulesPlugin { + /** + * @param {WebAssemblyModulesPluginOptions} options options + */ constructor(options) { this.options = options; } @@ -38,7 +50,7 @@ class WebAssemblyModulesPlugin { */ apply(compiler) { compiler.hooks.compilation.tap( - "WebAssemblyModulesPlugin", + PLUGIN_NAME, (compilation, { normalModuleFactory }) => { compilation.dependencyFactories.set( WebAssemblyImportDependency, @@ -51,17 +63,18 @@ class WebAssemblyModulesPlugin { ); normalModuleFactory.hooks.createParser - .for("webassembly/sync") - .tap("WebAssemblyModulesPlugin", () => { + .for(WEBASSEMBLY_MODULE_TYPE_SYNC) + .tap(PLUGIN_NAME, () => { const WebAssemblyParser = getWebAssemblyParser(); return new WebAssemblyParser(); }); normalModuleFactory.hooks.createGenerator - .for("webassembly/sync") - .tap("WebAssemblyModulesPlugin", () => { - const WebAssemblyJavascriptGenerator = getWebAssemblyJavascriptGenerator(); + .for(WEBASSEMBLY_MODULE_TYPE_SYNC) + .tap(PLUGIN_NAME, () => { + const WebAssemblyJavascriptGenerator = + getWebAssemblyJavascriptGenerator(); const WebAssemblyGenerator = getWebAssemblyGenerator(); return Generator.byType({ @@ -70,53 +83,51 @@ class WebAssemblyModulesPlugin { }); }); - compilation.hooks.renderManifest.tap( - "WebAssemblyModulesPlugin", - (result, options) => { - const { chunkGraph } = compilation; - const { chunk, outputOptions, codeGenerationResults } = options; - - for (const module of chunkGraph.getOrderedChunkModulesIterable( - chunk, - compareModulesByIdentifier - )) { - if (module.type === "webassembly/sync") { - const filenameTemplate = - outputOptions.webassemblyModuleFilename; - - result.push({ - render: () => - codeGenerationResults.getSource( - module, - chunk.runtime, - "webassembly" - ), - filenameTemplate, - pathOptions: { + compilation.hooks.renderManifest.tap(PLUGIN_NAME, (result, options) => { + const { chunkGraph } = compilation; + const { chunk, outputOptions, codeGenerationResults } = options; + + for (const module of chunkGraph.getOrderedChunkModulesIterable( + chunk, + compareModulesByIdentifier + )) { + if (module.type === WEBASSEMBLY_MODULE_TYPE_SYNC) { + const filenameTemplate = + /** @type {NonNullable} */ + (outputOptions.webassemblyModuleFilename); + + result.push({ + render: () => + codeGenerationResults.getSource( module, - runtime: chunk.runtime, - chunkGraph - }, - auxiliary: true, - identifier: `webassemblyModule${chunkGraph.getModuleId( - module - )}`, - hash: chunkGraph.getModuleHash(module, chunk.runtime) - }); - } + chunk.runtime, + "webassembly" + ), + filenameTemplate, + pathOptions: { + module, + runtime: chunk.runtime, + chunkGraph + }, + auxiliary: true, + identifier: `webassemblyModule${chunkGraph.getModuleId( + module + )}`, + hash: chunkGraph.getModuleHash(module, chunk.runtime) + }); } - - return result; } - ); - compilation.hooks.afterChunks.tap("WebAssemblyModulesPlugin", () => { + return result; + }); + + compilation.hooks.afterChunks.tap(PLUGIN_NAME, () => { const chunkGraph = compilation.chunkGraph; const initialWasmModules = new Set(); for (const chunk of compilation.chunks) { if (chunk.canBeInitial()) { for (const module of chunkGraph.getChunkModulesIterable(chunk)) { - if (module.type === "webassembly/sync") { + if (module.type === WEBASSEMBLY_MODULE_TYPE_SYNC) { initialWasmModules.add(module); } } diff --git a/lib/wasm-sync/WebAssemblyParser.js b/lib/wasm-sync/WebAssemblyParser.js index f4df7217ce3..b7dc394ec65 100644 --- a/lib/wasm-sync/WebAssemblyParser.js +++ b/lib/wasm-sync/WebAssemblyParser.js @@ -14,10 +14,12 @@ const WebAssemblyExportImportedDependency = require("../dependencies/WebAssembly const WebAssemblyImportDependency = require("../dependencies/WebAssemblyImportDependency"); /** @typedef {import("../Module")} Module */ +/** @typedef {import("../Module").BuildInfo} BuildInfo */ +/** @typedef {import("../Module").BuildMeta} BuildMeta */ /** @typedef {import("../Parser").ParserState} ParserState */ /** @typedef {import("../Parser").PreparsedAst} PreparsedAst */ -const JS_COMPAT_TYPES = new Set(["i32", "f32", "f64"]); +const JS_COMPAT_TYPES = new Set(["i32", "i64", "f32", "f64"]); /** * @param {t.Signature} signature the func signature @@ -61,6 +63,9 @@ const decoderOpts = { }; class WebAssemblyParser extends Parser { + /** + * @param {{}=} options parser options + */ constructor(options) { super(); this.hooks = Object.freeze({}); @@ -78,8 +83,10 @@ class WebAssemblyParser extends Parser { } // flag it as ESM - state.module.buildInfo.strict = true; - state.module.buildMeta.exportsType = "namespace"; + /** @type {BuildInfo} */ + (state.module.buildInfo).strict = true; + /** @type {BuildMeta} */ + (state.module.buildMeta).exportsType = "namespace"; // parse it const program = decode(source, decoderOpts); @@ -88,9 +95,13 @@ class WebAssemblyParser extends Parser { const moduleContext = moduleContextFromModuleAST(module); // extract imports and exports + /** @type {string[]} */ const exports = []; - let jsIncompatibleExports = (state.module.buildMeta.jsIncompatibleExports = undefined); + const buildMeta = /** @type {BuildMeta} */ (state.module.buildMeta); + /** @type {Record | undefined} */ + let jsIncompatibleExports = (buildMeta.jsIncompatibleExports = undefined); + /** @type {TODO[]} */ const importedGlobals = []; t.traverse(module, { ModuleExport({ node }) { @@ -102,13 +113,14 @@ class WebAssemblyParser extends Parser { /** @type {t.FuncSignature} */ const funcSignature = moduleContext.getFunction(funcIdx); - const incompatibleType = getJsIncompatibleTypeOfFuncSignature( - funcSignature - ); + const incompatibleType = + getJsIncompatibleTypeOfFuncSignature(funcSignature); if (incompatibleType) { if (jsIncompatibleExports === undefined) { - jsIncompatibleExports = state.module.buildMeta.jsIncompatibleExports = {}; + jsIncompatibleExports = + /** @type {BuildMeta} */ + (state.module.buildMeta).jsIncompatibleExports = {}; } jsIncompatibleExports[node.name] = incompatibleType; } @@ -117,7 +129,8 @@ class WebAssemblyParser extends Parser { exports.push(node.name); if (node.descr && node.descr.exportType === "Global") { - const refNode = importedGlobals[node.descr.id.value]; + const refNode = + importedGlobals[/** @type {TODO} */ (node.descr.id.value)]; if (refNode) { const dep = new WebAssemblyExportImportedDependency( node.name, @@ -156,12 +169,14 @@ class WebAssemblyParser extends Parser { } else if (t.isTable(node.descr) === true) { onlyDirectImport = "Table"; } else if (t.isFuncImportDescr(node.descr) === true) { - const incompatibleType = getJsIncompatibleType(node.descr.signature); + const incompatibleType = getJsIncompatibleType( + /** @type {t.Signature} */ (node.descr.signature) + ); if (incompatibleType) { onlyDirectImport = `Non-JS-compatible Func Signature (${incompatibleType})`; } } else if (t.isGlobalType(node.descr) === true) { - const type = node.descr.valtype; + const type = /** @type {string} */ (node.descr.valtype); if (!JS_COMPAT_TYPES.has(type)) { onlyDirectImport = `Non-JS-compatible Global Type (${type})`; } diff --git a/lib/wasm-sync/WebAssemblyUtils.js b/lib/wasm-sync/WebAssemblyUtils.js index fd00b2fd485..a67f3557268 100644 --- a/lib/wasm-sync/WebAssemblyUtils.js +++ b/lib/wasm-sync/WebAssemblyUtils.js @@ -11,7 +11,8 @@ const WebAssemblyImportDependency = require("../dependencies/WebAssemblyImportDe /** @typedef {import("../Module")} Module */ /** @typedef {import("../ModuleGraph")} ModuleGraph */ -/** @typedef {Object} UsedWasmDependency +/** + * @typedef {object} UsedWasmDependency * @property {WebAssemblyImportDependency} dependency the dependency * @property {string} name the export name * @property {string} module the module name @@ -22,7 +23,7 @@ const MANGLED_MODULE = "a"; /** * @param {ModuleGraph} moduleGraph the module graph * @param {Module} module the module - * @param {boolean} mangle mangle module and export names + * @param {boolean | undefined} mangle mangle module and export names * @returns {UsedWasmDependency[]} used dependencies and (mangled) name */ const getUsedDependencies = (moduleGraph, module, mangle) => { @@ -61,5 +62,5 @@ const getUsedDependencies = (moduleGraph, module, mangle) => { return array; }; -exports.getUsedDependencies = getUsedDependencies; -exports.MANGLED_MODULE = MANGLED_MODULE; +module.exports.getUsedDependencies = getUsedDependencies; +module.exports.MANGLED_MODULE = MANGLED_MODULE; diff --git a/lib/wasm/EnableWasmLoadingPlugin.js b/lib/wasm/EnableWasmLoadingPlugin.js index 19105a8da37..fc83d9f06b7 100644 --- a/lib/wasm/EnableWasmLoadingPlugin.js +++ b/lib/wasm/EnableWasmLoadingPlugin.js @@ -12,6 +12,10 @@ /** @type {WeakMap>} */ const enabledTypes = new WeakMap(); +/** + * @param {Compiler} compiler compiler instance + * @returns {Set} enabled types + */ const getEnabledTypes = compiler => { let set = enabledTypes.get(compiler); if (set === undefined) { @@ -48,10 +52,11 @@ class EnableWasmLoadingPlugin { throw new Error( `Library type "${type}" is not enabled. ` + "EnableWasmLoadingPlugin need to be used to enable this type of wasm loading. " + - 'This usually happens through the "output.enabledWasmLoadingTypes" option. ' + - 'If you are using a function as entry which sets "wasmLoading", you need to add all potential library types to "output.enabledWasmLoadingTypes". ' + - "These types are enabled: " + - Array.from(getEnabledTypes(compiler)).join(", ") + `This usually happens through the "output.enabledWasmLoadingTypes" option. ` + + `If you are using a function as entry which sets "wasmLoading", you need to add all potential library types to "output.enabledWasmLoadingTypes". ` + + `These types are enabled: ${Array.from( + getEnabledTypes(compiler) + ).join(", ")}` ); } } @@ -84,11 +89,20 @@ class EnableWasmLoadingPlugin { case "async-node": { // TODO webpack 6 remove ReadFileCompileWasmPlugin const ReadFileCompileWasmPlugin = require("../node/ReadFileCompileWasmPlugin"); + // @ts-expect-error typescript bug for duplicate require const ReadFileCompileAsyncWasmPlugin = require("../node/ReadFileCompileAsyncWasmPlugin"); new ReadFileCompileWasmPlugin({ mangleImports: compiler.options.optimization.mangleWasmImports }).apply(compiler); - new ReadFileCompileAsyncWasmPlugin().apply(compiler); + new ReadFileCompileAsyncWasmPlugin({ type }).apply(compiler); + break; + } + case "async-node-module": { + // @ts-expect-error typescript bug for duplicate require + const ReadFileCompileAsyncWasmPlugin = require("../node/ReadFileCompileAsyncWasmPlugin"); + new ReadFileCompileAsyncWasmPlugin({ type, import: true }).apply( + compiler + ); break; } case "universal": diff --git a/lib/web/FetchCompileAsyncWasmPlugin.js b/lib/web/FetchCompileAsyncWasmPlugin.js index 63889fa4b48..94aafc02468 100644 --- a/lib/web/FetchCompileAsyncWasmPlugin.js +++ b/lib/web/FetchCompileAsyncWasmPlugin.js @@ -5,9 +5,11 @@ "use strict"; +const { WEBASSEMBLY_MODULE_TYPE_ASYNC } = require("../ModuleTypeConstants"); const RuntimeGlobals = require("../RuntimeGlobals"); -const AsyncWasmChunkLoadingRuntimeModule = require("../wasm-async/AsyncWasmChunkLoadingRuntimeModule"); +const AsyncWasmLoadingRuntimeModule = require("../wasm-async/AsyncWasmLoadingRuntimeModule"); +/** @typedef {import("../Chunk")} Chunk */ /** @typedef {import("../Compiler")} Compiler */ class FetchCompileAsyncWasmPlugin { @@ -21,12 +23,22 @@ class FetchCompileAsyncWasmPlugin { "FetchCompileAsyncWasmPlugin", compilation => { const globalWasmLoading = compilation.outputOptions.wasmLoading; + /** + * @param {Chunk} chunk chunk + * @returns {boolean} true, if wasm loading is enabled for the chunk + */ const isEnabledForChunk = chunk => { const options = chunk.getEntryOptions(); const wasmLoading = - (options && options.wasmLoading) || globalWasmLoading; + options && options.wasmLoading !== undefined + ? options.wasmLoading + : globalWasmLoading; return wasmLoading === "fetch"; }; + /** + * @param {string} path path to the wasm file + * @returns {string} code to load the wasm file + */ const generateLoadBinaryCode = path => `fetch(${RuntimeGlobals.publicPath} + ${path})`; @@ -38,7 +50,7 @@ class FetchCompileAsyncWasmPlugin { if ( !chunkGraph.hasModuleInGraph( chunk, - m => m.type === "webassembly/async" + m => m.type === WEBASSEMBLY_MODULE_TYPE_ASYNC ) ) { return; @@ -46,7 +58,7 @@ class FetchCompileAsyncWasmPlugin { set.add(RuntimeGlobals.publicPath); compilation.addRuntimeModule( chunk, - new AsyncWasmChunkLoadingRuntimeModule({ + new AsyncWasmLoadingRuntimeModule({ generateLoadBinaryCode, supportsStreaming: true }) diff --git a/lib/web/FetchCompileWasmPlugin.js b/lib/web/FetchCompileWasmPlugin.js index 9bcb1276d03..8acb9a71186 100644 --- a/lib/web/FetchCompileWasmPlugin.js +++ b/lib/web/FetchCompileWasmPlugin.js @@ -5,16 +5,28 @@ "use strict"; +const { WEBASSEMBLY_MODULE_TYPE_SYNC } = require("../ModuleTypeConstants"); const RuntimeGlobals = require("../RuntimeGlobals"); const WasmChunkLoadingRuntimeModule = require("../wasm-sync/WasmChunkLoadingRuntimeModule"); +/** @typedef {import("../Chunk")} Chunk */ /** @typedef {import("../Compiler")} Compiler */ // TODO webpack 6 remove +const PLUGIN_NAME = "FetchCompileWasmPlugin"; + +/** + * @typedef {object} FetchCompileWasmPluginOptions + * @property {boolean} [mangleImports] mangle imports + */ + class FetchCompileWasmPlugin { - constructor(options) { - this.options = options || {}; + /** + * @param {FetchCompileWasmPluginOptions} [options] options + */ + constructor(options = {}) { + this.options = options; } /** @@ -23,45 +35,53 @@ class FetchCompileWasmPlugin { * @returns {void} */ apply(compiler) { - compiler.hooks.thisCompilation.tap( - "FetchCompileWasmPlugin", - compilation => { - const globalWasmLoading = compilation.outputOptions.wasmLoading; - const isEnabledForChunk = chunk => { - const options = chunk.getEntryOptions(); - const wasmLoading = - (options && options.wasmLoading) || globalWasmLoading; - return wasmLoading === "fetch"; - }; - const generateLoadBinaryCode = path => - `fetch(${RuntimeGlobals.publicPath} + ${path})`; + compiler.hooks.thisCompilation.tap(PLUGIN_NAME, compilation => { + const globalWasmLoading = compilation.outputOptions.wasmLoading; + /** + * @param {Chunk} chunk chunk + * @returns {boolean} true, if wasm loading is enabled for the chunk + */ + const isEnabledForChunk = chunk => { + const options = chunk.getEntryOptions(); + const wasmLoading = + options && options.wasmLoading !== undefined + ? options.wasmLoading + : globalWasmLoading; + return wasmLoading === "fetch"; + }; + /** + * @param {string} path path to the wasm file + * @returns {string} code to load the wasm file + */ + const generateLoadBinaryCode = path => + `fetch(${RuntimeGlobals.publicPath} + ${path})`; - compilation.hooks.runtimeRequirementInTree - .for(RuntimeGlobals.ensureChunkHandlers) - .tap("FetchCompileWasmPlugin", (chunk, set) => { - if (!isEnabledForChunk(chunk)) return; - const chunkGraph = compilation.chunkGraph; - if ( - !chunkGraph.hasModuleInGraph( - chunk, - m => m.type === "webassembly/sync" - ) - ) { - return; - } - set.add(RuntimeGlobals.moduleCache); - set.add(RuntimeGlobals.publicPath); - compilation.addRuntimeModule( + compilation.hooks.runtimeRequirementInTree + .for(RuntimeGlobals.ensureChunkHandlers) + .tap(PLUGIN_NAME, (chunk, set) => { + if (!isEnabledForChunk(chunk)) return; + const chunkGraph = compilation.chunkGraph; + if ( + !chunkGraph.hasModuleInGraph( chunk, - new WasmChunkLoadingRuntimeModule({ - generateLoadBinaryCode, - supportsStreaming: true, - mangleImports: this.options.mangleImports - }) - ); - }); - } - ); + m => m.type === WEBASSEMBLY_MODULE_TYPE_SYNC + ) + ) { + return; + } + set.add(RuntimeGlobals.moduleCache); + set.add(RuntimeGlobals.publicPath); + compilation.addRuntimeModule( + chunk, + new WasmChunkLoadingRuntimeModule({ + generateLoadBinaryCode, + supportsStreaming: true, + mangleImports: this.options.mangleImports, + runtimeRequirements: set + }) + ); + }); + }); } } diff --git a/lib/web/JsonpChunkLoadingPlugin.js b/lib/web/JsonpChunkLoadingPlugin.js index 01bcc97d91d..57b75f81f40 100644 --- a/lib/web/JsonpChunkLoadingPlugin.js +++ b/lib/web/JsonpChunkLoadingPlugin.js @@ -8,6 +8,7 @@ const RuntimeGlobals = require("../RuntimeGlobals"); const JsonpChunkLoadingRuntimeModule = require("./JsonpChunkLoadingRuntimeModule"); +/** @typedef {import("../Chunk")} Chunk */ /** @typedef {import("../Compiler")} Compiler */ class JsonpChunkLoadingPlugin { @@ -21,13 +22,23 @@ class JsonpChunkLoadingPlugin { "JsonpChunkLoadingPlugin", compilation => { const globalChunkLoading = compilation.outputOptions.chunkLoading; + /** + * @param {Chunk} chunk chunk + * @returns {boolean} true, if wasm loading is enabled for the chunk + */ const isEnabledForChunk = chunk => { const options = chunk.getEntryOptions(); const chunkLoading = - (options && options.chunkLoading) || globalChunkLoading; + options && options.chunkLoading !== undefined + ? options.chunkLoading + : globalChunkLoading; return chunkLoading === "jsonp"; }; const onceForChunkSet = new WeakSet(); + /** + * @param {Chunk} chunk chunk + * @param {Set} set runtime requirements + */ const handler = (chunk, set) => { if (onceForChunkSet.has(chunk)) return; onceForChunkSet.add(chunk); diff --git a/lib/web/JsonpChunkLoadingRuntimeModule.js b/lib/web/JsonpChunkLoadingRuntimeModule.js index 726c00f84d3..c6d8eeb5dbf 100644 --- a/lib/web/JsonpChunkLoadingRuntimeModule.js +++ b/lib/web/JsonpChunkLoadingRuntimeModule.js @@ -14,9 +14,11 @@ const { getInitialChunkIds } = require("../javascript/StartupHelpers"); const compileBooleanMatcher = require("../util/compileBooleanMatcher"); /** @typedef {import("../Chunk")} Chunk */ +/** @typedef {import("../ChunkGraph")} ChunkGraph */ +/** @typedef {import("../Module").ReadOnlyRuntimeRequirements} ReadOnlyRuntimeRequirements */ /** - * @typedef {Object} JsonpCompilationPluginHooks + * @typedef {object} JsonpCompilationPluginHooks * @property {SyncWaterfallHook<[string, Chunk]>} linkPreload * @property {SyncWaterfallHook<[string, Chunk]>} linkPrefetch */ @@ -46,31 +48,44 @@ class JsonpChunkLoadingRuntimeModule extends RuntimeModule { return hooks; } + /** + * @param {ReadOnlyRuntimeRequirements} runtimeRequirements runtime requirements + */ constructor(runtimeRequirements) { super("jsonp chunk loading", RuntimeModule.STAGE_ATTACH); this._runtimeRequirements = runtimeRequirements; } /** - * @returns {string} runtime code + * @private + * @param {Chunk} chunk chunk + * @returns {string} generated code + */ + _generateBaseUri(chunk) { + const options = chunk.getEntryOptions(); + if (options && options.baseUri) { + return `${RuntimeGlobals.baseURI} = ${JSON.stringify(options.baseUri)};`; + } + return `${RuntimeGlobals.baseURI} = document.baseURI || self.location.href;`; + } + + /** + * @returns {string | null} runtime code */ generate() { - const { compilation, chunk } = this; + const compilation = /** @type {Compilation} */ (this.compilation); const { runtimeTemplate, - chunkGraph, outputOptions: { - globalObject, chunkLoadingGlobal, hotUpdateGlobal, crossOriginLoading, scriptType } } = compilation; - const { - linkPreload, - linkPrefetch - } = JsonpChunkLoadingRuntimeModule.getCompilationHooks(compilation); + const globalObject = runtimeTemplate.globalObject; + const { linkPreload, linkPrefetch } = + JsonpChunkLoadingRuntimeModule.getCompilationHooks(compilation); const fn = RuntimeGlobals.ensureChunkHandlers; const withBaseURI = this._runtimeRequirements.has(RuntimeGlobals.baseURI); const withLoading = this._runtimeRequirements.has( @@ -94,24 +109,31 @@ class JsonpChunkLoadingRuntimeModule extends RuntimeModule { const withPreload = this._runtimeRequirements.has( RuntimeGlobals.preloadChunkHandlers ); + const withFetchPriority = this._runtimeRequirements.has( + RuntimeGlobals.hasFetchPriority + ); const chunkLoadingGlobalExpr = `${globalObject}[${JSON.stringify( chunkLoadingGlobal )}]`; + const chunkGraph = /** @type {ChunkGraph} */ (this.chunkGraph); + const chunk = /** @type {Chunk} */ (this.chunk); const conditionMap = chunkGraph.getChunkConditionMap(chunk, chunkHasJs); const hasJsMatcher = compileBooleanMatcher(conditionMap); - const initialChunkIds = getInitialChunkIds(chunk, chunkGraph); + const initialChunkIds = getInitialChunkIds(chunk, chunkGraph, chunkHasJs); + + const stateExpression = withHmr + ? `${RuntimeGlobals.hmrRuntimeStatePrefix}_jsonp` + : undefined; return Template.asString([ - withBaseURI - ? Template.asString([ - `${RuntimeGlobals.baseURI} = document.baseURI || self.location.href;` - ]) - : "// no baseURI", + withBaseURI ? this._generateBaseUri(chunk) : "// no baseURI", "", "// object to store loaded and loading chunks", "// undefined = chunk not loaded, null = chunk preloaded/prefetched", "// [resolve, reject, Promise] = chunk loading, 0 = chunk loaded", - "var installedChunks = {", + `var installedChunks = ${ + stateExpression ? `${stateExpression} = ${stateExpression} || ` : "" + }{`, Template.indent( Array.from(initialChunkIds, id => `${JSON.stringify(id)}: 0`).join( ",\n" @@ -122,7 +144,7 @@ class JsonpChunkLoadingRuntimeModule extends RuntimeModule { withLoading ? Template.asString([ `${fn}.j = ${runtimeTemplate.basicFunction( - "chunkId, promises", + `chunkId, promises${withFetchPriority ? ", fetchPriority" : ""}`, hasJsMatcher !== false ? Template.indent([ "// JSONP chunk loading for javascript", @@ -143,7 +165,7 @@ class JsonpChunkLoadingRuntimeModule extends RuntimeModule { Template.indent([ "// setup Promise in chunk cache", `var promise = new Promise(${runtimeTemplate.expressionFunction( - `installedChunkData = installedChunks[chunkId] = [resolve, reject]`, + "installedChunkData = installedChunks[chunkId] = [resolve, reject]", "resolve, reject" )});`, "promises.push(installedChunkData[2] = promise);", @@ -174,23 +196,29 @@ class JsonpChunkLoadingRuntimeModule extends RuntimeModule { "}" ] )};`, - `${RuntimeGlobals.loadScript}(url, loadingEnded, "chunk-" + chunkId, chunkId);` + `${ + RuntimeGlobals.loadScript + }(url, loadingEnded, "chunk-" + chunkId, chunkId${ + withFetchPriority ? ", fetchPriority" : "" + });` ]), - "} else installedChunks[chunkId] = 0;" + hasJsMatcher === true + ? "}" + : "} else installedChunks[chunkId] = 0;" ]), "}" ]), "}" - ]) + ]) : Template.indent(["installedChunks[chunkId] = 0;"]) )};` - ]) + ]) : "// no chunk on demand loading", "", withPrefetch && hasJsMatcher !== false ? `${ RuntimeGlobals.prefetchChunkHandlers - }.j = ${runtimeTemplate.basicFunction("chunkId", [ + }.j = ${runtimeTemplate.basicFunction("chunkId", [ `if((!${ RuntimeGlobals.hasOwnProperty }(installedChunks, chunkId) || installedChunks[chunkId] === undefined) && ${ @@ -204,7 +232,7 @@ class JsonpChunkLoadingRuntimeModule extends RuntimeModule { crossOriginLoading ? `link.crossOrigin = ${JSON.stringify( crossOriginLoading - )};` + )};` : "", `if (${RuntimeGlobals.scriptNonce}) {`, Template.indent( @@ -220,13 +248,13 @@ class JsonpChunkLoadingRuntimeModule extends RuntimeModule { "document.head.appendChild(link);" ]), "}" - ])};` + ])};` : "// no prefetching", "", withPreload && hasJsMatcher !== false ? `${ RuntimeGlobals.preloadChunkHandlers - }.j = ${runtimeTemplate.basicFunction("chunkId", [ + }.j = ${runtimeTemplate.basicFunction("chunkId", [ `if((!${ RuntimeGlobals.hasOwnProperty }(installedChunks, chunkId) || installedChunks[chunkId] === undefined) && ${ @@ -237,7 +265,7 @@ class JsonpChunkLoadingRuntimeModule extends RuntimeModule { linkPreload.call( Template.asString([ "var link = document.createElement('link');", - scriptType + scriptType && scriptType !== "module" ? `link.type = ${JSON.stringify(scriptType)};` : "", "link.charset = 'utf-8';", @@ -246,19 +274,23 @@ class JsonpChunkLoadingRuntimeModule extends RuntimeModule { `link.setAttribute("nonce", ${RuntimeGlobals.scriptNonce});` ), "}", - 'link.rel = "preload";', - 'link.as = "script";', + scriptType === "module" + ? 'link.rel = "modulepreload";' + : 'link.rel = "preload";', + scriptType === "module" ? "" : 'link.as = "script";', `link.href = ${RuntimeGlobals.publicPath} + ${RuntimeGlobals.getChunkScriptFilename}(chunkId);`, crossOriginLoading - ? Template.asString([ - "if (link.href.indexOf(window.location.origin + '/') !== 0) {", - Template.indent( - `link.crossOrigin = ${JSON.stringify( - crossOriginLoading - )};` - ), - "}" - ]) + ? crossOriginLoading === "use-credentials" + ? 'link.crossOrigin = "use-credentials";' + : Template.asString([ + "if (link.href.indexOf(window.location.origin + '/') !== 0) {", + Template.indent( + `link.crossOrigin = ${JSON.stringify( + crossOriginLoading + )};` + ), + "}" + ]) : "" ]), chunk @@ -266,15 +298,16 @@ class JsonpChunkLoadingRuntimeModule extends RuntimeModule { "document.head.appendChild(link);" ]), "}" - ])};` + ])};` : "// no preloaded", "", withHmr ? Template.asString([ "var currentUpdatedModulesList;", "var waitingUpdateResolves = {};", - "function loadUpdateChunk(chunkId) {", + "function loadUpdateChunk(chunkId, updatedModulesList) {", Template.indent([ + "currentUpdatedModulesList = updatedModulesList;", `return new Promise(${runtimeTemplate.basicFunction( "resolve, reject", [ @@ -350,7 +383,7 @@ class JsonpChunkLoadingRuntimeModule extends RuntimeModule { /\$hmrInvalidateModuleHandlers\$/g, RuntimeGlobals.hmrInvalidateModuleHandlers ) - ]) + ]) : "// no HMR", "", withHmrManifest @@ -367,16 +400,16 @@ class JsonpChunkLoadingRuntimeModule extends RuntimeModule { "return response.json();" ])});` ])};` - ]) + ]) : "// no HMR manifest", "", withOnChunkLoad ? `${ RuntimeGlobals.onChunksLoaded - }.j = ${runtimeTemplate.returningFunction( + }.j = ${runtimeTemplate.returningFunction( "installedChunks[chunkId] === 0", "chunkId" - )};` + )};` : "// no on chunks loaded", "", withCallback || withLoading @@ -392,16 +425,23 @@ class JsonpChunkLoadingRuntimeModule extends RuntimeModule { '// add "moreModules" to the modules object,', '// then flag all "chunkIds" as loaded and fire callback', "var moduleId, chunkId, i = 0;", - "for(moduleId in moreModules) {", + `if(chunkIds.some(${runtimeTemplate.returningFunction( + "installedChunks[id] !== 0", + "id" + )})) {`, Template.indent([ - `if(${RuntimeGlobals.hasOwnProperty}(moreModules, moduleId)) {`, - Template.indent( - `${RuntimeGlobals.moduleFactories}[moduleId] = moreModules[moduleId];` - ), - "}" + "for(moduleId in moreModules) {", + Template.indent([ + `if(${RuntimeGlobals.hasOwnProperty}(moreModules, moduleId)) {`, + Template.indent( + `${RuntimeGlobals.moduleFactories}[moduleId] = moreModules[moduleId];` + ), + "}" + ]), + "}", + `if(runtime) var result = runtime(${RuntimeGlobals.require});` ]), "}", - "if(runtime) runtime(__webpack_require__);", "if(parentChunkLoadingFunction) parentChunkLoadingFunction(data);", "for(;i < chunkIds.length; i++) {", Template.indent([ @@ -409,17 +449,19 @@ class JsonpChunkLoadingRuntimeModule extends RuntimeModule { `if(${RuntimeGlobals.hasOwnProperty}(installedChunks, chunkId) && installedChunks[chunkId]) {`, Template.indent("installedChunks[chunkId][0]();"), "}", - "installedChunks[chunkIds[i]] = 0;" + "installedChunks[chunkId] = 0;" ]), "}", - withOnChunkLoad ? `${RuntimeGlobals.onChunksLoaded}();` : "" + withOnChunkLoad + ? `return ${RuntimeGlobals.onChunksLoaded}(result);` + : "" ] )}`, "", `var chunkLoadingGlobal = ${chunkLoadingGlobalExpr} = ${chunkLoadingGlobalExpr} || [];`, "chunkLoadingGlobal.forEach(webpackJsonpCallback.bind(null, 0));", "chunkLoadingGlobal.push = webpackJsonpCallback.bind(null, chunkLoadingGlobal.push.bind(chunkLoadingGlobal));" - ]) + ]) : "// no jsonp function" ]); } diff --git a/lib/webpack.js b/lib/webpack.js index 810bb960f61..7396300a0b9 100644 --- a/lib/webpack.js +++ b/lib/webpack.js @@ -6,6 +6,7 @@ "use strict"; const util = require("util"); +const webpackOptionsSchemaCheck = require("../schemas/WebpackOptions.check.js"); const webpackOptionsSchema = require("../schemas/WebpackOptions.json"); const Compiler = require("./Compiler"); const MultiCompiler = require("./MultiCompiler"); @@ -16,29 +17,34 @@ const { } = require("./config/defaults"); const { getNormalizedWebpackOptions } = require("./config/normalization"); const NodeEnvironmentPlugin = require("./node/NodeEnvironmentPlugin"); -const validateSchema = require("./validateSchema"); +const memoize = require("./util/memoize"); /** @typedef {import("../declarations/WebpackOptions").WebpackOptions} WebpackOptions */ +/** @typedef {import("../declarations/WebpackOptions").WebpackPluginFunction} WebpackPluginFunction */ /** @typedef {import("./Compiler").WatchOptions} WatchOptions */ /** @typedef {import("./MultiCompiler").MultiCompilerOptions} MultiCompilerOptions */ /** @typedef {import("./MultiStats")} MultiStats */ /** @typedef {import("./Stats")} Stats */ +const getValidateSchema = memoize(() => require("./validateSchema")); + /** * @template T * @callback Callback - * @param {Error=} err + * @param {Error | null} err * @param {T=} stats * @returns {void} */ /** - * @param {WebpackOptions[]} childOptions options array + * @param {ReadonlyArray} childOptions options array * @param {MultiCompilerOptions} options options * @returns {MultiCompiler} a multi-compiler */ const createMultiCompiler = (childOptions, options) => { - const compilers = childOptions.map(options => createCompiler(options)); + const compilers = childOptions.map((options, index) => + createCompiler(options, index) + ); const compiler = new MultiCompiler(compilers, options); for (const childCompiler of compilers) { if (childCompiler.options.dependencies) { @@ -53,26 +59,36 @@ const createMultiCompiler = (childOptions, options) => { /** * @param {WebpackOptions} rawOptions options object + * @param {number} [compilerIndex] index of compiler * @returns {Compiler} a compiler */ -const createCompiler = rawOptions => { +const createCompiler = (rawOptions, compilerIndex) => { const options = getNormalizedWebpackOptions(rawOptions); applyWebpackOptionsBaseDefaults(options); - const compiler = new Compiler(options.context); - compiler.options = options; + const compiler = new Compiler( + /** @type {string} */ (options.context), + options + ); new NodeEnvironmentPlugin({ infrastructureLogging: options.infrastructureLogging }).apply(compiler); if (Array.isArray(options.plugins)) { for (const plugin of options.plugins) { if (typeof plugin === "function") { - plugin.call(compiler, compiler); - } else { + /** @type {WebpackPluginFunction} */ + (plugin).call(compiler, compiler); + } else if (plugin) { plugin.apply(compiler); } } } - applyWebpackOptionsDefaults(options); + const resolvedDefaultOptions = applyWebpackOptionsDefaults( + options, + compilerIndex + ); + if (resolvedDefaultOptions.platform) { + compiler.platform = resolvedDefaultOptions.platform; + } compiler.hooks.environment.call(); compiler.hooks.afterEnvironment.call(); new WebpackOptionsApply().process(options, compiler); @@ -89,35 +105,55 @@ const createCompiler = rawOptions => { /** * @callback WebpackFunctionMulti - * @param {WebpackOptions[] & MultiCompilerOptions} options options objects + * @param {ReadonlyArray & MultiCompilerOptions} options options objects * @param {Callback=} callback callback * @returns {MultiCompiler} the multi compiler object */ +/** + * @template T + * @param {Array | T} options options + * @returns {Array} array of options + */ +const asArray = options => + Array.isArray(options) ? Array.from(options) : [options]; + const webpack = /** @type {WebpackFunctionSingle & WebpackFunctionMulti} */ ( /** - * @param {WebpackOptions | (WebpackOptions[] & MultiCompilerOptions)} options options + * @param {WebpackOptions | (ReadonlyArray & MultiCompilerOptions)} options options * @param {Callback & Callback=} callback callback - * @returns {Compiler | MultiCompiler} + * @returns {Compiler | MultiCompiler | null} Compiler or MultiCompiler */ (options, callback) => { const create = () => { - validateSchema(webpackOptionsSchema, options); + if (!asArray(options).every(webpackOptionsSchemaCheck)) { + getValidateSchema()(webpackOptionsSchema, options); + util.deprecate( + () => {}, + "webpack bug: Pre-compiled schema reports error while real schema is happy. This has performance drawbacks.", + "DEP_WEBPACK_PRE_COMPILED_SCHEMA_INVALID" + )(); + } /** @type {MultiCompiler|Compiler} */ let compiler; + /** @type {boolean | undefined} */ let watch = false; /** @type {WatchOptions|WatchOptions[]} */ let watchOptions; if (Array.isArray(options)) { /** @type {MultiCompiler} */ - compiler = createMultiCompiler(options, options); + compiler = createMultiCompiler( + options, + /** @type {MultiCompilerOptions} */ (options) + ); watch = options.some(options => options.watch); watchOptions = options.map(options => options.watchOptions || {}); } else { + const webpackOptions = /** @type {WebpackOptions} */ (options); /** @type {Compiler} */ - compiler = createCompiler(options); - watch = options.watch; - watchOptions = options.watchOptions || {}; + compiler = createCompiler(webpackOptions); + watch = webpackOptions.watch; + watchOptions = webpackOptions.watchOptions || {}; } return { compiler, watch, watchOptions }; }; @@ -129,13 +165,17 @@ const webpack = /** @type {WebpackFunctionSingle & WebpackFunctionMulti} */ ( } else { compiler.run((err, stats) => { compiler.close(err2 => { - callback(err || err2, stats); + callback( + err || err2, + /** @type {options extends WebpackOptions ? Stats : MultiStats} */ + (stats) + ); }); }); } return compiler; } catch (err) { - process.nextTick(() => callback(err)); + process.nextTick(() => callback(/** @type {Error} */ (err))); return null; } } else { @@ -143,7 +183,7 @@ const webpack = /** @type {WebpackFunctionSingle & WebpackFunctionMulti} */ ( if (watch) { util.deprecate( () => {}, - "A 'callback' argument need to be provided to the 'webpack(options, callback)' function when the 'watch' option is set. There is no way to handle the 'watch' option without a callback.", + "A 'callback' argument needs to be provided to the 'webpack(options, callback)' function when the 'watch' option is set. There is no way to handle the 'watch' option without a callback.", "DEP_WEBPACK_WATCH_WITHOUT_CALLBACK" )(); } diff --git a/lib/webworker/ImportScriptsChunkLoadingPlugin.js b/lib/webworker/ImportScriptsChunkLoadingPlugin.js index 8be3eb8bc0c..ddb6cf51a7d 100644 --- a/lib/webworker/ImportScriptsChunkLoadingPlugin.js +++ b/lib/webworker/ImportScriptsChunkLoadingPlugin.js @@ -9,6 +9,7 @@ const RuntimeGlobals = require("../RuntimeGlobals"); const StartupChunkDependenciesPlugin = require("../runtime/StartupChunkDependenciesPlugin"); const ImportScriptsChunkLoadingRuntimeModule = require("./ImportScriptsChunkLoadingRuntimeModule"); +/** @typedef {import("../Chunk")} Chunk */ /** @typedef {import("../Compiler")} Compiler */ class ImportScriptsChunkLoadingPlugin { @@ -26,22 +27,38 @@ class ImportScriptsChunkLoadingPlugin { "ImportScriptsChunkLoadingPlugin", compilation => { const globalChunkLoading = compilation.outputOptions.chunkLoading; + /** + * @param {Chunk} chunk chunk + * @returns {boolean} true, if wasm loading is enabled for the chunk + */ const isEnabledForChunk = chunk => { const options = chunk.getEntryOptions(); const chunkLoading = - (options && options.chunkLoading) || globalChunkLoading; + options && options.chunkLoading !== undefined + ? options.chunkLoading + : globalChunkLoading; return chunkLoading === "import-scripts"; }; const onceForChunkSet = new WeakSet(); + /** + * @param {Chunk} chunk chunk + * @param {Set} set runtime requirements + */ const handler = (chunk, set) => { if (onceForChunkSet.has(chunk)) return; onceForChunkSet.add(chunk); if (!isEnabledForChunk(chunk)) return; + const withCreateScriptUrl = Boolean( + compilation.outputOptions.trustedTypes + ); set.add(RuntimeGlobals.moduleFactoriesAddOnly); set.add(RuntimeGlobals.hasOwnProperty); + if (withCreateScriptUrl) { + set.add(RuntimeGlobals.createScriptUrl); + } compilation.addRuntimeModule( chunk, - new ImportScriptsChunkLoadingRuntimeModule(set) + new ImportScriptsChunkLoadingRuntimeModule(set, withCreateScriptUrl) ); }; compilation.hooks.runtimeRequirementInTree diff --git a/lib/webworker/ImportScriptsChunkLoadingRuntimeModule.js b/lib/webworker/ImportScriptsChunkLoadingRuntimeModule.js index c43ed5c742d..7d2ae3a3d61 100644 --- a/lib/webworker/ImportScriptsChunkLoadingRuntimeModule.js +++ b/lib/webworker/ImportScriptsChunkLoadingRuntimeModule.js @@ -15,24 +15,55 @@ const { getInitialChunkIds } = require("../javascript/StartupHelpers"); const compileBooleanMatcher = require("../util/compileBooleanMatcher"); const { getUndoPath } = require("../util/identifier"); +/** @typedef {import("../Chunk")} Chunk */ +/** @typedef {import("../ChunkGraph")} ChunkGraph */ +/** @typedef {import("../Compilation")} Compilation */ +/** @typedef {import("../Module").ReadOnlyRuntimeRequirements} ReadOnlyRuntimeRequirements */ + class ImportScriptsChunkLoadingRuntimeModule extends RuntimeModule { - constructor(runtimeRequirements) { + /** + * @param {ReadOnlyRuntimeRequirements} runtimeRequirements runtime requirements + * @param {boolean} withCreateScriptUrl with createScriptUrl support + */ + constructor(runtimeRequirements, withCreateScriptUrl) { super("importScripts chunk loading", RuntimeModule.STAGE_ATTACH); this.runtimeRequirements = runtimeRequirements; + this._withCreateScriptUrl = withCreateScriptUrl; } /** - * @returns {string} runtime code + * @private + * @param {Chunk} chunk chunk + * @returns {string} generated code */ - generate() { - const { - chunk, - compilation: { - chunkGraph, - runtimeTemplate, - outputOptions: { globalObject, chunkLoadingGlobal, hotUpdateGlobal } + _generateBaseUri(chunk) { + const options = chunk.getEntryOptions(); + if (options && options.baseUri) { + return `${RuntimeGlobals.baseURI} = ${JSON.stringify(options.baseUri)};`; + } + const compilation = /** @type {Compilation} */ (this.compilation); + const outputName = compilation.getPath( + getChunkFilenameTemplate(chunk, compilation.outputOptions), + { + chunk, + contentHashType: "javascript" } - } = this; + ); + const rootOutputDir = getUndoPath( + outputName, + /** @type {string} */ (compilation.outputOptions.path), + false + ); + return `${RuntimeGlobals.baseURI} = self.location + ${JSON.stringify( + rootOutputDir ? `/../${rootOutputDir}` : "" + )};`; + } + + /** + * @returns {string | null} runtime code + */ + generate() { + const compilation = /** @type {Compilation} */ (this.compilation); const fn = RuntimeGlobals.ensureChunkHandlers; const withBaseURI = this.runtimeRequirements.has(RuntimeGlobals.baseURI); const withLoading = this.runtimeRequirements.has( @@ -44,39 +75,31 @@ class ImportScriptsChunkLoadingRuntimeModule extends RuntimeModule { const withHmrManifest = this.runtimeRequirements.has( RuntimeGlobals.hmrDownloadManifest ); + const globalObject = compilation.runtimeTemplate.globalObject; const chunkLoadingGlobalExpr = `${globalObject}[${JSON.stringify( - chunkLoadingGlobal + compilation.outputOptions.chunkLoadingGlobal )}]`; + const chunkGraph = /** @type {ChunkGraph} */ (this.chunkGraph); + const chunk = /** @type {Chunk} */ (this.chunk); const hasJsMatcher = compileBooleanMatcher( chunkGraph.getChunkConditionMap(chunk, chunkHasJs) ); - const initialChunkIds = getInitialChunkIds(chunk, chunkGraph); + const initialChunkIds = getInitialChunkIds(chunk, chunkGraph, chunkHasJs); - const outputName = this.compilation.getPath( - getChunkFilenameTemplate(chunk, this.compilation.outputOptions), - { - chunk, - contentHashType: "javascript" - } - ); - const rootOutputDir = getUndoPath( - outputName, - this.compilation.outputOptions.path, - false - ); + const stateExpression = withHmr + ? `${RuntimeGlobals.hmrRuntimeStatePrefix}_importScripts` + : undefined; + const runtimeTemplate = compilation.runtimeTemplate; + const { _withCreateScriptUrl: withCreateScriptUrl } = this; return Template.asString([ - withBaseURI - ? Template.asString([ - `${RuntimeGlobals.baseURI} = self.location + ${JSON.stringify( - rootOutputDir ? "/../" + rootOutputDir : "" - )};` - ]) - : "// no baseURI", + withBaseURI ? this._generateBaseUri(chunk) : "// no baseURI", "", "// object to store loaded chunks", '// "1" means "already loaded"', - "var installedChunks = {", + `var installedChunks = ${ + stateExpression ? `${stateExpression} = ${stateExpression} || ` : "" + }{`, Template.indent( Array.from(initialChunkIds, id => `${JSON.stringify(id)}: 1`).join( ",\n" @@ -101,12 +124,12 @@ class ImportScriptsChunkLoadingRuntimeModule extends RuntimeModule { "}" ]), "}", - "if(runtime) runtime(__webpack_require__);", + `if(runtime) runtime(${RuntimeGlobals.require});`, "while(chunkIds.length)", Template.indent("installedChunks[chunkIds.pop()] = 1;"), "parentChunkLoadingFunction(data);" ])};` - ]) + ]) : "// no chunk install function needed", withLoading ? Template.asString([ @@ -121,19 +144,23 @@ class ImportScriptsChunkLoadingRuntimeModule extends RuntimeModule { ? "if(true) { // all chunks have JS" : `if(${hasJsMatcher("chunkId")}) {`, Template.indent( - `importScripts(${RuntimeGlobals.publicPath} + ${RuntimeGlobals.getChunkScriptFilename}(chunkId));` + `importScripts(${ + withCreateScriptUrl + ? `${RuntimeGlobals.createScriptUrl}(${RuntimeGlobals.publicPath} + ${RuntimeGlobals.getChunkScriptFilename}(chunkId))` + : `${RuntimeGlobals.publicPath} + ${RuntimeGlobals.getChunkScriptFilename}(chunkId)` + });` ), "}" ]), "}" - ] + ] : "installedChunks[chunkId] = 1;" )};`, "", `var chunkLoadingGlobal = ${chunkLoadingGlobalExpr} = ${chunkLoadingGlobalExpr} || [];`, "var parentChunkLoadingFunction = chunkLoadingGlobal.push.bind(chunkLoadingGlobal);", "chunkLoadingGlobal.push = installChunk;" - ]) + ]) : "// no chunk loading", "", withHmr @@ -142,7 +169,7 @@ class ImportScriptsChunkLoadingRuntimeModule extends RuntimeModule { Template.indent([ "var success = false;", `${globalObject}[${JSON.stringify( - hotUpdateGlobal + compilation.outputOptions.hotUpdateGlobal )}] = ${runtimeTemplate.basicFunction("_, moreModules, runtime", [ "for(var moduleId in moreModules) {", Template.indent([ @@ -158,7 +185,11 @@ class ImportScriptsChunkLoadingRuntimeModule extends RuntimeModule { "success = true;" ])};`, "// start update chunk loading", - `importScripts(${RuntimeGlobals.publicPath} + ${RuntimeGlobals.getChunkUpdateScriptFilename}(chunkId));`, + `importScripts(${ + withCreateScriptUrl + ? `${RuntimeGlobals.createScriptUrl}(${RuntimeGlobals.publicPath} + ${RuntimeGlobals.getChunkUpdateScriptFilename}(chunkId))` + : `${RuntimeGlobals.publicPath} + ${RuntimeGlobals.getChunkUpdateScriptFilename}(chunkId)` + });`, 'if(!success) throw new Error("Loading update chunk failed for unknown reason");' ]), "}", @@ -166,7 +197,7 @@ class ImportScriptsChunkLoadingRuntimeModule extends RuntimeModule { Template.getFunctionContent( require("../hmr/JavascriptHotModuleReplacement.runtime.js") ) - .replace(/\$key\$/g, "importScrips") + .replace(/\$key\$/g, "importScripts") .replace(/\$installedChunks\$/g, "installedChunks") .replace(/\$loadUpdateChunk\$/g, "loadUpdateChunk") .replace(/\$moduleCache\$/g, RuntimeGlobals.moduleCache) @@ -185,7 +216,7 @@ class ImportScriptsChunkLoadingRuntimeModule extends RuntimeModule { /\$hmrInvalidateModuleHandlers\$/g, RuntimeGlobals.hmrInvalidateModuleHandlers ) - ]) + ]) : "// no HMR", "", withHmrManifest @@ -202,7 +233,7 @@ class ImportScriptsChunkLoadingRuntimeModule extends RuntimeModule { "return response.json();" ])});` ])};` - ]) + ]) : "// no HMR manifest" ]); } diff --git a/module.d.ts b/module.d.ts new file mode 100644 index 00000000000..a175caf3398 --- /dev/null +++ b/module.d.ts @@ -0,0 +1,233 @@ +declare namespace webpack { + type DeclinedEvent = + | { + type: "declined"; + /** The module in question. */ + moduleId: number | string; + /** the chain from where the update was propagated. */ + chain: (number | string)[]; + /** the module id of the declining parent */ + parentId: number | string; + } + | { + type: "self-declined"; + /** The module in question. */ + moduleId: number | string; + /** the chain from where the update was propagated. */ + chain: (number | string)[]; + }; + + type UnacceptedEvent = { + type: "unaccepted"; + /** The module in question. */ + moduleId: number | string; + /** the chain from where the update was propagated. */ + chain: (number | string)[]; + }; + + type AcceptedEvent = { + type: "accepted"; + /** The module in question. */ + moduleId: number | string; + /** the modules that are outdated and will be disposed */ + outdatedModules: (number | string)[]; + /** the accepted dependencies that are outdated */ + outdatedDependencies: { + [id: number]: (number | string)[]; + }; + }; + + type DisposedEvent = { + type: "disposed"; + /** The module in question. */ + moduleId: number | string; + }; + + type ErroredEvent = + | { + type: "accept-error-handler-errored"; + /** The module in question. */ + moduleId: number | string; + /** the module id owning the accept handler. */ + dependencyId: number | string; + /** the thrown error */ + error: Error; + /** the error thrown by the module before the error handler tried to handle it. */ + originalError: Error; + } + | { + type: "self-accept-error-handler-errored"; + /** The module in question. */ + moduleId: number | string; + /** the thrown error */ + error: Error; + /** the error thrown by the module before the error handler tried to handle it. */ + originalError: Error; + } + | { + type: "accept-errored"; + /** The module in question. */ + moduleId: number | string; + /** the module id owning the accept handler. */ + dependencyId: number | string; + /** the thrown error */ + error: Error; + } + | { + type: "self-accept-errored"; + /** The module in question. */ + moduleId: number | string; + /** the thrown error */ + error: Error; + }; + + type HotEvent = + | DeclinedEvent + | UnacceptedEvent + | AcceptedEvent + | DisposedEvent + | ErroredEvent; + + interface ApplyOptions { + ignoreUnaccepted?: boolean; + ignoreDeclined?: boolean; + ignoreErrored?: boolean; + onDeclined?: (event: DeclinedEvent) => void; + onUnaccepted?: (event: UnacceptedEvent) => void; + onAccepted?: (event: AcceptedEvent) => void; + onDisposed?: (event: DisposedEvent) => void; + onErrored?: (event: ErroredEvent) => void; + } + + const enum HotUpdateStatus { + idle = "idle", + check = "check", + prepare = "prepare", + ready = "ready", + dispose = "dispose", + apply = "apply", + abort = "abort", + fail = "fail" + } + + interface Hot { + accept: { + ( + modules: string | string[], + callback?: (outdatedDependencies: string[]) => void, + errorHandler?: ( + err: Error, + context: { moduleId: string | number; dependencyId: string | number } + ) => void + ): void; + ( + errorHandler?: ( + err: Error, + ids: { moduleId: string | number; module: NodeJS.Module } + ) => void + ): void; + }; + status(): HotUpdateStatus; + decline(module?: string | string[]): void; + dispose(callback: (data: object) => void): void; + addDisposeHandler(callback: (data: object) => void): void; + removeDisposeHandler(callback: (data: object) => void): void; + invalidate(): void; + addStatusHandler(callback: (status: HotUpdateStatus) => void): void; + removeStatusHandler(callback: (status: HotUpdateStatus) => void): void; + data: object; + check( + autoApply?: boolean | ApplyOptions + ): Promise<(string | number)[] | null>; + apply(options?: ApplyOptions): Promise<(string | number)[] | null>; + } + + interface ExportInfo { + used: boolean; + provideInfo: boolean | null | undefined; + useInfo: boolean | null | undefined; + canMangle: boolean; + } + + interface ExportsInfo { + [k: string]: ExportInfo & ExportsInfo; + } + + interface Context { + resolve(dependency: string): string | number; + keys(): Array; + id: string | number; + (dependency: string): unknown; + } +} + +interface ImportMeta { + url: string; + webpack: number; + webpackHot: webpack.Hot; + webpackContext: ( + request: string, + options?: { + recursive?: boolean; + regExp?: RegExp; + include?: RegExp; + exclude?: RegExp; + preload?: boolean | number; + prefetch?: boolean | number; + fetchPriority?: "low" | "high" | "auto"; + chunkName?: string; + exports?: string | string[][]; + mode?: "sync" | "eager" | "weak" | "lazy" | "lazy-once"; + } + ) => webpack.Context; +} + +declare const __resourceQuery: string; +declare var __webpack_public_path__: string; +declare var __webpack_nonce__: string; +declare const __webpack_chunkname__: string; +declare var __webpack_base_uri__: string; +declare var __webpack_runtime_id__: string; +declare const __webpack_hash__: string; +declare const __webpack_modules__: Record; +declare const __webpack_require__: (id: string | number) => unknown; +declare var __webpack_chunk_load__: (chunkId: string | number) => Promise; +declare var __webpack_get_script_filename__: ( + chunkId: string | number +) => string; +declare var __webpack_is_included__: (request: string) => boolean; +declare var __webpack_exports_info__: webpack.ExportsInfo; +declare const __webpack_share_scopes__: Record< + string, + Record< + string, + { loaded?: 1; get: () => Promise; from: string; eager: boolean } + > +>; +declare var __webpack_init_sharing__: (scope: string) => Promise; +declare var __non_webpack_require__: (id: any) => unknown; +declare const __system_context__: object; + +declare namespace NodeJS { + interface Module { + hot: webpack.Hot; + } + + interface Require { + ensure( + dependencies: string[], + callback: (require: (module: string) => void) => void, + errorCallback?: (error: Error) => void, + chunkName?: string + ): void; + context( + request: string, + includeSubdirectories?: boolean, + filter?: RegExp, + mode?: "sync" | "eager" | "weak" | "lazy" | "lazy-once" + ): webpack.Context; + include(dependency: string): void; + resolveWeak(dependency: string): void; + onError?: (error: Error) => void; + } +} diff --git a/open-bot.yaml b/open-bot.yaml index 1c417beeb23..34b6acf1d69 100644 --- a/open-bot.yaml +++ b/open-bot.yaml @@ -1,136 +1,5 @@ bot: "webpack-bot" rules: - # Add ci-ok, ci-not-ok labels depending on travis status - # comment to point the user to the results - # comment in case of success - - filters: - open: true - pull_request: - mergeable: true - check_1: - name: "webpack.webpack" - status_2: - context: "continuous-integration/appveyor/pr" - ensure_1: - value: "{{check_1.conclusion}}" - equals: "success" - ensure_2: - value: "{{status_2.state}}" - equals: "success" - actions: - label: - add: "PR: CI-ok" - remove: "PR: CI-not-ok" - comment: - identifier: "ci-result" - message: |- - Thank you for your pull request! The most important CI builds succeeded, weโ€™ll review the pull request soon. - - filters: - open: true - pull_request: - mergeable: true - check_1: - name: "webpack.webpack" - status_2: - context: "continuous-integration/appveyor/pr" - any: - ensure_1: - value: "{{check_1.conclusion}}" - equals: "failure" - ensure_2: - value: "{{status_2.state}}" - equals: "failure" - not: - any: - ensure_3: - value: "{{check_1.conclusion}}" - equals: "pending" - ensure_4: - value: "{{status_2.state}}" - equals: "pending" - actions: - label: - add: "PR: CI-not-ok" - remove: "PR: CI-ok" - set: - id: report_ci - value: yep - - # Report a general error message - - filters: - ensure: - value: "{{report_ci}}" - equals: yep - commit: true - check_1: - name: "webpack.webpack" - status_2: - context: "continuous-integration/appveyor/pr" - actions: - comment: - identifier: "ci-result" - message: |- - @{{commit.author.login}} The most important CI builds failed. This way your PR can't be merged. - - Please take a look at the CI results from azure ({{{check_1.output.summary}}}) and [appveyor]({{status_2.target_url}}) ({{status_2.state}}) and fix these issues. - - # Add tests-needed label depending on codecov status - # comment to point the user writing test cases - # comment in case of success - - filters: - open: true - pull_request: - mergeable: true - status: - context: "codecov/patch/integration" - ensure: - value: "{{status.state}}" - equals: "success" - label: "PR: tests-needed" - actions: - label: - remove: "PR: tests-needed" - comment: - identifier: "tests-result" - message: |- - The minimum test ratio has been reached. Thanks! - - filters: - open: true - pull_request: - mergeable: true - status: - context: "codecov/patch/integration" - ensure: - value: "{{status.state}}" - equals: "failure" - actions: - label: - add: "PR: tests-needed" - - filters: - open: true - pull_request: - mergeable: true - status: - context: "codecov/patch/integration" - ensure: - value: "{{status.state}}" - equals: "failure" - age: - value: "{{status.created_at}}" - minimum: 1h - permission: "read|none" - actions: - comment: - identifier: "tests-result" - message: |- - It looks like this Pull Request doesn't include [enough test cases]({{status.target_url}}) (based on Code Coverage analysis of the PR diff). - - A PR need to be covered by tests if you add a new feature (we want to make sure that your feature is working) or if you fix a bug (we want to make sure that we don't run into a regression in future). - - @{{issue.user.login}} Please check if this is appliable to your PR and if you can add more test cases. - - Read the [test readme](https://github.com/webpack/webpack/blob/master/test/README.md) for details how to write test cases. - # add conflict label to pull requests with conflict # on conflict all result labels are removed - filters: @@ -140,10 +9,6 @@ rules: actions: label: add: "PR: conflict" - remove: - - "PR: tests-needed" - - "PR: CI-ok" - - "PR: CI-not-ok" - filters: open: true pull_request: @@ -229,16 +94,27 @@ rules: actions: label: "PR: unreviewed" - # add non-master, webpack-4 and next label to pull request to other branch + # add non-main, dev-1, webpack-4 and next label to pull request to other branch - filters: pull_request: - base_ref: "^master$" + base_ref: "^main$" actions: label: remove: - "PR: next" + - "PR: dev-1" - "PR: webpack-4" - - "PR: non-master" + - "PR: non-main" + - filters: + pull_request: + base_ref: "^dev-1$" + actions: + label: + add: "PR: dev-1" + remove: + - "PR: next" + - "PR: webpack-4" + - "PR: non-main" - filters: pull_request: base_ref: "^next$" @@ -246,8 +122,9 @@ rules: label: add: "PR: next" remove: + - "PR: dev-1" - "PR: webpack-4" - - "PR: non-master" + - "PR: non-main" - filters: pull_request: base_ref: "^webpack-4$" @@ -255,65 +132,42 @@ rules: label: add: "PR: webpack-4" remove: + - "PR: dev-1" - "PR: next" - - "PR: non-master" + - "PR: non-main" - filters: pull_request: - base_ref: "^(?!master$)(?!webpack-4$)(?!next$)" + base_ref: "^(?!main$)(?!webpack-4$)(?!next$)" actions: label: - add: "PR: non-master" + add: "PR: non-main" remove: + - "PR: dev-1" - "PR: next" - "PR: webpack-4" - # add non-master label to pull request to other branch + # show hint about contributing - filters: open: true age: minimum: 1d maximum: 1w pull_request: - head_ref: "^master$" + head_ref: "^main$" permission: "read|none" actions: comment: - identifier: "head-master" + identifier: "head-main" edit: true message: |- Hi @{{pull_request.user.login}}. Just a little hint from a friendly bot about the best practice when submitting pull requests: - > Don't submit pull request from your own `master` branch. It's recommended to create a feature branch for the PR. + > Don't submit pull request from your own `main` branch. It's recommended to create a feature branch for the PR. *You don't have to change it for this PR, just make sure to follow this hint the next time you submit a PR.* - # skip CLA for dependabot - - filters: - open: true - pull_request: - author: "^dependabot(-preview)?\\[bot\\]$" - status: - context: "licence/cla" - state: "pending" - actions: - status: - context: "licence/cla" - description: "Contributor License Agreement is not needed for this user." - state: "success" - - # merge dependabot PRs automatically - - filters: - open: true - pull_request: - author: "^dependabot(-preview)?\\[bot\\]$" - mergeable_state: clean - merged: false - label: "PR: CI-ok" - actions: - merge: true - # add "Send a PR" label when somebody with write permission say it - filters: open: true @@ -466,158 +320,6 @@ rules: message: |- I've created an issue to backport this. - # Ask for tags on new issues - - filters: - open: true - issue: true - age: - maximum: 1w - any: - not_1: - any: - label_1: webpack-4 - label_2: webpack-5 - not_2: - any: - label_1: bug - label_2: critical-bug - label_3: enhancement - label_4: documentation - label_5: performance - label_6: dependencies - label_7: question - not: - comment: - author: webpack-bot - matching: admin-actions - actions: - comment: - identifier: admin-actions - edit: true - message: |- - *For maintainers only:* - - * [ ] webpack-4 - * [ ] webpack-5 - * [ ] bug - * [ ] critical-bug - * [ ] enhancement - * [ ] documentation - * [ ] performance - * [ ] dependencies - * [ ] question - - # Apply selected tags - - filters: - open: true - issue: true - comment: - author: webpack-bot - matching: "\\* \\[x\\] webpack-4" - actions: - label: webpack-4 - - filters: - open: true - issue: true - comment: - author: webpack-bot - matching: "\\* \\[x\\] webpack-5" - actions: - label: webpack-5 - - filters: - open: true - issue: true - comment: - author: webpack-bot - matching: "\\* \\[x\\] bug" - actions: - label: bug - - filters: - open: true - issue: true - comment: - author: webpack-bot - matching: "\\* \\[x\\] critical-bug" - actions: - label: critical-bug - - filters: - open: true - issue: true - comment: - author: webpack-bot - matching: "\\* \\[x\\] enhancement" - actions: - label: enhancement - - filters: - open: true - issue: true - comment: - author: webpack-bot - matching: "\\* \\[x\\] performance" - actions: - label: performance - - filters: - open: true - issue: true - comment: - author: webpack-bot - matching: "\\* \\[x\\] dependencies" - actions: - label: dependencies - - filters: - open: true - issue: true - comment: - author: webpack-bot - matching: "\\* \\[x\\] question" - actions: - label: question - - # Remove question about tags again - - filters: - open: true - issue: true - any_1: - label_1: webpack-4 - label_2: webpack-5 - any_2: - label_1: bug - label_2: critical-bug - label_3: enhancement - label_4: documentation - label_5: performance - label_6: dependencies - label_7: question - comment: - author: webpack-bot - matching: admin-actions - actions: - schedule: 30s - - filters: - open: true - issue: true - any_1: - label_1: webpack-4 - label_2: webpack-5 - any_2: - label_1: bug - label_2: critical-bug - label_3: enhancement - label_4: documentation - label_5: performance - label_6: dependencies - label_7: question - comment: - author: webpack-bot - matching: admin-actions - last_action_age: - minimum: 30s - includeBotActions: true - actions: - comment: - identifier: admin-actions - message: "" - # Check open issues and pull requests every day - filters: open: true diff --git a/package.json b/package.json index c6c56bbadf8..6648f5be355 100644 --- a/package.json +++ b/package.json @@ -1,33 +1,33 @@ { "name": "webpack", - "version": "5.27.2", + "version": "5.94.0", "author": "Tobias Koppers @sokra", - "description": "Packs CommonJs/AMD modules for the browser. Allows to split your codebase into multiple bundles, which can be loaded on demand. Support loaders to preprocess files, i.e. json, jsx, es7, css, less, ... and your custom stuff.", + "description": "Packs ECMAScript/CommonJs/AMD modules for the browser. Allows you to split your codebase into multiple bundles, which can be loaded on demand. Supports loaders to preprocess files, i.e. json, jsx, es7, css, less, ... and your custom stuff.", "license": "MIT", "dependencies": { - "@types/eslint-scope": "^3.7.0", - "@types/estree": "^0.0.46", - "@webassemblyjs/ast": "1.11.0", - "@webassemblyjs/wasm-edit": "1.11.0", - "@webassemblyjs/wasm-parser": "1.11.0", - "acorn": "^8.0.4", - "browserslist": "^4.14.5", + "@types/estree": "^1.0.5", + "@webassemblyjs/ast": "^1.12.1", + "@webassemblyjs/wasm-edit": "^1.12.1", + "@webassemblyjs/wasm-parser": "^1.12.1", + "acorn": "^8.7.1", + "acorn-import-attributes": "^1.9.5", + "browserslist": "^4.21.10", "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.7.0", - "es-module-lexer": "^0.4.0", - "eslint-scope": "^5.1.1", + "enhanced-resolve": "^5.17.1", + "es-module-lexer": "^1.2.1", + "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", + "graceful-fs": "^4.2.11", + "json-parse-even-better-errors": "^2.3.1", "loader-runner": "^4.2.0", "mime-types": "^2.1.27", "neo-async": "^2.6.2", - "schema-utils": "^3.0.0", + "schema-utils": "^3.2.0", "tapable": "^2.1.1", - "terser-webpack-plugin": "^5.1.1", - "watchpack": "^2.0.0", - "webpack-sources": "^2.1.1" + "terser-webpack-plugin": "^5.3.10", + "watchpack": "^2.4.1", + "webpack-sources": "^3.2.3" }, "peerDependenciesMeta": { "webpack-cli": { @@ -35,73 +35,84 @@ } }, "devDependencies": { - "@babel/core": "^7.11.1", - "@babel/preset-react": "^7.10.4", - "@types/es-module-lexer": "^0.3.0", - "@types/jest": "^26.0.15", - "@types/node": "^14.14.10", - "babel-loader": "^8.1.0", + "@babel/core": "^7.24.7", + "@babel/preset-react": "^7.24.7", + "@eslint/js": "^9.5.0", + "@stylistic/eslint-plugin": "^2.4.0", + "@types/eslint-scope": "^3.7.7", + "@types/glob-to-regexp": "^0.4.4", + "@types/jest": "^29.5.11", + "@types/mime-types": "^2.1.4", + "@types/node": "^22.0.0", + "assemblyscript": "^0.27.22", + "babel-loader": "^9.1.3", "benchmark": "^2.1.4", "bundle-loader": "^0.5.6", - "coffee-loader": "^1.0.0", + "coffee-loader": "^5.0.0", "coffeescript": "^2.5.1", "core-js": "^3.6.5", - "coveralls": "^3.1.0", - "cspell": "^4.0.63", - "css-loader": "^5.0.1", - "date-fns": "^2.15.0", + "cspell": "^8.8.4", + "css-loader": "^7.1.2", + "date-fns": "^3.2.0", "es5-ext": "^0.10.53", "es6-promise-polyfill": "^1.2.0", - "eslint": "^7.14.0", - "eslint-config-prettier": "^7.0.0", - "eslint-plugin-jest": "^24.1.3", - "eslint-plugin-jsdoc": "^32.0.2", - "eslint-plugin-node": "^11.0.0", - "eslint-plugin-prettier": "^3.1.4", + "eslint": "^9.5.0", + "eslint-config-prettier": "^9.1.0", + "eslint-plugin-jest": "^28.6.0", + "eslint-plugin-jsdoc": "^48.10.1", + "eslint-plugin-n": "^17.8.1", + "eslint-plugin-prettier": "^5.1.3", + "eslint-plugin-unicorn": "^55.0.0", "file-loader": "^6.0.0", - "fork-ts-checker-webpack-plugin": "^6.0.5", - "husky": "^5.1.2", + "fork-ts-checker-webpack-plugin": "^9.0.2", + "globals": "^15.4.0", + "hash-wasm": "^4.9.0", + "husky": "^9.0.11", "is-ci": "^3.0.0", "istanbul": "^0.4.5", - "jest": "^26.6.3", - "jest-diff": "^26.6.2", - "jest-junit": "^12.0.0", + "jest": "^29.7.0", + "jest-circus": "^29.7.0", + "jest-cli": "^29.7.0", + "jest-diff": "^29.7.0", + "jest-environment-node": "^29.7.0", + "jest-junit": "^16.0.0", "json-loader": "^0.5.7", "json5": "^2.1.3", "less": "^4.0.0", - "less-loader": "^8.0.0", - "lint-staged": "^10.2.11", - "loader-utils": "^2.0.0", + "less-loader": "^12.2.0", + "lint-staged": "^15.2.5", "lodash": "^4.17.19", "lodash-es": "^4.17.15", - "memfs": "^3.2.0", - "mini-css-extract-plugin": "^1.0.0", + "memfs": "^4.9.2", + "mini-css-extract-plugin": "^2.9.0", "mini-svg-data-uri": "^1.2.3", - "open-cli": "^6.0.1", - "prettier": "^2.2.0", - "pretty-format": "^26.3.0", - "pug": "^3.0.0", + "nyc": "^17.0.0", + "open-cli": "^8.0.0", + "prettier": "^3.2.1", + "prettier-2": "npm:prettier@^2", + "pretty-format": "^29.5.0", + "pug": "^3.0.3", "pug-loader": "^2.4.0", "raw-loader": "^4.0.1", - "react": "^17.0.1", - "react-dom": "^17.0.1", + "react": "^18.3.1", + "react-dom": "^18.3.1", "rimraf": "^3.0.2", "script-loader": "^0.7.2", - "simple-git": "^2.17.0", + "simple-git": "^3.25.0", "strip-ansi": "^6.0.0", - "style-loader": "^2.0.0", - "terser": "^5.5.0", + "style-loader": "^4.0.0", + "terser": "^5.31.1", "toml": "^3.0.0", - "tooling": "webpack/tooling#v1.14.1", - "ts-loader": "^8.0.2", - "typescript": "^4.2.0-beta", + "tooling": "webpack/tooling#v1.23.3", + "ts-loader": "^9.5.1", + "typescript": "^5.4.2", "url-loader": "^4.1.0", - "wast-loader": "^1.11.0", + "wast-loader": "^1.12.1", "webassembly-feature": "1.3.0", - "webpack-cli": "^4.3.0", + "webpack-cli": "^5.0.1", "xxhashjs": "^0.2.2", "yamljs": "^0.3.0", - "yarn-deduplicate": "^3.1.0" + "yarn-deduplicate": "^6.0.1" }, "engines": { "node": ">=10.13.0" @@ -115,6 +126,7 @@ "url": "https://opencollective.com/webpack" }, "homepage": "https://github.com/webpack/webpack", + "bugs": "https://github.com/webpack/webpack/issues", "main": "lib/index.js", "bin": { "webpack": "bin/webpack.js" @@ -126,107 +138,56 @@ "hot/", "schemas/", "SECURITY.md", + "module.d.ts", "types.d.ts" ], "scripts": { "setup": "node ./setup/setup.js", - "test": "node --max-old-space-size=4096 --trace-deprecation node_modules/jest-cli/bin/jest", + "jest": "node --expose-gc --max-old-space-size=4096 --experimental-vm-modules --trace-deprecation node_modules/jest-cli/bin/jest --logHeapUsage", + "test": "node --expose-gc --max-old-space-size=4096 --experimental-vm-modules --trace-deprecation node_modules/jest-cli/bin/jest --logHeapUsage", "test:update-snapshots": "yarn jest -u", - "test:integration": "node --max-old-space-size=4096 --trace-deprecation node_modules/jest-cli/bin/jest --testMatch \"/test/*.test.js\"", - "test:basic": "node --max-old-space-size=4096 --trace-deprecation node_modules/jest-cli/bin/jest --testMatch \"/te{st/TestCasesNormal,st/StatsTestCases,st/ConfigTestCases}.test.js\"", - "test:unit": "node --max-old-space-size=4096 --trace-deprecation node_modules/jest-cli/bin/jest --testMatch \"/test/*.unittest.js\"", - "travis:integration": "yarn cover:integration --ci $JEST", - "travis:basic": "yarn cover:basic --ci $JEST", - "travis:lintunit": "yarn lint && yarn cover:unit --ci $JEST", - "travis:benchmark": "yarn benchmark --ci", - "appveyor:integration": "yarn cover:integration --ci %JEST%", - "appveyor:unit": "yarn cover:unit --ci %JEST%", - "appveyor:benchmark": "yarn benchmark --ci", + "test:integration": "node --expose-gc --max-old-space-size=4096 --experimental-vm-modules --trace-deprecation node_modules/jest-cli/bin/jest --logHeapUsage --testMatch \"/test/*.{basictest,longtest,test}.js\"", + "test:basic": "node --expose-gc --max-old-space-size=4096 --experimental-vm-modules --trace-deprecation node_modules/jest-cli/bin/jest --logHeapUsage --testMatch \"/test/*.basictest.js\"", + "test:unit": "node --max-old-space-size=4096 --experimental-vm-modules --trace-deprecation node_modules/jest-cli/bin/jest --testMatch \"/test/*.unittest.js\"", "build:examples": "cd examples && node buildAll.js", "type-report": "rimraf coverage && yarn cover:types && yarn cover:report && open-cli coverage/lcov-report/index.html", "pretest": "yarn lint", "prelint": "yarn setup", - "lint": "yarn code-lint && yarn special-lint && yarn type-lint && yarn typings-lint && yarn yarn-lint && yarn pretty-lint && yarn spellcheck", - "code-lint": "eslint . --ext '.js' --cache", + "lint": "yarn code-lint && yarn special-lint && yarn type-lint && yarn typings-test && yarn module-typings-test && yarn yarn-lint && yarn pretty-lint && yarn spellcheck", + "code-lint": "eslint --cache .", "type-lint": "tsc", - "typings-lint": "tsc -p tsconfig.test.json", - "spellcheck": "cspell \"{.github,benchmark,bin,examples,hot,lib,schemas,setup,tooling}/**/*.{md,yml,yaml,js,json}\" \"*.md\"", - "special-lint": "node node_modules/tooling/lockfile-lint && node node_modules/tooling/schemas-lint && node node_modules/tooling/inherit-types && node node_modules/tooling/format-schemas && node tooling/generate-runtime-code.js && node node_modules/tooling/format-file-header && node node_modules/tooling/compile-to-definitions && node node_modules/tooling/generate-types --no-template-literals", - "special-lint-fix": "node node_modules/tooling/inherit-types --write && node node_modules/tooling/format-schemas --write && node tooling/generate-runtime-code.js --write && node node_modules/tooling/format-file-header --write && node node_modules/tooling/compile-to-definitions --write && node node_modules/tooling/generate-types --no-template-literals --write", + "typings-test": "tsc -p tsconfig.types.test.json", + "module-typings-test": "tsc -p tsconfig.module.test.json", + "spellcheck": "cspell --cache --no-must-find-files --quiet \"**/*.*\"", + "special-lint": "node node_modules/tooling/lockfile-lint && node node_modules/tooling/schemas-lint && node node_modules/tooling/inherit-types && node node_modules/tooling/format-schemas && node tooling/generate-runtime-code.js && node tooling/generate-wasm-code.js && node node_modules/tooling/format-file-header && node node_modules/tooling/compile-to-definitions && node node_modules/tooling/precompile-schemas && node node_modules/tooling/generate-types --no-template-literals", + "special-lint-fix": "node node_modules/tooling/inherit-types --write && node node_modules/tooling/format-schemas --write && node tooling/generate-runtime-code.js --write && node tooling/generate-wasm-code.js --write && node node_modules/tooling/format-file-header --write && node node_modules/tooling/compile-to-definitions --write && node node_modules/tooling/precompile-schemas --write && node node_modules/tooling/generate-types --no-template-literals --write", "fix": "yarn code-lint --fix && yarn special-lint-fix && yarn pretty-lint-fix", - "prepare": "husky install", - "pretty-lint-base": "prettier \"*.{ts,json,yml,yaml,md}\" \"{setup,lib,bin,hot,benchmark,tooling,schemas}/**/*.json\" \"examples/*.md\"", - "pretty-lint-base-all": "yarn pretty-lint-base \"*.js\" \"{setup,lib,bin,hot,benchmark,tooling,schemas}/**/*.js\" \"test/*.js\" \"test/helpers/*.js\" \"test/{configCases,watchCases,statsCases,hotCases,benchmarkCases}/**/webpack.config.js\" \"examples/**/webpack.config.js\"", - "pretty-lint-fix": "yarn pretty-lint-base-all --loglevel warn --write", + "prepare": "husky", + "pretty-lint-base": "node node_modules/prettier/bin/prettier.cjs --cache --ignore-unknown .", + "pretty-lint-fix": "yarn pretty-lint-base --log-level warn --write", "pretty-lint": "yarn pretty-lint-base --check", "yarn-lint": "yarn-deduplicate --fail --list -s highest yarn.lock", "yarn-lint-fix": "yarn-deduplicate -s highest yarn.lock", - "benchmark": "node --max-old-space-size=4096 --trace-deprecation node_modules/jest-cli/bin/jest --testMatch \"/test/*.benchmark.js\" --runInBand", + "benchmark": "node --max-old-space-size=4096 --experimental-vm-modules --trace-deprecation node_modules/jest-cli/bin/jest --testMatch \"/test/*.benchmark.js\" --runInBand", "cover": "yarn cover:all && yarn cover:report", - "cover:all": "node --max-old-space-size=4096 node_modules/jest-cli/bin/jest --coverage", - "cover:basic": "node --max-old-space-size=4096 node_modules/jest-cli/bin/jest --testMatch \"/te{st/TestCasesNormal,st/StatsTestCases,st/ConfigTestCases}.test.js\" --coverage", - "cover:integration": "node --max-old-space-size=4096 node_modules/jest-cli/bin/jest --testMatch \"/test/*.test.js\" --coverage", - "cover:unit": "node --max-old-space-size=4096 node_modules/jest-cli/bin/jest --testMatch \"/test/*.unittest.js\" --coverage", + "cover:clean": "rimraf .nyc_output coverage", + "cover:all": "node --expose-gc --max-old-space-size=4096 --experimental-vm-modules node_modules/jest-cli/bin/jest --logHeapUsage --coverage", + "cover:basic": "node --expose-gc --max-old-space-size=4096 --experimental-vm-modules node_modules/jest-cli/bin/jest --logHeapUsage --testMatch \"/test/*.basictest.js\" --coverage", + "cover:integration": "node --expose-gc --max-old-space-size=4096 --experimental-vm-modules node_modules/jest-cli/bin/jest --logHeapUsage --testMatch \"/test/*.{basictest,longtest,test}.js\" --coverage", + "cover:integration:a": "node --expose-gc --max-old-space-size=4096 --experimental-vm-modules node_modules/jest-cli/bin/jest --logHeapUsage --testMatch \"/test/*.{basictest,test}.js\" --coverage", + "cover:integration:b": "node --expose-gc --max-old-space-size=4096 --experimental-vm-modules node_modules/jest-cli/bin/jest --logHeapUsage --testMatch \"/test/*.longtest.js\" --coverage", + "cover:unit": "node --max-old-space-size=4096 --experimental-vm-modules node_modules/jest-cli/bin/jest --testMatch \"/test/*.unittest.js\" --coverage", "cover:types": "node node_modules/tooling/type-coverage", - "cover:report": "istanbul report" + "cover:merge": "yarn mkdirp .nyc_output && nyc merge .nyc_output coverage/coverage-nyc.json && rimraf .nyc_output", + "cover:report": "nyc report --reporter=lcov --reporter=text -t coverage" }, "lint-staged": { - "*.js|{lib,setup,bin,hot,tooling,schemas}/**/*.js|test/*.js|{test,examples}/**/webpack.config.js}": [ - "eslint --cache" + "*.{js,cjs,mjs}": [ + "eslint --cache --fix" ], - "*.{ts,json,yml,yaml,md}|examples/*.md": [ - "prettier --check" - ], - "*.md|{.github,benchmark,bin,examples,hot,lib,schemas,setup,tooling}/**/*.{md,yml,yaml,js,json}": [ - "cspell" - ] - }, - "jest": { - "forceExit": true, - "setupFilesAfterEnv": [ - "/test/setupTestFramework.js" - ], - "testMatch": [ - "/test/*.test.js", - "/test/*.unittest.js" - ], - "watchPathIgnorePatterns": [ - "/.git", - "/node_modules", - "/test/js", - "/test/browsertest/js", - "/test/fixtures/temp-cache-fixture", - "/test/fixtures/temp-", - "/benchmark", - "/examples/*/dist", - "/coverage", - "/.eslintcache" - ], - "modulePathIgnorePatterns": [ - "/.git", - "/node_modules/webpack/node_modules", - "/test/js", - "/test/browsertest/js", - "/test/fixtures/temp-cache-fixture", - "/test/fixtures/temp-", - "/benchmark", - "/examples/*/dist", - "/coverage", - "/.eslintcache" - ], - "transformIgnorePatterns": [ - "" - ], - "coverageDirectory": "/coverage", - "coveragePathIgnorePatterns": [ - "\\.runtime\\.js$", - "/test", - "/schemas", - "/node_modules" - ], - "testEnvironment": "node", - "coverageReporters": [ - "json" + "*": [ + "node node_modules/prettier/bin/prettier.cjs --cache --write --ignore-unknown", + "cspell --cache --no-must-find-files" ] } } diff --git a/schemas/WebpackOptions.check.d.ts b/schemas/WebpackOptions.check.d.ts new file mode 100644 index 00000000000..16a82711ee8 --- /dev/null +++ b/schemas/WebpackOptions.check.d.ts @@ -0,0 +1,7 @@ +/* + * This file was automatically generated. + * DO NOT MODIFY BY HAND. + * Run `yarn special-lint-fix` to update + */ +declare const check: (options: import("../declarations/WebpackOptions").WebpackOptions) => boolean; +export = check; diff --git a/schemas/WebpackOptions.check.js b/schemas/WebpackOptions.check.js new file mode 100644 index 00000000000..a00a2860ea7 --- /dev/null +++ b/schemas/WebpackOptions.check.js @@ -0,0 +1,6 @@ +/* + * This file was automatically generated. + * DO NOT MODIFY BY HAND. + * Run `yarn special-lint-fix` to update + */ +const e=/^(?:[A-Za-z]:[\\/]|\\\\|\/)/;module.exports=_e,module.exports.default=_e;const t={definitions:{Amd:{anyOf:[{enum:[!1]},{type:"object"}]},AmdContainer:{type:"string",minLength:1},AssetFilterItemTypes:{anyOf:[{instanceof:"RegExp"},{type:"string",absolutePath:!1},{instanceof:"Function"}]},AssetFilterTypes:{anyOf:[{type:"array",items:{oneOf:[{$ref:"#/definitions/AssetFilterItemTypes"}]}},{$ref:"#/definitions/AssetFilterItemTypes"}]},AssetGeneratorDataUrl:{anyOf:[{$ref:"#/definitions/AssetGeneratorDataUrlOptions"},{$ref:"#/definitions/AssetGeneratorDataUrlFunction"}]},AssetGeneratorDataUrlFunction:{instanceof:"Function"},AssetGeneratorDataUrlOptions:{type:"object",additionalProperties:!1,properties:{encoding:{enum:[!1,"base64"]},mimetype:{type:"string"}}},AssetGeneratorOptions:{type:"object",additionalProperties:!1,properties:{binary:{type:"boolean"},dataUrl:{$ref:"#/definitions/AssetGeneratorDataUrl"},emit:{type:"boolean"},filename:{$ref:"#/definitions/FilenameTemplate"},outputPath:{$ref:"#/definitions/AssetModuleOutputPath"},publicPath:{$ref:"#/definitions/RawPublicPath"}}},AssetInlineGeneratorOptions:{type:"object",additionalProperties:!1,properties:{binary:{type:"boolean"},dataUrl:{$ref:"#/definitions/AssetGeneratorDataUrl"}}},AssetModuleFilename:{anyOf:[{type:"string",absolutePath:!1},{instanceof:"Function"}]},AssetModuleOutputPath:{anyOf:[{type:"string",absolutePath:!1},{instanceof:"Function"}]},AssetParserDataUrlFunction:{instanceof:"Function"},AssetParserDataUrlOptions:{type:"object",additionalProperties:!1,properties:{maxSize:{type:"number"}}},AssetParserOptions:{type:"object",additionalProperties:!1,properties:{dataUrlCondition:{anyOf:[{$ref:"#/definitions/AssetParserDataUrlOptions"},{$ref:"#/definitions/AssetParserDataUrlFunction"}]}}},AssetResourceGeneratorOptions:{type:"object",additionalProperties:!1,properties:{binary:{type:"boolean"},emit:{type:"boolean"},filename:{$ref:"#/definitions/FilenameTemplate"},outputPath:{$ref:"#/definitions/AssetModuleOutputPath"},publicPath:{$ref:"#/definitions/RawPublicPath"}}},AuxiliaryComment:{anyOf:[{type:"string"},{$ref:"#/definitions/LibraryCustomUmdCommentObject"}]},Bail:{type:"boolean"},CacheOptions:{anyOf:[{enum:[!0]},{$ref:"#/definitions/CacheOptionsNormalized"}]},CacheOptionsNormalized:{anyOf:[{enum:[!1]},{$ref:"#/definitions/MemoryCacheOptions"},{$ref:"#/definitions/FileCacheOptions"}]},Charset:{type:"boolean"},ChunkFilename:{oneOf:[{$ref:"#/definitions/FilenameTemplate"}]},ChunkFormat:{anyOf:[{enum:["array-push","commonjs","module",!1]},{type:"string"}]},ChunkLoadTimeout:{type:"number"},ChunkLoading:{anyOf:[{enum:[!1]},{$ref:"#/definitions/ChunkLoadingType"}]},ChunkLoadingGlobal:{type:"string"},ChunkLoadingType:{anyOf:[{enum:["jsonp","import-scripts","require","async-node","import"]},{type:"string"}]},Clean:{anyOf:[{type:"boolean"},{$ref:"#/definitions/CleanOptions"}]},CleanOptions:{type:"object",additionalProperties:!1,properties:{dry:{type:"boolean"},keep:{anyOf:[{instanceof:"RegExp"},{type:"string",absolutePath:!1},{instanceof:"Function"}]}}},CompareBeforeEmit:{type:"boolean"},Context:{type:"string",absolutePath:!0},CrossOriginLoading:{enum:[!1,"anonymous","use-credentials"]},CssAutoGeneratorOptions:{type:"object",additionalProperties:!1,properties:{esModule:{$ref:"#/definitions/CssGeneratorEsModule"},exportsConvention:{$ref:"#/definitions/CssGeneratorExportsConvention"},exportsOnly:{$ref:"#/definitions/CssGeneratorExportsOnly"},localIdentName:{$ref:"#/definitions/CssGeneratorLocalIdentName"}}},CssAutoParserOptions:{type:"object",additionalProperties:!1,properties:{namedExports:{$ref:"#/definitions/CssParserNamedExports"}}},CssChunkFilename:{oneOf:[{$ref:"#/definitions/FilenameTemplate"}]},CssFilename:{oneOf:[{$ref:"#/definitions/FilenameTemplate"}]},CssGeneratorEsModule:{type:"boolean"},CssGeneratorExportsConvention:{anyOf:[{enum:["as-is","camel-case","camel-case-only","dashes","dashes-only"]},{instanceof:"Function"}]},CssGeneratorExportsOnly:{type:"boolean"},CssGeneratorLocalIdentName:{type:"string"},CssGeneratorOptions:{type:"object",additionalProperties:!1,properties:{esModule:{$ref:"#/definitions/CssGeneratorEsModule"},exportsOnly:{$ref:"#/definitions/CssGeneratorExportsOnly"}}},CssGlobalGeneratorOptions:{type:"object",additionalProperties:!1,properties:{esModule:{$ref:"#/definitions/CssGeneratorEsModule"},exportsConvention:{$ref:"#/definitions/CssGeneratorExportsConvention"},exportsOnly:{$ref:"#/definitions/CssGeneratorExportsOnly"},localIdentName:{$ref:"#/definitions/CssGeneratorLocalIdentName"}}},CssGlobalParserOptions:{type:"object",additionalProperties:!1,properties:{namedExports:{$ref:"#/definitions/CssParserNamedExports"}}},CssHeadDataCompression:{type:"boolean"},CssModuleGeneratorOptions:{type:"object",additionalProperties:!1,properties:{esModule:{$ref:"#/definitions/CssGeneratorEsModule"},exportsConvention:{$ref:"#/definitions/CssGeneratorExportsConvention"},exportsOnly:{$ref:"#/definitions/CssGeneratorExportsOnly"},localIdentName:{$ref:"#/definitions/CssGeneratorLocalIdentName"}}},CssModuleParserOptions:{type:"object",additionalProperties:!1,properties:{namedExports:{$ref:"#/definitions/CssParserNamedExports"}}},CssParserNamedExports:{type:"boolean"},CssParserOptions:{type:"object",additionalProperties:!1,properties:{namedExports:{$ref:"#/definitions/CssParserNamedExports"}}},Dependencies:{type:"array",items:{type:"string"}},DevServer:{anyOf:[{enum:[!1]},{type:"object"}]},DevTool:{anyOf:[{enum:[!1,"eval"]},{type:"string",pattern:"^(inline-|hidden-|eval-)?(nosources-)?(cheap-(module-)?)?source-map$"}]},DevtoolFallbackModuleFilenameTemplate:{anyOf:[{type:"string"},{instanceof:"Function"}]},DevtoolModuleFilenameTemplate:{anyOf:[{type:"string"},{instanceof:"Function"}]},DevtoolNamespace:{type:"string"},EmptyGeneratorOptions:{type:"object",additionalProperties:!1},EmptyParserOptions:{type:"object",additionalProperties:!1},EnabledChunkLoadingTypes:{type:"array",items:{$ref:"#/definitions/ChunkLoadingType"}},EnabledLibraryTypes:{type:"array",items:{$ref:"#/definitions/LibraryType"}},EnabledWasmLoadingTypes:{type:"array",items:{$ref:"#/definitions/WasmLoadingType"}},Entry:{anyOf:[{$ref:"#/definitions/EntryDynamic"},{$ref:"#/definitions/EntryStatic"}]},EntryDescription:{type:"object",additionalProperties:!1,properties:{asyncChunks:{type:"boolean"},baseUri:{type:"string"},chunkLoading:{$ref:"#/definitions/ChunkLoading"},dependOn:{anyOf:[{type:"array",items:{type:"string",minLength:1},minItems:1,uniqueItems:!0},{type:"string",minLength:1}]},filename:{$ref:"#/definitions/EntryFilename"},import:{$ref:"#/definitions/EntryItem"},layer:{$ref:"#/definitions/Layer"},library:{$ref:"#/definitions/LibraryOptions"},publicPath:{$ref:"#/definitions/PublicPath"},runtime:{$ref:"#/definitions/EntryRuntime"},wasmLoading:{$ref:"#/definitions/WasmLoading"}},required:["import"]},EntryDescriptionNormalized:{type:"object",additionalProperties:!1,properties:{asyncChunks:{type:"boolean"},baseUri:{type:"string"},chunkLoading:{$ref:"#/definitions/ChunkLoading"},dependOn:{type:"array",items:{type:"string",minLength:1},minItems:1,uniqueItems:!0},filename:{$ref:"#/definitions/Filename"},import:{type:"array",items:{type:"string",minLength:1},minItems:1,uniqueItems:!0},layer:{$ref:"#/definitions/Layer"},library:{$ref:"#/definitions/LibraryOptions"},publicPath:{$ref:"#/definitions/PublicPath"},runtime:{$ref:"#/definitions/EntryRuntime"},wasmLoading:{$ref:"#/definitions/WasmLoading"}}},EntryDynamic:{instanceof:"Function"},EntryDynamicNormalized:{instanceof:"Function"},EntryFilename:{oneOf:[{$ref:"#/definitions/FilenameTemplate"}]},EntryItem:{anyOf:[{type:"array",items:{type:"string",minLength:1},minItems:1,uniqueItems:!0},{type:"string",minLength:1}]},EntryNormalized:{anyOf:[{$ref:"#/definitions/EntryDynamicNormalized"},{$ref:"#/definitions/EntryStaticNormalized"}]},EntryObject:{type:"object",additionalProperties:{anyOf:[{$ref:"#/definitions/EntryItem"},{$ref:"#/definitions/EntryDescription"}]}},EntryRuntime:{anyOf:[{enum:[!1]},{type:"string",minLength:1}]},EntryStatic:{anyOf:[{$ref:"#/definitions/EntryObject"},{$ref:"#/definitions/EntryUnnamed"}]},EntryStaticNormalized:{type:"object",additionalProperties:{oneOf:[{$ref:"#/definitions/EntryDescriptionNormalized"}]}},EntryUnnamed:{oneOf:[{$ref:"#/definitions/EntryItem"}]},Environment:{type:"object",additionalProperties:!1,properties:{arrowFunction:{type:"boolean"},asyncFunction:{type:"boolean"},bigIntLiteral:{type:"boolean"},const:{type:"boolean"},destructuring:{type:"boolean"},document:{type:"boolean"},dynamicImport:{type:"boolean"},dynamicImportInWorker:{type:"boolean"},forOf:{type:"boolean"},globalThis:{type:"boolean"},module:{type:"boolean"},nodePrefixForCoreModules:{type:"boolean"},optionalChaining:{type:"boolean"},templateLiteral:{type:"boolean"}}},Experiments:{type:"object",additionalProperties:!1,properties:{asyncWebAssembly:{type:"boolean"},backCompat:{type:"boolean"},buildHttp:{anyOf:[{$ref:"#/definitions/HttpUriAllowedUris"},{$ref:"#/definitions/HttpUriOptions"}]},cacheUnaffected:{type:"boolean"},css:{type:"boolean"},futureDefaults:{type:"boolean"},layers:{type:"boolean"},lazyCompilation:{anyOf:[{type:"boolean"},{$ref:"#/definitions/LazyCompilationOptions"}]},outputModule:{type:"boolean"},syncWebAssembly:{type:"boolean"},topLevelAwait:{type:"boolean"}}},ExperimentsCommon:{type:"object",additionalProperties:!1,properties:{asyncWebAssembly:{type:"boolean"},backCompat:{type:"boolean"},cacheUnaffected:{type:"boolean"},futureDefaults:{type:"boolean"},layers:{type:"boolean"},outputModule:{type:"boolean"},syncWebAssembly:{type:"boolean"},topLevelAwait:{type:"boolean"}}},ExperimentsNormalized:{type:"object",additionalProperties:!1,properties:{asyncWebAssembly:{type:"boolean"},backCompat:{type:"boolean"},buildHttp:{oneOf:[{$ref:"#/definitions/HttpUriOptions"}]},cacheUnaffected:{type:"boolean"},css:{type:"boolean"},futureDefaults:{type:"boolean"},layers:{type:"boolean"},lazyCompilation:{anyOf:[{enum:[!1]},{$ref:"#/definitions/LazyCompilationOptions"}]},outputModule:{type:"boolean"},syncWebAssembly:{type:"boolean"},topLevelAwait:{type:"boolean"}}},Extends:{anyOf:[{type:"array",items:{$ref:"#/definitions/ExtendsItem"}},{$ref:"#/definitions/ExtendsItem"}]},ExtendsItem:{type:"string"},ExternalItem:{anyOf:[{instanceof:"RegExp"},{type:"string"},{type:"object",additionalProperties:{$ref:"#/definitions/ExternalItemValue"},properties:{byLayer:{anyOf:[{type:"object",additionalProperties:{$ref:"#/definitions/ExternalItem"}},{instanceof:"Function"}]}}},{instanceof:"Function"}]},ExternalItemFunctionData:{type:"object",additionalProperties:!1,properties:{context:{type:"string"},contextInfo:{type:"object"},dependencyType:{type:"string"},getResolve:{instanceof:"Function"},request:{type:"string"}}},ExternalItemValue:{anyOf:[{type:"array",items:{type:"string",minLength:1}},{type:"boolean"},{type:"string"},{type:"object"}]},Externals:{anyOf:[{type:"array",items:{$ref:"#/definitions/ExternalItem"}},{$ref:"#/definitions/ExternalItem"}]},ExternalsPresets:{type:"object",additionalProperties:!1,properties:{electron:{type:"boolean"},electronMain:{type:"boolean"},electronPreload:{type:"boolean"},electronRenderer:{type:"boolean"},node:{type:"boolean"},nwjs:{type:"boolean"},web:{type:"boolean"},webAsync:{type:"boolean"}}},ExternalsType:{enum:["var","module","assign","this","window","self","global","commonjs","commonjs2","commonjs-module","commonjs-static","amd","amd-require","umd","umd2","jsonp","system","promise","import","module-import","script","node-commonjs"]},Falsy:{enum:[!1,0,"",null],undefinedAsNull:!0},FileCacheOptions:{type:"object",additionalProperties:!1,properties:{allowCollectingMemory:{type:"boolean"},buildDependencies:{type:"object",additionalProperties:{type:"array",items:{type:"string",minLength:1}}},cacheDirectory:{type:"string",absolutePath:!0},cacheLocation:{type:"string",absolutePath:!0},compression:{enum:[!1,"gzip","brotli"]},hashAlgorithm:{type:"string"},idleTimeout:{type:"number",minimum:0},idleTimeoutAfterLargeChanges:{type:"number",minimum:0},idleTimeoutForInitialStore:{type:"number",minimum:0},immutablePaths:{type:"array",items:{anyOf:[{instanceof:"RegExp"},{type:"string",absolutePath:!0,minLength:1}]}},managedPaths:{type:"array",items:{anyOf:[{instanceof:"RegExp"},{type:"string",absolutePath:!0,minLength:1}]}},maxAge:{type:"number",minimum:0},maxMemoryGenerations:{type:"number",minimum:0},memoryCacheUnaffected:{type:"boolean"},name:{type:"string"},profile:{type:"boolean"},readonly:{type:"boolean"},store:{enum:["pack"]},type:{enum:["filesystem"]},version:{type:"string"}},required:["type"]},Filename:{oneOf:[{$ref:"#/definitions/FilenameTemplate"}]},FilenameTemplate:{anyOf:[{type:"string",absolutePath:!1,minLength:1},{instanceof:"Function"}]},FilterItemTypes:{anyOf:[{instanceof:"RegExp"},{type:"string",absolutePath:!1},{instanceof:"Function"}]},FilterTypes:{anyOf:[{type:"array",items:{oneOf:[{$ref:"#/definitions/FilterItemTypes"}]}},{$ref:"#/definitions/FilterItemTypes"}]},GeneratorOptionsByModuleType:{type:"object",additionalProperties:{type:"object",additionalProperties:!0},properties:{asset:{$ref:"#/definitions/AssetGeneratorOptions"},"asset/inline":{$ref:"#/definitions/AssetInlineGeneratorOptions"},"asset/resource":{$ref:"#/definitions/AssetResourceGeneratorOptions"},css:{$ref:"#/definitions/CssGeneratorOptions"},"css/auto":{$ref:"#/definitions/CssAutoGeneratorOptions"},"css/global":{$ref:"#/definitions/CssGlobalGeneratorOptions"},"css/module":{$ref:"#/definitions/CssModuleGeneratorOptions"},javascript:{$ref:"#/definitions/EmptyGeneratorOptions"},"javascript/auto":{$ref:"#/definitions/EmptyGeneratorOptions"},"javascript/dynamic":{$ref:"#/definitions/EmptyGeneratorOptions"},"javascript/esm":{$ref:"#/definitions/EmptyGeneratorOptions"}}},GlobalObject:{type:"string",minLength:1},HashDigest:{type:"string"},HashDigestLength:{type:"number",minimum:1},HashFunction:{anyOf:[{type:"string",minLength:1},{instanceof:"Function"}]},HashSalt:{type:"string",minLength:1},HotUpdateChunkFilename:{type:"string",absolutePath:!1},HotUpdateGlobal:{type:"string"},HotUpdateMainFilename:{type:"string",absolutePath:!1},HttpUriAllowedUris:{oneOf:[{$ref:"#/definitions/HttpUriOptionsAllowedUris"}]},HttpUriOptions:{type:"object",additionalProperties:!1,properties:{allowedUris:{$ref:"#/definitions/HttpUriOptionsAllowedUris"},cacheLocation:{anyOf:[{enum:[!1]},{type:"string",absolutePath:!0}]},frozen:{type:"boolean"},lockfileLocation:{type:"string",absolutePath:!0},proxy:{type:"string"},upgrade:{type:"boolean"}},required:["allowedUris"]},HttpUriOptionsAllowedUris:{type:"array",items:{anyOf:[{instanceof:"RegExp"},{type:"string",pattern:"^https?://"},{instanceof:"Function"}]}},IgnoreWarnings:{type:"array",items:{anyOf:[{instanceof:"RegExp"},{type:"object",additionalProperties:!1,properties:{file:{instanceof:"RegExp"},message:{instanceof:"RegExp"},module:{instanceof:"RegExp"}}},{instanceof:"Function"}]}},IgnoreWarningsNormalized:{type:"array",items:{instanceof:"Function"}},Iife:{type:"boolean"},ImportFunctionName:{type:"string"},ImportMetaName:{type:"string"},InfrastructureLogging:{type:"object",additionalProperties:!1,properties:{appendOnly:{type:"boolean"},colors:{type:"boolean"},console:{},debug:{anyOf:[{type:"boolean"},{$ref:"#/definitions/FilterTypes"}]},level:{enum:["none","error","warn","info","log","verbose"]},stream:{}}},JavascriptParserOptions:{type:"object",additionalProperties:!0,properties:{amd:{$ref:"#/definitions/Amd"},browserify:{type:"boolean"},commonjs:{type:"boolean"},commonjsMagicComments:{type:"boolean"},createRequire:{anyOf:[{type:"boolean"},{type:"string"}]},dynamicImportFetchPriority:{enum:["low","high","auto",!1]},dynamicImportMode:{enum:["eager","weak","lazy","lazy-once"]},dynamicImportPrefetch:{anyOf:[{type:"number"},{type:"boolean"}]},dynamicImportPreload:{anyOf:[{type:"number"},{type:"boolean"}]},exportsPresence:{enum:["error","warn","auto",!1]},exprContextCritical:{type:"boolean"},exprContextRecursive:{type:"boolean"},exprContextRegExp:{anyOf:[{instanceof:"RegExp"},{type:"boolean"}]},exprContextRequest:{type:"string"},harmony:{type:"boolean"},import:{type:"boolean"},importExportsPresence:{enum:["error","warn","auto",!1]},importMeta:{type:"boolean"},importMetaContext:{type:"boolean"},node:{$ref:"#/definitions/Node"},overrideStrict:{enum:["strict","non-strict"]},reexportExportsPresence:{enum:["error","warn","auto",!1]},requireContext:{type:"boolean"},requireEnsure:{type:"boolean"},requireInclude:{type:"boolean"},requireJs:{type:"boolean"},strictExportPresence:{type:"boolean"},strictThisContextOnImports:{type:"boolean"},system:{type:"boolean"},unknownContextCritical:{type:"boolean"},unknownContextRecursive:{type:"boolean"},unknownContextRegExp:{anyOf:[{instanceof:"RegExp"},{type:"boolean"}]},unknownContextRequest:{type:"string"},url:{anyOf:[{enum:["relative"]},{type:"boolean"}]},worker:{anyOf:[{type:"array",items:{type:"string",minLength:1}},{type:"boolean"}]},wrappedContextCritical:{type:"boolean"},wrappedContextRecursive:{type:"boolean"},wrappedContextRegExp:{instanceof:"RegExp"}}},Layer:{anyOf:[{enum:[null]},{type:"string",minLength:1}]},LazyCompilationDefaultBackendOptions:{type:"object",additionalProperties:!1,properties:{client:{type:"string"},listen:{anyOf:[{type:"number"},{type:"object",additionalProperties:!0,properties:{host:{type:"string"},port:{type:"number"}}},{instanceof:"Function"}]},protocol:{enum:["http","https"]},server:{anyOf:[{type:"object",additionalProperties:!0,properties:{}},{instanceof:"Function"}]}}},LazyCompilationOptions:{type:"object",additionalProperties:!1,properties:{backend:{anyOf:[{instanceof:"Function"},{$ref:"#/definitions/LazyCompilationDefaultBackendOptions"}]},entries:{type:"boolean"},imports:{type:"boolean"},test:{anyOf:[{instanceof:"RegExp"},{type:"string"},{instanceof:"Function"}]}}},Library:{anyOf:[{$ref:"#/definitions/LibraryName"},{$ref:"#/definitions/LibraryOptions"}]},LibraryCustomUmdCommentObject:{type:"object",additionalProperties:!1,properties:{amd:{type:"string"},commonjs:{type:"string"},commonjs2:{type:"string"},root:{type:"string"}}},LibraryCustomUmdObject:{type:"object",additionalProperties:!1,properties:{amd:{type:"string",minLength:1},commonjs:{type:"string",minLength:1},root:{anyOf:[{type:"array",items:{type:"string",minLength:1}},{type:"string",minLength:1}]}}},LibraryExport:{anyOf:[{type:"array",items:{type:"string",minLength:1}},{type:"string",minLength:1}]},LibraryName:{anyOf:[{type:"array",items:{type:"string",minLength:1},minItems:1},{type:"string",minLength:1},{$ref:"#/definitions/LibraryCustomUmdObject"}]},LibraryOptions:{type:"object",additionalProperties:!1,properties:{amdContainer:{$ref:"#/definitions/AmdContainer"},auxiliaryComment:{$ref:"#/definitions/AuxiliaryComment"},export:{$ref:"#/definitions/LibraryExport"},name:{$ref:"#/definitions/LibraryName"},type:{$ref:"#/definitions/LibraryType"},umdNamedDefine:{$ref:"#/definitions/UmdNamedDefine"}},required:["type"]},LibraryType:{anyOf:[{enum:["var","module","assign","assign-properties","this","window","self","global","commonjs","commonjs2","commonjs-module","commonjs-static","amd","amd-require","umd","umd2","jsonp","system"]},{type:"string"}]},Loader:{type:"object"},MemoryCacheOptions:{type:"object",additionalProperties:!1,properties:{cacheUnaffected:{type:"boolean"},maxGenerations:{type:"number",minimum:1},type:{enum:["memory"]}},required:["type"]},Mode:{enum:["development","production","none"]},ModuleFilterItemTypes:{anyOf:[{instanceof:"RegExp"},{type:"string",absolutePath:!1},{instanceof:"Function"}]},ModuleFilterTypes:{anyOf:[{type:"array",items:{oneOf:[{$ref:"#/definitions/ModuleFilterItemTypes"}]}},{$ref:"#/definitions/ModuleFilterItemTypes"}]},ModuleOptions:{type:"object",additionalProperties:!1,properties:{defaultRules:{oneOf:[{$ref:"#/definitions/RuleSetRules"}]},exprContextCritical:{type:"boolean"},exprContextRecursive:{type:"boolean"},exprContextRegExp:{anyOf:[{instanceof:"RegExp"},{type:"boolean"}]},exprContextRequest:{type:"string"},generator:{$ref:"#/definitions/GeneratorOptionsByModuleType"},noParse:{$ref:"#/definitions/NoParse"},parser:{$ref:"#/definitions/ParserOptionsByModuleType"},rules:{oneOf:[{$ref:"#/definitions/RuleSetRules"}]},strictExportPresence:{type:"boolean"},strictThisContextOnImports:{type:"boolean"},unknownContextCritical:{type:"boolean"},unknownContextRecursive:{type:"boolean"},unknownContextRegExp:{anyOf:[{instanceof:"RegExp"},{type:"boolean"}]},unknownContextRequest:{type:"string"},unsafeCache:{anyOf:[{type:"boolean"},{instanceof:"Function"}]},wrappedContextCritical:{type:"boolean"},wrappedContextRecursive:{type:"boolean"},wrappedContextRegExp:{instanceof:"RegExp"}}},ModuleOptionsNormalized:{type:"object",additionalProperties:!1,properties:{defaultRules:{oneOf:[{$ref:"#/definitions/RuleSetRules"}]},generator:{$ref:"#/definitions/GeneratorOptionsByModuleType"},noParse:{$ref:"#/definitions/NoParse"},parser:{$ref:"#/definitions/ParserOptionsByModuleType"},rules:{oneOf:[{$ref:"#/definitions/RuleSetRules"}]},unsafeCache:{anyOf:[{type:"boolean"},{instanceof:"Function"}]}},required:["defaultRules","generator","parser","rules"]},Name:{type:"string"},NoParse:{anyOf:[{type:"array",items:{anyOf:[{instanceof:"RegExp"},{type:"string",absolutePath:!0},{instanceof:"Function"}]},minItems:1},{instanceof:"RegExp"},{type:"string",absolutePath:!0},{instanceof:"Function"}]},Node:{anyOf:[{enum:[!1]},{$ref:"#/definitions/NodeOptions"}]},NodeOptions:{type:"object",additionalProperties:!1,properties:{__dirname:{enum:[!1,!0,"warn-mock","mock","node-module","eval-only"]},__filename:{enum:[!1,!0,"warn-mock","mock","node-module","eval-only"]},global:{enum:[!1,!0,"warn"]}}},Optimization:{type:"object",additionalProperties:!1,properties:{checkWasmTypes:{type:"boolean"},chunkIds:{enum:["natural","named","deterministic","size","total-size",!1]},concatenateModules:{type:"boolean"},emitOnErrors:{type:"boolean"},flagIncludedChunks:{type:"boolean"},innerGraph:{type:"boolean"},mangleExports:{anyOf:[{enum:["size","deterministic"]},{type:"boolean"}]},mangleWasmImports:{type:"boolean"},mergeDuplicateChunks:{type:"boolean"},minimize:{type:"boolean"},minimizer:{type:"array",items:{anyOf:[{enum:["..."]},{$ref:"#/definitions/Falsy"},{$ref:"#/definitions/WebpackPluginInstance"},{$ref:"#/definitions/WebpackPluginFunction"}]}},moduleIds:{enum:["natural","named","hashed","deterministic","size",!1]},noEmitOnErrors:{type:"boolean"},nodeEnv:{anyOf:[{enum:[!1]},{type:"string"}]},portableRecords:{type:"boolean"},providedExports:{type:"boolean"},realContentHash:{type:"boolean"},removeAvailableModules:{type:"boolean"},removeEmptyChunks:{type:"boolean"},runtimeChunk:{$ref:"#/definitions/OptimizationRuntimeChunk"},sideEffects:{anyOf:[{enum:["flag"]},{type:"boolean"}]},splitChunks:{anyOf:[{enum:[!1]},{$ref:"#/definitions/OptimizationSplitChunksOptions"}]},usedExports:{anyOf:[{enum:["global"]},{type:"boolean"}]}}},OptimizationRuntimeChunk:{anyOf:[{enum:["single","multiple"]},{type:"boolean"},{type:"object",additionalProperties:!1,properties:{name:{anyOf:[{type:"string"},{instanceof:"Function"}]}}}]},OptimizationRuntimeChunkNormalized:{anyOf:[{enum:[!1]},{type:"object",additionalProperties:!1,properties:{name:{instanceof:"Function"}}}]},OptimizationSplitChunksCacheGroup:{type:"object",additionalProperties:!1,properties:{automaticNameDelimiter:{type:"string",minLength:1},chunks:{anyOf:[{enum:["initial","async","all"]},{instanceof:"RegExp"},{instanceof:"Function"}]},enforce:{type:"boolean"},enforceSizeThreshold:{oneOf:[{$ref:"#/definitions/OptimizationSplitChunksSizes"}]},filename:{anyOf:[{type:"string",absolutePath:!1,minLength:1},{instanceof:"Function"}]},idHint:{type:"string"},layer:{anyOf:[{instanceof:"RegExp"},{type:"string"},{instanceof:"Function"}]},maxAsyncRequests:{type:"number",minimum:1},maxAsyncSize:{oneOf:[{$ref:"#/definitions/OptimizationSplitChunksSizes"}]},maxInitialRequests:{type:"number",minimum:1},maxInitialSize:{oneOf:[{$ref:"#/definitions/OptimizationSplitChunksSizes"}]},maxSize:{oneOf:[{$ref:"#/definitions/OptimizationSplitChunksSizes"}]},minChunks:{type:"number",minimum:1},minRemainingSize:{oneOf:[{$ref:"#/definitions/OptimizationSplitChunksSizes"}]},minSize:{oneOf:[{$ref:"#/definitions/OptimizationSplitChunksSizes"}]},minSizeReduction:{oneOf:[{$ref:"#/definitions/OptimizationSplitChunksSizes"}]},name:{anyOf:[{enum:[!1]},{type:"string"},{instanceof:"Function"}]},priority:{type:"number"},reuseExistingChunk:{type:"boolean"},test:{anyOf:[{instanceof:"RegExp"},{type:"string"},{instanceof:"Function"}]},type:{anyOf:[{instanceof:"RegExp"},{type:"string"},{instanceof:"Function"}]},usedExports:{type:"boolean"}}},OptimizationSplitChunksGetCacheGroups:{instanceof:"Function"},OptimizationSplitChunksOptions:{type:"object",additionalProperties:!1,properties:{automaticNameDelimiter:{type:"string",minLength:1},cacheGroups:{type:"object",additionalProperties:{anyOf:[{enum:[!1]},{instanceof:"RegExp"},{type:"string"},{instanceof:"Function"},{$ref:"#/definitions/OptimizationSplitChunksCacheGroup"}]},not:{type:"object",additionalProperties:!0,properties:{test:{anyOf:[{instanceof:"RegExp"},{type:"string"},{instanceof:"Function"}]}},required:["test"]}},chunks:{anyOf:[{enum:["initial","async","all"]},{instanceof:"RegExp"},{instanceof:"Function"}]},defaultSizeTypes:{type:"array",items:{type:"string"},minItems:1},enforceSizeThreshold:{oneOf:[{$ref:"#/definitions/OptimizationSplitChunksSizes"}]},fallbackCacheGroup:{type:"object",additionalProperties:!1,properties:{automaticNameDelimiter:{type:"string",minLength:1},chunks:{anyOf:[{enum:["initial","async","all"]},{instanceof:"RegExp"},{instanceof:"Function"}]},maxAsyncSize:{oneOf:[{$ref:"#/definitions/OptimizationSplitChunksSizes"}]},maxInitialSize:{oneOf:[{$ref:"#/definitions/OptimizationSplitChunksSizes"}]},maxSize:{oneOf:[{$ref:"#/definitions/OptimizationSplitChunksSizes"}]},minSize:{oneOf:[{$ref:"#/definitions/OptimizationSplitChunksSizes"}]},minSizeReduction:{oneOf:[{$ref:"#/definitions/OptimizationSplitChunksSizes"}]}}},filename:{anyOf:[{type:"string",absolutePath:!1,minLength:1},{instanceof:"Function"}]},hidePathInfo:{type:"boolean"},maxAsyncRequests:{type:"number",minimum:1},maxAsyncSize:{oneOf:[{$ref:"#/definitions/OptimizationSplitChunksSizes"}]},maxInitialRequests:{type:"number",minimum:1},maxInitialSize:{oneOf:[{$ref:"#/definitions/OptimizationSplitChunksSizes"}]},maxSize:{oneOf:[{$ref:"#/definitions/OptimizationSplitChunksSizes"}]},minChunks:{type:"number",minimum:1},minRemainingSize:{oneOf:[{$ref:"#/definitions/OptimizationSplitChunksSizes"}]},minSize:{oneOf:[{$ref:"#/definitions/OptimizationSplitChunksSizes"}]},minSizeReduction:{oneOf:[{$ref:"#/definitions/OptimizationSplitChunksSizes"}]},name:{anyOf:[{enum:[!1]},{type:"string"},{instanceof:"Function"}]},usedExports:{type:"boolean"}}},OptimizationSplitChunksSizes:{anyOf:[{type:"number",minimum:0},{type:"object",additionalProperties:{type:"number"}}]},Output:{type:"object",additionalProperties:!1,properties:{amdContainer:{oneOf:[{$ref:"#/definitions/AmdContainer"}]},assetModuleFilename:{$ref:"#/definitions/AssetModuleFilename"},asyncChunks:{type:"boolean"},auxiliaryComment:{oneOf:[{$ref:"#/definitions/AuxiliaryComment"}]},charset:{$ref:"#/definitions/Charset"},chunkFilename:{$ref:"#/definitions/ChunkFilename"},chunkFormat:{$ref:"#/definitions/ChunkFormat"},chunkLoadTimeout:{$ref:"#/definitions/ChunkLoadTimeout"},chunkLoading:{$ref:"#/definitions/ChunkLoading"},chunkLoadingGlobal:{$ref:"#/definitions/ChunkLoadingGlobal"},clean:{$ref:"#/definitions/Clean"},compareBeforeEmit:{$ref:"#/definitions/CompareBeforeEmit"},crossOriginLoading:{$ref:"#/definitions/CrossOriginLoading"},cssChunkFilename:{$ref:"#/definitions/CssChunkFilename"},cssFilename:{$ref:"#/definitions/CssFilename"},cssHeadDataCompression:{$ref:"#/definitions/CssHeadDataCompression"},devtoolFallbackModuleFilenameTemplate:{$ref:"#/definitions/DevtoolFallbackModuleFilenameTemplate"},devtoolModuleFilenameTemplate:{$ref:"#/definitions/DevtoolModuleFilenameTemplate"},devtoolNamespace:{$ref:"#/definitions/DevtoolNamespace"},enabledChunkLoadingTypes:{$ref:"#/definitions/EnabledChunkLoadingTypes"},enabledLibraryTypes:{$ref:"#/definitions/EnabledLibraryTypes"},enabledWasmLoadingTypes:{$ref:"#/definitions/EnabledWasmLoadingTypes"},environment:{$ref:"#/definitions/Environment"},filename:{$ref:"#/definitions/Filename"},globalObject:{$ref:"#/definitions/GlobalObject"},hashDigest:{$ref:"#/definitions/HashDigest"},hashDigestLength:{$ref:"#/definitions/HashDigestLength"},hashFunction:{$ref:"#/definitions/HashFunction"},hashSalt:{$ref:"#/definitions/HashSalt"},hotUpdateChunkFilename:{$ref:"#/definitions/HotUpdateChunkFilename"},hotUpdateGlobal:{$ref:"#/definitions/HotUpdateGlobal"},hotUpdateMainFilename:{$ref:"#/definitions/HotUpdateMainFilename"},ignoreBrowserWarnings:{type:"boolean"},iife:{$ref:"#/definitions/Iife"},importFunctionName:{$ref:"#/definitions/ImportFunctionName"},importMetaName:{$ref:"#/definitions/ImportMetaName"},library:{$ref:"#/definitions/Library"},libraryExport:{oneOf:[{$ref:"#/definitions/LibraryExport"}]},libraryTarget:{oneOf:[{$ref:"#/definitions/LibraryType"}]},module:{$ref:"#/definitions/OutputModule"},path:{$ref:"#/definitions/Path"},pathinfo:{$ref:"#/definitions/Pathinfo"},publicPath:{$ref:"#/definitions/PublicPath"},scriptType:{$ref:"#/definitions/ScriptType"},sourceMapFilename:{$ref:"#/definitions/SourceMapFilename"},sourcePrefix:{$ref:"#/definitions/SourcePrefix"},strictModuleErrorHandling:{$ref:"#/definitions/StrictModuleErrorHandling"},strictModuleExceptionHandling:{$ref:"#/definitions/StrictModuleExceptionHandling"},trustedTypes:{anyOf:[{enum:[!0]},{type:"string",minLength:1},{$ref:"#/definitions/TrustedTypes"}]},umdNamedDefine:{oneOf:[{$ref:"#/definitions/UmdNamedDefine"}]},uniqueName:{$ref:"#/definitions/UniqueName"},wasmLoading:{$ref:"#/definitions/WasmLoading"},webassemblyModuleFilename:{$ref:"#/definitions/WebassemblyModuleFilename"},workerChunkLoading:{$ref:"#/definitions/ChunkLoading"},workerPublicPath:{$ref:"#/definitions/WorkerPublicPath"},workerWasmLoading:{$ref:"#/definitions/WasmLoading"}}},OutputModule:{type:"boolean"},OutputNormalized:{type:"object",additionalProperties:!1,properties:{assetModuleFilename:{$ref:"#/definitions/AssetModuleFilename"},asyncChunks:{type:"boolean"},charset:{$ref:"#/definitions/Charset"},chunkFilename:{$ref:"#/definitions/ChunkFilename"},chunkFormat:{$ref:"#/definitions/ChunkFormat"},chunkLoadTimeout:{$ref:"#/definitions/ChunkLoadTimeout"},chunkLoading:{$ref:"#/definitions/ChunkLoading"},chunkLoadingGlobal:{$ref:"#/definitions/ChunkLoadingGlobal"},clean:{$ref:"#/definitions/Clean"},compareBeforeEmit:{$ref:"#/definitions/CompareBeforeEmit"},crossOriginLoading:{$ref:"#/definitions/CrossOriginLoading"},cssChunkFilename:{$ref:"#/definitions/CssChunkFilename"},cssFilename:{$ref:"#/definitions/CssFilename"},cssHeadDataCompression:{$ref:"#/definitions/CssHeadDataCompression"},devtoolFallbackModuleFilenameTemplate:{$ref:"#/definitions/DevtoolFallbackModuleFilenameTemplate"},devtoolModuleFilenameTemplate:{$ref:"#/definitions/DevtoolModuleFilenameTemplate"},devtoolNamespace:{$ref:"#/definitions/DevtoolNamespace"},enabledChunkLoadingTypes:{$ref:"#/definitions/EnabledChunkLoadingTypes"},enabledLibraryTypes:{$ref:"#/definitions/EnabledLibraryTypes"},enabledWasmLoadingTypes:{$ref:"#/definitions/EnabledWasmLoadingTypes"},environment:{$ref:"#/definitions/Environment"},filename:{$ref:"#/definitions/Filename"},globalObject:{$ref:"#/definitions/GlobalObject"},hashDigest:{$ref:"#/definitions/HashDigest"},hashDigestLength:{$ref:"#/definitions/HashDigestLength"},hashFunction:{$ref:"#/definitions/HashFunction"},hashSalt:{$ref:"#/definitions/HashSalt"},hotUpdateChunkFilename:{$ref:"#/definitions/HotUpdateChunkFilename"},hotUpdateGlobal:{$ref:"#/definitions/HotUpdateGlobal"},hotUpdateMainFilename:{$ref:"#/definitions/HotUpdateMainFilename"},ignoreBrowserWarnings:{type:"boolean"},iife:{$ref:"#/definitions/Iife"},importFunctionName:{$ref:"#/definitions/ImportFunctionName"},importMetaName:{$ref:"#/definitions/ImportMetaName"},library:{$ref:"#/definitions/LibraryOptions"},module:{$ref:"#/definitions/OutputModule"},path:{$ref:"#/definitions/Path"},pathinfo:{$ref:"#/definitions/Pathinfo"},publicPath:{$ref:"#/definitions/PublicPath"},scriptType:{$ref:"#/definitions/ScriptType"},sourceMapFilename:{$ref:"#/definitions/SourceMapFilename"},sourcePrefix:{$ref:"#/definitions/SourcePrefix"},strictModuleErrorHandling:{$ref:"#/definitions/StrictModuleErrorHandling"},strictModuleExceptionHandling:{$ref:"#/definitions/StrictModuleExceptionHandling"},trustedTypes:{$ref:"#/definitions/TrustedTypes"},uniqueName:{$ref:"#/definitions/UniqueName"},wasmLoading:{$ref:"#/definitions/WasmLoading"},webassemblyModuleFilename:{$ref:"#/definitions/WebassemblyModuleFilename"},workerChunkLoading:{$ref:"#/definitions/ChunkLoading"},workerPublicPath:{$ref:"#/definitions/WorkerPublicPath"},workerWasmLoading:{$ref:"#/definitions/WasmLoading"}}},Parallelism:{type:"number",minimum:1},ParserOptionsByModuleType:{type:"object",additionalProperties:{type:"object",additionalProperties:!0},properties:{asset:{$ref:"#/definitions/AssetParserOptions"},"asset/inline":{$ref:"#/definitions/EmptyParserOptions"},"asset/resource":{$ref:"#/definitions/EmptyParserOptions"},"asset/source":{$ref:"#/definitions/EmptyParserOptions"},css:{$ref:"#/definitions/CssParserOptions"},"css/auto":{$ref:"#/definitions/CssAutoParserOptions"},"css/global":{$ref:"#/definitions/CssGlobalParserOptions"},"css/module":{$ref:"#/definitions/CssModuleParserOptions"},javascript:{$ref:"#/definitions/JavascriptParserOptions"},"javascript/auto":{$ref:"#/definitions/JavascriptParserOptions"},"javascript/dynamic":{$ref:"#/definitions/JavascriptParserOptions"},"javascript/esm":{$ref:"#/definitions/JavascriptParserOptions"}}},Path:{type:"string",absolutePath:!0},Pathinfo:{anyOf:[{enum:["verbose"]},{type:"boolean"}]},Performance:{anyOf:[{enum:[!1]},{$ref:"#/definitions/PerformanceOptions"}]},PerformanceOptions:{type:"object",additionalProperties:!1,properties:{assetFilter:{instanceof:"Function"},hints:{enum:[!1,"warning","error"]},maxAssetSize:{type:"number"},maxEntrypointSize:{type:"number"}}},Plugins:{type:"array",items:{anyOf:[{$ref:"#/definitions/Falsy"},{$ref:"#/definitions/WebpackPluginInstance"},{$ref:"#/definitions/WebpackPluginFunction"}]}},Profile:{type:"boolean"},PublicPath:{anyOf:[{enum:["auto"]},{$ref:"#/definitions/RawPublicPath"}]},RawPublicPath:{anyOf:[{type:"string"},{instanceof:"Function"}]},RecordsInputPath:{anyOf:[{enum:[!1]},{type:"string",absolutePath:!0}]},RecordsOutputPath:{anyOf:[{enum:[!1]},{type:"string",absolutePath:!0}]},RecordsPath:{anyOf:[{enum:[!1]},{type:"string",absolutePath:!0}]},Resolve:{oneOf:[{$ref:"#/definitions/ResolveOptions"}]},ResolveAlias:{anyOf:[{type:"array",items:{type:"object",additionalProperties:!1,properties:{alias:{anyOf:[{type:"array",items:{type:"string",minLength:1}},{enum:[!1]},{type:"string",minLength:1}]},name:{type:"string"},onlyModule:{type:"boolean"}},required:["alias","name"]}},{type:"object",additionalProperties:{anyOf:[{type:"array",items:{type:"string",minLength:1}},{enum:[!1]},{type:"string",minLength:1}]}}]},ResolveLoader:{oneOf:[{$ref:"#/definitions/ResolveOptions"}]},ResolveOptions:{type:"object",additionalProperties:!1,properties:{alias:{$ref:"#/definitions/ResolveAlias"},aliasFields:{type:"array",items:{anyOf:[{type:"array",items:{type:"string",minLength:1}},{type:"string",minLength:1}]}},byDependency:{type:"object",additionalProperties:{oneOf:[{$ref:"#/definitions/ResolveOptions"}]}},cache:{type:"boolean"},cachePredicate:{instanceof:"Function"},cacheWithContext:{type:"boolean"},conditionNames:{type:"array",items:{type:"string"}},descriptionFiles:{type:"array",items:{type:"string",minLength:1}},enforceExtension:{type:"boolean"},exportsFields:{type:"array",items:{type:"string"}},extensionAlias:{type:"object",additionalProperties:{anyOf:[{type:"array",items:{type:"string",minLength:1}},{type:"string",minLength:1}]}},extensions:{type:"array",items:{type:"string"}},fallback:{oneOf:[{$ref:"#/definitions/ResolveAlias"}]},fileSystem:{},fullySpecified:{type:"boolean"},importsFields:{type:"array",items:{type:"string"}},mainFields:{type:"array",items:{anyOf:[{type:"array",items:{type:"string",minLength:1}},{type:"string",minLength:1}]}},mainFiles:{type:"array",items:{type:"string",minLength:1}},modules:{type:"array",items:{type:"string",minLength:1}},plugins:{type:"array",items:{anyOf:[{enum:["..."]},{$ref:"#/definitions/Falsy"},{$ref:"#/definitions/ResolvePluginInstance"}]}},preferAbsolute:{type:"boolean"},preferRelative:{type:"boolean"},resolver:{},restrictions:{type:"array",items:{anyOf:[{instanceof:"RegExp"},{type:"string",absolutePath:!0,minLength:1}]}},roots:{type:"array",items:{type:"string"}},symlinks:{type:"boolean"},unsafeCache:{anyOf:[{type:"boolean"},{type:"object",additionalProperties:!0}]},useSyncFileSystemCalls:{type:"boolean"}}},ResolvePluginInstance:{anyOf:[{type:"object",additionalProperties:!0,properties:{apply:{instanceof:"Function"}},required:["apply"]},{instanceof:"Function"}]},RuleSetCondition:{anyOf:[{instanceof:"RegExp"},{type:"string"},{instanceof:"Function"},{$ref:"#/definitions/RuleSetLogicalConditions"},{$ref:"#/definitions/RuleSetConditions"}]},RuleSetConditionAbsolute:{anyOf:[{instanceof:"RegExp"},{type:"string",absolutePath:!0},{instanceof:"Function"},{$ref:"#/definitions/RuleSetLogicalConditionsAbsolute"},{$ref:"#/definitions/RuleSetConditionsAbsolute"}]},RuleSetConditionOrConditions:{anyOf:[{$ref:"#/definitions/RuleSetCondition"},{$ref:"#/definitions/RuleSetConditions"}]},RuleSetConditionOrConditionsAbsolute:{anyOf:[{$ref:"#/definitions/RuleSetConditionAbsolute"},{$ref:"#/definitions/RuleSetConditionsAbsolute"}]},RuleSetConditions:{type:"array",items:{oneOf:[{$ref:"#/definitions/RuleSetCondition"}]}},RuleSetConditionsAbsolute:{type:"array",items:{oneOf:[{$ref:"#/definitions/RuleSetConditionAbsolute"}]}},RuleSetLoader:{type:"string",minLength:1},RuleSetLoaderOptions:{anyOf:[{type:"string"},{type:"object"}]},RuleSetLogicalConditions:{type:"object",additionalProperties:!1,properties:{and:{oneOf:[{$ref:"#/definitions/RuleSetConditions"}]},not:{oneOf:[{$ref:"#/definitions/RuleSetCondition"}]},or:{oneOf:[{$ref:"#/definitions/RuleSetConditions"}]}}},RuleSetLogicalConditionsAbsolute:{type:"object",additionalProperties:!1,properties:{and:{oneOf:[{$ref:"#/definitions/RuleSetConditionsAbsolute"}]},not:{oneOf:[{$ref:"#/definitions/RuleSetConditionAbsolute"}]},or:{oneOf:[{$ref:"#/definitions/RuleSetConditionsAbsolute"}]}}},RuleSetRule:{type:"object",additionalProperties:!1,properties:{assert:{type:"object",additionalProperties:{$ref:"#/definitions/RuleSetConditionOrConditions"}},compiler:{oneOf:[{$ref:"#/definitions/RuleSetConditionOrConditions"}]},dependency:{oneOf:[{$ref:"#/definitions/RuleSetConditionOrConditions"}]},descriptionData:{type:"object",additionalProperties:{$ref:"#/definitions/RuleSetConditionOrConditions"}},enforce:{enum:["pre","post"]},exclude:{oneOf:[{$ref:"#/definitions/RuleSetConditionOrConditionsAbsolute"}]},generator:{type:"object"},include:{oneOf:[{$ref:"#/definitions/RuleSetConditionOrConditionsAbsolute"}]},issuer:{oneOf:[{$ref:"#/definitions/RuleSetConditionOrConditionsAbsolute"}]},issuerLayer:{oneOf:[{$ref:"#/definitions/RuleSetConditionOrConditions"}]},layer:{type:"string"},loader:{oneOf:[{$ref:"#/definitions/RuleSetLoader"}]},mimetype:{oneOf:[{$ref:"#/definitions/RuleSetConditionOrConditions"}]},oneOf:{type:"array",items:{anyOf:[{$ref:"#/definitions/Falsy"},{$ref:"#/definitions/RuleSetRule"}]}},options:{oneOf:[{$ref:"#/definitions/RuleSetLoaderOptions"}]},parser:{type:"object",additionalProperties:!0},realResource:{oneOf:[{$ref:"#/definitions/RuleSetConditionOrConditionsAbsolute"}]},resolve:{type:"object",oneOf:[{$ref:"#/definitions/ResolveOptions"}]},resource:{oneOf:[{$ref:"#/definitions/RuleSetConditionOrConditionsAbsolute"}]},resourceFragment:{oneOf:[{$ref:"#/definitions/RuleSetConditionOrConditions"}]},resourceQuery:{oneOf:[{$ref:"#/definitions/RuleSetConditionOrConditions"}]},rules:{type:"array",items:{anyOf:[{$ref:"#/definitions/Falsy"},{$ref:"#/definitions/RuleSetRule"}]}},scheme:{oneOf:[{$ref:"#/definitions/RuleSetConditionOrConditions"}]},sideEffects:{type:"boolean"},test:{oneOf:[{$ref:"#/definitions/RuleSetConditionOrConditionsAbsolute"}]},type:{type:"string"},use:{oneOf:[{$ref:"#/definitions/RuleSetUse"}]},with:{type:"object",additionalProperties:{$ref:"#/definitions/RuleSetConditionOrConditions"}}}},RuleSetRules:{type:"array",items:{anyOf:[{enum:["..."]},{$ref:"#/definitions/Falsy"},{$ref:"#/definitions/RuleSetRule"}]}},RuleSetUse:{anyOf:[{type:"array",items:{anyOf:[{$ref:"#/definitions/Falsy"},{$ref:"#/definitions/RuleSetUseItem"}]}},{instanceof:"Function"},{$ref:"#/definitions/RuleSetUseItem"}]},RuleSetUseItem:{anyOf:[{type:"object",additionalProperties:!1,properties:{ident:{type:"string"},loader:{oneOf:[{$ref:"#/definitions/RuleSetLoader"}]},options:{oneOf:[{$ref:"#/definitions/RuleSetLoaderOptions"}]}}},{instanceof:"Function"},{$ref:"#/definitions/RuleSetLoader"}]},ScriptType:{enum:[!1,"text/javascript","module"]},SnapshotOptions:{type:"object",additionalProperties:!1,properties:{buildDependencies:{type:"object",additionalProperties:!1,properties:{hash:{type:"boolean"},timestamp:{type:"boolean"}}},immutablePaths:{type:"array",items:{anyOf:[{instanceof:"RegExp"},{type:"string",absolutePath:!0,minLength:1}]}},managedPaths:{type:"array",items:{anyOf:[{instanceof:"RegExp"},{type:"string",absolutePath:!0,minLength:1}]}},module:{type:"object",additionalProperties:!1,properties:{hash:{type:"boolean"},timestamp:{type:"boolean"}}},resolve:{type:"object",additionalProperties:!1,properties:{hash:{type:"boolean"},timestamp:{type:"boolean"}}},resolveBuildDependencies:{type:"object",additionalProperties:!1,properties:{hash:{type:"boolean"},timestamp:{type:"boolean"}}},unmanagedPaths:{type:"array",items:{anyOf:[{instanceof:"RegExp"},{type:"string",absolutePath:!0,minLength:1}]}}}},SourceMapFilename:{type:"string",absolutePath:!1},SourcePrefix:{type:"string"},StatsOptions:{type:"object",additionalProperties:!1,properties:{all:{type:"boolean"},assets:{type:"boolean"},assetsSort:{type:"string"},assetsSpace:{type:"number"},builtAt:{type:"boolean"},cached:{type:"boolean"},cachedAssets:{type:"boolean"},cachedModules:{type:"boolean"},children:{type:"boolean"},chunkGroupAuxiliary:{type:"boolean"},chunkGroupChildren:{type:"boolean"},chunkGroupMaxAssets:{type:"number"},chunkGroups:{type:"boolean"},chunkModules:{type:"boolean"},chunkModulesSpace:{type:"number"},chunkOrigins:{type:"boolean"},chunkRelations:{type:"boolean"},chunks:{type:"boolean"},chunksSort:{type:"string"},colors:{anyOf:[{type:"boolean"},{type:"object",additionalProperties:!1,properties:{bold:{type:"string"},cyan:{type:"string"},green:{type:"string"},magenta:{type:"string"},red:{type:"string"},yellow:{type:"string"}}}]},context:{type:"string",absolutePath:!0},dependentModules:{type:"boolean"},depth:{type:"boolean"},entrypoints:{anyOf:[{enum:["auto"]},{type:"boolean"}]},env:{type:"boolean"},errorDetails:{anyOf:[{enum:["auto"]},{type:"boolean"}]},errorStack:{type:"boolean"},errors:{type:"boolean"},errorsCount:{type:"boolean"},errorsSpace:{type:"number"},exclude:{anyOf:[{type:"boolean"},{$ref:"#/definitions/ModuleFilterTypes"}]},excludeAssets:{oneOf:[{$ref:"#/definitions/AssetFilterTypes"}]},excludeModules:{anyOf:[{type:"boolean"},{$ref:"#/definitions/ModuleFilterTypes"}]},groupAssetsByChunk:{type:"boolean"},groupAssetsByEmitStatus:{type:"boolean"},groupAssetsByExtension:{type:"boolean"},groupAssetsByInfo:{type:"boolean"},groupAssetsByPath:{type:"boolean"},groupModulesByAttributes:{type:"boolean"},groupModulesByCacheStatus:{type:"boolean"},groupModulesByExtension:{type:"boolean"},groupModulesByLayer:{type:"boolean"},groupModulesByPath:{type:"boolean"},groupModulesByType:{type:"boolean"},groupReasonsByOrigin:{type:"boolean"},hash:{type:"boolean"},ids:{type:"boolean"},logging:{anyOf:[{enum:["none","error","warn","info","log","verbose"]},{type:"boolean"}]},loggingDebug:{anyOf:[{type:"boolean"},{$ref:"#/definitions/FilterTypes"}]},loggingTrace:{type:"boolean"},moduleAssets:{type:"boolean"},moduleTrace:{type:"boolean"},modules:{type:"boolean"},modulesSort:{type:"string"},modulesSpace:{type:"number"},nestedModules:{type:"boolean"},nestedModulesSpace:{type:"number"},optimizationBailout:{type:"boolean"},orphanModules:{type:"boolean"},outputPath:{type:"boolean"},performance:{type:"boolean"},preset:{anyOf:[{type:"boolean"},{type:"string"}]},providedExports:{type:"boolean"},publicPath:{type:"boolean"},reasons:{type:"boolean"},reasonsSpace:{type:"number"},relatedAssets:{type:"boolean"},runtime:{type:"boolean"},runtimeModules:{type:"boolean"},source:{type:"boolean"},timings:{type:"boolean"},usedExports:{type:"boolean"},version:{type:"boolean"},warnings:{type:"boolean"},warningsCount:{type:"boolean"},warningsFilter:{oneOf:[{$ref:"#/definitions/WarningFilterTypes"}]},warningsSpace:{type:"number"}}},StatsValue:{anyOf:[{enum:["none","summary","errors-only","errors-warnings","minimal","normal","detailed","verbose"]},{type:"boolean"},{$ref:"#/definitions/StatsOptions"}]},StrictModuleErrorHandling:{type:"boolean"},StrictModuleExceptionHandling:{type:"boolean"},Target:{anyOf:[{type:"array",items:{type:"string",minLength:1},minItems:1},{enum:[!1]},{type:"string",minLength:1}]},TrustedTypes:{type:"object",additionalProperties:!1,properties:{onPolicyCreationFailure:{enum:["continue","stop"]},policyName:{type:"string",minLength:1}}},UmdNamedDefine:{type:"boolean"},UniqueName:{type:"string",minLength:1},WarningFilterItemTypes:{anyOf:[{instanceof:"RegExp"},{type:"string",absolutePath:!1},{instanceof:"Function"}]},WarningFilterTypes:{anyOf:[{type:"array",items:{oneOf:[{$ref:"#/definitions/WarningFilterItemTypes"}]}},{$ref:"#/definitions/WarningFilterItemTypes"}]},WasmLoading:{anyOf:[{enum:[!1]},{$ref:"#/definitions/WasmLoadingType"}]},WasmLoadingType:{anyOf:[{enum:["fetch-streaming","fetch","async-node"]},{type:"string"}]},Watch:{type:"boolean"},WatchOptions:{type:"object",additionalProperties:!1,properties:{aggregateTimeout:{type:"number"},followSymlinks:{type:"boolean"},ignored:{anyOf:[{type:"array",items:{type:"string",minLength:1}},{instanceof:"RegExp"},{type:"string",minLength:1}]},poll:{anyOf:[{type:"number"},{type:"boolean"}]},stdin:{type:"boolean"}}},WebassemblyModuleFilename:{type:"string",absolutePath:!1},WebpackOptionsNormalized:{type:"object",additionalProperties:!1,properties:{amd:{$ref:"#/definitions/Amd"},bail:{$ref:"#/definitions/Bail"},cache:{$ref:"#/definitions/CacheOptionsNormalized"},context:{$ref:"#/definitions/Context"},dependencies:{$ref:"#/definitions/Dependencies"},devServer:{$ref:"#/definitions/DevServer"},devtool:{$ref:"#/definitions/DevTool"},entry:{$ref:"#/definitions/EntryNormalized"},experiments:{$ref:"#/definitions/ExperimentsNormalized"},externals:{$ref:"#/definitions/Externals"},externalsPresets:{$ref:"#/definitions/ExternalsPresets"},externalsType:{$ref:"#/definitions/ExternalsType"},ignoreWarnings:{$ref:"#/definitions/IgnoreWarningsNormalized"},infrastructureLogging:{$ref:"#/definitions/InfrastructureLogging"},loader:{$ref:"#/definitions/Loader"},mode:{$ref:"#/definitions/Mode"},module:{$ref:"#/definitions/ModuleOptionsNormalized"},name:{$ref:"#/definitions/Name"},node:{$ref:"#/definitions/Node"},optimization:{$ref:"#/definitions/Optimization"},output:{$ref:"#/definitions/OutputNormalized"},parallelism:{$ref:"#/definitions/Parallelism"},performance:{$ref:"#/definitions/Performance"},plugins:{$ref:"#/definitions/Plugins"},profile:{$ref:"#/definitions/Profile"},recordsInputPath:{$ref:"#/definitions/RecordsInputPath"},recordsOutputPath:{$ref:"#/definitions/RecordsOutputPath"},resolve:{$ref:"#/definitions/Resolve"},resolveLoader:{$ref:"#/definitions/ResolveLoader"},snapshot:{$ref:"#/definitions/SnapshotOptions"},stats:{$ref:"#/definitions/StatsValue"},target:{$ref:"#/definitions/Target"},watch:{$ref:"#/definitions/Watch"},watchOptions:{$ref:"#/definitions/WatchOptions"}},required:["cache","snapshot","entry","experiments","externals","externalsPresets","infrastructureLogging","module","node","optimization","output","plugins","resolve","resolveLoader","stats","watchOptions"]},WebpackPluginFunction:{instanceof:"Function"},WebpackPluginInstance:{type:"object",additionalProperties:!0,properties:{apply:{instanceof:"Function"}},required:["apply"]},WorkerPublicPath:{type:"string"}},type:"object",additionalProperties:!1,properties:{amd:{$ref:"#/definitions/Amd"},bail:{$ref:"#/definitions/Bail"},cache:{$ref:"#/definitions/CacheOptions"},context:{$ref:"#/definitions/Context"},dependencies:{$ref:"#/definitions/Dependencies"},devServer:{$ref:"#/definitions/DevServer"},devtool:{$ref:"#/definitions/DevTool"},entry:{$ref:"#/definitions/Entry"},experiments:{$ref:"#/definitions/Experiments"},extends:{$ref:"#/definitions/Extends"},externals:{$ref:"#/definitions/Externals"},externalsPresets:{$ref:"#/definitions/ExternalsPresets"},externalsType:{$ref:"#/definitions/ExternalsType"},ignoreWarnings:{$ref:"#/definitions/IgnoreWarnings"},infrastructureLogging:{$ref:"#/definitions/InfrastructureLogging"},loader:{$ref:"#/definitions/Loader"},mode:{$ref:"#/definitions/Mode"},module:{$ref:"#/definitions/ModuleOptions"},name:{$ref:"#/definitions/Name"},node:{$ref:"#/definitions/Node"},optimization:{$ref:"#/definitions/Optimization"},output:{$ref:"#/definitions/Output"},parallelism:{$ref:"#/definitions/Parallelism"},performance:{$ref:"#/definitions/Performance"},plugins:{$ref:"#/definitions/Plugins"},profile:{$ref:"#/definitions/Profile"},recordsInputPath:{$ref:"#/definitions/RecordsInputPath"},recordsOutputPath:{$ref:"#/definitions/RecordsOutputPath"},recordsPath:{$ref:"#/definitions/RecordsPath"},resolve:{$ref:"#/definitions/Resolve"},resolveLoader:{$ref:"#/definitions/ResolveLoader"},snapshot:{$ref:"#/definitions/SnapshotOptions"},stats:{$ref:"#/definitions/StatsValue"},target:{$ref:"#/definitions/Target"},watch:{$ref:"#/definitions/Watch"},watchOptions:{$ref:"#/definitions/WatchOptions"}}},n=Object.prototype.hasOwnProperty,r={type:"object",additionalProperties:!1,properties:{allowCollectingMemory:{type:"boolean"},buildDependencies:{type:"object",additionalProperties:{type:"array",items:{type:"string",minLength:1}}},cacheDirectory:{type:"string",absolutePath:!0},cacheLocation:{type:"string",absolutePath:!0},compression:{enum:[!1,"gzip","brotli"]},hashAlgorithm:{type:"string"},idleTimeout:{type:"number",minimum:0},idleTimeoutAfterLargeChanges:{type:"number",minimum:0},idleTimeoutForInitialStore:{type:"number",minimum:0},immutablePaths:{type:"array",items:{anyOf:[{instanceof:"RegExp"},{type:"string",absolutePath:!0,minLength:1}]}},managedPaths:{type:"array",items:{anyOf:[{instanceof:"RegExp"},{type:"string",absolutePath:!0,minLength:1}]}},maxAge:{type:"number",minimum:0},maxMemoryGenerations:{type:"number",minimum:0},memoryCacheUnaffected:{type:"boolean"},name:{type:"string"},profile:{type:"boolean"},readonly:{type:"boolean"},store:{enum:["pack"]},type:{enum:["filesystem"]},version:{type:"string"}},required:["type"]};function o(t,{instancePath:s="",parentData:i,parentDataProperty:a,rootData:l=t}={}){let p=null,f=0;const u=f;let c=!1;const y=f;if(!1!==t){const e={params:{}};null===p?p=[e]:p.push(e),f++}var m=y===f;if(c=c||m,!c){const o=f;if(f==f)if(t&&"object"==typeof t&&!Array.isArray(t)){let e;if(void 0===t.type&&(e="type")){const t={params:{missingProperty:e}};null===p?p=[t]:p.push(t),f++}else{const e=f;for(const e in t)if("cacheUnaffected"!==e&&"maxGenerations"!==e&&"type"!==e){const t={params:{additionalProperty:e}};null===p?p=[t]:p.push(t),f++;break}if(e===f){if(void 0!==t.cacheUnaffected){const e=f;if("boolean"!=typeof t.cacheUnaffected){const e={params:{type:"boolean"}};null===p?p=[e]:p.push(e),f++}var d=e===f}else d=!0;if(d){if(void 0!==t.maxGenerations){let e=t.maxGenerations;const n=f;if(f===n)if("number"==typeof e){if(e<1||isNaN(e)){const e={params:{comparison:">=",limit:1}};null===p?p=[e]:p.push(e),f++}}else{const e={params:{type:"number"}};null===p?p=[e]:p.push(e),f++}d=n===f}else d=!0;if(d)if(void 0!==t.type){const e=f;if("memory"!==t.type){const e={params:{}};null===p?p=[e]:p.push(e),f++}d=e===f}else d=!0}}}}else{const e={params:{type:"object"}};null===p?p=[e]:p.push(e),f++}if(m=o===f,c=c||m,!c){const o=f;if(f==f)if(t&&"object"==typeof t&&!Array.isArray(t)){let o;if(void 0===t.type&&(o="type")){const e={params:{missingProperty:o}};null===p?p=[e]:p.push(e),f++}else{const o=f;for(const e in t)if(!n.call(r.properties,e)){const t={params:{additionalProperty:e}};null===p?p=[t]:p.push(t),f++;break}if(o===f){if(void 0!==t.allowCollectingMemory){const e=f;if("boolean"!=typeof t.allowCollectingMemory){const e={params:{type:"boolean"}};null===p?p=[e]:p.push(e),f++}var h=e===f}else h=!0;if(h){if(void 0!==t.buildDependencies){let e=t.buildDependencies;const n=f;if(f===n)if(e&&"object"==typeof e&&!Array.isArray(e))for(const t in e){let n=e[t];const r=f;if(f===r)if(Array.isArray(n)){const e=n.length;for(let t=0;t=",limit:0}};null===p?p=[e]:p.push(e),f++}}else{const e={params:{type:"number"}};null===p?p=[e]:p.push(e),f++}h=n===f}else h=!0;if(h){if(void 0!==t.idleTimeoutAfterLargeChanges){let e=t.idleTimeoutAfterLargeChanges;const n=f;if(f===n)if("number"==typeof e){if(e<0||isNaN(e)){const e={params:{comparison:">=",limit:0}};null===p?p=[e]:p.push(e),f++}}else{const e={params:{type:"number"}};null===p?p=[e]:p.push(e),f++}h=n===f}else h=!0;if(h){if(void 0!==t.idleTimeoutForInitialStore){let e=t.idleTimeoutForInitialStore;const n=f;if(f===n)if("number"==typeof e){if(e<0||isNaN(e)){const e={params:{comparison:">=",limit:0}};null===p?p=[e]:p.push(e),f++}}else{const e={params:{type:"number"}};null===p?p=[e]:p.push(e),f++}h=n===f}else h=!0;if(h){if(void 0!==t.immutablePaths){let n=t.immutablePaths;const r=f;if(f===r)if(Array.isArray(n)){const t=n.length;for(let r=0;r=",limit:0}};null===p?p=[e]:p.push(e),f++}}else{const e={params:{type:"number"}};null===p?p=[e]:p.push(e),f++}h=n===f}else h=!0;if(h){if(void 0!==t.maxMemoryGenerations){let e=t.maxMemoryGenerations;const n=f;if(f===n)if("number"==typeof e){if(e<0||isNaN(e)){const e={params:{comparison:">=",limit:0}};null===p?p=[e]:p.push(e),f++}}else{const e={params:{type:"number"}};null===p?p=[e]:p.push(e),f++}h=n===f}else h=!0;if(h){if(void 0!==t.memoryCacheUnaffected){const e=f;if("boolean"!=typeof t.memoryCacheUnaffected){const e={params:{type:"boolean"}};null===p?p=[e]:p.push(e),f++}h=e===f}else h=!0;if(h){if(void 0!==t.name){const e=f;if("string"!=typeof t.name){const e={params:{type:"string"}};null===p?p=[e]:p.push(e),f++}h=e===f}else h=!0;if(h){if(void 0!==t.profile){const e=f;if("boolean"!=typeof t.profile){const e={params:{type:"boolean"}};null===p?p=[e]:p.push(e),f++}h=e===f}else h=!0;if(h){if(void 0!==t.readonly){const e=f;if("boolean"!=typeof t.readonly){const e={params:{type:"boolean"}};null===p?p=[e]:p.push(e),f++}h=e===f}else h=!0;if(h){if(void 0!==t.store){const e=f;if("pack"!==t.store){const e={params:{}};null===p?p=[e]:p.push(e),f++}h=e===f}else h=!0;if(h){if(void 0!==t.type){const e=f;if("filesystem"!==t.type){const e={params:{}};null===p?p=[e]:p.push(e),f++}h=e===f}else h=!0;if(h)if(void 0!==t.version){const e=f;if("string"!=typeof t.version){const e={params:{type:"string"}};null===p?p=[e]:p.push(e),f++}h=e===f}else h=!0}}}}}}}}}}}}}}}}}}}}}else{const e={params:{type:"object"}};null===p?p=[e]:p.push(e),f++}m=o===f,c=c||m}}if(!c){const e={params:{}};return null===p?p=[e]:p.push(e),f++,o.errors=p,!1}return f=u,null!==p&&(u?p.length=u:p=null),o.errors=p,0===f}function s(e,{instancePath:t="",parentData:n,parentDataProperty:r,rootData:i=e}={}){let a=null,l=0;const p=l;let f=!1;const u=l;if(!0!==e){const e={params:{}};null===a?a=[e]:a.push(e),l++}var c=u===l;if(f=f||c,!f){const s=l;o(e,{instancePath:t,parentData:n,parentDataProperty:r,rootData:i})||(a=null===a?o.errors:a.concat(o.errors),l=a.length),c=s===l,f=f||c}if(!f){const e={params:{}};return null===a?a=[e]:a.push(e),l++,s.errors=a,!1}return l=p,null!==a&&(p?a.length=p:a=null),s.errors=a,0===l}const i={type:"object",additionalProperties:!1,properties:{asyncChunks:{type:"boolean"},baseUri:{type:"string"},chunkLoading:{$ref:"#/definitions/ChunkLoading"},dependOn:{anyOf:[{type:"array",items:{type:"string",minLength:1},minItems:1,uniqueItems:!0},{type:"string",minLength:1}]},filename:{$ref:"#/definitions/EntryFilename"},import:{$ref:"#/definitions/EntryItem"},layer:{$ref:"#/definitions/Layer"},library:{$ref:"#/definitions/LibraryOptions"},publicPath:{$ref:"#/definitions/PublicPath"},runtime:{$ref:"#/definitions/EntryRuntime"},wasmLoading:{$ref:"#/definitions/WasmLoading"}},required:["import"]};function a(e,{instancePath:t="",parentData:n,parentDataProperty:r,rootData:o=e}={}){let s=null,i=0;const l=i;let p=!1;const f=i;if(!1!==e){const e={params:{}};null===s?s=[e]:s.push(e),i++}var u=f===i;if(p=p||u,!p){const t=i,n=i;let r=!1;const o=i;if("jsonp"!==e&&"import-scripts"!==e&&"require"!==e&&"async-node"!==e&&"import"!==e){const e={params:{}};null===s?s=[e]:s.push(e),i++}var c=o===i;if(r=r||c,!r){const t=i;if("string"!=typeof e){const e={params:{type:"string"}};null===s?s=[e]:s.push(e),i++}c=t===i,r=r||c}if(r)i=n,null!==s&&(n?s.length=n:s=null);else{const e={params:{}};null===s?s=[e]:s.push(e),i++}u=t===i,p=p||u}if(!p){const e={params:{}};return null===s?s=[e]:s.push(e),i++,a.errors=s,!1}return i=l,null!==s&&(l?s.length=l:s=null),a.errors=s,0===i}function l(t,{instancePath:n="",parentData:r,parentDataProperty:o,rootData:s=t}={}){let i=null,a=0;const p=a;let f=!1,u=null;const c=a,y=a;let m=!1;const d=a;if(a===d)if("string"==typeof t){if(t.includes("!")||!1!==e.test(t)){const e={params:{}};null===i?i=[e]:i.push(e),a++}else if(t.length<1){const e={params:{}};null===i?i=[e]:i.push(e),a++}}else{const e={params:{type:"string"}};null===i?i=[e]:i.push(e),a++}var h=d===a;if(m=m||h,!m){const e=a;if(!(t instanceof Function)){const e={params:{}};null===i?i=[e]:i.push(e),a++}h=e===a,m=m||h}if(m)a=y,null!==i&&(y?i.length=y:i=null);else{const e={params:{}};null===i?i=[e]:i.push(e),a++}if(c===a&&(f=!0,u=0),!f){const e={params:{passingSchemas:u}};return null===i?i=[e]:i.push(e),a++,l.errors=i,!1}return a=p,null!==i&&(p?i.length=p:i=null),l.errors=i,0===a}function p(e,{instancePath:t="",parentData:n,parentDataProperty:r,rootData:o=e}={}){let s=null,i=0;const a=i;let l=!1;const f=i;if("string"!=typeof e){const e={params:{type:"string"}};null===s?s=[e]:s.push(e),i++}var u=f===i;if(l=l||u,!l){const t=i;if(i==i)if(e&&"object"==typeof e&&!Array.isArray(e)){const t=i;for(const t in e)if("amd"!==t&&"commonjs"!==t&&"commonjs2"!==t&&"root"!==t){const e={params:{additionalProperty:t}};null===s?s=[e]:s.push(e),i++;break}if(t===i){if(void 0!==e.amd){const t=i;if("string"!=typeof e.amd){const e={params:{type:"string"}};null===s?s=[e]:s.push(e),i++}var c=t===i}else c=!0;if(c){if(void 0!==e.commonjs){const t=i;if("string"!=typeof e.commonjs){const e={params:{type:"string"}};null===s?s=[e]:s.push(e),i++}c=t===i}else c=!0;if(c){if(void 0!==e.commonjs2){const t=i;if("string"!=typeof e.commonjs2){const e={params:{type:"string"}};null===s?s=[e]:s.push(e),i++}c=t===i}else c=!0;if(c)if(void 0!==e.root){const t=i;if("string"!=typeof e.root){const e={params:{type:"string"}};null===s?s=[e]:s.push(e),i++}c=t===i}else c=!0}}}}else{const e={params:{type:"object"}};null===s?s=[e]:s.push(e),i++}u=t===i,l=l||u}if(!l){const e={params:{}};return null===s?s=[e]:s.push(e),i++,p.errors=s,!1}return i=a,null!==s&&(a?s.length=a:s=null),p.errors=s,0===i}function f(e,{instancePath:t="",parentData:n,parentDataProperty:r,rootData:o=e}={}){let s=null,i=0;const a=i;let l=!1;const p=i;if(i===p)if(Array.isArray(e))if(e.length<1){const e={params:{limit:1}};null===s?s=[e]:s.push(e),i++}else{const t=e.length;for(let n=0;n1){const r={};for(;n--;){let o=t[n];if("string"==typeof o){if("number"==typeof r[o]){e=r[o];const t={params:{i:n,j:e}};null===p?p=[t]:p.push(t),f++;break}r[o]=n}}}}}else{const e={params:{type:"array"}};null===p?p=[e]:p.push(e),f++}var g=s===f;if(o=o||g,!o){const e=f;if(f===e)if("string"==typeof t){if(t.length<1){const e={params:{}};null===p?p=[e]:p.push(e),f++}}else{const e={params:{type:"string"}};null===p?p=[e]:p.push(e),f++}g=e===f,o=o||g}if(!o){const e={params:{}};return null===p?p=[e]:p.push(e),f++,m.errors=p,!1}f=r,null!==p&&(r?p.length=r:p=null),d=n===f}else d=!0;if(d){if(void 0!==e.filename){const n=f;l(e.filename,{instancePath:t+"/filename",parentData:e,parentDataProperty:"filename",rootData:s})||(p=null===p?l.errors:p.concat(l.errors),f=p.length),d=n===f}else d=!0;if(d){if(void 0!==e.import){let t=e.import;const n=f,r=f;let o=!1;const s=f;if(f===s)if(Array.isArray(t))if(t.length<1){const e={params:{limit:1}};null===p?p=[e]:p.push(e),f++}else{var b=!0;const e=t.length;for(let n=0;n1){const r={};for(;n--;){let o=t[n];if("string"==typeof o){if("number"==typeof r[o]){e=r[o];const t={params:{i:n,j:e}};null===p?p=[t]:p.push(t),f++;break}r[o]=n}}}}}else{const e={params:{type:"array"}};null===p?p=[e]:p.push(e),f++}var v=s===f;if(o=o||v,!o){const e=f;if(f===e)if("string"==typeof t){if(t.length<1){const e={params:{}};null===p?p=[e]:p.push(e),f++}}else{const e={params:{type:"string"}};null===p?p=[e]:p.push(e),f++}v=e===f,o=o||v}if(!o){const e={params:{}};return null===p?p=[e]:p.push(e),f++,m.errors=p,!1}f=r,null!==p&&(r?p.length=r:p=null),d=n===f}else d=!0;if(d){if(void 0!==e.layer){let t=e.layer;const n=f,r=f;let o=!1;const s=f;if(null!==t){const e={params:{}};null===p?p=[e]:p.push(e),f++}var P=s===f;if(o=o||P,!o){const e=f;if(f===e)if("string"==typeof t){if(t.length<1){const e={params:{}};null===p?p=[e]:p.push(e),f++}}else{const e={params:{type:"string"}};null===p?p=[e]:p.push(e),f++}P=e===f,o=o||P}if(!o){const e={params:{}};return null===p?p=[e]:p.push(e),f++,m.errors=p,!1}f=r,null!==p&&(r?p.length=r:p=null),d=n===f}else d=!0;if(d){if(void 0!==e.library){const n=f;u(e.library,{instancePath:t+"/library",parentData:e,parentDataProperty:"library",rootData:s})||(p=null===p?u.errors:p.concat(u.errors),f=p.length),d=n===f}else d=!0;if(d){if(void 0!==e.publicPath){const n=f;c(e.publicPath,{instancePath:t+"/publicPath",parentData:e,parentDataProperty:"publicPath",rootData:s})||(p=null===p?c.errors:p.concat(c.errors),f=p.length),d=n===f}else d=!0;if(d){if(void 0!==e.runtime){let t=e.runtime;const n=f,r=f;let o=!1;const s=f;if(!1!==t){const e={params:{}};null===p?p=[e]:p.push(e),f++}var D=s===f;if(o=o||D,!o){const e=f;if(f===e)if("string"==typeof t){if(t.length<1){const e={params:{}};null===p?p=[e]:p.push(e),f++}}else{const e={params:{type:"string"}};null===p?p=[e]:p.push(e),f++}D=e===f,o=o||D}if(!o){const e={params:{}};return null===p?p=[e]:p.push(e),f++,m.errors=p,!1}f=r,null!==p&&(r?p.length=r:p=null),d=n===f}else d=!0;if(d)if(void 0!==e.wasmLoading){const n=f;y(e.wasmLoading,{instancePath:t+"/wasmLoading",parentData:e,parentDataProperty:"wasmLoading",rootData:s})||(p=null===p?y.errors:p.concat(y.errors),f=p.length),d=n===f}else d=!0}}}}}}}}}}}}}return m.errors=p,0===f}function d(e,{instancePath:t="",parentData:n,parentDataProperty:r,rootData:o=e}={}){let s=null,i=0;if(0===i){if(!e||"object"!=typeof e||Array.isArray(e))return d.errors=[{params:{type:"object"}}],!1;for(const n in e){let r=e[n];const f=i,u=i;let c=!1;const y=i,h=i;let g=!1;const b=i;if(i===b)if(Array.isArray(r))if(r.length<1){const e={params:{limit:1}};null===s?s=[e]:s.push(e),i++}else{var a=!0;const e=r.length;for(let t=0;t1){const n={};for(;t--;){let o=r[t];if("string"==typeof o){if("number"==typeof n[o]){e=n[o];const r={params:{i:t,j:e}};null===s?s=[r]:s.push(r),i++;break}n[o]=t}}}}}else{const e={params:{type:"array"}};null===s?s=[e]:s.push(e),i++}var l=b===i;if(g=g||l,!g){const e=i;if(i===e)if("string"==typeof r){if(r.length<1){const e={params:{}};null===s?s=[e]:s.push(e),i++}}else{const e={params:{type:"string"}};null===s?s=[e]:s.push(e),i++}l=e===i,g=g||l}if(g)i=h,null!==s&&(h?s.length=h:s=null);else{const e={params:{}};null===s?s=[e]:s.push(e),i++}var p=y===i;if(c=c||p,!c){const a=i;m(r,{instancePath:t+"/"+n.replace(/~/g,"~0").replace(/\//g,"~1"),parentData:e,parentDataProperty:n,rootData:o})||(s=null===s?m.errors:s.concat(m.errors),i=s.length),p=a===i,c=c||p}if(!c){const e={params:{}};return null===s?s=[e]:s.push(e),i++,d.errors=s,!1}if(i=u,null!==s&&(u?s.length=u:s=null),f!==i)break}}return d.errors=s,0===i}function h(e,{instancePath:t="",parentData:n,parentDataProperty:r,rootData:o=e}={}){let s=null,i=0;const a=i;let l=!1,p=null;const f=i,u=i;let c=!1;const y=i;if(i===y)if(Array.isArray(e))if(e.length<1){const e={params:{limit:1}};null===s?s=[e]:s.push(e),i++}else{var m=!0;const t=e.length;for(let n=0;n1){const r={};for(;n--;){let o=e[n];if("string"==typeof o){if("number"==typeof r[o]){t=r[o];const e={params:{i:n,j:t}};null===s?s=[e]:s.push(e),i++;break}r[o]=n}}}}}else{const e={params:{type:"array"}};null===s?s=[e]:s.push(e),i++}var d=y===i;if(c=c||d,!c){const t=i;if(i===t)if("string"==typeof e){if(e.length<1){const e={params:{}};null===s?s=[e]:s.push(e),i++}}else{const e={params:{type:"string"}};null===s?s=[e]:s.push(e),i++}d=t===i,c=c||d}if(c)i=u,null!==s&&(u?s.length=u:s=null);else{const e={params:{}};null===s?s=[e]:s.push(e),i++}if(f===i&&(l=!0,p=0),!l){const e={params:{passingSchemas:p}};return null===s?s=[e]:s.push(e),i++,h.errors=s,!1}return i=a,null!==s&&(a?s.length=a:s=null),h.errors=s,0===i}function g(e,{instancePath:t="",parentData:n,parentDataProperty:r,rootData:o=e}={}){let s=null,i=0;const a=i;let l=!1;const p=i;d(e,{instancePath:t,parentData:n,parentDataProperty:r,rootData:o})||(s=null===s?d.errors:s.concat(d.errors),i=s.length);var f=p===i;if(l=l||f,!l){const a=i;h(e,{instancePath:t,parentData:n,parentDataProperty:r,rootData:o})||(s=null===s?h.errors:s.concat(h.errors),i=s.length),f=a===i,l=l||f}if(!l){const e={params:{}};return null===s?s=[e]:s.push(e),i++,g.errors=s,!1}return i=a,null!==s&&(a?s.length=a:s=null),g.errors=s,0===i}function b(e,{instancePath:t="",parentData:n,parentDataProperty:r,rootData:o=e}={}){let s=null,i=0;const a=i;let l=!1;const p=i;if(!(e instanceof Function)){const e={params:{}};null===s?s=[e]:s.push(e),i++}var f=p===i;if(l=l||f,!l){const a=i;g(e,{instancePath:t,parentData:n,parentDataProperty:r,rootData:o})||(s=null===s?g.errors:s.concat(g.errors),i=s.length),f=a===i,l=l||f}if(!l){const e={params:{}};return null===s?s=[e]:s.push(e),i++,b.errors=s,!1}return i=a,null!==s&&(a?s.length=a:s=null),b.errors=s,0===i}const v={type:"object",additionalProperties:!1,properties:{asyncWebAssembly:{type:"boolean"},backCompat:{type:"boolean"},buildHttp:{anyOf:[{$ref:"#/definitions/HttpUriAllowedUris"},{$ref:"#/definitions/HttpUriOptions"}]},cacheUnaffected:{type:"boolean"},css:{type:"boolean"},futureDefaults:{type:"boolean"},layers:{type:"boolean"},lazyCompilation:{anyOf:[{type:"boolean"},{$ref:"#/definitions/LazyCompilationOptions"}]},outputModule:{type:"boolean"},syncWebAssembly:{type:"boolean"},topLevelAwait:{type:"boolean"}}},P=new RegExp("^https?://","u");function D(e,{instancePath:t="",parentData:n,parentDataProperty:r,rootData:o=e}={}){let s=null,i=0;const a=i;let l=!1,p=null;const f=i;if(i==i)if(Array.isArray(e)){const t=e.length;for(let n=0;n=",limit:0}};null===a?a=[e]:a.push(e),l++}}else{const e={params:{type:"number"}};null===a?a=[e]:a.push(e),l++}var u=y===l;if(c=c||u,!c){const t=l;if(l===t)if(e&&"object"==typeof e&&!Array.isArray(e))for(const t in e){const n=l;if("number"!=typeof e[t]){const e={params:{type:"number"}};null===a?a=[e]:a.push(e),l++}if(n!==l)break}else{const e={params:{type:"object"}};null===a?a=[e]:a.push(e),l++}u=t===l,c=c||u}if(c)l=f,null!==a&&(f?a.length=f:a=null);else{const e={params:{}};null===a?a=[e]:a.push(e),l++}if(i===l&&(o=!0,s=0),!o){const e={params:{passingSchemas:s}};return null===a?a=[e]:a.push(e),l++,Pe.errors=a,!1}l=r,null!==a&&(r?a.length=r:a=null),p=n===l}else p=!0;if(p){if(void 0!==t.filename){let n=t.filename;const r=l,o=l;let s=!1;const i=l;if(l===i)if("string"==typeof n){if(n.includes("!")||!1!==e.test(n)){const e={params:{}};null===a?a=[e]:a.push(e),l++}else if(n.length<1){const e={params:{}};null===a?a=[e]:a.push(e),l++}}else{const e={params:{type:"string"}};null===a?a=[e]:a.push(e),l++}var c=i===l;if(s=s||c,!s){const e=l;if(!(n instanceof Function)){const e={params:{}};null===a?a=[e]:a.push(e),l++}c=e===l,s=s||c}if(!s){const e={params:{}};return null===a?a=[e]:a.push(e),l++,Pe.errors=a,!1}l=o,null!==a&&(o?a.length=o:a=null),p=r===l}else p=!0;if(p){if(void 0!==t.idHint){const e=l;if("string"!=typeof t.idHint)return Pe.errors=[{params:{type:"string"}}],!1;p=e===l}else p=!0;if(p){if(void 0!==t.layer){let e=t.layer;const n=l,r=l;let o=!1;const s=l;if(!(e instanceof RegExp)){const e={params:{}};null===a?a=[e]:a.push(e),l++}var y=s===l;if(o=o||y,!o){const t=l;if("string"!=typeof e){const e={params:{type:"string"}};null===a?a=[e]:a.push(e),l++}if(y=t===l,o=o||y,!o){const t=l;if(!(e instanceof Function)){const e={params:{}};null===a?a=[e]:a.push(e),l++}y=t===l,o=o||y}}if(!o){const e={params:{}};return null===a?a=[e]:a.push(e),l++,Pe.errors=a,!1}l=r,null!==a&&(r?a.length=r:a=null),p=n===l}else p=!0;if(p){if(void 0!==t.maxAsyncRequests){let e=t.maxAsyncRequests;const n=l;if(l===n){if("number"!=typeof e)return Pe.errors=[{params:{type:"number"}}],!1;if(e<1||isNaN(e))return Pe.errors=[{params:{comparison:">=",limit:1}}],!1}p=n===l}else p=!0;if(p){if(void 0!==t.maxAsyncSize){let e=t.maxAsyncSize;const n=l,r=l;let o=!1,s=null;const i=l,f=l;let u=!1;const c=l;if(l===c)if("number"==typeof e){if(e<0||isNaN(e)){const e={params:{comparison:">=",limit:0}};null===a?a=[e]:a.push(e),l++}}else{const e={params:{type:"number"}};null===a?a=[e]:a.push(e),l++}var m=c===l;if(u=u||m,!u){const t=l;if(l===t)if(e&&"object"==typeof e&&!Array.isArray(e))for(const t in e){const n=l;if("number"!=typeof e[t]){const e={params:{type:"number"}};null===a?a=[e]:a.push(e),l++}if(n!==l)break}else{const e={params:{type:"object"}};null===a?a=[e]:a.push(e),l++}m=t===l,u=u||m}if(u)l=f,null!==a&&(f?a.length=f:a=null);else{const e={params:{}};null===a?a=[e]:a.push(e),l++}if(i===l&&(o=!0,s=0),!o){const e={params:{passingSchemas:s}};return null===a?a=[e]:a.push(e),l++,Pe.errors=a,!1}l=r,null!==a&&(r?a.length=r:a=null),p=n===l}else p=!0;if(p){if(void 0!==t.maxInitialRequests){let e=t.maxInitialRequests;const n=l;if(l===n){if("number"!=typeof e)return Pe.errors=[{params:{type:"number"}}],!1;if(e<1||isNaN(e))return Pe.errors=[{params:{comparison:">=",limit:1}}],!1}p=n===l}else p=!0;if(p){if(void 0!==t.maxInitialSize){let e=t.maxInitialSize;const n=l,r=l;let o=!1,s=null;const i=l,f=l;let u=!1;const c=l;if(l===c)if("number"==typeof e){if(e<0||isNaN(e)){const e={params:{comparison:">=",limit:0}};null===a?a=[e]:a.push(e),l++}}else{const e={params:{type:"number"}};null===a?a=[e]:a.push(e),l++}var d=c===l;if(u=u||d,!u){const t=l;if(l===t)if(e&&"object"==typeof e&&!Array.isArray(e))for(const t in e){const n=l;if("number"!=typeof e[t]){const e={params:{type:"number"}};null===a?a=[e]:a.push(e),l++}if(n!==l)break}else{const e={params:{type:"object"}};null===a?a=[e]:a.push(e),l++}d=t===l,u=u||d}if(u)l=f,null!==a&&(f?a.length=f:a=null);else{const e={params:{}};null===a?a=[e]:a.push(e),l++}if(i===l&&(o=!0,s=0),!o){const e={params:{passingSchemas:s}};return null===a?a=[e]:a.push(e),l++,Pe.errors=a,!1}l=r,null!==a&&(r?a.length=r:a=null),p=n===l}else p=!0;if(p){if(void 0!==t.maxSize){let e=t.maxSize;const n=l,r=l;let o=!1,s=null;const i=l,f=l;let u=!1;const c=l;if(l===c)if("number"==typeof e){if(e<0||isNaN(e)){const e={params:{comparison:">=",limit:0}};null===a?a=[e]:a.push(e),l++}}else{const e={params:{type:"number"}};null===a?a=[e]:a.push(e),l++}var h=c===l;if(u=u||h,!u){const t=l;if(l===t)if(e&&"object"==typeof e&&!Array.isArray(e))for(const t in e){const n=l;if("number"!=typeof e[t]){const e={params:{type:"number"}};null===a?a=[e]:a.push(e),l++}if(n!==l)break}else{const e={params:{type:"object"}};null===a?a=[e]:a.push(e),l++}h=t===l,u=u||h}if(u)l=f,null!==a&&(f?a.length=f:a=null);else{const e={params:{}};null===a?a=[e]:a.push(e),l++}if(i===l&&(o=!0,s=0),!o){const e={params:{passingSchemas:s}};return null===a?a=[e]:a.push(e),l++,Pe.errors=a,!1}l=r,null!==a&&(r?a.length=r:a=null),p=n===l}else p=!0;if(p){if(void 0!==t.minChunks){let e=t.minChunks;const n=l;if(l===n){if("number"!=typeof e)return Pe.errors=[{params:{type:"number"}}],!1;if(e<1||isNaN(e))return Pe.errors=[{params:{comparison:">=",limit:1}}],!1}p=n===l}else p=!0;if(p){if(void 0!==t.minRemainingSize){let e=t.minRemainingSize;const n=l,r=l;let o=!1,s=null;const i=l,f=l;let u=!1;const c=l;if(l===c)if("number"==typeof e){if(e<0||isNaN(e)){const e={params:{comparison:">=",limit:0}};null===a?a=[e]:a.push(e),l++}}else{const e={params:{type:"number"}};null===a?a=[e]:a.push(e),l++}var g=c===l;if(u=u||g,!u){const t=l;if(l===t)if(e&&"object"==typeof e&&!Array.isArray(e))for(const t in e){const n=l;if("number"!=typeof e[t]){const e={params:{type:"number"}};null===a?a=[e]:a.push(e),l++}if(n!==l)break}else{const e={params:{type:"object"}};null===a?a=[e]:a.push(e),l++}g=t===l,u=u||g}if(u)l=f,null!==a&&(f?a.length=f:a=null);else{const e={params:{}};null===a?a=[e]:a.push(e),l++}if(i===l&&(o=!0,s=0),!o){const e={params:{passingSchemas:s}};return null===a?a=[e]:a.push(e),l++,Pe.errors=a,!1}l=r,null!==a&&(r?a.length=r:a=null),p=n===l}else p=!0;if(p){if(void 0!==t.minSize){let e=t.minSize;const n=l,r=l;let o=!1,s=null;const i=l,f=l;let u=!1;const c=l;if(l===c)if("number"==typeof e){if(e<0||isNaN(e)){const e={params:{comparison:">=",limit:0}};null===a?a=[e]:a.push(e),l++}}else{const e={params:{type:"number"}};null===a?a=[e]:a.push(e),l++}var b=c===l;if(u=u||b,!u){const t=l;if(l===t)if(e&&"object"==typeof e&&!Array.isArray(e))for(const t in e){const n=l;if("number"!=typeof e[t]){const e={params:{type:"number"}};null===a?a=[e]:a.push(e),l++}if(n!==l)break}else{const e={params:{type:"object"}};null===a?a=[e]:a.push(e),l++}b=t===l,u=u||b}if(u)l=f,null!==a&&(f?a.length=f:a=null);else{const e={params:{}};null===a?a=[e]:a.push(e),l++}if(i===l&&(o=!0,s=0),!o){const e={params:{passingSchemas:s}};return null===a?a=[e]:a.push(e),l++,Pe.errors=a,!1}l=r,null!==a&&(r?a.length=r:a=null),p=n===l}else p=!0;if(p){if(void 0!==t.minSizeReduction){let e=t.minSizeReduction;const n=l,r=l;let o=!1,s=null;const i=l,f=l;let u=!1;const c=l;if(l===c)if("number"==typeof e){if(e<0||isNaN(e)){const e={params:{comparison:">=",limit:0}};null===a?a=[e]:a.push(e),l++}}else{const e={params:{type:"number"}};null===a?a=[e]:a.push(e),l++}var v=c===l;if(u=u||v,!u){const t=l;if(l===t)if(e&&"object"==typeof e&&!Array.isArray(e))for(const t in e){const n=l;if("number"!=typeof e[t]){const e={params:{type:"number"}};null===a?a=[e]:a.push(e),l++}if(n!==l)break}else{const e={params:{type:"object"}};null===a?a=[e]:a.push(e),l++}v=t===l,u=u||v}if(u)l=f,null!==a&&(f?a.length=f:a=null);else{const e={params:{}};null===a?a=[e]:a.push(e),l++}if(i===l&&(o=!0,s=0),!o){const e={params:{passingSchemas:s}};return null===a?a=[e]:a.push(e),l++,Pe.errors=a,!1}l=r,null!==a&&(r?a.length=r:a=null),p=n===l}else p=!0;if(p){if(void 0!==t.name){let e=t.name;const n=l,r=l;let o=!1;const s=l;if(!1!==e){const e={params:{}};null===a?a=[e]:a.push(e),l++}var P=s===l;if(o=o||P,!o){const t=l;if("string"!=typeof e){const e={params:{type:"string"}};null===a?a=[e]:a.push(e),l++}if(P=t===l,o=o||P,!o){const t=l;if(!(e instanceof Function)){const e={params:{}};null===a?a=[e]:a.push(e),l++}P=t===l,o=o||P}}if(!o){const e={params:{}};return null===a?a=[e]:a.push(e),l++,Pe.errors=a,!1}l=r,null!==a&&(r?a.length=r:a=null),p=n===l}else p=!0;if(p){if(void 0!==t.priority){const e=l;if("number"!=typeof t.priority)return Pe.errors=[{params:{type:"number"}}],!1;p=e===l}else p=!0;if(p){if(void 0!==t.reuseExistingChunk){const e=l;if("boolean"!=typeof t.reuseExistingChunk)return Pe.errors=[{params:{type:"boolean"}}],!1;p=e===l}else p=!0;if(p){if(void 0!==t.test){let e=t.test;const n=l,r=l;let o=!1;const s=l;if(!(e instanceof RegExp)){const e={params:{}};null===a?a=[e]:a.push(e),l++}var D=s===l;if(o=o||D,!o){const t=l;if("string"!=typeof e){const e={params:{type:"string"}};null===a?a=[e]:a.push(e),l++}if(D=t===l,o=o||D,!o){const t=l;if(!(e instanceof Function)){const e={params:{}};null===a?a=[e]:a.push(e),l++}D=t===l,o=o||D}}if(!o){const e={params:{}};return null===a?a=[e]:a.push(e),l++,Pe.errors=a,!1}l=r,null!==a&&(r?a.length=r:a=null),p=n===l}else p=!0;if(p){if(void 0!==t.type){let e=t.type;const n=l,r=l;let o=!1;const s=l;if(!(e instanceof RegExp)){const e={params:{}};null===a?a=[e]:a.push(e),l++}var O=s===l;if(o=o||O,!o){const t=l;if("string"!=typeof e){const e={params:{type:"string"}};null===a?a=[e]:a.push(e),l++}if(O=t===l,o=o||O,!o){const t=l;if(!(e instanceof Function)){const e={params:{}};null===a?a=[e]:a.push(e),l++}O=t===l,o=o||O}}if(!o){const e={params:{}};return null===a?a=[e]:a.push(e),l++,Pe.errors=a,!1}l=r,null!==a&&(r?a.length=r:a=null),p=n===l}else p=!0;if(p)if(void 0!==t.usedExports){const e=l;if("boolean"!=typeof t.usedExports)return Pe.errors=[{params:{type:"boolean"}}],!1;p=e===l}else p=!0}}}}}}}}}}}}}}}}}}}}}}}return Pe.errors=a,0===l}function De(t,{instancePath:r="",parentData:o,parentDataProperty:s,rootData:i=t}={}){let a=null,l=0;if(0===l){if(!t||"object"!=typeof t||Array.isArray(t))return De.errors=[{params:{type:"object"}}],!1;{const o=l;for(const e in t)if(!n.call(be.properties,e))return De.errors=[{params:{additionalProperty:e}}],!1;if(o===l){if(void 0!==t.automaticNameDelimiter){let e=t.automaticNameDelimiter;const n=l;if(l===n){if("string"!=typeof e)return De.errors=[{params:{type:"string"}}],!1;if(e.length<1)return De.errors=[{params:{}}],!1}var p=n===l}else p=!0;if(p){if(void 0!==t.cacheGroups){let e=t.cacheGroups;const n=l,o=l,s=l;if(l===s)if(e&&"object"==typeof e&&!Array.isArray(e)){let t;if(void 0===e.test&&(t="test")){const e={};null===a?a=[e]:a.push(e),l++}else if(void 0!==e.test){let t=e.test;const n=l;let r=!1;const o=l;if(!(t instanceof RegExp)){const e={};null===a?a=[e]:a.push(e),l++}var f=o===l;if(r=r||f,!r){const e=l;if("string"!=typeof t){const e={};null===a?a=[e]:a.push(e),l++}if(f=e===l,r=r||f,!r){const e=l;if(!(t instanceof Function)){const e={};null===a?a=[e]:a.push(e),l++}f=e===l,r=r||f}}if(r)l=n,null!==a&&(n?a.length=n:a=null);else{const e={};null===a?a=[e]:a.push(e),l++}}}else{const e={};null===a?a=[e]:a.push(e),l++}if(s===l)return De.errors=[{params:{}}],!1;if(l=o,null!==a&&(o?a.length=o:a=null),l===n){if(!e||"object"!=typeof e||Array.isArray(e))return De.errors=[{params:{type:"object"}}],!1;for(const t in e){let n=e[t];const o=l,s=l;let p=!1;const f=l;if(!1!==n){const e={params:{}};null===a?a=[e]:a.push(e),l++}var u=f===l;if(p=p||u,!p){const o=l;if(!(n instanceof RegExp)){const e={params:{}};null===a?a=[e]:a.push(e),l++}if(u=o===l,p=p||u,!p){const o=l;if("string"!=typeof n){const e={params:{type:"string"}};null===a?a=[e]:a.push(e),l++}if(u=o===l,p=p||u,!p){const o=l;if(!(n instanceof Function)){const e={params:{}};null===a?a=[e]:a.push(e),l++}if(u=o===l,p=p||u,!p){const o=l;Pe(n,{instancePath:r+"/cacheGroups/"+t.replace(/~/g,"~0").replace(/\//g,"~1"),parentData:e,parentDataProperty:t,rootData:i})||(a=null===a?Pe.errors:a.concat(Pe.errors),l=a.length),u=o===l,p=p||u}}}}if(!p){const e={params:{}};return null===a?a=[e]:a.push(e),l++,De.errors=a,!1}if(l=s,null!==a&&(s?a.length=s:a=null),o!==l)break}}p=n===l}else p=!0;if(p){if(void 0!==t.chunks){let e=t.chunks;const n=l,r=l;let o=!1;const s=l;if("initial"!==e&&"async"!==e&&"all"!==e){const e={params:{}};null===a?a=[e]:a.push(e),l++}var c=s===l;if(o=o||c,!o){const t=l;if(!(e instanceof RegExp)){const e={params:{}};null===a?a=[e]:a.push(e),l++}if(c=t===l,o=o||c,!o){const t=l;if(!(e instanceof Function)){const e={params:{}};null===a?a=[e]:a.push(e),l++}c=t===l,o=o||c}}if(!o){const e={params:{}};return null===a?a=[e]:a.push(e),l++,De.errors=a,!1}l=r,null!==a&&(r?a.length=r:a=null),p=n===l}else p=!0;if(p){if(void 0!==t.defaultSizeTypes){let e=t.defaultSizeTypes;const n=l;if(l===n){if(!Array.isArray(e))return De.errors=[{params:{type:"array"}}],!1;if(e.length<1)return De.errors=[{params:{limit:1}}],!1;{const t=e.length;for(let n=0;n=",limit:0}};null===a?a=[e]:a.push(e),l++}}else{const e={params:{type:"number"}};null===a?a=[e]:a.push(e),l++}var y=c===l;if(u=u||y,!u){const t=l;if(l===t)if(e&&"object"==typeof e&&!Array.isArray(e))for(const t in e){const n=l;if("number"!=typeof e[t]){const e={params:{type:"number"}};null===a?a=[e]:a.push(e),l++}if(n!==l)break}else{const e={params:{type:"object"}};null===a?a=[e]:a.push(e),l++}y=t===l,u=u||y}if(u)l=f,null!==a&&(f?a.length=f:a=null);else{const e={params:{}};null===a?a=[e]:a.push(e),l++}if(i===l&&(o=!0,s=0),!o){const e={params:{passingSchemas:s}};return null===a?a=[e]:a.push(e),l++,De.errors=a,!1}l=r,null!==a&&(r?a.length=r:a=null),p=n===l}else p=!0;if(p){if(void 0!==t.fallbackCacheGroup){let e=t.fallbackCacheGroup;const n=l;if(l===n){if(!e||"object"!=typeof e||Array.isArray(e))return De.errors=[{params:{type:"object"}}],!1;{const t=l;for(const t in e)if("automaticNameDelimiter"!==t&&"chunks"!==t&&"maxAsyncSize"!==t&&"maxInitialSize"!==t&&"maxSize"!==t&&"minSize"!==t&&"minSizeReduction"!==t)return De.errors=[{params:{additionalProperty:t}}],!1;if(t===l){if(void 0!==e.automaticNameDelimiter){let t=e.automaticNameDelimiter;const n=l;if(l===n){if("string"!=typeof t)return De.errors=[{params:{type:"string"}}],!1;if(t.length<1)return De.errors=[{params:{}}],!1}var m=n===l}else m=!0;if(m){if(void 0!==e.chunks){let t=e.chunks;const n=l,r=l;let o=!1;const s=l;if("initial"!==t&&"async"!==t&&"all"!==t){const e={params:{}};null===a?a=[e]:a.push(e),l++}var d=s===l;if(o=o||d,!o){const e=l;if(!(t instanceof RegExp)){const e={params:{}};null===a?a=[e]:a.push(e),l++}if(d=e===l,o=o||d,!o){const e=l;if(!(t instanceof Function)){const e={params:{}};null===a?a=[e]:a.push(e),l++}d=e===l,o=o||d}}if(!o){const e={params:{}};return null===a?a=[e]:a.push(e),l++,De.errors=a,!1}l=r,null!==a&&(r?a.length=r:a=null),m=n===l}else m=!0;if(m){if(void 0!==e.maxAsyncSize){let t=e.maxAsyncSize;const n=l,r=l;let o=!1,s=null;const i=l,p=l;let f=!1;const u=l;if(l===u)if("number"==typeof t){if(t<0||isNaN(t)){const e={params:{comparison:">=",limit:0}};null===a?a=[e]:a.push(e),l++}}else{const e={params:{type:"number"}};null===a?a=[e]:a.push(e),l++}var h=u===l;if(f=f||h,!f){const e=l;if(l===e)if(t&&"object"==typeof t&&!Array.isArray(t))for(const e in t){const n=l;if("number"!=typeof t[e]){const e={params:{type:"number"}};null===a?a=[e]:a.push(e),l++}if(n!==l)break}else{const e={params:{type:"object"}};null===a?a=[e]:a.push(e),l++}h=e===l,f=f||h}if(f)l=p,null!==a&&(p?a.length=p:a=null);else{const e={params:{}};null===a?a=[e]:a.push(e),l++}if(i===l&&(o=!0,s=0),!o){const e={params:{passingSchemas:s}};return null===a?a=[e]:a.push(e),l++,De.errors=a,!1}l=r,null!==a&&(r?a.length=r:a=null),m=n===l}else m=!0;if(m){if(void 0!==e.maxInitialSize){let t=e.maxInitialSize;const n=l,r=l;let o=!1,s=null;const i=l,p=l;let f=!1;const u=l;if(l===u)if("number"==typeof t){if(t<0||isNaN(t)){const e={params:{comparison:">=",limit:0}};null===a?a=[e]:a.push(e),l++}}else{const e={params:{type:"number"}};null===a?a=[e]:a.push(e),l++}var g=u===l;if(f=f||g,!f){const e=l;if(l===e)if(t&&"object"==typeof t&&!Array.isArray(t))for(const e in t){const n=l;if("number"!=typeof t[e]){const e={params:{type:"number"}};null===a?a=[e]:a.push(e),l++}if(n!==l)break}else{const e={params:{type:"object"}};null===a?a=[e]:a.push(e),l++}g=e===l,f=f||g}if(f)l=p,null!==a&&(p?a.length=p:a=null);else{const e={params:{}};null===a?a=[e]:a.push(e),l++}if(i===l&&(o=!0,s=0),!o){const e={params:{passingSchemas:s}};return null===a?a=[e]:a.push(e),l++,De.errors=a,!1}l=r,null!==a&&(r?a.length=r:a=null),m=n===l}else m=!0;if(m){if(void 0!==e.maxSize){let t=e.maxSize;const n=l,r=l;let o=!1,s=null;const i=l,p=l;let f=!1;const u=l;if(l===u)if("number"==typeof t){if(t<0||isNaN(t)){const e={params:{comparison:">=",limit:0}};null===a?a=[e]:a.push(e),l++}}else{const e={params:{type:"number"}};null===a?a=[e]:a.push(e),l++}var b=u===l;if(f=f||b,!f){const e=l;if(l===e)if(t&&"object"==typeof t&&!Array.isArray(t))for(const e in t){const n=l;if("number"!=typeof t[e]){const e={params:{type:"number"}};null===a?a=[e]:a.push(e),l++}if(n!==l)break}else{const e={params:{type:"object"}};null===a?a=[e]:a.push(e),l++}b=e===l,f=f||b}if(f)l=p,null!==a&&(p?a.length=p:a=null);else{const e={params:{}};null===a?a=[e]:a.push(e),l++}if(i===l&&(o=!0,s=0),!o){const e={params:{passingSchemas:s}};return null===a?a=[e]:a.push(e),l++,De.errors=a,!1}l=r,null!==a&&(r?a.length=r:a=null),m=n===l}else m=!0;if(m){if(void 0!==e.minSize){let t=e.minSize;const n=l,r=l;let o=!1,s=null;const i=l,p=l;let f=!1;const u=l;if(l===u)if("number"==typeof t){if(t<0||isNaN(t)){const e={params:{comparison:">=",limit:0}};null===a?a=[e]:a.push(e),l++}}else{const e={params:{type:"number"}};null===a?a=[e]:a.push(e),l++}var v=u===l;if(f=f||v,!f){const e=l;if(l===e)if(t&&"object"==typeof t&&!Array.isArray(t))for(const e in t){const n=l;if("number"!=typeof t[e]){const e={params:{type:"number"}};null===a?a=[e]:a.push(e),l++}if(n!==l)break}else{const e={params:{type:"object"}};null===a?a=[e]:a.push(e),l++}v=e===l,f=f||v}if(f)l=p,null!==a&&(p?a.length=p:a=null);else{const e={params:{}};null===a?a=[e]:a.push(e),l++}if(i===l&&(o=!0,s=0),!o){const e={params:{passingSchemas:s}};return null===a?a=[e]:a.push(e),l++,De.errors=a,!1}l=r,null!==a&&(r?a.length=r:a=null),m=n===l}else m=!0;if(m)if(void 0!==e.minSizeReduction){let t=e.minSizeReduction;const n=l,r=l;let o=!1,s=null;const i=l,p=l;let f=!1;const u=l;if(l===u)if("number"==typeof t){if(t<0||isNaN(t)){const e={params:{comparison:">=",limit:0}};null===a?a=[e]:a.push(e),l++}}else{const e={params:{type:"number"}};null===a?a=[e]:a.push(e),l++}var P=u===l;if(f=f||P,!f){const e=l;if(l===e)if(t&&"object"==typeof t&&!Array.isArray(t))for(const e in t){const n=l;if("number"!=typeof t[e]){const e={params:{type:"number"}};null===a?a=[e]:a.push(e),l++}if(n!==l)break}else{const e={params:{type:"object"}};null===a?a=[e]:a.push(e),l++}P=e===l,f=f||P}if(f)l=p,null!==a&&(p?a.length=p:a=null);else{const e={params:{}};null===a?a=[e]:a.push(e),l++}if(i===l&&(o=!0,s=0),!o){const e={params:{passingSchemas:s}};return null===a?a=[e]:a.push(e),l++,De.errors=a,!1}l=r,null!==a&&(r?a.length=r:a=null),m=n===l}else m=!0}}}}}}}}p=n===l}else p=!0;if(p){if(void 0!==t.filename){let n=t.filename;const r=l,o=l;let s=!1;const i=l;if(l===i)if("string"==typeof n){if(n.includes("!")||!1!==e.test(n)){const e={params:{}};null===a?a=[e]:a.push(e),l++}else if(n.length<1){const e={params:{}};null===a?a=[e]:a.push(e),l++}}else{const e={params:{type:"string"}};null===a?a=[e]:a.push(e),l++}var D=i===l;if(s=s||D,!s){const e=l;if(!(n instanceof Function)){const e={params:{}};null===a?a=[e]:a.push(e),l++}D=e===l,s=s||D}if(!s){const e={params:{}};return null===a?a=[e]:a.push(e),l++,De.errors=a,!1}l=o,null!==a&&(o?a.length=o:a=null),p=r===l}else p=!0;if(p){if(void 0!==t.hidePathInfo){const e=l;if("boolean"!=typeof t.hidePathInfo)return De.errors=[{params:{type:"boolean"}}],!1;p=e===l}else p=!0;if(p){if(void 0!==t.maxAsyncRequests){let e=t.maxAsyncRequests;const n=l;if(l===n){if("number"!=typeof e)return De.errors=[{params:{type:"number"}}],!1;if(e<1||isNaN(e))return De.errors=[{params:{comparison:">=",limit:1}}],!1}p=n===l}else p=!0;if(p){if(void 0!==t.maxAsyncSize){let e=t.maxAsyncSize;const n=l,r=l;let o=!1,s=null;const i=l,f=l;let u=!1;const c=l;if(l===c)if("number"==typeof e){if(e<0||isNaN(e)){const e={params:{comparison:">=",limit:0}};null===a?a=[e]:a.push(e),l++}}else{const e={params:{type:"number"}};null===a?a=[e]:a.push(e),l++}var O=c===l;if(u=u||O,!u){const t=l;if(l===t)if(e&&"object"==typeof e&&!Array.isArray(e))for(const t in e){const n=l;if("number"!=typeof e[t]){const e={params:{type:"number"}};null===a?a=[e]:a.push(e),l++}if(n!==l)break}else{const e={params:{type:"object"}};null===a?a=[e]:a.push(e),l++}O=t===l,u=u||O}if(u)l=f,null!==a&&(f?a.length=f:a=null);else{const e={params:{}};null===a?a=[e]:a.push(e),l++}if(i===l&&(o=!0,s=0),!o){const e={params:{passingSchemas:s}};return null===a?a=[e]:a.push(e),l++,De.errors=a,!1}l=r,null!==a&&(r?a.length=r:a=null),p=n===l}else p=!0;if(p){if(void 0!==t.maxInitialRequests){let e=t.maxInitialRequests;const n=l;if(l===n){if("number"!=typeof e)return De.errors=[{params:{type:"number"}}],!1;if(e<1||isNaN(e))return De.errors=[{params:{comparison:">=",limit:1}}],!1}p=n===l}else p=!0;if(p){if(void 0!==t.maxInitialSize){let e=t.maxInitialSize;const n=l,r=l;let o=!1,s=null;const i=l,f=l;let u=!1;const c=l;if(l===c)if("number"==typeof e){if(e<0||isNaN(e)){const e={params:{comparison:">=",limit:0}};null===a?a=[e]:a.push(e),l++}}else{const e={params:{type:"number"}};null===a?a=[e]:a.push(e),l++}var C=c===l;if(u=u||C,!u){const t=l;if(l===t)if(e&&"object"==typeof e&&!Array.isArray(e))for(const t in e){const n=l;if("number"!=typeof e[t]){const e={params:{type:"number"}};null===a?a=[e]:a.push(e),l++}if(n!==l)break}else{const e={params:{type:"object"}};null===a?a=[e]:a.push(e),l++}C=t===l,u=u||C}if(u)l=f,null!==a&&(f?a.length=f:a=null);else{const e={params:{}};null===a?a=[e]:a.push(e),l++}if(i===l&&(o=!0,s=0),!o){const e={params:{passingSchemas:s}};return null===a?a=[e]:a.push(e),l++,De.errors=a,!1}l=r,null!==a&&(r?a.length=r:a=null),p=n===l}else p=!0;if(p){if(void 0!==t.maxSize){let e=t.maxSize;const n=l,r=l;let o=!1,s=null;const i=l,f=l;let u=!1;const c=l;if(l===c)if("number"==typeof e){if(e<0||isNaN(e)){const e={params:{comparison:">=",limit:0}};null===a?a=[e]:a.push(e),l++}}else{const e={params:{type:"number"}};null===a?a=[e]:a.push(e),l++}var x=c===l;if(u=u||x,!u){const t=l;if(l===t)if(e&&"object"==typeof e&&!Array.isArray(e))for(const t in e){const n=l;if("number"!=typeof e[t]){const e={params:{type:"number"}};null===a?a=[e]:a.push(e),l++}if(n!==l)break}else{const e={params:{type:"object"}};null===a?a=[e]:a.push(e),l++}x=t===l,u=u||x}if(u)l=f,null!==a&&(f?a.length=f:a=null);else{const e={params:{}};null===a?a=[e]:a.push(e),l++}if(i===l&&(o=!0,s=0),!o){const e={params:{passingSchemas:s}};return null===a?a=[e]:a.push(e),l++,De.errors=a,!1}l=r,null!==a&&(r?a.length=r:a=null),p=n===l}else p=!0;if(p){if(void 0!==t.minChunks){let e=t.minChunks;const n=l;if(l===n){if("number"!=typeof e)return De.errors=[{params:{type:"number"}}],!1;if(e<1||isNaN(e))return De.errors=[{params:{comparison:">=",limit:1}}],!1}p=n===l}else p=!0;if(p){if(void 0!==t.minRemainingSize){let e=t.minRemainingSize;const n=l,r=l;let o=!1,s=null;const i=l,f=l;let u=!1;const c=l;if(l===c)if("number"==typeof e){if(e<0||isNaN(e)){const e={params:{comparison:">=",limit:0}};null===a?a=[e]:a.push(e),l++}}else{const e={params:{type:"number"}};null===a?a=[e]:a.push(e),l++}var A=c===l;if(u=u||A,!u){const t=l;if(l===t)if(e&&"object"==typeof e&&!Array.isArray(e))for(const t in e){const n=l;if("number"!=typeof e[t]){const e={params:{type:"number"}};null===a?a=[e]:a.push(e),l++}if(n!==l)break}else{const e={params:{type:"object"}};null===a?a=[e]:a.push(e),l++}A=t===l,u=u||A}if(u)l=f,null!==a&&(f?a.length=f:a=null);else{const e={params:{}};null===a?a=[e]:a.push(e),l++}if(i===l&&(o=!0,s=0),!o){const e={params:{passingSchemas:s}};return null===a?a=[e]:a.push(e),l++,De.errors=a,!1}l=r,null!==a&&(r?a.length=r:a=null),p=n===l}else p=!0;if(p){if(void 0!==t.minSize){let e=t.minSize;const n=l,r=l;let o=!1,s=null;const i=l,f=l;let u=!1;const c=l;if(l===c)if("number"==typeof e){if(e<0||isNaN(e)){const e={params:{comparison:">=",limit:0}};null===a?a=[e]:a.push(e),l++}}else{const e={params:{type:"number"}};null===a?a=[e]:a.push(e),l++}var $=c===l;if(u=u||$,!u){const t=l;if(l===t)if(e&&"object"==typeof e&&!Array.isArray(e))for(const t in e){const n=l;if("number"!=typeof e[t]){const e={params:{type:"number"}};null===a?a=[e]:a.push(e),l++}if(n!==l)break}else{const e={params:{type:"object"}};null===a?a=[e]:a.push(e),l++}$=t===l,u=u||$}if(u)l=f,null!==a&&(f?a.length=f:a=null);else{const e={params:{}};null===a?a=[e]:a.push(e),l++}if(i===l&&(o=!0,s=0),!o){const e={params:{passingSchemas:s}};return null===a?a=[e]:a.push(e),l++,De.errors=a,!1}l=r,null!==a&&(r?a.length=r:a=null),p=n===l}else p=!0;if(p){if(void 0!==t.minSizeReduction){let e=t.minSizeReduction;const n=l,r=l;let o=!1,s=null;const i=l,f=l;let u=!1;const c=l;if(l===c)if("number"==typeof e){if(e<0||isNaN(e)){const e={params:{comparison:">=",limit:0}};null===a?a=[e]:a.push(e),l++}}else{const e={params:{type:"number"}};null===a?a=[e]:a.push(e),l++}var k=c===l;if(u=u||k,!u){const t=l;if(l===t)if(e&&"object"==typeof e&&!Array.isArray(e))for(const t in e){const n=l;if("number"!=typeof e[t]){const e={params:{type:"number"}};null===a?a=[e]:a.push(e),l++}if(n!==l)break}else{const e={params:{type:"object"}};null===a?a=[e]:a.push(e),l++}k=t===l,u=u||k}if(u)l=f,null!==a&&(f?a.length=f:a=null);else{const e={params:{}};null===a?a=[e]:a.push(e),l++}if(i===l&&(o=!0,s=0),!o){const e={params:{passingSchemas:s}};return null===a?a=[e]:a.push(e),l++,De.errors=a,!1}l=r,null!==a&&(r?a.length=r:a=null),p=n===l}else p=!0;if(p){if(void 0!==t.name){let e=t.name;const n=l,r=l;let o=!1;const s=l;if(!1!==e){const e={params:{}};null===a?a=[e]:a.push(e),l++}var j=s===l;if(o=o||j,!o){const t=l;if("string"!=typeof e){const e={params:{type:"string"}};null===a?a=[e]:a.push(e),l++}if(j=t===l,o=o||j,!o){const t=l;if(!(e instanceof Function)){const e={params:{}};null===a?a=[e]:a.push(e),l++}j=t===l,o=o||j}}if(!o){const e={params:{}};return null===a?a=[e]:a.push(e),l++,De.errors=a,!1}l=r,null!==a&&(r?a.length=r:a=null),p=n===l}else p=!0;if(p)if(void 0!==t.usedExports){const e=l;if("boolean"!=typeof t.usedExports)return De.errors=[{params:{type:"boolean"}}],!1;p=e===l}else p=!0}}}}}}}}}}}}}}}}}}}}return De.errors=a,0===l}function Oe(e,{instancePath:t="",parentData:r,parentDataProperty:o,rootData:s=e}={}){let i=null,a=0;if(0===a){if(!e||"object"!=typeof e||Array.isArray(e))return Oe.errors=[{params:{type:"object"}}],!1;{const r=a;for(const t in e)if(!n.call(ge.properties,t))return Oe.errors=[{params:{additionalProperty:t}}],!1;if(r===a){if(void 0!==e.checkWasmTypes){const t=a;if("boolean"!=typeof e.checkWasmTypes)return Oe.errors=[{params:{type:"boolean"}}],!1;var l=t===a}else l=!0;if(l){if(void 0!==e.chunkIds){let t=e.chunkIds;const n=a;if("natural"!==t&&"named"!==t&&"deterministic"!==t&&"size"!==t&&"total-size"!==t&&!1!==t)return Oe.errors=[{params:{}}],!1;l=n===a}else l=!0;if(l){if(void 0!==e.concatenateModules){const t=a;if("boolean"!=typeof e.concatenateModules)return Oe.errors=[{params:{type:"boolean"}}],!1;l=t===a}else l=!0;if(l){if(void 0!==e.emitOnErrors){const t=a;if("boolean"!=typeof e.emitOnErrors)return Oe.errors=[{params:{type:"boolean"}}],!1;l=t===a}else l=!0;if(l){if(void 0!==e.flagIncludedChunks){const t=a;if("boolean"!=typeof e.flagIncludedChunks)return Oe.errors=[{params:{type:"boolean"}}],!1;l=t===a}else l=!0;if(l){if(void 0!==e.innerGraph){const t=a;if("boolean"!=typeof e.innerGraph)return Oe.errors=[{params:{type:"boolean"}}],!1;l=t===a}else l=!0;if(l){if(void 0!==e.mangleExports){let t=e.mangleExports;const n=a,r=a;let o=!1;const s=a;if("size"!==t&&"deterministic"!==t){const e={params:{}};null===i?i=[e]:i.push(e),a++}var p=s===a;if(o=o||p,!o){const e=a;if("boolean"!=typeof t){const e={params:{type:"boolean"}};null===i?i=[e]:i.push(e),a++}p=e===a,o=o||p}if(!o){const e={params:{}};return null===i?i=[e]:i.push(e),a++,Oe.errors=i,!1}a=r,null!==i&&(r?i.length=r:i=null),l=n===a}else l=!0;if(l){if(void 0!==e.mangleWasmImports){const t=a;if("boolean"!=typeof e.mangleWasmImports)return Oe.errors=[{params:{type:"boolean"}}],!1;l=t===a}else l=!0;if(l){if(void 0!==e.mergeDuplicateChunks){const t=a;if("boolean"!=typeof e.mergeDuplicateChunks)return Oe.errors=[{params:{type:"boolean"}}],!1;l=t===a}else l=!0;if(l){if(void 0!==e.minimize){const t=a;if("boolean"!=typeof e.minimize)return Oe.errors=[{params:{type:"boolean"}}],!1;l=t===a}else l=!0;if(l){if(void 0!==e.minimizer){let t=e.minimizer;const n=a;if(a===n){if(!Array.isArray(t))return Oe.errors=[{params:{type:"array"}}],!1;{const e=t.length;for(let n=0;n=",limit:1}}],!1}u=n===f}else u=!0;if(u){if(void 0!==t.hashFunction){let e=t.hashFunction;const n=f,r=f;let o=!1;const s=f;if(f===s)if("string"==typeof e){if(e.length<1){const e={params:{}};null===l?l=[e]:l.push(e),f++}}else{const e={params:{type:"string"}};null===l?l=[e]:l.push(e),f++}var v=s===f;if(o=o||v,!o){const t=f;if(!(e instanceof Function)){const e={params:{}};null===l?l=[e]:l.push(e),f++}v=t===f,o=o||v}if(!o){const e={params:{}};return null===l?l=[e]:l.push(e),f++,ze.errors=l,!1}f=r,null!==l&&(r?l.length=r:l=null),u=n===f}else u=!0;if(u){if(void 0!==t.hashSalt){let e=t.hashSalt;const n=f;if(f==f){if("string"!=typeof e)return ze.errors=[{params:{type:"string"}}],!1;if(e.length<1)return ze.errors=[{params:{}}],!1}u=n===f}else u=!0;if(u){if(void 0!==t.hotUpdateChunkFilename){let n=t.hotUpdateChunkFilename;const r=f;if(f==f){if("string"!=typeof n)return ze.errors=[{params:{type:"string"}}],!1;if(n.includes("!")||!1!==e.test(n))return ze.errors=[{params:{}}],!1}u=r===f}else u=!0;if(u){if(void 0!==t.hotUpdateGlobal){const e=f;if("string"!=typeof t.hotUpdateGlobal)return ze.errors=[{params:{type:"string"}}],!1;u=e===f}else u=!0;if(u){if(void 0!==t.hotUpdateMainFilename){let n=t.hotUpdateMainFilename;const r=f;if(f==f){if("string"!=typeof n)return ze.errors=[{params:{type:"string"}}],!1;if(n.includes("!")||!1!==e.test(n))return ze.errors=[{params:{}}],!1}u=r===f}else u=!0;if(u){if(void 0!==t.ignoreBrowserWarnings){const e=f;if("boolean"!=typeof t.ignoreBrowserWarnings)return ze.errors=[{params:{type:"boolean"}}],!1;u=e===f}else u=!0;if(u){if(void 0!==t.iife){const e=f;if("boolean"!=typeof t.iife)return ze.errors=[{params:{type:"boolean"}}],!1;u=e===f}else u=!0;if(u){if(void 0!==t.importFunctionName){const e=f;if("string"!=typeof t.importFunctionName)return ze.errors=[{params:{type:"string"}}],!1;u=e===f}else u=!0;if(u){if(void 0!==t.importMetaName){const e=f;if("string"!=typeof t.importMetaName)return ze.errors=[{params:{type:"string"}}],!1;u=e===f}else u=!0;if(u){if(void 0!==t.library){const e=f;Le(t.library,{instancePath:r+"/library",parentData:t,parentDataProperty:"library",rootData:i})||(l=null===l?Le.errors:l.concat(Le.errors),f=l.length),u=e===f}else u=!0;if(u){if(void 0!==t.libraryExport){let e=t.libraryExport;const n=f,r=f;let o=!1,s=null;const i=f,a=f;let p=!1;const c=f;if(f===c)if(Array.isArray(e)){const t=e.length;for(let n=0;n=",limit:1}}],!1}c=t===f}else c=!0;if(c){if(void 0!==r.performance){const e=f;Me(r.performance,{instancePath:o+"/performance",parentData:r,parentDataProperty:"performance",rootData:l})||(p=null===p?Me.errors:p.concat(Me.errors),f=p.length),c=e===f}else c=!0;if(c){if(void 0!==r.plugins){const e=f;we(r.plugins,{instancePath:o+"/plugins",parentData:r,parentDataProperty:"plugins",rootData:l})||(p=null===p?we.errors:p.concat(we.errors),f=p.length),c=e===f}else c=!0;if(c){if(void 0!==r.profile){const e=f;if("boolean"!=typeof r.profile)return _e.errors=[{params:{type:"boolean"}}],!1;c=e===f}else c=!0;if(c){if(void 0!==r.recordsInputPath){let t=r.recordsInputPath;const n=f,o=f;let s=!1;const i=f;if(!1!==t){const e={params:{}};null===p?p=[e]:p.push(e),f++}var v=i===f;if(s=s||v,!s){const n=f;if(f===n)if("string"==typeof t){if(t.includes("!")||!0!==e.test(t)){const e={params:{}};null===p?p=[e]:p.push(e),f++}}else{const e={params:{type:"string"}};null===p?p=[e]:p.push(e),f++}v=n===f,s=s||v}if(!s){const e={params:{}};return null===p?p=[e]:p.push(e),f++,_e.errors=p,!1}f=o,null!==p&&(o?p.length=o:p=null),c=n===f}else c=!0;if(c){if(void 0!==r.recordsOutputPath){let t=r.recordsOutputPath;const n=f,o=f;let s=!1;const i=f;if(!1!==t){const e={params:{}};null===p?p=[e]:p.push(e),f++}var P=i===f;if(s=s||P,!s){const n=f;if(f===n)if("string"==typeof t){if(t.includes("!")||!0!==e.test(t)){const e={params:{}};null===p?p=[e]:p.push(e),f++}}else{const e={params:{type:"string"}};null===p?p=[e]:p.push(e),f++}P=n===f,s=s||P}if(!s){const e={params:{}};return null===p?p=[e]:p.push(e),f++,_e.errors=p,!1}f=o,null!==p&&(o?p.length=o:p=null),c=n===f}else c=!0;if(c){if(void 0!==r.recordsPath){let t=r.recordsPath;const n=f,o=f;let s=!1;const i=f;if(!1!==t){const e={params:{}};null===p?p=[e]:p.push(e),f++}var D=i===f;if(s=s||D,!s){const n=f;if(f===n)if("string"==typeof t){if(t.includes("!")||!0!==e.test(t)){const e={params:{}};null===p?p=[e]:p.push(e),f++}}else{const e={params:{type:"string"}};null===p?p=[e]:p.push(e),f++}D=n===f,s=s||D}if(!s){const e={params:{}};return null===p?p=[e]:p.push(e),f++,_e.errors=p,!1}f=o,null!==p&&(o?p.length=o:p=null),c=n===f}else c=!0;if(c){if(void 0!==r.resolve){const e=f;Te(r.resolve,{instancePath:o+"/resolve",parentData:r,parentDataProperty:"resolve",rootData:l})||(p=null===p?Te.errors:p.concat(Te.errors),f=p.length),c=e===f}else c=!0;if(c){if(void 0!==r.resolveLoader){const e=f;Ne(r.resolveLoader,{instancePath:o+"/resolveLoader",parentData:r,parentDataProperty:"resolveLoader",rootData:l})||(p=null===p?Ne.errors:p.concat(Ne.errors),f=p.length),c=e===f}else c=!0;if(c){if(void 0!==r.snapshot){let t=r.snapshot;const n=f;if(f==f){if(!t||"object"!=typeof t||Array.isArray(t))return _e.errors=[{params:{type:"object"}}],!1;{const n=f;for(const e in t)if("buildDependencies"!==e&&"immutablePaths"!==e&&"managedPaths"!==e&&"module"!==e&&"resolve"!==e&&"resolveBuildDependencies"!==e&&"unmanagedPaths"!==e)return _e.errors=[{params:{additionalProperty:e}}],!1;if(n===f){if(void 0!==t.buildDependencies){let e=t.buildDependencies;const n=f;if(f===n){if(!e||"object"!=typeof e||Array.isArray(e))return _e.errors=[{params:{type:"object"}}],!1;{const t=f;for(const t in e)if("hash"!==t&&"timestamp"!==t)return _e.errors=[{params:{additionalProperty:t}}],!1;if(t===f){if(void 0!==e.hash){const t=f;if("boolean"!=typeof e.hash)return _e.errors=[{params:{type:"boolean"}}],!1;var O=t===f}else O=!0;if(O)if(void 0!==e.timestamp){const t=f;if("boolean"!=typeof e.timestamp)return _e.errors=[{params:{type:"boolean"}}],!1;O=t===f}else O=!0}}}var C=n===f}else C=!0;if(C){if(void 0!==t.immutablePaths){let n=t.immutablePaths;const r=f;if(f===r){if(!Array.isArray(n))return _e.errors=[{params:{type:"array"}}],!1;{const t=n.length;for(let r=0;r string)" }, @@ -98,6 +103,10 @@ ], "additionalProperties": false, "properties": { + "binary": { + "description": "Whether or not this asset module should be considered binary. This can be set to 'false' to treat this asset module as text.", + "type": "boolean" + }, "dataUrl": { "$ref": "#/definitions/AssetGeneratorDataUrl" }, @@ -107,6 +116,12 @@ }, "filename": { "$ref": "#/definitions/FilenameTemplate" + }, + "outputPath": { + "$ref": "#/definitions/AssetModuleOutputPath" + }, + "publicPath": { + "$ref": "#/definitions/RawPublicPath" } } }, @@ -115,6 +130,10 @@ "type": "object", "additionalProperties": false, "properties": { + "binary": { + "description": "Whether or not this asset module should be considered binary. This can be set to 'false' to treat this asset module as text.", + "type": "boolean" + }, "dataUrl": { "$ref": "#/definitions/AssetGeneratorDataUrl" } @@ -133,6 +152,19 @@ } ] }, + "AssetModuleOutputPath": { + "description": "Emit the asset in the specified folder relative to 'output.path'. This should only be needed when custom 'publicPath' is specified to match the folder structure there.", + "anyOf": [ + { + "type": "string", + "absolutePath": false + }, + { + "instanceof": "Function", + "tsType": "((pathData: import(\"../lib/Compilation\").PathData, assetInfo?: import(\"../lib/Compilation\").AssetInfo) => string)" + } + ] + }, "AssetParserDataUrlFunction": { "description": "Function that executes for module and should return whenever asset should be inlined as DataUrl.", "instanceof": "Function", @@ -172,12 +204,22 @@ "type": "object", "additionalProperties": false, "properties": { + "binary": { + "description": "Whether or not this asset module should be considered binary. This can be set to 'false' to treat this asset module as text.", + "type": "boolean" + }, "emit": { "description": "Emit an output asset from this asset module. This can be set to 'false' to omit emitting e. g. for SSR.", "type": "boolean" }, "filename": { "$ref": "#/definitions/FilenameTemplate" + }, + "outputPath": { + "$ref": "#/definitions/AssetModuleOutputPath" + }, + "publicPath": { + "$ref": "#/definitions/RawPublicPath" } } }, @@ -237,10 +279,10 @@ ] }, "ChunkFormat": { - "description": "The format of chunks (formats included by default are 'array-push' (web/WebWorker), 'commonjs' (node.js), but others might be added by plugins).", + "description": "The format of chunks (formats included by default are 'array-push' (web/WebWorker), 'commonjs' (node.js), 'module' (ESM), but others might be added by plugins).", "anyOf": [ { - "enum": ["array-push", "commonjs", false] + "enum": ["array-push", "commonjs", "module", false] }, { "type": "string" @@ -252,7 +294,7 @@ "type": "number" }, "ChunkLoading": { - "description": "The method of loading chunks (methods included by default are 'jsonp' (web), 'importScripts' (WebWorker), 'require' (sync node.js), 'async-node' (async node.js), but others might be added by plugins).", + "description": "The method of loading chunks (methods included by default are 'jsonp' (web), 'import' (ESM), 'importScripts' (WebWorker), 'require' (sync node.js), 'async-node' (async node.js), but others might be added by plugins).", "anyOf": [ { "enum": [false] @@ -267,10 +309,10 @@ "type": "string" }, "ChunkLoadingType": { - "description": "The method of loading chunks (methods included by default are 'jsonp' (web), 'importScripts' (WebWorker), 'require' (sync node.js), 'async-node' (async node.js), but others might be added by plugins).", + "description": "The method of loading chunks (methods included by default are 'jsonp' (web), 'import' (ESM), 'importScripts' (WebWorker), 'require' (sync node.js), 'async-node' (async node.js), but others might be added by plugins).", "anyOf": [ { - "enum": ["jsonp", "import-scripts", "require", "async-node"] + "enum": ["jsonp", "import-scripts", "require", "async-node", "import"] }, { "type": "string" @@ -329,6 +371,170 @@ "description": "This option enables cross-origin loading of chunks.", "enum": [false, "anonymous", "use-credentials"] }, + "CssAutoGeneratorOptions": { + "description": "Generator options for css/auto modules.", + "type": "object", + "additionalProperties": false, + "properties": { + "esModule": { + "$ref": "#/definitions/CssGeneratorEsModule" + }, + "exportsConvention": { + "$ref": "#/definitions/CssGeneratorExportsConvention" + }, + "exportsOnly": { + "$ref": "#/definitions/CssGeneratorExportsOnly" + }, + "localIdentName": { + "$ref": "#/definitions/CssGeneratorLocalIdentName" + } + } + }, + "CssAutoParserOptions": { + "description": "Parser options for css/auto modules.", + "type": "object", + "additionalProperties": false, + "properties": { + "namedExports": { + "$ref": "#/definitions/CssParserNamedExports" + } + } + }, + "CssChunkFilename": { + "description": "Specifies the filename template of non-initial output css files on disk. You must **not** specify an absolute path here, but the path may contain folders separated by '/'! The specified path is joined with the value of the 'output.path' option to determine the location on disk.", + "oneOf": [ + { + "$ref": "#/definitions/FilenameTemplate" + } + ] + }, + "CssFilename": { + "description": "Specifies the filename template of output css files on disk. You must **not** specify an absolute path here, but the path may contain folders separated by '/'! The specified path is joined with the value of the 'output.path' option to determine the location on disk.", + "oneOf": [ + { + "$ref": "#/definitions/FilenameTemplate" + } + ] + }, + "CssGeneratorEsModule": { + "description": "Configure the generated JS modules that use the ES modules syntax.", + "type": "boolean" + }, + "CssGeneratorExportsConvention": { + "description": "Specifies the convention of exported names.", + "anyOf": [ + { + "enum": [ + "as-is", + "camel-case", + "camel-case-only", + "dashes", + "dashes-only" + ] + }, + { + "instanceof": "Function", + "tsType": "((name: string) => string)" + } + ] + }, + "CssGeneratorExportsOnly": { + "description": "Avoid generating and loading a stylesheet and only embed exports from css into output javascript files.", + "type": "boolean" + }, + "CssGeneratorLocalIdentName": { + "description": "Configure the generated local ident name.", + "type": "string" + }, + "CssGeneratorOptions": { + "description": "Generator options for css modules.", + "type": "object", + "additionalProperties": false, + "properties": { + "esModule": { + "$ref": "#/definitions/CssGeneratorEsModule" + }, + "exportsOnly": { + "$ref": "#/definitions/CssGeneratorExportsOnly" + } + } + }, + "CssGlobalGeneratorOptions": { + "description": "Generator options for css/global modules.", + "type": "object", + "additionalProperties": false, + "properties": { + "esModule": { + "$ref": "#/definitions/CssGeneratorEsModule" + }, + "exportsConvention": { + "$ref": "#/definitions/CssGeneratorExportsConvention" + }, + "exportsOnly": { + "$ref": "#/definitions/CssGeneratorExportsOnly" + }, + "localIdentName": { + "$ref": "#/definitions/CssGeneratorLocalIdentName" + } + } + }, + "CssGlobalParserOptions": { + "description": "Parser options for css/global modules.", + "type": "object", + "additionalProperties": false, + "properties": { + "namedExports": { + "$ref": "#/definitions/CssParserNamedExports" + } + } + }, + "CssHeadDataCompression": { + "description": "Compress the data in the head tag of CSS files.", + "type": "boolean" + }, + "CssModuleGeneratorOptions": { + "description": "Generator options for css/module modules.", + "type": "object", + "additionalProperties": false, + "properties": { + "esModule": { + "$ref": "#/definitions/CssGeneratorEsModule" + }, + "exportsConvention": { + "$ref": "#/definitions/CssGeneratorExportsConvention" + }, + "exportsOnly": { + "$ref": "#/definitions/CssGeneratorExportsOnly" + }, + "localIdentName": { + "$ref": "#/definitions/CssGeneratorLocalIdentName" + } + } + }, + "CssModuleParserOptions": { + "description": "Parser options for css/module modules.", + "type": "object", + "additionalProperties": false, + "properties": { + "namedExports": { + "$ref": "#/definitions/CssParserNamedExports" + } + } + }, + "CssParserNamedExports": { + "description": "Use ES modules named export for css exports.", + "type": "boolean" + }, + "CssParserOptions": { + "description": "Parser options for css modules.", + "type": "object", + "additionalProperties": false, + "properties": { + "namedExports": { + "$ref": "#/definitions/CssParserNamedExports" + } + } + }, "Dependencies": { "description": "References to other configurations to depend on.", "type": "array", @@ -339,7 +545,16 @@ }, "DevServer": { "description": "Options for the webpack-dev-server.", - "type": "object" + "anyOf": [ + { + "description": "Disable dev server.", + "enum": [false] + }, + { + "description": "Options for the webpack-dev-server.", + "type": "object" + } + ] }, "DevTool": { "description": "A developer tool to enhance debugging (false | eval | [inline-|hidden-|eval-][nosources-][cheap-[module-]]source-map).", @@ -428,6 +643,14 @@ "type": "object", "additionalProperties": false, "properties": { + "asyncChunks": { + "description": "Enable/disable creating async chunks that are loaded on demand.", + "type": "boolean" + }, + "baseUri": { + "description": "Base uri for this entry.", + "type": "string" + }, "chunkLoading": { "$ref": "#/definitions/ChunkLoading" }, @@ -464,6 +687,9 @@ "library": { "$ref": "#/definitions/LibraryOptions" }, + "publicPath": { + "$ref": "#/definitions/PublicPath" + }, "runtime": { "$ref": "#/definitions/EntryRuntime" }, @@ -478,6 +704,14 @@ "type": "object", "additionalProperties": false, "properties": { + "asyncChunks": { + "description": "Enable/disable creating async chunks that are loaded on demand.", + "type": "boolean" + }, + "baseUri": { + "description": "Base uri for this entry.", + "type": "string" + }, "chunkLoading": { "$ref": "#/definitions/ChunkLoading" }, @@ -512,6 +746,9 @@ "library": { "$ref": "#/definitions/LibraryOptions" }, + "publicPath": { + "$ref": "#/definitions/PublicPath" + }, "runtime": { "$ref": "#/definitions/EntryRuntime" }, @@ -587,8 +824,15 @@ }, "EntryRuntime": { "description": "The name of the runtime chunk. If set a runtime chunk with this name is created or an existing entrypoint is used as runtime.", - "type": "string", - "minLength": 1 + "anyOf": [ + { + "enum": [false] + }, + { + "type": "string", + "minLength": 1 + } + ] }, "EntryStatic": { "description": "A static entry description.", @@ -630,6 +874,10 @@ "description": "The environment supports arrow functions ('() => { ... }').", "type": "boolean" }, + "asyncFunction": { + "description": "The environment supports async function and await ('async function () { await ... }').", + "type": "boolean" + }, "bigIntLiteral": { "description": "The environment supports BigInt as literal (123n).", "type": "boolean" @@ -642,81 +890,195 @@ "description": "The environment supports destructuring ('{ a, b } = obj').", "type": "boolean" }, + "document": { + "description": "The environment supports 'document'.", + "type": "boolean" + }, "dynamicImport": { "description": "The environment supports an async import() function to import EcmaScript modules.", "type": "boolean" }, + "dynamicImportInWorker": { + "description": "The environment supports an async import() is available when creating a worker.", + "type": "boolean" + }, "forOf": { "description": "The environment supports 'for of' iteration ('for (const x of array) { ... }').", "type": "boolean" }, + "globalThis": { + "description": "The environment supports 'globalThis'.", + "type": "boolean" + }, "module": { "description": "The environment supports EcmaScript Module syntax to import EcmaScript modules (import ... from '...').", "type": "boolean" + }, + "nodePrefixForCoreModules": { + "description": "The environment supports `node:` prefix for Node.js core modules.", + "type": "boolean" + }, + "optionalChaining": { + "description": "The environment supports optional chaining ('obj?.a' or 'obj?.()').", + "type": "boolean" + }, + "templateLiteral": { + "description": "The environment supports template literals.", + "type": "boolean" } } }, "Experiments": { "description": "Enables/Disables experiments (experimental features with relax SemVer compatibility).", "type": "object", + "implements": ["#/definitions/ExperimentsCommon"], "additionalProperties": false, "properties": { - "asset": { - "description": "Allow module type 'asset' to generate assets.", + "asyncWebAssembly": { + "description": "Support WebAssembly as asynchronous EcmaScript Module.", + "type": "boolean" + }, + "backCompat": { + "description": "Enable backward-compat layer with deprecation warnings for many webpack 4 APIs.", + "type": "boolean" + }, + "buildHttp": { + "description": "Build http(s): urls using a lockfile and resource content cache.", + "anyOf": [ + { + "$ref": "#/definitions/HttpUriAllowedUris" + }, + { + "$ref": "#/definitions/HttpUriOptions" + } + ] + }, + "cacheUnaffected": { + "description": "Enable additional in memory caching of modules that are unchanged and reference only unchanged modules.", + "type": "boolean" + }, + "css": { + "description": "Enable css support.", + "type": "boolean" + }, + "futureDefaults": { + "description": "Apply defaults of next major version.", + "type": "boolean" + }, + "layers": { + "description": "Enable module layers.", + "type": "boolean" + }, + "lazyCompilation": { + "description": "Compile entrypoints and import()s only when they are accessed.", + "anyOf": [ + { + "type": "boolean" + }, + { + "$ref": "#/definitions/LazyCompilationOptions" + } + ] + }, + "outputModule": { + "description": "Allow output javascript files as module source type.", + "type": "boolean" + }, + "syncWebAssembly": { + "description": "Support WebAssembly as synchronous EcmaScript Module (outdated).", + "type": "boolean" + }, + "topLevelAwait": { + "description": "Allow using top-level-await in EcmaScript Modules.", + "type": "boolean" + } + } + }, + "ExperimentsCommon": { + "description": "Enables/Disables experiments (experimental features with relax SemVer compatibility).", + "type": "object", + "additionalProperties": false, + "properties": { + "asyncWebAssembly": { + "description": "Support WebAssembly as asynchronous EcmaScript Module.", + "type": "boolean" + }, + "backCompat": { + "description": "Enable backward-compat layer with deprecation warnings for many webpack 4 APIs.", + "type": "boolean" + }, + "cacheUnaffected": { + "description": "Enable additional in memory caching of modules that are unchanged and reference only unchanged modules.", + "type": "boolean" + }, + "futureDefaults": { + "description": "Apply defaults of next major version.", + "type": "boolean" + }, + "layers": { + "description": "Enable module layers.", "type": "boolean" }, + "outputModule": { + "description": "Allow output javascript files as module source type.", + "type": "boolean" + }, + "syncWebAssembly": { + "description": "Support WebAssembly as synchronous EcmaScript Module (outdated).", + "type": "boolean" + }, + "topLevelAwait": { + "description": "Allow using top-level-await in EcmaScript Modules.", + "type": "boolean" + } + } + }, + "ExperimentsNormalized": { + "description": "Enables/Disables experiments (experimental features with relax SemVer compatibility).", + "type": "object", + "implements": ["#/definitions/ExperimentsCommon"], + "additionalProperties": false, + "properties": { "asyncWebAssembly": { "description": "Support WebAssembly as asynchronous EcmaScript Module.", "type": "boolean" }, + "backCompat": { + "description": "Enable backward-compat layer with deprecation warnings for many webpack 4 APIs.", + "type": "boolean" + }, + "buildHttp": { + "description": "Build http(s): urls using a lockfile and resource content cache.", + "oneOf": [ + { + "$ref": "#/definitions/HttpUriOptions" + } + ] + }, + "cacheUnaffected": { + "description": "Enable additional in memory caching of modules that are unchanged and reference only unchanged modules.", + "type": "boolean" + }, + "css": { + "description": "Enable css support.", + "type": "boolean" + }, + "futureDefaults": { + "description": "Apply defaults of next major version.", + "type": "boolean" + }, "layers": { - "description": "Enable module and chunk layers.", + "description": "Enable module layers.", "type": "boolean" }, "lazyCompilation": { "description": "Compile entrypoints and import()s only when they are accessed.", "anyOf": [ { - "type": "boolean" + "enum": [false] }, { - "type": "object", - "additionalProperties": false, - "properties": { - "backend": { - "description": "A custom backend.", - "instanceof": "Function", - "tsType": "(((compiler: import('../lib/Compiler'), client: string, callback: (err?: Error, api?: any) => void) => void) | ((compiler: import('../lib/Compiler'), client: string) => Promise))" - }, - "client": { - "description": "A custom client.", - "type": "string" - }, - "entries": { - "description": "Enable/disable lazy compilation for entries.", - "type": "boolean" - }, - "imports": { - "description": "Enable/disable lazy compilation for import() modules.", - "type": "boolean" - }, - "test": { - "description": "Specify which entrypoints or import()ed modules should be lazily compiled. This is matched with the imported module and not the entrypoint name.", - "anyOf": [ - { - "instanceof": "RegExp", - "tsType": "RegExp" - }, - { - "type": "string" - }, - { - "instanceof": "Function", - "tsType": "((module: import('../lib/Module')) => boolean)" - } - ] - } - } + "$ref": "#/definitions/LazyCompilationOptions" } ] }, @@ -734,6 +1096,24 @@ } } }, + "Extends": { + "description": "Extend configuration from another configuration (only works when using webpack-cli).", + "anyOf": [ + { + "type": "array", + "items": { + "$ref": "#/definitions/ExtendsItem" + } + }, + { + "$ref": "#/definitions/ExtendsItem" + } + ] + }, + "ExtendsItem": { + "description": "Path to the configuration to be extended (only works when using webpack-cli).", + "type": "string" + }, "ExternalItem": { "description": "Specify dependency that shouldn't be resolved by webpack, but should become dependencies of the resulting bundle. The kind of the dependency depends on `output.libraryTarget`.", "anyOf": [ @@ -773,7 +1153,7 @@ { "description": "The function is called on each dependency (`function(context, request, callback(err, result))`).", "instanceof": "Function", - "tsType": "(((data: ExternalItemFunctionData, callback: (err?: Error, result?: ExternalItemValue) => void) => void) | ((data: ExternalItemFunctionData) => Promise))" + "tsType": "(((data: ExternalItemFunctionData, callback: (err?: (Error | null), result?: ExternalItemValue) => void) => void) | ((data: ExternalItemFunctionData) => Promise))" } ] }, @@ -791,6 +1171,10 @@ "type": "object", "tsType": "import('../lib/ModuleFactory').ModuleFactoryCreateDataContextInfo" }, + "dependencyType": { + "description": "The category of the referencing dependencies.", + "type": "string" + }, "getResolve": { "description": "Get a resolve function with the current resolver options.", "instanceof": "Function", @@ -892,6 +1276,7 @@ "commonjs", "commonjs2", "commonjs-module", + "commonjs-static", "amd", "amd-require", "umd", @@ -900,14 +1285,29 @@ "system", "promise", "import", - "script" + "module-import", + "script", + "node-commonjs" ] }, + "Falsy": { + "description": "These values will be ignored by webpack and created to be used with '&&' or '||' to improve readability of configurations.", + "cli": { + "exclude": true + }, + "enum": [false, 0, "", null], + "undefinedAsNull": true, + "tsType": "false | 0 | '' | null | undefined" + }, "FileCacheOptions": { "description": "Options object for persistent file-based caching.", "type": "object", "additionalProperties": false, "properties": { + "allowCollectingMemory": { + "description": "Allows to collect unused memory allocated during deserialization. This requires copying data into smaller buffers and has a performance cost.", + "type": "boolean" + }, "buildDependencies": { "description": "Dependencies the build depends on (in multiple categories, default categories: 'defaultWebpack').", "type": "object", @@ -931,17 +1331,26 @@ "type": "string", "absolutePath": true }, + "compression": { + "description": "Compression type used for the cache files.", + "enum": [false, "gzip", "brotli"] + }, "hashAlgorithm": { "description": "Algorithm used for generation the hash (see node.js crypto package).", "type": "string" }, "idleTimeout": { - "description": "Time in ms after which idle period the cache storing should happen (only for store: 'pack' or 'idle').", + "description": "Time in ms after which idle period the cache storing should happen.", + "type": "number", + "minimum": 0 + }, + "idleTimeoutAfterLargeChanges": { + "description": "Time in ms after which idle period the cache storing should happen when larger changes has been detected (cumulative build time > 2 x avg cache store time).", "type": "number", "minimum": 0 }, "idleTimeoutForInitialStore": { - "description": "Time in ms after which idle period the initial cache storing should happen (only for store: 'pack' or 'idle').", + "description": "Time in ms after which idle period the initial cache storing should happen.", "type": "number", "minimum": 0 }, @@ -949,26 +1358,68 @@ "description": "List of paths that are managed by a package manager and contain a version or hash in its path so all files are immutable.", "type": "array", "items": { - "description": "A path to a immutable directory (usually a package manager cache directory).", - "type": "string", - "absolutePath": true, - "minLength": 1 + "description": "List of paths that are managed by a package manager and contain a version or hash in its path so all files are immutable.", + "anyOf": [ + { + "description": "A RegExp matching an immutable directory (usually a package manager cache directory, including the tailing slash)", + "instanceof": "RegExp", + "tsType": "RegExp" + }, + { + "description": "A path to an immutable directory (usually a package manager cache directory).", + "type": "string", + "absolutePath": true, + "minLength": 1 + } + ] } }, "managedPaths": { "description": "List of paths that are managed by a package manager and can be trusted to not be modified otherwise.", "type": "array", "items": { - "description": "A path to a managed directory (usually a node_modules directory).", - "type": "string", - "absolutePath": true, - "minLength": 1 + "description": "List of paths that are managed by a package manager and can be trusted to not be modified otherwise.", + "anyOf": [ + { + "description": "A RegExp matching a managed directory (usually a node_modules directory, including the tailing slash)", + "instanceof": "RegExp", + "tsType": "RegExp" + }, + { + "description": "A path to a managed directory (usually a node_modules directory).", + "type": "string", + "absolutePath": true, + "minLength": 1 + } + ] } }, + "maxAge": { + "description": "Time for which unused cache entries stay in the filesystem cache at minimum (in milliseconds).", + "type": "number", + "minimum": 0 + }, + "maxMemoryGenerations": { + "description": "Number of generations unused cache entries stay in memory cache at minimum (0 = no memory cache used, 1 = may be removed after unused for a single compilation, ..., Infinity: kept forever). Cache entries will be deserialized from disk when removed from memory cache.", + "type": "number", + "minimum": 0 + }, + "memoryCacheUnaffected": { + "description": "Additionally cache computation of modules that are unchanged and reference only unchanged modules in memory.", + "type": "boolean" + }, "name": { "description": "Name for the cache. Different names will lead to different coexisting caches.", "type": "string" }, + "profile": { + "description": "Track and log detailed timing information for individual cache items.", + "type": "boolean" + }, + "readonly": { + "description": "Enable/disable readonly mode.", + "type": "boolean" + }, "store": { "description": "When to store data to the filesystem. (pack: Store data when compiler is idle in a single file).", "enum": ["pack"] @@ -1069,6 +1520,18 @@ "asset/resource": { "$ref": "#/definitions/AssetResourceGeneratorOptions" }, + "css": { + "$ref": "#/definitions/CssGeneratorOptions" + }, + "css/auto": { + "$ref": "#/definitions/CssAutoGeneratorOptions" + }, + "css/global": { + "$ref": "#/definitions/CssGlobalGeneratorOptions" + }, + "css/module": { + "$ref": "#/definitions/CssModuleGeneratorOptions" + }, "javascript": { "$ref": "#/definitions/EmptyGeneratorOptions" }, @@ -1129,6 +1592,81 @@ "type": "string", "absolutePath": false }, + "HttpUriAllowedUris": { + "description": "List of allowed URIs for building http resources.", + "cli": { + "exclude": true + }, + "oneOf": [ + { + "$ref": "#/definitions/HttpUriOptionsAllowedUris" + } + ] + }, + "HttpUriOptions": { + "description": "Options for building http resources.", + "type": "object", + "additionalProperties": false, + "properties": { + "allowedUris": { + "$ref": "#/definitions/HttpUriOptionsAllowedUris" + }, + "cacheLocation": { + "description": "Location where resource content is stored for lockfile entries. It's also possible to disable storing by passing false.", + "anyOf": [ + { + "enum": [false] + }, + { + "type": "string", + "absolutePath": true + } + ] + }, + "frozen": { + "description": "When set, anything that would lead to a modification of the lockfile or any resource content, will result in an error.", + "type": "boolean" + }, + "lockfileLocation": { + "description": "Location of the lockfile.", + "type": "string", + "absolutePath": true + }, + "proxy": { + "description": "Proxy configuration, which can be used to specify a proxy server to use for HTTP requests.", + "type": "string" + }, + "upgrade": { + "description": "When set, resources of existing lockfile entries will be fetched and entries will be upgraded when resource content has changed.", + "type": "boolean" + } + }, + "required": ["allowedUris"] + }, + "HttpUriOptionsAllowedUris": { + "description": "List of allowed URIs (resp. the beginning of them).", + "type": "array", + "items": { + "description": "List of allowed URIs (resp. the beginning of them).", + "anyOf": [ + { + "description": "Allowed URI pattern.", + "instanceof": "RegExp", + "tsType": "RegExp" + }, + { + "description": "Allowed URI (resp. the beginning of it).", + "type": "string", + "pattern": "^https?://" + }, + { + "description": "Allowed URI filter function.", + "instanceof": "Function", + "tsType": "((uri: string) => boolean)" + } + ] + } + }, "IgnoreWarnings": { "description": "Ignore specific warnings.", "type": "array", @@ -1195,6 +1733,18 @@ "type": "object", "additionalProperties": false, "properties": { + "appendOnly": { + "description": "Only appends lines to the output. Avoids updating existing output e. g. for status messages. This option is only used when no custom console is provided.", + "type": "boolean" + }, + "colors": { + "description": "Enables/Disables colorful output. This option is only used when no custom console is provided.", + "type": "boolean" + }, + "console": { + "description": "Custom console used for logging.", + "tsType": "Console" + }, "debug": { "description": "Enable debug logging for specific loggers.", "anyOf": [ @@ -1210,6 +1760,10 @@ "level": { "description": "Log level.", "enum": ["none", "error", "warn", "info", "log", "verbose"] + }, + "stream": { + "description": "Stream used for logging output. Defaults to process.stderr. This option is only used when no custom console is provided.", + "tsType": "NodeJS.WritableStream" } } }, @@ -1233,6 +1787,51 @@ "description": "Enable/disable parsing of magic comments in CommonJs syntax.", "type": "boolean" }, + "createRequire": { + "description": "Enable/disable parsing \"import { createRequire } from \"module\"\" and evaluating createRequire().", + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "string" + } + ] + }, + "dynamicImportFetchPriority": { + "description": "Specifies global fetchPriority for dynamic import.", + "enum": ["low", "high", "auto", false] + }, + "dynamicImportMode": { + "description": "Specifies global mode for dynamic import.", + "enum": ["eager", "weak", "lazy", "lazy-once"] + }, + "dynamicImportPrefetch": { + "description": "Specifies global prefetch for dynamic import.", + "anyOf": [ + { + "type": "number" + }, + { + "type": "boolean" + } + ] + }, + "dynamicImportPreload": { + "description": "Specifies global preload for dynamic import.", + "anyOf": [ + { + "type": "number" + }, + { + "type": "boolean" + } + ] + }, + "exportsPresence": { + "description": "Specifies the behavior of invalid export names in \"import ... from ...\" and \"export ... from ...\".", + "enum": ["error", "warn", "auto", false] + }, "exprContextCritical": { "description": "Enable warnings for full dynamic dependencies.", "type": "boolean" @@ -1265,9 +1864,29 @@ "description": "Enable/disable parsing of import() syntax.", "type": "boolean" }, + "importExportsPresence": { + "description": "Specifies the behavior of invalid export names in \"import ... from ...\".", + "enum": ["error", "warn", "auto", false] + }, + "importMeta": { + "description": "Enable/disable evaluating import.meta.", + "type": "boolean" + }, + "importMetaContext": { + "description": "Enable/disable evaluating import.meta.webpackContext.", + "type": "boolean" + }, "node": { "$ref": "#/definitions/Node" }, + "overrideStrict": { + "description": "Override the module to strict or non-strict. This may affect the behavior of the module (some behaviors differ between strict and non-strict), so please configure this option carefully.", + "enum": ["strict", "non-strict"] + }, + "reexportExportsPresence": { + "description": "Specifies the behavior of invalid export names in \"export ... from ...\". This might be useful to disable during the migration from \"export ... from ...\" to \"export type ... from ...\" when reexporting types in TypeScript.", + "enum": ["error", "warn", "auto", false] + }, "requireContext": { "description": "Enable/disable parsing of require.context syntax.", "type": "boolean" @@ -1285,7 +1904,7 @@ "type": "boolean" }, "strictExportPresence": { - "description": "Emit errors instead of warnings when imported names don't exist in imported module.", + "description": "Deprecated in favor of \"exportsPresence\". Emit errors instead of warnings when imported names don't exist in imported module.", "type": "boolean" }, "strictThisContextOnImports": { @@ -1374,6 +1993,112 @@ } ] }, + "LazyCompilationDefaultBackendOptions": { + "description": "Options for the default backend.", + "type": "object", + "additionalProperties": false, + "properties": { + "client": { + "description": "A custom client.", + "type": "string" + }, + "listen": { + "description": "Specifies where to listen to from the server.", + "anyOf": [ + { + "description": "A port.", + "type": "number" + }, + { + "description": "Listen options.", + "type": "object", + "additionalProperties": true, + "properties": { + "host": { + "description": "A host.", + "type": "string" + }, + "port": { + "description": "A port.", + "type": "number" + } + }, + "tsType": "import(\"net\").ListenOptions" + }, + { + "description": "A custom listen function.", + "instanceof": "Function", + "tsType": "((server: import(\"net\").Server) => void)" + } + ] + }, + "protocol": { + "description": "Specifies the protocol the client should use to connect to the server.", + "enum": ["http", "https"] + }, + "server": { + "description": "Specifies how to create the server handling the EventSource requests.", + "anyOf": [ + { + "description": "ServerOptions for the http or https createServer call.", + "type": "object", + "additionalProperties": true, + "properties": {}, + "tsType": "(import(\"https\").ServerOptions | import(\"http\").ServerOptions)" + }, + { + "description": "A custom create server function.", + "instanceof": "Function", + "tsType": "(() => import(\"net\").Server)" + } + ] + } + } + }, + "LazyCompilationOptions": { + "description": "Options for compiling entrypoints and import()s only when they are accessed.", + "type": "object", + "additionalProperties": false, + "properties": { + "backend": { + "description": "Specifies the backend that should be used for handling client keep alive.", + "anyOf": [ + { + "description": "A custom backend.", + "instanceof": "Function", + "tsType": "(((compiler: import('../lib/Compiler'), callback: (err?: Error, api?: import(\"../lib/hmr/LazyCompilationPlugin\").BackendApi) => void) => void) | ((compiler: import('../lib/Compiler')) => Promise))" + }, + { + "$ref": "#/definitions/LazyCompilationDefaultBackendOptions" + } + ] + }, + "entries": { + "description": "Enable/disable lazy compilation for entries.", + "type": "boolean" + }, + "imports": { + "description": "Enable/disable lazy compilation for import() modules.", + "type": "boolean" + }, + "test": { + "description": "Specify which entrypoints or import()ed modules should be lazily compiled. This is matched with the imported module and not the entrypoint name.", + "anyOf": [ + { + "instanceof": "RegExp", + "tsType": "RegExp" + }, + { + "type": "string" + }, + { + "instanceof": "Function", + "tsType": "((module: import('../lib/Module')) => boolean)" + } + ] + } + } + }, "Library": { "description": "Make the output files a library, exporting the exports of the entry point.", "anyOf": [ @@ -1485,6 +2210,9 @@ "type": "object", "additionalProperties": false, "properties": { + "amdContainer": { + "$ref": "#/definitions/AmdContainer" + }, "auxiliaryComment": { "$ref": "#/definitions/AuxiliaryComment" }, @@ -1504,7 +2232,7 @@ "required": ["type"] }, "LibraryType": { - "description": "Type of library (types included by default are 'var', 'module', 'assign', 'assign-properties', 'this', 'window', 'self', 'global', 'commonjs', 'commonjs2', 'commonjs-module', 'amd', 'amd-require', 'umd', 'umd2', 'jsonp', 'system', but others might be added by plugins).", + "description": "Type of library (types included by default are 'var', 'module', 'assign', 'assign-properties', 'this', 'window', 'self', 'global', 'commonjs', 'commonjs2', 'commonjs-module', 'commonjs-static', 'amd', 'amd-require', 'umd', 'umd2', 'jsonp', 'system', but others might be added by plugins).", "anyOf": [ { "enum": [ @@ -1519,6 +2247,7 @@ "commonjs", "commonjs2", "commonjs-module", + "commonjs-static", "amd", "amd-require", "umd", @@ -1541,6 +2270,15 @@ "type": "object", "additionalProperties": false, "properties": { + "cacheUnaffected": { + "description": "Additionally cache computation of modules that are unchanged and reference only unchanged modules.", + "type": "boolean" + }, + "maxGenerations": { + "description": "Number of generations unused cache entries stay in memory cache at minimum (1 = may be removed after unused for a single compilation, ..., Infinity: kept forever).", + "type": "number", + "minimum": 1 + }, "type": { "description": "In memory caching.", "enum": ["memory"] @@ -1825,15 +2563,15 @@ "properties": { "__dirname": { "description": "Include a polyfill for the '__dirname' variable.", - "enum": [false, true, "mock", "eval-only"] + "enum": [false, true, "warn-mock", "mock", "node-module", "eval-only"] }, "__filename": { "description": "Include a polyfill for the '__filename' variable.", - "enum": [false, true, "mock", "eval-only"] + "enum": [false, true, "warn-mock", "mock", "node-module", "eval-only"] }, "global": { "description": "Include a polyfill for the 'global' variable.", - "type": "boolean" + "enum": [false, true, "warn"] } } }, @@ -1908,6 +2646,9 @@ { "enum": ["..."] }, + { + "$ref": "#/definitions/Falsy" + }, { "$ref": "#/definitions/WebpackPluginInstance" }, @@ -2061,6 +2802,10 @@ { "enum": ["initial", "async", "all"] }, + { + "instanceof": "RegExp", + "tsType": "RegExp" + }, { "instanceof": "Function", "tsType": "((chunk: import('../lib/Chunk')) => boolean)" @@ -2168,6 +2913,14 @@ } ] }, + "minSizeReduction": { + "description": "Minimum size reduction due to the created chunk.", + "oneOf": [ + { + "$ref": "#/definitions/OptimizationSplitChunksSizes" + } + ] + }, "name": { "description": "Give chunks for this cache group a name (chunks with equal name are merged).", "anyOf": [ @@ -2278,15 +3031,15 @@ "description": "The test property is a cache group name, but using the test option of the cache group could be intended instead.", "anyOf": [ { - "instanceof": "Function", - "tsType": "Function" + "instanceof": "RegExp", + "tsType": "RegExp" }, { "type": "string" }, { - "instanceof": "RegExp", - "tsType": "RegExp" + "instanceof": "Function", + "tsType": "Function" } ] } @@ -2300,6 +3053,10 @@ { "enum": ["initial", "async", "all"] }, + { + "instanceof": "RegExp", + "tsType": "RegExp" + }, { "instanceof": "Function", "tsType": "((chunk: import('../lib/Chunk')) => boolean)" @@ -2313,7 +3070,7 @@ "description": "Size type, like 'javascript', 'webassembly'.", "type": "string" }, - "minLength": 1 + "minItems": 1 }, "enforceSizeThreshold": { "description": "Size threshold at which splitting is enforced and other restrictions (minRemainingSize, maxAsyncRequests, maxInitialRequests) are ignored.", @@ -2333,6 +3090,22 @@ "type": "string", "minLength": 1 }, + "chunks": { + "description": "Select chunks for determining shared modules (defaults to \"async\", \"initial\" and \"all\" requires adding these chunks to the HTML).", + "anyOf": [ + { + "enum": ["initial", "async", "all"] + }, + { + "instanceof": "RegExp", + "tsType": "RegExp" + }, + { + "instanceof": "Function", + "tsType": "((chunk: import('../lib/Chunk')) => boolean)" + } + ] + }, "maxAsyncSize": { "description": "Maximal size hint for the on-demand chunks.", "oneOf": [ @@ -2364,6 +3137,14 @@ "$ref": "#/definitions/OptimizationSplitChunksSizes" } ] + }, + "minSizeReduction": { + "description": "Minimum size reduction due to the created chunk.", + "oneOf": [ + { + "$ref": "#/definitions/OptimizationSplitChunksSizes" + } + ] } } }, @@ -2440,6 +3221,14 @@ } ] }, + "minSizeReduction": { + "description": "Minimum size reduction due to the created chunk.", + "oneOf": [ + { + "$ref": "#/definitions/OptimizationSplitChunksSizes" + } + ] + }, "name": { "description": "Give chunks created a name (chunks with equal name are merged).", "anyOf": [ @@ -2484,9 +3273,23 @@ "type": "object", "additionalProperties": false, "properties": { + "amdContainer": { + "cli": { + "exclude": true + }, + "oneOf": [ + { + "$ref": "#/definitions/AmdContainer" + } + ] + }, "assetModuleFilename": { "$ref": "#/definitions/AssetModuleFilename" }, + "asyncChunks": { + "description": "Enable/disable creating async chunks that are loaded on demand.", + "type": "boolean" + }, "auxiliaryComment": { "cli": { "exclude": true @@ -2524,6 +3327,15 @@ "crossOriginLoading": { "$ref": "#/definitions/CrossOriginLoading" }, + "cssChunkFilename": { + "$ref": "#/definitions/CssChunkFilename" + }, + "cssFilename": { + "$ref": "#/definitions/CssFilename" + }, + "cssHeadDataCompression": { + "$ref": "#/definitions/CssHeadDataCompression" + }, "devtoolFallbackModuleFilenameTemplate": { "$ref": "#/definitions/DevtoolFallbackModuleFilenameTemplate" }, @@ -2572,6 +3384,10 @@ "hotUpdateMainFilename": { "$ref": "#/definitions/HotUpdateMainFilename" }, + "ignoreBrowserWarnings": { + "description": "Ignore warnings in the browser.", + "type": "boolean" + }, "iife": { "$ref": "#/definitions/Iife" }, @@ -2631,6 +3447,22 @@ "strictModuleExceptionHandling": { "$ref": "#/definitions/StrictModuleExceptionHandling" }, + "trustedTypes": { + "description": "Use a Trusted Types policy to create urls for chunks. 'output.uniqueName' is used a default policy name. Passing a string sets a custom policy name.", + "anyOf": [ + { + "enum": [true] + }, + { + "description": "The name of the Trusted Types policy created by webpack to serve bundle chunks.", + "type": "string", + "minLength": 1 + }, + { + "$ref": "#/definitions/TrustedTypes" + } + ] + }, "umdNamedDefine": { "cli": { "exclude": true @@ -2653,6 +3485,9 @@ "workerChunkLoading": { "$ref": "#/definitions/ChunkLoading" }, + "workerPublicPath": { + "$ref": "#/definitions/WorkerPublicPath" + }, "workerWasmLoading": { "$ref": "#/definitions/WasmLoading" } @@ -2670,6 +3505,10 @@ "assetModuleFilename": { "$ref": "#/definitions/AssetModuleFilename" }, + "asyncChunks": { + "description": "Enable/disable creating async chunks that are loaded on demand.", + "type": "boolean" + }, "charset": { "$ref": "#/definitions/Charset" }, @@ -2697,6 +3536,15 @@ "crossOriginLoading": { "$ref": "#/definitions/CrossOriginLoading" }, + "cssChunkFilename": { + "$ref": "#/definitions/CssChunkFilename" + }, + "cssFilename": { + "$ref": "#/definitions/CssFilename" + }, + "cssHeadDataCompression": { + "$ref": "#/definitions/CssHeadDataCompression" + }, "devtoolFallbackModuleFilenameTemplate": { "$ref": "#/definitions/DevtoolFallbackModuleFilenameTemplate" }, @@ -2745,6 +3593,10 @@ "hotUpdateMainFilename": { "$ref": "#/definitions/HotUpdateMainFilename" }, + "ignoreBrowserWarnings": { + "description": "Ignore warnings in the browser.", + "type": "boolean" + }, "iife": { "$ref": "#/definitions/Iife" }, @@ -2784,6 +3636,9 @@ "strictModuleExceptionHandling": { "$ref": "#/definitions/StrictModuleExceptionHandling" }, + "trustedTypes": { + "$ref": "#/definitions/TrustedTypes" + }, "uniqueName": { "$ref": "#/definitions/UniqueName" }, @@ -2796,6 +3651,9 @@ "workerChunkLoading": { "$ref": "#/definitions/ChunkLoading" }, + "workerPublicPath": { + "$ref": "#/definitions/WorkerPublicPath" + }, "workerWasmLoading": { "$ref": "#/definitions/WasmLoading" } @@ -2827,6 +3685,18 @@ "asset/source": { "$ref": "#/definitions/EmptyParserOptions" }, + "css": { + "$ref": "#/definitions/CssParserOptions" + }, + "css/auto": { + "$ref": "#/definitions/CssAutoParserOptions" + }, + "css/global": { + "$ref": "#/definitions/CssGlobalParserOptions" + }, + "css/module": { + "$ref": "#/definitions/CssModuleParserOptions" + }, "javascript": { "$ref": "#/definitions/JavascriptParserOptions" }, @@ -2898,6 +3768,9 @@ "items": { "description": "Plugin of type object or instanceof Function.", "anyOf": [ + { + "$ref": "#/definitions/Falsy" + }, { "$ref": "#/definitions/WebpackPluginInstance" }, @@ -2912,11 +3785,19 @@ "type": "boolean" }, "PublicPath": { - "description": "The `publicPath` specifies the public URL address of the output files when referenced in a browser.", + "description": "The 'publicPath' specifies the public URL address of the output files when referenced in a browser.", "anyOf": [ { "enum": ["auto"] }, + { + "$ref": "#/definitions/RawPublicPath" + } + ] + }, + "RawPublicPath": { + "description": "The 'publicPath' specifies the public URL address of the output files when referenced in a browser.", + "anyOf": [ { "type": "string" }, @@ -3134,13 +4015,35 @@ "type": "string" } }, + "extensionAlias": { + "description": "An object which maps extension to extension aliases.", + "type": "object", + "additionalProperties": { + "description": "Extension alias.", + "anyOf": [ + { + "description": "Multiple extensions.", + "type": "array", + "items": { + "description": "Aliased extension.", + "type": "string", + "minLength": 1 + } + }, + { + "description": "Aliased extension.", + "type": "string", + "minLength": 1 + } + ] + } + }, "extensions": { "description": "Extensions added to the request when trying to find the file.", "type": "array", "items": { "description": "Extension added to the request when trying to find the file.", - "type": "string", - "minLength": 1 + "type": "string" } }, "fallback": { @@ -3218,6 +4121,9 @@ { "enum": ["..."] }, + { + "$ref": "#/definitions/Falsy" + }, { "$ref": "#/definitions/ResolvePluginInstance" } @@ -3286,16 +4192,24 @@ }, "ResolvePluginInstance": { "description": "Plugin instance.", - "type": "object", - "additionalProperties": true, - "properties": { - "apply": { - "description": "The run point of the plugin, required method.", + "anyOf": [ + { + "type": "object", + "additionalProperties": true, + "properties": { + "apply": { + "description": "The run point of the plugin, required method.", + "instanceof": "Function", + "tsType": "(arg0: import('enhanced-resolve').Resolver) => void" + } + }, + "required": ["apply"] + }, + { "instanceof": "Function", - "tsType": "(resolver: import('enhanced-resolve').Resolver) => void" + "tsType": "((this: import('enhanced-resolve').Resolver, arg1: import('enhanced-resolve').Resolver) => void)" } - }, - "required": ["apply"] + ] }, "RuleSetCondition": { "description": "A condition matcher.", @@ -3310,40 +4224,13 @@ { "type": "string" }, - { - "type": "object", - "additionalProperties": false, - "properties": { - "and": { - "description": "Logical AND.", - "oneOf": [ - { - "$ref": "#/definitions/RuleSetConditions" - } - ] - }, - "not": { - "description": "Logical NOT.", - "oneOf": [ - { - "$ref": "#/definitions/RuleSetConditions" - } - ] - }, - "or": { - "description": "Logical OR.", - "oneOf": [ - { - "$ref": "#/definitions/RuleSetConditions" - } - ] - } - } - }, { "instanceof": "Function", "tsType": "((value: string) => boolean)" }, + { + "$ref": "#/definitions/RuleSetLogicalConditions" + }, { "$ref": "#/definitions/RuleSetConditions" } @@ -3363,40 +4250,13 @@ "type": "string", "absolutePath": true }, - { - "type": "object", - "additionalProperties": false, - "properties": { - "and": { - "description": "Logical AND.", - "oneOf": [ - { - "$ref": "#/definitions/RuleSetConditionsAbsolute" - } - ] - }, - "not": { - "description": "Logical NOT.", - "oneOf": [ - { - "$ref": "#/definitions/RuleSetConditionsAbsolute" - } - ] - }, - "or": { - "description": "Logical OR.", - "oneOf": [ - { - "$ref": "#/definitions/RuleSetConditionsAbsolute" - } - ] - } - } - }, { "instanceof": "Function", "tsType": "((value: string) => boolean)" }, + { + "$ref": "#/definitions/RuleSetLogicalConditionsAbsolute" + }, { "$ref": "#/definitions/RuleSetConditionsAbsolute" } @@ -3470,11 +4330,80 @@ } ] }, + "RuleSetLogicalConditions": { + "description": "Logic operators used in a condition matcher.", + "type": "object", + "additionalProperties": false, + "properties": { + "and": { + "description": "Logical AND.", + "oneOf": [ + { + "$ref": "#/definitions/RuleSetConditions" + } + ] + }, + "not": { + "description": "Logical NOT.", + "oneOf": [ + { + "$ref": "#/definitions/RuleSetCondition" + } + ] + }, + "or": { + "description": "Logical OR.", + "oneOf": [ + { + "$ref": "#/definitions/RuleSetConditions" + } + ] + } + } + }, + "RuleSetLogicalConditionsAbsolute": { + "description": "Logic operators used in a condition matcher.", + "type": "object", + "additionalProperties": false, + "properties": { + "and": { + "description": "Logical AND.", + "oneOf": [ + { + "$ref": "#/definitions/RuleSetConditionsAbsolute" + } + ] + }, + "not": { + "description": "Logical NOT.", + "oneOf": [ + { + "$ref": "#/definitions/RuleSetConditionAbsolute" + } + ] + }, + "or": { + "description": "Logical OR.", + "oneOf": [ + { + "$ref": "#/definitions/RuleSetConditionsAbsolute" + } + ] + } + } + }, "RuleSetRule": { "description": "A rule description with conditions and effects for modules.", "type": "object", "additionalProperties": false, "properties": { + "assert": { + "description": "Match on import assertions of the dependency.", + "type": "object", + "additionalProperties": { + "$ref": "#/definitions/RuleSetConditionOrConditions" + } + }, "compiler": { "description": "Match the child compiler name.", "oneOf": [ @@ -3563,7 +4492,10 @@ "type": "array", "items": { "description": "A rule.", - "oneOf": [ + "anyOf": [ + { + "$ref": "#/definitions/Falsy" + }, { "$ref": "#/definitions/RuleSetRule" } @@ -3632,13 +4564,24 @@ "type": "array", "items": { "description": "A rule.", - "oneOf": [ + "anyOf": [ + { + "$ref": "#/definitions/Falsy" + }, { "$ref": "#/definitions/RuleSetRule" } ] } }, + "scheme": { + "description": "Match module scheme.", + "oneOf": [ + { + "$ref": "#/definitions/RuleSetConditionOrConditions" + } + ] + }, "sideEffects": { "description": "Flags a module as with or without side effects.", "type": "boolean" @@ -3662,6 +4605,13 @@ "$ref": "#/definitions/RuleSetUse" } ] + }, + "with": { + "description": "Match on import attributes of the dependency.", + "type": "object", + "additionalProperties": { + "$ref": "#/definitions/RuleSetConditionOrConditions" + } } } }, @@ -3677,6 +4627,9 @@ }, "enum": ["..."] }, + { + "$ref": "#/definitions/Falsy" + }, { "$ref": "#/definitions/RuleSetRule" } @@ -3690,7 +4643,10 @@ "type": "array", "items": { "description": "An use item.", - "oneOf": [ + "anyOf": [ + { + "$ref": "#/definitions/Falsy" + }, { "$ref": "#/definitions/RuleSetUseItem" } @@ -3699,7 +4655,7 @@ }, { "instanceof": "Function", - "tsType": "((data: { resource: string, realResource: string, resourceQuery: string, issuer: string, compiler: string }) => RuleSetUseItem[])" + "tsType": "((data: { resource: string, realResource: string, resourceQuery: string, issuer: string, compiler: string }) => (Falsy | RuleSetUseItem)[])" }, { "$ref": "#/definitions/RuleSetUseItem" @@ -3737,7 +4693,7 @@ }, { "instanceof": "Function", - "tsType": "((data: object) => RuleSetUseItem|RuleSetUseItem[])" + "tsType": "((data: object) => RuleSetUseItem | (Falsy | RuleSetUseItem)[])" }, { "$ref": "#/definitions/RuleSetLoader" @@ -3772,20 +4728,40 @@ "description": "List of paths that are managed by a package manager and contain a version or hash in its path so all files are immutable.", "type": "array", "items": { - "description": "A path to a immutable directory (usually a package manager cache directory).", - "type": "string", - "absolutePath": true, - "minLength": 1 + "description": "List of paths that are managed by a package manager and contain a version or hash in its path so all files are immutable.", + "anyOf": [ + { + "description": "A RegExp matching an immutable directory (usually a package manager cache directory, including the tailing slash)", + "instanceof": "RegExp", + "tsType": "RegExp" + }, + { + "description": "A path to an immutable directory (usually a package manager cache directory).", + "type": "string", + "absolutePath": true, + "minLength": 1 + } + ] } }, "managedPaths": { "description": "List of paths that are managed by a package manager and can be trusted to not be modified otherwise.", "type": "array", "items": { - "description": "A path to a managed directory (usually a node_modules directory).", - "type": "string", - "absolutePath": true, - "minLength": 1 + "description": "List of paths that are managed by a package manager and can be trusted to not be modified otherwise.", + "anyOf": [ + { + "description": "A RegExp matching a managed directory (usually a node_modules directory, including the tailing slash)", + "instanceof": "RegExp", + "tsType": "RegExp" + }, + { + "description": "A path to a managed directory (usually a node_modules directory).", + "type": "string", + "absolutePath": true, + "minLength": 1 + } + ] } }, "module": { @@ -3832,6 +4808,26 @@ "type": "boolean" } } + }, + "unmanagedPaths": { + "description": "List of paths that are not managed by a package manager and the contents are subject to change.", + "type": "array", + "items": { + "description": "List of paths that are not managed by a package manager and the contents are subject to change.", + "anyOf": [ + { + "description": "A RegExp matching an unmanaged directory.", + "instanceof": "RegExp", + "tsType": "RegExp" + }, + { + "description": "A path to an unmanaged directory.", + "type": "string", + "absolutePath": true, + "minLength": 1 + } + ] + } } } }, @@ -4015,6 +5011,10 @@ "description": "Add errors count.", "type": "boolean" }, + "errorsSpace": { + "description": "Space to display errors (value is in number of lines).", + "type": "number" + }, "exclude": { "description": "Please use excludeModules instead.", "cli": { @@ -4088,6 +5088,14 @@ "description": "Group modules by their path.", "type": "boolean" }, + "groupModulesByType": { + "description": "Group modules by their type.", + "type": "boolean" + }, + "groupReasonsByOrigin": { + "description": "Group reasons by their origin module.", + "type": "boolean" + }, "hash": { "description": "Add the hash of the compilation.", "type": "boolean" @@ -4192,6 +5200,10 @@ "description": "Add information about the reasons why modules are included.", "type": "boolean" }, + "reasonsSpace": { + "description": "Space to display reasons (groups will be collapsed to fit this space).", + "type": "number" + }, "relatedAssets": { "description": "Add information about assets that are related to other assets (like SourceMaps for assets).", "type": "boolean" @@ -4235,6 +5247,10 @@ "$ref": "#/definitions/WarningFilterTypes" } ] + }, + "warningsSpace": { + "description": "Space to display warnings (value is in number of lines).", + "type": "number" } } }, @@ -4290,6 +5306,22 @@ } ] }, + "TrustedTypes": { + "description": "Use a Trusted Types policy to create urls for chunks.", + "type": "object", + "additionalProperties": false, + "properties": { + "onPolicyCreationFailure": { + "description": "If the call to `trustedTypes.createPolicy(...)` fails -- e.g., due to the policy name missing from the CSP `trusted-types` list, or it being a duplicate name, etc. -- controls whether to continue with loading in the hope that `require-trusted-types-for 'script'` isn't enforced yet, versus fail immediately. Default behavior is 'stop'.", + "enum": ["continue", "stop"] + }, + "policyName": { + "description": "The name of the Trusted Types policy created by webpack to serve bundle chunks.", + "type": "string", + "minLength": 1 + } + } + }, "UmdNamedDefine": { "description": "If `output.libraryTarget` is set to umd and `output.library` is set, setting this to true will name the AMD module.", "type": "boolean" @@ -4459,7 +5491,7 @@ "$ref": "#/definitions/EntryNormalized" }, "experiments": { - "$ref": "#/definitions/Experiments" + "$ref": "#/definitions/ExperimentsNormalized" }, "externals": { "$ref": "#/definitions/Externals" @@ -4573,8 +5605,13 @@ } }, "required": ["apply"] + }, + "WorkerPublicPath": { + "description": "Worker public path. Much like the public path, this sets the location where the worker script file is intended to be found. If not set, webpack will use the publicPath. Don't set this option unless your worker scripts are located at a different path from your other script files.", + "type": "string" } }, + "title": "WebpackOptions", "description": "Options object as provided by the user.", "type": "object", "additionalProperties": false, @@ -4606,6 +5643,9 @@ "experiments": { "$ref": "#/definitions/Experiments" }, + "extends": { + "$ref": "#/definitions/Extends" + }, "externals": { "$ref": "#/definitions/Externals" }, diff --git a/schemas/plugins/BannerPlugin.check.d.ts b/schemas/plugins/BannerPlugin.check.d.ts new file mode 100644 index 00000000000..8e19c85abed --- /dev/null +++ b/schemas/plugins/BannerPlugin.check.d.ts @@ -0,0 +1,7 @@ +/* + * This file was automatically generated. + * DO NOT MODIFY BY HAND. + * Run `yarn special-lint-fix` to update + */ +declare const check: (options: import("../../declarations/plugins/BannerPlugin").BannerPluginArgument) => boolean; +export = check; diff --git a/schemas/plugins/BannerPlugin.check.js b/schemas/plugins/BannerPlugin.check.js new file mode 100644 index 00000000000..69e04d21c01 --- /dev/null +++ b/schemas/plugins/BannerPlugin.check.js @@ -0,0 +1,6 @@ +/* + * This file was automatically generated. + * DO NOT MODIFY BY HAND. + * Run `yarn special-lint-fix` to update + */ +"use strict";function n(t,{instancePath:e="",parentData:s,parentDataProperty:l,rootData:a=t}={}){let r=null,o=0;const u=o;let i=!1;const p=o;if(o===p)if(Array.isArray(t)){const n=t.length;for(let e=0;e string" + "tsType": "(data: { hash?: string, chunk: import('../../lib/Chunk'), filename: string }) => string" }, "Rule": { "description": "Filtering rule as regex or string.", @@ -73,6 +73,10 @@ } ] }, + "footer": { + "description": "If true, banner will be placed at the end of the output.", + "type": "boolean" + }, "include": { "description": "Include all modules matching any of these conditions.", "oneOf": [ @@ -85,6 +89,10 @@ "description": "If true, banner will not be wrapped in a comment.", "type": "boolean" }, + "stage": { + "description": "Specifies the banner.", + "type": "number" + }, "test": { "description": "Include all modules that pass test assertion.", "oneOf": [ diff --git a/schemas/plugins/DllPlugin.check.d.ts b/schemas/plugins/DllPlugin.check.d.ts new file mode 100644 index 00000000000..2e6198d3e8d --- /dev/null +++ b/schemas/plugins/DllPlugin.check.d.ts @@ -0,0 +1,7 @@ +/* + * This file was automatically generated. + * DO NOT MODIFY BY HAND. + * Run `yarn special-lint-fix` to update + */ +declare const check: (options: import("../../declarations/plugins/DllPlugin").DllPluginOptions) => boolean; +export = check; diff --git a/schemas/plugins/DllPlugin.check.js b/schemas/plugins/DllPlugin.check.js new file mode 100644 index 00000000000..c1a46039888 --- /dev/null +++ b/schemas/plugins/DllPlugin.check.js @@ -0,0 +1,6 @@ +/* + * This file was automatically generated. + * DO NOT MODIFY BY HAND. + * Run `yarn special-lint-fix` to update + */ +"use strict";function r(e,{instancePath:t="",parentData:o,parentDataProperty:n,rootData:a=e}={}){if(!e||"object"!=typeof e||Array.isArray(e))return r.errors=[{params:{type:"object"}}],!1;{let t;if(void 0===e.path&&(t="path"))return r.errors=[{params:{missingProperty:t}}],!1;{const t=0;for(const t in e)if("context"!==t&&"entryOnly"!==t&&"format"!==t&&"name"!==t&&"path"!==t&&"type"!==t)return r.errors=[{params:{additionalProperty:t}}],!1;if(0===t){if(void 0!==e.context){let t=e.context;const o=0;if(0===o){if("string"!=typeof t)return r.errors=[{params:{type:"string"}}],!1;if(t.length<1)return r.errors=[{params:{}}],!1}var s=0===o}else s=!0;if(s){if(void 0!==e.entryOnly){const t=0;if("boolean"!=typeof e.entryOnly)return r.errors=[{params:{type:"boolean"}}],!1;s=0===t}else s=!0;if(s){if(void 0!==e.format){const t=0;if("boolean"!=typeof e.format)return r.errors=[{params:{type:"boolean"}}],!1;s=0===t}else s=!0;if(s){if(void 0!==e.name){let t=e.name;const o=0;if(0===o){if("string"!=typeof t)return r.errors=[{params:{type:"string"}}],!1;if(t.length<1)return r.errors=[{params:{}}],!1}s=0===o}else s=!0;if(s){if(void 0!==e.path){let t=e.path;const o=0;if(0===o){if("string"!=typeof t)return r.errors=[{params:{type:"string"}}],!1;if(t.length<1)return r.errors=[{params:{}}],!1}s=0===o}else s=!0;if(s)if(void 0!==e.type){let t=e.type;const o=0;if(0===o){if("string"!=typeof t)return r.errors=[{params:{type:"string"}}],!1;if(t.length<1)return r.errors=[{params:{}}],!1}s=0===o}else s=!0}}}}}}}return r.errors=null,!0}module.exports=r,module.exports.default=r; \ No newline at end of file diff --git a/schemas/plugins/DllReferencePlugin.check.d.ts b/schemas/plugins/DllReferencePlugin.check.d.ts new file mode 100644 index 00000000000..43d31f1aa42 --- /dev/null +++ b/schemas/plugins/DllReferencePlugin.check.d.ts @@ -0,0 +1,7 @@ +/* + * This file was automatically generated. + * DO NOT MODIFY BY HAND. + * Run `yarn special-lint-fix` to update + */ +declare const check: (options: import("../../declarations/plugins/DllReferencePlugin").DllReferencePluginOptions) => boolean; +export = check; diff --git a/schemas/plugins/DllReferencePlugin.check.js b/schemas/plugins/DllReferencePlugin.check.js new file mode 100644 index 00000000000..6e8734cdc81 --- /dev/null +++ b/schemas/plugins/DllReferencePlugin.check.js @@ -0,0 +1,6 @@ +/* + * This file was automatically generated. + * DO NOT MODIFY BY HAND. + * Run `yarn special-lint-fix` to update + */ +const s=/^(?:[A-Za-z]:[\\/]|\\\\|\/)/;function t(s,{instancePath:e="",parentData:n,parentDataProperty:l,rootData:o=s}={}){let r=null,i=0;if(0===i){if(!s||"object"!=typeof s||Array.isArray(s))return t.errors=[{params:{type:"object"}}],!1;{let e;if(void 0===s.content&&(e="content"))return t.errors=[{params:{missingProperty:e}}],!1;{const e=i;for(const e in s)if("content"!==e&&"name"!==e&&"type"!==e)return t.errors=[{params:{additionalProperty:e}}],!1;if(e===i){if(void 0!==s.content){let e=s.content;const n=i,l=i;let o=!1,f=null;const m=i;if(i==i)if(e&&"object"==typeof e&&!Array.isArray(e))if(Object.keys(e).length<1){const s={params:{limit:1}};null===r?r=[s]:r.push(s),i++}else for(const s in e){let t=e[s];const n=i;if(i===n)if(t&&"object"==typeof t&&!Array.isArray(t)){let s;if(void 0===t.id&&(s="id")){const t={params:{missingProperty:s}};null===r?r=[t]:r.push(t),i++}else{const s=i;for(const s in t)if("buildMeta"!==s&&"exports"!==s&&"id"!==s){const t={params:{additionalProperty:s}};null===r?r=[t]:r.push(t),i++;break}if(s===i){if(void 0!==t.buildMeta){let s=t.buildMeta;const e=i;if(!s||"object"!=typeof s||Array.isArray(s)){const s={params:{type:"object"}};null===r?r=[s]:r.push(s),i++}var a=e===i}else a=!0;if(a){if(void 0!==t.exports){let s=t.exports;const e=i,n=i;let l=!1;const o=i;if(i===o)if(Array.isArray(s)){const t=s.length;for(let e=0;e boolean; +export = check; diff --git a/schemas/plugins/HashedModuleIdsPlugin.check.js b/schemas/plugins/HashedModuleIdsPlugin.check.js new file mode 100644 index 00000000000..68af3ad27d9 --- /dev/null +++ b/schemas/plugins/HashedModuleIdsPlugin.check.js @@ -0,0 +1,6 @@ +/* + * This file was automatically generated. + * DO NOT MODIFY BY HAND. + * Run `yarn special-lint-fix` to update + */ +const t=/^(?:[A-Za-z]:[\\/]|\\\\|\/)/;function e(r,{instancePath:s="",parentData:n,parentDataProperty:a,rootData:i=r}={}){let o=null,l=0;if(0===l){if(!r||"object"!=typeof r||Array.isArray(r))return e.errors=[{params:{type:"object"}}],!1;{const s=l;for(const t in r)if("context"!==t&&"hashDigest"!==t&&"hashDigestLength"!==t&&"hashFunction"!==t)return e.errors=[{params:{additionalProperty:t}}],!1;if(s===l){if(void 0!==r.context){let s=r.context;const n=l;if(l===n){if("string"!=typeof s)return e.errors=[{params:{type:"string"}}],!1;if(s.includes("!")||!0!==t.test(s))return e.errors=[{params:{}}],!1}var u=n===l}else u=!0;if(u){if(void 0!==r.hashDigest){let t=r.hashDigest;const s=l;if("hex"!==t&&"latin1"!==t&&"base64"!==t)return e.errors=[{params:{}}],!1;u=s===l}else u=!0;if(u){if(void 0!==r.hashDigestLength){let t=r.hashDigestLength;const s=l;if(l===s){if("number"!=typeof t)return e.errors=[{params:{type:"number"}}],!1;if(t<1||isNaN(t))return e.errors=[{params:{comparison:">=",limit:1}}],!1}u=s===l}else u=!0;if(u)if(void 0!==r.hashFunction){let t=r.hashFunction;const s=l,n=l;let a=!1,i=null;const p=l,h=l;let c=!1;const m=l;if(l===m)if("string"==typeof t){if(t.length<1){const t={params:{}};null===o?o=[t]:o.push(t),l++}}else{const t={params:{type:"string"}};null===o?o=[t]:o.push(t),l++}var f=m===l;if(c=c||f,!c){const e=l;if(!(t instanceof Function)){const t={params:{}};null===o?o=[t]:o.push(t),l++}f=e===l,c=c||f}if(c)l=h,null!==o&&(h?o.length=h:o=null);else{const t={params:{}};null===o?o=[t]:o.push(t),l++}if(p===l&&(a=!0,i=0),!a){const t={params:{passingSchemas:i}};return null===o?o=[t]:o.push(t),l++,e.errors=o,!1}l=n,null!==o&&(n?o.length=n:o=null),u=s===l}else u=!0}}}}}return e.errors=o,0===l}module.exports=e,module.exports.default=e; \ No newline at end of file diff --git a/schemas/plugins/HashedModuleIdsPlugin.json b/schemas/plugins/HashedModuleIdsPlugin.json index b365a851b91..1b4efc40b5e 100644 --- a/schemas/plugins/HashedModuleIdsPlugin.json +++ b/schemas/plugins/HashedModuleIdsPlugin.json @@ -1,4 +1,19 @@ { + "definitions": { + "HashFunction": { + "description": "Algorithm used for generation the hash (see node.js crypto package).", + "anyOf": [ + { + "type": "string", + "minLength": 1 + }, + { + "instanceof": "Function", + "tsType": "typeof import('../../lib/util/Hash')" + } + ] + } + }, "title": "HashedModuleIdsPluginOptions", "type": "object", "additionalProperties": false, @@ -19,8 +34,11 @@ }, "hashFunction": { "description": "The hashing algorithm to use, defaults to 'md4'. All functions from Node.JS' crypto.createHash are supported.", - "type": "string", - "minLength": 1 + "oneOf": [ + { + "$ref": "#/definitions/HashFunction" + } + ] } } } diff --git a/schemas/plugins/IgnorePlugin.check.d.ts b/schemas/plugins/IgnorePlugin.check.d.ts new file mode 100644 index 00000000000..a036f6d2b56 --- /dev/null +++ b/schemas/plugins/IgnorePlugin.check.d.ts @@ -0,0 +1,7 @@ +/* + * This file was automatically generated. + * DO NOT MODIFY BY HAND. + * Run `yarn special-lint-fix` to update + */ +declare const check: (options: import("../../declarations/plugins/IgnorePlugin").IgnorePluginOptions) => boolean; +export = check; diff --git a/schemas/plugins/IgnorePlugin.check.js b/schemas/plugins/IgnorePlugin.check.js new file mode 100644 index 00000000000..cde232b586d --- /dev/null +++ b/schemas/plugins/IgnorePlugin.check.js @@ -0,0 +1,6 @@ +/* + * This file was automatically generated. + * DO NOT MODIFY BY HAND. + * Run `yarn special-lint-fix` to update + */ +"use strict";function e(s,{instancePath:o="",parentData:r,parentDataProperty:t,rootData:n=s}={}){let c=null,a=0;const p=a;let l=!1;const i=a;if(a===i)if(s&&"object"==typeof s&&!Array.isArray(s)){let e;if(void 0===s.resourceRegExp&&(e="resourceRegExp")){const s={params:{missingProperty:e}};null===c?c=[s]:c.push(s),a++}else{const e=a;for(const e in s)if("contextRegExp"!==e&&"resourceRegExp"!==e){const s={params:{additionalProperty:e}};null===c?c=[s]:c.push(s),a++;break}if(e===a){if(void 0!==s.contextRegExp){const e=a;if(!(s.contextRegExp instanceof RegExp)){const e={params:{}};null===c?c=[e]:c.push(e),a++}var u=e===a}else u=!0;if(u)if(void 0!==s.resourceRegExp){const e=a;if(!(s.resourceRegExp instanceof RegExp)){const e={params:{}};null===c?c=[e]:c.push(e),a++}u=e===a}else u=!0}}}else{const e={params:{type:"object"}};null===c?c=[e]:c.push(e),a++}var f=i===a;if(l=l||f,!l){const e=a;if(a===e)if(s&&"object"==typeof s&&!Array.isArray(s)){let e;if(void 0===s.checkResource&&(e="checkResource")){const s={params:{missingProperty:e}};null===c?c=[s]:c.push(s),a++}else{const e=a;for(const e in s)if("checkResource"!==e){const s={params:{additionalProperty:e}};null===c?c=[s]:c.push(s),a++;break}if(e===a&&void 0!==s.checkResource&&!(s.checkResource instanceof Function)){const e={params:{}};null===c?c=[e]:c.push(e),a++}}}else{const e={params:{type:"object"}};null===c?c=[e]:c.push(e),a++}f=e===a,l=l||f}if(!l){const s={params:{}};return null===c?c=[s]:c.push(s),a++,e.errors=c,!1}return a=p,null!==c&&(p?c.length=p:c=null),e.errors=c,0===a}module.exports=e,module.exports.default=e; \ No newline at end of file diff --git a/schemas/plugins/IgnorePlugin.json b/schemas/plugins/IgnorePlugin.json index a78df10f42b..58c1d2c50c5 100644 --- a/schemas/plugins/IgnorePlugin.json +++ b/schemas/plugins/IgnorePlugin.json @@ -15,7 +15,8 @@ "instanceof": "RegExp", "tsType": "RegExp" } - } + }, + "required": ["resourceRegExp"] }, { "type": "object", @@ -26,7 +27,8 @@ "instanceof": "Function", "tsType": "((resource: string, context: string) => boolean)" } - } + }, + "required": ["checkResource"] } ] } diff --git a/schemas/plugins/JsonModulesPluginParser.check.d.ts b/schemas/plugins/JsonModulesPluginParser.check.d.ts new file mode 100644 index 00000000000..938383fb532 --- /dev/null +++ b/schemas/plugins/JsonModulesPluginParser.check.d.ts @@ -0,0 +1,7 @@ +/* + * This file was automatically generated. + * DO NOT MODIFY BY HAND. + * Run `yarn special-lint-fix` to update + */ +declare const check: (options: import("../../declarations/plugins/JsonModulesPluginParser").JsonModulesPluginParserOptions) => boolean; +export = check; diff --git a/schemas/plugins/JsonModulesPluginParser.check.js b/schemas/plugins/JsonModulesPluginParser.check.js new file mode 100644 index 00000000000..dab47727423 --- /dev/null +++ b/schemas/plugins/JsonModulesPluginParser.check.js @@ -0,0 +1,6 @@ +/* + * This file was automatically generated. + * DO NOT MODIFY BY HAND. + * Run `yarn special-lint-fix` to update + */ +"use strict";function r(t,{instancePath:e="",parentData:a,parentDataProperty:o,rootData:n=t}={}){if(!t||"object"!=typeof t||Array.isArray(t))return r.errors=[{params:{type:"object"}}],!1;{const e=0;for(const e in t)if("parse"!==e)return r.errors=[{params:{additionalProperty:e}}],!1;if(0===e&&void 0!==t.parse&&!(t.parse instanceof Function))return r.errors=[{params:{}}],!1}return r.errors=null,!0}module.exports=r,module.exports.default=r; \ No newline at end of file diff --git a/schemas/plugins/LoaderOptionsPlugin.check.d.ts b/schemas/plugins/LoaderOptionsPlugin.check.d.ts new file mode 100644 index 00000000000..9bdda55c9a9 --- /dev/null +++ b/schemas/plugins/LoaderOptionsPlugin.check.d.ts @@ -0,0 +1,7 @@ +/* + * This file was automatically generated. + * DO NOT MODIFY BY HAND. + * Run `yarn special-lint-fix` to update + */ +declare const check: (options: import("../../declarations/plugins/LoaderOptionsPlugin").LoaderOptionsPluginOptions) => boolean; +export = check; diff --git a/schemas/plugins/LoaderOptionsPlugin.check.js b/schemas/plugins/LoaderOptionsPlugin.check.js new file mode 100644 index 00000000000..03e210d6ba0 --- /dev/null +++ b/schemas/plugins/LoaderOptionsPlugin.check.js @@ -0,0 +1,6 @@ +/* + * This file was automatically generated. + * DO NOT MODIFY BY HAND. + * Run `yarn special-lint-fix` to update + */ +const r=/^(?:[A-Za-z]:[\\/]|\\\\|\/)/;function e(t,{instancePath:o="",parentData:a,parentDataProperty:i,rootData:n=t}={}){if(!t||"object"!=typeof t||Array.isArray(t))return e.errors=[{params:{type:"object"}}],!1;if(void 0!==t.debug){const r=0;if("boolean"!=typeof t.debug)return e.errors=[{params:{type:"boolean"}}],!1;var s=0===r}else s=!0;if(s){if(void 0!==t.minimize){const r=0;if("boolean"!=typeof t.minimize)return e.errors=[{params:{type:"boolean"}}],!1;s=0===r}else s=!0;if(s)if(void 0!==t.options){let o=t.options;const a=0;if(0===a){if(!o||"object"!=typeof o||Array.isArray(o))return e.errors=[{params:{type:"object"}}],!1;if(void 0!==o.context){let t=o.context;if("string"!=typeof t)return e.errors=[{params:{type:"string"}}],!1;if(t.includes("!")||!0!==r.test(t))return e.errors=[{params:{}}],!1}}s=0===a}else s=!0}return e.errors=null,!0}module.exports=e,module.exports.default=e; \ No newline at end of file diff --git a/schemas/plugins/ProgressPlugin.check.d.ts b/schemas/plugins/ProgressPlugin.check.d.ts new file mode 100644 index 00000000000..95c0e97ceb8 --- /dev/null +++ b/schemas/plugins/ProgressPlugin.check.d.ts @@ -0,0 +1,7 @@ +/* + * This file was automatically generated. + * DO NOT MODIFY BY HAND. + * Run `yarn special-lint-fix` to update + */ +declare const check: (options: import("../../declarations/plugins/ProgressPlugin").ProgressPluginArgument) => boolean; +export = check; diff --git a/schemas/plugins/ProgressPlugin.check.js b/schemas/plugins/ProgressPlugin.check.js new file mode 100644 index 00000000000..0c3fb4ffea3 --- /dev/null +++ b/schemas/plugins/ProgressPlugin.check.js @@ -0,0 +1,6 @@ +/* + * This file was automatically generated. + * DO NOT MODIFY BY HAND. + * Run `yarn special-lint-fix` to update + */ +"use strict";module.exports=t,module.exports.default=t;const e={type:"object",additionalProperties:!1,properties:{activeModules:{type:"boolean"},dependencies:{type:"boolean"},dependenciesCount:{type:"number"},entries:{type:"boolean"},handler:{oneOf:[{$ref:"#/definitions/HandlerFunction"}]},modules:{type:"boolean"},modulesCount:{type:"number"},percentBy:{enum:["entries","modules","dependencies",null]},profile:{enum:[!0,!1,null]}}},r=Object.prototype.hasOwnProperty;function n(t,{instancePath:o="",parentData:s,parentDataProperty:a,rootData:l=t}={}){let i=null,p=0;if(0===p){if(!t||"object"!=typeof t||Array.isArray(t))return n.errors=[{params:{type:"object"}}],!1;{const o=p;for(const o in t)if(!r.call(e.properties,o))return n.errors=[{params:{additionalProperty:o}}],!1;if(o===p){if(void 0!==t.activeModules){const e=p;if("boolean"!=typeof t.activeModules)return n.errors=[{params:{type:"boolean"}}],!1;var u=e===p}else u=!0;if(u){if(void 0!==t.dependencies){const e=p;if("boolean"!=typeof t.dependencies)return n.errors=[{params:{type:"boolean"}}],!1;u=e===p}else u=!0;if(u){if(void 0!==t.dependenciesCount){const e=p;if("number"!=typeof t.dependenciesCount)return n.errors=[{params:{type:"number"}}],!1;u=e===p}else u=!0;if(u){if(void 0!==t.entries){const e=p;if("boolean"!=typeof t.entries)return n.errors=[{params:{type:"boolean"}}],!1;u=e===p}else u=!0;if(u){if(void 0!==t.handler){const e=p,r=p;let o=!1,s=null;const a=p;if(!(t.handler instanceof Function)){const e={params:{}};null===i?i=[e]:i.push(e),p++}if(a===p&&(o=!0,s=0),!o){const e={params:{passingSchemas:s}};return null===i?i=[e]:i.push(e),p++,n.errors=i,!1}p=r,null!==i&&(r?i.length=r:i=null),u=e===p}else u=!0;if(u){if(void 0!==t.modules){const e=p;if("boolean"!=typeof t.modules)return n.errors=[{params:{type:"boolean"}}],!1;u=e===p}else u=!0;if(u){if(void 0!==t.modulesCount){const e=p;if("number"!=typeof t.modulesCount)return n.errors=[{params:{type:"number"}}],!1;u=e===p}else u=!0;if(u){if(void 0!==t.percentBy){let e=t.percentBy;const r=p;if("entries"!==e&&"modules"!==e&&"dependencies"!==e&&null!==e)return n.errors=[{params:{}}],!1;u=r===p}else u=!0;if(u)if(void 0!==t.profile){let e=t.profile;const r=p;if(!0!==e&&!1!==e&&null!==e)return n.errors=[{params:{}}],!1;u=r===p}else u=!0}}}}}}}}}}return n.errors=i,0===p}function t(e,{instancePath:r="",parentData:o,parentDataProperty:s,rootData:a=e}={}){let l=null,i=0;const p=i;let u=!1;const c=i;n(e,{instancePath:r,parentData:o,parentDataProperty:s,rootData:a})||(l=null===l?n.errors:l.concat(n.errors),i=l.length);var f=c===i;if(u=u||f,!u){const r=i;if(!(e instanceof Function)){const e={params:{}};null===l?l=[e]:l.push(e),i++}f=r===i,u=u||f}if(!u){const e={params:{}};return null===l?l=[e]:l.push(e),i++,t.errors=l,!1}return i=p,null!==l&&(p?l.length=p:l=null),t.errors=l,0===i} \ No newline at end of file diff --git a/schemas/plugins/SourceMapDevToolPlugin.check.d.ts b/schemas/plugins/SourceMapDevToolPlugin.check.d.ts new file mode 100644 index 00000000000..fecf29e2d49 --- /dev/null +++ b/schemas/plugins/SourceMapDevToolPlugin.check.d.ts @@ -0,0 +1,7 @@ +/* + * This file was automatically generated. + * DO NOT MODIFY BY HAND. + * Run `yarn special-lint-fix` to update + */ +declare const check: (options: import("../../declarations/plugins/SourceMapDevToolPlugin").SourceMapDevToolPluginOptions) => boolean; +export = check; diff --git a/schemas/plugins/SourceMapDevToolPlugin.check.js b/schemas/plugins/SourceMapDevToolPlugin.check.js new file mode 100644 index 00000000000..c821ebe496a --- /dev/null +++ b/schemas/plugins/SourceMapDevToolPlugin.check.js @@ -0,0 +1,6 @@ +/* + * This file was automatically generated. + * DO NOT MODIFY BY HAND. + * Run `yarn special-lint-fix` to update + */ +const e=/^(?:[A-Za-z]:[\\/]|\\\\|\/)/;module.exports=l,module.exports.default=l;const n={definitions:{rule:{anyOf:[{instanceof:"RegExp"},{type:"string",minLength:1}]},rules:{anyOf:[{type:"array",items:{oneOf:[{$ref:"#/definitions/rule"}]}},{$ref:"#/definitions/rule"}]}},type:"object",additionalProperties:!1,properties:{append:{anyOf:[{enum:[!1,null]},{type:"string",minLength:1},{instanceof:"Function"}]},columns:{type:"boolean"},exclude:{oneOf:[{$ref:"#/definitions/rules"}]},fallbackModuleFilenameTemplate:{anyOf:[{type:"string",minLength:1},{instanceof:"Function"}]},fileContext:{type:"string"},filename:{anyOf:[{enum:[!1,null]},{type:"string",absolutePath:!1,minLength:1}]},include:{oneOf:[{$ref:"#/definitions/rules"}]},module:{type:"boolean"},moduleFilenameTemplate:{anyOf:[{type:"string",minLength:1},{instanceof:"Function"}]},namespace:{type:"string"},noSources:{type:"boolean"},publicPath:{type:"string"},sourceRoot:{type:"string"},test:{$ref:"#/definitions/rules"}}},t=Object.prototype.hasOwnProperty;function s(e,{instancePath:n="",parentData:t,parentDataProperty:l,rootData:r=e}={}){let o=null,a=0;const i=a;let u=!1;const p=a;if(a===p)if(Array.isArray(e)){const n=e.length;for(let t=0;t string)" } ] }, diff --git a/schemas/plugins/WatchIgnorePlugin.check.d.ts b/schemas/plugins/WatchIgnorePlugin.check.d.ts new file mode 100644 index 00000000000..da36bafde54 --- /dev/null +++ b/schemas/plugins/WatchIgnorePlugin.check.d.ts @@ -0,0 +1,7 @@ +/* + * This file was automatically generated. + * DO NOT MODIFY BY HAND. + * Run `yarn special-lint-fix` to update + */ +declare const check: (options: import("../../declarations/plugins/WatchIgnorePlugin").WatchIgnorePluginOptions) => boolean; +export = check; diff --git a/schemas/plugins/WatchIgnorePlugin.check.js b/schemas/plugins/WatchIgnorePlugin.check.js new file mode 100644 index 00000000000..0dd766d2b25 --- /dev/null +++ b/schemas/plugins/WatchIgnorePlugin.check.js @@ -0,0 +1,6 @@ +/* + * This file was automatically generated. + * DO NOT MODIFY BY HAND. + * Run `yarn special-lint-fix` to update + */ +"use strict";function r(t,{instancePath:e="",parentData:s,parentDataProperty:a,rootData:n=t}={}){let o=null,i=0;if(0===i){if(!t||"object"!=typeof t||Array.isArray(t))return r.errors=[{params:{type:"object"}}],!1;{let e;if(void 0===t.paths&&(e="paths"))return r.errors=[{params:{missingProperty:e}}],!1;{const e=i;for(const e in t)if("paths"!==e)return r.errors=[{params:{additionalProperty:e}}],!1;if(e===i&&void 0!==t.paths){let e=t.paths;if(i==i){if(!Array.isArray(e))return r.errors=[{params:{type:"array"}}],!1;if(e.length<1)return r.errors=[{params:{limit:1}}],!1;{const t=e.length;for(let s=0;s boolean; +export = check; diff --git a/schemas/plugins/asset/AssetGeneratorOptions.check.js b/schemas/plugins/asset/AssetGeneratorOptions.check.js new file mode 100644 index 00000000000..2cf06373e05 --- /dev/null +++ b/schemas/plugins/asset/AssetGeneratorOptions.check.js @@ -0,0 +1,6 @@ +/* + * This file was automatically generated. + * DO NOT MODIFY BY HAND. + * Run `yarn special-lint-fix` to update + */ +const t=/^(?:[A-Za-z]:[\\/]|\\\\|\/)/;function n(t,{instancePath:r="",parentData:e,parentDataProperty:a,rootData:s=t}={}){let o=null,l=0;const i=l;let p=!1;const u=l;if(l==l)if(t&&"object"==typeof t&&!Array.isArray(t)){const n=l;for(const n in t)if("encoding"!==n&&"mimetype"!==n){const t={params:{additionalProperty:n}};null===o?o=[t]:o.push(t),l++;break}if(n===l){if(void 0!==t.encoding){let n=t.encoding;const r=l;if(!1!==n&&"base64"!==n){const t={params:{}};null===o?o=[t]:o.push(t),l++}var c=r===l}else c=!0;if(c)if(void 0!==t.mimetype){const n=l;if("string"!=typeof t.mimetype){const t={params:{type:"string"}};null===o?o=[t]:o.push(t),l++}c=n===l}else c=!0}}else{const t={params:{type:"object"}};null===o?o=[t]:o.push(t),l++}var f=u===l;if(p=p||f,!p){const n=l;if(!(t instanceof Function)){const t={params:{}};null===o?o=[t]:o.push(t),l++}f=n===l,p=p||f}if(!p){const t={params:{}};return null===o?o=[t]:o.push(t),l++,n.errors=o,!1}return l=i,null!==o&&(i?o.length=i:o=null),n.errors=o,0===l}function r(e,{instancePath:a="",parentData:s,parentDataProperty:o,rootData:l=e}={}){let i=null,p=0;if(0===p){if(!e||"object"!=typeof e||Array.isArray(e))return r.errors=[{params:{type:"object"}}],!1;{const s=p;for(const t in e)if("binary"!==t&&"dataUrl"!==t&&"emit"!==t&&"filename"!==t&&"outputPath"!==t&&"publicPath"!==t)return r.errors=[{params:{additionalProperty:t}}],!1;if(s===p){if(void 0!==e.binary){const t=p;if("boolean"!=typeof e.binary)return r.errors=[{params:{type:"boolean"}}],!1;var u=t===p}else u=!0;if(u){if(void 0!==e.dataUrl){const t=p;n(e.dataUrl,{instancePath:a+"/dataUrl",parentData:e,parentDataProperty:"dataUrl",rootData:l})||(i=null===i?n.errors:i.concat(n.errors),p=i.length),u=t===p}else u=!0;if(u){if(void 0!==e.emit){const t=p;if("boolean"!=typeof e.emit)return r.errors=[{params:{type:"boolean"}}],!1;u=t===p}else u=!0;if(u){if(void 0!==e.filename){let n=e.filename;const a=p,s=p;let o=!1;const l=p;if(p===l)if("string"==typeof n){if(n.includes("!")||!1!==t.test(n)){const t={params:{}};null===i?i=[t]:i.push(t),p++}else if(n.length<1){const t={params:{}};null===i?i=[t]:i.push(t),p++}}else{const t={params:{type:"string"}};null===i?i=[t]:i.push(t),p++}var c=l===p;if(o=o||c,!o){const t=p;if(!(n instanceof Function)){const t={params:{}};null===i?i=[t]:i.push(t),p++}c=t===p,o=o||c}if(!o){const t={params:{}};return null===i?i=[t]:i.push(t),p++,r.errors=i,!1}p=s,null!==i&&(s?i.length=s:i=null),u=a===p}else u=!0;if(u){if(void 0!==e.outputPath){let n=e.outputPath;const a=p,s=p;let o=!1;const l=p;if(p===l)if("string"==typeof n){if(n.includes("!")||!1!==t.test(n)){const t={params:{}};null===i?i=[t]:i.push(t),p++}}else{const t={params:{type:"string"}};null===i?i=[t]:i.push(t),p++}var f=l===p;if(o=o||f,!o){const t=p;if(!(n instanceof Function)){const t={params:{}};null===i?i=[t]:i.push(t),p++}f=t===p,o=o||f}if(!o){const t={params:{}};return null===i?i=[t]:i.push(t),p++,r.errors=i,!1}p=s,null!==i&&(s?i.length=s:i=null),u=a===p}else u=!0;if(u)if(void 0!==e.publicPath){let t=e.publicPath;const n=p,a=p;let s=!1;const o=p;if("string"!=typeof t){const t={params:{type:"string"}};null===i?i=[t]:i.push(t),p++}var h=o===p;if(s=s||h,!s){const n=p;if(!(t instanceof Function)){const t={params:{}};null===i?i=[t]:i.push(t),p++}h=n===p,s=s||h}if(!s){const t={params:{}};return null===i?i=[t]:i.push(t),p++,r.errors=i,!1}p=a,null!==i&&(a?i.length=a:i=null),u=n===p}else u=!0}}}}}}}return r.errors=i,0===p}function e(t,{instancePath:n="",parentData:a,parentDataProperty:s,rootData:o=t}={}){let l=null,i=0;return r(t,{instancePath:n,parentData:a,parentDataProperty:s,rootData:o})||(l=null===l?r.errors:l.concat(r.errors),i=l.length),e.errors=l,0===i}module.exports=e,module.exports.default=e; \ No newline at end of file diff --git a/schemas/plugins/asset/AssetGeneratorOptions.json b/schemas/plugins/asset/AssetGeneratorOptions.json new file mode 100644 index 00000000000..c00fc87197f --- /dev/null +++ b/schemas/plugins/asset/AssetGeneratorOptions.json @@ -0,0 +1,3 @@ +{ + "$ref": "../../WebpackOptions.json#/definitions/AssetGeneratorOptions" +} diff --git a/schemas/plugins/asset/AssetInlineGeneratorOptions.check.d.ts b/schemas/plugins/asset/AssetInlineGeneratorOptions.check.d.ts new file mode 100644 index 00000000000..6b6174c3f9d --- /dev/null +++ b/schemas/plugins/asset/AssetInlineGeneratorOptions.check.d.ts @@ -0,0 +1,7 @@ +/* + * This file was automatically generated. + * DO NOT MODIFY BY HAND. + * Run `yarn special-lint-fix` to update + */ +declare const check: (options: any) => boolean; +export = check; diff --git a/schemas/plugins/asset/AssetInlineGeneratorOptions.check.js b/schemas/plugins/asset/AssetInlineGeneratorOptions.check.js new file mode 100644 index 00000000000..bffab4f69ca --- /dev/null +++ b/schemas/plugins/asset/AssetInlineGeneratorOptions.check.js @@ -0,0 +1,6 @@ +/* + * This file was automatically generated. + * DO NOT MODIFY BY HAND. + * Run `yarn special-lint-fix` to update + */ +"use strict";function t(r,{instancePath:a="",parentData:e,parentDataProperty:n,rootData:o=r}={}){let s=null,i=0;const l=i;let p=!1;const c=i;if(i==i)if(r&&"object"==typeof r&&!Array.isArray(r)){const t=i;for(const t in r)if("encoding"!==t&&"mimetype"!==t){const r={params:{additionalProperty:t}};null===s?s=[r]:s.push(r),i++;break}if(t===i){if(void 0!==r.encoding){let t=r.encoding;const a=i;if(!1!==t&&"base64"!==t){const t={params:{}};null===s?s=[t]:s.push(t),i++}var u=a===i}else u=!0;if(u)if(void 0!==r.mimetype){const t=i;if("string"!=typeof r.mimetype){const t={params:{type:"string"}};null===s?s=[t]:s.push(t),i++}u=t===i}else u=!0}}else{const t={params:{type:"object"}};null===s?s=[t]:s.push(t),i++}var f=c===i;if(p=p||f,!p){const t=i;if(!(r instanceof Function)){const t={params:{}};null===s?s=[t]:s.push(t),i++}f=t===i,p=p||f}if(!p){const r={params:{}};return null===s?s=[r]:s.push(r),i++,t.errors=s,!1}return i=l,null!==s&&(l?s.length=l:s=null),t.errors=s,0===i}function r(a,{instancePath:e="",parentData:n,parentDataProperty:o,rootData:s=a}={}){let i=null,l=0;if(0===l){if(!a||"object"!=typeof a||Array.isArray(a))return r.errors=[{params:{type:"object"}}],!1;{const n=l;for(const t in a)if("binary"!==t&&"dataUrl"!==t)return r.errors=[{params:{additionalProperty:t}}],!1;if(n===l){if(void 0!==a.binary){const t=l;if("boolean"!=typeof a.binary)return r.errors=[{params:{type:"boolean"}}],!1;var p=t===l}else p=!0;if(p)if(void 0!==a.dataUrl){const r=l;t(a.dataUrl,{instancePath:e+"/dataUrl",parentData:a,parentDataProperty:"dataUrl",rootData:s})||(i=null===i?t.errors:i.concat(t.errors),l=i.length),p=r===l}else p=!0}}}return r.errors=i,0===l}function a(t,{instancePath:e="",parentData:n,parentDataProperty:o,rootData:s=t}={}){let i=null,l=0;return r(t,{instancePath:e,parentData:n,parentDataProperty:o,rootData:s})||(i=null===i?r.errors:i.concat(r.errors),l=i.length),a.errors=i,0===l}module.exports=a,module.exports.default=a; \ No newline at end of file diff --git a/schemas/plugins/asset/AssetInlineGeneratorOptions.json b/schemas/plugins/asset/AssetInlineGeneratorOptions.json new file mode 100644 index 00000000000..a6fff2a170a --- /dev/null +++ b/schemas/plugins/asset/AssetInlineGeneratorOptions.json @@ -0,0 +1,3 @@ +{ + "$ref": "../../WebpackOptions.json#/definitions/AssetInlineGeneratorOptions" +} diff --git a/schemas/plugins/asset/AssetParserOptions.check.d.ts b/schemas/plugins/asset/AssetParserOptions.check.d.ts new file mode 100644 index 00000000000..6b6174c3f9d --- /dev/null +++ b/schemas/plugins/asset/AssetParserOptions.check.d.ts @@ -0,0 +1,7 @@ +/* + * This file was automatically generated. + * DO NOT MODIFY BY HAND. + * Run `yarn special-lint-fix` to update + */ +declare const check: (options: any) => boolean; +export = check; diff --git a/schemas/plugins/asset/AssetParserOptions.check.js b/schemas/plugins/asset/AssetParserOptions.check.js new file mode 100644 index 00000000000..050bca321fc --- /dev/null +++ b/schemas/plugins/asset/AssetParserOptions.check.js @@ -0,0 +1,6 @@ +/* + * This file was automatically generated. + * DO NOT MODIFY BY HAND. + * Run `yarn special-lint-fix` to update + */ +"use strict";function t(r,{instancePath:a="",parentData:n,parentDataProperty:o,rootData:e=r}={}){let s=null,i=0;if(0===i){if(!r||"object"!=typeof r||Array.isArray(r))return t.errors=[{params:{type:"object"}}],!1;{const a=i;for(const a in r)if("dataUrlCondition"!==a)return t.errors=[{params:{additionalProperty:a}}],!1;if(a===i&&void 0!==r.dataUrlCondition){let a=r.dataUrlCondition;const n=i;let o=!1;const e=i;if(i==i)if(a&&"object"==typeof a&&!Array.isArray(a)){const t=i;for(const t in a)if("maxSize"!==t){const r={params:{additionalProperty:t}};null===s?s=[r]:s.push(r),i++;break}if(t===i&&void 0!==a.maxSize&&"number"!=typeof a.maxSize){const t={params:{type:"number"}};null===s?s=[t]:s.push(t),i++}}else{const t={params:{type:"object"}};null===s?s=[t]:s.push(t),i++}var l=e===i;if(o=o||l,!o){const t=i;if(!(a instanceof Function)){const t={params:{}};null===s?s=[t]:s.push(t),i++}l=t===i,o=o||l}if(!o){const r={params:{}};return null===s?s=[r]:s.push(r),i++,t.errors=s,!1}i=n,null!==s&&(n?s.length=n:s=null)}}}return t.errors=s,0===i}function r(a,{instancePath:n="",parentData:o,parentDataProperty:e,rootData:s=a}={}){let i=null,l=0;return t(a,{instancePath:n,parentData:o,parentDataProperty:e,rootData:s})||(i=null===i?t.errors:i.concat(t.errors),l=i.length),r.errors=i,0===l}module.exports=r,module.exports.default=r; \ No newline at end of file diff --git a/schemas/plugins/asset/AssetParserOptions.json b/schemas/plugins/asset/AssetParserOptions.json new file mode 100644 index 00000000000..66bf562d6c1 --- /dev/null +++ b/schemas/plugins/asset/AssetParserOptions.json @@ -0,0 +1,3 @@ +{ + "$ref": "../../WebpackOptions.json#/definitions/AssetParserOptions" +} diff --git a/schemas/plugins/asset/AssetResourceGeneratorOptions.check.d.ts b/schemas/plugins/asset/AssetResourceGeneratorOptions.check.d.ts new file mode 100644 index 00000000000..6b6174c3f9d --- /dev/null +++ b/schemas/plugins/asset/AssetResourceGeneratorOptions.check.d.ts @@ -0,0 +1,7 @@ +/* + * This file was automatically generated. + * DO NOT MODIFY BY HAND. + * Run `yarn special-lint-fix` to update + */ +declare const check: (options: any) => boolean; +export = check; diff --git a/schemas/plugins/asset/AssetResourceGeneratorOptions.check.js b/schemas/plugins/asset/AssetResourceGeneratorOptions.check.js new file mode 100644 index 00000000000..8f9396c923c --- /dev/null +++ b/schemas/plugins/asset/AssetResourceGeneratorOptions.check.js @@ -0,0 +1,6 @@ +/* + * This file was automatically generated. + * DO NOT MODIFY BY HAND. + * Run `yarn special-lint-fix` to update + */ +const t=/^(?:[A-Za-z]:[\\/]|\\\\|\/)/;function n(r,{instancePath:e="",parentData:a,parentDataProperty:s,rootData:o=r}={}){let l=null,i=0;if(0===i){if(!r||"object"!=typeof r||Array.isArray(r))return n.errors=[{params:{type:"object"}}],!1;{const e=i;for(const t in r)if("binary"!==t&&"emit"!==t&&"filename"!==t&&"outputPath"!==t&&"publicPath"!==t)return n.errors=[{params:{additionalProperty:t}}],!1;if(e===i){if(void 0!==r.binary){const t=i;if("boolean"!=typeof r.binary)return n.errors=[{params:{type:"boolean"}}],!1;var u=t===i}else u=!0;if(u){if(void 0!==r.emit){const t=i;if("boolean"!=typeof r.emit)return n.errors=[{params:{type:"boolean"}}],!1;u=t===i}else u=!0;if(u){if(void 0!==r.filename){let e=r.filename;const a=i,s=i;let o=!1;const f=i;if(i===f)if("string"==typeof e){if(e.includes("!")||!1!==t.test(e)){const t={params:{}};null===l?l=[t]:l.push(t),i++}else if(e.length<1){const t={params:{}};null===l?l=[t]:l.push(t),i++}}else{const t={params:{type:"string"}};null===l?l=[t]:l.push(t),i++}var p=f===i;if(o=o||p,!o){const t=i;if(!(e instanceof Function)){const t={params:{}};null===l?l=[t]:l.push(t),i++}p=t===i,o=o||p}if(!o){const t={params:{}};return null===l?l=[t]:l.push(t),i++,n.errors=l,!1}i=s,null!==l&&(s?l.length=s:l=null),u=a===i}else u=!0;if(u){if(void 0!==r.outputPath){let e=r.outputPath;const a=i,s=i;let o=!1;const p=i;if(i===p)if("string"==typeof e){if(e.includes("!")||!1!==t.test(e)){const t={params:{}};null===l?l=[t]:l.push(t),i++}}else{const t={params:{type:"string"}};null===l?l=[t]:l.push(t),i++}var f=p===i;if(o=o||f,!o){const t=i;if(!(e instanceof Function)){const t={params:{}};null===l?l=[t]:l.push(t),i++}f=t===i,o=o||f}if(!o){const t={params:{}};return null===l?l=[t]:l.push(t),i++,n.errors=l,!1}i=s,null!==l&&(s?l.length=s:l=null),u=a===i}else u=!0;if(u)if(void 0!==r.publicPath){let t=r.publicPath;const e=i,a=i;let s=!1;const o=i;if("string"!=typeof t){const t={params:{type:"string"}};null===l?l=[t]:l.push(t),i++}var c=o===i;if(s=s||c,!s){const n=i;if(!(t instanceof Function)){const t={params:{}};null===l?l=[t]:l.push(t),i++}c=n===i,s=s||c}if(!s){const t={params:{}};return null===l?l=[t]:l.push(t),i++,n.errors=l,!1}i=a,null!==l&&(a?l.length=a:l=null),u=e===i}else u=!0}}}}}}return n.errors=l,0===i}function r(t,{instancePath:e="",parentData:a,parentDataProperty:s,rootData:o=t}={}){let l=null,i=0;return n(t,{instancePath:e,parentData:a,parentDataProperty:s,rootData:o})||(l=null===l?n.errors:l.concat(n.errors),i=l.length),r.errors=l,0===i}module.exports=r,module.exports.default=r; \ No newline at end of file diff --git a/schemas/plugins/asset/AssetResourceGeneratorOptions.json b/schemas/plugins/asset/AssetResourceGeneratorOptions.json new file mode 100644 index 00000000000..8ae51d5ca91 --- /dev/null +++ b/schemas/plugins/asset/AssetResourceGeneratorOptions.json @@ -0,0 +1,3 @@ +{ + "$ref": "../../WebpackOptions.json#/definitions/AssetResourceGeneratorOptions" +} diff --git a/schemas/plugins/container/ContainerPlugin.check.d.ts b/schemas/plugins/container/ContainerPlugin.check.d.ts new file mode 100644 index 00000000000..acf68419868 --- /dev/null +++ b/schemas/plugins/container/ContainerPlugin.check.d.ts @@ -0,0 +1,7 @@ +/* + * This file was automatically generated. + * DO NOT MODIFY BY HAND. + * Run `yarn special-lint-fix` to update + */ +declare const check: (options: import("../../../declarations/plugins/container/ContainerPlugin").ContainerPluginOptions) => boolean; +export = check; diff --git a/schemas/plugins/container/ContainerPlugin.check.js b/schemas/plugins/container/ContainerPlugin.check.js new file mode 100644 index 00000000000..bb067d340a1 --- /dev/null +++ b/schemas/plugins/container/ContainerPlugin.check.js @@ -0,0 +1,6 @@ +/* + * This file was automatically generated. + * DO NOT MODIFY BY HAND. + * Run `yarn special-lint-fix` to update + */ +const r=/^(?:[A-Za-z]:[\\/]|\\\\|\/)/;function t(r,{instancePath:e="",parentData:n,parentDataProperty:s,rootData:a=r}={}){if(!Array.isArray(r))return t.errors=[{params:{type:"array"}}],!1;{const e=r.length;for(let n=0;n boolean; +export = check; diff --git a/schemas/plugins/container/ContainerReferencePlugin.check.js b/schemas/plugins/container/ContainerReferencePlugin.check.js new file mode 100644 index 00000000000..7762f19b421 --- /dev/null +++ b/schemas/plugins/container/ContainerReferencePlugin.check.js @@ -0,0 +1,6 @@ +/* + * This file was automatically generated. + * DO NOT MODIFY BY HAND. + * Run `yarn special-lint-fix` to update + */ +"use strict";function r(t,{instancePath:e="",parentData:a,parentDataProperty:n,rootData:o=t}={}){if(!Array.isArray(t))return r.errors=[{params:{type:"array"}}],!1;{const e=t.length;for(let a=0;a boolean; +export = check; diff --git a/schemas/plugins/container/ExternalsType.check.js b/schemas/plugins/container/ExternalsType.check.js new file mode 100644 index 00000000000..dd831ff3ab8 --- /dev/null +++ b/schemas/plugins/container/ExternalsType.check.js @@ -0,0 +1,6 @@ +/* + * This file was automatically generated. + * DO NOT MODIFY BY HAND. + * Run `yarn special-lint-fix` to update + */ +"use strict";function o(m,{instancePath:r="",parentData:s,parentDataProperty:t,rootData:e=m}={}){return"var"!==m&&"module"!==m&&"assign"!==m&&"this"!==m&&"window"!==m&&"self"!==m&&"global"!==m&&"commonjs"!==m&&"commonjs2"!==m&&"commonjs-module"!==m&&"commonjs-static"!==m&&"amd"!==m&&"amd-require"!==m&&"umd"!==m&&"umd2"!==m&&"jsonp"!==m&&"system"!==m&&"promise"!==m&&"import"!==m&&"module-import"!==m&&"script"!==m&&"node-commonjs"!==m?(o.errors=[{params:{}}],!1):(o.errors=null,!0)}module.exports=o,module.exports.default=o; \ No newline at end of file diff --git a/schemas/plugins/container/ExternalsType.json b/schemas/plugins/container/ExternalsType.json new file mode 100644 index 00000000000..d5898583c6b --- /dev/null +++ b/schemas/plugins/container/ExternalsType.json @@ -0,0 +1,3 @@ +{ + "$ref": "./ModuleFederationPlugin.json#/definitions/ExternalsType" +} diff --git a/schemas/plugins/container/ModuleFederationPlugin.check.d.ts b/schemas/plugins/container/ModuleFederationPlugin.check.d.ts new file mode 100644 index 00000000000..280e7d98a42 --- /dev/null +++ b/schemas/plugins/container/ModuleFederationPlugin.check.d.ts @@ -0,0 +1,7 @@ +/* + * This file was automatically generated. + * DO NOT MODIFY BY HAND. + * Run `yarn special-lint-fix` to update + */ +declare const check: (options: import("../../../declarations/plugins/container/ModuleFederationPlugin").ModuleFederationPluginOptions) => boolean; +export = check; diff --git a/schemas/plugins/container/ModuleFederationPlugin.check.js b/schemas/plugins/container/ModuleFederationPlugin.check.js new file mode 100644 index 00000000000..4e9bc895438 --- /dev/null +++ b/schemas/plugins/container/ModuleFederationPlugin.check.js @@ -0,0 +1,6 @@ +/* + * This file was automatically generated. + * DO NOT MODIFY BY HAND. + * Run `yarn special-lint-fix` to update + */ +const t=/^(?:[A-Za-z]:[\\/]|\\\\|\/)/;module.exports=D,module.exports.default=D;const e={definitions:{AmdContainer:{type:"string",minLength:1},AuxiliaryComment:{anyOf:[{type:"string"},{$ref:"#/definitions/LibraryCustomUmdCommentObject"}]},EntryRuntime:{anyOf:[{enum:[!1]},{type:"string",minLength:1}]},Exposes:{anyOf:[{type:"array",items:{anyOf:[{$ref:"#/definitions/ExposesItem"},{$ref:"#/definitions/ExposesObject"}]}},{$ref:"#/definitions/ExposesObject"}]},ExposesConfig:{type:"object",additionalProperties:!1,properties:{import:{anyOf:[{$ref:"#/definitions/ExposesItem"},{$ref:"#/definitions/ExposesItems"}]},name:{type:"string"}},required:["import"]},ExposesItem:{type:"string",minLength:1},ExposesItems:{type:"array",items:{$ref:"#/definitions/ExposesItem"}},ExposesObject:{type:"object",additionalProperties:{anyOf:[{$ref:"#/definitions/ExposesConfig"},{$ref:"#/definitions/ExposesItem"},{$ref:"#/definitions/ExposesItems"}]}},ExternalsType:{enum:["var","module","assign","this","window","self","global","commonjs","commonjs2","commonjs-module","commonjs-static","amd","amd-require","umd","umd2","jsonp","system","promise","import","module-import","script","node-commonjs"]},LibraryCustomUmdCommentObject:{type:"object",additionalProperties:!1,properties:{amd:{type:"string"},commonjs:{type:"string"},commonjs2:{type:"string"},root:{type:"string"}}},LibraryCustomUmdObject:{type:"object",additionalProperties:!1,properties:{amd:{type:"string",minLength:1},commonjs:{type:"string",minLength:1},root:{anyOf:[{type:"array",items:{type:"string",minLength:1}},{type:"string",minLength:1}]}}},LibraryExport:{anyOf:[{type:"array",items:{type:"string",minLength:1}},{type:"string",minLength:1}]},LibraryName:{anyOf:[{type:"array",items:{type:"string",minLength:1},minItems:1},{type:"string",minLength:1},{$ref:"#/definitions/LibraryCustomUmdObject"}]},LibraryOptions:{type:"object",additionalProperties:!1,properties:{amdContainer:{$ref:"#/definitions/AmdContainer"},auxiliaryComment:{$ref:"#/definitions/AuxiliaryComment"},export:{$ref:"#/definitions/LibraryExport"},name:{$ref:"#/definitions/LibraryName"},type:{$ref:"#/definitions/LibraryType"},umdNamedDefine:{$ref:"#/definitions/UmdNamedDefine"}},required:["type"]},LibraryType:{anyOf:[{enum:["var","module","assign","assign-properties","this","window","self","global","commonjs","commonjs2","commonjs-module","commonjs-static","amd","amd-require","umd","umd2","jsonp","system"]},{type:"string"}]},Remotes:{anyOf:[{type:"array",items:{anyOf:[{$ref:"#/definitions/RemotesItem"},{$ref:"#/definitions/RemotesObject"}]}},{$ref:"#/definitions/RemotesObject"}]},RemotesConfig:{type:"object",additionalProperties:!1,properties:{external:{anyOf:[{$ref:"#/definitions/RemotesItem"},{$ref:"#/definitions/RemotesItems"}]},shareScope:{type:"string",minLength:1}},required:["external"]},RemotesItem:{type:"string",minLength:1},RemotesItems:{type:"array",items:{$ref:"#/definitions/RemotesItem"}},RemotesObject:{type:"object",additionalProperties:{anyOf:[{$ref:"#/definitions/RemotesConfig"},{$ref:"#/definitions/RemotesItem"},{$ref:"#/definitions/RemotesItems"}]}},Shared:{anyOf:[{type:"array",items:{anyOf:[{$ref:"#/definitions/SharedItem"},{$ref:"#/definitions/SharedObject"}]}},{$ref:"#/definitions/SharedObject"}]},SharedConfig:{type:"object",additionalProperties:!1,properties:{eager:{type:"boolean"},import:{anyOf:[{enum:[!1]},{$ref:"#/definitions/SharedItem"}]},packageName:{type:"string",minLength:1},requiredVersion:{anyOf:[{enum:[!1]},{type:"string"}]},shareKey:{type:"string",minLength:1},shareScope:{type:"string",minLength:1},singleton:{type:"boolean"},strictVersion:{type:"boolean"},version:{anyOf:[{enum:[!1]},{type:"string"}]}}},SharedItem:{type:"string",minLength:1},SharedObject:{type:"object",additionalProperties:{anyOf:[{$ref:"#/definitions/SharedConfig"},{$ref:"#/definitions/SharedItem"}]}},UmdNamedDefine:{type:"boolean"}},type:"object",additionalProperties:!1,properties:{exposes:{$ref:"#/definitions/Exposes"},filename:{type:"string",absolutePath:!1},library:{$ref:"#/definitions/LibraryOptions"},name:{type:"string"},remoteType:{oneOf:[{$ref:"#/definitions/ExternalsType"}]},remotes:{$ref:"#/definitions/Remotes"},runtime:{$ref:"#/definitions/EntryRuntime"},shareScope:{type:"string",minLength:1},shared:{$ref:"#/definitions/Shared"}}},r=Object.prototype.hasOwnProperty;function n(t,{instancePath:e="",parentData:r,parentDataProperty:s,rootData:a=t}={}){if(!Array.isArray(t))return n.errors=[{params:{type:"array"}}],!1;{const e=t.length;for(let r=0;r boolean; +export = check; diff --git a/schemas/plugins/css/CssAutoGeneratorOptions.check.js b/schemas/plugins/css/CssAutoGeneratorOptions.check.js new file mode 100644 index 00000000000..c27c35e9a16 --- /dev/null +++ b/schemas/plugins/css/CssAutoGeneratorOptions.check.js @@ -0,0 +1,6 @@ +/* + * This file was automatically generated. + * DO NOT MODIFY BY HAND. + * Run `yarn special-lint-fix` to update + */ +"use strict";function e(r,{instancePath:t="",parentData:o,parentDataProperty:n,rootData:a=r}={}){let s=null,l=0;if(0===l){if(!r||"object"!=typeof r||Array.isArray(r))return e.errors=[{params:{type:"object"}}],!1;{const t=l;for(const t in r)if("esModule"!==t&&"exportsConvention"!==t&&"exportsOnly"!==t&&"localIdentName"!==t)return e.errors=[{params:{additionalProperty:t}}],!1;if(t===l){if(void 0!==r.esModule){const t=l;if("boolean"!=typeof r.esModule)return e.errors=[{params:{type:"boolean"}}],!1;var i=t===l}else i=!0;if(i){if(void 0!==r.exportsConvention){let t=r.exportsConvention;const o=l,n=l;let a=!1;const c=l;if("as-is"!==t&&"camel-case"!==t&&"camel-case-only"!==t&&"dashes"!==t&&"dashes-only"!==t){const e={params:{}};null===s?s=[e]:s.push(e),l++}var p=c===l;if(a=a||p,!a){const e=l;if(!(t instanceof Function)){const e={params:{}};null===s?s=[e]:s.push(e),l++}p=e===l,a=a||p}if(!a){const r={params:{}};return null===s?s=[r]:s.push(r),l++,e.errors=s,!1}l=n,null!==s&&(n?s.length=n:s=null),i=o===l}else i=!0;if(i){if(void 0!==r.exportsOnly){const t=l;if("boolean"!=typeof r.exportsOnly)return e.errors=[{params:{type:"boolean"}}],!1;i=t===l}else i=!0;if(i)if(void 0!==r.localIdentName){const t=l;if("string"!=typeof r.localIdentName)return e.errors=[{params:{type:"string"}}],!1;i=t===l}else i=!0}}}}}return e.errors=s,0===l}function r(t,{instancePath:o="",parentData:n,parentDataProperty:a,rootData:s=t}={}){let l=null,i=0;return e(t,{instancePath:o,parentData:n,parentDataProperty:a,rootData:s})||(l=null===l?e.errors:l.concat(e.errors),i=l.length),r.errors=l,0===i}module.exports=r,module.exports.default=r; \ No newline at end of file diff --git a/schemas/plugins/css/CssAutoGeneratorOptions.json b/schemas/plugins/css/CssAutoGeneratorOptions.json new file mode 100644 index 00000000000..99f9a565c31 --- /dev/null +++ b/schemas/plugins/css/CssAutoGeneratorOptions.json @@ -0,0 +1,3 @@ +{ + "$ref": "../../WebpackOptions.json#/definitions/CssAutoGeneratorOptions" +} diff --git a/schemas/plugins/css/CssAutoParserOptions.check.d.ts b/schemas/plugins/css/CssAutoParserOptions.check.d.ts new file mode 100644 index 00000000000..6b6174c3f9d --- /dev/null +++ b/schemas/plugins/css/CssAutoParserOptions.check.d.ts @@ -0,0 +1,7 @@ +/* + * This file was automatically generated. + * DO NOT MODIFY BY HAND. + * Run `yarn special-lint-fix` to update + */ +declare const check: (options: any) => boolean; +export = check; diff --git a/schemas/plugins/css/CssAutoParserOptions.check.js b/schemas/plugins/css/CssAutoParserOptions.check.js new file mode 100644 index 00000000000..43b6d176df5 --- /dev/null +++ b/schemas/plugins/css/CssAutoParserOptions.check.js @@ -0,0 +1,6 @@ +/* + * This file was automatically generated. + * DO NOT MODIFY BY HAND. + * Run `yarn special-lint-fix` to update + */ +"use strict";function r(t,{instancePath:a="",parentData:e,parentDataProperty:o,rootData:n=t}={}){if(!t||"object"!=typeof t||Array.isArray(t))return r.errors=[{params:{type:"object"}}],!1;{const a=0;for(const a in t)if("namedExports"!==a)return r.errors=[{params:{additionalProperty:a}}],!1;if(0===a&&void 0!==t.namedExports&&"boolean"!=typeof t.namedExports)return r.errors=[{params:{type:"boolean"}}],!1}return r.errors=null,!0}function t(a,{instancePath:e="",parentData:o,parentDataProperty:n,rootData:s=a}={}){let p=null,i=0;return r(a,{instancePath:e,parentData:o,parentDataProperty:n,rootData:s})||(p=null===p?r.errors:p.concat(r.errors),i=p.length),t.errors=p,0===i}module.exports=t,module.exports.default=t; \ No newline at end of file diff --git a/schemas/plugins/css/CssAutoParserOptions.json b/schemas/plugins/css/CssAutoParserOptions.json new file mode 100644 index 00000000000..0a406e58ff7 --- /dev/null +++ b/schemas/plugins/css/CssAutoParserOptions.json @@ -0,0 +1,3 @@ +{ + "$ref": "../../WebpackOptions.json#/definitions/CssAutoParserOptions" +} diff --git a/schemas/plugins/css/CssGeneratorOptions.check.d.ts b/schemas/plugins/css/CssGeneratorOptions.check.d.ts new file mode 100644 index 00000000000..6b6174c3f9d --- /dev/null +++ b/schemas/plugins/css/CssGeneratorOptions.check.d.ts @@ -0,0 +1,7 @@ +/* + * This file was automatically generated. + * DO NOT MODIFY BY HAND. + * Run `yarn special-lint-fix` to update + */ +declare const check: (options: any) => boolean; +export = check; diff --git a/schemas/plugins/css/CssGeneratorOptions.check.js b/schemas/plugins/css/CssGeneratorOptions.check.js new file mode 100644 index 00000000000..8d9a05ed3a4 --- /dev/null +++ b/schemas/plugins/css/CssGeneratorOptions.check.js @@ -0,0 +1,6 @@ +/* + * This file was automatically generated. + * DO NOT MODIFY BY HAND. + * Run `yarn special-lint-fix` to update + */ +"use strict";function r(e,{instancePath:t="",parentData:o,parentDataProperty:a,rootData:n=e}={}){if(!e||"object"!=typeof e||Array.isArray(e))return r.errors=[{params:{type:"object"}}],!1;{const t=0;for(const t in e)if("esModule"!==t&&"exportsOnly"!==t)return r.errors=[{params:{additionalProperty:t}}],!1;if(0===t){if(void 0!==e.esModule){const t=0;if("boolean"!=typeof e.esModule)return r.errors=[{params:{type:"boolean"}}],!1;var s=0===t}else s=!0;if(s)if(void 0!==e.exportsOnly){const t=0;if("boolean"!=typeof e.exportsOnly)return r.errors=[{params:{type:"boolean"}}],!1;s=0===t}else s=!0}}return r.errors=null,!0}function e(t,{instancePath:o="",parentData:a,parentDataProperty:n,rootData:s=t}={}){let p=null,l=0;return r(t,{instancePath:o,parentData:a,parentDataProperty:n,rootData:s})||(p=null===p?r.errors:p.concat(r.errors),l=p.length),e.errors=p,0===l}module.exports=e,module.exports.default=e; \ No newline at end of file diff --git a/schemas/plugins/css/CssGeneratorOptions.json b/schemas/plugins/css/CssGeneratorOptions.json new file mode 100644 index 00000000000..193ec90f759 --- /dev/null +++ b/schemas/plugins/css/CssGeneratorOptions.json @@ -0,0 +1,3 @@ +{ + "$ref": "../../WebpackOptions.json#/definitions/CssGeneratorOptions" +} diff --git a/schemas/plugins/css/CssGlobalGeneratorOptions.check.d.ts b/schemas/plugins/css/CssGlobalGeneratorOptions.check.d.ts new file mode 100644 index 00000000000..6b6174c3f9d --- /dev/null +++ b/schemas/plugins/css/CssGlobalGeneratorOptions.check.d.ts @@ -0,0 +1,7 @@ +/* + * This file was automatically generated. + * DO NOT MODIFY BY HAND. + * Run `yarn special-lint-fix` to update + */ +declare const check: (options: any) => boolean; +export = check; diff --git a/schemas/plugins/css/CssGlobalGeneratorOptions.check.js b/schemas/plugins/css/CssGlobalGeneratorOptions.check.js new file mode 100644 index 00000000000..c27c35e9a16 --- /dev/null +++ b/schemas/plugins/css/CssGlobalGeneratorOptions.check.js @@ -0,0 +1,6 @@ +/* + * This file was automatically generated. + * DO NOT MODIFY BY HAND. + * Run `yarn special-lint-fix` to update + */ +"use strict";function e(r,{instancePath:t="",parentData:o,parentDataProperty:n,rootData:a=r}={}){let s=null,l=0;if(0===l){if(!r||"object"!=typeof r||Array.isArray(r))return e.errors=[{params:{type:"object"}}],!1;{const t=l;for(const t in r)if("esModule"!==t&&"exportsConvention"!==t&&"exportsOnly"!==t&&"localIdentName"!==t)return e.errors=[{params:{additionalProperty:t}}],!1;if(t===l){if(void 0!==r.esModule){const t=l;if("boolean"!=typeof r.esModule)return e.errors=[{params:{type:"boolean"}}],!1;var i=t===l}else i=!0;if(i){if(void 0!==r.exportsConvention){let t=r.exportsConvention;const o=l,n=l;let a=!1;const c=l;if("as-is"!==t&&"camel-case"!==t&&"camel-case-only"!==t&&"dashes"!==t&&"dashes-only"!==t){const e={params:{}};null===s?s=[e]:s.push(e),l++}var p=c===l;if(a=a||p,!a){const e=l;if(!(t instanceof Function)){const e={params:{}};null===s?s=[e]:s.push(e),l++}p=e===l,a=a||p}if(!a){const r={params:{}};return null===s?s=[r]:s.push(r),l++,e.errors=s,!1}l=n,null!==s&&(n?s.length=n:s=null),i=o===l}else i=!0;if(i){if(void 0!==r.exportsOnly){const t=l;if("boolean"!=typeof r.exportsOnly)return e.errors=[{params:{type:"boolean"}}],!1;i=t===l}else i=!0;if(i)if(void 0!==r.localIdentName){const t=l;if("string"!=typeof r.localIdentName)return e.errors=[{params:{type:"string"}}],!1;i=t===l}else i=!0}}}}}return e.errors=s,0===l}function r(t,{instancePath:o="",parentData:n,parentDataProperty:a,rootData:s=t}={}){let l=null,i=0;return e(t,{instancePath:o,parentData:n,parentDataProperty:a,rootData:s})||(l=null===l?e.errors:l.concat(e.errors),i=l.length),r.errors=l,0===i}module.exports=r,module.exports.default=r; \ No newline at end of file diff --git a/schemas/plugins/css/CssGlobalGeneratorOptions.json b/schemas/plugins/css/CssGlobalGeneratorOptions.json new file mode 100644 index 00000000000..a4a1aaf56e8 --- /dev/null +++ b/schemas/plugins/css/CssGlobalGeneratorOptions.json @@ -0,0 +1,3 @@ +{ + "$ref": "../../WebpackOptions.json#/definitions/CssGlobalGeneratorOptions" +} diff --git a/schemas/plugins/css/CssGlobalParserOptions.check.d.ts b/schemas/plugins/css/CssGlobalParserOptions.check.d.ts new file mode 100644 index 00000000000..6b6174c3f9d --- /dev/null +++ b/schemas/plugins/css/CssGlobalParserOptions.check.d.ts @@ -0,0 +1,7 @@ +/* + * This file was automatically generated. + * DO NOT MODIFY BY HAND. + * Run `yarn special-lint-fix` to update + */ +declare const check: (options: any) => boolean; +export = check; diff --git a/schemas/plugins/css/CssGlobalParserOptions.check.js b/schemas/plugins/css/CssGlobalParserOptions.check.js new file mode 100644 index 00000000000..43b6d176df5 --- /dev/null +++ b/schemas/plugins/css/CssGlobalParserOptions.check.js @@ -0,0 +1,6 @@ +/* + * This file was automatically generated. + * DO NOT MODIFY BY HAND. + * Run `yarn special-lint-fix` to update + */ +"use strict";function r(t,{instancePath:a="",parentData:e,parentDataProperty:o,rootData:n=t}={}){if(!t||"object"!=typeof t||Array.isArray(t))return r.errors=[{params:{type:"object"}}],!1;{const a=0;for(const a in t)if("namedExports"!==a)return r.errors=[{params:{additionalProperty:a}}],!1;if(0===a&&void 0!==t.namedExports&&"boolean"!=typeof t.namedExports)return r.errors=[{params:{type:"boolean"}}],!1}return r.errors=null,!0}function t(a,{instancePath:e="",parentData:o,parentDataProperty:n,rootData:s=a}={}){let p=null,i=0;return r(a,{instancePath:e,parentData:o,parentDataProperty:n,rootData:s})||(p=null===p?r.errors:p.concat(r.errors),i=p.length),t.errors=p,0===i}module.exports=t,module.exports.default=t; \ No newline at end of file diff --git a/schemas/plugins/css/CssGlobalParserOptions.json b/schemas/plugins/css/CssGlobalParserOptions.json new file mode 100644 index 00000000000..75f9de6a2e7 --- /dev/null +++ b/schemas/plugins/css/CssGlobalParserOptions.json @@ -0,0 +1,3 @@ +{ + "$ref": "../../WebpackOptions.json#/definitions/CssGlobalParserOptions" +} diff --git a/schemas/plugins/css/CssModuleGeneratorOptions.check.d.ts b/schemas/plugins/css/CssModuleGeneratorOptions.check.d.ts new file mode 100644 index 00000000000..6b6174c3f9d --- /dev/null +++ b/schemas/plugins/css/CssModuleGeneratorOptions.check.d.ts @@ -0,0 +1,7 @@ +/* + * This file was automatically generated. + * DO NOT MODIFY BY HAND. + * Run `yarn special-lint-fix` to update + */ +declare const check: (options: any) => boolean; +export = check; diff --git a/schemas/plugins/css/CssModuleGeneratorOptions.check.js b/schemas/plugins/css/CssModuleGeneratorOptions.check.js new file mode 100644 index 00000000000..c27c35e9a16 --- /dev/null +++ b/schemas/plugins/css/CssModuleGeneratorOptions.check.js @@ -0,0 +1,6 @@ +/* + * This file was automatically generated. + * DO NOT MODIFY BY HAND. + * Run `yarn special-lint-fix` to update + */ +"use strict";function e(r,{instancePath:t="",parentData:o,parentDataProperty:n,rootData:a=r}={}){let s=null,l=0;if(0===l){if(!r||"object"!=typeof r||Array.isArray(r))return e.errors=[{params:{type:"object"}}],!1;{const t=l;for(const t in r)if("esModule"!==t&&"exportsConvention"!==t&&"exportsOnly"!==t&&"localIdentName"!==t)return e.errors=[{params:{additionalProperty:t}}],!1;if(t===l){if(void 0!==r.esModule){const t=l;if("boolean"!=typeof r.esModule)return e.errors=[{params:{type:"boolean"}}],!1;var i=t===l}else i=!0;if(i){if(void 0!==r.exportsConvention){let t=r.exportsConvention;const o=l,n=l;let a=!1;const c=l;if("as-is"!==t&&"camel-case"!==t&&"camel-case-only"!==t&&"dashes"!==t&&"dashes-only"!==t){const e={params:{}};null===s?s=[e]:s.push(e),l++}var p=c===l;if(a=a||p,!a){const e=l;if(!(t instanceof Function)){const e={params:{}};null===s?s=[e]:s.push(e),l++}p=e===l,a=a||p}if(!a){const r={params:{}};return null===s?s=[r]:s.push(r),l++,e.errors=s,!1}l=n,null!==s&&(n?s.length=n:s=null),i=o===l}else i=!0;if(i){if(void 0!==r.exportsOnly){const t=l;if("boolean"!=typeof r.exportsOnly)return e.errors=[{params:{type:"boolean"}}],!1;i=t===l}else i=!0;if(i)if(void 0!==r.localIdentName){const t=l;if("string"!=typeof r.localIdentName)return e.errors=[{params:{type:"string"}}],!1;i=t===l}else i=!0}}}}}return e.errors=s,0===l}function r(t,{instancePath:o="",parentData:n,parentDataProperty:a,rootData:s=t}={}){let l=null,i=0;return e(t,{instancePath:o,parentData:n,parentDataProperty:a,rootData:s})||(l=null===l?e.errors:l.concat(e.errors),i=l.length),r.errors=l,0===i}module.exports=r,module.exports.default=r; \ No newline at end of file diff --git a/schemas/plugins/css/CssModuleGeneratorOptions.json b/schemas/plugins/css/CssModuleGeneratorOptions.json new file mode 100644 index 00000000000..5c95fb5541c --- /dev/null +++ b/schemas/plugins/css/CssModuleGeneratorOptions.json @@ -0,0 +1,3 @@ +{ + "$ref": "../../WebpackOptions.json#/definitions/CssModuleGeneratorOptions" +} diff --git a/schemas/plugins/css/CssModuleParserOptions.check.d.ts b/schemas/plugins/css/CssModuleParserOptions.check.d.ts new file mode 100644 index 00000000000..6b6174c3f9d --- /dev/null +++ b/schemas/plugins/css/CssModuleParserOptions.check.d.ts @@ -0,0 +1,7 @@ +/* + * This file was automatically generated. + * DO NOT MODIFY BY HAND. + * Run `yarn special-lint-fix` to update + */ +declare const check: (options: any) => boolean; +export = check; diff --git a/schemas/plugins/css/CssModuleParserOptions.check.js b/schemas/plugins/css/CssModuleParserOptions.check.js new file mode 100644 index 00000000000..43b6d176df5 --- /dev/null +++ b/schemas/plugins/css/CssModuleParserOptions.check.js @@ -0,0 +1,6 @@ +/* + * This file was automatically generated. + * DO NOT MODIFY BY HAND. + * Run `yarn special-lint-fix` to update + */ +"use strict";function r(t,{instancePath:a="",parentData:e,parentDataProperty:o,rootData:n=t}={}){if(!t||"object"!=typeof t||Array.isArray(t))return r.errors=[{params:{type:"object"}}],!1;{const a=0;for(const a in t)if("namedExports"!==a)return r.errors=[{params:{additionalProperty:a}}],!1;if(0===a&&void 0!==t.namedExports&&"boolean"!=typeof t.namedExports)return r.errors=[{params:{type:"boolean"}}],!1}return r.errors=null,!0}function t(a,{instancePath:e="",parentData:o,parentDataProperty:n,rootData:s=a}={}){let p=null,i=0;return r(a,{instancePath:e,parentData:o,parentDataProperty:n,rootData:s})||(p=null===p?r.errors:p.concat(r.errors),i=p.length),t.errors=p,0===i}module.exports=t,module.exports.default=t; \ No newline at end of file diff --git a/schemas/plugins/css/CssModuleParserOptions.json b/schemas/plugins/css/CssModuleParserOptions.json new file mode 100644 index 00000000000..97168a04bed --- /dev/null +++ b/schemas/plugins/css/CssModuleParserOptions.json @@ -0,0 +1,3 @@ +{ + "$ref": "../../WebpackOptions.json#/definitions/CssModuleParserOptions" +} diff --git a/schemas/plugins/css/CssParserOptions.check.d.ts b/schemas/plugins/css/CssParserOptions.check.d.ts new file mode 100644 index 00000000000..6b6174c3f9d --- /dev/null +++ b/schemas/plugins/css/CssParserOptions.check.d.ts @@ -0,0 +1,7 @@ +/* + * This file was automatically generated. + * DO NOT MODIFY BY HAND. + * Run `yarn special-lint-fix` to update + */ +declare const check: (options: any) => boolean; +export = check; diff --git a/schemas/plugins/css/CssParserOptions.check.js b/schemas/plugins/css/CssParserOptions.check.js new file mode 100644 index 00000000000..43b6d176df5 --- /dev/null +++ b/schemas/plugins/css/CssParserOptions.check.js @@ -0,0 +1,6 @@ +/* + * This file was automatically generated. + * DO NOT MODIFY BY HAND. + * Run `yarn special-lint-fix` to update + */ +"use strict";function r(t,{instancePath:a="",parentData:e,parentDataProperty:o,rootData:n=t}={}){if(!t||"object"!=typeof t||Array.isArray(t))return r.errors=[{params:{type:"object"}}],!1;{const a=0;for(const a in t)if("namedExports"!==a)return r.errors=[{params:{additionalProperty:a}}],!1;if(0===a&&void 0!==t.namedExports&&"boolean"!=typeof t.namedExports)return r.errors=[{params:{type:"boolean"}}],!1}return r.errors=null,!0}function t(a,{instancePath:e="",parentData:o,parentDataProperty:n,rootData:s=a}={}){let p=null,i=0;return r(a,{instancePath:e,parentData:o,parentDataProperty:n,rootData:s})||(p=null===p?r.errors:p.concat(r.errors),i=p.length),t.errors=p,0===i}module.exports=t,module.exports.default=t; \ No newline at end of file diff --git a/schemas/plugins/css/CssParserOptions.json b/schemas/plugins/css/CssParserOptions.json new file mode 100644 index 00000000000..dc79f62c430 --- /dev/null +++ b/schemas/plugins/css/CssParserOptions.json @@ -0,0 +1,3 @@ +{ + "$ref": "../../WebpackOptions.json#/definitions/CssParserOptions" +} diff --git a/schemas/plugins/debug/ProfilingPlugin.check.d.ts b/schemas/plugins/debug/ProfilingPlugin.check.d.ts new file mode 100644 index 00000000000..37407dcfa0c --- /dev/null +++ b/schemas/plugins/debug/ProfilingPlugin.check.d.ts @@ -0,0 +1,7 @@ +/* + * This file was automatically generated. + * DO NOT MODIFY BY HAND. + * Run `yarn special-lint-fix` to update + */ +declare const check: (options: import("../../../declarations/plugins/debug/ProfilingPlugin").ProfilingPluginOptions) => boolean; +export = check; diff --git a/schemas/plugins/debug/ProfilingPlugin.check.js b/schemas/plugins/debug/ProfilingPlugin.check.js new file mode 100644 index 00000000000..6b876107dcb --- /dev/null +++ b/schemas/plugins/debug/ProfilingPlugin.check.js @@ -0,0 +1,6 @@ +/* + * This file was automatically generated. + * DO NOT MODIFY BY HAND. + * Run `yarn special-lint-fix` to update + */ +const r=/^(?:[A-Za-z]:[\\/]|\\\\|\/)/;function t(e,{instancePath:a="",parentData:o,parentDataProperty:n,rootData:s=e}={}){if(!e||"object"!=typeof e||Array.isArray(e))return t.errors=[{params:{type:"object"}}],!1;{const a=0;for(const r in e)if("outputPath"!==r)return t.errors=[{params:{additionalProperty:r}}],!1;if(0===a&&void 0!==e.outputPath){let a=e.outputPath;if("string"!=typeof a)return t.errors=[{params:{type:"string"}}],!1;if(a.includes("!")||!0!==r.test(a))return t.errors=[{params:{}}],!1}}return t.errors=null,!0}module.exports=t,module.exports.default=t; \ No newline at end of file diff --git a/schemas/plugins/ids/OccurrenceChunkIdsPlugin.check.d.ts b/schemas/plugins/ids/OccurrenceChunkIdsPlugin.check.d.ts new file mode 100644 index 00000000000..3332a7b32ac --- /dev/null +++ b/schemas/plugins/ids/OccurrenceChunkIdsPlugin.check.d.ts @@ -0,0 +1,7 @@ +/* + * This file was automatically generated. + * DO NOT MODIFY BY HAND. + * Run `yarn special-lint-fix` to update + */ +declare const check: (options: import("../../../declarations/plugins/ids/OccurrenceChunkIdsPlugin").OccurrenceChunkIdsPluginOptions) => boolean; +export = check; diff --git a/schemas/plugins/ids/OccurrenceChunkIdsPlugin.check.js b/schemas/plugins/ids/OccurrenceChunkIdsPlugin.check.js new file mode 100644 index 00000000000..45078106de3 --- /dev/null +++ b/schemas/plugins/ids/OccurrenceChunkIdsPlugin.check.js @@ -0,0 +1,6 @@ +/* + * This file was automatically generated. + * DO NOT MODIFY BY HAND. + * Run `yarn special-lint-fix` to update + */ +"use strict";function r(t,{instancePath:e="",parentData:o,parentDataProperty:a,rootData:i=t}={}){if(!t||"object"!=typeof t||Array.isArray(t))return r.errors=[{params:{type:"object"}}],!1;{const e=0;for(const e in t)if("prioritiseInitial"!==e)return r.errors=[{params:{additionalProperty:e}}],!1;if(0===e&&void 0!==t.prioritiseInitial&&"boolean"!=typeof t.prioritiseInitial)return r.errors=[{params:{type:"boolean"}}],!1}return r.errors=null,!0}module.exports=r,module.exports.default=r; \ No newline at end of file diff --git a/schemas/plugins/ids/OccurrenceModuleIdsPlugin.check.d.ts b/schemas/plugins/ids/OccurrenceModuleIdsPlugin.check.d.ts new file mode 100644 index 00000000000..8b5a22f15e4 --- /dev/null +++ b/schemas/plugins/ids/OccurrenceModuleIdsPlugin.check.d.ts @@ -0,0 +1,7 @@ +/* + * This file was automatically generated. + * DO NOT MODIFY BY HAND. + * Run `yarn special-lint-fix` to update + */ +declare const check: (options: import("../../../declarations/plugins/ids/OccurrenceModuleIdsPlugin").OccurrenceModuleIdsPluginOptions) => boolean; +export = check; diff --git a/schemas/plugins/ids/OccurrenceModuleIdsPlugin.check.js b/schemas/plugins/ids/OccurrenceModuleIdsPlugin.check.js new file mode 100644 index 00000000000..45078106de3 --- /dev/null +++ b/schemas/plugins/ids/OccurrenceModuleIdsPlugin.check.js @@ -0,0 +1,6 @@ +/* + * This file was automatically generated. + * DO NOT MODIFY BY HAND. + * Run `yarn special-lint-fix` to update + */ +"use strict";function r(t,{instancePath:e="",parentData:o,parentDataProperty:a,rootData:i=t}={}){if(!t||"object"!=typeof t||Array.isArray(t))return r.errors=[{params:{type:"object"}}],!1;{const e=0;for(const e in t)if("prioritiseInitial"!==e)return r.errors=[{params:{additionalProperty:e}}],!1;if(0===e&&void 0!==t.prioritiseInitial&&"boolean"!=typeof t.prioritiseInitial)return r.errors=[{params:{type:"boolean"}}],!1}return r.errors=null,!0}module.exports=r,module.exports.default=r; \ No newline at end of file diff --git a/schemas/plugins/optimize/AggressiveSplittingPlugin.check.d.ts b/schemas/plugins/optimize/AggressiveSplittingPlugin.check.d.ts new file mode 100644 index 00000000000..30a281d120d --- /dev/null +++ b/schemas/plugins/optimize/AggressiveSplittingPlugin.check.d.ts @@ -0,0 +1,7 @@ +/* + * This file was automatically generated. + * DO NOT MODIFY BY HAND. + * Run `yarn special-lint-fix` to update + */ +declare const check: (options: import("../../../declarations/plugins/optimize/AggressiveSplittingPlugin").AggressiveSplittingPluginOptions) => boolean; +export = check; diff --git a/schemas/plugins/optimize/AggressiveSplittingPlugin.check.js b/schemas/plugins/optimize/AggressiveSplittingPlugin.check.js new file mode 100644 index 00000000000..284fe8df432 --- /dev/null +++ b/schemas/plugins/optimize/AggressiveSplittingPlugin.check.js @@ -0,0 +1,6 @@ +/* + * This file was automatically generated. + * DO NOT MODIFY BY HAND. + * Run `yarn special-lint-fix` to update + */ +"use strict";function r(e,{instancePath:t="",parentData:n,parentDataProperty:i,rootData:o=e}={}){if(!e||"object"!=typeof e||Array.isArray(e))return r.errors=[{params:{type:"object"}}],!1;{const t=0;for(const t in e)if("chunkOverhead"!==t&&"entryChunkMultiplicator"!==t&&"maxSize"!==t&&"minSize"!==t)return r.errors=[{params:{additionalProperty:t}}],!1;if(0===t){if(void 0!==e.chunkOverhead){const t=0;if("number"!=typeof e.chunkOverhead)return r.errors=[{params:{type:"number"}}],!1;var a=0===t}else a=!0;if(a){if(void 0!==e.entryChunkMultiplicator){const t=0;if("number"!=typeof e.entryChunkMultiplicator)return r.errors=[{params:{type:"number"}}],!1;a=0===t}else a=!0;if(a){if(void 0!==e.maxSize){const t=0;if("number"!=typeof e.maxSize)return r.errors=[{params:{type:"number"}}],!1;a=0===t}else a=!0;if(a)if(void 0!==e.minSize){const t=0;if("number"!=typeof e.minSize)return r.errors=[{params:{type:"number"}}],!1;a=0===t}else a=!0}}}}return r.errors=null,!0}module.exports=r,module.exports.default=r; \ No newline at end of file diff --git a/schemas/plugins/optimize/LimitChunkCountPlugin.check.d.ts b/schemas/plugins/optimize/LimitChunkCountPlugin.check.d.ts new file mode 100644 index 00000000000..32c052536ca --- /dev/null +++ b/schemas/plugins/optimize/LimitChunkCountPlugin.check.d.ts @@ -0,0 +1,7 @@ +/* + * This file was automatically generated. + * DO NOT MODIFY BY HAND. + * Run `yarn special-lint-fix` to update + */ +declare const check: (options: import("../../../declarations/plugins/optimize/LimitChunkCountPlugin").LimitChunkCountPluginOptions) => boolean; +export = check; diff --git a/schemas/plugins/optimize/LimitChunkCountPlugin.check.js b/schemas/plugins/optimize/LimitChunkCountPlugin.check.js new file mode 100644 index 00000000000..69d9a8193ee --- /dev/null +++ b/schemas/plugins/optimize/LimitChunkCountPlugin.check.js @@ -0,0 +1,6 @@ +/* + * This file was automatically generated. + * DO NOT MODIFY BY HAND. + * Run `yarn special-lint-fix` to update + */ +"use strict";function r(e,{instancePath:t="",parentData:n,parentDataProperty:a,rootData:o=e}={}){if(!e||"object"!=typeof e||Array.isArray(e))return r.errors=[{params:{type:"object"}}],!1;{let t;if(void 0===e.maxChunks&&(t="maxChunks"))return r.errors=[{params:{missingProperty:t}}],!1;{const t=0;for(const t in e)if("chunkOverhead"!==t&&"entryChunkMultiplicator"!==t&&"maxChunks"!==t)return r.errors=[{params:{additionalProperty:t}}],!1;if(0===t){if(void 0!==e.chunkOverhead){const t=0;if("number"!=typeof e.chunkOverhead)return r.errors=[{params:{type:"number"}}],!1;var s=0===t}else s=!0;if(s){if(void 0!==e.entryChunkMultiplicator){const t=0;if("number"!=typeof e.entryChunkMultiplicator)return r.errors=[{params:{type:"number"}}],!1;s=0===t}else s=!0;if(s)if(void 0!==e.maxChunks){let t=e.maxChunks;const n=0;if(0===n){if("number"!=typeof t)return r.errors=[{params:{type:"number"}}],!1;if(t<1||isNaN(t))return r.errors=[{params:{comparison:">=",limit:1}}],!1}s=0===n}else s=!0}}}}return r.errors=null,!0}module.exports=r,module.exports.default=r; \ No newline at end of file diff --git a/schemas/plugins/optimize/MinChunkSizePlugin.check.d.ts b/schemas/plugins/optimize/MinChunkSizePlugin.check.d.ts new file mode 100644 index 00000000000..26de6798d18 --- /dev/null +++ b/schemas/plugins/optimize/MinChunkSizePlugin.check.d.ts @@ -0,0 +1,7 @@ +/* + * This file was automatically generated. + * DO NOT MODIFY BY HAND. + * Run `yarn special-lint-fix` to update + */ +declare const check: (options: import("../../../declarations/plugins/optimize/MinChunkSizePlugin").MinChunkSizePluginOptions) => boolean; +export = check; diff --git a/schemas/plugins/optimize/MinChunkSizePlugin.check.js b/schemas/plugins/optimize/MinChunkSizePlugin.check.js new file mode 100644 index 00000000000..78717b1929f --- /dev/null +++ b/schemas/plugins/optimize/MinChunkSizePlugin.check.js @@ -0,0 +1,6 @@ +/* + * This file was automatically generated. + * DO NOT MODIFY BY HAND. + * Run `yarn special-lint-fix` to update + */ +"use strict";function r(e,{instancePath:t="",parentData:n,parentDataProperty:i,rootData:o=e}={}){if(!e||"object"!=typeof e||Array.isArray(e))return r.errors=[{params:{type:"object"}}],!1;{let t;if(void 0===e.minChunkSize&&(t="minChunkSize"))return r.errors=[{params:{missingProperty:t}}],!1;{const t=0;for(const t in e)if("chunkOverhead"!==t&&"entryChunkMultiplicator"!==t&&"minChunkSize"!==t)return r.errors=[{params:{additionalProperty:t}}],!1;if(0===t){if(void 0!==e.chunkOverhead){const t=0;if("number"!=typeof e.chunkOverhead)return r.errors=[{params:{type:"number"}}],!1;var a=0===t}else a=!0;if(a){if(void 0!==e.entryChunkMultiplicator){const t=0;if("number"!=typeof e.entryChunkMultiplicator)return r.errors=[{params:{type:"number"}}],!1;a=0===t}else a=!0;if(a)if(void 0!==e.minChunkSize){const t=0;if("number"!=typeof e.minChunkSize)return r.errors=[{params:{type:"number"}}],!1;a=0===t}else a=!0}}}}return r.errors=null,!0}module.exports=r,module.exports.default=r; \ No newline at end of file diff --git a/schemas/plugins/schemes/HttpUriPlugin.check.d.ts b/schemas/plugins/schemes/HttpUriPlugin.check.d.ts new file mode 100644 index 00000000000..a6fd39a552c --- /dev/null +++ b/schemas/plugins/schemes/HttpUriPlugin.check.d.ts @@ -0,0 +1,7 @@ +/* + * This file was automatically generated. + * DO NOT MODIFY BY HAND. + * Run `yarn special-lint-fix` to update + */ +declare const check: (options: import("../../../declarations/plugins/schemes/HttpUriPlugin").HttpUriPluginOptions) => boolean; +export = check; diff --git a/schemas/plugins/schemes/HttpUriPlugin.check.js b/schemas/plugins/schemes/HttpUriPlugin.check.js new file mode 100644 index 00000000000..d6ca85eaec4 --- /dev/null +++ b/schemas/plugins/schemes/HttpUriPlugin.check.js @@ -0,0 +1,6 @@ +/* + * This file was automatically generated. + * DO NOT MODIFY BY HAND. + * Run `yarn special-lint-fix` to update + */ +const r=/^(?:[A-Za-z]:[\\/]|\\\\|\/)/;module.exports=n,module.exports.default=n;const t=new RegExp("^https?://","u");function e(n,{instancePath:o="",parentData:s,parentDataProperty:a,rootData:l=n}={}){let i=null,p=0;if(0===p){if(!n||"object"!=typeof n||Array.isArray(n))return e.errors=[{params:{type:"object"}}],!1;{let o;if(void 0===n.allowedUris&&(o="allowedUris"))return e.errors=[{params:{missingProperty:o}}],!1;{const o=p;for(const r in n)if("allowedUris"!==r&&"cacheLocation"!==r&&"frozen"!==r&&"lockfileLocation"!==r&&"proxy"!==r&&"upgrade"!==r)return e.errors=[{params:{additionalProperty:r}}],!1;if(o===p){if(void 0!==n.allowedUris){let r=n.allowedUris;const o=p;if(p==p){if(!Array.isArray(r))return e.errors=[{params:{type:"array"}}],!1;{const n=r.length;for(let o=0;o boolean)" + } + ] + } + } + }, + "title": "HttpUriPluginOptions", + "oneOf": [ + { + "$ref": "#/definitions/HttpUriOptions" + } + ] +} diff --git a/schemas/plugins/sharing/ConsumeSharedPlugin.check.d.ts b/schemas/plugins/sharing/ConsumeSharedPlugin.check.d.ts new file mode 100644 index 00000000000..5d05e0a5701 --- /dev/null +++ b/schemas/plugins/sharing/ConsumeSharedPlugin.check.d.ts @@ -0,0 +1,7 @@ +/* + * This file was automatically generated. + * DO NOT MODIFY BY HAND. + * Run `yarn special-lint-fix` to update + */ +declare const check: (options: import("../../../declarations/plugins/sharing/ConsumeSharedPlugin").ConsumeSharedPluginOptions) => boolean; +export = check; diff --git a/schemas/plugins/sharing/ConsumeSharedPlugin.check.js b/schemas/plugins/sharing/ConsumeSharedPlugin.check.js new file mode 100644 index 00000000000..1f206b676ea --- /dev/null +++ b/schemas/plugins/sharing/ConsumeSharedPlugin.check.js @@ -0,0 +1,6 @@ +/* + * This file was automatically generated. + * DO NOT MODIFY BY HAND. + * Run `yarn special-lint-fix` to update + */ +"use strict";function r(e,{instancePath:t="",parentData:n,parentDataProperty:s,rootData:a=e}={}){let o=null,i=0;if(0===i){if(!e||"object"!=typeof e||Array.isArray(e))return r.errors=[{params:{type:"object"}}],!1;{const t=i;for(const t in e)if("eager"!==t&&"import"!==t&&"packageName"!==t&&"requiredVersion"!==t&&"shareKey"!==t&&"shareScope"!==t&&"singleton"!==t&&"strictVersion"!==t)return r.errors=[{params:{additionalProperty:t}}],!1;if(t===i){if(void 0!==e.eager){const t=i;if("boolean"!=typeof e.eager)return r.errors=[{params:{type:"boolean"}}],!1;var l=t===i}else l=!0;if(l){if(void 0!==e.import){let t=e.import;const n=i,s=i;let a=!1;const f=i;if(!1!==t){const r={params:{}};null===o?o=[r]:o.push(r),i++}var p=f===i;if(a=a||p,!a){const r=i;if(i==i)if("string"==typeof t){if(t.length<1){const r={params:{}};null===o?o=[r]:o.push(r),i++}}else{const r={params:{type:"string"}};null===o?o=[r]:o.push(r),i++}p=r===i,a=a||p}if(!a){const e={params:{}};return null===o?o=[e]:o.push(e),i++,r.errors=o,!1}i=s,null!==o&&(s?o.length=s:o=null),l=n===i}else l=!0;if(l){if(void 0!==e.packageName){let t=e.packageName;const n=i;if(i===n){if("string"!=typeof t)return r.errors=[{params:{type:"string"}}],!1;if(t.length<1)return r.errors=[{params:{}}],!1}l=n===i}else l=!0;if(l){if(void 0!==e.requiredVersion){let t=e.requiredVersion;const n=i,s=i;let a=!1;const p=i;if(!1!==t){const r={params:{}};null===o?o=[r]:o.push(r),i++}var f=p===i;if(a=a||f,!a){const r=i;if("string"!=typeof t){const r={params:{type:"string"}};null===o?o=[r]:o.push(r),i++}f=r===i,a=a||f}if(!a){const e={params:{}};return null===o?o=[e]:o.push(e),i++,r.errors=o,!1}i=s,null!==o&&(s?o.length=s:o=null),l=n===i}else l=!0;if(l){if(void 0!==e.shareKey){let t=e.shareKey;const n=i;if(i===n){if("string"!=typeof t)return r.errors=[{params:{type:"string"}}],!1;if(t.length<1)return r.errors=[{params:{}}],!1}l=n===i}else l=!0;if(l){if(void 0!==e.shareScope){let t=e.shareScope;const n=i;if(i===n){if("string"!=typeof t)return r.errors=[{params:{type:"string"}}],!1;if(t.length<1)return r.errors=[{params:{}}],!1}l=n===i}else l=!0;if(l){if(void 0!==e.singleton){const t=i;if("boolean"!=typeof e.singleton)return r.errors=[{params:{type:"boolean"}}],!1;l=t===i}else l=!0;if(l)if(void 0!==e.strictVersion){const t=i;if("boolean"!=typeof e.strictVersion)return r.errors=[{params:{type:"boolean"}}],!1;l=t===i}else l=!0}}}}}}}}}return r.errors=o,0===i}function e(t,{instancePath:n="",parentData:s,parentDataProperty:a,rootData:o=t}={}){let i=null,l=0;if(0===l){if(!t||"object"!=typeof t||Array.isArray(t))return e.errors=[{params:{type:"object"}}],!1;for(const s in t){let a=t[s];const f=l,c=l;let u=!1;const y=l;r(a,{instancePath:n+"/"+s.replace(/~/g,"~0").replace(/\//g,"~1"),parentData:t,parentDataProperty:s,rootData:o})||(i=null===i?r.errors:i.concat(r.errors),l=i.length);var p=y===l;if(u=u||p,!u){const r=l;if(l==l)if("string"==typeof a){if(a.length<1){const r={params:{}};null===i?i=[r]:i.push(r),l++}}else{const r={params:{type:"string"}};null===i?i=[r]:i.push(r),l++}p=r===l,u=u||p}if(!u){const r={params:{}};return null===i?i=[r]:i.push(r),l++,e.errors=i,!1}if(l=c,null!==i&&(c?i.length=c:i=null),f!==l)break}}return e.errors=i,0===l}function t(r,{instancePath:n="",parentData:s,parentDataProperty:a,rootData:o=r}={}){let i=null,l=0;const p=l;let f=!1;const c=l;if(l===c)if(Array.isArray(r)){const t=r.length;for(let s=0;s boolean; +export = check; diff --git a/schemas/plugins/sharing/ProvideSharedPlugin.check.js b/schemas/plugins/sharing/ProvideSharedPlugin.check.js new file mode 100644 index 00000000000..920f0e2b0cf --- /dev/null +++ b/schemas/plugins/sharing/ProvideSharedPlugin.check.js @@ -0,0 +1,6 @@ +/* + * This file was automatically generated. + * DO NOT MODIFY BY HAND. + * Run `yarn special-lint-fix` to update + */ +"use strict";function r(t,{instancePath:e="",parentData:s,parentDataProperty:n,rootData:a=t}={}){let o=null,l=0;if(0===l){if(!t||"object"!=typeof t||Array.isArray(t))return r.errors=[{params:{type:"object"}}],!1;for(const e in t){let s=t[e];const n=l,a=l;let f=!1;const u=l;if(l==l)if(s&&"object"==typeof s&&!Array.isArray(s)){const r=l;for(const r in s)if("eager"!==r&&"shareKey"!==r&&"shareScope"!==r&&"version"!==r){const t={params:{additionalProperty:r}};null===o?o=[t]:o.push(t),l++;break}if(r===l){if(void 0!==s.eager){const r=l;if("boolean"!=typeof s.eager){const r={params:{type:"boolean"}};null===o?o=[r]:o.push(r),l++}var i=r===l}else i=!0;if(i){if(void 0!==s.shareKey){let r=s.shareKey;const t=l;if(l===t)if("string"==typeof r){if(r.length<1){const r={params:{}};null===o?o=[r]:o.push(r),l++}}else{const r={params:{type:"string"}};null===o?o=[r]:o.push(r),l++}i=t===l}else i=!0;if(i){if(void 0!==s.shareScope){let r=s.shareScope;const t=l;if(l===t)if("string"==typeof r){if(r.length<1){const r={params:{}};null===o?o=[r]:o.push(r),l++}}else{const r={params:{type:"string"}};null===o?o=[r]:o.push(r),l++}i=t===l}else i=!0;if(i)if(void 0!==s.version){let r=s.version;const t=l,e=l;let n=!1;const a=l;if(!1!==r){const r={params:{}};null===o?o=[r]:o.push(r),l++}var p=a===l;if(n=n||p,!n){const t=l;if("string"!=typeof r){const r={params:{type:"string"}};null===o?o=[r]:o.push(r),l++}p=t===l,n=n||p}if(n)l=e,null!==o&&(e?o.length=e:o=null);else{const r={params:{}};null===o?o=[r]:o.push(r),l++}i=t===l}else i=!0}}}}else{const r={params:{type:"object"}};null===o?o=[r]:o.push(r),l++}var c=u===l;if(f=f||c,!f){const r=l;if(l==l)if("string"==typeof s){if(s.length<1){const r={params:{}};null===o?o=[r]:o.push(r),l++}}else{const r={params:{type:"string"}};null===o?o=[r]:o.push(r),l++}c=r===l,f=f||c}if(!f){const t={params:{}};return null===o?o=[t]:o.push(t),l++,r.errors=o,!1}if(l=a,null!==o&&(a?o.length=a:o=null),n!==l)break}}return r.errors=o,0===l}function t(e,{instancePath:s="",parentData:n,parentDataProperty:a,rootData:o=e}={}){let l=null,i=0;const p=i;let c=!1;const f=i;if(i===f)if(Array.isArray(e)){const t=e.length;for(let n=0;n boolean; +export = check; diff --git a/schemas/plugins/sharing/SharePlugin.check.js b/schemas/plugins/sharing/SharePlugin.check.js new file mode 100644 index 00000000000..48fea9c81bf --- /dev/null +++ b/schemas/plugins/sharing/SharePlugin.check.js @@ -0,0 +1,6 @@ +/* + * This file was automatically generated. + * DO NOT MODIFY BY HAND. + * Run `yarn special-lint-fix` to update + */ +"use strict";module.exports=a,module.exports.default=a;const r={type:"object",additionalProperties:!1,properties:{eager:{type:"boolean"},import:{anyOf:[{enum:[!1]},{$ref:"#/definitions/SharedItem"}]},packageName:{type:"string",minLength:1},requiredVersion:{anyOf:[{enum:[!1]},{type:"string"}]},shareKey:{type:"string",minLength:1},shareScope:{type:"string",minLength:1},singleton:{type:"boolean"},strictVersion:{type:"boolean"},version:{anyOf:[{enum:[!1]},{type:"string"}]}}},e=Object.prototype.hasOwnProperty;function t(n,{instancePath:s="",parentData:a,parentDataProperty:o,rootData:i=n}={}){let l=null,p=0;if(0===p){if(!n||"object"!=typeof n||Array.isArray(n))return t.errors=[{params:{type:"object"}}],!1;{const s=p;for(const s in n)if(!e.call(r.properties,s))return t.errors=[{params:{additionalProperty:s}}],!1;if(s===p){if(void 0!==n.eager){const r=p;if("boolean"!=typeof n.eager)return t.errors=[{params:{type:"boolean"}}],!1;var f=r===p}else f=!0;if(f){if(void 0!==n.import){let r=n.import;const e=p,s=p;let a=!1;const o=p;if(!1!==r){const r={params:{}};null===l?l=[r]:l.push(r),p++}var u=o===p;if(a=a||u,!a){const e=p;if(p==p)if("string"==typeof r){if(r.length<1){const r={params:{}};null===l?l=[r]:l.push(r),p++}}else{const r={params:{type:"string"}};null===l?l=[r]:l.push(r),p++}u=e===p,a=a||u}if(!a){const r={params:{}};return null===l?l=[r]:l.push(r),p++,t.errors=l,!1}p=s,null!==l&&(s?l.length=s:l=null),f=e===p}else f=!0;if(f){if(void 0!==n.packageName){let r=n.packageName;const e=p;if(p===e){if("string"!=typeof r)return t.errors=[{params:{type:"string"}}],!1;if(r.length<1)return t.errors=[{params:{}}],!1}f=e===p}else f=!0;if(f){if(void 0!==n.requiredVersion){let r=n.requiredVersion;const e=p,s=p;let a=!1;const o=p;if(!1!==r){const r={params:{}};null===l?l=[r]:l.push(r),p++}var c=o===p;if(a=a||c,!a){const e=p;if("string"!=typeof r){const r={params:{type:"string"}};null===l?l=[r]:l.push(r),p++}c=e===p,a=a||c}if(!a){const r={params:{}};return null===l?l=[r]:l.push(r),p++,t.errors=l,!1}p=s,null!==l&&(s?l.length=s:l=null),f=e===p}else f=!0;if(f){if(void 0!==n.shareKey){let r=n.shareKey;const e=p;if(p===e){if("string"!=typeof r)return t.errors=[{params:{type:"string"}}],!1;if(r.length<1)return t.errors=[{params:{}}],!1}f=e===p}else f=!0;if(f){if(void 0!==n.shareScope){let r=n.shareScope;const e=p;if(p===e){if("string"!=typeof r)return t.errors=[{params:{type:"string"}}],!1;if(r.length<1)return t.errors=[{params:{}}],!1}f=e===p}else f=!0;if(f){if(void 0!==n.singleton){const r=p;if("boolean"!=typeof n.singleton)return t.errors=[{params:{type:"boolean"}}],!1;f=r===p}else f=!0;if(f){if(void 0!==n.strictVersion){const r=p;if("boolean"!=typeof n.strictVersion)return t.errors=[{params:{type:"boolean"}}],!1;f=r===p}else f=!0;if(f)if(void 0!==n.version){let r=n.version;const e=p,s=p;let a=!1;const o=p;if(!1!==r){const r={params:{}};null===l?l=[r]:l.push(r),p++}var y=o===p;if(a=a||y,!a){const e=p;if("string"!=typeof r){const r={params:{type:"string"}};null===l?l=[r]:l.push(r),p++}y=e===p,a=a||y}if(!a){const r={params:{}};return null===l?l=[r]:l.push(r),p++,t.errors=l,!1}p=s,null!==l&&(s?l.length=s:l=null),f=e===p}else f=!0}}}}}}}}}}return t.errors=l,0===p}function n(r,{instancePath:e="",parentData:s,parentDataProperty:a,rootData:o=r}={}){let i=null,l=0;if(0===l){if(!r||"object"!=typeof r||Array.isArray(r))return n.errors=[{params:{type:"object"}}],!1;for(const s in r){let a=r[s];const f=l,u=l;let c=!1;const y=l;t(a,{instancePath:e+"/"+s.replace(/~/g,"~0").replace(/\//g,"~1"),parentData:r,parentDataProperty:s,rootData:o})||(i=null===i?t.errors:i.concat(t.errors),l=i.length);var p=y===l;if(c=c||p,!c){const r=l;if(l==l)if("string"==typeof a){if(a.length<1){const r={params:{}};null===i?i=[r]:i.push(r),l++}}else{const r={params:{type:"string"}};null===i?i=[r]:i.push(r),l++}p=r===l,c=c||p}if(!c){const r={params:{}};return null===i?i=[r]:i.push(r),l++,n.errors=i,!1}if(l=u,null!==i&&(u?i.length=u:i=null),f!==l)break}}return n.errors=i,0===l}function s(r,{instancePath:e="",parentData:t,parentDataProperty:a,rootData:o=r}={}){let i=null,l=0;const p=l;let f=!1;const u=l;if(l===u)if(Array.isArray(r)){const t=r.length;for(let s=0;s { process.exitCode = 0; }) - .catch(e => { - console.error(e); + .catch(err => { + console.error(err); process.exitCode = 1; }); } @@ -36,7 +36,7 @@ async function runSetupSymlinkAsync() { function checkSymlinkExistsAsync() { return new Promise((resolve, reject) => { if ( - fs.existsSync(node_modulesFolder) && + fs.existsSync(nodeModulesFolder) && fs.existsSync(webpackDependencyFolder) && fs.lstatSync(webpackDependencyFolder).isSymbolicLink() ) { @@ -48,12 +48,13 @@ function checkSymlinkExistsAsync() { } async function ensureYarnInstalledAsync() { - const semverPattern = /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(-(0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(\.(0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*)?(\+[0-9a-zA-Z-]+(\.[0-9a-zA-Z-]+)*)?$/; + const semverPattern = + /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(-(0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(\.(0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*)?(\+[0-9a-zA-Z-]+(\.[0-9a-zA-Z-]+)*)?$/; let hasYarn = false; try { const stdout = await execGetOutput("yarn", ["-v"], "Check yarn version"); hasYarn = semverPattern.test(stdout); - } catch (e) { + } catch (_err) { hasYarn = false; } if (!hasYarn) await installYarnAsync(); @@ -66,7 +67,7 @@ function installYarnAsync() { function exec(command, args, description) { console.log(`Setup: ${description}`); return new Promise((resolve, reject) => { - let cp = require("child_process").spawn(command, args, { + const cp = require("child_process").spawn(command, args, { cwd: root, stdio: "inherit", shell: true @@ -87,7 +88,7 @@ function exec(command, args, description) { function execGetOutput(command, args, description) { console.log(`Setup: ${description}`); return new Promise((resolve, reject) => { - let cp = require("child_process").spawn(command, args, { + const cp = require("child_process").spawn(command, args, { cwd: root, stdio: [process.stdin, "pipe", process.stderr], shell: true diff --git a/test/ArrayHelpers.unittest.js b/test/ArrayHelpers.unittest.js new file mode 100644 index 00000000000..911174dd2fa --- /dev/null +++ b/test/ArrayHelpers.unittest.js @@ -0,0 +1,17 @@ +"use strict"; + +const ArrayHelpers = require("../lib/util/ArrayHelpers"); + +describe("ArrayHelpers", () => { + it("groupBy should partition into two arrays", () => { + expect( + ArrayHelpers.groupBy([1, 2, 3, 4, 5, 6], x => x % 2 === 0) + ).toStrictEqual([ + [2, 4, 6], + [1, 3, 5] + ]); + }); + it("groupBy works with empty array", () => { + expect(ArrayHelpers.groupBy([], x => x % 2 === 0)).toStrictEqual([[], []]); + }); +}); diff --git a/test/BannerPlugin.test.js b/test/BannerPlugin.test.js new file mode 100644 index 00000000000..335d6b006ad --- /dev/null +++ b/test/BannerPlugin.test.js @@ -0,0 +1,116 @@ +"use strict"; + +const path = require("path"); +const fs = require("graceful-fs"); + +const webpack = require(".."); + +const pluginDir = path.join(__dirname, "js", "BannerPlugin"); +const outputDir = path.join(pluginDir, "output"); + +it("should cache assets", done => { + const entry1File = path.join(pluginDir, "entry1.js"); + const entry2File = path.join(pluginDir, "entry2.js"); + const outputFile = path.join(outputDir, "entry1.js"); + try { + fs.mkdirSync(path.join(pluginDir), { + recursive: true + }); + } catch (_err) { + // empty + } + const compiler = webpack({ + mode: "development", + entry: { + entry1: entry1File, + entry2: entry2File + }, + output: { + path: outputDir + }, + plugins: [new webpack.BannerPlugin("banner is a string")] + }); + fs.writeFileSync(entry1File, "1", "utf-8"); + fs.writeFileSync(entry2File, "1", "utf-8"); + compiler.run(err => { + if (err) return done(err); + const footerFileResults = fs.readFileSync(outputFile, "utf8").split("\n"); + expect(footerFileResults[0]).toBe("/*! banner is a string */"); + fs.writeFileSync(entry2File, "2", "utf-8"); + compiler.run((err, stats) => { + const { assets } = stats.toJson(); + expect(assets.find(as => as.name === "entry1.js").emitted).toBe(false); + expect(assets.find(as => as.name === "entry2.js").emitted).toBe(true); + done(err); + }); + }); +}); + +it("can place banner as footer", done => { + const footerFile = path.join(pluginDir, "footerFile.js"); + const outputFile = path.join(outputDir, "footerFile.js"); + try { + fs.mkdirSync(path.join(pluginDir), { + recursive: true + }); + } catch (_err) { + // empty + } + const compiler = webpack({ + mode: "development", + entry: { + footerFile: footerFile + }, + output: { + path: outputDir + }, + plugins: [ + new webpack.BannerPlugin({ + banner: "banner is a string", + footer: true + }) + ] + }); + fs.writeFileSync(footerFile, "footer", "utf-8"); + compiler.run(err => { + if (err) return done(err); + const footerFileResults = fs.readFileSync(outputFile, "utf8").split("\n"); + expect(footerFileResults.pop()).toBe("/*! banner is a string */"); + done(); + }); +}); + +it("should allow to change stage", done => { + const entryFile = path.join(pluginDir, "entry3.js"); + const outputFile = path.join(outputDir, "entry3.js"); + try { + fs.mkdirSync(path.join(pluginDir), { + recursive: true + }); + } catch (_err) { + // empty + } + const compiler = webpack({ + mode: "production", + entry: { + entry3: entryFile + }, + output: { + path: outputDir + }, + plugins: [ + new webpack.BannerPlugin({ + raw: true, + banner: "/* banner is a string */", + stage: webpack.Compilation.PROCESS_ASSETS_STAGE_REPORT + }) + ] + }); + fs.writeFileSync(entryFile, "console.log(1 + 1);", "utf-8"); + compiler.run(err => { + if (err) return done(err); + const fileResult = fs.readFileSync(outputFile, "utf8").split("\n"); + expect(fileResult[0]).toBe("/* banner is a string */"); + done(); + }); +}); diff --git a/test/BenchmarkTestCases.benchmark.js b/test/BenchmarkTestCases.benchmark.js index 716bdf829da..c1b24e71f6e 100644 --- a/test/BenchmarkTestCases.benchmark.js +++ b/test/BenchmarkTestCases.benchmark.js @@ -10,7 +10,7 @@ describe("BenchmarkTestCases", function () { const casesPath = path.join(__dirname, "benchmarkCases"); const tests = fs.readdirSync(casesPath).filter(function (folder) { return ( - folder.indexOf("_") < 0 && + !folder.includes("_") && fs.existsSync(path.resolve(casesPath, folder, "webpack.config.js")) ); }); @@ -20,10 +20,10 @@ describe("BenchmarkTestCases", function () { try { fs.mkdirSync(path.join(__dirname, "js")); - } catch (e) {} // eslint-disable-line no-empty + } catch (_err) {} // eslint-disable-line no-empty try { fs.mkdirSync(baselinesPath); - } catch (e) {} // eslint-disable-line no-empty + } catch (_err) {} // eslint-disable-line no-empty beforeAll(function (done) { const git = require("simple-git"); @@ -40,7 +40,7 @@ describe("BenchmarkTestCases", function () { } else { try { fs.mkdirSync(baselinePath); - } catch (e) {} // eslint-disable-line no-empty + } catch (_err) {} // eslint-disable-line no-empty const gitIndex = path.resolve(rootPath, ".git/index"); const index = fs.readFileSync(gitIndex); git(rootPath).raw( @@ -105,7 +105,7 @@ describe("BenchmarkTestCases", function () { function getBaselineRevs(rootPath, callback) { const git = require("simple-git")(rootPath); - const lastVersionTag = "v" + require("../package.json").version; + const lastVersionTag = `v${require("../package.json").version}`; git.raw(["rev-list", "-n", "1", lastVersionTag], (err, resultVersion) => { if (err) return callback(err); const matchVersion = /^([a-f0-9]+)\s*$/.exec(resultVersion); @@ -157,9 +157,8 @@ describe("BenchmarkTestCases", function () { } ].filter(Boolean) ); - } else { - return callback(new Error("No baseline found")); } + return callback(new Error("No baseline found")); } ); }); @@ -171,59 +170,23 @@ describe("BenchmarkTestCases", function () { if (n <= 30) { // 1 2 ... const data = [ - 6.314, - 2.92, - 2.353, - 2.132, - 2.015, - 1.943, - 1.895, - 1.86, - 1.833, - 1.812, - 1.796, - 1.782, - 1.771, - 1.761, - 1.753, - 1.746, - 1.74, - 1.734, - 1.729, - 1.725, - 1.721, - 1.717, - 1.714, - 1.711, - 1.708, - 1.706, - 1.703, - 1.701, - 1.699, - 1.697 + 6.314, 2.92, 2.353, 2.132, 2.015, 1.943, 1.895, 1.86, 1.833, 1.812, + 1.796, 1.782, 1.771, 1.761, 1.753, 1.746, 1.74, 1.734, 1.729, 1.725, + 1.721, 1.717, 1.714, 1.711, 1.708, 1.706, 1.703, 1.701, 1.699, 1.697 ]; return data[n - 1]; } else if (n <= 120) { // 30 40 50 60 70 80 90 100 110 120 const data = [ - 1.697, - 1.684, - 1.676, - 1.671, - 1.667, - 1.664, - 1.662, - 1.66, - 1.659, - 1.658 + 1.697, 1.684, 1.676, 1.671, 1.667, 1.664, 1.662, 1.66, 1.659, 1.658 ]; var a = data[Math.floor(n / 10) - 3]; var b = data[Math.ceil(n / 10) - 3]; var f = n / 10 - Math.floor(n / 10); return a * (1 - f) + b * f; - } else { - return 1.645; } + + return 1.645; } function runBenchmark(webpack, config, callback) { @@ -273,12 +236,13 @@ describe("BenchmarkTestCases", function () { } function createTests() { - tests.forEach(testName => { + for (const testName of tests) { const testDirectory = path.join(casesPath, testName); let headStats = null; describe(`${testName} create benchmarks`, function () { - baselines.forEach(baseline => { + for (const baseline of baselines) { let baselineStats = null; + // eslint-disable-next-line no-loop-func it(`should benchmark ${baseline.name} (${baseline.rev})`, function (done) { const outputDirectory = path.join( __dirname, @@ -304,7 +268,7 @@ describe("BenchmarkTestCases", function () { done(); }); }, 180000); - + // eslint-disable-next-line no-loop-func it(`should benchmark ${baseline.name} (${baseline.rev})`, done => { const outputDirectory = path.join( __dirname, @@ -330,6 +294,7 @@ describe("BenchmarkTestCases", function () { }, 180000); if (baseline.name !== "HEAD") { + // eslint-disable-next-line no-loop-func it(`HEAD should not be slower than ${baseline.name} (${baseline.rev})`, function () { if (baselineStats.maxConfidence < headStats.minConfidence) { throw new Error( @@ -346,8 +311,8 @@ describe("BenchmarkTestCases", function () { } }); } - }); + } }); - }); + } } }); diff --git a/test/BinaryMiddleware.unittest.js b/test/BinaryMiddleware.unittest.js index c395013b35d..e22ed0eafdf 100644 --- a/test/BinaryMiddleware.unittest.js +++ b/test/BinaryMiddleware.unittest.js @@ -108,14 +108,14 @@ describe("BinaryMiddleware", () => { for (const prepend of items) { for (const append of items) { if (c > 1 && append !== undefined) continue; - let data = [prepend, ...caseData, append].filter( + const data = [prepend, ...caseData, append].filter( x => x !== undefined ); if (data.length * c > 200000) continue; if (data.length === 0) continue; let key = JSON.stringify(data.map(resolveLazy)); if (key.length > 100) - key = key.slice(0, 50) + " ... " + key.slice(-50); + key = `${key.slice(0, 50)} ... ${key.slice(-50)}`; it(`should serialize ${c} x ${key} (${data.length}) correctly`, () => { // process.stderr.write( // `${c} x ${key.slice(0, 20)} (${data.length})\n` diff --git a/test/BuildDependencies.test.js b/test/BuildDependencies.longtest.js similarity index 65% rename from test/BuildDependencies.test.js rename to test/BuildDependencies.longtest.js index c64016c4520..d222e41b366 100644 --- a/test/BuildDependencies.test.js +++ b/test/BuildDependencies.longtest.js @@ -9,31 +9,92 @@ const cacheDirectory = path.resolve(__dirname, "js/buildDepsCache"); const outputDirectory = path.resolve(__dirname, "js/buildDeps"); const inputDirectory = path.resolve(__dirname, "js/buildDepsInput"); -const exec = (n, options = {}) => { - return new Promise((resolve, reject) => { - const p = child_process.fork( - path.resolve(__dirname, "fixtures/buildDependencies/run.js"), - [n, JSON.stringify(options)], - { stdio: ["ignore", "pipe", "pipe", "ipc"] } +const exec = (n, options = {}) => + new Promise((resolve, reject) => { + const webpack = require("../"); + const coverageEnabled = webpack.toString().includes("++"); + + const p = child_process.execFile( + process.execPath, + [ + ...(coverageEnabled + ? [ + require.resolve("nyc/bin/nyc.js"), + "--silent", + "--no-clean", + "--cache-dir", + ".jest-cache/nyc", + process.execPath + ] + : []), + path.resolve(__dirname, "fixtures/buildDependencies/run.js"), + n, + JSON.stringify(options) + ], + { + stdio: ["ignore", "pipe", "pipe"] + } ); const chunks = []; p.stderr.on("data", chunk => chunks.push(chunk)); p.stdout.on("data", chunk => chunks.push(chunk)); p.once("exit", code => { - const stdout = Buffer.concat(chunks).toString("utf-8"); + const errors = []; + const warnings = []; + const rawStdout = chunks.join(""); + const stdout = rawStdout.replace( + // This warning is expected + /<([ew])> \[.+\n(?:<([ew])> [^[].+\n)*/g, + (message, type) => { + (type === "e" ? errors : warnings).push(message); + return ""; + } + ); + if (errors.length > 0) { + return reject( + new Error( + `Unexpected errors in ${n} output:\n${errors.join( + "\n" + )}\n\n${rawStdout}` + ) + ); + } + for (const regexp of options.warnings || []) { + const idx = warnings.findIndex(w => regexp.test(w)); + if (idx < 0) { + return reject( + new Error( + `Warning ${regexp} was not found in ${n} output:\n${rawStdout}` + ) + ); + } + warnings.splice(idx, 1); + } + if (warnings.length > 0) { + return reject( + new Error( + `Unexpected warnings in ${n} output:\n${warnings.join( + "\n" + )}\n\n${rawStdout}` + ) + ); + } if (code === 0) { if (!options.ignoreErrors && /<[ew]>/.test(stdout)) - return reject(stdout); + return reject(new Error(stdout)); resolve(stdout); } else { reject(new Error(`Code ${code}: ${stdout}`)); } }); - p.once("error", err => reject(err)); + p.once("error", err => { + const stdout = chunks.join(""); + console.log(stdout); + reject(err); + }); }); -}; -const supportsEsm = +process.versions.modules >= 83; +const supportsEsm = Number(process.versions.modules) >= 83; describe("BuildDependencies", () => { beforeEach(done => { @@ -71,12 +132,23 @@ describe("BuildDependencies", () => { ); fs.writeFileSync( path.resolve(inputDirectory, "esm-async-dependency.mjs"), - "export default 0;" + `import path from "node:path"; +import vm from "vm"; + +async function preload() { + await import(\`markdown-wasm/dist/markdown-node.js\`); + await import("markdown-wasm/dist/markdown-node.js"); + await import('markdown-wasm/dist/markdown-node.js'); + await import('test-"/test'); + await import(\`test-"/test\`); +} + +export default 0;` ); await exec("0", { - invalidBuildDepdencies: true, + invalidBuildDependencies: true, buildTwice: true, - ignoreErrors: true + warnings: [/Can't resolve 'should-fail-resolving'/] }); fs.writeFileSync( path.resolve(inputDirectory, "loader-dependency.js"), @@ -90,19 +162,31 @@ describe("BuildDependencies", () => { path.resolve(inputDirectory, "esm-dependency.js"), "module.exports = 1;" ); - await exec("1"); + await exec("1", { + warnings: supportsEsm && [ + /Managed item .+dep-without-package\.json isn't a directory or doesn't contain a package\.json/ + ] + }); fs.writeFileSync( path.resolve(inputDirectory, "loader-dependency.js"), "module.exports = Date.now();" ); const now1 = Date.now(); - const output2 = await exec("2"); + const output2 = await exec("2", { + warnings: supportsEsm && [ + /Managed item .+dep-without-package\.json isn't a directory or doesn't contain a package\.json/ + ] + }); expect(output2).toMatch(/but build dependencies have changed/); expect(output2).toMatch(/Captured build dependencies/); + expect(output2).not.toMatch(/Assuming/); + expect(output2).not.toMatch(//); const output3 = await exec("3"); expect(output3).not.toMatch(/resolving of build dependencies is invalid/); expect(output3).not.toMatch(/but build dependencies have changed/); expect(output3).not.toMatch(/Captured build dependencies/); + expect(output3).not.toMatch(/Assuming/); + expect(output3).not.toMatch(//); fs.writeFileSync( path.resolve(inputDirectory, "package.json"), JSON.stringify({ @@ -110,7 +194,11 @@ describe("BuildDependencies", () => { version: "2.0.0" }) ); - const output4 = await exec("4"); + const output4 = await exec("4", { + warnings: supportsEsm && [ + /Managed item .+dep-without-package\.json isn't a directory or doesn't contain a package\.json/ + ] + }); expect(output4).toMatch(/resolving of build dependencies is invalid/); expect(output4).not.toMatch(/but build dependencies have changed/); expect(output4).toMatch(/Captured build dependencies/); @@ -119,13 +207,18 @@ describe("BuildDependencies", () => { "module.exports = Date.now();" ); const now2 = Date.now(); - await exec("5"); + await exec("5", { + warnings: supportsEsm && [ + /Managed item .+dep-without-package\.json isn't a directory or doesn't contain a package\.json/ + ] + }); const now3 = Date.now(); await exec("6"); await exec("7", { definedValue: "other" }); - let now4, now5; + let now4; + let now5; if (supportsEsm) { fs.writeFileSync( path.resolve(inputDirectory, "esm-dependency.js"), @@ -133,7 +226,10 @@ describe("BuildDependencies", () => { ); now4 = Date.now(); await exec("8", { - definedValue: "other" + definedValue: "other", + warnings: [ + /Managed item .+dep-without-package\.json isn't a directory or doesn't contain a package\.json/ + ] }); fs.writeFileSync( path.resolve(inputDirectory, "esm-async-dependency.mjs"), @@ -142,7 +238,10 @@ describe("BuildDependencies", () => { now5 = Date.now(); await exec("9", { - definedValue: "other" + definedValue: "other", + warnings: [ + /Managed item .+dep-without-package\.json isn't a directory or doesn't contain a package\.json/ + ] }); } const results = Array.from({ length: supportsEsm ? 10 : 8 }).map((_, i) => @@ -218,5 +317,5 @@ describe("BuildDependencies", () => { expect(result.esmAsyncConfig).toBeGreaterThan(now5); expect(result.uncached).toBeGreaterThan(now5); } - }, 100000); + }, 500000); }); diff --git a/test/ChangesAndRemovals.test.js b/test/ChangesAndRemovals.test.js index fbd182064b2..be8762f5ce1 100644 --- a/test/ChangesAndRemovals.test.js +++ b/test/ChangesAndRemovals.test.js @@ -1,12 +1,14 @@ "use strict"; +require("./helpers/warmup-webpack"); + const path = require("path"); const { createFsFromVolume, Volume } = require("memfs"); -const webpack = require(".."); const fs = require("graceful-fs"); const rimraf = require("rimraf"); const createCompiler = config => { + const webpack = require(".."); const compiler = webpack(config); compiler.outputFileSystem = createFsFromVolume(new Volume()); return compiler; @@ -16,15 +18,14 @@ const tempFolderPath = path.join(__dirname, "ChangesAndRemovalsTemp"); const tempFilePath = path.join(tempFolderPath, "temp-file.js"); const tempFile2Path = path.join(tempFolderPath, "temp-file2.js"); -const createSingleCompiler = () => { - return createCompiler({ +const createSingleCompiler = () => + createCompiler({ entry: tempFilePath, output: { path: tempFolderPath, filename: "bundle.js" } }); -}; const onceDone = (compiler, action) => { let initial = true; @@ -66,6 +67,7 @@ function createFiles() { describe("ChangesAndRemovals", () => { if (process.env.NO_WATCH_TESTS) { + // eslint-disable-next-line jest/no-disabled-tests it.skip("watch tests excluded", () => {}); return; } @@ -85,7 +87,6 @@ describe("ChangesAndRemovals", () => { it("should not track modified/removed files during initial watchRun", done => { const compiler = createSingleCompiler(); - let watcher; const watchRunFinished = new Promise(resolve => { compiler.hooks.watchRun.tap("ChangesAndRemovalsTest", compiler => { expect(getChanges(compiler)).toEqual({ @@ -95,7 +96,7 @@ describe("ChangesAndRemovals", () => { resolve(); }); }); - watcher = compiler.watch({ aggregateTimeout: 200 }, err => { + const watcher = compiler.watch({ aggregateTimeout: 200 }, err => { if (err) done(err); }); diff --git a/test/Cli.test.js b/test/Cli.basictest.js similarity index 86% rename from test/Cli.test.js rename to test/Cli.basictest.js index 7a82fd1bc76..c1a7ad40f7c 100644 --- a/test/Cli.test.js +++ b/test/Cli.basictest.js @@ -5,6 +5,50 @@ describe("Cli", () => { expect(getArguments()).toMatchSnapshot(); }); + it("should generate the correct cli flags with custom schema", () => { + const schema = { + title: "custom CLI options", + type: "object", + additionalProperties: false, + properties: { + "with-reset-description": { + type: "array", + items: { + type: "string" + }, + description: "original description", + cli: { + resetDescription: "custom reset" + } + }, + "with-cli-description": { + type: "string", + description: "original description", + cli: { + description: "description for CLI option" + } + }, + "with-negative-description": { + type: "boolean", + description: "original description", + cli: { + negatedDescription: "custom negative description" + } + }, + "with-both-cli-and-negative-description": { + type: "boolean", + description: "original description", + cli: { + description: "description for CLI option", + negatedDescription: "custom negative description" + } + } + } + }; + + expect(getArguments(schema)).toMatchSnapshot(); + }); + const test = (name, values, config, fn) => { it(`should correctly process arguments for ${name}`, () => { const args = getArguments(); @@ -13,7 +57,7 @@ describe("Cli", () => { }); }; - test("none", {}, {}, e => e.toMatchInlineSnapshot(`Object {}`)); + test("none", {}, {}, e => e.toMatchInlineSnapshot("Object {}")); test("root boolean", { bail: true }, {}, e => e.toMatchInlineSnapshot(` @@ -264,6 +308,7 @@ describe("Cli", () => { `) ); + // cspell:ignore filsystem test( "errors", { diff --git a/test/Compiler-caching.test.js b/test/Compiler-caching.test.js index f4a6f9a9f77..9cad001327f 100644 --- a/test/Compiler-caching.test.js +++ b/test/Compiler-caching.test.js @@ -1,16 +1,18 @@ "use strict"; +require("./helpers/warmup-webpack"); + const path = require("path"); const fs = require("graceful-fs"); const rimraf = require("rimraf"); -const webpack = require(".."); let fixtureCount = 0; describe("Compiler (caching)", () => { jest.setTimeout(15000); function compile(entry, options, callback) { + const webpack = require(".."); options = webpack.config.getNormalizedWebpackOptions(options); options.mode = "none"; options.cache = true; @@ -68,11 +70,9 @@ describe("Compiler (caching)", () => { expect(Array.isArray(stats.errors)).toBe(true); if (options.expectErrors) { expect(stats.errors).toHaveLength(options.expectErrors); - } else { - if (stats.errors.length > 0) { - expect(typeof stats.errors[0]).toBe("string"); - throw new Error(stats.errors[0]); - } + } else if (stats.errors.length > 0) { + expect(typeof stats.errors[0]).toBe("string"); + throw new Error(stats.errors[0]); } stats.logs = logs; callback(stats, files, compilerIteration++); @@ -121,7 +121,7 @@ describe("Compiler (caching)", () => { }; } - it("should cache single file (with manual 1s wait) ", done => { + it("should cache single file (with manual 1s wait)", done => { const options = {}; const tempFixture = createTempFixture(); @@ -155,7 +155,7 @@ describe("Compiler (caching)", () => { }); }); - it("should cache single file (even with no timeout) ", done => { + it("should cache single file (even with no timeout)", done => { const options = {}; const tempFixture = createTempFixture(); diff --git a/test/Compiler-filesystem-caching.test.js b/test/Compiler-filesystem-caching.test.js new file mode 100644 index 00000000000..58ebeae3297 --- /dev/null +++ b/test/Compiler-filesystem-caching.test.js @@ -0,0 +1,250 @@ +"use strict"; + +require("./helpers/warmup-webpack"); + +const path = require("path"); +const fs = require("graceful-fs"); +const rimraf = require("rimraf"); + +let fixtureCount = 0; + +describe("Compiler (filesystem caching)", () => { + jest.setTimeout(5000); + + const tempFixturePath = path.join( + __dirname, + "fixtures", + "temp-filesystem-cache-fixture" + ); + + function compile(entry, onSuccess, onError) { + const webpack = require(".."); + const options = webpack.config.getNormalizedWebpackOptions({}); + options.cache = { + type: "filesystem", + cacheDirectory: path.join(tempFixturePath, "cache") + }; + options.entry = entry; + options.context = path.join(__dirname, "fixtures"); + options.output.path = path.join(tempFixturePath, "dist"); + options.output.filename = "bundle.js"; + options.output.pathinfo = true; + options.module = { + rules: [ + { + test: /\.svg$/, + type: "asset/resource", + use: { + loader: require.resolve("./fixtures/empty-svg-loader") + } + } + ] + }; + + const isBigIntSupported = typeof BigInt !== "undefined"; + const isErrorCaseSupported = + // eslint-disable-next-line n/no-unsupported-features/es-syntax + typeof new Error("test", { cause: new Error("cause") }).cause !== + "undefined"; + + options.plugins = [ + { + apply(compiler) { + const name = "TestCachePlugin"; + + compiler.hooks.thisCompilation.tap(name, compilation => { + compilation.hooks.processAssets.tapPromise( + { + name, + stage: + compiler.webpack.Compilation + .PROCESS_ASSETS_STAGE_OPTIMIZE_SIZE + }, + async () => { + const cache = compilation.getCache(name); + const ident = "test.ext"; + const cacheItem = cache.getItemCache(ident, null); + + const result = await cacheItem.getPromise(ident); + + if (result) { + expect(result.number).toEqual(42); + expect(result.number1).toEqual(3.14); + expect(result.number2).toEqual(6.2); + expect(result.string).toEqual("string"); + + if (isErrorCaseSupported) { + expect(result.error.cause.message).toEqual("cause"); + expect(result.error1.cause.string).toBe("string"); + expect(result.error1.cause.number).toBe(42); + } + + if (isBigIntSupported) { + expect(result.bigint).toEqual(5n); + expect(result.bigint1).toEqual(124n); + expect(result.bigint2).toEqual(125n); + expect(result.bigint3).toEqual(12345678901234567890n); + expect(result.bigint4).toEqual(5n); + expect(result.bigint5).toEqual(1000000n); + expect(result.bigint6).toEqual(128n); + expect(result.bigint7).toEqual(2147483647n); + expect(result.obj.foo).toBe(BigInt(-10)); + expect(Array.from(result.set)).toEqual([ + BigInt(1), + BigInt(2) + ]); + expect(result.arr).toEqual([256n, 257n, 258n]); + } + + return; + } + + const storeValue = {}; + + storeValue.number = 42; + storeValue.number1 = 3.14; + storeValue.number2 = 6.2; + storeValue.string = "string"; + + if (isErrorCaseSupported) { + // eslint-disable-next-line n/no-unsupported-features/es-syntax + storeValue.error = new Error("error", { + cause: new Error("cause") + }); + // eslint-disable-next-line n/no-unsupported-features/es-syntax + storeValue.error1 = new Error("error", { + cause: { string: "string", number: 42 } + }); + } + + if (isBigIntSupported) { + storeValue.bigint = BigInt(5); + storeValue.bigint1 = BigInt(124); + storeValue.bigint2 = BigInt(125); + storeValue.bigint3 = 12345678901234567890n; + storeValue.bigint4 = 5n; + storeValue.bigint5 = 1000000n; + storeValue.bigint6 = 128n; + storeValue.bigint7 = 2147483647n; + storeValue.obj = { foo: BigInt(-10) }; + storeValue.set = new Set([BigInt(1), BigInt(2)]); + storeValue.arr = [256n, 257n, 258n]; + } + + await cacheItem.storePromise(storeValue); + } + ); + }); + } + } + ]; + + function runCompiler(onSuccess, onError) { + const c = webpack(options); + c.hooks.compilation.tap( + "CompilerCachingTest", + compilation => (compilation.bail = true) + ); + c.run((err, stats) => { + if (err) throw err; + expect(typeof stats).toBe("object"); + stats = stats.toJson({ + modules: true, + reasons: true + }); + expect(typeof stats).toBe("object"); + expect(stats).toHaveProperty("errors"); + expect(Array.isArray(stats.errors)).toBe(true); + if (stats.errors.length > 0) { + onError(new Error(JSON.stringify(stats.errors, null, 4))); + } + c.close(() => { + onSuccess(stats); + }); + }); + } + + runCompiler(onSuccess, onError); + + return { + runAgain: runCompiler + }; + } + + function cleanup() { + rimraf.sync(`${tempFixturePath}*`); + } + + beforeAll(cleanup); + afterAll(cleanup); + + function createTempFixture() { + const fixturePath = `${tempFixturePath}-${fixtureCount}`; + const usesAssetFilepath = path.join(fixturePath, "uses-asset.js"); + const svgFilepath = path.join(fixturePath, "file.svg"); + + // Remove previous copy if present + rimraf.sync(fixturePath); + + // Copy over file since we"ll be modifying some of them + fs.mkdirSync(fixturePath); + fs.copyFileSync( + path.join(__dirname, "fixtures", "uses-asset.js"), + usesAssetFilepath + ); + fs.copyFileSync(path.join(__dirname, "fixtures", "file.svg"), svgFilepath); + + fixtureCount++; + return { + rootPath: fixturePath, + usesAssetFilepath: usesAssetFilepath, + svgFilepath: svgFilepath + }; + } + + it("should compile again when cached asset has changed but loader output remains the same", done => { + const tempFixture = createTempFixture(); + + const onError = error => done(error); + + const helper = compile( + tempFixture.usesAssetFilepath, + stats => { + // Not cached the first time + expect(stats.assets[0].name).toBe("bundle.js"); + expect(stats.assets[0].emitted).toBe(true); + + expect(stats.assets[1].name).toMatch(/\w+\.svg$/); + expect(stats.assets[0].emitted).toBe(true); + + helper.runAgain(stats => { + // Cached the second run + expect(stats.assets[0].name).toBe("bundle.js"); + expect(stats.assets[0].emitted).toBe(false); + + expect(stats.assets[1].name).toMatch(/\w+\.svg$/); + expect(stats.assets[0].emitted).toBe(false); + + const svgContent = fs + .readFileSync(tempFixture.svgFilepath) + .toString() + .replace("icon-square-small", "icon-square-smaller"); + + fs.writeFileSync(tempFixture.svgFilepath, svgContent); + + helper.runAgain(stats => { + // Still cached after file modification because loader always returns empty + expect(stats.assets[0].name).toBe("bundle.js"); + expect(stats.assets[0].emitted).toBe(false); + + expect(stats.assets[1].name).toMatch(/\w+\.svg$/); + expect(stats.assets[0].emitted).toBe(false); + + done(); + }, onError); + }, onError); + }, + onError + ); + }); +}); diff --git a/test/Compiler.test.js b/test/Compiler.test.js index 607813c4a22..8d28e9d8a64 100644 --- a/test/Compiler.test.js +++ b/test/Compiler.test.js @@ -1,8 +1,8 @@ "use strict"; -const path = require("path"); +require("./helpers/warmup-webpack"); -const webpack = require(".."); +const path = require("path"); const Stats = require("../lib/Stats"); const { createFsFromVolume, Volume } = require("memfs"); const captureStdio = require("./helpers/captureStdio"); @@ -12,6 +12,7 @@ describe("Compiler", () => { jest.setTimeout(20000); function compile(entry, options, callback) { const noOutputPath = !options.output || !options.output.path; + const webpack = require(".."); options = webpack.config.getNormalizedWebpackOptions(options); if (!options.mode) options.mode = "production"; options.entry = entry; @@ -64,10 +65,23 @@ describe("Compiler", () => { throw stats.errors[0]; } stats.logs = logs; - callback(stats, files, compilation); + c.close(err => { + if (err) return callback(err); + callback(stats, files, compilation); + }); }); } + let compiler; + afterEach(callback => { + if (compiler) { + compiler.close(callback); + compiler = undefined; + } else { + callback(); + } + }); + it("should compile a single file to deep output", done => { compile( "./c", @@ -149,9 +163,9 @@ describe("Compiler", () => { it("should compile a file with multiple chunks", done => { compile("./chunks", {}, (stats, files) => { expect(stats.chunks).toHaveLength(2); - expect(Object.keys(files)).toEqual(["/main.js", "/394.js"]); + expect(Object.keys(files)).toEqual(["/main.js", "/78.js"]); const bundle = files["/main.js"]; - const chunk = files["/394.js"]; + const chunk = files["/78.js"]; expect(bundle).toMatch("function __webpack_require__("); expect(bundle).toMatch("__webpack_require__(/*! ./b */"); expect(chunk).not.toMatch("__webpack_require__(/* ./b */"); @@ -171,6 +185,7 @@ describe("Compiler", () => { }); }); + // cspell:word asmjs it("should not evaluate constants in asm.js", done => { compile("./asmjs", {}, (stats, files) => { expect(Object.keys(files)).toEqual(["/main.js"]); @@ -193,6 +208,7 @@ describe("Compiler", () => { describe("methods", () => { let compiler; beforeEach(() => { + const webpack = require(".."); compiler = webpack({ entry: "./c", context: path.join(__dirname, "fixtures"), @@ -202,6 +218,20 @@ describe("Compiler", () => { } }); }); + afterEach(callback => { + if (compiler) { + compiler.close(callback); + compiler = undefined; + } else { + callback(); + } + }); + it("default platform info", done => { + const platform = compiler.platform; + expect(platform.web).toBe(true); + expect(platform.node).toBe(false); + done(); + }); describe("purgeInputFileSystem", () => { it("invokes purge() if inputFileSystem.purge", done => { const mockPurge = jest.fn(); @@ -256,15 +286,39 @@ describe("Compiler", () => { const response8 = compiler.isChild(); expect(response8).toBe(false); - compiler.parentCompilation = NaN; + compiler.parentCompilation = Number.NaN; const response9 = compiler.isChild(); expect(response9).toBe(false); done(); }); }); }); - it("should not emit on errors", done => { + + it("PlatformPlugin", done => { + const webpack = require(".."); const compiler = webpack({ + entry: "./c", + context: path.join(__dirname, "fixtures"), + output: { + path: "/directory" + }, + plugins: [ + new (require("../lib/PlatformPlugin"))({ node: true }), + compiler => { + compiler.hooks.afterEnvironment.tap("test", () => { + const platform = compiler.platform; + expect(platform.node).toBe(true); + expect(platform.web).toBe(true); + }); + } + ] + }); + compiler.close(done); + }); + + it("should not emit on errors", done => { + const webpack = require(".."); + compiler = webpack({ context: __dirname, mode: "production", entry: "./missing", @@ -281,10 +335,11 @@ describe("Compiler", () => { done(); }); }); - it("should bubble up errors when wrapped in a promise and bail is true", async done => { + it("should bubble up errors when wrapped in a promise and bail is true", async () => { try { - const createCompiler = options => { - return new Promise((resolve, reject) => { + const createCompiler = options => + new Promise((resolve, reject) => { + const webpack = require(".."); const c = webpack(options); c.run((err, stats) => { if (err) { @@ -297,8 +352,7 @@ describe("Compiler", () => { } }); }); - }; - const compiler = await createCompiler({ + compiler = await createCompiler({ context: __dirname, mode: "production", entry: "./missing-file", @@ -308,47 +362,40 @@ describe("Compiler", () => { }, bail: true }); - done(); - return compiler; } catch (err) { expect(err.toString()).toMatch( "ModuleNotFoundError: Module not found: Error: Can't resolve './missing-file'" ); - done(); } }); - it("should not emit compilation errors in async (watch)", async done => { - try { - const createCompiler = options => { - return new Promise((resolve, reject) => { - const c = webpack(options); - c.outputFileSystem = createFsFromVolume(new Volume()); - const watching = c.watch({}, (err, stats) => { - watching.close(() => { - if (err) return reject(err); - resolve(stats); - }); + it("should not emit compilation errors in async (watch)", async () => { + const createStats = options => + new Promise((resolve, reject) => { + const webpack = require(".."); + const c = webpack(options); + c.outputFileSystem = createFsFromVolume(new Volume()); + const watching = c.watch({}, (err, stats) => { + watching.close(() => { + if (err) return reject(err); + resolve(stats); }); }); - }; - const compiler = await createCompiler({ - context: __dirname, - mode: "production", - entry: "./missing-file", - output: { - path: "/directory", - filename: "bundle.js" - } }); - expect(compiler).toBeInstanceOf(Stats); - done(); - } catch (err) { - done(err); - } + const stats = await createStats({ + context: __dirname, + mode: "production", + entry: "./missing-file", + output: { + path: "/directory", + filename: "bundle.js" + } + }); + expect(stats).toBeInstanceOf(Stats); }); it("should not emit on errors (watch)", done => { - const compiler = webpack({ + const webpack = require(".."); + compiler = webpack({ context: __dirname, mode: "production", entry: "./missing", @@ -367,7 +414,8 @@ describe("Compiler", () => { }); }); it("should not be running twice at a time (run)", done => { - const compiler = webpack({ + const webpack = require(".."); + compiler = webpack({ context: __dirname, mode: "production", entry: "./c", @@ -385,7 +433,8 @@ describe("Compiler", () => { }); }); it("should not be running twice at a time (watch)", done => { - const compiler = webpack({ + const webpack = require(".."); + compiler = webpack({ context: __dirname, mode: "production", entry: "./c", @@ -403,7 +452,8 @@ describe("Compiler", () => { }); }); it("should not be running twice at a time (run - watch)", done => { - const compiler = webpack({ + const webpack = require(".."); + compiler = webpack({ context: __dirname, mode: "production", entry: "./c", @@ -421,7 +471,8 @@ describe("Compiler", () => { }); }); it("should not be running twice at a time (watch - run)", done => { - const compiler = webpack({ + const webpack = require(".."); + compiler = webpack({ context: __dirname, mode: "production", entry: "./c", @@ -439,7 +490,8 @@ describe("Compiler", () => { }); }); it("should not be running twice at a time (instance cb)", done => { - const compiler = webpack( + const webpack = require(".."); + compiler = webpack( { context: __dirname, mode: "production", @@ -457,7 +509,8 @@ describe("Compiler", () => { }); }); it("should run again correctly after first compilation", done => { - const compiler = webpack({ + const webpack = require(".."); + compiler = webpack({ context: __dirname, mode: "production", entry: "./c", @@ -467,17 +520,19 @@ describe("Compiler", () => { } }); compiler.outputFileSystem = createFsFromVolume(new Volume()); - compiler.run((err, stats) => { + compiler.run((err, stats1) => { if (err) return done(err); - compiler.run((err, stats) => { + compiler.run((err, stats2) => { if (err) return done(err); + expect(stats1.toString({ all: true })).toBeTypeOf("string"); done(); }); }); }); it("should watch again correctly after first compilation", done => { - const compiler = webpack({ + const webpack = require(".."); + compiler = webpack({ context: __dirname, mode: "production", entry: "./c", @@ -490,14 +545,15 @@ describe("Compiler", () => { compiler.run((err, stats) => { if (err) return done(err); - compiler.watch({}, (err, stats) => { + const watching = compiler.watch({}, (err, stats) => { if (err) return done(err); - done(); + watching.close(done); }); }); }); it("should run again correctly after first closed watch", done => { - const compiler = webpack({ + const webpack = require(".."); + compiler = webpack({ context: __dirname, mode: "production", entry: "./c", @@ -518,7 +574,8 @@ describe("Compiler", () => { }); }); it("should set compiler.watching correctly", function (done) { - const compiler = webpack({ + const webpack = require(".."); + compiler = webpack({ context: __dirname, mode: "production", entry: "./c", @@ -530,12 +587,13 @@ describe("Compiler", () => { compiler.outputFileSystem = createFsFromVolume(new Volume()); const watching = compiler.watch({}, (err, stats) => { if (err) return done(err); - done(); + watching.close(done); }); expect(compiler.watching).toBe(watching); }); it("should watch again correctly after first closed watch", done => { - const compiler = webpack({ + const webpack = require(".."); + compiler = webpack({ context: __dirname, mode: "production", entry: "./c", @@ -556,7 +614,8 @@ describe("Compiler", () => { }); }); it("should run again correctly inside afterDone hook", done => { - const compiler = webpack({ + const webpack = require(".."); + compiler = webpack({ context: __dirname, mode: "production", entry: "./c", @@ -580,7 +639,8 @@ describe("Compiler", () => { }); }); it("should call afterDone hook after other callbacks (run)", done => { - const compiler = webpack({ + const webpack = require(".."); + compiler = webpack({ context: __dirname, mode: "production", entry: "./c", @@ -605,7 +665,8 @@ describe("Compiler", () => { }); it("should call afterDone hook after other callbacks (instance cb)", done => { const instanceCb = jest.fn(); - const compiler = webpack( + const webpack = require(".."); + compiler = webpack( { context: __dirname, mode: "production", @@ -630,7 +691,8 @@ describe("Compiler", () => { }); }); it("should call afterDone hook after other callbacks (watch)", done => { - const compiler = webpack({ + const webpack = require(".."); + compiler = webpack({ context: __dirname, mode: "production", entry: "./c", @@ -651,18 +713,19 @@ describe("Compiler", () => { expect(doneHookCb).toHaveBeenCalled(); expect(watchCb).toHaveBeenCalled(); expect(invalidateCb).toHaveBeenCalled(); - done(); + watching.close(done); }); - const watch = compiler.watch({}, (err, stats) => { + const watching = compiler.watch({}, (err, stats) => { if (err) return done(err); watchCb(); }); process.nextTick(() => { - watch.invalidate(invalidateCb); + watching.invalidate(invalidateCb); }); }); it("should call afterDone hook after other callbacks (watch close)", done => { - const compiler = webpack({ + const webpack = require(".."); + compiler = webpack({ context: __dirname, mode: "production", entry: "./c", @@ -694,7 +757,8 @@ describe("Compiler", () => { }); }); it("should flag watchMode as true in watch", done => { - const compiler = webpack({ + const webpack = require(".."); + compiler = webpack({ context: __dirname, mode: "production", entry: "./c", @@ -716,7 +780,8 @@ describe("Compiler", () => { }); }); it("should use cache on second run call", done => { - const compiler = webpack({ + const webpack = require(".."); + compiler = webpack({ context: __dirname, mode: "development", devtool: false, @@ -739,7 +804,8 @@ describe("Compiler", () => { }); it("should call the failed-hook on error", done => { const failedSpy = jest.fn(); - const compiler = webpack({ + const webpack = require(".."); + compiler = webpack({ bail: true, context: __dirname, mode: "production", @@ -760,7 +826,8 @@ describe("Compiler", () => { }); it("should deprecate when watch option is used without callback", () => { const tracker = deprecationTracking.start(); - webpack({ + const webpack = require(".."); + compiler = webpack({ watch: true }); const deprecations = tracker(); @@ -778,6 +845,12 @@ describe("Compiler", () => { afterEach(() => { capture.restore(); }); + const escapeAnsi = stringRaw => + stringRaw + .replace(/\u001B\[1m\u001B\[([0-9;]*)m/g, "") + .replace(/\u001B\[1m/g, "") + .replace(/\u001B\[39m\u001B\[22m/g, "") + .replace(/\u001B\[([0-9;]*)m/g, ""); class MyPlugin { apply(compiler) { const logger = compiler.getInfrastructureLogger("MyPlugin"); @@ -788,7 +861,7 @@ describe("Compiler", () => { logger.info("Info"); logger.log("Log"); logger.debug("Debug"); - logger.groupCollapsed("Collaped group"); + logger.groupCollapsed("Collapsed group"); logger.log("Log inside collapsed group"); logger.groupEnd(); logger.groupEnd(); @@ -796,7 +869,8 @@ describe("Compiler", () => { } } it("should log to the console (verbose)", done => { - const compiler = webpack({ + const webpack = require(".."); + compiler = webpack({ context: path.join(__dirname, "fixtures"), entry: "./a", output: { @@ -817,7 +891,7 @@ describe("Compiler", () => { [MyPlugin] Warning [MyPlugin] Info [MyPlugin] Log - <-> [MyPlugin] Collaped group + <-> [MyPlugin] Collapsed group [MyPlugin] Log inside collapsed group [MyPlugin] Time: X ms " @@ -826,7 +900,8 @@ describe("Compiler", () => { }); }); it("should log to the console (debug mode)", done => { - const compiler = webpack({ + const webpack = require(".."); + compiler = webpack({ context: path.join(__dirname, "fixtures"), entry: "./a", output: { @@ -849,7 +924,7 @@ describe("Compiler", () => { [MyPlugin] Info [MyPlugin] Log [MyPlugin] Debug - <-> [MyPlugin] Collaped group + <-> [MyPlugin] Collapsed group [MyPlugin] Log inside collapsed group [MyPlugin] Time: X ms " @@ -858,7 +933,8 @@ describe("Compiler", () => { }); }); it("should log to the console (none)", done => { - const compiler = webpack({ + const webpack = require(".."); + compiler = webpack({ context: path.join(__dirname, "fixtures"), entry: "./a", output: { @@ -876,5 +952,71 @@ describe("Compiler", () => { done(); }); }); + it("should log to the console with colors (verbose)", done => { + const webpack = require(".."); + compiler = webpack({ + context: path.join(__dirname, "fixtures"), + entry: "./a", + output: { + path: "/directory", + filename: "bundle.js" + }, + infrastructureLogging: { + level: "verbose", + colors: true + }, + plugins: [new MyPlugin()] + }); + compiler.outputFileSystem = createFsFromVolume(new Volume()); + compiler.run((err, stats) => { + expect(escapeAnsi(capture.toStringRaw()).replace(/[\d.]+ ms/, "X ms")) + .toMatchInlineSnapshot(` +"<-> [MyPlugin] Group + [MyPlugin] Error + [MyPlugin] Warning + [MyPlugin] Info + [MyPlugin] Log + <-> [MyPlugin] Collapsed group + [MyPlugin] Log inside collapsed group + [MyPlugin] Time: X ms +" +`); + done(); + }); + }); + it("should log to the console with colors (debug mode)", done => { + const webpack = require(".."); + compiler = webpack({ + context: path.join(__dirname, "fixtures"), + entry: "./a", + output: { + path: "/directory", + filename: "bundle.js" + }, + infrastructureLogging: { + level: "error", + debug: /MyPlugin/, + colors: true + }, + plugins: [new MyPlugin()] + }); + compiler.outputFileSystem = createFsFromVolume(new Volume()); + compiler.run((err, stats) => { + expect(escapeAnsi(capture.toStringRaw()).replace(/[\d.]+ ms/, "X ms")) + .toMatchInlineSnapshot(` +"<-> [MyPlugin] Group + [MyPlugin] Error + [MyPlugin] Warning + [MyPlugin] Info + [MyPlugin] Log + [MyPlugin] Debug + <-> [MyPlugin] Collapsed group + [MyPlugin] Log inside collapsed group + [MyPlugin] Time: X ms +" +`); + done(); + }); + }); }); }); diff --git a/test/ConfigCacheTestCases.test.js b/test/ConfigCacheTestCases.longtest.js similarity index 50% rename from test/ConfigCacheTestCases.test.js rename to test/ConfigCacheTestCases.longtest.js index 308260ca862..d9ec699e5ea 100644 --- a/test/ConfigCacheTestCases.test.js +++ b/test/ConfigCacheTestCases.longtest.js @@ -1,12 +1,11 @@ -const path = require("path"); const { describeCases } = require("./ConfigTestCases.template"); describeCases({ name: "ConfigCacheTestCases", cache: { - type: "filesystem" - }, - snapshot: { - managedPaths: [path.resolve(__dirname, "../node_modules")] + type: "filesystem", + buildDependencies: { + defaultWebpack: [] + } } }); diff --git a/test/ConfigTestCases.test.js b/test/ConfigTestCases.basictest.js similarity index 100% rename from test/ConfigTestCases.test.js rename to test/ConfigTestCases.basictest.js diff --git a/test/ConfigTestCases.template.js b/test/ConfigTestCases.template.js index 61aeb676032..822284c795d 100644 --- a/test/ConfigTestCases.template.js +++ b/test/ConfigTestCases.template.js @@ -1,11 +1,12 @@ "use strict"; +require("./helpers/warmup-webpack"); + const path = require("path"); const fs = require("graceful-fs"); const vm = require("vm"); -const { URL } = require("url"); +const { URL, pathToFileURL, fileURLToPath } = require("url"); const rimraf = require("rimraf"); -const TerserPlugin = require("terser-webpack-plugin"); const checkArrayExpectation = require("./checkArrayExpectation"); const createLazyTestEnv = require("./helpers/createLazyTestEnv"); const deprecationTracking = require("./helpers/deprecationTracking"); @@ -15,18 +16,33 @@ const CurrentScript = require("./helpers/CurrentScript"); const prepareOptions = require("./helpers/prepareOptions"); const { parseResource } = require("../lib/util/identifier"); const captureStdio = require("./helpers/captureStdio"); - -let webpack; +const asModule = require("./helpers/asModule"); +const filterInfraStructureErrors = require("./helpers/infrastructureLogErrors"); const casesPath = path.join(__dirname, "configCases"); -const categories = fs.readdirSync(casesPath).map(cat => { - return { - name: cat, - tests: fs - .readdirSync(path.join(casesPath, cat)) - .filter(folder => !folder.startsWith("_")) - .sort() - }; +const categories = fs.readdirSync(casesPath).map(cat => ({ + name: cat, + tests: fs + .readdirSync(path.join(casesPath, cat)) + .filter(folder => !folder.startsWith("_")) + .sort() +})); + +const createLogger = appendTarget => ({ + log: l => appendTarget.push(l), + debug: l => appendTarget.push(l), + trace: l => appendTarget.push(l), + info: l => appendTarget.push(l), + warn: console.warn.bind(console), + error: console.error.bind(console), + logTime: () => {}, + group: () => {}, + groupCollapsed: () => {}, + groupEnd: () => {}, + profile: () => {}, + profileEnd: () => {}, + clear: () => {}, + status: () => {} }); const describeCases = config => { @@ -34,7 +50,6 @@ const describeCases = config => { let stderr; beforeEach(() => { stderr = captureStdio(process.stderr, true); - webpack = require(".."); }); afterEach(() => { stderr.restore(); @@ -49,24 +64,28 @@ const describeCases = config => { describe(testName, function () { const testDirectory = path.join(casesPath, category.name, testName); const filterPath = path.join(testDirectory, "test.filter.js"); - if (fs.existsSync(filterPath) && !require(filterPath)()) { + if (fs.existsSync(filterPath) && !require(filterPath)(config)) { + // eslint-disable-next-line jest/no-disabled-tests describe.skip(testName, () => { it("filtered", () => {}); }); return; } + const infraStructureLog = []; const outBaseDir = path.join(__dirname, "js"); const testSubPath = path.join(config.name, category.name, testName); const outputDirectory = path.join(outBaseDir, testSubPath); const cacheDirectory = path.join(outBaseDir, ".cache", testSubPath); - let options, optionsArr, testConfig; + let options; + let optionsArr; + let testConfig; beforeAll(() => { options = prepareOptions( require(path.join(testDirectory, "webpack.config.js")), { testPath: outputDirectory } ); optionsArr = [].concat(options); - optionsArr.forEach((options, idx) => { + for (const [idx, options] of optionsArr.entries()) { if (!options.context) options.context = testDirectory; if (!options.mode) options.mode = "production"; if (!options.optimization) options.optimization = {}; @@ -74,7 +93,7 @@ const describeCases = config => { options.optimization.minimize = false; if (options.optimization.minimizer === undefined) { options.optimization.minimizer = [ - new TerserPlugin({ + new (require("terser-webpack-plugin"))({ parallel: false }) ]; @@ -86,20 +105,34 @@ const describeCases = config => { if (typeof options.output.pathinfo === "undefined") options.output.pathinfo = true; if (!options.output.filename) - options.output.filename = "bundle" + idx + ".js"; + options.output.filename = `bundle${idx}${ + options.experiments && options.experiments.outputModule + ? ".mjs" + : ".js" + }`; if (config.cache) { options.cache = { cacheDirectory, - name: `config-${idx}`, + name: + options.cache && options.cache !== true + ? options.cache.name + : `config-${idx}`, ...config.cache }; } - if (config.snapshot) { - options.snapshot = { - ...config.snapshot + if (config.cache) { + options.infrastructureLogging = { + debug: true, + console: createLogger(infraStructureLog) }; } - }); + if (!options.snapshot) options.snapshot = {}; + if (!options.snapshot.managedPaths) { + options.snapshot.managedPaths = [ + path.resolve(__dirname, "../node_modules") + ]; + } + } testConfig = { findBundle: function (i, options) { const ext = path.extname( @@ -107,10 +140,10 @@ const describeCases = config => { ); if ( fs.existsSync( - path.join(options.output.path, "bundle" + i + ext) + path.join(options.output.path, `bundle${i}${ext}`) ) ) { - return "./bundle" + i + ext; + return `./bundle${i}${ext}`; } }, timeout: 30000 @@ -121,11 +154,17 @@ const describeCases = config => { testConfig, require(path.join(testDirectory, "test.config.js")) ); - } catch (e) { + } catch (_err) { // ignored } if (testConfig.timeout) setDefaultTimeout(testConfig.timeout); }); + afterAll(() => { + // cleanup + options = undefined; + optionsArr = undefined; + testConfig = undefined; + }); beforeAll(() => { rimraf.sync(cacheDirectory); }); @@ -151,24 +190,60 @@ const describeCases = config => { } // Wait for uncaught errors to occur setTimeout(done, 200); - return; }; if (config.cache) { it(`${testName} should pre-compile to fill disk cache (1st)`, done => { rimraf.sync(outputDirectory); fs.mkdirSync(outputDirectory, { recursive: true }); + infraStructureLog.length = 0; const deprecationTracker = deprecationTracking.start(); - webpack(options, err => { + const compiler = require("..")(options); + compiler.run(err => { deprecationTracker(); if (err) return handleFatalError(err, done); - done(); + const infrastructureLogging = stderr.toString(); + if (infrastructureLogging) { + return done( + new Error( + `Errors/Warnings during build:\n${ + infrastructureLogging + }` + ) + ); + } + const infrastructureLogErrors = filterInfraStructureErrors( + infraStructureLog, + { + run: 1, + options + } + ); + if ( + infrastructureLogErrors.length && + checkArrayExpectation( + testDirectory, + { infrastructureLogs: infrastructureLogErrors }, + "infrastructureLog", + "infrastructure-log", + "InfrastructureLog", + done + ) + ) { + return; + } + compiler.close(closeErr => { + if (closeErr) return handleFatalError(closeErr, done); + done(); + }); }); }, 60000); it(`${testName} should pre-compile to fill disk cache (2nd)`, done => { rimraf.sync(outputDirectory); fs.mkdirSync(outputDirectory, { recursive: true }); + infraStructureLog.length = 0; const deprecationTracker = deprecationTracking.start(); - webpack(options, (err, stats) => { + const compiler = require("..")(options); + compiler.run((err, stats) => { deprecationTracker(); if (err) return handleFatalError(err, done); const { modules, children, errorsCount } = stats.toJson({ @@ -177,11 +252,21 @@ const describeCases = config => { errorsCount: true }); if (errorsCount === 0) { + const infrastructureLogging = stderr.toString(); + if (infrastructureLogging) { + return done( + new Error( + `Errors/Warnings during build:\n${ + infrastructureLogging + }` + ) + ); + } const allModules = children ? children.reduce( (all, { modules }) => all.concat(modules), modules || [] - ) + ) : modules; if ( allModules.some( @@ -199,15 +284,39 @@ const describeCases = config => { ); } } - done(); + const infrastructureLogErrors = filterInfraStructureErrors( + infraStructureLog, + { + run: 2, + options + } + ); + if ( + infrastructureLogErrors.length && + checkArrayExpectation( + testDirectory, + { infrastructureLogs: infrastructureLogErrors }, + "infrastructureLog", + "infrastructure-log", + "InfrastructureLog", + done + ) + ) { + return; + } + compiler.close(closeErr => { + if (closeErr) return handleFatalError(closeErr, done); + done(); + }); }); - }, 20000); + }, 40000); } it(`${testName} should compile`, done => { rimraf.sync(outputDirectory); fs.mkdirSync(outputDirectory, { recursive: true }); + infraStructureLog.length = 0; const deprecationTracker = deprecationTracking.start(); - webpack(options, (err, stats) => { + const onCompiled = (err, stats) => { const deprecations = deprecationTracker(); if (err) return handleFatalError(err, done); const statOptions = { @@ -252,9 +361,9 @@ const describeCases = config => { } const infrastructureLogging = stderr.toString(); if (infrastructureLogging) { - done( + return done( new Error( - "Errors/Warnings during build:\n" + infrastructureLogging + `Errors/Warnings during build:\n${infrastructureLogging}` ) ); } @@ -269,6 +378,26 @@ const describeCases = config => { ) { return; } + const infrastructureLogErrors = filterInfraStructureErrors( + infraStructureLog, + { + run: 3, + options + } + ); + if ( + infrastructureLogErrors.length && + checkArrayExpectation( + testDirectory, + { infrastructureLogs: infrastructureLogErrors }, + "infrastructureLog", + "infrastructure-log", + "InfrastructureLog", + done + ) + ) { + return; + } let filesCount = 0; @@ -276,16 +405,19 @@ const describeCases = config => { if (testConfig.beforeExecute) testConfig.beforeExecute(); const results = []; for (let i = 0; i < optionsArr.length; i++) { + const options = optionsArr[i]; const bundlePath = testConfig.findBundle(i, optionsArr[i]); if (bundlePath) { filesCount++; - const document = new FakeDocument(); + const document = new FakeDocument(outputDirectory); const globalContext = { console: console, expect: expect, setTimeout: setTimeout, clearTimeout: clearTimeout, document, + getComputedStyle: + document.getComputedStyle.bind(document), location: { href: "https://test.cases/path/index.html", origin: "https://test.cases", @@ -296,8 +428,66 @@ const describeCases = config => { }; const requireCache = Object.create(null); + const esmCache = new Map(); + const esmIdentifier = `${category.name}-${testName}-${i}`; + const baseModuleScope = { + console: console, + it: _it, + beforeEach: _beforeEach, + afterEach: _afterEach, + expect, + jest, + __STATS__: jsonStats, + nsObj: m => { + Object.defineProperty(m, Symbol.toStringTag, { + value: "Module" + }); + return m; + } + }; + + let runInNewContext = false; + if ( + options.target === "web" || + options.target === "webworker" || + (Array.isArray(options.target) && + (options.target.includes("web") || + options.target.includes("webworker"))) + ) { + baseModuleScope.window = globalContext; + baseModuleScope.self = globalContext; + baseModuleScope.document = globalContext.document; + baseModuleScope.setTimeout = globalContext.setTimeout; + baseModuleScope.clearTimeout = globalContext.clearTimeout; + baseModuleScope.getComputedStyle = + globalContext.getComputedStyle; + baseModuleScope.URL = URL; + baseModuleScope.Worker = + require("./helpers/createFakeWorker")({ + outputDirectory + }); + runInNewContext = true; + } + if (testConfig.moduleScope) { + testConfig.moduleScope(baseModuleScope); + } + const esmContext = vm.createContext(baseModuleScope, { + name: "context for esm" + }); + // eslint-disable-next-line no-loop-func - const _require = (currentDirectory, options, module) => { + const _require = ( + currentDirectory, + options, + module, + esmMode, + parentModule + ) => { + if (testConfig === undefined) { + throw new Error( + `_require(${module}) called after all tests from ${category.name} ${testName} have completed` + ); + } if (Array.isArray(module) || /^\.\.?\//.test(module)) { let content; let p; @@ -305,9 +495,9 @@ const describeCases = config => { if (Array.isArray(module)) { p = path.join(currentDirectory, ".array-require.js"); content = `module.exports = (${module - .map(arg => { - return `require(${JSON.stringify(`./${arg}`)})`; - }) + .map( + arg => `require(${JSON.stringify(`./${arg}`)})` + ) .join(", ")});`; } else { p = path.join(currentDirectory, module); @@ -333,6 +523,79 @@ const describeCases = config => { ); } } + const isModule = + p.endsWith(".mjs") && + options.experiments && + options.experiments.outputModule; + + if (isModule) { + if (!vm.SourceTextModule) + throw new Error( + "Running this test requires '--experimental-vm-modules'.\nRun with 'node --experimental-vm-modules node_modules/jest-cli/bin/jest'." + ); + let esm = esmCache.get(p); + if (!esm) { + esm = new vm.SourceTextModule(content, { + identifier: `${esmIdentifier}-${p}`, + url: `${pathToFileURL(p).href}?${esmIdentifier}`, + context: esmContext, + initializeImportMeta: (meta, module) => { + meta.url = pathToFileURL(p).href; + }, + importModuleDynamically: async ( + specifier, + module + ) => { + const result = await _require( + path.dirname(p), + options, + specifier, + "evaluated", + module + ); + return await asModule(result, module.context); + } + }); + esmCache.set(p, esm); + } + if (esmMode === "unlinked") return esm; + return (async () => { + if (esmMode === "unlinked") return esm; + await esm.link( + async (specifier, referencingModule) => + await asModule( + await _require( + path.dirname( + referencingModule.identifier + ? referencingModule.identifier.slice( + esmIdentifier.length + 1 + ) + : fileURLToPath(referencingModule.url) + ), + options, + specifier, + "unlinked", + referencingModule + ), + referencingModule.context, + true + ) + ); + // node.js 10 needs instantiate + if (esm.instantiate) esm.instantiate(); + await esm.evaluate(); + if (esmMode === "evaluated") return esm; + const ns = esm.namespace; + return ns.default && ns.default instanceof Promise + ? ns.default + : ns; + })(); + } + const isJSON = p.endsWith(".json"); + if (isJSON) { + return JSON.parse(content); + } + if (p in requireCache) { return requireCache[p].exports; } @@ -340,11 +603,9 @@ const describeCases = config => { exports: {} }; requireCache[p] = m; - let runInNewContext = false; - let oldCurrentScript = document.currentScript; - document.currentScript = new CurrentScript(subPath); const moduleScope = { + ...baseModuleScope, require: _require.bind( null, path.dirname(p), @@ -364,62 +625,58 @@ const describeCases = config => { exports: m.exports, __dirname: path.dirname(p), __filename: p, - it: _it, - beforeEach: _beforeEach, - afterEach: _afterEach, - expect, - jest, - _globalAssign: { expect }, - __STATS__: jsonStats, - nsObj: m => { - Object.defineProperty(m, Symbol.toStringTag, { - value: "Module" - }); - return m; - } + _globalAssign: { expect } }; - if ( - options.target === "web" || - options.target === "webworker" - ) { - moduleScope.window = globalContext; - moduleScope.self = globalContext; - moduleScope.URL = URL; - moduleScope.Worker = require("./helpers/createFakeWorker")( - { outputDirectory } - ); - runInNewContext = true; - } if (testConfig.moduleScope) { testConfig.moduleScope(moduleScope); } - const args = Object.keys(moduleScope); - const argValues = args.map(arg => moduleScope[arg]); if (!runInNewContext) content = `Object.assign(global, _globalAssign); ${content}`; + const args = Object.keys(moduleScope); + const argValues = args.map(arg => moduleScope[arg]); const code = `(function(${args.join( ", " )}) {${content}\n})`; + + const oldCurrentScript = document.currentScript; + document.currentScript = new CurrentScript(subPath); const fn = runInNewContext ? vm.runInNewContext(code, globalContext, p) : vm.runInThisContext(code, p); - fn.call(m.exports, ...argValues); - - //restore state + fn.call( + testConfig.nonEsmThis + ? testConfig.nonEsmThis(module) + : m.exports, + ...argValues + ); document.currentScript = oldCurrentScript; - return m.exports; } else if ( testConfig.modules && module in testConfig.modules ) { return testConfig.modules[module]; - } else return require(module); + } + return require( + module.startsWith("node:") ? module.slice(5) : module + ); }; - results.push( - _require(outputDirectory, optionsArr[i], bundlePath) - ); + if (Array.isArray(bundlePath)) { + for (const bundlePathItem of bundlePath) { + results.push( + _require( + outputDirectory, + options, + `./${bundlePathItem}` + ) + ); + } + } else { + results.push( + _require(outputDirectory, options, bundlePath) + ); + } } } // give a free pass to compilation that generated an error @@ -436,14 +693,35 @@ const describeCases = config => { Promise.all(results) .then(() => { if (testConfig.afterExecute) testConfig.afterExecute(); + for (const key of Object.keys(global)) { + if (key.includes("webpack")) delete global[key]; + } if (getNumberOfTests() < filesCount) { return done(new Error("No tests exported by test case")); } done(); }) .catch(done); - }); - }); + }; + if (config.cache) { + try { + const compiler = require("..")(options); + compiler.run(err => { + if (err) return handleFatalError(err, done); + compiler.run((error, stats) => { + compiler.close(err => { + if (err) return handleFatalError(err, done); + onCompiled(error, stats); + }); + }); + }); + } catch (err) { + handleFatalError(err, done); + } + } else { + require("..")(options, onCompiled); + } + }, 30000); const { it: _it, @@ -451,7 +729,7 @@ const describeCases = config => { afterEach: _afterEach, setDefaultTimeout, getNumberOfTests - } = createLazyTestEnv(jasmine.getEnv(), 10000); + } = createLazyTestEnv(10000); }); } }); @@ -459,4 +737,5 @@ const describeCases = config => { }); }; -exports.describeCases = describeCases; +// eslint-disable-next-line jest/no-export +module.exports.describeCases = describeCases; diff --git a/test/ContextModule.unittest.js b/test/ContextModule.unittest.js new file mode 100644 index 00000000000..ae3ab350377 --- /dev/null +++ b/test/ContextModule.unittest.js @@ -0,0 +1,25 @@ +"use strict"; + +const ContextModule = require("../lib/ContextModule"); + +describe("contextModule", () => { + let contextModule; + let request; + beforeEach(() => { + request = "/some/request"; + }); + describe("#identifier", () => { + it("returns an safe identifier for this module", () => { + contextModule = new ContextModule(() => {}, { + type: "javascript/auto", + request, + resource: "a", + mode: "lazy", + regExp: /a|b/ + }); + expect(contextModule.identifier()).toEqual( + expect.stringContaining("/a%7Cb/") + ); + }); + }); +}); diff --git a/test/ContextModuleFactory.unittest.js b/test/ContextModuleFactory.unittest.js index 5ecc9bab59f..db673a7e967 100644 --- a/test/ContextModuleFactory.unittest.js +++ b/test/ContextModuleFactory.unittest.js @@ -5,7 +5,8 @@ const ContextModuleFactory = require("../lib/ContextModuleFactory"); describe("ContextModuleFactory", () => { describe("resolveDependencies", () => { - let factory, memfs; + let factory; + let memfs; beforeEach(() => { factory = new ContextModuleFactory([]); memfs = createFsFromVolume(new Volume()); @@ -15,7 +16,7 @@ describe("ContextModuleFactory", () => { setTimeout(() => callback(null, ["/file"])); }; memfs.stat = (file, callback) => { - let err = new Error("fake ENOENT error"); + const err = new Error("fake ENOENT error"); err.code = "ENOENT"; setTimeout(() => callback(err, null)); }; @@ -39,7 +40,7 @@ describe("ContextModuleFactory", () => { setTimeout(() => callback(null, ["/file"])); }; memfs.stat = (file, callback) => { - let err = new Error("fake EACCES error"); + const err = new Error("fake EACCES error"); err.code = "EACCES"; setTimeout(() => callback(err, null)); }; @@ -119,5 +120,43 @@ describe("ContextModuleFactory", () => { } ); }); + + it("should resolve correctly several resources", done => { + memfs.readdir = (dir, callback) => { + if (dir === "/a") setTimeout(() => callback(null, ["/B"])); + if (dir === "/b") setTimeout(() => callback(null, ["/A"])); + if (dir === "/a/B") setTimeout(() => callback(null, ["a"])); + if (dir === "/b/A") setTimeout(() => callback(null, ["b"])); + }; + memfs.stat = (file, callback) => { + const resolvedValue = { + isDirectory: () => file !== "/a/B/a" && file !== "/b/A/b", + isFile: () => file === "/a/B/a" || file === "/b/A/b" + }; + setTimeout(() => callback(null, resolvedValue)); + }; + memfs.realpath = undefined; + factory.resolveDependencies( + memfs, + { + resource: ["/a", "/b"], + resourceFragment: "#hash", + resourceQuery: "?query", + recursive: true, + regExp: /.*/ + }, + (err, res) => { + expect(res).not.toStrictEqual([]); + expect(Array.isArray(res)).toBe(true); + expect(res.map(r => r.request)).toEqual([ + "./B/a?query#hash", + "./A/b?query#hash" + ]); + expect(res.map(r => r.getContext())).toEqual(["/a", "/b"]); + expect(res.map(r => r.userRequest)).toEqual(["./B/a", "./A/b"]); + done(); + } + ); + }); }); }); diff --git a/test/Defaults.unittest.js b/test/Defaults.unittest.js index ba1c3f6b033..890743a3a4c 100644 --- a/test/Defaults.unittest.js +++ b/test/Defaults.unittest.js @@ -1,76 +1,74 @@ +require("./helpers/warmup-webpack"); + const path = require("path"); -const jestDiff = require("jest-diff").default; +const jestDiff = require("jest-diff").diff; const stripAnsi = require("strip-ansi"); -const { - applyWebpackOptionsDefaults, - getNormalizedWebpackOptions -} = require("..").config; /** * Escapes regular expression metacharacters * @param {string} str String to quote * @returns {string} Escaped string */ -const quotemeta = str => { - return str.replace(/[-[\]\\/{}()*+?.^$|]/g, "\\$&"); -}; +const quoteMeta = str => str.replace(/[-[\]\\/{}()*+?.^$|]/g, "\\$&"); -describe("Defaults", () => { - const cwd = process.cwd(); - const cwdRegExp = new RegExp( - `${quotemeta(cwd)}((?:\\\\)?(?:[a-zA-Z.\\-_]+\\\\)*)`, - "g" - ); - const escapedCwd = JSON.stringify(cwd).slice(1, -1); - const escapedCwdRegExp = new RegExp( - `${quotemeta(escapedCwd)}((?:\\\\\\\\)?(?:[a-zA-Z.\\-_]+\\\\\\\\)*)`, - "g" - ); - const normalize = str => { - if (cwd.startsWith("/")) { - str = str.replace(new RegExp(quotemeta(cwd), "g"), ""); - } else { - str = str.replace(cwdRegExp, (m, g) => `${g.replace(/\\/g, "/")}`); - str = str.replace( - escapedCwdRegExp, - (m, g) => `${g.replace(/\\\\/g, "/")}` - ); - } - str = str.replace(/@@ -\d+,\d+ \+\d+,\d+ @@/g, "@@ ... @@"); - return str; - }; +const cwd = process.cwd(); +const cwdRegExp = new RegExp( + `${quoteMeta(cwd)}((?:\\\\)?(?:[a-zA-Z.\\-_]+\\\\)*)`, + "g" +); +const escapedCwd = JSON.stringify(cwd).slice(1, -1); +const escapedCwdRegExp = new RegExp( + `${quoteMeta(escapedCwd)}((?:\\\\\\\\)?(?:[a-zA-Z.\\-_]+\\\\\\\\)*)`, + "g" +); +const normalize = str => { + if (cwd.startsWith("/")) { + str = str.replace(new RegExp(quoteMeta(cwd), "g"), ""); + } else { + str = str.replace(cwdRegExp, (m, g) => `${g.replace(/\\/g, "/")}`); + str = str.replace( + escapedCwdRegExp, + (m, g) => `${g.replace(/\\\\/g, "/")}` + ); + } + str = str.replace(/@@ -\d+,\d+ \+\d+,\d+ @@/g, "@@ ... @@"); + return str; +}; - class Diff { - constructor(value) { - this.value = value; - } +class Diff { + constructor(value) { + this.value = value; } +} - expect.addSnapshotSerializer({ - test(value) { - return value instanceof Diff; - }, - print(received) { - return normalize(received.value); - } - }); +expect.addSnapshotSerializer({ + test(value) { + return value instanceof Diff; + }, + print(received) { + return normalize(received.value); + } +}); - expect.addSnapshotSerializer({ - test(value) { - return typeof value === "string"; - }, - print(received) { - return JSON.stringify(normalize(received)); - } - }); +expect.addSnapshotSerializer({ + test(value) { + return typeof value === "string"; + }, + print(received) { + return JSON.stringify(normalize(received)); + } +}); - const getDefaultConfig = config => { - config = getNormalizedWebpackOptions(config); - applyWebpackOptionsDefaults(config); - process.chdir(cwd); - return config; - }; +const getDefaultConfig = config => { + const { applyWebpackOptionsDefaults, getNormalizedWebpackOptions } = + require("..").config; + config = getNormalizedWebpackOptions(config); + applyWebpackOptionsDefaults(config); + process.chdir(cwd); + return config; +}; +describe("snapshots", () => { const baseConfig = getDefaultConfig({ mode: "none" }); it("should have the correct base config", () => { @@ -92,9 +90,16 @@ describe("Defaults", () => { }, "experiments": Object { "asyncWebAssembly": false, + "backCompat": true, + "buildHttp": undefined, + "cacheUnaffected": false, + "css": undefined, + "futureDefaults": false, + "layers": false, + "lazyCompilation": undefined, "outputModule": false, "syncWebAssembly": false, - "topLevelAwait": false, + "topLevelAwait": true, }, "externals": undefined, "externalsPresets": Object { @@ -108,19 +113,29 @@ describe("Defaults", () => { }, "externalsType": "var", "ignoreWarnings": undefined, - "infrastructureLogging": Object { - "debug": false, - "level": "info", - }, + "infrastructureLogging": Object {}, "loader": Object { + "environment": Object { + "arrowFunction": true, + "asyncFunction": true, + "bigIntLiteral": true, + "const": true, + "destructuring": true, + "document": true, + "dynamicImport": undefined, + "dynamicImportInWorker": undefined, + "forOf": true, + "globalThis": undefined, + "module": undefined, + "nodePrefixForCoreModules": true, + "optionalChaining": true, + "templateLiteral": true, + }, "target": "web", }, "mode": "none", "module": Object { "defaultRules": Array [ - Object { - "type": "javascript/auto", - }, Object { "mimetype": "application/node", "type": "javascript/auto", @@ -187,7 +202,27 @@ describe("Defaults", () => { }, Object { "dependency": "url", - "type": "asset/resource", + "oneOf": Array [ + Object { + "scheme": /\\^data\\$/, + "type": "asset/inline", + }, + Object { + "type": "asset/resource", + }, + ], + }, + Object { + "assert": Object { + "type": "json", + }, + "type": "json", + }, + Object { + "type": "json", + "with": Object { + "type": "json", + }, }, ], "generator": Object {}, @@ -199,11 +234,17 @@ describe("Defaults", () => { }, }, "javascript": Object { + "createRequire": false, + "dynamicImportFetchPriority": false, + "dynamicImportMode": "lazy", + "dynamicImportPrefetch": false, + "dynamicImportPreload": false, "exprContextCritical": true, "exprContextRecursive": true, "exprContextRegExp": false, "exprContextRequest": ".", - "strictExportPresence": false, + "importMeta": true, + "strictExportPresence": undefined, "strictThisContextOnImports": false, "unknownContextCritical": true, "unknownContextRecursive": true, @@ -276,12 +317,13 @@ describe("Defaults", () => { "minChunks": 1, "minRemainingSize": undefined, "minSize": 10000, - "usedExports": true, + "usedExports": false, }, "usedExports": false, }, "output": Object { "assetModuleFilename": "[hash][ext][query]", + "asyncChunks": true, "charset": true, "chunkFilename": "[name].js", "chunkFormat": "array-push", @@ -291,6 +333,9 @@ describe("Defaults", () => { "clean": undefined, "compareBeforeEmit": true, "crossOriginLoading": false, + "cssChunkFilename": "[name].css", + "cssFilename": "[name].css", + "cssHeadDataCompression": true, "devtoolFallbackModuleFilenameTemplate": undefined, "devtoolModuleFilenameTemplate": undefined, "devtoolNamespace": "webpack", @@ -304,12 +349,19 @@ describe("Defaults", () => { ], "environment": Object { "arrowFunction": true, - "bigIntLiteral": undefined, + "asyncFunction": true, + "bigIntLiteral": true, "const": true, "destructuring": true, + "document": true, "dynamicImport": undefined, + "dynamicImportInWorker": undefined, "forOf": true, + "globalThis": undefined, "module": undefined, + "nodePrefixForCoreModules": true, + "optionalChaining": true, + "templateLiteral": true, }, "filename": "[name].js", "globalObject": "self", @@ -320,6 +372,7 @@ describe("Defaults", () => { "hotUpdateChunkFilename": "[id].[fullhash].hot-update.js", "hotUpdateGlobal": "webpackHotUpdatewebpack", "hotUpdateMainFilename": "[runtime].[fullhash].hot-update.json", + "ignoreBrowserWarnings": undefined, "iife": true, "importFunctionName": "import", "importMetaName": "import.meta", @@ -331,11 +384,14 @@ describe("Defaults", () => { "scriptType": false, "sourceMapFilename": "[file].map[query]", "sourcePrefix": undefined, + "strictModuleErrorHandling": false, "strictModuleExceptionHandling": false, + "trustedTypes": undefined, "uniqueName": "webpack", "wasmLoading": "fetch", "webassemblyModuleFilename": "[hash].module.wasm", "workerChunkLoading": "import-scripts", + "workerPublicPath": "", "workerWasmLoading": "fetch", }, "parallelism": 100, @@ -427,6 +483,26 @@ describe("Defaults", () => { "...", ], }, + "loaderImport": Object { + "aliasFields": Array [ + "browser", + ], + "conditionNames": Array [ + "import", + "module", + "...", + ], + "extensions": Array [ + ".js", + ".json", + ".wasm", + ], + "mainFields": Array [ + "browser", + "module", + "...", + ], + }, "undefined": Object { "aliasFields": Array [ "browser", @@ -522,6 +598,9 @@ describe("Defaults", () => { "exports", ], "extensions": Array [], + "importsFields": Array [ + "imports", + ], "mainFields": Array [ "main", ], @@ -563,7 +642,7 @@ describe("Defaults", () => { }, "immutablePaths": Array [], "managedPaths": Array [ - "/node_modules", + "/node_modules/", ], "module": Object { "timestamp": true, @@ -575,6 +654,7 @@ describe("Defaults", () => { "hash": true, "timestamp": true, }, + "unmanagedPaths": Array [], }, "stats": Object {}, "target": "web", @@ -603,10 +683,10 @@ describe("Defaults", () => { }; test("empty config", {}, e => - e.toMatchInlineSnapshot(`Compared values have no visual difference.`) + e.toMatchInlineSnapshot("Compared values have no visual difference.") ); test("none mode", { mode: "none" }, e => - e.toMatchInlineSnapshot(`Compared values have no visual difference.`) + e.toMatchInlineSnapshot("Compared values have no visual difference.") ); test("no mode provided", { mode: undefined }, e => e.toMatchInlineSnapshot(` @@ -656,7 +736,9 @@ describe("Defaults", () => { + "maxInitialRequests": 30, @@ ... @@ - "minSize": 10000, + - "usedExports": false, + "minSize": 20000, + + "usedExports": true, @@ ... @@ - "usedExports": false, + "usedExports": true, @@ -721,7 +803,9 @@ describe("Defaults", () => { + "maxInitialRequests": 30, @@ ... @@ - "minSize": 10000, + - "usedExports": false, + "minSize": 20000, + + "usedExports": true, @@ ... @@ - "usedExports": false, + "usedExports": true, @@ -746,6 +830,8 @@ describe("Defaults", () => { @@ ... @@ - "cache": false, + "cache": Object { + + "cacheUnaffected": false, + + "maxGenerations": Infinity, + "type": "memory", + }, @@ ... @@ @@ -769,6 +855,9 @@ describe("Defaults", () => { - "minRemainingSize": undefined, + "minRemainingSize": 0, @@ ... @@ + - "cssHeadDataCompression": true, + + "cssHeadDataCompression": false, + @@ ... @@ - "pathinfo": false, + "pathinfo": true, @@ ... @@ @@ -831,7 +920,32 @@ describe("Defaults", () => { + "outputModule": true, @@ ... @@ - "externalsType": "var", - + "externalsType": "module", + + "externalsType": "module-import", + @@ ... @@ + - "dynamicImport": undefined, + - "dynamicImportInWorker": undefined, + + "dynamicImport": true, + + "dynamicImportInWorker": true, + @@ ... @@ + - "module": undefined, + + "module": true, + @@ ... @@ + - "chunkFilename": "[name].js", + + "chunkFilename": "[name].mjs", + @@ ... @@ + - "dynamicImport": undefined, + - "dynamicImportInWorker": undefined, + + "dynamicImport": true, + + "dynamicImportInWorker": true, + @@ ... @@ + - "module": undefined, + + "module": true, + @@ ... @@ + - "filename": "[name].js", + + "filename": "[name].mjs", + @@ ... @@ + - "hotUpdateChunkFilename": "[id].[fullhash].hot-update.js", + + "hotUpdateChunkFilename": "[id].[fullhash].hot-update.mjs", @@ ... @@ - "iife": true, + "iife": false, @@ -936,6 +1050,11 @@ describe("Defaults", () => { - "chunkFilename": "[name].js", + "chunkFilename": "[id].bundle.js", @@ ... @@ + - "cssChunkFilename": "[name].css", + - "cssFilename": "[name].css", + + "cssChunkFilename": "[id].bundle.css", + + "cssFilename": "bundle.css", + @@ ... @@ - "filename": "[name].js", + "filename": "bundle.js", `) @@ -949,6 +1068,11 @@ describe("Defaults", () => { - "chunkFilename": "[name].js", + "chunkFilename": "[id].js", @@ ... @@ + - "cssChunkFilename": "[name].css", + - "cssFilename": "[name].css", + + "cssChunkFilename": "[id].css", + + "cssFilename": "[id].css", + @@ ... @@ - "filename": "[name].js", + "filename": [Function filename], `) @@ -975,6 +1099,7 @@ describe("Defaults", () => { @@ ... @@ - "library": undefined, + "library": Object { + + "amdContainer": undefined, + "auxiliaryComment": undefined, + "export": undefined, + "name": Array [ @@ -989,6 +1114,201 @@ describe("Defaults", () => { + "uniqueName": "myLib.awesome", `) ); + test( + "library contains [name] placeholder", + { + output: { + library: ["myLib", "[name]"] + } + }, + e => + e.toMatchInlineSnapshot(` + - Expected + + Received + + @@ ... @@ + - "chunkLoadingGlobal": "webpackChunkwebpack", + + "chunkLoadingGlobal": "webpackChunkmyLib", + @@ ... @@ + - "devtoolNamespace": "webpack", + + "devtoolNamespace": "myLib", + @@ ... @@ + - "enabledLibraryTypes": Array [], + + "enabledLibraryTypes": Array [ + + "var", + + ], + @@ ... @@ + - "hotUpdateGlobal": "webpackHotUpdatewebpack", + + "hotUpdateGlobal": "webpackHotUpdatemyLib", + @@ ... @@ + - "library": undefined, + + "library": Object { + + "amdContainer": undefined, + + "auxiliaryComment": undefined, + + "export": undefined, + + "name": Array [ + + "myLib", + + "[name]", + + ], + + "type": "var", + + "umdNamedDefine": undefined, + + }, + @@ ... @@ + - "uniqueName": "webpack", + + "uniqueName": "myLib", + `) + ); + test( + "library.name contains [name] placeholder", + { + output: { + library: { + name: ["my[name]Lib", "[name]", "lib"], + type: "var" + } + } + }, + e => + e.toMatchInlineSnapshot(` + - Expected + + Received + + @@ ... @@ + - "chunkLoadingGlobal": "webpackChunkwebpack", + + "chunkLoadingGlobal": "webpackChunkmyLib_lib", + @@ ... @@ + - "devtoolNamespace": "webpack", + + "devtoolNamespace": "myLib.lib", + @@ ... @@ + - "enabledLibraryTypes": Array [], + + "enabledLibraryTypes": Array [ + + "var", + + ], + @@ ... @@ + - "hotUpdateGlobal": "webpackHotUpdatewebpack", + + "hotUpdateGlobal": "webpackHotUpdatemyLib_lib", + @@ ... @@ + - "library": undefined, + + "library": Object { + + "amdContainer": undefined, + + "auxiliaryComment": undefined, + + "export": undefined, + + "name": Array [ + + "my[name]Lib", + + "[name]", + + "lib", + + ], + + "type": "var", + + "umdNamedDefine": undefined, + + }, + @@ ... @@ + - "uniqueName": "webpack", + + "uniqueName": "myLib.lib", + `) + ); + test( + "library.name.root contains [name] placeholder", + { + output: { + library: { + name: { + root: ["[name]", "myLib"] + }, + type: "var" + } + } + }, + e => + e.toMatchInlineSnapshot(` + - Expected + + Received + + @@ ... @@ + - "chunkLoadingGlobal": "webpackChunkwebpack", + + "chunkLoadingGlobal": "webpackChunkmyLib", + @@ ... @@ + - "devtoolNamespace": "webpack", + + "devtoolNamespace": "myLib", + @@ ... @@ + - "enabledLibraryTypes": Array [], + + "enabledLibraryTypes": Array [ + + "var", + + ], + @@ ... @@ + - "hotUpdateGlobal": "webpackHotUpdatewebpack", + + "hotUpdateGlobal": "webpackHotUpdatemyLib", + @@ ... @@ + - "library": undefined, + + "library": Object { + + "amdContainer": undefined, + + "auxiliaryComment": undefined, + + "export": undefined, + + "name": Object { + + "root": Array [ + + "[name]", + + "myLib", + + ], + + }, + + "type": "var", + + "umdNamedDefine": undefined, + + }, + @@ ... @@ + - "uniqueName": "webpack", + + "uniqueName": "myLib", + `) + ); + test( + "library.name.root contains escaped placeholder", + { + output: { + library: { + name: { + root: ["[\\name\\]", "my[\\name\\]Lib[name]", "[\\name\\]"] + }, + type: "var" + } + } + }, + e => + e.toMatchInlineSnapshot(` + - Expected + + Received + + @@ ... @@ + - "chunkLoadingGlobal": "webpackChunkwebpack", + + "chunkLoadingGlobal": "webpackChunk_name_my_name_Lib_name_", + @@ ... @@ + - "devtoolNamespace": "webpack", + + "devtoolNamespace": "[name].my[name]Lib.[name]", + @@ ... @@ + - "enabledLibraryTypes": Array [], + + "enabledLibraryTypes": Array [ + + "var", + + ], + @@ ... @@ + - "hotUpdateGlobal": "webpackHotUpdatewebpack", + + "hotUpdateGlobal": "webpackHotUpdate_name_my_name_Lib_name_", + @@ ... @@ + - "library": undefined, + + "library": Object { + + "amdContainer": undefined, + + "auxiliaryComment": undefined, + + "export": undefined, + + "name": Object { + + "root": Array [ + + "[\\\\name\\\\]", + + "my[\\\\name\\\\]Lib[name]", + + "[\\\\name\\\\]", + + ], + + }, + + "type": "var", + + "umdNamedDefine": undefined, + + }, + @@ ... @@ + - "uniqueName": "webpack", + + "uniqueName": "[name].my[name]Lib.[name]", + `) + ); test("target node", { target: "node" }, e => e.toMatchInlineSnapshot(` - Expected @@ -1001,9 +1321,15 @@ describe("Defaults", () => { - "web": true, + "web": false, @@ ... @@ + - "document": true, + + "document": false, + @@ ... @@ - "target": "web", + "target": "node", @@ ... @@ + - "createRequire": false, + + "createRequire": true, + @@ ... @@ - "__dirname": "mock", - "__filename": "mock", - "global": true, @@ -1024,6 +1350,9 @@ describe("Defaults", () => { - "fetch", + "async-node", @@ ... @@ + - "document": true, + + "document": false, + @@ ... @@ - "globalObject": "self", + "globalObject": "global", @@ ... @@ @@ -1034,8 +1363,9 @@ describe("Defaults", () => { + "wasmLoading": "async-node", @@ ... @@ - "workerChunkLoading": "import-scripts", - - "workerWasmLoading": "fetch", + "workerChunkLoading": "require", + @@ ... @@ + - "workerWasmLoading": "fetch", + "workerWasmLoading": "async-node", @@ ... @@ - "aliasFields": Array [ @@ -1094,6 +1424,13 @@ describe("Defaults", () => { @@ ... @@ - "browser", @@ ... @@ + - "aliasFields": Array [ + - "browser", + - ], + + "aliasFields": Array [], + @@ ... @@ + - "browser", + @@ ... @@ - "browser", + "node", @@ ... @@ @@ -1106,12 +1443,18 @@ describe("Defaults", () => { - Expected + Received + @@ ... @@ + - "document": true, + + "document": false, @@ ... @@ - "chunkLoading": "jsonp", + "chunkLoading": "import-scripts", @@ ... @@ - "jsonp", @@ ... @@ + - "document": true, + + "document": false, + @@ ... @@ + "worker", @@ ... @@ - "target": "web", @@ -1135,9 +1478,15 @@ describe("Defaults", () => { - "web": true, + "web": false, @@ ... @@ + - "document": true, + + "document": false, + @@ ... @@ - "target": "web", + "target": "electron-main", @@ ... @@ + - "createRequire": false, + + "createRequire": true, + @@ ... @@ - "__dirname": "mock", - "__filename": "mock", - "global": true, @@ -1158,6 +1507,9 @@ describe("Defaults", () => { - "fetch", + "async-node", @@ ... @@ + - "document": true, + + "document": false, + @@ ... @@ - "globalObject": "self", + "globalObject": "global", @@ ... @@ @@ -1168,8 +1520,9 @@ describe("Defaults", () => { + "wasmLoading": "async-node", @@ ... @@ - "workerChunkLoading": "import-scripts", - - "workerWasmLoading": "fetch", + "workerChunkLoading": "require", + @@ ... @@ + - "workerWasmLoading": "fetch", + "workerWasmLoading": "async-node", @@ ... @@ - "aliasFields": Array [ @@ -1228,6 +1581,13 @@ describe("Defaults", () => { @@ ... @@ - "browser", @@ ... @@ + - "aliasFields": Array [ + - "browser", + - ], + + "aliasFields": Array [], + @@ ... @@ + - "browser", + @@ ... @@ - "browser", + "node", + "electron", @@ -1251,9 +1611,15 @@ describe("Defaults", () => { - "node": false, + "node": true, @@ ... @@ + - "document": true, + + "document": false, + @@ ... @@ - "target": "web", + "target": "electron-preload", @@ ... @@ + - "createRequire": false, + + "createRequire": true, + @@ ... @@ - "__dirname": "mock", - "__filename": "mock", - "global": true, @@ -1274,6 +1640,9 @@ describe("Defaults", () => { - "fetch", + "async-node", @@ ... @@ + - "document": true, + + "document": false, + @@ ... @@ - "globalObject": "self", + "globalObject": "global", @@ ... @@ @@ -1284,8 +1653,9 @@ describe("Defaults", () => { + "wasmLoading": "async-node", @@ ... @@ - "workerChunkLoading": "import-scripts", - - "workerWasmLoading": "fetch", + "workerChunkLoading": "require", + @@ ... @@ + - "workerWasmLoading": "fetch", + "workerWasmLoading": "async-node", @@ ... @@ - "aliasFields": Array [ @@ -1344,6 +1714,13 @@ describe("Defaults", () => { @@ ... @@ - "browser", @@ ... @@ + - "aliasFields": Array [ + - "browser", + - ], + + "aliasFields": Array [], + @@ ... @@ + - "browser", + @@ ... @@ + "node", @@ ... @@ + "electron", @@ -1367,8 +1744,8 @@ describe("Defaults", () => { + "recordsOutputPath": "some-path", `) ); - test("ecamVersion", { output: { ecmaVersion: 2020 } }, e => - e.toMatchInlineSnapshot(`Compared values have no visual difference.`) + test("ecmaVersion", { output: { ecmaVersion: 2020 } }, e => + e.toMatchInlineSnapshot("Compared values have no visual difference.") ); test("single runtimeChunk", { optimization: { runtimeChunk: "single" } }, e => e.toMatchInlineSnapshot(` @@ -1417,6 +1794,8 @@ describe("Defaults", () => { @@ ... @@ - "cache": false, + "cache": Object { + + "cacheUnaffected": false, + + "maxGenerations": Infinity, + "type": "memory", + }, @@ ... @@ @@ -1438,6 +1817,7 @@ describe("Defaults", () => { @@ ... @@ - "cache": false, + "cache": Object { + + "allowCollectingMemory": false, + "buildDependencies": Object { + "defaultWebpack": Array [ + "/lib/", @@ -1445,10 +1825,17 @@ describe("Defaults", () => { + }, + "cacheDirectory": "/node_modules/.cache/webpack", + "cacheLocation": "/node_modules/.cache/webpack/default-none", + + "compression": false, + "hashAlgorithm": "md4", + "idleTimeout": 60000, - + "idleTimeoutForInitialStore": 0, + + "idleTimeoutAfterLargeChanges": 1000, + + "idleTimeoutForInitialStore": 5000, + + "maxAge": 5184000000, + + "maxMemoryGenerations": Infinity, + + "memoryCacheUnaffected": false, + "name": "default-none", + + "profile": false, + + "readonly": false, + "store": "pack", + "type": "filesystem", + "version": "", @@ -1464,6 +1851,77 @@ describe("Defaults", () => { + "cache": true, `) ); + test( + "cache filesystem development", + { mode: "development", cache: { type: "filesystem" } }, + e => + e.toMatchInlineSnapshot(` + - Expected + + Received + + @@ ... @@ + - "cache": false, + + "cache": Object { + + "allowCollectingMemory": true, + + "buildDependencies": Object { + + "defaultWebpack": Array [ + + "/lib/", + + ], + + }, + + "cacheDirectory": "/node_modules/.cache/webpack", + + "cacheLocation": "/node_modules/.cache/webpack/default-development", + + "compression": false, + + "hashAlgorithm": "md4", + + "idleTimeout": 60000, + + "idleTimeoutAfterLargeChanges": 1000, + + "idleTimeoutForInitialStore": 5000, + + "maxAge": 5184000000, + + "maxMemoryGenerations": 5, + + "memoryCacheUnaffected": false, + + "name": "default-development", + + "profile": false, + + "readonly": false, + + "store": "pack", + + "type": "filesystem", + + "version": "", + + }, + @@ ... @@ + - "devtool": false, + + "devtool": "eval", + @@ ... @@ + - "mode": "none", + + "mode": "development", + @@ ... @@ + - "unsafeCache": false, + + "unsafeCache": [Function anonymous], + @@ ... @@ + - "chunkIds": "natural", + + "chunkIds": "named", + @@ ... @@ + - "moduleIds": "natural", + - "nodeEnv": false, + + "moduleIds": "named", + + "nodeEnv": "development", + @@ ... @@ + - "minRemainingSize": undefined, + + "minRemainingSize": 0, + @@ ... @@ + - "cssHeadDataCompression": true, + + "cssHeadDataCompression": false, + @@ ... @@ + - "pathinfo": false, + + "pathinfo": true, + @@ ... @@ + - "cache": false, + + "cache": true, + @@ ... @@ + - "production", + + "development", + @@ ... @@ + - "cache": false, + + "cache": true, + `) + ); test( "disable", @@ -1517,7 +1975,7 @@ describe("Defaults", () => { - "minChunks": 1, - "minRemainingSize": undefined, - "minSize": 10000, - - "usedExports": true, + - "usedExports": false, - }, + "splitChunks": false, `) @@ -1527,7 +1985,8 @@ describe("Defaults", () => { "uniqueName", { output: { - uniqueName: "@@@Hello World!" + uniqueName: "@@@Hello World!", + trustedTypes: true } }, e => @@ -1545,7 +2004,12 @@ describe("Defaults", () => { - "hotUpdateGlobal": "webpackHotUpdatewebpack", + "hotUpdateGlobal": "webpackHotUpdate_Hello_World_", @@ ... @@ + - "trustedTypes": undefined, - "uniqueName": "webpack", + + "trustedTypes": Object { + + "onPolicyCreationFailure": "stop", + + "policyName": "@@@Hello_World_", + + }, + "uniqueName": "@@@Hello World!", `) ); @@ -1601,6 +2065,34 @@ describe("Defaults", () => { - "context": "", + "context": "/test/fixtures/browserslist", @@ ... @@ + - "arrowFunction": true, + - "asyncFunction": true, + - "bigIntLiteral": true, + - "const": true, + - "destructuring": true, + + "arrowFunction": false, + + "asyncFunction": false, + + "bigIntLiteral": false, + + "const": false, + + "destructuring": false, + @@ ... @@ + - "dynamicImport": undefined, + - "dynamicImportInWorker": undefined, + - "forOf": true, + - "globalThis": undefined, + - "module": undefined, + - "nodePrefixForCoreModules": true, + - "optionalChaining": true, + - "templateLiteral": true, + + "dynamicImport": false, + + "dynamicImportInWorker": false, + + "forOf": false, + + "globalThis": false, + + "module": false, + + "nodePrefixForCoreModules": false, + + "optionalChaining": false, + + "templateLiteral": false, + @@ ... @@ - "chunkLoadingGlobal": "webpackChunkwebpack", + "chunkLoadingGlobal": "webpackChunkbrowserslist_test", @@ ... @@ @@ -1608,19 +2100,32 @@ describe("Defaults", () => { + "devtoolNamespace": "browserslist-test", @@ ... @@ - "arrowFunction": true, - - "bigIntLiteral": undefined, + - "asyncFunction": true, + - "bigIntLiteral": true, - "const": true, - "destructuring": true, - - "dynamicImport": undefined, - - "forOf": true, - - "module": undefined, + "arrowFunction": false, + + "asyncFunction": false, + "bigIntLiteral": false, + "const": false, + "destructuring": false, + @@ ... @@ + - "dynamicImport": undefined, + - "dynamicImportInWorker": undefined, + - "forOf": true, + - "globalThis": undefined, + - "module": undefined, + - "nodePrefixForCoreModules": true, + - "optionalChaining": true, + - "templateLiteral": true, + "dynamicImport": false, + + "dynamicImportInWorker": false, + "forOf": false, + + "globalThis": false, + "module": false, + + "nodePrefixForCoreModules": false, + + "optionalChaining": false, + + "templateLiteral": false, @@ ... @@ - "hotUpdateGlobal": "webpackHotUpdatewebpack", + "hotUpdateGlobal": "webpackHotUpdatebrowserslist_test", @@ -1652,6 +2157,7 @@ describe("Defaults", () => { - "cache": false, - "context": "", + "cache": Object { + + "allowCollectingMemory": false, + "buildDependencies": Object { + "defaultWebpack": Array [ + "/lib/", @@ -1659,10 +2165,17 @@ describe("Defaults", () => { + }, + "cacheDirectory": "/node_modules/.cache/webpack", + "cacheLocation": "/node_modules/.cache/webpack/default-none", + + "compression": false, + "hashAlgorithm": "md4", + "idleTimeout": 60000, - + "idleTimeoutForInitialStore": 0, + + "idleTimeoutAfterLargeChanges": 1000, + + "idleTimeoutForInitialStore": 5000, + + "maxAge": 5184000000, + + "maxMemoryGenerations": Infinity, + + "memoryCacheUnaffected": false, + "name": "default-none", + + "profile": false, + + "readonly": false, + "store": "pack", + "type": "filesystem", + "version": "", @@ -1723,4 +2236,244 @@ describe("Defaults", () => { + "async-node", `) ); + + test( + "experiments.futureDefaults", + { + experiments: { + futureDefaults: true + } + }, + e => + e.toMatchInlineSnapshot(` + - Expected + + Received + + @@ ... @@ + - "asyncWebAssembly": false, + - "backCompat": true, + + "asyncWebAssembly": true, + + "backCompat": false, + @@ ... @@ + - "cacheUnaffected": false, + - "css": undefined, + - "futureDefaults": false, + + "cacheUnaffected": true, + + "css": true, + + "futureDefaults": true, + @@ ... @@ + + }, + + Object { + + "rules": Array [ + + Object { + + "descriptionData": Object { + + "type": "module", + + }, + + "resolve": Object { + + "fullySpecified": true, + + }, + + }, + + ], + + "test": /\\.wasm$/i, + + "type": "webassembly/async", + + }, + + Object { + + "mimetype": "application/wasm", + + "rules": Array [ + + Object { + + "descriptionData": Object { + + "type": "module", + + }, + + "resolve": Object { + + "fullySpecified": true, + + }, + + }, + + ], + + "type": "webassembly/async", + + }, + + Object { + + "resolve": Object { + + "fullySpecified": true, + + "preferRelative": true, + + }, + + "test": /\\.css$/i, + + "type": "css/auto", + + }, + + Object { + + "mimetype": "text/css+module", + + "resolve": Object { + + "fullySpecified": true, + + "preferRelative": true, + + }, + + "type": "css/module", + + }, + + Object { + + "mimetype": "text/css", + + "resolve": Object { + + "fullySpecified": true, + + "preferRelative": true, + @@ ... @@ + + "type": "css", + + }, + @@ ... @@ + - "generator": Object {}, + + "generator": Object { + + "css": Object { + + "esModule": true, + + "exportsOnly": false, + + }, + + "css/auto": Object { + + "exportsConvention": "as-is", + + "localIdentName": "[uniqueName]-[id]-[local]", + + }, + + "css/global": Object { + + "exportsConvention": "as-is", + + "localIdentName": "[uniqueName]-[id]-[local]", + + }, + + "css/module": Object { + + "exportsConvention": "as-is", + + "localIdentName": "[uniqueName]-[id]-[local]", + + }, + + }, + @@ ... @@ + + }, + + "css": Object { + + "namedExports": true, + @@ ... @@ + + "exportsPresence": "error", + @@ ... @@ + - "__dirname": "mock", + - "__filename": "mock", + - "global": true, + + "__dirname": "warn-mock", + + "__filename": "warn-mock", + + "global": "warn", + @@ ... @@ + + "css", + @@ ... @@ + - "hashDigestLength": 20, + - "hashFunction": "md4", + + "hashDigestLength": 16, + + "hashFunction": "xxhash64", + @@ ... @@ + + "css-import": Object { + + "conditionNames": Array [ + + "webpack", + + "production", + + "style", + + ], + + "extensions": Array [ + + ".css", + + ], + + "mainFields": Array [ + + "style", + + "...", + + ], + + "mainFiles": Array [], + + "preferRelative": true, + + }, + @@ ... @@ + - "/node_modules/", + + /^(.+?[\\\\/]node_modules[\\\\/])/, + `) + ); + + test( + "experiments.futureDefaults w/ experiments.css disabled", + { + experiments: { + css: false, + futureDefaults: true + } + }, + e => + e.toMatchInlineSnapshot(` + - Expected + + Received + + @@ ... @@ + - "asyncWebAssembly": false, + - "backCompat": true, + + "asyncWebAssembly": true, + + "backCompat": false, + @@ ... @@ + - "cacheUnaffected": false, + - "css": undefined, + - "futureDefaults": false, + + "cacheUnaffected": true, + + "css": false, + + "futureDefaults": true, + @@ ... @@ + + Object { + + "rules": Array [ + @@ ... @@ + + "descriptionData": Object { + + "type": "module", + + }, + + "resolve": Object { + + "fullySpecified": true, + + }, + + }, + + ], + + "test": /\\.wasm$/i, + + "type": "webassembly/async", + + }, + + Object { + + "mimetype": "application/wasm", + + "rules": Array [ + + Object { + + "descriptionData": Object { + + "type": "module", + + }, + + "resolve": Object { + + "fullySpecified": true, + + }, + + }, + + ], + + "type": "webassembly/async", + + }, + + Object { + @@ ... @@ + + "exportsPresence": "error", + @@ ... @@ + - "__dirname": "mock", + - "__filename": "mock", + - "global": true, + + "__dirname": "warn-mock", + + "__filename": "warn-mock", + + "global": "warn", + @@ ... @@ + - "hashDigestLength": 20, + - "hashFunction": "md4", + + "hashDigestLength": 16, + + "hashFunction": "xxhash64", + @@ ... @@ + - "/node_modules/", + + /^(.+?[\\\\/]node_modules[\\\\/])/, + `) + ); +}); + +it("should result in the same target options for same target", () => { + const inlineTarget = getDefaultConfig({ target: "node12.17" }); + const browserslistTarget = getDefaultConfig({ + target: "browserslist: node 12.17" + }); + const diff = stripAnsi( + jestDiff(inlineTarget, browserslistTarget, { + expand: false, + contextLines: 0 + }) + ); + + expect(inlineTarget.output.environment.module).toBe(true); + expect(inlineTarget.output.environment.dynamicImport).toBe(true); + expect(new Diff(diff)).toMatchInlineSnapshot(` + - Expected + + Received + + @@ ... @@ + - "target": "node12.17", + + "target": "browserslist: node 12.17", + `); }); diff --git a/test/Errors.test.js b/test/Errors.test.js index 14c52beecb7..ca74eafa946 100644 --- a/test/Errors.test.js +++ b/test/Errors.test.js @@ -1,9 +1,11 @@ "use strict"; +require("./helpers/warmup-webpack"); + const path = require("path"); const fs = require("graceful-fs"); const webpack = require(".."); -const prettyFormat = require("pretty-format"); +const prettyFormat = require("pretty-format").default; const CWD_PATTERN = new RegExp(process.cwd().replace(/\\/g, "/"), "gm"); const ERROR_STACK_PATTERN = /(?:\n\s+at\s.*)+/gm; @@ -114,7 +116,7 @@ async function compile(options) { }); }); } catch (err) { - // capture sync throwm errors + // capture sync thrown errors reject(err); } }); @@ -159,7 +161,7 @@ it("should emit warning for missingFile", async () => { "warnings": Array [], } `); -}); +}, 20000); it("should emit warning for require.extensions", async () => { await expect(compile({ entry: "./require.extensions" })).resolves @@ -311,30 +313,30 @@ it("should emit no errors or warnings for no-errors-deprecate", async () => { it("should emit errors for missingFile for production", async () => { await expect(compile({ mode: "production", entry: "./missingFile" })).resolves .toMatchInlineSnapshot(` - Object { - "errors": Array [ - Object { - "loc": "4:0-20", - "message": "Module not found: Error: Can't resolve './missing' in '/test/fixtures/errors'", - "moduleId": 814, - "moduleIdentifier": "/test/fixtures/errors/missingFile.js", - "moduleName": "./missingFile.js", - "moduleTrace": Array [], - "stack": "ModuleNotFoundError: Module not found: Error: Can't resolve './missing' in '/test/fixtures/errors'", - }, - Object { - "loc": "12:9-34", - "message": "Module not found: Error: Can't resolve './dir/missing2' in '/test/fixtures/errors'", - "moduleId": 814, - "moduleIdentifier": "/test/fixtures/errors/missingFile.js", - "moduleName": "./missingFile.js", - "moduleTrace": Array [], - "stack": "ModuleNotFoundError: Module not found: Error: Can't resolve './dir/missing2' in '/test/fixtures/errors'", - }, - ], - "warnings": Array [], - } - `); + Object { + "errors": Array [ + Object { + "loc": "4:0-20", + "message": "Module not found: Error: Can't resolve './missing' in '/test/fixtures/errors'", + "moduleId": 915, + "moduleIdentifier": "/test/fixtures/errors/missingFile.js", + "moduleName": "./missingFile.js", + "moduleTrace": Array [], + "stack": "ModuleNotFoundError: Module not found: Error: Can't resolve './missing' in '/test/fixtures/errors'", + }, + Object { + "loc": "12:9-34", + "message": "Module not found: Error: Can't resolve './dir/missing2' in '/test/fixtures/errors'", + "moduleId": 915, + "moduleIdentifier": "/test/fixtures/errors/missingFile.js", + "moduleName": "./missingFile.js", + "moduleTrace": Array [], + "stack": "ModuleNotFoundError: Module not found: Error: Can't resolve './dir/missing2' in '/test/fixtures/errors'", + }, + ], + "warnings": Array [], + } + `); }); it("should emit module build errors", async () => { @@ -642,6 +644,7 @@ describe("loaders", () => { `); }); + // cspell:ignore doesnt it("should emit error for doesnt-exist-loader", async () => { await expect(compile({ entry: "./doesnt-exist-loader!./entry-point.js" })) .resolves.toMatchInlineSnapshot(` diff --git a/test/Examples.test.js b/test/Examples.test.js index 747dc503c73..ead02675700 100644 --- a/test/Examples.test.js +++ b/test/Examples.test.js @@ -1,62 +1,69 @@ "use strict"; -/* describe it */ +require("./helpers/warmup-webpack"); + const path = require("path"); const fs = require("graceful-fs"); -const webpack = require(".."); describe("Examples", () => { const basePath = path.join(__dirname, "..", "examples"); const examples = require("../examples/examples.js"); - examples.forEach(examplePath => { + for (const examplePath of examples) { const filterPath = path.join(examplePath, "test.filter.js"); const relativePath = path.relative(basePath, examplePath); if (fs.existsSync(filterPath) && !require(filterPath)()) { - describe.skip(relativePath, () => it("filtered")); - return; + // eslint-disable-next-line jest/no-disabled-tests, jest/valid-describe-callback + describe.skip(relativePath, () => + it("filtered", done => { + done(); + }) + ); + continue; } - it( - "should compile " + relativePath, - function (done) { - let options = {}; - let webpackConfigPath = path.join(examplePath, "webpack.config.js"); - webpackConfigPath = - webpackConfigPath.substr(0, 1).toUpperCase() + - webpackConfigPath.substr(1); - if (fs.existsSync(webpackConfigPath)) - options = require(webpackConfigPath); - if (typeof options === "function") options = options(); - if (Array.isArray(options)) options.forEach(processOptions); - else processOptions(options); + it(`should compile ${relativePath}`, function (done) { + let options = {}; + let webpackConfigPath = path.join(examplePath, "webpack.config.js"); + webpackConfigPath = + webpackConfigPath.slice(0, 1).toUpperCase() + + webpackConfigPath.slice(1); + if (fs.existsSync(webpackConfigPath)) + options = require(webpackConfigPath); + if (typeof options === "function") options = options(); + if (Array.isArray(options)) { + for (const [_, item] of options.entries()) { + processOptions(item); + } + } else { + processOptions(options); + } - function processOptions(options) { - options.context = examplePath; - options.output = options.output || {}; - options.output.pathinfo = true; - options.output.path = path.join(examplePath, "dist"); - options.output.publicPath = "dist/"; - if (!options.entry) options.entry = "./example.js"; - if (!options.plugins) options.plugins = []; + function processOptions(options) { + options.context = examplePath; + options.output = options.output || {}; + options.output.pathinfo = true; + options.output.path = path.join(examplePath, "dist"); + options.output.publicPath = "dist/"; + if (!options.entry) options.entry = "./example.js"; + if (!options.plugins) options.plugins = []; + } + const webpack = require(".."); + webpack(options, (err, stats) => { + if (err) return done(err); + if (stats.hasErrors()) { + return done( + new Error( + stats.toString({ + all: false, + errors: true, + errorDetails: true, + errorStacks: true + }) + ) + ); } - webpack(options, (err, stats) => { - if (err) return done(err); - if (stats.hasErrors()) { - return done( - new Error( - stats.toString({ - all: false, - errors: true, - errorDetails: true, - errorStacks: true - }) - ) - ); - } - done(); - }); - }, - 90000 - ); - }); + done(); + }); + }, 90000); + } }); diff --git a/test/FileSystemInfo.unittest.js b/test/FileSystemInfo.unittest.js new file mode 100644 index 00000000000..21d37d9ff80 --- /dev/null +++ b/test/FileSystemInfo.unittest.js @@ -0,0 +1,436 @@ +"use strict"; + +const { createFsFromVolume, Volume } = require("memfs"); +const util = require("util"); +const FileSystemInfo = require("../lib/FileSystemInfo"); +const { buffersSerializer } = require("../lib/util/serialization"); + +describe("FileSystemInfo", () => { + const files = [ + "/path/file.txt", + "/path/nested/deep/file.txt", + "/path/nested/deep/ignored.txt", + "/path/context+files/file.txt", + "/path/context+files/sub/file.txt", + "/path/context+files/sub/ignored.txt", + "/path/node_modules/package/file.txt", + "/path/cache/package-1234/file.txt", + "/path/circular/circular/file2.txt", + "/path/nested/deep/symlink/file.txt", + "/path/context+files/sub/symlink/file.txt", + "/path/context/sub/symlink/file.txt", + "/path/missing.txt", + "/path/node_modules/@foo/package1/index.js", + "/path/node_modules/@foo/package2/index.js", + "/path/node_modules/bar-package3/index.js" + ]; + const directories = [ + "/path/context+files", + "/path/context", + "/path/missing", + "/path/node_modules/package", + "/path/node_modules/missing", + "/path/node_modules/@foo", + "/path/node_modules/@foo/package1", + "/path/node_modules/@foo/package2", + "/path/node_modules/bar-package3", + "/path/cache/package-1234", + "/path/cache/package-missing" + ]; + const missing = [ + "/path/package.json", + "/path/file2.txt", + "/path/context+files/file2.txt", + "/path/node_modules/package.txt", + "/path/node_modules/package/missing.txt", + "/path/cache/package-2345", + "/path/cache/package-1234/missing.txt", + "/path/ignored.txt" + ]; + const ignored = [ + "/path/nested/deep/ignored.txt", + "/path/context+files/sub/ignored.txt", + "/path/context/sub/ignored.txt", + "/path/ignored.txt", + "/path/node_modules/package/ignored.txt", + "/path/cache/package-1234/ignored.txt" + ]; + const unmanagedPaths = [ + "/path/node_modules/@foo/package1", + "/path/node_modules/@foo/package2", + "/path/node_modules/bar-package3" + ]; + const managedPaths = ["/path/node_modules"]; + const immutablePaths = ["/path/cache"]; + const createFs = () => { + const fs = createFsFromVolume(new Volume()); + fs.mkdirSync("/path/context+files/sub", { recursive: true }); + fs.mkdirSync("/path/context/sub", { recursive: true }); + fs.mkdirSync("/path/nested/deep", { recursive: true }); + fs.mkdirSync("/path/node_modules/package", { recursive: true }); + fs.mkdirSync("/path/node_modules/@foo", { recursive: true }); + fs.mkdirSync("/path/node_modules/@foo/package1", { recursive: true }); + fs.mkdirSync("/path/node_modules/@foo/package2", { recursive: true }); + fs.mkdirSync("/path/node_modules/bar-package3", { recursive: true }); + fs.mkdirSync("/path/cache/package-1234", { recursive: true }); + fs.mkdirSync("/path/folder/context", { recursive: true }); + fs.mkdirSync("/path/folder/context+files", { recursive: true }); + fs.mkdirSync("/path/folder/nested", { recursive: true }); + fs.writeFileSync("/path/file.txt", "Hello World"); + fs.writeFileSync("/path/file2.txt", "Hello World2"); + fs.writeFileSync("/path/nested/deep/file.txt", "Hello World"); + fs.writeFileSync("/path/nested/deep/ignored.txt", "Ignored"); + fs.writeFileSync("/path/context+files/file.txt", "Hello World"); + fs.writeFileSync("/path/context+files/file2.txt", "Hello World2"); + fs.writeFileSync("/path/context+files/sub/file.txt", "Hello World"); + fs.writeFileSync("/path/context+files/sub/file2.txt", "Hello World2"); + fs.writeFileSync("/path/context+files/sub/file3.txt", "Hello World3"); + fs.writeFileSync("/path/context+files/sub/ignored.txt", "Ignored"); + fs.writeFileSync("/path/context/file.txt", "Hello World"); + fs.writeFileSync("/path/context/file2.txt", "Hello World2"); + fs.writeFileSync("/path/context/sub/file.txt", "Hello World"); + fs.writeFileSync("/path/context/sub/file2.txt", "Hello World2"); + fs.writeFileSync("/path/context/sub/file3.txt", "Hello World3"); + fs.writeFileSync("/path/context/sub/ignored.txt", "Ignored"); + fs.writeFileSync( + "/path/node_modules/package/package.json", + JSON.stringify({ name: "package", version: "1.0.0" }) + ); + fs.writeFileSync("/path/node_modules/package/file.txt", "Hello World"); + fs.writeFileSync("/path/node_modules/package/ignored.txt", "Ignored"); + fs.writeFileSync( + "/path/cache/package-1234/package.json", + JSON.stringify({ name: "package", version: "1.0.0" }) + ); + fs.writeFileSync("/path/cache/package-1234/file.txt", "Hello World"); + fs.writeFileSync("/path/cache/package-1234/ignored.txt", "Ignored"); + fs.symlinkSync("/path", "/path/circular", "dir"); + fs.writeFileSync("/path/folder/context/file.txt", "Hello World"); + fs.writeFileSync("/path/folder/context+files/file.txt", "Hello World"); + fs.writeFileSync("/path/folder/nested/file.txt", "Hello World"); + fs.writeFileSync( + "/path/node_modules/@foo/package1/index.js", + "Hello World" + ); + fs.writeFileSync( + "/path/node_modules/@foo/package2/index.js", + "Hello World" + ); + fs.writeFileSync("/path/node_modules/bar-package3/index.js", "Hello World"); + fs.symlinkSync("/path/folder/context", "/path/context/sub/symlink", "dir"); + fs.symlinkSync( + "/path/folder/context+files", + "/path/context+files/sub/symlink", + "dir" + ); + fs.symlinkSync("/path/folder/nested", "/path/nested/deep/symlink", "dir"); + return fs; + }; + + const createFsInfo = fs => { + const logger = { + error: (...args) => { + throw new Error(util.format(...args)); + } + }; + const fsInfo = new FileSystemInfo(fs, { + logger, + unmanagedPaths, + managedPaths, + immutablePaths, + hashFunction: "sha256" + }); + for (const method of ["warn", "info", "log", "debug"]) { + fsInfo.logs = []; + fsInfo[method] = []; + logger[method] = (...args) => { + const msg = util.format(...args); + fsInfo[method].push(msg); + fsInfo.logs.push(`[${method}] ${msg}`); + }; + } + fsInfo.addFileTimestamps(new Map(ignored.map(i => [i, "ignore"]))); + return fsInfo; + }; + + const createSnapshot = (fs, options, callback) => { + const fsInfo = createFsInfo(fs); + fsInfo.createSnapshot( + Date.now() + 10000, + files, + directories, + missing, + options, + (err, snapshot) => { + if (err) return callback(err); + snapshot.name = "initial snapshot"; + // create another one to test the caching + fsInfo.createSnapshot( + Date.now() + 10000, + files, + directories, + missing, + options, + (err, snapshot2) => { + if (err) return callback(err); + snapshot2.name = "cached snapshot"; + callback(null, snapshot, snapshot2); + } + ); + } + ); + }; + + const clone = object => { + const serialized = buffersSerializer.serialize(object, {}); + return buffersSerializer.deserialize(serialized, {}); + }; + + const expectSnapshotsState = ( + fs, + snapshot, + snapshot2, + expected, + callback + ) => { + expectSnapshotState(fs, snapshot, expected, err => { + if (err) return callback(err); + if (!snapshot2) return callback(); + expectSnapshotState(fs, snapshot2, expected, callback); + }); + }; + + const expectSnapshotState = (fs, snapshot, expected, callback) => { + const fsInfo = createFsInfo(fs); + const details = snapshot => `${fsInfo.logs.join("\n")} +${util.inspect(snapshot, false, Infinity, true)}`; + fsInfo.checkSnapshotValid(snapshot, (err, valid) => { + if (err) return callback(err); + if (valid !== expected) { + return callback( + new Error(`Expected snapshot to be ${ + expected ? "valid" : "invalid" + } but it is ${valid ? "valid" : "invalid"}: +${details(snapshot)}`) + ); + } + // Another try to check if direct caching works + fsInfo.checkSnapshotValid(snapshot, (err, valid) => { + if (err) return callback(err); + if (valid !== expected) { + return callback( + new Error(`Expected snapshot lead to the same result when directly cached: +${details(snapshot)}`) + ); + } + // Another try to check if indirect caching works + fsInfo.checkSnapshotValid(clone(snapshot), (err, valid) => { + if (err) return callback(err); + if (valid !== expected) { + return callback( + new Error(`Expected snapshot lead to the same result when indirectly cached: +${details(snapshot)}`) + ); + } + callback(); + }); + }); + }); + }; + + const updateFile = (fs, filename) => { + const oldContent = fs.readFileSync(filename, "utf-8"); + if (filename.endsWith(".json")) { + const data = JSON.parse(oldContent); + fs.writeFileSync( + filename, + JSON.stringify({ + ...data, + version: `${data.version}.1` + }) + ); + } else { + fs.writeFileSync(filename, `${oldContent}!`); + } + }; + + for (const [name, options] of [ + ["timestamp", { timestamp: true }], + ["hash", { hash: true }], + ["tsh", { timestamp: true, hash: true }] + ]) { + describe(`${name} mode`, () => { + it("should always accept an empty snapshot", done => { + const fs = createFs(); + const fsInfo = createFsInfo(fs); + fsInfo.createSnapshot( + Date.now() + 10000, + [], + [], + [], + options, + (err, snapshot) => { + if (err) return done(err); + const fs = createFs(); + expectSnapshotState(fs, snapshot, true, done); + } + ); + }); + + it("should accept a snapshot when fs is unchanged", done => { + const fs = createFs(); + createSnapshot(fs, options, (err, snapshot, snapshot2) => { + if (err) return done(err); + expectSnapshotsState(fs, snapshot, snapshot2, true, done); + }); + }); + + const ignoredFileChanges = [ + "/path/nested/deep/ignored.txt", + "/path/context+files/sub/ignored.txt" + ]; + + for (const fileChange of [ + "/path/file.txt", + "/path/file2.txt", + "/path/nested/deep/file.txt", + "/path/context+files/file.txt", + "/path/context+files/file2.txt", + "/path/context+files/sub/file.txt", + "/path/context+files/sub/file2.txt", + "/path/context+files/sub/file3.txt", + "/path/context/file.txt", + "/path/context/file2.txt", + "/path/context/sub/file.txt", + "/path/context/sub/file2.txt", + "/path/context/sub/file3.txt", + "/path/node_modules/package/package.json", + "/path/folder/context/file.txt", + "/path/folder/context+files/file.txt", + "/path/folder/nested/file.txt", + "/path/node_modules/@foo/package1/index.js", + "/path/node_modules/@foo/package2/index.js", + "/path/node_modules/bar-package3/index.js", + ...(name !== "timestamp" ? ignoredFileChanges : []), + ...(name === "hash" ? ["/path/context/sub/ignored.txt"] : []) + ]) { + it(`should invalidate the snapshot when ${fileChange} is changed`, done => { + const fs = createFs(); + createSnapshot(fs, options, (err, snapshot, snapshot2) => { + if (err) return done(err); + updateFile(fs, fileChange); + expectSnapshotsState(fs, snapshot, snapshot2, false, done); + }); + }); + } + + for (const fileChange of [ + "/path/node_modules/package/file.txt", + "/path/node_modules/package/ignored.txt", + "/path/cache/package-1234/package.json", + "/path/cache/package-1234/file.txt", + "/path/cache/package-1234/ignored.txt", + ...(name === "timestamp" ? ignoredFileChanges : []), + ...(name !== "hash" ? ["/path/context/sub/ignored.txt"] : []) + ]) { + it(`should not invalidate the snapshot when ${fileChange} is changed`, done => { + const fs = createFs(); + createSnapshot(fs, options, (err, snapshot, snapshot2) => { + if (err) return done(err); + updateFile(fs, fileChange); + expectSnapshotsState(fs, snapshot, snapshot2, true, done); + }); + }); + } + + for (const newFile of [ + "/path/package.json", + "/path/file2.txt", + "/path/context+files/file2.txt", + "/path/node_modules/package.txt" + ]) { + it(`should invalidate the snapshot when ${newFile} is created`, done => { + const fs = createFs(); + createSnapshot(fs, options, (err, snapshot, snapshot2) => { + if (err) return done(err); + fs.writeFileSync(newFile, "New file"); + expectSnapshotsState(fs, snapshot, snapshot2, false, done); + }); + }); + } + + for (const newFile of [ + "/path/node_modules/package/missing.txt", + "/path/cache/package-1234/missing.txt", + "/path/cache/package-2345", + "/path/ignored.txt" + ]) { + it(`should not invalidate the snapshot when ${newFile} is created`, done => { + const fs = createFs(); + createSnapshot(fs, options, (err, snapshot, snapshot2) => { + if (err) return done(err); + fs.writeFileSync(newFile, "New file"); + expectSnapshotsState(fs, snapshot, snapshot2, true, done); + }); + }); + } + + if (name !== "timestamp") { + it("should not invalidate snapshot when only timestamps have changed", done => { + const fs = createFs(); + createSnapshot(fs, options, (err, snapshot, snapshot2) => { + if (err) return done(err); + const fs = createFs(); + expectSnapshotsState(fs, snapshot, snapshot2, true, done); + }); + }); + } + }); + } + + describe("stable iterables identity", () => { + const options = { timestamp: true }; + + /** + * @param {function((WebpackError | null)=, (Snapshot | null)=): void} callback callback function + */ + function getSnapshot(callback) { + const fs = createFs(); + const fsInfo = createFsInfo(fs); + fsInfo.createSnapshot( + Date.now() + 10000, + files, + directories, + missing, + options, + callback + ); + } + + it("should return same iterable for getFileIterable()", done => { + getSnapshot((err, snapshot) => { + if (err) done(err); + expect(snapshot.getFileIterable()).toEqual(snapshot.getFileIterable()); + done(); + }); + }); + + it("should return same iterable for getContextIterable()", done => { + getSnapshot((err, snapshot) => { + if (err) done(err); + expect(snapshot.getContextIterable()).toEqual( + snapshot.getContextIterable() + ); + done(); + }); + }); + + it("should return same iterable for getMissingIterable()", done => { + getSnapshot((err, snapshot) => { + if (err) done(err); + expect(snapshot.getFileIterable()).toEqual(snapshot.getFileIterable()); + done(); + }); + }); + }); +}); diff --git a/test/HotModuleReplacementPlugin.test.js b/test/HotModuleReplacementPlugin.test.js index dd3fb6c4907..b84d8242b3d 100644 --- a/test/HotModuleReplacementPlugin.test.js +++ b/test/HotModuleReplacementPlugin.test.js @@ -36,12 +36,12 @@ describe("HotModuleReplacementPlugin", () => { fs.mkdirSync(path.join(__dirname, "js", "HotModuleReplacementPlugin"), { recursive: true }); - } catch (e) { + } catch (_err) { // empty } try { fs.unlinkSync(recordsFile); - } catch (e) { + } catch (_err) { // empty } const compiler = webpack({ @@ -99,6 +99,81 @@ describe("HotModuleReplacementPlugin", () => { }); }, 120000); + it("output.clean=true should keep 1 last update", done => { + const outputPath = path.join(__dirname, "js", "HotModuleReplacementPlugin"); + const entryFile = path.join(outputPath, "entry.js"); + const recordsFile = path.join(outputPath, "records.json"); + let step = 0; + let firstUpdate; + try { + fs.mkdirSync(outputPath, { recursive: true }); + } catch (_err) { + // empty + } + fs.writeFileSync(entryFile, `${++step}`, "utf-8"); + const updates = new Set(); + const hasFile = file => { + try { + fs.statSync(path.join(outputPath, file)); + return true; + } catch (_err) { + return false; + } + }; + const compiler = webpack({ + mode: "development", + cache: false, + entry: { + 0: entryFile + }, + recordsPath: recordsFile, + output: { + path: outputPath, + clean: true + }, + plugins: [new webpack.HotModuleReplacementPlugin()] + }); + const callback = (err, stats) => { + if (err) return done(err); + const jsonStats = stats.toJson(); + const hash = jsonStats.hash; + const hmrUpdateMainFileName = `0.${hash}.hot-update.json`; + + switch (step) { + case 1: + expect(updates.size).toBe(0); + firstUpdate = hmrUpdateMainFileName; + break; + case 2: + expect(updates.size).toBe(1); + expect(updates.has(firstUpdate)).toBe(true); + expect(hasFile(firstUpdate)).toBe(true); + break; + case 3: + expect(updates.size).toBe(2); + for (const file of updates) { + expect(hasFile(file)).toBe(true); + } + return setTimeout(() => { + fs.writeFileSync(entryFile, `${++step}`, "utf-8"); + compiler.run(err => { + if (err) return done(err); + for (const file of updates) { + expect(hasFile(file)).toBe(false); + } + done(); + }); + }, 10100); + } + + updates.add(hmrUpdateMainFileName); + fs.writeFileSync(entryFile, `${++step}`, "utf-8"); + compiler.run(callback); + }; + + compiler.run(callback); + }, 20000); + it("should correct working when entry is Object and key is a number", done => { const outputPath = path.join(__dirname, "js", "HotModuleReplacementPlugin"); const entryFile = path.join(outputPath, "entry.js"); @@ -113,12 +188,12 @@ describe("HotModuleReplacementPlugin", () => { const recordsFile = path.join(outputPath, "records.json"); try { fs.mkdirSync(outputPath, { recursive: true }); - } catch (e) { + } catch (_err) { // empty } try { fs.unlinkSync(recordsFile); - } catch (e) { + } catch (_err) { // empty } const compiler = webpack({ @@ -155,7 +230,7 @@ describe("HotModuleReplacementPlugin", () => { path.join(outputPath, `0.${hash}.hot-update.json`), "utf-8" ) - )["c"]; + ).c; expect(result).toEqual([chunkName]); done(); }); @@ -196,12 +271,12 @@ describe("HotModuleReplacementPlugin", () => { recursive: true } ); - } catch (e) { + } catch (_err) { // empty } try { fs.unlinkSync(recordsFile); - } catch (e) { + } catch (_err) { // empty } const compiler = webpack({ @@ -237,13 +312,15 @@ describe("HotModuleReplacementPlugin", () => { let foundUpdates = false; - Object.keys(stats.compilation.assets).forEach(key => { + for (const key of Object.keys(stats.compilation.assets)) { foundUpdates = foundUpdates || - !!key.match( - /static\/webpack\/\[name\]\/entry\.js\..*?\.hot-update\.js/ + Boolean( + /static\/webpack\/\[name\]\/entry\.js\..*?\.hot-update\.js/.test( + key + ) ); - }); + } expect(foundUpdates).toBe(true); done(); diff --git a/test/HotTestCases.template.js b/test/HotTestCases.template.js index 8fe3e4657d7..607fdecfd23 100644 --- a/test/HotTestCases.template.js +++ b/test/HotTestCases.template.js @@ -1,5 +1,7 @@ "use strict"; +require("./helpers/warmup-webpack"); + const path = require("path"); const fs = require("graceful-fs"); const vm = require("vm"); @@ -7,327 +9,323 @@ const rimraf = require("rimraf"); const checkArrayExpectation = require("./checkArrayExpectation"); const createLazyTestEnv = require("./helpers/createLazyTestEnv"); -const webpack = require(".."); - const casesPath = path.join(__dirname, "hotCases"); let categories = fs .readdirSync(casesPath) .filter(dir => fs.statSync(path.join(casesPath, dir)).isDirectory()); -categories = categories.map(cat => { - return { - name: cat, - tests: fs - .readdirSync(path.join(casesPath, cat)) - .filter(folder => folder.indexOf("_") < 0) - }; -}); +categories = categories.map(cat => ({ + name: cat, + tests: fs + .readdirSync(path.join(casesPath, cat)) + .filter(folder => !folder.includes("_")) +})); const describeCases = config => { describe(config.name, () => { - categories.forEach(category => { + for (const category of categories) { describe(category.name, () => { - category.tests.forEach(testName => { + for (const testName of category.tests) { const testDirectory = path.join(casesPath, category.name, testName); const filterPath = path.join(testDirectory, "test.filter.js"); - if (fs.existsSync(filterPath) && !require(filterPath)()) { + if (fs.existsSync(filterPath) && !require(filterPath)(config)) { + // eslint-disable-next-line jest/no-disabled-tests describe.skip(testName, () => { it("filtered", () => {}); }); - return; + continue; } describe(testName, () => { let compiler; afterAll(callback => { compiler.close(callback); + compiler = undefined; }); - it( - testName + " should compile", - done => { - const outputDirectory = path.join( + it(`${testName} should compile`, done => { + const webpack = require(".."); + const outputDirectory = path.join( + __dirname, + "js", + `hot-cases-${config.name}`, + category.name, + testName + ); + rimraf.sync(outputDirectory); + const recordsPath = path.join(outputDirectory, "records.json"); + const fakeUpdateLoaderOptions = { + updateIndex: 0 + }; + const configPath = path.join(testDirectory, "webpack.config.js"); + let options = {}; + if (fs.existsSync(configPath)) options = require(configPath); + if (typeof options === "function") { + options = options({ config }); + } + if (!options.mode) options.mode = "development"; + if (!options.devtool) options.devtool = false; + if (!options.context) options.context = testDirectory; + if (!options.entry) options.entry = "./index.js"; + if (!options.output) options.output = {}; + if (!options.output.path) options.output.path = outputDirectory; + if (!options.output.filename) + options.output.filename = "bundle.js"; + if (!options.output.chunkFilename) + options.output.chunkFilename = "[name].chunk.[fullhash].js"; + if (options.output.pathinfo === undefined) + options.output.pathinfo = true; + if (options.output.publicPath === undefined) + options.output.publicPath = "https://test.cases/path/"; + if (options.output.library === undefined) + options.output.library = { type: "commonjs2" }; + if (!options.optimization) options.optimization = {}; + if (!options.optimization.moduleIds) + options.optimization.moduleIds = "named"; + if (!options.module) options.module = {}; + if (!options.module.rules) options.module.rules = []; + options.module.rules.push({ + loader: path.join( __dirname, - "js", - `hot-cases-${config.name}`, - category.name, - testName - ); - rimraf.sync(outputDirectory); - const recordsPath = path.join(outputDirectory, "records.json"); - const fakeUpdateLoaderOptions = { - updateIndex: 0 - }; - const configPath = path.join( - testDirectory, - "webpack.config.js" - ); - let options = {}; - if (fs.existsSync(configPath)) options = require(configPath); - if (!options.mode) options.mode = "development"; - if (!options.devtool) options.devtool = false; - if (!options.context) options.context = testDirectory; - if (!options.entry) options.entry = "./index.js"; - if (!options.output) options.output = {}; - if (!options.output.path) options.output.path = outputDirectory; - if (!options.output.filename) - options.output.filename = "bundle.js"; - if (!options.output.chunkFilename) - options.output.chunkFilename = "[name].chunk.[fullhash].js"; - if (options.output.pathinfo === undefined) - options.output.pathinfo = true; - if (options.output.publicPath === undefined) - options.output.publicPath = "https://test.cases/path/"; - if (options.output.library === undefined) - options.output.library = { type: "commonjs2" }; - if (!options.optimization) options.optimization = {}; - if (!options.optimization.moduleIds) - options.optimization.moduleIds = "named"; - if (!options.module) options.module = {}; - if (!options.module.rules) options.module.rules = []; - options.module.rules.push({ - loader: path.join( - __dirname, - "hotCases", - "fake-update-loader.js" - ), - enforce: "pre" + "hotCases", + "fake-update-loader.js" + ), + enforce: "pre" + }); + if (!options.target) options.target = config.target; + if (!options.plugins) options.plugins = []; + options.plugins.push( + new webpack.HotModuleReplacementPlugin(), + new webpack.LoaderOptionsPlugin(fakeUpdateLoaderOptions) + ); + if (!options.recordsPath) options.recordsPath = recordsPath; + compiler = webpack(options); + compiler.run((err, stats) => { + if (err) return done(err); + const jsonStats = stats.toJson({ + errorDetails: true }); - if (!options.target) options.target = config.target; - if (!options.plugins) options.plugins = []; - options.plugins.push( - new webpack.HotModuleReplacementPlugin(), - new webpack.LoaderOptionsPlugin(fakeUpdateLoaderOptions) - ); - if (!options.recordsPath) options.recordsPath = recordsPath; - compiler = webpack(options); - compiler.run((err, stats) => { - if (err) return done(err); - const jsonStats = stats.toJson({ - errorDetails: true - }); - if ( - checkArrayExpectation( - testDirectory, - jsonStats, - "error", - "Error", - done - ) - ) { - return; - } - if ( - checkArrayExpectation( - testDirectory, - jsonStats, - "warning", - "Warning", - done - ) - ) { - return; - } + if ( + checkArrayExpectation( + testDirectory, + jsonStats, + "error", + "Error", + done + ) + ) { + return; + } + if ( + checkArrayExpectation( + testDirectory, + jsonStats, + "warning", + "Warning", + done + ) + ) { + return; + } - const urlToPath = url => { - if (url.startsWith("https://test.cases/path/")) - url = url.slice(24); - return path.resolve(outputDirectory, `./${url}`); - }; - const urlToRelativePath = url => { - if (url.startsWith("https://test.cases/path/")) - url = url.slice(24); - return `./${url}`; - }; - const window = { - fetch: async url => { - try { - const buffer = await new Promise((resolve, reject) => - fs.readFile(urlToPath(url), (err, b) => - err ? reject(err) : resolve(b) - ) + const urlToPath = url => { + if (url.startsWith("https://test.cases/path/")) + url = url.slice(24); + return path.resolve(outputDirectory, `./${url}`); + }; + const urlToRelativePath = url => { + if (url.startsWith("https://test.cases/path/")) + url = url.slice(24); + return `./${url}`; + }; + const window = { + fetch: async url => { + try { + const buffer = await new Promise((resolve, reject) => { + fs.readFile(urlToPath(url), (err, b) => + err ? reject(err) : resolve(b) ); + }); + return { + status: 200, + ok: true, + json: async () => JSON.parse(buffer.toString("utf-8")) + }; + } catch (err) { + if (err.code === "ENOENT") { return { - status: 200, - ok: true, - json: async () => JSON.parse(buffer.toString("utf-8")) + status: 404, + ok: false }; - } catch (err) { - if (err.code === "ENOENT") { - return { - status: 404, - ok: false - }; - } - throw err; } - }, - importScripts: url => { - expect(url).toMatch(/^https:\/\/test\.cases\/path\//); - _require(urlToRelativePath(url)); - }, - document: { - createElement(type) { - return { - _type: type, - _attrs: {}, - setAttribute(name, value) { - this._attrs[name] = value; - }, - parentNode: { - removeChild(node) { - // ok - } - } - }; - }, - head: { - appendChild(element) { - if (element._type === "script") { - // run it - Promise.resolve().then(() => { - _require(urlToRelativePath(element.src)); - }); + throw err; + } + }, + importScripts: url => { + expect(url).toMatch(/^https:\/\/test\.cases\/path\//); + _require(urlToRelativePath(url)); + }, + document: { + createElement(type) { + return { + _type: type, + _attrs: {}, + setAttribute(name, value) { + this._attrs[name] = value; + }, + parentNode: { + removeChild(node) { + // ok } } - }, - getElementsByTagName(name) { - if (name === "head") return [this.head]; - if (name === "script") return []; - throw new Error("Not supported"); - } + }; }, - Worker: require("./helpers/createFakeWorker")({ - outputDirectory - }), - EventSource: require("./helpers/EventSourceForNode"), - location: { - href: "https://test.cases/path/index.html", - origin: "https://test.cases", - toString() { - return "https://test.cases/path/index.html"; + head: { + appendChild(element) { + if (element._type === "script") { + // run it + Promise.resolve().then(() => { + _require(urlToRelativePath(element.src)); + }); + } } + }, + getElementsByTagName(name) { + if (name === "head") return [this.head]; + if (name === "script") return []; + throw new Error("Not supported"); + } + }, + Worker: require("./helpers/createFakeWorker")({ + outputDirectory + }), + EventSource: require("./helpers/EventSourceForNode"), + location: { + href: "https://test.cases/path/index.html", + origin: "https://test.cases", + toString() { + return "https://test.cases/path/index.html"; } - }; + } + }; - function _next(callback) { - fakeUpdateLoaderOptions.updateIndex++; - compiler.run((err, stats) => { - if (err) return callback(err); - const jsonStats = stats.toJson({ - errorDetails: true - }); - if ( - checkArrayExpectation( - testDirectory, - jsonStats, - "error", - "errors" + fakeUpdateLoaderOptions.updateIndex, - "Error", - callback - ) - ) { - return; - } - if ( - checkArrayExpectation( - testDirectory, - jsonStats, - "warning", - "warnings" + fakeUpdateLoaderOptions.updateIndex, - "Warning", - callback - ) - ) { - return; - } - callback(null, jsonStats); + function _next(callback) { + fakeUpdateLoaderOptions.updateIndex++; + compiler.run((err, stats) => { + if (err) return callback(err); + const jsonStats = stats.toJson({ + errorDetails: true }); - } + if ( + checkArrayExpectation( + testDirectory, + jsonStats, + "error", + `errors${fakeUpdateLoaderOptions.updateIndex}`, + "Error", + callback + ) + ) { + return; + } + if ( + checkArrayExpectation( + testDirectory, + jsonStats, + "warning", + `warnings${fakeUpdateLoaderOptions.updateIndex}`, + "Warning", + callback + ) + ) { + return; + } + callback(null, jsonStats); + }); + } - function _require(module) { - if (module.substr(0, 2) === "./") { - const p = path.join(outputDirectory, module); - if (module.endsWith(".json")) { - return JSON.parse(fs.readFileSync(p, "utf-8")); - } else { - const fn = vm.runInThisContext( - "(function(require, module, exports, __dirname, __filename, it, beforeEach, afterEach, expect, self, window, fetch, document, importScripts, Worker, EventSource, NEXT, STATS) {" + - "global.expect = expect;" + - 'function nsObj(m) { Object.defineProperty(m, Symbol.toStringTag, { value: "Module" }); return m; }' + - fs.readFileSync(p, "utf-8") + - "\n})", - p - ); - const m = { - exports: {} - }; - fn.call( - m.exports, - _require, - m, - m.exports, - outputDirectory, + function _require(module) { + if (module.startsWith("./")) { + const p = path.join(outputDirectory, module); + if (module.endsWith(".json")) { + return JSON.parse(fs.readFileSync(p, "utf-8")); + } + const fn = vm.runInThisContext( + "(function(require, module, exports, __dirname, __filename, it, beforeEach, afterEach, expect, jest, self, window, fetch, document, importScripts, Worker, EventSource, NEXT, STATS) {" + + "global.expect = expect;" + + `function nsObj(m) { Object.defineProperty(m, Symbol.toStringTag, { value: "Module" }); return m; }${fs.readFileSync( p, - _it, - _beforeEach, - _afterEach, - expect, - window, - window, - window.fetch, - window.document, - window.importScripts, - window.Worker, - window.EventSource, - _next, - jsonStats - ); - return m.exports; - } - } else return require(module); - } - let promise = Promise.resolve(); - const info = stats.toJson({ all: false, entrypoints: true }); - if (config.target === "web") { - for (const file of info.entrypoints.main.assets) - _require(`./${file.name}`); - } else { - const assets = info.entrypoints.main.assets; - const result = _require( - `./${assets[assets.length - 1].name}` + "utf-8" + )}\n})`, + p + ); + const m = { + exports: {} + }; + fn.call( + m.exports, + _require, + m, + m.exports, + outputDirectory, + p, + _it, + _beforeEach, + _afterEach, + expect, + jest, + window, + window, + window.fetch, + window.document, + window.importScripts, + window.Worker, + window.EventSource, + _next, + jsonStats ); - if (typeof result === "object" && "then" in result) - promise = promise.then(() => result); + return m.exports; } - promise.then( - () => { - if (getNumberOfTests() < 1) - return done( - new Error("No tests exported by test case") - ); - - done(); - }, - err => { - console.log(err); - done(err); - } + return require(module); + } + let promise = Promise.resolve(); + const info = stats.toJson({ all: false, entrypoints: true }); + if (config.target === "web") { + for (const file of info.entrypoints.main.assets) + _require(`./${file.name}`); + } else { + const assets = info.entrypoints.main.assets; + const result = _require( + `./${assets[assets.length - 1].name}` ); - }); - }, - 20000 - ); + if (typeof result === "object" && "then" in result) + promise = promise.then(() => result); + } + promise.then( + () => { + if (getNumberOfTests() < 1) + return done(new Error("No tests exported by test case")); + + done(); + }, + err => { + console.log(err); + done(err); + } + ); + }); + }, 20000); const { it: _it, beforeEach: _beforeEach, afterEach: _afterEach, getNumberOfTests - } = createLazyTestEnv(jasmine.getEnv(), 20000); + } = createLazyTestEnv(20000); }); - }); + } }); - }); + } }); }; +// eslint-disable-next-line jest/no-export module.exports.describeCases = describeCases; diff --git a/test/JavascriptParser.unittest.js b/test/JavascriptParser.unittest.js index 64c5ad06005..bb4fba46693 100644 --- a/test/JavascriptParser.unittest.js +++ b/test/JavascriptParser.unittest.js @@ -1,12 +1,12 @@ "use strict"; +// cspell:ignore fghsub notry fghsub notry notry this's ijksub this's ijksub fghsub fghsub notry ijksub ijksub strrring strrring strr strrring strrring strr Sstrrringy strone stronetwo stronetwothree stronetwo stronetwothree stronetwothreefour onetwo onetwo twothree twothree twothree threefour onetwo onetwo threefour threefour fourfive startstrmid igmy igmyi igmya const BasicEvaluatedExpression = require("../lib/javascript/BasicEvaluatedExpression"); const JavascriptParser = require("../lib/javascript/JavascriptParser"); describe("JavascriptParser", () => { /* eslint-disable no-undef */ /* eslint-disable no-unused-vars */ - /* eslint-disable no-inner-declarations */ const testCases = { "call ident": [ function () { @@ -26,6 +26,7 @@ describe("JavascriptParser", () => { ], "call member using bracket notation": [ function () { + // eslint-disable-next-line dot-notation cde["abc"]("membertest"); }, { @@ -42,6 +43,7 @@ describe("JavascriptParser", () => { ], "call inner member using bracket notation": [ function () { + // eslint-disable-next-line dot-notation cde.ddd["abc"]("inner"); }, { @@ -67,6 +69,7 @@ describe("JavascriptParser", () => { "member expression": [ function () { test[memberExpr]; + // eslint-disable-next-line no-implicit-coercion test[+memberExpr]; }, { @@ -87,6 +90,7 @@ describe("JavascriptParser", () => { ], "const definition": [ function () { + // eslint-disable-next-line one-var let abc, cde, fgh; abc("test"); cde.abc("test"); @@ -98,6 +102,7 @@ describe("JavascriptParser", () => { ], "var definition": [ function () { + // eslint-disable-next-line one-var var abc, cde, fgh; abc("test"); cde.abc("test"); @@ -128,6 +133,7 @@ describe("JavascriptParser", () => { cde() { abc("cde"); } + static fgh() { abc("fgh"); fgh(); @@ -149,14 +155,14 @@ describe("JavascriptParser", () => { fgh.sub; fgh; } - } catch (e) { + } catch (err) { fgh.sub; fgh; } }, { fghsub: ["try", "notry", "notry"], - fgh: ["test", "test ttt", "test e"] + fgh: ["test", "test ttt", "test err"] } ], "renaming with const": [ @@ -231,6 +237,7 @@ describe("JavascriptParser", () => { ], "new Foo(...)": [ function () { + // eslint-disable-next-line new-cap new xyz("membertest"); }, { @@ -250,12 +257,11 @@ describe("JavascriptParser", () => { }; /* eslint-enable no-undef */ /* eslint-enable no-unused-vars */ - /* eslint-enable no-inner-declarations */ - Object.keys(testCases).forEach(name => { - it("should parse " + name, () => { + for (const name of Object.keys(testCases)) { + it(`should parse ${name}`, () => { let source = testCases[name][0].toString(); - source = source.substr(13, source.length - 14).trim(); + source = source.slice(13, -1).trim(); const state = testCases[name][1]; const testParser = new JavascriptParser({}); @@ -325,7 +331,7 @@ describe("JavascriptParser", () => { expect(typeof actual).toBe("object"); expect(actual).toEqual(state); }); - }); + } it("should parse comments", () => { const source = "//comment1\n/*comment2*/"; @@ -350,12 +356,12 @@ describe("JavascriptParser", () => { const actual = testParser.parse(source, {}); expect(typeof actual).toBe("object"); expect(typeof actual.comments).toBe("object"); - actual.comments.forEach((element, index) => { + for (const [index, element] of actual.comments.entries()) { expect(typeof element.type).toBe("string"); expect(typeof element.value).toBe("string"); expect(element.type).toBe(state[index].type); expect(element.value).toBe(state[index].value); - }); + } }); describe("expression evaluation", () => { @@ -376,7 +382,7 @@ describe("JavascriptParser", () => { .tap("JavascriptParserTest", expr => new BasicEvaluatedExpression().setNumber(123).setRange(expr.range) ); - return parser.parse("test(" + source + ");", {}).result; + return parser.parse(`test(${source});`, {}).result; } const testCases = { @@ -540,12 +546,20 @@ describe("JavascriptParser", () => { "`start${'str'}mid${obj2}end`": // eslint-disable-next-line no-template-curly-in-string "template=[start${'str'}mid string=startstrmid],[end string=end]", - "'abc'.substr(1)": "string=bc", - "'abcdef'.substr(2, 3)": "string=cde", + // eslint-disable-next-line no-template-curly-in-string + "`a${x}` === `b${x}`": "bool=false", + // eslint-disable-next-line no-template-curly-in-string + "`${x}a` === `${x}b`": "bool=false", + // eslint-disable-next-line no-template-curly-in-string + "`${a}${b}` === `a${b}`": "", + // eslint-disable-next-line no-template-curly-in-string + "`${a}${b}` === `${a}b`": "", + "'abc'.slice(1)": "string=bc", + "'abcdef'.slice(2, 5)": "string=cde", "'abcdef'.substring(2, 3)": "string=c", "'abcdef'.substring(2, 3, 4)": "", - "'abc'[\"substr\"](1)": "string=bc", - "'abc'[substr](1)": "", + "'abc'[\"slice\"](1)": "string=bc", + "'abc'[slice](1)": "", "'1,2+3'.split(/[,+]/)": "array=[1],[2],[3]", "'1,2+3'.split(expr)": "", "'a' + (expr + 'c')": "wrapped=['a' string=a]+['c' string=c]", @@ -554,62 +568,55 @@ describe("JavascriptParser", () => { "'a' + expr + 1": "wrapped=['a' string=a]+[1 string=1]" }; - Object.keys(testCases).forEach(key => { + for (const key of Object.keys(testCases)) { function evalExprToString(evalExpr) { if (!evalExpr) { return "null"; - } else { - const result = []; - if (evalExpr.isString()) result.push("string=" + evalExpr.string); - if (evalExpr.isNumber()) result.push("number=" + evalExpr.number); - if (evalExpr.isBigInt()) result.push("bigint=" + evalExpr.bigint); - if (evalExpr.isBoolean()) result.push("bool=" + evalExpr.bool); - if (evalExpr.isRegExp()) result.push("regExp=" + evalExpr.regExp); - if (evalExpr.isConditional()) - result.push( - "options=[" + - evalExpr.options.map(evalExprToString).join("],[") + - "]" - ); - if (evalExpr.isArray()) - result.push( - "items=[" + evalExpr.items.map(evalExprToString).join("],[") + "]" - ); - if (evalExpr.isConstArray()) - result.push("array=[" + evalExpr.array.join("],[") + "]"); - if (evalExpr.isTemplateString()) - result.push( - "template=[" + - evalExpr.quasis.map(evalExprToString).join("],[") + - "]" - ); - if (evalExpr.isWrapped()) - result.push( - "wrapped=[" + - evalExprToString(evalExpr.prefix) + - "]+[" + - evalExprToString(evalExpr.postfix) + - "]" - ); - if (evalExpr.range) { - const start = evalExpr.range[0] - 5; - const end = evalExpr.range[1] - 5; - return ( - key.substr(start, end - start) + - (result.length > 0 ? " " + result.join(" ") : "") - ); - } - return result.join(" "); } + const result = []; + if (evalExpr.isString()) result.push(`string=${evalExpr.string}`); + if (evalExpr.isNumber()) result.push(`number=${evalExpr.number}`); + if (evalExpr.isBigInt()) result.push(`bigint=${evalExpr.bigint}`); + if (evalExpr.isBoolean()) result.push(`bool=${evalExpr.bool}`); + if (evalExpr.isRegExp()) result.push(`regExp=${evalExpr.regExp}`); + if (evalExpr.isConditional()) + result.push( + `options=[${evalExpr.options.map(evalExprToString).join("],[")}]` + ); + if (evalExpr.isArray()) + result.push( + `items=[${evalExpr.items.map(evalExprToString).join("],[")}]` + ); + if (evalExpr.isConstArray()) + result.push(`array=[${evalExpr.array.join("],[")}]`); + if (evalExpr.isTemplateString()) + result.push( + `template=[${evalExpr.quasis.map(evalExprToString).join("],[")}]` + ); + if (evalExpr.isWrapped()) + result.push( + `wrapped=[${evalExprToString(evalExpr.prefix)}]+[${evalExprToString( + evalExpr.postfix + )}]` + ); + if (evalExpr.range) { + const start = evalExpr.range[0] - 5; + const end = evalExpr.range[1] - 5; + return ( + key.slice(start, end) + + (result.length > 0 ? ` ${result.join(" ")}` : "") + ); + } + return result.join(" "); } - it("should eval " + key, () => { + it(`should eval ${key}`, () => { const evalExpr = evaluateInParser(key); expect(evalExprToString(evalExpr)).toBe( - testCases[key] ? key + " " + testCases[key] : key + testCases[key] ? `${key} ${testCases[key]}` : key ); }); - }); + } }); describe("async/await support", () => { @@ -621,13 +628,13 @@ describe("JavascriptParser", () => { "await iteration": "async function f() { for await (x of xs); }" }; const parser = new JavascriptParser(); - Object.keys(cases).forEach(name => { + for (const name of Object.keys(cases)) { const expr = cases[name]; it(name, () => { const actual = parser.parse(expr, {}); expect(typeof actual).toBe("object"); }); - }); + } }); describe("should parse await", () => { const cases = { @@ -655,12 +662,12 @@ describe("JavascriptParser", () => { parser.state.param = param.string; }); - Object.keys(cases).forEach(name => { + for (const name of Object.keys(cases)) { it(name, () => { const actual = parser.parse(cases[name][0], {}); expect(actual).toEqual(cases[name][1]); }); - }); + } }); }); @@ -670,13 +677,13 @@ describe("JavascriptParser", () => { "object spread": "({...obj})", "object rest": "({...obj} = foo)" }; - Object.keys(cases).forEach(name => { + for (const name of Object.keys(cases)) { const expr = cases[name]; it(name, () => { const actual = JavascriptParser._parse(expr, {}); expect(typeof actual).toBe("object"); }); - }); + } }); it("should collect definitions from identifiers introduced in object patterns", () => { @@ -701,13 +708,13 @@ describe("JavascriptParser", () => { const cases = { "optional binding": "try {} catch {}" }; - Object.keys(cases).forEach(name => { + for (const name of Object.keys(cases)) { const expr = cases[name]; it(name, () => { const actual = JavascriptParser._parse(expr); expect(typeof actual).toBe("object"); }); - }); + } }); }); @@ -728,7 +735,7 @@ describe("JavascriptParser", () => { ["ia", false] ]; - tests.forEach(([suite, expected]) => { + for (const [suite, expected] of tests) { it(`BasicEvaluatedExpression.isValidRegExpFlags(${JSON.stringify( suite )})`, () => { @@ -736,6 +743,6 @@ describe("JavascriptParser", () => { expected ); }); - }); + } }); }); diff --git a/test/LazySet.unittest.js b/test/LazySet.unittest.js new file mode 100644 index 00000000000..92c829f7a33 --- /dev/null +++ b/test/LazySet.unittest.js @@ -0,0 +1,22 @@ +const LazySet = require("../lib/util/LazySet"); + +describe("LazySet", () => { + it("addAll", () => { + const a = new Set(["a"]); + const sut = new LazySet(a); + const empty = new LazySet([]); + expect(sut.size).toBe(1); + sut.addAll(empty); + expect(sut._toDeepMerge).toStrictEqual([]); + expect(sut.size).toBe(1); + const b = new Set(["b"]); + sut.addAll(b); + expect(sut._toMerge).toContain(b); + expect(sut.size).toBe(2); + const c = new LazySet(["c"]); + sut.addAll(c); + expect(sut._toDeepMerge).toContain(c); + expect(sut.size).toBe(3); + expect(sut._toDeepMerge).toStrictEqual([]); + }); +}); diff --git a/test/MemoryLimitTestCases.test.js b/test/MemoryLimitTestCases.test.js new file mode 100644 index 00000000000..2fb5a4c2eae --- /dev/null +++ b/test/MemoryLimitTestCases.test.js @@ -0,0 +1,135 @@ +"use strict"; + +require("./helpers/warmup-webpack"); +const path = require("path"); +const fs = require("graceful-fs"); +const rimraf = require("rimraf"); +const captureStdio = require("./helpers/captureStdio"); +const webpack = require(".."); + +const toMiB = bytes => `${Math.round(bytes / 1024 / 1024)}MiB`; +const base = path.join(__dirname, "memoryLimitCases"); +const outputBase = path.join(__dirname, "js", "memoryLimit"); +const tests = fs + .readdirSync(base) + .filter( + testName => + fs.existsSync(path.join(base, testName, "index.js")) || + fs.existsSync(path.join(base, testName, "webpack.config.js")) + ) + .filter(testName => { + const testDirectory = path.join(base, testName); + const filterPath = path.join(testDirectory, "test.filter.js"); + if (fs.existsSync(filterPath) && !require(filterPath)()) { + // eslint-disable-next-line jest/no-disabled-tests, jest/valid-describe-callback + describe.skip(testName, () => it("filtered")); + return false; + } + return true; + }); + +describe("MemoryLimitTestCases", () => { + jest.setTimeout(40000); + let stderr; + beforeEach(() => { + stderr = captureStdio(process.stderr, true); + if (global.gc) { + global.gc(); + global.gc(); + } + }); + afterEach(() => { + stderr.restore(); + }); + for (const testName of tests) { + let testConfig = { + heapSizeLimitBytes: 250 * 1024 * 1024 + }; + try { + // try to load a test file + testConfig = Object.assign( + testConfig, + require(path.join(base, testName, "test.config.js")) + ); + } catch (_err) { + // ignored + } + const size = toMiB(testConfig.heapSizeLimitBytes); + // eslint-disable-next-line no-loop-func + it(`should build ${JSON.stringify(testName)} with heap limit of ${size}`, done => { + const outputDirectory = path.join(outputBase, testName); + rimraf.sync(outputDirectory); + fs.mkdirSync(outputDirectory, { recursive: true }); + let options = { + mode: "development", + entry: "./index", + output: { + filename: "bundle.js" + } + }; + if (fs.existsSync(path.join(base, testName, "webpack.config.js"))) { + options = require(path.join(base, testName, "webpack.config.js")); + } + + const resolvedOptions = Array.isArray(options) ? options : [options]; + for (const options of resolvedOptions) { + if (!options.context) options.context = path.join(base, testName); + if (!options.output) options.output = options.output || {}; + if (!options.output.path) options.output.path = outputDirectory; + if (!options.plugins) options.plugins = []; + if (!options.optimization) options.optimization = {}; + if (options.optimization.minimize === undefined) + options.optimization.minimize = false; + } + const heapSizeStart = process.memoryUsage().heapUsed; + const c = webpack(options); + const compilers = c.compilers ? c.compilers : [c]; + for (const c of compilers) { + const ifs = c.inputFileSystem; + c.inputFileSystem = Object.create(ifs); + c.inputFileSystem.readFile = function () { + // eslint-disable-next-line prefer-rest-params + const args = Array.prototype.slice.call(arguments); + const callback = args.pop(); + // eslint-disable-next-line prefer-spread + ifs.readFile.apply( + ifs, + args.concat([ + (err, result) => { + if (err) return callback(err); + if (!/\.(js|json|txt)$/.test(args[0])) + return callback(null, result); + callback(null, result.toString("utf-8").replace(/\r/g, "")); + } + ]) + ); + }; + } + c.run((err, stats) => { + if (err) return done(err); + if (testName.endsWith("error")) { + expect(stats.hasErrors()).toBe(true); + } else if (stats.hasErrors()) { + return done( + new Error( + stats.toString({ + all: false, + errors: true, + errorStack: true, + errorDetails: true + }) + ) + ); + } + const heapUsed = process.memoryUsage().heapUsed - heapSizeStart; + if (heapUsed > testConfig.heapSizeLimitBytes) { + return done( + new Error(`Out of memory limit with ${toMiB(heapUsed)} heap used`) + ); + } + if (testConfig.validate) testConfig.validate(stats, stderr.toString()); + done(); + }); + }); + } +}); diff --git a/test/MultiCompiler.test.js b/test/MultiCompiler.test.js index 319e9b4470d..f75175f9da3 100644 --- a/test/MultiCompiler.test.js +++ b/test/MultiCompiler.test.js @@ -1,5 +1,6 @@ "use strict"; +require("./helpers/warmup-webpack"); const path = require("path"); const { createFsFromVolume, Volume } = require("memfs"); const webpack = require(".."); @@ -42,7 +43,7 @@ describe("MultiCompiler", function () { throw err; } expect(called).toBe(2); - done(); + compiler.close(done); }); }); @@ -51,13 +52,12 @@ describe("MultiCompiler", function () { let called = 0; compiler.hooks.watchRun.tap("MultiCompiler test", () => called++); - const watcher = compiler.watch(1000, err => { + compiler.watch(1000, err => { if (err) { throw err; } - watcher.close(); expect(called).toBe(2); - done(); + compiler.close(done); }); }); @@ -67,16 +67,20 @@ describe("MultiCompiler", function () { if (err) return done(err); }); compiler.run((err, stats) => { - if (err) return done(); + if (err) { + compiler.close(done); + } }); }); it("should not be running twice at a time (watch)", done => { const compiler = createMultiCompiler(); - const watcher = compiler.watch({}, (err, stats) => { + compiler.watch({}, (err, stats) => { if (err) return done(err); }); compiler.watch({}, (err, stats) => { - if (err) return watcher.close(done); + if (err) { + compiler.close(done); + } }); }); it("should not be running twice at a time (run - watch)", done => { @@ -85,17 +89,20 @@ describe("MultiCompiler", function () { if (err) return done(err); }); compiler.watch({}, (err, stats) => { - if (err) return done(); + if (err) { + compiler.close(done); + } }); }); it("should not be running twice at a time (watch - run)", done => { const compiler = createMultiCompiler(); - let watcher; - watcher = compiler.watch({}, (err, stats) => { + compiler.watch({}, (err, stats) => { if (err) return done(err); }); compiler.run((err, stats) => { - if (err) return watcher.close(done); + if (err) { + compiler.close(done); + } }); }); it("should not be running twice at a time (instance cb)", done => { @@ -113,7 +120,9 @@ describe("MultiCompiler", function () { ); compiler.outputFileSystem = createFsFromVolume(new Volume()); compiler.run((err, stats) => { - if (err) return done(); + if (err) { + compiler.close(done); + } }); }); it("should run again correctly after first compilation", done => { @@ -123,7 +132,7 @@ describe("MultiCompiler", function () { compiler.run((err, stats) => { if (err) return done(err); - done(); + compiler.close(done); }); }); }); @@ -132,10 +141,9 @@ describe("MultiCompiler", function () { compiler.run((err, stats) => { if (err) return done(err); - let watcher; - watcher = compiler.watch({}, (err, stats) => { + compiler.watch({}, (err, stats) => { if (err) return done(err); - watcher.close(done); + compiler.close(done); }); }); }); @@ -147,7 +155,7 @@ describe("MultiCompiler", function () { watching.close(() => { compiler.run((err, stats) => { if (err) return done(err); - done(); + compiler.close(done); }); }); }); @@ -157,10 +165,9 @@ describe("MultiCompiler", function () { if (err) return done(err); }); watching.close(() => { - let watcher; - watcher = compiler.watch({}, (err, stats) => { + compiler.watch({}, (err, stats) => { if (err) return done(err); - watcher.close(done); + compiler.close(done); }); }); }); @@ -185,19 +192,19 @@ describe("MultiCompiler", function () { } }); const events = []; - compiler.compilers.forEach(c => { + for (const c of compiler.compilers) { c.hooks.run.tap("test", () => { events.push(`${c.name} run`); }); c.hooks.done.tap("test", () => { events.push(`${c.name} done`); }); - }); + } compiler.run((err, stats) => { expect(events.join(" ")).toBe( "a run a done b run b done d run d done e run e done c run c done" ); - done(); + compiler.close(done); }); }); it("should respect parallelism and dependencies for watching", done => { @@ -245,17 +252,20 @@ describe("MultiCompiler", function () { } }; const events = []; - compiler.compilers.forEach(c => { + for (const c of compiler.compilers) { + c.hooks.invalid.tap("test", () => { + events.push(`${c.name} invalid`); + }); c.hooks.watchRun.tap("test", () => { events.push(`${c.name} run`); }); c.hooks.done.tap("test", () => { events.push(`${c.name} done`); }); - }); + } let update = 0; - const watching = compiler.watch({}, (err, stats) => { + compiler.watch({}, (err, stats) => { if (err) return done(err); const info = () => stats.toString({ preset: "summary", version: false }); switch (update++) { @@ -273,15 +283,15 @@ describe("MultiCompiler", function () { expect(compiler.compilers[0].modifiedFiles).toBe(undefined); expect(compiler.compilers[0].removedFiles).toBe(undefined); expect(events).toMatchInlineSnapshot(` - Array [ - "b run", - "b done", - "c run", - "c done", - "a run", - "a done", - ] - `); + Array [ + "b run", + "b done", + "c run", + "c done", + "a run", + "a done", + ] + `); events.length = 0; // wait until watching begins setTimeout(() => { @@ -301,8 +311,10 @@ describe("MultiCompiler", function () { expect(compiler.compilers[1].removedFiles).toEqual(new Set()); expect(events).toMatchInlineSnapshot(` Array [ + "b invalid", "b run", "b done", + "a invalid", "a run", "a done", ] @@ -317,10 +329,13 @@ describe("MultiCompiler", function () { `); expect(events).toMatchInlineSnapshot(` Array [ + "b invalid", "b run", "b done", + "a invalid", "a run", "a done", + "a invalid", "a run", "a done", ] @@ -344,19 +359,19 @@ describe("MultiCompiler", function () { `); expect(events).toMatchInlineSnapshot(` Array [ + "b invalid", + "c invalid", "b run", "b done", "c run", "c done", + "a invalid", "a run", "a done", ] `); events.length = 0; - watching.close(err => { - if (err) return done(err); - compiler.close(done); - }); + compiler.close(done); break; default: done(new Error("unexpected")); @@ -364,6 +379,165 @@ describe("MultiCompiler", function () { }); }); + it("should respect parallelism when using invalidate", done => { + const configs = [ + { + name: "a", + mode: "development", + entry: { a: "./a.js" }, + context: path.join(__dirname, "fixtures") + }, + { + name: "b", + mode: "development", + entry: { b: "./b.js" }, + context: path.join(__dirname, "fixtures") + } + ]; + configs.parallelism = 1; + const compiler = webpack(configs); + + const events = []; + for (const c of compiler.compilers) { + c.hooks.invalid.tap("test", () => { + events.push(`${c.name} invalid`); + }); + c.hooks.watchRun.tap("test", () => { + events.push(`${c.name} run`); + }); + c.hooks.done.tap("test", () => { + events.push(`${c.name} done`); + }); + } + + compiler.watchFileSystem = { watch() {} }; + compiler.outputFileSystem = createFsFromVolume(new Volume()); + + let state = 0; + const watching = compiler.watch({}, error => { + if (error) { + done(error); + return; + } + if (state !== 0) return; + state++; + + expect(events).toMatchInlineSnapshot(` + Array [ + "a run", + "a done", + "b run", + "b done", + ] + `); + events.length = 0; + + watching.invalidate(err => { + try { + if (err) return done(err); + + expect(events).toMatchInlineSnapshot(` + Array [ + "a invalid", + "b invalid", + "a run", + "a done", + "b run", + "b done", + ] + `); + events.length = 0; + expect(state).toBe(1); + setTimeout(() => { + compiler.close(done); + }, 1000); + } catch (err) { + console.error(err); + done(err); + } + }); + }); + }, 2000); + + it("should respect dependencies when using invalidate", done => { + const compiler = webpack([ + { + name: "a", + mode: "development", + entry: { a: "./a.js" }, + context: path.join(__dirname, "fixtures"), + dependencies: ["b"] + }, + { + name: "b", + mode: "development", + entry: { b: "./b.js" }, + context: path.join(__dirname, "fixtures") + } + ]); + + const events = []; + for (const c of compiler.compilers) { + c.hooks.invalid.tap("test", () => { + events.push(`${c.name} invalid`); + }); + c.hooks.watchRun.tap("test", () => { + events.push(`${c.name} run`); + }); + c.hooks.done.tap("test", () => { + events.push(`${c.name} done`); + }); + } + + compiler.watchFileSystem = { watch() {} }; + compiler.outputFileSystem = createFsFromVolume(new Volume()); + + let state = 0; + const watching = compiler.watch({}, error => { + if (error) { + done(error); + return; + } + if (state !== 0) return; + state++; + + expect(events).toMatchInlineSnapshot(` + Array [ + "b run", + "b done", + "a run", + "a done", + ] + `); + events.length = 0; + + watching.invalidate(err => { + try { + if (err) return done(err); + + expect(events).toMatchInlineSnapshot(` + Array [ + "a invalid", + "b invalid", + "b run", + "b done", + "a run", + "a done", + ] + `); + events.length = 0; + expect(state).toBe(1); + setTimeout(() => { + compiler.close(done); + }, 1000); + } catch (err) { + console.error(err); + done(err); + } + }); + }); + }, 2000); + it("shouldn't hang when invalidating watchers", done => { const entriesA = { a: "./a.js" }; const entriesB = { b: "./b.js" }; @@ -394,7 +568,10 @@ describe("MultiCompiler", function () { entriesA.b = "./b.js"; entriesB.a = "./a.js"; - watching.invalidate(done); + watching.invalidate(err => { + if (err) return done(err); + compiler.close(done); + }); }); }, 2000); @@ -441,7 +618,8 @@ describe("MultiCompiler", function () { } }; compiler.watch({}, (err, stats) => { - done(err); + if (err) return done(err); + compiler.close(done); }); }); }); diff --git a/test/MultiItemCache.unittest.js b/test/MultiItemCache.unittest.js new file mode 100644 index 00000000000..8b58a54d1cf --- /dev/null +++ b/test/MultiItemCache.unittest.js @@ -0,0 +1,61 @@ +"use strict"; + +const Cache = require("../lib/Cache"); +const { ItemCacheFacade, MultiItemCache } = require("../lib/CacheFacade"); + +describe("MultiItemCache", () => { + it("Throws when getting items from an empty Cache", () => { + const multiItemCache = new MultiItemCache(generateItemCaches(0)); + expect(() => multiItemCache.get(_ => _())).toThrow(); + }); + + it("Returns the single ItemCacheFacade when passed an array of length 1", () => { + const itemCaches = generateItemCaches(1); + const multiItemCache = new MultiItemCache(itemCaches); + expect(multiItemCache).toBe(itemCaches[0]); + }); + + it("Retrieves items from the underlying Cache when get is called", () => { + const itemCaches = generateItemCaches(10); + const multiItemCache = new MultiItemCache(itemCaches); + const callback = (err, res) => { + expect(err).toBeNull(); + expect(res).toBeInstanceOf(Object); + }; + for (let i = 0; i < 10; ++i) { + multiItemCache.get(callback); + } + }); + + it("Can get() a large number of items without exhausting the stack", () => { + const itemCaches = generateItemCaches(10000, () => undefined); + const multiItemCache = new MultiItemCache(itemCaches); + let callbacks = 0; + const callback = (err, res) => { + expect(err).toBeNull(); + expect(res).toBeUndefined(); + ++callbacks; + }; + multiItemCache.get(callback); + expect(callbacks).toEqual(1); + }); + + function generateItemCaches(howMany, dataGenerator) { + const ret = []; + for (let i = 0; i < howMany; ++i) { + const name = `ItemCache${i}`; + const tag = `ItemTag${i}`; + const dataGen = dataGenerator || (() => ({ name: tag })); + const cache = new Cache(); + cache.hooks.get.tapAsync( + "DataReturner", + (_identifier, _etag, _gotHandlers, callback) => { + callback(undefined, dataGen()); + } + ); + const itemCache = new ItemCacheFacade(cache, name, tag); + ret[i] = itemCache; + } + return ret; + } +}); diff --git a/test/MultiStats.test.js b/test/MultiStats.test.js index db5f64f6bc2..df12659778d 100644 --- a/test/MultiStats.test.js +++ b/test/MultiStats.test.js @@ -1,10 +1,12 @@ "use strict"; -const webpack = require(".."); +require("./helpers/warmup-webpack"); + const { createFsFromVolume, Volume } = require("memfs"); describe("MultiStats", () => { it("should create JSON of children stats", done => { + const webpack = require(".."); const compiler = webpack([ { context: __dirname, @@ -25,8 +27,8 @@ describe("MultiStats", () => { ); expect(statsObject.children).toHaveLength(2); done(); - } catch (e) { - done(e); + } catch (err) { + done(err); } }); }); diff --git a/test/MultiWatching.unittest.js b/test/MultiWatching.unittest.js index 4d063992200..051b2a9fa7f 100644 --- a/test/MultiWatching.unittest.js +++ b/test/MultiWatching.unittest.js @@ -3,14 +3,12 @@ const SyncHook = require("tapable").SyncHook; const MultiWatching = require("../lib/MultiWatching"); -const createWatching = () => { - return { - invalidate: jest.fn(), - suspend: jest.fn(), - resume: jest.fn(), - close: jest.fn() - }; -}; +const createWatching = () => ({ + invalidate: jest.fn(), + suspend: jest.fn(), + resume: jest.fn(), + close: jest.fn() +}); const createCompiler = () => { const compiler = { diff --git a/test/NodeTemplatePlugin.test.js b/test/NodeTemplatePlugin.test.js index be3f1c872dd..3ce706e3eb3 100644 --- a/test/NodeTemplatePlugin.test.js +++ b/test/NodeTemplatePlugin.test.js @@ -1,11 +1,14 @@ "use strict"; +require("./helpers/warmup-webpack"); + const path = require("path"); -const webpack = require(".."); +// cspell:word nodetest describe("NodeTemplatePlugin", () => { jest.setTimeout(20000); it("should compile and run a simple module", done => { + const webpack = require(".."); webpack( { mode: "production", @@ -24,7 +27,7 @@ describe("NodeTemplatePlugin", () => { if (err) return err; expect(stats.hasErrors()).toBe(false); expect(stats.hasWarnings()).toBe(false); - // eslint-disable-next-line node/no-missing-require + // eslint-disable-next-line n/no-missing-require const result = require("./js/NodeTemplatePlugin/result").abc; expect(result.nextTick).toBe(process.nextTick); expect(result.fs).toBe(require("fs")); @@ -42,6 +45,7 @@ describe("NodeTemplatePlugin", () => { }); it("should compile and run a simple module in single mode", done => { + const webpack = require(".."); webpack( { mode: "production", @@ -65,7 +69,7 @@ describe("NodeTemplatePlugin", () => { (err, stats) => { if (err) return err; expect(stats.hasErrors()).toBe(false); - // eslint-disable-next-line node/no-missing-require + // eslint-disable-next-line n/no-missing-require const result = require("./js/NodeTemplatePluginSingle/result2"); expect(result.nextTick).toBe(process.nextTick); expect(result.fs).toBe(require("fs")); diff --git a/test/NormalModule.unittest.js b/test/NormalModule.unittest.js index bba771d3fce..14ae35f46a9 100644 --- a/test/NormalModule.unittest.js +++ b/test/NormalModule.unittest.js @@ -91,6 +91,7 @@ describe("NormalModule", () => { }); describe("given a userRequest containing query parameters", () => { it("ignores paths in query parameters", () => { + // cspell:word testpath userRequest = "F:\\some\\context\\loader?query=foo\\bar&otherPath=testpath/other"; normalModule = new NormalModule({ @@ -118,7 +119,7 @@ describe("NormalModule", () => { describe("given a resource containing a ?-sign", () => { const baseResource = "some/resource"; beforeEach(() => { - resource = baseResource + "?some=query"; + resource = `${baseResource}?some=query`; normalModule = new NormalModule({ type: "javascript/auto", request, @@ -193,7 +194,7 @@ describe("NormalModule", () => { }); describe("#originalSource", () => { - let expectedSource = "some source"; + const expectedSource = "some source"; beforeEach(() => { normalModule._source = new RawSource(expectedSource); }); @@ -211,7 +212,7 @@ describe("NormalModule", () => { }); describe("and the content starting with the string specified in rule", () => { beforeEach(() => { - content = rule + "some-content"; + content = `${rule}some-content`; }); it("returns true", () => { expect(normalModule.shouldPreventParsing(rule, content)).toBe(true); @@ -232,7 +233,7 @@ describe("NormalModule", () => { }); describe("and the content matches the rule", () => { beforeEach(() => { - content = rule + "some-content"; + content = `${rule}some-content`; }); it("returns true", () => { expect(normalModule.shouldPreventParsing(rule, content)).toBe(true); @@ -284,7 +285,7 @@ describe("NormalModule", () => { }); }); describe("that is an array", () => { - describe("of strings and or regexs", () => { + describe("of strings and or regexps", () => { let someRules; beforeEach(() => { someRules = ["some rule", /some rule1/, "some rule2"]; diff --git a/test/PersistentCaching.test.js b/test/PersistentCaching.test.js index 8e9427a80d3..28dd169a71e 100644 --- a/test/PersistentCaching.test.js +++ b/test/PersistentCaching.test.js @@ -1,9 +1,10 @@ +require("./helpers/warmup-webpack"); + const path = require("path"); const util = require("util"); const fs = require("fs"); const rimraf = require("rimraf"); const vm = require("vm"); -const webpack = require("../"); const readdir = util.promisify(fs.readdir); const writeFile = util.promisify(fs.writeFile); @@ -29,6 +30,15 @@ describe("Persistent Caching", () => { }, cacheLocation: cachePath }, + experiments: { + css: true + }, + resolve: { + alias: { + "image.png": false, + "image1.png": false + } + }, target: "node", output: { library: { type: "commonjs-module", export: "default" }, @@ -50,16 +60,23 @@ describe("Persistent Caching", () => { } }; - const compile = async (configAdditions = {}) => { - return new Promise((resolve, reject) => { - webpack({ ...config, ...configAdditions }, (err, stats) => { - if (err) return reject(err); - if (stats.hasErrors()) - return reject(stats.toString({ preset: "errors-only" })); - resolve(stats); - }); + const compile = async (configAdditions = {}) => + new Promise((resolve, reject) => { + const webpack = require("../"); + webpack( + { + ...config, + ...configAdditions, + cache: { ...config.cache, ...configAdditions.cache } + }, + (err, stats) => { + if (err) return reject(err); + if (stats.hasErrors()) + return reject(stats.toString({ preset: "errors-only" })); + resolve(stats); + } + ); }); - }; const execute = () => { const cache = {}; @@ -84,33 +101,52 @@ describe("Persistent Caching", () => { return require("./main"); }; + it("should compile fine (warmup)", async () => { + const data = { + "index.js": `import file from "./file.js"; +export default 40 + file; +`, + "file.js": "export default 2;" + }; + await updateSrc(data); + await compile(); + expect(execute()).toBe(42); + }, 100000); + it("should merge multiple small files", async () => { const files = Array.from({ length: 30 }).map((_, i) => `file${i}.js`); const data = { "index.js": ` +import * as style from "./style.modules.css"; ${files.map((f, i) => `import f${i} from "./${f}";`).join("\n")} export default ${files.map((_, i) => `f${i}`).join(" + ")}; -` +export { style }; +`, + "style.modules.css": `.class { + color: red; + background: url('image.png'); +}` }; for (const file of files) { - data[file] = `export default 1;`; + data[file] = "export default 1;"; } await updateSrc(data); - await compile(); + await compile({ cache: { compression: false } }); expect(execute()).toBe(30); for (let i = 0; i < 30; i++) { updateSrc({ - [files[i]]: `export default 2;` + [files[i]]: "export default 2;", + "style.modules.css": `.class-${i} { color: red; background: url('image1.png'); }` }); - await compile(); + await compile({ cache: { compression: false } }); expect(execute()).toBe(31 + i); } const cacheFiles = await readdir(cachePath); expect(cacheFiles.length).toBeLessThan(20); expect(cacheFiles.length).toBeGreaterThan(10); - }, 60000); + }, 120000); it("should optimize unused content", async () => { const data = { @@ -120,21 +156,21 @@ export default ${files.map((_, i) => `f${i}`).join(" + ")}; "d.js": 'import "date-fns";', "e.js": 'import "lodash";' }; - const createEntry = items => { + await updateSrc(data); + const c = items => { const entry = {}; for (const item of items.split("")) entry[item] = `./src/${item}.js`; - return entry; + return compile({ entry, cache: { compression: false } }); }; - await updateSrc(data); - await compile({ entry: createEntry("abcde") }); - await compile({ entry: createEntry("abc") }); - await compile({ entry: createEntry("cde") }); - await compile({ entry: createEntry("acd") }); - await compile({ entry: createEntry("bce") }); - await compile({ entry: createEntry("abcde") }); + await c("abcde"); + await c("abc"); + await c("cde"); + await c("acd"); + await c("bce"); + await c("abcde"); const cacheFiles = await readdir(cachePath); expect(cacheFiles.length).toBeGreaterThan(4); - }, 60000); + }, 120000); it("should allow persistent caching of container related objects", async () => { const data = { @@ -145,6 +181,7 @@ export default ${files.map((_, i) => `f${i}`).join(" + ")}; "lib2.js": "export default 21" }; await updateSrc(data); + const webpack = require("../"); const configAdditions = { plugins: [ new webpack.container.ModuleFederationPlugin({ @@ -176,5 +213,40 @@ export default ${files.map((_, i) => `f${i}`).join(" + ")}; }); await compile(configAdditions); await expect(execute()).resolves.toEqual({ ok: true }); - }, 60000); + }, 120000); + + it("should not overwrite cache files if readonly = true", async () => { + await updateSrc({ + "main.js": ` +import { sum } from 'lodash'; + +sum([1,2,3]) + ` + }); + await compile({ entry: "./src/main.js" }); + const firstCacheFiles = (await readdir(cachePath)).sort(); + // cSpell:words Mtimes + const firstMtimes = firstCacheFiles.map( + f => fs.statSync(path.join(cachePath, f)).mtime + ); + + await updateSrc({ + "main.js": ` +import 'lodash'; + ` + }); + await compile({ + entry: "./src/main.js", + cache: { + ...config.cache, + readonly: true + } + }); + const cacheFiles = (await readdir(cachePath)).sort(); + expect(cacheFiles).toStrictEqual(firstCacheFiles); + expect( + firstCacheFiles.map(f => fs.statSync(path.join(cachePath, f)).mtime) + // cSpell:words Mtimes + ).toStrictEqual(firstMtimes); + }, 20000); }); diff --git a/test/ProfilingPlugin.test.js b/test/ProfilingPlugin.test.js index 0d254ebe430..ddd127d4faf 100644 --- a/test/ProfilingPlugin.test.js +++ b/test/ProfilingPlugin.test.js @@ -1,17 +1,21 @@ "use strict"; +require("./helpers/warmup-webpack"); + const path = require("path"); const fs = require("graceful-fs"); -const webpack = require("../"); const rimraf = require("rimraf"); describe("Profiling Plugin", function () { - jest.setTimeout(30000); + jest.setTimeout(120000); it("should handle output path with folder creation", done => { + const webpack = require("../"); const outputPath = path.join(__dirname, "js/profilingPath"); const finalPath = path.join(outputPath, "events.json"); + let counter = 0; rimraf(outputPath, () => { + const startTime = process.hrtime(); const compiler = webpack({ context: __dirname, entry: "./fixtures/a.js", @@ -21,18 +25,45 @@ describe("Profiling Plugin", function () { plugins: [ new webpack.debug.ProfilingPlugin({ outputPath: finalPath - }) - ] + }), + { + apply(compiler) { + const hook = compiler.hooks.make; + for (const { stage, order } of [ + { stage: 0, order: 1 }, + { stage: 1, order: 2 }, + { stage: -1, order: 0 } + ]) { + hook.tap( + { + name: "RespectStageCheckerPlugin", + stage + }, + // eslint-disable-next-line no-loop-func + () => { + expect(counter++).toBe(order); + } + ); + } + } + } + ], + experiments: { + backCompat: false + } }); compiler.run(err => { if (err) return done(err); + const testDuration = process.hrtime(startTime); if (!fs.existsSync(outputPath)) return done(new Error("Folder should be created.")); const data = require(finalPath); const maxTs = data.reduce((max, entry) => Math.max(max, entry.ts), 0); const minTs = data[0].ts; const duration = maxTs - minTs; - expect(duration).toBeLessThan(10000 * 1000); + expect(duration).toBeLessThan( + testDuration[0] * 1000000 + testDuration[1] / 1000 + ); const cpuProfile = data.find(entry => entry.name === "CpuProfile"); expect(cpuProfile).toBeTypeOf("object"); const profile = cpuProfile.args.data.cpuProfile; diff --git a/test/ProfilingPlugin.unittest.js b/test/ProfilingPlugin.unittest.js index b56bb833006..bf648eac925 100644 --- a/test/ProfilingPlugin.unittest.js +++ b/test/ProfilingPlugin.unittest.js @@ -4,7 +4,7 @@ const path = require("path"); const ProfilingPlugin = require("../lib/debug/ProfilingPlugin"); describe("Profiling Plugin", () => { - it("should persist the passed outpath", () => { + it("should persist the passed output path", () => { const outputPath = path.join(__dirname, "invest_in_doge_coin"); const plugin = new ProfilingPlugin({ outputPath: outputPath @@ -34,7 +34,7 @@ describe("Profiling Plugin", () => { it("handles sending a profiling message when no session", () => { const profiler = new ProfilingPlugin.Profiler(); - return profiler.sendCommand("randy", "is a puppers"); + return profiler.sendCommand("randy", "is awesome"); }); it("handles destroying when no session", () => { diff --git a/test/ProgressPlugin.test.js b/test/ProgressPlugin.test.js index aacda0c080d..a620c9f7b06 100644 --- a/test/ProgressPlugin.test.js +++ b/test/ProgressPlugin.test.js @@ -1,12 +1,13 @@ "use strict"; +require("./helpers/warmup-webpack"); + const _ = require("lodash"); const path = require("path"); const { createFsFromVolume, Volume } = require("memfs"); +const webpack = require(".."); const captureStdio = require("./helpers/captureStdio"); -let webpack; - const createMultiCompiler = (progressOptions, configOptions) => { const compiler = webpack( Object.assign( @@ -36,16 +37,17 @@ const createSimpleCompiler = progressOptions => { entry: "./a.js", infrastructureLogging: { debug: /Progress/ - } + }, + plugins: [ + new webpack.ProgressPlugin({ + activeModules: true, + ...progressOptions + }) + ] }); compiler.outputFileSystem = createFsFromVolume(new Volume()); - new webpack.ProgressPlugin({ - activeModules: true, - ...progressOptions - }).apply(compiler); - return compiler; }; @@ -68,7 +70,7 @@ const createSimpleCompilerWithCustomHandler = options => { const getLogs = logsStr => logsStr.split(/\r/).filter(v => !(v === " ")); -const RunCompilerAsync = compiler => +const runCompilerAsync = compiler => new Promise((resolve, reject) => { compiler.run(err => { if (err) { @@ -86,7 +88,6 @@ describe("ProgressPlugin", function () { beforeEach(() => { stderr = captureStdio(process.stderr, true); stdout = captureStdio(process.stdout, true); - webpack = require(".."); }); afterEach(() => { stderr && stderr.restore(); @@ -96,7 +97,7 @@ describe("ProgressPlugin", function () { const nanTest = createCompiler => () => { const compiler = createCompiler(); - return RunCompilerAsync(compiler).then(() => { + return runCompilerAsync(compiler).then(() => { expect(stderr.toString()).toContain("%"); expect(stderr.toString()).not.toContain("NaN"); }); @@ -111,16 +112,25 @@ describe("ProgressPlugin", function () { nanTest(createMultiCompiler) ); it( - "should not contain NaN as a percentage when it is applied to MultiCompiler (paralellism: 1)", + "should not contain NaN as a percentage when it is applied to MultiCompiler (parallelism: 1)", nanTest(() => createMultiCompiler(undefined, { parallelism: 1 })) ); + it("should start print only on call run/watch", done => { + const compiler = createSimpleCompiler(); + + const logs = getLogs(stderr.toString()); + expect(logs.join("")).toHaveLength(0); + + compiler.close(done); + }); + it("should print profile information", () => { const compiler = createSimpleCompiler({ profile: true }); - return RunCompilerAsync(compiler).then(() => { + return runCompilerAsync(compiler).then(() => { const logs = getLogs(stderr.toString()); expect(logs).toContainEqual( @@ -155,7 +165,7 @@ describe("ProgressPlugin", function () { } }); - return RunCompilerAsync(compiler).then(() => { + return runCompilerAsync(compiler).then(() => { let lastLine = handlerCalls[0]; for (const line of handlerCalls) { if (line.value < lastLine.value) { @@ -185,11 +195,14 @@ describe("ProgressPlugin", function () { const compiler = createSimpleCompiler(); process.stderr.columns = 36; - return RunCompilerAsync(compiler).then(() => { + return runCompilerAsync(compiler).then(() => { const logs = getLogs(stderr.toString()); expect(logs.length).toBeGreaterThan(20); - logs.forEach(log => expect(log.length).toBeLessThanOrEqual(35)); + for (const log of logs) { + expect(log.length).toBeLessThanOrEqual(35); + } + // cspell:ignore mization nsPlugin expect(logs).toContain( "75% sealing ...mization ...nsPlugin", "trims each detail string equally" @@ -203,11 +216,11 @@ describe("ProgressPlugin", function () { const compiler = createSimpleCompiler(); process.stderr.columns = undefined; - return RunCompilerAsync(compiler).then(() => { + return runCompilerAsync(compiler).then(() => { const logs = getLogs(stderr.toString()); expect(logs.length).toBeGreaterThan(20); - expect(_.maxBy(logs, "length").length).toBeGreaterThan(50); + expect(_.maxBy(logs, "length").length).not.toBeGreaterThan(40); }); }); @@ -215,7 +228,7 @@ describe("ProgressPlugin", function () { const compiler = createSimpleCompiler(); process.stderr.columns = undefined; - return RunCompilerAsync(compiler).then(() => { + return runCompilerAsync(compiler).then(() => { const logs = getLogs(stderr.toString()); expect(logs).toContain("4% setup normal module factory"); @@ -231,7 +244,8 @@ describe("ProgressPlugin", function () { activeModules: true }); - return RunCompilerAsync(compiler).then(() => { + process.stderr.columns = 70; + return runCompilerAsync(compiler).then(() => { const logs = stderr.toString(); expect(logs).toEqual(expect.stringMatching(/\d+\/\d+ entries/)); @@ -244,7 +258,8 @@ describe("ProgressPlugin", function () { it("should get the custom handler text from the log", () => { const compiler = createSimpleCompilerWithCustomHandler(); - return RunCompilerAsync(compiler).then(() => { + process.stderr.columns = 70; + return runCompilerAsync(compiler).then(() => { const logs = stderr.toString(); expect(logs).toEqual( expect.stringMatching(/\d+\/\d+ [custom test logger]/) diff --git a/test/README.md b/test/README.md index 4e63b45e268..f460a490b71 100644 --- a/test/README.md +++ b/test/README.md @@ -1,20 +1,25 @@ # Welcome to the webpack test suite!!!! + Every pull request that you submit to webpack (besides README and spelling corrections in comments) requires tests that are created. But don't give up hope!!! Although our tests may appear complex and overwhelming, once you become familiar with the test suite and structure, adding and creating tests will be fun and beneficial as you work inside the codebase! โค ## tl;dr + Run all tests (this automatically runs the setup): + ```sh yarn test ``` Run an individual suite: + ```sh yarn jest ConfigTestCases ``` Watch mode: + ```sh yarn jest --watch ConfigTestCases ``` @@ -22,28 +27,34 @@ yarn jest --watch ConfigTestCases See also: [Jest CLI docs](https://jestjs.io/docs/cli) ## Test suite overview + We use Jest for our tests. For more information on Jest you can visit their [homepage](https://jestjs.io/)! ### Class Tests -All test files can be found in *.test.js. There are many tests that simply test API's of a specific class/file (such as `Compiler`, `Errors`, Integration, `Parser`, `RuleSet`, Validation). + +All test files can be found in \*.test.js. There are many tests that simply test APIs of a specific class/file (such as `Compiler`, `Errors`, Integration, `Parser`, `RuleSet`, Validation). If the feature you are contributing involves one of those classes, then best to start there to understand the structure. ### xCases -In addition to Class specific tests, there are also directories that end in "Cases". The suites for these cases also have corresponding *.test.js files. + +In addition to Class specific tests, there are also directories that end in "Cases". The suites for these cases also have corresponding \*.test.js files. #### cases (`TestCases.test.js`) 1 + Cases are a set of general purpose tests that will run against a variety of permutations of webpack configurations. When you are making a general purpose change that doesn't require you to have a special configuration, you would likely add your tests here. Inside of the `./test/cases` directory you will find tests are broken into thematic sub directories. Take a moment to explore the different options. To add a new case, create a new directory inside of the top level test groups, and then add an `index.js` file (and any other supporting files). By default this file will be the entry point for the test suite and you can add your `it()`'s there. This will also become bundled so that node env support happens as well. -#### configCases (`ConfigTestCases.test.js`) 1 +#### configCases (`ConfigTestCases.basictest.js`) 1 + If you are trying to solve a bug which is reproducible when x and y properties are used together in a config, then configCases is the place to be!!!! In addition to an `index.js`, these configCases require a `webpack.config.js` is located inside of your test suite. This will run this specific config through `webpack` just as you were building individually. They will use the same loading/bundling technique of your `it()` tests, however you now have a more specific config use cases that you can write even before you start coding. -#### statsCases (`StatsTestCases.test.js`) +#### statsCases (`StatsTestCases.basictest.js`) + Stats cases are similar to configCases except specifically focusing on the `expected` output of your stats. Instead of writing to the console, however the output of stats will be written to disk. By default, the "expected" outcome is a pain to write by hand so instead when statsCases are run, runner is checking output using jest's awesome snapshot functionality. @@ -52,21 +63,23 @@ Basically you don't need to write any expected behaviors yourself. The assumptio Please follow the approach described below: -* write your test code in `statsCases/` folder by creating a separate folder for it, for example `statsCases/some-file-import-stats/index.js` +- write your test code in `statsCases/` folder by creating a separate folder for it, for example `statsCases/some-file-import-stats/index.js` ```javascript import("./someModule"); ``` -* don't forget the `webpack.config.js` -* run the test -* jest will automatically add the output from your test code to `StatsTestCases.test.js.snap` and you can always check your results there -* Next time test will run -> runner will compare results against your output written to snapshot previously + +- don't forget the `webpack.config.js` +- run the test +- jest will automatically add the output from your test code to `StatsTestCases.test.js.snap` and you can always check your results there +- Next time test will run -> runner will compare results against your output written to snapshot previously You can read more about SnapShot testing [right here](https://jestjs.io/docs/snapshot-testing) ## Questions? Comments? -If you are still nervous or don't quite understand, please submit an issue and tag us in it, and provide a relevant PR while working on! +If you are still nervous or don't quite understand, please submit an issue and tag us in it, and provide a relevant PR while working on! ## Footnotes -1 webpack's parser supports the use of ES2015 features like arrow functions, harmony exports, etc. However as a library we follow NodeJS's timeline for dropping older versions of node. Because of this we expect your tests on Travis to pass all the way back to NodeJS v10; Therefore if you would like specific tests that use these features to be ignored if they are not supported, then you should add a `test.filter.js` file. This allows you to import the syntax needed for that test, meanwhile ignoring it on node versions (during CI) that don't support it. webpack has a variety of helpful examples you can refer to if you are just starting out. See the `./helpers` folder to find a list of the versions. + +1 webpack's parser supports the use of ES2015 features like arrow functions, harmony exports, etc. However as a library we follow Node.js' timeline for dropping older versions of node. Because of this we expect your tests on GitHub Actions to pass all the way back to NodeJS v10; Therefore if you would like specific tests that use these features to be ignored if they are not supported, then you should add a `test.filter.js` file. This allows you to import the syntax needed for that test, meanwhile ignoring it on node versions (during CI) that don't support it. webpack has a variety of helpful examples you can refer to if you are just starting out. See the `./helpers` folder to find a list of the versions. diff --git a/test/RuntimeTemplate.unittest.js b/test/RuntimeTemplate.unittest.js new file mode 100644 index 00000000000..1cd083e3036 --- /dev/null +++ b/test/RuntimeTemplate.unittest.js @@ -0,0 +1,78 @@ +"use strict"; + +const RuntimeTemplate = require("../lib/RuntimeTemplate"); +const RequestShortener = require("../lib/RequestShortener"); + +describe("RuntimeTemplate.concatenation", () => { + it("no args", () => { + const runtimeTemplate = new RuntimeTemplate( + undefined, + { environment: { templateLiteral: false } }, + new RequestShortener(__dirname) + ); + expect(runtimeTemplate.concatenation()).toBe('""'); + }); + + it("1 arg", () => { + const runtimeTemplate = new RuntimeTemplate( + undefined, + { environment: { templateLiteral: false } }, + new RequestShortener(__dirname) + ); + expect(runtimeTemplate.concatenation({ expr: 1 })).toBe('"" + 1'); + expect(runtimeTemplate.concatenation("str")).toBe('"str"'); + }); + + it("es5", () => { + const runtimeTemplate = new RuntimeTemplate( + undefined, + { environment: { templateLiteral: false } }, + new RequestShortener(__dirname) + ); + + expect( + runtimeTemplate.concatenation({ expr: "__webpack__.p" }, "str/a") + ).toBe('__webpack__.p + "str/a"'); + expect( + runtimeTemplate.concatenation( + { expr: "__webpack__.p" }, + { expr: "str.a" }, + "str" + ) + ).toBe('"" + __webpack__.p + str.a + "str"'); + expect(runtimeTemplate.concatenation("a", "b", { expr: 1 })).toBe( + '"a" + "b" + 1' + ); + expect(runtimeTemplate.concatenation("a", { expr: 1 }, "b")).toBe( + '"a" + 1 + "b"' + ); + }); + + describe("es6", () => { + const runtimeTemplate = new RuntimeTemplate( + undefined, + { environment: { templateLiteral: true } }, + new RequestShortener(__dirname) + ); + + it("should prefer shorten variant #1", () => { + expect(runtimeTemplate.concatenation({ expr: 1 }, "a", { expr: 2 })).toBe( + '1 + "a" + 2' + ); + }); + + it("should prefer shorten variant #2", () => { + expect( + runtimeTemplate.concatenation({ expr: 1 }, "a", { expr: 2 }, "b") + ).toBe('1 + "a" + 2 + "b"'); + }); + + it("should prefer shorten variant #3", () => { + /* eslint-disable no-template-curly-in-string */ + expect(runtimeTemplate.concatenation("a", { expr: 1 }, "b")).toBe( + "`a${1}b`" + ); + /* eslint-enable */ + }); + }); +}); diff --git a/test/SemVer.unittest.js b/test/SemVer.unittest.js index ed37cf4d459..94cc46da336 100644 --- a/test/SemVer.unittest.js +++ b/test/SemVer.unittest.js @@ -36,7 +36,7 @@ describe("SemVer", () => { expect(fn("1.2.3-beta")).toEqual([1, 2, 3, , "beta"]); // eslint-disable-next-line no-sparse-arrays expect(fn("1.2.3-beta.1.2")).toEqual([1, 2, 3, , "beta", 1, 2]); - // eslint-disable-next-line no-sparse-arrays + /* eslint-disable no-sparse-arrays */ expect(fn("1.2.3-alpha.beta-42")).toEqual([ 1, 2, @@ -45,7 +45,6 @@ describe("SemVer", () => { "alpha", "beta-42" ]); - // eslint-disable-next-line no-sparse-arrays expect(fn("1.2.3-beta.1.alpha.0+5343")).toEqual([ 1, 2, @@ -58,6 +57,7 @@ describe("SemVer", () => { [], 5343 ]); + /* eslint-enable no-sparse-arrays */ expect(fn("1.2.3+5343.beta+1")).toEqual([1, 2, 3, [], 5343, "beta+1"]); expect(fn("1.2.3+5343.beta+1")).toEqual([1, 2, 3, [], 5343, "beta+1"]); }); @@ -129,12 +129,27 @@ describe("SemVer", () => { describe("parseRange", () => { const cases = { - "=3": ["3", "v3", "3.x", "3.X", "3.x.x", "3.*", "3.*.*", "^3", "^3.x"], - "=3.0": ["3.0", "v3.0", "3.0.x", "3.0.X", "3.0.*", "~3.0"], - "^3.4": ["^3.4.*"], - "3.4 - 6.5": [">=3.4 <=6.5"], - "<=3.4": ["<3.4 || =3.4"], - ">3.4": [">=3.4 !3.4"] + "5 || 6 || 7.x.x": ["5.x.x || 6.x || 7"], + "1 - 2": ["1 - 2"], + "=3": [ + "3", + "v3", + "3.x", + "3.X", + "3.x.x", + "3.*", + "3.*.*", + "^3", + "^3.x", + "= 3" + ], + "=3.0": ["3.0", "v3.0", "3.0.x", "3.0.X", "3.0.*", "~3.0", "= 3.0"], + "^3.4": ["^3.4.*", "^ 3.4"], + "3.4 - 6.5": [">=3.4 <=6.5", ">= 3.4 <= 6.5"], + "<=3.4": ["<3.4 || =3.4", "<= 3.4"], + ">3.4": [">=3.4 !3.4", "> 3.4"], + "1.2.3-alpha.x.x": ["1.2.3-alpha", "1.2.3-alpha+build.25"], + "1.2.3-NaN": ["1.2.3-NaN"] }; for (const key of Object.keys(cases)) { describe(key, () => { @@ -247,6 +262,19 @@ describe("SemVer", () => { "!1.3", "!1.20" ], + "~1": [ + "1", + "1.1", + "1.2", + "1.2.1", + "1.0.1", + "1.1.1", + "1.3.0", + "!2.0.0", + "!2.3.4", + "!1.0.0-beta", + "!1.1.0-beta" + ], ">=1.beta": [ "!1", "2", @@ -345,6 +373,20 @@ describe("SemVer", () => { "2.beta.alpha+gamma", "!2.beta-4" ], + "~2": [ + "2.0.0", + "2.1.0", + "2.1.1", + "2.2.0", + "!1.0.0", + "2.0.1", + "2.1.2", + "2.3.0", + "!3.0.0", + "!3.6.8", + "!2.0.0-beta", + "!2.1.0-beta" + ], "~2.3.4": [ "2.3.4", "2.3.5", diff --git a/test/SharingUtil.unittest.js b/test/SharingUtil.unittest.js new file mode 100644 index 00000000000..db5ea28003b --- /dev/null +++ b/test/SharingUtil.unittest.js @@ -0,0 +1,970 @@ +"use strict"; + +const { normalizeVersion } = require("../lib/sharing/utils"); + +describe("normalize dep version", () => { + const commonInvalid = [ + "https://github.com#v1.0", + "git://github.com#v1.0", + "other:github.com/foo/bar#v1.0", + "::", + "", + null, + undefined + ]; + + const commonValid = { + "git+ssh://git@github.com:npm/cli.git#v1.0.27": "v1.0.27", + "git+ssh://git@github.com:npm/cli#semver:^5.0": "^5.0", + "git://github.com/npm/cli.git#v1.0.27": "v1.0.27", + "git+https://isaacs@github.com/npm/cli.git": "", + "http://github.com/npm/cli.git#v1.0": "v1.0", + // for uppercase + "http://GITHUB.com/npm/cli.git#v1.0": "v1.0", + "HTTP://github.com/npm/cli.git#v1.0": "v1.0", + "FILE://foo/bar": "", + "file://foo/bar": "", + "v1.2": "v1.2", + "^1.2.0": "^1.2.0", + "git://localhost:12345/foo/bar#v1.0": "v1.0", + "localhost:foo/bar#v1.0": "v1.0" + }; + + const githubInvalid = [ + // foo/bar shorthand but specifying auth + "user@foo/bar#v1.0", + "user:password@foo/bar#v1.0", + ":password@foo/bar#v1.0", + // foo/bar shorthand but with a space in it + "foo/ bar#v1.0", + // string that ends with a slash, probably a directory + "foo/bar/#v1.0", + // git@github.com style, but omitting the username + "github.com:foo/bar#v1.0", + "github.com/foo/bar#v1.0", + // invalid URI encoding + "github:foo%0N/bar#v1.0", + // missing path + "git+ssh://git@github.com:#v1.0", + // a deep url to something we don't know + "https://github.com/foo/bar/issues#v1.0" + ]; + + const githubValid = { + // extreme shorthand (only for github) + "foo/bar": "", + "foo/bar#branch": "branch", + "foo/bar#v1.0": "v1.0", + "foo/bar.git": "", + "foo/bar.git#v1.0": "v1.0", + + // shortcuts + // + // NOTE auth is accepted but ignored + "github:foo/bar": "", + "github:foo/bar#v1.0": "v1.0", + "github:user@foo/bar": "", + "github:user@foo/bar#v1.0": "v1.0", + "github:user:password@foo/bar": "", + "github:user:password@foo/bar#v1.0": "v1.0", + "github::password@foo/bar": "", + "github::password@foo/bar#v1.0": "v1.0", + + "github:foo/bar.git": "", + "github:foo/bar.git#v1.0": "v1.0", + "github:user@foo/bar.git": "", + "github:user@foo/bar.git#v1.0": "v1.0", + "github:user:password@foo/bar.git": "", + "github:user:password@foo/bar.git#v1.0": "v1.0", + "github::password@foo/bar.git": "", + "github::password@foo/bar.git#v1.0": "v1.0", + + // NOTE auth is accepted and respected + "git://github.com/foo/bar": "", + "git://github.com/foo/bar#v1.0": "v1.0", + "git://user@github.com/foo/bar": "", + "git://user@github.com/foo/bar#v1.0": "v1.0", + "git://user:password@github.com/foo/bar": "", + "git://user:password@github.com/foo/bar#v1.0": "v1.0", + "git://:password@github.com/foo/bar": "", + "git://:password@github.com/foo/bar#v1.0": "v1.0", + + "git://github.com/foo/bar.git": "", + "git://github.com/foo/bar.git#v1.0": "v1.0", + "git://git@github.com/foo/bar.git": "", + "git://git@github.com/foo/bar.git#v1.0": "v1.0", + "git://user:password@github.com/foo/bar.git": "", + "git://user:password@github.com/foo/bar.git#v1.0": "v1.0", + "git://:password@github.com/foo/bar.git": "", + "git://:password@github.com/foo/bar.git#v1.0": "v1.0", + + // no-protocol git+ssh + // + // NOTE auth is _required_ (see invalid list) but ignored + "user@github.com:foo/bar": "", + "user@github.com:foo/bar#v1.0": "v1.0", + "user:password@github.com:foo/bar": "", + "user:password@github.com:foo/bar#v1.0": "v1.0", + ":password@github.com:foo/bar": "", + ":password@github.com:foo/bar#v1.0": "v1.0", + + "user@github.com:foo/bar.git": "", + "user@github.com:foo/bar.git#v1.0": "v1.0", + "user:password@github.com:foo/bar.git": "", + "user:password@github.com:foo/bar.git#v1.0": "v1.0", + ":password@github.com:foo/bar.git": "", + ":password@github.com:foo/bar.git#v1.0": "v1.0", + + // git+ssh urls + // + // NOTE auth is accepted but ignored + "git+ssh://github.com:foo/bar": "", + "git+ssh://github.com:foo/bar#v1.0": "v1.0", + "git+ssh://user@github.com:foo/bar": "", + "git+ssh://user@github.com:foo/bar#v1.0": "v1.0", + "git+ssh://user:password@github.com:foo/bar": "", + "git+ssh://user:password@github.com:foo/bar#v1.0": "v1.0", + "git+ssh://:password@github.com:foo/bar": "", + "git+ssh://:password@github.com:foo/bar#v1.0": "v1.0", + + "git+ssh://github.com:foo/bar.git": "", + "git+ssh://github.com:foo/bar.git#v1.0": "v1.0", + "git+ssh://user@github.com:foo/bar.git": "", + "git+ssh://user@github.com:foo/bar.git#v1.0": "v1.0", + "git+ssh://user:password@github.com:foo/bar.git": "", + "git+ssh://user:password@github.com:foo/bar.git#v1.0": "v1.0", + "git+ssh://:password@github.com:foo/bar.git": "", + "git+ssh://:password@github.com:foo/bar.git#v1.0": "v1.0", + + // ssh urls + // + // NOTE auth is accepted but ignored + "ssh://github.com:foo/bar": "", + "ssh://github.com:foo/bar#v1.0": "v1.0", + "ssh://user@github.com:foo/bar": "", + "ssh://user@github.com:foo/bar#v1.0": "v1.0", + "ssh://user:password@github.com:foo/bar": "", + "ssh://user:password@github.com:foo/bar#v1.0": "v1.0", + "ssh://:password@github.com:foo/bar": "", + "ssh://:password@github.com:foo/bar#v1.0": "v1.0", + + "ssh://github.com:foo/bar.git": "", + "ssh://github.com:foo/bar.git#v1.0": "v1.0", + "ssh://user@github.com:foo/bar.git": "", + "ssh://user@github.com:foo/bar.git#v1.0": "v1.0", + "ssh://user:password@github.com:foo/bar.git": "", + "ssh://user:password@github.com:foo/bar.git#v1.0": "v1.0", + "ssh://:password@github.com:foo/bar.git": "", + "ssh://:password@github.com:foo/bar.git#v1.0": "v1.0", + + // git+https urls + // + // NOTE auth is accepted and respected + "git+https://github.com/foo/bar": "", + "git+https://github.com/foo/bar#v1.0": "v1.0", + "git+https://user@github.com/foo/bar": "", + "git+https://user@github.com/foo/bar#v1.0": "v1.0", + "git+https://user:password@github.com/foo/bar": "", + "git+https://user:password@github.com/foo/bar#v1.0": "v1.0", + "git+https://:password@github.com/foo/bar": "", + "git+https://:password@github.com/foo/bar#v1.0": "v1.0", + + "git+https://github.com/foo/bar.git": "", + "git+https://github.com/foo/bar.git#v1.0": "v1.0", + "git+https://user@github.com/foo/bar.git": "", + "git+https://user@github.com/foo/bar.git#v1.0": "v1.0", + "git+https://user:password@github.com/foo/bar.git": "", + "git+https://user:password@github.com/foo/bar.git#v1.0": "v1.0", + "git+https://:password@github.com/foo/bar.git": "", + "git+https://:password@github.com/foo/bar.git#v1.0": "v1.0", + + // https urls + // + // NOTE auth is accepted and respected + "https://github.com/foo/bar": "", + "https://github.com/foo/bar#v1.0": "v1.0", + "https://user@github.com/foo/bar": "", + "https://user@github.com/foo/bar#v1.0": "v1.0", + "https://user:password@github.com/foo/bar": "", + "https://user:password@github.com/foo/bar#v1.0": "v1.0", + "https://:password@github.com/foo/bar": "", + "https://:password@github.com/foo/bar#v1.0": "v1.0", + + "https://github.com/foo/bar.git": "", + "https://github.com/foo/bar.git#v1.0": "v1.0", + "https://user@github.com/foo/bar.git": "", + "https://user@github.com/foo/bar.git#v1.0": "v1.0", + "https://user:password@github.com/foo/bar.git": "", + "https://user:password@github.com/foo/bar.git#v1.0": "v1.0", + "https://:password@github.com/foo/bar.git": "", + "https://:password@github.com/foo/bar.git#v1.0": "v1.0", + + // inputs that are not quite proper but we accept anyway + "https://www.github.com/foo/bar": "", + "foo/bar#branch with space": "branch with space", + "https://github.com/foo/bar/tree/branch": "branch", + "user..test--/..foo-js# . . . . . some . tags / / /": + " . . . . . some . tags / / /" + }; + + const gitlabInvalid = [ + // gitlab urls can contain a /-/ segment, make sure we ignore those + "https://gitlab.com/foo/-/something", + // missing project + "https://gitlab.com/foo", + // tarball, this should not parse so that it can be used for a remote package fetcher + "https://gitlab.com/foo/bar/repository/archive.tar.gz", + "https://gitlab.com/foo/bar/repository/archive.tar.gz?ref=49b393e2ded775f2df36ef2ffcb61b0359c194c9" + ]; + + const gitlabValid = { + // shortcuts + // + // NOTE auth is accepted but ignored + // NOTE subgroups are respected, but the subgroup is treated as the project and the real project is lost + "gitlab:foo/bar": "", + "gitlab:foo/bar#v1.0": "v1.0", + "gitlab:user@foo/bar": "", + "gitlab:user@foo/bar#v1.0": "v1.0", + "gitlab:user:password@foo/bar": "", + "gitlab:user:password@foo/bar#v1.0": "v1.0", + "gitlab::password@foo/bar": "", + "gitlab::password@foo/bar#v1.0": "v1.0", + + "gitlab:foo/bar.git": "", + "gitlab:foo/bar.git#v1.0": "v1.0", + "gitlab:user@foo/bar.git": "", + "gitlab:user@foo/bar.git#v1.0": "v1.0", + "gitlab:user:password@foo/bar.git": "", + "gitlab:user:password@foo/bar.git#v1.0": "v1.0", + "gitlab::password@foo/bar.git": "", + "gitlab::password@foo/bar.git#v1.0": "v1.0", + + "gitlab:foo/bar/baz": "", + "gitlab:foo/bar/baz#v1.0": "v1.0", + "gitlab:user@foo/bar/baz": "", + "gitlab:user@foo/bar/baz#v1.0": "v1.0", + "gitlab:user:password@foo/bar/baz": "", + "gitlab:user:password@foo/bar/baz#v1.0": "v1.0", + "gitlab::password@foo/bar/baz": "", + "gitlab::password@foo/bar/baz#v1.0": "v1.0", + + "gitlab:foo/bar/baz.git": "", + "gitlab:foo/bar/baz.git#v1.0": "v1.0", + "gitlab:user@foo/bar/baz.git": "", + "gitlab:user@foo/bar/baz.git#v1.0": "v1.0", + "gitlab:user:password@foo/bar/baz.git": "", + "gitlab:user:password@foo/bar/baz.git#v1.0": "v1.0", + "gitlab::password@foo/bar/baz.git": "", + "gitlab::password@foo/bar/baz.git#v1.0": "v1.0", + + // no-protocol git+ssh + // + // NOTE auth is _required_ (see invalid list) but ignored + "user@gitlab.com:foo/bar": "", + "user@gitlab.com:foo/bar#v1.0": "v1.0", + "user:password@gitlab.com:foo/bar": "", + "user:password@gitlab.com:foo/bar#v1.0": "v1.0", + ":password@gitlab.com:foo/bar": "", + ":password@gitlab.com:foo/bar#v1.0": "v1.0", + + "user@gitlab.com:foo/bar.git": "", + "user@gitlab.com:foo/bar.git#v1.0": "v1.0", + "user:password@gitlab.com:foo/bar.git": "", + "user:password@gitlab.com:foo/bar.git#v1.0": "v1.0", + ":password@gitlab.com:foo/bar.git": "", + ":password@gitlab.com:foo/bar.git#v1.0": "v1.0", + + "user@gitlab.com:foo/bar/baz": "", + "user@gitlab.com:foo/bar/baz#v1.0": "v1.0", + "user:password@gitlab.com:foo/bar/baz": "", + "user:password@gitlab.com:foo/bar/baz#v1.0": "v1.0", + ":password@gitlab.com:foo/bar/baz": "", + ":password@gitlab.com:foo/bar/baz#v1.0": "v1.0", + + "user@gitlab.com:foo/bar/baz.git": "", + "user@gitlab.com:foo/bar/baz.git#v1.0": "v1.0", + "user:password@gitlab.com:foo/bar/baz.git": "", + "user:password@gitlab.com:foo/bar/baz.git#v1.0": "v1.0", + ":password@gitlab.com:foo/bar/baz.git": "", + ":password@gitlab.com:foo/bar/baz.git#v1.0": "v1.0", + + // git+ssh urls + // + // NOTE auth is accepted but ignored + // NOTE sub projects are accepted, but the sub project is treated as the project and the real project is lost + "git+ssh://gitlab.com:foo/bar": "", + "git+ssh://gitlab.com:foo/bar#v1.0": "v1.0", + "git+ssh://user@gitlab.com:foo/bar": "", + "git+ssh://user@gitlab.com:foo/bar#v1.0": "v1.0", + "git+ssh://user:password@gitlab.com:foo/bar": "", + "git+ssh://user:password@gitlab.com:foo/bar#v1.0": "v1.0", + "git+ssh://:password@gitlab.com:foo/bar": "", + "git+ssh://:password@gitlab.com:foo/bar#v1.0": "v1.0", + + "git+ssh://gitlab.com:foo/bar.git": "", + "git+ssh://gitlab.com:foo/bar.git#v1.0": "v1.0", + "git+ssh://user@gitlab.com:foo/bar.git": "", + "git+ssh://user@gitlab.com:foo/bar.git#v1.0": "v1.0", + "git+ssh://user:password@gitlab.com:foo/bar.git": "", + "git+ssh://user:password@gitlab.com:foo/bar.git#v1.0": "v1.0", + "git+ssh://:password@gitlab.com:foo/bar.git": "", + "git+ssh://:password@gitlab.com:foo/bar.git#v1.0": "v1.0", + + "git+ssh://gitlab.com:foo/bar/baz": "", + "git+ssh://gitlab.com:foo/bar/baz#v1.0": "v1.0", + "git+ssh://user@gitlab.com:foo/bar/baz": "", + "git+ssh://user@gitlab.com:foo/bar/baz#v1.0": "v1.0", + "git+ssh://user:password@gitlab.com:foo/bar/baz": "", + "git+ssh://user:password@gitlab.com:foo/bar/baz#v1.0": "v1.0", + "git+ssh://:password@gitlab.com:foo/bar/baz": "", + "git+ssh://:password@gitlab.com:foo/bar/baz#v1.0": "v1.0", + + "git+ssh://gitlab.com:foo/bar/baz.git": "", + "git+ssh://gitlab.com:foo/bar/baz.git#v1.0": "v1.0", + "git+ssh://user@gitlab.com:foo/bar/baz.git": "", + "git+ssh://user@gitlab.com:foo/bar/baz.git#v1.0": "v1.0", + "git+ssh://user:password@gitlab.com:foo/bar/baz.git": "", + "git+ssh://user:password@gitlab.com:foo/bar/baz.git#v1.0": "v1.0", + "git+ssh://:password@gitlab.com:foo/bar/baz.git": "", + "git+ssh://:password@gitlab.com:foo/bar/baz.git#v1.0": "v1.0", + + // ssh urls + // + // NOTE auth is accepted but ignored + // NOTE sub projects are accepted, but the sub project is treated as the project and the real project is lost + "ssh://gitlab.com:foo/bar": "", + "ssh://gitlab.com:foo/bar#v1.0": "v1.0", + "ssh://user@gitlab.com:foo/bar": "", + "ssh://user@gitlab.com:foo/bar#v1.0": "v1.0", + "ssh://user:password@gitlab.com:foo/bar": "", + "ssh://user:password@gitlab.com:foo/bar#v1.0": "v1.0", + "ssh://:password@gitlab.com:foo/bar": "", + "ssh://:password@gitlab.com:foo/bar#v1.0": "v1.0", + + "ssh://gitlab.com:foo/bar.git": "", + "ssh://gitlab.com:foo/bar.git#v1.0": "v1.0", + "ssh://user@gitlab.com:foo/bar.git": "", + "ssh://user@gitlab.com:foo/bar.git#v1.0": "v1.0", + "ssh://user:password@gitlab.com:foo/bar.git": "", + "ssh://user:password@gitlab.com:foo/bar.git#v1.0": "v1.0", + "ssh://:password@gitlab.com:foo/bar.git": "", + "ssh://:password@gitlab.com:foo/bar.git#v1.0": "v1.0", + + "ssh://gitlab.com:foo/bar/baz": "", + "ssh://gitlab.com:foo/bar/baz#v1.0": "v1.0", + "ssh://user@gitlab.com:foo/bar/baz": "", + "ssh://user@gitlab.com:foo/bar/baz#v1.0": "v1.0", + "ssh://user:password@gitlab.com:foo/bar/baz": "", + "ssh://user:password@gitlab.com:foo/bar/baz#v1.0": "v1.0", + "ssh://:password@gitlab.com:foo/bar/baz": "", + "ssh://:password@gitlab.com:foo/bar/baz#v1.0": "v1.0", + + "ssh://gitlab.com:foo/bar/baz.git": "", + "ssh://gitlab.com:foo/bar/baz.git#v1.0": "v1.0", + "ssh://user@gitlab.com:foo/bar/baz.git": "", + "ssh://user@gitlab.com:foo/bar/baz.git#v1.0": "v1.0", + "ssh://user:password@gitlab.com:foo/bar/baz.git": "", + "ssh://user:password@gitlab.com:foo/bar/baz.git#v1.0": "v1.0", + "ssh://:password@gitlab.com:foo/bar/baz.git": "", + "ssh://:password@gitlab.com:foo/bar/baz.git#v1.0": "v1.0", + + // git+https urls + // + // NOTE auth is accepted and respected + // NOTE sub projects are accepted, but the sub project is treated as the project and the real project is lost + "git+https://gitlab.com/foo/bar": "", + "git+https://gitlab.com/foo/bar#v1.0": "v1.0", + "git+https://user@gitlab.com/foo/bar": "", + "git+https://user@gitlab.com/foo/bar#v1.0": "v1.0", + "git+https://user:password@gitlab.com/foo/bar": "", + "git+https://user:password@gitlab.com/foo/bar#v1.0": "v1.0", + "git+https://:password@gitlab.com/foo/bar": "", + "git+https://:password@gitlab.com/foo/bar#v1.0": "v1.0", + + "git+https://gitlab.com/foo/bar.git": "", + "git+https://gitlab.com/foo/bar.git#v1.0": "v1.0", + "git+https://user@gitlab.com/foo/bar.git": "", + "git+https://user@gitlab.com/foo/bar.git#v1.0": "v1.0", + "git+https://user:password@gitlab.com/foo/bar.git": "", + "git+https://user:password@gitlab.com/foo/bar.git#v1.0": "v1.0", + "git+https://:password@gitlab.com/foo/bar.git": "", + "git+https://:password@gitlab.com/foo/bar.git#v1.0": "v1.0", + + "git+https://gitlab.com/foo/bar/baz": "", + "git+https://gitlab.com/foo/bar/baz#v1.0": "v1.0", + "git+https://user@gitlab.com/foo/bar/baz": "", + "git+https://user@gitlab.com/foo/bar/baz#v1.0": "v1.0", + "git+https://user:password@gitlab.com/foo/bar/baz": "", + "git+https://user:password@gitlab.com/foo/bar/baz#v1.0": "v1.0", + "git+https://:password@gitlab.com/foo/bar/baz": "", + "git+https://:password@gitlab.com/foo/bar/baz#v1.0": "v1.0", + + "git+https://gitlab.com/foo/bar/baz.git": "", + "git+https://gitlab.com/foo/bar/baz.git#v1.0": "v1.0", + "git+https://user@gitlab.com/foo/bar/baz.git": "", + "git+https://user@gitlab.com/foo/bar/baz.git#v1.0": "v1.0", + "git+https://user:password@gitlab.com/foo/bar/baz.git": "", + "git+https://user:password@gitlab.com/foo/bar/baz.git#v1.0": "v1.0", + "git+https://:password@gitlab.com/foo/bar/baz.git": "", + "git+https://:password@gitlab.com/foo/bar/baz.git#v1.0": "v1.0", + + // https urls + // + // NOTE auth is accepted and respected + // NOTE sub projects are accepted, but the sub project is treated as the project and the real project is lost + "https://gitlab.com/foo/bar": "", + "https://gitlab.com/foo/bar#v1.0": "v1.0", + "https://user@gitlab.com/foo/bar": "", + "https://user@gitlab.com/foo/bar#v1.0": "v1.0", + "https://user:password@gitlab.com/foo/bar": "", + "https://user:password@gitlab.com/foo/bar#v1.0": "v1.0", + "https://:password@gitlab.com/foo/bar": "", + "https://:password@gitlab.com/foo/bar#v1.0": "v1.0", + + "https://gitlab.com/foo/bar.git": "", + "https://gitlab.com/foo/bar.git#v1.0": "v1.0", + "https://user@gitlab.com/foo/bar.git": "", + "https://user@gitlab.com/foo/bar.git#v1.0": "v1.0", + "https://user:password@gitlab.com/foo/bar.git": "", + "https://user:password@gitlab.com/foo/bar.git#v1.0": "v1.0", + "https://:password@gitlab.com/foo/bar.git": "", + "https://:password@gitlab.com/foo/bar.git#v1.0": "v1.0", + + "https://gitlab.com/foo/bar/baz": "", + "https://gitlab.com/foo/bar/baz#v1.0": "v1.0", + "https://user@gitlab.com/foo/bar/baz": "", + "https://user@gitlab.com/foo/bar/baz#v1.0": "v1.0", + "https://user:password@gitlab.com/foo/bar/baz": "", + "https://user:password@gitlab.com/foo/bar/baz#v1.0": "v1.0", + "https://:password@gitlab.com/foo/bar/baz": "", + "https://:password@gitlab.com/foo/bar/baz#v1.0": "v1.0", + + "https://gitlab.com/foo/bar/baz.git": "", + "https://gitlab.com/foo/bar/baz.git#v1.0": "v1.0", + "https://user@gitlab.com/foo/bar/baz.git": "", + "https://user@gitlab.com/foo/bar/baz.git#v1.0": "v1.0", + "https://user:password@gitlab.com/foo/bar/baz.git": "", + "https://user:password@gitlab.com/foo/bar/baz.git#v1.0": "v1.0", + "https://:password@gitlab.com/foo/bar/baz.git": "", + "https://:password@gitlab.com/foo/bar/baz.git#v1.0": "v1.0" + }; + + const bitbucketInvalid = [ + // invalid protocol + "git://bitbucket.org/foo/bar", + // url to get a tarball + "https://bitbucket.org/foo/bar/get/archive.tar.gz", + // missing project + "https://bitbucket.org/foo" + ]; + + const bitbucketValid = { + // shortcuts + // + // NOTE auth is accepted but ignored + "bitbucket:foo/bar": "", + "bitbucket:foo/bar#v1.0": "v1.0", + "bitbucket:user@foo/bar": "", + "bitbucket:user@foo/bar#v1.0": "v1.0", + "bitbucket:user:password@foo/bar": "", + "bitbucket:user:password@foo/bar#v1.0": "v1.0", + "bitbucket::password@foo/bar": "", + "bitbucket::password@foo/bar#v1.0": "v1.0", + + "bitbucket:foo/bar.git": "", + "bitbucket:foo/bar.git#v1.0": "v1.0", + "bitbucket:user@foo/bar.git": "", + "bitbucket:user@foo/bar.git#v1.0": "v1.0", + "bitbucket:user:password@foo/bar.git": "", + "bitbucket:user:password@foo/bar.git#v1.0": "v1.0", + "bitbucket::password@foo/bar.git": "", + "bitbucket::password@foo/bar.git#v1.0": "v1.0", + + // no-protocol git+ssh + // + // NOTE auth is accepted but ignored + "git@bitbucket.org:foo/bar": "", + "git@bitbucket.org:foo/bar#v1.0": "v1.0", + "user@bitbucket.org:foo/bar": "", + "user@bitbucket.org:foo/bar#v1.0": "v1.0", + "user:password@bitbucket.org:foo/bar": "", + "user:password@bitbucket.org:foo/bar#v1.0": "v1.0", + ":password@bitbucket.org:foo/bar": "", + ":password@bitbucket.org:foo/bar#v1.0": "v1.0", + + "git@bitbucket.org:foo/bar.git": "", + "git@bitbucket.org:foo/bar.git#v1.0": "v1.0", + "user@bitbucket.org:foo/bar.git": "", + "user@bitbucket.org:foo/bar.git#v1.0": "v1.0", + "user:password@bitbucket.org:foo/bar.git": "", + "user:password@bitbucket.org:foo/bar.git#v1.0": "v1.0", + ":password@bitbucket.org:foo/bar.git": "", + ":password@bitbucket.org:foo/bar.git#v1.0": "v1.0", + + // git+ssh urls + // + // NOTE auth is accepted but ignored + "git+ssh://bitbucket.org:foo/bar": "", + "git+ssh://bitbucket.org:foo/bar#v1.0": "v1.0", + "git+ssh://user@bitbucket.org:foo/bar": "", + "git+ssh://user@bitbucket.org:foo/bar#v1.0": "v1.0", + "git+ssh://user:password@bitbucket.org:foo/bar": "", + "git+ssh://user:password@bitbucket.org:foo/bar#v1.0": "v1.0", + "git+ssh://:password@bitbucket.org:foo/bar": "", + "git+ssh://:password@bitbucket.org:foo/bar#v1.0": "v1.0", + + "git+ssh://bitbucket.org:foo/bar.git": "", + "git+ssh://bitbucket.org:foo/bar.git#v1.0": "v1.0", + "git+ssh://user@bitbucket.org:foo/bar.git": "", + "git+ssh://user@bitbucket.org:foo/bar.git#v1.0": "v1.0", + "git+ssh://user:password@bitbucket.org:foo/bar.git": "", + "git+ssh://user:password@bitbucket.org:foo/bar.git#v1.0": "v1.0", + "git+ssh://:password@bitbucket.org:foo/bar.git": "", + "git+ssh://:password@bitbucket.org:foo/bar.git#v1.0": "v1.0", + + // ssh urls + // + // NOTE auth is accepted but ignored + "ssh://bitbucket.org:foo/bar": "", + "ssh://bitbucket.org:foo/bar#v1.0": "v1.0", + "ssh://user@bitbucket.org:foo/bar": "", + "ssh://user@bitbucket.org:foo/bar#v1.0": "v1.0", + "ssh://user:password@bitbucket.org:foo/bar": "", + "ssh://user:password@bitbucket.org:foo/bar#v1.0": "v1.0", + "ssh://:password@bitbucket.org:foo/bar": "", + "ssh://:password@bitbucket.org:foo/bar#v1.0": "v1.0", + + "ssh://bitbucket.org:foo/bar.git": "", + "ssh://bitbucket.org:foo/bar.git#v1.0": "v1.0", + "ssh://user@bitbucket.org:foo/bar.git": "", + "ssh://user@bitbucket.org:foo/bar.git#v1.0": "v1.0", + "ssh://user:password@bitbucket.org:foo/bar.git": "", + "ssh://user:password@bitbucket.org:foo/bar.git#v1.0": "v1.0", + "ssh://:password@bitbucket.org:foo/bar.git": "", + "ssh://:password@bitbucket.org:foo/bar.git#v1.0": "v1.0", + + // git+https urls + // + // NOTE auth is accepted and respected + "git+https://bitbucket.org/foo/bar": "", + "git+https://bitbucket.org/foo/bar#v1.0": "v1.0", + "git+https://user@bitbucket.org/foo/bar": "", + "git+https://user@bitbucket.org/foo/bar#v1.0": "v1.0", + "git+https://user:password@bitbucket.org/foo/bar": "", + "git+https://user:password@bitbucket.org/foo/bar#v1.0": "v1.0", + "git+https://:password@bitbucket.org/foo/bar": "", + "git+https://:password@bitbucket.org/foo/bar#v1.0": "v1.0", + + "git+https://bitbucket.org/foo/bar.git": "", + "git+https://bitbucket.org/foo/bar.git#v1.0": "v1.0", + "git+https://user@bitbucket.org/foo/bar.git": "", + "git+https://user@bitbucket.org/foo/bar.git#v1.0": "v1.0", + "git+https://user:password@bitbucket.org/foo/bar.git": "", + "git+https://user:password@bitbucket.org/foo/bar.git#v1.0": "v1.0", + "git+https://:password@bitbucket.org/foo/bar.git": "", + "git+https://:password@bitbucket.org/foo/bar.git#v1.0": "v1.0", + + // https urls + // + // NOTE auth is accepted and respected + "https://bitbucket.org/foo/bar": "", + "https://bitbucket.org/foo/bar#v1.0": "v1.0", + "https://user@bitbucket.org/foo/bar": "", + "https://user@bitbucket.org/foo/bar#v1.0": "v1.0", + "https://user:password@bitbucket.org/foo/bar": "", + "https://user:password@bitbucket.org/foo/bar#v1.0": "v1.0", + "https://:password@bitbucket.org/foo/bar": "", + "https://:password@bitbucket.org/foo/bar#v1.0": "v1.0", + + "https://bitbucket.org/foo/bar.git": "", + "https://bitbucket.org/foo/bar.git#v1.0": "v1.0", + "https://user@bitbucket.org/foo/bar.git": "", + "https://user@bitbucket.org/foo/bar.git#v1.0": "v1.0", + "https://user:password@bitbucket.org/foo/bar.git": "", + "https://user:password@bitbucket.org/foo/bar.git#v1.0": "v1.0", + "https://:password@bitbucket.org/foo/bar.git": "", + "https://:password@bitbucket.org/foo/bar.git#v1.0": "v1.0" + }; + + const gistInvalid = [ + // raw urls that are wrong anyway but for some reason are in the wild + "https://gist.github.com/foo/feed/raw/fix%2Fbug/", + // missing both user and project + "https://gist.github.com/" + ]; + + const gistValid = { + // shortcuts + // + // NOTE auth is accepted but ignored + "gist:feed": "", + "gist:feed#v1.0": "v1.0", + "gist:user@feed": "", + "gist:user@feed#v1.0": "v1.0", + "gist:user:password@feed": "", + "gist:user:password@feed#v1.0": "v1.0", + "gist::password@feed": "", + "gist::password@feed#v1.0": "v1.0", + + "gist:feed.git": "", + "gist:feed.git#v1.0": "v1.0", + "gist:user@feed.git": "", + "gist:user@feed.git#v1.0": "v1.0", + "gist:user:password@feed.git": "", + "gist:user:password@feed.git#v1.0": "v1.0", + "gist::password@feed.git": "", + "gist::password@feed.git#v1.0": "v1.0", + + "gist:/feed": "", + "gist:/feed#v1.0": "v1.0", + "gist:user@/feed": "", + "gist:user@/feed#v1.0": "v1.0", + "gist:user:password@/feed": "", + "gist:user:password@/feed#v1.0": "v1.0", + "gist::password@/feed": "", + "gist::password@/feed#v1.0": "v1.0", + + "gist:/feed.git": "", + "gist:/feed.git#v1.0": "v1.0", + "gist:user@/feed.git": "", + "gist:user@/feed.git#v1.0": "v1.0", + "gist:user:password@/feed.git": "", + "gist:user:password@/feed.git#v1.0": "v1.0", + "gist::password@/feed.git": "", + "gist::password@/feed.git#v1.0": "v1.0", + + "gist:foo/feed": "", + "gist:foo/feed#v1.0": "v1.0", + "gist:user@foo/feed": "", + "gist:user@foo/feed#v1.0": "v1.0", + "gist:user:password@foo/feed": "", + "gist:user:password@foo/feed#v1.0": "v1.0", + "gist::password@foo/feed": "", + "gist::password@foo/feed#v1.0": "v1.0", + + "gist:foo/feed.git": "", + "gist:foo/feed.git#v1.0": "v1.0", + "gist:user@foo/feed.git": "", + "gist:user@foo/feed.git#v1.0": "v1.0", + "gist:user:password@foo/feed.git": "", + "gist:user:password@foo/feed.git#v1.0": "v1.0", + "gist::password@foo/feed.git": "", + "gist::password@foo/feed.git#v1.0": "v1.0", + + // git urls + // + // NOTE auth is accepted and respected + "git://gist.github.com/feed": "", + "git://gist.github.com/feed#v1.0": "v1.0", + "git://user@gist.github.com/feed": "", + "git://user@gist.github.com/feed#v1.0": "v1.0", + "git://user:password@gist.github.com/feed": "", + "git://user:password@gist.github.com/feed#v1.0": "v1.0", + "git://:password@gist.github.com/feed": "", + "git://:password@gist.github.com/feed#v1.0": "v1.0", + + "git://gist.github.com/feed.git": "", + "git://gist.github.com/feed.git#v1.0": "v1.0", + "git://user@gist.github.com/feed.git": "", + "git://user@gist.github.com/feed.git#v1.0": "v1.0", + "git://user:password@gist.github.com/feed.git": "", + "git://user:password@gist.github.com/feed.git#v1.0": "v1.0", + "git://:password@gist.github.com/feed.git": "", + "git://:password@gist.github.com/feed.git#v1.0": "v1.0", + + "git://gist.github.com/foo/feed": "", + "git://gist.github.com/foo/feed#v1.0": "v1.0", + "git://user@gist.github.com/foo/feed": "", + "git://user@gist.github.com/foo/feed#v1.0": "v1.0", + "git://user:password@gist.github.com/foo/feed": "", + "git://user:password@gist.github.com/foo/feed#v1.0": "v1.0", + "git://:password@gist.github.com/foo/feed": "", + "git://:password@gist.github.com/foo/feed#v1.0": "v1.0", + + "git://gist.github.com/foo/feed.git": "", + "git://gist.github.com/foo/feed.git#v1.0": "v1.0", + "git://user@gist.github.com/foo/feed.git": "", + "git://user@gist.github.com/foo/feed.git#v1.0": "v1.0", + "git://user:password@gist.github.com/foo/feed.git": "", + "git://user:password@gist.github.com/foo/feed.git#v1.0": "v1.0", + "git://:password@gist.github.com/foo/feed.git": "", + "git://:password@gist.github.com/foo/feed.git#v1.0": "v1.0", + + // no-protocol git+ssh + // + // NOTE auth is accepted and ignored + "git@gist.github.com:feed": "", + "git@gist.github.com:feed#v1.0": "v1.0", + "user@gist.github.com:feed": "", + "user@gist.github.com:feed#v1.0": "v1.0", + "user:password@gist.github.com:feed": "", + "user:password@gist.github.com:feed#v1.0": "v1.0", + ":password@gist.github.com:feed": "", + ":password@gist.github.com:feed#v1.0": "v1.0", + + "git@gist.github.com:feed.git": "", + "git@gist.github.com:feed.git#v1.0": "v1.0", + "user@gist.github.com:feed.git": "", + "user@gist.github.com:feed.git#v1.0": "v1.0", + "user:password@gist.github.com:feed.git": "", + "user:password@gist.github.com:feed.git#v1.0": "v1.0", + ":password@gist.github.com:feed.git": "", + ":password@gist.github.com:feed.git#v1.0": "v1.0", + + "git@gist.github.com:foo/feed": "", + "git@gist.github.com:foo/feed#v1.0": "v1.0", + "user@gist.github.com:foo/feed": "", + "user@gist.github.com:foo/feed#v1.0": "v1.0", + "user:password@gist.github.com:foo/feed": "", + "user:password@gist.github.com:foo/feed#v1.0": "v1.0", + ":password@gist.github.com:foo/feed": "", + ":password@gist.github.com:foo/feed#v1.0": "v1.0", + + "git@gist.github.com:foo/feed.git": "", + "git@gist.github.com:foo/feed.git#v1.0": "v1.0", + "user@gist.github.com:foo/feed.git": "", + "user@gist.github.com:foo/feed.git#v1.0": "v1.0", + "user:password@gist.github.com:foo/feed.git": "", + "user:password@gist.github.com:foo/feed.git#v1.0": "v1.0", + ":password@gist.github.com:foo/feed.git": "", + ":password@gist.github.com:foo/feed.git#v1.0": "v1.0", + + // git+ssh urls + // + // NOTE auth is accepted but ignored + // NOTE see TODO at list of invalids, some inputs fail and shouldn't + "git+ssh://gist.github.com:feed": "", + "git+ssh://gist.github.com:feed#v1.0": "v1.0", + "git+ssh://user@gist.github.com:feed": "", + "git+ssh://user@gist.github.com:feed#v1.0": "v1.0", + "git+ssh://user:password@gist.github.com:feed": "", + "git+ssh://user:password@gist.github.com:feed#v1.0": "v1.0", + "git+ssh://:password@gist.github.com:feed": "", + "git+ssh://:password@gist.github.com:feed#v1.0": "v1.0", + + "git+ssh://gist.github.com:feed.git": "", + "git+ssh://gist.github.com:feed.git#v1.0": "v1.0", + "git+ssh://user@gist.github.com:feed.git": "", + "git+ssh://user@gist.github.com:feed.git#v1.0": "v1.0", + "git+ssh://user:password@gist.github.com:feed.git": "", + "git+ssh://user:password@gist.github.com:feed.git#v1.0": "v1.0", + "git+ssh://:password@gist.github.com:feed.git": "", + "git+ssh://:password@gist.github.com:feed.git#v1.0": "v1.0", + + "git+ssh://gist.github.com:foo/feed": "", + "git+ssh://gist.github.com:foo/feed#v1.0": "v1.0", + "git+ssh://user@gist.github.com:foo/feed": "", + "git+ssh://user@gist.github.com:foo/feed#v1.0": "v1.0", + "git+ssh://user:password@gist.github.com:foo/feed": "", + "git+ssh://user:password@gist.github.com:foo/feed#v1.0": "v1.0", + "git+ssh://:password@gist.github.com:foo/feed": "", + "git+ssh://:password@gist.github.com:foo/feed#v1.0": "v1.0", + + "git+ssh://gist.github.com:foo/feed.git": "", + "git+ssh://gist.github.com:foo/feed.git#v1.0": "v1.0", + "git+ssh://user@gist.github.com:foo/feed.git": "", + "git+ssh://user@gist.github.com:foo/feed.git#v1.0": "v1.0", + "git+ssh://user:password@gist.github.com:foo/feed.git": "", + "git+ssh://user:password@gist.github.com:foo/feed.git#v1.0": "v1.0", + "git+ssh://:password@gist.github.com:foo/feed.git": "", + "git+ssh://:password@gist.github.com:foo/feed.git#v1.0": "v1.0", + + // ssh urls + // + // NOTE auth is accepted but ignored + "ssh://gist.github.com:feed": "", + "ssh://gist.github.com:feed#v1.0": "v1.0", + "ssh://user@gist.github.com:feed": "", + "ssh://user@gist.github.com:feed#v1.0": "v1.0", + "ssh://user:password@gist.github.com:feed": "", + "ssh://user:password@gist.github.com:feed#v1.0": "v1.0", + "ssh://:password@gist.github.com:feed": "", + "ssh://:password@gist.github.com:feed#v1.0": "v1.0", + + "ssh://gist.github.com:feed.git": "", + "ssh://gist.github.com:feed.git#v1.0": "v1.0", + "ssh://user@gist.github.com:feed.git": "", + "ssh://user@gist.github.com:feed.git#v1.0": "v1.0", + "ssh://user:password@gist.github.com:feed.git": "", + "ssh://user:password@gist.github.com:feed.git#v1.0": "v1.0", + "ssh://:password@gist.github.com:feed.git": "", + "ssh://:password@gist.github.com:feed.git#v1.0": "v1.0", + + "ssh://gist.github.com:foo/feed": "", + "ssh://gist.github.com:foo/feed#v1.0": "v1.0", + "ssh://user@gist.github.com:foo/feed": "", + "ssh://user@gist.github.com:foo/feed#v1.0": "v1.0", + "ssh://user:password@gist.github.com:foo/feed": "", + "ssh://user:password@gist.github.com:foo/feed#v1.0": "v1.0", + "ssh://:password@gist.github.com:foo/feed": "", + "ssh://:password@gist.github.com:foo/feed#v1.0": "v1.0", + + "ssh://gist.github.com:foo/feed.git": "", + "ssh://gist.github.com:foo/feed.git#v1.0": "v1.0", + "ssh://user@gist.github.com:foo/feed.git": "", + "ssh://user@gist.github.com:foo/feed.git#v1.0": "v1.0", + "ssh://user:password@gist.github.com:foo/feed.git": "", + "ssh://user:password@gist.github.com:foo/feed.git#v1.0": "v1.0", + "ssh://:password@gist.github.com:foo/feed.git": "", + "ssh://:password@gist.github.com:foo/feed.git#v1.0": "v1.0", + + // git+https urls + // + // NOTE auth is accepted and respected + "git+https://gist.github.com/feed": "", + "git+https://gist.github.com/feed#v1.0": "v1.0", + "git+https://user@gist.github.com/feed": "", + "git+https://user@gist.github.com/feed#v1.0": "v1.0", + "git+https://user:password@gist.github.com/feed": "", + "git+https://user:password@gist.github.com/feed#v1.0": "v1.0", + "git+https://:password@gist.github.com/feed": "", + "git+https://:password@gist.github.com/feed#v1.0": "v1.0", + + "git+https://gist.github.com/feed.git": "", + "git+https://gist.github.com/feed.git#v1.0": "v1.0", + "git+https://user@gist.github.com/feed.git": "", + "git+https://user@gist.github.com/feed.git#v1.0": "v1.0", + "git+https://user:password@gist.github.com/feed.git": "", + "git+https://user:password@gist.github.com/feed.git#v1.0": "v1.0", + "git+https://:password@gist.github.com/feed.git": "", + "git+https://:password@gist.github.com/feed.git#v1.0": "v1.0", + + "git+https://gist.github.com/foo/feed": "", + "git+https://gist.github.com/foo/feed#v1.0": "v1.0", + "git+https://user@gist.github.com/foo/feed": "", + "git+https://user@gist.github.com/foo/feed#v1.0": "v1.0", + "git+https://user:password@gist.github.com/foo/feed": "", + "git+https://user:password@gist.github.com/foo/feed#v1.0": "v1.0", + "git+https://:password@gist.github.com/foo/feed": "", + "git+https://:password@gist.github.com/foo/feed#v1.0": "v1.0", + + "git+https://gist.github.com/foo/feed.git": "", + "git+https://gist.github.com/foo/feed.git#v1.0": "v1.0", + "git+https://user@gist.github.com/foo/feed.git": "", + "git+https://user@gist.github.com/foo/feed.git#v1.0": "v1.0", + "git+https://user:password@gist.github.com/foo/feed.git": "", + "git+https://user:password@gist.github.com/foo/feed.git#v1.0": "v1.0", + "git+https://:password@gist.github.com/foo/feed.git": "", + "git+https://:password@gist.github.com/foo/feed.git#v1.0": "v1.0", + + // https urls + // + // NOTE auth is accepted and respected + "https://gist.github.com/feed": "", + "https://gist.github.com/feed#v1.0": "v1.0", + "https://user@gist.github.com/feed": "", + "https://user@gist.github.com/feed#v1.0": "v1.0", + "https://user:password@gist.github.com/feed": "", + "https://user:password@gist.github.com/feed#v1.0": "v1.0", + "https://:password@gist.github.com/feed": "", + "https://:password@gist.github.com/feed#v1.0": "v1.0", + + "https://gist.github.com/feed.git": "", + "https://gist.github.com/feed.git#v1.0": "v1.0", + "https://user@gist.github.com/feed.git": "", + "https://user@gist.github.com/feed.git#v1.0": "v1.0", + "https://user:password@gist.github.com/feed.git": "", + "https://user:password@gist.github.com/feed.git#v1.0": "v1.0", + "https://:password@gist.github.com/feed.git": "", + "https://:password@gist.github.com/feed.git#v1.0": "v1.0", + + "https://gist.github.com/foo/feed": "", + "https://gist.github.com/foo/feed#v1.0": "v1.0", + "https://user@gist.github.com/foo/feed": "", + "https://user@gist.github.com/foo/feed#v1.0": "v1.0", + "https://user:password@gist.github.com/foo/feed": "", + "https://user:password@gist.github.com/foo/feed#v1.0": "v1.0", + "https://:password@gist.github.com/foo/feed": "", + "https://:password@gist.github.com/foo/feed#v1.0": "v1.0", + + "https://gist.github.com/foo/feed.git": "", + "https://gist.github.com/foo/feed.git#v1.0": "v1.0", + "https://user@gist.github.com/foo/feed.git": "", + "https://user@gist.github.com/foo/feed.git#v1.0": "v1.0", + "https://user:password@gist.github.com/foo/feed.git": "", + "https://user:password@gist.github.com/foo/feed.git#v1.0": "v1.0", + "https://:password@gist.github.com/foo/feed.git": "", + "https://:password@gist.github.com/foo/feed.git#v1.0": "v1.0" + }; + + const otherDomainValid = { + "https://other.com/foo/bar.git#v1.0": "v1.0", + "ssh://other.com:foo/bar.git#v1.0": "v1.0", + "user@other.com:foo/bar#v1.0": "v1.0" + }; + + const otherDomainInvalid = ["other:foo/bar#v1.0"]; + + it("should return empty string for some invalid URL deps", () => { + for (const url of commonInvalid) { + expect(normalizeVersion(url)).toBe(""); + } + }); + + it("should get correct version for some valid URL deps", () => { + for (const url of Object.keys(commonValid)) { + expect(normalizeVersion(url)).toBe(commonValid[url]); + } + }); + + it("should return empty string for github invalid URL deps", () => { + for (const url of githubInvalid) { + expect(normalizeVersion(url)).toBe(""); + } + }); + + it("should get correct version for github URL deps", () => { + for (const url of Object.keys(githubValid)) { + expect(normalizeVersion(url)).toBe(githubValid[url]); + } + }); + + it("should return empty string for gitlab invalid URL deps", () => { + for (const url of gitlabInvalid) { + expect(normalizeVersion(url)).toBe(""); + } + }); + + it("should get correct version for gitlab URL deps", () => { + for (const url of Object.keys(gitlabValid)) { + expect(normalizeVersion(url)).toBe(gitlabValid[url]); + } + }); + + it("should return empty string for bitbucket invalid URL deps", () => { + for (const url of bitbucketInvalid) { + expect(normalizeVersion(url)).toBe(""); + } + }); + + it("should get correct version for bitbucket URL deps", () => { + for (const url of Object.keys(bitbucketValid)) { + expect(normalizeVersion(url)).toBe(bitbucketValid[url]); + } + }); + + it("should return empty string for gist invalid URL deps", () => { + for (const url of gistInvalid) { + expect(normalizeVersion(url)).toBe(""); + } + }); + + it("should get correct version for gist URL deps", () => { + for (const url of Object.keys(gistValid)) { + expect(normalizeVersion(url)).toBe(gistValid[url]); + } + }); + + it("should return empty string for other domain invalid URL deps", () => { + for (const url of otherDomainInvalid) { + expect(normalizeVersion(url)).toBe(""); + } + }); + + it("should return correct version for other domain URL deps", () => { + for (const url of Object.keys(otherDomainValid)) { + expect(normalizeVersion(url)).toBe(otherDomainValid[url]); + } + }); +}); diff --git a/test/SizeFormatHelpers.unittest.js b/test/SizeFormatHelpers.unittest.js index e42459a7372..bd17e8419e8 100644 --- a/test/SizeFormatHelpers.unittest.js +++ b/test/SizeFormatHelpers.unittest.js @@ -37,8 +37,8 @@ describe("SizeFormatHelpers", () => { }); it("should handle undefined/NaN", () => { - expect(formatSize(undefined)).toBe("unknown size"); - expect(formatSize(NaN)).toBe("unknown size"); + expect(formatSize()).toBe("unknown size"); + expect(formatSize(Number.NaN)).toBe("unknown size"); }); }); }); diff --git a/test/Stats.test.js b/test/Stats.test.js index 15dc0c220e1..a1965e4123c 100644 --- a/test/Stats.test.js +++ b/test/Stats.test.js @@ -1,10 +1,12 @@ "use strict"; -const webpack = require(".."); +require("./helpers/warmup-webpack"); + const { createFsFromVolume, Volume } = require("memfs"); -const compile = options => { - return new Promise((resolve, reject) => { +const compile = options => + new Promise((resolve, reject) => { + const webpack = require(".."); const compiler = webpack(options); compiler.outputFileSystem = createFsFromVolume(new Volume()); compiler.run((err, stats) => { @@ -15,7 +17,6 @@ const compile = options => { } }); }); -}; describe("Stats", () => { it("should print env string in stats", async () => { @@ -60,6 +61,22 @@ describe("Stats", () => { }) ).toEqual({}); }); + it("should the results of hasWarnings() be affected by ignoreWarnings", async () => { + const stats = await compile({ + mode: "development", + context: __dirname, + entry: "./fixtures/ignoreWarnings/index", + module: { + rules: [ + { + loader: "./fixtures/ignoreWarnings/loader" + } + ] + }, + ignoreWarnings: [/__mocked__warning__/] + }); + expect(stats.hasWarnings()).toBeFalsy(); + }); describe("chunkGroups", () => { it("should be empty when there is no additional chunks", async () => { const stats = await compile({ @@ -173,10 +190,10 @@ describe("Stats", () => { "assets": Array [ Object { "name": "entryB.js", - "size": 2938, + "size": 3060, }, ], - "assetsSize": 2938, + "assetsSize": 3060, "auxiliaryAssets": undefined, "auxiliaryAssetsSize": 0, "childAssets": undefined, @@ -221,10 +238,10 @@ describe("Stats", () => { "info": Object { "javascriptModule": false, "minimized": true, - "size": 2938, + "size": 3060, }, "name": "entryB.js", - "size": 2938, + "size": 3060, "type": "asset", }, Object { diff --git a/test/StatsTestCases.test.js b/test/StatsTestCases.basictest.js similarity index 76% rename from test/StatsTestCases.test.js rename to test/StatsTestCases.basictest.js index 416c3d67182..2e9d04cfacc 100644 --- a/test/StatsTestCases.test.js +++ b/test/StatsTestCases.basictest.js @@ -1,20 +1,18 @@ "use strict"; +require("./helpers/warmup-webpack"); const path = require("path"); const fs = require("graceful-fs"); const rimraf = require("rimraf"); const captureStdio = require("./helpers/captureStdio"); - -let webpack; +const webpack = require(".."); /** * Escapes regular expression metacharacters * @param {string} str String to quote * @returns {string} Escaped string */ -const quotemeta = str => { - return str.replace(/[-[\]\\/{}()*+?.^$|]/g, "\\$&"); -}; +const quoteMeta = str => str.replace(/[-[\]\\/{}()*+?.^$|]/g, "\\$&"); const base = path.join(__dirname, "statsCases"); const outputBase = path.join(__dirname, "js", "stats"); @@ -29,6 +27,7 @@ const tests = fs const testDirectory = path.join(base, testName); const filterPath = path.join(testDirectory, "test.filter.js"); if (fs.existsSync(filterPath) && !require(filterPath)()) { + // eslint-disable-next-line jest/no-disabled-tests, jest/valid-describe-callback describe.skip(testName, () => it("filtered")); return false; } @@ -36,17 +35,17 @@ const tests = fs }); describe("StatsTestCases", () => { + jest.setTimeout(30000); let stderr; beforeEach(() => { stderr = captureStdio(process.stderr, true); - webpack = require(".."); }); afterEach(() => { stderr.restore(); }); - tests.forEach(testName => { - it("should print correct stats for " + testName, done => { - jest.setTimeout(30000); + for (const testName of tests) { + // eslint-disable-next-line no-loop-func + it(`should print correct stats for ${testName}`, done => { const outputDirectory = path.join(outputBase, testName); rimraf.sync(outputDirectory); fs.mkdirSync(outputDirectory, { recursive: true }); @@ -67,11 +66,12 @@ describe("StatsTestCases", () => { testConfig, require(path.join(base, testName, "test.config.js")) ); - } catch (e) { + } catch (_err) { // ignored } - (Array.isArray(options) ? options : [options]).forEach(options => { + const resolvedOptions = Array.isArray(options) ? options : [options]; + for (const options of resolvedOptions) { if (!options.context) options.context = path.join(base, testName); if (!options.output) options.output = options.output || {}; if (!options.output.path) options.output.path = outputDirectory; @@ -79,15 +79,28 @@ describe("StatsTestCases", () => { if (!options.optimization) options.optimization = {}; if (options.optimization.minimize === undefined) options.optimization.minimize = false; - }); + if ( + options.cache && + options.cache !== true && + options.cache.type === "filesystem" + ) { + options.cache.cacheDirectory = path.resolve( + outputBase, + ".cache", + testName + ); + } + } const c = webpack(options); const compilers = c.compilers ? c.compilers : [c]; - compilers.forEach(c => { + for (const c of compilers) { const ifs = c.inputFileSystem; c.inputFileSystem = Object.create(ifs); c.inputFileSystem.readFile = function () { + // eslint-disable-next-line prefer-rest-params const args = Array.prototype.slice.call(arguments); const callback = args.pop(); + // eslint-disable-next-line prefer-spread ifs.readFile.apply( ifs, args.concat([ @@ -101,20 +114,20 @@ describe("StatsTestCases", () => { ); }; c.hooks.compilation.tap("StatsTestCasesTest", compilation => { - [ + for (const hook of [ "optimize", "optimizeModules", "optimizeChunks", "afterOptimizeTree", "afterOptimizeAssets", "beforeHash" - ].forEach(hook => { + ]) { compilation.hooks[hook].tap("TestCasesTest", () => compilation.checkConstraints() ); - }); + } }); - }); + } c.run((err, stats) => { if (err) return done(err); for (const compilation of [] @@ -122,7 +135,7 @@ describe("StatsTestCases", () => { .map(s => s.compilation)) { compilation.logging.delete("webpack.Compilation.ModuleProfile"); } - if (/error$/.test(testName)) { + if (testName.endsWith("error")) { expect(stats.hasErrors()).toBe(true); } else if (stats.hasErrors()) { return done( @@ -174,28 +187,35 @@ describe("StatsTestCases", () => { if (!hasColorSetting) { actual = stderr.toString() + actual; actual = actual - .replace(/\u001b\[[0-9;]*m/g, "") + .replace(/\u001B\[[0-9;]*m/g, "") .replace(/[.0-9]+(\s?ms)/g, "X$1"); } else { actual = stderr.toStringRaw() + actual; actual = actual - .replace(/\u001b\[1m\u001b\[([0-9;]*)m/g, "") - .replace(/\u001b\[1m/g, "") - .replace(/\u001b\[39m\u001b\[22m/g, "") - .replace(/\u001b\[([0-9;]*)m/g, "") + .replace(/\u001B\[1m\u001B\[([0-9;]*)m/g, "") + .replace(/\u001B\[1m/g, "") + .replace(/\u001B\[39m\u001B\[22m/g, "") + .replace(/\u001B\[([0-9;]*)m/g, "") .replace(/[.0-9]+(<\/CLR>)?(\s?ms)/g, "X$1$2"); } + // cspell:ignore Xdir const testPath = path.join(base, testName); actual = actual .replace(/\r\n?/g, "\n") .replace(/webpack [^ )]+(\)?) compiled/g, "webpack x.x.x$1 compiled") - .replace(new RegExp(quotemeta(testPath), "g"), "Xdir/" + testName) + .replace(new RegExp(quoteMeta(testPath), "g"), `Xdir/${testName}`) .replace(/(\w)\\(\w)/g, "$1/$2") - .replace(/, additional resolving: X ms/g, ""); + .replace(/, additional resolving: X ms/g, "") + .replace(/Unexpected identifier '.+?'/g, "Unexpected identifier") + .replace(/[.0-9]+(\s?(bytes|KiB))/g, "X$1") + .replace( + /ms\s\([0-9a-f]{6,32}\)|(?![0-9]+-)[0-9a-f-]{6,32}\./g, + match => `${match.replace(/[0-9a-f]/g, "X")}` + ); expect(actual).toMatchSnapshot(); if (testConfig.validate) testConfig.validate(stats, stderr.toString()); done(); }); }); - }); + } }); diff --git a/test/Template.unittest.js b/test/Template.unittest.js index e951fbf95b6..7740884ac15 100644 --- a/test/Template.unittest.js +++ b/test/Template.unittest.js @@ -16,6 +16,7 @@ describe("Template", () => { items.push(item); } }); + // cspell:ignore sdfas sadfome it("should generate sanitized path identifiers", () => { expect(Template.toPath("path/to-sdfas/sadfome$$.js")).toBe( "path-to-sdfas-sadfome$$-js" diff --git a/test/TestCases.template.js b/test/TestCases.template.js index c08fa2b049b..1f9dca4a3aa 100644 --- a/test/TestCases.template.js +++ b/test/TestCases.template.js @@ -1,51 +1,42 @@ "use strict"; +require("./helpers/warmup-webpack"); const path = require("path"); const fs = require("graceful-fs"); const vm = require("vm"); +const { pathToFileURL, URL } = require("url"); const rimraf = require("rimraf"); -const TerserPlugin = require("terser-webpack-plugin"); const checkArrayExpectation = require("./checkArrayExpectation"); const createLazyTestEnv = require("./helpers/createLazyTestEnv"); const deprecationTracking = require("./helpers/deprecationTracking"); const captureStdio = require("./helpers/captureStdio"); - -let webpack; - -const terserForTesting = new TerserPlugin({ - parallel: false -}); - -const DEFAULT_OPTIMIZATIONS = { - removeAvailableModules: true, - removeEmptyChunks: true, - mergeDuplicateChunks: true, - flagIncludedChunks: true, - sideEffects: true, - providedExports: true, - usedExports: true, - mangleExports: true, - emitOnErrors: true, - concatenateModules: false, - moduleIds: "size", - chunkIds: "size", - minimizer: [terserForTesting] -}; - -const NO_EMIT_ON_ERRORS_OPTIMIZATIONS = { - emitOnErrors: true, - minimizer: [terserForTesting] -}; +const asModule = require("./helpers/asModule"); +const filterInfraStructureErrors = require("./helpers/infrastructureLogErrors"); const casesPath = path.join(__dirname, "cases"); let categories = fs.readdirSync(casesPath); -categories = categories.map(cat => { - return { - name: cat, - tests: fs - .readdirSync(path.join(casesPath, cat)) - .filter(folder => folder.indexOf("_") < 0) - }; +categories = categories.map(cat => ({ + name: cat, + tests: fs + .readdirSync(path.join(casesPath, cat)) + .filter(folder => !folder.includes("_")) +})); + +const createLogger = appendTarget => ({ + log: l => appendTarget.push(l), + debug: l => appendTarget.push(l), + trace: l => appendTarget.push(l), + info: l => appendTarget.push(l), + warn: console.warn.bind(console), + error: console.error.bind(console), + logTime: () => {}, + group: () => {}, + groupCollapsed: () => {}, + groupEnd: () => {}, + profile: () => {}, + profileEnd: () => {}, + clear: () => {}, + status: () => {} }); const describeCases = config => { @@ -53,304 +44,475 @@ const describeCases = config => { let stderr; beforeEach(() => { stderr = captureStdio(process.stderr, true); - webpack = require(".."); }); afterEach(() => { stderr.restore(); }); - categories.forEach(category => { + for (const category of categories) { + // eslint-disable-next-line no-loop-func describe(category.name, function () { jest.setTimeout(20000); - category.tests - .filter(test => { - const testDirectory = path.join(casesPath, category.name, test); - const filterPath = path.join(testDirectory, "test.filter.js"); - if (fs.existsSync(filterPath) && !require(filterPath)(config)) { - describe.skip(test, () => { - it("filtered", () => {}); - }); - return false; + for (const testName of category.tests.filter(test => { + const testDirectory = path.join(casesPath, category.name, test); + const filterPath = path.join(testDirectory, "test.filter.js"); + if (fs.existsSync(filterPath) && !require(filterPath)(config)) { + // eslint-disable-next-line jest/no-disabled-tests + describe.skip(test, () => { + it("filtered", () => {}); + }); + return false; + } + return true; + })) { + const infraStructureLog = []; + + // eslint-disable-next-line no-loop-func + describe(testName, () => { + const testDirectory = path.join(casesPath, category.name, testName); + const outputDirectory = path.join( + __dirname, + "js", + config.name, + category.name, + testName + ); + const cacheDirectory = path.join( + __dirname, + "js/.cache", + config.name, + category.name, + testName + ); + let testConfig = {}; + const testConfigPath = path.join(testDirectory, "test.config.js"); + if (fs.existsSync(testConfigPath)) { + testConfig = require(testConfigPath); } - return true; - }) - .forEach(testName => { - describe(testName, () => { - const testDirectory = path.join( - casesPath, - category.name, - testName - ); - const outputDirectory = path.join( - __dirname, - "js", - config.name, - category.name, - testName - ); - const cacheDirectory = path.join( - __dirname, - "js/.cache", - config.name, - category.name, - testName - ); - const options = { - context: casesPath, - entry: "./" + category.name + "/" + testName + "/", - target: "async-node", - devtool: config.devtool, - mode: config.mode || "none", - optimization: config.mode - ? { - ...NO_EMIT_ON_ERRORS_OPTIMIZATIONS, - ...config.optimization - } - : { - ...DEFAULT_OPTIMIZATIONS, - ...config.optimization - }, - performance: { - hints: false - }, - node: { - __dirname: "mock", - __filename: "mock" - }, - cache: config.cache && { - cacheDirectory, - ...config.cache - }, - output: { - pathinfo: true, - path: outputDirectory, - filename: "bundle.js" - }, - resolve: { - modules: ["web_modules", "node_modules"], - mainFields: [ - "webpack", - "browser", - "web", - "browserify", - ["jam", "main"], - "main" - ], - aliasFields: ["browser"], - extensions: [".webpack.js", ".web.js", ".js", ".json"] - }, - resolveLoader: { - modules: [ - "web_loaders", - "web_modules", - "node_loaders", - "node_modules" - ], - mainFields: ["webpackLoader", "webLoader", "loader", "main"], - extensions: [ - ".webpack-loader.js", - ".web-loader.js", - ".loader.js", - ".js" - ] - }, - module: { - rules: [ - { - test: /\.coffee$/, - loader: "coffee-loader" - }, - { - test: /\.pug/, - loader: "pug-loader" - }, - { - test: /\.wat$/i, - loader: "wast-loader", - type: "webassembly/async" - } - ] - }, - plugins: (config.plugins || []).concat(function () { - this.hooks.compilation.tap("TestCasesTest", compilation => { - [ - "optimize", - "optimizeModules", - "optimizeChunks", - "afterOptimizeTree", - "afterOptimizeAssets" - ].forEach(hook => { - compilation.hooks[hook].tap("TestCasesTest", () => - compilation.checkConstraints() - ); - }); - }); - }), - experiments: { - asyncWebAssembly: true, - topLevelAwait: true - } - }; - beforeAll(done => { - rimraf(cacheDirectory, done); - }); - if (config.cache) { - it(`${testName} should pre-compile to fill disk cache (1st)`, done => { + const TerserPlugin = require("terser-webpack-plugin"); + const terserForTesting = new TerserPlugin({ + parallel: false + }); + let options = { + context: casesPath, + entry: `./${category.name}/${testName}/`, + target: config.target || "async-node", + devtool: config.devtool, + mode: config.mode || "none", + optimization: config.mode + ? { + emitOnErrors: true, + minimizer: [terserForTesting], + ...config.optimization + } + : { + removeAvailableModules: true, + removeEmptyChunks: true, + mergeDuplicateChunks: true, + flagIncludedChunks: true, + sideEffects: true, + providedExports: true, + usedExports: true, + mangleExports: true, + emitOnErrors: true, + concatenateModules: false, + moduleIds: "size", + chunkIds: "size", + minimizer: [terserForTesting], + ...config.optimization + }, + performance: { + hints: false + }, + node: { + __dirname: "mock", + __filename: "mock" + }, + cache: config.cache && { + cacheDirectory, + ...config.cache + }, + output: { + pathinfo: "verbose", + path: outputDirectory, + filename: config.module ? "bundle.mjs" : "bundle.js" + }, + resolve: { + modules: ["web_modules", "node_modules"], + mainFields: [ + "webpack", + "browser", + "web", + "browserify", + ["jam", "main"], + "main" + ], + aliasFields: ["browser"], + extensions: [".webpack.js", ".web.js", ".js", ".json"] + }, + resolveLoader: { + modules: [ + "web_loaders", + "web_modules", + "node_loaders", + "node_modules" + ], + mainFields: ["webpackLoader", "webLoader", "loader", "main"], + extensions: [ + ".webpack-loader.js", + ".web-loader.js", + ".loader.js", + ".js" + ] + }, + module: { + rules: [ + { + test: /\.coffee$/, + loader: "coffee-loader" + }, + { + test: /\.pug/, + loader: "pug-loader" + }, + { + test: /\.wat$/i, + loader: "wast-loader", + type: "webassembly/async" + } + ] + }, + plugins: (config.plugins || []).concat(function () { + this.hooks.compilation.tap("TestCasesTest", compilation => { + for (const hook of [ + "optimize", + "optimizeModules", + "optimizeChunks", + "afterOptimizeTree", + "afterOptimizeAssets" + ]) { + compilation.hooks[hook].tap("TestCasesTest", () => + compilation.checkConstraints() + ); + } + }); + }), + experiments: { + asyncWebAssembly: true, + topLevelAwait: true, + backCompat: false, + ...(config.module ? { outputModule: true } : {}) + }, + infrastructureLogging: config.cache && { + debug: true, + console: createLogger(infraStructureLog) + } + }; + const cleanups = []; + afterAll(() => { + options = undefined; + testConfig = undefined; + for (const fn of cleanups) fn(); + }); + beforeAll(done => { + rimraf(cacheDirectory, done); + }); + if (config.cache) { + it( + `${testName} should pre-compile to fill disk cache (1st)`, + done => { const oldPath = options.output.path; options.output.path = path.join( options.output.path, "cache1" ); + infraStructureLog.length = 0; const deprecationTracker = deprecationTracking.start(); + const webpack = require(".."); webpack(options, err => { deprecationTracker(); options.output.path = oldPath; if (err) return done(err); + const infrastructureLogErrors = filterInfraStructureErrors( + infraStructureLog, + { + run: 1, + options + } + ); + if ( + infrastructureLogErrors.length && + checkArrayExpectation( + testDirectory, + { infrastructureLogs: infrastructureLogErrors }, + "infrastructureLog", + "infrastructure-log", + "InfrastructureLog", + done + ) + ) { + return; + } done(); }); - }, 60000); - it(`${testName} should pre-compile to fill disk cache (2nd)`, done => { + }, + testConfig.timeout || 60000 + ); + it( + `${testName} should pre-compile to fill disk cache (2nd)`, + done => { const oldPath = options.output.path; options.output.path = path.join( options.output.path, "cache2" ); + infraStructureLog.length = 0; const deprecationTracker = deprecationTracking.start(); + const webpack = require(".."); webpack(options, err => { deprecationTracker(); options.output.path = oldPath; if (err) return done(err); + const infrastructureLogErrors = filterInfraStructureErrors( + infraStructureLog, + { + run: 2, + options + } + ); + if ( + infrastructureLogErrors.length && + checkArrayExpectation( + testDirectory, + { infrastructureLogs: infrastructureLogErrors }, + "infrastructureLog", + "infrastructure-log", + "InfrastructureLog", + done + ) + ) { + return; + } done(); }); - }, 10000); - } - it( - testName + " should compile", - done => { - const compiler = webpack(options); - const run = () => { - const deprecationTracker = deprecationTracking.start(); - compiler.run((err, stats) => { - const deprecations = deprecationTracker(); + }, + testConfig.cachedTimeout || testConfig.timeout || 10000 + ); + } + it( + `${testName} should compile`, + done => { + infraStructureLog.length = 0; + const webpack = require(".."); + const compiler = webpack(options); + const run = () => { + const deprecationTracker = deprecationTracking.start(); + compiler.run((err, stats) => { + const deprecations = deprecationTracker(); + if (err) return done(err); + const infrastructureLogErrors = filterInfraStructureErrors( + infraStructureLog, + { + run: 3, + options + } + ); + if ( + infrastructureLogErrors.length && + checkArrayExpectation( + testDirectory, + { infrastructureLogs: infrastructureLogErrors }, + "infrastructureLog", + "infrastructure-log", + "InfrastructureLog", + done + ) + ) { + return; + } + compiler.close(err => { if (err) return done(err); - compiler.close(err => { - if (err) return done(err); - const statOptions = { - preset: "verbose", - colors: false, - modules: true - }; - fs.mkdirSync(outputDirectory, { recursive: true }); - fs.writeFileSync( - path.join(outputDirectory, "stats.txt"), - stats.toString(statOptions), - "utf-8" - ); - const jsonStats = stats.toJson({ - errorDetails: true - }); - if ( - checkArrayExpectation( - testDirectory, - jsonStats, - "error", - "Error", - done - ) - ) { - return; - } - if ( - checkArrayExpectation( - testDirectory, - jsonStats, - "warning", - "Warning", - done + const statOptions = { + preset: "verbose", + colors: false, + modules: true, + reasonsSpace: 1000 + }; + fs.mkdirSync(outputDirectory, { recursive: true }); + fs.writeFileSync( + path.join(outputDirectory, "stats.txt"), + stats.toString(statOptions), + "utf-8" + ); + const jsonStats = stats.toJson({ + errorDetails: true, + modules: false, + assets: false, + chunks: false + }); + if ( + checkArrayExpectation( + testDirectory, + jsonStats, + "error", + "Error", + done + ) + ) { + return; + } + if ( + checkArrayExpectation( + testDirectory, + jsonStats, + "warning", + "Warning", + done + ) + ) { + return; + } + const infrastructureLogging = stderr.toString(); + if (infrastructureLogging) { + done( + new Error( + `Errors/Warnings during build:\n${ + infrastructureLogging + }` ) - ) { - return; - } - const infrastructureLogging = stderr.toString(); - if (infrastructureLogging) { - done( - new Error( - "Errors/Warnings during build:\n" + - infrastructureLogging - ) - ); - } + ); + } - expect(deprecations).toEqual(config.deprecations || []); + expect(deprecations).toEqual(config.deprecations || []); - Promise.resolve().then(done); - }); - }); - }; - if (config.cache) { - // pre-compile to fill memory cache - const deprecationTracker = deprecationTracking.start(); - compiler.run(err => { - deprecationTracker(); - if (err) return done(err); - run(); + Promise.resolve().then(done); }); - } else { + }); + }; + if (config.cache) { + // pre-compile to fill memory cache + const deprecationTracker = deprecationTracking.start(); + compiler.run(err => { + deprecationTracker(); + if (err) return done(err); run(); - } - }, - config.cache ? 10000 : 60000 - ); + }); + } else { + run(); + } + }, + testConfig.cachedTimeout || + testConfig.timeout || + (config.cache ? 20000 : 60000) + ); - it( - testName + " should load the compiled tests", - done => { - function _require(module) { - if (module.substr(0, 2) === "./") { - const p = path.join(outputDirectory, module); - const fn = vm.runInThisContext( - "(function(require, module, exports, __dirname, __filename, it, expect) {" + - "global.expect = expect;" + - 'function nsObj(m) { Object.defineProperty(m, Symbol.toStringTag, { value: "Module" }); return m; }' + - fs.readFileSync(p, "utf-8") + - "\n})", - p - ); - const m = { - exports: {}, - webpackTestSuiteModule: true - }; - fn.call( - m.exports, - _require, - m, - m.exports, - outputDirectory, - p, - _it, - expect + it(`${testName} should load the compiled tests`, done => { + const esmContext = vm.createContext({ + it: _it, + expect, + process, + global, + URL, + Buffer, + setTimeout, + setImmediate, + nsObj: function (m) { + Object.defineProperty(m, Symbol.toStringTag, { + value: "Module" + }); + return m; + } + }); + cleanups.push(() => (esmContext.it = undefined)); + function _require(module, esmMode) { + if (module.startsWith("./")) { + const p = path.join(outputDirectory, module); + const content = fs.readFileSync(p, "utf-8"); + if (p.endsWith(".mjs")) { + let esm; + try { + esm = new vm.SourceTextModule(content, { + identifier: p, + context: esmContext, + initializeImportMeta: (meta, module) => { + meta.url = pathToFileURL(p).href; + }, + importModuleDynamically: async (specifier, module) => { + const result = await _require(specifier, "evaluated"); + return await asModule(result, module.context); + } + }); + cleanups.push(() => (esmContext.it = undefined)); + } catch (err) { + console.log(err); + err.message += `\nwhile parsing ${p}`; + throw err; + } + if (esmMode === "unlinked") return esm; + return (async () => { + await esm.link( + async (specifier, module) => + await asModule( + await _require(specifier, "unlinked"), + module.context, + true + ) ); - return m.exports; - } else return require(module); + // node.js 10 needs instantiate + if (esm.instantiate) esm.instantiate(); + await esm.evaluate(); + if (esmMode === "evaluated") return esm; + const ns = esm.namespace; + return ns.default && ns.default instanceof Promise + ? ns.default + : ns; + })(); } - _require.webpackTestSuiteRequire = true; - _require("./bundle.js"); + const fn = vm.runInThisContext( + "(function(require, module, exports, __dirname, __filename, it, expect) {" + + "global.expect = expect;" + + `function nsObj(m) { Object.defineProperty(m, Symbol.toStringTag, { value: "Module" }); return m; }${ + content + }\n})`, + p + ); + const m = { + exports: {}, + webpackTestSuiteModule: true + }; + fn.call( + m.exports, + _require, + m, + m.exports, + outputDirectory, + p, + _it, + expect + ); + return m.exports; + } + return require(module); + } + _require.webpackTestSuiteRequire = true; + Promise.resolve() + .then(() => _require(`./${options.output.filename}`)) + .then(() => { if (getNumberOfTests() === 0) return done(new Error("No tests exported by test case")); done(); - }, - 10000 - ); + }, done); + }, 10000); - const { it: _it, getNumberOfTests } = createLazyTestEnv( - jasmine.getEnv(), - 10000 - ); - }); + const { it: _it, getNumberOfTests } = createLazyTestEnv( + testConfig.timeout || 10000 + ); }); + } }); - }); + } }); }; -exports.describeCases = describeCases; +// eslint-disable-next-line jest/no-export +module.exports.describeCases = describeCases; diff --git a/test/TestCasesAllCombined.test.js b/test/TestCasesAllCombined.longtest.js similarity index 69% rename from test/TestCasesAllCombined.test.js rename to test/TestCasesAllCombined.longtest.js index c6482879ebd..1d193c5f601 100644 --- a/test/TestCasesAllCombined.test.js +++ b/test/TestCasesAllCombined.longtest.js @@ -1,5 +1,4 @@ const { describeCases } = require("./TestCases.template"); -const webpack = require(".."); describe("TestCases", () => { describeCases({ @@ -11,6 +10,11 @@ describe("TestCases", () => { moduleIds: "named", chunkIds: "named" }, - plugins: [new webpack.HotModuleReplacementPlugin()] + plugins: [ + c => { + const webpack = require(".."); + new webpack.HotModuleReplacementPlugin().apply(c); + } + ] }); }); diff --git a/test/TestCasesCachePack.test.js b/test/TestCasesCachePack.longtest.js similarity index 82% rename from test/TestCasesCachePack.test.js rename to test/TestCasesCachePack.longtest.js index 6599b29dced..a25219da6e4 100644 --- a/test/TestCasesCachePack.test.js +++ b/test/TestCasesCachePack.longtest.js @@ -5,7 +5,10 @@ describe("TestCases", () => { describeCases({ name: "cache pack", cache: { - type: "filesystem" + type: "filesystem", + buildDependencies: { + defaultWebpack: [] + } }, snapshot: { managedPaths: [path.resolve(__dirname, "../node_modules")] diff --git a/test/TestCasesDevtoolInlineSourceMap.test.js b/test/TestCasesDevtoolInlineSourceMap.longtest.js similarity index 100% rename from test/TestCasesDevtoolInlineSourceMap.test.js rename to test/TestCasesDevtoolInlineSourceMap.longtest.js diff --git a/test/TestCasesDevtoolSourceMap.test.js b/test/TestCasesDevtoolSourceMap.longtest.js similarity index 100% rename from test/TestCasesDevtoolSourceMap.test.js rename to test/TestCasesDevtoolSourceMap.longtest.js diff --git a/test/TestCasesMinimizedSourceMap.test.js b/test/TestCasesMinimizedSourceMap.longtest.js similarity index 100% rename from test/TestCasesMinimizedSourceMap.test.js rename to test/TestCasesMinimizedSourceMap.longtest.js diff --git a/test/TestCasesModule.test.js b/test/TestCasesModule.test.js new file mode 100644 index 00000000000..2ce910feb75 --- /dev/null +++ b/test/TestCasesModule.test.js @@ -0,0 +1,15 @@ +const { describeCases } = require("./TestCases.template"); +const vm = require("vm"); + +describe("TestCases", () => { + if (!vm.SourceTextModule) { + throw new Error( + "Running this test requires '--experimental-vm-modules'.\nRun with 'node --experimental-vm-modules node_modules/jest-cli/bin/jest'." + ); + } + describeCases({ + name: "module", + target: "node14", + module: true + }); +}); diff --git a/test/TestCasesNormal.test.js b/test/TestCasesNormal.basictest.js similarity index 100% rename from test/TestCasesNormal.test.js rename to test/TestCasesNormal.basictest.js diff --git a/test/TestCasesProdGlobalUsed.test.js b/test/TestCasesProdGlobalUsed.test.js index abbdbc0818e..ee3d0fbb2c8 100644 --- a/test/TestCasesProdGlobalUsed.test.js +++ b/test/TestCasesProdGlobalUsed.test.js @@ -1,6 +1,6 @@ const { describeCases } = require("./TestCases.template"); -describe("TestCases", () => { +describe("TestCasesProdGlobalUsed", () => { describeCases({ name: "production with usedExports global", mode: "production", diff --git a/test/TestCasesProduction.test.js b/test/TestCasesProduction.longtest.js similarity index 100% rename from test/TestCasesProduction.test.js rename to test/TestCasesProduction.longtest.js diff --git a/test/URLAbsoluteSpecifier.unittest.js b/test/URLAbsoluteSpecifier.unittest.js index 1899d705d85..92f479a2ff4 100644 --- a/test/URLAbsoluteSpecifier.unittest.js +++ b/test/URLAbsoluteSpecifier.unittest.js @@ -67,19 +67,19 @@ const samples = [ ]; describe("getScheme", () => { - samples.forEach(({ specifier, expected }, i) => { + for (const [_i, { specifier, expected }] of samples.entries()) { it(`should handle ${specifier}`, () => { expect(getScheme(specifier)).toBe(expected); }); - }); + } }); describe("getProtocol", () => { - samples.forEach(({ specifier, expected }, i) => { + for (const [_i, { specifier, expected }] of samples.entries()) { it(`should handle ${specifier}`, () => { expect(getProtocol(specifier)).toBe( - expected ? expected + ":" : undefined + expected ? `${expected}:` : undefined ); }); - }); + } }); diff --git a/test/Validation.test.js b/test/Validation.test.js index 6dccf0a4a9b..fb61178eecb 100644 --- a/test/Validation.test.js +++ b/test/Validation.test.js @@ -1,11 +1,12 @@ "use strict"; -const webpack = require(".."); +require("./helpers/warmup-webpack"); describe("Validation", () => { const createTestCase = (name, config, fn) => { - it("should fail validation for " + name, () => { + it(`should fail validation for ${name}`, () => { try { + const webpack = require(".."); webpack(config); } catch (err) { if (err.name !== "ValidationError") throw err; @@ -24,7 +25,7 @@ describe("Validation", () => { expect(msg).toMatchInlineSnapshot(` "Invalid configuration object. Webpack has been initialized using a configuration object that does not match the API schema. - configuration should be an object: - object { amd?, bail?, cache?, context?, dependencies?, devServer?, devtool?, entry?, experiments?, externals?, externalsPresets?, externalsType?, ignoreWarnings?, infrastructureLogging?, loader?, mode?, module?, name?, node?, optimization?, output?, parallelism?, performance?, plugins?, profile?, recordsInputPath?, recordsOutputPath?, recordsPath?, resolve?, resolveLoader?, snapshot?, stats?, target?, watch?, watchOptions? } + object { amd?, bail?, cache?, context?, dependencies?, devServer?, devtool?, entry?, experiments?, extends?, externals?, externalsPresets?, externalsType?, ignoreWarnings?, infrastructureLogging?, loader?, mode?, module?, name?, node?, optimization?, output?, parallelism?, performance?, plugins?, profile?, recordsInputPath?, recordsOutputPath?, recordsPath?, resolve?, resolveLoader?, snapshot?, stats?, target?, watch?, watchOptions? } -> Options object as provided by the user." `) ); @@ -33,7 +34,7 @@ describe("Validation", () => { expect(msg).toMatchInlineSnapshot(` "Invalid configuration object. Webpack has been initialized using a configuration object that does not match the API schema. - configuration should be an object: - object { amd?, bail?, cache?, context?, dependencies?, devServer?, devtool?, entry?, experiments?, externals?, externalsPresets?, externalsType?, ignoreWarnings?, infrastructureLogging?, loader?, mode?, module?, name?, node?, optimization?, output?, parallelism?, performance?, plugins?, profile?, recordsInputPath?, recordsOutputPath?, recordsPath?, resolve?, resolveLoader?, snapshot?, stats?, target?, watch?, watchOptions? } + object { amd?, bail?, cache?, context?, dependencies?, devServer?, devtool?, entry?, experiments?, extends?, externals?, externalsPresets?, externalsType?, ignoreWarnings?, infrastructureLogging?, loader?, mode?, module?, name?, node?, optimization?, output?, parallelism?, performance?, plugins?, profile?, recordsInputPath?, recordsOutputPath?, recordsPath?, resolve?, resolveLoader?, snapshot?, stats?, target?, watch?, watchOptions? } -> Options object as provided by the user." `) ); @@ -46,7 +47,7 @@ describe("Validation", () => { msg => expect(msg).toMatchInlineSnapshot(` "Invalid configuration object. Webpack has been initialized using a configuration object that does not match the API schema. - - configuration.entry should be an non-empty string. + - configuration.entry should be a non-empty string. -> The string is resolved to a module which is loaded upon startup." `) ); @@ -61,7 +62,7 @@ describe("Validation", () => { msg => expect(msg).toMatchInlineSnapshot(` "Invalid configuration object. Webpack has been initialized using a configuration object that does not match the API schema. - - configuration.entry['bundle'] should be an non-empty array. + - configuration.entry['bundle'] should be a non-empty array. -> All modules are loaded upon startup. The last one is exported." `) ); @@ -181,7 +182,7 @@ describe("Validation", () => { expect(msg).toMatchInlineSnapshot(` "Invalid configuration object. Webpack has been initialized using a configuration object that does not match the API schema. - configuration.module.rules[0].oneOf[0] has an unknown property 'passer'. These properties are valid: - object { compiler?, dependency?, descriptionData?, enforce?, exclude?, generator?, include?, issuer?, issuerLayer?, layer?, loader?, mimetype?, oneOf?, options?, parser?, realResource?, resolve?, resource?, resourceFragment?, resourceQuery?, rules?, sideEffects?, test?, type?, use? } + object { assert?, compiler?, dependency?, descriptionData?, enforce?, exclude?, generator?, include?, issuer?, issuerLayer?, layer?, loader?, mimetype?, oneOf?, options?, parser?, realResource?, resolve?, resource?, resourceFragment?, resourceQuery?, rules?, scheme?, sideEffects?, test?, type?, use?, with? } -> A rule description with conditions and effects for modules." `) ); @@ -196,7 +197,7 @@ describe("Validation", () => { expect(msg).toMatchInlineSnapshot(` "Invalid configuration object. Webpack has been initialized using a configuration object that does not match the API schema. - configuration has an unknown property 'postcss'. These properties are valid: - object { amd?, bail?, cache?, context?, dependencies?, devServer?, devtool?, entry?, experiments?, externals?, externalsPresets?, externalsType?, ignoreWarnings?, infrastructureLogging?, loader?, mode?, module?, name?, node?, optimization?, output?, parallelism?, performance?, plugins?, profile?, recordsInputPath?, recordsOutputPath?, recordsPath?, resolve?, resolveLoader?, snapshot?, stats?, target?, watch?, watchOptions? } + object { amd?, bail?, cache?, context?, dependencies?, devServer?, devtool?, entry?, experiments?, extends?, externals?, externalsPresets?, externalsType?, ignoreWarnings?, infrastructureLogging?, loader?, mode?, module?, name?, node?, optimization?, output?, parallelism?, performance?, plugins?, profile?, recordsInputPath?, recordsOutputPath?, recordsPath?, resolve?, resolveLoader?, snapshot?, stats?, target?, watch?, watchOptions? } -> Options object as provided by the user. For typos: please correct them. For loader options: webpack >= v2.0.0 no longer allows custom properties in configuration. @@ -308,15 +309,18 @@ describe("Validation", () => { "Invalid plugin provided: bool", { entry: "foo.js", - plugins: [false] + plugins: [true] }, msg => expect(msg).toMatchInlineSnapshot(` "Invalid configuration object. Webpack has been initialized using a configuration object that does not match the API schema. - configuration.plugins[0] should be one of these: - object { apply, โ€ฆ } | function + false | 0 | \\"\\" | null | undefined | object { apply, โ€ฆ } | function -> Plugin of type object or instanceof Function. Details: + * configuration.plugins[0] should be one of these: + false | 0 | \\"\\" | null | undefined + -> These values will be ignored by webpack and created to be used with '&&' or '||' to improve readability of configurations. * configuration.plugins[0] should be an object: object { apply, โ€ฆ } -> Plugin instance. @@ -335,9 +339,12 @@ describe("Validation", () => { expect(msg).toMatchInlineSnapshot(` "Invalid configuration object. Webpack has been initialized using a configuration object that does not match the API schema. - configuration.plugins[0] should be one of these: - object { apply, โ€ฆ } | function + false | 0 | \\"\\" | null | undefined | object { apply, โ€ฆ } | function -> Plugin of type object or instanceof Function. Details: + * configuration.plugins[0] should be one of these: + false | 0 | \\"\\" | null | undefined + -> These values will be ignored by webpack and created to be used with '&&' or '||' to improve readability of configurations. * configuration.plugins[0] should be an object: object { apply, โ€ฆ } -> Plugin instance. @@ -356,9 +363,12 @@ describe("Validation", () => { expect(msg).toMatchInlineSnapshot(` "Invalid configuration object. Webpack has been initialized using a configuration object that does not match the API schema. - configuration.plugins[0] should be one of these: - object { apply, โ€ฆ } | function + false | 0 | \\"\\" | null | undefined | object { apply, โ€ฆ } | function -> Plugin of type object or instanceof Function. Details: + * configuration.plugins[0] should be one of these: + false | 0 | \\"\\" | null | undefined + -> These values will be ignored by webpack and created to be used with '&&' or '||' to improve readability of configurations. * configuration.plugins[0] should be an object: object { apply, โ€ฆ } -> Plugin instance. @@ -377,9 +387,12 @@ describe("Validation", () => { expect(msg).toMatchInlineSnapshot(` "Invalid configuration object. Webpack has been initialized using a configuration object that does not match the API schema. - configuration.plugins[0] should be one of these: - object { apply, โ€ฆ } | function + false | 0 | \\"\\" | null | undefined | object { apply, โ€ฆ } | function -> Plugin of type object or instanceof Function. Details: + * configuration.plugins[0] should be one of these: + false | 0 | \\"\\" | null | undefined + -> These values will be ignored by webpack and created to be used with '&&' or '||' to improve readability of configurations. * configuration.plugins[0] should be an object: object { apply, โ€ฆ } -> Plugin instance. @@ -403,6 +416,7 @@ describe("Validation", () => { `) ); + // cspell:Ignore protuction createTestCase( "invalid mode", { @@ -426,7 +440,7 @@ describe("Validation", () => { expect(msg).toMatchInlineSnapshot(` "Invalid configuration object. Webpack has been initialized using a configuration object that does not match the API schema. - configuration has an unknown property 'debug'. These properties are valid: - object { amd?, bail?, cache?, context?, dependencies?, devServer?, devtool?, entry?, experiments?, externals?, externalsPresets?, externalsType?, ignoreWarnings?, infrastructureLogging?, loader?, mode?, module?, name?, node?, optimization?, output?, parallelism?, performance?, plugins?, profile?, recordsInputPath?, recordsOutputPath?, recordsPath?, resolve?, resolveLoader?, snapshot?, stats?, target?, watch?, watchOptions? } + object { amd?, bail?, cache?, context?, dependencies?, devServer?, devtool?, entry?, experiments?, extends?, externals?, externalsPresets?, externalsType?, ignoreWarnings?, infrastructureLogging?, loader?, mode?, module?, name?, node?, optimization?, output?, parallelism?, performance?, plugins?, profile?, recordsInputPath?, recordsOutputPath?, recordsPath?, resolve?, resolveLoader?, snapshot?, stats?, target?, watch?, watchOptions? } -> Options object as provided by the user. The 'debug' property was removed in webpack 2.0.0. Loaders should be updated to allow passing this option via loader options in module.rules. @@ -461,7 +475,7 @@ describe("Validation", () => { test: ... } }. - object { : false | RegExp | string | function | object { automaticNameDelimiter?, chunks?, enforce?, enforceSizeThreshold?, filename?, idHint?, layer?, maxAsyncRequests?, maxAsyncSize?, maxInitialRequests?, maxInitialSize?, maxSize?, minChunks?, minRemainingSize?, minSize?, name?, priority?, reuseExistingChunk?, test?, type?, usedExports? } } + object { : false | RegExp | string | function | object { automaticNameDelimiter?, chunks?, enforce?, enforceSizeThreshold?, filename?, idHint?, layer?, maxAsyncRequests?, maxAsyncSize?, maxInitialRequests?, maxInitialSize?, maxSize?, minChunks?, minRemainingSize?, minSize?, minSizeReduction?, name?, priority?, reuseExistingChunk?, test?, type?, usedExports? } } -> Assign modules to a cache group (modules from different cache groups are tried to keep in separate chunks, default categories: 'default', 'defaultVendors')." `) ); @@ -469,20 +483,12 @@ describe("Validation", () => { createTestCase( "holey array", // eslint-disable-next-line no-sparse-arrays - [ - { - mode: "production" - }, - , - { - mode: "development" - } - ], + [{ mode: "production" }, , { mode: "development" }], msg => expect(msg).toMatchInlineSnapshot(` "Invalid configuration object. Webpack has been initialized using a configuration object that does not match the API schema. - configuration[1] should be an object: - object { amd?, bail?, cache?, context?, dependencies?, devServer?, devtool?, entry?, experiments?, externals?, externalsPresets?, externalsType?, ignoreWarnings?, infrastructureLogging?, loader?, mode?, module?, name?, node?, optimization?, output?, parallelism?, performance?, plugins?, profile?, recordsInputPath?, recordsOutputPath?, recordsPath?, resolve?, resolveLoader?, snapshot?, stats?, target?, watch?, watchOptions? } + object { amd?, bail?, cache?, context?, dependencies?, devServer?, devtool?, entry?, experiments?, extends?, externals?, externalsPresets?, externalsType?, ignoreWarnings?, infrastructureLogging?, loader?, mode?, module?, name?, node?, optimization?, output?, parallelism?, performance?, plugins?, profile?, recordsInputPath?, recordsOutputPath?, recordsPath?, resolve?, resolveLoader?, snapshot?, stats?, target?, watch?, watchOptions? } -> Options object as provided by the user." `) ); @@ -496,7 +502,7 @@ describe("Validation", () => { expect(msg).toMatchInlineSnapshot(` "Invalid configuration object. Webpack has been initialized using a configuration object that does not match the API schema. - configuration.output has an unknown property 'ecmaVersion'. These properties are valid: - object { assetModuleFilename?, auxiliaryComment?, charset?, chunkFilename?, chunkFormat?, chunkLoadTimeout?, chunkLoading?, chunkLoadingGlobal?, clean?, compareBeforeEmit?, crossOriginLoading?, devtoolFallbackModuleFilenameTemplate?, devtoolModuleFilenameTemplate?, devtoolNamespace?, enabledChunkLoadingTypes?, enabledLibraryTypes?, enabledWasmLoadingTypes?, environment?, filename?, globalObject?, hashDigest?, hashDigestLength?, hashFunction?, hashSalt?, hotUpdateChunkFilename?, hotUpdateGlobal?, hotUpdateMainFilename?, iife?, importFunctionName?, importMetaName?, library?, libraryExport?, libraryTarget?, module?, path?, pathinfo?, publicPath?, scriptType?, sourceMapFilename?, sourcePrefix?, strictModuleErrorHandling?, strictModuleExceptionHandling?, umdNamedDefine?, uniqueName?, wasmLoading?, webassemblyModuleFilename?, workerChunkLoading?, workerWasmLoading? } + object { amdContainer?, assetModuleFilename?, asyncChunks?, auxiliaryComment?, charset?, chunkFilename?, chunkFormat?, chunkLoadTimeout?, chunkLoading?, chunkLoadingGlobal?, clean?, compareBeforeEmit?, crossOriginLoading?, cssChunkFilename?, cssFilename?, cssHeadDataCompression?, devtoolFallbackModuleFilenameTemplate?, devtoolModuleFilenameTemplate?, devtoolNamespace?, enabledChunkLoadingTypes?, enabledLibraryTypes?, enabledWasmLoadingTypes?, environment?, filename?, globalObject?, hashDigest?, hashDigestLength?, hashFunction?, hashSalt?, hotUpdateChunkFilename?, hotUpdateGlobal?, hotUpdateMainFilename?, ignoreBrowserWarnings?, iife?, importFunctionName?, importMetaName?, library?, libraryExport?, libraryTarget?, module?, path?, pathinfo?, publicPath?, scriptType?, sourceMapFilename?, sourcePrefix?, strictModuleErrorHandling?, strictModuleExceptionHandling?, trustedTypes?, umdNamedDefine?, uniqueName?, wasmLoading?, webassemblyModuleFilename?, workerChunkLoading?, workerPublicPath?, workerWasmLoading? } -> Options affecting the output of the compilation. \`output\` options tell webpack how to write the compiled files to disk. Did you mean output.environment (output.ecmaVersion was a temporary configuration option during webpack 5 beta)?" `) @@ -568,7 +574,7 @@ describe("Validation", () => { expect(msg).toMatchInlineSnapshot(` "Invalid configuration object. Webpack has been initialized using a configuration object that does not match the API schema. - configuration has an unknown property 'rules'. These properties are valid: - object { amd?, bail?, cache?, context?, dependencies?, devServer?, devtool?, entry?, experiments?, externals?, externalsPresets?, externalsType?, ignoreWarnings?, infrastructureLogging?, loader?, mode?, module?, name?, node?, optimization?, output?, parallelism?, performance?, plugins?, profile?, recordsInputPath?, recordsOutputPath?, recordsPath?, resolve?, resolveLoader?, snapshot?, stats?, target?, watch?, watchOptions? } + object { amd?, bail?, cache?, context?, dependencies?, devServer?, devtool?, entry?, experiments?, extends?, externals?, externalsPresets?, externalsType?, ignoreWarnings?, infrastructureLogging?, loader?, mode?, module?, name?, node?, optimization?, output?, parallelism?, performance?, plugins?, profile?, recordsInputPath?, recordsOutputPath?, recordsPath?, resolve?, resolveLoader?, snapshot?, stats?, target?, watch?, watchOptions? } -> Options object as provided by the user. Did you mean module.rules?" `) @@ -582,7 +588,7 @@ describe("Validation", () => { expect(msg).toMatchInlineSnapshot(` "Invalid configuration object. Webpack has been initialized using a configuration object that does not match the API schema. - configuration has an unknown property 'splitChunks'. These properties are valid: - object { amd?, bail?, cache?, context?, dependencies?, devServer?, devtool?, entry?, experiments?, externals?, externalsPresets?, externalsType?, ignoreWarnings?, infrastructureLogging?, loader?, mode?, module?, name?, node?, optimization?, output?, parallelism?, performance?, plugins?, profile?, recordsInputPath?, recordsOutputPath?, recordsPath?, resolve?, resolveLoader?, snapshot?, stats?, target?, watch?, watchOptions? } + object { amd?, bail?, cache?, context?, dependencies?, devServer?, devtool?, entry?, experiments?, extends?, externals?, externalsPresets?, externalsType?, ignoreWarnings?, infrastructureLogging?, loader?, mode?, module?, name?, node?, optimization?, output?, parallelism?, performance?, plugins?, profile?, recordsInputPath?, recordsOutputPath?, recordsPath?, resolve?, resolveLoader?, snapshot?, stats?, target?, watch?, watchOptions? } -> Options object as provided by the user. Did you mean optimization.splitChunks?" `) @@ -596,13 +602,13 @@ describe("Validation", () => { expect(msg).toMatchInlineSnapshot(` "Invalid configuration object. Webpack has been initialized using a configuration object that does not match the API schema. - configuration has an unknown property 'noParse'. These properties are valid: - object { amd?, bail?, cache?, context?, dependencies?, devServer?, devtool?, entry?, experiments?, externals?, externalsPresets?, externalsType?, ignoreWarnings?, infrastructureLogging?, loader?, mode?, module?, name?, node?, optimization?, output?, parallelism?, performance?, plugins?, profile?, recordsInputPath?, recordsOutputPath?, recordsPath?, resolve?, resolveLoader?, snapshot?, stats?, target?, watch?, watchOptions? } + object { amd?, bail?, cache?, context?, dependencies?, devServer?, devtool?, entry?, experiments?, extends?, externals?, externalsPresets?, externalsType?, ignoreWarnings?, infrastructureLogging?, loader?, mode?, module?, name?, node?, optimization?, output?, parallelism?, performance?, plugins?, profile?, recordsInputPath?, recordsOutputPath?, recordsPath?, resolve?, resolveLoader?, snapshot?, stats?, target?, watch?, watchOptions? } -> Options object as provided by the user. Did you mean module.noParse?" `) ); createTestCase( - "opimization.moduleIds", + "optimization.moduleIds", { optimization: { hashedModuleIds: true @@ -662,7 +668,7 @@ describe("Validation", () => { expect(msg).toMatchInlineSnapshot(` "Invalid configuration object. Webpack has been initialized using a configuration object that does not match the API schema. - configuration.optimization.splitChunks has an unknown property 'automaticNamePrefix'. These properties are valid: - object { automaticNameDelimiter?, cacheGroups?, chunks?, defaultSizeTypes?, enforceSizeThreshold?, fallbackCacheGroup?, filename?, hidePathInfo?, maxAsyncRequests?, maxAsyncSize?, maxInitialRequests?, maxInitialSize?, maxSize?, minChunks?, minRemainingSize?, minSize?, name?, usedExports? } + object { automaticNameDelimiter?, cacheGroups?, chunks?, defaultSizeTypes?, enforceSizeThreshold?, fallbackCacheGroup?, filename?, hidePathInfo?, maxAsyncRequests?, maxAsyncSize?, maxInitialRequests?, maxInitialSize?, maxSize?, minChunks?, minRemainingSize?, minSize?, minSizeReduction?, name?, usedExports? } -> Options object for splitting chunks into smaller chunks." `) ); diff --git a/test/WasmHashes.unittest.js b/test/WasmHashes.unittest.js new file mode 100644 index 00000000000..e5b5416e1cb --- /dev/null +++ b/test/WasmHashes.unittest.js @@ -0,0 +1,159 @@ +const { randomBytes, createHash } = require("crypto"); + +const wasmHashes = { + xxhash64: () => { + const createHash = require("../lib/util/hash/xxhash64"); + const createReferenceHash = + require("hash-wasm/dist/xxhash64.umd.min.js").createXXHash64; + return { + createHash, + createReferenceHash: async () => (await createReferenceHash()).init(), + regExp: /^[0-9a-f]{16}$/ + }; + }, + "xxhash64-createHash": () => { + const createXxHash = require("../lib/util/hash/xxhash64"); + const createHash = require("../lib/util/createHash"); + return { + createHash: () => createHash("xxhash64"), + createReferenceHash: createXxHash, + regExp: /^[0-9a-f]{16}$/ + }; + }, + md4: () => { + const createMd4Hash = require("../lib/util/hash/md4"); + return { + createHash: createMd4Hash, + createReferenceHash: + Number.parseInt(process.version.slice(1), 10) < 17 + ? async () => createHash("md4") + : createMd4Hash, + regExp: /^[0-9a-f]{32}$/ + }; + }, + "md4-createHash": () => { + const createMd4Hash = require("../lib/util/hash/md4"); + const createHash = require("../lib/util/createHash"); + return { + createHash: () => createHash("md4"), + createReferenceHash: createMd4Hash, + regExp: /^[0-9a-f]{32}$/ + }; + } +}; + +for (const name of Object.keys(wasmHashes)) { + const { createHash, createReferenceHash, regExp } = wasmHashes[name](); + + describe(name, () => { + const sizes = [ + 1, + 2, + 3, + 4, + 5, + 7, + 8, + 9, + 16, + 31, + 32, + 33, + 64 - 10, + 64 - 9, + 64 - 8, + 63, + 64, + 65, + 100, + 1000, + 65536 - 1, + 65536, + 65536 + 1, + 65536 + 31, + 65536 * 5, + 65536 * 7 - 1, + 65536 * 9 + 31 + ]; + + const test = (name, sizes) => { + it(`${name} should generate a hash from binary data`, async () => { + const hash = createHash(); + const hashString = createHash(); + const reference = await createReferenceHash(); + for (const size of sizes) { + const bytes = randomBytes(size); + const string = bytes.toString("base64"); + hash.update(bytes); + hashString.update(string, "base64"); + reference.update(bytes); + } + const result = hash.digest("hex"); + expect(result).toMatch(regExp); + const resultFromString = hashString.digest("hex"); + expect(resultFromString).toMatch(regExp); + const expected = reference.digest("hex"); + expect(result).toBe(expected); + expect(resultFromString).toBe(expected); + }); + }; + + test("empty hash", []); + + for (const size of sizes) { + test(`single update ${size} bytes`, [size]); + } + + for (const size1 of sizes) { + for (const size2 of sizes) { + test(`two updates ${size1} + ${size2} bytes`, [size1, size2]); + } + } + test("many updates 1", sizes); + test("many updates 2", sizes.slice().reverse()); + test("many updates 3", sizes.concat(sizes.slice().reverse())); + test("many updates 4", sizes.slice().reverse().concat(sizes)); + + const unicodeTest = (name, codePoints) => { + it(`${name} should hash unicode chars correctly`, async () => { + const hash = createHash(); + const reference = await createReferenceHash(); + const str = + typeof codePoints === "string" + ? codePoints + : String.fromCodePoint(...codePoints); + hash.update(str); + reference.update(str); + const result = hash.digest("hex"); + expect(result).toMatch(regExp); + const expected = reference.digest("hex"); + expect(result).toBe(expected); + }); + }; + + const unicodeRangeTest = (name, start, end) => { + const codePoints = []; + for (let i = start; i <= end; i++) { + codePoints.push(i); + } + unicodeTest(name, codePoints); + }; + + // cspell:word Thaana + unicodeRangeTest("Latin-1 Supplement", 0xa0, 0xff); + unicodeRangeTest("Latin Extended", 0x100, 0x24f); + unicodeRangeTest("Thaana", 0x780, 0x7bf); + unicodeRangeTest("Devanagari", 0x900, 0x97f); + unicodeRangeTest("Emoticons", 0x1f600, 0x1f64f); + + unicodeTest("with zero char", "abc\0๐Ÿ’ฉ"); + unicodeTest("weird code point after long code point", [1497, 243248]); + + for (let i = 0; i < 1000; i++) { + const chars = Array.from({ length: 20 }, () => + Math.floor(Math.random() * 0x10ffff) + ); + unicodeTest(`fuzzy ${JSON.stringify(chars)}`, chars); + } + }); +} diff --git a/test/Watch.test.js b/test/Watch.test.js new file mode 100644 index 00000000000..cba04e35eab --- /dev/null +++ b/test/Watch.test.js @@ -0,0 +1,61 @@ +"use strict"; + +require("./helpers/warmup-webpack"); + +const path = require("path"); +const webpack = require(".."); +const { createFsFromVolume, Volume } = require("memfs"); + +describe("Watch", () => { + jest.setTimeout(10000); + + it("should only compile a single time", done => { + let counterBeforeCompile = 0; + let counterDone = 0; + let counterHandler = 0; + const compiler = webpack( + { + context: path.resolve(__dirname, "fixtures/watch"), + watch: true, + mode: "development", + snapshot: { + managedPaths: [/^(.+?[\\/]node_modules[\\/])/] + }, + experiments: { + futureDefaults: true + }, + module: { + // unsafeCache: false, + rules: [ + { + test: /\.js$/, + use: "some-loader" + } + ] + }, + plugins: [ + c => { + c.hooks.beforeCompile.tap("test", () => { + counterBeforeCompile++; + }); + c.hooks.done.tap("test", () => { + counterDone++; + }); + } + ] + }, + (err, stats) => { + if (err) return done(err); + if (stats.hasErrors()) return done(new Error(stats.toString())); + counterHandler++; + } + ); + compiler.outputFileSystem = createFsFromVolume(new Volume()); + setTimeout(() => { + expect(counterBeforeCompile).toBe(1); + expect(counterDone).toBe(1); + expect(counterHandler).toBe(1); + compiler.close(done); + }, 5000); + }); +}); diff --git a/test/WatchCacheUnaffectedTestCases.longtest.js b/test/WatchCacheUnaffectedTestCases.longtest.js new file mode 100644 index 00000000000..3a9ab819e4c --- /dev/null +++ b/test/WatchCacheUnaffectedTestCases.longtest.js @@ -0,0 +1,8 @@ +const { describeCases } = require("./WatchTestCases.template"); + +describeCases({ + name: "WatchCacheUnaffectedTestCases", + experiments: { + cacheUnaffected: true + } +}); diff --git a/test/WatchClose.test.js b/test/WatchClose.test.js index 3186ee7a9e8..1b632e13c03 100644 --- a/test/WatchClose.test.js +++ b/test/WatchClose.test.js @@ -1,25 +1,27 @@ "use strict"; -const path = require("path"); +require("./helpers/warmup-webpack"); -const webpack = require("../"); +const path = require("path"); describe("WatchClose", () => { jest.setTimeout(5000); describe("multiple calls watcher", () => { const fixturePath = path.join(__dirname, "fixtures"); + const outputPath = path.join(__dirname, "js/WatchClose"); const filePath = path.join(fixturePath, "a.js"); let compiler; let watcher; beforeEach(() => { + const webpack = require("../"); compiler = webpack({ mode: "development", entry: filePath, output: { - path: fixturePath, + path: outputPath, filename: "bundle.js" } }); @@ -41,7 +43,7 @@ describe("WatchClose", () => { }); } - it("each callback should be called", async done => { + it("each callback should be called", async () => { let num = 0; await Promise.all([ @@ -54,8 +56,6 @@ describe("WatchClose", () => { ]); expect(num).toBe(1111); - - done(); }); }); }); diff --git a/test/WatchDetection.test.js b/test/WatchDetection.test.js index 758737ed536..5ad4c1c6f12 100644 --- a/test/WatchDetection.test.js +++ b/test/WatchDetection.test.js @@ -8,12 +8,16 @@ const webpack = require(".."); describe("WatchDetection", () => { if (process.env.NO_WATCH_TESTS) { + // eslint-disable-next-line jest/no-disabled-tests it.skip("long running tests excluded", () => {}); return; } jest.setTimeout(10000); + createTestCase(100, true); + createTestCase(10, true); + createTestCase(600, true); for (let changeTimeout = 10; changeTimeout < 100; changeTimeout += 10) { createTestCase(changeTimeout); } @@ -21,12 +25,14 @@ describe("WatchDetection", () => { createTestCase(changeTimeout); } - function createTestCase(changeTimeout) { - describe(`time between changes ${changeTimeout}ms`, () => { + function createTestCase(changeTimeout, invalidate) { + describe(`time between changes ${changeTimeout}ms${ + invalidate ? " with invalidate call" : "" + }`, () => { const fixturePath = path.join( __dirname, "fixtures", - "temp-" + changeTimeout + `temp-${changeTimeout}` ); const filePath = path.join(fixturePath, "file.js"); const file2Path = path.join(fixturePath, "file2.js"); @@ -35,7 +41,7 @@ describe("WatchDetection", () => { beforeAll(() => { try { fs.mkdirSync(fixturePath); - } catch (e) { + } catch (_err) { // empty } fs.writeFileSync(filePath, "require('./file2')", "utf-8"); @@ -46,17 +52,17 @@ describe("WatchDetection", () => { setTimeout(() => { try { fs.unlinkSync(filePath); - } catch (e) { + } catch (_err) { // empty } try { fs.unlinkSync(file2Path); - } catch (e) { + } catch (_err) { // empty } try { fs.rmdirSync(fixturePath); - } catch (e) { + } catch (_err) { // empty } done(); @@ -66,7 +72,7 @@ describe("WatchDetection", () => { it("should build the bundle correctly", done => { const compiler = webpack({ mode: "development", - entry: loaderPath + "!" + filePath, + entry: `${loaderPath}!${filePath}`, output: { path: "/directory", filename: "bundle.js" @@ -91,7 +97,7 @@ describe("WatchDetection", () => { memfs .readFileSync("/directory/bundle.js") .toString() - .indexOf("original") >= 0 + .includes("original") ) step2(); }; @@ -105,7 +111,10 @@ describe("WatchDetection", () => { } function step2() { - onChange = null; + onChange = () => { + expect(compiler.modifiedFiles).not.toBe(undefined); + expect(compiler.removedFiles).not.toBe(undefined); + }; fs.writeFile( filePath, @@ -118,8 +127,7 @@ describe("WatchDetection", () => { } function step3() { - onChange = null; - + if (invalidate) watcher.invalidate(); fs.writeFile(file2Path, "wrong", "utf-8", handleError); setTimeout(step4, changeTimeout); @@ -127,11 +135,13 @@ describe("WatchDetection", () => { function step4() { onChange = () => { + expect(compiler.modifiedFiles).not.toBe(undefined); + expect(compiler.removedFiles).not.toBe(undefined); if ( memfs .readFileSync("/directory/bundle.js") .toString() - .indexOf("correct") >= 0 + .includes("correct") ) step5(); }; diff --git a/test/WatchSuspend.test.js b/test/WatchSuspend.test.js index a4cdc67a811..5e0d572e432 100644 --- a/test/WatchSuspend.test.js +++ b/test/WatchSuspend.test.js @@ -1,12 +1,13 @@ "use strict"; +require("./helpers/warmup-webpack"); + const path = require("path"); const fs = require("fs"); -const webpack = require("../"); - describe("WatchSuspend", () => { if (process.env.NO_WATCH_TESTS) { + // eslint-disable-next-line jest/no-disabled-tests it.skip("long running tests excluded", () => {}); return; } @@ -17,10 +18,13 @@ describe("WatchSuspend", () => { const fixturePath = path.join( __dirname, "fixtures", - "temp-watch-" + Date.now() + `temp-watch-${Date.now()}` ); const filePath = path.join(fixturePath, "file.js"); - const outputPath = path.join(fixturePath, "bundle.js"); + const file2Path = path.join(fixturePath, "file2.js"); + const file3Path = path.join(fixturePath, "file3.js"); + const outputPath = path.join(__dirname, "js/WatchSuspend"); + const outputFile = path.join(outputPath, "bundle.js"); let compiler = null; let watching = null; let onChange = null; @@ -28,23 +32,27 @@ describe("WatchSuspend", () => { beforeAll(() => { try { fs.mkdirSync(fixturePath); - } catch (e) { + } catch (_err) { // skip } try { fs.writeFileSync(filePath, "'foo'", "utf-8"); - } catch (e) { + fs.writeFileSync(file2Path, "'file2'", "utf-8"); + fs.writeFileSync(file3Path, "'file3'", "utf-8"); + } catch (_err) { // skip } + const webpack = require("../"); compiler = webpack({ mode: "development", entry: filePath, output: { - path: fixturePath, + path: outputPath, filename: "bundle.js" } }); watching = compiler.watch({ aggregateTimeout: 50 }, () => {}); + compiler.hooks.done.tap("WatchSuspendTest", () => { if (onChange) onChange(); }); @@ -55,19 +63,19 @@ describe("WatchSuspend", () => { compiler = null; try { fs.unlinkSync(filePath); - } catch (e) { + } catch (_err) { // skip } try { fs.rmdirSync(fixturePath); - } catch (e) { + } catch (_err) { // skip } }); it("should compile successfully", done => { onChange = () => { - expect(fs.readFileSync(outputPath, "utf-8")).toContain("'foo'"); + expect(fs.readFileSync(outputFile, "utf-8")).toContain("'foo'"); onChange = null; done(); }; @@ -86,11 +94,87 @@ describe("WatchSuspend", () => { it("should resume compilation", done => { onChange = () => { - expect(fs.readFileSync(outputPath, "utf-8")).toContain("'bar'"); + expect(fs.readFileSync(outputFile, "utf-8")).toContain("'bar'"); onChange = null; done(); }; watching.resume(); }); + + for (const changeBefore of [false, true]) + for (const delay of [200, 1500]) { + // eslint-disable-next-line no-loop-func + it(`should not ignore changes during resumed compilation (changeBefore: ${changeBefore}, delay: ${delay}ms)`, async () => { + // aggregateTimeout must be long enough for this test + // So set-up new watcher and wait when initial compilation is done + await new Promise(resolve => { + watching.close(() => { + watching = compiler.watch({ aggregateTimeout: 1000 }, () => { + resolve(); + }); + }); + }); + return new Promise(resolve => { + if (changeBefore) fs.writeFileSync(filePath, "'bar'", "utf-8"); + setTimeout(() => { + watching.suspend(); + fs.writeFileSync(filePath, "'baz'", "utf-8"); + + onChange = "throw"; + setTimeout(() => { + onChange = () => { + expect(fs.readFileSync(outputFile, "utf-8")).toContain( + "'baz'" + ); + expect( + compiler.modifiedFiles && + Array.from(compiler.modifiedFiles).sort() + ).toEqual([filePath]); + expect( + compiler.removedFiles && Array.from(compiler.removedFiles) + ).toEqual([]); + onChange = null; + resolve(); + }; + watching.resume(); + }, delay); + }, 200); + }); + }); + } + + it("should not drop changes when suspended", done => { + const aggregateTimeout = 50; + // Trigger initial compilation with file2.js (assuming correct) + fs.writeFileSync( + filePath, + 'require("./file2.js"); require("./file3.js")', + "utf-8" + ); + + onChange = () => { + // Initial compilation is done, start the test + watching.suspend(); + + // Trigger the first change (works as expected): + fs.writeFileSync(file2Path, "'foo'", "utf-8"); + + // Trigger the second change _after_ aggregation timeout of the first + setTimeout(() => { + fs.writeFileSync(file3Path, "'bar'", "utf-8"); + + // Wait when the file3 edit is settled and re-compile + setTimeout(() => { + watching.resume(); + + onChange = () => { + onChange = null; + expect(fs.readFileSync(outputFile, "utf-8")).toContain("'bar'"); + done(); + }; + }, 200); + }, aggregateTimeout + 50); + }; + }); }); }); diff --git a/test/WatchTestCases.longtest.js b/test/WatchTestCases.longtest.js new file mode 100644 index 00000000000..14de99b424e --- /dev/null +++ b/test/WatchTestCases.longtest.js @@ -0,0 +1,5 @@ +const { describeCases } = require("./WatchTestCases.template"); + +describeCases({ + name: "WatchTestCases" +}); diff --git a/test/WatchTestCases.test.js b/test/WatchTestCases.template.js similarity index 66% rename from test/WatchTestCases.test.js rename to test/WatchTestCases.template.js index cb30887f2bf..6b66b38da5d 100644 --- a/test/WatchTestCases.test.js +++ b/test/WatchTestCases.template.js @@ -1,5 +1,7 @@ "use strict"; +require("./helpers/warmup-webpack"); + const path = require("path"); const fs = require("graceful-fs"); const vm = require("vm"); @@ -11,12 +13,10 @@ const prepareOptions = require("./helpers/prepareOptions"); const deprecationTracking = require("./helpers/deprecationTracking"); const FakeDocument = require("./helpers/FakeDocument"); -const webpack = require(".."); - function copyDiff(src, dest, initial) { if (!fs.existsSync(dest)) fs.mkdirSync(dest); const files = fs.readdirSync(src); - files.forEach(filename => { + for (const filename of files) { const srcFile = path.join(src, filename); const destFile = path.join(dest, filename); const directory = fs.statSync(srcFile).isDirectory(); @@ -40,77 +40,81 @@ function copyDiff(src, dest, initial) { } } } - }); + } } -describe("WatchTestCases", () => { - if (process.env.NO_WATCH_TESTS) { - it.skip("long running tests excluded", () => {}); - return; - } +const describeCases = config => { + describe(config.name, () => { + if (process.env.NO_WATCH_TESTS) { + // eslint-disable-next-line jest/no-disabled-tests + it.skip("long running tests excluded", () => {}); + return; + } - const casesPath = path.join(__dirname, "watchCases"); - let categories = fs.readdirSync(casesPath); + const casesPath = path.join(__dirname, "watchCases"); + let categories = fs.readdirSync(casesPath); - categories = categories.map(cat => { - return { + categories = categories.map(cat => ({ name: cat, tests: fs .readdirSync(path.join(casesPath, cat)) - .filter(folder => folder.indexOf("_") < 0) + .filter(folder => !folder.includes("_")) .filter(testName => { const testDirectory = path.join(casesPath, cat, testName); const filterPath = path.join(testDirectory, "test.filter.js"); - if (fs.existsSync(filterPath) && !require(filterPath)()) { - describe.skip(testName, () => it("filtered")); + if (fs.existsSync(filterPath) && !require(filterPath)(config)) { + // eslint-disable-next-line jest/no-disabled-tests, jest/valid-describe-callback + describe.skip(testName, () => it("filtered", () => {})); return false; } return true; }) .sort() - }; - }); - beforeAll(() => { - let dest = path.join(__dirname, "js"); - if (!fs.existsSync(dest)) fs.mkdirSync(dest); - dest = path.join(__dirname, "js", "watch-src"); - if (!fs.existsSync(dest)) fs.mkdirSync(dest); - }); - categories.forEach(category => { + })); beforeAll(() => { - const dest = path.join(__dirname, "js", "watch-src", category.name); + let dest = path.join(__dirname, "js"); + if (!fs.existsSync(dest)) fs.mkdirSync(dest); + dest = path.join(__dirname, "js", `${config.name}-src`); if (!fs.existsSync(dest)) fs.mkdirSync(dest); }); - describe(category.name, () => { - category.tests.forEach(testName => { - describe(testName, () => { - const tempDirectory = path.join( - __dirname, - "js", - "watch-src", - category.name, - testName - ); - const testDirectory = path.join(casesPath, category.name, testName); - const runs = fs - .readdirSync(testDirectory) - .sort() - .filter(name => { - return fs.statSync(path.join(testDirectory, name)).isDirectory(); - }) - .map(name => ({ name })); + for (const category of categories) { + beforeAll(() => { + const dest = path.join( + __dirname, + "js", + `${config.name}-src`, + category.name + ); + if (!fs.existsSync(dest)) fs.mkdirSync(dest); + }); + describe(category.name, () => { + for (const testName of category.tests) { + describe(testName, () => { + const tempDirectory = path.join( + __dirname, + "js", + `${config.name}-src`, + category.name, + testName + ); + const testDirectory = path.join(casesPath, category.name, testName); + const runs = fs + .readdirSync(testDirectory) + .sort() + .filter(name => + fs.statSync(path.join(testDirectory, name)).isDirectory() + ) + .map(name => ({ name })); - beforeAll(done => { - rimraf(tempDirectory, done); - }); + beforeAll(done => { + rimraf(tempDirectory, done); + }); - it( - testName + " should compile", - done => { + it(`${testName} should compile`, done => { const outputDirectory = path.join( __dirname, "js", - "watch", + config.name, category.name, testName ); @@ -125,7 +129,7 @@ describe("WatchTestCases", () => { srcPath: tempDirectory }); } - const applyConfig = options => { + const applyConfig = (options, idx) => { if (!options.mode) options.mode = "development"; if (!options.context) options.context = tempDirectory; if (!options.entry) options.entry = "./index.js"; @@ -136,11 +140,32 @@ describe("WatchTestCases", () => { options.output.pathinfo = true; if (!options.output.filename) options.output.filename = "bundle.js"; + if (options.cache && options.cache.type === "filesystem") { + const cacheDirectory = path.join(tempDirectory, ".cache"); + options.cache.cacheDirectory = cacheDirectory; + options.cache.name = `config-${idx}`; + } + if (config.experiments) { + if (!options.experiments) options.experiments = {}; + for (const key of Object.keys(config.experiments)) { + if (options.experiments[key] === undefined) + options.experiments[key] = config.experiments[key]; + } + } + if (config.optimization) { + if (!options.optimization) options.optimization = {}; + for (const key of Object.keys(config.optimization)) { + if (options.optimization[key] === undefined) + options.optimization[key] = config.optimization[key]; + } + } }; if (Array.isArray(options)) { - options.forEach(applyConfig); + for (const [idx, item] of options.entries()) { + applyConfig(item, idx); + } } else { - applyConfig(options); + applyConfig(options, 0); } const state = {}; @@ -156,6 +181,7 @@ describe("WatchTestCases", () => { setTimeout(() => { const deprecationTracker = deprecationTracking.start(); + const webpack = require(".."); const compiler = webpack(options); compiler.hooks.invalid.tap( "WatchTestCasesTest", @@ -163,35 +189,32 @@ describe("WatchTestCases", () => { triggeringFilename = filename; } ); - const watching = compiler.watch( + compiler.watch( { aggregateTimeout: 1000 }, (err, stats) => { if (err) return compilationFinished(err); - if (!stats) + if (!stats) { return compilationFinished( new Error("No stats reported from Compiler") ); + } if (stats.hash === lastHash) return; lastHash = stats.hash; if (run.done && lastHash !== stats.hash) { return compilationFinished( new Error( - "Compilation changed but no change was issued " + - lastHash + - " != " + - stats.hash + - " (run " + - runIdx + - ")\n" + - "Triggering change: " + - triggeringFilename + `Compilation changed but no change was issued ${ + lastHash + } != ${stats.hash} (run ${runIdx})\n` + + `Triggering change: ${triggeringFilename}` ) ); } if (waitMode) return; run.done = true; + run.stats = stats; if (err) return compilationFinished(err); const statOptions = { preset: "verbose", @@ -264,9 +287,9 @@ describe("WatchTestCases", () => { ) { fn = vm.runInNewContext( "(function(require, module, exports, __dirname, __filename, it, WATCH_STEP, STATS_JSON, STATE, expect, window, self) {" + - 'function nsObj(m) { Object.defineProperty(m, Symbol.toStringTag, { value: "Module" }); return m; }' + - content + - "\n})", + `function nsObj(m) { Object.defineProperty(m, Symbol.toStringTag, { value: "Module" }); return m; }${ + content + }\n})`, globalContext, p ); @@ -274,9 +297,9 @@ describe("WatchTestCases", () => { fn = vm.runInThisContext( "(function(require, module, exports, __dirname, __filename, it, WATCH_STEP, STATS_JSON, STATE, expect) {" + "global.expect = expect;" + - 'function nsObj(m) { Object.defineProperty(m, Symbol.toStringTag, { value: "Module" }); return m; }' + - content + - "\n})", + `function nsObj(m) { Object.defineProperty(m, Symbol.toStringTag, { value: "Module" }); return m; }${ + content + }\n})`, p ); } @@ -304,17 +327,17 @@ describe("WatchTestCases", () => { module in testConfig.modules ) { return testConfig.modules[module]; - } else return jest.requireActual(module); + } + return jest.requireActual(module); } let testConfig = {}; try { // try to load a test file - testConfig = require(path.join( - testDirectory, - "test.config.js" - )); - } catch (e) { + testConfig = require( + path.join(testDirectory, "test.config.js") + ); + } catch (_err) { // empty } @@ -358,10 +381,10 @@ describe("WatchTestCases", () => { done ) ) { - watching.close(); + compiler.close(() => {}); return; } - watching.close(done); + compiler.close(done); } }, 45000 @@ -371,25 +394,33 @@ describe("WatchTestCases", () => { } ); }, 300); - }, - 45000 - ); + }, 45000); - for (const run of runs) { - const { it: _it, getNumberOfTests } = createLazyTestEnv( - jasmine.getEnv(), - 10000, - run.name - ); - run.it = _it; - run.getNumberOfTests = getNumberOfTests; - } + for (const run of runs) { + const { it: _it, getNumberOfTests } = createLazyTestEnv( + 10000, + run.name + ); + run.it = _it; + run.getNumberOfTests = getNumberOfTests; + it(`${run.name} should allow to read stats`, done => { + if (run.stats) { + run.stats.toString({ all: true }); + run.stats = undefined; + } + done(); + }); + } - afterAll(() => { - remove(tempDirectory); + afterAll(() => { + remove(tempDirectory); + }); }); - }); + } }); - }); + } }); -}); +}; + +// eslint-disable-next-line jest/no-export +module.exports.describeCases = describeCases; diff --git a/test/WatcherEvents.test.js b/test/WatcherEvents.test.js index d5068d0dc3e..fee7a7912f5 100644 --- a/test/WatcherEvents.test.js +++ b/test/WatcherEvents.test.js @@ -10,24 +10,23 @@ const createCompiler = config => { return compiler; }; -const createSingleCompiler = () => { - return createCompiler({ +const createSingleCompiler = () => + createCompiler({ context: path.join(__dirname, "fixtures"), entry: "./a.js" }); -}; -const createMultiCompiler = () => { - return createCompiler([ +const createMultiCompiler = () => + createCompiler([ { context: path.join(__dirname, "fixtures"), entry: "./a.js" } ]); -}; describe("WatcherEvents", () => { if (process.env.NO_WATCH_TESTS) { + // eslint-disable-next-line jest/no-disabled-tests it.skip("long running tests excluded", () => {}); return; } diff --git a/test/__snapshots__/Cli.test.js.snap b/test/__snapshots__/Cli.basictest.js.snap similarity index 70% rename from test/__snapshots__/Cli.test.js.snap rename to test/__snapshots__/Cli.basictest.js.snap index c2406f5f72e..619ea75192f 100644 --- a/test/__snapshots__/Cli.test.js.snap +++ b/test/__snapshots__/Cli.basictest.js.snap @@ -56,6 +56,19 @@ Object { "multiple": false, "simpleType": "boolean", }, + "cache-allow-collecting-memory": Object { + "configs": Array [ + Object { + "description": "Allows to collect unused memory allocated during deserialization. This requires copying data into smaller buffers and has a performance cost.", + "multiple": false, + "path": "cache.allowCollectingMemory", + "type": "boolean", + }, + ], + "description": "Allows to collect unused memory allocated during deserialization. This requires copying data into smaller buffers and has a performance cost.", + "multiple": false, + "simpleType": "boolean", + }, "cache-cache-directory": Object { "configs": Array [ Object { @@ -82,6 +95,37 @@ Object { "multiple": false, "simpleType": "string", }, + "cache-cache-unaffected": Object { + "configs": Array [ + Object { + "description": "Additionally cache computation of modules that are unchanged and reference only unchanged modules.", + "multiple": false, + "path": "cache.cacheUnaffected", + "type": "boolean", + }, + ], + "description": "Additionally cache computation of modules that are unchanged and reference only unchanged modules.", + "multiple": false, + "simpleType": "boolean", + }, + "cache-compression": Object { + "configs": Array [ + Object { + "description": "Compression type used for the cache files.", + "multiple": false, + "path": "cache.compression", + "type": "enum", + "values": Array [ + false, + "gzip", + "brotli", + ], + }, + ], + "description": "Compression type used for the cache files.", + "multiple": false, + "simpleType": "string", + }, "cache-hash-algorithm": Object { "configs": Array [ Object { @@ -98,57 +142,82 @@ Object { "cache-idle-timeout": Object { "configs": Array [ Object { - "description": "Time in ms after which idle period the cache storing should happen (only for store: 'pack' or 'idle').", + "description": "Time in ms after which idle period the cache storing should happen.", "multiple": false, "path": "cache.idleTimeout", "type": "number", }, ], - "description": "Time in ms after which idle period the cache storing should happen (only for store: 'pack' or 'idle').", + "description": "Time in ms after which idle period the cache storing should happen.", + "multiple": false, + "simpleType": "number", + }, + "cache-idle-timeout-after-large-changes": Object { + "configs": Array [ + Object { + "description": "Time in ms after which idle period the cache storing should happen when larger changes has been detected (cumulative build time > 2 x avg cache store time).", + "multiple": false, + "path": "cache.idleTimeoutAfterLargeChanges", + "type": "number", + }, + ], + "description": "Time in ms after which idle period the cache storing should happen when larger changes has been detected (cumulative build time > 2 x avg cache store time).", "multiple": false, "simpleType": "number", }, "cache-idle-timeout-for-initial-store": Object { "configs": Array [ Object { - "description": "Time in ms after which idle period the initial cache storing should happen (only for store: 'pack' or 'idle').", + "description": "Time in ms after which idle period the initial cache storing should happen.", "multiple": false, "path": "cache.idleTimeoutForInitialStore", "type": "number", }, ], - "description": "Time in ms after which idle period the initial cache storing should happen (only for store: 'pack' or 'idle').", + "description": "Time in ms after which idle period the initial cache storing should happen.", "multiple": false, "simpleType": "number", }, "cache-immutable-paths": Object { "configs": Array [ Object { - "description": "A path to a immutable directory (usually a package manager cache directory).", + "description": "A RegExp matching an immutable directory (usually a package manager cache directory, including the tailing slash)", + "multiple": true, + "path": "cache.immutablePaths[]", + "type": "RegExp", + }, + Object { + "description": "A path to an immutable directory (usually a package manager cache directory).", "multiple": true, "path": "cache.immutablePaths[]", "type": "path", }, ], - "description": "A path to a immutable directory (usually a package manager cache directory).", + "description": "A RegExp matching an immutable directory (usually a package manager cache directory, including the tailing slash) A path to an immutable directory (usually a package manager cache directory).", "multiple": true, "simpleType": "string", }, "cache-immutable-paths-reset": Object { "configs": Array [ Object { - "description": "Clear all items provided in configuration. List of paths that are managed by a package manager and contain a version or hash in its path so all files are immutable.", + "description": "Clear all items provided in 'cache.immutablePaths' configuration. List of paths that are managed by a package manager and contain a version or hash in its path so all files are immutable.", "multiple": false, "path": "cache.immutablePaths", "type": "reset", }, ], - "description": "Clear all items provided in configuration. List of paths that are managed by a package manager and contain a version or hash in its path so all files are immutable.", + "description": "Clear all items provided in 'cache.immutablePaths' configuration. List of paths that are managed by a package manager and contain a version or hash in its path so all files are immutable.", "multiple": false, "simpleType": "boolean", }, "cache-managed-paths": Object { "configs": Array [ + Object { + "description": "A RegExp matching a managed directory (usually a node_modules directory, including the tailing slash)", + "multiple": true, + "path": "cache.managedPaths[]", + "type": "RegExp", + }, Object { "description": "A path to a managed directory (usually a node_modules directory).", "multiple": true, @@ -156,20 +225,72 @@ Object { "type": "path", }, ], - "description": "A path to a managed directory (usually a node_modules directory).", + "description": "A RegExp matching a managed directory (usually a node_modules directory, including the tailing slash) A path to a managed directory (usually a node_modules directory).", "multiple": true, "simpleType": "string", }, "cache-managed-paths-reset": Object { "configs": Array [ Object { - "description": "Clear all items provided in configuration. List of paths that are managed by a package manager and can be trusted to not be modified otherwise.", + "description": "Clear all items provided in 'cache.managedPaths' configuration. List of paths that are managed by a package manager and can be trusted to not be modified otherwise.", "multiple": false, "path": "cache.managedPaths", "type": "reset", }, ], - "description": "Clear all items provided in configuration. List of paths that are managed by a package manager and can be trusted to not be modified otherwise.", + "description": "Clear all items provided in 'cache.managedPaths' configuration. List of paths that are managed by a package manager and can be trusted to not be modified otherwise.", + "multiple": false, + "simpleType": "boolean", + }, + "cache-max-age": Object { + "configs": Array [ + Object { + "description": "Time for which unused cache entries stay in the filesystem cache at minimum (in milliseconds).", + "multiple": false, + "path": "cache.maxAge", + "type": "number", + }, + ], + "description": "Time for which unused cache entries stay in the filesystem cache at minimum (in milliseconds).", + "multiple": false, + "simpleType": "number", + }, + "cache-max-generations": Object { + "configs": Array [ + Object { + "description": "Number of generations unused cache entries stay in memory cache at minimum (1 = may be removed after unused for a single compilation, ..., Infinity: kept forever).", + "multiple": false, + "path": "cache.maxGenerations", + "type": "number", + }, + ], + "description": "Number of generations unused cache entries stay in memory cache at minimum (1 = may be removed after unused for a single compilation, ..., Infinity: kept forever).", + "multiple": false, + "simpleType": "number", + }, + "cache-max-memory-generations": Object { + "configs": Array [ + Object { + "description": "Number of generations unused cache entries stay in memory cache at minimum (0 = no memory cache used, 1 = may be removed after unused for a single compilation, ..., Infinity: kept forever). Cache entries will be deserialized from disk when removed from memory cache.", + "multiple": false, + "path": "cache.maxMemoryGenerations", + "type": "number", + }, + ], + "description": "Number of generations unused cache entries stay in memory cache at minimum (0 = no memory cache used, 1 = may be removed after unused for a single compilation, ..., Infinity: kept forever). Cache entries will be deserialized from disk when removed from memory cache.", + "multiple": false, + "simpleType": "number", + }, + "cache-memory-cache-unaffected": Object { + "configs": Array [ + Object { + "description": "Additionally cache computation of modules that are unchanged and reference only unchanged modules in memory.", + "multiple": false, + "path": "cache.memoryCacheUnaffected", + "type": "boolean", + }, + ], + "description": "Additionally cache computation of modules that are unchanged and reference only unchanged modules in memory.", "multiple": false, "simpleType": "boolean", }, @@ -186,6 +307,32 @@ Object { "multiple": false, "simpleType": "string", }, + "cache-profile": Object { + "configs": Array [ + Object { + "description": "Track and log detailed timing information for individual cache items.", + "multiple": false, + "path": "cache.profile", + "type": "boolean", + }, + ], + "description": "Track and log detailed timing information for individual cache items.", + "multiple": false, + "simpleType": "boolean", + }, + "cache-readonly": Object { + "configs": Array [ + Object { + "description": "Enable/disable readonly mode.", + "multiple": false, + "path": "cache.readonly", + "type": "boolean", + }, + ], + "description": "Enable/disable readonly mode.", + "multiple": false, + "simpleType": "boolean", + }, "cache-store": Object { "configs": Array [ Object { @@ -269,13 +416,29 @@ Object { "dependencies-reset": Object { "configs": Array [ Object { - "description": "Clear all items provided in configuration. References to other configurations to depend on.", + "description": "Clear all items provided in 'dependencies' configuration. References to other configurations to depend on.", "multiple": false, "path": "dependencies", "type": "reset", }, ], - "description": "Clear all items provided in configuration. References to other configurations to depend on.", + "description": "Clear all items provided in 'dependencies' configuration. References to other configurations to depend on.", + "multiple": false, + "simpleType": "boolean", + }, + "dev-server": Object { + "configs": Array [ + Object { + "description": "Disable dev server.", + "multiple": false, + "path": "devServer", + "type": "enum", + "values": Array [ + false, + ], + }, + ], + "description": "Disable dev server.", "multiple": false, "simpleType": "boolean", }, @@ -318,266 +481,493 @@ Object { "entry-reset": Object { "configs": Array [ Object { - "description": "Clear all items provided in configuration. All modules are loaded upon startup. The last one is exported.", + "description": "Clear all items provided in 'entry' configuration. All modules are loaded upon startup. The last one is exported.", "multiple": false, "path": "entry", "type": "reset", }, ], - "description": "Clear all items provided in configuration. All modules are loaded upon startup. The last one is exported.", + "description": "Clear all items provided in 'entry' configuration. All modules are loaded upon startup. The last one is exported.", "multiple": false, "simpleType": "boolean", }, - "experiments-asset": Object { + "experiments-async-web-assembly": Object { "configs": Array [ Object { - "description": "Allow module type 'asset' to generate assets.", + "description": "Support WebAssembly as asynchronous EcmaScript Module.", "multiple": false, - "path": "experiments.asset", + "path": "experiments.asyncWebAssembly", "type": "boolean", }, ], - "description": "Allow module type 'asset' to generate assets.", + "description": "Support WebAssembly as asynchronous EcmaScript Module.", "multiple": false, "simpleType": "boolean", }, - "experiments-async-web-assembly": Object { + "experiments-back-compat": Object { "configs": Array [ Object { - "description": "Support WebAssembly as asynchronous EcmaScript Module.", + "description": "Enable backward-compat layer with deprecation warnings for many webpack 4 APIs.", "multiple": false, - "path": "experiments.asyncWebAssembly", + "path": "experiments.backCompat", "type": "boolean", }, ], - "description": "Support WebAssembly as asynchronous EcmaScript Module.", + "description": "Enable backward-compat layer with deprecation warnings for many webpack 4 APIs.", "multiple": false, "simpleType": "boolean", }, - "experiments-layers": Object { + "experiments-build-http-allowed-uris": Object { "configs": Array [ Object { - "description": "Enable module and chunk layers.", - "multiple": false, - "path": "experiments.layers", - "type": "boolean", + "description": "Allowed URI pattern.", + "multiple": true, + "path": "experiments.buildHttp.allowedUris[]", + "type": "RegExp", + }, + Object { + "description": "Allowed URI (resp. the beginning of it).", + "multiple": true, + "path": "experiments.buildHttp.allowedUris[]", + "type": "string", }, ], - "description": "Enable module and chunk layers.", - "multiple": false, - "simpleType": "boolean", + "description": "Allowed URI pattern. Allowed URI (resp. the beginning of it).", + "multiple": true, + "simpleType": "string", }, - "experiments-lazy-compilation": Object { + "experiments-build-http-allowed-uris-reset": Object { "configs": Array [ Object { - "description": "Compile entrypoints and import()s only when they are accessed.", + "description": "Clear all items provided in 'experiments.buildHttp.allowedUris' configuration. List of allowed URIs (resp. the beginning of them).", "multiple": false, - "path": "experiments.lazyCompilation", - "type": "boolean", + "path": "experiments.buildHttp.allowedUris", + "type": "reset", }, ], - "description": "Compile entrypoints and import()s only when they are accessed.", + "description": "Clear all items provided in 'experiments.buildHttp.allowedUris' configuration. List of allowed URIs (resp. the beginning of them).", "multiple": false, "simpleType": "boolean", }, - "experiments-lazy-compilation-client": Object { + "experiments-build-http-cache-location": Object { "configs": Array [ Object { - "description": "A custom client.", + "description": "Location where resource content is stored for lockfile entries. It's also possible to disable storing by passing false.", "multiple": false, - "path": "experiments.lazyCompilation.client", - "type": "string", + "path": "experiments.buildHttp.cacheLocation", + "type": "enum", + "values": Array [ + false, + ], + }, + Object { + "description": "Location where resource content is stored for lockfile entries. It's also possible to disable storing by passing false.", + "multiple": false, + "path": "experiments.buildHttp.cacheLocation", + "type": "path", }, ], - "description": "A custom client.", + "description": "Location where resource content is stored for lockfile entries. It's also possible to disable storing by passing false.", "multiple": false, "simpleType": "string", }, - "experiments-lazy-compilation-entries": Object { + "experiments-build-http-frozen": Object { "configs": Array [ Object { - "description": "Enable/disable lazy compilation for entries.", + "description": "When set, anything that would lead to a modification of the lockfile or any resource content, will result in an error.", "multiple": false, - "path": "experiments.lazyCompilation.entries", + "path": "experiments.buildHttp.frozen", "type": "boolean", }, ], - "description": "Enable/disable lazy compilation for entries.", + "description": "When set, anything that would lead to a modification of the lockfile or any resource content, will result in an error.", "multiple": false, "simpleType": "boolean", }, - "experiments-lazy-compilation-imports": Object { + "experiments-build-http-lockfile-location": Object { "configs": Array [ Object { - "description": "Enable/disable lazy compilation for import() modules.", + "description": "Location of the lockfile.", "multiple": false, - "path": "experiments.lazyCompilation.imports", - "type": "boolean", + "path": "experiments.buildHttp.lockfileLocation", + "type": "path", }, ], - "description": "Enable/disable lazy compilation for import() modules.", + "description": "Location of the lockfile.", "multiple": false, - "simpleType": "boolean", + "simpleType": "string", }, - "experiments-lazy-compilation-test": Object { + "experiments-build-http-proxy": Object { "configs": Array [ Object { - "description": "Specify which entrypoints or import()ed modules should be lazily compiled. This is matched with the imported module and not the entrypoint name.", - "multiple": false, - "path": "experiments.lazyCompilation.test", - "type": "RegExp", - }, - Object { - "description": "Specify which entrypoints or import()ed modules should be lazily compiled. This is matched with the imported module and not the entrypoint name.", + "description": "Proxy configuration, which can be used to specify a proxy server to use for HTTP requests.", "multiple": false, - "path": "experiments.lazyCompilation.test", + "path": "experiments.buildHttp.proxy", "type": "string", }, ], - "description": "Specify which entrypoints or import()ed modules should be lazily compiled. This is matched with the imported module and not the entrypoint name.", + "description": "Proxy configuration, which can be used to specify a proxy server to use for HTTP requests.", "multiple": false, "simpleType": "string", }, - "experiments-output-module": Object { + "experiments-build-http-upgrade": Object { "configs": Array [ Object { - "description": "Allow output javascript files as module source type.", + "description": "When set, resources of existing lockfile entries will be fetched and entries will be upgraded when resource content has changed.", "multiple": false, - "path": "experiments.outputModule", + "path": "experiments.buildHttp.upgrade", "type": "boolean", }, ], - "description": "Allow output javascript files as module source type.", + "description": "When set, resources of existing lockfile entries will be fetched and entries will be upgraded when resource content has changed.", "multiple": false, "simpleType": "boolean", }, - "experiments-sync-web-assembly": Object { + "experiments-cache-unaffected": Object { "configs": Array [ Object { - "description": "Support WebAssembly as synchronous EcmaScript Module (outdated).", + "description": "Enable additional in memory caching of modules that are unchanged and reference only unchanged modules.", "multiple": false, - "path": "experiments.syncWebAssembly", + "path": "experiments.cacheUnaffected", "type": "boolean", }, ], - "description": "Support WebAssembly as synchronous EcmaScript Module (outdated).", + "description": "Enable additional in memory caching of modules that are unchanged and reference only unchanged modules.", "multiple": false, "simpleType": "boolean", }, - "experiments-top-level-await": Object { + "experiments-css": Object { "configs": Array [ Object { - "description": "Allow using top-level-await in EcmaScript Modules.", + "description": "Enable css support.", "multiple": false, - "path": "experiments.topLevelAwait", + "path": "experiments.css", "type": "boolean", }, ], - "description": "Allow using top-level-await in EcmaScript Modules.", + "description": "Enable css support.", "multiple": false, "simpleType": "boolean", }, - "externals": Object { + "experiments-future-defaults": Object { "configs": Array [ Object { - "description": "Every matched dependency becomes external.", - "multiple": true, - "path": "externals[]", - "type": "RegExp", - }, - Object { - "description": "An exact matched dependency becomes external. The same string is used as external dependency.", - "multiple": true, - "path": "externals[]", - "type": "string", + "description": "Apply defaults of next major version.", + "multiple": false, + "path": "experiments.futureDefaults", + "type": "boolean", }, ], - "description": "Every matched dependency becomes external. An exact matched dependency becomes external. The same string is used as external dependency.", - "multiple": true, - "simpleType": "string", + "description": "Apply defaults of next major version.", + "multiple": false, + "simpleType": "boolean", }, - "externals-presets-electron": Object { + "experiments-layers": Object { "configs": Array [ Object { - "description": "Treat common electron built-in modules in main and preload context like 'electron', 'ipc' or 'shell' as external and load them via require() when used.", + "description": "Enable module layers.", "multiple": false, - "path": "externalsPresets.electron", + "path": "experiments.layers", "type": "boolean", }, ], - "description": "Treat common electron built-in modules in main and preload context like 'electron', 'ipc' or 'shell' as external and load them via require() when used.", + "description": "Enable module layers.", "multiple": false, "simpleType": "boolean", }, - "externals-presets-electron-main": Object { + "experiments-lazy-compilation": Object { "configs": Array [ Object { - "description": "Treat electron built-in modules in the main context like 'app', 'ipc-main' or 'shell' as external and load them via require() when used.", + "description": "Compile entrypoints and import()s only when they are accessed.", "multiple": false, - "path": "externalsPresets.electronMain", + "path": "experiments.lazyCompilation", "type": "boolean", }, ], - "description": "Treat electron built-in modules in the main context like 'app', 'ipc-main' or 'shell' as external and load them via require() when used.", + "description": "Compile entrypoints and import()s only when they are accessed.", "multiple": false, "simpleType": "boolean", }, - "externals-presets-electron-preload": Object { + "experiments-lazy-compilation-backend-client": Object { "configs": Array [ Object { - "description": "Treat electron built-in modules in the preload context like 'web-frame', 'ipc-renderer' or 'shell' as external and load them via require() when used.", + "description": "A custom client.", "multiple": false, - "path": "externalsPresets.electronPreload", - "type": "boolean", + "path": "experiments.lazyCompilation.backend.client", + "type": "string", }, ], - "description": "Treat electron built-in modules in the preload context like 'web-frame', 'ipc-renderer' or 'shell' as external and load them via require() when used.", + "description": "A custom client.", "multiple": false, - "simpleType": "boolean", + "simpleType": "string", }, - "externals-presets-electron-renderer": Object { + "experiments-lazy-compilation-backend-listen": Object { "configs": Array [ Object { - "description": "Treat electron built-in modules in the renderer context like 'web-frame', 'ipc-renderer' or 'shell' as external and load them via require() when used.", + "description": "A port.", "multiple": false, - "path": "externalsPresets.electronRenderer", - "type": "boolean", + "path": "experiments.lazyCompilation.backend.listen", + "type": "number", }, ], - "description": "Treat electron built-in modules in the renderer context like 'web-frame', 'ipc-renderer' or 'shell' as external and load them via require() when used.", + "description": "A port.", "multiple": false, - "simpleType": "boolean", + "simpleType": "number", }, - "externals-presets-node": Object { + "experiments-lazy-compilation-backend-listen-host": Object { "configs": Array [ Object { - "description": "Treat node.js built-in modules like fs, path or vm as external and load them via require() when used.", + "description": "A host.", "multiple": false, - "path": "externalsPresets.node", - "type": "boolean", + "path": "experiments.lazyCompilation.backend.listen.host", + "type": "string", }, ], - "description": "Treat node.js built-in modules like fs, path or vm as external and load them via require() when used.", + "description": "A host.", "multiple": false, - "simpleType": "boolean", + "simpleType": "string", }, - "externals-presets-nwjs": Object { + "experiments-lazy-compilation-backend-listen-port": Object { "configs": Array [ Object { - "description": "Treat NW.js legacy nw.gui module as external and load it via require() when used.", + "description": "A port.", "multiple": false, - "path": "externalsPresets.nwjs", - "type": "boolean", + "path": "experiments.lazyCompilation.backend.listen.port", + "type": "number", }, ], - "description": "Treat NW.js legacy nw.gui module as external and load it via require() when used.", + "description": "A port.", "multiple": false, - "simpleType": "boolean", + "simpleType": "number", }, - "externals-presets-web": Object { + "experiments-lazy-compilation-backend-protocol": Object { "configs": Array [ Object { - "description": "Treat references to 'http(s)://...' and 'std:...' as external and load them via import when used (Note that this changes execution order as externals are executed before any other code in the chunk).", + "description": "Specifies the protocol the client should use to connect to the server.", + "multiple": false, + "path": "experiments.lazyCompilation.backend.protocol", + "type": "enum", + "values": Array [ + "http", + "https", + ], + }, + ], + "description": "Specifies the protocol the client should use to connect to the server.", + "multiple": false, + "simpleType": "string", + }, + "experiments-lazy-compilation-entries": Object { + "configs": Array [ + Object { + "description": "Enable/disable lazy compilation for entries.", + "multiple": false, + "path": "experiments.lazyCompilation.entries", + "type": "boolean", + }, + ], + "description": "Enable/disable lazy compilation for entries.", + "multiple": false, + "simpleType": "boolean", + }, + "experiments-lazy-compilation-imports": Object { + "configs": Array [ + Object { + "description": "Enable/disable lazy compilation for import() modules.", + "multiple": false, + "path": "experiments.lazyCompilation.imports", + "type": "boolean", + }, + ], + "description": "Enable/disable lazy compilation for import() modules.", + "multiple": false, + "simpleType": "boolean", + }, + "experiments-lazy-compilation-test": Object { + "configs": Array [ + Object { + "description": "Specify which entrypoints or import()ed modules should be lazily compiled. This is matched with the imported module and not the entrypoint name.", + "multiple": false, + "path": "experiments.lazyCompilation.test", + "type": "RegExp", + }, + Object { + "description": "Specify which entrypoints or import()ed modules should be lazily compiled. This is matched with the imported module and not the entrypoint name.", + "multiple": false, + "path": "experiments.lazyCompilation.test", + "type": "string", + }, + ], + "description": "Specify which entrypoints or import()ed modules should be lazily compiled. This is matched with the imported module and not the entrypoint name.", + "multiple": false, + "simpleType": "string", + }, + "experiments-output-module": Object { + "configs": Array [ + Object { + "description": "Allow output javascript files as module source type.", + "multiple": false, + "path": "experiments.outputModule", + "type": "boolean", + }, + ], + "description": "Allow output javascript files as module source type.", + "multiple": false, + "simpleType": "boolean", + }, + "experiments-sync-web-assembly": Object { + "configs": Array [ + Object { + "description": "Support WebAssembly as synchronous EcmaScript Module (outdated).", + "multiple": false, + "path": "experiments.syncWebAssembly", + "type": "boolean", + }, + ], + "description": "Support WebAssembly as synchronous EcmaScript Module (outdated).", + "multiple": false, + "simpleType": "boolean", + }, + "experiments-top-level-await": Object { + "configs": Array [ + Object { + "description": "Allow using top-level-await in EcmaScript Modules.", + "multiple": false, + "path": "experiments.topLevelAwait", + "type": "boolean", + }, + ], + "description": "Allow using top-level-await in EcmaScript Modules.", + "multiple": false, + "simpleType": "boolean", + }, + "extends": Object { + "configs": Array [ + Object { + "description": "Path to the configuration to be extended (only works when using webpack-cli).", + "multiple": true, + "path": "extends[]", + "type": "string", + }, + ], + "description": "Path to the configuration to be extended (only works when using webpack-cli).", + "multiple": true, + "simpleType": "string", + }, + "extends-reset": Object { + "configs": Array [ + Object { + "description": "Clear all items provided in 'extends' configuration. Extend configuration from another configuration (only works when using webpack-cli).", + "multiple": false, + "path": "extends", + "type": "reset", + }, + ], + "description": "Clear all items provided in 'extends' configuration. Extend configuration from another configuration (only works when using webpack-cli).", + "multiple": false, + "simpleType": "boolean", + }, + "externals": Object { + "configs": Array [ + Object { + "description": "Every matched dependency becomes external.", + "multiple": true, + "path": "externals[]", + "type": "RegExp", + }, + Object { + "description": "An exact matched dependency becomes external. The same string is used as external dependency.", + "multiple": true, + "path": "externals[]", + "type": "string", + }, + ], + "description": "Every matched dependency becomes external. An exact matched dependency becomes external. The same string is used as external dependency.", + "multiple": true, + "simpleType": "string", + }, + "externals-presets-electron": Object { + "configs": Array [ + Object { + "description": "Treat common electron built-in modules in main and preload context like 'electron', 'ipc' or 'shell' as external and load them via require() when used.", + "multiple": false, + "path": "externalsPresets.electron", + "type": "boolean", + }, + ], + "description": "Treat common electron built-in modules in main and preload context like 'electron', 'ipc' or 'shell' as external and load them via require() when used.", + "multiple": false, + "simpleType": "boolean", + }, + "externals-presets-electron-main": Object { + "configs": Array [ + Object { + "description": "Treat electron built-in modules in the main context like 'app', 'ipc-main' or 'shell' as external and load them via require() when used.", + "multiple": false, + "path": "externalsPresets.electronMain", + "type": "boolean", + }, + ], + "description": "Treat electron built-in modules in the main context like 'app', 'ipc-main' or 'shell' as external and load them via require() when used.", + "multiple": false, + "simpleType": "boolean", + }, + "externals-presets-electron-preload": Object { + "configs": Array [ + Object { + "description": "Treat electron built-in modules in the preload context like 'web-frame', 'ipc-renderer' or 'shell' as external and load them via require() when used.", + "multiple": false, + "path": "externalsPresets.electronPreload", + "type": "boolean", + }, + ], + "description": "Treat electron built-in modules in the preload context like 'web-frame', 'ipc-renderer' or 'shell' as external and load them via require() when used.", + "multiple": false, + "simpleType": "boolean", + }, + "externals-presets-electron-renderer": Object { + "configs": Array [ + Object { + "description": "Treat electron built-in modules in the renderer context like 'web-frame', 'ipc-renderer' or 'shell' as external and load them via require() when used.", + "multiple": false, + "path": "externalsPresets.electronRenderer", + "type": "boolean", + }, + ], + "description": "Treat electron built-in modules in the renderer context like 'web-frame', 'ipc-renderer' or 'shell' as external and load them via require() when used.", + "multiple": false, + "simpleType": "boolean", + }, + "externals-presets-node": Object { + "configs": Array [ + Object { + "description": "Treat node.js built-in modules like fs, path or vm as external and load them via require() when used.", + "multiple": false, + "path": "externalsPresets.node", + "type": "boolean", + }, + ], + "description": "Treat node.js built-in modules like fs, path or vm as external and load them via require() when used.", + "multiple": false, + "simpleType": "boolean", + }, + "externals-presets-nwjs": Object { + "configs": Array [ + Object { + "description": "Treat NW.js legacy nw.gui module as external and load it via require() when used.", + "multiple": false, + "path": "externalsPresets.nwjs", + "type": "boolean", + }, + ], + "description": "Treat NW.js legacy nw.gui module as external and load it via require() when used.", + "multiple": false, + "simpleType": "boolean", + }, + "externals-presets-web": Object { + "configs": Array [ + Object { + "description": "Treat references to 'http(s)://...' and 'std:...' as external and load them via import when used (Note that this changes execution order as externals are executed before any other code in the chunk).", "multiple": false, "path": "externalsPresets.web", "type": "boolean", @@ -603,13 +993,13 @@ Object { "externals-reset": Object { "configs": Array [ Object { - "description": "Clear all items provided in configuration. Specify dependencies that shouldn't be resolved by webpack, but should become dependencies of the resulting bundle. The kind of the dependency depends on \`output.libraryTarget\`.", + "description": "Clear all items provided in 'externals' configuration. Specify dependencies that shouldn't be resolved by webpack, but should become dependencies of the resulting bundle. The kind of the dependency depends on \`output.libraryTarget\`.", "multiple": false, "path": "externals", "type": "reset", }, ], - "description": "Clear all items provided in configuration. Specify dependencies that shouldn't be resolved by webpack, but should become dependencies of the resulting bundle. The kind of the dependency depends on \`output.libraryTarget\`.", + "description": "Clear all items provided in 'externals' configuration. Specify dependencies that shouldn't be resolved by webpack, but should become dependencies of the resulting bundle. The kind of the dependency depends on \`output.libraryTarget\`.", "multiple": false, "simpleType": "boolean", }, @@ -631,6 +1021,7 @@ Object { "commonjs", "commonjs2", "commonjs-module", + "commonjs-static", "amd", "amd-require", "umd", @@ -639,7 +1030,9 @@ Object { "system", "promise", "import", + "module-import", "script", + "node-commonjs", ], }, ], @@ -702,13 +1095,39 @@ Object { "ignore-warnings-reset": Object { "configs": Array [ Object { - "description": "Clear all items provided in configuration. Ignore specific warnings.", + "description": "Clear all items provided in 'ignoreWarnings' configuration. Ignore specific warnings.", "multiple": false, "path": "ignoreWarnings", "type": "reset", }, ], - "description": "Clear all items provided in configuration. Ignore specific warnings.", + "description": "Clear all items provided in 'ignoreWarnings' configuration. Ignore specific warnings.", + "multiple": false, + "simpleType": "boolean", + }, + "infrastructure-logging-append-only": Object { + "configs": Array [ + Object { + "description": "Only appends lines to the output. Avoids updating existing output e. g. for status messages. This option is only used when no custom console is provided.", + "multiple": false, + "path": "infrastructureLogging.appendOnly", + "type": "boolean", + }, + ], + "description": "Only appends lines to the output. Avoids updating existing output e. g. for status messages. This option is only used when no custom console is provided.", + "multiple": false, + "simpleType": "boolean", + }, + "infrastructure-logging-colors": Object { + "configs": Array [ + Object { + "description": "Enables/Disables colorful output. This option is only used when no custom console is provided.", + "multiple": false, + "path": "infrastructureLogging.colors", + "type": "boolean", + }, + ], + "description": "Enables/Disables colorful output. This option is only used when no custom console is provided.", "multiple": false, "simpleType": "boolean", }, @@ -740,13 +1159,13 @@ Object { "infrastructure-logging-debug-reset": Object { "configs": Array [ Object { - "description": "Clear all items provided in configuration. Enable debug logging for specific loggers.", + "description": "Clear all items provided in 'infrastructureLogging.debug' configuration. Enable debug logging for specific loggers.", "multiple": false, "path": "infrastructureLogging.debug", "type": "reset", }, ], - "description": "Clear all items provided in configuration. Enable debug logging for specific loggers.", + "description": "Clear all items provided in 'infrastructureLogging.debug' configuration. Enable debug logging for specific loggers.", "multiple": false, "simpleType": "boolean", }, @@ -847,6 +1266,19 @@ Object { "multiple": false, "simpleType": "string", }, + "module-generator-asset-binary": Object { + "configs": Array [ + Object { + "description": "Whether or not this asset module should be considered binary. This can be set to 'false' to treat this asset module as text.", + "multiple": false, + "path": "module.generator.asset.binary", + "type": "boolean", + }, + ], + "description": "Whether or not this asset module should be considered binary. This can be set to 'false' to treat this asset module as text.", + "multiple": false, + "simpleType": "boolean", + }, "module-generator-asset-data-url-encoding": Object { "configs": Array [ Object { @@ -903,6 +1335,19 @@ Object { "multiple": false, "simpleType": "string", }, + "module-generator-asset-inline-binary": Object { + "configs": Array [ + Object { + "description": "Whether or not this asset module should be considered binary. This can be set to 'false' to treat this asset module as text.", + "multiple": false, + "path": "module.generator.asset/inline.binary", + "type": "boolean", + }, + ], + "description": "Whether or not this asset module should be considered binary. This can be set to 'false' to treat this asset module as text.", + "multiple": false, + "simpleType": "boolean", + }, "module-generator-asset-inline-data-url-encoding": Object { "configs": Array [ Object { @@ -933,18 +1378,57 @@ Object { "multiple": false, "simpleType": "string", }, - "module-generator-asset-resource-emit": Object { + "module-generator-asset-output-path": Object { "configs": Array [ Object { - "description": "Emit an output asset from this asset module. This can be set to 'false' to omit emitting e. g. for SSR.", + "description": "Emit the asset in the specified folder relative to 'output.path'. This should only be needed when custom 'publicPath' is specified to match the folder structure there.", "multiple": false, - "path": "module.generator.asset/resource.emit", - "type": "boolean", + "path": "module.generator.asset.outputPath", + "type": "string", }, ], - "description": "Emit an output asset from this asset module. This can be set to 'false' to omit emitting e. g. for SSR.", + "description": "Emit the asset in the specified folder relative to 'output.path'. This should only be needed when custom 'publicPath' is specified to match the folder structure there.", "multiple": false, - "simpleType": "boolean", + "simpleType": "string", + }, + "module-generator-asset-public-path": Object { + "configs": Array [ + Object { + "description": "The 'publicPath' specifies the public URL address of the output files when referenced in a browser.", + "multiple": false, + "path": "module.generator.asset.publicPath", + "type": "string", + }, + ], + "description": "The 'publicPath' specifies the public URL address of the output files when referenced in a browser.", + "multiple": false, + "simpleType": "string", + }, + "module-generator-asset-resource-binary": Object { + "configs": Array [ + Object { + "description": "Whether or not this asset module should be considered binary. This can be set to 'false' to treat this asset module as text.", + "multiple": false, + "path": "module.generator.asset/resource.binary", + "type": "boolean", + }, + ], + "description": "Whether or not this asset module should be considered binary. This can be set to 'false' to treat this asset module as text.", + "multiple": false, + "simpleType": "boolean", + }, + "module-generator-asset-resource-emit": Object { + "configs": Array [ + Object { + "description": "Emit an output asset from this asset module. This can be set to 'false' to omit emitting e. g. for SSR.", + "multiple": false, + "path": "module.generator.asset/resource.emit", + "type": "boolean", + }, + ], + "description": "Emit an output asset from this asset module. This can be set to 'false' to omit emitting e. g. for SSR.", + "multiple": false, + "simpleType": "boolean", }, "module-generator-asset-resource-filename": Object { "configs": Array [ @@ -959,6 +1443,235 @@ Object { "multiple": false, "simpleType": "string", }, + "module-generator-asset-resource-output-path": Object { + "configs": Array [ + Object { + "description": "Emit the asset in the specified folder relative to 'output.path'. This should only be needed when custom 'publicPath' is specified to match the folder structure there.", + "multiple": false, + "path": "module.generator.asset/resource.outputPath", + "type": "string", + }, + ], + "description": "Emit the asset in the specified folder relative to 'output.path'. This should only be needed when custom 'publicPath' is specified to match the folder structure there.", + "multiple": false, + "simpleType": "string", + }, + "module-generator-asset-resource-public-path": Object { + "configs": Array [ + Object { + "description": "The 'publicPath' specifies the public URL address of the output files when referenced in a browser.", + "multiple": false, + "path": "module.generator.asset/resource.publicPath", + "type": "string", + }, + ], + "description": "The 'publicPath' specifies the public URL address of the output files when referenced in a browser.", + "multiple": false, + "simpleType": "string", + }, + "module-generator-css-auto-es-module": Object { + "configs": Array [ + Object { + "description": "Configure the generated JS modules that use the ES modules syntax.", + "multiple": false, + "path": "module.generator.css/auto.esModule", + "type": "boolean", + }, + ], + "description": "Configure the generated JS modules that use the ES modules syntax.", + "multiple": false, + "simpleType": "boolean", + }, + "module-generator-css-auto-exports-convention": Object { + "configs": Array [ + Object { + "description": "Specifies the convention of exported names.", + "multiple": false, + "path": "module.generator.css/auto.exportsConvention", + "type": "enum", + "values": Array [ + "as-is", + "camel-case", + "camel-case-only", + "dashes", + "dashes-only", + ], + }, + ], + "description": "Specifies the convention of exported names.", + "multiple": false, + "simpleType": "string", + }, + "module-generator-css-auto-exports-only": Object { + "configs": Array [ + Object { + "description": "Avoid generating and loading a stylesheet and only embed exports from css into output javascript files.", + "multiple": false, + "path": "module.generator.css/auto.exportsOnly", + "type": "boolean", + }, + ], + "description": "Avoid generating and loading a stylesheet and only embed exports from css into output javascript files.", + "multiple": false, + "simpleType": "boolean", + }, + "module-generator-css-auto-local-ident-name": Object { + "configs": Array [ + Object { + "description": "Configure the generated local ident name.", + "multiple": false, + "path": "module.generator.css/auto.localIdentName", + "type": "string", + }, + ], + "description": "Configure the generated local ident name.", + "multiple": false, + "simpleType": "string", + }, + "module-generator-css-es-module": Object { + "configs": Array [ + Object { + "description": "Configure the generated JS modules that use the ES modules syntax.", + "multiple": false, + "path": "module.generator.css.esModule", + "type": "boolean", + }, + ], + "description": "Configure the generated JS modules that use the ES modules syntax.", + "multiple": false, + "simpleType": "boolean", + }, + "module-generator-css-exports-only": Object { + "configs": Array [ + Object { + "description": "Avoid generating and loading a stylesheet and only embed exports from css into output javascript files.", + "multiple": false, + "path": "module.generator.css.exportsOnly", + "type": "boolean", + }, + ], + "description": "Avoid generating and loading a stylesheet and only embed exports from css into output javascript files.", + "multiple": false, + "simpleType": "boolean", + }, + "module-generator-css-global-es-module": Object { + "configs": Array [ + Object { + "description": "Configure the generated JS modules that use the ES modules syntax.", + "multiple": false, + "path": "module.generator.css/global.esModule", + "type": "boolean", + }, + ], + "description": "Configure the generated JS modules that use the ES modules syntax.", + "multiple": false, + "simpleType": "boolean", + }, + "module-generator-css-global-exports-convention": Object { + "configs": Array [ + Object { + "description": "Specifies the convention of exported names.", + "multiple": false, + "path": "module.generator.css/global.exportsConvention", + "type": "enum", + "values": Array [ + "as-is", + "camel-case", + "camel-case-only", + "dashes", + "dashes-only", + ], + }, + ], + "description": "Specifies the convention of exported names.", + "multiple": false, + "simpleType": "string", + }, + "module-generator-css-global-exports-only": Object { + "configs": Array [ + Object { + "description": "Avoid generating and loading a stylesheet and only embed exports from css into output javascript files.", + "multiple": false, + "path": "module.generator.css/global.exportsOnly", + "type": "boolean", + }, + ], + "description": "Avoid generating and loading a stylesheet and only embed exports from css into output javascript files.", + "multiple": false, + "simpleType": "boolean", + }, + "module-generator-css-global-local-ident-name": Object { + "configs": Array [ + Object { + "description": "Configure the generated local ident name.", + "multiple": false, + "path": "module.generator.css/global.localIdentName", + "type": "string", + }, + ], + "description": "Configure the generated local ident name.", + "multiple": false, + "simpleType": "string", + }, + "module-generator-css-module-es-module": Object { + "configs": Array [ + Object { + "description": "Configure the generated JS modules that use the ES modules syntax.", + "multiple": false, + "path": "module.generator.css/module.esModule", + "type": "boolean", + }, + ], + "description": "Configure the generated JS modules that use the ES modules syntax.", + "multiple": false, + "simpleType": "boolean", + }, + "module-generator-css-module-exports-convention": Object { + "configs": Array [ + Object { + "description": "Specifies the convention of exported names.", + "multiple": false, + "path": "module.generator.css/module.exportsConvention", + "type": "enum", + "values": Array [ + "as-is", + "camel-case", + "camel-case-only", + "dashes", + "dashes-only", + ], + }, + ], + "description": "Specifies the convention of exported names.", + "multiple": false, + "simpleType": "string", + }, + "module-generator-css-module-exports-only": Object { + "configs": Array [ + Object { + "description": "Avoid generating and loading a stylesheet and only embed exports from css into output javascript files.", + "multiple": false, + "path": "module.generator.css/module.exportsOnly", + "type": "boolean", + }, + ], + "description": "Avoid generating and loading a stylesheet and only embed exports from css into output javascript files.", + "multiple": false, + "simpleType": "boolean", + }, + "module-generator-css-module-local-ident-name": Object { + "configs": Array [ + Object { + "description": "Configure the generated local ident name.", + "multiple": false, + "path": "module.generator.css/module.localIdentName", + "type": "string", + }, + ], + "description": "Configure the generated local ident name.", + "multiple": false, + "simpleType": "string", + }, "module-no-parse": Object { "configs": Array [ Object { @@ -981,13 +1694,13 @@ Object { "module-no-parse-reset": Object { "configs": Array [ Object { - "description": "Clear all items provided in configuration. Don't parse files matching. It's matched against the full resolved request.", + "description": "Clear all items provided in 'module.noParse' configuration. Don't parse files matching. It's matched against the full resolved request.", "multiple": false, "path": "module.noParse", "type": "reset", }, ], - "description": "Clear all items provided in configuration. Don't parse files matching. It's matched against the full resolved request.", + "description": "Clear all items provided in 'module.noParse' configuration. Don't parse files matching. It's matched against the full resolved request.", "multiple": false, "simpleType": "boolean", }, @@ -1004,6 +1717,58 @@ Object { "multiple": false, "simpleType": "number", }, + "module-parser-css-auto-named-exports": Object { + "configs": Array [ + Object { + "description": "Use ES modules named export for css exports.", + "multiple": false, + "path": "module.parser.css/auto.namedExports", + "type": "boolean", + }, + ], + "description": "Use ES modules named export for css exports.", + "multiple": false, + "simpleType": "boolean", + }, + "module-parser-css-global-named-exports": Object { + "configs": Array [ + Object { + "description": "Use ES modules named export for css exports.", + "multiple": false, + "path": "module.parser.css/global.namedExports", + "type": "boolean", + }, + ], + "description": "Use ES modules named export for css exports.", + "multiple": false, + "simpleType": "boolean", + }, + "module-parser-css-module-named-exports": Object { + "configs": Array [ + Object { + "description": "Use ES modules named export for css exports.", + "multiple": false, + "path": "module.parser.css/module.namedExports", + "type": "boolean", + }, + ], + "description": "Use ES modules named export for css exports.", + "multiple": false, + "simpleType": "boolean", + }, + "module-parser-css-named-exports": Object { + "configs": Array [ + Object { + "description": "Use ES modules named export for css exports.", + "multiple": false, + "path": "module.parser.css.namedExports", + "type": "boolean", + }, + ], + "description": "Use ES modules named export for css exports.", + "multiple": false, + "simpleType": "boolean", + }, "module-parser-javascript-amd": Object { "configs": Array [ Object { @@ -1075,6 +1840,120 @@ Object { "multiple": false, "simpleType": "boolean", }, + "module-parser-javascript-auto-create-require": Object { + "configs": Array [ + Object { + "description": "Enable/disable parsing \\"import { createRequire } from \\"module\\"\\" and evaluating createRequire().", + "multiple": false, + "path": "module.parser.javascript/auto.createRequire", + "type": "boolean", + }, + Object { + "description": "Enable/disable parsing \\"import { createRequire } from \\"module\\"\\" and evaluating createRequire().", + "multiple": false, + "path": "module.parser.javascript/auto.createRequire", + "type": "string", + }, + ], + "description": "Enable/disable parsing \\"import { createRequire } from \\"module\\"\\" and evaluating createRequire().", + "multiple": false, + "simpleType": "string", + }, + "module-parser-javascript-auto-dynamic-import-fetch-priority": Object { + "configs": Array [ + Object { + "description": "Specifies global fetchPriority for dynamic import.", + "multiple": false, + "path": "module.parser.javascript/auto.dynamicImportFetchPriority", + "type": "enum", + "values": Array [ + "low", + "high", + "auto", + false, + ], + }, + ], + "description": "Specifies global fetchPriority for dynamic import.", + "multiple": false, + "simpleType": "string", + }, + "module-parser-javascript-auto-dynamic-import-mode": Object { + "configs": Array [ + Object { + "description": "Specifies global mode for dynamic import.", + "multiple": false, + "path": "module.parser.javascript/auto.dynamicImportMode", + "type": "enum", + "values": Array [ + "eager", + "weak", + "lazy", + "lazy-once", + ], + }, + ], + "description": "Specifies global mode for dynamic import.", + "multiple": false, + "simpleType": "string", + }, + "module-parser-javascript-auto-dynamic-import-prefetch": Object { + "configs": Array [ + Object { + "description": "Specifies global prefetch for dynamic import.", + "multiple": false, + "path": "module.parser.javascript/auto.dynamicImportPrefetch", + "type": "number", + }, + Object { + "description": "Specifies global prefetch for dynamic import.", + "multiple": false, + "path": "module.parser.javascript/auto.dynamicImportPrefetch", + "type": "boolean", + }, + ], + "description": "Specifies global prefetch for dynamic import.", + "multiple": false, + "simpleType": "string", + }, + "module-parser-javascript-auto-dynamic-import-preload": Object { + "configs": Array [ + Object { + "description": "Specifies global preload for dynamic import.", + "multiple": false, + "path": "module.parser.javascript/auto.dynamicImportPreload", + "type": "number", + }, + Object { + "description": "Specifies global preload for dynamic import.", + "multiple": false, + "path": "module.parser.javascript/auto.dynamicImportPreload", + "type": "boolean", + }, + ], + "description": "Specifies global preload for dynamic import.", + "multiple": false, + "simpleType": "string", + }, + "module-parser-javascript-auto-exports-presence": Object { + "configs": Array [ + Object { + "description": "Specifies the behavior of invalid export names in \\"import ... from ...\\" and \\"export ... from ...\\".", + "multiple": false, + "path": "module.parser.javascript/auto.exportsPresence", + "type": "enum", + "values": Array [ + "error", + "warn", + "auto", + false, + ], + }, + ], + "description": "Specifies the behavior of invalid export names in \\"import ... from ...\\" and \\"export ... from ...\\".", + "multiple": false, + "simpleType": "string", + }, "module-parser-javascript-auto-expr-context-critical": Object { "configs": Array [ Object { @@ -1129,33 +2008,78 @@ Object { "type": "string", }, ], - "description": "Set the default request for full dynamic dependencies.", + "description": "Set the default request for full dynamic dependencies.", + "multiple": false, + "simpleType": "string", + }, + "module-parser-javascript-auto-harmony": Object { + "configs": Array [ + Object { + "description": "Enable/disable parsing of EcmaScript Modules syntax.", + "multiple": false, + "path": "module.parser.javascript/auto.harmony", + "type": "boolean", + }, + ], + "description": "Enable/disable parsing of EcmaScript Modules syntax.", + "multiple": false, + "simpleType": "boolean", + }, + "module-parser-javascript-auto-import": Object { + "configs": Array [ + Object { + "description": "Enable/disable parsing of import() syntax.", + "multiple": false, + "path": "module.parser.javascript/auto.import", + "type": "boolean", + }, + ], + "description": "Enable/disable parsing of import() syntax.", + "multiple": false, + "simpleType": "boolean", + }, + "module-parser-javascript-auto-import-exports-presence": Object { + "configs": Array [ + Object { + "description": "Specifies the behavior of invalid export names in \\"import ... from ...\\".", + "multiple": false, + "path": "module.parser.javascript/auto.importExportsPresence", + "type": "enum", + "values": Array [ + "error", + "warn", + "auto", + false, + ], + }, + ], + "description": "Specifies the behavior of invalid export names in \\"import ... from ...\\".", "multiple": false, "simpleType": "string", }, - "module-parser-javascript-auto-harmony": Object { + "module-parser-javascript-auto-import-meta": Object { "configs": Array [ Object { - "description": "Enable/disable parsing of EcmaScript Modules syntax.", + "description": "Enable/disable evaluating import.meta.", "multiple": false, - "path": "module.parser.javascript/auto.harmony", + "path": "module.parser.javascript/auto.importMeta", "type": "boolean", }, ], - "description": "Enable/disable parsing of EcmaScript Modules syntax.", + "description": "Enable/disable evaluating import.meta.", "multiple": false, "simpleType": "boolean", }, - "module-parser-javascript-auto-import": Object { + "module-parser-javascript-auto-import-meta-context": Object { "configs": Array [ Object { - "description": "Enable/disable parsing of import() syntax.", + "description": "Enable/disable evaluating import.meta.webpackContext.", "multiple": false, - "path": "module.parser.javascript/auto.import", + "path": "module.parser.javascript/auto.importMetaContext", "type": "boolean", }, ], - "description": "Enable/disable parsing of import() syntax.", + "description": "Enable/disable evaluating import.meta.webpackContext.", "multiple": false, "simpleType": "boolean", }, @@ -1185,7 +2109,9 @@ Object { "values": Array [ false, true, + "warn-mock", "mock", + "node-module", "eval-only", ], }, @@ -1204,7 +2130,9 @@ Object { "values": Array [ false, true, + "warn-mock", "mock", + "node-module", "eval-only", ], }, @@ -1219,12 +2147,53 @@ Object { "description": "Include a polyfill for the 'global' variable.", "multiple": false, "path": "module.parser.javascript/auto.node.global", - "type": "boolean", + "type": "enum", + "values": Array [ + false, + true, + "warn", + ], }, ], "description": "Include a polyfill for the 'global' variable.", "multiple": false, - "simpleType": "boolean", + "simpleType": "string", + }, + "module-parser-javascript-auto-override-strict": Object { + "configs": Array [ + Object { + "description": "Override the module to strict or non-strict. This may affect the behavior of the module (some behaviors differ between strict and non-strict), so please configure this option carefully.", + "multiple": false, + "path": "module.parser.javascript/auto.overrideStrict", + "type": "enum", + "values": Array [ + "strict", + "non-strict", + ], + }, + ], + "description": "Override the module to strict or non-strict. This may affect the behavior of the module (some behaviors differ between strict and non-strict), so please configure this option carefully.", + "multiple": false, + "simpleType": "string", + }, + "module-parser-javascript-auto-reexport-exports-presence": Object { + "configs": Array [ + Object { + "description": "Specifies the behavior of invalid export names in \\"export ... from ...\\". This might be useful to disable during the migration from \\"export ... from ...\\" to \\"export type ... from ...\\" when reexporting types in TypeScript.", + "multiple": false, + "path": "module.parser.javascript/auto.reexportExportsPresence", + "type": "enum", + "values": Array [ + "error", + "warn", + "auto", + false, + ], + }, + ], + "description": "Specifies the behavior of invalid export names in \\"export ... from ...\\". This might be useful to disable during the migration from \\"export ... from ...\\" to \\"export type ... from ...\\" when reexporting types in TypeScript.", + "multiple": false, + "simpleType": "string", }, "module-parser-javascript-auto-require-context": Object { "configs": Array [ @@ -1281,13 +2250,13 @@ Object { "module-parser-javascript-auto-strict-export-presence": Object { "configs": Array [ Object { - "description": "Emit errors instead of warnings when imported names don't exist in imported module.", + "description": "Deprecated in favor of \\"exportsPresence\\". Emit errors instead of warnings when imported names don't exist in imported module.", "multiple": false, "path": "module.parser.javascript/auto.strictExportPresence", "type": "boolean", }, ], - "description": "Emit errors instead of warnings when imported names don't exist in imported module.", + "description": "Deprecated in favor of \\"exportsPresence\\". Emit errors instead of warnings when imported names don't exist in imported module.", "multiple": false, "simpleType": "boolean", }, @@ -1419,13 +2388,13 @@ Object { "module-parser-javascript-auto-worker-reset": Object { "configs": Array [ Object { - "description": "Clear all items provided in configuration. Disable or configure parsing of WebWorker syntax like new Worker() or navigator.serviceWorker.register().", + "description": "Clear all items provided in 'module.parser.javascript/auto.worker' configuration. Disable or configure parsing of WebWorker syntax like new Worker() or navigator.serviceWorker.register().", "multiple": false, "path": "module.parser.javascript/auto.worker", "type": "reset", }, ], - "description": "Clear all items provided in configuration. Disable or configure parsing of WebWorker syntax like new Worker() or navigator.serviceWorker.register().", + "description": "Clear all items provided in 'module.parser.javascript/auto.worker' configuration. Disable or configure parsing of WebWorker syntax like new Worker() or navigator.serviceWorker.register().", "multiple": false, "simpleType": "boolean", }, @@ -1507,6 +2476,25 @@ Object { "multiple": false, "simpleType": "boolean", }, + "module-parser-javascript-create-require": Object { + "configs": Array [ + Object { + "description": "Enable/disable parsing \\"import { createRequire } from \\"module\\"\\" and evaluating createRequire().", + "multiple": false, + "path": "module.parser.javascript.createRequire", + "type": "boolean", + }, + Object { + "description": "Enable/disable parsing \\"import { createRequire } from \\"module\\"\\" and evaluating createRequire().", + "multiple": false, + "path": "module.parser.javascript.createRequire", + "type": "string", + }, + ], + "description": "Enable/disable parsing \\"import { createRequire } from \\"module\\"\\" and evaluating createRequire().", + "multiple": false, + "simpleType": "string", + }, "module-parser-javascript-dynamic-amd": Object { "configs": Array [ Object { @@ -1562,6 +2550,120 @@ Object { "multiple": false, "simpleType": "boolean", }, + "module-parser-javascript-dynamic-create-require": Object { + "configs": Array [ + Object { + "description": "Enable/disable parsing \\"import { createRequire } from \\"module\\"\\" and evaluating createRequire().", + "multiple": false, + "path": "module.parser.javascript/dynamic.createRequire", + "type": "boolean", + }, + Object { + "description": "Enable/disable parsing \\"import { createRequire } from \\"module\\"\\" and evaluating createRequire().", + "multiple": false, + "path": "module.parser.javascript/dynamic.createRequire", + "type": "string", + }, + ], + "description": "Enable/disable parsing \\"import { createRequire } from \\"module\\"\\" and evaluating createRequire().", + "multiple": false, + "simpleType": "string", + }, + "module-parser-javascript-dynamic-dynamic-import-fetch-priority": Object { + "configs": Array [ + Object { + "description": "Specifies global fetchPriority for dynamic import.", + "multiple": false, + "path": "module.parser.javascript/dynamic.dynamicImportFetchPriority", + "type": "enum", + "values": Array [ + "low", + "high", + "auto", + false, + ], + }, + ], + "description": "Specifies global fetchPriority for dynamic import.", + "multiple": false, + "simpleType": "string", + }, + "module-parser-javascript-dynamic-dynamic-import-mode": Object { + "configs": Array [ + Object { + "description": "Specifies global mode for dynamic import.", + "multiple": false, + "path": "module.parser.javascript/dynamic.dynamicImportMode", + "type": "enum", + "values": Array [ + "eager", + "weak", + "lazy", + "lazy-once", + ], + }, + ], + "description": "Specifies global mode for dynamic import.", + "multiple": false, + "simpleType": "string", + }, + "module-parser-javascript-dynamic-dynamic-import-prefetch": Object { + "configs": Array [ + Object { + "description": "Specifies global prefetch for dynamic import.", + "multiple": false, + "path": "module.parser.javascript/dynamic.dynamicImportPrefetch", + "type": "number", + }, + Object { + "description": "Specifies global prefetch for dynamic import.", + "multiple": false, + "path": "module.parser.javascript/dynamic.dynamicImportPrefetch", + "type": "boolean", + }, + ], + "description": "Specifies global prefetch for dynamic import.", + "multiple": false, + "simpleType": "string", + }, + "module-parser-javascript-dynamic-dynamic-import-preload": Object { + "configs": Array [ + Object { + "description": "Specifies global preload for dynamic import.", + "multiple": false, + "path": "module.parser.javascript/dynamic.dynamicImportPreload", + "type": "number", + }, + Object { + "description": "Specifies global preload for dynamic import.", + "multiple": false, + "path": "module.parser.javascript/dynamic.dynamicImportPreload", + "type": "boolean", + }, + ], + "description": "Specifies global preload for dynamic import.", + "multiple": false, + "simpleType": "string", + }, + "module-parser-javascript-dynamic-exports-presence": Object { + "configs": Array [ + Object { + "description": "Specifies the behavior of invalid export names in \\"import ... from ...\\" and \\"export ... from ...\\".", + "multiple": false, + "path": "module.parser.javascript/dynamic.exportsPresence", + "type": "enum", + "values": Array [ + "error", + "warn", + "auto", + false, + ], + }, + ], + "description": "Specifies the behavior of invalid export names in \\"import ... from ...\\" and \\"export ... from ...\\".", + "multiple": false, + "simpleType": "string", + }, "module-parser-javascript-dynamic-expr-context-critical": Object { "configs": Array [ Object { @@ -1646,6 +2748,127 @@ Object { "multiple": false, "simpleType": "boolean", }, + "module-parser-javascript-dynamic-import-exports-presence": Object { + "configs": Array [ + Object { + "description": "Specifies the behavior of invalid export names in \\"import ... from ...\\".", + "multiple": false, + "path": "module.parser.javascript/dynamic.importExportsPresence", + "type": "enum", + "values": Array [ + "error", + "warn", + "auto", + false, + ], + }, + ], + "description": "Specifies the behavior of invalid export names in \\"import ... from ...\\".", + "multiple": false, + "simpleType": "string", + }, + "module-parser-javascript-dynamic-import-fetch-priority": Object { + "configs": Array [ + Object { + "description": "Specifies global fetchPriority for dynamic import.", + "multiple": false, + "path": "module.parser.javascript.dynamicImportFetchPriority", + "type": "enum", + "values": Array [ + "low", + "high", + "auto", + false, + ], + }, + ], + "description": "Specifies global fetchPriority for dynamic import.", + "multiple": false, + "simpleType": "string", + }, + "module-parser-javascript-dynamic-import-meta": Object { + "configs": Array [ + Object { + "description": "Enable/disable evaluating import.meta.", + "multiple": false, + "path": "module.parser.javascript/dynamic.importMeta", + "type": "boolean", + }, + ], + "description": "Enable/disable evaluating import.meta.", + "multiple": false, + "simpleType": "boolean", + }, + "module-parser-javascript-dynamic-import-meta-context": Object { + "configs": Array [ + Object { + "description": "Enable/disable evaluating import.meta.webpackContext.", + "multiple": false, + "path": "module.parser.javascript/dynamic.importMetaContext", + "type": "boolean", + }, + ], + "description": "Enable/disable evaluating import.meta.webpackContext.", + "multiple": false, + "simpleType": "boolean", + }, + "module-parser-javascript-dynamic-import-mode": Object { + "configs": Array [ + Object { + "description": "Specifies global mode for dynamic import.", + "multiple": false, + "path": "module.parser.javascript.dynamicImportMode", + "type": "enum", + "values": Array [ + "eager", + "weak", + "lazy", + "lazy-once", + ], + }, + ], + "description": "Specifies global mode for dynamic import.", + "multiple": false, + "simpleType": "string", + }, + "module-parser-javascript-dynamic-import-prefetch": Object { + "configs": Array [ + Object { + "description": "Specifies global prefetch for dynamic import.", + "multiple": false, + "path": "module.parser.javascript.dynamicImportPrefetch", + "type": "number", + }, + Object { + "description": "Specifies global prefetch for dynamic import.", + "multiple": false, + "path": "module.parser.javascript.dynamicImportPrefetch", + "type": "boolean", + }, + ], + "description": "Specifies global prefetch for dynamic import.", + "multiple": false, + "simpleType": "string", + }, + "module-parser-javascript-dynamic-import-preload": Object { + "configs": Array [ + Object { + "description": "Specifies global preload for dynamic import.", + "multiple": false, + "path": "module.parser.javascript.dynamicImportPreload", + "type": "number", + }, + Object { + "description": "Specifies global preload for dynamic import.", + "multiple": false, + "path": "module.parser.javascript.dynamicImportPreload", + "type": "boolean", + }, + ], + "description": "Specifies global preload for dynamic import.", + "multiple": false, + "simpleType": "string", + }, "module-parser-javascript-dynamic-node": Object { "configs": Array [ Object { @@ -1672,7 +2895,9 @@ Object { "values": Array [ false, true, + "warn-mock", "mock", + "node-module", "eval-only", ], }, @@ -1691,7 +2916,9 @@ Object { "values": Array [ false, true, + "warn-mock", "mock", + "node-module", "eval-only", ], }, @@ -1706,12 +2933,53 @@ Object { "description": "Include a polyfill for the 'global' variable.", "multiple": false, "path": "module.parser.javascript/dynamic.node.global", - "type": "boolean", + "type": "enum", + "values": Array [ + false, + true, + "warn", + ], }, ], "description": "Include a polyfill for the 'global' variable.", "multiple": false, - "simpleType": "boolean", + "simpleType": "string", + }, + "module-parser-javascript-dynamic-override-strict": Object { + "configs": Array [ + Object { + "description": "Override the module to strict or non-strict. This may affect the behavior of the module (some behaviors differ between strict and non-strict), so please configure this option carefully.", + "multiple": false, + "path": "module.parser.javascript/dynamic.overrideStrict", + "type": "enum", + "values": Array [ + "strict", + "non-strict", + ], + }, + ], + "description": "Override the module to strict or non-strict. This may affect the behavior of the module (some behaviors differ between strict and non-strict), so please configure this option carefully.", + "multiple": false, + "simpleType": "string", + }, + "module-parser-javascript-dynamic-reexport-exports-presence": Object { + "configs": Array [ + Object { + "description": "Specifies the behavior of invalid export names in \\"export ... from ...\\". This might be useful to disable during the migration from \\"export ... from ...\\" to \\"export type ... from ...\\" when reexporting types in TypeScript.", + "multiple": false, + "path": "module.parser.javascript/dynamic.reexportExportsPresence", + "type": "enum", + "values": Array [ + "error", + "warn", + "auto", + false, + ], + }, + ], + "description": "Specifies the behavior of invalid export names in \\"export ... from ...\\". This might be useful to disable during the migration from \\"export ... from ...\\" to \\"export type ... from ...\\" when reexporting types in TypeScript.", + "multiple": false, + "simpleType": "string", }, "module-parser-javascript-dynamic-require-context": Object { "configs": Array [ @@ -1768,13 +3036,13 @@ Object { "module-parser-javascript-dynamic-strict-export-presence": Object { "configs": Array [ Object { - "description": "Emit errors instead of warnings when imported names don't exist in imported module.", + "description": "Deprecated in favor of \\"exportsPresence\\". Emit errors instead of warnings when imported names don't exist in imported module.", "multiple": false, "path": "module.parser.javascript/dynamic.strictExportPresence", "type": "boolean", }, ], - "description": "Emit errors instead of warnings when imported names don't exist in imported module.", + "description": "Deprecated in favor of \\"exportsPresence\\". Emit errors instead of warnings when imported names don't exist in imported module.", "multiple": false, "simpleType": "boolean", }, @@ -1906,13 +3174,13 @@ Object { "module-parser-javascript-dynamic-worker-reset": Object { "configs": Array [ Object { - "description": "Clear all items provided in configuration. Disable or configure parsing of WebWorker syntax like new Worker() or navigator.serviceWorker.register().", + "description": "Clear all items provided in 'module.parser.javascript/dynamic.worker' configuration. Disable or configure parsing of WebWorker syntax like new Worker() or navigator.serviceWorker.register().", "multiple": false, "path": "module.parser.javascript/dynamic.worker", "type": "reset", }, ], - "description": "Clear all items provided in configuration. Disable or configure parsing of WebWorker syntax like new Worker() or navigator.serviceWorker.register().", + "description": "Clear all items provided in 'module.parser.javascript/dynamic.worker' configuration. Disable or configure parsing of WebWorker syntax like new Worker() or navigator.serviceWorker.register().", "multiple": false, "simpleType": "boolean", }, @@ -2010,6 +3278,120 @@ Object { "multiple": false, "simpleType": "boolean", }, + "module-parser-javascript-esm-create-require": Object { + "configs": Array [ + Object { + "description": "Enable/disable parsing \\"import { createRequire } from \\"module\\"\\" and evaluating createRequire().", + "multiple": false, + "path": "module.parser.javascript/esm.createRequire", + "type": "boolean", + }, + Object { + "description": "Enable/disable parsing \\"import { createRequire } from \\"module\\"\\" and evaluating createRequire().", + "multiple": false, + "path": "module.parser.javascript/esm.createRequire", + "type": "string", + }, + ], + "description": "Enable/disable parsing \\"import { createRequire } from \\"module\\"\\" and evaluating createRequire().", + "multiple": false, + "simpleType": "string", + }, + "module-parser-javascript-esm-dynamic-import-fetch-priority": Object { + "configs": Array [ + Object { + "description": "Specifies global fetchPriority for dynamic import.", + "multiple": false, + "path": "module.parser.javascript/esm.dynamicImportFetchPriority", + "type": "enum", + "values": Array [ + "low", + "high", + "auto", + false, + ], + }, + ], + "description": "Specifies global fetchPriority for dynamic import.", + "multiple": false, + "simpleType": "string", + }, + "module-parser-javascript-esm-dynamic-import-mode": Object { + "configs": Array [ + Object { + "description": "Specifies global mode for dynamic import.", + "multiple": false, + "path": "module.parser.javascript/esm.dynamicImportMode", + "type": "enum", + "values": Array [ + "eager", + "weak", + "lazy", + "lazy-once", + ], + }, + ], + "description": "Specifies global mode for dynamic import.", + "multiple": false, + "simpleType": "string", + }, + "module-parser-javascript-esm-dynamic-import-prefetch": Object { + "configs": Array [ + Object { + "description": "Specifies global prefetch for dynamic import.", + "multiple": false, + "path": "module.parser.javascript/esm.dynamicImportPrefetch", + "type": "number", + }, + Object { + "description": "Specifies global prefetch for dynamic import.", + "multiple": false, + "path": "module.parser.javascript/esm.dynamicImportPrefetch", + "type": "boolean", + }, + ], + "description": "Specifies global prefetch for dynamic import.", + "multiple": false, + "simpleType": "string", + }, + "module-parser-javascript-esm-dynamic-import-preload": Object { + "configs": Array [ + Object { + "description": "Specifies global preload for dynamic import.", + "multiple": false, + "path": "module.parser.javascript/esm.dynamicImportPreload", + "type": "number", + }, + Object { + "description": "Specifies global preload for dynamic import.", + "multiple": false, + "path": "module.parser.javascript/esm.dynamicImportPreload", + "type": "boolean", + }, + ], + "description": "Specifies global preload for dynamic import.", + "multiple": false, + "simpleType": "string", + }, + "module-parser-javascript-esm-exports-presence": Object { + "configs": Array [ + Object { + "description": "Specifies the behavior of invalid export names in \\"import ... from ...\\" and \\"export ... from ...\\".", + "multiple": false, + "path": "module.parser.javascript/esm.exportsPresence", + "type": "enum", + "values": Array [ + "error", + "warn", + "auto", + false, + ], + }, + ], + "description": "Specifies the behavior of invalid export names in \\"import ... from ...\\" and \\"export ... from ...\\".", + "multiple": false, + "simpleType": "string", + }, "module-parser-javascript-esm-expr-context-critical": Object { "configs": Array [ Object { @@ -2094,6 +3476,51 @@ Object { "multiple": false, "simpleType": "boolean", }, + "module-parser-javascript-esm-import-exports-presence": Object { + "configs": Array [ + Object { + "description": "Specifies the behavior of invalid export names in \\"import ... from ...\\".", + "multiple": false, + "path": "module.parser.javascript/esm.importExportsPresence", + "type": "enum", + "values": Array [ + "error", + "warn", + "auto", + false, + ], + }, + ], + "description": "Specifies the behavior of invalid export names in \\"import ... from ...\\".", + "multiple": false, + "simpleType": "string", + }, + "module-parser-javascript-esm-import-meta": Object { + "configs": Array [ + Object { + "description": "Enable/disable evaluating import.meta.", + "multiple": false, + "path": "module.parser.javascript/esm.importMeta", + "type": "boolean", + }, + ], + "description": "Enable/disable evaluating import.meta.", + "multiple": false, + "simpleType": "boolean", + }, + "module-parser-javascript-esm-import-meta-context": Object { + "configs": Array [ + Object { + "description": "Enable/disable evaluating import.meta.webpackContext.", + "multiple": false, + "path": "module.parser.javascript/esm.importMetaContext", + "type": "boolean", + }, + ], + "description": "Enable/disable evaluating import.meta.webpackContext.", + "multiple": false, + "simpleType": "boolean", + }, "module-parser-javascript-esm-node": Object { "configs": Array [ Object { @@ -2120,7 +3547,9 @@ Object { "values": Array [ false, true, + "warn-mock", "mock", + "node-module", "eval-only", ], }, @@ -2139,7 +3568,9 @@ Object { "values": Array [ false, true, + "warn-mock", "mock", + "node-module", "eval-only", ], }, @@ -2154,12 +3585,53 @@ Object { "description": "Include a polyfill for the 'global' variable.", "multiple": false, "path": "module.parser.javascript/esm.node.global", - "type": "boolean", + "type": "enum", + "values": Array [ + false, + true, + "warn", + ], }, ], "description": "Include a polyfill for the 'global' variable.", "multiple": false, - "simpleType": "boolean", + "simpleType": "string", + }, + "module-parser-javascript-esm-override-strict": Object { + "configs": Array [ + Object { + "description": "Override the module to strict or non-strict. This may affect the behavior of the module (some behaviors differ between strict and non-strict), so please configure this option carefully.", + "multiple": false, + "path": "module.parser.javascript/esm.overrideStrict", + "type": "enum", + "values": Array [ + "strict", + "non-strict", + ], + }, + ], + "description": "Override the module to strict or non-strict. This may affect the behavior of the module (some behaviors differ between strict and non-strict), so please configure this option carefully.", + "multiple": false, + "simpleType": "string", + }, + "module-parser-javascript-esm-reexport-exports-presence": Object { + "configs": Array [ + Object { + "description": "Specifies the behavior of invalid export names in \\"export ... from ...\\". This might be useful to disable during the migration from \\"export ... from ...\\" to \\"export type ... from ...\\" when reexporting types in TypeScript.", + "multiple": false, + "path": "module.parser.javascript/esm.reexportExportsPresence", + "type": "enum", + "values": Array [ + "error", + "warn", + "auto", + false, + ], + }, + ], + "description": "Specifies the behavior of invalid export names in \\"export ... from ...\\". This might be useful to disable during the migration from \\"export ... from ...\\" to \\"export type ... from ...\\" when reexporting types in TypeScript.", + "multiple": false, + "simpleType": "string", }, "module-parser-javascript-esm-require-context": Object { "configs": Array [ @@ -2216,13 +3688,13 @@ Object { "module-parser-javascript-esm-strict-export-presence": Object { "configs": Array [ Object { - "description": "Emit errors instead of warnings when imported names don't exist in imported module.", + "description": "Deprecated in favor of \\"exportsPresence\\". Emit errors instead of warnings when imported names don't exist in imported module.", "multiple": false, "path": "module.parser.javascript/esm.strictExportPresence", "type": "boolean", }, ], - "description": "Emit errors instead of warnings when imported names don't exist in imported module.", + "description": "Deprecated in favor of \\"exportsPresence\\". Emit errors instead of warnings when imported names don't exist in imported module.", "multiple": false, "simpleType": "boolean", }, @@ -2354,13 +3826,13 @@ Object { "module-parser-javascript-esm-worker-reset": Object { "configs": Array [ Object { - "description": "Clear all items provided in configuration. Disable or configure parsing of WebWorker syntax like new Worker() or navigator.serviceWorker.register().", + "description": "Clear all items provided in 'module.parser.javascript/esm.worker' configuration. Disable or configure parsing of WebWorker syntax like new Worker() or navigator.serviceWorker.register().", "multiple": false, "path": "module.parser.javascript/esm.worker", "type": "reset", }, ], - "description": "Clear all items provided in configuration. Disable or configure parsing of WebWorker syntax like new Worker() or navigator.serviceWorker.register().", + "description": "Clear all items provided in 'module.parser.javascript/esm.worker' configuration. Disable or configure parsing of WebWorker syntax like new Worker() or navigator.serviceWorker.register().", "multiple": false, "simpleType": "boolean", }, @@ -2403,6 +3875,25 @@ Object { "multiple": false, "simpleType": "string", }, + "module-parser-javascript-exports-presence": Object { + "configs": Array [ + Object { + "description": "Specifies the behavior of invalid export names in \\"import ... from ...\\" and \\"export ... from ...\\".", + "multiple": false, + "path": "module.parser.javascript.exportsPresence", + "type": "enum", + "values": Array [ + "error", + "warn", + "auto", + false, + ], + }, + ], + "description": "Specifies the behavior of invalid export names in \\"import ... from ...\\" and \\"export ... from ...\\".", + "multiple": false, + "simpleType": "string", + }, "module-parser-javascript-expr-context-critical": Object { "configs": Array [ Object { @@ -2487,6 +3978,51 @@ Object { "multiple": false, "simpleType": "boolean", }, + "module-parser-javascript-import-exports-presence": Object { + "configs": Array [ + Object { + "description": "Specifies the behavior of invalid export names in \\"import ... from ...\\".", + "multiple": false, + "path": "module.parser.javascript.importExportsPresence", + "type": "enum", + "values": Array [ + "error", + "warn", + "auto", + false, + ], + }, + ], + "description": "Specifies the behavior of invalid export names in \\"import ... from ...\\".", + "multiple": false, + "simpleType": "string", + }, + "module-parser-javascript-import-meta": Object { + "configs": Array [ + Object { + "description": "Enable/disable evaluating import.meta.", + "multiple": false, + "path": "module.parser.javascript.importMeta", + "type": "boolean", + }, + ], + "description": "Enable/disable evaluating import.meta.", + "multiple": false, + "simpleType": "boolean", + }, + "module-parser-javascript-import-meta-context": Object { + "configs": Array [ + Object { + "description": "Enable/disable evaluating import.meta.webpackContext.", + "multiple": false, + "path": "module.parser.javascript.importMetaContext", + "type": "boolean", + }, + ], + "description": "Enable/disable evaluating import.meta.webpackContext.", + "multiple": false, + "simpleType": "boolean", + }, "module-parser-javascript-node": Object { "configs": Array [ Object { @@ -2513,7 +4049,9 @@ Object { "values": Array [ false, true, + "warn-mock", "mock", + "node-module", "eval-only", ], }, @@ -2532,7 +4070,9 @@ Object { "values": Array [ false, true, + "warn-mock", "mock", + "node-module", "eval-only", ], }, @@ -2547,12 +4087,53 @@ Object { "description": "Include a polyfill for the 'global' variable.", "multiple": false, "path": "module.parser.javascript.node.global", - "type": "boolean", + "type": "enum", + "values": Array [ + false, + true, + "warn", + ], }, ], "description": "Include a polyfill for the 'global' variable.", "multiple": false, - "simpleType": "boolean", + "simpleType": "string", + }, + "module-parser-javascript-override-strict": Object { + "configs": Array [ + Object { + "description": "Override the module to strict or non-strict. This may affect the behavior of the module (some behaviors differ between strict and non-strict), so please configure this option carefully.", + "multiple": false, + "path": "module.parser.javascript.overrideStrict", + "type": "enum", + "values": Array [ + "strict", + "non-strict", + ], + }, + ], + "description": "Override the module to strict or non-strict. This may affect the behavior of the module (some behaviors differ between strict and non-strict), so please configure this option carefully.", + "multiple": false, + "simpleType": "string", + }, + "module-parser-javascript-reexport-exports-presence": Object { + "configs": Array [ + Object { + "description": "Specifies the behavior of invalid export names in \\"export ... from ...\\". This might be useful to disable during the migration from \\"export ... from ...\\" to \\"export type ... from ...\\" when reexporting types in TypeScript.", + "multiple": false, + "path": "module.parser.javascript.reexportExportsPresence", + "type": "enum", + "values": Array [ + "error", + "warn", + "auto", + false, + ], + }, + ], + "description": "Specifies the behavior of invalid export names in \\"export ... from ...\\". This might be useful to disable during the migration from \\"export ... from ...\\" to \\"export type ... from ...\\" when reexporting types in TypeScript.", + "multiple": false, + "simpleType": "string", }, "module-parser-javascript-require-context": Object { "configs": Array [ @@ -2609,13 +4190,13 @@ Object { "module-parser-javascript-strict-export-presence": Object { "configs": Array [ Object { - "description": "Emit errors instead of warnings when imported names don't exist in imported module.", + "description": "Deprecated in favor of \\"exportsPresence\\". Emit errors instead of warnings when imported names don't exist in imported module.", "multiple": false, "path": "module.parser.javascript.strictExportPresence", "type": "boolean", }, ], - "description": "Emit errors instead of warnings when imported names don't exist in imported module.", + "description": "Deprecated in favor of \\"exportsPresence\\". Emit errors instead of warnings when imported names don't exist in imported module.", "multiple": false, "simpleType": "boolean", }, @@ -2747,13 +4328,13 @@ Object { "module-parser-javascript-worker-reset": Object { "configs": Array [ Object { - "description": "Clear all items provided in configuration. Disable or configure parsing of WebWorker syntax like new Worker() or navigator.serviceWorker.register().", + "description": "Clear all items provided in 'module.parser.javascript.worker' configuration. Disable or configure parsing of WebWorker syntax like new Worker() or navigator.serviceWorker.register().", "multiple": false, "path": "module.parser.javascript.worker", "type": "reset", }, ], - "description": "Clear all items provided in configuration. Disable or configure parsing of WebWorker syntax like new Worker() or navigator.serviceWorker.register().", + "description": "Clear all items provided in 'module.parser.javascript.worker' configuration. Disable or configure parsing of WebWorker syntax like new Worker() or navigator.serviceWorker.register().", "multiple": false, "simpleType": "boolean", }, @@ -2815,6 +4396,25 @@ Object { "multiple": true, "simpleType": "string", }, + "module-rules-compiler-not": Object { + "configs": Array [ + Object { + "description": "Logical NOT.", + "multiple": true, + "path": "module.rules[].compiler.not", + "type": "RegExp", + }, + Object { + "description": "Logical NOT.", + "multiple": true, + "path": "module.rules[].compiler.not", + "type": "string", + }, + ], + "description": "Logical NOT.", + "multiple": true, + "simpleType": "string", + }, "module-rules-dependency": Object { "configs": Array [ Object { @@ -2834,6 +4434,25 @@ Object { "multiple": true, "simpleType": "string", }, + "module-rules-dependency-not": Object { + "configs": Array [ + Object { + "description": "Logical NOT.", + "multiple": true, + "path": "module.rules[].dependency.not", + "type": "RegExp", + }, + Object { + "description": "Logical NOT.", + "multiple": true, + "path": "module.rules[].dependency.not", + "type": "string", + }, + ], + "description": "Logical NOT.", + "multiple": true, + "simpleType": "string", + }, "module-rules-enforce": Object { "configs": Array [ Object { @@ -2870,6 +4489,25 @@ Object { "multiple": true, "simpleType": "string", }, + "module-rules-exclude-not": Object { + "configs": Array [ + Object { + "description": "Logical NOT.", + "multiple": true, + "path": "module.rules[].exclude.not", + "type": "RegExp", + }, + Object { + "description": "Logical NOT.", + "multiple": true, + "path": "module.rules[].exclude.not", + "type": "path", + }, + ], + "description": "Logical NOT.", + "multiple": true, + "simpleType": "string", + }, "module-rules-include": Object { "configs": Array [ Object { @@ -2889,6 +4527,25 @@ Object { "multiple": true, "simpleType": "string", }, + "module-rules-include-not": Object { + "configs": Array [ + Object { + "description": "Logical NOT.", + "multiple": true, + "path": "module.rules[].include.not", + "type": "RegExp", + }, + Object { + "description": "Logical NOT.", + "multiple": true, + "path": "module.rules[].include.not", + "type": "path", + }, + ], + "description": "Logical NOT.", + "multiple": true, + "simpleType": "string", + }, "module-rules-issuer": Object { "configs": Array [ Object { @@ -2927,6 +4584,44 @@ Object { "multiple": true, "simpleType": "string", }, + "module-rules-issuer-layer-not": Object { + "configs": Array [ + Object { + "description": "Logical NOT.", + "multiple": true, + "path": "module.rules[].issuerLayer.not", + "type": "RegExp", + }, + Object { + "description": "Logical NOT.", + "multiple": true, + "path": "module.rules[].issuerLayer.not", + "type": "string", + }, + ], + "description": "Logical NOT.", + "multiple": true, + "simpleType": "string", + }, + "module-rules-issuer-not": Object { + "configs": Array [ + Object { + "description": "Logical NOT.", + "multiple": true, + "path": "module.rules[].issuer.not", + "type": "RegExp", + }, + Object { + "description": "Logical NOT.", + "multiple": true, + "path": "module.rules[].issuer.not", + "type": "path", + }, + ], + "description": "Logical NOT.", + "multiple": true, + "simpleType": "string", + }, "module-rules-layer": Object { "configs": Array [ Object { @@ -2972,6 +4667,25 @@ Object { "multiple": true, "simpleType": "string", }, + "module-rules-mimetype-not": Object { + "configs": Array [ + Object { + "description": "Logical NOT.", + "multiple": true, + "path": "module.rules[].mimetype.not", + "type": "RegExp", + }, + Object { + "description": "Logical NOT.", + "multiple": true, + "path": "module.rules[].mimetype.not", + "type": "string", + }, + ], + "description": "Logical NOT.", + "multiple": true, + "simpleType": "string", + }, "module-rules-real-resource": Object { "configs": Array [ Object { @@ -2991,16 +4705,35 @@ Object { "multiple": true, "simpleType": "string", }, + "module-rules-real-resource-not": Object { + "configs": Array [ + Object { + "description": "Logical NOT.", + "multiple": true, + "path": "module.rules[].realResource.not", + "type": "RegExp", + }, + Object { + "description": "Logical NOT.", + "multiple": true, + "path": "module.rules[].realResource.not", + "type": "path", + }, + ], + "description": "Logical NOT.", + "multiple": true, + "simpleType": "string", + }, "module-rules-reset": Object { "configs": Array [ Object { - "description": "Clear all items provided in configuration. A list of rules.", + "description": "Clear all items provided in 'module.rules' configuration. A list of rules.", "multiple": false, "path": "module.rules", "type": "reset", }, ], - "description": "Clear all items provided in configuration. A list of rules.", + "description": "Clear all items provided in 'module.rules' configuration. A list of rules.", "multiple": false, "simpleType": "boolean", }, @@ -3042,6 +4775,44 @@ Object { "multiple": true, "simpleType": "string", }, + "module-rules-resource-fragment-not": Object { + "configs": Array [ + Object { + "description": "Logical NOT.", + "multiple": true, + "path": "module.rules[].resourceFragment.not", + "type": "RegExp", + }, + Object { + "description": "Logical NOT.", + "multiple": true, + "path": "module.rules[].resourceFragment.not", + "type": "string", + }, + ], + "description": "Logical NOT.", + "multiple": true, + "simpleType": "string", + }, + "module-rules-resource-not": Object { + "configs": Array [ + Object { + "description": "Logical NOT.", + "multiple": true, + "path": "module.rules[].resource.not", + "type": "RegExp", + }, + Object { + "description": "Logical NOT.", + "multiple": true, + "path": "module.rules[].resource.not", + "type": "path", + }, + ], + "description": "Logical NOT.", + "multiple": true, + "simpleType": "string", + }, "module-rules-resource-query": Object { "configs": Array [ Object { @@ -3061,6 +4832,63 @@ Object { "multiple": true, "simpleType": "string", }, + "module-rules-resource-query-not": Object { + "configs": Array [ + Object { + "description": "Logical NOT.", + "multiple": true, + "path": "module.rules[].resourceQuery.not", + "type": "RegExp", + }, + Object { + "description": "Logical NOT.", + "multiple": true, + "path": "module.rules[].resourceQuery.not", + "type": "string", + }, + ], + "description": "Logical NOT.", + "multiple": true, + "simpleType": "string", + }, + "module-rules-scheme": Object { + "configs": Array [ + Object { + "description": "Match module scheme.", + "multiple": true, + "path": "module.rules[].scheme", + "type": "RegExp", + }, + Object { + "description": "Match module scheme.", + "multiple": true, + "path": "module.rules[].scheme", + "type": "string", + }, + ], + "description": "Match module scheme.", + "multiple": true, + "simpleType": "string", + }, + "module-rules-scheme-not": Object { + "configs": Array [ + Object { + "description": "Logical NOT.", + "multiple": true, + "path": "module.rules[].scheme.not", + "type": "RegExp", + }, + Object { + "description": "Logical NOT.", + "multiple": true, + "path": "module.rules[].scheme.not", + "type": "string", + }, + ], + "description": "Logical NOT.", + "multiple": true, + "simpleType": "string", + }, "module-rules-side-effects": Object { "configs": Array [ Object { @@ -3093,6 +4921,25 @@ Object { "multiple": true, "simpleType": "string", }, + "module-rules-test-not": Object { + "configs": Array [ + Object { + "description": "Logical NOT.", + "multiple": true, + "path": "module.rules[].test.not", + "type": "RegExp", + }, + Object { + "description": "Logical NOT.", + "multiple": true, + "path": "module.rules[].test.not", + "type": "path", + }, + ], + "description": "Logical NOT.", + "multiple": true, + "simpleType": "string", + }, "module-rules-type": Object { "configs": Array [ Object { @@ -3333,7 +5180,9 @@ Object { "values": Array [ false, true, + "warn-mock", "mock", + "node-module", "eval-only", ], }, @@ -3352,7 +5201,9 @@ Object { "values": Array [ false, true, + "warn-mock", "mock", + "node-module", "eval-only", ], }, @@ -3367,12 +5218,17 @@ Object { "description": "Include a polyfill for the 'global' variable.", "multiple": false, "path": "node.global", - "type": "boolean", + "type": "enum", + "values": Array [ + false, + true, + "warn", + ], }, ], "description": "Include a polyfill for the 'global' variable.", "multiple": false, - "simpleType": "boolean", + "simpleType": "string", }, "optimization-check-wasm-types": Object { "configs": Array [ @@ -3730,6 +5586,12 @@ Object { "all", ], }, + Object { + "description": "Select chunks for determining shared modules (defaults to \\"async\\", \\"initial\\" and \\"all\\" requires adding these chunks to the HTML).", + "multiple": false, + "path": "optimization.splitChunks.chunks", + "type": "RegExp", + }, ], "description": "Select chunks for determining shared modules (defaults to \\"async\\", \\"initial\\" and \\"all\\" requires adding these chunks to the HTML).", "multiple": false, @@ -3751,13 +5613,13 @@ Object { "optimization-split-chunks-default-size-types-reset": Object { "configs": Array [ Object { - "description": "Clear all items provided in configuration. Sets the size types which are used when a number is used for sizes.", + "description": "Clear all items provided in 'optimization.splitChunks.defaultSizeTypes' configuration. Sets the size types which are used when a number is used for sizes.", "multiple": false, "path": "optimization.splitChunks.defaultSizeTypes", "type": "reset", }, ], - "description": "Clear all items provided in configuration. Sets the size types which are used when a number is used for sizes.", + "description": "Clear all items provided in 'optimization.splitChunks.defaultSizeTypes' configuration. Sets the size types which are used when a number is used for sizes.", "multiple": false, "simpleType": "boolean", }, @@ -3787,6 +5649,30 @@ Object { "multiple": false, "simpleType": "string", }, + "optimization-split-chunks-fallback-cache-group-chunks": Object { + "configs": Array [ + Object { + "description": "Select chunks for determining shared modules (defaults to \\"async\\", \\"initial\\" and \\"all\\" requires adding these chunks to the HTML).", + "multiple": false, + "path": "optimization.splitChunks.fallbackCacheGroup.chunks", + "type": "enum", + "values": Array [ + "initial", + "async", + "all", + ], + }, + Object { + "description": "Select chunks for determining shared modules (defaults to \\"async\\", \\"initial\\" and \\"all\\" requires adding these chunks to the HTML).", + "multiple": false, + "path": "optimization.splitChunks.fallbackCacheGroup.chunks", + "type": "RegExp", + }, + ], + "description": "Select chunks for determining shared modules (defaults to \\"async\\", \\"initial\\" and \\"all\\" requires adding these chunks to the HTML).", + "multiple": false, + "simpleType": "string", + }, "optimization-split-chunks-fallback-cache-group-max-async-size": Object { "configs": Array [ Object { @@ -3839,6 +5725,19 @@ Object { "multiple": false, "simpleType": "number", }, + "optimization-split-chunks-fallback-cache-group-min-size-reduction": Object { + "configs": Array [ + Object { + "description": "Size of the javascript part of the chunk.", + "multiple": false, + "path": "optimization.splitChunks.fallbackCacheGroup.minSizeReduction", + "type": "number", + }, + ], + "description": "Size of the javascript part of the chunk.", + "multiple": false, + "simpleType": "number", + }, "optimization-split-chunks-filename": Object { "configs": Array [ Object { @@ -3969,6 +5868,19 @@ Object { "multiple": false, "simpleType": "number", }, + "optimization-split-chunks-min-size-reduction": Object { + "configs": Array [ + Object { + "description": "Size of the javascript part of the chunk.", + "multiple": false, + "path": "optimization.splitChunks.minSizeReduction", + "type": "number", + }, + ], + "description": "Size of the javascript part of the chunk.", + "multiple": false, + "simpleType": "number", + }, "optimization-split-chunks-name": Object { "configs": Array [ Object { @@ -4039,6 +5951,19 @@ Object { "multiple": false, "simpleType": "string", }, + "output-async-chunks": Object { + "configs": Array [ + Object { + "description": "Enable/disable creating async chunks that are loaded on demand.", + "multiple": false, + "path": "output.asyncChunks", + "type": "boolean", + }, + ], + "description": "Enable/disable creating async chunks that are loaded on demand.", + "multiple": false, + "simpleType": "boolean", + }, "output-charset": Object { "configs": Array [ Object { @@ -4068,24 +5993,25 @@ Object { "output-chunk-format": Object { "configs": Array [ Object { - "description": "The format of chunks (formats included by default are 'array-push' (web/WebWorker), 'commonjs' (node.js), but others might be added by plugins).", + "description": "The format of chunks (formats included by default are 'array-push' (web/WebWorker), 'commonjs' (node.js), 'module' (ESM), but others might be added by plugins).", "multiple": false, "path": "output.chunkFormat", "type": "enum", "values": Array [ "array-push", "commonjs", + "module", false, ], }, Object { - "description": "The format of chunks (formats included by default are 'array-push' (web/WebWorker), 'commonjs' (node.js), but others might be added by plugins).", + "description": "The format of chunks (formats included by default are 'array-push' (web/WebWorker), 'commonjs' (node.js), 'module' (ESM), but others might be added by plugins).", "multiple": false, "path": "output.chunkFormat", "type": "string", }, ], - "description": "The format of chunks (formats included by default are 'array-push' (web/WebWorker), 'commonjs' (node.js), but others might be added by plugins).", + "description": "The format of chunks (formats included by default are 'array-push' (web/WebWorker), 'commonjs' (node.js), 'module' (ESM), but others might be added by plugins).", "multiple": false, "simpleType": "string", }, @@ -4105,7 +6031,7 @@ Object { "output-chunk-loading": Object { "configs": Array [ Object { - "description": "The method of loading chunks (methods included by default are 'jsonp' (web), 'importScripts' (WebWorker), 'require' (sync node.js), 'async-node' (async node.js), but others might be added by plugins).", + "description": "The method of loading chunks (methods included by default are 'jsonp' (web), 'import' (ESM), 'importScripts' (WebWorker), 'require' (sync node.js), 'async-node' (async node.js), but others might be added by plugins).", "multiple": false, "path": "output.chunkLoading", "type": "enum", @@ -4114,7 +6040,7 @@ Object { ], }, Object { - "description": "The method of loading chunks (methods included by default are 'jsonp' (web), 'importScripts' (WebWorker), 'require' (sync node.js), 'async-node' (async node.js), but others might be added by plugins).", + "description": "The method of loading chunks (methods included by default are 'jsonp' (web), 'import' (ESM), 'importScripts' (WebWorker), 'require' (sync node.js), 'async-node' (async node.js), but others might be added by plugins).", "multiple": false, "path": "output.chunkLoading", "type": "enum", @@ -4123,16 +6049,17 @@ Object { "import-scripts", "require", "async-node", + "import", ], }, Object { - "description": "The method of loading chunks (methods included by default are 'jsonp' (web), 'importScripts' (WebWorker), 'require' (sync node.js), 'async-node' (async node.js), but others might be added by plugins).", + "description": "The method of loading chunks (methods included by default are 'jsonp' (web), 'import' (ESM), 'importScripts' (WebWorker), 'require' (sync node.js), 'async-node' (async node.js), but others might be added by plugins).", "multiple": false, "path": "output.chunkLoading", "type": "string", }, ], - "description": "The method of loading chunks (methods included by default are 'jsonp' (web), 'importScripts' (WebWorker), 'require' (sync node.js), 'async-node' (async node.js), but others might be added by plugins).", + "description": "The method of loading chunks (methods included by default are 'jsonp' (web), 'import' (ESM), 'importScripts' (WebWorker), 'require' (sync node.js), 'async-node' (async node.js), but others might be added by plugins).", "multiple": false, "simpleType": "string", }, @@ -4223,7 +6150,46 @@ Object { ], "description": "This option enables cross-origin loading of chunks.", "multiple": false, - "simpleType": "string", + "simpleType": "string", + }, + "output-css-chunk-filename": Object { + "configs": Array [ + Object { + "description": "Specifies the filename template of output files on disk. You must **not** specify an absolute path here, but the path may contain folders separated by '/'! The specified path is joined with the value of the 'output.path' option to determine the location on disk.", + "multiple": false, + "path": "output.cssChunkFilename", + "type": "string", + }, + ], + "description": "Specifies the filename template of output files on disk. You must **not** specify an absolute path here, but the path may contain folders separated by '/'! The specified path is joined with the value of the 'output.path' option to determine the location on disk.", + "multiple": false, + "simpleType": "string", + }, + "output-css-filename": Object { + "configs": Array [ + Object { + "description": "Specifies the filename template of output files on disk. You must **not** specify an absolute path here, but the path may contain folders separated by '/'! The specified path is joined with the value of the 'output.path' option to determine the location on disk.", + "multiple": false, + "path": "output.cssFilename", + "type": "string", + }, + ], + "description": "Specifies the filename template of output files on disk. You must **not** specify an absolute path here, but the path may contain folders separated by '/'! The specified path is joined with the value of the 'output.path' option to determine the location on disk.", + "multiple": false, + "simpleType": "string", + }, + "output-css-head-data-compression": Object { + "configs": Array [ + Object { + "description": "Compress the data in the head tag of CSS files.", + "multiple": false, + "path": "output.cssHeadDataCompression", + "type": "boolean", + }, + ], + "description": "Compress the data in the head tag of CSS files.", + "multiple": false, + "simpleType": "boolean", }, "output-devtool-fallback-module-filename-template": Object { "configs": Array [ @@ -4267,7 +6233,7 @@ Object { "output-enabled-chunk-loading-types": Object { "configs": Array [ Object { - "description": "The method of loading chunks (methods included by default are 'jsonp' (web), 'importScripts' (WebWorker), 'require' (sync node.js), 'async-node' (async node.js), but others might be added by plugins).", + "description": "The method of loading chunks (methods included by default are 'jsonp' (web), 'import' (ESM), 'importScripts' (WebWorker), 'require' (sync node.js), 'async-node' (async node.js), but others might be added by plugins).", "multiple": true, "path": "output.enabledChunkLoadingTypes[]", "type": "enum", @@ -4276,36 +6242,37 @@ Object { "import-scripts", "require", "async-node", + "import", ], }, Object { - "description": "The method of loading chunks (methods included by default are 'jsonp' (web), 'importScripts' (WebWorker), 'require' (sync node.js), 'async-node' (async node.js), but others might be added by plugins).", + "description": "The method of loading chunks (methods included by default are 'jsonp' (web), 'import' (ESM), 'importScripts' (WebWorker), 'require' (sync node.js), 'async-node' (async node.js), but others might be added by plugins).", "multiple": true, "path": "output.enabledChunkLoadingTypes[]", "type": "string", }, ], - "description": "The method of loading chunks (methods included by default are 'jsonp' (web), 'importScripts' (WebWorker), 'require' (sync node.js), 'async-node' (async node.js), but others might be added by plugins).", + "description": "The method of loading chunks (methods included by default are 'jsonp' (web), 'import' (ESM), 'importScripts' (WebWorker), 'require' (sync node.js), 'async-node' (async node.js), but others might be added by plugins).", "multiple": true, "simpleType": "string", }, "output-enabled-chunk-loading-types-reset": Object { "configs": Array [ Object { - "description": "Clear all items provided in configuration. List of chunk loading types enabled for use by entry points.", + "description": "Clear all items provided in 'output.enabledChunkLoadingTypes' configuration. List of chunk loading types enabled for use by entry points.", "multiple": false, "path": "output.enabledChunkLoadingTypes", "type": "reset", }, ], - "description": "Clear all items provided in configuration. List of chunk loading types enabled for use by entry points.", + "description": "Clear all items provided in 'output.enabledChunkLoadingTypes' configuration. List of chunk loading types enabled for use by entry points.", "multiple": false, "simpleType": "boolean", }, "output-enabled-library-types": Object { "configs": Array [ Object { - "description": "Type of library (types included by default are 'var', 'module', 'assign', 'assign-properties', 'this', 'window', 'self', 'global', 'commonjs', 'commonjs2', 'commonjs-module', 'amd', 'amd-require', 'umd', 'umd2', 'jsonp', 'system', but others might be added by plugins).", + "description": "Type of library (types included by default are 'var', 'module', 'assign', 'assign-properties', 'this', 'window', 'self', 'global', 'commonjs', 'commonjs2', 'commonjs-module', 'commonjs-static', 'amd', 'amd-require', 'umd', 'umd2', 'jsonp', 'system', but others might be added by plugins).", "multiple": true, "path": "output.enabledLibraryTypes[]", "type": "enum", @@ -4321,6 +6288,7 @@ Object { "commonjs", "commonjs2", "commonjs-module", + "commonjs-static", "amd", "amd-require", "umd", @@ -4330,26 +6298,26 @@ Object { ], }, Object { - "description": "Type of library (types included by default are 'var', 'module', 'assign', 'assign-properties', 'this', 'window', 'self', 'global', 'commonjs', 'commonjs2', 'commonjs-module', 'amd', 'amd-require', 'umd', 'umd2', 'jsonp', 'system', but others might be added by plugins).", + "description": "Type of library (types included by default are 'var', 'module', 'assign', 'assign-properties', 'this', 'window', 'self', 'global', 'commonjs', 'commonjs2', 'commonjs-module', 'commonjs-static', 'amd', 'amd-require', 'umd', 'umd2', 'jsonp', 'system', but others might be added by plugins).", "multiple": true, "path": "output.enabledLibraryTypes[]", "type": "string", }, ], - "description": "Type of library (types included by default are 'var', 'module', 'assign', 'assign-properties', 'this', 'window', 'self', 'global', 'commonjs', 'commonjs2', 'commonjs-module', 'amd', 'amd-require', 'umd', 'umd2', 'jsonp', 'system', but others might be added by plugins).", + "description": "Type of library (types included by default are 'var', 'module', 'assign', 'assign-properties', 'this', 'window', 'self', 'global', 'commonjs', 'commonjs2', 'commonjs-module', 'commonjs-static', 'amd', 'amd-require', 'umd', 'umd2', 'jsonp', 'system', but others might be added by plugins).", "multiple": true, "simpleType": "string", }, "output-enabled-library-types-reset": Object { "configs": Array [ Object { - "description": "Clear all items provided in configuration. List of library types enabled for use by entry points.", + "description": "Clear all items provided in 'output.enabledLibraryTypes' configuration. List of library types enabled for use by entry points.", "multiple": false, "path": "output.enabledLibraryTypes", "type": "reset", }, ], - "description": "Clear all items provided in configuration. List of library types enabled for use by entry points.", + "description": "Clear all items provided in 'output.enabledLibraryTypes' configuration. List of library types enabled for use by entry points.", "multiple": false, "simpleType": "boolean", }, @@ -4380,13 +6348,13 @@ Object { "output-enabled-wasm-loading-types-reset": Object { "configs": Array [ Object { - "description": "Clear all items provided in configuration. List of wasm loading types enabled for use by entry points.", + "description": "Clear all items provided in 'output.enabledWasmLoadingTypes' configuration. List of wasm loading types enabled for use by entry points.", "multiple": false, "path": "output.enabledWasmLoadingTypes", "type": "reset", }, ], - "description": "Clear all items provided in configuration. List of wasm loading types enabled for use by entry points.", + "description": "Clear all items provided in 'output.enabledWasmLoadingTypes' configuration. List of wasm loading types enabled for use by entry points.", "multiple": false, "simpleType": "boolean", }, @@ -4403,6 +6371,19 @@ Object { "multiple": false, "simpleType": "boolean", }, + "output-environment-async-function": Object { + "configs": Array [ + Object { + "description": "The environment supports async function and await ('async function () { await ... }').", + "multiple": false, + "path": "output.environment.asyncFunction", + "type": "boolean", + }, + ], + "description": "The environment supports async function and await ('async function () { await ... }').", + "multiple": false, + "simpleType": "boolean", + }, "output-environment-big-int-literal": Object { "configs": Array [ Object { @@ -4442,6 +6423,19 @@ Object { "multiple": false, "simpleType": "boolean", }, + "output-environment-document": Object { + "configs": Array [ + Object { + "description": "The environment supports 'document'.", + "multiple": false, + "path": "output.environment.document", + "type": "boolean", + }, + ], + "description": "The environment supports 'document'.", + "multiple": false, + "simpleType": "boolean", + }, "output-environment-dynamic-import": Object { "configs": Array [ Object { @@ -4455,6 +6449,19 @@ Object { "multiple": false, "simpleType": "boolean", }, + "output-environment-dynamic-import-in-worker": Object { + "configs": Array [ + Object { + "description": "The environment supports an async import() is available when creating a worker.", + "multiple": false, + "path": "output.environment.dynamicImportInWorker", + "type": "boolean", + }, + ], + "description": "The environment supports an async import() is available when creating a worker.", + "multiple": false, + "simpleType": "boolean", + }, "output-environment-for-of": Object { "configs": Array [ Object { @@ -4468,6 +6475,19 @@ Object { "multiple": false, "simpleType": "boolean", }, + "output-environment-global-this": Object { + "configs": Array [ + Object { + "description": "The environment supports 'globalThis'.", + "multiple": false, + "path": "output.environment.globalThis", + "type": "boolean", + }, + ], + "description": "The environment supports 'globalThis'.", + "multiple": false, + "simpleType": "boolean", + }, "output-environment-module": Object { "configs": Array [ Object { @@ -4481,6 +6501,45 @@ Object { "multiple": false, "simpleType": "boolean", }, + "output-environment-node-prefix-for-core-modules": Object { + "configs": Array [ + Object { + "description": "The environment supports \`node:\` prefix for Node.js core modules.", + "multiple": false, + "path": "output.environment.nodePrefixForCoreModules", + "type": "boolean", + }, + ], + "description": "The environment supports \`node:\` prefix for Node.js core modules.", + "multiple": false, + "simpleType": "boolean", + }, + "output-environment-optional-chaining": Object { + "configs": Array [ + Object { + "description": "The environment supports optional chaining ('obj?.a' or 'obj?.()').", + "multiple": false, + "path": "output.environment.optionalChaining", + "type": "boolean", + }, + ], + "description": "The environment supports optional chaining ('obj?.a' or 'obj?.()').", + "multiple": false, + "simpleType": "boolean", + }, + "output-environment-template-literal": Object { + "configs": Array [ + Object { + "description": "The environment supports template literals.", + "multiple": false, + "path": "output.environment.templateLiteral", + "type": "boolean", + }, + ], + "description": "The environment supports template literals.", + "multiple": false, + "simpleType": "boolean", + }, "output-filename": Object { "configs": Array [ Object { @@ -4598,6 +6657,19 @@ Object { "multiple": false, "simpleType": "string", }, + "output-ignore-browser-warnings": Object { + "configs": Array [ + Object { + "description": "Ignore warnings in the browser.", + "multiple": false, + "path": "output.ignoreBrowserWarnings", + "type": "boolean", + }, + ], + "description": "Ignore warnings in the browser.", + "multiple": false, + "simpleType": "boolean", + }, "output-iife": Object { "configs": Array [ Object { @@ -4663,6 +6735,19 @@ Object { "multiple": false, "simpleType": "string", }, + "output-library-amd-container": Object { + "configs": Array [ + Object { + "description": "Add a container for define/require functions in the AMD module.", + "multiple": false, + "path": "output.library.amdContainer", + "type": "string", + }, + ], + "description": "Add a container for define/require functions in the AMD module.", + "multiple": false, + "simpleType": "string", + }, "output-library-auxiliary-comment": Object { "configs": Array [ Object { @@ -4757,13 +6842,13 @@ Object { "output-library-export-reset": Object { "configs": Array [ Object { - "description": "Clear all items provided in configuration. Specify which export should be exposed as library.", + "description": "Clear all items provided in 'output.library.export' configuration. Specify which export should be exposed as library.", "multiple": false, "path": "output.library.export", "type": "reset", }, ], - "description": "Clear all items provided in configuration. Specify which export should be exposed as library.", + "description": "Clear all items provided in 'output.library.export' configuration. Specify which export should be exposed as library.", "multiple": false, "simpleType": "boolean", }, @@ -4809,13 +6894,13 @@ Object { "output-library-name-reset": Object { "configs": Array [ Object { - "description": "Clear all items provided in configuration. The name of the library (some types allow unnamed libraries too).", + "description": "Clear all items provided in 'output.library.name' configuration. The name of the library (some types allow unnamed libraries too).", "multiple": false, "path": "output.library.name", "type": "reset", }, ], - "description": "Clear all items provided in configuration. The name of the library (some types allow unnamed libraries too).", + "description": "Clear all items provided in 'output.library.name' configuration. The name of the library (some types allow unnamed libraries too).", "multiple": false, "simpleType": "boolean", }, @@ -4835,26 +6920,26 @@ Object { "output-library-name-root-reset": Object { "configs": Array [ Object { - "description": "Clear all items provided in configuration. Name of the property exposed globally by a UMD library.", + "description": "Clear all items provided in 'output.library.name.root' configuration. Name of the property exposed globally by a UMD library.", "multiple": false, "path": "output.library.name.root", "type": "reset", }, ], - "description": "Clear all items provided in configuration. Name of the property exposed globally by a UMD library.", + "description": "Clear all items provided in 'output.library.name.root' configuration. Name of the property exposed globally by a UMD library.", "multiple": false, "simpleType": "boolean", }, "output-library-reset": Object { "configs": Array [ Object { - "description": "Clear all items provided in configuration. The name of the library (some types allow unnamed libraries too).", + "description": "Clear all items provided in 'output.library' configuration. The name of the library (some types allow unnamed libraries too).", "multiple": false, "path": "output.library", "type": "reset", }, ], - "description": "Clear all items provided in configuration. The name of the library (some types allow unnamed libraries too).", + "description": "Clear all items provided in 'output.library' configuration. The name of the library (some types allow unnamed libraries too).", "multiple": false, "simpleType": "boolean", }, @@ -4874,20 +6959,20 @@ Object { "output-library-root-reset": Object { "configs": Array [ Object { - "description": "Clear all items provided in configuration. Name of the property exposed globally by a UMD library.", + "description": "Clear all items provided in 'output.library.root' configuration. Name of the property exposed globally by a UMD library.", "multiple": false, "path": "output.library.root", "type": "reset", }, ], - "description": "Clear all items provided in configuration. Name of the property exposed globally by a UMD library.", + "description": "Clear all items provided in 'output.library.root' configuration. Name of the property exposed globally by a UMD library.", "multiple": false, "simpleType": "boolean", }, "output-library-type": Object { "configs": Array [ Object { - "description": "Type of library (types included by default are 'var', 'module', 'assign', 'assign-properties', 'this', 'window', 'self', 'global', 'commonjs', 'commonjs2', 'commonjs-module', 'amd', 'amd-require', 'umd', 'umd2', 'jsonp', 'system', but others might be added by plugins).", + "description": "Type of library (types included by default are 'var', 'module', 'assign', 'assign-properties', 'this', 'window', 'self', 'global', 'commonjs', 'commonjs2', 'commonjs-module', 'commonjs-static', 'amd', 'amd-require', 'umd', 'umd2', 'jsonp', 'system', but others might be added by plugins).", "multiple": false, "path": "output.library.type", "type": "enum", @@ -4903,6 +6988,7 @@ Object { "commonjs", "commonjs2", "commonjs-module", + "commonjs-static", "amd", "amd-require", "umd", @@ -4912,13 +6998,13 @@ Object { ], }, Object { - "description": "Type of library (types included by default are 'var', 'module', 'assign', 'assign-properties', 'this', 'window', 'self', 'global', 'commonjs', 'commonjs2', 'commonjs-module', 'amd', 'amd-require', 'umd', 'umd2', 'jsonp', 'system', but others might be added by plugins).", + "description": "Type of library (types included by default are 'var', 'module', 'assign', 'assign-properties', 'this', 'window', 'self', 'global', 'commonjs', 'commonjs2', 'commonjs-module', 'commonjs-static', 'amd', 'amd-require', 'umd', 'umd2', 'jsonp', 'system', but others might be added by plugins).", "multiple": false, "path": "output.library.type", "type": "string", }, ], - "description": "Type of library (types included by default are 'var', 'module', 'assign', 'assign-properties', 'this', 'window', 'self', 'global', 'commonjs', 'commonjs2', 'commonjs-module', 'amd', 'amd-require', 'umd', 'umd2', 'jsonp', 'system', but others might be added by plugins).", + "description": "Type of library (types included by default are 'var', 'module', 'assign', 'assign-properties', 'this', 'window', 'self', 'global', 'commonjs', 'commonjs2', 'commonjs-module', 'commonjs-static', 'amd', 'amd-require', 'umd', 'umd2', 'jsonp', 'system', but others might be added by plugins).", "multiple": false, "simpleType": "string", }, @@ -4986,7 +7072,7 @@ Object { "output-public-path": Object { "configs": Array [ Object { - "description": "The \`publicPath\` specifies the public URL address of the output files when referenced in a browser.", + "description": "The 'publicPath' specifies the public URL address of the output files when referenced in a browser.", "multiple": false, "path": "output.publicPath", "type": "enum", @@ -4995,13 +7081,13 @@ Object { ], }, Object { - "description": "The \`publicPath\` specifies the public URL address of the output files when referenced in a browser.", + "description": "The 'publicPath' specifies the public URL address of the output files when referenced in a browser.", "multiple": false, "path": "output.publicPath", "type": "string", }, ], - "description": "The \`publicPath\` specifies the public URL address of the output files when referenced in a browser.", + "description": "The 'publicPath' specifies the public URL address of the output files when referenced in a browser.", "multiple": false, "simpleType": "string", }, @@ -5075,6 +7161,58 @@ Object { "multiple": false, "simpleType": "boolean", }, + "output-trusted-types": Object { + "configs": Array [ + Object { + "description": "Use a Trusted Types policy to create urls for chunks. 'output.uniqueName' is used a default policy name. Passing a string sets a custom policy name.", + "multiple": false, + "path": "output.trustedTypes", + "type": "enum", + "values": Array [ + true, + ], + }, + Object { + "description": "The name of the Trusted Types policy created by webpack to serve bundle chunks.", + "multiple": false, + "path": "output.trustedTypes", + "type": "string", + }, + ], + "description": "Use a Trusted Types policy to create urls for chunks. 'output.uniqueName' is used a default policy name. Passing a string sets a custom policy name. The name of the Trusted Types policy created by webpack to serve bundle chunks.", + "multiple": false, + "simpleType": "string", + }, + "output-trusted-types-on-policy-creation-failure": Object { + "configs": Array [ + Object { + "description": "If the call to \`trustedTypes.createPolicy(...)\` fails -- e.g., due to the policy name missing from the CSP \`trusted-types\` list, or it being a duplicate name, etc. -- controls whether to continue with loading in the hope that \`require-trusted-types-for 'script'\` isn't enforced yet, versus fail immediately. Default behavior is 'stop'.", + "multiple": false, + "path": "output.trustedTypes.onPolicyCreationFailure", + "type": "enum", + "values": Array [ + "continue", + "stop", + ], + }, + ], + "description": "If the call to \`trustedTypes.createPolicy(...)\` fails -- e.g., due to the policy name missing from the CSP \`trusted-types\` list, or it being a duplicate name, etc. -- controls whether to continue with loading in the hope that \`require-trusted-types-for 'script'\` isn't enforced yet, versus fail immediately. Default behavior is 'stop'.", + "multiple": false, + "simpleType": "string", + }, + "output-trusted-types-policy-name": Object { + "configs": Array [ + Object { + "description": "The name of the Trusted Types policy created by webpack to serve bundle chunks.", + "multiple": false, + "path": "output.trustedTypes.policyName", + "type": "string", + }, + ], + "description": "The name of the Trusted Types policy created by webpack to serve bundle chunks.", + "multiple": false, + "simpleType": "string", + }, "output-unique-name": Object { "configs": Array [ Object { @@ -5137,7 +7275,7 @@ Object { "output-worker-chunk-loading": Object { "configs": Array [ Object { - "description": "The method of loading chunks (methods included by default are 'jsonp' (web), 'importScripts' (WebWorker), 'require' (sync node.js), 'async-node' (async node.js), but others might be added by plugins).", + "description": "The method of loading chunks (methods included by default are 'jsonp' (web), 'import' (ESM), 'importScripts' (WebWorker), 'require' (sync node.js), 'async-node' (async node.js), but others might be added by plugins).", "multiple": false, "path": "output.workerChunkLoading", "type": "enum", @@ -5146,7 +7284,7 @@ Object { ], }, Object { - "description": "The method of loading chunks (methods included by default are 'jsonp' (web), 'importScripts' (WebWorker), 'require' (sync node.js), 'async-node' (async node.js), but others might be added by plugins).", + "description": "The method of loading chunks (methods included by default are 'jsonp' (web), 'import' (ESM), 'importScripts' (WebWorker), 'require' (sync node.js), 'async-node' (async node.js), but others might be added by plugins).", "multiple": false, "path": "output.workerChunkLoading", "type": "enum", @@ -5155,16 +7293,30 @@ Object { "import-scripts", "require", "async-node", + "import", ], }, Object { - "description": "The method of loading chunks (methods included by default are 'jsonp' (web), 'importScripts' (WebWorker), 'require' (sync node.js), 'async-node' (async node.js), but others might be added by plugins).", + "description": "The method of loading chunks (methods included by default are 'jsonp' (web), 'import' (ESM), 'importScripts' (WebWorker), 'require' (sync node.js), 'async-node' (async node.js), but others might be added by plugins).", "multiple": false, "path": "output.workerChunkLoading", "type": "string", }, ], - "description": "The method of loading chunks (methods included by default are 'jsonp' (web), 'importScripts' (WebWorker), 'require' (sync node.js), 'async-node' (async node.js), but others might be added by plugins).", + "description": "The method of loading chunks (methods included by default are 'jsonp' (web), 'import' (ESM), 'importScripts' (WebWorker), 'require' (sync node.js), 'async-node' (async node.js), but others might be added by plugins).", + "multiple": false, + "simpleType": "string", + }, + "output-worker-public-path": Object { + "configs": Array [ + Object { + "description": "Worker public path. Much like the public path, this sets the location where the worker script file is intended to be found. If not set, webpack will use the publicPath. Don't set this option unless your worker scripts are located at a different path from your other script files.", + "multiple": false, + "path": "output.workerPublicPath", + "type": "string", + }, + ], + "description": "Worker public path. Much like the public path, this sets the location where the worker script file is intended to be found. If not set, webpack will use the publicPath. Don't set this option unless your worker scripts are located at a different path from your other script files.", "multiple": false, "simpleType": "string", }, @@ -5391,13 +7543,13 @@ Object { "resolve-alias-fields-reset": Object { "configs": Array [ Object { - "description": "Clear all items provided in configuration. Fields in the description file (usually package.json) which are used to redirect requests inside the module.", + "description": "Clear all items provided in 'resolve.aliasFields' configuration. Fields in the description file (usually package.json) which are used to redirect requests inside the module.", "multiple": false, "path": "resolve.aliasFields", "type": "reset", }, ], - "description": "Clear all items provided in configuration. Fields in the description file (usually package.json) which are used to redirect requests inside the module.", + "description": "Clear all items provided in 'resolve.aliasFields' configuration. Fields in the description file (usually package.json) which are used to redirect requests inside the module.", "multiple": false, "simpleType": "boolean", }, @@ -5430,13 +7582,13 @@ Object { "resolve-alias-reset": Object { "configs": Array [ Object { - "description": "Clear all items provided in configuration. Redirect module requests.", + "description": "Clear all items provided in 'resolve.alias' configuration. Redirect module requests.", "multiple": false, "path": "resolve.alias", "type": "reset", }, ], - "description": "Clear all items provided in configuration. Redirect module requests.", + "description": "Clear all items provided in 'resolve.alias' configuration. Redirect module requests.", "multiple": false, "simpleType": "boolean", }, @@ -5482,13 +7634,13 @@ Object { "resolve-condition-names-reset": Object { "configs": Array [ Object { - "description": "Clear all items provided in configuration. Condition names for exports field entry point.", + "description": "Clear all items provided in 'resolve.conditionNames' configuration. Condition names for exports field entry point.", "multiple": false, "path": "resolve.conditionNames", "type": "reset", }, ], - "description": "Clear all items provided in configuration. Condition names for exports field entry point.", + "description": "Clear all items provided in 'resolve.conditionNames' configuration. Condition names for exports field entry point.", "multiple": false, "simpleType": "boolean", }, @@ -5508,13 +7660,13 @@ Object { "resolve-description-files-reset": Object { "configs": Array [ Object { - "description": "Clear all items provided in configuration. Filenames used to find a description file (like a package.json).", + "description": "Clear all items provided in 'resolve.descriptionFiles' configuration. Filenames used to find a description file (like a package.json).", "multiple": false, "path": "resolve.descriptionFiles", "type": "reset", }, ], - "description": "Clear all items provided in configuration. Filenames used to find a description file (like a package.json).", + "description": "Clear all items provided in 'resolve.descriptionFiles' configuration. Filenames used to find a description file (like a package.json).", "multiple": false, "simpleType": "boolean", }, @@ -5547,13 +7699,13 @@ Object { "resolve-exports-fields-reset": Object { "configs": Array [ Object { - "description": "Clear all items provided in configuration. Field names from the description file (usually package.json) which are used to provide entry points of a package.", + "description": "Clear all items provided in 'resolve.exportsFields' configuration. Field names from the description file (usually package.json) which are used to provide entry points of a package.", "multiple": false, "path": "resolve.exportsFields", "type": "reset", }, ], - "description": "Clear all items provided in configuration. Field names from the description file (usually package.json) which are used to provide entry points of a package.", + "description": "Clear all items provided in 'resolve.exportsFields' configuration. Field names from the description file (usually package.json) which are used to provide entry points of a package.", "multiple": false, "simpleType": "boolean", }, @@ -5573,13 +7725,13 @@ Object { "resolve-extensions-reset": Object { "configs": Array [ Object { - "description": "Clear all items provided in configuration. Extensions added to the request when trying to find the file.", + "description": "Clear all items provided in 'resolve.extensions' configuration. Extensions added to the request when trying to find the file.", "multiple": false, "path": "resolve.extensions", "type": "reset", }, ], - "description": "Clear all items provided in configuration. Extensions added to the request when trying to find the file.", + "description": "Clear all items provided in 'resolve.extensions' configuration. Extensions added to the request when trying to find the file.", "multiple": false, "simpleType": "boolean", }, @@ -5634,13 +7786,13 @@ Object { "resolve-fallback-reset": Object { "configs": Array [ Object { - "description": "Clear all items provided in configuration. Redirect module requests.", + "description": "Clear all items provided in 'resolve.fallback' configuration. Redirect module requests.", "multiple": false, "path": "resolve.fallback", "type": "reset", }, ], - "description": "Clear all items provided in configuration. Redirect module requests.", + "description": "Clear all items provided in 'resolve.fallback' configuration. Redirect module requests.", "multiple": false, "simpleType": "boolean", }, @@ -5673,13 +7825,13 @@ Object { "resolve-imports-fields-reset": Object { "configs": Array [ Object { - "description": "Clear all items provided in configuration. Field names from the description file (usually package.json) which are used to provide internal request of a package (requests starting with # are considered as internal).", + "description": "Clear all items provided in 'resolve.importsFields' configuration. Field names from the description file (usually package.json) which are used to provide internal request of a package (requests starting with # are considered as internal).", "multiple": false, "path": "resolve.importsFields", "type": "reset", }, ], - "description": "Clear all items provided in configuration. Field names from the description file (usually package.json) which are used to provide internal request of a package (requests starting with # are considered as internal).", + "description": "Clear all items provided in 'resolve.importsFields' configuration. Field names from the description file (usually package.json) which are used to provide internal request of a package (requests starting with # are considered as internal).", "multiple": false, "simpleType": "boolean", }, @@ -5721,13 +7873,13 @@ Object { "resolve-loader-alias-fields-reset": Object { "configs": Array [ Object { - "description": "Clear all items provided in configuration. Fields in the description file (usually package.json) which are used to redirect requests inside the module.", + "description": "Clear all items provided in 'resolveLoader.aliasFields' configuration. Fields in the description file (usually package.json) which are used to redirect requests inside the module.", "multiple": false, "path": "resolveLoader.aliasFields", "type": "reset", }, ], - "description": "Clear all items provided in configuration. Fields in the description file (usually package.json) which are used to redirect requests inside the module.", + "description": "Clear all items provided in 'resolveLoader.aliasFields' configuration. Fields in the description file (usually package.json) which are used to redirect requests inside the module.", "multiple": false, "simpleType": "boolean", }, @@ -5760,13 +7912,13 @@ Object { "resolve-loader-alias-reset": Object { "configs": Array [ Object { - "description": "Clear all items provided in configuration. Redirect module requests.", + "description": "Clear all items provided in 'resolveLoader.alias' configuration. Redirect module requests.", "multiple": false, "path": "resolveLoader.alias", "type": "reset", }, ], - "description": "Clear all items provided in configuration. Redirect module requests.", + "description": "Clear all items provided in 'resolveLoader.alias' configuration. Redirect module requests.", "multiple": false, "simpleType": "boolean", }, @@ -5812,13 +7964,13 @@ Object { "resolve-loader-condition-names-reset": Object { "configs": Array [ Object { - "description": "Clear all items provided in configuration. Condition names for exports field entry point.", + "description": "Clear all items provided in 'resolveLoader.conditionNames' configuration. Condition names for exports field entry point.", "multiple": false, "path": "resolveLoader.conditionNames", "type": "reset", }, ], - "description": "Clear all items provided in configuration. Condition names for exports field entry point.", + "description": "Clear all items provided in 'resolveLoader.conditionNames' configuration. Condition names for exports field entry point.", "multiple": false, "simpleType": "boolean", }, @@ -5838,13 +7990,13 @@ Object { "resolve-loader-description-files-reset": Object { "configs": Array [ Object { - "description": "Clear all items provided in configuration. Filenames used to find a description file (like a package.json).", + "description": "Clear all items provided in 'resolveLoader.descriptionFiles' configuration. Filenames used to find a description file (like a package.json).", "multiple": false, "path": "resolveLoader.descriptionFiles", "type": "reset", }, ], - "description": "Clear all items provided in configuration. Filenames used to find a description file (like a package.json).", + "description": "Clear all items provided in 'resolveLoader.descriptionFiles' configuration. Filenames used to find a description file (like a package.json).", "multiple": false, "simpleType": "boolean", }, @@ -5877,13 +8029,13 @@ Object { "resolve-loader-exports-fields-reset": Object { "configs": Array [ Object { - "description": "Clear all items provided in configuration. Field names from the description file (usually package.json) which are used to provide entry points of a package.", + "description": "Clear all items provided in 'resolveLoader.exportsFields' configuration. Field names from the description file (usually package.json) which are used to provide entry points of a package.", "multiple": false, "path": "resolveLoader.exportsFields", "type": "reset", }, ], - "description": "Clear all items provided in configuration. Field names from the description file (usually package.json) which are used to provide entry points of a package.", + "description": "Clear all items provided in 'resolveLoader.exportsFields' configuration. Field names from the description file (usually package.json) which are used to provide entry points of a package.", "multiple": false, "simpleType": "boolean", }, @@ -5903,13 +8055,13 @@ Object { "resolve-loader-extensions-reset": Object { "configs": Array [ Object { - "description": "Clear all items provided in configuration. Extensions added to the request when trying to find the file.", + "description": "Clear all items provided in 'resolveLoader.extensions' configuration. Extensions added to the request when trying to find the file.", "multiple": false, "path": "resolveLoader.extensions", "type": "reset", }, ], - "description": "Clear all items provided in configuration. Extensions added to the request when trying to find the file.", + "description": "Clear all items provided in 'resolveLoader.extensions' configuration. Extensions added to the request when trying to find the file.", "multiple": false, "simpleType": "boolean", }, @@ -5964,13 +8116,13 @@ Object { "resolve-loader-fallback-reset": Object { "configs": Array [ Object { - "description": "Clear all items provided in configuration. Redirect module requests.", + "description": "Clear all items provided in 'resolveLoader.fallback' configuration. Redirect module requests.", "multiple": false, "path": "resolveLoader.fallback", "type": "reset", }, ], - "description": "Clear all items provided in configuration. Redirect module requests.", + "description": "Clear all items provided in 'resolveLoader.fallback' configuration. Redirect module requests.", "multiple": false, "simpleType": "boolean", }, @@ -6003,13 +8155,13 @@ Object { "resolve-loader-imports-fields-reset": Object { "configs": Array [ Object { - "description": "Clear all items provided in configuration. Field names from the description file (usually package.json) which are used to provide internal request of a package (requests starting with # are considered as internal).", + "description": "Clear all items provided in 'resolveLoader.importsFields' configuration. Field names from the description file (usually package.json) which are used to provide internal request of a package (requests starting with # are considered as internal).", "multiple": false, "path": "resolveLoader.importsFields", "type": "reset", }, ], - "description": "Clear all items provided in configuration. Field names from the description file (usually package.json) which are used to provide internal request of a package (requests starting with # are considered as internal).", + "description": "Clear all items provided in 'resolveLoader.importsFields' configuration. Field names from the description file (usually package.json) which are used to provide internal request of a package (requests starting with # are considered as internal).", "multiple": false, "simpleType": "boolean", }, @@ -6029,13 +8181,13 @@ Object { "resolve-loader-main-fields-reset": Object { "configs": Array [ Object { - "description": "Clear all items provided in configuration. Field names from the description file (package.json) which are used to find the default entry point.", + "description": "Clear all items provided in 'resolveLoader.mainFields' configuration. Field names from the description file (package.json) which are used to find the default entry point.", "multiple": false, "path": "resolveLoader.mainFields", "type": "reset", }, ], - "description": "Clear all items provided in configuration. Field names from the description file (package.json) which are used to find the default entry point.", + "description": "Clear all items provided in 'resolveLoader.mainFields' configuration. Field names from the description file (package.json) which are used to find the default entry point.", "multiple": false, "simpleType": "boolean", }, @@ -6055,13 +8207,13 @@ Object { "resolve-loader-main-files-reset": Object { "configs": Array [ Object { - "description": "Clear all items provided in configuration. Filenames used to find the default entry point if there is no description file or main field.", + "description": "Clear all items provided in 'resolveLoader.mainFiles' configuration. Filenames used to find the default entry point if there is no description file or main field.", "multiple": false, "path": "resolveLoader.mainFiles", "type": "reset", }, ], - "description": "Clear all items provided in configuration. Filenames used to find the default entry point if there is no description file or main field.", + "description": "Clear all items provided in 'resolveLoader.mainFiles' configuration. Filenames used to find the default entry point if there is no description file or main field.", "multiple": false, "simpleType": "boolean", }, @@ -6081,13 +8233,13 @@ Object { "resolve-loader-modules-reset": Object { "configs": Array [ Object { - "description": "Clear all items provided in configuration. Folder names or directory paths where to find modules.", + "description": "Clear all items provided in 'resolveLoader.modules' configuration. Folder names or directory paths where to find modules.", "multiple": false, "path": "resolveLoader.modules", "type": "reset", }, ], - "description": "Clear all items provided in configuration. Folder names or directory paths where to find modules.", + "description": "Clear all items provided in 'resolveLoader.modules' configuration. Folder names or directory paths where to find modules.", "multiple": false, "simpleType": "boolean", }, @@ -6139,13 +8291,13 @@ Object { "resolve-loader-restrictions-reset": Object { "configs": Array [ Object { - "description": "Clear all items provided in configuration. A list of resolve restrictions. Resolve results must fulfill all of these restrictions to resolve successfully. Other resolve paths are taken when restrictions are not met.", + "description": "Clear all items provided in 'resolveLoader.restrictions' configuration. A list of resolve restrictions. Resolve results must fulfill all of these restrictions to resolve successfully. Other resolve paths are taken when restrictions are not met.", "multiple": false, "path": "resolveLoader.restrictions", "type": "reset", }, ], - "description": "Clear all items provided in configuration. A list of resolve restrictions. Resolve results must fulfill all of these restrictions to resolve successfully. Other resolve paths are taken when restrictions are not met.", + "description": "Clear all items provided in 'resolveLoader.restrictions' configuration. A list of resolve restrictions. Resolve results must fulfill all of these restrictions to resolve successfully. Other resolve paths are taken when restrictions are not met.", "multiple": false, "simpleType": "boolean", }, @@ -6165,13 +8317,13 @@ Object { "resolve-loader-roots-reset": Object { "configs": Array [ Object { - "description": "Clear all items provided in configuration. A list of directories in which requests that are server-relative URLs (starting with '/') are resolved.", + "description": "Clear all items provided in 'resolveLoader.roots' configuration. A list of directories in which requests that are server-relative URLs (starting with '/') are resolved.", "multiple": false, "path": "resolveLoader.roots", "type": "reset", }, ], - "description": "Clear all items provided in configuration. A list of directories in which requests that are server-relative URLs (starting with '/') are resolved.", + "description": "Clear all items provided in 'resolveLoader.roots' configuration. A list of directories in which requests that are server-relative URLs (starting with '/') are resolved.", "multiple": false, "simpleType": "boolean", }, @@ -6230,13 +8382,13 @@ Object { "resolve-main-fields-reset": Object { "configs": Array [ Object { - "description": "Clear all items provided in configuration. Field names from the description file (package.json) which are used to find the default entry point.", + "description": "Clear all items provided in 'resolve.mainFields' configuration. Field names from the description file (package.json) which are used to find the default entry point.", "multiple": false, "path": "resolve.mainFields", "type": "reset", }, ], - "description": "Clear all items provided in configuration. Field names from the description file (package.json) which are used to find the default entry point.", + "description": "Clear all items provided in 'resolve.mainFields' configuration. Field names from the description file (package.json) which are used to find the default entry point.", "multiple": false, "simpleType": "boolean", }, @@ -6256,13 +8408,13 @@ Object { "resolve-main-files-reset": Object { "configs": Array [ Object { - "description": "Clear all items provided in configuration. Filenames used to find the default entry point if there is no description file or main field.", + "description": "Clear all items provided in 'resolve.mainFiles' configuration. Filenames used to find the default entry point if there is no description file or main field.", "multiple": false, "path": "resolve.mainFiles", "type": "reset", }, ], - "description": "Clear all items provided in configuration. Filenames used to find the default entry point if there is no description file or main field.", + "description": "Clear all items provided in 'resolve.mainFiles' configuration. Filenames used to find the default entry point if there is no description file or main field.", "multiple": false, "simpleType": "boolean", }, @@ -6282,13 +8434,13 @@ Object { "resolve-modules-reset": Object { "configs": Array [ Object { - "description": "Clear all items provided in configuration. Folder names or directory paths where to find modules.", + "description": "Clear all items provided in 'resolve.modules' configuration. Folder names or directory paths where to find modules.", "multiple": false, "path": "resolve.modules", "type": "reset", }, ], - "description": "Clear all items provided in configuration. Folder names or directory paths where to find modules.", + "description": "Clear all items provided in 'resolve.modules' configuration. Folder names or directory paths where to find modules.", "multiple": false, "simpleType": "boolean", }, @@ -6340,13 +8492,13 @@ Object { "resolve-restrictions-reset": Object { "configs": Array [ Object { - "description": "Clear all items provided in configuration. A list of resolve restrictions. Resolve results must fulfill all of these restrictions to resolve successfully. Other resolve paths are taken when restrictions are not met.", + "description": "Clear all items provided in 'resolve.restrictions' configuration. A list of resolve restrictions. Resolve results must fulfill all of these restrictions to resolve successfully. Other resolve paths are taken when restrictions are not met.", "multiple": false, "path": "resolve.restrictions", "type": "reset", }, ], - "description": "Clear all items provided in configuration. A list of resolve restrictions. Resolve results must fulfill all of these restrictions to resolve successfully. Other resolve paths are taken when restrictions are not met.", + "description": "Clear all items provided in 'resolve.restrictions' configuration. A list of resolve restrictions. Resolve results must fulfill all of these restrictions to resolve successfully. Other resolve paths are taken when restrictions are not met.", "multiple": false, "simpleType": "boolean", }, @@ -6366,13 +8518,13 @@ Object { "resolve-roots-reset": Object { "configs": Array [ Object { - "description": "Clear all items provided in configuration. A list of directories in which requests that are server-relative URLs (starting with '/') are resolved.", + "description": "Clear all items provided in 'resolve.roots' configuration. A list of directories in which requests that are server-relative URLs (starting with '/') are resolved.", "multiple": false, "path": "resolve.roots", "type": "reset", }, ], - "description": "Clear all items provided in configuration. A list of directories in which requests that are server-relative URLs (starting with '/') are resolved.", + "description": "Clear all items provided in 'resolve.roots' configuration. A list of directories in which requests that are server-relative URLs (starting with '/') are resolved.", "multiple": false, "simpleType": "boolean", }, @@ -6444,31 +8596,43 @@ Object { "snapshot-immutable-paths": Object { "configs": Array [ Object { - "description": "A path to a immutable directory (usually a package manager cache directory).", + "description": "A RegExp matching an immutable directory (usually a package manager cache directory, including the tailing slash)", + "multiple": true, + "path": "snapshot.immutablePaths[]", + "type": "RegExp", + }, + Object { + "description": "A path to an immutable directory (usually a package manager cache directory).", "multiple": true, "path": "snapshot.immutablePaths[]", "type": "path", }, ], - "description": "A path to a immutable directory (usually a package manager cache directory).", + "description": "A RegExp matching an immutable directory (usually a package manager cache directory, including the tailing slash) A path to an immutable directory (usually a package manager cache directory).", "multiple": true, "simpleType": "string", }, "snapshot-immutable-paths-reset": Object { "configs": Array [ Object { - "description": "Clear all items provided in configuration. List of paths that are managed by a package manager and contain a version or hash in its path so all files are immutable.", + "description": "Clear all items provided in 'snapshot.immutablePaths' configuration. List of paths that are managed by a package manager and contain a version or hash in its path so all files are immutable.", "multiple": false, "path": "snapshot.immutablePaths", "type": "reset", }, ], - "description": "Clear all items provided in configuration. List of paths that are managed by a package manager and contain a version or hash in its path so all files are immutable.", + "description": "Clear all items provided in 'snapshot.immutablePaths' configuration. List of paths that are managed by a package manager and contain a version or hash in its path so all files are immutable.", "multiple": false, "simpleType": "boolean", }, "snapshot-managed-paths": Object { "configs": Array [ + Object { + "description": "A RegExp matching a managed directory (usually a node_modules directory, including the tailing slash)", + "multiple": true, + "path": "snapshot.managedPaths[]", + "type": "RegExp", + }, Object { "description": "A path to a managed directory (usually a node_modules directory).", "multiple": true, @@ -6476,20 +8640,20 @@ Object { "type": "path", }, ], - "description": "A path to a managed directory (usually a node_modules directory).", + "description": "A RegExp matching a managed directory (usually a node_modules directory, including the tailing slash) A path to a managed directory (usually a node_modules directory).", "multiple": true, "simpleType": "string", }, "snapshot-managed-paths-reset": Object { "configs": Array [ Object { - "description": "Clear all items provided in configuration. List of paths that are managed by a package manager and can be trusted to not be modified otherwise.", + "description": "Clear all items provided in 'snapshot.managedPaths' configuration. List of paths that are managed by a package manager and can be trusted to not be modified otherwise.", "multiple": false, "path": "snapshot.managedPaths", "type": "reset", }, ], - "description": "Clear all items provided in configuration. List of paths that are managed by a package manager and can be trusted to not be modified otherwise.", + "description": "Clear all items provided in 'snapshot.managedPaths' configuration. List of paths that are managed by a package manager and can be trusted to not be modified otherwise.", "multiple": false, "simpleType": "boolean", }, @@ -6571,6 +8735,38 @@ Object { "multiple": false, "simpleType": "boolean", }, + "snapshot-unmanaged-paths": Object { + "configs": Array [ + Object { + "description": "A RegExp matching an unmanaged directory.", + "multiple": true, + "path": "snapshot.unmanagedPaths[]", + "type": "RegExp", + }, + Object { + "description": "A path to an unmanaged directory.", + "multiple": true, + "path": "snapshot.unmanagedPaths[]", + "type": "path", + }, + ], + "description": "A RegExp matching an unmanaged directory. A path to an unmanaged directory.", + "multiple": true, + "simpleType": "string", + }, + "snapshot-unmanaged-paths-reset": Object { + "configs": Array [ + Object { + "description": "Clear all items provided in 'snapshot.unmanagedPaths' configuration. List of paths that are not managed by a package manager and the contents are subject to change.", + "multiple": false, + "path": "snapshot.unmanagedPaths", + "type": "reset", + }, + ], + "description": "Clear all items provided in 'snapshot.unmanagedPaths' configuration. List of paths that are not managed by a package manager and the contents are subject to change.", + "multiple": false, + "simpleType": "boolean", + }, "stats": Object { "configs": Array [ Object { @@ -7073,6 +9269,19 @@ Object { "multiple": false, "simpleType": "boolean", }, + "stats-errors-space": Object { + "configs": Array [ + Object { + "description": "Space to display errors (value is in number of lines).", + "multiple": false, + "path": "stats.errorsSpace", + "type": "number", + }, + ], + "description": "Space to display errors (value is in number of lines).", + "multiple": false, + "simpleType": "number", + }, "stats-exclude-assets": Object { "configs": Array [ Object { @@ -7095,13 +9304,13 @@ Object { "stats-exclude-assets-reset": Object { "configs": Array [ Object { - "description": "Clear all items provided in configuration. Suppress assets that match the specified filters. Filters can be Strings, RegExps or Functions.", + "description": "Clear all items provided in 'stats.excludeAssets' configuration. Suppress assets that match the specified filters. Filters can be Strings, RegExps or Functions.", "multiple": false, "path": "stats.excludeAssets", "type": "reset", }, ], - "description": "Clear all items provided in configuration. Suppress assets that match the specified filters. Filters can be Strings, RegExps or Functions.", + "description": "Clear all items provided in 'stats.excludeAssets' configuration. Suppress assets that match the specified filters. Filters can be Strings, RegExps or Functions.", "multiple": false, "simpleType": "boolean", }, @@ -7133,13 +9342,13 @@ Object { "stats-exclude-modules-reset": Object { "configs": Array [ Object { - "description": "Clear all items provided in configuration. Suppress modules that match the specified filters. Filters can be Strings, RegExps, Booleans or Functions.", + "description": "Clear all items provided in 'stats.excludeModules' configuration. Suppress modules that match the specified filters. Filters can be Strings, RegExps, Booleans or Functions.", "multiple": false, "path": "stats.excludeModules", "type": "reset", }, ], - "description": "Clear all items provided in configuration. Suppress modules that match the specified filters. Filters can be Strings, RegExps, Booleans or Functions.", + "description": "Clear all items provided in 'stats.excludeModules' configuration. Suppress modules that match the specified filters. Filters can be Strings, RegExps, Booleans or Functions.", "multiple": false, "simpleType": "boolean", }, @@ -7273,6 +9482,32 @@ Object { "multiple": false, "simpleType": "boolean", }, + "stats-group-modules-by-type": Object { + "configs": Array [ + Object { + "description": "Group modules by their type.", + "multiple": false, + "path": "stats.groupModulesByType", + "type": "boolean", + }, + ], + "description": "Group modules by their type.", + "multiple": false, + "simpleType": "boolean", + }, + "stats-group-reasons-by-origin": Object { + "configs": Array [ + Object { + "description": "Group reasons by their origin module.", + "multiple": false, + "path": "stats.groupReasonsByOrigin", + "type": "boolean", + }, + ], + "description": "Group reasons by their origin module.", + "multiple": false, + "simpleType": "boolean", + }, "stats-hash": Object { "configs": Array [ Object { @@ -7354,13 +9589,13 @@ Object { "stats-logging-debug-reset": Object { "configs": Array [ Object { - "description": "Clear all items provided in configuration. Include debug logging of specified loggers (i. e. for plugins or loaders). Filters can be Strings, RegExps or Functions.", + "description": "Clear all items provided in 'stats.loggingDebug' configuration. Include debug logging of specified loggers (i. e. for plugins or loaders). Filters can be Strings, RegExps or Functions.", "multiple": false, "path": "stats.loggingDebug", "type": "reset", }, ], - "description": "Clear all items provided in configuration. Include debug logging of specified loggers (i. e. for plugins or loaders). Filters can be Strings, RegExps or Functions.", + "description": "Clear all items provided in 'stats.loggingDebug' configuration. Include debug logging of specified loggers (i. e. for plugins or loaders). Filters can be Strings, RegExps or Functions.", "multiple": false, "simpleType": "boolean", }, @@ -7578,6 +9813,19 @@ Object { "multiple": false, "simpleType": "boolean", }, + "stats-reasons-space": Object { + "configs": Array [ + Object { + "description": "Space to display reasons (groups will be collapsed to fit this space).", + "multiple": false, + "path": "stats.reasonsSpace", + "type": "number", + }, + ], + "description": "Space to display reasons (groups will be collapsed to fit this space).", + "multiple": false, + "simpleType": "number", + }, "stats-related-assets": Object { "configs": Array [ Object { @@ -7717,16 +9965,29 @@ Object { "stats-warnings-filter-reset": Object { "configs": Array [ Object { - "description": "Clear all items provided in configuration. Suppress listing warnings that match the specified filters (they will still be counted). Filters can be Strings, RegExps or Functions.", + "description": "Clear all items provided in 'stats.warningsFilter' configuration. Suppress listing warnings that match the specified filters (they will still be counted). Filters can be Strings, RegExps or Functions.", "multiple": false, "path": "stats.warningsFilter", "type": "reset", }, ], - "description": "Clear all items provided in configuration. Suppress listing warnings that match the specified filters (they will still be counted). Filters can be Strings, RegExps or Functions.", + "description": "Clear all items provided in 'stats.warningsFilter' configuration. Suppress listing warnings that match the specified filters (they will still be counted). Filters can be Strings, RegExps or Functions.", "multiple": false, "simpleType": "boolean", }, + "stats-warnings-space": Object { + "configs": Array [ + Object { + "description": "Space to display warnings (value is in number of lines).", + "multiple": false, + "path": "stats.warningsSpace", + "type": "number", + }, + ], + "description": "Space to display warnings (value is in number of lines).", + "multiple": false, + "simpleType": "number", + }, "target": Object { "configs": Array [ Object { @@ -7752,13 +10013,13 @@ Object { "target-reset": Object { "configs": Array [ Object { - "description": "Clear all items provided in configuration. Environment to build for. An array of environments to build for all of them when possible.", + "description": "Clear all items provided in 'target' configuration. Environment to build for. An array of environments to build for all of them when possible.", "multiple": false, "path": "target", "type": "reset", }, ], - "description": "Clear all items provided in configuration. Environment to build for. An array of environments to build for all of them when possible.", + "description": "Clear all items provided in 'target' configuration. Environment to build for. An array of environments to build for all of them when possible.", "multiple": false, "simpleType": "boolean", }, @@ -7823,13 +10084,13 @@ Object { "watch-options-ignored-reset": Object { "configs": Array [ Object { - "description": "Clear all items provided in configuration. Ignore some files from watching (glob pattern or regexp).", + "description": "Clear all items provided in 'watchOptions.ignored' configuration. Ignore some files from watching (glob pattern or regexp).", "multiple": false, "path": "watchOptions.ignored", "type": "reset", }, ], - "description": "Clear all items provided in configuration. Ignore some files from watching (glob pattern or regexp).", + "description": "Clear all items provided in 'watchOptions.ignored' configuration. Ignore some files from watching (glob pattern or regexp).", "multiple": false, "simpleType": "boolean", }, @@ -7867,3 +10128,75 @@ Object { }, } `; + +exports[`Cli should generate the correct cli flags with custom schema 1`] = ` +Object { + "with-both-cli-and-negative-description": Object { + "configs": Array [ + Object { + "description": "description for CLI option", + "multiple": false, + "negatedDescription": "custom negative description", + "path": "with-both-cli-and-negative-description", + "type": "boolean", + }, + ], + "description": "description for CLI option", + "multiple": false, + "simpleType": "boolean", + }, + "with-cli-description": Object { + "configs": Array [ + Object { + "description": "description for CLI option", + "multiple": false, + "path": "with-cli-description", + "type": "string", + }, + ], + "description": "description for CLI option", + "multiple": false, + "simpleType": "string", + }, + "with-negative-description": Object { + "configs": Array [ + Object { + "description": "original description", + "multiple": false, + "negatedDescription": "custom negative description", + "path": "with-negative-description", + "type": "boolean", + }, + ], + "description": "original description", + "multiple": false, + "simpleType": "boolean", + }, + "with-reset-description": Object { + "configs": Array [ + Object { + "description": "original description", + "multiple": true, + "path": "with-reset-description[]", + "type": "string", + }, + ], + "description": "original description", + "multiple": true, + "simpleType": "string", + }, + "with-reset-description-reset": Object { + "configs": Array [ + Object { + "description": "custom reset", + "multiple": false, + "path": "with-reset-description", + "type": "reset", + }, + ], + "description": "custom reset", + "multiple": false, + "simpleType": "boolean", + }, +} +`; diff --git a/test/__snapshots__/ConfigCacheTestCases.longtest.js.snap b/test/__snapshots__/ConfigCacheTestCases.longtest.js.snap new file mode 100644 index 00000000000..1c924ae8834 --- /dev/null +++ b/test/__snapshots__/ConfigCacheTestCases.longtest.js.snap @@ -0,0 +1,4928 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`ConfigCacheTestCases css css-import exported tests should compile 1`] = ` +Array [ + "/*!**********************************************************************************************!*\\\\ + !*** external \\"https://test.cases/path/../../../../configCases/css/css-import/external.css\\" ***! + \\\\**********************************************************************************************/ +body { + externally-imported: true; +} + +/*!******************************************!*\\\\ + !*** external \\"//example.com/style.css\\" ***! + \\\\******************************************/ +@import url(\\"//example.com/style.css\\"); +/*!*****************************************************************!*\\\\ + !*** external \\"https://fonts.googleapis.com/css?family=Roboto\\" ***! + \\\\*****************************************************************/ +@import url(\\"https://fonts.googleapis.com/css?family=Roboto\\"); +/*!***********************************************************************!*\\\\ + !*** external \\"https://fonts.googleapis.com/css?family=Noto+Sans+TC\\" ***! + \\\\***********************************************************************/ +@import url(\\"https://fonts.googleapis.com/css?family=Noto+Sans+TC\\"); +/*!******************************************************************************!*\\\\ + !*** external \\"https://fonts.googleapis.com/css?family=Noto+Sans+TC|Roboto\\" ***! + \\\\******************************************************************************/ +@import url(\\"https://fonts.googleapis.com/css?family=Noto+Sans+TC|Roboto\\"); +/*!************************************************************************************!*\\\\ + !*** external \\"https://fonts.googleapis.com/css?family=Noto+Sans+TC|Roboto?foo=1\\" ***! + \\\\************************************************************************************/ +@import url(\\"https://fonts.googleapis.com/css?family=Noto+Sans+TC|Roboto?foo=1\\") layer(super.foo) supports(display: flex) screen and (min-width: 400px); +/*!***********************************************************************************************!*\\\\ + !*** external \\"https://test.cases/path/../../../../configCases/css/css-import/external1.css\\" ***! + \\\\***********************************************************************************************/ +body { + externally-imported1: true; +} + +/*!***********************************************************************************************!*\\\\ + !*** external \\"https://test.cases/path/../../../../configCases/css/css-import/external2.css\\" ***! + \\\\***********************************************************************************************/ +body { + externally-imported2: true; +} + +/*!*********************************!*\\\\ + !*** external \\"external-1.css\\" ***! + \\\\*********************************/ +@import url(\\"external-1.css\\"); +/*!*********************************!*\\\\ + !*** external \\"external-2.css\\" ***! + \\\\*********************************/ +@import url(\\"external-2.css\\") supports(display: grid) screen and (max-width: 400px); +/*!*********************************!*\\\\ + !*** external \\"external-3.css\\" ***! + \\\\*********************************/ +@import url(\\"external-3.css\\") supports(not (display: grid) and (display: flex)) screen and (max-width: 400px); +/*!*********************************!*\\\\ + !*** external \\"external-4.css\\" ***! + \\\\*********************************/ +@import url(\\"external-4.css\\") supports((selector(h2 > p)) and + (font-tech(color-COLRv1))); +/*!*********************************!*\\\\ + !*** external \\"external-5.css\\" ***! + \\\\*********************************/ +@import url(\\"external-5.css\\") layer(default); +/*!*********************************!*\\\\ + !*** external \\"external-6.css\\" ***! + \\\\*********************************/ +@import url(\\"external-6.css\\") layer(default); +/*!*********************************!*\\\\ + !*** external \\"external-7.css\\" ***! + \\\\*********************************/ +@import url(\\"external-7.css\\") layer(); +/*!*********************************!*\\\\ + !*** external \\"external-8.css\\" ***! + \\\\*********************************/ +@import url(\\"external-8.css\\") layer(); +/*!*********************************!*\\\\ + !*** external \\"external-9.css\\" ***! + \\\\*********************************/ +@import url(\\"external-9.css\\") print; +/*!**********************************!*\\\\ + !*** external \\"external-10.css\\" ***! + \\\\**********************************/ +@import url(\\"external-10.css\\") print, screen; +/*!**********************************!*\\\\ + !*** external \\"external-11.css\\" ***! + \\\\**********************************/ +@import url(\\"external-11.css\\") screen; +/*!**********************************!*\\\\ + !*** external \\"external-12.css\\" ***! + \\\\**********************************/ +@import url(\\"external-12.css\\") screen and (orientation: landscape); +/*!**********************************!*\\\\ + !*** external \\"external-13.css\\" ***! + \\\\**********************************/ +@import url(\\"external-13.css\\") supports(not (display: flex)); +/*!**********************************!*\\\\ + !*** external \\"external-14.css\\" ***! + \\\\**********************************/ +@import url(\\"external-14.css\\") layer(default) supports(display: grid) screen and (max-width: 400px); +/*!***************************************************!*\\\\ + !*** css ./node_modules/style-library/styles.css ***! + \\\\***************************************************/ +p { + color: steelblue; +} + +/*!************************************************!*\\\\ + !*** css ./node_modules/main-field/styles.css ***! + \\\\************************************************/ +p { + color: antiquewhite; +} + +/*!*********************************************************!*\\\\ + !*** css ./node_modules/package-with-exports/style.css ***! + \\\\*********************************************************/ +.load-me { + color: red; +} + +/*!***************************************!*\\\\ + !*** css ./extensions-imported.mycss ***! + \\\\***************************************/ +.custom-extension{ + color: green; +}.using-loader { color: red; } +/*!***********************!*\\\\ + !*** css ./file.less ***! + \\\\***********************/ +.link { + color: #428bca; +} + +/*!**********************************!*\\\\ + !*** css ./with-less-import.css ***! + \\\\**********************************/ + +.foo { + color: red; +} + +/*!*********************************!*\\\\ + !*** css ./prefer-relative.css ***! + \\\\*********************************/ +.relative { + color: red; +} + +/*!************************************************************!*\\\\ + !*** css ./node_modules/condition-names-style/default.css ***! + \\\\************************************************************/ +.default { + color: steelblue; +} + +/*!**************************************************************!*\\\\ + !*** css ./node_modules/condition-names-style-mode/mode.css ***! + \\\\**************************************************************/ +.mode { + color: red; +} + +/*!******************************************************************!*\\\\ + !*** css ./node_modules/condition-names-subpath/dist/custom.css ***! + \\\\******************************************************************/ +.dist { + color: steelblue; +} + +/*!************************************************************************!*\\\\ + !*** css ./node_modules/condition-names-subpath-extra/dist/custom.css ***! + \\\\************************************************************************/ +.dist { + color: steelblue; +} + +/*!******************************************************************!*\\\\ + !*** css ./node_modules/condition-names-style-less/default.less ***! + \\\\******************************************************************/ +.conditional-names { + color: #428bca; +} + +/*!**********************************************************************!*\\\\ + !*** css ./node_modules/condition-names-custom-name/custom-name.css ***! + \\\\**********************************************************************/ +.custom-name { + color: steelblue; +} + +/*!************************************************************!*\\\\ + !*** css ./node_modules/style-and-main-library/styles.css ***! + \\\\************************************************************/ +.style { + color: steelblue; +} + +/*!**************************************************************!*\\\\ + !*** css ./node_modules/condition-names-webpack/webpack.css ***! + \\\\**************************************************************/ +.webpack { + color: steelblue; +} + +/*!*******************************************************************!*\\\\ + !*** css ./node_modules/condition-names-style-nested/default.css ***! + \\\\*******************************************************************/ +.default { + color: steelblue; +} + +/*!******************************!*\\\\ + !*** css ./style-import.css ***! + \\\\******************************/ + +/* Technically, this is not entirely true, but we allow it because the final file can be processed by the loader and return the CSS code */ + + +/* Failed */ + + +/*!*****************************!*\\\\ + !*** css ./print.css?foo=1 ***! + \\\\*****************************/ +body { + background: black; +} + +/*!*****************************!*\\\\ + !*** css ./print.css?foo=2 ***! + \\\\*****************************/ +body { + background: black; +} + +/*!**********************************************!*\\\\ + !*** css ./print.css?foo=3 (layer: default) ***! + \\\\**********************************************/ +@layer default { + body { + background: black; + } +} + +/*!**********************************************!*\\\\ + !*** css ./print.css?foo=4 (layer: default) ***! + \\\\**********************************************/ +@layer default { + body { + background: black; + } +} + +/*!*******************************************************!*\\\\ + !*** css ./print.css?foo=5 (supports: display: flex) ***! + \\\\*******************************************************/ +@supports (display: flex) { + body { + background: black; + } +} + +/*!*******************************************************!*\\\\ + !*** css ./print.css?foo=6 (supports: display: flex) ***! + \\\\*******************************************************/ +@supports (display: flex) { + body { + background: black; + } +} + +/*!********************************************************************!*\\\\ + !*** css ./print.css?foo=7 (media: screen and (min-width: 400px)) ***! + \\\\********************************************************************/ +@media screen and (min-width: 400px) { + body { + background: black; + } +} + +/*!********************************************************************!*\\\\ + !*** css ./print.css?foo=8 (media: screen and (min-width: 400px)) ***! + \\\\********************************************************************/ +@media screen and (min-width: 400px) { + body { + background: black; + } +} + +/*!************************************************************************!*\\\\ + !*** css ./print.css?foo=9 (layer: default) (supports: display: flex) ***! + \\\\************************************************************************/ +@layer default { + @supports (display: flex) { + body { + background: black; + } + } +} + +/*!**************************************************************************************!*\\\\ + !*** css ./print.css?foo=10 (layer: default) (media: screen and (min-width: 400px)) ***! + \\\\**************************************************************************************/ +@layer default { + @media screen and (min-width: 400px) { + body { + background: black; + } + } +} + +/*!***********************************************************************************************!*\\\\ + !*** css ./print.css?foo=11 (supports: display: flex) (media: screen and (min-width: 400px)) ***! + \\\\***********************************************************************************************/ +@supports (display: flex) { + @media screen and (min-width: 400px) { + body { + background: black; + } + } +} + +/*!****************************************************************************************************************!*\\\\ + !*** css ./print.css?foo=12 (layer: default) (supports: display: flex) (media: screen and (min-width: 400px)) ***! + \\\\****************************************************************************************************************/ +@layer default { + @supports (display: flex) { + @media screen and (min-width: 400px) { + body { + background: black; + } + } + } +} + +/*!****************************************************************************************************************!*\\\\ + !*** css ./print.css?foo=13 (layer: default) (supports: display: flex) (media: screen and (min-width: 400px)) ***! + \\\\****************************************************************************************************************/ +@layer default { + @supports (display: flex) { + @media screen and (min-width: 400px) { + body { + background: black; + } + } + } +} + +/*!****************************************************************************************************************!*\\\\ + !*** css ./print.css?foo=14 (layer: default) (supports: display: flex) (media: screen and (min-width: 400px)) ***! + \\\\****************************************************************************************************************/ +@layer default { + @supports (display: flex) { + @media screen and (min-width: 400px) { + body { + background: black; + } + } + } +} + +/*!****************************************************************************************************************!*\\\\ + !*** css ./print.css?foo=15 (layer: default) (supports: display: flex) (media: screen and (min-width: 400px)) ***! + \\\\****************************************************************************************************************/ +@layer default { + @supports (display: flex) { + @media screen and (min-width: 400px) { + body { + background: black; + } + } + } +} + +/*!*****************************************************************************************************************************!*\\\\ + !*** css ./print.css?foo=16 (layer: default) (supports: background: url(./img.png)) (media: screen and (min-width: 400px)) ***! + \\\\*****************************************************************************************************************************/ +@layer default { + @supports (background: url(./img.png)) { + @media screen and (min-width: 400px) { + body { + background: black; + } + } + } +} + +/*!*******************************************************************************************************************************!*\\\\ + !*** css ./print.css?foo=17 (layer: default) (supports: background: url(\\"./img.png\\")) (media: screen and (min-width: 400px)) ***! + \\\\*******************************************************************************************************************************/ +@layer default { + @supports (background: url(\\"./img.png\\")) { + @media screen and (min-width: 400px) { + body { + background: black; + } + } + } +} + +/*!**********************************************!*\\\\ + !*** css ./print.css?foo=18 (media: screen) ***! + \\\\**********************************************/ +@media screen { + body { + background: black; + } +} + +/*!**********************************************!*\\\\ + !*** css ./print.css?foo=19 (media: screen) ***! + \\\\**********************************************/ +@media screen { + body { + background: black; + } +} + +/*!**********************************************!*\\\\ + !*** css ./print.css?foo=20 (media: screen) ***! + \\\\**********************************************/ +@media screen { + body { + background: black; + } +} + +/*!******************************!*\\\\ + !*** css ./print.css?foo=21 ***! + \\\\******************************/ +body { + background: black; +} + +/*!**************************!*\\\\ + !*** css ./imported.css ***! + \\\\**************************/ +body { + background: green; +} + +/*!****************************************!*\\\\ + !*** css ./imported.css (layer: base) ***! + \\\\****************************************/ +@layer base { + body { + background: green; + } +} + +/*!****************************************************!*\\\\ + !*** css ./imported.css (supports: display: flex) ***! + \\\\****************************************************/ +@supports (display: flex) { + body { + background: green; + } +} + +/*!*************************************************!*\\\\ + !*** css ./imported.css (media: screen, print) ***! + \\\\*************************************************/ +@media screen, print { + body { + background: green; + } +} + +/*!******************************!*\\\\ + !*** css ./style2.css?foo=1 ***! + \\\\******************************/ +a { + color: red; +} + +/*!******************************!*\\\\ + !*** css ./style2.css?foo=2 ***! + \\\\******************************/ +a { + color: red; +} + +/*!******************************!*\\\\ + !*** css ./style2.css?foo=3 ***! + \\\\******************************/ +a { + color: red; +} + +/*!******************************!*\\\\ + !*** css ./style2.css?foo=4 ***! + \\\\******************************/ +a { + color: red; +} + +/*!******************************!*\\\\ + !*** css ./style2.css?foo=5 ***! + \\\\******************************/ +a { + color: red; +} + +/*!******************************!*\\\\ + !*** css ./style2.css?foo=6 ***! + \\\\******************************/ +a { + color: red; +} + +/*!******************************!*\\\\ + !*** css ./style2.css?foo=7 ***! + \\\\******************************/ +a { + color: red; +} + +/*!******************************!*\\\\ + !*** css ./style2.css?foo=8 ***! + \\\\******************************/ +a { + color: red; +} + +/*!******************************!*\\\\ + !*** css ./style2.css?foo=9 ***! + \\\\******************************/ +a { + color: red; +} + +/*!********************************************************************!*\\\\ + !*** css ./style2.css (media: screen and (orientation:landscape)) ***! + \\\\********************************************************************/ +@media screen and (orientation:landscape) { + a { + color: red; + } +} + +/*!*********************************************************************!*\\\\ + !*** css ./style2.css (media: SCREEN AND (ORIENTATION: LANDSCAPE)) ***! + \\\\*********************************************************************/ +@media SCREEN AND (ORIENTATION: LANDSCAPE) { + a { + color: red; + } +} + +/*!****************************************************!*\\\\ + !*** css ./style2.css (media: (min-width: 100px)) ***! + \\\\****************************************************/ +@media (min-width: 100px) { + a { + color: red; + } +} + +/*!**********************************!*\\\\ + !*** css ./test.css?foo=1&bar=1 ***! + \\\\**********************************/ +.class { + content: \\"test.css\\"; +} + +/*!*****************************************!*\\\\ + !*** css ./style2.css?foo=1&bar=1#hash ***! + \\\\*****************************************/ +a { + color: red; +} + +/*!*************************************************************************************!*\\\\ + !*** css ./style2.css?foo=1&bar=1#hash (media: screen and (orientation:landscape)) ***! + \\\\*************************************************************************************/ +@media screen and (orientation:landscape) { + a { + color: red; + } +} + +/*!******************************!*\\\\ + !*** css ./style3.css?bar=1 ***! + \\\\******************************/ +.class { + content: \\"style.css\\"; + color: red; +} + +/*!******************************!*\\\\ + !*** css ./style3.css?bar=2 ***! + \\\\******************************/ +.class { + content: \\"style.css\\"; + color: red; +} + +/*!******************************!*\\\\ + !*** css ./style3.css?bar=3 ***! + \\\\******************************/ +.class { + content: \\"style.css\\"; + color: red; +} + +/*!******************************!*\\\\ + !*** css ./style3.css?=bar4 ***! + \\\\******************************/ +.class { + content: \\"style.css\\"; + color: red; +} + +/*!**************************!*\\\\ + !*** css ./styl'le7.css ***! + \\\\**************************/ +.class { + content: \\"style7.css\\"; +} + +/*!********************************!*\\\\ + !*** css ./styl'le7.css?foo=1 ***! + \\\\********************************/ +.class { + content: \\"style7.css\\"; +} + +/*!***************************!*\\\\ + !*** css ./test test.css ***! + \\\\***************************/ +.class { + content: \\"test test.css\\"; +} + +/*!*********************************!*\\\\ + !*** css ./test test.css?foo=1 ***! + \\\\*********************************/ +.class { + content: \\"test test.css\\"; +} + +/*!*********************************!*\\\\ + !*** css ./test test.css?foo=2 ***! + \\\\*********************************/ +.class { + content: \\"test test.css\\"; +} + +/*!*********************************!*\\\\ + !*** css ./test test.css?foo=3 ***! + \\\\*********************************/ +.class { + content: \\"test test.css\\"; +} + +/*!*********************************!*\\\\ + !*** css ./test test.css?foo=4 ***! + \\\\*********************************/ +.class { + content: \\"test test.css\\"; +} + +/*!*********************************!*\\\\ + !*** css ./test test.css?foo=5 ***! + \\\\*********************************/ +.class { + content: \\"test test.css\\"; +} + +/*!**********************!*\\\\ + !*** css ./test.css ***! + \\\\**********************/ +.class { + content: \\"test.css\\"; +} + +/*!****************************!*\\\\ + !*** css ./test.css?foo=1 ***! + \\\\****************************/ +.class { + content: \\"test.css\\"; +} + +/*!****************************!*\\\\ + !*** css ./test.css?foo=2 ***! + \\\\****************************/ +.class { + content: \\"test.css\\"; +} + +/*!****************************!*\\\\ + !*** css ./test.css?foo=3 ***! + \\\\****************************/ +.class { + content: \\"test.css\\"; +} + +/*!*********************************!*\\\\ + !*** css ./test test.css?foo=6 ***! + \\\\*********************************/ +.class { + content: \\"test test.css\\"; +} + +/*!*********************************!*\\\\ + !*** css ./test test.css?foo=7 ***! + \\\\*********************************/ +.class { + content: \\"test test.css\\"; +} + +/*!*********************************!*\\\\ + !*** css ./test test.css?foo=8 ***! + \\\\*********************************/ +.class { + content: \\"test test.css\\"; +} + +/*!*********************************!*\\\\ + !*** css ./test test.css?foo=9 ***! + \\\\*********************************/ +.class { + content: \\"test test.css\\"; +} + +/*!**********************************!*\\\\ + !*** css ./test test.css?fpp=10 ***! + \\\\**********************************/ +.class { + content: \\"test test.css\\"; +} + +/*!**********************************!*\\\\ + !*** css ./test test.css?foo=11 ***! + \\\\**********************************/ +.class { + content: \\"test test.css\\"; +} + +/*!*********************************!*\\\\ + !*** css ./style6.css?foo=bazz ***! + \\\\*********************************/ +.class { + content: \\"style6.css\\"; +} + +/*!********************************************************!*\\\\ + !*** css ./string-loader.js?esModule=false!./test.css ***! + \\\\********************************************************/ +.class { + content: \\"test.css\\"; +} +.using-loader { color: red; } +/*!********************************!*\\\\ + !*** css ./style4.css?foo=bar ***! + \\\\********************************/ +.class { + content: \\"style4.css\\"; +} + +/*!*************************************!*\\\\ + !*** css ./style4.css?foo=bar#hash ***! + \\\\*************************************/ +.class { + content: \\"style4.css\\"; +} + +/*!******************************!*\\\\ + !*** css ./style4.css?#hash ***! + \\\\******************************/ +.class { + content: \\"style4.css\\"; +} + +/*!********************************************************!*\\\\ + !*** css ./style4.css?foo=1 (supports: display: flex) ***! + \\\\********************************************************/ +@supports (display: flex) { + .class { + content: \\"style4.css\\"; + } +} + +/*!****************************************************************************************************!*\\\\ + !*** css ./style4.css?foo=2 (supports: display: flex) (media: screen and (orientation:landscape)) ***! + \\\\****************************************************************************************************/ +@supports (display: flex) { + @media screen and (orientation:landscape) { + .class { + content: \\"style4.css\\"; + } + } +} + +/*!******************************!*\\\\ + !*** css ./style4.css?foo=3 ***! + \\\\******************************/ +.class { + content: \\"style4.css\\"; +} + +/*!******************************!*\\\\ + !*** css ./style4.css?foo=4 ***! + \\\\******************************/ +.class { + content: \\"style4.css\\"; +} + +/*!******************************!*\\\\ + !*** css ./style4.css?foo=5 ***! + \\\\******************************/ +.class { + content: \\"style4.css\\"; +} + +/*!*****************************************************************************************************!*\\\\ + !*** css ./string-loader.js?esModule=false!./test.css (media: screen and (orientation: landscape)) ***! + \\\\*****************************************************************************************************/ +@media screen and (orientation: landscape) { + .class { + content: \\"test.css\\"; + } + .using-loader { color: red; }} + +/*!*************************************************************************************!*\\\\ + !*** css data:text/css;charset=utf-8,a%20%7B%0D%0A%20%20color%3A%20red%3B%0D%0A%7D ***! + \\\\*************************************************************************************/ +a { + color: red; +} +/*!**********************************************************************************************************************************!*\\\\ + !*** css data:text/css;charset=utf-8,a%20%7B%0D%0A%20%20color%3A%20blue%3B%0D%0A%7D (media: screen and (orientation:landscape)) ***! + \\\\**********************************************************************************************************************************/ +@media screen and (orientation:landscape) { + a { + color: blue; + }} + +/*!***************************************************************************!*\\\\ + !*** css data:text/css;charset=utf-8;base64,YSB7DQogIGNvbG9yOiByZWQ7DQp9 ***! + \\\\***************************************************************************/ +a { + color: red; +} +/*!******************************!*\\\\ + !*** css ./style5.css?foo=1 ***! + \\\\******************************/ +.class { + content: \\"style5.css\\"; +} + +/*!******************************!*\\\\ + !*** css ./style5.css?foo=2 ***! + \\\\******************************/ +.class { + content: \\"style5.css\\"; +} + +/*!**************************************************!*\\\\ + !*** css ./style5.css?foo=3 (supports: unknown) ***! + \\\\**************************************************/ +@supports (unknown) { + .class { + content: \\"style5.css\\"; + } +} + +/*!********************************************************!*\\\\ + !*** css ./style5.css?foo=4 (supports: display: flex) ***! + \\\\********************************************************/ +@supports (display: flex) { + .class { + content: \\"style5.css\\"; + } +} + +/*!*******************************************************************!*\\\\ + !*** css ./style5.css?foo=5 (supports: display: flex !important) ***! + \\\\*******************************************************************/ +@supports (display: flex !important) { + .class { + content: \\"style5.css\\"; + } +} + +/*!***********************************************************************************************!*\\\\ + !*** css ./style5.css?foo=6 (supports: display: flex) (media: screen and (min-width: 400px)) ***! + \\\\***********************************************************************************************/ +@supports (display: flex) { + @media screen and (min-width: 400px) { + .class { + content: \\"style5.css\\"; + } + } +} + +/*!********************************************************!*\\\\ + !*** css ./style5.css?foo=7 (supports: selector(a b)) ***! + \\\\********************************************************/ +@supports (selector(a b)) { + .class { + content: \\"style5.css\\"; + } +} + +/*!********************************************************!*\\\\ + !*** css ./style5.css?foo=8 (supports: display: flex) ***! + \\\\********************************************************/ +@supports (display: flex) { + .class { + content: \\"style5.css\\"; + } +} + +/*!*****************************!*\\\\ + !*** css ./layer.css?foo=1 ***! + \\\\*****************************/ +@layer { + .class { + content: \\"layer.css\\"; + } +} + +/*!**********************************************!*\\\\ + !*** css ./layer.css?foo=2 (layer: default) ***! + \\\\**********************************************/ +@layer default { + .class { + content: \\"layer.css\\"; + } +} + +/*!***************************************************************************************************************!*\\\\ + !*** css ./layer.css?foo=3 (layer: default) (supports: display: flex) (media: screen and (min-width: 400px)) ***! + \\\\***************************************************************************************************************/ +@layer default { + @supports (display: flex) { + @media screen and (min-width: 400px) { + .class { + content: \\"layer.css\\"; + } + } + } +} + +/*!**********************************************************************************************!*\\\\ + !*** css ./layer.css?foo=3 (supports: display: flex) (media: screen and (min-width: 400px)) ***! + \\\\**********************************************************************************************/ +@layer { + @supports (display: flex) { + @media screen and (min-width: 400px) { + .class { + content: \\"layer.css\\"; + } + } + } +} + +/*!**********************************************************************************************!*\\\\ + !*** css ./layer.css?foo=4 (supports: display: flex) (media: screen and (min-width: 400px)) ***! + \\\\**********************************************************************************************/ +@layer { + @supports (display: flex) { + @media screen and (min-width: 400px) { + .class { + content: \\"layer.css\\"; + } + } + } +} + +/*!*****************************!*\\\\ + !*** css ./layer.css?foo=5 ***! + \\\\*****************************/ +@layer { + .class { + content: \\"layer.css\\"; + } +} + +/*!**************************************************!*\\\\ + !*** css ./layer.css?foo=6 (layer: foo.bar.baz) ***! + \\\\**************************************************/ +@layer foo.bar.baz { + .class { + content: \\"layer.css\\"; + } +} + +/*!*****************************!*\\\\ + !*** css ./layer.css?foo=7 ***! + \\\\*****************************/ +@layer { + .class { + content: \\"layer.css\\"; + } +} + +/*!*********************************************************************************************************!*\\\\ + !*** css ./style6.css (layer: default) (supports: display: flex) (media: screen and (min-width:400px)) ***! + \\\\*********************************************************************************************************/ +@layer default { + @supports (display: flex) { + @media screen and (min-width:400px) { + .class { + content: \\"style6.css\\"; + } + } + } +} + +/*!***************************************************************************************************************!*\\\\ + !*** css ./style6.css?foo=1 (layer: default) (supports: display: flex) (media: screen and (min-width:400px)) ***! + \\\\***************************************************************************************************************/ +@layer default { + @supports (display: flex) { + @media screen and (min-width:400px) { + .class { + content: \\"style6.css\\"; + } + } + } +} + +/*!**********************************************************************************************!*\\\\ + !*** css ./style6.css?foo=2 (supports: display: flex) (media: screen and (min-width:400px)) ***! + \\\\**********************************************************************************************/ +@supports (display: flex) { + @media screen and (min-width:400px) { + .class { + content: \\"style6.css\\"; + } + } +} + +/*!********************************************************************!*\\\\ + !*** css ./style6.css?foo=3 (media: screen and (min-width:400px)) ***! + \\\\********************************************************************/ +@media screen and (min-width:400px) { + .class { + content: \\"style6.css\\"; + } +} + +/*!********************************************************************!*\\\\ + !*** css ./style6.css?foo=4 (media: screen and (min-width:400px)) ***! + \\\\********************************************************************/ +@media screen and (min-width:400px) { + .class { + content: \\"style6.css\\"; + } +} + +/*!********************************************************************!*\\\\ + !*** css ./style6.css?foo=5 (media: screen and (min-width:400px)) ***! + \\\\********************************************************************/ +@media screen and (min-width:400px) { + .class { + content: \\"style6.css\\"; + } +} + +/*!****************************************************************************************************************************************************!*\\\\ + !*** css ./style6.css?foo=6 (layer: default) (supports: display : flex) (media: screen and ( min-width : 400px )) ***! + \\\\****************************************************************************************************************************************************/ +@layer default { + @supports (display : flex) { + @media screen and ( min-width : 400px ) { + .class { + content: \\"style6.css\\"; + } + } + } +} + +/*!****************************************************************************************************************!*\\\\ + !*** css ./style6.css?foo=7 (layer: DEFAULT) (supports: DISPLAY: FLEX) (media: SCREEN AND (MIN-WIDTH: 400PX)) ***! + \\\\****************************************************************************************************************/ +@layer DEFAULT { + @supports (DISPLAY: FLEX) { + @media SCREEN AND (MIN-WIDTH: 400PX) { + .class { + content: \\"style6.css\\"; + } + } + } +} + +/*!***********************************************************************************************!*\\\\ + !*** css ./style6.css?foo=8 (supports: DISPLAY: FLEX) (media: SCREEN AND (MIN-WIDTH: 400PX)) ***! + \\\\***********************************************************************************************/ +@layer { + @supports (DISPLAY: FLEX) { + @media SCREEN AND (MIN-WIDTH: 400PX) { + .class { + content: \\"style6.css\\"; + } + } + } +} + +/*!*******************************************************************************************************************************************************************************************************************************************************************************************************!*\\\\ + !*** css ./style6.css?foo=9 (layer: /* Comment *_/default/* Comment *_/) (supports: /* Comment *_/display/* Comment *_/:/* Comment *_/ flex/* Comment *_/) (media: /* Comment *_/ screen/* Comment *_/ and/* Comment *_/ (/* Comment *_/min-width/* Comment *_/: /* Comment *_/400px/* Comment *_/)) ***! + \\\\*******************************************************************************************************************************************************************************************************************************************************************************************************/ +@layer /* Comment */default/* Comment */ { + @supports (/* Comment */display/* Comment */:/* Comment */ flex/* Comment */) { + @media /* Comment */ screen/* Comment */ and/* Comment */ (/* Comment */min-width/* Comment */: /* Comment */400px/* Comment */) { + .class { + content: \\"style6.css\\"; + } + } + } +} + +/*!*******************************!*\\\\ + !*** css ./style6.css?foo=10 ***! + \\\\*******************************/ +.class { + content: \\"style6.css\\"; +} + +/*!*******************************!*\\\\ + !*** css ./style6.css?foo=11 ***! + \\\\*******************************/ +.class { + content: \\"style6.css\\"; +} + +/*!*******************************!*\\\\ + !*** css ./style6.css?foo=12 ***! + \\\\*******************************/ +.class { + content: \\"style6.css\\"; +} + +/*!*******************************!*\\\\ + !*** css ./style6.css?foo=13 ***! + \\\\*******************************/ +.class { + content: \\"style6.css\\"; +} + +/*!*******************************!*\\\\ + !*** css ./style6.css?foo=14 ***! + \\\\*******************************/ +.class { + content: \\"style6.css\\"; +} + +/*!*******************************!*\\\\ + !*** css ./style6.css?foo=15 ***! + \\\\*******************************/ +.class { + content: \\"style6.css\\"; +} + +/*!*****************************************************************************************!*\\\\ + !*** css ./style6.css?foo=16 (media: /* Comment *_/ print and (orientation:landscape)) ***! + \\\\*****************************************************************************************/ +@media /* Comment */ print and (orientation:landscape) { + .class { + content: \\"style6.css\\"; + } +} + +/*!******************************************************************************************************!*\\\\ + !*** css ./style6.css?foo=17 (media: /* Comment *_/print and (orientation:landscape)/* Comment *_/) ***! + \\\\******************************************************************************************************/ +@media /* Comment */print and (orientation:landscape)/* Comment */ { + .class { + content: \\"style6.css\\"; + } +} + +/*!*****************************************************************************************!*\\\\ + !*** css ./style6.css?foo=18 (media: /* Comment *_/ print and (orientation:landscape)) ***! + \\\\*****************************************************************************************/ +@media /* Comment */ print and (orientation:landscape) { + .class { + content: \\"style6.css\\"; + } +} + +/*!***************************************************************!*\\\\ + !*** css ./style8.css (media: screen and (min-width: 400px)) ***! + \\\\***************************************************************/ +@media screen and (min-width: 400px) { + .class { + content: \\"style8.css\\"; + } +} + +/*!**************************************************************!*\\\\ + !*** css ./style8.css (media: (prefers-color-scheme: dark)) ***! + \\\\**************************************************************/ +@media (prefers-color-scheme: dark) { + .class { + content: \\"style8.css\\"; + } +} + +/*!**************************************************!*\\\\ + !*** css ./style8.css (supports: display: flex) ***! + \\\\**************************************************/ +@supports (display: flex) { + .class { + content: \\"style8.css\\"; + } +} + +/*!******************************************************!*\\\\ + !*** css ./style8.css (supports: ((display: flex))) ***! + \\\\******************************************************/ +@supports (((display: flex))) { + .class { + content: \\"style8.css\\"; + } +} + +/*!********************************************************************************************************!*\\\\ + !*** css ./style8.css (supports: ((display: inline-grid))) (media: screen and (((min-width: 400px)))) ***! + \\\\********************************************************************************************************/ +@supports (((display: inline-grid))) { + @media screen and (((min-width: 400px))) { + .class { + content: \\"style8.css\\"; + } + } +} + +/*!**************************************************!*\\\\ + !*** css ./style8.css (supports: display: grid) ***! + \\\\**************************************************/ +@supports (display: grid) { + .class { + content: \\"style8.css\\"; + } +} + +/*!*****************************************************************************************!*\\\\ + !*** css ./style8.css (supports: display: flex) (media: screen and (min-width: 400px)) ***! + \\\\*****************************************************************************************/ +@supports (display: flex) { + @media screen and (min-width: 400px) { + .class { + content: \\"style8.css\\"; + } + } +} + +/*!*******************************************!*\\\\ + !*** css ./style8.css (layer: framework) ***! + \\\\*******************************************/ +@layer framework { + .class { + content: \\"style8.css\\"; + } +} + +/*!*****************************************!*\\\\ + !*** css ./style8.css (layer: default) ***! + \\\\*****************************************/ +@layer default { + .class { + content: \\"style8.css\\"; + } +} + +/*!**************************************!*\\\\ + !*** css ./style8.css (layer: base) ***! + \\\\**************************************/ +@layer base { + .class { + content: \\"style8.css\\"; + } +} + +/*!*******************************************************************!*\\\\ + !*** css ./style8.css (layer: default) (supports: display: flex) ***! + \\\\*******************************************************************/ +@layer default { + @supports (display: flex) { + .class { + content: \\"style8.css\\"; + } + } +} + +/*!**********************************************************************************************************!*\\\\ + !*** css ./style8.css (layer: default) (supports: display: flex) (media: screen and (min-width: 400px)) ***! + \\\\**********************************************************************************************************/ +@layer default { + @supports (display: flex) { + @media screen and (min-width: 400px) { + .class { + content: \\"style8.css\\"; + } + } + } +} + +/*!************************!*\\\\ + !*** css ./style2.css ***! + \\\\************************/ +@layer { + a { + color: red; + } +} + +/*!*********************************************************************************!*\\\\ + !*** css ./style9.css (media: unknown(default) unknown(display: flex) unknown) ***! + \\\\*********************************************************************************/ +@media unknown(default) unknown(display: flex) unknown { + .class { + content: \\"style9.css\\"; + } +} + +/*!**************************************************!*\\\\ + !*** css ./style9.css (media: unknown(default)) ***! + \\\\**************************************************/ +@media unknown(default) { + .class { + content: \\"style9.css\\"; + } +} + +/*!*************************!*\\\\ + !*** css ./style11.css ***! + \\\\*************************/ +.style11 { + color: red; +} + +/*!*************************!*\\\\ + !*** css ./style12.css ***! + \\\\*************************/ + +.style12 { + color: red; +} + +/*!*************************!*\\\\ + !*** css ./style13.css ***! + \\\\*************************/ +div{color: red;} + +/*!*************************!*\\\\ + !*** css ./style10.css ***! + \\\\*************************/ + + +.style10 { + color: red; +} + +/*!************************************************************************************!*\\\\ + !*** css ./media-deep-deep-nested.css (media: screen and (orientation: portrait)) ***! + \\\\************************************************************************************/ +@media screen and (min-width: 400px) { + @media screen and (max-width: 500px) { + @media screen and (orientation: portrait) { + .class { + deep-deep-nested: 1; + } + } + } +} + +/*!**************************************************************************!*\\\\ + !*** css ./media-deep-nested.css (media: screen and (max-width: 500px)) ***! + \\\\**************************************************************************/ +@media screen and (min-width: 400px) { + @media screen and (max-width: 500px) { + + .class { + deep-nested: 1; + } + } +} + +/*!*********************************************************************!*\\\\ + !*** css ./media-nested.css (media: screen and (min-width: 400px)) ***! + \\\\*********************************************************************/ +@media screen and (min-width: 400px) { + + .class { + nested: 1; + } +} + +/*!**********************************************************************!*\\\\ + !*** css ./supports-deep-deep-nested.css (supports: display: table) ***! + \\\\**********************************************************************/ +@supports (display: flex) { + @supports (display: grid) { + @supports (display: table) { + .class { + deep-deep-nested: 1; + } + } + } +} + +/*!****************************************************************!*\\\\ + !*** css ./supports-deep-nested.css (supports: display: grid) ***! + \\\\****************************************************************/ +@supports (display: flex) { + @supports (display: grid) { + + .class { + deep-nested: 1; + } + } +} + +/*!***********************************************************!*\\\\ + !*** css ./supports-nested.css (supports: display: flex) ***! + \\\\***********************************************************/ +@supports (display: flex) { + + .class { + nested: 1; + } +} + +/*!*****************************************************!*\\\\ + !*** css ./layer-deep-deep-nested.css (layer: baz) ***! + \\\\*****************************************************/ +@layer foo { + @layer bar { + @layer baz { + .class { + deep-deep-nested: 1; + } + } + } +} + +/*!************************************************!*\\\\ + !*** css ./layer-deep-nested.css (layer: bar) ***! + \\\\************************************************/ +@layer foo { + @layer bar { + + .class { + deep-nested: 1; + } + } +} + +/*!*******************************************!*\\\\ + !*** css ./layer-nested.css (layer: foo) ***! + \\\\*******************************************/ +@layer foo { + + .class { + nested: 1; + } +} + +/*!*********************************************************************************************************************!*\\\\ + !*** css ./all-deep-deep-nested.css (layer: baz) (supports: display: table) (media: screen and (min-width: 600px)) ***! + \\\\*********************************************************************************************************************/ +@layer foo { + @supports (display: flex) { + @media screen and (min-width: 400px) { + @layer bar { + @supports (display: grid) { + @media screen and (min-width: 500px) { + @layer baz { + @supports (display: table) { + @media screen and (min-width: 600px) { + .class { + deep-deep-nested: 1; + } + } + } + } + } + } + } + } + } +} + +/*!***************************************************************************************************************!*\\\\ + !*** css ./all-deep-nested.css (layer: bar) (supports: display: grid) (media: screen and (min-width: 500px)) ***! + \\\\***************************************************************************************************************/ +@layer foo { + @supports (display: flex) { + @media screen and (min-width: 400px) { + @layer bar { + @supports (display: grid) { + @media screen and (min-width: 500px) { + + .class { + deep-nested: 1; + } + } + } + } + } + } +} + +/*!**********************************************************************************************************!*\\\\ + !*** css ./all-nested.css (layer: foo) (supports: display: flex) (media: screen and (min-width: 400px)) ***! + \\\\**********************************************************************************************************/ +@layer foo { + @supports (display: flex) { + @media screen and (min-width: 400px) { + + .class { + nested: 1; + } + } + } +} + +/*!*****************************************************!*\\\\ + !*** css ./mixed-deep-deep-nested.css (layer: bar) ***! + \\\\*****************************************************/ +@media screen and (min-width: 400px) { + @supports (display: flex) { + @layer bar { + .class { + deep-deep-nested: 1; + } + } + } +} + +/*!*************************************************************!*\\\\ + !*** css ./mixed-deep-nested.css (supports: display: flex) ***! + \\\\*************************************************************/ +@media screen and (min-width: 400px) { + @supports (display: flex) { + + .class { + deep-nested: 1; + } + } +} + +/*!*********************************************************************!*\\\\ + !*** css ./mixed-nested.css (media: screen and (min-width: 400px)) ***! + \\\\*********************************************************************/ +@media screen and (min-width: 400px) { + + .class { + nested: 1; + } +} + +/*!********************************************!*\\\\ + !*** css ./anonymous-deep-deep-nested.css ***! + \\\\********************************************/ +@layer { + @layer { + @layer { + .class { + deep-deep-nested: 1; + } + } + } +} + +/*!***************************************!*\\\\ + !*** css ./anonymous-deep-nested.css ***! + \\\\***************************************/ +@layer { + @layer { + + .class { + deep-nested: 1; + } + } +} + +/*!*****************************************************!*\\\\ + !*** css ./layer-deep-deep-nested.css (layer: baz) ***! + \\\\*****************************************************/ +@layer { + @layer base { + @layer baz { + .class { + deep-deep-nested: 1; + } + } + } +} + +/*!*************************************************!*\\\\ + !*** css ./layer-deep-nested.css (layer: base) ***! + \\\\*************************************************/ +@layer { + @layer base { + + .class { + deep-nested: 1; + } + } +} + +/*!**********************************!*\\\\ + !*** css ./anonymous-nested.css ***! + \\\\**********************************/ +@layer { + + .class { + deep-nested: 1; + } +} + +/*!************************************************************************************!*\\\\ + !*** css ./media-deep-deep-nested.css (media: screen and (orientation: portrait)) ***! + \\\\************************************************************************************/ +@media screen and (orientation: portrait) { + .class { + deep-deep-nested: 1; + } +} + +/*!**************************************************!*\\\\ + !*** css ./style8.css (supports: display: flex) ***! + \\\\**************************************************/ +@media screen and (orientation: portrait) { + @supports (display: flex) { + .class { + content: \\"style8.css\\"; + } + } +} + +/*!******************************************************************************!*\\\\ + !*** css ./duplicate-nested.css (media: screen and (orientation: portrait)) ***! + \\\\******************************************************************************/ +@media screen and (orientation: portrait) { + + .class { + duplicate-nested: true; + } +} + +/*!********************************************!*\\\\ + !*** css ./anonymous-deep-deep-nested.css ***! + \\\\********************************************/ +@supports (display: flex) { + @media screen and (orientation: portrait) { + @layer { + @layer { + .class { + deep-deep-nested: 1; + } + } + } + } +} + +/*!***************************************!*\\\\ + !*** css ./anonymous-deep-nested.css ***! + \\\\***************************************/ +@supports (display: flex) { + @media screen and (orientation: portrait) { + @layer { + + .class { + deep-nested: 1; + } + } + } +} + +/*!*****************************************************!*\\\\ + !*** css ./layer-deep-deep-nested.css (layer: baz) ***! + \\\\*****************************************************/ +@supports (display: flex) { + @media screen and (orientation: portrait) { + @layer base { + @layer baz { + .class { + deep-deep-nested: 1; + } + } + } + } +} + +/*!*************************************************!*\\\\ + !*** css ./layer-deep-nested.css (layer: base) ***! + \\\\*************************************************/ +@supports (display: flex) { + @media screen and (orientation: portrait) { + @layer base { + + .class { + deep-nested: 1; + } + } + } +} + +/*!********************************************************************************************************!*\\\\ + !*** css ./anonymous-nested.css (supports: display: flex) (media: screen and (orientation: portrait)) ***! + \\\\********************************************************************************************************/ +@supports (display: flex) { + @media screen and (orientation: portrait) { + + .class { + deep-nested: 1; + } + } +} + +/*!*********************************************************************************************************************!*\\\\ + !*** css ./all-deep-deep-nested.css (layer: baz) (supports: display: table) (media: screen and (min-width: 600px)) ***! + \\\\*********************************************************************************************************************/ +@layer super.foo { + @supports (display: flex) { + @media screen and (min-width: 400px) { + @layer bar { + @supports (display: grid) { + @media screen and (min-width: 500px) { + @layer baz { + @supports (display: table) { + @media screen and (min-width: 600px) { + .class { + deep-deep-nested: 1; + } + } + } + } + } + } + } + } + } +} + +/*!***************************************************************************************************************!*\\\\ + !*** css ./all-deep-nested.css (layer: bar) (supports: display: grid) (media: screen and (min-width: 500px)) ***! + \\\\***************************************************************************************************************/ +@layer super.foo { + @supports (display: flex) { + @media screen and (min-width: 400px) { + @layer bar { + @supports (display: grid) { + @media screen and (min-width: 500px) { + + .class { + deep-nested: 1; + } + } + } + } + } + } +} + +/*!****************************************************************************************************************!*\\\\ + !*** css ./all-nested.css (layer: super.foo) (supports: display: flex) (media: screen and (min-width: 400px)) ***! + \\\\****************************************************************************************************************/ +@layer super.foo { + @supports (display: flex) { + @media screen and (min-width: 400px) { + + .class { + nested: 1; + } + } + } +} + +/*!***************************************************************************************************************!*\\\\ + !*** css ./style2.css?warning=6 (supports: unknown: layer(super.foo)) (media: screen and (min-width: 400px)) ***! + \\\\***************************************************************************************************************/ +@supports (unknown: layer(super.foo)) { + @media screen and (min-width: 400px) { + a { + color: red; + } + } +} + +/*!***************************************************************************************************************!*\\\\ + !*** css ./style2.css?warning=7 (supports: url: url(\\"./unknown.css\\")) (media: screen and (min-width: 400px)) ***! + \\\\***************************************************************************************************************/ +@supports (url: url(\\"./unknown.css\\")) { + @media screen and (min-width: 400px) { + a { + color: red; + } + } +} + +/*!*************************************************************************************************************!*\\\\ + !*** css ./style2.css?warning=8 (supports: url: url(./unknown.css)) (media: screen and (min-width: 400px)) ***! + \\\\*************************************************************************************************************/ +@supports (url: url(./unknown.css)) { + @media screen and (min-width: 400px) { + a { + color: red; + } + } +} + +/*!***************************************************************************************************************************************!*\\\\ + !*** css ./style2.css?foo=unknown (layer: super.foo) (supports: display: flex) (media: unknown(\\"foo\\") screen and (min-width: 400px)) ***! + \\\\***************************************************************************************************************************************/ +@layer super.foo { + @supports (display: flex) { + @media unknown(\\"foo\\") screen and (min-width: 400px) { + a { + color: red; + } + } + } +} + +/*!******************************************************************************************************************************************************!*\\\\ + !*** css ./style2.css?foo=unknown1 (layer: super.foo) (supports: display: url(\\"./unknown.css\\")) (media: unknown(foo) screen and (min-width: 400px)) ***! + \\\\******************************************************************************************************************************************************/ +@layer super.foo { + @supports (display: url(\\"./unknown.css\\")) { + @media unknown(foo) screen and (min-width: 400px) { + a { + color: red; + } + } + } +} + +/*!*********************************************************************************************************************************************!*\\\\ + !*** css ./style2.css?foo=unknown2 (layer: super.foo) (supports: display: url(./unknown.css)) (media: \\"foo\\" screen and (min-width: 400px)) ***! + \\\\*********************************************************************************************************************************************/ +@layer super.foo { + @supports (display: url(./unknown.css)) { + @media \\"foo\\" screen and (min-width: 400px) { + a { + color: red; + } + } + } +} + +/*!***************************************************!*\\\\ + !*** css ./style2.css?unknown3 (media: \\"string\\") ***! + \\\\***************************************************/ +@media \\"string\\" { + a { + color: red; + } +} + +/*!****************************************!*\\\\ + !*** css ./style2.css?after-namespace ***! + \\\\****************************************/ +a { + color: red; +} + +/*!*************************************************************************!*\\\\ + !*** css ./style2.css?multiple=1 (media: url(./style2.css?multiple=2)) ***! + \\\\*************************************************************************/ +@media url(./style2.css?multiple=2) { + a { + color: red; + } +} + +/*!***********************************!*\\\\ + !*** css ./style2.css?multiple=3 ***! + \\\\***********************************/ +a { + color: red; +} + +/*!**********************************!*\\\\ + !*** css ./style2.css?strange=3 ***! + \\\\**********************************/ +a { + color: red; +} + +/*!***********************!*\\\\ + !*** css ./style.css ***! + \\\\***********************/ + +/* Has the same URL */ + + + + + + + + +/* anonymous */ + +/* All unknown parse as media for compatibility */ + + + +/* Inside support */ + + +/** Possible syntax in future */ + + +/** Unknown */ + +@import-normalize; + +/** Warnings */ + +@import nourl(test.css); +@import ; +@import foo-bar; +@import layer(super.foo) \\"./style2.css?warning=1\\" supports(display: flex) screen and (min-width: 400px); +@import layer(super.foo) supports(display: flex) \\"./style2.css?warning=2\\" screen and (min-width: 400px); +@import layer(super.foo) supports(display: flex) screen and (min-width: 400px) \\"./style2.css?warning=3\\"; +@import layer(super.foo) url(\\"./style2.css?warning=4\\") supports(display: flex) screen and (min-width: 400px); +@import layer(super.foo) supports(display: flex) url(\\"./style2.css?warning=5\\") screen and (min-width: 400px); +@import layer(super.foo) supports(display: flex) screen and (min-width: 400px) url(\\"./style2.css?warning=6\\"); +@import url(\\"/style2.css?warning=6\\") supports(display: flex) layer(super.foo) screen and (min-width: 400px); +@namespace url(http://www.w3.org/1999/xhtml); +@import supports(background: url(\\"./img.png\\")); +@import supports(background: url(\\"./img.png\\")) screen and (min-width: 400px); +@import layer(test) supports(background: url(\\"./img.png\\")) screen and (min-width: 400px); +@import screen and (min-width: 400px); + + + +body { + background: red; +} + +head{--webpack-main:https\\\\:\\\\/\\\\/test\\\\.cases\\\\/path\\\\/\\\\.\\\\.\\\\/\\\\.\\\\.\\\\/\\\\.\\\\.\\\\/\\\\.\\\\.\\\\/configCases\\\\/css\\\\/css-import\\\\/external\\\\.css,\\\\/\\\\/example\\\\.com\\\\/style\\\\.css,https\\\\:\\\\/\\\\/fonts\\\\.googleapis\\\\.com\\\\/css\\\\?family\\\\=Roboto,https\\\\:\\\\/\\\\/fonts\\\\.googleapis\\\\.com\\\\/css\\\\?family\\\\=Noto\\\\+Sans\\\\+TC,https\\\\:\\\\/\\\\/fonts\\\\.googleapis\\\\.com\\\\/css\\\\?family\\\\=Noto\\\\+Sans\\\\+TC\\\\|Roboto,https\\\\:\\\\/\\\\/fonts\\\\.googleapis\\\\.com\\\\/css\\\\?family\\\\=Noto\\\\+Sans\\\\+TC\\\\|Roboto\\\\?foo\\\\=1,https\\\\:\\\\/\\\\/test\\\\.cases\\\\/path\\\\/\\\\.\\\\.\\\\/\\\\.\\\\.\\\\/\\\\.\\\\.\\\\/\\\\.\\\\.\\\\/configCases\\\\/css\\\\/css-import\\\\/external1\\\\.css,https\\\\:\\\\/\\\\/test\\\\.cases\\\\/path\\\\/\\\\.\\\\.\\\\/\\\\.\\\\.\\\\/\\\\.\\\\.\\\\/\\\\.\\\\.\\\\/configCases\\\\/css\\\\/css-import\\\\/external2\\\\.css,external-1\\\\.css,external-2\\\\.css,external-3\\\\.css,external-4\\\\.css,external-5\\\\.css,external-6\\\\.css,external-7\\\\.css,external-8\\\\.css,external-9\\\\.css,external-10\\\\.css,external-11\\\\.css,external-12\\\\.css,external-13\\\\.css,external-14\\\\.css,&\\\\.\\\\/node_modules\\\\/style-library\\\\/styles\\\\.css,&\\\\.\\\\/node_modules\\\\/main-field\\\\/styles\\\\.css,&\\\\.\\\\/node_modules\\\\/package-with-exports\\\\/style\\\\.css,&\\\\.\\\\/extensions-imported\\\\.mycss,&\\\\.\\\\/file\\\\.less,&\\\\.\\\\/with-less-import\\\\.css,&\\\\.\\\\/prefer-relative\\\\.css,&\\\\.\\\\/node_modules\\\\/condition-names-style\\\\/default\\\\.css,&\\\\.\\\\/node_modules\\\\/condition-names-style-mode\\\\/mode\\\\.css,&\\\\.\\\\/node_modules\\\\/condition-names-subpath\\\\/dist\\\\/custom\\\\.css,&\\\\.\\\\/node_modules\\\\/condition-names-subpath-extra\\\\/dist\\\\/custom\\\\.css,&\\\\.\\\\/node_modules\\\\/condition-names-style-less\\\\/default\\\\.less,&\\\\.\\\\/node_modules\\\\/condition-names-custom-name\\\\/custom-name\\\\.css,&\\\\.\\\\/node_modules\\\\/style-and-main-library\\\\/styles\\\\.css,&\\\\.\\\\/node_modules\\\\/condition-names-webpack\\\\/webpack\\\\.css,&\\\\.\\\\/node_modules\\\\/condition-names-style-nested\\\\/default\\\\.css,&\\\\.\\\\/style-import\\\\.css,&\\\\.\\\\/print\\\\.css\\\\?foo\\\\=1,&\\\\.\\\\/print\\\\.css\\\\?foo\\\\=2,&\\\\.\\\\/print\\\\.css\\\\?foo\\\\=3,&\\\\.\\\\/print\\\\.css\\\\?foo\\\\=4,&\\\\.\\\\/print\\\\.css\\\\?foo\\\\=5,&\\\\.\\\\/print\\\\.css\\\\?foo\\\\=6,&\\\\.\\\\/print\\\\.css\\\\?foo\\\\=7,&\\\\.\\\\/print\\\\.css\\\\?foo\\\\=8,&\\\\.\\\\/print\\\\.css\\\\?foo\\\\=9,&\\\\.\\\\/print\\\\.css\\\\?foo\\\\=10,&\\\\.\\\\/print\\\\.css\\\\?foo\\\\=11,&\\\\.\\\\/print\\\\.css\\\\?foo\\\\=12,&\\\\.\\\\/print\\\\.css\\\\?foo\\\\=13,&\\\\.\\\\/print\\\\.css\\\\?foo\\\\=14,&\\\\.\\\\/print\\\\.css\\\\?foo\\\\=15,&\\\\.\\\\/print\\\\.css\\\\?foo\\\\=16,&\\\\.\\\\/print\\\\.css\\\\?foo\\\\=17,&\\\\.\\\\/print\\\\.css\\\\?foo\\\\=18,&\\\\.\\\\/print\\\\.css\\\\?foo\\\\=19,&\\\\.\\\\/print\\\\.css\\\\?foo\\\\=20,&\\\\.\\\\/print\\\\.css\\\\?foo\\\\=21,&\\\\.\\\\/imported\\\\.css\\\\?1832,&\\\\.\\\\/imported\\\\.css\\\\?e0bb,&\\\\.\\\\/imported\\\\.css\\\\?769a,&\\\\.\\\\/imported\\\\.css\\\\?d4d6,&\\\\.\\\\/style2\\\\.css\\\\?foo\\\\=1,&\\\\.\\\\/style2\\\\.css\\\\?foo\\\\=2,&\\\\.\\\\/style2\\\\.css\\\\?foo\\\\=3,&\\\\.\\\\/style2\\\\.css\\\\?foo\\\\=4,&\\\\.\\\\/style2\\\\.css\\\\?foo\\\\=5,&\\\\.\\\\/style2\\\\.css\\\\?foo\\\\=6,&\\\\.\\\\/style2\\\\.css\\\\?foo\\\\=7,&\\\\.\\\\/style2\\\\.css\\\\?foo\\\\=8,&\\\\.\\\\/style2\\\\.css\\\\?foo\\\\=9,&\\\\.\\\\/style2\\\\.css\\\\?cf0d,&\\\\.\\\\/style2\\\\.css\\\\?dfe6,&\\\\.\\\\/style2\\\\.css\\\\?7d49,&\\\\.\\\\/test\\\\.css\\\\?foo\\\\=1\\\\&bar\\\\=1,&\\\\.\\\\/style2\\\\.css\\\\?foo\\\\=1\\\\&bar\\\\=1\\\\#hash\\\\?63d2,&\\\\.\\\\/style2\\\\.css\\\\?foo\\\\=1\\\\&bar\\\\=1\\\\#hash\\\\?e75b,&\\\\.\\\\/style3\\\\.css\\\\?bar\\\\=1,&\\\\.\\\\/style3\\\\.css\\\\?bar\\\\=2,&\\\\.\\\\/style3\\\\.css\\\\?bar\\\\=3,&\\\\.\\\\/style3\\\\.css\\\\?\\\\=bar4,&\\\\.\\\\/styl\\\\'le7\\\\.css,&\\\\.\\\\/styl\\\\'le7\\\\.css\\\\?foo\\\\=1,&\\\\.\\\\/test\\\\ test\\\\.css,&\\\\.\\\\/test\\\\ test\\\\.css\\\\?foo\\\\=1,&\\\\.\\\\/test\\\\ test\\\\.css\\\\?foo\\\\=2,&\\\\.\\\\/test\\\\ test\\\\.css\\\\?foo\\\\=3,&\\\\.\\\\/test\\\\ test\\\\.css\\\\?foo\\\\=4,&\\\\.\\\\/test\\\\ test\\\\.css\\\\?foo\\\\=5,&\\\\.\\\\/test\\\\.css,&\\\\.\\\\/test\\\\.css\\\\?foo\\\\=1,&\\\\.\\\\/test\\\\.css\\\\?foo\\\\=2,&\\\\.\\\\/test\\\\.css\\\\?foo\\\\=3,&\\\\.\\\\/test\\\\ test\\\\.css\\\\?foo\\\\=6,&\\\\.\\\\/test\\\\ test\\\\.css\\\\?foo\\\\=7,&\\\\.\\\\/test\\\\ test\\\\.css\\\\?foo\\\\=8,&\\\\.\\\\/test\\\\ test\\\\.css\\\\?foo\\\\=9,&\\\\.\\\\/test\\\\ test\\\\.css\\\\?fpp\\\\=10,&\\\\.\\\\/test\\\\ test\\\\.css\\\\?foo\\\\=11,&\\\\.\\\\/style6\\\\.css\\\\?foo\\\\=bazz,&\\\\.\\\\/string-loader\\\\.js\\\\?esModule\\\\=false\\\\!\\\\.\\\\/test\\\\.css\\\\?10e0,&\\\\.\\\\/style4\\\\.css\\\\?foo\\\\=bar,&\\\\.\\\\/style4\\\\.css\\\\?foo\\\\=bar\\\\#hash,&\\\\.\\\\/style4\\\\.css\\\\?\\\\#hash,&\\\\.\\\\/style4\\\\.css\\\\?foo\\\\=1,&\\\\.\\\\/style4\\\\.css\\\\?foo\\\\=2,&\\\\.\\\\/style4\\\\.css\\\\?foo\\\\=3,&\\\\.\\\\/style4\\\\.css\\\\?foo\\\\=4,&\\\\.\\\\/style4\\\\.css\\\\?foo\\\\=5,&\\\\.\\\\/string-loader\\\\.js\\\\?esModule\\\\=false\\\\!\\\\.\\\\/test\\\\.css\\\\?6393,&data\\\\:text\\\\/css\\\\;charset\\\\=utf-8\\\\,a\\\\%20\\\\%7B\\\\%0D\\\\%0A\\\\%20\\\\%20color\\\\%3A\\\\%20red\\\\%3B\\\\%0D\\\\%0A\\\\%7D,&data\\\\:text\\\\/css\\\\;charset\\\\=utf-8\\\\,a\\\\%20\\\\%7B\\\\%0D\\\\%0A\\\\%20\\\\%20color\\\\%3A\\\\%20blue\\\\%3B\\\\%0D\\\\%0A\\\\%7D,&data\\\\:text\\\\/css\\\\;charset\\\\=utf-8\\\\;base64\\\\,YSB7DQogIGNvbG9yOiByZWQ7DQp9,&\\\\.\\\\/style5\\\\.css\\\\?foo\\\\=1,&\\\\.\\\\/style5\\\\.css\\\\?foo\\\\=2,&\\\\.\\\\/style5\\\\.css\\\\?foo\\\\=3,&\\\\.\\\\/style5\\\\.css\\\\?foo\\\\=4,&\\\\.\\\\/style5\\\\.css\\\\?foo\\\\=5,&\\\\.\\\\/style5\\\\.css\\\\?foo\\\\=6,&\\\\.\\\\/style5\\\\.css\\\\?foo\\\\=7,&\\\\.\\\\/style5\\\\.css\\\\?foo\\\\=8,&\\\\.\\\\/layer\\\\.css\\\\?foo\\\\=1,&\\\\.\\\\/layer\\\\.css\\\\?foo\\\\=2,&\\\\.\\\\/layer\\\\.css\\\\?foo\\\\=3\\\\?1ab5,&\\\\.\\\\/layer\\\\.css\\\\?foo\\\\=3\\\\?19e1,&\\\\.\\\\/layer\\\\.css\\\\?foo\\\\=4,&\\\\.\\\\/layer\\\\.css\\\\?foo\\\\=5,&\\\\.\\\\/layer\\\\.css\\\\?foo\\\\=6,&\\\\.\\\\/layer\\\\.css\\\\?foo\\\\=7,&\\\\.\\\\/style6\\\\.css,&\\\\.\\\\/style6\\\\.css\\\\?foo\\\\=1,&\\\\.\\\\/style6\\\\.css\\\\?foo\\\\=2,&\\\\.\\\\/style6\\\\.css\\\\?foo\\\\=3,&\\\\.\\\\/style6\\\\.css\\\\?foo\\\\=4,&\\\\.\\\\/style6\\\\.css\\\\?foo\\\\=5,&\\\\.\\\\/style6\\\\.css\\\\?foo\\\\=6,&\\\\.\\\\/style6\\\\.css\\\\?foo\\\\=7,&\\\\.\\\\/style6\\\\.css\\\\?foo\\\\=8,&\\\\.\\\\/style6\\\\.css\\\\?foo\\\\=9,&\\\\.\\\\/style6\\\\.css\\\\?foo\\\\=10,&\\\\.\\\\/style6\\\\.css\\\\?foo\\\\=11,&\\\\.\\\\/style6\\\\.css\\\\?foo\\\\=12,&\\\\.\\\\/style6\\\\.css\\\\?foo\\\\=13,&\\\\.\\\\/style6\\\\.css\\\\?foo\\\\=14,&\\\\.\\\\/style6\\\\.css\\\\?foo\\\\=15,&\\\\.\\\\/style6\\\\.css\\\\?foo\\\\=16,&\\\\.\\\\/style6\\\\.css\\\\?foo\\\\=17,&\\\\.\\\\/style6\\\\.css\\\\?foo\\\\=18,&\\\\.\\\\/style8\\\\.css\\\\?b84b,&\\\\.\\\\/style8\\\\.css\\\\?5dc5,&\\\\.\\\\/style8\\\\.css\\\\?71be,&\\\\.\\\\/style8\\\\.css\\\\?386a,&\\\\.\\\\/style8\\\\.css\\\\?568a,&\\\\.\\\\/style8\\\\.css\\\\?b9af,&\\\\.\\\\/style8\\\\.css\\\\?7300,&\\\\.\\\\/style8\\\\.css\\\\?6efd,&\\\\.\\\\/style8\\\\.css\\\\?288c,&\\\\.\\\\/style8\\\\.css\\\\?1094,&\\\\.\\\\/style8\\\\.css\\\\?38bf,&\\\\.\\\\/style8\\\\.css\\\\?d697,&\\\\.\\\\/style2\\\\.css\\\\?0aae,&\\\\.\\\\/style9\\\\.css\\\\?8e91,&\\\\.\\\\/style9\\\\.css\\\\?71b5,&\\\\.\\\\/style11\\\\.css,&\\\\.\\\\/style12\\\\.css,&\\\\.\\\\/style13\\\\.css,&\\\\.\\\\/style10\\\\.css,&\\\\.\\\\/media-deep-deep-nested\\\\.css\\\\?ef21,&\\\\.\\\\/media-deep-nested\\\\.css,&\\\\.\\\\/media-nested\\\\.css,&\\\\.\\\\/supports-deep-deep-nested\\\\.css,&\\\\.\\\\/supports-deep-nested\\\\.css,&\\\\.\\\\/supports-nested\\\\.css,&\\\\.\\\\/layer-deep-deep-nested\\\\.css\\\\?5660,&\\\\.\\\\/layer-deep-nested\\\\.css\\\\?9fd1,&\\\\.\\\\/layer-nested\\\\.css,&\\\\.\\\\/all-deep-deep-nested\\\\.css\\\\?af0a,&\\\\.\\\\/all-deep-nested\\\\.css\\\\?4e94,&\\\\.\\\\/all-nested\\\\.css\\\\?c0fa,&\\\\.\\\\/mixed-deep-deep-nested\\\\.css,&\\\\.\\\\/mixed-deep-nested\\\\.css,&\\\\.\\\\/mixed-nested\\\\.css,&\\\\.\\\\/anonymous-deep-deep-nested\\\\.css\\\\?1f16,&\\\\.\\\\/anonymous-deep-nested\\\\.css\\\\?c0a8,&\\\\.\\\\/layer-deep-deep-nested\\\\.css\\\\?4bce,&\\\\.\\\\/layer-deep-nested\\\\.css\\\\?a03f,&\\\\.\\\\/anonymous-nested\\\\.css\\\\?390d,&\\\\.\\\\/media-deep-deep-nested\\\\.css\\\\?7047,&\\\\.\\\\/style8\\\\.css\\\\?8af1,&\\\\.\\\\/duplicate-nested\\\\.css,&\\\\.\\\\/anonymous-deep-deep-nested\\\\.css\\\\?9cec,&\\\\.\\\\/anonymous-deep-nested\\\\.css\\\\?dea4,&\\\\.\\\\/layer-deep-deep-nested\\\\.css\\\\?4897,&\\\\.\\\\/layer-deep-nested\\\\.css\\\\?4579,&\\\\.\\\\/anonymous-nested\\\\.css\\\\?df05,&\\\\.\\\\/all-deep-deep-nested\\\\.css\\\\?55ab,&\\\\.\\\\/all-deep-nested\\\\.css\\\\?1513,&\\\\.\\\\/all-nested\\\\.css\\\\?ccc9,&\\\\.\\\\/style2\\\\.css\\\\?warning\\\\=6,&\\\\.\\\\/style2\\\\.css\\\\?warning\\\\=7,&\\\\.\\\\/style2\\\\.css\\\\?warning\\\\=8,&\\\\.\\\\/style2\\\\.css\\\\?foo\\\\=unknown,&\\\\.\\\\/style2\\\\.css\\\\?foo\\\\=unknown1,&\\\\.\\\\/style2\\\\.css\\\\?foo\\\\=unknown2,&\\\\.\\\\/style2\\\\.css\\\\?unknown3,&\\\\.\\\\/style2\\\\.css\\\\?after-namespace,&\\\\.\\\\/style2\\\\.css\\\\?multiple\\\\=1,&\\\\.\\\\/style2\\\\.css\\\\?multiple\\\\=3,&\\\\.\\\\/style2\\\\.css\\\\?strange\\\\=3,&\\\\.\\\\/style\\\\.css;}", +] +`; + +exports[`ConfigCacheTestCases css css-modules exported tests should allow to create css modules 1`] = ` +"/*!******************************!*\\\\ + !*** css ./style.module.css ***! + \\\\******************************/ +._-_style_module_css-class { + color: red; +} + +._-_style_module_css-local1, +._-_style_module_css-local2 .global, +._-_style_module_css-local3 { + color: green; +} + +.global ._-_style_module_css-local4 { + color: yellow; +} + +._-_style_module_css-local5.global._-_style_module_css-local6 { + color: blue; +} + +._-_style_module_css-local7 div:not(._-_style_module_css-disabled, ._-_style_module_css-mButtonDisabled, ._-_style_module_css-tipOnly) { + pointer-events: initial !important; +} + +._-_style_module_css-local8 :is(div._-_style_module_css-parent1._-_style_module_css-child1._-_style_module_css-vertical-tiny, + div._-_style_module_css-parent1._-_style_module_css-child1._-_style_module_css-vertical-small, + div._-_style_module_css-otherDiv._-_style_module_css-horizontal-tiny, + div._-_style_module_css-otherDiv._-_style_module_css-horizontal-small div._-_style_module_css-description) { + max-height: 0; + margin: 0; + overflow: hidden; +} + +._-_style_module_css-local9 :matches(div._-_style_module_css-parent1._-_style_module_css-child1._-_style_module_css-vertical-tiny, + div._-_style_module_css-parent1._-_style_module_css-child1._-_style_module_css-vertical-small, + div._-_style_module_css-otherDiv._-_style_module_css-horizontal-tiny, + div._-_style_module_css-otherDiv._-_style_module_css-horizontal-small div._-_style_module_css-description) { + max-height: 0; + margin: 0; + overflow: hidden; +} + +._-_style_module_css-local10 :where(div._-_style_module_css-parent1._-_style_module_css-child1._-_style_module_css-vertical-tiny, + div._-_style_module_css-parent1._-_style_module_css-child1._-_style_module_css-vertical-small, + div._-_style_module_css-otherDiv._-_style_module_css-horizontal-tiny, + div._-_style_module_css-otherDiv._-_style_module_css-horizontal-small div._-_style_module_css-description) { + max-height: 0; + margin: 0; + overflow: hidden; +} + +._-_style_module_css-local11 div:has(._-_style_module_css-disabled, ._-_style_module_css-mButtonDisabled, ._-_style_module_css-tipOnly) { + pointer-events: initial !important; +} + +._-_style_module_css-local12 div:current(p, span) { + background-color: yellow; +} + +._-_style_module_css-local13 div:past(p, span) { + display: none; +} + +._-_style_module_css-local14 div:future(p, span) { + background-color: yellow; +} + +._-_style_module_css-local15 div:-moz-any(ol, ul, menu, dir) { + list-style-type: square; +} + +._-_style_module_css-local16 li:-webkit-any(:first-child, :last-child) { + background-color: aquamarine; +} + +._-_style_module_css-local9 :matches(div._-_style_module_css-parent1._-_style_module_css-child1._-_style_module_css-vertical-tiny, + div._-_style_module_css-parent1._-_style_module_css-child1._-_style_module_css-vertical-small, + div._-_style_module_css-otherDiv._-_style_module_css-horizontal-tiny, + div._-_style_module_css-otherDiv._-_style_module_css-horizontal-small div._-_style_module_css-description) { + max-height: 0; + margin: 0; + overflow: hidden; +} + +._-_style_module_css-nested1.nested2._-_style_module_css-nested3 { + color: pink; +} + +#_-_style_module_css-ident { + color: purple; +} + +@keyframes _-_style_module_css-localkeyframes{ + 0% { + left: var(---_style_module_css-pos1x); + top: var(---_style_module_css-pos1y); + color: var(--theme-color1); + } + 100% { + left: var(---_style_module_css-pos2x); + top: var(---_style_module_css-pos2y); + color: var(--theme-color2); + } +} + +@keyframes _-_style_module_css-localkeyframes2{ + 0% { + left: 0; + } + 100% { + left: 100px; + } +} + +._-_style_module_css-animation { + animation-name: _-_style_module_css-localkeyframes; + animation: 3s ease-in 1s 2 reverse both paused _-_style_module_css-localkeyframes, _-_style_module_css-localkeyframes2; + ---_style_module_css-pos1x: 0px; + ---_style_module_css-pos1y: 0px; + ---_style_module_css-pos2x: 10px; + ---_style_module_css-pos2y: 20px; +} + +/* .composed { + composes: local1; + composes: local2; +} */ + +._-_style_module_css-vars { + color: var(---_style_module_css-local-color); + ---_style_module_css-local-color: red; +} + +._-_style_module_css-globalVars { + color: var(--global-color); + --global-color: red; +} + +@media (min-width: 1600px) { + ._-_style_module_css-wideScreenClass { + color: var(---_style_module_css-local-color); + ---_style_module_css-local-color: green; + } +} + +@media screen and (max-width: 600px) { + ._-_style_module_css-narrowScreenClass { + color: var(---_style_module_css-local-color); + ---_style_module_css-local-color: purple; + } +} + +@supports (display: grid) { + ._-_style_module_css-displayGridInSupports { + display: grid; + } +} + +@supports not (display: grid) { + ._-_style_module_css-floatRightInNegativeSupports { + float: right; + } +} + +@supports (display: flex) { + @media screen and (min-width: 900px) { + ._-_style_module_css-displayFlexInMediaInSupports { + display: flex; + } + } +} + +@media screen and (min-width: 900px) { + @supports (display: flex) { + ._-_style_module_css-displayFlexInSupportsInMedia { + display: flex; + } + } +} + +@MEDIA screen and (min-width: 900px) { + @SUPPORTS (display: flex) { + ._-_style_module_css-displayFlexInSupportsInMediaUpperCase { + display: flex; + } + } +} + +._-_style_module_css-animationUpperCase { + ANIMATION-NAME: _-_style_module_css-localkeyframesUPPERCASE; + ANIMATION: 3s ease-in 1s 2 reverse both paused _-_style_module_css-localkeyframesUPPERCASE, _-_style_module_css-localkeyframes2UPPPERCASE; + ---_style_module_css-pos1x: 0px; + ---_style_module_css-pos1y: 0px; + ---_style_module_css-pos2x: 10px; + ---_style_module_css-pos2y: 20px; +} + +@KEYFRAMES _-_style_module_css-localkeyframesUPPERCASE{ + 0% { + left: VAR(---_style_module_css-pos1x); + top: VAR(---_style_module_css-pos1y); + color: VAR(--theme-color1); + } + 100% { + left: VAR(---_style_module_css-pos2x); + top: VAR(---_style_module_css-pos2y); + color: VAR(--theme-color2); + } +} + +@KEYframes _-_style_module_css-localkeyframes2UPPPERCASE{ + 0% { + left: 0; + } + 100% { + left: 100px; + } +} + +.globalUpperCase ._-_style_module_css-localUpperCase { + color: yellow; +} + +._-_style_module_css-VARS { + color: VAR(---_style_module_css-LOCAL-COLOR); + ---_style_module_css-LOCAL-COLOR: red; +} + +._-_style_module_css-globalVarsUpperCase { + COLOR: VAR(--GLOBAR-COLOR); + --GLOBAR-COLOR: red; +} + +@supports (top: env(safe-area-inset-top, 0)) { + ._-_style_module_css-inSupportScope { + color: red; + } +} + +._-_style_module_css-a { + animation: 3s _-_style_module_css-animationName; + -webkit-animation: 3s _-_style_module_css-animationName; +} + +._-_style_module_css-b { + animation: _-_style_module_css-animationName 3s; + -webkit-animation: _-_style_module_css-animationName 3s; +} + +._-_style_module_css-c { + animation-name: _-_style_module_css-animationName; + -webkit-animation-name: _-_style_module_css-animationName; +} + +._-_style_module_css-d { + ---_style_module_css-animation-name: animationName; +} + +@keyframes _-_style_module_css-animationName{ + 0% { + background: white; + } + 100% { + background: red; + } +} + +@-webkit-keyframes _-_style_module_css-animationName{ + 0% { + background: white; + } + 100% { + background: red; + } +} + +@-moz-keyframes _-_style_module_css-mozAnimationName{ + 0% { + background: white; + } + 100% { + background: red; + } +} + +@counter-style thumbs { + system: cyclic; + symbols: \\"\\\\1F44D\\"; + suffix: \\" \\"; +} + +@font-feature-values Font One { + @styleset { + nice-style: 12; + } +} + +/* At-rule for \\"nice-style\\" in Font Two */ +@font-feature-values Font Two { + @styleset { + nice-style: 4; + } +} + +@property ---_style_module_css-my-color{ + syntax: \\"\\"; + inherits: false; + initial-value: #_-_style_module_css-c0ffee; +} + +._-_style_module_css-class { + color: var(---_style_module_css-my-color); +} + +@layer utilities { + ._-_style_module_css-padding-sm { + padding: 0.5rem; + } + + ._-_style_module_css-padding-lg { + padding: 0.8rem; + } +} + +._-_style_module_css-class { + color: red; + + ._-_style_module_css-nested-pure { + color: red; + } + + @media screen and (min-width: 200px) { + color: blue; + + ._-_style_module_css-nested-media { + color: blue; + } + } + + @supports (display: flex) { + display: flex; + + ._-_style_module_css-nested-supports { + display: flex; + } + } + + @layer foo { + background: red; + + ._-_style_module_css-nested-layer { + background: red; + } + } + + @container foo { + background: red; + + ._-_style_module_css-nested-layer { + background: red; + } + } +} + +._-_style_module_css-not-selector-inside { + color: #fff; + opacity: 0.12; + padding: .5px; + unknown: :local(.test); + unknown1: :local .test; + unknown2: :global .test; + unknown3: :global .test; + unknown4: .foo, .bar, #bar; +} + +@unknown :local .local :global .global { + color: red; +} + +@unknown :local(.local) :global(.global) { + color: red; +} + +._-_style_module_css-nested-var { + ._-_style_module_css-again { + color: var(---_style_module_css-local-color); + } +} + +._-_style_module_css-nested-with-local-pseudo { + color: red; + + ._-_style_module_css-local-nested { + color: red; + } + + .global-nested { + color: red; + } + + ._-_style_module_css-local-nested { + color: red; + } + + .global-nested { + color: red; + } + + ._-_style_module_css-local-nested, .global-nested-next { + color: red; + } + + ._-_style_module_css-local-nested, .global-nested-next { + color: red; + } + + .foo, ._-_style_module_css-bar { + color: red; + } +} + +#_-_style_module_css-id-foo { + color: red; + + #_-_style_module_css-id-bar { + color: red; + } +} + +._-_style_module_css-nested-parens { + ._-_style_module_css-local9 div:has(._-_style_module_css-vertical-tiny, ._-_style_module_css-vertical-small) { + max-height: 0; + margin: 0; + overflow: hidden; + } +} + +.global-foo { + .nested-global { + color: red; + } + + ._-_style_module_css-local-in-global { + color: blue; + } +} + +@unknown .class { + color: red; + + .class { + color: red; + } +} + +.class ._-_style_module_css-in-local-global-scope, +.class ._-_style_module_css-in-local-global-scope, +._-_style_module_css-class-local-scope .in-local-global-scope { + color: red; +} + +@container (width > 400px) { + ._-_style_module_css-class-in-container { + font-size: 1.5em; + } +} + +@container summary (min-width: 400px) { + @container (width > 400px) { + ._-_style_module_css-deep-class-in-container { + font-size: 1.5em; + } + } +} + +:scope { + color: red; +} + +._-_style_module_css-placeholder-gray-700:-ms-input-placeholder { + ---_style_module_css-placeholder-opacity: 1; + color: #4a5568; + color: rgba(74, 85, 104, var(---_style_module_css-placeholder-opacity)); +} +._-_style_module_css-placeholder-gray-700::-ms-input-placeholder { + ---_style_module_css-placeholder-opacity: 1; + color: #4a5568; + color: rgba(74, 85, 104, var(---_style_module_css-placeholder-opacity)); +} +._-_style_module_css-placeholder-gray-700::placeholder { + ---_style_module_css-placeholder-opacity: 1; + color: #4a5568; + color: rgba(74, 85, 104, var(---_style_module_css-placeholder-opacity)); +} + +:root { + ---_style_module_css-test: dark; +} + +@media screen and (prefers-color-scheme: var(---_style_module_css-test)) { + ._-_style_module_css-baz { + color: white; + } +} + +@keyframes _-_style_module_css-slidein{ + from { + margin-left: 100%; + width: 300%; + } + + to { + margin-left: 0%; + width: 100%; + } +} + +._-_style_module_css-class { + animation: + foo var(---_style_module_css-animation-name) 3s, + var(---_style_module_css-animation-name) 3s, + 3s linear 1s infinite running _-_style_module_css-slidein, + 3s linear env(foo, var(---_style_module_css-baz)) infinite running _-_style_module_css-slidein; +} + +:root { + ---_style_module_css-baz: 10px; +} + +._-_style_module_css-class { + bar: env(foo, var(---_style_module_css-baz)); +} + +.global-foo, ._-_style_module_css-bar { + ._-_style_module_css-local-in-global { + color: blue; + } + + @media screen { + .my-global-class-again, + ._-_style_module_css-my-global-class-again { + color: red; + } + } +} + +._-_style_module_css-first-nested { + ._-_style_module_css-first-nested-nested { + color: red; + } +} + +._-_style_module_css-first-nested-at-rule { + @media screen { + ._-_style_module_css-first-nested-nested-at-rule-deep { + color: red; + } + } +} + +.again-global { + color:red; +} + +.again-again-global { + .again-again-global { + color: red; + } +} + +:root { + ---_style_module_css-foo: red; +} + +.again-again-global { + color: var(--foo); + + .again-again-global { + color: var(--foo); + } +} + +.again-again-global { + animation: slidein 3s; + + .again-again-global, ._-_style_module_css-class, ._-_style_module_css-nested1.nested2._-_style_module_css-nested3 { + animation: _-_style_module_css-slidein 3s; + } + + ._-_style_module_css-local2 .global, + ._-_style_module_css-local3 { + color: red; + } +} + +@unknown var(--foo) { + color: red; +} + +._-_style_module_css-class { + ._-_style_module_css-class { + ._-_style_module_css-class { + ._-_style_module_css-class {} + } + } +} + +._-_style_module_css-class { + ._-_style_module_css-class { + ._-_style_module_css-class { + ._-_style_module_css-class { + animation: _-_style_module_css-slidein 3s; + } + } + } +} + +._-_style_module_css-class { + animation: _-_style_module_css-slidein 3s; + ._-_style_module_css-class { + animation: _-_style_module_css-slidein 3s; + ._-_style_module_css-class { + animation: _-_style_module_css-slidein 3s; + ._-_style_module_css-class { + animation: _-_style_module_css-slidein 3s; + } + } + } +} + +/*!*********************************!*\\\\ + !*** css ./style.module.my-css ***! + \\\\*********************************/ +._-_style_module_my-css-myCssClass { + color: red; +} + +/*!**************************************!*\\\\ + !*** css ./style.module.css.invalid ***! + \\\\**************************************/ +.class { + color: teal; +} + +/*!************************************!*\\\\ + !*** css ./identifiers.module.css ***! + \\\\************************************/ +._-_identifiers_module_css-UnusedClassName{ + color: red; + padding: var(---_identifiers_module_css-variable-unused-class); + ---_identifiers_module_css-variable-unused-class: 10px; +} + +._-_identifiers_module_css-UsedClassName { + color: green; + padding: var(---_identifiers_module_css-variable-used-class); + ---_identifiers_module_css-variable-used-class: 10px; +} + +head{--webpack-use-style_js:class:_-_style_module_css-class/local1:_-_style_module_css-local1/local2:_-_style_module_css-local2/local3:_-_style_module_css-local3/local4:_-_style_module_css-local4/local5:_-_style_module_css-local5/local6:_-_style_module_css-local6/local7:_-_style_module_css-local7/disabled:_-_style_module_css-disabled/mButtonDisabled:_-_style_module_css-mButtonDisabled/tipOnly:_-_style_module_css-tipOnly/local8:_-_style_module_css-local8/parent1:_-_style_module_css-parent1/child1:_-_style_module_css-child1/vertical-tiny:_-_style_module_css-vertical-tiny/vertical-small:_-_style_module_css-vertical-small/otherDiv:_-_style_module_css-otherDiv/horizontal-tiny:_-_style_module_css-horizontal-tiny/horizontal-small:_-_style_module_css-horizontal-small/description:_-_style_module_css-description/local9:_-_style_module_css-local9/local10:_-_style_module_css-local10/local11:_-_style_module_css-local11/local12:_-_style_module_css-local12/local13:_-_style_module_css-local13/local14:_-_style_module_css-local14/local15:_-_style_module_css-local15/local16:_-_style_module_css-local16/nested1:_-_style_module_css-nested1/nested3:_-_style_module_css-nested3/ident:_-_style_module_css-ident/localkeyframes:_-_style_module_css-localkeyframes/pos1x:---_style_module_css-pos1x/pos1y:---_style_module_css-pos1y/pos2x:---_style_module_css-pos2x/pos2y:---_style_module_css-pos2y/localkeyframes2:_-_style_module_css-localkeyframes2/animation:_-_style_module_css-animation/vars:_-_style_module_css-vars/local-color:---_style_module_css-local-color/globalVars:_-_style_module_css-globalVars/wideScreenClass:_-_style_module_css-wideScreenClass/narrowScreenClass:_-_style_module_css-narrowScreenClass/displayGridInSupports:_-_style_module_css-displayGridInSupports/floatRightInNegativeSupports:_-_style_module_css-floatRightInNegativeSupports/displayFlexInMediaInSupports:_-_style_module_css-displayFlexInMediaInSupports/displayFlexInSupportsInMedia:_-_style_module_css-displayFlexInSupportsInMedia/displayFlexInSupportsInMediaUpperCase:_-_style_module_css-displayFlexInSupportsInMediaUpperCase/animationUpperCase:_-_style_module_css-animationUpperCase/localkeyframesUPPERCASE:_-_style_module_css-localkeyframesUPPERCASE/localkeyframes2UPPPERCASE:_-_style_module_css-localkeyframes2UPPPERCASE/localUpperCase:_-_style_module_css-localUpperCase/VARS:_-_style_module_css-VARS/LOCAL-COLOR:---_style_module_css-LOCAL-COLOR/globalVarsUpperCase:_-_style_module_css-globalVarsUpperCase/inSupportScope:_-_style_module_css-inSupportScope/a:_-_style_module_css-a/animationName:_-_style_module_css-animationName/b:_-_style_module_css-b/c:_-_style_module_css-c/d:_-_style_module_css-d/animation-name:---_style_module_css-animation-name/mozAnimationName:_-_style_module_css-mozAnimationName/my-color:---_style_module_css-my-color/c0ffee:_-_style_module_css-c0ffee/padding-sm:_-_style_module_css-padding-sm/padding-lg:_-_style_module_css-padding-lg/nested-pure:_-_style_module_css-nested-pure/nested-media:_-_style_module_css-nested-media/nested-supports:_-_style_module_css-nested-supports/nested-layer:_-_style_module_css-nested-layer/not-selector-inside:_-_style_module_css-not-selector-inside/nested-var:_-_style_module_css-nested-var/again:_-_style_module_css-again/nested-with-local-pseudo:_-_style_module_css-nested-with-local-pseudo/local-nested:_-_style_module_css-local-nested/bar:_-_style_module_css-bar/id-foo:_-_style_module_css-id-foo/id-bar:_-_style_module_css-id-bar/nested-parens:_-_style_module_css-nested-parens/local-in-global:_-_style_module_css-local-in-global/in-local-global-scope:_-_style_module_css-in-local-global-scope/class-local-scope:_-_style_module_css-class-local-scope/class-in-container:_-_style_module_css-class-in-container/deep-class-in-container:_-_style_module_css-deep-class-in-container/placeholder-gray-700:_-_style_module_css-placeholder-gray-700/placeholder-opacity:---_style_module_css-placeholder-opacity/test:---_style_module_css-test/baz:---_style_module_css-baz/slidein:_-_style_module_css-slidein/my-global-class-again:_-_style_module_css-my-global-class-again/first-nested:_-_style_module_css-first-nested/first-nested-nested:_-_style_module_css-first-nested-nested/first-nested-at-rule:_-_style_module_css-first-nested-at-rule/first-nested-nested-at-rule-deep:_-_style_module_css-first-nested-nested-at-rule-deep/foo:---_style_module_css-foo/&\\\\.\\\\/style\\\\.module\\\\.css,myCssClass:_-_style_module_my-css-myCssClass/&\\\\.\\\\/style\\\\.module\\\\.my-css,&\\\\.\\\\/style\\\\.module\\\\.css\\\\.invalid,UnusedClassName:_-_identifiers_module_css-UnusedClassName/variable-unused-class:---_identifiers_module_css-variable-unused-class/UsedClassName:_-_identifiers_module_css-UsedClassName/variable-used-class:---_identifiers_module_css-variable-used-class/&\\\\.\\\\/identifiers\\\\.module\\\\.css;}" +`; + +exports[`ConfigCacheTestCases css css-modules exported tests should allow to create css modules 2`] = ` +"/*!******************************!*\\\\ + !*** css ./style.module.css ***! + \\\\******************************/ +.my-app-235-zg { + color: red; +} + +.my-app-235-Hi, +.my-app-235-OB .global, +.my-app-235-VE { + color: green; +} + +.global .my-app-235-O2 { + color: yellow; +} + +.my-app-235-Vj.global.my-app-235-OH { + color: blue; +} + +.my-app-235-H5 div:not(.disabled, .mButtonDisabled, .tipOnly) { + pointer-events: initial !important; +} + +.my-app-235-aq :is(div.parent1.child1.vertical-tiny, + div.parent1.child1.vertical-small, + div.otherDiv.horizontal-tiny, + div.otherDiv.horizontal-small div.description) { + max-height: 0; + margin: 0; + overflow: hidden; +} + +.my-app-235-VN :matches(div.parent1.child1.vertical-tiny, + div.parent1.child1.vertical-small, + div.otherDiv.horizontal-tiny, + div.otherDiv.horizontal-small div.description) { + max-height: 0; + margin: 0; + overflow: hidden; +} + +.my-app-235-VM :where(div.parent1.child1.vertical-tiny, + div.parent1.child1.vertical-small, + div.otherDiv.horizontal-tiny, + div.otherDiv.horizontal-small div.description) { + max-height: 0; + margin: 0; + overflow: hidden; +} + +.my-app-235-AO div:has(.disabled, .mButtonDisabled, .tipOnly) { + pointer-events: initial !important; +} + +.my-app-235-Hq div:current(p, span) { + background-color: yellow; +} + +.my-app-235-O4 div:past(p, span) { + display: none; +} + +.my-app-235-Hb div:future(p, span) { + background-color: yellow; +} + +.my-app-235-OP div:-moz-any(ol, ul, menu, dir) { + list-style-type: square; +} + +.my-app-235-Hw li:-webkit-any(:first-child, :last-child) { + background-color: aquamarine; +} + +.my-app-235-VN :matches(div.parent1.child1.vertical-tiny, + div.parent1.child1.vertical-small, + div.otherDiv.horizontal-tiny, + div.otherDiv.horizontal-small div.description) { + max-height: 0; + margin: 0; + overflow: hidden; +} + +.my-app-235-nb.nested2.my-app-235-\\\\$Q { + color: pink; +} + +#my-app-235-bD { + color: purple; +} + +@keyframes my-app-235-\\\\$t{ + 0% { + left: var(--my-app-235-qi); + top: var(--my-app-235-xB); + color: var(--theme-color1); + } + 100% { + left: var(--my-app-235-\\\\$6); + top: var(--my-app-235-gJ); + color: var(--theme-color2); + } +} + +@keyframes my-app-235-x{ + 0% { + left: 0; + } + 100% { + left: 100px; + } +} + +.my-app-235-lY { + animation-name: my-app-235-\\\\$t; + animation: 3s ease-in 1s 2 reverse both paused my-app-235-\\\\$t, my-app-235-x; + --my-app-235-qi: 0px; + --my-app-235-xB: 0px; + --my-app-235-\\\\$6: 10px; + --my-app-235-gJ: 20px; +} + +/* .composed { + composes: local1; + composes: local2; +} */ + +.my-app-235-f { + color: var(--my-app-235-uz); + --my-app-235-uz: red; +} + +.my-app-235-aK { + color: var(--global-color); + --global-color: red; +} + +@media (min-width: 1600px) { + .my-app-235-a7 { + color: var(--my-app-235-uz); + --my-app-235-uz: green; + } +} + +@media screen and (max-width: 600px) { + .my-app-235-uf { + color: var(--my-app-235-uz); + --my-app-235-uz: purple; + } +} + +@supports (display: grid) { + .my-app-235-sW { + display: grid; + } +} + +@supports not (display: grid) { + .my-app-235-TZ { + float: right; + } +} + +@supports (display: flex) { + @media screen and (min-width: 900px) { + .my-app-235-aY { + display: flex; + } + } +} + +@media screen and (min-width: 900px) { + @supports (display: flex) { + .my-app-235-II { + display: flex; + } + } +} + +@MEDIA screen and (min-width: 900px) { + @SUPPORTS (display: flex) { + .my-app-235-ij { + display: flex; + } + } +} + +.animationUpperCase { + ANIMATION-NAME: my-app-235-zG; + ANIMATION: 3s ease-in 1s 2 reverse both paused my-app-235-zG, my-app-235-Dk; + --my-app-235-qi: 0px; + --my-app-235-xB: 0px; + --my-app-235-\\\\$6: 10px; + --my-app-235-gJ: 20px; +} + +@KEYFRAMES my-app-235-zG{ + 0% { + left: VAR(--my-app-235-qi); + top: VAR(--my-app-235-xB); + color: VAR(--theme-color1); + } + 100% { + left: VAR(--my-app-235-\\\\$6); + top: VAR(--my-app-235-gJ); + color: VAR(--theme-color2); + } +} + +@KEYframes my-app-235-Dk{ + 0% { + left: 0; + } + 100% { + left: 100px; + } +} + +.globalUpperCase .localUpperCase { + color: yellow; +} + +.my-app-235-XE { + color: VAR(--my-app-235-I0); + --my-app-235-I0: red; +} + +.my-app-235-wt { + COLOR: VAR(--GLOBAR-COLOR); + --GLOBAR-COLOR: red; +} + +@supports (top: env(safe-area-inset-top, 0)) { + .my-app-235-nc { + color: red; + } +} + +.a { + animation: 3s my-app-235-iZ; + -webkit-animation: 3s my-app-235-iZ; +} + +.b { + animation: my-app-235-iZ 3s; + -webkit-animation: my-app-235-iZ 3s; +} + +.c { + animation-name: my-app-235-iZ; + -webkit-animation-name: my-app-235-iZ; +} + +.d { + --my-app-235-ZP: animationName; +} + +@keyframes my-app-235-iZ{ + 0% { + background: white; + } + 100% { + background: red; + } +} + +@-webkit-keyframes my-app-235-iZ{ + 0% { + background: white; + } + 100% { + background: red; + } +} + +@-moz-keyframes my-app-235-M6{ + 0% { + background: white; + } + 100% { + background: red; + } +} + +@counter-style thumbs { + system: cyclic; + symbols: \\"\\\\1F44D\\"; + suffix: \\" \\"; +} + +@font-feature-values Font One { + @styleset { + nice-style: 12; + } +} + +/* At-rule for \\"nice-style\\" in Font Two */ +@font-feature-values Font Two { + @styleset { + nice-style: 4; + } +} + +@property --my-app-235-rX{ + syntax: \\"\\"; + inherits: false; + initial-value: #c0ffee; +} + +.my-app-235-zg { + color: var(--my-app-235-rX); +} + +@layer utilities { + .my-app-235-dW { + padding: 0.5rem; + } + + .my-app-235-cD { + padding: 0.8rem; + } +} + +.my-app-235-zg { + color: red; + + .nested-pure { + color: red; + } + + @media screen and (min-width: 200px) { + color: blue; + + .nested-media { + color: blue; + } + } + + @supports (display: flex) { + display: flex; + + .nested-supports { + display: flex; + } + } + + @layer foo { + background: red; + + .nested-layer { + background: red; + } + } + + @container foo { + background: red; + + .nested-layer { + background: red; + } + } +} + +.not-selector-inside { + color: #fff; + opacity: 0.12; + padding: .5px; + unknown: :local(.test); + unknown1: :local .test; + unknown2: :global .test; + unknown3: :global .test; + unknown4: .foo, .bar, #bar; +} + +@unknown :local .local :global .global { + color: red; +} + +@unknown :local(.local) :global(.global) { + color: red; +} + +.nested-var { + .again { + color: var(--my-app-235-uz); + } +} + +.nested-with-local-pseudo { + color: red; + + .local-nested { + color: red; + } + + .global-nested { + color: red; + } + + .local-nested { + color: red; + } + + .global-nested { + color: red; + } + + .local-nested, .global-nested-next { + color: red; + } + + .local-nested, .global-nested-next { + color: red; + } + + .foo, .bar { + color: red; + } +} + +#id-foo { + color: red; + + #id-bar { + color: red; + } +} + +.nested-parens { + .my-app-235-VN div:has(.vertical-tiny, .vertical-small) { + max-height: 0; + margin: 0; + overflow: hidden; + } +} + +.global-foo { + .nested-global { + color: red; + } + + .local-in-global { + color: blue; + } +} + +@unknown .class { + color: red; + + .class { + color: red; + } +} + +.class .my-app-235-V0, +.class .my-app-235-V0, +.my-app-235-Ci .in-local-global-scope { + color: red; +} + +@container (width > 400px) { + .my-app-235-bK { + font-size: 1.5em; + } +} + +@container summary (min-width: 400px) { + @container (width > 400px) { + .my-app-235-Y1 { + font-size: 1.5em; + } + } +} + +:scope { + color: red; +} + +.placeholder-gray-700:-ms-input-placeholder { + --my-app-235-Y: 1; + color: #4a5568; + color: rgba(74, 85, 104, var(--my-app-235-Y)); +} +.placeholder-gray-700::-ms-input-placeholder { + --my-app-235-Y: 1; + color: #4a5568; + color: rgba(74, 85, 104, var(--my-app-235-Y)); +} +.placeholder-gray-700::placeholder { + --my-app-235-Y: 1; + color: #4a5568; + color: rgba(74, 85, 104, var(--my-app-235-Y)); +} + +:root { + --my-app-235-t6: dark; +} + +@media screen and (prefers-color-scheme: var(--my-app-235-t6)) { + .my-app-235-KR { + color: white; + } +} + +@keyframes my-app-235-Fk{ + from { + margin-left: 100%; + width: 300%; + } + + to { + margin-left: 0%; + width: 100%; + } +} + +.my-app-235-zg { + animation: + foo var(--my-app-235-ZP) 3s, + var(--my-app-235-ZP) 3s, + 3s linear 1s infinite running my-app-235-Fk, + 3s linear env(foo, var(--my-app-235-KR)) infinite running my-app-235-Fk; +} + +:root { + --my-app-235-KR: 10px; +} + +.my-app-235-zg { + bar: env(foo, var(--my-app-235-KR)); +} + +.global-foo, .bar { + .local-in-global { + color: blue; + } + + @media screen { + .my-global-class-again, + .my-global-class-again { + color: red; + } + } +} + +.first-nested { + .first-nested-nested { + color: red; + } +} + +.first-nested-at-rule { + @media screen { + .first-nested-nested-at-rule-deep { + color: red; + } + } +} + +.again-global { + color:red; +} + +.again-again-global { + .again-again-global { + color: red; + } +} + +:root { + --foo: red; +} + +.again-again-global { + color: var(--foo); + + .again-again-global { + color: var(--foo); + } +} + +.again-again-global { + animation: slidein 3s; + + .again-again-global, .my-app-235-zg, .my-app-235-nb.nested2.my-app-235-\\\\$Q { + animation: my-app-235-Fk 3s; + } + + .my-app-235-OB .global, + .my-app-235-VE { + color: red; + } +} + +@unknown var(--foo) { + color: red; +} + +.my-app-235-zg { + .my-app-235-zg { + .my-app-235-zg { + .my-app-235-zg {} + } + } +} + +.my-app-235-zg { + .my-app-235-zg { + .my-app-235-zg { + .my-app-235-zg { + animation: my-app-235-Fk 3s; + } + } + } +} + +.my-app-235-zg { + animation: my-app-235-Fk 3s; + .my-app-235-zg { + animation: my-app-235-Fk 3s; + .my-app-235-zg { + animation: my-app-235-Fk 3s; + .my-app-235-zg { + animation: my-app-235-Fk 3s; + } + } + } +} + +/*!*********************************!*\\\\ + !*** css ./style.module.my-css ***! + \\\\*********************************/ +.my-app-666-k { + color: red; +} + +/*!**************************************!*\\\\ + !*** css ./style.module.css.invalid ***! + \\\\**************************************/ +.class { + color: teal; +} + +/*!************************************!*\\\\ + !*** css ./identifiers.module.css ***! + \\\\************************************/ +.UnusedClassName{ + color: red; + padding: var(--my-app-194-RJ); + --my-app-194-RJ: 10px; +} + +.my-app-194-ZL { + color: green; + padding: var(--my-app-194-c5); + --my-app-194-c5: 10px; +} + +head{--webpack-my-app-226:zg:my-app-235-ฤ€/Hiฤ‚ฤ„ฤ†ฤˆฤŠฤŒฤ/OBฤ’ฤ…ฤ‡ฤ‰ฤ‹-ฤš/VEฤœฤ”ฤŸฤŒฤคฤ™2ฤฆฤžฤ–ฤก2ฤฃjฤญฤ•ฤ Vjฤ™HฤดฤจฤกHฤ5ฤปฤฏH5/aqลฤ ล†ฤฃNลˆฤฉNฤฃMล-VM/AOล’ล—ฤล‡ฤƒฤฤตฤ—qฤ™4ล’O4ฤbล’Hbฤ™PลคPฤwลฉw/nลจลฤงฤฏลต/\\\\$Qล’ลผQ/bDล’ฦƒลป$tลฟฦˆ/qฤ‘--ลทฤฎฤ ฦ/xฤ›ฦฦ‘ลŸ-ฦ–ฦ‡6:ฦ˜ฤ“ฦ’ฤŒลผ6/gJฦŸฦฦกฦšฦงฦ•ล’x/lYล’ฦฒ/fล’f/uzฦฉฦ™ฤผฦปล…Kล’aKล…7วƒ7ฦบฦทฦพฤฏuฦนsWล’ว/TZล’ว•ล…ฦณวŒล‰Y/IIล’วŸ/iฤณว›ฤŒวค/zGล’วช/Dkล’วฏ/Xฤฅวฆ-วดวž0ฦฝฦซฤผI0/wฦ‰วถศลดcล’ncวฃว–วถiZ/Zลญฦ ลžฤผศ/Mฦžวถศ—/rXวปศ“ฤฏศœ/dว‘วถศฃ/cฦ„วถศจฤฃวบวถVวฟCฤ‘วถศฑฦ‚ว‚วถbว…Y1ล’ศบ/ฦณศ’ลธฤ วtฦžษ€ฦข-ษ„/KRศžษฤŒษ‹/Fวฐวถษ’/&_ฤ–,ษ“วผ6ษ-kษ–_ษ6,ษ—81ษคRฦจษ†ฤˆ194-ษชศLฤปษฎษฐZLศงล€ษฌ-ษถ-cล„ษ—ษถ;}" +`; + +exports[`ConfigCacheTestCases css css-modules exported tests should allow to create css modules: dev 1`] = ` +Object { + "UsedClassName": "-_identifiers_module_css-UsedClassName", + "VARS": "---_style_module_css-LOCAL-COLOR -_style_module_css-VARS undefined -_style_module_css-globalVarsUpperCase", + "animation": "-_style_module_css-animation", + "animationName": "-_style_module_css-animationName", + "class": "-_style_module_css-class", + "classInContainer": "-_style_module_css-class-in-container", + "classLocalScope": "-_style_module_css-class-local-scope", + "cssModuleWithCustomFileExtension": "-_style_module_my-css-myCssClass", + "currentWmultiParams": "-_style_module_css-local12", + "deepClassInContainer": "-_style_module_css-deep-class-in-container", + "displayFlexInSupportsInMediaUpperCase": "-_style_module_css-displayFlexInSupportsInMediaUpperCase", + "exportLocalVarsShouldCleanup": "false false", + "futureWmultiParams": "-_style_module_css-local14", + "global": undefined, + "hasWmultiParams": "-_style_module_css-local11", + "ident": "-_style_module_css-ident", + "inLocalGlobalScope": "-_style_module_css-in-local-global-scope", + "inSupportScope": "-_style_module_css-inSupportScope", + "isWmultiParams": "-_style_module_css-local8", + "keyframes": "-_style_module_css-localkeyframes", + "keyframesUPPERCASE": "-_style_module_css-localkeyframesUPPERCASE", + "local": "-_style_module_css-local1 -_style_module_css-local2 -_style_module_css-local3 -_style_module_css-local4", + "local2": "-_style_module_css-local5 -_style_module_css-local6", + "localkeyframes2UPPPERCASE": "-_style_module_css-localkeyframes2UPPPERCASE", + "matchesWmultiParams": "-_style_module_css-local9", + "media": "-_style_module_css-wideScreenClass", + "mediaInSupports": "-_style_module_css-displayFlexInMediaInSupports", + "mediaWithOperator": "-_style_module_css-narrowScreenClass", + "mozAnimationName": "-_style_module_css-mozAnimationName", + "mozAnyWmultiParams": "-_style_module_css-local15", + "myColor": "---_style_module_css-my-color", + "nested": "-_style_module_css-nested1 undefined -_style_module_css-nested3", + "notAValidCssModuleExtension": true, + "notWmultiParams": "-_style_module_css-local7", + "paddingLg": "-_style_module_css-padding-lg", + "paddingSm": "-_style_module_css-padding-sm", + "pastWmultiParams": "-_style_module_css-local13", + "supports": "-_style_module_css-displayGridInSupports", + "supportsInMedia": "-_style_module_css-displayFlexInSupportsInMedia", + "supportsWithOperator": "-_style_module_css-floatRightInNegativeSupports", + "vars": "---_style_module_css-local-color -_style_module_css-vars undefined -_style_module_css-globalVars", + "webkitAnyWmultiParams": "-_style_module_css-local16", + "whereWmultiParams": "-_style_module_css-local10", +} +`; + +exports[`ConfigCacheTestCases css css-modules exported tests should allow to create css modules: prod 1`] = ` +Object { + "UsedClassName": "my-app-194-ZL", + "VARS": "--my-app-235-I0 my-app-235-XE undefined my-app-235-wt", + "animation": "my-app-235-lY", + "animationName": "my-app-235-iZ", + "class": "my-app-235-zg", + "classInContainer": "my-app-235-bK", + "classLocalScope": "my-app-235-Ci", + "cssModuleWithCustomFileExtension": "my-app-666-k", + "currentWmultiParams": "my-app-235-Hq", + "deepClassInContainer": "my-app-235-Y1", + "displayFlexInSupportsInMediaUpperCase": "my-app-235-ij", + "exportLocalVarsShouldCleanup": "false false", + "futureWmultiParams": "my-app-235-Hb", + "global": undefined, + "hasWmultiParams": "my-app-235-AO", + "ident": "my-app-235-bD", + "inLocalGlobalScope": "my-app-235-V0", + "inSupportScope": "my-app-235-nc", + "isWmultiParams": "my-app-235-aq", + "keyframes": "my-app-235-$t", + "keyframesUPPERCASE": "my-app-235-zG", + "local": "my-app-235-Hi my-app-235-OB my-app-235-VE my-app-235-O2", + "local2": "my-app-235-Vj my-app-235-OH", + "localkeyframes2UPPPERCASE": "my-app-235-Dk", + "matchesWmultiParams": "my-app-235-VN", + "media": "my-app-235-a7", + "mediaInSupports": "my-app-235-aY", + "mediaWithOperator": "my-app-235-uf", + "mozAnimationName": "my-app-235-M6", + "mozAnyWmultiParams": "my-app-235-OP", + "myColor": "--my-app-235-rX", + "nested": "my-app-235-nb undefined my-app-235-$Q", + "notAValidCssModuleExtension": true, + "notWmultiParams": "my-app-235-H5", + "paddingLg": "my-app-235-cD", + "paddingSm": "my-app-235-dW", + "pastWmultiParams": "my-app-235-O4", + "supports": "my-app-235-sW", + "supportsInMedia": "my-app-235-II", + "supportsWithOperator": "my-app-235-TZ", + "vars": "--my-app-235-uz my-app-235-f undefined my-app-235-aK", + "webkitAnyWmultiParams": "my-app-235-Hw", + "whereWmultiParams": "my-app-235-VM", +} +`; + +exports[`ConfigCacheTestCases css css-modules-broken-keyframes exported tests should allow to create css modules: prod 1`] = ` +Object { + "class": "my-app-235-z", +} +`; + +exports[`ConfigCacheTestCases css css-modules-in-node exported tests should allow to create css modules: dev 1`] = ` +Object { + "UsedClassName": "-_identifiers_module_css-UsedClassName", + "VARS": "---_style_module_css-LOCAL-COLOR -_style_module_css-VARS undefined -_style_module_css-globalVarsUpperCase", + "animation": "-_style_module_css-animation", + "animationName": "-_style_module_css-animationName", + "class": "-_style_module_css-class", + "classInContainer": "-_style_module_css-class-in-container", + "classLocalScope": "-_style_module_css-class-local-scope", + "cssModuleWithCustomFileExtension": "-_style_module_my-css-myCssClass", + "currentWmultiParams": "-_style_module_css-local12", + "deepClassInContainer": "-_style_module_css-deep-class-in-container", + "displayFlexInSupportsInMediaUpperCase": "-_style_module_css-displayFlexInSupportsInMediaUpperCase", + "exportLocalVarsShouldCleanup": "false false", + "futureWmultiParams": "-_style_module_css-local14", + "global": undefined, + "hasWmultiParams": "-_style_module_css-local11", + "ident": "-_style_module_css-ident", + "inLocalGlobalScope": "-_style_module_css-in-local-global-scope", + "inSupportScope": "-_style_module_css-inSupportScope", + "isWmultiParams": "-_style_module_css-local8", + "keyframes": "-_style_module_css-localkeyframes", + "keyframesUPPERCASE": "-_style_module_css-localkeyframesUPPERCASE", + "local": "-_style_module_css-local1 -_style_module_css-local2 -_style_module_css-local3 -_style_module_css-local4", + "local2": "-_style_module_css-local5 -_style_module_css-local6", + "localkeyframes2UPPPERCASE": "-_style_module_css-localkeyframes2UPPPERCASE", + "matchesWmultiParams": "-_style_module_css-local9", + "media": "-_style_module_css-wideScreenClass", + "mediaInSupports": "-_style_module_css-displayFlexInMediaInSupports", + "mediaWithOperator": "-_style_module_css-narrowScreenClass", + "mozAnimationName": "-_style_module_css-mozAnimationName", + "mozAnyWmultiParams": "-_style_module_css-local15", + "myColor": "---_style_module_css-my-color", + "nested": "-_style_module_css-nested1 undefined -_style_module_css-nested3", + "notAValidCssModuleExtension": true, + "notWmultiParams": "-_style_module_css-local7", + "paddingLg": "-_style_module_css-padding-lg", + "paddingSm": "-_style_module_css-padding-sm", + "pastWmultiParams": "-_style_module_css-local13", + "supports": "-_style_module_css-displayGridInSupports", + "supportsInMedia": "-_style_module_css-displayFlexInSupportsInMedia", + "supportsWithOperator": "-_style_module_css-floatRightInNegativeSupports", + "vars": "---_style_module_css-local-color -_style_module_css-vars undefined -_style_module_css-globalVars", + "webkitAnyWmultiParams": "-_style_module_css-local16", + "whereWmultiParams": "-_style_module_css-local10", +} +`; + +exports[`ConfigCacheTestCases css css-modules-in-node exported tests should allow to create css modules: prod 1`] = ` +Object { + "UsedClassName": "my-app-194-ZL", + "VARS": "--my-app-235-I0 my-app-235-XE undefined my-app-235-wt", + "animation": "my-app-235-lY", + "animationName": "my-app-235-iZ", + "class": "my-app-235-zg", + "classInContainer": "my-app-235-bK", + "classLocalScope": "my-app-235-Ci", + "cssModuleWithCustomFileExtension": "my-app-666-k", + "currentWmultiParams": "my-app-235-Hq", + "deepClassInContainer": "my-app-235-Y1", + "displayFlexInSupportsInMediaUpperCase": "my-app-235-ij", + "exportLocalVarsShouldCleanup": "false false", + "futureWmultiParams": "my-app-235-Hb", + "global": undefined, + "hasWmultiParams": "my-app-235-AO", + "ident": "my-app-235-bD", + "inLocalGlobalScope": "my-app-235-V0", + "inSupportScope": "my-app-235-nc", + "isWmultiParams": "my-app-235-aq", + "keyframes": "my-app-235-$t", + "keyframesUPPERCASE": "my-app-235-zG", + "local": "my-app-235-Hi my-app-235-OB my-app-235-VE my-app-235-O2", + "local2": "my-app-235-Vj my-app-235-OH", + "localkeyframes2UPPPERCASE": "my-app-235-Dk", + "matchesWmultiParams": "my-app-235-VN", + "media": "my-app-235-a7", + "mediaInSupports": "my-app-235-aY", + "mediaWithOperator": "my-app-235-uf", + "mozAnimationName": "my-app-235-M6", + "mozAnyWmultiParams": "my-app-235-OP", + "myColor": "--my-app-235-rX", + "nested": "my-app-235-nb undefined my-app-235-$Q", + "notAValidCssModuleExtension": true, + "notWmultiParams": "my-app-235-H5", + "paddingLg": "my-app-235-cD", + "paddingSm": "my-app-235-dW", + "pastWmultiParams": "my-app-235-O4", + "supports": "my-app-235-sW", + "supportsInMedia": "my-app-235-II", + "supportsWithOperator": "my-app-235-TZ", + "vars": "--my-app-235-uz my-app-235-f undefined my-app-235-aK", + "webkitAnyWmultiParams": "my-app-235-Hw", + "whereWmultiParams": "my-app-235-VM", +} +`; + +exports[`ConfigCacheTestCases css css-modules-in-node exported tests should allow to create css modules: prod 2`] = ` +Object { + "UsedClassName": "my-app-194-ZL", + "VARS": "--my-app-235-I0 my-app-235-XE undefined my-app-235-wt", + "animation": "my-app-235-lY", + "animationName": "my-app-235-iZ", + "class": "my-app-235-zg", + "classInContainer": "my-app-235-bK", + "classLocalScope": "my-app-235-Ci", + "cssModuleWithCustomFileExtension": "my-app-666-k", + "currentWmultiParams": "my-app-235-Hq", + "deepClassInContainer": "my-app-235-Y1", + "displayFlexInSupportsInMediaUpperCase": "my-app-235-ij", + "exportLocalVarsShouldCleanup": "false false", + "futureWmultiParams": "my-app-235-Hb", + "global": undefined, + "hasWmultiParams": "my-app-235-AO", + "ident": "my-app-235-bD", + "inLocalGlobalScope": "my-app-235-V0", + "inSupportScope": "my-app-235-nc", + "isWmultiParams": "my-app-235-aq", + "keyframes": "my-app-235-$t", + "keyframesUPPERCASE": "my-app-235-zG", + "local": "my-app-235-Hi my-app-235-OB my-app-235-VE my-app-235-O2", + "local2": "my-app-235-Vj my-app-235-OH", + "localkeyframes2UPPPERCASE": "my-app-235-Dk", + "matchesWmultiParams": "my-app-235-VN", + "media": "my-app-235-a7", + "mediaInSupports": "my-app-235-aY", + "mediaWithOperator": "my-app-235-uf", + "mozAnimationName": "my-app-235-M6", + "mozAnyWmultiParams": "my-app-235-OP", + "myColor": "--my-app-235-rX", + "nested": "my-app-235-nb undefined my-app-235-$Q", + "notAValidCssModuleExtension": true, + "notWmultiParams": "my-app-235-H5", + "paddingLg": "my-app-235-cD", + "paddingSm": "my-app-235-dW", + "pastWmultiParams": "my-app-235-O4", + "supports": "my-app-235-sW", + "supportsInMedia": "my-app-235-II", + "supportsWithOperator": "my-app-235-TZ", + "vars": "--my-app-235-uz my-app-235-f undefined my-app-235-aK", + "webkitAnyWmultiParams": "my-app-235-Hw", + "whereWmultiParams": "my-app-235-VM", +} +`; + +exports[`ConfigCacheTestCases css css-modules-in-node exported tests should allow to import css modules: class-dev 1`] = `"-_style_module_css-class"`; + +exports[`ConfigCacheTestCases css css-modules-in-node exported tests should allow to import css modules: class-prod 1`] = `"my-app-235-zg"`; + +exports[`ConfigCacheTestCases css css-modules-in-node exported tests should allow to import css modules: class-prod 2`] = `"my-app-235-zg"`; + +exports[`ConfigCacheTestCases css css-modules-in-node exported tests should allow to import css modules: local1-dev 1`] = `"-_style_module_css-local1"`; + +exports[`ConfigCacheTestCases css css-modules-in-node exported tests should allow to import css modules: local1-prod 1`] = `"my-app-235-Hi"`; + +exports[`ConfigCacheTestCases css css-modules-in-node exported tests should allow to import css modules: local1-prod 2`] = `"my-app-235-Hi"`; + +exports[`ConfigCacheTestCases css css-modules-in-node exported tests should allow to import css modules: local2-dev 1`] = `"-_style_module_css-local2"`; + +exports[`ConfigCacheTestCases css css-modules-in-node exported tests should allow to import css modules: local2-prod 1`] = `"my-app-235-OB"`; + +exports[`ConfigCacheTestCases css css-modules-in-node exported tests should allow to import css modules: local2-prod 2`] = `"my-app-235-OB"`; + +exports[`ConfigCacheTestCases css css-modules-in-node exported tests should allow to import css modules: local3-dev 1`] = `"-_style_module_css-local3"`; + +exports[`ConfigCacheTestCases css css-modules-in-node exported tests should allow to import css modules: local3-prod 1`] = `"my-app-235-VE"`; + +exports[`ConfigCacheTestCases css css-modules-in-node exported tests should allow to import css modules: local3-prod 2`] = `"my-app-235-VE"`; + +exports[`ConfigCacheTestCases css css-modules-in-node exported tests should allow to import css modules: local4-dev 1`] = `"-_style_module_css-local4"`; + +exports[`ConfigCacheTestCases css css-modules-in-node exported tests should allow to import css modules: local4-prod 1`] = `"my-app-235-O2"`; + +exports[`ConfigCacheTestCases css css-modules-in-node exported tests should allow to import css modules: local4-prod 2`] = `"my-app-235-O2"`; + +exports[`ConfigCacheTestCases css exports-convention exported tests should have correct convention for css exports name 1`] = ` +Object { + "btn--info_is-disabled_1": "-_style_module_css_as-is-btn--info_is-disabled_1", + "btn-info_is-disabled": "-_style_module_css_as-is-btn-info_is-disabled", + "foo": "bar", + "foo_bar": "-_style_module_css_as-is-foo_bar", + "my-btn-info_is-disabled": "value", + "simple": "-_style_module_css_as-is-simple", +} +`; + +exports[`ConfigCacheTestCases css exports-convention exported tests should have correct convention for css exports name 2`] = ` +Object { + "btn--info_is-disabled_1": "-_style_module_css_camel-case-btn--info_is-disabled_1", + "btn-info_is-disabled": "-_style_module_css_camel-case-btn-info_is-disabled", + "btnInfoIsDisabled": "-_style_module_css_camel-case-btn-info_is-disabled", + "btnInfoIsDisabled1": "-_style_module_css_camel-case-btn--info_is-disabled_1", + "foo": "bar", + "fooBar": "-_style_module_css_camel-case-foo_bar", + "foo_bar": "-_style_module_css_camel-case-foo_bar", + "my-btn-info_is-disabled": "value", + "myBtnInfoIsDisabled": "value", + "simple": "-_style_module_css_camel-case-simple", +} +`; + +exports[`ConfigCacheTestCases css exports-convention exported tests should have correct convention for css exports name 3`] = ` +Object { + "btnInfoIsDisabled": "-_style_module_css_camel-case-only-btnInfoIsDisabled", + "btnInfoIsDisabled1": "-_style_module_css_camel-case-only-btnInfoIsDisabled1", + "foo": "bar", + "fooBar": "-_style_module_css_camel-case-only-fooBar", + "myBtnInfoIsDisabled": "value", + "simple": "-_style_module_css_camel-case-only-simple", +} +`; + +exports[`ConfigCacheTestCases css exports-convention exported tests should have correct convention for css exports name 4`] = ` +Object { + "btn--info_is-disabled_1": "-_style_module_css_dashes-btn--info_is-disabled_1", + "btn-info_is-disabled": "-_style_module_css_dashes-btn-info_is-disabled", + "btnInfo_isDisabled": "-_style_module_css_dashes-btn-info_is-disabled", + "btnInfo_isDisabled_1": "-_style_module_css_dashes-btn--info_is-disabled_1", + "foo": "bar", + "foo_bar": "-_style_module_css_dashes-foo_bar", + "my-btn-info_is-disabled": "value", + "myBtnInfo_isDisabled": "value", + "simple": "-_style_module_css_dashes-simple", +} +`; + +exports[`ConfigCacheTestCases css exports-convention exported tests should have correct convention for css exports name 5`] = ` +Object { + "btnInfo_isDisabled": "-_style_module_css_dashes-only-btnInfo_isDisabled", + "btnInfo_isDisabled_1": "-_style_module_css_dashes-only-btnInfo_isDisabled_1", + "foo": "bar", + "foo_bar": "-_style_module_css_dashes-only-foo_bar", + "myBtnInfo_isDisabled": "value", + "simple": "-_style_module_css_dashes-only-simple", +} +`; + +exports[`ConfigCacheTestCases css exports-convention exported tests should have correct convention for css exports name 6`] = ` +Object { + "BTN--INFO_IS-DISABLED_1": "-_style_module_css_upper-BTN--INFO_IS-DISABLED_1", + "BTN-INFO_IS-DISABLED": "-_style_module_css_upper-BTN-INFO_IS-DISABLED", + "FOO": "bar", + "FOO_BAR": "-_style_module_css_upper-FOO_BAR", + "MY-BTN-INFO_IS-DISABLED": "value", + "SIMPLE": "-_style_module_css_upper-SIMPLE", +} +`; + +exports[`ConfigCacheTestCases css exports-convention exported tests should have correct convention for css exports name 7`] = ` +Object { + "btn--info_is-disabled_1": "-_style_module_css_as-is-btn--info_is-disabled_1", + "btn-info_is-disabled": "-_style_module_css_as-is-btn-info_is-disabled", + "foo": "bar", + "foo_bar": "-_style_module_css_as-is-foo_bar", + "my-btn-info_is-disabled": "value", + "simple": "-_style_module_css_as-is-simple", +} +`; + +exports[`ConfigCacheTestCases css exports-convention exported tests should have correct convention for css exports name 8`] = ` +Object { + "btn--info_is-disabled_1": "-_style_module_css_camel-case-btn--info_is-disabled_1", + "btn-info_is-disabled": "-_style_module_css_camel-case-btn-info_is-disabled", + "btnInfoIsDisabled": "-_style_module_css_camel-case-btn-info_is-disabled", + "btnInfoIsDisabled1": "-_style_module_css_camel-case-btn--info_is-disabled_1", + "foo": "bar", + "fooBar": "-_style_module_css_camel-case-foo_bar", + "foo_bar": "-_style_module_css_camel-case-foo_bar", + "my-btn-info_is-disabled": "value", + "myBtnInfoIsDisabled": "value", + "simple": "-_style_module_css_camel-case-simple", +} +`; + +exports[`ConfigCacheTestCases css exports-convention exported tests should have correct convention for css exports name 9`] = ` +Object { + "btnInfoIsDisabled": "-_style_module_css_camel-case-only-btnInfoIsDisabled", + "btnInfoIsDisabled1": "-_style_module_css_camel-case-only-btnInfoIsDisabled1", + "foo": "bar", + "fooBar": "-_style_module_css_camel-case-only-fooBar", + "myBtnInfoIsDisabled": "value", + "simple": "-_style_module_css_camel-case-only-simple", +} +`; + +exports[`ConfigCacheTestCases css exports-convention exported tests should have correct convention for css exports name 10`] = ` +Object { + "btn--info_is-disabled_1": "-_style_module_css_dashes-btn--info_is-disabled_1", + "btn-info_is-disabled": "-_style_module_css_dashes-btn-info_is-disabled", + "btnInfo_isDisabled": "-_style_module_css_dashes-btn-info_is-disabled", + "btnInfo_isDisabled_1": "-_style_module_css_dashes-btn--info_is-disabled_1", + "foo": "bar", + "foo_bar": "-_style_module_css_dashes-foo_bar", + "my-btn-info_is-disabled": "value", + "myBtnInfo_isDisabled": "value", + "simple": "-_style_module_css_dashes-simple", +} +`; + +exports[`ConfigCacheTestCases css exports-convention exported tests should have correct convention for css exports name 11`] = ` +Object { + "btnInfo_isDisabled": "-_style_module_css_dashes-only-btnInfo_isDisabled", + "btnInfo_isDisabled_1": "-_style_module_css_dashes-only-btnInfo_isDisabled_1", + "foo": "bar", + "foo_bar": "-_style_module_css_dashes-only-foo_bar", + "myBtnInfo_isDisabled": "value", + "simple": "-_style_module_css_dashes-only-simple", +} +`; + +exports[`ConfigCacheTestCases css exports-convention exported tests should have correct convention for css exports name 12`] = ` +Object { + "BTN--INFO_IS-DISABLED_1": "-_style_module_css_upper-BTN--INFO_IS-DISABLED_1", + "BTN-INFO_IS-DISABLED": "-_style_module_css_upper-BTN-INFO_IS-DISABLED", + "FOO": "bar", + "FOO_BAR": "-_style_module_css_upper-FOO_BAR", + "MY-BTN-INFO_IS-DISABLED": "value", + "SIMPLE": "-_style_module_css_upper-SIMPLE", +} +`; + +exports[`ConfigCacheTestCases css large exported tests should allow to create css modules: dev 1`] = ` +Object { + "placeholder": "my-app-_tailwind_module_css-placeholder-gray-700", +} +`; + +exports[`ConfigCacheTestCases css large exported tests should allow to create css modules: prod 1`] = ` +Object { + "placeholder": "-144-Oh6j", +} +`; + +exports[`ConfigCacheTestCases css large-css-head-data-compression exported tests should allow to create css modules: dev 1`] = ` +Object { + "placeholder": "my-app-_large_tailwind_module_css-placeholder-gray-700", +} +`; + +exports[`ConfigCacheTestCases css large-css-head-data-compression exported tests should allow to create css modules: prod 1`] = ` +Object { + "placeholder": "-658-Oh6j", +} +`; + +exports[`ConfigCacheTestCases css local-ident-name exported tests should have correct local ident for css export locals 1`] = ` +Object { + "btn--info_is-disabled_1": "-_style_module_css-btn--info_is-disabled_1", + "btn-info_is-disabled": "-_style_module_css-btn-info_is-disabled", + "color-red": "---_style_module_css-color-red", + "foo": "bar", + "foo_bar": "-_style_module_css-foo_bar", + "my-btn-info_is-disabled": "value", + "simple": "-_style_module_css-simple", +} +`; + +exports[`ConfigCacheTestCases css local-ident-name exported tests should have correct local ident for css export locals 2`] = ` +Object { + "btn--info_is-disabled_1": "de84261a9640bc9390f3", + "btn-info_is-disabled": "ecdfa12ee9c667c55af7", + "color-red": "--b7dc4acdff896aeffb60", + "foo": "bar", + "foo_bar": "d46074bbd7d5ee641466", + "my-btn-info_is-disabled": "value", + "simple": "d55fd643016d378ac454", +} +`; + +exports[`ConfigCacheTestCases css local-ident-name exported tests should have correct local ident for css export locals 3`] = ` +Object { + "btn--info_is-disabled_1": "ea850e6088d2566f677d-btn--info_is-disabled_1", + "btn-info_is-disabled": "ea850e6088d2566f677d-btn-info_is-disabled", + "color-red": "--ea850e6088d2566f677d-color-red", + "foo": "bar", + "foo_bar": "ea850e6088d2566f677d-foo_bar", + "my-btn-info_is-disabled": "value", + "simple": "ea850e6088d2566f677d-simple", +} +`; + +exports[`ConfigCacheTestCases css local-ident-name exported tests should have correct local ident for css export locals 4`] = ` +Object { + "btn--info_is-disabled_1": "./style.module__btn--info_is-disabled_1", + "btn-info_is-disabled": "./style.module__btn-info_is-disabled", + "color-red": "--./style.module__color-red", + "foo": "bar", + "foo_bar": "./style.module__foo_bar", + "my-btn-info_is-disabled": "value", + "simple": "./style.module__simple", +} +`; + +exports[`ConfigCacheTestCases css local-ident-name exported tests should have correct local ident for css export locals 5`] = ` +Object { + "btn--info_is-disabled_1": "./style.module.css__btn--info_is-disabled_1", + "btn-info_is-disabled": "./style.module.css__btn-info_is-disabled", + "color-red": "--./style.module.css__color-red", + "foo": "bar", + "foo_bar": "./style.module.css__foo_bar", + "my-btn-info_is-disabled": "value", + "simple": "./style.module.css__simple", +} +`; + +exports[`ConfigCacheTestCases css local-ident-name exported tests should have correct local ident for css export locals 6`] = ` +Object { + "btn--info_is-disabled_1": "./style.module.css__btn--info_is-disabled_1", + "btn-info_is-disabled": "./style.module.css__btn-info_is-disabled", + "color-red": "--./style.module.css__color-red", + "foo": "bar", + "foo_bar": "./style.module.css__foo_bar", + "my-btn-info_is-disabled": "value", + "simple": "./style.module.css__simple", +} +`; + +exports[`ConfigCacheTestCases css local-ident-name exported tests should have correct local ident for css export locals 7`] = ` +Object { + "btn--info_is-disabled_1": "-_style_module_css_uniqueName-id-contenthash-de84261a9640bc9390f3", + "btn-info_is-disabled": "-_style_module_css_uniqueName-id-contenthash-ecdfa12ee9c667c55af7", + "color-red": "---_style_module_css_uniqueName-id-contenthash-b7dc4acdff896aeffb60", + "foo": "bar", + "foo_bar": "-_style_module_css_uniqueName-id-contenthash-d46074bbd7d5ee641466", + "my-btn-info_is-disabled": "value", + "simple": "-_style_module_css_uniqueName-id-contenthash-d55fd643016d378ac454", +} +`; + +exports[`ConfigCacheTestCases css local-ident-name exported tests should have correct local ident for css export locals 8`] = ` +Object { + "btn--info_is-disabled_1": "./style.module.less__btn--info_is-disabled_1", + "btn-info_is-disabled": "./style.module.less__btn-info_is-disabled", + "color-red": "--./style.module.less__color-red", + "foo": "bar", + "foo_bar": "./style.module.less__foo_bar", + "my-btn-info_is-disabled": "value", + "simple": "./style.module.less__simple", +} +`; + +exports[`ConfigCacheTestCases css local-ident-name exported tests should have correct local ident for css export locals 9`] = ` +Object { + "btn--info_is-disabled_1": "-_style_module_css-btn--info_is-disabled_1", + "btn-info_is-disabled": "-_style_module_css-btn-info_is-disabled", + "color-red": "---_style_module_css-color-red", + "foo": "bar", + "foo_bar": "-_style_module_css-foo_bar", + "my-btn-info_is-disabled": "value", + "simple": "-_style_module_css-simple", +} +`; + +exports[`ConfigCacheTestCases css local-ident-name exported tests should have correct local ident for css export locals 10`] = ` +Object { + "btn--info_is-disabled_1": "de84261a9640bc9390f3", + "btn-info_is-disabled": "ecdfa12ee9c667c55af7", + "color-red": "--b7dc4acdff896aeffb60", + "foo": "bar", + "foo_bar": "d46074bbd7d5ee641466", + "my-btn-info_is-disabled": "value", + "simple": "d55fd643016d378ac454", +} +`; + +exports[`ConfigCacheTestCases css local-ident-name exported tests should have correct local ident for css export locals 11`] = ` +Object { + "btn--info_is-disabled_1": "ea850e6088d2566f677d-btn--info_is-disabled_1", + "btn-info_is-disabled": "ea850e6088d2566f677d-btn-info_is-disabled", + "color-red": "--ea850e6088d2566f677d-color-red", + "foo": "bar", + "foo_bar": "ea850e6088d2566f677d-foo_bar", + "my-btn-info_is-disabled": "value", + "simple": "ea850e6088d2566f677d-simple", +} +`; + +exports[`ConfigCacheTestCases css local-ident-name exported tests should have correct local ident for css export locals 12`] = ` +Object { + "btn--info_is-disabled_1": "./style.module__btn--info_is-disabled_1", + "btn-info_is-disabled": "./style.module__btn-info_is-disabled", + "color-red": "--./style.module__color-red", + "foo": "bar", + "foo_bar": "./style.module__foo_bar", + "my-btn-info_is-disabled": "value", + "simple": "./style.module__simple", +} +`; + +exports[`ConfigCacheTestCases css local-ident-name exported tests should have correct local ident for css export locals 13`] = ` +Object { + "btn--info_is-disabled_1": "./style.module.css__btn--info_is-disabled_1", + "btn-info_is-disabled": "./style.module.css__btn-info_is-disabled", + "color-red": "--./style.module.css__color-red", + "foo": "bar", + "foo_bar": "./style.module.css__foo_bar", + "my-btn-info_is-disabled": "value", + "simple": "./style.module.css__simple", +} +`; + +exports[`ConfigCacheTestCases css local-ident-name exported tests should have correct local ident for css export locals 14`] = ` +Object { + "btn--info_is-disabled_1": "./style.module.css__btn--info_is-disabled_1", + "btn-info_is-disabled": "./style.module.css__btn-info_is-disabled", + "color-red": "--./style.module.css__color-red", + "foo": "bar", + "foo_bar": "./style.module.css__foo_bar", + "my-btn-info_is-disabled": "value", + "simple": "./style.module.css__simple", +} +`; + +exports[`ConfigCacheTestCases css local-ident-name exported tests should have correct local ident for css export locals 15`] = ` +Object { + "btn--info_is-disabled_1": "-_style_module_css_uniqueName-id-contenthash-de84261a9640bc9390f3", + "btn-info_is-disabled": "-_style_module_css_uniqueName-id-contenthash-ecdfa12ee9c667c55af7", + "color-red": "---_style_module_css_uniqueName-id-contenthash-b7dc4acdff896aeffb60", + "foo": "bar", + "foo_bar": "-_style_module_css_uniqueName-id-contenthash-d46074bbd7d5ee641466", + "my-btn-info_is-disabled": "value", + "simple": "-_style_module_css_uniqueName-id-contenthash-d55fd643016d378ac454", +} +`; + +exports[`ConfigCacheTestCases css local-ident-name exported tests should have correct local ident for css export locals 16`] = ` +Object { + "btn--info_is-disabled_1": "./style.module.less__btn--info_is-disabled_1", + "btn-info_is-disabled": "./style.module.less__btn-info_is-disabled", + "color-red": "--./style.module.less__color-red", + "foo": "bar", + "foo_bar": "./style.module.less__foo_bar", + "my-btn-info_is-disabled": "value", + "simple": "./style.module.less__simple", +} +`; + +exports[`ConfigCacheTestCases css pure-css exported tests should compile 1`] = ` +Array [ + "/*!*******************************************!*\\\\ + !*** css ../css-modules/style.module.css ***! + \\\\*******************************************/ +.class { + color: red; +} + +.local1, +.local2 .global, +.local3 { + color: green; +} + +.global ._-_css-modules_style_module_css-local4 { + color: yellow; +} + +.local5.global.local6 { + color: blue; +} + +.local7 div:not(.disabled, .mButtonDisabled, .tipOnly) { + pointer-events: initial !important; +} + +.local8 :is(div.parent1.child1.vertical-tiny, + div.parent1.child1.vertical-small, + div.otherDiv.horizontal-tiny, + div.otherDiv.horizontal-small div.description) { + max-height: 0; + margin: 0; + overflow: hidden; +} + +.local9 :matches(div.parent1.child1.vertical-tiny, + div.parent1.child1.vertical-small, + div.otherDiv.horizontal-tiny, + div.otherDiv.horizontal-small div.description) { + max-height: 0; + margin: 0; + overflow: hidden; +} + +.local10 :where(div.parent1.child1.vertical-tiny, + div.parent1.child1.vertical-small, + div.otherDiv.horizontal-tiny, + div.otherDiv.horizontal-small div.description) { + max-height: 0; + margin: 0; + overflow: hidden; +} + +.local11 div:has(.disabled, .mButtonDisabled, .tipOnly) { + pointer-events: initial !important; +} + +.local12 div:current(p, span) { + background-color: yellow; +} + +.local13 div:past(p, span) { + display: none; +} + +.local14 div:future(p, span) { + background-color: yellow; +} + +.local15 div:-moz-any(ol, ul, menu, dir) { + list-style-type: square; +} + +.local16 li:-webkit-any(:first-child, :last-child) { + background-color: aquamarine; +} + +.local9 :matches(div.parent1.child1.vertical-tiny, + div.parent1.child1.vertical-small, + div.otherDiv.horizontal-tiny, + div.otherDiv.horizontal-small div.description) { + max-height: 0; + margin: 0; + overflow: hidden; +} + +._-_css-modules_style_module_css-nested1.nested2.nested3 { + color: pink; +} + +#ident { + color: purple; +} + +@keyframes localkeyframes { + 0% { + left: var(--pos1x); + top: var(--pos1y); + color: var(--theme-color1); + } + 100% { + left: var(--pos2x); + top: var(--pos2y); + color: var(--theme-color2); + } +} + +@keyframes localkeyframes2 { + 0% { + left: 0; + } + 100% { + left: 100px; + } +} + +.animation { + animation-name: localkeyframes; + animation: 3s ease-in 1s 2 reverse both paused localkeyframes, localkeyframes2; + --pos1x: 0px; + --pos1y: 0px; + --pos2x: 10px; + --pos2y: 20px; +} + +/* .composed { + composes: local1; + composes: local2; +} */ + +.vars { + color: var(--local-color); + --local-color: red; +} + +.globalVars { + color: var(--global-color); + --global-color: red; +} + +@media (min-width: 1600px) { + .wideScreenClass { + color: var(--local-color); + --local-color: green; + } +} + +@media screen and (max-width: 600px) { + .narrowScreenClass { + color: var(--local-color); + --local-color: purple; + } +} + +@supports (display: grid) { + .displayGridInSupports { + display: grid; + } +} + +@supports not (display: grid) { + .floatRightInNegativeSupports { + float: right; + } +} + +@supports (display: flex) { + @media screen and (min-width: 900px) { + .displayFlexInMediaInSupports { + display: flex; + } + } +} + +@media screen and (min-width: 900px) { + @supports (display: flex) { + .displayFlexInSupportsInMedia { + display: flex; + } + } +} + +@MEDIA screen and (min-width: 900px) { + @SUPPORTS (display: flex) { + .displayFlexInSupportsInMediaUpperCase { + display: flex; + } + } +} + +.animationUpperCase { + ANIMATION-NAME: localkeyframesUPPERCASE; + ANIMATION: 3s ease-in 1s 2 reverse both paused localkeyframesUPPERCASE, localkeyframes2UPPPERCASE; + --pos1x: 0px; + --pos1y: 0px; + --pos2x: 10px; + --pos2y: 20px; +} + +@KEYFRAMES localkeyframesUPPERCASE { + 0% { + left: VAR(--pos1x); + top: VAR(--pos1y); + color: VAR(--theme-color1); + } + 100% { + left: VAR(--pos2x); + top: VAR(--pos2y); + color: VAR(--theme-color2); + } +} + +@KEYframes localkeyframes2UPPPERCASE { + 0% { + left: 0; + } + 100% { + left: 100px; + } +} + +.globalUpperCase ._-_css-modules_style_module_css-localUpperCase { + color: yellow; +} + +.VARS { + color: VAR(--LOCAL-COLOR); + --LOCAL-COLOR: red; +} + +.globalVarsUpperCase { + COLOR: VAR(--GLOBAR-COLOR); + --GLOBAR-COLOR: red; +} + +@supports (top: env(safe-area-inset-top, 0)) { + .inSupportScope { + color: red; + } +} + +.a { + animation: 3s animationName; + -webkit-animation: 3s animationName; +} + +.b { + animation: animationName 3s; + -webkit-animation: animationName 3s; +} + +.c { + animation-name: animationName; + -webkit-animation-name: animationName; +} + +.d { + --animation-name: animationName; +} + +@keyframes animationName { + 0% { + background: white; + } + 100% { + background: red; + } +} + +@-webkit-keyframes animationName { + 0% { + background: white; + } + 100% { + background: red; + } +} + +@-moz-keyframes mozAnimationName { + 0% { + background: white; + } + 100% { + background: red; + } +} + +@counter-style thumbs { + system: cyclic; + symbols: \\"\\\\1F44D\\"; + suffix: \\" \\"; +} + +@font-feature-values Font One { + @styleset { + nice-style: 12; + } +} + +/* At-rule for \\"nice-style\\" in Font Two */ +@font-feature-values Font Two { + @styleset { + nice-style: 4; + } +} + +@property --my-color { + syntax: \\"\\"; + inherits: false; + initial-value: #c0ffee; +} + +.class { + color: var(--my-color); +} + +@layer utilities { + .padding-sm { + padding: 0.5rem; + } + + .padding-lg { + padding: 0.8rem; + } +} + +.class { + color: red; + + .nested-pure { + color: red; + } + + @media screen and (min-width: 200px) { + color: blue; + + .nested-media { + color: blue; + } + } + + @supports (display: flex) { + display: flex; + + .nested-supports { + display: flex; + } + } + + @layer foo { + background: red; + + .nested-layer { + background: red; + } + } + + @container foo { + background: red; + + .nested-layer { + background: red; + } + } +} + +.not-selector-inside { + color: #fff; + opacity: 0.12; + padding: .5px; + unknown: :local(.test); + unknown1: :local .test; + unknown2: :global .test; + unknown3: :global .test; + unknown4: .foo, .bar, #bar; +} + +@unknown :local .local :global .global { + color: red; +} + +@unknown :local(.local) :global(.global) { + color: red; +} + +.nested-var { + .again { + color: var(--local-color); + } +} + +.nested-with-local-pseudo { + color: red; + + ._-_css-modules_style_module_css-local-nested { + color: red; + } + + .global-nested { + color: red; + } + + ._-_css-modules_style_module_css-local-nested { + color: red; + } + + .global-nested { + color: red; + } + + ._-_css-modules_style_module_css-local-nested, .global-nested-next { + color: red; + } + + ._-_css-modules_style_module_css-local-nested, .global-nested-next { + color: red; + } + + .foo, .bar { + color: red; + } +} + +#id-foo { + color: red; + + #id-bar { + color: red; + } +} + +.nested-parens { + .local9 div:has(.vertical-tiny, .vertical-small) { + max-height: 0; + margin: 0; + overflow: hidden; + } +} + +.global-foo { + .nested-global { + color: red; + } + + ._-_css-modules_style_module_css-local-in-global { + color: blue; + } +} + +@unknown .class { + color: red; + + .class { + color: red; + } +} + +.class ._-_css-modules_style_module_css-in-local-global-scope, +.class ._-_css-modules_style_module_css-in-local-global-scope, +._-_css-modules_style_module_css-class-local-scope .in-local-global-scope { + color: red; +} + +@container (width > 400px) { + .class-in-container { + font-size: 1.5em; + } +} + +@container summary (min-width: 400px) { + @container (width > 400px) { + .deep-class-in-container { + font-size: 1.5em; + } + } +} + +:scope { + color: red; +} + +.placeholder-gray-700:-ms-input-placeholder { + --placeholder-opacity: 1; + color: #4a5568; + color: rgba(74, 85, 104, var(--placeholder-opacity)); +} +.placeholder-gray-700::-ms-input-placeholder { + --placeholder-opacity: 1; + color: #4a5568; + color: rgba(74, 85, 104, var(--placeholder-opacity)); +} +.placeholder-gray-700::placeholder { + --placeholder-opacity: 1; + color: #4a5568; + color: rgba(74, 85, 104, var(--placeholder-opacity)); +} + +:root { + --test: dark; +} + +@media screen and (prefers-color-scheme: var(--test)) { + .baz { + color: white; + } +} + +@keyframes slidein { + from { + margin-left: 100%; + width: 300%; + } + + to { + margin-left: 0%; + width: 100%; + } +} + +.class { + animation: + foo var(--animation-name) 3s, + var(--animation-name) 3s, + 3s linear 1s infinite running slidein, + 3s linear env(foo, var(--baz)) infinite running slidein; +} + +:root { + --baz: 10px; +} + +.class { + bar: env(foo, var(--baz)); +} + +.global-foo, ._-_css-modules_style_module_css-bar { + ._-_css-modules_style_module_css-local-in-global { + color: blue; + } + + @media screen { + .my-global-class-again, + ._-_css-modules_style_module_css-my-global-class-again { + color: red; + } + } +} + +.first-nested { + .first-nested-nested { + color: red; + } +} + +.first-nested-at-rule { + @media screen { + .first-nested-nested-at-rule-deep { + color: red; + } + } +} + +.again-global { + color:red; +} + +.again-again-global { + .again-again-global { + color: red; + } +} + +:root { + --foo: red; +} + +.again-again-global { + color: var(--foo); + + .again-again-global { + color: var(--foo); + } +} + +.again-again-global { + animation: slidein 3s; + + .again-again-global, .class, ._-_css-modules_style_module_css-nested1.nested2.nested3 { + animation: slidein 3s; + } + + .local2 .global, + .local3 { + color: red; + } +} + +@unknown var(--foo) { + color: red; +} + +.class { + .class { + .class { + .class {} + } + } +} + +.class { + .class { + .class { + .class { + animation: slidein 3s; + } + } + } +} + +.class { + animation: slidein 3s; + .class { + animation: slidein 3s; + .class { + animation: slidein 3s; + .class { + animation: slidein 3s; + } + } + } +} + +/*!***********************!*\\\\ + !*** css ./style.css ***! + \\\\***********************/ + +.class { + color: red; + background: var(--color); +} + +@keyframes test { + 0% { + color: red; + } + 100% { + color: blue; + } +} + +._-_style_css-class { + color: red; +} + +._-_style_css-class { + color: green; +} + +.class { + color: blue; +} + +.class { + color: white; +} + + +.class { + animation: test 1s, test; +} + +head{--webpack-main:local4:_-_css-modules_style_module_css-local4/nested1:_-_css-modules_style_module_css-nested1/localUpperCase:_-_css-modules_style_module_css-localUpperCase/local-nested:_-_css-modules_style_module_css-local-nested/local-in-global:_-_css-modules_style_module_css-local-in-global/in-local-global-scope:_-_css-modules_style_module_css-in-local-global-scope/class-local-scope:_-_css-modules_style_module_css-class-local-scope/bar:_-_css-modules_style_module_css-bar/my-global-class-again:_-_css-modules_style_module_css-my-global-class-again/&\\\\.\\\\.\\\\/css-modules\\\\/style\\\\.module\\\\.css,class:_-_style_css-class/foo:bar/&\\\\.\\\\/style\\\\.css;}", +] +`; + +exports[`ConfigCacheTestCases css urls exported tests should be able to handle styles in div.css 1`] = ` +Object { + "--foo": " url(img.09a1a1112c577c279435.png)", + "--foo-bar": " \\"http://www.example.com/pinkish.gif\\"", + "a": " url(img.09a1a1112c577c279435.png)", + "a1": " url(img.09a1a1112c577c279435.png)", + "a10": " green url( img\\\\ img.09a1a1112c577c279435.png ) xyz", + "a100": " url(img\\\\)img.09a1a1112c577c279435.png)", + "a101": " url(img\\\\ img.09a1a1112c577c279435.png)", + "a102": " url(img\\\\ img.09a1a1112c577c279435.png)", + "a103": " url(img\\\\(img.09a1a1112c577c279435.png)", + "a104": " url(img\\\\(img.09a1a1112c577c279435.png)", + "a105": " url(img\\\\(img.09a1a1112c577c279435.png)", + "a106": " url(img\\\\(img.09a1a1112c577c279435.png)", + "a107": " url(img\\\\'\\\\'\\\\'img.09a1a1112c577c279435.png)", + "a108": " url(\\"img'() img.09a1a1112c577c279435.png\\")", + "a109": " url(img\\\\'img.09a1a1112c577c279435.png)", + "a11": " green url( img\\\\ img.09a1a1112c577c279435.png ) xyz", + "a110": " url(img\\\\(img.09a1a1112c577c279435.png)", + "a111": " url(img\\\\)img.09a1a1112c577c279435.png)", + "a112": " url(img\\\\ img.09a1a1112c577c279435.png)", + "a113": " url(img\\\\'\\\\'\\\\'img.09a1a1112c577c279435.png)", + "a114": " url(\\"img'() img.09a1a1112c577c279435.png\\")", + "a115": " url(img\\\\'img.09a1a1112c577c279435.png)", + "a116": " url(img\\\\(img.09a1a1112c577c279435.png)", + "a117": " url(img\\\\)img.09a1a1112c577c279435.png)", + "a118": " url(img\\\\ img.09a1a1112c577c279435.png)", + "a119": " url(img.09a1a1112c577c279435.png)", + "a12": " green url(img.09a1a1112c577c279435.png) xyz", + "a120": " url(img\\\\'\\\\'\\\\'img.09a1a1112c577c279435.png)", + "a121": " url(\\"img'() img.09a1a1112c577c279435.png\\")", + "a122": " url(img\\\\'img.09a1a1112c577c279435.png)", + "a123": " url(img\\\\(img.09a1a1112c577c279435.png)", + "a124": " url(img\\\\)img.09a1a1112c577c279435.png)", + "a125": " url(img\\\\ img.09a1a1112c577c279435.png)", + "a126": " url(img.09a1a1112c577c279435.png)", + "a127": " url(img.09a1a1112c577c279435.png)", + "a128": " url(img\\\\'img.09a1a1112c577c279435.png)", + "a129": " url(\\"img'() img.09a1a1112c577c279435.png\\")", + "a13": " green url(data:image/png;base64,AAA) url(http://example.com/image.jpg) url(//example.com/image.png) xyz", + "a130": " url(\\"img'() img.09a1a1112c577c279435.png\\")", + "a131": " url(img.09a1a1112c577c279435.png)", + "a132": " url(img.09a1a1112c577c279435.png)", + "a133": " url(img.09a1a1112c577c279435.png?foo=bar)", + "a134": " url(img.09a1a1112c577c279435.png?foo=bar)", + "a135": " url(img.09a1a1112c577c279435.png?foo=bar#hash)", + "a136": " url(img.09a1a1112c577c279435.png?foo=bar#hash)", + "a137": " url(img.09a1a1112c577c279435.png?foo=bar)", + "a138": " url(img.09a1a1112c577c279435.png?bar=foo)", + "a139": " url(img.09a1a1112c577c279435.png?foo=bar#foo)", + "a14": " url(\\"data:image/svg+xml;charset=utf-8,\\")", + "a140": " url(img.09a1a1112c577c279435.png?bar=foo#bar)", + "a141": " url(img.09a1a1112c577c279435.png?foo=1&bar=2)", + "a142": " url(img.09a1a1112c577c279435.png?foo=2&bar=1)", + "a143": " url(data:image/svg+xml;charset=UTF-8,%3C%3Fxml%20version%3D%221.0%22%20encoding%3D%22utf-8%22%3F%3E%0A%3C!DOCTYPE%20svg%20PUBLIC%20%22-%2F%2FW3C%2F%2FDTD%20SVG%201.1%2F%2FEN%22%20%22http%3A%2F%2Fwww.w3.org%2FGraphics%2FSVG%2F1.1%2FDTD%2Fsvg11.dtd%22%3E%0A%3Csvg%20version%3D%221.1%22%20id%3D%22Layer_1%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20xmlns%3Axlink%3D%22http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink%22%20x%3D%220px%22%20y%3D%220px%22%0A%09%20width%3D%22191px%22%20height%3D%22191px%22%20viewBox%3D%220%200%20191%20191%22%20enable-background%3D%22new%200%200%20191%20191%22%20xml%3Aspace%3D%22preserve%22%3E%0A%3Cpath%20fill%3D%22%23636363%22%20d%3D%22M95.5%2C0C42.8%2C0%2C0%2C42.8%2C0%2C95.5S42.8%2C191%2C95.5%2C191S191%2C148.2%2C191%2C95.5S148.2%2C0%2C95.5%2C0z%20M95.5%2C187.6%0A%09c-50.848%2C0-92.1-41.25-92.1-92.1c0-50.848%2C41.252-92.1%2C92.1-92.1c50.85%2C0%2C92.1%2C41.252%2C92.1%2C92.1%0A%09C187.6%2C146.35%2C146.35%2C187.6%2C95.5%2C187.6z%22%2F%3E%0A%3Cg%3E%0A%09%3Cpath%20fill%3D%22%23636363%22%20d%3D%22M92.9%2C10v8.6H91v-6.5c-0.1%2C0.1-0.2%2C0.2-0.4%2C0.3c-0.2%2C0.1-0.3%2C0.2-0.4%2C0.2c-0.1%2C0-0.3%2C0.1-0.5%2C0.2%0A%09%09c-0.2%2C0.1-0.3%2C0.1-0.5%2C0.1v-1.6c0.5-0.1%2C0.9-0.3%2C1.4-0.5c0.5-0.2%2C0.8-0.5%2C1.2-0.7h1.1V10z%22%2F%3E%0A%09%3Cpath%20fill%3D%22%23636363%22%20d%3D%22M97.1%2C17.1h3.602v1.5h-5.6V18c0-0.4%2C0.1-0.8%2C0.2-1.2c0.1-0.4%2C0.3-0.6%2C0.5-0.9c0.2-0.3%2C0.5-0.5%2C0.7-0.7%0A%09%09c0.2-0.2%2C0.5-0.4%2C0.7-0.6c0.199-0.2%2C0.5-0.3%2C0.6-0.5c0.102-0.2%2C0.301-0.3%2C0.5-0.5c0.2-0.2%2C0.2-0.3%2C0.301-0.5%0A%09%09c0.101-0.2%2C0.101-0.3%2C0.101-0.5c0-0.4-0.101-0.6-0.3-0.8c-0.2-0.2-0.4-0.3-0.801-0.3c-0.699%2C0-1.399%2C0.3-2.101%2C0.9v-1.6%0A%09%09c0.7-0.5%2C1.5-0.7%2C2.5-0.7c0.399%2C0%2C0.8%2C0.1%2C1.101%2C0.2c0.301%2C0.1%2C0.601%2C0.3%2C0.899%2C0.5c0.3%2C0.2%2C0.399%2C0.5%2C0.5%2C0.8%0A%09%09c0.101%2C0.3%2C0.2%2C0.6%2C0.2%2C1s-0.102%2C0.7-0.2%2C1c-0.099%2C0.3-0.3%2C0.6-0.5%2C0.8c-0.2%2C0.2-0.399%2C0.5-0.7%2C0.7c-0.3%2C0.2-0.5%2C0.4-0.8%2C0.6%0A%09%09c-0.2%2C0.1-0.399%2C0.3-0.5%2C0.4s-0.3%2C0.3-0.5%2C0.4s-0.2%2C0.3-0.3%2C0.4C97.1%2C17%2C97.1%2C17%2C97.1%2C17.1z%22%2F%3E%0A%3C%2Fg%3E%0A%3Cg%3E%0A%09%3Cpath%20fill%3D%22%23636363%22%20d%3D%22M15%2C95.4c0%2C0.7-0.1%2C1.4-0.2%2C2c-0.1%2C0.6-0.4%2C1.1-0.7%2C1.5C13.8%2C99.3%2C13.4%2C99.6%2C12.9%2C99.8s-1%2C0.3-1.5%2C0.3%0A%09%09c-0.7%2C0-1.3-0.1-1.8-0.3v-1.5c0.4%2C0.3%2C1%2C0.4%2C1.6%2C0.4c0.6%2C0%2C1.1-0.2%2C1.5-0.7c0.4-0.5%2C0.5-1.1%2C0.5-1.9l0%2C0%0A%09%09C12.8%2C96.7%2C12.3%2C96.9%2C11.5%2C96.9c-0.3%2C0-0.7-0.102-1-0.2c-0.3-0.101-0.5-0.3-0.8-0.5c-0.3-0.2-0.4-0.5-0.5-0.8%0A%09%09c-0.1-0.3-0.2-0.7-0.2-1c0-0.4%2C0.1-0.8%2C0.2-1.2c0.1-0.4%2C0.3-0.7%2C0.6-0.9c0.3-0.2%2C0.6-0.5%2C0.9-0.6c0.3-0.1%2C0.8-0.2%2C1.2-0.2%0A%09%09c0.5%2C0%2C0.9%2C0.1%2C1.2%2C0.3c0.3%2C0.2%2C0.7%2C0.4%2C0.9%2C0.8s0.5%2C0.7%2C0.6%2C1.2S15%2C94.8%2C15%2C95.4z%20M13.1%2C94.4c0-0.2%2C0-0.4-0.1-0.6%0A%09%09c-0.1-0.2-0.1-0.4-0.2-0.5c-0.1-0.1-0.2-0.2-0.4-0.3c-0.2-0.1-0.3-0.1-0.5-0.1c-0.2%2C0-0.3%2C0-0.4%2C0.1s-0.3%2C0.2-0.3%2C0.3%0A%09%09c0%2C0.1-0.2%2C0.3-0.2%2C0.4c0%2C0.1-0.1%2C0.4-0.1%2C0.6c0%2C0.2%2C0%2C0.4%2C0.1%2C0.6c0.1%2C0.2%2C0.1%2C0.3%2C0.2%2C0.4c0.1%2C0.1%2C0.2%2C0.2%2C0.4%2C0.3%0A%09%09c0.2%2C0.1%2C0.3%2C0.1%2C0.5%2C0.1c0.2%2C0%2C0.3%2C0%2C0.4-0.1s0.2-0.2%2C0.3-0.3c0.1-0.1%2C0.2-0.2%2C0.2-0.4C13%2C94.7%2C13.1%2C94.6%2C13.1%2C94.4z%22%2F%3E%0A%3C%2Fg%3E%0A%3Cg%3E%0A%09%3Cpath%20fill%3D%22%23636363%22%20d%3D%22M176%2C99.7V98.1c0.6%2C0.4%2C1.2%2C0.602%2C2%2C0.602c0.5%2C0%2C0.8-0.102%2C1.1-0.301c0.301-0.199%2C0.4-0.5%2C0.4-0.801%0A%09%09c0-0.398-0.2-0.699-0.5-0.898c-0.3-0.2-0.8-0.301-1.3-0.301h-0.802V95h0.701c1.101%2C0%2C1.601-0.4%2C1.601-1.1c0-0.7-0.4-1-1.302-1%0A%09%09c-0.6%2C0-1.1%2C0.2-1.6%2C0.5v-1.5c0.6-0.3%2C1.301-0.4%2C2.1-0.4c0.9%2C0%2C1.5%2C0.2%2C2%2C0.6s0.701%2C0.9%2C0.701%2C1.5c0%2C1.1-0.601%2C1.8-1.701%2C2.1l0%2C0%0A%09%09c0.602%2C0.1%2C1.102%2C0.3%2C1.4%2C0.6s0.5%2C0.8%2C0.5%2C1.3c0%2C0.801-0.3%2C1.4-0.9%2C1.9c-0.6%2C0.5-1.398%2C0.7-2.398%2C0.7%0A%09%09C177.2%2C100.1%2C176.5%2C100%2C176%2C99.7z%22%2F%3E%0A%3C%2Fg%3E%0A%3Cg%3E%0A%09%3Cpath%20fill%3D%22%23636363%22%20d%3D%22M98.5%2C179.102c0%2C0.398-0.1%2C0.799-0.2%2C1.199C98.2%2C180.7%2C98%2C181%2C97.7%2C181.2s-0.601%2C0.5-0.9%2C0.601%0A%09%09c-0.3%2C0.1-0.7%2C0.199-1.2%2C0.199c-0.5%2C0-0.9-0.1-1.3-0.3c-0.4-0.2-0.7-0.399-0.9-0.8c-0.2-0.4-0.5-0.7-0.6-1.2%0A%09%09c-0.1-0.5-0.2-1-0.2-1.601c0-0.699%2C0.1-1.399%2C0.3-2c0.2-0.601%2C0.4-1.101%2C0.8-1.5c0.4-0.399%2C0.7-0.699%2C1.2-1c0.5-0.3%2C1-0.3%2C1.6-0.3%0A%09%09c0.6%2C0%2C1.2%2C0.101%2C1.5%2C0.199v1.5c-0.4-0.199-0.9-0.399-1.4-0.399c-0.3%2C0-0.6%2C0.101-0.8%2C0.2c-0.2%2C0.101-0.5%2C0.3-0.7%2C0.5%0A%09%09c-0.2%2C0.199-0.3%2C0.5-0.4%2C0.8c-0.1%2C0.301-0.2%2C0.7-0.2%2C1.101l0%2C0c0.4-0.601%2C1-0.8%2C1.8-0.8c0.3%2C0%2C0.7%2C0.1%2C0.9%2C0.199%0A%09%09c0.2%2C0.101%2C0.5%2C0.301%2C0.7%2C0.5c0.199%2C0.2%2C0.398%2C0.5%2C0.5%2C0.801C98.5%2C178.2%2C98.5%2C178.7%2C98.5%2C179.102z%20M96.7%2C179.2%0A%09%09c0-0.899-0.4-1.399-1.1-1.399c-0.2%2C0-0.3%2C0-0.5%2C0.1c-0.2%2C0.101-0.3%2C0.201-0.4%2C0.301c-0.1%2C0.101-0.2%2C0.199-0.2%2C0.4%0A%09%09c0%2C0.199-0.1%2C0.299-0.1%2C0.5c0%2C0.199%2C0%2C0.398%2C0.1%2C0.6s0.1%2C0.3%2C0.2%2C0.5c0.1%2C0.199%2C0.2%2C0.199%2C0.4%2C0.3c0.2%2C0.101%2C0.3%2C0.101%2C0.5%2C0.101%0A%09%09c0.2%2C0%2C0.3%2C0%2C0.5-0.101c0.2-0.101%2C0.301-0.199%2C0.301-0.3c0-0.1%2C0.199-0.301%2C0.199-0.399C96.6%2C179.7%2C96.7%2C179.4%2C96.7%2C179.2z%22%2F%3E%0A%3C%2Fg%3E%0A%3Ccircle%20fill%3D%22%23636363%22%20cx%3D%2295%22%20cy%3D%2295%22%20r%3D%227%22%2F%3E%0A%3C%2Fsvg%3E%0A) 50% 50%/191px no-repeat", + "a144": " url(img.09a1a1112c577c279435.png)", + "a145": " url(img.09a1a1112c577c279435.png)", + "a148": " url('data:image/svg+xml,%3Csvg xmlns=\\"http://www.w3.org/2000/svg\\"%3E%3Crect width=\\"100%25\\" height=\\"100%25\\" style=\\"stroke: rgb(223,224,225); stroke-width: 2px; fill: none; stroke-dasharray: 6px 3px\\" /%3E%3C/svg%3E')", + "a149": " url('data:image/svg+xml,%3Csvg xmlns=\\"http://www.w3.org/2000/svg\\"%3E%3Crect width=\\"100%25\\" height=\\"100%25\\" style=\\"stroke: rgb(223,224,225); stroke-width: 2px; fill: none; stroke-dasharray: 6px 3px\\" /%3E%3C/svg%3E')", + "a15": " url(data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20viewBox%3D%270%200%2042%2026%27%20fill%3D%27%2523007aff%27%3E%3Crect%20width%3D%274%27%20height%3D%274%27%2F%3E%3Crect%20x%3D%278%27%20y%3D%271%27%20width%3D%2734%27%20height%3D%272%27%2F%3E%3Crect%20y%3D%2711%27%20width%3D%274%27%20height%3D%274%27%2F%3E%3Crect%20x%3D%278%27%20y%3D%2712%27%20width%3D%2734%27%20height%3D%272%27%2F%3E%3Crect%20y%3D%2722%27%20width%3D%274%27%20height%3D%274%27%2F%3E%3Crect%20x%3D%278%27%20y%3D%2723%27%20width%3D%2734%27%20height%3D%272%27%2F%3E%3C%2Fsvg%3E)", + "a150": " url('data:image/svg+xml,%3Csvg xmlns=\\"http://www.w3.org/2000/svg\\"%3E%3Crect width=\\"100%25\\" height=\\"100%25\\" style=\\"stroke: rgb(223,224,225); stroke-width: 2px; fill: none; stroke-dasharray: 6px 3px\\" /%3E%3C/svg%3E')", + "a151": " url('data:image/svg+xml;utf8,')", + "a152": " url(img.09a1a1112c577c279435.png)", + "a153": " url(img.09a1a1112c577c279435.png)", + "a154": " url(other.09a1a1112c577c279435.png)", + "a155": " url(img.09a1a1112c577c279435.png)", + "a156": " url(\\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23343a40' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M2 5l6 6 6-6'/%3e%3c/svg%3e\\")", + "a157": " url('data:image/svg+xml;utf8,')", + "a158": " src(\\"http://www.example.com/pinkish.gif\\")", + "a159": " src(var(--foo))", + "a16": " url('data:image/svg+xml;charset=utf-8,#filter')", + "a160": " url(img.09a1a1112c577c279435.png param(--color var(--primary-color)))", + "a161": " src(\\"img.png\\" param(--color var(--primary-color)))", + "a162": " url(img\\\\ img.09a1a1112c577c279435.png)", + "a163": " url(img.09a1a1112c577c279435.png)", + "a164": " url( img.png bug)", + "a165": " url(imgn.09a1a1112c577c279435.png)", + "a166": " url('data:image/svg+xml;utf8,')", + "a167": " url(http://example.com/image.jpg)", + "a168": " url(http://example.com/image.jpg)", + "a169": " url(data:,)", + "a17": " url(\\"data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D%5C%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%5C%22%3E%3Cfilter%20id%3D%5C%22filter%5C%22%3E%3CfeGaussianBlur%20in%3D%5C%22SourceAlpha%5C%22%20stdDeviation%3D%5C%220%5C%22%20%2F%3E%3CfeOffset%20dx%3D%5C%221%5C%22%20dy%3D%5C%222%5C%22%20result%3D%5C%22offsetblur%5C%22%20%2F%3E%3CfeFlood%20flood-color%3D%5C%22rgba(255%2C255%2C255%2C1)%5C%22%20%2F%3E%3CfeComposite%20in2%3D%5C%22offsetblur%5C%22%20operator%3D%5C%22in%5C%22%20%2F%3E%3CfeMerge%3E%3CfeMergeNode%20%2F%3E%3CfeMergeNode%20in%3D%5C%22SourceGraphic%5C%22%20%2F%3E%3C%2FfeMerge%3E%3C%2Ffilter%3E%3C%2Fsvg%3E%23filter\\")", + "a170": " url(data:,)", + "a171": " image(ltr 'img.png#xywh=0,0,16,16', red)", + "a172": " image-set( + linear-gradient(blue, white) 1x, + linear-gradient(blue, green) 2x + )", + "a173": " image-set( + url(img.09a1a1112c577c279435.png) type(\\"image/png\\"), + url(img.09a1a1112c577c279435.png) type(\\"image/png\\") + )", + "a174": " image-set( + url(img.09a1a1112c577c279435.png) 1x, + url(img.09a1a1112c577c279435.png) 2x + )", + "a175": " image-set( + url(img.09a1a1112c577c279435.png) 1x, + url(img.09a1a1112c577c279435.png) 2x, + url(img.09a1a1112c577c279435.png) 3x + )", + "a176": " image-set( + url(img.09a1a1112c577c279435.png) type(\\"image/png\\"), + url(img.09a1a1112c577c279435.png) type(\\"image/png\\") + ) \\"img.png\\"", + "a177": " image-set( + url(img.09a1a1112c577c279435.png) 1x type(\\"image/png\\"), + url(img.09a1a1112c577c279435.png) 2x type(\\"image/png\\") + )", + "a178": " image-set( + url(img.09a1a1112c577c279435.png) type(\\"image/png\\") 1x, + url(img.09a1a1112c577c279435.png) type(\\"image/png\\") 2x + )", + "a179": " -webkit-image-set( + url(img.09a1a1112c577c279435.png) 1x + )", + "a18": " url(#highlight)", + "a180": " -webkit-image-set( + url(img.09a1a1112c577c279435.png var(--foo, \\"test.png\\")) 1x + )", + "a181": " src( \\"img.png\\" )", + "a182": " src('img.png')", + "a183": " src('img.png' var(--foo, \\"test.png\\"))", + "a184": " src(var(--foo, \\"test.png\\"))", + "a185": " src(\\" img.png \\")", + "a186": " image-set(url(img.09a1a1112c577c279435.png)1x,url(img.09a1a1112c577c279435.png)2x,url(img.09a1a1112c577c279435.png)3x)", + "a187": " image-set(url(img.09a1a1112c577c279435.png)1x,url(img.09a1a1112c577c279435.png)2x,url(img.09a1a1112c577c279435.png)3x)", + "a188": " image-set(url(img.09a1a1112c577c279435.png)1x,url(img.09a1a1112c577c279435.png)2x,url(img.09a1a1112c577c279435.png)3x)", + "a189": " image-set(url(img.09a1a1112c577c279435.png)1x,url(img.09a1a1112c577c279435.png)2x,url(img.09a1a1112c577c279435.png)3x)", + "a19": " url(#line-marker)", + "a190": " image-set(url(img.09a1a1112c577c279435.png)1x)", + "a191": " image-set(url(img.09a1a1112c577c279435.png)1x,url(img.09a1a1112c577c279435.png)2x)", + "a197": " \\\\u\\\\r\\\\l(img.09a1a1112c577c279435.png)", + "a198": " \\\\image-\\\\set(url(img.09a1a1112c577c279435.png)1x,url(img.09a1a1112c577c279435.png)2x,url(img.09a1a1112c577c279435.png)3x)", + "a199": " \\\\-webk\\\\it-image-set(url(img.09a1a1112c577c279435.png)1x)", + "a2": " url(img.09a1a1112c577c279435.png)", + "a200": "-webkit-image-set(url(img.09a1a1112c577c279435.png)1x)", + "a22": " \\"do not use url(path)\\"", + "a23": " 'do not \\"use\\" url(path)'", + "a24": " -webkit-image-set(url(img1x.09a1a1112c577c279435.png) 1x, url(img2x.09a1a1112c577c279435.png) 2x) +", + "a25": " image-set(url(img1x.09a1a1112c577c279435.png) 1x, url(img2x.09a1a1112c577c279435.png) 2x) +", + "a26": " green url() xyz", + "a27": " green url('') xyz", + "a28": " green url(\\"\\") xyz", + "a29": " green url(' ') xyz", + "a3": " url(img.09a1a1112c577c279435.png)", + "a30": " green url( + ) xyz", + "a4": " url(img.09a1a1112c577c279435.png#hash)", + "a40": " green url(https://raw.githubusercontent.com/webpack/media/master/logo/icon.png) xyz", + "a41": " green url(//raw.githubusercontent.com/webpack/media/master/logo/icon.png) xyz", + "a42": " url(img.09a1a1112c577c279435.png?foo)", + "a43": " url(img.09a1a1112c577c279435.png?foo=bar)", + "a44": " url(img.09a1a1112c577c279435.png?foo=bar#hash)", + "a45": " url(img.09a1a1112c577c279435.png?foo=bar#hash)", + "a46": " url(img.09a1a1112c577c279435.png?)", + "a47": " url(img.09a1a1112c577c279435.png) url(\\"data:image/svg+xml;charset=utf-8,\\") url(img.09a1a1112c577c279435.png)", + "a48": " __URL__()", + "a49": " url(img-simple.09a1a1112c577c279435.png)", + "a5": " url( + img.09a1a1112c577c279435.png + )", + "a50": " url(img-simple.09a1a1112c577c279435.png)", + "a51": " url(img-simple.09a1a1112c577c279435.png)", + "a52": " url(img.09a1a1112c577c279435.png)", + "a53": " url(img.09a1a1112c577c279435.png)", + "a55": " -webkit-image-set()", + "a56": " image-set()", + "a58": " image-set('')", + "a59": " image-set(\\"\\")", + "a6": " green url( img.09a1a1112c577c279435.png ) xyz", + "a60": " image-set(\\"\\" 1x)", + "a61": " image-set(url())", + "a62": " image-set( + url() + )", + "a63": " image-set(URL())", + "a64": " image-set(url(''))", + "a65": " image-set(url(\\"\\"))", + "a66": " image-set(url('') 1x)", + "a67": " image-set(1x)", + "a68": " image-set( + 1x + )", + "a69": " image-set(calc(1rem + 1px) 1x)", + "a7": " green url( img.09a1a1112c577c279435.png ) xyz", + "a70": " -webkit-image-set(url(img1x.09a1a1112c577c279435.png) 1x, url(img2x.09a1a1112c577c279435.png) 2x)", + "a71": " image-set(url(img1x.09a1a1112c577c279435.png) 1x)", + "a72": " image-set(url(img1x.09a1a1112c577c279435.png) 1x, url(img2x.09a1a1112c577c279435.png) 2x)", + "a73": " image-set(url(img\\\\ img.09a1a1112c577c279435.png) 1x, url(img\\\\ img.09a1a1112c577c279435.png) 2x)", + "a74": " image-set(url(img1x.09a1a1112c577c279435.png) 1x, url(img2x.09a1a1112c577c279435.png) 2x), + image-set(url(img1x.09a1a1112c577c279435.png) 1x, url(img2x.09a1a1112c577c279435.png) 2x)", + "a75": " image-set( + url(img1x.09a1a1112c577c279435.png) 1x, + url(img2x.09a1a1112c577c279435.png) 2x, + url(img3x.09a1a1112c577c279435.png) 600dpi + )", + "a76": " image-set(url(img1x.09a1a1112c577c279435.png?foo=bar) 1x)", + "a77": " image-set(url(img1x.09a1a1112c577c279435.png#hash) 1x)", + "a78": " image-set(url(img1x.09a1a1112c577c279435.png?#iefix) 1x)", + "a79": " -webkit-image-set(url(img1x.09a1a1112c577c279435.png) 1x, url(img2x.09a1a1112c577c279435.png) 2x)", + "a8": " green url(img.09a1a1112c577c279435.png) xyz", + "a80": " -webkit-image-set(url(img1x.09a1a1112c577c279435.png) 1x)", + "a81": " -webkit-image-set( + url(img1x.09a1a1112c577c279435.png) 1x + )", + "a82": " image-set(url(img1x.09a1a1112c577c279435.png) 1x)", + "a83": " image-set( + url(img1x.09a1a1112c577c279435.png) 1x + )", + "a84": " image-set(url(img1x.09a1a1112c577c279435.png) 1x, url(img2x.09a1a1112c577c279435.png) 2x)", + "a85": " image-set( + url(img1x.09a1a1112c577c279435.png) 1x, + url(img2x.09a1a1112c577c279435.png) 2x, + url(img3x.09a1a1112c577c279435.png) 600dpi + )", + "a86": " image-set(url(img\\\\ img.09a1a1112c577c279435.png) 1x, url(img\\\\ img.09a1a1112c577c279435.png) 2x)", + "a87": " image-set(url(img1x.09a1a1112c577c279435.png) 1x, url(img2x.09a1a1112c577c279435.png) 2x)", + "a88": " url(imgimg.09a1a1112c577c279435.png)", + "a89": " url(img\\\\'img.09a1a1112c577c279435.png)", + "a9": " green url(img.09a1a1112c577c279435.png) url(other-img.09a1a1112c577c279435.png) xyz", + "a90": " url(img\\\\'\\\\'\\\\'img.09a1a1112c577c279435.png)", + "a91": " url(img\\\\(img.09a1a1112c577c279435.png)", + "a92": " url(img\\\\)img.09a1a1112c577c279435.png)", + "a93": " url(img\\\\ img.09a1a1112c577c279435.png)", + "a94": " url(\\"img'() img.09a1a1112c577c279435.png\\")", + "a95": " image-set( + url(imgimg.09a1a1112c577c279435.png) 1x, + url(img\\\\'\\\\'\\\\'img.09a1a1112c577c279435.png) 2x, + url(img\\\\'img.09a1a1112c577c279435.png) 3x, + url(img\\\\(img.09a1a1112c577c279435.png) 4x, + url(img\\\\)img.09a1a1112c577c279435.png) 5x, + url(img\\\\ img.09a1a1112c577c279435.png) 6x, + url(\\"img'() img.09a1a1112c577c279435.png\\") 7x + )", + "a96": " url(img\\\\'\\\\'\\\\'img.09a1a1112c577c279435.png)", + "a97": " url(\\"img'() img.09a1a1112c577c279435.png\\")", + "a98": " url(img\\\\'img.09a1a1112c577c279435.png)", + "a99": " url(img\\\\(img.09a1a1112c577c279435.png)", + "b": " url(img.09a1a1112c577c279435.png)", + "c": " url(img.09a1a1112c577c279435.png)", + "d": " url(img.09a1a1112c577c279435.png#hash)", + "e": " url( + img.09a1a1112c577c279435.png + )", + "f": " green url( img.09a1a1112c577c279435.png ) xyz", + "g": " green url( img.09a1a1112c577c279435.png ) xyz", + "getPropertyValue": [Function], + "h": " green url(img.09a1a1112c577c279435.png) xyz", + "i": " green url(img.09a1a1112c577c279435.png) url(img.09a1a1112c577c279435.png) xyz", + "j": " green url( img\\\\ img.09a1a1112c577c279435.png ) xyz", + "k": " green url( img\\\\ img.09a1a1112c577c279435.png ) xyz", + "l": " green url(img.09a1a1112c577c279435.png) xyz", + "m": " green url(img.09a1a1112c577c279435.png) xyz", + "n": " green url(img.09a1a1112c577c279435.png) xyz", +} +`; + +exports[`ConfigCacheTestCases css urls-css-filename exported tests should generate correct url public path with css filename 1`] = ` +Object { + "getPropertyValue": [Function], + "nested-dir": " url(../../bundle0/assets/img2.png)", + "nested-nested-dir": " url(../../bundle0/assets/img3.png)", + "same-dir": " url(../../bundle0/assets/img1.png)", +} +`; + +exports[`ConfigCacheTestCases css urls-css-filename exported tests should generate correct url public path with css filename 2`] = ` +Object { + "getPropertyValue": [Function], + "nested-dir": " url(../../bundle0/assets/img3.png)", + "outer-dir": " url(../../bundle0/assets/img1.png)", + "same-dir": " url(../../bundle0/assets/img2.png)", +} +`; + +exports[`ConfigCacheTestCases css urls-css-filename exported tests should generate correct url public path with css filename 3`] = ` +Object { + "getPropertyValue": [Function], + "outer-dir": " url(../../bundle0/assets/img2.png)", + "outer-outer-dir": " url(../../bundle0/assets/img1.png)", + "same-dir": " url(../../bundle0/assets/img3.png)", +} +`; + +exports[`ConfigCacheTestCases css urls-css-filename exported tests should generate correct url public path with css filename 4`] = ` +Object { + "getPropertyValue": [Function], + "nested-dir": " url(https://test.cases/path/bundle1/assets/img2.png)", + "nested-nested-dir": " url(https://test.cases/path/bundle1/assets/img3.png)", + "same-dir": " url(https://test.cases/path/bundle1/assets/img1.png)", +} +`; + +exports[`ConfigCacheTestCases css urls-css-filename exported tests should generate correct url public path with css filename 5`] = ` +Object { + "getPropertyValue": [Function], + "nested-dir": " url(https://test.cases/path/bundle1/assets/img3.png)", + "outer-dir": " url(https://test.cases/path/bundle1/assets/img1.png)", + "same-dir": " url(https://test.cases/path/bundle1/assets/img2.png)", +} +`; + +exports[`ConfigCacheTestCases css urls-css-filename exported tests should generate correct url public path with css filename 6`] = ` +Object { + "getPropertyValue": [Function], + "outer-dir": " url(https://test.cases/path/bundle1/assets/img2.png)", + "outer-outer-dir": " url(https://test.cases/path/bundle1/assets/img1.png)", + "same-dir": " url(https://test.cases/path/bundle1/assets/img3.png)", +} +`; + +exports[`ConfigCacheTestCases css urls-css-filename exported tests should generate correct url public path with css filename 7`] = ` +Object { + "getPropertyValue": [Function], + "nested-dir": " url(https://test.cases/path/bundle2/assets/img2.png)", + "nested-nested-dir": " url(https://test.cases/path/bundle2/assets/img3.png)", + "same-dir": " url(https://test.cases/path/bundle2/assets/img1.png)", +} +`; + +exports[`ConfigCacheTestCases css urls-css-filename exported tests should generate correct url public path with css filename 8`] = ` +Object { + "getPropertyValue": [Function], + "nested-dir": " url(https://test.cases/path/bundle2/assets/img3.png)", + "outer-dir": " url(https://test.cases/path/bundle2/assets/img1.png)", + "same-dir": " url(https://test.cases/path/bundle2/assets/img2.png)", +} +`; + +exports[`ConfigCacheTestCases css urls-css-filename exported tests should generate correct url public path with css filename 9`] = ` +Object { + "getPropertyValue": [Function], + "outer-dir": " url(https://test.cases/path/bundle2/assets/img2.png)", + "outer-outer-dir": " url(https://test.cases/path/bundle2/assets/img1.png)", + "same-dir": " url(https://test.cases/path/bundle2/assets/img3.png)", +} +`; diff --git a/test/__snapshots__/ConfigCacheTestCases.test.js.snap b/test/__snapshots__/ConfigCacheTestCases.test.js.snap deleted file mode 100644 index a0ff693b4ea..00000000000 --- a/test/__snapshots__/ConfigCacheTestCases.test.js.snap +++ /dev/null @@ -1,78 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`ConfigCacheTestCases custom-modules json-custom exported tests should transform toml to json 1`] = ` -Object { - "owner": Object { - "bio": "GitHub Cofounder & CEO -Likes tater tots and beer.", - "dob": "1979-05-27T07:32:00.000Z", - "name": "Tom Preston-Werner", - "organization": "GitHub", - }, - "title": "TOML Example", -} -`; - -exports[`ConfigCacheTestCases records issue-2991 exported tests should write relative paths to records 1`] = ` -"{ - \\"chunks\\": { - \\"byName\\": { - \\"main\\": 179 - }, - \\"bySource\\": { - \\"0 main\\": 179 - }, - \\"usedIds\\": [ - 179 - ] - }, - \\"modules\\": { - \\"byIdentifier\\": { - \\"./test.js\\": 393, - \\"external \\\\\\"fs\\\\\\"\\": 747, - \\"external \\\\\\"path\\\\\\"\\": 622, - \\"ignored|./|pkgs/somepackage/foo\\": 907 - }, - \\"usedIds\\": [ - 393, - 622, - 747, - 907 - ] - } -}" -`; - -exports[`ConfigCacheTestCases records issue-7339 exported tests should write relative dynamic-require paths to records 1`] = ` -"{ - \\"chunks\\": { - \\"byName\\": { - \\"main\\": 179 - }, - \\"bySource\\": { - \\"0 main\\": 179 - }, - \\"usedIds\\": [ - 179 - ] - }, - \\"modules\\": { - \\"byIdentifier\\": { - \\"./dependencies/bar.js\\": 379, - \\"./dependencies/foo.js\\": 117, - \\"./dependencies|sync|/^\\\\\\\\.\\\\\\\\/.*$/\\": 412, - \\"./test.js\\": 393, - \\"external \\\\\\"fs\\\\\\"\\": 747, - \\"external \\\\\\"path\\\\\\"\\": 622 - }, - \\"usedIds\\": [ - 117, - 379, - 393, - 412, - 622, - 747 - ] - } -}" -`; diff --git a/test/__snapshots__/ConfigTestCases.basictest.js.snap b/test/__snapshots__/ConfigTestCases.basictest.js.snap new file mode 100644 index 00000000000..1f0e2a40be3 --- /dev/null +++ b/test/__snapshots__/ConfigTestCases.basictest.js.snap @@ -0,0 +1,4928 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`ConfigTestCases css css-import exported tests should compile 1`] = ` +Array [ + "/*!**********************************************************************************************!*\\\\ + !*** external \\"https://test.cases/path/../../../../configCases/css/css-import/external.css\\" ***! + \\\\**********************************************************************************************/ +body { + externally-imported: true; +} + +/*!******************************************!*\\\\ + !*** external \\"//example.com/style.css\\" ***! + \\\\******************************************/ +@import url(\\"//example.com/style.css\\"); +/*!*****************************************************************!*\\\\ + !*** external \\"https://fonts.googleapis.com/css?family=Roboto\\" ***! + \\\\*****************************************************************/ +@import url(\\"https://fonts.googleapis.com/css?family=Roboto\\"); +/*!***********************************************************************!*\\\\ + !*** external \\"https://fonts.googleapis.com/css?family=Noto+Sans+TC\\" ***! + \\\\***********************************************************************/ +@import url(\\"https://fonts.googleapis.com/css?family=Noto+Sans+TC\\"); +/*!******************************************************************************!*\\\\ + !*** external \\"https://fonts.googleapis.com/css?family=Noto+Sans+TC|Roboto\\" ***! + \\\\******************************************************************************/ +@import url(\\"https://fonts.googleapis.com/css?family=Noto+Sans+TC|Roboto\\"); +/*!************************************************************************************!*\\\\ + !*** external \\"https://fonts.googleapis.com/css?family=Noto+Sans+TC|Roboto?foo=1\\" ***! + \\\\************************************************************************************/ +@import url(\\"https://fonts.googleapis.com/css?family=Noto+Sans+TC|Roboto?foo=1\\") layer(super.foo) supports(display: flex) screen and (min-width: 400px); +/*!***********************************************************************************************!*\\\\ + !*** external \\"https://test.cases/path/../../../../configCases/css/css-import/external1.css\\" ***! + \\\\***********************************************************************************************/ +body { + externally-imported1: true; +} + +/*!***********************************************************************************************!*\\\\ + !*** external \\"https://test.cases/path/../../../../configCases/css/css-import/external2.css\\" ***! + \\\\***********************************************************************************************/ +body { + externally-imported2: true; +} + +/*!*********************************!*\\\\ + !*** external \\"external-1.css\\" ***! + \\\\*********************************/ +@import url(\\"external-1.css\\"); +/*!*********************************!*\\\\ + !*** external \\"external-2.css\\" ***! + \\\\*********************************/ +@import url(\\"external-2.css\\") supports(display: grid) screen and (max-width: 400px); +/*!*********************************!*\\\\ + !*** external \\"external-3.css\\" ***! + \\\\*********************************/ +@import url(\\"external-3.css\\") supports(not (display: grid) and (display: flex)) screen and (max-width: 400px); +/*!*********************************!*\\\\ + !*** external \\"external-4.css\\" ***! + \\\\*********************************/ +@import url(\\"external-4.css\\") supports((selector(h2 > p)) and + (font-tech(color-COLRv1))); +/*!*********************************!*\\\\ + !*** external \\"external-5.css\\" ***! + \\\\*********************************/ +@import url(\\"external-5.css\\") layer(default); +/*!*********************************!*\\\\ + !*** external \\"external-6.css\\" ***! + \\\\*********************************/ +@import url(\\"external-6.css\\") layer(default); +/*!*********************************!*\\\\ + !*** external \\"external-7.css\\" ***! + \\\\*********************************/ +@import url(\\"external-7.css\\") layer(); +/*!*********************************!*\\\\ + !*** external \\"external-8.css\\" ***! + \\\\*********************************/ +@import url(\\"external-8.css\\") layer(); +/*!*********************************!*\\\\ + !*** external \\"external-9.css\\" ***! + \\\\*********************************/ +@import url(\\"external-9.css\\") print; +/*!**********************************!*\\\\ + !*** external \\"external-10.css\\" ***! + \\\\**********************************/ +@import url(\\"external-10.css\\") print, screen; +/*!**********************************!*\\\\ + !*** external \\"external-11.css\\" ***! + \\\\**********************************/ +@import url(\\"external-11.css\\") screen; +/*!**********************************!*\\\\ + !*** external \\"external-12.css\\" ***! + \\\\**********************************/ +@import url(\\"external-12.css\\") screen and (orientation: landscape); +/*!**********************************!*\\\\ + !*** external \\"external-13.css\\" ***! + \\\\**********************************/ +@import url(\\"external-13.css\\") supports(not (display: flex)); +/*!**********************************!*\\\\ + !*** external \\"external-14.css\\" ***! + \\\\**********************************/ +@import url(\\"external-14.css\\") layer(default) supports(display: grid) screen and (max-width: 400px); +/*!***************************************************!*\\\\ + !*** css ./node_modules/style-library/styles.css ***! + \\\\***************************************************/ +p { + color: steelblue; +} + +/*!************************************************!*\\\\ + !*** css ./node_modules/main-field/styles.css ***! + \\\\************************************************/ +p { + color: antiquewhite; +} + +/*!*********************************************************!*\\\\ + !*** css ./node_modules/package-with-exports/style.css ***! + \\\\*********************************************************/ +.load-me { + color: red; +} + +/*!***************************************!*\\\\ + !*** css ./extensions-imported.mycss ***! + \\\\***************************************/ +.custom-extension{ + color: green; +}.using-loader { color: red; } +/*!***********************!*\\\\ + !*** css ./file.less ***! + \\\\***********************/ +.link { + color: #428bca; +} + +/*!**********************************!*\\\\ + !*** css ./with-less-import.css ***! + \\\\**********************************/ + +.foo { + color: red; +} + +/*!*********************************!*\\\\ + !*** css ./prefer-relative.css ***! + \\\\*********************************/ +.relative { + color: red; +} + +/*!************************************************************!*\\\\ + !*** css ./node_modules/condition-names-style/default.css ***! + \\\\************************************************************/ +.default { + color: steelblue; +} + +/*!**************************************************************!*\\\\ + !*** css ./node_modules/condition-names-style-mode/mode.css ***! + \\\\**************************************************************/ +.mode { + color: red; +} + +/*!******************************************************************!*\\\\ + !*** css ./node_modules/condition-names-subpath/dist/custom.css ***! + \\\\******************************************************************/ +.dist { + color: steelblue; +} + +/*!************************************************************************!*\\\\ + !*** css ./node_modules/condition-names-subpath-extra/dist/custom.css ***! + \\\\************************************************************************/ +.dist { + color: steelblue; +} + +/*!******************************************************************!*\\\\ + !*** css ./node_modules/condition-names-style-less/default.less ***! + \\\\******************************************************************/ +.conditional-names { + color: #428bca; +} + +/*!**********************************************************************!*\\\\ + !*** css ./node_modules/condition-names-custom-name/custom-name.css ***! + \\\\**********************************************************************/ +.custom-name { + color: steelblue; +} + +/*!************************************************************!*\\\\ + !*** css ./node_modules/style-and-main-library/styles.css ***! + \\\\************************************************************/ +.style { + color: steelblue; +} + +/*!**************************************************************!*\\\\ + !*** css ./node_modules/condition-names-webpack/webpack.css ***! + \\\\**************************************************************/ +.webpack { + color: steelblue; +} + +/*!*******************************************************************!*\\\\ + !*** css ./node_modules/condition-names-style-nested/default.css ***! + \\\\*******************************************************************/ +.default { + color: steelblue; +} + +/*!******************************!*\\\\ + !*** css ./style-import.css ***! + \\\\******************************/ + +/* Technically, this is not entirely true, but we allow it because the final file can be processed by the loader and return the CSS code */ + + +/* Failed */ + + +/*!*****************************!*\\\\ + !*** css ./print.css?foo=1 ***! + \\\\*****************************/ +body { + background: black; +} + +/*!*****************************!*\\\\ + !*** css ./print.css?foo=2 ***! + \\\\*****************************/ +body { + background: black; +} + +/*!**********************************************!*\\\\ + !*** css ./print.css?foo=3 (layer: default) ***! + \\\\**********************************************/ +@layer default { + body { + background: black; + } +} + +/*!**********************************************!*\\\\ + !*** css ./print.css?foo=4 (layer: default) ***! + \\\\**********************************************/ +@layer default { + body { + background: black; + } +} + +/*!*******************************************************!*\\\\ + !*** css ./print.css?foo=5 (supports: display: flex) ***! + \\\\*******************************************************/ +@supports (display: flex) { + body { + background: black; + } +} + +/*!*******************************************************!*\\\\ + !*** css ./print.css?foo=6 (supports: display: flex) ***! + \\\\*******************************************************/ +@supports (display: flex) { + body { + background: black; + } +} + +/*!********************************************************************!*\\\\ + !*** css ./print.css?foo=7 (media: screen and (min-width: 400px)) ***! + \\\\********************************************************************/ +@media screen and (min-width: 400px) { + body { + background: black; + } +} + +/*!********************************************************************!*\\\\ + !*** css ./print.css?foo=8 (media: screen and (min-width: 400px)) ***! + \\\\********************************************************************/ +@media screen and (min-width: 400px) { + body { + background: black; + } +} + +/*!************************************************************************!*\\\\ + !*** css ./print.css?foo=9 (layer: default) (supports: display: flex) ***! + \\\\************************************************************************/ +@layer default { + @supports (display: flex) { + body { + background: black; + } + } +} + +/*!**************************************************************************************!*\\\\ + !*** css ./print.css?foo=10 (layer: default) (media: screen and (min-width: 400px)) ***! + \\\\**************************************************************************************/ +@layer default { + @media screen and (min-width: 400px) { + body { + background: black; + } + } +} + +/*!***********************************************************************************************!*\\\\ + !*** css ./print.css?foo=11 (supports: display: flex) (media: screen and (min-width: 400px)) ***! + \\\\***********************************************************************************************/ +@supports (display: flex) { + @media screen and (min-width: 400px) { + body { + background: black; + } + } +} + +/*!****************************************************************************************************************!*\\\\ + !*** css ./print.css?foo=12 (layer: default) (supports: display: flex) (media: screen and (min-width: 400px)) ***! + \\\\****************************************************************************************************************/ +@layer default { + @supports (display: flex) { + @media screen and (min-width: 400px) { + body { + background: black; + } + } + } +} + +/*!****************************************************************************************************************!*\\\\ + !*** css ./print.css?foo=13 (layer: default) (supports: display: flex) (media: screen and (min-width: 400px)) ***! + \\\\****************************************************************************************************************/ +@layer default { + @supports (display: flex) { + @media screen and (min-width: 400px) { + body { + background: black; + } + } + } +} + +/*!****************************************************************************************************************!*\\\\ + !*** css ./print.css?foo=14 (layer: default) (supports: display: flex) (media: screen and (min-width: 400px)) ***! + \\\\****************************************************************************************************************/ +@layer default { + @supports (display: flex) { + @media screen and (min-width: 400px) { + body { + background: black; + } + } + } +} + +/*!****************************************************************************************************************!*\\\\ + !*** css ./print.css?foo=15 (layer: default) (supports: display: flex) (media: screen and (min-width: 400px)) ***! + \\\\****************************************************************************************************************/ +@layer default { + @supports (display: flex) { + @media screen and (min-width: 400px) { + body { + background: black; + } + } + } +} + +/*!*****************************************************************************************************************************!*\\\\ + !*** css ./print.css?foo=16 (layer: default) (supports: background: url(./img.png)) (media: screen and (min-width: 400px)) ***! + \\\\*****************************************************************************************************************************/ +@layer default { + @supports (background: url(./img.png)) { + @media screen and (min-width: 400px) { + body { + background: black; + } + } + } +} + +/*!*******************************************************************************************************************************!*\\\\ + !*** css ./print.css?foo=17 (layer: default) (supports: background: url(\\"./img.png\\")) (media: screen and (min-width: 400px)) ***! + \\\\*******************************************************************************************************************************/ +@layer default { + @supports (background: url(\\"./img.png\\")) { + @media screen and (min-width: 400px) { + body { + background: black; + } + } + } +} + +/*!**********************************************!*\\\\ + !*** css ./print.css?foo=18 (media: screen) ***! + \\\\**********************************************/ +@media screen { + body { + background: black; + } +} + +/*!**********************************************!*\\\\ + !*** css ./print.css?foo=19 (media: screen) ***! + \\\\**********************************************/ +@media screen { + body { + background: black; + } +} + +/*!**********************************************!*\\\\ + !*** css ./print.css?foo=20 (media: screen) ***! + \\\\**********************************************/ +@media screen { + body { + background: black; + } +} + +/*!******************************!*\\\\ + !*** css ./print.css?foo=21 ***! + \\\\******************************/ +body { + background: black; +} + +/*!**************************!*\\\\ + !*** css ./imported.css ***! + \\\\**************************/ +body { + background: green; +} + +/*!****************************************!*\\\\ + !*** css ./imported.css (layer: base) ***! + \\\\****************************************/ +@layer base { + body { + background: green; + } +} + +/*!****************************************************!*\\\\ + !*** css ./imported.css (supports: display: flex) ***! + \\\\****************************************************/ +@supports (display: flex) { + body { + background: green; + } +} + +/*!*************************************************!*\\\\ + !*** css ./imported.css (media: screen, print) ***! + \\\\*************************************************/ +@media screen, print { + body { + background: green; + } +} + +/*!******************************!*\\\\ + !*** css ./style2.css?foo=1 ***! + \\\\******************************/ +a { + color: red; +} + +/*!******************************!*\\\\ + !*** css ./style2.css?foo=2 ***! + \\\\******************************/ +a { + color: red; +} + +/*!******************************!*\\\\ + !*** css ./style2.css?foo=3 ***! + \\\\******************************/ +a { + color: red; +} + +/*!******************************!*\\\\ + !*** css ./style2.css?foo=4 ***! + \\\\******************************/ +a { + color: red; +} + +/*!******************************!*\\\\ + !*** css ./style2.css?foo=5 ***! + \\\\******************************/ +a { + color: red; +} + +/*!******************************!*\\\\ + !*** css ./style2.css?foo=6 ***! + \\\\******************************/ +a { + color: red; +} + +/*!******************************!*\\\\ + !*** css ./style2.css?foo=7 ***! + \\\\******************************/ +a { + color: red; +} + +/*!******************************!*\\\\ + !*** css ./style2.css?foo=8 ***! + \\\\******************************/ +a { + color: red; +} + +/*!******************************!*\\\\ + !*** css ./style2.css?foo=9 ***! + \\\\******************************/ +a { + color: red; +} + +/*!********************************************************************!*\\\\ + !*** css ./style2.css (media: screen and (orientation:landscape)) ***! + \\\\********************************************************************/ +@media screen and (orientation:landscape) { + a { + color: red; + } +} + +/*!*********************************************************************!*\\\\ + !*** css ./style2.css (media: SCREEN AND (ORIENTATION: LANDSCAPE)) ***! + \\\\*********************************************************************/ +@media SCREEN AND (ORIENTATION: LANDSCAPE) { + a { + color: red; + } +} + +/*!****************************************************!*\\\\ + !*** css ./style2.css (media: (min-width: 100px)) ***! + \\\\****************************************************/ +@media (min-width: 100px) { + a { + color: red; + } +} + +/*!**********************************!*\\\\ + !*** css ./test.css?foo=1&bar=1 ***! + \\\\**********************************/ +.class { + content: \\"test.css\\"; +} + +/*!*****************************************!*\\\\ + !*** css ./style2.css?foo=1&bar=1#hash ***! + \\\\*****************************************/ +a { + color: red; +} + +/*!*************************************************************************************!*\\\\ + !*** css ./style2.css?foo=1&bar=1#hash (media: screen and (orientation:landscape)) ***! + \\\\*************************************************************************************/ +@media screen and (orientation:landscape) { + a { + color: red; + } +} + +/*!******************************!*\\\\ + !*** css ./style3.css?bar=1 ***! + \\\\******************************/ +.class { + content: \\"style.css\\"; + color: red; +} + +/*!******************************!*\\\\ + !*** css ./style3.css?bar=2 ***! + \\\\******************************/ +.class { + content: \\"style.css\\"; + color: red; +} + +/*!******************************!*\\\\ + !*** css ./style3.css?bar=3 ***! + \\\\******************************/ +.class { + content: \\"style.css\\"; + color: red; +} + +/*!******************************!*\\\\ + !*** css ./style3.css?=bar4 ***! + \\\\******************************/ +.class { + content: \\"style.css\\"; + color: red; +} + +/*!**************************!*\\\\ + !*** css ./styl'le7.css ***! + \\\\**************************/ +.class { + content: \\"style7.css\\"; +} + +/*!********************************!*\\\\ + !*** css ./styl'le7.css?foo=1 ***! + \\\\********************************/ +.class { + content: \\"style7.css\\"; +} + +/*!***************************!*\\\\ + !*** css ./test test.css ***! + \\\\***************************/ +.class { + content: \\"test test.css\\"; +} + +/*!*********************************!*\\\\ + !*** css ./test test.css?foo=1 ***! + \\\\*********************************/ +.class { + content: \\"test test.css\\"; +} + +/*!*********************************!*\\\\ + !*** css ./test test.css?foo=2 ***! + \\\\*********************************/ +.class { + content: \\"test test.css\\"; +} + +/*!*********************************!*\\\\ + !*** css ./test test.css?foo=3 ***! + \\\\*********************************/ +.class { + content: \\"test test.css\\"; +} + +/*!*********************************!*\\\\ + !*** css ./test test.css?foo=4 ***! + \\\\*********************************/ +.class { + content: \\"test test.css\\"; +} + +/*!*********************************!*\\\\ + !*** css ./test test.css?foo=5 ***! + \\\\*********************************/ +.class { + content: \\"test test.css\\"; +} + +/*!**********************!*\\\\ + !*** css ./test.css ***! + \\\\**********************/ +.class { + content: \\"test.css\\"; +} + +/*!****************************!*\\\\ + !*** css ./test.css?foo=1 ***! + \\\\****************************/ +.class { + content: \\"test.css\\"; +} + +/*!****************************!*\\\\ + !*** css ./test.css?foo=2 ***! + \\\\****************************/ +.class { + content: \\"test.css\\"; +} + +/*!****************************!*\\\\ + !*** css ./test.css?foo=3 ***! + \\\\****************************/ +.class { + content: \\"test.css\\"; +} + +/*!*********************************!*\\\\ + !*** css ./test test.css?foo=6 ***! + \\\\*********************************/ +.class { + content: \\"test test.css\\"; +} + +/*!*********************************!*\\\\ + !*** css ./test test.css?foo=7 ***! + \\\\*********************************/ +.class { + content: \\"test test.css\\"; +} + +/*!*********************************!*\\\\ + !*** css ./test test.css?foo=8 ***! + \\\\*********************************/ +.class { + content: \\"test test.css\\"; +} + +/*!*********************************!*\\\\ + !*** css ./test test.css?foo=9 ***! + \\\\*********************************/ +.class { + content: \\"test test.css\\"; +} + +/*!**********************************!*\\\\ + !*** css ./test test.css?fpp=10 ***! + \\\\**********************************/ +.class { + content: \\"test test.css\\"; +} + +/*!**********************************!*\\\\ + !*** css ./test test.css?foo=11 ***! + \\\\**********************************/ +.class { + content: \\"test test.css\\"; +} + +/*!*********************************!*\\\\ + !*** css ./style6.css?foo=bazz ***! + \\\\*********************************/ +.class { + content: \\"style6.css\\"; +} + +/*!********************************************************!*\\\\ + !*** css ./string-loader.js?esModule=false!./test.css ***! + \\\\********************************************************/ +.class { + content: \\"test.css\\"; +} +.using-loader { color: red; } +/*!********************************!*\\\\ + !*** css ./style4.css?foo=bar ***! + \\\\********************************/ +.class { + content: \\"style4.css\\"; +} + +/*!*************************************!*\\\\ + !*** css ./style4.css?foo=bar#hash ***! + \\\\*************************************/ +.class { + content: \\"style4.css\\"; +} + +/*!******************************!*\\\\ + !*** css ./style4.css?#hash ***! + \\\\******************************/ +.class { + content: \\"style4.css\\"; +} + +/*!********************************************************!*\\\\ + !*** css ./style4.css?foo=1 (supports: display: flex) ***! + \\\\********************************************************/ +@supports (display: flex) { + .class { + content: \\"style4.css\\"; + } +} + +/*!****************************************************************************************************!*\\\\ + !*** css ./style4.css?foo=2 (supports: display: flex) (media: screen and (orientation:landscape)) ***! + \\\\****************************************************************************************************/ +@supports (display: flex) { + @media screen and (orientation:landscape) { + .class { + content: \\"style4.css\\"; + } + } +} + +/*!******************************!*\\\\ + !*** css ./style4.css?foo=3 ***! + \\\\******************************/ +.class { + content: \\"style4.css\\"; +} + +/*!******************************!*\\\\ + !*** css ./style4.css?foo=4 ***! + \\\\******************************/ +.class { + content: \\"style4.css\\"; +} + +/*!******************************!*\\\\ + !*** css ./style4.css?foo=5 ***! + \\\\******************************/ +.class { + content: \\"style4.css\\"; +} + +/*!*****************************************************************************************************!*\\\\ + !*** css ./string-loader.js?esModule=false!./test.css (media: screen and (orientation: landscape)) ***! + \\\\*****************************************************************************************************/ +@media screen and (orientation: landscape) { + .class { + content: \\"test.css\\"; + } + .using-loader { color: red; }} + +/*!*************************************************************************************!*\\\\ + !*** css data:text/css;charset=utf-8,a%20%7B%0D%0A%20%20color%3A%20red%3B%0D%0A%7D ***! + \\\\*************************************************************************************/ +a { + color: red; +} +/*!**********************************************************************************************************************************!*\\\\ + !*** css data:text/css;charset=utf-8,a%20%7B%0D%0A%20%20color%3A%20blue%3B%0D%0A%7D (media: screen and (orientation:landscape)) ***! + \\\\**********************************************************************************************************************************/ +@media screen and (orientation:landscape) { + a { + color: blue; + }} + +/*!***************************************************************************!*\\\\ + !*** css data:text/css;charset=utf-8;base64,YSB7DQogIGNvbG9yOiByZWQ7DQp9 ***! + \\\\***************************************************************************/ +a { + color: red; +} +/*!******************************!*\\\\ + !*** css ./style5.css?foo=1 ***! + \\\\******************************/ +.class { + content: \\"style5.css\\"; +} + +/*!******************************!*\\\\ + !*** css ./style5.css?foo=2 ***! + \\\\******************************/ +.class { + content: \\"style5.css\\"; +} + +/*!**************************************************!*\\\\ + !*** css ./style5.css?foo=3 (supports: unknown) ***! + \\\\**************************************************/ +@supports (unknown) { + .class { + content: \\"style5.css\\"; + } +} + +/*!********************************************************!*\\\\ + !*** css ./style5.css?foo=4 (supports: display: flex) ***! + \\\\********************************************************/ +@supports (display: flex) { + .class { + content: \\"style5.css\\"; + } +} + +/*!*******************************************************************!*\\\\ + !*** css ./style5.css?foo=5 (supports: display: flex !important) ***! + \\\\*******************************************************************/ +@supports (display: flex !important) { + .class { + content: \\"style5.css\\"; + } +} + +/*!***********************************************************************************************!*\\\\ + !*** css ./style5.css?foo=6 (supports: display: flex) (media: screen and (min-width: 400px)) ***! + \\\\***********************************************************************************************/ +@supports (display: flex) { + @media screen and (min-width: 400px) { + .class { + content: \\"style5.css\\"; + } + } +} + +/*!********************************************************!*\\\\ + !*** css ./style5.css?foo=7 (supports: selector(a b)) ***! + \\\\********************************************************/ +@supports (selector(a b)) { + .class { + content: \\"style5.css\\"; + } +} + +/*!********************************************************!*\\\\ + !*** css ./style5.css?foo=8 (supports: display: flex) ***! + \\\\********************************************************/ +@supports (display: flex) { + .class { + content: \\"style5.css\\"; + } +} + +/*!*****************************!*\\\\ + !*** css ./layer.css?foo=1 ***! + \\\\*****************************/ +@layer { + .class { + content: \\"layer.css\\"; + } +} + +/*!**********************************************!*\\\\ + !*** css ./layer.css?foo=2 (layer: default) ***! + \\\\**********************************************/ +@layer default { + .class { + content: \\"layer.css\\"; + } +} + +/*!***************************************************************************************************************!*\\\\ + !*** css ./layer.css?foo=3 (layer: default) (supports: display: flex) (media: screen and (min-width: 400px)) ***! + \\\\***************************************************************************************************************/ +@layer default { + @supports (display: flex) { + @media screen and (min-width: 400px) { + .class { + content: \\"layer.css\\"; + } + } + } +} + +/*!**********************************************************************************************!*\\\\ + !*** css ./layer.css?foo=3 (supports: display: flex) (media: screen and (min-width: 400px)) ***! + \\\\**********************************************************************************************/ +@layer { + @supports (display: flex) { + @media screen and (min-width: 400px) { + .class { + content: \\"layer.css\\"; + } + } + } +} + +/*!**********************************************************************************************!*\\\\ + !*** css ./layer.css?foo=4 (supports: display: flex) (media: screen and (min-width: 400px)) ***! + \\\\**********************************************************************************************/ +@layer { + @supports (display: flex) { + @media screen and (min-width: 400px) { + .class { + content: \\"layer.css\\"; + } + } + } +} + +/*!*****************************!*\\\\ + !*** css ./layer.css?foo=5 ***! + \\\\*****************************/ +@layer { + .class { + content: \\"layer.css\\"; + } +} + +/*!**************************************************!*\\\\ + !*** css ./layer.css?foo=6 (layer: foo.bar.baz) ***! + \\\\**************************************************/ +@layer foo.bar.baz { + .class { + content: \\"layer.css\\"; + } +} + +/*!*****************************!*\\\\ + !*** css ./layer.css?foo=7 ***! + \\\\*****************************/ +@layer { + .class { + content: \\"layer.css\\"; + } +} + +/*!*********************************************************************************************************!*\\\\ + !*** css ./style6.css (layer: default) (supports: display: flex) (media: screen and (min-width:400px)) ***! + \\\\*********************************************************************************************************/ +@layer default { + @supports (display: flex) { + @media screen and (min-width:400px) { + .class { + content: \\"style6.css\\"; + } + } + } +} + +/*!***************************************************************************************************************!*\\\\ + !*** css ./style6.css?foo=1 (layer: default) (supports: display: flex) (media: screen and (min-width:400px)) ***! + \\\\***************************************************************************************************************/ +@layer default { + @supports (display: flex) { + @media screen and (min-width:400px) { + .class { + content: \\"style6.css\\"; + } + } + } +} + +/*!**********************************************************************************************!*\\\\ + !*** css ./style6.css?foo=2 (supports: display: flex) (media: screen and (min-width:400px)) ***! + \\\\**********************************************************************************************/ +@supports (display: flex) { + @media screen and (min-width:400px) { + .class { + content: \\"style6.css\\"; + } + } +} + +/*!********************************************************************!*\\\\ + !*** css ./style6.css?foo=3 (media: screen and (min-width:400px)) ***! + \\\\********************************************************************/ +@media screen and (min-width:400px) { + .class { + content: \\"style6.css\\"; + } +} + +/*!********************************************************************!*\\\\ + !*** css ./style6.css?foo=4 (media: screen and (min-width:400px)) ***! + \\\\********************************************************************/ +@media screen and (min-width:400px) { + .class { + content: \\"style6.css\\"; + } +} + +/*!********************************************************************!*\\\\ + !*** css ./style6.css?foo=5 (media: screen and (min-width:400px)) ***! + \\\\********************************************************************/ +@media screen and (min-width:400px) { + .class { + content: \\"style6.css\\"; + } +} + +/*!****************************************************************************************************************************************************!*\\\\ + !*** css ./style6.css?foo=6 (layer: default) (supports: display : flex) (media: screen and ( min-width : 400px )) ***! + \\\\****************************************************************************************************************************************************/ +@layer default { + @supports (display : flex) { + @media screen and ( min-width : 400px ) { + .class { + content: \\"style6.css\\"; + } + } + } +} + +/*!****************************************************************************************************************!*\\\\ + !*** css ./style6.css?foo=7 (layer: DEFAULT) (supports: DISPLAY: FLEX) (media: SCREEN AND (MIN-WIDTH: 400PX)) ***! + \\\\****************************************************************************************************************/ +@layer DEFAULT { + @supports (DISPLAY: FLEX) { + @media SCREEN AND (MIN-WIDTH: 400PX) { + .class { + content: \\"style6.css\\"; + } + } + } +} + +/*!***********************************************************************************************!*\\\\ + !*** css ./style6.css?foo=8 (supports: DISPLAY: FLEX) (media: SCREEN AND (MIN-WIDTH: 400PX)) ***! + \\\\***********************************************************************************************/ +@layer { + @supports (DISPLAY: FLEX) { + @media SCREEN AND (MIN-WIDTH: 400PX) { + .class { + content: \\"style6.css\\"; + } + } + } +} + +/*!*******************************************************************************************************************************************************************************************************************************************************************************************************!*\\\\ + !*** css ./style6.css?foo=9 (layer: /* Comment *_/default/* Comment *_/) (supports: /* Comment *_/display/* Comment *_/:/* Comment *_/ flex/* Comment *_/) (media: /* Comment *_/ screen/* Comment *_/ and/* Comment *_/ (/* Comment *_/min-width/* Comment *_/: /* Comment *_/400px/* Comment *_/)) ***! + \\\\*******************************************************************************************************************************************************************************************************************************************************************************************************/ +@layer /* Comment */default/* Comment */ { + @supports (/* Comment */display/* Comment */:/* Comment */ flex/* Comment */) { + @media /* Comment */ screen/* Comment */ and/* Comment */ (/* Comment */min-width/* Comment */: /* Comment */400px/* Comment */) { + .class { + content: \\"style6.css\\"; + } + } + } +} + +/*!*******************************!*\\\\ + !*** css ./style6.css?foo=10 ***! + \\\\*******************************/ +.class { + content: \\"style6.css\\"; +} + +/*!*******************************!*\\\\ + !*** css ./style6.css?foo=11 ***! + \\\\*******************************/ +.class { + content: \\"style6.css\\"; +} + +/*!*******************************!*\\\\ + !*** css ./style6.css?foo=12 ***! + \\\\*******************************/ +.class { + content: \\"style6.css\\"; +} + +/*!*******************************!*\\\\ + !*** css ./style6.css?foo=13 ***! + \\\\*******************************/ +.class { + content: \\"style6.css\\"; +} + +/*!*******************************!*\\\\ + !*** css ./style6.css?foo=14 ***! + \\\\*******************************/ +.class { + content: \\"style6.css\\"; +} + +/*!*******************************!*\\\\ + !*** css ./style6.css?foo=15 ***! + \\\\*******************************/ +.class { + content: \\"style6.css\\"; +} + +/*!*****************************************************************************************!*\\\\ + !*** css ./style6.css?foo=16 (media: /* Comment *_/ print and (orientation:landscape)) ***! + \\\\*****************************************************************************************/ +@media /* Comment */ print and (orientation:landscape) { + .class { + content: \\"style6.css\\"; + } +} + +/*!******************************************************************************************************!*\\\\ + !*** css ./style6.css?foo=17 (media: /* Comment *_/print and (orientation:landscape)/* Comment *_/) ***! + \\\\******************************************************************************************************/ +@media /* Comment */print and (orientation:landscape)/* Comment */ { + .class { + content: \\"style6.css\\"; + } +} + +/*!*****************************************************************************************!*\\\\ + !*** css ./style6.css?foo=18 (media: /* Comment *_/ print and (orientation:landscape)) ***! + \\\\*****************************************************************************************/ +@media /* Comment */ print and (orientation:landscape) { + .class { + content: \\"style6.css\\"; + } +} + +/*!***************************************************************!*\\\\ + !*** css ./style8.css (media: screen and (min-width: 400px)) ***! + \\\\***************************************************************/ +@media screen and (min-width: 400px) { + .class { + content: \\"style8.css\\"; + } +} + +/*!**************************************************************!*\\\\ + !*** css ./style8.css (media: (prefers-color-scheme: dark)) ***! + \\\\**************************************************************/ +@media (prefers-color-scheme: dark) { + .class { + content: \\"style8.css\\"; + } +} + +/*!**************************************************!*\\\\ + !*** css ./style8.css (supports: display: flex) ***! + \\\\**************************************************/ +@supports (display: flex) { + .class { + content: \\"style8.css\\"; + } +} + +/*!******************************************************!*\\\\ + !*** css ./style8.css (supports: ((display: flex))) ***! + \\\\******************************************************/ +@supports (((display: flex))) { + .class { + content: \\"style8.css\\"; + } +} + +/*!********************************************************************************************************!*\\\\ + !*** css ./style8.css (supports: ((display: inline-grid))) (media: screen and (((min-width: 400px)))) ***! + \\\\********************************************************************************************************/ +@supports (((display: inline-grid))) { + @media screen and (((min-width: 400px))) { + .class { + content: \\"style8.css\\"; + } + } +} + +/*!**************************************************!*\\\\ + !*** css ./style8.css (supports: display: grid) ***! + \\\\**************************************************/ +@supports (display: grid) { + .class { + content: \\"style8.css\\"; + } +} + +/*!*****************************************************************************************!*\\\\ + !*** css ./style8.css (supports: display: flex) (media: screen and (min-width: 400px)) ***! + \\\\*****************************************************************************************/ +@supports (display: flex) { + @media screen and (min-width: 400px) { + .class { + content: \\"style8.css\\"; + } + } +} + +/*!*******************************************!*\\\\ + !*** css ./style8.css (layer: framework) ***! + \\\\*******************************************/ +@layer framework { + .class { + content: \\"style8.css\\"; + } +} + +/*!*****************************************!*\\\\ + !*** css ./style8.css (layer: default) ***! + \\\\*****************************************/ +@layer default { + .class { + content: \\"style8.css\\"; + } +} + +/*!**************************************!*\\\\ + !*** css ./style8.css (layer: base) ***! + \\\\**************************************/ +@layer base { + .class { + content: \\"style8.css\\"; + } +} + +/*!*******************************************************************!*\\\\ + !*** css ./style8.css (layer: default) (supports: display: flex) ***! + \\\\*******************************************************************/ +@layer default { + @supports (display: flex) { + .class { + content: \\"style8.css\\"; + } + } +} + +/*!**********************************************************************************************************!*\\\\ + !*** css ./style8.css (layer: default) (supports: display: flex) (media: screen and (min-width: 400px)) ***! + \\\\**********************************************************************************************************/ +@layer default { + @supports (display: flex) { + @media screen and (min-width: 400px) { + .class { + content: \\"style8.css\\"; + } + } + } +} + +/*!************************!*\\\\ + !*** css ./style2.css ***! + \\\\************************/ +@layer { + a { + color: red; + } +} + +/*!*********************************************************************************!*\\\\ + !*** css ./style9.css (media: unknown(default) unknown(display: flex) unknown) ***! + \\\\*********************************************************************************/ +@media unknown(default) unknown(display: flex) unknown { + .class { + content: \\"style9.css\\"; + } +} + +/*!**************************************************!*\\\\ + !*** css ./style9.css (media: unknown(default)) ***! + \\\\**************************************************/ +@media unknown(default) { + .class { + content: \\"style9.css\\"; + } +} + +/*!*************************!*\\\\ + !*** css ./style11.css ***! + \\\\*************************/ +.style11 { + color: red; +} + +/*!*************************!*\\\\ + !*** css ./style12.css ***! + \\\\*************************/ + +.style12 { + color: red; +} + +/*!*************************!*\\\\ + !*** css ./style13.css ***! + \\\\*************************/ +div{color: red;} + +/*!*************************!*\\\\ + !*** css ./style10.css ***! + \\\\*************************/ + + +.style10 { + color: red; +} + +/*!************************************************************************************!*\\\\ + !*** css ./media-deep-deep-nested.css (media: screen and (orientation: portrait)) ***! + \\\\************************************************************************************/ +@media screen and (min-width: 400px) { + @media screen and (max-width: 500px) { + @media screen and (orientation: portrait) { + .class { + deep-deep-nested: 1; + } + } + } +} + +/*!**************************************************************************!*\\\\ + !*** css ./media-deep-nested.css (media: screen and (max-width: 500px)) ***! + \\\\**************************************************************************/ +@media screen and (min-width: 400px) { + @media screen and (max-width: 500px) { + + .class { + deep-nested: 1; + } + } +} + +/*!*********************************************************************!*\\\\ + !*** css ./media-nested.css (media: screen and (min-width: 400px)) ***! + \\\\*********************************************************************/ +@media screen and (min-width: 400px) { + + .class { + nested: 1; + } +} + +/*!**********************************************************************!*\\\\ + !*** css ./supports-deep-deep-nested.css (supports: display: table) ***! + \\\\**********************************************************************/ +@supports (display: flex) { + @supports (display: grid) { + @supports (display: table) { + .class { + deep-deep-nested: 1; + } + } + } +} + +/*!****************************************************************!*\\\\ + !*** css ./supports-deep-nested.css (supports: display: grid) ***! + \\\\****************************************************************/ +@supports (display: flex) { + @supports (display: grid) { + + .class { + deep-nested: 1; + } + } +} + +/*!***********************************************************!*\\\\ + !*** css ./supports-nested.css (supports: display: flex) ***! + \\\\***********************************************************/ +@supports (display: flex) { + + .class { + nested: 1; + } +} + +/*!*****************************************************!*\\\\ + !*** css ./layer-deep-deep-nested.css (layer: baz) ***! + \\\\*****************************************************/ +@layer foo { + @layer bar { + @layer baz { + .class { + deep-deep-nested: 1; + } + } + } +} + +/*!************************************************!*\\\\ + !*** css ./layer-deep-nested.css (layer: bar) ***! + \\\\************************************************/ +@layer foo { + @layer bar { + + .class { + deep-nested: 1; + } + } +} + +/*!*******************************************!*\\\\ + !*** css ./layer-nested.css (layer: foo) ***! + \\\\*******************************************/ +@layer foo { + + .class { + nested: 1; + } +} + +/*!*********************************************************************************************************************!*\\\\ + !*** css ./all-deep-deep-nested.css (layer: baz) (supports: display: table) (media: screen and (min-width: 600px)) ***! + \\\\*********************************************************************************************************************/ +@layer foo { + @supports (display: flex) { + @media screen and (min-width: 400px) { + @layer bar { + @supports (display: grid) { + @media screen and (min-width: 500px) { + @layer baz { + @supports (display: table) { + @media screen and (min-width: 600px) { + .class { + deep-deep-nested: 1; + } + } + } + } + } + } + } + } + } +} + +/*!***************************************************************************************************************!*\\\\ + !*** css ./all-deep-nested.css (layer: bar) (supports: display: grid) (media: screen and (min-width: 500px)) ***! + \\\\***************************************************************************************************************/ +@layer foo { + @supports (display: flex) { + @media screen and (min-width: 400px) { + @layer bar { + @supports (display: grid) { + @media screen and (min-width: 500px) { + + .class { + deep-nested: 1; + } + } + } + } + } + } +} + +/*!**********************************************************************************************************!*\\\\ + !*** css ./all-nested.css (layer: foo) (supports: display: flex) (media: screen and (min-width: 400px)) ***! + \\\\**********************************************************************************************************/ +@layer foo { + @supports (display: flex) { + @media screen and (min-width: 400px) { + + .class { + nested: 1; + } + } + } +} + +/*!*****************************************************!*\\\\ + !*** css ./mixed-deep-deep-nested.css (layer: bar) ***! + \\\\*****************************************************/ +@media screen and (min-width: 400px) { + @supports (display: flex) { + @layer bar { + .class { + deep-deep-nested: 1; + } + } + } +} + +/*!*************************************************************!*\\\\ + !*** css ./mixed-deep-nested.css (supports: display: flex) ***! + \\\\*************************************************************/ +@media screen and (min-width: 400px) { + @supports (display: flex) { + + .class { + deep-nested: 1; + } + } +} + +/*!*********************************************************************!*\\\\ + !*** css ./mixed-nested.css (media: screen and (min-width: 400px)) ***! + \\\\*********************************************************************/ +@media screen and (min-width: 400px) { + + .class { + nested: 1; + } +} + +/*!********************************************!*\\\\ + !*** css ./anonymous-deep-deep-nested.css ***! + \\\\********************************************/ +@layer { + @layer { + @layer { + .class { + deep-deep-nested: 1; + } + } + } +} + +/*!***************************************!*\\\\ + !*** css ./anonymous-deep-nested.css ***! + \\\\***************************************/ +@layer { + @layer { + + .class { + deep-nested: 1; + } + } +} + +/*!*****************************************************!*\\\\ + !*** css ./layer-deep-deep-nested.css (layer: baz) ***! + \\\\*****************************************************/ +@layer { + @layer base { + @layer baz { + .class { + deep-deep-nested: 1; + } + } + } +} + +/*!*************************************************!*\\\\ + !*** css ./layer-deep-nested.css (layer: base) ***! + \\\\*************************************************/ +@layer { + @layer base { + + .class { + deep-nested: 1; + } + } +} + +/*!**********************************!*\\\\ + !*** css ./anonymous-nested.css ***! + \\\\**********************************/ +@layer { + + .class { + deep-nested: 1; + } +} + +/*!************************************************************************************!*\\\\ + !*** css ./media-deep-deep-nested.css (media: screen and (orientation: portrait)) ***! + \\\\************************************************************************************/ +@media screen and (orientation: portrait) { + .class { + deep-deep-nested: 1; + } +} + +/*!**************************************************!*\\\\ + !*** css ./style8.css (supports: display: flex) ***! + \\\\**************************************************/ +@media screen and (orientation: portrait) { + @supports (display: flex) { + .class { + content: \\"style8.css\\"; + } + } +} + +/*!******************************************************************************!*\\\\ + !*** css ./duplicate-nested.css (media: screen and (orientation: portrait)) ***! + \\\\******************************************************************************/ +@media screen and (orientation: portrait) { + + .class { + duplicate-nested: true; + } +} + +/*!********************************************!*\\\\ + !*** css ./anonymous-deep-deep-nested.css ***! + \\\\********************************************/ +@supports (display: flex) { + @media screen and (orientation: portrait) { + @layer { + @layer { + .class { + deep-deep-nested: 1; + } + } + } + } +} + +/*!***************************************!*\\\\ + !*** css ./anonymous-deep-nested.css ***! + \\\\***************************************/ +@supports (display: flex) { + @media screen and (orientation: portrait) { + @layer { + + .class { + deep-nested: 1; + } + } + } +} + +/*!*****************************************************!*\\\\ + !*** css ./layer-deep-deep-nested.css (layer: baz) ***! + \\\\*****************************************************/ +@supports (display: flex) { + @media screen and (orientation: portrait) { + @layer base { + @layer baz { + .class { + deep-deep-nested: 1; + } + } + } + } +} + +/*!*************************************************!*\\\\ + !*** css ./layer-deep-nested.css (layer: base) ***! + \\\\*************************************************/ +@supports (display: flex) { + @media screen and (orientation: portrait) { + @layer base { + + .class { + deep-nested: 1; + } + } + } +} + +/*!********************************************************************************************************!*\\\\ + !*** css ./anonymous-nested.css (supports: display: flex) (media: screen and (orientation: portrait)) ***! + \\\\********************************************************************************************************/ +@supports (display: flex) { + @media screen and (orientation: portrait) { + + .class { + deep-nested: 1; + } + } +} + +/*!*********************************************************************************************************************!*\\\\ + !*** css ./all-deep-deep-nested.css (layer: baz) (supports: display: table) (media: screen and (min-width: 600px)) ***! + \\\\*********************************************************************************************************************/ +@layer super.foo { + @supports (display: flex) { + @media screen and (min-width: 400px) { + @layer bar { + @supports (display: grid) { + @media screen and (min-width: 500px) { + @layer baz { + @supports (display: table) { + @media screen and (min-width: 600px) { + .class { + deep-deep-nested: 1; + } + } + } + } + } + } + } + } + } +} + +/*!***************************************************************************************************************!*\\\\ + !*** css ./all-deep-nested.css (layer: bar) (supports: display: grid) (media: screen and (min-width: 500px)) ***! + \\\\***************************************************************************************************************/ +@layer super.foo { + @supports (display: flex) { + @media screen and (min-width: 400px) { + @layer bar { + @supports (display: grid) { + @media screen and (min-width: 500px) { + + .class { + deep-nested: 1; + } + } + } + } + } + } +} + +/*!****************************************************************************************************************!*\\\\ + !*** css ./all-nested.css (layer: super.foo) (supports: display: flex) (media: screen and (min-width: 400px)) ***! + \\\\****************************************************************************************************************/ +@layer super.foo { + @supports (display: flex) { + @media screen and (min-width: 400px) { + + .class { + nested: 1; + } + } + } +} + +/*!***************************************************************************************************************!*\\\\ + !*** css ./style2.css?warning=6 (supports: unknown: layer(super.foo)) (media: screen and (min-width: 400px)) ***! + \\\\***************************************************************************************************************/ +@supports (unknown: layer(super.foo)) { + @media screen and (min-width: 400px) { + a { + color: red; + } + } +} + +/*!***************************************************************************************************************!*\\\\ + !*** css ./style2.css?warning=7 (supports: url: url(\\"./unknown.css\\")) (media: screen and (min-width: 400px)) ***! + \\\\***************************************************************************************************************/ +@supports (url: url(\\"./unknown.css\\")) { + @media screen and (min-width: 400px) { + a { + color: red; + } + } +} + +/*!*************************************************************************************************************!*\\\\ + !*** css ./style2.css?warning=8 (supports: url: url(./unknown.css)) (media: screen and (min-width: 400px)) ***! + \\\\*************************************************************************************************************/ +@supports (url: url(./unknown.css)) { + @media screen and (min-width: 400px) { + a { + color: red; + } + } +} + +/*!***************************************************************************************************************************************!*\\\\ + !*** css ./style2.css?foo=unknown (layer: super.foo) (supports: display: flex) (media: unknown(\\"foo\\") screen and (min-width: 400px)) ***! + \\\\***************************************************************************************************************************************/ +@layer super.foo { + @supports (display: flex) { + @media unknown(\\"foo\\") screen and (min-width: 400px) { + a { + color: red; + } + } + } +} + +/*!******************************************************************************************************************************************************!*\\\\ + !*** css ./style2.css?foo=unknown1 (layer: super.foo) (supports: display: url(\\"./unknown.css\\")) (media: unknown(foo) screen and (min-width: 400px)) ***! + \\\\******************************************************************************************************************************************************/ +@layer super.foo { + @supports (display: url(\\"./unknown.css\\")) { + @media unknown(foo) screen and (min-width: 400px) { + a { + color: red; + } + } + } +} + +/*!*********************************************************************************************************************************************!*\\\\ + !*** css ./style2.css?foo=unknown2 (layer: super.foo) (supports: display: url(./unknown.css)) (media: \\"foo\\" screen and (min-width: 400px)) ***! + \\\\*********************************************************************************************************************************************/ +@layer super.foo { + @supports (display: url(./unknown.css)) { + @media \\"foo\\" screen and (min-width: 400px) { + a { + color: red; + } + } + } +} + +/*!***************************************************!*\\\\ + !*** css ./style2.css?unknown3 (media: \\"string\\") ***! + \\\\***************************************************/ +@media \\"string\\" { + a { + color: red; + } +} + +/*!****************************************!*\\\\ + !*** css ./style2.css?after-namespace ***! + \\\\****************************************/ +a { + color: red; +} + +/*!*************************************************************************!*\\\\ + !*** css ./style2.css?multiple=1 (media: url(./style2.css?multiple=2)) ***! + \\\\*************************************************************************/ +@media url(./style2.css?multiple=2) { + a { + color: red; + } +} + +/*!***********************************!*\\\\ + !*** css ./style2.css?multiple=3 ***! + \\\\***********************************/ +a { + color: red; +} + +/*!**********************************!*\\\\ + !*** css ./style2.css?strange=3 ***! + \\\\**********************************/ +a { + color: red; +} + +/*!***********************!*\\\\ + !*** css ./style.css ***! + \\\\***********************/ + +/* Has the same URL */ + + + + + + + + +/* anonymous */ + +/* All unknown parse as media for compatibility */ + + + +/* Inside support */ + + +/** Possible syntax in future */ + + +/** Unknown */ + +@import-normalize; + +/** Warnings */ + +@import nourl(test.css); +@import ; +@import foo-bar; +@import layer(super.foo) \\"./style2.css?warning=1\\" supports(display: flex) screen and (min-width: 400px); +@import layer(super.foo) supports(display: flex) \\"./style2.css?warning=2\\" screen and (min-width: 400px); +@import layer(super.foo) supports(display: flex) screen and (min-width: 400px) \\"./style2.css?warning=3\\"; +@import layer(super.foo) url(\\"./style2.css?warning=4\\") supports(display: flex) screen and (min-width: 400px); +@import layer(super.foo) supports(display: flex) url(\\"./style2.css?warning=5\\") screen and (min-width: 400px); +@import layer(super.foo) supports(display: flex) screen and (min-width: 400px) url(\\"./style2.css?warning=6\\"); +@import url(\\"/style2.css?warning=6\\") supports(display: flex) layer(super.foo) screen and (min-width: 400px); +@namespace url(http://www.w3.org/1999/xhtml); +@import supports(background: url(\\"./img.png\\")); +@import supports(background: url(\\"./img.png\\")) screen and (min-width: 400px); +@import layer(test) supports(background: url(\\"./img.png\\")) screen and (min-width: 400px); +@import screen and (min-width: 400px); + + + +body { + background: red; +} + +head{--webpack-main:https\\\\:\\\\/\\\\/test\\\\.cases\\\\/path\\\\/\\\\.\\\\.\\\\/\\\\.\\\\.\\\\/\\\\.\\\\.\\\\/\\\\.\\\\.\\\\/configCases\\\\/css\\\\/css-import\\\\/external\\\\.css,\\\\/\\\\/example\\\\.com\\\\/style\\\\.css,https\\\\:\\\\/\\\\/fonts\\\\.googleapis\\\\.com\\\\/css\\\\?family\\\\=Roboto,https\\\\:\\\\/\\\\/fonts\\\\.googleapis\\\\.com\\\\/css\\\\?family\\\\=Noto\\\\+Sans\\\\+TC,https\\\\:\\\\/\\\\/fonts\\\\.googleapis\\\\.com\\\\/css\\\\?family\\\\=Noto\\\\+Sans\\\\+TC\\\\|Roboto,https\\\\:\\\\/\\\\/fonts\\\\.googleapis\\\\.com\\\\/css\\\\?family\\\\=Noto\\\\+Sans\\\\+TC\\\\|Roboto\\\\?foo\\\\=1,https\\\\:\\\\/\\\\/test\\\\.cases\\\\/path\\\\/\\\\.\\\\.\\\\/\\\\.\\\\.\\\\/\\\\.\\\\.\\\\/\\\\.\\\\.\\\\/configCases\\\\/css\\\\/css-import\\\\/external1\\\\.css,https\\\\:\\\\/\\\\/test\\\\.cases\\\\/path\\\\/\\\\.\\\\.\\\\/\\\\.\\\\.\\\\/\\\\.\\\\.\\\\/\\\\.\\\\.\\\\/configCases\\\\/css\\\\/css-import\\\\/external2\\\\.css,external-1\\\\.css,external-2\\\\.css,external-3\\\\.css,external-4\\\\.css,external-5\\\\.css,external-6\\\\.css,external-7\\\\.css,external-8\\\\.css,external-9\\\\.css,external-10\\\\.css,external-11\\\\.css,external-12\\\\.css,external-13\\\\.css,external-14\\\\.css,&\\\\.\\\\/node_modules\\\\/style-library\\\\/styles\\\\.css,&\\\\.\\\\/node_modules\\\\/main-field\\\\/styles\\\\.css,&\\\\.\\\\/node_modules\\\\/package-with-exports\\\\/style\\\\.css,&\\\\.\\\\/extensions-imported\\\\.mycss,&\\\\.\\\\/file\\\\.less,&\\\\.\\\\/with-less-import\\\\.css,&\\\\.\\\\/prefer-relative\\\\.css,&\\\\.\\\\/node_modules\\\\/condition-names-style\\\\/default\\\\.css,&\\\\.\\\\/node_modules\\\\/condition-names-style-mode\\\\/mode\\\\.css,&\\\\.\\\\/node_modules\\\\/condition-names-subpath\\\\/dist\\\\/custom\\\\.css,&\\\\.\\\\/node_modules\\\\/condition-names-subpath-extra\\\\/dist\\\\/custom\\\\.css,&\\\\.\\\\/node_modules\\\\/condition-names-style-less\\\\/default\\\\.less,&\\\\.\\\\/node_modules\\\\/condition-names-custom-name\\\\/custom-name\\\\.css,&\\\\.\\\\/node_modules\\\\/style-and-main-library\\\\/styles\\\\.css,&\\\\.\\\\/node_modules\\\\/condition-names-webpack\\\\/webpack\\\\.css,&\\\\.\\\\/node_modules\\\\/condition-names-style-nested\\\\/default\\\\.css,&\\\\.\\\\/style-import\\\\.css,&\\\\.\\\\/print\\\\.css\\\\?foo\\\\=1,&\\\\.\\\\/print\\\\.css\\\\?foo\\\\=2,&\\\\.\\\\/print\\\\.css\\\\?foo\\\\=3,&\\\\.\\\\/print\\\\.css\\\\?foo\\\\=4,&\\\\.\\\\/print\\\\.css\\\\?foo\\\\=5,&\\\\.\\\\/print\\\\.css\\\\?foo\\\\=6,&\\\\.\\\\/print\\\\.css\\\\?foo\\\\=7,&\\\\.\\\\/print\\\\.css\\\\?foo\\\\=8,&\\\\.\\\\/print\\\\.css\\\\?foo\\\\=9,&\\\\.\\\\/print\\\\.css\\\\?foo\\\\=10,&\\\\.\\\\/print\\\\.css\\\\?foo\\\\=11,&\\\\.\\\\/print\\\\.css\\\\?foo\\\\=12,&\\\\.\\\\/print\\\\.css\\\\?foo\\\\=13,&\\\\.\\\\/print\\\\.css\\\\?foo\\\\=14,&\\\\.\\\\/print\\\\.css\\\\?foo\\\\=15,&\\\\.\\\\/print\\\\.css\\\\?foo\\\\=16,&\\\\.\\\\/print\\\\.css\\\\?foo\\\\=17,&\\\\.\\\\/print\\\\.css\\\\?foo\\\\=18,&\\\\.\\\\/print\\\\.css\\\\?foo\\\\=19,&\\\\.\\\\/print\\\\.css\\\\?foo\\\\=20,&\\\\.\\\\/print\\\\.css\\\\?foo\\\\=21,&\\\\.\\\\/imported\\\\.css\\\\?1832,&\\\\.\\\\/imported\\\\.css\\\\?e0bb,&\\\\.\\\\/imported\\\\.css\\\\?769a,&\\\\.\\\\/imported\\\\.css\\\\?d4d6,&\\\\.\\\\/style2\\\\.css\\\\?foo\\\\=1,&\\\\.\\\\/style2\\\\.css\\\\?foo\\\\=2,&\\\\.\\\\/style2\\\\.css\\\\?foo\\\\=3,&\\\\.\\\\/style2\\\\.css\\\\?foo\\\\=4,&\\\\.\\\\/style2\\\\.css\\\\?foo\\\\=5,&\\\\.\\\\/style2\\\\.css\\\\?foo\\\\=6,&\\\\.\\\\/style2\\\\.css\\\\?foo\\\\=7,&\\\\.\\\\/style2\\\\.css\\\\?foo\\\\=8,&\\\\.\\\\/style2\\\\.css\\\\?foo\\\\=9,&\\\\.\\\\/style2\\\\.css\\\\?cf0d,&\\\\.\\\\/style2\\\\.css\\\\?dfe6,&\\\\.\\\\/style2\\\\.css\\\\?7d49,&\\\\.\\\\/test\\\\.css\\\\?foo\\\\=1\\\\&bar\\\\=1,&\\\\.\\\\/style2\\\\.css\\\\?foo\\\\=1\\\\&bar\\\\=1\\\\#hash\\\\?63d2,&\\\\.\\\\/style2\\\\.css\\\\?foo\\\\=1\\\\&bar\\\\=1\\\\#hash\\\\?e75b,&\\\\.\\\\/style3\\\\.css\\\\?bar\\\\=1,&\\\\.\\\\/style3\\\\.css\\\\?bar\\\\=2,&\\\\.\\\\/style3\\\\.css\\\\?bar\\\\=3,&\\\\.\\\\/style3\\\\.css\\\\?\\\\=bar4,&\\\\.\\\\/styl\\\\'le7\\\\.css,&\\\\.\\\\/styl\\\\'le7\\\\.css\\\\?foo\\\\=1,&\\\\.\\\\/test\\\\ test\\\\.css,&\\\\.\\\\/test\\\\ test\\\\.css\\\\?foo\\\\=1,&\\\\.\\\\/test\\\\ test\\\\.css\\\\?foo\\\\=2,&\\\\.\\\\/test\\\\ test\\\\.css\\\\?foo\\\\=3,&\\\\.\\\\/test\\\\ test\\\\.css\\\\?foo\\\\=4,&\\\\.\\\\/test\\\\ test\\\\.css\\\\?foo\\\\=5,&\\\\.\\\\/test\\\\.css,&\\\\.\\\\/test\\\\.css\\\\?foo\\\\=1,&\\\\.\\\\/test\\\\.css\\\\?foo\\\\=2,&\\\\.\\\\/test\\\\.css\\\\?foo\\\\=3,&\\\\.\\\\/test\\\\ test\\\\.css\\\\?foo\\\\=6,&\\\\.\\\\/test\\\\ test\\\\.css\\\\?foo\\\\=7,&\\\\.\\\\/test\\\\ test\\\\.css\\\\?foo\\\\=8,&\\\\.\\\\/test\\\\ test\\\\.css\\\\?foo\\\\=9,&\\\\.\\\\/test\\\\ test\\\\.css\\\\?fpp\\\\=10,&\\\\.\\\\/test\\\\ test\\\\.css\\\\?foo\\\\=11,&\\\\.\\\\/style6\\\\.css\\\\?foo\\\\=bazz,&\\\\.\\\\/string-loader\\\\.js\\\\?esModule\\\\=false\\\\!\\\\.\\\\/test\\\\.css\\\\?10e0,&\\\\.\\\\/style4\\\\.css\\\\?foo\\\\=bar,&\\\\.\\\\/style4\\\\.css\\\\?foo\\\\=bar\\\\#hash,&\\\\.\\\\/style4\\\\.css\\\\?\\\\#hash,&\\\\.\\\\/style4\\\\.css\\\\?foo\\\\=1,&\\\\.\\\\/style4\\\\.css\\\\?foo\\\\=2,&\\\\.\\\\/style4\\\\.css\\\\?foo\\\\=3,&\\\\.\\\\/style4\\\\.css\\\\?foo\\\\=4,&\\\\.\\\\/style4\\\\.css\\\\?foo\\\\=5,&\\\\.\\\\/string-loader\\\\.js\\\\?esModule\\\\=false\\\\!\\\\.\\\\/test\\\\.css\\\\?6393,&data\\\\:text\\\\/css\\\\;charset\\\\=utf-8\\\\,a\\\\%20\\\\%7B\\\\%0D\\\\%0A\\\\%20\\\\%20color\\\\%3A\\\\%20red\\\\%3B\\\\%0D\\\\%0A\\\\%7D,&data\\\\:text\\\\/css\\\\;charset\\\\=utf-8\\\\,a\\\\%20\\\\%7B\\\\%0D\\\\%0A\\\\%20\\\\%20color\\\\%3A\\\\%20blue\\\\%3B\\\\%0D\\\\%0A\\\\%7D,&data\\\\:text\\\\/css\\\\;charset\\\\=utf-8\\\\;base64\\\\,YSB7DQogIGNvbG9yOiByZWQ7DQp9,&\\\\.\\\\/style5\\\\.css\\\\?foo\\\\=1,&\\\\.\\\\/style5\\\\.css\\\\?foo\\\\=2,&\\\\.\\\\/style5\\\\.css\\\\?foo\\\\=3,&\\\\.\\\\/style5\\\\.css\\\\?foo\\\\=4,&\\\\.\\\\/style5\\\\.css\\\\?foo\\\\=5,&\\\\.\\\\/style5\\\\.css\\\\?foo\\\\=6,&\\\\.\\\\/style5\\\\.css\\\\?foo\\\\=7,&\\\\.\\\\/style5\\\\.css\\\\?foo\\\\=8,&\\\\.\\\\/layer\\\\.css\\\\?foo\\\\=1,&\\\\.\\\\/layer\\\\.css\\\\?foo\\\\=2,&\\\\.\\\\/layer\\\\.css\\\\?foo\\\\=3\\\\?1ab5,&\\\\.\\\\/layer\\\\.css\\\\?foo\\\\=3\\\\?19e1,&\\\\.\\\\/layer\\\\.css\\\\?foo\\\\=4,&\\\\.\\\\/layer\\\\.css\\\\?foo\\\\=5,&\\\\.\\\\/layer\\\\.css\\\\?foo\\\\=6,&\\\\.\\\\/layer\\\\.css\\\\?foo\\\\=7,&\\\\.\\\\/style6\\\\.css,&\\\\.\\\\/style6\\\\.css\\\\?foo\\\\=1,&\\\\.\\\\/style6\\\\.css\\\\?foo\\\\=2,&\\\\.\\\\/style6\\\\.css\\\\?foo\\\\=3,&\\\\.\\\\/style6\\\\.css\\\\?foo\\\\=4,&\\\\.\\\\/style6\\\\.css\\\\?foo\\\\=5,&\\\\.\\\\/style6\\\\.css\\\\?foo\\\\=6,&\\\\.\\\\/style6\\\\.css\\\\?foo\\\\=7,&\\\\.\\\\/style6\\\\.css\\\\?foo\\\\=8,&\\\\.\\\\/style6\\\\.css\\\\?foo\\\\=9,&\\\\.\\\\/style6\\\\.css\\\\?foo\\\\=10,&\\\\.\\\\/style6\\\\.css\\\\?foo\\\\=11,&\\\\.\\\\/style6\\\\.css\\\\?foo\\\\=12,&\\\\.\\\\/style6\\\\.css\\\\?foo\\\\=13,&\\\\.\\\\/style6\\\\.css\\\\?foo\\\\=14,&\\\\.\\\\/style6\\\\.css\\\\?foo\\\\=15,&\\\\.\\\\/style6\\\\.css\\\\?foo\\\\=16,&\\\\.\\\\/style6\\\\.css\\\\?foo\\\\=17,&\\\\.\\\\/style6\\\\.css\\\\?foo\\\\=18,&\\\\.\\\\/style8\\\\.css\\\\?b84b,&\\\\.\\\\/style8\\\\.css\\\\?5dc5,&\\\\.\\\\/style8\\\\.css\\\\?71be,&\\\\.\\\\/style8\\\\.css\\\\?386a,&\\\\.\\\\/style8\\\\.css\\\\?568a,&\\\\.\\\\/style8\\\\.css\\\\?b9af,&\\\\.\\\\/style8\\\\.css\\\\?7300,&\\\\.\\\\/style8\\\\.css\\\\?6efd,&\\\\.\\\\/style8\\\\.css\\\\?288c,&\\\\.\\\\/style8\\\\.css\\\\?1094,&\\\\.\\\\/style8\\\\.css\\\\?38bf,&\\\\.\\\\/style8\\\\.css\\\\?d697,&\\\\.\\\\/style2\\\\.css\\\\?0aae,&\\\\.\\\\/style9\\\\.css\\\\?8e91,&\\\\.\\\\/style9\\\\.css\\\\?71b5,&\\\\.\\\\/style11\\\\.css,&\\\\.\\\\/style12\\\\.css,&\\\\.\\\\/style13\\\\.css,&\\\\.\\\\/style10\\\\.css,&\\\\.\\\\/media-deep-deep-nested\\\\.css\\\\?ef21,&\\\\.\\\\/media-deep-nested\\\\.css,&\\\\.\\\\/media-nested\\\\.css,&\\\\.\\\\/supports-deep-deep-nested\\\\.css,&\\\\.\\\\/supports-deep-nested\\\\.css,&\\\\.\\\\/supports-nested\\\\.css,&\\\\.\\\\/layer-deep-deep-nested\\\\.css\\\\?5660,&\\\\.\\\\/layer-deep-nested\\\\.css\\\\?9fd1,&\\\\.\\\\/layer-nested\\\\.css,&\\\\.\\\\/all-deep-deep-nested\\\\.css\\\\?af0a,&\\\\.\\\\/all-deep-nested\\\\.css\\\\?4e94,&\\\\.\\\\/all-nested\\\\.css\\\\?c0fa,&\\\\.\\\\/mixed-deep-deep-nested\\\\.css,&\\\\.\\\\/mixed-deep-nested\\\\.css,&\\\\.\\\\/mixed-nested\\\\.css,&\\\\.\\\\/anonymous-deep-deep-nested\\\\.css\\\\?1f16,&\\\\.\\\\/anonymous-deep-nested\\\\.css\\\\?c0a8,&\\\\.\\\\/layer-deep-deep-nested\\\\.css\\\\?4bce,&\\\\.\\\\/layer-deep-nested\\\\.css\\\\?a03f,&\\\\.\\\\/anonymous-nested\\\\.css\\\\?390d,&\\\\.\\\\/media-deep-deep-nested\\\\.css\\\\?7047,&\\\\.\\\\/style8\\\\.css\\\\?8af1,&\\\\.\\\\/duplicate-nested\\\\.css,&\\\\.\\\\/anonymous-deep-deep-nested\\\\.css\\\\?9cec,&\\\\.\\\\/anonymous-deep-nested\\\\.css\\\\?dea4,&\\\\.\\\\/layer-deep-deep-nested\\\\.css\\\\?4897,&\\\\.\\\\/layer-deep-nested\\\\.css\\\\?4579,&\\\\.\\\\/anonymous-nested\\\\.css\\\\?df05,&\\\\.\\\\/all-deep-deep-nested\\\\.css\\\\?55ab,&\\\\.\\\\/all-deep-nested\\\\.css\\\\?1513,&\\\\.\\\\/all-nested\\\\.css\\\\?ccc9,&\\\\.\\\\/style2\\\\.css\\\\?warning\\\\=6,&\\\\.\\\\/style2\\\\.css\\\\?warning\\\\=7,&\\\\.\\\\/style2\\\\.css\\\\?warning\\\\=8,&\\\\.\\\\/style2\\\\.css\\\\?foo\\\\=unknown,&\\\\.\\\\/style2\\\\.css\\\\?foo\\\\=unknown1,&\\\\.\\\\/style2\\\\.css\\\\?foo\\\\=unknown2,&\\\\.\\\\/style2\\\\.css\\\\?unknown3,&\\\\.\\\\/style2\\\\.css\\\\?after-namespace,&\\\\.\\\\/style2\\\\.css\\\\?multiple\\\\=1,&\\\\.\\\\/style2\\\\.css\\\\?multiple\\\\=3,&\\\\.\\\\/style2\\\\.css\\\\?strange\\\\=3,&\\\\.\\\\/style\\\\.css;}", +] +`; + +exports[`ConfigTestCases css css-modules exported tests should allow to create css modules 1`] = ` +"/*!******************************!*\\\\ + !*** css ./style.module.css ***! + \\\\******************************/ +._-_style_module_css-class { + color: red; +} + +._-_style_module_css-local1, +._-_style_module_css-local2 .global, +._-_style_module_css-local3 { + color: green; +} + +.global ._-_style_module_css-local4 { + color: yellow; +} + +._-_style_module_css-local5.global._-_style_module_css-local6 { + color: blue; +} + +._-_style_module_css-local7 div:not(._-_style_module_css-disabled, ._-_style_module_css-mButtonDisabled, ._-_style_module_css-tipOnly) { + pointer-events: initial !important; +} + +._-_style_module_css-local8 :is(div._-_style_module_css-parent1._-_style_module_css-child1._-_style_module_css-vertical-tiny, + div._-_style_module_css-parent1._-_style_module_css-child1._-_style_module_css-vertical-small, + div._-_style_module_css-otherDiv._-_style_module_css-horizontal-tiny, + div._-_style_module_css-otherDiv._-_style_module_css-horizontal-small div._-_style_module_css-description) { + max-height: 0; + margin: 0; + overflow: hidden; +} + +._-_style_module_css-local9 :matches(div._-_style_module_css-parent1._-_style_module_css-child1._-_style_module_css-vertical-tiny, + div._-_style_module_css-parent1._-_style_module_css-child1._-_style_module_css-vertical-small, + div._-_style_module_css-otherDiv._-_style_module_css-horizontal-tiny, + div._-_style_module_css-otherDiv._-_style_module_css-horizontal-small div._-_style_module_css-description) { + max-height: 0; + margin: 0; + overflow: hidden; +} + +._-_style_module_css-local10 :where(div._-_style_module_css-parent1._-_style_module_css-child1._-_style_module_css-vertical-tiny, + div._-_style_module_css-parent1._-_style_module_css-child1._-_style_module_css-vertical-small, + div._-_style_module_css-otherDiv._-_style_module_css-horizontal-tiny, + div._-_style_module_css-otherDiv._-_style_module_css-horizontal-small div._-_style_module_css-description) { + max-height: 0; + margin: 0; + overflow: hidden; +} + +._-_style_module_css-local11 div:has(._-_style_module_css-disabled, ._-_style_module_css-mButtonDisabled, ._-_style_module_css-tipOnly) { + pointer-events: initial !important; +} + +._-_style_module_css-local12 div:current(p, span) { + background-color: yellow; +} + +._-_style_module_css-local13 div:past(p, span) { + display: none; +} + +._-_style_module_css-local14 div:future(p, span) { + background-color: yellow; +} + +._-_style_module_css-local15 div:-moz-any(ol, ul, menu, dir) { + list-style-type: square; +} + +._-_style_module_css-local16 li:-webkit-any(:first-child, :last-child) { + background-color: aquamarine; +} + +._-_style_module_css-local9 :matches(div._-_style_module_css-parent1._-_style_module_css-child1._-_style_module_css-vertical-tiny, + div._-_style_module_css-parent1._-_style_module_css-child1._-_style_module_css-vertical-small, + div._-_style_module_css-otherDiv._-_style_module_css-horizontal-tiny, + div._-_style_module_css-otherDiv._-_style_module_css-horizontal-small div._-_style_module_css-description) { + max-height: 0; + margin: 0; + overflow: hidden; +} + +._-_style_module_css-nested1.nested2._-_style_module_css-nested3 { + color: pink; +} + +#_-_style_module_css-ident { + color: purple; +} + +@keyframes _-_style_module_css-localkeyframes{ + 0% { + left: var(---_style_module_css-pos1x); + top: var(---_style_module_css-pos1y); + color: var(--theme-color1); + } + 100% { + left: var(---_style_module_css-pos2x); + top: var(---_style_module_css-pos2y); + color: var(--theme-color2); + } +} + +@keyframes _-_style_module_css-localkeyframes2{ + 0% { + left: 0; + } + 100% { + left: 100px; + } +} + +._-_style_module_css-animation { + animation-name: _-_style_module_css-localkeyframes; + animation: 3s ease-in 1s 2 reverse both paused _-_style_module_css-localkeyframes, _-_style_module_css-localkeyframes2; + ---_style_module_css-pos1x: 0px; + ---_style_module_css-pos1y: 0px; + ---_style_module_css-pos2x: 10px; + ---_style_module_css-pos2y: 20px; +} + +/* .composed { + composes: local1; + composes: local2; +} */ + +._-_style_module_css-vars { + color: var(---_style_module_css-local-color); + ---_style_module_css-local-color: red; +} + +._-_style_module_css-globalVars { + color: var(--global-color); + --global-color: red; +} + +@media (min-width: 1600px) { + ._-_style_module_css-wideScreenClass { + color: var(---_style_module_css-local-color); + ---_style_module_css-local-color: green; + } +} + +@media screen and (max-width: 600px) { + ._-_style_module_css-narrowScreenClass { + color: var(---_style_module_css-local-color); + ---_style_module_css-local-color: purple; + } +} + +@supports (display: grid) { + ._-_style_module_css-displayGridInSupports { + display: grid; + } +} + +@supports not (display: grid) { + ._-_style_module_css-floatRightInNegativeSupports { + float: right; + } +} + +@supports (display: flex) { + @media screen and (min-width: 900px) { + ._-_style_module_css-displayFlexInMediaInSupports { + display: flex; + } + } +} + +@media screen and (min-width: 900px) { + @supports (display: flex) { + ._-_style_module_css-displayFlexInSupportsInMedia { + display: flex; + } + } +} + +@MEDIA screen and (min-width: 900px) { + @SUPPORTS (display: flex) { + ._-_style_module_css-displayFlexInSupportsInMediaUpperCase { + display: flex; + } + } +} + +._-_style_module_css-animationUpperCase { + ANIMATION-NAME: _-_style_module_css-localkeyframesUPPERCASE; + ANIMATION: 3s ease-in 1s 2 reverse both paused _-_style_module_css-localkeyframesUPPERCASE, _-_style_module_css-localkeyframes2UPPPERCASE; + ---_style_module_css-pos1x: 0px; + ---_style_module_css-pos1y: 0px; + ---_style_module_css-pos2x: 10px; + ---_style_module_css-pos2y: 20px; +} + +@KEYFRAMES _-_style_module_css-localkeyframesUPPERCASE{ + 0% { + left: VAR(---_style_module_css-pos1x); + top: VAR(---_style_module_css-pos1y); + color: VAR(--theme-color1); + } + 100% { + left: VAR(---_style_module_css-pos2x); + top: VAR(---_style_module_css-pos2y); + color: VAR(--theme-color2); + } +} + +@KEYframes _-_style_module_css-localkeyframes2UPPPERCASE{ + 0% { + left: 0; + } + 100% { + left: 100px; + } +} + +.globalUpperCase ._-_style_module_css-localUpperCase { + color: yellow; +} + +._-_style_module_css-VARS { + color: VAR(---_style_module_css-LOCAL-COLOR); + ---_style_module_css-LOCAL-COLOR: red; +} + +._-_style_module_css-globalVarsUpperCase { + COLOR: VAR(--GLOBAR-COLOR); + --GLOBAR-COLOR: red; +} + +@supports (top: env(safe-area-inset-top, 0)) { + ._-_style_module_css-inSupportScope { + color: red; + } +} + +._-_style_module_css-a { + animation: 3s _-_style_module_css-animationName; + -webkit-animation: 3s _-_style_module_css-animationName; +} + +._-_style_module_css-b { + animation: _-_style_module_css-animationName 3s; + -webkit-animation: _-_style_module_css-animationName 3s; +} + +._-_style_module_css-c { + animation-name: _-_style_module_css-animationName; + -webkit-animation-name: _-_style_module_css-animationName; +} + +._-_style_module_css-d { + ---_style_module_css-animation-name: animationName; +} + +@keyframes _-_style_module_css-animationName{ + 0% { + background: white; + } + 100% { + background: red; + } +} + +@-webkit-keyframes _-_style_module_css-animationName{ + 0% { + background: white; + } + 100% { + background: red; + } +} + +@-moz-keyframes _-_style_module_css-mozAnimationName{ + 0% { + background: white; + } + 100% { + background: red; + } +} + +@counter-style thumbs { + system: cyclic; + symbols: \\"\\\\1F44D\\"; + suffix: \\" \\"; +} + +@font-feature-values Font One { + @styleset { + nice-style: 12; + } +} + +/* At-rule for \\"nice-style\\" in Font Two */ +@font-feature-values Font Two { + @styleset { + nice-style: 4; + } +} + +@property ---_style_module_css-my-color{ + syntax: \\"\\"; + inherits: false; + initial-value: #_-_style_module_css-c0ffee; +} + +._-_style_module_css-class { + color: var(---_style_module_css-my-color); +} + +@layer utilities { + ._-_style_module_css-padding-sm { + padding: 0.5rem; + } + + ._-_style_module_css-padding-lg { + padding: 0.8rem; + } +} + +._-_style_module_css-class { + color: red; + + ._-_style_module_css-nested-pure { + color: red; + } + + @media screen and (min-width: 200px) { + color: blue; + + ._-_style_module_css-nested-media { + color: blue; + } + } + + @supports (display: flex) { + display: flex; + + ._-_style_module_css-nested-supports { + display: flex; + } + } + + @layer foo { + background: red; + + ._-_style_module_css-nested-layer { + background: red; + } + } + + @container foo { + background: red; + + ._-_style_module_css-nested-layer { + background: red; + } + } +} + +._-_style_module_css-not-selector-inside { + color: #fff; + opacity: 0.12; + padding: .5px; + unknown: :local(.test); + unknown1: :local .test; + unknown2: :global .test; + unknown3: :global .test; + unknown4: .foo, .bar, #bar; +} + +@unknown :local .local :global .global { + color: red; +} + +@unknown :local(.local) :global(.global) { + color: red; +} + +._-_style_module_css-nested-var { + ._-_style_module_css-again { + color: var(---_style_module_css-local-color); + } +} + +._-_style_module_css-nested-with-local-pseudo { + color: red; + + ._-_style_module_css-local-nested { + color: red; + } + + .global-nested { + color: red; + } + + ._-_style_module_css-local-nested { + color: red; + } + + .global-nested { + color: red; + } + + ._-_style_module_css-local-nested, .global-nested-next { + color: red; + } + + ._-_style_module_css-local-nested, .global-nested-next { + color: red; + } + + .foo, ._-_style_module_css-bar { + color: red; + } +} + +#_-_style_module_css-id-foo { + color: red; + + #_-_style_module_css-id-bar { + color: red; + } +} + +._-_style_module_css-nested-parens { + ._-_style_module_css-local9 div:has(._-_style_module_css-vertical-tiny, ._-_style_module_css-vertical-small) { + max-height: 0; + margin: 0; + overflow: hidden; + } +} + +.global-foo { + .nested-global { + color: red; + } + + ._-_style_module_css-local-in-global { + color: blue; + } +} + +@unknown .class { + color: red; + + .class { + color: red; + } +} + +.class ._-_style_module_css-in-local-global-scope, +.class ._-_style_module_css-in-local-global-scope, +._-_style_module_css-class-local-scope .in-local-global-scope { + color: red; +} + +@container (width > 400px) { + ._-_style_module_css-class-in-container { + font-size: 1.5em; + } +} + +@container summary (min-width: 400px) { + @container (width > 400px) { + ._-_style_module_css-deep-class-in-container { + font-size: 1.5em; + } + } +} + +:scope { + color: red; +} + +._-_style_module_css-placeholder-gray-700:-ms-input-placeholder { + ---_style_module_css-placeholder-opacity: 1; + color: #4a5568; + color: rgba(74, 85, 104, var(---_style_module_css-placeholder-opacity)); +} +._-_style_module_css-placeholder-gray-700::-ms-input-placeholder { + ---_style_module_css-placeholder-opacity: 1; + color: #4a5568; + color: rgba(74, 85, 104, var(---_style_module_css-placeholder-opacity)); +} +._-_style_module_css-placeholder-gray-700::placeholder { + ---_style_module_css-placeholder-opacity: 1; + color: #4a5568; + color: rgba(74, 85, 104, var(---_style_module_css-placeholder-opacity)); +} + +:root { + ---_style_module_css-test: dark; +} + +@media screen and (prefers-color-scheme: var(---_style_module_css-test)) { + ._-_style_module_css-baz { + color: white; + } +} + +@keyframes _-_style_module_css-slidein{ + from { + margin-left: 100%; + width: 300%; + } + + to { + margin-left: 0%; + width: 100%; + } +} + +._-_style_module_css-class { + animation: + foo var(---_style_module_css-animation-name) 3s, + var(---_style_module_css-animation-name) 3s, + 3s linear 1s infinite running _-_style_module_css-slidein, + 3s linear env(foo, var(---_style_module_css-baz)) infinite running _-_style_module_css-slidein; +} + +:root { + ---_style_module_css-baz: 10px; +} + +._-_style_module_css-class { + bar: env(foo, var(---_style_module_css-baz)); +} + +.global-foo, ._-_style_module_css-bar { + ._-_style_module_css-local-in-global { + color: blue; + } + + @media screen { + .my-global-class-again, + ._-_style_module_css-my-global-class-again { + color: red; + } + } +} + +._-_style_module_css-first-nested { + ._-_style_module_css-first-nested-nested { + color: red; + } +} + +._-_style_module_css-first-nested-at-rule { + @media screen { + ._-_style_module_css-first-nested-nested-at-rule-deep { + color: red; + } + } +} + +.again-global { + color:red; +} + +.again-again-global { + .again-again-global { + color: red; + } +} + +:root { + ---_style_module_css-foo: red; +} + +.again-again-global { + color: var(--foo); + + .again-again-global { + color: var(--foo); + } +} + +.again-again-global { + animation: slidein 3s; + + .again-again-global, ._-_style_module_css-class, ._-_style_module_css-nested1.nested2._-_style_module_css-nested3 { + animation: _-_style_module_css-slidein 3s; + } + + ._-_style_module_css-local2 .global, + ._-_style_module_css-local3 { + color: red; + } +} + +@unknown var(--foo) { + color: red; +} + +._-_style_module_css-class { + ._-_style_module_css-class { + ._-_style_module_css-class { + ._-_style_module_css-class {} + } + } +} + +._-_style_module_css-class { + ._-_style_module_css-class { + ._-_style_module_css-class { + ._-_style_module_css-class { + animation: _-_style_module_css-slidein 3s; + } + } + } +} + +._-_style_module_css-class { + animation: _-_style_module_css-slidein 3s; + ._-_style_module_css-class { + animation: _-_style_module_css-slidein 3s; + ._-_style_module_css-class { + animation: _-_style_module_css-slidein 3s; + ._-_style_module_css-class { + animation: _-_style_module_css-slidein 3s; + } + } + } +} + +/*!*********************************!*\\\\ + !*** css ./style.module.my-css ***! + \\\\*********************************/ +._-_style_module_my-css-myCssClass { + color: red; +} + +/*!**************************************!*\\\\ + !*** css ./style.module.css.invalid ***! + \\\\**************************************/ +.class { + color: teal; +} + +/*!************************************!*\\\\ + !*** css ./identifiers.module.css ***! + \\\\************************************/ +._-_identifiers_module_css-UnusedClassName{ + color: red; + padding: var(---_identifiers_module_css-variable-unused-class); + ---_identifiers_module_css-variable-unused-class: 10px; +} + +._-_identifiers_module_css-UsedClassName { + color: green; + padding: var(---_identifiers_module_css-variable-used-class); + ---_identifiers_module_css-variable-used-class: 10px; +} + +head{--webpack-use-style_js:class:_-_style_module_css-class/local1:_-_style_module_css-local1/local2:_-_style_module_css-local2/local3:_-_style_module_css-local3/local4:_-_style_module_css-local4/local5:_-_style_module_css-local5/local6:_-_style_module_css-local6/local7:_-_style_module_css-local7/disabled:_-_style_module_css-disabled/mButtonDisabled:_-_style_module_css-mButtonDisabled/tipOnly:_-_style_module_css-tipOnly/local8:_-_style_module_css-local8/parent1:_-_style_module_css-parent1/child1:_-_style_module_css-child1/vertical-tiny:_-_style_module_css-vertical-tiny/vertical-small:_-_style_module_css-vertical-small/otherDiv:_-_style_module_css-otherDiv/horizontal-tiny:_-_style_module_css-horizontal-tiny/horizontal-small:_-_style_module_css-horizontal-small/description:_-_style_module_css-description/local9:_-_style_module_css-local9/local10:_-_style_module_css-local10/local11:_-_style_module_css-local11/local12:_-_style_module_css-local12/local13:_-_style_module_css-local13/local14:_-_style_module_css-local14/local15:_-_style_module_css-local15/local16:_-_style_module_css-local16/nested1:_-_style_module_css-nested1/nested3:_-_style_module_css-nested3/ident:_-_style_module_css-ident/localkeyframes:_-_style_module_css-localkeyframes/pos1x:---_style_module_css-pos1x/pos1y:---_style_module_css-pos1y/pos2x:---_style_module_css-pos2x/pos2y:---_style_module_css-pos2y/localkeyframes2:_-_style_module_css-localkeyframes2/animation:_-_style_module_css-animation/vars:_-_style_module_css-vars/local-color:---_style_module_css-local-color/globalVars:_-_style_module_css-globalVars/wideScreenClass:_-_style_module_css-wideScreenClass/narrowScreenClass:_-_style_module_css-narrowScreenClass/displayGridInSupports:_-_style_module_css-displayGridInSupports/floatRightInNegativeSupports:_-_style_module_css-floatRightInNegativeSupports/displayFlexInMediaInSupports:_-_style_module_css-displayFlexInMediaInSupports/displayFlexInSupportsInMedia:_-_style_module_css-displayFlexInSupportsInMedia/displayFlexInSupportsInMediaUpperCase:_-_style_module_css-displayFlexInSupportsInMediaUpperCase/animationUpperCase:_-_style_module_css-animationUpperCase/localkeyframesUPPERCASE:_-_style_module_css-localkeyframesUPPERCASE/localkeyframes2UPPPERCASE:_-_style_module_css-localkeyframes2UPPPERCASE/localUpperCase:_-_style_module_css-localUpperCase/VARS:_-_style_module_css-VARS/LOCAL-COLOR:---_style_module_css-LOCAL-COLOR/globalVarsUpperCase:_-_style_module_css-globalVarsUpperCase/inSupportScope:_-_style_module_css-inSupportScope/a:_-_style_module_css-a/animationName:_-_style_module_css-animationName/b:_-_style_module_css-b/c:_-_style_module_css-c/d:_-_style_module_css-d/animation-name:---_style_module_css-animation-name/mozAnimationName:_-_style_module_css-mozAnimationName/my-color:---_style_module_css-my-color/c0ffee:_-_style_module_css-c0ffee/padding-sm:_-_style_module_css-padding-sm/padding-lg:_-_style_module_css-padding-lg/nested-pure:_-_style_module_css-nested-pure/nested-media:_-_style_module_css-nested-media/nested-supports:_-_style_module_css-nested-supports/nested-layer:_-_style_module_css-nested-layer/not-selector-inside:_-_style_module_css-not-selector-inside/nested-var:_-_style_module_css-nested-var/again:_-_style_module_css-again/nested-with-local-pseudo:_-_style_module_css-nested-with-local-pseudo/local-nested:_-_style_module_css-local-nested/bar:_-_style_module_css-bar/id-foo:_-_style_module_css-id-foo/id-bar:_-_style_module_css-id-bar/nested-parens:_-_style_module_css-nested-parens/local-in-global:_-_style_module_css-local-in-global/in-local-global-scope:_-_style_module_css-in-local-global-scope/class-local-scope:_-_style_module_css-class-local-scope/class-in-container:_-_style_module_css-class-in-container/deep-class-in-container:_-_style_module_css-deep-class-in-container/placeholder-gray-700:_-_style_module_css-placeholder-gray-700/placeholder-opacity:---_style_module_css-placeholder-opacity/test:---_style_module_css-test/baz:---_style_module_css-baz/slidein:_-_style_module_css-slidein/my-global-class-again:_-_style_module_css-my-global-class-again/first-nested:_-_style_module_css-first-nested/first-nested-nested:_-_style_module_css-first-nested-nested/first-nested-at-rule:_-_style_module_css-first-nested-at-rule/first-nested-nested-at-rule-deep:_-_style_module_css-first-nested-nested-at-rule-deep/foo:---_style_module_css-foo/&\\\\.\\\\/style\\\\.module\\\\.css,myCssClass:_-_style_module_my-css-myCssClass/&\\\\.\\\\/style\\\\.module\\\\.my-css,&\\\\.\\\\/style\\\\.module\\\\.css\\\\.invalid,UnusedClassName:_-_identifiers_module_css-UnusedClassName/variable-unused-class:---_identifiers_module_css-variable-unused-class/UsedClassName:_-_identifiers_module_css-UsedClassName/variable-used-class:---_identifiers_module_css-variable-used-class/&\\\\.\\\\/identifiers\\\\.module\\\\.css;}" +`; + +exports[`ConfigTestCases css css-modules exported tests should allow to create css modules 2`] = ` +"/*!******************************!*\\\\ + !*** css ./style.module.css ***! + \\\\******************************/ +.my-app-235-zg { + color: red; +} + +.my-app-235-Hi, +.my-app-235-OB .global, +.my-app-235-VE { + color: green; +} + +.global .my-app-235-O2 { + color: yellow; +} + +.my-app-235-Vj.global.my-app-235-OH { + color: blue; +} + +.my-app-235-H5 div:not(.disabled, .mButtonDisabled, .tipOnly) { + pointer-events: initial !important; +} + +.my-app-235-aq :is(div.parent1.child1.vertical-tiny, + div.parent1.child1.vertical-small, + div.otherDiv.horizontal-tiny, + div.otherDiv.horizontal-small div.description) { + max-height: 0; + margin: 0; + overflow: hidden; +} + +.my-app-235-VN :matches(div.parent1.child1.vertical-tiny, + div.parent1.child1.vertical-small, + div.otherDiv.horizontal-tiny, + div.otherDiv.horizontal-small div.description) { + max-height: 0; + margin: 0; + overflow: hidden; +} + +.my-app-235-VM :where(div.parent1.child1.vertical-tiny, + div.parent1.child1.vertical-small, + div.otherDiv.horizontal-tiny, + div.otherDiv.horizontal-small div.description) { + max-height: 0; + margin: 0; + overflow: hidden; +} + +.my-app-235-AO div:has(.disabled, .mButtonDisabled, .tipOnly) { + pointer-events: initial !important; +} + +.my-app-235-Hq div:current(p, span) { + background-color: yellow; +} + +.my-app-235-O4 div:past(p, span) { + display: none; +} + +.my-app-235-Hb div:future(p, span) { + background-color: yellow; +} + +.my-app-235-OP div:-moz-any(ol, ul, menu, dir) { + list-style-type: square; +} + +.my-app-235-Hw li:-webkit-any(:first-child, :last-child) { + background-color: aquamarine; +} + +.my-app-235-VN :matches(div.parent1.child1.vertical-tiny, + div.parent1.child1.vertical-small, + div.otherDiv.horizontal-tiny, + div.otherDiv.horizontal-small div.description) { + max-height: 0; + margin: 0; + overflow: hidden; +} + +.my-app-235-nb.nested2.my-app-235-\\\\$Q { + color: pink; +} + +#my-app-235-bD { + color: purple; +} + +@keyframes my-app-235-\\\\$t{ + 0% { + left: var(--my-app-235-qi); + top: var(--my-app-235-xB); + color: var(--theme-color1); + } + 100% { + left: var(--my-app-235-\\\\$6); + top: var(--my-app-235-gJ); + color: var(--theme-color2); + } +} + +@keyframes my-app-235-x{ + 0% { + left: 0; + } + 100% { + left: 100px; + } +} + +.my-app-235-lY { + animation-name: my-app-235-\\\\$t; + animation: 3s ease-in 1s 2 reverse both paused my-app-235-\\\\$t, my-app-235-x; + --my-app-235-qi: 0px; + --my-app-235-xB: 0px; + --my-app-235-\\\\$6: 10px; + --my-app-235-gJ: 20px; +} + +/* .composed { + composes: local1; + composes: local2; +} */ + +.my-app-235-f { + color: var(--my-app-235-uz); + --my-app-235-uz: red; +} + +.my-app-235-aK { + color: var(--global-color); + --global-color: red; +} + +@media (min-width: 1600px) { + .my-app-235-a7 { + color: var(--my-app-235-uz); + --my-app-235-uz: green; + } +} + +@media screen and (max-width: 600px) { + .my-app-235-uf { + color: var(--my-app-235-uz); + --my-app-235-uz: purple; + } +} + +@supports (display: grid) { + .my-app-235-sW { + display: grid; + } +} + +@supports not (display: grid) { + .my-app-235-TZ { + float: right; + } +} + +@supports (display: flex) { + @media screen and (min-width: 900px) { + .my-app-235-aY { + display: flex; + } + } +} + +@media screen and (min-width: 900px) { + @supports (display: flex) { + .my-app-235-II { + display: flex; + } + } +} + +@MEDIA screen and (min-width: 900px) { + @SUPPORTS (display: flex) { + .my-app-235-ij { + display: flex; + } + } +} + +.animationUpperCase { + ANIMATION-NAME: my-app-235-zG; + ANIMATION: 3s ease-in 1s 2 reverse both paused my-app-235-zG, my-app-235-Dk; + --my-app-235-qi: 0px; + --my-app-235-xB: 0px; + --my-app-235-\\\\$6: 10px; + --my-app-235-gJ: 20px; +} + +@KEYFRAMES my-app-235-zG{ + 0% { + left: VAR(--my-app-235-qi); + top: VAR(--my-app-235-xB); + color: VAR(--theme-color1); + } + 100% { + left: VAR(--my-app-235-\\\\$6); + top: VAR(--my-app-235-gJ); + color: VAR(--theme-color2); + } +} + +@KEYframes my-app-235-Dk{ + 0% { + left: 0; + } + 100% { + left: 100px; + } +} + +.globalUpperCase .localUpperCase { + color: yellow; +} + +.my-app-235-XE { + color: VAR(--my-app-235-I0); + --my-app-235-I0: red; +} + +.my-app-235-wt { + COLOR: VAR(--GLOBAR-COLOR); + --GLOBAR-COLOR: red; +} + +@supports (top: env(safe-area-inset-top, 0)) { + .my-app-235-nc { + color: red; + } +} + +.a { + animation: 3s my-app-235-iZ; + -webkit-animation: 3s my-app-235-iZ; +} + +.b { + animation: my-app-235-iZ 3s; + -webkit-animation: my-app-235-iZ 3s; +} + +.c { + animation-name: my-app-235-iZ; + -webkit-animation-name: my-app-235-iZ; +} + +.d { + --my-app-235-ZP: animationName; +} + +@keyframes my-app-235-iZ{ + 0% { + background: white; + } + 100% { + background: red; + } +} + +@-webkit-keyframes my-app-235-iZ{ + 0% { + background: white; + } + 100% { + background: red; + } +} + +@-moz-keyframes my-app-235-M6{ + 0% { + background: white; + } + 100% { + background: red; + } +} + +@counter-style thumbs { + system: cyclic; + symbols: \\"\\\\1F44D\\"; + suffix: \\" \\"; +} + +@font-feature-values Font One { + @styleset { + nice-style: 12; + } +} + +/* At-rule for \\"nice-style\\" in Font Two */ +@font-feature-values Font Two { + @styleset { + nice-style: 4; + } +} + +@property --my-app-235-rX{ + syntax: \\"\\"; + inherits: false; + initial-value: #c0ffee; +} + +.my-app-235-zg { + color: var(--my-app-235-rX); +} + +@layer utilities { + .my-app-235-dW { + padding: 0.5rem; + } + + .my-app-235-cD { + padding: 0.8rem; + } +} + +.my-app-235-zg { + color: red; + + .nested-pure { + color: red; + } + + @media screen and (min-width: 200px) { + color: blue; + + .nested-media { + color: blue; + } + } + + @supports (display: flex) { + display: flex; + + .nested-supports { + display: flex; + } + } + + @layer foo { + background: red; + + .nested-layer { + background: red; + } + } + + @container foo { + background: red; + + .nested-layer { + background: red; + } + } +} + +.not-selector-inside { + color: #fff; + opacity: 0.12; + padding: .5px; + unknown: :local(.test); + unknown1: :local .test; + unknown2: :global .test; + unknown3: :global .test; + unknown4: .foo, .bar, #bar; +} + +@unknown :local .local :global .global { + color: red; +} + +@unknown :local(.local) :global(.global) { + color: red; +} + +.nested-var { + .again { + color: var(--my-app-235-uz); + } +} + +.nested-with-local-pseudo { + color: red; + + .local-nested { + color: red; + } + + .global-nested { + color: red; + } + + .local-nested { + color: red; + } + + .global-nested { + color: red; + } + + .local-nested, .global-nested-next { + color: red; + } + + .local-nested, .global-nested-next { + color: red; + } + + .foo, .bar { + color: red; + } +} + +#id-foo { + color: red; + + #id-bar { + color: red; + } +} + +.nested-parens { + .my-app-235-VN div:has(.vertical-tiny, .vertical-small) { + max-height: 0; + margin: 0; + overflow: hidden; + } +} + +.global-foo { + .nested-global { + color: red; + } + + .local-in-global { + color: blue; + } +} + +@unknown .class { + color: red; + + .class { + color: red; + } +} + +.class .my-app-235-V0, +.class .my-app-235-V0, +.my-app-235-Ci .in-local-global-scope { + color: red; +} + +@container (width > 400px) { + .my-app-235-bK { + font-size: 1.5em; + } +} + +@container summary (min-width: 400px) { + @container (width > 400px) { + .my-app-235-Y1 { + font-size: 1.5em; + } + } +} + +:scope { + color: red; +} + +.placeholder-gray-700:-ms-input-placeholder { + --my-app-235-Y: 1; + color: #4a5568; + color: rgba(74, 85, 104, var(--my-app-235-Y)); +} +.placeholder-gray-700::-ms-input-placeholder { + --my-app-235-Y: 1; + color: #4a5568; + color: rgba(74, 85, 104, var(--my-app-235-Y)); +} +.placeholder-gray-700::placeholder { + --my-app-235-Y: 1; + color: #4a5568; + color: rgba(74, 85, 104, var(--my-app-235-Y)); +} + +:root { + --my-app-235-t6: dark; +} + +@media screen and (prefers-color-scheme: var(--my-app-235-t6)) { + .my-app-235-KR { + color: white; + } +} + +@keyframes my-app-235-Fk{ + from { + margin-left: 100%; + width: 300%; + } + + to { + margin-left: 0%; + width: 100%; + } +} + +.my-app-235-zg { + animation: + foo var(--my-app-235-ZP) 3s, + var(--my-app-235-ZP) 3s, + 3s linear 1s infinite running my-app-235-Fk, + 3s linear env(foo, var(--my-app-235-KR)) infinite running my-app-235-Fk; +} + +:root { + --my-app-235-KR: 10px; +} + +.my-app-235-zg { + bar: env(foo, var(--my-app-235-KR)); +} + +.global-foo, .bar { + .local-in-global { + color: blue; + } + + @media screen { + .my-global-class-again, + .my-global-class-again { + color: red; + } + } +} + +.first-nested { + .first-nested-nested { + color: red; + } +} + +.first-nested-at-rule { + @media screen { + .first-nested-nested-at-rule-deep { + color: red; + } + } +} + +.again-global { + color:red; +} + +.again-again-global { + .again-again-global { + color: red; + } +} + +:root { + --foo: red; +} + +.again-again-global { + color: var(--foo); + + .again-again-global { + color: var(--foo); + } +} + +.again-again-global { + animation: slidein 3s; + + .again-again-global, .my-app-235-zg, .my-app-235-nb.nested2.my-app-235-\\\\$Q { + animation: my-app-235-Fk 3s; + } + + .my-app-235-OB .global, + .my-app-235-VE { + color: red; + } +} + +@unknown var(--foo) { + color: red; +} + +.my-app-235-zg { + .my-app-235-zg { + .my-app-235-zg { + .my-app-235-zg {} + } + } +} + +.my-app-235-zg { + .my-app-235-zg { + .my-app-235-zg { + .my-app-235-zg { + animation: my-app-235-Fk 3s; + } + } + } +} + +.my-app-235-zg { + animation: my-app-235-Fk 3s; + .my-app-235-zg { + animation: my-app-235-Fk 3s; + .my-app-235-zg { + animation: my-app-235-Fk 3s; + .my-app-235-zg { + animation: my-app-235-Fk 3s; + } + } + } +} + +/*!*********************************!*\\\\ + !*** css ./style.module.my-css ***! + \\\\*********************************/ +.my-app-666-k { + color: red; +} + +/*!**************************************!*\\\\ + !*** css ./style.module.css.invalid ***! + \\\\**************************************/ +.class { + color: teal; +} + +/*!************************************!*\\\\ + !*** css ./identifiers.module.css ***! + \\\\************************************/ +.UnusedClassName{ + color: red; + padding: var(--my-app-194-RJ); + --my-app-194-RJ: 10px; +} + +.my-app-194-ZL { + color: green; + padding: var(--my-app-194-c5); + --my-app-194-c5: 10px; +} + +head{--webpack-my-app-226:zg:my-app-235-ฤ€/Hiฤ‚ฤ„ฤ†ฤˆฤŠฤŒฤ/OBฤ’ฤ…ฤ‡ฤ‰ฤ‹-ฤš/VEฤœฤ”ฤŸฤŒฤคฤ™2ฤฆฤžฤ–ฤก2ฤฃjฤญฤ•ฤ Vjฤ™HฤดฤจฤกHฤ5ฤปฤฏH5/aqลฤ ล†ฤฃNลˆฤฉNฤฃMล-VM/AOล’ล—ฤล‡ฤƒฤฤตฤ—qฤ™4ล’O4ฤbล’Hbฤ™PลคPฤwลฉw/nลจลฤงฤฏลต/\\\\$Qล’ลผQ/bDล’ฦƒลป$tลฟฦˆ/qฤ‘--ลทฤฎฤ ฦ/xฤ›ฦฦ‘ลŸ-ฦ–ฦ‡6:ฦ˜ฤ“ฦ’ฤŒลผ6/gJฦŸฦฦกฦšฦงฦ•ล’x/lYล’ฦฒ/fล’f/uzฦฉฦ™ฤผฦปล…Kล’aKล…7วƒ7ฦบฦทฦพฤฏuฦนsWล’ว/TZล’ว•ล…ฦณวŒล‰Y/IIล’วŸ/iฤณว›ฤŒวค/zGล’วช/Dkล’วฏ/Xฤฅวฆ-วดวž0ฦฝฦซฤผI0/wฦ‰วถศลดcล’ncวฃว–วถiZ/Zลญฦ ลžฤผศ/Mฦžวถศ—/rXวปศ“ฤฏศœ/dว‘วถศฃ/cฦ„วถศจฤฃวบวถVวฟCฤ‘วถศฑฦ‚ว‚วถbว…Y1ล’ศบ/ฦณศ’ลธฤ วtฦžษ€ฦข-ษ„/KRศžษฤŒษ‹/Fวฐวถษ’/&_ฤ–,ษ“วผ6ษ-kษ–_ษ6,ษ—81ษคRฦจษ†ฤˆ194-ษชศLฤปษฎษฐZLศงล€ษฌ-ษถ-cล„ษ—ษถ;}" +`; + +exports[`ConfigTestCases css css-modules exported tests should allow to create css modules: dev 1`] = ` +Object { + "UsedClassName": "-_identifiers_module_css-UsedClassName", + "VARS": "---_style_module_css-LOCAL-COLOR -_style_module_css-VARS undefined -_style_module_css-globalVarsUpperCase", + "animation": "-_style_module_css-animation", + "animationName": "-_style_module_css-animationName", + "class": "-_style_module_css-class", + "classInContainer": "-_style_module_css-class-in-container", + "classLocalScope": "-_style_module_css-class-local-scope", + "cssModuleWithCustomFileExtension": "-_style_module_my-css-myCssClass", + "currentWmultiParams": "-_style_module_css-local12", + "deepClassInContainer": "-_style_module_css-deep-class-in-container", + "displayFlexInSupportsInMediaUpperCase": "-_style_module_css-displayFlexInSupportsInMediaUpperCase", + "exportLocalVarsShouldCleanup": "false false", + "futureWmultiParams": "-_style_module_css-local14", + "global": undefined, + "hasWmultiParams": "-_style_module_css-local11", + "ident": "-_style_module_css-ident", + "inLocalGlobalScope": "-_style_module_css-in-local-global-scope", + "inSupportScope": "-_style_module_css-inSupportScope", + "isWmultiParams": "-_style_module_css-local8", + "keyframes": "-_style_module_css-localkeyframes", + "keyframesUPPERCASE": "-_style_module_css-localkeyframesUPPERCASE", + "local": "-_style_module_css-local1 -_style_module_css-local2 -_style_module_css-local3 -_style_module_css-local4", + "local2": "-_style_module_css-local5 -_style_module_css-local6", + "localkeyframes2UPPPERCASE": "-_style_module_css-localkeyframes2UPPPERCASE", + "matchesWmultiParams": "-_style_module_css-local9", + "media": "-_style_module_css-wideScreenClass", + "mediaInSupports": "-_style_module_css-displayFlexInMediaInSupports", + "mediaWithOperator": "-_style_module_css-narrowScreenClass", + "mozAnimationName": "-_style_module_css-mozAnimationName", + "mozAnyWmultiParams": "-_style_module_css-local15", + "myColor": "---_style_module_css-my-color", + "nested": "-_style_module_css-nested1 undefined -_style_module_css-nested3", + "notAValidCssModuleExtension": true, + "notWmultiParams": "-_style_module_css-local7", + "paddingLg": "-_style_module_css-padding-lg", + "paddingSm": "-_style_module_css-padding-sm", + "pastWmultiParams": "-_style_module_css-local13", + "supports": "-_style_module_css-displayGridInSupports", + "supportsInMedia": "-_style_module_css-displayFlexInSupportsInMedia", + "supportsWithOperator": "-_style_module_css-floatRightInNegativeSupports", + "vars": "---_style_module_css-local-color -_style_module_css-vars undefined -_style_module_css-globalVars", + "webkitAnyWmultiParams": "-_style_module_css-local16", + "whereWmultiParams": "-_style_module_css-local10", +} +`; + +exports[`ConfigTestCases css css-modules exported tests should allow to create css modules: prod 1`] = ` +Object { + "UsedClassName": "my-app-194-ZL", + "VARS": "--my-app-235-I0 my-app-235-XE undefined my-app-235-wt", + "animation": "my-app-235-lY", + "animationName": "my-app-235-iZ", + "class": "my-app-235-zg", + "classInContainer": "my-app-235-bK", + "classLocalScope": "my-app-235-Ci", + "cssModuleWithCustomFileExtension": "my-app-666-k", + "currentWmultiParams": "my-app-235-Hq", + "deepClassInContainer": "my-app-235-Y1", + "displayFlexInSupportsInMediaUpperCase": "my-app-235-ij", + "exportLocalVarsShouldCleanup": "false false", + "futureWmultiParams": "my-app-235-Hb", + "global": undefined, + "hasWmultiParams": "my-app-235-AO", + "ident": "my-app-235-bD", + "inLocalGlobalScope": "my-app-235-V0", + "inSupportScope": "my-app-235-nc", + "isWmultiParams": "my-app-235-aq", + "keyframes": "my-app-235-$t", + "keyframesUPPERCASE": "my-app-235-zG", + "local": "my-app-235-Hi my-app-235-OB my-app-235-VE my-app-235-O2", + "local2": "my-app-235-Vj my-app-235-OH", + "localkeyframes2UPPPERCASE": "my-app-235-Dk", + "matchesWmultiParams": "my-app-235-VN", + "media": "my-app-235-a7", + "mediaInSupports": "my-app-235-aY", + "mediaWithOperator": "my-app-235-uf", + "mozAnimationName": "my-app-235-M6", + "mozAnyWmultiParams": "my-app-235-OP", + "myColor": "--my-app-235-rX", + "nested": "my-app-235-nb undefined my-app-235-$Q", + "notAValidCssModuleExtension": true, + "notWmultiParams": "my-app-235-H5", + "paddingLg": "my-app-235-cD", + "paddingSm": "my-app-235-dW", + "pastWmultiParams": "my-app-235-O4", + "supports": "my-app-235-sW", + "supportsInMedia": "my-app-235-II", + "supportsWithOperator": "my-app-235-TZ", + "vars": "--my-app-235-uz my-app-235-f undefined my-app-235-aK", + "webkitAnyWmultiParams": "my-app-235-Hw", + "whereWmultiParams": "my-app-235-VM", +} +`; + +exports[`ConfigTestCases css css-modules-broken-keyframes exported tests should allow to create css modules: prod 1`] = ` +Object { + "class": "my-app-235-z", +} +`; + +exports[`ConfigTestCases css css-modules-in-node exported tests should allow to create css modules: dev 1`] = ` +Object { + "UsedClassName": "-_identifiers_module_css-UsedClassName", + "VARS": "---_style_module_css-LOCAL-COLOR -_style_module_css-VARS undefined -_style_module_css-globalVarsUpperCase", + "animation": "-_style_module_css-animation", + "animationName": "-_style_module_css-animationName", + "class": "-_style_module_css-class", + "classInContainer": "-_style_module_css-class-in-container", + "classLocalScope": "-_style_module_css-class-local-scope", + "cssModuleWithCustomFileExtension": "-_style_module_my-css-myCssClass", + "currentWmultiParams": "-_style_module_css-local12", + "deepClassInContainer": "-_style_module_css-deep-class-in-container", + "displayFlexInSupportsInMediaUpperCase": "-_style_module_css-displayFlexInSupportsInMediaUpperCase", + "exportLocalVarsShouldCleanup": "false false", + "futureWmultiParams": "-_style_module_css-local14", + "global": undefined, + "hasWmultiParams": "-_style_module_css-local11", + "ident": "-_style_module_css-ident", + "inLocalGlobalScope": "-_style_module_css-in-local-global-scope", + "inSupportScope": "-_style_module_css-inSupportScope", + "isWmultiParams": "-_style_module_css-local8", + "keyframes": "-_style_module_css-localkeyframes", + "keyframesUPPERCASE": "-_style_module_css-localkeyframesUPPERCASE", + "local": "-_style_module_css-local1 -_style_module_css-local2 -_style_module_css-local3 -_style_module_css-local4", + "local2": "-_style_module_css-local5 -_style_module_css-local6", + "localkeyframes2UPPPERCASE": "-_style_module_css-localkeyframes2UPPPERCASE", + "matchesWmultiParams": "-_style_module_css-local9", + "media": "-_style_module_css-wideScreenClass", + "mediaInSupports": "-_style_module_css-displayFlexInMediaInSupports", + "mediaWithOperator": "-_style_module_css-narrowScreenClass", + "mozAnimationName": "-_style_module_css-mozAnimationName", + "mozAnyWmultiParams": "-_style_module_css-local15", + "myColor": "---_style_module_css-my-color", + "nested": "-_style_module_css-nested1 undefined -_style_module_css-nested3", + "notAValidCssModuleExtension": true, + "notWmultiParams": "-_style_module_css-local7", + "paddingLg": "-_style_module_css-padding-lg", + "paddingSm": "-_style_module_css-padding-sm", + "pastWmultiParams": "-_style_module_css-local13", + "supports": "-_style_module_css-displayGridInSupports", + "supportsInMedia": "-_style_module_css-displayFlexInSupportsInMedia", + "supportsWithOperator": "-_style_module_css-floatRightInNegativeSupports", + "vars": "---_style_module_css-local-color -_style_module_css-vars undefined -_style_module_css-globalVars", + "webkitAnyWmultiParams": "-_style_module_css-local16", + "whereWmultiParams": "-_style_module_css-local10", +} +`; + +exports[`ConfigTestCases css css-modules-in-node exported tests should allow to create css modules: prod 1`] = ` +Object { + "UsedClassName": "my-app-194-ZL", + "VARS": "--my-app-235-I0 my-app-235-XE undefined my-app-235-wt", + "animation": "my-app-235-lY", + "animationName": "my-app-235-iZ", + "class": "my-app-235-zg", + "classInContainer": "my-app-235-bK", + "classLocalScope": "my-app-235-Ci", + "cssModuleWithCustomFileExtension": "my-app-666-k", + "currentWmultiParams": "my-app-235-Hq", + "deepClassInContainer": "my-app-235-Y1", + "displayFlexInSupportsInMediaUpperCase": "my-app-235-ij", + "exportLocalVarsShouldCleanup": "false false", + "futureWmultiParams": "my-app-235-Hb", + "global": undefined, + "hasWmultiParams": "my-app-235-AO", + "ident": "my-app-235-bD", + "inLocalGlobalScope": "my-app-235-V0", + "inSupportScope": "my-app-235-nc", + "isWmultiParams": "my-app-235-aq", + "keyframes": "my-app-235-$t", + "keyframesUPPERCASE": "my-app-235-zG", + "local": "my-app-235-Hi my-app-235-OB my-app-235-VE my-app-235-O2", + "local2": "my-app-235-Vj my-app-235-OH", + "localkeyframes2UPPPERCASE": "my-app-235-Dk", + "matchesWmultiParams": "my-app-235-VN", + "media": "my-app-235-a7", + "mediaInSupports": "my-app-235-aY", + "mediaWithOperator": "my-app-235-uf", + "mozAnimationName": "my-app-235-M6", + "mozAnyWmultiParams": "my-app-235-OP", + "myColor": "--my-app-235-rX", + "nested": "my-app-235-nb undefined my-app-235-$Q", + "notAValidCssModuleExtension": true, + "notWmultiParams": "my-app-235-H5", + "paddingLg": "my-app-235-cD", + "paddingSm": "my-app-235-dW", + "pastWmultiParams": "my-app-235-O4", + "supports": "my-app-235-sW", + "supportsInMedia": "my-app-235-II", + "supportsWithOperator": "my-app-235-TZ", + "vars": "--my-app-235-uz my-app-235-f undefined my-app-235-aK", + "webkitAnyWmultiParams": "my-app-235-Hw", + "whereWmultiParams": "my-app-235-VM", +} +`; + +exports[`ConfigTestCases css css-modules-in-node exported tests should allow to create css modules: prod 2`] = ` +Object { + "UsedClassName": "my-app-194-ZL", + "VARS": "--my-app-235-I0 my-app-235-XE undefined my-app-235-wt", + "animation": "my-app-235-lY", + "animationName": "my-app-235-iZ", + "class": "my-app-235-zg", + "classInContainer": "my-app-235-bK", + "classLocalScope": "my-app-235-Ci", + "cssModuleWithCustomFileExtension": "my-app-666-k", + "currentWmultiParams": "my-app-235-Hq", + "deepClassInContainer": "my-app-235-Y1", + "displayFlexInSupportsInMediaUpperCase": "my-app-235-ij", + "exportLocalVarsShouldCleanup": "false false", + "futureWmultiParams": "my-app-235-Hb", + "global": undefined, + "hasWmultiParams": "my-app-235-AO", + "ident": "my-app-235-bD", + "inLocalGlobalScope": "my-app-235-V0", + "inSupportScope": "my-app-235-nc", + "isWmultiParams": "my-app-235-aq", + "keyframes": "my-app-235-$t", + "keyframesUPPERCASE": "my-app-235-zG", + "local": "my-app-235-Hi my-app-235-OB my-app-235-VE my-app-235-O2", + "local2": "my-app-235-Vj my-app-235-OH", + "localkeyframes2UPPPERCASE": "my-app-235-Dk", + "matchesWmultiParams": "my-app-235-VN", + "media": "my-app-235-a7", + "mediaInSupports": "my-app-235-aY", + "mediaWithOperator": "my-app-235-uf", + "mozAnimationName": "my-app-235-M6", + "mozAnyWmultiParams": "my-app-235-OP", + "myColor": "--my-app-235-rX", + "nested": "my-app-235-nb undefined my-app-235-$Q", + "notAValidCssModuleExtension": true, + "notWmultiParams": "my-app-235-H5", + "paddingLg": "my-app-235-cD", + "paddingSm": "my-app-235-dW", + "pastWmultiParams": "my-app-235-O4", + "supports": "my-app-235-sW", + "supportsInMedia": "my-app-235-II", + "supportsWithOperator": "my-app-235-TZ", + "vars": "--my-app-235-uz my-app-235-f undefined my-app-235-aK", + "webkitAnyWmultiParams": "my-app-235-Hw", + "whereWmultiParams": "my-app-235-VM", +} +`; + +exports[`ConfigTestCases css css-modules-in-node exported tests should allow to import css modules: class-dev 1`] = `"-_style_module_css-class"`; + +exports[`ConfigTestCases css css-modules-in-node exported tests should allow to import css modules: class-prod 1`] = `"my-app-235-zg"`; + +exports[`ConfigTestCases css css-modules-in-node exported tests should allow to import css modules: class-prod 2`] = `"my-app-235-zg"`; + +exports[`ConfigTestCases css css-modules-in-node exported tests should allow to import css modules: local1-dev 1`] = `"-_style_module_css-local1"`; + +exports[`ConfigTestCases css css-modules-in-node exported tests should allow to import css modules: local1-prod 1`] = `"my-app-235-Hi"`; + +exports[`ConfigTestCases css css-modules-in-node exported tests should allow to import css modules: local1-prod 2`] = `"my-app-235-Hi"`; + +exports[`ConfigTestCases css css-modules-in-node exported tests should allow to import css modules: local2-dev 1`] = `"-_style_module_css-local2"`; + +exports[`ConfigTestCases css css-modules-in-node exported tests should allow to import css modules: local2-prod 1`] = `"my-app-235-OB"`; + +exports[`ConfigTestCases css css-modules-in-node exported tests should allow to import css modules: local2-prod 2`] = `"my-app-235-OB"`; + +exports[`ConfigTestCases css css-modules-in-node exported tests should allow to import css modules: local3-dev 1`] = `"-_style_module_css-local3"`; + +exports[`ConfigTestCases css css-modules-in-node exported tests should allow to import css modules: local3-prod 1`] = `"my-app-235-VE"`; + +exports[`ConfigTestCases css css-modules-in-node exported tests should allow to import css modules: local3-prod 2`] = `"my-app-235-VE"`; + +exports[`ConfigTestCases css css-modules-in-node exported tests should allow to import css modules: local4-dev 1`] = `"-_style_module_css-local4"`; + +exports[`ConfigTestCases css css-modules-in-node exported tests should allow to import css modules: local4-prod 1`] = `"my-app-235-O2"`; + +exports[`ConfigTestCases css css-modules-in-node exported tests should allow to import css modules: local4-prod 2`] = `"my-app-235-O2"`; + +exports[`ConfigTestCases css exports-convention exported tests should have correct convention for css exports name 1`] = ` +Object { + "btn--info_is-disabled_1": "-_style_module_css_as-is-btn--info_is-disabled_1", + "btn-info_is-disabled": "-_style_module_css_as-is-btn-info_is-disabled", + "foo": "bar", + "foo_bar": "-_style_module_css_as-is-foo_bar", + "my-btn-info_is-disabled": "value", + "simple": "-_style_module_css_as-is-simple", +} +`; + +exports[`ConfigTestCases css exports-convention exported tests should have correct convention for css exports name 2`] = ` +Object { + "btn--info_is-disabled_1": "-_style_module_css_camel-case-btn--info_is-disabled_1", + "btn-info_is-disabled": "-_style_module_css_camel-case-btn-info_is-disabled", + "btnInfoIsDisabled": "-_style_module_css_camel-case-btn-info_is-disabled", + "btnInfoIsDisabled1": "-_style_module_css_camel-case-btn--info_is-disabled_1", + "foo": "bar", + "fooBar": "-_style_module_css_camel-case-foo_bar", + "foo_bar": "-_style_module_css_camel-case-foo_bar", + "my-btn-info_is-disabled": "value", + "myBtnInfoIsDisabled": "value", + "simple": "-_style_module_css_camel-case-simple", +} +`; + +exports[`ConfigTestCases css exports-convention exported tests should have correct convention for css exports name 3`] = ` +Object { + "btnInfoIsDisabled": "-_style_module_css_camel-case-only-btnInfoIsDisabled", + "btnInfoIsDisabled1": "-_style_module_css_camel-case-only-btnInfoIsDisabled1", + "foo": "bar", + "fooBar": "-_style_module_css_camel-case-only-fooBar", + "myBtnInfoIsDisabled": "value", + "simple": "-_style_module_css_camel-case-only-simple", +} +`; + +exports[`ConfigTestCases css exports-convention exported tests should have correct convention for css exports name 4`] = ` +Object { + "btn--info_is-disabled_1": "-_style_module_css_dashes-btn--info_is-disabled_1", + "btn-info_is-disabled": "-_style_module_css_dashes-btn-info_is-disabled", + "btnInfo_isDisabled": "-_style_module_css_dashes-btn-info_is-disabled", + "btnInfo_isDisabled_1": "-_style_module_css_dashes-btn--info_is-disabled_1", + "foo": "bar", + "foo_bar": "-_style_module_css_dashes-foo_bar", + "my-btn-info_is-disabled": "value", + "myBtnInfo_isDisabled": "value", + "simple": "-_style_module_css_dashes-simple", +} +`; + +exports[`ConfigTestCases css exports-convention exported tests should have correct convention for css exports name 5`] = ` +Object { + "btnInfo_isDisabled": "-_style_module_css_dashes-only-btnInfo_isDisabled", + "btnInfo_isDisabled_1": "-_style_module_css_dashes-only-btnInfo_isDisabled_1", + "foo": "bar", + "foo_bar": "-_style_module_css_dashes-only-foo_bar", + "myBtnInfo_isDisabled": "value", + "simple": "-_style_module_css_dashes-only-simple", +} +`; + +exports[`ConfigTestCases css exports-convention exported tests should have correct convention for css exports name 6`] = ` +Object { + "BTN--INFO_IS-DISABLED_1": "-_style_module_css_upper-BTN--INFO_IS-DISABLED_1", + "BTN-INFO_IS-DISABLED": "-_style_module_css_upper-BTN-INFO_IS-DISABLED", + "FOO": "bar", + "FOO_BAR": "-_style_module_css_upper-FOO_BAR", + "MY-BTN-INFO_IS-DISABLED": "value", + "SIMPLE": "-_style_module_css_upper-SIMPLE", +} +`; + +exports[`ConfigTestCases css exports-convention exported tests should have correct convention for css exports name 7`] = ` +Object { + "btn--info_is-disabled_1": "-_style_module_css_as-is-btn--info_is-disabled_1", + "btn-info_is-disabled": "-_style_module_css_as-is-btn-info_is-disabled", + "foo": "bar", + "foo_bar": "-_style_module_css_as-is-foo_bar", + "my-btn-info_is-disabled": "value", + "simple": "-_style_module_css_as-is-simple", +} +`; + +exports[`ConfigTestCases css exports-convention exported tests should have correct convention for css exports name 8`] = ` +Object { + "btn--info_is-disabled_1": "-_style_module_css_camel-case-btn--info_is-disabled_1", + "btn-info_is-disabled": "-_style_module_css_camel-case-btn-info_is-disabled", + "btnInfoIsDisabled": "-_style_module_css_camel-case-btn-info_is-disabled", + "btnInfoIsDisabled1": "-_style_module_css_camel-case-btn--info_is-disabled_1", + "foo": "bar", + "fooBar": "-_style_module_css_camel-case-foo_bar", + "foo_bar": "-_style_module_css_camel-case-foo_bar", + "my-btn-info_is-disabled": "value", + "myBtnInfoIsDisabled": "value", + "simple": "-_style_module_css_camel-case-simple", +} +`; + +exports[`ConfigTestCases css exports-convention exported tests should have correct convention for css exports name 9`] = ` +Object { + "btnInfoIsDisabled": "-_style_module_css_camel-case-only-btnInfoIsDisabled", + "btnInfoIsDisabled1": "-_style_module_css_camel-case-only-btnInfoIsDisabled1", + "foo": "bar", + "fooBar": "-_style_module_css_camel-case-only-fooBar", + "myBtnInfoIsDisabled": "value", + "simple": "-_style_module_css_camel-case-only-simple", +} +`; + +exports[`ConfigTestCases css exports-convention exported tests should have correct convention for css exports name 10`] = ` +Object { + "btn--info_is-disabled_1": "-_style_module_css_dashes-btn--info_is-disabled_1", + "btn-info_is-disabled": "-_style_module_css_dashes-btn-info_is-disabled", + "btnInfo_isDisabled": "-_style_module_css_dashes-btn-info_is-disabled", + "btnInfo_isDisabled_1": "-_style_module_css_dashes-btn--info_is-disabled_1", + "foo": "bar", + "foo_bar": "-_style_module_css_dashes-foo_bar", + "my-btn-info_is-disabled": "value", + "myBtnInfo_isDisabled": "value", + "simple": "-_style_module_css_dashes-simple", +} +`; + +exports[`ConfigTestCases css exports-convention exported tests should have correct convention for css exports name 11`] = ` +Object { + "btnInfo_isDisabled": "-_style_module_css_dashes-only-btnInfo_isDisabled", + "btnInfo_isDisabled_1": "-_style_module_css_dashes-only-btnInfo_isDisabled_1", + "foo": "bar", + "foo_bar": "-_style_module_css_dashes-only-foo_bar", + "myBtnInfo_isDisabled": "value", + "simple": "-_style_module_css_dashes-only-simple", +} +`; + +exports[`ConfigTestCases css exports-convention exported tests should have correct convention for css exports name 12`] = ` +Object { + "BTN--INFO_IS-DISABLED_1": "-_style_module_css_upper-BTN--INFO_IS-DISABLED_1", + "BTN-INFO_IS-DISABLED": "-_style_module_css_upper-BTN-INFO_IS-DISABLED", + "FOO": "bar", + "FOO_BAR": "-_style_module_css_upper-FOO_BAR", + "MY-BTN-INFO_IS-DISABLED": "value", + "SIMPLE": "-_style_module_css_upper-SIMPLE", +} +`; + +exports[`ConfigTestCases css large exported tests should allow to create css modules: dev 1`] = ` +Object { + "placeholder": "my-app-_tailwind_module_css-placeholder-gray-700", +} +`; + +exports[`ConfigTestCases css large exported tests should allow to create css modules: prod 1`] = ` +Object { + "placeholder": "-144-Oh6j", +} +`; + +exports[`ConfigTestCases css large-css-head-data-compression exported tests should allow to create css modules: dev 1`] = ` +Object { + "placeholder": "my-app-_large_tailwind_module_css-placeholder-gray-700", +} +`; + +exports[`ConfigTestCases css large-css-head-data-compression exported tests should allow to create css modules: prod 1`] = ` +Object { + "placeholder": "-658-Oh6j", +} +`; + +exports[`ConfigTestCases css local-ident-name exported tests should have correct local ident for css export locals 1`] = ` +Object { + "btn--info_is-disabled_1": "-_style_module_css-btn--info_is-disabled_1", + "btn-info_is-disabled": "-_style_module_css-btn-info_is-disabled", + "color-red": "---_style_module_css-color-red", + "foo": "bar", + "foo_bar": "-_style_module_css-foo_bar", + "my-btn-info_is-disabled": "value", + "simple": "-_style_module_css-simple", +} +`; + +exports[`ConfigTestCases css local-ident-name exported tests should have correct local ident for css export locals 2`] = ` +Object { + "btn--info_is-disabled_1": "de84261a9640bc9390f3", + "btn-info_is-disabled": "ecdfa12ee9c667c55af7", + "color-red": "--b7dc4acdff896aeffb60", + "foo": "bar", + "foo_bar": "d46074bbd7d5ee641466", + "my-btn-info_is-disabled": "value", + "simple": "d55fd643016d378ac454", +} +`; + +exports[`ConfigTestCases css local-ident-name exported tests should have correct local ident for css export locals 3`] = ` +Object { + "btn--info_is-disabled_1": "ea850e6088d2566f677d-btn--info_is-disabled_1", + "btn-info_is-disabled": "ea850e6088d2566f677d-btn-info_is-disabled", + "color-red": "--ea850e6088d2566f677d-color-red", + "foo": "bar", + "foo_bar": "ea850e6088d2566f677d-foo_bar", + "my-btn-info_is-disabled": "value", + "simple": "ea850e6088d2566f677d-simple", +} +`; + +exports[`ConfigTestCases css local-ident-name exported tests should have correct local ident for css export locals 4`] = ` +Object { + "btn--info_is-disabled_1": "./style.module__btn--info_is-disabled_1", + "btn-info_is-disabled": "./style.module__btn-info_is-disabled", + "color-red": "--./style.module__color-red", + "foo": "bar", + "foo_bar": "./style.module__foo_bar", + "my-btn-info_is-disabled": "value", + "simple": "./style.module__simple", +} +`; + +exports[`ConfigTestCases css local-ident-name exported tests should have correct local ident for css export locals 5`] = ` +Object { + "btn--info_is-disabled_1": "./style.module.css__btn--info_is-disabled_1", + "btn-info_is-disabled": "./style.module.css__btn-info_is-disabled", + "color-red": "--./style.module.css__color-red", + "foo": "bar", + "foo_bar": "./style.module.css__foo_bar", + "my-btn-info_is-disabled": "value", + "simple": "./style.module.css__simple", +} +`; + +exports[`ConfigTestCases css local-ident-name exported tests should have correct local ident for css export locals 6`] = ` +Object { + "btn--info_is-disabled_1": "./style.module.css__btn--info_is-disabled_1", + "btn-info_is-disabled": "./style.module.css__btn-info_is-disabled", + "color-red": "--./style.module.css__color-red", + "foo": "bar", + "foo_bar": "./style.module.css__foo_bar", + "my-btn-info_is-disabled": "value", + "simple": "./style.module.css__simple", +} +`; + +exports[`ConfigTestCases css local-ident-name exported tests should have correct local ident for css export locals 7`] = ` +Object { + "btn--info_is-disabled_1": "-_style_module_css_uniqueName-id-contenthash-de84261a9640bc9390f3", + "btn-info_is-disabled": "-_style_module_css_uniqueName-id-contenthash-ecdfa12ee9c667c55af7", + "color-red": "---_style_module_css_uniqueName-id-contenthash-b7dc4acdff896aeffb60", + "foo": "bar", + "foo_bar": "-_style_module_css_uniqueName-id-contenthash-d46074bbd7d5ee641466", + "my-btn-info_is-disabled": "value", + "simple": "-_style_module_css_uniqueName-id-contenthash-d55fd643016d378ac454", +} +`; + +exports[`ConfigTestCases css local-ident-name exported tests should have correct local ident for css export locals 8`] = ` +Object { + "btn--info_is-disabled_1": "./style.module.less__btn--info_is-disabled_1", + "btn-info_is-disabled": "./style.module.less__btn-info_is-disabled", + "color-red": "--./style.module.less__color-red", + "foo": "bar", + "foo_bar": "./style.module.less__foo_bar", + "my-btn-info_is-disabled": "value", + "simple": "./style.module.less__simple", +} +`; + +exports[`ConfigTestCases css local-ident-name exported tests should have correct local ident for css export locals 9`] = ` +Object { + "btn--info_is-disabled_1": "-_style_module_css-btn--info_is-disabled_1", + "btn-info_is-disabled": "-_style_module_css-btn-info_is-disabled", + "color-red": "---_style_module_css-color-red", + "foo": "bar", + "foo_bar": "-_style_module_css-foo_bar", + "my-btn-info_is-disabled": "value", + "simple": "-_style_module_css-simple", +} +`; + +exports[`ConfigTestCases css local-ident-name exported tests should have correct local ident for css export locals 10`] = ` +Object { + "btn--info_is-disabled_1": "de84261a9640bc9390f3", + "btn-info_is-disabled": "ecdfa12ee9c667c55af7", + "color-red": "--b7dc4acdff896aeffb60", + "foo": "bar", + "foo_bar": "d46074bbd7d5ee641466", + "my-btn-info_is-disabled": "value", + "simple": "d55fd643016d378ac454", +} +`; + +exports[`ConfigTestCases css local-ident-name exported tests should have correct local ident for css export locals 11`] = ` +Object { + "btn--info_is-disabled_1": "ea850e6088d2566f677d-btn--info_is-disabled_1", + "btn-info_is-disabled": "ea850e6088d2566f677d-btn-info_is-disabled", + "color-red": "--ea850e6088d2566f677d-color-red", + "foo": "bar", + "foo_bar": "ea850e6088d2566f677d-foo_bar", + "my-btn-info_is-disabled": "value", + "simple": "ea850e6088d2566f677d-simple", +} +`; + +exports[`ConfigTestCases css local-ident-name exported tests should have correct local ident for css export locals 12`] = ` +Object { + "btn--info_is-disabled_1": "./style.module__btn--info_is-disabled_1", + "btn-info_is-disabled": "./style.module__btn-info_is-disabled", + "color-red": "--./style.module__color-red", + "foo": "bar", + "foo_bar": "./style.module__foo_bar", + "my-btn-info_is-disabled": "value", + "simple": "./style.module__simple", +} +`; + +exports[`ConfigTestCases css local-ident-name exported tests should have correct local ident for css export locals 13`] = ` +Object { + "btn--info_is-disabled_1": "./style.module.css__btn--info_is-disabled_1", + "btn-info_is-disabled": "./style.module.css__btn-info_is-disabled", + "color-red": "--./style.module.css__color-red", + "foo": "bar", + "foo_bar": "./style.module.css__foo_bar", + "my-btn-info_is-disabled": "value", + "simple": "./style.module.css__simple", +} +`; + +exports[`ConfigTestCases css local-ident-name exported tests should have correct local ident for css export locals 14`] = ` +Object { + "btn--info_is-disabled_1": "./style.module.css__btn--info_is-disabled_1", + "btn-info_is-disabled": "./style.module.css__btn-info_is-disabled", + "color-red": "--./style.module.css__color-red", + "foo": "bar", + "foo_bar": "./style.module.css__foo_bar", + "my-btn-info_is-disabled": "value", + "simple": "./style.module.css__simple", +} +`; + +exports[`ConfigTestCases css local-ident-name exported tests should have correct local ident for css export locals 15`] = ` +Object { + "btn--info_is-disabled_1": "-_style_module_css_uniqueName-id-contenthash-de84261a9640bc9390f3", + "btn-info_is-disabled": "-_style_module_css_uniqueName-id-contenthash-ecdfa12ee9c667c55af7", + "color-red": "---_style_module_css_uniqueName-id-contenthash-b7dc4acdff896aeffb60", + "foo": "bar", + "foo_bar": "-_style_module_css_uniqueName-id-contenthash-d46074bbd7d5ee641466", + "my-btn-info_is-disabled": "value", + "simple": "-_style_module_css_uniqueName-id-contenthash-d55fd643016d378ac454", +} +`; + +exports[`ConfigTestCases css local-ident-name exported tests should have correct local ident for css export locals 16`] = ` +Object { + "btn--info_is-disabled_1": "./style.module.less__btn--info_is-disabled_1", + "btn-info_is-disabled": "./style.module.less__btn-info_is-disabled", + "color-red": "--./style.module.less__color-red", + "foo": "bar", + "foo_bar": "./style.module.less__foo_bar", + "my-btn-info_is-disabled": "value", + "simple": "./style.module.less__simple", +} +`; + +exports[`ConfigTestCases css pure-css exported tests should compile 1`] = ` +Array [ + "/*!*******************************************!*\\\\ + !*** css ../css-modules/style.module.css ***! + \\\\*******************************************/ +.class { + color: red; +} + +.local1, +.local2 .global, +.local3 { + color: green; +} + +.global ._-_css-modules_style_module_css-local4 { + color: yellow; +} + +.local5.global.local6 { + color: blue; +} + +.local7 div:not(.disabled, .mButtonDisabled, .tipOnly) { + pointer-events: initial !important; +} + +.local8 :is(div.parent1.child1.vertical-tiny, + div.parent1.child1.vertical-small, + div.otherDiv.horizontal-tiny, + div.otherDiv.horizontal-small div.description) { + max-height: 0; + margin: 0; + overflow: hidden; +} + +.local9 :matches(div.parent1.child1.vertical-tiny, + div.parent1.child1.vertical-small, + div.otherDiv.horizontal-tiny, + div.otherDiv.horizontal-small div.description) { + max-height: 0; + margin: 0; + overflow: hidden; +} + +.local10 :where(div.parent1.child1.vertical-tiny, + div.parent1.child1.vertical-small, + div.otherDiv.horizontal-tiny, + div.otherDiv.horizontal-small div.description) { + max-height: 0; + margin: 0; + overflow: hidden; +} + +.local11 div:has(.disabled, .mButtonDisabled, .tipOnly) { + pointer-events: initial !important; +} + +.local12 div:current(p, span) { + background-color: yellow; +} + +.local13 div:past(p, span) { + display: none; +} + +.local14 div:future(p, span) { + background-color: yellow; +} + +.local15 div:-moz-any(ol, ul, menu, dir) { + list-style-type: square; +} + +.local16 li:-webkit-any(:first-child, :last-child) { + background-color: aquamarine; +} + +.local9 :matches(div.parent1.child1.vertical-tiny, + div.parent1.child1.vertical-small, + div.otherDiv.horizontal-tiny, + div.otherDiv.horizontal-small div.description) { + max-height: 0; + margin: 0; + overflow: hidden; +} + +._-_css-modules_style_module_css-nested1.nested2.nested3 { + color: pink; +} + +#ident { + color: purple; +} + +@keyframes localkeyframes { + 0% { + left: var(--pos1x); + top: var(--pos1y); + color: var(--theme-color1); + } + 100% { + left: var(--pos2x); + top: var(--pos2y); + color: var(--theme-color2); + } +} + +@keyframes localkeyframes2 { + 0% { + left: 0; + } + 100% { + left: 100px; + } +} + +.animation { + animation-name: localkeyframes; + animation: 3s ease-in 1s 2 reverse both paused localkeyframes, localkeyframes2; + --pos1x: 0px; + --pos1y: 0px; + --pos2x: 10px; + --pos2y: 20px; +} + +/* .composed { + composes: local1; + composes: local2; +} */ + +.vars { + color: var(--local-color); + --local-color: red; +} + +.globalVars { + color: var(--global-color); + --global-color: red; +} + +@media (min-width: 1600px) { + .wideScreenClass { + color: var(--local-color); + --local-color: green; + } +} + +@media screen and (max-width: 600px) { + .narrowScreenClass { + color: var(--local-color); + --local-color: purple; + } +} + +@supports (display: grid) { + .displayGridInSupports { + display: grid; + } +} + +@supports not (display: grid) { + .floatRightInNegativeSupports { + float: right; + } +} + +@supports (display: flex) { + @media screen and (min-width: 900px) { + .displayFlexInMediaInSupports { + display: flex; + } + } +} + +@media screen and (min-width: 900px) { + @supports (display: flex) { + .displayFlexInSupportsInMedia { + display: flex; + } + } +} + +@MEDIA screen and (min-width: 900px) { + @SUPPORTS (display: flex) { + .displayFlexInSupportsInMediaUpperCase { + display: flex; + } + } +} + +.animationUpperCase { + ANIMATION-NAME: localkeyframesUPPERCASE; + ANIMATION: 3s ease-in 1s 2 reverse both paused localkeyframesUPPERCASE, localkeyframes2UPPPERCASE; + --pos1x: 0px; + --pos1y: 0px; + --pos2x: 10px; + --pos2y: 20px; +} + +@KEYFRAMES localkeyframesUPPERCASE { + 0% { + left: VAR(--pos1x); + top: VAR(--pos1y); + color: VAR(--theme-color1); + } + 100% { + left: VAR(--pos2x); + top: VAR(--pos2y); + color: VAR(--theme-color2); + } +} + +@KEYframes localkeyframes2UPPPERCASE { + 0% { + left: 0; + } + 100% { + left: 100px; + } +} + +.globalUpperCase ._-_css-modules_style_module_css-localUpperCase { + color: yellow; +} + +.VARS { + color: VAR(--LOCAL-COLOR); + --LOCAL-COLOR: red; +} + +.globalVarsUpperCase { + COLOR: VAR(--GLOBAR-COLOR); + --GLOBAR-COLOR: red; +} + +@supports (top: env(safe-area-inset-top, 0)) { + .inSupportScope { + color: red; + } +} + +.a { + animation: 3s animationName; + -webkit-animation: 3s animationName; +} + +.b { + animation: animationName 3s; + -webkit-animation: animationName 3s; +} + +.c { + animation-name: animationName; + -webkit-animation-name: animationName; +} + +.d { + --animation-name: animationName; +} + +@keyframes animationName { + 0% { + background: white; + } + 100% { + background: red; + } +} + +@-webkit-keyframes animationName { + 0% { + background: white; + } + 100% { + background: red; + } +} + +@-moz-keyframes mozAnimationName { + 0% { + background: white; + } + 100% { + background: red; + } +} + +@counter-style thumbs { + system: cyclic; + symbols: \\"\\\\1F44D\\"; + suffix: \\" \\"; +} + +@font-feature-values Font One { + @styleset { + nice-style: 12; + } +} + +/* At-rule for \\"nice-style\\" in Font Two */ +@font-feature-values Font Two { + @styleset { + nice-style: 4; + } +} + +@property --my-color { + syntax: \\"\\"; + inherits: false; + initial-value: #c0ffee; +} + +.class { + color: var(--my-color); +} + +@layer utilities { + .padding-sm { + padding: 0.5rem; + } + + .padding-lg { + padding: 0.8rem; + } +} + +.class { + color: red; + + .nested-pure { + color: red; + } + + @media screen and (min-width: 200px) { + color: blue; + + .nested-media { + color: blue; + } + } + + @supports (display: flex) { + display: flex; + + .nested-supports { + display: flex; + } + } + + @layer foo { + background: red; + + .nested-layer { + background: red; + } + } + + @container foo { + background: red; + + .nested-layer { + background: red; + } + } +} + +.not-selector-inside { + color: #fff; + opacity: 0.12; + padding: .5px; + unknown: :local(.test); + unknown1: :local .test; + unknown2: :global .test; + unknown3: :global .test; + unknown4: .foo, .bar, #bar; +} + +@unknown :local .local :global .global { + color: red; +} + +@unknown :local(.local) :global(.global) { + color: red; +} + +.nested-var { + .again { + color: var(--local-color); + } +} + +.nested-with-local-pseudo { + color: red; + + ._-_css-modules_style_module_css-local-nested { + color: red; + } + + .global-nested { + color: red; + } + + ._-_css-modules_style_module_css-local-nested { + color: red; + } + + .global-nested { + color: red; + } + + ._-_css-modules_style_module_css-local-nested, .global-nested-next { + color: red; + } + + ._-_css-modules_style_module_css-local-nested, .global-nested-next { + color: red; + } + + .foo, .bar { + color: red; + } +} + +#id-foo { + color: red; + + #id-bar { + color: red; + } +} + +.nested-parens { + .local9 div:has(.vertical-tiny, .vertical-small) { + max-height: 0; + margin: 0; + overflow: hidden; + } +} + +.global-foo { + .nested-global { + color: red; + } + + ._-_css-modules_style_module_css-local-in-global { + color: blue; + } +} + +@unknown .class { + color: red; + + .class { + color: red; + } +} + +.class ._-_css-modules_style_module_css-in-local-global-scope, +.class ._-_css-modules_style_module_css-in-local-global-scope, +._-_css-modules_style_module_css-class-local-scope .in-local-global-scope { + color: red; +} + +@container (width > 400px) { + .class-in-container { + font-size: 1.5em; + } +} + +@container summary (min-width: 400px) { + @container (width > 400px) { + .deep-class-in-container { + font-size: 1.5em; + } + } +} + +:scope { + color: red; +} + +.placeholder-gray-700:-ms-input-placeholder { + --placeholder-opacity: 1; + color: #4a5568; + color: rgba(74, 85, 104, var(--placeholder-opacity)); +} +.placeholder-gray-700::-ms-input-placeholder { + --placeholder-opacity: 1; + color: #4a5568; + color: rgba(74, 85, 104, var(--placeholder-opacity)); +} +.placeholder-gray-700::placeholder { + --placeholder-opacity: 1; + color: #4a5568; + color: rgba(74, 85, 104, var(--placeholder-opacity)); +} + +:root { + --test: dark; +} + +@media screen and (prefers-color-scheme: var(--test)) { + .baz { + color: white; + } +} + +@keyframes slidein { + from { + margin-left: 100%; + width: 300%; + } + + to { + margin-left: 0%; + width: 100%; + } +} + +.class { + animation: + foo var(--animation-name) 3s, + var(--animation-name) 3s, + 3s linear 1s infinite running slidein, + 3s linear env(foo, var(--baz)) infinite running slidein; +} + +:root { + --baz: 10px; +} + +.class { + bar: env(foo, var(--baz)); +} + +.global-foo, ._-_css-modules_style_module_css-bar { + ._-_css-modules_style_module_css-local-in-global { + color: blue; + } + + @media screen { + .my-global-class-again, + ._-_css-modules_style_module_css-my-global-class-again { + color: red; + } + } +} + +.first-nested { + .first-nested-nested { + color: red; + } +} + +.first-nested-at-rule { + @media screen { + .first-nested-nested-at-rule-deep { + color: red; + } + } +} + +.again-global { + color:red; +} + +.again-again-global { + .again-again-global { + color: red; + } +} + +:root { + --foo: red; +} + +.again-again-global { + color: var(--foo); + + .again-again-global { + color: var(--foo); + } +} + +.again-again-global { + animation: slidein 3s; + + .again-again-global, .class, ._-_css-modules_style_module_css-nested1.nested2.nested3 { + animation: slidein 3s; + } + + .local2 .global, + .local3 { + color: red; + } +} + +@unknown var(--foo) { + color: red; +} + +.class { + .class { + .class { + .class {} + } + } +} + +.class { + .class { + .class { + .class { + animation: slidein 3s; + } + } + } +} + +.class { + animation: slidein 3s; + .class { + animation: slidein 3s; + .class { + animation: slidein 3s; + .class { + animation: slidein 3s; + } + } + } +} + +/*!***********************!*\\\\ + !*** css ./style.css ***! + \\\\***********************/ + +.class { + color: red; + background: var(--color); +} + +@keyframes test { + 0% { + color: red; + } + 100% { + color: blue; + } +} + +._-_style_css-class { + color: red; +} + +._-_style_css-class { + color: green; +} + +.class { + color: blue; +} + +.class { + color: white; +} + + +.class { + animation: test 1s, test; +} + +head{--webpack-main:local4:_-_css-modules_style_module_css-local4/nested1:_-_css-modules_style_module_css-nested1/localUpperCase:_-_css-modules_style_module_css-localUpperCase/local-nested:_-_css-modules_style_module_css-local-nested/local-in-global:_-_css-modules_style_module_css-local-in-global/in-local-global-scope:_-_css-modules_style_module_css-in-local-global-scope/class-local-scope:_-_css-modules_style_module_css-class-local-scope/bar:_-_css-modules_style_module_css-bar/my-global-class-again:_-_css-modules_style_module_css-my-global-class-again/&\\\\.\\\\.\\\\/css-modules\\\\/style\\\\.module\\\\.css,class:_-_style_css-class/foo:bar/&\\\\.\\\\/style\\\\.css;}", +] +`; + +exports[`ConfigTestCases css urls exported tests should be able to handle styles in div.css 1`] = ` +Object { + "--foo": " url(img.09a1a1112c577c279435.png)", + "--foo-bar": " \\"http://www.example.com/pinkish.gif\\"", + "a": " url(img.09a1a1112c577c279435.png)", + "a1": " url(img.09a1a1112c577c279435.png)", + "a10": " green url( img\\\\ img.09a1a1112c577c279435.png ) xyz", + "a100": " url(img\\\\)img.09a1a1112c577c279435.png)", + "a101": " url(img\\\\ img.09a1a1112c577c279435.png)", + "a102": " url(img\\\\ img.09a1a1112c577c279435.png)", + "a103": " url(img\\\\(img.09a1a1112c577c279435.png)", + "a104": " url(img\\\\(img.09a1a1112c577c279435.png)", + "a105": " url(img\\\\(img.09a1a1112c577c279435.png)", + "a106": " url(img\\\\(img.09a1a1112c577c279435.png)", + "a107": " url(img\\\\'\\\\'\\\\'img.09a1a1112c577c279435.png)", + "a108": " url(\\"img'() img.09a1a1112c577c279435.png\\")", + "a109": " url(img\\\\'img.09a1a1112c577c279435.png)", + "a11": " green url( img\\\\ img.09a1a1112c577c279435.png ) xyz", + "a110": " url(img\\\\(img.09a1a1112c577c279435.png)", + "a111": " url(img\\\\)img.09a1a1112c577c279435.png)", + "a112": " url(img\\\\ img.09a1a1112c577c279435.png)", + "a113": " url(img\\\\'\\\\'\\\\'img.09a1a1112c577c279435.png)", + "a114": " url(\\"img'() img.09a1a1112c577c279435.png\\")", + "a115": " url(img\\\\'img.09a1a1112c577c279435.png)", + "a116": " url(img\\\\(img.09a1a1112c577c279435.png)", + "a117": " url(img\\\\)img.09a1a1112c577c279435.png)", + "a118": " url(img\\\\ img.09a1a1112c577c279435.png)", + "a119": " url(img.09a1a1112c577c279435.png)", + "a12": " green url(img.09a1a1112c577c279435.png) xyz", + "a120": " url(img\\\\'\\\\'\\\\'img.09a1a1112c577c279435.png)", + "a121": " url(\\"img'() img.09a1a1112c577c279435.png\\")", + "a122": " url(img\\\\'img.09a1a1112c577c279435.png)", + "a123": " url(img\\\\(img.09a1a1112c577c279435.png)", + "a124": " url(img\\\\)img.09a1a1112c577c279435.png)", + "a125": " url(img\\\\ img.09a1a1112c577c279435.png)", + "a126": " url(img.09a1a1112c577c279435.png)", + "a127": " url(img.09a1a1112c577c279435.png)", + "a128": " url(img\\\\'img.09a1a1112c577c279435.png)", + "a129": " url(\\"img'() img.09a1a1112c577c279435.png\\")", + "a13": " green url(data:image/png;base64,AAA) url(http://example.com/image.jpg) url(//example.com/image.png) xyz", + "a130": " url(\\"img'() img.09a1a1112c577c279435.png\\")", + "a131": " url(img.09a1a1112c577c279435.png)", + "a132": " url(img.09a1a1112c577c279435.png)", + "a133": " url(img.09a1a1112c577c279435.png?foo=bar)", + "a134": " url(img.09a1a1112c577c279435.png?foo=bar)", + "a135": " url(img.09a1a1112c577c279435.png?foo=bar#hash)", + "a136": " url(img.09a1a1112c577c279435.png?foo=bar#hash)", + "a137": " url(img.09a1a1112c577c279435.png?foo=bar)", + "a138": " url(img.09a1a1112c577c279435.png?bar=foo)", + "a139": " url(img.09a1a1112c577c279435.png?foo=bar#foo)", + "a14": " url(\\"data:image/svg+xml;charset=utf-8,\\")", + "a140": " url(img.09a1a1112c577c279435.png?bar=foo#bar)", + "a141": " url(img.09a1a1112c577c279435.png?foo=1&bar=2)", + "a142": " url(img.09a1a1112c577c279435.png?foo=2&bar=1)", + "a143": " url(data:image/svg+xml;charset=UTF-8,%3C%3Fxml%20version%3D%221.0%22%20encoding%3D%22utf-8%22%3F%3E%0A%3C!DOCTYPE%20svg%20PUBLIC%20%22-%2F%2FW3C%2F%2FDTD%20SVG%201.1%2F%2FEN%22%20%22http%3A%2F%2Fwww.w3.org%2FGraphics%2FSVG%2F1.1%2FDTD%2Fsvg11.dtd%22%3E%0A%3Csvg%20version%3D%221.1%22%20id%3D%22Layer_1%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20xmlns%3Axlink%3D%22http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink%22%20x%3D%220px%22%20y%3D%220px%22%0A%09%20width%3D%22191px%22%20height%3D%22191px%22%20viewBox%3D%220%200%20191%20191%22%20enable-background%3D%22new%200%200%20191%20191%22%20xml%3Aspace%3D%22preserve%22%3E%0A%3Cpath%20fill%3D%22%23636363%22%20d%3D%22M95.5%2C0C42.8%2C0%2C0%2C42.8%2C0%2C95.5S42.8%2C191%2C95.5%2C191S191%2C148.2%2C191%2C95.5S148.2%2C0%2C95.5%2C0z%20M95.5%2C187.6%0A%09c-50.848%2C0-92.1-41.25-92.1-92.1c0-50.848%2C41.252-92.1%2C92.1-92.1c50.85%2C0%2C92.1%2C41.252%2C92.1%2C92.1%0A%09C187.6%2C146.35%2C146.35%2C187.6%2C95.5%2C187.6z%22%2F%3E%0A%3Cg%3E%0A%09%3Cpath%20fill%3D%22%23636363%22%20d%3D%22M92.9%2C10v8.6H91v-6.5c-0.1%2C0.1-0.2%2C0.2-0.4%2C0.3c-0.2%2C0.1-0.3%2C0.2-0.4%2C0.2c-0.1%2C0-0.3%2C0.1-0.5%2C0.2%0A%09%09c-0.2%2C0.1-0.3%2C0.1-0.5%2C0.1v-1.6c0.5-0.1%2C0.9-0.3%2C1.4-0.5c0.5-0.2%2C0.8-0.5%2C1.2-0.7h1.1V10z%22%2F%3E%0A%09%3Cpath%20fill%3D%22%23636363%22%20d%3D%22M97.1%2C17.1h3.602v1.5h-5.6V18c0-0.4%2C0.1-0.8%2C0.2-1.2c0.1-0.4%2C0.3-0.6%2C0.5-0.9c0.2-0.3%2C0.5-0.5%2C0.7-0.7%0A%09%09c0.2-0.2%2C0.5-0.4%2C0.7-0.6c0.199-0.2%2C0.5-0.3%2C0.6-0.5c0.102-0.2%2C0.301-0.3%2C0.5-0.5c0.2-0.2%2C0.2-0.3%2C0.301-0.5%0A%09%09c0.101-0.2%2C0.101-0.3%2C0.101-0.5c0-0.4-0.101-0.6-0.3-0.8c-0.2-0.2-0.4-0.3-0.801-0.3c-0.699%2C0-1.399%2C0.3-2.101%2C0.9v-1.6%0A%09%09c0.7-0.5%2C1.5-0.7%2C2.5-0.7c0.399%2C0%2C0.8%2C0.1%2C1.101%2C0.2c0.301%2C0.1%2C0.601%2C0.3%2C0.899%2C0.5c0.3%2C0.2%2C0.399%2C0.5%2C0.5%2C0.8%0A%09%09c0.101%2C0.3%2C0.2%2C0.6%2C0.2%2C1s-0.102%2C0.7-0.2%2C1c-0.099%2C0.3-0.3%2C0.6-0.5%2C0.8c-0.2%2C0.2-0.399%2C0.5-0.7%2C0.7c-0.3%2C0.2-0.5%2C0.4-0.8%2C0.6%0A%09%09c-0.2%2C0.1-0.399%2C0.3-0.5%2C0.4s-0.3%2C0.3-0.5%2C0.4s-0.2%2C0.3-0.3%2C0.4C97.1%2C17%2C97.1%2C17%2C97.1%2C17.1z%22%2F%3E%0A%3C%2Fg%3E%0A%3Cg%3E%0A%09%3Cpath%20fill%3D%22%23636363%22%20d%3D%22M15%2C95.4c0%2C0.7-0.1%2C1.4-0.2%2C2c-0.1%2C0.6-0.4%2C1.1-0.7%2C1.5C13.8%2C99.3%2C13.4%2C99.6%2C12.9%2C99.8s-1%2C0.3-1.5%2C0.3%0A%09%09c-0.7%2C0-1.3-0.1-1.8-0.3v-1.5c0.4%2C0.3%2C1%2C0.4%2C1.6%2C0.4c0.6%2C0%2C1.1-0.2%2C1.5-0.7c0.4-0.5%2C0.5-1.1%2C0.5-1.9l0%2C0%0A%09%09C12.8%2C96.7%2C12.3%2C96.9%2C11.5%2C96.9c-0.3%2C0-0.7-0.102-1-0.2c-0.3-0.101-0.5-0.3-0.8-0.5c-0.3-0.2-0.4-0.5-0.5-0.8%0A%09%09c-0.1-0.3-0.2-0.7-0.2-1c0-0.4%2C0.1-0.8%2C0.2-1.2c0.1-0.4%2C0.3-0.7%2C0.6-0.9c0.3-0.2%2C0.6-0.5%2C0.9-0.6c0.3-0.1%2C0.8-0.2%2C1.2-0.2%0A%09%09c0.5%2C0%2C0.9%2C0.1%2C1.2%2C0.3c0.3%2C0.2%2C0.7%2C0.4%2C0.9%2C0.8s0.5%2C0.7%2C0.6%2C1.2S15%2C94.8%2C15%2C95.4z%20M13.1%2C94.4c0-0.2%2C0-0.4-0.1-0.6%0A%09%09c-0.1-0.2-0.1-0.4-0.2-0.5c-0.1-0.1-0.2-0.2-0.4-0.3c-0.2-0.1-0.3-0.1-0.5-0.1c-0.2%2C0-0.3%2C0-0.4%2C0.1s-0.3%2C0.2-0.3%2C0.3%0A%09%09c0%2C0.1-0.2%2C0.3-0.2%2C0.4c0%2C0.1-0.1%2C0.4-0.1%2C0.6c0%2C0.2%2C0%2C0.4%2C0.1%2C0.6c0.1%2C0.2%2C0.1%2C0.3%2C0.2%2C0.4c0.1%2C0.1%2C0.2%2C0.2%2C0.4%2C0.3%0A%09%09c0.2%2C0.1%2C0.3%2C0.1%2C0.5%2C0.1c0.2%2C0%2C0.3%2C0%2C0.4-0.1s0.2-0.2%2C0.3-0.3c0.1-0.1%2C0.2-0.2%2C0.2-0.4C13%2C94.7%2C13.1%2C94.6%2C13.1%2C94.4z%22%2F%3E%0A%3C%2Fg%3E%0A%3Cg%3E%0A%09%3Cpath%20fill%3D%22%23636363%22%20d%3D%22M176%2C99.7V98.1c0.6%2C0.4%2C1.2%2C0.602%2C2%2C0.602c0.5%2C0%2C0.8-0.102%2C1.1-0.301c0.301-0.199%2C0.4-0.5%2C0.4-0.801%0A%09%09c0-0.398-0.2-0.699-0.5-0.898c-0.3-0.2-0.8-0.301-1.3-0.301h-0.802V95h0.701c1.101%2C0%2C1.601-0.4%2C1.601-1.1c0-0.7-0.4-1-1.302-1%0A%09%09c-0.6%2C0-1.1%2C0.2-1.6%2C0.5v-1.5c0.6-0.3%2C1.301-0.4%2C2.1-0.4c0.9%2C0%2C1.5%2C0.2%2C2%2C0.6s0.701%2C0.9%2C0.701%2C1.5c0%2C1.1-0.601%2C1.8-1.701%2C2.1l0%2C0%0A%09%09c0.602%2C0.1%2C1.102%2C0.3%2C1.4%2C0.6s0.5%2C0.8%2C0.5%2C1.3c0%2C0.801-0.3%2C1.4-0.9%2C1.9c-0.6%2C0.5-1.398%2C0.7-2.398%2C0.7%0A%09%09C177.2%2C100.1%2C176.5%2C100%2C176%2C99.7z%22%2F%3E%0A%3C%2Fg%3E%0A%3Cg%3E%0A%09%3Cpath%20fill%3D%22%23636363%22%20d%3D%22M98.5%2C179.102c0%2C0.398-0.1%2C0.799-0.2%2C1.199C98.2%2C180.7%2C98%2C181%2C97.7%2C181.2s-0.601%2C0.5-0.9%2C0.601%0A%09%09c-0.3%2C0.1-0.7%2C0.199-1.2%2C0.199c-0.5%2C0-0.9-0.1-1.3-0.3c-0.4-0.2-0.7-0.399-0.9-0.8c-0.2-0.4-0.5-0.7-0.6-1.2%0A%09%09c-0.1-0.5-0.2-1-0.2-1.601c0-0.699%2C0.1-1.399%2C0.3-2c0.2-0.601%2C0.4-1.101%2C0.8-1.5c0.4-0.399%2C0.7-0.699%2C1.2-1c0.5-0.3%2C1-0.3%2C1.6-0.3%0A%09%09c0.6%2C0%2C1.2%2C0.101%2C1.5%2C0.199v1.5c-0.4-0.199-0.9-0.399-1.4-0.399c-0.3%2C0-0.6%2C0.101-0.8%2C0.2c-0.2%2C0.101-0.5%2C0.3-0.7%2C0.5%0A%09%09c-0.2%2C0.199-0.3%2C0.5-0.4%2C0.8c-0.1%2C0.301-0.2%2C0.7-0.2%2C1.101l0%2C0c0.4-0.601%2C1-0.8%2C1.8-0.8c0.3%2C0%2C0.7%2C0.1%2C0.9%2C0.199%0A%09%09c0.2%2C0.101%2C0.5%2C0.301%2C0.7%2C0.5c0.199%2C0.2%2C0.398%2C0.5%2C0.5%2C0.801C98.5%2C178.2%2C98.5%2C178.7%2C98.5%2C179.102z%20M96.7%2C179.2%0A%09%09c0-0.899-0.4-1.399-1.1-1.399c-0.2%2C0-0.3%2C0-0.5%2C0.1c-0.2%2C0.101-0.3%2C0.201-0.4%2C0.301c-0.1%2C0.101-0.2%2C0.199-0.2%2C0.4%0A%09%09c0%2C0.199-0.1%2C0.299-0.1%2C0.5c0%2C0.199%2C0%2C0.398%2C0.1%2C0.6s0.1%2C0.3%2C0.2%2C0.5c0.1%2C0.199%2C0.2%2C0.199%2C0.4%2C0.3c0.2%2C0.101%2C0.3%2C0.101%2C0.5%2C0.101%0A%09%09c0.2%2C0%2C0.3%2C0%2C0.5-0.101c0.2-0.101%2C0.301-0.199%2C0.301-0.3c0-0.1%2C0.199-0.301%2C0.199-0.399C96.6%2C179.7%2C96.7%2C179.4%2C96.7%2C179.2z%22%2F%3E%0A%3C%2Fg%3E%0A%3Ccircle%20fill%3D%22%23636363%22%20cx%3D%2295%22%20cy%3D%2295%22%20r%3D%227%22%2F%3E%0A%3C%2Fsvg%3E%0A) 50% 50%/191px no-repeat", + "a144": " url(img.09a1a1112c577c279435.png)", + "a145": " url(img.09a1a1112c577c279435.png)", + "a148": " url('data:image/svg+xml,%3Csvg xmlns=\\"http://www.w3.org/2000/svg\\"%3E%3Crect width=\\"100%25\\" height=\\"100%25\\" style=\\"stroke: rgb(223,224,225); stroke-width: 2px; fill: none; stroke-dasharray: 6px 3px\\" /%3E%3C/svg%3E')", + "a149": " url('data:image/svg+xml,%3Csvg xmlns=\\"http://www.w3.org/2000/svg\\"%3E%3Crect width=\\"100%25\\" height=\\"100%25\\" style=\\"stroke: rgb(223,224,225); stroke-width: 2px; fill: none; stroke-dasharray: 6px 3px\\" /%3E%3C/svg%3E')", + "a15": " url(data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20viewBox%3D%270%200%2042%2026%27%20fill%3D%27%2523007aff%27%3E%3Crect%20width%3D%274%27%20height%3D%274%27%2F%3E%3Crect%20x%3D%278%27%20y%3D%271%27%20width%3D%2734%27%20height%3D%272%27%2F%3E%3Crect%20y%3D%2711%27%20width%3D%274%27%20height%3D%274%27%2F%3E%3Crect%20x%3D%278%27%20y%3D%2712%27%20width%3D%2734%27%20height%3D%272%27%2F%3E%3Crect%20y%3D%2722%27%20width%3D%274%27%20height%3D%274%27%2F%3E%3Crect%20x%3D%278%27%20y%3D%2723%27%20width%3D%2734%27%20height%3D%272%27%2F%3E%3C%2Fsvg%3E)", + "a150": " url('data:image/svg+xml,%3Csvg xmlns=\\"http://www.w3.org/2000/svg\\"%3E%3Crect width=\\"100%25\\" height=\\"100%25\\" style=\\"stroke: rgb(223,224,225); stroke-width: 2px; fill: none; stroke-dasharray: 6px 3px\\" /%3E%3C/svg%3E')", + "a151": " url('data:image/svg+xml;utf8,')", + "a152": " url(img.09a1a1112c577c279435.png)", + "a153": " url(img.09a1a1112c577c279435.png)", + "a154": " url(other.09a1a1112c577c279435.png)", + "a155": " url(img.09a1a1112c577c279435.png)", + "a156": " url(\\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23343a40' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M2 5l6 6 6-6'/%3e%3c/svg%3e\\")", + "a157": " url('data:image/svg+xml;utf8,')", + "a158": " src(\\"http://www.example.com/pinkish.gif\\")", + "a159": " src(var(--foo))", + "a16": " url('data:image/svg+xml;charset=utf-8,#filter')", + "a160": " url(img.09a1a1112c577c279435.png param(--color var(--primary-color)))", + "a161": " src(\\"img.png\\" param(--color var(--primary-color)))", + "a162": " url(img\\\\ img.09a1a1112c577c279435.png)", + "a163": " url(img.09a1a1112c577c279435.png)", + "a164": " url( img.png bug)", + "a165": " url(imgn.09a1a1112c577c279435.png)", + "a166": " url('data:image/svg+xml;utf8,')", + "a167": " url(http://example.com/image.jpg)", + "a168": " url(http://example.com/image.jpg)", + "a169": " url(data:,)", + "a17": " url(\\"data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D%5C%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%5C%22%3E%3Cfilter%20id%3D%5C%22filter%5C%22%3E%3CfeGaussianBlur%20in%3D%5C%22SourceAlpha%5C%22%20stdDeviation%3D%5C%220%5C%22%20%2F%3E%3CfeOffset%20dx%3D%5C%221%5C%22%20dy%3D%5C%222%5C%22%20result%3D%5C%22offsetblur%5C%22%20%2F%3E%3CfeFlood%20flood-color%3D%5C%22rgba(255%2C255%2C255%2C1)%5C%22%20%2F%3E%3CfeComposite%20in2%3D%5C%22offsetblur%5C%22%20operator%3D%5C%22in%5C%22%20%2F%3E%3CfeMerge%3E%3CfeMergeNode%20%2F%3E%3CfeMergeNode%20in%3D%5C%22SourceGraphic%5C%22%20%2F%3E%3C%2FfeMerge%3E%3C%2Ffilter%3E%3C%2Fsvg%3E%23filter\\")", + "a170": " url(data:,)", + "a171": " image(ltr 'img.png#xywh=0,0,16,16', red)", + "a172": " image-set( + linear-gradient(blue, white) 1x, + linear-gradient(blue, green) 2x + )", + "a173": " image-set( + url(img.09a1a1112c577c279435.png) type(\\"image/png\\"), + url(img.09a1a1112c577c279435.png) type(\\"image/png\\") + )", + "a174": " image-set( + url(img.09a1a1112c577c279435.png) 1x, + url(img.09a1a1112c577c279435.png) 2x + )", + "a175": " image-set( + url(img.09a1a1112c577c279435.png) 1x, + url(img.09a1a1112c577c279435.png) 2x, + url(img.09a1a1112c577c279435.png) 3x + )", + "a176": " image-set( + url(img.09a1a1112c577c279435.png) type(\\"image/png\\"), + url(img.09a1a1112c577c279435.png) type(\\"image/png\\") + ) \\"img.png\\"", + "a177": " image-set( + url(img.09a1a1112c577c279435.png) 1x type(\\"image/png\\"), + url(img.09a1a1112c577c279435.png) 2x type(\\"image/png\\") + )", + "a178": " image-set( + url(img.09a1a1112c577c279435.png) type(\\"image/png\\") 1x, + url(img.09a1a1112c577c279435.png) type(\\"image/png\\") 2x + )", + "a179": " -webkit-image-set( + url(img.09a1a1112c577c279435.png) 1x + )", + "a18": " url(#highlight)", + "a180": " -webkit-image-set( + url(img.09a1a1112c577c279435.png var(--foo, \\"test.png\\")) 1x + )", + "a181": " src( \\"img.png\\" )", + "a182": " src('img.png')", + "a183": " src('img.png' var(--foo, \\"test.png\\"))", + "a184": " src(var(--foo, \\"test.png\\"))", + "a185": " src(\\" img.png \\")", + "a186": " image-set(url(img.09a1a1112c577c279435.png)1x,url(img.09a1a1112c577c279435.png)2x,url(img.09a1a1112c577c279435.png)3x)", + "a187": " image-set(url(img.09a1a1112c577c279435.png)1x,url(img.09a1a1112c577c279435.png)2x,url(img.09a1a1112c577c279435.png)3x)", + "a188": " image-set(url(img.09a1a1112c577c279435.png)1x,url(img.09a1a1112c577c279435.png)2x,url(img.09a1a1112c577c279435.png)3x)", + "a189": " image-set(url(img.09a1a1112c577c279435.png)1x,url(img.09a1a1112c577c279435.png)2x,url(img.09a1a1112c577c279435.png)3x)", + "a19": " url(#line-marker)", + "a190": " image-set(url(img.09a1a1112c577c279435.png)1x)", + "a191": " image-set(url(img.09a1a1112c577c279435.png)1x,url(img.09a1a1112c577c279435.png)2x)", + "a197": " \\\\u\\\\r\\\\l(img.09a1a1112c577c279435.png)", + "a198": " \\\\image-\\\\set(url(img.09a1a1112c577c279435.png)1x,url(img.09a1a1112c577c279435.png)2x,url(img.09a1a1112c577c279435.png)3x)", + "a199": " \\\\-webk\\\\it-image-set(url(img.09a1a1112c577c279435.png)1x)", + "a2": " url(img.09a1a1112c577c279435.png)", + "a200": "-webkit-image-set(url(img.09a1a1112c577c279435.png)1x)", + "a22": " \\"do not use url(path)\\"", + "a23": " 'do not \\"use\\" url(path)'", + "a24": " -webkit-image-set(url(img1x.09a1a1112c577c279435.png) 1x, url(img2x.09a1a1112c577c279435.png) 2x) +", + "a25": " image-set(url(img1x.09a1a1112c577c279435.png) 1x, url(img2x.09a1a1112c577c279435.png) 2x) +", + "a26": " green url() xyz", + "a27": " green url('') xyz", + "a28": " green url(\\"\\") xyz", + "a29": " green url(' ') xyz", + "a3": " url(img.09a1a1112c577c279435.png)", + "a30": " green url( + ) xyz", + "a4": " url(img.09a1a1112c577c279435.png#hash)", + "a40": " green url(https://raw.githubusercontent.com/webpack/media/master/logo/icon.png) xyz", + "a41": " green url(//raw.githubusercontent.com/webpack/media/master/logo/icon.png) xyz", + "a42": " url(img.09a1a1112c577c279435.png?foo)", + "a43": " url(img.09a1a1112c577c279435.png?foo=bar)", + "a44": " url(img.09a1a1112c577c279435.png?foo=bar#hash)", + "a45": " url(img.09a1a1112c577c279435.png?foo=bar#hash)", + "a46": " url(img.09a1a1112c577c279435.png?)", + "a47": " url(img.09a1a1112c577c279435.png) url(\\"data:image/svg+xml;charset=utf-8,\\") url(img.09a1a1112c577c279435.png)", + "a48": " __URL__()", + "a49": " url(img-simple.09a1a1112c577c279435.png)", + "a5": " url( + img.09a1a1112c577c279435.png + )", + "a50": " url(img-simple.09a1a1112c577c279435.png)", + "a51": " url(img-simple.09a1a1112c577c279435.png)", + "a52": " url(img.09a1a1112c577c279435.png)", + "a53": " url(img.09a1a1112c577c279435.png)", + "a55": " -webkit-image-set()", + "a56": " image-set()", + "a58": " image-set('')", + "a59": " image-set(\\"\\")", + "a6": " green url( img.09a1a1112c577c279435.png ) xyz", + "a60": " image-set(\\"\\" 1x)", + "a61": " image-set(url())", + "a62": " image-set( + url() + )", + "a63": " image-set(URL())", + "a64": " image-set(url(''))", + "a65": " image-set(url(\\"\\"))", + "a66": " image-set(url('') 1x)", + "a67": " image-set(1x)", + "a68": " image-set( + 1x + )", + "a69": " image-set(calc(1rem + 1px) 1x)", + "a7": " green url( img.09a1a1112c577c279435.png ) xyz", + "a70": " -webkit-image-set(url(img1x.09a1a1112c577c279435.png) 1x, url(img2x.09a1a1112c577c279435.png) 2x)", + "a71": " image-set(url(img1x.09a1a1112c577c279435.png) 1x)", + "a72": " image-set(url(img1x.09a1a1112c577c279435.png) 1x, url(img2x.09a1a1112c577c279435.png) 2x)", + "a73": " image-set(url(img\\\\ img.09a1a1112c577c279435.png) 1x, url(img\\\\ img.09a1a1112c577c279435.png) 2x)", + "a74": " image-set(url(img1x.09a1a1112c577c279435.png) 1x, url(img2x.09a1a1112c577c279435.png) 2x), + image-set(url(img1x.09a1a1112c577c279435.png) 1x, url(img2x.09a1a1112c577c279435.png) 2x)", + "a75": " image-set( + url(img1x.09a1a1112c577c279435.png) 1x, + url(img2x.09a1a1112c577c279435.png) 2x, + url(img3x.09a1a1112c577c279435.png) 600dpi + )", + "a76": " image-set(url(img1x.09a1a1112c577c279435.png?foo=bar) 1x)", + "a77": " image-set(url(img1x.09a1a1112c577c279435.png#hash) 1x)", + "a78": " image-set(url(img1x.09a1a1112c577c279435.png?#iefix) 1x)", + "a79": " -webkit-image-set(url(img1x.09a1a1112c577c279435.png) 1x, url(img2x.09a1a1112c577c279435.png) 2x)", + "a8": " green url(img.09a1a1112c577c279435.png) xyz", + "a80": " -webkit-image-set(url(img1x.09a1a1112c577c279435.png) 1x)", + "a81": " -webkit-image-set( + url(img1x.09a1a1112c577c279435.png) 1x + )", + "a82": " image-set(url(img1x.09a1a1112c577c279435.png) 1x)", + "a83": " image-set( + url(img1x.09a1a1112c577c279435.png) 1x + )", + "a84": " image-set(url(img1x.09a1a1112c577c279435.png) 1x, url(img2x.09a1a1112c577c279435.png) 2x)", + "a85": " image-set( + url(img1x.09a1a1112c577c279435.png) 1x, + url(img2x.09a1a1112c577c279435.png) 2x, + url(img3x.09a1a1112c577c279435.png) 600dpi + )", + "a86": " image-set(url(img\\\\ img.09a1a1112c577c279435.png) 1x, url(img\\\\ img.09a1a1112c577c279435.png) 2x)", + "a87": " image-set(url(img1x.09a1a1112c577c279435.png) 1x, url(img2x.09a1a1112c577c279435.png) 2x)", + "a88": " url(imgimg.09a1a1112c577c279435.png)", + "a89": " url(img\\\\'img.09a1a1112c577c279435.png)", + "a9": " green url(img.09a1a1112c577c279435.png) url(other-img.09a1a1112c577c279435.png) xyz", + "a90": " url(img\\\\'\\\\'\\\\'img.09a1a1112c577c279435.png)", + "a91": " url(img\\\\(img.09a1a1112c577c279435.png)", + "a92": " url(img\\\\)img.09a1a1112c577c279435.png)", + "a93": " url(img\\\\ img.09a1a1112c577c279435.png)", + "a94": " url(\\"img'() img.09a1a1112c577c279435.png\\")", + "a95": " image-set( + url(imgimg.09a1a1112c577c279435.png) 1x, + url(img\\\\'\\\\'\\\\'img.09a1a1112c577c279435.png) 2x, + url(img\\\\'img.09a1a1112c577c279435.png) 3x, + url(img\\\\(img.09a1a1112c577c279435.png) 4x, + url(img\\\\)img.09a1a1112c577c279435.png) 5x, + url(img\\\\ img.09a1a1112c577c279435.png) 6x, + url(\\"img'() img.09a1a1112c577c279435.png\\") 7x + )", + "a96": " url(img\\\\'\\\\'\\\\'img.09a1a1112c577c279435.png)", + "a97": " url(\\"img'() img.09a1a1112c577c279435.png\\")", + "a98": " url(img\\\\'img.09a1a1112c577c279435.png)", + "a99": " url(img\\\\(img.09a1a1112c577c279435.png)", + "b": " url(img.09a1a1112c577c279435.png)", + "c": " url(img.09a1a1112c577c279435.png)", + "d": " url(img.09a1a1112c577c279435.png#hash)", + "e": " url( + img.09a1a1112c577c279435.png + )", + "f": " green url( img.09a1a1112c577c279435.png ) xyz", + "g": " green url( img.09a1a1112c577c279435.png ) xyz", + "getPropertyValue": [Function], + "h": " green url(img.09a1a1112c577c279435.png) xyz", + "i": " green url(img.09a1a1112c577c279435.png) url(img.09a1a1112c577c279435.png) xyz", + "j": " green url( img\\\\ img.09a1a1112c577c279435.png ) xyz", + "k": " green url( img\\\\ img.09a1a1112c577c279435.png ) xyz", + "l": " green url(img.09a1a1112c577c279435.png) xyz", + "m": " green url(img.09a1a1112c577c279435.png) xyz", + "n": " green url(img.09a1a1112c577c279435.png) xyz", +} +`; + +exports[`ConfigTestCases css urls-css-filename exported tests should generate correct url public path with css filename 1`] = ` +Object { + "getPropertyValue": [Function], + "nested-dir": " url(../../bundle0/assets/img2.png)", + "nested-nested-dir": " url(../../bundle0/assets/img3.png)", + "same-dir": " url(../../bundle0/assets/img1.png)", +} +`; + +exports[`ConfigTestCases css urls-css-filename exported tests should generate correct url public path with css filename 2`] = ` +Object { + "getPropertyValue": [Function], + "nested-dir": " url(../../bundle0/assets/img3.png)", + "outer-dir": " url(../../bundle0/assets/img1.png)", + "same-dir": " url(../../bundle0/assets/img2.png)", +} +`; + +exports[`ConfigTestCases css urls-css-filename exported tests should generate correct url public path with css filename 3`] = ` +Object { + "getPropertyValue": [Function], + "outer-dir": " url(../../bundle0/assets/img2.png)", + "outer-outer-dir": " url(../../bundle0/assets/img1.png)", + "same-dir": " url(../../bundle0/assets/img3.png)", +} +`; + +exports[`ConfigTestCases css urls-css-filename exported tests should generate correct url public path with css filename 4`] = ` +Object { + "getPropertyValue": [Function], + "nested-dir": " url(https://test.cases/path/bundle1/assets/img2.png)", + "nested-nested-dir": " url(https://test.cases/path/bundle1/assets/img3.png)", + "same-dir": " url(https://test.cases/path/bundle1/assets/img1.png)", +} +`; + +exports[`ConfigTestCases css urls-css-filename exported tests should generate correct url public path with css filename 5`] = ` +Object { + "getPropertyValue": [Function], + "nested-dir": " url(https://test.cases/path/bundle1/assets/img3.png)", + "outer-dir": " url(https://test.cases/path/bundle1/assets/img1.png)", + "same-dir": " url(https://test.cases/path/bundle1/assets/img2.png)", +} +`; + +exports[`ConfigTestCases css urls-css-filename exported tests should generate correct url public path with css filename 6`] = ` +Object { + "getPropertyValue": [Function], + "outer-dir": " url(https://test.cases/path/bundle1/assets/img2.png)", + "outer-outer-dir": " url(https://test.cases/path/bundle1/assets/img1.png)", + "same-dir": " url(https://test.cases/path/bundle1/assets/img3.png)", +} +`; + +exports[`ConfigTestCases css urls-css-filename exported tests should generate correct url public path with css filename 7`] = ` +Object { + "getPropertyValue": [Function], + "nested-dir": " url(https://test.cases/path/bundle2/assets/img2.png)", + "nested-nested-dir": " url(https://test.cases/path/bundle2/assets/img3.png)", + "same-dir": " url(https://test.cases/path/bundle2/assets/img1.png)", +} +`; + +exports[`ConfigTestCases css urls-css-filename exported tests should generate correct url public path with css filename 8`] = ` +Object { + "getPropertyValue": [Function], + "nested-dir": " url(https://test.cases/path/bundle2/assets/img3.png)", + "outer-dir": " url(https://test.cases/path/bundle2/assets/img1.png)", + "same-dir": " url(https://test.cases/path/bundle2/assets/img2.png)", +} +`; + +exports[`ConfigTestCases css urls-css-filename exported tests should generate correct url public path with css filename 9`] = ` +Object { + "getPropertyValue": [Function], + "outer-dir": " url(https://test.cases/path/bundle2/assets/img2.png)", + "outer-outer-dir": " url(https://test.cases/path/bundle2/assets/img1.png)", + "same-dir": " url(https://test.cases/path/bundle2/assets/img3.png)", +} +`; diff --git a/test/__snapshots__/ConfigTestCases.test.js.snap b/test/__snapshots__/ConfigTestCases.test.js.snap deleted file mode 100644 index 214d4778243..00000000000 --- a/test/__snapshots__/ConfigTestCases.test.js.snap +++ /dev/null @@ -1,78 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`ConfigTestCases custom-modules json-custom exported tests should transform toml to json 1`] = ` -Object { - "owner": Object { - "bio": "GitHub Cofounder & CEO -Likes tater tots and beer.", - "dob": "1979-05-27T07:32:00.000Z", - "name": "Tom Preston-Werner", - "organization": "GitHub", - }, - "title": "TOML Example", -} -`; - -exports[`ConfigTestCases records issue-2991 exported tests should write relative paths to records 1`] = ` -"{ - \\"chunks\\": { - \\"byName\\": { - \\"main\\": 179 - }, - \\"bySource\\": { - \\"0 main\\": 179 - }, - \\"usedIds\\": [ - 179 - ] - }, - \\"modules\\": { - \\"byIdentifier\\": { - \\"./test.js\\": 393, - \\"external \\\\\\"fs\\\\\\"\\": 747, - \\"external \\\\\\"path\\\\\\"\\": 622, - \\"ignored|./|pkgs/somepackage/foo\\": 907 - }, - \\"usedIds\\": [ - 393, - 622, - 747, - 907 - ] - } -}" -`; - -exports[`ConfigTestCases records issue-7339 exported tests should write relative dynamic-require paths to records 1`] = ` -"{ - \\"chunks\\": { - \\"byName\\": { - \\"main\\": 179 - }, - \\"bySource\\": { - \\"0 main\\": 179 - }, - \\"usedIds\\": [ - 179 - ] - }, - \\"modules\\": { - \\"byIdentifier\\": { - \\"./dependencies/bar.js\\": 379, - \\"./dependencies/foo.js\\": 117, - \\"./dependencies|sync|/^\\\\\\\\.\\\\\\\\/.*$/\\": 412, - \\"./test.js\\": 393, - \\"external \\\\\\"fs\\\\\\"\\": 747, - \\"external \\\\\\"path\\\\\\"\\": 622 - }, - \\"usedIds\\": [ - 117, - 379, - 393, - 412, - 622, - 747 - ] - } -}" -`; diff --git a/test/__snapshots__/StatsTestCases.basictest.js.snap b/test/__snapshots__/StatsTestCases.basictest.js.snap new file mode 100644 index 00000000000..70e128f6ceb --- /dev/null +++ b/test/__snapshots__/StatsTestCases.basictest.js.snap @@ -0,0 +1,4834 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`StatsTestCases should print correct stats for aggressive-splitting-entry 1`] = ` +"fitting: + PublicPath: auto + asset fitting-XXXXXXXXXXXXXXXXXXXX.js X KiB [emitted] [immutable] + asset fitting-XXXXXXXXXXXXXXXXXXXX.js X KiB [emitted] [immutable] + asset fitting-XXXXXXXXXXXXXXXXXXXX.js X KiB [emitted] [immutable] + asset fitting-XXXXXXXXXXXXXXXXXXXX.js X KiB [emitted] [immutable] + Entrypoint main X KiB = fitting-XXXXXXXXXXXXXXXXXXXX.js X KiB fitting-XXXXXXXXXXXXXXXXXXXX.js X KiB fitting-XXXXXXXXXXXXXXXXXXXX.js X KiB + chunk (runtime: main) fitting-XXXXXXXXXXXXXXXXXXXX.js X KiB [initial] [rendered] [recorded] aggressive splitted + > ./index main + ./a.js X bytes [built] [code generated] + ./b.js X bytes [built] [code generated] + chunk (runtime: main) fitting-XXXXXXXXXXXXXXXXXXXX.js X KiB (javascript) X KiB (runtime) [entry] [rendered] + > ./index main + runtime modules X KiB 11 modules + cacheable modules X KiB + ./e.js X bytes [dependent] [built] [code generated] + ./f.js X bytes [dependent] [built] [code generated] + ./index.js X bytes [built] [code generated] + chunk (runtime: main) fitting-XXXXXXXXXXXXXXXXXXXX.js X KiB [initial] [rendered] [recorded] aggressive splitted + > ./index main + ./c.js X bytes [built] [code generated] + ./d.js X bytes [built] [code generated] + chunk (runtime: main) fitting-XXXXXXXXXXXXXXXXXXXX.js X bytes [rendered] + > ./g ./index.js 7:0-13 + ./g.js X bytes [built] [code generated] + fitting (webpack x.x.x) compiled successfully in X ms + +content-change: + PublicPath: auto + asset content-changX-XXXXXXXXXXXXXXXXXXXX.js X KiB [emitted] [immutable] + asset content-changX-XXXXXXXXXXXXXXXXXXXX.js X KiB [emitted] [immutable] + asset content-changX-XXXXXXXXXXXXXXXXXXXX.js X KiB [emitted] [immutable] + asset content-changX-XXXXXXXXXXXXXXXXXXXX.js X KiB [emitted] [immutable] + Entrypoint main X KiB = content-changX-XXXXXXXXXXXXXXXXXXXX.js X KiB content-changX-XXXXXXXXXXXXXXXXXXXX.js X KiB content-changX-XXXXXXXXXXXXXXXXXXXX.js X KiB + chunk (runtime: main) content-changX-XXXXXXXXXXXXXXXXXXXX.js X KiB [initial] [rendered] [recorded] aggressive splitted + > ./index main + ./a.js X bytes [built] [code generated] + ./b.js X bytes [built] [code generated] + chunk (runtime: main) content-changX-XXXXXXXXXXXXXXXXXXXX.js X KiB (javascript) X KiB (runtime) [entry] [rendered] + > ./index main + runtime modules X KiB 11 modules + cacheable modules X KiB + ./e.js X bytes [dependent] [built] [code generated] + ./f.js X bytes [dependent] [built] [code generated] + ./index.js X bytes [built] [code generated] + chunk (runtime: main) content-changX-XXXXXXXXXXXXXXXXXXXX.js X KiB [initial] [rendered] [recorded] aggressive splitted + > ./index main + ./c.js X bytes [built] [code generated] + ./d.js X bytes [built] [code generated] + chunk (runtime: main) content-changX-XXXXXXXXXXXXXXXXXXXX.js X bytes [rendered] + > ./g ./index.js 7:0-13 + ./g.js X bytes [built] [code generated] + content-change (webpack x.x.x) compiled successfully in X ms" +`; + +exports[`StatsTestCases should print correct stats for aggressive-splitting-on-demand 1`] = ` +"PublicPath: auto +asset XXXXXXXXXXXXXXXXXXXX.js X KiB [emitted] [immutable] (name: main) +asset XXXXXXXXXXXXXXXXXXXX.js X KiB [emitted] [immutable] +asset XXXXXXXXXXXXXXXXXXXX.js X KiB [emitted] [immutable] +asset XXXXXXXXXXXXXXXXXXXX.js X KiB [emitted] [immutable] +asset XXXXXXXXXXXXXXXXXXXX.js X KiB [emitted] [immutable] +asset XXXXXXXXXXXXXXXXXXXX.js X KiB [emitted] [immutable] +asset XXXXXXXXXXXXXXXXXXXX.js X KiB [emitted] [immutable] +asset XXXXXXXXXXXXXXXXXXXX.js X KiB [emitted] [immutable] +asset XXXXXXXXXXXXXXXXXXXX.js X KiB [emitted] [immutable] +asset XXXXXXXXXXXXXXXXXXXX.js X bytes [emitted] [immutable] +asset XXXXXXXXXXXXXXXXXXXX.js X bytes [emitted] [immutable] +asset XXXXXXXXXXXXXXXXXXXX.js X bytes [emitted] [immutable] +Entrypoint main X KiB = XXXXXXXXXXXXXXXXXXXX.js +chunk (runtime: main) XXXXXXXXXXXXXXXXXXXX.js X bytes [rendered] + > ./c ./d ./e ./index.js 3:0-30 + > ./b ./d ./e ./f ./g ./index.js 5:0-44 + ./e.js X bytes [built] [code generated] +chunk (runtime: main) XXXXXXXXXXXXXXXXXXXX.js X KiB [rendered] + > ./b ./c ./index.js 2:0-23 + ./b.js X bytes [built] [code generated] + ./c.js X bytes [built] [code generated] +chunk (runtime: main) XXXXXXXXXXXXXXXXXXXX.js X KiB [rendered] [recorded] aggressive splitted + > ./c ./d ./e ./index.js 3:0-30 + ./c.js X bytes [built] [code generated] + ./d.js X bytes [built] [code generated] +chunk (runtime: main) XXXXXXXXXXXXXXXXXXXX.js X bytes [rendered] + > ./b ./d ./e ./f ./g ./h ./i ./j ./k ./index.js 6:0-72 + ./k.js X bytes [built] [code generated] +chunk (runtime: main) XXXXXXXXXXXXXXXXXXXX.js X KiB [rendered] [recorded] aggressive splitted + > ./f ./g ./h ./i ./j ./k ./index.js 4:0-51 + ./h.js X bytes [built] [code generated] + ./i.js X bytes [built] [code generated] +chunk (runtime: main) XXXXXXXXXXXXXXXXXXXX.js X KiB [rendered] [recorded] aggressive splitted + > ./b ./d ./e ./f ./g ./h ./i ./j ./k ./index.js 6:0-72 + ./i.js X bytes [built] [code generated] + ./j.js X bytes [built] [code generated] +chunk (runtime: main) XXXXXXXXXXXXXXXXXXXX.js X KiB [rendered] + > ./f ./g ./h ./i ./j ./k ./index.js 4:0-51 + ./j.js X bytes [built] [code generated] + ./k.js X bytes [built] [code generated] +chunk (runtime: main) XXXXXXXXXXXXXXXXXXXX.js X bytes [rendered] + > ./a ./index.js 1:0-16 + ./a.js X bytes [built] [code generated] +chunk (runtime: main) XXXXXXXXXXXXXXXXXXXX.js X KiB [rendered] [recorded] aggressive splitted + > ./b ./d ./e ./f ./g ./h ./i ./j ./k ./index.js 6:0-72 + ./e.js X bytes [built] [code generated] + ./h.js X bytes [built] [code generated] +chunk (runtime: main) XXXXXXXXXXXXXXXXXXXX.js X KiB [rendered] [recorded] aggressive splitted + > ./b ./d ./e ./f ./g ./index.js 5:0-44 + > ./b ./d ./e ./f ./g ./h ./i ./j ./k ./index.js 6:0-72 + ./b.js X bytes [built] [code generated] + ./d.js X bytes [built] [code generated] +chunk (runtime: main) XXXXXXXXXXXXXXXXXXXX.js (main) X bytes (javascript) X KiB (runtime) [entry] [rendered] + > ./index main + runtime modules X KiB 7 modules + ./index.js X bytes [built] [code generated] +chunk (runtime: main) XXXXXXXXXXXXXXXXXXXX.js X KiB [rendered] [recorded] aggressive splitted + > ./f ./g ./h ./i ./j ./k ./index.js 4:0-51 + > ./b ./d ./e ./f ./g ./index.js 5:0-44 + > ./b ./d ./e ./f ./g ./h ./i ./j ./k ./index.js 6:0-72 + ./f.js X bytes [built] [code generated] + ./g.js X bytes [built] [code generated] +webpack x.x.x compiled successfully in X ms" +`; + +exports[`StatsTestCases should print correct stats for all-stats 1`] = ` +"PublicPath: auto +asset bundle.js X KiB {main} [emitted] (name: main) +Entrypoint main X KiB = bundle.js +chunk {main} (runtime: main) bundle.js (main) X bytes (javascript) X bytes (runtime) [entry] [rendered] + > ./index.js main + ./index.js X bytes {main} [depth 0] [built] [code generated] + [no exports] + [used exports unknown] + entry ./index.js main + data:text/plain;base64,szsaAAdsadasdfaf.. X bytes {main} [depth 1] [dependent] [built] [code generated] + [no exports] + [used exports unknown] + harmony side effect evaluation data:text/plain;base64,szsaAAdsadasdfaf.. [./index.js] 1:0-81 + webpack/runtime/make namespace object X bytes {main} [code generated] + [no exports] + [used exports unknown] +./index.js X bytes {main} [depth 0] [built] [code generated] + [no exports] + [used exports unknown] + entry ./index.js main +data:text/plain;base64,szsaAAdsadasdfaf.. X bytes {main} [depth 1] [built] [code generated] + [no exports] + [used exports unknown] + harmony side effect evaluation data:text/plain;base64,szsaAAdsadasdfaf.. [./index.js] 1:0-81 +webpack/runtime/make namespace object X bytes {main} [code generated] + [no exports] + [used exports unknown] + +1970-04-20 12:42:42: webpack x.x.x compiled successfully in X ms (XXXXXXXXXXXXXXXXXXXX)" +`; + +exports[`StatsTestCases should print correct stats for asset 1`] = ` +"asset XXXXXXXXXXXXXXXXXXXX.png X KiB [emitted] [immutable] [from: images/file.png] (auxiliary name: main) +asset bundle.js X KiB [emitted] (name: main) +asset static/file.html X bytes [emitted] [from: static/file.html] (auxiliary name: main) +runtime modules X KiB 2 modules +modules by path ./ X KiB (javascript) X KiB (asset) + modules by path ./images/ X KiB (javascript) X KiB (asset) + ./images/file.png X bytes (javascript) X KiB (asset) [built] [code generated] + ./images/file.svg X bytes [built] [code generated] + ./images/file.jpg X KiB [built] [code generated] + modules by path ./*.js X bytes + ./index.js X bytes [built] [code generated] + ./a.source.js X bytes [built] [code generated] + ./static/file.html X bytes (javascript) X bytes (asset) [built] [code generated] + ./a.css X bytes [built] [code generated] +modules by mime type text/plain X bytes + data:text/plain;base64,szsaAAdsadasdfaf.. X bytes [built] [code generated] + data:text/plain,asd= X bytes [built] [code generated] + data:text/plain,XXXXXXXXXXXXXXX.. X bytes [built] [code generated] +webpack x.x.x compiled successfully in X ms" +`; + +exports[`StatsTestCases should print correct stats for asset-concat 1`] = ` +"asset XXXXXXXXXXXXXXXXXXXX.png X KiB [emitted] [immutable] [from: images/file.png] (auxiliary name: main) +asset bundle.js X KiB [emitted] (name: main) +asset static/file.html X bytes [emitted] [from: static/file.html] (auxiliary name: main) +orphan modules X KiB [orphan] 7 modules +runtime modules X KiB 2 modules +cacheable modules X KiB (javascript) X KiB (asset) + ./index.js + 9 modules X KiB [built] [code generated] + ./images/file.png X bytes (javascript) X KiB (asset) [built] [code generated] + ./static/file.html X bytes (javascript) X bytes (asset) [built] [code generated] +webpack x.x.x compiled successfully in X ms" +`; + +exports[`StatsTestCases should print correct stats for async-commons-chunk 1`] = ` +"chunk (runtime: main) 670.js X bytes <{792}> ={899}= ={964}= [rendered] reused as split chunk (cache group: default) + > ./index.js 17:1-21:3 + > ./index.js 2:1-5:3 + > ./a ./b ./index.js 9:1-13:3 + ./a.js X bytes [built] [code generated] +chunk (runtime: main) main.js (main) X bytes (javascript) X KiB (runtime) >{670}< >{899}< >{964}< [entry] [rendered] + > ./ main + runtime modules X KiB 7 modules + ./index.js X bytes [built] [code generated] +chunk (runtime: main) 899.js X bytes <{792}> ={670}= [rendered] + > ./a ./b ./index.js 9:1-13:3 + ./b.js X bytes [built] [code generated] +chunk (runtime: main) 964.js X bytes <{792}> ={670}= [rendered] + > ./index.js 17:1-21:3 + ./c.js X bytes [built] [code generated] +webpack x.x.x compiled successfully" +`; + +exports[`StatsTestCases should print correct stats for async-commons-chunk-auto 1`] = ` +"disabled: + chunk (runtime: a, main) disabled/async-g.js (async-g) X bytes [rendered] + > ./g ./a.js 6:0-47 + dependent modules X bytes [dependent] 1 module + ./g.js X bytes [built] [code generated] + chunk (runtime: main) disabled/async-b.js (async-b) X bytes [rendered] + > ./b ./index.js 2:0-47 + dependent modules X bytes [dependent] 4 modules + ./b.js X bytes [built] [code generated] + chunk (runtime: b) disabled/b.js (b) X bytes (javascript) X bytes (runtime) [entry] [rendered] + > ./b b + dependent modules X bytes [dependent] 4 modules + runtime modules X bytes 2 modules + ./b.js X bytes [built] [code generated] + chunk (runtime: main) disabled/async-a.js (async-a) X bytes [rendered] + > ./a ./index.js 1:0-47 + dependent modules X bytes [dependent] 3 modules + ./a.js + 1 modules X bytes [built] [code generated] + chunk (runtime: c) disabled/c.js (c) X bytes (javascript) X bytes (runtime) [entry] [rendered] + > ./c c + dependent modules X bytes [dependent] 3 modules + runtime modules X bytes 2 modules + ./c.js + 1 modules X bytes [built] [code generated] + chunk (runtime: main) disabled/main.js (main) X bytes (javascript) X KiB (runtime) [entry] [rendered] + > ./ main + runtime modules X KiB 9 modules + ./index.js X bytes [built] [code generated] + chunk (runtime: main) disabled/async-c.js (async-c) X bytes [rendered] + > ./c ./index.js 3:0-47 + dependent modules X bytes [dependent] 3 modules + ./c.js + 1 modules X bytes [built] [code generated] + chunk (runtime: a) disabled/a.js (a) X bytes (javascript) X KiB (runtime) [entry] [rendered] + > ./a a + runtime modules X KiB 9 modules + dependent modules X bytes [dependent] 3 modules + ./a.js + 1 modules X bytes [built] [code generated] + disabled (webpack x.x.x) compiled successfully + +default: + chunk (runtime: a, main) default/async-g.js (async-g) X bytes [rendered] + > ./g ./a.js 6:0-47 + ./g.js X bytes [built] [code generated] + chunk (runtime: main) default/async-b.js (async-b) X bytes [rendered] + > ./b ./index.js 2:0-47 + ./b.js X bytes [built] [code generated] + chunk (runtime: b) default/b.js (b) X bytes (javascript) X bytes (runtime) [entry] [rendered] + > ./b b + dependent modules X bytes [dependent] 4 modules + runtime modules X bytes 2 modules + ./b.js X bytes [built] [code generated] + chunk (runtime: main) default/async-a.js (async-a) X bytes [rendered] + > ./a ./index.js 1:0-47 + ./a.js + 1 modules X bytes [built] [code generated] + chunk (runtime: c) default/c.js (c) X bytes (javascript) X bytes (runtime) [entry] [rendered] + > ./c c + dependent modules X bytes [dependent] 4 modules + runtime modules X bytes 2 modules + ./c.js X bytes [built] [code generated] + chunk (runtime: main) default/425.js X bytes [rendered] split chunk (cache group: default) + > ./a ./index.js 1:0-47 + > ./b ./index.js 2:0-47 + > ./c ./index.js 3:0-47 + ./d.js X bytes [built] [code generated] + chunk (runtime: main) default/628.js (id hint: vendors) X bytes [rendered] split chunk (cache group: defaultVendors) + > ./a ./index.js 1:0-47 + > ./b ./index.js 2:0-47 + > ./c ./index.js 3:0-47 + ./node_modules/x.js X bytes [built] [code generated] + chunk (runtime: main) default/723.js (id hint: vendors) X bytes [rendered] split chunk (cache group: defaultVendors) + > ./a ./index.js 1:0-47 + > ./b ./index.js 2:0-47 + ./node_modules/y.js X bytes [built] [code generated] + chunk (runtime: main) default/main.js (main) X bytes (javascript) X KiB (runtime) [entry] [rendered] + > ./ main + runtime modules X KiB 9 modules + ./index.js X bytes [built] [code generated] + chunk (runtime: main) default/862.js (id hint: vendors) X bytes [rendered] split chunk (cache group: defaultVendors) + > ./c ./index.js 3:0-47 + ./node_modules/z.js X bytes [built] [code generated] + chunk (runtime: main) default/async-c.js (async-c) X bytes [rendered] + > ./c ./index.js 3:0-47 + ./c.js X bytes [built] [code generated] + chunk (runtime: a, main) default/935.js X bytes [rendered] split chunk (cache group: default) + > ./b ./index.js 2:0-47 + > ./c ./index.js 3:0-47 + > ./g ./a.js 6:0-47 + ./f.js X bytes [built] [code generated] + chunk (runtime: a) default/a.js (a) X bytes (javascript) X KiB (runtime) [entry] [rendered] + > ./a a + runtime modules X KiB 9 modules + dependent modules X bytes [dependent] 3 modules + ./a.js + 1 modules X bytes [built] [code generated] + default (webpack x.x.x) compiled successfully + +vendors: + Entrypoint main X KiB = vendors/main.js + Entrypoint a X KiB = vendors/vendors.js X KiB vendors/a.js X KiB + Entrypoint b X KiB = vendors/vendors.js X KiB vendors/b.js X KiB + Entrypoint c X KiB = vendors/vendors.js X KiB vendors/c.js X KiB + chunk (runtime: a, main) vendors/async-g.js (async-g) X bytes [rendered] + > ./g ./a.js 6:0-47 + dependent modules X bytes [dependent] 1 module + ./g.js X bytes [built] [code generated] + chunk (runtime: main) vendors/async-b.js (async-b) X bytes [rendered] + > ./b ./index.js 2:0-47 + dependent modules X bytes [dependent] 4 modules + ./b.js X bytes [built] [code generated] + chunk (runtime: a, b, c) vendors/vendors.js (vendors) (id hint: vendors) X bytes [initial] [rendered] split chunk (cache group: vendors) (name: vendors) + > ./a a + > ./b b + > ./c c + ./node_modules/x.js X bytes [built] [code generated] + ./node_modules/y.js X bytes [built] [code generated] + ./node_modules/z.js X bytes [built] [code generated] + chunk (runtime: b) vendors/b.js (b) X bytes (javascript) X KiB (runtime) [entry] [rendered] + > ./b b + runtime modules X KiB 4 modules + dependent modules X bytes [dependent] 2 modules + ./b.js X bytes [built] [code generated] + chunk (runtime: main) vendors/async-a.js (async-a) X bytes [rendered] + > ./a ./index.js 1:0-47 + dependent modules X bytes [dependent] 3 modules + ./a.js + 1 modules X bytes [built] [code generated] + chunk (runtime: c) vendors/c.js (c) X bytes (javascript) X KiB (runtime) [entry] [rendered] + > ./c c + runtime modules X KiB 4 modules + dependent modules X bytes [dependent] 2 modules + ./c.js X bytes [built] [code generated] + chunk (runtime: main) vendors/main.js (main) X bytes (javascript) X KiB (runtime) [entry] [rendered] + > ./ main + runtime modules X KiB 9 modules + ./index.js X bytes [built] [code generated] + chunk (runtime: main) vendors/async-c.js (async-c) X bytes [rendered] + > ./c ./index.js 3:0-47 + dependent modules X bytes [dependent] 4 modules + ./c.js X bytes [built] [code generated] + chunk (runtime: a) vendors/a.js (a) X bytes (javascript) X KiB (runtime) [entry] [rendered] + > ./a a + runtime modules X KiB 10 modules + dependent modules X bytes [dependent] 1 module + ./a.js + 1 modules X bytes [built] [code generated] + vendors (webpack x.x.x) compiled successfully + +multiple-vendors: + Entrypoint main X KiB = multiple-vendors/main.js + Entrypoint a X KiB = multiple-vendors/libs-x.js X bytes multiple-vendors/723.js X bytes multiple-vendors/425.js X bytes multiple-vendors/210.js X bytes multiple-vendors/a.js X KiB + Entrypoint b X KiB = multiple-vendors/libs-x.js X bytes multiple-vendors/723.js X bytes multiple-vendors/425.js X bytes multiple-vendors/935.js X bytes multiple-vendors/b.js X KiB + Entrypoint c X KiB = multiple-vendors/libs-x.js X bytes multiple-vendors/862.js X bytes multiple-vendors/425.js X bytes multiple-vendors/935.js X bytes multiple-vendors/c.js X KiB + chunk (runtime: a, main) multiple-vendors/async-g.js (async-g) X bytes [rendered] + > ./g ./a.js 6:0-47 + ./g.js X bytes [built] [code generated] + chunk (runtime: main) multiple-vendors/async-b.js (async-b) X bytes [rendered] + > ./b ./index.js 2:0-47 + ./b.js X bytes [built] [code generated] + chunk (runtime: b) multiple-vendors/b.js (b) X bytes (javascript) X KiB (runtime) [entry] [rendered] + > ./b b + runtime modules X KiB 4 modules + ./b.js X bytes [built] [code generated] + chunk (runtime: a, main) multiple-vendors/210.js X bytes [initial] [rendered] split chunk (cache group: default) + > ./a ./index.js 1:0-47 + > ./a a + ./e.js X bytes [built] [code generated] + chunk (runtime: main) multiple-vendors/async-a.js (async-a) X bytes [rendered] + > ./a ./index.js 1:0-47 + ./a.js X bytes [built] [code generated] + chunk (runtime: c) multiple-vendors/c.js (c) X bytes (javascript) X KiB (runtime) [entry] [rendered] + > ./c c + runtime modules X KiB 4 modules + ./c.js X bytes [built] [code generated] + chunk (runtime: a, b, c, main) multiple-vendors/libs-x.js (libs-x) (id hint: libs) X bytes [initial] [rendered] split chunk (cache group: libs) (name: libs-x) + > ./a ./index.js 1:0-47 + > ./b ./index.js 2:0-47 + > ./c ./index.js 3:0-47 + > ./a a + > ./b b + > ./c c + ./node_modules/x.js X bytes [built] [code generated] + chunk (runtime: a, b, c, main) multiple-vendors/425.js X bytes [initial] [rendered] split chunk (cache group: default) + > ./a ./index.js 1:0-47 + > ./b ./index.js 2:0-47 + > ./c ./index.js 3:0-47 + > ./a a + > ./b b + > ./c c + ./d.js X bytes [built] [code generated] + chunk (runtime: a, b, main) multiple-vendors/723.js (id hint: vendors) X bytes [initial] [rendered] split chunk (cache group: vendors) + > ./a ./index.js 1:0-47 + > ./b ./index.js 2:0-47 + > ./a a + > ./b b + ./node_modules/y.js X bytes [built] [code generated] + chunk (runtime: main) multiple-vendors/main.js (main) X bytes (javascript) X KiB (runtime) [entry] [rendered] + > ./ main + runtime modules X KiB 9 modules + ./index.js X bytes [built] [code generated] + chunk (runtime: c, main) multiple-vendors/862.js (id hint: vendors) X bytes [initial] [rendered] split chunk (cache group: vendors) + > ./c ./index.js 3:0-47 + > ./c c + ./node_modules/z.js X bytes [built] [code generated] + chunk (runtime: main) multiple-vendors/async-c.js (async-c) X bytes [rendered] + > ./c ./index.js 3:0-47 + ./c.js X bytes [built] [code generated] + chunk (runtime: a, b, c, main) multiple-vendors/935.js X bytes [initial] [rendered] split chunk (cache group: default) + > ./b ./index.js 2:0-47 + > ./c ./index.js 3:0-47 + > ./g ./a.js 6:0-47 + > ./b b + > ./c c + ./f.js X bytes [built] [code generated] + chunk (runtime: a) multiple-vendors/a.js (a) X bytes (javascript) X KiB (runtime) [entry] [rendered] + > ./a a + runtime modules X KiB 10 modules + ./a.js X bytes [built] [code generated] + multiple-vendors (webpack x.x.x) compiled successfully + +all: + Entrypoint main X KiB = all/main.js + Entrypoint a X KiB = all/628.js X bytes all/723.js X bytes all/425.js X bytes all/210.js X bytes all/a.js X KiB + Entrypoint b X KiB = all/628.js X bytes all/723.js X bytes all/425.js X bytes all/935.js X bytes all/b.js X KiB + Entrypoint c X KiB = all/628.js X bytes all/862.js X bytes all/425.js X bytes all/935.js X bytes all/c.js X KiB + chunk (runtime: a, main) all/async-g.js (async-g) X bytes [rendered] + > ./g ./a.js 6:0-47 + ./g.js X bytes [built] [code generated] + chunk (runtime: main) all/async-b.js (async-b) X bytes [rendered] + > ./b ./index.js 2:0-47 + ./b.js X bytes [built] [code generated] + chunk (runtime: b) all/b.js (b) X bytes (javascript) X KiB (runtime) [entry] [rendered] + > ./b b + runtime modules X KiB 4 modules + ./b.js X bytes [built] [code generated] + chunk (runtime: a, main) all/210.js X bytes [initial] [rendered] split chunk (cache group: default) + > ./a ./index.js 1:0-47 + > ./a a + ./e.js X bytes [built] [code generated] + chunk (runtime: main) all/async-a.js (async-a) X bytes [rendered] + > ./a ./index.js 1:0-47 + ./a.js X bytes [built] [code generated] + chunk (runtime: c) all/c.js (c) X bytes (javascript) X KiB (runtime) [entry] [rendered] + > ./c c + runtime modules X KiB 4 modules + ./c.js X bytes [built] [code generated] + chunk (runtime: a, b, c, main) all/425.js X bytes [initial] [rendered] split chunk (cache group: default) + > ./a ./index.js 1:0-47 + > ./b ./index.js 2:0-47 + > ./c ./index.js 3:0-47 + > ./a a + > ./b b + > ./c c + ./d.js X bytes [built] [code generated] + chunk (runtime: a, b, c, main) all/628.js (id hint: vendors) X bytes [initial] [rendered] split chunk (cache group: vendors) + > ./a ./index.js 1:0-47 + > ./b ./index.js 2:0-47 + > ./c ./index.js 3:0-47 + > ./a a + > ./b b + > ./c c + ./node_modules/x.js X bytes [built] [code generated] + chunk (runtime: a, b, main) all/723.js (id hint: vendors) X bytes [initial] [rendered] split chunk (cache group: vendors) + > ./a ./index.js 1:0-47 + > ./b ./index.js 2:0-47 + > ./a a + > ./b b + ./node_modules/y.js X bytes [built] [code generated] + chunk (runtime: main) all/main.js (main) X bytes (javascript) X KiB (runtime) [entry] [rendered] + > ./ main + runtime modules X KiB 9 modules + ./index.js X bytes [built] [code generated] + chunk (runtime: c, main) all/862.js (id hint: vendors) X bytes [initial] [rendered] split chunk (cache group: vendors) + > ./c ./index.js 3:0-47 + > ./c c + ./node_modules/z.js X bytes [built] [code generated] + chunk (runtime: main) all/async-c.js (async-c) X bytes [rendered] + > ./c ./index.js 3:0-47 + ./c.js X bytes [built] [code generated] + chunk (runtime: a, b, c, main) all/935.js X bytes [initial] [rendered] split chunk (cache group: default) + > ./b ./index.js 2:0-47 + > ./c ./index.js 3:0-47 + > ./g ./a.js 6:0-47 + > ./b b + > ./c c + ./f.js X bytes [built] [code generated] + chunk (runtime: a) all/a.js (a) X bytes (javascript) X KiB (runtime) [entry] [rendered] + > ./a a + runtime modules X KiB 10 modules + ./a.js X bytes [built] [code generated] + all (webpack x.x.x) compiled successfully" +`; + +exports[`StatsTestCases should print correct stats for child-compiler-apply-entry-option 1`] = ` +"asset child.js X bytes [emitted] +asset parent.js X bytes [emitted] (name: parent) +Entrypoint parent X bytes = parent.js +./parent.js X bytes [built] [code generated] + assets by status X bytes [cached] 1 asset + Entrypoint child = child.js + ./child.js X bytes [built] [code generated] + + Child TestApplyEntryOptionPlugin compiled successfully + +WARNING in configuration +The 'mode' option has not been set, webpack will fallback to 'production' for this value. +Set 'mode' option to 'development' or 'production' to enable defaults for each environment. +You can also set it to 'none' to disable any default behavior. Learn more: https://webpack.js.org/configuration/mode/ + +webpack x.x.x compiled with 1 warning in X ms" +`; + +exports[`StatsTestCases should print correct stats for chunk-module-id-range 1`] = ` +"PublicPath: auto +asset main1.js X KiB [emitted] (name: main1) +asset main2.js X KiB [emitted] (name: main2) +Entrypoint main1 X KiB = main1.js +Entrypoint main2 X KiB = main2.js +chunk (runtime: main1) main1.js (main1) X bytes (javascript) X bytes (runtime) [entry] [rendered] + > ./main1 main1 + runtime modules X bytes 3 modules + cacheable modules X bytes + ./a.js X bytes [dependent] [built] [code generated] + ./b.js X bytes [dependent] [built] [code generated] + ./c.js X bytes [dependent] [built] [code generated] + ./d.js X bytes [dependent] [built] [code generated] + ./main1.js X bytes [built] [code generated] +chunk (runtime: main2) main2.js (main2) X bytes (javascript) X bytes (runtime) [entry] [rendered] + > ./main2 main2 + runtime modules X bytes 3 modules + cacheable modules X bytes + ./a.js X bytes [dependent] [built] [code generated] + ./d.js X bytes [dependent] [built] [code generated] + ./e.js X bytes [dependent] [built] [code generated] + ./f.js X bytes [dependent] [built] [code generated] + ./main2.js X bytes [built] [code generated] +webpack x.x.x compiled successfully in X ms" +`; + +exports[`StatsTestCases should print correct stats for chunks 1`] = ` +"PublicPath: auto +asset bundle.js X KiB [emitted] (name: main) +asset 964.bundle.js X bytes [emitted] +asset 226.bundle.js X bytes [emitted] +asset 899.bundle.js X bytes [emitted] +chunk (runtime: main) 226.bundle.js X bytes <{964}> [rendered] + > ./c.js 1:0-52 + ./d.js X bytes [built] [code generated] + require.ensure item ./d ./c.js 1:0-52 + cjs self exports reference ./d.js 1:0-14 + X ms -> X ms -> + X ms (resolving: X ms, restoring: X ms, integration: X ms, building: X ms, storing: X ms) + ./e.js X bytes [built] [code generated] + require.ensure item ./e ./c.js 1:0-52 + cjs self exports reference ./e.js 1:0-14 + X ms -> X ms -> + X ms (resolving: X ms, restoring: X ms, integration: X ms, building: X ms, storing: X ms) +chunk (runtime: main) bundle.js (main) X bytes (javascript) X KiB (runtime) >{899}< >{964}< [entry] [rendered] + > ./index main + runtime modules X KiB 7 modules + cacheable modules X bytes + ./a.js X bytes [dependent] [built] [code generated] + cjs self exports reference ./a.js 1:0-14 + cjs require ./a ./index.js 1:0-14 + X ms -> + X ms (resolving: X ms, restoring: X ms, integration: X ms, building: X ms, storing: X ms) + ./index.js X bytes [built] [code generated] + entry ./index main + X ms (resolving: X ms, restoring: X ms, integration: X ms, building: X ms, storing: X ms) +chunk (runtime: main) 899.bundle.js X bytes <{792}> [rendered] + > ./b ./index.js 2:0-16 + ./b.js X bytes [built] [code generated] + cjs self exports reference ./b.js 1:0-14 + amd require ./b ./index.js 2:0-16 + X ms -> + X ms (resolving: X ms, restoring: X ms, integration: X ms, building: X ms, storing: X ms) +chunk (runtime: main) 964.bundle.js X bytes <{792}> >{226}< [rendered] + > ./c ./index.js 3:0-16 + ./c.js X bytes [built] [code generated] + amd require ./c ./index.js 3:0-16 + X ms -> + X ms (resolving: X ms, restoring: X ms, integration: X ms, building: X ms, storing: X ms) +webpack x.x.x compiled successfully in X ms" +`; + +exports[`StatsTestCases should print correct stats for chunks-development 1`] = ` +"PublicPath: auto +asset bundle.js X KiB [emitted] (name: main) +asset d_js-e_js.bundle.js X KiB [emitted] +asset c_js.bundle.js X bytes [emitted] +asset b_js.bundle.js X bytes [emitted] +chunk (runtime: main) b_js.bundle.js X bytes <{main}> [rendered] + > ./b ./index.js 2:0-16 + ./b.js X bytes [built] [code generated] + cjs self exports reference ./b.js 1:0-14 + amd require ./b ./index.js 2:0-16 + X ms -> + X ms (resolving: X ms, restoring: X ms, integration: X ms, building: X ms, storing: X ms) +chunk (runtime: main) c_js.bundle.js X bytes <{main}> >{d_js-e_js}< [rendered] + > ./c ./index.js 3:0-16 + ./c.js X bytes [built] [code generated] + amd require ./c ./index.js 3:0-16 + X ms -> + X ms (resolving: X ms, restoring: X ms, integration: X ms, building: X ms, storing: X ms) +chunk (runtime: main) d_js-e_js.bundle.js X bytes <{c_js}> [rendered] + > ./c.js 1:0-52 + ./d.js X bytes [built] [code generated] + require.ensure item ./d ./c.js 1:0-52 + cjs self exports reference ./d.js 1:0-14 + X ms -> X ms -> + X ms (resolving: X ms, restoring: X ms, integration: X ms, building: X ms, storing: X ms) + ./e.js X bytes [built] [code generated] + require.ensure item ./e ./c.js 1:0-52 + cjs self exports reference ./e.js 2:0-14 + X ms -> X ms -> + X ms (resolving: X ms, restoring: X ms, integration: X ms, building: X ms, storing: X ms) +chunk (runtime: main) bundle.js (main) X bytes (javascript) X KiB (runtime) >{b_js}< >{c_js}< [entry] [rendered] + > ./index main + runtime modules X KiB 7 modules + cacheable modules X bytes + ./a.js X bytes [dependent] [built] [code generated] + cjs self exports reference ./a.js 1:0-14 + cjs require ./a ./e.js 1:0-14 + cjs require ./a ./index.js 1:0-14 + X ms -> + X ms (resolving: X ms, restoring: X ms, integration: X ms, building: X ms, storing: X ms) + ./index.js X bytes [built] [code generated] + entry ./index main + X ms (resolving: X ms, restoring: X ms, integration: X ms, building: X ms, storing: X ms) +webpack x.x.x compiled successfully in X ms" +`; + +exports[`StatsTestCases should print correct stats for circular-correctness 1`] = ` +"chunk (runtime: main) 199.bundle.js (b) X bytes <{390}> <{792}> >{390}< [rendered] + ./module-b.js X bytes [built] [code generated] +chunk (runtime: main) 390.bundle.js (c) X bytes <{199}> <{996}> >{199}< >{996}< [rendered] + ./module-c.js X bytes [built] [code generated] +chunk (runtime: main) bundle.js (main) X bytes (javascript) X KiB (runtime) >{199}< >{996}< [entry] [rendered] + runtime modules X KiB 10 modules + ./index.js X bytes [built] [code generated] +chunk (runtime: main) 996.bundle.js (a) X bytes <{390}> <{792}> >{390}< [rendered] + ./module-a.js X bytes [built] [code generated] +webpack x.x.x compiled successfully" +`; + +exports[`StatsTestCases should print correct stats for color-disabled 1`] = ` +"asset main.js X bytes [emitted] (name: main) +./index.js X bytes [built] [code generated] +webpack x.x.x compiled successfully in X ms" +`; + +exports[`StatsTestCases should print correct stats for color-enabled 1`] = ` +"asset main.js X bytes [emitted] (name: main) +./index.js X bytes [built] [code generated] +webpack x.x.x compiled successfully in X ms" +`; + +exports[`StatsTestCases should print correct stats for color-enabled-custom 1`] = ` +"asset main.js X bytes [emitted] (name: main) +./index.js X bytes [built] [code generated] +webpack x.x.x compiled successfully in X ms" +`; + +exports[`StatsTestCases should print correct stats for common-libs 1`] = ` +"asset react.js X KiB [emitted] [minimized] (name: react) 1 related asset +./react.js X bytes [built] [code generated] +../../../node_modules/react/index.js X bytes [built] [code generated] +../../../node_modules/react/cjs/react.production.min.js X KiB [built] [code generated] +webpack x.x.x compiled successfully in X ms" +`; + +exports[`StatsTestCases should print correct stats for commons-chunk-min-size-0 1`] = ` +"asset entry-1.js X KiB [emitted] (name: entry-1) +asset 903.js X bytes [emitted] (id hint: vendor-1) +Entrypoint entry-1 X KiB = 903.js X bytes entry-1.js X KiB +runtime modules X KiB 3 modules +modules by path ./modules/*.js X bytes + ./modules/a.js X bytes [built] [code generated] + ./modules/b.js X bytes [built] [code generated] + ./modules/c.js X bytes [built] [code generated] + ./modules/d.js X bytes [built] [code generated] + ./modules/e.js X bytes [built] [code generated] + ./modules/f.js X bytes [built] [code generated] +./entry-1.js X bytes [built] [code generated] +webpack x.x.x compiled successfully in X ms" +`; + +exports[`StatsTestCases should print correct stats for commons-chunk-min-size-Infinity 1`] = ` +"asset entry-1.js X KiB [emitted] (name: entry-1) +asset vendor-1.js X bytes [emitted] (name: vendor-1) (id hint: vendor-1) +Entrypoint entry-1 X KiB = vendor-1.js X bytes entry-1.js X KiB +runtime modules X KiB 3 modules +modules by path ./modules/*.js X bytes + ./modules/a.js X bytes [built] [code generated] + ./modules/b.js X bytes [built] [code generated] + ./modules/c.js X bytes [built] [code generated] + ./modules/d.js X bytes [built] [code generated] + ./modules/e.js X bytes [built] [code generated] + ./modules/f.js X bytes [built] [code generated] +./entry-1.js X bytes [built] [code generated] +webpack x.x.x compiled successfully in X ms" +`; + +exports[`StatsTestCases should print correct stats for commons-plugin-issue-4980 1`] = ` +"asset app.XXXXXXXXXXXXXXXXXXXX-X.js X KiB [emitted] [immutable] (name: app) +asset vendor.XXXXXXXXXXXXXXXXXXXX-X.js X bytes [emitted] [immutable] (name: vendor) (id hint: vendor) +Entrypoint app X KiB = vendor.XXXXXXXXXXXXXXXXXXXX-X.js X bytes app.XXXXXXXXXXXXXXXXXXXX-X.js X KiB +runtime modules X KiB 4 modules +orphan modules X bytes [orphan] 2 modules +cacheable modules X bytes + ./entry-1.js + 2 modules X bytes [built] [code generated] + ./constants.js X bytes [built] [code generated] +webpack x.x.x compiled successfully in X ms + +asset app.XXXXXXXXXXXXXXXXXXXX-X.js X KiB [emitted] [immutable] (name: app) +asset vendor.XXXXXXXXXXXXXXXXXXXX-X.js X bytes [emitted] [immutable] (name: vendor) (id hint: vendor) +Entrypoint app X KiB = vendor.XXXXXXXXXXXXXXXXXXXX-X.js X bytes app.XXXXXXXXXXXXXXXXXXXX-X.js X KiB +runtime modules X KiB 4 modules +orphan modules X bytes [orphan] 2 modules +cacheable modules X bytes + ./entry-2.js + 2 modules X bytes [built] [code generated] + ./constants.js X bytes [built] [code generated] +webpack x.x.x compiled successfully in X ms" +`; + +exports[`StatsTestCases should print correct stats for concat-and-sideeffects 1`] = ` +"./index.js + 2 modules X bytes [built] [code generated] + | ./index.js X bytes [built] + | Statement (ExpressionStatement) with side effects in source code at 3:0-15 + | ./node_modules/pmodule/a.js X bytes [built] + | ./node_modules/pmodule/aa.js X bytes [built] +./node_modules/pmodule/a.js X bytes [orphan] [built] +./node_modules/pmodule/index.js X bytes [orphan] [built] + ModuleConcatenation bailout: Module is not in any chunk +./node_modules/pmodule/aa.js X bytes [orphan] [built] +./node_modules/pmodule/b.js X bytes [orphan] [built] + ModuleConcatenation bailout: Module is not in any chunk +./node_modules/pmodule/c.js X bytes [orphan] [built] + ModuleConcatenation bailout: Module is not in any chunk +./node_modules/pmodule/bb.js X bytes [orphan] [built] + ModuleConcatenation bailout: Module is not in any chunk +./node_modules/pmodule/cc.js X bytes [orphan] [built] + ModuleConcatenation bailout: Module is not in any chunk" +`; + +exports[`StatsTestCases should print correct stats for context-independence 1`] = ` +"asset main-XXXXXXXXXXXXXXXXXXXX.js X KiB [emitted] [immutable] (name: main) + sourceMap main-XXXXXXXXXXXXXXXXXXXX.js.map X KiB [emitted] [dev] (auxiliary name: main) +asset 977-XXXXXXXXXXXXXXXXXXXX.js X bytes [emitted] [immutable] + sourceMap 977-XXXXXXXXXXXXXXXXXXXX.js.map X bytes [emitted] [dev] +runtime modules X KiB 9 modules +orphan modules X bytes [orphan] 1 module +built modules X bytes [built] + modules by path ./a/*.js X bytes + ./a/index.js (in my-layer) X bytes [built] [code generated] + ./a/chunk.js + 1 modules (in my-layer) X bytes [built] [code generated] + modules by path ./a/c/ X bytes + ./a/c/ ./a/cc/ eager ^\\\\.\\\\/.*$ namespace object (in my-layer) X bytes [built] [code generated] + ./a/c/a.js (in my-layer) X bytes [optional] [built] [code generated] + ./a/cc/b.js (in my-layer) X bytes [optional] [built] [code generated] +webpack x.x.x compiled successfully in X ms + +asset main-XXXXXXXXXXXXXXXXXXXX.js X KiB [emitted] [immutable] (name: main) + sourceMap main-XXXXXXXXXXXXXXXXXXXX.js.map X KiB [emitted] [dev] (auxiliary name: main) +asset 977-XXXXXXXXXXXXXXXXXXXX.js X bytes [emitted] [immutable] + sourceMap 977-XXXXXXXXXXXXXXXXXXXX.js.map X bytes [emitted] [dev] +runtime modules X KiB 9 modules +orphan modules X bytes [orphan] 1 module +built modules X bytes [built] + modules by path ./b/*.js X bytes + ./b/index.js (in my-layer) X bytes [built] [code generated] + ./b/chunk.js + 1 modules (in my-layer) X bytes [built] [code generated] + modules by path ./b/c/ X bytes + ./b/c/ ./b/cc/ eager ^\\\\.\\\\/.*$ namespace object (in my-layer) X bytes [built] [code generated] + ./b/c/a.js (in my-layer) X bytes [optional] [built] [code generated] + ./b/cc/b.js (in my-layer) X bytes [optional] [built] [code generated] +webpack x.x.x compiled successfully in X ms + +asset main-XXXXXXXXXXXXXXXXXXXX.js X KiB [emitted] [immutable] (name: main) +asset 977-XXXXXXXXXXXXXXXXXXXX.js X KiB [emitted] [immutable] +runtime modules X KiB 9 modules +orphan modules X bytes [orphan] 1 module +built modules X bytes [built] + modules by path ./a/*.js X bytes + ./a/index.js (in my-layer) X bytes [built] [code generated] + ./a/chunk.js + 1 modules (in my-layer) X bytes [built] [code generated] + modules by path ./a/c/ X bytes + ./a/c/ ./a/cc/ eager ^\\\\.\\\\/.*$ namespace object (in my-layer) X bytes [built] [code generated] + ./a/c/a.js (in my-layer) X bytes [optional] [built] [code generated] + ./a/cc/b.js (in my-layer) X bytes [optional] [built] [code generated] +webpack x.x.x compiled successfully in X ms + +asset main-XXXXXXXXXXXXXXXXXXXX.js X KiB [emitted] [immutable] (name: main) +asset 977-XXXXXXXXXXXXXXXXXXXX.js X KiB [emitted] [immutable] +runtime modules X KiB 9 modules +orphan modules X bytes [orphan] 1 module +built modules X bytes [built] + modules by path ./b/*.js X bytes + ./b/index.js (in my-layer) X bytes [built] [code generated] + ./b/chunk.js + 1 modules (in my-layer) X bytes [built] [code generated] + modules by path ./b/c/ X bytes + ./b/c/ ./b/cc/ eager ^\\\\.\\\\/.*$ namespace object (in my-layer) X bytes [built] [code generated] + ./b/c/a.js (in my-layer) X bytes [optional] [built] [code generated] + ./b/cc/b.js (in my-layer) X bytes [optional] [built] [code generated] +webpack x.x.x compiled successfully in X ms + +asset main-XXXXXXXXXXXXXXXXXXXX.js X KiB [emitted] [immutable] (name: main) +asset 977-XXXXXXXXXXXXXXXXXXXX.js X bytes [emitted] [immutable] +runtime modules X KiB 9 modules +orphan modules X bytes [orphan] 1 module +built modules X bytes [built] + modules by path ./a/*.js X bytes + ./a/index.js (in my-layer) X bytes [built] [code generated] + ./a/chunk.js + 1 modules (in my-layer) X bytes [built] [code generated] + modules by path ./a/c/ X bytes + ./a/c/ ./a/cc/ eager ^\\\\.\\\\/.*$ namespace object (in my-layer) X bytes [built] [code generated] + ./a/c/a.js (in my-layer) X bytes [optional] [built] [code generated] + ./a/cc/b.js (in my-layer) X bytes [optional] [built] [code generated] +webpack x.x.x compiled successfully in X ms + +asset main-XXXXXXXXXXXXXXXXXXXX.js X KiB [emitted] [immutable] (name: main) +asset 977-XXXXXXXXXXXXXXXXXXXX.js X bytes [emitted] [immutable] +runtime modules X KiB 9 modules +orphan modules X bytes [orphan] 1 module +built modules X bytes [built] + modules by path ./b/*.js X bytes + ./b/index.js (in my-layer) X bytes [built] [code generated] + ./b/chunk.js + 1 modules (in my-layer) X bytes [built] [code generated] + modules by path ./b/c/ X bytes + ./b/c/ ./b/cc/ eager ^\\\\.\\\\/.*$ namespace object (in my-layer) X bytes [built] [code generated] + ./b/c/a.js (in my-layer) X bytes [optional] [built] [code generated] + ./b/cc/b.js (in my-layer) X bytes [optional] [built] [code generated] +webpack x.x.x compiled successfully in X ms" +`; + +exports[`StatsTestCases should print correct stats for custom-terser 1`] = ` +"asset bundle.js X bytes [emitted] [minimized] (name: main) +./index.js X bytes [built] [code generated] + [no exports used] +./a.js X bytes [built] [code generated] + [used exports unknown] +webpack x.x.x compiled successfully in X ms" +`; + +exports[`StatsTestCases should print correct stats for define-plugin 1`] = ` +"asset 123.js X KiB [emitted] (name: main) +./index.js X bytes [built] [code generated] +webpack x.x.x compiled successfully in X ms + +asset 321.js X KiB [emitted] (name: main) +./index.js X bytes [built] [code generated] +webpack x.x.x compiled successfully in X ms + +asset both.js X KiB [emitted] (name: main) +./index.js X bytes [built] [code generated] +webpack x.x.x compiled successfully in X ms + +asset log.js X KiB [emitted] (name: main) +./index.js X bytes [built] [code generated] + +DEBUG LOG from webpack.DefinePlugin + Replaced \\"VALUE\\" with \\"123\\" + +webpack x.x.x compiled successfully in X ms" +`; + +exports[`StatsTestCases should print correct stats for details-error 1`] = ` +"0 errors 0 warnings: + asset 0.js X KiB [emitted] (name: main) + ./index.js X bytes [built] [code generated] + 0 errors 0 warnings (webpack x.x.x) compiled successfully in X ms + +1 errors 0 warnings: + asset 1.js X KiB [emitted] (name: main) + ./index.js X bytes [built] [code generated] + + ERROR in Test + Error details + + 1 errors 0 warnings (webpack x.x.x) compiled with 1 error in X ms + +0 errors 1 warnings: + asset 10.js X KiB [emitted] (name: main) + ./index.js X bytes [built] [code generated] + + WARNING in Test + + 1 warning has detailed information that is not shown. + Use 'stats.errorDetails: true' resp. '--stats-error-details' to show it. + + 0 errors 1 warnings (webpack x.x.x) compiled with 1 warning in X ms + +2 errors 0 warnings: + asset 2.js X KiB [emitted] (name: main) + ./index.js X bytes [built] [code generated] + + ERROR in Test + Error details + + ERROR in Test + Error details + + 2 errors 0 warnings (webpack x.x.x) compiled with 2 errors in X ms + +0 errors 2 warnings: + asset 20.js X KiB [emitted] (name: main) + ./index.js X bytes [built] [code generated] + + WARNING in Test + + WARNING in Test + + 2 warnings have detailed information that is not shown. + Use 'stats.errorDetails: true' resp. '--stats-error-details' to show it. + + 0 errors 2 warnings (webpack x.x.x) compiled with 2 warnings in X ms + +1 errors 1 warnings: + asset 11.js X KiB [emitted] (name: main) + ./index.js X bytes [built] [code generated] + + WARNING in Test + + 1 warning has detailed information that is not shown. + Use 'stats.errorDetails: true' resp. '--stats-error-details' to show it. + + ERROR in Test + Error details + + 1 errors 1 warnings (webpack x.x.x) compiled with 1 error and 1 warning in X ms + +2 errors 1 warnings: + asset 12.js X KiB [emitted] (name: main) + ./index.js X bytes [built] [code generated] + + WARNING in Test + + 1 warning has detailed information that is not shown. + Use 'stats.errorDetails: true' resp. '--stats-error-details' to show it. + + ERROR in Test + Error details + + ERROR in Test + Error details + + 2 errors 1 warnings (webpack x.x.x) compiled with 2 errors and 1 warning in X ms + +3 errors 1 warnings: + asset 13.js X KiB [emitted] (name: main) + ./index.js X bytes [built] [code generated] + + WARNING in Test + + 1 warning has detailed information that is not shown. + Use 'stats.errorDetails: true' resp. '--stats-error-details' to show it. + + ERROR in Test + + ERROR in Test + + ERROR in Test + + 3 errors have detailed information that is not shown. + Use 'stats.errorDetails: true' resp. '--stats-error-details' to show it. + + 3 errors 1 warnings (webpack x.x.x) compiled with 3 errors and 1 warning in X ms + +3 errors 0 warnings: + asset 3.js X KiB [emitted] (name: main) + ./index.js X bytes [built] [code generated] + + ERROR in Test + + ERROR in Test + + ERROR in Test + + 3 errors have detailed information that is not shown. + Use 'stats.errorDetails: true' resp. '--stats-error-details' to show it. + + 3 errors 0 warnings (webpack x.x.x) compiled with 3 errors in X ms + +0 errors 3 warnings: + asset 30.js X KiB [emitted] (name: main) + ./index.js X bytes [built] [code generated] + + WARNING in Test + + WARNING in Test + + WARNING in Test + + 3 warnings have detailed information that is not shown. + Use 'stats.errorDetails: true' resp. '--stats-error-details' to show it. + + 0 errors 3 warnings (webpack x.x.x) compiled with 3 warnings in X ms" +`; + +exports[`StatsTestCases should print correct stats for dll-reference-plugin-issue-7624 1`] = ` +"asset bundle.js X bytes [emitted] (name: main) +./entry.js X bytes [built] [code generated] +webpack x.x.x compiled successfully in X ms" +`; + +exports[`StatsTestCases should print correct stats for dll-reference-plugin-issue-7624-error 1`] = ` +"assets by status X bytes [cached] 1 asset +./entry.js X bytes [built] [code generated] + +ERROR in Dll manifest ./blank-manifest.json +Unexpected end of JSON input while parsing empty string + +webpack x.x.x compiled with 1 error in X ms" +`; + +exports[`StatsTestCases should print correct stats for dynamic-chunk-name-error 1`] = ` +"assets by status X KiB [cached] 3 assets +runtime modules X KiB 8 modules +cacheable modules X bytes + ./entry-1.js X bytes [built] [code generated] + ./entry-2.js X bytes [built] [code generated] + ./entry-3.js X bytes [built] [code generated] + ./dynamic.js X bytes [built] [code generated] + +ERROR in ./entry-1.js 1:7-58 +It's not allowed to load an initial chunk on demand. The chunk name \\"entry2\\" is already used by an entrypoint. + +ERROR in ./entry-3.js 1:7-58 +It's not allowed to load an initial chunk on demand. The chunk name \\"entry3\\" is already used by an entrypoint. + +webpack x.x.x compiled with 2 errors in X ms" +`; + +exports[`StatsTestCases should print correct stats for entry-filename 1`] = ` +"PublicPath: auto +asset a.js X KiB [emitted] (name: a) +asset c.js X KiB [emitted] (name: b) +chunk (runtime: b) c.js (b) X bytes [entry] [rendered] + > ./b.js b + ./b.js X bytes [built] [code generated] + cjs self exports reference ./b.js 1:0-14 + entry ./b.js b + X ms (resolving: X ms, restoring: X ms, integration: X ms, building: X ms, storing: X ms) +chunk (runtime: a) a.js (a) X bytes [entry] [rendered] + > ./a.js a + ./a.js X bytes [built] [code generated] + cjs self exports reference ./a.js 1:0-14 + entry ./a.js a + X ms (resolving: X ms, restoring: X ms, integration: X ms, building: X ms, storing: X ms) +webpack x.x.x compiled successfully in X ms" +`; + +exports[`StatsTestCases should print correct stats for errors-space-error 1`] = ` +"assets by status X bytes [cached] 1 asset +./loader.js!./index.js X bytes [built] [code generated] [2 errors] + +ERROR in ./index.js (./loader.js!./index.js) +Module Error (from ./loader.js): +loader error1 + +ERROR in ./index.js (./loader.js!./index.js) +Module Error (from ./loader.js): +loader error2 + +2 errors have detailed information that is not shown. +Use 'stats.errorDetails: true' resp. '--stats-error-details' to show it. + +webpack x.x.x compiled with 2 errors in X ms + +assets by status X bytes [cached] 1 asset +./loader.js!./index.js X bytes [built] [code generated] [2 errors] + +ERROR in ./index.js (./loader.js!./index.js) +Module Error (from ./loader.js): +loader error1 + +ERROR in ./index.js (./loader.js!./index.js) +Module Error (from ./loader.js): +loader error2 + +2 errors have detailed information that is not shown. +Use 'stats.errorDetails: true' resp. '--stats-error-details' to show it. + +webpack x.x.x compiled with 2 errors in X ms + +assets by status X bytes [cached] 1 asset +./loader.js!./index.js X bytes [built] [code generated] [2 errors] + +ERROR in ./index.js (./loader.js!./index.js) +Module Error (from ./loader.js): +loader error1 + +ERROR in ./index.js (./loader.js!./index.js) +Module Error (from ./loader.js): +loader error2 + +2 errors have detailed information that is not shown. +Use 'stats.errorDetails: true' resp. '--stats-error-details' to show it. + +webpack x.x.x compiled with 2 errors in X ms + +assets by status X bytes [cached] 1 asset +./loader.js!./index.js X bytes [built] [code generated] [2 errors] + +ERROR in ./index.js (./loader.js!./index.js) +Module Error (from ./loader.js): +loader error1 +stack1 ++ 2 hidden lines + +ERROR in ./index.js (./loader.js!./index.js) +Module Error (from ./loader.js): +loader error2 + +1 error has detailed information that is not shown. +Use 'stats.errorDetails: true' resp. '--stats-error-details' to show it. + +webpack x.x.x compiled with 2 errors in X ms + +assets by status X bytes [cached] 1 asset +./loader.js!./index.js X bytes [built] [code generated] [2 errors] + +ERROR in ./index.js (./loader.js!./index.js) +Module Error (from ./loader.js): +loader error1 +stack1 +stack2 +stack3 + +ERROR in ./index.js (./loader.js!./index.js) +Module Error (from ./loader.js): +loader error2 + +1 error has detailed information that is not shown. +Use 'stats.errorDetails: true' resp. '--stats-error-details' to show it. + +webpack x.x.x compiled with 2 errors in X ms + +assets by status X bytes [cached] 1 asset +./loader.js!./index.js X bytes [built] [code generated] [2 errors] + +ERROR in ./index.js (./loader.js!./index.js) +Module Error (from ./loader.js): +loader error1 +stack1 +stack2 +stack3 + +ERROR in ./index.js (./loader.js!./index.js) +Module Error (from ./loader.js): +loader error2 +stack1 +stack2 + +webpack x.x.x compiled with 2 errors in X ms" +`; + +exports[`StatsTestCases should print correct stats for exclude-with-loader 1`] = ` +"hidden assets X bytes 1 asset +asset bundle.js X KiB [emitted] (name: main) +runtime modules X KiB 5 modules +hidden modules X bytes 2 modules +cacheable modules X bytes + ./index.js X bytes [built] [code generated] + ./a.txt X bytes [built] [code generated] +webpack x.x.x compiled successfully in X ms" +`; + +exports[`StatsTestCases should print correct stats for external 1`] = ` +"asset main.js X KiB [emitted] (name: main) +./index.js X bytes [built] [code generated] +external \\"test\\" X bytes [built] [code generated] +webpack x.x.x compiled successfully in X ms" +`; + +exports[`StatsTestCases should print correct stats for graph-correctness-entries 1`] = ` +"chunk (runtime: e2) e2.js (e2) X bytes (javascript) X KiB (runtime) >{390}< [entry] [rendered] + runtime modules X KiB 10 modules + ./e2.js X bytes [built] [code generated] + entry ./e2 e2 +chunk (runtime: e1, e2) b.js (b) X bytes <{996}> >{390}< [rendered] + ./module-b.js X bytes [built] [code generated] + import() ./module-b ./module-a.js 1:0-47 +chunk (runtime: e1) e1.js (e1) X bytes (javascript) X KiB (runtime) >{996}< [entry] [rendered] + runtime modules X KiB 10 modules + ./e1.js X bytes [built] [code generated] + entry ./e1 e1 +chunk (runtime: e1, e2) c.js (c) X bytes <{130}> <{199}> >{996}< [rendered] + ./module-c.js X bytes [built] [code generated] + import() ./module-c ./e2.js 1:0-47 + import() ./module-c ./module-b.js 1:0-47 +chunk (runtime: e1, e2) a.js (a) X bytes <{321}> <{390}> >{199}< [rendered] + ./module-a.js X bytes [built] [code generated] + import() ./module-a ./e1.js 1:0-47 + import() ./module-a ./module-c.js 1:0-47 +webpack x.x.x compiled successfully" +`; + +exports[`StatsTestCases should print correct stats for graph-correctness-modules 1`] = ` +"chunk (runtime: e2) e2.js (e2) X bytes (javascript) X KiB (runtime) >{390}< >{460}< [entry] [rendered] + runtime modules X KiB 11 modules + cacheable modules X bytes + ./e2.js X bytes [built] [code generated] + entry ./e2 e2 + ./module-x.js X bytes [dependent] [built] [code generated] + harmony side effect evaluation ./module-x ./e1.js 1:0-20 + harmony side effect evaluation ./module-x ./e2.js 1:0-20 + import() ./module-x ./module-b.js 2:0-20 +chunk (runtime: e1, e2) b.js (b) X bytes <{996}> >{390}< [rendered] + ./module-b.js X bytes [built] [code generated] + import() ./module-b ./module-a.js 1:0-47 +chunk (runtime: e1) e1.js (e1) X bytes (javascript) X KiB (runtime) >{460}< >{996}< [entry] [rendered] + runtime modules X KiB 11 modules + cacheable modules X bytes + ./e1.js X bytes [built] [code generated] + entry ./e1 e1 + ./module-x.js X bytes [dependent] [built] [code generated] + harmony side effect evaluation ./module-x ./e1.js 1:0-20 + harmony side effect evaluation ./module-x ./e2.js 1:0-20 + import() ./module-x ./module-b.js 2:0-20 +chunk (runtime: e1, e2) c.js (c) X bytes <{130}> <{199}> >{996}< [rendered] + ./module-c.js X bytes [built] [code generated] + import() ./module-c ./e2.js 2:0-47 + import() ./module-c ./module-b.js 1:0-47 +chunk (runtime: e1, e2) y.js (y) X bytes <{130}> <{321}> [rendered] + ./module-y.js X bytes [built] [code generated] + import() ./module-y ./module-x.js 1:0-47 +chunk (runtime: e1, e2) a.js (a) X bytes <{321}> <{390}> >{199}< [rendered] + ./module-a.js X bytes [built] [code generated] + import() ./module-a ./e1.js 2:0-47 + import() ./module-a ./module-c.js 1:0-47 +webpack x.x.x compiled successfully" +`; + +exports[`StatsTestCases should print correct stats for graph-roots 1`] = ` +"chunk (runtime: main) cycle.js (cycle) X bytes [rendered] + ./cycle/a.js X bytes [built] [code generated] + ./cycle/b.js X bytes [built] [code generated] + ./cycle/c.js X bytes [built] [code generated] + ./cycle/index.js X bytes [built] [code generated] +chunk (runtime: main) cycle2.js (cycle2) X bytes [rendered] + dependent modules X bytes [dependent] 3 modules + ./cycle2/index.js X bytes [built] [code generated] +chunk (runtime: main) cycles.js (cycles) X bytes [rendered] + dependent modules X bytes [dependent] 6 modules + ./cycles/1/index.js X bytes [built] [code generated] + ./cycles/2/index.js X bytes [built] [code generated] +chunk (runtime: main) id-equals-name_js.js (id-equals-name_js) X bytes [rendered] + ./id-equals-name.js?1 X bytes [built] [code generated] +chunk (runtime: main) id-equals-name_js-_70e2.js (id-equals-name_js-_70e2) X bytes [rendered] + ./id-equals-name.js?2 X bytes [built] [code generated] +chunk (runtime: main) id-equals-name_js0.js X bytes [rendered] + ./id-equals-name.js X bytes [built] [code generated] +chunk (runtime: main) id-equals-name_js_3.js X bytes [rendered] + ./id-equals-name.js?3 X bytes [built] [code generated] +chunk (runtime: main) main.js (main) X bytes (javascript) X KiB (runtime) [entry] [rendered] + runtime modules X KiB 9 modules + ./index.js X bytes [built] [code generated] +chunk (runtime: main) tree.js (tree) X bytes [rendered] + dependent modules X bytes [dependent] 3 modules + ./tree/index.js X bytes [built] [code generated] +chunk (runtime: main) trees.js (trees) X bytes [rendered] + dependent modules X bytes [dependent] 3 modules + ./trees/1.js X bytes [built] [code generated] + ./trees/2.js X bytes [built] [code generated] + ./trees/3.js X bytes [built] [code generated]" +`; + +exports[`StatsTestCases should print correct stats for ignore-warnings 1`] = ` +"asset main.js X bytes [emitted] (name: main) +orphan modules X bytes [orphan] 9 modules +./index.js + 9 modules X bytes [built] [code generated] + +WARNING in ./module.js?4 3:12-20 +Should not import the named export 'homepage' (imported as 'homepage') from default-exporting module (only default export is available soon) + @ ./index.js 4:0-20 + +WARNING in ./module2.js?1 3:12-16 +Should not import the named export 'name' (imported as 'name') from default-exporting module (only default export is available soon) + @ ./index.js 6:0-21 + +webpack x.x.x compiled with 2 warnings in X ms" +`; + +exports[`StatsTestCases should print correct stats for immutable 1`] = ` +"asset XXXXXXXXXXXXXXXXXXXX.js X KiB [emitted] [immutable] (name: main) +asset XXXXXXXXXXXXXXXXXXXX.js X bytes [emitted] [immutable]" +`; + +exports[`StatsTestCases should print correct stats for import-context-filter 1`] = ` +"asset entry.js X KiB [emitted] (name: entry) +asset 717.js X bytes [emitted] +asset 776.js X bytes [emitted] +asset 0.js X bytes [emitted] +runtime modules X KiB 9 modules +built modules X bytes [built] + modules by path ./templates/*.js X bytes + ./templates/bar.js X bytes [optional] [built] [code generated] + ./templates/baz.js X bytes [optional] [built] [code generated] + ./templates/foo.js X bytes [optional] [built] [code generated] + ./entry.js X bytes [built] [code generated] + ./templates/ lazy ^\\\\.\\\\/.*$ include: \\\\.js$ exclude: \\\\.noimport\\\\.js$ na...(truncated) X bytes [optional] [built] [code generated] +webpack x.x.x compiled successfully in X ms" +`; + +exports[`StatsTestCases should print correct stats for import-weak 1`] = ` +"asset entry.js X KiB [emitted] (name: entry) +asset 237.js X bytes [emitted] +runtime modules X KiB 10 modules +orphan modules X bytes [orphan] 1 module +cacheable modules X bytes + ./entry.js X bytes [built] [code generated] + ./modules/b.js X bytes [built] [code generated] +webpack x.x.x compiled successfully in X ms" +`; + +exports[`StatsTestCases should print correct stats for import-weak-parser-option 1`] = ` +"asset entry.js X KiB [emitted] (name: entry) +asset 237.js X bytes [emitted] +runtime modules X KiB 10 modules +orphan modules X bytes [orphan] 1 module +cacheable modules X bytes + ./entry.js X bytes [built] [code generated] + ./modules/b.js X bytes [built] [code generated] +webpack x.x.x compiled successfully in X ms" +`; + +exports[`StatsTestCases should print correct stats for import-with-invalid-options-comments 1`] = ` +"runtime modules X KiB 12 modules +cacheable modules X bytes + ./index.js X bytes [built] [code generated] + ./chunk.js X bytes [built] [code generated] [3 warnings] + ./chunk-a.js X bytes [built] [code generated] + ./chunk-b.js X bytes [built] [code generated] + ./chunk-c.js X bytes [built] [code generated] + ./chunk-d.js X bytes [built] [code generated] + +WARNING in ./chunk.js 2:11-84 +Compilation error while processing magic comment(-s): /* webpackPrefetch: true, webpackChunkName: notGoingToCompileChunkName */: notGoingToCompileChunkName is not defined + @ ./index.js 1:0-49 + +WARNING in ./chunk.js 4:11-77 +Compilation error while processing magic comment(-s): /* webpack Prefetch: 0, webpackChunkName: \\"notGoingToCompile-c\\" */: Unexpected identifier + @ ./index.js 1:0-49 + +WARNING in ./chunk.js 5:11-38 +Compilation error while processing magic comment(-s): /* webpackPrefetch: nope */: nope is not defined + @ ./index.js 1:0-49 + +webpack x.x.x compiled with 3 warnings" +`; + +exports[`StatsTestCases should print correct stats for issue-7577 1`] = ` +"asset a-runtime~main-XXXXXXXXXXXXXXXXXXXX.js X KiB [emitted] [immutable] (name: runtime~main) +asset a-main-XXXXXXXXXXXXXXXXXXXX.js X bytes [emitted] [immutable] (name: main) +asset a-all-a_js-XXXXXXXXXXXXXXXXXXXX.js X bytes [emitted] [immutable] (id hint: all) +Entrypoint main X KiB = a-runtime~main-XXXXXXXXXXXXXXXXXXXX.js X KiB a-all-a_js-XXXXXXXXXXXXXXXXXXXX.js X bytes a-main-XXXXXXXXXXXXXXXXXXXX.js X bytes +runtime modules X KiB 3 modules +./a.js X bytes [built] [code generated] +webpack x.x.x compiled successfully in X ms + +asset b-runtime~main-XXXXXXXXXXXXXXXXXXXX.js X KiB [emitted] [immutable] (name: runtime~main) +asset b-all-b_js-XXXXXXXXXXXXXXXXXXXX.js X bytes [emitted] [immutable] (id hint: all) +asset b-main-XXXXXXXXXXXXXXXXXXXX.js X bytes [emitted] [immutable] (name: main) +asset b-vendors-node_modules_vendor_js-XXXXXXXXXXXXXXXXXXXX.js X bytes [emitted] [immutable] (id hint: vendors) +Entrypoint main X KiB = b-runtime~main-XXXXXXXXXXXXXXXXXXXX.js X KiB b-vendors-node_modules_vendor_js-XXXXXXXXXXXXXXXXXXXX.js X bytes b-all-b_js-XXXXXXXXXXXXXXXXXXXX.js X bytes b-main-XXXXXXXXXXXXXXXXXXXX.js X bytes +runtime modules X KiB 5 modules +cacheable modules X bytes + ./b.js X bytes [built] [code generated] + ./node_modules/vendor.js X bytes [built] [code generated] +webpack x.x.x compiled successfully in X ms + +assets by chunk X bytes (id hint: all) + asset c-all-b_js-XXXXXXXXXXXXXXXXXXXX.js X bytes [emitted] [immutable] (id hint: all) + asset c-all-c_js-XXXXXXXXXXXXXXXXXXXX.js X bytes [emitted] [immutable] (id hint: all) +asset c-runtime~main-XXXXXXXXXXXXXXXXXXXX.js X KiB [emitted] [immutable] (name: runtime~main) +asset c-main-XXXXXXXXXXXXXXXXXXXX.js X bytes [emitted] [immutable] (name: main) +asset c-vendors-node_modules_vendor_js-XXXXXXXXXXXXXXXXXXXX.js X bytes [emitted] [immutable] (id hint: vendors) +Entrypoint main X KiB = c-runtime~main-XXXXXXXXXXXXXXXXXXXX.js X KiB c-all-c_js-XXXXXXXXXXXXXXXXXXXX.js X bytes c-main-XXXXXXXXXXXXXXXXXXXX.js X bytes +runtime modules X KiB 13 modules +cacheable modules X bytes + ./c.js X bytes [built] [code generated] + ./b.js X bytes [built] [code generated] + ./node_modules/vendor.js X bytes [built] [code generated] +webpack x.x.x compiled successfully in X ms" +`; + +exports[`StatsTestCases should print correct stats for limit-chunk-count-plugin 1`] = ` +"1 chunks: + asset bundle1.js X KiB [emitted] (name: main) + chunk (runtime: main) bundle1.js (main) X bytes (javascript) X KiB (runtime) <{792}> >{792}< [entry] [rendered] + runtime modules X KiB 4 modules + cacheable modules X bytes + ./a.js X bytes [dependent] [built] [code generated] + ./b.js X bytes [dependent] [built] [code generated] + ./c.js X bytes [dependent] [built] [code generated] + ./d.js X bytes [dependent] [built] [code generated] + ./e.js X bytes [dependent] [built] [code generated] + ./index.js X bytes [built] [code generated] + 1 chunks (webpack x.x.x) compiled successfully in X ms + +2 chunks: + asset bundle2.js X KiB [emitted] (name: main) + asset 390.bundle2.js X bytes [emitted] (name: c) + chunk (runtime: main) 390.bundle2.js (c) X bytes <{390}> <{792}> >{390}< [rendered] + dependent modules X bytes [dependent] + ./d.js X bytes [dependent] [built] [code generated] + ./e.js X bytes [dependent] [built] [code generated] + ./a.js X bytes [built] [code generated] + ./b.js X bytes [built] [code generated] + ./c.js X bytes [built] [code generated] + chunk (runtime: main) bundle2.js (main) X bytes (javascript) X KiB (runtime) >{390}< [entry] [rendered] + runtime modules X KiB 10 modules + ./index.js X bytes [built] [code generated] + 2 chunks (webpack x.x.x) compiled successfully in X ms + +3 chunks: + asset bundle3.js X KiB [emitted] (name: main) + asset 390.bundle3.js X bytes [emitted] (name: c) + asset 226.bundle3.js X bytes [emitted] + chunk (runtime: main) 226.bundle3.js X bytes <{390}> [rendered] + ./d.js X bytes [built] [code generated] + ./e.js X bytes [built] [code generated] + chunk (runtime: main) 390.bundle3.js (c) X bytes <{792}> >{226}< [rendered] + ./a.js X bytes [built] [code generated] + ./b.js X bytes [built] [code generated] + ./c.js X bytes [built] [code generated] + chunk (runtime: main) bundle3.js (main) X bytes (javascript) X KiB (runtime) >{390}< [entry] [rendered] + runtime modules X KiB 10 modules + ./index.js X bytes [built] [code generated] + 3 chunks (webpack x.x.x) compiled successfully in X ms + +4 chunks: + asset bundle4.js X KiB [emitted] (name: main) + asset 390.bundle4.js X bytes [emitted] (name: c) + asset 226.bundle4.js X bytes [emitted] + asset 78.bundle4.js X bytes [emitted] + chunk (runtime: main) 78.bundle4.js X bytes <{792}> [rendered] + ./a.js X bytes [built] [code generated] + ./b.js X bytes [built] [code generated] + chunk (runtime: main) 226.bundle4.js X bytes <{390}> [rendered] + ./d.js X bytes [built] [code generated] + ./e.js X bytes [built] [code generated] + chunk (runtime: main) 390.bundle4.js (c) X bytes <{792}> >{226}< [rendered] + ./c.js X bytes [built] [code generated] + chunk (runtime: main) bundle4.js (main) X bytes (javascript) X KiB (runtime) >{78}< >{390}< [entry] [rendered] + runtime modules X KiB 10 modules + ./index.js X bytes [built] [code generated] + 4 chunks (webpack x.x.x) compiled successfully in X ms" +`; + +exports[`StatsTestCases should print correct stats for logging 1`] = ` +" [LogTestPlugin] Info +asset main.js X bytes [emitted] (name: main) +./index.js X bytes [built] [code generated] + +LOG from LogTestPlugin +<-> Group + Info + Log + <+> Collapsed group + Log + End ++ 6 hidden lines + +DEBUG LOG from ./node_modules/custom-loader/index.js ./node_modules/custom-loader/index.js!./index.js + An error +| at Object..module.exports (Xdir/logging/node_modules/custom-loader/index.js:5:9) + A warning +| at Object..module.exports (Xdir/logging/node_modules/custom-loader/index.js:6:9) +<-> Unimportant + Info message + Just log + Just debug + Measure: X ms + <-> Nested + Log inside collapsed group + Trace + | at Object..module.exports (Xdir/logging/node_modules/custom-loader/index.js:15:9) + Measure: X ms + ------- + After clear + +DEBUG LOG from ./node_modules/custom-loader/index.js Named Logger ./node_modules/custom-loader/index.js!./index.js + Message with named logger + +LOG from webpack.Compilation + 1 modules hashed, 0 from cache (1 variants per module in average) + 100% code generated (1 generated, 0 from cache) ++ 24 hidden lines + +LOG from webpack.FlagDependencyExportsPlugin + 0% of exports of modules have been determined (1 no declared exports, 0 not cached, 0 flagged uncacheable, 0 from cache, 0 from mem cache, 0 additional calculations due to dependencies) ++ 3 hidden lines + +LOG from webpack.buildChunkGraph + 2 queue items processed (1 blocks) + 0 chunk groups connected + 0 chunk groups processed for merging (0 module sets, 0 forked, 0 + 0 modules forked, 0 + 0 modules merged into fork, 0 resulting modules) + 0 chunk group info updated (0 already connected chunk groups reconnected) ++ 5 hidden lines + +LOG from webpack.FileSystemInfo + 1 new snapshots created + 0% root snapshot uncached (0 / 0) + 0% children snapshot uncached (0 / 0) + 0 entries tested + File info in cache: 1 timestamps 1 hashes 1 timestamp hash combinations + File timestamp hash combination snapshot optimization: 0% (0/1) entries shared via 0 shared snapshots (0 times referenced) + Directory info in cache: 0 timestamps 0 hashes 0 timestamp hash combinations + Managed items info in cache: 0 items + +webpack x.x.x compiled successfully in X ms" +`; + +exports[`StatsTestCases should print correct stats for logging-debug 1`] = ` +" [LogTestPlugin] Info +asset main.js X bytes [emitted] (name: main) +./index.js X bytes [built] [code generated] + +DEBUG LOG from ../logging/node_modules/custom-loader/index.js ../logging/node_modules/custom-loader/index.js!./index.js + An error + A warning +<-> Unimportant + Info message + Just log + Just debug + Measure: X ms + <-> Nested + Log inside collapsed group + Trace + Measure: X ms + ------- + After clear + +DEBUG LOG from ../logging/node_modules/custom-loader/index.js Named Logger ../logging/node_modules/custom-loader/index.js!./index.js + Message with named logger + +webpack x.x.x compiled successfully in X ms" +`; + +exports[`StatsTestCases should print correct stats for max-external-module-readable-identifier 1`] = ` +"asset main.js X KiB [emitted] (name: main) +./index.js X bytes [built] [code generated] +external \\"very-very-very-very-long-external-module-readable-identifier-it-should...(truncated) X bytes [built] [code generated] +webpack x.x.x compiled successfully in X ms" +`; + +exports[`StatsTestCases should print correct stats for max-modules 1`] = ` +"asset main.js X KiB [emitted] (name: main) +./index.js X bytes [built] [code generated] +./a.js?1 X bytes [built] [code generated] +./a.js?2 X bytes [built] [code generated] +./a.js?3 X bytes [built] [code generated] +./a.js?4 X bytes [built] [code generated] +./a.js?5 X bytes [built] [code generated] +./a.js?6 X bytes [built] [code generated] +./a.js?7 X bytes [built] [code generated] +./a.js?8 X bytes [built] [code generated] +./a.js?9 X bytes [built] [code generated] +./a.js?10 X bytes [built] [code generated] +./c.js?1 X bytes [built] [code generated] +./c.js?2 X bytes [built] [code generated] +./c.js?3 X bytes [built] [code generated] +./c.js?4 X bytes [built] [code generated] +./c.js?5 X bytes [built] [code generated] +./c.js?6 X bytes [built] [code generated] +./c.js?7 X bytes [built] [code generated] +./c.js?8 X bytes [built] [code generated] ++ 12 modules +webpack x.x.x compiled successfully in X ms" +`; + +exports[`StatsTestCases should print correct stats for max-modules-default 1`] = ` +"asset main.js X KiB [emitted] (name: main) +./index.js X bytes [built] [code generated] +./a.js?1 X bytes [built] [code generated] +./a.js?2 X bytes [built] [code generated] +./a.js?3 X bytes [built] [code generated] +./a.js?4 X bytes [built] [code generated] +./a.js?5 X bytes [built] [code generated] +./a.js?6 X bytes [built] [code generated] +./a.js?7 X bytes [built] [code generated] +./a.js?8 X bytes [built] [code generated] +./a.js?9 X bytes [built] [code generated] +./a.js?10 X bytes [built] [code generated] +./c.js?1 X bytes [built] [code generated] +./c.js?2 X bytes [built] [code generated] +./c.js?3 X bytes [built] [code generated] ++ 17 modules +webpack x.x.x compiled successfully in X ms" +`; + +exports[`StatsTestCases should print correct stats for module-assets 1`] = ` +"assets by path *.js X KiB + asset main.js X KiB [emitted] (name: main) + asset a.js X bytes [emitted] (name: a) + asset b.js X bytes [emitted] (name: b) +assets by path *.png X KiB + asset 1.png X KiB [emitted] [from: node_modules/a/1.png] (auxiliary name: a) + asset 2.png X KiB [emitted] [from: node_modules/a/2.png] (auxiliary name: a, b) +Entrypoint main X KiB = main.js +Chunk Group a X bytes (X KiB) = a.js X bytes (1.png X KiB 2.png X KiB) +Chunk Group b X bytes (X KiB) = b.js X bytes (2.png X KiB) +chunk (runtime: main) b.js (b) X bytes [rendered] + ./node_modules/a/2.png X bytes [dependent] [built] [code generated] [1 asset] + ./node_modules/b/index.js X bytes [built] [code generated] +chunk (runtime: main) main.js (main) X bytes (javascript) X KiB (runtime) [entry] [rendered] + runtime modules X KiB 8 modules + ./index.js X bytes [built] [code generated] +chunk (runtime: main) a.js (a) X bytes [rendered] + ./node_modules/a/2.png X bytes [dependent] [built] [code generated] [1 asset] + ./node_modules/a/index.js + 1 modules X bytes [built] [code generated] [1 asset] +runtime modules X KiB 8 modules +orphan modules X bytes [orphan] 1 module +modules with assets X bytes + modules by path ./node_modules/a/ X bytes + ./node_modules/a/index.js + 1 modules X bytes [built] [code generated] [1 asset] + ./node_modules/a/2.png X bytes [built] [code generated] [1 asset] + ./index.js X bytes [built] [code generated] + ./node_modules/b/index.js X bytes [built] [code generated] +webpack x.x.x compiled successfully in X ms" +`; + +exports[`StatsTestCases should print correct stats for module-deduplication 1`] = ` +"asset e2.js X KiB [emitted] (name: e2) +asset e3.js X KiB [emitted] (name: e3) +asset e1.js X KiB [emitted] (name: e1) +asset 471.js X bytes [emitted] +asset 752.js X bytes [emitted] +asset 637.js X bytes [emitted] +asset 371.js X bytes [emitted] +asset 852.js X bytes [emitted] +asset 18.js X bytes [emitted] +chunk (runtime: e1) 18.js X bytes [rendered] + ./async1.js X bytes [built] [code generated] +chunk (runtime: e2) e2.js (e2) X bytes (javascript) X KiB (runtime) [entry] [rendered] + runtime modules X KiB 9 modules + cacheable modules X bytes + ./b.js X bytes [dependent] [built] [code generated] + ./e2.js + 2 modules X bytes [built] [code generated] + ./f.js X bytes [dependent] [built] [code generated] +chunk (runtime: e1) e1.js (e1) X bytes (javascript) X KiB (runtime) [entry] [rendered] + runtime modules X KiB 9 modules + cacheable modules X bytes + ./b.js X bytes [dependent] [built] [code generated] + ./d.js X bytes [dependent] [built] [code generated] + ./e1.js + 2 modules X bytes [built] [code generated] +chunk (runtime: e3) 371.js X bytes [rendered] + ./async3.js X bytes [built] [code generated] +chunk (runtime: e1, e3) 471.js X bytes [rendered] + ./async2.js X bytes [built] [code generated] + ./f.js X bytes [dependent] [built] [code generated] +chunk (runtime: e2, e3) 637.js X bytes [rendered] + ./async1.js X bytes [built] [code generated] + ./d.js X bytes [dependent] [built] [code generated] +chunk (runtime: e1, e2) 752.js X bytes [rendered] + ./async3.js X bytes [built] [code generated] + ./h.js X bytes [dependent] [built] [code generated] +chunk (runtime: e2) 852.js X bytes [rendered] + ./async2.js X bytes [built] [code generated] +chunk (runtime: e3) e3.js (e3) X bytes (javascript) X KiB (runtime) [entry] [rendered] + runtime modules X KiB 9 modules + cacheable modules X bytes + ./b.js X bytes [dependent] [built] [code generated] + ./e3.js + 2 modules X bytes [built] [code generated] + ./h.js X bytes [dependent] [built] [code generated] +webpack x.x.x compiled successfully" +`; + +exports[`StatsTestCases should print correct stats for module-deduplication-named 1`] = ` +"asset e2.js X KiB [emitted] (name: e2) +asset e1.js X KiB [emitted] (name: e1) +asset e3.js X KiB [emitted] (name: e3) +asset async1.js X bytes [emitted] (name: async1) +asset async2.js X bytes [emitted] (name: async2) +asset async3.js X bytes [emitted] (name: async3) +chunk (runtime: e1, e2, e3) async3.js (async3) X bytes [rendered] + ./async3.js X bytes [built] [code generated] + ./h.js X bytes [dependent] [built] [code generated] +chunk (runtime: e2) e2.js (e2) X bytes (javascript) X KiB (runtime) [entry] [rendered] + runtime modules X KiB 9 modules + cacheable modules X bytes + ./b.js X bytes [dependent] [built] [code generated] + ./e2.js + 2 modules X bytes [built] [code generated] + ./f.js X bytes [dependent] [built] [code generated] +chunk (runtime: e1, e2, e3) async1.js (async1) X bytes [rendered] + ./async1.js X bytes [built] [code generated] + ./d.js X bytes [dependent] [built] [code generated] +chunk (runtime: e1) e1.js (e1) X bytes (javascript) X KiB (runtime) [entry] [rendered] + runtime modules X KiB 9 modules + cacheable modules X bytes + ./b.js X bytes [dependent] [built] [code generated] + ./d.js X bytes [dependent] [built] [code generated] + ./e1.js + 2 modules X bytes [built] [code generated] +chunk (runtime: e1, e2, e3) async2.js (async2) X bytes [rendered] + ./async2.js X bytes [built] [code generated] + ./f.js X bytes [dependent] [built] [code generated] +chunk (runtime: e3) e3.js (e3) X bytes (javascript) X KiB (runtime) [entry] [rendered] + runtime modules X KiB 9 modules + cacheable modules X bytes + ./b.js X bytes [dependent] [built] [code generated] + ./e3.js + 2 modules X bytes [built] [code generated] + ./h.js X bytes [dependent] [built] [code generated] +webpack x.x.x compiled successfully" +`; + +exports[`StatsTestCases should print correct stats for module-federation-custom-exposed-module-name 1`] = ` +"asset container_bundle.js X KiB [emitted] (name: container) +asset custom-entry_bundle.js X bytes [emitted] (name: custom-entry) +asset main_bundle.js X bytes [emitted] (name: main) +runtime modules X KiB 9 modules +built modules X bytes [built] + ./index.js X bytes [built] [code generated] + container entry X bytes [built] [code generated] + ./entry.js X bytes [built] [code generated] +webpack x.x.x compiled successfully in X ms" +`; + +exports[`StatsTestCases should print correct stats for module-not-found-error 1`] = ` +"ERROR in ./index.js 1:0-17 +Module not found: Error: Can't resolve 'buffer' in 'Xdir/module-not-found-error' + +BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default. +This is no longer the case. Verify if you need this module and configure a polyfill for it. + +If you want to include a polyfill, you need to: + - add a fallback 'resolve.fallback: { \\"buffer\\": require.resolve(\\"buffer/\\") }' + - install 'buffer' +If you don't want to include a polyfill, you can use an empty module like this: + resolve.fallback: { \\"buffer\\": false } + +ERROR in ./index.js 2:0-13 +Module not found: Error: Can't resolve 'os' in 'Xdir/module-not-found-error' + +BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default. +This is no longer the case. Verify if you need this module and configure a polyfill for it. + +If you want to include a polyfill, you need to: + - add a fallback 'resolve.fallback: { \\"os\\": require.resolve(\\"os-browserify/browser\\") }' + - install 'os-browserify' +If you don't want to include a polyfill, you can use an empty module like this: + resolve.fallback: { \\"os\\": false } + +webpack compiled with 2 errors" +`; + +exports[`StatsTestCases should print correct stats for module-reasons 1`] = ` +"asset main.js X KiB [emitted] (name: main) +orphan modules X bytes [orphan] 2 modules +cacheable modules X bytes + ./index.js + 2 modules X bytes [built] [code generated] + entry ./index main + ./c.js X bytes [built] [code generated] + cjs require ./c ./index.js + 2 modules ./a.js 1:0-14 + cjs require ./c ./index.js + 2 modules ./b.js 1:0-14 +webpack x.x.x compiled successfully in X ms" +`; + +exports[`StatsTestCases should print correct stats for module-trace-disabled-in-error 1`] = ` +"assets by status X KiB [cached] 1 asset +./index.js X bytes [built] [code generated] +./inner.js X bytes [built] [code generated] +./not-existing.js X bytes [built] [code generated] +./parse-error.js X bytes [built] [code generated] [1 error] + +ERROR in ./not-existing.js 1:0-25 +Module not found: Error: Can't resolve 'does-not-exist' in 'Xdir/module-trace-disabled-in-error' + +ERROR in ./parse-error.js 3:4 +Module parse failed: Unexpected token (3:4) +You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders +| Here +| could +> be :) +| your +| code + +webpack x.x.x compiled with 2 errors in X ms" +`; + +exports[`StatsTestCases should print correct stats for module-trace-enabled-in-error 1`] = ` +"assets by status X KiB [cached] 1 asset +./index.js X bytes [built] [code generated] +./inner.js X bytes [built] [code generated] +./not-existing.js X bytes [built] [code generated] +./parse-error.js X bytes [built] [code generated] [1 error] + +ERROR in ./not-existing.js 1:0-25 +Module not found: Error: Can't resolve 'does-not-exist' in 'Xdir/module-trace-enabled-in-error' + @ ./inner.js 1:0-25 + @ ./index.js 1:0-18 + +ERROR in ./parse-error.js 3:4 +Module parse failed: Unexpected token (3:4) +You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders +| Here +| could +> be :) +| your +| code + @ ./inner.js 2:0-24 + @ ./index.js 1:0-18 + +webpack x.x.x compiled with 2 errors in X ms" +`; + +exports[`StatsTestCases should print correct stats for name 1`] = ` +"./app.js: + asset bundle1.js X bytes [emitted] (name: main) + ./app.js X bytes [built] [code generated] + Xdir/name/app.js (webpack x.x.x) compiled successfully in X ms + +./server.js: + asset bundle2.js X bytes [emitted] (name: main) + ./server.js X bytes [built] [code generated] + Xdir/name/server.js (webpack x.x.x) compiled successfully in X ms" +`; + +exports[`StatsTestCases should print correct stats for named-chunk-groups 1`] = ` +"Chunk Group main X KiB = a-main.js +Chunk Group async-a X KiB = a-48.js X bytes a-async-a.js X bytes +Chunk Group async-b X KiB = a-48.js X bytes a-async-b.js X bytes +Chunk Group async-c X KiB = a-vendors.js X bytes a-async-c.js X bytes +chunk (runtime: main) a-48.js X bytes [rendered] split chunk (cache group: default) + > ./a ./index.js 1:0-47 + > ./b ./index.js 2:0-47 + ./shared.js X bytes [built] [code generated] +chunk (runtime: main) a-async-b.js (async-b) X bytes [rendered] + > ./b ./index.js 2:0-47 + ./b.js X bytes [built] [code generated] +chunk (runtime: main) a-vendors.js (vendors) (id hint: vendors) X bytes [rendered] split chunk (cache group: vendors) (name: vendors) + > ./c ./index.js 3:0-47 + ./node_modules/x.js X bytes [built] [code generated] + ./node_modules/y.js X bytes [built] [code generated] +chunk (runtime: main) a-async-a.js (async-a) X bytes [rendered] + > ./a ./index.js 1:0-47 + ./a.js X bytes [built] [code generated] +chunk (runtime: main) a-main.js (main) X bytes (javascript) X KiB (runtime) [entry] [rendered] + > ./ main + runtime modules X KiB 10 modules + ./index.js X bytes [built] [code generated] +chunk (runtime: main) a-async-c.js (async-c) X bytes [rendered] + > ./c ./index.js 3:0-47 + ./c.js X bytes [built] [code generated] +webpack x.x.x compiled successfully + +Entrypoint main X KiB = b-main.js +Chunk Group async-a X KiB = b-48.js X bytes b-async-a.js X bytes +Chunk Group async-b X KiB = b-48.js X bytes b-async-b.js X bytes +Chunk Group async-c X KiB = b-vendors.js X bytes b-async-c.js X bytes +chunk (runtime: main) b-48.js X bytes [rendered] split chunk (cache group: default) + > ./a ./index.js 1:0-47 + > ./b ./index.js 2:0-47 + ./shared.js X bytes [built] [code generated] +chunk (runtime: main) b-async-b.js (async-b) X bytes [rendered] + > ./b ./index.js 2:0-47 + ./b.js X bytes [built] [code generated] +chunk (runtime: main) b-vendors.js (vendors) (id hint: vendors) X bytes [rendered] split chunk (cache group: vendors) (name: vendors) + > ./c ./index.js 3:0-47 + ./node_modules/x.js X bytes [built] [code generated] + ./node_modules/y.js X bytes [built] [code generated] +chunk (runtime: main) b-async-a.js (async-a) X bytes [rendered] + > ./a ./index.js 1:0-47 + ./a.js X bytes [built] [code generated] +chunk (runtime: main) b-main.js (main) X bytes (javascript) X KiB (runtime) [entry] [rendered] + > ./ main + runtime modules X KiB 10 modules + ./index.js X bytes [built] [code generated] +chunk (runtime: main) b-async-c.js (async-c) X bytes [rendered] + > ./c ./index.js 3:0-47 + ./c.js X bytes [built] [code generated] +webpack x.x.x compiled successfully" +`; + +exports[`StatsTestCases should print correct stats for named-chunks-plugin 1`] = ` +"asset entry.js X KiB [emitted] (name: entry) +asset vendor.js X bytes [emitted] (name: vendor) (id hint: vendor) +Entrypoint entry X KiB = vendor.js X bytes entry.js X KiB +runtime modules X KiB 3 modules +cacheable modules X bytes + ./entry.js X bytes [built] [code generated] + ./modules/a.js X bytes [built] [code generated] + ./modules/b.js X bytes [built] [code generated] + ./modules/c.js X bytes [built] [code generated] +webpack x.x.x compiled successfully in X ms" +`; + +exports[`StatsTestCases should print correct stats for named-chunks-plugin-async 1`] = ` +"asset entry.js X KiB [emitted] (name: entry) +asset modules_a_js.js X bytes [emitted] +asset modules_b_js.js X bytes [emitted] +runtime modules X KiB 10 modules +cacheable modules X bytes + ./entry.js X bytes [built] [code generated] + ./modules/a.js X bytes [built] [code generated] + ./modules/b.js X bytes [built] [code generated] +webpack x.x.x compiled successfully in X ms" +`; + +exports[`StatsTestCases should print correct stats for no-emit-on-errors-plugin-with-child-error 1`] = ` +"assets by status X bytes [cached] 2 assets +./index.js X bytes [built] [code generated] + +WARNING in configuration +The 'mode' option has not been set, webpack will fallback to 'production' for this value. +Set 'mode' option to 'development' or 'production' to enable defaults for each environment. +You can also set it to 'none' to disable any default behavior. Learn more: https://webpack.js.org/configuration/mode/ + +1 ERROR in child compilations (Use 'stats.children: true' resp. '--stats-children' for more details) +webpack x.x.x compiled with 1 error and 1 warning in X ms" +`; + +exports[`StatsTestCases should print correct stats for optimize-chunks 1`] = ` +"asset main.js X KiB {792} [emitted] (name: main) +asset cir2 from cir1.js X bytes {816}, {915} [emitted] (name: cir2 from cir1) +asset cir1.js X bytes {712} [emitted] (name: cir1) +asset cir2.js X bytes {915} [emitted] (name: cir2) +asset abd.js X bytes {470}, {518} [emitted] (name: abd) +asset chunk.js X bytes {125}, {982} [emitted] (name: chunk) +asset ab.js X bytes {470} [emitted] (name: ab) +asset ac in ab.js X bytes {125} [emitted] (name: ac in ab) +chunk {125} (runtime: main) ac in ab.js (ac in ab) X bytes <{470}> >{982}< [rendered] + > [237] ./index.js 2:1-5:15 + ./modules/c.js [494] X bytes {125} {982} [built] [code generated] +chunk {470} (runtime: main) ab.js (ab) X bytes <{792}> >{125}< [rendered] + > [237] ./index.js 1:0-6:8 + ./modules/a.js [36] X bytes {470} {518} [built] [code generated] + ./modules/b.js [618] X bytes {470} {518} [built] [code generated] +chunk {518} (runtime: main) abd.js (abd) X bytes <{792}> >{982}< [rendered] + > [237] ./index.js 8:0-11:9 + ./modules/a.js [36] X bytes {470} {518} [built] [code generated] + ./modules/b.js [618] X bytes {470} {518} [built] [code generated] + ./modules/d.js [503] X bytes {518} {982} [built] [code generated] +chunk {712} (runtime: main) cir1.js (cir1) X bytes <{792}> <{816}> <{915}> >{816}< [rendered] + > [237] ./index.js 13:0-54 + > [448] ./circular2.js 1:0-79 + ./circular1.js [985] X bytes {712} [built] [code generated] +chunk {792} (runtime: main) main.js (main) X bytes (javascript) X KiB (runtime) >{470}< >{518}< >{712}< >{915}< [entry] [rendered] + > ./index main + runtime modules X KiB 7 modules + cacheable modules X bytes + ./index.js [237] X bytes {792} [built] [code generated] + ./modules/f.js [633] X bytes {792} [dependent] [built] [code generated] +chunk {816} (runtime: main) cir2 from cir1.js (cir2 from cir1) X bytes <{712}> >{712}< [rendered] + > [985] ./circular1.js 1:0-79 + ./circular2.js [448] X bytes {816} {915} [built] [code generated] + ./modules/e.js [888] X bytes {816} [built] [code generated] +chunk {915} (runtime: main) cir2.js (cir2) X bytes <{792}> >{712}< [rendered] + > [237] ./index.js 14:0-54 + ./circular2.js [448] X bytes {816} {915} [built] [code generated] +chunk {982} (runtime: main) chunk.js (chunk) X bytes <{125}> <{518}> [rendered] + > [237] ./index.js 3:2-4:13 + > [237] ./index.js 9:1-10:12 + ./modules/c.js [494] X bytes {125} {982} [built] [code generated] + ./modules/d.js [503] X bytes {518} {982} [built] [code generated] +webpack x.x.x compiled successfully in X ms" +`; + +exports[`StatsTestCases should print correct stats for output-module 1`] = ` +"asset main.mjs X KiB [emitted] [javascript module] (name: main) +asset 936.mjs X bytes [emitted] [javascript module] +runtime modules X KiB 7 modules +orphan modules X bytes [orphan] 1 module +cacheable modules X bytes + ./index.js + 1 modules X bytes [built] [code generated] + ./chunk.js X bytes [built] [code generated] +webpack x.x.x compiled successfully in X ms" +`; + +exports[`StatsTestCases should print correct stats for parse-error 1`] = ` +"assets by status X KiB [cached] 1 asset +orphan modules X bytes [orphan] 1 module +./index.js + 1 modules X bytes [built] [code generated] +./b.js X bytes [built] [code generated] [1 error] + +ERROR in ./b.js 6:7 +Module parse failed: Unexpected token (6:7) +You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders +| includes +| a +> parser ) +| error +| in + @ ./a.js 2:0-13 + @ ./index.js 2:0-13 + +webpack x.x.x compiled with 1 error" +`; + +exports[`StatsTestCases should print correct stats for performance-different-mode-and-target 1`] = ` +"asset warning.pro-web.js X KiB [emitted] [big] (name: main) +./index.js X KiB [built] [code generated] + +WARNING in asset size limit: The following asset(s) exceed the recommended size limit (X KiB). +This can impact web performance. +Assets: + warning.pro-web.js (X KiB) + +WARNING in entrypoint size limit: The following entrypoint(s) combined asset size exceeds the recommended limit (X KiB). This can impact web performance. +Entrypoints: + main (X KiB) + warning.pro-web.js + +WARNING in webpack performance recommendations: +You can limit the size of your bundles by using import() or require.ensure to lazy load some parts of your application. +For more info visit https://webpack.js.org/guides/code-splitting/ + +webpack x.x.x compiled with 3 warnings in X ms + +asset warning.pro-webworker.js X KiB [emitted] [big] (name: main) +./index.js X KiB [built] [code generated] + +WARNING in asset size limit: The following asset(s) exceed the recommended size limit (X KiB). +This can impact web performance. +Assets: + warning.pro-webworker.js (X KiB) + +WARNING in entrypoint size limit: The following entrypoint(s) combined asset size exceeds the recommended limit (X KiB). This can impact web performance. +Entrypoints: + main (X KiB) + warning.pro-webworker.js + +WARNING in webpack performance recommendations: +You can limit the size of your bundles by using import() or require.ensure to lazy load some parts of your application. +For more info visit https://webpack.js.org/guides/code-splitting/ + +webpack x.x.x compiled with 3 warnings in X ms + +asset no-warning.pro-node.js X KiB [emitted] (name: main) +./index.js X KiB [built] [code generated] +webpack x.x.x compiled successfully in X ms + +asset no-warning.dev-web.js 1.72 MiB [emitted] (name: main) +./index.js X KiB [built] [code generated] +webpack x.x.x compiled successfully in X ms + +asset no-warning.dev-node.js 1.72 MiB [emitted] (name: main) +./index.js X KiB [built] [code generated] +webpack x.x.x compiled successfully in X ms + +asset no-warning.dev-web-with-limit-set.js 1.72 MiB [emitted] [big] (name: main) +./index.js X KiB [built] [code generated] +webpack x.x.x compiled successfully in X ms + +asset warning.pro-node-with-hints-set.js X KiB [emitted] [big] (name: main) +./index.js X KiB [built] [code generated] + +WARNING in asset size limit: The following asset(s) exceed the recommended size limit (X KiB). +This can impact web performance. +Assets: + warning.pro-node-with-hints-set.js (X KiB) + +WARNING in entrypoint size limit: The following entrypoint(s) combined asset size exceeds the recommended limit (X KiB). This can impact web performance. +Entrypoints: + main (X KiB) + warning.pro-node-with-hints-set.js + +WARNING in webpack performance recommendations: +You can limit the size of your bundles by using import() or require.ensure to lazy load some parts of your application. +For more info visit https://webpack.js.org/guides/code-splitting/ + +webpack x.x.x compiled with 3 warnings in X ms" +`; + +exports[`StatsTestCases should print correct stats for performance-disabled 1`] = ` +"asset main.js X KiB [emitted] (name: main) +asset 964.js X bytes [emitted] +asset 226.js X bytes [emitted] +asset 899.js X bytes [emitted] +Entrypoint main X KiB = main.js +runtime modules X KiB 7 modules +cacheable modules X KiB + ./index.js X bytes [built] [code generated] + ./a.js X KiB [built] [code generated] + ./b.js X bytes [built] [code generated] + ./c.js X bytes [built] [code generated] + ./d.js X bytes [built] [code generated] + ./e.js X bytes [built] [code generated] +webpack x.x.x compiled successfully in X ms" +`; + +exports[`StatsTestCases should print correct stats for performance-error 1`] = ` +"asset main.js X KiB [emitted] [big] (name: main) +asset 964.js X bytes [emitted] +asset 226.js X bytes [emitted] +asset 899.js X bytes [emitted] +Entrypoint main [big] X KiB = main.js +runtime modules X KiB 7 modules +cacheable modules X KiB + ./index.js X bytes [built] [code generated] + ./a.js X KiB [built] [code generated] + ./b.js X bytes [built] [code generated] + ./c.js X bytes [built] [code generated] + ./d.js X bytes [built] [code generated] + ./e.js X bytes [built] [code generated] + +ERROR in asset size limit: The following asset(s) exceed the recommended size limit (X KiB). +This can impact web performance. +Assets: + main.js (X KiB) + +ERROR in entrypoint size limit: The following entrypoint(s) combined asset size exceeds the recommended limit (X KiB). This can impact web performance. +Entrypoints: + main (X KiB) + main.js + + +webpack x.x.x compiled with 2 errors in X ms" +`; + +exports[`StatsTestCases should print correct stats for performance-no-async-chunks-shown 1`] = ` +"asset main.js X KiB [emitted] [big] (name: main) +asset sec.js X KiB [emitted] (name: sec) +Entrypoint main [big] X KiB = main.js +Entrypoint sec X KiB = sec.js +./index.js X bytes [built] [code generated] +./index2.js X bytes [built] [code generated] +./a.js X KiB [built] [code generated] +./b.js X bytes [built] [code generated] +./c.js X bytes [built] [code generated] +./d.js X bytes [built] [code generated] + +WARNING in asset size limit: The following asset(s) exceed the recommended size limit (X KiB). +This can impact web performance. +Assets: + main.js (X KiB) + +WARNING in entrypoint size limit: The following entrypoint(s) combined asset size exceeds the recommended limit (X KiB). This can impact web performance. +Entrypoints: + main (X KiB) + main.js + + +WARNING in webpack performance recommendations: +You can limit the size of your bundles by using import() or require.ensure to lazy load some parts of your application. +For more info visit https://webpack.js.org/guides/code-splitting/ + +webpack x.x.x compiled with 3 warnings in X ms" +`; + +exports[`StatsTestCases should print correct stats for performance-no-hints 1`] = ` +"asset main.js X KiB [emitted] [big] (name: main) +asset 964.js X bytes [emitted] +asset 226.js X bytes [emitted] +asset 899.js X bytes [emitted] +Entrypoint main [big] X KiB = main.js +runtime modules X KiB 7 modules +cacheable modules X KiB + ./index.js X bytes [built] [code generated] + ./a.js X KiB [built] [code generated] + ./b.js X bytes [built] [code generated] + ./c.js X bytes [built] [code generated] + ./d.js X bytes [built] [code generated] + ./e.js X bytes [built] [code generated] +webpack x.x.x compiled successfully in X ms" +`; + +exports[`StatsTestCases should print correct stats for performance-oversize-limit-error 1`] = ` +"asset main.js X KiB [emitted] [big] (name: main) +asset sec.js X KiB [emitted] [big] (name: sec) +Entrypoint main [big] X KiB = main.js +Entrypoint sec [big] X KiB = sec.js +./index.js X bytes [built] [code generated] +./index2.js X bytes [built] [code generated] +./a.js X KiB [built] [code generated] + +ERROR in asset size limit: The following asset(s) exceed the recommended size limit (X KiB). +This can impact web performance. +Assets: + main.js (X KiB) + sec.js (X KiB) + +ERROR in entrypoint size limit: The following entrypoint(s) combined asset size exceeds the recommended limit (X KiB). This can impact web performance. +Entrypoints: + main (X KiB) + main.js + sec (X KiB) + sec.js + + +ERROR in webpack performance recommendations: +You can limit the size of your bundles by using import() or require.ensure to lazy load some parts of your application. +For more info visit https://webpack.js.org/guides/code-splitting/ + +webpack x.x.x compiled with 3 errors in X ms" +`; + +exports[`StatsTestCases should print correct stats for prefetch 1`] = ` +"asset main.js X KiB {792} [emitted] (name: main) +asset prefetched.js X bytes {529} [emitted] (name: prefetched) +asset inner2.js X bytes {573} [emitted] (name: inner2) +asset inner.js X bytes {253} [emitted] (name: inner) +asset normal.js X bytes {574} [emitted] (name: normal) +asset prefetched2.js X bytes {337} [emitted] (name: prefetched2) +asset prefetched3.js X bytes {528} [emitted] (name: prefetched3) +Entrypoint main X KiB = main.js + prefetch: prefetched2.js {337} (name: prefetched2), prefetched.js {529} (name: prefetched), prefetched3.js {528} (name: prefetched3) +chunk {253} (runtime: main) inner.js (inner) X bytes <{529}> [rendered] +chunk {337} (runtime: main) prefetched2.js (prefetched2) X bytes <{792}> [rendered] +chunk {528} (runtime: main) prefetched3.js (prefetched3) X bytes <{792}> [rendered] +chunk {529} (runtime: main) prefetched.js (prefetched) X bytes <{792}> >{253}< >{573}< (prefetch: {573} {253}) [rendered] +chunk {573} (runtime: main) inner2.js (inner2) X bytes <{529}> [rendered] +chunk {574} (runtime: main) normal.js (normal) X bytes <{792}> [rendered] +chunk {792} (runtime: main) main.js (main) X bytes (javascript) X KiB (runtime) >{337}< >{528}< >{529}< >{574}< (prefetch: {337} {529} {528}) [entry] [rendered]" +`; + +exports[`StatsTestCases should print correct stats for prefetch-preload-mixed 1`] = ` +"chunk (runtime: main) a2.js (a2) X bytes <{996}> [rendered] +chunk (runtime: main) b.js (b) X bytes <{792}> >{364}< >{567}< >{758}< (prefetch: {364} {758}) (preload: {567}) [rendered] +chunk (runtime: main) a1.js (a1) X bytes <{996}> [rendered] +chunk (runtime: main) b1.js (b1) X bytes <{199}> [rendered] +chunk (runtime: main) c.js (c) X bytes <{792}> >{896}< >{907}< (preload: {907} {896}) [rendered] +chunk (runtime: main) b2.js (b2) X bytes <{199}> [rendered] +chunk (runtime: main) b3.js (b3) X bytes <{199}> [rendered] +chunk (runtime: main) main.js (main) X bytes (javascript) X KiB (runtime) >{199}< >{390}< >{996}< (prefetch: {996} {199} {390}) [entry] [rendered] +chunk (runtime: main) c2.js (c2) X bytes <{390}> [rendered] +chunk (runtime: main) c1.js (c1) X bytes <{390}> [rendered] +chunk (runtime: main) a.js (a) X bytes <{792}> >{150}< >{341}< (prefetch: {341} {150}) [rendered]" +`; + +exports[`StatsTestCases should print correct stats for preload 1`] = ` +"asset main.js X KiB [emitted] (name: main) +asset preloaded.js X bytes [emitted] (name: preloaded) +asset inner2.js X bytes [emitted] (name: inner2) +asset inner.js X bytes [emitted] (name: inner) +asset normal.js X bytes [emitted] (name: normal) +asset preloaded3.js X bytes [emitted] (name: preloaded3) +asset preloaded2.js X bytes [emitted] (name: preloaded2) +Entrypoint main X KiB = main.js + preload: preloaded2.js (name: preloaded2), preloaded.js (name: preloaded), preloaded3.js (name: preloaded3) +chunk (runtime: main) preloaded.js (preloaded) X bytes (preload: {573} {253}) [rendered] +chunk (runtime: main) inner.js (inner) X bytes [rendered] +chunk (runtime: main) preloaded2.js (preloaded2) X bytes [rendered] +chunk (runtime: main) inner2.js (inner2) X bytes [rendered] +chunk (runtime: main) normal.js (normal) X bytes [rendered] +chunk (runtime: main) preloaded3.js (preloaded3) X bytes [rendered] +chunk (runtime: main) main.js (main) X bytes (javascript) X KiB (runtime) (preload: {485} {165} {676}) [entry] [rendered]" +`; + +exports[`StatsTestCases should print correct stats for preset-detailed 1`] = ` +"<-> [LogTestPlugin] Group + [LogTestPlugin] Error + [LogTestPlugin] Warning + [LogTestPlugin] Info + [LogTestPlugin] Log + <+> [LogTestPlugin] Collapsed group + [LogTestPlugin] Log + [LogTestPlugin] End +PublicPath: auto +asset main.js X KiB {792} [emitted] (name: main) +asset 964.js X bytes {964} [emitted] +asset 226.js X bytes {226} [emitted] +asset 899.js X bytes {899} [emitted] +Entrypoint main X KiB = main.js +chunk {226} (runtime: main) 226.js X bytes <{964}> [rendered] + > [964] ./c.js 1:0-52 +chunk {792} (runtime: main) main.js (main) X bytes (javascript) X KiB (runtime) >{899}< >{964}< [entry] [rendered] + > ./index main +chunk {899} (runtime: main) 899.js X bytes <{792}> [rendered] + > ./b [237] ./index.js 2:0-16 +chunk {964} (runtime: main) 964.js X bytes <{792}> >{226}< [rendered] + > ./c [237] ./index.js 3:0-16 +runtime modules X KiB + webpack/runtime/ensure chunk X bytes {792} [code generated] + [no exports] + [used exports unknown] + webpack/runtime/get javascript chunk filename X bytes {792} [code generated] + [no exports] + [used exports unknown] + webpack/runtime/global X bytes {792} [code generated] + [no exports] + [used exports unknown] + webpack/runtime/hasOwnProperty shorthand X bytes {792} [code generated] + [no exports] + [used exports unknown] + webpack/runtime/jsonp chunk loading X KiB {792} [code generated] + [no exports] + [used exports unknown] + webpack/runtime/load script X KiB {792} [code generated] + [no exports] + [used exports unknown] + webpack/runtime/publicPath X bytes {792} [code generated] + [no exports] + [used exports unknown] +cacheable modules X bytes + ./index.js [237] X bytes {792} [depth 0] [built] [code generated] + [no exports used] + Statement (ExpressionStatement) with side effects in source code at 1:0-15 + ModuleConcatenation bailout: Module is not an ECMAScript module + ./a.js [670] X bytes {792} [depth 1] [built] [code generated] + [used exports unknown] + CommonJS bailout: module.exports is used directly at 1:0-14 + Statement (ExpressionStatement) with side effects in source code at 1:0-21 + ModuleConcatenation bailout: Module is not an ECMAScript module + ./b.js [899] X bytes {899} [depth 1] [built] [code generated] + [used exports unknown] + CommonJS bailout: module.exports is used directly at 1:0-14 + Statement (ExpressionStatement) with side effects in source code at 1:0-21 + ModuleConcatenation bailout: Module is not an ECMAScript module + ./c.js [964] X bytes {964} [depth 1] [built] [code generated] + [used exports unknown] + Statement (ExpressionStatement) with side effects in source code at 1:0-53 + ModuleConcatenation bailout: Module is not an ECMAScript module + ./d.js [425] X bytes {226} [depth 2] [built] [code generated] + [used exports unknown] + CommonJS bailout: module.exports is used directly at 1:0-14 + Statement (ExpressionStatement) with side effects in source code at 1:0-21 + ModuleConcatenation bailout: Module is not an ECMAScript module + ./e.js [210] X bytes {226} [depth 2] [built] [code generated] + [used exports unknown] + CommonJS bailout: module.exports is used directly at 1:0-14 + Statement (ExpressionStatement) with side effects in source code at 1:0-21 + ModuleConcatenation bailout: Module is not an ECMAScript module + +LOG from LogTestPlugin +<-> Group + Error + Warning + Info + Log + <+> Collapsed group + Log + End ++ 6 hidden lines + +LOG from webpack.Compilation + 6 modules hashed, 0 from cache (1 variants per module in average) + 100% code generated (6 generated, 0 from cache) + 100% code generated (7 generated, 0 from cache) ++ 24 hidden lines + +LOG from webpack.FlagDependencyExportsPlugin + 0% of exports of modules have been determined (6 no declared exports, 0 not cached, 0 flagged uncacheable, 0 from cache, 0 from mem cache, 0 additional calculations due to dependencies) ++ 3 hidden lines + +LOG from webpack.buildChunkGraph + 15 queue items processed (9 blocks) + 3 chunk groups connected + 3 chunk groups processed for merging (3 module sets, 0 forked, 0 + 0 modules forked, 0 + 0 modules merged into fork, 0 resulting modules) + 3 chunk group info updated (0 already connected chunk groups reconnected) ++ 15 hidden lines + +LOG from webpack.FileSystemInfo + 6 new snapshots created + 0% root snapshot uncached (0 / 0) + 0% children snapshot uncached (0 / 0) + 0 entries tested + File info in cache: 6 timestamps 6 hashes 6 timestamp hash combinations + File timestamp hash combination snapshot optimization: 0% (0/6) entries shared via 0 shared snapshots (0 times referenced) + Directory info in cache: 0 timestamps 0 hashes 0 timestamp hash combinations + Managed items info in cache: 0 items + +1970-04-20 12:42:42: webpack x.x.x compiled successfully in X ms (XXXXXXXXXXXXXXXXXXXX)" +`; + +exports[`StatsTestCases should print correct stats for preset-errors-only 1`] = `""`; + +exports[`StatsTestCases should print correct stats for preset-errors-only-error 1`] = ` +" [LogTestPlugin] Error +LOG from LogTestPlugin + Error ++ 14 hidden lines + +ERROR in ./index.js 1:0-25 +Module not found: Error: Can't resolve 'does-not-exist' in 'Xdir/preset-errors-only-error' + +webpack compiled with 1 error" +`; + +exports[`StatsTestCases should print correct stats for preset-errors-warnings 1`] = ` +" [LogTestPlugin] Error + [LogTestPlugin] Warning +LOG from LogTestPlugin + Error + Warning ++ 13 hidden lines + +webpack compiled successfully" +`; + +exports[`StatsTestCases should print correct stats for preset-minimal 1`] = ` +" [LogTestPlugin] Error + [LogTestPlugin] Warning +4 assets +13 modules + +LOG from LogTestPlugin + Error + Warning ++ 13 hidden lines + +webpack x.x.x compiled successfully in X ms" +`; + +exports[`StatsTestCases should print correct stats for preset-minimal-simple 1`] = ` +"1 asset +1 module +webpack x.x.x compiled successfully in X ms" +`; + +exports[`StatsTestCases should print correct stats for preset-mixed-array 1`] = ` +"minimal: + 1 asset + 1 module + minimal (webpack x.x.x) compiled successfully in X ms + +verbose: + Entrypoint main X bytes = verbose.js + ./index.js X bytes [built] [code generated] + verbose (webpack x.x.x) compiled successfully" +`; + +exports[`StatsTestCases should print correct stats for preset-none 1`] = ` +" [LogTestPlugin] Error + [LogTestPlugin] Warning + [LogTestPlugin] Info +" +`; + +exports[`StatsTestCases should print correct stats for preset-none-array 1`] = `""`; + +exports[`StatsTestCases should print correct stats for preset-none-error 1`] = `""`; + +exports[`StatsTestCases should print correct stats for preset-normal 1`] = ` +" [LogTestPlugin] Error + [LogTestPlugin] Warning + [LogTestPlugin] Info +asset main.js X KiB [emitted] (name: main) +asset 964.js X bytes [emitted] +asset 226.js X bytes [emitted] +asset 899.js X bytes [emitted] +runtime modules X KiB 7 modules +cacheable modules X bytes + ./index.js X bytes [built] [code generated] + ./a.js X bytes [built] [code generated] + ./b.js X bytes [built] [code generated] + ./c.js X bytes [built] [code generated] + ./d.js X bytes [built] [code generated] + ./e.js X bytes [built] [code generated] + +LOG from LogTestPlugin + Error + Warning + Info ++ 12 hidden lines + +webpack x.x.x compiled successfully in X ms" +`; + +exports[`StatsTestCases should print correct stats for preset-normal-performance 1`] = ` +"asset main.js X KiB [emitted] [big] (name: main) +asset 964.js X bytes [emitted] +asset 226.js X bytes [emitted] +asset 899.js X bytes [emitted] +runtime modules X KiB 7 modules +cacheable modules X KiB + ./index.js X bytes [built] [code generated] + ./a.js X KiB [built] [code generated] + ./b.js X bytes [built] [code generated] + ./c.js X bytes [built] [code generated] + ./d.js X bytes [built] [code generated] + ./e.js X bytes [built] [code generated] + +WARNING in asset size limit: The following asset(s) exceed the recommended size limit (X KiB). +This can impact web performance. +Assets: + main.js (X KiB) + +WARNING in entrypoint size limit: The following entrypoint(s) combined asset size exceeds the recommended limit (X KiB). This can impact web performance. +Entrypoints: + main (X KiB) + main.js + + +webpack x.x.x compiled with 2 warnings in X ms" +`; + +exports[`StatsTestCases should print correct stats for preset-normal-performance-ensure-filter-sourcemaps 1`] = ` +"asset main.js X KiB [emitted] [big] (name: main) 1 related asset +asset 964.js X bytes [emitted] 1 related asset +asset 226.js X bytes [emitted] 1 related asset +asset 899.js X bytes [emitted] 1 related asset +runtime modules X KiB 7 modules +cacheable modules X KiB + ./index.js X bytes [built] [code generated] + ./a.js X KiB [built] [code generated] + ./b.js X bytes [built] [code generated] + ./c.js X bytes [built] [code generated] + ./d.js X bytes [built] [code generated] + ./e.js X bytes [built] [code generated] + +WARNING in asset size limit: The following asset(s) exceed the recommended size limit (X KiB). +This can impact web performance. +Assets: + main.js (X KiB) + +WARNING in entrypoint size limit: The following entrypoint(s) combined asset size exceeds the recommended limit (X KiB). This can impact web performance. +Entrypoints: + main (X KiB) + main.js + + +webpack x.x.x compiled with 2 warnings in X ms" +`; + +exports[`StatsTestCases should print correct stats for preset-summary 1`] = ` +" [LogTestPlugin] Error + [LogTestPlugin] Warning + [LogTestPlugin] Info +webpack x.x.x compiled successfully" +`; + +exports[`StatsTestCases should print correct stats for preset-verbose 1`] = ` +"<-> [LogTestPlugin] Group + [LogTestPlugin] Error + [LogTestPlugin] Warning + [LogTestPlugin] Info + [LogTestPlugin] Log + <-> [LogTestPlugin] Collapsed group + [LogTestPlugin] Log inside collapsed group + <-> [LogTestPlugin] Inner group + [LogTestPlugin] Inner inner message + [LogTestPlugin] Log + [LogTestPlugin] End +PublicPath: auto +asset main.js X KiB {792} [emitted] (name: main) +asset 964.js X bytes {964} [emitted] +asset 226.js X bytes {226} [emitted] +asset 899.js X bytes {899} [emitted] +Entrypoint main X KiB = main.js +chunk {226} (runtime: main) 226.js X bytes <{964}> [rendered] + > [964] ./c.js 1:0-52 + ./d.js [425] X bytes {226} [depth 2] [built] [code generated] + [used exports unknown] + CommonJS bailout: module.exports is used directly at 1:0-14 + Statement (ExpressionStatement) with side effects in source code at 1:0-21 + ModuleConcatenation bailout: Module is not an ECMAScript module + require.ensure item ./d [964] ./c.js 1:0-52 + cjs self exports reference [425] ./d.js 1:0-14 + X ms [237] -> X ms [964] -> + X ms (resolving: X ms, restoring: X ms, integration: X ms, building: X ms, storing: X ms) + ./e.js [210] X bytes {226} [depth 2] [built] [code generated] + [used exports unknown] + CommonJS bailout: module.exports is used directly at 1:0-14 + Statement (ExpressionStatement) with side effects in source code at 1:0-21 + ModuleConcatenation bailout: Module is not an ECMAScript module + require.ensure item ./e [964] ./c.js 1:0-52 + cjs self exports reference [210] ./e.js 1:0-14 + X ms [237] -> X ms [964] -> + X ms (resolving: X ms, restoring: X ms, integration: X ms, building: X ms, storing: X ms) +chunk {792} (runtime: main) main.js (main) X bytes (javascript) X KiB (runtime) >{899}< >{964}< [entry] [rendered] + > ./index main + runtime modules X KiB + webpack/runtime/ensure chunk X bytes {792} [code generated] + [no exports] + [used exports unknown] + webpack/runtime/get javascript chunk filename X bytes {792} [code generated] + [no exports] + [used exports unknown] + webpack/runtime/global X bytes {792} [code generated] + [no exports] + [used exports unknown] + webpack/runtime/hasOwnProperty shorthand X bytes {792} [code generated] + [no exports] + [used exports unknown] + webpack/runtime/jsonp chunk loading X KiB {792} [code generated] + [no exports] + [used exports unknown] + webpack/runtime/load script X KiB {792} [code generated] + [no exports] + [used exports unknown] + webpack/runtime/publicPath X bytes {792} [code generated] + [no exports] + [used exports unknown] + cacheable modules X bytes + ./a.js [670] X bytes {792} [depth 1] [dependent] [built] [code generated] + [used exports unknown] + CommonJS bailout: module.exports is used directly at 1:0-14 + Statement (ExpressionStatement) with side effects in source code at 1:0-21 + ModuleConcatenation bailout: Module is not an ECMAScript module + cjs self exports reference [670] ./a.js 1:0-14 + cjs require ./a [237] ./index.js 1:0-14 + X ms [237] -> + X ms (resolving: X ms, restoring: X ms, integration: X ms, building: X ms, storing: X ms) + ./index.js [237] X bytes {792} [depth 0] [built] [code generated] + [no exports used] + Statement (ExpressionStatement) with side effects in source code at 1:0-15 + ModuleConcatenation bailout: Module is not an ECMAScript module + entry ./index main + X ms (resolving: X ms, restoring: X ms, integration: X ms, building: X ms, storing: X ms) +chunk {899} (runtime: main) 899.js X bytes <{792}> [rendered] + > ./b [237] ./index.js 2:0-16 + ./b.js [899] X bytes {899} [depth 1] [built] [code generated] + [used exports unknown] + CommonJS bailout: module.exports is used directly at 1:0-14 + Statement (ExpressionStatement) with side effects in source code at 1:0-21 + ModuleConcatenation bailout: Module is not an ECMAScript module + cjs self exports reference [899] ./b.js 1:0-14 + amd require ./b [237] ./index.js 2:0-16 + X ms [237] -> + X ms (resolving: X ms, restoring: X ms, integration: X ms, building: X ms, storing: X ms) +chunk {964} (runtime: main) 964.js X bytes <{792}> >{226}< [rendered] + > ./c [237] ./index.js 3:0-16 + ./c.js [964] X bytes {964} [depth 1] [built] [code generated] + [used exports unknown] + Statement (ExpressionStatement) with side effects in source code at 1:0-53 + ModuleConcatenation bailout: Module is not an ECMAScript module + amd require ./c [237] ./index.js 3:0-16 + X ms [237] -> + X ms (resolving: X ms, restoring: X ms, integration: X ms, building: X ms, storing: X ms) + + +LOG from LogTestPlugin +<-> Group + Error + Warning + Info + Log + <-> Collapsed group + Log inside collapsed group + <-> Inner group + Inner inner message + Log + End ++ 1 hidden lines + +LOG from webpack.Compiler + make hook: X ms + finish make hook: X ms + finish compilation: X ms + seal compilation: X ms + afterCompile hook: X ms + emitAssets: X ms + emitRecords: X ms + done hook: X ms + beginIdle: X ms + +LOG from webpack.Compilation + finish module profiles: X ms + compute affected modules: X ms + finish modules: X ms + report dependency errors and warnings: X ms + optimize dependencies: X ms + create chunks: X ms + compute affected modules with chunk graph: X ms + optimize: X ms + 6 modules hashed, 0 from cache (1 variants per module in average) + module hashing: X ms + 100% code generated (6 generated, 0 from cache) + code generation: X ms + runtime requirements.modules: X ms + runtime requirements.chunks: X ms + runtime requirements.entries: X ms + runtime requirements: X ms + hashing: initialize hash: X ms + hashing: sort chunks: X ms + hashing: hash runtime modules: X ms + hashing: hash chunks: X ms + hashing: hash digest: X ms + hashing: process full hash modules: X ms + hashing: X ms + 100% code generated (7 generated, 0 from cache) + record hash: X ms + module assets: X ms + create chunk assets: X ms + process assets: X ms + +LOG from webpack.FlagDependencyExportsPlugin + restore cached provided exports: X ms + figure out provided exports: X ms + 0% of exports of modules have been determined (6 no declared exports, 0 not cached, 0 flagged uncacheable, 0 from cache, 0 from mem cache, 0 additional calculations due to dependencies) + store provided exports into cache: X ms + +LOG from webpack.InnerGraphPlugin + infer dependency usage: X ms + +LOG from webpack.SideEffectsFlagPlugin + update dependencies: X ms + +LOG from webpack.FlagDependencyUsagePlugin + initialize exports usage: X ms + trace exports usage in graph: X ms + +LOG from webpack.buildChunkGraph + visitModules: prepare: X ms + visitModules: visiting: X ms + visitModules: calculating available modules: X ms + visitModules: merging available modules: X ms + visitModules: check modules for revisit: X ms + visitModules: prepare: X ms + visitModules: visiting: X ms + visitModules: calculating available modules: X ms + visitModules: merging available modules: X ms + visitModules: check modules for revisit: X ms + visitModules: prepare: X ms + visitModules: visiting: X ms + 15 queue items processed (9 blocks) + 3 chunk groups connected + 3 chunk groups processed for merging (3 module sets, 0 forked, 0 + 0 modules forked, 0 + 0 modules merged into fork, 0 resulting modules) + 3 chunk group info updated (0 already connected chunk groups reconnected) + visitModules: X ms + connectChunkGroups: X ms + cleanup: X ms + +LOG from webpack.SplitChunksPlugin + prepare: X ms + modules: X ms + queue: X ms + maxSize: X ms + +LOG from webpack.ModuleConcatenationPlugin + select relevant modules: X ms + sort relevant modules: X ms + find modules to concatenate: X ms + sort concat configurations: X ms + create concatenated modules: X ms ++ 3 hidden lines + +LOG from webpack.FileSystemInfo + 6 new snapshots created + 0% root snapshot uncached (0 / 0) + 0% children snapshot uncached (0 / 0) + 0 entries tested + File info in cache: 6 timestamps 6 hashes 6 timestamp hash combinations + File timestamp hash combination snapshot optimization: 0% (0/6) entries shared via 0 shared snapshots (0 times referenced) + Directory info in cache: 0 timestamps 0 hashes 0 timestamp hash combinations + Managed items info in cache: 0 items + +1970-04-20 12:42:42: webpack x.x.x compiled successfully in X ms (XXXXXXXXXXXXXXXXXXXX)" +`; + +exports[`StatsTestCases should print correct stats for real-content-hash 1`] = ` +"a-normal: + assets by path *.js X KiB + asset XXXXXXXXXXXXXXXXXXXX-XXXXXX.js X KiB [emitted] [immutable] [minimized] (name: runtime) + asset XXXXXXXXXXXXXXXXXXXX-XXXXXX.js X bytes [emitted] [immutable] [minimized] (name: lazy) + asset XXXXXXXXXXXXXXXXXXXX-XXXXXX.js X bytes [emitted] [immutable] [minimized] (name: index) + asset XXXXXXXXXXXXXXXXXXXX-XXXXXX.js X bytes [emitted] [immutable] [minimized] (name: a, b) + assets by chunk X KiB (auxiliary name: lazy) + asset XXXXXXXXXXXXXXXXXXXX.png X KiB [emitted] [immutable] [from: file.png] (auxiliary name: lazy) + asset XXXXXXXXXXXXXXXXXXXX.jpg?query X KiB [cached] [immutable] [from: file.jpg?query] (auxiliary name: lazy) + asset XXXXXXXXXXXXXXXXXXXX.jpg X KiB [emitted] [immutable] [from: file.jpg] (auxiliary name: index) + Entrypoint index X KiB (X KiB) = XXXXXXXXXXXXXXXXXXXX-XXXXXX.js X KiB XXXXXXXXXXXXXXXXXXXX-XXXXXX.js X bytes 1 auxiliary asset + Entrypoint a X bytes = XXXXXXXXXXXXXXXXXXXX-XXXXXX.js + Entrypoint b X bytes = XXXXXXXXXXXXXXXXXXXX-XXXXXX.js + runtime modules X KiB 8 modules + orphan modules X bytes [orphan] 1 module + cacheable modules X bytes (javascript) X KiB (asset) + javascript modules X bytes + ./a/index.js X bytes [built] [code generated] + ./a/a.js X bytes [built] [code generated] + ./a/b.js X bytes [built] [code generated] + ./a/lazy.js + 2 modules X bytes [built] [code generated] + asset modules X bytes (javascript) X KiB (asset) + ./a/file.jpg X bytes (javascript) X KiB (asset) [built] [code generated] + ./a/file.png X bytes (javascript) X KiB (asset) [built] [code generated] + ./a/file.jpg?query X bytes (javascript) X KiB (asset) [built] [code generated] + a-normal (webpack x.x.x) compiled successfully in X ms + +b-normal: + assets by path *.js X KiB + asset XXXXXXXXXXXXXXXXXXXX-XXXXXX.js X KiB [emitted] [immutable] [minimized] (name: runtime) + asset XXXXXXXXXXXXXXXXXXXX-XXXXXX.js X bytes [emitted] [immutable] [minimized] (name: lazy) + asset XXXXXXXXXXXXXXXXXXXX-XXXXXX.js X bytes [emitted] [immutable] [minimized] (name: index) + asset XXXXXXXXXXXXXXXXXXXX-XXXXXX.js X bytes [emitted] [immutable] [minimized] (name: a, b) + assets by chunk X KiB (auxiliary name: lazy) + asset XXXXXXXXXXXXXXXXXXXX.png X KiB [emitted] [immutable] [from: file.png] (auxiliary name: lazy) + asset XXXXXXXXXXXXXXXXXXXX.jpg?query X KiB [cached] [immutable] [from: file.jpg?query] (auxiliary name: lazy) + asset XXXXXXXXXXXXXXXXXXXX.jpg X KiB [emitted] [immutable] [from: file.jpg] (auxiliary name: index) + Entrypoint index X KiB (X KiB) = XXXXXXXXXXXXXXXXXXXX-XXXXXX.js X KiB XXXXXXXXXXXXXXXXXXXX-XXXXXX.js X bytes 1 auxiliary asset + Entrypoint a X bytes = XXXXXXXXXXXXXXXXXXXX-XXXXXX.js + Entrypoint b X bytes = XXXXXXXXXXXXXXXXXXXX-XXXXXX.js + runtime modules X KiB 8 modules + orphan modules X bytes [orphan] 1 module + cacheable modules X bytes (javascript) X KiB (asset) + javascript modules X bytes + ./b/index.js X bytes [built] [code generated] + ./b/a.js X bytes [built] [code generated] + ./b/b.js X bytes [built] [code generated] + ./b/lazy.js + 2 modules X bytes [built] [code generated] + asset modules X bytes (javascript) X KiB (asset) + ./b/file.jpg X bytes (javascript) X KiB (asset) [built] [code generated] + ./b/file.png X bytes (javascript) X KiB (asset) [built] [code generated] + ./b/file.jpg?query X bytes (javascript) X KiB (asset) [built] [code generated] + b-normal (webpack x.x.x) compiled successfully in X ms + +a-source-map: + assets by path *.js X KiB + asset XXXXXXXXXXXXXXXXXXXX-XXXXXX.js X KiB [emitted] [immutable] [minimized] (name: runtime) + sourceMap XXXXXXXXXXXXXXXXXXXX-XXXXXX.js.map X KiB [emitted] [dev] (auxiliary name: runtime) + asset XXXXXXXXXXXXXXXXXXXX-XXXXXX.js X bytes [emitted] [immutable] [minimized] (name: lazy) + sourceMap XXXXXXXXXXXXXXXXXXXX-XXXXXX.js.map X bytes [emitted] [dev] (auxiliary name: lazy) + asset XXXXXXXXXXXXXXXXXXXX-XXXXXX.js X bytes [emitted] [immutable] [minimized] (name: index) + sourceMap XXXXXXXXXXXXXXXXXXXX-XXXXXX.js.map X bytes [emitted] [dev] (auxiliary name: index) + asset XXXXXXXXXXXXXXXXXXXX-XXXXXX.js X bytes [emitted] [immutable] [minimized] (name: a, b) + sourceMap XXXXXXXXXXXXXXXXXXXX-XXXXXX.js.map X bytes [emitted] [dev] (auxiliary name: a, b) + assets by chunk X KiB (auxiliary name: lazy) + asset XXXXXXXXXXXXXXXXXXXX.png X KiB [emitted] [immutable] [from: file.png] (auxiliary name: lazy) + asset XXXXXXXXXXXXXXXXXXXX.jpg?query X KiB [cached] [immutable] [from: file.jpg?query] (auxiliary name: lazy) + asset XXXXXXXXXXXXXXXXXXXX.jpg X KiB [emitted] [immutable] [from: file.jpg] (auxiliary name: index) + Entrypoint index X KiB (X KiB) = XXXXXXXXXXXXXXXXXXXX-XXXXXX.js X KiB XXXXXXXXXXXXXXXXXXXX-XXXXXX.js X bytes 3 auxiliary assets + Entrypoint a X bytes (X bytes) = XXXXXXXXXXXXXXXXXXXX-XXXXXX.js 1 auxiliary asset + Entrypoint b X bytes (X bytes) = XXXXXXXXXXXXXXXXXXXX-XXXXXX.js 1 auxiliary asset + runtime modules X KiB 8 modules + orphan modules X bytes [orphan] 1 module + cacheable modules X bytes (javascript) X KiB (asset) + javascript modules X bytes + ./a/index.js X bytes [built] [code generated] + ./a/a.js X bytes [built] [code generated] + ./a/b.js X bytes [built] [code generated] + ./a/lazy.js + 2 modules X bytes [built] [code generated] + asset modules X bytes (javascript) X KiB (asset) + ./a/file.jpg X bytes (javascript) X KiB (asset) [built] [code generated] + ./a/file.png X bytes (javascript) X KiB (asset) [built] [code generated] + ./a/file.jpg?query X bytes (javascript) X KiB (asset) [built] [code generated] + a-source-map (webpack x.x.x) compiled successfully in X ms + +b-source-map: + assets by path *.js X KiB + asset XXXXXXXXXXXXXXXXXXXX-XXXXXX.js X KiB [emitted] [immutable] [minimized] (name: runtime) + sourceMap XXXXXXXXXXXXXXXXXXXX-XXXXXX.js.map X KiB [emitted] [dev] (auxiliary name: runtime) + asset XXXXXXXXXXXXXXXXXXXX-XXXXXX.js X bytes [emitted] [immutable] [minimized] (name: lazy) + sourceMap XXXXXXXXXXXXXXXXXXXX-XXXXXX.js.map X bytes [emitted] [dev] (auxiliary name: lazy) + asset XXXXXXXXXXXXXXXXXXXX-XXXXXX.js X bytes [emitted] [immutable] [minimized] (name: index) + sourceMap XXXXXXXXXXXXXXXXXXXX-XXXXXX.js.map X bytes [emitted] [dev] (auxiliary name: index) + asset XXXXXXXXXXXXXXXXXXXX-XXXXXX.js X bytes [emitted] [immutable] [minimized] (name: a, b) + sourceMap XXXXXXXXXXXXXXXXXXXX-XXXXXX.js.map X bytes [emitted] [dev] (auxiliary name: a, b) + assets by chunk X KiB (auxiliary name: lazy) + asset XXXXXXXXXXXXXXXXXXXX.png X KiB [emitted] [immutable] [from: file.png] (auxiliary name: lazy) + asset XXXXXXXXXXXXXXXXXXXX.jpg?query X KiB [cached] [immutable] [from: file.jpg?query] (auxiliary name: lazy) + asset XXXXXXXXXXXXXXXXXXXX.jpg X KiB [emitted] [immutable] [from: file.jpg] (auxiliary name: index) + Entrypoint index X KiB (X KiB) = XXXXXXXXXXXXXXXXXXXX-XXXXXX.js X KiB XXXXXXXXXXXXXXXXXXXX-XXXXXX.js X bytes 3 auxiliary assets + Entrypoint a X bytes (X bytes) = XXXXXXXXXXXXXXXXXXXX-XXXXXX.js 1 auxiliary asset + Entrypoint b X bytes (X bytes) = XXXXXXXXXXXXXXXXXXXX-XXXXXX.js 1 auxiliary asset + runtime modules X KiB 8 modules + orphan modules X bytes [orphan] 1 module + cacheable modules X bytes (javascript) X KiB (asset) + javascript modules X bytes + ./b/index.js X bytes [built] [code generated] + ./b/a.js X bytes [built] [code generated] + ./b/b.js X bytes [built] [code generated] + ./b/lazy.js + 2 modules X bytes [built] [code generated] + asset modules X bytes (javascript) X KiB (asset) + ./b/file.jpg X bytes (javascript) X KiB (asset) [built] [code generated] + ./b/file.png X bytes (javascript) X KiB (asset) [built] [code generated] + ./b/file.jpg?query X bytes (javascript) X KiB (asset) [built] [code generated] + b-source-map (webpack x.x.x) compiled successfully in X ms" +`; + +exports[`StatsTestCases should print correct stats for related-assets 1`] = ` +"default: + assets by path *.js X KiB + asset default-main.js X KiB [emitted] (name: main) 3 related assets + asset default-chunk_js.js X bytes [emitted] 3 related assets + assets by path *.css X bytes + asset default-chunk_js.css X bytes [emitted] 3 related assets + asset default-main.css X bytes [emitted] (name: main) 3 related assets + asset default-file.jpg X KiB [emitted] [from: file.jpg] (auxiliary name: main) + +relatedAssets: + assets by path *.js X KiB + asset relatedAssets-main.js X KiB [emitted] (name: main) + compressed relatedAssets-main.js.br X KiB [emitted] + compressed relatedAssets-main.js.gz X KiB [emitted] + sourceMap relatedAssets-main.js.map X KiB [emitted] [dev] (auxiliary name: main) + compressed relatedAssets-main.js.map.br X KiB [emitted] + compressed relatedAssets-main.js.map.gz X KiB [emitted] + asset relatedAssets-chunk_js.js X bytes [emitted] + compressed relatedAssets-chunk_js.js.br X bytes [emitted] + compressed relatedAssets-chunk_js.js.gz X bytes [emitted] + sourceMap relatedAssets-chunk_js.js.map X bytes [emitted] [dev] + compressed relatedAssets-chunk_js.js.map.br X bytes [emitted] + compressed relatedAssets-chunk_js.js.map.gz X bytes [emitted] + assets by path *.css X bytes + asset relatedAssets-chunk_js.css X bytes [emitted] + sourceMap relatedAssets-chunk_js.css.map X bytes [emitted] [dev] + compressed relatedAssets-chunk_js.css.map.br X bytes [emitted] + compressed relatedAssets-chunk_js.css.map.gz X bytes [emitted] + compressed relatedAssets-chunk_js.css.br X bytes [emitted] + compressed relatedAssets-chunk_js.css.gz X bytes [emitted] + asset relatedAssets-main.css X bytes [emitted] (name: main) + sourceMap relatedAssets-main.css.map X bytes [emitted] [dev] (auxiliary name: main) + compressed relatedAssets-main.css.map.br X bytes [emitted] + compressed relatedAssets-main.css.map.gz X bytes [emitted] + compressed relatedAssets-main.css.br X bytes [emitted] + compressed relatedAssets-main.css.gz X bytes [emitted] + asset relatedAssets-file.jpg X KiB [emitted] [from: file.jpg] (auxiliary name: main) + +exclude1: + assets by path *.js X KiB + asset exclude1-main.js X KiB [emitted] (name: main) + hidden assets X KiB 2 assets + sourceMap exclude1-main.js.map X KiB [emitted] [dev] (auxiliary name: main) + hidden assets X KiB 2 assets + + 1 related asset + + 1 related asset + asset exclude1-chunk_js.js X bytes [emitted] + hidden assets X KiB 2 assets + sourceMap exclude1-chunk_js.js.map X bytes [emitted] [dev] + hidden assets X bytes 2 assets + + 1 related asset + + 1 related asset + assets by path *.css X bytes + asset exclude1-chunk_js.css X bytes [emitted] + hidden assets X bytes 2 assets + sourceMap exclude1-chunk_js.css.map X bytes [emitted] [dev] + hidden assets X bytes 2 assets + + 1 related asset + + 1 related asset + asset exclude1-main.css X bytes [emitted] (name: main) + hidden assets X bytes 2 assets + sourceMap exclude1-main.css.map X bytes [emitted] [dev] (auxiliary name: main) + hidden assets X bytes 2 assets + + 1 related asset + + 1 related asset + asset exclude1-file.jpg X KiB [emitted] [from: file.jpg] (auxiliary name: main) + +exclude2: + assets by path *.js X KiB + asset exclude2-main.js X KiB [emitted] (name: main) + hidden assets X KiB 1 asset + compressed exclude2-main.js.br X KiB [emitted] + compressed exclude2-main.js.gz X KiB [emitted] + asset exclude2-chunk_js.js X bytes [emitted] + hidden assets X bytes 1 asset + compressed exclude2-chunk_js.js.br X bytes [emitted] + compressed exclude2-chunk_js.js.gz X bytes [emitted] + assets by path *.css X bytes + asset exclude2-chunk_js.css X bytes [emitted] + hidden assets X bytes 1 asset + compressed exclude2-chunk_js.css.br X bytes [emitted] + compressed exclude2-chunk_js.css.gz X bytes [emitted] + asset exclude2-main.css X bytes [emitted] (name: main) + hidden assets X bytes 1 asset + compressed exclude2-main.css.br X bytes [emitted] + compressed exclude2-main.css.gz X bytes [emitted] + asset exclude2-file.jpg X KiB [emitted] [from: file.jpg] (auxiliary name: main) + +exclude3: + hidden assets X bytes 2 assets + assets by status X KiB [emitted] + asset exclude3-main.js X KiB [emitted] (name: main) + compressed exclude3-main.js.br X KiB [emitted] + compressed exclude3-main.js.gz X KiB [emitted] + sourceMap exclude3-main.js.map X KiB [emitted] [dev] (auxiliary name: main) + compressed exclude3-main.js.map.br X KiB [emitted] + compressed exclude3-main.js.map.gz X KiB [emitted] + asset exclude3-file.jpg X KiB [emitted] [from: file.jpg] (auxiliary name: main) + asset exclude3-main.css X bytes [emitted] (name: main) + sourceMap exclude3-main.css.map X bytes [emitted] [dev] (auxiliary name: main) + compressed exclude3-main.css.map.br X bytes [emitted] + compressed exclude3-main.css.map.gz X bytes [emitted] + compressed exclude3-main.css.br X bytes [emitted] + compressed exclude3-main.css.gz X bytes [emitted]" +`; + +exports[`StatsTestCases should print correct stats for resolve-plugin-context 1`] = ` +"asset bundle.js X KiB [emitted] (name: main) +modules by path ./node_modules/def/ X bytes + ./node_modules/def/index.js X bytes [built] [code generated] + ./node_modules/def/node_modules/xyz/index.js X bytes [built] [code generated] +./index.js X bytes [built] [code generated] +./node_modules/abc/index.js X bytes [built] [code generated] +./node_modules/xyz/index.js X bytes [built] [code generated] +webpack x.x.x compiled successfully in X ms" +`; + +exports[`StatsTestCases should print correct stats for reverse-sort-modules 1`] = ` +"asset main.js X KiB [emitted] (name: main) +./index.js X bytes [built] [code generated] +./c.js?9 X bytes [built] [code generated] +./c.js?8 X bytes [built] [code generated] +./c.js?7 X bytes [built] [code generated] +./c.js?6 X bytes [built] [code generated] +./c.js?5 X bytes [built] [code generated] +./c.js?4 X bytes [built] [code generated] +./c.js?3 X bytes [built] [code generated] +./c.js?2 X bytes [built] [code generated] +./c.js?10 X bytes [built] [code generated] +./c.js?1 X bytes [built] [code generated] +./b.js?9 X bytes [built] [code generated] +./b.js?8 X bytes [built] [code generated] +./b.js?7 X bytes [built] [code generated] +./b.js?6 X bytes [built] [code generated] +./b.js?5 X bytes [built] [code generated] +./b.js?4 X bytes [built] [code generated] +./b.js?3 X bytes [built] [code generated] +./b.js?2 X bytes [built] [code generated] +./b.js?10 X bytes [built] [code generated] +./b.js?1 X bytes [built] [code generated] +./a.js?9 X bytes [built] [code generated] +./a.js?8 X bytes [built] [code generated] +./a.js?7 X bytes [built] [code generated] +./a.js?6 X bytes [built] [code generated] +./a.js?5 X bytes [built] [code generated] +./a.js?4 X bytes [built] [code generated] +./a.js?3 X bytes [built] [code generated] +./a.js?2 X bytes [built] [code generated] +./a.js?10 X bytes [built] [code generated] +./a.js?1 X bytes [built] [code generated] +webpack x.x.x compiled successfully in X ms" +`; + +exports[`StatsTestCases should print correct stats for runtime-chunk 1`] = ` +"Entrypoint e1 X KiB = runtime~e1.js X KiB e1.js X KiB +Entrypoint e2 X KiB = runtime~e2.js X KiB e2.js X KiB +webpack x.x.x compiled successfully" +`; + +exports[`StatsTestCases should print correct stats for runtime-chunk-integration 1`] = ` +"base: + asset without-runtime.js X KiB [emitted] (name: runtime) + asset without-580.js X KiB [emitted] + asset without-main1.js X bytes [emitted] (name: main1) + Entrypoint main1 X KiB = without-runtime.js X KiB without-main1.js X bytes + runtime modules X KiB 10 modules + cacheable modules X bytes + ./main1.js X bytes [built] [code generated] + ./b.js X bytes [built] [code generated] + ./c.js X bytes [built] [code generated] + ./d.js X bytes [built] [code generated] + base (webpack x.x.x) compiled successfully + +static custom name: + asset with-manifest.js X KiB [emitted] (name: manifest) + asset with-580.js X KiB [emitted] + asset with-main1.js X bytes [emitted] (name: main1) + asset with-main2.js X bytes [emitted] (name: main2) + asset with-main3.js X bytes [emitted] (name: main3) + Entrypoint main1 X KiB = with-manifest.js X KiB with-main1.js X bytes + Entrypoint main2 X KiB = with-manifest.js X KiB with-main2.js X bytes + Entrypoint main3 X KiB = with-manifest.js X KiB with-main3.js X bytes + runtime modules X KiB 10 modules + cacheable modules X bytes + ./main1.js X bytes [built] [code generated] + ./main2.js X bytes [built] [code generated] + ./main3.js X bytes [built] [code generated] + ./b.js X bytes [built] [code generated] + ./c.js X bytes [built] [code generated] + ./d.js X bytes [built] [code generated] + static custom name (webpack x.x.x) compiled successfully + +dynamic custom name: + asset func-b.js X KiB [emitted] (name: b) + asset func-a.js X KiB [emitted] (name: a) + asset func-580.js X KiB [emitted] + asset func-main1.js X bytes [emitted] (name: main1) + asset func-main2.js X bytes [emitted] (name: main2) + asset func-main3.js X bytes [emitted] (name: main3) + Entrypoint main1 X KiB = func-b.js X KiB func-main1.js X bytes + Entrypoint main2 X KiB = func-b.js X KiB func-main2.js X bytes + Entrypoint main3 X KiB = func-a.js X KiB func-main3.js X bytes + runtime modules X KiB 13 modules + cacheable modules X bytes + ./main1.js X bytes [built] [code generated] + ./main2.js X bytes [built] [code generated] + ./main3.js X bytes [built] [code generated] + ./b.js X bytes [built] [code generated] + ./c.js X bytes [built] [code generated] + ./d.js X bytes [built] [code generated] + dynamic custom name (webpack x.x.x) compiled successfully" +`; + +exports[`StatsTestCases should print correct stats for runtime-chunk-issue-7382 1`] = ` +"Entrypoint e1 X KiB = runtime.js X KiB all.js X bytes e1.js X bytes +Entrypoint e2 X KiB = runtime.js X KiB all.js X bytes e2.js X bytes +webpack x.x.x compiled successfully" +`; + +exports[`StatsTestCases should print correct stats for runtime-chunk-single 1`] = ` +"Entrypoint e1 X KiB = runtime.js X KiB e1.js X KiB +Entrypoint e2 X KiB = runtime.js X KiB e2.js X KiB +webpack x.x.x compiled successfully" +`; + +exports[`StatsTestCases should print correct stats for runtime-specific-used-exports 1`] = ` +"production: + asset production-a.js X KiB [emitted] (name: a) + asset production-b.js X KiB [emitted] (name: b) + asset production-dw_js-_a6170.js X KiB [emitted] + asset production-dw_js-_a6171.js X KiB [emitted] + asset production-dx_js.js X KiB [emitted] + asset production-dy_js.js X KiB [emitted] + asset production-dz_js.js X KiB [emitted] + asset production-c.js X bytes [emitted] (name: c) + chunk (runtime: a) production-a.js (a) X bytes (javascript) X KiB (runtime) [entry] [rendered] + runtime modules X KiB 9 modules + cacheable modules X bytes + ./a.js X bytes [built] [code generated] + [no exports used] + ./dx-importer.js X bytes [dependent] [built] [code generated] + [only some exports used: default] + ./module.js X bytes [dependent] [built] [code generated] + [only some exports used: x] + ./module.js?reexported X bytes [dependent] [built] [code generated] + [only some exports used: x] + ./reexport.js X bytes [dependent] [built] [code generated] + [only some exports used: x] + chunk (runtime: b) production-b.js (b) X bytes (javascript) X KiB (runtime) [entry] [rendered] + runtime modules X KiB 9 modules + cacheable modules X bytes + ./b.js X bytes [built] [code generated] + [no exports used] + ./dx-importer.js X bytes [dependent] [built] [code generated] + [only some exports used: default] + ./module.js X bytes [dependent] [built] [code generated] + [only some exports used: y] + ./module.js?reexported X bytes [dependent] [built] [code generated] + [only some exports used: y] + ./reexport.js X bytes [dependent] [built] [code generated] + [only some exports used: y] + chunk (runtime: c) production-c.js (c) X bytes [entry] [rendered] + ./c.js X bytes [built] [code generated] + [no exports used] + chunk (runtime: a) production-dw_js-_a6170.js X bytes [rendered] + ./dw.js X bytes [built] [code generated] + ./module.js?chunk X bytes [dependent] [built] [code generated] + [only some exports used: identity, w, x, y] + chunk (runtime: b) production-dw_js-_a6171.js X bytes [rendered] + ./dw.js X bytes [built] [code generated] + ./module.js?chunk X bytes [dependent] [built] [code generated] + [only some exports used: identity, w, x, z] + chunk (runtime: a, b) production-dx_js.js X bytes [rendered] + ./dx.js X bytes [built] [code generated] + ./module.js?chunk X bytes [dependent] [built] [code generated] + [only some exports used: identity, w, x, y, z] + chunk (runtime: a) production-dy_js.js X bytes [rendered] + ./dy.js X bytes [built] [code generated] + ./module.js?chunk X bytes [dependent] [built] [code generated] + [only some exports used: identity, w, x, y] + chunk (runtime: b) production-dz_js.js X bytes [rendered] + ./dz.js X bytes [built] [code generated] + ./module.js?chunk X bytes [dependent] [built] [code generated] + [only some exports used: identity, w, x, z] + runtime modules X KiB 18 modules + cacheable modules X KiB + ./a.js X bytes [built] [code generated] + [no exports used] + ./b.js X bytes [built] [code generated] + [no exports used] + ./c.js X bytes [built] [code generated] + [no exports used] + ./module.js X bytes [built] [code generated] + [only some exports used: x, y] + ./reexport.js X bytes [built] [code generated] + [only some exports used: x, y] + ./dx-importer.js X bytes [built] [code generated] + [only some exports used: default] + ./dy.js X bytes [built] [code generated] + ./dw.js X bytes [built] [code generated] + ./dz.js X bytes [built] [code generated] + ./module.js?reexported X bytes [built] [code generated] + [only some exports used: x, y] + ./module.js?chunk X bytes [built] [code generated] + [only some exports used: identity, w, x, y, z] + ./dx.js X bytes [built] [code generated] + production (webpack x.x.x) compiled successfully in X ms + +development: + asset development-a.js X KiB [emitted] (name: a) + asset development-b.js X KiB [emitted] (name: b) + asset development-dw_js.js X KiB [emitted] + asset development-dx_js.js X KiB [emitted] + asset development-dy_js.js X KiB [emitted] + asset development-dz_js.js X KiB [emitted] + asset development-c.js X KiB [emitted] (name: c) + chunk (runtime: a) development-a.js (a) X bytes (javascript) X KiB (runtime) [entry] [rendered] + runtime modules X KiB 9 modules + cacheable modules X bytes + ./a.js X bytes [built] [code generated] + [used exports unknown] + ./dx-importer.js X bytes [dependent] [built] [code generated] + [used exports unknown] + ./module.js X bytes [dependent] [built] [code generated] + [used exports unknown] + ./module.js?reexported X bytes [dependent] [built] [code generated] + [used exports unknown] + ./reexport.js X bytes [dependent] [built] [code generated] + [used exports unknown] + chunk (runtime: b) development-b.js (b) X bytes (javascript) X KiB (runtime) [entry] [rendered] + runtime modules X KiB 9 modules + cacheable modules X bytes + ./b.js X bytes [built] [code generated] + [used exports unknown] + ./dx-importer.js X bytes [dependent] [built] [code generated] + [used exports unknown] + ./module.js X bytes [dependent] [built] [code generated] + [used exports unknown] + ./module.js?reexported X bytes [dependent] [built] [code generated] + [used exports unknown] + ./reexport.js X bytes [dependent] [built] [code generated] + [used exports unknown] + chunk (runtime: c) development-c.js (c) X bytes [entry] [rendered] + ./c.js X bytes [built] [code generated] + [used exports unknown] + chunk (runtime: a, b) development-dw_js.js X bytes [rendered] + ./dw.js X bytes [built] [code generated] + [used exports unknown] + ./module.js?chunk X bytes [dependent] [built] [code generated] + [used exports unknown] + chunk (runtime: a, b) development-dx_js.js X bytes [rendered] + ./dx.js X bytes [built] [code generated] + [used exports unknown] + ./module.js?chunk X bytes [dependent] [built] [code generated] + [used exports unknown] + chunk (runtime: a) development-dy_js.js X bytes [rendered] + ./dy.js X bytes [built] [code generated] + [used exports unknown] + ./module.js?chunk X bytes [dependent] [built] [code generated] + [used exports unknown] + chunk (runtime: b) development-dz_js.js X bytes [rendered] + ./dz.js X bytes [built] [code generated] + [used exports unknown] + ./module.js?chunk X bytes [dependent] [built] [code generated] + [used exports unknown] + runtime modules X KiB 18 modules + cacheable modules X KiB + ./a.js X bytes [built] [code generated] + [used exports unknown] + ./b.js X bytes [built] [code generated] + [used exports unknown] + ./c.js X bytes [built] [code generated] + [used exports unknown] + ./module.js X bytes [built] [code generated] + [used exports unknown] + ./reexport.js X bytes [built] [code generated] + [used exports unknown] + ./dx-importer.js X bytes [built] [code generated] + [used exports unknown] + ./dy.js X bytes [built] [code generated] + [used exports unknown] + ./dw.js X bytes [built] [code generated] + [used exports unknown] + ./dz.js X bytes [built] [code generated] + [used exports unknown] + ./module.js?reexported X bytes [built] [code generated] + [used exports unknown] + ./module.js?chunk X bytes [built] [code generated] + [used exports unknown] + ./dx.js X bytes [built] [code generated] + [used exports unknown] + development (webpack x.x.x) compiled successfully in X ms + +global: + asset global-a.js X KiB [emitted] (name: a) + asset global-b.js X KiB [emitted] (name: b) + asset global-dw_js.js X KiB [emitted] + asset global-dx_js.js X KiB [emitted] + asset global-dy_js.js X KiB [emitted] + asset global-dz_js.js X KiB [emitted] + asset global-c.js X bytes [emitted] (name: c) + chunk (runtime: a) global-a.js (a) X bytes (javascript) X KiB (runtime) [entry] [rendered] + runtime modules X KiB 9 modules + cacheable modules X bytes + ./a.js X bytes [built] [code generated] + [no exports used] + ./dx-importer.js X bytes [dependent] [built] [code generated] + [only some exports used: default] + ./module.js X bytes [dependent] [built] [code generated] + [only some exports used: x, y] + ./module.js?reexported X bytes [dependent] [built] [code generated] + [only some exports used: x, y] + ./reexport.js X bytes [dependent] [built] [code generated] + [only some exports used: x, y] + chunk (runtime: b) global-b.js (b) X bytes (javascript) X KiB (runtime) [entry] [rendered] + runtime modules X KiB 9 modules + cacheable modules X bytes + ./b.js X bytes [built] [code generated] + [no exports used] + ./dx-importer.js X bytes [dependent] [built] [code generated] + [only some exports used: default] + ./module.js X bytes [dependent] [built] [code generated] + [only some exports used: x, y] + ./module.js?reexported X bytes [dependent] [built] [code generated] + [only some exports used: x, y] + ./reexport.js X bytes [dependent] [built] [code generated] + [only some exports used: x, y] + chunk (runtime: c) global-c.js (c) X bytes [entry] [rendered] + ./c.js X bytes [built] [code generated] + [no exports used] + chunk (runtime: a, b) global-dw_js.js X bytes [rendered] + ./dw.js X bytes [built] [code generated] + ./module.js?chunk X bytes [dependent] [built] [code generated] + [only some exports used: identity, w, x, y, z] + chunk (runtime: a, b) global-dx_js.js X bytes [rendered] + ./dx.js X bytes [built] [code generated] + ./module.js?chunk X bytes [dependent] [built] [code generated] + [only some exports used: identity, w, x, y, z] + chunk (runtime: a) global-dy_js.js X bytes [rendered] + ./dy.js X bytes [built] [code generated] + ./module.js?chunk X bytes [dependent] [built] [code generated] + [only some exports used: identity, w, x, y, z] + chunk (runtime: b) global-dz_js.js X bytes [rendered] + ./dz.js X bytes [built] [code generated] + ./module.js?chunk X bytes [dependent] [built] [code generated] + [only some exports used: identity, w, x, y, z] + runtime modules X KiB 18 modules + cacheable modules X KiB + ./a.js X bytes [built] [code generated] + [no exports used] + ./b.js X bytes [built] [code generated] + [no exports used] + ./c.js X bytes [built] [code generated] + [no exports used] + ./module.js X bytes [built] [code generated] + [only some exports used: x, y] + ./reexport.js X bytes [built] [code generated] + [only some exports used: x, y] + ./dx-importer.js X bytes [built] [code generated] + [only some exports used: default] + ./dy.js X bytes [built] [code generated] + ./dw.js X bytes [built] [code generated] + ./dz.js X bytes [built] [code generated] + ./module.js?reexported X bytes [built] [code generated] + [only some exports used: x, y] + ./module.js?chunk X bytes [built] [code generated] + [only some exports used: identity, w, x, y, z] + ./dx.js X bytes [built] [code generated] + global (webpack x.x.x) compiled successfully in X ms" +`; + +exports[`StatsTestCases should print correct stats for scope-hoisting-bailouts 1`] = ` +"runtime modules X KiB 10 modules +built modules X bytes [built] + code generated modules X bytes [code generated] + ./index.js X bytes [built] [code generated] + Statement (ExpressionStatement) with side effects in source code at 7:0-25 + ModuleConcatenation bailout: Cannot concat with ./cjs.js: Module is not an ECMAScript module + ModuleConcatenation bailout: Cannot concat with ./eval.js: Module uses eval() + ModuleConcatenation bailout: Cannot concat with ./module-id.js: Module uses module.id + ModuleConcatenation bailout: Cannot concat with ./module-loaded.js: Module uses module.loaded + ./entry.js X bytes [built] [code generated] + ./cjs.js X bytes [built] [code generated] + CommonJS bailout: module.exports is used directly at 3:0-14 + Statement (ExpressionStatement) with side effects in source code at 1:0-26 + ModuleConcatenation bailout: Module is not an ECMAScript module + ./ref-from-cjs.js X bytes [built] [code generated] + ./eval.js X bytes [built] [code generated] + Statement (ExportDefaultDeclaration) with side effects in source code at 1:0-34 + ModuleConcatenation bailout: Module uses eval() + ./module-id.js X bytes [built] [code generated] + Statement (ExportDefaultDeclaration) with side effects in source code at 1:0-25 + ModuleConcatenation bailout: Module uses module.id + ./module-loaded.js X bytes [built] [code generated] + Statement (ExportDefaultDeclaration) with side effects in source code at 1:0-29 + ModuleConcatenation bailout: Module uses module.loaded + ./concatenated.js + 2 modules X bytes [built] [code generated] + ModuleConcatenation bailout: Cannot concat with external \\"external\\": Module external \\"external\\" is not in the same chunk(s) (expected in chunk(s) unnamed chunk(s), module is in chunk(s) index) + external \\"external\\" X bytes [built] [code generated] + orphan modules X bytes [orphan] + ./concatenated1.js X bytes [orphan] [built] + Dependency (harmony side effect evaluation) with side effects at 1:0-36 + ./concatenated2.js X bytes [orphan] [built] + Dependency (harmony side effect evaluation) with side effects at 1:0-29 +webpack x.x.x compiled successfully in X ms" +`; + +exports[`StatsTestCases should print correct stats for scope-hoisting-multi 1`] = ` +"Entrypoint first X KiB = a-vendor.js X bytes a-first.js X KiB +Entrypoint second X KiB = a-vendor.js X bytes a-second.js X KiB +runtime modules X KiB 20 modules +orphan modules X bytes [orphan] 1 module +cacheable modules X bytes + ./first.js X bytes [built] [code generated] + ./second.js X bytes [built] [code generated] + ./vendor.js X bytes [built] [code generated] + ./module_first.js X bytes [built] [code generated] + ./common2.js X bytes [built] [code generated] + ./lazy_first.js X bytes [built] [code generated] + ./lazy_shared.js X bytes [built] [code generated] + ./lazy_second.js X bytes [built] [code generated] + ./common_lazy.js X bytes [built] [code generated] + ./common_lazy_shared.js X bytes [built] [code generated] +webpack x.x.x compiled successfully in X ms + +Entrypoint first X KiB = b-vendor.js X bytes b-first.js X KiB +Entrypoint second X KiB = b-vendor.js X bytes b-second.js X KiB +runtime modules X KiB 20 modules +cacheable modules X bytes + code generated modules X bytes [code generated] + ./first.js + 2 modules X bytes [built] [code generated] + ModuleConcatenation bailout: Cannot concat with ./vendor.js: Module ./vendor.js is not in the same chunk(s) (expected in chunk(s) first, module is in chunk(s) vendor) + ./second.js + 1 modules X bytes [built] [code generated] + ModuleConcatenation bailout: Cannot concat with ./vendor.js: Module ./vendor.js is not in the same chunk(s) (expected in chunk(s) second, module is in chunk(s) vendor) + ./vendor.js X bytes [built] [code generated] + ./lazy_first.js + 1 modules X bytes [built] [code generated] + ModuleConcatenation bailout: Cannot concat with ./common_lazy_shared.js: Module ./common_lazy_shared.js is referenced from different chunks by these modules: ./lazy_shared.js + ./lazy_shared.js X bytes [built] [code generated] + ModuleConcatenation bailout: Cannot concat with ./common_lazy_shared.js: Module ./common_lazy_shared.js is referenced from different chunks by these modules: ./lazy_first.js, ./lazy_second.js + ./lazy_second.js + 1 modules X bytes [built] [code generated] + ModuleConcatenation bailout: Cannot concat with ./common_lazy_shared.js: Module ./common_lazy_shared.js is referenced from different chunks by these modules: ./lazy_shared.js + ./common_lazy_shared.js X bytes [built] [code generated] + orphan modules X bytes [orphan] + ./module_first.js X bytes [orphan] [built] + ./common2.js X bytes [orphan] [built] + ./common.js X bytes [orphan] [built] + ModuleConcatenation bailout: Module is not in any chunk + ./common_lazy.js X bytes [orphan] [built] +webpack x.x.x compiled successfully in X ms" +`; + +exports[`StatsTestCases should print correct stats for side-effects-issue-7428 1`] = ` +"asset main.js X KiB [emitted] (name: main) +asset 1.js X bytes [emitted] +runtime modules X KiB 9 modules +cacheable modules X bytes + modules by path ./components/src/ X bytes + orphan modules X bytes [orphan] + modules by path ./components/src/CompAB/*.js X bytes 2 modules + modules by path ./components/src/CompC/*.js X bytes 2 modules + ./components/src/index.js X bytes [orphan] [built] + [module unused] + [inactive] from origin ./main.js + 1 modules + [inactive] harmony side effect evaluation ./components ./main.js + 1 modules ./main.js 1:0-44 + [inactive] harmony import specifier ./components ./main.js + 1 modules ./main.js 3:15-20 + [inactive] harmony import specifier ./components ./main.js + 1 modules ./main.js 4:15-20 + [inactive] from origin ./foo.js + [inactive] harmony side effect evaluation ./components ./foo.js 1:0-37 + [inactive] harmony import specifier ./components ./foo.js 3:20-25 + code generated modules X bytes [code generated] + ./components/src/CompAB/CompA.js X bytes [built] [code generated] + [only some exports used: default] + [inactive] from origin ./components/src/CompAB/index.js + [inactive] harmony side effect evaluation ./CompA ./components/src/CompAB/index.js 1:0-43 + [inactive] harmony export imported specifier ./CompA ./components/src/CompAB/index.js 1:0-43 + [inactive] harmony export imported specifier ./CompAB ./components/src/index.js 1:0-40 (skipped side-effect-free modules) + harmony import specifier ./components ./foo.js 3:20-25 (skipped side-effect-free modules) + harmony import specifier ./components ./main.js + 1 modules ./main.js 3:15-20 (skipped side-effect-free modules) + ./components/src/CompAB/utils.js X bytes [built] [code generated] + from origin ./components/src/CompAB/CompA.js + [inactive] harmony side effect evaluation ./utils ./components/src/CompAB/CompA.js 1:0-35 + harmony import specifier ./utils ./components/src/CompAB/CompA.js 5:5-12 + from origin ./components/src/CompAB/CompB.js + [inactive] harmony side effect evaluation ./utils ./components/src/CompAB/CompB.js 1:0-30 + harmony import specifier ./utils ./components/src/CompAB/CompB.js 5:2-5 + from origin ./main.js + 1 modules + [inactive] harmony side effect evaluation ./utils ./main.js + 1 modules ./components/src/CompAB/CompB.js 1:0-30 + harmony import specifier ./utils ./main.js + 1 modules ./components/src/CompAB/CompB.js 5:2-5 + modules by path ./*.js X bytes + ./main.js + 1 modules X bytes [built] [code generated] + [no exports used] + entry ./main.js main + | ./main.js X bytes [built] + | [no exports used] + | ./components/src/CompAB/CompB.js X bytes [built] + | [only some exports used: default] + | [inactive] from origin ./components/src/CompAB/index.js + | [inactive] harmony side effect evaluation ./CompB ./components/src/CompAB/index.js 2:0-43 + | [inactive] harmony export imported specifier ./CompB ./components/src/CompAB/index.js 2:0-43 + | [inactive] harmony export imported specifier ./CompAB ./components/src/index.js 1:0-40 (skipped side-effect-free modules) + | harmony import specifier ./components ./main.js 4:15-20 (skipped side-effect-free modules) + ./foo.js X bytes [built] [code generated] + import() ./foo ./main.js + 1 modules ./main.js 6:0-15 +webpack x.x.x compiled successfully in X ms" +`; + +exports[`StatsTestCases should print correct stats for side-effects-optimization 1`] = ` +"asset main.js X bytes [emitted] [minimized] (name: main) +orphan modules X KiB [orphan] 4 modules +cacheable modules X KiB + ./index.js + 2 modules X KiB [built] [code generated] + [no exports] + [no exports used] + ModuleConcatenation bailout: Cannot concat with ./node_modules/module-with-export/emptyModule.js: Module is not an ECMAScript module + | ./index.js X bytes [built] + | [no exports] + | [no exports used] + | Statement (ExpressionStatement) with side effects in source code at 4:0-30 + | ./node_modules/module-with-export/index.js X KiB [built] + | [only some exports used: smallVar] + | ./node_modules/big-module/a.js X bytes [built] + | [only some exports used: a] + ./node_modules/module-with-export/emptyModule.js X bytes [built] [code generated] + [used exports unknown] + ModuleConcatenation bailout: Module is not an ECMAScript module +webpack x.x.x compiled successfully in X ms + +asset main.no-side.js X bytes [emitted] [minimized] (name: main) +runtime modules X bytes 4 modules +orphan modules X bytes [orphan] 2 modules +cacheable modules X KiB + modules by path ./node_modules/module-with-export/*.js X KiB + ./node_modules/module-with-export/index.js X KiB [built] [code generated] + [only some exports used: huh, smallVar] + ModuleConcatenation bailout: List of module exports is dynamic (huh: maybe provided (runtime-defined) and used in main) + ./node_modules/module-with-export/emptyModule.js X bytes [built] [code generated] + [used exports unknown] + ModuleConcatenation bailout: Module is not an ECMAScript module + ./index.js + 2 modules X bytes [built] [code generated] + [no exports] + [no exports used] + ModuleConcatenation bailout: Cannot concat with ./node_modules/big-module/log.js: Module ./node_modules/big-module/log.js is referenced from these modules with unsupported syntax: ./node_modules/big-module/log.js (referenced with module decorator) + ModuleConcatenation bailout: Cannot concat with ./node_modules/module-with-export/index.js: Module ./node_modules/big-module/log.js is referenced from these modules with unsupported syntax: ./node_modules/big-module/log.js (referenced with module decorator) + | ./index.js X bytes [built] + | [no exports] + | [no exports used] + | ./node_modules/big-module/index.js X bytes [built] + | [only some exports used: a, huh] + | ModuleConcatenation bailout: List of module exports is dynamic (a: maybe provided (runtime-defined) and used in main, huh: maybe provided (runtime-defined) and used in main) + | ./node_modules/big-module/a.js X bytes [built] + | [only some exports used: a, huh] + | ModuleConcatenation bailout: List of module exports is dynamic (huh: maybe provided (runtime-defined) and used in main) + ./node_modules/big-module/log.js X bytes [built] [code generated] + [only some exports used: huh] + ModuleConcatenation bailout: List of module exports is dynamic (huh: maybe provided (runtime-defined) and used in main) +webpack x.x.x compiled successfully in X ms" +`; + +exports[`StatsTestCases should print correct stats for side-effects-simple-unused 1`] = ` +"asset main.js X bytes [emitted] (name: main) +./index.js + 2 modules X bytes [built] [code generated] + [no exports used] + entry ./index main + | ./index.js X bytes [built] + | [no exports used] + | ./node_modules/pmodule/index.js X bytes [built] + | [only some exports used: default] + | [inactive] harmony side effect evaluation pmodule ./index.js 1:0-33 + | harmony import specifier pmodule ./index.js 3:12-15 + | [inactive] harmony import specifier pmodule ./index.js 3:17-18 + | ./node_modules/pmodule/c.js X bytes [built] + | [only some exports used: z] + | [inactive] from origin ./node_modules/pmodule/b.js + | [inactive] harmony side effect evaluation ./c ./node_modules/pmodule/b.js 5:0-24 + | [inactive] harmony export imported specifier ./c ./node_modules/pmodule/b.js 5:0-24 + | harmony import specifier pmodule ./index.js 3:17-18 (skipped side-effect-free modules) + | [inactive] harmony export imported specifier ./b ./node_modules/pmodule/index.js 2:0-30 (skipped side-effect-free modules) +./node_modules/pmodule/index.js X bytes [orphan] [built] + [only some exports used: default] + [inactive] harmony side effect evaluation pmodule ./index.js 1:0-33 + harmony import specifier pmodule ./index.js 3:12-15 + [inactive] harmony import specifier pmodule ./index.js 3:17-18 +./node_modules/pmodule/c.js X bytes [orphan] [built] + [only some exports used: z] + [inactive] from origin ./node_modules/pmodule/b.js + [inactive] harmony side effect evaluation ./c ./node_modules/pmodule/b.js 5:0-24 + [inactive] harmony export imported specifier ./c ./node_modules/pmodule/b.js 5:0-24 + harmony import specifier pmodule ./index.js 3:17-18 (skipped side-effect-free modules) + [inactive] harmony export imported specifier ./b ./node_modules/pmodule/index.js 2:0-30 (skipped side-effect-free modules) +./node_modules/pmodule/a.js X bytes [orphan] [built] + [module unused] + [inactive] from origin ./index.js + 2 modules + [inactive] harmony side effect evaluation ./a ./index.js + 2 modules ./node_modules/pmodule/index.js 1:0-20 + [inactive] harmony export imported specifier ./a ./index.js + 2 modules ./node_modules/pmodule/index.js 1:0-20 + [inactive] from origin ./node_modules/pmodule/index.js + [inactive] harmony side effect evaluation ./a ./node_modules/pmodule/index.js 1:0-20 + [inactive] harmony export imported specifier ./a ./node_modules/pmodule/index.js 1:0-20 +./node_modules/pmodule/b.js X bytes [orphan] [built] + [module unused] + [inactive] from origin ./index.js + 2 modules + [inactive] harmony side effect evaluation ./b ./index.js + 2 modules ./node_modules/pmodule/index.js 2:0-30 + [inactive] harmony export imported specifier ./b ./index.js + 2 modules ./node_modules/pmodule/index.js 2:0-30 + [inactive] harmony export imported specifier ./b ./index.js + 2 modules ./node_modules/pmodule/index.js 2:0-30 + [inactive] harmony export imported specifier ./b ./index.js + 2 modules ./node_modules/pmodule/index.js 2:0-30 + [inactive] from origin ./node_modules/pmodule/index.js + [inactive] harmony side effect evaluation ./b ./node_modules/pmodule/index.js 2:0-30 + [inactive] harmony export imported specifier ./b ./node_modules/pmodule/index.js 2:0-30 + [inactive] harmony export imported specifier ./b ./node_modules/pmodule/index.js 2:0-30 + [inactive] harmony export imported specifier ./b ./node_modules/pmodule/index.js 2:0-30 +webpack x.x.x compiled successfully in X ms" +`; + +exports[`StatsTestCases should print correct stats for simple 1`] = ` +"asset bundle.js X KiB [emitted] (name: main) +./index.js X bytes [built] [code generated] +webpack x.x.x compiled successfully in X ms" +`; + +exports[`StatsTestCases should print correct stats for simple-more-info 1`] = ` +"PublicPath: auto +asset bundle.js X bytes [emitted] (name: main) +./index.js X bytes [built] [code generated] + entry ./index main + X ms (resolving: X ms, restoring: X ms, integration: X ms, building: X ms, storing: X ms) +webpack x.x.x compiled successfully in X ms" +`; + +exports[`StatsTestCases should print correct stats for split-chunks 1`] = ` +"default: + Entrypoint main X KiB = default/main.js + Entrypoint a X KiB = default/a.js + Entrypoint b X KiB = default/b.js + Entrypoint c X KiB = default/c.js + chunk (runtime: a, main) default/async-g.js (async-g) X bytes <{263}> <{425}> <{628}> <{723}> <{996}> ={935}= [rendered] + > ./g ./a.js 6:0-47 + ./g.js X bytes [built] [code generated] + chunk (runtime: main) default/async-b.js (async-b) X bytes <{792}> ={425}= ={628}= ={723}= ={935}= [rendered] + > ./b ./index.js 2:0-47 + ./b.js X bytes [built] [code generated] + chunk (runtime: b) default/b.js (b) X bytes (javascript) X bytes (runtime) [entry] [rendered] + > ./b b + dependent modules X bytes [dependent] 4 modules + runtime modules X bytes 2 modules + ./b.js X bytes [built] [code generated] + chunk (runtime: main) default/async-a.js (async-a) X bytes <{792}> ={425}= ={628}= ={723}= >{49}< >{935}< [rendered] + > ./a ./index.js 1:0-47 + ./a.js + 1 modules X bytes [built] [code generated] + chunk (runtime: c) default/c.js (c) X bytes (javascript) X bytes (runtime) [entry] [rendered] + > ./c c + dependent modules X bytes [dependent] 4 modules + runtime modules X bytes 2 modules + ./c.js X bytes [built] [code generated] + chunk (runtime: main) default/425.js X bytes <{792}> ={60}= ={263}= ={628}= ={723}= ={862}= ={869}= ={935}= >{49}< >{935}< [rendered] split chunk (cache group: default) + > ./a ./index.js 1:0-47 + > ./b ./index.js 2:0-47 + > ./c ./index.js 3:0-47 + ./d.js X bytes [built] [code generated] + chunk (runtime: main) default/628.js (id hint: vendors) X bytes <{792}> ={60}= ={263}= ={425}= ={723}= ={862}= ={869}= ={935}= >{49}< >{935}< [rendered] split chunk (cache group: defaultVendors) + > ./a ./index.js 1:0-47 + > ./b ./index.js 2:0-47 + > ./c ./index.js 3:0-47 + ./node_modules/x.js X bytes [built] [code generated] + chunk (runtime: main) default/723.js (id hint: vendors) X bytes <{792}> ={60}= ={263}= ={425}= ={628}= ={935}= >{49}< >{935}< [rendered] split chunk (cache group: defaultVendors) + > ./a ./index.js 1:0-47 + > ./b ./index.js 2:0-47 + ./node_modules/y.js X bytes [built] [code generated] + chunk (runtime: main) default/main.js (main) X bytes (javascript) X KiB (runtime) >{60}< >{263}< >{425}< >{628}< >{723}< >{862}< >{869}< >{935}< [entry] [rendered] + > ./ main + runtime modules X KiB 9 modules + ./index.js X bytes [built] [code generated] + chunk (runtime: main) default/862.js (id hint: vendors) X bytes <{792}> ={425}= ={628}= ={869}= ={935}= [rendered] split chunk (cache group: defaultVendors) + > ./c ./index.js 3:0-47 + ./node_modules/z.js X bytes [built] [code generated] + chunk (runtime: main) default/async-c.js (async-c) X bytes <{792}> ={425}= ={628}= ={862}= ={935}= [rendered] + > ./c ./index.js 3:0-47 + ./c.js X bytes [built] [code generated] + chunk (runtime: a, main) default/935.js X bytes <{263}> <{425}> <{628}> <{723}> <{792}> <{996}> ={49}= ={60}= ={425}= ={628}= ={723}= ={862}= ={869}= [rendered] split chunk (cache group: default) + > ./b ./index.js 2:0-47 + > ./c ./index.js 3:0-47 + > ./g ./a.js 6:0-47 + ./f.js X bytes [built] [code generated] + chunk (runtime: a) default/a.js (a) X bytes (javascript) X KiB (runtime) >{49}< >{935}< [entry] [rendered] + > ./a a + runtime modules X KiB 9 modules + dependent modules X bytes [dependent] 3 modules + ./a.js + 1 modules X bytes [built] [code generated] + default (webpack x.x.x) compiled successfully + +all-chunks: + Entrypoint main X KiB = all-chunks/main.js + Entrypoint a X KiB = all-chunks/628.js X bytes all-chunks/723.js X bytes all-chunks/425.js X bytes all-chunks/210.js X bytes all-chunks/a.js X KiB + Entrypoint b X KiB = all-chunks/628.js X bytes all-chunks/723.js X bytes all-chunks/425.js X bytes all-chunks/935.js X bytes all-chunks/b.js X KiB + Entrypoint c X KiB = all-chunks/628.js X bytes all-chunks/862.js X bytes all-chunks/425.js X bytes all-chunks/935.js X bytes all-chunks/c.js X KiB + chunk (runtime: a, main) all-chunks/async-g.js (async-g) X bytes <{210}> <{263}> <{425}> <{628}> <{723}> <{996}> ={935}= [rendered] + > ./g ./a.js 6:0-47 + ./g.js X bytes [built] [code generated] + chunk (runtime: main) all-chunks/async-b.js (async-b) X bytes <{792}> ={425}= ={628}= ={723}= ={935}= [rendered] + > ./b ./index.js 2:0-47 + ./b.js X bytes [built] [code generated] + chunk (runtime: b) all-chunks/b.js (b) X bytes (javascript) X KiB (runtime) ={425}= ={628}= ={723}= ={935}= [entry] [rendered] + > ./b b + runtime modules X KiB 4 modules + ./b.js X bytes [built] [code generated] + chunk (runtime: a, main) all-chunks/210.js X bytes <{792}> ={263}= ={425}= ={628}= ={723}= ={996}= >{49}< >{935}< [initial] [rendered] split chunk (cache group: default) + > ./a ./index.js 1:0-47 + > ./a a + ./e.js X bytes [built] [code generated] + chunk (runtime: main) all-chunks/async-a.js (async-a) X bytes <{792}> ={210}= ={425}= ={628}= ={723}= >{49}< >{935}< [rendered] + > ./a ./index.js 1:0-47 + ./a.js X bytes [built] [code generated] + chunk (runtime: c) all-chunks/c.js (c) X bytes (javascript) X KiB (runtime) ={425}= ={628}= ={862}= ={935}= [entry] [rendered] + > ./c c + runtime modules X KiB 4 modules + ./c.js X bytes [built] [code generated] + chunk (runtime: a, b, c, main) all-chunks/425.js X bytes <{792}> ={60}= ={199}= ={210}= ={263}= ={390}= ={628}= ={723}= ={862}= ={869}= ={935}= ={996}= >{49}< >{935}< [initial] [rendered] split chunk (cache group: default) + > ./a ./index.js 1:0-47 + > ./b ./index.js 2:0-47 + > ./c ./index.js 3:0-47 + > ./a a + > ./b b + > ./c c + ./d.js X bytes [built] [code generated] + chunk (runtime: a, b, c, main) all-chunks/628.js (id hint: vendors) X bytes <{792}> ={60}= ={199}= ={210}= ={263}= ={390}= ={425}= ={723}= ={862}= ={869}= ={935}= ={996}= >{49}< >{935}< [initial] [rendered] split chunk (cache group: defaultVendors) + > ./a ./index.js 1:0-47 + > ./b ./index.js 2:0-47 + > ./c ./index.js 3:0-47 + > ./a a + > ./b b + > ./c c + ./node_modules/x.js X bytes [built] [code generated] + chunk (runtime: a, b, main) all-chunks/723.js (id hint: vendors) X bytes <{792}> ={60}= ={199}= ={210}= ={263}= ={425}= ={628}= ={935}= ={996}= >{49}< >{935}< [initial] [rendered] split chunk (cache group: defaultVendors) + > ./a ./index.js 1:0-47 + > ./b ./index.js 2:0-47 + > ./a a + > ./b b + ./node_modules/y.js X bytes [built] [code generated] + chunk (runtime: main) all-chunks/main.js (main) X bytes (javascript) X KiB (runtime) >{60}< >{210}< >{263}< >{425}< >{628}< >{723}< >{862}< >{869}< >{935}< [entry] [rendered] + > ./ main + runtime modules X KiB 9 modules + ./index.js X bytes [built] [code generated] + chunk (runtime: c, main) all-chunks/862.js (id hint: vendors) X bytes <{792}> ={390}= ={425}= ={628}= ={869}= ={935}= [initial] [rendered] split chunk (cache group: defaultVendors) + > ./c ./index.js 3:0-47 + > ./c c + ./node_modules/z.js X bytes [built] [code generated] + chunk (runtime: main) all-chunks/async-c.js (async-c) X bytes <{792}> ={425}= ={628}= ={862}= ={935}= [rendered] + > ./c ./index.js 3:0-47 + ./c.js X bytes [built] [code generated] + chunk (runtime: a, b, c, main) all-chunks/935.js X bytes <{210}> <{263}> <{425}> <{628}> <{723}> <{792}> <{996}> ={49}= ={60}= ={199}= ={390}= ={425}= ={628}= ={723}= ={862}= ={869}= [initial] [rendered] split chunk (cache group: default) + > ./b ./index.js 2:0-47 + > ./c ./index.js 3:0-47 + > ./g ./a.js 6:0-47 + > ./b b + > ./c c + ./f.js X bytes [built] [code generated] + chunk (runtime: a) all-chunks/a.js (a) X bytes (javascript) X KiB (runtime) ={210}= ={425}= ={628}= ={723}= >{49}< >{935}< [entry] [rendered] + > ./a a + runtime modules X KiB 10 modules + ./a.js X bytes [built] [code generated] + all-chunks (webpack x.x.x) compiled successfully + +manual: + Entrypoint main X KiB = manual/main.js + Entrypoint a X KiB = manual/vendors.js X KiB manual/a.js X KiB + Entrypoint b X KiB = manual/vendors.js X KiB manual/b.js X KiB + Entrypoint c X KiB = manual/vendors.js X KiB manual/c.js X KiB + chunk (runtime: a, main) manual/async-g.js (async-g) X bytes <{96}> <{263}> <{996}> [rendered] + > ./g ./a.js 6:0-47 + dependent modules X bytes [dependent] 1 module + ./g.js X bytes [built] [code generated] + chunk (runtime: main) manual/async-b.js (async-b) X bytes <{792}> ={96}= [rendered] + > ./b ./index.js 2:0-47 + dependent modules X bytes [dependent] 2 modules + ./b.js X bytes [built] [code generated] + chunk (runtime: a, b, c, main) manual/vendors.js (vendors) (id hint: vendors) X bytes <{792}> ={60}= ={199}= ={263}= ={390}= ={869}= ={996}= >{49}< [initial] [rendered] split chunk (cache group: vendors) (name: vendors) + > ./a ./index.js 1:0-47 + > ./b ./index.js 2:0-47 + > ./c ./index.js 3:0-47 + > ./a a + > x a + > y a + > z a + > ./b b + > x b + > y b + > z b + > ./c c + > x c + > y c + > z c + ./node_modules/x.js X bytes [built] [code generated] + ./node_modules/y.js X bytes [built] [code generated] + ./node_modules/z.js X bytes [built] [code generated] + chunk (runtime: b) manual/b.js (b) X bytes (javascript) X KiB (runtime) ={96}= [entry] [rendered] + > ./b b + > x b + > y b + > z b + runtime modules X KiB 4 modules + dependent modules X bytes [dependent] 2 modules + ./b.js X bytes [built] [code generated] + chunk (runtime: main) manual/async-a.js (async-a) X bytes <{792}> ={96}= >{49}< [rendered] + > ./a ./index.js 1:0-47 + dependent modules X bytes [dependent] 1 module + ./a.js + 1 modules X bytes [built] [code generated] + chunk (runtime: c) manual/c.js (c) X bytes (javascript) X KiB (runtime) ={96}= [entry] [rendered] + > ./c c + > x c + > y c + > z c + runtime modules X KiB 4 modules + dependent modules X bytes [dependent] 2 modules + ./c.js X bytes [built] [code generated] + chunk (runtime: main) manual/main.js (main) X bytes (javascript) X KiB (runtime) >{60}< >{96}< >{263}< >{869}< [entry] [rendered] + > ./ main + runtime modules X KiB 9 modules + ./index.js X bytes [built] [code generated] + chunk (runtime: main) manual/async-c.js (async-c) X bytes <{792}> ={96}= [rendered] + > ./c ./index.js 3:0-47 + dependent modules X bytes [dependent] 2 modules + ./c.js X bytes [built] [code generated] + chunk (runtime: a) manual/a.js (a) X bytes (javascript) X KiB (runtime) ={96}= >{49}< [entry] [rendered] + > ./a a + > x a + > y a + > z a + runtime modules X KiB 10 modules + dependent modules X bytes [dependent] 1 module + ./a.js + 1 modules X bytes [built] [code generated] + manual (webpack x.x.x) compiled successfully + +name-too-long: + Entrypoint main X KiB = name-too-long/main.js + Entrypoint aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa X KiB = name-too-long/628.js X bytes name-too-long/723.js X bytes name-too-long/425.js X bytes name-too-long/210.js X bytes name-too-long/XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX.js X KiB + Entrypoint bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb X KiB = name-too-long/628.js X bytes name-too-long/723.js X bytes name-too-long/425.js X bytes name-too-long/935.js X bytes name-too-long/XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX.js X KiB + Entrypoint cccccccccccccccccccccccccccccc X KiB = name-too-long/628.js X bytes name-too-long/862.js X bytes name-too-long/425.js X bytes name-too-long/935.js X bytes name-too-long/XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX.js X KiB + chunk (runtime: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, main) name-too-long/async-g.js (async-g) X bytes <{210}> <{263}> <{425}> <{505}> <{628}> <{723}> ={935}= [rendered] + > ./g ./a.js 6:0-47 + ./g.js X bytes [built] [code generated] + chunk (runtime: main) name-too-long/async-b.js (async-b) X bytes <{792}> ={425}= ={628}= ={723}= ={935}= [rendered] + > ./b ./index.js 2:0-47 + ./b.js X bytes [built] [code generated] + chunk (runtime: bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb) name-too-long/XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX.js (bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb) X bytes (javascript) X KiB (runtime) ={425}= ={628}= ={723}= ={935}= [entry] [rendered] + > ./b bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb + runtime modules X KiB 4 modules + ./b.js X bytes [built] [code generated] + chunk (runtime: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, main) name-too-long/210.js X bytes <{792}> ={263}= ={425}= ={505}= ={628}= ={723}= >{49}< >{935}< [initial] [rendered] split chunk (cache group: default) + > ./a ./index.js 1:0-47 + > ./a aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + ./e.js X bytes [built] [code generated] + chunk (runtime: main) name-too-long/async-a.js (async-a) X bytes <{792}> ={210}= ={425}= ={628}= ={723}= >{49}< >{935}< [rendered] + > ./a ./index.js 1:0-47 + ./a.js X bytes [built] [code generated] + chunk (runtime: cccccccccccccccccccccccccccccc) name-too-long/XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX.js (cccccccccccccccccccccccccccccc) X bytes (javascript) X KiB (runtime) ={425}= ={628}= ={862}= ={935}= [entry] [rendered] + > ./c cccccccccccccccccccccccccccccc + runtime modules X KiB 4 modules + ./c.js X bytes [built] [code generated] + chunk (runtime: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb, cccccccccccccccccccccccccccccc, main) name-too-long/425.js X bytes <{792}> ={60}= ={63}= ={210}= ={263}= ={349}= ={505}= ={628}= ={723}= ={862}= ={869}= ={935}= >{49}< >{935}< [initial] [rendered] split chunk (cache group: default) + > ./a ./index.js 1:0-47 + > ./b ./index.js 2:0-47 + > ./c ./index.js 3:0-47 + > ./a aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + > ./b bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb + > ./c cccccccccccccccccccccccccccccc + ./d.js X bytes [built] [code generated] + chunk (runtime: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa) name-too-long/XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX.js (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa) X bytes (javascript) X KiB (runtime) ={210}= ={425}= ={628}= ={723}= >{49}< >{935}< [entry] [rendered] + > ./a aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + runtime modules X KiB 10 modules + ./a.js X bytes [built] [code generated] + chunk (runtime: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb, cccccccccccccccccccccccccccccc, main) name-too-long/628.js (id hint: vendors) X bytes <{792}> ={60}= ={63}= ={210}= ={263}= ={349}= ={425}= ={505}= ={723}= ={862}= ={869}= ={935}= >{49}< >{935}< [initial] [rendered] split chunk (cache group: defaultVendors) + > ./a ./index.js 1:0-47 + > ./b ./index.js 2:0-47 + > ./c ./index.js 3:0-47 + > ./a aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + > ./b bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb + > ./c cccccccccccccccccccccccccccccc + ./node_modules/x.js X bytes [built] [code generated] + chunk (runtime: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb, main) name-too-long/723.js (id hint: vendors) X bytes <{792}> ={60}= ={63}= ={210}= ={263}= ={425}= ={505}= ={628}= ={935}= >{49}< >{935}< [initial] [rendered] split chunk (cache group: defaultVendors) + > ./a ./index.js 1:0-47 + > ./b ./index.js 2:0-47 + > ./a aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + > ./b bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb + ./node_modules/y.js X bytes [built] [code generated] + chunk (runtime: main) name-too-long/main.js (main) X bytes (javascript) X KiB (runtime) >{60}< >{210}< >{263}< >{425}< >{628}< >{723}< >{862}< >{869}< >{935}< [entry] [rendered] + > ./ main + runtime modules X KiB 9 modules + ./index.js X bytes [built] [code generated] + chunk (runtime: cccccccccccccccccccccccccccccc, main) name-too-long/862.js (id hint: vendors) X bytes <{792}> ={349}= ={425}= ={628}= ={869}= ={935}= [initial] [rendered] split chunk (cache group: defaultVendors) + > ./c ./index.js 3:0-47 + > ./c cccccccccccccccccccccccccccccc + ./node_modules/z.js X bytes [built] [code generated] + chunk (runtime: main) name-too-long/async-c.js (async-c) X bytes <{792}> ={425}= ={628}= ={862}= ={935}= [rendered] + > ./c ./index.js 3:0-47 + ./c.js X bytes [built] [code generated] + chunk (runtime: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb, cccccccccccccccccccccccccccccc, main) name-too-long/935.js X bytes <{210}> <{263}> <{425}> <{505}> <{628}> <{723}> <{792}> ={49}= ={60}= ={63}= ={349}= ={425}= ={628}= ={723}= ={862}= ={869}= [initial] [rendered] split chunk (cache group: default) + > ./b ./index.js 2:0-47 + > ./c ./index.js 3:0-47 + > ./g ./a.js 6:0-47 + > ./b bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb + > ./c cccccccccccccccccccccccccccccc + ./f.js X bytes [built] [code generated] + name-too-long (webpack x.x.x) compiled successfully + +custom-chunks-filter: + Entrypoint main X KiB = custom-chunks-filter/main.js + Entrypoint a X KiB = custom-chunks-filter/a.js + Entrypoint b X KiB = custom-chunks-filter/628.js X bytes custom-chunks-filter/723.js X bytes custom-chunks-filter/935.js X bytes custom-chunks-filter/425.js X bytes custom-chunks-filter/b.js X KiB + Entrypoint c X KiB = custom-chunks-filter/628.js X bytes custom-chunks-filter/862.js X bytes custom-chunks-filter/935.js X bytes custom-chunks-filter/425.js X bytes custom-chunks-filter/c.js X KiB + chunk (runtime: a, main) custom-chunks-filter/async-g.js (async-g) X bytes <{263}> <{425}> <{628}> <{723}> <{996}> ={935}= [rendered] + > ./g ./a.js 6:0-47 + ./g.js X bytes [built] [code generated] + chunk (runtime: main) custom-chunks-filter/async-b.js (async-b) X bytes <{792}> ={425}= ={628}= ={723}= ={935}= [rendered] + > ./b ./index.js 2:0-47 + ./b.js X bytes [built] [code generated] + chunk (runtime: b) custom-chunks-filter/b.js (b) X bytes (javascript) X KiB (runtime) ={425}= ={628}= ={723}= ={935}= [entry] [rendered] + > ./b b + runtime modules X KiB 4 modules + ./b.js X bytes [built] [code generated] + chunk (runtime: main) custom-chunks-filter/async-a.js (async-a) X bytes <{792}> ={425}= ={628}= ={723}= >{49}< >{935}< [rendered] + > ./a ./index.js 1:0-47 + ./a.js + 1 modules X bytes [built] [code generated] + chunk (runtime: c) custom-chunks-filter/c.js (c) X bytes (javascript) X KiB (runtime) ={425}= ={628}= ={862}= ={935}= [entry] [rendered] + > ./c c + runtime modules X KiB 4 modules + ./c.js X bytes [built] [code generated] + chunk (runtime: b, c, main) custom-chunks-filter/425.js X bytes <{792}> ={60}= ={199}= ={263}= ={390}= ={628}= ={723}= ={862}= ={869}= ={935}= >{49}< >{935}< [initial] [rendered] split chunk (cache group: default) + > ./a ./index.js 1:0-47 + > ./b ./index.js 2:0-47 + > ./c ./index.js 3:0-47 + > ./b b + > ./c c + ./d.js X bytes [built] [code generated] + chunk (runtime: b, c, main) custom-chunks-filter/628.js (id hint: vendors) X bytes <{792}> ={60}= ={199}= ={263}= ={390}= ={425}= ={723}= ={862}= ={869}= ={935}= >{49}< >{935}< [initial] [rendered] split chunk (cache group: defaultVendors) + > ./a ./index.js 1:0-47 + > ./b ./index.js 2:0-47 + > ./c ./index.js 3:0-47 + > ./b b + > ./c c + ./node_modules/x.js X bytes [built] [code generated] + chunk (runtime: b, main) custom-chunks-filter/723.js (id hint: vendors) X bytes <{792}> ={60}= ={199}= ={263}= ={425}= ={628}= ={935}= >{49}< >{935}< [initial] [rendered] split chunk (cache group: defaultVendors) + > ./a ./index.js 1:0-47 + > ./b ./index.js 2:0-47 + > ./b b + ./node_modules/y.js X bytes [built] [code generated] + chunk (runtime: main) custom-chunks-filter/main.js (main) X bytes (javascript) X KiB (runtime) >{60}< >{263}< >{425}< >{628}< >{723}< >{862}< >{869}< >{935}< [entry] [rendered] + > ./ main + runtime modules X KiB 9 modules + ./index.js X bytes [built] [code generated] + chunk (runtime: c, main) custom-chunks-filter/862.js (id hint: vendors) X bytes <{792}> ={390}= ={425}= ={628}= ={869}= ={935}= [initial] [rendered] split chunk (cache group: defaultVendors) + > ./c ./index.js 3:0-47 + > ./c c + ./node_modules/z.js X bytes [built] [code generated] + chunk (runtime: main) custom-chunks-filter/async-c.js (async-c) X bytes <{792}> ={425}= ={628}= ={862}= ={935}= [rendered] + > ./c ./index.js 3:0-47 + ./c.js X bytes [built] [code generated] + chunk (runtime: a, b, c, main) custom-chunks-filter/935.js X bytes <{263}> <{425}> <{628}> <{723}> <{792}> <{996}> ={49}= ={60}= ={199}= ={390}= ={425}= ={628}= ={723}= ={862}= ={869}= [initial] [rendered] split chunk (cache group: default) + > ./b ./index.js 2:0-47 + > ./c ./index.js 3:0-47 + > ./g ./a.js 6:0-47 + > ./b b + > ./c c + ./f.js X bytes [built] [code generated] + chunk (runtime: a) custom-chunks-filter/a.js (a) X bytes (javascript) X KiB (runtime) >{49}< >{935}< [entry] [rendered] + > ./a a + runtime modules X KiB 9 modules + dependent modules X bytes [dependent] 3 modules + ./a.js + 1 modules X bytes [built] [code generated] + custom-chunks-filter (webpack x.x.x) compiled successfully + +custom-chunks-filter-in-cache-groups: + Entrypoint main X KiB = custom-chunks-filter-in-cache-groups/main.js + Entrypoint a X KiB = custom-chunks-filter-in-cache-groups/765.js X bytes custom-chunks-filter-in-cache-groups/a.js X KiB + Entrypoint b X KiB = custom-chunks-filter-in-cache-groups/vendors.js X KiB custom-chunks-filter-in-cache-groups/b.js X KiB + Entrypoint c X KiB = custom-chunks-filter-in-cache-groups/vendors.js X KiB custom-chunks-filter-in-cache-groups/c.js X KiB + chunk (runtime: a, main) custom-chunks-filter-in-cache-groups/async-g.js (async-g) X bytes <{96}> <{263}> <{765}> <{996}> [rendered] + > ./g ./a.js 6:0-47 + dependent modules X bytes [dependent] 1 module + ./g.js X bytes [built] [code generated] + chunk (runtime: main) custom-chunks-filter-in-cache-groups/async-b.js (async-b) X bytes <{792}> ={96}= [rendered] + > ./b ./index.js 2:0-47 + dependent modules X bytes [dependent] 2 modules + ./b.js X bytes [built] [code generated] + chunk (runtime: b, c, main) custom-chunks-filter-in-cache-groups/vendors.js (vendors) (id hint: vendors) X bytes <{792}> ={60}= ={199}= ={263}= ={390}= ={869}= >{49}< [initial] [rendered] split chunk (cache group: vendors) (name: vendors) + > ./a ./index.js 1:0-47 + > ./b ./index.js 2:0-47 + > ./c ./index.js 3:0-47 + > ./b b + > x b + > y b + > z b + > ./c c + > x c + > y c + > z c + ./node_modules/x.js X bytes [built] [code generated] + ./node_modules/y.js X bytes [built] [code generated] + ./node_modules/z.js X bytes [built] [code generated] + chunk (runtime: b) custom-chunks-filter-in-cache-groups/b.js (b) X bytes (javascript) X KiB (runtime) ={96}= [entry] [rendered] + > ./b b + > x b + > y b + > z b + runtime modules X KiB 4 modules + dependent modules X bytes [dependent] 2 modules + ./b.js X bytes [built] [code generated] + chunk (runtime: main) custom-chunks-filter-in-cache-groups/async-a.js (async-a) X bytes <{792}> ={96}= >{49}< [rendered] + > ./a ./index.js 1:0-47 + dependent modules X bytes [dependent] 1 module + ./a.js + 1 modules X bytes [built] [code generated] + chunk (runtime: c) custom-chunks-filter-in-cache-groups/c.js (c) X bytes (javascript) X KiB (runtime) ={96}= [entry] [rendered] + > ./c c + > x c + > y c + > z c + runtime modules X KiB 4 modules + dependent modules X bytes [dependent] 2 modules + ./c.js X bytes [built] [code generated] + chunk (runtime: a) custom-chunks-filter-in-cache-groups/765.js (id hint: vendors) X bytes ={996}= >{49}< [initial] [rendered] split chunk (cache group: defaultVendors) + > ./a a + > x a + > y a + > z a + ./node_modules/x.js X bytes [built] [code generated] + ./node_modules/y.js X bytes [built] [code generated] + ./node_modules/z.js X bytes [built] [code generated] + chunk (runtime: main) custom-chunks-filter-in-cache-groups/main.js (main) X bytes (javascript) X KiB (runtime) >{60}< >{96}< >{263}< >{869}< [entry] [rendered] + > ./ main + runtime modules X KiB 9 modules + ./index.js X bytes [built] [code generated] + chunk (runtime: main) custom-chunks-filter-in-cache-groups/async-c.js (async-c) X bytes <{792}> ={96}= [rendered] + > ./c ./index.js 3:0-47 + dependent modules X bytes [dependent] 2 modules + ./c.js X bytes [built] [code generated] + chunk (runtime: a) custom-chunks-filter-in-cache-groups/a.js (a) X bytes (javascript) X KiB (runtime) ={765}= >{49}< [entry] [rendered] + > ./a a + > x a + > y a + > z a + runtime modules X KiB 10 modules + dependent modules X bytes [dependent] 1 module + ./a.js + 1 modules X bytes [built] [code generated] + custom-chunks-filter-in-cache-groups (webpack x.x.x) compiled successfully" +`; + +exports[`StatsTestCases should print correct stats for split-chunks-automatic-name 1`] = ` +"Entrypoint main X KiB = main.js +chunk (runtime: main) async-a.js (async-a) X bytes <{main}> ={common-d_js}= ={common-node_modules_x_js}= ={common-node_modules_y_js}= [rendered] + > ./a ./index.js 1:0-47 + ./a.js + 1 modules X bytes [built] [code generated] +chunk (runtime: main) async-b.js (async-b) X bytes <{main}> ={common-d_js}= ={common-f_js}= ={common-node_modules_x_js}= ={common-node_modules_y_js}= [rendered] + > ./b ./index.js 2:0-47 + ./b.js X bytes [built] [code generated] +chunk (runtime: main) async-c.js (async-c) X bytes <{main}> ={common-d_js}= ={common-f_js}= ={common-node_modules_x_js}= ={common-node_modules_z_js}= [rendered] + > ./c ./index.js 3:0-47 + ./c.js X bytes [built] [code generated] +chunk (runtime: main) common-d_js.js (id hint: common) X bytes <{main}> ={async-a}= ={async-b}= ={async-c}= ={common-f_js}= ={common-node_modules_x_js}= ={common-node_modules_y_js}= ={common-node_modules_z_js}= [rendered] split chunk (cache group: a) + > ./a ./index.js 1:0-47 + > ./b ./index.js 2:0-47 + > ./c ./index.js 3:0-47 + ./d.js X bytes [built] [code generated] +chunk (runtime: main) common-f_js.js (id hint: common) X bytes <{main}> ={async-b}= ={async-c}= ={common-d_js}= ={common-node_modules_x_js}= ={common-node_modules_y_js}= ={common-node_modules_z_js}= [rendered] split chunk (cache group: a) + > ./b ./index.js 2:0-47 + > ./c ./index.js 3:0-47 + ./f.js X bytes [built] [code generated] +chunk (runtime: main) common-node_modules_x_js.js (id hint: common) X bytes <{main}> ={async-a}= ={async-b}= ={async-c}= ={common-d_js}= ={common-f_js}= ={common-node_modules_y_js}= ={common-node_modules_z_js}= [rendered] split chunk (cache group: b) + > ./a ./index.js 1:0-47 + > ./b ./index.js 2:0-47 + > ./c ./index.js 3:0-47 + ./node_modules/x.js X bytes [built] [code generated] +chunk (runtime: main) common-node_modules_y_js.js (id hint: common) X bytes <{main}> ={async-a}= ={async-b}= ={common-d_js}= ={common-f_js}= ={common-node_modules_x_js}= [rendered] split chunk (cache group: b) + > ./a ./index.js 1:0-47 + > ./b ./index.js 2:0-47 + ./node_modules/y.js X bytes [built] [code generated] +chunk (runtime: main) common-node_modules_z_js.js (id hint: common) X bytes <{main}> ={async-c}= ={common-d_js}= ={common-f_js}= ={common-node_modules_x_js}= [rendered] split chunk (cache group: b) + > ./c ./index.js 3:0-47 + ./node_modules/z.js X bytes [built] [code generated] +chunk (runtime: main) main.js (main) X bytes (javascript) X KiB (runtime) >{async-a}< >{async-b}< >{async-c}< >{common-d_js}< >{common-f_js}< >{common-node_modules_x_js}< >{common-node_modules_y_js}< >{common-node_modules_z_js}< [entry] [rendered] + > ./ main + runtime modules X KiB 9 modules + ./index.js X bytes [built] [code generated] +production (webpack x.x.x) compiled successfully" +`; + +exports[`StatsTestCases should print correct stats for split-chunks-chunk-name 1`] = ` +"Entrypoint main X KiB = default/main.js +chunk (runtime: main) default/async-b.js (async-b) (id hint: vendors) X bytes <{792}> [rendered] reused as split chunk (cache group: defaultVendors) + > b ./index.js 2:0-45 + ./node_modules/b.js X bytes [built] [code generated] +chunk (runtime: main) default/async-a.js (async-a) X bytes <{792}> [rendered] + > a ./index.js 1:0-45 + ./node_modules/a.js X bytes [built] [code generated] +chunk (runtime: main) default/async-c-1.js (async-c-1) (id hint: vendors) X bytes <{792}> [rendered] reused as split chunk (cache group: defaultVendors) + > c ./index.js 3:0-47 + > c ./index.js 4:0-47 + ./node_modules/c.js X bytes [built] [code generated] +chunk (runtime: main) default/main.js (main) X bytes (javascript) X KiB (runtime) >{60}< >{263}< >{511}< [entry] [rendered] + > ./ main + runtime modules X KiB 9 modules + ./index.js X bytes [built] [code generated] +webpack x.x.x compiled successfully" +`; + +exports[`StatsTestCases should print correct stats for split-chunks-combinations 1`] = ` +"Entrypoint main X KiB = main.js +chunk (runtime: main) async-g.js (async-g) X bytes <{792}> [rendered] + > ./g ./index.js 7:0-47 + dependent modules X bytes [dependent] 1 module + ./g.js X bytes [built] [code generated] +chunk (runtime: main) async-b.js (async-b) X bytes <{792}> ={914}= [rendered] + > ./b ./index.js 2:0-47 + ./b.js X bytes [built] [code generated] +chunk (runtime: main) async-f.js (async-f) X bytes <{792}> [rendered] + > ./f ./index.js 6:0-47 + dependent modules X bytes [dependent] 1 module + ./f.js X bytes [built] [code generated] +chunk (runtime: main) async-e.js (async-e) X bytes <{792}> [rendered] + > ./e ./index.js 5:0-47 + dependent modules X bytes [dependent] 1 module + ./e.js X bytes [built] [code generated] +chunk (runtime: main) async-a.js (async-a) X bytes <{792}> ={914}= [rendered] + > ./a ./index.js 1:0-47 + ./a.js X bytes [built] [code generated] +chunk (runtime: main) async-d.js (async-d) X bytes <{792}> [rendered] + > ./d ./index.js 4:0-47 + dependent modules X bytes [dependent] 1 module + ./d.js X bytes [built] [code generated] +chunk (runtime: main) main.js (main) X bytes (javascript) X KiB (runtime) >{49}< >{60}< >{240}< >{251}< >{263}< >{442}< >{869}< >{914}< [entry] [rendered] + > ./ main + runtime modules X KiB 9 modules + ./index.js X bytes [built] [code generated] +chunk (runtime: main) async-c.js (async-c) X bytes <{792}> [rendered] + > ./c ./index.js 3:0-47 + dependent modules X bytes [dependent] 1 module + ./c.js X bytes [built] [code generated] +chunk (runtime: main) 914.js X bytes <{792}> ={60}= ={263}= [rendered] split chunk (cache group: default) + > ./a ./index.js 1:0-47 + > ./b ./index.js 2:0-47 + ./x.js X bytes [built] [code generated] + ./y.js X bytes [built] [code generated] +webpack x.x.x compiled successfully" +`; + +exports[`StatsTestCases should print correct stats for split-chunks-issue-6413 1`] = ` +"Entrypoint main X KiB = main.js +chunk (runtime: main) async-b.js (async-b) X bytes <{792}> ={476}= ={628}= [rendered] + > ./b ./index.js 2:0-47 + ./b.js X bytes [built] [code generated] +chunk (runtime: main) async-a.js (async-a) X bytes <{792}> ={476}= ={628}= [rendered] + > ./a ./index.js 1:0-47 + ./a.js X bytes [built] [code generated] +chunk (runtime: main) 476.js X bytes <{792}> ={60}= ={263}= ={628}= ={869}= [rendered] split chunk (cache group: default) + > ./a ./index.js 1:0-47 + > ./b ./index.js 2:0-47 + > ./c ./index.js 3:0-47 + ./common.js X bytes [built] [code generated] +chunk (runtime: main) 628.js (id hint: vendors) X bytes <{792}> ={60}= ={263}= ={476}= ={869}= [rendered] split chunk (cache group: defaultVendors) + > ./a ./index.js 1:0-47 + > ./b ./index.js 2:0-47 + > ./c ./index.js 3:0-47 + ./node_modules/x.js X bytes [built] [code generated] +chunk (runtime: main) main.js (main) X bytes (javascript) X KiB (runtime) >{60}< >{263}< >{476}< >{628}< >{869}< [entry] [rendered] + > ./ main + runtime modules X KiB 9 modules + ./index.js X bytes [built] [code generated] +chunk (runtime: main) async-c.js (async-c) X bytes <{792}> ={476}= ={628}= [rendered] + > ./c ./index.js 3:0-47 + ./c.js X bytes [built] [code generated] +default (webpack x.x.x) compiled successfully" +`; + +exports[`StatsTestCases should print correct stats for split-chunks-issue-6696 1`] = ` +"Entrypoint main X KiB = vendors.js X bytes main.js X KiB +chunk (runtime: main) async-b.js (async-b) X bytes <{96}> <{792}> [rendered] + > ./b ./index.js 3:0-47 + dependent modules X bytes [dependent] 1 module + ./b.js X bytes [built] [code generated] +chunk (runtime: main) vendors.js (vendors) (id hint: vendors) X bytes ={792}= >{60}< >{263}< [initial] [rendered] split chunk (cache group: vendors) (name: vendors) + > ./ main + ./node_modules/y.js X bytes [built] [code generated] +chunk (runtime: main) async-a.js (async-a) X bytes <{96}> <{792}> [rendered] + > ./a ./index.js 2:0-47 + dependent modules X bytes [dependent] 1 module + ./a.js X bytes [built] [code generated] +chunk (runtime: main) main.js (main) X bytes (javascript) X KiB (runtime) ={96}= >{60}< >{263}< [entry] [rendered] + > ./ main + runtime modules X KiB 10 modules + ./index.js X bytes [built] [code generated] +default (webpack x.x.x) compiled successfully" +`; + +exports[`StatsTestCases should print correct stats for split-chunks-issue-7401 1`] = ` +"Entrypoint a X KiB = 628.js X bytes a.js X KiB +Entrypoint b X KiB = b.js +Chunk Group c X bytes = 628.js X bytes c.js X bytes +chunk (runtime: b) b.js (b) X bytes (javascript) X KiB (runtime) >{390}< >{628}< [entry] [rendered] + > ./b b + runtime modules X KiB 9 modules + ./b.js X bytes [built] [code generated] +chunk (runtime: b) c.js (c) X bytes <{199}> ={628}= [rendered] + > ./c ./b.js 1:0-41 + ./c.js X bytes [built] [code generated] +chunk (runtime: a, b) 628.js (id hint: vendors) X bytes <{199}> ={390}= ={996}= [initial] [rendered] split chunk (cache group: defaultVendors) + > ./c ./b.js 1:0-41 + > ./a a + ./node_modules/x.js X bytes [built] [code generated] +chunk (runtime: a) a.js (a) X bytes (javascript) X KiB (runtime) ={628}= [entry] [rendered] + > ./a a + runtime modules X KiB 4 modules + ./a.js X bytes [built] [code generated] +default (webpack x.x.x) compiled successfully" +`; + +exports[`StatsTestCases should print correct stats for split-chunks-keep-remaining-size 1`] = ` +"Entrypoint main X KiB = default/main.js +chunk (runtime: main) default/async-b.js (async-b) X bytes <{792}> ={784}= [rendered] + > ./b ./index.js 2:0-47 + ./b.js X bytes [built] [code generated] +chunk (runtime: main) default/async-a.js (async-a) X bytes <{792}> [rendered] + > ./a ./index.js 1:0-47 + ./a.js + 1 modules X bytes [built] [code generated] +chunk (runtime: main) default/async-d.js (async-d) X bytes <{792}> ={670}= [rendered] + > ./d ./index.js 4:0-47 + ./d.js X bytes [built] [code generated] +chunk (runtime: main) default/670.js (id hint: vendors) X bytes <{792}> ={442}= [rendered] split chunk (cache group: defaultVendors) + > ./d ./index.js 4:0-47 + ./node_modules/shared.js?3 X bytes [built] [code generated] + ./node_modules/shared.js?4 X bytes [built] [code generated] +chunk (runtime: main) default/784.js (id hint: vendors) X bytes <{792}> ={60}= ={869}= [rendered] split chunk (cache group: defaultVendors) + > ./b ./index.js 2:0-47 + > ./c ./index.js 3:0-47 + ./node_modules/shared.js?2 X bytes [built] [code generated] +chunk (runtime: main) default/main.js (main) X bytes (javascript) X KiB (runtime) >{60}< >{263}< >{442}< >{670}< >{784}< >{869}< [entry] [rendered] + > ./ main + runtime modules X KiB 9 modules + ./index.js X bytes [built] [code generated] +chunk (runtime: main) default/async-c.js (async-c) X bytes <{792}> ={784}= [rendered] + > ./c ./index.js 3:0-47 + ./c.js X bytes [built] [code generated] +webpack x.x.x compiled successfully" +`; + +exports[`StatsTestCases should print correct stats for split-chunks-max-size 1`] = ` +"production: + Entrypoint main X KiB = 13 assets + chunk (runtime: main) prod-main-XXXXXXXX.js (main-6bb16544) X KiB ={59}= ={121}= ={124}= ={161}= ={181}= ={241}= ={273}= ={382}= ={409}= ={808}= ={942}= ={945}= [initial] [rendered] + > ./ main + ./in-some-directory/very-big.js?1 X KiB [built] [code generated] + chunk (runtime: main) prod-main-XXXXXXXX.js (main-1df31ce3) X KiB ={37}= ={121}= ={124}= ={161}= ={181}= ={241}= ={273}= ={382}= ={409}= ={808}= ={942}= ={945}= [initial] [rendered] + > ./ main + ./index.js X KiB [built] [code generated] + chunk (runtime: main) prod-main-XXXXXXXX.js (main-10f51d07) X bytes ={37}= ={59}= ={124}= ={161}= ={181}= ={241}= ={273}= ={382}= ={409}= ={808}= ={942}= ={945}= [initial] [rendered] + > ./ main + ./big.js?1 X bytes [built] [code generated] + ./big.js?2 X bytes [built] [code generated] + chunk (runtime: main) prod-main-XXXXXXXX.js (main-12217e1d) X KiB (javascript) X KiB (runtime) ={37}= ={59}= ={121}= ={161}= ={181}= ={241}= ={273}= ={382}= ={409}= ={808}= ={942}= ={945}= [entry] [rendered] + > ./ main + runtime modules X KiB 5 modules + ./very-big.js?1 X KiB [built] [code generated] + chunk (runtime: main) prod-main-XXXXXXXX.js (main-77a8c116) X KiB ={37}= ={59}= ={121}= ={124}= ={181}= ={241}= ={273}= ={382}= ={409}= ={808}= ={942}= ={945}= [initial] [rendered] + > ./ main + ./very-big.js?2 X KiB [built] [code generated] + chunk (runtime: main) prod-main-XXXXXXXX.js (main-e7c5ace7) X bytes ={37}= ={59}= ={121}= ={124}= ={161}= ={241}= ={273}= ={382}= ={409}= ={808}= ={942}= ={945}= [initial] [rendered] + > ./ main + ./small.js?1 X bytes [built] [code generated] + ./small.js?2 X bytes [built] [code generated] + ./small.js?3 X bytes [built] [code generated] + ./small.js?4 X bytes [built] [code generated] + ./small.js?5 X bytes [built] [code generated] + ./small.js?6 X bytes [built] [code generated] + ./small.js?7 X bytes [built] [code generated] + ./small.js?8 X bytes [built] [code generated] + ./small.js?9 X bytes [built] [code generated] + chunk (runtime: main) prod-241.js (id hint: vendors) X bytes ={37}= ={59}= ={121}= ={124}= ={161}= ={181}= ={273}= ={382}= ={409}= ={808}= ={942}= ={945}= [initial] [rendered] split chunk (cache group: defaultVendors) + > ./ main + ./node_modules/big.js?1 X bytes [built] [code generated] + ./node_modules/small.js?1 X bytes [built] [code generated] + ./node_modules/small.js?2 X bytes [built] [code generated] + chunk (runtime: main) prod-273.js (id hint: vendors) X KiB ={37}= ={59}= ={121}= ={124}= ={161}= ={181}= ={241}= ={382}= ={409}= ={808}= ={942}= ={945}= [initial] [rendered] split chunk (cache group: defaultVendors) + > ./ main + ./node_modules/very-big.js?1 X KiB [built] [code generated] + chunk (runtime: main) prod-main-XXXXXXXX.js (main-5cfff2c6) X bytes ={37}= ={59}= ={121}= ={124}= ={161}= ={181}= ={241}= ={273}= ={409}= ={808}= ={942}= ={945}= [initial] [rendered] + > ./ main + ./subfolder/big.js?1 X bytes [built] [code generated] + ./subfolder/big.js?2 X bytes [built] [code generated] + chunk (runtime: main) prod-main-XXXXXXXX.js (main-3c98d7c3) X bytes ={37}= ={59}= ={121}= ={124}= ={161}= ={181}= ={241}= ={273}= ={382}= ={808}= ={942}= ={945}= [initial] [rendered] + > ./ main + ./in-some-directory/big.js?1 X bytes [built] [code generated] + ./in-some-directory/small.js?1 X bytes [built] [code generated] + ./in-some-directory/small.js?2 X bytes [built] [code generated] + ./in-some-directory/small.js?3 X bytes [built] [code generated] + ./in-some-directory/small.js?4 X bytes [built] [code generated] + chunk (runtime: main) prod-main-XXXXXXXX.js (main-2f7dcf2e) X bytes ={37}= ={59}= ={121}= ={124}= ={161}= ={181}= ={241}= ={273}= ={382}= ={409}= ={942}= ={945}= [initial] [rendered] + > ./ main + ./inner-module/small.js?1 X bytes [built] [code generated] + ./inner-module/small.js?2 X bytes [built] [code generated] + ./inner-module/small.js?3 X bytes [built] [code generated] + ./inner-module/small.js?4 X bytes [built] [code generated] + ./inner-module/small.js?5 X bytes [built] [code generated] + ./inner-module/small.js?6 X bytes [built] [code generated] + ./inner-module/small.js?7 X bytes [built] [code generated] + ./inner-module/small.js?8 X bytes [built] [code generated] + ./inner-module/small.js?9 X bytes [built] [code generated] + chunk (runtime: main) prod-main-XXXXXXXX.js (main-1443e336) X bytes ={37}= ={59}= ={121}= ={124}= ={161}= ={181}= ={241}= ={273}= ={382}= ={409}= ={808}= ={945}= [initial] [rendered] + > ./ main + ./subfolder/small.js?1 X bytes [built] [code generated] + ./subfolder/small.js?2 X bytes [built] [code generated] + ./subfolder/small.js?3 X bytes [built] [code generated] + ./subfolder/small.js?4 X bytes [built] [code generated] + ./subfolder/small.js?5 X bytes [built] [code generated] + ./subfolder/small.js?6 X bytes [built] [code generated] + ./subfolder/small.js?7 X bytes [built] [code generated] + ./subfolder/small.js?8 X bytes [built] [code generated] + ./subfolder/small.js?9 X bytes [built] [code generated] + chunk (runtime: main) prod-main-XXXXXXXX.js (main-89a43a0f) X KiB ={37}= ={59}= ={121}= ={124}= ={161}= ={181}= ={241}= ={273}= ={382}= ={409}= ={808}= ={942}= [initial] [rendered] + > ./ main + ./very-big.js?3 X KiB [built] [code generated] + production (webpack x.x.x) compiled successfully + +development: + Entrypoint main X KiB = 13 assets + chunk (runtime: main) dev-main-big_js-1.js (main-big_js-1) X bytes ={main-in-some-directory_b}= ={main-in-some-directory_very-big_js-8d76cf03}= ={main-index_js-41f5a26e}= ={main-inner-module_small_js-3}= ={main-small_js-1}= ={main-subfolder_big_js-b}= ={main-subfolder_small_js-1}= ={main-very-big_js-08cf55cf}= ={main-very-big_js-4647fb9d}= ={main-very-big_js-62f7f644}= ={vendors-node_modules_big_js_1-node_modules_small_js_1-node_modules_small_js_2}= ={vendors-node_modules_very-big_js_1}= [initial] [rendered] + > ./ main + ./big.js?1 X bytes [built] [code generated] + ./big.js?2 X bytes [built] [code generated] + chunk (runtime: main) dev-main-in-some-directory_b.js (main-in-some-directory_b) X bytes ={main-big_js-1}= ={main-in-some-directory_very-big_js-8d76cf03}= ={main-index_js-41f5a26e}= ={main-inner-module_small_js-3}= ={main-small_js-1}= ={main-subfolder_big_js-b}= ={main-subfolder_small_js-1}= ={main-very-big_js-08cf55cf}= ={main-very-big_js-4647fb9d}= ={main-very-big_js-62f7f644}= ={vendors-node_modules_big_js_1-node_modules_small_js_1-node_modules_small_js_2}= ={vendors-node_modules_very-big_js_1}= [initial] [rendered] + > ./ main + ./in-some-directory/big.js?1 X bytes [built] [code generated] + ./in-some-directory/small.js?1 X bytes [built] [code generated] + ./in-some-directory/small.js?2 X bytes [built] [code generated] + ./in-some-directory/small.js?3 X bytes [built] [code generated] + ./in-some-directory/small.js?4 X bytes [built] [code generated] + chunk (runtime: main) dev-main-in-some-directory_very-big_js-XXXXXXXX.js (main-in-some-directory_very-big_js-8d76cf03) X KiB ={main-big_js-1}= ={main-in-some-directory_b}= ={main-index_js-41f5a26e}= ={main-inner-module_small_js-3}= ={main-small_js-1}= ={main-subfolder_big_js-b}= ={main-subfolder_small_js-1}= ={main-very-big_js-08cf55cf}= ={main-very-big_js-4647fb9d}= ={main-very-big_js-62f7f644}= ={vendors-node_modules_big_js_1-node_modules_small_js_1-node_modules_small_js_2}= ={vendors-node_modules_very-big_js_1}= [initial] [rendered] + > ./ main + ./in-some-directory/very-big.js?1 X KiB [built] [code generated] + chunk (runtime: main) dev-main-index_js-XXXXXXXX.js (main-index_js-41f5a26e) X KiB ={main-big_js-1}= ={main-in-some-directory_b}= ={main-in-some-directory_very-big_js-8d76cf03}= ={main-inner-module_small_js-3}= ={main-small_js-1}= ={main-subfolder_big_js-b}= ={main-subfolder_small_js-1}= ={main-very-big_js-08cf55cf}= ={main-very-big_js-4647fb9d}= ={main-very-big_js-62f7f644}= ={vendors-node_modules_big_js_1-node_modules_small_js_1-node_modules_small_js_2}= ={vendors-node_modules_very-big_js_1}= [initial] [rendered] + > ./ main + ./index.js X KiB [built] [code generated] + chunk (runtime: main) dev-main-inner-module_small_js-3.js (main-inner-module_small_js-3) X bytes ={main-big_js-1}= ={main-in-some-directory_b}= ={main-in-some-directory_very-big_js-8d76cf03}= ={main-index_js-41f5a26e}= ={main-small_js-1}= ={main-subfolder_big_js-b}= ={main-subfolder_small_js-1}= ={main-very-big_js-08cf55cf}= ={main-very-big_js-4647fb9d}= ={main-very-big_js-62f7f644}= ={vendors-node_modules_big_js_1-node_modules_small_js_1-node_modules_small_js_2}= ={vendors-node_modules_very-big_js_1}= [initial] [rendered] + > ./ main + ./inner-module/small.js?1 X bytes [built] [code generated] + ./inner-module/small.js?2 X bytes [built] [code generated] + ./inner-module/small.js?3 X bytes [built] [code generated] + ./inner-module/small.js?4 X bytes [built] [code generated] + ./inner-module/small.js?5 X bytes [built] [code generated] + ./inner-module/small.js?6 X bytes [built] [code generated] + ./inner-module/small.js?7 X bytes [built] [code generated] + ./inner-module/small.js?8 X bytes [built] [code generated] + ./inner-module/small.js?9 X bytes [built] [code generated] + chunk (runtime: main) dev-main-small_js-1.js (main-small_js-1) X bytes ={main-big_js-1}= ={main-in-some-directory_b}= ={main-in-some-directory_very-big_js-8d76cf03}= ={main-index_js-41f5a26e}= ={main-inner-module_small_js-3}= ={main-subfolder_big_js-b}= ={main-subfolder_small_js-1}= ={main-very-big_js-08cf55cf}= ={main-very-big_js-4647fb9d}= ={main-very-big_js-62f7f644}= ={vendors-node_modules_big_js_1-node_modules_small_js_1-node_modules_small_js_2}= ={vendors-node_modules_very-big_js_1}= [initial] [rendered] + > ./ main + ./small.js?1 X bytes [built] [code generated] + ./small.js?2 X bytes [built] [code generated] + ./small.js?3 X bytes [built] [code generated] + ./small.js?4 X bytes [built] [code generated] + ./small.js?5 X bytes [built] [code generated] + ./small.js?6 X bytes [built] [code generated] + ./small.js?7 X bytes [built] [code generated] + ./small.js?8 X bytes [built] [code generated] + ./small.js?9 X bytes [built] [code generated] + chunk (runtime: main) dev-main-subfolder_big_js-b.js (main-subfolder_big_js-b) X bytes ={main-big_js-1}= ={main-in-some-directory_b}= ={main-in-some-directory_very-big_js-8d76cf03}= ={main-index_js-41f5a26e}= ={main-inner-module_small_js-3}= ={main-small_js-1}= ={main-subfolder_small_js-1}= ={main-very-big_js-08cf55cf}= ={main-very-big_js-4647fb9d}= ={main-very-big_js-62f7f644}= ={vendors-node_modules_big_js_1-node_modules_small_js_1-node_modules_small_js_2}= ={vendors-node_modules_very-big_js_1}= [initial] [rendered] + > ./ main + ./subfolder/big.js?1 X bytes [built] [code generated] + ./subfolder/big.js?2 X bytes [built] [code generated] + chunk (runtime: main) dev-main-subfolder_small_js-1.js (main-subfolder_small_js-1) X bytes ={main-big_js-1}= ={main-in-some-directory_b}= ={main-in-some-directory_very-big_js-8d76cf03}= ={main-index_js-41f5a26e}= ={main-inner-module_small_js-3}= ={main-small_js-1}= ={main-subfolder_big_js-b}= ={main-very-big_js-08cf55cf}= ={main-very-big_js-4647fb9d}= ={main-very-big_js-62f7f644}= ={vendors-node_modules_big_js_1-node_modules_small_js_1-node_modules_small_js_2}= ={vendors-node_modules_very-big_js_1}= [initial] [rendered] + > ./ main + ./subfolder/small.js?1 X bytes [built] [code generated] + ./subfolder/small.js?2 X bytes [built] [code generated] + ./subfolder/small.js?3 X bytes [built] [code generated] + ./subfolder/small.js?4 X bytes [built] [code generated] + ./subfolder/small.js?5 X bytes [built] [code generated] + ./subfolder/small.js?6 X bytes [built] [code generated] + ./subfolder/small.js?7 X bytes [built] [code generated] + ./subfolder/small.js?8 X bytes [built] [code generated] + ./subfolder/small.js?9 X bytes [built] [code generated] + chunk (runtime: main) dev-main-very-big_js-XXXXXXXX.js (main-very-big_js-08cf55cf) X KiB ={main-big_js-1}= ={main-in-some-directory_b}= ={main-in-some-directory_very-big_js-8d76cf03}= ={main-index_js-41f5a26e}= ={main-inner-module_small_js-3}= ={main-small_js-1}= ={main-subfolder_big_js-b}= ={main-subfolder_small_js-1}= ={main-very-big_js-4647fb9d}= ={main-very-big_js-62f7f644}= ={vendors-node_modules_big_js_1-node_modules_small_js_1-node_modules_small_js_2}= ={vendors-node_modules_very-big_js_1}= [initial] [rendered] + > ./ main + ./very-big.js?2 X KiB [built] [code generated] + chunk (runtime: main) dev-main-very-big_js-XXXXXXXX.js (main-very-big_js-4647fb9d) X KiB ={main-big_js-1}= ={main-in-some-directory_b}= ={main-in-some-directory_very-big_js-8d76cf03}= ={main-index_js-41f5a26e}= ={main-inner-module_small_js-3}= ={main-small_js-1}= ={main-subfolder_big_js-b}= ={main-subfolder_small_js-1}= ={main-very-big_js-08cf55cf}= ={main-very-big_js-62f7f644}= ={vendors-node_modules_big_js_1-node_modules_small_js_1-node_modules_small_js_2}= ={vendors-node_modules_very-big_js_1}= [initial] [rendered] + > ./ main + ./very-big.js?3 X KiB [built] [code generated] + chunk (runtime: main) dev-main-very-big_js-XXXXXXXX.js (main-very-big_js-62f7f644) X KiB (javascript) X KiB (runtime) ={main-big_js-1}= ={main-in-some-directory_b}= ={main-in-some-directory_very-big_js-8d76cf03}= ={main-index_js-41f5a26e}= ={main-inner-module_small_js-3}= ={main-small_js-1}= ={main-subfolder_big_js-b}= ={main-subfolder_small_js-1}= ={main-very-big_js-08cf55cf}= ={main-very-big_js-4647fb9d}= ={vendors-node_modules_big_js_1-node_modules_small_js_1-node_modules_small_js_2}= ={vendors-node_modules_very-big_js_1}= [entry] [rendered] + > ./ main + runtime modules X KiB 6 modules + ./very-big.js?1 X KiB [built] [code generated] + chunk (runtime: main) dev-vendors-node_modules_big_js_1-node_modules_small_js_1-node_modules_small_js_2.js (id hint: vendors) X bytes ={main-big_js-1}= ={main-in-some-directory_b}= ={main-in-some-directory_very-big_js-8d76cf03}= ={main-index_js-41f5a26e}= ={main-inner-module_small_js-3}= ={main-small_js-1}= ={main-subfolder_big_js-b}= ={main-subfolder_small_js-1}= ={main-very-big_js-08cf55cf}= ={main-very-big_js-4647fb9d}= ={main-very-big_js-62f7f644}= ={vendors-node_modules_very-big_js_1}= [initial] [rendered] split chunk (cache group: defaultVendors) + > ./ main + ./node_modules/big.js?1 X bytes [built] [code generated] + ./node_modules/small.js?1 X bytes [built] [code generated] + ./node_modules/small.js?2 X bytes [built] [code generated] + chunk (runtime: main) dev-vendors-node_modules_very-big_js_1.js (id hint: vendors) X KiB ={main-big_js-1}= ={main-in-some-directory_b}= ={main-in-some-directory_very-big_js-8d76cf03}= ={main-index_js-41f5a26e}= ={main-inner-module_small_js-3}= ={main-small_js-1}= ={main-subfolder_big_js-b}= ={main-subfolder_small_js-1}= ={main-very-big_js-08cf55cf}= ={main-very-big_js-4647fb9d}= ={main-very-big_js-62f7f644}= ={vendors-node_modules_big_js_1-node_modules_small_js_1-node_modules_small_js_2}= [initial] [rendered] split chunk (cache group: defaultVendors) + > ./ main + ./node_modules/very-big.js?1 X KiB [built] [code generated] + development (webpack x.x.x) compiled successfully + +switched: + Entrypoint main X KiB = 9 assets + chunk (runtime: main) switched-main-XXXXXXXX.js (main-6bb16544) X KiB ={59}= ={124}= ={161}= ={210}= ={241}= ={273}= ={866}= ={945}= [initial] [rendered] + > ./ main + ./in-some-directory/very-big.js?1 X KiB [built] [code generated] + chunk (runtime: main) switched-main-XXXXXXXX.js (main-1df31ce3) X KiB ={37}= ={124}= ={161}= ={210}= ={241}= ={273}= ={866}= ={945}= [initial] [rendered] + > ./ main + ./index.js X KiB [built] [code generated] + chunk (runtime: main) switched-main-XXXXXXXX.js (main-12217e1d) X KiB (javascript) X KiB (runtime) ={37}= ={59}= ={161}= ={210}= ={241}= ={273}= ={866}= ={945}= [entry] [rendered] + > ./ main + runtime modules X KiB 5 modules + ./very-big.js?1 X KiB [built] [code generated] + chunk (runtime: main) switched-main-XXXXXXXX.js (main-77a8c116) X KiB ={37}= ={59}= ={124}= ={210}= ={241}= ={273}= ={866}= ={945}= [initial] [rendered] + > ./ main + ./very-big.js?2 X KiB [built] [code generated] + chunk (runtime: main) switched-main-XXXXXXXX.js (main-7aeafcb2) X KiB ={37}= ={59}= ={124}= ={161}= ={241}= ={273}= ={866}= ={945}= [initial] [rendered] + > ./ main + modules by path ./inner-module/*.js X bytes + ./inner-module/small.js?1 X bytes [built] [code generated] + + 8 modules + modules by path ./in-some-directory/*.js X bytes + ./in-some-directory/big.js?1 X bytes [built] [code generated] + ./in-some-directory/small.js?1 X bytes [built] [code generated] + + 3 modules + modules by path ./*.js X bytes + ./big.js?1 X bytes [built] [code generated] + ./big.js?2 X bytes [built] [code generated] + chunk (runtime: main) switchXX-XXX.js (id hint: vendors) X bytes ={37}= ={59}= ={124}= ={161}= ={210}= ={273}= ={866}= ={945}= [initial] [rendered] split chunk (cache group: defaultVendors) + > ./ main + ./node_modules/big.js?1 X bytes [built] [code generated] + ./node_modules/small.js?1 X bytes [built] [code generated] + ./node_modules/small.js?2 X bytes [built] [code generated] + chunk (runtime: main) switchXX-XXX.js (id hint: vendors) X KiB ={37}= ={59}= ={124}= ={161}= ={210}= ={241}= ={866}= ={945}= [initial] [rendered] split chunk (cache group: defaultVendors) + > ./ main + ./node_modules/very-big.js?1 X KiB [built] [code generated] + chunk (runtime: main) switched-main-XXXXXXXX.js (main-879072e3) X KiB ={37}= ={59}= ={124}= ={161}= ={210}= ={241}= ={273}= ={945}= [initial] [rendered] + > ./ main + modules by path ./subfolder/*.js X KiB + ./subfolder/big.js?1 X bytes [built] [code generated] + ./subfolder/big.js?2 X bytes [built] [code generated] + ./subfolder/small.js?1 X bytes [built] [code generated] + + 8 modules + modules by path ./*.js X bytes + ./small.js?1 X bytes [built] [code generated] + ./small.js?2 X bytes [built] [code generated] + ./small.js?3 X bytes [built] [code generated] + + 6 modules + chunk (runtime: main) switched-main-XXXXXXXX.js (main-89a43a0f) X KiB ={37}= ={59}= ={124}= ={161}= ={210}= ={241}= ={273}= ={866}= [initial] [rendered] + > ./ main + ./very-big.js?3 X KiB [built] [code generated] + + WARNING in SplitChunksPlugin + Cache group defaultVendors + Configured minSize (X bytes) is bigger than maxSize (X bytes). + This seem to be a invalid optimization.splitChunks configuration. + + WARNING in SplitChunksPlugin + Fallback cache group + Configured minSize (X bytes) is bigger than maxSize (X bytes). + This seem to be a invalid optimization.splitChunks configuration. + + switched (webpack x.x.x) compiled with 2 warnings + +zero-min: + Entrypoint main X KiB = 13 assets + chunk (runtime: main) zero-min-main-XXXXXXXX.js (main-6bb16544) X KiB ={59}= ={121}= ={124}= ={161}= ={181}= ={241}= ={273}= ={382}= ={409}= ={808}= ={942}= ={945}= [initial] [rendered] + > ./ main + ./in-some-directory/very-big.js?1 X KiB [built] [code generated] + chunk (runtime: main) zero-min-main-XXXXXXXX.js (main-1df31ce3) X KiB ={37}= ={121}= ={124}= ={161}= ={181}= ={241}= ={273}= ={382}= ={409}= ={808}= ={942}= ={945}= [initial] [rendered] + > ./ main + ./index.js X KiB [built] [code generated] + chunk (runtime: main) zero-min-main-XXXXXXXX.js (main-10f51d07) X bytes ={37}= ={59}= ={124}= ={161}= ={181}= ={241}= ={273}= ={382}= ={409}= ={808}= ={942}= ={945}= [initial] [rendered] + > ./ main + ./big.js?1 X bytes [built] [code generated] + ./big.js?2 X bytes [built] [code generated] + chunk (runtime: main) zero-min-main-XXXXXXXX.js (main-12217e1d) X KiB (javascript) X KiB (runtime) ={37}= ={59}= ={121}= ={161}= ={181}= ={241}= ={273}= ={382}= ={409}= ={808}= ={942}= ={945}= [entry] [rendered] + > ./ main + runtime modules X KiB 5 modules + ./very-big.js?1 X KiB [built] [code generated] + chunk (runtime: main) zero-min-main-XXXXXXXX.js (main-77a8c116) X KiB ={37}= ={59}= ={121}= ={124}= ={181}= ={241}= ={273}= ={382}= ={409}= ={808}= ={942}= ={945}= [initial] [rendered] + > ./ main + ./very-big.js?2 X KiB [built] [code generated] + chunk (runtime: main) zero-min-main-XXXXXXXX.js (main-e7c5ace7) X bytes ={37}= ={59}= ={121}= ={124}= ={161}= ={241}= ={273}= ={382}= ={409}= ={808}= ={942}= ={945}= [initial] [rendered] + > ./ main + ./small.js?1 X bytes [built] [code generated] + ./small.js?2 X bytes [built] [code generated] + ./small.js?3 X bytes [built] [code generated] + ./small.js?4 X bytes [built] [code generated] + ./small.js?5 X bytes [built] [code generated] + ./small.js?6 X bytes [built] [code generated] + ./small.js?7 X bytes [built] [code generated] + ./small.js?8 X bytes [built] [code generated] + ./small.js?9 X bytes [built] [code generated] + chunk (runtime: main) zero-min-241.js (id hint: vendors) X bytes ={37}= ={59}= ={121}= ={124}= ={161}= ={181}= ={273}= ={382}= ={409}= ={808}= ={942}= ={945}= [initial] [rendered] split chunk (cache group: defaultVendors) + > ./ main + ./node_modules/big.js?1 X bytes [built] [code generated] + ./node_modules/small.js?1 X bytes [built] [code generated] + ./node_modules/small.js?2 X bytes [built] [code generated] + chunk (runtime: main) zero-min-273.js (id hint: vendors) X KiB ={37}= ={59}= ={121}= ={124}= ={161}= ={181}= ={241}= ={382}= ={409}= ={808}= ={942}= ={945}= [initial] [rendered] split chunk (cache group: defaultVendors) + > ./ main + ./node_modules/very-big.js?1 X KiB [built] [code generated] + chunk (runtime: main) zero-min-main-XXXXXXXX.js (main-5cfff2c6) X bytes ={37}= ={59}= ={121}= ={124}= ={161}= ={181}= ={241}= ={273}= ={409}= ={808}= ={942}= ={945}= [initial] [rendered] + > ./ main + ./subfolder/big.js?1 X bytes [built] [code generated] + ./subfolder/big.js?2 X bytes [built] [code generated] + chunk (runtime: main) zero-min-main-XXXXXXXX.js (main-3c98d7c3) X bytes ={37}= ={59}= ={121}= ={124}= ={161}= ={181}= ={241}= ={273}= ={382}= ={808}= ={942}= ={945}= [initial] [rendered] + > ./ main + ./in-some-directory/big.js?1 X bytes [built] [code generated] + ./in-some-directory/small.js?1 X bytes [built] [code generated] + ./in-some-directory/small.js?2 X bytes [built] [code generated] + ./in-some-directory/small.js?3 X bytes [built] [code generated] + ./in-some-directory/small.js?4 X bytes [built] [code generated] + chunk (runtime: main) zero-min-main-XXXXXXXX.js (main-2f7dcf2e) X bytes ={37}= ={59}= ={121}= ={124}= ={161}= ={181}= ={241}= ={273}= ={382}= ={409}= ={942}= ={945}= [initial] [rendered] + > ./ main + ./inner-module/small.js?1 X bytes [built] [code generated] + ./inner-module/small.js?2 X bytes [built] [code generated] + ./inner-module/small.js?3 X bytes [built] [code generated] + ./inner-module/small.js?4 X bytes [built] [code generated] + ./inner-module/small.js?5 X bytes [built] [code generated] + ./inner-module/small.js?6 X bytes [built] [code generated] + ./inner-module/small.js?7 X bytes [built] [code generated] + ./inner-module/small.js?8 X bytes [built] [code generated] + ./inner-module/small.js?9 X bytes [built] [code generated] + chunk (runtime: main) zero-min-main-XXXXXXXX.js (main-1443e336) X bytes ={37}= ={59}= ={121}= ={124}= ={161}= ={181}= ={241}= ={273}= ={382}= ={409}= ={808}= ={945}= [initial] [rendered] + > ./ main + ./subfolder/small.js?1 X bytes [built] [code generated] + ./subfolder/small.js?2 X bytes [built] [code generated] + ./subfolder/small.js?3 X bytes [built] [code generated] + ./subfolder/small.js?4 X bytes [built] [code generated] + ./subfolder/small.js?5 X bytes [built] [code generated] + ./subfolder/small.js?6 X bytes [built] [code generated] + ./subfolder/small.js?7 X bytes [built] [code generated] + ./subfolder/small.js?8 X bytes [built] [code generated] + ./subfolder/small.js?9 X bytes [built] [code generated] + chunk (runtime: main) zero-min-main-XXXXXXXX.js (main-89a43a0f) X KiB ={37}= ={59}= ={121}= ={124}= ={161}= ={181}= ={241}= ={273}= ={382}= ={409}= ={808}= ={942}= [initial] [rendered] + > ./ main + ./very-big.js?3 X KiB [built] [code generated] + zero-min (webpack x.x.x) compiled successfully + +max-async-size: + Entrypoint main X KiB = max-async-size-main.js + chunk (runtime: main) max-async-size-asynX-X-XXXXXXXX.js (async-b-bde52cb3) X bytes <{792}> ={565}= ={664}= ={901}= [rendered] + > ./b ./async/index.js 10:2-49 + > ./a ./async/index.js 9:2-49 + dependent modules X bytes [dependent] 9 modules + cacheable modules X bytes + ./async/a.js X bytes [built] [code generated] + ./async/b.js X bytes [built] [code generated] + chunk (runtime: main) max-async-size-asynX-X-XXXXXXXX.js (async-b-89a43a0f) X KiB <{792}> ={265}= ={664}= ={901}= [rendered] + > ./b ./async/index.js 10:2-49 + > ./a ./async/index.js 9:2-49 + ./very-big.js?3 X KiB [built] [code generated] + chunk (runtime: main) max-async-size-asynX-X-XXXXXXXX.js (async-b-12217e1d) X KiB <{792}> ={265}= ={565}= ={901}= [rendered] + > ./b ./async/index.js 10:2-49 + > ./a ./async/index.js 9:2-49 + ./very-big.js?1 X KiB [built] [code generated] + chunk (runtime: main) max-async-size-main.js (main) X KiB (javascript) X KiB (runtime) >{265}< >{565}< >{664}< >{901}< [entry] [rendered] + > ./async main + runtime modules X KiB 10 modules + dependent modules X KiB [dependent] 6 modules + ./async/index.js X bytes [built] [code generated] + chunk (runtime: main) max-async-size-asynX-X-XXXXXXXX.js (async-b-77a8c116) X KiB <{792}> ={265}= ={565}= ={664}= [rendered] + > ./b ./async/index.js 10:2-49 + > ./a ./async/index.js 9:2-49 + ./very-big.js?2 X KiB [built] [code generated] + max-async-size (webpack x.x.x) compiled successfully + +enforce-min-size: + Entrypoint main X KiB = 14 assets + chunk (runtime: main) enforce-min-size-35.js (id hint: all) X bytes ={90}= ={120}= ={237}= ={241}= ={262}= ={273}= ={411}= ={491}= ={792}= ={858}= ={928}= ={929}= ={962}= [initial] [rendered] split chunk (cache group: all) + > ./ main + ./subfolder/small.js?1 X bytes [built] [code generated] + ./subfolder/small.js?2 X bytes [built] [code generated] + ./subfolder/small.js?3 X bytes [built] [code generated] + ./subfolder/small.js?4 X bytes [built] [code generated] + ./subfolder/small.js?5 X bytes [built] [code generated] + ./subfolder/small.js?6 X bytes [built] [code generated] + ./subfolder/small.js?7 X bytes [built] [code generated] + ./subfolder/small.js?8 X bytes [built] [code generated] + ./subfolder/small.js?9 X bytes [built] [code generated] + chunk (runtime: main) enforce-min-size-90.js (id hint: all) X KiB ={35}= ={120}= ={237}= ={241}= ={262}= ={273}= ={411}= ={491}= ={792}= ={858}= ={928}= ={929}= ={962}= [initial] [rendered] split chunk (cache group: all) + > ./ main + ./very-big.js?1 X KiB [built] [code generated] + chunk (runtime: main) enforce-min-size-120.js (id hint: all) X KiB ={35}= ={90}= ={237}= ={241}= ={262}= ={273}= ={411}= ={491}= ={792}= ={858}= ={928}= ={929}= ={962}= [initial] [rendered] split chunk (cache group: all) + > ./ main + ./very-big.js?3 X KiB [built] [code generated] + chunk (runtime: main) enforce-min-size-237.js (id hint: all) X KiB ={35}= ={90}= ={120}= ={241}= ={262}= ={273}= ={411}= ={491}= ={792}= ={858}= ={928}= ={929}= ={962}= [initial] [rendered] split chunk (cache group: all) + > ./ main + ./index.js X KiB [built] [code generated] + chunk (runtime: main) enforce-min-size-241.js (id hint: all) X bytes ={35}= ={90}= ={120}= ={237}= ={262}= ={273}= ={411}= ={491}= ={792}= ={858}= ={928}= ={929}= ={962}= [initial] [rendered] split chunk (cache group: all) + > ./ main + ./node_modules/big.js?1 X bytes [built] [code generated] + ./node_modules/small.js?1 X bytes [built] [code generated] + ./node_modules/small.js?2 X bytes [built] [code generated] + chunk (runtime: main) enforce-min-size-262.js (id hint: all) X bytes ={35}= ={90}= ={120}= ={237}= ={241}= ={273}= ={411}= ={491}= ={792}= ={858}= ={928}= ={929}= ={962}= [initial] [rendered] split chunk (cache group: all) + > ./ main + ./small.js?1 X bytes [built] [code generated] + ./small.js?2 X bytes [built] [code generated] + ./small.js?3 X bytes [built] [code generated] + ./small.js?4 X bytes [built] [code generated] + ./small.js?5 X bytes [built] [code generated] + ./small.js?6 X bytes [built] [code generated] + ./small.js?7 X bytes [built] [code generated] + ./small.js?8 X bytes [built] [code generated] + ./small.js?9 X bytes [built] [code generated] + chunk (runtime: main) enforce-min-size-273.js (id hint: all) X KiB ={35}= ={90}= ={120}= ={237}= ={241}= ={262}= ={411}= ={491}= ={792}= ={858}= ={928}= ={929}= ={962}= [initial] [rendered] split chunk (cache group: all) + > ./ main + ./node_modules/very-big.js?1 X KiB [built] [code generated] + chunk (runtime: main) enforce-min-size-411.js (id hint: all) X bytes ={35}= ={90}= ={120}= ={237}= ={241}= ={262}= ={273}= ={491}= ={792}= ={858}= ={928}= ={929}= ={962}= [initial] [rendered] split chunk (cache group: all) + > ./ main + ./subfolder/big.js?1 X bytes [built] [code generated] + ./subfolder/big.js?2 X bytes [built] [code generated] + chunk (runtime: main) enforce-min-size-491.js (id hint: all) X KiB ={35}= ={90}= ={120}= ={237}= ={241}= ={262}= ={273}= ={411}= ={792}= ={858}= ={928}= ={929}= ={962}= [initial] [rendered] split chunk (cache group: all) + > ./ main + ./in-some-directory/very-big.js?1 X KiB [built] [code generated] + chunk (runtime: main) enforce-min-size-main.js (main) X KiB ={35}= ={90}= ={120}= ={237}= ={241}= ={262}= ={273}= ={411}= ={491}= ={858}= ={928}= ={929}= ={962}= [entry] [rendered] + > ./ main + runtime modules X KiB 5 modules + chunk (runtime: main) enforce-min-size-858.js (id hint: all) X bytes ={35}= ={90}= ={120}= ={237}= ={241}= ={262}= ={273}= ={411}= ={491}= ={792}= ={928}= ={929}= ={962}= [initial] [rendered] split chunk (cache group: all) + > ./ main + ./inner-module/small.js?1 X bytes [built] [code generated] + ./inner-module/small.js?2 X bytes [built] [code generated] + ./inner-module/small.js?3 X bytes [built] [code generated] + ./inner-module/small.js?4 X bytes [built] [code generated] + ./inner-module/small.js?5 X bytes [built] [code generated] + ./inner-module/small.js?6 X bytes [built] [code generated] + ./inner-module/small.js?7 X bytes [built] [code generated] + ./inner-module/small.js?8 X bytes [built] [code generated] + ./inner-module/small.js?9 X bytes [built] [code generated] + chunk (runtime: main) enforce-min-size-928.js (id hint: all) X bytes ={35}= ={90}= ={120}= ={237}= ={241}= ={262}= ={273}= ={411}= ={491}= ={792}= ={858}= ={929}= ={962}= [initial] [rendered] split chunk (cache group: all) + > ./ main + ./in-some-directory/big.js?1 X bytes [built] [code generated] + ./in-some-directory/small.js?1 X bytes [built] [code generated] + ./in-some-directory/small.js?2 X bytes [built] [code generated] + ./in-some-directory/small.js?3 X bytes [built] [code generated] + ./in-some-directory/small.js?4 X bytes [built] [code generated] + chunk (runtime: main) enforce-min-size-929.js (id hint: all) X KiB ={35}= ={90}= ={120}= ={237}= ={241}= ={262}= ={273}= ={411}= ={491}= ={792}= ={858}= ={928}= ={962}= [initial] [rendered] split chunk (cache group: all) + > ./ main + ./very-big.js?2 X KiB [built] [code generated] + chunk (runtime: main) enforce-min-size-962.js (id hint: all) X bytes ={35}= ={90}= ={120}= ={237}= ={241}= ={262}= ={273}= ={411}= ={491}= ={792}= ={858}= ={928}= ={929}= [initial] [rendered] split chunk (cache group: all) + > ./ main + ./big.js?1 X bytes [built] [code generated] + ./big.js?2 X bytes [built] [code generated] + enforce-min-size (webpack x.x.x) compiled successfully + +only-async: + Entrypoint main X KiB = only-async-main.js + chunk (runtime: main) only-async-main.js (main) X KiB (javascript) X bytes (runtime) [entry] [rendered] + > ./ main + dependent modules X KiB [dependent] 44 modules + runtime modules X bytes 3 modules + ./index.js X KiB [built] [code generated] + only-async (webpack x.x.x) compiled successfully" +`; + +exports[`StatsTestCases should print correct stats for split-chunks-min-size-reduction 1`] = ` +"Entrypoint main X KiB = default/main.js +chunk (runtime: main) default/async-b.js (async-b) X bytes <{792}> [rendered] + > ./b ./index.js 2:0-47 + ./b.js X bytes [built] [code generated] + ./node_modules/shared.js?1 X bytes [dependent] [built] [code generated] +chunk (runtime: main) default/async-e.js (async-e) X bytes <{792}> ={784}= [rendered] + > ./e ./index.js 5:0-47 + ./e.js X bytes [built] [code generated] +chunk (runtime: main) default/async-a.js (async-a) X bytes <{792}> [rendered] + > ./a ./index.js 1:0-47 + ./a.js X bytes [built] [code generated] + ./node_modules/shared.js?1 X bytes [dependent] [built] [code generated] +chunk (runtime: main) default/async-d.js (async-d) X bytes <{792}> ={784}= [rendered] + > ./d ./index.js 4:0-47 + ./d.js X bytes [built] [code generated] +chunk (runtime: main) default/784.js (id hint: vendors) X bytes <{792}> ={251}= ={442}= ={869}= [rendered] split chunk (cache group: defaultVendors) + > ./c ./index.js 3:0-47 + > ./d ./index.js 4:0-47 + > ./e ./index.js 5:0-47 + ./node_modules/shared.js?2 X bytes [built] [code generated] +chunk (runtime: main) default/main.js (main) X bytes (javascript) X KiB (runtime) >{60}< >{251}< >{263}< >{442}< >{784}< >{869}< [entry] [rendered] + > ./ main + runtime modules X KiB 9 modules + ./index.js X bytes [built] [code generated] +chunk (runtime: main) default/async-c.js (async-c) X bytes <{792}> ={784}= [rendered] + > ./c ./index.js 3:0-47 + ./c.js X bytes [built] [code generated] +webpack x.x.x compiled successfully" +`; + +exports[`StatsTestCases should print correct stats for split-chunks-prefer-bigger-splits 1`] = ` +"Entrypoint main X KiB = default/main.js +chunk (runtime: main) default/async-b.js (async-b) X bytes <{792}> ={415}= [rendered] + > ./b ./index.js 2:0-47 + dependent modules X bytes [dependent] 1 module + ./b.js X bytes [built] [code generated] +chunk (runtime: main) default/async-a.js (async-a) X bytes <{792}> [rendered] + > ./a ./index.js 1:0-47 + dependent modules X bytes [dependent] 2 modules + ./a.js X bytes [built] [code generated] +chunk (runtime: main) default/415.js X bytes <{792}> ={60}= ={869}= [rendered] split chunk (cache group: default) + > ./b ./index.js 2:0-47 + > ./c ./index.js 3:0-47 + ./d.js X bytes [built] [code generated] + ./f.js X bytes [built] [code generated] +chunk (runtime: main) default/main.js (main) X bytes (javascript) X KiB (runtime) >{60}< >{263}< >{415}< >{869}< [entry] [rendered] + > ./ main + runtime modules X KiB 9 modules + ./index.js X bytes [built] [code generated] +chunk (runtime: main) default/async-c.js (async-c) X bytes <{792}> ={415}= [rendered] + > ./c ./index.js 3:0-47 + ./c.js X bytes [built] [code generated] +webpack x.x.x compiled successfully" +`; + +exports[`StatsTestCases should print correct stats for split-chunks-runtime-specific 1`] = ` +"used-exports: + asset used-exports-c.js X KiB [emitted] (name: c) + asset used-exports-b.js X KiB [emitted] (name: b) + asset used-exports-637.js X bytes [emitted] + asset used-exports-a.js X bytes [emitted] (name: a) + Entrypoint a X bytes = used-exports-a.js + Entrypoint b X KiB = used-exports-637.js X bytes used-exports-b.js X KiB + Entrypoint c X KiB = used-exports-637.js X bytes used-exports-c.js X KiB + chunk (runtime: b) used-exports-b.js (b) X bytes (javascript) X KiB (runtime) [entry] [rendered] + runtime modules X KiB 4 modules + ./b.js X bytes [built] [code generated] + chunk (runtime: c) used-exports-c.js (c) X bytes (javascript) X KiB (runtime) [entry] [rendered] + runtime modules X KiB 4 modules + ./c.js X bytes [built] [code generated] + chunk (runtime: b, c) used-exports-637.js X bytes [initial] [rendered] split chunk (cache group: default) + ./objects.js X bytes [built] [code generated] + chunk (runtime: a) used-exports-a.js (a) X bytes [entry] [rendered] + ./a.js + 1 modules X bytes [built] [code generated] + used-exports (webpack x.x.x) compiled successfully in X ms + +no-used-exports: + asset no-used-exports-c.js X KiB [emitted] (name: c) + asset no-used-exports-a.js X KiB [emitted] (name: a) + asset no-used-exports-b.js X KiB [emitted] (name: b) + asset no-used-exports-637.js X bytes [emitted] + Entrypoint a X KiB = no-used-exports-637.js X bytes no-used-exports-a.js X KiB + Entrypoint b X KiB = no-used-exports-637.js X bytes no-used-exports-b.js X KiB + Entrypoint c X KiB = no-used-exports-637.js X bytes no-used-exports-c.js X KiB + chunk (runtime: b) no-used-exports-b.js (b) X bytes (javascript) X KiB (runtime) [entry] [rendered] + runtime modules X KiB 4 modules + ./b.js X bytes [built] [code generated] + chunk (runtime: c) no-used-exports-c.js (c) X bytes (javascript) X KiB (runtime) [entry] [rendered] + runtime modules X KiB 4 modules + ./c.js X bytes [built] [code generated] + chunk (runtime: a, b, c) no-used-exports-637.js X bytes [initial] [rendered] split chunk (cache group: default) + ./objects.js X bytes [built] [code generated] + chunk (runtime: a) no-used-exports-a.js (a) X bytes (javascript) X KiB (runtime) [entry] [rendered] + runtime modules X KiB 4 modules + ./a.js X bytes [built] [code generated] + no-used-exports (webpack x.x.x) compiled successfully in X ms + +global: + asset global-c.js X KiB [emitted] (name: c) + asset global-a.js X KiB [emitted] (name: a) + asset global-b.js X KiB [emitted] (name: b) + asset global-637.js X bytes [emitted] + Entrypoint a X KiB = global-637.js X bytes global-a.js X KiB + Entrypoint b X KiB = global-637.js X bytes global-b.js X KiB + Entrypoint c X KiB = global-637.js X bytes global-c.js X KiB + chunk (runtime: b) global-b.js (b) X bytes (javascript) X KiB (runtime) [entry] [rendered] + runtime modules X KiB 4 modules + ./b.js X bytes [built] [code generated] + chunk (runtime: c) global-c.js (c) X bytes (javascript) X KiB (runtime) [entry] [rendered] + runtime modules X KiB 4 modules + ./c.js X bytes [built] [code generated] + chunk (runtime: a, b, c) global-637.js X bytes [initial] [rendered] split chunk (cache group: default) + ./objects.js X bytes [built] [code generated] + chunk (runtime: a) global-a.js (a) X bytes (javascript) X KiB (runtime) [entry] [rendered] + runtime modules X KiB 4 modules + ./a.js X bytes [built] [code generated] + global (webpack x.x.x) compiled successfully in X ms" +`; + +exports[`StatsTestCases should print correct stats for tree-shaking 1`] = ` +"asset bundle.js X KiB [emitted] (name: main) +runtime modules X bytes 3 modules +orphan modules X bytes [orphan] 1 module +cacheable modules X bytes + ./index.js X bytes [built] [code generated] [1 warning] + [no exports] + [no exports used] + ./reexport-known.js X bytes [built] [code generated] + [exports: a, b] + [only some exports used: a] + ./reexport-unknown.js X bytes [built] [code generated] + [exports: a, b, c, d] + [only some exports used: a, c] + ./reexport-star-known.js X bytes [built] [code generated] + [exports: a, b] + [only some exports used: a] + ./reexport-star-unknown.js X bytes [built] [code generated] + [only some exports used: a, c] + ./edge.js X bytes [built] [code generated] + [only some exports used: y] + ./require.include.js X bytes [built] [code generated] + [exports: a, default] + [no exports used] + ./a.js X bytes [built] [code generated] + [exports: a] + [all exports used] + ./unknown.js X bytes [built] [code generated] + [used exports unknown] + ./unknown2.js X bytes [built] [code generated] + [used exports unknown] + +WARNING in ./index.js 9:0-36 +require.include() is deprecated and will be removed soon. + +webpack x.x.x compiled with 1 warning in X ms" +`; + +exports[`StatsTestCases should print correct stats for warnings-space-warning 1`] = ` +"asset main.js X bytes [emitted] (name: main) +orphan modules X bytes [orphan] 1 module +runtime modules X bytes 1 module +./index.js + 1 modules X bytes [built] [code generated] + +WARNING in ./index.js 3:12-14 +export 'bb' (imported as 'bb') was not found in './a' (possible exports: a) + +webpack x.x.x compiled with 1 warning in X ms" +`; + +exports[`StatsTestCases should print correct stats for wasm-explorer-examples-sync 1`] = ` +"assets by path *.js X KiB + asset bundle.js X KiB [emitted] (name: main) + asset 836.bundle.js X KiB [emitted] + asset 946.bundle.js X bytes [emitted] + asset 787.bundle.js X bytes [emitted] (id hint: vendors) + asset 573.bundle.js X bytes [emitted] + asset 672.bundle.js X bytes [emitted] + asset 989.bundle.js X bytes [emitted] +assets by path *.wasm X KiB + asset XXXXXXXXXXXXXXXXXXXX.module.wasm X bytes [emitted] [immutable] + asset XXXXXXXXXXXXXXXXXXXX.module.wasm X bytes [emitted] [immutable] + asset XXXXXXXXXXXXXXXXXXXX.module.wasm X bytes [emitted] [immutable] + asset XXXXXXXXXXXXXXXXXXXX.module.wasm X bytes [emitted] [immutable] + asset XXXXXXXXXXXXXXXXXXXX.module.wasm X bytes [emitted] [immutable] + asset XXXXXXXXXXXXXXXXXXXX.module.wasm X bytes [emitted] [immutable] +chunk (runtime: main) 573.bundle.js X bytes (javascript) X bytes (webassembly) [rendered] + ./Q_rsqrt.wasm X bytes (javascript) X bytes (webassembly) [built] [code generated] +chunk (runtime: main) 672.bundle.js X bytes (javascript) X bytes (webassembly) [rendered] + ./duff.wasm X bytes (javascript) X bytes (webassembly) [built] [code generated] +chunk (runtime: main) 787.bundle.js (id hint: vendors) X bytes [rendered] split chunk (cache group: defaultVendors) + ./node_modules/env.js X bytes [built] [code generated] +chunk (runtime: main) bundle.js (main) X bytes (javascript) X KiB (runtime) [entry] [rendered] + runtime modules X KiB 11 modules + ./index.js X bytes [built] [code generated] +chunk (runtime: main) 836.bundle.js X KiB (javascript) X bytes (webassembly) [rendered] + ./testFunction.wasm X bytes (javascript) X bytes (webassembly) [dependent] [built] [code generated] + ./tests.js X KiB [built] [code generated] +chunk (runtime: main) 946.bundle.js X bytes (javascript) X bytes (webassembly) [rendered] + ./fact.wasm X bytes (javascript) X bytes (webassembly) [built] [code generated] + ./fast-math.wasm X bytes (javascript) X bytes (webassembly) [built] [code generated] +chunk (runtime: main) 989.bundle.js X bytes (javascript) X bytes (webassembly) [rendered] + ./popcnt.wasm X bytes (javascript) X bytes (webassembly) [built] [code generated] +runtime modules X KiB 11 modules +cacheable modules X KiB (javascript) X KiB (webassembly) + webassembly modules X bytes (javascript) X KiB (webassembly) + ./Q_rsqrt.wasm X bytes (javascript) X bytes (webassembly) [built] [code generated] + ./testFunction.wasm X bytes (javascript) X bytes (webassembly) [built] [code generated] + ./fact.wasm X bytes (javascript) X bytes (webassembly) [built] [code generated] + ./popcnt.wasm X bytes (javascript) X bytes (webassembly) [built] [code generated] + ./fast-math.wasm X bytes (javascript) X bytes (webassembly) [built] [code generated] + ./duff.wasm X bytes (javascript) X bytes (webassembly) [built] [code generated] + javascript modules X KiB + ./index.js X bytes [built] [code generated] + ./tests.js X KiB [built] [code generated] + ./node_modules/env.js X bytes [built] [code generated] +webpack x.x.x compiled successfully in X ms" +`; + +exports[`StatsTestCases should print correct stats for worker-public-path 1`] = ` +"asset main-XXXXXXXXXXXXXXXXXXXX.js X KiB [emitted] [immutable] (name: main) +asset 447-XXXXXXXXXXXXXXXXXXXX.js X bytes [emitted] [immutable] +runtime modules X KiB 5 modules +cacheable modules X bytes + ./index.js X bytes [built] [code generated] + ./worker.js X bytes [built] [code generated] +webpack x.x.x compiled successfully in X ms" +`; diff --git a/test/__snapshots__/StatsTestCases.test.js.snap b/test/__snapshots__/StatsTestCases.test.js.snap deleted file mode 100644 index a56e90db48f..00000000000 --- a/test/__snapshots__/StatsTestCases.test.js.snap +++ /dev/null @@ -1,4429 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`StatsTestCases should print correct stats for aggressive-splitting-entry 1`] = ` -"fitting: - PublicPath: auto - asset fitting-8b66832b8222bd7b9a9b.js 15.9 KiB [emitted] [immutable] - asset fitting-1c702fff0ba9fe1126d9.js 1.9 KiB [emitted] [immutable] - asset fitting-c0e0ed061413e64a66c5.js 1.9 KiB [emitted] [immutable] - asset fitting-445185754184bf780ddc.js 1.08 KiB [emitted] [immutable] - Entrypoint main 19.8 KiB = fitting-1c702fff0ba9fe1126d9.js 1.9 KiB fitting-c0e0ed061413e64a66c5.js 1.9 KiB fitting-8b66832b8222bd7b9a9b.js 15.9 KiB - chunk (runtime: main) fitting-8b66832b8222bd7b9a9b.js 1.87 KiB (javascript) 8.53 KiB (runtime) [entry] [rendered] - > ./index main - runtime modules 8.53 KiB 11 modules - cacheable modules 1.87 KiB - ./e.js 899 bytes [dependent] [built] [code generated] - ./f.js 900 bytes [dependent] [built] [code generated] - ./index.js 111 bytes [built] [code generated] - chunk (runtime: main) fitting-c0e0ed061413e64a66c5.js 1.76 KiB [initial] [rendered] [recorded] aggressive splitted - > ./index main - ./c.js 899 bytes [built] [code generated] - ./d.js 899 bytes [built] [code generated] - chunk (runtime: main) fitting-1c702fff0ba9fe1126d9.js 1.76 KiB [initial] [rendered] [recorded] aggressive splitted - > ./index main - ./a.js 899 bytes [built] [code generated] - ./b.js 899 bytes [built] [code generated] - chunk (runtime: main) fitting-445185754184bf780ddc.js 916 bytes [rendered] - > ./g ./index.js 7:0-13 - ./g.js 916 bytes [built] [code generated] - fitting (webpack x.x.x) compiled successfully in X ms - -content-change: - PublicPath: auto - asset content-change-a9ec79ece87f8c1092a8.js 16 KiB [emitted] [immutable] - asset content-change-1c702fff0ba9fe1126d9.js 1.9 KiB [emitted] [immutable] - asset content-change-c0e0ed061413e64a66c5.js 1.9 KiB [emitted] [immutable] - asset content-change-445185754184bf780ddc.js 1.08 KiB [emitted] [immutable] - Entrypoint main 19.8 KiB = content-change-1c702fff0ba9fe1126d9.js 1.9 KiB content-change-c0e0ed061413e64a66c5.js 1.9 KiB content-change-a9ec79ece87f8c1092a8.js 16 KiB - chunk (runtime: main) content-change-a9ec79ece87f8c1092a8.js 1.87 KiB (javascript) 8.54 KiB (runtime) [entry] [rendered] - > ./index main - runtime modules 8.54 KiB 11 modules - cacheable modules 1.87 KiB - ./e.js 899 bytes [dependent] [built] [code generated] - ./f.js 900 bytes [dependent] [built] [code generated] - ./index.js 111 bytes [built] [code generated] - chunk (runtime: main) content-change-c0e0ed061413e64a66c5.js 1.76 KiB [initial] [rendered] [recorded] aggressive splitted - > ./index main - ./c.js 899 bytes [built] [code generated] - ./d.js 899 bytes [built] [code generated] - chunk (runtime: main) content-change-1c702fff0ba9fe1126d9.js 1.76 KiB [initial] [rendered] [recorded] aggressive splitted - > ./index main - ./a.js 899 bytes [built] [code generated] - ./b.js 899 bytes [built] [code generated] - chunk (runtime: main) content-change-445185754184bf780ddc.js 916 bytes [rendered] - > ./g ./index.js 7:0-13 - ./g.js 916 bytes [built] [code generated] - content-change (webpack x.x.x) compiled successfully in X ms" -`; - -exports[`StatsTestCases should print correct stats for aggressive-splitting-on-demand 1`] = ` -"PublicPath: auto -asset 8478503a92a5e63fa432.js 11.5 KiB [emitted] [immutable] (name: main) -asset b28b42175852a350ae55.js 1.91 KiB [emitted] [immutable] -asset 5dc82ad1144129efc6f0.js 1.91 KiB [emitted] [immutable] -asset 6861109a893ce5c56a08.js 1.9 KiB [emitted] [immutable] -asset cdb7e2808114a2288d95.js 1.9 KiB [emitted] [immutable] -asset 73372ad6d7fbb1fb063f.js 1.9 KiB [emitted] [immutable] -asset 84ccadf9c4e1e366e5ef.js 1.9 KiB [emitted] [immutable] -asset c0e0ed061413e64a66c5.js 1.9 KiB [emitted] [immutable] -asset c98f03fbb3549a9685f2.js 1.9 KiB [emitted] [immutable] -asset 4437b7a806fda9652d78.js 1010 bytes [emitted] [immutable] -asset 9711883e11bdd4d550ff.js 1010 bytes [emitted] [immutable] -asset e0332efe5dd181ffeff5.js 1010 bytes [emitted] [immutable] -Entrypoint main 11.5 KiB = 8478503a92a5e63fa432.js -chunk (runtime: main) c0e0ed061413e64a66c5.js 1.76 KiB [rendered] [recorded] aggressive splitted - > ./c ./d ./e ./index.js 3:0-30 - ./c.js 899 bytes [built] [code generated] - ./d.js 899 bytes [built] [code generated] -chunk (runtime: main) 8478503a92a5e63fa432.js (main) 248 bytes (javascript) 6.24 KiB (runtime) [entry] [rendered] - > ./index main - runtime modules 6.24 KiB 7 modules - ./index.js 248 bytes [built] [code generated] -chunk (runtime: main) b28b42175852a350ae55.js 1.76 KiB [rendered] - > ./f ./g ./h ./i ./j ./k ./index.js 4:0-51 - ./j.js 901 bytes [built] [code generated] - ./k.js 899 bytes [built] [code generated] -chunk (runtime: main) e0332efe5dd181ffeff5.js 899 bytes [rendered] - > ./c ./d ./e ./index.js 3:0-30 - > ./b ./d ./e ./f ./g ./index.js 5:0-44 - ./e.js 899 bytes [built] [code generated] -chunk (runtime: main) cdb7e2808114a2288d95.js 1.76 KiB [rendered] [recorded] aggressive splitted - > ./b ./d ./e ./f ./g ./h ./i ./j ./k ./index.js 6:0-72 - ./i.js 899 bytes [built] [code generated] - ./j.js 901 bytes [built] [code generated] -chunk (runtime: main) 5dc82ad1144129efc6f0.js 1.76 KiB [rendered] [recorded] aggressive splitted - > ./b ./d ./e ./f ./g ./h ./i ./j ./k ./index.js 6:0-72 - ./e.js 899 bytes [built] [code generated] - ./h.js 899 bytes [built] [code generated] -chunk (runtime: main) 73372ad6d7fbb1fb063f.js 1.76 KiB [rendered] - > ./b ./c ./index.js 2:0-23 - ./b.js 899 bytes [built] [code generated] - ./c.js 899 bytes [built] [code generated] -chunk (runtime: main) c98f03fbb3549a9685f2.js 1.76 KiB [rendered] [recorded] aggressive splitted - > ./f ./g ./h ./i ./j ./k ./index.js 4:0-51 - ./h.js 899 bytes [built] [code generated] - ./i.js 899 bytes [built] [code generated] -chunk (runtime: main) 6861109a893ce5c56a08.js 1.76 KiB [rendered] [recorded] aggressive splitted - > ./f ./g ./h ./i ./j ./k ./index.js 4:0-51 - > ./b ./d ./e ./f ./g ./index.js 5:0-44 - > ./b ./d ./e ./f ./g ./h ./i ./j ./k ./index.js 6:0-72 - ./f.js 899 bytes [built] [code generated] - ./g.js 901 bytes [built] [code generated] -chunk (runtime: main) 9711883e11bdd4d550ff.js 899 bytes [rendered] - > ./b ./d ./e ./f ./g ./h ./i ./j ./k ./index.js 6:0-72 - ./k.js 899 bytes [built] [code generated] -chunk (runtime: main) 84ccadf9c4e1e366e5ef.js 1.76 KiB [rendered] [recorded] aggressive splitted - > ./b ./d ./e ./f ./g ./index.js 5:0-44 - > ./b ./d ./e ./f ./g ./h ./i ./j ./k ./index.js 6:0-72 - ./b.js 899 bytes [built] [code generated] - ./d.js 899 bytes [built] [code generated] -chunk (runtime: main) 4437b7a806fda9652d78.js 899 bytes [rendered] - > ./a ./index.js 1:0-16 - ./a.js 899 bytes [built] [code generated] -webpack x.x.x compiled successfully in X ms" -`; - -exports[`StatsTestCases should print correct stats for asset 1`] = ` -"asset 89a353e9c515885abd8e.png 14.6 KiB [emitted] [immutable] [from: images/file.png] (auxiliary name: main) -asset bundle.js 12.4 KiB [emitted] (name: main) -asset static/file.html 12 bytes [emitted] [from: static/file.html] (auxiliary name: main) -runtime modules 1.06 KiB 2 modules -asset modules 8.9 KiB (javascript) 14.6 KiB (asset) - ./images/file.png 42 bytes (javascript) 14.6 KiB (asset) [built] [code generated] - ./images/file.svg 915 bytes [built] [code generated] - ./images/file.jpg 7.92 KiB [built] [code generated] - ./static/file.html 42 bytes (javascript) 12 bytes (asset) [built] [code generated] -./index.js 150 bytes [built] [code generated] -webpack x.x.x compiled successfully in X ms" -`; - -exports[`StatsTestCases should print correct stats for async-commons-chunk 1`] = ` -"chunk (runtime: main) main.js (main) 515 bytes (javascript) 5.92 KiB (runtime) >{460}< >{847}< >{996}< [entry] [rendered] - > ./ main - runtime modules 5.92 KiB 7 modules - ./index.js 515 bytes [built] [code generated] -chunk (runtime: main) 460.js 21 bytes <{179}> ={847}= [rendered] - > ./index.js 17:1-21:3 - ./c.js 21 bytes [built] [code generated] -chunk (runtime: main) 847.js 21 bytes <{179}> ={460}= ={996}= [rendered] reused as split chunk (cache group: default) - > ./index.js 17:1-21:3 - > ./index.js 2:1-5:3 - > ./a ./b ./index.js 9:1-13:3 - ./a.js 21 bytes [built] [code generated] -chunk (runtime: main) 996.js 21 bytes <{179}> ={847}= [rendered] - > ./a ./b ./index.js 9:1-13:3 - ./b.js 21 bytes [built] [code generated] -webpack x.x.x compiled successfully" -`; - -exports[`StatsTestCases should print correct stats for async-commons-chunk-auto 1`] = ` -"disabled: - chunk (runtime: b) disabled/b.js (b) 196 bytes (javascript) 396 bytes (runtime) [entry] [rendered] - > ./b b - dependent modules 80 bytes [dependent] 4 modules - runtime modules 396 bytes 2 modules - ./b.js 116 bytes [built] [code generated] - chunk (runtime: a, main) disabled/async-g.js (async-g) 65 bytes [rendered] - > ./g ./a.js 6:0-47 - dependent modules 20 bytes [dependent] 1 module - ./g.js 45 bytes [built] [code generated] - chunk (runtime: main) disabled/main.js (main) 147 bytes (javascript) 6.57 KiB (runtime) [entry] [rendered] - > ./ main - runtime modules 6.57 KiB 9 modules - ./index.js 147 bytes [built] [code generated] - chunk (runtime: main) disabled/async-b.js (async-b) 196 bytes [rendered] - > ./b ./index.js 2:0-47 - dependent modules 80 bytes [dependent] 4 modules - ./b.js 116 bytes [built] [code generated] - chunk (runtime: main) disabled/async-c.js (async-c) 196 bytes [rendered] - > ./c ./index.js 3:0-47 - dependent modules 60 bytes [dependent] 3 modules - ./c.js + 1 modules 136 bytes [built] [code generated] - chunk (runtime: c) disabled/c.js (c) 196 bytes (javascript) 396 bytes (runtime) [entry] [rendered] - > ./c c - dependent modules 60 bytes [dependent] 3 modules - runtime modules 396 bytes 2 modules - ./c.js + 1 modules 136 bytes [built] [code generated] - chunk (runtime: a) disabled/a.js (a) 245 bytes (javascript) 6.52 KiB (runtime) [entry] [rendered] - > ./a a - runtime modules 6.52 KiB 9 modules - dependent modules 60 bytes [dependent] 3 modules - ./a.js + 1 modules 185 bytes [built] [code generated] - chunk (runtime: main) disabled/async-a.js (async-a) 245 bytes [rendered] - > ./a ./index.js 1:0-47 - dependent modules 60 bytes [dependent] 3 modules - ./a.js + 1 modules 185 bytes [built] [code generated] - disabled (webpack x.x.x) compiled successfully - -default: - chunk (runtime: b) default/b.js (b) 196 bytes (javascript) 396 bytes (runtime) [entry] [rendered] - > ./b b - dependent modules 80 bytes [dependent] 4 modules - runtime modules 396 bytes 2 modules - ./b.js 116 bytes [built] [code generated] - chunk (runtime: a, main) default/async-g.js (async-g) 45 bytes [rendered] - > ./g ./a.js 6:0-47 - ./g.js 45 bytes [built] [code generated] - chunk (runtime: main) default/main.js (main) 147 bytes (javascript) 6.58 KiB (runtime) [entry] [rendered] - > ./ main - runtime modules 6.58 KiB 9 modules - ./index.js 147 bytes [built] [code generated] - chunk (runtime: main) default/282.js (id hint: vendors) 20 bytes [rendered] split chunk (cache group: defaultVendors) - > ./a ./index.js 1:0-47 - > ./b ./index.js 2:0-47 - > ./c ./index.js 3:0-47 - ./node_modules/x.js 20 bytes [built] [code generated] - chunk (runtime: main) default/async-b.js (async-b) 116 bytes [rendered] - > ./b ./index.js 2:0-47 - ./b.js 116 bytes [built] [code generated] - chunk (runtime: main) default/async-c.js (async-c) 116 bytes [rendered] - > ./c ./index.js 3:0-47 - ./c.js 116 bytes [built] [code generated] - chunk (runtime: c) default/c.js (c) 196 bytes (javascript) 396 bytes (runtime) [entry] [rendered] - > ./c c - dependent modules 80 bytes [dependent] 4 modules - runtime modules 396 bytes 2 modules - ./c.js 116 bytes [built] [code generated] - chunk (runtime: a, main) default/568.js 20 bytes [rendered] split chunk (cache group: default) - > ./b ./index.js 2:0-47 - > ./c ./index.js 3:0-47 - > ./g ./a.js 6:0-47 - ./f.js 20 bytes [built] [code generated] - chunk (runtime: main) default/767.js 20 bytes [rendered] split chunk (cache group: default) - > ./a ./index.js 1:0-47 - > ./b ./index.js 2:0-47 - > ./c ./index.js 3:0-47 - ./d.js 20 bytes [built] [code generated] - chunk (runtime: main) default/769.js (id hint: vendors) 20 bytes [rendered] split chunk (cache group: defaultVendors) - > ./c ./index.js 3:0-47 - ./node_modules/z.js 20 bytes [built] [code generated] - chunk (runtime: a) default/a.js (a) 245 bytes (javascript) 6.57 KiB (runtime) [entry] [rendered] - > ./a a - runtime modules 6.57 KiB 9 modules - dependent modules 60 bytes [dependent] 3 modules - ./a.js + 1 modules 185 bytes [built] [code generated] - chunk (runtime: main) default/async-a.js (async-a) 185 bytes [rendered] - > ./a ./index.js 1:0-47 - ./a.js + 1 modules 185 bytes [built] [code generated] - chunk (runtime: main) default/954.js (id hint: vendors) 20 bytes [rendered] split chunk (cache group: defaultVendors) - > ./a ./index.js 1:0-47 - > ./b ./index.js 2:0-47 - ./node_modules/y.js 20 bytes [built] [code generated] - default (webpack x.x.x) compiled successfully - -vendors: - Entrypoint main 11 KiB = vendors/main.js - Entrypoint a 14.3 KiB = vendors/vendors.js 1.08 KiB vendors/a.js 13.3 KiB - Entrypoint b 8.04 KiB = vendors/vendors.js 1.08 KiB vendors/b.js 6.97 KiB - Entrypoint c 8.04 KiB = vendors/vendors.js 1.08 KiB vendors/c.js 6.97 KiB - chunk (runtime: b) vendors/b.js (b) 156 bytes (javascript) 2.63 KiB (runtime) [entry] [rendered] - > ./b b - runtime modules 2.63 KiB 4 modules - dependent modules 40 bytes [dependent] 2 modules - ./b.js 116 bytes [built] [code generated] - chunk (runtime: a, main) vendors/async-g.js (async-g) 65 bytes [rendered] - > ./g ./a.js 6:0-47 - dependent modules 20 bytes [dependent] 1 module - ./g.js 45 bytes [built] [code generated] - chunk (runtime: main) vendors/main.js (main) 147 bytes (javascript) 6.57 KiB (runtime) [entry] [rendered] - > ./ main - runtime modules 6.57 KiB 9 modules - ./index.js 147 bytes [built] [code generated] - chunk (runtime: a, b, c) vendors/vendors.js (vendors) (id hint: vendors) 60 bytes [initial] [rendered] split chunk (cache group: vendors) (name: vendors) - > ./a a - > ./b b - > ./c c - ./node_modules/x.js 20 bytes [built] [code generated] - ./node_modules/y.js 20 bytes [built] [code generated] - ./node_modules/z.js 20 bytes [built] [code generated] - chunk (runtime: main) vendors/async-b.js (async-b) 196 bytes [rendered] - > ./b ./index.js 2:0-47 - dependent modules 80 bytes [dependent] 4 modules - ./b.js 116 bytes [built] [code generated] - chunk (runtime: main) vendors/async-c.js (async-c) 196 bytes [rendered] - > ./c ./index.js 3:0-47 - dependent modules 80 bytes [dependent] 4 modules - ./c.js 116 bytes [built] [code generated] - chunk (runtime: c) vendors/c.js (c) 156 bytes (javascript) 2.63 KiB (runtime) [entry] [rendered] - > ./c c - runtime modules 2.63 KiB 4 modules - dependent modules 40 bytes [dependent] 2 modules - ./c.js 116 bytes [built] [code generated] - chunk (runtime: a) vendors/a.js (a) 205 bytes (javascript) 7.41 KiB (runtime) [entry] [rendered] - > ./a a - runtime modules 7.41 KiB 10 modules - dependent modules 20 bytes [dependent] 1 module - ./a.js + 1 modules 185 bytes [built] [code generated] - chunk (runtime: main) vendors/async-a.js (async-a) 245 bytes [rendered] - > ./a ./index.js 1:0-47 - dependent modules 60 bytes [dependent] 3 modules - ./a.js + 1 modules 185 bytes [built] [code generated] - vendors (webpack x.x.x) compiled successfully - -multiple-vendors: - Entrypoint main 11.4 KiB = multiple-vendors/main.js - Entrypoint a 14.8 KiB = multiple-vendors/libs-x.js 414 bytes multiple-vendors/954.js 414 bytes multiple-vendors/767.js 414 bytes multiple-vendors/390.js 414 bytes multiple-vendors/a.js 13.2 KiB - Entrypoint b 7.97 KiB = multiple-vendors/libs-x.js 414 bytes multiple-vendors/954.js 414 bytes multiple-vendors/767.js 414 bytes multiple-vendors/568.js 414 bytes multiple-vendors/b.js 6.35 KiB - Entrypoint c 7.97 KiB = multiple-vendors/libs-x.js 414 bytes multiple-vendors/769.js 414 bytes multiple-vendors/767.js 414 bytes multiple-vendors/568.js 414 bytes multiple-vendors/c.js 6.35 KiB - chunk (runtime: a, b, c, main) multiple-vendors/libs-x.js (libs-x) (id hint: libs) 20 bytes [initial] [rendered] split chunk (cache group: libs) (name: libs-x) - > ./a ./index.js 1:0-47 - > ./b ./index.js 2:0-47 - > ./c ./index.js 3:0-47 - > ./a a - > ./b b - > ./c c - ./node_modules/x.js 20 bytes [built] [code generated] - chunk (runtime: b) multiple-vendors/b.js (b) 116 bytes (javascript) 2.64 KiB (runtime) [entry] [rendered] - > ./b b - runtime modules 2.64 KiB 4 modules - ./b.js 116 bytes [built] [code generated] - chunk (runtime: a, main) multiple-vendors/async-g.js (async-g) 45 bytes [rendered] - > ./g ./a.js 6:0-47 - ./g.js 45 bytes [built] [code generated] - chunk (runtime: main) multiple-vendors/main.js (main) 147 bytes (javascript) 6.61 KiB (runtime) [entry] [rendered] - > ./ main - runtime modules 6.61 KiB 9 modules - ./index.js 147 bytes [built] [code generated] - chunk (runtime: main) multiple-vendors/async-b.js (async-b) 116 bytes [rendered] - > ./b ./index.js 2:0-47 - ./b.js 116 bytes [built] [code generated] - chunk (runtime: main) multiple-vendors/async-c.js (async-c) 116 bytes [rendered] - > ./c ./index.js 3:0-47 - ./c.js 116 bytes [built] [code generated] - chunk (runtime: a, main) multiple-vendors/390.js 20 bytes [initial] [rendered] split chunk (cache group: default) - > ./a ./index.js 1:0-47 - > ./a a - ./e.js 20 bytes [built] [code generated] - chunk (runtime: c) multiple-vendors/c.js (c) 116 bytes (javascript) 2.64 KiB (runtime) [entry] [rendered] - > ./c c - runtime modules 2.64 KiB 4 modules - ./c.js 116 bytes [built] [code generated] - chunk (runtime: a, b, c, main) multiple-vendors/568.js 20 bytes [initial] [rendered] split chunk (cache group: default) - > ./b ./index.js 2:0-47 - > ./c ./index.js 3:0-47 - > ./g ./a.js 6:0-47 - > ./b b - > ./c c - ./f.js 20 bytes [built] [code generated] - chunk (runtime: a, b, c, main) multiple-vendors/767.js 20 bytes [initial] [rendered] split chunk (cache group: default) - > ./a ./index.js 1:0-47 - > ./b ./index.js 2:0-47 - > ./c ./index.js 3:0-47 - > ./a a - > ./b b - > ./c c - ./d.js 20 bytes [built] [code generated] - chunk (runtime: c, main) multiple-vendors/769.js (id hint: vendors) 20 bytes [initial] [rendered] split chunk (cache group: vendors) - > ./c ./index.js 3:0-47 - > ./c c - ./node_modules/z.js 20 bytes [built] [code generated] - chunk (runtime: a) multiple-vendors/a.js (a) 165 bytes (javascript) 7.46 KiB (runtime) [entry] [rendered] - > ./a a - runtime modules 7.46 KiB 10 modules - ./a.js 165 bytes [built] [code generated] - chunk (runtime: main) multiple-vendors/async-a.js (async-a) 165 bytes [rendered] - > ./a ./index.js 1:0-47 - ./a.js 165 bytes [built] [code generated] - chunk (runtime: a, b, main) multiple-vendors/954.js (id hint: vendors) 20 bytes [initial] [rendered] split chunk (cache group: vendors) - > ./a ./index.js 1:0-47 - > ./b ./index.js 2:0-47 - > ./a a - > ./b b - ./node_modules/y.js 20 bytes [built] [code generated] - multiple-vendors (webpack x.x.x) compiled successfully - -all: - Entrypoint main 11.4 KiB = all/main.js - Entrypoint a 14.8 KiB = all/282.js 414 bytes all/954.js 414 bytes all/767.js 414 bytes all/390.js 414 bytes all/a.js 13.2 KiB - Entrypoint b 7.97 KiB = all/282.js 414 bytes all/954.js 414 bytes all/767.js 414 bytes all/568.js 414 bytes all/b.js 6.35 KiB - Entrypoint c 7.97 KiB = all/282.js 414 bytes all/769.js 414 bytes all/767.js 414 bytes all/568.js 414 bytes all/c.js 6.35 KiB - chunk (runtime: b) all/b.js (b) 116 bytes (javascript) 2.64 KiB (runtime) [entry] [rendered] - > ./b b - runtime modules 2.64 KiB 4 modules - ./b.js 116 bytes [built] [code generated] - chunk (runtime: a, main) all/async-g.js (async-g) 45 bytes [rendered] - > ./g ./a.js 6:0-47 - ./g.js 45 bytes [built] [code generated] - chunk (runtime: main) all/main.js (main) 147 bytes (javascript) 6.58 KiB (runtime) [entry] [rendered] - > ./ main - runtime modules 6.58 KiB 9 modules - ./index.js 147 bytes [built] [code generated] - chunk (runtime: a, b, c, main) all/282.js (id hint: vendors) 20 bytes [initial] [rendered] split chunk (cache group: vendors) - > ./a ./index.js 1:0-47 - > ./b ./index.js 2:0-47 - > ./c ./index.js 3:0-47 - > ./a a - > ./b b - > ./c c - ./node_modules/x.js 20 bytes [built] [code generated] - chunk (runtime: main) all/async-b.js (async-b) 116 bytes [rendered] - > ./b ./index.js 2:0-47 - ./b.js 116 bytes [built] [code generated] - chunk (runtime: main) all/async-c.js (async-c) 116 bytes [rendered] - > ./c ./index.js 3:0-47 - ./c.js 116 bytes [built] [code generated] - chunk (runtime: a, main) all/390.js 20 bytes [initial] [rendered] split chunk (cache group: default) - > ./a ./index.js 1:0-47 - > ./a a - ./e.js 20 bytes [built] [code generated] - chunk (runtime: c) all/c.js (c) 116 bytes (javascript) 2.64 KiB (runtime) [entry] [rendered] - > ./c c - runtime modules 2.64 KiB 4 modules - ./c.js 116 bytes [built] [code generated] - chunk (runtime: a, b, c, main) all/568.js 20 bytes [initial] [rendered] split chunk (cache group: default) - > ./b ./index.js 2:0-47 - > ./c ./index.js 3:0-47 - > ./g ./a.js 6:0-47 - > ./b b - > ./c c - ./f.js 20 bytes [built] [code generated] - chunk (runtime: a, b, c, main) all/767.js 20 bytes [initial] [rendered] split chunk (cache group: default) - > ./a ./index.js 1:0-47 - > ./b ./index.js 2:0-47 - > ./c ./index.js 3:0-47 - > ./a a - > ./b b - > ./c c - ./d.js 20 bytes [built] [code generated] - chunk (runtime: c, main) all/769.js (id hint: vendors) 20 bytes [initial] [rendered] split chunk (cache group: vendors) - > ./c ./index.js 3:0-47 - > ./c c - ./node_modules/z.js 20 bytes [built] [code generated] - chunk (runtime: a) all/a.js (a) 165 bytes (javascript) 7.45 KiB (runtime) [entry] [rendered] - > ./a a - runtime modules 7.45 KiB 10 modules - ./a.js 165 bytes [built] [code generated] - chunk (runtime: main) all/async-a.js (async-a) 165 bytes [rendered] - > ./a ./index.js 1:0-47 - ./a.js 165 bytes [built] [code generated] - chunk (runtime: a, b, main) all/954.js (id hint: vendors) 20 bytes [initial] [rendered] split chunk (cache group: vendors) - > ./a ./index.js 1:0-47 - > ./b ./index.js 2:0-47 - > ./a a - > ./b b - ./node_modules/y.js 20 bytes [built] [code generated] - all (webpack x.x.x) compiled successfully" -`; - -exports[`StatsTestCases should print correct stats for child-compiler-apply-entry-option 1`] = ` -"asset child.js 84 bytes [emitted] -asset parent.js 84 bytes [emitted] (name: parent) -Entrypoint parent 84 bytes = parent.js -./parent.js 1 bytes [built] [code generated] - assets by status 84 bytes [cached] 1 asset - Entrypoint child = child.js - ./child.js 1 bytes [built] [code generated] - - Child TestApplyEntryOptionPlugin compiled successfully - -WARNING in configuration -The 'mode' option has not been set, webpack will fallback to 'production' for this value. -Set 'mode' option to 'development' or 'production' to enable defaults for each environment. -You can also set it to 'none' to disable any default behavior. Learn more: https://webpack.js.org/configuration/mode/ - -webpack x.x.x compiled with 1 warning in X ms" -`; - -exports[`StatsTestCases should print correct stats for chunk-module-id-range 1`] = ` -"PublicPath: auto -asset main1.js 4.51 KiB [emitted] (name: main1) -asset main2.js 4.5 KiB [emitted] (name: main2) -Entrypoint main1 4.51 KiB = main1.js -Entrypoint main2 4.5 KiB = main2.js -chunk (runtime: main1) main1.js (main1) 189 bytes (javascript) 670 bytes (runtime) [entry] [rendered] - > ./main1 main1 - runtime modules 670 bytes 3 modules - cacheable modules 189 bytes - ./a.js 20 bytes [dependent] [built] [code generated] - ./b.js 20 bytes [dependent] [built] [code generated] - ./c.js 20 bytes [dependent] [built] [code generated] - ./d.js 20 bytes [dependent] [built] [code generated] - ./main1.js 109 bytes [built] [code generated] -chunk (runtime: main2) main2.js (main2) 189 bytes (javascript) 670 bytes (runtime) [entry] [rendered] - > ./main2 main2 - runtime modules 670 bytes 3 modules - cacheable modules 189 bytes - ./a.js 20 bytes [dependent] [built] [code generated] - ./d.js 20 bytes [dependent] [built] [code generated] - ./e.js 20 bytes [dependent] [built] [code generated] - ./f.js 20 bytes [dependent] [built] [code generated] - ./main2.js 109 bytes [built] [code generated] -webpack x.x.x compiled successfully in X ms" -`; - -exports[`StatsTestCases should print correct stats for chunks 1`] = ` -"PublicPath: auto -asset bundle.js 10.1 KiB [emitted] (name: main) -asset 460.bundle.js 320 bytes [emitted] -asset 524.bundle.js 206 bytes [emitted] -asset 996.bundle.js 138 bytes [emitted] -chunk (runtime: main) bundle.js (main) 73 bytes (javascript) 5.93 KiB (runtime) >{460}< >{996}< [entry] [rendered] - > ./index main - runtime modules 5.93 KiB 7 modules - cacheable modules 73 bytes - ./a.js 22 bytes [dependent] [built] [code generated] - cjs self exports reference ./a.js 1:0-14 - cjs require ./a ./index.js 1:0-14 - X ms -> - X ms (resolving: X ms, restoring: X ms, integration: X ms, building: X ms, storing: X ms) - ./index.js 51 bytes [built] [code generated] - entry ./index main - X ms (resolving: X ms, restoring: X ms, integration: X ms, building: X ms, storing: X ms) -chunk (runtime: main) 460.bundle.js 54 bytes <{179}> >{524}< [rendered] - > ./c ./index.js 3:0-16 - ./c.js 54 bytes [built] [code generated] - amd require ./c ./index.js 3:0-16 - X ms -> - X ms (resolving: X ms, restoring: X ms, integration: X ms, building: X ms, storing: X ms) -chunk (runtime: main) 524.bundle.js 44 bytes <{460}> [rendered] - > ./c.js 1:0-52 - ./d.js 22 bytes [built] [code generated] - require.ensure item ./d ./c.js 1:0-52 - cjs self exports reference ./d.js 1:0-14 - X ms -> X ms -> - X ms (resolving: X ms, restoring: X ms, integration: X ms, building: X ms, storing: X ms) - ./e.js 22 bytes [built] [code generated] - require.ensure item ./e ./c.js 1:0-52 - cjs self exports reference ./e.js 1:0-14 - X ms -> X ms -> - X ms (resolving: X ms, restoring: X ms, integration: X ms, building: X ms, storing: X ms) -chunk (runtime: main) 996.bundle.js 22 bytes <{179}> [rendered] - > ./b ./index.js 2:0-16 - ./b.js 22 bytes [built] [code generated] - cjs self exports reference ./b.js 1:0-14 - amd require ./b ./index.js 2:0-16 - X ms -> - X ms (resolving: X ms, restoring: X ms, integration: X ms, building: X ms, storing: X ms) -webpack x.x.x compiled successfully in X ms" -`; - -exports[`StatsTestCases should print correct stats for chunks-development 1`] = ` -"PublicPath: auto -asset bundle.js 11.2 KiB [emitted] (name: main) -asset d_js-e_js.bundle.js 1.07 KiB [emitted] -asset c_js.bundle.js 1010 bytes [emitted] -asset b_js.bundle.js 816 bytes [emitted] -chunk (runtime: main) b_js.bundle.js 22 bytes <{main}> [rendered] - > ./b ./index.js 2:0-16 - ./b.js 22 bytes [built] [code generated] - cjs self exports reference ./b.js 1:0-14 - amd require ./b ./index.js 2:0-16 - X ms -> - X ms (resolving: X ms, restoring: X ms, integration: X ms, building: X ms, storing: X ms) -chunk (runtime: main) c_js.bundle.js 54 bytes <{main}> >{d_js-e_js}< [rendered] - > ./c ./index.js 3:0-16 - ./c.js 54 bytes [built] [code generated] - amd require ./c ./index.js 3:0-16 - X ms -> - X ms (resolving: X ms, restoring: X ms, integration: X ms, building: X ms, storing: X ms) -chunk (runtime: main) d_js-e_js.bundle.js 60 bytes <{c_js}> [rendered] - > ./c.js 1:0-52 - ./d.js 22 bytes [built] [code generated] - require.ensure item ./d ./c.js 1:0-52 - cjs self exports reference ./d.js 1:0-14 - X ms -> X ms -> - X ms (resolving: X ms, restoring: X ms, integration: X ms, building: X ms, storing: X ms) - ./e.js 38 bytes [built] [code generated] - require.ensure item ./e ./c.js 1:0-52 - cjs self exports reference ./e.js 2:0-14 - X ms -> X ms -> - X ms (resolving: X ms, restoring: X ms, integration: X ms, building: X ms, storing: X ms) -chunk (runtime: main) bundle.js (main) 73 bytes (javascript) 5.93 KiB (runtime) >{b_js}< >{c_js}< [entry] [rendered] - > ./index main - runtime modules 5.93 KiB 7 modules - cacheable modules 73 bytes - ./a.js 22 bytes [dependent] [built] [code generated] - cjs self exports reference ./a.js 1:0-14 - cjs require ./a ./e.js 1:0-14 - cjs require ./a ./index.js 1:0-14 - X ms -> - X ms (resolving: X ms, restoring: X ms, integration: X ms, building: X ms, storing: X ms) - ./index.js 51 bytes [built] [code generated] - entry ./index main - X ms (resolving: X ms, restoring: X ms, integration: X ms, building: X ms, storing: X ms) -webpack x.x.x compiled successfully in X ms" -`; - -exports[`StatsTestCases should print correct stats for circular-correctness 1`] = ` -"chunk (runtime: main) 128.bundle.js (b) 49 bytes <{179}> <{459}> >{459}< [rendered] - ./module-b.js 49 bytes [built] [code generated] -chunk (runtime: main) bundle.js (main) 98 bytes (javascript) 7.61 KiB (runtime) >{128}< >{786}< [entry] [rendered] - runtime modules 7.61 KiB 10 modules - ./index.js 98 bytes [built] [code generated] -chunk (runtime: main) 459.bundle.js (c) 98 bytes <{128}> <{786}> >{128}< >{786}< [rendered] - ./module-c.js 98 bytes [built] [code generated] -chunk (runtime: main) 786.bundle.js (a) 49 bytes <{179}> <{459}> >{459}< [rendered] - ./module-a.js 49 bytes [built] [code generated] -webpack x.x.x compiled successfully" -`; - -exports[`StatsTestCases should print correct stats for color-disabled 1`] = ` -"asset main.js 84 bytes [emitted] (name: main) -./index.js 1 bytes [built] [code generated] -webpack x.x.x compiled successfully in X ms" -`; - -exports[`StatsTestCases should print correct stats for color-enabled 1`] = ` -"asset main.js 84 bytes [emitted] (name: main) -./index.js 1 bytes [built] [code generated] -webpack x.x.x compiled successfully in X ms" -`; - -exports[`StatsTestCases should print correct stats for color-enabled-custom 1`] = ` -"asset main.js 84 bytes [emitted] (name: main) -./index.js 1 bytes [built] [code generated] -webpack x.x.x compiled successfully in X ms" -`; - -exports[`StatsTestCases should print correct stats for common-libs 1`] = ` -"asset react.js 3.02 KiB [emitted] [minimized] (name: react) 1 related asset -modules by path ../../../node_modules/react/ 6.48 KiB - ../../../node_modules/react/index.js 190 bytes [built] [code generated] - ../../../node_modules/react/cjs/react.production.min.js 6.3 KiB [built] [code generated] -./react.js 74 bytes [built] [code generated] -../../../node_modules/object-assign/index.js 2.06 KiB [built] [code generated] -webpack x.x.x compiled successfully in X ms" -`; - -exports[`StatsTestCases should print correct stats for commons-chunk-min-size-0 1`] = ` -"asset entry-1.js 5.55 KiB [emitted] (name: entry-1) -asset 429.js 274 bytes [emitted] (id hint: vendor-1) -Entrypoint entry-1 5.82 KiB = 429.js 274 bytes entry-1.js 5.55 KiB -runtime modules 2.33 KiB 3 modules -modules by path ./modules/*.js 132 bytes - ./modules/a.js 22 bytes [built] [code generated] - ./modules/b.js 22 bytes [built] [code generated] - ./modules/c.js 22 bytes [built] [code generated] - ./modules/d.js 22 bytes [built] [code generated] - ./modules/e.js 22 bytes [built] [code generated] - ./modules/f.js 22 bytes [built] [code generated] -./entry-1.js 145 bytes [built] [code generated] -webpack x.x.x compiled successfully in X ms" -`; - -exports[`StatsTestCases should print correct stats for commons-chunk-min-size-Infinity 1`] = ` -"asset entry-1.js 5.55 KiB [emitted] (name: entry-1) -asset vendor-1.js 274 bytes [emitted] (name: vendor-1) (id hint: vendor-1) -Entrypoint entry-1 5.82 KiB = vendor-1.js 274 bytes entry-1.js 5.55 KiB -runtime modules 2.33 KiB 3 modules -modules by path ./modules/*.js 132 bytes - ./modules/a.js 22 bytes [built] [code generated] - ./modules/b.js 22 bytes [built] [code generated] - ./modules/c.js 22 bytes [built] [code generated] - ./modules/d.js 22 bytes [built] [code generated] - ./modules/e.js 22 bytes [built] [code generated] - ./modules/f.js 22 bytes [built] [code generated] -./entry-1.js 145 bytes [built] [code generated] -webpack x.x.x compiled successfully in X ms" -`; - -exports[`StatsTestCases should print correct stats for commons-plugin-issue-4980 1`] = ` -"asset app.d57c29ee13b80ecca98d-1.js 6.08 KiB [emitted] [immutable] (name: app) -asset vendor.ebb9b6c7e5493f36bead-1.js 619 bytes [emitted] [immutable] (name: vendor) (id hint: vendor) -Entrypoint app 6.69 KiB = vendor.ebb9b6c7e5493f36bead-1.js 619 bytes app.d57c29ee13b80ecca98d-1.js 6.08 KiB -runtime modules 2.63 KiB 4 modules -orphan modules 118 bytes [orphan] 2 modules -cacheable modules 272 bytes - ./entry-1.js + 2 modules 185 bytes [built] [code generated] - ./constants.js 87 bytes [built] [code generated] -webpack x.x.x compiled successfully in X ms - -asset app.4b538163b6d1bbb268b8-2.js 6.1 KiB [emitted] [immutable] (name: app) -asset vendor.ebb9b6c7e5493f36bead-2.js 619 bytes [emitted] [immutable] (name: vendor) (id hint: vendor) -Entrypoint app 6.7 KiB = vendor.ebb9b6c7e5493f36bead-2.js 619 bytes app.4b538163b6d1bbb268b8-2.js 6.1 KiB -runtime modules 2.63 KiB 4 modules -orphan modules 125 bytes [orphan] 2 modules -cacheable modules 279 bytes - ./entry-2.js + 2 modules 192 bytes [built] [code generated] - ./constants.js 87 bytes [built] [code generated] -webpack x.x.x compiled successfully in X ms" -`; - -exports[`StatsTestCases should print correct stats for concat-and-sideeffects 1`] = ` -"./index.js + 2 modules 119 bytes [built] [code generated] - | ./index.js 46 bytes [built] - | Statement (ExpressionStatement) with side effects in source code at 3:0-15 - | ./node_modules/pmodule/a.js 49 bytes [built] - | ./node_modules/pmodule/aa.js 24 bytes [built] -./node_modules/pmodule/a.js 49 bytes [orphan] [built] -./node_modules/pmodule/index.js 63 bytes [orphan] [built] - ModuleConcatenation bailout: Module is not in any chunk -./node_modules/pmodule/aa.js 24 bytes [orphan] [built] -./node_modules/pmodule/b.js 49 bytes [orphan] [built] - ModuleConcatenation bailout: Module is not in any chunk -./node_modules/pmodule/c.js 49 bytes [orphan] [built] - ModuleConcatenation bailout: Module is not in any chunk -./node_modules/pmodule/bb.js 24 bytes [orphan] [built] - ModuleConcatenation bailout: Module is not in any chunk -./node_modules/pmodule/cc.js 24 bytes [orphan] [built] - ModuleConcatenation bailout: Module is not in any chunk" -`; - -exports[`StatsTestCases should print correct stats for context-independence 1`] = ` -"asset main-12ecd19fc14f0e0fe627.js 10.3 KiB [emitted] [immutable] (name: main) - sourceMap main-12ecd19fc14f0e0fe627.js.map 9.2 KiB [emitted] [dev] (auxiliary name: main) -asset 664-a0b92720f0f2d9d4aaf4.js 455 bytes [emitted] [immutable] - sourceMap 664-a0b92720f0f2d9d4aaf4.js.map 344 bytes [emitted] [dev] -runtime modules 6.22 KiB 8 modules -orphan modules 19 bytes [orphan] 1 module -cacheable modules 106 bytes - ./a/index.js 40 bytes [built] [code generated] - ./a/chunk.js + 1 modules 66 bytes [built] [code generated] -webpack x.x.x compiled successfully in X ms - -asset main-12ecd19fc14f0e0fe627.js 10.3 KiB [emitted] [immutable] (name: main) - sourceMap main-12ecd19fc14f0e0fe627.js.map 9.2 KiB [emitted] [dev] (auxiliary name: main) -asset 664-a0b92720f0f2d9d4aaf4.js 455 bytes [emitted] [immutable] - sourceMap 664-a0b92720f0f2d9d4aaf4.js.map 344 bytes [emitted] [dev] -runtime modules 6.22 KiB 8 modules -orphan modules 19 bytes [orphan] 1 module -cacheable modules 106 bytes - ./b/index.js 40 bytes [built] [code generated] - ./b/chunk.js + 1 modules 66 bytes [built] [code generated] -webpack x.x.x compiled successfully in X ms - -asset main-c6e32bcdbc5169b9a7dc.js 11.5 KiB [emitted] [immutable] (name: main) -asset 664-3cdeef446e88ad105071.js 1.5 KiB [emitted] [immutable] -runtime modules 6.22 KiB 8 modules -orphan modules 19 bytes [orphan] 1 module -cacheable modules 106 bytes - ./a/index.js 40 bytes [built] [code generated] - ./a/chunk.js + 1 modules 66 bytes [built] [code generated] -webpack x.x.x compiled successfully in X ms - -asset main-c6e32bcdbc5169b9a7dc.js 11.5 KiB [emitted] [immutable] (name: main) -asset 664-3cdeef446e88ad105071.js 1.5 KiB [emitted] [immutable] -runtime modules 6.22 KiB 8 modules -orphan modules 19 bytes [orphan] 1 module -cacheable modules 106 bytes - ./b/index.js 40 bytes [built] [code generated] - ./b/chunk.js + 1 modules 66 bytes [built] [code generated] -webpack x.x.x compiled successfully in X ms" -`; - -exports[`StatsTestCases should print correct stats for custom-terser 1`] = ` -"asset bundle.js 586 bytes [emitted] [minimized] (name: main) -./index.js 128 bytes [built] [code generated] - [no exports used] -./a.js 49 bytes [built] [code generated] - [used exports unknown] -webpack x.x.x compiled successfully in X ms" -`; - -exports[`StatsTestCases should print correct stats for define-plugin 1`] = ` -"asset 123.js 1.4 KiB [emitted] (name: main) -./index.js 24 bytes [built] [code generated] -webpack x.x.x compiled successfully in X ms - -asset 321.js 1.4 KiB [emitted] (name: main) -./index.js 24 bytes [built] [code generated] -webpack x.x.x compiled successfully in X ms - -asset both.js 1.4 KiB [emitted] (name: main) -./index.js 24 bytes [built] [code generated] -webpack x.x.x compiled successfully in X ms" -`; - -exports[`StatsTestCases should print correct stats for details-error 1`] = ` -"0 errors 0 warnings: - asset 0.js 1.15 KiB [emitted] (name: main) - ./index.js 1 bytes [built] [code generated] - 0 errors 0 warnings (webpack x.x.x) compiled successfully in X ms - -1 errors 0 warnings: - asset 1.js 1.15 KiB [emitted] (name: main) - ./index.js 1 bytes [built] [code generated] - - ERROR in Test - Error details - - 1 errors 0 warnings (webpack x.x.x) compiled with 1 error in X ms - -0 errors 1 warnings: - asset 10.js 1.15 KiB [emitted] (name: main) - ./index.js 1 bytes [built] [code generated] - - WARNING in Test - - 1 warning has detailed information that is not shown. - Use 'stats.errorDetails: true' resp. '--stats-error-details' to show it. - - 0 errors 1 warnings (webpack x.x.x) compiled with 1 warning in X ms - -2 errors 0 warnings: - asset 2.js 1.15 KiB [emitted] (name: main) - ./index.js 1 bytes [built] [code generated] - - ERROR in Test - Error details - - ERROR in Test - Error details - - 2 errors 0 warnings (webpack x.x.x) compiled with 2 errors in X ms - -0 errors 2 warnings: - asset 20.js 1.15 KiB [emitted] (name: main) - ./index.js 1 bytes [built] [code generated] - - WARNING in Test - - WARNING in Test - - 2 warnings have detailed information that is not shown. - Use 'stats.errorDetails: true' resp. '--stats-error-details' to show it. - - 0 errors 2 warnings (webpack x.x.x) compiled with 2 warnings in X ms - -1 errors 1 warnings: - asset 11.js 1.15 KiB [emitted] (name: main) - ./index.js 1 bytes [built] [code generated] - - WARNING in Test - - 1 warning has detailed information that is not shown. - Use 'stats.errorDetails: true' resp. '--stats-error-details' to show it. - - ERROR in Test - Error details - - 1 errors 1 warnings (webpack x.x.x) compiled with 1 error and 1 warning in X ms - -2 errors 1 warnings: - asset 12.js 1.15 KiB [emitted] (name: main) - ./index.js 1 bytes [built] [code generated] - - WARNING in Test - - 1 warning has detailed information that is not shown. - Use 'stats.errorDetails: true' resp. '--stats-error-details' to show it. - - ERROR in Test - Error details - - ERROR in Test - Error details - - 2 errors 1 warnings (webpack x.x.x) compiled with 2 errors and 1 warning in X ms - -3 errors 1 warnings: - asset 13.js 1.15 KiB [emitted] (name: main) - ./index.js 1 bytes [built] [code generated] - - WARNING in Test - - 1 warning has detailed information that is not shown. - Use 'stats.errorDetails: true' resp. '--stats-error-details' to show it. - - ERROR in Test - - ERROR in Test - - ERROR in Test - - 3 errors have detailed information that is not shown. - Use 'stats.errorDetails: true' resp. '--stats-error-details' to show it. - - 3 errors 1 warnings (webpack x.x.x) compiled with 3 errors and 1 warning in X ms - -3 errors 0 warnings: - asset 3.js 1.15 KiB [emitted] (name: main) - ./index.js 1 bytes [built] [code generated] - - ERROR in Test - - ERROR in Test - - ERROR in Test - - 3 errors have detailed information that is not shown. - Use 'stats.errorDetails: true' resp. '--stats-error-details' to show it. - - 3 errors 0 warnings (webpack x.x.x) compiled with 3 errors in X ms - -0 errors 3 warnings: - asset 30.js 1.15 KiB [emitted] (name: main) - ./index.js 1 bytes [built] [code generated] - - WARNING in Test - - WARNING in Test - - WARNING in Test - - 3 warnings have detailed information that is not shown. - Use 'stats.errorDetails: true' resp. '--stats-error-details' to show it. - - 0 errors 3 warnings (webpack x.x.x) compiled with 3 warnings in X ms" -`; - -exports[`StatsTestCases should print correct stats for dll-reference-plugin-issue-7624 1`] = ` -"asset bundle.js 113 bytes [emitted] (name: main) -./entry.js 29 bytes [built] [code generated] -webpack x.x.x compiled successfully in X ms" -`; - -exports[`StatsTestCases should print correct stats for dll-reference-plugin-issue-7624-error 1`] = ` -"assets by status 113 bytes [cached] 1 asset -./entry.js 29 bytes [built] [code generated] - -ERROR in Dll manifest ./blank-manifest.json -Unexpected end of JSON input while parsing near '' - -webpack x.x.x compiled with 1 error in X ms" -`; - -exports[`StatsTestCases should print correct stats for entry-filename 1`] = ` -"PublicPath: auto -asset a.js 1.4 KiB [emitted] (name: a) -asset c.js 1.4 KiB [emitted] (name: b) -chunk (runtime: b) c.js (b) 22 bytes [entry] [rendered] - > ./b.js b - ./b.js 22 bytes [built] [code generated] - cjs self exports reference ./b.js 1:0-14 - entry ./b.js b - X ms (resolving: X ms, restoring: X ms, integration: X ms, building: X ms, storing: X ms) -chunk (runtime: a) a.js (a) 22 bytes [entry] [rendered] - > ./a.js a - ./a.js 22 bytes [built] [code generated] - cjs self exports reference ./a.js 1:0-14 - entry ./a.js a - X ms (resolving: X ms, restoring: X ms, integration: X ms, building: X ms, storing: X ms) -webpack x.x.x compiled successfully in X ms" -`; - -exports[`StatsTestCases should print correct stats for exclude-with-loader 1`] = ` -"hidden assets 34 bytes 1 asset -asset bundle.js 5.28 KiB [emitted] (name: main) -runtime modules 1.72 KiB 5 modules -hidden modules 123 bytes 2 modules -cacheable modules 119 bytes - ./index.js 77 bytes [built] [code generated] - ./a.txt 42 bytes [built] [code generated] -webpack x.x.x compiled successfully in X ms" -`; - -exports[`StatsTestCases should print correct stats for external 1`] = ` -"asset main.js 1.37 KiB [emitted] (name: main) -./index.js 17 bytes [built] [code generated] -external \\"test\\" 42 bytes [built] [code generated] -webpack x.x.x compiled successfully in X ms" -`; - -exports[`StatsTestCases should print correct stats for graph-correctness-entries 1`] = ` -"chunk (runtime: e1, e2) b.js (b) 49 bytes <{786}> >{459}< [rendered] - ./module-b.js 49 bytes [built] [code generated] - import() ./module-b ./module-a.js 1:0-47 -chunk (runtime: e1) e1.js (e1) 49 bytes (javascript) 7.64 KiB (runtime) >{786}< [entry] [rendered] - runtime modules 7.64 KiB 10 modules - ./e1.js 49 bytes [built] [code generated] - entry ./e1 e1 -chunk (runtime: e1, e2) c.js (c) 49 bytes <{128}> <{621}> >{786}< [rendered] - ./module-c.js 49 bytes [built] [code generated] - import() ./module-c ./e2.js 1:0-47 - import() ./module-c ./module-b.js 1:0-47 -chunk (runtime: e2) e2.js (e2) 49 bytes (javascript) 7.64 KiB (runtime) >{459}< [entry] [rendered] - runtime modules 7.64 KiB 10 modules - ./e2.js 49 bytes [built] [code generated] - entry ./e2 e2 -chunk (runtime: e1, e2) a.js (a) 49 bytes <{257}> <{459}> >{128}< [rendered] - ./module-a.js 49 bytes [built] [code generated] - import() ./module-a ./e1.js 1:0-47 - import() ./module-a ./module-c.js 1:0-47 -webpack x.x.x compiled successfully" -`; - -exports[`StatsTestCases should print correct stats for graph-correctness-modules 1`] = ` -"chunk (runtime: e1, e2) b.js (b) 179 bytes <{786}> >{459}< [rendered] - ./module-b.js 179 bytes [built] [code generated] - import() ./module-b ./module-a.js 1:0-47 -chunk (runtime: e1) e1.js (e1) 119 bytes (javascript) 7.91 KiB (runtime) >{786}< >{892}< [entry] [rendered] - runtime modules 7.91 KiB 11 modules - cacheable modules 119 bytes - ./e1.js 70 bytes [built] [code generated] - entry ./e1 e1 - ./module-x.js 49 bytes [dependent] [built] [code generated] - harmony side effect evaluation ./module-x ./e1.js 1:0-20 - harmony side effect evaluation ./module-x ./e2.js 1:0-20 - import() ./module-x ./module-b.js 2:0-20 -chunk (runtime: e1, e2) c.js (c) 49 bytes <{128}> <{621}> >{786}< [rendered] - ./module-c.js 49 bytes [built] [code generated] - import() ./module-c ./e2.js 2:0-47 - import() ./module-c ./module-b.js 1:0-47 -chunk (runtime: e2) e2.js (e2) 119 bytes (javascript) 7.91 KiB (runtime) >{459}< >{892}< [entry] [rendered] - runtime modules 7.91 KiB 11 modules - cacheable modules 119 bytes - ./e2.js 70 bytes [built] [code generated] - entry ./e2 e2 - ./module-x.js 49 bytes [dependent] [built] [code generated] - harmony side effect evaluation ./module-x ./e1.js 1:0-20 - harmony side effect evaluation ./module-x ./e2.js 1:0-20 - import() ./module-x ./module-b.js 2:0-20 -chunk (runtime: e1, e2) a.js (a) 49 bytes <{257}> <{459}> >{128}< [rendered] - ./module-a.js 49 bytes [built] [code generated] - import() ./module-a ./e1.js 2:0-47 - import() ./module-a ./module-c.js 1:0-47 -chunk (runtime: e1, e2) y.js (y) 1 bytes <{257}> <{621}> [rendered] - ./module-y.js 1 bytes [built] [code generated] - import() ./module-y ./module-x.js 1:0-47 -webpack x.x.x compiled successfully" -`; - -exports[`StatsTestCases should print correct stats for graph-roots 1`] = ` -"chunk (runtime: main) cycle.js (cycle) 168 bytes [rendered] - ./cycle/a.js 39 bytes [built] [code generated] - ./cycle/b.js 39 bytes [built] [code generated] - ./cycle/c.js 51 bytes [built] [code generated] - ./cycle/index.js 39 bytes [built] [code generated] -chunk (runtime: main) cycle2.js (cycle2) 205 bytes [rendered] - dependent modules 166 bytes [dependent] 3 modules - ./cycle2/index.js 39 bytes [built] [code generated] -chunk (runtime: main) cycles.js (cycles) 410 bytes [rendered] - dependent modules 332 bytes [dependent] 6 modules - ./cycles/1/index.js 39 bytes [built] [code generated] - ./cycles/2/index.js 39 bytes [built] [code generated] -chunk (runtime: main) id-equals-name_js.js (id-equals-name_js) 21 bytes [rendered] - ./id-equals-name.js?1 21 bytes [built] [code generated] -chunk (runtime: main) id-equals-name_js-_70e2.js (id-equals-name_js-_70e2) 21 bytes [rendered] - ./id-equals-name.js?2 21 bytes [built] [code generated] -chunk (runtime: main) id-equals-name_js0.js 21 bytes [rendered] - ./id-equals-name.js 21 bytes [built] [code generated] -chunk (runtime: main) id-equals-name_js_3.js 21 bytes [rendered] - ./id-equals-name.js?3 21 bytes [built] [code generated] -chunk (runtime: main) main.js (main) 639 bytes (javascript) 6.49 KiB (runtime) [entry] [rendered] - runtime modules 6.49 KiB 9 modules - ./index.js 639 bytes [built] [code generated] -chunk (runtime: main) tree.js (tree) 137 bytes [rendered] - dependent modules 98 bytes [dependent] 3 modules - ./tree/index.js 39 bytes [built] [code generated] -chunk (runtime: main) trees.js (trees) 215 bytes [rendered] - dependent modules 98 bytes [dependent] 3 modules - ./trees/1.js 39 bytes [built] [code generated] - ./trees/2.js 39 bytes [built] [code generated] - ./trees/3.js 39 bytes [built] [code generated]" -`; - -exports[`StatsTestCases should print correct stats for ignore-warnings 1`] = ` -"asset main.js 1.37 KiB [emitted] (name: main) -orphan modules 617 bytes [orphan] 9 modules -./index.js + 9 modules 790 bytes [built] [code generated] - -WARNING in ./module.js?4 3:12-20 -Should not import the named export 'homepage' (imported as 'homepage') from default-exporting module (only default export is available soon) - @ ./index.js 4:0-20 - -WARNING in ./module2.js?1 3:12-16 -Should not import the named export 'name' (imported as 'name') from default-exporting module (only default export is available soon) - @ ./index.js 6:0-21 - -webpack x.x.x compiled with 2 warnings in X ms" -`; - -exports[`StatsTestCases should print correct stats for immutable 1`] = ` -"asset 583eb2ab68152b489f54.js 13.3 KiB [emitted] [immutable] (name: main) -asset 22c24a3b26d46118dc06.js 809 bytes [emitted] [immutable]" -`; - -exports[`StatsTestCases should print correct stats for import-context-filter 1`] = ` -"asset entry.js 11.8 KiB [emitted] (name: entry) -asset 398.js 482 bytes [emitted] -asset 544.js 482 bytes [emitted] -asset 718.js 482 bytes [emitted] -runtime modules 6.49 KiB 9 modules -built modules 724 bytes [built] - modules by path ./templates/*.js 114 bytes - ./templates/bar.js 38 bytes [optional] [built] [code generated] - ./templates/baz.js 38 bytes [optional] [built] [code generated] - ./templates/foo.js 38 bytes [optional] [built] [code generated] - ./entry.js 450 bytes [built] [code generated] - ./templates/ lazy ^\\\\.\\\\/.*$ include: \\\\.js$ exclude: \\\\.noimport\\\\.js$ namespace object 160 bytes [optional] [built] [code generated] -webpack x.x.x compiled successfully in X ms" -`; - -exports[`StatsTestCases should print correct stats for import-weak 1`] = ` -"asset entry.js 12.9 KiB [emitted] (name: entry) -asset 836.js 138 bytes [emitted] -runtime modules 7.61 KiB 10 modules -orphan modules 37 bytes [orphan] 1 module -cacheable modules 142 bytes - ./entry.js 120 bytes [built] [code generated] - ./modules/b.js 22 bytes [built] [code generated] -webpack x.x.x compiled successfully in X ms" -`; - -exports[`StatsTestCases should print correct stats for import-with-invalid-options-comments 1`] = ` -"runtime modules 8.53 KiB 12 modules -cacheable modules 559 bytes - ./index.js 50 bytes [built] [code generated] - ./chunk.js 401 bytes [built] [code generated] [3 warnings] - ./chunk-a.js 27 bytes [built] [code generated] - ./chunk-b.js 27 bytes [built] [code generated] - ./chunk-c.js 27 bytes [built] [code generated] - ./chunk-d.js 27 bytes [built] [code generated] - -WARNING in ./chunk.js 2:11-84 -Compilation error while processing magic comment(-s): /* webpackPrefetch: true, webpackChunkName: notGoingToCompileChunkName */: notGoingToCompileChunkName is not defined - @ ./index.js 1:0-49 - -WARNING in ./chunk.js 4:11-77 -Compilation error while processing magic comment(-s): /* webpack Prefetch: 0, webpackChunkName: \\"notGoingToCompile-c\\" */: Unexpected identifier - @ ./index.js 1:0-49 - -WARNING in ./chunk.js 5:11-38 -Compilation error while processing magic comment(-s): /* webpackPrefetch: nope */: nope is not defined - @ ./index.js 1:0-49 - -webpack x.x.x compiled with 3 warnings" -`; - -exports[`StatsTestCases should print correct stats for issue-7577 1`] = ` -"asset a-runtime~main-2ee3b719049796c1a859.js 4.8 KiB [emitted] [immutable] (name: runtime~main) -asset a-main-ef61ff9b5cacf52087be.js 424 bytes [emitted] [immutable] (name: main) -asset a-all-a_js-5af81d3b60f9e87be69d.js 140 bytes [emitted] [immutable] (id hint: all) -Entrypoint main 5.35 KiB = a-runtime~main-2ee3b719049796c1a859.js 4.8 KiB a-all-a_js-5af81d3b60f9e87be69d.js 140 bytes a-main-ef61ff9b5cacf52087be.js 424 bytes -runtime modules 2.34 KiB 3 modules -./a.js 18 bytes [built] [code generated] -webpack x.x.x compiled successfully in X ms - -asset b-runtime~main-c0fda4a5ca3ab8452a13.js 5.74 KiB [emitted] [immutable] (name: runtime~main) -asset b-all-b_js-286fe88eae15de65188e.js 475 bytes [emitted] [immutable] (id hint: all) -asset b-main-132fd6da6e6e6728c990.js 457 bytes [emitted] [immutable] (name: main) -asset b-vendors-node_modules_vendor_js-499179597d8c965dd5e0.js 185 bytes [emitted] [immutable] (id hint: vendors) -Entrypoint main 6.83 KiB = b-runtime~main-c0fda4a5ca3ab8452a13.js 5.74 KiB b-vendors-node_modules_vendor_js-499179597d8c965dd5e0.js 185 bytes b-all-b_js-286fe88eae15de65188e.js 475 bytes b-main-132fd6da6e6e6728c990.js 457 bytes -runtime modules 2.9 KiB 5 modules -cacheable modules 40 bytes - ./b.js 17 bytes [built] [code generated] - ./node_modules/vendor.js 23 bytes [built] [code generated] -webpack x.x.x compiled successfully in X ms - -assets by chunk 895 bytes (id hint: all) - asset c-all-b_js-fe3b412293f057de38c8.js 502 bytes [emitted] [immutable] (id hint: all) - asset c-all-c_js-172fc4c28be7e411e551.js 393 bytes [emitted] [immutable] (id hint: all) -asset c-runtime~main-ef835ea1b67a6d1dc497.js 13.4 KiB [emitted] [immutable] (name: runtime~main) -asset c-main-a443d2f54b3b7aebaf75.js 664 bytes [emitted] [immutable] (name: main) -asset c-vendors-node_modules_vendor_js-499179597d8c965dd5e0.js 185 bytes [emitted] [immutable] (id hint: vendors) -Entrypoint main 14.5 KiB = c-runtime~main-ef835ea1b67a6d1dc497.js 13.4 KiB c-all-c_js-172fc4c28be7e411e551.js 393 bytes c-main-a443d2f54b3b7aebaf75.js 664 bytes -runtime modules 8.54 KiB 13 modules -cacheable modules 101 bytes - ./c.js 61 bytes [built] [code generated] - ./b.js 17 bytes [built] [code generated] - ./node_modules/vendor.js 23 bytes [built] [code generated] -webpack x.x.x compiled successfully in X ms" -`; - -exports[`StatsTestCases should print correct stats for limit-chunk-count-plugin 1`] = ` -"1 chunks: - asset bundle1.js 4.84 KiB [emitted] (name: main) - chunk (runtime: main) bundle1.js (main) 219 bytes (javascript) 1.77 KiB (runtime) <{179}> >{179}< [entry] [rendered] - runtime modules 1.77 KiB 4 modules - cacheable modules 219 bytes - ./a.js 22 bytes [dependent] [built] [code generated] - ./b.js 22 bytes [dependent] [built] [code generated] - ./c.js 30 bytes [dependent] [built] [code generated] - ./d.js 22 bytes [dependent] [built] [code generated] - ./e.js 22 bytes [dependent] [built] [code generated] - ./index.js 101 bytes [built] [code generated] - 1 chunks (webpack x.x.x) compiled successfully in X ms - -2 chunks: - asset bundle2.js 12.5 KiB [emitted] (name: main) - asset 459.bundle2.js 664 bytes [emitted] (name: c) - chunk (runtime: main) bundle2.js (main) 101 bytes (javascript) 7.61 KiB (runtime) >{459}< [entry] [rendered] - runtime modules 7.61 KiB 10 modules - ./index.js 101 bytes [built] [code generated] - chunk (runtime: main) 459.bundle2.js (c) 118 bytes <{179}> <{459}> >{459}< [rendered] - dependent modules 44 bytes [dependent] - ./d.js 22 bytes [dependent] [built] [code generated] - ./e.js 22 bytes [dependent] [built] [code generated] - ./a.js 22 bytes [built] [code generated] - ./b.js 22 bytes [built] [code generated] - ./c.js 30 bytes [built] [code generated] - 2 chunks (webpack x.x.x) compiled successfully in X ms - -3 chunks: - asset bundle3.js 12.5 KiB [emitted] (name: main) - asset 459.bundle3.js 528 bytes [emitted] (name: c) - asset 524.bundle3.js 206 bytes [emitted] - chunk (runtime: main) bundle3.js (main) 101 bytes (javascript) 7.61 KiB (runtime) >{459}< [entry] [rendered] - runtime modules 7.61 KiB 10 modules - ./index.js 101 bytes [built] [code generated] - chunk (runtime: main) 459.bundle3.js (c) 74 bytes <{179}> >{524}< [rendered] - ./a.js 22 bytes [built] [code generated] - ./b.js 22 bytes [built] [code generated] - ./c.js 30 bytes [built] [code generated] - chunk (runtime: main) 524.bundle3.js 44 bytes <{459}> [rendered] - ./d.js 22 bytes [built] [code generated] - ./e.js 22 bytes [built] [code generated] - 3 chunks (webpack x.x.x) compiled successfully in X ms - -4 chunks: - asset bundle4.js 12.5 KiB [emitted] (name: main) - asset 459.bundle4.js 392 bytes [emitted] (name: c) - asset 394.bundle4.js 206 bytes [emitted] - asset 524.bundle4.js 206 bytes [emitted] - chunk (runtime: main) bundle4.js (main) 101 bytes (javascript) 7.61 KiB (runtime) >{394}< >{459}< [entry] [rendered] - runtime modules 7.61 KiB 10 modules - ./index.js 101 bytes [built] [code generated] - chunk (runtime: main) 394.bundle4.js 44 bytes <{179}> [rendered] - ./a.js 22 bytes [built] [code generated] - ./b.js 22 bytes [built] [code generated] - chunk (runtime: main) 459.bundle4.js (c) 30 bytes <{179}> >{524}< [rendered] - ./c.js 30 bytes [built] [code generated] - chunk (runtime: main) 524.bundle4.js 44 bytes <{459}> [rendered] - ./d.js 22 bytes [built] [code generated] - ./e.js 22 bytes [built] [code generated] - 4 chunks (webpack x.x.x) compiled successfully in X ms" -`; - -exports[`StatsTestCases should print correct stats for logging 1`] = ` -" [LogTestPlugin] Info -asset main.js 84 bytes [emitted] (name: main) -./index.js 1 bytes [built] [code generated] - -LOG from LogTestPlugin -<-> Group - Info - Log - <+> Collaped group - Log - End -+ 6 hidden lines - -DEBUG LOG from ./node_modules/custom-loader/index.js ./node_modules/custom-loader/index.js!./index.js - An error -| at Object..module.exports (Xdir/logging/node_modules/custom-loader/index.js:5:9) - A warning -| at Object..module.exports (Xdir/logging/node_modules/custom-loader/index.js:6:9) -<-> Unimportant - Info message - Just log - Just debug - Measure: X ms - <-> Nested - Log inside collapsed group - Trace - | at Object..module.exports (Xdir/logging/node_modules/custom-loader/index.js:15:9) - Measure: X ms - ------- - After clear - -DEBUG LOG from ./node_modules/custom-loader/index.js Named Logger ./node_modules/custom-loader/index.js!./index.js - Message with named logger - -LOG from webpack.FlagDependencyExportsPlugin - 100% of exports of modules have been determined (1 not cached, 0 flagged uncacheable, 0 from cache, 0 additional calculations due to dependencies) -+ 3 hidden lines - -LOG from webpack.Compilation - 1 modules hashed (1 variants per module in average) - 100% code generated (1 generated, 0 from cache) - NaN% code generated (0 generated, 0 from cache) -+ 19 hidden lines - -LOG from webpack.buildChunkGraph - 2 queue items processed (1 blocks) - 0 chunk groups connected - 0 chunk groups processed for merging (0 module sets, 0 forked, 0 + 0 modules forked, 0 + 0 modules merged into fork, 0 resulting modules) - 0 chunk group info updated (0 already connected chunk groups reconnected) -+ 5 hidden lines - -LOG from webpack.FileSystemInfo - 1 new snapshots created - 0% root snapshot uncached (0 / 0) - 0% children snapshot uncached (0 / 0) - 0 entries tested - File info in cache: 1 timestamps 1 hashes 1 timestamp hash combinations - File timestamp hash combination snapshot optimization: 0% (0/1) entries shared via 0 shared snapshots (0 times referenced) - Directory info in cache: 0 timestamps 0 hashes 0 timestamp hash combinations - Managed items info in cache: 0 items - -webpack x.x.x compiled successfully in X ms" -`; - -exports[`StatsTestCases should print correct stats for logging-debug 1`] = ` -" [LogTestPlugin] Info -asset main.js 84 bytes [emitted] (name: main) -./index.js 1 bytes [built] [code generated] - -DEBUG LOG from ../logging/node_modules/custom-loader/index.js ../logging/node_modules/custom-loader/index.js!./index.js - An error - A warning -<-> Unimportant - Info message - Just log - Just debug - Measure: X ms - <-> Nested - Log inside collapsed group - Trace - Measure: X ms - ------- - After clear - -DEBUG LOG from ../logging/node_modules/custom-loader/index.js Named Logger ../logging/node_modules/custom-loader/index.js!./index.js - Message with named logger - -webpack x.x.x compiled successfully in X ms" -`; - -exports[`StatsTestCases should print correct stats for max-modules 1`] = ` -"asset main.js 5.47 KiB [emitted] (name: main) -31 modules -webpack x.x.x compiled successfully in X ms" -`; - -exports[`StatsTestCases should print correct stats for max-modules-default 1`] = ` -"asset main.js 5.47 KiB [emitted] (name: main) -31 modules -webpack x.x.x compiled successfully in X ms" -`; - -exports[`StatsTestCases should print correct stats for module-assets 1`] = ` -"assets by path *.js 11.6 KiB - asset main.js 10.3 KiB [emitted] (name: main) - asset a.js 746 bytes [emitted] (name: a) - asset b.js 563 bytes [emitted] (name: b) -assets by path *.png 42 KiB - asset 1.png 21 KiB [emitted] [from: node_modules/a/1.png] (auxiliary name: a) - asset 2.png 21 KiB [emitted] [from: node_modules/a/2.png] (auxiliary name: a, b) -Entrypoint main 10.3 KiB = main.js -Chunk Group a 746 bytes (42 KiB) = a.js 746 bytes (1.png 21 KiB 2.png 21 KiB) -Chunk Group b 563 bytes (21 KiB) = b.js 563 bytes (2.png 21 KiB) -chunk (runtime: main) b.js (b) 67 bytes [rendered] - ./node_modules/a/2.png 49 bytes [dependent] [built] [code generated] [1 asset] - ./node_modules/b/index.js 18 bytes [built] [code generated] -chunk (runtime: main) main.js (main) 82 bytes (javascript) 6.21 KiB (runtime) [entry] [rendered] - runtime modules 6.21 KiB 8 modules - ./index.js 82 bytes [built] [code generated] -chunk (runtime: main) a.js (a) 134 bytes [rendered] - ./node_modules/a/2.png 49 bytes [dependent] [built] [code generated] [1 asset] - ./node_modules/a/index.js + 1 modules 85 bytes [built] [code generated] [1 asset] -runtime modules 6.21 KiB 8 modules -orphan modules 49 bytes [orphan] 1 module -modules with assets 234 bytes - modules by path ./node_modules/a/ 134 bytes - ./node_modules/a/index.js + 1 modules 85 bytes [built] [code generated] [1 asset] - ./node_modules/a/2.png 49 bytes [built] [code generated] [1 asset] - ./index.js 82 bytes [built] [code generated] - ./node_modules/b/index.js 18 bytes [built] [code generated] -webpack x.x.x compiled successfully in X ms" -`; - -exports[`StatsTestCases should print correct stats for module-deduplication 1`] = ` -"asset e1.js 12.1 KiB [emitted] (name: e1) -asset e2.js 12.1 KiB [emitted] (name: e2) -asset e3.js 12.1 KiB [emitted] (name: e3) -asset 172.js 866 bytes [emitted] -asset 326.js 866 bytes [emitted] -asset 923.js 866 bytes [emitted] -asset 114.js 518 bytes [emitted] -asset 593.js 518 bytes [emitted] -asset 716.js 518 bytes [emitted] -chunk (runtime: e1) 114.js 61 bytes [rendered] - ./async1.js 61 bytes [built] [code generated] -chunk (runtime: e3) e3.js (e3) 249 bytes (javascript) 6.49 KiB (runtime) [entry] [rendered] - runtime modules 6.49 KiB 9 modules - cacheable modules 249 bytes - ./b.js 20 bytes [dependent] [built] [code generated] - ./e3.js + 2 modules 209 bytes [built] [code generated] - ./h.js 20 bytes [dependent] [built] [code generated] -chunk (runtime: e1, e3) 172.js 81 bytes [rendered] - ./async2.js 61 bytes [built] [code generated] - ./f.js 20 bytes [dependent] [built] [code generated] -chunk (runtime: e1) e1.js (e1) 249 bytes (javascript) 6.49 KiB (runtime) [entry] [rendered] - runtime modules 6.49 KiB 9 modules - cacheable modules 249 bytes - ./b.js 20 bytes [dependent] [built] [code generated] - ./d.js 20 bytes [dependent] [built] [code generated] - ./e1.js + 2 modules 209 bytes [built] [code generated] -chunk (runtime: e1, e2) 326.js 81 bytes [rendered] - ./async3.js 61 bytes [built] [code generated] - ./h.js 20 bytes [dependent] [built] [code generated] -chunk (runtime: e3) 593.js 61 bytes [rendered] - ./async3.js 61 bytes [built] [code generated] -chunk (runtime: e2) e2.js (e2) 249 bytes (javascript) 6.49 KiB (runtime) [entry] [rendered] - runtime modules 6.49 KiB 9 modules - cacheable modules 249 bytes - ./b.js 20 bytes [dependent] [built] [code generated] - ./e2.js + 2 modules 209 bytes [built] [code generated] - ./f.js 20 bytes [dependent] [built] [code generated] -chunk (runtime: e2) 716.js 61 bytes [rendered] - ./async2.js 61 bytes [built] [code generated] -chunk (runtime: e2, e3) 923.js 81 bytes [rendered] - ./async1.js 61 bytes [built] [code generated] - ./d.js 20 bytes [dependent] [built] [code generated] -webpack x.x.x compiled successfully" -`; - -exports[`StatsTestCases should print correct stats for module-deduplication-named 1`] = ` -"asset e1.js 11.9 KiB [emitted] (name: e1) -asset e2.js 11.9 KiB [emitted] (name: e2) -asset e3.js 11.9 KiB [emitted] (name: e3) -asset async1.js 972 bytes [emitted] (name: async1) -asset async2.js 972 bytes [emitted] (name: async2) -asset async3.js 972 bytes [emitted] (name: async3) -chunk (runtime: e3) e3.js (e3) 242 bytes (javascript) 6.54 KiB (runtime) [entry] [rendered] - runtime modules 6.54 KiB 9 modules - cacheable modules 242 bytes - ./b.js 20 bytes [dependent] [built] [code generated] - ./e3.js + 2 modules 202 bytes [built] [code generated] - ./h.js 20 bytes [dependent] [built] [code generated] -chunk (runtime: e1) e1.js (e1) 242 bytes (javascript) 6.54 KiB (runtime) [entry] [rendered] - runtime modules 6.54 KiB 9 modules - cacheable modules 242 bytes - ./b.js 20 bytes [dependent] [built] [code generated] - ./d.js 20 bytes [dependent] [built] [code generated] - ./e1.js + 2 modules 202 bytes [built] [code generated] -chunk (runtime: e1, e2, e3) async1.js (async1) 135 bytes [rendered] - ./async1.js 115 bytes [built] [code generated] - ./d.js 20 bytes [dependent] [built] [code generated] -chunk (runtime: e1, e2, e3) async3.js (async3) 135 bytes [rendered] - ./async3.js 115 bytes [built] [code generated] - ./h.js 20 bytes [dependent] [built] [code generated] -chunk (runtime: e2) e2.js (e2) 242 bytes (javascript) 6.54 KiB (runtime) [entry] [rendered] - runtime modules 6.54 KiB 9 modules - cacheable modules 242 bytes - ./b.js 20 bytes [dependent] [built] [code generated] - ./e2.js + 2 modules 202 bytes [built] [code generated] - ./f.js 20 bytes [dependent] [built] [code generated] -chunk (runtime: e1, e2, e3) async2.js (async2) 135 bytes [rendered] - ./async2.js 115 bytes [built] [code generated] - ./f.js 20 bytes [dependent] [built] [code generated] -webpack x.x.x compiled successfully" -`; - -exports[`StatsTestCases should print correct stats for module-federation-custom-exposed-module-name 1`] = ` -"asset container_bundle.js 11.8 KiB [emitted] (name: container) -asset custom-entry_bundle.js 414 bytes [emitted] (name: custom-entry) -asset main_bundle.js 84 bytes [emitted] (name: main) -runtime modules 6.5 KiB 9 modules -built modules 82 bytes [built] - ./index.js 1 bytes [built] [code generated] - container entry 42 bytes [built] [code generated] - ./entry.js 39 bytes [built] [code generated] -webpack x.x.x compiled successfully in X ms" -`; - -exports[`StatsTestCases should print correct stats for module-not-found-error 1`] = ` -"ERROR in ./index.js 1:0-17 -Module not found: Error: Can't resolve 'buffer' in 'Xdir/module-not-found-error' - -BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default. -This is no longer the case. Verify if you need this module and configure a polyfill for it. - -If you want to include a polyfill, you need to: - - add a fallback 'resolve.fallback: { \\"buffer\\": require.resolve(\\"buffer/\\") }' - - install 'buffer' -If you don't want to include a polyfill, you can use an empty module like this: - resolve.fallback: { \\"buffer\\": false } - -ERROR in ./index.js 2:0-13 -Module not found: Error: Can't resolve 'os' in 'Xdir/module-not-found-error' - -BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default. -This is no longer the case. Verify if you need this module and configure a polyfill for it. - -If you want to include a polyfill, you need to: - - add a fallback 'resolve.fallback: { \\"os\\": require.resolve(\\"os-browserify/browser\\") }' - - install 'os-browserify' -If you don't want to include a polyfill, you can use an empty module like this: - resolve.fallback: { \\"os\\": false } - -webpack compiled with 2 errors" -`; - -exports[`StatsTestCases should print correct stats for module-reasons 1`] = ` -"asset main.js 1.47 KiB [emitted] (name: main) -orphan modules 75 bytes [orphan] 2 modules -cacheable modules 110 bytes - ./index.js + 2 modules 102 bytes [built] [code generated] - entry ./index main - ./c.js 8 bytes [built] [code generated] - cjs require ./c ./index.js + 2 modules ./a.js 1:0-14 - cjs require ./c ./index.js + 2 modules ./b.js 1:0-14 -webpack x.x.x compiled successfully in X ms" -`; - -exports[`StatsTestCases should print correct stats for module-trace-disabled-in-error 1`] = ` -"assets by status 2 KiB [cached] 1 asset -./index.js 19 bytes [built] [code generated] -./inner.js 53 bytes [built] [code generated] -./not-existing.js 26 bytes [built] [code generated] -./parse-error.js 27 bytes [built] [code generated] [1 error] - -ERROR in ./not-existing.js 1:0-25 -Module not found: Error: Can't resolve 'does-not-exist' in 'Xdir/module-trace-disabled-in-error' - -ERROR in ./parse-error.js 3:4 -Module parse failed: Unexpected token (3:4) -You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders -| Here -| could -> be :) -| your -| code - -webpack x.x.x compiled with 2 errors in X ms" -`; - -exports[`StatsTestCases should print correct stats for module-trace-enabled-in-error 1`] = ` -"assets by status 2 KiB [cached] 1 asset -./index.js 19 bytes [built] [code generated] -./inner.js 53 bytes [built] [code generated] -./not-existing.js 26 bytes [built] [code generated] -./parse-error.js 27 bytes [built] [code generated] [1 error] - -ERROR in ./not-existing.js 1:0-25 -Module not found: Error: Can't resolve 'does-not-exist' in 'Xdir/module-trace-enabled-in-error' - @ ./inner.js 1:0-25 - @ ./index.js 1:0-18 - -ERROR in ./parse-error.js 3:4 -Module parse failed: Unexpected token (3:4) -You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders -| Here -| could -> be :) -| your -| code - @ ./inner.js 2:0-24 - @ ./index.js 1:0-18 - -webpack x.x.x compiled with 2 errors in X ms" -`; - -exports[`StatsTestCases should print correct stats for named-chunk-groups 1`] = ` -"Chunk Group main 11.6 KiB = a-main.js -Chunk Group async-a 1.07 KiB = a-52.js 257 bytes a-async-a.js 836 bytes -Chunk Group async-b 1.07 KiB = a-52.js 257 bytes a-async-b.js 836 bytes -Chunk Group async-c 1.46 KiB = a-vendors.js 758 bytes a-async-c.js 735 bytes -chunk (runtime: main) a-52.js 149 bytes [rendered] split chunk (cache group: default) - > ./a ./index.js 1:0-47 - > ./b ./index.js 2:0-47 - ./shared.js 149 bytes [built] [code generated] -chunk (runtime: main) a-main.js (main) 146 bytes (javascript) 6.83 KiB (runtime) [entry] [rendered] - > ./ main - runtime modules 6.83 KiB 10 modules - ./index.js 146 bytes [built] [code generated] -chunk (runtime: main) a-vendors.js (vendors) (id hint: vendors) 40 bytes [rendered] split chunk (cache group: vendors) (name: vendors) - > ./c ./index.js 3:0-47 - ./node_modules/x.js 20 bytes [built] [code generated] - ./node_modules/y.js 20 bytes [built] [code generated] -chunk (runtime: main) a-async-b.js (async-b) 175 bytes [rendered] - > ./b ./index.js 2:0-47 - ./b.js 175 bytes [built] [code generated] -chunk (runtime: main) a-async-c.js (async-c) 67 bytes [rendered] - > ./c ./index.js 3:0-47 - ./c.js 67 bytes [built] [code generated] -chunk (runtime: main) a-async-a.js (async-a) 175 bytes [rendered] - > ./a ./index.js 1:0-47 - ./a.js 175 bytes [built] [code generated] -webpack x.x.x compiled successfully - -Entrypoint main 11.6 KiB = b-main.js -Chunk Group async-a 1.07 KiB = b-52.js 257 bytes b-async-a.js 836 bytes -Chunk Group async-b 1.07 KiB = b-52.js 257 bytes b-async-b.js 836 bytes -Chunk Group async-c 1.46 KiB = b-vendors.js 758 bytes b-async-c.js 735 bytes -chunk (runtime: main) b-52.js 149 bytes [rendered] split chunk (cache group: default) - > ./a ./index.js 1:0-47 - > ./b ./index.js 2:0-47 - ./shared.js 149 bytes [built] [code generated] -chunk (runtime: main) b-main.js (main) 146 bytes (javascript) 6.83 KiB (runtime) [entry] [rendered] - > ./ main - runtime modules 6.83 KiB 10 modules - ./index.js 146 bytes [built] [code generated] -chunk (runtime: main) b-vendors.js (vendors) (id hint: vendors) 40 bytes [rendered] split chunk (cache group: vendors) (name: vendors) - > ./c ./index.js 3:0-47 - ./node_modules/x.js 20 bytes [built] [code generated] - ./node_modules/y.js 20 bytes [built] [code generated] -chunk (runtime: main) b-async-b.js (async-b) 175 bytes [rendered] - > ./b ./index.js 2:0-47 - ./b.js 175 bytes [built] [code generated] -chunk (runtime: main) b-async-c.js (async-c) 67 bytes [rendered] - > ./c ./index.js 3:0-47 - ./c.js 67 bytes [built] [code generated] -chunk (runtime: main) b-async-a.js (async-a) 175 bytes [rendered] - > ./a ./index.js 1:0-47 - ./a.js 175 bytes [built] [code generated] -webpack x.x.x compiled successfully" -`; - -exports[`StatsTestCases should print correct stats for named-chunks-plugin 1`] = ` -"asset entry.js 5.42 KiB [emitted] (name: entry) -asset vendor.js 237 bytes [emitted] (name: vendor) (id hint: vendor) -Entrypoint entry 5.65 KiB = vendor.js 237 bytes entry.js 5.42 KiB -runtime modules 2.34 KiB 3 modules -cacheable modules 138 bytes - ./entry.js 72 bytes [built] [code generated] - ./modules/a.js 22 bytes [built] [code generated] - ./modules/b.js 22 bytes [built] [code generated] - ./modules/c.js 22 bytes [built] [code generated] -webpack x.x.x compiled successfully in X ms" -`; - -exports[`StatsTestCases should print correct stats for named-chunks-plugin-async 1`] = ` -"asset entry.js 12.3 KiB [emitted] (name: entry) -asset modules_a_js.js 313 bytes [emitted] -asset modules_b_js.js 149 bytes [emitted] -runtime modules 7.61 KiB 10 modules -cacheable modules 106 bytes - ./entry.js 47 bytes [built] [code generated] - ./modules/a.js 37 bytes [built] [code generated] - ./modules/b.js 22 bytes [built] [code generated] -webpack x.x.x compiled successfully in X ms" -`; - -exports[`StatsTestCases should print correct stats for no-emit-on-errors-plugin-with-child-error 1`] = ` -"assets by status 168 bytes [cached] 2 assets -./index.js 1 bytes [built] [code generated] - -WARNING in configuration -The 'mode' option has not been set, webpack will fallback to 'production' for this value. -Set 'mode' option to 'development' or 'production' to enable defaults for each environment. -You can also set it to 'none' to disable any default behavior. Learn more: https://webpack.js.org/configuration/mode/ - -1 ERROR in child compilations (Use 'stats.children: true' resp. '--stats-children' for more details) -webpack x.x.x compiled with 1 error and 1 warning in X ms" -`; - -exports[`StatsTestCases should print correct stats for optimize-chunks 1`] = ` -"asset main.js 10.9 KiB {179} [emitted] (name: main) -asset cir2 from cir1.js 374 bytes {288}, {289} [emitted] (name: cir2 from cir1) -asset cir1.js 330 bytes {592} [emitted] (name: cir1) -asset cir2.js 330 bytes {289} [emitted] (name: cir2) -asset abd.js 193 bytes {90}, {374} [emitted] (name: abd) -asset chunk.js 154 bytes {284}, {753} [emitted] (name: chunk) -asset ab.js 149 bytes {90} [emitted] (name: ab) -asset ac in ab.js 110 bytes {753} [emitted] (name: ac in ab) -chunk {90} (runtime: main) ab.js (ab) 2 bytes <{179}> >{753}< [rendered] - > [10] ./index.js 1:0-6:8 - ./modules/a.js [839] 1 bytes {90} {374} [built] [code generated] - ./modules/b.js [836] 1 bytes {90} {374} [built] [code generated] -chunk {179} (runtime: main) main.js (main) 524 bytes (javascript) 6.03 KiB (runtime) >{90}< >{289}< >{374}< >{592}< [entry] [rendered] - > ./index main - runtime modules 6.03 KiB 7 modules - cacheable modules 524 bytes - ./index.js [10] 523 bytes {179} [built] [code generated] - ./modules/f.js [544] 1 bytes {179} [dependent] [built] [code generated] -chunk {284} (runtime: main) chunk.js (chunk) 2 bytes <{374}> <{753}> [rendered] - > [10] ./index.js 3:2-4:13 - > [10] ./index.js 9:1-10:12 - ./modules/c.js [115] 1 bytes {284} {753} [built] [code generated] - ./modules/d.js [928] 1 bytes {284} {374} [built] [code generated] -chunk {288} (runtime: main) cir2 from cir1.js (cir2 from cir1) 82 bytes <{592}> >{592}< [rendered] - > [655] ./circular1.js 1:0-79 - ./circular2.js [193] 81 bytes {288} {289} [built] [code generated] - ./modules/e.js [798] 1 bytes {288} [built] [code generated] -chunk {289} (runtime: main) cir2.js (cir2) 81 bytes <{179}> >{592}< [rendered] - > [10] ./index.js 14:0-54 - ./circular2.js [193] 81 bytes {288} {289} [built] [code generated] -chunk {374} (runtime: main) abd.js (abd) 3 bytes <{179}> >{284}< [rendered] - > [10] ./index.js 8:0-11:9 - ./modules/a.js [839] 1 bytes {90} {374} [built] [code generated] - ./modules/b.js [836] 1 bytes {90} {374} [built] [code generated] - ./modules/d.js [928] 1 bytes {284} {374} [built] [code generated] -chunk {592} (runtime: main) cir1.js (cir1) 81 bytes <{179}> <{288}> <{289}> >{288}< [rendered] - > [10] ./index.js 13:0-54 - > [193] ./circular2.js 1:0-79 - ./circular1.js [655] 81 bytes {592} [built] [code generated] -chunk {753} (runtime: main) ac in ab.js (ac in ab) 1 bytes <{90}> >{284}< [rendered] - > [10] ./index.js 2:1-5:15 - ./modules/c.js [115] 1 bytes {284} {753} [built] [code generated] -webpack x.x.x compiled successfully in X ms" -`; - -exports[`StatsTestCases should print correct stats for output-module 1`] = ` -"asset main.js 9.94 KiB [emitted] [javascript module] (name: main) -asset 52.js 417 bytes [emitted] [javascript module] -runtime modules 5.99 KiB 8 modules -orphan modules 38 bytes [orphan] 1 module -cacheable modules 263 bytes - ./index.js + 1 modules 225 bytes [built] [code generated] - ./chunk.js 38 bytes [built] [code generated] -webpack x.x.x compiled successfully in X ms" -`; - -exports[`StatsTestCases should print correct stats for parse-error 1`] = ` -"assets by status 1.67 KiB [cached] 1 asset -orphan modules 15 bytes [orphan] 1 module -./index.js + 1 modules 30 bytes [built] [code generated] -./b.js 55 bytes [built] [code generated] [1 error] - -ERROR in ./b.js 6:7 -Module parse failed: Unexpected token (6:7) -You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders -| includes -| a -> parser ) -| error -| in - @ ./a.js 2:0-13 - @ ./index.js 2:0-13 - -webpack x.x.x compiled with 1 error" -`; - -exports[`StatsTestCases should print correct stats for performance-different-mode-and-target 1`] = ` -"asset warning.pro-web.js 294 KiB [emitted] [big] (name: main) -./index.js 293 KiB [built] [code generated] - -WARNING in asset size limit: The following asset(s) exceed the recommended size limit (244 KiB). -This can impact web performance. -Assets: - warning.pro-web.js (294 KiB) - -WARNING in entrypoint size limit: The following entrypoint(s) combined asset size exceeds the recommended limit (244 KiB). This can impact web performance. -Entrypoints: - main (294 KiB) - warning.pro-web.js - -WARNING in webpack performance recommendations: -You can limit the size of your bundles by using import() or require.ensure to lazy load some parts of your application. -For more info visit https://webpack.js.org/guides/code-splitting/ - -webpack x.x.x compiled with 3 warnings in X ms - -asset warning.pro-webworker.js 294 KiB [emitted] [big] (name: main) -./index.js 293 KiB [built] [code generated] - -WARNING in asset size limit: The following asset(s) exceed the recommended size limit (244 KiB). -This can impact web performance. -Assets: - warning.pro-webworker.js (294 KiB) - -WARNING in entrypoint size limit: The following entrypoint(s) combined asset size exceeds the recommended limit (244 KiB). This can impact web performance. -Entrypoints: - main (294 KiB) - warning.pro-webworker.js - -WARNING in webpack performance recommendations: -You can limit the size of your bundles by using import() or require.ensure to lazy load some parts of your application. -For more info visit https://webpack.js.org/guides/code-splitting/ - -webpack x.x.x compiled with 3 warnings in X ms - -asset no-warning.pro-node.js 294 KiB [emitted] (name: main) -./index.js 293 KiB [built] [code generated] -webpack x.x.x compiled successfully in X ms - -asset no-warning.dev-web.js 1.72 MiB [emitted] (name: main) -./index.js 293 KiB [built] [code generated] -webpack x.x.x compiled successfully in X ms - -asset no-warning.dev-node.js 1.72 MiB [emitted] (name: main) -./index.js 293 KiB [built] [code generated] -webpack x.x.x compiled successfully in X ms - -asset no-warning.dev-web-with-limit-set.js 1.72 MiB [emitted] [big] (name: main) -./index.js 293 KiB [built] [code generated] -webpack x.x.x compiled successfully in X ms - -asset warning.pro-node-with-hints-set.js 294 KiB [emitted] [big] (name: main) -./index.js 293 KiB [built] [code generated] - -WARNING in asset size limit: The following asset(s) exceed the recommended size limit (244 KiB). -This can impact web performance. -Assets: - warning.pro-node-with-hints-set.js (294 KiB) - -WARNING in entrypoint size limit: The following entrypoint(s) combined asset size exceeds the recommended limit (244 KiB). This can impact web performance. -Entrypoints: - main (294 KiB) - warning.pro-node-with-hints-set.js - -WARNING in webpack performance recommendations: -You can limit the size of your bundles by using import() or require.ensure to lazy load some parts of your application. -For more info visit https://webpack.js.org/guides/code-splitting/ - -webpack x.x.x compiled with 3 warnings in X ms" -`; - -exports[`StatsTestCases should print correct stats for performance-disabled 1`] = ` -"asset main.js 303 KiB [emitted] (name: main) -asset 460.js 320 bytes [emitted] -asset 524.js 206 bytes [emitted] -asset 996.js 138 bytes [emitted] -Entrypoint main 303 KiB = main.js -runtime modules 5.92 KiB 7 modules -cacheable modules 293 KiB - ./index.js 52 bytes [built] [code generated] - ./a.js 293 KiB [built] [code generated] - ./b.js 22 bytes [built] [code generated] - ./c.js 54 bytes [built] [code generated] - ./d.js 22 bytes [built] [code generated] - ./e.js 22 bytes [built] [code generated] -webpack x.x.x compiled successfully in X ms" -`; - -exports[`StatsTestCases should print correct stats for performance-error 1`] = ` -"asset main.js 303 KiB [emitted] [big] (name: main) -asset 460.js 320 bytes [emitted] -asset 524.js 206 bytes [emitted] -asset 996.js 138 bytes [emitted] -Entrypoint main [big] 303 KiB = main.js -runtime modules 5.92 KiB 7 modules -cacheable modules 293 KiB - ./index.js 52 bytes [built] [code generated] - ./a.js 293 KiB [built] [code generated] - ./b.js 22 bytes [built] [code generated] - ./c.js 54 bytes [built] [code generated] - ./d.js 22 bytes [built] [code generated] - ./e.js 22 bytes [built] [code generated] - -ERROR in asset size limit: The following asset(s) exceed the recommended size limit (244 KiB). -This can impact web performance. -Assets: - main.js (303 KiB) - -ERROR in entrypoint size limit: The following entrypoint(s) combined asset size exceeds the recommended limit (244 KiB). This can impact web performance. -Entrypoints: - main (303 KiB) - main.js - - -webpack x.x.x compiled with 2 errors in X ms" -`; - -exports[`StatsTestCases should print correct stats for performance-no-async-chunks-shown 1`] = ` -"asset main.js 294 KiB [emitted] [big] (name: main) -asset sec.js 1.53 KiB [emitted] (name: sec) -Entrypoint main [big] 294 KiB = main.js -Entrypoint sec 1.53 KiB = sec.js -./index.js 32 bytes [built] [code generated] -./index2.js 48 bytes [built] [code generated] -./a.js 293 KiB [built] [code generated] -./b.js 22 bytes [built] [code generated] -./c.js 22 bytes [built] [code generated] -./d.js 22 bytes [built] [code generated] - -WARNING in asset size limit: The following asset(s) exceed the recommended size limit (244 KiB). -This can impact web performance. -Assets: - main.js (294 KiB) - -WARNING in entrypoint size limit: The following entrypoint(s) combined asset size exceeds the recommended limit (244 KiB). This can impact web performance. -Entrypoints: - main (294 KiB) - main.js - - -WARNING in webpack performance recommendations: -You can limit the size of your bundles by using import() or require.ensure to lazy load some parts of your application. -For more info visit https://webpack.js.org/guides/code-splitting/ - -webpack x.x.x compiled with 3 warnings in X ms" -`; - -exports[`StatsTestCases should print correct stats for performance-no-hints 1`] = ` -"asset main.js 303 KiB [emitted] [big] (name: main) -asset 460.js 320 bytes [emitted] -asset 524.js 206 bytes [emitted] -asset 996.js 138 bytes [emitted] -Entrypoint main [big] 303 KiB = main.js -runtime modules 5.92 KiB 7 modules -cacheable modules 293 KiB - ./index.js 52 bytes [built] [code generated] - ./a.js 293 KiB [built] [code generated] - ./b.js 22 bytes [built] [code generated] - ./c.js 54 bytes [built] [code generated] - ./d.js 22 bytes [built] [code generated] - ./e.js 22 bytes [built] [code generated] -webpack x.x.x compiled successfully in X ms" -`; - -exports[`StatsTestCases should print correct stats for performance-oversize-limit-error 1`] = ` -"asset main.js 294 KiB [emitted] [big] (name: main) -asset sec.js 294 KiB [emitted] [big] (name: sec) -Entrypoint main [big] 294 KiB = main.js -Entrypoint sec [big] 294 KiB = sec.js -./index.js 16 bytes [built] [code generated] -./index2.js 16 bytes [built] [code generated] -./a.js 293 KiB [built] [code generated] - -ERROR in asset size limit: The following asset(s) exceed the recommended size limit (244 KiB). -This can impact web performance. -Assets: - main.js (294 KiB) - sec.js (294 KiB) - -ERROR in entrypoint size limit: The following entrypoint(s) combined asset size exceeds the recommended limit (244 KiB). This can impact web performance. -Entrypoints: - main (294 KiB) - main.js - sec (294 KiB) - sec.js - - -ERROR in webpack performance recommendations: -You can limit the size of your bundles by using import() or require.ensure to lazy load some parts of your application. -For more info visit https://webpack.js.org/guides/code-splitting/ - -webpack x.x.x compiled with 3 errors in X ms" -`; - -exports[`StatsTestCases should print correct stats for prefetch 1`] = ` -"asset main.js 16.6 KiB {179} [emitted] (name: main) -asset prefetched.js 556 bytes {505} [emitted] (name: prefetched) -asset inner2.js 150 bytes {641} [emitted] (name: inner2) -asset inner.js 110 bytes {746} [emitted] (name: inner) -asset prefetched2.js 110 bytes {379} [emitted] (name: prefetched2) -asset prefetched3.js 110 bytes {220} [emitted] (name: prefetched3) -asset normal.js 109 bytes {30} [emitted] (name: normal) -Entrypoint main 16.6 KiB = main.js - prefetch: prefetched2.js {379} (name: prefetched2), prefetched.js {505} (name: prefetched), prefetched3.js {220} (name: prefetched3) -chunk {30} (runtime: main) normal.js (normal) 1 bytes <{179}> [rendered] -chunk {179} (runtime: main) main.js (main) 436 bytes (javascript) 9.82 KiB (runtime) >{30}< >{220}< >{379}< >{505}< (prefetch: {379} {505} {220}) [entry] [rendered] -chunk {220} (runtime: main) prefetched3.js (prefetched3) 1 bytes <{179}> [rendered] -chunk {379} (runtime: main) prefetched2.js (prefetched2) 1 bytes <{179}> [rendered] -chunk {505} (runtime: main) prefetched.js (prefetched) 228 bytes <{179}> >{641}< >{746}< (prefetch: {641} {746}) [rendered] -chunk {641} (runtime: main) inner2.js (inner2) 2 bytes <{505}> [rendered] -chunk {746} (runtime: main) inner.js (inner) 1 bytes <{505}> [rendered]" -`; - -exports[`StatsTestCases should print correct stats for prefetch-preload-mixed 1`] = ` -"chunk (runtime: main) c2.js (c2) 1 bytes <{459}> [rendered] -chunk (runtime: main) a1.js (a1) 1 bytes <{786}> [rendered] -chunk (runtime: main) c1.js (c1) 1 bytes <{459}> [rendered] -chunk (runtime: main) b.js (b) 203 bytes <{179}> >{132}< >{751}< >{978}< (prefetch: {751} {132}) (preload: {978}) [rendered] -chunk (runtime: main) b3.js (b3) 1 bytes <{128}> [rendered] -chunk (runtime: main) a2.js (a2) 1 bytes <{786}> [rendered] -chunk (runtime: main) main.js (main) 195 bytes (javascript) 10.4 KiB (runtime) >{128}< >{459}< >{786}< (prefetch: {786} {128} {459}) [entry] [rendered] -chunk (runtime: main) c.js (c) 134 bytes <{179}> >{3}< >{76}< (preload: {76} {3}) [rendered] -chunk (runtime: main) b1.js (b1) 1 bytes <{128}> [rendered] -chunk (runtime: main) a.js (a) 136 bytes <{179}> >{74}< >{178}< (prefetch: {74} {178}) [rendered] -chunk (runtime: main) b2.js (b2) 1 bytes <{128}> [rendered]" -`; - -exports[`StatsTestCases should print correct stats for preload 1`] = ` -"asset main.js 15.1 KiB [emitted] (name: main) -asset preloaded.js 556 bytes [emitted] (name: preloaded) -asset inner2.js 150 bytes [emitted] (name: inner2) -asset inner.js 110 bytes [emitted] (name: inner) -asset normal.js 109 bytes [emitted] (name: normal) -asset preloaded2.js 109 bytes [emitted] (name: preloaded2) -asset preloaded3.js 108 bytes [emitted] (name: preloaded3) -Entrypoint main 15.1 KiB = main.js - preload: preloaded2.js (name: preloaded2), preloaded.js (name: preloaded), preloaded3.js (name: preloaded3) -chunk (runtime: main) normal.js (normal) 1 bytes [rendered] -chunk (runtime: main) main.js (main) 424 bytes (javascript) 8.81 KiB (runtime) (preload: {363} {851} {355}) [entry] [rendered] -chunk (runtime: main) preloaded3.js (preloaded3) 1 bytes [rendered] -chunk (runtime: main) preloaded2.js (preloaded2) 1 bytes [rendered] -chunk (runtime: main) inner2.js (inner2) 2 bytes [rendered] -chunk (runtime: main) inner.js (inner) 1 bytes [rendered] -chunk (runtime: main) preloaded.js (preloaded) 226 bytes (preload: {641} {746}) [rendered]" -`; - -exports[`StatsTestCases should print correct stats for preset-detailed 1`] = ` -"<-> [LogTestPlugin] Group - [LogTestPlugin] Error - [LogTestPlugin] Warning - [LogTestPlugin] Info - [LogTestPlugin] Log - <+> [LogTestPlugin] Collaped group - [LogTestPlugin] Log - [LogTestPlugin] End -PublicPath: auto -asset main.js 10.1 KiB {179} [emitted] (name: main) -asset 460.js 320 bytes {460} [emitted] -asset 524.js 206 bytes {524} [emitted] -asset 996.js 138 bytes {996} [emitted] -Entrypoint main 10.1 KiB = main.js -chunk {179} (runtime: main) main.js (main) 73 bytes (javascript) 5.92 KiB (runtime) >{460}< >{996}< [entry] [rendered] - > ./index main -chunk {460} (runtime: main) 460.js 54 bytes <{179}> >{524}< [rendered] - > ./c [10] ./index.js 3:0-16 -chunk {524} (runtime: main) 524.js 44 bytes <{460}> [rendered] - > [460] ./c.js 1:0-52 -chunk {996} (runtime: main) 996.js 22 bytes <{179}> [rendered] - > ./b [10] ./index.js 2:0-16 -runtime modules 5.92 KiB - webpack/runtime/ensure chunk 326 bytes {179} [code generated] - [no exports] - [used exports unknown] - webpack/runtime/get javascript chunk filename 167 bytes {179} [code generated] - [no exports] - [used exports unknown] - webpack/runtime/global 221 bytes {179} [code generated] - [no exports] - [used exports unknown] - webpack/runtime/hasOwnProperty shorthand 88 bytes {179} [code generated] - [no exports] - [used exports unknown] - webpack/runtime/jsonp chunk loading 2.93 KiB {179} [code generated] - [no exports] - [used exports unknown] - webpack/runtime/load script 1.37 KiB {179} [code generated] - [no exports] - [used exports unknown] - webpack/runtime/publicPath 867 bytes {179} [code generated] - [no exports] - [used exports unknown] -cacheable modules 193 bytes - ./index.js [10] 51 bytes {179} [depth 0] [built] [code generated] - [no exports used] - Statement (ExpressionStatement) with side effects in source code at 1:0-15 - ModuleConcatenation bailout: Module is not an ECMAScript module - ./a.js [847] 22 bytes {179} [depth 1] [built] [code generated] - [used exports unknown] - CommonJS bailout: module.exports is used directly at 1:0-14 - Statement (ExpressionStatement) with side effects in source code at 1:0-21 - ModuleConcatenation bailout: Module is not an ECMAScript module - ./b.js [996] 22 bytes {996} [depth 1] [built] [code generated] - [used exports unknown] - CommonJS bailout: module.exports is used directly at 1:0-14 - Statement (ExpressionStatement) with side effects in source code at 1:0-21 - ModuleConcatenation bailout: Module is not an ECMAScript module - ./c.js [460] 54 bytes {460} [depth 1] [built] [code generated] - [used exports unknown] - Statement (ExpressionStatement) with side effects in source code at 1:0-53 - ModuleConcatenation bailout: Module is not an ECMAScript module - ./d.js [767] 22 bytes {524} [depth 2] [built] [code generated] - [used exports unknown] - CommonJS bailout: module.exports is used directly at 1:0-14 - Statement (ExpressionStatement) with side effects in source code at 1:0-21 - ModuleConcatenation bailout: Module is not an ECMAScript module - ./e.js [390] 22 bytes {524} [depth 2] [built] [code generated] - [used exports unknown] - CommonJS bailout: module.exports is used directly at 1:0-14 - Statement (ExpressionStatement) with side effects in source code at 1:0-21 - ModuleConcatenation bailout: Module is not an ECMAScript module - -LOG from LogTestPlugin -<-> Group - Error - Warning - Info - Log - <+> Collaped group - Log - End -+ 6 hidden lines - -LOG from webpack.FlagDependencyExportsPlugin - 100% of exports of modules have been determined (6 not cached, 0 flagged uncacheable, 0 from cache, 0 additional calculations due to dependencies) -+ 3 hidden lines - -LOG from webpack.Compilation - 6 modules hashed (1 variants per module in average) - 100% code generated (6 generated, 0 from cache) - 100% code generated (7 generated, 0 from cache) -+ 19 hidden lines - -LOG from webpack.buildChunkGraph - 15 queue items processed (9 blocks) - 3 chunk groups connected - 3 chunk groups processed for merging (3 module sets, 0 forked, 0 + 0 modules forked, 0 + 0 modules merged into fork, 0 resulting modules) - 3 chunk group info updated (0 already connected chunk groups reconnected) -+ 13 hidden lines - -LOG from webpack.FileSystemInfo - 6 new snapshots created - 0% root snapshot uncached (0 / 0) - 0% children snapshot uncached (0 / 0) - 0 entries tested - File info in cache: 6 timestamps 6 hashes 6 timestamp hash combinations - File timestamp hash combination snapshot optimization: 0% (0/6) entries shared via 0 shared snapshots (0 times referenced) - Directory info in cache: 0 timestamps 0 hashes 0 timestamp hash combinations - Managed items info in cache: 0 items - -1970-04-20 12:42:42: webpack x.x.x compiled successfully in X ms (5ca0f92d29f872af27fe)" -`; - -exports[`StatsTestCases should print correct stats for preset-errors-only 1`] = `""`; - -exports[`StatsTestCases should print correct stats for preset-errors-only-error 1`] = ` -" [LogTestPlugin] Error -LOG from LogTestPlugin - Error -+ 14 hidden lines - -ERROR in ./index.js 1:0-25 -Module not found: Error: Can't resolve 'does-not-exist' in 'Xdir/preset-errors-only-error' - -webpack compiled with 1 error" -`; - -exports[`StatsTestCases should print correct stats for preset-errors-warnings 1`] = ` -" [LogTestPlugin] Error - [LogTestPlugin] Warning -LOG from LogTestPlugin - Error - Warning -+ 13 hidden lines - -webpack compiled successfully" -`; - -exports[`StatsTestCases should print correct stats for preset-minimal 1`] = ` -" [LogTestPlugin] Error - [LogTestPlugin] Warning -4 assets -13 modules - -LOG from LogTestPlugin - Error - Warning -+ 13 hidden lines - -webpack x.x.x compiled successfully in X ms" -`; - -exports[`StatsTestCases should print correct stats for preset-minimal-simple 1`] = ` -"1 asset -1 module -webpack x.x.x compiled successfully in X ms" -`; - -exports[`StatsTestCases should print correct stats for preset-mixed-array 1`] = ` -"minimal: - 1 asset - 1 module - minimal (webpack x.x.x) compiled successfully in X ms - -verbose: - Entrypoint main 92 bytes = verbose.js - ./index.js 8 bytes [built] [code generated] - verbose (webpack x.x.x) compiled successfully" -`; - -exports[`StatsTestCases should print correct stats for preset-none 1`] = ` -" [LogTestPlugin] Error - [LogTestPlugin] Warning - [LogTestPlugin] Info -" -`; - -exports[`StatsTestCases should print correct stats for preset-none-array 1`] = `""`; - -exports[`StatsTestCases should print correct stats for preset-none-error 1`] = `""`; - -exports[`StatsTestCases should print correct stats for preset-normal 1`] = ` -" [LogTestPlugin] Error - [LogTestPlugin] Warning - [LogTestPlugin] Info -asset main.js 10.1 KiB [emitted] (name: main) -asset 460.js 320 bytes [emitted] -asset 524.js 206 bytes [emitted] -asset 996.js 138 bytes [emitted] -runtime modules 5.92 KiB 7 modules -cacheable modules 193 bytes - ./index.js 51 bytes [built] [code generated] - ./a.js 22 bytes [built] [code generated] - ./b.js 22 bytes [built] [code generated] - ./c.js 54 bytes [built] [code generated] - ./d.js 22 bytes [built] [code generated] - ./e.js 22 bytes [built] [code generated] - -LOG from LogTestPlugin - Error - Warning - Info -+ 12 hidden lines - -webpack x.x.x compiled successfully in X ms" -`; - -exports[`StatsTestCases should print correct stats for preset-normal-performance 1`] = ` -"asset main.js 303 KiB [emitted] [big] (name: main) -asset 460.js 320 bytes [emitted] -asset 524.js 206 bytes [emitted] -asset 996.js 138 bytes [emitted] -runtime modules 5.92 KiB 7 modules -cacheable modules 293 KiB - ./index.js 52 bytes [built] [code generated] - ./a.js 293 KiB [built] [code generated] - ./b.js 22 bytes [built] [code generated] - ./c.js 54 bytes [built] [code generated] - ./d.js 22 bytes [built] [code generated] - ./e.js 22 bytes [built] [code generated] - -WARNING in asset size limit: The following asset(s) exceed the recommended size limit (244 KiB). -This can impact web performance. -Assets: - main.js (303 KiB) - -WARNING in entrypoint size limit: The following entrypoint(s) combined asset size exceeds the recommended limit (244 KiB). This can impact web performance. -Entrypoints: - main (303 KiB) - main.js - - -webpack x.x.x compiled with 2 warnings in X ms" -`; - -exports[`StatsTestCases should print correct stats for preset-normal-performance-ensure-filter-sourcemaps 1`] = ` -"asset main.js 303 KiB [emitted] [big] (name: main) 1 related asset -asset 460.js 352 bytes [emitted] 1 related asset -asset 524.js 238 bytes [emitted] 1 related asset -asset 996.js 170 bytes [emitted] 1 related asset -runtime modules 5.92 KiB 7 modules -cacheable modules 293 KiB - ./index.js 52 bytes [built] [code generated] - ./a.js 293 KiB [built] [code generated] - ./b.js 22 bytes [built] [code generated] - ./c.js 54 bytes [built] [code generated] - ./d.js 22 bytes [built] [code generated] - ./e.js 22 bytes [built] [code generated] - -WARNING in asset size limit: The following asset(s) exceed the recommended size limit (244 KiB). -This can impact web performance. -Assets: - main.js (303 KiB) - -WARNING in entrypoint size limit: The following entrypoint(s) combined asset size exceeds the recommended limit (244 KiB). This can impact web performance. -Entrypoints: - main (303 KiB) - main.js - - -webpack x.x.x compiled with 2 warnings in X ms" -`; - -exports[`StatsTestCases should print correct stats for preset-summary 1`] = ` -" [LogTestPlugin] Error - [LogTestPlugin] Warning - [LogTestPlugin] Info -webpack x.x.x compiled successfully" -`; - -exports[`StatsTestCases should print correct stats for preset-verbose 1`] = ` -"<-> [LogTestPlugin] Group - [LogTestPlugin] Error - [LogTestPlugin] Warning - [LogTestPlugin] Info - [LogTestPlugin] Log - <-> [LogTestPlugin] Collaped group - [LogTestPlugin] Log inside collapsed group - <-> [LogTestPlugin] Inner group - [LogTestPlugin] Inner inner message - [LogTestPlugin] Log - [LogTestPlugin] End -PublicPath: auto -asset main.js 10.1 KiB {179} [emitted] (name: main) -asset 460.js 320 bytes {460} [emitted] -asset 524.js 206 bytes {524} [emitted] -asset 996.js 138 bytes {996} [emitted] -Entrypoint main 10.1 KiB = main.js -chunk {179} (runtime: main) main.js (main) 73 bytes (javascript) 5.92 KiB (runtime) >{460}< >{996}< [entry] [rendered] - > ./index main - runtime modules 5.92 KiB - webpack/runtime/ensure chunk 326 bytes {179} [code generated] - [no exports] - [used exports unknown] - webpack/runtime/get javascript chunk filename 167 bytes {179} [code generated] - [no exports] - [used exports unknown] - webpack/runtime/global 221 bytes {179} [code generated] - [no exports] - [used exports unknown] - webpack/runtime/hasOwnProperty shorthand 88 bytes {179} [code generated] - [no exports] - [used exports unknown] - webpack/runtime/jsonp chunk loading 2.93 KiB {179} [code generated] - [no exports] - [used exports unknown] - webpack/runtime/load script 1.37 KiB {179} [code generated] - [no exports] - [used exports unknown] - webpack/runtime/publicPath 867 bytes {179} [code generated] - [no exports] - [used exports unknown] - cacheable modules 73 bytes - ./a.js [847] 22 bytes {179} [depth 1] [dependent] [built] [code generated] - [used exports unknown] - CommonJS bailout: module.exports is used directly at 1:0-14 - Statement (ExpressionStatement) with side effects in source code at 1:0-21 - ModuleConcatenation bailout: Module is not an ECMAScript module - cjs self exports reference [847] ./a.js 1:0-14 - cjs require ./a [10] ./index.js 1:0-14 - X ms [10] -> - X ms (resolving: X ms, restoring: X ms, integration: X ms, building: X ms, storing: X ms) - ./index.js [10] 51 bytes {179} [depth 0] [built] [code generated] - [no exports used] - Statement (ExpressionStatement) with side effects in source code at 1:0-15 - ModuleConcatenation bailout: Module is not an ECMAScript module - entry ./index main - X ms (resolving: X ms, restoring: X ms, integration: X ms, building: X ms, storing: X ms) -chunk {460} (runtime: main) 460.js 54 bytes <{179}> >{524}< [rendered] - > ./c [10] ./index.js 3:0-16 - ./c.js [460] 54 bytes {460} [depth 1] [built] [code generated] - [used exports unknown] - Statement (ExpressionStatement) with side effects in source code at 1:0-53 - ModuleConcatenation bailout: Module is not an ECMAScript module - amd require ./c [10] ./index.js 3:0-16 - X ms [10] -> - X ms (resolving: X ms, restoring: X ms, integration: X ms, building: X ms, storing: X ms) -chunk {524} (runtime: main) 524.js 44 bytes <{460}> [rendered] - > [460] ./c.js 1:0-52 - ./d.js [767] 22 bytes {524} [depth 2] [built] [code generated] - [used exports unknown] - CommonJS bailout: module.exports is used directly at 1:0-14 - Statement (ExpressionStatement) with side effects in source code at 1:0-21 - ModuleConcatenation bailout: Module is not an ECMAScript module - require.ensure item ./d [460] ./c.js 1:0-52 - cjs self exports reference [767] ./d.js 1:0-14 - X ms [10] -> X ms [460] -> - X ms (resolving: X ms, restoring: X ms, integration: X ms, building: X ms, storing: X ms) - ./e.js [390] 22 bytes {524} [depth 2] [built] [code generated] - [used exports unknown] - CommonJS bailout: module.exports is used directly at 1:0-14 - Statement (ExpressionStatement) with side effects in source code at 1:0-21 - ModuleConcatenation bailout: Module is not an ECMAScript module - require.ensure item ./e [460] ./c.js 1:0-52 - cjs self exports reference [390] ./e.js 1:0-14 - X ms [10] -> X ms [460] -> - X ms (resolving: X ms, restoring: X ms, integration: X ms, building: X ms, storing: X ms) -chunk {996} (runtime: main) 996.js 22 bytes <{179}> [rendered] - > ./b [10] ./index.js 2:0-16 - ./b.js [996] 22 bytes {996} [depth 1] [built] [code generated] - [used exports unknown] - CommonJS bailout: module.exports is used directly at 1:0-14 - Statement (ExpressionStatement) with side effects in source code at 1:0-21 - ModuleConcatenation bailout: Module is not an ECMAScript module - cjs self exports reference [996] ./b.js 1:0-14 - amd require ./b [10] ./index.js 2:0-16 - X ms [10] -> - X ms (resolving: X ms, restoring: X ms, integration: X ms, building: X ms, storing: X ms) - - -LOG from LogTestPlugin -<-> Group - Error - Warning - Info - Log - <-> Collaped group - Log inside collapsed group - <-> Inner group - Inner inner message - Log - End -+ 1 hidden lines - -LOG from webpack.Compiler - make hook: X ms - finish make hook: X ms - finish compilation: X ms - seal compilation: X ms - afterCompile hook: X ms - emitAssets: X ms - emitRecords: X ms - done hook: X ms - beginIdle: X ms - -LOG from webpack.Compilation - finish module profiles: X ms - finish modules: X ms - report dependency errors and warnings: X ms - optimize dependencies: X ms - create chunks: X ms - optimize: X ms - 6 modules hashed (1 variants per module in average) - module hashing: X ms - 100% code generated (6 generated, 0 from cache) - code generation: X ms - runtime requirements: X ms - hashing: initialize hash: X ms - hashing: sort chunks: X ms - hashing: hash runtime modules: X ms - hashing: hash chunks: X ms - hashing: hash digest: X ms - hashing: process full hash modules: X ms - hashing: X ms - 100% code generated (7 generated, 0 from cache) - record hash: X ms - module assets: X ms - create chunk assets: X ms - process assets: X ms - -LOG from webpack.FlagDependencyExportsPlugin - restore cached provided exports: X ms - figure out provided exports: X ms - 100% of exports of modules have been determined (6 not cached, 0 flagged uncacheable, 0 from cache, 0 additional calculations due to dependencies) - store provided exports into cache: X ms - -LOG from webpack.InnerGraphPlugin - infer dependency usage: X ms - -LOG from webpack.SideEffectsFlagPlugin - update dependencies: X ms - -LOG from webpack.FlagDependencyUsagePlugin - initialize exports usage: X ms - trace exports usage in graph: X ms - -LOG from webpack.buildChunkGraph - visitModules: prepare: X ms - visitModules: visiting: X ms - visitModules: calculating available modules: X ms - visitModules: merging available modules: X ms - visitModules: check modules for revisit: X ms - visitModules: visiting: X ms - visitModules: calculating available modules: X ms - visitModules: merging available modules: X ms - visitModules: check modules for revisit: X ms - visitModules: visiting: X ms - 15 queue items processed (9 blocks) - 3 chunk groups connected - 3 chunk groups processed for merging (3 module sets, 0 forked, 0 + 0 modules forked, 0 + 0 modules merged into fork, 0 resulting modules) - 3 chunk group info updated (0 already connected chunk groups reconnected) - visitModules: X ms - connectChunkGroups: X ms - cleanup: X ms - -LOG from webpack.SplitChunksPlugin - prepare: X ms - modules: X ms - queue: X ms - maxSize: X ms - -LOG from webpack.ModuleConcatenationPlugin - select relevant modules: X ms - sort relevant modules: X ms - find modules to concatenate: X ms - sort concat configurations: X ms - create concatenated modules: X ms -+ 3 hidden lines - -LOG from webpack.FileSystemInfo - 6 new snapshots created - 0% root snapshot uncached (0 / 0) - 0% children snapshot uncached (0 / 0) - 0 entries tested - File info in cache: 6 timestamps 6 hashes 6 timestamp hash combinations - File timestamp hash combination snapshot optimization: 0% (0/6) entries shared via 0 shared snapshots (0 times referenced) - Directory info in cache: 0 timestamps 0 hashes 0 timestamp hash combinations - Managed items info in cache: 0 items - -1970-04-20 12:42:42: webpack x.x.x compiled successfully in X ms (5ca0f92d29f872af27fe)" -`; - -exports[`StatsTestCases should print correct stats for real-content-hash 1`] = ` -"a-normal: - assets by path *.js 3.21 KiB - asset ed18d22ff50f3233bc67-ed18d2.js 2.69 KiB [emitted] [immutable] [minimized] (name: runtime) - asset a639a9edc4557744bf94-a639a9.js 288 bytes [emitted] [immutable] [minimized] (name: lazy) - asset e00b58ce2785691cd374-e00b58.js 225 bytes [emitted] [immutable] [minimized] (name: index) - asset 666f2b8847021ccc7608-666f2b.js 21 bytes [emitted] [immutable] [minimized] (name: a, b) - assets by chunk 20.4 KiB (auxiliary name: lazy) - asset 89a353e9c515885abd8e.png 14.6 KiB [emitted] [immutable] [from: file.png] (auxiliary name: lazy) - asset 7382fad5b015914e0811.jpg?query 5.89 KiB [cached] [immutable] [from: file.jpg?query] (auxiliary name: lazy) - asset 7382fad5b015914e0811.jpg 5.89 KiB [emitted] [immutable] [from: file.jpg] (auxiliary name: index) - Entrypoint index 2.91 KiB (5.89 KiB) = ed18d22ff50f3233bc67-ed18d2.js 2.69 KiB e00b58ce2785691cd374-e00b58.js 225 bytes 1 auxiliary asset - Entrypoint a 21 bytes = 666f2b8847021ccc7608-666f2b.js - Entrypoint b 21 bytes = 666f2b8847021ccc7608-666f2b.js - runtime modules 7.16 KiB 9 modules - orphan modules 23 bytes [orphan] 1 module - cacheable modules 514 bytes (javascript) 26.3 KiB (asset) - javascript modules 388 bytes - ./a/index.js 150 bytes [built] [code generated] - ./a/a.js 22 bytes [built] [code generated] - ./a/b.js 66 bytes [built] [code generated] - ./a/lazy.js + 1 modules 150 bytes [built] [code generated] - asset modules 126 bytes (javascript) 26.3 KiB (asset) - ./a/file.jpg 42 bytes (javascript) 5.89 KiB (asset) [built] [code generated] - ./a/file.png 42 bytes (javascript) 14.6 KiB (asset) [built] [code generated] - ./a/file.jpg?query 42 bytes (javascript) 5.89 KiB (asset) [built] [code generated] - a-normal (webpack x.x.x) compiled successfully in X ms - -b-normal: - assets by path *.js 3.21 KiB - asset ebd94803ef81e849174e-ebd948.js 2.69 KiB [emitted] [immutable] [minimized] (name: runtime) - asset a639a9edc4557744bf94-a639a9.js 288 bytes [emitted] [immutable] [minimized] (name: lazy) - asset e00b58ce2785691cd374-e00b58.js 225 bytes [emitted] [immutable] [minimized] (name: index) - asset 666f2b8847021ccc7608-666f2b.js 21 bytes [emitted] [immutable] [minimized] (name: a, b) - assets by chunk 20.4 KiB (auxiliary name: lazy) - asset 89a353e9c515885abd8e.png 14.6 KiB [emitted] [immutable] [from: file.png] (auxiliary name: lazy) - asset 7382fad5b015914e0811.jpg?query 5.89 KiB [cached] [immutable] [from: file.jpg?query] (auxiliary name: lazy) - asset 7382fad5b015914e0811.jpg 5.89 KiB [emitted] [immutable] [from: file.jpg] (auxiliary name: index) - Entrypoint index 2.91 KiB (5.89 KiB) = ebd94803ef81e849174e-ebd948.js 2.69 KiB e00b58ce2785691cd374-e00b58.js 225 bytes 1 auxiliary asset - Entrypoint a 21 bytes = 666f2b8847021ccc7608-666f2b.js - Entrypoint b 21 bytes = 666f2b8847021ccc7608-666f2b.js - runtime modules 7.16 KiB 9 modules - orphan modules 19 bytes [orphan] 1 module - cacheable modules 469 bytes (javascript) 26.3 KiB (asset) - javascript modules 343 bytes - ./b/index.js 109 bytes [built] [code generated] - ./b/a.js 22 bytes [built] [code generated] - ./b/b.js 66 bytes [built] [code generated] - ./b/lazy.js + 1 modules 146 bytes [built] [code generated] - asset modules 126 bytes (javascript) 26.3 KiB (asset) - ./b/file.jpg 42 bytes (javascript) 5.89 KiB (asset) [built] [code generated] - ./b/file.png 42 bytes (javascript) 14.6 KiB (asset) [built] [code generated] - ./b/file.jpg?query 42 bytes (javascript) 5.89 KiB (asset) [built] [code generated] - b-normal (webpack x.x.x) compiled successfully in X ms - -a-source-map: - assets by path *.js 3.43 KiB - asset 6d6bdd8cd3e5c9a1c02a-6d6bdd.js 2.75 KiB [emitted] [immutable] [minimized] (name: runtime) - sourceMap 6d6bdd8cd3e5c9a1c02a-6d6bdd.js.map 14.2 KiB [emitted] [dev] (auxiliary name: runtime) - asset 05c637d15dff2d0dc5fd-05c637.js 344 bytes [emitted] [immutable] [minimized] (name: lazy) - sourceMap 05c637d15dff2d0dc5fd-05c637.js.map 399 bytes [emitted] [dev] (auxiliary name: lazy) - asset c41aff3dd03dbe1d8aa3-c41aff.js 281 bytes [emitted] [immutable] [minimized] (name: index) - sourceMap c41aff3dd03dbe1d8aa3-c41aff.js.map 366 bytes [emitted] [dev] (auxiliary name: index) - asset 222c2acc68675174e6b2-222c2a.js 77 bytes [emitted] [immutable] [minimized] (name: a, b) - sourceMap 222c2acc68675174e6b2-222c2a.js.map 254 bytes [emitted] [dev] (auxiliary name: a, b) - assets by chunk 20.4 KiB (auxiliary name: lazy) - asset 89a353e9c515885abd8e.png 14.6 KiB [emitted] [immutable] [from: file.png] (auxiliary name: lazy) - asset 7382fad5b015914e0811.jpg?query 5.89 KiB [cached] [immutable] [from: file.jpg?query] (auxiliary name: lazy) - asset 7382fad5b015914e0811.jpg 5.89 KiB [emitted] [immutable] [from: file.jpg] (auxiliary name: index) - Entrypoint index 3.02 KiB (20.4 KiB) = 6d6bdd8cd3e5c9a1c02a-6d6bdd.js 2.75 KiB c41aff3dd03dbe1d8aa3-c41aff.js 281 bytes 3 auxiliary assets - Entrypoint a 77 bytes (254 bytes) = 222c2acc68675174e6b2-222c2a.js 1 auxiliary asset - Entrypoint b 77 bytes (254 bytes) = 222c2acc68675174e6b2-222c2a.js 1 auxiliary asset - runtime modules 7.16 KiB 9 modules - orphan modules 23 bytes [orphan] 1 module - cacheable modules 514 bytes (javascript) 26.3 KiB (asset) - javascript modules 388 bytes - ./a/index.js 150 bytes [built] [code generated] - ./a/a.js 22 bytes [built] [code generated] - ./a/b.js 66 bytes [built] [code generated] - ./a/lazy.js + 1 modules 150 bytes [built] [code generated] - asset modules 126 bytes (javascript) 26.3 KiB (asset) - ./a/file.jpg 42 bytes (javascript) 5.89 KiB (asset) [built] [code generated] - ./a/file.png 42 bytes (javascript) 14.6 KiB (asset) [built] [code generated] - ./a/file.jpg?query 42 bytes (javascript) 5.89 KiB (asset) [built] [code generated] - a-source-map (webpack x.x.x) compiled successfully in X ms - -b-source-map: - assets by path *.js 3.43 KiB - asset d443c1f1a2a7bebef466-d443c1.js 2.75 KiB [emitted] [immutable] [minimized] (name: runtime) - sourceMap d443c1f1a2a7bebef466-d443c1.js.map 14.2 KiB [emitted] [dev] (auxiliary name: runtime) - asset 05c637d15dff2d0dc5fd-05c637.js 344 bytes [emitted] [immutable] [minimized] (name: lazy) - sourceMap 05c637d15dff2d0dc5fd-05c637.js.map 395 bytes [emitted] [dev] (auxiliary name: lazy) - asset c41aff3dd03dbe1d8aa3-c41aff.js 281 bytes [emitted] [immutable] [minimized] (name: index) - sourceMap c41aff3dd03dbe1d8aa3-c41aff.js.map 323 bytes [emitted] [dev] (auxiliary name: index) - asset 222c2acc68675174e6b2-222c2a.js 77 bytes [emitted] [immutable] [minimized] (name: a, b) - sourceMap 222c2acc68675174e6b2-222c2a.js.map 254 bytes [emitted] [dev] (auxiliary name: a, b) - assets by chunk 20.4 KiB (auxiliary name: lazy) - asset 89a353e9c515885abd8e.png 14.6 KiB [emitted] [immutable] [from: file.png] (auxiliary name: lazy) - asset 7382fad5b015914e0811.jpg?query 5.89 KiB [cached] [immutable] [from: file.jpg?query] (auxiliary name: lazy) - asset 7382fad5b015914e0811.jpg 5.89 KiB [emitted] [immutable] [from: file.jpg] (auxiliary name: index) - Entrypoint index 3.02 KiB (20.4 KiB) = d443c1f1a2a7bebef466-d443c1.js 2.75 KiB c41aff3dd03dbe1d8aa3-c41aff.js 281 bytes 3 auxiliary assets - Entrypoint a 77 bytes (254 bytes) = 222c2acc68675174e6b2-222c2a.js 1 auxiliary asset - Entrypoint b 77 bytes (254 bytes) = 222c2acc68675174e6b2-222c2a.js 1 auxiliary asset - runtime modules 7.16 KiB 9 modules - orphan modules 19 bytes [orphan] 1 module - cacheable modules 469 bytes (javascript) 26.3 KiB (asset) - javascript modules 343 bytes - ./b/index.js 109 bytes [built] [code generated] - ./b/a.js 22 bytes [built] [code generated] - ./b/b.js 66 bytes [built] [code generated] - ./b/lazy.js + 1 modules 146 bytes [built] [code generated] - asset modules 126 bytes (javascript) 26.3 KiB (asset) - ./b/file.jpg 42 bytes (javascript) 5.89 KiB (asset) [built] [code generated] - ./b/file.png 42 bytes (javascript) 14.6 KiB (asset) [built] [code generated] - ./b/file.jpg?query 42 bytes (javascript) 5.89 KiB (asset) [built] [code generated] - b-source-map (webpack x.x.x) compiled successfully in X ms" -`; - -exports[`StatsTestCases should print correct stats for related-assets 1`] = ` -"default: - assets by path *.js 15.1 KiB - asset default-main.js 14.4 KiB [emitted] (name: main) 3 related assets - asset default-chunk_js.js 817 bytes [emitted] 3 related assets - assets by path *.css 142 bytes - asset default-chunk_js.css 73 bytes [emitted] 3 related assets - asset default-main.css 69 bytes [emitted] (name: main) 3 related assets - -relatedAssets: - assets by path *.js 15.2 KiB - asset relatedAssets-main.js 14.4 KiB [emitted] (name: main) - compressed relatedAssets-main.js.br 14.4 KiB [emitted] - compressed relatedAssets-main.js.gz 14.4 KiB [emitted] - sourceMap relatedAssets-main.js.map 12.4 KiB [emitted] [dev] (auxiliary name: main) - compressed relatedAssets-main.js.map.br 12.4 KiB [emitted] - compressed relatedAssets-main.js.map.gz 12.4 KiB [emitted] - asset relatedAssets-chunk_js.js 823 bytes [emitted] - compressed relatedAssets-chunk_js.js.br 823 bytes [emitted] - compressed relatedAssets-chunk_js.js.gz 823 bytes [emitted] - sourceMap relatedAssets-chunk_js.js.map 301 bytes [emitted] [dev] - compressed relatedAssets-chunk_js.js.map.br 301 bytes [emitted] - compressed relatedAssets-chunk_js.js.map.gz 301 bytes [emitted] - assets by path *.css 154 bytes - asset relatedAssets-chunk_js.css 79 bytes [emitted] - sourceMap relatedAssets-chunk_js.css.map 202 bytes [emitted] [dev] - compressed relatedAssets-chunk_js.css.map.br 202 bytes [emitted] - compressed relatedAssets-chunk_js.css.map.gz 202 bytes [emitted] - compressed relatedAssets-chunk_js.css.br 79 bytes [emitted] - compressed relatedAssets-chunk_js.css.gz 79 bytes [emitted] - asset relatedAssets-main.css 75 bytes [emitted] (name: main) - sourceMap relatedAssets-main.css.map 192 bytes [emitted] [dev] (auxiliary name: main) - compressed relatedAssets-main.css.map.br 192 bytes [emitted] - compressed relatedAssets-main.css.map.gz 192 bytes [emitted] - compressed relatedAssets-main.css.br 75 bytes [emitted] - compressed relatedAssets-main.css.gz 75 bytes [emitted] - -exclude1: - assets by path *.js 15.2 KiB - asset exclude1-main.js 14.4 KiB [emitted] (name: main) - hidden assets 28.7 KiB 2 assets - sourceMap exclude1-main.js.map 12.4 KiB [emitted] [dev] (auxiliary name: main) - hidden assets 24.8 KiB 2 assets - 1 related asset - 1 related asset - asset exclude1-chunk_js.js 818 bytes [emitted] - hidden assets 1.6 KiB 2 assets - sourceMap exclude1-chunk_js.js.map 296 bytes [emitted] [dev] - hidden assets 592 bytes 2 assets - 1 related asset - 1 related asset - assets by path *.css 144 bytes - asset exclude1-chunk_js.css 74 bytes [emitted] - hidden assets 148 bytes 2 assets - sourceMap exclude1-chunk_js.css.map 197 bytes [emitted] [dev] - hidden assets 394 bytes 2 assets - 1 related asset - 1 related asset - asset exclude1-main.css 70 bytes [emitted] (name: main) - hidden assets 140 bytes 2 assets - sourceMap exclude1-main.css.map 187 bytes [emitted] [dev] (auxiliary name: main) - hidden assets 374 bytes 2 assets - 1 related asset - 1 related asset - -exclude2: - assets by path *.js 15.2 KiB - asset exclude2-main.js 14.4 KiB [emitted] (name: main) - hidden assets 12.4 KiB 1 asset - compressed exclude2-main.js.br 14.4 KiB [emitted] - compressed exclude2-main.js.gz 14.4 KiB [emitted] - asset exclude2-chunk_js.js 818 bytes [emitted] - hidden assets 296 bytes 1 asset - compressed exclude2-chunk_js.js.br 818 bytes [emitted] - compressed exclude2-chunk_js.js.gz 818 bytes [emitted] - assets by path *.css 144 bytes - asset exclude2-chunk_js.css 74 bytes [emitted] - hidden assets 197 bytes 1 asset - compressed exclude2-chunk_js.css.br 74 bytes [emitted] - compressed exclude2-chunk_js.css.gz 74 bytes [emitted] - asset exclude2-main.css 70 bytes [emitted] (name: main) - hidden assets 187 bytes 1 asset - compressed exclude2-main.css.br 70 bytes [emitted] - compressed exclude2-main.css.gz 70 bytes [emitted] - -exclude3: - hidden assets 892 bytes 2 assets - assets by status 14.4 KiB [emitted] - asset exclude3-main.js 14.4 KiB [emitted] (name: main) - compressed exclude3-main.js.br 14.4 KiB [emitted] - compressed exclude3-main.js.gz 14.4 KiB [emitted] - sourceMap exclude3-main.js.map 12.4 KiB [emitted] [dev] (auxiliary name: main) - compressed exclude3-main.js.map.br 12.4 KiB [emitted] - compressed exclude3-main.js.map.gz 12.4 KiB [emitted] - asset exclude3-main.css 70 bytes [emitted] (name: main) - sourceMap exclude3-main.css.map 187 bytes [emitted] [dev] (auxiliary name: main) - compressed exclude3-main.css.map.br 187 bytes [emitted] - compressed exclude3-main.css.map.gz 187 bytes [emitted] - compressed exclude3-main.css.br 70 bytes [emitted] - compressed exclude3-main.css.gz 70 bytes [emitted]" -`; - -exports[`StatsTestCases should print correct stats for resolve-plugin-context 1`] = ` -"asset bundle.js 1.67 KiB [emitted] (name: main) -modules by path ./node_modules/def/ 17 bytes - ./node_modules/def/index.js 16 bytes [built] [code generated] - ./node_modules/def/node_modules/xyz/index.js 1 bytes [built] [code generated] -./index.js 48 bytes [built] [code generated] -./node_modules/abc/index.js 16 bytes [built] [code generated] -./node_modules/xyz/index.js 1 bytes [built] [code generated] -webpack x.x.x compiled successfully in X ms" -`; - -exports[`StatsTestCases should print correct stats for reverse-sort-modules 1`] = ` -"asset main.js 5.47 KiB [emitted] (name: main) -./index.js 181 bytes [built] [code generated] -./c.js?9 33 bytes [built] [code generated] -./c.js?8 33 bytes [built] [code generated] -./c.js?7 33 bytes [built] [code generated] -./c.js?6 33 bytes [built] [code generated] -./c.js?5 33 bytes [built] [code generated] -./c.js?4 33 bytes [built] [code generated] -./c.js?3 33 bytes [built] [code generated] -./c.js?2 33 bytes [built] [code generated] -./c.js?10 33 bytes [built] [code generated] -./c.js?1 33 bytes [built] [code generated] -./b.js?9 34 bytes [built] [code generated] -./b.js?8 34 bytes [built] [code generated] -./b.js?7 34 bytes [built] [code generated] -./b.js?6 34 bytes [built] [code generated] -./b.js?5 34 bytes [built] [code generated] -./b.js?4 34 bytes [built] [code generated] -./b.js?3 34 bytes [built] [code generated] -./b.js?2 34 bytes [built] [code generated] -./b.js?10 34 bytes [built] [code generated] -./b.js?1 34 bytes [built] [code generated] -./a.js?9 33 bytes [built] [code generated] -./a.js?8 33 bytes [built] [code generated] -./a.js?7 33 bytes [built] [code generated] -./a.js?6 33 bytes [built] [code generated] -./a.js?5 33 bytes [built] [code generated] -./a.js?4 33 bytes [built] [code generated] -./a.js?3 33 bytes [built] [code generated] -./a.js?2 33 bytes [built] [code generated] -./a.js?10 33 bytes [built] [code generated] -./a.js?1 33 bytes [built] [code generated] -webpack x.x.x compiled successfully in X ms" -`; - -exports[`StatsTestCases should print correct stats for runtime-chunk 1`] = ` -"Entrypoint e1 6.42 KiB = runtime~e1.js 5.35 KiB e1.js 1.07 KiB -Entrypoint e2 6.42 KiB = runtime~e2.js 5.35 KiB e2.js 1.07 KiB -webpack x.x.x compiled successfully" -`; - -exports[`StatsTestCases should print correct stats for runtime-chunk-integration 1`] = ` -"base: - asset without-runtime.js 11.9 KiB [emitted] (name: runtime) - asset without-505.js 1.22 KiB [emitted] - asset without-main1.js 848 bytes [emitted] (name: main1) - Entrypoint main1 12.8 KiB = without-runtime.js 11.9 KiB without-main1.js 848 bytes - runtime modules 7.39 KiB 10 modules - cacheable modules 126 bytes - ./main1.js 66 bytes [built] [code generated] - ./b.js 20 bytes [built] [code generated] - ./c.js 20 bytes [built] [code generated] - ./d.js 20 bytes [built] [code generated] - base (webpack x.x.x) compiled successfully - -static custom name: - asset with-manifest.js 11.9 KiB [emitted] (name: manifest) - asset with-505.js 1.22 KiB [emitted] - asset with-main1.js 848 bytes [emitted] (name: main1) - asset with-main2.js 467 bytes [emitted] (name: main2) - asset with-main3.js 467 bytes [emitted] (name: main3) - Entrypoint main1 12.7 KiB = with-manifest.js 11.9 KiB with-main1.js 848 bytes - Entrypoint main2 12.4 KiB = with-manifest.js 11.9 KiB with-main2.js 467 bytes - Entrypoint main3 12.4 KiB = with-manifest.js 11.9 KiB with-main3.js 467 bytes - runtime modules 7.39 KiB 10 modules - cacheable modules 166 bytes - ./main1.js 66 bytes [built] [code generated] - ./main2.js 20 bytes [built] [code generated] - ./main3.js 20 bytes [built] [code generated] - ./b.js 20 bytes [built] [code generated] - ./c.js 20 bytes [built] [code generated] - ./d.js 20 bytes [built] [code generated] - static custom name (webpack x.x.x) compiled successfully - -dynamic custom name: - asset func-b.js 11.9 KiB [emitted] (name: b) - asset func-a.js 4.79 KiB [emitted] (name: a) - asset func-505.js 1.22 KiB [emitted] - asset func-main1.js 848 bytes [emitted] (name: main1) - asset func-main2.js 467 bytes [emitted] (name: main2) - asset func-main3.js 467 bytes [emitted] (name: main3) - Entrypoint main1 12.7 KiB = func-b.js 11.9 KiB func-main1.js 848 bytes - Entrypoint main2 12.4 KiB = func-b.js 11.9 KiB func-main2.js 467 bytes - Entrypoint main3 5.25 KiB = func-a.js 4.79 KiB func-main3.js 467 bytes - runtime modules 9.72 KiB 13 modules - cacheable modules 166 bytes - ./main1.js 66 bytes [built] [code generated] - ./main2.js 20 bytes [built] [code generated] - ./main3.js 20 bytes [built] [code generated] - ./b.js 20 bytes [built] [code generated] - ./c.js 20 bytes [built] [code generated] - ./d.js 20 bytes [built] [code generated] - dynamic custom name (webpack x.x.x) compiled successfully" -`; - -exports[`StatsTestCases should print correct stats for runtime-chunk-issue-7382 1`] = ` -"Entrypoint e1 7.29 KiB = runtime.js 5.34 KiB all.js 1020 bytes e1.js 981 bytes -Entrypoint e2 7.29 KiB = runtime.js 5.34 KiB all.js 1020 bytes e2.js 981 bytes -webpack x.x.x compiled successfully" -`; - -exports[`StatsTestCases should print correct stats for runtime-chunk-single 1`] = ` -"Entrypoint e1 6.42 KiB = runtime.js 5.34 KiB e1.js 1.07 KiB -Entrypoint e2 6.42 KiB = runtime.js 5.34 KiB e2.js 1.07 KiB -webpack x.x.x compiled successfully" -`; - -exports[`StatsTestCases should print correct stats for runtime-specific-used-exports 1`] = ` -"production: - asset production-a.js 13 KiB [emitted] (name: a) - asset production-b.js 13 KiB [emitted] (name: b) - asset production-dx_js.js 1.17 KiB [emitted] - asset production-dw_js-_a6170.js 1.17 KiB [emitted] - asset production-dw_js-_a6171.js 1.17 KiB [emitted] - asset production-dy_js.js 1.15 KiB [emitted] - asset production-dz_js.js 1.15 KiB [emitted] - asset production-c.js 93 bytes [emitted] (name: c) - chunk (runtime: a) production-a.js (a) 605 bytes (javascript) 6.5 KiB (runtime) [entry] [rendered] - runtime modules 6.5 KiB 9 modules - cacheable modules 605 bytes - ./a.js 261 bytes [built] [code generated] - [no exports used] - ./dx-importer.js 63 bytes [dependent] [built] [code generated] - [only some exports used: default] - ./module.js 122 bytes [dependent] [built] [code generated] - [only some exports used: x] - ./module.js?reexported 122 bytes [dependent] [built] [code generated] - [only some exports used: x] - ./reexport.js 37 bytes [dependent] [built] [code generated] - [only some exports used: x] - chunk (runtime: b) production-b.js (b) 605 bytes (javascript) 6.5 KiB (runtime) [entry] [rendered] - runtime modules 6.5 KiB 9 modules - cacheable modules 605 bytes - ./b.js 261 bytes [built] [code generated] - [no exports used] - ./dx-importer.js 63 bytes [dependent] [built] [code generated] - [only some exports used: default] - ./module.js 122 bytes [dependent] [built] [code generated] - [only some exports used: y] - ./module.js?reexported 122 bytes [dependent] [built] [code generated] - [only some exports used: y] - ./reexport.js 37 bytes [dependent] [built] [code generated] - [only some exports used: y] - chunk (runtime: c) production-c.js (c) 9 bytes [entry] [rendered] - ./c.js 9 bytes [built] [code generated] - [no exports used] - chunk (runtime: a) production-dw_js-_a6170.js 168 bytes [rendered] - ./dw.js 46 bytes [built] [code generated] - ./module.js?chunk 122 bytes [dependent] [built] [code generated] - [only some exports used: identity, w, x, y] - chunk (runtime: b) production-dw_js-_a6171.js 168 bytes [rendered] - ./dw.js 46 bytes [built] [code generated] - ./module.js?chunk 122 bytes [dependent] [built] [code generated] - [only some exports used: identity, w, x, z] - chunk (runtime: a, b) production-dx_js.js 168 bytes [rendered] - ./dx.js 46 bytes [built] [code generated] - ./module.js?chunk 122 bytes [dependent] [built] [code generated] - [only some exports used: identity, w, x, y, z] - chunk (runtime: a) production-dy_js.js 168 bytes [rendered] - ./dy.js 46 bytes [built] [code generated] - ./module.js?chunk 122 bytes [dependent] [built] [code generated] - [only some exports used: identity, w, x, y] - chunk (runtime: b) production-dz_js.js 168 bytes [rendered] - ./dz.js 46 bytes [built] [code generated] - ./module.js?chunk 122 bytes [dependent] [built] [code generated] - [only some exports used: identity, w, x, z] - runtime modules 13 KiB 18 modules - cacheable modules 1.15 KiB - ./a.js 261 bytes [built] [code generated] - [no exports used] - ./b.js 261 bytes [built] [code generated] - [no exports used] - ./c.js 9 bytes [built] [code generated] - [no exports used] - ./module.js 122 bytes [built] [code generated] - [only some exports used: x, y] - ./reexport.js 37 bytes [built] [code generated] - [only some exports used: x, y] - ./dx-importer.js 63 bytes [built] [code generated] - [only some exports used: default] - ./dy.js 46 bytes [built] [code generated] - ./dw.js 46 bytes [built] [code generated] - ./dz.js 46 bytes [built] [code generated] - ./module.js?reexported 122 bytes [built] [code generated] - [only some exports used: x, y] - ./module.js?chunk 122 bytes [built] [code generated] - [only some exports used: identity, w, x, y, z] - ./dx.js 46 bytes [built] [code generated] - production (webpack x.x.x) compiled successfully in X ms - -development: - asset development-a.js 15.8 KiB [emitted] (name: a) - asset development-b.js 15.8 KiB [emitted] (name: b) - asset development-dw_js.js 2.13 KiB [emitted] - asset development-dx_js.js 2.13 KiB [emitted] - asset development-dy_js.js 2.13 KiB [emitted] - asset development-dz_js.js 2.13 KiB [emitted] - asset development-c.js 1.13 KiB [emitted] (name: c) - chunk (runtime: a) development-a.js (a) 605 bytes (javascript) 6.5 KiB (runtime) [entry] [rendered] - runtime modules 6.5 KiB 9 modules - cacheable modules 605 bytes - ./a.js 261 bytes [built] [code generated] - [used exports unknown] - ./dx-importer.js 63 bytes [dependent] [built] [code generated] - [used exports unknown] - ./module.js 122 bytes [dependent] [built] [code generated] - [used exports unknown] - ./module.js?reexported 122 bytes [dependent] [built] [code generated] - [used exports unknown] - ./reexport.js 37 bytes [dependent] [built] [code generated] - [used exports unknown] - chunk (runtime: b) development-b.js (b) 605 bytes (javascript) 6.5 KiB (runtime) [entry] [rendered] - runtime modules 6.5 KiB 9 modules - cacheable modules 605 bytes - ./b.js 261 bytes [built] [code generated] - [used exports unknown] - ./dx-importer.js 63 bytes [dependent] [built] [code generated] - [used exports unknown] - ./module.js 122 bytes [dependent] [built] [code generated] - [used exports unknown] - ./module.js?reexported 122 bytes [dependent] [built] [code generated] - [used exports unknown] - ./reexport.js 37 bytes [dependent] [built] [code generated] - [used exports unknown] - chunk (runtime: c) development-c.js (c) 9 bytes [entry] [rendered] - ./c.js 9 bytes [built] [code generated] - [used exports unknown] - chunk (runtime: a, b) development-dw_js.js 168 bytes [rendered] - ./dw.js 46 bytes [built] [code generated] - [used exports unknown] - ./module.js?chunk 122 bytes [dependent] [built] [code generated] - [used exports unknown] - chunk (runtime: a, b) development-dx_js.js 168 bytes [rendered] - ./dx.js 46 bytes [built] [code generated] - [used exports unknown] - ./module.js?chunk 122 bytes [dependent] [built] [code generated] - [used exports unknown] - chunk (runtime: a) development-dy_js.js 168 bytes [rendered] - ./dy.js 46 bytes [built] [code generated] - [used exports unknown] - ./module.js?chunk 122 bytes [dependent] [built] [code generated] - [used exports unknown] - chunk (runtime: b) development-dz_js.js 168 bytes [rendered] - ./dz.js 46 bytes [built] [code generated] - [used exports unknown] - ./module.js?chunk 122 bytes [dependent] [built] [code generated] - [used exports unknown] - runtime modules 13 KiB 18 modules - cacheable modules 1.15 KiB - ./a.js 261 bytes [built] [code generated] - [used exports unknown] - ./b.js 261 bytes [built] [code generated] - [used exports unknown] - ./c.js 9 bytes [built] [code generated] - [used exports unknown] - ./module.js 122 bytes [built] [code generated] - [used exports unknown] - ./reexport.js 37 bytes [built] [code generated] - [used exports unknown] - ./dx-importer.js 63 bytes [built] [code generated] - [used exports unknown] - ./dy.js 46 bytes [built] [code generated] - [used exports unknown] - ./dw.js 46 bytes [built] [code generated] - [used exports unknown] - ./dz.js 46 bytes [built] [code generated] - [used exports unknown] - ./module.js?reexported 122 bytes [built] [code generated] - [used exports unknown] - ./module.js?chunk 122 bytes [built] [code generated] - [used exports unknown] - ./dx.js 46 bytes [built] [code generated] - [used exports unknown] - development (webpack x.x.x) compiled successfully in X ms - -global: - asset global-a.js 13.2 KiB [emitted] (name: a) - asset global-b.js 13.2 KiB [emitted] (name: b) - asset global-dw_js.js 1.17 KiB [emitted] - asset global-dx_js.js 1.17 KiB [emitted] - asset global-dy_js.js 1.17 KiB [emitted] - asset global-dz_js.js 1.17 KiB [emitted] - asset global-c.js 93 bytes [emitted] (name: c) - chunk (runtime: a) global-a.js (a) 605 bytes (javascript) 6.5 KiB (runtime) [entry] [rendered] - runtime modules 6.5 KiB 9 modules - cacheable modules 605 bytes - ./a.js 261 bytes [built] [code generated] - [no exports used] - ./dx-importer.js 63 bytes [dependent] [built] [code generated] - [only some exports used: default] - ./module.js 122 bytes [dependent] [built] [code generated] - [only some exports used: x, y] - ./module.js?reexported 122 bytes [dependent] [built] [code generated] - [only some exports used: x, y] - ./reexport.js 37 bytes [dependent] [built] [code generated] - [only some exports used: x, y] - chunk (runtime: b) global-b.js (b) 605 bytes (javascript) 6.5 KiB (runtime) [entry] [rendered] - runtime modules 6.5 KiB 9 modules - cacheable modules 605 bytes - ./b.js 261 bytes [built] [code generated] - [no exports used] - ./dx-importer.js 63 bytes [dependent] [built] [code generated] - [only some exports used: default] - ./module.js 122 bytes [dependent] [built] [code generated] - [only some exports used: x, y] - ./module.js?reexported 122 bytes [dependent] [built] [code generated] - [only some exports used: x, y] - ./reexport.js 37 bytes [dependent] [built] [code generated] - [only some exports used: x, y] - chunk (runtime: c) global-c.js (c) 9 bytes [entry] [rendered] - ./c.js 9 bytes [built] [code generated] - [no exports used] - chunk (runtime: a, b) global-dw_js.js 168 bytes [rendered] - ./dw.js 46 bytes [built] [code generated] - ./module.js?chunk 122 bytes [dependent] [built] [code generated] - [only some exports used: identity, w, x, y, z] - chunk (runtime: a, b) global-dx_js.js 168 bytes [rendered] - ./dx.js 46 bytes [built] [code generated] - ./module.js?chunk 122 bytes [dependent] [built] [code generated] - [only some exports used: identity, w, x, y, z] - chunk (runtime: a) global-dy_js.js 168 bytes [rendered] - ./dy.js 46 bytes [built] [code generated] - ./module.js?chunk 122 bytes [dependent] [built] [code generated] - [only some exports used: identity, w, x, y, z] - chunk (runtime: b) global-dz_js.js 168 bytes [rendered] - ./dz.js 46 bytes [built] [code generated] - ./module.js?chunk 122 bytes [dependent] [built] [code generated] - [only some exports used: identity, w, x, y, z] - runtime modules 13 KiB 18 modules - cacheable modules 1.15 KiB - ./a.js 261 bytes [built] [code generated] - [no exports used] - ./b.js 261 bytes [built] [code generated] - [no exports used] - ./c.js 9 bytes [built] [code generated] - [no exports used] - ./module.js 122 bytes [built] [code generated] - [only some exports used: x, y] - ./reexport.js 37 bytes [built] [code generated] - [only some exports used: x, y] - ./dx-importer.js 63 bytes [built] [code generated] - [only some exports used: default] - ./dy.js 46 bytes [built] [code generated] - ./dw.js 46 bytes [built] [code generated] - ./dz.js 46 bytes [built] [code generated] - ./module.js?reexported 122 bytes [built] [code generated] - [only some exports used: x, y] - ./module.js?chunk 122 bytes [built] [code generated] - [only some exports used: identity, w, x, y, z] - ./dx.js 46 bytes [built] [code generated] - global (webpack x.x.x) compiled successfully in X ms" -`; - -exports[`StatsTestCases should print correct stats for scope-hoisting-bailouts 1`] = ` -"runtime modules 6.75 KiB 10 modules -built modules 615 bytes [built] - code generated modules 530 bytes [code generated] - modules by path ./*.js 377 bytes 7 modules - ./concatenated.js + 2 modules 111 bytes [built] [code generated] - ModuleConcatenation bailout: Cannot concat with external \\"external\\": Module external \\"external\\" is not in the same chunk(s) (expected in chunk(s) unnamed chunk(s), module is in chunk(s) index) - external \\"external\\" 42 bytes [built] [code generated] - orphan modules 85 bytes [orphan] - ./concatenated1.js 37 bytes [orphan] [built] - Dependency (harmony side effect evaluation) with side effects at 1:0-36 - ./concatenated2.js 48 bytes [orphan] [built] - Dependency (harmony side effect evaluation) with side effects at 1:0-29 -webpack x.x.x compiled successfully in X ms" -`; - -exports[`StatsTestCases should print correct stats for scope-hoisting-multi 1`] = ` -"Entrypoint first 14.2 KiB = a-vendor.js 419 bytes a-first.js 13.8 KiB -Entrypoint second 13.7 KiB = a-vendor.js 419 bytes a-second.js 13.3 KiB -runtime modules 14.9 KiB 20 modules -orphan modules 37 bytes [orphan] 1 module -cacheable modules 807 bytes - ./first.js 236 bytes [built] [code generated] - ./second.js 202 bytes [built] [code generated] - ./vendor.js 25 bytes [built] [code generated] - ./common2.js 25 bytes [built] [code generated] - ./module_first.js 31 bytes [built] [code generated] - ./lazy_first.js 91 bytes [built] [code generated] - ./lazy_shared.js 56 bytes [built] [code generated] - ./lazy_second.js 91 bytes [built] [code generated] - ./common_lazy.js 25 bytes [built] [code generated] - ./common_lazy_shared.js 25 bytes [built] [code generated] -webpack x.x.x compiled successfully in X ms - -Entrypoint first 13.5 KiB = b-vendor.js 419 bytes b-first.js 13.1 KiB -Entrypoint second 13.4 KiB = b-vendor.js 419 bytes b-second.js 12.9 KiB -runtime modules 14.9 KiB 20 modules -cacheable modules 975 bytes - code generated modules 857 bytes [code generated] - modules by path ./*.js + 1 modules 459 bytes 3 modules - modules by path ./*.js 106 bytes - ./vendor.js 25 bytes [built] [code generated] - ./lazy_shared.js 56 bytes [built] [code generated] - ModuleConcatenation bailout: Cannot concat with ./common_lazy_shared.js: Module ./common_lazy_shared.js is referenced from different chunks by these modules: ./lazy_first.js, ./lazy_second.js - ./common_lazy_shared.js 25 bytes [built] [code generated] - ./first.js + 2 modules 292 bytes [built] [code generated] - ModuleConcatenation bailout: Cannot concat with ./vendor.js: Module ./vendor.js is not in the same chunk(s) (expected in chunk(s) first, module is in chunk(s) vendor) - orphan modules 118 bytes [orphan] - ./common2.js 25 bytes [orphan] [built] - ./module_first.js 31 bytes [orphan] [built] - ./common.js 37 bytes [orphan] [built] - ModuleConcatenation bailout: Module is not in any chunk - ./common_lazy.js 25 bytes [orphan] [built] -webpack x.x.x compiled successfully in X ms" -`; - -exports[`StatsTestCases should print correct stats for side-effects-issue-7428 1`] = ` -"asset main.js 12.2 KiB [emitted] (name: main) -asset 1.js 640 bytes [emitted] -runtime modules 6.49 KiB 9 modules -cacheable modules 823 bytes - modules by path ./components/src/ 501 bytes - orphan modules 315 bytes [orphan] - modules by path ./components/src/CompAB/*.js 164 bytes 2 modules - modules by path ./components/src/CompC/*.js 67 bytes - ./components/src/CompC/CompC.js 33 bytes [orphan] [built] - [module unused] - [inactive] harmony side effect evaluation ./CompC ./components/src/CompC/index.js 1:0-34 - [inactive] harmony export imported specifier ./CompC ./components/src/CompC/index.js 1:0-34 - [inactive] harmony export imported specifier ./CompC ./components/src/index.js 2:0-43 (skipped side-effect-free modules) - ./components/src/CompC/index.js 34 bytes [orphan] [built] - [module unused] - [inactive] harmony side effect evaluation ./CompC ./components/src/index.js 2:0-43 - [inactive] harmony export imported specifier ./CompC ./components/src/index.js 2:0-43 - ./components/src/index.js 84 bytes [orphan] [built] - [module unused] - [inactive] harmony side effect evaluation ./components ./foo.js 1:0-37 - [inactive] harmony import specifier ./components ./foo.js 3:20-25 - [inactive] harmony side effect evaluation ./components ./main.js + 1 modules ./main.js 1:0-44 - [inactive] harmony import specifier ./components ./main.js + 1 modules ./main.js 3:15-20 - [inactive] harmony import specifier ./components ./main.js + 1 modules ./main.js 4:15-20 - code generated modules 186 bytes [code generated] - ./components/src/CompAB/CompA.js 89 bytes [built] [code generated] - [only some exports used: default] - [inactive] harmony side effect evaluation ./CompA ./components/src/CompAB/index.js 1:0-43 - [inactive] harmony export imported specifier ./CompA ./components/src/CompAB/index.js 1:0-43 - [inactive] harmony export imported specifier ./CompAB ./components/src/index.js 1:0-40 (skipped side-effect-free modules) - harmony import specifier ./components ./foo.js 3:20-25 (skipped side-effect-free modules) - harmony import specifier ./components ./main.js + 1 modules ./main.js 3:15-20 (skipped side-effect-free modules) - ./components/src/CompAB/utils.js 97 bytes [built] [code generated] - [inactive] harmony side effect evaluation ./utils ./components/src/CompAB/CompA.js 1:0-35 - harmony import specifier ./utils ./components/src/CompAB/CompA.js 5:5-12 - [inactive] harmony side effect evaluation ./utils ./components/src/CompAB/CompB.js 1:0-30 - harmony import specifier ./utils ./components/src/CompAB/CompB.js 5:2-5 - [inactive] harmony side effect evaluation ./utils ./main.js + 1 modules ./components/src/CompAB/CompB.js 1:0-30 - harmony import specifier ./utils ./main.js + 1 modules ./components/src/CompAB/CompB.js 5:2-5 - ./main.js + 1 modules 221 bytes [built] [code generated] - [no exports used] - entry ./main.js main - | ./main.js 144 bytes [built] - | [no exports used] - | ./components/src/CompAB/CompB.js 77 bytes [built] - | [only some exports used: default] - | [inactive] harmony side effect evaluation ./CompB ./components/src/CompAB/index.js 2:0-43 - | [inactive] harmony export imported specifier ./CompB ./components/src/CompAB/index.js 2:0-43 - | [inactive] harmony export imported specifier ./CompAB ./components/src/index.js 1:0-40 (skipped side-effect-free modules) - | harmony import specifier ./components ./main.js 4:15-20 (skipped side-effect-free modules) - ./foo.js 101 bytes [built] [code generated] - import() ./foo ./main.js + 1 modules ./main.js 6:0-15 -webpack x.x.x compiled successfully in X ms" -`; - -exports[`StatsTestCases should print correct stats for side-effects-optimization 1`] = ` -"asset main.js 221 bytes [emitted] [minimized] (name: main) -orphan modules 1.2 KiB [orphan] 4 modules -cacheable modules 1.22 KiB - ./index.js + 2 modules 1.18 KiB [built] [code generated] - [no exports] - [no exports used] - ModuleConcatenation bailout: Cannot concat with ./node_modules/module-with-export/emptyModule.js: Module is not an ECMAScript module - | ./index.js 116 bytes [built] - | [no exports] - | [no exports used] - | Statement (ExpressionStatement) with side effects in source code at 4:0-30 - | ./node_modules/big-module/a.js 58 bytes [built] - | [only some exports used: a] - | ./node_modules/module-with-export/index.js 1.01 KiB [built] - | [only some exports used: smallVar] - ./node_modules/module-with-export/emptyModule.js 43 bytes [built] [code generated] - [used exports unknown] - ModuleConcatenation bailout: Module is not an ECMAScript module -webpack x.x.x compiled successfully in X ms - -asset main.no-side.js 979 bytes [emitted] [minimized] (name: main) -runtime modules 1010 bytes 4 modules -orphan modules 102 bytes [orphan] 2 modules -cacheable modules 1.35 KiB - modules by path ./node_modules/module-with-export/*.js 1.05 KiB - ./node_modules/module-with-export/index.js 1.01 KiB [built] [code generated] - [only some exports used: huh, smallVar] - ModuleConcatenation bailout: List of module exports is dynamic (huh: maybe provided (runtime-defined) and used in main) - ./node_modules/module-with-export/emptyModule.js 43 bytes [built] [code generated] - [used exports unknown] - ModuleConcatenation bailout: Module is not an ECMAScript module - ./index.js + 2 modules 218 bytes [built] [code generated] - [no exports] - [no exports used] - ModuleConcatenation bailout: Cannot concat with ./node_modules/big-module/log.js: Module ./node_modules/big-module/log.js is referenced from these modules with unsupported syntax: ./node_modules/big-module/log.js (referenced with module decorator) - ModuleConcatenation bailout: Cannot concat with ./node_modules/module-with-export/index.js: Module ./node_modules/big-module/log.js is referenced from these modules with unsupported syntax: ./node_modules/big-module/log.js (referenced with module decorator) - | ./index.js 116 bytes [built] - | [no exports] - | [no exports used] - | ./node_modules/big-module/index.js 44 bytes [built] - | [only some exports used: a, huh] - | ModuleConcatenation bailout: List of module exports is dynamic (huh: maybe provided (runtime-defined) and used in main) - | ./node_modules/big-module/a.js 58 bytes [built] - | [only some exports used: a, huh] - | ModuleConcatenation bailout: List of module exports is dynamic (huh: maybe provided (runtime-defined) and used in main) - ./node_modules/big-module/log.js 92 bytes [built] [code generated] - [only some exports used: huh] - ModuleConcatenation bailout: List of module exports is dynamic (huh: maybe provided (runtime-defined) and used in main) -webpack x.x.x compiled successfully in X ms" -`; - -exports[`StatsTestCases should print correct stats for side-effects-simple-unused 1`] = ` -"asset main.js 355 bytes [emitted] (name: main) -./index.js + 2 modules 158 bytes [built] [code generated] - [no exports used] - entry ./index main - | ./index.js 55 bytes [built] - | [no exports used] - | ./node_modules/pmodule/index.js 75 bytes [built] - | [only some exports used: default] - | [inactive] harmony side effect evaluation pmodule ./index.js 1:0-33 - | harmony import specifier pmodule ./index.js 3:12-15 - | [inactive] harmony import specifier pmodule ./index.js 3:17-18 - | ./node_modules/pmodule/c.js 28 bytes [built] - | [only some exports used: z] - | harmony import specifier pmodule ./index.js 3:17-18 (skipped side-effect-free modules) - | [inactive] harmony side effect evaluation ./c ./node_modules/pmodule/b.js 5:0-24 - | [inactive] harmony export imported specifier ./c ./node_modules/pmodule/b.js 5:0-24 - | [inactive] harmony export imported specifier ./b ./node_modules/pmodule/index.js 2:0-30 (skipped side-effect-free modules) -./node_modules/pmodule/index.js 75 bytes [orphan] [built] - [only some exports used: default] - [inactive] harmony side effect evaluation pmodule ./index.js 1:0-33 - harmony import specifier pmodule ./index.js 3:12-15 - [inactive] harmony import specifier pmodule ./index.js 3:17-18 -./node_modules/pmodule/c.js 28 bytes [orphan] [built] - [only some exports used: z] - harmony import specifier pmodule ./index.js 3:17-18 (skipped side-effect-free modules) - [inactive] harmony side effect evaluation ./c ./node_modules/pmodule/b.js 5:0-24 - [inactive] harmony export imported specifier ./c ./node_modules/pmodule/b.js 5:0-24 - [inactive] harmony export imported specifier ./b ./node_modules/pmodule/index.js 2:0-30 (skipped side-effect-free modules) -./node_modules/pmodule/a.js 60 bytes [orphan] [built] - [module unused] - [inactive] harmony side effect evaluation ./a ./index.js + 2 modules ./node_modules/pmodule/index.js 1:0-20 - [inactive] harmony export imported specifier ./a ./index.js + 2 modules ./node_modules/pmodule/index.js 1:0-20 - [inactive] harmony side effect evaluation ./a ./node_modules/pmodule/index.js 1:0-20 - [inactive] harmony export imported specifier ./a ./node_modules/pmodule/index.js 1:0-20 -./node_modules/pmodule/b.js 69 bytes [orphan] [built] - [module unused] - [inactive] harmony side effect evaluation ./b ./index.js + 2 modules ./node_modules/pmodule/index.js 2:0-30 - [inactive] harmony export imported specifier ./b ./index.js + 2 modules ./node_modules/pmodule/index.js 2:0-30 - [inactive] harmony export imported specifier ./b ./index.js + 2 modules ./node_modules/pmodule/index.js 2:0-30 - [inactive] harmony export imported specifier ./b ./index.js + 2 modules ./node_modules/pmodule/index.js 2:0-30 - [inactive] harmony side effect evaluation ./b ./node_modules/pmodule/index.js 2:0-30 - [inactive] harmony export imported specifier ./b ./node_modules/pmodule/index.js 2:0-30 - [inactive] harmony export imported specifier ./b ./node_modules/pmodule/index.js 2:0-30 - [inactive] harmony export imported specifier ./b ./node_modules/pmodule/index.js 2:0-30 -webpack x.x.x compiled successfully in X ms" -`; - -exports[`StatsTestCases should print correct stats for simple 1`] = ` -"asset bundle.js 1.15 KiB [emitted] (name: main) -./index.js 1 bytes [built] [code generated] -webpack x.x.x compiled successfully in X ms" -`; - -exports[`StatsTestCases should print correct stats for simple-more-info 1`] = ` -"PublicPath: auto -asset bundle.js 84 bytes [emitted] (name: main) -./index.js 1 bytes [built] [code generated] - entry ./index main - X ms (resolving: X ms, restoring: X ms, integration: X ms, building: X ms, storing: X ms) -webpack x.x.x compiled successfully in X ms" -`; - -exports[`StatsTestCases should print correct stats for split-chunks 1`] = ` -"default: - Entrypoint main 11.4 KiB = default/main.js - Entrypoint a 12.4 KiB = default/a.js - Entrypoint b 3.93 KiB = default/b.js - Entrypoint c 3.93 KiB = default/c.js - chunk (runtime: b) default/b.js (b) 196 bytes (javascript) 396 bytes (runtime) [entry] [rendered] - > ./b b - dependent modules 80 bytes [dependent] 4 modules - runtime modules 396 bytes 2 modules - ./b.js 116 bytes [built] [code generated] - chunk (runtime: a, main) default/async-g.js (async-g) 45 bytes <{282}> <{767}> <{786}> <{794}> <{954}> ={568}= [rendered] - > ./g ./a.js 6:0-47 - ./g.js 45 bytes [built] [code generated] - chunk (runtime: main) default/main.js (main) 147 bytes (javascript) 6.58 KiB (runtime) >{282}< >{334}< >{383}< >{568}< >{767}< >{769}< >{794}< >{954}< [entry] [rendered] - > ./ main - runtime modules 6.58 KiB 9 modules - ./index.js 147 bytes [built] [code generated] - chunk (runtime: main) default/282.js (id hint: vendors) 20 bytes <{179}> ={334}= ={383}= ={568}= ={767}= ={769}= ={794}= ={954}= >{137}< >{568}< [rendered] split chunk (cache group: defaultVendors) - > ./a ./index.js 1:0-47 - > ./b ./index.js 2:0-47 - > ./c ./index.js 3:0-47 - ./node_modules/x.js 20 bytes [built] [code generated] - chunk (runtime: main) default/async-b.js (async-b) 116 bytes <{179}> ={282}= ={568}= ={767}= ={954}= [rendered] - > ./b ./index.js 2:0-47 - ./b.js 116 bytes [built] [code generated] - chunk (runtime: main) default/async-c.js (async-c) 116 bytes <{179}> ={282}= ={568}= ={767}= ={769}= [rendered] - > ./c ./index.js 3:0-47 - ./c.js 116 bytes [built] [code generated] - chunk (runtime: c) default/c.js (c) 196 bytes (javascript) 396 bytes (runtime) [entry] [rendered] - > ./c c - dependent modules 80 bytes [dependent] 4 modules - runtime modules 396 bytes 2 modules - ./c.js 116 bytes [built] [code generated] - chunk (runtime: a, main) default/568.js 20 bytes <{179}> <{282}> <{767}> <{786}> <{794}> <{954}> ={137}= ={282}= ={334}= ={383}= ={767}= ={769}= ={954}= [rendered] split chunk (cache group: default) - > ./b ./index.js 2:0-47 - > ./c ./index.js 3:0-47 - > ./g ./a.js 6:0-47 - ./f.js 20 bytes [built] [code generated] - chunk (runtime: main) default/767.js 20 bytes <{179}> ={282}= ={334}= ={383}= ={568}= ={769}= ={794}= ={954}= >{137}< >{568}< [rendered] split chunk (cache group: default) - > ./a ./index.js 1:0-47 - > ./b ./index.js 2:0-47 - > ./c ./index.js 3:0-47 - ./d.js 20 bytes [built] [code generated] - chunk (runtime: main) default/769.js (id hint: vendors) 20 bytes <{179}> ={282}= ={383}= ={568}= ={767}= [rendered] split chunk (cache group: defaultVendors) - > ./c ./index.js 3:0-47 - ./node_modules/z.js 20 bytes [built] [code generated] - chunk (runtime: a) default/a.js (a) 245 bytes (javascript) 6.57 KiB (runtime) >{137}< >{568}< [entry] [rendered] - > ./a a - runtime modules 6.57 KiB 9 modules - dependent modules 60 bytes [dependent] 3 modules - ./a.js + 1 modules 185 bytes [built] [code generated] - chunk (runtime: main) default/async-a.js (async-a) 185 bytes <{179}> ={282}= ={767}= ={954}= >{137}< >{568}< [rendered] - > ./a ./index.js 1:0-47 - ./a.js + 1 modules 185 bytes [built] [code generated] - chunk (runtime: main) default/954.js (id hint: vendors) 20 bytes <{179}> ={282}= ={334}= ={568}= ={767}= ={794}= >{137}< >{568}< [rendered] split chunk (cache group: defaultVendors) - > ./a ./index.js 1:0-47 - > ./b ./index.js 2:0-47 - ./node_modules/y.js 20 bytes [built] [code generated] - default (webpack x.x.x) compiled successfully - -all-chunks: - Entrypoint main 11.4 KiB = all-chunks/main.js - Entrypoint a 14.8 KiB = all-chunks/282.js 414 bytes all-chunks/954.js 414 bytes all-chunks/767.js 414 bytes all-chunks/390.js 414 bytes all-chunks/a.js 13.2 KiB - Entrypoint b 7.97 KiB = all-chunks/282.js 414 bytes all-chunks/954.js 414 bytes all-chunks/767.js 414 bytes all-chunks/568.js 414 bytes all-chunks/b.js 6.35 KiB - Entrypoint c 7.97 KiB = all-chunks/282.js 414 bytes all-chunks/769.js 414 bytes all-chunks/767.js 414 bytes all-chunks/568.js 414 bytes all-chunks/c.js 6.35 KiB - chunk (runtime: b) all-chunks/b.js (b) 116 bytes (javascript) 2.64 KiB (runtime) ={282}= ={568}= ={767}= ={954}= [entry] [rendered] - > ./b b - runtime modules 2.64 KiB 4 modules - ./b.js 116 bytes [built] [code generated] - chunk (runtime: a, main) all-chunks/async-g.js (async-g) 45 bytes <{282}> <{390}> <{767}> <{786}> <{794}> <{954}> ={568}= [rendered] - > ./g ./a.js 6:0-47 - ./g.js 45 bytes [built] [code generated] - chunk (runtime: main) all-chunks/main.js (main) 147 bytes (javascript) 6.59 KiB (runtime) >{282}< >{334}< >{383}< >{390}< >{568}< >{767}< >{769}< >{794}< >{954}< [entry] [rendered] - > ./ main - runtime modules 6.59 KiB 9 modules - ./index.js 147 bytes [built] [code generated] - chunk (runtime: a, b, c, main) all-chunks/282.js (id hint: vendors) 20 bytes <{179}> ={128}= ={334}= ={383}= ={390}= ={459}= ={568}= ={767}= ={769}= ={786}= ={794}= ={954}= >{137}< >{568}< [initial] [rendered] split chunk (cache group: defaultVendors) - > ./a ./index.js 1:0-47 - > ./b ./index.js 2:0-47 - > ./c ./index.js 3:0-47 - > ./a a - > ./b b - > ./c c - ./node_modules/x.js 20 bytes [built] [code generated] - chunk (runtime: main) all-chunks/async-b.js (async-b) 116 bytes <{179}> ={282}= ={568}= ={767}= ={954}= [rendered] - > ./b ./index.js 2:0-47 - ./b.js 116 bytes [built] [code generated] - chunk (runtime: main) all-chunks/async-c.js (async-c) 116 bytes <{179}> ={282}= ={568}= ={767}= ={769}= [rendered] - > ./c ./index.js 3:0-47 - ./c.js 116 bytes [built] [code generated] - chunk (runtime: a, main) all-chunks/390.js 20 bytes <{179}> ={282}= ={767}= ={786}= ={794}= ={954}= >{137}< >{568}< [initial] [rendered] split chunk (cache group: default) - > ./a ./index.js 1:0-47 - > ./a a - ./e.js 20 bytes [built] [code generated] - chunk (runtime: c) all-chunks/c.js (c) 116 bytes (javascript) 2.64 KiB (runtime) ={282}= ={568}= ={767}= ={769}= [entry] [rendered] - > ./c c - runtime modules 2.64 KiB 4 modules - ./c.js 116 bytes [built] [code generated] - chunk (runtime: a, b, c, main) all-chunks/568.js 20 bytes <{179}> <{282}> <{390}> <{767}> <{786}> <{794}> <{954}> ={128}= ={137}= ={282}= ={334}= ={383}= ={459}= ={767}= ={769}= ={954}= [initial] [rendered] split chunk (cache group: default) - > ./b ./index.js 2:0-47 - > ./c ./index.js 3:0-47 - > ./g ./a.js 6:0-47 - > ./b b - > ./c c - ./f.js 20 bytes [built] [code generated] - chunk (runtime: a, b, c, main) all-chunks/767.js 20 bytes <{179}> ={128}= ={282}= ={334}= ={383}= ={390}= ={459}= ={568}= ={769}= ={786}= ={794}= ={954}= >{137}< >{568}< [initial] [rendered] split chunk (cache group: default) - > ./a ./index.js 1:0-47 - > ./b ./index.js 2:0-47 - > ./c ./index.js 3:0-47 - > ./a a - > ./b b - > ./c c - ./d.js 20 bytes [built] [code generated] - chunk (runtime: c, main) all-chunks/769.js (id hint: vendors) 20 bytes <{179}> ={282}= ={383}= ={459}= ={568}= ={767}= [initial] [rendered] split chunk (cache group: defaultVendors) - > ./c ./index.js 3:0-47 - > ./c c - ./node_modules/z.js 20 bytes [built] [code generated] - chunk (runtime: a) all-chunks/a.js (a) 165 bytes (javascript) 7.45 KiB (runtime) ={282}= ={390}= ={767}= ={954}= >{137}< >{568}< [entry] [rendered] - > ./a a - runtime modules 7.45 KiB 10 modules - ./a.js 165 bytes [built] [code generated] - chunk (runtime: main) all-chunks/async-a.js (async-a) 165 bytes <{179}> ={282}= ={390}= ={767}= ={954}= >{137}< >{568}< [rendered] - > ./a ./index.js 1:0-47 - ./a.js 165 bytes [built] [code generated] - chunk (runtime: a, b, main) all-chunks/954.js (id hint: vendors) 20 bytes <{179}> ={128}= ={282}= ={334}= ={390}= ={568}= ={767}= ={786}= ={794}= >{137}< >{568}< [initial] [rendered] split chunk (cache group: defaultVendors) - > ./a ./index.js 1:0-47 - > ./b ./index.js 2:0-47 - > ./a a - > ./b b - ./node_modules/y.js 20 bytes [built] [code generated] - all-chunks (webpack x.x.x) compiled successfully - -manual: - Entrypoint main 11.1 KiB = manual/main.js - Entrypoint a 14.6 KiB = manual/vendors.js 1.08 KiB manual/a.js 13.5 KiB - Entrypoint b 8.31 KiB = manual/vendors.js 1.08 KiB manual/b.js 7.23 KiB - Entrypoint c 8.31 KiB = manual/vendors.js 1.08 KiB manual/c.js 7.23 KiB - chunk (runtime: b) manual/b.js (b) 156 bytes (javascript) 2.64 KiB (runtime) ={216}= [entry] [rendered] - > ./b b - > x b - > y b - > z b - runtime modules 2.64 KiB 4 modules - dependent modules 40 bytes [dependent] 2 modules - ./b.js 116 bytes [built] [code generated] - chunk (runtime: a, main) manual/async-g.js (async-g) 65 bytes <{216}> <{786}> <{794}> [rendered] - > ./g ./a.js 6:0-47 - dependent modules 20 bytes [dependent] 1 module - ./g.js 45 bytes [built] [code generated] - chunk (runtime: main) manual/main.js (main) 147 bytes (javascript) 6.59 KiB (runtime) >{216}< >{334}< >{383}< >{794}< [entry] [rendered] - > ./ main - runtime modules 6.59 KiB 9 modules - ./index.js 147 bytes [built] [code generated] - chunk (runtime: a, b, c, main) manual/vendors.js (vendors) (id hint: vendors) 60 bytes <{179}> ={128}= ={334}= ={383}= ={459}= ={786}= ={794}= >{137}< [initial] [rendered] split chunk (cache group: vendors) (name: vendors) - > ./a ./index.js 1:0-47 - > ./b ./index.js 2:0-47 - > ./c ./index.js 3:0-47 - > ./a a - > x a - > y a - > z a - > ./b b - > x b - > y b - > z b - > ./c c - > x c - > y c - > z c - ./node_modules/x.js 20 bytes [built] [code generated] - ./node_modules/y.js 20 bytes [built] [code generated] - ./node_modules/z.js 20 bytes [built] [code generated] - chunk (runtime: main) manual/async-b.js (async-b) 156 bytes <{179}> ={216}= [rendered] - > ./b ./index.js 2:0-47 - dependent modules 40 bytes [dependent] 2 modules - ./b.js 116 bytes [built] [code generated] - chunk (runtime: main) manual/async-c.js (async-c) 156 bytes <{179}> ={216}= [rendered] - > ./c ./index.js 3:0-47 - dependent modules 40 bytes [dependent] 2 modules - ./c.js 116 bytes [built] [code generated] - chunk (runtime: c) manual/c.js (c) 156 bytes (javascript) 2.64 KiB (runtime) ={216}= [entry] [rendered] - > ./c c - > x c - > y c - > z c - runtime modules 2.64 KiB 4 modules - dependent modules 40 bytes [dependent] 2 modules - ./c.js 116 bytes [built] [code generated] - chunk (runtime: a) manual/a.js (a) 205 bytes (javascript) 7.42 KiB (runtime) ={216}= >{137}< [entry] [rendered] - > ./a a - > x a - > y a - > z a - runtime modules 7.42 KiB 10 modules - dependent modules 20 bytes [dependent] 1 module - ./a.js + 1 modules 185 bytes [built] [code generated] - chunk (runtime: main) manual/async-a.js (async-a) 205 bytes <{179}> ={216}= >{137}< [rendered] - > ./a ./index.js 1:0-47 - dependent modules 20 bytes [dependent] 1 module - ./a.js + 1 modules 185 bytes [built] [code generated] - manual (webpack x.x.x) compiled successfully - -name-too-long: - Entrypoint main 11.4 KiB = name-too-long/main.js - Entrypoint aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 14.8 KiB = name-too-long/282.js 414 bytes name-too-long/954.js 414 bytes name-too-long/767.js 414 bytes name-too-long/390.js 414 bytes name-too-long/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.js 13.2 KiB - Entrypoint bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb 7.97 KiB = name-too-long/282.js 414 bytes name-too-long/954.js 414 bytes name-too-long/767.js 414 bytes name-too-long/568.js 414 bytes name-too-long/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.js 6.35 KiB - Entrypoint cccccccccccccccccccccccccccccc 7.97 KiB = name-too-long/282.js 414 bytes name-too-long/769.js 414 bytes name-too-long/767.js 414 bytes name-too-long/568.js 414 bytes name-too-long/cccccccccccccccccccccccccccccc.js 6.35 KiB - chunk (runtime: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, main) name-too-long/async-g.js (async-g) 45 bytes <{282}> <{390}> <{751}> <{767}> <{794}> <{954}> ={568}= [rendered] - > ./g ./a.js 6:0-47 - ./g.js 45 bytes [built] [code generated] - chunk (runtime: main) name-too-long/main.js (main) 147 bytes (javascript) 6.59 KiB (runtime) >{282}< >{334}< >{383}< >{390}< >{568}< >{767}< >{769}< >{794}< >{954}< [entry] [rendered] - > ./ main - runtime modules 6.59 KiB 9 modules - ./index.js 147 bytes [built] [code generated] - chunk (runtime: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb, cccccccccccccccccccccccccccccc, main) name-too-long/282.js (id hint: vendors) 20 bytes <{179}> ={334}= ={383}= ={390}= ={568}= ={658}= ={751}= ={766}= ={767}= ={769}= ={794}= ={954}= >{137}< >{568}< [initial] [rendered] split chunk (cache group: defaultVendors) - > ./a ./index.js 1:0-47 - > ./b ./index.js 2:0-47 - > ./c ./index.js 3:0-47 - > ./a aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa - > ./b bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb - > ./c cccccccccccccccccccccccccccccc - ./node_modules/x.js 20 bytes [built] [code generated] - chunk (runtime: main) name-too-long/async-b.js (async-b) 116 bytes <{179}> ={282}= ={568}= ={767}= ={954}= [rendered] - > ./b ./index.js 2:0-47 - ./b.js 116 bytes [built] [code generated] - chunk (runtime: main) name-too-long/async-c.js (async-c) 116 bytes <{179}> ={282}= ={568}= ={767}= ={769}= [rendered] - > ./c ./index.js 3:0-47 - ./c.js 116 bytes [built] [code generated] - chunk (runtime: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, main) name-too-long/390.js 20 bytes <{179}> ={282}= ={751}= ={767}= ={794}= ={954}= >{137}< >{568}< [initial] [rendered] split chunk (cache group: default) - > ./a ./index.js 1:0-47 - > ./a aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa - ./e.js 20 bytes [built] [code generated] - chunk (runtime: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb, cccccccccccccccccccccccccccccc, main) name-too-long/568.js 20 bytes <{179}> <{282}> <{390}> <{751}> <{767}> <{794}> <{954}> ={137}= ={282}= ={334}= ={383}= ={658}= ={766}= ={767}= ={769}= ={954}= [initial] [rendered] split chunk (cache group: default) - > ./b ./index.js 2:0-47 - > ./c ./index.js 3:0-47 - > ./g ./a.js 6:0-47 - > ./b bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb - > ./c cccccccccccccccccccccccccccccc - ./f.js 20 bytes [built] [code generated] - chunk (runtime: cccccccccccccccccccccccccccccc) name-too-long/cccccccccccccccccccccccccccccc.js (cccccccccccccccccccccccccccccc) 116 bytes (javascript) 2.64 KiB (runtime) ={282}= ={568}= ={767}= ={769}= [entry] [rendered] - > ./c cccccccccccccccccccccccccccccc - runtime modules 2.64 KiB 4 modules - ./c.js 116 bytes [built] [code generated] - chunk (runtime: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa) name-too-long/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.js (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa) 165 bytes (javascript) 7.46 KiB (runtime) ={282}= ={390}= ={767}= ={954}= >{137}< >{568}< [entry] [rendered] - > ./a aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa - runtime modules 7.46 KiB 10 modules - ./a.js 165 bytes [built] [code generated] - chunk (runtime: bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb) name-too-long/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.js (bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb) 116 bytes (javascript) 2.64 KiB (runtime) ={282}= ={568}= ={767}= ={954}= [entry] [rendered] - > ./b bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb - runtime modules 2.64 KiB 4 modules - ./b.js 116 bytes [built] [code generated] - chunk (runtime: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb, cccccccccccccccccccccccccccccc, main) name-too-long/767.js 20 bytes <{179}> ={282}= ={334}= ={383}= ={390}= ={568}= ={658}= ={751}= ={766}= ={769}= ={794}= ={954}= >{137}< >{568}< [initial] [rendered] split chunk (cache group: default) - > ./a ./index.js 1:0-47 - > ./b ./index.js 2:0-47 - > ./c ./index.js 3:0-47 - > ./a aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa - > ./b bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb - > ./c cccccccccccccccccccccccccccccc - ./d.js 20 bytes [built] [code generated] - chunk (runtime: cccccccccccccccccccccccccccccc, main) name-too-long/769.js (id hint: vendors) 20 bytes <{179}> ={282}= ={383}= ={568}= ={658}= ={767}= [initial] [rendered] split chunk (cache group: defaultVendors) - > ./c ./index.js 3:0-47 - > ./c cccccccccccccccccccccccccccccc - ./node_modules/z.js 20 bytes [built] [code generated] - chunk (runtime: main) name-too-long/async-a.js (async-a) 165 bytes <{179}> ={282}= ={390}= ={767}= ={954}= >{137}< >{568}< [rendered] - > ./a ./index.js 1:0-47 - ./a.js 165 bytes [built] [code generated] - chunk (runtime: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb, main) name-too-long/954.js (id hint: vendors) 20 bytes <{179}> ={282}= ={334}= ={390}= ={568}= ={751}= ={766}= ={767}= ={794}= >{137}< >{568}< [initial] [rendered] split chunk (cache group: defaultVendors) - > ./a ./index.js 1:0-47 - > ./b ./index.js 2:0-47 - > ./a aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa - > ./b bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb - ./node_modules/y.js 20 bytes [built] [code generated] - name-too-long (webpack x.x.x) compiled successfully - -custom-chunks-filter: - Entrypoint main 11.4 KiB = custom-chunks-filter/main.js - Entrypoint a 12.5 KiB = custom-chunks-filter/a.js - Entrypoint b 7.97 KiB = custom-chunks-filter/282.js 414 bytes custom-chunks-filter/954.js 414 bytes custom-chunks-filter/568.js 414 bytes custom-chunks-filter/767.js 414 bytes custom-chunks-filter/b.js 6.35 KiB - Entrypoint c 7.97 KiB = custom-chunks-filter/282.js 414 bytes custom-chunks-filter/769.js 414 bytes custom-chunks-filter/568.js 414 bytes custom-chunks-filter/767.js 414 bytes custom-chunks-filter/c.js 6.35 KiB - chunk (runtime: b) custom-chunks-filter/b.js (b) 116 bytes (javascript) 2.64 KiB (runtime) ={282}= ={568}= ={767}= ={954}= [entry] [rendered] - > ./b b - runtime modules 2.64 KiB 4 modules - ./b.js 116 bytes [built] [code generated] - chunk (runtime: a, main) custom-chunks-filter/async-g.js (async-g) 45 bytes <{282}> <{767}> <{786}> <{794}> <{954}> ={568}= [rendered] - > ./g ./a.js 6:0-47 - ./g.js 45 bytes [built] [code generated] - chunk (runtime: main) custom-chunks-filter/main.js (main) 147 bytes (javascript) 6.6 KiB (runtime) >{282}< >{334}< >{383}< >{568}< >{767}< >{769}< >{794}< >{954}< [entry] [rendered] - > ./ main - runtime modules 6.6 KiB 9 modules - ./index.js 147 bytes [built] [code generated] - chunk (runtime: b, c, main) custom-chunks-filter/282.js (id hint: vendors) 20 bytes <{179}> ={128}= ={334}= ={383}= ={459}= ={568}= ={767}= ={769}= ={794}= ={954}= >{137}< >{568}< [initial] [rendered] split chunk (cache group: defaultVendors) - > ./a ./index.js 1:0-47 - > ./b ./index.js 2:0-47 - > ./c ./index.js 3:0-47 - > ./b b - > ./c c - ./node_modules/x.js 20 bytes [built] [code generated] - chunk (runtime: main) custom-chunks-filter/async-b.js (async-b) 116 bytes <{179}> ={282}= ={568}= ={767}= ={954}= [rendered] - > ./b ./index.js 2:0-47 - ./b.js 116 bytes [built] [code generated] - chunk (runtime: main) custom-chunks-filter/async-c.js (async-c) 116 bytes <{179}> ={282}= ={568}= ={767}= ={769}= [rendered] - > ./c ./index.js 3:0-47 - ./c.js 116 bytes [built] [code generated] - chunk (runtime: c) custom-chunks-filter/c.js (c) 116 bytes (javascript) 2.64 KiB (runtime) ={282}= ={568}= ={767}= ={769}= [entry] [rendered] - > ./c c - runtime modules 2.64 KiB 4 modules - ./c.js 116 bytes [built] [code generated] - chunk (runtime: a, b, c, main) custom-chunks-filter/568.js 20 bytes <{179}> <{282}> <{767}> <{786}> <{794}> <{954}> ={128}= ={137}= ={282}= ={334}= ={383}= ={459}= ={767}= ={769}= ={954}= [initial] [rendered] split chunk (cache group: default) - > ./b ./index.js 2:0-47 - > ./c ./index.js 3:0-47 - > ./g ./a.js 6:0-47 - > ./b b - > ./c c - ./f.js 20 bytes [built] [code generated] - chunk (runtime: b, c, main) custom-chunks-filter/767.js 20 bytes <{179}> ={128}= ={282}= ={334}= ={383}= ={459}= ={568}= ={769}= ={794}= ={954}= >{137}< >{568}< [initial] [rendered] split chunk (cache group: default) - > ./a ./index.js 1:0-47 - > ./b ./index.js 2:0-47 - > ./c ./index.js 3:0-47 - > ./b b - > ./c c - ./d.js 20 bytes [built] [code generated] - chunk (runtime: c, main) custom-chunks-filter/769.js (id hint: vendors) 20 bytes <{179}> ={282}= ={383}= ={459}= ={568}= ={767}= [initial] [rendered] split chunk (cache group: defaultVendors) - > ./c ./index.js 3:0-47 - > ./c c - ./node_modules/z.js 20 bytes [built] [code generated] - chunk (runtime: a) custom-chunks-filter/a.js (a) 245 bytes (javascript) 6.59 KiB (runtime) >{137}< >{568}< [entry] [rendered] - > ./a a - runtime modules 6.59 KiB 9 modules - dependent modules 60 bytes [dependent] 3 modules - ./a.js + 1 modules 185 bytes [built] [code generated] - chunk (runtime: main) custom-chunks-filter/async-a.js (async-a) 185 bytes <{179}> ={282}= ={767}= ={954}= >{137}< >{568}< [rendered] - > ./a ./index.js 1:0-47 - ./a.js + 1 modules 185 bytes [built] [code generated] - chunk (runtime: b, main) custom-chunks-filter/954.js (id hint: vendors) 20 bytes <{179}> ={128}= ={282}= ={334}= ={568}= ={767}= ={794}= >{137}< >{568}< [initial] [rendered] split chunk (cache group: defaultVendors) - > ./a ./index.js 1:0-47 - > ./b ./index.js 2:0-47 - > ./b b - ./node_modules/y.js 20 bytes [built] [code generated] - custom-chunks-filter (webpack x.x.x) compiled successfully - -custom-chunks-filter-in-cache-groups: - Entrypoint main 11.2 KiB = custom-chunks-filter-in-cache-groups/main.js - Entrypoint a 14.4 KiB = custom-chunks-filter-in-cache-groups/176.js 892 bytes custom-chunks-filter-in-cache-groups/a.js 13.6 KiB - Entrypoint b 8.31 KiB = custom-chunks-filter-in-cache-groups/vendors.js 1.08 KiB custom-chunks-filter-in-cache-groups/b.js 7.23 KiB - Entrypoint c 8.31 KiB = custom-chunks-filter-in-cache-groups/vendors.js 1.08 KiB custom-chunks-filter-in-cache-groups/c.js 7.23 KiB - chunk (runtime: b) custom-chunks-filter-in-cache-groups/b.js (b) 156 bytes (javascript) 2.64 KiB (runtime) ={216}= [entry] [rendered] - > ./b b - > x b - > y b - > z b - runtime modules 2.64 KiB 4 modules - dependent modules 40 bytes [dependent] 2 modules - ./b.js 116 bytes [built] [code generated] - chunk (runtime: a, main) custom-chunks-filter-in-cache-groups/async-g.js (async-g) 65 bytes <{176}> <{216}> <{786}> <{794}> [rendered] - > ./g ./a.js 6:0-47 - dependent modules 20 bytes [dependent] 1 module - ./g.js 45 bytes [built] [code generated] - chunk (runtime: a) custom-chunks-filter-in-cache-groups/176.js (id hint: vendors) 60 bytes ={786}= >{137}< [initial] [rendered] split chunk (cache group: defaultVendors) - > ./a a - > x a - > y a - > z a - ./node_modules/x.js 20 bytes [built] [code generated] - ./node_modules/y.js 20 bytes [built] [code generated] - ./node_modules/z.js 20 bytes [built] [code generated] - chunk (runtime: main) custom-chunks-filter-in-cache-groups/main.js (main) 147 bytes (javascript) 6.62 KiB (runtime) >{216}< >{334}< >{383}< >{794}< [entry] [rendered] - > ./ main - runtime modules 6.62 KiB 9 modules - ./index.js 147 bytes [built] [code generated] - chunk (runtime: b, c, main) custom-chunks-filter-in-cache-groups/vendors.js (vendors) (id hint: vendors) 60 bytes <{179}> ={128}= ={334}= ={383}= ={459}= ={794}= >{137}< [initial] [rendered] split chunk (cache group: vendors) (name: vendors) - > ./a ./index.js 1:0-47 - > ./b ./index.js 2:0-47 - > ./c ./index.js 3:0-47 - > ./b b - > x b - > y b - > z b - > ./c c - > x c - > y c - > z c - ./node_modules/x.js 20 bytes [built] [code generated] - ./node_modules/y.js 20 bytes [built] [code generated] - ./node_modules/z.js 20 bytes [built] [code generated] - chunk (runtime: main) custom-chunks-filter-in-cache-groups/async-b.js (async-b) 156 bytes <{179}> ={216}= [rendered] - > ./b ./index.js 2:0-47 - dependent modules 40 bytes [dependent] 2 modules - ./b.js 116 bytes [built] [code generated] - chunk (runtime: main) custom-chunks-filter-in-cache-groups/async-c.js (async-c) 156 bytes <{179}> ={216}= [rendered] - > ./c ./index.js 3:0-47 - dependent modules 40 bytes [dependent] 2 modules - ./c.js 116 bytes [built] [code generated] - chunk (runtime: c) custom-chunks-filter-in-cache-groups/c.js (c) 156 bytes (javascript) 2.64 KiB (runtime) ={216}= [entry] [rendered] - > ./c c - > x c - > y c - > z c - runtime modules 2.64 KiB 4 modules - dependent modules 40 bytes [dependent] 2 modules - ./c.js 116 bytes [built] [code generated] - chunk (runtime: a) custom-chunks-filter-in-cache-groups/a.js (a) 205 bytes (javascript) 7.45 KiB (runtime) ={176}= >{137}< [entry] [rendered] - > ./a a - > x a - > y a - > z a - runtime modules 7.45 KiB 10 modules - dependent modules 20 bytes [dependent] 1 module - ./a.js + 1 modules 185 bytes [built] [code generated] - chunk (runtime: main) custom-chunks-filter-in-cache-groups/async-a.js (async-a) 205 bytes <{179}> ={216}= >{137}< [rendered] - > ./a ./index.js 1:0-47 - dependent modules 20 bytes [dependent] 1 module - ./a.js + 1 modules 185 bytes [built] [code generated] - custom-chunks-filter-in-cache-groups (webpack x.x.x) compiled successfully" -`; - -exports[`StatsTestCases should print correct stats for split-chunks-automatic-name 1`] = ` -"Entrypoint main 11.5 KiB = main.js -chunk (runtime: main) async-a.js (async-a) 136 bytes <{main}> ={common-d_js}= ={common-node_modules_x_js}= ={common-node_modules_y_js}= [rendered] - > ./a ./index.js 1:0-47 - ./a.js + 1 modules 136 bytes [built] [code generated] -chunk (runtime: main) async-b.js (async-b) 116 bytes <{main}> ={common-d_js}= ={common-f_js}= ={common-node_modules_x_js}= ={common-node_modules_y_js}= [rendered] - > ./b ./index.js 2:0-47 - ./b.js 116 bytes [built] [code generated] -chunk (runtime: main) async-c.js (async-c) 116 bytes <{main}> ={common-d_js}= ={common-f_js}= ={common-node_modules_x_js}= ={common-node_modules_z_js}= [rendered] - > ./c ./index.js 3:0-47 - ./c.js 116 bytes [built] [code generated] -chunk (runtime: main) common-d_js.js (id hint: common) 20 bytes <{main}> ={async-a}= ={async-b}= ={async-c}= ={common-f_js}= ={common-node_modules_x_js}= ={common-node_modules_y_js}= ={common-node_modules_z_js}= [rendered] split chunk (cache group: a) - > ./a ./index.js 1:0-47 - > ./b ./index.js 2:0-47 - > ./c ./index.js 3:0-47 - ./d.js 20 bytes [built] [code generated] -chunk (runtime: main) common-f_js.js (id hint: common) 20 bytes <{main}> ={async-b}= ={async-c}= ={common-d_js}= ={common-node_modules_x_js}= ={common-node_modules_y_js}= ={common-node_modules_z_js}= [rendered] split chunk (cache group: a) - > ./b ./index.js 2:0-47 - > ./c ./index.js 3:0-47 - ./f.js 20 bytes [built] [code generated] -chunk (runtime: main) common-node_modules_x_js.js (id hint: common) 20 bytes <{main}> ={async-a}= ={async-b}= ={async-c}= ={common-d_js}= ={common-f_js}= ={common-node_modules_y_js}= ={common-node_modules_z_js}= [rendered] split chunk (cache group: b) - > ./a ./index.js 1:0-47 - > ./b ./index.js 2:0-47 - > ./c ./index.js 3:0-47 - ./node_modules/x.js 20 bytes [built] [code generated] -chunk (runtime: main) common-node_modules_y_js.js (id hint: common) 20 bytes <{main}> ={async-a}= ={async-b}= ={common-d_js}= ={common-f_js}= ={common-node_modules_x_js}= [rendered] split chunk (cache group: b) - > ./a ./index.js 1:0-47 - > ./b ./index.js 2:0-47 - ./node_modules/y.js 20 bytes [built] [code generated] -chunk (runtime: main) common-node_modules_z_js.js (id hint: common) 20 bytes <{main}> ={async-c}= ={common-d_js}= ={common-f_js}= ={common-node_modules_x_js}= [rendered] split chunk (cache group: b) - > ./c ./index.js 3:0-47 - ./node_modules/z.js 20 bytes [built] [code generated] -chunk (runtime: main) main.js (main) 147 bytes (javascript) 6.49 KiB (runtime) >{async-a}< >{async-b}< >{async-c}< >{common-d_js}< >{common-f_js}< >{common-node_modules_x_js}< >{common-node_modules_y_js}< >{common-node_modules_z_js}< [entry] [rendered] - > ./ main - runtime modules 6.49 KiB 9 modules - ./index.js 147 bytes [built] [code generated] -production (webpack x.x.x) compiled successfully" -`; - -exports[`StatsTestCases should print correct stats for split-chunks-chunk-name 1`] = ` -"Entrypoint main 11.1 KiB = default/main.js -chunk (runtime: main) default/main.js (main) 192 bytes (javascript) 6.56 KiB (runtime) >{334}< >{709}< >{794}< [entry] [rendered] - > ./ main - runtime modules 6.56 KiB 9 modules - ./index.js 192 bytes [built] [code generated] -chunk (runtime: main) default/async-b.js (async-b) (id hint: vendors) 122 bytes <{179}> [rendered] reused as split chunk (cache group: defaultVendors) - > b ./index.js 2:0-45 - ./node_modules/b.js 122 bytes [built] [code generated] -chunk (runtime: main) default/async-c-1.js (async-c-1) (id hint: vendors) 122 bytes <{179}> [rendered] reused as split chunk (cache group: defaultVendors) - > c ./index.js 3:0-47 - > c ./index.js 4:0-47 - ./node_modules/c.js 122 bytes [built] [code generated] -chunk (runtime: main) default/async-a.js (async-a) 20 bytes <{179}> [rendered] - > a ./index.js 1:0-45 - ./node_modules/a.js 20 bytes [built] [code generated] -webpack x.x.x compiled successfully" -`; - -exports[`StatsTestCases should print correct stats for split-chunks-combinations 1`] = ` -"Entrypoint main 11.6 KiB = main.js -chunk (runtime: main) async-d.js (async-d) 132 bytes <{179}> [rendered] - > ./d ./index.js 4:0-47 - dependent modules 87 bytes [dependent] 1 module - ./d.js 45 bytes [built] [code generated] -chunk (runtime: main) async-g.js (async-g) 132 bytes <{179}> [rendered] - > ./g ./index.js 7:0-47 - dependent modules 87 bytes [dependent] 1 module - ./g.js 45 bytes [built] [code generated] -chunk (runtime: main) main.js (main) 343 bytes (javascript) 6.62 KiB (runtime) >{31}< >{137}< >{206}< >{334}< >{383}< >{449}< >{794}< >{804}< [entry] [rendered] - > ./ main - runtime modules 6.62 KiB 9 modules - ./index.js 343 bytes [built] [code generated] -chunk (runtime: main) async-f.js (async-f) 132 bytes <{179}> [rendered] - > ./f ./index.js 6:0-47 - dependent modules 87 bytes [dependent] 1 module - ./f.js 45 bytes [built] [code generated] -chunk (runtime: main) async-b.js (async-b) 70 bytes <{179}> ={804}= [rendered] - > ./b ./index.js 2:0-47 - ./b.js 70 bytes [built] [code generated] -chunk (runtime: main) async-c.js (async-c) 132 bytes <{179}> [rendered] - > ./c ./index.js 3:0-47 - dependent modules 87 bytes [dependent] 1 module - ./c.js 45 bytes [built] [code generated] -chunk (runtime: main) async-e.js (async-e) 132 bytes <{179}> [rendered] - > ./e ./index.js 5:0-47 - dependent modules 87 bytes [dependent] 1 module - ./e.js 45 bytes [built] [code generated] -chunk (runtime: main) async-a.js (async-a) 70 bytes <{179}> ={804}= [rendered] - > ./a ./index.js 1:0-47 - ./a.js 70 bytes [built] [code generated] -chunk (runtime: main) 804.js 174 bytes <{179}> ={334}= ={794}= [rendered] split chunk (cache group: default) - > ./a ./index.js 1:0-47 - > ./b ./index.js 2:0-47 - ./x.js 87 bytes [built] [code generated] - ./y.js 87 bytes [built] [code generated] -webpack x.x.x compiled successfully" -`; - -exports[`StatsTestCases should print correct stats for split-chunks-issue-6413 1`] = ` -"Entrypoint main 11.2 KiB = main.js -chunk (runtime: main) main.js (main) 147 bytes (javascript) 6.55 KiB (runtime) >{282}< >{334}< >{383}< >{543}< >{794}< [entry] [rendered] - > ./ main - runtime modules 6.55 KiB 9 modules - ./index.js 147 bytes [built] [code generated] -chunk (runtime: main) 282.js (id hint: vendors) 20 bytes <{179}> ={334}= ={383}= ={543}= ={794}= [rendered] split chunk (cache group: defaultVendors) - > ./a ./index.js 1:0-47 - > ./b ./index.js 2:0-47 - > ./c ./index.js 3:0-47 - ./node_modules/x.js 20 bytes [built] [code generated] -chunk (runtime: main) async-b.js (async-b) 36 bytes <{179}> ={282}= ={543}= [rendered] - > ./b ./index.js 2:0-47 - ./b.js 36 bytes [built] [code generated] -chunk (runtime: main) async-c.js (async-c) 36 bytes <{179}> ={282}= ={543}= [rendered] - > ./c ./index.js 3:0-47 - ./c.js 36 bytes [built] [code generated] -chunk (runtime: main) 543.js 45 bytes <{179}> ={282}= ={334}= ={383}= ={794}= [rendered] split chunk (cache group: default) - > ./a ./index.js 1:0-47 - > ./b ./index.js 2:0-47 - > ./c ./index.js 3:0-47 - ./common.js 45 bytes [built] [code generated] -chunk (runtime: main) async-a.js (async-a) 36 bytes <{179}> ={282}= ={543}= [rendered] - > ./a ./index.js 1:0-47 - ./a.js 36 bytes [built] [code generated] -default (webpack x.x.x) compiled successfully" -`; - -exports[`StatsTestCases should print correct stats for split-chunks-issue-6696 1`] = ` -"Entrypoint main 13.2 KiB = vendors.js 414 bytes main.js 12.8 KiB -chunk (runtime: main) main.js (main) 134 bytes (javascript) 7.43 KiB (runtime) ={216}= >{334}< >{794}< [entry] [rendered] - > ./ main - runtime modules 7.43 KiB 10 modules - ./index.js 134 bytes [built] [code generated] -chunk (runtime: main) vendors.js (vendors) (id hint: vendors) 20 bytes ={179}= >{334}< >{794}< [initial] [rendered] split chunk (cache group: vendors) (name: vendors) - > ./ main - ./node_modules/y.js 20 bytes [built] [code generated] -chunk (runtime: main) async-b.js (async-b) 49 bytes <{179}> <{216}> [rendered] - > ./b ./index.js 3:0-47 - dependent modules 20 bytes [dependent] 1 module - ./b.js 29 bytes [built] [code generated] -chunk (runtime: main) async-a.js (async-a) 49 bytes <{179}> <{216}> [rendered] - > ./a ./index.js 2:0-47 - dependent modules 20 bytes [dependent] 1 module - ./a.js 29 bytes [built] [code generated] -default (webpack x.x.x) compiled successfully" -`; - -exports[`StatsTestCases should print correct stats for split-chunks-issue-7401 1`] = ` -"Entrypoint a 6.27 KiB = 282.js 414 bytes a.js 5.86 KiB -Entrypoint b 10.8 KiB = b.js -Chunk Group c 794 bytes = 282.js 414 bytes c.js 380 bytes -chunk (runtime: b) b.js (b) 43 bytes (javascript) 6.52 KiB (runtime) >{282}< >{459}< [entry] [rendered] - > ./b b - runtime modules 6.52 KiB 9 modules - ./b.js 43 bytes [built] [code generated] -chunk (runtime: a, b) 282.js (id hint: vendors) 20 bytes <{128}> ={459}= ={786}= [initial] [rendered] split chunk (cache group: defaultVendors) - > ./c ./b.js 1:0-41 - > ./a a - ./node_modules/x.js 20 bytes [built] [code generated] -chunk (runtime: b) c.js (c) 35 bytes <{128}> ={282}= [rendered] - > ./c ./b.js 1:0-41 - ./c.js 35 bytes [built] [code generated] -chunk (runtime: a) a.js (a) 35 bytes (javascript) 2.63 KiB (runtime) ={282}= [entry] [rendered] - > ./a a - runtime modules 2.63 KiB 4 modules - ./a.js 35 bytes [built] [code generated] -default (webpack x.x.x) compiled successfully" -`; - -exports[`StatsTestCases should print correct stats for split-chunks-keep-remaining-size 1`] = ` -"Entrypoint main 11.2 KiB = default/main.js -chunk (runtime: main) default/async-d.js (async-d) 84 bytes <{179}> ={782}= [rendered] - > ./d ./index.js 4:0-47 - ./d.js 84 bytes [built] [code generated] -chunk (runtime: main) default/main.js (main) 196 bytes (javascript) 6.58 KiB (runtime) >{31}< >{334}< >{383}< >{782}< >{794}< >{821}< [entry] [rendered] - > ./ main - runtime modules 6.58 KiB 9 modules - ./index.js 196 bytes [built] [code generated] -chunk (runtime: main) default/async-b.js (async-b) 50 bytes <{179}> ={821}= [rendered] - > ./b ./index.js 2:0-47 - ./b.js 50 bytes [built] [code generated] -chunk (runtime: main) default/async-c.js (async-c) 50 bytes <{179}> ={821}= [rendered] - > ./c ./index.js 3:0-47 - ./c.js 50 bytes [built] [code generated] -chunk (runtime: main) default/782.js (id hint: vendors) 252 bytes <{179}> ={31}= [rendered] split chunk (cache group: defaultVendors) - > ./d ./index.js 4:0-47 - ./node_modules/shared.js?3 126 bytes [built] [code generated] - ./node_modules/shared.js?4 126 bytes [built] [code generated] -chunk (runtime: main) default/async-a.js (async-a) 176 bytes <{179}> [rendered] - > ./a ./index.js 1:0-47 - ./a.js + 1 modules 176 bytes [built] [code generated] -chunk (runtime: main) default/821.js (id hint: vendors) 126 bytes <{179}> ={334}= ={383}= [rendered] split chunk (cache group: defaultVendors) - > ./b ./index.js 2:0-47 - > ./c ./index.js 3:0-47 - ./node_modules/shared.js?2 126 bytes [built] [code generated] -webpack x.x.x compiled successfully" -`; - -exports[`StatsTestCases should print correct stats for split-chunks-max-size 1`] = ` -"production: - Entrypoint main 31.7 KiB = 13 assets - chunk (runtime: main) prod-main-6bb16544.js (main-6bb16544) 1.57 KiB ={59}= ={198}= ={204}= ={318}= ={358}= ={400}= ={410}= ={490}= ={520}= ={662}= ={663}= ={869}= [initial] [rendered] - > ./ main - ./in-some-directory/very-big.js?1 1.57 KiB [built] [code generated] - chunk (runtime: main) prod-main-77a8c116.js (main-77a8c116) 1.57 KiB ={1}= ={198}= ={204}= ={318}= ={358}= ={400}= ={410}= ={490}= ={520}= ={662}= ={663}= ={869}= [initial] [rendered] - > ./ main - ./very-big.js?2 1.57 KiB [built] [code generated] - chunk (runtime: main) prod-main-3c98d7c3.js (main-3c98d7c3) 531 bytes ={1}= ={59}= ={204}= ={318}= ={358}= ={400}= ={410}= ={490}= ={520}= ={662}= ={663}= ={869}= [initial] [rendered] - > ./ main - ./in-some-directory/big.js?1 267 bytes [built] [code generated] - ./in-some-directory/small.js?1 66 bytes [built] [code generated] - ./in-some-directory/small.js?2 66 bytes [built] [code generated] - ./in-some-directory/small.js?3 66 bytes [built] [code generated] - ./in-some-directory/small.js?4 66 bytes [built] [code generated] - chunk (runtime: main) prod-main-2f7dcf2e.js (main-2f7dcf2e) 594 bytes ={1}= ={59}= ={198}= ={318}= ={358}= ={400}= ={410}= ={490}= ={520}= ={662}= ={663}= ={869}= [initial] [rendered] - > ./ main - ./inner-module/small.js?1 66 bytes [built] [code generated] - ./inner-module/small.js?2 66 bytes [built] [code generated] - ./inner-module/small.js?3 66 bytes [built] [code generated] - ./inner-module/small.js?4 66 bytes [built] [code generated] - ./inner-module/small.js?5 66 bytes [built] [code generated] - ./inner-module/small.js?6 66 bytes [built] [code generated] - ./inner-module/small.js?7 66 bytes [built] [code generated] - ./inner-module/small.js?8 66 bytes [built] [code generated] - ./inner-module/small.js?9 66 bytes [built] [code generated] - chunk (runtime: main) prod-main-89a43a0f.js (main-89a43a0f) 1.57 KiB ={1}= ={59}= ={198}= ={204}= ={358}= ={400}= ={410}= ={490}= ={520}= ={662}= ={663}= ={869}= [initial] [rendered] - > ./ main - ./very-big.js?3 1.57 KiB [built] [code generated] - chunk (runtime: main) prod-main-e7c5ace7.js (main-e7c5ace7) 594 bytes ={1}= ={59}= ={198}= ={204}= ={318}= ={400}= ={410}= ={490}= ={520}= ={662}= ={663}= ={869}= [initial] [rendered] - > ./ main - ./small.js?1 66 bytes [built] [code generated] - ./small.js?2 66 bytes [built] [code generated] - ./small.js?3 66 bytes [built] [code generated] - ./small.js?4 66 bytes [built] [code generated] - ./small.js?5 66 bytes [built] [code generated] - ./small.js?6 66 bytes [built] [code generated] - ./small.js?7 66 bytes [built] [code generated] - ./small.js?8 66 bytes [built] [code generated] - ./small.js?9 66 bytes [built] [code generated] - chunk (runtime: main) prod-main-1443e336.js (main-1443e336) 594 bytes ={1}= ={59}= ={198}= ={204}= ={318}= ={358}= ={410}= ={490}= ={520}= ={662}= ={663}= ={869}= [initial] [rendered] - > ./ main - ./subfolder/small.js?1 66 bytes [built] [code generated] - ./subfolder/small.js?2 66 bytes [built] [code generated] - ./subfolder/small.js?3 66 bytes [built] [code generated] - ./subfolder/small.js?4 66 bytes [built] [code generated] - ./subfolder/small.js?5 66 bytes [built] [code generated] - ./subfolder/small.js?6 66 bytes [built] [code generated] - ./subfolder/small.js?7 66 bytes [built] [code generated] - ./subfolder/small.js?8 66 bytes [built] [code generated] - ./subfolder/small.js?9 66 bytes [built] [code generated] - chunk (runtime: main) prod-410.js (id hint: vendors) 1.57 KiB ={1}= ={59}= ={198}= ={204}= ={318}= ={358}= ={400}= ={490}= ={520}= ={662}= ={663}= ={869}= [initial] [rendered] split chunk (cache group: defaultVendors) - > ./ main - ./node_modules/very-big.js?1 1.57 KiB [built] [code generated] - chunk (runtime: main) prod-main-5cfff2c6.js (main-5cfff2c6) 534 bytes ={1}= ={59}= ={198}= ={204}= ={318}= ={358}= ={400}= ={410}= ={520}= ={662}= ={663}= ={869}= [initial] [rendered] - > ./ main - ./subfolder/big.js?1 267 bytes [built] [code generated] - ./subfolder/big.js?2 267 bytes [built] [code generated] - chunk (runtime: main) prod-main-1df31ce3.js (main-1df31ce3) 1.19 KiB ={1}= ={59}= ={198}= ={204}= ={318}= ={358}= ={400}= ={410}= ={490}= ={662}= ={663}= ={869}= [initial] [rendered] - > ./ main - ./index.js 1.19 KiB [built] [code generated] - chunk (runtime: main) prod-main-10f51d07.js (main-10f51d07) 534 bytes ={1}= ={59}= ={198}= ={204}= ={318}= ={358}= ={400}= ={410}= ={490}= ={520}= ={663}= ={869}= [initial] [rendered] - > ./ main - ./big.js?1 267 bytes [built] [code generated] - ./big.js?2 267 bytes [built] [code generated] - chunk (runtime: main) prod-main-12217e1d.js (main-12217e1d) 1.57 KiB (javascript) 2.89 KiB (runtime) ={1}= ={59}= ={198}= ={204}= ={318}= ={358}= ={400}= ={410}= ={490}= ={520}= ={662}= ={869}= [entry] [rendered] - > ./ main - runtime modules 2.89 KiB 5 modules - ./very-big.js?1 1.57 KiB [built] [code generated] - chunk (runtime: main) prod-869.js (id hint: vendors) 399 bytes ={1}= ={59}= ={198}= ={204}= ={318}= ={358}= ={400}= ={410}= ={490}= ={520}= ={662}= ={663}= [initial] [rendered] split chunk (cache group: defaultVendors) - > ./ main - ./node_modules/big.js?1 267 bytes [built] [code generated] - ./node_modules/small.js?1 66 bytes [built] [code generated] - ./node_modules/small.js?2 66 bytes [built] [code generated] - production (webpack x.x.x) compiled successfully - -development: - Entrypoint main 50.2 KiB = 13 assets - chunk (runtime: main) dev-main-big_js-1.js (main-big_js-1) 534 bytes ={main-in-some-directory_b}= ={main-in-some-directory_very-big_js-8d76cf03}= ={main-index_js-41f5a26e}= ={main-inner-module_small_js-3}= ={main-small_js-1}= ={main-subfolder_big_js-b}= ={main-subfolder_small_js-1}= ={main-very-big_js-08cf55cf}= ={main-very-big_js-4647fb9d}= ={main-very-big_js-62f7f644}= ={vendors-node_modules_big_js_1-node_modules_small_js_1-node_modules_small_js_2}= ={vendors-node_modules_very-big_js_1}= [initial] [rendered] - > ./ main - ./big.js?1 267 bytes [built] [code generated] - ./big.js?2 267 bytes [built] [code generated] - chunk (runtime: main) dev-main-in-some-directory_b.js (main-in-some-directory_b) 531 bytes ={main-big_js-1}= ={main-in-some-directory_very-big_js-8d76cf03}= ={main-index_js-41f5a26e}= ={main-inner-module_small_js-3}= ={main-small_js-1}= ={main-subfolder_big_js-b}= ={main-subfolder_small_js-1}= ={main-very-big_js-08cf55cf}= ={main-very-big_js-4647fb9d}= ={main-very-big_js-62f7f644}= ={vendors-node_modules_big_js_1-node_modules_small_js_1-node_modules_small_js_2}= ={vendors-node_modules_very-big_js_1}= [initial] [rendered] - > ./ main - ./in-some-directory/big.js?1 267 bytes [built] [code generated] - ./in-some-directory/small.js?1 66 bytes [built] [code generated] - ./in-some-directory/small.js?2 66 bytes [built] [code generated] - ./in-some-directory/small.js?3 66 bytes [built] [code generated] - ./in-some-directory/small.js?4 66 bytes [built] [code generated] - chunk (runtime: main) dev-main-in-some-directory_very-big_js-8d76cf03.js (main-in-some-directory_very-big_js-8d76cf03) 1.57 KiB ={main-big_js-1}= ={main-in-some-directory_b}= ={main-index_js-41f5a26e}= ={main-inner-module_small_js-3}= ={main-small_js-1}= ={main-subfolder_big_js-b}= ={main-subfolder_small_js-1}= ={main-very-big_js-08cf55cf}= ={main-very-big_js-4647fb9d}= ={main-very-big_js-62f7f644}= ={vendors-node_modules_big_js_1-node_modules_small_js_1-node_modules_small_js_2}= ={vendors-node_modules_very-big_js_1}= [initial] [rendered] - > ./ main - ./in-some-directory/very-big.js?1 1.57 KiB [built] [code generated] - chunk (runtime: main) dev-main-index_js-41f5a26e.js (main-index_js-41f5a26e) 1.19 KiB ={main-big_js-1}= ={main-in-some-directory_b}= ={main-in-some-directory_very-big_js-8d76cf03}= ={main-inner-module_small_js-3}= ={main-small_js-1}= ={main-subfolder_big_js-b}= ={main-subfolder_small_js-1}= ={main-very-big_js-08cf55cf}= ={main-very-big_js-4647fb9d}= ={main-very-big_js-62f7f644}= ={vendors-node_modules_big_js_1-node_modules_small_js_1-node_modules_small_js_2}= ={vendors-node_modules_very-big_js_1}= [initial] [rendered] - > ./ main - ./index.js 1.19 KiB [built] [code generated] - chunk (runtime: main) dev-main-inner-module_small_js-3.js (main-inner-module_small_js-3) 594 bytes ={main-big_js-1}= ={main-in-some-directory_b}= ={main-in-some-directory_very-big_js-8d76cf03}= ={main-index_js-41f5a26e}= ={main-small_js-1}= ={main-subfolder_big_js-b}= ={main-subfolder_small_js-1}= ={main-very-big_js-08cf55cf}= ={main-very-big_js-4647fb9d}= ={main-very-big_js-62f7f644}= ={vendors-node_modules_big_js_1-node_modules_small_js_1-node_modules_small_js_2}= ={vendors-node_modules_very-big_js_1}= [initial] [rendered] - > ./ main - ./inner-module/small.js?1 66 bytes [built] [code generated] - ./inner-module/small.js?2 66 bytes [built] [code generated] - ./inner-module/small.js?3 66 bytes [built] [code generated] - ./inner-module/small.js?4 66 bytes [built] [code generated] - ./inner-module/small.js?5 66 bytes [built] [code generated] - ./inner-module/small.js?6 66 bytes [built] [code generated] - ./inner-module/small.js?7 66 bytes [built] [code generated] - ./inner-module/small.js?8 66 bytes [built] [code generated] - ./inner-module/small.js?9 66 bytes [built] [code generated] - chunk (runtime: main) dev-main-small_js-1.js (main-small_js-1) 594 bytes ={main-big_js-1}= ={main-in-some-directory_b}= ={main-in-some-directory_very-big_js-8d76cf03}= ={main-index_js-41f5a26e}= ={main-inner-module_small_js-3}= ={main-subfolder_big_js-b}= ={main-subfolder_small_js-1}= ={main-very-big_js-08cf55cf}= ={main-very-big_js-4647fb9d}= ={main-very-big_js-62f7f644}= ={vendors-node_modules_big_js_1-node_modules_small_js_1-node_modules_small_js_2}= ={vendors-node_modules_very-big_js_1}= [initial] [rendered] - > ./ main - ./small.js?1 66 bytes [built] [code generated] - ./small.js?2 66 bytes [built] [code generated] - ./small.js?3 66 bytes [built] [code generated] - ./small.js?4 66 bytes [built] [code generated] - ./small.js?5 66 bytes [built] [code generated] - ./small.js?6 66 bytes [built] [code generated] - ./small.js?7 66 bytes [built] [code generated] - ./small.js?8 66 bytes [built] [code generated] - ./small.js?9 66 bytes [built] [code generated] - chunk (runtime: main) dev-main-subfolder_big_js-b.js (main-subfolder_big_js-b) 534 bytes ={main-big_js-1}= ={main-in-some-directory_b}= ={main-in-some-directory_very-big_js-8d76cf03}= ={main-index_js-41f5a26e}= ={main-inner-module_small_js-3}= ={main-small_js-1}= ={main-subfolder_small_js-1}= ={main-very-big_js-08cf55cf}= ={main-very-big_js-4647fb9d}= ={main-very-big_js-62f7f644}= ={vendors-node_modules_big_js_1-node_modules_small_js_1-node_modules_small_js_2}= ={vendors-node_modules_very-big_js_1}= [initial] [rendered] - > ./ main - ./subfolder/big.js?1 267 bytes [built] [code generated] - ./subfolder/big.js?2 267 bytes [built] [code generated] - chunk (runtime: main) dev-main-subfolder_small_js-1.js (main-subfolder_small_js-1) 594 bytes ={main-big_js-1}= ={main-in-some-directory_b}= ={main-in-some-directory_very-big_js-8d76cf03}= ={main-index_js-41f5a26e}= ={main-inner-module_small_js-3}= ={main-small_js-1}= ={main-subfolder_big_js-b}= ={main-very-big_js-08cf55cf}= ={main-very-big_js-4647fb9d}= ={main-very-big_js-62f7f644}= ={vendors-node_modules_big_js_1-node_modules_small_js_1-node_modules_small_js_2}= ={vendors-node_modules_very-big_js_1}= [initial] [rendered] - > ./ main - ./subfolder/small.js?1 66 bytes [built] [code generated] - ./subfolder/small.js?2 66 bytes [built] [code generated] - ./subfolder/small.js?3 66 bytes [built] [code generated] - ./subfolder/small.js?4 66 bytes [built] [code generated] - ./subfolder/small.js?5 66 bytes [built] [code generated] - ./subfolder/small.js?6 66 bytes [built] [code generated] - ./subfolder/small.js?7 66 bytes [built] [code generated] - ./subfolder/small.js?8 66 bytes [built] [code generated] - ./subfolder/small.js?9 66 bytes [built] [code generated] - chunk (runtime: main) dev-main-very-big_js-08cf55cf.js (main-very-big_js-08cf55cf) 1.57 KiB ={main-big_js-1}= ={main-in-some-directory_b}= ={main-in-some-directory_very-big_js-8d76cf03}= ={main-index_js-41f5a26e}= ={main-inner-module_small_js-3}= ={main-small_js-1}= ={main-subfolder_big_js-b}= ={main-subfolder_small_js-1}= ={main-very-big_js-4647fb9d}= ={main-very-big_js-62f7f644}= ={vendors-node_modules_big_js_1-node_modules_small_js_1-node_modules_small_js_2}= ={vendors-node_modules_very-big_js_1}= [initial] [rendered] - > ./ main - ./very-big.js?2 1.57 KiB [built] [code generated] - chunk (runtime: main) dev-main-very-big_js-4647fb9d.js (main-very-big_js-4647fb9d) 1.57 KiB ={main-big_js-1}= ={main-in-some-directory_b}= ={main-in-some-directory_very-big_js-8d76cf03}= ={main-index_js-41f5a26e}= ={main-inner-module_small_js-3}= ={main-small_js-1}= ={main-subfolder_big_js-b}= ={main-subfolder_small_js-1}= ={main-very-big_js-08cf55cf}= ={main-very-big_js-62f7f644}= ={vendors-node_modules_big_js_1-node_modules_small_js_1-node_modules_small_js_2}= ={vendors-node_modules_very-big_js_1}= [initial] [rendered] - > ./ main - ./very-big.js?3 1.57 KiB [built] [code generated] - chunk (runtime: main) dev-main-very-big_js-62f7f644.js (main-very-big_js-62f7f644) 1.57 KiB (javascript) 3.18 KiB (runtime) ={main-big_js-1}= ={main-in-some-directory_b}= ={main-in-some-directory_very-big_js-8d76cf03}= ={main-index_js-41f5a26e}= ={main-inner-module_small_js-3}= ={main-small_js-1}= ={main-subfolder_big_js-b}= ={main-subfolder_small_js-1}= ={main-very-big_js-08cf55cf}= ={main-very-big_js-4647fb9d}= ={vendors-node_modules_big_js_1-node_modules_small_js_1-node_modules_small_js_2}= ={vendors-node_modules_very-big_js_1}= [entry] [rendered] - > ./ main - runtime modules 3.18 KiB 6 modules - ./very-big.js?1 1.57 KiB [built] [code generated] - chunk (runtime: main) dev-vendors-node_modules_big_js_1-node_modules_small_js_1-node_modules_small_js_2.js (id hint: vendors) 399 bytes ={main-big_js-1}= ={main-in-some-directory_b}= ={main-in-some-directory_very-big_js-8d76cf03}= ={main-index_js-41f5a26e}= ={main-inner-module_small_js-3}= ={main-small_js-1}= ={main-subfolder_big_js-b}= ={main-subfolder_small_js-1}= ={main-very-big_js-08cf55cf}= ={main-very-big_js-4647fb9d}= ={main-very-big_js-62f7f644}= ={vendors-node_modules_very-big_js_1}= [initial] [rendered] split chunk (cache group: defaultVendors) - > ./ main - ./node_modules/big.js?1 267 bytes [built] [code generated] - ./node_modules/small.js?1 66 bytes [built] [code generated] - ./node_modules/small.js?2 66 bytes [built] [code generated] - chunk (runtime: main) dev-vendors-node_modules_very-big_js_1.js (id hint: vendors) 1.57 KiB ={main-big_js-1}= ={main-in-some-directory_b}= ={main-in-some-directory_very-big_js-8d76cf03}= ={main-index_js-41f5a26e}= ={main-inner-module_small_js-3}= ={main-small_js-1}= ={main-subfolder_big_js-b}= ={main-subfolder_small_js-1}= ={main-very-big_js-08cf55cf}= ={main-very-big_js-4647fb9d}= ={main-very-big_js-62f7f644}= ={vendors-node_modules_big_js_1-node_modules_small_js_1-node_modules_small_js_2}= [initial] [rendered] split chunk (cache group: defaultVendors) - > ./ main - ./node_modules/very-big.js?1 1.57 KiB [built] [code generated] - development (webpack x.x.x) compiled successfully - -switched: - Entrypoint main 31.4 KiB = 9 assets - chunk (runtime: main) switched-main-6bb16544.js (main-6bb16544) 1.57 KiB ={59}= ={318}= ={410}= ={520}= ={581}= ={663}= ={869}= ={997}= [initial] [rendered] - > ./ main - ./in-some-directory/very-big.js?1 1.57 KiB [built] [code generated] - chunk (runtime: main) switched-main-77a8c116.js (main-77a8c116) 1.57 KiB ={1}= ={318}= ={410}= ={520}= ={581}= ={663}= ={869}= ={997}= [initial] [rendered] - > ./ main - ./very-big.js?2 1.57 KiB [built] [code generated] - chunk (runtime: main) switched-main-89a43a0f.js (main-89a43a0f) 1.57 KiB ={1}= ={59}= ={410}= ={520}= ={581}= ={663}= ={869}= ={997}= [initial] [rendered] - > ./ main - ./very-big.js?3 1.57 KiB [built] [code generated] - chunk (runtime: main) switched-410.js (id hint: vendors) 1.57 KiB ={1}= ={59}= ={318}= ={520}= ={581}= ={663}= ={869}= ={997}= [initial] [rendered] split chunk (cache group: defaultVendors) - > ./ main - ./node_modules/very-big.js?1 1.57 KiB [built] [code generated] - chunk (runtime: main) switched-main-1df31ce3.js (main-1df31ce3) 1.19 KiB ={1}= ={59}= ={318}= ={410}= ={581}= ={663}= ={869}= ={997}= [initial] [rendered] - > ./ main - ./index.js 1.19 KiB [built] [code generated] - chunk (runtime: main) switched-main-879072e3.js (main-879072e3) 1.68 KiB ={1}= ={59}= ={318}= ={410}= ={520}= ={663}= ={869}= ={997}= [initial] [rendered] - > ./ main - modules by path ./subfolder/*.js 1.1 KiB 11 modules - modules by path ./*.js 594 bytes 9 modules - chunk (runtime: main) switched-main-12217e1d.js (main-12217e1d) 1.57 KiB (javascript) 2.89 KiB (runtime) ={1}= ={59}= ={318}= ={410}= ={520}= ={581}= ={869}= ={997}= [entry] [rendered] - > ./ main - runtime modules 2.89 KiB 5 modules - ./very-big.js?1 1.57 KiB [built] [code generated] - chunk (runtime: main) switched-869.js (id hint: vendors) 399 bytes ={1}= ={59}= ={318}= ={410}= ={520}= ={581}= ={663}= ={997}= [initial] [rendered] split chunk (cache group: defaultVendors) - > ./ main - ./node_modules/big.js?1 267 bytes [built] [code generated] - ./node_modules/small.js?1 66 bytes [built] [code generated] - ./node_modules/small.js?2 66 bytes [built] [code generated] - chunk (runtime: main) switched-main-7aeafcb2.js (main-7aeafcb2) 1.62 KiB ={1}= ={59}= ={318}= ={410}= ={520}= ={581}= ={663}= ={869}= [initial] [rendered] - > ./ main - modules by path ./inner-module/*.js 594 bytes 9 modules - modules by path ./in-some-directory/*.js 531 bytes - ./in-some-directory/big.js?1 267 bytes [built] [code generated] - ./in-some-directory/small.js?1 66 bytes [built] [code generated] - ./in-some-directory/small.js?2 66 bytes [built] [code generated] - ./in-some-directory/small.js?3 66 bytes [built] [code generated] - ./in-some-directory/small.js?4 66 bytes [built] [code generated] - modules by path ./*.js 534 bytes - ./big.js?1 267 bytes [built] [code generated] - ./big.js?2 267 bytes [built] [code generated] - - WARNING in SplitChunksPlugin - Cache group defaultVendors - Configured minSize (1000 bytes) is bigger than maxSize (100 bytes). - This seem to be a invalid optimization.splitChunks configuration. - - WARNING in SplitChunksPlugin - Fallback cache group - Configured minSize (1000 bytes) is bigger than maxSize (100 bytes). - This seem to be a invalid optimization.splitChunks configuration. - - switched (webpack x.x.x) compiled with 2 warnings - -zero-min: - Entrypoint main 31.7 KiB = 13 assets - chunk (runtime: main) zero-min-main-6bb16544.js (main-6bb16544) 1.57 KiB ={59}= ={198}= ={204}= ={318}= ={358}= ={400}= ={410}= ={490}= ={520}= ={662}= ={663}= ={869}= [initial] [rendered] - > ./ main - ./in-some-directory/very-big.js?1 1.57 KiB [built] [code generated] - chunk (runtime: main) zero-min-main-77a8c116.js (main-77a8c116) 1.57 KiB ={1}= ={198}= ={204}= ={318}= ={358}= ={400}= ={410}= ={490}= ={520}= ={662}= ={663}= ={869}= [initial] [rendered] - > ./ main - ./very-big.js?2 1.57 KiB [built] [code generated] - chunk (runtime: main) zero-min-main-3c98d7c3.js (main-3c98d7c3) 531 bytes ={1}= ={59}= ={204}= ={318}= ={358}= ={400}= ={410}= ={490}= ={520}= ={662}= ={663}= ={869}= [initial] [rendered] - > ./ main - ./in-some-directory/big.js?1 267 bytes [built] [code generated] - ./in-some-directory/small.js?1 66 bytes [built] [code generated] - ./in-some-directory/small.js?2 66 bytes [built] [code generated] - ./in-some-directory/small.js?3 66 bytes [built] [code generated] - ./in-some-directory/small.js?4 66 bytes [built] [code generated] - chunk (runtime: main) zero-min-main-2f7dcf2e.js (main-2f7dcf2e) 594 bytes ={1}= ={59}= ={198}= ={318}= ={358}= ={400}= ={410}= ={490}= ={520}= ={662}= ={663}= ={869}= [initial] [rendered] - > ./ main - ./inner-module/small.js?1 66 bytes [built] [code generated] - ./inner-module/small.js?2 66 bytes [built] [code generated] - ./inner-module/small.js?3 66 bytes [built] [code generated] - ./inner-module/small.js?4 66 bytes [built] [code generated] - ./inner-module/small.js?5 66 bytes [built] [code generated] - ./inner-module/small.js?6 66 bytes [built] [code generated] - ./inner-module/small.js?7 66 bytes [built] [code generated] - ./inner-module/small.js?8 66 bytes [built] [code generated] - ./inner-module/small.js?9 66 bytes [built] [code generated] - chunk (runtime: main) zero-min-main-89a43a0f.js (main-89a43a0f) 1.57 KiB ={1}= ={59}= ={198}= ={204}= ={358}= ={400}= ={410}= ={490}= ={520}= ={662}= ={663}= ={869}= [initial] [rendered] - > ./ main - ./very-big.js?3 1.57 KiB [built] [code generated] - chunk (runtime: main) zero-min-main-e7c5ace7.js (main-e7c5ace7) 594 bytes ={1}= ={59}= ={198}= ={204}= ={318}= ={400}= ={410}= ={490}= ={520}= ={662}= ={663}= ={869}= [initial] [rendered] - > ./ main - ./small.js?1 66 bytes [built] [code generated] - ./small.js?2 66 bytes [built] [code generated] - ./small.js?3 66 bytes [built] [code generated] - ./small.js?4 66 bytes [built] [code generated] - ./small.js?5 66 bytes [built] [code generated] - ./small.js?6 66 bytes [built] [code generated] - ./small.js?7 66 bytes [built] [code generated] - ./small.js?8 66 bytes [built] [code generated] - ./small.js?9 66 bytes [built] [code generated] - chunk (runtime: main) zero-min-main-1443e336.js (main-1443e336) 594 bytes ={1}= ={59}= ={198}= ={204}= ={318}= ={358}= ={410}= ={490}= ={520}= ={662}= ={663}= ={869}= [initial] [rendered] - > ./ main - ./subfolder/small.js?1 66 bytes [built] [code generated] - ./subfolder/small.js?2 66 bytes [built] [code generated] - ./subfolder/small.js?3 66 bytes [built] [code generated] - ./subfolder/small.js?4 66 bytes [built] [code generated] - ./subfolder/small.js?5 66 bytes [built] [code generated] - ./subfolder/small.js?6 66 bytes [built] [code generated] - ./subfolder/small.js?7 66 bytes [built] [code generated] - ./subfolder/small.js?8 66 bytes [built] [code generated] - ./subfolder/small.js?9 66 bytes [built] [code generated] - chunk (runtime: main) zero-min-410.js (id hint: vendors) 1.57 KiB ={1}= ={59}= ={198}= ={204}= ={318}= ={358}= ={400}= ={490}= ={520}= ={662}= ={663}= ={869}= [initial] [rendered] split chunk (cache group: defaultVendors) - > ./ main - ./node_modules/very-big.js?1 1.57 KiB [built] [code generated] - chunk (runtime: main) zero-min-main-5cfff2c6.js (main-5cfff2c6) 534 bytes ={1}= ={59}= ={198}= ={204}= ={318}= ={358}= ={400}= ={410}= ={520}= ={662}= ={663}= ={869}= [initial] [rendered] - > ./ main - ./subfolder/big.js?1 267 bytes [built] [code generated] - ./subfolder/big.js?2 267 bytes [built] [code generated] - chunk (runtime: main) zero-min-main-1df31ce3.js (main-1df31ce3) 1.19 KiB ={1}= ={59}= ={198}= ={204}= ={318}= ={358}= ={400}= ={410}= ={490}= ={662}= ={663}= ={869}= [initial] [rendered] - > ./ main - ./index.js 1.19 KiB [built] [code generated] - chunk (runtime: main) zero-min-main-10f51d07.js (main-10f51d07) 534 bytes ={1}= ={59}= ={198}= ={204}= ={318}= ={358}= ={400}= ={410}= ={490}= ={520}= ={663}= ={869}= [initial] [rendered] - > ./ main - ./big.js?1 267 bytes [built] [code generated] - ./big.js?2 267 bytes [built] [code generated] - chunk (runtime: main) zero-min-main-12217e1d.js (main-12217e1d) 1.57 KiB (javascript) 2.89 KiB (runtime) ={1}= ={59}= ={198}= ={204}= ={318}= ={358}= ={400}= ={410}= ={490}= ={520}= ={662}= ={869}= [entry] [rendered] - > ./ main - runtime modules 2.89 KiB 5 modules - ./very-big.js?1 1.57 KiB [built] [code generated] - chunk (runtime: main) zero-min-869.js (id hint: vendors) 399 bytes ={1}= ={59}= ={198}= ={204}= ={318}= ={358}= ={400}= ={410}= ={490}= ={520}= ={662}= ={663}= [initial] [rendered] split chunk (cache group: defaultVendors) - > ./ main - ./node_modules/big.js?1 267 bytes [built] [code generated] - ./node_modules/small.js?1 66 bytes [built] [code generated] - ./node_modules/small.js?2 66 bytes [built] [code generated] - zero-min (webpack x.x.x) compiled successfully - -max-async-size: - Entrypoint main 15.8 KiB = max-async-size-main.js - chunk (runtime: main) max-async-size-main.js (main) 2.46 KiB (javascript) 6.87 KiB (runtime) >{342}< >{385}< >{820}< >{920}< [entry] [rendered] - > ./async main - runtime modules 6.87 KiB 10 modules - dependent modules 2.09 KiB [dependent] 6 modules - ./async/index.js 386 bytes [built] [code generated] - chunk (runtime: main) max-async-size-async-b-77a8c116.js (async-b-77a8c116) 1.57 KiB <{179}> ={385}= ={820}= ={920}= [rendered] - > ./b ./async/index.js 10:2-49 - > ./a ./async/index.js 9:2-49 - ./very-big.js?2 1.57 KiB [built] [code generated] - chunk (runtime: main) max-async-size-async-b-12217e1d.js (async-b-12217e1d) 1.57 KiB <{179}> ={342}= ={820}= ={920}= [rendered] - > ./b ./async/index.js 10:2-49 - > ./a ./async/index.js 9:2-49 - ./very-big.js?1 1.57 KiB [built] [code generated] - chunk (runtime: main) max-async-size-async-b-89a43a0f.js (async-b-89a43a0f) 1.57 KiB <{179}> ={342}= ={385}= ={920}= [rendered] - > ./b ./async/index.js 10:2-49 - > ./a ./async/index.js 9:2-49 - ./very-big.js?3 1.57 KiB [built] [code generated] - chunk (runtime: main) max-async-size-async-b-bde52cb3.js (async-b-bde52cb3) 855 bytes <{179}> ={342}= ={385}= ={820}= [rendered] - > ./b ./async/index.js 10:2-49 - > ./a ./async/index.js 9:2-49 - dependent modules 594 bytes [dependent] 9 modules - cacheable modules 261 bytes - ./async/a.js 189 bytes [built] [code generated] - ./async/b.js 72 bytes [built] [code generated] - max-async-size (webpack x.x.x) compiled successfully - -enforce-min-size: - Entrypoint main 31.7 KiB = 14 assets - chunk (runtime: main) enforce-min-size-10.js (id hint: all) 1.19 KiB ={179}= ={221}= ={262}= ={410}= ={434}= ={463}= ={519}= ={575}= ={614}= ={692}= ={822}= ={825}= ={869}= [initial] [rendered] split chunk (cache group: all) - > ./ main - ./index.js 1.19 KiB [built] [code generated] - chunk (runtime: main) enforce-min-size-main.js (main) 2.89 KiB ={10}= ={221}= ={262}= ={410}= ={434}= ={463}= ={519}= ={575}= ={614}= ={692}= ={822}= ={825}= ={869}= [entry] [rendered] - > ./ main - runtime modules 2.89 KiB 5 modules - chunk (runtime: main) enforce-min-size-221.js (id hint: all) 1.57 KiB ={10}= ={179}= ={262}= ={410}= ={434}= ={463}= ={519}= ={575}= ={614}= ={692}= ={822}= ={825}= ={869}= [initial] [rendered] split chunk (cache group: all) - > ./ main - ./very-big.js?3 1.57 KiB [built] [code generated] - chunk (runtime: main) enforce-min-size-262.js (id hint: all) 1.57 KiB ={10}= ={179}= ={221}= ={410}= ={434}= ={463}= ={519}= ={575}= ={614}= ={692}= ={822}= ={825}= ={869}= [initial] [rendered] split chunk (cache group: all) - > ./ main - ./in-some-directory/very-big.js?1 1.57 KiB [built] [code generated] - chunk (runtime: main) enforce-min-size-410.js (id hint: all) 1.57 KiB ={10}= ={179}= ={221}= ={262}= ={434}= ={463}= ={519}= ={575}= ={614}= ={692}= ={822}= ={825}= ={869}= [initial] [rendered] split chunk (cache group: all) - > ./ main - ./node_modules/very-big.js?1 1.57 KiB [built] [code generated] - chunk (runtime: main) enforce-min-size-434.js (id hint: all) 594 bytes ={10}= ={179}= ={221}= ={262}= ={410}= ={463}= ={519}= ={575}= ={614}= ={692}= ={822}= ={825}= ={869}= [initial] [rendered] split chunk (cache group: all) - > ./ main - ./inner-module/small.js?1 66 bytes [built] [code generated] - ./inner-module/small.js?2 66 bytes [built] [code generated] - ./inner-module/small.js?3 66 bytes [built] [code generated] - ./inner-module/small.js?4 66 bytes [built] [code generated] - ./inner-module/small.js?5 66 bytes [built] [code generated] - ./inner-module/small.js?6 66 bytes [built] [code generated] - ./inner-module/small.js?7 66 bytes [built] [code generated] - ./inner-module/small.js?8 66 bytes [built] [code generated] - ./inner-module/small.js?9 66 bytes [built] [code generated] - chunk (runtime: main) enforce-min-size-463.js (id hint: all) 1.57 KiB ={10}= ={179}= ={221}= ={262}= ={410}= ={434}= ={519}= ={575}= ={614}= ={692}= ={822}= ={825}= ={869}= [initial] [rendered] split chunk (cache group: all) - > ./ main - ./very-big.js?1 1.57 KiB [built] [code generated] - chunk (runtime: main) enforce-min-size-519.js (id hint: all) 534 bytes ={10}= ={179}= ={221}= ={262}= ={410}= ={434}= ={463}= ={575}= ={614}= ={692}= ={822}= ={825}= ={869}= [initial] [rendered] split chunk (cache group: all) - > ./ main - ./big.js?1 267 bytes [built] [code generated] - ./big.js?2 267 bytes [built] [code generated] - chunk (runtime: main) enforce-min-size-575.js (id hint: all) 1.57 KiB ={10}= ={179}= ={221}= ={262}= ={410}= ={434}= ={463}= ={519}= ={614}= ={692}= ={822}= ={825}= ={869}= [initial] [rendered] split chunk (cache group: all) - > ./ main - ./very-big.js?2 1.57 KiB [built] [code generated] - chunk (runtime: main) enforce-min-size-614.js (id hint: all) 531 bytes ={10}= ={179}= ={221}= ={262}= ={410}= ={434}= ={463}= ={519}= ={575}= ={692}= ={822}= ={825}= ={869}= [initial] [rendered] split chunk (cache group: all) - > ./ main - ./in-some-directory/big.js?1 267 bytes [built] [code generated] - ./in-some-directory/small.js?1 66 bytes [built] [code generated] - ./in-some-directory/small.js?2 66 bytes [built] [code generated] - ./in-some-directory/small.js?3 66 bytes [built] [code generated] - ./in-some-directory/small.js?4 66 bytes [built] [code generated] - chunk (runtime: main) enforce-min-size-692.js (id hint: all) 594 bytes ={10}= ={179}= ={221}= ={262}= ={410}= ={434}= ={463}= ={519}= ={575}= ={614}= ={822}= ={825}= ={869}= [initial] [rendered] split chunk (cache group: all) - > ./ main - ./small.js?1 66 bytes [built] [code generated] - ./small.js?2 66 bytes [built] [code generated] - ./small.js?3 66 bytes [built] [code generated] - ./small.js?4 66 bytes [built] [code generated] - ./small.js?5 66 bytes [built] [code generated] - ./small.js?6 66 bytes [built] [code generated] - ./small.js?7 66 bytes [built] [code generated] - ./small.js?8 66 bytes [built] [code generated] - ./small.js?9 66 bytes [built] [code generated] - chunk (runtime: main) enforce-min-size-822.js (id hint: all) 594 bytes ={10}= ={179}= ={221}= ={262}= ={410}= ={434}= ={463}= ={519}= ={575}= ={614}= ={692}= ={825}= ={869}= [initial] [rendered] split chunk (cache group: all) - > ./ main - ./subfolder/small.js?1 66 bytes [built] [code generated] - ./subfolder/small.js?2 66 bytes [built] [code generated] - ./subfolder/small.js?3 66 bytes [built] [code generated] - ./subfolder/small.js?4 66 bytes [built] [code generated] - ./subfolder/small.js?5 66 bytes [built] [code generated] - ./subfolder/small.js?6 66 bytes [built] [code generated] - ./subfolder/small.js?7 66 bytes [built] [code generated] - ./subfolder/small.js?8 66 bytes [built] [code generated] - ./subfolder/small.js?9 66 bytes [built] [code generated] - chunk (runtime: main) enforce-min-size-825.js (id hint: all) 534 bytes ={10}= ={179}= ={221}= ={262}= ={410}= ={434}= ={463}= ={519}= ={575}= ={614}= ={692}= ={822}= ={869}= [initial] [rendered] split chunk (cache group: all) - > ./ main - ./subfolder/big.js?1 267 bytes [built] [code generated] - ./subfolder/big.js?2 267 bytes [built] [code generated] - chunk (runtime: main) enforce-min-size-869.js (id hint: all) 399 bytes ={10}= ={179}= ={221}= ={262}= ={410}= ={434}= ={463}= ={519}= ={575}= ={614}= ={692}= ={822}= ={825}= [initial] [rendered] split chunk (cache group: all) - > ./ main - ./node_modules/big.js?1 267 bytes [built] [code generated] - ./node_modules/small.js?1 66 bytes [built] [code generated] - ./node_modules/small.js?2 66 bytes [built] [code generated] - enforce-min-size (webpack x.x.x) compiled successfully" -`; - -exports[`StatsTestCases should print correct stats for split-chunks-prefer-bigger-splits 1`] = ` -"Entrypoint main 11.1 KiB = default/main.js -chunk (runtime: main) default/118.js 150 bytes <{179}> ={334}= ={383}= [rendered] split chunk (cache group: default) - > ./b ./index.js 2:0-47 - > ./c ./index.js 3:0-47 - ./d.js 63 bytes [built] [code generated] - ./f.js 87 bytes [built] [code generated] -chunk (runtime: main) default/main.js (main) 147 bytes (javascript) 6.57 KiB (runtime) >{118}< >{334}< >{383}< >{794}< [entry] [rendered] - > ./ main - runtime modules 6.57 KiB 9 modules - ./index.js 147 bytes [built] [code generated] -chunk (runtime: main) default/async-b.js (async-b) 158 bytes <{179}> ={118}= [rendered] - > ./b ./index.js 2:0-47 - dependent modules 63 bytes [dependent] 1 module - ./b.js 95 bytes [built] [code generated] -chunk (runtime: main) default/async-c.js (async-c) 70 bytes <{179}> ={118}= [rendered] - > ./c ./index.js 3:0-47 - ./c.js 70 bytes [built] [code generated] -chunk (runtime: main) default/async-a.js (async-a) 196 bytes <{179}> [rendered] - > ./a ./index.js 1:0-47 - dependent modules 126 bytes [dependent] 2 modules - ./a.js 70 bytes [built] [code generated] -webpack x.x.x compiled successfully" -`; - -exports[`StatsTestCases should print correct stats for split-chunks-runtime-specific 1`] = ` -"used-exports: - asset used-exports-c.js 5.88 KiB [emitted] (name: c) - asset used-exports-b.js 5.88 KiB [emitted] (name: b) - asset used-exports-332.js 424 bytes [emitted] - asset used-exports-a.js 257 bytes [emitted] (name: a) - Entrypoint a 257 bytes = used-exports-a.js - Entrypoint b 6.29 KiB = used-exports-332.js 424 bytes used-exports-b.js 5.88 KiB - Entrypoint c 6.3 KiB = used-exports-332.js 424 bytes used-exports-c.js 5.88 KiB - chunk (runtime: b) used-exports-b.js (b) 54 bytes (javascript) 2.63 KiB (runtime) [entry] [rendered] - runtime modules 2.63 KiB 4 modules - ./b.js 54 bytes [built] [code generated] - chunk (runtime: b, c) used-exports-332.js 72 bytes [initial] [rendered] split chunk (cache group: default) - ./objects.js 72 bytes [built] [code generated] - chunk (runtime: c) used-exports-c.js (c) 59 bytes (javascript) 2.63 KiB (runtime) [entry] [rendered] - runtime modules 2.63 KiB 4 modules - ./c.js 59 bytes [built] [code generated] - chunk (runtime: a) used-exports-a.js (a) 126 bytes [entry] [rendered] - ./a.js + 1 modules 126 bytes [built] [code generated] - used-exports (webpack x.x.x) compiled successfully in X ms - -no-used-exports: - asset no-used-exports-c.js 5.88 KiB [emitted] (name: c) - asset no-used-exports-a.js 5.88 KiB [emitted] (name: a) - asset no-used-exports-b.js 5.88 KiB [emitted] (name: b) - asset no-used-exports-332.js 447 bytes [emitted] - Entrypoint a 6.31 KiB = no-used-exports-332.js 447 bytes no-used-exports-a.js 5.88 KiB - Entrypoint b 6.31 KiB = no-used-exports-332.js 447 bytes no-used-exports-b.js 5.88 KiB - Entrypoint c 6.32 KiB = no-used-exports-332.js 447 bytes no-used-exports-c.js 5.88 KiB - chunk (runtime: b) no-used-exports-b.js (b) 54 bytes (javascript) 2.63 KiB (runtime) [entry] [rendered] - runtime modules 2.63 KiB 4 modules - ./b.js 54 bytes [built] [code generated] - chunk (runtime: a, b, c) no-used-exports-332.js 72 bytes [initial] [rendered] split chunk (cache group: default) - ./objects.js 72 bytes [built] [code generated] - chunk (runtime: c) no-used-exports-c.js (c) 59 bytes (javascript) 2.63 KiB (runtime) [entry] [rendered] - runtime modules 2.63 KiB 4 modules - ./c.js 59 bytes [built] [code generated] - chunk (runtime: a) no-used-exports-a.js (a) 54 bytes (javascript) 2.63 KiB (runtime) [entry] [rendered] - runtime modules 2.63 KiB 4 modules - ./a.js 54 bytes [built] [code generated] - no-used-exports (webpack x.x.x) compiled successfully in X ms - -global: - asset global-c.js 5.88 KiB [emitted] (name: c) - asset global-a.js 5.88 KiB [emitted] (name: a) - asset global-b.js 5.88 KiB [emitted] (name: b) - asset global-332.js 447 bytes [emitted] - Entrypoint a 6.31 KiB = global-332.js 447 bytes global-a.js 5.88 KiB - Entrypoint b 6.31 KiB = global-332.js 447 bytes global-b.js 5.88 KiB - Entrypoint c 6.32 KiB = global-332.js 447 bytes global-c.js 5.88 KiB - chunk (runtime: b) global-b.js (b) 54 bytes (javascript) 2.63 KiB (runtime) [entry] [rendered] - runtime modules 2.63 KiB 4 modules - ./b.js 54 bytes [built] [code generated] - chunk (runtime: a, b, c) global-332.js 72 bytes [initial] [rendered] split chunk (cache group: default) - ./objects.js 72 bytes [built] [code generated] - chunk (runtime: c) global-c.js (c) 59 bytes (javascript) 2.63 KiB (runtime) [entry] [rendered] - runtime modules 2.63 KiB 4 modules - ./c.js 59 bytes [built] [code generated] - chunk (runtime: a) global-a.js (a) 54 bytes (javascript) 2.63 KiB (runtime) [entry] [rendered] - runtime modules 2.63 KiB 4 modules - ./a.js 54 bytes [built] [code generated] - global (webpack x.x.x) compiled successfully in X ms" -`; - -exports[`StatsTestCases should print correct stats for tree-shaking 1`] = ` -"asset bundle.js 6.89 KiB [emitted] (name: main) -runtime modules 663 bytes 3 modules -orphan modules 14 bytes [orphan] 1 module -cacheable modules 782 bytes - ./index.js 316 bytes [built] [code generated] [1 warning] - [no exports] - [no exports used] - ./reexport-known.js 49 bytes [built] [code generated] - [exports: a, b] - [only some exports used: a] - ./reexport-unknown.js 100 bytes [built] [code generated] - [exports: a, b, c, d] - [only some exports used: a, c] - ./reexport-star-known.js 58 bytes [built] [code generated] - [exports: a, b] - [only some exports used: a] - ./reexport-star-unknown.js 85 bytes [built] [code generated] - [only some exports used: a, c] - ./edge.js 62 bytes [built] [code generated] - [only some exports used: y] - ./require.include.js 52 bytes [built] [code generated] - [exports: a, default] - [no exports used] - ./a.js 30 bytes [built] [code generated] - [exports: a] - [all exports used] - ./unknown.js 15 bytes [built] [code generated] - [used exports unknown] - ./unknown2.js 15 bytes [built] [code generated] - [used exports unknown] - -WARNING in ./index.js 9:0-36 -require.include() is deprecated and will be removed soon. - -webpack x.x.x compiled with 1 warning in X ms" -`; - -exports[`StatsTestCases should print correct stats for wasm-explorer-examples-sync 1`] = ` -"assets by path *.js 21.4 KiB - asset bundle.js 16 KiB [emitted] (name: main) - asset 325.bundle.js 3.98 KiB [emitted] - asset 780.bundle.js 571 bytes [emitted] - asset 526.bundle.js 366 bytes [emitted] (id hint: vendors) - asset 230.bundle.js 243 bytes [emitted] - asset 99.bundle.js 241 bytes [emitted] -assets by path *.wasm 1.37 KiB - asset 4098dd6bcb43bd54baf6.module.wasm 531 bytes [emitted] [immutable] - asset c3c66cf69b0a4bd721a4.module.wasm 290 bytes [emitted] [immutable] - asset 86fec7665231a0198df8.module.wasm 156 bytes [emitted] [immutable] - asset 1da1d844c1509ed4d4c3.module.wasm 154 bytes [emitted] [immutable] - asset 2be4d707a05b1f7313ca.module.wasm 154 bytes [emitted] [immutable] - asset d1fdb94978c775bdc12a.module.wasm 120 bytes [emitted] [immutable] -chunk (runtime: main) 99.bundle.js 50 bytes (javascript) 531 bytes (webassembly) [rendered] - ./duff.wasm 50 bytes (javascript) 531 bytes (webassembly) [built] [code generated] -chunk (runtime: main) bundle.js (main) 586 bytes (javascript) 9.11 KiB (runtime) [entry] [rendered] - runtime modules 9.11 KiB 11 modules - ./index.js 586 bytes [built] [code generated] -chunk (runtime: main) 230.bundle.js 50 bytes (javascript) 156 bytes (webassembly) [rendered] - ./Q_rsqrt.wasm 50 bytes (javascript) 156 bytes (webassembly) [built] [code generated] -chunk (runtime: main) 325.bundle.js 1.5 KiB (javascript) 274 bytes (webassembly) [rendered] - ./popcnt.wasm 50 bytes (javascript) 120 bytes (webassembly) [dependent] [built] [code generated] - ./testFunction.wasm 50 bytes (javascript) 154 bytes (webassembly) [dependent] [built] [code generated] - ./tests.js 1.4 KiB [built] [code generated] -chunk (runtime: main) 526.bundle.js (id hint: vendors) 34 bytes [rendered] split chunk (cache group: defaultVendors) - ./node_modules/env.js 34 bytes [built] [code generated] -chunk (runtime: main) 780.bundle.js 110 bytes (javascript) 444 bytes (webassembly) [rendered] - ./fact.wasm 50 bytes (javascript) 154 bytes (webassembly) [built] [code generated] - ./fast-math.wasm 60 bytes (javascript) 290 bytes (webassembly) [built] [code generated] -runtime modules 9.11 KiB 11 modules -cacheable modules 2.31 KiB (javascript) 1.37 KiB (webassembly) - webassembly modules 310 bytes (javascript) 1.37 KiB (webassembly) - ./Q_rsqrt.wasm 50 bytes (javascript) 156 bytes (webassembly) [built] [code generated] - ./testFunction.wasm 50 bytes (javascript) 154 bytes (webassembly) [built] [code generated] - ./fact.wasm 50 bytes (javascript) 154 bytes (webassembly) [built] [code generated] - ./popcnt.wasm 50 bytes (javascript) 120 bytes (webassembly) [built] [code generated] - ./fast-math.wasm 60 bytes (javascript) 290 bytes (webassembly) [built] [code generated] - ./duff.wasm 50 bytes (javascript) 531 bytes (webassembly) [built] [code generated] - javascript modules 2.01 KiB - ./index.js 586 bytes [built] [code generated] - ./tests.js 1.4 KiB [built] [code generated] - ./node_modules/env.js 34 bytes [built] [code generated] -webpack x.x.x compiled successfully in X ms" -`; diff --git a/test/__snapshots__/target-browserslist.unittest.js.snap b/test/__snapshots__/target-browserslist.unittest.js.snap index 5ad5ef48319..613382978d6 100644 --- a/test/__snapshots__/target-browserslist.unittest.js.snap +++ b/test/__snapshots__/target-browserslist.unittest.js.snap @@ -3,6 +3,7 @@ exports[`browserslist target ["and_chr 80"] 1`] = ` Object { "arrowFunction": true, + "asyncFunction": true, "bigIntLiteral": true, "browser": true, "const": true, @@ -20,8 +21,11 @@ Object { "module": true, "node": false, "nodeBuiltins": false, + "nodePrefixForCoreModules": false, "nwjs": false, + "optionalChaining": true, "require": false, + "templateLiteral": true, "web": true, "webworker": false, } @@ -30,6 +34,7 @@ Object { exports[`browserslist target ["and_ff 68"] 1`] = ` Object { "arrowFunction": true, + "asyncFunction": true, "bigIntLiteral": true, "browser": true, "const": true, @@ -47,8 +52,11 @@ Object { "module": true, "node": false, "nodeBuiltins": false, + "nodePrefixForCoreModules": false, "nwjs": false, + "optionalChaining": false, "require": false, + "templateLiteral": true, "web": true, "webworker": false, } @@ -57,6 +65,7 @@ Object { exports[`browserslist target ["and_qq 10.4"] 1`] = ` Object { "arrowFunction": true, + "asyncFunction": false, "bigIntLiteral": false, "browser": true, "const": true, @@ -74,8 +83,11 @@ Object { "module": true, "node": false, "nodeBuiltins": false, + "nodePrefixForCoreModules": false, "nwjs": false, + "optionalChaining": false, "require": false, + "templateLiteral": true, "web": true, "webworker": false, } @@ -84,6 +96,7 @@ Object { exports[`browserslist target ["and_uc 12.12"] 1`] = ` Object { "arrowFunction": true, + "asyncFunction": false, "bigIntLiteral": false, "browser": true, "const": true, @@ -101,8 +114,11 @@ Object { "module": false, "node": false, "nodeBuiltins": false, + "nodePrefixForCoreModules": false, "nwjs": false, + "optionalChaining": false, "require": false, + "templateLiteral": true, "web": true, "webworker": false, } @@ -111,6 +127,7 @@ Object { exports[`browserslist target ["android 4"] 1`] = ` Object { "arrowFunction": false, + "asyncFunction": false, "bigIntLiteral": false, "browser": true, "const": false, @@ -128,8 +145,11 @@ Object { "module": false, "node": false, "nodeBuiltins": false, + "nodePrefixForCoreModules": false, "nwjs": false, + "optionalChaining": false, "require": false, + "templateLiteral": false, "web": true, "webworker": false, } @@ -138,6 +158,7 @@ Object { exports[`browserslist target ["android 4.1"] 1`] = ` Object { "arrowFunction": false, + "asyncFunction": false, "bigIntLiteral": false, "browser": true, "const": false, @@ -155,8 +176,11 @@ Object { "module": false, "node": false, "nodeBuiltins": false, + "nodePrefixForCoreModules": false, "nwjs": false, + "optionalChaining": false, "require": false, + "templateLiteral": false, "web": true, "webworker": false, } @@ -165,6 +189,7 @@ Object { exports[`browserslist target ["android 4.4.3-4.4.4"] 1`] = ` Object { "arrowFunction": false, + "asyncFunction": false, "bigIntLiteral": false, "browser": true, "const": false, @@ -182,8 +207,11 @@ Object { "module": false, "node": false, "nodeBuiltins": false, + "nodePrefixForCoreModules": false, "nwjs": false, + "optionalChaining": false, "require": false, + "templateLiteral": false, "web": true, "webworker": false, } @@ -192,6 +220,7 @@ Object { exports[`browserslist target ["android 81"] 1`] = ` Object { "arrowFunction": true, + "asyncFunction": true, "bigIntLiteral": true, "browser": true, "const": true, @@ -209,8 +238,11 @@ Object { "module": true, "node": false, "nodeBuiltins": false, + "nodePrefixForCoreModules": false, "nwjs": false, + "optionalChaining": true, "require": false, + "templateLiteral": true, "web": true, "webworker": false, } @@ -219,6 +251,7 @@ Object { exports[`browserslist target ["baidu 7.12"] 1`] = ` Object { "arrowFunction": true, + "asyncFunction": false, "bigIntLiteral": false, "browser": true, "const": false, @@ -236,8 +269,11 @@ Object { "module": false, "node": false, "nodeBuiltins": false, + "nodePrefixForCoreModules": false, "nwjs": false, + "optionalChaining": false, "require": false, + "templateLiteral": true, "web": true, "webworker": false, } @@ -246,6 +282,7 @@ Object { exports[`browserslist target ["bb 10"] 1`] = ` Object { "arrowFunction": false, + "asyncFunction": false, "bigIntLiteral": false, "browser": true, "const": false, @@ -263,8 +300,11 @@ Object { "module": false, "node": false, "nodeBuiltins": false, + "nodePrefixForCoreModules": false, "nwjs": false, + "optionalChaining": false, "require": false, + "templateLiteral": false, "web": true, "webworker": false, } @@ -273,12 +313,13 @@ Object { exports[`browserslist target ["chrome 80","node 12.19.0"] 1`] = ` Object { "arrowFunction": true, + "asyncFunction": true, "bigIntLiteral": true, "browser": null, "const": true, "destructuring": true, "document": null, - "dynamicImport": false, + "dynamicImport": true, "dynamicImportInWorker": false, "electron": false, "fetchWasm": null, @@ -287,11 +328,14 @@ Object { "globalThis": true, "importScripts": false, "importScriptsInWorker": true, - "module": false, + "module": true, "node": null, "nodeBuiltins": null, + "nodePrefixForCoreModules": null, "nwjs": false, + "optionalChaining": false, "require": null, + "templateLiteral": true, "web": null, "webworker": false, } @@ -300,6 +344,7 @@ Object { exports[`browserslist target ["chrome 80"] 1`] = ` Object { "arrowFunction": true, + "asyncFunction": true, "bigIntLiteral": true, "browser": true, "const": true, @@ -317,8 +362,11 @@ Object { "module": true, "node": false, "nodeBuiltins": false, + "nodePrefixForCoreModules": false, "nwjs": false, + "optionalChaining": true, "require": false, + "templateLiteral": true, "web": true, "webworker": false, } @@ -327,6 +375,7 @@ Object { exports[`browserslist target ["edge 79"] 1`] = ` Object { "arrowFunction": true, + "asyncFunction": true, "bigIntLiteral": true, "browser": true, "const": true, @@ -344,8 +393,11 @@ Object { "module": true, "node": false, "nodeBuiltins": false, + "nodePrefixForCoreModules": false, "nwjs": false, + "optionalChaining": false, "require": false, + "templateLiteral": true, "web": true, "webworker": false, } @@ -354,6 +406,7 @@ Object { exports[`browserslist target ["firefox 68"] 1`] = ` Object { "arrowFunction": true, + "asyncFunction": true, "bigIntLiteral": true, "browser": true, "const": true, @@ -371,8 +424,11 @@ Object { "module": true, "node": false, "nodeBuiltins": false, + "nodePrefixForCoreModules": false, "nwjs": false, + "optionalChaining": false, "require": false, + "templateLiteral": true, "web": true, "webworker": false, } @@ -381,6 +437,7 @@ Object { exports[`browserslist target ["firefox 80","chrome 80"] 1`] = ` Object { "arrowFunction": true, + "asyncFunction": true, "bigIntLiteral": true, "browser": true, "const": true, @@ -398,8 +455,11 @@ Object { "module": true, "node": false, "nodeBuiltins": false, + "nodePrefixForCoreModules": false, "nwjs": false, + "optionalChaining": true, "require": false, + "templateLiteral": true, "web": true, "webworker": false, } @@ -408,6 +468,7 @@ Object { exports[`browserslist target ["ie 11"] 1`] = ` Object { "arrowFunction": false, + "asyncFunction": false, "bigIntLiteral": false, "browser": true, "const": false, @@ -425,8 +486,11 @@ Object { "module": false, "node": false, "nodeBuiltins": false, + "nodePrefixForCoreModules": false, "nwjs": false, + "optionalChaining": false, "require": false, + "templateLiteral": false, "web": true, "webworker": false, } @@ -435,6 +499,7 @@ Object { exports[`browserslist target ["ie_mob 11"] 1`] = ` Object { "arrowFunction": false, + "asyncFunction": false, "bigIntLiteral": false, "browser": true, "const": false, @@ -452,8 +517,11 @@ Object { "module": false, "node": false, "nodeBuiltins": false, + "nodePrefixForCoreModules": false, "nwjs": false, + "optionalChaining": false, "require": false, + "templateLiteral": false, "web": true, "webworker": false, } @@ -462,6 +530,7 @@ Object { exports[`browserslist target ["ios_saf 12.0-12.1"] 1`] = ` Object { "arrowFunction": true, + "asyncFunction": true, "bigIntLiteral": false, "browser": true, "const": true, @@ -479,8 +548,11 @@ Object { "module": true, "node": false, "nodeBuiltins": false, + "nodePrefixForCoreModules": false, "nwjs": false, + "optionalChaining": false, "require": false, + "templateLiteral": true, "web": true, "webworker": false, } @@ -489,10 +561,11 @@ Object { exports[`browserslist target ["kaios 2.5"] 1`] = ` Object { "arrowFunction": true, + "asyncFunction": false, "bigIntLiteral": false, "browser": true, "const": true, - "destructuring": false, + "destructuring": true, "document": true, "dynamicImport": false, "dynamicImportInWorker": false, @@ -506,8 +579,11 @@ Object { "module": false, "node": false, "nodeBuiltins": false, + "nodePrefixForCoreModules": false, "nwjs": false, + "optionalChaining": false, "require": false, + "templateLiteral": true, "web": true, "webworker": false, } @@ -516,6 +592,7 @@ Object { exports[`browserslist target ["node 0.10.0"] 1`] = ` Object { "arrowFunction": false, + "asyncFunction": false, "bigIntLiteral": false, "browser": false, "const": false, @@ -533,8 +610,11 @@ Object { "module": false, "node": true, "nodeBuiltins": true, + "nodePrefixForCoreModules": false, "nwjs": false, + "optionalChaining": false, "require": true, + "templateLiteral": false, "web": false, "webworker": false, } @@ -543,6 +623,7 @@ Object { exports[`browserslist target ["node 0.12.0"] 1`] = ` Object { "arrowFunction": false, + "asyncFunction": false, "bigIntLiteral": false, "browser": false, "const": false, @@ -560,8 +641,11 @@ Object { "module": false, "node": true, "nodeBuiltins": true, + "nodePrefixForCoreModules": false, "nwjs": false, + "optionalChaining": false, "require": true, + "templateLiteral": false, "web": false, "webworker": false, } @@ -570,6 +654,7 @@ Object { exports[`browserslist target ["node 10.0.0"] 1`] = ` Object { "arrowFunction": true, + "asyncFunction": true, "bigIntLiteral": false, "browser": false, "const": true, @@ -587,8 +672,11 @@ Object { "module": false, "node": true, "nodeBuiltins": true, + "nodePrefixForCoreModules": false, "nwjs": false, + "optionalChaining": false, "require": true, + "templateLiteral": true, "web": false, "webworker": false, } @@ -597,6 +685,7 @@ Object { exports[`browserslist target ["node 10.17.0"] 1`] = ` Object { "arrowFunction": true, + "asyncFunction": true, "bigIntLiteral": true, "browser": false, "const": true, @@ -614,8 +703,11 @@ Object { "module": false, "node": true, "nodeBuiltins": true, + "nodePrefixForCoreModules": false, "nwjs": false, + "optionalChaining": false, "require": true, + "templateLiteral": true, "web": false, "webworker": false, } @@ -624,12 +716,13 @@ Object { exports[`browserslist target ["node 12.19.0"] 1`] = ` Object { "arrowFunction": true, + "asyncFunction": true, "bigIntLiteral": true, "browser": false, "const": true, "destructuring": true, "document": false, - "dynamicImport": false, + "dynamicImport": true, "dynamicImportInWorker": false, "electron": false, "fetchWasm": false, @@ -638,11 +731,14 @@ Object { "globalThis": true, "importScripts": false, "importScriptsInWorker": true, - "module": false, + "module": true, "node": true, "nodeBuiltins": true, + "nodePrefixForCoreModules": false, "nwjs": false, + "optionalChaining": false, "require": true, + "templateLiteral": true, "web": false, "webworker": false, } @@ -651,6 +747,7 @@ Object { exports[`browserslist target ["op_mini all"] 1`] = ` Object { "arrowFunction": false, + "asyncFunction": false, "bigIntLiteral": false, "browser": true, "const": false, @@ -668,8 +765,11 @@ Object { "module": false, "node": false, "nodeBuiltins": false, + "nodePrefixForCoreModules": false, "nwjs": false, + "optionalChaining": false, "require": false, + "templateLiteral": false, "web": true, "webworker": false, } @@ -678,6 +778,7 @@ Object { exports[`browserslist target ["op_mob 54"] 1`] = ` Object { "arrowFunction": true, + "asyncFunction": true, "bigIntLiteral": true, "browser": true, "const": true, @@ -695,8 +796,11 @@ Object { "module": true, "node": false, "nodeBuiltins": false, + "nodePrefixForCoreModules": false, "nwjs": false, + "optionalChaining": false, "require": false, + "templateLiteral": false, "web": true, "webworker": false, } @@ -705,6 +809,7 @@ Object { exports[`browserslist target ["opera 54"] 1`] = ` Object { "arrowFunction": true, + "asyncFunction": true, "bigIntLiteral": true, "browser": true, "const": true, @@ -722,8 +827,11 @@ Object { "module": true, "node": false, "nodeBuiltins": false, + "nodePrefixForCoreModules": false, "nwjs": false, + "optionalChaining": false, "require": false, + "templateLiteral": true, "web": true, "webworker": false, } @@ -732,6 +840,7 @@ Object { exports[`browserslist target ["safari 10"] 1`] = ` Object { "arrowFunction": true, + "asyncFunction": false, "bigIntLiteral": false, "browser": true, "const": false, @@ -749,8 +858,11 @@ Object { "module": false, "node": false, "nodeBuiltins": false, + "nodePrefixForCoreModules": false, "nwjs": false, + "optionalChaining": false, "require": false, + "templateLiteral": true, "web": true, "webworker": false, } @@ -759,6 +871,7 @@ Object { exports[`browserslist target ["safari 11"] 1`] = ` Object { "arrowFunction": true, + "asyncFunction": true, "bigIntLiteral": false, "browser": true, "const": true, @@ -776,8 +889,11 @@ Object { "module": true, "node": false, "nodeBuiltins": false, + "nodePrefixForCoreModules": false, "nwjs": false, + "optionalChaining": false, "require": false, + "templateLiteral": true, "web": true, "webworker": false, } @@ -786,6 +902,7 @@ Object { exports[`browserslist target ["safari 12.0"] 1`] = ` Object { "arrowFunction": true, + "asyncFunction": true, "bigIntLiteral": false, "browser": true, "const": true, @@ -803,8 +920,11 @@ Object { "module": true, "node": false, "nodeBuiltins": false, + "nodePrefixForCoreModules": false, "nwjs": false, + "optionalChaining": false, "require": false, + "templateLiteral": true, "web": true, "webworker": false, } @@ -813,6 +933,7 @@ Object { exports[`browserslist target ["safari 12.1"] 1`] = ` Object { "arrowFunction": true, + "asyncFunction": true, "bigIntLiteral": false, "browser": true, "const": true, @@ -830,8 +951,11 @@ Object { "module": true, "node": false, "nodeBuiltins": false, + "nodePrefixForCoreModules": false, "nwjs": false, + "optionalChaining": false, "require": false, + "templateLiteral": true, "web": true, "webworker": false, } @@ -840,6 +964,7 @@ Object { exports[`browserslist target ["safari 13"] 1`] = ` Object { "arrowFunction": true, + "asyncFunction": true, "bigIntLiteral": false, "browser": true, "const": true, @@ -857,8 +982,11 @@ Object { "module": true, "node": false, "nodeBuiltins": false, + "nodePrefixForCoreModules": false, "nwjs": false, + "optionalChaining": false, "require": false, + "templateLiteral": true, "web": true, "webworker": false, } @@ -867,6 +995,7 @@ Object { exports[`browserslist target ["safari TP"] 1`] = ` Object { "arrowFunction": true, + "asyncFunction": true, "bigIntLiteral": true, "browser": true, "const": true, @@ -884,8 +1013,11 @@ Object { "module": true, "node": false, "nodeBuiltins": false, + "nodePrefixForCoreModules": false, "nwjs": false, + "optionalChaining": true, "require": false, + "templateLiteral": true, "web": true, "webworker": false, } @@ -894,6 +1026,7 @@ Object { exports[`browserslist target ["samsung 4"] 1`] = ` Object { "arrowFunction": false, + "asyncFunction": false, "bigIntLiteral": false, "browser": true, "const": false, @@ -911,8 +1044,11 @@ Object { "module": false, "node": false, "nodeBuiltins": false, + "nodePrefixForCoreModules": false, "nwjs": false, + "optionalChaining": false, "require": false, + "templateLiteral": true, "web": true, "webworker": false, } @@ -921,6 +1057,7 @@ Object { exports[`browserslist target ["samsung 9.2"] 1`] = ` Object { "arrowFunction": true, + "asyncFunction": true, "bigIntLiteral": true, "browser": true, "const": true, @@ -938,8 +1075,11 @@ Object { "module": true, "node": false, "nodeBuiltins": false, + "nodePrefixForCoreModules": false, "nwjs": false, + "optionalChaining": false, "require": false, + "templateLiteral": true, "web": true, "webworker": false, } @@ -948,6 +1088,7 @@ Object { exports[`browserslist target ["samsung 11.1-11.2"] 1`] = ` Object { "arrowFunction": true, + "asyncFunction": true, "bigIntLiteral": true, "browser": true, "const": true, @@ -965,8 +1106,11 @@ Object { "module": true, "node": false, "nodeBuiltins": false, + "nodePrefixForCoreModules": false, "nwjs": false, + "optionalChaining": false, "require": false, + "templateLiteral": true, "web": true, "webworker": false, } @@ -975,6 +1119,7 @@ Object { exports[`browserslist target ["unknown 50"] 1`] = ` Object { "arrowFunction": false, + "asyncFunction": false, "bigIntLiteral": false, "browser": true, "const": false, @@ -992,8 +1137,11 @@ Object { "module": false, "node": false, "nodeBuiltins": false, + "nodePrefixForCoreModules": false, "nwjs": false, + "optionalChaining": false, "require": false, + "templateLiteral": false, "web": true, "webworker": false, } diff --git a/test/benchmarkCases/many-chunks/b.js b/test/benchmarkCases/many-chunks/b.js index 670c28f0d85..3d3fd298ee3 100644 --- a/test/benchmarkCases/many-chunks/b.js +++ b/test/benchmarkCases/many-chunks/b.js @@ -3,4 +3,4 @@ import("./c?1" + __resourceQuery); import("./c?2" + __resourceQuery); import("./c?3" + __resourceQuery); import("./c?4" + __resourceQuery); -import("./a" + __resourceQuery.substr(0, 2)); +import("./a" + __resourceQuery.slice(0, 2)); diff --git a/test/benchmarkCases/many-modules-source-map/b.js b/test/benchmarkCases/many-modules-source-map/b.js index 269a2572379..d0d91d3f727 100644 --- a/test/benchmarkCases/many-modules-source-map/b.js +++ b/test/benchmarkCases/many-modules-source-map/b.js @@ -8,4 +8,4 @@ require("./c?6" + __resourceQuery); require("./c?7" + __resourceQuery); require("./c?8" + __resourceQuery); require("./c?9" + __resourceQuery); -require("./a" + __resourceQuery.substr(0, 2)); +require("./a" + __resourceQuery.slice(0, 2)); diff --git a/test/benchmarkCases/many-modules/b.js b/test/benchmarkCases/many-modules/b.js index 269a2572379..d0d91d3f727 100644 --- a/test/benchmarkCases/many-modules/b.js +++ b/test/benchmarkCases/many-modules/b.js @@ -8,4 +8,4 @@ require("./c?6" + __resourceQuery); require("./c?7" + __resourceQuery); require("./c?8" + __resourceQuery); require("./c?9" + __resourceQuery); -require("./a" + __resourceQuery.substr(0, 2)); +require("./a" + __resourceQuery.slice(0, 2)); diff --git a/test/benchmarkCases/many-stuff-harmony/a.js b/test/benchmarkCases/many-stuff-harmony/a.js index be76a218755..30dd82bc0e2 100644 --- a/test/benchmarkCases/many-stuff-harmony/a.js +++ b/test/benchmarkCases/many-stuff-harmony/a.js @@ -1,7 +1,7 @@ module.exports = function() { let str = ""; let sum = ["1"]; - const query = +this.query.substr(1); + const query = +this.query.slice(1); for(let i = 0; i < query; i++) { str += `import b${i} from "./b?${Math.floor(i/2)}!";\n`; sum.push(`b${i}`); diff --git a/test/cases/async-modules/double-import/a.js b/test/cases/async-modules/double-import/a.js new file mode 100644 index 00000000000..1f752aa2b54 --- /dev/null +++ b/test/cases/async-modules/double-import/a.js @@ -0,0 +1,3 @@ +import x from "./shared"; + +export default x + " world"; diff --git a/test/cases/async-modules/double-import/b.js b/test/cases/async-modules/double-import/b.js new file mode 100644 index 00000000000..1f752aa2b54 --- /dev/null +++ b/test/cases/async-modules/double-import/b.js @@ -0,0 +1,3 @@ +import x from "./shared"; + +export default x + " world"; diff --git a/test/cases/async-modules/double-import/index.js b/test/cases/async-modules/double-import/index.js new file mode 100644 index 00000000000..d84fc8076af --- /dev/null +++ b/test/cases/async-modules/double-import/index.js @@ -0,0 +1,4 @@ +it("should allow to import an async module twice", async () => { + const result = await require("./main"); + expect(result.default).toBe("hello world, hello world"); +}); diff --git a/test/cases/async-modules/double-import/main.js b/test/cases/async-modules/double-import/main.js new file mode 100644 index 00000000000..2bd775ed752 --- /dev/null +++ b/test/cases/async-modules/double-import/main.js @@ -0,0 +1,4 @@ +import a from "./a"; +import b from "./b"; + +export default a + ", " + b; diff --git a/test/cases/async-modules/double-import/shared.js b/test/cases/async-modules/double-import/shared.js new file mode 100644 index 00000000000..6d4c734a406 --- /dev/null +++ b/test/cases/async-modules/double-import/shared.js @@ -0,0 +1,3 @@ +await 1; +await 1; +export default "hello"; diff --git a/test/cases/async-modules/issue-16097/index.js b/test/cases/async-modules/issue-16097/index.js new file mode 100644 index 00000000000..d0fc5d626e1 --- /dev/null +++ b/test/cases/async-modules/issue-16097/index.js @@ -0,0 +1,6 @@ +import i, { foo } from "./won't-run-tla"; + +it("should have value imported from won't-run-tla", async () => { + expect(i).toBe(42); + expect(foo).toBe(undefined); +}); diff --git a/test/cases/async-modules/issue-16097/won't-run-tla.js b/test/cases/async-modules/issue-16097/won't-run-tla.js new file mode 100644 index 00000000000..786e32c1cf3 --- /dev/null +++ b/test/cases/async-modules/issue-16097/won't-run-tla.js @@ -0,0 +1,4 @@ +global.someNonExistentVariable && await 'test'; +const foo = global.otherSomeNonExistentVariable && await 43; +export default 42; +export { foo } diff --git a/test/cases/async-modules/reexport-unknown/async-unknown.js b/test/cases/async-modules/reexport-unknown/async-unknown.js new file mode 100644 index 00000000000..ca2eb248ac7 --- /dev/null +++ b/test/cases/async-modules/reexport-unknown/async-unknown.js @@ -0,0 +1,3 @@ +export * from "./unknown.js"; + +await 1; diff --git a/test/cases/async-modules/reexport-unknown/index.js b/test/cases/async-modules/reexport-unknown/index.js new file mode 100644 index 00000000000..303a8df3157 --- /dev/null +++ b/test/cases/async-modules/reexport-unknown/index.js @@ -0,0 +1,2 @@ +it("should handle re-export from async modules correctly", () => + import("./test.js")); diff --git a/test/cases/async-modules/reexport-unknown/reexport-async-unknown.js b/test/cases/async-modules/reexport-unknown/reexport-async-unknown.js new file mode 100644 index 00000000000..49ae13b84c1 --- /dev/null +++ b/test/cases/async-modules/reexport-unknown/reexport-async-unknown.js @@ -0,0 +1,3 @@ +export * from "./async-unknown.js"; +export { a } from "./async-unknown.js"; +export default "default"; diff --git a/test/cases/async-modules/reexport-unknown/test.js b/test/cases/async-modules/reexport-unknown/test.js new file mode 100644 index 00000000000..3d5ccedf9d9 --- /dev/null +++ b/test/cases/async-modules/reexport-unknown/test.js @@ -0,0 +1,23 @@ +import * as ns from "./reexport-async-unknown.js?ns"; +import { a, b, c } from "./reexport-async-unknown.js?named"; +import value from "./reexport-async-unknown.js?default"; + +function nsObj(m) { + Object.defineProperty(m, Symbol.toStringTag, { value: "Module" }); + return m; +} + +expect(ns).toEqual( + nsObj({ + default: "default", + a: "a", + b: "b", + c: "c" + }) +); + +expect(a).toBe("a"); +expect(b).toBe("b"); +expect(c).toBe("c"); + +expect(value).toBe("default"); diff --git a/test/cases/async-modules/reexport-unknown/unknown.js b/test/cases/async-modules/reexport-unknown/unknown.js new file mode 100644 index 00000000000..293d229b741 --- /dev/null +++ b/test/cases/async-modules/reexport-unknown/unknown.js @@ -0,0 +1,7 @@ +const o = { + a: "a", + b: "b", + c: "c" +}; + +module.exports = Object(o); diff --git a/test/cases/async-modules/runtime-performance/async.js b/test/cases/async-modules/runtime-performance/async.js new file mode 100644 index 00000000000..03ed4ae4663 --- /dev/null +++ b/test/cases/async-modules/runtime-performance/async.js @@ -0,0 +1,2 @@ +await 1; +export default 1; diff --git a/test/cases/async-modules/runtime-performance/index.js b/test/cases/async-modules/runtime-performance/index.js new file mode 100644 index 00000000000..1aca8000cd4 --- /dev/null +++ b/test/cases/async-modules/runtime-performance/index.js @@ -0,0 +1,5 @@ +it("should not take too long to evaluate nested async modules", async () => { + const start = Date.now(); + await import(/* webpackMode: "eager" */ "./loader.js?i=40!./loader.js"); + expect(Date.now() - start).toBeLessThan(100); +}); diff --git a/test/cases/async-modules/runtime-performance/loader.js b/test/cases/async-modules/runtime-performance/loader.js new file mode 100644 index 00000000000..ea46f2bea9b --- /dev/null +++ b/test/cases/async-modules/runtime-performance/loader.js @@ -0,0 +1,14 @@ +/** @type {import("../../../../").LoaderDefinition<{ i: string }>} */ +module.exports = function () { + const options = this.getOptions(); + const i = +options.i; + let src = `import n from "./async.js";\n`; + if (i > 0) { + src += `import a from "./loader.js?i=${i - 1}&a!./loader.js";\n`; + src += `import b from "./loader.js?i=${i - 1}&b!./loader.js";\n`; + src += `export default n + a + b;\n`; + } else { + src += `export default n;\n`; + } + return src; +}; diff --git a/test/cases/async-modules/top-level-error/counter.js b/test/cases/async-modules/top-level-error/counter.js new file mode 100644 index 00000000000..45158af96f0 --- /dev/null +++ b/test/cases/async-modules/top-level-error/counter.js @@ -0,0 +1,6 @@ +await 1; +let value = 0; +export const count = () => { + value++; + return value; +}; diff --git a/test/cases/async-modules/top-level-error/index.js b/test/cases/async-modules/top-level-error/index.js new file mode 100644 index 00000000000..6a5d4b995fa --- /dev/null +++ b/test/cases/async-modules/top-level-error/index.js @@ -0,0 +1,39 @@ +it("should allow to import an rejected async module again", async () => { + await expect(require("./main")).rejects.toEqual( + expect.objectContaining({ + message: expect.stringContaining("expected rejection 1") + }) + ); + await expect(require("./module")).rejects.toEqual( + expect.objectContaining({ + message: expect.stringContaining("expected rejection 1") + }) + ); + await expect(require("./module?2")).rejects.toEqual( + expect.objectContaining({ + message: expect.stringContaining("expected rejection 2") + }) + ); + await expect(require("./reexport?2")).rejects.toEqual( + expect.objectContaining({ + message: expect.stringContaining("expected rejection 1") + }) + ); + await Promise.all([ + expect(require("./module?3")).rejects.toEqual( + expect.objectContaining({ + message: expect.stringContaining("expected rejection 3") + }) + ), + expect(require("./module?4")).rejects.toEqual( + expect.objectContaining({ + message: expect.stringContaining("expected rejection 4") + }) + ), + expect(require("./module?5")).rejects.toEqual( + expect.objectContaining({ + message: expect.stringContaining("expected rejection 5") + }) + ) + ]); +}); diff --git a/test/cases/async-modules/top-level-error/main.js b/test/cases/async-modules/top-level-error/main.js new file mode 100644 index 00000000000..bfc4f032eea --- /dev/null +++ b/test/cases/async-modules/top-level-error/main.js @@ -0,0 +1,2 @@ +export { default as a } from "./reexport"; +export { default as b } from "./module?2"; diff --git a/test/cases/async-modules/top-level-error/module.js b/test/cases/async-modules/top-level-error/module.js new file mode 100644 index 00000000000..e8096da821a --- /dev/null +++ b/test/cases/async-modules/top-level-error/module.js @@ -0,0 +1,6 @@ +import { count } from "./counter"; + +const c = count(); +throw new Error("expected rejection " + c); + +export default "ok"; diff --git a/test/cases/async-modules/top-level-error/reexport.js b/test/cases/async-modules/top-level-error/reexport.js new file mode 100644 index 00000000000..b29130d0f5f --- /dev/null +++ b/test/cases/async-modules/top-level-error/reexport.js @@ -0,0 +1 @@ +export { default as default } from "./module"; diff --git a/test/cases/chunks/context-weak/index.js b/test/cases/chunks/context-weak/index.js index 65aa0c58c1d..e4f711141f5 100644 --- a/test/cases/chunks/context-weak/index.js +++ b/test/cases/chunks/context-weak/index.js @@ -5,6 +5,17 @@ it("should not bundle context requires with asyncMode === 'weak'", function() { }).toThrowError(/not available/); }); +it("should not bundle context requires with asyncMode === 'weak' using import.meta.webpackContext", function() { + const contextRequire = import.meta.webpackContext(".", { + recursive: false, + regExp: /two/, + mode: "weak" + }); + expect(function() { + contextRequire("./two") + }).toThrowError(/not available/); +}); + it("should find module with asyncMode === 'weak' when required elsewhere", function() { var contextRequire = require.context(".", false, /.+/, "weak"); expect(contextRequire("./three")).toBe(3); diff --git a/test/cases/chunks/destructuring-assignment/dir1/a.js b/test/cases/chunks/destructuring-assignment/dir1/a.js new file mode 100644 index 00000000000..ce622ee6530 --- /dev/null +++ b/test/cases/chunks/destructuring-assignment/dir1/a.js @@ -0,0 +1,3 @@ +export const a = 1; +export default 3; +export const usedExports = __webpack_exports_info__.usedExports; diff --git a/test/cases/chunks/destructuring-assignment/dir2/a.js b/test/cases/chunks/destructuring-assignment/dir2/a.js new file mode 100644 index 00000000000..59aa6ffd125 --- /dev/null +++ b/test/cases/chunks/destructuring-assignment/dir2/a.js @@ -0,0 +1,2 @@ +exports.a = 1; +exports.b = 2; diff --git a/test/cases/chunks/destructuring-assignment/dir2/json/array.json b/test/cases/chunks/destructuring-assignment/dir2/json/array.json new file mode 100644 index 00000000000..eac5f7b46e0 --- /dev/null +++ b/test/cases/chunks/destructuring-assignment/dir2/json/array.json @@ -0,0 +1 @@ +["a"] \ No newline at end of file diff --git a/test/cases/chunks/destructuring-assignment/dir2/json/object.json b/test/cases/chunks/destructuring-assignment/dir2/json/object.json new file mode 100644 index 00000000000..cb5b2f69bab --- /dev/null +++ b/test/cases/chunks/destructuring-assignment/dir2/json/object.json @@ -0,0 +1 @@ +{"a": 1} diff --git a/test/cases/chunks/destructuring-assignment/dir2/json/primitive.json b/test/cases/chunks/destructuring-assignment/dir2/json/primitive.json new file mode 100644 index 00000000000..231f150c579 --- /dev/null +++ b/test/cases/chunks/destructuring-assignment/dir2/json/primitive.json @@ -0,0 +1 @@ +"a" diff --git a/test/cases/chunks/destructuring-assignment/index.js b/test/cases/chunks/destructuring-assignment/index.js new file mode 100644 index 00000000000..1725b877fdb --- /dev/null +++ b/test/cases/chunks/destructuring-assignment/index.js @@ -0,0 +1,23 @@ +it("should load only used exports", async (done) => { + const { default: def, usedExports } = await import("./dir1/a"); + expect(def).toBe(3); + expect(usedExports).toEqual(["default", "usedExports"]); + done(); +}); + +it("should get warning on using 'webpackExports' with destructuring assignment", async (done) => { + const { default: def } = await import(/* webpackExports: ["a"] */"./dir1/a?2"); + expect(def).toBe(3); + done(); +}); + +it("should not tree-shake default export for exportsType=default module", async () => { + const { default: object } = await import("./dir2/json/object.json"); + const { default: array } = await import("./dir2/json/array.json"); + const { default: primitive } = await import("./dir2/json/primitive.json"); + expect(object).toEqual({ a: 1 }); + expect(array).toEqual(["a"]); + expect(primitive).toBe("a"); + const { default: a } = await import("./dir2/a"); + expect(a).toEqual({ a: 1, b: 2 }); +}); diff --git a/test/cases/chunks/destructuring-assignment/test.filter.js b/test/cases/chunks/destructuring-assignment/test.filter.js new file mode 100644 index 00000000000..f176154b261 --- /dev/null +++ b/test/cases/chunks/destructuring-assignment/test.filter.js @@ -0,0 +1,4 @@ +module.exports = function (config) { + // This test can't run in development mode + return config.mode !== "development"; +}; diff --git a/test/cases/chunks/destructuring-assignment/warnings.js b/test/cases/chunks/destructuring-assignment/warnings.js new file mode 100644 index 00000000000..f2a8d6f3837 --- /dev/null +++ b/test/cases/chunks/destructuring-assignment/warnings.js @@ -0,0 +1,3 @@ +module.exports = [ + [/`webpackExports` could not be used with destructuring assignment./] +]; diff --git a/test/cases/chunks/inline-options/dir14/a.js b/test/cases/chunks/inline-options/dir14/a.js new file mode 100644 index 00000000000..e94fef18587 --- /dev/null +++ b/test/cases/chunks/inline-options/dir14/a.js @@ -0,0 +1 @@ +export default "a"; diff --git a/test/cases/chunks/inline-options/dir14/b.js b/test/cases/chunks/inline-options/dir14/b.js new file mode 100644 index 00000000000..eff703ff465 --- /dev/null +++ b/test/cases/chunks/inline-options/dir14/b.js @@ -0,0 +1 @@ +export default "b"; diff --git a/test/cases/chunks/inline-options/dir14/c.js b/test/cases/chunks/inline-options/dir14/c.js new file mode 100644 index 00000000000..5d50db5bc15 --- /dev/null +++ b/test/cases/chunks/inline-options/dir14/c.js @@ -0,0 +1 @@ +export default "c"; diff --git a/test/cases/chunks/inline-options/dir15/a.js b/test/cases/chunks/inline-options/dir15/a.js new file mode 100644 index 00000000000..59aa6ffd125 --- /dev/null +++ b/test/cases/chunks/inline-options/dir15/a.js @@ -0,0 +1,2 @@ +exports.a = 1; +exports.b = 2; diff --git a/test/cases/chunks/inline-options/dir15/json/array.json b/test/cases/chunks/inline-options/dir15/json/array.json new file mode 100644 index 00000000000..eac5f7b46e0 --- /dev/null +++ b/test/cases/chunks/inline-options/dir15/json/array.json @@ -0,0 +1 @@ +["a"] \ No newline at end of file diff --git a/test/cases/chunks/inline-options/dir15/json/object.json b/test/cases/chunks/inline-options/dir15/json/object.json new file mode 100644 index 00000000000..cb5b2f69bab --- /dev/null +++ b/test/cases/chunks/inline-options/dir15/json/object.json @@ -0,0 +1 @@ +{"a": 1} diff --git a/test/cases/chunks/inline-options/dir15/json/primitive.json b/test/cases/chunks/inline-options/dir15/json/primitive.json new file mode 100644 index 00000000000..231f150c579 --- /dev/null +++ b/test/cases/chunks/inline-options/dir15/json/primitive.json @@ -0,0 +1 @@ +"a" diff --git a/test/cases/chunks/inline-options/index.js b/test/cases/chunks/inline-options/index.js index 4b127cc089c..f75ddad9041 100644 --- a/test/cases/chunks/inline-options/index.js +++ b/test/cases/chunks/inline-options/index.js @@ -60,7 +60,7 @@ it("should be able to combine chunks by name", function () { case "d": return import(/* webpackChunkName: "name-3" */ "./dir7/d"); default: - throw new Error("Unexcepted test data"); + throw new Error("Unexpected test data"); } } return testChunkLoading(load, false, true); @@ -86,7 +86,7 @@ it("should be able to use weak mode (without context)", function () { case "c": return import(/* webpackMode: "weak" */ "./dir9/c"); default: - throw new Error("Unexcepted test data"); + throw new Error("Unexpected test data"); } } require("./dir9/a"); // chunks served manually by the user @@ -180,6 +180,29 @@ if (process.env.NODE_ENV === "production") { } ); }); + + it("should be able to load with webpackFetchPriority high, low and auto", function () { + return Promise.all([ + import(/* webpackFetchPriority: "high"*/ "./dir14/a"), + import(/* webpackFetchPriority: "low"*/ "./dir14/b"), + import(/* webpackFetchPriority: "auto"*/ "./dir14/c"), + ]) + }) + + it("should not tree-shake default export for exportsType=default module", async function () { + const jsonObject = await import(/* webpackExports: ["default"] */ "./dir15/json/object.json"); + const jsonArray = await import(/* webpackExports: ["default"] */ "./dir15/json/array.json"); + const jsonPrimitive = await import(/* webpackExports: ["default"] */ "./dir15/json/primitive.json"); + expect(jsonObject.default).toEqual({ a: 1 }); + expect(jsonObject.a).toEqual(1); + expect(jsonArray.default).toEqual(["a"]); + expect(jsonArray[0]).toBe("a"); + expect(jsonPrimitive.default).toBe("a"); + const a = await import(/* webpackExports: ["default"] */"./dir15/a"); + expect(a.default).toEqual({ a: 1, b: 2 }); + expect(a.a).toBe(1); + expect(a.b).toBe(2); + }) } function testChunkLoading(load, expectedSyncInitial, expectedSyncRequested) { diff --git a/test/cases/chunks/named-chunks/index.js b/test/cases/chunks/named-chunks/index.js index 1897b9a0b6b..0f3bad6211d 100644 --- a/test/cases/chunks/named-chunks/index.js +++ b/test/cases/chunks/named-chunks/index.js @@ -94,6 +94,7 @@ it("should be able to use named chunks in import()", function(done) { }); it("should be able to use named chunk in context import()", function(done) { + // cspell:ignore mpty var mpty = "mpty"; var sync = false; import("./e" + mpty + "2" /* webpackChunkName: "context-named-chunk" */).then(function(result) { diff --git a/test/cases/chunks/runtime/test.filter.js b/test/cases/chunks/runtime/test.filter.js index 3ed2e8ae961..7ba4ada1c94 100644 --- a/test/cases/chunks/runtime/test.filter.js +++ b/test/cases/chunks/runtime/test.filter.js @@ -1,4 +1,4 @@ -module.exports = function(config) { +module.exports = function (config) { // This test can't run in development mode as it depends on the flagIncludedChunks optimization return config.mode !== "development"; }; diff --git a/test/cases/chunks/weird-reference-to-entry/errors.js b/test/cases/chunks/weird-reference-to-entry/errors.js index 5cdd2850ba3..0eda0fbec8e 100644 --- a/test/cases/chunks/weird-reference-to-entry/errors.js +++ b/test/cases/chunks/weird-reference-to-entry/errors.js @@ -1,3 +1,5 @@ module.exports = [ - [/It's not allowed to load an initial chunk on demand\. The chunk name "main" is already used by an entrypoint\./], + [ + /It's not allowed to load an initial chunk on demand\. The chunk name "main" is already used by an entrypoint\./ + ] ]; diff --git a/test/cases/cjs-tree-shaking/object-define-property-replace/index.js b/test/cases/cjs-tree-shaking/object-define-property-replace/index.js index 47e843e3afe..b93250f8526 100644 --- a/test/cases/cjs-tree-shaking/object-define-property-replace/index.js +++ b/test/cases/cjs-tree-shaking/object-define-property-replace/index.js @@ -1,3 +1,3 @@ -it("should replace Object.defineProperty correctly with brakets", () => { +it("should replace Object.defineProperty correctly with brackets", () => { expect(require("./module").test).toBe(true); }); diff --git a/test/cases/compile/error-hide-stack/errors.js b/test/cases/compile/error-hide-stack/errors.js index 4c65e31d637..6d8bf4df7a7 100644 --- a/test/cases/compile/error-hide-stack/errors.js +++ b/test/cases/compile/error-hide-stack/errors.js @@ -1,6 +1,3 @@ module.exports = [ - [ - /Module build failed( \(from [^)]+\))?:\nMessage/, - {details: /Stack/} - ] + [/Module build failed( \(from [^)]+\))?:\nMessage/, { details: /Stack/ }] ]; diff --git a/test/cases/compile/error-hide-stack/infrastructure-log.js b/test/cases/compile/error-hide-stack/infrastructure-log.js new file mode 100644 index 00000000000..83685aa57b3 --- /dev/null +++ b/test/cases/compile/error-hide-stack/infrastructure-log.js @@ -0,0 +1,3 @@ +module.exports = [ + /^Pack got invalid because of write to: Compilation\/modules.+loader\.js!$/ +]; diff --git a/test/cases/compile/error-hide-stack/loader.js b/test/cases/compile/error-hide-stack/loader.js index 674e66c655f..b499c32a083 100644 --- a/test/cases/compile/error-hide-stack/loader.js +++ b/test/cases/compile/error-hide-stack/loader.js @@ -1,6 +1,8 @@ -module.exports = function() { +/** @type {import("../../../../").LoaderDefinition} */ +module.exports = function () { var err = new Error("Message"); err.stack = "Stack"; + //@ts-expect-error hideStack is not a property on normal errors err.hideStack = true; throw err; }; diff --git a/test/cases/compile/long-module-chain/module.js b/test/cases/compile/long-module-chain/module.js index 30bf15c0cfc..10eccfc47bd 100644 --- a/test/cases/compile/long-module-chain/module.js +++ b/test/cases/compile/long-module-chain/module.js @@ -1,5 +1,5 @@ if(__resourceQuery === "?0") { module.exports = "module"; } else { - module.exports = require("./module?" + (+__resourceQuery.substr(1) - 1)); + module.exports = require("./module?" + (+__resourceQuery.slice(1) - 1)); } diff --git a/test/cases/context/import-meta-webpack-context/dir/four.js b/test/cases/context/import-meta-webpack-context/dir/four.js new file mode 100644 index 00000000000..a9bbdd80578 --- /dev/null +++ b/test/cases/context/import-meta-webpack-context/dir/four.js @@ -0,0 +1 @@ +module.exports = 4; diff --git a/test/cases/context/import-meta-webpack-context/index.js b/test/cases/context/import-meta-webpack-context/index.js new file mode 100644 index 00000000000..9ad5d42ee59 --- /dev/null +++ b/test/cases/context/import-meta-webpack-context/index.js @@ -0,0 +1,27 @@ +it("should allow prefetch/preload", function() { + const contextRequire = import.meta.webpackContext("./dir", { + prefetch: true, + preload: 1 + }); + expect(contextRequire("./four")).toBe(4); +}); + +it("should allow include/exclude", function() { + const contextRequire = import.meta.webpackContext(".", { + recursive: false, + regExp: /two/, + mode: "weak", + exclude: /three/ + }); + expect(function() { + contextRequire("./two-three") + }).toThrowError(/Cannot find module/); +}); + +it("should allow chunkName", function() { + const contextRequire = import.meta.webpackContext(".", { + regExp: /two-three/, + chunkName: "chunk012" + }); + expect(contextRequire("./two-three")).toBe(3); +}); diff --git a/test/cases/context/import-meta-webpack-context/two-three.js b/test/cases/context/import-meta-webpack-context/two-three.js new file mode 100644 index 00000000000..690aad34a46 --- /dev/null +++ b/test/cases/context/import-meta-webpack-context/two-three.js @@ -0,0 +1 @@ +module.exports = 3; diff --git a/test/cases/context/import-meta-webpack-context/two.js b/test/cases/context/import-meta-webpack-context/two.js new file mode 100644 index 00000000000..4bbffde1044 --- /dev/null +++ b/test/cases/context/import-meta-webpack-context/two.js @@ -0,0 +1 @@ +module.exports = 2; diff --git a/test/cases/context/issue-10969/index.js b/test/cases/context/issue-10969/index.js index b0403cb8c9f..200b8f31018 100644 --- a/test/cases/context/issue-10969/index.js +++ b/test/cases/context/issue-10969/index.js @@ -1,21 +1,12 @@ -expect.extend({ - toBeValidModuleId(received, moduleIdString) { - const pass = typeof received === "number" || received === moduleIdString; - if (pass) { - return { - message: () => `expected ${received} not to be a valid module id`, - pass: true - }; - } else { - return { - message: () => `expected ${received} to be a valid module id`, - pass: false - }; - } - } -}); - it("should replace ! with %21 in the module id string of the context module", function () { - const moduleId = require.context("./folder", true, /^(?!file1\.js$).*$/i, "lazy").id; - expect(moduleId).toBeValidModuleId("./context/issue-10969/folder lazy recursive ^(?%21file1\\.js$).*$/"); + const moduleId = require.context( + "./folder", + true, + /^(?!file1\.js$).*$/i, + "lazy" + ).id; + if (typeof moduleId !== "number") + expect(moduleId).toBe( + "./context/issue-10969/folder lazy recursive ^(?%21file1\\.js$).*$i" + ); }); diff --git a/test/cases/context/issue-5750/warnings.js b/test/cases/context/issue-5750/warnings.js index 62587ab93e0..957d94c627f 100644 --- a/test/cases/context/issue-5750/warnings.js +++ b/test/cases/context/issue-5750/warnings.js @@ -1,3 +1,3 @@ module.exports = [ - [/Critical dependency: Contexts can't use RegExps with the 'g' or 'y' flags/], + [/Critical dependency: Contexts can't use RegExps with the 'g' or 'y' flags/] ]; diff --git a/test/cases/errors/case-sensitive/test.filter.js b/test/cases/errors/case-sensitive/test.filter.js index 9ae7a5027bc..c3e1f9382ec 100644 --- a/test/cases/errors/case-sensitive/test.filter.js +++ b/test/cases/errors/case-sensitive/test.filter.js @@ -1,6 +1,6 @@ var fs = require("fs"); var path = require("path"); -module.exports = function(config) { +module.exports = function (config) { return fs.existsSync(path.join(__dirname, "TEST.FILTER.JS")); }; diff --git a/test/cases/errors/case-sensitive/warnings.js b/test/cases/errors/case-sensitive/warnings.js index 99ac2e5cf9e..1a2c38230f1 100644 --- a/test/cases/errors/case-sensitive/warnings.js +++ b/test/cases/errors/case-sensitive/warnings.js @@ -1,4 +1,12 @@ module.exports = [ - [/There are multiple modules with names that only differ in casing/, /case-sensitive.A\.js/, /case-sensitive.a\.js/], - [/There are multiple modules with names that only differ in casing/, /case-sensitive.B.file\.js/, /case-sensitive.b.file\.js/] + [ + /There are multiple modules with names that only differ in casing/, + /case-sensitive.A\.js/, + /case-sensitive.a\.js/ + ], + [ + /There are multiple modules with names that only differ in casing/, + /case-sensitive.B.file\.js/, + /case-sensitive.b.file\.js/ + ] ]; diff --git a/test/cases/errors/crash-missing-import/errors.js b/test/cases/errors/crash-missing-import/errors.js index 4eefda428cf..d85236a2c74 100644 --- a/test/cases/errors/crash-missing-import/errors.js +++ b/test/cases/errors/crash-missing-import/errors.js @@ -1,3 +1 @@ -module.exports = [ - [/Module not found/], -]; +module.exports = [[/Module not found/]]; diff --git a/test/cases/errors/harmony-import-missing/errors.js b/test/cases/errors/harmony-import-missing/errors.js index 6084546bf7b..baab751255d 100644 --- a/test/cases/errors/harmony-import-missing/errors.js +++ b/test/cases/errors/harmony-import-missing/errors.js @@ -1,5 +1 @@ -module.exports = [ - [ - /Can't resolve '.\/missing'/ - ] -]; +module.exports = [[/Can't resolve '.\/missing'/]]; diff --git a/test/cases/errors/import-module-cycle-multiple/1/a.json b/test/cases/errors/import-module-cycle-multiple/1/a.json new file mode 100644 index 00000000000..9a389c9696a --- /dev/null +++ b/test/cases/errors/import-module-cycle-multiple/1/a.json @@ -0,0 +1 @@ +"./a.json" diff --git a/test/cases/errors/import-module-cycle-multiple/2/a.json b/test/cases/errors/import-module-cycle-multiple/2/a.json new file mode 100644 index 00000000000..75e02a30f04 --- /dev/null +++ b/test/cases/errors/import-module-cycle-multiple/2/a.json @@ -0,0 +1 @@ +"./b.json" diff --git a/test/cases/errors/import-module-cycle-multiple/2/b.json b/test/cases/errors/import-module-cycle-multiple/2/b.json new file mode 100644 index 00000000000..9a389c9696a --- /dev/null +++ b/test/cases/errors/import-module-cycle-multiple/2/b.json @@ -0,0 +1 @@ +"./a.json" diff --git a/test/cases/errors/import-module-cycle-multiple/3/a.json b/test/cases/errors/import-module-cycle-multiple/3/a.json new file mode 100644 index 00000000000..75e02a30f04 --- /dev/null +++ b/test/cases/errors/import-module-cycle-multiple/3/a.json @@ -0,0 +1 @@ +"./b.json" diff --git a/test/cases/errors/import-module-cycle-multiple/3/b.json b/test/cases/errors/import-module-cycle-multiple/3/b.json new file mode 100644 index 00000000000..5a2d1989f77 --- /dev/null +++ b/test/cases/errors/import-module-cycle-multiple/3/b.json @@ -0,0 +1 @@ +"./c.json" diff --git a/test/cases/errors/import-module-cycle-multiple/3/c.json b/test/cases/errors/import-module-cycle-multiple/3/c.json new file mode 100644 index 00000000000..9a389c9696a --- /dev/null +++ b/test/cases/errors/import-module-cycle-multiple/3/c.json @@ -0,0 +1 @@ +"./a.json" diff --git a/test/cases/errors/import-module-cycle-multiple/4/a.json b/test/cases/errors/import-module-cycle-multiple/4/a.json new file mode 100644 index 00000000000..08a6371d338 --- /dev/null +++ b/test/cases/errors/import-module-cycle-multiple/4/a.json @@ -0,0 +1 @@ +["./b.json", "./b.json"] diff --git a/test/cases/errors/import-module-cycle-multiple/4/b.json b/test/cases/errors/import-module-cycle-multiple/4/b.json new file mode 100644 index 00000000000..5a2d1989f77 --- /dev/null +++ b/test/cases/errors/import-module-cycle-multiple/4/b.json @@ -0,0 +1 @@ +"./c.json" diff --git a/test/cases/errors/import-module-cycle-multiple/4/c.json b/test/cases/errors/import-module-cycle-multiple/4/c.json new file mode 100644 index 00000000000..fe51488c706 --- /dev/null +++ b/test/cases/errors/import-module-cycle-multiple/4/c.json @@ -0,0 +1 @@ +[] diff --git a/test/cases/errors/import-module-cycle-multiple/index.js b/test/cases/errors/import-module-cycle-multiple/index.js new file mode 100644 index 00000000000..054ea2e1af6 --- /dev/null +++ b/test/cases/errors/import-module-cycle-multiple/index.js @@ -0,0 +1,31 @@ +it("should error importModule when a cycle with 2 modules is requested", () => { + expect(require("./loader!./2/a")).toEqual([ + ["./b.json", [ + ["./a.json", "err: There is a circular build dependency, which makes it impossible to create this module"] + ]] + ]); +}); +it("should error importModule when a cycle with 3 modules is requested", () => { + expect(require("./loader!./3/a")).toEqual([ + ["./b.json", [ + ["./c.json", [ + ["./a.json", "err: There is a circular build dependency, which makes it impossible to create this module"] + ]] + ]] + ]); +}); +it("should error importModule when requesting itself", () => { + expect(require("./loader!./1/a")).toEqual([ + ["./a.json", "err: There is a circular build dependency, which makes it impossible to create this module"] + ]); +}); +it("should not report a cycle when importModule is used twice", () => { + expect(require("./loader!./4/a")).toEqual([ + ["./b.json", [ + ["./c.json", []] + ]], + ["./b.json", [ + ["./c.json", []] + ]] + ]); +}); diff --git a/test/cases/errors/import-module-cycle-multiple/loader.js b/test/cases/errors/import-module-cycle-multiple/loader.js new file mode 100644 index 00000000000..3d13b9953d3 --- /dev/null +++ b/test/cases/errors/import-module-cycle-multiple/loader.js @@ -0,0 +1,23 @@ +/** @type {import("../../../../").LoaderDefinitionFunction} */ +exports.default = function (source) { + const content = JSON.parse(source); + // content is one reference or an array of references + const refs = Array.isArray(content) ? content : [content]; + const callback = this.async(); + const importReferencedModules = async () => { + const loadedRefs = [] + for(const ref of refs) { + try { + const source = await this.importModule("../loader!" + ref); + loadedRefs.push([ref, source]); + } catch(err) { + loadedRefs.push([ref, `err: ${err && err.message}`]); + } + } + return loadedRefs; + } + + importReferencedModules().then((loadResults) => { + callback(null, JSON.stringify(loadResults)); + }); +}; diff --git a/test/cases/errors/import-module-cycle/1/a.json b/test/cases/errors/import-module-cycle/1/a.json new file mode 100644 index 00000000000..9a389c9696a --- /dev/null +++ b/test/cases/errors/import-module-cycle/1/a.json @@ -0,0 +1 @@ +"./a.json" diff --git a/test/cases/errors/import-module-cycle/2/a.json b/test/cases/errors/import-module-cycle/2/a.json new file mode 100644 index 00000000000..75e02a30f04 --- /dev/null +++ b/test/cases/errors/import-module-cycle/2/a.json @@ -0,0 +1 @@ +"./b.json" diff --git a/test/cases/errors/import-module-cycle/2/b.json b/test/cases/errors/import-module-cycle/2/b.json new file mode 100644 index 00000000000..9a389c9696a --- /dev/null +++ b/test/cases/errors/import-module-cycle/2/b.json @@ -0,0 +1 @@ +"./a.json" diff --git a/test/cases/errors/import-module-cycle/3/a.json b/test/cases/errors/import-module-cycle/3/a.json new file mode 100644 index 00000000000..75e02a30f04 --- /dev/null +++ b/test/cases/errors/import-module-cycle/3/a.json @@ -0,0 +1 @@ +"./b.json" diff --git a/test/cases/errors/import-module-cycle/3/b.json b/test/cases/errors/import-module-cycle/3/b.json new file mode 100644 index 00000000000..5a2d1989f77 --- /dev/null +++ b/test/cases/errors/import-module-cycle/3/b.json @@ -0,0 +1 @@ +"./c.json" diff --git a/test/cases/errors/import-module-cycle/3/c.json b/test/cases/errors/import-module-cycle/3/c.json new file mode 100644 index 00000000000..9a389c9696a --- /dev/null +++ b/test/cases/errors/import-module-cycle/3/c.json @@ -0,0 +1 @@ +"./a.json" diff --git a/test/cases/errors/import-module-cycle/index.js b/test/cases/errors/import-module-cycle/index.js new file mode 100644 index 00000000000..3d5f92f0087 --- /dev/null +++ b/test/cases/errors/import-module-cycle/index.js @@ -0,0 +1,15 @@ +it("should error importModule when a cycle with 2 modules is requested", () => { + expect(require("./loader!./2/a")).toMatch( + /^source: err: There is a circular build dependency/ + ); +}); +it("should error importModule when a cycle with 3 modules is requested", () => { + expect(require("./loader!./3/a")).toMatch( + /^source: source: err: There is a circular build dependency/ + ); +}); +it("should error importModule when requesting itself", () => { + expect(require("./loader!./1/a")).toMatch( + /^err: There is a circular build dependency/ + ); +}); diff --git a/test/cases/errors/import-module-cycle/loader.js b/test/cases/errors/import-module-cycle/loader.js new file mode 100644 index 00000000000..84022701942 --- /dev/null +++ b/test/cases/errors/import-module-cycle/loader.js @@ -0,0 +1,12 @@ +/** @type {import("../../../../").LoaderDefinitionFunction} */ +exports.default = function (source) { + const ref = JSON.parse(source); + const callback = this.async(); + this.importModule("../loader!" + ref, {}, (err, exports) => { + if (err) { + callback(null, JSON.stringify(`err: ${err && err.message}`)); + } else { + callback(null, JSON.stringify(`source: ${exports}`)); + } + }); +}; diff --git a/test/cases/errors/load-module-cycle-multiple/1/a.json b/test/cases/errors/load-module-cycle-multiple/1/a.json new file mode 100644 index 00000000000..9a389c9696a --- /dev/null +++ b/test/cases/errors/load-module-cycle-multiple/1/a.json @@ -0,0 +1 @@ +"./a.json" diff --git a/test/cases/errors/load-module-cycle-multiple/2/a.json b/test/cases/errors/load-module-cycle-multiple/2/a.json new file mode 100644 index 00000000000..75e02a30f04 --- /dev/null +++ b/test/cases/errors/load-module-cycle-multiple/2/a.json @@ -0,0 +1 @@ +"./b.json" diff --git a/test/cases/errors/load-module-cycle-multiple/2/b.json b/test/cases/errors/load-module-cycle-multiple/2/b.json new file mode 100644 index 00000000000..9a389c9696a --- /dev/null +++ b/test/cases/errors/load-module-cycle-multiple/2/b.json @@ -0,0 +1 @@ +"./a.json" diff --git a/test/cases/errors/load-module-cycle-multiple/3/a.json b/test/cases/errors/load-module-cycle-multiple/3/a.json new file mode 100644 index 00000000000..75e02a30f04 --- /dev/null +++ b/test/cases/errors/load-module-cycle-multiple/3/a.json @@ -0,0 +1 @@ +"./b.json" diff --git a/test/cases/errors/load-module-cycle-multiple/3/b.json b/test/cases/errors/load-module-cycle-multiple/3/b.json new file mode 100644 index 00000000000..5a2d1989f77 --- /dev/null +++ b/test/cases/errors/load-module-cycle-multiple/3/b.json @@ -0,0 +1 @@ +"./c.json" diff --git a/test/cases/errors/load-module-cycle-multiple/3/c.json b/test/cases/errors/load-module-cycle-multiple/3/c.json new file mode 100644 index 00000000000..9a389c9696a --- /dev/null +++ b/test/cases/errors/load-module-cycle-multiple/3/c.json @@ -0,0 +1 @@ +"./a.json" diff --git a/test/cases/errors/load-module-cycle-multiple/4/a.json b/test/cases/errors/load-module-cycle-multiple/4/a.json new file mode 100644 index 00000000000..08a6371d338 --- /dev/null +++ b/test/cases/errors/load-module-cycle-multiple/4/a.json @@ -0,0 +1 @@ +["./b.json", "./b.json"] diff --git a/test/cases/errors/load-module-cycle-multiple/4/b.json b/test/cases/errors/load-module-cycle-multiple/4/b.json new file mode 100644 index 00000000000..5a2d1989f77 --- /dev/null +++ b/test/cases/errors/load-module-cycle-multiple/4/b.json @@ -0,0 +1 @@ +"./c.json" diff --git a/test/cases/errors/load-module-cycle-multiple/4/c.json b/test/cases/errors/load-module-cycle-multiple/4/c.json new file mode 100644 index 00000000000..fe51488c706 --- /dev/null +++ b/test/cases/errors/load-module-cycle-multiple/4/c.json @@ -0,0 +1 @@ +[] diff --git a/test/cases/errors/load-module-cycle-multiple/index.js b/test/cases/errors/load-module-cycle-multiple/index.js new file mode 100644 index 00000000000..c728f5ab60d --- /dev/null +++ b/test/cases/errors/load-module-cycle-multiple/index.js @@ -0,0 +1,31 @@ +it("should error loadModule when a cycle with 2 modules is requested", () => { + expect(require("./loader!./2/a")).toEqual([ + ["./b.json", [ + ["./a.json", "err: There is a circular build dependency, which makes it impossible to create this module"] + ]] + ]); +}); +it("should error loadModule when a cycle with 3 modules is requested", () => { + expect(require("./loader!./3/a")).toEqual([ + ["./b.json", [ + ["./c.json", [ + ["./a.json", "err: There is a circular build dependency, which makes it impossible to create this module"] + ]] + ]] + ]); +}); +it("should error loadModule when requesting itself", () => { + expect(require("./loader!./1/a")).toEqual([ + ["./a.json", "err: There is a circular build dependency, which makes it impossible to create this module"] + ]); +}); +it("should not report a cycle when loadModule is used twice (https://github.com/webpack/webpack/issues/14379)", () => { + expect(require("./loader!./4/a")).toEqual([ + ["./b.json", [ + ["./c.json", []] + ]], + ["./b.json", [ + ["./c.json", []] + ]] + ]); +}); diff --git a/test/cases/errors/load-module-cycle-multiple/loader.js b/test/cases/errors/load-module-cycle-multiple/loader.js new file mode 100644 index 00000000000..e91f9dc4b60 --- /dev/null +++ b/test/cases/errors/load-module-cycle-multiple/loader.js @@ -0,0 +1,30 @@ +const { promisify } = require("util"); + +/** @type {import("../../../../").LoaderDefinitionFunction} */ +exports.default = function (source) { + const content = JSON.parse(source); + // content is one reference or an array of references + const refs = Array.isArray(content) ? content : [content]; + const callback = this.async(); + const loadModulePromise = promisify(this.loadModule.bind(this)); + + async function loadReferencedModules() { + // Modules are loaded sequentially as the false-positive circular reference + // bug from https://github.com/webpack/webpack/issues/14379 doesn't occur if + // they are loaded in parallel. + const loadedRefs = [] + for(const ref of refs) { + try { + const source = await loadModulePromise("../loader!" + ref); + loadedRefs.push([ref, JSON.parse(source)]); + } catch(err) { + loadedRefs.push([ref, `err: ${err && err.message}`]); + } + } + return loadedRefs; + } + + loadReferencedModules().then((loadResults) => { + callback(null, JSON.stringify(loadResults)); + }); +}; diff --git a/test/cases/errors/load-module-cycle/loader.js b/test/cases/errors/load-module-cycle/loader.js index 19a8c699bc9..ed4a740b947 100644 --- a/test/cases/errors/load-module-cycle/loader.js +++ b/test/cases/errors/load-module-cycle/loader.js @@ -1,4 +1,5 @@ -exports.default = function(source) { +/** @type {import("../../../../").LoaderDefinitionFunction} */ +exports.default = function (source) { const ref = JSON.parse(source); const callback = this.async(); this.loadModule("../loader!" + ref, (err, source, sourceMap, module) => { diff --git a/test/cases/errors/load-module-error/error-loader.js b/test/cases/errors/load-module-error/error-loader.js index 114e742cb87..5758c7646c7 100644 --- a/test/cases/errors/load-module-error/error-loader.js +++ b/test/cases/errors/load-module-error/error-loader.js @@ -1,3 +1,4 @@ +/** @type {import("../../../../types").LoaderDefinition} */ module.exports = function(source) { const callback = this.async(); callback(new Error("err: abc")); diff --git a/test/cases/errors/load-module-error/errors.js b/test/cases/errors/load-module-error/errors.js index d2c4b1da922..ce88c1bc32e 100644 --- a/test/cases/errors/load-module-error/errors.js +++ b/test/cases/errors/load-module-error/errors.js @@ -1,8 +1 @@ -module.exports = [ - [ - /err: abc/, - ], - [ - /The loaded module contains errors/, - ], -]; +module.exports = [[/err: abc/], [/The loaded module contains errors/]]; diff --git a/test/cases/errors/load-module-error/infrastructure-log.js b/test/cases/errors/load-module-error/infrastructure-log.js new file mode 100644 index 00000000000..236f5a502ab --- /dev/null +++ b/test/cases/errors/load-module-error/infrastructure-log.js @@ -0,0 +1,3 @@ +module.exports = [ + /^Pack got invalid because of write to: Compilation\/modules|json.+error-loader\.js!/ +]; diff --git a/test/cases/errors/load-module-error/loader.js b/test/cases/errors/load-module-error/loader.js index 6001a39c5df..3eb4fa42c63 100644 --- a/test/cases/errors/load-module-error/loader.js +++ b/test/cases/errors/load-module-error/loader.js @@ -1,4 +1,5 @@ -exports.default = function(source) { +/** @type {import("../../../../").LoaderDefinitionFunction} */ +exports.default = function (source) { const callback = this.async(); const ref = JSON.parse(source); this.loadModule("./error-loader!" + ref, (err, source, sourceMap, module) => { diff --git a/test/cases/errors/loader-error-warning/error-loader.js b/test/cases/errors/loader-error-warning/error-loader.js index 175192c08da..981790bb520 100644 --- a/test/cases/errors/loader-error-warning/error-loader.js +++ b/test/cases/errors/loader-error-warning/error-loader.js @@ -1,4 +1,6 @@ -module.exports = function(source) { - this.emitError(this.query.substr(1)); +/** @type {import("../../../../").LoaderDefinition} */ +module.exports = function (source) { + //@ts-expect-error errors must be Errors, string is not recommended and should lead to type error + this.emitError(this.query.slice(1)); return source; -} +}; diff --git a/test/cases/errors/loader-error-warning/errors.js b/test/cases/errors/loader-error-warning/errors.js index c5801200e1c..16bfd86a57f 100644 --- a/test/cases/errors/loader-error-warning/errors.js +++ b/test/cases/errors/loader-error-warning/errors.js @@ -1,12 +1,4 @@ module.exports = [ - [ - /abc/, - /Emitted value instead of an instance of Error/, - /error-loader\.js/ - ], - [ - /def/, - /Emitted value instead of an instance of Error/, - /error-loader\.js/ - ] + [/abc/, /Emitted value instead of an instance of Error/, /error-loader\.js/], + [/def/, /Emitted value instead of an instance of Error/, /error-loader\.js/] ]; diff --git a/test/cases/errors/loader-error-warning/warning-loader.js b/test/cases/errors/loader-error-warning/warning-loader.js index 05142648f6c..90c6ad19d72 100644 --- a/test/cases/errors/loader-error-warning/warning-loader.js +++ b/test/cases/errors/loader-error-warning/warning-loader.js @@ -1,4 +1,6 @@ -module.exports = function(source) { - this.emitWarning(this.query.substr(1)); +/** @type {import("../../../../").LoaderDefinition} */ +module.exports = function (source) { + //@ts-expect-error warnings must be Errors, string is not recommended and should lead to type error + this.emitWarning(this.query.slice(1)); return source; -} +}; diff --git a/test/cases/errors/loader-error-warning/warnings.js b/test/cases/errors/loader-error-warning/warnings.js index 82ea0b1dd31..c776962fc05 100644 --- a/test/cases/errors/loader-error-warning/warnings.js +++ b/test/cases/errors/loader-error-warning/warnings.js @@ -1,7 +1,3 @@ module.exports = [ - [ - /xyz/, - /Emitted value instead of an instance of Error/, - /warning-loader\.js/ - ] + [/xyz/, /Emitted value instead of an instance of Error/, /warning-loader\.js/] ]; diff --git a/test/cases/esm/import-meta/index.js b/test/cases/esm/import-meta/index.js index 43fe084d41e..8f57a9a700f 100644 --- a/test/cases/esm/import-meta/index.js +++ b/test/cases/esm/import-meta/index.js @@ -42,5 +42,16 @@ it("should return undefined for unknown property", () => { expect(import.meta.other).toBe(undefined); if (typeof import.meta.other !== "undefined") require("fail"); expect(() => import.meta.other.other.other).toThrowError(); - // if (typeof import.meta.other.other.other !== "undefined") require("fail"); +}); + +it("should add warning on direct import.meta usage", () => { + expect(Object.keys(import.meta)).toHaveLength(0); +}); + +it("should support destructuring assignment", () => { + let version, url2, c; + ({ webpack: version } = { url: url2 } = { c } = import.meta); + expect(version).toBeTypeOf("number"); + expect(url2).toBe(url); + expect(c).toBe(undefined); }); diff --git a/test/cases/esm/import-meta/test.filter.js b/test/cases/esm/import-meta/test.filter.js new file mode 100644 index 00000000000..3f0358f64f9 --- /dev/null +++ b/test/cases/esm/import-meta/test.filter.js @@ -0,0 +1,3 @@ +const supportsRequireInModule = require("../../../helpers/supportsRequireInModule"); + +module.exports = config => !config.module || supportsRequireInModule(); diff --git a/test/cases/esm/import-meta/warnings.js b/test/cases/esm/import-meta/warnings.js new file mode 100644 index 00000000000..d8fc384d81d --- /dev/null +++ b/test/cases/esm/import-meta/warnings.js @@ -0,0 +1,5 @@ +module.exports = [ + [ + /Accessing import.meta directly is unsupported \(only property access or destructuring is supported\)/ + ] +]; diff --git a/test/cases/indirect-call/call/dep.js b/test/cases/indirect-call/call/dep.js new file mode 100644 index 00000000000..2d312b5ce01 --- /dev/null +++ b/test/cases/indirect-call/call/dep.js @@ -0,0 +1,3 @@ +export default function dep() { + return this; +}; diff --git a/test/cases/indirect-call/call/index.js b/test/cases/indirect-call/call/index.js new file mode 100644 index 00000000000..a3ef545f255 --- /dev/null +++ b/test/cases/indirect-call/call/index.js @@ -0,0 +1,10 @@ +import a from "./dep.js" + +const global = a(); + +it("should generate indirect call", () => { + expect(a()).toBeUndefined(); + expect((a)()).toBeUndefined(); + expect((a())).toBeUndefined(); + expect(global).toBeUndefined(); +}); diff --git a/test/cases/indirect-call/tagged-template-expression/dep.js b/test/cases/indirect-call/tagged-template-expression/dep.js new file mode 100644 index 00000000000..2d312b5ce01 --- /dev/null +++ b/test/cases/indirect-call/tagged-template-expression/dep.js @@ -0,0 +1,3 @@ +export default function dep() { + return this; +}; diff --git a/test/cases/indirect-call/tagged-template-expression/dep1.js b/test/cases/indirect-call/tagged-template-expression/dep1.js new file mode 100644 index 00000000000..c81820d5cb7 --- /dev/null +++ b/test/cases/indirect-call/tagged-template-expression/dep1.js @@ -0,0 +1,5 @@ +export default function dep() { + return () => { + return this; + }; +}; diff --git a/test/cases/indirect-call/tagged-template-expression/index.js b/test/cases/indirect-call/tagged-template-expression/index.js new file mode 100644 index 00000000000..20e9e1c47ec --- /dev/null +++ b/test/cases/indirect-call/tagged-template-expression/index.js @@ -0,0 +1,12 @@ +import a from "./dep.js" +import b from "./dep1.js" + +const global = a``; + +it("should generate indirect call", () => { + expect(a``).toBeUndefined(); + expect(a`${{a}}`).toBeUndefined(); + expect((a)``).toBeUndefined(); + expect(b()``).toBeUndefined(); + expect(global).toBeUndefined(); +}); diff --git a/test/cases/inner-graph/class-dynamic-props/index.js b/test/cases/inner-graph/class-dynamic-props/index.js new file mode 100644 index 00000000000..a8b69c9ead4 --- /dev/null +++ b/test/cases/inner-graph/class-dynamic-props/index.js @@ -0,0 +1,22 @@ +it("should not throw when using dynamic properties in unused classes", () => { + require("./unused1"); +}); + +it("should not throw when using dynamic properties in used classes", () => { + const exports = require("./used1"); + const x = new exports.Used(); + expect(x.a()).toBe("A"); + expect(x.b).toBe("B"); + expect(x.c).toBe("C"); + expect(exports.Used.d()).toBe("D"); + expect(exports.Used.e).toBe("E"); + expect(exports.Used.f).toBe("F"); + const x2 = new exports.Used2(); + expect(x2.a()).toBe("A"); + expect(x2.b).toBe("B"); + expect(x2.c).toBe("C"); + expect(exports.Used2.d()).toBe("D"); + expect(exports.Used2.e).toBe("E"); + expect(exports.Used2.f).toBe("F"); + expect(x2.x).toBe("X"); +}); diff --git a/test/cases/inner-graph/class-dynamic-props/module.js b/test/cases/inner-graph/class-dynamic-props/module.js new file mode 100644 index 00000000000..f7f9dad52d2 --- /dev/null +++ b/test/cases/inner-graph/class-dynamic-props/module.js @@ -0,0 +1,16 @@ +export const a = () => "a"; +export const A = "A"; +export const b = "b"; +export const B = "B"; +export const c = "c"; +export const C = "C"; +export const d = () => "d"; +export const D = "D"; +export const e = "e"; +export const E = "E"; +export const f = "f"; +export const F = "F"; +export class X { + x = "X"; +} +export const y = "y"; diff --git a/test/cases/inner-graph/class-dynamic-props/test.filter.js b/test/cases/inner-graph/class-dynamic-props/test.filter.js new file mode 100644 index 00000000000..25a2a20eb28 --- /dev/null +++ b/test/cases/inner-graph/class-dynamic-props/test.filter.js @@ -0,0 +1,5 @@ +var supportsClassFields = require("../../../helpers/supportsClassFields"); + +module.exports = function (config) { + return supportsClassFields(); +}; diff --git a/test/cases/inner-graph/class-dynamic-props/unused1.js b/test/cases/inner-graph/class-dynamic-props/unused1.js new file mode 100644 index 00000000000..6abeb0f71c1 --- /dev/null +++ b/test/cases/inner-graph/class-dynamic-props/unused1.js @@ -0,0 +1,37 @@ +import { a, b, c, d, e, f, A, B, C, D, E, F, X } from "./module"; + +class Unused { + [a()]() { + return A; + } + [b] = B; + get [c]() { + return C; + } + static [d()]() { + return D; + } + static [e] = E; + static get [f]() { + return F; + } +} + +class Unused2 extends X { + [a()]() { + return A; + } + [b] = B; + get [c]() { + return C; + } + static [d()]() { + return D; + } + static [e] = E; + static get [f]() { + return F; + } +} + +export {}; diff --git a/test/cases/inner-graph/class-dynamic-props/used1.js b/test/cases/inner-graph/class-dynamic-props/used1.js new file mode 100644 index 00000000000..f9ce10b5bc9 --- /dev/null +++ b/test/cases/inner-graph/class-dynamic-props/used1.js @@ -0,0 +1,37 @@ +import { a, b, c, d, e, f, A, B, C, D, E, F, X } from "./module?1"; + +class Used { + [a()]() { + return A; + } + [b] = B; + get [c]() { + return C; + } + static [d()]() { + return D; + } + static [e] = E; + static get [f]() { + return F; + } +} + +class Used2 extends X { + [a()]() { + return A; + } + [b] = B; + get [c]() { + return C; + } + static [d()]() { + return D; + } + static [e] = E; + static get [f]() { + return F; + } +} + +export { Used, Used2 }; diff --git a/test/cases/inner-graph/extend-class/a.js b/test/cases/inner-graph/extend-class/a.js new file mode 100644 index 00000000000..3fd13175a08 --- /dev/null +++ b/test/cases/inner-graph/extend-class/a.js @@ -0,0 +1,14 @@ +import B from "./b.js"; +import { A1 } from "./dep1"; + +export default class A extends B { + constructor() { + super(); + } + test() { + super.test(); + + this.b = new B(); + this.a1 = new A1(); + } +} diff --git a/test/cases/inner-graph/extend-class/b.js b/test/cases/inner-graph/extend-class/b.js new file mode 100644 index 00000000000..478800ea513 --- /dev/null +++ b/test/cases/inner-graph/extend-class/b.js @@ -0,0 +1,10 @@ +import A from "./a.js"; +import { A1 } from "./dep1"; + +export default class B { + constructor() {} + test() { + this.a = new A(); + this.a2 = new A1(); + } +} diff --git a/test/cases/inner-graph/extend-class/c.js b/test/cases/inner-graph/extend-class/c.js new file mode 100644 index 00000000000..9fbff09a7ca --- /dev/null +++ b/test/cases/inner-graph/extend-class/c.js @@ -0,0 +1,21 @@ +import { BaseError, BaseError1, BaseError2, BaseError3 } from "./dep2"; + +export class ExtendedError extends BaseError { + constructor(message) { + super(message); + } +} +export class ExtendedError1 extends BaseError1 { + constructor(message) { + super(message); + } +} +export class ExtendedError2 extends BaseError2 { + myMethod() {} +} +export class ExtendedError3 extends BaseError3 {} +export class ExtendedError4 extends Error { + constructor(message = 'ExtendedError') { + super(message); + } +} diff --git a/test/cases/inner-graph/extend-class/dep1.js b/test/cases/inner-graph/extend-class/dep1.js index 50b7759b648..cdbb374a8b4 100644 --- a/test/cases/inner-graph/extend-class/dep1.js +++ b/test/cases/inner-graph/extend-class/dep1.js @@ -1,4 +1,4 @@ -import {A, B, Z} from "./dep2"; +import { A, B, Z, W } from "./dep2"; export const A1 = class A1 extends A { render() {return new E();} @@ -20,3 +20,4 @@ class D { } export const isZ = (new Z1()) instanceof Z; +export { W }; diff --git a/test/cases/inner-graph/extend-class/dep2.js b/test/cases/inner-graph/extend-class/dep2.js index 9fecc682117..75343cd50cf 100644 --- a/test/cases/inner-graph/extend-class/dep2.js +++ b/test/cases/inner-graph/extend-class/dep2.js @@ -6,12 +6,35 @@ export class Z {} export function mixin1(_class) {return _class} export function mixin2(_class) {return _class} export function mixin3(_class) {return _class} +export function mixin4(_class) {return _class} +export function mixin5(_class) {return _class} +export function getField() { return "test" } +export class BaseError extends Error {} +export class BaseError1 extends Error {} +export class BaseError2 extends Error {} +export class BaseError3 extends Error {} +export class W {} +export class J {} +export class K {} +var SuperClass = class {}; +export { SuperClass }; export const exportsInfoForA = __webpack_exports_info__.A.used; export const exportsInfoForB = __webpack_exports_info__.B.used; export const exportsInfoForC = __webpack_exports_info__.C.used; export const exportsInfoForY = __webpack_exports_info__.Y.used; export const exportsInfoForZ = __webpack_exports_info__.Z.used; +export const exportsInfoForW = __webpack_exports_info__.W.used; +export const exportsInfoForJ = __webpack_exports_info__.J.used; +export const exportsInfoForK = __webpack_exports_info__.K.used; export const exportsInfoForMixin1 = __webpack_exports_info__.mixin1.used; export const exportsInfoForMixin2 = __webpack_exports_info__.mixin2.used; export const exportsInfoForMixin3 = __webpack_exports_info__.mixin3.used; +export const exportsInfoForMixin4 = __webpack_exports_info__.mixin4.used; +export const exportsInfoForMixin5 = __webpack_exports_info__.mixin5.used; +export const exportsInfoForgetField = __webpack_exports_info__.getField.used; +export const exportsInfoForBaseError = __webpack_exports_info__.BaseError.used; +export const exportsInfoForBaseError1 = __webpack_exports_info__.BaseError1.used; +export const exportsInfoForBaseError2 = __webpack_exports_info__.BaseError2.used; +export const exportsInfoForBaseError3 = __webpack_exports_info__.BaseError3.used; +export const exportsInfoForSuperClass = __webpack_exports_info__.SuperClass.used; diff --git a/test/cases/inner-graph/extend-class/dep3.js b/test/cases/inner-graph/extend-class/dep3.js index 02dd576d004..afeaec1bfbf 100644 --- a/test/cases/inner-graph/extend-class/dep3.js +++ b/test/cases/inner-graph/extend-class/dep3.js @@ -1,4 +1,4 @@ -import {mixin1, mixin2, mixin3, A, B, C, Y} from "./dep2"; +import {mixin1, mixin2, mixin3, getField, A, B, C, Y, mixin4} from "./dep2"; export const A1 = class A1 extends A { render() {return new E();} @@ -12,7 +12,7 @@ export const C1 = class C1 extends mixin2(Y, /*#__PURE__*/ mixin3(C)) { render() {return new D();} }; -export class Y1 extends mixin2(Y) { +export class Y1 extends /*#__PURE__*/ mixin2(Y) { constructor() { super(); @@ -22,5 +22,9 @@ export class Y1 extends mixin2(Y) { render() {return new D();} } +export class Bar extends /*#__PURE__*/ mixin4(A) { + [/*#__PURE__*/ getField()] = 12; +} + export class E {} const D = class D {}; diff --git a/test/cases/inner-graph/extend-class/index.js b/test/cases/inner-graph/extend-class/index.js index 92a68764e25..69f1c125ca2 100644 --- a/test/cases/inner-graph/extend-class/index.js +++ b/test/cases/inner-graph/extend-class/index.js @@ -4,19 +4,44 @@ import { exportsInfoForC, exportsInfoForY, exportsInfoForZ, + exportsInfoForW, + exportsInfoForJ, + exportsInfoForK, exportsInfoForMixin1, exportsInfoForMixin2, - exportsInfoForMixin3 + exportsInfoForMixin3, + exportsInfoForMixin4, + exportsInfoForMixin5, + exportsInfoForBaseError, + exportsInfoForBaseError1, + exportsInfoForBaseError2, + exportsInfoForBaseError3, + exportsInfoForSuperClass } from "./dep2"; it("should load modules correctly", () => { require("./module1"); require("./module2"); + require("./module3"); + require("./module4"); + require("./module5"); + require("./module6"); + require("./module7"); + require("./module8"); + require("./module9"); }); if (process.env.NODE_ENV === "production") { - it("B should not be used", () => { - expect(exportsInfoForB).toBe(false); + it("W and J should not be used", () => { + expect(exportsInfoForJ).toBe(false); + expect(exportsInfoForW).toBe(false); + }); + + it("Keep extends with constructor", () => { + expect(exportsInfoForBaseError).toBe(true); + expect(exportsInfoForBaseError1).toBe(true); + expect(exportsInfoForBaseError2).toBe(false); + expect(exportsInfoForBaseError3).toBe(false); }); } @@ -24,15 +49,29 @@ it("A should be used", () => { expect(exportsInfoForA).toBe(true); }); +it("B should be used", () => { + expect(exportsInfoForB).toBe(true); +}); + +it("K should be used", () => { + expect(exportsInfoForK).toBe(true); +}); + it("Z used, inner graph can not determine const usage", () => { expect(exportsInfoForZ).toBe(true); }); +it("SuperClass should be used", () => { + expect(exportsInfoForSuperClass).toBe(true); +}); + it("Pure super expression should be unused, another used", () => { if (process.env.NODE_ENV === "production") { - expect(exportsInfoForMixin1).toBe(false); + expect(exportsInfoForMixin4).toBe(false); + expect(exportsInfoForMixin5).toBe(false); } + expect(exportsInfoForMixin1).toBe(true); expect(exportsInfoForMixin2).toBe(true); expect(exportsInfoForMixin3).toBe(true); expect(exportsInfoForC).toBe(true); diff --git a/test/cases/inner-graph/extend-class/module3.js b/test/cases/inner-graph/extend-class/module3.js new file mode 100644 index 00000000000..7a1f7dc8856 --- /dev/null +++ b/test/cases/inner-graph/extend-class/module3.js @@ -0,0 +1,3 @@ +import A from "./a.js"; +let a = new A(); +a.test(); diff --git a/test/cases/inner-graph/extend-class/module4.js b/test/cases/inner-graph/extend-class/module4.js new file mode 100644 index 00000000000..1e78b04f6c1 --- /dev/null +++ b/test/cases/inner-graph/extend-class/module4.js @@ -0,0 +1,3 @@ +import {ExtendedError4} from "./c.js"; + +export default new ExtendedError4() diff --git a/test/cases/inner-graph/extend-class/module5.js b/test/cases/inner-graph/extend-class/module5.js new file mode 100644 index 00000000000..c05aaf0def2 --- /dev/null +++ b/test/cases/inner-graph/extend-class/module5.js @@ -0,0 +1,3 @@ +import { W } from "./dep2"; + +class BaseW extends W {} diff --git a/test/cases/inner-graph/extend-class/module6.js b/test/cases/inner-graph/extend-class/module6.js new file mode 100644 index 00000000000..046e9df215d --- /dev/null +++ b/test/cases/inner-graph/extend-class/module6.js @@ -0,0 +1,4 @@ +import { J } from "./dep2"; + +class BaseJ extends J {} +class BaseBaseJ extends BaseJ {} diff --git a/test/cases/inner-graph/extend-class/module7.js b/test/cases/inner-graph/extend-class/module7.js new file mode 100644 index 00000000000..86c9beccffb --- /dev/null +++ b/test/cases/inner-graph/extend-class/module7.js @@ -0,0 +1,6 @@ +import { K } from "./dep2"; + +class BaseK extends K {} +class BaseBaseK extends BaseK {} + +export default new BaseBaseK(); diff --git a/test/cases/inner-graph/extend-class/module8.js b/test/cases/inner-graph/extend-class/module8.js new file mode 100644 index 00000000000..f2d076b0fe0 --- /dev/null +++ b/test/cases/inner-graph/extend-class/module8.js @@ -0,0 +1,9 @@ +import { mixin5 } from "./dep2"; + +class Bar extends /*#__PURE__*/ mixin5(null) { + static displayName = "Point"; +} + +function test() { + return Bar.displayName; +} diff --git a/test/cases/inner-graph/extend-class/module9.js b/test/cases/inner-graph/extend-class/module9.js new file mode 100644 index 00000000000..efc36d37579 --- /dev/null +++ b/test/cases/inner-graph/extend-class/module9.js @@ -0,0 +1,8 @@ +import { SuperClass } from "./dep2"; + +var UnusedClass = class extends SuperClass { + constructor() { + super(); + } + }, + unusedVariable = new UnusedClass(); diff --git a/test/cases/inner-graph/extend-class/test.filter.js b/test/cases/inner-graph/extend-class/test.filter.js new file mode 100644 index 00000000000..4df515a5d8b --- /dev/null +++ b/test/cases/inner-graph/extend-class/test.filter.js @@ -0,0 +1,5 @@ +var supportsClassStaticBlock = require("../../../helpers/supportsClassStaticBlock"); + +module.exports = function (config) { + return supportsClassStaticBlock(); +}; diff --git a/test/cases/inner-graph/extend-class2/dep-decl.js b/test/cases/inner-graph/extend-class2/dep-decl.js index a94766a3508..bcce7df94ae 100644 --- a/test/cases/inner-graph/extend-class2/dep-decl.js +++ b/test/cases/inner-graph/extend-class2/dep-decl.js @@ -1,5 +1,5 @@ -import { A, B, getC, getD, getE, getF } from "./dep2?decl"; -import { A3, B3, C3, D3, E3, F3 } from "./dep3?decl"; +import { A, B, getC, getD, getE, getF, Foo, Pure, DateFormatter, ConditionalExpression, LogicalExpression } from "./dep2?decl"; +import { A3, B3, C3, D3, E3, F3, Pure3, ConditionalExpression3, LogicalExpression3 } from "./dep3?decl"; export class A1 extends A { render() { @@ -39,6 +39,125 @@ export class F1 extends getF() { } } +function foo(instance) { + return new instance() +} + +class Bar extends Foo { + static prop = 42; + static a = foo(this).prop; + static b = foo(Bar).prop; + static c = foo(super.Bar).prop; + static inStatic1; + static inStatic2; + static inStatic3; + static { + this.inStatic1 = new Bar().prop; + this.inStatic2 = new super.Bar().prop; + this.inStatic3 = (new this).prop; + } +} + +class BarA extends Foo { + static prop = 42; + static a = foo(this).prop; +} + +class BarB extends Foo { + static prop = 42; + static b = foo(Bar).prop; +} + +class BarC extends Foo { + static prop = 42; + static c = foo(super.Bar).prop; +} + +class BarPA extends Foo { + static prop = 42; + static #a = foo(this).prop; +} + +class BarPB extends Foo { + static prop = 42; + static #b = foo(Bar).prop; +} + +class BarPC extends Foo { + static prop = 42; + static #c = foo(super.Bar).prop; +} + +const ExpressionFoo = class Bar extends Foo { + static prop = 42; + static a = foo(this).prop; + static b = foo(Bar).prop; + static c = foo(super.Bar).prop; + static inStatic1; + static inStatic2; + static inStatic3; + static { + this.inStatic1 = new Bar().prop; + this.inStatic2 = new super.Bar().prop; + this.inStatic3 = (new this).prop; + } +} + +export class Baz extends Foo { + static prop = 42; + static a = foo(this).prop; + static b = foo(Bar).prop; + static c = foo(super.Bar).prop; + static inStatic1; + static inStatic2; + static inStatic3; + static { + this.inStatic1 = new Bar().prop; + this.inStatic2 = new super.Bar().prop; + this.inStatic3 = (new this).prop; + } +} + +export default class DefaultBar extends Foo { + static prop = 42; + static a = foo(this).prop; + static b = foo(Bar).prop; + static c = foo(super.Bar).prop; + static inStatic1; + static inStatic2; + static inStatic3; + static { + this.inStatic1 = new Bar().prop; + this.inStatic2 = new super.Bar().prop; + this.inStatic3 = (new this).prop; + } +} + +export class ExtendsPure extends Pure { + render() { + return new Pure3(); + } +} + +export class DateBar extends DateFormatter { + constructor() { + super(); + } + render() {} +} + +export class ConditionalExpression1 extends ConditionalExpression { + render() { + return new ConditionalExpression3(); + } +} + +export class LogicalExpression1 extends LogicalExpression { + render() { + return new LogicalExpression3(); + } +} + export class A2 extends A3 {} export class B2 extends B3 {} export class C2 extends C3 {} diff --git a/test/cases/inner-graph/extend-class2/dep-expr.js b/test/cases/inner-graph/extend-class2/dep-expr.js index afa476b438c..957b59d98ce 100644 --- a/test/cases/inner-graph/extend-class2/dep-expr.js +++ b/test/cases/inner-graph/extend-class2/dep-expr.js @@ -1,5 +1,5 @@ -import { A, B, getC, getD, getE, getF } from "./dep2?expr"; -import { A3, B3, C3, D3, E3, F3 } from "./dep3?expr"; +import {A, B, DateFormatter, getC, getD, getE, getF, Pure, ConditionalExpression, LogicalExpression} from "./dep2?expr"; +import { A3, B3, C3, D3, E3, F3, Pure3} from "./dep3?expr"; export const A1 = class extends A { render() { @@ -39,6 +39,31 @@ export const F1 = class extends getF() { } }; +export const ExtendsPure = class extends Pure { + render() { + return new Pure3(); + } +}; + +export class DateBar extends DateFormatter { + constructor() { + super(); + } + render() {} +} + +export class ConditionalExpression1 extends ConditionalExpression { + render() { + return new ConditionalExpression3(); + } +} + +export class LogicalExpression1 extends LogicalExpression { + render() { + return new LogicalExpression3(); + } +} + export const A2 = class extends A3 {}; export const B2 = class extends B3 {}; export const C2 = class extends C3 {}; diff --git a/test/cases/inner-graph/extend-class2/dep2.js b/test/cases/inner-graph/extend-class2/dep2.js index ef8f85169f3..5581cdd2199 100644 --- a/test/cases/inner-graph/extend-class2/dep2.js +++ b/test/cases/inner-graph/extend-class2/dep2.js @@ -4,6 +4,16 @@ export const getC = () => class C {}; export const getD = () => class D {}; export const getE = () => class E {}; export const getF = () => class F {}; +export class Foo { static Bar = Foo; } +export class Pure {} +export class DateFormatter extends Date { + constructor() { + super(); + this.date = this.getDate(); + } +} +export class ConditionalExpression extends (true ? A : B) {} +export class LogicalExpression extends (A || B) {} export const exportsInfoForA = __webpack_exports_info__.A.used; export const exportsInfoForB = __webpack_exports_info__.B.used; @@ -11,3 +21,8 @@ export const exportsInfoForC = __webpack_exports_info__.getC.used; export const exportsInfoForD = __webpack_exports_info__.getD.used; export const exportsInfoForE = __webpack_exports_info__.getE.used; export const exportsInfoForF = __webpack_exports_info__.getF.used; +export const exportsInfoForFoo = __webpack_exports_info__.Foo.used; +export const exportsInfoForPure = __webpack_exports_info__.Pure.used; +export const exportsInfoForDateFormatter = __webpack_exports_info__.DateFormatter.used; +export const exportsInfoForConditionalExpression = __webpack_exports_info__.ConditionalExpression.used; +export const exportsInfoForLogicalExpression = __webpack_exports_info__.LogicalExpression.used; diff --git a/test/cases/inner-graph/extend-class2/dep3.js b/test/cases/inner-graph/extend-class2/dep3.js index 974ee9572d0..74377293433 100644 --- a/test/cases/inner-graph/extend-class2/dep3.js +++ b/test/cases/inner-graph/extend-class2/dep3.js @@ -4,3 +4,6 @@ export class C3 {} export class D3 {} export class E3 {} export class F3 {} +export class Pure3 {} +export class ConditionalExpression3 extends (true ? A3 : B3) {} +export class LogicalExpression3 extends (A3 || B3) {} diff --git a/test/cases/inner-graph/extend-class2/index.js b/test/cases/inner-graph/extend-class2/index.js index 895e369f5c6..87322d5f5b3 100644 --- a/test/cases/inner-graph/extend-class2/index.js +++ b/test/cases/inner-graph/extend-class2/index.js @@ -4,7 +4,12 @@ import { exportsInfoForC as declC, exportsInfoForD as declD, exportsInfoForE as declE, - exportsInfoForF as declF + exportsInfoForF as declF, + exportsInfoForFoo as declFoo, + exportsInfoForPure as declPure, + exportsInfoForDateFormatter as declDateFormatter, + exportsInfoForConditionalExpression as declConditionalExpression, + exportsInfoForLogicalExpression as declLogicalExpression } from "./dep2?decl"; import { exportsInfoForA as exprA, @@ -12,7 +17,11 @@ import { exportsInfoForC as exprC, exportsInfoForD as exprD, exportsInfoForE as exprE, - exportsInfoForF as exprF + exportsInfoForF as exprF, + exportsInfoForPure as exprPure, + exportsInfoForDateFormatter as exprDateFormatter, + exportsInfoForConditionalExpression as exprConditionalExpression, + exportsInfoForLogicalExpression as exprLogicalExpression } from "./dep2?expr"; it("should load module correctly", () => { @@ -50,7 +59,19 @@ it("E should be used", () => { }); it("F should be used", () => { + if (process.env.NODE_ENV === "production") { + expect(declPure).toBe(false); + expect(exprPure).toBe(false); + expect(declConditionalExpression).toBe(false); + expect(exprConditionalExpression).toBe(false); + expect(declLogicalExpression).toBe(false); + expect(exprLogicalExpression).toBe(false); + } + // Note: it has side-effects and is not affected by usage of the class expect(declF).toBe(true); + expect(declFoo).toBe(true); expect(exprF).toBe(true); + expect(declDateFormatter).toBe(true); + expect(exprDateFormatter).toBe(true); }); diff --git a/test/cases/inner-graph/extend-class2/module-decl.js b/test/cases/inner-graph/extend-class2/module-decl.js index 7d164adb26a..9ca859760f3 100644 --- a/test/cases/inner-graph/extend-class2/module-decl.js +++ b/test/cases/inner-graph/extend-class2/module-decl.js @@ -1,3 +1,3 @@ -import { A1, C1, E1 } from "./dep-decl"; +import { A1, C1, E1, DateBar } from "./dep-decl"; -export default [new A1().render(), new C1().render(), new E1().render()]; +export default [new A1().render(), new C1().render(), new E1().render(), new DateBar()]; diff --git a/test/cases/inner-graph/extend-class2/module-expr.js b/test/cases/inner-graph/extend-class2/module-expr.js index 4395782a890..b04d26a339a 100644 --- a/test/cases/inner-graph/extend-class2/module-expr.js +++ b/test/cases/inner-graph/extend-class2/module-expr.js @@ -1,3 +1,3 @@ -import { A1, C1, E1 } from "./dep-expr"; +import { A1, C1, E1, DateBar } from "./dep-expr"; -export default [new A1().render(), new C1().render(), new E1().render()]; +export default [new A1().render(), new C1().render(), new E1().render(), new DateBar()]; diff --git a/test/cases/inner-graph/extend-class2/test.filter.js b/test/cases/inner-graph/extend-class2/test.filter.js new file mode 100644 index 00000000000..4df515a5d8b --- /dev/null +++ b/test/cases/inner-graph/extend-class2/test.filter.js @@ -0,0 +1,5 @@ +var supportsClassStaticBlock = require("../../../helpers/supportsClassStaticBlock"); + +module.exports = function (config) { + return supportsClassStaticBlock(); +}; diff --git a/test/cases/inner-graph/simple/module.js b/test/cases/inner-graph/simple/module.js index a02c0fceb84..e59ea2672c0 100644 --- a/test/cases/inner-graph/simple/module.js +++ b/test/cases/inner-graph/simple/module.js @@ -12,7 +12,7 @@ function f3() { return EXPORT; } -const f4 = function() { +const f4 = function () { return EXPORT; }; @@ -95,6 +95,6 @@ export function fWithDefault(r = EXPORT4) { return r; } -export default (function() { +export default (function () { return EXPORT; }); diff --git a/test/cases/json/data/poison b/test/cases/json/data/poison new file mode 100644 index 00000000000..84d53767a2e --- /dev/null +++ b/test/cases/json/data/poison @@ -0,0 +1 @@ +throw new Error("imported") diff --git a/test/cases/json/data/unknown b/test/cases/json/data/unknown new file mode 100644 index 00000000000..12bae17cf72 --- /dev/null +++ b/test/cases/json/data/unknown @@ -0,0 +1 @@ +[1, 2, 3, 4] diff --git a/test/cases/json/import-assertions-type-json/errors.js b/test/cases/json/import-assertions-type-json/errors.js new file mode 100644 index 00000000000..c5c7bd571c6 --- /dev/null +++ b/test/cases/json/import-assertions-type-json/errors.js @@ -0,0 +1,3 @@ +module.exports = [ + [{ moduleName: /data.poison/, message: /Unexpected token .+ JSON/ }] +]; diff --git a/test/cases/json/import-assertions-type-json/import-poison.js b/test/cases/json/import-assertions-type-json/import-poison.js new file mode 100644 index 00000000000..0c1cc934c7d --- /dev/null +++ b/test/cases/json/import-assertions-type-json/import-poison.js @@ -0,0 +1,3 @@ +import poison from "../data/poison" assert { type: "json" }; + +export default poison; diff --git a/test/cases/json/import-assertions-type-json/index.js b/test/cases/json/import-assertions-type-json/index.js new file mode 100644 index 00000000000..d757fbaf4aa --- /dev/null +++ b/test/cases/json/import-assertions-type-json/index.js @@ -0,0 +1,21 @@ +import c from "../data/c.json" assert { type: "json" }; +import unknownJson from "../data/unknown" assert { type: "json" }; +import unknownJs from "../data/unknown"; + +it("should be possible to import json data with import assertion", function () { + expect(c).toEqual([1, 2, 3, 4]); +}); + +it("should be possible to import json data without extension with import assertion", function () { + expect(unknownJson).toEqual([1, 2, 3, 4]); +}); + +it("should be possible to import js without extension without import assertion in the same file", function () { + expect(unknownJs).toEqual({}); +}); + +it("should not be possible to import js with import assertion", function () { + expect(() => { + require("./import-poison.js"); + }).toThrowError(); +}); diff --git a/test/cases/json/import-assertions-type-json/infrastructure-log.js b/test/cases/json/import-assertions-type-json/infrastructure-log.js new file mode 100644 index 00000000000..17279bf2b81 --- /dev/null +++ b/test/cases/json/import-assertions-type-json/infrastructure-log.js @@ -0,0 +1,3 @@ +module.exports = [ + /^Pack got invalid because of write to: Compilation\/modules|json.+json\/data\/poison$/ +]; diff --git a/test/cases/json/import-with-type-json/errors.js b/test/cases/json/import-with-type-json/errors.js new file mode 100644 index 00000000000..c5c7bd571c6 --- /dev/null +++ b/test/cases/json/import-with-type-json/errors.js @@ -0,0 +1,3 @@ +module.exports = [ + [{ moduleName: /data.poison/, message: /Unexpected token .+ JSON/ }] +]; diff --git a/test/cases/json/import-with-type-json/import-poison.js b/test/cases/json/import-with-type-json/import-poison.js new file mode 100644 index 00000000000..41905fa6530 --- /dev/null +++ b/test/cases/json/import-with-type-json/import-poison.js @@ -0,0 +1,3 @@ +import poison from "../data/poison" with { type: "json" }; + +export default poison; diff --git a/test/cases/json/import-with-type-json/index.js b/test/cases/json/import-with-type-json/index.js new file mode 100644 index 00000000000..95e23f74729 --- /dev/null +++ b/test/cases/json/import-with-type-json/index.js @@ -0,0 +1,21 @@ +import c from "../data/c.json" with { type: "json" }; +import unknownJson from "../data/unknown" with { type: "json" }; +import unknownJs from "../data/unknown"; + +it("should be possible to import json data with import assertion", function () { + expect(c).toEqual([1, 2, 3, 4]); +}); + +it("should be possible to import json data without extension with import assertion", function () { + expect(unknownJson).toEqual([1, 2, 3, 4]); +}); + +it("should be possible to import js without extension without import assertion in the same file", function () { + expect(unknownJs).toEqual({}); +}); + +it("should not be possible to import js with import assertion", function () { + expect(() => { + require("./import-poison.js"); + }).toThrowError(); +}); diff --git a/test/cases/json/import-with-type-json/infrastructure-log.js b/test/cases/json/import-with-type-json/infrastructure-log.js new file mode 100644 index 00000000000..17279bf2b81 --- /dev/null +++ b/test/cases/json/import-with-type-json/infrastructure-log.js @@ -0,0 +1,3 @@ +module.exports = [ + /^Pack got invalid because of write to: Compilation\/modules|json.+json\/data\/poison$/ +]; diff --git a/test/cases/large/big-assets/generate-big-asset-loader.js b/test/cases/large/big-assets/generate-big-asset-loader.js new file mode 100644 index 00000000000..b904193be38 --- /dev/null +++ b/test/cases/large/big-assets/generate-big-asset-loader.js @@ -0,0 +1,6 @@ +/** @type {import("../../../../").RawLoaderDefinition<{ size: string }>} */ +module.exports = function () { + const options = this.getOptions(); + return Buffer.alloc(+options.size).fill(0xa5); +}; +module.exports.raw = true; diff --git a/test/cases/large/big-assets/index.js b/test/cases/large/big-assets/index.js new file mode 100644 index 00000000000..106c4f2c339 --- /dev/null +++ b/test/cases/large/big-assets/index.js @@ -0,0 +1,41 @@ +const createHash = require("../../../../lib/util/hash/xxhash64"); +const fs = require("fs"); + +const h = url => { + const hash = createHash(); + hash.update(fs.readFileSync(url)); + return hash.digest("hex"); +}; + +it("should compile fine", () => { + const a = new URL( + "./generate-big-asset-loader.js?size=100000000!", + import.meta.url + ); + const b = new URL( + "./generate-big-asset-loader.js?size=200000000!", + import.meta.url + ); + const c = new URL( + "./generate-big-asset-loader.js?size=300000000!", + import.meta.url + ); + const d = new URL( + "./generate-big-asset-loader.js?size=400000000!", + import.meta.url + ); + const e = new URL( + "./generate-big-asset-loader.js?size=500000000!", + import.meta.url + ); + const f = new URL( + "./generate-big-asset-loader.js?size=600000000!", + import.meta.url + ); + expect(h(a)).toBe("a7540f59366bb641"); + expect(h(b)).toBe("f642344242fa9de4"); + expect(h(c)).toBe("255d2b78f94dd585"); + expect(h(d)).toBe("c75503096358dd24"); + expect(h(e)).toBe("33ba203498301384"); + expect(h(f)).toBe("e71a39b9b1138c07"); +}); diff --git a/test/cases/large/big-assets/test.config.js b/test/cases/large/big-assets/test.config.js new file mode 100644 index 00000000000..7ab4fa5eeff --- /dev/null +++ b/test/cases/large/big-assets/test.config.js @@ -0,0 +1,3 @@ +module.exports = { + timeout: 120000 +}; diff --git a/test/cases/large/big-assets/test.filter.js b/test/cases/large/big-assets/test.filter.js new file mode 100644 index 00000000000..71a71e594ff --- /dev/null +++ b/test/cases/large/big-assets/test.filter.js @@ -0,0 +1,3 @@ +module.exports = function (config) { + return !process.env.CI; +}; diff --git a/test/cases/large/many-replacements/generate-many-replacements-loader.js b/test/cases/large/many-replacements/generate-many-replacements-loader.js new file mode 100644 index 00000000000..341649ed407 --- /dev/null +++ b/test/cases/large/many-replacements/generate-many-replacements-loader.js @@ -0,0 +1,8 @@ +/** @type {import("../../../../").RawLoaderDefinition<{ count: string }>} */ +module.exports = function () { + const options = this.getOptions(); + return `import thing from "./module"; +export default [${Array.from({ length: +options.count }, () => "thing").join( + ", " + )}].reduce((a, b) => a + b);`; +}; diff --git a/test/cases/large/many-replacements/index.js b/test/cases/large/many-replacements/index.js new file mode 100644 index 00000000000..ebe68a120f6 --- /dev/null +++ b/test/cases/large/many-replacements/index.js @@ -0,0 +1,11 @@ +import a from "./generate-many-replacements-loader?count=1000!./module"; +import b from "./generate-many-replacements-loader?count=10000!./module"; +import c from "./generate-many-replacements-loader?count=100000!./module"; +import d from "./generate-many-replacements-loader?count=1000000!./module"; + +it("should compile fine", () => { + expect(a).toBe(1000); + expect(b).toBe(10000); + expect(c).toBe(100000); + expect(d).toBe(1000000); +}); diff --git a/test/cases/large/many-replacements/module.js b/test/cases/large/many-replacements/module.js new file mode 100644 index 00000000000..aef22247d75 --- /dev/null +++ b/test/cases/large/many-replacements/module.js @@ -0,0 +1 @@ +export default 1; diff --git a/test/cases/large/many-replacements/test.config.js b/test/cases/large/many-replacements/test.config.js new file mode 100644 index 00000000000..7ab4fa5eeff --- /dev/null +++ b/test/cases/large/many-replacements/test.config.js @@ -0,0 +1,3 @@ +module.exports = { + timeout: 120000 +}; diff --git a/test/cases/large/many-replacements/test.filter.js b/test/cases/large/many-replacements/test.filter.js new file mode 100644 index 00000000000..71a71e594ff --- /dev/null +++ b/test/cases/large/many-replacements/test.filter.js @@ -0,0 +1,3 @@ +module.exports = function (config) { + return !process.env.CI; +}; diff --git a/test/cases/loaders/_esm-loader-type/index.js b/test/cases/loaders/_esm-loader-type/index.js new file mode 100644 index 00000000000..5545f1b4ff5 --- /dev/null +++ b/test/cases/loaders/_esm-loader-type/index.js @@ -0,0 +1,9 @@ +it("should pass package.json type to loader", function () { + expect(require("esm/loader.js!")).toBe("module"); +}); + +it("should pass 'module' type to loader for .mjs", function () { + expect(require("cjs/loader.mjs!")).toBe("module"); + expect(require("esm/loader.mjs!")).toBe("module"); + expect(require("./loader.mjs!")).toBe("module"); +}); diff --git a/test/cases/loaders/_esm-loader-type/loader.mjs b/test/cases/loaders/_esm-loader-type/loader.mjs new file mode 100644 index 00000000000..58914cd70e5 --- /dev/null +++ b/test/cases/loaders/_esm-loader-type/loader.mjs @@ -0,0 +1,4 @@ +/** @type {import("../../../../").LoaderDefinition} */ +export default function loader() { + return `export default "${this.loaders[this.loaderIndex].type}";`; +} diff --git a/test/cases/loaders/_esm-loader-type/node_modules/cjs/loader.mjs b/test/cases/loaders/_esm-loader-type/node_modules/cjs/loader.mjs new file mode 100644 index 00000000000..35c1f17332d --- /dev/null +++ b/test/cases/loaders/_esm-loader-type/node_modules/cjs/loader.mjs @@ -0,0 +1,4 @@ +/** @type {import("../../../../../../").LoaderDefinition} */ +export default function loader() { + return `export default "${this.loaders[this.loaderIndex].type}";`; +} diff --git a/test/cases/loaders/_esm-loader-type/node_modules/cjs/package.json b/test/cases/loaders/_esm-loader-type/node_modules/cjs/package.json new file mode 100644 index 00000000000..5b56c70baa3 --- /dev/null +++ b/test/cases/loaders/_esm-loader-type/node_modules/cjs/package.json @@ -0,0 +1,4 @@ +{ + "name": "cjs-package", + "type": "commonjs" +} diff --git a/test/cases/loaders/_esm-loader-type/node_modules/esm/loader.js b/test/cases/loaders/_esm-loader-type/node_modules/esm/loader.js new file mode 100644 index 00000000000..58914cd70e5 --- /dev/null +++ b/test/cases/loaders/_esm-loader-type/node_modules/esm/loader.js @@ -0,0 +1,4 @@ +/** @type {import("../../../../").LoaderDefinition} */ +export default function loader() { + return `export default "${this.loaders[this.loaderIndex].type}";`; +} diff --git a/test/cases/loaders/_esm-loader-type/node_modules/esm/loader.mjs b/test/cases/loaders/_esm-loader-type/node_modules/esm/loader.mjs new file mode 100644 index 00000000000..35c1f17332d --- /dev/null +++ b/test/cases/loaders/_esm-loader-type/node_modules/esm/loader.mjs @@ -0,0 +1,4 @@ +/** @type {import("../../../../../../").LoaderDefinition} */ +export default function loader() { + return `export default "${this.loaders[this.loaderIndex].type}";`; +} diff --git a/test/cases/loaders/_esm-loader-type/node_modules/esm/package.json b/test/cases/loaders/_esm-loader-type/node_modules/esm/package.json new file mode 100644 index 00000000000..64069d2b941 --- /dev/null +++ b/test/cases/loaders/_esm-loader-type/node_modules/esm/package.json @@ -0,0 +1,4 @@ +{ + "name": "esm-package", + "type": "module" +} diff --git a/test/cases/loaders/_esm-loader-type/test.filter.js b/test/cases/loaders/_esm-loader-type/test.filter.js new file mode 100644 index 00000000000..7cc1b5dd3d5 --- /dev/null +++ b/test/cases/loaders/_esm-loader-type/test.filter.js @@ -0,0 +1,5 @@ +module.exports = function (config) { + // TODO need fix in v8 https://github.com/nodejs/node/issues/35889 + // TODO otherwise this test case cause segment fault + return false; +}; diff --git a/test/cases/loaders/async/loaders/asyncloader.js b/test/cases/loaders/async/loaders/asyncloader.js index d9be05de326..c6c0eb8d422 100644 --- a/test/cases/loaders/async/loaders/asyncloader.js +++ b/test/cases/loaders/async/loaders/asyncloader.js @@ -1,8 +1,10 @@ -module.exports = function(content) { +/** @type {import("../../../../../").LoaderDefinition} */ +module.exports = function (content) { var cb = this.async(); - if(!cb) throw new Error("Loader should allow async mode"); - if(cb !== this.callback) throw new Error("result of this.async() should be equal to this.callback"); - process.nextTick(function() { + if (!cb) throw new Error("Loader should allow async mode"); + if (cb !== this.callback) + throw new Error("result of this.async() should be equal to this.callback"); + process.nextTick(function () { cb(null, content); }); -}; \ No newline at end of file +}; diff --git a/test/cases/loaders/async/loaders/syncloader.js b/test/cases/loaders/async/loaders/syncloader.js index 0356c896f23..fe0c014dba4 100644 --- a/test/cases/loaders/async/loaders/syncloader.js +++ b/test/cases/loaders/async/loaders/syncloader.js @@ -1,3 +1,4 @@ -module.exports = function(content) { +/** @type {import("../../../../../").LoaderDefinition} */ +module.exports = function (content) { return content; -}; \ No newline at end of file +}; diff --git a/test/cases/loaders/cjs-loader-type/index.js b/test/cases/loaders/cjs-loader-type/index.js new file mode 100644 index 00000000000..9bda36284e3 --- /dev/null +++ b/test/cases/loaders/cjs-loader-type/index.js @@ -0,0 +1,12 @@ +it("should pass package.json type to loader", function () { + expect(require("cjs/loader.js!")).toBe("commonjs"); + expect(require("./loader.js!")).toBe("undefined"); +}); + +it("should pass 'commonjs' type to loader for .cjs", function () { + expect(require("cjs/loader.cjs!")).toBe("commonjs"); + expect(require("./loader.cjs!")).toBe("commonjs"); + // TODO need fix in v8 https://github.com/nodejs/node/issues/35889 + // TODO otherwise this test case cause segment fault + // expect(require("esm/loader.cjs!")).toBe("commonjs"); +}); diff --git a/test/cases/loaders/cjs-loader-type/loader.cjs b/test/cases/loaders/cjs-loader-type/loader.cjs new file mode 100644 index 00000000000..94974dcfad5 --- /dev/null +++ b/test/cases/loaders/cjs-loader-type/loader.cjs @@ -0,0 +1,4 @@ +/** @type {import("../../../../").LoaderDefinition} */ +module.exports = function loader() { + return `module.exports = "${this.loaders[this.loaderIndex].type}";`; +}; diff --git a/test/cases/loaders/cjs-loader-type/loader.js b/test/cases/loaders/cjs-loader-type/loader.js new file mode 100644 index 00000000000..94974dcfad5 --- /dev/null +++ b/test/cases/loaders/cjs-loader-type/loader.js @@ -0,0 +1,4 @@ +/** @type {import("../../../../").LoaderDefinition} */ +module.exports = function loader() { + return `module.exports = "${this.loaders[this.loaderIndex].type}";`; +}; diff --git a/test/cases/loaders/cjs-loader-type/node_modules/cjs/loader.cjs b/test/cases/loaders/cjs-loader-type/node_modules/cjs/loader.cjs new file mode 100644 index 00000000000..b47e68eb16c --- /dev/null +++ b/test/cases/loaders/cjs-loader-type/node_modules/cjs/loader.cjs @@ -0,0 +1,4 @@ +/** @type {import("../../../../../../").LoaderDefinition} */ +module.exports = function loader() { + return `module.exports = "${this.loaders[this.loaderIndex].type}";`; +}; diff --git a/test/cases/loaders/cjs-loader-type/node_modules/cjs/loader.js b/test/cases/loaders/cjs-loader-type/node_modules/cjs/loader.js new file mode 100644 index 00000000000..b47e68eb16c --- /dev/null +++ b/test/cases/loaders/cjs-loader-type/node_modules/cjs/loader.js @@ -0,0 +1,4 @@ +/** @type {import("../../../../../../").LoaderDefinition} */ +module.exports = function loader() { + return `module.exports = "${this.loaders[this.loaderIndex].type}";`; +}; diff --git a/test/cases/loaders/cjs-loader-type/node_modules/cjs/package.json b/test/cases/loaders/cjs-loader-type/node_modules/cjs/package.json new file mode 100644 index 00000000000..5b56c70baa3 --- /dev/null +++ b/test/cases/loaders/cjs-loader-type/node_modules/cjs/package.json @@ -0,0 +1,4 @@ +{ + "name": "cjs-package", + "type": "commonjs" +} diff --git a/test/cases/loaders/cjs-loader-type/node_modules/esm/loader.cjs b/test/cases/loaders/cjs-loader-type/node_modules/esm/loader.cjs new file mode 100644 index 00000000000..b47e68eb16c --- /dev/null +++ b/test/cases/loaders/cjs-loader-type/node_modules/esm/loader.cjs @@ -0,0 +1,4 @@ +/** @type {import("../../../../../../").LoaderDefinition} */ +module.exports = function loader() { + return `module.exports = "${this.loaders[this.loaderIndex].type}";`; +}; diff --git a/test/cases/loaders/cjs-loader-type/node_modules/esm/package.json b/test/cases/loaders/cjs-loader-type/node_modules/esm/package.json new file mode 100644 index 00000000000..64069d2b941 --- /dev/null +++ b/test/cases/loaders/cjs-loader-type/node_modules/esm/package.json @@ -0,0 +1,4 @@ +{ + "name": "esm-package", + "type": "module" +} diff --git a/test/cases/loaders/coffee-loader/index.js b/test/cases/loaders/coffee-loader/index.js index be3924f1e3f..8d028239592 100644 --- a/test/cases/loaders/coffee-loader/index.js +++ b/test/cases/loaders/coffee-loader/index.js @@ -4,7 +4,7 @@ it("should handle the coffee loader correctly", function() { }); it("should handle literate coffee script correctly", function() { - expect(require("!coffee-loader?literate!./script.coffee.md")).toBe("literate coffee test"); + expect(require("!coffee-loader?literate=1!./script.coffee.md")).toBe("literate coffee test"); }); it("should generate valid code with cheap-source-map", function() { diff --git a/test/cases/loaders/context/test.filter.js b/test/cases/loaders/context/test.filter.js new file mode 100644 index 00000000000..3f0358f64f9 --- /dev/null +++ b/test/cases/loaders/context/test.filter.js @@ -0,0 +1,3 @@ +const supportsRequireInModule = require("../../../helpers/supportsRequireInModule"); + +module.exports = config => !config.module || supportsRequireInModule(); diff --git a/test/cases/loaders/emit-file/loader.js b/test/cases/loaders/emit-file/loader.js index 126cb485d51..c53b3e18fbc 100644 --- a/test/cases/loaders/emit-file/loader.js +++ b/test/cases/loaders/emit-file/loader.js @@ -1,4 +1,5 @@ -module.exports = function(content) { +/** @type {import("../../../../").LoaderDefinition} */ +module.exports = function (content) { this.emitFile("extra-file.js", content); return ""; -} +}; diff --git a/test/cases/loaders/emit-file/test.filter.js b/test/cases/loaders/emit-file/test.filter.js new file mode 100644 index 00000000000..d957820f37a --- /dev/null +++ b/test/cases/loaders/emit-file/test.filter.js @@ -0,0 +1,3 @@ +module.exports = function (config) { + return !config.module; +}; diff --git a/test/cases/loaders/import-module/a.json b/test/cases/loaders/import-module/a.json new file mode 100644 index 00000000000..0187f3b09d6 --- /dev/null +++ b/test/cases/loaders/import-module/a.json @@ -0,0 +1 @@ +{"a":1} diff --git a/test/cases/loaders/import-module/index.js b/test/cases/loaders/import-module/index.js new file mode 100644 index 00000000000..56a4d03f137 --- /dev/null +++ b/test/cases/loaders/import-module/index.js @@ -0,0 +1,6 @@ +import content from "./loader!!"; + +it("should compile", () => { + expect(typeof content).toBe("string"); + expect(content.startsWith("webpack://")).toBe(true); +}); diff --git a/test/cases/loaders/import-module/loader.js b/test/cases/loaders/import-module/loader.js new file mode 100644 index 00000000000..960d39ff9fa --- /dev/null +++ b/test/cases/loaders/import-module/loader.js @@ -0,0 +1,25 @@ +"use strict"; + +const path = require("path"); + +/** @type {import("../../../../").LoaderDefinition} */ +module.exports = function () { + const callback = this.async(); + this.importModule( + path.resolve(__dirname, "module.js"), + { baseUri: "webpack://" }, + (error, exports) => { + if (error) { + callback(error); + return; + } + + callback( + null, + `module.exports = ${ + exports.asset ? JSON.stringify(exports.asset) : undefined + }` + ); + } + ); +}; diff --git a/test/cases/loaders/import-module/module.js b/test/cases/loaders/import-module/module.js new file mode 100644 index 00000000000..97520ef4628 --- /dev/null +++ b/test/cases/loaders/import-module/module.js @@ -0,0 +1,3 @@ +const asset = new URL("./a.json", import.meta.url); + +export { asset } diff --git a/test/cases/loaders/import-module/test.filter.js b/test/cases/loaders/import-module/test.filter.js new file mode 100644 index 00000000000..e5009984cdb --- /dev/null +++ b/test/cases/loaders/import-module/test.filter.js @@ -0,0 +1 @@ +module.exports = config => !config.module; diff --git a/test/cases/loaders/issue-10725/loader.js b/test/cases/loaders/issue-10725/loader.js index 7c3bb85cd93..ff2b347224d 100644 --- a/test/cases/loaders/issue-10725/loader.js +++ b/test/cases/loaders/issue-10725/loader.js @@ -1,23 +1,22 @@ -const { getRemainingRequest, stringifyRequest } = require("loader-utils"); - const loaderPath = require.resolve("./loader"); +/** @type {import("../../../../").LoaderDefinition} */ module.exports = function () { if (this.query === "?load") { return ` import { answer } from "./lib"; export default answer; -` +`; } - const matchResource = `${this.resourcePath}.js`; - const loader = `${loaderPath}?load`; - const remaining = getRemainingRequest(this); - const request = JSON.parse(stringifyRequest(this, `${matchResource}!=!${loader}!${remaining}`)); + const matchResource = `${this.utils.contextify(this.context, this.resourcePath)}.js`; + const loader = `${this.utils.contextify(this.context, loaderPath)}?load`; + const remaining = this.utils.contextify(this.context, this.remainingRequest); + const request = `${matchResource}!=!${loader}!${remaining}`; this.async(); this.loadModule(request, (err, source) => { - this.callback(err, source) + this.callback(err, source); }); }; diff --git a/test/cases/loaders/module-description-file/reverseloader.js b/test/cases/loaders/module-description-file/reverseloader.js index 2983d5650c6..4cbb644664a 100644 --- a/test/cases/loaders/module-description-file/reverseloader.js +++ b/test/cases/loaders/module-description-file/reverseloader.js @@ -1,3 +1,4 @@ -module.exports = function(content) { +/** @type {import("../../../../").LoaderDefinition} */ +module.exports = function (content) { return content.split("").reverse().join(""); -} +}; diff --git a/test/cases/loaders/no-string/errors.js b/test/cases/loaders/no-string/errors.js index 7a3a289d730..79aef6533f4 100644 --- a/test/cases/loaders/no-string/errors.js +++ b/test/cases/loaders/no-string/errors.js @@ -1,10 +1,16 @@ module.exports = [ [ - {moduleName: /\.\/loaders\/no-string\/loader\.js!\.\/loaders\/no-string\/file\.js/}, + { + moduleName: + /\.\/loaders\/no-string\/loader\.js!\.\/loaders\/no-string\/file\.js/ + }, /Module build failed: Error: Final loader \(\.\/loaders\/no-string\/loader\.js\) didn't return a Buffer or String/ ], [ - {moduleName: /\.\/loaders\/no-string\/loader\.js!\.\/loaders\/no-string\/pitch-loader\.js!\.\/loaders\/no-string\/file\.js/}, + { + moduleName: + /\.\/loaders\/no-string\/loader\.js!\.\/loaders\/no-string\/pitch-loader\.js!\.\/loaders\/no-string\/file\.js/ + }, /Module build failed: Error: Final loader \(\.\/loaders\/no-string\/loader\.js\) didn't return a Buffer or String/ ] ]; diff --git a/test/cases/loaders/no-string/infrastructure-log.js b/test/cases/loaders/no-string/infrastructure-log.js new file mode 100644 index 00000000000..af316e72467 --- /dev/null +++ b/test/cases/loaders/no-string/infrastructure-log.js @@ -0,0 +1,3 @@ +module.exports = [ + /^Pack got invalid because of write to: Compilation\/modules.+no-string[/\\]loader\.js!.+no-string[/\\]file\.js$/ +]; diff --git a/test/cases/loaders/pug-loader/test.filter.js b/test/cases/loaders/pug-loader/test.filter.js new file mode 100644 index 00000000000..3f0358f64f9 --- /dev/null +++ b/test/cases/loaders/pug-loader/test.filter.js @@ -0,0 +1,3 @@ +const supportsRequireInModule = require("../../../helpers/supportsRequireInModule"); + +module.exports = config => !config.module || supportsRequireInModule(); diff --git a/test/cases/loaders/query/loaders/queryloader.js b/test/cases/loaders/query/loaders/queryloader.js index 8d606f560f8..f9bb23e1f55 100644 --- a/test/cases/loaders/query/loaders/queryloader.js +++ b/test/cases/loaders/query/loaders/queryloader.js @@ -1,7 +1,11 @@ -module.exports = function(content) { - return "module.exports = " + JSON.stringify({ - resourceQuery: this.resourceQuery, - query: this.query, - prev: content - }); -} +/** @type {import("../../../../../").LoaderDefinition} */ +module.exports = function (content) { + return ( + "module.exports = " + + JSON.stringify({ + resourceQuery: this.resourceQuery, + query: this.query, + prev: content + }) + ); +}; diff --git a/test/cases/loaders/resolve/loader.js b/test/cases/loaders/resolve/loader.js index 3bb4b23d839..53fc4aaf2f1 100644 --- a/test/cases/loaders/resolve/loader.js +++ b/test/cases/loaders/resolve/loader.js @@ -1,5 +1,6 @@ const path = require("path"); -module.exports = function() { +/** @type {import("../../../../").LoaderDefinition} */ +module.exports = function () { const resolve1 = this.getResolve(); const resolve2 = this.getResolve({ extensions: [".xyz", ".js"] diff --git a/test/cases/loaders/utils/loader.js b/test/cases/loaders/utils/loader.js index 3ee7d109250..2d9e6e37073 100644 --- a/test/cases/loaders/utils/loader.js +++ b/test/cases/loaders/utils/loader.js @@ -1,3 +1,4 @@ +/** @type {import("../../../../").LoaderDefinition} */ module.exports = function () { return `module.exports = { request1: ${JSON.stringify( diff --git a/test/cases/mjs/namespace-object-lazy/cjs-dynamic.js b/test/cases/mjs/namespace-object-lazy/cjs-dynamic.js new file mode 100644 index 00000000000..1aaa6e03da1 --- /dev/null +++ b/test/cases/mjs/namespace-object-lazy/cjs-dynamic.js @@ -0,0 +1 @@ +module.exports = Promise.resolve(1); diff --git a/test/cases/mjs/namespace-object-lazy/index.mjs b/test/cases/mjs/namespace-object-lazy/index.mjs index 088acd55a2b..63405d836e9 100644 --- a/test/cases/mjs/namespace-object-lazy/index.mjs +++ b/test/cases/mjs/namespace-object-lazy/index.mjs @@ -26,6 +26,16 @@ it("should receive a namespace object when importing commonjs with __esModule", .catch(done); }); +it("should resolve the promise returned by the imported dynamic commonjs", function (done) { + const post = "dynamic.js"; + import(/* webpackMode: "eager" */ "./cjs-" + post) // context module + .then(function (result) { + expect(result).toBe(1); + done(); + }) + .catch(done); +}); + function contextCJS(name) { return Promise.all([ import(`./dir-cjs/${name}.js`), diff --git a/test/cases/mjs/namespace-object-lazy/test.filter.js b/test/cases/mjs/namespace-object-lazy/test.filter.js index 2602795eefb..ca08e60111d 100644 --- a/test/cases/mjs/namespace-object-lazy/test.filter.js +++ b/test/cases/mjs/namespace-object-lazy/test.filter.js @@ -1,3 +1,3 @@ -module.exports = function(config) { +module.exports = function (config) { return !config.minimize; }; diff --git a/test/cases/mjs/non-enumerable/analysable-module.js b/test/cases/mjs/non-enumerable/analyzable-module.js similarity index 100% rename from test/cases/mjs/non-enumerable/analysable-module.js rename to test/cases/mjs/non-enumerable/analyzable-module.js diff --git a/test/cases/mjs/non-enumerable/errors.js b/test/cases/mjs/non-enumerable/errors.js index 4b271fd5684..95a95c2df13 100644 --- a/test/cases/mjs/non-enumerable/errors.js +++ b/test/cases/mjs/non-enumerable/errors.js @@ -1,8 +1,8 @@ module.exports = [ [ - /export '__esModule' \(imported as 'm1'\) was not found in '\.\/analysable-module\.js'/ + /export '__esModule' \(imported as 'm1'\) was not found in '\.\/analyzable-module\.js'/ ], [ - /export '__esModule' \(imported as 'm1'\) was not found in '\.\/analysable-module\.js'/ + /export '__esModule' \(imported as 'm1'\) was not found in '\.\/analyzable-module\.js'/ ] ]; diff --git a/test/cases/mjs/non-enumerable/test.js b/test/cases/mjs/non-enumerable/test.js index f610975239d..d5d2e7f4b15 100644 --- a/test/cases/mjs/non-enumerable/test.js +++ b/test/cases/mjs/non-enumerable/test.js @@ -1,7 +1,7 @@ -import * as m1 from "./analysable-module.js"; +import * as m1 from "./analyzable-module.js"; import * as m2 from "./weird-module.js"; import * as m3 from "./esModule.js"; -import d1 from "./analysable-module.js"; +import d1 from "./analyzable-module.js"; import d2 from "./weird-module.js"; import d3 from "./esModule.js"; @@ -22,7 +22,7 @@ it("should include non-enumerable properties (non-mjs)", () => { }); it("should include non-enumerable properties (non-mjs, promise)", () => - import("./analysable-module").then(m1 => { + import("./analyzable-module").then(m1 => { const ns = m1; expect(m1.prop).toBe(true); @@ -108,7 +108,7 @@ it("should include non-enumerable properties with __esModule (non-mjs)", () => { }); it("should include non-enumerable properties with __esModule (non-mjs, promise)", () => - import("./analysable-module").then(m3 => { + import("./analyzable-module").then(m3 => { const ns = m3; expect(m3.prop).toBe(true); diff --git a/test/cases/mjs/non-enumerable/test.mjs b/test/cases/mjs/non-enumerable/test.mjs index f205cdaad27..a4c1bf6915e 100644 --- a/test/cases/mjs/non-enumerable/test.mjs +++ b/test/cases/mjs/non-enumerable/test.mjs @@ -1,11 +1,11 @@ -import * as m1 from "./analysable-module.js"; +import * as m1 from "./analyzable-module.js"; import * as m2 from "./weird-module.js"; import * as m3 from "./esModule.js"; -import d1 from "./analysable-module.js"; +import d1 from "./analyzable-module.js"; import d2 from "./weird-module.js"; import d3 from "./esModule.js"; -it("should include non-enumable properties (mjs)", () => { +it("should include non-enumerable properties (mjs)", () => { const ns = m1; expect(m1.prop).toBe(true); @@ -21,8 +21,8 @@ it("should include non-enumable properties (mjs)", () => { expect(ns.__esModule).toBe(true); }); -it("should include non-enumable properties (mjs, promise)", () => - import("./analysable-module.js").then(m1 => { +it("should include non-enumerable properties (mjs, promise)", () => + import("./analyzable-module.js").then(m1 => { const ns = m1; expect(m1.prop).toBe(true); @@ -91,7 +91,7 @@ it("should not include prototype properties and symbols (mjs, promise)", () => expect(ns.__esModule).toBe(true); })); -it("should include non-enumable properties with __esModule (non-mjs)", () => { +it("should include non-enumerable properties with __esModule (non-mjs)", () => { const ns = m3; expect(m3.prop).toBe(true); @@ -107,8 +107,8 @@ it("should include non-enumable properties with __esModule (non-mjs)", () => { expect(ns.__esModule).toBe(true); }); -it("should include non-enumable properties with __esModule (non-mjs, promise)", () => - import("./analysable-module.js").then(m3 => { +it("should include non-enumerable properties with __esModule (non-mjs, promise)", () => + import("./analyzable-module.js").then(m3 => { const ns = m3; expect(m3.prop).toBe(true); diff --git a/test/cases/mjs/non-enumerable/warnings.js b/test/cases/mjs/non-enumerable/warnings.js index 2dacc856e15..d2ed9734d9d 100644 --- a/test/cases/mjs/non-enumerable/warnings.js +++ b/test/cases/mjs/non-enumerable/warnings.js @@ -1,11 +1,11 @@ module.exports = [ [ - /export '__esModule' \(imported as 'm1'\) was not found in '\.\/analysable-module\.js'/ + /export '__esModule' \(imported as 'm1'\) was not found in '\.\/analyzable-module\.js'/ ], [/export 'default' \(imported as 'm3'\) was not found in '\.\/esModule\.js'/], [/export 'default' \(imported as 'd3'\) was not found in '\.\/esModule\.js'/], [ - /export '__esModule' \(imported as 'm1'\) was not found in '\.\/analysable-module\.js'/ + /export '__esModule' \(imported as 'm1'\) was not found in '\.\/analyzable-module\.js'/ ], [/export 'default' \(imported as 'm3'\) was not found in '\.\/esModule\.js'/], [/export 'default' \(imported as 'd3'\) was not found in '\.\/esModule\.js'/] diff --git a/test/cases/mjs/non-mjs-namespace-object-lazy/cjs-dynamic.js b/test/cases/mjs/non-mjs-namespace-object-lazy/cjs-dynamic.js new file mode 100644 index 00000000000..1aaa6e03da1 --- /dev/null +++ b/test/cases/mjs/non-mjs-namespace-object-lazy/cjs-dynamic.js @@ -0,0 +1 @@ +module.exports = Promise.resolve(1); diff --git a/test/cases/mjs/non-mjs-namespace-object-lazy/index.js b/test/cases/mjs/non-mjs-namespace-object-lazy/index.js index 1059b4dc9d4..dc83158405b 100644 --- a/test/cases/mjs/non-mjs-namespace-object-lazy/index.js +++ b/test/cases/mjs/non-mjs-namespace-object-lazy/index.js @@ -12,6 +12,16 @@ it("should receive a namespace object when importing commonjs with __esModule", }).catch(done); }); +it("should resolve the promise returned by the imported dynamic commonjs", function (done) { + const post = "dynamic.js"; + import(/* webpackMode: "eager" */ "./cjs-" + post) // context module + .then(function (result) { + expect(result).toBe(1); + done(); + }) + .catch(done); +}); + function contextCJS(name) { return Promise.all([ import(`./dir-cjs/${name}`), diff --git a/test/cases/mjs/non-mjs-namespace-object-lazy/test.filter.js b/test/cases/mjs/non-mjs-namespace-object-lazy/test.filter.js index 2602795eefb..ca08e60111d 100644 --- a/test/cases/mjs/non-mjs-namespace-object-lazy/test.filter.js +++ b/test/cases/mjs/non-mjs-namespace-object-lazy/test.filter.js @@ -1,3 +1,3 @@ -module.exports = function(config) { +module.exports = function (config) { return !config.minimize; }; diff --git a/test/cases/mjs/type-module/index.js b/test/cases/mjs/type-module/index.js index b0f2a073905..8799340658e 100644 --- a/test/cases/mjs/type-module/index.js +++ b/test/cases/mjs/type-module/index.js @@ -1,5 +1,9 @@ it("should not have access to require, module and define", () => { - expect(require.webpackTestSuiteRequire).toBe(true); - expect(module.webpackTestSuiteModule).toBe(true); + expect( + typeof require === "undefined" || require.webpackTestSuiteRequire + ).toBe(true); + expect(typeof module === "undefined" || module.webpackTestSuiteModule).toBe( + true + ); expect(typeof define).toBe("undefined"); }); diff --git a/test/cases/mjs/type-null/index.js b/test/cases/mjs/type-null/index.js new file mode 100644 index 00000000000..ba421732e06 --- /dev/null +++ b/test/cases/mjs/type-null/index.js @@ -0,0 +1 @@ +it("should compile", () => {}); diff --git a/test/cases/mjs/type-null/package.json b/test/cases/mjs/type-null/package.json new file mode 100644 index 00000000000..f4d94c0c979 --- /dev/null +++ b/test/cases/mjs/type-null/package.json @@ -0,0 +1,3 @@ +{ + "type": null +} diff --git a/test/cases/optimize/side-effects-all-chain-unused/test.filter.js b/test/cases/optimize/side-effects-all-chain-unused/test.filter.js index 9022ab6415f..49ac5066bb8 100644 --- a/test/cases/optimize/side-effects-all-chain-unused/test.filter.js +++ b/test/cases/optimize/side-effects-all-chain-unused/test.filter.js @@ -1,3 +1,3 @@ -module.exports = function(config) { +module.exports = function (config) { return config.mode !== "development"; }; diff --git a/test/cases/optimize/side-effects-all-used/test.filter.js b/test/cases/optimize/side-effects-all-used/test.filter.js index 9022ab6415f..49ac5066bb8 100644 --- a/test/cases/optimize/side-effects-all-used/test.filter.js +++ b/test/cases/optimize/side-effects-all-used/test.filter.js @@ -1,3 +1,3 @@ -module.exports = function(config) { +module.exports = function (config) { return config.mode !== "development"; }; diff --git a/test/cases/optimize/side-effects-immediate-unused/test.filter.js b/test/cases/optimize/side-effects-immediate-unused/test.filter.js index 9022ab6415f..49ac5066bb8 100644 --- a/test/cases/optimize/side-effects-immediate-unused/test.filter.js +++ b/test/cases/optimize/side-effects-immediate-unused/test.filter.js @@ -1,3 +1,3 @@ -module.exports = function(config) { +module.exports = function (config) { return config.mode !== "development"; }; diff --git a/test/cases/optimize/side-effects-reexport-start-unknown/test.filter.js b/test/cases/optimize/side-effects-reexport-start-unknown/test.filter.js index 9022ab6415f..49ac5066bb8 100644 --- a/test/cases/optimize/side-effects-reexport-start-unknown/test.filter.js +++ b/test/cases/optimize/side-effects-reexport-start-unknown/test.filter.js @@ -1,3 +1,3 @@ -module.exports = function(config) { +module.exports = function (config) { return config.mode !== "development"; }; diff --git a/test/cases/optimize/side-effects-root-unused/test.filter.js b/test/cases/optimize/side-effects-root-unused/test.filter.js index 9022ab6415f..49ac5066bb8 100644 --- a/test/cases/optimize/side-effects-root-unused/test.filter.js +++ b/test/cases/optimize/side-effects-root-unused/test.filter.js @@ -1,3 +1,3 @@ -module.exports = function(config) { +module.exports = function (config) { return config.mode !== "development"; }; diff --git a/test/cases/optimize/side-effects-simple-unused/test.filter.js b/test/cases/optimize/side-effects-simple-unused/test.filter.js index 9022ab6415f..49ac5066bb8 100644 --- a/test/cases/optimize/side-effects-simple-unused/test.filter.js +++ b/test/cases/optimize/side-effects-simple-unused/test.filter.js @@ -1,3 +1,3 @@ -module.exports = function(config) { +module.exports = function (config) { return config.mode !== "development"; }; diff --git a/test/cases/optimize/side-effects-transitive-unused/test.filter.js b/test/cases/optimize/side-effects-transitive-unused/test.filter.js index 9022ab6415f..49ac5066bb8 100644 --- a/test/cases/optimize/side-effects-transitive-unused/test.filter.js +++ b/test/cases/optimize/side-effects-transitive-unused/test.filter.js @@ -1,3 +1,3 @@ -module.exports = function(config) { +module.exports = function (config) { return config.mode !== "development"; }; diff --git a/test/cases/parsing/api/id.js b/test/cases/parsing/api/id.js new file mode 100644 index 00000000000..853bd9aaad1 --- /dev/null +++ b/test/cases/parsing/api/id.js @@ -0,0 +1 @@ +export default __webpack_module__.id; diff --git a/test/cases/parsing/api/index.js b/test/cases/parsing/api/index.js new file mode 100644 index 00000000000..c8e0d9150fb --- /dev/null +++ b/test/cases/parsing/api/index.js @@ -0,0 +1,18 @@ +import id from "./id"; +import mod from "./module"; +import modType from "./typeof-module"; + +it("should support __webpack_module__.id", () => { + expect(typeof id).toMatch(/^(string|number)$/); + expect(id).not.toBe(__webpack_module__.id); +}); + +it("should support __webpack_module__", () => { + expect(mod.exports).toBeTypeOf("object"); + expect(typeof mod.id).toMatch(/^(string|number)$/); + expect(mod).not.toBe(__webpack_module__); +}); + +it("should support typeof __webpack_module__", () => { + expect(modType).toBe("object"); +}); diff --git a/test/cases/parsing/api/module.js b/test/cases/parsing/api/module.js new file mode 100644 index 00000000000..61171d82a9d --- /dev/null +++ b/test/cases/parsing/api/module.js @@ -0,0 +1 @@ +export default __webpack_module__; diff --git a/test/cases/parsing/api/typeof-module.js b/test/cases/parsing/api/typeof-module.js new file mode 100644 index 00000000000..1adb27f3e79 --- /dev/null +++ b/test/cases/parsing/api/typeof-module.js @@ -0,0 +1 @@ +export default typeof __webpack_module__; diff --git a/test/cases/parsing/asi/index.js b/test/cases/parsing/asi/index.js index c3d7ec5e767..d1fab7e4954 100644 --- a/test/cases/parsing/asi/index.js +++ b/test/cases/parsing/asi/index.js @@ -41,5 +41,8 @@ it("should respect asi flag", () => { return callme() })() + ;(donotcallme) + require("./b.json").prop + expect(getCount()).toBe(29) }); diff --git a/test/cases/parsing/asi/warnings.js b/test/cases/parsing/asi/warnings.js index 79f938e1498..39b26d59cff 100644 --- a/test/cases/parsing/asi/warnings.js +++ b/test/cases/parsing/asi/warnings.js @@ -1,3 +1 @@ -module.exports = [ - [/Critical dependency: Accessing import\.meta/] -]; +module.exports = [[/Critical dependency: Accessing import\.meta/]]; diff --git a/test/cases/parsing/bom/index.js b/test/cases/parsing/bom/index.js index 20d38778569..007b2dc22d8 100644 --- a/test/cases/parsing/bom/index.js +++ b/test/cases/parsing/bom/index.js @@ -5,7 +5,7 @@ it("should load a utf-8 file with BOM", function () { it("should load a css file with BOM", function () { var css = require("!css-loader!./bomfile.css").default + ""; - expect(css).toBe("body{color:#abc}"); + expect(css.replace(/\n\/\*[\s\S]*?\*\/|([^\\:]|^)\/\/.*$/gm, '$1')).toBe("body{color:#abc}"); }); it("should load a json file with BOM", function () { diff --git a/test/cases/parsing/class-properties/index.js b/test/cases/parsing/class-properties/index.js new file mode 100644 index 00000000000..e81488eac65 --- /dev/null +++ b/test/cases/parsing/class-properties/index.js @@ -0,0 +1,21 @@ +import { A, B } from "./module"; +import { A as A1, B as B1 } from "./module?1"; + +it("should not rename class properties", function () { + expect(A.staticProp).toBe("value"); + expect(B.staticProp).toBe("value"); + expect(A1.staticProp).toBe("value"); + expect(B1.staticProp).toBe("value"); + expect(A.value).toBe("value"); + expect(B.value).toBe("value"); + expect(A1.value).toBe("value"); + expect(B1.value).toBe("value"); + expect(new A().prop).toBe("value"); + expect(new B().prop).toBe("value"); + expect(new A1().prop).toBe("value"); + expect(new B1().prop).toBe("value"); + expect(new A().value).toBe("value"); + expect(new B().value).toBe("value"); + expect(new A1().value).toBe("value"); + expect(new B1().value).toBe("value"); +}); diff --git a/test/cases/parsing/class-properties/module.js b/test/cases/parsing/class-properties/module.js new file mode 100644 index 00000000000..8736c7ca191 --- /dev/null +++ b/test/cases/parsing/class-properties/module.js @@ -0,0 +1,21 @@ +import { + staticProp as importedStaticProp, + prop as importedProp +} from "./module"; + +export const staticProp = "value"; +export const prop = "value"; + +export class A { + static staticProp = staticProp; + static [staticProp] = staticProp; + prop = prop; + [prop] = prop; +} + +export class B { + static staticProp = importedStaticProp; + static [importedStaticProp] = importedStaticProp; + prop = importedProp; + [importedProp] = importedProp; +} diff --git a/test/cases/parsing/class-properties/test.filter.js b/test/cases/parsing/class-properties/test.filter.js new file mode 100644 index 00000000000..25a2a20eb28 --- /dev/null +++ b/test/cases/parsing/class-properties/test.filter.js @@ -0,0 +1,5 @@ +var supportsClassFields = require("../../../helpers/supportsClassFields"); + +module.exports = function (config) { + return supportsClassFields(); +}; diff --git a/test/cases/parsing/context/index.js b/test/cases/parsing/context/index.js index 6822f3c8892..c2bbbc43eef 100644 --- a/test/cases/parsing/context/index.js +++ b/test/cases/parsing/context/index.js @@ -20,7 +20,7 @@ it("should automatically create contexts", function() { expect(require("./templates/t" + mp + "l")).toBe("test template"); }); -it("should be able to require.resolve with automatical context", function() { +it("should be able to require.resolve with automatic context", function() { var template = "tmpl"; expect(require.resolve("./templates/" + template)).toBe( require.resolve("./templates/tmpl") diff --git a/test/cases/parsing/context/infrastructure-log.js b/test/cases/parsing/context/infrastructure-log.js new file mode 100644 index 00000000000..e458f85280b --- /dev/null +++ b/test/cases/parsing/context/infrastructure-log.js @@ -0,0 +1,3 @@ +module.exports = [ + /^Pack got invalid because of write to: Compilation\/modules|.+dump-file\.txt/ +]; diff --git a/test/cases/parsing/context/loaders/queryloader.js b/test/cases/parsing/context/loaders/queryloader.js index 02707b2ba37..f9bb23e1f55 100644 --- a/test/cases/parsing/context/loaders/queryloader.js +++ b/test/cases/parsing/context/loaders/queryloader.js @@ -1,7 +1,11 @@ -module.exports = function(content) { - return "module.exports = " + JSON.stringify({ - resourceQuery: this.resourceQuery, - query: this.query, - prev: content - }); +/** @type {import("../../../../../").LoaderDefinition} */ +module.exports = function (content) { + return ( + "module.exports = " + + JSON.stringify({ + resourceQuery: this.resourceQuery, + query: this.query, + prev: content + }) + ); }; diff --git a/test/cases/parsing/es2020/index.js b/test/cases/parsing/es2020/index.js new file mode 100644 index 00000000000..50e196c8d76 --- /dev/null +++ b/test/cases/parsing/es2020/index.js @@ -0,0 +1,38 @@ +import { a } from "./module"; + +class Class { + #field = this instanceof Class ? a : false; + field = this instanceof Class ? a : false; + #method = () => (this instanceof Class ? a : false); + method = () => (this instanceof Class ? a : false); + [`key${!this ? a : false}`] = this instanceof Class ? a : false; + + static CLASS = true; + + static #sfield = this.CLASS ? a : false; + static sfield = this.CLASS ? a : false; + static #smethod = () => (this.CLASS ? a : false); + static smethod = () => (this.CLASS ? a : false); + static [`skey${!this ? a : false}`] = this.CLASS ? a : false; + + test() { + expect(this.#field).toBe(42); + expect(this.field).toBe(42); + expect(this.#method()).toBe(42); + expect(this.method()).toBe(42); + expect(this.key42).toBe(42); + } + + static stest() { + expect(Class.#sfield).toBe(42); + expect(Class.sfield).toBe(42); + expect(Class.#smethod()).toBe(42); + expect(Class.smethod()).toBe(42); + expect(Class.skey42).toBe(42); + } +} + +it("should support class fields", () => { + Class.stest(); + new Class().test(); +}); diff --git a/test/cases/parsing/es2020/module.js b/test/cases/parsing/es2020/module.js new file mode 100644 index 00000000000..71becd3a350 --- /dev/null +++ b/test/cases/parsing/es2020/module.js @@ -0,0 +1 @@ +export const a = 42; diff --git a/test/cases/parsing/es2020/test.filter.js b/test/cases/parsing/es2020/test.filter.js new file mode 100644 index 00000000000..25a2a20eb28 --- /dev/null +++ b/test/cases/parsing/es2020/test.filter.js @@ -0,0 +1,5 @@ +var supportsClassFields = require("../../../helpers/supportsClassFields"); + +module.exports = function (config) { + return supportsClassFields(); +}; diff --git a/test/cases/parsing/es2022/counter.js b/test/cases/parsing/es2022/counter.js new file mode 100644 index 00000000000..befe6cdde9d --- /dev/null +++ b/test/cases/parsing/es2022/counter.js @@ -0,0 +1,4 @@ +let value = 0; +const add = () => value++; + +export { value, add } diff --git a/test/cases/parsing/es2022/es2022.js b/test/cases/parsing/es2022/es2022.js new file mode 100644 index 00000000000..de68a3d3cab --- /dev/null +++ b/test/cases/parsing/es2022/es2022.js @@ -0,0 +1,20 @@ +import { "\0 add" as add } from './reexport'; + +export default class Foo { + static { + new Foo(add); + } + + constructor(fn) { + this.#foo = fn; + this.#add(); + } + + #foo = undefined; + + #add() { + if (#foo in this && this.#foo) { + this.#foo(); + } + } +} diff --git a/test/cases/parsing/es2022/index.js b/test/cases/parsing/es2022/index.js new file mode 100644 index 00000000000..1050bdd8a2d --- /dev/null +++ b/test/cases/parsing/es2022/index.js @@ -0,0 +1,7 @@ +import { value, add } from "./counter"; +import Foo from "./es2022"; + +it("should compile and run", () => { + new Foo(add); + expect(value).toBe(2); +}); diff --git a/test/cases/parsing/es2022/reexport.js b/test/cases/parsing/es2022/reexport.js new file mode 100644 index 00000000000..f2e9cce1091 --- /dev/null +++ b/test/cases/parsing/es2022/reexport.js @@ -0,0 +1 @@ +export { add as "\0 add" } from "./counter"; diff --git a/test/cases/parsing/es2022/test.filter.js b/test/cases/parsing/es2022/test.filter.js new file mode 100644 index 00000000000..38c3136db5a --- /dev/null +++ b/test/cases/parsing/es2022/test.filter.js @@ -0,0 +1,11 @@ +module.exports = function (config) { + // terser doesn't support static {} + if (config.mode === "production") return false; + + try { + eval("class A { static {} }"); + return true; + } catch { + return false; + } +}; diff --git a/test/cases/parsing/es6.nominimize/index.js b/test/cases/parsing/es6.nominimize/index.js index 70031b4cad6..8fc415c51e0 100644 --- a/test/cases/parsing/es6.nominimize/index.js +++ b/test/cases/parsing/es6.nominimize/index.js @@ -2,7 +2,7 @@ import a from "./a"; -it("should parse classes", function() { +it("should parse classes", function () { class MyClass { constructor() { this.a = require("./a"); @@ -24,30 +24,32 @@ it("should parse classes", function() { expect(x.c()).toBe("c"); }); -it("should parse spread operator"/*, function() { +it("should parse spread operator", function () { expect([0, ...require("./array")]).toEqual([0, 1, 2, 3]); - expect(({z: 0, ...require("./object")})).toEqual({z: 0, a: 1, b: 2, c: 3}); -}*/); + expect({ z: 0, ...require("./object") }).toEqual({ z: 0, a: 1, b: 2, c: 3 }); +}); -it("should parse arrow function", function() { +it("should parse arrow function", function () { expect((() => require("./a"))()).toBe("a"); - expect((() => { - return require("./a"); - })()).toBe("a"); + expect( + (() => { + return require("./a"); + })() + ).toBe("a"); require.ensure([], () => { require("./a"); }); require.ensure([], () => { require("./async"); }); - if(module.hot) { + if (module.hot) { module.hot.accept("./a", () => { var x = 1; }); } }); -it("should parse template literals", function() { +it("should parse template literals", function () { function tag(strings, value) { return value; } @@ -55,9 +57,9 @@ it("should parse template literals", function() { var y = tag`a${require("./b")}c`; expect(x).toBe("abc"); expect(y).toBe("b"); -}) +}); -it("should parse generators and yield", function() { +it("should parse generators and yield", function () { function* gen() { yield require("./a"); yield require("./b"); @@ -66,4 +68,4 @@ it("should parse generators and yield", function() { expect(x.next().value).toBe("a"); expect(x.next().value).toBe("b"); expect(x.next().done).toBe(true); -}) +}); diff --git a/test/cases/parsing/evaluate-nullish/index.js b/test/cases/parsing/evaluate-nullish/index.js index bd2dfbac3f9..128a96c8e52 100644 --- a/test/cases/parsing/evaluate-nullish/index.js +++ b/test/cases/parsing/evaluate-nullish/index.js @@ -1,5 +1,9 @@ +function a() {} + it("should evaluate nullish coalescing", function () { expect("" ?? require("fail")).toBe(""); + expect(String.raw`aaaa` ?? require("fail")).toBe("aaaa"); + expect(a`aaaa` ?? "expected").toBe("expected"); expect(null ?? "expected").toBe("expected"); expect(("" ?? require("fail")) && true).toBe(""); let x = 0; diff --git a/test/cases/parsing/evaluate/index.js b/test/cases/parsing/evaluate/index.js index 420bce02b6a..e29a31fb622 100644 --- a/test/cases/parsing/evaluate/index.js +++ b/test/cases/parsing/evaluate/index.js @@ -3,6 +3,12 @@ it("should evaluate null", function () { if (null) require("fail"); }); +it("should evaluate undefined", function () { + const y = undefined ? require("fail") : require("./a"); + if (undefined) require("fail"); + undefined && require("fail"); +}); + it("should evaluate logical expression", function () { const value1 = "hello" || require("fail"); const value2 = typeof require === "function" || require("fail"); diff --git a/test/cases/parsing/evaluate/resourceFragment/index.js b/test/cases/parsing/evaluate/resourceFragment/index.js index fc699a5aad8..cf443cdc4e6 100644 --- a/test/cases/parsing/evaluate/resourceFragment/index.js +++ b/test/cases/parsing/evaluate/resourceFragment/index.js @@ -1,3 +1,3 @@ module.exports = require(( - __resourceFragment.substr(1) + "/resourceFragment/returnRF#XXXFragment" + __resourceFragment.slice(1) + "/resourceFragment/returnRF#XXXFragment" ).replace(/XXX/g, "resource")); diff --git a/test/cases/parsing/evaluate/resourceQuery/index.js b/test/cases/parsing/evaluate/resourceQuery/index.js index 21596f97369..173f9da8dfd 100644 --- a/test/cases/parsing/evaluate/resourceQuery/index.js +++ b/test/cases/parsing/evaluate/resourceQuery/index.js @@ -1 +1 @@ -module.exports = require((__resourceQuery.substr(1) + "/resourceQuery/returnRQ?XXXQuery").replace(/XXX/g, "resource")); \ No newline at end of file +module.exports = require((__resourceQuery.slice(1) + "/resourceQuery/returnRQ?XXXQuery").replace(/XXX/g, "resource")); diff --git a/test/cases/parsing/extract-amd.nominimize/index.js b/test/cases/parsing/extract-amd.nominimize/index.js index a79383e0026..3bfc3fa2749 100644 --- a/test/cases/parsing/extract-amd.nominimize/index.js +++ b/test/cases/parsing/extract-amd.nominimize/index.js @@ -17,7 +17,7 @@ it("should parse fancy function calls with arrow functions", function() { it("should parse fancy AMD calls with arrow functions", function() { require("./constructor ./a".split(" ")); - require("-> module module exports *constructor *a".replace("module", "require").substr(3).replace(/\*/g, "./").split(" "), (require, module, exports, constructor, a) => { + require("-> module module exports *constructor *a".replace("module", "require").slice(3).replace(/\*/g, "./").split(" "), (require, module, exports, constructor, a) => { expect((typeof require)).toBe("function"); expect((typeof module)).toBe("object"); expect((typeof exports)).toBe("object"); @@ -25,7 +25,7 @@ it("should parse fancy AMD calls with arrow functions", function() { expect((typeof constructor)).toBe("function"); expect(a).toBe("a"); }); - define("-> module module exports *constructor *a".replace("module", "require").substr(3).replace(/\*/g, "./").split(" "), (require, module, exports, constructor, a) => { + define("-> module module exports *constructor *a".replace("module", "require").slice(3).replace(/\*/g, "./").split(" "), (require, module, exports, constructor, a) => { expect((typeof require)).toBe("function"); expect((typeof module)).toBe("object"); expect((typeof exports)).toBe("object"); diff --git a/test/cases/parsing/extract-amd/index.js b/test/cases/parsing/extract-amd/index.js index 13cc0d3f047..39822b5b9eb 100644 --- a/test/cases/parsing/extract-amd/index.js +++ b/test/cases/parsing/extract-amd/index.js @@ -17,7 +17,7 @@ it("should parse fancy function calls", function() { it("should parse fancy AMD calls", function() { require("./constructor ./a".split(" ")); - require("-> module module exports *constructor *a".replace("module", "require").substr(3).replace(/\*/g, "./").split(" "), function(require, module, exports, constructor, a) { + require("-> module module exports *constructor *a".replace("module", "require").slice(3).replace(/\*/g, "./").split(" "), function(require, module, exports, constructor, a) { expect((typeof require)).toBe("function"); expect((typeof module)).toBe("object"); expect((typeof exports)).toBe("object"); @@ -25,7 +25,7 @@ it("should parse fancy AMD calls", function() { expect((typeof constructor)).toBe("function"); expect(a).toBe("a"); }); - define("-> module module exports *constructor *a".replace("module", "require").substr(3).replace(/\*/g, "./").split(" "), function(require, module, exports, constructor, a) { + define("-> module module exports *constructor *a".replace("module", "require").slice(3).replace(/\*/g, "./").split(" "), function(require, module, exports, constructor, a) { expect((typeof require)).toBe("function"); expect((typeof module)).toBe("object"); expect((typeof exports)).toBe("object"); diff --git a/test/cases/parsing/extract-amd/warnings.js b/test/cases/parsing/extract-amd/warnings.js index aa20932a1d3..418492a70f6 100644 --- a/test/cases/parsing/extract-amd/warnings.js +++ b/test/cases/parsing/extract-amd/warnings.js @@ -1,3 +1,3 @@ module.exports = [ - [/Module not found/, /Can't resolve '\.\/b' /, {details: /b\.js/}] + [/Module not found/, /Can't resolve '\.\/b' /, { details: /b\.js/ }] ]; diff --git a/test/cases/parsing/extract-require/errors.js b/test/cases/parsing/extract-require/errors.js index 576a4be9ecf..cb2596c1104 100644 --- a/test/cases/parsing/extract-require/errors.js +++ b/test/cases/parsing/extract-require/errors.js @@ -1,3 +1,7 @@ module.exports = [ - [/Module not found/, /Can't resolve '\.\/missingModule' /, {moduleName: /extract-require\/index.js/}] + [ + /Module not found/, + /Can't resolve '\.\/missingModule' /, + { moduleName: /extract-require\/index.js/ } + ] ]; diff --git a/test/cases/parsing/harmony-commonjs-mix/module1.js b/test/cases/parsing/harmony-commonjs-mix/module1.js index aa3681a495c..45bb8d02e35 100644 --- a/test/cases/parsing/harmony-commonjs-mix/module1.js +++ b/test/cases/parsing/harmony-commonjs-mix/module1.js @@ -14,6 +14,6 @@ expect(function() { export default 1234; if(eval("typeof exports !== \"undefined\"")) { - // exports is node.js exports and not webpacks + // exports is node.js exports and not webpack's expect(Object.keys(exports)).toEqual([]); } diff --git a/test/cases/parsing/harmony-deep-exports/cjs2.js b/test/cases/parsing/harmony-deep-exports/cjs2.js new file mode 100644 index 00000000000..61d6ba1833b --- /dev/null +++ b/test/cases/parsing/harmony-deep-exports/cjs2.js @@ -0,0 +1 @@ +module.exports = require("./cjs3"); diff --git a/test/cases/parsing/harmony-deep-exports/cjs3.js b/test/cases/parsing/harmony-deep-exports/cjs3.js new file mode 100644 index 00000000000..f02c088c18c --- /dev/null +++ b/test/cases/parsing/harmony-deep-exports/cjs3.js @@ -0,0 +1,3 @@ +exports.a = 1; +exports.b = 2; +exports.cjs3DefaultProvidedInfo = __webpack_exports_info__.default.provideInfo; diff --git a/test/cases/parsing/harmony-deep-exports/esm1.js b/test/cases/parsing/harmony-deep-exports/esm1.js new file mode 100644 index 00000000000..e7edf24999f --- /dev/null +++ b/test/cases/parsing/harmony-deep-exports/esm1.js @@ -0,0 +1,2 @@ +export default 2; +export const esmDefaultProvidedInfo = __webpack_exports_info__.default.provideInfo; diff --git a/test/cases/parsing/harmony-deep-exports/index.js b/test/cases/parsing/harmony-deep-exports/index.js index b2895c18251..627455e7746 100644 --- a/test/cases/parsing/harmony-deep-exports/index.js +++ b/test/cases/parsing/harmony-deep-exports/index.js @@ -1,6 +1,19 @@ import * as C from "./reexport-namespace"; import { counter } from "./reexport-namespace"; import * as C2 from "./reexport-namespace-again"; +import cj2, { cjs3DefaultProvidedInfo } from "./cjs2"; +import esm1, { esmDefaultProvidedInfo } from "./esm1"; + +it("default providedInfo should be correct for cjs", () => { + expect(cj2.a).toBe(1); + expect(cjs3DefaultProvidedInfo).toBe(false); + expect(__webpack_exports_info__.cj2.default.provideInfo).toBe(false); +}); + +it("default providedInfo and usedInfo should be correct for esm", () => { + expect(esm1).toBe(2); + expect(esmDefaultProvidedInfo).toBe(true); +}); it("should allow to reexport namespaces 1", () => { (0, counter.reset)(); diff --git a/test/cases/parsing/harmony-destructuring-assignment/counter.js b/test/cases/parsing/harmony-destructuring-assignment/counter.js new file mode 100644 index 00000000000..a33b7727575 --- /dev/null +++ b/test/cases/parsing/harmony-destructuring-assignment/counter.js @@ -0,0 +1,9 @@ +export let counter = 0; +export const d = 1; +export const c = 1; + +export const exportsInfo = { + counter: __webpack_exports_info__.counter.used, + d: __webpack_exports_info__.d.used, + c: __webpack_exports_info__.c.used +}; diff --git a/test/cases/parsing/harmony-destructuring-assignment/counter2.js b/test/cases/parsing/harmony-destructuring-assignment/counter2.js new file mode 100644 index 00000000000..21dbf67c4b0 --- /dev/null +++ b/test/cases/parsing/harmony-destructuring-assignment/counter2.js @@ -0,0 +1,7 @@ +export let counter = 0; +export const d = 1; + +export const exportsInfo = { + counter: __webpack_exports_info__.counter.used, + d: __webpack_exports_info__.d.used +}; diff --git a/test/cases/parsing/harmony-destructuring-assignment/counter3.js b/test/cases/parsing/harmony-destructuring-assignment/counter3.js new file mode 100644 index 00000000000..21dbf67c4b0 --- /dev/null +++ b/test/cases/parsing/harmony-destructuring-assignment/counter3.js @@ -0,0 +1,7 @@ +export let counter = 0; +export const d = 1; + +export const exportsInfo = { + counter: __webpack_exports_info__.counter.used, + d: __webpack_exports_info__.d.used +}; diff --git a/test/cases/parsing/harmony-destructuring-assignment/counter4.js b/test/cases/parsing/harmony-destructuring-assignment/counter4.js new file mode 100644 index 00000000000..43eff0ee0a3 --- /dev/null +++ b/test/cases/parsing/harmony-destructuring-assignment/counter4.js @@ -0,0 +1,15 @@ +export let counter = 0; +export const d = 1; +export const c = 1; +export const e = 1; +export const f = 1; +export const g = 1; + +export const exportsInfo = { + counter: __webpack_exports_info__.counter.used, + d: __webpack_exports_info__.d.used, + c: __webpack_exports_info__.c.used, + e: __webpack_exports_info__.e.used, + f: __webpack_exports_info__.f.used, + g: __webpack_exports_info__.g.used +}; diff --git a/test/cases/parsing/harmony-destructuring-assignment/index.js b/test/cases/parsing/harmony-destructuring-assignment/index.js new file mode 100644 index 00000000000..42e573e3900 --- /dev/null +++ b/test/cases/parsing/harmony-destructuring-assignment/index.js @@ -0,0 +1,55 @@ +import * as C from "./reexport-namespace"; +import { counter } from "./reexport-namespace"; +import { exportsInfo } from "./counter"; +import { exportsInfo as exportsInfo2 } from "./counter2"; +import * as counter3 from "./counter3"; +import * as counter4 from "./counter4"; + +it("expect tree-shake unused exports #1", () => { + const { D } = C; + expect(D).toBe(1); + expect(C.exportsInfo.D).toBe(true); + expect(C.exportsInfo.E).toBe(false); +}); + +it("expect tree-shake unused exports #2", () => { + const { d, c } = C.counter; + const { ['d']: d1 } = counter; + expect(d).toBe(1); + expect(c).toBe(1); + expect(d1).toBe(1); + expect(exportsInfo.d).toBe(true); + expect(exportsInfo.c).toBe(true); + expect(exportsInfo.counter).toBe(false); +}); + +it("expect multiple assignment work correctly", () => { + const { e, d: d1 } = counter4; + let c1; + const { f, d: d2 } = { c: c1 } = counter4; + expect(c1).toBe(1); + expect(d1).toBe(1); + expect(d2).toBe(1); + expect(e).toBe(1); + expect(f).toBe(1); + expect(counter4.exportsInfo.c).toBe(true); + expect(counter4.exportsInfo.d).toBe(true); + expect(counter4.exportsInfo.e).toBe(true); + expect(counter4.exportsInfo.f).toBe(true); + expect(counter4.exportsInfo.g).toBe(false); + expect(counter4.exportsInfo.counter).toBe(false); +}); + +it("expect tree-shake bailout when rest element is used", () => { + const { d, ...rest } = counter3; + expect(d).toBe(1); + expect(rest.exportsInfo.d).toBe(true); + expect(rest.exportsInfo.counter).toBe(true); +}); + +it("expect no support of \"deep\" tree-shaking", () => { + const { counter2: { d } } = C; + expect(d).toBe(1); + expect(exportsInfo2.d).toBe(true); + expect(exportsInfo2.counter).toBe(true); +}); diff --git a/test/cases/parsing/harmony-destructuring-assignment/reexport-namespace.js b/test/cases/parsing/harmony-destructuring-assignment/reexport-namespace.js new file mode 100644 index 00000000000..4a41ad89f66 --- /dev/null +++ b/test/cases/parsing/harmony-destructuring-assignment/reexport-namespace.js @@ -0,0 +1,14 @@ +import * as counter from "./counter"; +export { counter }; +import * as counter2 from "./counter2"; +export { counter2 }; + +export const D = 1; +export const E = 1; + +export const exportsInfo = { + D: __webpack_exports_info__.D.used, + E: __webpack_exports_info__.E.used, + counter: __webpack_exports_info__.counter.used, + counter2: __webpack_exports_info__.counter2.used, +}; diff --git a/test/cases/parsing/harmony-destructuring-assignment/test.filter.js b/test/cases/parsing/harmony-destructuring-assignment/test.filter.js new file mode 100644 index 00000000000..f176154b261 --- /dev/null +++ b/test/cases/parsing/harmony-destructuring-assignment/test.filter.js @@ -0,0 +1,4 @@ +module.exports = function (config) { + // This test can't run in development mode + return config.mode !== "development"; +}; diff --git a/test/cases/parsing/harmony-export-import-specifier-asi/a.js b/test/cases/parsing/harmony-export-import-specifier-asi/a.js new file mode 100644 index 00000000000..9549e18a567 --- /dev/null +++ b/test/cases/parsing/harmony-export-import-specifier-asi/a.js @@ -0,0 +1,3 @@ +export const fn = (num) => { + return num; +}; diff --git a/test/cases/parsing/harmony-export-import-specifier-asi/index.js b/test/cases/parsing/harmony-export-import-specifier-asi/index.js new file mode 100644 index 00000000000..3c0ae95aaa7 --- /dev/null +++ b/test/cases/parsing/harmony-export-import-specifier-asi/index.js @@ -0,0 +1,11 @@ +import { fn } from './a.js'; + +const num = 1 + +export { fn } from './a.js'; + +fn(num); + +it("should work", function() { + expect(fn(num)).toBe(1); +}); diff --git a/test/cases/parsing/harmony-export-import-specifier/cjs1.js b/test/cases/parsing/harmony-export-import-specifier/cjs1.js new file mode 100644 index 00000000000..01fa3b71d0e --- /dev/null +++ b/test/cases/parsing/harmony-export-import-specifier/cjs1.js @@ -0,0 +1,2 @@ +exports.a = 2; +exports.b = 3; diff --git a/test/cases/parsing/harmony-export-import-specifier/cjs2.js b/test/cases/parsing/harmony-export-import-specifier/cjs2.js new file mode 100644 index 00000000000..e650ca0fe4f --- /dev/null +++ b/test/cases/parsing/harmony-export-import-specifier/cjs2.js @@ -0,0 +1 @@ +module.exports = require("./cjs1"); diff --git a/test/cases/parsing/harmony-export-import-specifier/index.js b/test/cases/parsing/harmony-export-import-specifier/index.js index 013653cb1c1..b33516186da 100644 --- a/test/cases/parsing/harmony-export-import-specifier/index.js +++ b/test/cases/parsing/harmony-export-import-specifier/index.js @@ -5,6 +5,17 @@ import { d2, usedD1, usedD2 } from "./d.js"; import { b1, usedB1, usedB2, usedB3, usedB4 } from "./b.js"; import { usedE1, usedE2 } from "./e.js"; import { h } from "./h.js"; +import * as m from "./m"; +import { object as obj } from "./m"; +import cjs from "./cjs2"; +import * as o from "./o"; +import * as p from "./p"; +import * as q from "./q"; +import * as so from "./side-effect-free/o"; +import * as sm from "./side-effect-free/m"; +import json1 from "./some.json"; +import json2 from "./some1.json"; +import weirdCjs from "./weird-cjs"; it("namespace export as from commonjs should override named export", function () { expect(x).toBe(1); @@ -35,3 +46,45 @@ it("complex case should work correctly", () => { expect(usedE2).toBe(false); } }); + +it("should handle 'm in n' case", () => { + const obj = { aaa: "aaa" in m }; + expect(obj.aaa).toBe(true); + expect("not_here" in m.object).toBe(false); + expect("not_here" in obj).toBe(false); + expect("__esModule" in q).toBe(true); + expect(() => "value" in q.__esModule).toThrow(); + expect(() => "not_here" in json1).toThrow(); + expect("not_here" in json2).toBe(false); + expect("a" in json2).toBe(true); + expect("a" in cjs).toBe(true); + expect("not_here" in cjs).toBe(false); + expect("not_here" in weirdCjs).toBe(false); + expect("a" in weirdCjs).toBe(true); + expect(() => "a" in weirdCjs.a).toThrow(); + expect("aaa" in o).toBe(true); + expect("aaa" in p).toBe(false); + expect("ccc" in m).toBe(false); + expect("aaa" in q).toBe(true); + expect("aaa" in so).toBe(true); + expect("ccc" in sm).toBe(false); + expect("ccc" in (false ? {} : m.ddd)).toBe(true); + expect("ccc" in (false ? {} : sm.ddd)).toBe(true); + expect("ddd" in m.ddd).toBe(false); + expect("ddd" in sm.ddd).toBe(false); + if (process.env.NODE_ENV === "production") { + expect(m.ddd.usedA).toBe(false); + expect(m.usedB).toBe(false); + expect(m.usedA).toBe(true); + expect(m.canMangleA).toBe(true); + } +}); + +it("issue-15759", () => { + function foo() { + // PLEASE CONFIRM there is no space after return + // prettier-ignore + return"usedA"in m; + } + expect(foo.call()).toBe(true); +}); diff --git a/test/cases/parsing/harmony-export-import-specifier/m.js b/test/cases/parsing/harmony-export-import-specifier/m.js new file mode 100644 index 00000000000..d47ba358a40 --- /dev/null +++ b/test/cases/parsing/harmony-export-import-specifier/m.js @@ -0,0 +1,7 @@ +export const aaa = 1; +export const bbb = 2; +export const object = {}; +export * as ddd from "./n"; +export const usedA = __webpack_exports_info__.aaa.used; +export const canMangleA = __webpack_exports_info__.ccc.canMangle; +export const usedB = __webpack_exports_info__.bbb.used; diff --git a/test/cases/parsing/harmony-export-import-specifier/n.js b/test/cases/parsing/harmony-export-import-specifier/n.js new file mode 100644 index 00000000000..f41485c9dc1 --- /dev/null +++ b/test/cases/parsing/harmony-export-import-specifier/n.js @@ -0,0 +1,5 @@ +export const ccc = 3; +export const mmm = () => ({}); +export const aaa = 1; +export const usedA = __webpack_exports_info__.a.used; +export const canMangleC = __webpack_exports_info__.c.canMangle; diff --git a/test/cases/parsing/harmony-export-import-specifier/o.js b/test/cases/parsing/harmony-export-import-specifier/o.js new file mode 100644 index 00000000000..561e90cc163 --- /dev/null +++ b/test/cases/parsing/harmony-export-import-specifier/o.js @@ -0,0 +1,2 @@ +const exports_ = { aaa: 1, bbb: 2 }; +module.exports = exports_; diff --git a/test/configCases/asset-modules/opus/file.opus b/test/cases/parsing/harmony-export-import-specifier/p.js similarity index 100% rename from test/configCases/asset-modules/opus/file.opus rename to test/cases/parsing/harmony-export-import-specifier/p.js diff --git a/test/cases/parsing/harmony-export-import-specifier/q.js b/test/cases/parsing/harmony-export-import-specifier/q.js new file mode 100644 index 00000000000..aea63e5b1d8 --- /dev/null +++ b/test/cases/parsing/harmony-export-import-specifier/q.js @@ -0,0 +1 @@ +export * from "./o"; diff --git a/test/cases/parsing/harmony-export-import-specifier/side-effect-free/m.js b/test/cases/parsing/harmony-export-import-specifier/side-effect-free/m.js new file mode 100644 index 00000000000..2385ca4646c --- /dev/null +++ b/test/cases/parsing/harmony-export-import-specifier/side-effect-free/m.js @@ -0,0 +1 @@ +export * from "../m"; diff --git a/test/cases/parsing/harmony-export-import-specifier/side-effect-free/o.js b/test/cases/parsing/harmony-export-import-specifier/side-effect-free/o.js new file mode 100644 index 00000000000..9b7e1d2e4c5 --- /dev/null +++ b/test/cases/parsing/harmony-export-import-specifier/side-effect-free/o.js @@ -0,0 +1 @@ +export * from "../o"; diff --git a/test/cases/parsing/harmony-export-import-specifier/side-effect-free/package.json b/test/cases/parsing/harmony-export-import-specifier/side-effect-free/package.json new file mode 100644 index 00000000000..a43829151e1 --- /dev/null +++ b/test/cases/parsing/harmony-export-import-specifier/side-effect-free/package.json @@ -0,0 +1,3 @@ +{ + "sideEffects": false +} diff --git a/test/cases/parsing/harmony-export-import-specifier/some.json b/test/cases/parsing/harmony-export-import-specifier/some.json new file mode 100644 index 00000000000..27ba77ddaf6 --- /dev/null +++ b/test/cases/parsing/harmony-export-import-specifier/some.json @@ -0,0 +1 @@ +true diff --git a/test/cases/parsing/harmony-export-import-specifier/some1.json b/test/cases/parsing/harmony-export-import-specifier/some1.json new file mode 100644 index 00000000000..8d6b85c7b3f --- /dev/null +++ b/test/cases/parsing/harmony-export-import-specifier/some1.json @@ -0,0 +1,3 @@ +{ + "a": 1 +} diff --git a/test/cases/parsing/harmony-export-import-specifier/weird-cjs.js b/test/cases/parsing/harmony-export-import-specifier/weird-cjs.js new file mode 100644 index 00000000000..698bfce670d --- /dev/null +++ b/test/cases/parsing/harmony-export-import-specifier/weird-cjs.js @@ -0,0 +1,7 @@ +exports.__esModule = false; + +function dynamic(exports) { + exports.a = 1; +} + +dynamic(exports); diff --git a/test/cases/parsing/harmony-export-precedence/warnings.js b/test/cases/parsing/harmony-export-precedence/warnings.js index c57b3a2cce4..af730a435fd 100644 --- a/test/cases/parsing/harmony-export-precedence/warnings.js +++ b/test/cases/parsing/harmony-export-precedence/warnings.js @@ -1,3 +1,5 @@ module.exports = [ - [/export 'default' \(imported as 'defaultImport'\) was not found in '.\/a' \(possible exports: a, b, c, d, e, f\)/] + [ + /export 'default' \(imported as 'defaultImport'\) was not found in '.\/a' \(possible exports: a, b, c, d, e, f\)/ + ] ]; diff --git a/test/cases/parsing/harmony-export-specifier-asi/a.js b/test/cases/parsing/harmony-export-specifier-asi/a.js new file mode 100644 index 00000000000..9549e18a567 --- /dev/null +++ b/test/cases/parsing/harmony-export-specifier-asi/a.js @@ -0,0 +1,3 @@ +export const fn = (num) => { + return num; +}; diff --git a/test/cases/parsing/harmony-export-specifier-asi/index.js b/test/cases/parsing/harmony-export-specifier-asi/index.js new file mode 100644 index 00000000000..3bff5046362 --- /dev/null +++ b/test/cases/parsing/harmony-export-specifier-asi/index.js @@ -0,0 +1,11 @@ +import { fn } from './a.js'; + +const num = 1 + +export { num }; + +fn(num); + +it("should work", function() { + expect(fn(num)).toBe(1); +}); diff --git a/test/cases/parsing/harmony-reexport/a.js b/test/cases/parsing/harmony-reexport/a.js new file mode 100644 index 00000000000..9b794cf0f1a --- /dev/null +++ b/test/cases/parsing/harmony-reexport/a.js @@ -0,0 +1,11 @@ +import { b } from "./b"; + +export function a() { + return b(); +} +export const obj = {}; +export const aUsed = __webpack_exports_info__.a.used; +export const aProvided = __webpack_exports_info__.a.provideInfo; +export const objUsed = __webpack_exports_info__.obj.used; +export const objAProvided = __webpack_exports_info__.obj.A.provideInfo; +export const aToStringProvided = __webpack_exports_info__.a.toString.provideInfo; diff --git a/test/cases/parsing/harmony-reexport/b.js b/test/cases/parsing/harmony-reexport/b.js new file mode 100644 index 00000000000..7554fde97b5 --- /dev/null +++ b/test/cases/parsing/harmony-reexport/b.js @@ -0,0 +1 @@ +export function b() {} diff --git a/test/cases/parsing/harmony-reexport/empty.js b/test/cases/parsing/harmony-reexport/empty.js new file mode 100644 index 00000000000..e69de29bb2d diff --git a/test/cases/parsing/harmony-reexport/index.js b/test/cases/parsing/harmony-reexport/index.js new file mode 100644 index 00000000000..28837e5f54a --- /dev/null +++ b/test/cases/parsing/harmony-reexport/index.js @@ -0,0 +1,12 @@ +import { a, aUsed, aCanBeMangled, aProvided, aToStringProvided, obj, objUsed, objAProvided } from "./reexport"; + +if (a()) console.log("a", obj); + +it("should not allow mangle if some exports are unknown", () => { + expect(aUsed).toBe(true); + expect(aProvided).toBe(true); + expect(aCanBeMangled).toBe(false); + expect(objUsed).toBe(true); + expect(objAProvided).toBe(undefined); + expect(aToStringProvided).toBe(undefined); +}); diff --git a/test/cases/parsing/harmony-reexport/reexport.js b/test/cases/parsing/harmony-reexport/reexport.js new file mode 100644 index 00000000000..648d898edc8 --- /dev/null +++ b/test/cases/parsing/harmony-reexport/reexport.js @@ -0,0 +1,3 @@ +export * from "./a"; +export * from "./empty"; +export const aCanBeMangled = __webpack_exports_info__.a.canMangle; diff --git a/test/cases/parsing/harmony-star-conflict/index.js b/test/cases/parsing/harmony-star-conflict/index.js index 8363d6963c0..b3d2c53fb64 100644 --- a/test/cases/parsing/harmony-star-conflict/index.js +++ b/test/cases/parsing/harmony-star-conflict/index.js @@ -28,7 +28,7 @@ import { named6 as snamed6 } from "./named-with-namespace-no-side"; -it("should point out conflicts from named to namespace (without sideeffects)", () => { +it("should point out conflicts from named to namespace (without side effects)", () => { expect(snamed1).toBe(1); expect(snamed2).toBe(2); expect(snamed3).toBe(2); diff --git a/test/cases/parsing/hashbang/file.js b/test/cases/parsing/hashbang/file.js new file mode 100644 index 00000000000..2866673b1ee --- /dev/null +++ b/test/cases/parsing/hashbang/file.js @@ -0,0 +1,2 @@ +#!/usr/bin/env node +module.exports = "ok"; diff --git a/test/cases/parsing/hashbang/file.mjs b/test/cases/parsing/hashbang/file.mjs new file mode 100644 index 00000000000..97e357ad75e --- /dev/null +++ b/test/cases/parsing/hashbang/file.mjs @@ -0,0 +1,2 @@ +#!/usr/bin/env node +export default "ok"; diff --git a/test/cases/parsing/hashbang/index.js b/test/cases/parsing/hashbang/index.js new file mode 100644 index 00000000000..f4bb6745333 --- /dev/null +++ b/test/cases/parsing/hashbang/index.js @@ -0,0 +1,9 @@ +it("should load a file with hashbang", function () { + var result = require("./file.js"); + expect(result).toEqual("ok"); +}); + +import result from "./file.mjs"; +it("should load a module with hashbang", function () { + expect(result).toEqual("ok"); +}); diff --git a/test/cases/parsing/import-define/index.js b/test/cases/parsing/import-define/index.js index 4ac3fd353c7..10db43f27d5 100644 --- a/test/cases/parsing/import-define/index.js +++ b/test/cases/parsing/import-define/index.js @@ -6,7 +6,7 @@ it("should allow to import a variable named define (call)", () => { expect(define()).toBe("ok"); }); -it("should allow to import a variable named define (expresion)", () => { +it("should allow to import a variable named define (expression)", () => { const d = i(define); expect(d()).toBe("ok"); }); diff --git a/test/cases/parsing/issue-14610/index.js b/test/cases/parsing/issue-14610/index.js new file mode 100644 index 00000000000..bdbeb6fbdc2 --- /dev/null +++ b/test/cases/parsing/issue-14610/index.js @@ -0,0 +1,4 @@ +it("should keep parentheses when replacing", () => { + // prettier-ignore + expect(new (require("./module")).Thing(42).property).toBe(42) +}); diff --git a/test/cases/parsing/issue-14610/module.js b/test/cases/parsing/issue-14610/module.js new file mode 100644 index 00000000000..d532367112a --- /dev/null +++ b/test/cases/parsing/issue-14610/module.js @@ -0,0 +1,5 @@ +export class Thing { + constructor(p) { + this.property = p; + } +} diff --git a/test/cases/parsing/issue-16763/a.js b/test/cases/parsing/issue-16763/a.js new file mode 100644 index 00000000000..cc798ff50da --- /dev/null +++ b/test/cases/parsing/issue-16763/a.js @@ -0,0 +1 @@ +export const a = 1; diff --git a/test/cases/parsing/issue-16763/class.js b/test/cases/parsing/issue-16763/class.js new file mode 100644 index 00000000000..4f5ed245709 --- /dev/null +++ b/test/cases/parsing/issue-16763/class.js @@ -0,0 +1,82 @@ +import { a as C, a as B } from "./a.js"; + +let staticBlockValue; +let staticPrivateBlockValue; +let valueInStaticBlock; +let staticPrivateMethod; +let staticThis; + +let A = class C { + static name = "test"; + + otherName = C.name; + #privateName = C.name; + propertyB = B; + #propertyB = B; + + static otherName = C.name; + static #staticPrivateName = C.name; + static staticB = B; + static #staticB = B; + static #this = this; + static #thisAndC = C.#this; + + #privateMethod() { + return { privateName: this.#privateName, B } + } + publicMethod() { + const privateMethod = this.#privateMethod(); + + return { B, privateMethod, propertyB: this.propertyB, privatePropertyB: this.#propertyB } + } + test() { + return { className: C.name, propertyValue: this.otherName }; + } + static test() { + return C.name; + } + static getB() { + return B; + } + static #staticPrivateMethod() { + return { + staticB: this.staticB, + privateStaticB: this.#staticB, + B + }; + } + static { + staticBlockValue = C.name; + staticPrivateBlockValue = C.#staticPrivateName; + valueInStaticBlock = B; + staticPrivateMethod = C.#staticPrivateMethod(); + staticThis = C.#thisAndC; + } +}; + + +const b = function C() { + return C.name; +} + +const staticProperty = A.otherName; +const staticMethod = A.test(); +const staticB = A.getB(); +const method = new A().test(); +const publicMethod = new A().publicMethod(); +const reexport = C; +const functionName = b(); + +export { + staticBlockValue, + staticProperty, + staticMethod, + reexport, + method, + functionName, + publicMethod, + valueInStaticBlock, + staticB, + staticPrivateMethod, + staticThis +}; diff --git a/test/cases/parsing/issue-16763/index.js b/test/cases/parsing/issue-16763/index.js new file mode 100644 index 00000000000..1ca4c16d620 --- /dev/null +++ b/test/cases/parsing/issue-16763/index.js @@ -0,0 +1,22 @@ +import * as mod from "./class.js"; + +it('should correctly handle class methods and properties (include static)', () => { + expect(mod.staticBlockValue).toBe("test"); + expect(mod.staticProperty).toBe("test"); + expect(mod.staticMethod).toBe("test"); + expect(mod.reexport).toBe(1); + expect(mod.method.className).toBe("test"); + expect(mod.method.propertyValue).toBe("test"); + expect(typeof mod.functionName).toBe("string"); + expect(mod.publicMethod.B).toBe(1); + expect(mod.publicMethod.propertyB).toBe(1); + expect(mod.publicMethod.privatePropertyB).toBe(1); + expect(mod.publicMethod.privateMethod.privateName).toBe("test"); + expect(mod.publicMethod.privateMethod.B).toBe(1); + expect(mod.valueInStaticBlock).toBe(1); + expect(mod.staticB).toBe(1); + expect(mod.staticPrivateMethod.B).toBe(1); + expect(mod.staticPrivateMethod.staticB).toBe(1); + expect(mod.staticPrivateMethod.privateStaticB).toBe(1); + expect(mod.staticThis.name).toBe("test"); +}); diff --git a/test/cases/parsing/issue-16763/test.filter.js b/test/cases/parsing/issue-16763/test.filter.js new file mode 100644 index 00000000000..4df515a5d8b --- /dev/null +++ b/test/cases/parsing/issue-16763/test.filter.js @@ -0,0 +1,5 @@ +var supportsClassStaticBlock = require("../../../helpers/supportsClassStaticBlock"); + +module.exports = function (config) { + return supportsClassStaticBlock(); +}; diff --git a/test/cases/parsing/issue-17189/index.js b/test/cases/parsing/issue-17189/index.js new file mode 100644 index 00000000000..15775cc183a --- /dev/null +++ b/test/cases/parsing/issue-17189/index.js @@ -0,0 +1,15 @@ +import module from "./module.js"; + +it("should parse sparse arrays", function() { + var { + a, + ...other1 + } = module; + var { + b, + ...other2 + } = module; + + expect(other1).toEqual({ b: 2, c: 3 }); + expect(other2).toEqual({ a: 1, c: 3 }); +}); diff --git a/test/cases/parsing/issue-17189/module.js b/test/cases/parsing/issue-17189/module.js new file mode 100644 index 00000000000..5831362066a --- /dev/null +++ b/test/cases/parsing/issue-17189/module.js @@ -0,0 +1,6 @@ +var test = { + a: 1, + b: 2, + c: 3 +}; +export default test; diff --git a/test/cases/parsing/issue-2006/errors.js b/test/cases/parsing/issue-2006/errors.js index 7936b2e9d73..2b82b710bf3 100644 --- a/test/cases/parsing/issue-2006/errors.js +++ b/test/cases/parsing/issue-2006/errors.js @@ -1,3 +1 @@ -module.exports = [ - [/Empty dependency/] -]; \ No newline at end of file +module.exports = [[/Empty dependency/]]; diff --git a/test/cases/parsing/issue-2600/errors.js b/test/cases/parsing/issue-2600/errors.js index 8894d7a69d5..9cd234c7331 100644 --- a/test/cases/parsing/issue-2600/errors.js +++ b/test/cases/parsing/issue-2600/errors.js @@ -1,3 +1 @@ -module.exports = [ - [/Can't resolve 'missing'/] -]; \ No newline at end of file +module.exports = [[/Can't resolve 'missing'/]]; diff --git a/test/cases/parsing/issue-2641/errors.js b/test/cases/parsing/issue-2641/errors.js index 01d80f2952d..4c8eabefcdb 100644 --- a/test/cases/parsing/issue-2641/errors.js +++ b/test/cases/parsing/issue-2641/errors.js @@ -1,3 +1 @@ -module.exports = [ - [/Module not found/, /Can't resolve '\.\/missingModule' /] -]; +module.exports = [[/Module not found/, /Can't resolve '\.\/missingModule' /]]; diff --git a/test/cases/parsing/issue-4608-1-non-strict/index.js b/test/cases/parsing/issue-4608-1-non-strict/index.js new file mode 100644 index 00000000000..8ccf3291498 --- /dev/null +++ b/test/cases/parsing/issue-4608-1-non-strict/index.js @@ -0,0 +1,31 @@ +it("should find var declaration in control statements", function () { + var f = function (x) { + expect(x).toBe("fail"); + }; + + (function () { + with ({ a: 1 }) { + var require = f; + } + + require("fail"); + })(); +}); + +it("should find var declaration in control statements after usage", function () { + var f = function (x) { + expect(x).toBe("fail"); + }; + + (function () { + var test = function () { + require("fail"); + }; + + with ({ a: 1 }) { + var require = f; + } + + test(); + })(); +}); diff --git a/test/cases/parsing/issue-4608-1-non-strict/test.filter.js b/test/cases/parsing/issue-4608-1-non-strict/test.filter.js new file mode 100644 index 00000000000..d957820f37a --- /dev/null +++ b/test/cases/parsing/issue-4608-1-non-strict/test.filter.js @@ -0,0 +1,3 @@ +module.exports = function (config) { + return !config.module; +}; diff --git a/test/cases/parsing/issue-4608-1/index.js b/test/cases/parsing/issue-4608-1/index.js index 760ccdba7ce..181f01499a7 100644 --- a/test/cases/parsing/issue-4608-1/index.js +++ b/test/cases/parsing/issue-4608-1/index.js @@ -1,149 +1,142 @@ -it("should find var declaration later in code", function() { - expect((typeof require)).toBe("undefined"); +it("should find var declaration later in code", function () { + expect(typeof require).toBe("undefined"); var require; }); -it("should find var declaration in same statement", function() { - var fn = (function() { - require("fail"); - }), require; +it("should find var declaration in same statement", function () { + var fn = function () { + require("fail"); + }, + require; - require = (function(x) { + require = function (x) { expect(x).toBe("fail"); - }); + }; fn(); }); -it("should find a catch block declaration", function() { +it("should find a catch block declaration", function () { try { - var f = (function(x) { + var f = function (x) { expect(x).toBe("fail"); - }); + }; throw f; - } catch(require) { + } catch (require) { require("fail"); } }); -it("should find var declaration in control statements", function() { - var f = (function(x) { +it("should find var declaration in control statements", function () { + var f = function (x) { expect(x).toBe("fail"); - }); + }; - (function() { + (function () { { var require = f; } require("fail"); - }()); + })(); - (function() { + (function () { var i = 1; - while(i--) { + while (i--) { var require = f; } require("fail"); - }()); + })(); - (function() { + (function () { do { var require = f; - } while(false); - - require("fail"); - }()); - - (function() { - for(var i = 0; i < 1; i++) { - var require = f; - } + } while (false); require("fail"); - }()); + })(); - (function() { - for(var i in {a:1}) { + (function () { + for (var i = 0; i < 1; i++) { var require = f; } require("fail"); - }()); + })(); - (function() { - with({ a: 1 }) { + (function () { + for (var i in { a: 1 }) { var require = f; } require("fail"); - }()); + })(); }); -it("should find var declaration in control statements after usage", function() { - var f = (function(x) { +it("should find var declaration in control statements after usage", function () { + var f = function (x) { expect(x).toBe("fail"); - }); + }; - (function() { - var test = (function() { require("fail"); }); + (function () { + var test = function () { + require("fail"); + }; { var require = f; } test(); - }()); + })(); - (function() { - var test = (function() { require("fail"); }); + (function () { + var test = function () { + require("fail"); + }; var i = 1; - while(i--) { + while (i--) { var require = f; } test(); - }()); + })(); - (function() { - var test = (function() { require("fail"); }); + (function () { + var test = function () { + require("fail"); + }; do { var require = f; - } while(false); - - test(); - }()); - - (function() { - var test = (function() { require("fail"); }); - - for(var i = 0; i < 1; i++) { - var require = f; - } + } while (false); test(); - }()); + })(); - (function() { - var test = (function() { require("fail"); }); + (function () { + var test = function () { + require("fail"); + }; - for(var i in {a:1}) { + for (var i = 0; i < 1; i++) { var require = f; } test(); - }()); + })(); - (function() { - var test = (function() { require("fail"); }); + (function () { + var test = function () { + require("fail"); + }; - with({ a: 1 }) { + for (var i in { a: 1 }) { var require = f; } test(); - }()); + })(); }); diff --git a/test/cases/parsing/issue-627/warnings.js b/test/cases/parsing/issue-627/warnings.js index ea6102af436..f1a4bb46d11 100644 --- a/test/cases/parsing/issue-627/warnings.js +++ b/test/cases/parsing/issue-627/warnings.js @@ -1,3 +1 @@ -module.exports = [ - [/Critical dependency/] -]; +module.exports = [[/Critical dependency/]]; diff --git a/test/cases/parsing/issue-7519/a.js b/test/cases/parsing/issue-7519/a.js new file mode 100644 index 00000000000..3df259fa7ba --- /dev/null +++ b/test/cases/parsing/issue-7519/a.js @@ -0,0 +1,20 @@ +export let count = 1; + +export function inc() { + count++; +} + +export function incTruthy() { + count++; + return true; +} + +export function mult(n) { + count *= n; +} + +export function setCount(c) { + count = c; +} + +export const multUsed = __webpack_exports_info__.mult.used; diff --git a/test/cases/parsing/issue-7519/index.js b/test/cases/parsing/issue-7519/index.js new file mode 100644 index 00000000000..2c25bebe550 --- /dev/null +++ b/test/cases/parsing/issue-7519/index.js @@ -0,0 +1,38 @@ +import { + count, + mult, + inc, + incTruthy, + setCount, + multUsed, + incUsed +} from "./a"; + +it("logical 'and' should work", () => { + setCount(1); + inc() && "true" && 0 && mult(2); + expect(count).toBe(2); + inc() && false && mult(2); + expect(count).toBe(3); + true && inc() && inc() && false && mult(2); + /* inc itself returns undefined */ + expect(count).toBe(4); + true && incTruthy() && incTruthy() && false && mult(2); + expect(count).toBe(6); +}); + +it("logical 'or' should work", () => { + setCount(1); + false || "" || inc(); + expect(count).toBe(2); + (0 || "" || inc() || inc()) && false && mult(2); + expect(count).toBe(4); +}); + +it("mult should not be used", () => { + if (inc() && true && false) { + mult(2); + } + + expect(multUsed).toBe(false); +}); diff --git a/test/cases/parsing/issue-7519/test.filter.js b/test/cases/parsing/issue-7519/test.filter.js new file mode 100644 index 00000000000..49ac5066bb8 --- /dev/null +++ b/test/cases/parsing/issue-7519/test.filter.js @@ -0,0 +1,3 @@ +module.exports = function (config) { + return config.mode !== "development"; +}; diff --git a/test/cases/parsing/issue-758/errors.js b/test/cases/parsing/issue-758/errors.js index 01d80f2952d..4c8eabefcdb 100644 --- a/test/cases/parsing/issue-758/errors.js +++ b/test/cases/parsing/issue-758/errors.js @@ -1,3 +1 @@ -module.exports = [ - [/Module not found/, /Can't resolve '\.\/missingModule' /] -]; +module.exports = [[/Module not found/, /Can't resolve '\.\/missingModule' /]]; diff --git a/test/cases/parsing/logical-assignment/test.filter.js b/test/cases/parsing/logical-assignment/test.filter.js index cecf771eddb..52cd61a8efe 100644 --- a/test/cases/parsing/logical-assignment/test.filter.js +++ b/test/cases/parsing/logical-assignment/test.filter.js @@ -1,5 +1,5 @@ var supportsLogicalAssignment = require("../../../helpers/supportsLogicalAssignment"); -module.exports = function(config) { +module.exports = function (config) { return supportsLogicalAssignment(); }; diff --git a/test/cases/parsing/optional-catch-binding/test.filter.js b/test/cases/parsing/optional-catch-binding/test.filter.js index a09b8642687..5e7d911be6e 100644 --- a/test/cases/parsing/optional-catch-binding/test.filter.js +++ b/test/cases/parsing/optional-catch-binding/test.filter.js @@ -1,6 +1,6 @@ const supportsOptionalCatchBinding = require("../../../helpers/supportsOptionalCatchBinding"); -module.exports = function(config) { +module.exports = function (config) { // XXX: Disable this test if Terser is used because it does not support ES 2019 if (config.mode === "production") { return false; diff --git a/test/cases/parsing/optional-chaining/b.js b/test/cases/parsing/optional-chaining/b.js new file mode 100644 index 00000000000..5fe49d553b2 --- /dev/null +++ b/test/cases/parsing/optional-chaining/b.js @@ -0,0 +1,3 @@ +export default {}; +export * as a from "./c"; +export const call = () => ({ c: 1 }); diff --git a/test/cases/parsing/optional-chaining/c.js b/test/cases/parsing/optional-chaining/c.js new file mode 100644 index 00000000000..c37f7387e3e --- /dev/null +++ b/test/cases/parsing/optional-chaining/c.js @@ -0,0 +1,2 @@ +const call = () => 2; +export { call }; diff --git a/test/cases/parsing/optional-chaining/index.js b/test/cases/parsing/optional-chaining/index.js index cff0a3dbb5b..0d48ae94dd1 100644 --- a/test/cases/parsing/optional-chaining/index.js +++ b/test/cases/parsing/optional-chaining/index.js @@ -1,3 +1,15 @@ +import b, * as bb from "./b"; + +it("should keep optional chaining", () => { + expect(b?.a?.a).toBe(undefined); + expect(b?.a).toBe(undefined); + expect(typeof bb?.a).toBe("object"); + expect(bb.call?.().c).toBe(1); + expect(bb.call?.().b?.a).toBe(undefined); + expect(bb.a?.call()).toBe(2); + expect(bb.a?.c?.b).toBe(undefined); +}); + it("should evaluate optional members", () => { if (!module.hot) { expect( diff --git a/test/cases/parsing/precreated-ast/ast-loader.js b/test/cases/parsing/precreated-ast/ast-loader.js index 6293e064441..e150377260e 100644 --- a/test/cases/parsing/precreated-ast/ast-loader.js +++ b/test/cases/parsing/precreated-ast/ast-loader.js @@ -3,7 +3,8 @@ const acorn = require("acorn"); const acornParser = acorn.Parser; -module.exports = function(source) { +/** @type {import("../../../../").LoaderDefinition} */ +module.exports = function (source) { const comments = []; const ast = acornParser.parse(source, { @@ -15,9 +16,12 @@ module.exports = function(source) { }); // change something to test if it's really used + //@ts-ignore ast.body[0].expression.right.arguments[0].value = "./ok"; - ast.body[0].expression.right.arguments[0].raw = "\"./ok\""; + //@ts-ignore + ast.body[0].expression.right.arguments[0].raw = '"./ok"'; + //@ts-ignore ast.comments = comments; this.callback(null, source, null, { webpackAST: ast diff --git a/test/cases/parsing/sequence-expression-asi/a.js b/test/cases/parsing/sequence-expression-asi/a.js new file mode 100644 index 00000000000..9549e18a567 --- /dev/null +++ b/test/cases/parsing/sequence-expression-asi/a.js @@ -0,0 +1,3 @@ +export const fn = (num) => { + return num; +}; diff --git a/test/cases/parsing/sequence-expression-asi/index.js b/test/cases/parsing/sequence-expression-asi/index.js new file mode 100644 index 00000000000..540ac012c81 --- /dev/null +++ b/test/cases/parsing/sequence-expression-asi/index.js @@ -0,0 +1,21 @@ +import { fn } from "./a" + +function d() {} + +var num = 1 +d(), fn(); + +export const b = 2 +d(), fn(); + +export default (function Foo() {}) +d(), fn(); + +export const c = 3 +function foo() { + d(), fn(); +} + +it("should work", function() { + expect(fn(num)).toBe(1); +}); diff --git a/test/cases/parsing/spread/test.filter.js b/test/cases/parsing/spread/test.filter.js index 741b76b8c15..dff5bad7782 100644 --- a/test/cases/parsing/spread/test.filter.js +++ b/test/cases/parsing/spread/test.filter.js @@ -1,5 +1,5 @@ var supportsSpread = require("../../../helpers/supportsSpread"); -module.exports = function(config) { +module.exports = function (config) { return supportsSpread(); }; diff --git a/test/cases/parsing/typeof-non-module/index.js b/test/cases/parsing/typeof-non-module/index.js new file mode 100644 index 00000000000..10a88cf80b7 --- /dev/null +++ b/test/cases/parsing/typeof-non-module/index.js @@ -0,0 +1,9 @@ +it("should answer typeof __non_webpack_require__ correctly", function () { + var oldValue; + eval("oldValue = require;"); + expect(typeof __non_webpack_require__).toBe("function"); + eval("require = undefined;"); + expect(typeof __non_webpack_require__).toBe("undefined"); + eval("require = oldValue;"); + expect(typeof __non_webpack_require__).toBe("function"); +}); diff --git a/test/cases/parsing/typeof-non-module/test.filter.js b/test/cases/parsing/typeof-non-module/test.filter.js new file mode 100644 index 00000000000..d957820f37a --- /dev/null +++ b/test/cases/parsing/typeof-non-module/test.filter.js @@ -0,0 +1,3 @@ +module.exports = function (config) { + return !config.module; +}; diff --git a/test/cases/parsing/typeof/index.js b/test/cases/parsing/typeof/index.js index 4ed20de3525..0e3fbbb0b97 100644 --- a/test/cases/parsing/typeof/index.js +++ b/test/cases/parsing/typeof/index.js @@ -1,56 +1,48 @@ -it("should not create a context for typeof require", function() { +it("should not create a context for typeof require", function () { expect(require("./typeof")).toBe("function"); }); -it("should answer typeof require correctly", function() { - expect((typeof require)).toBe("function"); +it("should answer typeof require correctly", function () { + expect(typeof require).toBe("function"); }); -it("should answer typeof define correctly", function() { - expect((typeof define)).toBe("function"); +it("should answer typeof define correctly", function () { + expect(typeof define).toBe("function"); }); -it("should answer typeof require.amd correctly", function() { - expect((typeof require.amd)).toBe("object"); +it("should answer typeof require.amd correctly", function () { + expect(typeof require.amd).toBe("object"); }); -it("should answer typeof define.amd correctly", function() { - expect((typeof define.amd)).toBe("object"); +it("should answer typeof define.amd correctly", function () { + expect(typeof define.amd).toBe("object"); }); -it("should answer typeof module correctly", function() { - expect((typeof module)).toBe("object"); +it("should answer typeof module correctly", function () { + expect(typeof module).toBe("object"); }); -it("should answer typeof exports correctly", function() { - expect((typeof exports)).toBe("object"); +it("should answer typeof exports correctly", function () { + expect(typeof exports).toBe("object"); }); -it("should answer typeof require.include correctly", function() { - expect((typeof require.include)).toBe("function"); +it("should answer typeof require.include correctly", function () { + expect(typeof require.include).toBe("function"); }); -it("should answer typeof require.ensure correctly", function() { - expect((typeof require.ensure)).toBe("function"); +it("should answer typeof require.ensure correctly", function () { + expect(typeof require.ensure).toBe("function"); }); -it("should answer typeof require.resolve correctly", function() { - expect((typeof require.resolve)).toBe("function"); -}); -it("should answer typeof __non_webpack_require__ correctly", function() { - var oldValue; - eval("oldValue = require;"); - expect((typeof __non_webpack_require__)).toBe("function"); - eval("require = undefined;"); - expect((typeof __non_webpack_require__)).toBe("undefined"); - eval("require = oldValue;"); - expect((typeof __non_webpack_require__)).toBe("function"); +it("should answer typeof require.resolve correctly", function () { + expect(typeof require.resolve).toBe("function"); }); -it("should not parse filtered stuff", function() { - if(typeof require != "function") require("fail"); - if(typeof require !== "function") require("fail"); - if(!(typeof require == "function")) require("fail"); - if(!(typeof require === "function")) require("fail"); - if(typeof require == "undefined") require = require("fail"); - if(typeof require === "undefined") require = require("fail"); - if(typeof require.resolve !== "function") require("fail"); - if(typeof module == "undefined") module = require("fail"); - if(typeof module === "undefined") module = require("fail"); - if(typeof module != "object") module = require("fail"); - if(typeof exports == "undefined") exports = require("fail"); - if(typeof require.include !== "function") require.include("fail"); - if(typeof require.ensure !== "function") require.ensure(["fail"], function(){}); +it("should not parse filtered stuff", function () { + if (typeof require != "function") require("fail"); + if (typeof require !== "function") require("fail"); + if (!(typeof require == "function")) require("fail"); + if (!(typeof require === "function")) require("fail"); + if (typeof require == "undefined") require = require("fail"); + if (typeof require === "undefined") require = require("fail"); + if (typeof require.resolve !== "function") require("fail"); + if (typeof module == "undefined") module = require("fail"); + if (typeof module === "undefined") module = require("fail"); + if (typeof module != "object") module = require("fail"); + if (typeof exports == "undefined") exports = require("fail"); + if (typeof require.include !== "function") require.include("fail"); + if (typeof require.ensure !== "function") + require.ensure(["fail"], function () {}); }); diff --git a/test/cases/resolving/browser-field/errors.js b/test/cases/resolving/browser-field/errors.js index 4b56bd34420..43f6c3086fc 100644 --- a/test/cases/resolving/browser-field/errors.js +++ b/test/cases/resolving/browser-field/errors.js @@ -3,4 +3,4 @@ module.exports = [ [/Module not found/, /recursive-file\/b/, /Recursion in resolving/], [/Module not found/, /recursive-file\/c/, /Recursion in resolving/], [/Module not found/, /recursive-file\/d/, /Recursion in resolving/] -]; \ No newline at end of file +]; diff --git a/test/cases/resolving/context/loaders/queryloader.js b/test/cases/resolving/context/loaders/queryloader.js index 8d606f560f8..f9bb23e1f55 100644 --- a/test/cases/resolving/context/loaders/queryloader.js +++ b/test/cases/resolving/context/loaders/queryloader.js @@ -1,7 +1,11 @@ -module.exports = function(content) { - return "module.exports = " + JSON.stringify({ - resourceQuery: this.resourceQuery, - query: this.query, - prev: content - }); -} +/** @type {import("../../../../../").LoaderDefinition} */ +module.exports = function (content) { + return ( + "module.exports = " + + JSON.stringify({ + resourceQuery: this.resourceQuery, + query: this.query, + prev: content + }) + ); +}; diff --git a/test/cases/runtime/error-handling/errors.js b/test/cases/runtime/error-handling/errors.js index d3f6fa22daf..0332131095e 100644 --- a/test/cases/runtime/error-handling/errors.js +++ b/test/cases/runtime/error-handling/errors.js @@ -1,3 +1,7 @@ module.exports = [ - [/Module not found/, /Can't resolve '\.\/missingModule' /, {moduleName: /error-handling\/index.js/}] + [ + /Module not found/, + /Can't resolve '\.\/missingModule' /, + { moduleName: /error-handling\/index.js/ } + ] ]; diff --git a/test/cases/runtime/error-handling/warnings.js b/test/cases/runtime/error-handling/warnings.js index c9f21009797..c005d4830f8 100644 --- a/test/cases/runtime/error-handling/warnings.js +++ b/test/cases/runtime/error-handling/warnings.js @@ -1,3 +1,7 @@ module.exports = [ - [/Module not found/, /Can't resolve '\.\/missingModule2' /, {moduleName: /error-handling\/index.js/}] + [ + /Module not found/, + /Can't resolve '\.\/missingModule2' /, + { moduleName: /error-handling\/index.js/ } + ] ]; diff --git a/test/cases/runtime/issue-15518/dynamic_a/module_a1.js b/test/cases/runtime/issue-15518/dynamic_a/module_a1.js new file mode 100644 index 00000000000..bb015c33f2f --- /dev/null +++ b/test/cases/runtime/issue-15518/dynamic_a/module_a1.js @@ -0,0 +1 @@ +export const log = 1; diff --git a/test/cases/runtime/issue-15518/dynamic_a/module_a2.js b/test/cases/runtime/issue-15518/dynamic_a/module_a2.js new file mode 100644 index 00000000000..e69de29bb2d diff --git a/test/cases/runtime/issue-15518/index.js b/test/cases/runtime/issue-15518/index.js new file mode 100644 index 00000000000..6eb4b80c0ba --- /dev/null +++ b/test/cases/runtime/issue-15518/index.js @@ -0,0 +1,13 @@ +async function dynamic_import(dir, name) { + if (dir === "a") { + return import( + /* webpackChunkName: "a" */ + /* webpackMode: "lazy-once" */ + `./dynamic_a/${name}.js`); + } + throw new Error(); +} + +it("should compile and run", async () => { + await dynamic_import("a", "module_a1"); +}); diff --git a/test/cases/runtime/missing-module-exception-dynamic-import/index.js b/test/cases/runtime/missing-module-exception-dynamic-import/index.js new file mode 100644 index 00000000000..8ed1ed4676d --- /dev/null +++ b/test/cases/runtime/missing-module-exception-dynamic-import/index.js @@ -0,0 +1,9 @@ +it("should have correct error code", async function () { + try { + await import("./fail-1"); + await import("./fail-2").property; + await import("./fail-3").property.sub(); + } catch (e) { + expect(e.code).toBe("MODULE_NOT_FOUND"); + } +}); diff --git a/test/cases/runtime/missing-module-exception/warnings.js b/test/cases/runtime/missing-module-exception-dynamic-import/warnings.js similarity index 100% rename from test/cases/runtime/missing-module-exception/warnings.js rename to test/cases/runtime/missing-module-exception-dynamic-import/warnings.js diff --git a/test/cases/runtime/missing-module-exception/index.js b/test/cases/runtime/missing-module-exception-require/index.js similarity index 100% rename from test/cases/runtime/missing-module-exception/index.js rename to test/cases/runtime/missing-module-exception-require/index.js diff --git a/test/cases/runtime/missing-module-exception-require/warnings.js b/test/cases/runtime/missing-module-exception-require/warnings.js new file mode 100644 index 00000000000..f0cafe0c42f --- /dev/null +++ b/test/cases/runtime/missing-module-exception-require/warnings.js @@ -0,0 +1,5 @@ +module.exports = [ + [/Module not found/, /Can't resolve '\.\/fail-1' /], + [/Module not found/, /Can't resolve '\.\/fail-2' /], + [/Module not found/, /Can't resolve '\.\/fail-3' /] +]; diff --git a/test/cases/runtime/missing-module-syntax-error/errors.js b/test/cases/runtime/missing-module-syntax-error/errors.js index 4ce4a4dd952..ced71bb9976 100644 --- a/test/cases/runtime/missing-module-syntax-error/errors.js +++ b/test/cases/runtime/missing-module-syntax-error/errors.js @@ -1,3 +1 @@ -module.exports = [ - [/Module not found/, /Can't resolve '\.\/someModule' /], -]; +module.exports = [[/Module not found/, /Can't resolve '\.\/someModule' /]]; diff --git a/test/cases/scope-hoisting/renaming-shorthand-5027/test.filter.js b/test/cases/scope-hoisting/renaming-shorthand-5027/test.filter.js index ccd1717d158..810114c1d73 100644 --- a/test/cases/scope-hoisting/renaming-shorthand-5027/test.filter.js +++ b/test/cases/scope-hoisting/renaming-shorthand-5027/test.filter.js @@ -3,10 +3,12 @@ var supportDefaultAssignment = require("../../../helpers/supportDefaultAssignmen var supportsObjectDestructuring = require("../../../helpers/supportsObjectDestructuring"); var supportsIteratorDestructuring = require("../../../helpers/supportsIteratorDestructuring"); -module.exports = function(config) { - return !config.minimize && +module.exports = function (config) { + return ( + !config.minimize && supportsES6() && supportDefaultAssignment() && supportsObjectDestructuring() && - supportsIteratorDestructuring(); + supportsIteratorDestructuring() + ); }; diff --git a/test/cases/side-effects/order-issue-7665/index.js b/test/cases/side-effects/order-issue-7665/index.js index 378de0e896e..85e9d3df58a 100644 --- a/test/cases/side-effects/order-issue-7665/index.js +++ b/test/cases/side-effects/order-issue-7665/index.js @@ -1,7 +1,7 @@ import array from "./tracker"; import { b } from "./module"; -it("should evaulate modules in the correct order", () => { +it("should evaluate modules in the correct order", () => { expect(b).toEqual("b"); expect(array).toEqual(["b", "a"]); }) diff --git a/test/cases/wasm/decoding/test.filter.js b/test/cases/wasm/decoding/test.filter.js index 23177349638..bd7f4573a77 100644 --- a/test/cases/wasm/decoding/test.filter.js +++ b/test/cases/wasm/decoding/test.filter.js @@ -1,5 +1,5 @@ var supportsWebAssembly = require("../../../helpers/supportsWebAssembly"); -module.exports = function(config) { +module.exports = function (config) { return supportsWebAssembly(); }; diff --git a/test/cases/wasm/export-imported-global/test.filter.js b/test/cases/wasm/export-imported-global/test.filter.js index 23177349638..bd7f4573a77 100644 --- a/test/cases/wasm/export-imported-global/test.filter.js +++ b/test/cases/wasm/export-imported-global/test.filter.js @@ -1,5 +1,5 @@ var supportsWebAssembly = require("../../../helpers/supportsWebAssembly"); -module.exports = function(config) { +module.exports = function (config) { return supportsWebAssembly(); }; diff --git a/test/cases/wasm/finalize-exports-issue-8261/test.filter.js b/test/cases/wasm/finalize-exports-issue-8261/test.filter.js index 23177349638..bd7f4573a77 100644 --- a/test/cases/wasm/finalize-exports-issue-8261/test.filter.js +++ b/test/cases/wasm/finalize-exports-issue-8261/test.filter.js @@ -1,5 +1,5 @@ var supportsWebAssembly = require("../../../helpers/supportsWebAssembly"); -module.exports = function(config) { +module.exports = function (config) { return supportsWebAssembly(); }; diff --git a/test/cases/wasm/global-refs-imported-global/test.filter.js b/test/cases/wasm/global-refs-imported-global/test.filter.js index 23177349638..bd7f4573a77 100644 --- a/test/cases/wasm/global-refs-imported-global/test.filter.js +++ b/test/cases/wasm/global-refs-imported-global/test.filter.js @@ -1,5 +1,5 @@ var supportsWebAssembly = require("../../../helpers/supportsWebAssembly"); -module.exports = function(config) { +module.exports = function (config) { return supportsWebAssembly(); }; diff --git a/test/cases/wasm/import-wasm-wasm/test.filter.js b/test/cases/wasm/import-wasm-wasm/test.filter.js index 23177349638..bd7f4573a77 100644 --- a/test/cases/wasm/import-wasm-wasm/test.filter.js +++ b/test/cases/wasm/import-wasm-wasm/test.filter.js @@ -1,5 +1,5 @@ var supportsWebAssembly = require("../../../helpers/supportsWebAssembly"); -module.exports = function(config) { +module.exports = function (config) { return supportsWebAssembly(); }; diff --git a/test/cases/wasm/imported-global-preserve-ordering/test.filter.js b/test/cases/wasm/imported-global-preserve-ordering/test.filter.js index 23177349638..bd7f4573a77 100644 --- a/test/cases/wasm/imported-global-preserve-ordering/test.filter.js +++ b/test/cases/wasm/imported-global-preserve-ordering/test.filter.js @@ -1,5 +1,5 @@ var supportsWebAssembly = require("../../../helpers/supportsWebAssembly"); -module.exports = function(config) { +module.exports = function (config) { return supportsWebAssembly(); }; diff --git a/test/cases/wasm/imported-global-preserve-type/test.filter.js b/test/cases/wasm/imported-global-preserve-type/test.filter.js index 23177349638..bd7f4573a77 100644 --- a/test/cases/wasm/imported-global-preserve-type/test.filter.js +++ b/test/cases/wasm/imported-global-preserve-type/test.filter.js @@ -1,5 +1,5 @@ var supportsWebAssembly = require("../../../helpers/supportsWebAssembly"); -module.exports = function(config) { +module.exports = function (config) { return supportsWebAssembly(); }; diff --git a/test/cases/wasm/imports-circular/test.filter.js b/test/cases/wasm/imports-circular/test.filter.js index 23177349638..bd7f4573a77 100644 --- a/test/cases/wasm/imports-circular/test.filter.js +++ b/test/cases/wasm/imports-circular/test.filter.js @@ -1,5 +1,5 @@ var supportsWebAssembly = require("../../../helpers/supportsWebAssembly"); -module.exports = function(config) { +module.exports = function (config) { return supportsWebAssembly(); }; diff --git a/test/cases/wasm/imports-complex-types/index.js b/test/cases/wasm/imports-complex-types/index.js index c2e0b23fead..3d2b113b93f 100644 --- a/test/cases/wasm/imports-complex-types/index.js +++ b/test/cases/wasm/imports-complex-types/index.js @@ -1,6 +1,6 @@ it("should allow to run a WebAssembly module with non-js-compatible imports", function() { return import("./wasm.wasm").then(function(wasm) { - const result = wasm.testI64(); + const result = wasm.testV128(); expect(result).toEqual(42); }); }); diff --git a/test/cases/wasm/imports-complex-types/other.wasm b/test/cases/wasm/imports-complex-types/other.wasm index 70c5aee0fa3..6949d18dd24 100644 Binary files a/test/cases/wasm/imports-complex-types/other.wasm and b/test/cases/wasm/imports-complex-types/other.wasm differ diff --git a/test/cases/wasm/imports-complex-types/test.filter.js b/test/cases/wasm/imports-complex-types/test.filter.js index 23177349638..d8ad45ba057 100644 --- a/test/cases/wasm/imports-complex-types/test.filter.js +++ b/test/cases/wasm/imports-complex-types/test.filter.js @@ -1,5 +1,5 @@ -var supportsWebAssembly = require("../../../helpers/supportsWebAssembly"); +const supports = require("webassembly-feature"); -module.exports = function(config) { - return supportsWebAssembly(); +module.exports = function (config) { + return supports.simd(); }; diff --git a/test/cases/wasm/imports-complex-types/wasm.wasm b/test/cases/wasm/imports-complex-types/wasm.wasm index 8374df1439f..a94d0954e7b 100644 Binary files a/test/cases/wasm/imports-complex-types/wasm.wasm and b/test/cases/wasm/imports-complex-types/wasm.wasm differ diff --git a/test/cases/wasm/imports-many-direct/test.filter.js b/test/cases/wasm/imports-many-direct/test.filter.js index 23177349638..bd7f4573a77 100644 --- a/test/cases/wasm/imports-many-direct/test.filter.js +++ b/test/cases/wasm/imports-many-direct/test.filter.js @@ -1,5 +1,5 @@ var supportsWebAssembly = require("../../../helpers/supportsWebAssembly"); -module.exports = function(config) { +module.exports = function (config) { return supportsWebAssembly(); }; diff --git a/test/cases/wasm/imports-multiple/test.filter.js b/test/cases/wasm/imports-multiple/test.filter.js index 23177349638..bd7f4573a77 100644 --- a/test/cases/wasm/imports-multiple/test.filter.js +++ b/test/cases/wasm/imports-multiple/test.filter.js @@ -1,5 +1,5 @@ var supportsWebAssembly = require("../../../helpers/supportsWebAssembly"); -module.exports = function(config) { +module.exports = function (config) { return supportsWebAssembly(); }; diff --git a/test/cases/wasm/imports/test.filter.js b/test/cases/wasm/imports/test.filter.js index 23177349638..bd7f4573a77 100644 --- a/test/cases/wasm/imports/test.filter.js +++ b/test/cases/wasm/imports/test.filter.js @@ -1,5 +1,5 @@ var supportsWebAssembly = require("../../../helpers/supportsWebAssembly"); -module.exports = function(config) { +module.exports = function (config) { return supportsWebAssembly(); }; diff --git a/test/cases/wasm/memory/test.filter.js b/test/cases/wasm/memory/test.filter.js index 23177349638..bd7f4573a77 100644 --- a/test/cases/wasm/memory/test.filter.js +++ b/test/cases/wasm/memory/test.filter.js @@ -1,5 +1,5 @@ var supportsWebAssembly = require("../../../helpers/supportsWebAssembly"); -module.exports = function(config) { +module.exports = function (config) { return supportsWebAssembly(); }; diff --git a/test/cases/wasm/order/test.filter.js b/test/cases/wasm/order/test.filter.js index 23177349638..bd7f4573a77 100644 --- a/test/cases/wasm/order/test.filter.js +++ b/test/cases/wasm/order/test.filter.js @@ -1,5 +1,5 @@ var supportsWebAssembly = require("../../../helpers/supportsWebAssembly"); -module.exports = function(config) { +module.exports = function (config) { return supportsWebAssembly(); }; diff --git a/test/cases/wasm/simple/test.filter.js b/test/cases/wasm/simple/test.filter.js index 23177349638..bd7f4573a77 100644 --- a/test/cases/wasm/simple/test.filter.js +++ b/test/cases/wasm/simple/test.filter.js @@ -1,5 +1,5 @@ var supportsWebAssembly = require("../../../helpers/supportsWebAssembly"); -module.exports = function(config) { +module.exports = function (config) { return supportsWebAssembly(); }; diff --git a/test/cases/wasm/table/index.js b/test/cases/wasm/table/index.js index 4d3d85a3b5b..9f77a985056 100644 --- a/test/cases/wasm/table/index.js +++ b/test/cases/wasm/table/index.js @@ -1,16 +1,16 @@ // the message is inconsistency between some nodejs versions -const UNKNOWN_FUNCTION_TABLE = /invalid index into function table|invalid function/; +const UNKNOWN_FUNCTION_TABLE = /table index is out of bounds|invalid index into function table|invalid function/; -it("should support tables", function() { - return import("./wasm-table.wat").then(function(wasm) { +it("should support tables", function () { + return import("./wasm-table.wat").then(function (wasm) { expect(wasm.callByIndex(0)).toEqual(42); expect(wasm.callByIndex(1)).toEqual(13); expect(() => wasm.callByIndex(2)).toThrow(UNKNOWN_FUNCTION_TABLE); }); }); -it("should support exported tables", function() { - return import("./wasm-table-export.wat").then(function(wasm) { +it("should support exported tables", function () { + return import("./wasm-table-export.wat").then(function (wasm) { expect(wasm.table).toBeInstanceOf(WebAssembly.Table); expect(wasm.table.length).toBe(2); const e0 = wasm.table.get(0); @@ -22,8 +22,8 @@ it("should support exported tables", function() { }); }); -it("should support imported tables", function() { - return import("./wasm-table-imported.wat").then(function(wasm) { +it("should support imported tables", function () { + return import("./wasm-table-imported.wat").then(function (wasm) { expect(wasm.callByIndex(0)).toEqual(42); expect(wasm.callByIndex(1)).toEqual(13); expect(() => wasm.callByIndex(2)).toThrow(UNKNOWN_FUNCTION_TABLE); diff --git a/test/cases/wasm/table/test.filter.js b/test/cases/wasm/table/test.filter.js index 23177349638..bd7f4573a77 100644 --- a/test/cases/wasm/table/test.filter.js +++ b/test/cases/wasm/table/test.filter.js @@ -1,5 +1,5 @@ var supportsWebAssembly = require("../../../helpers/supportsWebAssembly"); -module.exports = function(config) { +module.exports = function (config) { return supportsWebAssembly(); }; diff --git a/test/cases/wasm/two-files-loader/test.filter.js b/test/cases/wasm/two-files-loader/test.filter.js index 23177349638..bd7f4573a77 100644 --- a/test/cases/wasm/two-files-loader/test.filter.js +++ b/test/cases/wasm/two-files-loader/test.filter.js @@ -1,5 +1,5 @@ var supportsWebAssembly = require("../../../helpers/supportsWebAssembly"); -module.exports = function(config) { +module.exports = function (config) { return supportsWebAssembly(); }; diff --git a/test/cases/wasm/two-files-loader/wrapper-loader.js b/test/cases/wasm/two-files-loader/wrapper-loader.js index 736d6fa0cf8..6ffbf502972 100644 --- a/test/cases/wasm/two-files-loader/wrapper-loader.js +++ b/test/cases/wasm/two-files-loader/wrapper-loader.js @@ -1,11 +1,9 @@ -const stringifyRequest = require("loader-utils").stringifyRequest; - +/** @type {import("../../../../").PitchLoaderDefinitionFunction} */ module.exports.pitch = function (remainingRequest) { return ` - import { getString as _getString, memory } from ${stringifyRequest( - this, - `${this.resourcePath}.wat!=!${remainingRequest}` - )}; + import { getString as _getString, memory } from ${ + JSON.stringify(`${this.utils.contextify(this.context, this.resourcePath)}.wat!=!${this.utils.contextify(this.context, remainingRequest)}`) + }; export function getString() { const strBuf = new Uint8Array(memory.buffer, _getString()); diff --git a/test/cases/wasm/two-files-loader/wrapper-loader2.js b/test/cases/wasm/two-files-loader/wrapper-loader2.js index 478a1f4f427..6ffbf502972 100644 --- a/test/cases/wasm/two-files-loader/wrapper-loader2.js +++ b/test/cases/wasm/two-files-loader/wrapper-loader2.js @@ -1,11 +1,9 @@ -const stringifyRequest = require("loader-utils").stringifyRequest; - +/** @type {import("../../../../").PitchLoaderDefinitionFunction} */ module.exports.pitch = function (remainingRequest) { return ` - import { getString as _getString, memory } from ${stringifyRequest( - this, - `${this.resourcePath}.wasm!=!wast-loader!${remainingRequest}` - )}; + import { getString as _getString, memory } from ${ + JSON.stringify(`${this.utils.contextify(this.context, this.resourcePath)}.wat!=!${this.utils.contextify(this.context, remainingRequest)}`) + }; export function getString() { const strBuf = new Uint8Array(memory.buffer, _getString()); diff --git a/test/cases/wasm/unused-export/test.filter.js b/test/cases/wasm/unused-export/test.filter.js index 23177349638..bd7f4573a77 100644 --- a/test/cases/wasm/unused-export/test.filter.js +++ b/test/cases/wasm/unused-export/test.filter.js @@ -1,5 +1,5 @@ var supportsWebAssembly = require("../../../helpers/supportsWebAssembly"); -module.exports = function(config) { +module.exports = function (config) { return supportsWebAssembly(); }; diff --git a/test/cases/wasm/v128/test.filter.js b/test/cases/wasm/v128/test.filter.js index 794b421bde9..a4c4664b2ea 100644 --- a/test/cases/wasm/v128/test.filter.js +++ b/test/cases/wasm/v128/test.filter.js @@ -1,6 +1,8 @@ -const supportsWebAssembly = require("../../../helpers/supportsWebAssembly"); -const supportsFeature = require("webassembly-feature"); +// const supportsWebAssembly = require("../../../helpers/supportsWebAssembly"); +// const supportsFeature = require("webassembly-feature"); -module.exports = function(config) { - return supportsWebAssembly() && supportsFeature.simd(); +module.exports = function (config) { + // TODO fails with CompileError: WebAssembly.instantiate(): Compiling function #0 failed: memory instruction with no memory @+24 + return false; + // return supportsWebAssembly() && supportsFeature.simd(); }; diff --git a/test/cases/wasm/wasm-explorer-examples-async/test.filter.js b/test/cases/wasm/wasm-explorer-examples-async/test.filter.js index 23177349638..bd7f4573a77 100644 --- a/test/cases/wasm/wasm-explorer-examples-async/test.filter.js +++ b/test/cases/wasm/wasm-explorer-examples-async/test.filter.js @@ -1,5 +1,5 @@ var supportsWebAssembly = require("../../../helpers/supportsWebAssembly"); -module.exports = function(config) { +module.exports = function (config) { return supportsWebAssembly(); }; diff --git a/test/cases/wasm/wasm-explorer-examples-sync/test.filter.js b/test/cases/wasm/wasm-explorer-examples-sync/test.filter.js index 23177349638..bd7f4573a77 100644 --- a/test/cases/wasm/wasm-explorer-examples-sync/test.filter.js +++ b/test/cases/wasm/wasm-explorer-examples-sync/test.filter.js @@ -1,5 +1,5 @@ var supportsWebAssembly = require("../../../helpers/supportsWebAssembly"); -module.exports = function(config) { +module.exports = function (config) { return supportsWebAssembly(); }; diff --git a/test/checkArrayExpectation.js b/test/checkArrayExpectation.js index 448c0f787b8..3097d1c3f2c 100644 --- a/test/checkArrayExpectation.js +++ b/test/checkArrayExpectation.js @@ -6,6 +6,9 @@ const check = (expected, actual) => { if (expected instanceof RegExp) { expected = { message: expected }; } + if (Array.isArray(expected)) { + return expected.every(e => check(e, actual)); + } return Object.keys(expected).every(key => { let value = actual[key]; if (typeof value === "object") { @@ -27,12 +30,38 @@ const explain = object => { } let msg = `${key} = ${value}`; if (key !== "stack" && key !== "details" && msg.length > 100) - msg = msg.slice(0, 97) + "..."; + msg = `${msg.slice(0, 97)}...`; return msg; }) .join("; "); }; +const diffItems = (actual, expected, kind) => { + const tooMuch = actual.slice(); + const missing = expected.slice(); + for (let i = 0; i < missing.length; i++) { + const current = missing[i]; + for (let j = 0; j < tooMuch.length; j++) { + if (check(current, tooMuch[j])) { + tooMuch.splice(j, 1); + missing.splice(i, 1); + i--; + break; + } + } + } + const diff = []; + if (missing.length > 0) { + diff.push(`The following expected ${kind}s are missing: +${missing.map(item => `${explain(item)}`).join("\n\n")}`); + } + if (tooMuch.length > 0) { + diff.push(`The following ${kind}s are unexpected: +${tooMuch.map(item => `${explain(item)}`).join("\n\n")}`); + } + return diff.join("\n\n"); +}; + module.exports = function checkArrayExpectation( testDirectory, object, @@ -47,21 +76,18 @@ module.exports = function checkArrayExpectation( filename = `${kind}s`; } let array = object[`${kind}s`]; - if (Array.isArray(array)) { - if (kind === "warning") { - array = array.filter(item => !/from Terser/.test(item)); - } + if (Array.isArray(array) && kind === "warning") { + array = array.filter(item => !/from Terser/.test(item)); } if (fs.existsSync(path.join(testDirectory, `${filename}.js`))) { const expectedFilename = path.join(testDirectory, `${filename}.js`); const expected = require(expectedFilename); + const diff = diffItems(array, expected, kind); if (expected.length < array.length) { return ( done( new Error( - `More ${kind}s while compiling than expected:\n\n${array - .map(explain) - .join("\n\n")}. Check expected ${kind}s: ${expectedFilename}` + `More ${kind}s (${array.length} instead of ${expected.length}) while compiling than expected:\n\n${diff}\n\nCheck expected ${kind}s: ${expectedFilename}` ) ), true @@ -70,9 +96,7 @@ module.exports = function checkArrayExpectation( return ( done( new Error( - `Less ${kind}s while compiling than expected:\n\n${array - .map(explain) - .join("\n\n")}. Check expected ${kind}s: ${expectedFilename}` + `Less ${kind}s (${array.length} instead of ${expected.length}) while compiling than expected:\n\n${diff}\n\nCheck expected ${kind}s: ${expectedFilename}` ) ), true @@ -94,7 +118,7 @@ module.exports = function checkArrayExpectation( ); } } - } else if (!check(expected[i], array[i])) + } else if (!check(expected[i], array[i])) { return ( done( new Error( @@ -105,6 +129,7 @@ module.exports = function checkArrayExpectation( ), true ); + } } } else if (array.length > 0) { return ( diff --git a/test/compareLocations.unittest.js b/test/compareLocations.unittest.js index 17e4e159079..3c7a03d084e 100644 --- a/test/compareLocations.unittest.js +++ b/test/compareLocations.unittest.js @@ -1,25 +1,22 @@ "use strict"; const { compareLocations } = require("../lib/util/comparators"); -const createPosition = overrides => { - return { - line: 10, - column: 5, - ...overrides - }; -}; - -const createLocation = (start, end, index) => { - return { - start: createPosition(start), - end: createPosition(end), - index: index || 3 - }; -}; +const createPosition = overrides => ({ + line: 10, + column: 5, + ...overrides +}); + +const createLocation = (start, end, index) => ({ + start: createPosition(start), + end: createPosition(end), + index: index || 3 +}); describe("compareLocations", () => { describe("object location comparison", () => { - let a, b; + let a; + let b; describe("location line number", () => { beforeEach(() => { diff --git a/test/compareStringsNumeric.unittest.js b/test/compareStringsNumeric.unittest.js new file mode 100644 index 00000000000..061729ddfc8 --- /dev/null +++ b/test/compareStringsNumeric.unittest.js @@ -0,0 +1,93 @@ +const { compareStringsNumeric } = require("../lib/util/comparators.js"); + +/** + * @param {string} a string + * @param {string} b string + * @returns {-1|0|1} compare result + */ +const referenceComparer = (a, b) => { + const partsA = a.split(/(\d+)/); + const partsB = b.split(/(\d+)/); + const len = Math.min(partsA.length, partsB.length); + for (let i = 0; i < len; i++) { + const pA = partsA[i]; + const pB = partsB[i]; + if (i % 2 === 0) { + if (pA.length > pB.length) { + if (pA.slice(0, pB.length) > pB) return 1; + return -1; + } else if (pB.length > pA.length) { + if (pB.slice(0, pA.length) > pA) return -1; + return 1; + } + if (pA < pB) return -1; + if (pA > pB) return 1; + } else { + const nA = Number(pA); + const nB = Number(pB); + if (nA < nB) return -1; + if (nA > nB) return 1; + } + } + if (partsB.length < partsA.length) return 1; + if (partsB.length > partsA.length) return -1; + return 0; +}; + +describe(compareStringsNumeric.name, () => { + const testCases = [ + ["", "a", 1], + ["a", "", -1], + ["", "0", -1], + ["1", "", 1], + ["", "", 0], + ["a", "1", -1], + ["1", "a", 1], + ["_", "1", -1], + ["1", "_", 1], + ["a", "b", -1], + ["b", "a", 1], + ["a", "a", 0], + ["a1", "a2", -1], + ["a2", "a1", 1], + ["a1", "a1", 0], + ["ab1", "ab2", -1], + ["ab2", "ab1", 1], + ["ab1", "a1", -1], + ["a1", "ab1", 1], + ["a1", "a10", -1], + ["a10", "a1", 1], + ["a1", "a01", 0], + ["a1", "a1a", 1], + ["a1a", "a1", -1], + ["a1a", "a01a", 0], + ["a1a", "a1b", -1], + ["a1b", "a1a", 1], + ["a1a", "a1a1", -1], + ["a1a1", "a1a", 1], + ["a1a1", "a1a1", 0], + ["a1a1", "a1a2", -1], + ["a1a2", "a1a1", 1], + ["a1a1", "a1a01", 0], + ["a1a1", "a1a1a", 1], + ["a1a1a", "a1a1", -1], + ["a1a1a", "a1a1a", 0], + ["a1a1a", "a1a1b", -1], + ["a1a1b", "a1a1a", 1], + ["a1a1a", "a1a1a1", -1], + ["a1a1a1", "a1a1a", 1], + ["a1a1a1", "a1a1a1", 0], + ["a1a1a1", "a1a1a2", -1], + ["a1a1a2", "a1a1a1", 1], + ["a1a1a1", "a1a1a01", 0], + ["a1a1a1", "a1a1a1a", 1] + ]; + + for (const testCase of testCases) { + const [a, b, expected] = testCase; + it(`returns ${expected} when comparing "${a}" to "${b}"`, () => { + expect(referenceComparer(a, b)).toBe(expected); + expect(compareStringsNumeric(a, b)).toBe(expected); + }); + } +}); diff --git a/test/compileBooleanMatcher.unittest.js b/test/compileBooleanMatcher.unittest.js index 8a8778848b0..7b2f1998dac 100644 --- a/test/compileBooleanMatcher.unittest.js +++ b/test/compileBooleanMatcher.unittest.js @@ -24,31 +24,31 @@ describe("itemsToRegexp", () => { }); expectCompiled("basic", ["abc", "def", "123", "45", "6"], e => - e.toMatchInlineSnapshot(`(123|45|6|abc|def)`) + e.toMatchInlineSnapshot("(123|45|6|abc|def)") ); expectCompiled("single chars", ["a", "b", "c", "1", "2", "3"], e => - e.toMatchInlineSnapshot(`[123abc]`) + e.toMatchInlineSnapshot("[123abc]") ); expectCompiled( "prefixes", ["ab1", "ab2", "ab3", "ab4", "de5", "de6", "de7", "ef8", "ef9", "gh0"], - e => e.toMatchInlineSnapshot(`(ab[1234]|de[567]|ef[89]|gh0)`) + e => e.toMatchInlineSnapshot("(ab[1234]|de[567]|ef[89]|gh0)") ); expectCompiled("short prefixes", "a,ab", e => - e.toMatchInlineSnapshot(`a(|b)`) + e.toMatchInlineSnapshot("a(|b)") ); expectCompiled( "nested prefixes", ["a", "ab", "abc", "abcd", "abcde", "abcdef"], - e => e.toMatchInlineSnapshot(`a(b(c(d(|e|ef)|)|)|)`) + e => e.toMatchInlineSnapshot("a(b(c(d(|e|ef)|)|)|)") ); expectCompiled("suffixes", "a1,b1,c1,d1,e1,a2,b2,c2", e => - e.toMatchInlineSnapshot(`([abcde]1|[abc]2)`) + e.toMatchInlineSnapshot("([abcde]1|[abc]2)") ); expectCompiled( @@ -56,7 +56,7 @@ describe("itemsToRegexp", () => { "674,542,965,12,942,483,445,943,423,995,434,122,995,248,432,165,436,86,435,221", e => e.toMatchInlineSnapshot( - `(1(2|22|65)|4(3[2456]|23|45|83)|9(42|43|65|95)|221|248|542|674|86)` + "(1(2|22|65)|4(3[2456]|23|45|83)|9(42|43|65|95)|221|248|542|674|86)" ) ); @@ -74,7 +74,7 @@ describe("itemsToRegexp", () => { ], e => e.toMatchInlineSnapshot( - `(\\.\\/path\\/to\\/(directory\\/with\\/(file\\.(js(|on)|css)|module\\.css)|file\\.(|m)js|other\\-file\\.js)|webpack\\/runtime\\/module)` + "(\\.\\/path\\/to\\/(directory\\/with\\/(file\\.(js(|on)|css)|module\\.css)|file\\.(|m)js|other\\-file\\.js)|webpack\\/runtime\\/module)" ) ); @@ -86,7 +86,7 @@ describe("itemsToRegexp", () => { ], e => e.toMatchInlineSnapshot( - `webpack_sharing_consume_default_(|classnames_classnames\\-webpack_sharing_consume_default_)react_react` + "webpack_sharing_consume_default_(|classnames_classnames\\-webpack_sharing_consume_default_)react_react" ) ); }); diff --git a/test/configCases/additional-pass/simple/webpack.config.js b/test/configCases/additional-pass/simple/webpack.config.js index 36318c9badf..54060e83fe9 100644 --- a/test/configCases/additional-pass/simple/webpack.config.js +++ b/test/configCases/additional-pass/simple/webpack.config.js @@ -1,5 +1,5 @@ /** @type {import("../../../../").WebpackPluginFunction} */ -var testPlugin = function () { +function testPlugin() { var counter = 1; this.hooks.compilation.tap("TestPlugin", compilation => { var nr = counter++; @@ -7,7 +7,7 @@ var testPlugin = function () { if (nr < 5) return true; }); }); -}; +} /** @type {import("../../../../").Configuration} */ module.exports = { diff --git a/test/configCases/asset-emitted/normal/index.js b/test/configCases/asset-emitted/normal/index.js index c5d0cd4199f..9e1b6b1cd1b 100644 --- a/test/configCases/asset-emitted/normal/index.js +++ b/test/configCases/asset-emitted/normal/index.js @@ -1,3 +1 @@ -import("./module"); - -it("should run", () => {}); +it("should run", () => import("./module")); diff --git a/test/configCases/asset-emitted/normal/webpack.config.js b/test/configCases/asset-emitted/normal/webpack.config.js index 63eaa7b5db4..d49782512ac 100644 --- a/test/configCases/asset-emitted/normal/webpack.config.js +++ b/test/configCases/asset-emitted/normal/webpack.config.js @@ -19,11 +19,11 @@ module.exports = { ); compiler.hooks.afterEmit.tap("Test", () => { expect(files).toMatchInlineSnapshot(` -Object { - "662.bundle0.js": true, - "bundle0.js": true, -} -`); + Object { + "93.bundle0.js": true, + "bundle0.js": true, + } + `); }); } ] diff --git a/test/configCases/asset-modules/data-url/index.js b/test/configCases/asset-modules/data-url/index.js index 938da5684ad..ee46bb5c044 100644 --- a/test/configCases/asset-modules/data-url/index.js +++ b/test/configCases/asset-modules/data-url/index.js @@ -1,9 +1,31 @@ import png from "../_images/file.png"; import svg from "../_images/file.svg"; import jpg from "../_images/file.jpg"; +import dataSvg from "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA2MDAgNjAwIj48dGl0bGU+aWNvbi1zcXVhcmUtc21hbGw8L3RpdGxlPjxwYXRoIGZpbGw9IiNGRkYiIGQ9Ik0zMDAgLjFMNTY1IDE1MHYyOTkuOUwzMDAgNTk5LjggMzUgNDQ5LjlWMTUweiIvPjxwYXRoIGZpbGw9IiM4RUQ2RkIiIGQ9Ik01MTcuNyA0MzkuNUwzMDguOCA1NTcuOHYtOTJMNDM5IDM5NC4xbDc4LjcgNDUuNHptMTQuMy0xMi45VjE3OS40bC03Ni40IDQ0LjF2MTU5bDc2LjQgNDQuMXpNODEuNSA0MzkuNWwyMDguOSAxMTguMnYtOTJsLTEzMC4yLTcxLjYtNzguNyA0NS40em0tMTQuMy0xMi45VjE3OS40bDc2LjQgNDQuMXYxNTlsLTc2LjQgNDQuMXptOC45LTI2My4yTDI5MC40IDQyLjJ2ODlsLTEzNy4zIDc1LjUtMS4xLjYtNzUuOS00My45em00NDYuOSAwTDMwOC44IDQyLjJ2ODlMNDQ2IDIwNi44bDEuMS42IDc1LjktNDR6Ii8+PHBhdGggZmlsbD0iIzFDNzhDMCIgZD0iTTI5MC40IDQ0NC44TDE2MiAzNzQuMVYyMzQuMmwxMjguNCA3NC4xdjEzNi41em0xOC40IDBsMTI4LjQtNzAuNnYtMTQwbC0xMjguNCA3NC4xdjEzNi41ek0yOTkuNiAzMDN6bS0xMjktODVsMTI5LTcwLjlMNDI4LjUgMjE4bC0xMjguOSA3NC40LTEyOS03NC40eiIvPjwvc3ZnPgo="; +const urlSvg = new URL( + "data:image/svg;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA2MDAgNjAwIj48dGl0bGU+aWNvbi1zcXVhcmUtc21hbGw8L3RpdGxlPjxwYXRoIGZpbGw9IiNGRkYiIGQ9Ik0zMDAgLjFMNTY1IDE1MHYyOTkuOUwzMDAgNTk5LjggMzUgNDQ5LjlWMTUweiIvPjxwYXRoIGZpbGw9IiM4RUQ2RkIiIGQ9Ik01MTcuNyA0MzkuNUwzMDguOCA1NTcuOHYtOTJMNDM5IDM5NC4xbDc4LjcgNDUuNHptMTQuMy0xMi45VjE3OS40bC03Ni40IDQ0LjF2MTU5bDc2LjQgNDQuMXpNODEuNSA0MzkuNWwyMDguOSAxMTguMnYtOTJsLTEzMC4yLTcxLjYtNzguNyA0NS40em0tMTQuMy0xMi45VjE3OS40bDc2LjQgNDQuMXYxNTlsLTc2LjQgNDQuMXptOC45LTI2My4yTDI5MC40IDQyLjJ2ODlsLTEzNy4zIDc1LjUtMS4xLjYtNzUuOS00My45em00NDYuOSAwTDMwOC44IDQyLjJ2ODlMNDQ2IDIwNi44bDEuMS42IDc1LjktNDR6Ii8+PHBhdGggZmlsbD0iIzFDNzhDMCIgZD0iTTI5MC40IDQ0NC44TDE2MiAzNzQuMVYyMzQuMmwxMjguNCA3NC4xdjEzNi41em0xOC40IDBsMTI4LjQtNzAuNnYtMTQwbC0xMjguNCA3NC4xdjEzNi41ek0yOTkuNiAzMDN6bS0xMjktODVsMTI5LTcwLjlMNDI4LjUgMjE4bC0xMjguOSA3NC40LTEyOS03NC40eiIvPjwvc3ZnPgo=" +); +const urlSvg2 = new URL( + "data:image/svg+xml;p=1;q=2,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke=\"%23343a40\" stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M2 5l6 6 6-6'/%3e%3c/svg%3e", + import.meta.url +); +const helloWorld = new URL("data:text/plain,Hello", import.meta.url); +const helloWorldBase64 = new URL( + "data:text/plain;base64,SGVsbG8=", + import.meta.url +); it("should generate various data-url types", () => { expect(png).toContain("data:image/png;base64,"); expect(svg).toContain("data:image/svg+xml;base64"); expect(jpg).toContain("data:image/jpeg;base64,"); + expect(dataSvg).toContain("data:image/svg+xml;base64,"); + expect(urlSvg.href).toContain("data:image/svg;base64,"); + expect(urlSvg2.href).toContain( + "data:image/svg+xml;p=1;q=2,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke=\"%23343a40\" stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M2 5l6 6 6-6'/%3e%3c/svg%3e" + ); + expect(helloWorld.href).toContain("data:text/plain,Hello%2C%20World%21"); + expect(helloWorldBase64.href).toContain( + "data:text/plain;base64,SGVsbG8sIFdvcmxkIQ==" + ); }); diff --git a/test/configCases/asset-modules/data-url/loader.js b/test/configCases/asset-modules/data-url/loader.js new file mode 100644 index 00000000000..c5048a9c3df --- /dev/null +++ b/test/configCases/asset-modules/data-url/loader.js @@ -0,0 +1,4 @@ +/** @type {import("../../../../").LoaderDefinition<{ f(): any }>} */ +module.exports = function (source) { + return `${source}, World!`; +}; diff --git a/test/configCases/asset-modules/data-url/webpack.config.js b/test/configCases/asset-modules/data-url/webpack.config.js index 924725978dc..ab9e619ce2f 100644 --- a/test/configCases/asset-modules/data-url/webpack.config.js +++ b/test/configCases/asset-modules/data-url/webpack.config.js @@ -7,6 +7,10 @@ module.exports = { test: /\.(png|svg)$/, type: "asset/inline" }, + { + mimetype: "image/svg+xml", + type: "asset/inline" + }, { test: /\.jpg$/, type: "asset", @@ -15,6 +19,11 @@ module.exports = { maxSize: Infinity } } + }, + { + mimetype: "text/plain", + type: "asset/inline", + loader: "./loader" } ] } diff --git a/test/configCases/asset-modules/emit/index.js b/test/configCases/asset-modules/emit/index.js index 7fad7b428cb..3bc85a00242 100644 --- a/test/configCases/asset-modules/emit/index.js +++ b/test/configCases/asset-modules/emit/index.js @@ -1,11 +1,12 @@ import url from "../_images/file.png"; +import url2 from "../_images/file.jpg"; import fs from "fs"; +import path from "path"; it("should output asset with path", () => { expect(url).toEqual("images/file.png"); - expect(() => fs.statSync(url)).toThrowError( - expect.objectContaining({ - code: "ENOENT" - }) - ); + expect(url2).toEqual("images/file.jpg"); + + expect(fs.existsSync(path.join(__STATS__.outputPath, url))).toBe(false); + expect(fs.existsSync(path.join(__STATS__.outputPath, url2))).toBe(true); }); diff --git a/test/configCases/asset-modules/emit/webpack.config.js b/test/configCases/asset-modules/emit/webpack.config.js index 01ec74645c9..f764349bb04 100644 --- a/test/configCases/asset-modules/emit/webpack.config.js +++ b/test/configCases/asset-modules/emit/webpack.config.js @@ -8,10 +8,14 @@ module.exports = { rules: [ { test: /\.png$/, - type: "asset", + type: "asset/resource", generator: { emit: false } + }, + { + test: /\.jpg$/, + type: "asset/resource" } ] } diff --git a/test/configCases/asset-modules/file-url/webpack.config.js b/test/configCases/asset-modules/file-url/webpack.config.js index 6595e498ff8..81395d57854 100644 --- a/test/configCases/asset-modules/file-url/webpack.config.js +++ b/test/configCases/asset-modules/file-url/webpack.config.js @@ -1,12 +1,10 @@ const fs = require("fs"); const path = require("path"); const { pathToFileURL } = require("url"); -const file = path.resolve( - "./test/configCases/asset-modules/file-url", - "./temp/index.js" -); +const dir = path.resolve(__dirname, "temp"); +const file = path.resolve(dir, "index.js"); -fs.mkdirSync("./test/configCases/asset-modules/file-url/temp", { +fs.mkdirSync(dir, { recursive: true }); fs.writeFileSync( @@ -19,18 +17,18 @@ fs.writeFileSync( ) )}; import v2 from ${JSON.stringify( - "file://localhost" + - pathToFileURL( - path.resolve( - "./test/configCases/asset-modules/file-url/src with spaces/module.js" - ) + `file://localhost${pathToFileURL( + path.resolve( + "./test/configCases/asset-modules/file-url/src with spaces/module.js" ) - .toString() - .slice("file://".length) + ) + .toString() + .slice("file://".length)}` )}; export const val1 = v1; export const val2 = v2;` ); +fs.utimesSync(file, new Date(Date.now() - 10000), new Date(Date.now() - 10000)); /** @type {import("../../../../").Configuration} */ module.exports = { diff --git a/test/configCases/asset-modules/generator-asset-publicPath-hash/index.js b/test/configCases/asset-modules/generator-asset-publicPath-hash/index.js new file mode 100644 index 00000000000..2cd9f385a96 --- /dev/null +++ b/test/configCases/asset-modules/generator-asset-publicPath-hash/index.js @@ -0,0 +1,12 @@ +import url from "../_images/file.png"; + +it("should import asset with module.generator.asset.publicPath", () => { + expect(url).toMatch(/^[a-f0-9]{20}\/assets\/[a-f0-9]{10}\.file\.png$/); + const assetInfo = __STATS__.assets.find( + a => a.info.sourceFilename === "../_images/file.png" + ).info; + expect(assetInfo.immutable).toBe(true); + expect(assetInfo.contenthash.length).toBe(2); + expect(assetInfo.contenthash[0].length).toBe(10); + expect(assetInfo.contenthash[1].length).toBe(20); +}); diff --git a/test/configCases/asset-modules/generator-asset-publicPath-hash/webpack.config.js b/test/configCases/asset-modules/generator-asset-publicPath-hash/webpack.config.js new file mode 100644 index 00000000000..f21eb61c884 --- /dev/null +++ b/test/configCases/asset-modules/generator-asset-publicPath-hash/webpack.config.js @@ -0,0 +1,20 @@ +/** @type {import("../../../../").Configuration} */ +module.exports = { + mode: "development", + output: { + assetModuleFilename: "[contenthash:10].file[ext]" + }, + module: { + rules: [ + { + test: /\.png$/, + type: "asset" + } + ], + generator: { + asset: { + publicPath: "[contenthash]/assets/" + } + } + } +}; diff --git a/test/configCases/asset-modules/generator-asset-publicPath/index.js b/test/configCases/asset-modules/generator-asset-publicPath/index.js new file mode 100644 index 00000000000..dfeeec0a55b --- /dev/null +++ b/test/configCases/asset-modules/generator-asset-publicPath/index.js @@ -0,0 +1,5 @@ +import url from "../_images/file.png"; + +it("should import asset with module.generator.asset.publicPath", () => { + expect(url).toEqual("assets/file.png"); +}); diff --git a/test/configCases/asset-modules/generator-asset-publicPath/webpack.config.js b/test/configCases/asset-modules/generator-asset-publicPath/webpack.config.js new file mode 100644 index 00000000000..8dbee301fd5 --- /dev/null +++ b/test/configCases/asset-modules/generator-asset-publicPath/webpack.config.js @@ -0,0 +1,20 @@ +/** @type {import("../../../../").Configuration} */ +module.exports = { + mode: "development", + output: { + assetModuleFilename: "file[ext]" + }, + module: { + rules: [ + { + test: /\.png$/, + type: "asset" + } + ], + generator: { + asset: { + publicPath: "assets/" + } + } + } +}; diff --git a/test/configCases/asset-modules/global-options/webpack.config.js b/test/configCases/asset-modules/global-options/webpack.config.js index fc324dde061..91fbfcff635 100644 --- a/test/configCases/asset-modules/global-options/webpack.config.js +++ b/test/configCases/asset-modules/global-options/webpack.config.js @@ -7,9 +7,7 @@ module.exports = { module: { parser: { asset: { - dataUrlCondition: (source, { filename }) => { - return filename.includes("?inline"); - } + dataUrlCondition: (source, { filename }) => filename.includes("?inline") } }, generator: { diff --git a/test/configCases/asset-modules/http-url/dev-defaults.webpack.lock.data/http_localhost_9990/asset_72216076a225ea0abbaa.txt b/test/configCases/asset-modules/http-url/dev-defaults.webpack.lock.data/http_localhost_9990/asset_72216076a225ea0abbaa.txt new file mode 100644 index 00000000000..5e1c309dae7 --- /dev/null +++ b/test/configCases/asset-modules/http-url/dev-defaults.webpack.lock.data/http_localhost_9990/asset_72216076a225ea0abbaa.txt @@ -0,0 +1 @@ +Hello World \ No newline at end of file diff --git a/test/configCases/asset-modules/http-url/dev-defaults.webpack.lock.data/http_localhost_9990/asset_query_590ffbc5acc20bf1dc88.txt b/test/configCases/asset-modules/http-url/dev-defaults.webpack.lock.data/http_localhost_9990/asset_query_590ffbc5acc20bf1dc88.txt new file mode 100644 index 00000000000..5e1c309dae7 --- /dev/null +++ b/test/configCases/asset-modules/http-url/dev-defaults.webpack.lock.data/http_localhost_9990/asset_query_590ffbc5acc20bf1dc88.txt @@ -0,0 +1 @@ +Hello World \ No newline at end of file diff --git a/test/configCases/asset-modules/http-url/dev-defaults.webpack.lock.data/http_localhost_9990/fallback_4972219bd28762fbfd18.js b/test/configCases/asset-modules/http-url/dev-defaults.webpack.lock.data/http_localhost_9990/fallback_4972219bd28762fbfd18.js new file mode 100644 index 00000000000..e5dfb6da968 --- /dev/null +++ b/test/configCases/asset-modules/http-url/dev-defaults.webpack.lock.data/http_localhost_9990/fallback_4972219bd28762fbfd18.js @@ -0,0 +1 @@ +export * from "fallback-package"; \ No newline at end of file diff --git a/test/configCases/asset-modules/http-url/dev-defaults.webpack.lock.data/http_localhost_9990/folder_dependency_3263dc642c8ad1171873.js b/test/configCases/asset-modules/http-url/dev-defaults.webpack.lock.data/http_localhost_9990/folder_dependency_3263dc642c8ad1171873.js new file mode 100644 index 00000000000..e3e81f78e6b --- /dev/null +++ b/test/configCases/asset-modules/http-url/dev-defaults.webpack.lock.data/http_localhost_9990/folder_dependency_3263dc642c8ad1171873.js @@ -0,0 +1,2 @@ +export * from "./sub-dependency.js"; +export * from "/folder/sub-dependency2.js"; \ No newline at end of file diff --git a/test/configCases/asset-modules/http-url/dev-defaults.webpack.lock.data/http_localhost_9990/folder_sub-dependency2_f750536150de4f4db445.js b/test/configCases/asset-modules/http-url/dev-defaults.webpack.lock.data/http_localhost_9990/folder_sub-dependency2_f750536150de4f4db445.js new file mode 100644 index 00000000000..72fdbad6cad --- /dev/null +++ b/test/configCases/asset-modules/http-url/dev-defaults.webpack.lock.data/http_localhost_9990/folder_sub-dependency2_f750536150de4f4db445.js @@ -0,0 +1 @@ +export const value2 = 42; \ No newline at end of file diff --git a/test/configCases/asset-modules/http-url/dev-defaults.webpack.lock.data/http_localhost_9990/folder_sub-dependency_a662b3b186898f776088.js b/test/configCases/asset-modules/http-url/dev-defaults.webpack.lock.data/http_localhost_9990/folder_sub-dependency_a662b3b186898f776088.js new file mode 100644 index 00000000000..b7159db4840 --- /dev/null +++ b/test/configCases/asset-modules/http-url/dev-defaults.webpack.lock.data/http_localhost_9990/folder_sub-dependency_a662b3b186898f776088.js @@ -0,0 +1 @@ +export const value = 42; \ No newline at end of file diff --git a/test/configCases/asset-modules/http-url/dev-defaults.webpack.lock.data/http_localhost_9990/index_cache_502725659b59ae63a82a.css b/test/configCases/asset-modules/http-url/dev-defaults.webpack.lock.data/http_localhost_9990/index_cache_502725659b59ae63a82a.css new file mode 100644 index 00000000000..b978c1b5980 --- /dev/null +++ b/test/configCases/asset-modules/http-url/dev-defaults.webpack.lock.data/http_localhost_9990/index_cache_502725659b59ae63a82a.css @@ -0,0 +1 @@ +a {} \ No newline at end of file diff --git a/test/configCases/asset-modules/http-url/dev-defaults.webpack.lock.data/http_localhost_9990/index_query_169a64b251bcdc02a084.css b/test/configCases/asset-modules/http-url/dev-defaults.webpack.lock.data/http_localhost_9990/index_query_169a64b251bcdc02a084.css new file mode 100644 index 00000000000..b978c1b5980 --- /dev/null +++ b/test/configCases/asset-modules/http-url/dev-defaults.webpack.lock.data/http_localhost_9990/index_query_169a64b251bcdc02a084.css @@ -0,0 +1 @@ +a {} \ No newline at end of file diff --git a/test/configCases/asset-modules/http-url/dev-defaults.webpack.lock.data/http_localhost_9990/redirect_d3dcf71bcf15dc29654c.js b/test/configCases/asset-modules/http-url/dev-defaults.webpack.lock.data/http_localhost_9990/redirect_d3dcf71bcf15dc29654c.js new file mode 100644 index 00000000000..d31cf81a327 --- /dev/null +++ b/test/configCases/asset-modules/http-url/dev-defaults.webpack.lock.data/http_localhost_9990/redirect_d3dcf71bcf15dc29654c.js @@ -0,0 +1 @@ +export default { ok: true }; \ No newline at end of file diff --git a/test/configCases/asset-modules/http-url/dev-defaults.webpack.lock.data/http_localhost_9990/resolve_69c3f44e55195d0c14cf.js b/test/configCases/asset-modules/http-url/dev-defaults.webpack.lock.data/http_localhost_9990/resolve_69c3f44e55195d0c14cf.js new file mode 100644 index 00000000000..7a369ecb8ec --- /dev/null +++ b/test/configCases/asset-modules/http-url/dev-defaults.webpack.lock.data/http_localhost_9990/resolve_69c3f44e55195d0c14cf.js @@ -0,0 +1 @@ +export * from "./folder/dependency.js"; \ No newline at end of file diff --git a/test/configCases/asset-modules/http-url/dev-defaults.webpack.lock.data/http_localhost_9990/url_cc93d527a81c32b07ab8.js b/test/configCases/asset-modules/http-url/dev-defaults.webpack.lock.data/http_localhost_9990/url_cc93d527a81c32b07ab8.js new file mode 100644 index 00000000000..1948b244cf1 --- /dev/null +++ b/test/configCases/asset-modules/http-url/dev-defaults.webpack.lock.data/http_localhost_9990/url_cc93d527a81c32b07ab8.js @@ -0,0 +1 @@ +export default new URL("asset.txt?query", import.meta.url); \ No newline at end of file diff --git a/test/configCases/asset-modules/http-url/dev-defaults.webpack.lock.data/https_raw.githubusercontent.com/webpack_webpack_main_CODE_OF_CONDUCT_06e7b335922db99b918d.md b/test/configCases/asset-modules/http-url/dev-defaults.webpack.lock.data/https_raw.githubusercontent.com/webpack_webpack_main_CODE_OF_CONDUCT_06e7b335922db99b918d.md new file mode 100644 index 00000000000..4faf227c455 --- /dev/null +++ b/test/configCases/asset-modules/http-url/dev-defaults.webpack.lock.data/https_raw.githubusercontent.com/webpack_webpack_main_CODE_OF_CONDUCT_06e7b335922db99b918d.md @@ -0,0 +1 @@ +[Code of Conduct](https://github.com/openjs-foundation/code-and-learn/blob/master/CODE_OF_CONDUCT.md) diff --git a/test/configCases/asset-modules/http-url/errors.js b/test/configCases/asset-modules/http-url/errors.js new file mode 100644 index 00000000000..4e46c194963 --- /dev/null +++ b/test/configCases/asset-modules/http-url/errors.js @@ -0,0 +1,18 @@ +module.exports = [ + [ + /http:\/\/localhost:9990\/index\.css\?cache used to have no-cache lockfile entry and has content now, but lockfile is frozen/ + ], + [ + /http:\/\/localhost:9990\/index\.css\?no-cache has a lockfile entry and is no-cache now, but lockfile is frozen/ + ], + [ + /http:\/\/localhost:9990\/index\.css has an outdated lockfile entry, but lockfile is frozen/ + ], + [/http:\/\/localhost:9990\/resolve\.js integrity mismatch/], + [ + /http:\/\/localhost:9990\/fallback\.js has no lockfile entry and lockfile is frozen/ + ], + [ + /http:\/\/localhost:9990\/redirect has an outdated lockfile entry, but lockfile is frozen/ + ] +]; diff --git a/test/configCases/asset-modules/http-url/errors.webpack.lock b/test/configCases/asset-modules/http-url/errors.webpack.lock new file mode 100644 index 00000000000..8f9855c35bd --- /dev/null +++ b/test/configCases/asset-modules/http-url/errors.webpack.lock @@ -0,0 +1,13 @@ +{ + "http://localhost:9990/asset.txt?ignore": "ignore", + "http://localhost:9990/index.css": { "integrity": "sha512-sqhF9JAEi5h3ziP48SBnzQnaeei8cf/pfYJBdKL4F7xdu3v5yr71eQ0kCL11/jWRFjLG4TKOudUnS/u6WLMqYw==", "contentType": "invalid" }, + "http://localhost:9990/index.css?query#fragment": { "integrity": "sha512-sqhF9JAEi5h3ziP48SBnzQnaeei8cf/pfYJBdKL4F7xdu3v5yr71eQ0kCL11/jWRFjLG4TKOudUnS/u6WLMqYw==", "contentType": "text/css" }, + "http://localhost:9990/index.css?no-cache": { "integrity": "sha512-sqhF9JAEi5h3ziP48SBnzQnaeei8cf/pfYJBdKL4F7xdu3v5yr71eQ0kCL11/jWRFjLG4TKOudUnS/u6WLMqYw==", "contentType": "text/css" }, + "http://localhost:9990/index.css?cache": "no-cache", + "http://localhost:9990/redirect": { "integrity": "sha512-BV/MK/QTq+NHRve1XpZyQ8V6cjRP/fwbtJvENRdm5C73qNYZ4i2/fw+soj7J4qxzBXMHDbvOnA6E0ShnX2hc1w==", "contentType": "text/javascript" }, + "http://localhost:9990/redirect.js": { "resolved": "http://localhost:9990/redirect", "integrity": "sha512-BV/MK/QTq+NHRve1XpZyQ8V6cjRP/fwbtJvENRdm5C73qNYZ4i2/fw+soj7J4qxzBXMHDbvOnA6E0ShnX2hc1w==", "contentType": "text/javascript" }, + "http://localhost:9990/resolve.js": { "integrity": "sha512-SHOULD_BE_INVALID", "contentType": "text/javascript" }, + "https://raw.githubusercontent.com//webpack//webpack//main/CODE_OF_CONDUCT.md": { "integrity": "sha512-OLJ9q6iSO652hVBkTLsMLtQnFBBTzEbFqLGyWD62nPga/0DZ9bc3oOFb5OYT8RIPzmlOX4WzK2uiLgc1NSGtBA==", "contentType": "text/plain; charset=utf-8" }, + "https://raw.githubusercontent.com/webpack/webpack/main/CODE_OF_CONDUCT.md": { "integrity": "sha512-OLJ9q6iSO652hVBkTLsMLtQnFBBTzEbFqLGyWD62nPga/0DZ9bc3oOFb5OYT8RIPzmlOX4WzK2uiLgc1NSGtBA==", "contentType": "text/plain; charset=utf-8" }, + "version": 1 +} diff --git a/test/configCases/asset-modules/http-url/errors.webpack.lock.data/http_localhost_9990/fallback_4972219bd28762fbfd18.js b/test/configCases/asset-modules/http-url/errors.webpack.lock.data/http_localhost_9990/fallback_4972219bd28762fbfd18.js new file mode 100644 index 00000000000..e5dfb6da968 --- /dev/null +++ b/test/configCases/asset-modules/http-url/errors.webpack.lock.data/http_localhost_9990/fallback_4972219bd28762fbfd18.js @@ -0,0 +1 @@ +export * from "fallback-package"; \ No newline at end of file diff --git a/test/configCases/asset-modules/http-url/errors.webpack.lock.data/http_localhost_9990/index_query_169a64b251bcdc02a084.css b/test/configCases/asset-modules/http-url/errors.webpack.lock.data/http_localhost_9990/index_query_169a64b251bcdc02a084.css new file mode 100644 index 00000000000..b978c1b5980 --- /dev/null +++ b/test/configCases/asset-modules/http-url/errors.webpack.lock.data/http_localhost_9990/index_query_169a64b251bcdc02a084.css @@ -0,0 +1 @@ +a {} \ No newline at end of file diff --git a/test/configCases/asset-modules/http-url/errors.webpack.lock.data/http_localhost_9990/redirect_d3dcf71bcf15dc29654c.js b/test/configCases/asset-modules/http-url/errors.webpack.lock.data/http_localhost_9990/redirect_d3dcf71bcf15dc29654c.js new file mode 100644 index 00000000000..d31cf81a327 --- /dev/null +++ b/test/configCases/asset-modules/http-url/errors.webpack.lock.data/http_localhost_9990/redirect_d3dcf71bcf15dc29654c.js @@ -0,0 +1 @@ +export default { ok: true }; \ No newline at end of file diff --git a/test/configCases/asset-modules/http-url/errors.webpack.lock.data/http_localhost_9990/resolve_69c3f44e55195d0c14cf.js b/test/configCases/asset-modules/http-url/errors.webpack.lock.data/http_localhost_9990/resolve_69c3f44e55195d0c14cf.js new file mode 100644 index 00000000000..7a369ecb8ec --- /dev/null +++ b/test/configCases/asset-modules/http-url/errors.webpack.lock.data/http_localhost_9990/resolve_69c3f44e55195d0c14cf.js @@ -0,0 +1 @@ +export * from "./folder/dependency.js"; \ No newline at end of file diff --git a/test/configCases/asset-modules/http-url/errors.webpack.lock.data/https_raw.githubusercontent.com/webpack_webpack_main_CODE_OF_CONDUCT_06e7b335922db99b918d.md b/test/configCases/asset-modules/http-url/errors.webpack.lock.data/https_raw.githubusercontent.com/webpack_webpack_main_CODE_OF_CONDUCT_06e7b335922db99b918d.md new file mode 100644 index 00000000000..4faf227c455 --- /dev/null +++ b/test/configCases/asset-modules/http-url/errors.webpack.lock.data/https_raw.githubusercontent.com/webpack_webpack_main_CODE_OF_CONDUCT_06e7b335922db99b918d.md @@ -0,0 +1 @@ +[Code of Conduct](https://github.com/openjs-foundation/code-and-learn/blob/master/CODE_OF_CONDUCT.md) diff --git a/test/configCases/asset-modules/http-url/frozen-verify.webpack.lock b/test/configCases/asset-modules/http-url/frozen-verify.webpack.lock new file mode 100644 index 00000000000..3ced737c148 --- /dev/null +++ b/test/configCases/asset-modules/http-url/frozen-verify.webpack.lock @@ -0,0 +1,18 @@ +{ + "http://localhost:9990/asset.txt": { "integrity": "sha512-LHT9F+2v2A6ER7DUZ0HuJDt+t03SFJoKsbkkb7MDgvJ+hT2FhXGeDmfL2g2qj1FnEGRhXWRa4nrLFb+xRH9Fmw==", "contentType": "text/css" }, + "http://localhost:9990/asset.txt?query": { "integrity": "sha512-LHT9F+2v2A6ER7DUZ0HuJDt+t03SFJoKsbkkb7MDgvJ+hT2FhXGeDmfL2g2qj1FnEGRhXWRa4nrLFb+xRH9Fmw==", "contentType": "text/css" }, + "http://localhost:9990/fallback.js": { "integrity": "sha512-BCkBS4Wb0EreudEceuobqZZwTE7SeVUJ2vVHxDQKm8xW6dGJRcUrrSWcjd/61zijOeYAW0P+boOg7u0vxrGwYg==", "contentType": "text/javascript" }, + "http://localhost:9990/folder/dependency.js": { "integrity": "sha512-N0En4W3aNPY82MPu16+50P4PqLLyPLI6l33wR2a3ue8VCRjY8RJl8erRB8ztWSEYNad7yRDPrqlYT+IBtoOA9w==", "contentType": "text/javascript" }, + "http://localhost:9990/folder/sub-dependency.js": { "integrity": "sha512-Jjmwazwmg67EwNPViCBwvSIxhENfS6gwufXoQLrB0B/JDA4v1p+p2S5Y6IGP4SzZqqVTsROlU8meD6ep3q6MTA==", "contentType": "text/javascript" }, + "http://localhost:9990/folder/sub-dependency2.js": { "integrity": "sha512-BDZKEwlnwBabeHEwmMd02NxFEjYy+QwKAKP0S8zMMesX7dUsvh11hM7LUOPPFOS+nIEFZPtnc7kFwmnojVUw5A==", "contentType": "text/javascript" }, + "http://localhost:9990/index.css?cache": { "integrity": "sha512-sqhF9JAEi5h3ziP48SBnzQnaeei8cf/pfYJBdKL4F7xdu3v5yr71eQ0kCL11/jWRFjLG4TKOudUnS/u6WLMqYw==", "contentType": "text/css" }, + "http://localhost:9990/index.css?no-cache": "no-cache", + "http://localhost:9990/index.css?query#fragment": { "integrity": "sha512-sqhF9JAEi5h3ziP48SBnzQnaeei8cf/pfYJBdKL4F7xdu3v5yr71eQ0kCL11/jWRFjLG4TKOudUnS/u6WLMqYw==", "contentType": "text/css" }, + "http://localhost:9990/redirect": { "resolved": "http://localhost:9990/redirect.js", "integrity": "sha512-BV/MK/QTq+NHRve1XpZyQ8V6cjRP/fwbtJvENRdm5C73qNYZ4i2/fw+soj7J4qxzBXMHDbvOnA6E0ShnX2hc1w==", "contentType": "text/javascript" }, + "http://localhost:9990/redirect.js": { "integrity": "sha512-BV/MK/QTq+NHRve1XpZyQ8V6cjRP/fwbtJvENRdm5C73qNYZ4i2/fw+soj7J4qxzBXMHDbvOnA6E0ShnX2hc1w==", "contentType": "text/javascript" }, + "http://localhost:9990/resolve.js": { "integrity": "sha512-6J9zBO2hXSMTO1EtXJOxSRB2nVPHCoNmNHS8an1QeehzJFc3uoBPRWu6hqHPc54gv2/QME9RBR/BXIan68virg==", "contentType": "text/javascript" }, + "http://localhost:9990/url.js": { "integrity": "sha512-Dlw99Gtp/ZRxWvGlqD2EKnvbo1i6j/slwQO4WV8RIRhYZx9ErI+rndpyDMaKykSnq20HCp5H73TJ+dtO+wDyEg==", "contentType": "text/javascript" }, + "https://raw.githubusercontent.com//webpack//webpack//main/CODE_OF_CONDUCT.md": { "resolved": "https://raw.githubusercontent.com/webpack/webpack/main/CODE_OF_CONDUCT.md", "integrity": "sha512-OLJ9q6iSO652hVBkTLsMLtQnFBBTzEbFqLGyWD62nPga/0DZ9bc3oOFb5OYT8RIPzmlOX4WzK2uiLgc1NSGtBA==", "contentType": "text/plain; charset=utf-8" }, + "https://raw.githubusercontent.com/webpack/webpack/main/CODE_OF_CONDUCT.md": { "integrity": "sha512-OLJ9q6iSO652hVBkTLsMLtQnFBBTzEbFqLGyWD62nPga/0DZ9bc3oOFb5OYT8RIPzmlOX4WzK2uiLgc1NSGtBA==", "contentType": "text/plain; charset=utf-8" }, + "version": 1 +} diff --git a/test/configCases/asset-modules/http-url/frozen-verify.webpack.lock.data/http_localhost_9990/asset_72216076a225ea0abbaa.txt b/test/configCases/asset-modules/http-url/frozen-verify.webpack.lock.data/http_localhost_9990/asset_72216076a225ea0abbaa.txt new file mode 100644 index 00000000000..5e1c309dae7 --- /dev/null +++ b/test/configCases/asset-modules/http-url/frozen-verify.webpack.lock.data/http_localhost_9990/asset_72216076a225ea0abbaa.txt @@ -0,0 +1 @@ +Hello World \ No newline at end of file diff --git a/test/configCases/asset-modules/http-url/frozen-verify.webpack.lock.data/http_localhost_9990/asset_query_590ffbc5acc20bf1dc88.txt b/test/configCases/asset-modules/http-url/frozen-verify.webpack.lock.data/http_localhost_9990/asset_query_590ffbc5acc20bf1dc88.txt new file mode 100644 index 00000000000..5e1c309dae7 --- /dev/null +++ b/test/configCases/asset-modules/http-url/frozen-verify.webpack.lock.data/http_localhost_9990/asset_query_590ffbc5acc20bf1dc88.txt @@ -0,0 +1 @@ +Hello World \ No newline at end of file diff --git a/test/configCases/asset-modules/http-url/frozen-verify.webpack.lock.data/http_localhost_9990/fallback_4972219bd28762fbfd18.js b/test/configCases/asset-modules/http-url/frozen-verify.webpack.lock.data/http_localhost_9990/fallback_4972219bd28762fbfd18.js new file mode 100644 index 00000000000..e5dfb6da968 --- /dev/null +++ b/test/configCases/asset-modules/http-url/frozen-verify.webpack.lock.data/http_localhost_9990/fallback_4972219bd28762fbfd18.js @@ -0,0 +1 @@ +export * from "fallback-package"; \ No newline at end of file diff --git a/test/configCases/asset-modules/http-url/frozen-verify.webpack.lock.data/http_localhost_9990/folder_dependency_3263dc642c8ad1171873.js b/test/configCases/asset-modules/http-url/frozen-verify.webpack.lock.data/http_localhost_9990/folder_dependency_3263dc642c8ad1171873.js new file mode 100644 index 00000000000..e3e81f78e6b --- /dev/null +++ b/test/configCases/asset-modules/http-url/frozen-verify.webpack.lock.data/http_localhost_9990/folder_dependency_3263dc642c8ad1171873.js @@ -0,0 +1,2 @@ +export * from "./sub-dependency.js"; +export * from "/folder/sub-dependency2.js"; \ No newline at end of file diff --git a/test/configCases/asset-modules/http-url/frozen-verify.webpack.lock.data/http_localhost_9990/folder_sub-dependency2_f750536150de4f4db445.js b/test/configCases/asset-modules/http-url/frozen-verify.webpack.lock.data/http_localhost_9990/folder_sub-dependency2_f750536150de4f4db445.js new file mode 100644 index 00000000000..72fdbad6cad --- /dev/null +++ b/test/configCases/asset-modules/http-url/frozen-verify.webpack.lock.data/http_localhost_9990/folder_sub-dependency2_f750536150de4f4db445.js @@ -0,0 +1 @@ +export const value2 = 42; \ No newline at end of file diff --git a/test/configCases/asset-modules/http-url/frozen-verify.webpack.lock.data/http_localhost_9990/folder_sub-dependency_a662b3b186898f776088.js b/test/configCases/asset-modules/http-url/frozen-verify.webpack.lock.data/http_localhost_9990/folder_sub-dependency_a662b3b186898f776088.js new file mode 100644 index 00000000000..b7159db4840 --- /dev/null +++ b/test/configCases/asset-modules/http-url/frozen-verify.webpack.lock.data/http_localhost_9990/folder_sub-dependency_a662b3b186898f776088.js @@ -0,0 +1 @@ +export const value = 42; \ No newline at end of file diff --git a/test/configCases/asset-modules/http-url/frozen-verify.webpack.lock.data/http_localhost_9990/index_cache_502725659b59ae63a82a.css b/test/configCases/asset-modules/http-url/frozen-verify.webpack.lock.data/http_localhost_9990/index_cache_502725659b59ae63a82a.css new file mode 100644 index 00000000000..b978c1b5980 --- /dev/null +++ b/test/configCases/asset-modules/http-url/frozen-verify.webpack.lock.data/http_localhost_9990/index_cache_502725659b59ae63a82a.css @@ -0,0 +1 @@ +a {} \ No newline at end of file diff --git a/test/configCases/asset-modules/http-url/frozen-verify.webpack.lock.data/http_localhost_9990/index_query_169a64b251bcdc02a084.css b/test/configCases/asset-modules/http-url/frozen-verify.webpack.lock.data/http_localhost_9990/index_query_169a64b251bcdc02a084.css new file mode 100644 index 00000000000..b978c1b5980 --- /dev/null +++ b/test/configCases/asset-modules/http-url/frozen-verify.webpack.lock.data/http_localhost_9990/index_query_169a64b251bcdc02a084.css @@ -0,0 +1 @@ +a {} \ No newline at end of file diff --git a/test/configCases/asset-modules/http-url/frozen-verify.webpack.lock.data/http_localhost_9990/redirect_d3dcf71bcf15dc29654c.js b/test/configCases/asset-modules/http-url/frozen-verify.webpack.lock.data/http_localhost_9990/redirect_d3dcf71bcf15dc29654c.js new file mode 100644 index 00000000000..d31cf81a327 --- /dev/null +++ b/test/configCases/asset-modules/http-url/frozen-verify.webpack.lock.data/http_localhost_9990/redirect_d3dcf71bcf15dc29654c.js @@ -0,0 +1 @@ +export default { ok: true }; \ No newline at end of file diff --git a/test/configCases/asset-modules/http-url/frozen-verify.webpack.lock.data/http_localhost_9990/resolve_69c3f44e55195d0c14cf.js b/test/configCases/asset-modules/http-url/frozen-verify.webpack.lock.data/http_localhost_9990/resolve_69c3f44e55195d0c14cf.js new file mode 100644 index 00000000000..7a369ecb8ec --- /dev/null +++ b/test/configCases/asset-modules/http-url/frozen-verify.webpack.lock.data/http_localhost_9990/resolve_69c3f44e55195d0c14cf.js @@ -0,0 +1 @@ +export * from "./folder/dependency.js"; \ No newline at end of file diff --git a/test/configCases/asset-modules/http-url/frozen-verify.webpack.lock.data/http_localhost_9990/url_cc93d527a81c32b07ab8.js b/test/configCases/asset-modules/http-url/frozen-verify.webpack.lock.data/http_localhost_9990/url_cc93d527a81c32b07ab8.js new file mode 100644 index 00000000000..1948b244cf1 --- /dev/null +++ b/test/configCases/asset-modules/http-url/frozen-verify.webpack.lock.data/http_localhost_9990/url_cc93d527a81c32b07ab8.js @@ -0,0 +1 @@ +export default new URL("asset.txt?query", import.meta.url); \ No newline at end of file diff --git a/test/configCases/asset-modules/http-url/frozen-verify.webpack.lock.data/https_raw.githubusercontent.com/webpack_webpack_main_CODE_OF_CONDUCT_06e7b335922db99b918d.md b/test/configCases/asset-modules/http-url/frozen-verify.webpack.lock.data/https_raw.githubusercontent.com/webpack_webpack_main_CODE_OF_CONDUCT_06e7b335922db99b918d.md new file mode 100644 index 00000000000..4faf227c455 --- /dev/null +++ b/test/configCases/asset-modules/http-url/frozen-verify.webpack.lock.data/https_raw.githubusercontent.com/webpack_webpack_main_CODE_OF_CONDUCT_06e7b335922db99b918d.md @@ -0,0 +1 @@ +[Code of Conduct](https://github.com/openjs-foundation/code-and-learn/blob/master/CODE_OF_CONDUCT.md) diff --git a/test/configCases/asset-modules/http-url/index.errors.js b/test/configCases/asset-modules/http-url/index.errors.js new file mode 100644 index 00000000000..ee4a379b4e2 --- /dev/null +++ b/test/configCases/asset-modules/http-url/index.errors.js @@ -0,0 +1,32 @@ +it("error when lockfile is outdated/invalid", () => { + expect(() => { + require("http://localhost:9990/index.css?cache"); + }).toThrowError(); + expect(() => { + require("http://localhost:9990/index.css?no-cache"); + }).toThrowError(); + expect(() => { + require("http://localhost:9990/index.css"); + }).toThrowError(); + expect(() => { + require("http://localhost:9990/resolve.js"); + }).toThrowError(); + expect(() => { + require("http://localhost:9990/fallback.js"); + }).toThrowError(); + expect(() => { + require("http://localhost:9990/redirect"); + }).toThrowError(); +}); + +import text from "http://localhost:9990/asset.txt?ignore"; + +it("should allow to ignore lockfile entries", () => { + expect(text.trim()).toBe("Hello World"); +}); + +import cssContent from "http://localhost:9990/index.css?query#fragment"; + +it("should use the entry with query and fragment", () => { + expect(cssContent).toBe("a {}.webpack{}"); +}); diff --git a/test/configCases/asset-modules/http-url/index.js b/test/configCases/asset-modules/http-url/index.js index 2dea8140c41..eab2d79add0 100644 --- a/test/configCases/asset-modules/http-url/index.js +++ b/test/configCases/asset-modules/http-url/index.js @@ -1,5 +1,31 @@ import cssContent from "http://localhost:9990/index.css?query#fragment"; +import noCacheCssContent from "http://localhost:9990/index.css?no-cache"; +import cachedCssContent from "http://localhost:9990/index.css?cache"; +import { value, value2 } from "http://localhost:9990/resolve.js"; +import { fallback } from "http://localhost:9990/fallback.js"; +import redirect1 from "http://localhost:9990/redirect"; +import redirect2 from "http://localhost:9990/redirect.js"; +import text from "http://localhost:9990/asset.txt"; +import textUrl from "http://localhost:9990/url.js"; +import codeOfConduct1 from "https://raw.githubusercontent.com//webpack//webpack//main/CODE_OF_CONDUCT.md"; +import codeOfConduct2 from "https://raw.githubusercontent.com/webpack/webpack/main/CODE_OF_CONDUCT.md"; it("http url request should be supported", () => { expect(cssContent).toBe("a {}.webpack{}"); + expect(noCacheCssContent).toBe("a {}.webpack{}"); + expect(cachedCssContent).toBe("a {}.webpack{}"); + expect(value).toBe(42); + expect(value2).toBe(42); + expect(fallback).toBe(42); + expect(redirect1).toEqual({ ok: true }); + expect(redirect2).toEqual({ ok: true }); + expect(redirect2).not.toBe(redirect1); + expect(text.trim()).toBe("Hello World"); + expect(textUrl instanceof URL).toBeTruthy(); + expect(textUrl.href).toMatch(/^file:\/\/.+\.txt\?query$/); +}); + +it("https url request should be supported", () => { + expect(codeOfConduct1.includes("CODE_OF_CONDUCT")).toBeTruthy(); + expect(codeOfConduct2.includes("CODE_OF_CONDUCT")).toBeTruthy(); }); diff --git a/test/configCases/asset-modules/https-url/loaders/md-loader.js b/test/configCases/asset-modules/http-url/loaders/md-loader.js similarity index 100% rename from test/configCases/asset-modules/https-url/loaders/md-loader.js rename to test/configCases/asset-modules/http-url/loaders/md-loader.js diff --git a/test/configCases/asset-modules/http-url/no-cache.webpack.lock b/test/configCases/asset-modules/http-url/no-cache.webpack.lock new file mode 100644 index 00000000000..3ced737c148 --- /dev/null +++ b/test/configCases/asset-modules/http-url/no-cache.webpack.lock @@ -0,0 +1,18 @@ +{ + "http://localhost:9990/asset.txt": { "integrity": "sha512-LHT9F+2v2A6ER7DUZ0HuJDt+t03SFJoKsbkkb7MDgvJ+hT2FhXGeDmfL2g2qj1FnEGRhXWRa4nrLFb+xRH9Fmw==", "contentType": "text/css" }, + "http://localhost:9990/asset.txt?query": { "integrity": "sha512-LHT9F+2v2A6ER7DUZ0HuJDt+t03SFJoKsbkkb7MDgvJ+hT2FhXGeDmfL2g2qj1FnEGRhXWRa4nrLFb+xRH9Fmw==", "contentType": "text/css" }, + "http://localhost:9990/fallback.js": { "integrity": "sha512-BCkBS4Wb0EreudEceuobqZZwTE7SeVUJ2vVHxDQKm8xW6dGJRcUrrSWcjd/61zijOeYAW0P+boOg7u0vxrGwYg==", "contentType": "text/javascript" }, + "http://localhost:9990/folder/dependency.js": { "integrity": "sha512-N0En4W3aNPY82MPu16+50P4PqLLyPLI6l33wR2a3ue8VCRjY8RJl8erRB8ztWSEYNad7yRDPrqlYT+IBtoOA9w==", "contentType": "text/javascript" }, + "http://localhost:9990/folder/sub-dependency.js": { "integrity": "sha512-Jjmwazwmg67EwNPViCBwvSIxhENfS6gwufXoQLrB0B/JDA4v1p+p2S5Y6IGP4SzZqqVTsROlU8meD6ep3q6MTA==", "contentType": "text/javascript" }, + "http://localhost:9990/folder/sub-dependency2.js": { "integrity": "sha512-BDZKEwlnwBabeHEwmMd02NxFEjYy+QwKAKP0S8zMMesX7dUsvh11hM7LUOPPFOS+nIEFZPtnc7kFwmnojVUw5A==", "contentType": "text/javascript" }, + "http://localhost:9990/index.css?cache": { "integrity": "sha512-sqhF9JAEi5h3ziP48SBnzQnaeei8cf/pfYJBdKL4F7xdu3v5yr71eQ0kCL11/jWRFjLG4TKOudUnS/u6WLMqYw==", "contentType": "text/css" }, + "http://localhost:9990/index.css?no-cache": "no-cache", + "http://localhost:9990/index.css?query#fragment": { "integrity": "sha512-sqhF9JAEi5h3ziP48SBnzQnaeei8cf/pfYJBdKL4F7xdu3v5yr71eQ0kCL11/jWRFjLG4TKOudUnS/u6WLMqYw==", "contentType": "text/css" }, + "http://localhost:9990/redirect": { "resolved": "http://localhost:9990/redirect.js", "integrity": "sha512-BV/MK/QTq+NHRve1XpZyQ8V6cjRP/fwbtJvENRdm5C73qNYZ4i2/fw+soj7J4qxzBXMHDbvOnA6E0ShnX2hc1w==", "contentType": "text/javascript" }, + "http://localhost:9990/redirect.js": { "integrity": "sha512-BV/MK/QTq+NHRve1XpZyQ8V6cjRP/fwbtJvENRdm5C73qNYZ4i2/fw+soj7J4qxzBXMHDbvOnA6E0ShnX2hc1w==", "contentType": "text/javascript" }, + "http://localhost:9990/resolve.js": { "integrity": "sha512-6J9zBO2hXSMTO1EtXJOxSRB2nVPHCoNmNHS8an1QeehzJFc3uoBPRWu6hqHPc54gv2/QME9RBR/BXIan68virg==", "contentType": "text/javascript" }, + "http://localhost:9990/url.js": { "integrity": "sha512-Dlw99Gtp/ZRxWvGlqD2EKnvbo1i6j/slwQO4WV8RIRhYZx9ErI+rndpyDMaKykSnq20HCp5H73TJ+dtO+wDyEg==", "contentType": "text/javascript" }, + "https://raw.githubusercontent.com//webpack//webpack//main/CODE_OF_CONDUCT.md": { "resolved": "https://raw.githubusercontent.com/webpack/webpack/main/CODE_OF_CONDUCT.md", "integrity": "sha512-OLJ9q6iSO652hVBkTLsMLtQnFBBTzEbFqLGyWD62nPga/0DZ9bc3oOFb5OYT8RIPzmlOX4WzK2uiLgc1NSGtBA==", "contentType": "text/plain; charset=utf-8" }, + "https://raw.githubusercontent.com/webpack/webpack/main/CODE_OF_CONDUCT.md": { "integrity": "sha512-OLJ9q6iSO652hVBkTLsMLtQnFBBTzEbFqLGyWD62nPga/0DZ9bc3oOFb5OYT8RIPzmlOX4WzK2uiLgc1NSGtBA==", "contentType": "text/plain; charset=utf-8" }, + "version": 1 +} diff --git a/test/configCases/asset-modules/http-url/node_modules/fallback-package.js b/test/configCases/asset-modules/http-url/node_modules/fallback-package.js new file mode 100644 index 00000000000..fb9f84be363 --- /dev/null +++ b/test/configCases/asset-modules/http-url/node_modules/fallback-package.js @@ -0,0 +1 @@ +export const fallback = 42; diff --git a/test/configCases/asset-modules/http-url/prod-defaults.webpack.lock b/test/configCases/asset-modules/http-url/prod-defaults.webpack.lock new file mode 100644 index 00000000000..3ced737c148 --- /dev/null +++ b/test/configCases/asset-modules/http-url/prod-defaults.webpack.lock @@ -0,0 +1,18 @@ +{ + "http://localhost:9990/asset.txt": { "integrity": "sha512-LHT9F+2v2A6ER7DUZ0HuJDt+t03SFJoKsbkkb7MDgvJ+hT2FhXGeDmfL2g2qj1FnEGRhXWRa4nrLFb+xRH9Fmw==", "contentType": "text/css" }, + "http://localhost:9990/asset.txt?query": { "integrity": "sha512-LHT9F+2v2A6ER7DUZ0HuJDt+t03SFJoKsbkkb7MDgvJ+hT2FhXGeDmfL2g2qj1FnEGRhXWRa4nrLFb+xRH9Fmw==", "contentType": "text/css" }, + "http://localhost:9990/fallback.js": { "integrity": "sha512-BCkBS4Wb0EreudEceuobqZZwTE7SeVUJ2vVHxDQKm8xW6dGJRcUrrSWcjd/61zijOeYAW0P+boOg7u0vxrGwYg==", "contentType": "text/javascript" }, + "http://localhost:9990/folder/dependency.js": { "integrity": "sha512-N0En4W3aNPY82MPu16+50P4PqLLyPLI6l33wR2a3ue8VCRjY8RJl8erRB8ztWSEYNad7yRDPrqlYT+IBtoOA9w==", "contentType": "text/javascript" }, + "http://localhost:9990/folder/sub-dependency.js": { "integrity": "sha512-Jjmwazwmg67EwNPViCBwvSIxhENfS6gwufXoQLrB0B/JDA4v1p+p2S5Y6IGP4SzZqqVTsROlU8meD6ep3q6MTA==", "contentType": "text/javascript" }, + "http://localhost:9990/folder/sub-dependency2.js": { "integrity": "sha512-BDZKEwlnwBabeHEwmMd02NxFEjYy+QwKAKP0S8zMMesX7dUsvh11hM7LUOPPFOS+nIEFZPtnc7kFwmnojVUw5A==", "contentType": "text/javascript" }, + "http://localhost:9990/index.css?cache": { "integrity": "sha512-sqhF9JAEi5h3ziP48SBnzQnaeei8cf/pfYJBdKL4F7xdu3v5yr71eQ0kCL11/jWRFjLG4TKOudUnS/u6WLMqYw==", "contentType": "text/css" }, + "http://localhost:9990/index.css?no-cache": "no-cache", + "http://localhost:9990/index.css?query#fragment": { "integrity": "sha512-sqhF9JAEi5h3ziP48SBnzQnaeei8cf/pfYJBdKL4F7xdu3v5yr71eQ0kCL11/jWRFjLG4TKOudUnS/u6WLMqYw==", "contentType": "text/css" }, + "http://localhost:9990/redirect": { "resolved": "http://localhost:9990/redirect.js", "integrity": "sha512-BV/MK/QTq+NHRve1XpZyQ8V6cjRP/fwbtJvENRdm5C73qNYZ4i2/fw+soj7J4qxzBXMHDbvOnA6E0ShnX2hc1w==", "contentType": "text/javascript" }, + "http://localhost:9990/redirect.js": { "integrity": "sha512-BV/MK/QTq+NHRve1XpZyQ8V6cjRP/fwbtJvENRdm5C73qNYZ4i2/fw+soj7J4qxzBXMHDbvOnA6E0ShnX2hc1w==", "contentType": "text/javascript" }, + "http://localhost:9990/resolve.js": { "integrity": "sha512-6J9zBO2hXSMTO1EtXJOxSRB2nVPHCoNmNHS8an1QeehzJFc3uoBPRWu6hqHPc54gv2/QME9RBR/BXIan68virg==", "contentType": "text/javascript" }, + "http://localhost:9990/url.js": { "integrity": "sha512-Dlw99Gtp/ZRxWvGlqD2EKnvbo1i6j/slwQO4WV8RIRhYZx9ErI+rndpyDMaKykSnq20HCp5H73TJ+dtO+wDyEg==", "contentType": "text/javascript" }, + "https://raw.githubusercontent.com//webpack//webpack//main/CODE_OF_CONDUCT.md": { "resolved": "https://raw.githubusercontent.com/webpack/webpack/main/CODE_OF_CONDUCT.md", "integrity": "sha512-OLJ9q6iSO652hVBkTLsMLtQnFBBTzEbFqLGyWD62nPga/0DZ9bc3oOFb5OYT8RIPzmlOX4WzK2uiLgc1NSGtBA==", "contentType": "text/plain; charset=utf-8" }, + "https://raw.githubusercontent.com/webpack/webpack/main/CODE_OF_CONDUCT.md": { "integrity": "sha512-OLJ9q6iSO652hVBkTLsMLtQnFBBTzEbFqLGyWD62nPga/0DZ9bc3oOFb5OYT8RIPzmlOX4WzK2uiLgc1NSGtBA==", "contentType": "text/plain; charset=utf-8" }, + "version": 1 +} diff --git a/test/configCases/asset-modules/http-url/prod-defaults.webpack.lock.data/http_localhost_9990/asset_72216076a225ea0abbaa.txt b/test/configCases/asset-modules/http-url/prod-defaults.webpack.lock.data/http_localhost_9990/asset_72216076a225ea0abbaa.txt new file mode 100644 index 00000000000..5e1c309dae7 --- /dev/null +++ b/test/configCases/asset-modules/http-url/prod-defaults.webpack.lock.data/http_localhost_9990/asset_72216076a225ea0abbaa.txt @@ -0,0 +1 @@ +Hello World \ No newline at end of file diff --git a/test/configCases/asset-modules/http-url/prod-defaults.webpack.lock.data/http_localhost_9990/asset_query_590ffbc5acc20bf1dc88.txt b/test/configCases/asset-modules/http-url/prod-defaults.webpack.lock.data/http_localhost_9990/asset_query_590ffbc5acc20bf1dc88.txt new file mode 100644 index 00000000000..5e1c309dae7 --- /dev/null +++ b/test/configCases/asset-modules/http-url/prod-defaults.webpack.lock.data/http_localhost_9990/asset_query_590ffbc5acc20bf1dc88.txt @@ -0,0 +1 @@ +Hello World \ No newline at end of file diff --git a/test/configCases/asset-modules/http-url/prod-defaults.webpack.lock.data/http_localhost_9990/fallback_4972219bd28762fbfd18.js b/test/configCases/asset-modules/http-url/prod-defaults.webpack.lock.data/http_localhost_9990/fallback_4972219bd28762fbfd18.js new file mode 100644 index 00000000000..e5dfb6da968 --- /dev/null +++ b/test/configCases/asset-modules/http-url/prod-defaults.webpack.lock.data/http_localhost_9990/fallback_4972219bd28762fbfd18.js @@ -0,0 +1 @@ +export * from "fallback-package"; \ No newline at end of file diff --git a/test/configCases/asset-modules/http-url/prod-defaults.webpack.lock.data/http_localhost_9990/folder_dependency_3263dc642c8ad1171873.js b/test/configCases/asset-modules/http-url/prod-defaults.webpack.lock.data/http_localhost_9990/folder_dependency_3263dc642c8ad1171873.js new file mode 100644 index 00000000000..e3e81f78e6b --- /dev/null +++ b/test/configCases/asset-modules/http-url/prod-defaults.webpack.lock.data/http_localhost_9990/folder_dependency_3263dc642c8ad1171873.js @@ -0,0 +1,2 @@ +export * from "./sub-dependency.js"; +export * from "/folder/sub-dependency2.js"; \ No newline at end of file diff --git a/test/configCases/asset-modules/http-url/prod-defaults.webpack.lock.data/http_localhost_9990/folder_sub-dependency2_f750536150de4f4db445.js b/test/configCases/asset-modules/http-url/prod-defaults.webpack.lock.data/http_localhost_9990/folder_sub-dependency2_f750536150de4f4db445.js new file mode 100644 index 00000000000..72fdbad6cad --- /dev/null +++ b/test/configCases/asset-modules/http-url/prod-defaults.webpack.lock.data/http_localhost_9990/folder_sub-dependency2_f750536150de4f4db445.js @@ -0,0 +1 @@ +export const value2 = 42; \ No newline at end of file diff --git a/test/configCases/asset-modules/http-url/prod-defaults.webpack.lock.data/http_localhost_9990/folder_sub-dependency_a662b3b186898f776088.js b/test/configCases/asset-modules/http-url/prod-defaults.webpack.lock.data/http_localhost_9990/folder_sub-dependency_a662b3b186898f776088.js new file mode 100644 index 00000000000..b7159db4840 --- /dev/null +++ b/test/configCases/asset-modules/http-url/prod-defaults.webpack.lock.data/http_localhost_9990/folder_sub-dependency_a662b3b186898f776088.js @@ -0,0 +1 @@ +export const value = 42; \ No newline at end of file diff --git a/test/configCases/asset-modules/http-url/prod-defaults.webpack.lock.data/http_localhost_9990/index_cache_502725659b59ae63a82a.css b/test/configCases/asset-modules/http-url/prod-defaults.webpack.lock.data/http_localhost_9990/index_cache_502725659b59ae63a82a.css new file mode 100644 index 00000000000..b978c1b5980 --- /dev/null +++ b/test/configCases/asset-modules/http-url/prod-defaults.webpack.lock.data/http_localhost_9990/index_cache_502725659b59ae63a82a.css @@ -0,0 +1 @@ +a {} \ No newline at end of file diff --git a/test/configCases/asset-modules/http-url/prod-defaults.webpack.lock.data/http_localhost_9990/index_query_169a64b251bcdc02a084.css b/test/configCases/asset-modules/http-url/prod-defaults.webpack.lock.data/http_localhost_9990/index_query_169a64b251bcdc02a084.css new file mode 100644 index 00000000000..b978c1b5980 --- /dev/null +++ b/test/configCases/asset-modules/http-url/prod-defaults.webpack.lock.data/http_localhost_9990/index_query_169a64b251bcdc02a084.css @@ -0,0 +1 @@ +a {} \ No newline at end of file diff --git a/test/configCases/asset-modules/http-url/prod-defaults.webpack.lock.data/http_localhost_9990/redirect_d3dcf71bcf15dc29654c.js b/test/configCases/asset-modules/http-url/prod-defaults.webpack.lock.data/http_localhost_9990/redirect_d3dcf71bcf15dc29654c.js new file mode 100644 index 00000000000..d31cf81a327 --- /dev/null +++ b/test/configCases/asset-modules/http-url/prod-defaults.webpack.lock.data/http_localhost_9990/redirect_d3dcf71bcf15dc29654c.js @@ -0,0 +1 @@ +export default { ok: true }; \ No newline at end of file diff --git a/test/configCases/asset-modules/http-url/prod-defaults.webpack.lock.data/http_localhost_9990/resolve_69c3f44e55195d0c14cf.js b/test/configCases/asset-modules/http-url/prod-defaults.webpack.lock.data/http_localhost_9990/resolve_69c3f44e55195d0c14cf.js new file mode 100644 index 00000000000..7a369ecb8ec --- /dev/null +++ b/test/configCases/asset-modules/http-url/prod-defaults.webpack.lock.data/http_localhost_9990/resolve_69c3f44e55195d0c14cf.js @@ -0,0 +1 @@ +export * from "./folder/dependency.js"; \ No newline at end of file diff --git a/test/configCases/asset-modules/http-url/prod-defaults.webpack.lock.data/http_localhost_9990/url_cc93d527a81c32b07ab8.js b/test/configCases/asset-modules/http-url/prod-defaults.webpack.lock.data/http_localhost_9990/url_cc93d527a81c32b07ab8.js new file mode 100644 index 00000000000..1948b244cf1 --- /dev/null +++ b/test/configCases/asset-modules/http-url/prod-defaults.webpack.lock.data/http_localhost_9990/url_cc93d527a81c32b07ab8.js @@ -0,0 +1 @@ +export default new URL("asset.txt?query", import.meta.url); \ No newline at end of file diff --git a/test/configCases/asset-modules/http-url/prod-defaults.webpack.lock.data/https_raw.githubusercontent.com/webpack_webpack_main_CODE_OF_CONDUCT_06e7b335922db99b918d.md b/test/configCases/asset-modules/http-url/prod-defaults.webpack.lock.data/https_raw.githubusercontent.com/webpack_webpack_main_CODE_OF_CONDUCT_06e7b335922db99b918d.md new file mode 100644 index 00000000000..4faf227c455 --- /dev/null +++ b/test/configCases/asset-modules/http-url/prod-defaults.webpack.lock.data/https_raw.githubusercontent.com/webpack_webpack_main_CODE_OF_CONDUCT_06e7b335922db99b918d.md @@ -0,0 +1 @@ +[Code of Conduct](https://github.com/openjs-foundation/code-and-learn/blob/master/CODE_OF_CONDUCT.md) diff --git a/test/configCases/asset-modules/http-url/server/asset.txt b/test/configCases/asset-modules/http-url/server/asset.txt new file mode 100644 index 00000000000..557db03de99 --- /dev/null +++ b/test/configCases/asset-modules/http-url/server/asset.txt @@ -0,0 +1 @@ +Hello World diff --git a/test/configCases/asset-modules/http-url/server/fallback.js b/test/configCases/asset-modules/http-url/server/fallback.js new file mode 100644 index 00000000000..4dda52bd88e --- /dev/null +++ b/test/configCases/asset-modules/http-url/server/fallback.js @@ -0,0 +1 @@ +export * from "fallback-package"; diff --git a/test/configCases/asset-modules/http-url/server/folder/dependency.js b/test/configCases/asset-modules/http-url/server/folder/dependency.js new file mode 100644 index 00000000000..aaefe3bf362 --- /dev/null +++ b/test/configCases/asset-modules/http-url/server/folder/dependency.js @@ -0,0 +1,2 @@ +export * from "./sub-dependency.js"; +export * from "/folder/sub-dependency2.js"; diff --git a/test/configCases/asset-modules/http-url/server/folder/sub-dependency.js b/test/configCases/asset-modules/http-url/server/folder/sub-dependency.js new file mode 100644 index 00000000000..46d3ca8c61f --- /dev/null +++ b/test/configCases/asset-modules/http-url/server/folder/sub-dependency.js @@ -0,0 +1 @@ +export const value = 42; diff --git a/test/configCases/asset-modules/http-url/server/folder/sub-dependency2.js b/test/configCases/asset-modules/http-url/server/folder/sub-dependency2.js new file mode 100644 index 00000000000..0eb474a6b3f --- /dev/null +++ b/test/configCases/asset-modules/http-url/server/folder/sub-dependency2.js @@ -0,0 +1 @@ +export const value2 = 42; diff --git a/test/configCases/asset-modules/http-url/server/index.js b/test/configCases/asset-modules/http-url/server/index.js index e48a3072fce..46ee3e21965 100644 --- a/test/configCases/asset-modules/http-url/server/index.js +++ b/test/configCases/asset-modules/http-url/server/index.js @@ -1,31 +1,44 @@ const http = require("http"); const fs = require("fs"); +const path = require("path"); /** - * @param {number} port port - * @returns {Promise} server instance + * @returns {import("http").Server} server instance */ -function createServer(port) { - const file = fs.readFileSync("./test/configCases/asset-modules/http-url/server/index.css").toString().trim(); - +function createServer() { const server = http.createServer((req, res) => { - if (req.url !== "/index.css") { - res.statusCode = 404; - res.end(); + let file; + const pathname = "." + req.url.replace(/\?.*$/, ""); + if (req.url.endsWith("?no-cache")) { + res.setHeader("Cache-Control", "no-cache, max-age=60"); } else { - res.end(file); + res.setHeader("Cache-Control", "public, immutable, max-age=600"); } - }); - - return new Promise((resolve, reject) => { - server.listen(port, (err) => { - if (err) { - reject(err); - } else { - resolve(server); + try { + file = fs + .readFileSync(path.resolve(__dirname, pathname)) + .toString() + .replace(/\r\n?/g, "\n") + .trim(); + } catch (e) { + if (fs.existsSync(path.resolve(__dirname, pathname + ".js"))) { + res.statusCode = 301; + res.setHeader("Location", pathname.slice(1) + ".js"); + res.end(); + return; } - }); + res.statusCode = 404; + res.end(); + return; + } + res.setHeader( + "Content-Type", + pathname.endsWith(".js") ? "text/javascript" : "text/css" + ); + res.end(file); }); + server.unref(); + return server; } class ServerPlugin { @@ -34,27 +47,41 @@ class ServerPlugin { */ constructor(port) { this.port = port; + this.refs = 0; + this.server = undefined; } /** * @param {import("../../../../../").Compiler} compiler */ apply(compiler) { - const serverPromise = createServer(this.port); - - serverPromise - .then(server => server.unref()); + compiler.hooks.beforeRun.tapPromise( + "ServerPlugin", + async (compiler, callback) => { + this.refs++; + if (!this.server) { + this.server = createServer(); + await new Promise((resolve, reject) => { + this.server.listen(this.port, err => { + if (err) { + reject(err); + } else { + resolve(); + } + }); + }); + } + } + ); compiler.hooks.done.tapAsync("ServerPlugin", (stats, callback) => { - serverPromise - .then(server => server.close(callback)) - .catch(callback) - }); - - compiler.hooks.beforeRun.tapAsync("ServerPlugin", (compiler, callback) => { - serverPromise - .then(() => callback()) - .catch(callback) + const s = this.server; + if (s && --this.refs === 0) { + this.server = undefined; + s.close(callback); + } else { + callback(); + } }); } } diff --git a/test/configCases/asset-modules/http-url/server/redirect.js b/test/configCases/asset-modules/http-url/server/redirect.js new file mode 100644 index 00000000000..47362862dc8 --- /dev/null +++ b/test/configCases/asset-modules/http-url/server/redirect.js @@ -0,0 +1 @@ +export default { ok: true }; diff --git a/test/configCases/asset-modules/http-url/server/resolve.js b/test/configCases/asset-modules/http-url/server/resolve.js new file mode 100644 index 00000000000..b181699cfe6 --- /dev/null +++ b/test/configCases/asset-modules/http-url/server/resolve.js @@ -0,0 +1 @@ +export * from "./folder/dependency.js"; diff --git a/test/configCases/asset-modules/http-url/server/url.js b/test/configCases/asset-modules/http-url/server/url.js new file mode 100644 index 00000000000..c2eaf0c491d --- /dev/null +++ b/test/configCases/asset-modules/http-url/server/url.js @@ -0,0 +1 @@ +export default new URL("asset.txt?query", import.meta.url); diff --git a/test/configCases/asset-modules/http-url/test.config.js b/test/configCases/asset-modules/http-url/test.config.js new file mode 100644 index 00000000000..718aa51dc5e --- /dev/null +++ b/test/configCases/asset-modules/http-url/test.config.js @@ -0,0 +1,19 @@ +const fs = require("fs"); +const path = require("path"); + +module.exports = { + beforeExecute() { + try { + fs.unlinkSync(path.join(__dirname, "dev-defaults.webpack.lock")); + } catch (_err) { + // Empty + } + }, + afterExecute() { + try { + fs.unlinkSync(path.join(__dirname, "dev-defaults.webpack.lock")); + } catch (_err) { + // Empty + } + } +}; diff --git a/test/configCases/asset-modules/http-url/webpack.config.js b/test/configCases/asset-modules/http-url/webpack.config.js index 4c3a2d4c161..426378bb04a 100644 --- a/test/configCases/asset-modules/http-url/webpack.config.js +++ b/test/configCases/asset-modules/http-url/webpack.config.js @@ -5,16 +5,95 @@ const { } = require("../../../../"); const ServerPlugin = require("./server"); +const serverPlugin = new ServerPlugin(9990); /** @type {import("../../../../").Configuration} */ -module.exports = { +const base = { mode: "development", module: { rules: [ { test: /\.css$/, loader: "./loaders/css-loader" + }, + { + test: /\.md$/, + loader: "./loaders/md-loader" + }, + { + test: /\.txt$/, + dependency: { not: "url" }, + type: "asset/source" } ] - }, - plugins: [new ServerPlugin(9990), new HttpUriPlugin()] + } }; + +const frozen = true; +const allowedUris = [ + "http://localhost:9990/", + "https://raw.githubusercontent.com/" +]; + +module.exports = [ + { + name: "frozen-verify", + ...base, + plugins: [ + serverPlugin, + new HttpUriPlugin({ + allowedUris, + upgrade: true, + frozen + }) + ] + }, + { + name: "dev-defaults", + ...base, + plugins: [ + serverPlugin, + new HttpUriPlugin({ + allowedUris, + upgrade: false, + frozen: false + }) + ] + }, + { + name: "prod-defaults", + ...base, + plugins: [ + serverPlugin, + new HttpUriPlugin({ + allowedUris, + upgrade: false, + frozen + }) + ] + }, + { + name: "no-cache", + ...base, + plugins: [ + serverPlugin, + new HttpUriPlugin({ + allowedUris, + cacheLocation: false, + frozen + }) + ] + }, + { + name: "errors", + ...base, + entry: "./index.errors.js", + plugins: [ + serverPlugin, + new HttpUriPlugin({ + allowedUris, + upgrade: true, + frozen: true + }) + ] + } +]; diff --git a/test/configCases/asset-modules/https-url/index.js b/test/configCases/asset-modules/https-url/index.js deleted file mode 100644 index 5f2ccb2259d..00000000000 --- a/test/configCases/asset-modules/https-url/index.js +++ /dev/null @@ -1,5 +0,0 @@ -import codeOfConduct from "https://raw.githubusercontent.com/webpack/webpack/master/CODE_OF_CONDUCT.md"; - -it("https url request should be supported", () => { - expect(codeOfConduct.includes("CODE_OF_CONDUCT")).toBeTruthy(); -}); diff --git a/test/configCases/asset-modules/input-data-url-encoding/index.js b/test/configCases/asset-modules/input-data-url-encoding/index.js new file mode 100644 index 00000000000..561c29d9516 --- /dev/null +++ b/test/configCases/asset-modules/input-data-url-encoding/index.js @@ -0,0 +1,33 @@ +it("should keep original encoding", () => { + const url = new URL( + "data:image/svg+xml;p=1;q=2,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke=\"%23343a40\" stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M2 5l6 6 6-6'/%3e%3c/svg%3e", + import.meta.url + ); + expect(url.href).toBe( + "data:image/svg+xml;p=1;q=2,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke=\"%23343a40\" stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M2 5l6 6 6-6'/%3e%3c/svg%3e" + ); +}); + +it("should work with 'image/svg+xml'", () => { + const one = new URL( + "data:image/svg+xml;base64,PHN2ZyB4bWxucz0naHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnIHZpZXdCb3g9JzAgMCAxNiAxNic+PHBhdGggZmlsbD0nbm9uZScgc3Ryb2tlPScjMzQzYTQwJyBzdHJva2UtbGluZWNhcD0ncm91bmQnIHN0cm9rZS1saW5lam9pbj0ncm91bmQnIHN0cm9rZS13aWR0aD0nMicgZD0nTTIgNWw2IDYgNi02Jy8+PC9zdmc+", + import.meta.url + ); + expect(one.href).toBe( + "data:image/svg+xml,%3Csvg%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20viewBox%3D%270%200%2016%2016%27%3E%3Cpath%20fill%3D%27none%27%20stroke%3D%27%23343a40%27%20stroke-linecap%3D%27round%27%20stroke-linejoin%3D%27round%27%20stroke-width%3D%272%27%20d%3D%27M2%205l6%206%206-6%27%2F%3E%3C%2Fsvg%3E" + ); + const two = new URL( + "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxNiAxNiI+PHBhdGggZmlsbD0ibm9uZSIgc3Ryb2tlPSIjMzQzYTQwIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiIHN0cm9rZS13aWR0aD0iMiIgZD0iTTIgNWw2IDYgNi02Ii8+PC9zdmc+", + import.meta.url + ); + expect(two.href).toBe( + "data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%2016%2016%22%3E%3Cpath%20fill%3D%22none%22%20stroke%3D%22%23343a40%22%20stroke-linecap%3D%22round%22%20stroke-linejoin%3D%22round%22%20stroke-width%3D%222%22%20d%3D%22M2%205l6%206%206-6%22%2F%3E%3C%2Fsvg%3E" + ); + const three = new URL( + "data:IMAGE/SVG+XML;param=123;base64,PHN2ZyB4bWxucz0naHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnIHZpZXdCb3g9JzAgMCAxNyAxNyc+PHBhdGggZmlsbD0nbm9uZScgc3Ryb2tlPScjMzQzYTQwJyBzdHJva2UtbGluZWNhcD0ncm91bmQnIHN0cm9rZS1saW5lam9pbj0ncm91bmQnIHN0cm9rZS13aWR0aD0nMicgZD0nTTIgNWw2IDYgNi02Jy8+PC9zdmc+", + import.meta.url + ); + expect(three.href).toBe( + "data:IMAGE/SVG+XML;param=123,%3Csvg%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20viewBox%3D%270%200%2017%2017%27%3E%3Cpath%20fill%3D%27none%27%20stroke%3D%27%23343a40%27%20stroke-linecap%3D%27round%27%20stroke-linejoin%3D%27round%27%20stroke-width%3D%272%27%20d%3D%27M2%205l6%206%206-6%27%2F%3E%3C%2Fsvg%3E" + ); +}); diff --git a/test/configCases/asset-modules/input-data-url-encoding/webpack.config.js b/test/configCases/asset-modules/input-data-url-encoding/webpack.config.js new file mode 100644 index 00000000000..dd1ef6a41d9 --- /dev/null +++ b/test/configCases/asset-modules/input-data-url-encoding/webpack.config.js @@ -0,0 +1,19 @@ +/** @type {import("../../../../").Configuration} */ +module.exports = { + mode: "development", + devtool: false, + module: { + rules: [ + { + dependency: "url", + type: "asset", + generator: { + dataUrl: { + encoding: false + } + } + } + ] + }, + target: "web" +}; diff --git a/test/configCases/asset-modules/input-data-url/index.js b/test/configCases/asset-modules/input-data-url/index.js new file mode 100644 index 00000000000..1ad4a669cc4 --- /dev/null +++ b/test/configCases/asset-modules/input-data-url/index.js @@ -0,0 +1,30 @@ +it("should allow empty urls", () => { + const url = new URL("data:,", import.meta.url); + expect(url.href).toBe("data:,"); + expect(url.protocol).toBe("data:"); + expect(url.pathname).toBe(","); +}); + +it("should allow empty urls with mimetype", () => { + const url = new URL("data:test,", import.meta.url); + expect(url.href).toBe("data:test,"); + expect(url.protocol).toBe("data:"); + expect(url.pathname).toBe("test,"); +}); + +it("should allow data urls with mimetype", () => { + const url = new URL( + "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA2MDAgNjAwIj48dGl0bGU+aWNvbi1zcXVhcmUtc21hbGw8L3RpdGxlPjxwYXRoIGZpbGw9IiNGRkYiIGQ9Ik0zMDAgLjFMNTY1IDE1MHYyOTkuOUwzMDAgNTk5LjggMzUgNDQ5LjlWMTUweiIvPjxwYXRoIGZpbGw9IiM4RUQ2RkIiIGQ9Ik01MTcuNyA0MzkuNUwzMDguOCA1NTcuOHYtOTJMNDM5IDM5NC4xbDc4LjcgNDUuNHptMTQuMy0xMi45VjE3OS40bC03Ni40IDQ0LjF2MTU5bDc2LjQgNDQuMXpNODEuNSA0MzkuNWwyMDguOSAxMTguMnYtOTJsLTEzMC4yLTcxLjYtNzguNyA0NS40em0tMTQuMy0xMi45VjE3OS40bDc2LjQgNDQuMXYxNTlsLTc2LjQgNDQuMXptOC45LTI2My4yTDI5MC40IDQyLjJ2ODlsLTEzNy4zIDc1LjUtMS4xLjYtNzUuOS00My45em00NDYuOSAwTDMwOC44IDQyLjJ2ODlMNDQ2IDIwNi44bDEuMS42IDc1LjktNDR6Ii8+PHBhdGggZmlsbD0iIzFDNzhDMCIgZD0iTTI5MC40IDQ0NC44TDE2MiAzNzQuMVYyMzQuMmwxMjguNCA3NC4xdjEzNi41em0xOC40IDBsMTI4LjQtNzAuNnYtMTQwbC0xMjguNCA3NC4xdjEzNi41ek0yOTkuNiAzMDN6bS0xMjktODVsMTI5LTcwLjlMNDI4LjUgMjE4bC0xMjguOSA3NC40LTEyOS03NC40eiIvPjwvc3ZnPgo=", + import.meta.url + ); + expect(url.protocol).toBe("data:"); + expect(url.href).toMatch(/^data:image\/svg\+xml;base64,/); +}); + +it("should allow data urls with mimetype mapped to rules", () => { + const url = new URL( + "data:image/svg+xml+external;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA2MDAgNjAwIj48dGl0bGU+aWNvbi1zcXVhcmUtc21hbGw8L3RpdGxlPjxwYXRoIGZpbGw9IiNGRkYiIGQ9Ik0zMDAgLjFMNTY1IDE1MHYyOTkuOUwzMDAgNTk5LjggMzUgNDQ5LjlWMTUweiIvPjxwYXRoIGZpbGw9IiM4RUQ2RkIiIGQ9Ik01MTcuNyA0MzkuNUwzMDguOCA1NTcuOHYtOTJMNDM5IDM5NC4xbDc4LjcgNDUuNHptMTQuMy0xMi45VjE3OS40bC03Ni40IDQ0LjF2MTU5bDc2LjQgNDQuMXpNODEuNSA0MzkuNWwyMDguOSAxMTguMnYtOTJsLTEzMC4yLTcxLjYtNzguNyA0NS40em0tMTQuMy0xMi45VjE3OS40bDc2LjQgNDQuMXYxNTlsLTc2LjQgNDQuMXptOC45LTI2My4yTDI5MC40IDQyLjJ2ODlsLTEzNy4zIDc1LjUtMS4xLjYtNzUuOS00My45em00NDYuOSAwTDMwOC44IDQyLjJ2ODlMNDQ2IDIwNi44bDEuMS42IDc1LjktNDR6Ii8+PHBhdGggZmlsbD0iIzFDNzhDMCIgZD0iTTI5MC40IDQ0NC44TDE2MiAzNzQuMVYyMzQuMmwxMjguNCA3NC4xdjEzNi41em0xOC40IDBsMTI4LjQtNzAuNnYtMTQwbC0xMjguNCA3NC4xdjEzNi41ek0yOTkuNiAzMDN6bS0xMjktODVsMTI5LTcwLjlMNDI4LjUgMjE4bC0xMjguOSA3NC40LTEyOS03NC40eiIvPjwvc3ZnPgo=", + import.meta.url + ); + expect(url.href).toMatch(/^https:\/\/test\.cases\/path\/[a-f0-9]+\.svg$/); +}); diff --git a/test/configCases/asset-modules/input-data-url/webpack.config.js b/test/configCases/asset-modules/input-data-url/webpack.config.js new file mode 100644 index 00000000000..fa4618f8037 --- /dev/null +++ b/test/configCases/asset-modules/input-data-url/webpack.config.js @@ -0,0 +1,16 @@ +/** @type {import("../../../../").Configuration} */ +module.exports = { + mode: "development", + module: { + rules: [ + { + mimetype: "image/svg+xml+external", + type: "asset/resource", + generator: { + filename: "[hash].svg" + } + } + ] + }, + target: "web" +}; diff --git a/test/configCases/asset-modules/keep-source-maps/asset.scss b/test/configCases/asset-modules/keep-source-maps/asset.scss new file mode 100644 index 00000000000..74e5c3fa9a9 --- /dev/null +++ b/test/configCases/asset-modules/keep-source-maps/asset.scss @@ -0,0 +1 @@ +body { background-color: red; } diff --git a/test/configCases/asset-modules/keep-source-maps/data/asset.css b/test/configCases/asset-modules/keep-source-maps/data/asset.css new file mode 100644 index 00000000000..26d7f9d5a51 --- /dev/null +++ b/test/configCases/asset-modules/keep-source-maps/data/asset.css @@ -0,0 +1 @@ +body{background-color:red} diff --git a/test/configCases/asset-modules/keep-source-maps/data/asset.css.map b/test/configCases/asset-modules/keep-source-maps/data/asset.css.map new file mode 100644 index 00000000000..7555b6230b6 --- /dev/null +++ b/test/configCases/asset-modules/keep-source-maps/data/asset.css.map @@ -0,0 +1 @@ +{"version":3,"sourceRoot":"","sources":["asset.scss", "data:;charset=utf-8,@import%20%22base%22;%0A%0Aa%20%7B%0A%20%20color:%20red;%0A%7D%0A", "http://example.com/index.js.map", "https://example.com/index.js.map"],"names":[],"mappings":"AAAA","file":"asset.css"} diff --git a/test/configCases/asset-modules/keep-source-maps/index.js b/test/configCases/asset-modules/keep-source-maps/index.js new file mode 100644 index 00000000000..9d16831156b --- /dev/null +++ b/test/configCases/asset-modules/keep-source-maps/index.js @@ -0,0 +1,17 @@ +it("should write asset file to output directory", function() { + const fs = require("fs"); + const path = require("path"); + const source = fs.readFileSync(path.join(__dirname, "asset.css"), "utf-8"); + expect(source).toMatch("/*# sourceMappingURL=asset.css.map*/"); +}); + +it("should write sourcemap file relative to fileContext", function() { + const fs = require("fs"); + const path = require("path"); + expect(fs.existsSync(path.join(__dirname, "asset.css.map"))).toBe(true); + const source = JSON.parse(fs.readFileSync(path.join(__dirname, "asset.css.map"), "utf-8")); + expect(source.sources[0]).toBe("webpack:///asset.scss"); + expect(source.sources[1]).toBe("data:;charset=utf-8,@import%20%22base%22;%0A%0Aa%20%7B%0A%20%20color:%20red;%0A%7D%0A"); + expect(source.sources[2]).toBe("http://example.com/index.js.map"); + expect(source.sources[3]).toBe('https://example.com/index.js.map'); +}); diff --git a/test/configCases/asset-modules/keep-source-maps/loader.js b/test/configCases/asset-modules/keep-source-maps/loader.js new file mode 100644 index 00000000000..372bf5cf22f --- /dev/null +++ b/test/configCases/asset-modules/keep-source-maps/loader.js @@ -0,0 +1,11 @@ +const fs = require("fs"); +const path = require("path"); + +/** @type {import("../../../../").LoaderDefinition<{ f(): any }>} */ +module.exports = function(_) { + // return the would-be output from SASS without needing the compiler as a dependency + const transformed = fs.readFileSync(path.join(__dirname, "data/asset.css"), { encoding: "utf8" }); + const sourceMap = fs.readFileSync(path.join(__dirname, "data/asset.css.map"), { encoding: "utf8" }); + + this.callback(null, transformed, JSON.parse(sourceMap)); +} diff --git a/test/configCases/asset-modules/keep-source-maps/webpack.config.js b/test/configCases/asset-modules/keep-source-maps/webpack.config.js new file mode 100644 index 00000000000..759e76bdd31 --- /dev/null +++ b/test/configCases/asset-modules/keep-source-maps/webpack.config.js @@ -0,0 +1,29 @@ +/** @type {import("../../../../").Configuration} */ +module.exports = { + node: { + __dirname: false, + __filename: false + }, + devtool: "source-map", + entry: { + bundle0: ["./index.js"], + asset: ["./asset.scss"] + }, + output: { + filename: "[name].js", + assetModuleFilename: "[name][ext]" + }, + module: { + rules: [ + { + test: /\.scss$/i, + type: "asset/resource", + generator: { + binary: false, + filename: pathInfo => pathInfo.filename.replace(/\.scss/gi, ".css") + }, + use: ["./loader.js"] + } + ] + } +}; diff --git a/test/configCases/asset-modules/only-hash-url/file.png b/test/configCases/asset-modules/only-hash-url/file.png new file mode 100644 index 00000000000..fb53b9dedd3 Binary files /dev/null and b/test/configCases/asset-modules/only-hash-url/file.png differ diff --git a/test/configCases/asset-modules/only-hash-url/index.js b/test/configCases/asset-modules/only-hash-url/index.js new file mode 100644 index 00000000000..5814f924032 --- /dev/null +++ b/test/configCases/asset-modules/only-hash-url/index.js @@ -0,0 +1,10 @@ +import img from "#internal"; + +it("should allow to use an URL started with '#'", () => { + const url = new URL("#test", import.meta.url); + expect(url.hash).toBe("#test"); +}); + +it("should allow to use an URL started with '#'", () => { + expect(img).toEndWith("path/images/file.png"); +}); diff --git a/test/configCases/asset-modules/only-hash-url/package.json b/test/configCases/asset-modules/only-hash-url/package.json new file mode 100644 index 00000000000..0f6e3543a3e --- /dev/null +++ b/test/configCases/asset-modules/only-hash-url/package.json @@ -0,0 +1,7 @@ +{ + "name": "pkg", + "exports": "./pkg.mjs", + "imports": { + "#internal": "./file.png" + } +} diff --git a/test/configCases/asset-modules/only-hash-url/webpack.config.js b/test/configCases/asset-modules/only-hash-url/webpack.config.js new file mode 100644 index 00000000000..0da77aa0f7a --- /dev/null +++ b/test/configCases/asset-modules/only-hash-url/webpack.config.js @@ -0,0 +1,16 @@ +/** @type {import("../../../../").Configuration} */ +module.exports = { + mode: "development", + output: { + assetModuleFilename: "images/file[ext]" + }, + module: { + rules: [ + { + test: /\.png$/, + type: "asset/resource" + } + ] + }, + target: "web" +}; diff --git a/test/configCases/asset-modules/opus/file.opuuus b/test/configCases/asset-modules/opus/file.opuuus new file mode 100644 index 00000000000..e69de29bb2d diff --git a/test/configCases/asset-modules/opus/index.js b/test/configCases/asset-modules/opus/index.js index 717c7bea282..ad63f39a0b1 100644 --- a/test/configCases/asset-modules/opus/index.js +++ b/test/configCases/asset-modules/opus/index.js @@ -1,3 +1,3 @@ it("should throw an error for unknown mimetype", () => { - if (Math.random() < 0) require("./file.opus"); + if (Math.random() < 0) require("./file.opuuus"); }); diff --git a/test/configCases/asset-modules/opus/webpack.config.js b/test/configCases/asset-modules/opus/webpack.config.js index 7e76d203b01..5a9c737db9b 100644 --- a/test/configCases/asset-modules/opus/webpack.config.js +++ b/test/configCases/asset-modules/opus/webpack.config.js @@ -4,7 +4,7 @@ module.exports = { module: { rules: [ { - test: /\.opus$/, + test: /\.opuuus$/, type: "asset" } ] diff --git a/test/configCases/asset-modules/publicPath/webpack.config.js b/test/configCases/asset-modules/publicPath/webpack.config.js index 70d5e4bf8ea..d6363ec564d 100644 --- a/test/configCases/asset-modules/publicPath/webpack.config.js +++ b/test/configCases/asset-modules/publicPath/webpack.config.js @@ -3,7 +3,10 @@ module.exports = { mode: "development", output: { publicPath: "assets/", - assetModuleFilename: "file[ext]" + assetModuleFilename: "file[ext]", + environment: { + templateLiteral: true + } }, module: { rules: [ diff --git a/test/configCases/asset-modules/query-and-custom-condition/webpack.config.js b/test/configCases/asset-modules/query-and-custom-condition/webpack.config.js index 3e775fec34e..547ac30ded9 100644 --- a/test/configCases/asset-modules/query-and-custom-condition/webpack.config.js +++ b/test/configCases/asset-modules/query-and-custom-condition/webpack.config.js @@ -7,9 +7,8 @@ module.exports = { test: /\.(png|svg|jpg)$/, type: "asset", parser: { - dataUrlCondition: (source, { filename, module }) => { - return filename.includes("?foo=bar"); - } + dataUrlCondition: (source, { filename, module }) => + filename.includes("?foo=bar") } } ] diff --git a/test/configCases/asset-modules/query/webpack.config.js b/test/configCases/asset-modules/query/webpack.config.js index 7e9116bd012..63b0636fec6 100644 --- a/test/configCases/asset-modules/query/webpack.config.js +++ b/test/configCases/asset-modules/query/webpack.config.js @@ -1,6 +1,11 @@ /** @type {import("../../../../").Configuration} */ module.exports = { mode: "development", + output: { + environment: { + templateLiteral: false + } + }, module: { rules: [ { diff --git a/test/configCases/asset-modules/resource-from-data-uri/index.js b/test/configCases/asset-modules/resource-from-data-uri/index.js new file mode 100644 index 00000000000..ad16b26e2f9 --- /dev/null +++ b/test/configCases/asset-modules/resource-from-data-uri/index.js @@ -0,0 +1,5 @@ +import asset from "data:image/svg+xml;utf8,icon-square-small" + +it("should compile with correct filename", () => { + expect(asset).toMatch(/public\/media\/\.[0-9a-zA-Z]{8}\.svg/); +}); diff --git a/test/configCases/asset-modules/resource-from-data-uri/webpack.config.js b/test/configCases/asset-modules/resource-from-data-uri/webpack.config.js new file mode 100644 index 00000000000..92bff82560f --- /dev/null +++ b/test/configCases/asset-modules/resource-from-data-uri/webpack.config.js @@ -0,0 +1,16 @@ +/** @type {import("../../../../").Configuration} */ +module.exports = { + output: { + assetModuleFilename: "media/[name].[contenthash:8][ext]", + publicPath: "public/" + }, + module: { + rules: [ + { + mimetype: "image/svg+xml", + type: "asset/resource" + } + ] + }, + target: "web" +}; diff --git a/test/configCases/asset-modules/rule-generator-outputPath/index.js b/test/configCases/asset-modules/rule-generator-outputPath/index.js new file mode 100644 index 00000000000..2995c8b6d23 --- /dev/null +++ b/test/configCases/asset-modules/rule-generator-outputPath/index.js @@ -0,0 +1,10 @@ +import url from "../_images/file.png"; +import fs from "fs"; +import path from "path"; + +it("should emit asset with module.generator.asset.outputPath", () => { + expect(url).toEqual("https://cdn/assets/file.png"); + + const emitPath = path.join(__STATS__.outputPath, "cdn-assets/file.png") + expect(fs.existsSync(emitPath)).toBe(true); +}); diff --git a/test/configCases/asset-modules/rule-generator-outputPath/webpack.config.js b/test/configCases/asset-modules/rule-generator-outputPath/webpack.config.js new file mode 100644 index 00000000000..dd65cf885dc --- /dev/null +++ b/test/configCases/asset-modules/rule-generator-outputPath/webpack.config.js @@ -0,0 +1,19 @@ +/** @type {import("../../../../").Configuration} */ +module.exports = { + mode: "development", + output: { + assetModuleFilename: "file[ext]" + }, + module: { + rules: [ + { + test: /\.png$/, + type: "asset/resource", + generator: { + publicPath: "https://cdn/assets/", + outputPath: "cdn-assets/" + } + } + ] + } +}; diff --git a/test/configCases/asset-modules/rule-generator-publicPath-override/index.js b/test/configCases/asset-modules/rule-generator-publicPath-override/index.js new file mode 100644 index 00000000000..72297579ded --- /dev/null +++ b/test/configCases/asset-modules/rule-generator-publicPath-override/index.js @@ -0,0 +1,5 @@ +import url from "../_images/file.png"; + +it("should import asset with empty string rule.generator.publicPath", () => { + expect(url).toEqual("file.png"); +}); diff --git a/test/configCases/asset-modules/rule-generator-publicPath-override/webpack.config.js b/test/configCases/asset-modules/rule-generator-publicPath-override/webpack.config.js new file mode 100644 index 00000000000..75890c52181 --- /dev/null +++ b/test/configCases/asset-modules/rule-generator-publicPath-override/webpack.config.js @@ -0,0 +1,19 @@ +/** @type {import("../../../../types").Configuration} */ +module.exports = { + mode: "development", + output: { + assetModuleFilename: "file[ext]", + publicPath: "assets/" + }, + module: { + rules: [ + { + test: /\.png$/, + type: "asset", + generator: { + publicPath: "" + } + } + ] + } +}; diff --git a/test/configCases/asset-modules/rule-generator-publicPath/index.js b/test/configCases/asset-modules/rule-generator-publicPath/index.js new file mode 100644 index 00000000000..2a95a2fc5b0 --- /dev/null +++ b/test/configCases/asset-modules/rule-generator-publicPath/index.js @@ -0,0 +1,5 @@ +import url from "../_images/file.png"; + +it("should import asset with rule.generator.publicPath", () => { + expect(url).toEqual("assets/file.png"); +}); diff --git a/test/configCases/asset-modules/rule-generator-publicPath/webpack.config.js b/test/configCases/asset-modules/rule-generator-publicPath/webpack.config.js new file mode 100644 index 00000000000..9f8072e1fa4 --- /dev/null +++ b/test/configCases/asset-modules/rule-generator-publicPath/webpack.config.js @@ -0,0 +1,18 @@ +/** @type {import("../../../../").Configuration} */ +module.exports = { + mode: "development", + output: { + assetModuleFilename: "file[ext]" + }, + module: { + rules: [ + { + test: /\.png$/, + type: "asset", + generator: { + publicPath: () => "assets/" + } + } + ] + } +}; diff --git a/test/configCases/asset-modules/unsafe-cache-13827/index.js b/test/configCases/asset-modules/unsafe-cache-13827/index.js new file mode 100644 index 00000000000..1e8a11e39c7 --- /dev/null +++ b/test/configCases/asset-modules/unsafe-cache-13827/index.js @@ -0,0 +1,5 @@ +import url from "package"; + +it("should create a data url", () => { + expect(url.protocol).toBe("data:"); +}); diff --git a/test/configCases/asset-modules/unsafe-cache-13827/node_modules/package/file.svg b/test/configCases/asset-modules/unsafe-cache-13827/node_modules/package/file.svg new file mode 100644 index 00000000000..d7b7e40b4f8 --- /dev/null +++ b/test/configCases/asset-modules/unsafe-cache-13827/node_modules/package/file.svg @@ -0,0 +1 @@ +icon-square-small diff --git a/test/configCases/asset-modules/unsafe-cache-13827/node_modules/package/index.js b/test/configCases/asset-modules/unsafe-cache-13827/node_modules/package/index.js new file mode 100644 index 00000000000..b8d757bda87 --- /dev/null +++ b/test/configCases/asset-modules/unsafe-cache-13827/node_modules/package/index.js @@ -0,0 +1 @@ +export default new URL("file.svg", import.meta.url); diff --git a/test/configCases/asset-modules/unsafe-cache-13827/webpack.config.js b/test/configCases/asset-modules/unsafe-cache-13827/webpack.config.js new file mode 100644 index 00000000000..693c302c6c7 --- /dev/null +++ b/test/configCases/asset-modules/unsafe-cache-13827/webpack.config.js @@ -0,0 +1,12 @@ +/** @type {import("../../../../").Configuration} */ +module.exports = { + mode: "development", + module: { + rules: [ + { + dependency: "url", + type: "asset" + } + ] + } +}; diff --git a/test/configCases/assets/delete-asset/infrastructure-log.js b/test/configCases/assets/delete-asset/infrastructure-log.js new file mode 100644 index 00000000000..9d9c6526e4a --- /dev/null +++ b/test/configCases/assets/delete-asset/infrastructure-log.js @@ -0,0 +1,5 @@ +module.exports = [ + // each time sets different assetsInfo object instance in webpack.config.js:54 + // this prevents hit in inmemory cache + /^Pack got invalid because of write to: TerserWebpackPlugin|bundle0\.js$/ +]; diff --git a/test/configCases/async-commons-chunk/existing-name/index.js b/test/configCases/async-commons-chunk/existing-name/index.js index b05f483e755..b953c1a09b4 100644 --- a/test/configCases/async-commons-chunk/existing-name/index.js +++ b/test/configCases/async-commons-chunk/existing-name/index.js @@ -1,11 +1,17 @@ const chunkLoadingSpy = jest.spyOn(__webpack_require__, "e"); -it("should not have duplicate chunks in blocks", function(done) { +it("should not have duplicate chunks in blocks", function (done) { + let i = 0; + const d = () => { + if (i++ >= 3) done(); + }; + // This split point should contain: a require.ensure( [], - function(require) { + function (require) { expect(require("./a")).toBe("a"); + d(); }, "a" ); @@ -14,9 +20,10 @@ it("should not have duplicate chunks in blocks", function(done) { // have it only contain b and make chunk a be an async dependency. require.ensure( [], - function(require) { + function (require) { expect(require("./a")).toBe("a"); expect(require("./b")).toBe("b"); + d(); }, "a+b" ); @@ -25,10 +32,11 @@ it("should not have duplicate chunks in blocks", function(done) { // have it only contain c and make chunks a and a+b be async dependencies. require.ensure( [], - function(require) { + function (require) { expect(require("./a")).toBe("a"); expect(require("./b")).toBe("b"); expect(require("./c")).toBe("c"); + d(); }, "a+b+c" ); @@ -46,5 +54,5 @@ it("should not have duplicate chunks in blocks", function(done) { ["a+b" /* == b */], ["a+b+c" /* == c */] ]); - done(); + d(); }); diff --git a/test/configCases/async-library/0-create-library/a.js b/test/configCases/async-library/0-create-library/a.js new file mode 100644 index 00000000000..b18b50cdba1 --- /dev/null +++ b/test/configCases/async-library/0-create-library/a.js @@ -0,0 +1 @@ +export const a = await Promise.resolve(42); diff --git a/test/configCases/async-library/0-create-library/test.config.js b/test/configCases/async-library/0-create-library/test.config.js new file mode 100644 index 00000000000..04581a81040 --- /dev/null +++ b/test/configCases/async-library/0-create-library/test.config.js @@ -0,0 +1 @@ +module.exports.noTests = true; diff --git a/test/configCases/async-library/0-create-library/webpack.config.js b/test/configCases/async-library/0-create-library/webpack.config.js new file mode 100644 index 00000000000..0f5270b0881 --- /dev/null +++ b/test/configCases/async-library/0-create-library/webpack.config.js @@ -0,0 +1,18 @@ +/** @type {import("../../../../types").Configuration} */ +module.exports = { + entry: "./a.js", + output: { + filename: "lib.js", + library: { + type: "module" + } + }, + target: "node14", + optimization: { + minimize: true + }, + experiments: { + topLevelAwait: true, + outputModule: true + } +}; diff --git a/test/configCases/async-library/1-use-library/index.js b/test/configCases/async-library/1-use-library/index.js new file mode 100644 index 00000000000..c342b51c1e2 --- /dev/null +++ b/test/configCases/async-library/1-use-library/index.js @@ -0,0 +1,5 @@ +it("should get valid export from library", () => { + return import("library").then(({ a }) => { + expect(a).toBe(42); + }); +}); diff --git a/test/configCases/async-library/1-use-library/webpack.config.js b/test/configCases/async-library/1-use-library/webpack.config.js new file mode 100644 index 00000000000..1d8496ba49e --- /dev/null +++ b/test/configCases/async-library/1-use-library/webpack.config.js @@ -0,0 +1,18 @@ +var path = require("path"); + +/** @type {function(any, any): import("../../../../types").Configuration} */ +module.exports = (env, { testPath }) => ({ + target: "node14", + output: { + chunkLoading: "import" + }, + resolve: { + alias: { + library: path.resolve(testPath, "../0-create-library/lib.js") + } + }, + experiments: { + topLevelAwait: true, + outputModule: true + } +}); diff --git a/test/configCases/async-module/environment-not-support-async-warning/index.js b/test/configCases/async-module/environment-not-support-async-warning/index.js new file mode 100644 index 00000000000..b80f6c769f1 --- /dev/null +++ b/test/configCases/async-module/environment-not-support-async-warning/index.js @@ -0,0 +1,9 @@ +it("should have warnings for environment not support async/await when using asyncModule", () => { + return import("./reexport").then(({ number, getNumber, importRequest, moduleRequest, promiseRequest }) => { + expect(number).toBe(1); + expect(getNumber()).toBe(42); + expect(importRequest).toBe("import.js"); + expect(moduleRequest).toBe("module.js"); + expect(promiseRequest).toBe("promise.js"); + }); +}); diff --git a/test/configCases/async-module/environment-not-support-async-warning/reexport.js b/test/configCases/async-module/environment-not-support-async-warning/reexport.js new file mode 100644 index 00000000000..e4c330e84fe --- /dev/null +++ b/test/configCases/async-module/environment-not-support-async-warning/reexport.js @@ -0,0 +1,5 @@ +export { default as number } from "./tla"; +export { getNumber } from "./wasm.wat" +export { default as moduleRequest } from "external-module" +export { default as importRequest } from "external-import" +export { default as promiseRequest } from "external-promise" diff --git a/test/configCases/async-module/environment-not-support-async-warning/test.filter.js b/test/configCases/async-module/environment-not-support-async-warning/test.filter.js new file mode 100644 index 00000000000..bd7f4573a77 --- /dev/null +++ b/test/configCases/async-module/environment-not-support-async-warning/test.filter.js @@ -0,0 +1,5 @@ +var supportsWebAssembly = require("../../../helpers/supportsWebAssembly"); + +module.exports = function (config) { + return supportsWebAssembly(); +}; diff --git a/test/configCases/async-module/environment-not-support-async-warning/tla.js b/test/configCases/async-module/environment-not-support-async-warning/tla.js new file mode 100644 index 00000000000..7ff47b218ac --- /dev/null +++ b/test/configCases/async-module/environment-not-support-async-warning/tla.js @@ -0,0 +1 @@ +export default await Promise.resolve(1) diff --git a/test/configCases/async-module/environment-not-support-async-warning/warnings.js b/test/configCases/async-module/environment-not-support-async-warning/warnings.js new file mode 100644 index 00000000000..e0bb2da70fe --- /dev/null +++ b/test/configCases/async-module/environment-not-support-async-warning/warnings.js @@ -0,0 +1,27 @@ +module.exports = [ + [ + { moduleName: /tla\.js/ }, + /The generated code contains 'async\/await'/, + /"topLevelAwait"/ + ], + [ + { moduleName: /external \["import\.js","request"\]/ }, + /The generated code contains 'async\/await'/, + /"external import"/ + ], + [ + { moduleName: /external \["module\.js","request"\]/ }, + /The generated code contains 'async\/await'/, + /"external module"/ + ], + [ + { moduleName: /external "Promise\.resolve\('promise\.js'\)"/ }, + /The generated code contains 'async\/await'/, + /"external promise"/ + ], + [ + { moduleName: /wasm\.wat/ }, + /The generated code contains 'async\/await'/, + /"asyncWebAssembly"/ + ] +]; diff --git a/test/configCases/async-module/environment-not-support-async-warning/wasm.wat b/test/configCases/async-module/environment-not-support-async-warning/wasm.wat new file mode 100644 index 00000000000..d8081e18c3b --- /dev/null +++ b/test/configCases/async-module/environment-not-support-async-warning/wasm.wat @@ -0,0 +1,4 @@ +(module + (func $getNumber (export "getNumber") (result i32) + (i32.const 42))) + diff --git a/test/configCases/async-module/environment-not-support-async-warning/webpack.config.js b/test/configCases/async-module/environment-not-support-async-warning/webpack.config.js new file mode 100644 index 00000000000..81f034c466e --- /dev/null +++ b/test/configCases/async-module/environment-not-support-async-warning/webpack.config.js @@ -0,0 +1,27 @@ +/** @type {import("../../../../").Configuration} */ +module.exports = { + module: { + rules: [ + { + test: /\.wat$/, + loader: "wast-loader", + type: "webassembly/async" + } + ] + }, + output: { + environment: { + dynamicImport: true, + asyncFunction: false + }, + importFunctionName: "((name) => Promise.resolve({ request: name }))" + }, + externals: { + "external-module": ["module module.js", "request"], + "external-import": ["import import.js", "request"], + "external-promise": "promise Promise.resolve('promise.js')" + }, + experiments: { + asyncWebAssembly: true + } +}; diff --git a/test/configCases/cache-dependencies/managed-items-unsafe-cache/extra.js b/test/configCases/cache-dependencies/managed-items-unsafe-cache/extra.js new file mode 100644 index 00000000000..e69de29bb2d diff --git a/test/configCases/cache-dependencies/managed-items-unsafe-cache/index.js b/test/configCases/cache-dependencies/managed-items-unsafe-cache/index.js new file mode 100644 index 00000000000..3b676a7c54d --- /dev/null +++ b/test/configCases/cache-dependencies/managed-items-unsafe-cache/index.js @@ -0,0 +1,3 @@ +import "./loader!package"; + +it("should compile and run the test in config", () => {}); diff --git a/test/configCases/cache-dependencies/managed-items-unsafe-cache/loader.js b/test/configCases/cache-dependencies/managed-items-unsafe-cache/loader.js new file mode 100644 index 00000000000..3a6935623f6 --- /dev/null +++ b/test/configCases/cache-dependencies/managed-items-unsafe-cache/loader.js @@ -0,0 +1,8 @@ +const path = require("path"); + +/** @type {import("../../../../").LoaderDefinition} */ +module.exports = function (source) { + this.addDependency(path.resolve(__dirname, "node_modules/package/extra.js")); + this.addDependency(path.resolve(__dirname, "extra.js")); + return source; +}; diff --git a/test/configCases/cache-dependencies/managed-items-unsafe-cache/node_modules/package/extra.js b/test/configCases/cache-dependencies/managed-items-unsafe-cache/node_modules/package/extra.js new file mode 100644 index 00000000000..e69de29bb2d diff --git a/test/configCases/cache-dependencies/managed-items-unsafe-cache/node_modules/package/index.js b/test/configCases/cache-dependencies/managed-items-unsafe-cache/node_modules/package/index.js new file mode 100644 index 00000000000..e69de29bb2d diff --git a/test/configCases/cache-dependencies/managed-items-unsafe-cache/node_modules/package/package.json b/test/configCases/cache-dependencies/managed-items-unsafe-cache/node_modules/package/package.json new file mode 100644 index 00000000000..75b93e3b25a --- /dev/null +++ b/test/configCases/cache-dependencies/managed-items-unsafe-cache/node_modules/package/package.json @@ -0,0 +1,4 @@ +{ + "name": "package", + "version": "1.0.0" +} diff --git a/test/configCases/cache-dependencies/managed-items-unsafe-cache/webpack.config.js b/test/configCases/cache-dependencies/managed-items-unsafe-cache/webpack.config.js new file mode 100644 index 00000000000..b9132adacad --- /dev/null +++ b/test/configCases/cache-dependencies/managed-items-unsafe-cache/webpack.config.js @@ -0,0 +1,29 @@ +const path = require("path"); + +/** @type {import("../../../../").Configuration} */ +module.exports = { + snapshot: { + managedPaths: [path.resolve(__dirname, "node_modules")] + }, + plugins: [ + compiler => { + compiler.hooks.done.tap("Test", ({ compilation }) => { + const fileDeps = Array.from(compilation.fileDependencies); + expect(fileDeps).toContain( + path.resolve(__dirname, "node_modules/package/index.js") + ); + expect(fileDeps).toContain( + path.resolve(__dirname, "node_modules/package/extra.js") + ); + expect(fileDeps).toContain( + path.resolve(__dirname, "node_modules/package/package.json") + ); + expect(fileDeps).toContain(path.resolve(__dirname, "extra.js")); + expect(fileDeps).toContain(path.resolve(__dirname, "index.js")); + }); + } + ], + module: { + unsafeCache: true + } +}; diff --git a/test/configCases/cache-dependencies/managed-items/loader.js b/test/configCases/cache-dependencies/managed-items/loader.js index 82546670808..3a6935623f6 100644 --- a/test/configCases/cache-dependencies/managed-items/loader.js +++ b/test/configCases/cache-dependencies/managed-items/loader.js @@ -1,4 +1,6 @@ const path = require("path"); + +/** @type {import("../../../../").LoaderDefinition} */ module.exports = function (source) { this.addDependency(path.resolve(__dirname, "node_modules/package/extra.js")); this.addDependency(path.resolve(__dirname, "extra.js")); diff --git a/test/configCases/cache-dependencies/managed-items/webpack.config.js b/test/configCases/cache-dependencies/managed-items/webpack.config.js index a39582ccf43..e79abba3493 100644 --- a/test/configCases/cache-dependencies/managed-items/webpack.config.js +++ b/test/configCases/cache-dependencies/managed-items/webpack.config.js @@ -23,5 +23,8 @@ module.exports = { expect(fileDeps).toContain(path.resolve(__dirname, "index.js")); }); } - ] + ], + module: { + unsafeCache: false + } }; diff --git a/test/configCases/cache-filesystem/multicompiler-mode-cache-1/index.js b/test/configCases/cache-filesystem/multicompiler-mode-cache-1/index.js new file mode 100644 index 00000000000..7fd9507bb82 --- /dev/null +++ b/test/configCases/cache-filesystem/multicompiler-mode-cache-1/index.js @@ -0,0 +1 @@ +it("should build", () => {}); diff --git a/test/configCases/cache-filesystem/multicompiler-mode-cache-1/test.filter.js b/test/configCases/cache-filesystem/multicompiler-mode-cache-1/test.filter.js new file mode 100644 index 00000000000..02c207529bd --- /dev/null +++ b/test/configCases/cache-filesystem/multicompiler-mode-cache-1/test.filter.js @@ -0,0 +1 @@ +module.exports = config => config.cache; diff --git a/test/configCases/cache-filesystem/multicompiler-mode-cache-1/webpack.config.js b/test/configCases/cache-filesystem/multicompiler-mode-cache-1/webpack.config.js new file mode 100644 index 00000000000..6de7ce1389f --- /dev/null +++ b/test/configCases/cache-filesystem/multicompiler-mode-cache-1/webpack.config.js @@ -0,0 +1,33 @@ +"use strict"; + +// default settings. should just work + +/** @type {import("../../../../").Configuration} */ +module.exports = [ + { + mode: "production", + entry: "./index", + cache: { + type: "filesystem", + name: "name2" + } + }, + { + mode: "production", + entry: "./index", + cache: { + type: "filesystem", + name: "name1" + } + }, + { + mode: "production", + entry: "./index", + cache: true + }, + { + mode: "production", + entry: "./index", + cache: true + } +]; diff --git a/test/configCases/cache-filesystem/multicompiler-mode-cache-2/index.js b/test/configCases/cache-filesystem/multicompiler-mode-cache-2/index.js new file mode 100644 index 00000000000..7fd9507bb82 --- /dev/null +++ b/test/configCases/cache-filesystem/multicompiler-mode-cache-2/index.js @@ -0,0 +1 @@ +it("should build", () => {}); diff --git a/test/configCases/cache-filesystem/multicompiler-mode-cache-2/test.filter.js b/test/configCases/cache-filesystem/multicompiler-mode-cache-2/test.filter.js new file mode 100644 index 00000000000..02c207529bd --- /dev/null +++ b/test/configCases/cache-filesystem/multicompiler-mode-cache-2/test.filter.js @@ -0,0 +1 @@ +module.exports = config => config.cache; diff --git a/test/configCases/cache-filesystem/multicompiler-mode-cache-2/webpack.config.js b/test/configCases/cache-filesystem/multicompiler-mode-cache-2/webpack.config.js new file mode 100644 index 00000000000..a829799c8c1 --- /dev/null +++ b/test/configCases/cache-filesystem/multicompiler-mode-cache-2/webpack.config.js @@ -0,0 +1,29 @@ +"use strict"; + +// no cache names + +/** @type {import("../../../../").Configuration} */ +module.exports = [ + { + mode: "production", + entry: "./index", + cache: { + type: "filesystem" + } + }, + { + mode: "production", + entry: "./index", + cache: { + type: "filesystem" + } + }, + { + name: "3rd compiler", + mode: "production", + entry: "./index", + cache: { + type: "filesystem" + } + } +]; diff --git a/test/configCases/cache-filesystem/multicompiler-mode-cache-3/index.js b/test/configCases/cache-filesystem/multicompiler-mode-cache-3/index.js new file mode 100644 index 00000000000..7fd9507bb82 --- /dev/null +++ b/test/configCases/cache-filesystem/multicompiler-mode-cache-3/index.js @@ -0,0 +1 @@ +it("should build", () => {}); diff --git a/test/configCases/cache-filesystem/multicompiler-mode-cache-3/test.filter.js b/test/configCases/cache-filesystem/multicompiler-mode-cache-3/test.filter.js new file mode 100644 index 00000000000..02c207529bd --- /dev/null +++ b/test/configCases/cache-filesystem/multicompiler-mode-cache-3/test.filter.js @@ -0,0 +1 @@ +module.exports = config => config.cache; diff --git a/test/configCases/cache-filesystem/multicompiler-mode-cache-3/warnings.js b/test/configCases/cache-filesystem/multicompiler-mode-cache-3/warnings.js new file mode 100644 index 00000000000..c6828833f80 --- /dev/null +++ b/test/configCases/cache-filesystem/multicompiler-mode-cache-3/warnings.js @@ -0,0 +1,4 @@ +module.exports = [ + /Please set unique "cache\.name" option/, + /Compiler with name "3rd compiler" doesn't use unique cache name/ +]; diff --git a/test/configCases/cache-filesystem/multicompiler-mode-cache-3/webpack.config.js b/test/configCases/cache-filesystem/multicompiler-mode-cache-3/webpack.config.js new file mode 100644 index 00000000000..f1db5fe1a45 --- /dev/null +++ b/test/configCases/cache-filesystem/multicompiler-mode-cache-3/webpack.config.js @@ -0,0 +1,58 @@ +"use strict"; + +// with explicit cache names + +/** @type {import("../../../../").Configuration} */ +module.exports = [ + { + mode: "production", + entry: "./index", + cache: { + name: "filesystem", + type: "filesystem" + }, + plugins: [ + { + apply(compiler) { + compiler.hooks.environment.tap("FixTestCachePlugin", () => { + compiler.options.cache.cacheLocation = + compiler.options.cache.cacheLocation.replace( + /filesystem$/, + "filesystem-extra-1" + ); + }); + } + } + ] + }, + { + mode: "production", + entry: "./index", + cache: { + name: "filesystem", + type: "filesystem" + }, + plugins: [ + { + apply(compiler) { + compiler.hooks.environment.tap("FixTestCachePlugin", () => { + compiler.options.cache.cacheLocation = + compiler.options.cache.cacheLocation.replace( + /filesystem$/, + "filesystem-extra-2" + ); + }); + } + } + ] + }, + { + name: "3rd compiler", + mode: "production", + entry: "./index", + cache: { + name: "filesystem", + type: "filesystem" + } + } +]; diff --git a/test/configCases/cache-filesystem/multicompiler-mode-cache-4/index.js b/test/configCases/cache-filesystem/multicompiler-mode-cache-4/index.js new file mode 100644 index 00000000000..7fd9507bb82 --- /dev/null +++ b/test/configCases/cache-filesystem/multicompiler-mode-cache-4/index.js @@ -0,0 +1 @@ +it("should build", () => {}); diff --git a/test/configCases/cache-filesystem/multicompiler-mode-cache-4/test.filter.js b/test/configCases/cache-filesystem/multicompiler-mode-cache-4/test.filter.js new file mode 100644 index 00000000000..02c207529bd --- /dev/null +++ b/test/configCases/cache-filesystem/multicompiler-mode-cache-4/test.filter.js @@ -0,0 +1 @@ +module.exports = config => config.cache; diff --git a/test/configCases/cache-filesystem/multicompiler-mode-cache-4/warnings.js b/test/configCases/cache-filesystem/multicompiler-mode-cache-4/warnings.js new file mode 100644 index 00000000000..d0bff241879 --- /dev/null +++ b/test/configCases/cache-filesystem/multicompiler-mode-cache-4/warnings.js @@ -0,0 +1 @@ +module.exports = [/Please set unique "cache\.name" option/]; diff --git a/test/configCases/cache-filesystem/multicompiler-mode-cache-4/webpack.config.js b/test/configCases/cache-filesystem/multicompiler-mode-cache-4/webpack.config.js new file mode 100644 index 00000000000..aea54cf812c --- /dev/null +++ b/test/configCases/cache-filesystem/multicompiler-mode-cache-4/webpack.config.js @@ -0,0 +1,36 @@ +"use strict"; + +// with explicit cache names + +/** @type {import("../../../../").Configuration} */ +module.exports = [ + { + mode: "production", + entry: "./index", + cache: { + name: "default", + type: "filesystem" + }, + plugins: [ + { + apply(compiler) { + compiler.hooks.environment.tap("FixTestCachePlugin", () => { + compiler.options.cache.cacheLocation = + compiler.options.cache.cacheLocation.replace( + /default$/, + "default-extra" + ); + }); + } + } + ] + }, + { + mode: "production", + entry: "./index", + cache: { + name: "default", + type: "filesystem" + } + } +]; diff --git a/test/configCases/cache-filesystem/multicompiler-mode-cache-5/index.js b/test/configCases/cache-filesystem/multicompiler-mode-cache-5/index.js new file mode 100644 index 00000000000..7fd9507bb82 --- /dev/null +++ b/test/configCases/cache-filesystem/multicompiler-mode-cache-5/index.js @@ -0,0 +1 @@ +it("should build", () => {}); diff --git a/test/configCases/cache-filesystem/multicompiler-mode-cache-5/test.filter.js b/test/configCases/cache-filesystem/multicompiler-mode-cache-5/test.filter.js new file mode 100644 index 00000000000..02c207529bd --- /dev/null +++ b/test/configCases/cache-filesystem/multicompiler-mode-cache-5/test.filter.js @@ -0,0 +1 @@ +module.exports = config => config.cache; diff --git a/test/configCases/cache-filesystem/multicompiler-mode-cache-5/webpack.config.js b/test/configCases/cache-filesystem/multicompiler-mode-cache-5/webpack.config.js new file mode 100644 index 00000000000..d285e6a9a2a --- /dev/null +++ b/test/configCases/cache-filesystem/multicompiler-mode-cache-5/webpack.config.js @@ -0,0 +1,22 @@ +"use strict"; + +// no cache names + +/** @type {import("../../../../").Configuration} */ +module.exports = [ + { + mode: "production", + entry: "./index", + cache: { + type: "filesystem", + name: "default" + } + }, + { + mode: "production", + entry: "./index", + cache: { + type: "filesystem" + } + } +]; diff --git a/test/configCases/cache-filesystem/multicompiler-mode-cache-6/index.js b/test/configCases/cache-filesystem/multicompiler-mode-cache-6/index.js new file mode 100644 index 00000000000..7fd9507bb82 --- /dev/null +++ b/test/configCases/cache-filesystem/multicompiler-mode-cache-6/index.js @@ -0,0 +1 @@ +it("should build", () => {}); diff --git a/test/configCases/cache-filesystem/multicompiler-mode-cache-6/test.filter.js b/test/configCases/cache-filesystem/multicompiler-mode-cache-6/test.filter.js new file mode 100644 index 00000000000..02c207529bd --- /dev/null +++ b/test/configCases/cache-filesystem/multicompiler-mode-cache-6/test.filter.js @@ -0,0 +1 @@ +module.exports = config => config.cache; diff --git a/test/configCases/cache-filesystem/multicompiler-mode-cache-6/webpack.config.js b/test/configCases/cache-filesystem/multicompiler-mode-cache-6/webpack.config.js new file mode 100644 index 00000000000..ee0c98d205c --- /dev/null +++ b/test/configCases/cache-filesystem/multicompiler-mode-cache-6/webpack.config.js @@ -0,0 +1,22 @@ +"use strict"; + +// no cache names + +/** @type {import("../../../../").Configuration} */ +module.exports = [ + { + mode: "production", + entry: "./index", + cache: { + type: "filesystem" + } + }, + { + mode: "production", + entry: "./index", + cache: { + type: "filesystem", + name: "default" + } + } +]; diff --git a/test/configCases/chunk-graph/issue-15173/commonAsync/index.js b/test/configCases/chunk-graph/issue-15173/commonAsync/index.js new file mode 100644 index 00000000000..35d239bab0b --- /dev/null +++ b/test/configCases/chunk-graph/issue-15173/commonAsync/index.js @@ -0,0 +1,5 @@ +import { commonUtil } from "../commonSync"; + +export function getCommonAsync() { + return commonUtil(); +} diff --git a/test/configCases/chunk-graph/issue-15173/commonSync/index.js b/test/configCases/chunk-graph/issue-15173/commonSync/index.js new file mode 100644 index 00000000000..65d10feef9a --- /dev/null +++ b/test/configCases/chunk-graph/issue-15173/commonSync/index.js @@ -0,0 +1,5 @@ +var EmptyObj = {}; + +export function commonUtil() { + return EmptyObj; +} diff --git a/test/configCases/chunk-graph/issue-15173/entries/entryA.js b/test/configCases/chunk-graph/issue-15173/entries/entryA.js new file mode 100644 index 00000000000..a09b91e2e6e --- /dev/null +++ b/test/configCases/chunk-graph/issue-15173/entries/entryA.js @@ -0,0 +1,19 @@ +import { commonUtil } from "../commonSync"; + +export default { + doSomethingInEntryA() { + return commonUtil("entryA"); + }, + getFeatureA() { + return import(/* webpackChunkName: 'featureA' */ "../featureA"); + }, + getFeatureB() { + return import(/* webpackChunkName: 'featureB' */ "../featureB"); + } +}; + +it("common async should contain self only", () => { + expect( + __STATS__.chunks.find(c => c.names.includes("commonAsync")).modules + ).toHaveLength(1); +}); diff --git a/test/configCases/chunk-graph/issue-15173/entries/entryB.js b/test/configCases/chunk-graph/issue-15173/entries/entryB.js new file mode 100644 index 00000000000..e96fa8920c5 --- /dev/null +++ b/test/configCases/chunk-graph/issue-15173/entries/entryB.js @@ -0,0 +1,10 @@ +import { commonUtil } from "../commonSync"; + +export default { + doSomethingInEntryB() { + return commonUtil("entryB"); + }, + getFeatureC() { + return import(/* webpackChunkName: 'featureC' */ "../featureC"); + } +}; diff --git a/test/configCases/chunk-graph/issue-15173/featureA/index.js b/test/configCases/chunk-graph/issue-15173/featureA/index.js new file mode 100644 index 00000000000..1da55f5d93b --- /dev/null +++ b/test/configCases/chunk-graph/issue-15173/featureA/index.js @@ -0,0 +1,5 @@ +import(/* webpackChunkName: 'commonAsync' */ "../commonAsync"); + +export function getFeatureA() { + return "featureA"; +} diff --git a/test/configCases/chunk-graph/issue-15173/featureB/index.js b/test/configCases/chunk-graph/issue-15173/featureB/index.js new file mode 100644 index 00000000000..ea15e118f38 --- /dev/null +++ b/test/configCases/chunk-graph/issue-15173/featureB/index.js @@ -0,0 +1,5 @@ +import(/* webpackChunkName: 'commonAsync' */ "../commonAsync"); + +export function getFeatureB() { + return "featureB"; +} diff --git a/test/configCases/chunk-graph/issue-15173/featureC/index.js b/test/configCases/chunk-graph/issue-15173/featureC/index.js new file mode 100644 index 00000000000..41067715217 --- /dev/null +++ b/test/configCases/chunk-graph/issue-15173/featureC/index.js @@ -0,0 +1,5 @@ +import(/* webpackChunkName: 'commonAsync' */ "../commonAsync"); + +export function getFeatureC() { + return "featuraC"; +} diff --git a/test/configCases/chunk-graph/issue-15173/test.config.js b/test/configCases/chunk-graph/issue-15173/test.config.js new file mode 100644 index 00000000000..8519d9c5e1c --- /dev/null +++ b/test/configCases/chunk-graph/issue-15173/test.config.js @@ -0,0 +1,5 @@ +module.exports = { + findBundle: function () { + return ["entryA.js"]; + } +}; diff --git a/test/configCases/chunk-graph/issue-15173/webpack.config.js b/test/configCases/chunk-graph/issue-15173/webpack.config.js new file mode 100644 index 00000000000..b5e57a94a20 --- /dev/null +++ b/test/configCases/chunk-graph/issue-15173/webpack.config.js @@ -0,0 +1,9 @@ +module.exports = { + entry: { + entryA: "./entries/entryA.js", + entryB: "./entries/entryB.js" + }, + output: { + filename: "[name].js" + } +}; diff --git a/test/configCases/chunk-graph/issue-17989/entry-a.js b/test/configCases/chunk-graph/issue-17989/entry-a.js new file mode 100644 index 00000000000..18c5225b738 --- /dev/null +++ b/test/configCases/chunk-graph/issue-17989/entry-a.js @@ -0,0 +1,10 @@ +import loadModule from "./shared" + +it("should not have a.add from entry-a + entry-b", () => { + return loadModule().then(module => { + const { arg } = module; + expect(arg).toBe(42) + expect(typeof __webpack_modules__["./util2.js"]).toBe("function") + expect(require.cache["./util2.js"]).toBe(undefined); // not loaded on __webpack_require__.c["./util2.js"] + }); +}); diff --git a/test/configCases/chunk-graph/issue-17989/entry-b.js b/test/configCases/chunk-graph/issue-17989/entry-b.js new file mode 100644 index 00000000000..f47830e8c37 --- /dev/null +++ b/test/configCases/chunk-graph/issue-17989/entry-b.js @@ -0,0 +1,17 @@ +it("should have util2.js in util chunk", () => { + return import("./shared") + .then(({ default: loadModule }) => loadModule()) + .then((module) => { + let arg = module.arg; + expect(arg).toBe(42) + expect(typeof __webpack_modules__["./util2.js"]).toBe("function") + expect(typeof require.cache["./util2.js"]).toBe("object"); // loaded on __webpack_require__.c["./util2.js"] + return arg + }) + .then(arg => { + return import("./util1").then(module => { + let res = module.f(arg); + expect(res).toBe(84); + }) + }) +}); diff --git a/test/configCases/chunk-graph/issue-17989/shared.js b/test/configCases/chunk-graph/issue-17989/shared.js new file mode 100644 index 00000000000..984113dd888 --- /dev/null +++ b/test/configCases/chunk-graph/issue-17989/shared.js @@ -0,0 +1 @@ +export default () => import("./util") diff --git a/test/configCases/chunk-graph/issue-17989/test.config.js b/test/configCases/chunk-graph/issue-17989/test.config.js new file mode 100644 index 00000000000..3fe44b616c5 --- /dev/null +++ b/test/configCases/chunk-graph/issue-17989/test.config.js @@ -0,0 +1,5 @@ +module.exports = { + findBundle: function (i, options) { + return ["a.js", "b.js"]; + } +}; diff --git a/test/configCases/chunk-graph/issue-17989/util.js b/test/configCases/chunk-graph/issue-17989/util.js new file mode 100644 index 00000000000..70f7445abfe --- /dev/null +++ b/test/configCases/chunk-graph/issue-17989/util.js @@ -0,0 +1 @@ +export { arg } from './util1' diff --git a/test/configCases/chunk-graph/issue-17989/util1.js b/test/configCases/chunk-graph/issue-17989/util1.js new file mode 100644 index 00000000000..092f75a8fc0 --- /dev/null +++ b/test/configCases/chunk-graph/issue-17989/util1.js @@ -0,0 +1,2 @@ +export const arg = 42 +export { f } from "./util2" diff --git a/test/configCases/chunk-graph/issue-17989/util2.js b/test/configCases/chunk-graph/issue-17989/util2.js new file mode 100644 index 00000000000..95e23faf57c --- /dev/null +++ b/test/configCases/chunk-graph/issue-17989/util2.js @@ -0,0 +1 @@ +export const f = a => a * 2 diff --git a/test/configCases/chunk-graph/issue-17989/webpack.config.js b/test/configCases/chunk-graph/issue-17989/webpack.config.js new file mode 100644 index 00000000000..0410aaf3e99 --- /dev/null +++ b/test/configCases/chunk-graph/issue-17989/webpack.config.js @@ -0,0 +1,17 @@ +/** @type {import("../../../../").Configuration} */ +module.exports = { + entry: { + a: "./entry-a", + b: "./entry-b" + }, + optimization: { + sideEffects: true, + providedExports: true, + usedExports: true, + concatenateModules: false, + moduleIds: "named" + }, + output: { + filename: "[name].js" + } +}; diff --git a/test/configCases/chunk-graph/issue-9634/test.config.js b/test/configCases/chunk-graph/issue-9634/test.config.js index 4f87cbec712..3fe44b616c5 100644 --- a/test/configCases/chunk-graph/issue-9634/test.config.js +++ b/test/configCases/chunk-graph/issue-9634/test.config.js @@ -1,5 +1,5 @@ module.exports = { - findBundle: function(i, options) { + findBundle: function (i, options) { return ["a.js", "b.js"]; } }; diff --git a/test/configCases/chunk-index/issue-18008/A.js b/test/configCases/chunk-index/issue-18008/A.js new file mode 100644 index 00000000000..38498ca8aab --- /dev/null +++ b/test/configCases/chunk-index/issue-18008/A.js @@ -0,0 +1,3 @@ +import './m.css' + +export default import(/* webpackChunkName: 'shared' */ './shared') diff --git a/test/configCases/chunk-index/issue-18008/B-2.js b/test/configCases/chunk-index/issue-18008/B-2.js new file mode 100644 index 00000000000..d76708775e3 --- /dev/null +++ b/test/configCases/chunk-index/issue-18008/B-2.js @@ -0,0 +1 @@ +export default import(/* webpackChunkName: 'shared' */ './shared') diff --git a/test/configCases/chunk-index/issue-18008/B.js b/test/configCases/chunk-index/issue-18008/B.js new file mode 100644 index 00000000000..06d9beae119 --- /dev/null +++ b/test/configCases/chunk-index/issue-18008/B.js @@ -0,0 +1 @@ +export default import(/* webpackChunkName: 'B-2' */ './B-2') diff --git a/test/configCases/chunk-index/issue-18008/m.css b/test/configCases/chunk-index/issue-18008/m.css new file mode 100644 index 00000000000..42109d1e8e6 --- /dev/null +++ b/test/configCases/chunk-index/issue-18008/m.css @@ -0,0 +1,3 @@ +.m { + color: red; +} \ No newline at end of file diff --git a/test/configCases/chunk-index/issue-18008/main.js b/test/configCases/chunk-index/issue-18008/main.js new file mode 100644 index 00000000000..db0004aced8 --- /dev/null +++ b/test/configCases/chunk-index/issue-18008/main.js @@ -0,0 +1,4 @@ +it('should compile', async () => { + await (await import(/* webpackChunkName: 'A' */ './A')).default + await (await import(/* webpackChunkName: 'B' */ './B')).default +}) diff --git a/test/configCases/chunk-index/issue-18008/n.css b/test/configCases/chunk-index/issue-18008/n.css new file mode 100644 index 00000000000..d98c8a002b6 --- /dev/null +++ b/test/configCases/chunk-index/issue-18008/n.css @@ -0,0 +1,3 @@ +.n { + color: red; +} \ No newline at end of file diff --git a/test/configCases/chunk-index/issue-18008/shared.js b/test/configCases/chunk-index/issue-18008/shared.js new file mode 100644 index 00000000000..fa12217397f --- /dev/null +++ b/test/configCases/chunk-index/issue-18008/shared.js @@ -0,0 +1,2 @@ +import './m.css' +import './n.css' diff --git a/test/configCases/chunk-index/issue-18008/test.config.js b/test/configCases/chunk-index/issue-18008/test.config.js new file mode 100644 index 00000000000..3ea542cb9cb --- /dev/null +++ b/test/configCases/chunk-index/issue-18008/test.config.js @@ -0,0 +1,5 @@ +module.exports = { + findBundle: function (i, options) { + return ["main.js", "A.js", "shared.js", "B.js", "B-2.js"]; + } +}; diff --git a/test/configCases/chunk-index/issue-18008/webpack.config.js b/test/configCases/chunk-index/issue-18008/webpack.config.js new file mode 100644 index 00000000000..0144aa7d610 --- /dev/null +++ b/test/configCases/chunk-index/issue-18008/webpack.config.js @@ -0,0 +1,65 @@ +/** @typedef {import("../../../../types").Compilation} Compilation */ +/** @typedef {import("../../../../types").Module} Module */ +/** @type {import("../../../../types").Configuration} */ +module.exports = { + entry: { + main: "./main.js" + }, + output: { + filename: "[name].js" + }, + optimization: { + splitChunks: false, + chunkIds: "named" + }, + plugins: [ + function () { + /** + * @param {Compilation} compilation compilation + * @returns {void} + */ + const handler = compilation => { + compilation.hooks.afterSeal.tap("testcase", () => { + const data = {}; + for (const [name, group] of compilation.namedChunkGroups) { + /** @type {Map} */ + const modules = new Map(); + for (const chunk of group.chunks) { + for (const module of compilation.chunkGraph.getChunkModulesIterable( + chunk + )) { + const preOrder = group.getModulePreOrderIndex(module); + if (typeof preOrder === "number") { + modules.set(module, preOrder); + } + } + } + const sortedModules = Array.from(modules).sort( + (a, b) => a[1] - b[1] + ); + const text = sortedModules + .map( + ([m, index]) => + `${index}: ${m.readableIdentifier( + compilation.requestShortener + )}` + ) + .join(", "); + data[`${name}Index`] = text; + } + expect(data).toEqual({ + AIndex: "0: ./A.js, 1: css ./m.css", + "B-2Index": "0: ./B-2.js", + BIndex: "0: ./B.js", + mainIndex: "0: ./main.js", + sharedIndex: "0: ./shared.js, 1: css ./m.css, 2: css ./n.css" + }); + }); + }; + this.hooks.compilation.tap("testcase", handler); + } + ], + experiments: { + css: true + } +}; diff --git a/test/configCases/chunk-index/order-multiple-entries/entry1.js b/test/configCases/chunk-index/order-multiple-entries/entry1.js index 32a5fa8c867..ff832a0bcad 100644 --- a/test/configCases/chunk-index/order-multiple-entries/entry1.js +++ b/test/configCases/chunk-index/order-multiple-entries/entry1.js @@ -1,6 +1,4 @@ import "./a"; -import(/* webpackChunkName: "async" */ "./async"); +it("should compile", () => import(/* webpackChunkName: "async" */ "./async")); import "./b"; import "./c"; - -it("should compile", () => {}); diff --git a/test/configCases/chunk-index/order-multiple-entries/entry2.js b/test/configCases/chunk-index/order-multiple-entries/entry2.js index aa9ec2317ed..92f9311d3d5 100644 --- a/test/configCases/chunk-index/order-multiple-entries/entry2.js +++ b/test/configCases/chunk-index/order-multiple-entries/entry2.js @@ -1,6 +1,4 @@ import "./c"; -import(/* webpackChunkName: "async" */ "./async"); +it("should compile", () => import(/* webpackChunkName: "async" */ "./async")); import "./b"; import "./a"; - -it("should compile", () => {}); diff --git a/test/configCases/chunk-index/order-multiple-entries/test.config.js b/test/configCases/chunk-index/order-multiple-entries/test.config.js index 65c1791bce3..7c714985915 100644 --- a/test/configCases/chunk-index/order-multiple-entries/test.config.js +++ b/test/configCases/chunk-index/order-multiple-entries/test.config.js @@ -1,5 +1,5 @@ module.exports = { - findBundle: function(i, options) { + findBundle: function (i, options) { return ["entry1.js", "entry2.js"]; } }; diff --git a/test/configCases/chunk-index/order-multiple-entries/webpack.config.js b/test/configCases/chunk-index/order-multiple-entries/webpack.config.js index 51102d0cd7b..a3cc5123886 100644 --- a/test/configCases/chunk-index/order-multiple-entries/webpack.config.js +++ b/test/configCases/chunk-index/order-multiple-entries/webpack.config.js @@ -42,12 +42,12 @@ module.exports = { } } } - const sortedModules = Array.from(modules).sort((a, b) => { - return a[1] - b[1]; - }); - const sortedModules2 = Array.from(modules2).sort((a, b) => { - return a[1] - b[1]; - }); + const sortedModules = Array.from(modules).sort( + (a, b) => a[1] - b[1] + ); + const sortedModules2 = Array.from(modules2).sort( + (a, b) => a[1] - b[1] + ); const text = sortedModules .map( ([m, index]) => @@ -64,8 +64,8 @@ module.exports = { )}` ) .join(", "); - data[name + "Index"] = text; - data[name + "Index2"] = text2; + data[`${name}Index`] = text; + data[`${name}Index2`] = text2; } expect(data).toEqual({ entry1Index: diff --git a/test/configCases/chunk-index/recalc-index/a.css b/test/configCases/chunk-index/recalc-index/a.css new file mode 100644 index 00000000000..5451a331f9c --- /dev/null +++ b/test/configCases/chunk-index/recalc-index/a.css @@ -0,0 +1,3 @@ +.a { + color: red; +} diff --git a/test/configCases/chunk-index/recalc-index/b.css b/test/configCases/chunk-index/recalc-index/b.css new file mode 100644 index 00000000000..c209e56a74e --- /dev/null +++ b/test/configCases/chunk-index/recalc-index/b.css @@ -0,0 +1,5 @@ +@import './a.css'; + +.b { + color: blue; +} diff --git a/test/configCases/chunk-index/recalc-index/dynamic.js b/test/configCases/chunk-index/recalc-index/dynamic.js new file mode 100644 index 00000000000..08cf4e01b3a --- /dev/null +++ b/test/configCases/chunk-index/recalc-index/dynamic.js @@ -0,0 +1,2 @@ +import './b.css' +import './a.css' diff --git a/test/configCases/chunk-index/recalc-index/index.js b/test/configCases/chunk-index/recalc-index/index.js new file mode 100644 index 00000000000..aedaa047530 --- /dev/null +++ b/test/configCases/chunk-index/recalc-index/index.js @@ -0,0 +1,3 @@ +it('should compile', async () => { + await import(/* webpackChunkName: 'dynamic' */ './dynamic') +}) diff --git a/test/configCases/chunk-index/recalc-index/webpack.config.js b/test/configCases/chunk-index/recalc-index/webpack.config.js new file mode 100644 index 00000000000..05b98629bec --- /dev/null +++ b/test/configCases/chunk-index/recalc-index/webpack.config.js @@ -0,0 +1,55 @@ +/** @typedef {import("../../../../types").Compilation} Compilation */ +/** @typedef {import("../../../../types").Module} Module */ +/** @type {import("../../../../types").Configuration} */ +module.exports = { + entry: { + main: "./index.js" + }, + experiments: { + css: true + }, + plugins: [ + function () { + /** + * @param {Compilation} compilation compilation + * @returns {void} + */ + const handler = compilation => { + compilation.hooks.afterSeal.tap("testcase", () => { + const data = {}; + for (const [name, group] of compilation.namedChunkGroups) { + /** @type {Map} */ + const modules = new Map(); + for (const chunk of group.chunks) { + for (const module of compilation.chunkGraph.getChunkModulesIterable( + chunk + )) { + const postOrder = group.getModulePostOrderIndex(module); + if (typeof postOrder === "number") { + modules.set(module, postOrder); + } + } + } + const sortedModules = Array.from(modules).sort( + (a, b) => a[1] - b[1] + ); + const text = sortedModules + .map( + ([m, index]) => + `${index}: ${m.readableIdentifier( + compilation.requestShortener + )}` + ) + .join(", "); + data[`${name}Index`] = text; + } + expect(data).toEqual({ + dynamicIndex: "0: css ./a.css, 1: css ./b.css, 2: ./dynamic.js", + mainIndex: "0: ./index.js" + }); + }); + }; + this.hooks.compilation.tap("testcase", handler); + } + ] +}; diff --git a/test/configCases/clean/enabled/webpack.config.js b/test/configCases/clean/enabled/webpack.config.js index ade18386541..16575014af3 100644 --- a/test/configCases/clean/enabled/webpack.config.js +++ b/test/configCases/clean/enabled/webpack.config.js @@ -10,12 +10,19 @@ module.exports = { }, plugins: [ compiler => { + let once = true; compiler.hooks.thisCompilation.tap("Test", compilation => { compilation.hooks.processAssets.tap("Test", assets => { - const outputPath = compilation.getPath(compiler.outputPath, {}); - const customDir = path.join(outputPath, "this/dir/should/be/removed"); - fs.mkdirSync(customDir, { recursive: true }); - fs.writeFileSync(path.join(customDir, "file.ext"), ""); + if (once) { + const outputPath = compilation.getPath(compiler.outputPath, {}); + const customDir = path.join( + outputPath, + "this/dir/should/be/removed" + ); + fs.mkdirSync(customDir, { recursive: true }); + fs.writeFileSync(path.join(customDir, "file.ext"), ""); + once = false; + } assets["this/dir/should/not/be/removed/file.ext"] = new RawSource(""); }); }); diff --git a/test/configCases/clean/ignore-fn/webpack.config.js b/test/configCases/clean/ignore-fn/webpack.config.js index e9a42c5c2b5..9313802ace3 100644 --- a/test/configCases/clean/ignore-fn/webpack.config.js +++ b/test/configCases/clean/ignore-fn/webpack.config.js @@ -8,24 +8,31 @@ module.exports = { output: { clean: { keep(asset) { - return asset.includes(`ignored/dir`); + return asset.includes("ignored/dir"); } } }, plugins: [ compiler => { + let once = true; compiler.hooks.thisCompilation.tap("Test", compilation => { compilation.hooks.processAssets.tap("Test", assets => { - const outputPath = compilation.getPath(compiler.outputPath, {}); - const customDir = path.join(outputPath, "this/dir/should/be/removed"); - const ignoredDir = path.join( - outputPath, - "this/is/ignored/dir/that/should/not/be/removed" - ); - fs.mkdirSync(customDir, { recursive: true }); - fs.writeFileSync(path.join(customDir, "file.ext"), ""); - fs.mkdirSync(ignoredDir, { recursive: true }); - fs.writeFileSync(path.join(ignoredDir, "file.ext"), ""); + if (once) { + const outputPath = compilation.getPath(compiler.outputPath, {}); + const customDir = path.join( + outputPath, + "this/dir/should/be/removed" + ); + const ignoredDir = path.join( + outputPath, + "this/is/ignored/dir/that/should/not/be/removed" + ); + fs.mkdirSync(customDir, { recursive: true }); + fs.writeFileSync(path.join(customDir, "file.ext"), ""); + fs.mkdirSync(ignoredDir, { recursive: true }); + fs.writeFileSync(path.join(ignoredDir, "file.ext"), ""); + once = false; + } assets["this/dir/should/not/be/removed/file.ext"] = new RawSource(""); }); }); diff --git a/test/configCases/clean/ignore-hook/webpack.config.js b/test/configCases/clean/ignore-hook/webpack.config.js index 7cdf7734043..312874b4f4d 100644 --- a/test/configCases/clean/ignore-hook/webpack.config.js +++ b/test/configCases/clean/ignore-hook/webpack.config.js @@ -11,31 +11,38 @@ module.exports = { }, plugins: [ compiler => { + let once = true; compiler.hooks.thisCompilation.tap("Test", compilation => { webpack.CleanPlugin.getCompilationHooks(compilation).keep.tap( "Test", asset => { if (/[/\\]ignored[/\\]dir[/\\]/.test(asset)) return true; - if (asset.includes(`ignored/too`)) return true; + if (asset.includes("ignored/too")) return true; } ); compilation.hooks.processAssets.tap("Test", assets => { - const outputPath = compilation.getPath(compiler.outputPath, {}); - const customDir = path.join(outputPath, "this/dir/should/be/removed"); - const ignoredDir = path.join( - outputPath, - "this/is/ignored/dir/that/should/not/be/removed" - ); - const ignoredTooDir = path.join( - outputPath, - "this/is/ignored/too/dir/that/should/not/be/removed" - ); - fs.mkdirSync(customDir, { recursive: true }); - fs.writeFileSync(path.join(customDir, "file.ext"), ""); - fs.mkdirSync(ignoredDir, { recursive: true }); - fs.writeFileSync(path.join(ignoredDir, "file.ext"), ""); - fs.mkdirSync(ignoredTooDir, { recursive: true }); - fs.writeFileSync(path.join(ignoredTooDir, "file.ext"), ""); + if (once) { + const outputPath = compilation.getPath(compiler.outputPath, {}); + const customDir = path.join( + outputPath, + "this/dir/should/be/removed" + ); + const ignoredDir = path.join( + outputPath, + "this/is/ignored/dir/that/should/not/be/removed" + ); + const ignoredTooDir = path.join( + outputPath, + "this/is/ignored/too/dir/that/should/not/be/removed" + ); + fs.mkdirSync(customDir, { recursive: true }); + fs.writeFileSync(path.join(customDir, "file.ext"), ""); + fs.mkdirSync(ignoredDir, { recursive: true }); + fs.writeFileSync(path.join(ignoredDir, "file.ext"), ""); + fs.mkdirSync(ignoredTooDir, { recursive: true }); + fs.writeFileSync(path.join(ignoredTooDir, "file.ext"), ""); + once = false; + } assets["this/dir/should/not/be/removed/file.ext"] = new RawSource(""); }); }); diff --git a/test/configCases/clean/ignore-rx/webpack.config.js b/test/configCases/clean/ignore-rx/webpack.config.js index 9a4d6abe6f1..82623ce620c 100644 --- a/test/configCases/clean/ignore-rx/webpack.config.js +++ b/test/configCases/clean/ignore-rx/webpack.config.js @@ -12,18 +12,25 @@ module.exports = { }, plugins: [ compiler => { + let once = true; compiler.hooks.thisCompilation.tap("Test", compilation => { compilation.hooks.processAssets.tap("Test", assets => { - const outputPath = compilation.getPath(compiler.outputPath, {}); - const customDir = path.join(outputPath, "this/dir/should/be/removed"); - const ignoredDir = path.join( - outputPath, - "this/is/ignored/dir/that/should/not/be/removed" - ); - fs.mkdirSync(customDir, { recursive: true }); - fs.writeFileSync(path.join(customDir, "file.ext"), ""); - fs.mkdirSync(ignoredDir, { recursive: true }); - fs.writeFileSync(path.join(ignoredDir, "file.ext"), ""); + if (once) { + const outputPath = compilation.getPath(compiler.outputPath, {}); + const customDir = path.join( + outputPath, + "this/dir/should/be/removed" + ); + const ignoredDir = path.join( + outputPath, + "this/is/ignored/dir/that/should/not/be/removed" + ); + fs.mkdirSync(customDir, { recursive: true }); + fs.writeFileSync(path.join(customDir, "file.ext"), ""); + fs.mkdirSync(ignoredDir, { recursive: true }); + fs.writeFileSync(path.join(ignoredDir, "file.ext"), ""); + once = false; + } assets["this/dir/should/not/be/removed/file.ext"] = new RawSource(""); }); }); diff --git a/test/configCases/clean/lib-manifest-plugin/index.js b/test/configCases/clean/lib-manifest-plugin/index.js new file mode 100644 index 00000000000..bbd9de4153f --- /dev/null +++ b/test/configCases/clean/lib-manifest-plugin/index.js @@ -0,0 +1 @@ +it("should compile and run the test", function() {}); diff --git a/test/configCases/clean/lib-manifest-plugin/readdir.js b/test/configCases/clean/lib-manifest-plugin/readdir.js new file mode 100644 index 00000000000..b2f404e7f74 --- /dev/null +++ b/test/configCases/clean/lib-manifest-plugin/readdir.js @@ -0,0 +1,38 @@ +const fs = require('fs'); +const path = require('path'); + +function handlePath(path) { + return path.replace(/\\/g, "/"); +} + +module.exports = function readDir(from) { + const collectedFiles = []; + const collectedDirectories = []; + const stack = [from]; + let cursor; + + while ((cursor = stack.pop())) { + const stat = fs.statSync(cursor); + + if (stat.isDirectory()) { + const items = fs.readdirSync(cursor); + + if (from !== cursor) { + const relative = path.relative(from, cursor); + collectedDirectories.push(handlePath(relative)); + } + + for (let i = 0; i < items.length; i++) { + stack.push(path.join(cursor, items[i])); + } + } else { + const relative = path.relative(from, cursor); + collectedFiles.push(handlePath(relative)); + } + } + + return { + files: collectedFiles, + directories: collectedDirectories + }; +} diff --git a/test/configCases/clean/lib-manifest-plugin/webpack.config.js b/test/configCases/clean/lib-manifest-plugin/webpack.config.js new file mode 100644 index 00000000000..0efe44f4d54 --- /dev/null +++ b/test/configCases/clean/lib-manifest-plugin/webpack.config.js @@ -0,0 +1,33 @@ +const path = require("path"); +const readDir = require("./readdir"); +const webpack = require("../../../../"); + +/** @type {import("../../../../").Configuration} */ +module.exports = { + output: { + clean: true + }, + plugins: [ + compiler => { + compiler.hooks.thisCompilation.tap("Test", compilation => { + const outputPath = compilation.getPath(compiler.outputPath, {}); + new webpack.DllPlugin({ + name: "[name]_dll", + path: path.resolve(outputPath, "manifest.json") + }).apply(compiler); + }); + compiler.hooks.afterEmit.tap("Test", compilation => { + const outputPath = compilation.getPath(compiler.outputPath, {}); + expect(readDir(outputPath)).toMatchInlineSnapshot(` + Object { + "directories": Array [], + "files": Array [ + "manifest.json", + "bundle0.js", + ], + } + `); + }); + } + ] +}; diff --git a/test/configCases/clean/link/index.js b/test/configCases/clean/link/index.js new file mode 100644 index 00000000000..bbd9de4153f --- /dev/null +++ b/test/configCases/clean/link/index.js @@ -0,0 +1 @@ +it("should compile and run the test", function() {}); diff --git a/test/configCases/clean/link/test.filter.js b/test/configCases/clean/link/test.filter.js new file mode 100644 index 00000000000..e627dbe1937 --- /dev/null +++ b/test/configCases/clean/link/test.filter.js @@ -0,0 +1,16 @@ +const fs = require("fs"); +const path = require("path"); + +module.exports = () => { + try { + fs.symlinkSync( + path.join(__dirname, "index.js"), + path.join(__dirname, ".testlink"), + "file" + ); + fs.unlinkSync(path.join(__dirname, ".testlink")); + return true; + } catch (_err) { + return false; + } +}; diff --git a/test/configCases/clean/link/webpack.config.js b/test/configCases/clean/link/webpack.config.js new file mode 100644 index 00000000000..6250f15d47b --- /dev/null +++ b/test/configCases/clean/link/webpack.config.js @@ -0,0 +1,41 @@ +const fs = require("fs"); +const path = require("path"); +const readDir = require("../enabled/readdir"); + +/** @type {import("../../../../").Configuration} */ +module.exports = { + output: { + clean: true + }, + plugins: [ + compiler => { + let once = true; + compiler.hooks.environment.tap("Test", () => { + if (once) { + const outputPath = compiler.options.output.path; + const originalPath = path.join(outputPath, "file.ext"); + fs.writeFileSync(originalPath, ""); + const customDir = path.join(outputPath, "this/dir/should/be/removed"); + fs.mkdirSync(customDir, { recursive: true }); + fs.symlinkSync( + originalPath, + path.join(customDir, "file-link.ext"), + "file" + ); + once = false; + } + }); + compiler.hooks.afterEmit.tap("Test", compilation => { + const outputPath = compilation.getPath(compiler.outputPath, {}); + expect(readDir(outputPath)).toMatchInlineSnapshot(` + Object { + "directories": Array [], + "files": Array [ + "bundle0.js", + ], + } + `); + }); + } + ] +}; diff --git a/test/configCases/code-generation/import-export-format-2/cjs-module.js b/test/configCases/code-generation/import-export-format-2/cjs-module.js new file mode 100644 index 00000000000..1286372d8b3 --- /dev/null +++ b/test/configCases/code-generation/import-export-format-2/cjs-module.js @@ -0,0 +1,3 @@ +const foo = 42; + +module.exports = { foo }; diff --git a/test/configCases/code-generation/import-export-format-2/export-default-expression.js b/test/configCases/code-generation/import-export-format-2/export-default-expression.js new file mode 100644 index 00000000000..db070255f2c --- /dev/null +++ b/test/configCases/code-generation/import-export-format-2/export-default-expression.js @@ -0,0 +1,3 @@ +const ___CSS_LOADER_EXPORT___ = {}; +___CSS_LOADER_EXPORT___.locals = {}; +export default ___CSS_LOADER_EXPORT___; diff --git a/test/configCases/code-generation/import-export-format-2/harmony-module-2.js b/test/configCases/code-generation/import-export-format-2/harmony-module-2.js new file mode 100644 index 00000000000..4cd5fd6fb2e --- /dev/null +++ b/test/configCases/code-generation/import-export-format-2/harmony-module-2.js @@ -0,0 +1,10 @@ +export const baz = 11; + +import { mod3 } from "./index"; + +function test(value) { + return value; +} + +test(mod3.apple); + diff --git a/test/configCases/code-generation/import-export-format-2/harmony-module-3.js b/test/configCases/code-generation/import-export-format-2/harmony-module-3.js new file mode 100644 index 00000000000..11dbbe78d28 --- /dev/null +++ b/test/configCases/code-generation/import-export-format-2/harmony-module-3.js @@ -0,0 +1 @@ +export var apple = 45; diff --git a/test/configCases/code-generation/import-export-format-2/harmony-module.js b/test/configCases/code-generation/import-export-format-2/harmony-module.js new file mode 100644 index 00000000000..b4f6c9f9a65 --- /dev/null +++ b/test/configCases/code-generation/import-export-format-2/harmony-module.js @@ -0,0 +1,5 @@ +export const bar = 42; + +const def = -12; +export default def; + diff --git a/test/configCases/code-generation/import-export-format-2/index.js b/test/configCases/code-generation/import-export-format-2/index.js new file mode 100644 index 00000000000..ed0e03c8b34 --- /dev/null +++ b/test/configCases/code-generation/import-export-format-2/index.js @@ -0,0 +1,50 @@ +import { foo as cjsexport_harmonyimport } from "./cjs-module"; +import theDefault, { bar as harmonyexport_harmonyimport } from "./harmony-module"; +import theDefaultExpression from "./export-default-expression"; +const { harmonyexport_cjsimport } = require("./harmony-module").bar; +const harmonyexport_cjsimportdefault = require("./export-default-expression").default; +import { baz as harmonyexport_harmonyimport_2 } from "./harmony-module-2"; + +import * as mod3 from "./harmony-module-3"; +export { mod3 }; +export { theDefaultExpression } + +const { expectSourceToContain, expectSourceToMatch } = require("../../../helpers/expectSource"); +const regexEscape = require("../../../helpers/regexEscape.js"); + +// It's important to use propertyName when generating object members to ensure that the exported property name +// uses the same accessor syntax (quotes vs. dot notatation) as the imported property name on the other end +// (which needs to use propertyAccess). Else, minifiers such as Closure Compiler will not be able to minify correctly. +it("should use the same accessor syntax for import and export", function() { + + var fs = require("fs"); + var source = fs.readFileSync(__filename, "utf-8").toString(); + + // Reference these imports to generate uses in the source. + + cjsexport_harmonyimport; + harmonyexport_harmonyimport; + harmonyexport_cjsimport; + harmonyexport_harmonyimport_2; + theDefault; + theDefaultExpression; + harmonyexport_cjsimportdefault; + + /*********** DO NOT MATCH BELOW THIS LINE ***********/ + + // Checking harmonyexportinitfragment.js formation of standard export fragment + expectSourceToContain(source, "/* harmony export */ bar: () => (/* binding */ bar)"); + + // Checking formation of imports + expectSourceToMatch(source, `${regexEscape("const { harmonyexport_cjsimport } = (__webpack_require__(/*! ./harmony-module */ ")}\\d+${regexEscape(").bar);")}`); + expectSourceToMatch(source, `${regexEscape("const harmonyexport_cjsimportdefault = (__webpack_require__(/*! ./export-default-expression */ ")}\\d+${regexEscape(")[\"default\"]);")}`); + + // Checking concatenatedmodule.js formation of exports + expectSourceToContain(source, "mod3: () => (/* reexport */ harmony_module_3_namespaceObject)"); + + // Checking concatenatedmodule.js formation of namespace objects + expectSourceToContain(source, "apple: () => (apple)"); + + // Do not break default option + expectSourceToContain(source, "[\"default\"] = (___CSS_LOADER_EXPORT___)"); +}); diff --git a/test/configCases/code-generation/import-export-format-2/webpack.config.js b/test/configCases/code-generation/import-export-format-2/webpack.config.js new file mode 100644 index 00000000000..777d038c05b --- /dev/null +++ b/test/configCases/code-generation/import-export-format-2/webpack.config.js @@ -0,0 +1,25 @@ +/** @type {import("../../../../").Configuration} */ +module.exports = { + output: { + environment: { + arrowFunction: true, + bigIntLiteral: false, + const: false, + destructuring: false, + forOf: false, + dynamicImport: true, + module: false + } + }, + node: { + __dirname: false, + __filename: false + }, + optimization: { + concatenateModules: true, + usedExports: true, + providedExports: true, + minimize: false, + mangleExports: false + } +}; diff --git a/test/configCases/code-generation/import-export-format/cjs-module.js b/test/configCases/code-generation/import-export-format/cjs-module.js new file mode 100644 index 00000000000..1286372d8b3 --- /dev/null +++ b/test/configCases/code-generation/import-export-format/cjs-module.js @@ -0,0 +1,3 @@ +const foo = 42; + +module.exports = { foo }; diff --git a/test/configCases/code-generation/import-export-format/harmony-module-2.js b/test/configCases/code-generation/import-export-format/harmony-module-2.js new file mode 100644 index 00000000000..4cd5fd6fb2e --- /dev/null +++ b/test/configCases/code-generation/import-export-format/harmony-module-2.js @@ -0,0 +1,10 @@ +export const baz = 11; + +import { mod3 } from "./index"; + +function test(value) { + return value; +} + +test(mod3.apple); + diff --git a/test/configCases/code-generation/import-export-format/harmony-module-3.js b/test/configCases/code-generation/import-export-format/harmony-module-3.js new file mode 100644 index 00000000000..11dbbe78d28 --- /dev/null +++ b/test/configCases/code-generation/import-export-format/harmony-module-3.js @@ -0,0 +1 @@ +export var apple = 45; diff --git a/test/configCases/code-generation/import-export-format/harmony-module.js b/test/configCases/code-generation/import-export-format/harmony-module.js new file mode 100644 index 00000000000..b4f6c9f9a65 --- /dev/null +++ b/test/configCases/code-generation/import-export-format/harmony-module.js @@ -0,0 +1,5 @@ +export const bar = 42; + +const def = -12; +export default def; + diff --git a/test/configCases/code-generation/import-export-format/index.js b/test/configCases/code-generation/import-export-format/index.js new file mode 100644 index 00000000000..836850d5917 --- /dev/null +++ b/test/configCases/code-generation/import-export-format/index.js @@ -0,0 +1,44 @@ +import { foo as cjsexport_harmonyimport } from "./cjs-module"; +import theDefault, { bar as harmonyexport_harmonyimport } from "./harmony-module"; +const { harmonyexport_cjsimport } = require("./harmony-module").bar; +import { baz as harmonyexport_harmonyimport_2 } from "./harmony-module-2"; + +import * as mod3 from "./harmony-module-3"; +export { mod3 }; + +const { expectSourceToContain, expectSourceToMatch } = require("../../../helpers/expectSource"); +const regexEscape = require("../../../helpers/regexEscape.js"); + +// It's important to use propertyName when generating object members to ensure that the exported property name +// uses the same accessor syntax (quotes vs. dot notatation) as the imported property name on the other end +// (which needs to use propertyAccess). Else, minifiers such as Closure Compiler will not be able to minify correctly. +it("should use the same accessor syntax for import and export", function() { + + var fs = require("fs"); + var source = fs.readFileSync(__filename, "utf-8").toString(); + + // Reference these imports to generate uses in the source. + + cjsexport_harmonyimport; + harmonyexport_harmonyimport; + harmonyexport_cjsimport; + harmonyexport_harmonyimport_2; + theDefault; + + /*********** DO NOT MATCH BELOW THIS LINE ***********/ + + // Note that there are no quotes around the "a" and "b" properties in the following lines. + + // Checking harmonyexportinitfragment.js formation of standard export fragment + expectSourceToContain(source, "/* harmony export */ a: () => (/* binding */ bar)"); + + // Checking formation of imports + expectSourceToContain(source, "harmony_module/* bar */.a;"); + expectSourceToMatch(source, `${regexEscape("const { harmonyexport_cjsimport } = (__webpack_require__(/*! ./harmony-module */ ")}\\d+${regexEscape(")/* .bar */ .a);")}`); + + // Checking concatenatedmodule.js formation of exports + expectSourceToContain(source, "a: () => (/* reexport */ harmony_module_3_namespaceObject)"); + + // Checking concatenatedmodule.js formation of namespace objects + expectSourceToContain(source, "a: () => (apple)"); +}); diff --git a/test/configCases/code-generation/import-export-format/webpack.config.js b/test/configCases/code-generation/import-export-format/webpack.config.js new file mode 100644 index 00000000000..d68b9b7d455 --- /dev/null +++ b/test/configCases/code-generation/import-export-format/webpack.config.js @@ -0,0 +1,14 @@ +/** @type {import("../../../../").Configuration} */ +module.exports = { + node: { + __dirname: false, + __filename: false + }, + optimization: { + concatenateModules: true, + usedExports: true, + providedExports: true, + minimize: false, + mangleExports: "size" + } +}; diff --git a/test/configCases/code-generation/re-export-namespace-concat/data.json b/test/configCases/code-generation/re-export-namespace-concat/data.json new file mode 100644 index 00000000000..7726aedd0c5 --- /dev/null +++ b/test/configCases/code-generation/re-export-namespace-concat/data.json @@ -0,0 +1,5 @@ +{ + "nested": { + "object3": {} + } +} diff --git a/test/configCases/code-generation/re-export-namespace-concat/index.js b/test/configCases/code-generation/re-export-namespace-concat/index.js new file mode 100644 index 00000000000..37eb0a558f5 --- /dev/null +++ b/test/configCases/code-generation/re-export-namespace-concat/index.js @@ -0,0 +1,83 @@ +import { obj1 } from './module1'; +import * as m_1 from './module1'; +import * as m_2 from './module2'; +import * as m_3 from './module3'; +import data from "./data"; + +const { expectSourceToContain } = require("../../../helpers/expectSource"); + +// It's important to preserve the same accessor syntax (quotes vs. dot notatation) after the actual export variable. +// Else, minifiers such as Closure Compiler will not be able to minify correctly in ADVANCED mode. + +it("should use/preserve accessor form for import object and namespaces", function() { + var fs = require("fs"); + var source = fs.readFileSync(__filename, "utf-8").toString(); + + // Reference the imports to generate uses in the source. + + const f = false; + if (f) { + const x1 = m_1; + const x2 = obj1; + + const z1 = obj1["plants"]; + const z2 = obj1["funcs"](); + const z3 = m_1["obj1"]["pots"]; + const z4 = m_1["obj1"]["subs"](); + + const a = m_2["m_1"].obj1["flip"].flap; + const b = m_2["m_1"]["obj1"].zip["zap"]; + const c = m_2.m_1.obj1["ding"].dong(); + const d = m_2.m_1["obj1"].sing["song"](); + + const aa = m_3["m_2"].m_1["obj1"]["zoom"]; + + const bb = obj1.up.down?.left.right; + + const ww = require('./module1').obj1["bing"]?.bang; + const xx = require('./module1').obj1["pip"].pop(); + const yy = require('./module3')["m_2"]["m_1"]["obj1"]["tip"].top(); + + data.nested.object3["unknownProperty"].depth = "deep"; + + (obj1)["aaa"].bbb; + (m_1.obj1)["ccc"].ddd; + (obj1["eee"]).fff; + (m_1.obj1["ggg"]).hhh; + (((m_1).obj1)["iii"]).jjj; + } + + /************ DO NOT MATCH BELOW THIS LINE ************/ + + // Imported objects and import namespaces should use dot notation. Any references to the properties of exports + // should be preserved as either quotes or dot notation, depending on the original source. + + expectSourceToContain(source, 'const x1 = module1;'); + expectSourceToContain(source, 'const x2 = module1.obj1;'); + + expectSourceToContain(source, 'const z1 = module1.obj1["plants"];'); + expectSourceToContain(source, 'const z2 = module1.obj1["funcs"]();'); + expectSourceToContain(source, 'const z3 = module1.obj1["pots"];'); + expectSourceToContain(source, 'const z4 = module1.obj1["subs"]();'); + + expectSourceToContain(source, 'const a = module2/* m_1.obj1 */.a.obj1["flip"].flap;'); + expectSourceToContain(source, 'const b = module2/* m_1.obj1 */.a.obj1.zip["zap"];'); + expectSourceToContain(source, 'const c = module2/* m_1.obj1 */.a.obj1["ding"].dong();'); + expectSourceToContain(source, 'const d = module2/* m_1.obj1 */.a.obj1.sing["song"]();'); + + expectSourceToContain(source, 'const aa = module3/* m_2.m_1.obj1 */.a.a.obj1["zoom"];'); + + expectSourceToContain(source, 'const bb = module1.obj1.up.down?.left.right;'); + + expectSourceToContain(source, 'const ww = (__webpack_require__(/*! ./module1 */ 602).obj1)["bing"]?.bang;'); + expectSourceToContain(source, 'const xx = (__webpack_require__(/*! ./module1 */ 602).obj1)["pip"].pop();'); + expectSourceToContain(source, 'const yy = (__webpack_require__(/*! ./module3 */ 144)/* .m_2.m_1.obj1 */ .a.a.obj1)["tip"].top();'); + + expectSourceToContain(source, 'data_namespaceObject.a.a["unknownProperty"].depth = "deep";'); + + expectSourceToContain(source, '(module1.obj1)["aaa"].bbb;'); + expectSourceToContain(source, '(module1.obj1)["ccc"].ddd;'); + expectSourceToContain(source, '(module1.obj1["eee"]).fff;'); + expectSourceToContain(source, '(module1.obj1["ggg"]).hhh;'); + expectSourceToContain(source, '((module1.obj1)["iii"]).jjj;'); +}); diff --git a/test/configCases/code-generation/re-export-namespace-concat/module1.js b/test/configCases/code-generation/re-export-namespace-concat/module1.js new file mode 100644 index 00000000000..e85ec664386 --- /dev/null +++ b/test/configCases/code-generation/re-export-namespace-concat/module1.js @@ -0,0 +1,3 @@ +export const obj1 = {}; + +export default { obj2: {} }; diff --git a/test/configCases/code-generation/re-export-namespace-concat/module2.js b/test/configCases/code-generation/re-export-namespace-concat/module2.js new file mode 100644 index 00000000000..a91c5e7a055 --- /dev/null +++ b/test/configCases/code-generation/re-export-namespace-concat/module2.js @@ -0,0 +1,2 @@ +import * as m1 from './module1'; +export { m1 as m_1 }; diff --git a/test/configCases/code-generation/re-export-namespace-concat/module3.js b/test/configCases/code-generation/re-export-namespace-concat/module3.js new file mode 100644 index 00000000000..cf0e8cd08d8 --- /dev/null +++ b/test/configCases/code-generation/re-export-namespace-concat/module3.js @@ -0,0 +1,2 @@ +import * as m2 from './module2'; +export { m2 as m_2 }; diff --git a/test/configCases/code-generation/re-export-namespace-concat/test.filter.js b/test/configCases/code-generation/re-export-namespace-concat/test.filter.js new file mode 100644 index 00000000000..698f2822d2d --- /dev/null +++ b/test/configCases/code-generation/re-export-namespace-concat/test.filter.js @@ -0,0 +1,5 @@ +var supportsOptionalChaining = require("../../../helpers/supportsOptionalChaining"); + +module.exports = function (config) { + return supportsOptionalChaining(); +}; diff --git a/test/configCases/code-generation/re-export-namespace-concat/webpack.config.js b/test/configCases/code-generation/re-export-namespace-concat/webpack.config.js new file mode 100644 index 00000000000..7e1057f2f3c --- /dev/null +++ b/test/configCases/code-generation/re-export-namespace-concat/webpack.config.js @@ -0,0 +1,11 @@ +/** @type {import("../../../../").Configuration} */ +module.exports = { + node: { + __dirname: false, + __filename: false + }, + mode: "production", + optimization: { + mangleExports: "size" + } +}; diff --git a/test/configCases/code-generation/re-export-namespace/data.json b/test/configCases/code-generation/re-export-namespace/data.json new file mode 100644 index 00000000000..7726aedd0c5 --- /dev/null +++ b/test/configCases/code-generation/re-export-namespace/data.json @@ -0,0 +1,5 @@ +{ + "nested": { + "object3": {} + } +} diff --git a/test/configCases/code-generation/re-export-namespace/index.js b/test/configCases/code-generation/re-export-namespace/index.js new file mode 100644 index 00000000000..376c4287873 --- /dev/null +++ b/test/configCases/code-generation/re-export-namespace/index.js @@ -0,0 +1,83 @@ +import { obj1 } from './module1'; +import * as m_1 from './module1'; +import * as m_2 from './module2'; +import * as m_3 from './module3'; +import data from "./data"; + +const { expectSourceToContain } = require("../../../helpers/expectSource"); + +// It's important to preserve the same accessor syntax (quotes vs. dot notatation) after the actual export variable. +// Else, minifiers such as Closure Compiler will not be able to minify correctly in ADVANCED mode. + +it("should use/preserve accessor form for import object and namespaces", function() { + var fs = require("fs"); + var source = fs.readFileSync(__filename, "utf-8").toString(); + + // Reference the imports to generate uses in the source. + + const f = false; + if (f) { + const x1 = m_1; + const x2 = obj1; + + const z1 = obj1["plants"]; + const z2 = obj1["funcs"](); + const z3 = m_1["obj1"]["pots"]; + const z4 = m_1["obj1"]["subs"](); + + const a = m_2["m_1"].obj1["flip"].flap; + const b = m_2["m_1"]["obj1"].zip["zap"]; + const c = m_2.m_1.obj1["ding"].dong(); + const d = m_2.m_1["obj1"].sing["song"](); + + const aa = m_3["m_2"].m_1["obj1"]["zoom"]; + + const bb = obj1.up.down?.left.right; + + const ww = require('./module1').obj1["bing"]?.bang; + const xx = require('./module1').obj1["pip"].pop(); + const yy = require('./module3')["m_2"]["m_1"]["obj1"]["tip"].top(); + + data.nested.object3["unknownProperty"].depth = "deep"; + + (obj1)["aaa"].bbb; + (m_1.obj1)["ccc"].ddd; + (obj1["eee"]).fff; + (m_1.obj1["ggg"]).hhh; + (((m_1).obj1)["iii"]).jjj; + } + + /************ DO NOT MATCH BELOW THIS LINE ************/ + + // Imported objects and import namespaces should use dot notation. Any references to the properties of exports + // should be preserved as either quotes or dot notation, depending on the original source. + + expectSourceToContain(source, 'const x1 = _module1__WEBPACK_IMPORTED_MODULE_0__;'); + expectSourceToContain(source, 'const x2 = _module1__WEBPACK_IMPORTED_MODULE_0__.obj1;'); + + expectSourceToContain(source, 'const z1 = _module1__WEBPACK_IMPORTED_MODULE_0__.obj1["plants"];'); + expectSourceToContain(source, 'const z2 = _module1__WEBPACK_IMPORTED_MODULE_0__.obj1["funcs"]();'); + expectSourceToContain(source, 'const z3 = _module1__WEBPACK_IMPORTED_MODULE_0__.obj1["pots"];'); + expectSourceToContain(source, 'const z4 = _module1__WEBPACK_IMPORTED_MODULE_0__.obj1["subs"]();'); + + expectSourceToContain(source, 'const a = _module2__WEBPACK_IMPORTED_MODULE_1__.m_1.obj1["flip"].flap;'); + expectSourceToContain(source, 'const b = _module2__WEBPACK_IMPORTED_MODULE_1__.m_1.obj1.zip["zap"];'); + expectSourceToContain(source, 'const c = _module2__WEBPACK_IMPORTED_MODULE_1__.m_1.obj1["ding"].dong();'); + expectSourceToContain(source, 'const d = _module2__WEBPACK_IMPORTED_MODULE_1__.m_1.obj1.sing["song"]();'); + + expectSourceToContain(source, 'const aa = _module3__WEBPACK_IMPORTED_MODULE_2__.m_2.m_1.obj1["zoom"];'); + + expectSourceToContain(source, 'const bb = _module1__WEBPACK_IMPORTED_MODULE_0__.obj1.up.down?.left.right;'); + + expectSourceToContain(source, 'const ww = (__webpack_require__(/*! ./module1 */ 602).obj1)["bing"]?.bang;'); + expectSourceToContain(source, 'const xx = (__webpack_require__(/*! ./module1 */ 602).obj1)["pip"].pop();'); + expectSourceToContain(source, 'const yy = (__webpack_require__(/*! ./module3 */ 144).m_2.m_1.obj1)["tip"].top();'); + + expectSourceToContain(source, '_data__WEBPACK_IMPORTED_MODULE_3__.nested.object3["unknownProperty"].depth = "deep";'); + + expectSourceToContain(source, '(_module1__WEBPACK_IMPORTED_MODULE_0__.obj1)["aaa"].bbb;'); + expectSourceToContain(source, '(_module1__WEBPACK_IMPORTED_MODULE_0__.obj1)["ccc"].ddd;'); + expectSourceToContain(source, '(_module1__WEBPACK_IMPORTED_MODULE_0__.obj1["eee"]).fff;'); + expectSourceToContain(source, '(_module1__WEBPACK_IMPORTED_MODULE_0__.obj1["ggg"]).hhh;'); + expectSourceToContain(source, '((_module1__WEBPACK_IMPORTED_MODULE_0__.obj1)["iii"]).jjj;'); +}); diff --git a/test/configCases/code-generation/re-export-namespace/module1.js b/test/configCases/code-generation/re-export-namespace/module1.js new file mode 100644 index 00000000000..e85ec664386 --- /dev/null +++ b/test/configCases/code-generation/re-export-namespace/module1.js @@ -0,0 +1,3 @@ +export const obj1 = {}; + +export default { obj2: {} }; diff --git a/test/configCases/code-generation/re-export-namespace/module2.js b/test/configCases/code-generation/re-export-namespace/module2.js new file mode 100644 index 00000000000..a91c5e7a055 --- /dev/null +++ b/test/configCases/code-generation/re-export-namespace/module2.js @@ -0,0 +1,2 @@ +import * as m1 from './module1'; +export { m1 as m_1 }; diff --git a/test/configCases/code-generation/re-export-namespace/module3.js b/test/configCases/code-generation/re-export-namespace/module3.js new file mode 100644 index 00000000000..cf0e8cd08d8 --- /dev/null +++ b/test/configCases/code-generation/re-export-namespace/module3.js @@ -0,0 +1,2 @@ +import * as m2 from './module2'; +export { m2 as m_2 }; diff --git a/test/configCases/code-generation/re-export-namespace/test.filter.js b/test/configCases/code-generation/re-export-namespace/test.filter.js new file mode 100644 index 00000000000..698f2822d2d --- /dev/null +++ b/test/configCases/code-generation/re-export-namespace/test.filter.js @@ -0,0 +1,5 @@ +var supportsOptionalChaining = require("../../../helpers/supportsOptionalChaining"); + +module.exports = function (config) { + return supportsOptionalChaining(); +}; diff --git a/test/configCases/code-generation/re-export-namespace/webpack.config.js b/test/configCases/code-generation/re-export-namespace/webpack.config.js new file mode 100644 index 00000000000..5da817461a6 --- /dev/null +++ b/test/configCases/code-generation/re-export-namespace/webpack.config.js @@ -0,0 +1,14 @@ +/** @type {import("../../../../").Configuration} */ +module.exports = { + node: { + __dirname: false, + __filename: false + }, + optimization: { + concatenateModules: false, + usedExports: true, + providedExports: true, + minimize: false, + mangleExports: false + } +}; diff --git a/test/configCases/code-generation/require-context-id/warnings.js b/test/configCases/code-generation/require-context-id/warnings.js index 5d0640d1c37..70fefa270fb 100644 --- a/test/configCases/code-generation/require-context-id/warnings.js +++ b/test/configCases/code-generation/require-context-id/warnings.js @@ -1,3 +1 @@ -module.exports = [ - [/hashed/, /deprecated/] -]; +module.exports = [[/hashed/, /deprecated/]]; diff --git a/test/configCases/compiletime/error-not-found/errors.js b/test/configCases/compiletime/error-not-found/errors.js index e36b112fde3..59aab9d5ba7 100644 --- a/test/configCases/compiletime/error-not-found/errors.js +++ b/test/configCases/compiletime/error-not-found/errors.js @@ -1,3 +1 @@ -module.exports = [ - /not found/ -]; +module.exports = [/not found/]; diff --git a/test/configCases/compiletime/exports-presence/aaa/index.js b/test/configCases/compiletime/exports-presence/aaa/index.js new file mode 100644 index 00000000000..1b2793ba6e3 --- /dev/null +++ b/test/configCases/compiletime/exports-presence/aaa/index.js @@ -0,0 +1,4 @@ +import { NoNo } from "../stub"; +export { NotHere } from "../stub"; + +export default `${typeof NoNo}`; diff --git a/test/configCases/compiletime/exports-presence/bbb/index.js b/test/configCases/compiletime/exports-presence/bbb/index.js new file mode 100644 index 00000000000..1b2793ba6e3 --- /dev/null +++ b/test/configCases/compiletime/exports-presence/bbb/index.js @@ -0,0 +1,4 @@ +import { NoNo } from "../stub"; +export { NotHere } from "../stub"; + +export default `${typeof NoNo}`; diff --git a/test/configCases/compiletime/exports-presence/ccc/index.js b/test/configCases/compiletime/exports-presence/ccc/index.js new file mode 100644 index 00000000000..1b2793ba6e3 --- /dev/null +++ b/test/configCases/compiletime/exports-presence/ccc/index.js @@ -0,0 +1,4 @@ +import { NoNo } from "../stub"; +export { NotHere } from "../stub"; + +export default `${typeof NoNo}`; diff --git a/test/configCases/compiletime/exports-presence/ddd/index.js b/test/configCases/compiletime/exports-presence/ddd/index.js new file mode 100644 index 00000000000..1b2793ba6e3 --- /dev/null +++ b/test/configCases/compiletime/exports-presence/ddd/index.js @@ -0,0 +1,4 @@ +import { NoNo } from "../stub"; +export { NotHere } from "../stub"; + +export default `${typeof NoNo}`; diff --git a/test/configCases/compiletime/exports-presence/errors.js b/test/configCases/compiletime/exports-presence/errors.js new file mode 100644 index 00000000000..257f6952694 --- /dev/null +++ b/test/configCases/compiletime/exports-presence/errors.js @@ -0,0 +1,10 @@ +module.exports = [ + { + moduleName: /ccc/, + message: /NotHere.+not found/ + }, + { + moduleName: /ccc/, + message: /NoNo.+not found/ + } +]; diff --git a/test/configCases/compiletime/exports-presence/index.js b/test/configCases/compiletime/exports-presence/index.js new file mode 100644 index 00000000000..3b8d2e8b66d --- /dev/null +++ b/test/configCases/compiletime/exports-presence/index.js @@ -0,0 +1,11 @@ +import { NotHere as aaa } from "./aaa/index.js"; +import { NotHere as bbb } from "./bbb/index.js"; +import { NotHere as ccc } from "./ccc/index.js"; +import { NotHere as ddd } from "./ddd/index.js"; + +it("should do nothing", () => { + expect(aaa).toBe(undefined); + expect(bbb).toBe(undefined); + expect(ccc).toBe(undefined); + expect(ddd).toBe(undefined); +}); diff --git a/test/configCases/compiletime/exports-presence/stub.js b/test/configCases/compiletime/exports-presence/stub.js new file mode 100644 index 00000000000..131d19e366f --- /dev/null +++ b/test/configCases/compiletime/exports-presence/stub.js @@ -0,0 +1,3 @@ +const foo = 'bar' + +export default foo diff --git a/test/configCases/compiletime/exports-presence/warnings.js b/test/configCases/compiletime/exports-presence/warnings.js new file mode 100644 index 00000000000..ca07ad2aacf --- /dev/null +++ b/test/configCases/compiletime/exports-presence/warnings.js @@ -0,0 +1,14 @@ +module.exports = [ + { + moduleName: /bbb/, + message: /NotHere.+not found/ + }, + { + moduleName: /bbb/, + message: /NoNo.+not found/ + }, + { + moduleName: /ddd/, + message: /NoNo.+not found/ + } +]; diff --git a/test/configCases/compiletime/exports-presence/webpack.config.js b/test/configCases/compiletime/exports-presence/webpack.config.js new file mode 100644 index 00000000000..7634dfd7a65 --- /dev/null +++ b/test/configCases/compiletime/exports-presence/webpack.config.js @@ -0,0 +1,34 @@ +/** @type {import("../../../../").Configuration} */ +module.exports = { + mode: "production", + module: { + rules: [ + { + test: /aaa/, + parser: { + exportsPresence: false + } + }, + { + test: /bbb/, + parser: { + exportsPresence: "warn" + } + }, + { + test: /ccc/, + parser: { + exportsPresence: "error" + } + }, + { + test: /ddd/, + parser: { + exportsPresence: "error", + importExportsPresence: "warn", + reexportExportsPresence: false + } + } + ] + } +}; diff --git a/test/configCases/compiletime/warn-not-found/warnings.js b/test/configCases/compiletime/warn-not-found/warnings.js index e36b112fde3..59aab9d5ba7 100644 --- a/test/configCases/compiletime/warn-not-found/warnings.js +++ b/test/configCases/compiletime/warn-not-found/warnings.js @@ -1,3 +1 @@ -module.exports = [ - /not found/ -]; +module.exports = [/not found/]; diff --git a/test/configCases/concatenate-modules/import-module/a.txt b/test/configCases/concatenate-modules/import-module/a.txt new file mode 100644 index 00000000000..1269488f7fb --- /dev/null +++ b/test/configCases/concatenate-modules/import-module/a.txt @@ -0,0 +1 @@ +data diff --git a/test/configCases/concatenate-modules/import-module/index.js b/test/configCases/concatenate-modules/import-module/index.js new file mode 100644 index 00000000000..76922431787 --- /dev/null +++ b/test/configCases/concatenate-modules/import-module/index.js @@ -0,0 +1,7 @@ +import url from "./loader!!"; +import {url as url2} from "./module1"; + +it("should compile and run", () => { + expect(url).toBe("webpack:///a.txt"); + expect(url2.toString()).toMatch(/^file:/); +}); diff --git a/test/configCases/concatenate-modules/import-module/loader.js b/test/configCases/concatenate-modules/import-module/loader.js new file mode 100644 index 00000000000..d09266dadfa --- /dev/null +++ b/test/configCases/concatenate-modules/import-module/loader.js @@ -0,0 +1,8 @@ +/** @type {import("../../../../").LoaderDefinitionFunction} */ +module.exports = function () { + const callback = this.async(); + this.importModule("./module1", { baseUri: "webpack://" }, (err, exports) => { + if (err) return callback(err); + callback(null, `module.exports = ${JSON.stringify(exports.url)}`); + }); +}; diff --git a/test/configCases/concatenate-modules/import-module/module1.js b/test/configCases/concatenate-modules/import-module/module1.js new file mode 100644 index 00000000000..5600ae2d20d --- /dev/null +++ b/test/configCases/concatenate-modules/import-module/module1.js @@ -0,0 +1,3 @@ +const url = new URL("./a.txt", import.meta.url); + +export { url } diff --git a/test/configCases/concatenate-modules/import-module/webpack.config.js b/test/configCases/concatenate-modules/import-module/webpack.config.js new file mode 100644 index 00000000000..161c13c0dd5 --- /dev/null +++ b/test/configCases/concatenate-modules/import-module/webpack.config.js @@ -0,0 +1,6 @@ +/** @type {import("../../../../").Configuration} */ +module.exports = { + output: { + assetModuleFilename: "[name][ext]" + } +}; diff --git a/test/configCases/concatenate-modules/issue-13022/a.js b/test/configCases/concatenate-modules/issue-13022/a.js new file mode 100644 index 00000000000..a87b4d9f98c --- /dev/null +++ b/test/configCases/concatenate-modules/issue-13022/a.js @@ -0,0 +1,4 @@ +const doc = console; +const setTimeout = 1; + +export default 1; diff --git a/test/configCases/concatenate-modules/issue-13022/index.js b/test/configCases/concatenate-modules/issue-13022/index.js new file mode 100644 index 00000000000..5395e7c6ba8 --- /dev/null +++ b/test/configCases/concatenate-modules/issue-13022/index.js @@ -0,0 +1,11 @@ +import "./a"; + +setTimeout(() => {}, 0); + +const doc = console; + +export default 1; + +it("should compile and run", () => { + expect(doc).toBe(console); +}); diff --git a/test/configCases/concatenate-modules/issue-13022/webpack.config.js b/test/configCases/concatenate-modules/issue-13022/webpack.config.js new file mode 100644 index 00000000000..dbbdda7ead7 --- /dev/null +++ b/test/configCases/concatenate-modules/issue-13022/webpack.config.js @@ -0,0 +1,29 @@ +const path = require("path"); + +/** @type {import("../../../../").Configuration[]} */ +module.exports = [ + { + entry: { + index: path.resolve(__dirname, "./index.js") + }, + output: { + library: "[name]", + libraryExport: "default" + }, + optimization: { + concatenateModules: true + } + }, + { + entry: { + index: path.resolve(__dirname, "./index.js") + }, + output: { + library: "[name]_doc", + libraryExport: "default" + }, + optimization: { + concatenateModules: true + } + } +]; diff --git a/test/configCases/concatenate-modules/load-chunk-function/test.config.js b/test/configCases/concatenate-modules/load-chunk-function/test.config.js index 65c1791bce3..7c714985915 100644 --- a/test/configCases/concatenate-modules/load-chunk-function/test.config.js +++ b/test/configCases/concatenate-modules/load-chunk-function/test.config.js @@ -1,5 +1,5 @@ module.exports = { - findBundle: function(i, options) { + findBundle: function (i, options) { return ["entry1.js", "entry2.js"]; } }; diff --git a/test/configCases/concatenate-modules/side-effects/index.js b/test/configCases/concatenate-modules/side-effects/index.js new file mode 100644 index 00000000000..354609dca02 --- /dev/null +++ b/test/configCases/concatenate-modules/side-effects/index.js @@ -0,0 +1,11 @@ +import { b, a, c } from "dep"; + +c.cc(); +b.bbb(); +a.aa(); + +import { order } from "dep/order.js"; + +it("should import side-effect-free modules in deterministic order (usage order)", () => { + expect(order).toEqual(["c", "b", "a"]); +}); diff --git a/test/configCases/concatenate-modules/side-effects/node_modules/dep/a.js b/test/configCases/concatenate-modules/side-effects/node_modules/dep/a.js new file mode 100644 index 00000000000..e913fb686ff --- /dev/null +++ b/test/configCases/concatenate-modules/side-effects/node_modules/dep/a.js @@ -0,0 +1,4 @@ +import { track } from "./order.js"; +track("a"); +export function aa() {} +export function aaa() {} diff --git a/test/configCases/concatenate-modules/side-effects/node_modules/dep/b.js b/test/configCases/concatenate-modules/side-effects/node_modules/dep/b.js new file mode 100644 index 00000000000..f6ffeb634bc --- /dev/null +++ b/test/configCases/concatenate-modules/side-effects/node_modules/dep/b.js @@ -0,0 +1,4 @@ +import { track } from "./order.js"; +track("b"); +export function bb() {} +export function bbb() {} diff --git a/test/configCases/concatenate-modules/side-effects/node_modules/dep/c.js b/test/configCases/concatenate-modules/side-effects/node_modules/dep/c.js new file mode 100644 index 00000000000..4478c310b26 --- /dev/null +++ b/test/configCases/concatenate-modules/side-effects/node_modules/dep/c.js @@ -0,0 +1,4 @@ +import { track } from "./order.js"; +track("c"); +export function cc() {} +export function ccc() {} diff --git a/test/configCases/concatenate-modules/side-effects/node_modules/dep/index.js b/test/configCases/concatenate-modules/side-effects/node_modules/dep/index.js new file mode 100644 index 00000000000..6195488abca --- /dev/null +++ b/test/configCases/concatenate-modules/side-effects/node_modules/dep/index.js @@ -0,0 +1,8 @@ +import * as a from "./a.js"; +import * as b from "./b.js"; +import * as c from "./c.js"; +export { + a, + b, + c +} diff --git a/test/configCases/concatenate-modules/side-effects/node_modules/dep/order.js b/test/configCases/concatenate-modules/side-effects/node_modules/dep/order.js new file mode 100644 index 00000000000..306f83ab171 --- /dev/null +++ b/test/configCases/concatenate-modules/side-effects/node_modules/dep/order.js @@ -0,0 +1,4 @@ +export let order = []; +export function track(name) { + order.push(name); +} diff --git a/test/configCases/concatenate-modules/side-effects/node_modules/dep/package.json b/test/configCases/concatenate-modules/side-effects/node_modules/dep/package.json new file mode 100644 index 00000000000..644d902d8e0 --- /dev/null +++ b/test/configCases/concatenate-modules/side-effects/node_modules/dep/package.json @@ -0,0 +1,6 @@ +{ + "name": "dep", + "version": "1.0.0", + "type": "module", + "sideEffects": false +} diff --git a/test/configCases/concatenate-modules/side-effects/webpack.config.js b/test/configCases/concatenate-modules/side-effects/webpack.config.js new file mode 100644 index 00000000000..c939ba33f61 --- /dev/null +++ b/test/configCases/concatenate-modules/side-effects/webpack.config.js @@ -0,0 +1,6 @@ +/** @type {import("../../../../").Configuration} */ +module.exports = { + optimization: { + concatenateModules: true + } +}; diff --git a/test/configCases/concatenate-modules/split-chunk-entry-module/test.config.js b/test/configCases/concatenate-modules/split-chunk-entry-module/test.config.js index b2809a12398..d2cb4260cff 100644 --- a/test/configCases/concatenate-modules/split-chunk-entry-module/test.config.js +++ b/test/configCases/concatenate-modules/split-chunk-entry-module/test.config.js @@ -1,5 +1,5 @@ module.exports = { - findBundle: function(i, options) { + findBundle: function (i, options) { return ["runtime.js", "common-index_js.js", "main.js"]; } }; diff --git a/test/configCases/container/0-container-full/test.config.js b/test/configCases/container/0-container-full/test.config.js new file mode 100644 index 00000000000..2d0d66fd4c0 --- /dev/null +++ b/test/configCases/container/0-container-full/test.config.js @@ -0,0 +1,5 @@ +module.exports = { + findBundle: function (i, options) { + return i === 0 ? "./main.js" : "./module/main.mjs"; + } +}; diff --git a/test/configCases/container/0-container-full/webpack.config.js b/test/configCases/container/0-container-full/webpack.config.js index 96cd2424ce8..3fe8d8bab2c 100644 --- a/test/configCases/container/0-container-full/webpack.config.js +++ b/test/configCases/container/0-container-full/webpack.config.js @@ -1,28 +1,61 @@ const { ModuleFederationPlugin } = require("../../../../").container; -/** @type {import("../../../../").Configuration} */ -module.exports = { - plugins: [ - new ModuleFederationPlugin({ - name: "container", - library: { type: "commonjs-module" }, - filename: "container.js", - exposes: { - "./ComponentA": { - import: "./ComponentA" - } - }, - remotes: { - containerA: { - external: "./container.js" - } - }, - shared: { - react: { - version: false, - requiredVersion: false - } - } - }) - ] +/** @type {ConstructorParameters[0]} */ +const common = { + name: "container", + exposes: { + "./ComponentA": { + import: "./ComponentA" + } + }, + shared: { + react: { + version: false, + requiredVersion: false + } + } }; + +/** @type {import("../../../../").Configuration[]} */ +module.exports = [ + { + output: { + filename: "[name].js", + uniqueName: "0-container-full" + }, + plugins: [ + new ModuleFederationPlugin({ + library: { type: "commonjs-module" }, + filename: "container.js", + remotes: { + containerA: { + external: "./container.js" + } + }, + ...common + }) + ] + }, + { + experiments: { + outputModule: true + }, + output: { + filename: "module/[name].mjs", + uniqueName: "0-container-full-mjs" + }, + plugins: [ + new ModuleFederationPlugin({ + library: { type: "module" }, + filename: "module/container.mjs", + remotes: { + containerA: { + external: "./container.mjs" + } + }, + ...common + }) + ], + target: "node14" + } +]; diff --git a/test/configCases/container/0-eager-shared/App.js b/test/configCases/container/0-eager-shared/App.js new file mode 100644 index 00000000000..aa4e4480be0 --- /dev/null +++ b/test/configCases/container/0-eager-shared/App.js @@ -0,0 +1,7 @@ +import { emitter } from "./emitter.js"; + +function App() { + return emitter; +} + +export default App; diff --git a/test/configCases/container/0-eager-shared/emitter.js b/test/configCases/container/0-eager-shared/emitter.js new file mode 100644 index 00000000000..199bf88f9ab --- /dev/null +++ b/test/configCases/container/0-eager-shared/emitter.js @@ -0,0 +1,9 @@ +import { TinyEmitter } from 'tiny-emitter' + +const emitter = new TinyEmitter() + +emitter.on('hello', () => console.log('hello[service]')) + +export { + emitter, +} diff --git a/test/configCases/container/0-eager-shared/index.js b/test/configCases/container/0-eager-shared/index.js new file mode 100644 index 00000000000..d512f614112 --- /dev/null +++ b/test/configCases/container/0-eager-shared/index.js @@ -0,0 +1,6 @@ +it("should allow to import exposed modules sync", () => { + return import("./App").then(({ default: App }) => { + expect(App().e.hello).toBeDefined(); + }); +}); + diff --git a/test/configCases/container/0-eager-shared/node_modules/tiny-emitter/index.js b/test/configCases/container/0-eager-shared/node_modules/tiny-emitter/index.js new file mode 100644 index 00000000000..7ca4a606e18 --- /dev/null +++ b/test/configCases/container/0-eager-shared/node_modules/tiny-emitter/index.js @@ -0,0 +1,67 @@ +function E () { + // Keep this empty so it's easier to inherit from + // (via https://github.com/lipsmack from https://github.com/scottcorgan/tiny-emitter/issues/3) +} + +E.prototype = { + on: function (name, callback, ctx) { + var e = this.e || (this.e = {}); + + (e[name] || (e[name] = [])).push({ + fn: callback, + ctx: ctx + }); + + return this; + }, + + once: function (name, callback, ctx) { + var self = this; + function listener () { + self.off(name, listener); + callback.apply(ctx, arguments); + }; + + listener._ = callback + return this.on(name, listener, ctx); + }, + + emit: function (name) { + var data = [].slice.call(arguments, 1); + var evtArr = ((this.e || (this.e = {}))[name] || []).slice(); + var i = 0; + var len = evtArr.length; + + for (i; i < len; i++) { + evtArr[i].fn.apply(evtArr[i].ctx, data); + } + + return this; + }, + + off: function (name, callback) { + var e = this.e || (this.e = {}); + var evts = e[name]; + var liveEvents = []; + + if (evts && callback) { + for (var i = 0, len = evts.length; i < len; i++) { + if (evts[i].fn !== callback && evts[i].fn._ !== callback) + liveEvents.push(evts[i]); + } + } + + // Remove event from queue to prevent memory leak + // Suggested by https://github.com/lazd + // Ref: https://github.com/scottcorgan/tiny-emitter/commit/c6ebfaa9bc973b33d110a84a307742b7cf94c953#commitcomment-5024910 + + (liveEvents.length) + ? e[name] = liveEvents + : delete e[name]; + + return this; + } +}; + +module.exports = E; +module.exports.TinyEmitter = E; diff --git a/test/configCases/container/0-eager-shared/node_modules/tiny-emitter/package.json b/test/configCases/container/0-eager-shared/node_modules/tiny-emitter/package.json new file mode 100644 index 00000000000..4bf445b8e9f --- /dev/null +++ b/test/configCases/container/0-eager-shared/node_modules/tiny-emitter/package.json @@ -0,0 +1,7 @@ +{ + "name": "tiny-emitter", + "version": "2.1.0", + "description": "A tiny (less than 1k) event emitter library", + "main": "index.js", + "license": "MIT" +} diff --git a/test/configCases/container/0-eager-shared/package.json b/test/configCases/container/0-eager-shared/package.json new file mode 100644 index 00000000000..7fc07107aa7 --- /dev/null +++ b/test/configCases/container/0-eager-shared/package.json @@ -0,0 +1,9 @@ +{ + "private": true, + "engines": { + "node": ">=10.13.0" + }, + "dependencies": { + "tiny-emitter": "^2.1.0" + } +} diff --git a/test/configCases/container/0-eager-shared/webpack.config.js b/test/configCases/container/0-eager-shared/webpack.config.js new file mode 100644 index 00000000000..f50ceb49734 --- /dev/null +++ b/test/configCases/container/0-eager-shared/webpack.config.js @@ -0,0 +1,26 @@ +const { dependencies } = require("./package.json"); +const { ModuleFederationPlugin } = require("../../../../").container; + +/** @type {import("../../../../").Configuration} */ +module.exports = { + optimization: { + chunkIds: "named", + moduleIds: "named" + }, + plugins: [ + new ModuleFederationPlugin({ + name: "container", + filename: "container.js", + library: { type: "commonjs-module" }, + exposes: { + "./emitter": { + name: "emitter", + import: "./emitter.js" + } + }, + shared: { + ...dependencies + } + }) + ] +}; diff --git a/test/configCases/container/1-container-full/App.js b/test/configCases/container/1-container-full/App.js index 6c2730a0b88..43f44221946 100644 --- a/test/configCases/container/1-container-full/App.js +++ b/test/configCases/container/1-container-full/App.js @@ -1,7 +1,10 @@ import React from "react"; import ComponentA from "containerA/ComponentA"; import ComponentB from "containerB/ComponentB"; +import LocalComponentB from "./ComponentB"; export default () => { return `App rendered with [${React()}] and [${ComponentA()}] and [${ComponentB()}]`; }; + +expect(ComponentB).not.toBe(LocalComponentB); diff --git a/test/configCases/container/1-container-full/package.json b/test/configCases/container/1-container-full/package.json index e04e63e83ad..be6238fec84 100644 --- a/test/configCases/container/1-container-full/package.json +++ b/test/configCases/container/1-container-full/package.json @@ -1,4 +1,8 @@ { + "private": true, + "engines": { + "node": ">=10.13.0" + }, "dependencies": { "react": "*" } diff --git a/test/configCases/container/1-container-full/test.config.js b/test/configCases/container/1-container-full/test.config.js new file mode 100644 index 00000000000..2d0d66fd4c0 --- /dev/null +++ b/test/configCases/container/1-container-full/test.config.js @@ -0,0 +1,5 @@ +module.exports = { + findBundle: function (i, options) { + return i === 0 ? "./main.js" : "./module/main.mjs"; + } +}; diff --git a/test/configCases/container/1-container-full/webpack.config.js b/test/configCases/container/1-container-full/webpack.config.js index e9de08d139a..0c9d66c16d2 100644 --- a/test/configCases/container/1-container-full/webpack.config.js +++ b/test/configCases/container/1-container-full/webpack.config.js @@ -1,22 +1,66 @@ -// eslint-disable-next-line node/no-unpublished-require const { ModuleFederationPlugin } = require("../../../../").container; -/** @type {import("../../../../").Configuration} */ -module.exports = { - plugins: [ - new ModuleFederationPlugin({ - name: "container", - library: { type: "commonjs-module" }, - filename: "container.js", - exposes: { - "./ComponentB": "./ComponentB", - "./ComponentC": "./ComponentC" - }, - remotes: { - containerA: "../0-container-full/container.js", - containerB: "./container.js" - }, - shared: ["react"] - }) - ] +const common = { + entry: { + main: "./index.js" + }, + optimization: { + runtimeChunk: "single" + } }; + +/** @type {ConstructorParameters[0]} */ +const commonMF = { + runtime: false, + exposes: { + "./ComponentB": "./ComponentB", + "./ComponentC": "./ComponentC" + }, + shared: ["react"] +}; + +/** @type {import("../../../../").Configuration[]} */ +module.exports = [ + { + ...common, + output: { + filename: "[name].js", + uniqueName: "1-container-full" + }, + plugins: [ + new ModuleFederationPlugin({ + name: "container", + library: { type: "commonjs-module" }, + filename: "container.js", + remotes: { + containerA: "../0-container-full/container.js", + containerB: "./container.js" + }, + ...commonMF + }) + ] + }, + { + ...common, + experiments: { + outputModule: true + }, + output: { + filename: "module/[name].mjs", + uniqueName: "1-container-full-mjs" + }, + plugins: [ + new ModuleFederationPlugin({ + name: "container", + library: { type: "module" }, + filename: "module/container.mjs", + remotes: { + containerA: "../../0-container-full/module/container.mjs", + containerB: "./container.mjs" + }, + ...commonMF + }) + ], + target: "node14" + } +]; diff --git a/test/configCases/container/2-container-full/index.js b/test/configCases/container/2-container-full/index.js index 942f87c5a5b..4dcf93a5a1e 100644 --- a/test/configCases/container/2-container-full/index.js +++ b/test/configCases/container/2-container-full/index.js @@ -30,7 +30,7 @@ const expectWarning = regexp => { it("should load the component from container", () => { return import("./App").then(({ default: App }) => { expectWarning( - /Unsatisfied version 8 of shared singleton module react \(required \^2\)/ + /Unsatisfied version 8 from 2-container-full of shared singleton module react \(required \^2\)/ ); const rendered = App(); expect(rendered).toBe( diff --git a/test/configCases/container/2-container-full/webpack.config.js b/test/configCases/container/2-container-full/webpack.config.js index 16e44280410..8f8dc9aac55 100644 --- a/test/configCases/container/2-container-full/webpack.config.js +++ b/test/configCases/container/2-container-full/webpack.config.js @@ -1,8 +1,11 @@ -// eslint-disable-next-line node/no-unpublished-require +// eslint-disable-next-line n/no-unpublished-require const { ModuleFederationPlugin } = require("../../../../").container; /** @type {import("../../../../").Configuration} */ module.exports = { + output: { + uniqueName: "2-container-full" + }, plugins: [ new ModuleFederationPlugin({ name: "main", diff --git a/test/configCases/container/3-container-full/webpack.config.js b/test/configCases/container/3-container-full/webpack.config.js index ed46429112e..a20051ec9af 100644 --- a/test/configCases/container/3-container-full/webpack.config.js +++ b/test/configCases/container/3-container-full/webpack.config.js @@ -1,4 +1,4 @@ -// eslint-disable-next-line node/no-unpublished-require +// eslint-disable-next-line n/no-unpublished-require const { ModuleFederationPlugin } = require("../../../../").container; /** @type {import("../../../../").Configuration} */ diff --git a/test/configCases/container/container-reference-override/test.config.js b/test/configCases/container/container-reference-override/test.config.js index 201ec2bece0..28fa0bd58bd 100644 --- a/test/configCases/container/container-reference-override/test.config.js +++ b/test/configCases/container/container-reference-override/test.config.js @@ -5,9 +5,7 @@ module.exports = { async get(module) { const testFactory = await ss.test[Object.keys(ss.test)[0]].get(); const test = testFactory(); - return () => { - return test(module); - }; + return () => test(module); }, async init(shareScope) { ss = shareScope; diff --git a/test/configCases/container/container-reference/test.config.js b/test/configCases/container/container-reference/test.config.js index d5a19987d97..96099b8e50f 100644 --- a/test/configCases/container/container-reference/test.config.js +++ b/test/configCases/container/container-reference/test.config.js @@ -4,7 +4,7 @@ module.exports = { get(module) { return new Promise(resolve => { setTimeout(() => { - resolve(() => "abc " + module); + resolve(() => `abc ${module}`); }, 100); }); } diff --git a/test/configCases/container/eager-shared/index.js b/test/configCases/container/eager-shared/index.js new file mode 100644 index 00000000000..6ca58a71970 --- /dev/null +++ b/test/configCases/container/eager-shared/index.js @@ -0,0 +1,13 @@ +import TinyEmitter from 'tiny-emitter' + +it("should load the component from container", () => { + const emitter = new TinyEmitter() + + emitter.on('hello', () => {}) + + expect(emitter.e.hello).toBeDefined(); + + return import('service/emitter').then(({ emitter }) => { + expect(emitter.e.hello).toBeDefined(); + }) +}); diff --git a/test/configCases/container/eager-shared/node_modules/tiny-emitter/index.js b/test/configCases/container/eager-shared/node_modules/tiny-emitter/index.js new file mode 100644 index 00000000000..b85d8921718 --- /dev/null +++ b/test/configCases/container/eager-shared/node_modules/tiny-emitter/index.js @@ -0,0 +1,66 @@ +function E () { + // Keep this empty so it's easier to inherit from + // (via https://github.com/lipsmack from https://github.com/scottcorgan/tiny-emitter/issues/3) +} + +E.prototype = { + on: function (name, callback, ctx) { + var e = this.e || (this.e = {}); + + (e[name] || (e[name] = [])).push({ + fn: callback, + ctx: ctx + }); + + return this; + }, + + once: function (name, callback, ctx) { + var self = this; + function listener () { + self.off(name, listener); + callback.apply(ctx, arguments); + }; + + listener._ = callback + return this.on(name, listener, ctx); + }, + + emit: function (name) { + var data = [].slice.call(arguments, 1); + var evtArr = ((this.e || (this.e = {}))[name] || []).slice(); + var i = 0; + var len = evtArr.length; + + for (i; i < len; i++) { + evtArr[i].fn.apply(evtArr[i].ctx, data); + } + + return this; + }, + + off: function (name, callback) { + var e = this.e || (this.e = {}); + var evts = e[name]; + var liveEvents = []; + + if (evts && callback) { + for (var i = 0, len = evts.length; i < len; i++) { + if (evts[i].fn !== callback && evts[i].fn._ !== callback) + liveEvents.push(evts[i]); + } + } + + // Remove event from queue to prevent memory leak + // Suggested by https://github.com/lazd + // Ref: https://github.com/scottcorgan/tiny-emitter/commit/c6ebfaa9bc973b33d110a84a307742b7cf94c953#commitcomment-5024910 + + (liveEvents.length) + ? e[name] = liveEvents + : delete e[name]; + + return this; + } +}; + +module.exports = E; diff --git a/test/configCases/container/eager-shared/node_modules/tiny-emitter/package.json b/test/configCases/container/eager-shared/node_modules/tiny-emitter/package.json new file mode 100644 index 00000000000..00786ca095d --- /dev/null +++ b/test/configCases/container/eager-shared/node_modules/tiny-emitter/package.json @@ -0,0 +1,7 @@ +{ + "name": "tiny-emitter", + "version": "2.0.0", + "description": "A tiny (less than 1k) event emitter library", + "main": "index.js", + "license": "MIT" +} diff --git a/test/configCases/container/eager-shared/package.json b/test/configCases/container/eager-shared/package.json new file mode 100644 index 00000000000..4460fc7aaab --- /dev/null +++ b/test/configCases/container/eager-shared/package.json @@ -0,0 +1,9 @@ +{ + "private": true, + "engines": { + "node": ">=10.13.0" + }, + "dependencies": { + "tiny-emitter": "=2.0.0" + } +} diff --git a/test/configCases/container/eager-shared/webpack.config.js b/test/configCases/container/eager-shared/webpack.config.js new file mode 100644 index 00000000000..0d31eaeb68c --- /dev/null +++ b/test/configCases/container/eager-shared/webpack.config.js @@ -0,0 +1,25 @@ +const { dependencies } = require("./package.json"); +const { ModuleFederationPlugin } = require("../../../../").container; + +/** @type {import("../../../../").Configuration} */ +module.exports = { + optimization: { + chunkIds: "named", + moduleIds: "named" + }, + plugins: [ + new ModuleFederationPlugin({ + remoteType: "commonjs-module", + remotes: { + service: "../0-eager-shared/container.js" + }, + shared: { + "tiny-emitter": { + eager: true, + singleton: true, + requiredVersion: dependencies["tiny-emitter"] + } + } + }) + ] +}; diff --git a/test/configCases/container/exposed-overridables/webpack.config.js b/test/configCases/container/exposed-overridables/webpack.config.js index 2e5f55e1ee0..cc5aa51bb95 100644 --- a/test/configCases/container/exposed-overridables/webpack.config.js +++ b/test/configCases/container/exposed-overridables/webpack.config.js @@ -1,4 +1,4 @@ -// eslint-disable-next-line node/no-unpublished-require +// eslint-disable-next-line n/no-unpublished-require const { ModuleFederationPlugin } = require("../../../../").container; /** @type {import("../../../../").Configuration} */ diff --git a/test/configCases/container/module-federation-with-shareScope/App.js b/test/configCases/container/module-federation-with-shareScope/App.js new file mode 100644 index 00000000000..43f44221946 --- /dev/null +++ b/test/configCases/container/module-federation-with-shareScope/App.js @@ -0,0 +1,10 @@ +import React from "react"; +import ComponentA from "containerA/ComponentA"; +import ComponentB from "containerB/ComponentB"; +import LocalComponentB from "./ComponentB"; + +export default () => { + return `App rendered with [${React()}] and [${ComponentA()}] and [${ComponentB()}]`; +}; + +expect(ComponentB).not.toBe(LocalComponentB); diff --git a/test/configCases/container/module-federation-with-shareScope/ComponentB.js b/test/configCases/container/module-federation-with-shareScope/ComponentB.js new file mode 100644 index 00000000000..1943469c746 --- /dev/null +++ b/test/configCases/container/module-federation-with-shareScope/ComponentB.js @@ -0,0 +1,5 @@ +import React from "react"; + +export default () => { + return `ComponentB rendered with [${React()}]`; +}; diff --git a/test/configCases/container/module-federation-with-shareScope/ComponentC.js b/test/configCases/container/module-federation-with-shareScope/ComponentC.js new file mode 100644 index 00000000000..3ff3832c718 --- /dev/null +++ b/test/configCases/container/module-federation-with-shareScope/ComponentC.js @@ -0,0 +1,7 @@ +import React from "react"; +import ComponentA from "containerA/ComponentA"; +import ComponentB from "containerB/ComponentB"; + +export default () => { + return `ComponentC rendered with [${React()}] and [${ComponentA()}] and [${ComponentB()}]`; +}; diff --git a/test/configCases/container/module-federation-with-shareScope/index.js b/test/configCases/container/module-federation-with-shareScope/index.js new file mode 100644 index 00000000000..cedabf6db95 --- /dev/null +++ b/test/configCases/container/module-federation-with-shareScope/index.js @@ -0,0 +1,20 @@ +it("should load the component from container", async () => { + await __webpack_init_sharing__("test-scope"); + + // 2 scopes for "0-container-full-mjs" & "mf-with-shareScope-mjs" + expect(Object.keys(__webpack_share_scopes__["test-scope"].react).length).toBe(2); + + return import("./App").then(({ default: App }) => { + const rendered = App(); + expect(rendered).toBe( + "App rendered with [This is react 2.1.0] and [ComponentA rendered with [This is react 2.1.0]] and [ComponentB rendered with [This is react 2.1.0]]" + ); + return import("./upgrade-react").then(({ default: upgrade }) => { + upgrade(); + const rendered = App(); + expect(rendered).toBe( + "App rendered with [This is react 3.2.1] and [ComponentA rendered with [This is react 3.2.1]] and [ComponentB rendered with [This is react 3.2.1]]" + ); + }); + }); +}); diff --git a/test/configCases/container/module-federation-with-shareScope/node_modules/package.json b/test/configCases/container/module-federation-with-shareScope/node_modules/package.json new file mode 100644 index 00000000000..87032da008a --- /dev/null +++ b/test/configCases/container/module-federation-with-shareScope/node_modules/package.json @@ -0,0 +1,3 @@ +{ + "version": "2.1.0" +} diff --git a/test/configCases/container/module-federation-with-shareScope/node_modules/react.js b/test/configCases/container/module-federation-with-shareScope/node_modules/react.js new file mode 100644 index 00000000000..97d35a4bc9c --- /dev/null +++ b/test/configCases/container/module-federation-with-shareScope/node_modules/react.js @@ -0,0 +1,3 @@ +let version = "2.1.0"; +export default () => `This is react ${version}`; +export function setVersion(v) { version = v; } diff --git a/test/configCases/container/module-federation-with-shareScope/package.json b/test/configCases/container/module-federation-with-shareScope/package.json new file mode 100644 index 00000000000..be6238fec84 --- /dev/null +++ b/test/configCases/container/module-federation-with-shareScope/package.json @@ -0,0 +1,9 @@ +{ + "private": true, + "engines": { + "node": ">=10.13.0" + }, + "dependencies": { + "react": "*" + } +} diff --git a/test/configCases/container/module-federation-with-shareScope/test.config.js b/test/configCases/container/module-federation-with-shareScope/test.config.js new file mode 100644 index 00000000000..2d0d66fd4c0 --- /dev/null +++ b/test/configCases/container/module-federation-with-shareScope/test.config.js @@ -0,0 +1,5 @@ +module.exports = { + findBundle: function (i, options) { + return i === 0 ? "./main.js" : "./module/main.mjs"; + } +}; diff --git a/test/configCases/container/module-federation-with-shareScope/upgrade-react.js b/test/configCases/container/module-federation-with-shareScope/upgrade-react.js new file mode 100644 index 00000000000..2cadfc0b71a --- /dev/null +++ b/test/configCases/container/module-federation-with-shareScope/upgrade-react.js @@ -0,0 +1,5 @@ +import { setVersion } from "react"; + +export default function upgrade() { + setVersion("3.2.1"); +} diff --git a/test/configCases/container/module-federation-with-shareScope/webpack.config.js b/test/configCases/container/module-federation-with-shareScope/webpack.config.js new file mode 100644 index 00000000000..218ebc25ddb --- /dev/null +++ b/test/configCases/container/module-federation-with-shareScope/webpack.config.js @@ -0,0 +1,67 @@ +const { ModuleFederationPlugin } = require("../../../../").container; + +const common = { + entry: { + main: "./index.js" + }, + optimization: { + runtimeChunk: "single" + } +}; + +/** @type {ConstructorParameters[0]} */ +const commonMF = { + runtime: false, + exposes: { + "./ComponentB": "./ComponentB", + "./ComponentC": "./ComponentC" + }, + shared: ["react"], + shareScope: "test-scope" +}; + +/** @type {import("../../../../types").Configuration[]} */ +module.exports = [ + { + ...common, + output: { + filename: "[name].js", + uniqueName: "mf-with-shareScope" + }, + plugins: [ + new ModuleFederationPlugin({ + name: "container", + library: { type: "commonjs-module" }, + filename: "container.js", + remotes: { + containerA: "../0-container-full/container.js", + containerB: "./container.js" + }, + ...commonMF + }) + ] + }, + { + ...common, + experiments: { + outputModule: true + }, + output: { + filename: "module/[name].mjs", + uniqueName: "mf-with-shareScope-mjs" + }, + plugins: [ + new ModuleFederationPlugin({ + name: "container", + library: { type: "module" }, + filename: "module/container.mjs", + remotes: { + containerA: "../../0-container-full/module/container.mjs", + containerB: "./container.mjs" + }, + ...commonMF + }) + ], + target: "node14" + } +]; diff --git a/test/configCases/container/module-federation/test.config.js b/test/configCases/container/module-federation/test.config.js index 3a6f27d21a5..bd9d9060de0 100644 --- a/test/configCases/container/module-federation/test.config.js +++ b/test/configCases/container/module-federation/test.config.js @@ -11,7 +11,7 @@ module.exports = { get(module) { return new Promise(resolve => { setTimeout(() => { - resolve(() => "abc " + module); + resolve(() => `abc ${module}`); }, 100); }); } diff --git a/test/configCases/contenthash/assets/1.jpg b/test/configCases/contenthash/assets/1.jpg new file mode 100644 index 00000000000..e69de29bb2d diff --git a/test/configCases/contenthash/assets/index.js b/test/configCases/contenthash/assets/index.js new file mode 100644 index 00000000000..0123092aa0d --- /dev/null +++ b/test/configCases/contenthash/assets/index.js @@ -0,0 +1,5 @@ +import img from "./1.jpg"; + +it("should compile", () => { + expect(typeof img).toBe("string"); +}); diff --git a/test/configCases/contenthash/assets/test.config.js b/test/configCases/contenthash/assets/test.config.js new file mode 100644 index 00000000000..0a8a1250095 --- /dev/null +++ b/test/configCases/contenthash/assets/test.config.js @@ -0,0 +1,31 @@ +const findOutputFiles = require("../../../helpers/findOutputFiles"); + +const allAssets = new Set(); +const allBundles = new Set(); + +module.exports = { + findBundle: function (i, options) { + const bundle = findOutputFiles(options, new RegExp(`^bundle${i}`))[0]; + allBundles.add(/\.([^.]+)\./.exec(bundle)[1]); + + let asset; + + switch (i) { + case 0: + asset = findOutputFiles(options, /^1\.[^.]*\.jpg$/, "img")[0]; + break; + case 1: + case 5: + asset = findOutputFiles(options, /^1\.[^.]*\.jpg$/, "asset")[0]; + break; + } + + if (asset) allAssets.add(asset); + + return `./${bundle}`; + }, + afterExecute: () => { + expect(allBundles.size).toBe(6); + expect(allAssets.size).toBe(1); + } +}; diff --git a/test/configCases/contenthash/assets/webpack.config.js b/test/configCases/contenthash/assets/webpack.config.js new file mode 100644 index 00000000000..1d6fb419763 --- /dev/null +++ b/test/configCases/contenthash/assets/webpack.config.js @@ -0,0 +1,118 @@ +/** @type {import("../../../../").Configuration[]} */ +module.exports = [ + { + output: { + filename: "bundle0.[contenthash].js", + assetModuleFilename: "img/[name].[contenthash][ext]" + }, + module: { + rules: [ + { + test: /\.jpg$/, + type: "asset/resource" + } + ] + } + }, + { + output: { + filename: "bundle1.[contenthash].js", + assetModuleFilename: "asset/[name].[contenthash][ext]" + }, + module: { + rules: [ + { + test: /\.jpg$/, + type: "asset/resource" + } + ] + } + }, + { + output: { + filename: "bundle2.[contenthash].js", + assetModuleFilename: "asset/[name].[contenthash][ext]" + }, + module: { + rules: [ + { + test: /\.jpg$/, + type: "asset/resource", + generator: { + publicPath: "/public/" + } + } + ] + } + }, + { + output: { + filename: "bundle3.[contenthash].js", + assetModuleFilename: "asset/[name].[contenthash][ext]" + }, + module: { + rules: [ + { + test: /\.jpg$/, + type: "asset/inline" + } + ] + } + }, + { + output: { + filename: "bundle4.[contenthash].js", + assetModuleFilename: "asset/[name].[contenthash][ext]" + }, + module: { + rules: [ + { + test: /\.jpg$/, + type: "asset/inline", + generator: { + dataUrl: { + encoding: false + } + } + } + ] + } + }, + { + output: { + filename: "bundle5.[contenthash].js", + assetModuleFilename: "asset/[name].[contenthash][ext]" + }, + module: { + rules: [ + { + test: /\.jpg$/, + type: "asset/source", + generator: { + dataUrl: { + mimetype: "text/plain" + } + } + } + ] + } + }, + { + output: { + filename: "bundle6.[contenthash].js", + assetModuleFilename: "asset/[name].[contenthash][ext]" + }, + module: { + rules: [ + { + test: /\.jpg$/, + type: "asset/resource", + generator: { + // should result in same hash as bundle2 + publicPath: () => "/public/" + } + } + ] + } + } +]; diff --git a/test/configCases/contenthash/css-generator-options/index.js b/test/configCases/contenthash/css-generator-options/index.js new file mode 100644 index 00000000000..ed3f045974b --- /dev/null +++ b/test/configCases/contenthash/css-generator-options/index.js @@ -0,0 +1,5 @@ +it("should compile", async () => { + await import("./style.module.css"); + // The real test is in test.config.js afterExecute + expect(true).toBe(true); +}); diff --git a/test/configCases/contenthash/css-generator-options/style.module.css b/test/configCases/contenthash/css-generator-options/style.module.css new file mode 100644 index 00000000000..e26591a3906 --- /dev/null +++ b/test/configCases/contenthash/css-generator-options/style.module.css @@ -0,0 +1,7 @@ +.class-a { + color: red; +} + +.class-b { + color: blue; +} diff --git a/test/configCases/contenthash/css-generator-options/test.config.js b/test/configCases/contenthash/css-generator-options/test.config.js new file mode 100644 index 00000000000..2c2fd1e61c8 --- /dev/null +++ b/test/configCases/contenthash/css-generator-options/test.config.js @@ -0,0 +1,18 @@ +const findOutputFiles = require("../../../helpers/findOutputFiles"); + +const allCss = new Set(); +const allBundles = new Set(); + +module.exports = { + findBundle: function (i, options) { + const bundle = findOutputFiles(options, new RegExp(`^bundle${i}`))[0]; + allBundles.add(/\.([^.]+)\./.exec(bundle)[1]); + const css = findOutputFiles(options, /^.*\.[^.]*\.css$/, `css${i}`)[0]; + allCss.add(css); + return `./${bundle}`; + }, + afterExecute: () => { + expect(allBundles.size).toBe(7); + expect(allCss.size).toBe(7); + } +}; diff --git a/test/configCases/contenthash/css-generator-options/webpack.config.js b/test/configCases/contenthash/css-generator-options/webpack.config.js new file mode 100644 index 00000000000..ac95029eb56 --- /dev/null +++ b/test/configCases/contenthash/css-generator-options/webpack.config.js @@ -0,0 +1,136 @@ +const common = { + target: "web", + optimization: { + realContentHash: false + }, + experiments: { + css: true + } +}; + +/** @type {import("../../../../").Configuration[]} */ +module.exports = [ + { + ...common, + output: { + filename: "bundle0.[contenthash].js", + cssChunkFilename: "css0/[name].[contenthash].css" + }, + module: { + rules: [ + { + test: /\.css$/, + type: "css/module" + } + ] + } + }, + { + ...common, + output: { + filename: "bundle1.[contenthash].js", + cssChunkFilename: "css1/[name].[contenthash].css" + }, + module: { + rules: [ + { + test: /\.css$/, + type: "css/module", + generator: { + exportsConvention: "camel-case" + } + } + ] + } + }, + { + ...common, + output: { + filename: "bundle2.[contenthash].js", + cssChunkFilename: "css2/[name].[contenthash].css" + }, + module: { + rules: [ + { + test: /\.css$/, + type: "css/module", + generator: { + exportsConvention: "camel-case-only" + } + } + ] + } + }, + { + ...common, + output: { + filename: "bundle3.[contenthash].js", + cssChunkFilename: "css3/[name].[contenthash].css" + }, + module: { + rules: [ + { + test: /\.css$/, + type: "css/module", + generator: { + exportsConvention: name => name.toUpperCase() + } + } + ] + } + }, + { + ...common, + output: { + filename: "bundle4.[contenthash].js", + cssChunkFilename: "css4/[name].[contenthash].css" + }, + module: { + rules: [ + { + test: /\.css$/, + type: "css/module", + generator: { + localIdentName: "[hash]-[local]" + } + } + ] + } + }, + { + ...common, + output: { + filename: "bundle5.[contenthash].js", + cssChunkFilename: "css5/[name].[contenthash].css" + }, + module: { + rules: [ + { + test: /\.css$/, + type: "css/module", + generator: { + localIdentName: "[path][name][ext]__[local]" + } + } + ] + } + }, + { + ...common, + output: { + filename: "bundle6.[contenthash].js", + cssChunkFilename: "css6/[name].[contenthash].css" + }, + module: { + rules: [ + { + test: /\.css$/, + type: "css/module", + generator: { + esModule: false + } + } + ] + } + } +]; diff --git a/test/configCases/contenthash/include-chunk-id/test.config.js b/test/configCases/contenthash/include-chunk-id/test.config.js index 6aa0c3c30ca..b88656a81c2 100644 --- a/test/configCases/contenthash/include-chunk-id/test.config.js +++ b/test/configCases/contenthash/include-chunk-id/test.config.js @@ -1,29 +1,19 @@ -var fs = require("fs"); - -var findFile = function(files, regex) { - return files.find(function(file) { - if (regex.test(file)) { - return true; - } - }); -}; +const findOutputFiles = require("../../../helpers/findOutputFiles"); const allFilenameHashes = new Set(); const allChunkHashes = new Set(); module.exports = { - findBundle: function(i, options) { - var files = fs.readdirSync(options.output.path); - - const filename = findFile(files, new RegExp(`^bundle${i}`)); + findBundle: function (i, options) { + const filename = findOutputFiles(options, new RegExp(`^bundle${i}`))[0]; const filenameHash = /\.([a-f0-9]+)\.js$/.exec(filename)[1]; allFilenameHashes.add(filenameHash); - const chunk = findFile(files, new RegExp(`^chunk${i}`)); + const chunk = findOutputFiles(options, new RegExp(`^chunk${i}`))[0]; const chunkHash = /\.([a-f0-9]+)\.js$/.exec(chunk)[1]; allChunkHashes.add(chunkHash); - return "./" + filename; + return `./${filename}`; }, afterExecute: () => { expect(allFilenameHashes.size).toBe(2); diff --git a/test/configCases/contenthash/module-ids-size/1.jpg b/test/configCases/contenthash/module-ids-size/1.jpg new file mode 100644 index 00000000000..e69de29bb2d diff --git a/test/configCases/contenthash/module-ids-size/async.js b/test/configCases/contenthash/module-ids-size/async.js new file mode 100644 index 00000000000..ec6ae927a27 --- /dev/null +++ b/test/configCases/contenthash/module-ids-size/async.js @@ -0,0 +1,10 @@ +export default function test() { + const a = 1; + const b = 2; + const c = 3; + const d = 4; + const f = 5; + const e = 6; + + return a + b + c + d + f + e; +} diff --git a/test/configCases/contenthash/module-ids-size/file-1.js b/test/configCases/contenthash/module-ids-size/file-1.js new file mode 100644 index 00000000000..a3825a0f846 --- /dev/null +++ b/test/configCases/contenthash/module-ids-size/file-1.js @@ -0,0 +1,19 @@ +async function test() { + const a = 1; + const b = 2; + const c = 3; + const d = 4; + const f = 5; + const e = 6; + + await import("./async.js"); + + return a + b + c + d + f + e; +} + +test(); + +export { test } +export default test; + +test(); diff --git a/test/configCases/contenthash/module-ids-size/file-2.js b/test/configCases/contenthash/module-ids-size/file-2.js new file mode 100644 index 00000000000..5217d109731 --- /dev/null +++ b/test/configCases/contenthash/module-ids-size/file-2.js @@ -0,0 +1,5 @@ +import { test } from "./file-1.js"; + +export default function foobar() { + return "test" + test(); +} diff --git a/test/configCases/contenthash/module-ids-size/file-3.js b/test/configCases/contenthash/module-ids-size/file-3.js new file mode 100644 index 00000000000..5e033ab9f4a --- /dev/null +++ b/test/configCases/contenthash/module-ids-size/file-3.js @@ -0,0 +1,7 @@ +function test() { + return "test"; +} + +test(); + +module.exports = "test"; diff --git a/test/configCases/contenthash/module-ids-size/file.js b/test/configCases/contenthash/module-ids-size/file.js new file mode 100644 index 00000000000..2f8412c218e --- /dev/null +++ b/test/configCases/contenthash/module-ids-size/file.js @@ -0,0 +1,25 @@ +import file from "./file-1.js"; +import file2 from "./file-2.js"; + +async function test() { + const a = 1; + const b = 2; + const c = 3; + const d = 4; + const f = 5; + const e = 6; + + await import(/* webpackMode: "eager" */"./async.js"); + await import(/* webpackMode: "eager" */"./file-3.js"); + + return a + b + c + d + f + e; +} + +test(); + +export { test, file, file2 } +export default function foo() { + return "test"; +} + +test(); diff --git a/test/configCases/contenthash/module-ids-size/index.js b/test/configCases/contenthash/module-ids-size/index.js new file mode 100644 index 00000000000..c43e8c29af8 --- /dev/null +++ b/test/configCases/contenthash/module-ids-size/index.js @@ -0,0 +1,7 @@ +import img from "./1.jpg"; +import file from "./file.js"; + +it("should compile", () => { + expect(typeof img).toBe("string"); + expect(typeof file).toBe("function"); +}); diff --git a/test/configCases/contenthash/module-ids-size/test.config.js b/test/configCases/contenthash/module-ids-size/test.config.js new file mode 100644 index 00000000000..2ade34513db --- /dev/null +++ b/test/configCases/contenthash/module-ids-size/test.config.js @@ -0,0 +1,28 @@ +const findOutputFiles = require("../../../helpers/findOutputFiles"); + +const allAssets = new Set(); +const allBundles = new Set(); + +module.exports = { + findBundle: function (i, options) { + const bundle = findOutputFiles(options, new RegExp(`^bundle${i}`))[0]; + + allBundles.add(/\.([^.]+)\./.exec(bundle)[1]); + + let asset; + + switch (i) { + case 0: + asset = findOutputFiles(options, /^1\.[^.]*\.jpg$/, "img")[0]; + break; + } + + if (asset) allAssets.add(asset); + + return `./${bundle}`; + }, + afterExecute: () => { + // Bundles have the same contenthash + expect(allBundles.size).toBe(1); + } +}; diff --git a/test/configCases/contenthash/module-ids-size/webpack.config.js b/test/configCases/contenthash/module-ids-size/webpack.config.js new file mode 100644 index 00000000000..2b768573875 --- /dev/null +++ b/test/configCases/contenthash/module-ids-size/webpack.config.js @@ -0,0 +1,37 @@ +/** @type {import("../../../../").Configuration} */ +module.exports = [ + { + output: { + filename: "bundle0.[contenthash].a.js", + assetModuleFilename: "img/[name].a.[contenthash][ext]" + }, + optimization: { + moduleIds: "size" + }, + module: { + rules: [ + { + test: /\.jpg$/, + type: "asset/resource" + } + ] + } + }, + { + output: { + filename: "bundle1.[contenthash].b.js", + assetModuleFilename: "img/[name].a.[contenthash][ext]" + }, + optimization: { + moduleIds: "size" + }, + module: { + rules: [ + { + test: /\.jpg$/, + type: "asset/resource" + } + ] + } + } +]; diff --git a/test/configCases/contenthash/salt/img.jpg b/test/configCases/contenthash/salt/img.jpg new file mode 100644 index 00000000000..e69de29bb2d diff --git a/test/configCases/contenthash/salt/index.js b/test/configCases/contenthash/salt/index.js new file mode 100644 index 00000000000..2d2b98703ee --- /dev/null +++ b/test/configCases/contenthash/salt/index.js @@ -0,0 +1,5 @@ +import img from "./img.jpg"; + +it("should compile", () => { + expect(typeof img).toBe("string"); +}); diff --git a/test/configCases/contenthash/salt/test.config.js b/test/configCases/contenthash/salt/test.config.js new file mode 100644 index 00000000000..ce9494812e9 --- /dev/null +++ b/test/configCases/contenthash/salt/test.config.js @@ -0,0 +1,24 @@ +const findOutputFiles = require("../../../helpers/findOutputFiles"); + +const allAssets = new Set(); +const allBundles = new Set(); + +module.exports = { + findBundle: function (i, options) { + const bundle = findOutputFiles(options, new RegExp(`^bundle${i}`))[0]; + allBundles.add(/\.([^.]+)\./.exec(bundle)[1]); + + const assets = findOutputFiles(options, /^img/); + for (const asset of assets) { + allAssets.add(asset); + } + + return `./${bundle}`; + }, + afterExecute: () => { + // Since there are exactly 2 unique values of output.hashSalt, + // there should be exactly 2 unique output hashes for each file. + expect(allBundles.size).toBe(2); + expect(allAssets.size).toBe(2); + } +}; diff --git a/test/configCases/contenthash/salt/webpack.config.js b/test/configCases/contenthash/salt/webpack.config.js new file mode 100644 index 00000000000..1ec1c83b9d9 --- /dev/null +++ b/test/configCases/contenthash/salt/webpack.config.js @@ -0,0 +1,48 @@ +/** @type {import("../../../../").Configuration[]} */ +module.exports = [ + { + output: { + filename: "bundle0.[contenthash].js", + assetModuleFilename: "[name].[contenthash][ext]", + hashSalt: "1" + }, + module: { + rules: [ + { + test: /\.jpg$/, + type: "asset/resource" + } + ] + } + }, + { + output: { + filename: "bundle1.[contenthash].js", + assetModuleFilename: "[name].[contenthash][ext]", + hashSalt: "1" + }, + module: { + rules: [ + { + test: /\.jpg$/, + type: "asset/resource" + } + ] + } + }, + { + output: { + filename: "bundle2.[contenthash].js", + assetModuleFilename: "[name].[contenthash][ext]", + hashSalt: "2" + }, + module: { + rules: [ + { + test: /\.jpg$/, + type: "asset/resource" + } + ] + } + } +]; diff --git a/test/configCases/context-replacement/d/queryloader.js b/test/configCases/context-replacement/d/queryloader.js index 88a2fd607bc..821519145eb 100644 --- a/test/configCases/context-replacement/d/queryloader.js +++ b/test/configCases/context-replacement/d/queryloader.js @@ -1,7 +1,11 @@ -module.exports = function(content) { - return "module.exports = " + JSON.stringify({ - resourceQuery: this.resourceQuery, - query: this.query, - prev: content.replace(/\r\n?/g, "\n") - }); +/** @type {import("../../../../").LoaderDefinition} */ +module.exports = function (content) { + return ( + "module.exports = " + + JSON.stringify({ + resourceQuery: this.resourceQuery, + query: this.query, + prev: content.replace(/\r\n?/g, "\n") + }) + ); }; diff --git a/test/configCases/crossorigin/set-crossorigin/index.js b/test/configCases/crossorigin/set-crossorigin/index.js index 6330978d157..a5e6677d872 100644 --- a/test/configCases/crossorigin/set-crossorigin/index.js +++ b/test/configCases/crossorigin/set-crossorigin/index.js @@ -65,3 +65,17 @@ it("should load script with crossorigin attribute anonymous (different origin)", return promise; }); + +it("should load style with crossorigin attribute anonymous (different origin)", function() { + var originalValue = __webpack_public_path__; + __webpack_public_path__ = "https://example.com/"; + const promise = import("./style.css?e" /* webpackChunkName: "crossorigin-different-origin" */); + __webpack_public_path__ = originalValue; + + var link = document.head._children[0]; + + expect(link.href).toBe("https://example.com/crossorigin-different-origin.web.css"); + expect(link.crossOrigin).toBe("anonymous"); + + return promise; +}); diff --git a/test/configCases/crossorigin/set-crossorigin/style.css b/test/configCases/crossorigin/set-crossorigin/style.css new file mode 100644 index 00000000000..60f1eab9713 --- /dev/null +++ b/test/configCases/crossorigin/set-crossorigin/style.css @@ -0,0 +1,3 @@ +body { + color: red; +} diff --git a/test/configCases/crossorigin/set-crossorigin/webpack.config.js b/test/configCases/crossorigin/set-crossorigin/webpack.config.js index f76ae2a4fa3..10096afbdf0 100644 --- a/test/configCases/crossorigin/set-crossorigin/webpack.config.js +++ b/test/configCases/crossorigin/set-crossorigin/webpack.config.js @@ -10,5 +10,8 @@ module.exports = { }, optimization: { minimize: false + }, + experiments: { + css: true } }; diff --git a/test/configCases/css/basic-esm-target-node/index.js b/test/configCases/css/basic-esm-target-node/index.js new file mode 100644 index 00000000000..49a5dd1fd07 --- /dev/null +++ b/test/configCases/css/basic-esm-target-node/index.js @@ -0,0 +1,9 @@ +import * as style from "./style.css"; + +it("should compile and load style on demand", done => { + expect(style).toEqual(nsObj({})); + import("./style2.css").then(x => { + expect(x).toEqual(nsObj({})); + done(); + }, done); +}); diff --git a/test/configCases/css/basic-esm-target-node/style-imported.css b/test/configCases/css/basic-esm-target-node/style-imported.css new file mode 100644 index 00000000000..eb0ae451455 --- /dev/null +++ b/test/configCases/css/basic-esm-target-node/style-imported.css @@ -0,0 +1,3 @@ +body { + margin: 10px; +} diff --git a/test/configCases/css/basic-esm-target-node/style.css b/test/configCases/css/basic-esm-target-node/style.css new file mode 100644 index 00000000000..ba0cfaf6561 --- /dev/null +++ b/test/configCases/css/basic-esm-target-node/style.css @@ -0,0 +1,4 @@ +@import "style-imported.css"; +body { + background: red; +} diff --git a/test/configCases/css/basic-esm-target-node/style2-imported.css b/test/configCases/css/basic-esm-target-node/style2-imported.css new file mode 100644 index 00000000000..ff9387e5d3e --- /dev/null +++ b/test/configCases/css/basic-esm-target-node/style2-imported.css @@ -0,0 +1,3 @@ +body { + padding: 20px 10px; +} diff --git a/test/configCases/css/basic-esm-target-node/style2.css b/test/configCases/css/basic-esm-target-node/style2.css new file mode 100644 index 00000000000..d80cbcd05df --- /dev/null +++ b/test/configCases/css/basic-esm-target-node/style2.css @@ -0,0 +1,4 @@ +@import "./style2-imported.css"; +body { + color: green; +} diff --git a/test/configCases/css/basic-esm-target-node/webpack.config.js b/test/configCases/css/basic-esm-target-node/webpack.config.js new file mode 100644 index 00000000000..91b082607b5 --- /dev/null +++ b/test/configCases/css/basic-esm-target-node/webpack.config.js @@ -0,0 +1,13 @@ +/** @type {import("../../../../").Configuration} */ +module.exports = { + target: "node", + mode: "development", + experiments: { + outputModule: true, + css: true + }, + output: { + module: true, + chunkFormat: "module" + } +}; diff --git a/test/configCases/css/basic-esm-target-web/index.js b/test/configCases/css/basic-esm-target-web/index.js new file mode 100644 index 00000000000..c1507825419 --- /dev/null +++ b/test/configCases/css/basic-esm-target-web/index.js @@ -0,0 +1,14 @@ +import * as style from "./style.css"; + +it("should compile and load style on demand", done => { + expect(style).toEqual(nsObj({})); + import("./style2.css").then(x => { + expect(x).toEqual(nsObj({})); + const style = getComputedStyle(document.body); + expect(style.getPropertyValue("background")).toBe(" red"); + expect(style.getPropertyValue("margin")).toBe(" 10px"); + expect(style.getPropertyValue("color")).toBe(" green"); + expect(style.getPropertyValue("padding")).toBe(" 20px 10px"); + done(); + }, done); +}); diff --git a/test/configCases/css/basic-esm-target-web/style-imported.css b/test/configCases/css/basic-esm-target-web/style-imported.css new file mode 100644 index 00000000000..eb0ae451455 --- /dev/null +++ b/test/configCases/css/basic-esm-target-web/style-imported.css @@ -0,0 +1,3 @@ +body { + margin: 10px; +} diff --git a/test/configCases/css/basic-esm-target-web/style.css b/test/configCases/css/basic-esm-target-web/style.css new file mode 100644 index 00000000000..ba0cfaf6561 --- /dev/null +++ b/test/configCases/css/basic-esm-target-web/style.css @@ -0,0 +1,4 @@ +@import "style-imported.css"; +body { + background: red; +} diff --git a/test/configCases/css/basic-esm-target-web/style2-imported.css b/test/configCases/css/basic-esm-target-web/style2-imported.css new file mode 100644 index 00000000000..ff9387e5d3e --- /dev/null +++ b/test/configCases/css/basic-esm-target-web/style2-imported.css @@ -0,0 +1,3 @@ +body { + padding: 20px 10px; +} diff --git a/test/configCases/css/basic-esm-target-web/style2.css b/test/configCases/css/basic-esm-target-web/style2.css new file mode 100644 index 00000000000..d80cbcd05df --- /dev/null +++ b/test/configCases/css/basic-esm-target-web/style2.css @@ -0,0 +1,4 @@ +@import "./style2-imported.css"; +body { + color: green; +} diff --git a/test/configCases/css/basic-esm-target-web/test.config.js b/test/configCases/css/basic-esm-target-web/test.config.js new file mode 100644 index 00000000000..0590757288f --- /dev/null +++ b/test/configCases/css/basic-esm-target-web/test.config.js @@ -0,0 +1,8 @@ +module.exports = { + moduleScope(scope) { + const link = scope.window.document.createElement("link"); + link.rel = "stylesheet"; + link.href = "bundle0.css"; + scope.window.document.head.appendChild(link); + } +}; diff --git a/test/configCases/css/basic-esm-target-web/webpack.config.js b/test/configCases/css/basic-esm-target-web/webpack.config.js new file mode 100644 index 00000000000..673fa0ebded --- /dev/null +++ b/test/configCases/css/basic-esm-target-web/webpack.config.js @@ -0,0 +1,13 @@ +/** @type {import("../../../../").Configuration} */ +module.exports = { + target: "web", + mode: "development", + experiments: { + outputModule: true, + css: true + }, + output: { + module: true, + chunkFormat: "module" + } +}; diff --git a/test/configCases/css/basic-initial-only/index.js b/test/configCases/css/basic-initial-only/index.js new file mode 100644 index 00000000000..652fef343dd --- /dev/null +++ b/test/configCases/css/basic-initial-only/index.js @@ -0,0 +1,8 @@ +import * as style from "./style.css"; + +it("should compile and load style on demand", () => { + expect(style).toEqual(nsObj({})); + const computedStyle = getComputedStyle(document.body); + expect(computedStyle.getPropertyValue("background")).toBe(" red"); + expect(computedStyle.getPropertyValue("margin")).toBe(" 10px"); +}); diff --git a/test/configCases/css/basic-initial-only/style-imported.css b/test/configCases/css/basic-initial-only/style-imported.css new file mode 100644 index 00000000000..eb0ae451455 --- /dev/null +++ b/test/configCases/css/basic-initial-only/style-imported.css @@ -0,0 +1,3 @@ +body { + margin: 10px; +} diff --git a/test/configCases/css/basic-initial-only/style.css b/test/configCases/css/basic-initial-only/style.css new file mode 100644 index 00000000000..8ed46132b24 --- /dev/null +++ b/test/configCases/css/basic-initial-only/style.css @@ -0,0 +1,5 @@ +@import url(https://test.cases/path/../../../../configCases/css/css-import/external.css); +@import "style-imported.css"; +body { + background: red; +} diff --git a/test/configCases/css/basic-initial-only/test.config.js b/test/configCases/css/basic-initial-only/test.config.js new file mode 100644 index 00000000000..0590757288f --- /dev/null +++ b/test/configCases/css/basic-initial-only/test.config.js @@ -0,0 +1,8 @@ +module.exports = { + moduleScope(scope) { + const link = scope.window.document.createElement("link"); + link.rel = "stylesheet"; + link.href = "bundle0.css"; + scope.window.document.head.appendChild(link); + } +}; diff --git a/test/configCases/css/basic-initial-only/webpack.config.js b/test/configCases/css/basic-initial-only/webpack.config.js new file mode 100644 index 00000000000..eb8b0ebb1bd --- /dev/null +++ b/test/configCases/css/basic-initial-only/webpack.config.js @@ -0,0 +1,9 @@ +/** @type {import("../../../../").Configuration} */ +module.exports = { + target: "web", + mode: "development", + externalsPresets: { web: false, webAsync: true }, + experiments: { + css: true + } +}; diff --git a/test/configCases/css/basic-web-async/index.js b/test/configCases/css/basic-web-async/index.js new file mode 100644 index 00000000000..c1507825419 --- /dev/null +++ b/test/configCases/css/basic-web-async/index.js @@ -0,0 +1,14 @@ +import * as style from "./style.css"; + +it("should compile and load style on demand", done => { + expect(style).toEqual(nsObj({})); + import("./style2.css").then(x => { + expect(x).toEqual(nsObj({})); + const style = getComputedStyle(document.body); + expect(style.getPropertyValue("background")).toBe(" red"); + expect(style.getPropertyValue("margin")).toBe(" 10px"); + expect(style.getPropertyValue("color")).toBe(" green"); + expect(style.getPropertyValue("padding")).toBe(" 20px 10px"); + done(); + }, done); +}); diff --git a/test/configCases/css/basic-web-async/style-imported.css b/test/configCases/css/basic-web-async/style-imported.css new file mode 100644 index 00000000000..eb0ae451455 --- /dev/null +++ b/test/configCases/css/basic-web-async/style-imported.css @@ -0,0 +1,3 @@ +body { + margin: 10px; +} diff --git a/test/configCases/css/basic-web-async/style.css b/test/configCases/css/basic-web-async/style.css new file mode 100644 index 00000000000..ba0cfaf6561 --- /dev/null +++ b/test/configCases/css/basic-web-async/style.css @@ -0,0 +1,4 @@ +@import "style-imported.css"; +body { + background: red; +} diff --git a/test/configCases/css/basic-web-async/style2-imported.css b/test/configCases/css/basic-web-async/style2-imported.css new file mode 100644 index 00000000000..ff9387e5d3e --- /dev/null +++ b/test/configCases/css/basic-web-async/style2-imported.css @@ -0,0 +1,3 @@ +body { + padding: 20px 10px; +} diff --git a/test/configCases/css/basic-web-async/style2.css b/test/configCases/css/basic-web-async/style2.css new file mode 100644 index 00000000000..d80cbcd05df --- /dev/null +++ b/test/configCases/css/basic-web-async/style2.css @@ -0,0 +1,4 @@ +@import "./style2-imported.css"; +body { + color: green; +} diff --git a/test/configCases/css/basic-web-async/test.config.js b/test/configCases/css/basic-web-async/test.config.js new file mode 100644 index 00000000000..0590757288f --- /dev/null +++ b/test/configCases/css/basic-web-async/test.config.js @@ -0,0 +1,8 @@ +module.exports = { + moduleScope(scope) { + const link = scope.window.document.createElement("link"); + link.rel = "stylesheet"; + link.href = "bundle0.css"; + scope.window.document.head.appendChild(link); + } +}; diff --git a/test/configCases/css/basic-web-async/webpack.config.js b/test/configCases/css/basic-web-async/webpack.config.js new file mode 100644 index 00000000000..eb8b0ebb1bd --- /dev/null +++ b/test/configCases/css/basic-web-async/webpack.config.js @@ -0,0 +1,9 @@ +/** @type {import("../../../../").Configuration} */ +module.exports = { + target: "web", + mode: "development", + externalsPresets: { web: false, webAsync: true }, + experiments: { + css: true + } +}; diff --git a/test/configCases/css/basic/index.js b/test/configCases/css/basic/index.js new file mode 100644 index 00000000000..c1507825419 --- /dev/null +++ b/test/configCases/css/basic/index.js @@ -0,0 +1,14 @@ +import * as style from "./style.css"; + +it("should compile and load style on demand", done => { + expect(style).toEqual(nsObj({})); + import("./style2.css").then(x => { + expect(x).toEqual(nsObj({})); + const style = getComputedStyle(document.body); + expect(style.getPropertyValue("background")).toBe(" red"); + expect(style.getPropertyValue("margin")).toBe(" 10px"); + expect(style.getPropertyValue("color")).toBe(" green"); + expect(style.getPropertyValue("padding")).toBe(" 20px 10px"); + done(); + }, done); +}); diff --git a/test/configCases/css/basic/style-imported.css b/test/configCases/css/basic/style-imported.css new file mode 100644 index 00000000000..eb0ae451455 --- /dev/null +++ b/test/configCases/css/basic/style-imported.css @@ -0,0 +1,3 @@ +body { + margin: 10px; +} diff --git a/test/configCases/css/basic/style.css b/test/configCases/css/basic/style.css new file mode 100644 index 00000000000..ba0cfaf6561 --- /dev/null +++ b/test/configCases/css/basic/style.css @@ -0,0 +1,4 @@ +@import "style-imported.css"; +body { + background: red; +} diff --git a/test/configCases/css/basic/style2-imported.css b/test/configCases/css/basic/style2-imported.css new file mode 100644 index 00000000000..ff9387e5d3e --- /dev/null +++ b/test/configCases/css/basic/style2-imported.css @@ -0,0 +1,3 @@ +body { + padding: 20px 10px; +} diff --git a/test/configCases/css/basic/style2.css b/test/configCases/css/basic/style2.css new file mode 100644 index 00000000000..d80cbcd05df --- /dev/null +++ b/test/configCases/css/basic/style2.css @@ -0,0 +1,4 @@ +@import "./style2-imported.css"; +body { + color: green; +} diff --git a/test/configCases/css/basic/test.config.js b/test/configCases/css/basic/test.config.js new file mode 100644 index 00000000000..0590757288f --- /dev/null +++ b/test/configCases/css/basic/test.config.js @@ -0,0 +1,8 @@ +module.exports = { + moduleScope(scope) { + const link = scope.window.document.createElement("link"); + link.rel = "stylesheet"; + link.href = "bundle0.css"; + scope.window.document.head.appendChild(link); + } +}; diff --git a/test/configCases/css/basic/webpack.config.js b/test/configCases/css/basic/webpack.config.js new file mode 100644 index 00000000000..cfb8e5c0346 --- /dev/null +++ b/test/configCases/css/basic/webpack.config.js @@ -0,0 +1,8 @@ +/** @type {import("../../../../").Configuration} */ +module.exports = { + target: "web", + mode: "development", + experiments: { + css: true + } +}; diff --git a/test/configCases/css/cjs-module-syntax/index.js b/test/configCases/css/cjs-module-syntax/index.js new file mode 100644 index 00000000000..093af6f7c53 --- /dev/null +++ b/test/configCases/css/cjs-module-syntax/index.js @@ -0,0 +1,11 @@ +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +it("should able to require the css module as commonjs", () => { + const style = require("./style.module.css"); + const interoperatedStyle = _interopRequireDefault(require("./style.module.css")); + + expect(style).toEqual({ foo: '-_style_module_css-foo' }); + expect(style).not.toEqual(nsObj({ foo: '-_style_module_css-foo' })); + expect(style.__esModule).toEqual(undefined); + expect(interoperatedStyle.default.foo).toEqual("-_style_module_css-foo"); +}); diff --git a/test/configCases/css/cjs-module-syntax/style.module.css b/test/configCases/css/cjs-module-syntax/style.module.css new file mode 100644 index 00000000000..cedf0a6d1f1 --- /dev/null +++ b/test/configCases/css/cjs-module-syntax/style.module.css @@ -0,0 +1,3 @@ +.foo { + color: red; +} diff --git a/test/configCases/css/cjs-module-syntax/test.config.js b/test/configCases/css/cjs-module-syntax/test.config.js new file mode 100644 index 00000000000..d8b1cd2e6ed --- /dev/null +++ b/test/configCases/css/cjs-module-syntax/test.config.js @@ -0,0 +1,10 @@ +module.exports = { + moduleScope(scope) { + if (scope.document) { + const link = scope.document.createElement("link"); + link.rel = "stylesheet"; + link.href = "bundle0.css"; + scope.document.head.appendChild(link); + } + } +}; diff --git a/test/configCases/css/cjs-module-syntax/webpack.config.js b/test/configCases/css/cjs-module-syntax/webpack.config.js new file mode 100644 index 00000000000..c99de4b1ee8 --- /dev/null +++ b/test/configCases/css/cjs-module-syntax/webpack.config.js @@ -0,0 +1,31 @@ +/** @type {import("../../../../").Configuration} */ +module.exports = [ + { + target: "web", + mode: "development", + module: { + generator: { + "css/auto": { + esModule: false + } + } + }, + experiments: { + css: true + } + }, + { + target: "node", + mode: "development", + module: { + generator: { + "css/auto": { + esModule: false + } + } + }, + experiments: { + css: true + } + } +]; diff --git a/test/configCases/css/conflicting-order/a.css b/test/configCases/css/conflicting-order/a.css new file mode 100644 index 00000000000..facff2572fd --- /dev/null +++ b/test/configCases/css/conflicting-order/a.css @@ -0,0 +1,3 @@ +body { + color: a; +} diff --git a/test/configCases/css/conflicting-order/b.css b/test/configCases/css/conflicting-order/b.css new file mode 100644 index 00000000000..d056e75b364 --- /dev/null +++ b/test/configCases/css/conflicting-order/b.css @@ -0,0 +1,3 @@ +body { + color: b; +} diff --git a/test/configCases/css/conflicting-order/c.css b/test/configCases/css/conflicting-order/c.css new file mode 100644 index 00000000000..f3ed682c771 --- /dev/null +++ b/test/configCases/css/conflicting-order/c.css @@ -0,0 +1,3 @@ +body { + color: c; +} diff --git a/test/configCases/css/conflicting-order/d.css b/test/configCases/css/conflicting-order/d.css new file mode 100644 index 00000000000..3f32d017594 --- /dev/null +++ b/test/configCases/css/conflicting-order/d.css @@ -0,0 +1,3 @@ +body { + color: d; +} diff --git a/test/configCases/css/conflicting-order/e.css b/test/configCases/css/conflicting-order/e.css new file mode 100644 index 00000000000..1860e384e83 --- /dev/null +++ b/test/configCases/css/conflicting-order/e.css @@ -0,0 +1,3 @@ +body { + color: e; +} diff --git a/test/configCases/css/conflicting-order/index.js b/test/configCases/css/conflicting-order/index.js new file mode 100644 index 00000000000..1bb72365811 --- /dev/null +++ b/test/configCases/css/conflicting-order/index.js @@ -0,0 +1,23 @@ +import fs from "fs"; +import path from "path"; + +it("should lead to conflicting order warning", done => { + __non_webpack_require__("./lazy4_js.bundle0.js"); + Promise.all([ + import("./lazy1.css"), + import("./lazy2.css"), + import("./lazy3.css"), + import("./lazy4.js") + ]).then(() => { + try { + const matches = fs + .readFileSync(path.join(__dirname, "css.bundle0.css"), "utf-8") + .match(/color: ([a-z0-9])/g) + .map(match => match[7]); + expect(matches).toEqual("bcdea123".split("")); + done(); + } catch (e) { + done(e); + } + }, done); +}); diff --git a/test/configCases/css/conflicting-order/lazy1.css b/test/configCases/css/conflicting-order/lazy1.css new file mode 100644 index 00000000000..0cf98e07196 --- /dev/null +++ b/test/configCases/css/conflicting-order/lazy1.css @@ -0,0 +1,7 @@ +@import "b.css"; +@import "c.css"; +@import "a.css"; + +body { + color: 1; +} diff --git a/test/configCases/css/conflicting-order/lazy2.css b/test/configCases/css/conflicting-order/lazy2.css new file mode 100644 index 00000000000..9926298dfaf --- /dev/null +++ b/test/configCases/css/conflicting-order/lazy2.css @@ -0,0 +1,7 @@ +@import "c.css"; +@import "b.css"; +@import "a.css"; + +body { + color: 2; +} diff --git a/test/configCases/css/conflicting-order/lazy3.css b/test/configCases/css/conflicting-order/lazy3.css new file mode 100644 index 00000000000..945f24b7a0b --- /dev/null +++ b/test/configCases/css/conflicting-order/lazy3.css @@ -0,0 +1,6 @@ +@import "d.css"; +@import "a.css"; + +body { + color: 3; +} diff --git a/test/configCases/css/conflicting-order/lazy4.js b/test/configCases/css/conflicting-order/lazy4.js new file mode 100644 index 00000000000..1e7987525f3 --- /dev/null +++ b/test/configCases/css/conflicting-order/lazy4.js @@ -0,0 +1,2 @@ +import "./e.css"; +import "./a.css"; diff --git a/test/configCases/css/conflicting-order/warnings.js b/test/configCases/css/conflicting-order/warnings.js new file mode 100644 index 00000000000..bf0f21a942d --- /dev/null +++ b/test/configCases/css/conflicting-order/warnings.js @@ -0,0 +1,3 @@ +module.exports = [ + [/Conflicting order between css \.\/b\.css and css \.\/c\.css/] +]; diff --git a/test/configCases/css/conflicting-order/webpack.config.js b/test/configCases/css/conflicting-order/webpack.config.js new file mode 100644 index 00000000000..a5f3136eaa4 --- /dev/null +++ b/test/configCases/css/conflicting-order/webpack.config.js @@ -0,0 +1,25 @@ +/** @type {import("../../../../").Configuration} */ +module.exports = { + target: "web", + mode: "development", + experiments: { + css: true + }, + optimization: { + splitChunks: { + cacheGroups: { + css: { + type: "css/auto", + enforce: true, + name: "css" + } + } + } + }, + externalsPresets: { + node: true + }, + node: { + __dirname: false + } +}; diff --git a/test/configCases/css/contenthash/async.css b/test/configCases/css/contenthash/async.css new file mode 100644 index 00000000000..e05a8819abb --- /dev/null +++ b/test/configCases/css/contenthash/async.css @@ -0,0 +1,4 @@ +body { + background: yellow; + color: green; +} diff --git a/test/configCases/css/contenthash/async.js b/test/configCases/css/contenthash/async.js new file mode 100644 index 00000000000..6308565c261 --- /dev/null +++ b/test/configCases/css/contenthash/async.js @@ -0,0 +1 @@ +export const name = 'async'; diff --git a/test/configCases/css/contenthash/index.js b/test/configCases/css/contenthash/index.js new file mode 100644 index 00000000000..6215ea756e3 --- /dev/null +++ b/test/configCases/css/contenthash/index.js @@ -0,0 +1,28 @@ +import * as style from "./style.css"; + +it("should work with js", done => { + import('./async.js').then(x => { + expect(x.name).toBe("async") + done(); + }, done); +}); + +it("should work with css", done => { + expect(style).toEqual(nsObj({})); + + const computedStyle = getComputedStyle(document.body); + + expect(computedStyle.getPropertyValue("background")).toBe(" green"); + expect(computedStyle.getPropertyValue("color")).toBe(" yellow"); + + import("./async.css").then(x => { + expect(x).toEqual(nsObj({})); + + const style = getComputedStyle(document.body); + + expect(style.getPropertyValue("background")).toBe(" yellow"); + expect(style.getPropertyValue("color")).toBe(" green"); + + done(); + }, done); +}); diff --git a/test/configCases/css/contenthash/style.css b/test/configCases/css/contenthash/style.css new file mode 100644 index 00000000000..9cbc00618c7 --- /dev/null +++ b/test/configCases/css/contenthash/style.css @@ -0,0 +1,4 @@ +body { + background: green; + color: yellow; +} diff --git a/test/configCases/css/contenthash/test.config.js b/test/configCases/css/contenthash/test.config.js new file mode 100644 index 00000000000..fbe65cee429 --- /dev/null +++ b/test/configCases/css/contenthash/test.config.js @@ -0,0 +1,49 @@ +const fs = require("fs"); + +let cssBundle; + +module.exports = { + findBundle: function (_, options) { + const jsBundleRegex = new RegExp(/^bundle\..+\.js$/, "i"); + const cssBundleRegex = new RegExp(/^bundle\..+\.css$/, "i"); + const asyncRegex = new RegExp(/^async\..+\.js$/, "i"); + const files = fs.readdirSync(options.output.path); + const jsBundle = files.find(file => jsBundleRegex.test(file)); + + if (!jsBundle) { + throw new Error( + `No file found with correct name (regex: ${ + jsBundleRegex.source + }, files: ${files.join(", ")})` + ); + } + + const async = files.find(file => asyncRegex.test(file)); + + if (!async) { + throw new Error( + `No file found with correct name (regex: ${ + asyncRegex.source + }, files: ${files.join(", ")})` + ); + } + + cssBundle = files.find(file => cssBundleRegex.test(file)); + + if (!cssBundle) { + throw new Error( + `No file found with correct name (regex: ${ + cssBundleRegex.source + }, files: ${files.join(", ")})` + ); + } + + return [jsBundle, async]; + }, + moduleScope(scope) { + const link = scope.window.document.createElement("link"); + link.rel = "stylesheet"; + link.href = cssBundle; + scope.window.document.head.appendChild(link); + } +}; diff --git a/test/configCases/css/contenthash/webpack.config.js b/test/configCases/css/contenthash/webpack.config.js new file mode 100644 index 00000000000..2f799e18d58 --- /dev/null +++ b/test/configCases/css/contenthash/webpack.config.js @@ -0,0 +1,14 @@ +/** @type {import("../../../../").Configuration} */ +module.exports = { + target: "web", + mode: "development", + output: { + filename: "bundle.[name].[contenthash].js", + cssFilename: "bundle.[name].[contenthash].css", + chunkFilename: "async.[name].[contenthash].js", + cssChunkFilename: "async.[name].[contenthash].css" + }, + experiments: { + css: true + } +}; diff --git a/test/configCases/css/css-auto/colors.js b/test/configCases/css/css-auto/colors.js new file mode 100644 index 00000000000..91f7b0d0db4 --- /dev/null +++ b/test/configCases/css/css-auto/colors.js @@ -0,0 +1,2 @@ +export const red = '#f00'; +export const green = '#0f0'; \ No newline at end of file diff --git a/test/configCases/css/css-auto/global.less b/test/configCases/css/css-auto/global.less new file mode 100644 index 00000000000..f815695493b --- /dev/null +++ b/test/configCases/css/css-auto/global.less @@ -0,0 +1,3 @@ +body { + color: green; +} diff --git a/test/configCases/css/css-auto/index.js b/test/configCases/css/css-auto/index.js new file mode 100644 index 00000000000..5f53534201b --- /dev/null +++ b/test/configCases/css/css-auto/index.js @@ -0,0 +1,17 @@ +import "./global.less"; +import * as style1 from "./style1.module.less"; +import * as style2 from "./style2.modules.less"; +import * as style3 from "./style3.module.less!=!./loader.js!./style3.module.js"; +import * as style4 from "./style4.module.less!=!./loader.js!./style4.js"; +import * as style5 from "./style5.module.css!=!./loader.js!./style4.js"; + +it("should correctly compile css/auto", () => { + const style = getComputedStyle(document.body); + expect(style.getPropertyValue("color")).toBe(" green"); + expect(style.getPropertyValue("background")).toBe(" #f00"); + expect(style1.class).toBe("-_style1_module_less-class"); + expect(style2.class).toBe("-_style2_modules_less-class"); + expect(style3.class).toBe("-_style3_module_less_loader_js_style3_module_js-class"); + expect(style4.class).toBe("-_style4_module_less_loader_js_style4_js-class"); + expect(style5.class).toBe("-_style5_module_css_loader_js_style4_js-class"); +}); diff --git a/test/configCases/css/css-auto/loader.js b/test/configCases/css/css-auto/loader.js new file mode 100644 index 00000000000..5165d32de03 --- /dev/null +++ b/test/configCases/css/css-auto/loader.js @@ -0,0 +1,8 @@ +/** @type {import("../../../../").PitchLoaderDefinitionFunction} */ +exports.pitch = async function (remaining) { + const result = await this.importModule( + this.resourcePath + '.webpack[javascript/auto]' + '!=!' + remaining, { + publicPath: '' + }); + return result.default || result; +}; diff --git a/test/configCases/css/css-auto/style1.module.less b/test/configCases/css/css-auto/style1.module.less new file mode 100644 index 00000000000..626e93720d0 --- /dev/null +++ b/test/configCases/css/css-auto/style1.module.less @@ -0,0 +1,3 @@ +.class { + color: red; +} diff --git a/test/configCases/css/css-auto/style2.modules.less b/test/configCases/css/css-auto/style2.modules.less new file mode 100644 index 00000000000..323ffaed199 --- /dev/null +++ b/test/configCases/css/css-auto/style2.modules.less @@ -0,0 +1,3 @@ +.class { + color: blue; +} diff --git a/test/configCases/css/css-auto/style3.module.js b/test/configCases/css/css-auto/style3.module.js new file mode 100644 index 00000000000..c56e98fb281 --- /dev/null +++ b/test/configCases/css/css-auto/style3.module.js @@ -0,0 +1,6 @@ +import { green, red } from './colors.js'; + +export default ` +.class { color: ${green}; } +body { background: ${red}; } +`; diff --git a/test/configCases/css/css-auto/style4.js b/test/configCases/css/css-auto/style4.js new file mode 100644 index 00000000000..c56e98fb281 --- /dev/null +++ b/test/configCases/css/css-auto/style4.js @@ -0,0 +1,6 @@ +import { green, red } from './colors.js'; + +export default ` +.class { color: ${green}; } +body { background: ${red}; } +`; diff --git a/test/configCases/css/css-auto/style6.modules.css b/test/configCases/css/css-auto/style6.modules.css new file mode 100644 index 00000000000..323ffaed199 --- /dev/null +++ b/test/configCases/css/css-auto/style6.modules.css @@ -0,0 +1,3 @@ +.class { + color: blue; +} diff --git a/test/configCases/css/css-auto/test.config.js b/test/configCases/css/css-auto/test.config.js new file mode 100644 index 00000000000..0590757288f --- /dev/null +++ b/test/configCases/css/css-auto/test.config.js @@ -0,0 +1,8 @@ +module.exports = { + moduleScope(scope) { + const link = scope.window.document.createElement("link"); + link.rel = "stylesheet"; + link.href = "bundle0.css"; + scope.window.document.head.appendChild(link); + } +}; diff --git a/test/configCases/css/css-auto/webpack.config.js b/test/configCases/css/css-auto/webpack.config.js new file mode 100644 index 00000000000..a9ddb2d852d --- /dev/null +++ b/test/configCases/css/css-auto/webpack.config.js @@ -0,0 +1,17 @@ +/** @type {import("../../../../types").Configuration} */ +module.exports = { + target: "web", + mode: "development", + experiments: { + css: true + }, + module: { + rules: [ + { + test: /\.less$/, + use: "less-loader", + type: "css/auto" + } + ] + } +}; diff --git a/test/configCases/css/css-import-at-middle/a.css b/test/configCases/css/css-import-at-middle/a.css new file mode 100644 index 00000000000..f0d5b13bffd --- /dev/null +++ b/test/configCases/css/css-import-at-middle/a.css @@ -0,0 +1,3 @@ +body { + background: red; +} diff --git a/test/configCases/css/css-import-at-middle/b.css b/test/configCases/css/css-import-at-middle/b.css new file mode 100644 index 00000000000..575be7ba729 --- /dev/null +++ b/test/configCases/css/css-import-at-middle/b.css @@ -0,0 +1,10 @@ +body { + background: blue; +} + +@import "./a.css"; +@import url(./a.css); + +body { + color: green; +} diff --git a/test/configCases/css/css-import-at-middle/c.css b/test/configCases/css/css-import-at-middle/c.css new file mode 100644 index 00000000000..8fc0fb15442 --- /dev/null +++ b/test/configCases/css/css-import-at-middle/c.css @@ -0,0 +1,9 @@ +body { + background: red; +} +@import "./a.css"; +@import "./b.css"; + +body { + color: yellow; +} diff --git a/test/configCases/css/css-import-at-middle/index.js b/test/configCases/css/css-import-at-middle/index.js new file mode 100644 index 00000000000..9b54f968864 --- /dev/null +++ b/test/configCases/css/css-import-at-middle/index.js @@ -0,0 +1,9 @@ +import "./style.css"; + +it("should compile with warnings", done => { + const style = getComputedStyle(document.body); + expect(style.getPropertyValue("background")).toBe(" blue"); + expect(style.getPropertyValue("color")).toBe(" green"); + + done(); +}); diff --git a/test/configCases/css/css-import-at-middle/style.css b/test/configCases/css/css-import-at-middle/style.css new file mode 100644 index 00000000000..1d835e13228 --- /dev/null +++ b/test/configCases/css/css-import-at-middle/style.css @@ -0,0 +1,2 @@ +@import "./c.css"; +@import "./b.css"; diff --git a/test/configCases/css/css-import-at-middle/test.config.js b/test/configCases/css/css-import-at-middle/test.config.js new file mode 100644 index 00000000000..0590757288f --- /dev/null +++ b/test/configCases/css/css-import-at-middle/test.config.js @@ -0,0 +1,8 @@ +module.exports = { + moduleScope(scope) { + const link = scope.window.document.createElement("link"); + link.rel = "stylesheet"; + link.href = "bundle0.css"; + scope.window.document.head.appendChild(link); + } +}; diff --git a/test/configCases/css/css-import-at-middle/warnings.js b/test/configCases/css/css-import-at-middle/warnings.js new file mode 100644 index 00000000000..dff5dce2b35 --- /dev/null +++ b/test/configCases/css/css-import-at-middle/warnings.js @@ -0,0 +1,6 @@ +module.exports = [ + /Any '@import' rules must precede all other rules/, + /Any '@import' rules must precede all other rules/, + /Any '@import' rules must precede all other rules/, + /Any '@import' rules must precede all other rules/ +]; diff --git a/test/configCases/css/css-import-at-middle/webpack.config.js b/test/configCases/css/css-import-at-middle/webpack.config.js new file mode 100644 index 00000000000..cfb8e5c0346 --- /dev/null +++ b/test/configCases/css/css-import-at-middle/webpack.config.js @@ -0,0 +1,8 @@ +/** @type {import("../../../../").Configuration} */ +module.exports = { + target: "web", + mode: "development", + experiments: { + css: true + } +}; diff --git a/test/configCases/css/css-import/all-deep-deep-nested.css b/test/configCases/css/css-import/all-deep-deep-nested.css new file mode 100644 index 00000000000..2b3fb00069f --- /dev/null +++ b/test/configCases/css/css-import/all-deep-deep-nested.css @@ -0,0 +1,3 @@ +.class { + deep-deep-nested: 1; +} diff --git a/test/configCases/css/css-import/all-deep-nested.css b/test/configCases/css/css-import/all-deep-nested.css new file mode 100644 index 00000000000..78ed2513899 --- /dev/null +++ b/test/configCases/css/css-import/all-deep-nested.css @@ -0,0 +1,5 @@ +@import "./all-deep-deep-nested.css" layer(baz) supports(display: table) screen and (min-width: 600px); + +.class { + deep-nested: 1; +} diff --git a/test/configCases/css/css-import/all-nested.css b/test/configCases/css/css-import/all-nested.css new file mode 100644 index 00000000000..1bfcebf48ac --- /dev/null +++ b/test/configCases/css/css-import/all-nested.css @@ -0,0 +1,5 @@ +@import "./all-deep-nested.css" layer(bar) supports(display: grid) screen and (min-width: 500px); + +.class { + nested: 1; +} diff --git a/test/configCases/css/css-import/anonymous-deep-deep-nested.css b/test/configCases/css/css-import/anonymous-deep-deep-nested.css new file mode 100644 index 00000000000..2b3fb00069f --- /dev/null +++ b/test/configCases/css/css-import/anonymous-deep-deep-nested.css @@ -0,0 +1,3 @@ +.class { + deep-deep-nested: 1; +} diff --git a/test/configCases/css/css-import/anonymous-deep-nested.css b/test/configCases/css/css-import/anonymous-deep-nested.css new file mode 100644 index 00000000000..f22d30e30b4 --- /dev/null +++ b/test/configCases/css/css-import/anonymous-deep-nested.css @@ -0,0 +1,5 @@ +@import "./anonymous-deep-deep-nested.css" layer; + +.class { + deep-nested: 1; +} diff --git a/test/configCases/css/css-import/anonymous-nested.css b/test/configCases/css/css-import/anonymous-nested.css new file mode 100644 index 00000000000..9187d233eea --- /dev/null +++ b/test/configCases/css/css-import/anonymous-nested.css @@ -0,0 +1,6 @@ +@import "./anonymous-deep-nested.css" layer; +@import "./layer-deep-nested.css" layer(base); + +.class { + deep-nested: 1; +} diff --git a/test/configCases/css/css-import/directory/index.css b/test/configCases/css/css-import/directory/index.css new file mode 100644 index 00000000000..dfd5bb45b24 --- /dev/null +++ b/test/configCases/css/css-import/directory/index.css @@ -0,0 +1,3 @@ +.directory-css { + color: red; +} \ No newline at end of file diff --git a/test/configCases/css/css-import/duplicate-nested.css b/test/configCases/css/css-import/duplicate-nested.css new file mode 100644 index 00000000000..94e620d7427 --- /dev/null +++ b/test/configCases/css/css-import/duplicate-nested.css @@ -0,0 +1,6 @@ +@import url("./style8.css") supports(display: flex); +@import url("./style8.css") supports(display: flex); + +.class { + duplicate-nested: true; +} diff --git a/test/configCases/css/css-import/errors.js b/test/configCases/css/css-import/errors.js new file mode 100644 index 00000000000..290655b24f3 --- /dev/null +++ b/test/configCases/css/css-import/errors.js @@ -0,0 +1,6 @@ +module.exports = [ + /Can't resolve 'non-exported-css'/, + /Can't resolve '\.\/directory'/, + /Can't resolve 'condition-names-subpath\/non-valid\.css'/, + /Can't resolve '\.\/no-extension-in-request'/ +]; diff --git a/test/configCases/css/css-import/extensions-imported.mycss b/test/configCases/css/css-import/extensions-imported.mycss new file mode 100644 index 00000000000..d70a689d7e7 --- /dev/null +++ b/test/configCases/css/css-import/extensions-imported.mycss @@ -0,0 +1,3 @@ +.custom-extension{ + color: green; +} \ No newline at end of file diff --git a/test/configCases/css/css-import/external.css b/test/configCases/css/css-import/external.css new file mode 100644 index 00000000000..2da62ee0768 --- /dev/null +++ b/test/configCases/css/css-import/external.css @@ -0,0 +1,3 @@ +body { + externally-imported: true; +} diff --git a/test/configCases/css/css-import/external1.css b/test/configCases/css/css-import/external1.css new file mode 100644 index 00000000000..f334e79ce27 --- /dev/null +++ b/test/configCases/css/css-import/external1.css @@ -0,0 +1,3 @@ +body { + externally-imported1: true; +} diff --git a/test/configCases/css/css-import/external2.css b/test/configCases/css/css-import/external2.css new file mode 100644 index 00000000000..8a7481f3e91 --- /dev/null +++ b/test/configCases/css/css-import/external2.css @@ -0,0 +1,3 @@ +body { + externally-imported2: true; +} diff --git a/test/configCases/css/css-import/file.less b/test/configCases/css/css-import/file.less new file mode 100644 index 00000000000..a5eb48d6d65 --- /dev/null +++ b/test/configCases/css/css-import/file.less @@ -0,0 +1,5 @@ +@link-color: #428bca; + +.link { + color: @link-color; +} diff --git a/test/configCases/css/css-import/img.png b/test/configCases/css/css-import/img.png new file mode 100644 index 00000000000..b74b839e2b8 Binary files /dev/null and b/test/configCases/css/css-import/img.png differ diff --git a/test/configCases/css/css-import/imported.css b/test/configCases/css/css-import/imported.css new file mode 100644 index 00000000000..828bff206d5 --- /dev/null +++ b/test/configCases/css/css-import/imported.css @@ -0,0 +1,3 @@ +body { + background: green; +} diff --git a/test/configCases/css/css-import/index.js b/test/configCases/css/css-import/index.js new file mode 100644 index 00000000000..3b26850a1e7 --- /dev/null +++ b/test/configCases/css/css-import/index.js @@ -0,0 +1,14 @@ +import "./style.css"; + +it("should compile", done => { + const links = document.getElementsByTagName("link"); + const css = []; + + // Skip first because import it by default + for (const link of links.slice(1)) { + css.push(link.sheet.css); + } + + expect(css).toMatchSnapshot(); + done(); +}); diff --git a/test/configCases/css/css-import/layer-deep-deep-nested.css b/test/configCases/css/css-import/layer-deep-deep-nested.css new file mode 100644 index 00000000000..2b3fb00069f --- /dev/null +++ b/test/configCases/css/css-import/layer-deep-deep-nested.css @@ -0,0 +1,3 @@ +.class { + deep-deep-nested: 1; +} diff --git a/test/configCases/css/css-import/layer-deep-nested.css b/test/configCases/css/css-import/layer-deep-nested.css new file mode 100644 index 00000000000..ad882bcd450 --- /dev/null +++ b/test/configCases/css/css-import/layer-deep-nested.css @@ -0,0 +1,5 @@ +@import "./layer-deep-deep-nested.css" layer(baz); + +.class { + deep-nested: 1; +} diff --git a/test/configCases/css/css-import/layer-nested.css b/test/configCases/css/css-import/layer-nested.css new file mode 100644 index 00000000000..476020101a6 --- /dev/null +++ b/test/configCases/css/css-import/layer-nested.css @@ -0,0 +1,5 @@ +@import "./layer-deep-nested.css" layer(bar); + +.class { + nested: 1; +} diff --git a/test/configCases/css/css-import/layer.css b/test/configCases/css/css-import/layer.css new file mode 100644 index 00000000000..317776dde97 --- /dev/null +++ b/test/configCases/css/css-import/layer.css @@ -0,0 +1,3 @@ +.class { + content: "layer.css"; +} diff --git a/test/configCases/css/css-import/media-deep-deep-nested.css b/test/configCases/css/css-import/media-deep-deep-nested.css new file mode 100644 index 00000000000..2b3fb00069f --- /dev/null +++ b/test/configCases/css/css-import/media-deep-deep-nested.css @@ -0,0 +1,3 @@ +.class { + deep-deep-nested: 1; +} diff --git a/test/configCases/css/css-import/media-deep-nested.css b/test/configCases/css/css-import/media-deep-nested.css new file mode 100644 index 00000000000..b49af1e9239 --- /dev/null +++ b/test/configCases/css/css-import/media-deep-nested.css @@ -0,0 +1,5 @@ +@import "./media-deep-deep-nested.css" screen and (orientation: portrait); + +.class { + deep-nested: 1; +} diff --git a/test/configCases/css/css-import/media-nested.css b/test/configCases/css/css-import/media-nested.css new file mode 100644 index 00000000000..74f9e969f2c --- /dev/null +++ b/test/configCases/css/css-import/media-nested.css @@ -0,0 +1,5 @@ +@import "./media-deep-nested.css" screen and (max-width: 500px); + +.class { + nested: 1; +} diff --git a/test/configCases/css/css-import/mixed-deep-deep-nested.css b/test/configCases/css/css-import/mixed-deep-deep-nested.css new file mode 100644 index 00000000000..2b3fb00069f --- /dev/null +++ b/test/configCases/css/css-import/mixed-deep-deep-nested.css @@ -0,0 +1,3 @@ +.class { + deep-deep-nested: 1; +} diff --git a/test/configCases/css/css-import/mixed-deep-nested.css b/test/configCases/css/css-import/mixed-deep-nested.css new file mode 100644 index 00000000000..f646d9558db --- /dev/null +++ b/test/configCases/css/css-import/mixed-deep-nested.css @@ -0,0 +1,5 @@ +@import "./mixed-deep-deep-nested.css" layer(bar); + +.class { + deep-nested: 1; +} diff --git a/test/configCases/css/css-import/mixed-nested.css b/test/configCases/css/css-import/mixed-nested.css new file mode 100644 index 00000000000..af6552df728 --- /dev/null +++ b/test/configCases/css/css-import/mixed-nested.css @@ -0,0 +1,5 @@ +@import "./mixed-deep-nested.css" supports(display: flex); + +.class { + nested: 1; +} diff --git a/test/configCases/css/css-import/no-extension-in-request.css b/test/configCases/css/css-import/no-extension-in-request.css new file mode 100644 index 00000000000..e69de29bb2d diff --git a/test/configCases/css/css-import/node_modules/condition-names-custom-name/custom-name.css b/test/configCases/css/css-import/node_modules/condition-names-custom-name/custom-name.css new file mode 100644 index 00000000000..438223bb105 --- /dev/null +++ b/test/configCases/css/css-import/node_modules/condition-names-custom-name/custom-name.css @@ -0,0 +1,3 @@ +.custom-name { + color: steelblue; +} diff --git a/test/configCases/css/css-import/node_modules/condition-names-custom-name/default.css b/test/configCases/css/css-import/node_modules/condition-names-custom-name/default.css new file mode 100644 index 00000000000..03ea02130bf --- /dev/null +++ b/test/configCases/css/css-import/node_modules/condition-names-custom-name/default.css @@ -0,0 +1,3 @@ +.default { + color: steelblue; +} diff --git a/test/configCases/css/css-import/node_modules/condition-names-custom-name/package.json b/test/configCases/css/css-import/node_modules/condition-names-custom-name/package.json new file mode 100644 index 00000000000..72986fb14da --- /dev/null +++ b/test/configCases/css/css-import/node_modules/condition-names-custom-name/package.json @@ -0,0 +1,9 @@ +{ + "name": "condition-names-custom-name", + "exports": { + ".": { + "custom-name": "./custom-name.css", + "default": "./default.css" + } + } +} diff --git a/test/configCases/css/css-import/node_modules/condition-names-style-less/default.less b/test/configCases/css/css-import/node_modules/condition-names-style-less/default.less new file mode 100644 index 00000000000..37deb87d851 --- /dev/null +++ b/test/configCases/css/css-import/node_modules/condition-names-style-less/default.less @@ -0,0 +1,5 @@ +@link-color: #428bca; + +.conditional-names { + color: @link-color; +} diff --git a/test/configCases/css/css-import/node_modules/condition-names-style-less/package.json b/test/configCases/css/css-import/node_modules/condition-names-style-less/package.json new file mode 100644 index 00000000000..3eb7a0ae36c --- /dev/null +++ b/test/configCases/css/css-import/node_modules/condition-names-style-less/package.json @@ -0,0 +1,8 @@ +{ + "name": "condition-names-style-less", + "exports": { + ".": { + "default": "./default.less" + } + } +} diff --git a/test/configCases/css/css-import/node_modules/condition-names-style-mode/default.css b/test/configCases/css/css-import/node_modules/condition-names-style-mode/default.css new file mode 100644 index 00000000000..03ea02130bf --- /dev/null +++ b/test/configCases/css/css-import/node_modules/condition-names-style-mode/default.css @@ -0,0 +1,3 @@ +.default { + color: steelblue; +} diff --git a/test/configCases/css/css-import/node_modules/condition-names-style-mode/mode.css b/test/configCases/css/css-import/node_modules/condition-names-style-mode/mode.css new file mode 100644 index 00000000000..300f0091cfc --- /dev/null +++ b/test/configCases/css/css-import/node_modules/condition-names-style-mode/mode.css @@ -0,0 +1,3 @@ +.mode { + color: red; +} diff --git a/test/configCases/css/css-import/node_modules/condition-names-style-mode/package.json b/test/configCases/css/css-import/node_modules/condition-names-style-mode/package.json new file mode 100644 index 00000000000..55ade3385c8 --- /dev/null +++ b/test/configCases/css/css-import/node_modules/condition-names-style-mode/package.json @@ -0,0 +1,10 @@ +{ + "name": "condition-names-style-development", + "exports": { + ".": { + "production": "./mode.css", + "development": "./mode.css", + "default": "./default.css" + } + } +} diff --git a/test/configCases/css/css-import/node_modules/condition-names-style-nested/default.css b/test/configCases/css/css-import/node_modules/condition-names-style-nested/default.css new file mode 100644 index 00000000000..03ea02130bf --- /dev/null +++ b/test/configCases/css/css-import/node_modules/condition-names-style-nested/default.css @@ -0,0 +1,3 @@ +.default { + color: steelblue; +} diff --git a/test/configCases/css/css-import/node_modules/condition-names-style-nested/package.json b/test/configCases/css/css-import/node_modules/condition-names-style-nested/package.json new file mode 100644 index 00000000000..1181e52d22d --- /dev/null +++ b/test/configCases/css/css-import/node_modules/condition-names-style-nested/package.json @@ -0,0 +1,8 @@ +{ + "name": "condition-names-style-nested", + "exports": { + "style": { + "default": "./default.css" + } + } +} diff --git a/test/configCases/css/css-import/node_modules/condition-names-style/default.css b/test/configCases/css/css-import/node_modules/condition-names-style/default.css new file mode 100644 index 00000000000..03ea02130bf --- /dev/null +++ b/test/configCases/css/css-import/node_modules/condition-names-style/default.css @@ -0,0 +1,3 @@ +.default { + color: steelblue; +} diff --git a/test/configCases/css/css-import/node_modules/condition-names-style/package.json b/test/configCases/css/css-import/node_modules/condition-names-style/package.json new file mode 100644 index 00000000000..b397e56043d --- /dev/null +++ b/test/configCases/css/css-import/node_modules/condition-names-style/package.json @@ -0,0 +1,9 @@ +{ + "name": "condition-names-style", + "exports": { + ".": { + "style": "./default.css", + "default": "./unknown.css" + } + } +} diff --git a/test/configCases/css/css-import/node_modules/condition-names-subpath-extra/custom.js b/test/configCases/css/css-import/node_modules/condition-names-subpath-extra/custom.js new file mode 100644 index 00000000000..b77c717214b --- /dev/null +++ b/test/configCases/css/css-import/node_modules/condition-names-subpath-extra/custom.js @@ -0,0 +1 @@ +export default "should not be used"; diff --git a/test/configCases/css/css-import/node_modules/condition-names-subpath-extra/dist/custom.css b/test/configCases/css/css-import/node_modules/condition-names-subpath-extra/dist/custom.css new file mode 100644 index 00000000000..7920c3d9f42 --- /dev/null +++ b/test/configCases/css/css-import/node_modules/condition-names-subpath-extra/dist/custom.css @@ -0,0 +1,3 @@ +.dist { + color: steelblue; +} diff --git a/test/configCases/css/css-import/node_modules/condition-names-subpath-extra/package.json b/test/configCases/css/css-import/node_modules/condition-names-subpath-extra/package.json new file mode 100644 index 00000000000..795cf640f88 --- /dev/null +++ b/test/configCases/css/css-import/node_modules/condition-names-subpath-extra/package.json @@ -0,0 +1,6 @@ +{ + "name": "condition-names-subpath-extra", + "exports": { + "./custom.css":"./dist/custom.css" + } +} diff --git a/test/configCases/css/css-import/node_modules/condition-names-subpath/custom.js b/test/configCases/css/css-import/node_modules/condition-names-subpath/custom.js new file mode 100644 index 00000000000..b77c717214b --- /dev/null +++ b/test/configCases/css/css-import/node_modules/condition-names-subpath/custom.js @@ -0,0 +1 @@ +export default "should not be used"; diff --git a/test/configCases/css/css-import/node_modules/condition-names-subpath/dist/custom.css b/test/configCases/css/css-import/node_modules/condition-names-subpath/dist/custom.css new file mode 100644 index 00000000000..7920c3d9f42 --- /dev/null +++ b/test/configCases/css/css-import/node_modules/condition-names-subpath/dist/custom.css @@ -0,0 +1,3 @@ +.dist { + color: steelblue; +} diff --git a/test/configCases/css/css-import/node_modules/condition-names-subpath/package.json b/test/configCases/css/css-import/node_modules/condition-names-subpath/package.json new file mode 100644 index 00000000000..8c94521a959 --- /dev/null +++ b/test/configCases/css/css-import/node_modules/condition-names-subpath/package.json @@ -0,0 +1,11 @@ +{ + "name": "condition-names-subpath", + "exports": { + "./custom.css": { + "default": "./dist/custom.css" + }, + "./non-valid.css": { + "default": "./dist/custom.js" + } + } +} diff --git a/test/configCases/css/css-import/node_modules/condition-names-webpack-js/package.json b/test/configCases/css/css-import/node_modules/condition-names-webpack-js/package.json new file mode 100644 index 00000000000..21c3e50d229 --- /dev/null +++ b/test/configCases/css/css-import/node_modules/condition-names-webpack-js/package.json @@ -0,0 +1,9 @@ +{ + "name": "condition-names-webpack", + "exports": { + ".": { + "webpack": "./webpack.js", + "default": "./unknown.js" + } + } +} diff --git a/test/configCases/css/css-import/node_modules/condition-names-webpack-js/webpack.js b/test/configCases/css/css-import/node_modules/condition-names-webpack-js/webpack.js new file mode 100644 index 00000000000..bc0fdf485a6 --- /dev/null +++ b/test/configCases/css/css-import/node_modules/condition-names-webpack-js/webpack.js @@ -0,0 +1 @@ +export default "webpack"; diff --git a/test/configCases/css/css-import/node_modules/condition-names-webpack/package.json b/test/configCases/css/css-import/node_modules/condition-names-webpack/package.json new file mode 100644 index 00000000000..471a210fa9b --- /dev/null +++ b/test/configCases/css/css-import/node_modules/condition-names-webpack/package.json @@ -0,0 +1,9 @@ +{ + "name": "condition-names-webpack", + "exports": { + ".": { + "webpack": "./webpack.css", + "default": "./unknown.css" + } + } +} diff --git a/test/configCases/css/css-import/node_modules/condition-names-webpack/webpack.css b/test/configCases/css/css-import/node_modules/condition-names-webpack/webpack.css new file mode 100644 index 00000000000..44867d273a4 --- /dev/null +++ b/test/configCases/css/css-import/node_modules/condition-names-webpack/webpack.css @@ -0,0 +1,3 @@ +.webpack { + color: steelblue; +} diff --git a/test/configCases/css/css-import/node_modules/js-import/index.js b/test/configCases/css/css-import/node_modules/js-import/index.js new file mode 100644 index 00000000000..0b2a8ed66e2 --- /dev/null +++ b/test/configCases/css/css-import/node_modules/js-import/index.js @@ -0,0 +1,3 @@ +function someCode() { + console.log('some code'); +} \ No newline at end of file diff --git a/test/configCases/css/css-import/node_modules/js-import/package.json b/test/configCases/css/css-import/node_modules/js-import/package.json new file mode 100644 index 00000000000..1f4546b29f3 --- /dev/null +++ b/test/configCases/css/css-import/node_modules/js-import/package.json @@ -0,0 +1,3 @@ +{ + "main": "index.js" +} \ No newline at end of file diff --git a/test/configCases/css/css-import/node_modules/main-field/package.json b/test/configCases/css/css-import/node_modules/main-field/package.json new file mode 100644 index 00000000000..51c982d306f --- /dev/null +++ b/test/configCases/css/css-import/node_modules/main-field/package.json @@ -0,0 +1,3 @@ +{ + "main": "styles.css" +} \ No newline at end of file diff --git a/test/configCases/css/css-import/node_modules/main-field/styles.css b/test/configCases/css/css-import/node_modules/main-field/styles.css new file mode 100644 index 00000000000..7ccc4470fc5 --- /dev/null +++ b/test/configCases/css/css-import/node_modules/main-field/styles.css @@ -0,0 +1,3 @@ +p { + color: antiquewhite; +} diff --git a/test/configCases/css/css-import/node_modules/non-exported-css/index.css b/test/configCases/css/css-import/node_modules/non-exported-css/index.css new file mode 100644 index 00000000000..3b220caa96f --- /dev/null +++ b/test/configCases/css/css-import/node_modules/non-exported-css/index.css @@ -0,0 +1,3 @@ +.non-exported-css{ + color: red; +} \ No newline at end of file diff --git a/test/configCases/css/css-import/node_modules/non-exported-css/package.json b/test/configCases/css/css-import/node_modules/non-exported-css/package.json new file mode 100644 index 00000000000..55c03f597b3 --- /dev/null +++ b/test/configCases/css/css-import/node_modules/non-exported-css/package.json @@ -0,0 +1,3 @@ +{ + "name": "non-exported-css" +} \ No newline at end of file diff --git a/test/configCases/css/css-import/node_modules/package-with-exports/index.cjs b/test/configCases/css/css-import/node_modules/package-with-exports/index.cjs new file mode 100644 index 00000000000..e69de29bb2d diff --git a/test/configCases/css/css-import/node_modules/package-with-exports/index.js b/test/configCases/css/css-import/node_modules/package-with-exports/index.js new file mode 100644 index 00000000000..e69de29bb2d diff --git a/test/configCases/css/css-import/node_modules/package-with-exports/package.json b/test/configCases/css/css-import/node_modules/package-with-exports/package.json new file mode 100644 index 00000000000..9b5e2b602a8 --- /dev/null +++ b/test/configCases/css/css-import/node_modules/package-with-exports/package.json @@ -0,0 +1,19 @@ +{ + "name": "package-with-exports", + "version": "1.0.0", + "description": "test", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "", + "license": "MIT", + "type": "module", + "module": "index.js", + "main": "index.cjs", + "style": "style.css", + "exports": { + "style": "./style.css", + "require": "./index.cjs", + "import": "./index.js" + } +} diff --git a/test/configCases/css/css-import/node_modules/package-with-exports/style.css b/test/configCases/css/css-import/node_modules/package-with-exports/style.css new file mode 100644 index 00000000000..38ef857cb7d --- /dev/null +++ b/test/configCases/css/css-import/node_modules/package-with-exports/style.css @@ -0,0 +1,3 @@ +.load-me { + color: red; +} diff --git a/test/configCases/css/css-import/node_modules/prefer-relative.css/package.json b/test/configCases/css/css-import/node_modules/prefer-relative.css/package.json new file mode 100644 index 00000000000..183575c78ed --- /dev/null +++ b/test/configCases/css/css-import/node_modules/prefer-relative.css/package.json @@ -0,0 +1,4 @@ +{ + "name": "prefer-relative.css", + "style": "./styles.css" +} diff --git a/test/configCases/css/css-import/node_modules/prefer-relative.css/styles.css b/test/configCases/css/css-import/node_modules/prefer-relative.css/styles.css new file mode 100644 index 00000000000..f8ad35f95ed --- /dev/null +++ b/test/configCases/css/css-import/node_modules/prefer-relative.css/styles.css @@ -0,0 +1,3 @@ +.should-be-not-imported { + color: steelblue; +} diff --git a/test/configCases/css/css-import/node_modules/style-and-main-library/main.css b/test/configCases/css/css-import/node_modules/style-and-main-library/main.css new file mode 100644 index 00000000000..864a5060ae2 --- /dev/null +++ b/test/configCases/css/css-import/node_modules/style-and-main-library/main.css @@ -0,0 +1,3 @@ +.main { + color: steelblue; +} diff --git a/test/configCases/css/css-import/node_modules/style-and-main-library/package.json b/test/configCases/css/css-import/node_modules/style-and-main-library/package.json new file mode 100644 index 00000000000..f0dab2e32cb --- /dev/null +++ b/test/configCases/css/css-import/node_modules/style-and-main-library/package.json @@ -0,0 +1,4 @@ +{ + "name": "style-and-main-library", + "style": "./styles.css" +} diff --git a/test/configCases/css/css-import/node_modules/style-and-main-library/styles.css b/test/configCases/css/css-import/node_modules/style-and-main-library/styles.css new file mode 100644 index 00000000000..b5795b7efc5 --- /dev/null +++ b/test/configCases/css/css-import/node_modules/style-and-main-library/styles.css @@ -0,0 +1,3 @@ +.style { + color: steelblue; +} diff --git a/test/configCases/css/css-import/node_modules/style-library/package.json b/test/configCases/css/css-import/node_modules/style-library/package.json new file mode 100644 index 00000000000..4b64f1e4715 --- /dev/null +++ b/test/configCases/css/css-import/node_modules/style-library/package.json @@ -0,0 +1,4 @@ +{ + "name": "style-library", + "style": "./styles.css" +} diff --git a/test/configCases/css/css-import/node_modules/style-library/styles.css b/test/configCases/css/css-import/node_modules/style-library/styles.css new file mode 100644 index 00000000000..cf378a3afca --- /dev/null +++ b/test/configCases/css/css-import/node_modules/style-library/styles.css @@ -0,0 +1,3 @@ +p { + color: steelblue; +} diff --git a/test/configCases/css/css-import/prefer-relative.css b/test/configCases/css/css-import/prefer-relative.css new file mode 100644 index 00000000000..53ebf9f616d --- /dev/null +++ b/test/configCases/css/css-import/prefer-relative.css @@ -0,0 +1,3 @@ +.relative { + color: red; +} diff --git a/test/configCases/css/css-import/print.css b/test/configCases/css/css-import/print.css new file mode 100644 index 00000000000..5fa2bfe59ff --- /dev/null +++ b/test/configCases/css/css-import/print.css @@ -0,0 +1,3 @@ +body { + background: black; +} diff --git a/test/configCases/css/css-import/some-file.js b/test/configCases/css/css-import/some-file.js new file mode 100644 index 00000000000..ba55c81f9c5 --- /dev/null +++ b/test/configCases/css/css-import/some-file.js @@ -0,0 +1,3 @@ +function doNotImportCss() { + return 'doNotImportCss'; +} \ No newline at end of file diff --git a/test/configCases/css/css-import/string-loader.js b/test/configCases/css/css-import/string-loader.js new file mode 100644 index 00000000000..f34eccc67ff --- /dev/null +++ b/test/configCases/css/css-import/string-loader.js @@ -0,0 +1,3 @@ +module.exports = function loader(content) { + return content + `.using-loader { color: red; }`; +}; diff --git a/test/configCases/css/css-import/styl'le7.css b/test/configCases/css/css-import/styl'le7.css new file mode 100644 index 00000000000..8e5fc45d459 --- /dev/null +++ b/test/configCases/css/css-import/styl'le7.css @@ -0,0 +1,3 @@ +.class { + content: "style7.css"; +} diff --git a/test/configCases/css/css-import/style-import.css b/test/configCases/css/css-import/style-import.css new file mode 100644 index 00000000000..043966ece80 --- /dev/null +++ b/test/configCases/css/css-import/style-import.css @@ -0,0 +1,28 @@ +@import "style-library"; +@import "main-field"; +@import "package-with-exports"; +@import "./extensions-imported.mycss"; +@import "./with-less-import.css"; +@import "prefer-relative.css"; +@import "condition-names-style"; +@import "condition-names-style-mode"; +@import "condition-names-subpath/custom.css"; +@import "condition-names-subpath-extra/custom.css"; +@import "condition-names-style-less"; +@import "condition-names-custom-name"; +@import "style-and-main-library"; +@import "condition-names-webpack"; +@import "condition-names-style-nested"; + +/* Technically, this is not entirely true, but we allow it because the final file can be processed by the loader and return the CSS code */ + +@import "js-import"; +@import "condition-names-webpack-js"; +@import url("some-file.js"); + +/* Failed */ + +@import "non-exported-css"; +@import "./directory"; +@import "condition-names-subpath/non-valid.css"; +@import "./no-extension-in-request"; diff --git a/test/configCases/css/css-import/style.css b/test/configCases/css/css-import/style.css new file mode 100644 index 00000000000..8089f5bb580 --- /dev/null +++ b/test/configCases/css/css-import/style.css @@ -0,0 +1,262 @@ +@import "./style-import.css"; +@import "print.css?foo=1"; +@import url("print.css?foo=2"); +@import "print.css?foo=3" layer(default); +@import url("print.css?foo=4") layer(default); +@import "print.css?foo=5" supports(display: flex); +@import url("print.css?foo=6") supports(display: flex); +@import "print.css?foo=7" screen and (min-width: 400px); +@import url("print.css?foo=8") screen and (min-width: 400px); +@import "print.css?foo=9" layer(default) supports(display: flex); +@import "print.css?foo=10" layer(default) screen and (min-width: 400px); +@import "print.css?foo=11" supports(display: flex) screen and (min-width: 400px); +@import "print.css?foo=12" layer(default) supports(display: flex) screen and (min-width: 400px); +@import "print.css?foo=13"layer(default)supports(display: flex)screen and (min-width: 400px); +@import url(print.css?foo=14)layer(default)supports(display: flex)screen and (min-width: 400px); +@import url("print.css?foo=15")layer(default)supports(display: flex)screen and (min-width: 400px); +@import url(print.css?foo=16)layer(default)supports(background: url(./img.png))screen and (min-width: 400px); +@import url(print.css?foo=17)layer(default)supports(background: url("./img.png"))screen and (min-width: 400px); +@import url(print.css?foo=18)screen; +@import url("print.css?foo=19")screen; +@import "print.css?foo=20"screen; +@import url(print.css?foo=18) screen ; +@import url("print.css?foo=19") screen ; +@import "print.css?foo=20" screen ; +@import "print.css?foo=21" ; + +/* Has the same URL */ +@import "imported.css"; +@import "imported.css" layer(base); +@import "imported.css" supports(display: flex); +@import "imported.css" screen, print; + +@import url(style2.css?foo=1); +@import url('style2.css?foo=2'); +@import url("style2.css?foo=3"); +@IMPORT url(style2.css?foo=4); +@import URL(style2.css?foo=5); +@import url(style2.css?foo=6 ); +@import url( style2.css?foo=7); +@import url( style2.css?foo=8 ); +@import url( +style2.css?foo=9 +); +@import url(); +@import url(''); +@import url(""); +@import ''; +@import ""; +@import " "; +@import "\ +"; +@import url(); +@import url(''); +@import url(""); +@import url("") /* test */; +@import url("") screen and (orientation:landscape); +@import url(style2.css) screen and (orientation:landscape); +@import url(style2.css) SCREEN AND (ORIENTATION: LANDSCAPE); +@import url(style2.css)screen and (orientation:landscape); +@import url(style2.css) screen and (orientation:landscape); +@import url(style2.css) screen and (orientation:landscape); +@import url(style2.css) (min-width: 100px); +@import url(https://test.cases/path/../../../../configCases/css/css-import/external.css); +@import url(https://test.cases/path/../../../../configCases/css/css-import/external.css) screen and (orientation:landscape); +@import "//example.com/style.css"; +@import url('test.css?foo=1&bar=1'); +@import url('style2.css?foo=1&bar=1#hash'); +@import url('style2.css?foo=1&bar=1#hash') screen and (orientation:landscape); +@import url('https://fonts.googleapis.com/css?family=Roboto'); +@import url('https://fonts.googleapis.com/css?family=Noto+Sans+TC'); +@import url('https://fonts.googleapis.com/css?family=Noto+Sans+TC|Roboto'); +@import url('https://fonts.googleapis.com/css?family=Noto+Sans+TC|Roboto?foo=1') layer(super.foo) supports(display: flex) screen and (min-width: 400px); + +@import './sty\ +le3.css?bar=1'; +@import './sty\ +\ +\ +le3.css?bar=2'; +@import url('./sty\ +le3.css?bar=3'); +@import url('./sty\ +\ +\ +le3.css?=bar4'); + +@import "./styl'le7.css"; +@import url("./styl'le7.css?foo=1"); +@import './styl\'le7.css'; +@import url('./styl\'le7.css'); +@import './test test.css'; +@import url('./test test.css?foo=1'); +@import './test\ test.css?foo=2'; +@import url('./test\ test.css?foo=3'); +@import './test%20test.css?foo=4'; +@import url('./test%20test.css?foo=5'); +@import './\74\65\73\74.css'; +@import url('./\74\65\73\74.css?foo=1'); +@import './t\65\73\74.css?foo=2'; +@import url('./t\65\73\74.css?foo=3'); +@import url(./test\ test.css?foo=6); +@import url(./t\65st%20test.css?foo=7); +@import url('./t\65st%20test.css?foo=8'); +@import url("./t\65st%20test.css?foo=9"); +@import "./t\65st%20test.css?fpp=10"; +@import './t\65st%20test.css?foo=11'; +@import url( style6.css?foo=bazz ); +@import '\ +\ +\ +'; +@import url('./string-loader.js?esModule=false!./test.css'); +@import url(style4.css?foo=bar); +@import url(style4.css?foo=bar#hash); +@import url(style4.css?#hash); +@import "style4.css?foo=1" supports(display: flex); +@import "style4.css?foo=2" supports(display: flex) screen and (orientation:landscape); + +@import " ./style4.css?foo=3 "; +@import url(' ./style4.css?foo=4 '); +@import url( ./style4.css?foo=5 ); + +@import url(' https://fonts.googleapis.com/css?family=Roboto '); +@import url('./string-loader.js?esModule=false'); +@import url(' ./string-loader.js?esModule=false!./test.css ') screen and (orientation: landscape); +@import url(data:text/css;charset=utf-8,a%20%7B%0D%0A%20%20color%3A%20red%3B%0D%0A%7D); +@import url(data:text/css;charset=utf-8,a%20%7B%0D%0A%20%20color%3A%20blue%3B%0D%0A%7D) screen and (orientation:landscape); +@import url("data:text/css;charset=utf-8;base64,YSB7DQogIGNvbG9yOiByZWQ7DQp9"); + +@import url("./style5.css?foo=1") supports(); +@import url("./style5.css?foo=2") supports( ); +@import url("./style5.css?foo=3") supports(unknown); +@import url("./style5.css?foo=4") supports(display: flex); +@import url("./style5.css?foo=5") supports(display: flex !important); +@import url("./style5.css?foo=6") supports(display: flex) screen and (min-width: 400px); +@import url("./style5.css?foo=7") supports(selector(a b)); +@import url("./style5.css?foo=8") supports( display: flex ); +@import url("./layer.css?foo=1") layer; +@import url("./layer.css?foo=2") layer(default); +@import url("./layer.css?foo=3") layer(default) supports(display: flex) screen and (min-width: 400px); +@import url("./layer.css?foo=3") layer supports(display: flex) screen and (min-width: 400px); +@import url("./layer.css?foo=4") layer() supports(display: flex) screen and (min-width: 400px); +@import url("./layer.css?foo=5") layer(); +@import url("./layer.css?foo=6") layer( foo.bar.baz ); +@import url("./layer.css?foo=7") layer( ); +@import url("./style6.css")layer(default)supports(display: flex)screen and (min-width:400px); +@import "./style6.css?foo=1"layer(default)supports(display: flex)screen and (min-width:400px); +@import "./style6.css?foo=2"supports(display: flex)screen and (min-width:400px); +@import "./style6.css?foo=3"screen and (min-width:400px); +@import url("./style6.css?foo=4")screen and (min-width:400px); +@import url(./style6.css?foo=5)screen and (min-width:400px); +@import url("./style6.css?foo=6") layer( default ) supports( display : flex ) screen and ( min-width : 400px ); +@import URL("./style6.css?foo=7") LAYER(DEFAULT) SUPPORTS(DISPLAY: FLEX) SCREEN AND (MIN-WIDTH: 400PX); +@import url("./style6.css?foo=8") LAYER SUPPORTS(DISPLAY: FLEX) SCREEN AND (MIN-WIDTH: 400PX); +@import url("./style6.css?foo=9") /* Comment */ layer(/* Comment */default/* Comment */) /* Comment */ supports(/* Comment */display/* Comment */:/* Comment */ flex/* Comment */)/* Comment */ screen/* Comment */ and/* Comment */ (/* Comment */min-width/* Comment */: /* Comment */400px/* Comment */); +@import url(style6.css?foo=10) /* Comment */; +@import url(style6.css?foo=11) /* Comment */ /* Comment */; +@import url(style6.css?foo=12) /* Comment *//* Comment */; +@import url(style6.css?foo=13)/* Comment *//* Comment */; +@import +url(style6.css?foo=14) +/* Comment */ +/* Comment */; +@import /* Comment */ url(style6.css?foo=15) /* Comment */; +@import url(style6.css?foo=16) /* Comment */ print and (orientation:landscape); +@import url(style6.css?foo=17)/* Comment */print and (orientation:landscape)/* Comment */; +@import /* Comment */ url(style6.css?foo=18) /* Comment */ print and (orientation:landscape); + +@import url("./style8.css") screen and (min-width: 400px); +@import url("./style8.css") (prefers-color-scheme: dark); +@import url("./style8.css") supports(display: flex); +@import url("./style8.css") supports(((display: flex))); +@import url("./style8.css") supports(((display: inline-grid))) screen and (((min-width: 400px))); +@import url("./style8.css") supports(display: flex); +@import url('./style8.css') supports(display: grid); +@import url("./style8.css") supports(display: flex) screen and (min-width: 400px); +@import url("./style8.css") layer(framework); +@import url("./style8.css") layer(default); +@import url("./style8.css") layer(base); +@import url("./style8.css") layer(default) supports(display: flex); +@import url("./style8.css") layer(default) supports(display: flex) screen and (min-width: 400px); + +/* anonymous */ +@import "style2.css" layer(); +@import "style2.css" layer; + +/* All unknown parse as media for compatibility */ +@import url("./style9.css") unknown(default) unknown(display: flex) unknown; +@import url("./style9.css") unknown(default); + +@import url("./style10.css"); + +@import "./media-nested.css" screen and (min-width: 400px); +@import "./supports-nested.css" supports(display: flex); +@import "./layer-nested.css" layer(foo); +@import "./all-nested.css" layer(foo) supports(display: flex) screen and (min-width: 400px); +@import "./mixed-nested.css" screen and (min-width: 400px); +@import "./anonymous-nested.css" layer; +@import "./media-deep-deep-nested.css" screen and (orientation: portrait); +@import "./duplicate-nested.css" screen and (orientation: portrait); +@import "./anonymous-nested.css" supports(display: flex) screen and (orientation: portrait); +@import "./all-nested.css" layer(super.foo) supports(display: flex) screen and (min-width: 400px); + +/* Inside support */ + +@import url("/style2.css?warning=6") supports(unknown: layer(super.foo)) screen and (min-width: 400px); +@import url("/style2.css?warning=7") supports(url: url("./unknown.css")) screen and (min-width: 400px); +@import url("/style2.css?warning=8") supports(url: url(./unknown.css)) screen and (min-width: 400px); + +/** Possible syntax in future */ + +@import url("/style2.css?foo=unknown") layer(super.foo) supports(display: flex) unknown("foo") screen and (min-width: 400px); +@import url("/style2.css?foo=unknown1") layer(super.foo) supports(display: url("./unknown.css")) unknown(foo) screen and (min-width: 400px); +@import url("/style2.css?foo=unknown2") layer(super.foo) supports(display: url(./unknown.css)) "foo" screen and (min-width: 400px); +@import "./style2.css?unknown3" "string"; + +/** Unknown */ + +@import-normalize; + +/** Warnings */ + +@import nourl(test.css); +@import ; +@import foo-bar; +@import layer(super.foo) "./style2.css?warning=1" supports(display: flex) screen and (min-width: 400px); +@import layer(super.foo) supports(display: flex) "./style2.css?warning=2" screen and (min-width: 400px); +@import layer(super.foo) supports(display: flex) screen and (min-width: 400px) "./style2.css?warning=3"; +@import layer(super.foo) url("./style2.css?warning=4") supports(display: flex) screen and (min-width: 400px); +@import layer(super.foo) supports(display: flex) url("./style2.css?warning=5") screen and (min-width: 400px); +@import layer(super.foo) supports(display: flex) screen and (min-width: 400px) url("./style2.css?warning=6"); +@import url("/style2.css?warning=6") supports(display: flex) layer(super.foo) screen and (min-width: 400px); +@namespace url(http://www.w3.org/1999/xhtml); +@import url("./style2.css?after-namespace"); +@import supports(background: url("./img.png")); +@import supports(background: url("./img.png")) screen and (min-width: 400px); +@import layer(test) supports(background: url("./img.png")) screen and (min-width: 400px); +@import screen and (min-width: 400px); + +@import url(./style2.css?multiple=1) url(./style2.css?multiple=2); +@import url("./style2.css?multiple=3") url("./style2.css?multiple=4"); +@import "./style2.css?strange=3" url("./style2.css?multiple=4"); + +@import url("external-1.css"); +@import url("external-2.css") supports(display: grid) screen and (max-width: 400px); +@import url("external-3.css") supports(not (display: grid) and (display: flex)) screen and (max-width: 400px); +@import url("external-4.css") supports((selector(h2 > p)) and + (font-tech(color-COLRv1))); +@import url(external-5.css) layer(default); +@import url(external-6.css) layer(default); +@import url("external-7.css") layer(); +@import url("external-8.css") layer; +@import url("external-9.css") print; +@import url("external-10.css") print, screen; +@import url("external-11.css") screen; +@import url("external-12.css") screen and (orientation: landscape); +@import url("external-13.css") supports(not (display: flex)); +@import url("external-14.css") layer(default) supports(display: grid) screen and (max-width: 400px); + +body { + background: red; +} diff --git a/test/configCases/css/css-import/style10.css b/test/configCases/css/css-import/style10.css new file mode 100644 index 00000000000..6d75449c3b5 --- /dev/null +++ b/test/configCases/css/css-import/style10.css @@ -0,0 +1,9 @@ +@import url(./style11.css); +@import url(https://test.cases/path/../../../../configCases/css/css-import/external1.css); +@import url(./style12.css); +@import url(./style13.css); + + +.style10 { + color: red; +} diff --git a/test/configCases/css/css-import/style11.css b/test/configCases/css/css-import/style11.css new file mode 100644 index 00000000000..09831e221ec --- /dev/null +++ b/test/configCases/css/css-import/style11.css @@ -0,0 +1,3 @@ +.style11 { + color: red; +} diff --git a/test/configCases/css/css-import/style12.css b/test/configCases/css/css-import/style12.css new file mode 100644 index 00000000000..72fbefafc03 --- /dev/null +++ b/test/configCases/css/css-import/style12.css @@ -0,0 +1,5 @@ +@import url(https://test.cases/path/../../../../configCases/css/css-import/external2.css); + +.style12 { + color: red; +} diff --git a/test/configCases/css/css-import/style13.css b/test/configCases/css/css-import/style13.css new file mode 100644 index 00000000000..e3450265ad2 --- /dev/null +++ b/test/configCases/css/css-import/style13.css @@ -0,0 +1 @@ +@import url(https://test.cases/path/../../../../configCases/css/css-import/external2.css);div{color: red;} diff --git a/test/configCases/css/css-import/style2.css b/test/configCases/css/css-import/style2.css new file mode 100644 index 00000000000..195b6bcf6d2 --- /dev/null +++ b/test/configCases/css/css-import/style2.css @@ -0,0 +1,3 @@ +a { + color: red; +} diff --git a/test/configCases/css/css-import/style3.css b/test/configCases/css/css-import/style3.css new file mode 100644 index 00000000000..3da7fa6f9a7 --- /dev/null +++ b/test/configCases/css/css-import/style3.css @@ -0,0 +1,4 @@ +.class { + content: "style.css"; + color: red; +} diff --git a/test/configCases/css/css-import/style4.css b/test/configCases/css/css-import/style4.css new file mode 100644 index 00000000000..ffafcc6bc82 --- /dev/null +++ b/test/configCases/css/css-import/style4.css @@ -0,0 +1,3 @@ +.class { + content: "style4.css"; +} diff --git a/test/configCases/css/css-import/style5.css b/test/configCases/css/css-import/style5.css new file mode 100644 index 00000000000..762f796a624 --- /dev/null +++ b/test/configCases/css/css-import/style5.css @@ -0,0 +1,3 @@ +.class { + content: "style5.css"; +} diff --git a/test/configCases/css/css-import/style6.css b/test/configCases/css/css-import/style6.css new file mode 100644 index 00000000000..07cf8d4947d --- /dev/null +++ b/test/configCases/css/css-import/style6.css @@ -0,0 +1,3 @@ +.class { + content: "style6.css"; +} diff --git a/test/configCases/css/css-import/style8.css b/test/configCases/css/css-import/style8.css new file mode 100644 index 00000000000..cdf5c7ed93a --- /dev/null +++ b/test/configCases/css/css-import/style8.css @@ -0,0 +1,3 @@ +.class { + content: "style8.css"; +} diff --git a/test/configCases/css/css-import/style9.css b/test/configCases/css/css-import/style9.css new file mode 100644 index 00000000000..cdaaa1da655 --- /dev/null +++ b/test/configCases/css/css-import/style9.css @@ -0,0 +1,3 @@ +.class { + content: "style9.css"; +} diff --git a/test/configCases/css/css-import/supports-deep-deep-nested.css b/test/configCases/css/css-import/supports-deep-deep-nested.css new file mode 100644 index 00000000000..2b3fb00069f --- /dev/null +++ b/test/configCases/css/css-import/supports-deep-deep-nested.css @@ -0,0 +1,3 @@ +.class { + deep-deep-nested: 1; +} diff --git a/test/configCases/css/css-import/supports-deep-nested.css b/test/configCases/css/css-import/supports-deep-nested.css new file mode 100644 index 00000000000..7a2e5ae40c8 --- /dev/null +++ b/test/configCases/css/css-import/supports-deep-nested.css @@ -0,0 +1,5 @@ +@import "./supports-deep-deep-nested.css" supports(display: table); + +.class { + deep-nested: 1; +} diff --git a/test/configCases/css/css-import/supports-nested.css b/test/configCases/css/css-import/supports-nested.css new file mode 100644 index 00000000000..29703ad014b --- /dev/null +++ b/test/configCases/css/css-import/supports-nested.css @@ -0,0 +1,5 @@ +@import "./supports-deep-nested.css" supports(display: grid); + +.class { + nested: 1; +} diff --git a/test/configCases/css/css-import/test test.css b/test/configCases/css/css-import/test test.css new file mode 100644 index 00000000000..1e68c3da01e --- /dev/null +++ b/test/configCases/css/css-import/test test.css @@ -0,0 +1,3 @@ +.class { + content: "test test.css"; +} diff --git a/test/configCases/css/css-import/test.config.js b/test/configCases/css/css-import/test.config.js new file mode 100644 index 00000000000..0590757288f --- /dev/null +++ b/test/configCases/css/css-import/test.config.js @@ -0,0 +1,8 @@ +module.exports = { + moduleScope(scope) { + const link = scope.window.document.createElement("link"); + link.rel = "stylesheet"; + link.href = "bundle0.css"; + scope.window.document.head.appendChild(link); + } +}; diff --git a/test/configCases/css/css-import/test.css b/test/configCases/css/css-import/test.css new file mode 100644 index 00000000000..2c03574bff6 --- /dev/null +++ b/test/configCases/css/css-import/test.css @@ -0,0 +1,3 @@ +.class { + content: "test.css"; +} diff --git a/test/configCases/css/css-import/warnings.js b/test/configCases/css/css-import/warnings.js new file mode 100644 index 00000000000..8a386d43435 --- /dev/null +++ b/test/configCases/css/css-import/warnings.js @@ -0,0 +1,20 @@ +module.exports = [ + /Expected URL in '@import nourl\(test.css\);'/, + /Expected URL in '@import ;'/, + /Expected URL in '@import foo-bar;'/, + /An URL in '@import layer\(super\.foo\) "\.\/style2\.css\?warning=1" supports\(display: flex\) screen and \(min-width: 400px\);' should be before 'layer\(\.\.\.\)' or 'supports\(\.\.\.\)'/, + /An URL in '@import layer\(super\.foo\) supports\(display: flex\) "\.\/style2.css\?warning=2" screen and \(min-width: 400px\);' should be before 'layer\(\.\.\.\)' or 'supports\(\.\.\.\)'/, + /An URL in '@import layer\(super\.foo\) supports\(display: flex\) screen and \(min-width: 400px\) "\.\/style2.css\?warning=3";' should be before 'layer\(\.\.\.\)' or 'supports\(\.\.\.\)'/, + /An URL in '@import layer\(super\.foo\) url\("\.\/style2.css\?warning=4"\) supports\(display: flex\) screen and \(min-width: 400px\);' should be before 'layer\(\.\.\.\)' or 'supports\(\.\.\.\)'/, + /An URL in '@import layer\(super\.foo\) supports\(display: flex\) url\("\.\/style2.css\?warning=5"\) screen and \(min-width: 400px\);' should be before 'layer\(\.\.\.\)' or 'supports\(\.\.\.\)'/, + /An URL in '@import layer\(super\.foo\) supports\(display: flex\) screen and \(min-width: 400px\) url\("\.\/style2.css\?warning=6"\);' should be before 'layer\(\.\.\.\)' or 'supports\(\.\.\.\)'/, + /The 'layer\(\.\.\.\)' in '@import url\("\/style2.css\?warning=6"\) supports\(display: flex\) layer\(super.foo\) screen and \(min-width: 400px\);' should be before 'supports\(\.\.\.\)'/, + /'@namespace' is not supported in bundled CSS/, + /Expected URL in '@import supports\(background: url\("\.\/img.png"\)\);'/, + /Expected URL in '@import supports\(background: url\("\.\/img.png"\)\) screen and \(min-width: 400px\);'/, + /Expected URL in '@import layer\(test\) supports\(background: url\("\.\/img.png"\)\) screen and \(min-width: 400px\);'/, + /Expected URL in '@import screen and \(min-width: 400px\);'/, + /Duplicate of 'url\(\.\.\.\)' in '@import url\(\.\/style2.css\?multiple=1\) url\(\.\/style2.css\?multiple=2\)'/, + /Duplicate of 'url\(\.\.\.\)' in '@import url\("\.\/style2.css\?multiple=3"\) url\("\.\/style2.css\?multiple=4"'/, + /Duplicate of 'url\(\.\.\.\)' in '@import "\.\/style2.css\?strange=3" url\("\.\/style2.css\?multiple=4"'/ +]; diff --git a/test/configCases/css/css-import/webpack.config.js b/test/configCases/css/css-import/webpack.config.js new file mode 100644 index 00000000000..eabd36c963f --- /dev/null +++ b/test/configCases/css/css-import/webpack.config.js @@ -0,0 +1,46 @@ +/** @type {import("../../../../").Configuration} */ +module.exports = { + target: "web", + mode: "development", + experiments: { + css: true + }, + resolve: { + byDependency: { + "css-import": { + conditionNames: ["custom-name", "..."], + extensions: [".mycss", "..."] + } + } + }, + module: { + rules: [ + { + test: /\.mycss$/, + loader: "./string-loader", + type: "css/global" + }, + { + test: /\.less$/, + loader: "less-loader", + type: "css/global" + } + ] + }, + externals: { + "external-1.css": "css-import external-1.css", + "external-2.css": "css-import external-2.css", + "external-3.css": "css-import external-3.css", + "external-4.css": "css-import external-4.css", + "external-5.css": "css-import external-5.css", + "external-6.css": "css-import external-6.css", + "external-7.css": "css-import external-7.css", + "external-8.css": "css-import external-8.css", + "external-9.css": "css-import external-9.css", + "external-10.css": "css-import external-10.css", + "external-11.css": "css-import external-11.css", + "external-12.css": "css-import external-12.css", + "external-13.css": "css-import external-13.css", + "external-14.css": "css-import external-14.css" + } +}; diff --git a/test/configCases/css/css-import/with-less-import.css b/test/configCases/css/css-import/with-less-import.css new file mode 100644 index 00000000000..75b8a62307d --- /dev/null +++ b/test/configCases/css/css-import/with-less-import.css @@ -0,0 +1,5 @@ +@import "./file.less"; + +.foo { + color: red; +} diff --git a/test/configCases/css/css-modules-broken-keyframes/index.js b/test/configCases/css/css-modules-broken-keyframes/index.js new file mode 100644 index 00000000000..e037b925cc8 --- /dev/null +++ b/test/configCases/css/css-modules-broken-keyframes/index.js @@ -0,0 +1,15 @@ +const prod = process.env.NODE_ENV === "production"; + +it("should allow to create css modules", done => { + prod + ? __non_webpack_require__("./226.bundle0.js") + : __non_webpack_require__("./use-style_js.bundle0.js"); + import("./use-style.js").then(({ default: x }) => { + try { + expect(x).toMatchSnapshot(prod ? "prod" : "dev"); + } catch (e) { + return done(e); + } + done(); + }, done); +}); diff --git a/test/configCases/css/css-modules-broken-keyframes/style.module.css b/test/configCases/css/css-modules-broken-keyframes/style.module.css new file mode 100644 index 00000000000..9b20545cc15 --- /dev/null +++ b/test/configCases/css/css-modules-broken-keyframes/style.module.css @@ -0,0 +1,15 @@ +@keyframes broken; + +.class { + color: red; +} + +@keyframes/*test*/animationName/*test*/{ + 0% { + background: white; + } + 100% { + background: red; + } +} + diff --git a/test/configCases/css/css-modules-broken-keyframes/use-style.js b/test/configCases/css/css-modules-broken-keyframes/use-style.js new file mode 100644 index 00000000000..c2929a40c9c --- /dev/null +++ b/test/configCases/css/css-modules-broken-keyframes/use-style.js @@ -0,0 +1,5 @@ +import * as style from "./style.module.css"; + +export default { + class: style.class, +}; diff --git a/test/configCases/css/css-modules-broken-keyframes/warnings.js b/test/configCases/css/css-modules-broken-keyframes/warnings.js new file mode 100644 index 00000000000..5a2ded6dbc9 --- /dev/null +++ b/test/configCases/css/css-modules-broken-keyframes/warnings.js @@ -0,0 +1,3 @@ +module.exports = [ + /Unexpected ';' at 17 during parsing of @keyframes \(expected '{'\)/ +]; diff --git a/test/configCases/css/css-modules-broken-keyframes/webpack.config.js b/test/configCases/css/css-modules-broken-keyframes/webpack.config.js new file mode 100644 index 00000000000..b952b563cb6 --- /dev/null +++ b/test/configCases/css/css-modules-broken-keyframes/webpack.config.js @@ -0,0 +1,27 @@ +const webpack = require("../../../../"); +const path = require("path"); + +/** @type {function(any, any): import("../../../../").Configuration} */ +module.exports = (env, { testPath }) => ({ + target: "web", + mode: "production", + output: { + uniqueName: "my-app" + }, + experiments: { + css: true + }, + plugins: [ + new webpack.ids.DeterministicModuleIdsPlugin({ + maxLength: 3, + failOnConflict: true, + fixedLength: true, + test: m => m.type.startsWith("css") + }), + new webpack.experiments.ids.SyncModuleIdsPlugin({ + test: m => m.type.startsWith("css"), + path: path.resolve(testPath, "module-ids.json"), + mode: "create" + }) + ] +}); diff --git a/test/configCases/css/css-modules-in-node/index.js b/test/configCases/css/css-modules-in-node/index.js new file mode 100644 index 00000000000..935999b86c9 --- /dev/null +++ b/test/configCases/css/css-modules-in-node/index.js @@ -0,0 +1,22 @@ +const prod = process.env.NODE_ENV === "production"; + +it("should allow to create css modules", done => { + import("../css-modules/use-style.js").then(({ default: x }) => { + try { + expect(x).toMatchSnapshot(prod ? "prod" : "dev"); + } catch (e) { + return done(e); + } + done(); + }, done); +}); + +import * as style from "../css-modules/style.module.css"; + +it("should allow to import css modules", () => { + expect(style.class).toMatchSnapshot(prod ? "class-prod" : "class-dev"); + expect(style.local1).toMatchSnapshot(prod ? "local1-prod" : "local1-dev"); + expect(style.local2).toMatchSnapshot(prod ? "local2-prod" : "local2-dev"); + expect(style.local3).toMatchSnapshot(prod ? "local3-prod" : "local3-dev"); + expect(style.local4).toMatchSnapshot(prod ? "local4-prod" : "local4-dev"); +}); diff --git a/test/configCases/css/css-modules-in-node/warnings.js b/test/configCases/css/css-modules-in-node/warnings.js new file mode 100644 index 00000000000..6dd56176214 --- /dev/null +++ b/test/configCases/css/css-modules-in-node/warnings.js @@ -0,0 +1,3 @@ +module.exports = require("../css-modules/warnings"); +for (const item of module.exports.slice(0, module.exports.length / 2)) + module.exports.push(item); diff --git a/test/configCases/css/css-modules-in-node/webpack.config.js b/test/configCases/css/css-modules-in-node/webpack.config.js new file mode 100644 index 00000000000..6de693f81b0 --- /dev/null +++ b/test/configCases/css/css-modules-in-node/webpack.config.js @@ -0,0 +1,90 @@ +const path = require("path"); +const webpack = require("../../../../"); + +/** @type {function(any, any): import("../../../../").Configuration[]} */ +module.exports = (env, { testPath }) => [ + { + context: path.join(__dirname, "../css-modules"), + entry: "../css-modules-in-node/index.js", + target: "node", + mode: "development", + experiments: { + css: true + }, + module: { + rules: [ + { + test: /\.my-css$/i, + type: "css/auto" + }, + { + test: /\.invalid$/i, + type: "css/auto" + } + ] + } + }, + { + context: path.join(__dirname, "../css-modules"), + entry: "../css-modules-in-node/index.js", + target: "node", + mode: "production", + output: { + uniqueName: "my-app" + }, + experiments: { + css: true + }, + plugins: [ + new webpack.ids.DeterministicModuleIdsPlugin({ + maxLength: 3, + failOnConflict: true, + fixedLength: true, + test: m => m.type.startsWith("css") + }) + ], + module: { + rules: [ + { + test: /\.my-css$/i, + type: "css/auto" + }, + { + test: /\.invalid$/i, + type: "css/auto" + } + ] + } + }, + { + context: path.join(__dirname, "../css-modules"), + entry: "../css-modules-in-node/index.js", + target: "node", + mode: "production", + output: { + uniqueName: "my-app" + }, + experiments: { + css: true + }, + plugins: [ + new webpack.experiments.ids.SyncModuleIdsPlugin({ + test: m => m.type.startsWith("css"), + path: path.resolve(testPath, "../css-modules/module-ids.json"), + mode: "read" + }) + ], + module: { + rules: [ + { + test: /\.my-css$/i, + type: "css/auto" + }, + { + test: /\.invalid$/i, + type: "css/auto" + } + ] + } + } +]; diff --git a/test/configCases/css/css-modules/identifiers.module.css b/test/configCases/css/css-modules/identifiers.module.css new file mode 100644 index 00000000000..100bb05e5e5 --- /dev/null +++ b/test/configCases/css/css-modules/identifiers.module.css @@ -0,0 +1,11 @@ +.UnusedClassName{ + color: red; + padding: var(--variable-unused-class); + --variable-unused-class: 10px; +} + +.UsedClassName { + color: green; + padding: var(--variable-used-class); + --variable-used-class: 10px; +} diff --git a/test/configCases/css/css-modules/index.js b/test/configCases/css/css-modules/index.js new file mode 100644 index 00000000000..5232fad5ea1 --- /dev/null +++ b/test/configCases/css/css-modules/index.js @@ -0,0 +1,26 @@ +const prod = process.env.NODE_ENV === "production"; + +it("should allow to create css modules", done => { + prod + ? __non_webpack_require__("./226.bundle1.js") + : __non_webpack_require__("./use-style_js.bundle0.js"); + import("./use-style.js").then(({ default: x }) => { + try { + expect(x).toMatchSnapshot(prod ? "prod" : "dev"); + + const fs = __non_webpack_require__("fs"); + const path = __non_webpack_require__("path"); + const cssOutputFilename = prod ? "226.bundle1.css" : "use-style_js.bundle0.css"; + + const cssContent = fs.readFileSync( + path.join(__dirname, cssOutputFilename), + "utf-8" + ); + expect(cssContent).not.toContain(".my-app--"); + expect(cssContent).toMatchSnapshot(); + } catch (e) { + return done(e); + } + done(); + }, done); +}); diff --git a/test/configCases/css/css-modules/style.module.css b/test/configCases/css/css-modules/style.module.css new file mode 100644 index 00000000000..eae52a0c821 --- /dev/null +++ b/test/configCases/css/css-modules/style.module.css @@ -0,0 +1,627 @@ +.class { + color: red; +} + +.local1, +.local2 :global .global, +.local3 { + color: green; +} + +:global .global :local .local4 { + color: yellow; +} + +.local5:global(.global).local6 { + color: blue; +} + +.local7 div:not(.disabled, .mButtonDisabled, .tipOnly) { + pointer-events: initial !important; +} + +.local8 :is(div.parent1.child1.vertical-tiny, + div.parent1.child1.vertical-small, + div.otherDiv.horizontal-tiny, + div.otherDiv.horizontal-small div.description) { + max-height: 0; + margin: 0; + overflow: hidden; +} + +.local9 :matches(div.parent1.child1.vertical-tiny, + div.parent1.child1.vertical-small, + div.otherDiv.horizontal-tiny, + div.otherDiv.horizontal-small div.description) { + max-height: 0; + margin: 0; + overflow: hidden; +} + +.local10 :where(div.parent1.child1.vertical-tiny, + div.parent1.child1.vertical-small, + div.otherDiv.horizontal-tiny, + div.otherDiv.horizontal-small div.description) { + max-height: 0; + margin: 0; + overflow: hidden; +} + +.local11 div:has(.disabled, .mButtonDisabled, .tipOnly) { + pointer-events: initial !important; +} + +.local12 div:current(p, span) { + background-color: yellow; +} + +.local13 div:past(p, span) { + display: none; +} + +.local14 div:future(p, span) { + background-color: yellow; +} + +.local15 div:-moz-any(ol, ul, menu, dir) { + list-style-type: square; +} + +.local16 li:-webkit-any(:first-child, :last-child) { + background-color: aquamarine; +} + +.local9 :matches(div.parent1.child1.vertical-tiny, + div.parent1.child1.vertical-small, + div.otherDiv.horizontal-tiny, + div.otherDiv.horizontal-small div.description) { + max-height: 0; + margin: 0; + overflow: hidden; +} + +:global(:global(:local(.nested1)).nested2).nested3 { + color: pink; +} + +#ident { + color: purple; +} + +@keyframes localkeyframes { + 0% { + left: var(--pos1x); + top: var(--pos1y); + color: var(--theme-color1); + } + 100% { + left: var(--pos2x); + top: var(--pos2y); + color: var(--theme-color2); + } +} + +@keyframes localkeyframes2 { + 0% { + left: 0; + } + 100% { + left: 100px; + } +} + +.animation { + animation-name: localkeyframes; + animation: 3s ease-in 1s 2 reverse both paused localkeyframes, localkeyframes2; + --pos1x: 0px; + --pos1y: 0px; + --pos2x: 10px; + --pos2y: 20px; +} + +/* .composed { + composes: local1; + composes: local2; +} */ + +.vars { + color: var(--local-color); + --local-color: red; +} + +.globalVars :global { + color: var(--global-color); + --global-color: red; +} + +@media (min-width: 1600px) { + .wideScreenClass { + color: var(--local-color); + --local-color: green; + } +} + +@media screen and (max-width: 600px) { + .narrowScreenClass { + color: var(--local-color); + --local-color: purple; + } +} + +@supports (display: grid) { + .displayGridInSupports { + display: grid; + } +} + +@supports not (display: grid) { + .floatRightInNegativeSupports { + float: right; + } +} + +@supports (display: flex) { + @media screen and (min-width: 900px) { + .displayFlexInMediaInSupports { + display: flex; + } + } +} + +@media screen and (min-width: 900px) { + @supports (display: flex) { + .displayFlexInSupportsInMedia { + display: flex; + } + } +} + +@MEDIA screen and (min-width: 900px) { + @SUPPORTS (display: flex) { + .displayFlexInSupportsInMediaUpperCase { + display: flex; + } + } +} + +.animationUpperCase { + ANIMATION-NAME: localkeyframesUPPERCASE; + ANIMATION: 3s ease-in 1s 2 reverse both paused localkeyframesUPPERCASE, localkeyframes2UPPPERCASE; + --pos1x: 0px; + --pos1y: 0px; + --pos2x: 10px; + --pos2y: 20px; +} + +@KEYFRAMES localkeyframesUPPERCASE { + 0% { + left: VAR(--pos1x); + top: VAR(--pos1y); + color: VAR(--theme-color1); + } + 100% { + left: VAR(--pos2x); + top: VAR(--pos2y); + color: VAR(--theme-color2); + } +} + +@KEYframes localkeyframes2UPPPERCASE { + 0% { + left: 0; + } + 100% { + left: 100px; + } +} + +:GLOBAL .globalUpperCase :LOCAL .localUpperCase { + color: yellow; +} + +.VARS { + color: VAR(--LOCAL-COLOR); + --LOCAL-COLOR: red; +} + +.globalVarsUpperCase :GLOBAL { + COLOR: VAR(--GLOBAR-COLOR); + --GLOBAR-COLOR: red; +} + +@supports (top: env(safe-area-inset-top, 0)) { + .inSupportScope { + color: red; + } +} + +.a { + animation: 3s animationName; + -webkit-animation: 3s animationName; +} + +.b { + animation: animationName 3s; + -webkit-animation: animationName 3s; +} + +.c { + animation-name: animationName; + -webkit-animation-name: animationName; +} + +.d { + --animation-name: animationName; +} + +@keyframes animationName { + 0% { + background: white; + } + 100% { + background: red; + } +} + +@-webkit-keyframes animationName { + 0% { + background: white; + } + 100% { + background: red; + } +} + +@-moz-keyframes mozAnimationName { + 0% { + background: white; + } + 100% { + background: red; + } +} + +@counter-style thumbs { + system: cyclic; + symbols: "\1F44D"; + suffix: " "; +} + +@font-feature-values Font One { + @styleset { + nice-style: 12; + } +} + +/* At-rule for "nice-style" in Font Two */ +@font-feature-values Font Two { + @styleset { + nice-style: 4; + } +} + +@property --my-color { + syntax: ""; + inherits: false; + initial-value: #c0ffee; +} + +.class { + color: var(--my-color); +} + +@layer utilities { + .padding-sm { + padding: 0.5rem; + } + + .padding-lg { + padding: 0.8rem; + } +} + +.class { + color: red; + + .nested-pure { + color: red; + } + + @media screen and (min-width: 200px) { + color: blue; + + .nested-media { + color: blue; + } + } + + @supports (display: flex) { + display: flex; + + .nested-supports { + display: flex; + } + } + + @layer foo { + background: red; + + .nested-layer { + background: red; + } + } + + @container foo { + background: red; + + .nested-layer { + background: red; + } + } +} + +.not-selector-inside { + color: #fff; + opacity: 0.12; + padding: .5px; + unknown: :local(.test); + unknown1: :local .test; + unknown2: :global .test; + unknown3: :global .test; + unknown4: .foo, .bar, #bar; +} + +@unknown :local .local :global .global { + color: red; +} + +@unknown :local(.local) :global(.global) { + color: red; +} + +.nested-var { + .again { + color: var(--local-color); + } +} + +.nested-with-local-pseudo { + color: red; + + :local .local-nested { + color: red; + } + + :global .global-nested { + color: red; + } + + :local(.local-nested) { + color: red; + } + + :global(.global-nested) { + color: red; + } + + :local .local-nested, :global .global-nested-next { + color: red; + } + + :local(.local-nested), :global(.global-nested-next) { + color: red; + } + + :global .foo, .bar { + color: red; + } +} + +#id-foo { + color: red; + + #id-bar { + color: red; + } +} + +.nested-parens { + .local9 div:has(.vertical-tiny, .vertical-small) { + max-height: 0; + margin: 0; + overflow: hidden; + } +} + +:global .global-foo { + .nested-global { + color: red; + } + + :local .local-in-global { + color: blue; + } +} + +@unknown .class { + color: red; + + .class { + color: red; + } +} + +:global .class :local .in-local-global-scope, +:global .class :local .in-local-global-scope, +:local .class-local-scope :global .in-local-global-scope { + color: red; +} + +@container (width > 400px) { + .class-in-container { + font-size: 1.5em; + } +} + +@container summary (min-width: 400px) { + @container (width > 400px) { + .deep-class-in-container { + font-size: 1.5em; + } + } +} + +:scope { + color: red; +} + +.placeholder-gray-700:-ms-input-placeholder { + --placeholder-opacity: 1; + color: #4a5568; + color: rgba(74, 85, 104, var(--placeholder-opacity)); +} +.placeholder-gray-700::-ms-input-placeholder { + --placeholder-opacity: 1; + color: #4a5568; + color: rgba(74, 85, 104, var(--placeholder-opacity)); +} +.placeholder-gray-700::placeholder { + --placeholder-opacity: 1; + color: #4a5568; + color: rgba(74, 85, 104, var(--placeholder-opacity)); +} + +:root { + --test: dark; +} + +@media screen and (prefers-color-scheme: var(--test)) { + .baz { + color: white; + } +} + +@keyframes slidein { + from { + margin-left: 100%; + width: 300%; + } + + to { + margin-left: 0%; + width: 100%; + } +} + +.class { + animation: + foo var(--animation-name) 3s, + var(--animation-name) 3s, + 3s linear 1s infinite running slidein, + 3s linear env(foo, var(--baz)) infinite running slidein; +} + +:root { + --baz: 10px; +} + +.class { + bar: env(foo, var(--baz)); +} + +:global .global-foo, :local .bar { + :local .local-in-global { + color: blue; + } + + @media screen { + :global .my-global-class-again, + :local .my-global-class-again { + color: red; + } + } +} + +.first-nested { + .first-nested-nested { + color: red; + } +} + +.first-nested-at-rule { + @media screen { + .first-nested-nested-at-rule-deep { + color: red; + } + } +} + +:global .again-global { + color:red; +} + +:global .again-again-global { + :global .again-again-global { + color: red; + } +} + +:root { + --foo: red; +} + +:global .again-again-global { + color: var(--foo); + + :global .again-again-global { + color: var(--foo); + } +} + +:global .again-again-global { + animation: slidein 3s; + + :global .again-again-global, .class, :global(:global(:local(.nested1)).nested2).nested3 { + animation: slidein 3s; + } + + .local2 :global .global, + .local3 { + color: red; + } +} + +@unknown var(--foo) { + color: red; +} + +.class { + .class { + .class { + .class {} + } + } +} + +.class { + .class { + .class { + .class { + animation: slidein 3s; + } + } + } +} + +.class { + animation: slidein 3s; + .class { + animation: slidein 3s; + .class { + animation: slidein 3s; + .class { + animation: slidein 3s; + } + } + } +} diff --git a/test/configCases/css/css-modules/style.module.css.invalid b/test/configCases/css/css-modules/style.module.css.invalid new file mode 100644 index 00000000000..953e362ee15 --- /dev/null +++ b/test/configCases/css/css-modules/style.module.css.invalid @@ -0,0 +1,3 @@ +.class { + color: teal; +} diff --git a/test/configCases/css/css-modules/style.module.my-css b/test/configCases/css/css-modules/style.module.my-css new file mode 100644 index 00000000000..4f4f0b7f873 --- /dev/null +++ b/test/configCases/css/css-modules/style.module.my-css @@ -0,0 +1,3 @@ +.myCssClass { + color: red; +} diff --git a/test/configCases/css/css-modules/test.config.js b/test/configCases/css/css-modules/test.config.js new file mode 100644 index 00000000000..9e2ae626a7b --- /dev/null +++ b/test/configCases/css/css-modules/test.config.js @@ -0,0 +1,7 @@ +module.exports = { + findBundle: function (i, options) { + return i === 0 + ? ["./use-style_js.bundle0.js", "bundle0.js"] + : ["./226.bundle1.js", "bundle1.js"]; + } +}; diff --git a/test/configCases/css/css-modules/use-style.js b/test/configCases/css/css-modules/use-style.js new file mode 100644 index 00000000000..abed76c7931 --- /dev/null +++ b/test/configCases/css/css-modules/use-style.js @@ -0,0 +1,55 @@ +import * as style from "./style.module.css"; +import { local1, local2, local3, local4, ident } from "./style.module.css"; +import { myCssClass } from "./style.module.my-css"; +import * as notACssModule from "./style.module.css.invalid"; +import { UsedClassName } from "./identifiers.module.css"; + +// To prevent analysis export +const isNotACSSModule = typeof notACssModule["c" + "lass"] === "undefined"; +const hasOwnProperty = (obj, p) => Object.hasOwnProperty.call(obj, p) + +export default { + global: style.global, + class: style.class, + local: `${local1} ${local2} ${local3} ${local4}`, + local2: `${style.local5} ${style.local6}`, + nested: `${style.nested1} ${style.nested2} ${style.nested3}`, + notWmultiParams: `${style.local7}`, + isWmultiParams: `${style.local8}`, + matchesWmultiParams: `${style.local9}`, + whereWmultiParams: `${style.local10}`, + hasWmultiParams: `${style.local11}`, + currentWmultiParams: `${style.local12}`, + pastWmultiParams: `${style.local13}`, + futureWmultiParams: `${style.local14}`, + mozAnyWmultiParams: `${style.local15}`, + webkitAnyWmultiParams: `${style.local16}`, + ident, + keyframes: style.localkeyframes, + keyframesUPPERCASE: style.localkeyframesUPPERCASE, + localkeyframes2UPPPERCASE: style.localkeyframes2UPPPERCASE, + animation: style.animation, + vars: `${style["local-color"]} ${style.vars} ${style["global-color"]} ${style.globalVars}`, + media: style.wideScreenClass, + mediaWithOperator: style.narrowScreenClass, + supports: style.displayGridInSupports, + supportsWithOperator: style.floatRightInNegativeSupports, + mediaInSupports: style.displayFlexInMediaInSupports, + supportsInMedia: style.displayFlexInSupportsInMedia, + displayFlexInSupportsInMediaUpperCase: style.displayFlexInSupportsInMediaUpperCase, + VARS: `${style["LOCAL-COLOR"]} ${style.VARS} ${style["GLOBAL-COLOR"]} ${style.globalVarsUpperCase}`, + inSupportScope: style.inSupportScope, + animationName: style.animationName, + mozAnimationName: style.mozAnimationName, + myColor: style['my-color'], + paddingSm: style['padding-sm'], + paddingLg: style['padding-lg'], + inLocalGlobalScope: style['in-local-global-scope'], + classLocalScope: style['class-local-scope'], + classInContainer: style['class-in-container'], + deepClassInContainer: style['deep-class-in-container'], + cssModuleWithCustomFileExtension: myCssClass, + notAValidCssModuleExtension: isNotACSSModule, + UsedClassName, + exportLocalVarsShouldCleanup: `${hasOwnProperty(notACssModule, 'local-color')} ${hasOwnProperty(notACssModule, "LOCAL-COLOR")}` +}; diff --git a/test/configCases/css/css-modules/warnings.js b/test/configCases/css/css-modules/warnings.js new file mode 100644 index 00000000000..8052a28b9e3 --- /dev/null +++ b/test/configCases/css/css-modules/warnings.js @@ -0,0 +1,10 @@ +module.exports = [ + [/export 'global' \(imported as 'style'\) was not found/], + [/export 'nested2' \(imported as 'style'\) was not found/], + [/export 'global-color' \(imported as 'style'\) was not found/], + [/export 'GLOBAL-COLOR' \(imported as 'style'\) was not found/], + [/export 'global' \(imported as 'style'\) was not found/], + [/export 'nested2' \(imported as 'style'\) was not found/], + [/export 'global-color' \(imported as 'style'\) was not found/], + [/export 'GLOBAL-COLOR' \(imported as 'style'\) was not found/] +]; diff --git a/test/configCases/css/css-modules/webpack.config.js b/test/configCases/css/css-modules/webpack.config.js new file mode 100644 index 00000000000..a8404dd9102 --- /dev/null +++ b/test/configCases/css/css-modules/webpack.config.js @@ -0,0 +1,68 @@ +const webpack = require("../../../../"); +const path = require("path"); + +/** @type {function(any, any): import("../../../../").Configuration[]} */ +module.exports = (env, { testPath }) => [ + { + target: "web", + mode: "development", + experiments: { + css: true + }, + module: { + rules: [ + { + test: /\.my-css$/i, + type: "css/auto" + }, + { + test: /\.invalid$/i, + type: "css/auto" + } + ] + }, + node: { + __dirname: false, + __filename: false + } + }, + { + target: "web", + mode: "production", + output: { + uniqueName: "my-app" + }, + experiments: { + css: true + }, + module: { + rules: [ + { + test: /\.my-css$/i, + type: "css/auto" + }, + { + test: /\.invalid$/i, + type: "css/auto" + } + ] + }, + node: { + __dirname: false, + __filename: false + }, + plugins: [ + new webpack.ids.DeterministicModuleIdsPlugin({ + maxLength: 3, + failOnConflict: true, + fixedLength: true, + test: m => m.type.startsWith("css") + }), + new webpack.experiments.ids.SyncModuleIdsPlugin({ + test: m => m.type.startsWith("css"), + path: path.resolve(testPath, "module-ids.json"), + mode: "create" + }) + ] + } +]; diff --git a/test/configCases/css/default-exports-parser-options/index.js b/test/configCases/css/default-exports-parser-options/index.js new file mode 100644 index 00000000000..033c4b52e92 --- /dev/null +++ b/test/configCases/css/default-exports-parser-options/index.js @@ -0,0 +1,19 @@ +import * as style1 from "./style.module.css?namespace"; +import style2 from "./style.module.css?default"; +import { foo } from "./style.module.css?named"; + +it("should able to import with default and named exports", () => { + expect(style1.default).toEqual(nsObj({ foo: '-_style_module_css_namespace-foo' })); + expect(style1.foo).toEqual("-_style_module_css_namespace-foo"); + expect(style2).toEqual(nsObj({ foo: '-_style_module_css_default-foo' })); + expect(foo).toEqual("-_style_module_css_named-foo"); +}); + +it("should able to import with different default and namex dynamic export", (done) => { + import("./style.module.css?namespace").then((style1) => { + expect(style1.default).toEqual(nsObj({ foo: '-_style_module_css_namespace-foo' })); + expect(style1.foo).toEqual('-_style_module_css_namespace-foo'); + + done(); + }, done) +}); diff --git a/test/configCases/css/default-exports-parser-options/style.module.css b/test/configCases/css/default-exports-parser-options/style.module.css new file mode 100644 index 00000000000..cedf0a6d1f1 --- /dev/null +++ b/test/configCases/css/default-exports-parser-options/style.module.css @@ -0,0 +1,3 @@ +.foo { + color: red; +} diff --git a/test/configCases/asset-modules/https-url/webpack.config.js b/test/configCases/css/default-exports-parser-options/webpack.config.js similarity index 50% rename from test/configCases/asset-modules/https-url/webpack.config.js rename to test/configCases/css/default-exports-parser-options/webpack.config.js index 6375d2a4fa2..b7d7852b059 100644 --- a/test/configCases/asset-modules/https-url/webpack.config.js +++ b/test/configCases/css/default-exports-parser-options/webpack.config.js @@ -1,19 +1,20 @@ -const { - experiments: { - schemes: { HttpsUriPlugin } - } -} = require("../../../../"); - /** @type {import("../../../../").Configuration} */ module.exports = { + target: "node", mode: "development", + devtool: false, module: { rules: [ { - test: /\.md$/, - loader: "./loaders/md-loader" + test: /\.css/, + parser: { + namedExports: false + }, + type: "css/module" } ] }, - plugins: [new HttpsUriPlugin()] + experiments: { + css: true + } }; diff --git a/test/configCases/css/exports-convention-prod/index.js b/test/configCases/css/exports-convention-prod/index.js new file mode 100644 index 00000000000..376dee2bb8b --- /dev/null +++ b/test/configCases/css/exports-convention-prod/index.js @@ -0,0 +1,37 @@ +import * as styles1 from "./style.module.css?camel-case#1"; +import * as styles2 from "./style.module.css?camel-case#2"; +import * as styles3 from "./style.module.css?camel-case#3"; + +const nsObjForWebTarget = m => { + if (global.document) { + return nsObj(m); + } + return m +} + +it("should have correct value for css exports", () => { + expect(styles1.classA).toBe("-_style_module_css_camel-case_1-E"); + expect(styles1["class-b"]).toBe("-_style_module_css_camel-case_1-Id"); + expect(__webpack_require__("./style.module.css?camel-case#1")).toEqual(nsObjForWebTarget({ + "E": "-_style_module_css_camel-case_1-E", + "Id": "-_style_module_css_camel-case_1-Id", + })) + + expect(styles2["class-a"]).toBe("-_style_module_css_camel-case_2-zj"); + expect(styles2.classA).toBe("-_style_module_css_camel-case_2-zj"); + expect(__webpack_require__("./style.module.css?camel-case#2")).toEqual(nsObjForWebTarget({ + "zj": "-_style_module_css_camel-case_2-zj", + "E": "-_style_module_css_camel-case_2-zj", + })) + + expect(styles3["class-a"]).toBe("-_style_module_css_camel-case_3-zj"); + expect(styles3.classA).toBe("-_style_module_css_camel-case_3-zj"); + expect(styles3["class-b"]).toBe("-_style_module_css_camel-case_3-Id"); + expect(styles3.classB).toBe("-_style_module_css_camel-case_3-Id"); + expect(__webpack_require__("./style.module.css?camel-case#3")).toEqual(nsObjForWebTarget({ + "zj": "-_style_module_css_camel-case_3-zj", + "E": "-_style_module_css_camel-case_3-zj", + "Id": "-_style_module_css_camel-case_3-Id", + "LO": "-_style_module_css_camel-case_3-Id", + })) +}); diff --git a/test/configCases/css/exports-convention-prod/style.module.css b/test/configCases/css/exports-convention-prod/style.module.css new file mode 100644 index 00000000000..e26591a3906 --- /dev/null +++ b/test/configCases/css/exports-convention-prod/style.module.css @@ -0,0 +1,7 @@ +.class-a { + color: red; +} + +.class-b { + color: blue; +} diff --git a/test/configCases/css/exports-convention-prod/test.config.js b/test/configCases/css/exports-convention-prod/test.config.js new file mode 100644 index 00000000000..8eea890a4d0 --- /dev/null +++ b/test/configCases/css/exports-convention-prod/test.config.js @@ -0,0 +1,10 @@ +module.exports = { + moduleScope(scope) { + if (scope.window) { + const link = scope.window.document.createElement("link"); + link.rel = "stylesheet"; + link.href = "bundle0.css"; + scope.window.document.head.appendChild(link); + } + } +}; diff --git a/test/configCases/css/exports-convention-prod/webpack.config.js b/test/configCases/css/exports-convention-prod/webpack.config.js new file mode 100644 index 00000000000..175e5eeea1a --- /dev/null +++ b/test/configCases/css/exports-convention-prod/webpack.config.js @@ -0,0 +1,37 @@ +const common = { + mode: "production", + optimization: { + moduleIds: "named" + }, + module: { + rules: [ + { + test: /\.module\.css$/, + type: "css/module", + oneOf: [ + { + resourceQuery: /\?camel-case$/, + generator: { + exportsConvention: "camel-case" + } + } + ] + } + ] + }, + experiments: { + css: true + } +}; + +/** @type {import("../../../../").Configuration} */ +module.exports = [ + { + ...common, + target: "web" + }, + { + ...common, + target: "node" + } +]; diff --git a/test/configCases/css/exports-convention/index.js b/test/configCases/css/exports-convention/index.js new file mode 100644 index 00000000000..e39aa530c2d --- /dev/null +++ b/test/configCases/css/exports-convention/index.js @@ -0,0 +1,18 @@ +it("should have correct convention for css exports name", (done) => { + Promise.all([ + import("./style.module.css?as-is"), + import("./style.module.css?camel-case"), + import("./style.module.css?camel-case-only"), + import("./style.module.css?dashes"), + import("./style.module.css?dashes-only"), + import("./style.module.css?upper"), + ]).then(([asIs, camelCase, camelCaseOnly, dashes, dashesOnly, upper]) => { + expect(asIs).toMatchSnapshot(); + expect(camelCase).toMatchSnapshot(); + expect(camelCaseOnly).toMatchSnapshot(); + expect(dashes).toMatchSnapshot(); + expect(dashesOnly).toMatchSnapshot(); + expect(upper).toMatchSnapshot(); + done() + }).catch(done) +}); diff --git a/test/configCases/css/exports-convention/style.module.css b/test/configCases/css/exports-convention/style.module.css new file mode 100644 index 00000000000..894f64b1890 --- /dev/null +++ b/test/configCases/css/exports-convention/style.module.css @@ -0,0 +1,24 @@ +.btn-info_is-disabled { + color: blue; +} + +.btn--info_is-disabled_1 { + color: blue; +} + +.simple { + color: red; +} + +a { + color: yellow; +} + +:export { + foo: bar; + my-btn-info_is-disabled: value; +} + +.foo_bar { + color: red; +} diff --git a/test/configCases/css/exports-convention/webpack.config.js b/test/configCases/css/exports-convention/webpack.config.js new file mode 100644 index 00000000000..2fc08e9abf5 --- /dev/null +++ b/test/configCases/css/exports-convention/webpack.config.js @@ -0,0 +1,64 @@ +const common = { + mode: "development", + module: { + rules: [ + { + test: /\.module\.css$/, + type: "css/module", + oneOf: [ + { + resourceQuery: /\?as-is$/, + generator: { + exportsConvention: "as-is" + } + }, + { + resourceQuery: /\?camel-case$/, + generator: { + exportsConvention: "camel-case" + } + }, + { + resourceQuery: /\?camel-case-only$/, + generator: { + exportsConvention: "camel-case-only" + } + }, + { + resourceQuery: /\?dashes$/, + generator: { + exportsConvention: "dashes" + } + }, + { + resourceQuery: /\?dashes-only$/, + generator: { + exportsConvention: "dashes-only" + } + }, + { + resourceQuery: /\?upper$/, + generator: { + exportsConvention: name => name.toUpperCase() + } + } + ] + } + ] + }, + experiments: { + css: true + } +}; + +/** @type {import("../../../../").Configuration} */ +module.exports = [ + { + ...common, + target: "web" + }, + { + ...common, + target: "node" + } +]; diff --git a/test/configCases/css/exports-in-node/index.js b/test/configCases/css/exports-in-node/index.js new file mode 100644 index 00000000000..0c59f3e16d2 --- /dev/null +++ b/test/configCases/css/exports-in-node/index.js @@ -0,0 +1,74 @@ +import * as style from "../exports/style.module.css?ns"; +import { a, abc } from "../exports/style.module.css?picked"; +import def from "../exports/style.module.css?default"; + +it("should allow to import a css module", () => { + expect(style).toEqual( + nsObj({ + a: "a", + abc: "a b c", + comments: "abc def", + "white space": "abc\n\tdef", + default: "default" + }) + ); + expect(a).toBe("a"); + expect(abc).toBe("a b c"); + expect(def).toBe("default"); +}); + +it("should allow to dynamic import a css module", done => { + import("../exports/style.module.css").then(x => { + try { + expect(x).toEqual( + nsObj({ + a: "a", + abc: "a b c", + comments: "abc def", + "white space": "abc\n\tdef", + default: "default" + }) + ); + } catch (e) { + return done(e); + } + done(); + }, done); +}); + +it("should allow to reexport a css module", done => { + import("../exports/reexported").then(x => { + try { + expect(x).toEqual( + nsObj({ + a: "a", + abc: "a b c", + comments: "abc def", + "white space": "abc\n\tdef" + }) + ); + } catch (e) { + return done(e); + } + done(); + }, done); +}); + +it("should allow to import a css module", done => { + import("../exports/imported").then(({ default: x }) => { + try { + expect(x).toEqual( + nsObj({ + a: "a", + abc: "a b c", + comments: "abc def", + "white space": "abc\n\tdef", + default: "default" + }) + ); + } catch (e) { + return done(e); + } + done(); + }, done); +}); diff --git a/test/configCases/css/exports-in-node/webpack.config.js b/test/configCases/css/exports-in-node/webpack.config.js new file mode 100644 index 00000000000..a91e72d278a --- /dev/null +++ b/test/configCases/css/exports-in-node/webpack.config.js @@ -0,0 +1,8 @@ +/** @type {import("../../../../").Configuration} */ +module.exports = { + target: "node", + mode: "development", + experiments: { + css: true + } +}; diff --git a/test/configCases/css/exports-only-generator-options/index.js b/test/configCases/css/exports-only-generator-options/index.js new file mode 100644 index 00000000000..1d827846c58 --- /dev/null +++ b/test/configCases/css/exports-only-generator-options/index.js @@ -0,0 +1,26 @@ +it("should not have .css file", (done) => { + __non_webpack_require__("./exports_style_module_css.bundle0.js"); + __non_webpack_require__("./exports_style_module_css_exportsOnly.bundle0.js"); + Promise.all([ + import("../exports/style.module.css"), + import("../exports/style.module.css?module"), + import("../exports/style.module.css?exportsOnly"), + ]).then(([style1, style2, style3]) => { + const ns = nsObj({ + a: "a", + abc: "a b c", + comments: "abc def", + "white space": "abc\n\tdef", + default: "default" + }); + expect(style1).toEqual(ns); + expect(style2).toEqual(ns); + expect(style3).toEqual(ns); + }).then(() => { + const fs = __non_webpack_require__("fs"); + const path = __non_webpack_require__("path"); + expect(fs.existsSync(path.resolve(__dirname, "exports_style_module_css.bundle0.css"))).toBe(false); + expect(fs.existsSync(path.resolve(__dirname, "exports_style_module_css_exportsOnly.bundle0.css"))).toBe(false); + done() + }).catch(e => done(e)) +}); diff --git a/test/configCases/css/exports-only-generator-options/webpack.config.js b/test/configCases/css/exports-only-generator-options/webpack.config.js new file mode 100644 index 00000000000..c2f9beae76e --- /dev/null +++ b/test/configCases/css/exports-only-generator-options/webpack.config.js @@ -0,0 +1,36 @@ +/** @type {import("../../../../").Configuration} */ +module.exports = [ + { + target: "web", + mode: "development", + module: { + generator: { + css: { + exportsOnly: true + }, + "css/module": { + exportsOnly: false + } + }, + rules: [ + { + resourceQuery: /\?module/, + type: "css/module" + }, + { + resourceQuery: /\?exportsOnly/, + generator: { + exportsOnly: true + }, + type: "css/global" + } + ] + }, + experiments: { + css: true + }, + node: { + __dirname: false + } + } +]; diff --git a/test/configCases/css/exports/imported.js b/test/configCases/css/exports/imported.js new file mode 100644 index 00000000000..c00487d795d --- /dev/null +++ b/test/configCases/css/exports/imported.js @@ -0,0 +1,3 @@ +import * as style from "./style.module.css?imported"; + +export default Object(style); diff --git a/test/configCases/css/exports/index.js b/test/configCases/css/exports/index.js new file mode 100644 index 00000000000..b65dc05aee5 --- /dev/null +++ b/test/configCases/css/exports/index.js @@ -0,0 +1,57 @@ +it("should allow to dynamic import a css module", done => { + import("./style.module.css").then(x => { + try { + expect(x).toEqual( + nsObj({ + a: "a", + abc: "a b c", + comments: "abc def", + "white space": "abc\n\tdef", + default: "default" + }) + ); + } catch (e) { + return done(e); + } + done(); + }, done); +}); + +it("should allow to reexport a css module", done => { + __non_webpack_require__("./reexported_js.bundle0.js"); + import("./reexported").then(x => { + try { + expect(x).toEqual( + nsObj({ + a: "a", + abc: "a b c", + comments: "abc def", + "white space": "abc\n\tdef" + }) + ); + } catch (e) { + return done(e); + } + done(); + }, done); +}); + +it("should allow to import a css module", done => { + __non_webpack_require__("./imported_js.bundle0.js"); + import("./imported").then(({ default: x }) => { + try { + expect(x).toEqual( + nsObj({ + a: "a", + abc: "a b c", + comments: "abc def", + "white space": "abc\n\tdef", + default: "default" + }) + ); + } catch (e) { + return done(e); + } + done(); + }, done); +}); diff --git a/test/configCases/css/exports/reexported.js b/test/configCases/css/exports/reexported.js new file mode 100644 index 00000000000..d50dc4c5003 --- /dev/null +++ b/test/configCases/css/exports/reexported.js @@ -0,0 +1 @@ +export * from "./style.module.css?reexported"; diff --git a/test/configCases/css/exports/style.module.css b/test/configCases/css/exports/style.module.css new file mode 100644 index 00000000000..c64b4ff9a64 --- /dev/null +++ b/test/configCases/css/exports/style.module.css @@ -0,0 +1,25 @@ +:export { + a: a; +} + +:export { + abc: a b c; + comments: abc/****/ /* hello world *//****/ def +} + +:export + + +{ + + + white space + + : + + abc + def + +} + +:export{default:default} diff --git a/test/configCases/css/exports/webpack.config.js b/test/configCases/css/exports/webpack.config.js new file mode 100644 index 00000000000..cfb8e5c0346 --- /dev/null +++ b/test/configCases/css/exports/webpack.config.js @@ -0,0 +1,8 @@ +/** @type {import("../../../../").Configuration} */ +module.exports = { + target: "web", + mode: "development", + experiments: { + css: true + } +}; diff --git a/test/configCases/css/external-in-node/index.js b/test/configCases/css/external-in-node/index.js new file mode 100644 index 00000000000..526b3c0a8b2 --- /dev/null +++ b/test/configCases/css/external-in-node/index.js @@ -0,0 +1,6 @@ +it("should import an external css", done => { + import("../external/style.css").then(x => { + expect(x).toEqual(nsObj({})); + done(); + }, done); +}); diff --git a/test/configCases/css/external-in-node/webpack.config.js b/test/configCases/css/external-in-node/webpack.config.js new file mode 100644 index 00000000000..87766dc8dae --- /dev/null +++ b/test/configCases/css/external-in-node/webpack.config.js @@ -0,0 +1,11 @@ +const path = require("path"); + +/** @type {import("../../../../").Configuration} */ +module.exports = { + context: path.join(__dirname, "../external"), + entry: "../external-in-node/index.js", + target: "node", + experiments: { + css: true + } +}; diff --git a/test/configCases/css/external/external.css b/test/configCases/css/external/external.css new file mode 100644 index 00000000000..f815695493b --- /dev/null +++ b/test/configCases/css/external/external.css @@ -0,0 +1,3 @@ +body { + color: green; +} diff --git a/test/configCases/css/external/index.js b/test/configCases/css/external/index.js new file mode 100644 index 00000000000..fb100cf0d99 --- /dev/null +++ b/test/configCases/css/external/index.js @@ -0,0 +1,14 @@ +it("should import an external css", done => { + import("./style.css").then(x => { + expect(x).toEqual(nsObj({})); + const style = getComputedStyle(document.body); + expect(style.getPropertyValue("color")).toBe(" green"); + expect(style.getPropertyValue("background")).toBe( + " url(//example.com/image.png) url(https://example.com/image.png)" + ); + expect(style.getPropertyValue("background-image")).toBe( + " url(http://example.com/image.png)" + ); + done(); + }, done); +}); diff --git a/test/configCases/css/external/style.css b/test/configCases/css/external/style.css new file mode 100644 index 00000000000..a186274dce1 --- /dev/null +++ b/test/configCases/css/external/style.css @@ -0,0 +1,2 @@ +@import "style2.css"; +@import "https://test.cases/path/../../../../configCases/css/external/external.css"; diff --git a/test/configCases/css/external/style2.css b/test/configCases/css/external/style2.css new file mode 100644 index 00000000000..326ac4a1831 --- /dev/null +++ b/test/configCases/css/external/style2.css @@ -0,0 +1,4 @@ +body { + background: url(//example.com/image.png) url(https://example.com/image.png); + background-image: url(http://example.com/image.png); +} diff --git a/test/configCases/css/external/webpack.config.js b/test/configCases/css/external/webpack.config.js new file mode 100644 index 00000000000..72bc3e86f47 --- /dev/null +++ b/test/configCases/css/external/webpack.config.js @@ -0,0 +1,7 @@ +/** @type {import("../../../../").Configuration} */ +module.exports = { + target: "web", + experiments: { + css: true + } +}; diff --git a/test/configCases/css/import-different-case/index.js b/test/configCases/css/import-different-case/index.js new file mode 100644 index 00000000000..652fef343dd --- /dev/null +++ b/test/configCases/css/import-different-case/index.js @@ -0,0 +1,8 @@ +import * as style from "./style.css"; + +it("should compile and load style on demand", () => { + expect(style).toEqual(nsObj({})); + const computedStyle = getComputedStyle(document.body); + expect(computedStyle.getPropertyValue("background")).toBe(" red"); + expect(computedStyle.getPropertyValue("margin")).toBe(" 10px"); +}); diff --git a/test/configCases/css/import-different-case/style-imported.css b/test/configCases/css/import-different-case/style-imported.css new file mode 100644 index 00000000000..eb0ae451455 --- /dev/null +++ b/test/configCases/css/import-different-case/style-imported.css @@ -0,0 +1,3 @@ +body { + margin: 10px; +} diff --git a/test/configCases/css/import-different-case/style.css b/test/configCases/css/import-different-case/style.css new file mode 100644 index 00000000000..602ea2d5aa8 --- /dev/null +++ b/test/configCases/css/import-different-case/style.css @@ -0,0 +1,4 @@ +@IMPORT "style-imported.css"; +body { + background: red; +} diff --git a/test/configCases/css/import-different-case/test.config.js b/test/configCases/css/import-different-case/test.config.js new file mode 100644 index 00000000000..0590757288f --- /dev/null +++ b/test/configCases/css/import-different-case/test.config.js @@ -0,0 +1,8 @@ +module.exports = { + moduleScope(scope) { + const link = scope.window.document.createElement("link"); + link.rel = "stylesheet"; + link.href = "bundle0.css"; + scope.window.document.head.appendChild(link); + } +}; diff --git a/test/configCases/css/import-different-case/webpack.config.js b/test/configCases/css/import-different-case/webpack.config.js new file mode 100644 index 00000000000..cfb8e5c0346 --- /dev/null +++ b/test/configCases/css/import-different-case/webpack.config.js @@ -0,0 +1,8 @@ +/** @type {import("../../../../").Configuration} */ +module.exports = { + target: "web", + mode: "development", + experiments: { + css: true + } +}; diff --git a/test/configCases/css/import-module/a-pitching-loader.js b/test/configCases/css/import-module/a-pitching-loader.js new file mode 100644 index 00000000000..eb9ad595ce8 --- /dev/null +++ b/test/configCases/css/import-module/a-pitching-loader.js @@ -0,0 +1,9 @@ +/** @type {import("../../../../").PitchLoaderDefinitionFunction} */ +exports.pitch = async function (remaining) { + const result = await this.importModule( + this.resourcePath + '.webpack[javascript/auto]' + '!=!' + remaining, { + publicPath: '' + }); + + return result.default || result; +}; diff --git a/test/configCases/css/import-module/colors.js b/test/configCases/css/import-module/colors.js new file mode 100644 index 00000000000..91f7b0d0db4 --- /dev/null +++ b/test/configCases/css/import-module/colors.js @@ -0,0 +1,2 @@ +export const red = '#f00'; +export const green = '#0f0'; \ No newline at end of file diff --git a/test/configCases/css/import-module/index.js b/test/configCases/css/import-module/index.js new file mode 100644 index 00000000000..ba908562a78 --- /dev/null +++ b/test/configCases/css/import-module/index.js @@ -0,0 +1,6 @@ +import stylesheet from './stylesheet.js'; + +it("should compile", () => { + expect(stylesheet).toBe("body { background: #f00; color: #0f0; }"); +}); + diff --git a/test/configCases/css/import-module/stylesheet.js b/test/configCases/css/import-module/stylesheet.js new file mode 100644 index 00000000000..a2400fa41d9 --- /dev/null +++ b/test/configCases/css/import-module/stylesheet.js @@ -0,0 +1,3 @@ +import { green, red } from './colors.js'; + +export default `body { background: ${red}; color: ${green}; }`; diff --git a/test/configCases/css/import-module/webpack.config.js b/test/configCases/css/import-module/webpack.config.js new file mode 100644 index 00000000000..06bb9ba027a --- /dev/null +++ b/test/configCases/css/import-module/webpack.config.js @@ -0,0 +1,19 @@ +const webpack = require("../../../../"); +/** @type {import("../../../../").Configuration} */ +module.exports = { + plugins: [new webpack.HotModuleReplacementPlugin()], + target: "web", + mode: "development", + module: { + rules: [ + { + test: /stylesheet\.js$/i, + use: ["./a-pitching-loader.js"], + type: "asset/source" + } + ] + }, + experiments: { + css: true + } +}; diff --git a/test/configCases/css/large-css-head-data-compression/index.js b/test/configCases/css/large-css-head-data-compression/index.js new file mode 100644 index 00000000000..cd938863abe --- /dev/null +++ b/test/configCases/css/large-css-head-data-compression/index.js @@ -0,0 +1,19 @@ +const prod = process.env.NODE_ENV === "production"; + +it("should allow to create css modules", done => { + prod + ? __non_webpack_require__("./530.bundle1.js") + : __non_webpack_require__("./large_use-style_js.bundle0.js"); + import("../large/use-style.js").then(({ default: x }) => { + try { + expect(x).toMatchSnapshot(prod ? "prod" : "dev"); + } catch (e) { + return done(e); + } + done(); + }, done); +}); + +it("should allow to process tailwind as global css", done => { + import("../large/tailwind.min.css").then(() => done(), done); +}); diff --git a/test/configCases/css/large-css-head-data-compression/webpack.config.js b/test/configCases/css/large-css-head-data-compression/webpack.config.js new file mode 100644 index 00000000000..56bddb1dd3a --- /dev/null +++ b/test/configCases/css/large-css-head-data-compression/webpack.config.js @@ -0,0 +1,25 @@ +/** @type {import("../../../../").Configuration[]} */ +module.exports = [ + { + target: "web", + mode: "development", + output: { + uniqueName: "my-app", + cssHeadDataCompression: true + }, + experiments: { + css: true + } + }, + { + target: "web", + mode: "production", + output: { + cssHeadDataCompression: false + }, + performance: false, + experiments: { + css: true + } + } +]; diff --git a/test/configCases/css/large/index.js b/test/configCases/css/large/index.js new file mode 100644 index 00000000000..6b7ca056cff --- /dev/null +++ b/test/configCases/css/large/index.js @@ -0,0 +1,19 @@ +const prod = process.env.NODE_ENV === "production"; + +it("should allow to create css modules", done => { + prod + ? __non_webpack_require__("./226.bundle1.js") + : __non_webpack_require__("./use-style_js.bundle0.js"); + import("./use-style.js").then(({ default: x }) => { + try { + expect(x).toMatchSnapshot(prod ? "prod" : "dev"); + } catch (e) { + return done(e); + } + done(); + }, done); +}); + +it("should allow to process tailwind as global css", done => { + import("./tailwind.min.css").then(() => done(), done); +}); diff --git a/test/configCases/css/large/tailwind.min.css b/test/configCases/css/large/tailwind.min.css new file mode 100644 index 00000000000..dc016181652 --- /dev/null +++ b/test/configCases/css/large/tailwind.min.css @@ -0,0 +1 @@ +/*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */html{line-height:1.15;-webkit-text-size-adjust:100%}body{margin:0}main{display:block}h1{font-size:2em;margin:.67em 0}hr{box-sizing:content-box;height:0;overflow:visible}pre{font-family:monospace,monospace;font-size:1em}a{background-color:transparent}abbr[title]{border-bottom:none;text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted}b,strong{font-weight:bolder}code,kbd,samp{font-family:monospace,monospace;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}img{border-style:none}button,input,optgroup,select,textarea{font-family:inherit;font-size:100%;line-height:1.15;margin:0}button,input{overflow:visible}button,select{text-transform:none}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{border-style:none;padding:0}[type=button]:-moz-focusring,[type=reset]:-moz-focusring,[type=submit]:-moz-focusring,button:-moz-focusring{outline:1px dotted ButtonText}fieldset{padding:.35em .75em .625em}legend{box-sizing:border-box;color:inherit;display:table;max-width:100%;padding:0;white-space:normal}progress{vertical-align:baseline}textarea{overflow:auto}[type=checkbox],[type=radio]{box-sizing:border-box;padding:0}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}details{display:block}summary{display:list-item}template{display:none}[hidden]{display:none}blockquote,dd,dl,figure,h1,h2,h3,h4,h5,h6,hr,p,pre{margin:0}button{background-color:transparent;background-image:none}button:focus{outline:1px dotted;outline:5px auto -webkit-focus-ring-color}fieldset{margin:0;padding:0}ol,ul{list-style:none;margin:0;padding:0}html{font-family:system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";line-height:1.5}*,::after,::before{box-sizing:border-box;border-width:0;border-style:solid;border-color:#e2e8f0}hr{border-top-width:1px}img{border-style:solid}textarea{resize:vertical}input:-ms-input-placeholder,textarea:-ms-input-placeholder{color:#a0aec0}input::-ms-input-placeholder,textarea::-ms-input-placeholder{color:#a0aec0}input::placeholder,textarea::placeholder{color:#a0aec0}[role=button],button{cursor:pointer}table{border-collapse:collapse}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}button,input,optgroup,select,textarea{padding:0;line-height:inherit;color:inherit}code,kbd,pre,samp{font-family:Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace}audio,canvas,embed,iframe,img,object,svg,video{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}.container{width:100%}@media (min-width:640px){.container{max-width:640px}}@media (min-width:768px){.container{max-width:768px}}@media (min-width:1024px){.container{max-width:1024px}}@media (min-width:1280px){.container{max-width:1280px}}.space-y-0>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(0px * calc(1 - var(--space-y-reverse)));margin-bottom:calc(0px * var(--space-y-reverse))}.space-x-0>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(0px * var(--space-x-reverse));margin-left:calc(0px * calc(1 - var(--space-x-reverse)))}.space-y-1>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(.25rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(.25rem * var(--space-y-reverse))}.space-x-1>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(.25rem * var(--space-x-reverse));margin-left:calc(.25rem * calc(1 - var(--space-x-reverse)))}.space-y-2>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(.5rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(.5rem * var(--space-y-reverse))}.space-x-2>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(.5rem * var(--space-x-reverse));margin-left:calc(.5rem * calc(1 - var(--space-x-reverse)))}.space-y-3>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(.75rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(.75rem * var(--space-y-reverse))}.space-x-3>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(.75rem * var(--space-x-reverse));margin-left:calc(.75rem * calc(1 - var(--space-x-reverse)))}.space-y-4>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(1rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(1rem * var(--space-y-reverse))}.space-x-4>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(1rem * var(--space-x-reverse));margin-left:calc(1rem * calc(1 - var(--space-x-reverse)))}.space-y-5>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(1.25rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(1.25rem * var(--space-y-reverse))}.space-x-5>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(1.25rem * var(--space-x-reverse));margin-left:calc(1.25rem * calc(1 - var(--space-x-reverse)))}.space-y-6>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(1.5rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(1.5rem * var(--space-y-reverse))}.space-x-6>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(1.5rem * var(--space-x-reverse));margin-left:calc(1.5rem * calc(1 - var(--space-x-reverse)))}.space-y-8>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(2rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(2rem * var(--space-y-reverse))}.space-x-8>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(2rem * var(--space-x-reverse));margin-left:calc(2rem * calc(1 - var(--space-x-reverse)))}.space-y-10>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(2.5rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(2.5rem * var(--space-y-reverse))}.space-x-10>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(2.5rem * var(--space-x-reverse));margin-left:calc(2.5rem * calc(1 - var(--space-x-reverse)))}.space-y-12>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(3rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(3rem * var(--space-y-reverse))}.space-x-12>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(3rem * var(--space-x-reverse));margin-left:calc(3rem * calc(1 - var(--space-x-reverse)))}.space-y-16>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(4rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(4rem * var(--space-y-reverse))}.space-x-16>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(4rem * var(--space-x-reverse));margin-left:calc(4rem * calc(1 - var(--space-x-reverse)))}.space-y-20>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(5rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(5rem * var(--space-y-reverse))}.space-x-20>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(5rem * var(--space-x-reverse));margin-left:calc(5rem * calc(1 - var(--space-x-reverse)))}.space-y-24>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(6rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(6rem * var(--space-y-reverse))}.space-x-24>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(6rem * var(--space-x-reverse));margin-left:calc(6rem * calc(1 - var(--space-x-reverse)))}.space-y-32>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(8rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(8rem * var(--space-y-reverse))}.space-x-32>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(8rem * var(--space-x-reverse));margin-left:calc(8rem * calc(1 - var(--space-x-reverse)))}.space-y-40>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(10rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(10rem * var(--space-y-reverse))}.space-x-40>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(10rem * var(--space-x-reverse));margin-left:calc(10rem * calc(1 - var(--space-x-reverse)))}.space-y-48>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(12rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(12rem * var(--space-y-reverse))}.space-x-48>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(12rem * var(--space-x-reverse));margin-left:calc(12rem * calc(1 - var(--space-x-reverse)))}.space-y-56>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(14rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(14rem * var(--space-y-reverse))}.space-x-56>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(14rem * var(--space-x-reverse));margin-left:calc(14rem * calc(1 - var(--space-x-reverse)))}.space-y-64>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(16rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(16rem * var(--space-y-reverse))}.space-x-64>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(16rem * var(--space-x-reverse));margin-left:calc(16rem * calc(1 - var(--space-x-reverse)))}.space-y-px>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(1px * calc(1 - var(--space-y-reverse)));margin-bottom:calc(1px * var(--space-y-reverse))}.space-x-px>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(1px * var(--space-x-reverse));margin-left:calc(1px * calc(1 - var(--space-x-reverse)))}.-space-y-1>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-.25rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-.25rem * var(--space-y-reverse))}.-space-x-1>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-.25rem * var(--space-x-reverse));margin-left:calc(-.25rem * calc(1 - var(--space-x-reverse)))}.-space-y-2>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-.5rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-.5rem * var(--space-y-reverse))}.-space-x-2>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-.5rem * var(--space-x-reverse));margin-left:calc(-.5rem * calc(1 - var(--space-x-reverse)))}.-space-y-3>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-.75rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-.75rem * var(--space-y-reverse))}.-space-x-3>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-.75rem * var(--space-x-reverse));margin-left:calc(-.75rem * calc(1 - var(--space-x-reverse)))}.-space-y-4>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-1rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-1rem * var(--space-y-reverse))}.-space-x-4>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-1rem * var(--space-x-reverse));margin-left:calc(-1rem * calc(1 - var(--space-x-reverse)))}.-space-y-5>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-1.25rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-1.25rem * var(--space-y-reverse))}.-space-x-5>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-1.25rem * var(--space-x-reverse));margin-left:calc(-1.25rem * calc(1 - var(--space-x-reverse)))}.-space-y-6>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-1.5rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-1.5rem * var(--space-y-reverse))}.-space-x-6>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-1.5rem * var(--space-x-reverse));margin-left:calc(-1.5rem * calc(1 - var(--space-x-reverse)))}.-space-y-8>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-2rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-2rem * var(--space-y-reverse))}.-space-x-8>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-2rem * var(--space-x-reverse));margin-left:calc(-2rem * calc(1 - var(--space-x-reverse)))}.-space-y-10>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-2.5rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-2.5rem * var(--space-y-reverse))}.-space-x-10>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-2.5rem * var(--space-x-reverse));margin-left:calc(-2.5rem * calc(1 - var(--space-x-reverse)))}.-space-y-12>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-3rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-3rem * var(--space-y-reverse))}.-space-x-12>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-3rem * var(--space-x-reverse));margin-left:calc(-3rem * calc(1 - var(--space-x-reverse)))}.-space-y-16>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-4rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-4rem * var(--space-y-reverse))}.-space-x-16>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-4rem * var(--space-x-reverse));margin-left:calc(-4rem * calc(1 - var(--space-x-reverse)))}.-space-y-20>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-5rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-5rem * var(--space-y-reverse))}.-space-x-20>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-5rem * var(--space-x-reverse));margin-left:calc(-5rem * calc(1 - var(--space-x-reverse)))}.-space-y-24>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-6rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-6rem * var(--space-y-reverse))}.-space-x-24>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-6rem * var(--space-x-reverse));margin-left:calc(-6rem * calc(1 - var(--space-x-reverse)))}.-space-y-32>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-8rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-8rem * var(--space-y-reverse))}.-space-x-32>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-8rem * var(--space-x-reverse));margin-left:calc(-8rem * calc(1 - var(--space-x-reverse)))}.-space-y-40>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-10rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-10rem * var(--space-y-reverse))}.-space-x-40>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-10rem * var(--space-x-reverse));margin-left:calc(-10rem * calc(1 - var(--space-x-reverse)))}.-space-y-48>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-12rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-12rem * var(--space-y-reverse))}.-space-x-48>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-12rem * var(--space-x-reverse));margin-left:calc(-12rem * calc(1 - var(--space-x-reverse)))}.-space-y-56>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-14rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-14rem * var(--space-y-reverse))}.-space-x-56>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-14rem * var(--space-x-reverse));margin-left:calc(-14rem * calc(1 - var(--space-x-reverse)))}.-space-y-64>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-16rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-16rem * var(--space-y-reverse))}.-space-x-64>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-16rem * var(--space-x-reverse));margin-left:calc(-16rem * calc(1 - var(--space-x-reverse)))}.-space-y-px>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-1px * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-1px * var(--space-y-reverse))}.-space-x-px>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-1px * var(--space-x-reverse));margin-left:calc(-1px * calc(1 - var(--space-x-reverse)))}.space-y-reverse>:not(template)~:not(template){--space-y-reverse:1}.space-x-reverse>:not(template)~:not(template){--space-x-reverse:1}.divide-y-0>:not(template)~:not(template){--divide-y-reverse:0;border-top-width:calc(0px * calc(1 - var(--divide-y-reverse)));border-bottom-width:calc(0px * var(--divide-y-reverse))}.divide-x-0>:not(template)~:not(template){--divide-x-reverse:0;border-right-width:calc(0px * var(--divide-x-reverse));border-left-width:calc(0px * calc(1 - var(--divide-x-reverse)))}.divide-y-2>:not(template)~:not(template){--divide-y-reverse:0;border-top-width:calc(2px * calc(1 - var(--divide-y-reverse)));border-bottom-width:calc(2px * var(--divide-y-reverse))}.divide-x-2>:not(template)~:not(template){--divide-x-reverse:0;border-right-width:calc(2px * var(--divide-x-reverse));border-left-width:calc(2px * calc(1 - var(--divide-x-reverse)))}.divide-y-4>:not(template)~:not(template){--divide-y-reverse:0;border-top-width:calc(4px * calc(1 - var(--divide-y-reverse)));border-bottom-width:calc(4px * var(--divide-y-reverse))}.divide-x-4>:not(template)~:not(template){--divide-x-reverse:0;border-right-width:calc(4px * var(--divide-x-reverse));border-left-width:calc(4px * calc(1 - var(--divide-x-reverse)))}.divide-y-8>:not(template)~:not(template){--divide-y-reverse:0;border-top-width:calc(8px * calc(1 - var(--divide-y-reverse)));border-bottom-width:calc(8px * var(--divide-y-reverse))}.divide-x-8>:not(template)~:not(template){--divide-x-reverse:0;border-right-width:calc(8px * var(--divide-x-reverse));border-left-width:calc(8px * calc(1 - var(--divide-x-reverse)))}.divide-y>:not(template)~:not(template){--divide-y-reverse:0;border-top-width:calc(1px * calc(1 - var(--divide-y-reverse)));border-bottom-width:calc(1px * var(--divide-y-reverse))}.divide-x>:not(template)~:not(template){--divide-x-reverse:0;border-right-width:calc(1px * var(--divide-x-reverse));border-left-width:calc(1px * calc(1 - var(--divide-x-reverse)))}.divide-y-reverse>:not(template)~:not(template){--divide-y-reverse:1}.divide-x-reverse>:not(template)~:not(template){--divide-x-reverse:1}.divide-transparent>:not(template)~:not(template){border-color:transparent}.divide-current>:not(template)~:not(template){border-color:currentColor}.divide-black>:not(template)~:not(template){--divide-opacity:1;border-color:#000;border-color:rgba(0,0,0,var(--divide-opacity))}.divide-white>:not(template)~:not(template){--divide-opacity:1;border-color:#fff;border-color:rgba(255,255,255,var(--divide-opacity))}.divide-gray-100>:not(template)~:not(template){--divide-opacity:1;border-color:#f7fafc;border-color:rgba(247,250,252,var(--divide-opacity))}.divide-gray-200>:not(template)~:not(template){--divide-opacity:1;border-color:#edf2f7;border-color:rgba(237,242,247,var(--divide-opacity))}.divide-gray-300>:not(template)~:not(template){--divide-opacity:1;border-color:#e2e8f0;border-color:rgba(226,232,240,var(--divide-opacity))}.divide-gray-400>:not(template)~:not(template){--divide-opacity:1;border-color:#cbd5e0;border-color:rgba(203,213,224,var(--divide-opacity))}.divide-gray-500>:not(template)~:not(template){--divide-opacity:1;border-color:#a0aec0;border-color:rgba(160,174,192,var(--divide-opacity))}.divide-gray-600>:not(template)~:not(template){--divide-opacity:1;border-color:#718096;border-color:rgba(113,128,150,var(--divide-opacity))}.divide-gray-700>:not(template)~:not(template){--divide-opacity:1;border-color:#4a5568;border-color:rgba(74,85,104,var(--divide-opacity))}.divide-gray-800>:not(template)~:not(template){--divide-opacity:1;border-color:#2d3748;border-color:rgba(45,55,72,var(--divide-opacity))}.divide-gray-900>:not(template)~:not(template){--divide-opacity:1;border-color:#1a202c;border-color:rgba(26,32,44,var(--divide-opacity))}.divide-red-100>:not(template)~:not(template){--divide-opacity:1;border-color:#fff5f5;border-color:rgba(255,245,245,var(--divide-opacity))}.divide-red-200>:not(template)~:not(template){--divide-opacity:1;border-color:#fed7d7;border-color:rgba(254,215,215,var(--divide-opacity))}.divide-red-300>:not(template)~:not(template){--divide-opacity:1;border-color:#feb2b2;border-color:rgba(254,178,178,var(--divide-opacity))}.divide-red-400>:not(template)~:not(template){--divide-opacity:1;border-color:#fc8181;border-color:rgba(252,129,129,var(--divide-opacity))}.divide-red-500>:not(template)~:not(template){--divide-opacity:1;border-color:#f56565;border-color:rgba(245,101,101,var(--divide-opacity))}.divide-red-600>:not(template)~:not(template){--divide-opacity:1;border-color:#e53e3e;border-color:rgba(229,62,62,var(--divide-opacity))}.divide-red-700>:not(template)~:not(template){--divide-opacity:1;border-color:#c53030;border-color:rgba(197,48,48,var(--divide-opacity))}.divide-red-800>:not(template)~:not(template){--divide-opacity:1;border-color:#9b2c2c;border-color:rgba(155,44,44,var(--divide-opacity))}.divide-red-900>:not(template)~:not(template){--divide-opacity:1;border-color:#742a2a;border-color:rgba(116,42,42,var(--divide-opacity))}.divide-orange-100>:not(template)~:not(template){--divide-opacity:1;border-color:#fffaf0;border-color:rgba(255,250,240,var(--divide-opacity))}.divide-orange-200>:not(template)~:not(template){--divide-opacity:1;border-color:#feebc8;border-color:rgba(254,235,200,var(--divide-opacity))}.divide-orange-300>:not(template)~:not(template){--divide-opacity:1;border-color:#fbd38d;border-color:rgba(251,211,141,var(--divide-opacity))}.divide-orange-400>:not(template)~:not(template){--divide-opacity:1;border-color:#f6ad55;border-color:rgba(246,173,85,var(--divide-opacity))}.divide-orange-500>:not(template)~:not(template){--divide-opacity:1;border-color:#ed8936;border-color:rgba(237,137,54,var(--divide-opacity))}.divide-orange-600>:not(template)~:not(template){--divide-opacity:1;border-color:#dd6b20;border-color:rgba(221,107,32,var(--divide-opacity))}.divide-orange-700>:not(template)~:not(template){--divide-opacity:1;border-color:#c05621;border-color:rgba(192,86,33,var(--divide-opacity))}.divide-orange-800>:not(template)~:not(template){--divide-opacity:1;border-color:#9c4221;border-color:rgba(156,66,33,var(--divide-opacity))}.divide-orange-900>:not(template)~:not(template){--divide-opacity:1;border-color:#7b341e;border-color:rgba(123,52,30,var(--divide-opacity))}.divide-yellow-100>:not(template)~:not(template){--divide-opacity:1;border-color:ivory;border-color:rgba(255,255,240,var(--divide-opacity))}.divide-yellow-200>:not(template)~:not(template){--divide-opacity:1;border-color:#fefcbf;border-color:rgba(254,252,191,var(--divide-opacity))}.divide-yellow-300>:not(template)~:not(template){--divide-opacity:1;border-color:#faf089;border-color:rgba(250,240,137,var(--divide-opacity))}.divide-yellow-400>:not(template)~:not(template){--divide-opacity:1;border-color:#f6e05e;border-color:rgba(246,224,94,var(--divide-opacity))}.divide-yellow-500>:not(template)~:not(template){--divide-opacity:1;border-color:#ecc94b;border-color:rgba(236,201,75,var(--divide-opacity))}.divide-yellow-600>:not(template)~:not(template){--divide-opacity:1;border-color:#d69e2e;border-color:rgba(214,158,46,var(--divide-opacity))}.divide-yellow-700>:not(template)~:not(template){--divide-opacity:1;border-color:#b7791f;border-color:rgba(183,121,31,var(--divide-opacity))}.divide-yellow-800>:not(template)~:not(template){--divide-opacity:1;border-color:#975a16;border-color:rgba(151,90,22,var(--divide-opacity))}.divide-yellow-900>:not(template)~:not(template){--divide-opacity:1;border-color:#744210;border-color:rgba(116,66,16,var(--divide-opacity))}.divide-green-100>:not(template)~:not(template){--divide-opacity:1;border-color:#f0fff4;border-color:rgba(240,255,244,var(--divide-opacity))}.divide-green-200>:not(template)~:not(template){--divide-opacity:1;border-color:#c6f6d5;border-color:rgba(198,246,213,var(--divide-opacity))}.divide-green-300>:not(template)~:not(template){--divide-opacity:1;border-color:#9ae6b4;border-color:rgba(154,230,180,var(--divide-opacity))}.divide-green-400>:not(template)~:not(template){--divide-opacity:1;border-color:#68d391;border-color:rgba(104,211,145,var(--divide-opacity))}.divide-green-500>:not(template)~:not(template){--divide-opacity:1;border-color:#48bb78;border-color:rgba(72,187,120,var(--divide-opacity))}.divide-green-600>:not(template)~:not(template){--divide-opacity:1;border-color:#38a169;border-color:rgba(56,161,105,var(--divide-opacity))}.divide-green-700>:not(template)~:not(template){--divide-opacity:1;border-color:#2f855a;border-color:rgba(47,133,90,var(--divide-opacity))}.divide-green-800>:not(template)~:not(template){--divide-opacity:1;border-color:#276749;border-color:rgba(39,103,73,var(--divide-opacity))}.divide-green-900>:not(template)~:not(template){--divide-opacity:1;border-color:#22543d;border-color:rgba(34,84,61,var(--divide-opacity))}.divide-teal-100>:not(template)~:not(template){--divide-opacity:1;border-color:#e6fffa;border-color:rgba(230,255,250,var(--divide-opacity))}.divide-teal-200>:not(template)~:not(template){--divide-opacity:1;border-color:#b2f5ea;border-color:rgba(178,245,234,var(--divide-opacity))}.divide-teal-300>:not(template)~:not(template){--divide-opacity:1;border-color:#81e6d9;border-color:rgba(129,230,217,var(--divide-opacity))}.divide-teal-400>:not(template)~:not(template){--divide-opacity:1;border-color:#4fd1c5;border-color:rgba(79,209,197,var(--divide-opacity))}.divide-teal-500>:not(template)~:not(template){--divide-opacity:1;border-color:#38b2ac;border-color:rgba(56,178,172,var(--divide-opacity))}.divide-teal-600>:not(template)~:not(template){--divide-opacity:1;border-color:#319795;border-color:rgba(49,151,149,var(--divide-opacity))}.divide-teal-700>:not(template)~:not(template){--divide-opacity:1;border-color:#2c7a7b;border-color:rgba(44,122,123,var(--divide-opacity))}.divide-teal-800>:not(template)~:not(template){--divide-opacity:1;border-color:#285e61;border-color:rgba(40,94,97,var(--divide-opacity))}.divide-teal-900>:not(template)~:not(template){--divide-opacity:1;border-color:#234e52;border-color:rgba(35,78,82,var(--divide-opacity))}.divide-blue-100>:not(template)~:not(template){--divide-opacity:1;border-color:#ebf8ff;border-color:rgba(235,248,255,var(--divide-opacity))}.divide-blue-200>:not(template)~:not(template){--divide-opacity:1;border-color:#bee3f8;border-color:rgba(190,227,248,var(--divide-opacity))}.divide-blue-300>:not(template)~:not(template){--divide-opacity:1;border-color:#90cdf4;border-color:rgba(144,205,244,var(--divide-opacity))}.divide-blue-400>:not(template)~:not(template){--divide-opacity:1;border-color:#63b3ed;border-color:rgba(99,179,237,var(--divide-opacity))}.divide-blue-500>:not(template)~:not(template){--divide-opacity:1;border-color:#4299e1;border-color:rgba(66,153,225,var(--divide-opacity))}.divide-blue-600>:not(template)~:not(template){--divide-opacity:1;border-color:#3182ce;border-color:rgba(49,130,206,var(--divide-opacity))}.divide-blue-700>:not(template)~:not(template){--divide-opacity:1;border-color:#2b6cb0;border-color:rgba(43,108,176,var(--divide-opacity))}.divide-blue-800>:not(template)~:not(template){--divide-opacity:1;border-color:#2c5282;border-color:rgba(44,82,130,var(--divide-opacity))}.divide-blue-900>:not(template)~:not(template){--divide-opacity:1;border-color:#2a4365;border-color:rgba(42,67,101,var(--divide-opacity))}.divide-indigo-100>:not(template)~:not(template){--divide-opacity:1;border-color:#ebf4ff;border-color:rgba(235,244,255,var(--divide-opacity))}.divide-indigo-200>:not(template)~:not(template){--divide-opacity:1;border-color:#c3dafe;border-color:rgba(195,218,254,var(--divide-opacity))}.divide-indigo-300>:not(template)~:not(template){--divide-opacity:1;border-color:#a3bffa;border-color:rgba(163,191,250,var(--divide-opacity))}.divide-indigo-400>:not(template)~:not(template){--divide-opacity:1;border-color:#7f9cf5;border-color:rgba(127,156,245,var(--divide-opacity))}.divide-indigo-500>:not(template)~:not(template){--divide-opacity:1;border-color:#667eea;border-color:rgba(102,126,234,var(--divide-opacity))}.divide-indigo-600>:not(template)~:not(template){--divide-opacity:1;border-color:#5a67d8;border-color:rgba(90,103,216,var(--divide-opacity))}.divide-indigo-700>:not(template)~:not(template){--divide-opacity:1;border-color:#4c51bf;border-color:rgba(76,81,191,var(--divide-opacity))}.divide-indigo-800>:not(template)~:not(template){--divide-opacity:1;border-color:#434190;border-color:rgba(67,65,144,var(--divide-opacity))}.divide-indigo-900>:not(template)~:not(template){--divide-opacity:1;border-color:#3c366b;border-color:rgba(60,54,107,var(--divide-opacity))}.divide-purple-100>:not(template)~:not(template){--divide-opacity:1;border-color:#faf5ff;border-color:rgba(250,245,255,var(--divide-opacity))}.divide-purple-200>:not(template)~:not(template){--divide-opacity:1;border-color:#e9d8fd;border-color:rgba(233,216,253,var(--divide-opacity))}.divide-purple-300>:not(template)~:not(template){--divide-opacity:1;border-color:#d6bcfa;border-color:rgba(214,188,250,var(--divide-opacity))}.divide-purple-400>:not(template)~:not(template){--divide-opacity:1;border-color:#b794f4;border-color:rgba(183,148,244,var(--divide-opacity))}.divide-purple-500>:not(template)~:not(template){--divide-opacity:1;border-color:#9f7aea;border-color:rgba(159,122,234,var(--divide-opacity))}.divide-purple-600>:not(template)~:not(template){--divide-opacity:1;border-color:#805ad5;border-color:rgba(128,90,213,var(--divide-opacity))}.divide-purple-700>:not(template)~:not(template){--divide-opacity:1;border-color:#6b46c1;border-color:rgba(107,70,193,var(--divide-opacity))}.divide-purple-800>:not(template)~:not(template){--divide-opacity:1;border-color:#553c9a;border-color:rgba(85,60,154,var(--divide-opacity))}.divide-purple-900>:not(template)~:not(template){--divide-opacity:1;border-color:#44337a;border-color:rgba(68,51,122,var(--divide-opacity))}.divide-pink-100>:not(template)~:not(template){--divide-opacity:1;border-color:#fff5f7;border-color:rgba(255,245,247,var(--divide-opacity))}.divide-pink-200>:not(template)~:not(template){--divide-opacity:1;border-color:#fed7e2;border-color:rgba(254,215,226,var(--divide-opacity))}.divide-pink-300>:not(template)~:not(template){--divide-opacity:1;border-color:#fbb6ce;border-color:rgba(251,182,206,var(--divide-opacity))}.divide-pink-400>:not(template)~:not(template){--divide-opacity:1;border-color:#f687b3;border-color:rgba(246,135,179,var(--divide-opacity))}.divide-pink-500>:not(template)~:not(template){--divide-opacity:1;border-color:#ed64a6;border-color:rgba(237,100,166,var(--divide-opacity))}.divide-pink-600>:not(template)~:not(template){--divide-opacity:1;border-color:#d53f8c;border-color:rgba(213,63,140,var(--divide-opacity))}.divide-pink-700>:not(template)~:not(template){--divide-opacity:1;border-color:#b83280;border-color:rgba(184,50,128,var(--divide-opacity))}.divide-pink-800>:not(template)~:not(template){--divide-opacity:1;border-color:#97266d;border-color:rgba(151,38,109,var(--divide-opacity))}.divide-pink-900>:not(template)~:not(template){--divide-opacity:1;border-color:#702459;border-color:rgba(112,36,89,var(--divide-opacity))}.divide-solid>:not(template)~:not(template){border-style:solid}.divide-dashed>:not(template)~:not(template){border-style:dashed}.divide-dotted>:not(template)~:not(template){border-style:dotted}.divide-double>:not(template)~:not(template){border-style:double}.divide-none>:not(template)~:not(template){border-style:none}.divide-opacity-0>:not(template)~:not(template){--divide-opacity:0}.divide-opacity-25>:not(template)~:not(template){--divide-opacity:0.25}.divide-opacity-50>:not(template)~:not(template){--divide-opacity:0.5}.divide-opacity-75>:not(template)~:not(template){--divide-opacity:0.75}.divide-opacity-100>:not(template)~:not(template){--divide-opacity:1}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border-width:0}.not-sr-only{position:static;width:auto;height:auto;padding:0;margin:0;overflow:visible;clip:auto;white-space:normal}.focus\:sr-only:focus{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border-width:0}.focus\:not-sr-only:focus{position:static;width:auto;height:auto;padding:0;margin:0;overflow:visible;clip:auto;white-space:normal}.appearance-none{-webkit-appearance:none;-moz-appearance:none;appearance:none}.bg-fixed{background-attachment:fixed}.bg-local{background-attachment:local}.bg-scroll{background-attachment:scroll}.bg-clip-border{background-clip:border-box}.bg-clip-padding{background-clip:padding-box}.bg-clip-content{background-clip:content-box}.bg-clip-text{-webkit-background-clip:text;background-clip:text}.bg-transparent{background-color:transparent}.bg-current{background-color:currentColor}.bg-black{--bg-opacity:1;background-color:#000;background-color:rgba(0,0,0,var(--bg-opacity))}.bg-white{--bg-opacity:1;background-color:#fff;background-color:rgba(255,255,255,var(--bg-opacity))}.bg-gray-100{--bg-opacity:1;background-color:#f7fafc;background-color:rgba(247,250,252,var(--bg-opacity))}.bg-gray-200{--bg-opacity:1;background-color:#edf2f7;background-color:rgba(237,242,247,var(--bg-opacity))}.bg-gray-300{--bg-opacity:1;background-color:#e2e8f0;background-color:rgba(226,232,240,var(--bg-opacity))}.bg-gray-400{--bg-opacity:1;background-color:#cbd5e0;background-color:rgba(203,213,224,var(--bg-opacity))}.bg-gray-500{--bg-opacity:1;background-color:#a0aec0;background-color:rgba(160,174,192,var(--bg-opacity))}.bg-gray-600{--bg-opacity:1;background-color:#718096;background-color:rgba(113,128,150,var(--bg-opacity))}.bg-gray-700{--bg-opacity:1;background-color:#4a5568;background-color:rgba(74,85,104,var(--bg-opacity))}.bg-gray-800{--bg-opacity:1;background-color:#2d3748;background-color:rgba(45,55,72,var(--bg-opacity))}.bg-gray-900{--bg-opacity:1;background-color:#1a202c;background-color:rgba(26,32,44,var(--bg-opacity))}.bg-red-100{--bg-opacity:1;background-color:#fff5f5;background-color:rgba(255,245,245,var(--bg-opacity))}.bg-red-200{--bg-opacity:1;background-color:#fed7d7;background-color:rgba(254,215,215,var(--bg-opacity))}.bg-red-300{--bg-opacity:1;background-color:#feb2b2;background-color:rgba(254,178,178,var(--bg-opacity))}.bg-red-400{--bg-opacity:1;background-color:#fc8181;background-color:rgba(252,129,129,var(--bg-opacity))}.bg-red-500{--bg-opacity:1;background-color:#f56565;background-color:rgba(245,101,101,var(--bg-opacity))}.bg-red-600{--bg-opacity:1;background-color:#e53e3e;background-color:rgba(229,62,62,var(--bg-opacity))}.bg-red-700{--bg-opacity:1;background-color:#c53030;background-color:rgba(197,48,48,var(--bg-opacity))}.bg-red-800{--bg-opacity:1;background-color:#9b2c2c;background-color:rgba(155,44,44,var(--bg-opacity))}.bg-red-900{--bg-opacity:1;background-color:#742a2a;background-color:rgba(116,42,42,var(--bg-opacity))}.bg-orange-100{--bg-opacity:1;background-color:#fffaf0;background-color:rgba(255,250,240,var(--bg-opacity))}.bg-orange-200{--bg-opacity:1;background-color:#feebc8;background-color:rgba(254,235,200,var(--bg-opacity))}.bg-orange-300{--bg-opacity:1;background-color:#fbd38d;background-color:rgba(251,211,141,var(--bg-opacity))}.bg-orange-400{--bg-opacity:1;background-color:#f6ad55;background-color:rgba(246,173,85,var(--bg-opacity))}.bg-orange-500{--bg-opacity:1;background-color:#ed8936;background-color:rgba(237,137,54,var(--bg-opacity))}.bg-orange-600{--bg-opacity:1;background-color:#dd6b20;background-color:rgba(221,107,32,var(--bg-opacity))}.bg-orange-700{--bg-opacity:1;background-color:#c05621;background-color:rgba(192,86,33,var(--bg-opacity))}.bg-orange-800{--bg-opacity:1;background-color:#9c4221;background-color:rgba(156,66,33,var(--bg-opacity))}.bg-orange-900{--bg-opacity:1;background-color:#7b341e;background-color:rgba(123,52,30,var(--bg-opacity))}.bg-yellow-100{--bg-opacity:1;background-color:ivory;background-color:rgba(255,255,240,var(--bg-opacity))}.bg-yellow-200{--bg-opacity:1;background-color:#fefcbf;background-color:rgba(254,252,191,var(--bg-opacity))}.bg-yellow-300{--bg-opacity:1;background-color:#faf089;background-color:rgba(250,240,137,var(--bg-opacity))}.bg-yellow-400{--bg-opacity:1;background-color:#f6e05e;background-color:rgba(246,224,94,var(--bg-opacity))}.bg-yellow-500{--bg-opacity:1;background-color:#ecc94b;background-color:rgba(236,201,75,var(--bg-opacity))}.bg-yellow-600{--bg-opacity:1;background-color:#d69e2e;background-color:rgba(214,158,46,var(--bg-opacity))}.bg-yellow-700{--bg-opacity:1;background-color:#b7791f;background-color:rgba(183,121,31,var(--bg-opacity))}.bg-yellow-800{--bg-opacity:1;background-color:#975a16;background-color:rgba(151,90,22,var(--bg-opacity))}.bg-yellow-900{--bg-opacity:1;background-color:#744210;background-color:rgba(116,66,16,var(--bg-opacity))}.bg-green-100{--bg-opacity:1;background-color:#f0fff4;background-color:rgba(240,255,244,var(--bg-opacity))}.bg-green-200{--bg-opacity:1;background-color:#c6f6d5;background-color:rgba(198,246,213,var(--bg-opacity))}.bg-green-300{--bg-opacity:1;background-color:#9ae6b4;background-color:rgba(154,230,180,var(--bg-opacity))}.bg-green-400{--bg-opacity:1;background-color:#68d391;background-color:rgba(104,211,145,var(--bg-opacity))}.bg-green-500{--bg-opacity:1;background-color:#48bb78;background-color:rgba(72,187,120,var(--bg-opacity))}.bg-green-600{--bg-opacity:1;background-color:#38a169;background-color:rgba(56,161,105,var(--bg-opacity))}.bg-green-700{--bg-opacity:1;background-color:#2f855a;background-color:rgba(47,133,90,var(--bg-opacity))}.bg-green-800{--bg-opacity:1;background-color:#276749;background-color:rgba(39,103,73,var(--bg-opacity))}.bg-green-900{--bg-opacity:1;background-color:#22543d;background-color:rgba(34,84,61,var(--bg-opacity))}.bg-teal-100{--bg-opacity:1;background-color:#e6fffa;background-color:rgba(230,255,250,var(--bg-opacity))}.bg-teal-200{--bg-opacity:1;background-color:#b2f5ea;background-color:rgba(178,245,234,var(--bg-opacity))}.bg-teal-300{--bg-opacity:1;background-color:#81e6d9;background-color:rgba(129,230,217,var(--bg-opacity))}.bg-teal-400{--bg-opacity:1;background-color:#4fd1c5;background-color:rgba(79,209,197,var(--bg-opacity))}.bg-teal-500{--bg-opacity:1;background-color:#38b2ac;background-color:rgba(56,178,172,var(--bg-opacity))}.bg-teal-600{--bg-opacity:1;background-color:#319795;background-color:rgba(49,151,149,var(--bg-opacity))}.bg-teal-700{--bg-opacity:1;background-color:#2c7a7b;background-color:rgba(44,122,123,var(--bg-opacity))}.bg-teal-800{--bg-opacity:1;background-color:#285e61;background-color:rgba(40,94,97,var(--bg-opacity))}.bg-teal-900{--bg-opacity:1;background-color:#234e52;background-color:rgba(35,78,82,var(--bg-opacity))}.bg-blue-100{--bg-opacity:1;background-color:#ebf8ff;background-color:rgba(235,248,255,var(--bg-opacity))}.bg-blue-200{--bg-opacity:1;background-color:#bee3f8;background-color:rgba(190,227,248,var(--bg-opacity))}.bg-blue-300{--bg-opacity:1;background-color:#90cdf4;background-color:rgba(144,205,244,var(--bg-opacity))}.bg-blue-400{--bg-opacity:1;background-color:#63b3ed;background-color:rgba(99,179,237,var(--bg-opacity))}.bg-blue-500{--bg-opacity:1;background-color:#4299e1;background-color:rgba(66,153,225,var(--bg-opacity))}.bg-blue-600{--bg-opacity:1;background-color:#3182ce;background-color:rgba(49,130,206,var(--bg-opacity))}.bg-blue-700{--bg-opacity:1;background-color:#2b6cb0;background-color:rgba(43,108,176,var(--bg-opacity))}.bg-blue-800{--bg-opacity:1;background-color:#2c5282;background-color:rgba(44,82,130,var(--bg-opacity))}.bg-blue-900{--bg-opacity:1;background-color:#2a4365;background-color:rgba(42,67,101,var(--bg-opacity))}.bg-indigo-100{--bg-opacity:1;background-color:#ebf4ff;background-color:rgba(235,244,255,var(--bg-opacity))}.bg-indigo-200{--bg-opacity:1;background-color:#c3dafe;background-color:rgba(195,218,254,var(--bg-opacity))}.bg-indigo-300{--bg-opacity:1;background-color:#a3bffa;background-color:rgba(163,191,250,var(--bg-opacity))}.bg-indigo-400{--bg-opacity:1;background-color:#7f9cf5;background-color:rgba(127,156,245,var(--bg-opacity))}.bg-indigo-500{--bg-opacity:1;background-color:#667eea;background-color:rgba(102,126,234,var(--bg-opacity))}.bg-indigo-600{--bg-opacity:1;background-color:#5a67d8;background-color:rgba(90,103,216,var(--bg-opacity))}.bg-indigo-700{--bg-opacity:1;background-color:#4c51bf;background-color:rgba(76,81,191,var(--bg-opacity))}.bg-indigo-800{--bg-opacity:1;background-color:#434190;background-color:rgba(67,65,144,var(--bg-opacity))}.bg-indigo-900{--bg-opacity:1;background-color:#3c366b;background-color:rgba(60,54,107,var(--bg-opacity))}.bg-purple-100{--bg-opacity:1;background-color:#faf5ff;background-color:rgba(250,245,255,var(--bg-opacity))}.bg-purple-200{--bg-opacity:1;background-color:#e9d8fd;background-color:rgba(233,216,253,var(--bg-opacity))}.bg-purple-300{--bg-opacity:1;background-color:#d6bcfa;background-color:rgba(214,188,250,var(--bg-opacity))}.bg-purple-400{--bg-opacity:1;background-color:#b794f4;background-color:rgba(183,148,244,var(--bg-opacity))}.bg-purple-500{--bg-opacity:1;background-color:#9f7aea;background-color:rgba(159,122,234,var(--bg-opacity))}.bg-purple-600{--bg-opacity:1;background-color:#805ad5;background-color:rgba(128,90,213,var(--bg-opacity))}.bg-purple-700{--bg-opacity:1;background-color:#6b46c1;background-color:rgba(107,70,193,var(--bg-opacity))}.bg-purple-800{--bg-opacity:1;background-color:#553c9a;background-color:rgba(85,60,154,var(--bg-opacity))}.bg-purple-900{--bg-opacity:1;background-color:#44337a;background-color:rgba(68,51,122,var(--bg-opacity))}.bg-pink-100{--bg-opacity:1;background-color:#fff5f7;background-color:rgba(255,245,247,var(--bg-opacity))}.bg-pink-200{--bg-opacity:1;background-color:#fed7e2;background-color:rgba(254,215,226,var(--bg-opacity))}.bg-pink-300{--bg-opacity:1;background-color:#fbb6ce;background-color:rgba(251,182,206,var(--bg-opacity))}.bg-pink-400{--bg-opacity:1;background-color:#f687b3;background-color:rgba(246,135,179,var(--bg-opacity))}.bg-pink-500{--bg-opacity:1;background-color:#ed64a6;background-color:rgba(237,100,166,var(--bg-opacity))}.bg-pink-600{--bg-opacity:1;background-color:#d53f8c;background-color:rgba(213,63,140,var(--bg-opacity))}.bg-pink-700{--bg-opacity:1;background-color:#b83280;background-color:rgba(184,50,128,var(--bg-opacity))}.bg-pink-800{--bg-opacity:1;background-color:#97266d;background-color:rgba(151,38,109,var(--bg-opacity))}.bg-pink-900{--bg-opacity:1;background-color:#702459;background-color:rgba(112,36,89,var(--bg-opacity))}.hover\:bg-transparent:hover{background-color:transparent}.hover\:bg-current:hover{background-color:currentColor}.hover\:bg-black:hover{--bg-opacity:1;background-color:#000;background-color:rgba(0,0,0,var(--bg-opacity))}.hover\:bg-white:hover{--bg-opacity:1;background-color:#fff;background-color:rgba(255,255,255,var(--bg-opacity))}.hover\:bg-gray-100:hover{--bg-opacity:1;background-color:#f7fafc;background-color:rgba(247,250,252,var(--bg-opacity))}.hover\:bg-gray-200:hover{--bg-opacity:1;background-color:#edf2f7;background-color:rgba(237,242,247,var(--bg-opacity))}.hover\:bg-gray-300:hover{--bg-opacity:1;background-color:#e2e8f0;background-color:rgba(226,232,240,var(--bg-opacity))}.hover\:bg-gray-400:hover{--bg-opacity:1;background-color:#cbd5e0;background-color:rgba(203,213,224,var(--bg-opacity))}.hover\:bg-gray-500:hover{--bg-opacity:1;background-color:#a0aec0;background-color:rgba(160,174,192,var(--bg-opacity))}.hover\:bg-gray-600:hover{--bg-opacity:1;background-color:#718096;background-color:rgba(113,128,150,var(--bg-opacity))}.hover\:bg-gray-700:hover{--bg-opacity:1;background-color:#4a5568;background-color:rgba(74,85,104,var(--bg-opacity))}.hover\:bg-gray-800:hover{--bg-opacity:1;background-color:#2d3748;background-color:rgba(45,55,72,var(--bg-opacity))}.hover\:bg-gray-900:hover{--bg-opacity:1;background-color:#1a202c;background-color:rgba(26,32,44,var(--bg-opacity))}.hover\:bg-red-100:hover{--bg-opacity:1;background-color:#fff5f5;background-color:rgba(255,245,245,var(--bg-opacity))}.hover\:bg-red-200:hover{--bg-opacity:1;background-color:#fed7d7;background-color:rgba(254,215,215,var(--bg-opacity))}.hover\:bg-red-300:hover{--bg-opacity:1;background-color:#feb2b2;background-color:rgba(254,178,178,var(--bg-opacity))}.hover\:bg-red-400:hover{--bg-opacity:1;background-color:#fc8181;background-color:rgba(252,129,129,var(--bg-opacity))}.hover\:bg-red-500:hover{--bg-opacity:1;background-color:#f56565;background-color:rgba(245,101,101,var(--bg-opacity))}.hover\:bg-red-600:hover{--bg-opacity:1;background-color:#e53e3e;background-color:rgba(229,62,62,var(--bg-opacity))}.hover\:bg-red-700:hover{--bg-opacity:1;background-color:#c53030;background-color:rgba(197,48,48,var(--bg-opacity))}.hover\:bg-red-800:hover{--bg-opacity:1;background-color:#9b2c2c;background-color:rgba(155,44,44,var(--bg-opacity))}.hover\:bg-red-900:hover{--bg-opacity:1;background-color:#742a2a;background-color:rgba(116,42,42,var(--bg-opacity))}.hover\:bg-orange-100:hover{--bg-opacity:1;background-color:#fffaf0;background-color:rgba(255,250,240,var(--bg-opacity))}.hover\:bg-orange-200:hover{--bg-opacity:1;background-color:#feebc8;background-color:rgba(254,235,200,var(--bg-opacity))}.hover\:bg-orange-300:hover{--bg-opacity:1;background-color:#fbd38d;background-color:rgba(251,211,141,var(--bg-opacity))}.hover\:bg-orange-400:hover{--bg-opacity:1;background-color:#f6ad55;background-color:rgba(246,173,85,var(--bg-opacity))}.hover\:bg-orange-500:hover{--bg-opacity:1;background-color:#ed8936;background-color:rgba(237,137,54,var(--bg-opacity))}.hover\:bg-orange-600:hover{--bg-opacity:1;background-color:#dd6b20;background-color:rgba(221,107,32,var(--bg-opacity))}.hover\:bg-orange-700:hover{--bg-opacity:1;background-color:#c05621;background-color:rgba(192,86,33,var(--bg-opacity))}.hover\:bg-orange-800:hover{--bg-opacity:1;background-color:#9c4221;background-color:rgba(156,66,33,var(--bg-opacity))}.hover\:bg-orange-900:hover{--bg-opacity:1;background-color:#7b341e;background-color:rgba(123,52,30,var(--bg-opacity))}.hover\:bg-yellow-100:hover{--bg-opacity:1;background-color:ivory;background-color:rgba(255,255,240,var(--bg-opacity))}.hover\:bg-yellow-200:hover{--bg-opacity:1;background-color:#fefcbf;background-color:rgba(254,252,191,var(--bg-opacity))}.hover\:bg-yellow-300:hover{--bg-opacity:1;background-color:#faf089;background-color:rgba(250,240,137,var(--bg-opacity))}.hover\:bg-yellow-400:hover{--bg-opacity:1;background-color:#f6e05e;background-color:rgba(246,224,94,var(--bg-opacity))}.hover\:bg-yellow-500:hover{--bg-opacity:1;background-color:#ecc94b;background-color:rgba(236,201,75,var(--bg-opacity))}.hover\:bg-yellow-600:hover{--bg-opacity:1;background-color:#d69e2e;background-color:rgba(214,158,46,var(--bg-opacity))}.hover\:bg-yellow-700:hover{--bg-opacity:1;background-color:#b7791f;background-color:rgba(183,121,31,var(--bg-opacity))}.hover\:bg-yellow-800:hover{--bg-opacity:1;background-color:#975a16;background-color:rgba(151,90,22,var(--bg-opacity))}.hover\:bg-yellow-900:hover{--bg-opacity:1;background-color:#744210;background-color:rgba(116,66,16,var(--bg-opacity))}.hover\:bg-green-100:hover{--bg-opacity:1;background-color:#f0fff4;background-color:rgba(240,255,244,var(--bg-opacity))}.hover\:bg-green-200:hover{--bg-opacity:1;background-color:#c6f6d5;background-color:rgba(198,246,213,var(--bg-opacity))}.hover\:bg-green-300:hover{--bg-opacity:1;background-color:#9ae6b4;background-color:rgba(154,230,180,var(--bg-opacity))}.hover\:bg-green-400:hover{--bg-opacity:1;background-color:#68d391;background-color:rgba(104,211,145,var(--bg-opacity))}.hover\:bg-green-500:hover{--bg-opacity:1;background-color:#48bb78;background-color:rgba(72,187,120,var(--bg-opacity))}.hover\:bg-green-600:hover{--bg-opacity:1;background-color:#38a169;background-color:rgba(56,161,105,var(--bg-opacity))}.hover\:bg-green-700:hover{--bg-opacity:1;background-color:#2f855a;background-color:rgba(47,133,90,var(--bg-opacity))}.hover\:bg-green-800:hover{--bg-opacity:1;background-color:#276749;background-color:rgba(39,103,73,var(--bg-opacity))}.hover\:bg-green-900:hover{--bg-opacity:1;background-color:#22543d;background-color:rgba(34,84,61,var(--bg-opacity))}.hover\:bg-teal-100:hover{--bg-opacity:1;background-color:#e6fffa;background-color:rgba(230,255,250,var(--bg-opacity))}.hover\:bg-teal-200:hover{--bg-opacity:1;background-color:#b2f5ea;background-color:rgba(178,245,234,var(--bg-opacity))}.hover\:bg-teal-300:hover{--bg-opacity:1;background-color:#81e6d9;background-color:rgba(129,230,217,var(--bg-opacity))}.hover\:bg-teal-400:hover{--bg-opacity:1;background-color:#4fd1c5;background-color:rgba(79,209,197,var(--bg-opacity))}.hover\:bg-teal-500:hover{--bg-opacity:1;background-color:#38b2ac;background-color:rgba(56,178,172,var(--bg-opacity))}.hover\:bg-teal-600:hover{--bg-opacity:1;background-color:#319795;background-color:rgba(49,151,149,var(--bg-opacity))}.hover\:bg-teal-700:hover{--bg-opacity:1;background-color:#2c7a7b;background-color:rgba(44,122,123,var(--bg-opacity))}.hover\:bg-teal-800:hover{--bg-opacity:1;background-color:#285e61;background-color:rgba(40,94,97,var(--bg-opacity))}.hover\:bg-teal-900:hover{--bg-opacity:1;background-color:#234e52;background-color:rgba(35,78,82,var(--bg-opacity))}.hover\:bg-blue-100:hover{--bg-opacity:1;background-color:#ebf8ff;background-color:rgba(235,248,255,var(--bg-opacity))}.hover\:bg-blue-200:hover{--bg-opacity:1;background-color:#bee3f8;background-color:rgba(190,227,248,var(--bg-opacity))}.hover\:bg-blue-300:hover{--bg-opacity:1;background-color:#90cdf4;background-color:rgba(144,205,244,var(--bg-opacity))}.hover\:bg-blue-400:hover{--bg-opacity:1;background-color:#63b3ed;background-color:rgba(99,179,237,var(--bg-opacity))}.hover\:bg-blue-500:hover{--bg-opacity:1;background-color:#4299e1;background-color:rgba(66,153,225,var(--bg-opacity))}.hover\:bg-blue-600:hover{--bg-opacity:1;background-color:#3182ce;background-color:rgba(49,130,206,var(--bg-opacity))}.hover\:bg-blue-700:hover{--bg-opacity:1;background-color:#2b6cb0;background-color:rgba(43,108,176,var(--bg-opacity))}.hover\:bg-blue-800:hover{--bg-opacity:1;background-color:#2c5282;background-color:rgba(44,82,130,var(--bg-opacity))}.hover\:bg-blue-900:hover{--bg-opacity:1;background-color:#2a4365;background-color:rgba(42,67,101,var(--bg-opacity))}.hover\:bg-indigo-100:hover{--bg-opacity:1;background-color:#ebf4ff;background-color:rgba(235,244,255,var(--bg-opacity))}.hover\:bg-indigo-200:hover{--bg-opacity:1;background-color:#c3dafe;background-color:rgba(195,218,254,var(--bg-opacity))}.hover\:bg-indigo-300:hover{--bg-opacity:1;background-color:#a3bffa;background-color:rgba(163,191,250,var(--bg-opacity))}.hover\:bg-indigo-400:hover{--bg-opacity:1;background-color:#7f9cf5;background-color:rgba(127,156,245,var(--bg-opacity))}.hover\:bg-indigo-500:hover{--bg-opacity:1;background-color:#667eea;background-color:rgba(102,126,234,var(--bg-opacity))}.hover\:bg-indigo-600:hover{--bg-opacity:1;background-color:#5a67d8;background-color:rgba(90,103,216,var(--bg-opacity))}.hover\:bg-indigo-700:hover{--bg-opacity:1;background-color:#4c51bf;background-color:rgba(76,81,191,var(--bg-opacity))}.hover\:bg-indigo-800:hover{--bg-opacity:1;background-color:#434190;background-color:rgba(67,65,144,var(--bg-opacity))}.hover\:bg-indigo-900:hover{--bg-opacity:1;background-color:#3c366b;background-color:rgba(60,54,107,var(--bg-opacity))}.hover\:bg-purple-100:hover{--bg-opacity:1;background-color:#faf5ff;background-color:rgba(250,245,255,var(--bg-opacity))}.hover\:bg-purple-200:hover{--bg-opacity:1;background-color:#e9d8fd;background-color:rgba(233,216,253,var(--bg-opacity))}.hover\:bg-purple-300:hover{--bg-opacity:1;background-color:#d6bcfa;background-color:rgba(214,188,250,var(--bg-opacity))}.hover\:bg-purple-400:hover{--bg-opacity:1;background-color:#b794f4;background-color:rgba(183,148,244,var(--bg-opacity))}.hover\:bg-purple-500:hover{--bg-opacity:1;background-color:#9f7aea;background-color:rgba(159,122,234,var(--bg-opacity))}.hover\:bg-purple-600:hover{--bg-opacity:1;background-color:#805ad5;background-color:rgba(128,90,213,var(--bg-opacity))}.hover\:bg-purple-700:hover{--bg-opacity:1;background-color:#6b46c1;background-color:rgba(107,70,193,var(--bg-opacity))}.hover\:bg-purple-800:hover{--bg-opacity:1;background-color:#553c9a;background-color:rgba(85,60,154,var(--bg-opacity))}.hover\:bg-purple-900:hover{--bg-opacity:1;background-color:#44337a;background-color:rgba(68,51,122,var(--bg-opacity))}.hover\:bg-pink-100:hover{--bg-opacity:1;background-color:#fff5f7;background-color:rgba(255,245,247,var(--bg-opacity))}.hover\:bg-pink-200:hover{--bg-opacity:1;background-color:#fed7e2;background-color:rgba(254,215,226,var(--bg-opacity))}.hover\:bg-pink-300:hover{--bg-opacity:1;background-color:#fbb6ce;background-color:rgba(251,182,206,var(--bg-opacity))}.hover\:bg-pink-400:hover{--bg-opacity:1;background-color:#f687b3;background-color:rgba(246,135,179,var(--bg-opacity))}.hover\:bg-pink-500:hover{--bg-opacity:1;background-color:#ed64a6;background-color:rgba(237,100,166,var(--bg-opacity))}.hover\:bg-pink-600:hover{--bg-opacity:1;background-color:#d53f8c;background-color:rgba(213,63,140,var(--bg-opacity))}.hover\:bg-pink-700:hover{--bg-opacity:1;background-color:#b83280;background-color:rgba(184,50,128,var(--bg-opacity))}.hover\:bg-pink-800:hover{--bg-opacity:1;background-color:#97266d;background-color:rgba(151,38,109,var(--bg-opacity))}.hover\:bg-pink-900:hover{--bg-opacity:1;background-color:#702459;background-color:rgba(112,36,89,var(--bg-opacity))}.focus\:bg-transparent:focus{background-color:transparent}.focus\:bg-current:focus{background-color:currentColor}.focus\:bg-black:focus{--bg-opacity:1;background-color:#000;background-color:rgba(0,0,0,var(--bg-opacity))}.focus\:bg-white:focus{--bg-opacity:1;background-color:#fff;background-color:rgba(255,255,255,var(--bg-opacity))}.focus\:bg-gray-100:focus{--bg-opacity:1;background-color:#f7fafc;background-color:rgba(247,250,252,var(--bg-opacity))}.focus\:bg-gray-200:focus{--bg-opacity:1;background-color:#edf2f7;background-color:rgba(237,242,247,var(--bg-opacity))}.focus\:bg-gray-300:focus{--bg-opacity:1;background-color:#e2e8f0;background-color:rgba(226,232,240,var(--bg-opacity))}.focus\:bg-gray-400:focus{--bg-opacity:1;background-color:#cbd5e0;background-color:rgba(203,213,224,var(--bg-opacity))}.focus\:bg-gray-500:focus{--bg-opacity:1;background-color:#a0aec0;background-color:rgba(160,174,192,var(--bg-opacity))}.focus\:bg-gray-600:focus{--bg-opacity:1;background-color:#718096;background-color:rgba(113,128,150,var(--bg-opacity))}.focus\:bg-gray-700:focus{--bg-opacity:1;background-color:#4a5568;background-color:rgba(74,85,104,var(--bg-opacity))}.focus\:bg-gray-800:focus{--bg-opacity:1;background-color:#2d3748;background-color:rgba(45,55,72,var(--bg-opacity))}.focus\:bg-gray-900:focus{--bg-opacity:1;background-color:#1a202c;background-color:rgba(26,32,44,var(--bg-opacity))}.focus\:bg-red-100:focus{--bg-opacity:1;background-color:#fff5f5;background-color:rgba(255,245,245,var(--bg-opacity))}.focus\:bg-red-200:focus{--bg-opacity:1;background-color:#fed7d7;background-color:rgba(254,215,215,var(--bg-opacity))}.focus\:bg-red-300:focus{--bg-opacity:1;background-color:#feb2b2;background-color:rgba(254,178,178,var(--bg-opacity))}.focus\:bg-red-400:focus{--bg-opacity:1;background-color:#fc8181;background-color:rgba(252,129,129,var(--bg-opacity))}.focus\:bg-red-500:focus{--bg-opacity:1;background-color:#f56565;background-color:rgba(245,101,101,var(--bg-opacity))}.focus\:bg-red-600:focus{--bg-opacity:1;background-color:#e53e3e;background-color:rgba(229,62,62,var(--bg-opacity))}.focus\:bg-red-700:focus{--bg-opacity:1;background-color:#c53030;background-color:rgba(197,48,48,var(--bg-opacity))}.focus\:bg-red-800:focus{--bg-opacity:1;background-color:#9b2c2c;background-color:rgba(155,44,44,var(--bg-opacity))}.focus\:bg-red-900:focus{--bg-opacity:1;background-color:#742a2a;background-color:rgba(116,42,42,var(--bg-opacity))}.focus\:bg-orange-100:focus{--bg-opacity:1;background-color:#fffaf0;background-color:rgba(255,250,240,var(--bg-opacity))}.focus\:bg-orange-200:focus{--bg-opacity:1;background-color:#feebc8;background-color:rgba(254,235,200,var(--bg-opacity))}.focus\:bg-orange-300:focus{--bg-opacity:1;background-color:#fbd38d;background-color:rgba(251,211,141,var(--bg-opacity))}.focus\:bg-orange-400:focus{--bg-opacity:1;background-color:#f6ad55;background-color:rgba(246,173,85,var(--bg-opacity))}.focus\:bg-orange-500:focus{--bg-opacity:1;background-color:#ed8936;background-color:rgba(237,137,54,var(--bg-opacity))}.focus\:bg-orange-600:focus{--bg-opacity:1;background-color:#dd6b20;background-color:rgba(221,107,32,var(--bg-opacity))}.focus\:bg-orange-700:focus{--bg-opacity:1;background-color:#c05621;background-color:rgba(192,86,33,var(--bg-opacity))}.focus\:bg-orange-800:focus{--bg-opacity:1;background-color:#9c4221;background-color:rgba(156,66,33,var(--bg-opacity))}.focus\:bg-orange-900:focus{--bg-opacity:1;background-color:#7b341e;background-color:rgba(123,52,30,var(--bg-opacity))}.focus\:bg-yellow-100:focus{--bg-opacity:1;background-color:ivory;background-color:rgba(255,255,240,var(--bg-opacity))}.focus\:bg-yellow-200:focus{--bg-opacity:1;background-color:#fefcbf;background-color:rgba(254,252,191,var(--bg-opacity))}.focus\:bg-yellow-300:focus{--bg-opacity:1;background-color:#faf089;background-color:rgba(250,240,137,var(--bg-opacity))}.focus\:bg-yellow-400:focus{--bg-opacity:1;background-color:#f6e05e;background-color:rgba(246,224,94,var(--bg-opacity))}.focus\:bg-yellow-500:focus{--bg-opacity:1;background-color:#ecc94b;background-color:rgba(236,201,75,var(--bg-opacity))}.focus\:bg-yellow-600:focus{--bg-opacity:1;background-color:#d69e2e;background-color:rgba(214,158,46,var(--bg-opacity))}.focus\:bg-yellow-700:focus{--bg-opacity:1;background-color:#b7791f;background-color:rgba(183,121,31,var(--bg-opacity))}.focus\:bg-yellow-800:focus{--bg-opacity:1;background-color:#975a16;background-color:rgba(151,90,22,var(--bg-opacity))}.focus\:bg-yellow-900:focus{--bg-opacity:1;background-color:#744210;background-color:rgba(116,66,16,var(--bg-opacity))}.focus\:bg-green-100:focus{--bg-opacity:1;background-color:#f0fff4;background-color:rgba(240,255,244,var(--bg-opacity))}.focus\:bg-green-200:focus{--bg-opacity:1;background-color:#c6f6d5;background-color:rgba(198,246,213,var(--bg-opacity))}.focus\:bg-green-300:focus{--bg-opacity:1;background-color:#9ae6b4;background-color:rgba(154,230,180,var(--bg-opacity))}.focus\:bg-green-400:focus{--bg-opacity:1;background-color:#68d391;background-color:rgba(104,211,145,var(--bg-opacity))}.focus\:bg-green-500:focus{--bg-opacity:1;background-color:#48bb78;background-color:rgba(72,187,120,var(--bg-opacity))}.focus\:bg-green-600:focus{--bg-opacity:1;background-color:#38a169;background-color:rgba(56,161,105,var(--bg-opacity))}.focus\:bg-green-700:focus{--bg-opacity:1;background-color:#2f855a;background-color:rgba(47,133,90,var(--bg-opacity))}.focus\:bg-green-800:focus{--bg-opacity:1;background-color:#276749;background-color:rgba(39,103,73,var(--bg-opacity))}.focus\:bg-green-900:focus{--bg-opacity:1;background-color:#22543d;background-color:rgba(34,84,61,var(--bg-opacity))}.focus\:bg-teal-100:focus{--bg-opacity:1;background-color:#e6fffa;background-color:rgba(230,255,250,var(--bg-opacity))}.focus\:bg-teal-200:focus{--bg-opacity:1;background-color:#b2f5ea;background-color:rgba(178,245,234,var(--bg-opacity))}.focus\:bg-teal-300:focus{--bg-opacity:1;background-color:#81e6d9;background-color:rgba(129,230,217,var(--bg-opacity))}.focus\:bg-teal-400:focus{--bg-opacity:1;background-color:#4fd1c5;background-color:rgba(79,209,197,var(--bg-opacity))}.focus\:bg-teal-500:focus{--bg-opacity:1;background-color:#38b2ac;background-color:rgba(56,178,172,var(--bg-opacity))}.focus\:bg-teal-600:focus{--bg-opacity:1;background-color:#319795;background-color:rgba(49,151,149,var(--bg-opacity))}.focus\:bg-teal-700:focus{--bg-opacity:1;background-color:#2c7a7b;background-color:rgba(44,122,123,var(--bg-opacity))}.focus\:bg-teal-800:focus{--bg-opacity:1;background-color:#285e61;background-color:rgba(40,94,97,var(--bg-opacity))}.focus\:bg-teal-900:focus{--bg-opacity:1;background-color:#234e52;background-color:rgba(35,78,82,var(--bg-opacity))}.focus\:bg-blue-100:focus{--bg-opacity:1;background-color:#ebf8ff;background-color:rgba(235,248,255,var(--bg-opacity))}.focus\:bg-blue-200:focus{--bg-opacity:1;background-color:#bee3f8;background-color:rgba(190,227,248,var(--bg-opacity))}.focus\:bg-blue-300:focus{--bg-opacity:1;background-color:#90cdf4;background-color:rgba(144,205,244,var(--bg-opacity))}.focus\:bg-blue-400:focus{--bg-opacity:1;background-color:#63b3ed;background-color:rgba(99,179,237,var(--bg-opacity))}.focus\:bg-blue-500:focus{--bg-opacity:1;background-color:#4299e1;background-color:rgba(66,153,225,var(--bg-opacity))}.focus\:bg-blue-600:focus{--bg-opacity:1;background-color:#3182ce;background-color:rgba(49,130,206,var(--bg-opacity))}.focus\:bg-blue-700:focus{--bg-opacity:1;background-color:#2b6cb0;background-color:rgba(43,108,176,var(--bg-opacity))}.focus\:bg-blue-800:focus{--bg-opacity:1;background-color:#2c5282;background-color:rgba(44,82,130,var(--bg-opacity))}.focus\:bg-blue-900:focus{--bg-opacity:1;background-color:#2a4365;background-color:rgba(42,67,101,var(--bg-opacity))}.focus\:bg-indigo-100:focus{--bg-opacity:1;background-color:#ebf4ff;background-color:rgba(235,244,255,var(--bg-opacity))}.focus\:bg-indigo-200:focus{--bg-opacity:1;background-color:#c3dafe;background-color:rgba(195,218,254,var(--bg-opacity))}.focus\:bg-indigo-300:focus{--bg-opacity:1;background-color:#a3bffa;background-color:rgba(163,191,250,var(--bg-opacity))}.focus\:bg-indigo-400:focus{--bg-opacity:1;background-color:#7f9cf5;background-color:rgba(127,156,245,var(--bg-opacity))}.focus\:bg-indigo-500:focus{--bg-opacity:1;background-color:#667eea;background-color:rgba(102,126,234,var(--bg-opacity))}.focus\:bg-indigo-600:focus{--bg-opacity:1;background-color:#5a67d8;background-color:rgba(90,103,216,var(--bg-opacity))}.focus\:bg-indigo-700:focus{--bg-opacity:1;background-color:#4c51bf;background-color:rgba(76,81,191,var(--bg-opacity))}.focus\:bg-indigo-800:focus{--bg-opacity:1;background-color:#434190;background-color:rgba(67,65,144,var(--bg-opacity))}.focus\:bg-indigo-900:focus{--bg-opacity:1;background-color:#3c366b;background-color:rgba(60,54,107,var(--bg-opacity))}.focus\:bg-purple-100:focus{--bg-opacity:1;background-color:#faf5ff;background-color:rgba(250,245,255,var(--bg-opacity))}.focus\:bg-purple-200:focus{--bg-opacity:1;background-color:#e9d8fd;background-color:rgba(233,216,253,var(--bg-opacity))}.focus\:bg-purple-300:focus{--bg-opacity:1;background-color:#d6bcfa;background-color:rgba(214,188,250,var(--bg-opacity))}.focus\:bg-purple-400:focus{--bg-opacity:1;background-color:#b794f4;background-color:rgba(183,148,244,var(--bg-opacity))}.focus\:bg-purple-500:focus{--bg-opacity:1;background-color:#9f7aea;background-color:rgba(159,122,234,var(--bg-opacity))}.focus\:bg-purple-600:focus{--bg-opacity:1;background-color:#805ad5;background-color:rgba(128,90,213,var(--bg-opacity))}.focus\:bg-purple-700:focus{--bg-opacity:1;background-color:#6b46c1;background-color:rgba(107,70,193,var(--bg-opacity))}.focus\:bg-purple-800:focus{--bg-opacity:1;background-color:#553c9a;background-color:rgba(85,60,154,var(--bg-opacity))}.focus\:bg-purple-900:focus{--bg-opacity:1;background-color:#44337a;background-color:rgba(68,51,122,var(--bg-opacity))}.focus\:bg-pink-100:focus{--bg-opacity:1;background-color:#fff5f7;background-color:rgba(255,245,247,var(--bg-opacity))}.focus\:bg-pink-200:focus{--bg-opacity:1;background-color:#fed7e2;background-color:rgba(254,215,226,var(--bg-opacity))}.focus\:bg-pink-300:focus{--bg-opacity:1;background-color:#fbb6ce;background-color:rgba(251,182,206,var(--bg-opacity))}.focus\:bg-pink-400:focus{--bg-opacity:1;background-color:#f687b3;background-color:rgba(246,135,179,var(--bg-opacity))}.focus\:bg-pink-500:focus{--bg-opacity:1;background-color:#ed64a6;background-color:rgba(237,100,166,var(--bg-opacity))}.focus\:bg-pink-600:focus{--bg-opacity:1;background-color:#d53f8c;background-color:rgba(213,63,140,var(--bg-opacity))}.focus\:bg-pink-700:focus{--bg-opacity:1;background-color:#b83280;background-color:rgba(184,50,128,var(--bg-opacity))}.focus\:bg-pink-800:focus{--bg-opacity:1;background-color:#97266d;background-color:rgba(151,38,109,var(--bg-opacity))}.focus\:bg-pink-900:focus{--bg-opacity:1;background-color:#702459;background-color:rgba(112,36,89,var(--bg-opacity))}.bg-none{background-image:none}.bg-gradient-to-t{background-image:linear-gradient(to top,var(--gradient-color-stops))}.bg-gradient-to-tr{background-image:linear-gradient(to top right,var(--gradient-color-stops))}.bg-gradient-to-r{background-image:linear-gradient(to right,var(--gradient-color-stops))}.bg-gradient-to-br{background-image:linear-gradient(to bottom right,var(--gradient-color-stops))}.bg-gradient-to-b{background-image:linear-gradient(to bottom,var(--gradient-color-stops))}.bg-gradient-to-bl{background-image:linear-gradient(to bottom left,var(--gradient-color-stops))}.bg-gradient-to-l{background-image:linear-gradient(to left,var(--gradient-color-stops))}.bg-gradient-to-tl{background-image:linear-gradient(to top left,var(--gradient-color-stops))}.from-transparent{--gradient-from-color:transparent;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(0, 0, 0, 0))}.from-current{--gradient-from-color:currentColor;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 255, 255, 0))}.from-black{--gradient-from-color:#000;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(0, 0, 0, 0))}.from-white{--gradient-from-color:#fff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 255, 255, 0))}.from-gray-100{--gradient-from-color:#f7fafc;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(247, 250, 252, 0))}.from-gray-200{--gradient-from-color:#edf2f7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(237, 242, 247, 0))}.from-gray-300{--gradient-from-color:#e2e8f0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(226, 232, 240, 0))}.from-gray-400{--gradient-from-color:#cbd5e0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(203, 213, 224, 0))}.from-gray-500{--gradient-from-color:#a0aec0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(160, 174, 192, 0))}.from-gray-600{--gradient-from-color:#718096;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(113, 128, 150, 0))}.from-gray-700{--gradient-from-color:#4a5568;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(74, 85, 104, 0))}.from-gray-800{--gradient-from-color:#2d3748;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(45, 55, 72, 0))}.from-gray-900{--gradient-from-color:#1a202c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(26, 32, 44, 0))}.from-red-100{--gradient-from-color:#fff5f5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 245, 245, 0))}.from-red-200{--gradient-from-color:#fed7d7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(254, 215, 215, 0))}.from-red-300{--gradient-from-color:#feb2b2;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(254, 178, 178, 0))}.from-red-400{--gradient-from-color:#fc8181;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(252, 129, 129, 0))}.from-red-500{--gradient-from-color:#f56565;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(245, 101, 101, 0))}.from-red-600{--gradient-from-color:#e53e3e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(229, 62, 62, 0))}.from-red-700{--gradient-from-color:#c53030;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(197, 48, 48, 0))}.from-red-800{--gradient-from-color:#9b2c2c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(155, 44, 44, 0))}.from-red-900{--gradient-from-color:#742a2a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(116, 42, 42, 0))}.from-orange-100{--gradient-from-color:#fffaf0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 250, 240, 0))}.from-orange-200{--gradient-from-color:#feebc8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(254, 235, 200, 0))}.from-orange-300{--gradient-from-color:#fbd38d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(251, 211, 141, 0))}.from-orange-400{--gradient-from-color:#f6ad55;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(246, 173, 85, 0))}.from-orange-500{--gradient-from-color:#ed8936;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(237, 137, 54, 0))}.from-orange-600{--gradient-from-color:#dd6b20;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(221, 107, 32, 0))}.from-orange-700{--gradient-from-color:#c05621;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(192, 86, 33, 0))}.from-orange-800{--gradient-from-color:#9c4221;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(156, 66, 33, 0))}.from-orange-900{--gradient-from-color:#7b341e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(123, 52, 30, 0))}.from-yellow-100{--gradient-from-color:#fffff0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 255, 240, 0))}.from-yellow-200{--gradient-from-color:#fefcbf;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(254, 252, 191, 0))}.from-yellow-300{--gradient-from-color:#faf089;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(250, 240, 137, 0))}.from-yellow-400{--gradient-from-color:#f6e05e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(246, 224, 94, 0))}.from-yellow-500{--gradient-from-color:#ecc94b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(236, 201, 75, 0))}.from-yellow-600{--gradient-from-color:#d69e2e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(214, 158, 46, 0))}.from-yellow-700{--gradient-from-color:#b7791f;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(183, 121, 31, 0))}.from-yellow-800{--gradient-from-color:#975a16;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(151, 90, 22, 0))}.from-yellow-900{--gradient-from-color:#744210;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(116, 66, 16, 0))}.from-green-100{--gradient-from-color:#f0fff4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(240, 255, 244, 0))}.from-green-200{--gradient-from-color:#c6f6d5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(198, 246, 213, 0))}.from-green-300{--gradient-from-color:#9ae6b4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(154, 230, 180, 0))}.from-green-400{--gradient-from-color:#68d391;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(104, 211, 145, 0))}.from-green-500{--gradient-from-color:#48bb78;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(72, 187, 120, 0))}.from-green-600{--gradient-from-color:#38a169;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(56, 161, 105, 0))}.from-green-700{--gradient-from-color:#2f855a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(47, 133, 90, 0))}.from-green-800{--gradient-from-color:#276749;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(39, 103, 73, 0))}.from-green-900{--gradient-from-color:#22543d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(34, 84, 61, 0))}.from-teal-100{--gradient-from-color:#e6fffa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(230, 255, 250, 0))}.from-teal-200{--gradient-from-color:#b2f5ea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(178, 245, 234, 0))}.from-teal-300{--gradient-from-color:#81e6d9;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(129, 230, 217, 0))}.from-teal-400{--gradient-from-color:#4fd1c5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(79, 209, 197, 0))}.from-teal-500{--gradient-from-color:#38b2ac;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(56, 178, 172, 0))}.from-teal-600{--gradient-from-color:#319795;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(49, 151, 149, 0))}.from-teal-700{--gradient-from-color:#2c7a7b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(44, 122, 123, 0))}.from-teal-800{--gradient-from-color:#285e61;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(40, 94, 97, 0))}.from-teal-900{--gradient-from-color:#234e52;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(35, 78, 82, 0))}.from-blue-100{--gradient-from-color:#ebf8ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(235, 248, 255, 0))}.from-blue-200{--gradient-from-color:#bee3f8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(190, 227, 248, 0))}.from-blue-300{--gradient-from-color:#90cdf4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(144, 205, 244, 0))}.from-blue-400{--gradient-from-color:#63b3ed;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(99, 179, 237, 0))}.from-blue-500{--gradient-from-color:#4299e1;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(66, 153, 225, 0))}.from-blue-600{--gradient-from-color:#3182ce;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(49, 130, 206, 0))}.from-blue-700{--gradient-from-color:#2b6cb0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(43, 108, 176, 0))}.from-blue-800{--gradient-from-color:#2c5282;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(44, 82, 130, 0))}.from-blue-900{--gradient-from-color:#2a4365;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(42, 67, 101, 0))}.from-indigo-100{--gradient-from-color:#ebf4ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(235, 244, 255, 0))}.from-indigo-200{--gradient-from-color:#c3dafe;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(195, 218, 254, 0))}.from-indigo-300{--gradient-from-color:#a3bffa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(163, 191, 250, 0))}.from-indigo-400{--gradient-from-color:#7f9cf5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(127, 156, 245, 0))}.from-indigo-500{--gradient-from-color:#667eea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(102, 126, 234, 0))}.from-indigo-600{--gradient-from-color:#5a67d8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(90, 103, 216, 0))}.from-indigo-700{--gradient-from-color:#4c51bf;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(76, 81, 191, 0))}.from-indigo-800{--gradient-from-color:#434190;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(67, 65, 144, 0))}.from-indigo-900{--gradient-from-color:#3c366b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(60, 54, 107, 0))}.from-purple-100{--gradient-from-color:#faf5ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(250, 245, 255, 0))}.from-purple-200{--gradient-from-color:#e9d8fd;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(233, 216, 253, 0))}.from-purple-300{--gradient-from-color:#d6bcfa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(214, 188, 250, 0))}.from-purple-400{--gradient-from-color:#b794f4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(183, 148, 244, 0))}.from-purple-500{--gradient-from-color:#9f7aea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(159, 122, 234, 0))}.from-purple-600{--gradient-from-color:#805ad5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(128, 90, 213, 0))}.from-purple-700{--gradient-from-color:#6b46c1;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(107, 70, 193, 0))}.from-purple-800{--gradient-from-color:#553c9a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(85, 60, 154, 0))}.from-purple-900{--gradient-from-color:#44337a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(68, 51, 122, 0))}.from-pink-100{--gradient-from-color:#fff5f7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 245, 247, 0))}.from-pink-200{--gradient-from-color:#fed7e2;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(254, 215, 226, 0))}.from-pink-300{--gradient-from-color:#fbb6ce;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(251, 182, 206, 0))}.from-pink-400{--gradient-from-color:#f687b3;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(246, 135, 179, 0))}.from-pink-500{--gradient-from-color:#ed64a6;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(237, 100, 166, 0))}.from-pink-600{--gradient-from-color:#d53f8c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(213, 63, 140, 0))}.from-pink-700{--gradient-from-color:#b83280;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(184, 50, 128, 0))}.from-pink-800{--gradient-from-color:#97266d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(151, 38, 109, 0))}.from-pink-900{--gradient-from-color:#702459;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(112, 36, 89, 0))}.via-transparent{--gradient-via-color:transparent;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(0, 0, 0, 0))}.via-current{--gradient-via-color:currentColor;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 255, 255, 0))}.via-black{--gradient-via-color:#000;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(0, 0, 0, 0))}.via-white{--gradient-via-color:#fff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 255, 255, 0))}.via-gray-100{--gradient-via-color:#f7fafc;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(247, 250, 252, 0))}.via-gray-200{--gradient-via-color:#edf2f7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(237, 242, 247, 0))}.via-gray-300{--gradient-via-color:#e2e8f0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(226, 232, 240, 0))}.via-gray-400{--gradient-via-color:#cbd5e0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(203, 213, 224, 0))}.via-gray-500{--gradient-via-color:#a0aec0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(160, 174, 192, 0))}.via-gray-600{--gradient-via-color:#718096;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(113, 128, 150, 0))}.via-gray-700{--gradient-via-color:#4a5568;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(74, 85, 104, 0))}.via-gray-800{--gradient-via-color:#2d3748;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(45, 55, 72, 0))}.via-gray-900{--gradient-via-color:#1a202c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(26, 32, 44, 0))}.via-red-100{--gradient-via-color:#fff5f5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 245, 245, 0))}.via-red-200{--gradient-via-color:#fed7d7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(254, 215, 215, 0))}.via-red-300{--gradient-via-color:#feb2b2;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(254, 178, 178, 0))}.via-red-400{--gradient-via-color:#fc8181;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(252, 129, 129, 0))}.via-red-500{--gradient-via-color:#f56565;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(245, 101, 101, 0))}.via-red-600{--gradient-via-color:#e53e3e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(229, 62, 62, 0))}.via-red-700{--gradient-via-color:#c53030;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(197, 48, 48, 0))}.via-red-800{--gradient-via-color:#9b2c2c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(155, 44, 44, 0))}.via-red-900{--gradient-via-color:#742a2a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(116, 42, 42, 0))}.via-orange-100{--gradient-via-color:#fffaf0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 250, 240, 0))}.via-orange-200{--gradient-via-color:#feebc8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(254, 235, 200, 0))}.via-orange-300{--gradient-via-color:#fbd38d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(251, 211, 141, 0))}.via-orange-400{--gradient-via-color:#f6ad55;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(246, 173, 85, 0))}.via-orange-500{--gradient-via-color:#ed8936;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(237, 137, 54, 0))}.via-orange-600{--gradient-via-color:#dd6b20;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(221, 107, 32, 0))}.via-orange-700{--gradient-via-color:#c05621;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(192, 86, 33, 0))}.via-orange-800{--gradient-via-color:#9c4221;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(156, 66, 33, 0))}.via-orange-900{--gradient-via-color:#7b341e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(123, 52, 30, 0))}.via-yellow-100{--gradient-via-color:#fffff0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 255, 240, 0))}.via-yellow-200{--gradient-via-color:#fefcbf;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(254, 252, 191, 0))}.via-yellow-300{--gradient-via-color:#faf089;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(250, 240, 137, 0))}.via-yellow-400{--gradient-via-color:#f6e05e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(246, 224, 94, 0))}.via-yellow-500{--gradient-via-color:#ecc94b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(236, 201, 75, 0))}.via-yellow-600{--gradient-via-color:#d69e2e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(214, 158, 46, 0))}.via-yellow-700{--gradient-via-color:#b7791f;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(183, 121, 31, 0))}.via-yellow-800{--gradient-via-color:#975a16;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(151, 90, 22, 0))}.via-yellow-900{--gradient-via-color:#744210;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(116, 66, 16, 0))}.via-green-100{--gradient-via-color:#f0fff4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(240, 255, 244, 0))}.via-green-200{--gradient-via-color:#c6f6d5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(198, 246, 213, 0))}.via-green-300{--gradient-via-color:#9ae6b4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(154, 230, 180, 0))}.via-green-400{--gradient-via-color:#68d391;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(104, 211, 145, 0))}.via-green-500{--gradient-via-color:#48bb78;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(72, 187, 120, 0))}.via-green-600{--gradient-via-color:#38a169;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(56, 161, 105, 0))}.via-green-700{--gradient-via-color:#2f855a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(47, 133, 90, 0))}.via-green-800{--gradient-via-color:#276749;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(39, 103, 73, 0))}.via-green-900{--gradient-via-color:#22543d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(34, 84, 61, 0))}.via-teal-100{--gradient-via-color:#e6fffa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(230, 255, 250, 0))}.via-teal-200{--gradient-via-color:#b2f5ea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(178, 245, 234, 0))}.via-teal-300{--gradient-via-color:#81e6d9;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(129, 230, 217, 0))}.via-teal-400{--gradient-via-color:#4fd1c5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(79, 209, 197, 0))}.via-teal-500{--gradient-via-color:#38b2ac;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(56, 178, 172, 0))}.via-teal-600{--gradient-via-color:#319795;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(49, 151, 149, 0))}.via-teal-700{--gradient-via-color:#2c7a7b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(44, 122, 123, 0))}.via-teal-800{--gradient-via-color:#285e61;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(40, 94, 97, 0))}.via-teal-900{--gradient-via-color:#234e52;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(35, 78, 82, 0))}.via-blue-100{--gradient-via-color:#ebf8ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(235, 248, 255, 0))}.via-blue-200{--gradient-via-color:#bee3f8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(190, 227, 248, 0))}.via-blue-300{--gradient-via-color:#90cdf4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(144, 205, 244, 0))}.via-blue-400{--gradient-via-color:#63b3ed;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(99, 179, 237, 0))}.via-blue-500{--gradient-via-color:#4299e1;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(66, 153, 225, 0))}.via-blue-600{--gradient-via-color:#3182ce;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(49, 130, 206, 0))}.via-blue-700{--gradient-via-color:#2b6cb0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(43, 108, 176, 0))}.via-blue-800{--gradient-via-color:#2c5282;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(44, 82, 130, 0))}.via-blue-900{--gradient-via-color:#2a4365;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(42, 67, 101, 0))}.via-indigo-100{--gradient-via-color:#ebf4ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(235, 244, 255, 0))}.via-indigo-200{--gradient-via-color:#c3dafe;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(195, 218, 254, 0))}.via-indigo-300{--gradient-via-color:#a3bffa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(163, 191, 250, 0))}.via-indigo-400{--gradient-via-color:#7f9cf5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(127, 156, 245, 0))}.via-indigo-500{--gradient-via-color:#667eea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(102, 126, 234, 0))}.via-indigo-600{--gradient-via-color:#5a67d8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(90, 103, 216, 0))}.via-indigo-700{--gradient-via-color:#4c51bf;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(76, 81, 191, 0))}.via-indigo-800{--gradient-via-color:#434190;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(67, 65, 144, 0))}.via-indigo-900{--gradient-via-color:#3c366b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(60, 54, 107, 0))}.via-purple-100{--gradient-via-color:#faf5ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(250, 245, 255, 0))}.via-purple-200{--gradient-via-color:#e9d8fd;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(233, 216, 253, 0))}.via-purple-300{--gradient-via-color:#d6bcfa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(214, 188, 250, 0))}.via-purple-400{--gradient-via-color:#b794f4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(183, 148, 244, 0))}.via-purple-500{--gradient-via-color:#9f7aea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(159, 122, 234, 0))}.via-purple-600{--gradient-via-color:#805ad5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(128, 90, 213, 0))}.via-purple-700{--gradient-via-color:#6b46c1;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(107, 70, 193, 0))}.via-purple-800{--gradient-via-color:#553c9a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(85, 60, 154, 0))}.via-purple-900{--gradient-via-color:#44337a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(68, 51, 122, 0))}.via-pink-100{--gradient-via-color:#fff5f7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 245, 247, 0))}.via-pink-200{--gradient-via-color:#fed7e2;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(254, 215, 226, 0))}.via-pink-300{--gradient-via-color:#fbb6ce;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(251, 182, 206, 0))}.via-pink-400{--gradient-via-color:#f687b3;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(246, 135, 179, 0))}.via-pink-500{--gradient-via-color:#ed64a6;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(237, 100, 166, 0))}.via-pink-600{--gradient-via-color:#d53f8c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(213, 63, 140, 0))}.via-pink-700{--gradient-via-color:#b83280;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(184, 50, 128, 0))}.via-pink-800{--gradient-via-color:#97266d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(151, 38, 109, 0))}.via-pink-900{--gradient-via-color:#702459;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(112, 36, 89, 0))}.to-transparent{--gradient-to-color:transparent}.to-current{--gradient-to-color:currentColor}.to-black{--gradient-to-color:#000}.to-white{--gradient-to-color:#fff}.to-gray-100{--gradient-to-color:#f7fafc}.to-gray-200{--gradient-to-color:#edf2f7}.to-gray-300{--gradient-to-color:#e2e8f0}.to-gray-400{--gradient-to-color:#cbd5e0}.to-gray-500{--gradient-to-color:#a0aec0}.to-gray-600{--gradient-to-color:#718096}.to-gray-700{--gradient-to-color:#4a5568}.to-gray-800{--gradient-to-color:#2d3748}.to-gray-900{--gradient-to-color:#1a202c}.to-red-100{--gradient-to-color:#fff5f5}.to-red-200{--gradient-to-color:#fed7d7}.to-red-300{--gradient-to-color:#feb2b2}.to-red-400{--gradient-to-color:#fc8181}.to-red-500{--gradient-to-color:#f56565}.to-red-600{--gradient-to-color:#e53e3e}.to-red-700{--gradient-to-color:#c53030}.to-red-800{--gradient-to-color:#9b2c2c}.to-red-900{--gradient-to-color:#742a2a}.to-orange-100{--gradient-to-color:#fffaf0}.to-orange-200{--gradient-to-color:#feebc8}.to-orange-300{--gradient-to-color:#fbd38d}.to-orange-400{--gradient-to-color:#f6ad55}.to-orange-500{--gradient-to-color:#ed8936}.to-orange-600{--gradient-to-color:#dd6b20}.to-orange-700{--gradient-to-color:#c05621}.to-orange-800{--gradient-to-color:#9c4221}.to-orange-900{--gradient-to-color:#7b341e}.to-yellow-100{--gradient-to-color:#fffff0}.to-yellow-200{--gradient-to-color:#fefcbf}.to-yellow-300{--gradient-to-color:#faf089}.to-yellow-400{--gradient-to-color:#f6e05e}.to-yellow-500{--gradient-to-color:#ecc94b}.to-yellow-600{--gradient-to-color:#d69e2e}.to-yellow-700{--gradient-to-color:#b7791f}.to-yellow-800{--gradient-to-color:#975a16}.to-yellow-900{--gradient-to-color:#744210}.to-green-100{--gradient-to-color:#f0fff4}.to-green-200{--gradient-to-color:#c6f6d5}.to-green-300{--gradient-to-color:#9ae6b4}.to-green-400{--gradient-to-color:#68d391}.to-green-500{--gradient-to-color:#48bb78}.to-green-600{--gradient-to-color:#38a169}.to-green-700{--gradient-to-color:#2f855a}.to-green-800{--gradient-to-color:#276749}.to-green-900{--gradient-to-color:#22543d}.to-teal-100{--gradient-to-color:#e6fffa}.to-teal-200{--gradient-to-color:#b2f5ea}.to-teal-300{--gradient-to-color:#81e6d9}.to-teal-400{--gradient-to-color:#4fd1c5}.to-teal-500{--gradient-to-color:#38b2ac}.to-teal-600{--gradient-to-color:#319795}.to-teal-700{--gradient-to-color:#2c7a7b}.to-teal-800{--gradient-to-color:#285e61}.to-teal-900{--gradient-to-color:#234e52}.to-blue-100{--gradient-to-color:#ebf8ff}.to-blue-200{--gradient-to-color:#bee3f8}.to-blue-300{--gradient-to-color:#90cdf4}.to-blue-400{--gradient-to-color:#63b3ed}.to-blue-500{--gradient-to-color:#4299e1}.to-blue-600{--gradient-to-color:#3182ce}.to-blue-700{--gradient-to-color:#2b6cb0}.to-blue-800{--gradient-to-color:#2c5282}.to-blue-900{--gradient-to-color:#2a4365}.to-indigo-100{--gradient-to-color:#ebf4ff}.to-indigo-200{--gradient-to-color:#c3dafe}.to-indigo-300{--gradient-to-color:#a3bffa}.to-indigo-400{--gradient-to-color:#7f9cf5}.to-indigo-500{--gradient-to-color:#667eea}.to-indigo-600{--gradient-to-color:#5a67d8}.to-indigo-700{--gradient-to-color:#4c51bf}.to-indigo-800{--gradient-to-color:#434190}.to-indigo-900{--gradient-to-color:#3c366b}.to-purple-100{--gradient-to-color:#faf5ff}.to-purple-200{--gradient-to-color:#e9d8fd}.to-purple-300{--gradient-to-color:#d6bcfa}.to-purple-400{--gradient-to-color:#b794f4}.to-purple-500{--gradient-to-color:#9f7aea}.to-purple-600{--gradient-to-color:#805ad5}.to-purple-700{--gradient-to-color:#6b46c1}.to-purple-800{--gradient-to-color:#553c9a}.to-purple-900{--gradient-to-color:#44337a}.to-pink-100{--gradient-to-color:#fff5f7}.to-pink-200{--gradient-to-color:#fed7e2}.to-pink-300{--gradient-to-color:#fbb6ce}.to-pink-400{--gradient-to-color:#f687b3}.to-pink-500{--gradient-to-color:#ed64a6}.to-pink-600{--gradient-to-color:#d53f8c}.to-pink-700{--gradient-to-color:#b83280}.to-pink-800{--gradient-to-color:#97266d}.to-pink-900{--gradient-to-color:#702459}.hover\:from-transparent:hover{--gradient-from-color:transparent;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(0, 0, 0, 0))}.hover\:from-current:hover{--gradient-from-color:currentColor;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 255, 255, 0))}.hover\:from-black:hover{--gradient-from-color:#000;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(0, 0, 0, 0))}.hover\:from-white:hover{--gradient-from-color:#fff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 255, 255, 0))}.hover\:from-gray-100:hover{--gradient-from-color:#f7fafc;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(247, 250, 252, 0))}.hover\:from-gray-200:hover{--gradient-from-color:#edf2f7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(237, 242, 247, 0))}.hover\:from-gray-300:hover{--gradient-from-color:#e2e8f0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(226, 232, 240, 0))}.hover\:from-gray-400:hover{--gradient-from-color:#cbd5e0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(203, 213, 224, 0))}.hover\:from-gray-500:hover{--gradient-from-color:#a0aec0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(160, 174, 192, 0))}.hover\:from-gray-600:hover{--gradient-from-color:#718096;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(113, 128, 150, 0))}.hover\:from-gray-700:hover{--gradient-from-color:#4a5568;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(74, 85, 104, 0))}.hover\:from-gray-800:hover{--gradient-from-color:#2d3748;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(45, 55, 72, 0))}.hover\:from-gray-900:hover{--gradient-from-color:#1a202c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(26, 32, 44, 0))}.hover\:from-red-100:hover{--gradient-from-color:#fff5f5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 245, 245, 0))}.hover\:from-red-200:hover{--gradient-from-color:#fed7d7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(254, 215, 215, 0))}.hover\:from-red-300:hover{--gradient-from-color:#feb2b2;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(254, 178, 178, 0))}.hover\:from-red-400:hover{--gradient-from-color:#fc8181;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(252, 129, 129, 0))}.hover\:from-red-500:hover{--gradient-from-color:#f56565;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(245, 101, 101, 0))}.hover\:from-red-600:hover{--gradient-from-color:#e53e3e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(229, 62, 62, 0))}.hover\:from-red-700:hover{--gradient-from-color:#c53030;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(197, 48, 48, 0))}.hover\:from-red-800:hover{--gradient-from-color:#9b2c2c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(155, 44, 44, 0))}.hover\:from-red-900:hover{--gradient-from-color:#742a2a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(116, 42, 42, 0))}.hover\:from-orange-100:hover{--gradient-from-color:#fffaf0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 250, 240, 0))}.hover\:from-orange-200:hover{--gradient-from-color:#feebc8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(254, 235, 200, 0))}.hover\:from-orange-300:hover{--gradient-from-color:#fbd38d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(251, 211, 141, 0))}.hover\:from-orange-400:hover{--gradient-from-color:#f6ad55;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(246, 173, 85, 0))}.hover\:from-orange-500:hover{--gradient-from-color:#ed8936;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(237, 137, 54, 0))}.hover\:from-orange-600:hover{--gradient-from-color:#dd6b20;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(221, 107, 32, 0))}.hover\:from-orange-700:hover{--gradient-from-color:#c05621;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(192, 86, 33, 0))}.hover\:from-orange-800:hover{--gradient-from-color:#9c4221;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(156, 66, 33, 0))}.hover\:from-orange-900:hover{--gradient-from-color:#7b341e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(123, 52, 30, 0))}.hover\:from-yellow-100:hover{--gradient-from-color:#fffff0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 255, 240, 0))}.hover\:from-yellow-200:hover{--gradient-from-color:#fefcbf;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(254, 252, 191, 0))}.hover\:from-yellow-300:hover{--gradient-from-color:#faf089;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(250, 240, 137, 0))}.hover\:from-yellow-400:hover{--gradient-from-color:#f6e05e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(246, 224, 94, 0))}.hover\:from-yellow-500:hover{--gradient-from-color:#ecc94b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(236, 201, 75, 0))}.hover\:from-yellow-600:hover{--gradient-from-color:#d69e2e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(214, 158, 46, 0))}.hover\:from-yellow-700:hover{--gradient-from-color:#b7791f;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(183, 121, 31, 0))}.hover\:from-yellow-800:hover{--gradient-from-color:#975a16;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(151, 90, 22, 0))}.hover\:from-yellow-900:hover{--gradient-from-color:#744210;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(116, 66, 16, 0))}.hover\:from-green-100:hover{--gradient-from-color:#f0fff4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(240, 255, 244, 0))}.hover\:from-green-200:hover{--gradient-from-color:#c6f6d5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(198, 246, 213, 0))}.hover\:from-green-300:hover{--gradient-from-color:#9ae6b4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(154, 230, 180, 0))}.hover\:from-green-400:hover{--gradient-from-color:#68d391;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(104, 211, 145, 0))}.hover\:from-green-500:hover{--gradient-from-color:#48bb78;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(72, 187, 120, 0))}.hover\:from-green-600:hover{--gradient-from-color:#38a169;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(56, 161, 105, 0))}.hover\:from-green-700:hover{--gradient-from-color:#2f855a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(47, 133, 90, 0))}.hover\:from-green-800:hover{--gradient-from-color:#276749;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(39, 103, 73, 0))}.hover\:from-green-900:hover{--gradient-from-color:#22543d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(34, 84, 61, 0))}.hover\:from-teal-100:hover{--gradient-from-color:#e6fffa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(230, 255, 250, 0))}.hover\:from-teal-200:hover{--gradient-from-color:#b2f5ea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(178, 245, 234, 0))}.hover\:from-teal-300:hover{--gradient-from-color:#81e6d9;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(129, 230, 217, 0))}.hover\:from-teal-400:hover{--gradient-from-color:#4fd1c5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(79, 209, 197, 0))}.hover\:from-teal-500:hover{--gradient-from-color:#38b2ac;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(56, 178, 172, 0))}.hover\:from-teal-600:hover{--gradient-from-color:#319795;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(49, 151, 149, 0))}.hover\:from-teal-700:hover{--gradient-from-color:#2c7a7b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(44, 122, 123, 0))}.hover\:from-teal-800:hover{--gradient-from-color:#285e61;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(40, 94, 97, 0))}.hover\:from-teal-900:hover{--gradient-from-color:#234e52;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(35, 78, 82, 0))}.hover\:from-blue-100:hover{--gradient-from-color:#ebf8ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(235, 248, 255, 0))}.hover\:from-blue-200:hover{--gradient-from-color:#bee3f8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(190, 227, 248, 0))}.hover\:from-blue-300:hover{--gradient-from-color:#90cdf4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(144, 205, 244, 0))}.hover\:from-blue-400:hover{--gradient-from-color:#63b3ed;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(99, 179, 237, 0))}.hover\:from-blue-500:hover{--gradient-from-color:#4299e1;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(66, 153, 225, 0))}.hover\:from-blue-600:hover{--gradient-from-color:#3182ce;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(49, 130, 206, 0))}.hover\:from-blue-700:hover{--gradient-from-color:#2b6cb0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(43, 108, 176, 0))}.hover\:from-blue-800:hover{--gradient-from-color:#2c5282;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(44, 82, 130, 0))}.hover\:from-blue-900:hover{--gradient-from-color:#2a4365;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(42, 67, 101, 0))}.hover\:from-indigo-100:hover{--gradient-from-color:#ebf4ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(235, 244, 255, 0))}.hover\:from-indigo-200:hover{--gradient-from-color:#c3dafe;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(195, 218, 254, 0))}.hover\:from-indigo-300:hover{--gradient-from-color:#a3bffa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(163, 191, 250, 0))}.hover\:from-indigo-400:hover{--gradient-from-color:#7f9cf5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(127, 156, 245, 0))}.hover\:from-indigo-500:hover{--gradient-from-color:#667eea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(102, 126, 234, 0))}.hover\:from-indigo-600:hover{--gradient-from-color:#5a67d8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(90, 103, 216, 0))}.hover\:from-indigo-700:hover{--gradient-from-color:#4c51bf;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(76, 81, 191, 0))}.hover\:from-indigo-800:hover{--gradient-from-color:#434190;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(67, 65, 144, 0))}.hover\:from-indigo-900:hover{--gradient-from-color:#3c366b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(60, 54, 107, 0))}.hover\:from-purple-100:hover{--gradient-from-color:#faf5ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(250, 245, 255, 0))}.hover\:from-purple-200:hover{--gradient-from-color:#e9d8fd;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(233, 216, 253, 0))}.hover\:from-purple-300:hover{--gradient-from-color:#d6bcfa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(214, 188, 250, 0))}.hover\:from-purple-400:hover{--gradient-from-color:#b794f4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(183, 148, 244, 0))}.hover\:from-purple-500:hover{--gradient-from-color:#9f7aea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(159, 122, 234, 0))}.hover\:from-purple-600:hover{--gradient-from-color:#805ad5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(128, 90, 213, 0))}.hover\:from-purple-700:hover{--gradient-from-color:#6b46c1;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(107, 70, 193, 0))}.hover\:from-purple-800:hover{--gradient-from-color:#553c9a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(85, 60, 154, 0))}.hover\:from-purple-900:hover{--gradient-from-color:#44337a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(68, 51, 122, 0))}.hover\:from-pink-100:hover{--gradient-from-color:#fff5f7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 245, 247, 0))}.hover\:from-pink-200:hover{--gradient-from-color:#fed7e2;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(254, 215, 226, 0))}.hover\:from-pink-300:hover{--gradient-from-color:#fbb6ce;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(251, 182, 206, 0))}.hover\:from-pink-400:hover{--gradient-from-color:#f687b3;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(246, 135, 179, 0))}.hover\:from-pink-500:hover{--gradient-from-color:#ed64a6;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(237, 100, 166, 0))}.hover\:from-pink-600:hover{--gradient-from-color:#d53f8c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(213, 63, 140, 0))}.hover\:from-pink-700:hover{--gradient-from-color:#b83280;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(184, 50, 128, 0))}.hover\:from-pink-800:hover{--gradient-from-color:#97266d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(151, 38, 109, 0))}.hover\:from-pink-900:hover{--gradient-from-color:#702459;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(112, 36, 89, 0))}.hover\:via-transparent:hover{--gradient-via-color:transparent;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(0, 0, 0, 0))}.hover\:via-current:hover{--gradient-via-color:currentColor;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 255, 255, 0))}.hover\:via-black:hover{--gradient-via-color:#000;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(0, 0, 0, 0))}.hover\:via-white:hover{--gradient-via-color:#fff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 255, 255, 0))}.hover\:via-gray-100:hover{--gradient-via-color:#f7fafc;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(247, 250, 252, 0))}.hover\:via-gray-200:hover{--gradient-via-color:#edf2f7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(237, 242, 247, 0))}.hover\:via-gray-300:hover{--gradient-via-color:#e2e8f0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(226, 232, 240, 0))}.hover\:via-gray-400:hover{--gradient-via-color:#cbd5e0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(203, 213, 224, 0))}.hover\:via-gray-500:hover{--gradient-via-color:#a0aec0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(160, 174, 192, 0))}.hover\:via-gray-600:hover{--gradient-via-color:#718096;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(113, 128, 150, 0))}.hover\:via-gray-700:hover{--gradient-via-color:#4a5568;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(74, 85, 104, 0))}.hover\:via-gray-800:hover{--gradient-via-color:#2d3748;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(45, 55, 72, 0))}.hover\:via-gray-900:hover{--gradient-via-color:#1a202c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(26, 32, 44, 0))}.hover\:via-red-100:hover{--gradient-via-color:#fff5f5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 245, 245, 0))}.hover\:via-red-200:hover{--gradient-via-color:#fed7d7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(254, 215, 215, 0))}.hover\:via-red-300:hover{--gradient-via-color:#feb2b2;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(254, 178, 178, 0))}.hover\:via-red-400:hover{--gradient-via-color:#fc8181;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(252, 129, 129, 0))}.hover\:via-red-500:hover{--gradient-via-color:#f56565;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(245, 101, 101, 0))}.hover\:via-red-600:hover{--gradient-via-color:#e53e3e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(229, 62, 62, 0))}.hover\:via-red-700:hover{--gradient-via-color:#c53030;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(197, 48, 48, 0))}.hover\:via-red-800:hover{--gradient-via-color:#9b2c2c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(155, 44, 44, 0))}.hover\:via-red-900:hover{--gradient-via-color:#742a2a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(116, 42, 42, 0))}.hover\:via-orange-100:hover{--gradient-via-color:#fffaf0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 250, 240, 0))}.hover\:via-orange-200:hover{--gradient-via-color:#feebc8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(254, 235, 200, 0))}.hover\:via-orange-300:hover{--gradient-via-color:#fbd38d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(251, 211, 141, 0))}.hover\:via-orange-400:hover{--gradient-via-color:#f6ad55;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(246, 173, 85, 0))}.hover\:via-orange-500:hover{--gradient-via-color:#ed8936;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(237, 137, 54, 0))}.hover\:via-orange-600:hover{--gradient-via-color:#dd6b20;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(221, 107, 32, 0))}.hover\:via-orange-700:hover{--gradient-via-color:#c05621;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(192, 86, 33, 0))}.hover\:via-orange-800:hover{--gradient-via-color:#9c4221;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(156, 66, 33, 0))}.hover\:via-orange-900:hover{--gradient-via-color:#7b341e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(123, 52, 30, 0))}.hover\:via-yellow-100:hover{--gradient-via-color:#fffff0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 255, 240, 0))}.hover\:via-yellow-200:hover{--gradient-via-color:#fefcbf;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(254, 252, 191, 0))}.hover\:via-yellow-300:hover{--gradient-via-color:#faf089;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(250, 240, 137, 0))}.hover\:via-yellow-400:hover{--gradient-via-color:#f6e05e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(246, 224, 94, 0))}.hover\:via-yellow-500:hover{--gradient-via-color:#ecc94b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(236, 201, 75, 0))}.hover\:via-yellow-600:hover{--gradient-via-color:#d69e2e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(214, 158, 46, 0))}.hover\:via-yellow-700:hover{--gradient-via-color:#b7791f;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(183, 121, 31, 0))}.hover\:via-yellow-800:hover{--gradient-via-color:#975a16;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(151, 90, 22, 0))}.hover\:via-yellow-900:hover{--gradient-via-color:#744210;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(116, 66, 16, 0))}.hover\:via-green-100:hover{--gradient-via-color:#f0fff4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(240, 255, 244, 0))}.hover\:via-green-200:hover{--gradient-via-color:#c6f6d5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(198, 246, 213, 0))}.hover\:via-green-300:hover{--gradient-via-color:#9ae6b4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(154, 230, 180, 0))}.hover\:via-green-400:hover{--gradient-via-color:#68d391;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(104, 211, 145, 0))}.hover\:via-green-500:hover{--gradient-via-color:#48bb78;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(72, 187, 120, 0))}.hover\:via-green-600:hover{--gradient-via-color:#38a169;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(56, 161, 105, 0))}.hover\:via-green-700:hover{--gradient-via-color:#2f855a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(47, 133, 90, 0))}.hover\:via-green-800:hover{--gradient-via-color:#276749;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(39, 103, 73, 0))}.hover\:via-green-900:hover{--gradient-via-color:#22543d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(34, 84, 61, 0))}.hover\:via-teal-100:hover{--gradient-via-color:#e6fffa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(230, 255, 250, 0))}.hover\:via-teal-200:hover{--gradient-via-color:#b2f5ea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(178, 245, 234, 0))}.hover\:via-teal-300:hover{--gradient-via-color:#81e6d9;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(129, 230, 217, 0))}.hover\:via-teal-400:hover{--gradient-via-color:#4fd1c5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(79, 209, 197, 0))}.hover\:via-teal-500:hover{--gradient-via-color:#38b2ac;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(56, 178, 172, 0))}.hover\:via-teal-600:hover{--gradient-via-color:#319795;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(49, 151, 149, 0))}.hover\:via-teal-700:hover{--gradient-via-color:#2c7a7b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(44, 122, 123, 0))}.hover\:via-teal-800:hover{--gradient-via-color:#285e61;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(40, 94, 97, 0))}.hover\:via-teal-900:hover{--gradient-via-color:#234e52;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(35, 78, 82, 0))}.hover\:via-blue-100:hover{--gradient-via-color:#ebf8ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(235, 248, 255, 0))}.hover\:via-blue-200:hover{--gradient-via-color:#bee3f8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(190, 227, 248, 0))}.hover\:via-blue-300:hover{--gradient-via-color:#90cdf4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(144, 205, 244, 0))}.hover\:via-blue-400:hover{--gradient-via-color:#63b3ed;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(99, 179, 237, 0))}.hover\:via-blue-500:hover{--gradient-via-color:#4299e1;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(66, 153, 225, 0))}.hover\:via-blue-600:hover{--gradient-via-color:#3182ce;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(49, 130, 206, 0))}.hover\:via-blue-700:hover{--gradient-via-color:#2b6cb0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(43, 108, 176, 0))}.hover\:via-blue-800:hover{--gradient-via-color:#2c5282;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(44, 82, 130, 0))}.hover\:via-blue-900:hover{--gradient-via-color:#2a4365;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(42, 67, 101, 0))}.hover\:via-indigo-100:hover{--gradient-via-color:#ebf4ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(235, 244, 255, 0))}.hover\:via-indigo-200:hover{--gradient-via-color:#c3dafe;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(195, 218, 254, 0))}.hover\:via-indigo-300:hover{--gradient-via-color:#a3bffa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(163, 191, 250, 0))}.hover\:via-indigo-400:hover{--gradient-via-color:#7f9cf5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(127, 156, 245, 0))}.hover\:via-indigo-500:hover{--gradient-via-color:#667eea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(102, 126, 234, 0))}.hover\:via-indigo-600:hover{--gradient-via-color:#5a67d8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(90, 103, 216, 0))}.hover\:via-indigo-700:hover{--gradient-via-color:#4c51bf;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(76, 81, 191, 0))}.hover\:via-indigo-800:hover{--gradient-via-color:#434190;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(67, 65, 144, 0))}.hover\:via-indigo-900:hover{--gradient-via-color:#3c366b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(60, 54, 107, 0))}.hover\:via-purple-100:hover{--gradient-via-color:#faf5ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(250, 245, 255, 0))}.hover\:via-purple-200:hover{--gradient-via-color:#e9d8fd;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(233, 216, 253, 0))}.hover\:via-purple-300:hover{--gradient-via-color:#d6bcfa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(214, 188, 250, 0))}.hover\:via-purple-400:hover{--gradient-via-color:#b794f4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(183, 148, 244, 0))}.hover\:via-purple-500:hover{--gradient-via-color:#9f7aea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(159, 122, 234, 0))}.hover\:via-purple-600:hover{--gradient-via-color:#805ad5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(128, 90, 213, 0))}.hover\:via-purple-700:hover{--gradient-via-color:#6b46c1;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(107, 70, 193, 0))}.hover\:via-purple-800:hover{--gradient-via-color:#553c9a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(85, 60, 154, 0))}.hover\:via-purple-900:hover{--gradient-via-color:#44337a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(68, 51, 122, 0))}.hover\:via-pink-100:hover{--gradient-via-color:#fff5f7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 245, 247, 0))}.hover\:via-pink-200:hover{--gradient-via-color:#fed7e2;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(254, 215, 226, 0))}.hover\:via-pink-300:hover{--gradient-via-color:#fbb6ce;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(251, 182, 206, 0))}.hover\:via-pink-400:hover{--gradient-via-color:#f687b3;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(246, 135, 179, 0))}.hover\:via-pink-500:hover{--gradient-via-color:#ed64a6;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(237, 100, 166, 0))}.hover\:via-pink-600:hover{--gradient-via-color:#d53f8c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(213, 63, 140, 0))}.hover\:via-pink-700:hover{--gradient-via-color:#b83280;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(184, 50, 128, 0))}.hover\:via-pink-800:hover{--gradient-via-color:#97266d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(151, 38, 109, 0))}.hover\:via-pink-900:hover{--gradient-via-color:#702459;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(112, 36, 89, 0))}.hover\:to-transparent:hover{--gradient-to-color:transparent}.hover\:to-current:hover{--gradient-to-color:currentColor}.hover\:to-black:hover{--gradient-to-color:#000}.hover\:to-white:hover{--gradient-to-color:#fff}.hover\:to-gray-100:hover{--gradient-to-color:#f7fafc}.hover\:to-gray-200:hover{--gradient-to-color:#edf2f7}.hover\:to-gray-300:hover{--gradient-to-color:#e2e8f0}.hover\:to-gray-400:hover{--gradient-to-color:#cbd5e0}.hover\:to-gray-500:hover{--gradient-to-color:#a0aec0}.hover\:to-gray-600:hover{--gradient-to-color:#718096}.hover\:to-gray-700:hover{--gradient-to-color:#4a5568}.hover\:to-gray-800:hover{--gradient-to-color:#2d3748}.hover\:to-gray-900:hover{--gradient-to-color:#1a202c}.hover\:to-red-100:hover{--gradient-to-color:#fff5f5}.hover\:to-red-200:hover{--gradient-to-color:#fed7d7}.hover\:to-red-300:hover{--gradient-to-color:#feb2b2}.hover\:to-red-400:hover{--gradient-to-color:#fc8181}.hover\:to-red-500:hover{--gradient-to-color:#f56565}.hover\:to-red-600:hover{--gradient-to-color:#e53e3e}.hover\:to-red-700:hover{--gradient-to-color:#c53030}.hover\:to-red-800:hover{--gradient-to-color:#9b2c2c}.hover\:to-red-900:hover{--gradient-to-color:#742a2a}.hover\:to-orange-100:hover{--gradient-to-color:#fffaf0}.hover\:to-orange-200:hover{--gradient-to-color:#feebc8}.hover\:to-orange-300:hover{--gradient-to-color:#fbd38d}.hover\:to-orange-400:hover{--gradient-to-color:#f6ad55}.hover\:to-orange-500:hover{--gradient-to-color:#ed8936}.hover\:to-orange-600:hover{--gradient-to-color:#dd6b20}.hover\:to-orange-700:hover{--gradient-to-color:#c05621}.hover\:to-orange-800:hover{--gradient-to-color:#9c4221}.hover\:to-orange-900:hover{--gradient-to-color:#7b341e}.hover\:to-yellow-100:hover{--gradient-to-color:#fffff0}.hover\:to-yellow-200:hover{--gradient-to-color:#fefcbf}.hover\:to-yellow-300:hover{--gradient-to-color:#faf089}.hover\:to-yellow-400:hover{--gradient-to-color:#f6e05e}.hover\:to-yellow-500:hover{--gradient-to-color:#ecc94b}.hover\:to-yellow-600:hover{--gradient-to-color:#d69e2e}.hover\:to-yellow-700:hover{--gradient-to-color:#b7791f}.hover\:to-yellow-800:hover{--gradient-to-color:#975a16}.hover\:to-yellow-900:hover{--gradient-to-color:#744210}.hover\:to-green-100:hover{--gradient-to-color:#f0fff4}.hover\:to-green-200:hover{--gradient-to-color:#c6f6d5}.hover\:to-green-300:hover{--gradient-to-color:#9ae6b4}.hover\:to-green-400:hover{--gradient-to-color:#68d391}.hover\:to-green-500:hover{--gradient-to-color:#48bb78}.hover\:to-green-600:hover{--gradient-to-color:#38a169}.hover\:to-green-700:hover{--gradient-to-color:#2f855a}.hover\:to-green-800:hover{--gradient-to-color:#276749}.hover\:to-green-900:hover{--gradient-to-color:#22543d}.hover\:to-teal-100:hover{--gradient-to-color:#e6fffa}.hover\:to-teal-200:hover{--gradient-to-color:#b2f5ea}.hover\:to-teal-300:hover{--gradient-to-color:#81e6d9}.hover\:to-teal-400:hover{--gradient-to-color:#4fd1c5}.hover\:to-teal-500:hover{--gradient-to-color:#38b2ac}.hover\:to-teal-600:hover{--gradient-to-color:#319795}.hover\:to-teal-700:hover{--gradient-to-color:#2c7a7b}.hover\:to-teal-800:hover{--gradient-to-color:#285e61}.hover\:to-teal-900:hover{--gradient-to-color:#234e52}.hover\:to-blue-100:hover{--gradient-to-color:#ebf8ff}.hover\:to-blue-200:hover{--gradient-to-color:#bee3f8}.hover\:to-blue-300:hover{--gradient-to-color:#90cdf4}.hover\:to-blue-400:hover{--gradient-to-color:#63b3ed}.hover\:to-blue-500:hover{--gradient-to-color:#4299e1}.hover\:to-blue-600:hover{--gradient-to-color:#3182ce}.hover\:to-blue-700:hover{--gradient-to-color:#2b6cb0}.hover\:to-blue-800:hover{--gradient-to-color:#2c5282}.hover\:to-blue-900:hover{--gradient-to-color:#2a4365}.hover\:to-indigo-100:hover{--gradient-to-color:#ebf4ff}.hover\:to-indigo-200:hover{--gradient-to-color:#c3dafe}.hover\:to-indigo-300:hover{--gradient-to-color:#a3bffa}.hover\:to-indigo-400:hover{--gradient-to-color:#7f9cf5}.hover\:to-indigo-500:hover{--gradient-to-color:#667eea}.hover\:to-indigo-600:hover{--gradient-to-color:#5a67d8}.hover\:to-indigo-700:hover{--gradient-to-color:#4c51bf}.hover\:to-indigo-800:hover{--gradient-to-color:#434190}.hover\:to-indigo-900:hover{--gradient-to-color:#3c366b}.hover\:to-purple-100:hover{--gradient-to-color:#faf5ff}.hover\:to-purple-200:hover{--gradient-to-color:#e9d8fd}.hover\:to-purple-300:hover{--gradient-to-color:#d6bcfa}.hover\:to-purple-400:hover{--gradient-to-color:#b794f4}.hover\:to-purple-500:hover{--gradient-to-color:#9f7aea}.hover\:to-purple-600:hover{--gradient-to-color:#805ad5}.hover\:to-purple-700:hover{--gradient-to-color:#6b46c1}.hover\:to-purple-800:hover{--gradient-to-color:#553c9a}.hover\:to-purple-900:hover{--gradient-to-color:#44337a}.hover\:to-pink-100:hover{--gradient-to-color:#fff5f7}.hover\:to-pink-200:hover{--gradient-to-color:#fed7e2}.hover\:to-pink-300:hover{--gradient-to-color:#fbb6ce}.hover\:to-pink-400:hover{--gradient-to-color:#f687b3}.hover\:to-pink-500:hover{--gradient-to-color:#ed64a6}.hover\:to-pink-600:hover{--gradient-to-color:#d53f8c}.hover\:to-pink-700:hover{--gradient-to-color:#b83280}.hover\:to-pink-800:hover{--gradient-to-color:#97266d}.hover\:to-pink-900:hover{--gradient-to-color:#702459}.focus\:from-transparent:focus{--gradient-from-color:transparent;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(0, 0, 0, 0))}.focus\:from-current:focus{--gradient-from-color:currentColor;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 255, 255, 0))}.focus\:from-black:focus{--gradient-from-color:#000;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(0, 0, 0, 0))}.focus\:from-white:focus{--gradient-from-color:#fff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 255, 255, 0))}.focus\:from-gray-100:focus{--gradient-from-color:#f7fafc;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(247, 250, 252, 0))}.focus\:from-gray-200:focus{--gradient-from-color:#edf2f7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(237, 242, 247, 0))}.focus\:from-gray-300:focus{--gradient-from-color:#e2e8f0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(226, 232, 240, 0))}.focus\:from-gray-400:focus{--gradient-from-color:#cbd5e0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(203, 213, 224, 0))}.focus\:from-gray-500:focus{--gradient-from-color:#a0aec0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(160, 174, 192, 0))}.focus\:from-gray-600:focus{--gradient-from-color:#718096;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(113, 128, 150, 0))}.focus\:from-gray-700:focus{--gradient-from-color:#4a5568;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(74, 85, 104, 0))}.focus\:from-gray-800:focus{--gradient-from-color:#2d3748;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(45, 55, 72, 0))}.focus\:from-gray-900:focus{--gradient-from-color:#1a202c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(26, 32, 44, 0))}.focus\:from-red-100:focus{--gradient-from-color:#fff5f5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 245, 245, 0))}.focus\:from-red-200:focus{--gradient-from-color:#fed7d7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(254, 215, 215, 0))}.focus\:from-red-300:focus{--gradient-from-color:#feb2b2;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(254, 178, 178, 0))}.focus\:from-red-400:focus{--gradient-from-color:#fc8181;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(252, 129, 129, 0))}.focus\:from-red-500:focus{--gradient-from-color:#f56565;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(245, 101, 101, 0))}.focus\:from-red-600:focus{--gradient-from-color:#e53e3e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(229, 62, 62, 0))}.focus\:from-red-700:focus{--gradient-from-color:#c53030;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(197, 48, 48, 0))}.focus\:from-red-800:focus{--gradient-from-color:#9b2c2c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(155, 44, 44, 0))}.focus\:from-red-900:focus{--gradient-from-color:#742a2a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(116, 42, 42, 0))}.focus\:from-orange-100:focus{--gradient-from-color:#fffaf0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 250, 240, 0))}.focus\:from-orange-200:focus{--gradient-from-color:#feebc8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(254, 235, 200, 0))}.focus\:from-orange-300:focus{--gradient-from-color:#fbd38d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(251, 211, 141, 0))}.focus\:from-orange-400:focus{--gradient-from-color:#f6ad55;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(246, 173, 85, 0))}.focus\:from-orange-500:focus{--gradient-from-color:#ed8936;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(237, 137, 54, 0))}.focus\:from-orange-600:focus{--gradient-from-color:#dd6b20;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(221, 107, 32, 0))}.focus\:from-orange-700:focus{--gradient-from-color:#c05621;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(192, 86, 33, 0))}.focus\:from-orange-800:focus{--gradient-from-color:#9c4221;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(156, 66, 33, 0))}.focus\:from-orange-900:focus{--gradient-from-color:#7b341e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(123, 52, 30, 0))}.focus\:from-yellow-100:focus{--gradient-from-color:#fffff0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 255, 240, 0))}.focus\:from-yellow-200:focus{--gradient-from-color:#fefcbf;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(254, 252, 191, 0))}.focus\:from-yellow-300:focus{--gradient-from-color:#faf089;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(250, 240, 137, 0))}.focus\:from-yellow-400:focus{--gradient-from-color:#f6e05e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(246, 224, 94, 0))}.focus\:from-yellow-500:focus{--gradient-from-color:#ecc94b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(236, 201, 75, 0))}.focus\:from-yellow-600:focus{--gradient-from-color:#d69e2e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(214, 158, 46, 0))}.focus\:from-yellow-700:focus{--gradient-from-color:#b7791f;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(183, 121, 31, 0))}.focus\:from-yellow-800:focus{--gradient-from-color:#975a16;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(151, 90, 22, 0))}.focus\:from-yellow-900:focus{--gradient-from-color:#744210;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(116, 66, 16, 0))}.focus\:from-green-100:focus{--gradient-from-color:#f0fff4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(240, 255, 244, 0))}.focus\:from-green-200:focus{--gradient-from-color:#c6f6d5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(198, 246, 213, 0))}.focus\:from-green-300:focus{--gradient-from-color:#9ae6b4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(154, 230, 180, 0))}.focus\:from-green-400:focus{--gradient-from-color:#68d391;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(104, 211, 145, 0))}.focus\:from-green-500:focus{--gradient-from-color:#48bb78;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(72, 187, 120, 0))}.focus\:from-green-600:focus{--gradient-from-color:#38a169;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(56, 161, 105, 0))}.focus\:from-green-700:focus{--gradient-from-color:#2f855a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(47, 133, 90, 0))}.focus\:from-green-800:focus{--gradient-from-color:#276749;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(39, 103, 73, 0))}.focus\:from-green-900:focus{--gradient-from-color:#22543d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(34, 84, 61, 0))}.focus\:from-teal-100:focus{--gradient-from-color:#e6fffa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(230, 255, 250, 0))}.focus\:from-teal-200:focus{--gradient-from-color:#b2f5ea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(178, 245, 234, 0))}.focus\:from-teal-300:focus{--gradient-from-color:#81e6d9;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(129, 230, 217, 0))}.focus\:from-teal-400:focus{--gradient-from-color:#4fd1c5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(79, 209, 197, 0))}.focus\:from-teal-500:focus{--gradient-from-color:#38b2ac;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(56, 178, 172, 0))}.focus\:from-teal-600:focus{--gradient-from-color:#319795;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(49, 151, 149, 0))}.focus\:from-teal-700:focus{--gradient-from-color:#2c7a7b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(44, 122, 123, 0))}.focus\:from-teal-800:focus{--gradient-from-color:#285e61;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(40, 94, 97, 0))}.focus\:from-teal-900:focus{--gradient-from-color:#234e52;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(35, 78, 82, 0))}.focus\:from-blue-100:focus{--gradient-from-color:#ebf8ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(235, 248, 255, 0))}.focus\:from-blue-200:focus{--gradient-from-color:#bee3f8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(190, 227, 248, 0))}.focus\:from-blue-300:focus{--gradient-from-color:#90cdf4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(144, 205, 244, 0))}.focus\:from-blue-400:focus{--gradient-from-color:#63b3ed;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(99, 179, 237, 0))}.focus\:from-blue-500:focus{--gradient-from-color:#4299e1;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(66, 153, 225, 0))}.focus\:from-blue-600:focus{--gradient-from-color:#3182ce;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(49, 130, 206, 0))}.focus\:from-blue-700:focus{--gradient-from-color:#2b6cb0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(43, 108, 176, 0))}.focus\:from-blue-800:focus{--gradient-from-color:#2c5282;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(44, 82, 130, 0))}.focus\:from-blue-900:focus{--gradient-from-color:#2a4365;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(42, 67, 101, 0))}.focus\:from-indigo-100:focus{--gradient-from-color:#ebf4ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(235, 244, 255, 0))}.focus\:from-indigo-200:focus{--gradient-from-color:#c3dafe;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(195, 218, 254, 0))}.focus\:from-indigo-300:focus{--gradient-from-color:#a3bffa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(163, 191, 250, 0))}.focus\:from-indigo-400:focus{--gradient-from-color:#7f9cf5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(127, 156, 245, 0))}.focus\:from-indigo-500:focus{--gradient-from-color:#667eea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(102, 126, 234, 0))}.focus\:from-indigo-600:focus{--gradient-from-color:#5a67d8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(90, 103, 216, 0))}.focus\:from-indigo-700:focus{--gradient-from-color:#4c51bf;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(76, 81, 191, 0))}.focus\:from-indigo-800:focus{--gradient-from-color:#434190;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(67, 65, 144, 0))}.focus\:from-indigo-900:focus{--gradient-from-color:#3c366b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(60, 54, 107, 0))}.focus\:from-purple-100:focus{--gradient-from-color:#faf5ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(250, 245, 255, 0))}.focus\:from-purple-200:focus{--gradient-from-color:#e9d8fd;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(233, 216, 253, 0))}.focus\:from-purple-300:focus{--gradient-from-color:#d6bcfa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(214, 188, 250, 0))}.focus\:from-purple-400:focus{--gradient-from-color:#b794f4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(183, 148, 244, 0))}.focus\:from-purple-500:focus{--gradient-from-color:#9f7aea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(159, 122, 234, 0))}.focus\:from-purple-600:focus{--gradient-from-color:#805ad5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(128, 90, 213, 0))}.focus\:from-purple-700:focus{--gradient-from-color:#6b46c1;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(107, 70, 193, 0))}.focus\:from-purple-800:focus{--gradient-from-color:#553c9a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(85, 60, 154, 0))}.focus\:from-purple-900:focus{--gradient-from-color:#44337a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(68, 51, 122, 0))}.focus\:from-pink-100:focus{--gradient-from-color:#fff5f7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 245, 247, 0))}.focus\:from-pink-200:focus{--gradient-from-color:#fed7e2;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(254, 215, 226, 0))}.focus\:from-pink-300:focus{--gradient-from-color:#fbb6ce;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(251, 182, 206, 0))}.focus\:from-pink-400:focus{--gradient-from-color:#f687b3;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(246, 135, 179, 0))}.focus\:from-pink-500:focus{--gradient-from-color:#ed64a6;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(237, 100, 166, 0))}.focus\:from-pink-600:focus{--gradient-from-color:#d53f8c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(213, 63, 140, 0))}.focus\:from-pink-700:focus{--gradient-from-color:#b83280;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(184, 50, 128, 0))}.focus\:from-pink-800:focus{--gradient-from-color:#97266d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(151, 38, 109, 0))}.focus\:from-pink-900:focus{--gradient-from-color:#702459;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(112, 36, 89, 0))}.focus\:via-transparent:focus{--gradient-via-color:transparent;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(0, 0, 0, 0))}.focus\:via-current:focus{--gradient-via-color:currentColor;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 255, 255, 0))}.focus\:via-black:focus{--gradient-via-color:#000;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(0, 0, 0, 0))}.focus\:via-white:focus{--gradient-via-color:#fff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 255, 255, 0))}.focus\:via-gray-100:focus{--gradient-via-color:#f7fafc;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(247, 250, 252, 0))}.focus\:via-gray-200:focus{--gradient-via-color:#edf2f7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(237, 242, 247, 0))}.focus\:via-gray-300:focus{--gradient-via-color:#e2e8f0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(226, 232, 240, 0))}.focus\:via-gray-400:focus{--gradient-via-color:#cbd5e0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(203, 213, 224, 0))}.focus\:via-gray-500:focus{--gradient-via-color:#a0aec0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(160, 174, 192, 0))}.focus\:via-gray-600:focus{--gradient-via-color:#718096;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(113, 128, 150, 0))}.focus\:via-gray-700:focus{--gradient-via-color:#4a5568;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(74, 85, 104, 0))}.focus\:via-gray-800:focus{--gradient-via-color:#2d3748;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(45, 55, 72, 0))}.focus\:via-gray-900:focus{--gradient-via-color:#1a202c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(26, 32, 44, 0))}.focus\:via-red-100:focus{--gradient-via-color:#fff5f5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 245, 245, 0))}.focus\:via-red-200:focus{--gradient-via-color:#fed7d7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(254, 215, 215, 0))}.focus\:via-red-300:focus{--gradient-via-color:#feb2b2;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(254, 178, 178, 0))}.focus\:via-red-400:focus{--gradient-via-color:#fc8181;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(252, 129, 129, 0))}.focus\:via-red-500:focus{--gradient-via-color:#f56565;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(245, 101, 101, 0))}.focus\:via-red-600:focus{--gradient-via-color:#e53e3e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(229, 62, 62, 0))}.focus\:via-red-700:focus{--gradient-via-color:#c53030;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(197, 48, 48, 0))}.focus\:via-red-800:focus{--gradient-via-color:#9b2c2c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(155, 44, 44, 0))}.focus\:via-red-900:focus{--gradient-via-color:#742a2a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(116, 42, 42, 0))}.focus\:via-orange-100:focus{--gradient-via-color:#fffaf0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 250, 240, 0))}.focus\:via-orange-200:focus{--gradient-via-color:#feebc8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(254, 235, 200, 0))}.focus\:via-orange-300:focus{--gradient-via-color:#fbd38d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(251, 211, 141, 0))}.focus\:via-orange-400:focus{--gradient-via-color:#f6ad55;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(246, 173, 85, 0))}.focus\:via-orange-500:focus{--gradient-via-color:#ed8936;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(237, 137, 54, 0))}.focus\:via-orange-600:focus{--gradient-via-color:#dd6b20;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(221, 107, 32, 0))}.focus\:via-orange-700:focus{--gradient-via-color:#c05621;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(192, 86, 33, 0))}.focus\:via-orange-800:focus{--gradient-via-color:#9c4221;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(156, 66, 33, 0))}.focus\:via-orange-900:focus{--gradient-via-color:#7b341e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(123, 52, 30, 0))}.focus\:via-yellow-100:focus{--gradient-via-color:#fffff0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 255, 240, 0))}.focus\:via-yellow-200:focus{--gradient-via-color:#fefcbf;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(254, 252, 191, 0))}.focus\:via-yellow-300:focus{--gradient-via-color:#faf089;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(250, 240, 137, 0))}.focus\:via-yellow-400:focus{--gradient-via-color:#f6e05e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(246, 224, 94, 0))}.focus\:via-yellow-500:focus{--gradient-via-color:#ecc94b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(236, 201, 75, 0))}.focus\:via-yellow-600:focus{--gradient-via-color:#d69e2e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(214, 158, 46, 0))}.focus\:via-yellow-700:focus{--gradient-via-color:#b7791f;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(183, 121, 31, 0))}.focus\:via-yellow-800:focus{--gradient-via-color:#975a16;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(151, 90, 22, 0))}.focus\:via-yellow-900:focus{--gradient-via-color:#744210;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(116, 66, 16, 0))}.focus\:via-green-100:focus{--gradient-via-color:#f0fff4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(240, 255, 244, 0))}.focus\:via-green-200:focus{--gradient-via-color:#c6f6d5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(198, 246, 213, 0))}.focus\:via-green-300:focus{--gradient-via-color:#9ae6b4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(154, 230, 180, 0))}.focus\:via-green-400:focus{--gradient-via-color:#68d391;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(104, 211, 145, 0))}.focus\:via-green-500:focus{--gradient-via-color:#48bb78;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(72, 187, 120, 0))}.focus\:via-green-600:focus{--gradient-via-color:#38a169;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(56, 161, 105, 0))}.focus\:via-green-700:focus{--gradient-via-color:#2f855a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(47, 133, 90, 0))}.focus\:via-green-800:focus{--gradient-via-color:#276749;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(39, 103, 73, 0))}.focus\:via-green-900:focus{--gradient-via-color:#22543d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(34, 84, 61, 0))}.focus\:via-teal-100:focus{--gradient-via-color:#e6fffa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(230, 255, 250, 0))}.focus\:via-teal-200:focus{--gradient-via-color:#b2f5ea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(178, 245, 234, 0))}.focus\:via-teal-300:focus{--gradient-via-color:#81e6d9;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(129, 230, 217, 0))}.focus\:via-teal-400:focus{--gradient-via-color:#4fd1c5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(79, 209, 197, 0))}.focus\:via-teal-500:focus{--gradient-via-color:#38b2ac;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(56, 178, 172, 0))}.focus\:via-teal-600:focus{--gradient-via-color:#319795;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(49, 151, 149, 0))}.focus\:via-teal-700:focus{--gradient-via-color:#2c7a7b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(44, 122, 123, 0))}.focus\:via-teal-800:focus{--gradient-via-color:#285e61;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(40, 94, 97, 0))}.focus\:via-teal-900:focus{--gradient-via-color:#234e52;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(35, 78, 82, 0))}.focus\:via-blue-100:focus{--gradient-via-color:#ebf8ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(235, 248, 255, 0))}.focus\:via-blue-200:focus{--gradient-via-color:#bee3f8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(190, 227, 248, 0))}.focus\:via-blue-300:focus{--gradient-via-color:#90cdf4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(144, 205, 244, 0))}.focus\:via-blue-400:focus{--gradient-via-color:#63b3ed;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(99, 179, 237, 0))}.focus\:via-blue-500:focus{--gradient-via-color:#4299e1;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(66, 153, 225, 0))}.focus\:via-blue-600:focus{--gradient-via-color:#3182ce;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(49, 130, 206, 0))}.focus\:via-blue-700:focus{--gradient-via-color:#2b6cb0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(43, 108, 176, 0))}.focus\:via-blue-800:focus{--gradient-via-color:#2c5282;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(44, 82, 130, 0))}.focus\:via-blue-900:focus{--gradient-via-color:#2a4365;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(42, 67, 101, 0))}.focus\:via-indigo-100:focus{--gradient-via-color:#ebf4ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(235, 244, 255, 0))}.focus\:via-indigo-200:focus{--gradient-via-color:#c3dafe;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(195, 218, 254, 0))}.focus\:via-indigo-300:focus{--gradient-via-color:#a3bffa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(163, 191, 250, 0))}.focus\:via-indigo-400:focus{--gradient-via-color:#7f9cf5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(127, 156, 245, 0))}.focus\:via-indigo-500:focus{--gradient-via-color:#667eea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(102, 126, 234, 0))}.focus\:via-indigo-600:focus{--gradient-via-color:#5a67d8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(90, 103, 216, 0))}.focus\:via-indigo-700:focus{--gradient-via-color:#4c51bf;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(76, 81, 191, 0))}.focus\:via-indigo-800:focus{--gradient-via-color:#434190;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(67, 65, 144, 0))}.focus\:via-indigo-900:focus{--gradient-via-color:#3c366b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(60, 54, 107, 0))}.focus\:via-purple-100:focus{--gradient-via-color:#faf5ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(250, 245, 255, 0))}.focus\:via-purple-200:focus{--gradient-via-color:#e9d8fd;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(233, 216, 253, 0))}.focus\:via-purple-300:focus{--gradient-via-color:#d6bcfa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(214, 188, 250, 0))}.focus\:via-purple-400:focus{--gradient-via-color:#b794f4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(183, 148, 244, 0))}.focus\:via-purple-500:focus{--gradient-via-color:#9f7aea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(159, 122, 234, 0))}.focus\:via-purple-600:focus{--gradient-via-color:#805ad5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(128, 90, 213, 0))}.focus\:via-purple-700:focus{--gradient-via-color:#6b46c1;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(107, 70, 193, 0))}.focus\:via-purple-800:focus{--gradient-via-color:#553c9a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(85, 60, 154, 0))}.focus\:via-purple-900:focus{--gradient-via-color:#44337a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(68, 51, 122, 0))}.focus\:via-pink-100:focus{--gradient-via-color:#fff5f7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 245, 247, 0))}.focus\:via-pink-200:focus{--gradient-via-color:#fed7e2;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(254, 215, 226, 0))}.focus\:via-pink-300:focus{--gradient-via-color:#fbb6ce;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(251, 182, 206, 0))}.focus\:via-pink-400:focus{--gradient-via-color:#f687b3;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(246, 135, 179, 0))}.focus\:via-pink-500:focus{--gradient-via-color:#ed64a6;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(237, 100, 166, 0))}.focus\:via-pink-600:focus{--gradient-via-color:#d53f8c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(213, 63, 140, 0))}.focus\:via-pink-700:focus{--gradient-via-color:#b83280;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(184, 50, 128, 0))}.focus\:via-pink-800:focus{--gradient-via-color:#97266d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(151, 38, 109, 0))}.focus\:via-pink-900:focus{--gradient-via-color:#702459;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(112, 36, 89, 0))}.focus\:to-transparent:focus{--gradient-to-color:transparent}.focus\:to-current:focus{--gradient-to-color:currentColor}.focus\:to-black:focus{--gradient-to-color:#000}.focus\:to-white:focus{--gradient-to-color:#fff}.focus\:to-gray-100:focus{--gradient-to-color:#f7fafc}.focus\:to-gray-200:focus{--gradient-to-color:#edf2f7}.focus\:to-gray-300:focus{--gradient-to-color:#e2e8f0}.focus\:to-gray-400:focus{--gradient-to-color:#cbd5e0}.focus\:to-gray-500:focus{--gradient-to-color:#a0aec0}.focus\:to-gray-600:focus{--gradient-to-color:#718096}.focus\:to-gray-700:focus{--gradient-to-color:#4a5568}.focus\:to-gray-800:focus{--gradient-to-color:#2d3748}.focus\:to-gray-900:focus{--gradient-to-color:#1a202c}.focus\:to-red-100:focus{--gradient-to-color:#fff5f5}.focus\:to-red-200:focus{--gradient-to-color:#fed7d7}.focus\:to-red-300:focus{--gradient-to-color:#feb2b2}.focus\:to-red-400:focus{--gradient-to-color:#fc8181}.focus\:to-red-500:focus{--gradient-to-color:#f56565}.focus\:to-red-600:focus{--gradient-to-color:#e53e3e}.focus\:to-red-700:focus{--gradient-to-color:#c53030}.focus\:to-red-800:focus{--gradient-to-color:#9b2c2c}.focus\:to-red-900:focus{--gradient-to-color:#742a2a}.focus\:to-orange-100:focus{--gradient-to-color:#fffaf0}.focus\:to-orange-200:focus{--gradient-to-color:#feebc8}.focus\:to-orange-300:focus{--gradient-to-color:#fbd38d}.focus\:to-orange-400:focus{--gradient-to-color:#f6ad55}.focus\:to-orange-500:focus{--gradient-to-color:#ed8936}.focus\:to-orange-600:focus{--gradient-to-color:#dd6b20}.focus\:to-orange-700:focus{--gradient-to-color:#c05621}.focus\:to-orange-800:focus{--gradient-to-color:#9c4221}.focus\:to-orange-900:focus{--gradient-to-color:#7b341e}.focus\:to-yellow-100:focus{--gradient-to-color:#fffff0}.focus\:to-yellow-200:focus{--gradient-to-color:#fefcbf}.focus\:to-yellow-300:focus{--gradient-to-color:#faf089}.focus\:to-yellow-400:focus{--gradient-to-color:#f6e05e}.focus\:to-yellow-500:focus{--gradient-to-color:#ecc94b}.focus\:to-yellow-600:focus{--gradient-to-color:#d69e2e}.focus\:to-yellow-700:focus{--gradient-to-color:#b7791f}.focus\:to-yellow-800:focus{--gradient-to-color:#975a16}.focus\:to-yellow-900:focus{--gradient-to-color:#744210}.focus\:to-green-100:focus{--gradient-to-color:#f0fff4}.focus\:to-green-200:focus{--gradient-to-color:#c6f6d5}.focus\:to-green-300:focus{--gradient-to-color:#9ae6b4}.focus\:to-green-400:focus{--gradient-to-color:#68d391}.focus\:to-green-500:focus{--gradient-to-color:#48bb78}.focus\:to-green-600:focus{--gradient-to-color:#38a169}.focus\:to-green-700:focus{--gradient-to-color:#2f855a}.focus\:to-green-800:focus{--gradient-to-color:#276749}.focus\:to-green-900:focus{--gradient-to-color:#22543d}.focus\:to-teal-100:focus{--gradient-to-color:#e6fffa}.focus\:to-teal-200:focus{--gradient-to-color:#b2f5ea}.focus\:to-teal-300:focus{--gradient-to-color:#81e6d9}.focus\:to-teal-400:focus{--gradient-to-color:#4fd1c5}.focus\:to-teal-500:focus{--gradient-to-color:#38b2ac}.focus\:to-teal-600:focus{--gradient-to-color:#319795}.focus\:to-teal-700:focus{--gradient-to-color:#2c7a7b}.focus\:to-teal-800:focus{--gradient-to-color:#285e61}.focus\:to-teal-900:focus{--gradient-to-color:#234e52}.focus\:to-blue-100:focus{--gradient-to-color:#ebf8ff}.focus\:to-blue-200:focus{--gradient-to-color:#bee3f8}.focus\:to-blue-300:focus{--gradient-to-color:#90cdf4}.focus\:to-blue-400:focus{--gradient-to-color:#63b3ed}.focus\:to-blue-500:focus{--gradient-to-color:#4299e1}.focus\:to-blue-600:focus{--gradient-to-color:#3182ce}.focus\:to-blue-700:focus{--gradient-to-color:#2b6cb0}.focus\:to-blue-800:focus{--gradient-to-color:#2c5282}.focus\:to-blue-900:focus{--gradient-to-color:#2a4365}.focus\:to-indigo-100:focus{--gradient-to-color:#ebf4ff}.focus\:to-indigo-200:focus{--gradient-to-color:#c3dafe}.focus\:to-indigo-300:focus{--gradient-to-color:#a3bffa}.focus\:to-indigo-400:focus{--gradient-to-color:#7f9cf5}.focus\:to-indigo-500:focus{--gradient-to-color:#667eea}.focus\:to-indigo-600:focus{--gradient-to-color:#5a67d8}.focus\:to-indigo-700:focus{--gradient-to-color:#4c51bf}.focus\:to-indigo-800:focus{--gradient-to-color:#434190}.focus\:to-indigo-900:focus{--gradient-to-color:#3c366b}.focus\:to-purple-100:focus{--gradient-to-color:#faf5ff}.focus\:to-purple-200:focus{--gradient-to-color:#e9d8fd}.focus\:to-purple-300:focus{--gradient-to-color:#d6bcfa}.focus\:to-purple-400:focus{--gradient-to-color:#b794f4}.focus\:to-purple-500:focus{--gradient-to-color:#9f7aea}.focus\:to-purple-600:focus{--gradient-to-color:#805ad5}.focus\:to-purple-700:focus{--gradient-to-color:#6b46c1}.focus\:to-purple-800:focus{--gradient-to-color:#553c9a}.focus\:to-purple-900:focus{--gradient-to-color:#44337a}.focus\:to-pink-100:focus{--gradient-to-color:#fff5f7}.focus\:to-pink-200:focus{--gradient-to-color:#fed7e2}.focus\:to-pink-300:focus{--gradient-to-color:#fbb6ce}.focus\:to-pink-400:focus{--gradient-to-color:#f687b3}.focus\:to-pink-500:focus{--gradient-to-color:#ed64a6}.focus\:to-pink-600:focus{--gradient-to-color:#d53f8c}.focus\:to-pink-700:focus{--gradient-to-color:#b83280}.focus\:to-pink-800:focus{--gradient-to-color:#97266d}.focus\:to-pink-900:focus{--gradient-to-color:#702459}.bg-opacity-0{--bg-opacity:0}.bg-opacity-25{--bg-opacity:0.25}.bg-opacity-50{--bg-opacity:0.5}.bg-opacity-75{--bg-opacity:0.75}.bg-opacity-100{--bg-opacity:1}.hover\:bg-opacity-0:hover{--bg-opacity:0}.hover\:bg-opacity-25:hover{--bg-opacity:0.25}.hover\:bg-opacity-50:hover{--bg-opacity:0.5}.hover\:bg-opacity-75:hover{--bg-opacity:0.75}.hover\:bg-opacity-100:hover{--bg-opacity:1}.focus\:bg-opacity-0:focus{--bg-opacity:0}.focus\:bg-opacity-25:focus{--bg-opacity:0.25}.focus\:bg-opacity-50:focus{--bg-opacity:0.5}.focus\:bg-opacity-75:focus{--bg-opacity:0.75}.focus\:bg-opacity-100:focus{--bg-opacity:1}.bg-bottom{background-position:bottom}.bg-center{background-position:center}.bg-left{background-position:left}.bg-left-bottom{background-position:left bottom}.bg-left-top{background-position:left top}.bg-right{background-position:right}.bg-right-bottom{background-position:right bottom}.bg-right-top{background-position:right top}.bg-top{background-position:top}.bg-repeat{background-repeat:repeat}.bg-no-repeat{background-repeat:no-repeat}.bg-repeat-x{background-repeat:repeat-x}.bg-repeat-y{background-repeat:repeat-y}.bg-repeat-round{background-repeat:round}.bg-repeat-space{background-repeat:space}.bg-auto{background-size:auto}.bg-cover{background-size:cover}.bg-contain{background-size:contain}.border-collapse{border-collapse:collapse}.border-separate{border-collapse:separate}.border-transparent{border-color:transparent}.border-current{border-color:currentColor}.border-black{--border-opacity:1;border-color:#000;border-color:rgba(0,0,0,var(--border-opacity))}.border-white{--border-opacity:1;border-color:#fff;border-color:rgba(255,255,255,var(--border-opacity))}.border-gray-100{--border-opacity:1;border-color:#f7fafc;border-color:rgba(247,250,252,var(--border-opacity))}.border-gray-200{--border-opacity:1;border-color:#edf2f7;border-color:rgba(237,242,247,var(--border-opacity))}.border-gray-300{--border-opacity:1;border-color:#e2e8f0;border-color:rgba(226,232,240,var(--border-opacity))}.border-gray-400{--border-opacity:1;border-color:#cbd5e0;border-color:rgba(203,213,224,var(--border-opacity))}.border-gray-500{--border-opacity:1;border-color:#a0aec0;border-color:rgba(160,174,192,var(--border-opacity))}.border-gray-600{--border-opacity:1;border-color:#718096;border-color:rgba(113,128,150,var(--border-opacity))}.border-gray-700{--border-opacity:1;border-color:#4a5568;border-color:rgba(74,85,104,var(--border-opacity))}.border-gray-800{--border-opacity:1;border-color:#2d3748;border-color:rgba(45,55,72,var(--border-opacity))}.border-gray-900{--border-opacity:1;border-color:#1a202c;border-color:rgba(26,32,44,var(--border-opacity))}.border-red-100{--border-opacity:1;border-color:#fff5f5;border-color:rgba(255,245,245,var(--border-opacity))}.border-red-200{--border-opacity:1;border-color:#fed7d7;border-color:rgba(254,215,215,var(--border-opacity))}.border-red-300{--border-opacity:1;border-color:#feb2b2;border-color:rgba(254,178,178,var(--border-opacity))}.border-red-400{--border-opacity:1;border-color:#fc8181;border-color:rgba(252,129,129,var(--border-opacity))}.border-red-500{--border-opacity:1;border-color:#f56565;border-color:rgba(245,101,101,var(--border-opacity))}.border-red-600{--border-opacity:1;border-color:#e53e3e;border-color:rgba(229,62,62,var(--border-opacity))}.border-red-700{--border-opacity:1;border-color:#c53030;border-color:rgba(197,48,48,var(--border-opacity))}.border-red-800{--border-opacity:1;border-color:#9b2c2c;border-color:rgba(155,44,44,var(--border-opacity))}.border-red-900{--border-opacity:1;border-color:#742a2a;border-color:rgba(116,42,42,var(--border-opacity))}.border-orange-100{--border-opacity:1;border-color:#fffaf0;border-color:rgba(255,250,240,var(--border-opacity))}.border-orange-200{--border-opacity:1;border-color:#feebc8;border-color:rgba(254,235,200,var(--border-opacity))}.border-orange-300{--border-opacity:1;border-color:#fbd38d;border-color:rgba(251,211,141,var(--border-opacity))}.border-orange-400{--border-opacity:1;border-color:#f6ad55;border-color:rgba(246,173,85,var(--border-opacity))}.border-orange-500{--border-opacity:1;border-color:#ed8936;border-color:rgba(237,137,54,var(--border-opacity))}.border-orange-600{--border-opacity:1;border-color:#dd6b20;border-color:rgba(221,107,32,var(--border-opacity))}.border-orange-700{--border-opacity:1;border-color:#c05621;border-color:rgba(192,86,33,var(--border-opacity))}.border-orange-800{--border-opacity:1;border-color:#9c4221;border-color:rgba(156,66,33,var(--border-opacity))}.border-orange-900{--border-opacity:1;border-color:#7b341e;border-color:rgba(123,52,30,var(--border-opacity))}.border-yellow-100{--border-opacity:1;border-color:ivory;border-color:rgba(255,255,240,var(--border-opacity))}.border-yellow-200{--border-opacity:1;border-color:#fefcbf;border-color:rgba(254,252,191,var(--border-opacity))}.border-yellow-300{--border-opacity:1;border-color:#faf089;border-color:rgba(250,240,137,var(--border-opacity))}.border-yellow-400{--border-opacity:1;border-color:#f6e05e;border-color:rgba(246,224,94,var(--border-opacity))}.border-yellow-500{--border-opacity:1;border-color:#ecc94b;border-color:rgba(236,201,75,var(--border-opacity))}.border-yellow-600{--border-opacity:1;border-color:#d69e2e;border-color:rgba(214,158,46,var(--border-opacity))}.border-yellow-700{--border-opacity:1;border-color:#b7791f;border-color:rgba(183,121,31,var(--border-opacity))}.border-yellow-800{--border-opacity:1;border-color:#975a16;border-color:rgba(151,90,22,var(--border-opacity))}.border-yellow-900{--border-opacity:1;border-color:#744210;border-color:rgba(116,66,16,var(--border-opacity))}.border-green-100{--border-opacity:1;border-color:#f0fff4;border-color:rgba(240,255,244,var(--border-opacity))}.border-green-200{--border-opacity:1;border-color:#c6f6d5;border-color:rgba(198,246,213,var(--border-opacity))}.border-green-300{--border-opacity:1;border-color:#9ae6b4;border-color:rgba(154,230,180,var(--border-opacity))}.border-green-400{--border-opacity:1;border-color:#68d391;border-color:rgba(104,211,145,var(--border-opacity))}.border-green-500{--border-opacity:1;border-color:#48bb78;border-color:rgba(72,187,120,var(--border-opacity))}.border-green-600{--border-opacity:1;border-color:#38a169;border-color:rgba(56,161,105,var(--border-opacity))}.border-green-700{--border-opacity:1;border-color:#2f855a;border-color:rgba(47,133,90,var(--border-opacity))}.border-green-800{--border-opacity:1;border-color:#276749;border-color:rgba(39,103,73,var(--border-opacity))}.border-green-900{--border-opacity:1;border-color:#22543d;border-color:rgba(34,84,61,var(--border-opacity))}.border-teal-100{--border-opacity:1;border-color:#e6fffa;border-color:rgba(230,255,250,var(--border-opacity))}.border-teal-200{--border-opacity:1;border-color:#b2f5ea;border-color:rgba(178,245,234,var(--border-opacity))}.border-teal-300{--border-opacity:1;border-color:#81e6d9;border-color:rgba(129,230,217,var(--border-opacity))}.border-teal-400{--border-opacity:1;border-color:#4fd1c5;border-color:rgba(79,209,197,var(--border-opacity))}.border-teal-500{--border-opacity:1;border-color:#38b2ac;border-color:rgba(56,178,172,var(--border-opacity))}.border-teal-600{--border-opacity:1;border-color:#319795;border-color:rgba(49,151,149,var(--border-opacity))}.border-teal-700{--border-opacity:1;border-color:#2c7a7b;border-color:rgba(44,122,123,var(--border-opacity))}.border-teal-800{--border-opacity:1;border-color:#285e61;border-color:rgba(40,94,97,var(--border-opacity))}.border-teal-900{--border-opacity:1;border-color:#234e52;border-color:rgba(35,78,82,var(--border-opacity))}.border-blue-100{--border-opacity:1;border-color:#ebf8ff;border-color:rgba(235,248,255,var(--border-opacity))}.border-blue-200{--border-opacity:1;border-color:#bee3f8;border-color:rgba(190,227,248,var(--border-opacity))}.border-blue-300{--border-opacity:1;border-color:#90cdf4;border-color:rgba(144,205,244,var(--border-opacity))}.border-blue-400{--border-opacity:1;border-color:#63b3ed;border-color:rgba(99,179,237,var(--border-opacity))}.border-blue-500{--border-opacity:1;border-color:#4299e1;border-color:rgba(66,153,225,var(--border-opacity))}.border-blue-600{--border-opacity:1;border-color:#3182ce;border-color:rgba(49,130,206,var(--border-opacity))}.border-blue-700{--border-opacity:1;border-color:#2b6cb0;border-color:rgba(43,108,176,var(--border-opacity))}.border-blue-800{--border-opacity:1;border-color:#2c5282;border-color:rgba(44,82,130,var(--border-opacity))}.border-blue-900{--border-opacity:1;border-color:#2a4365;border-color:rgba(42,67,101,var(--border-opacity))}.border-indigo-100{--border-opacity:1;border-color:#ebf4ff;border-color:rgba(235,244,255,var(--border-opacity))}.border-indigo-200{--border-opacity:1;border-color:#c3dafe;border-color:rgba(195,218,254,var(--border-opacity))}.border-indigo-300{--border-opacity:1;border-color:#a3bffa;border-color:rgba(163,191,250,var(--border-opacity))}.border-indigo-400{--border-opacity:1;border-color:#7f9cf5;border-color:rgba(127,156,245,var(--border-opacity))}.border-indigo-500{--border-opacity:1;border-color:#667eea;border-color:rgba(102,126,234,var(--border-opacity))}.border-indigo-600{--border-opacity:1;border-color:#5a67d8;border-color:rgba(90,103,216,var(--border-opacity))}.border-indigo-700{--border-opacity:1;border-color:#4c51bf;border-color:rgba(76,81,191,var(--border-opacity))}.border-indigo-800{--border-opacity:1;border-color:#434190;border-color:rgba(67,65,144,var(--border-opacity))}.border-indigo-900{--border-opacity:1;border-color:#3c366b;border-color:rgba(60,54,107,var(--border-opacity))}.border-purple-100{--border-opacity:1;border-color:#faf5ff;border-color:rgba(250,245,255,var(--border-opacity))}.border-purple-200{--border-opacity:1;border-color:#e9d8fd;border-color:rgba(233,216,253,var(--border-opacity))}.border-purple-300{--border-opacity:1;border-color:#d6bcfa;border-color:rgba(214,188,250,var(--border-opacity))}.border-purple-400{--border-opacity:1;border-color:#b794f4;border-color:rgba(183,148,244,var(--border-opacity))}.border-purple-500{--border-opacity:1;border-color:#9f7aea;border-color:rgba(159,122,234,var(--border-opacity))}.border-purple-600{--border-opacity:1;border-color:#805ad5;border-color:rgba(128,90,213,var(--border-opacity))}.border-purple-700{--border-opacity:1;border-color:#6b46c1;border-color:rgba(107,70,193,var(--border-opacity))}.border-purple-800{--border-opacity:1;border-color:#553c9a;border-color:rgba(85,60,154,var(--border-opacity))}.border-purple-900{--border-opacity:1;border-color:#44337a;border-color:rgba(68,51,122,var(--border-opacity))}.border-pink-100{--border-opacity:1;border-color:#fff5f7;border-color:rgba(255,245,247,var(--border-opacity))}.border-pink-200{--border-opacity:1;border-color:#fed7e2;border-color:rgba(254,215,226,var(--border-opacity))}.border-pink-300{--border-opacity:1;border-color:#fbb6ce;border-color:rgba(251,182,206,var(--border-opacity))}.border-pink-400{--border-opacity:1;border-color:#f687b3;border-color:rgba(246,135,179,var(--border-opacity))}.border-pink-500{--border-opacity:1;border-color:#ed64a6;border-color:rgba(237,100,166,var(--border-opacity))}.border-pink-600{--border-opacity:1;border-color:#d53f8c;border-color:rgba(213,63,140,var(--border-opacity))}.border-pink-700{--border-opacity:1;border-color:#b83280;border-color:rgba(184,50,128,var(--border-opacity))}.border-pink-800{--border-opacity:1;border-color:#97266d;border-color:rgba(151,38,109,var(--border-opacity))}.border-pink-900{--border-opacity:1;border-color:#702459;border-color:rgba(112,36,89,var(--border-opacity))}.hover\:border-transparent:hover{border-color:transparent}.hover\:border-current:hover{border-color:currentColor}.hover\:border-black:hover{--border-opacity:1;border-color:#000;border-color:rgba(0,0,0,var(--border-opacity))}.hover\:border-white:hover{--border-opacity:1;border-color:#fff;border-color:rgba(255,255,255,var(--border-opacity))}.hover\:border-gray-100:hover{--border-opacity:1;border-color:#f7fafc;border-color:rgba(247,250,252,var(--border-opacity))}.hover\:border-gray-200:hover{--border-opacity:1;border-color:#edf2f7;border-color:rgba(237,242,247,var(--border-opacity))}.hover\:border-gray-300:hover{--border-opacity:1;border-color:#e2e8f0;border-color:rgba(226,232,240,var(--border-opacity))}.hover\:border-gray-400:hover{--border-opacity:1;border-color:#cbd5e0;border-color:rgba(203,213,224,var(--border-opacity))}.hover\:border-gray-500:hover{--border-opacity:1;border-color:#a0aec0;border-color:rgba(160,174,192,var(--border-opacity))}.hover\:border-gray-600:hover{--border-opacity:1;border-color:#718096;border-color:rgba(113,128,150,var(--border-opacity))}.hover\:border-gray-700:hover{--border-opacity:1;border-color:#4a5568;border-color:rgba(74,85,104,var(--border-opacity))}.hover\:border-gray-800:hover{--border-opacity:1;border-color:#2d3748;border-color:rgba(45,55,72,var(--border-opacity))}.hover\:border-gray-900:hover{--border-opacity:1;border-color:#1a202c;border-color:rgba(26,32,44,var(--border-opacity))}.hover\:border-red-100:hover{--border-opacity:1;border-color:#fff5f5;border-color:rgba(255,245,245,var(--border-opacity))}.hover\:border-red-200:hover{--border-opacity:1;border-color:#fed7d7;border-color:rgba(254,215,215,var(--border-opacity))}.hover\:border-red-300:hover{--border-opacity:1;border-color:#feb2b2;border-color:rgba(254,178,178,var(--border-opacity))}.hover\:border-red-400:hover{--border-opacity:1;border-color:#fc8181;border-color:rgba(252,129,129,var(--border-opacity))}.hover\:border-red-500:hover{--border-opacity:1;border-color:#f56565;border-color:rgba(245,101,101,var(--border-opacity))}.hover\:border-red-600:hover{--border-opacity:1;border-color:#e53e3e;border-color:rgba(229,62,62,var(--border-opacity))}.hover\:border-red-700:hover{--border-opacity:1;border-color:#c53030;border-color:rgba(197,48,48,var(--border-opacity))}.hover\:border-red-800:hover{--border-opacity:1;border-color:#9b2c2c;border-color:rgba(155,44,44,var(--border-opacity))}.hover\:border-red-900:hover{--border-opacity:1;border-color:#742a2a;border-color:rgba(116,42,42,var(--border-opacity))}.hover\:border-orange-100:hover{--border-opacity:1;border-color:#fffaf0;border-color:rgba(255,250,240,var(--border-opacity))}.hover\:border-orange-200:hover{--border-opacity:1;border-color:#feebc8;border-color:rgba(254,235,200,var(--border-opacity))}.hover\:border-orange-300:hover{--border-opacity:1;border-color:#fbd38d;border-color:rgba(251,211,141,var(--border-opacity))}.hover\:border-orange-400:hover{--border-opacity:1;border-color:#f6ad55;border-color:rgba(246,173,85,var(--border-opacity))}.hover\:border-orange-500:hover{--border-opacity:1;border-color:#ed8936;border-color:rgba(237,137,54,var(--border-opacity))}.hover\:border-orange-600:hover{--border-opacity:1;border-color:#dd6b20;border-color:rgba(221,107,32,var(--border-opacity))}.hover\:border-orange-700:hover{--border-opacity:1;border-color:#c05621;border-color:rgba(192,86,33,var(--border-opacity))}.hover\:border-orange-800:hover{--border-opacity:1;border-color:#9c4221;border-color:rgba(156,66,33,var(--border-opacity))}.hover\:border-orange-900:hover{--border-opacity:1;border-color:#7b341e;border-color:rgba(123,52,30,var(--border-opacity))}.hover\:border-yellow-100:hover{--border-opacity:1;border-color:ivory;border-color:rgba(255,255,240,var(--border-opacity))}.hover\:border-yellow-200:hover{--border-opacity:1;border-color:#fefcbf;border-color:rgba(254,252,191,var(--border-opacity))}.hover\:border-yellow-300:hover{--border-opacity:1;border-color:#faf089;border-color:rgba(250,240,137,var(--border-opacity))}.hover\:border-yellow-400:hover{--border-opacity:1;border-color:#f6e05e;border-color:rgba(246,224,94,var(--border-opacity))}.hover\:border-yellow-500:hover{--border-opacity:1;border-color:#ecc94b;border-color:rgba(236,201,75,var(--border-opacity))}.hover\:border-yellow-600:hover{--border-opacity:1;border-color:#d69e2e;border-color:rgba(214,158,46,var(--border-opacity))}.hover\:border-yellow-700:hover{--border-opacity:1;border-color:#b7791f;border-color:rgba(183,121,31,var(--border-opacity))}.hover\:border-yellow-800:hover{--border-opacity:1;border-color:#975a16;border-color:rgba(151,90,22,var(--border-opacity))}.hover\:border-yellow-900:hover{--border-opacity:1;border-color:#744210;border-color:rgba(116,66,16,var(--border-opacity))}.hover\:border-green-100:hover{--border-opacity:1;border-color:#f0fff4;border-color:rgba(240,255,244,var(--border-opacity))}.hover\:border-green-200:hover{--border-opacity:1;border-color:#c6f6d5;border-color:rgba(198,246,213,var(--border-opacity))}.hover\:border-green-300:hover{--border-opacity:1;border-color:#9ae6b4;border-color:rgba(154,230,180,var(--border-opacity))}.hover\:border-green-400:hover{--border-opacity:1;border-color:#68d391;border-color:rgba(104,211,145,var(--border-opacity))}.hover\:border-green-500:hover{--border-opacity:1;border-color:#48bb78;border-color:rgba(72,187,120,var(--border-opacity))}.hover\:border-green-600:hover{--border-opacity:1;border-color:#38a169;border-color:rgba(56,161,105,var(--border-opacity))}.hover\:border-green-700:hover{--border-opacity:1;border-color:#2f855a;border-color:rgba(47,133,90,var(--border-opacity))}.hover\:border-green-800:hover{--border-opacity:1;border-color:#276749;border-color:rgba(39,103,73,var(--border-opacity))}.hover\:border-green-900:hover{--border-opacity:1;border-color:#22543d;border-color:rgba(34,84,61,var(--border-opacity))}.hover\:border-teal-100:hover{--border-opacity:1;border-color:#e6fffa;border-color:rgba(230,255,250,var(--border-opacity))}.hover\:border-teal-200:hover{--border-opacity:1;border-color:#b2f5ea;border-color:rgba(178,245,234,var(--border-opacity))}.hover\:border-teal-300:hover{--border-opacity:1;border-color:#81e6d9;border-color:rgba(129,230,217,var(--border-opacity))}.hover\:border-teal-400:hover{--border-opacity:1;border-color:#4fd1c5;border-color:rgba(79,209,197,var(--border-opacity))}.hover\:border-teal-500:hover{--border-opacity:1;border-color:#38b2ac;border-color:rgba(56,178,172,var(--border-opacity))}.hover\:border-teal-600:hover{--border-opacity:1;border-color:#319795;border-color:rgba(49,151,149,var(--border-opacity))}.hover\:border-teal-700:hover{--border-opacity:1;border-color:#2c7a7b;border-color:rgba(44,122,123,var(--border-opacity))}.hover\:border-teal-800:hover{--border-opacity:1;border-color:#285e61;border-color:rgba(40,94,97,var(--border-opacity))}.hover\:border-teal-900:hover{--border-opacity:1;border-color:#234e52;border-color:rgba(35,78,82,var(--border-opacity))}.hover\:border-blue-100:hover{--border-opacity:1;border-color:#ebf8ff;border-color:rgba(235,248,255,var(--border-opacity))}.hover\:border-blue-200:hover{--border-opacity:1;border-color:#bee3f8;border-color:rgba(190,227,248,var(--border-opacity))}.hover\:border-blue-300:hover{--border-opacity:1;border-color:#90cdf4;border-color:rgba(144,205,244,var(--border-opacity))}.hover\:border-blue-400:hover{--border-opacity:1;border-color:#63b3ed;border-color:rgba(99,179,237,var(--border-opacity))}.hover\:border-blue-500:hover{--border-opacity:1;border-color:#4299e1;border-color:rgba(66,153,225,var(--border-opacity))}.hover\:border-blue-600:hover{--border-opacity:1;border-color:#3182ce;border-color:rgba(49,130,206,var(--border-opacity))}.hover\:border-blue-700:hover{--border-opacity:1;border-color:#2b6cb0;border-color:rgba(43,108,176,var(--border-opacity))}.hover\:border-blue-800:hover{--border-opacity:1;border-color:#2c5282;border-color:rgba(44,82,130,var(--border-opacity))}.hover\:border-blue-900:hover{--border-opacity:1;border-color:#2a4365;border-color:rgba(42,67,101,var(--border-opacity))}.hover\:border-indigo-100:hover{--border-opacity:1;border-color:#ebf4ff;border-color:rgba(235,244,255,var(--border-opacity))}.hover\:border-indigo-200:hover{--border-opacity:1;border-color:#c3dafe;border-color:rgba(195,218,254,var(--border-opacity))}.hover\:border-indigo-300:hover{--border-opacity:1;border-color:#a3bffa;border-color:rgba(163,191,250,var(--border-opacity))}.hover\:border-indigo-400:hover{--border-opacity:1;border-color:#7f9cf5;border-color:rgba(127,156,245,var(--border-opacity))}.hover\:border-indigo-500:hover{--border-opacity:1;border-color:#667eea;border-color:rgba(102,126,234,var(--border-opacity))}.hover\:border-indigo-600:hover{--border-opacity:1;border-color:#5a67d8;border-color:rgba(90,103,216,var(--border-opacity))}.hover\:border-indigo-700:hover{--border-opacity:1;border-color:#4c51bf;border-color:rgba(76,81,191,var(--border-opacity))}.hover\:border-indigo-800:hover{--border-opacity:1;border-color:#434190;border-color:rgba(67,65,144,var(--border-opacity))}.hover\:border-indigo-900:hover{--border-opacity:1;border-color:#3c366b;border-color:rgba(60,54,107,var(--border-opacity))}.hover\:border-purple-100:hover{--border-opacity:1;border-color:#faf5ff;border-color:rgba(250,245,255,var(--border-opacity))}.hover\:border-purple-200:hover{--border-opacity:1;border-color:#e9d8fd;border-color:rgba(233,216,253,var(--border-opacity))}.hover\:border-purple-300:hover{--border-opacity:1;border-color:#d6bcfa;border-color:rgba(214,188,250,var(--border-opacity))}.hover\:border-purple-400:hover{--border-opacity:1;border-color:#b794f4;border-color:rgba(183,148,244,var(--border-opacity))}.hover\:border-purple-500:hover{--border-opacity:1;border-color:#9f7aea;border-color:rgba(159,122,234,var(--border-opacity))}.hover\:border-purple-600:hover{--border-opacity:1;border-color:#805ad5;border-color:rgba(128,90,213,var(--border-opacity))}.hover\:border-purple-700:hover{--border-opacity:1;border-color:#6b46c1;border-color:rgba(107,70,193,var(--border-opacity))}.hover\:border-purple-800:hover{--border-opacity:1;border-color:#553c9a;border-color:rgba(85,60,154,var(--border-opacity))}.hover\:border-purple-900:hover{--border-opacity:1;border-color:#44337a;border-color:rgba(68,51,122,var(--border-opacity))}.hover\:border-pink-100:hover{--border-opacity:1;border-color:#fff5f7;border-color:rgba(255,245,247,var(--border-opacity))}.hover\:border-pink-200:hover{--border-opacity:1;border-color:#fed7e2;border-color:rgba(254,215,226,var(--border-opacity))}.hover\:border-pink-300:hover{--border-opacity:1;border-color:#fbb6ce;border-color:rgba(251,182,206,var(--border-opacity))}.hover\:border-pink-400:hover{--border-opacity:1;border-color:#f687b3;border-color:rgba(246,135,179,var(--border-opacity))}.hover\:border-pink-500:hover{--border-opacity:1;border-color:#ed64a6;border-color:rgba(237,100,166,var(--border-opacity))}.hover\:border-pink-600:hover{--border-opacity:1;border-color:#d53f8c;border-color:rgba(213,63,140,var(--border-opacity))}.hover\:border-pink-700:hover{--border-opacity:1;border-color:#b83280;border-color:rgba(184,50,128,var(--border-opacity))}.hover\:border-pink-800:hover{--border-opacity:1;border-color:#97266d;border-color:rgba(151,38,109,var(--border-opacity))}.hover\:border-pink-900:hover{--border-opacity:1;border-color:#702459;border-color:rgba(112,36,89,var(--border-opacity))}.focus\:border-transparent:focus{border-color:transparent}.focus\:border-current:focus{border-color:currentColor}.focus\:border-black:focus{--border-opacity:1;border-color:#000;border-color:rgba(0,0,0,var(--border-opacity))}.focus\:border-white:focus{--border-opacity:1;border-color:#fff;border-color:rgba(255,255,255,var(--border-opacity))}.focus\:border-gray-100:focus{--border-opacity:1;border-color:#f7fafc;border-color:rgba(247,250,252,var(--border-opacity))}.focus\:border-gray-200:focus{--border-opacity:1;border-color:#edf2f7;border-color:rgba(237,242,247,var(--border-opacity))}.focus\:border-gray-300:focus{--border-opacity:1;border-color:#e2e8f0;border-color:rgba(226,232,240,var(--border-opacity))}.focus\:border-gray-400:focus{--border-opacity:1;border-color:#cbd5e0;border-color:rgba(203,213,224,var(--border-opacity))}.focus\:border-gray-500:focus{--border-opacity:1;border-color:#a0aec0;border-color:rgba(160,174,192,var(--border-opacity))}.focus\:border-gray-600:focus{--border-opacity:1;border-color:#718096;border-color:rgba(113,128,150,var(--border-opacity))}.focus\:border-gray-700:focus{--border-opacity:1;border-color:#4a5568;border-color:rgba(74,85,104,var(--border-opacity))}.focus\:border-gray-800:focus{--border-opacity:1;border-color:#2d3748;border-color:rgba(45,55,72,var(--border-opacity))}.focus\:border-gray-900:focus{--border-opacity:1;border-color:#1a202c;border-color:rgba(26,32,44,var(--border-opacity))}.focus\:border-red-100:focus{--border-opacity:1;border-color:#fff5f5;border-color:rgba(255,245,245,var(--border-opacity))}.focus\:border-red-200:focus{--border-opacity:1;border-color:#fed7d7;border-color:rgba(254,215,215,var(--border-opacity))}.focus\:border-red-300:focus{--border-opacity:1;border-color:#feb2b2;border-color:rgba(254,178,178,var(--border-opacity))}.focus\:border-red-400:focus{--border-opacity:1;border-color:#fc8181;border-color:rgba(252,129,129,var(--border-opacity))}.focus\:border-red-500:focus{--border-opacity:1;border-color:#f56565;border-color:rgba(245,101,101,var(--border-opacity))}.focus\:border-red-600:focus{--border-opacity:1;border-color:#e53e3e;border-color:rgba(229,62,62,var(--border-opacity))}.focus\:border-red-700:focus{--border-opacity:1;border-color:#c53030;border-color:rgba(197,48,48,var(--border-opacity))}.focus\:border-red-800:focus{--border-opacity:1;border-color:#9b2c2c;border-color:rgba(155,44,44,var(--border-opacity))}.focus\:border-red-900:focus{--border-opacity:1;border-color:#742a2a;border-color:rgba(116,42,42,var(--border-opacity))}.focus\:border-orange-100:focus{--border-opacity:1;border-color:#fffaf0;border-color:rgba(255,250,240,var(--border-opacity))}.focus\:border-orange-200:focus{--border-opacity:1;border-color:#feebc8;border-color:rgba(254,235,200,var(--border-opacity))}.focus\:border-orange-300:focus{--border-opacity:1;border-color:#fbd38d;border-color:rgba(251,211,141,var(--border-opacity))}.focus\:border-orange-400:focus{--border-opacity:1;border-color:#f6ad55;border-color:rgba(246,173,85,var(--border-opacity))}.focus\:border-orange-500:focus{--border-opacity:1;border-color:#ed8936;border-color:rgba(237,137,54,var(--border-opacity))}.focus\:border-orange-600:focus{--border-opacity:1;border-color:#dd6b20;border-color:rgba(221,107,32,var(--border-opacity))}.focus\:border-orange-700:focus{--border-opacity:1;border-color:#c05621;border-color:rgba(192,86,33,var(--border-opacity))}.focus\:border-orange-800:focus{--border-opacity:1;border-color:#9c4221;border-color:rgba(156,66,33,var(--border-opacity))}.focus\:border-orange-900:focus{--border-opacity:1;border-color:#7b341e;border-color:rgba(123,52,30,var(--border-opacity))}.focus\:border-yellow-100:focus{--border-opacity:1;border-color:ivory;border-color:rgba(255,255,240,var(--border-opacity))}.focus\:border-yellow-200:focus{--border-opacity:1;border-color:#fefcbf;border-color:rgba(254,252,191,var(--border-opacity))}.focus\:border-yellow-300:focus{--border-opacity:1;border-color:#faf089;border-color:rgba(250,240,137,var(--border-opacity))}.focus\:border-yellow-400:focus{--border-opacity:1;border-color:#f6e05e;border-color:rgba(246,224,94,var(--border-opacity))}.focus\:border-yellow-500:focus{--border-opacity:1;border-color:#ecc94b;border-color:rgba(236,201,75,var(--border-opacity))}.focus\:border-yellow-600:focus{--border-opacity:1;border-color:#d69e2e;border-color:rgba(214,158,46,var(--border-opacity))}.focus\:border-yellow-700:focus{--border-opacity:1;border-color:#b7791f;border-color:rgba(183,121,31,var(--border-opacity))}.focus\:border-yellow-800:focus{--border-opacity:1;border-color:#975a16;border-color:rgba(151,90,22,var(--border-opacity))}.focus\:border-yellow-900:focus{--border-opacity:1;border-color:#744210;border-color:rgba(116,66,16,var(--border-opacity))}.focus\:border-green-100:focus{--border-opacity:1;border-color:#f0fff4;border-color:rgba(240,255,244,var(--border-opacity))}.focus\:border-green-200:focus{--border-opacity:1;border-color:#c6f6d5;border-color:rgba(198,246,213,var(--border-opacity))}.focus\:border-green-300:focus{--border-opacity:1;border-color:#9ae6b4;border-color:rgba(154,230,180,var(--border-opacity))}.focus\:border-green-400:focus{--border-opacity:1;border-color:#68d391;border-color:rgba(104,211,145,var(--border-opacity))}.focus\:border-green-500:focus{--border-opacity:1;border-color:#48bb78;border-color:rgba(72,187,120,var(--border-opacity))}.focus\:border-green-600:focus{--border-opacity:1;border-color:#38a169;border-color:rgba(56,161,105,var(--border-opacity))}.focus\:border-green-700:focus{--border-opacity:1;border-color:#2f855a;border-color:rgba(47,133,90,var(--border-opacity))}.focus\:border-green-800:focus{--border-opacity:1;border-color:#276749;border-color:rgba(39,103,73,var(--border-opacity))}.focus\:border-green-900:focus{--border-opacity:1;border-color:#22543d;border-color:rgba(34,84,61,var(--border-opacity))}.focus\:border-teal-100:focus{--border-opacity:1;border-color:#e6fffa;border-color:rgba(230,255,250,var(--border-opacity))}.focus\:border-teal-200:focus{--border-opacity:1;border-color:#b2f5ea;border-color:rgba(178,245,234,var(--border-opacity))}.focus\:border-teal-300:focus{--border-opacity:1;border-color:#81e6d9;border-color:rgba(129,230,217,var(--border-opacity))}.focus\:border-teal-400:focus{--border-opacity:1;border-color:#4fd1c5;border-color:rgba(79,209,197,var(--border-opacity))}.focus\:border-teal-500:focus{--border-opacity:1;border-color:#38b2ac;border-color:rgba(56,178,172,var(--border-opacity))}.focus\:border-teal-600:focus{--border-opacity:1;border-color:#319795;border-color:rgba(49,151,149,var(--border-opacity))}.focus\:border-teal-700:focus{--border-opacity:1;border-color:#2c7a7b;border-color:rgba(44,122,123,var(--border-opacity))}.focus\:border-teal-800:focus{--border-opacity:1;border-color:#285e61;border-color:rgba(40,94,97,var(--border-opacity))}.focus\:border-teal-900:focus{--border-opacity:1;border-color:#234e52;border-color:rgba(35,78,82,var(--border-opacity))}.focus\:border-blue-100:focus{--border-opacity:1;border-color:#ebf8ff;border-color:rgba(235,248,255,var(--border-opacity))}.focus\:border-blue-200:focus{--border-opacity:1;border-color:#bee3f8;border-color:rgba(190,227,248,var(--border-opacity))}.focus\:border-blue-300:focus{--border-opacity:1;border-color:#90cdf4;border-color:rgba(144,205,244,var(--border-opacity))}.focus\:border-blue-400:focus{--border-opacity:1;border-color:#63b3ed;border-color:rgba(99,179,237,var(--border-opacity))}.focus\:border-blue-500:focus{--border-opacity:1;border-color:#4299e1;border-color:rgba(66,153,225,var(--border-opacity))}.focus\:border-blue-600:focus{--border-opacity:1;border-color:#3182ce;border-color:rgba(49,130,206,var(--border-opacity))}.focus\:border-blue-700:focus{--border-opacity:1;border-color:#2b6cb0;border-color:rgba(43,108,176,var(--border-opacity))}.focus\:border-blue-800:focus{--border-opacity:1;border-color:#2c5282;border-color:rgba(44,82,130,var(--border-opacity))}.focus\:border-blue-900:focus{--border-opacity:1;border-color:#2a4365;border-color:rgba(42,67,101,var(--border-opacity))}.focus\:border-indigo-100:focus{--border-opacity:1;border-color:#ebf4ff;border-color:rgba(235,244,255,var(--border-opacity))}.focus\:border-indigo-200:focus{--border-opacity:1;border-color:#c3dafe;border-color:rgba(195,218,254,var(--border-opacity))}.focus\:border-indigo-300:focus{--border-opacity:1;border-color:#a3bffa;border-color:rgba(163,191,250,var(--border-opacity))}.focus\:border-indigo-400:focus{--border-opacity:1;border-color:#7f9cf5;border-color:rgba(127,156,245,var(--border-opacity))}.focus\:border-indigo-500:focus{--border-opacity:1;border-color:#667eea;border-color:rgba(102,126,234,var(--border-opacity))}.focus\:border-indigo-600:focus{--border-opacity:1;border-color:#5a67d8;border-color:rgba(90,103,216,var(--border-opacity))}.focus\:border-indigo-700:focus{--border-opacity:1;border-color:#4c51bf;border-color:rgba(76,81,191,var(--border-opacity))}.focus\:border-indigo-800:focus{--border-opacity:1;border-color:#434190;border-color:rgba(67,65,144,var(--border-opacity))}.focus\:border-indigo-900:focus{--border-opacity:1;border-color:#3c366b;border-color:rgba(60,54,107,var(--border-opacity))}.focus\:border-purple-100:focus{--border-opacity:1;border-color:#faf5ff;border-color:rgba(250,245,255,var(--border-opacity))}.focus\:border-purple-200:focus{--border-opacity:1;border-color:#e9d8fd;border-color:rgba(233,216,253,var(--border-opacity))}.focus\:border-purple-300:focus{--border-opacity:1;border-color:#d6bcfa;border-color:rgba(214,188,250,var(--border-opacity))}.focus\:border-purple-400:focus{--border-opacity:1;border-color:#b794f4;border-color:rgba(183,148,244,var(--border-opacity))}.focus\:border-purple-500:focus{--border-opacity:1;border-color:#9f7aea;border-color:rgba(159,122,234,var(--border-opacity))}.focus\:border-purple-600:focus{--border-opacity:1;border-color:#805ad5;border-color:rgba(128,90,213,var(--border-opacity))}.focus\:border-purple-700:focus{--border-opacity:1;border-color:#6b46c1;border-color:rgba(107,70,193,var(--border-opacity))}.focus\:border-purple-800:focus{--border-opacity:1;border-color:#553c9a;border-color:rgba(85,60,154,var(--border-opacity))}.focus\:border-purple-900:focus{--border-opacity:1;border-color:#44337a;border-color:rgba(68,51,122,var(--border-opacity))}.focus\:border-pink-100:focus{--border-opacity:1;border-color:#fff5f7;border-color:rgba(255,245,247,var(--border-opacity))}.focus\:border-pink-200:focus{--border-opacity:1;border-color:#fed7e2;border-color:rgba(254,215,226,var(--border-opacity))}.focus\:border-pink-300:focus{--border-opacity:1;border-color:#fbb6ce;border-color:rgba(251,182,206,var(--border-opacity))}.focus\:border-pink-400:focus{--border-opacity:1;border-color:#f687b3;border-color:rgba(246,135,179,var(--border-opacity))}.focus\:border-pink-500:focus{--border-opacity:1;border-color:#ed64a6;border-color:rgba(237,100,166,var(--border-opacity))}.focus\:border-pink-600:focus{--border-opacity:1;border-color:#d53f8c;border-color:rgba(213,63,140,var(--border-opacity))}.focus\:border-pink-700:focus{--border-opacity:1;border-color:#b83280;border-color:rgba(184,50,128,var(--border-opacity))}.focus\:border-pink-800:focus{--border-opacity:1;border-color:#97266d;border-color:rgba(151,38,109,var(--border-opacity))}.focus\:border-pink-900:focus{--border-opacity:1;border-color:#702459;border-color:rgba(112,36,89,var(--border-opacity))}.border-opacity-0{--border-opacity:0}.border-opacity-25{--border-opacity:0.25}.border-opacity-50{--border-opacity:0.5}.border-opacity-75{--border-opacity:0.75}.border-opacity-100{--border-opacity:1}.hover\:border-opacity-0:hover{--border-opacity:0}.hover\:border-opacity-25:hover{--border-opacity:0.25}.hover\:border-opacity-50:hover{--border-opacity:0.5}.hover\:border-opacity-75:hover{--border-opacity:0.75}.hover\:border-opacity-100:hover{--border-opacity:1}.focus\:border-opacity-0:focus{--border-opacity:0}.focus\:border-opacity-25:focus{--border-opacity:0.25}.focus\:border-opacity-50:focus{--border-opacity:0.5}.focus\:border-opacity-75:focus{--border-opacity:0.75}.focus\:border-opacity-100:focus{--border-opacity:1}.rounded-none{border-radius:0}.rounded-sm{border-radius:.125rem}.rounded{border-radius:.25rem}.rounded-md{border-radius:.375rem}.rounded-lg{border-radius:.5rem}.rounded-xl{border-radius:.75rem}.rounded-2xl{border-radius:1rem}.rounded-3xl{border-radius:1.5rem}.rounded-full{border-radius:9999px}.rounded-t-none{border-top-left-radius:0;border-top-right-radius:0}.rounded-r-none{border-top-right-radius:0;border-bottom-right-radius:0}.rounded-b-none{border-bottom-right-radius:0;border-bottom-left-radius:0}.rounded-l-none{border-top-left-radius:0;border-bottom-left-radius:0}.rounded-t-sm{border-top-left-radius:.125rem;border-top-right-radius:.125rem}.rounded-r-sm{border-top-right-radius:.125rem;border-bottom-right-radius:.125rem}.rounded-b-sm{border-bottom-right-radius:.125rem;border-bottom-left-radius:.125rem}.rounded-l-sm{border-top-left-radius:.125rem;border-bottom-left-radius:.125rem}.rounded-t{border-top-left-radius:.25rem;border-top-right-radius:.25rem}.rounded-r{border-top-right-radius:.25rem;border-bottom-right-radius:.25rem}.rounded-b{border-bottom-right-radius:.25rem;border-bottom-left-radius:.25rem}.rounded-l{border-top-left-radius:.25rem;border-bottom-left-radius:.25rem}.rounded-t-md{border-top-left-radius:.375rem;border-top-right-radius:.375rem}.rounded-r-md{border-top-right-radius:.375rem;border-bottom-right-radius:.375rem}.rounded-b-md{border-bottom-right-radius:.375rem;border-bottom-left-radius:.375rem}.rounded-l-md{border-top-left-radius:.375rem;border-bottom-left-radius:.375rem}.rounded-t-lg{border-top-left-radius:.5rem;border-top-right-radius:.5rem}.rounded-r-lg{border-top-right-radius:.5rem;border-bottom-right-radius:.5rem}.rounded-b-lg{border-bottom-right-radius:.5rem;border-bottom-left-radius:.5rem}.rounded-l-lg{border-top-left-radius:.5rem;border-bottom-left-radius:.5rem}.rounded-t-xl{border-top-left-radius:.75rem;border-top-right-radius:.75rem}.rounded-r-xl{border-top-right-radius:.75rem;border-bottom-right-radius:.75rem}.rounded-b-xl{border-bottom-right-radius:.75rem;border-bottom-left-radius:.75rem}.rounded-l-xl{border-top-left-radius:.75rem;border-bottom-left-radius:.75rem}.rounded-t-2xl{border-top-left-radius:1rem;border-top-right-radius:1rem}.rounded-r-2xl{border-top-right-radius:1rem;border-bottom-right-radius:1rem}.rounded-b-2xl{border-bottom-right-radius:1rem;border-bottom-left-radius:1rem}.rounded-l-2xl{border-top-left-radius:1rem;border-bottom-left-radius:1rem}.rounded-t-3xl{border-top-left-radius:1.5rem;border-top-right-radius:1.5rem}.rounded-r-3xl{border-top-right-radius:1.5rem;border-bottom-right-radius:1.5rem}.rounded-b-3xl{border-bottom-right-radius:1.5rem;border-bottom-left-radius:1.5rem}.rounded-l-3xl{border-top-left-radius:1.5rem;border-bottom-left-radius:1.5rem}.rounded-t-full{border-top-left-radius:9999px;border-top-right-radius:9999px}.rounded-r-full{border-top-right-radius:9999px;border-bottom-right-radius:9999px}.rounded-b-full{border-bottom-right-radius:9999px;border-bottom-left-radius:9999px}.rounded-l-full{border-top-left-radius:9999px;border-bottom-left-radius:9999px}.rounded-tl-none{border-top-left-radius:0}.rounded-tr-none{border-top-right-radius:0}.rounded-br-none{border-bottom-right-radius:0}.rounded-bl-none{border-bottom-left-radius:0}.rounded-tl-sm{border-top-left-radius:.125rem}.rounded-tr-sm{border-top-right-radius:.125rem}.rounded-br-sm{border-bottom-right-radius:.125rem}.rounded-bl-sm{border-bottom-left-radius:.125rem}.rounded-tl{border-top-left-radius:.25rem}.rounded-tr{border-top-right-radius:.25rem}.rounded-br{border-bottom-right-radius:.25rem}.rounded-bl{border-bottom-left-radius:.25rem}.rounded-tl-md{border-top-left-radius:.375rem}.rounded-tr-md{border-top-right-radius:.375rem}.rounded-br-md{border-bottom-right-radius:.375rem}.rounded-bl-md{border-bottom-left-radius:.375rem}.rounded-tl-lg{border-top-left-radius:.5rem}.rounded-tr-lg{border-top-right-radius:.5rem}.rounded-br-lg{border-bottom-right-radius:.5rem}.rounded-bl-lg{border-bottom-left-radius:.5rem}.rounded-tl-xl{border-top-left-radius:.75rem}.rounded-tr-xl{border-top-right-radius:.75rem}.rounded-br-xl{border-bottom-right-radius:.75rem}.rounded-bl-xl{border-bottom-left-radius:.75rem}.rounded-tl-2xl{border-top-left-radius:1rem}.rounded-tr-2xl{border-top-right-radius:1rem}.rounded-br-2xl{border-bottom-right-radius:1rem}.rounded-bl-2xl{border-bottom-left-radius:1rem}.rounded-tl-3xl{border-top-left-radius:1.5rem}.rounded-tr-3xl{border-top-right-radius:1.5rem}.rounded-br-3xl{border-bottom-right-radius:1.5rem}.rounded-bl-3xl{border-bottom-left-radius:1.5rem}.rounded-tl-full{border-top-left-radius:9999px}.rounded-tr-full{border-top-right-radius:9999px}.rounded-br-full{border-bottom-right-radius:9999px}.rounded-bl-full{border-bottom-left-radius:9999px}.border-solid{border-style:solid}.border-dashed{border-style:dashed}.border-dotted{border-style:dotted}.border-double{border-style:double}.border-none{border-style:none}.border-0{border-width:0}.border-2{border-width:2px}.border-4{border-width:4px}.border-8{border-width:8px}.border{border-width:1px}.border-t-0{border-top-width:0}.border-r-0{border-right-width:0}.border-b-0{border-bottom-width:0}.border-l-0{border-left-width:0}.border-t-2{border-top-width:2px}.border-r-2{border-right-width:2px}.border-b-2{border-bottom-width:2px}.border-l-2{border-left-width:2px}.border-t-4{border-top-width:4px}.border-r-4{border-right-width:4px}.border-b-4{border-bottom-width:4px}.border-l-4{border-left-width:4px}.border-t-8{border-top-width:8px}.border-r-8{border-right-width:8px}.border-b-8{border-bottom-width:8px}.border-l-8{border-left-width:8px}.border-t{border-top-width:1px}.border-r{border-right-width:1px}.border-b{border-bottom-width:1px}.border-l{border-left-width:1px}.box-border{box-sizing:border-box}.box-content{box-sizing:content-box}.cursor-auto{cursor:auto}.cursor-default{cursor:default}.cursor-pointer{cursor:pointer}.cursor-wait{cursor:wait}.cursor-text{cursor:text}.cursor-move{cursor:move}.cursor-not-allowed{cursor:not-allowed}.block{display:block}.inline-block{display:inline-block}.inline{display:inline}.flex{display:flex}.inline-flex{display:inline-flex}.table{display:table}.table-caption{display:table-caption}.table-cell{display:table-cell}.table-column{display:table-column}.table-column-group{display:table-column-group}.table-footer-group{display:table-footer-group}.table-header-group{display:table-header-group}.table-row-group{display:table-row-group}.table-row{display:table-row}.flow-root{display:flow-root}.grid{display:grid}.inline-grid{display:inline-grid}.contents{display:contents}.hidden{display:none}.flex-row{flex-direction:row}.flex-row-reverse{flex-direction:row-reverse}.flex-col{flex-direction:column}.flex-col-reverse{flex-direction:column-reverse}.flex-wrap{flex-wrap:wrap}.flex-wrap-reverse{flex-wrap:wrap-reverse}.flex-no-wrap{flex-wrap:nowrap}.place-items-auto{place-items:auto}.place-items-start{place-items:start}.place-items-end{place-items:end}.place-items-center{place-items:center}.place-items-stretch{place-items:stretch}.place-content-center{place-content:center}.place-content-start{place-content:start}.place-content-end{place-content:end}.place-content-between{place-content:space-between}.place-content-around{place-content:space-around}.place-content-evenly{place-content:space-evenly}.place-content-stretch{place-content:stretch}.place-self-auto{place-self:auto}.place-self-start{place-self:start}.place-self-end{place-self:end}.place-self-center{place-self:center}.place-self-stretch{place-self:stretch}.items-start{align-items:flex-start}.items-end{align-items:flex-end}.items-center{align-items:center}.items-baseline{align-items:baseline}.items-stretch{align-items:stretch}.content-center{align-content:center}.content-start{align-content:flex-start}.content-end{align-content:flex-end}.content-between{align-content:space-between}.content-around{align-content:space-around}.content-evenly{align-content:space-evenly}.self-auto{align-self:auto}.self-start{align-self:flex-start}.self-end{align-self:flex-end}.self-center{align-self:center}.self-stretch{align-self:stretch}.justify-items-auto{justify-items:auto}.justify-items-start{justify-items:start}.justify-items-end{justify-items:end}.justify-items-center{justify-items:center}.justify-items-stretch{justify-items:stretch}.justify-start{justify-content:flex-start}.justify-end{justify-content:flex-end}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.justify-around{justify-content:space-around}.justify-evenly{justify-content:space-evenly}.justify-self-auto{justify-self:auto}.justify-self-start{justify-self:start}.justify-self-end{justify-self:end}.justify-self-center{justify-self:center}.justify-self-stretch{justify-self:stretch}.flex-1{flex:1 1 0%}.flex-auto{flex:1 1 auto}.flex-initial{flex:0 1 auto}.flex-none{flex:none}.flex-grow-0{flex-grow:0}.flex-grow{flex-grow:1}.flex-shrink-0{flex-shrink:0}.flex-shrink{flex-shrink:1}.order-1{order:1}.order-2{order:2}.order-3{order:3}.order-4{order:4}.order-5{order:5}.order-6{order:6}.order-7{order:7}.order-8{order:8}.order-9{order:9}.order-10{order:10}.order-11{order:11}.order-12{order:12}.order-first{order:-9999}.order-last{order:9999}.order-none{order:0}.float-right{float:right}.float-left{float:left}.float-none{float:none}.clearfix:after{content:"";display:table;clear:both}.clear-left{clear:left}.clear-right{clear:right}.clear-both{clear:both}.clear-none{clear:none}.font-sans{font-family:system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji"}.font-serif{font-family:Georgia,Cambria,"Times New Roman",Times,serif}.font-mono{font-family:Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace}.font-hairline{font-weight:100}.font-thin{font-weight:200}.font-light{font-weight:300}.font-normal{font-weight:400}.font-medium{font-weight:500}.font-semibold{font-weight:600}.font-bold{font-weight:700}.font-extrabold{font-weight:800}.font-black{font-weight:900}.hover\:font-hairline:hover{font-weight:100}.hover\:font-thin:hover{font-weight:200}.hover\:font-light:hover{font-weight:300}.hover\:font-normal:hover{font-weight:400}.hover\:font-medium:hover{font-weight:500}.hover\:font-semibold:hover{font-weight:600}.hover\:font-bold:hover{font-weight:700}.hover\:font-extrabold:hover{font-weight:800}.hover\:font-black:hover{font-weight:900}.focus\:font-hairline:focus{font-weight:100}.focus\:font-thin:focus{font-weight:200}.focus\:font-light:focus{font-weight:300}.focus\:font-normal:focus{font-weight:400}.focus\:font-medium:focus{font-weight:500}.focus\:font-semibold:focus{font-weight:600}.focus\:font-bold:focus{font-weight:700}.focus\:font-extrabold:focus{font-weight:800}.focus\:font-black:focus{font-weight:900}.h-0{height:0}.h-1{height:.25rem}.h-2{height:.5rem}.h-3{height:.75rem}.h-4{height:1rem}.h-5{height:1.25rem}.h-6{height:1.5rem}.h-8{height:2rem}.h-10{height:2.5rem}.h-12{height:3rem}.h-16{height:4rem}.h-20{height:5rem}.h-24{height:6rem}.h-32{height:8rem}.h-40{height:10rem}.h-48{height:12rem}.h-56{height:14rem}.h-64{height:16rem}.h-auto{height:auto}.h-px{height:1px}.h-full{height:100%}.h-screen{height:100vh}.text-xs{font-size:.75rem}.text-sm{font-size:.875rem}.text-base{font-size:1rem}.text-lg{font-size:1.125rem}.text-xl{font-size:1.25rem}.text-2xl{font-size:1.5rem}.text-3xl{font-size:1.875rem}.text-4xl{font-size:2.25rem}.text-5xl{font-size:3rem}.text-6xl{font-size:4rem}.leading-3{line-height:.75rem}.leading-4{line-height:1rem}.leading-5{line-height:1.25rem}.leading-6{line-height:1.5rem}.leading-7{line-height:1.75rem}.leading-8{line-height:2rem}.leading-9{line-height:2.25rem}.leading-10{line-height:2.5rem}.leading-none{line-height:1}.leading-tight{line-height:1.25}.leading-snug{line-height:1.375}.leading-normal{line-height:1.5}.leading-relaxed{line-height:1.625}.leading-loose{line-height:2}.list-inside{list-style-position:inside}.list-outside{list-style-position:outside}.list-none{list-style-type:none}.list-disc{list-style-type:disc}.list-decimal{list-style-type:decimal}.m-0{margin:0}.m-1{margin:.25rem}.m-2{margin:.5rem}.m-3{margin:.75rem}.m-4{margin:1rem}.m-5{margin:1.25rem}.m-6{margin:1.5rem}.m-8{margin:2rem}.m-10{margin:2.5rem}.m-12{margin:3rem}.m-16{margin:4rem}.m-20{margin:5rem}.m-24{margin:6rem}.m-32{margin:8rem}.m-40{margin:10rem}.m-48{margin:12rem}.m-56{margin:14rem}.m-64{margin:16rem}.m-auto{margin:auto}.m-px{margin:1px}.-m-1{margin:-.25rem}.-m-2{margin:-.5rem}.-m-3{margin:-.75rem}.-m-4{margin:-1rem}.-m-5{margin:-1.25rem}.-m-6{margin:-1.5rem}.-m-8{margin:-2rem}.-m-10{margin:-2.5rem}.-m-12{margin:-3rem}.-m-16{margin:-4rem}.-m-20{margin:-5rem}.-m-24{margin:-6rem}.-m-32{margin:-8rem}.-m-40{margin:-10rem}.-m-48{margin:-12rem}.-m-56{margin:-14rem}.-m-64{margin:-16rem}.-m-px{margin:-1px}.my-0{margin-top:0;margin-bottom:0}.mx-0{margin-left:0;margin-right:0}.my-1{margin-top:.25rem;margin-bottom:.25rem}.mx-1{margin-left:.25rem;margin-right:.25rem}.my-2{margin-top:.5rem;margin-bottom:.5rem}.mx-2{margin-left:.5rem;margin-right:.5rem}.my-3{margin-top:.75rem;margin-bottom:.75rem}.mx-3{margin-left:.75rem;margin-right:.75rem}.my-4{margin-top:1rem;margin-bottom:1rem}.mx-4{margin-left:1rem;margin-right:1rem}.my-5{margin-top:1.25rem;margin-bottom:1.25rem}.mx-5{margin-left:1.25rem;margin-right:1.25rem}.my-6{margin-top:1.5rem;margin-bottom:1.5rem}.mx-6{margin-left:1.5rem;margin-right:1.5rem}.my-8{margin-top:2rem;margin-bottom:2rem}.mx-8{margin-left:2rem;margin-right:2rem}.my-10{margin-top:2.5rem;margin-bottom:2.5rem}.mx-10{margin-left:2.5rem;margin-right:2.5rem}.my-12{margin-top:3rem;margin-bottom:3rem}.mx-12{margin-left:3rem;margin-right:3rem}.my-16{margin-top:4rem;margin-bottom:4rem}.mx-16{margin-left:4rem;margin-right:4rem}.my-20{margin-top:5rem;margin-bottom:5rem}.mx-20{margin-left:5rem;margin-right:5rem}.my-24{margin-top:6rem;margin-bottom:6rem}.mx-24{margin-left:6rem;margin-right:6rem}.my-32{margin-top:8rem;margin-bottom:8rem}.mx-32{margin-left:8rem;margin-right:8rem}.my-40{margin-top:10rem;margin-bottom:10rem}.mx-40{margin-left:10rem;margin-right:10rem}.my-48{margin-top:12rem;margin-bottom:12rem}.mx-48{margin-left:12rem;margin-right:12rem}.my-56{margin-top:14rem;margin-bottom:14rem}.mx-56{margin-left:14rem;margin-right:14rem}.my-64{margin-top:16rem;margin-bottom:16rem}.mx-64{margin-left:16rem;margin-right:16rem}.my-auto{margin-top:auto;margin-bottom:auto}.mx-auto{margin-left:auto;margin-right:auto}.my-px{margin-top:1px;margin-bottom:1px}.mx-px{margin-left:1px;margin-right:1px}.-my-1{margin-top:-.25rem;margin-bottom:-.25rem}.-mx-1{margin-left:-.25rem;margin-right:-.25rem}.-my-2{margin-top:-.5rem;margin-bottom:-.5rem}.-mx-2{margin-left:-.5rem;margin-right:-.5rem}.-my-3{margin-top:-.75rem;margin-bottom:-.75rem}.-mx-3{margin-left:-.75rem;margin-right:-.75rem}.-my-4{margin-top:-1rem;margin-bottom:-1rem}.-mx-4{margin-left:-1rem;margin-right:-1rem}.-my-5{margin-top:-1.25rem;margin-bottom:-1.25rem}.-mx-5{margin-left:-1.25rem;margin-right:-1.25rem}.-my-6{margin-top:-1.5rem;margin-bottom:-1.5rem}.-mx-6{margin-left:-1.5rem;margin-right:-1.5rem}.-my-8{margin-top:-2rem;margin-bottom:-2rem}.-mx-8{margin-left:-2rem;margin-right:-2rem}.-my-10{margin-top:-2.5rem;margin-bottom:-2.5rem}.-mx-10{margin-left:-2.5rem;margin-right:-2.5rem}.-my-12{margin-top:-3rem;margin-bottom:-3rem}.-mx-12{margin-left:-3rem;margin-right:-3rem}.-my-16{margin-top:-4rem;margin-bottom:-4rem}.-mx-16{margin-left:-4rem;margin-right:-4rem}.-my-20{margin-top:-5rem;margin-bottom:-5rem}.-mx-20{margin-left:-5rem;margin-right:-5rem}.-my-24{margin-top:-6rem;margin-bottom:-6rem}.-mx-24{margin-left:-6rem;margin-right:-6rem}.-my-32{margin-top:-8rem;margin-bottom:-8rem}.-mx-32{margin-left:-8rem;margin-right:-8rem}.-my-40{margin-top:-10rem;margin-bottom:-10rem}.-mx-40{margin-left:-10rem;margin-right:-10rem}.-my-48{margin-top:-12rem;margin-bottom:-12rem}.-mx-48{margin-left:-12rem;margin-right:-12rem}.-my-56{margin-top:-14rem;margin-bottom:-14rem}.-mx-56{margin-left:-14rem;margin-right:-14rem}.-my-64{margin-top:-16rem;margin-bottom:-16rem}.-mx-64{margin-left:-16rem;margin-right:-16rem}.-my-px{margin-top:-1px;margin-bottom:-1px}.-mx-px{margin-left:-1px;margin-right:-1px}.mt-0{margin-top:0}.mr-0{margin-right:0}.mb-0{margin-bottom:0}.ml-0{margin-left:0}.mt-1{margin-top:.25rem}.mr-1{margin-right:.25rem}.mb-1{margin-bottom:.25rem}.ml-1{margin-left:.25rem}.mt-2{margin-top:.5rem}.mr-2{margin-right:.5rem}.mb-2{margin-bottom:.5rem}.ml-2{margin-left:.5rem}.mt-3{margin-top:.75rem}.mr-3{margin-right:.75rem}.mb-3{margin-bottom:.75rem}.ml-3{margin-left:.75rem}.mt-4{margin-top:1rem}.mr-4{margin-right:1rem}.mb-4{margin-bottom:1rem}.ml-4{margin-left:1rem}.mt-5{margin-top:1.25rem}.mr-5{margin-right:1.25rem}.mb-5{margin-bottom:1.25rem}.ml-5{margin-left:1.25rem}.mt-6{margin-top:1.5rem}.mr-6{margin-right:1.5rem}.mb-6{margin-bottom:1.5rem}.ml-6{margin-left:1.5rem}.mt-8{margin-top:2rem}.mr-8{margin-right:2rem}.mb-8{margin-bottom:2rem}.ml-8{margin-left:2rem}.mt-10{margin-top:2.5rem}.mr-10{margin-right:2.5rem}.mb-10{margin-bottom:2.5rem}.ml-10{margin-left:2.5rem}.mt-12{margin-top:3rem}.mr-12{margin-right:3rem}.mb-12{margin-bottom:3rem}.ml-12{margin-left:3rem}.mt-16{margin-top:4rem}.mr-16{margin-right:4rem}.mb-16{margin-bottom:4rem}.ml-16{margin-left:4rem}.mt-20{margin-top:5rem}.mr-20{margin-right:5rem}.mb-20{margin-bottom:5rem}.ml-20{margin-left:5rem}.mt-24{margin-top:6rem}.mr-24{margin-right:6rem}.mb-24{margin-bottom:6rem}.ml-24{margin-left:6rem}.mt-32{margin-top:8rem}.mr-32{margin-right:8rem}.mb-32{margin-bottom:8rem}.ml-32{margin-left:8rem}.mt-40{margin-top:10rem}.mr-40{margin-right:10rem}.mb-40{margin-bottom:10rem}.ml-40{margin-left:10rem}.mt-48{margin-top:12rem}.mr-48{margin-right:12rem}.mb-48{margin-bottom:12rem}.ml-48{margin-left:12rem}.mt-56{margin-top:14rem}.mr-56{margin-right:14rem}.mb-56{margin-bottom:14rem}.ml-56{margin-left:14rem}.mt-64{margin-top:16rem}.mr-64{margin-right:16rem}.mb-64{margin-bottom:16rem}.ml-64{margin-left:16rem}.mt-auto{margin-top:auto}.mr-auto{margin-right:auto}.mb-auto{margin-bottom:auto}.ml-auto{margin-left:auto}.mt-px{margin-top:1px}.mr-px{margin-right:1px}.mb-px{margin-bottom:1px}.ml-px{margin-left:1px}.-mt-1{margin-top:-.25rem}.-mr-1{margin-right:-.25rem}.-mb-1{margin-bottom:-.25rem}.-ml-1{margin-left:-.25rem}.-mt-2{margin-top:-.5rem}.-mr-2{margin-right:-.5rem}.-mb-2{margin-bottom:-.5rem}.-ml-2{margin-left:-.5rem}.-mt-3{margin-top:-.75rem}.-mr-3{margin-right:-.75rem}.-mb-3{margin-bottom:-.75rem}.-ml-3{margin-left:-.75rem}.-mt-4{margin-top:-1rem}.-mr-4{margin-right:-1rem}.-mb-4{margin-bottom:-1rem}.-ml-4{margin-left:-1rem}.-mt-5{margin-top:-1.25rem}.-mr-5{margin-right:-1.25rem}.-mb-5{margin-bottom:-1.25rem}.-ml-5{margin-left:-1.25rem}.-mt-6{margin-top:-1.5rem}.-mr-6{margin-right:-1.5rem}.-mb-6{margin-bottom:-1.5rem}.-ml-6{margin-left:-1.5rem}.-mt-8{margin-top:-2rem}.-mr-8{margin-right:-2rem}.-mb-8{margin-bottom:-2rem}.-ml-8{margin-left:-2rem}.-mt-10{margin-top:-2.5rem}.-mr-10{margin-right:-2.5rem}.-mb-10{margin-bottom:-2.5rem}.-ml-10{margin-left:-2.5rem}.-mt-12{margin-top:-3rem}.-mr-12{margin-right:-3rem}.-mb-12{margin-bottom:-3rem}.-ml-12{margin-left:-3rem}.-mt-16{margin-top:-4rem}.-mr-16{margin-right:-4rem}.-mb-16{margin-bottom:-4rem}.-ml-16{margin-left:-4rem}.-mt-20{margin-top:-5rem}.-mr-20{margin-right:-5rem}.-mb-20{margin-bottom:-5rem}.-ml-20{margin-left:-5rem}.-mt-24{margin-top:-6rem}.-mr-24{margin-right:-6rem}.-mb-24{margin-bottom:-6rem}.-ml-24{margin-left:-6rem}.-mt-32{margin-top:-8rem}.-mr-32{margin-right:-8rem}.-mb-32{margin-bottom:-8rem}.-ml-32{margin-left:-8rem}.-mt-40{margin-top:-10rem}.-mr-40{margin-right:-10rem}.-mb-40{margin-bottom:-10rem}.-ml-40{margin-left:-10rem}.-mt-48{margin-top:-12rem}.-mr-48{margin-right:-12rem}.-mb-48{margin-bottom:-12rem}.-ml-48{margin-left:-12rem}.-mt-56{margin-top:-14rem}.-mr-56{margin-right:-14rem}.-mb-56{margin-bottom:-14rem}.-ml-56{margin-left:-14rem}.-mt-64{margin-top:-16rem}.-mr-64{margin-right:-16rem}.-mb-64{margin-bottom:-16rem}.-ml-64{margin-left:-16rem}.-mt-px{margin-top:-1px}.-mr-px{margin-right:-1px}.-mb-px{margin-bottom:-1px}.-ml-px{margin-left:-1px}.max-h-full{max-height:100%}.max-h-screen{max-height:100vh}.max-w-none{max-width:none}.max-w-xs{max-width:20rem}.max-w-sm{max-width:24rem}.max-w-md{max-width:28rem}.max-w-lg{max-width:32rem}.max-w-xl{max-width:36rem}.max-w-2xl{max-width:42rem}.max-w-3xl{max-width:48rem}.max-w-4xl{max-width:56rem}.max-w-5xl{max-width:64rem}.max-w-6xl{max-width:72rem}.max-w-full{max-width:100%}.max-w-screen-sm{max-width:640px}.max-w-screen-md{max-width:768px}.max-w-screen-lg{max-width:1024px}.max-w-screen-xl{max-width:1280px}.min-h-0{min-height:0}.min-h-full{min-height:100%}.min-h-screen{min-height:100vh}.min-w-0{min-width:0}.min-w-full{min-width:100%}.object-contain{object-fit:contain}.object-cover{object-fit:cover}.object-fill{object-fit:fill}.object-none{object-fit:none}.object-scale-down{object-fit:scale-down}.object-bottom{object-position:bottom}.object-center{object-position:center}.object-left{object-position:left}.object-left-bottom{object-position:left bottom}.object-left-top{object-position:left top}.object-right{object-position:right}.object-right-bottom{object-position:right bottom}.object-right-top{object-position:right top}.object-top{object-position:top}.opacity-0{opacity:0}.opacity-25{opacity:.25}.opacity-50{opacity:.5}.opacity-75{opacity:.75}.opacity-100{opacity:1}.hover\:opacity-0:hover{opacity:0}.hover\:opacity-25:hover{opacity:.25}.hover\:opacity-50:hover{opacity:.5}.hover\:opacity-75:hover{opacity:.75}.hover\:opacity-100:hover{opacity:1}.focus\:opacity-0:focus{opacity:0}.focus\:opacity-25:focus{opacity:.25}.focus\:opacity-50:focus{opacity:.5}.focus\:opacity-75:focus{opacity:.75}.focus\:opacity-100:focus{opacity:1}.outline-none{outline:2px solid transparent;outline-offset:2px}.outline-white{outline:2px dotted #fff;outline-offset:2px}.outline-black{outline:2px dotted #000;outline-offset:2px}.focus\:outline-none:focus{outline:2px solid transparent;outline-offset:2px}.focus\:outline-white:focus{outline:2px dotted #fff;outline-offset:2px}.focus\:outline-black:focus{outline:2px dotted #000;outline-offset:2px}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-visible{overflow:visible}.overflow-scroll{overflow:scroll}.overflow-x-auto{overflow-x:auto}.overflow-y-auto{overflow-y:auto}.overflow-x-hidden{overflow-x:hidden}.overflow-y-hidden{overflow-y:hidden}.overflow-x-visible{overflow-x:visible}.overflow-y-visible{overflow-y:visible}.overflow-x-scroll{overflow-x:scroll}.overflow-y-scroll{overflow-y:scroll}.scrolling-touch{-webkit-overflow-scrolling:touch}.scrolling-auto{-webkit-overflow-scrolling:auto}.overscroll-auto{-ms-scroll-chaining:chained;overscroll-behavior:auto}.overscroll-contain{-ms-scroll-chaining:none;overscroll-behavior:contain}.overscroll-none{-ms-scroll-chaining:none;overscroll-behavior:none}.overscroll-y-auto{overscroll-behavior-y:auto}.overscroll-y-contain{overscroll-behavior-y:contain}.overscroll-y-none{overscroll-behavior-y:none}.overscroll-x-auto{overscroll-behavior-x:auto}.overscroll-x-contain{overscroll-behavior-x:contain}.overscroll-x-none{overscroll-behavior-x:none}.p-0{padding:0}.p-1{padding:.25rem}.p-2{padding:.5rem}.p-3{padding:.75rem}.p-4{padding:1rem}.p-5{padding:1.25rem}.p-6{padding:1.5rem}.p-8{padding:2rem}.p-10{padding:2.5rem}.p-12{padding:3rem}.p-16{padding:4rem}.p-20{padding:5rem}.p-24{padding:6rem}.p-32{padding:8rem}.p-40{padding:10rem}.p-48{padding:12rem}.p-56{padding:14rem}.p-64{padding:16rem}.p-px{padding:1px}.py-0{padding-top:0;padding-bottom:0}.px-0{padding-left:0;padding-right:0}.py-1{padding-top:.25rem;padding-bottom:.25rem}.px-1{padding-left:.25rem;padding-right:.25rem}.py-2{padding-top:.5rem;padding-bottom:.5rem}.px-2{padding-left:.5rem;padding-right:.5rem}.py-3{padding-top:.75rem;padding-bottom:.75rem}.px-3{padding-left:.75rem;padding-right:.75rem}.py-4{padding-top:1rem;padding-bottom:1rem}.px-4{padding-left:1rem;padding-right:1rem}.py-5{padding-top:1.25rem;padding-bottom:1.25rem}.px-5{padding-left:1.25rem;padding-right:1.25rem}.py-6{padding-top:1.5rem;padding-bottom:1.5rem}.px-6{padding-left:1.5rem;padding-right:1.5rem}.py-8{padding-top:2rem;padding-bottom:2rem}.px-8{padding-left:2rem;padding-right:2rem}.py-10{padding-top:2.5rem;padding-bottom:2.5rem}.px-10{padding-left:2.5rem;padding-right:2.5rem}.py-12{padding-top:3rem;padding-bottom:3rem}.px-12{padding-left:3rem;padding-right:3rem}.py-16{padding-top:4rem;padding-bottom:4rem}.px-16{padding-left:4rem;padding-right:4rem}.py-20{padding-top:5rem;padding-bottom:5rem}.px-20{padding-left:5rem;padding-right:5rem}.py-24{padding-top:6rem;padding-bottom:6rem}.px-24{padding-left:6rem;padding-right:6rem}.py-32{padding-top:8rem;padding-bottom:8rem}.px-32{padding-left:8rem;padding-right:8rem}.py-40{padding-top:10rem;padding-bottom:10rem}.px-40{padding-left:10rem;padding-right:10rem}.py-48{padding-top:12rem;padding-bottom:12rem}.px-48{padding-left:12rem;padding-right:12rem}.py-56{padding-top:14rem;padding-bottom:14rem}.px-56{padding-left:14rem;padding-right:14rem}.py-64{padding-top:16rem;padding-bottom:16rem}.px-64{padding-left:16rem;padding-right:16rem}.py-px{padding-top:1px;padding-bottom:1px}.px-px{padding-left:1px;padding-right:1px}.pt-0{padding-top:0}.pr-0{padding-right:0}.pb-0{padding-bottom:0}.pl-0{padding-left:0}.pt-1{padding-top:.25rem}.pr-1{padding-right:.25rem}.pb-1{padding-bottom:.25rem}.pl-1{padding-left:.25rem}.pt-2{padding-top:.5rem}.pr-2{padding-right:.5rem}.pb-2{padding-bottom:.5rem}.pl-2{padding-left:.5rem}.pt-3{padding-top:.75rem}.pr-3{padding-right:.75rem}.pb-3{padding-bottom:.75rem}.pl-3{padding-left:.75rem}.pt-4{padding-top:1rem}.pr-4{padding-right:1rem}.pb-4{padding-bottom:1rem}.pl-4{padding-left:1rem}.pt-5{padding-top:1.25rem}.pr-5{padding-right:1.25rem}.pb-5{padding-bottom:1.25rem}.pl-5{padding-left:1.25rem}.pt-6{padding-top:1.5rem}.pr-6{padding-right:1.5rem}.pb-6{padding-bottom:1.5rem}.pl-6{padding-left:1.5rem}.pt-8{padding-top:2rem}.pr-8{padding-right:2rem}.pb-8{padding-bottom:2rem}.pl-8{padding-left:2rem}.pt-10{padding-top:2.5rem}.pr-10{padding-right:2.5rem}.pb-10{padding-bottom:2.5rem}.pl-10{padding-left:2.5rem}.pt-12{padding-top:3rem}.pr-12{padding-right:3rem}.pb-12{padding-bottom:3rem}.pl-12{padding-left:3rem}.pt-16{padding-top:4rem}.pr-16{padding-right:4rem}.pb-16{padding-bottom:4rem}.pl-16{padding-left:4rem}.pt-20{padding-top:5rem}.pr-20{padding-right:5rem}.pb-20{padding-bottom:5rem}.pl-20{padding-left:5rem}.pt-24{padding-top:6rem}.pr-24{padding-right:6rem}.pb-24{padding-bottom:6rem}.pl-24{padding-left:6rem}.pt-32{padding-top:8rem}.pr-32{padding-right:8rem}.pb-32{padding-bottom:8rem}.pl-32{padding-left:8rem}.pt-40{padding-top:10rem}.pr-40{padding-right:10rem}.pb-40{padding-bottom:10rem}.pl-40{padding-left:10rem}.pt-48{padding-top:12rem}.pr-48{padding-right:12rem}.pb-48{padding-bottom:12rem}.pl-48{padding-left:12rem}.pt-56{padding-top:14rem}.pr-56{padding-right:14rem}.pb-56{padding-bottom:14rem}.pl-56{padding-left:14rem}.pt-64{padding-top:16rem}.pr-64{padding-right:16rem}.pb-64{padding-bottom:16rem}.pl-64{padding-left:16rem}.pt-px{padding-top:1px}.pr-px{padding-right:1px}.pb-px{padding-bottom:1px}.pl-px{padding-left:1px}.placeholder-transparent:-ms-input-placeholder{color:transparent}.placeholder-transparent::-ms-input-placeholder{color:transparent}.placeholder-transparent::placeholder{color:transparent}.placeholder-current:-ms-input-placeholder{color:currentColor}.placeholder-current::-ms-input-placeholder{color:currentColor}.placeholder-current::placeholder{color:currentColor}.placeholder-black:-ms-input-placeholder{--placeholder-opacity:1;color:#000;color:rgba(0,0,0,var(--placeholder-opacity))}.placeholder-black::-ms-input-placeholder{--placeholder-opacity:1;color:#000;color:rgba(0,0,0,var(--placeholder-opacity))}.placeholder-black::placeholder{--placeholder-opacity:1;color:#000;color:rgba(0,0,0,var(--placeholder-opacity))}.placeholder-white:-ms-input-placeholder{--placeholder-opacity:1;color:#fff;color:rgba(255,255,255,var(--placeholder-opacity))}.placeholder-white::-ms-input-placeholder{--placeholder-opacity:1;color:#fff;color:rgba(255,255,255,var(--placeholder-opacity))}.placeholder-white::placeholder{--placeholder-opacity:1;color:#fff;color:rgba(255,255,255,var(--placeholder-opacity))}.placeholder-gray-100:-ms-input-placeholder{--placeholder-opacity:1;color:#f7fafc;color:rgba(247,250,252,var(--placeholder-opacity))}.placeholder-gray-100::-ms-input-placeholder{--placeholder-opacity:1;color:#f7fafc;color:rgba(247,250,252,var(--placeholder-opacity))}.placeholder-gray-100::placeholder{--placeholder-opacity:1;color:#f7fafc;color:rgba(247,250,252,var(--placeholder-opacity))}.placeholder-gray-200:-ms-input-placeholder{--placeholder-opacity:1;color:#edf2f7;color:rgba(237,242,247,var(--placeholder-opacity))}.placeholder-gray-200::-ms-input-placeholder{--placeholder-opacity:1;color:#edf2f7;color:rgba(237,242,247,var(--placeholder-opacity))}.placeholder-gray-200::placeholder{--placeholder-opacity:1;color:#edf2f7;color:rgba(237,242,247,var(--placeholder-opacity))}.placeholder-gray-300:-ms-input-placeholder{--placeholder-opacity:1;color:#e2e8f0;color:rgba(226,232,240,var(--placeholder-opacity))}.placeholder-gray-300::-ms-input-placeholder{--placeholder-opacity:1;color:#e2e8f0;color:rgba(226,232,240,var(--placeholder-opacity))}.placeholder-gray-300::placeholder{--placeholder-opacity:1;color:#e2e8f0;color:rgba(226,232,240,var(--placeholder-opacity))}.placeholder-gray-400:-ms-input-placeholder{--placeholder-opacity:1;color:#cbd5e0;color:rgba(203,213,224,var(--placeholder-opacity))}.placeholder-gray-400::-ms-input-placeholder{--placeholder-opacity:1;color:#cbd5e0;color:rgba(203,213,224,var(--placeholder-opacity))}.placeholder-gray-400::placeholder{--placeholder-opacity:1;color:#cbd5e0;color:rgba(203,213,224,var(--placeholder-opacity))}.placeholder-gray-500:-ms-input-placeholder{--placeholder-opacity:1;color:#a0aec0;color:rgba(160,174,192,var(--placeholder-opacity))}.placeholder-gray-500::-ms-input-placeholder{--placeholder-opacity:1;color:#a0aec0;color:rgba(160,174,192,var(--placeholder-opacity))}.placeholder-gray-500::placeholder{--placeholder-opacity:1;color:#a0aec0;color:rgba(160,174,192,var(--placeholder-opacity))}.placeholder-gray-600:-ms-input-placeholder{--placeholder-opacity:1;color:#718096;color:rgba(113,128,150,var(--placeholder-opacity))}.placeholder-gray-600::-ms-input-placeholder{--placeholder-opacity:1;color:#718096;color:rgba(113,128,150,var(--placeholder-opacity))}.placeholder-gray-600::placeholder{--placeholder-opacity:1;color:#718096;color:rgba(113,128,150,var(--placeholder-opacity))}.placeholder-gray-700:-ms-input-placeholder{--placeholder-opacity:1;color:#4a5568;color:rgba(74,85,104,var(--placeholder-opacity))}.placeholder-gray-700::-ms-input-placeholder{--placeholder-opacity:1;color:#4a5568;color:rgba(74,85,104,var(--placeholder-opacity))}.placeholder-gray-700::placeholder{--placeholder-opacity:1;color:#4a5568;color:rgba(74,85,104,var(--placeholder-opacity))}.placeholder-gray-800:-ms-input-placeholder{--placeholder-opacity:1;color:#2d3748;color:rgba(45,55,72,var(--placeholder-opacity))}.placeholder-gray-800::-ms-input-placeholder{--placeholder-opacity:1;color:#2d3748;color:rgba(45,55,72,var(--placeholder-opacity))}.placeholder-gray-800::placeholder{--placeholder-opacity:1;color:#2d3748;color:rgba(45,55,72,var(--placeholder-opacity))}.placeholder-gray-900:-ms-input-placeholder{--placeholder-opacity:1;color:#1a202c;color:rgba(26,32,44,var(--placeholder-opacity))}.placeholder-gray-900::-ms-input-placeholder{--placeholder-opacity:1;color:#1a202c;color:rgba(26,32,44,var(--placeholder-opacity))}.placeholder-gray-900::placeholder{--placeholder-opacity:1;color:#1a202c;color:rgba(26,32,44,var(--placeholder-opacity))}.placeholder-red-100:-ms-input-placeholder{--placeholder-opacity:1;color:#fff5f5;color:rgba(255,245,245,var(--placeholder-opacity))}.placeholder-red-100::-ms-input-placeholder{--placeholder-opacity:1;color:#fff5f5;color:rgba(255,245,245,var(--placeholder-opacity))}.placeholder-red-100::placeholder{--placeholder-opacity:1;color:#fff5f5;color:rgba(255,245,245,var(--placeholder-opacity))}.placeholder-red-200:-ms-input-placeholder{--placeholder-opacity:1;color:#fed7d7;color:rgba(254,215,215,var(--placeholder-opacity))}.placeholder-red-200::-ms-input-placeholder{--placeholder-opacity:1;color:#fed7d7;color:rgba(254,215,215,var(--placeholder-opacity))}.placeholder-red-200::placeholder{--placeholder-opacity:1;color:#fed7d7;color:rgba(254,215,215,var(--placeholder-opacity))}.placeholder-red-300:-ms-input-placeholder{--placeholder-opacity:1;color:#feb2b2;color:rgba(254,178,178,var(--placeholder-opacity))}.placeholder-red-300::-ms-input-placeholder{--placeholder-opacity:1;color:#feb2b2;color:rgba(254,178,178,var(--placeholder-opacity))}.placeholder-red-300::placeholder{--placeholder-opacity:1;color:#feb2b2;color:rgba(254,178,178,var(--placeholder-opacity))}.placeholder-red-400:-ms-input-placeholder{--placeholder-opacity:1;color:#fc8181;color:rgba(252,129,129,var(--placeholder-opacity))}.placeholder-red-400::-ms-input-placeholder{--placeholder-opacity:1;color:#fc8181;color:rgba(252,129,129,var(--placeholder-opacity))}.placeholder-red-400::placeholder{--placeholder-opacity:1;color:#fc8181;color:rgba(252,129,129,var(--placeholder-opacity))}.placeholder-red-500:-ms-input-placeholder{--placeholder-opacity:1;color:#f56565;color:rgba(245,101,101,var(--placeholder-opacity))}.placeholder-red-500::-ms-input-placeholder{--placeholder-opacity:1;color:#f56565;color:rgba(245,101,101,var(--placeholder-opacity))}.placeholder-red-500::placeholder{--placeholder-opacity:1;color:#f56565;color:rgba(245,101,101,var(--placeholder-opacity))}.placeholder-red-600:-ms-input-placeholder{--placeholder-opacity:1;color:#e53e3e;color:rgba(229,62,62,var(--placeholder-opacity))}.placeholder-red-600::-ms-input-placeholder{--placeholder-opacity:1;color:#e53e3e;color:rgba(229,62,62,var(--placeholder-opacity))}.placeholder-red-600::placeholder{--placeholder-opacity:1;color:#e53e3e;color:rgba(229,62,62,var(--placeholder-opacity))}.placeholder-red-700:-ms-input-placeholder{--placeholder-opacity:1;color:#c53030;color:rgba(197,48,48,var(--placeholder-opacity))}.placeholder-red-700::-ms-input-placeholder{--placeholder-opacity:1;color:#c53030;color:rgba(197,48,48,var(--placeholder-opacity))}.placeholder-red-700::placeholder{--placeholder-opacity:1;color:#c53030;color:rgba(197,48,48,var(--placeholder-opacity))}.placeholder-red-800:-ms-input-placeholder{--placeholder-opacity:1;color:#9b2c2c;color:rgba(155,44,44,var(--placeholder-opacity))}.placeholder-red-800::-ms-input-placeholder{--placeholder-opacity:1;color:#9b2c2c;color:rgba(155,44,44,var(--placeholder-opacity))}.placeholder-red-800::placeholder{--placeholder-opacity:1;color:#9b2c2c;color:rgba(155,44,44,var(--placeholder-opacity))}.placeholder-red-900:-ms-input-placeholder{--placeholder-opacity:1;color:#742a2a;color:rgba(116,42,42,var(--placeholder-opacity))}.placeholder-red-900::-ms-input-placeholder{--placeholder-opacity:1;color:#742a2a;color:rgba(116,42,42,var(--placeholder-opacity))}.placeholder-red-900::placeholder{--placeholder-opacity:1;color:#742a2a;color:rgba(116,42,42,var(--placeholder-opacity))}.placeholder-orange-100:-ms-input-placeholder{--placeholder-opacity:1;color:#fffaf0;color:rgba(255,250,240,var(--placeholder-opacity))}.placeholder-orange-100::-ms-input-placeholder{--placeholder-opacity:1;color:#fffaf0;color:rgba(255,250,240,var(--placeholder-opacity))}.placeholder-orange-100::placeholder{--placeholder-opacity:1;color:#fffaf0;color:rgba(255,250,240,var(--placeholder-opacity))}.placeholder-orange-200:-ms-input-placeholder{--placeholder-opacity:1;color:#feebc8;color:rgba(254,235,200,var(--placeholder-opacity))}.placeholder-orange-200::-ms-input-placeholder{--placeholder-opacity:1;color:#feebc8;color:rgba(254,235,200,var(--placeholder-opacity))}.placeholder-orange-200::placeholder{--placeholder-opacity:1;color:#feebc8;color:rgba(254,235,200,var(--placeholder-opacity))}.placeholder-orange-300:-ms-input-placeholder{--placeholder-opacity:1;color:#fbd38d;color:rgba(251,211,141,var(--placeholder-opacity))}.placeholder-orange-300::-ms-input-placeholder{--placeholder-opacity:1;color:#fbd38d;color:rgba(251,211,141,var(--placeholder-opacity))}.placeholder-orange-300::placeholder{--placeholder-opacity:1;color:#fbd38d;color:rgba(251,211,141,var(--placeholder-opacity))}.placeholder-orange-400:-ms-input-placeholder{--placeholder-opacity:1;color:#f6ad55;color:rgba(246,173,85,var(--placeholder-opacity))}.placeholder-orange-400::-ms-input-placeholder{--placeholder-opacity:1;color:#f6ad55;color:rgba(246,173,85,var(--placeholder-opacity))}.placeholder-orange-400::placeholder{--placeholder-opacity:1;color:#f6ad55;color:rgba(246,173,85,var(--placeholder-opacity))}.placeholder-orange-500:-ms-input-placeholder{--placeholder-opacity:1;color:#ed8936;color:rgba(237,137,54,var(--placeholder-opacity))}.placeholder-orange-500::-ms-input-placeholder{--placeholder-opacity:1;color:#ed8936;color:rgba(237,137,54,var(--placeholder-opacity))}.placeholder-orange-500::placeholder{--placeholder-opacity:1;color:#ed8936;color:rgba(237,137,54,var(--placeholder-opacity))}.placeholder-orange-600:-ms-input-placeholder{--placeholder-opacity:1;color:#dd6b20;color:rgba(221,107,32,var(--placeholder-opacity))}.placeholder-orange-600::-ms-input-placeholder{--placeholder-opacity:1;color:#dd6b20;color:rgba(221,107,32,var(--placeholder-opacity))}.placeholder-orange-600::placeholder{--placeholder-opacity:1;color:#dd6b20;color:rgba(221,107,32,var(--placeholder-opacity))}.placeholder-orange-700:-ms-input-placeholder{--placeholder-opacity:1;color:#c05621;color:rgba(192,86,33,var(--placeholder-opacity))}.placeholder-orange-700::-ms-input-placeholder{--placeholder-opacity:1;color:#c05621;color:rgba(192,86,33,var(--placeholder-opacity))}.placeholder-orange-700::placeholder{--placeholder-opacity:1;color:#c05621;color:rgba(192,86,33,var(--placeholder-opacity))}.placeholder-orange-800:-ms-input-placeholder{--placeholder-opacity:1;color:#9c4221;color:rgba(156,66,33,var(--placeholder-opacity))}.placeholder-orange-800::-ms-input-placeholder{--placeholder-opacity:1;color:#9c4221;color:rgba(156,66,33,var(--placeholder-opacity))}.placeholder-orange-800::placeholder{--placeholder-opacity:1;color:#9c4221;color:rgba(156,66,33,var(--placeholder-opacity))}.placeholder-orange-900:-ms-input-placeholder{--placeholder-opacity:1;color:#7b341e;color:rgba(123,52,30,var(--placeholder-opacity))}.placeholder-orange-900::-ms-input-placeholder{--placeholder-opacity:1;color:#7b341e;color:rgba(123,52,30,var(--placeholder-opacity))}.placeholder-orange-900::placeholder{--placeholder-opacity:1;color:#7b341e;color:rgba(123,52,30,var(--placeholder-opacity))}.placeholder-yellow-100:-ms-input-placeholder{--placeholder-opacity:1;color:ivory;color:rgba(255,255,240,var(--placeholder-opacity))}.placeholder-yellow-100::-ms-input-placeholder{--placeholder-opacity:1;color:ivory;color:rgba(255,255,240,var(--placeholder-opacity))}.placeholder-yellow-100::placeholder{--placeholder-opacity:1;color:ivory;color:rgba(255,255,240,var(--placeholder-opacity))}.placeholder-yellow-200:-ms-input-placeholder{--placeholder-opacity:1;color:#fefcbf;color:rgba(254,252,191,var(--placeholder-opacity))}.placeholder-yellow-200::-ms-input-placeholder{--placeholder-opacity:1;color:#fefcbf;color:rgba(254,252,191,var(--placeholder-opacity))}.placeholder-yellow-200::placeholder{--placeholder-opacity:1;color:#fefcbf;color:rgba(254,252,191,var(--placeholder-opacity))}.placeholder-yellow-300:-ms-input-placeholder{--placeholder-opacity:1;color:#faf089;color:rgba(250,240,137,var(--placeholder-opacity))}.placeholder-yellow-300::-ms-input-placeholder{--placeholder-opacity:1;color:#faf089;color:rgba(250,240,137,var(--placeholder-opacity))}.placeholder-yellow-300::placeholder{--placeholder-opacity:1;color:#faf089;color:rgba(250,240,137,var(--placeholder-opacity))}.placeholder-yellow-400:-ms-input-placeholder{--placeholder-opacity:1;color:#f6e05e;color:rgba(246,224,94,var(--placeholder-opacity))}.placeholder-yellow-400::-ms-input-placeholder{--placeholder-opacity:1;color:#f6e05e;color:rgba(246,224,94,var(--placeholder-opacity))}.placeholder-yellow-400::placeholder{--placeholder-opacity:1;color:#f6e05e;color:rgba(246,224,94,var(--placeholder-opacity))}.placeholder-yellow-500:-ms-input-placeholder{--placeholder-opacity:1;color:#ecc94b;color:rgba(236,201,75,var(--placeholder-opacity))}.placeholder-yellow-500::-ms-input-placeholder{--placeholder-opacity:1;color:#ecc94b;color:rgba(236,201,75,var(--placeholder-opacity))}.placeholder-yellow-500::placeholder{--placeholder-opacity:1;color:#ecc94b;color:rgba(236,201,75,var(--placeholder-opacity))}.placeholder-yellow-600:-ms-input-placeholder{--placeholder-opacity:1;color:#d69e2e;color:rgba(214,158,46,var(--placeholder-opacity))}.placeholder-yellow-600::-ms-input-placeholder{--placeholder-opacity:1;color:#d69e2e;color:rgba(214,158,46,var(--placeholder-opacity))}.placeholder-yellow-600::placeholder{--placeholder-opacity:1;color:#d69e2e;color:rgba(214,158,46,var(--placeholder-opacity))}.placeholder-yellow-700:-ms-input-placeholder{--placeholder-opacity:1;color:#b7791f;color:rgba(183,121,31,var(--placeholder-opacity))}.placeholder-yellow-700::-ms-input-placeholder{--placeholder-opacity:1;color:#b7791f;color:rgba(183,121,31,var(--placeholder-opacity))}.placeholder-yellow-700::placeholder{--placeholder-opacity:1;color:#b7791f;color:rgba(183,121,31,var(--placeholder-opacity))}.placeholder-yellow-800:-ms-input-placeholder{--placeholder-opacity:1;color:#975a16;color:rgba(151,90,22,var(--placeholder-opacity))}.placeholder-yellow-800::-ms-input-placeholder{--placeholder-opacity:1;color:#975a16;color:rgba(151,90,22,var(--placeholder-opacity))}.placeholder-yellow-800::placeholder{--placeholder-opacity:1;color:#975a16;color:rgba(151,90,22,var(--placeholder-opacity))}.placeholder-yellow-900:-ms-input-placeholder{--placeholder-opacity:1;color:#744210;color:rgba(116,66,16,var(--placeholder-opacity))}.placeholder-yellow-900::-ms-input-placeholder{--placeholder-opacity:1;color:#744210;color:rgba(116,66,16,var(--placeholder-opacity))}.placeholder-yellow-900::placeholder{--placeholder-opacity:1;color:#744210;color:rgba(116,66,16,var(--placeholder-opacity))}.placeholder-green-100:-ms-input-placeholder{--placeholder-opacity:1;color:#f0fff4;color:rgba(240,255,244,var(--placeholder-opacity))}.placeholder-green-100::-ms-input-placeholder{--placeholder-opacity:1;color:#f0fff4;color:rgba(240,255,244,var(--placeholder-opacity))}.placeholder-green-100::placeholder{--placeholder-opacity:1;color:#f0fff4;color:rgba(240,255,244,var(--placeholder-opacity))}.placeholder-green-200:-ms-input-placeholder{--placeholder-opacity:1;color:#c6f6d5;color:rgba(198,246,213,var(--placeholder-opacity))}.placeholder-green-200::-ms-input-placeholder{--placeholder-opacity:1;color:#c6f6d5;color:rgba(198,246,213,var(--placeholder-opacity))}.placeholder-green-200::placeholder{--placeholder-opacity:1;color:#c6f6d5;color:rgba(198,246,213,var(--placeholder-opacity))}.placeholder-green-300:-ms-input-placeholder{--placeholder-opacity:1;color:#9ae6b4;color:rgba(154,230,180,var(--placeholder-opacity))}.placeholder-green-300::-ms-input-placeholder{--placeholder-opacity:1;color:#9ae6b4;color:rgba(154,230,180,var(--placeholder-opacity))}.placeholder-green-300::placeholder{--placeholder-opacity:1;color:#9ae6b4;color:rgba(154,230,180,var(--placeholder-opacity))}.placeholder-green-400:-ms-input-placeholder{--placeholder-opacity:1;color:#68d391;color:rgba(104,211,145,var(--placeholder-opacity))}.placeholder-green-400::-ms-input-placeholder{--placeholder-opacity:1;color:#68d391;color:rgba(104,211,145,var(--placeholder-opacity))}.placeholder-green-400::placeholder{--placeholder-opacity:1;color:#68d391;color:rgba(104,211,145,var(--placeholder-opacity))}.placeholder-green-500:-ms-input-placeholder{--placeholder-opacity:1;color:#48bb78;color:rgba(72,187,120,var(--placeholder-opacity))}.placeholder-green-500::-ms-input-placeholder{--placeholder-opacity:1;color:#48bb78;color:rgba(72,187,120,var(--placeholder-opacity))}.placeholder-green-500::placeholder{--placeholder-opacity:1;color:#48bb78;color:rgba(72,187,120,var(--placeholder-opacity))}.placeholder-green-600:-ms-input-placeholder{--placeholder-opacity:1;color:#38a169;color:rgba(56,161,105,var(--placeholder-opacity))}.placeholder-green-600::-ms-input-placeholder{--placeholder-opacity:1;color:#38a169;color:rgba(56,161,105,var(--placeholder-opacity))}.placeholder-green-600::placeholder{--placeholder-opacity:1;color:#38a169;color:rgba(56,161,105,var(--placeholder-opacity))}.placeholder-green-700:-ms-input-placeholder{--placeholder-opacity:1;color:#2f855a;color:rgba(47,133,90,var(--placeholder-opacity))}.placeholder-green-700::-ms-input-placeholder{--placeholder-opacity:1;color:#2f855a;color:rgba(47,133,90,var(--placeholder-opacity))}.placeholder-green-700::placeholder{--placeholder-opacity:1;color:#2f855a;color:rgba(47,133,90,var(--placeholder-opacity))}.placeholder-green-800:-ms-input-placeholder{--placeholder-opacity:1;color:#276749;color:rgba(39,103,73,var(--placeholder-opacity))}.placeholder-green-800::-ms-input-placeholder{--placeholder-opacity:1;color:#276749;color:rgba(39,103,73,var(--placeholder-opacity))}.placeholder-green-800::placeholder{--placeholder-opacity:1;color:#276749;color:rgba(39,103,73,var(--placeholder-opacity))}.placeholder-green-900:-ms-input-placeholder{--placeholder-opacity:1;color:#22543d;color:rgba(34,84,61,var(--placeholder-opacity))}.placeholder-green-900::-ms-input-placeholder{--placeholder-opacity:1;color:#22543d;color:rgba(34,84,61,var(--placeholder-opacity))}.placeholder-green-900::placeholder{--placeholder-opacity:1;color:#22543d;color:rgba(34,84,61,var(--placeholder-opacity))}.placeholder-teal-100:-ms-input-placeholder{--placeholder-opacity:1;color:#e6fffa;color:rgba(230,255,250,var(--placeholder-opacity))}.placeholder-teal-100::-ms-input-placeholder{--placeholder-opacity:1;color:#e6fffa;color:rgba(230,255,250,var(--placeholder-opacity))}.placeholder-teal-100::placeholder{--placeholder-opacity:1;color:#e6fffa;color:rgba(230,255,250,var(--placeholder-opacity))}.placeholder-teal-200:-ms-input-placeholder{--placeholder-opacity:1;color:#b2f5ea;color:rgba(178,245,234,var(--placeholder-opacity))}.placeholder-teal-200::-ms-input-placeholder{--placeholder-opacity:1;color:#b2f5ea;color:rgba(178,245,234,var(--placeholder-opacity))}.placeholder-teal-200::placeholder{--placeholder-opacity:1;color:#b2f5ea;color:rgba(178,245,234,var(--placeholder-opacity))}.placeholder-teal-300:-ms-input-placeholder{--placeholder-opacity:1;color:#81e6d9;color:rgba(129,230,217,var(--placeholder-opacity))}.placeholder-teal-300::-ms-input-placeholder{--placeholder-opacity:1;color:#81e6d9;color:rgba(129,230,217,var(--placeholder-opacity))}.placeholder-teal-300::placeholder{--placeholder-opacity:1;color:#81e6d9;color:rgba(129,230,217,var(--placeholder-opacity))}.placeholder-teal-400:-ms-input-placeholder{--placeholder-opacity:1;color:#4fd1c5;color:rgba(79,209,197,var(--placeholder-opacity))}.placeholder-teal-400::-ms-input-placeholder{--placeholder-opacity:1;color:#4fd1c5;color:rgba(79,209,197,var(--placeholder-opacity))}.placeholder-teal-400::placeholder{--placeholder-opacity:1;color:#4fd1c5;color:rgba(79,209,197,var(--placeholder-opacity))}.placeholder-teal-500:-ms-input-placeholder{--placeholder-opacity:1;color:#38b2ac;color:rgba(56,178,172,var(--placeholder-opacity))}.placeholder-teal-500::-ms-input-placeholder{--placeholder-opacity:1;color:#38b2ac;color:rgba(56,178,172,var(--placeholder-opacity))}.placeholder-teal-500::placeholder{--placeholder-opacity:1;color:#38b2ac;color:rgba(56,178,172,var(--placeholder-opacity))}.placeholder-teal-600:-ms-input-placeholder{--placeholder-opacity:1;color:#319795;color:rgba(49,151,149,var(--placeholder-opacity))}.placeholder-teal-600::-ms-input-placeholder{--placeholder-opacity:1;color:#319795;color:rgba(49,151,149,var(--placeholder-opacity))}.placeholder-teal-600::placeholder{--placeholder-opacity:1;color:#319795;color:rgba(49,151,149,var(--placeholder-opacity))}.placeholder-teal-700:-ms-input-placeholder{--placeholder-opacity:1;color:#2c7a7b;color:rgba(44,122,123,var(--placeholder-opacity))}.placeholder-teal-700::-ms-input-placeholder{--placeholder-opacity:1;color:#2c7a7b;color:rgba(44,122,123,var(--placeholder-opacity))}.placeholder-teal-700::placeholder{--placeholder-opacity:1;color:#2c7a7b;color:rgba(44,122,123,var(--placeholder-opacity))}.placeholder-teal-800:-ms-input-placeholder{--placeholder-opacity:1;color:#285e61;color:rgba(40,94,97,var(--placeholder-opacity))}.placeholder-teal-800::-ms-input-placeholder{--placeholder-opacity:1;color:#285e61;color:rgba(40,94,97,var(--placeholder-opacity))}.placeholder-teal-800::placeholder{--placeholder-opacity:1;color:#285e61;color:rgba(40,94,97,var(--placeholder-opacity))}.placeholder-teal-900:-ms-input-placeholder{--placeholder-opacity:1;color:#234e52;color:rgba(35,78,82,var(--placeholder-opacity))}.placeholder-teal-900::-ms-input-placeholder{--placeholder-opacity:1;color:#234e52;color:rgba(35,78,82,var(--placeholder-opacity))}.placeholder-teal-900::placeholder{--placeholder-opacity:1;color:#234e52;color:rgba(35,78,82,var(--placeholder-opacity))}.placeholder-blue-100:-ms-input-placeholder{--placeholder-opacity:1;color:#ebf8ff;color:rgba(235,248,255,var(--placeholder-opacity))}.placeholder-blue-100::-ms-input-placeholder{--placeholder-opacity:1;color:#ebf8ff;color:rgba(235,248,255,var(--placeholder-opacity))}.placeholder-blue-100::placeholder{--placeholder-opacity:1;color:#ebf8ff;color:rgba(235,248,255,var(--placeholder-opacity))}.placeholder-blue-200:-ms-input-placeholder{--placeholder-opacity:1;color:#bee3f8;color:rgba(190,227,248,var(--placeholder-opacity))}.placeholder-blue-200::-ms-input-placeholder{--placeholder-opacity:1;color:#bee3f8;color:rgba(190,227,248,var(--placeholder-opacity))}.placeholder-blue-200::placeholder{--placeholder-opacity:1;color:#bee3f8;color:rgba(190,227,248,var(--placeholder-opacity))}.placeholder-blue-300:-ms-input-placeholder{--placeholder-opacity:1;color:#90cdf4;color:rgba(144,205,244,var(--placeholder-opacity))}.placeholder-blue-300::-ms-input-placeholder{--placeholder-opacity:1;color:#90cdf4;color:rgba(144,205,244,var(--placeholder-opacity))}.placeholder-blue-300::placeholder{--placeholder-opacity:1;color:#90cdf4;color:rgba(144,205,244,var(--placeholder-opacity))}.placeholder-blue-400:-ms-input-placeholder{--placeholder-opacity:1;color:#63b3ed;color:rgba(99,179,237,var(--placeholder-opacity))}.placeholder-blue-400::-ms-input-placeholder{--placeholder-opacity:1;color:#63b3ed;color:rgba(99,179,237,var(--placeholder-opacity))}.placeholder-blue-400::placeholder{--placeholder-opacity:1;color:#63b3ed;color:rgba(99,179,237,var(--placeholder-opacity))}.placeholder-blue-500:-ms-input-placeholder{--placeholder-opacity:1;color:#4299e1;color:rgba(66,153,225,var(--placeholder-opacity))}.placeholder-blue-500::-ms-input-placeholder{--placeholder-opacity:1;color:#4299e1;color:rgba(66,153,225,var(--placeholder-opacity))}.placeholder-blue-500::placeholder{--placeholder-opacity:1;color:#4299e1;color:rgba(66,153,225,var(--placeholder-opacity))}.placeholder-blue-600:-ms-input-placeholder{--placeholder-opacity:1;color:#3182ce;color:rgba(49,130,206,var(--placeholder-opacity))}.placeholder-blue-600::-ms-input-placeholder{--placeholder-opacity:1;color:#3182ce;color:rgba(49,130,206,var(--placeholder-opacity))}.placeholder-blue-600::placeholder{--placeholder-opacity:1;color:#3182ce;color:rgba(49,130,206,var(--placeholder-opacity))}.placeholder-blue-700:-ms-input-placeholder{--placeholder-opacity:1;color:#2b6cb0;color:rgba(43,108,176,var(--placeholder-opacity))}.placeholder-blue-700::-ms-input-placeholder{--placeholder-opacity:1;color:#2b6cb0;color:rgba(43,108,176,var(--placeholder-opacity))}.placeholder-blue-700::placeholder{--placeholder-opacity:1;color:#2b6cb0;color:rgba(43,108,176,var(--placeholder-opacity))}.placeholder-blue-800:-ms-input-placeholder{--placeholder-opacity:1;color:#2c5282;color:rgba(44,82,130,var(--placeholder-opacity))}.placeholder-blue-800::-ms-input-placeholder{--placeholder-opacity:1;color:#2c5282;color:rgba(44,82,130,var(--placeholder-opacity))}.placeholder-blue-800::placeholder{--placeholder-opacity:1;color:#2c5282;color:rgba(44,82,130,var(--placeholder-opacity))}.placeholder-blue-900:-ms-input-placeholder{--placeholder-opacity:1;color:#2a4365;color:rgba(42,67,101,var(--placeholder-opacity))}.placeholder-blue-900::-ms-input-placeholder{--placeholder-opacity:1;color:#2a4365;color:rgba(42,67,101,var(--placeholder-opacity))}.placeholder-blue-900::placeholder{--placeholder-opacity:1;color:#2a4365;color:rgba(42,67,101,var(--placeholder-opacity))}.placeholder-indigo-100:-ms-input-placeholder{--placeholder-opacity:1;color:#ebf4ff;color:rgba(235,244,255,var(--placeholder-opacity))}.placeholder-indigo-100::-ms-input-placeholder{--placeholder-opacity:1;color:#ebf4ff;color:rgba(235,244,255,var(--placeholder-opacity))}.placeholder-indigo-100::placeholder{--placeholder-opacity:1;color:#ebf4ff;color:rgba(235,244,255,var(--placeholder-opacity))}.placeholder-indigo-200:-ms-input-placeholder{--placeholder-opacity:1;color:#c3dafe;color:rgba(195,218,254,var(--placeholder-opacity))}.placeholder-indigo-200::-ms-input-placeholder{--placeholder-opacity:1;color:#c3dafe;color:rgba(195,218,254,var(--placeholder-opacity))}.placeholder-indigo-200::placeholder{--placeholder-opacity:1;color:#c3dafe;color:rgba(195,218,254,var(--placeholder-opacity))}.placeholder-indigo-300:-ms-input-placeholder{--placeholder-opacity:1;color:#a3bffa;color:rgba(163,191,250,var(--placeholder-opacity))}.placeholder-indigo-300::-ms-input-placeholder{--placeholder-opacity:1;color:#a3bffa;color:rgba(163,191,250,var(--placeholder-opacity))}.placeholder-indigo-300::placeholder{--placeholder-opacity:1;color:#a3bffa;color:rgba(163,191,250,var(--placeholder-opacity))}.placeholder-indigo-400:-ms-input-placeholder{--placeholder-opacity:1;color:#7f9cf5;color:rgba(127,156,245,var(--placeholder-opacity))}.placeholder-indigo-400::-ms-input-placeholder{--placeholder-opacity:1;color:#7f9cf5;color:rgba(127,156,245,var(--placeholder-opacity))}.placeholder-indigo-400::placeholder{--placeholder-opacity:1;color:#7f9cf5;color:rgba(127,156,245,var(--placeholder-opacity))}.placeholder-indigo-500:-ms-input-placeholder{--placeholder-opacity:1;color:#667eea;color:rgba(102,126,234,var(--placeholder-opacity))}.placeholder-indigo-500::-ms-input-placeholder{--placeholder-opacity:1;color:#667eea;color:rgba(102,126,234,var(--placeholder-opacity))}.placeholder-indigo-500::placeholder{--placeholder-opacity:1;color:#667eea;color:rgba(102,126,234,var(--placeholder-opacity))}.placeholder-indigo-600:-ms-input-placeholder{--placeholder-opacity:1;color:#5a67d8;color:rgba(90,103,216,var(--placeholder-opacity))}.placeholder-indigo-600::-ms-input-placeholder{--placeholder-opacity:1;color:#5a67d8;color:rgba(90,103,216,var(--placeholder-opacity))}.placeholder-indigo-600::placeholder{--placeholder-opacity:1;color:#5a67d8;color:rgba(90,103,216,var(--placeholder-opacity))}.placeholder-indigo-700:-ms-input-placeholder{--placeholder-opacity:1;color:#4c51bf;color:rgba(76,81,191,var(--placeholder-opacity))}.placeholder-indigo-700::-ms-input-placeholder{--placeholder-opacity:1;color:#4c51bf;color:rgba(76,81,191,var(--placeholder-opacity))}.placeholder-indigo-700::placeholder{--placeholder-opacity:1;color:#4c51bf;color:rgba(76,81,191,var(--placeholder-opacity))}.placeholder-indigo-800:-ms-input-placeholder{--placeholder-opacity:1;color:#434190;color:rgba(67,65,144,var(--placeholder-opacity))}.placeholder-indigo-800::-ms-input-placeholder{--placeholder-opacity:1;color:#434190;color:rgba(67,65,144,var(--placeholder-opacity))}.placeholder-indigo-800::placeholder{--placeholder-opacity:1;color:#434190;color:rgba(67,65,144,var(--placeholder-opacity))}.placeholder-indigo-900:-ms-input-placeholder{--placeholder-opacity:1;color:#3c366b;color:rgba(60,54,107,var(--placeholder-opacity))}.placeholder-indigo-900::-ms-input-placeholder{--placeholder-opacity:1;color:#3c366b;color:rgba(60,54,107,var(--placeholder-opacity))}.placeholder-indigo-900::placeholder{--placeholder-opacity:1;color:#3c366b;color:rgba(60,54,107,var(--placeholder-opacity))}.placeholder-purple-100:-ms-input-placeholder{--placeholder-opacity:1;color:#faf5ff;color:rgba(250,245,255,var(--placeholder-opacity))}.placeholder-purple-100::-ms-input-placeholder{--placeholder-opacity:1;color:#faf5ff;color:rgba(250,245,255,var(--placeholder-opacity))}.placeholder-purple-100::placeholder{--placeholder-opacity:1;color:#faf5ff;color:rgba(250,245,255,var(--placeholder-opacity))}.placeholder-purple-200:-ms-input-placeholder{--placeholder-opacity:1;color:#e9d8fd;color:rgba(233,216,253,var(--placeholder-opacity))}.placeholder-purple-200::-ms-input-placeholder{--placeholder-opacity:1;color:#e9d8fd;color:rgba(233,216,253,var(--placeholder-opacity))}.placeholder-purple-200::placeholder{--placeholder-opacity:1;color:#e9d8fd;color:rgba(233,216,253,var(--placeholder-opacity))}.placeholder-purple-300:-ms-input-placeholder{--placeholder-opacity:1;color:#d6bcfa;color:rgba(214,188,250,var(--placeholder-opacity))}.placeholder-purple-300::-ms-input-placeholder{--placeholder-opacity:1;color:#d6bcfa;color:rgba(214,188,250,var(--placeholder-opacity))}.placeholder-purple-300::placeholder{--placeholder-opacity:1;color:#d6bcfa;color:rgba(214,188,250,var(--placeholder-opacity))}.placeholder-purple-400:-ms-input-placeholder{--placeholder-opacity:1;color:#b794f4;color:rgba(183,148,244,var(--placeholder-opacity))}.placeholder-purple-400::-ms-input-placeholder{--placeholder-opacity:1;color:#b794f4;color:rgba(183,148,244,var(--placeholder-opacity))}.placeholder-purple-400::placeholder{--placeholder-opacity:1;color:#b794f4;color:rgba(183,148,244,var(--placeholder-opacity))}.placeholder-purple-500:-ms-input-placeholder{--placeholder-opacity:1;color:#9f7aea;color:rgba(159,122,234,var(--placeholder-opacity))}.placeholder-purple-500::-ms-input-placeholder{--placeholder-opacity:1;color:#9f7aea;color:rgba(159,122,234,var(--placeholder-opacity))}.placeholder-purple-500::placeholder{--placeholder-opacity:1;color:#9f7aea;color:rgba(159,122,234,var(--placeholder-opacity))}.placeholder-purple-600:-ms-input-placeholder{--placeholder-opacity:1;color:#805ad5;color:rgba(128,90,213,var(--placeholder-opacity))}.placeholder-purple-600::-ms-input-placeholder{--placeholder-opacity:1;color:#805ad5;color:rgba(128,90,213,var(--placeholder-opacity))}.placeholder-purple-600::placeholder{--placeholder-opacity:1;color:#805ad5;color:rgba(128,90,213,var(--placeholder-opacity))}.placeholder-purple-700:-ms-input-placeholder{--placeholder-opacity:1;color:#6b46c1;color:rgba(107,70,193,var(--placeholder-opacity))}.placeholder-purple-700::-ms-input-placeholder{--placeholder-opacity:1;color:#6b46c1;color:rgba(107,70,193,var(--placeholder-opacity))}.placeholder-purple-700::placeholder{--placeholder-opacity:1;color:#6b46c1;color:rgba(107,70,193,var(--placeholder-opacity))}.placeholder-purple-800:-ms-input-placeholder{--placeholder-opacity:1;color:#553c9a;color:rgba(85,60,154,var(--placeholder-opacity))}.placeholder-purple-800::-ms-input-placeholder{--placeholder-opacity:1;color:#553c9a;color:rgba(85,60,154,var(--placeholder-opacity))}.placeholder-purple-800::placeholder{--placeholder-opacity:1;color:#553c9a;color:rgba(85,60,154,var(--placeholder-opacity))}.placeholder-purple-900:-ms-input-placeholder{--placeholder-opacity:1;color:#44337a;color:rgba(68,51,122,var(--placeholder-opacity))}.placeholder-purple-900::-ms-input-placeholder{--placeholder-opacity:1;color:#44337a;color:rgba(68,51,122,var(--placeholder-opacity))}.placeholder-purple-900::placeholder{--placeholder-opacity:1;color:#44337a;color:rgba(68,51,122,var(--placeholder-opacity))}.placeholder-pink-100:-ms-input-placeholder{--placeholder-opacity:1;color:#fff5f7;color:rgba(255,245,247,var(--placeholder-opacity))}.placeholder-pink-100::-ms-input-placeholder{--placeholder-opacity:1;color:#fff5f7;color:rgba(255,245,247,var(--placeholder-opacity))}.placeholder-pink-100::placeholder{--placeholder-opacity:1;color:#fff5f7;color:rgba(255,245,247,var(--placeholder-opacity))}.placeholder-pink-200:-ms-input-placeholder{--placeholder-opacity:1;color:#fed7e2;color:rgba(254,215,226,var(--placeholder-opacity))}.placeholder-pink-200::-ms-input-placeholder{--placeholder-opacity:1;color:#fed7e2;color:rgba(254,215,226,var(--placeholder-opacity))}.placeholder-pink-200::placeholder{--placeholder-opacity:1;color:#fed7e2;color:rgba(254,215,226,var(--placeholder-opacity))}.placeholder-pink-300:-ms-input-placeholder{--placeholder-opacity:1;color:#fbb6ce;color:rgba(251,182,206,var(--placeholder-opacity))}.placeholder-pink-300::-ms-input-placeholder{--placeholder-opacity:1;color:#fbb6ce;color:rgba(251,182,206,var(--placeholder-opacity))}.placeholder-pink-300::placeholder{--placeholder-opacity:1;color:#fbb6ce;color:rgba(251,182,206,var(--placeholder-opacity))}.placeholder-pink-400:-ms-input-placeholder{--placeholder-opacity:1;color:#f687b3;color:rgba(246,135,179,var(--placeholder-opacity))}.placeholder-pink-400::-ms-input-placeholder{--placeholder-opacity:1;color:#f687b3;color:rgba(246,135,179,var(--placeholder-opacity))}.placeholder-pink-400::placeholder{--placeholder-opacity:1;color:#f687b3;color:rgba(246,135,179,var(--placeholder-opacity))}.placeholder-pink-500:-ms-input-placeholder{--placeholder-opacity:1;color:#ed64a6;color:rgba(237,100,166,var(--placeholder-opacity))}.placeholder-pink-500::-ms-input-placeholder{--placeholder-opacity:1;color:#ed64a6;color:rgba(237,100,166,var(--placeholder-opacity))}.placeholder-pink-500::placeholder{--placeholder-opacity:1;color:#ed64a6;color:rgba(237,100,166,var(--placeholder-opacity))}.placeholder-pink-600:-ms-input-placeholder{--placeholder-opacity:1;color:#d53f8c;color:rgba(213,63,140,var(--placeholder-opacity))}.placeholder-pink-600::-ms-input-placeholder{--placeholder-opacity:1;color:#d53f8c;color:rgba(213,63,140,var(--placeholder-opacity))}.placeholder-pink-600::placeholder{--placeholder-opacity:1;color:#d53f8c;color:rgba(213,63,140,var(--placeholder-opacity))}.placeholder-pink-700:-ms-input-placeholder{--placeholder-opacity:1;color:#b83280;color:rgba(184,50,128,var(--placeholder-opacity))}.placeholder-pink-700::-ms-input-placeholder{--placeholder-opacity:1;color:#b83280;color:rgba(184,50,128,var(--placeholder-opacity))}.placeholder-pink-700::placeholder{--placeholder-opacity:1;color:#b83280;color:rgba(184,50,128,var(--placeholder-opacity))}.placeholder-pink-800:-ms-input-placeholder{--placeholder-opacity:1;color:#97266d;color:rgba(151,38,109,var(--placeholder-opacity))}.placeholder-pink-800::-ms-input-placeholder{--placeholder-opacity:1;color:#97266d;color:rgba(151,38,109,var(--placeholder-opacity))}.placeholder-pink-800::placeholder{--placeholder-opacity:1;color:#97266d;color:rgba(151,38,109,var(--placeholder-opacity))}.placeholder-pink-900:-ms-input-placeholder{--placeholder-opacity:1;color:#702459;color:rgba(112,36,89,var(--placeholder-opacity))}.placeholder-pink-900::-ms-input-placeholder{--placeholder-opacity:1;color:#702459;color:rgba(112,36,89,var(--placeholder-opacity))}.placeholder-pink-900::placeholder{--placeholder-opacity:1;color:#702459;color:rgba(112,36,89,var(--placeholder-opacity))}.focus\:placeholder-transparent:focus:-ms-input-placeholder{color:transparent}.focus\:placeholder-transparent:focus::-ms-input-placeholder{color:transparent}.focus\:placeholder-transparent:focus::placeholder{color:transparent}.focus\:placeholder-current:focus:-ms-input-placeholder{color:currentColor}.focus\:placeholder-current:focus::-ms-input-placeholder{color:currentColor}.focus\:placeholder-current:focus::placeholder{color:currentColor}.focus\:placeholder-black:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#000;color:rgba(0,0,0,var(--placeholder-opacity))}.focus\:placeholder-black:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#000;color:rgba(0,0,0,var(--placeholder-opacity))}.focus\:placeholder-black:focus::placeholder{--placeholder-opacity:1;color:#000;color:rgba(0,0,0,var(--placeholder-opacity))}.focus\:placeholder-white:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#fff;color:rgba(255,255,255,var(--placeholder-opacity))}.focus\:placeholder-white:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#fff;color:rgba(255,255,255,var(--placeholder-opacity))}.focus\:placeholder-white:focus::placeholder{--placeholder-opacity:1;color:#fff;color:rgba(255,255,255,var(--placeholder-opacity))}.focus\:placeholder-gray-100:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#f7fafc;color:rgba(247,250,252,var(--placeholder-opacity))}.focus\:placeholder-gray-100:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#f7fafc;color:rgba(247,250,252,var(--placeholder-opacity))}.focus\:placeholder-gray-100:focus::placeholder{--placeholder-opacity:1;color:#f7fafc;color:rgba(247,250,252,var(--placeholder-opacity))}.focus\:placeholder-gray-200:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#edf2f7;color:rgba(237,242,247,var(--placeholder-opacity))}.focus\:placeholder-gray-200:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#edf2f7;color:rgba(237,242,247,var(--placeholder-opacity))}.focus\:placeholder-gray-200:focus::placeholder{--placeholder-opacity:1;color:#edf2f7;color:rgba(237,242,247,var(--placeholder-opacity))}.focus\:placeholder-gray-300:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#e2e8f0;color:rgba(226,232,240,var(--placeholder-opacity))}.focus\:placeholder-gray-300:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#e2e8f0;color:rgba(226,232,240,var(--placeholder-opacity))}.focus\:placeholder-gray-300:focus::placeholder{--placeholder-opacity:1;color:#e2e8f0;color:rgba(226,232,240,var(--placeholder-opacity))}.focus\:placeholder-gray-400:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#cbd5e0;color:rgba(203,213,224,var(--placeholder-opacity))}.focus\:placeholder-gray-400:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#cbd5e0;color:rgba(203,213,224,var(--placeholder-opacity))}.focus\:placeholder-gray-400:focus::placeholder{--placeholder-opacity:1;color:#cbd5e0;color:rgba(203,213,224,var(--placeholder-opacity))}.focus\:placeholder-gray-500:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#a0aec0;color:rgba(160,174,192,var(--placeholder-opacity))}.focus\:placeholder-gray-500:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#a0aec0;color:rgba(160,174,192,var(--placeholder-opacity))}.focus\:placeholder-gray-500:focus::placeholder{--placeholder-opacity:1;color:#a0aec0;color:rgba(160,174,192,var(--placeholder-opacity))}.focus\:placeholder-gray-600:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#718096;color:rgba(113,128,150,var(--placeholder-opacity))}.focus\:placeholder-gray-600:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#718096;color:rgba(113,128,150,var(--placeholder-opacity))}.focus\:placeholder-gray-600:focus::placeholder{--placeholder-opacity:1;color:#718096;color:rgba(113,128,150,var(--placeholder-opacity))}.focus\:placeholder-gray-700:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#4a5568;color:rgba(74,85,104,var(--placeholder-opacity))}.focus\:placeholder-gray-700:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#4a5568;color:rgba(74,85,104,var(--placeholder-opacity))}.focus\:placeholder-gray-700:focus::placeholder{--placeholder-opacity:1;color:#4a5568;color:rgba(74,85,104,var(--placeholder-opacity))}.focus\:placeholder-gray-800:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#2d3748;color:rgba(45,55,72,var(--placeholder-opacity))}.focus\:placeholder-gray-800:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#2d3748;color:rgba(45,55,72,var(--placeholder-opacity))}.focus\:placeholder-gray-800:focus::placeholder{--placeholder-opacity:1;color:#2d3748;color:rgba(45,55,72,var(--placeholder-opacity))}.focus\:placeholder-gray-900:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#1a202c;color:rgba(26,32,44,var(--placeholder-opacity))}.focus\:placeholder-gray-900:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#1a202c;color:rgba(26,32,44,var(--placeholder-opacity))}.focus\:placeholder-gray-900:focus::placeholder{--placeholder-opacity:1;color:#1a202c;color:rgba(26,32,44,var(--placeholder-opacity))}.focus\:placeholder-red-100:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#fff5f5;color:rgba(255,245,245,var(--placeholder-opacity))}.focus\:placeholder-red-100:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#fff5f5;color:rgba(255,245,245,var(--placeholder-opacity))}.focus\:placeholder-red-100:focus::placeholder{--placeholder-opacity:1;color:#fff5f5;color:rgba(255,245,245,var(--placeholder-opacity))}.focus\:placeholder-red-200:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#fed7d7;color:rgba(254,215,215,var(--placeholder-opacity))}.focus\:placeholder-red-200:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#fed7d7;color:rgba(254,215,215,var(--placeholder-opacity))}.focus\:placeholder-red-200:focus::placeholder{--placeholder-opacity:1;color:#fed7d7;color:rgba(254,215,215,var(--placeholder-opacity))}.focus\:placeholder-red-300:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#feb2b2;color:rgba(254,178,178,var(--placeholder-opacity))}.focus\:placeholder-red-300:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#feb2b2;color:rgba(254,178,178,var(--placeholder-opacity))}.focus\:placeholder-red-300:focus::placeholder{--placeholder-opacity:1;color:#feb2b2;color:rgba(254,178,178,var(--placeholder-opacity))}.focus\:placeholder-red-400:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#fc8181;color:rgba(252,129,129,var(--placeholder-opacity))}.focus\:placeholder-red-400:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#fc8181;color:rgba(252,129,129,var(--placeholder-opacity))}.focus\:placeholder-red-400:focus::placeholder{--placeholder-opacity:1;color:#fc8181;color:rgba(252,129,129,var(--placeholder-opacity))}.focus\:placeholder-red-500:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#f56565;color:rgba(245,101,101,var(--placeholder-opacity))}.focus\:placeholder-red-500:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#f56565;color:rgba(245,101,101,var(--placeholder-opacity))}.focus\:placeholder-red-500:focus::placeholder{--placeholder-opacity:1;color:#f56565;color:rgba(245,101,101,var(--placeholder-opacity))}.focus\:placeholder-red-600:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#e53e3e;color:rgba(229,62,62,var(--placeholder-opacity))}.focus\:placeholder-red-600:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#e53e3e;color:rgba(229,62,62,var(--placeholder-opacity))}.focus\:placeholder-red-600:focus::placeholder{--placeholder-opacity:1;color:#e53e3e;color:rgba(229,62,62,var(--placeholder-opacity))}.focus\:placeholder-red-700:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#c53030;color:rgba(197,48,48,var(--placeholder-opacity))}.focus\:placeholder-red-700:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#c53030;color:rgba(197,48,48,var(--placeholder-opacity))}.focus\:placeholder-red-700:focus::placeholder{--placeholder-opacity:1;color:#c53030;color:rgba(197,48,48,var(--placeholder-opacity))}.focus\:placeholder-red-800:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#9b2c2c;color:rgba(155,44,44,var(--placeholder-opacity))}.focus\:placeholder-red-800:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#9b2c2c;color:rgba(155,44,44,var(--placeholder-opacity))}.focus\:placeholder-red-800:focus::placeholder{--placeholder-opacity:1;color:#9b2c2c;color:rgba(155,44,44,var(--placeholder-opacity))}.focus\:placeholder-red-900:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#742a2a;color:rgba(116,42,42,var(--placeholder-opacity))}.focus\:placeholder-red-900:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#742a2a;color:rgba(116,42,42,var(--placeholder-opacity))}.focus\:placeholder-red-900:focus::placeholder{--placeholder-opacity:1;color:#742a2a;color:rgba(116,42,42,var(--placeholder-opacity))}.focus\:placeholder-orange-100:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#fffaf0;color:rgba(255,250,240,var(--placeholder-opacity))}.focus\:placeholder-orange-100:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#fffaf0;color:rgba(255,250,240,var(--placeholder-opacity))}.focus\:placeholder-orange-100:focus::placeholder{--placeholder-opacity:1;color:#fffaf0;color:rgba(255,250,240,var(--placeholder-opacity))}.focus\:placeholder-orange-200:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#feebc8;color:rgba(254,235,200,var(--placeholder-opacity))}.focus\:placeholder-orange-200:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#feebc8;color:rgba(254,235,200,var(--placeholder-opacity))}.focus\:placeholder-orange-200:focus::placeholder{--placeholder-opacity:1;color:#feebc8;color:rgba(254,235,200,var(--placeholder-opacity))}.focus\:placeholder-orange-300:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#fbd38d;color:rgba(251,211,141,var(--placeholder-opacity))}.focus\:placeholder-orange-300:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#fbd38d;color:rgba(251,211,141,var(--placeholder-opacity))}.focus\:placeholder-orange-300:focus::placeholder{--placeholder-opacity:1;color:#fbd38d;color:rgba(251,211,141,var(--placeholder-opacity))}.focus\:placeholder-orange-400:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#f6ad55;color:rgba(246,173,85,var(--placeholder-opacity))}.focus\:placeholder-orange-400:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#f6ad55;color:rgba(246,173,85,var(--placeholder-opacity))}.focus\:placeholder-orange-400:focus::placeholder{--placeholder-opacity:1;color:#f6ad55;color:rgba(246,173,85,var(--placeholder-opacity))}.focus\:placeholder-orange-500:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#ed8936;color:rgba(237,137,54,var(--placeholder-opacity))}.focus\:placeholder-orange-500:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#ed8936;color:rgba(237,137,54,var(--placeholder-opacity))}.focus\:placeholder-orange-500:focus::placeholder{--placeholder-opacity:1;color:#ed8936;color:rgba(237,137,54,var(--placeholder-opacity))}.focus\:placeholder-orange-600:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#dd6b20;color:rgba(221,107,32,var(--placeholder-opacity))}.focus\:placeholder-orange-600:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#dd6b20;color:rgba(221,107,32,var(--placeholder-opacity))}.focus\:placeholder-orange-600:focus::placeholder{--placeholder-opacity:1;color:#dd6b20;color:rgba(221,107,32,var(--placeholder-opacity))}.focus\:placeholder-orange-700:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#c05621;color:rgba(192,86,33,var(--placeholder-opacity))}.focus\:placeholder-orange-700:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#c05621;color:rgba(192,86,33,var(--placeholder-opacity))}.focus\:placeholder-orange-700:focus::placeholder{--placeholder-opacity:1;color:#c05621;color:rgba(192,86,33,var(--placeholder-opacity))}.focus\:placeholder-orange-800:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#9c4221;color:rgba(156,66,33,var(--placeholder-opacity))}.focus\:placeholder-orange-800:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#9c4221;color:rgba(156,66,33,var(--placeholder-opacity))}.focus\:placeholder-orange-800:focus::placeholder{--placeholder-opacity:1;color:#9c4221;color:rgba(156,66,33,var(--placeholder-opacity))}.focus\:placeholder-orange-900:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#7b341e;color:rgba(123,52,30,var(--placeholder-opacity))}.focus\:placeholder-orange-900:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#7b341e;color:rgba(123,52,30,var(--placeholder-opacity))}.focus\:placeholder-orange-900:focus::placeholder{--placeholder-opacity:1;color:#7b341e;color:rgba(123,52,30,var(--placeholder-opacity))}.focus\:placeholder-yellow-100:focus:-ms-input-placeholder{--placeholder-opacity:1;color:ivory;color:rgba(255,255,240,var(--placeholder-opacity))}.focus\:placeholder-yellow-100:focus::-ms-input-placeholder{--placeholder-opacity:1;color:ivory;color:rgba(255,255,240,var(--placeholder-opacity))}.focus\:placeholder-yellow-100:focus::placeholder{--placeholder-opacity:1;color:ivory;color:rgba(255,255,240,var(--placeholder-opacity))}.focus\:placeholder-yellow-200:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#fefcbf;color:rgba(254,252,191,var(--placeholder-opacity))}.focus\:placeholder-yellow-200:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#fefcbf;color:rgba(254,252,191,var(--placeholder-opacity))}.focus\:placeholder-yellow-200:focus::placeholder{--placeholder-opacity:1;color:#fefcbf;color:rgba(254,252,191,var(--placeholder-opacity))}.focus\:placeholder-yellow-300:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#faf089;color:rgba(250,240,137,var(--placeholder-opacity))}.focus\:placeholder-yellow-300:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#faf089;color:rgba(250,240,137,var(--placeholder-opacity))}.focus\:placeholder-yellow-300:focus::placeholder{--placeholder-opacity:1;color:#faf089;color:rgba(250,240,137,var(--placeholder-opacity))}.focus\:placeholder-yellow-400:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#f6e05e;color:rgba(246,224,94,var(--placeholder-opacity))}.focus\:placeholder-yellow-400:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#f6e05e;color:rgba(246,224,94,var(--placeholder-opacity))}.focus\:placeholder-yellow-400:focus::placeholder{--placeholder-opacity:1;color:#f6e05e;color:rgba(246,224,94,var(--placeholder-opacity))}.focus\:placeholder-yellow-500:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#ecc94b;color:rgba(236,201,75,var(--placeholder-opacity))}.focus\:placeholder-yellow-500:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#ecc94b;color:rgba(236,201,75,var(--placeholder-opacity))}.focus\:placeholder-yellow-500:focus::placeholder{--placeholder-opacity:1;color:#ecc94b;color:rgba(236,201,75,var(--placeholder-opacity))}.focus\:placeholder-yellow-600:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#d69e2e;color:rgba(214,158,46,var(--placeholder-opacity))}.focus\:placeholder-yellow-600:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#d69e2e;color:rgba(214,158,46,var(--placeholder-opacity))}.focus\:placeholder-yellow-600:focus::placeholder{--placeholder-opacity:1;color:#d69e2e;color:rgba(214,158,46,var(--placeholder-opacity))}.focus\:placeholder-yellow-700:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#b7791f;color:rgba(183,121,31,var(--placeholder-opacity))}.focus\:placeholder-yellow-700:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#b7791f;color:rgba(183,121,31,var(--placeholder-opacity))}.focus\:placeholder-yellow-700:focus::placeholder{--placeholder-opacity:1;color:#b7791f;color:rgba(183,121,31,var(--placeholder-opacity))}.focus\:placeholder-yellow-800:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#975a16;color:rgba(151,90,22,var(--placeholder-opacity))}.focus\:placeholder-yellow-800:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#975a16;color:rgba(151,90,22,var(--placeholder-opacity))}.focus\:placeholder-yellow-800:focus::placeholder{--placeholder-opacity:1;color:#975a16;color:rgba(151,90,22,var(--placeholder-opacity))}.focus\:placeholder-yellow-900:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#744210;color:rgba(116,66,16,var(--placeholder-opacity))}.focus\:placeholder-yellow-900:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#744210;color:rgba(116,66,16,var(--placeholder-opacity))}.focus\:placeholder-yellow-900:focus::placeholder{--placeholder-opacity:1;color:#744210;color:rgba(116,66,16,var(--placeholder-opacity))}.focus\:placeholder-green-100:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#f0fff4;color:rgba(240,255,244,var(--placeholder-opacity))}.focus\:placeholder-green-100:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#f0fff4;color:rgba(240,255,244,var(--placeholder-opacity))}.focus\:placeholder-green-100:focus::placeholder{--placeholder-opacity:1;color:#f0fff4;color:rgba(240,255,244,var(--placeholder-opacity))}.focus\:placeholder-green-200:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#c6f6d5;color:rgba(198,246,213,var(--placeholder-opacity))}.focus\:placeholder-green-200:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#c6f6d5;color:rgba(198,246,213,var(--placeholder-opacity))}.focus\:placeholder-green-200:focus::placeholder{--placeholder-opacity:1;color:#c6f6d5;color:rgba(198,246,213,var(--placeholder-opacity))}.focus\:placeholder-green-300:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#9ae6b4;color:rgba(154,230,180,var(--placeholder-opacity))}.focus\:placeholder-green-300:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#9ae6b4;color:rgba(154,230,180,var(--placeholder-opacity))}.focus\:placeholder-green-300:focus::placeholder{--placeholder-opacity:1;color:#9ae6b4;color:rgba(154,230,180,var(--placeholder-opacity))}.focus\:placeholder-green-400:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#68d391;color:rgba(104,211,145,var(--placeholder-opacity))}.focus\:placeholder-green-400:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#68d391;color:rgba(104,211,145,var(--placeholder-opacity))}.focus\:placeholder-green-400:focus::placeholder{--placeholder-opacity:1;color:#68d391;color:rgba(104,211,145,var(--placeholder-opacity))}.focus\:placeholder-green-500:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#48bb78;color:rgba(72,187,120,var(--placeholder-opacity))}.focus\:placeholder-green-500:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#48bb78;color:rgba(72,187,120,var(--placeholder-opacity))}.focus\:placeholder-green-500:focus::placeholder{--placeholder-opacity:1;color:#48bb78;color:rgba(72,187,120,var(--placeholder-opacity))}.focus\:placeholder-green-600:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#38a169;color:rgba(56,161,105,var(--placeholder-opacity))}.focus\:placeholder-green-600:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#38a169;color:rgba(56,161,105,var(--placeholder-opacity))}.focus\:placeholder-green-600:focus::placeholder{--placeholder-opacity:1;color:#38a169;color:rgba(56,161,105,var(--placeholder-opacity))}.focus\:placeholder-green-700:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#2f855a;color:rgba(47,133,90,var(--placeholder-opacity))}.focus\:placeholder-green-700:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#2f855a;color:rgba(47,133,90,var(--placeholder-opacity))}.focus\:placeholder-green-700:focus::placeholder{--placeholder-opacity:1;color:#2f855a;color:rgba(47,133,90,var(--placeholder-opacity))}.focus\:placeholder-green-800:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#276749;color:rgba(39,103,73,var(--placeholder-opacity))}.focus\:placeholder-green-800:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#276749;color:rgba(39,103,73,var(--placeholder-opacity))}.focus\:placeholder-green-800:focus::placeholder{--placeholder-opacity:1;color:#276749;color:rgba(39,103,73,var(--placeholder-opacity))}.focus\:placeholder-green-900:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#22543d;color:rgba(34,84,61,var(--placeholder-opacity))}.focus\:placeholder-green-900:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#22543d;color:rgba(34,84,61,var(--placeholder-opacity))}.focus\:placeholder-green-900:focus::placeholder{--placeholder-opacity:1;color:#22543d;color:rgba(34,84,61,var(--placeholder-opacity))}.focus\:placeholder-teal-100:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#e6fffa;color:rgba(230,255,250,var(--placeholder-opacity))}.focus\:placeholder-teal-100:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#e6fffa;color:rgba(230,255,250,var(--placeholder-opacity))}.focus\:placeholder-teal-100:focus::placeholder{--placeholder-opacity:1;color:#e6fffa;color:rgba(230,255,250,var(--placeholder-opacity))}.focus\:placeholder-teal-200:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#b2f5ea;color:rgba(178,245,234,var(--placeholder-opacity))}.focus\:placeholder-teal-200:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#b2f5ea;color:rgba(178,245,234,var(--placeholder-opacity))}.focus\:placeholder-teal-200:focus::placeholder{--placeholder-opacity:1;color:#b2f5ea;color:rgba(178,245,234,var(--placeholder-opacity))}.focus\:placeholder-teal-300:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#81e6d9;color:rgba(129,230,217,var(--placeholder-opacity))}.focus\:placeholder-teal-300:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#81e6d9;color:rgba(129,230,217,var(--placeholder-opacity))}.focus\:placeholder-teal-300:focus::placeholder{--placeholder-opacity:1;color:#81e6d9;color:rgba(129,230,217,var(--placeholder-opacity))}.focus\:placeholder-teal-400:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#4fd1c5;color:rgba(79,209,197,var(--placeholder-opacity))}.focus\:placeholder-teal-400:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#4fd1c5;color:rgba(79,209,197,var(--placeholder-opacity))}.focus\:placeholder-teal-400:focus::placeholder{--placeholder-opacity:1;color:#4fd1c5;color:rgba(79,209,197,var(--placeholder-opacity))}.focus\:placeholder-teal-500:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#38b2ac;color:rgba(56,178,172,var(--placeholder-opacity))}.focus\:placeholder-teal-500:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#38b2ac;color:rgba(56,178,172,var(--placeholder-opacity))}.focus\:placeholder-teal-500:focus::placeholder{--placeholder-opacity:1;color:#38b2ac;color:rgba(56,178,172,var(--placeholder-opacity))}.focus\:placeholder-teal-600:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#319795;color:rgba(49,151,149,var(--placeholder-opacity))}.focus\:placeholder-teal-600:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#319795;color:rgba(49,151,149,var(--placeholder-opacity))}.focus\:placeholder-teal-600:focus::placeholder{--placeholder-opacity:1;color:#319795;color:rgba(49,151,149,var(--placeholder-opacity))}.focus\:placeholder-teal-700:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#2c7a7b;color:rgba(44,122,123,var(--placeholder-opacity))}.focus\:placeholder-teal-700:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#2c7a7b;color:rgba(44,122,123,var(--placeholder-opacity))}.focus\:placeholder-teal-700:focus::placeholder{--placeholder-opacity:1;color:#2c7a7b;color:rgba(44,122,123,var(--placeholder-opacity))}.focus\:placeholder-teal-800:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#285e61;color:rgba(40,94,97,var(--placeholder-opacity))}.focus\:placeholder-teal-800:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#285e61;color:rgba(40,94,97,var(--placeholder-opacity))}.focus\:placeholder-teal-800:focus::placeholder{--placeholder-opacity:1;color:#285e61;color:rgba(40,94,97,var(--placeholder-opacity))}.focus\:placeholder-teal-900:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#234e52;color:rgba(35,78,82,var(--placeholder-opacity))}.focus\:placeholder-teal-900:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#234e52;color:rgba(35,78,82,var(--placeholder-opacity))}.focus\:placeholder-teal-900:focus::placeholder{--placeholder-opacity:1;color:#234e52;color:rgba(35,78,82,var(--placeholder-opacity))}.focus\:placeholder-blue-100:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#ebf8ff;color:rgba(235,248,255,var(--placeholder-opacity))}.focus\:placeholder-blue-100:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#ebf8ff;color:rgba(235,248,255,var(--placeholder-opacity))}.focus\:placeholder-blue-100:focus::placeholder{--placeholder-opacity:1;color:#ebf8ff;color:rgba(235,248,255,var(--placeholder-opacity))}.focus\:placeholder-blue-200:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#bee3f8;color:rgba(190,227,248,var(--placeholder-opacity))}.focus\:placeholder-blue-200:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#bee3f8;color:rgba(190,227,248,var(--placeholder-opacity))}.focus\:placeholder-blue-200:focus::placeholder{--placeholder-opacity:1;color:#bee3f8;color:rgba(190,227,248,var(--placeholder-opacity))}.focus\:placeholder-blue-300:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#90cdf4;color:rgba(144,205,244,var(--placeholder-opacity))}.focus\:placeholder-blue-300:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#90cdf4;color:rgba(144,205,244,var(--placeholder-opacity))}.focus\:placeholder-blue-300:focus::placeholder{--placeholder-opacity:1;color:#90cdf4;color:rgba(144,205,244,var(--placeholder-opacity))}.focus\:placeholder-blue-400:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#63b3ed;color:rgba(99,179,237,var(--placeholder-opacity))}.focus\:placeholder-blue-400:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#63b3ed;color:rgba(99,179,237,var(--placeholder-opacity))}.focus\:placeholder-blue-400:focus::placeholder{--placeholder-opacity:1;color:#63b3ed;color:rgba(99,179,237,var(--placeholder-opacity))}.focus\:placeholder-blue-500:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#4299e1;color:rgba(66,153,225,var(--placeholder-opacity))}.focus\:placeholder-blue-500:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#4299e1;color:rgba(66,153,225,var(--placeholder-opacity))}.focus\:placeholder-blue-500:focus::placeholder{--placeholder-opacity:1;color:#4299e1;color:rgba(66,153,225,var(--placeholder-opacity))}.focus\:placeholder-blue-600:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#3182ce;color:rgba(49,130,206,var(--placeholder-opacity))}.focus\:placeholder-blue-600:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#3182ce;color:rgba(49,130,206,var(--placeholder-opacity))}.focus\:placeholder-blue-600:focus::placeholder{--placeholder-opacity:1;color:#3182ce;color:rgba(49,130,206,var(--placeholder-opacity))}.focus\:placeholder-blue-700:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#2b6cb0;color:rgba(43,108,176,var(--placeholder-opacity))}.focus\:placeholder-blue-700:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#2b6cb0;color:rgba(43,108,176,var(--placeholder-opacity))}.focus\:placeholder-blue-700:focus::placeholder{--placeholder-opacity:1;color:#2b6cb0;color:rgba(43,108,176,var(--placeholder-opacity))}.focus\:placeholder-blue-800:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#2c5282;color:rgba(44,82,130,var(--placeholder-opacity))}.focus\:placeholder-blue-800:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#2c5282;color:rgba(44,82,130,var(--placeholder-opacity))}.focus\:placeholder-blue-800:focus::placeholder{--placeholder-opacity:1;color:#2c5282;color:rgba(44,82,130,var(--placeholder-opacity))}.focus\:placeholder-blue-900:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#2a4365;color:rgba(42,67,101,var(--placeholder-opacity))}.focus\:placeholder-blue-900:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#2a4365;color:rgba(42,67,101,var(--placeholder-opacity))}.focus\:placeholder-blue-900:focus::placeholder{--placeholder-opacity:1;color:#2a4365;color:rgba(42,67,101,var(--placeholder-opacity))}.focus\:placeholder-indigo-100:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#ebf4ff;color:rgba(235,244,255,var(--placeholder-opacity))}.focus\:placeholder-indigo-100:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#ebf4ff;color:rgba(235,244,255,var(--placeholder-opacity))}.focus\:placeholder-indigo-100:focus::placeholder{--placeholder-opacity:1;color:#ebf4ff;color:rgba(235,244,255,var(--placeholder-opacity))}.focus\:placeholder-indigo-200:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#c3dafe;color:rgba(195,218,254,var(--placeholder-opacity))}.focus\:placeholder-indigo-200:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#c3dafe;color:rgba(195,218,254,var(--placeholder-opacity))}.focus\:placeholder-indigo-200:focus::placeholder{--placeholder-opacity:1;color:#c3dafe;color:rgba(195,218,254,var(--placeholder-opacity))}.focus\:placeholder-indigo-300:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#a3bffa;color:rgba(163,191,250,var(--placeholder-opacity))}.focus\:placeholder-indigo-300:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#a3bffa;color:rgba(163,191,250,var(--placeholder-opacity))}.focus\:placeholder-indigo-300:focus::placeholder{--placeholder-opacity:1;color:#a3bffa;color:rgba(163,191,250,var(--placeholder-opacity))}.focus\:placeholder-indigo-400:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#7f9cf5;color:rgba(127,156,245,var(--placeholder-opacity))}.focus\:placeholder-indigo-400:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#7f9cf5;color:rgba(127,156,245,var(--placeholder-opacity))}.focus\:placeholder-indigo-400:focus::placeholder{--placeholder-opacity:1;color:#7f9cf5;color:rgba(127,156,245,var(--placeholder-opacity))}.focus\:placeholder-indigo-500:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#667eea;color:rgba(102,126,234,var(--placeholder-opacity))}.focus\:placeholder-indigo-500:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#667eea;color:rgba(102,126,234,var(--placeholder-opacity))}.focus\:placeholder-indigo-500:focus::placeholder{--placeholder-opacity:1;color:#667eea;color:rgba(102,126,234,var(--placeholder-opacity))}.focus\:placeholder-indigo-600:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#5a67d8;color:rgba(90,103,216,var(--placeholder-opacity))}.focus\:placeholder-indigo-600:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#5a67d8;color:rgba(90,103,216,var(--placeholder-opacity))}.focus\:placeholder-indigo-600:focus::placeholder{--placeholder-opacity:1;color:#5a67d8;color:rgba(90,103,216,var(--placeholder-opacity))}.focus\:placeholder-indigo-700:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#4c51bf;color:rgba(76,81,191,var(--placeholder-opacity))}.focus\:placeholder-indigo-700:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#4c51bf;color:rgba(76,81,191,var(--placeholder-opacity))}.focus\:placeholder-indigo-700:focus::placeholder{--placeholder-opacity:1;color:#4c51bf;color:rgba(76,81,191,var(--placeholder-opacity))}.focus\:placeholder-indigo-800:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#434190;color:rgba(67,65,144,var(--placeholder-opacity))}.focus\:placeholder-indigo-800:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#434190;color:rgba(67,65,144,var(--placeholder-opacity))}.focus\:placeholder-indigo-800:focus::placeholder{--placeholder-opacity:1;color:#434190;color:rgba(67,65,144,var(--placeholder-opacity))}.focus\:placeholder-indigo-900:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#3c366b;color:rgba(60,54,107,var(--placeholder-opacity))}.focus\:placeholder-indigo-900:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#3c366b;color:rgba(60,54,107,var(--placeholder-opacity))}.focus\:placeholder-indigo-900:focus::placeholder{--placeholder-opacity:1;color:#3c366b;color:rgba(60,54,107,var(--placeholder-opacity))}.focus\:placeholder-purple-100:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#faf5ff;color:rgba(250,245,255,var(--placeholder-opacity))}.focus\:placeholder-purple-100:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#faf5ff;color:rgba(250,245,255,var(--placeholder-opacity))}.focus\:placeholder-purple-100:focus::placeholder{--placeholder-opacity:1;color:#faf5ff;color:rgba(250,245,255,var(--placeholder-opacity))}.focus\:placeholder-purple-200:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#e9d8fd;color:rgba(233,216,253,var(--placeholder-opacity))}.focus\:placeholder-purple-200:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#e9d8fd;color:rgba(233,216,253,var(--placeholder-opacity))}.focus\:placeholder-purple-200:focus::placeholder{--placeholder-opacity:1;color:#e9d8fd;color:rgba(233,216,253,var(--placeholder-opacity))}.focus\:placeholder-purple-300:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#d6bcfa;color:rgba(214,188,250,var(--placeholder-opacity))}.focus\:placeholder-purple-300:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#d6bcfa;color:rgba(214,188,250,var(--placeholder-opacity))}.focus\:placeholder-purple-300:focus::placeholder{--placeholder-opacity:1;color:#d6bcfa;color:rgba(214,188,250,var(--placeholder-opacity))}.focus\:placeholder-purple-400:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#b794f4;color:rgba(183,148,244,var(--placeholder-opacity))}.focus\:placeholder-purple-400:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#b794f4;color:rgba(183,148,244,var(--placeholder-opacity))}.focus\:placeholder-purple-400:focus::placeholder{--placeholder-opacity:1;color:#b794f4;color:rgba(183,148,244,var(--placeholder-opacity))}.focus\:placeholder-purple-500:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#9f7aea;color:rgba(159,122,234,var(--placeholder-opacity))}.focus\:placeholder-purple-500:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#9f7aea;color:rgba(159,122,234,var(--placeholder-opacity))}.focus\:placeholder-purple-500:focus::placeholder{--placeholder-opacity:1;color:#9f7aea;color:rgba(159,122,234,var(--placeholder-opacity))}.focus\:placeholder-purple-600:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#805ad5;color:rgba(128,90,213,var(--placeholder-opacity))}.focus\:placeholder-purple-600:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#805ad5;color:rgba(128,90,213,var(--placeholder-opacity))}.focus\:placeholder-purple-600:focus::placeholder{--placeholder-opacity:1;color:#805ad5;color:rgba(128,90,213,var(--placeholder-opacity))}.focus\:placeholder-purple-700:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#6b46c1;color:rgba(107,70,193,var(--placeholder-opacity))}.focus\:placeholder-purple-700:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#6b46c1;color:rgba(107,70,193,var(--placeholder-opacity))}.focus\:placeholder-purple-700:focus::placeholder{--placeholder-opacity:1;color:#6b46c1;color:rgba(107,70,193,var(--placeholder-opacity))}.focus\:placeholder-purple-800:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#553c9a;color:rgba(85,60,154,var(--placeholder-opacity))}.focus\:placeholder-purple-800:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#553c9a;color:rgba(85,60,154,var(--placeholder-opacity))}.focus\:placeholder-purple-800:focus::placeholder{--placeholder-opacity:1;color:#553c9a;color:rgba(85,60,154,var(--placeholder-opacity))}.focus\:placeholder-purple-900:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#44337a;color:rgba(68,51,122,var(--placeholder-opacity))}.focus\:placeholder-purple-900:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#44337a;color:rgba(68,51,122,var(--placeholder-opacity))}.focus\:placeholder-purple-900:focus::placeholder{--placeholder-opacity:1;color:#44337a;color:rgba(68,51,122,var(--placeholder-opacity))}.focus\:placeholder-pink-100:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#fff5f7;color:rgba(255,245,247,var(--placeholder-opacity))}.focus\:placeholder-pink-100:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#fff5f7;color:rgba(255,245,247,var(--placeholder-opacity))}.focus\:placeholder-pink-100:focus::placeholder{--placeholder-opacity:1;color:#fff5f7;color:rgba(255,245,247,var(--placeholder-opacity))}.focus\:placeholder-pink-200:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#fed7e2;color:rgba(254,215,226,var(--placeholder-opacity))}.focus\:placeholder-pink-200:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#fed7e2;color:rgba(254,215,226,var(--placeholder-opacity))}.focus\:placeholder-pink-200:focus::placeholder{--placeholder-opacity:1;color:#fed7e2;color:rgba(254,215,226,var(--placeholder-opacity))}.focus\:placeholder-pink-300:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#fbb6ce;color:rgba(251,182,206,var(--placeholder-opacity))}.focus\:placeholder-pink-300:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#fbb6ce;color:rgba(251,182,206,var(--placeholder-opacity))}.focus\:placeholder-pink-300:focus::placeholder{--placeholder-opacity:1;color:#fbb6ce;color:rgba(251,182,206,var(--placeholder-opacity))}.focus\:placeholder-pink-400:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#f687b3;color:rgba(246,135,179,var(--placeholder-opacity))}.focus\:placeholder-pink-400:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#f687b3;color:rgba(246,135,179,var(--placeholder-opacity))}.focus\:placeholder-pink-400:focus::placeholder{--placeholder-opacity:1;color:#f687b3;color:rgba(246,135,179,var(--placeholder-opacity))}.focus\:placeholder-pink-500:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#ed64a6;color:rgba(237,100,166,var(--placeholder-opacity))}.focus\:placeholder-pink-500:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#ed64a6;color:rgba(237,100,166,var(--placeholder-opacity))}.focus\:placeholder-pink-500:focus::placeholder{--placeholder-opacity:1;color:#ed64a6;color:rgba(237,100,166,var(--placeholder-opacity))}.focus\:placeholder-pink-600:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#d53f8c;color:rgba(213,63,140,var(--placeholder-opacity))}.focus\:placeholder-pink-600:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#d53f8c;color:rgba(213,63,140,var(--placeholder-opacity))}.focus\:placeholder-pink-600:focus::placeholder{--placeholder-opacity:1;color:#d53f8c;color:rgba(213,63,140,var(--placeholder-opacity))}.focus\:placeholder-pink-700:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#b83280;color:rgba(184,50,128,var(--placeholder-opacity))}.focus\:placeholder-pink-700:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#b83280;color:rgba(184,50,128,var(--placeholder-opacity))}.focus\:placeholder-pink-700:focus::placeholder{--placeholder-opacity:1;color:#b83280;color:rgba(184,50,128,var(--placeholder-opacity))}.focus\:placeholder-pink-800:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#97266d;color:rgba(151,38,109,var(--placeholder-opacity))}.focus\:placeholder-pink-800:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#97266d;color:rgba(151,38,109,var(--placeholder-opacity))}.focus\:placeholder-pink-800:focus::placeholder{--placeholder-opacity:1;color:#97266d;color:rgba(151,38,109,var(--placeholder-opacity))}.focus\:placeholder-pink-900:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#702459;color:rgba(112,36,89,var(--placeholder-opacity))}.focus\:placeholder-pink-900:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#702459;color:rgba(112,36,89,var(--placeholder-opacity))}.focus\:placeholder-pink-900:focus::placeholder{--placeholder-opacity:1;color:#702459;color:rgba(112,36,89,var(--placeholder-opacity))}.placeholder-opacity-0:-ms-input-placeholder{--placeholder-opacity:0}.placeholder-opacity-0::-ms-input-placeholder{--placeholder-opacity:0}.placeholder-opacity-0::placeholder{--placeholder-opacity:0}.placeholder-opacity-25:-ms-input-placeholder{--placeholder-opacity:0.25}.placeholder-opacity-25::-ms-input-placeholder{--placeholder-opacity:0.25}.placeholder-opacity-25::placeholder{--placeholder-opacity:0.25}.placeholder-opacity-50:-ms-input-placeholder{--placeholder-opacity:0.5}.placeholder-opacity-50::-ms-input-placeholder{--placeholder-opacity:0.5}.placeholder-opacity-50::placeholder{--placeholder-opacity:0.5}.placeholder-opacity-75:-ms-input-placeholder{--placeholder-opacity:0.75}.placeholder-opacity-75::-ms-input-placeholder{--placeholder-opacity:0.75}.placeholder-opacity-75::placeholder{--placeholder-opacity:0.75}.placeholder-opacity-100:-ms-input-placeholder{--placeholder-opacity:1}.placeholder-opacity-100::-ms-input-placeholder{--placeholder-opacity:1}.placeholder-opacity-100::placeholder{--placeholder-opacity:1}.focus\:placeholder-opacity-0:focus:-ms-input-placeholder{--placeholder-opacity:0}.focus\:placeholder-opacity-0:focus::-ms-input-placeholder{--placeholder-opacity:0}.focus\:placeholder-opacity-0:focus::placeholder{--placeholder-opacity:0}.focus\:placeholder-opacity-25:focus:-ms-input-placeholder{--placeholder-opacity:0.25}.focus\:placeholder-opacity-25:focus::-ms-input-placeholder{--placeholder-opacity:0.25}.focus\:placeholder-opacity-25:focus::placeholder{--placeholder-opacity:0.25}.focus\:placeholder-opacity-50:focus:-ms-input-placeholder{--placeholder-opacity:0.5}.focus\:placeholder-opacity-50:focus::-ms-input-placeholder{--placeholder-opacity:0.5}.focus\:placeholder-opacity-50:focus::placeholder{--placeholder-opacity:0.5}.focus\:placeholder-opacity-75:focus:-ms-input-placeholder{--placeholder-opacity:0.75}.focus\:placeholder-opacity-75:focus::-ms-input-placeholder{--placeholder-opacity:0.75}.focus\:placeholder-opacity-75:focus::placeholder{--placeholder-opacity:0.75}.focus\:placeholder-opacity-100:focus:-ms-input-placeholder{--placeholder-opacity:1}.focus\:placeholder-opacity-100:focus::-ms-input-placeholder{--placeholder-opacity:1}.focus\:placeholder-opacity-100:focus::placeholder{--placeholder-opacity:1}.pointer-events-none{pointer-events:none}.pointer-events-auto{pointer-events:auto}.static{position:static}.fixed{position:fixed}.absolute{position:absolute}.relative{position:relative}.sticky{position:-webkit-sticky;position:sticky}.inset-0{top:0;right:0;bottom:0;left:0}.inset-auto{top:auto;right:auto;bottom:auto;left:auto}.inset-y-0{top:0;bottom:0}.inset-x-0{right:0;left:0}.inset-y-auto{top:auto;bottom:auto}.inset-x-auto{right:auto;left:auto}.top-0{top:0}.right-0{right:0}.bottom-0{bottom:0}.left-0{left:0}.top-auto{top:auto}.right-auto{right:auto}.bottom-auto{bottom:auto}.left-auto{left:auto}.resize-none{resize:none}.resize-y{resize:vertical}.resize-x{resize:horizontal}.resize{resize:both}.shadow-xs{box-shadow:0 0 0 1px rgba(0,0,0,.05)}.shadow-sm{box-shadow:0 1px 2px 0 rgba(0,0,0,.05)}.shadow{box-shadow:0 1px 3px 0 rgba(0,0,0,.1),0 1px 2px 0 rgba(0,0,0,.06)}.shadow-md{box-shadow:0 4px 6px -1px rgba(0,0,0,.1),0 2px 4px -1px rgba(0,0,0,.06)}.shadow-lg{box-shadow:0 10px 15px -3px rgba(0,0,0,.1),0 4px 6px -2px rgba(0,0,0,.05)}.shadow-xl{box-shadow:0 20px 25px -5px rgba(0,0,0,.1),0 10px 10px -5px rgba(0,0,0,.04)}.shadow-2xl{box-shadow:0 25px 50px -12px rgba(0,0,0,.25)}.shadow-inner{box-shadow:inset 0 2px 4px 0 rgba(0,0,0,.06)}.shadow-outline{box-shadow:0 0 0 3px rgba(66,153,225,.5)}.shadow-none{box-shadow:none}.hover\:shadow-xs:hover{box-shadow:0 0 0 1px rgba(0,0,0,.05)}.hover\:shadow-sm:hover{box-shadow:0 1px 2px 0 rgba(0,0,0,.05)}.hover\:shadow:hover{box-shadow:0 1px 3px 0 rgba(0,0,0,.1),0 1px 2px 0 rgba(0,0,0,.06)}.hover\:shadow-md:hover{box-shadow:0 4px 6px -1px rgba(0,0,0,.1),0 2px 4px -1px rgba(0,0,0,.06)}.hover\:shadow-lg:hover{box-shadow:0 10px 15px -3px rgba(0,0,0,.1),0 4px 6px -2px rgba(0,0,0,.05)}.hover\:shadow-xl:hover{box-shadow:0 20px 25px -5px rgba(0,0,0,.1),0 10px 10px -5px rgba(0,0,0,.04)}.hover\:shadow-2xl:hover{box-shadow:0 25px 50px -12px rgba(0,0,0,.25)}.hover\:shadow-inner:hover{box-shadow:inset 0 2px 4px 0 rgba(0,0,0,.06)}.hover\:shadow-outline:hover{box-shadow:0 0 0 3px rgba(66,153,225,.5)}.hover\:shadow-none:hover{box-shadow:none}.focus\:shadow-xs:focus{box-shadow:0 0 0 1px rgba(0,0,0,.05)}.focus\:shadow-sm:focus{box-shadow:0 1px 2px 0 rgba(0,0,0,.05)}.focus\:shadow:focus{box-shadow:0 1px 3px 0 rgba(0,0,0,.1),0 1px 2px 0 rgba(0,0,0,.06)}.focus\:shadow-md:focus{box-shadow:0 4px 6px -1px rgba(0,0,0,.1),0 2px 4px -1px rgba(0,0,0,.06)}.focus\:shadow-lg:focus{box-shadow:0 10px 15px -3px rgba(0,0,0,.1),0 4px 6px -2px rgba(0,0,0,.05)}.focus\:shadow-xl:focus{box-shadow:0 20px 25px -5px rgba(0,0,0,.1),0 10px 10px -5px rgba(0,0,0,.04)}.focus\:shadow-2xl:focus{box-shadow:0 25px 50px -12px rgba(0,0,0,.25)}.focus\:shadow-inner:focus{box-shadow:inset 0 2px 4px 0 rgba(0,0,0,.06)}.focus\:shadow-outline:focus{box-shadow:0 0 0 3px rgba(66,153,225,.5)}.focus\:shadow-none:focus{box-shadow:none}.fill-current{fill:currentColor}.stroke-current{stroke:currentColor}.stroke-0{stroke-width:0}.stroke-1{stroke-width:1}.stroke-2{stroke-width:2}.table-auto{table-layout:auto}.table-fixed{table-layout:fixed}.text-left{text-align:left}.text-center{text-align:center}.text-right{text-align:right}.text-justify{text-align:justify}.text-transparent{color:transparent}.text-current{color:currentColor}.text-black{--text-opacity:1;color:#000;color:rgba(0,0,0,var(--text-opacity))}.text-white{--text-opacity:1;color:#fff;color:rgba(255,255,255,var(--text-opacity))}.text-gray-100{--text-opacity:1;color:#f7fafc;color:rgba(247,250,252,var(--text-opacity))}.text-gray-200{--text-opacity:1;color:#edf2f7;color:rgba(237,242,247,var(--text-opacity))}.text-gray-300{--text-opacity:1;color:#e2e8f0;color:rgba(226,232,240,var(--text-opacity))}.text-gray-400{--text-opacity:1;color:#cbd5e0;color:rgba(203,213,224,var(--text-opacity))}.text-gray-500{--text-opacity:1;color:#a0aec0;color:rgba(160,174,192,var(--text-opacity))}.text-gray-600{--text-opacity:1;color:#718096;color:rgba(113,128,150,var(--text-opacity))}.text-gray-700{--text-opacity:1;color:#4a5568;color:rgba(74,85,104,var(--text-opacity))}.text-gray-800{--text-opacity:1;color:#2d3748;color:rgba(45,55,72,var(--text-opacity))}.text-gray-900{--text-opacity:1;color:#1a202c;color:rgba(26,32,44,var(--text-opacity))}.text-red-100{--text-opacity:1;color:#fff5f5;color:rgba(255,245,245,var(--text-opacity))}.text-red-200{--text-opacity:1;color:#fed7d7;color:rgba(254,215,215,var(--text-opacity))}.text-red-300{--text-opacity:1;color:#feb2b2;color:rgba(254,178,178,var(--text-opacity))}.text-red-400{--text-opacity:1;color:#fc8181;color:rgba(252,129,129,var(--text-opacity))}.text-red-500{--text-opacity:1;color:#f56565;color:rgba(245,101,101,var(--text-opacity))}.text-red-600{--text-opacity:1;color:#e53e3e;color:rgba(229,62,62,var(--text-opacity))}.text-red-700{--text-opacity:1;color:#c53030;color:rgba(197,48,48,var(--text-opacity))}.text-red-800{--text-opacity:1;color:#9b2c2c;color:rgba(155,44,44,var(--text-opacity))}.text-red-900{--text-opacity:1;color:#742a2a;color:rgba(116,42,42,var(--text-opacity))}.text-orange-100{--text-opacity:1;color:#fffaf0;color:rgba(255,250,240,var(--text-opacity))}.text-orange-200{--text-opacity:1;color:#feebc8;color:rgba(254,235,200,var(--text-opacity))}.text-orange-300{--text-opacity:1;color:#fbd38d;color:rgba(251,211,141,var(--text-opacity))}.text-orange-400{--text-opacity:1;color:#f6ad55;color:rgba(246,173,85,var(--text-opacity))}.text-orange-500{--text-opacity:1;color:#ed8936;color:rgba(237,137,54,var(--text-opacity))}.text-orange-600{--text-opacity:1;color:#dd6b20;color:rgba(221,107,32,var(--text-opacity))}.text-orange-700{--text-opacity:1;color:#c05621;color:rgba(192,86,33,var(--text-opacity))}.text-orange-800{--text-opacity:1;color:#9c4221;color:rgba(156,66,33,var(--text-opacity))}.text-orange-900{--text-opacity:1;color:#7b341e;color:rgba(123,52,30,var(--text-opacity))}.text-yellow-100{--text-opacity:1;color:ivory;color:rgba(255,255,240,var(--text-opacity))}.text-yellow-200{--text-opacity:1;color:#fefcbf;color:rgba(254,252,191,var(--text-opacity))}.text-yellow-300{--text-opacity:1;color:#faf089;color:rgba(250,240,137,var(--text-opacity))}.text-yellow-400{--text-opacity:1;color:#f6e05e;color:rgba(246,224,94,var(--text-opacity))}.text-yellow-500{--text-opacity:1;color:#ecc94b;color:rgba(236,201,75,var(--text-opacity))}.text-yellow-600{--text-opacity:1;color:#d69e2e;color:rgba(214,158,46,var(--text-opacity))}.text-yellow-700{--text-opacity:1;color:#b7791f;color:rgba(183,121,31,var(--text-opacity))}.text-yellow-800{--text-opacity:1;color:#975a16;color:rgba(151,90,22,var(--text-opacity))}.text-yellow-900{--text-opacity:1;color:#744210;color:rgba(116,66,16,var(--text-opacity))}.text-green-100{--text-opacity:1;color:#f0fff4;color:rgba(240,255,244,var(--text-opacity))}.text-green-200{--text-opacity:1;color:#c6f6d5;color:rgba(198,246,213,var(--text-opacity))}.text-green-300{--text-opacity:1;color:#9ae6b4;color:rgba(154,230,180,var(--text-opacity))}.text-green-400{--text-opacity:1;color:#68d391;color:rgba(104,211,145,var(--text-opacity))}.text-green-500{--text-opacity:1;color:#48bb78;color:rgba(72,187,120,var(--text-opacity))}.text-green-600{--text-opacity:1;color:#38a169;color:rgba(56,161,105,var(--text-opacity))}.text-green-700{--text-opacity:1;color:#2f855a;color:rgba(47,133,90,var(--text-opacity))}.text-green-800{--text-opacity:1;color:#276749;color:rgba(39,103,73,var(--text-opacity))}.text-green-900{--text-opacity:1;color:#22543d;color:rgba(34,84,61,var(--text-opacity))}.text-teal-100{--text-opacity:1;color:#e6fffa;color:rgba(230,255,250,var(--text-opacity))}.text-teal-200{--text-opacity:1;color:#b2f5ea;color:rgba(178,245,234,var(--text-opacity))}.text-teal-300{--text-opacity:1;color:#81e6d9;color:rgba(129,230,217,var(--text-opacity))}.text-teal-400{--text-opacity:1;color:#4fd1c5;color:rgba(79,209,197,var(--text-opacity))}.text-teal-500{--text-opacity:1;color:#38b2ac;color:rgba(56,178,172,var(--text-opacity))}.text-teal-600{--text-opacity:1;color:#319795;color:rgba(49,151,149,var(--text-opacity))}.text-teal-700{--text-opacity:1;color:#2c7a7b;color:rgba(44,122,123,var(--text-opacity))}.text-teal-800{--text-opacity:1;color:#285e61;color:rgba(40,94,97,var(--text-opacity))}.text-teal-900{--text-opacity:1;color:#234e52;color:rgba(35,78,82,var(--text-opacity))}.text-blue-100{--text-opacity:1;color:#ebf8ff;color:rgba(235,248,255,var(--text-opacity))}.text-blue-200{--text-opacity:1;color:#bee3f8;color:rgba(190,227,248,var(--text-opacity))}.text-blue-300{--text-opacity:1;color:#90cdf4;color:rgba(144,205,244,var(--text-opacity))}.text-blue-400{--text-opacity:1;color:#63b3ed;color:rgba(99,179,237,var(--text-opacity))}.text-blue-500{--text-opacity:1;color:#4299e1;color:rgba(66,153,225,var(--text-opacity))}.text-blue-600{--text-opacity:1;color:#3182ce;color:rgba(49,130,206,var(--text-opacity))}.text-blue-700{--text-opacity:1;color:#2b6cb0;color:rgba(43,108,176,var(--text-opacity))}.text-blue-800{--text-opacity:1;color:#2c5282;color:rgba(44,82,130,var(--text-opacity))}.text-blue-900{--text-opacity:1;color:#2a4365;color:rgba(42,67,101,var(--text-opacity))}.text-indigo-100{--text-opacity:1;color:#ebf4ff;color:rgba(235,244,255,var(--text-opacity))}.text-indigo-200{--text-opacity:1;color:#c3dafe;color:rgba(195,218,254,var(--text-opacity))}.text-indigo-300{--text-opacity:1;color:#a3bffa;color:rgba(163,191,250,var(--text-opacity))}.text-indigo-400{--text-opacity:1;color:#7f9cf5;color:rgba(127,156,245,var(--text-opacity))}.text-indigo-500{--text-opacity:1;color:#667eea;color:rgba(102,126,234,var(--text-opacity))}.text-indigo-600{--text-opacity:1;color:#5a67d8;color:rgba(90,103,216,var(--text-opacity))}.text-indigo-700{--text-opacity:1;color:#4c51bf;color:rgba(76,81,191,var(--text-opacity))}.text-indigo-800{--text-opacity:1;color:#434190;color:rgba(67,65,144,var(--text-opacity))}.text-indigo-900{--text-opacity:1;color:#3c366b;color:rgba(60,54,107,var(--text-opacity))}.text-purple-100{--text-opacity:1;color:#faf5ff;color:rgba(250,245,255,var(--text-opacity))}.text-purple-200{--text-opacity:1;color:#e9d8fd;color:rgba(233,216,253,var(--text-opacity))}.text-purple-300{--text-opacity:1;color:#d6bcfa;color:rgba(214,188,250,var(--text-opacity))}.text-purple-400{--text-opacity:1;color:#b794f4;color:rgba(183,148,244,var(--text-opacity))}.text-purple-500{--text-opacity:1;color:#9f7aea;color:rgba(159,122,234,var(--text-opacity))}.text-purple-600{--text-opacity:1;color:#805ad5;color:rgba(128,90,213,var(--text-opacity))}.text-purple-700{--text-opacity:1;color:#6b46c1;color:rgba(107,70,193,var(--text-opacity))}.text-purple-800{--text-opacity:1;color:#553c9a;color:rgba(85,60,154,var(--text-opacity))}.text-purple-900{--text-opacity:1;color:#44337a;color:rgba(68,51,122,var(--text-opacity))}.text-pink-100{--text-opacity:1;color:#fff5f7;color:rgba(255,245,247,var(--text-opacity))}.text-pink-200{--text-opacity:1;color:#fed7e2;color:rgba(254,215,226,var(--text-opacity))}.text-pink-300{--text-opacity:1;color:#fbb6ce;color:rgba(251,182,206,var(--text-opacity))}.text-pink-400{--text-opacity:1;color:#f687b3;color:rgba(246,135,179,var(--text-opacity))}.text-pink-500{--text-opacity:1;color:#ed64a6;color:rgba(237,100,166,var(--text-opacity))}.text-pink-600{--text-opacity:1;color:#d53f8c;color:rgba(213,63,140,var(--text-opacity))}.text-pink-700{--text-opacity:1;color:#b83280;color:rgba(184,50,128,var(--text-opacity))}.text-pink-800{--text-opacity:1;color:#97266d;color:rgba(151,38,109,var(--text-opacity))}.text-pink-900{--text-opacity:1;color:#702459;color:rgba(112,36,89,var(--text-opacity))}.hover\:text-transparent:hover{color:transparent}.hover\:text-current:hover{color:currentColor}.hover\:text-black:hover{--text-opacity:1;color:#000;color:rgba(0,0,0,var(--text-opacity))}.hover\:text-white:hover{--text-opacity:1;color:#fff;color:rgba(255,255,255,var(--text-opacity))}.hover\:text-gray-100:hover{--text-opacity:1;color:#f7fafc;color:rgba(247,250,252,var(--text-opacity))}.hover\:text-gray-200:hover{--text-opacity:1;color:#edf2f7;color:rgba(237,242,247,var(--text-opacity))}.hover\:text-gray-300:hover{--text-opacity:1;color:#e2e8f0;color:rgba(226,232,240,var(--text-opacity))}.hover\:text-gray-400:hover{--text-opacity:1;color:#cbd5e0;color:rgba(203,213,224,var(--text-opacity))}.hover\:text-gray-500:hover{--text-opacity:1;color:#a0aec0;color:rgba(160,174,192,var(--text-opacity))}.hover\:text-gray-600:hover{--text-opacity:1;color:#718096;color:rgba(113,128,150,var(--text-opacity))}.hover\:text-gray-700:hover{--text-opacity:1;color:#4a5568;color:rgba(74,85,104,var(--text-opacity))}.hover\:text-gray-800:hover{--text-opacity:1;color:#2d3748;color:rgba(45,55,72,var(--text-opacity))}.hover\:text-gray-900:hover{--text-opacity:1;color:#1a202c;color:rgba(26,32,44,var(--text-opacity))}.hover\:text-red-100:hover{--text-opacity:1;color:#fff5f5;color:rgba(255,245,245,var(--text-opacity))}.hover\:text-red-200:hover{--text-opacity:1;color:#fed7d7;color:rgba(254,215,215,var(--text-opacity))}.hover\:text-red-300:hover{--text-opacity:1;color:#feb2b2;color:rgba(254,178,178,var(--text-opacity))}.hover\:text-red-400:hover{--text-opacity:1;color:#fc8181;color:rgba(252,129,129,var(--text-opacity))}.hover\:text-red-500:hover{--text-opacity:1;color:#f56565;color:rgba(245,101,101,var(--text-opacity))}.hover\:text-red-600:hover{--text-opacity:1;color:#e53e3e;color:rgba(229,62,62,var(--text-opacity))}.hover\:text-red-700:hover{--text-opacity:1;color:#c53030;color:rgba(197,48,48,var(--text-opacity))}.hover\:text-red-800:hover{--text-opacity:1;color:#9b2c2c;color:rgba(155,44,44,var(--text-opacity))}.hover\:text-red-900:hover{--text-opacity:1;color:#742a2a;color:rgba(116,42,42,var(--text-opacity))}.hover\:text-orange-100:hover{--text-opacity:1;color:#fffaf0;color:rgba(255,250,240,var(--text-opacity))}.hover\:text-orange-200:hover{--text-opacity:1;color:#feebc8;color:rgba(254,235,200,var(--text-opacity))}.hover\:text-orange-300:hover{--text-opacity:1;color:#fbd38d;color:rgba(251,211,141,var(--text-opacity))}.hover\:text-orange-400:hover{--text-opacity:1;color:#f6ad55;color:rgba(246,173,85,var(--text-opacity))}.hover\:text-orange-500:hover{--text-opacity:1;color:#ed8936;color:rgba(237,137,54,var(--text-opacity))}.hover\:text-orange-600:hover{--text-opacity:1;color:#dd6b20;color:rgba(221,107,32,var(--text-opacity))}.hover\:text-orange-700:hover{--text-opacity:1;color:#c05621;color:rgba(192,86,33,var(--text-opacity))}.hover\:text-orange-800:hover{--text-opacity:1;color:#9c4221;color:rgba(156,66,33,var(--text-opacity))}.hover\:text-orange-900:hover{--text-opacity:1;color:#7b341e;color:rgba(123,52,30,var(--text-opacity))}.hover\:text-yellow-100:hover{--text-opacity:1;color:ivory;color:rgba(255,255,240,var(--text-opacity))}.hover\:text-yellow-200:hover{--text-opacity:1;color:#fefcbf;color:rgba(254,252,191,var(--text-opacity))}.hover\:text-yellow-300:hover{--text-opacity:1;color:#faf089;color:rgba(250,240,137,var(--text-opacity))}.hover\:text-yellow-400:hover{--text-opacity:1;color:#f6e05e;color:rgba(246,224,94,var(--text-opacity))}.hover\:text-yellow-500:hover{--text-opacity:1;color:#ecc94b;color:rgba(236,201,75,var(--text-opacity))}.hover\:text-yellow-600:hover{--text-opacity:1;color:#d69e2e;color:rgba(214,158,46,var(--text-opacity))}.hover\:text-yellow-700:hover{--text-opacity:1;color:#b7791f;color:rgba(183,121,31,var(--text-opacity))}.hover\:text-yellow-800:hover{--text-opacity:1;color:#975a16;color:rgba(151,90,22,var(--text-opacity))}.hover\:text-yellow-900:hover{--text-opacity:1;color:#744210;color:rgba(116,66,16,var(--text-opacity))}.hover\:text-green-100:hover{--text-opacity:1;color:#f0fff4;color:rgba(240,255,244,var(--text-opacity))}.hover\:text-green-200:hover{--text-opacity:1;color:#c6f6d5;color:rgba(198,246,213,var(--text-opacity))}.hover\:text-green-300:hover{--text-opacity:1;color:#9ae6b4;color:rgba(154,230,180,var(--text-opacity))}.hover\:text-green-400:hover{--text-opacity:1;color:#68d391;color:rgba(104,211,145,var(--text-opacity))}.hover\:text-green-500:hover{--text-opacity:1;color:#48bb78;color:rgba(72,187,120,var(--text-opacity))}.hover\:text-green-600:hover{--text-opacity:1;color:#38a169;color:rgba(56,161,105,var(--text-opacity))}.hover\:text-green-700:hover{--text-opacity:1;color:#2f855a;color:rgba(47,133,90,var(--text-opacity))}.hover\:text-green-800:hover{--text-opacity:1;color:#276749;color:rgba(39,103,73,var(--text-opacity))}.hover\:text-green-900:hover{--text-opacity:1;color:#22543d;color:rgba(34,84,61,var(--text-opacity))}.hover\:text-teal-100:hover{--text-opacity:1;color:#e6fffa;color:rgba(230,255,250,var(--text-opacity))}.hover\:text-teal-200:hover{--text-opacity:1;color:#b2f5ea;color:rgba(178,245,234,var(--text-opacity))}.hover\:text-teal-300:hover{--text-opacity:1;color:#81e6d9;color:rgba(129,230,217,var(--text-opacity))}.hover\:text-teal-400:hover{--text-opacity:1;color:#4fd1c5;color:rgba(79,209,197,var(--text-opacity))}.hover\:text-teal-500:hover{--text-opacity:1;color:#38b2ac;color:rgba(56,178,172,var(--text-opacity))}.hover\:text-teal-600:hover{--text-opacity:1;color:#319795;color:rgba(49,151,149,var(--text-opacity))}.hover\:text-teal-700:hover{--text-opacity:1;color:#2c7a7b;color:rgba(44,122,123,var(--text-opacity))}.hover\:text-teal-800:hover{--text-opacity:1;color:#285e61;color:rgba(40,94,97,var(--text-opacity))}.hover\:text-teal-900:hover{--text-opacity:1;color:#234e52;color:rgba(35,78,82,var(--text-opacity))}.hover\:text-blue-100:hover{--text-opacity:1;color:#ebf8ff;color:rgba(235,248,255,var(--text-opacity))}.hover\:text-blue-200:hover{--text-opacity:1;color:#bee3f8;color:rgba(190,227,248,var(--text-opacity))}.hover\:text-blue-300:hover{--text-opacity:1;color:#90cdf4;color:rgba(144,205,244,var(--text-opacity))}.hover\:text-blue-400:hover{--text-opacity:1;color:#63b3ed;color:rgba(99,179,237,var(--text-opacity))}.hover\:text-blue-500:hover{--text-opacity:1;color:#4299e1;color:rgba(66,153,225,var(--text-opacity))}.hover\:text-blue-600:hover{--text-opacity:1;color:#3182ce;color:rgba(49,130,206,var(--text-opacity))}.hover\:text-blue-700:hover{--text-opacity:1;color:#2b6cb0;color:rgba(43,108,176,var(--text-opacity))}.hover\:text-blue-800:hover{--text-opacity:1;color:#2c5282;color:rgba(44,82,130,var(--text-opacity))}.hover\:text-blue-900:hover{--text-opacity:1;color:#2a4365;color:rgba(42,67,101,var(--text-opacity))}.hover\:text-indigo-100:hover{--text-opacity:1;color:#ebf4ff;color:rgba(235,244,255,var(--text-opacity))}.hover\:text-indigo-200:hover{--text-opacity:1;color:#c3dafe;color:rgba(195,218,254,var(--text-opacity))}.hover\:text-indigo-300:hover{--text-opacity:1;color:#a3bffa;color:rgba(163,191,250,var(--text-opacity))}.hover\:text-indigo-400:hover{--text-opacity:1;color:#7f9cf5;color:rgba(127,156,245,var(--text-opacity))}.hover\:text-indigo-500:hover{--text-opacity:1;color:#667eea;color:rgba(102,126,234,var(--text-opacity))}.hover\:text-indigo-600:hover{--text-opacity:1;color:#5a67d8;color:rgba(90,103,216,var(--text-opacity))}.hover\:text-indigo-700:hover{--text-opacity:1;color:#4c51bf;color:rgba(76,81,191,var(--text-opacity))}.hover\:text-indigo-800:hover{--text-opacity:1;color:#434190;color:rgba(67,65,144,var(--text-opacity))}.hover\:text-indigo-900:hover{--text-opacity:1;color:#3c366b;color:rgba(60,54,107,var(--text-opacity))}.hover\:text-purple-100:hover{--text-opacity:1;color:#faf5ff;color:rgba(250,245,255,var(--text-opacity))}.hover\:text-purple-200:hover{--text-opacity:1;color:#e9d8fd;color:rgba(233,216,253,var(--text-opacity))}.hover\:text-purple-300:hover{--text-opacity:1;color:#d6bcfa;color:rgba(214,188,250,var(--text-opacity))}.hover\:text-purple-400:hover{--text-opacity:1;color:#b794f4;color:rgba(183,148,244,var(--text-opacity))}.hover\:text-purple-500:hover{--text-opacity:1;color:#9f7aea;color:rgba(159,122,234,var(--text-opacity))}.hover\:text-purple-600:hover{--text-opacity:1;color:#805ad5;color:rgba(128,90,213,var(--text-opacity))}.hover\:text-purple-700:hover{--text-opacity:1;color:#6b46c1;color:rgba(107,70,193,var(--text-opacity))}.hover\:text-purple-800:hover{--text-opacity:1;color:#553c9a;color:rgba(85,60,154,var(--text-opacity))}.hover\:text-purple-900:hover{--text-opacity:1;color:#44337a;color:rgba(68,51,122,var(--text-opacity))}.hover\:text-pink-100:hover{--text-opacity:1;color:#fff5f7;color:rgba(255,245,247,var(--text-opacity))}.hover\:text-pink-200:hover{--text-opacity:1;color:#fed7e2;color:rgba(254,215,226,var(--text-opacity))}.hover\:text-pink-300:hover{--text-opacity:1;color:#fbb6ce;color:rgba(251,182,206,var(--text-opacity))}.hover\:text-pink-400:hover{--text-opacity:1;color:#f687b3;color:rgba(246,135,179,var(--text-opacity))}.hover\:text-pink-500:hover{--text-opacity:1;color:#ed64a6;color:rgba(237,100,166,var(--text-opacity))}.hover\:text-pink-600:hover{--text-opacity:1;color:#d53f8c;color:rgba(213,63,140,var(--text-opacity))}.hover\:text-pink-700:hover{--text-opacity:1;color:#b83280;color:rgba(184,50,128,var(--text-opacity))}.hover\:text-pink-800:hover{--text-opacity:1;color:#97266d;color:rgba(151,38,109,var(--text-opacity))}.hover\:text-pink-900:hover{--text-opacity:1;color:#702459;color:rgba(112,36,89,var(--text-opacity))}.focus\:text-transparent:focus{color:transparent}.focus\:text-current:focus{color:currentColor}.focus\:text-black:focus{--text-opacity:1;color:#000;color:rgba(0,0,0,var(--text-opacity))}.focus\:text-white:focus{--text-opacity:1;color:#fff;color:rgba(255,255,255,var(--text-opacity))}.focus\:text-gray-100:focus{--text-opacity:1;color:#f7fafc;color:rgba(247,250,252,var(--text-opacity))}.focus\:text-gray-200:focus{--text-opacity:1;color:#edf2f7;color:rgba(237,242,247,var(--text-opacity))}.focus\:text-gray-300:focus{--text-opacity:1;color:#e2e8f0;color:rgba(226,232,240,var(--text-opacity))}.focus\:text-gray-400:focus{--text-opacity:1;color:#cbd5e0;color:rgba(203,213,224,var(--text-opacity))}.focus\:text-gray-500:focus{--text-opacity:1;color:#a0aec0;color:rgba(160,174,192,var(--text-opacity))}.focus\:text-gray-600:focus{--text-opacity:1;color:#718096;color:rgba(113,128,150,var(--text-opacity))}.focus\:text-gray-700:focus{--text-opacity:1;color:#4a5568;color:rgba(74,85,104,var(--text-opacity))}.focus\:text-gray-800:focus{--text-opacity:1;color:#2d3748;color:rgba(45,55,72,var(--text-opacity))}.focus\:text-gray-900:focus{--text-opacity:1;color:#1a202c;color:rgba(26,32,44,var(--text-opacity))}.focus\:text-red-100:focus{--text-opacity:1;color:#fff5f5;color:rgba(255,245,245,var(--text-opacity))}.focus\:text-red-200:focus{--text-opacity:1;color:#fed7d7;color:rgba(254,215,215,var(--text-opacity))}.focus\:text-red-300:focus{--text-opacity:1;color:#feb2b2;color:rgba(254,178,178,var(--text-opacity))}.focus\:text-red-400:focus{--text-opacity:1;color:#fc8181;color:rgba(252,129,129,var(--text-opacity))}.focus\:text-red-500:focus{--text-opacity:1;color:#f56565;color:rgba(245,101,101,var(--text-opacity))}.focus\:text-red-600:focus{--text-opacity:1;color:#e53e3e;color:rgba(229,62,62,var(--text-opacity))}.focus\:text-red-700:focus{--text-opacity:1;color:#c53030;color:rgba(197,48,48,var(--text-opacity))}.focus\:text-red-800:focus{--text-opacity:1;color:#9b2c2c;color:rgba(155,44,44,var(--text-opacity))}.focus\:text-red-900:focus{--text-opacity:1;color:#742a2a;color:rgba(116,42,42,var(--text-opacity))}.focus\:text-orange-100:focus{--text-opacity:1;color:#fffaf0;color:rgba(255,250,240,var(--text-opacity))}.focus\:text-orange-200:focus{--text-opacity:1;color:#feebc8;color:rgba(254,235,200,var(--text-opacity))}.focus\:text-orange-300:focus{--text-opacity:1;color:#fbd38d;color:rgba(251,211,141,var(--text-opacity))}.focus\:text-orange-400:focus{--text-opacity:1;color:#f6ad55;color:rgba(246,173,85,var(--text-opacity))}.focus\:text-orange-500:focus{--text-opacity:1;color:#ed8936;color:rgba(237,137,54,var(--text-opacity))}.focus\:text-orange-600:focus{--text-opacity:1;color:#dd6b20;color:rgba(221,107,32,var(--text-opacity))}.focus\:text-orange-700:focus{--text-opacity:1;color:#c05621;color:rgba(192,86,33,var(--text-opacity))}.focus\:text-orange-800:focus{--text-opacity:1;color:#9c4221;color:rgba(156,66,33,var(--text-opacity))}.focus\:text-orange-900:focus{--text-opacity:1;color:#7b341e;color:rgba(123,52,30,var(--text-opacity))}.focus\:text-yellow-100:focus{--text-opacity:1;color:ivory;color:rgba(255,255,240,var(--text-opacity))}.focus\:text-yellow-200:focus{--text-opacity:1;color:#fefcbf;color:rgba(254,252,191,var(--text-opacity))}.focus\:text-yellow-300:focus{--text-opacity:1;color:#faf089;color:rgba(250,240,137,var(--text-opacity))}.focus\:text-yellow-400:focus{--text-opacity:1;color:#f6e05e;color:rgba(246,224,94,var(--text-opacity))}.focus\:text-yellow-500:focus{--text-opacity:1;color:#ecc94b;color:rgba(236,201,75,var(--text-opacity))}.focus\:text-yellow-600:focus{--text-opacity:1;color:#d69e2e;color:rgba(214,158,46,var(--text-opacity))}.focus\:text-yellow-700:focus{--text-opacity:1;color:#b7791f;color:rgba(183,121,31,var(--text-opacity))}.focus\:text-yellow-800:focus{--text-opacity:1;color:#975a16;color:rgba(151,90,22,var(--text-opacity))}.focus\:text-yellow-900:focus{--text-opacity:1;color:#744210;color:rgba(116,66,16,var(--text-opacity))}.focus\:text-green-100:focus{--text-opacity:1;color:#f0fff4;color:rgba(240,255,244,var(--text-opacity))}.focus\:text-green-200:focus{--text-opacity:1;color:#c6f6d5;color:rgba(198,246,213,var(--text-opacity))}.focus\:text-green-300:focus{--text-opacity:1;color:#9ae6b4;color:rgba(154,230,180,var(--text-opacity))}.focus\:text-green-400:focus{--text-opacity:1;color:#68d391;color:rgba(104,211,145,var(--text-opacity))}.focus\:text-green-500:focus{--text-opacity:1;color:#48bb78;color:rgba(72,187,120,var(--text-opacity))}.focus\:text-green-600:focus{--text-opacity:1;color:#38a169;color:rgba(56,161,105,var(--text-opacity))}.focus\:text-green-700:focus{--text-opacity:1;color:#2f855a;color:rgba(47,133,90,var(--text-opacity))}.focus\:text-green-800:focus{--text-opacity:1;color:#276749;color:rgba(39,103,73,var(--text-opacity))}.focus\:text-green-900:focus{--text-opacity:1;color:#22543d;color:rgba(34,84,61,var(--text-opacity))}.focus\:text-teal-100:focus{--text-opacity:1;color:#e6fffa;color:rgba(230,255,250,var(--text-opacity))}.focus\:text-teal-200:focus{--text-opacity:1;color:#b2f5ea;color:rgba(178,245,234,var(--text-opacity))}.focus\:text-teal-300:focus{--text-opacity:1;color:#81e6d9;color:rgba(129,230,217,var(--text-opacity))}.focus\:text-teal-400:focus{--text-opacity:1;color:#4fd1c5;color:rgba(79,209,197,var(--text-opacity))}.focus\:text-teal-500:focus{--text-opacity:1;color:#38b2ac;color:rgba(56,178,172,var(--text-opacity))}.focus\:text-teal-600:focus{--text-opacity:1;color:#319795;color:rgba(49,151,149,var(--text-opacity))}.focus\:text-teal-700:focus{--text-opacity:1;color:#2c7a7b;color:rgba(44,122,123,var(--text-opacity))}.focus\:text-teal-800:focus{--text-opacity:1;color:#285e61;color:rgba(40,94,97,var(--text-opacity))}.focus\:text-teal-900:focus{--text-opacity:1;color:#234e52;color:rgba(35,78,82,var(--text-opacity))}.focus\:text-blue-100:focus{--text-opacity:1;color:#ebf8ff;color:rgba(235,248,255,var(--text-opacity))}.focus\:text-blue-200:focus{--text-opacity:1;color:#bee3f8;color:rgba(190,227,248,var(--text-opacity))}.focus\:text-blue-300:focus{--text-opacity:1;color:#90cdf4;color:rgba(144,205,244,var(--text-opacity))}.focus\:text-blue-400:focus{--text-opacity:1;color:#63b3ed;color:rgba(99,179,237,var(--text-opacity))}.focus\:text-blue-500:focus{--text-opacity:1;color:#4299e1;color:rgba(66,153,225,var(--text-opacity))}.focus\:text-blue-600:focus{--text-opacity:1;color:#3182ce;color:rgba(49,130,206,var(--text-opacity))}.focus\:text-blue-700:focus{--text-opacity:1;color:#2b6cb0;color:rgba(43,108,176,var(--text-opacity))}.focus\:text-blue-800:focus{--text-opacity:1;color:#2c5282;color:rgba(44,82,130,var(--text-opacity))}.focus\:text-blue-900:focus{--text-opacity:1;color:#2a4365;color:rgba(42,67,101,var(--text-opacity))}.focus\:text-indigo-100:focus{--text-opacity:1;color:#ebf4ff;color:rgba(235,244,255,var(--text-opacity))}.focus\:text-indigo-200:focus{--text-opacity:1;color:#c3dafe;color:rgba(195,218,254,var(--text-opacity))}.focus\:text-indigo-300:focus{--text-opacity:1;color:#a3bffa;color:rgba(163,191,250,var(--text-opacity))}.focus\:text-indigo-400:focus{--text-opacity:1;color:#7f9cf5;color:rgba(127,156,245,var(--text-opacity))}.focus\:text-indigo-500:focus{--text-opacity:1;color:#667eea;color:rgba(102,126,234,var(--text-opacity))}.focus\:text-indigo-600:focus{--text-opacity:1;color:#5a67d8;color:rgba(90,103,216,var(--text-opacity))}.focus\:text-indigo-700:focus{--text-opacity:1;color:#4c51bf;color:rgba(76,81,191,var(--text-opacity))}.focus\:text-indigo-800:focus{--text-opacity:1;color:#434190;color:rgba(67,65,144,var(--text-opacity))}.focus\:text-indigo-900:focus{--text-opacity:1;color:#3c366b;color:rgba(60,54,107,var(--text-opacity))}.focus\:text-purple-100:focus{--text-opacity:1;color:#faf5ff;color:rgba(250,245,255,var(--text-opacity))}.focus\:text-purple-200:focus{--text-opacity:1;color:#e9d8fd;color:rgba(233,216,253,var(--text-opacity))}.focus\:text-purple-300:focus{--text-opacity:1;color:#d6bcfa;color:rgba(214,188,250,var(--text-opacity))}.focus\:text-purple-400:focus{--text-opacity:1;color:#b794f4;color:rgba(183,148,244,var(--text-opacity))}.focus\:text-purple-500:focus{--text-opacity:1;color:#9f7aea;color:rgba(159,122,234,var(--text-opacity))}.focus\:text-purple-600:focus{--text-opacity:1;color:#805ad5;color:rgba(128,90,213,var(--text-opacity))}.focus\:text-purple-700:focus{--text-opacity:1;color:#6b46c1;color:rgba(107,70,193,var(--text-opacity))}.focus\:text-purple-800:focus{--text-opacity:1;color:#553c9a;color:rgba(85,60,154,var(--text-opacity))}.focus\:text-purple-900:focus{--text-opacity:1;color:#44337a;color:rgba(68,51,122,var(--text-opacity))}.focus\:text-pink-100:focus{--text-opacity:1;color:#fff5f7;color:rgba(255,245,247,var(--text-opacity))}.focus\:text-pink-200:focus{--text-opacity:1;color:#fed7e2;color:rgba(254,215,226,var(--text-opacity))}.focus\:text-pink-300:focus{--text-opacity:1;color:#fbb6ce;color:rgba(251,182,206,var(--text-opacity))}.focus\:text-pink-400:focus{--text-opacity:1;color:#f687b3;color:rgba(246,135,179,var(--text-opacity))}.focus\:text-pink-500:focus{--text-opacity:1;color:#ed64a6;color:rgba(237,100,166,var(--text-opacity))}.focus\:text-pink-600:focus{--text-opacity:1;color:#d53f8c;color:rgba(213,63,140,var(--text-opacity))}.focus\:text-pink-700:focus{--text-opacity:1;color:#b83280;color:rgba(184,50,128,var(--text-opacity))}.focus\:text-pink-800:focus{--text-opacity:1;color:#97266d;color:rgba(151,38,109,var(--text-opacity))}.focus\:text-pink-900:focus{--text-opacity:1;color:#702459;color:rgba(112,36,89,var(--text-opacity))}.text-opacity-0{--text-opacity:0}.text-opacity-25{--text-opacity:0.25}.text-opacity-50{--text-opacity:0.5}.text-opacity-75{--text-opacity:0.75}.text-opacity-100{--text-opacity:1}.hover\:text-opacity-0:hover{--text-opacity:0}.hover\:text-opacity-25:hover{--text-opacity:0.25}.hover\:text-opacity-50:hover{--text-opacity:0.5}.hover\:text-opacity-75:hover{--text-opacity:0.75}.hover\:text-opacity-100:hover{--text-opacity:1}.focus\:text-opacity-0:focus{--text-opacity:0}.focus\:text-opacity-25:focus{--text-opacity:0.25}.focus\:text-opacity-50:focus{--text-opacity:0.5}.focus\:text-opacity-75:focus{--text-opacity:0.75}.focus\:text-opacity-100:focus{--text-opacity:1}.italic{font-style:italic}.not-italic{font-style:normal}.uppercase{text-transform:uppercase}.lowercase{text-transform:lowercase}.capitalize{text-transform:capitalize}.normal-case{text-transform:none}.underline{text-decoration:underline}.line-through{text-decoration:line-through}.no-underline{text-decoration:none}.hover\:underline:hover{text-decoration:underline}.hover\:line-through:hover{text-decoration:line-through}.hover\:no-underline:hover{text-decoration:none}.focus\:underline:focus{text-decoration:underline}.focus\:line-through:focus{text-decoration:line-through}.focus\:no-underline:focus{text-decoration:none}.antialiased{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.subpixel-antialiased{-webkit-font-smoothing:auto;-moz-osx-font-smoothing:auto}.diagonal-fractions,.lining-nums,.oldstyle-nums,.ordinal,.proportional-nums,.slashed-zero,.stacked-fractions,.tabular-nums{--font-variant-numeric-ordinal:var(--tailwind-empty, );/*!*//*!*/--font-variant-numeric-slashed-zero:var(--tailwind-empty, );/*!*//*!*/--font-variant-numeric-figure:var(--tailwind-empty, );/*!*//*!*/--font-variant-numeric-spacing:var(--tailwind-empty, );/*!*//*!*/--font-variant-numeric-fraction:var(--tailwind-empty, );/*!*//*!*/font-variant-numeric:var(--font-variant-numeric-ordinal) var(--font-variant-numeric-slashed-zero) var(--font-variant-numeric-figure) var(--font-variant-numeric-spacing) var(--font-variant-numeric-fraction)}.normal-nums{font-variant-numeric:normal}.ordinal{--font-variant-numeric-ordinal:ordinal}.slashed-zero{--font-variant-numeric-slashed-zero:slashed-zero}.lining-nums{--font-variant-numeric-figure:lining-nums}.oldstyle-nums{--font-variant-numeric-figure:oldstyle-nums}.proportional-nums{--font-variant-numeric-spacing:proportional-nums}.tabular-nums{--font-variant-numeric-spacing:tabular-nums}.diagonal-fractions{--font-variant-numeric-fraction:diagonal-fractions}.stacked-fractions{--font-variant-numeric-fraction:stacked-fractions}.tracking-tighter{letter-spacing:-.05em}.tracking-tight{letter-spacing:-.025em}.tracking-normal{letter-spacing:0}.tracking-wide{letter-spacing:.025em}.tracking-wider{letter-spacing:.05em}.tracking-widest{letter-spacing:.1em}.select-none{-webkit-user-select:none;-ms-user-select:none;user-select:none}.select-text{-webkit-user-select:text;-ms-user-select:text;user-select:text}.select-all{-webkit-user-select:all;-ms-user-select:all;user-select:all}.select-auto{-webkit-user-select:auto;-ms-user-select:auto;user-select:auto}.align-baseline{vertical-align:baseline}.align-top{vertical-align:top}.align-middle{vertical-align:middle}.align-bottom{vertical-align:bottom}.align-text-top{vertical-align:text-top}.align-text-bottom{vertical-align:text-bottom}.visible{visibility:visible}.invisible{visibility:hidden}.whitespace-normal{white-space:normal}.whitespace-no-wrap{white-space:nowrap}.whitespace-pre{white-space:pre}.whitespace-pre-line{white-space:pre-line}.whitespace-pre-wrap{white-space:pre-wrap}.break-normal{word-wrap:normal;overflow-wrap:normal;word-break:normal}.break-words{word-wrap:break-word;overflow-wrap:break-word}.break-all{word-break:break-all}.truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.w-0{width:0}.w-1{width:.25rem}.w-2{width:.5rem}.w-3{width:.75rem}.w-4{width:1rem}.w-5{width:1.25rem}.w-6{width:1.5rem}.w-8{width:2rem}.w-10{width:2.5rem}.w-12{width:3rem}.w-16{width:4rem}.w-20{width:5rem}.w-24{width:6rem}.w-32{width:8rem}.w-40{width:10rem}.w-48{width:12rem}.w-56{width:14rem}.w-64{width:16rem}.w-auto{width:auto}.w-px{width:1px}.w-1\/2{width:50%}.w-1\/3{width:33.333333%}.w-2\/3{width:66.666667%}.w-1\/4{width:25%}.w-2\/4{width:50%}.w-3\/4{width:75%}.w-1\/5{width:20%}.w-2\/5{width:40%}.w-3\/5{width:60%}.w-4\/5{width:80%}.w-1\/6{width:16.666667%}.w-2\/6{width:33.333333%}.w-3\/6{width:50%}.w-4\/6{width:66.666667%}.w-5\/6{width:83.333333%}.w-1\/12{width:8.333333%}.w-2\/12{width:16.666667%}.w-3\/12{width:25%}.w-4\/12{width:33.333333%}.w-5\/12{width:41.666667%}.w-6\/12{width:50%}.w-7\/12{width:58.333333%}.w-8\/12{width:66.666667%}.w-9\/12{width:75%}.w-10\/12{width:83.333333%}.w-11\/12{width:91.666667%}.w-full{width:100%}.w-screen{width:100vw}.z-0{z-index:0}.z-10{z-index:10}.z-20{z-index:20}.z-30{z-index:30}.z-40{z-index:40}.z-50{z-index:50}.z-auto{z-index:auto}.gap-0{grid-gap:0;gap:0}.gap-1{grid-gap:.25rem;gap:.25rem}.gap-2{grid-gap:.5rem;gap:.5rem}.gap-3{grid-gap:.75rem;gap:.75rem}.gap-4{grid-gap:1rem;gap:1rem}.gap-5{grid-gap:1.25rem;gap:1.25rem}.gap-6{grid-gap:1.5rem;gap:1.5rem}.gap-8{grid-gap:2rem;gap:2rem}.gap-10{grid-gap:2.5rem;gap:2.5rem}.gap-12{grid-gap:3rem;gap:3rem}.gap-16{grid-gap:4rem;gap:4rem}.gap-20{grid-gap:5rem;gap:5rem}.gap-24{grid-gap:6rem;gap:6rem}.gap-32{grid-gap:8rem;gap:8rem}.gap-40{grid-gap:10rem;gap:10rem}.gap-48{grid-gap:12rem;gap:12rem}.gap-56{grid-gap:14rem;gap:14rem}.gap-64{grid-gap:16rem;gap:16rem}.gap-px{grid-gap:1px;gap:1px}.col-gap-0{grid-column-gap:0;column-gap:0}.col-gap-1{grid-column-gap:.25rem;column-gap:.25rem}.col-gap-2{grid-column-gap:.5rem;column-gap:.5rem}.col-gap-3{grid-column-gap:.75rem;column-gap:.75rem}.col-gap-4{grid-column-gap:1rem;column-gap:1rem}.col-gap-5{grid-column-gap:1.25rem;column-gap:1.25rem}.col-gap-6{grid-column-gap:1.5rem;column-gap:1.5rem}.col-gap-8{grid-column-gap:2rem;column-gap:2rem}.col-gap-10{grid-column-gap:2.5rem;column-gap:2.5rem}.col-gap-12{grid-column-gap:3rem;column-gap:3rem}.col-gap-16{grid-column-gap:4rem;column-gap:4rem}.col-gap-20{grid-column-gap:5rem;column-gap:5rem}.col-gap-24{grid-column-gap:6rem;column-gap:6rem}.col-gap-32{grid-column-gap:8rem;column-gap:8rem}.col-gap-40{grid-column-gap:10rem;column-gap:10rem}.col-gap-48{grid-column-gap:12rem;column-gap:12rem}.col-gap-56{grid-column-gap:14rem;column-gap:14rem}.col-gap-64{grid-column-gap:16rem;column-gap:16rem}.col-gap-px{grid-column-gap:1px;column-gap:1px}.gap-x-0{grid-column-gap:0;column-gap:0}.gap-x-1{grid-column-gap:.25rem;column-gap:.25rem}.gap-x-2{grid-column-gap:.5rem;column-gap:.5rem}.gap-x-3{grid-column-gap:.75rem;column-gap:.75rem}.gap-x-4{grid-column-gap:1rem;column-gap:1rem}.gap-x-5{grid-column-gap:1.25rem;column-gap:1.25rem}.gap-x-6{grid-column-gap:1.5rem;column-gap:1.5rem}.gap-x-8{grid-column-gap:2rem;column-gap:2rem}.gap-x-10{grid-column-gap:2.5rem;column-gap:2.5rem}.gap-x-12{grid-column-gap:3rem;column-gap:3rem}.gap-x-16{grid-column-gap:4rem;column-gap:4rem}.gap-x-20{grid-column-gap:5rem;column-gap:5rem}.gap-x-24{grid-column-gap:6rem;column-gap:6rem}.gap-x-32{grid-column-gap:8rem;column-gap:8rem}.gap-x-40{grid-column-gap:10rem;column-gap:10rem}.gap-x-48{grid-column-gap:12rem;column-gap:12rem}.gap-x-56{grid-column-gap:14rem;column-gap:14rem}.gap-x-64{grid-column-gap:16rem;column-gap:16rem}.gap-x-px{grid-column-gap:1px;column-gap:1px}.row-gap-0{grid-row-gap:0;row-gap:0}.row-gap-1{grid-row-gap:.25rem;row-gap:.25rem}.row-gap-2{grid-row-gap:.5rem;row-gap:.5rem}.row-gap-3{grid-row-gap:.75rem;row-gap:.75rem}.row-gap-4{grid-row-gap:1rem;row-gap:1rem}.row-gap-5{grid-row-gap:1.25rem;row-gap:1.25rem}.row-gap-6{grid-row-gap:1.5rem;row-gap:1.5rem}.row-gap-8{grid-row-gap:2rem;row-gap:2rem}.row-gap-10{grid-row-gap:2.5rem;row-gap:2.5rem}.row-gap-12{grid-row-gap:3rem;row-gap:3rem}.row-gap-16{grid-row-gap:4rem;row-gap:4rem}.row-gap-20{grid-row-gap:5rem;row-gap:5rem}.row-gap-24{grid-row-gap:6rem;row-gap:6rem}.row-gap-32{grid-row-gap:8rem;row-gap:8rem}.row-gap-40{grid-row-gap:10rem;row-gap:10rem}.row-gap-48{grid-row-gap:12rem;row-gap:12rem}.row-gap-56{grid-row-gap:14rem;row-gap:14rem}.row-gap-64{grid-row-gap:16rem;row-gap:16rem}.row-gap-px{grid-row-gap:1px;row-gap:1px}.gap-y-0{grid-row-gap:0;row-gap:0}.gap-y-1{grid-row-gap:.25rem;row-gap:.25rem}.gap-y-2{grid-row-gap:.5rem;row-gap:.5rem}.gap-y-3{grid-row-gap:.75rem;row-gap:.75rem}.gap-y-4{grid-row-gap:1rem;row-gap:1rem}.gap-y-5{grid-row-gap:1.25rem;row-gap:1.25rem}.gap-y-6{grid-row-gap:1.5rem;row-gap:1.5rem}.gap-y-8{grid-row-gap:2rem;row-gap:2rem}.gap-y-10{grid-row-gap:2.5rem;row-gap:2.5rem}.gap-y-12{grid-row-gap:3rem;row-gap:3rem}.gap-y-16{grid-row-gap:4rem;row-gap:4rem}.gap-y-20{grid-row-gap:5rem;row-gap:5rem}.gap-y-24{grid-row-gap:6rem;row-gap:6rem}.gap-y-32{grid-row-gap:8rem;row-gap:8rem}.gap-y-40{grid-row-gap:10rem;row-gap:10rem}.gap-y-48{grid-row-gap:12rem;row-gap:12rem}.gap-y-56{grid-row-gap:14rem;row-gap:14rem}.gap-y-64{grid-row-gap:16rem;row-gap:16rem}.gap-y-px{grid-row-gap:1px;row-gap:1px}.grid-flow-row{grid-auto-flow:row}.grid-flow-col{grid-auto-flow:column}.grid-flow-row-dense{grid-auto-flow:row dense}.grid-flow-col-dense{grid-auto-flow:column dense}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.grid-cols-5{grid-template-columns:repeat(5,minmax(0,1fr))}.grid-cols-6{grid-template-columns:repeat(6,minmax(0,1fr))}.grid-cols-7{grid-template-columns:repeat(7,minmax(0,1fr))}.grid-cols-8{grid-template-columns:repeat(8,minmax(0,1fr))}.grid-cols-9{grid-template-columns:repeat(9,minmax(0,1fr))}.grid-cols-10{grid-template-columns:repeat(10,minmax(0,1fr))}.grid-cols-11{grid-template-columns:repeat(11,minmax(0,1fr))}.grid-cols-12{grid-template-columns:repeat(12,minmax(0,1fr))}.grid-cols-none{grid-template-columns:none}.auto-cols-auto{grid-auto-columns:auto}.auto-cols-min{grid-auto-columns:-webkit-min-content;grid-auto-columns:min-content}.auto-cols-max{grid-auto-columns:-webkit-max-content;grid-auto-columns:max-content}.auto-cols-fr{grid-auto-columns:minmax(0,1fr)}.col-auto{grid-column:auto}.col-span-1{grid-column:span 1/span 1}.col-span-2{grid-column:span 2/span 2}.col-span-3{grid-column:span 3/span 3}.col-span-4{grid-column:span 4/span 4}.col-span-5{grid-column:span 5/span 5}.col-span-6{grid-column:span 6/span 6}.col-span-7{grid-column:span 7/span 7}.col-span-8{grid-column:span 8/span 8}.col-span-9{grid-column:span 9/span 9}.col-span-10{grid-column:span 10/span 10}.col-span-11{grid-column:span 11/span 11}.col-span-12{grid-column:span 12/span 12}.col-span-full{grid-column:1/-1}.col-start-1{grid-column-start:1}.col-start-2{grid-column-start:2}.col-start-3{grid-column-start:3}.col-start-4{grid-column-start:4}.col-start-5{grid-column-start:5}.col-start-6{grid-column-start:6}.col-start-7{grid-column-start:7}.col-start-8{grid-column-start:8}.col-start-9{grid-column-start:9}.col-start-10{grid-column-start:10}.col-start-11{grid-column-start:11}.col-start-12{grid-column-start:12}.col-start-13{grid-column-start:13}.col-start-auto{grid-column-start:auto}.col-end-1{grid-column-end:1}.col-end-2{grid-column-end:2}.col-end-3{grid-column-end:3}.col-end-4{grid-column-end:4}.col-end-5{grid-column-end:5}.col-end-6{grid-column-end:6}.col-end-7{grid-column-end:7}.col-end-8{grid-column-end:8}.col-end-9{grid-column-end:9}.col-end-10{grid-column-end:10}.col-end-11{grid-column-end:11}.col-end-12{grid-column-end:12}.col-end-13{grid-column-end:13}.col-end-auto{grid-column-end:auto}.grid-rows-1{grid-template-rows:repeat(1,minmax(0,1fr))}.grid-rows-2{grid-template-rows:repeat(2,minmax(0,1fr))}.grid-rows-3{grid-template-rows:repeat(3,minmax(0,1fr))}.grid-rows-4{grid-template-rows:repeat(4,minmax(0,1fr))}.grid-rows-5{grid-template-rows:repeat(5,minmax(0,1fr))}.grid-rows-6{grid-template-rows:repeat(6,minmax(0,1fr))}.grid-rows-none{grid-template-rows:none}.auto-rows-auto{grid-auto-rows:auto}.auto-rows-min{grid-auto-rows:-webkit-min-content;grid-auto-rows:min-content}.auto-rows-max{grid-auto-rows:-webkit-max-content;grid-auto-rows:max-content}.auto-rows-fr{grid-auto-rows:minmax(0,1fr)}.row-auto{grid-row:auto}.row-span-1{grid-row:span 1/span 1}.row-span-2{grid-row:span 2/span 2}.row-span-3{grid-row:span 3/span 3}.row-span-4{grid-row:span 4/span 4}.row-span-5{grid-row:span 5/span 5}.row-span-6{grid-row:span 6/span 6}.row-span-full{grid-row:1/-1}.row-start-1{grid-row-start:1}.row-start-2{grid-row-start:2}.row-start-3{grid-row-start:3}.row-start-4{grid-row-start:4}.row-start-5{grid-row-start:5}.row-start-6{grid-row-start:6}.row-start-7{grid-row-start:7}.row-start-auto{grid-row-start:auto}.row-end-1{grid-row-end:1}.row-end-2{grid-row-end:2}.row-end-3{grid-row-end:3}.row-end-4{grid-row-end:4}.row-end-5{grid-row-end:5}.row-end-6{grid-row-end:6}.row-end-7{grid-row-end:7}.row-end-auto{grid-row-end:auto}.transform{--transform-translate-x:0;--transform-translate-y:0;--transform-rotate:0;--transform-skew-x:0;--transform-skew-y:0;--transform-scale-x:1;--transform-scale-y:1;transform:translateX(var(--transform-translate-x)) translateY(var(--transform-translate-y)) rotate(var(--transform-rotate)) skewX(var(--transform-skew-x)) skewY(var(--transform-skew-y)) scaleX(var(--transform-scale-x)) scaleY(var(--transform-scale-y))}.transform-none{transform:none}.origin-center{transform-origin:center}.origin-top{transform-origin:top}.origin-top-right{transform-origin:top right}.origin-right{transform-origin:right}.origin-bottom-right{transform-origin:bottom right}.origin-bottom{transform-origin:bottom}.origin-bottom-left{transform-origin:bottom left}.origin-left{transform-origin:left}.origin-top-left{transform-origin:top left}.scale-0{--transform-scale-x:0;--transform-scale-y:0}.scale-50{--transform-scale-x:.5;--transform-scale-y:.5}.scale-75{--transform-scale-x:.75;--transform-scale-y:.75}.scale-90{--transform-scale-x:.9;--transform-scale-y:.9}.scale-95{--transform-scale-x:.95;--transform-scale-y:.95}.scale-100{--transform-scale-x:1;--transform-scale-y:1}.scale-105{--transform-scale-x:1.05;--transform-scale-y:1.05}.scale-110{--transform-scale-x:1.1;--transform-scale-y:1.1}.scale-125{--transform-scale-x:1.25;--transform-scale-y:1.25}.scale-150{--transform-scale-x:1.5;--transform-scale-y:1.5}.scale-x-0{--transform-scale-x:0}.scale-x-50{--transform-scale-x:.5}.scale-x-75{--transform-scale-x:.75}.scale-x-90{--transform-scale-x:.9}.scale-x-95{--transform-scale-x:.95}.scale-x-100{--transform-scale-x:1}.scale-x-105{--transform-scale-x:1.05}.scale-x-110{--transform-scale-x:1.1}.scale-x-125{--transform-scale-x:1.25}.scale-x-150{--transform-scale-x:1.5}.scale-y-0{--transform-scale-y:0}.scale-y-50{--transform-scale-y:.5}.scale-y-75{--transform-scale-y:.75}.scale-y-90{--transform-scale-y:.9}.scale-y-95{--transform-scale-y:.95}.scale-y-100{--transform-scale-y:1}.scale-y-105{--transform-scale-y:1.05}.scale-y-110{--transform-scale-y:1.1}.scale-y-125{--transform-scale-y:1.25}.scale-y-150{--transform-scale-y:1.5}.hover\:scale-0:hover{--transform-scale-x:0;--transform-scale-y:0}.hover\:scale-50:hover{--transform-scale-x:.5;--transform-scale-y:.5}.hover\:scale-75:hover{--transform-scale-x:.75;--transform-scale-y:.75}.hover\:scale-90:hover{--transform-scale-x:.9;--transform-scale-y:.9}.hover\:scale-95:hover{--transform-scale-x:.95;--transform-scale-y:.95}.hover\:scale-100:hover{--transform-scale-x:1;--transform-scale-y:1}.hover\:scale-105:hover{--transform-scale-x:1.05;--transform-scale-y:1.05}.hover\:scale-110:hover{--transform-scale-x:1.1;--transform-scale-y:1.1}.hover\:scale-125:hover{--transform-scale-x:1.25;--transform-scale-y:1.25}.hover\:scale-150:hover{--transform-scale-x:1.5;--transform-scale-y:1.5}.hover\:scale-x-0:hover{--transform-scale-x:0}.hover\:scale-x-50:hover{--transform-scale-x:.5}.hover\:scale-x-75:hover{--transform-scale-x:.75}.hover\:scale-x-90:hover{--transform-scale-x:.9}.hover\:scale-x-95:hover{--transform-scale-x:.95}.hover\:scale-x-100:hover{--transform-scale-x:1}.hover\:scale-x-105:hover{--transform-scale-x:1.05}.hover\:scale-x-110:hover{--transform-scale-x:1.1}.hover\:scale-x-125:hover{--transform-scale-x:1.25}.hover\:scale-x-150:hover{--transform-scale-x:1.5}.hover\:scale-y-0:hover{--transform-scale-y:0}.hover\:scale-y-50:hover{--transform-scale-y:.5}.hover\:scale-y-75:hover{--transform-scale-y:.75}.hover\:scale-y-90:hover{--transform-scale-y:.9}.hover\:scale-y-95:hover{--transform-scale-y:.95}.hover\:scale-y-100:hover{--transform-scale-y:1}.hover\:scale-y-105:hover{--transform-scale-y:1.05}.hover\:scale-y-110:hover{--transform-scale-y:1.1}.hover\:scale-y-125:hover{--transform-scale-y:1.25}.hover\:scale-y-150:hover{--transform-scale-y:1.5}.focus\:scale-0:focus{--transform-scale-x:0;--transform-scale-y:0}.focus\:scale-50:focus{--transform-scale-x:.5;--transform-scale-y:.5}.focus\:scale-75:focus{--transform-scale-x:.75;--transform-scale-y:.75}.focus\:scale-90:focus{--transform-scale-x:.9;--transform-scale-y:.9}.focus\:scale-95:focus{--transform-scale-x:.95;--transform-scale-y:.95}.focus\:scale-100:focus{--transform-scale-x:1;--transform-scale-y:1}.focus\:scale-105:focus{--transform-scale-x:1.05;--transform-scale-y:1.05}.focus\:scale-110:focus{--transform-scale-x:1.1;--transform-scale-y:1.1}.focus\:scale-125:focus{--transform-scale-x:1.25;--transform-scale-y:1.25}.focus\:scale-150:focus{--transform-scale-x:1.5;--transform-scale-y:1.5}.focus\:scale-x-0:focus{--transform-scale-x:0}.focus\:scale-x-50:focus{--transform-scale-x:.5}.focus\:scale-x-75:focus{--transform-scale-x:.75}.focus\:scale-x-90:focus{--transform-scale-x:.9}.focus\:scale-x-95:focus{--transform-scale-x:.95}.focus\:scale-x-100:focus{--transform-scale-x:1}.focus\:scale-x-105:focus{--transform-scale-x:1.05}.focus\:scale-x-110:focus{--transform-scale-x:1.1}.focus\:scale-x-125:focus{--transform-scale-x:1.25}.focus\:scale-x-150:focus{--transform-scale-x:1.5}.focus\:scale-y-0:focus{--transform-scale-y:0}.focus\:scale-y-50:focus{--transform-scale-y:.5}.focus\:scale-y-75:focus{--transform-scale-y:.75}.focus\:scale-y-90:focus{--transform-scale-y:.9}.focus\:scale-y-95:focus{--transform-scale-y:.95}.focus\:scale-y-100:focus{--transform-scale-y:1}.focus\:scale-y-105:focus{--transform-scale-y:1.05}.focus\:scale-y-110:focus{--transform-scale-y:1.1}.focus\:scale-y-125:focus{--transform-scale-y:1.25}.focus\:scale-y-150:focus{--transform-scale-y:1.5}.rotate-0{--transform-rotate:0}.rotate-1{--transform-rotate:1deg}.rotate-2{--transform-rotate:2deg}.rotate-3{--transform-rotate:3deg}.rotate-6{--transform-rotate:6deg}.rotate-12{--transform-rotate:12deg}.rotate-45{--transform-rotate:45deg}.rotate-90{--transform-rotate:90deg}.rotate-180{--transform-rotate:180deg}.-rotate-180{--transform-rotate:-180deg}.-rotate-90{--transform-rotate:-90deg}.-rotate-45{--transform-rotate:-45deg}.-rotate-12{--transform-rotate:-12deg}.-rotate-6{--transform-rotate:-6deg}.-rotate-3{--transform-rotate:-3deg}.-rotate-2{--transform-rotate:-2deg}.-rotate-1{--transform-rotate:-1deg}.hover\:rotate-0:hover{--transform-rotate:0}.hover\:rotate-1:hover{--transform-rotate:1deg}.hover\:rotate-2:hover{--transform-rotate:2deg}.hover\:rotate-3:hover{--transform-rotate:3deg}.hover\:rotate-6:hover{--transform-rotate:6deg}.hover\:rotate-12:hover{--transform-rotate:12deg}.hover\:rotate-45:hover{--transform-rotate:45deg}.hover\:rotate-90:hover{--transform-rotate:90deg}.hover\:rotate-180:hover{--transform-rotate:180deg}.hover\:-rotate-180:hover{--transform-rotate:-180deg}.hover\:-rotate-90:hover{--transform-rotate:-90deg}.hover\:-rotate-45:hover{--transform-rotate:-45deg}.hover\:-rotate-12:hover{--transform-rotate:-12deg}.hover\:-rotate-6:hover{--transform-rotate:-6deg}.hover\:-rotate-3:hover{--transform-rotate:-3deg}.hover\:-rotate-2:hover{--transform-rotate:-2deg}.hover\:-rotate-1:hover{--transform-rotate:-1deg}.focus\:rotate-0:focus{--transform-rotate:0}.focus\:rotate-1:focus{--transform-rotate:1deg}.focus\:rotate-2:focus{--transform-rotate:2deg}.focus\:rotate-3:focus{--transform-rotate:3deg}.focus\:rotate-6:focus{--transform-rotate:6deg}.focus\:rotate-12:focus{--transform-rotate:12deg}.focus\:rotate-45:focus{--transform-rotate:45deg}.focus\:rotate-90:focus{--transform-rotate:90deg}.focus\:rotate-180:focus{--transform-rotate:180deg}.focus\:-rotate-180:focus{--transform-rotate:-180deg}.focus\:-rotate-90:focus{--transform-rotate:-90deg}.focus\:-rotate-45:focus{--transform-rotate:-45deg}.focus\:-rotate-12:focus{--transform-rotate:-12deg}.focus\:-rotate-6:focus{--transform-rotate:-6deg}.focus\:-rotate-3:focus{--transform-rotate:-3deg}.focus\:-rotate-2:focus{--transform-rotate:-2deg}.focus\:-rotate-1:focus{--transform-rotate:-1deg}.translate-x-0{--transform-translate-x:0}.translate-x-1{--transform-translate-x:0.25rem}.translate-x-2{--transform-translate-x:0.5rem}.translate-x-3{--transform-translate-x:0.75rem}.translate-x-4{--transform-translate-x:1rem}.translate-x-5{--transform-translate-x:1.25rem}.translate-x-6{--transform-translate-x:1.5rem}.translate-x-8{--transform-translate-x:2rem}.translate-x-10{--transform-translate-x:2.5rem}.translate-x-12{--transform-translate-x:3rem}.translate-x-16{--transform-translate-x:4rem}.translate-x-20{--transform-translate-x:5rem}.translate-x-24{--transform-translate-x:6rem}.translate-x-32{--transform-translate-x:8rem}.translate-x-40{--transform-translate-x:10rem}.translate-x-48{--transform-translate-x:12rem}.translate-x-56{--transform-translate-x:14rem}.translate-x-64{--transform-translate-x:16rem}.translate-x-px{--transform-translate-x:1px}.-translate-x-1{--transform-translate-x:-0.25rem}.-translate-x-2{--transform-translate-x:-0.5rem}.-translate-x-3{--transform-translate-x:-0.75rem}.-translate-x-4{--transform-translate-x:-1rem}.-translate-x-5{--transform-translate-x:-1.25rem}.-translate-x-6{--transform-translate-x:-1.5rem}.-translate-x-8{--transform-translate-x:-2rem}.-translate-x-10{--transform-translate-x:-2.5rem}.-translate-x-12{--transform-translate-x:-3rem}.-translate-x-16{--transform-translate-x:-4rem}.-translate-x-20{--transform-translate-x:-5rem}.-translate-x-24{--transform-translate-x:-6rem}.-translate-x-32{--transform-translate-x:-8rem}.-translate-x-40{--transform-translate-x:-10rem}.-translate-x-48{--transform-translate-x:-12rem}.-translate-x-56{--transform-translate-x:-14rem}.-translate-x-64{--transform-translate-x:-16rem}.-translate-x-px{--transform-translate-x:-1px}.-translate-x-full{--transform-translate-x:-100%}.-translate-x-1\/2{--transform-translate-x:-50%}.translate-x-1\/2{--transform-translate-x:50%}.translate-x-full{--transform-translate-x:100%}.translate-y-0{--transform-translate-y:0}.translate-y-1{--transform-translate-y:0.25rem}.translate-y-2{--transform-translate-y:0.5rem}.translate-y-3{--transform-translate-y:0.75rem}.translate-y-4{--transform-translate-y:1rem}.translate-y-5{--transform-translate-y:1.25rem}.translate-y-6{--transform-translate-y:1.5rem}.translate-y-8{--transform-translate-y:2rem}.translate-y-10{--transform-translate-y:2.5rem}.translate-y-12{--transform-translate-y:3rem}.translate-y-16{--transform-translate-y:4rem}.translate-y-20{--transform-translate-y:5rem}.translate-y-24{--transform-translate-y:6rem}.translate-y-32{--transform-translate-y:8rem}.translate-y-40{--transform-translate-y:10rem}.translate-y-48{--transform-translate-y:12rem}.translate-y-56{--transform-translate-y:14rem}.translate-y-64{--transform-translate-y:16rem}.translate-y-px{--transform-translate-y:1px}.-translate-y-1{--transform-translate-y:-0.25rem}.-translate-y-2{--transform-translate-y:-0.5rem}.-translate-y-3{--transform-translate-y:-0.75rem}.-translate-y-4{--transform-translate-y:-1rem}.-translate-y-5{--transform-translate-y:-1.25rem}.-translate-y-6{--transform-translate-y:-1.5rem}.-translate-y-8{--transform-translate-y:-2rem}.-translate-y-10{--transform-translate-y:-2.5rem}.-translate-y-12{--transform-translate-y:-3rem}.-translate-y-16{--transform-translate-y:-4rem}.-translate-y-20{--transform-translate-y:-5rem}.-translate-y-24{--transform-translate-y:-6rem}.-translate-y-32{--transform-translate-y:-8rem}.-translate-y-40{--transform-translate-y:-10rem}.-translate-y-48{--transform-translate-y:-12rem}.-translate-y-56{--transform-translate-y:-14rem}.-translate-y-64{--transform-translate-y:-16rem}.-translate-y-px{--transform-translate-y:-1px}.-translate-y-full{--transform-translate-y:-100%}.-translate-y-1\/2{--transform-translate-y:-50%}.translate-y-1\/2{--transform-translate-y:50%}.translate-y-full{--transform-translate-y:100%}.hover\:translate-x-0:hover{--transform-translate-x:0}.hover\:translate-x-1:hover{--transform-translate-x:0.25rem}.hover\:translate-x-2:hover{--transform-translate-x:0.5rem}.hover\:translate-x-3:hover{--transform-translate-x:0.75rem}.hover\:translate-x-4:hover{--transform-translate-x:1rem}.hover\:translate-x-5:hover{--transform-translate-x:1.25rem}.hover\:translate-x-6:hover{--transform-translate-x:1.5rem}.hover\:translate-x-8:hover{--transform-translate-x:2rem}.hover\:translate-x-10:hover{--transform-translate-x:2.5rem}.hover\:translate-x-12:hover{--transform-translate-x:3rem}.hover\:translate-x-16:hover{--transform-translate-x:4rem}.hover\:translate-x-20:hover{--transform-translate-x:5rem}.hover\:translate-x-24:hover{--transform-translate-x:6rem}.hover\:translate-x-32:hover{--transform-translate-x:8rem}.hover\:translate-x-40:hover{--transform-translate-x:10rem}.hover\:translate-x-48:hover{--transform-translate-x:12rem}.hover\:translate-x-56:hover{--transform-translate-x:14rem}.hover\:translate-x-64:hover{--transform-translate-x:16rem}.hover\:translate-x-px:hover{--transform-translate-x:1px}.hover\:-translate-x-1:hover{--transform-translate-x:-0.25rem}.hover\:-translate-x-2:hover{--transform-translate-x:-0.5rem}.hover\:-translate-x-3:hover{--transform-translate-x:-0.75rem}.hover\:-translate-x-4:hover{--transform-translate-x:-1rem}.hover\:-translate-x-5:hover{--transform-translate-x:-1.25rem}.hover\:-translate-x-6:hover{--transform-translate-x:-1.5rem}.hover\:-translate-x-8:hover{--transform-translate-x:-2rem}.hover\:-translate-x-10:hover{--transform-translate-x:-2.5rem}.hover\:-translate-x-12:hover{--transform-translate-x:-3rem}.hover\:-translate-x-16:hover{--transform-translate-x:-4rem}.hover\:-translate-x-20:hover{--transform-translate-x:-5rem}.hover\:-translate-x-24:hover{--transform-translate-x:-6rem}.hover\:-translate-x-32:hover{--transform-translate-x:-8rem}.hover\:-translate-x-40:hover{--transform-translate-x:-10rem}.hover\:-translate-x-48:hover{--transform-translate-x:-12rem}.hover\:-translate-x-56:hover{--transform-translate-x:-14rem}.hover\:-translate-x-64:hover{--transform-translate-x:-16rem}.hover\:-translate-x-px:hover{--transform-translate-x:-1px}.hover\:-translate-x-full:hover{--transform-translate-x:-100%}.hover\:-translate-x-1\/2:hover{--transform-translate-x:-50%}.hover\:translate-x-1\/2:hover{--transform-translate-x:50%}.hover\:translate-x-full:hover{--transform-translate-x:100%}.hover\:translate-y-0:hover{--transform-translate-y:0}.hover\:translate-y-1:hover{--transform-translate-y:0.25rem}.hover\:translate-y-2:hover{--transform-translate-y:0.5rem}.hover\:translate-y-3:hover{--transform-translate-y:0.75rem}.hover\:translate-y-4:hover{--transform-translate-y:1rem}.hover\:translate-y-5:hover{--transform-translate-y:1.25rem}.hover\:translate-y-6:hover{--transform-translate-y:1.5rem}.hover\:translate-y-8:hover{--transform-translate-y:2rem}.hover\:translate-y-10:hover{--transform-translate-y:2.5rem}.hover\:translate-y-12:hover{--transform-translate-y:3rem}.hover\:translate-y-16:hover{--transform-translate-y:4rem}.hover\:translate-y-20:hover{--transform-translate-y:5rem}.hover\:translate-y-24:hover{--transform-translate-y:6rem}.hover\:translate-y-32:hover{--transform-translate-y:8rem}.hover\:translate-y-40:hover{--transform-translate-y:10rem}.hover\:translate-y-48:hover{--transform-translate-y:12rem}.hover\:translate-y-56:hover{--transform-translate-y:14rem}.hover\:translate-y-64:hover{--transform-translate-y:16rem}.hover\:translate-y-px:hover{--transform-translate-y:1px}.hover\:-translate-y-1:hover{--transform-translate-y:-0.25rem}.hover\:-translate-y-2:hover{--transform-translate-y:-0.5rem}.hover\:-translate-y-3:hover{--transform-translate-y:-0.75rem}.hover\:-translate-y-4:hover{--transform-translate-y:-1rem}.hover\:-translate-y-5:hover{--transform-translate-y:-1.25rem}.hover\:-translate-y-6:hover{--transform-translate-y:-1.5rem}.hover\:-translate-y-8:hover{--transform-translate-y:-2rem}.hover\:-translate-y-10:hover{--transform-translate-y:-2.5rem}.hover\:-translate-y-12:hover{--transform-translate-y:-3rem}.hover\:-translate-y-16:hover{--transform-translate-y:-4rem}.hover\:-translate-y-20:hover{--transform-translate-y:-5rem}.hover\:-translate-y-24:hover{--transform-translate-y:-6rem}.hover\:-translate-y-32:hover{--transform-translate-y:-8rem}.hover\:-translate-y-40:hover{--transform-translate-y:-10rem}.hover\:-translate-y-48:hover{--transform-translate-y:-12rem}.hover\:-translate-y-56:hover{--transform-translate-y:-14rem}.hover\:-translate-y-64:hover{--transform-translate-y:-16rem}.hover\:-translate-y-px:hover{--transform-translate-y:-1px}.hover\:-translate-y-full:hover{--transform-translate-y:-100%}.hover\:-translate-y-1\/2:hover{--transform-translate-y:-50%}.hover\:translate-y-1\/2:hover{--transform-translate-y:50%}.hover\:translate-y-full:hover{--transform-translate-y:100%}.focus\:translate-x-0:focus{--transform-translate-x:0}.focus\:translate-x-1:focus{--transform-translate-x:0.25rem}.focus\:translate-x-2:focus{--transform-translate-x:0.5rem}.focus\:translate-x-3:focus{--transform-translate-x:0.75rem}.focus\:translate-x-4:focus{--transform-translate-x:1rem}.focus\:translate-x-5:focus{--transform-translate-x:1.25rem}.focus\:translate-x-6:focus{--transform-translate-x:1.5rem}.focus\:translate-x-8:focus{--transform-translate-x:2rem}.focus\:translate-x-10:focus{--transform-translate-x:2.5rem}.focus\:translate-x-12:focus{--transform-translate-x:3rem}.focus\:translate-x-16:focus{--transform-translate-x:4rem}.focus\:translate-x-20:focus{--transform-translate-x:5rem}.focus\:translate-x-24:focus{--transform-translate-x:6rem}.focus\:translate-x-32:focus{--transform-translate-x:8rem}.focus\:translate-x-40:focus{--transform-translate-x:10rem}.focus\:translate-x-48:focus{--transform-translate-x:12rem}.focus\:translate-x-56:focus{--transform-translate-x:14rem}.focus\:translate-x-64:focus{--transform-translate-x:16rem}.focus\:translate-x-px:focus{--transform-translate-x:1px}.focus\:-translate-x-1:focus{--transform-translate-x:-0.25rem}.focus\:-translate-x-2:focus{--transform-translate-x:-0.5rem}.focus\:-translate-x-3:focus{--transform-translate-x:-0.75rem}.focus\:-translate-x-4:focus{--transform-translate-x:-1rem}.focus\:-translate-x-5:focus{--transform-translate-x:-1.25rem}.focus\:-translate-x-6:focus{--transform-translate-x:-1.5rem}.focus\:-translate-x-8:focus{--transform-translate-x:-2rem}.focus\:-translate-x-10:focus{--transform-translate-x:-2.5rem}.focus\:-translate-x-12:focus{--transform-translate-x:-3rem}.focus\:-translate-x-16:focus{--transform-translate-x:-4rem}.focus\:-translate-x-20:focus{--transform-translate-x:-5rem}.focus\:-translate-x-24:focus{--transform-translate-x:-6rem}.focus\:-translate-x-32:focus{--transform-translate-x:-8rem}.focus\:-translate-x-40:focus{--transform-translate-x:-10rem}.focus\:-translate-x-48:focus{--transform-translate-x:-12rem}.focus\:-translate-x-56:focus{--transform-translate-x:-14rem}.focus\:-translate-x-64:focus{--transform-translate-x:-16rem}.focus\:-translate-x-px:focus{--transform-translate-x:-1px}.focus\:-translate-x-full:focus{--transform-translate-x:-100%}.focus\:-translate-x-1\/2:focus{--transform-translate-x:-50%}.focus\:translate-x-1\/2:focus{--transform-translate-x:50%}.focus\:translate-x-full:focus{--transform-translate-x:100%}.focus\:translate-y-0:focus{--transform-translate-y:0}.focus\:translate-y-1:focus{--transform-translate-y:0.25rem}.focus\:translate-y-2:focus{--transform-translate-y:0.5rem}.focus\:translate-y-3:focus{--transform-translate-y:0.75rem}.focus\:translate-y-4:focus{--transform-translate-y:1rem}.focus\:translate-y-5:focus{--transform-translate-y:1.25rem}.focus\:translate-y-6:focus{--transform-translate-y:1.5rem}.focus\:translate-y-8:focus{--transform-translate-y:2rem}.focus\:translate-y-10:focus{--transform-translate-y:2.5rem}.focus\:translate-y-12:focus{--transform-translate-y:3rem}.focus\:translate-y-16:focus{--transform-translate-y:4rem}.focus\:translate-y-20:focus{--transform-translate-y:5rem}.focus\:translate-y-24:focus{--transform-translate-y:6rem}.focus\:translate-y-32:focus{--transform-translate-y:8rem}.focus\:translate-y-40:focus{--transform-translate-y:10rem}.focus\:translate-y-48:focus{--transform-translate-y:12rem}.focus\:translate-y-56:focus{--transform-translate-y:14rem}.focus\:translate-y-64:focus{--transform-translate-y:16rem}.focus\:translate-y-px:focus{--transform-translate-y:1px}.focus\:-translate-y-1:focus{--transform-translate-y:-0.25rem}.focus\:-translate-y-2:focus{--transform-translate-y:-0.5rem}.focus\:-translate-y-3:focus{--transform-translate-y:-0.75rem}.focus\:-translate-y-4:focus{--transform-translate-y:-1rem}.focus\:-translate-y-5:focus{--transform-translate-y:-1.25rem}.focus\:-translate-y-6:focus{--transform-translate-y:-1.5rem}.focus\:-translate-y-8:focus{--transform-translate-y:-2rem}.focus\:-translate-y-10:focus{--transform-translate-y:-2.5rem}.focus\:-translate-y-12:focus{--transform-translate-y:-3rem}.focus\:-translate-y-16:focus{--transform-translate-y:-4rem}.focus\:-translate-y-20:focus{--transform-translate-y:-5rem}.focus\:-translate-y-24:focus{--transform-translate-y:-6rem}.focus\:-translate-y-32:focus{--transform-translate-y:-8rem}.focus\:-translate-y-40:focus{--transform-translate-y:-10rem}.focus\:-translate-y-48:focus{--transform-translate-y:-12rem}.focus\:-translate-y-56:focus{--transform-translate-y:-14rem}.focus\:-translate-y-64:focus{--transform-translate-y:-16rem}.focus\:-translate-y-px:focus{--transform-translate-y:-1px}.focus\:-translate-y-full:focus{--transform-translate-y:-100%}.focus\:-translate-y-1\/2:focus{--transform-translate-y:-50%}.focus\:translate-y-1\/2:focus{--transform-translate-y:50%}.focus\:translate-y-full:focus{--transform-translate-y:100%}.skew-x-0{--transform-skew-x:0}.skew-x-1{--transform-skew-x:1deg}.skew-x-2{--transform-skew-x:2deg}.skew-x-3{--transform-skew-x:3deg}.skew-x-6{--transform-skew-x:6deg}.skew-x-12{--transform-skew-x:12deg}.-skew-x-12{--transform-skew-x:-12deg}.-skew-x-6{--transform-skew-x:-6deg}.-skew-x-3{--transform-skew-x:-3deg}.-skew-x-2{--transform-skew-x:-2deg}.-skew-x-1{--transform-skew-x:-1deg}.skew-y-0{--transform-skew-y:0}.skew-y-1{--transform-skew-y:1deg}.skew-y-2{--transform-skew-y:2deg}.skew-y-3{--transform-skew-y:3deg}.skew-y-6{--transform-skew-y:6deg}.skew-y-12{--transform-skew-y:12deg}.-skew-y-12{--transform-skew-y:-12deg}.-skew-y-6{--transform-skew-y:-6deg}.-skew-y-3{--transform-skew-y:-3deg}.-skew-y-2{--transform-skew-y:-2deg}.-skew-y-1{--transform-skew-y:-1deg}.hover\:skew-x-0:hover{--transform-skew-x:0}.hover\:skew-x-1:hover{--transform-skew-x:1deg}.hover\:skew-x-2:hover{--transform-skew-x:2deg}.hover\:skew-x-3:hover{--transform-skew-x:3deg}.hover\:skew-x-6:hover{--transform-skew-x:6deg}.hover\:skew-x-12:hover{--transform-skew-x:12deg}.hover\:-skew-x-12:hover{--transform-skew-x:-12deg}.hover\:-skew-x-6:hover{--transform-skew-x:-6deg}.hover\:-skew-x-3:hover{--transform-skew-x:-3deg}.hover\:-skew-x-2:hover{--transform-skew-x:-2deg}.hover\:-skew-x-1:hover{--transform-skew-x:-1deg}.hover\:skew-y-0:hover{--transform-skew-y:0}.hover\:skew-y-1:hover{--transform-skew-y:1deg}.hover\:skew-y-2:hover{--transform-skew-y:2deg}.hover\:skew-y-3:hover{--transform-skew-y:3deg}.hover\:skew-y-6:hover{--transform-skew-y:6deg}.hover\:skew-y-12:hover{--transform-skew-y:12deg}.hover\:-skew-y-12:hover{--transform-skew-y:-12deg}.hover\:-skew-y-6:hover{--transform-skew-y:-6deg}.hover\:-skew-y-3:hover{--transform-skew-y:-3deg}.hover\:-skew-y-2:hover{--transform-skew-y:-2deg}.hover\:-skew-y-1:hover{--transform-skew-y:-1deg}.focus\:skew-x-0:focus{--transform-skew-x:0}.focus\:skew-x-1:focus{--transform-skew-x:1deg}.focus\:skew-x-2:focus{--transform-skew-x:2deg}.focus\:skew-x-3:focus{--transform-skew-x:3deg}.focus\:skew-x-6:focus{--transform-skew-x:6deg}.focus\:skew-x-12:focus{--transform-skew-x:12deg}.focus\:-skew-x-12:focus{--transform-skew-x:-12deg}.focus\:-skew-x-6:focus{--transform-skew-x:-6deg}.focus\:-skew-x-3:focus{--transform-skew-x:-3deg}.focus\:-skew-x-2:focus{--transform-skew-x:-2deg}.focus\:-skew-x-1:focus{--transform-skew-x:-1deg}.focus\:skew-y-0:focus{--transform-skew-y:0}.focus\:skew-y-1:focus{--transform-skew-y:1deg}.focus\:skew-y-2:focus{--transform-skew-y:2deg}.focus\:skew-y-3:focus{--transform-skew-y:3deg}.focus\:skew-y-6:focus{--transform-skew-y:6deg}.focus\:skew-y-12:focus{--transform-skew-y:12deg}.focus\:-skew-y-12:focus{--transform-skew-y:-12deg}.focus\:-skew-y-6:focus{--transform-skew-y:-6deg}.focus\:-skew-y-3:focus{--transform-skew-y:-3deg}.focus\:-skew-y-2:focus{--transform-skew-y:-2deg}.focus\:-skew-y-1:focus{--transform-skew-y:-1deg}.transition-none{transition-property:none}.transition-all{transition-property:all}.transition{transition-property:background-color,border-color,color,fill,stroke,opacity,box-shadow,transform}.transition-colors{transition-property:background-color,border-color,color,fill,stroke}.transition-opacity{transition-property:opacity}.transition-shadow{transition-property:box-shadow}.transition-transform{transition-property:transform}.ease-linear{transition-timing-function:linear}.ease-in{transition-timing-function:cubic-bezier(.4,0,1,1)}.ease-out{transition-timing-function:cubic-bezier(0,0,.2,1)}.ease-in-out{transition-timing-function:cubic-bezier(.4,0,.2,1)}.duration-75{transition-duration:75ms}.duration-100{transition-duration:.1s}.duration-150{transition-duration:150ms}.duration-200{transition-duration:.2s}.duration-300{transition-duration:.3s}.duration-500{transition-duration:.5s}.duration-700{transition-duration:.7s}.duration-1000{transition-duration:1s}.delay-75{transition-delay:75ms}.delay-100{transition-delay:.1s}.delay-150{transition-delay:150ms}.delay-200{transition-delay:.2s}.delay-300{transition-delay:.3s}.delay-500{transition-delay:.5s}.delay-700{transition-delay:.7s}.delay-1000{transition-delay:1s}@keyframes spin{to{transform:rotate(360deg)}}@keyframes ping{100%,75%{transform:scale(2);opacity:0}}@keyframes pulse{50%{opacity:.5}}@keyframes bounce{0%,100%{transform:translateY(-25%);animation-timing-function:cubic-bezier(.8,0,1,1)}50%{transform:none;animation-timing-function:cubic-bezier(0,0,.2,1)}}.animate-none{animation:none}.animate-spin{animation:spin 1s linear infinite}.animate-ping{animation:ping 1s cubic-bezier(0,0,.2,1) infinite}.animate-pulse{animation:pulse 2s cubic-bezier(.4,0,.6,1) infinite}.animate-bounce{animation:bounce 1s infinite}@media (min-width:640px){.sm\:container{width:100%}@media (min-width:640px){.sm\:container{max-width:640px}}@media (min-width:768px){.sm\:container{max-width:768px}}@media (min-width:1024px){.sm\:container{max-width:1024px}}@media (min-width:1280px){.sm\:container{max-width:1280px}}.sm\:space-y-0>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(0px * calc(1 - var(--space-y-reverse)));margin-bottom:calc(0px * var(--space-y-reverse))}.sm\:space-x-0>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(0px * var(--space-x-reverse));margin-left:calc(0px * calc(1 - var(--space-x-reverse)))}.sm\:space-y-1>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(.25rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(.25rem * var(--space-y-reverse))}.sm\:space-x-1>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(.25rem * var(--space-x-reverse));margin-left:calc(.25rem * calc(1 - var(--space-x-reverse)))}.sm\:space-y-2>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(.5rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(.5rem * var(--space-y-reverse))}.sm\:space-x-2>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(.5rem * var(--space-x-reverse));margin-left:calc(.5rem * calc(1 - var(--space-x-reverse)))}.sm\:space-y-3>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(.75rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(.75rem * var(--space-y-reverse))}.sm\:space-x-3>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(.75rem * var(--space-x-reverse));margin-left:calc(.75rem * calc(1 - var(--space-x-reverse)))}.sm\:space-y-4>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(1rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(1rem * var(--space-y-reverse))}.sm\:space-x-4>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(1rem * var(--space-x-reverse));margin-left:calc(1rem * calc(1 - var(--space-x-reverse)))}.sm\:space-y-5>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(1.25rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(1.25rem * var(--space-y-reverse))}.sm\:space-x-5>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(1.25rem * var(--space-x-reverse));margin-left:calc(1.25rem * calc(1 - var(--space-x-reverse)))}.sm\:space-y-6>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(1.5rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(1.5rem * var(--space-y-reverse))}.sm\:space-x-6>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(1.5rem * var(--space-x-reverse));margin-left:calc(1.5rem * calc(1 - var(--space-x-reverse)))}.sm\:space-y-8>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(2rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(2rem * var(--space-y-reverse))}.sm\:space-x-8>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(2rem * var(--space-x-reverse));margin-left:calc(2rem * calc(1 - var(--space-x-reverse)))}.sm\:space-y-10>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(2.5rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(2.5rem * var(--space-y-reverse))}.sm\:space-x-10>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(2.5rem * var(--space-x-reverse));margin-left:calc(2.5rem * calc(1 - var(--space-x-reverse)))}.sm\:space-y-12>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(3rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(3rem * var(--space-y-reverse))}.sm\:space-x-12>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(3rem * var(--space-x-reverse));margin-left:calc(3rem * calc(1 - var(--space-x-reverse)))}.sm\:space-y-16>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(4rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(4rem * var(--space-y-reverse))}.sm\:space-x-16>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(4rem * var(--space-x-reverse));margin-left:calc(4rem * calc(1 - var(--space-x-reverse)))}.sm\:space-y-20>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(5rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(5rem * var(--space-y-reverse))}.sm\:space-x-20>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(5rem * var(--space-x-reverse));margin-left:calc(5rem * calc(1 - var(--space-x-reverse)))}.sm\:space-y-24>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(6rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(6rem * var(--space-y-reverse))}.sm\:space-x-24>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(6rem * var(--space-x-reverse));margin-left:calc(6rem * calc(1 - var(--space-x-reverse)))}.sm\:space-y-32>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(8rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(8rem * var(--space-y-reverse))}.sm\:space-x-32>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(8rem * var(--space-x-reverse));margin-left:calc(8rem * calc(1 - var(--space-x-reverse)))}.sm\:space-y-40>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(10rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(10rem * var(--space-y-reverse))}.sm\:space-x-40>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(10rem * var(--space-x-reverse));margin-left:calc(10rem * calc(1 - var(--space-x-reverse)))}.sm\:space-y-48>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(12rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(12rem * var(--space-y-reverse))}.sm\:space-x-48>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(12rem * var(--space-x-reverse));margin-left:calc(12rem * calc(1 - var(--space-x-reverse)))}.sm\:space-y-56>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(14rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(14rem * var(--space-y-reverse))}.sm\:space-x-56>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(14rem * var(--space-x-reverse));margin-left:calc(14rem * calc(1 - var(--space-x-reverse)))}.sm\:space-y-64>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(16rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(16rem * var(--space-y-reverse))}.sm\:space-x-64>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(16rem * var(--space-x-reverse));margin-left:calc(16rem * calc(1 - var(--space-x-reverse)))}.sm\:space-y-px>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(1px * calc(1 - var(--space-y-reverse)));margin-bottom:calc(1px * var(--space-y-reverse))}.sm\:space-x-px>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(1px * var(--space-x-reverse));margin-left:calc(1px * calc(1 - var(--space-x-reverse)))}.sm\:-space-y-1>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-.25rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-.25rem * var(--space-y-reverse))}.sm\:-space-x-1>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-.25rem * var(--space-x-reverse));margin-left:calc(-.25rem * calc(1 - var(--space-x-reverse)))}.sm\:-space-y-2>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-.5rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-.5rem * var(--space-y-reverse))}.sm\:-space-x-2>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-.5rem * var(--space-x-reverse));margin-left:calc(-.5rem * calc(1 - var(--space-x-reverse)))}.sm\:-space-y-3>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-.75rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-.75rem * var(--space-y-reverse))}.sm\:-space-x-3>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-.75rem * var(--space-x-reverse));margin-left:calc(-.75rem * calc(1 - var(--space-x-reverse)))}.sm\:-space-y-4>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-1rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-1rem * var(--space-y-reverse))}.sm\:-space-x-4>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-1rem * var(--space-x-reverse));margin-left:calc(-1rem * calc(1 - var(--space-x-reverse)))}.sm\:-space-y-5>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-1.25rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-1.25rem * var(--space-y-reverse))}.sm\:-space-x-5>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-1.25rem * var(--space-x-reverse));margin-left:calc(-1.25rem * calc(1 - var(--space-x-reverse)))}.sm\:-space-y-6>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-1.5rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-1.5rem * var(--space-y-reverse))}.sm\:-space-x-6>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-1.5rem * var(--space-x-reverse));margin-left:calc(-1.5rem * calc(1 - var(--space-x-reverse)))}.sm\:-space-y-8>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-2rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-2rem * var(--space-y-reverse))}.sm\:-space-x-8>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-2rem * var(--space-x-reverse));margin-left:calc(-2rem * calc(1 - var(--space-x-reverse)))}.sm\:-space-y-10>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-2.5rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-2.5rem * var(--space-y-reverse))}.sm\:-space-x-10>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-2.5rem * var(--space-x-reverse));margin-left:calc(-2.5rem * calc(1 - var(--space-x-reverse)))}.sm\:-space-y-12>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-3rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-3rem * var(--space-y-reverse))}.sm\:-space-x-12>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-3rem * var(--space-x-reverse));margin-left:calc(-3rem * calc(1 - var(--space-x-reverse)))}.sm\:-space-y-16>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-4rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-4rem * var(--space-y-reverse))}.sm\:-space-x-16>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-4rem * var(--space-x-reverse));margin-left:calc(-4rem * calc(1 - var(--space-x-reverse)))}.sm\:-space-y-20>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-5rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-5rem * var(--space-y-reverse))}.sm\:-space-x-20>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-5rem * var(--space-x-reverse));margin-left:calc(-5rem * calc(1 - var(--space-x-reverse)))}.sm\:-space-y-24>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-6rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-6rem * var(--space-y-reverse))}.sm\:-space-x-24>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-6rem * var(--space-x-reverse));margin-left:calc(-6rem * calc(1 - var(--space-x-reverse)))}.sm\:-space-y-32>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-8rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-8rem * var(--space-y-reverse))}.sm\:-space-x-32>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-8rem * var(--space-x-reverse));margin-left:calc(-8rem * calc(1 - var(--space-x-reverse)))}.sm\:-space-y-40>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-10rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-10rem * var(--space-y-reverse))}.sm\:-space-x-40>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-10rem * var(--space-x-reverse));margin-left:calc(-10rem * calc(1 - var(--space-x-reverse)))}.sm\:-space-y-48>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-12rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-12rem * var(--space-y-reverse))}.sm\:-space-x-48>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-12rem * var(--space-x-reverse));margin-left:calc(-12rem * calc(1 - var(--space-x-reverse)))}.sm\:-space-y-56>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-14rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-14rem * var(--space-y-reverse))}.sm\:-space-x-56>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-14rem * var(--space-x-reverse));margin-left:calc(-14rem * calc(1 - var(--space-x-reverse)))}.sm\:-space-y-64>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-16rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-16rem * var(--space-y-reverse))}.sm\:-space-x-64>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-16rem * var(--space-x-reverse));margin-left:calc(-16rem * calc(1 - var(--space-x-reverse)))}.sm\:-space-y-px>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-1px * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-1px * var(--space-y-reverse))}.sm\:-space-x-px>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-1px * var(--space-x-reverse));margin-left:calc(-1px * calc(1 - var(--space-x-reverse)))}.sm\:space-y-reverse>:not(template)~:not(template){--space-y-reverse:1}.sm\:space-x-reverse>:not(template)~:not(template){--space-x-reverse:1}.sm\:divide-y-0>:not(template)~:not(template){--divide-y-reverse:0;border-top-width:calc(0px * calc(1 - var(--divide-y-reverse)));border-bottom-width:calc(0px * var(--divide-y-reverse))}.sm\:divide-x-0>:not(template)~:not(template){--divide-x-reverse:0;border-right-width:calc(0px * var(--divide-x-reverse));border-left-width:calc(0px * calc(1 - var(--divide-x-reverse)))}.sm\:divide-y-2>:not(template)~:not(template){--divide-y-reverse:0;border-top-width:calc(2px * calc(1 - var(--divide-y-reverse)));border-bottom-width:calc(2px * var(--divide-y-reverse))}.sm\:divide-x-2>:not(template)~:not(template){--divide-x-reverse:0;border-right-width:calc(2px * var(--divide-x-reverse));border-left-width:calc(2px * calc(1 - var(--divide-x-reverse)))}.sm\:divide-y-4>:not(template)~:not(template){--divide-y-reverse:0;border-top-width:calc(4px * calc(1 - var(--divide-y-reverse)));border-bottom-width:calc(4px * var(--divide-y-reverse))}.sm\:divide-x-4>:not(template)~:not(template){--divide-x-reverse:0;border-right-width:calc(4px * var(--divide-x-reverse));border-left-width:calc(4px * calc(1 - var(--divide-x-reverse)))}.sm\:divide-y-8>:not(template)~:not(template){--divide-y-reverse:0;border-top-width:calc(8px * calc(1 - var(--divide-y-reverse)));border-bottom-width:calc(8px * var(--divide-y-reverse))}.sm\:divide-x-8>:not(template)~:not(template){--divide-x-reverse:0;border-right-width:calc(8px * var(--divide-x-reverse));border-left-width:calc(8px * calc(1 - var(--divide-x-reverse)))}.sm\:divide-y>:not(template)~:not(template){--divide-y-reverse:0;border-top-width:calc(1px * calc(1 - var(--divide-y-reverse)));border-bottom-width:calc(1px * var(--divide-y-reverse))}.sm\:divide-x>:not(template)~:not(template){--divide-x-reverse:0;border-right-width:calc(1px * var(--divide-x-reverse));border-left-width:calc(1px * calc(1 - var(--divide-x-reverse)))}.sm\:divide-y-reverse>:not(template)~:not(template){--divide-y-reverse:1}.sm\:divide-x-reverse>:not(template)~:not(template){--divide-x-reverse:1}.sm\:divide-transparent>:not(template)~:not(template){border-color:transparent}.sm\:divide-current>:not(template)~:not(template){border-color:currentColor}.sm\:divide-black>:not(template)~:not(template){--divide-opacity:1;border-color:#000;border-color:rgba(0,0,0,var(--divide-opacity))}.sm\:divide-white>:not(template)~:not(template){--divide-opacity:1;border-color:#fff;border-color:rgba(255,255,255,var(--divide-opacity))}.sm\:divide-gray-100>:not(template)~:not(template){--divide-opacity:1;border-color:#f7fafc;border-color:rgba(247,250,252,var(--divide-opacity))}.sm\:divide-gray-200>:not(template)~:not(template){--divide-opacity:1;border-color:#edf2f7;border-color:rgba(237,242,247,var(--divide-opacity))}.sm\:divide-gray-300>:not(template)~:not(template){--divide-opacity:1;border-color:#e2e8f0;border-color:rgba(226,232,240,var(--divide-opacity))}.sm\:divide-gray-400>:not(template)~:not(template){--divide-opacity:1;border-color:#cbd5e0;border-color:rgba(203,213,224,var(--divide-opacity))}.sm\:divide-gray-500>:not(template)~:not(template){--divide-opacity:1;border-color:#a0aec0;border-color:rgba(160,174,192,var(--divide-opacity))}.sm\:divide-gray-600>:not(template)~:not(template){--divide-opacity:1;border-color:#718096;border-color:rgba(113,128,150,var(--divide-opacity))}.sm\:divide-gray-700>:not(template)~:not(template){--divide-opacity:1;border-color:#4a5568;border-color:rgba(74,85,104,var(--divide-opacity))}.sm\:divide-gray-800>:not(template)~:not(template){--divide-opacity:1;border-color:#2d3748;border-color:rgba(45,55,72,var(--divide-opacity))}.sm\:divide-gray-900>:not(template)~:not(template){--divide-opacity:1;border-color:#1a202c;border-color:rgba(26,32,44,var(--divide-opacity))}.sm\:divide-red-100>:not(template)~:not(template){--divide-opacity:1;border-color:#fff5f5;border-color:rgba(255,245,245,var(--divide-opacity))}.sm\:divide-red-200>:not(template)~:not(template){--divide-opacity:1;border-color:#fed7d7;border-color:rgba(254,215,215,var(--divide-opacity))}.sm\:divide-red-300>:not(template)~:not(template){--divide-opacity:1;border-color:#feb2b2;border-color:rgba(254,178,178,var(--divide-opacity))}.sm\:divide-red-400>:not(template)~:not(template){--divide-opacity:1;border-color:#fc8181;border-color:rgba(252,129,129,var(--divide-opacity))}.sm\:divide-red-500>:not(template)~:not(template){--divide-opacity:1;border-color:#f56565;border-color:rgba(245,101,101,var(--divide-opacity))}.sm\:divide-red-600>:not(template)~:not(template){--divide-opacity:1;border-color:#e53e3e;border-color:rgba(229,62,62,var(--divide-opacity))}.sm\:divide-red-700>:not(template)~:not(template){--divide-opacity:1;border-color:#c53030;border-color:rgba(197,48,48,var(--divide-opacity))}.sm\:divide-red-800>:not(template)~:not(template){--divide-opacity:1;border-color:#9b2c2c;border-color:rgba(155,44,44,var(--divide-opacity))}.sm\:divide-red-900>:not(template)~:not(template){--divide-opacity:1;border-color:#742a2a;border-color:rgba(116,42,42,var(--divide-opacity))}.sm\:divide-orange-100>:not(template)~:not(template){--divide-opacity:1;border-color:#fffaf0;border-color:rgba(255,250,240,var(--divide-opacity))}.sm\:divide-orange-200>:not(template)~:not(template){--divide-opacity:1;border-color:#feebc8;border-color:rgba(254,235,200,var(--divide-opacity))}.sm\:divide-orange-300>:not(template)~:not(template){--divide-opacity:1;border-color:#fbd38d;border-color:rgba(251,211,141,var(--divide-opacity))}.sm\:divide-orange-400>:not(template)~:not(template){--divide-opacity:1;border-color:#f6ad55;border-color:rgba(246,173,85,var(--divide-opacity))}.sm\:divide-orange-500>:not(template)~:not(template){--divide-opacity:1;border-color:#ed8936;border-color:rgba(237,137,54,var(--divide-opacity))}.sm\:divide-orange-600>:not(template)~:not(template){--divide-opacity:1;border-color:#dd6b20;border-color:rgba(221,107,32,var(--divide-opacity))}.sm\:divide-orange-700>:not(template)~:not(template){--divide-opacity:1;border-color:#c05621;border-color:rgba(192,86,33,var(--divide-opacity))}.sm\:divide-orange-800>:not(template)~:not(template){--divide-opacity:1;border-color:#9c4221;border-color:rgba(156,66,33,var(--divide-opacity))}.sm\:divide-orange-900>:not(template)~:not(template){--divide-opacity:1;border-color:#7b341e;border-color:rgba(123,52,30,var(--divide-opacity))}.sm\:divide-yellow-100>:not(template)~:not(template){--divide-opacity:1;border-color:ivory;border-color:rgba(255,255,240,var(--divide-opacity))}.sm\:divide-yellow-200>:not(template)~:not(template){--divide-opacity:1;border-color:#fefcbf;border-color:rgba(254,252,191,var(--divide-opacity))}.sm\:divide-yellow-300>:not(template)~:not(template){--divide-opacity:1;border-color:#faf089;border-color:rgba(250,240,137,var(--divide-opacity))}.sm\:divide-yellow-400>:not(template)~:not(template){--divide-opacity:1;border-color:#f6e05e;border-color:rgba(246,224,94,var(--divide-opacity))}.sm\:divide-yellow-500>:not(template)~:not(template){--divide-opacity:1;border-color:#ecc94b;border-color:rgba(236,201,75,var(--divide-opacity))}.sm\:divide-yellow-600>:not(template)~:not(template){--divide-opacity:1;border-color:#d69e2e;border-color:rgba(214,158,46,var(--divide-opacity))}.sm\:divide-yellow-700>:not(template)~:not(template){--divide-opacity:1;border-color:#b7791f;border-color:rgba(183,121,31,var(--divide-opacity))}.sm\:divide-yellow-800>:not(template)~:not(template){--divide-opacity:1;border-color:#975a16;border-color:rgba(151,90,22,var(--divide-opacity))}.sm\:divide-yellow-900>:not(template)~:not(template){--divide-opacity:1;border-color:#744210;border-color:rgba(116,66,16,var(--divide-opacity))}.sm\:divide-green-100>:not(template)~:not(template){--divide-opacity:1;border-color:#f0fff4;border-color:rgba(240,255,244,var(--divide-opacity))}.sm\:divide-green-200>:not(template)~:not(template){--divide-opacity:1;border-color:#c6f6d5;border-color:rgba(198,246,213,var(--divide-opacity))}.sm\:divide-green-300>:not(template)~:not(template){--divide-opacity:1;border-color:#9ae6b4;border-color:rgba(154,230,180,var(--divide-opacity))}.sm\:divide-green-400>:not(template)~:not(template){--divide-opacity:1;border-color:#68d391;border-color:rgba(104,211,145,var(--divide-opacity))}.sm\:divide-green-500>:not(template)~:not(template){--divide-opacity:1;border-color:#48bb78;border-color:rgba(72,187,120,var(--divide-opacity))}.sm\:divide-green-600>:not(template)~:not(template){--divide-opacity:1;border-color:#38a169;border-color:rgba(56,161,105,var(--divide-opacity))}.sm\:divide-green-700>:not(template)~:not(template){--divide-opacity:1;border-color:#2f855a;border-color:rgba(47,133,90,var(--divide-opacity))}.sm\:divide-green-800>:not(template)~:not(template){--divide-opacity:1;border-color:#276749;border-color:rgba(39,103,73,var(--divide-opacity))}.sm\:divide-green-900>:not(template)~:not(template){--divide-opacity:1;border-color:#22543d;border-color:rgba(34,84,61,var(--divide-opacity))}.sm\:divide-teal-100>:not(template)~:not(template){--divide-opacity:1;border-color:#e6fffa;border-color:rgba(230,255,250,var(--divide-opacity))}.sm\:divide-teal-200>:not(template)~:not(template){--divide-opacity:1;border-color:#b2f5ea;border-color:rgba(178,245,234,var(--divide-opacity))}.sm\:divide-teal-300>:not(template)~:not(template){--divide-opacity:1;border-color:#81e6d9;border-color:rgba(129,230,217,var(--divide-opacity))}.sm\:divide-teal-400>:not(template)~:not(template){--divide-opacity:1;border-color:#4fd1c5;border-color:rgba(79,209,197,var(--divide-opacity))}.sm\:divide-teal-500>:not(template)~:not(template){--divide-opacity:1;border-color:#38b2ac;border-color:rgba(56,178,172,var(--divide-opacity))}.sm\:divide-teal-600>:not(template)~:not(template){--divide-opacity:1;border-color:#319795;border-color:rgba(49,151,149,var(--divide-opacity))}.sm\:divide-teal-700>:not(template)~:not(template){--divide-opacity:1;border-color:#2c7a7b;border-color:rgba(44,122,123,var(--divide-opacity))}.sm\:divide-teal-800>:not(template)~:not(template){--divide-opacity:1;border-color:#285e61;border-color:rgba(40,94,97,var(--divide-opacity))}.sm\:divide-teal-900>:not(template)~:not(template){--divide-opacity:1;border-color:#234e52;border-color:rgba(35,78,82,var(--divide-opacity))}.sm\:divide-blue-100>:not(template)~:not(template){--divide-opacity:1;border-color:#ebf8ff;border-color:rgba(235,248,255,var(--divide-opacity))}.sm\:divide-blue-200>:not(template)~:not(template){--divide-opacity:1;border-color:#bee3f8;border-color:rgba(190,227,248,var(--divide-opacity))}.sm\:divide-blue-300>:not(template)~:not(template){--divide-opacity:1;border-color:#90cdf4;border-color:rgba(144,205,244,var(--divide-opacity))}.sm\:divide-blue-400>:not(template)~:not(template){--divide-opacity:1;border-color:#63b3ed;border-color:rgba(99,179,237,var(--divide-opacity))}.sm\:divide-blue-500>:not(template)~:not(template){--divide-opacity:1;border-color:#4299e1;border-color:rgba(66,153,225,var(--divide-opacity))}.sm\:divide-blue-600>:not(template)~:not(template){--divide-opacity:1;border-color:#3182ce;border-color:rgba(49,130,206,var(--divide-opacity))}.sm\:divide-blue-700>:not(template)~:not(template){--divide-opacity:1;border-color:#2b6cb0;border-color:rgba(43,108,176,var(--divide-opacity))}.sm\:divide-blue-800>:not(template)~:not(template){--divide-opacity:1;border-color:#2c5282;border-color:rgba(44,82,130,var(--divide-opacity))}.sm\:divide-blue-900>:not(template)~:not(template){--divide-opacity:1;border-color:#2a4365;border-color:rgba(42,67,101,var(--divide-opacity))}.sm\:divide-indigo-100>:not(template)~:not(template){--divide-opacity:1;border-color:#ebf4ff;border-color:rgba(235,244,255,var(--divide-opacity))}.sm\:divide-indigo-200>:not(template)~:not(template){--divide-opacity:1;border-color:#c3dafe;border-color:rgba(195,218,254,var(--divide-opacity))}.sm\:divide-indigo-300>:not(template)~:not(template){--divide-opacity:1;border-color:#a3bffa;border-color:rgba(163,191,250,var(--divide-opacity))}.sm\:divide-indigo-400>:not(template)~:not(template){--divide-opacity:1;border-color:#7f9cf5;border-color:rgba(127,156,245,var(--divide-opacity))}.sm\:divide-indigo-500>:not(template)~:not(template){--divide-opacity:1;border-color:#667eea;border-color:rgba(102,126,234,var(--divide-opacity))}.sm\:divide-indigo-600>:not(template)~:not(template){--divide-opacity:1;border-color:#5a67d8;border-color:rgba(90,103,216,var(--divide-opacity))}.sm\:divide-indigo-700>:not(template)~:not(template){--divide-opacity:1;border-color:#4c51bf;border-color:rgba(76,81,191,var(--divide-opacity))}.sm\:divide-indigo-800>:not(template)~:not(template){--divide-opacity:1;border-color:#434190;border-color:rgba(67,65,144,var(--divide-opacity))}.sm\:divide-indigo-900>:not(template)~:not(template){--divide-opacity:1;border-color:#3c366b;border-color:rgba(60,54,107,var(--divide-opacity))}.sm\:divide-purple-100>:not(template)~:not(template){--divide-opacity:1;border-color:#faf5ff;border-color:rgba(250,245,255,var(--divide-opacity))}.sm\:divide-purple-200>:not(template)~:not(template){--divide-opacity:1;border-color:#e9d8fd;border-color:rgba(233,216,253,var(--divide-opacity))}.sm\:divide-purple-300>:not(template)~:not(template){--divide-opacity:1;border-color:#d6bcfa;border-color:rgba(214,188,250,var(--divide-opacity))}.sm\:divide-purple-400>:not(template)~:not(template){--divide-opacity:1;border-color:#b794f4;border-color:rgba(183,148,244,var(--divide-opacity))}.sm\:divide-purple-500>:not(template)~:not(template){--divide-opacity:1;border-color:#9f7aea;border-color:rgba(159,122,234,var(--divide-opacity))}.sm\:divide-purple-600>:not(template)~:not(template){--divide-opacity:1;border-color:#805ad5;border-color:rgba(128,90,213,var(--divide-opacity))}.sm\:divide-purple-700>:not(template)~:not(template){--divide-opacity:1;border-color:#6b46c1;border-color:rgba(107,70,193,var(--divide-opacity))}.sm\:divide-purple-800>:not(template)~:not(template){--divide-opacity:1;border-color:#553c9a;border-color:rgba(85,60,154,var(--divide-opacity))}.sm\:divide-purple-900>:not(template)~:not(template){--divide-opacity:1;border-color:#44337a;border-color:rgba(68,51,122,var(--divide-opacity))}.sm\:divide-pink-100>:not(template)~:not(template){--divide-opacity:1;border-color:#fff5f7;border-color:rgba(255,245,247,var(--divide-opacity))}.sm\:divide-pink-200>:not(template)~:not(template){--divide-opacity:1;border-color:#fed7e2;border-color:rgba(254,215,226,var(--divide-opacity))}.sm\:divide-pink-300>:not(template)~:not(template){--divide-opacity:1;border-color:#fbb6ce;border-color:rgba(251,182,206,var(--divide-opacity))}.sm\:divide-pink-400>:not(template)~:not(template){--divide-opacity:1;border-color:#f687b3;border-color:rgba(246,135,179,var(--divide-opacity))}.sm\:divide-pink-500>:not(template)~:not(template){--divide-opacity:1;border-color:#ed64a6;border-color:rgba(237,100,166,var(--divide-opacity))}.sm\:divide-pink-600>:not(template)~:not(template){--divide-opacity:1;border-color:#d53f8c;border-color:rgba(213,63,140,var(--divide-opacity))}.sm\:divide-pink-700>:not(template)~:not(template){--divide-opacity:1;border-color:#b83280;border-color:rgba(184,50,128,var(--divide-opacity))}.sm\:divide-pink-800>:not(template)~:not(template){--divide-opacity:1;border-color:#97266d;border-color:rgba(151,38,109,var(--divide-opacity))}.sm\:divide-pink-900>:not(template)~:not(template){--divide-opacity:1;border-color:#702459;border-color:rgba(112,36,89,var(--divide-opacity))}.sm\:divide-solid>:not(template)~:not(template){border-style:solid}.sm\:divide-dashed>:not(template)~:not(template){border-style:dashed}.sm\:divide-dotted>:not(template)~:not(template){border-style:dotted}.sm\:divide-double>:not(template)~:not(template){border-style:double}.sm\:divide-none>:not(template)~:not(template){border-style:none}.sm\:divide-opacity-0>:not(template)~:not(template){--divide-opacity:0}.sm\:divide-opacity-25>:not(template)~:not(template){--divide-opacity:0.25}.sm\:divide-opacity-50>:not(template)~:not(template){--divide-opacity:0.5}.sm\:divide-opacity-75>:not(template)~:not(template){--divide-opacity:0.75}.sm\:divide-opacity-100>:not(template)~:not(template){--divide-opacity:1}.sm\:sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border-width:0}.sm\:not-sr-only{position:static;width:auto;height:auto;padding:0;margin:0;overflow:visible;clip:auto;white-space:normal}.sm\:focus\:sr-only:focus{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border-width:0}.sm\:focus\:not-sr-only:focus{position:static;width:auto;height:auto;padding:0;margin:0;overflow:visible;clip:auto;white-space:normal}.sm\:appearance-none{-webkit-appearance:none;-moz-appearance:none;appearance:none}.sm\:bg-fixed{background-attachment:fixed}.sm\:bg-local{background-attachment:local}.sm\:bg-scroll{background-attachment:scroll}.sm\:bg-clip-border{background-clip:border-box}.sm\:bg-clip-padding{background-clip:padding-box}.sm\:bg-clip-content{background-clip:content-box}.sm\:bg-clip-text{-webkit-background-clip:text;background-clip:text}.sm\:bg-transparent{background-color:transparent}.sm\:bg-current{background-color:currentColor}.sm\:bg-black{--bg-opacity:1;background-color:#000;background-color:rgba(0,0,0,var(--bg-opacity))}.sm\:bg-white{--bg-opacity:1;background-color:#fff;background-color:rgba(255,255,255,var(--bg-opacity))}.sm\:bg-gray-100{--bg-opacity:1;background-color:#f7fafc;background-color:rgba(247,250,252,var(--bg-opacity))}.sm\:bg-gray-200{--bg-opacity:1;background-color:#edf2f7;background-color:rgba(237,242,247,var(--bg-opacity))}.sm\:bg-gray-300{--bg-opacity:1;background-color:#e2e8f0;background-color:rgba(226,232,240,var(--bg-opacity))}.sm\:bg-gray-400{--bg-opacity:1;background-color:#cbd5e0;background-color:rgba(203,213,224,var(--bg-opacity))}.sm\:bg-gray-500{--bg-opacity:1;background-color:#a0aec0;background-color:rgba(160,174,192,var(--bg-opacity))}.sm\:bg-gray-600{--bg-opacity:1;background-color:#718096;background-color:rgba(113,128,150,var(--bg-opacity))}.sm\:bg-gray-700{--bg-opacity:1;background-color:#4a5568;background-color:rgba(74,85,104,var(--bg-opacity))}.sm\:bg-gray-800{--bg-opacity:1;background-color:#2d3748;background-color:rgba(45,55,72,var(--bg-opacity))}.sm\:bg-gray-900{--bg-opacity:1;background-color:#1a202c;background-color:rgba(26,32,44,var(--bg-opacity))}.sm\:bg-red-100{--bg-opacity:1;background-color:#fff5f5;background-color:rgba(255,245,245,var(--bg-opacity))}.sm\:bg-red-200{--bg-opacity:1;background-color:#fed7d7;background-color:rgba(254,215,215,var(--bg-opacity))}.sm\:bg-red-300{--bg-opacity:1;background-color:#feb2b2;background-color:rgba(254,178,178,var(--bg-opacity))}.sm\:bg-red-400{--bg-opacity:1;background-color:#fc8181;background-color:rgba(252,129,129,var(--bg-opacity))}.sm\:bg-red-500{--bg-opacity:1;background-color:#f56565;background-color:rgba(245,101,101,var(--bg-opacity))}.sm\:bg-red-600{--bg-opacity:1;background-color:#e53e3e;background-color:rgba(229,62,62,var(--bg-opacity))}.sm\:bg-red-700{--bg-opacity:1;background-color:#c53030;background-color:rgba(197,48,48,var(--bg-opacity))}.sm\:bg-red-800{--bg-opacity:1;background-color:#9b2c2c;background-color:rgba(155,44,44,var(--bg-opacity))}.sm\:bg-red-900{--bg-opacity:1;background-color:#742a2a;background-color:rgba(116,42,42,var(--bg-opacity))}.sm\:bg-orange-100{--bg-opacity:1;background-color:#fffaf0;background-color:rgba(255,250,240,var(--bg-opacity))}.sm\:bg-orange-200{--bg-opacity:1;background-color:#feebc8;background-color:rgba(254,235,200,var(--bg-opacity))}.sm\:bg-orange-300{--bg-opacity:1;background-color:#fbd38d;background-color:rgba(251,211,141,var(--bg-opacity))}.sm\:bg-orange-400{--bg-opacity:1;background-color:#f6ad55;background-color:rgba(246,173,85,var(--bg-opacity))}.sm\:bg-orange-500{--bg-opacity:1;background-color:#ed8936;background-color:rgba(237,137,54,var(--bg-opacity))}.sm\:bg-orange-600{--bg-opacity:1;background-color:#dd6b20;background-color:rgba(221,107,32,var(--bg-opacity))}.sm\:bg-orange-700{--bg-opacity:1;background-color:#c05621;background-color:rgba(192,86,33,var(--bg-opacity))}.sm\:bg-orange-800{--bg-opacity:1;background-color:#9c4221;background-color:rgba(156,66,33,var(--bg-opacity))}.sm\:bg-orange-900{--bg-opacity:1;background-color:#7b341e;background-color:rgba(123,52,30,var(--bg-opacity))}.sm\:bg-yellow-100{--bg-opacity:1;background-color:ivory;background-color:rgba(255,255,240,var(--bg-opacity))}.sm\:bg-yellow-200{--bg-opacity:1;background-color:#fefcbf;background-color:rgba(254,252,191,var(--bg-opacity))}.sm\:bg-yellow-300{--bg-opacity:1;background-color:#faf089;background-color:rgba(250,240,137,var(--bg-opacity))}.sm\:bg-yellow-400{--bg-opacity:1;background-color:#f6e05e;background-color:rgba(246,224,94,var(--bg-opacity))}.sm\:bg-yellow-500{--bg-opacity:1;background-color:#ecc94b;background-color:rgba(236,201,75,var(--bg-opacity))}.sm\:bg-yellow-600{--bg-opacity:1;background-color:#d69e2e;background-color:rgba(214,158,46,var(--bg-opacity))}.sm\:bg-yellow-700{--bg-opacity:1;background-color:#b7791f;background-color:rgba(183,121,31,var(--bg-opacity))}.sm\:bg-yellow-800{--bg-opacity:1;background-color:#975a16;background-color:rgba(151,90,22,var(--bg-opacity))}.sm\:bg-yellow-900{--bg-opacity:1;background-color:#744210;background-color:rgba(116,66,16,var(--bg-opacity))}.sm\:bg-green-100{--bg-opacity:1;background-color:#f0fff4;background-color:rgba(240,255,244,var(--bg-opacity))}.sm\:bg-green-200{--bg-opacity:1;background-color:#c6f6d5;background-color:rgba(198,246,213,var(--bg-opacity))}.sm\:bg-green-300{--bg-opacity:1;background-color:#9ae6b4;background-color:rgba(154,230,180,var(--bg-opacity))}.sm\:bg-green-400{--bg-opacity:1;background-color:#68d391;background-color:rgba(104,211,145,var(--bg-opacity))}.sm\:bg-green-500{--bg-opacity:1;background-color:#48bb78;background-color:rgba(72,187,120,var(--bg-opacity))}.sm\:bg-green-600{--bg-opacity:1;background-color:#38a169;background-color:rgba(56,161,105,var(--bg-opacity))}.sm\:bg-green-700{--bg-opacity:1;background-color:#2f855a;background-color:rgba(47,133,90,var(--bg-opacity))}.sm\:bg-green-800{--bg-opacity:1;background-color:#276749;background-color:rgba(39,103,73,var(--bg-opacity))}.sm\:bg-green-900{--bg-opacity:1;background-color:#22543d;background-color:rgba(34,84,61,var(--bg-opacity))}.sm\:bg-teal-100{--bg-opacity:1;background-color:#e6fffa;background-color:rgba(230,255,250,var(--bg-opacity))}.sm\:bg-teal-200{--bg-opacity:1;background-color:#b2f5ea;background-color:rgba(178,245,234,var(--bg-opacity))}.sm\:bg-teal-300{--bg-opacity:1;background-color:#81e6d9;background-color:rgba(129,230,217,var(--bg-opacity))}.sm\:bg-teal-400{--bg-opacity:1;background-color:#4fd1c5;background-color:rgba(79,209,197,var(--bg-opacity))}.sm\:bg-teal-500{--bg-opacity:1;background-color:#38b2ac;background-color:rgba(56,178,172,var(--bg-opacity))}.sm\:bg-teal-600{--bg-opacity:1;background-color:#319795;background-color:rgba(49,151,149,var(--bg-opacity))}.sm\:bg-teal-700{--bg-opacity:1;background-color:#2c7a7b;background-color:rgba(44,122,123,var(--bg-opacity))}.sm\:bg-teal-800{--bg-opacity:1;background-color:#285e61;background-color:rgba(40,94,97,var(--bg-opacity))}.sm\:bg-teal-900{--bg-opacity:1;background-color:#234e52;background-color:rgba(35,78,82,var(--bg-opacity))}.sm\:bg-blue-100{--bg-opacity:1;background-color:#ebf8ff;background-color:rgba(235,248,255,var(--bg-opacity))}.sm\:bg-blue-200{--bg-opacity:1;background-color:#bee3f8;background-color:rgba(190,227,248,var(--bg-opacity))}.sm\:bg-blue-300{--bg-opacity:1;background-color:#90cdf4;background-color:rgba(144,205,244,var(--bg-opacity))}.sm\:bg-blue-400{--bg-opacity:1;background-color:#63b3ed;background-color:rgba(99,179,237,var(--bg-opacity))}.sm\:bg-blue-500{--bg-opacity:1;background-color:#4299e1;background-color:rgba(66,153,225,var(--bg-opacity))}.sm\:bg-blue-600{--bg-opacity:1;background-color:#3182ce;background-color:rgba(49,130,206,var(--bg-opacity))}.sm\:bg-blue-700{--bg-opacity:1;background-color:#2b6cb0;background-color:rgba(43,108,176,var(--bg-opacity))}.sm\:bg-blue-800{--bg-opacity:1;background-color:#2c5282;background-color:rgba(44,82,130,var(--bg-opacity))}.sm\:bg-blue-900{--bg-opacity:1;background-color:#2a4365;background-color:rgba(42,67,101,var(--bg-opacity))}.sm\:bg-indigo-100{--bg-opacity:1;background-color:#ebf4ff;background-color:rgba(235,244,255,var(--bg-opacity))}.sm\:bg-indigo-200{--bg-opacity:1;background-color:#c3dafe;background-color:rgba(195,218,254,var(--bg-opacity))}.sm\:bg-indigo-300{--bg-opacity:1;background-color:#a3bffa;background-color:rgba(163,191,250,var(--bg-opacity))}.sm\:bg-indigo-400{--bg-opacity:1;background-color:#7f9cf5;background-color:rgba(127,156,245,var(--bg-opacity))}.sm\:bg-indigo-500{--bg-opacity:1;background-color:#667eea;background-color:rgba(102,126,234,var(--bg-opacity))}.sm\:bg-indigo-600{--bg-opacity:1;background-color:#5a67d8;background-color:rgba(90,103,216,var(--bg-opacity))}.sm\:bg-indigo-700{--bg-opacity:1;background-color:#4c51bf;background-color:rgba(76,81,191,var(--bg-opacity))}.sm\:bg-indigo-800{--bg-opacity:1;background-color:#434190;background-color:rgba(67,65,144,var(--bg-opacity))}.sm\:bg-indigo-900{--bg-opacity:1;background-color:#3c366b;background-color:rgba(60,54,107,var(--bg-opacity))}.sm\:bg-purple-100{--bg-opacity:1;background-color:#faf5ff;background-color:rgba(250,245,255,var(--bg-opacity))}.sm\:bg-purple-200{--bg-opacity:1;background-color:#e9d8fd;background-color:rgba(233,216,253,var(--bg-opacity))}.sm\:bg-purple-300{--bg-opacity:1;background-color:#d6bcfa;background-color:rgba(214,188,250,var(--bg-opacity))}.sm\:bg-purple-400{--bg-opacity:1;background-color:#b794f4;background-color:rgba(183,148,244,var(--bg-opacity))}.sm\:bg-purple-500{--bg-opacity:1;background-color:#9f7aea;background-color:rgba(159,122,234,var(--bg-opacity))}.sm\:bg-purple-600{--bg-opacity:1;background-color:#805ad5;background-color:rgba(128,90,213,var(--bg-opacity))}.sm\:bg-purple-700{--bg-opacity:1;background-color:#6b46c1;background-color:rgba(107,70,193,var(--bg-opacity))}.sm\:bg-purple-800{--bg-opacity:1;background-color:#553c9a;background-color:rgba(85,60,154,var(--bg-opacity))}.sm\:bg-purple-900{--bg-opacity:1;background-color:#44337a;background-color:rgba(68,51,122,var(--bg-opacity))}.sm\:bg-pink-100{--bg-opacity:1;background-color:#fff5f7;background-color:rgba(255,245,247,var(--bg-opacity))}.sm\:bg-pink-200{--bg-opacity:1;background-color:#fed7e2;background-color:rgba(254,215,226,var(--bg-opacity))}.sm\:bg-pink-300{--bg-opacity:1;background-color:#fbb6ce;background-color:rgba(251,182,206,var(--bg-opacity))}.sm\:bg-pink-400{--bg-opacity:1;background-color:#f687b3;background-color:rgba(246,135,179,var(--bg-opacity))}.sm\:bg-pink-500{--bg-opacity:1;background-color:#ed64a6;background-color:rgba(237,100,166,var(--bg-opacity))}.sm\:bg-pink-600{--bg-opacity:1;background-color:#d53f8c;background-color:rgba(213,63,140,var(--bg-opacity))}.sm\:bg-pink-700{--bg-opacity:1;background-color:#b83280;background-color:rgba(184,50,128,var(--bg-opacity))}.sm\:bg-pink-800{--bg-opacity:1;background-color:#97266d;background-color:rgba(151,38,109,var(--bg-opacity))}.sm\:bg-pink-900{--bg-opacity:1;background-color:#702459;background-color:rgba(112,36,89,var(--bg-opacity))}.sm\:hover\:bg-transparent:hover{background-color:transparent}.sm\:hover\:bg-current:hover{background-color:currentColor}.sm\:hover\:bg-black:hover{--bg-opacity:1;background-color:#000;background-color:rgba(0,0,0,var(--bg-opacity))}.sm\:hover\:bg-white:hover{--bg-opacity:1;background-color:#fff;background-color:rgba(255,255,255,var(--bg-opacity))}.sm\:hover\:bg-gray-100:hover{--bg-opacity:1;background-color:#f7fafc;background-color:rgba(247,250,252,var(--bg-opacity))}.sm\:hover\:bg-gray-200:hover{--bg-opacity:1;background-color:#edf2f7;background-color:rgba(237,242,247,var(--bg-opacity))}.sm\:hover\:bg-gray-300:hover{--bg-opacity:1;background-color:#e2e8f0;background-color:rgba(226,232,240,var(--bg-opacity))}.sm\:hover\:bg-gray-400:hover{--bg-opacity:1;background-color:#cbd5e0;background-color:rgba(203,213,224,var(--bg-opacity))}.sm\:hover\:bg-gray-500:hover{--bg-opacity:1;background-color:#a0aec0;background-color:rgba(160,174,192,var(--bg-opacity))}.sm\:hover\:bg-gray-600:hover{--bg-opacity:1;background-color:#718096;background-color:rgba(113,128,150,var(--bg-opacity))}.sm\:hover\:bg-gray-700:hover{--bg-opacity:1;background-color:#4a5568;background-color:rgba(74,85,104,var(--bg-opacity))}.sm\:hover\:bg-gray-800:hover{--bg-opacity:1;background-color:#2d3748;background-color:rgba(45,55,72,var(--bg-opacity))}.sm\:hover\:bg-gray-900:hover{--bg-opacity:1;background-color:#1a202c;background-color:rgba(26,32,44,var(--bg-opacity))}.sm\:hover\:bg-red-100:hover{--bg-opacity:1;background-color:#fff5f5;background-color:rgba(255,245,245,var(--bg-opacity))}.sm\:hover\:bg-red-200:hover{--bg-opacity:1;background-color:#fed7d7;background-color:rgba(254,215,215,var(--bg-opacity))}.sm\:hover\:bg-red-300:hover{--bg-opacity:1;background-color:#feb2b2;background-color:rgba(254,178,178,var(--bg-opacity))}.sm\:hover\:bg-red-400:hover{--bg-opacity:1;background-color:#fc8181;background-color:rgba(252,129,129,var(--bg-opacity))}.sm\:hover\:bg-red-500:hover{--bg-opacity:1;background-color:#f56565;background-color:rgba(245,101,101,var(--bg-opacity))}.sm\:hover\:bg-red-600:hover{--bg-opacity:1;background-color:#e53e3e;background-color:rgba(229,62,62,var(--bg-opacity))}.sm\:hover\:bg-red-700:hover{--bg-opacity:1;background-color:#c53030;background-color:rgba(197,48,48,var(--bg-opacity))}.sm\:hover\:bg-red-800:hover{--bg-opacity:1;background-color:#9b2c2c;background-color:rgba(155,44,44,var(--bg-opacity))}.sm\:hover\:bg-red-900:hover{--bg-opacity:1;background-color:#742a2a;background-color:rgba(116,42,42,var(--bg-opacity))}.sm\:hover\:bg-orange-100:hover{--bg-opacity:1;background-color:#fffaf0;background-color:rgba(255,250,240,var(--bg-opacity))}.sm\:hover\:bg-orange-200:hover{--bg-opacity:1;background-color:#feebc8;background-color:rgba(254,235,200,var(--bg-opacity))}.sm\:hover\:bg-orange-300:hover{--bg-opacity:1;background-color:#fbd38d;background-color:rgba(251,211,141,var(--bg-opacity))}.sm\:hover\:bg-orange-400:hover{--bg-opacity:1;background-color:#f6ad55;background-color:rgba(246,173,85,var(--bg-opacity))}.sm\:hover\:bg-orange-500:hover{--bg-opacity:1;background-color:#ed8936;background-color:rgba(237,137,54,var(--bg-opacity))}.sm\:hover\:bg-orange-600:hover{--bg-opacity:1;background-color:#dd6b20;background-color:rgba(221,107,32,var(--bg-opacity))}.sm\:hover\:bg-orange-700:hover{--bg-opacity:1;background-color:#c05621;background-color:rgba(192,86,33,var(--bg-opacity))}.sm\:hover\:bg-orange-800:hover{--bg-opacity:1;background-color:#9c4221;background-color:rgba(156,66,33,var(--bg-opacity))}.sm\:hover\:bg-orange-900:hover{--bg-opacity:1;background-color:#7b341e;background-color:rgba(123,52,30,var(--bg-opacity))}.sm\:hover\:bg-yellow-100:hover{--bg-opacity:1;background-color:ivory;background-color:rgba(255,255,240,var(--bg-opacity))}.sm\:hover\:bg-yellow-200:hover{--bg-opacity:1;background-color:#fefcbf;background-color:rgba(254,252,191,var(--bg-opacity))}.sm\:hover\:bg-yellow-300:hover{--bg-opacity:1;background-color:#faf089;background-color:rgba(250,240,137,var(--bg-opacity))}.sm\:hover\:bg-yellow-400:hover{--bg-opacity:1;background-color:#f6e05e;background-color:rgba(246,224,94,var(--bg-opacity))}.sm\:hover\:bg-yellow-500:hover{--bg-opacity:1;background-color:#ecc94b;background-color:rgba(236,201,75,var(--bg-opacity))}.sm\:hover\:bg-yellow-600:hover{--bg-opacity:1;background-color:#d69e2e;background-color:rgba(214,158,46,var(--bg-opacity))}.sm\:hover\:bg-yellow-700:hover{--bg-opacity:1;background-color:#b7791f;background-color:rgba(183,121,31,var(--bg-opacity))}.sm\:hover\:bg-yellow-800:hover{--bg-opacity:1;background-color:#975a16;background-color:rgba(151,90,22,var(--bg-opacity))}.sm\:hover\:bg-yellow-900:hover{--bg-opacity:1;background-color:#744210;background-color:rgba(116,66,16,var(--bg-opacity))}.sm\:hover\:bg-green-100:hover{--bg-opacity:1;background-color:#f0fff4;background-color:rgba(240,255,244,var(--bg-opacity))}.sm\:hover\:bg-green-200:hover{--bg-opacity:1;background-color:#c6f6d5;background-color:rgba(198,246,213,var(--bg-opacity))}.sm\:hover\:bg-green-300:hover{--bg-opacity:1;background-color:#9ae6b4;background-color:rgba(154,230,180,var(--bg-opacity))}.sm\:hover\:bg-green-400:hover{--bg-opacity:1;background-color:#68d391;background-color:rgba(104,211,145,var(--bg-opacity))}.sm\:hover\:bg-green-500:hover{--bg-opacity:1;background-color:#48bb78;background-color:rgba(72,187,120,var(--bg-opacity))}.sm\:hover\:bg-green-600:hover{--bg-opacity:1;background-color:#38a169;background-color:rgba(56,161,105,var(--bg-opacity))}.sm\:hover\:bg-green-700:hover{--bg-opacity:1;background-color:#2f855a;background-color:rgba(47,133,90,var(--bg-opacity))}.sm\:hover\:bg-green-800:hover{--bg-opacity:1;background-color:#276749;background-color:rgba(39,103,73,var(--bg-opacity))}.sm\:hover\:bg-green-900:hover{--bg-opacity:1;background-color:#22543d;background-color:rgba(34,84,61,var(--bg-opacity))}.sm\:hover\:bg-teal-100:hover{--bg-opacity:1;background-color:#e6fffa;background-color:rgba(230,255,250,var(--bg-opacity))}.sm\:hover\:bg-teal-200:hover{--bg-opacity:1;background-color:#b2f5ea;background-color:rgba(178,245,234,var(--bg-opacity))}.sm\:hover\:bg-teal-300:hover{--bg-opacity:1;background-color:#81e6d9;background-color:rgba(129,230,217,var(--bg-opacity))}.sm\:hover\:bg-teal-400:hover{--bg-opacity:1;background-color:#4fd1c5;background-color:rgba(79,209,197,var(--bg-opacity))}.sm\:hover\:bg-teal-500:hover{--bg-opacity:1;background-color:#38b2ac;background-color:rgba(56,178,172,var(--bg-opacity))}.sm\:hover\:bg-teal-600:hover{--bg-opacity:1;background-color:#319795;background-color:rgba(49,151,149,var(--bg-opacity))}.sm\:hover\:bg-teal-700:hover{--bg-opacity:1;background-color:#2c7a7b;background-color:rgba(44,122,123,var(--bg-opacity))}.sm\:hover\:bg-teal-800:hover{--bg-opacity:1;background-color:#285e61;background-color:rgba(40,94,97,var(--bg-opacity))}.sm\:hover\:bg-teal-900:hover{--bg-opacity:1;background-color:#234e52;background-color:rgba(35,78,82,var(--bg-opacity))}.sm\:hover\:bg-blue-100:hover{--bg-opacity:1;background-color:#ebf8ff;background-color:rgba(235,248,255,var(--bg-opacity))}.sm\:hover\:bg-blue-200:hover{--bg-opacity:1;background-color:#bee3f8;background-color:rgba(190,227,248,var(--bg-opacity))}.sm\:hover\:bg-blue-300:hover{--bg-opacity:1;background-color:#90cdf4;background-color:rgba(144,205,244,var(--bg-opacity))}.sm\:hover\:bg-blue-400:hover{--bg-opacity:1;background-color:#63b3ed;background-color:rgba(99,179,237,var(--bg-opacity))}.sm\:hover\:bg-blue-500:hover{--bg-opacity:1;background-color:#4299e1;background-color:rgba(66,153,225,var(--bg-opacity))}.sm\:hover\:bg-blue-600:hover{--bg-opacity:1;background-color:#3182ce;background-color:rgba(49,130,206,var(--bg-opacity))}.sm\:hover\:bg-blue-700:hover{--bg-opacity:1;background-color:#2b6cb0;background-color:rgba(43,108,176,var(--bg-opacity))}.sm\:hover\:bg-blue-800:hover{--bg-opacity:1;background-color:#2c5282;background-color:rgba(44,82,130,var(--bg-opacity))}.sm\:hover\:bg-blue-900:hover{--bg-opacity:1;background-color:#2a4365;background-color:rgba(42,67,101,var(--bg-opacity))}.sm\:hover\:bg-indigo-100:hover{--bg-opacity:1;background-color:#ebf4ff;background-color:rgba(235,244,255,var(--bg-opacity))}.sm\:hover\:bg-indigo-200:hover{--bg-opacity:1;background-color:#c3dafe;background-color:rgba(195,218,254,var(--bg-opacity))}.sm\:hover\:bg-indigo-300:hover{--bg-opacity:1;background-color:#a3bffa;background-color:rgba(163,191,250,var(--bg-opacity))}.sm\:hover\:bg-indigo-400:hover{--bg-opacity:1;background-color:#7f9cf5;background-color:rgba(127,156,245,var(--bg-opacity))}.sm\:hover\:bg-indigo-500:hover{--bg-opacity:1;background-color:#667eea;background-color:rgba(102,126,234,var(--bg-opacity))}.sm\:hover\:bg-indigo-600:hover{--bg-opacity:1;background-color:#5a67d8;background-color:rgba(90,103,216,var(--bg-opacity))}.sm\:hover\:bg-indigo-700:hover{--bg-opacity:1;background-color:#4c51bf;background-color:rgba(76,81,191,var(--bg-opacity))}.sm\:hover\:bg-indigo-800:hover{--bg-opacity:1;background-color:#434190;background-color:rgba(67,65,144,var(--bg-opacity))}.sm\:hover\:bg-indigo-900:hover{--bg-opacity:1;background-color:#3c366b;background-color:rgba(60,54,107,var(--bg-opacity))}.sm\:hover\:bg-purple-100:hover{--bg-opacity:1;background-color:#faf5ff;background-color:rgba(250,245,255,var(--bg-opacity))}.sm\:hover\:bg-purple-200:hover{--bg-opacity:1;background-color:#e9d8fd;background-color:rgba(233,216,253,var(--bg-opacity))}.sm\:hover\:bg-purple-300:hover{--bg-opacity:1;background-color:#d6bcfa;background-color:rgba(214,188,250,var(--bg-opacity))}.sm\:hover\:bg-purple-400:hover{--bg-opacity:1;background-color:#b794f4;background-color:rgba(183,148,244,var(--bg-opacity))}.sm\:hover\:bg-purple-500:hover{--bg-opacity:1;background-color:#9f7aea;background-color:rgba(159,122,234,var(--bg-opacity))}.sm\:hover\:bg-purple-600:hover{--bg-opacity:1;background-color:#805ad5;background-color:rgba(128,90,213,var(--bg-opacity))}.sm\:hover\:bg-purple-700:hover{--bg-opacity:1;background-color:#6b46c1;background-color:rgba(107,70,193,var(--bg-opacity))}.sm\:hover\:bg-purple-800:hover{--bg-opacity:1;background-color:#553c9a;background-color:rgba(85,60,154,var(--bg-opacity))}.sm\:hover\:bg-purple-900:hover{--bg-opacity:1;background-color:#44337a;background-color:rgba(68,51,122,var(--bg-opacity))}.sm\:hover\:bg-pink-100:hover{--bg-opacity:1;background-color:#fff5f7;background-color:rgba(255,245,247,var(--bg-opacity))}.sm\:hover\:bg-pink-200:hover{--bg-opacity:1;background-color:#fed7e2;background-color:rgba(254,215,226,var(--bg-opacity))}.sm\:hover\:bg-pink-300:hover{--bg-opacity:1;background-color:#fbb6ce;background-color:rgba(251,182,206,var(--bg-opacity))}.sm\:hover\:bg-pink-400:hover{--bg-opacity:1;background-color:#f687b3;background-color:rgba(246,135,179,var(--bg-opacity))}.sm\:hover\:bg-pink-500:hover{--bg-opacity:1;background-color:#ed64a6;background-color:rgba(237,100,166,var(--bg-opacity))}.sm\:hover\:bg-pink-600:hover{--bg-opacity:1;background-color:#d53f8c;background-color:rgba(213,63,140,var(--bg-opacity))}.sm\:hover\:bg-pink-700:hover{--bg-opacity:1;background-color:#b83280;background-color:rgba(184,50,128,var(--bg-opacity))}.sm\:hover\:bg-pink-800:hover{--bg-opacity:1;background-color:#97266d;background-color:rgba(151,38,109,var(--bg-opacity))}.sm\:hover\:bg-pink-900:hover{--bg-opacity:1;background-color:#702459;background-color:rgba(112,36,89,var(--bg-opacity))}.sm\:focus\:bg-transparent:focus{background-color:transparent}.sm\:focus\:bg-current:focus{background-color:currentColor}.sm\:focus\:bg-black:focus{--bg-opacity:1;background-color:#000;background-color:rgba(0,0,0,var(--bg-opacity))}.sm\:focus\:bg-white:focus{--bg-opacity:1;background-color:#fff;background-color:rgba(255,255,255,var(--bg-opacity))}.sm\:focus\:bg-gray-100:focus{--bg-opacity:1;background-color:#f7fafc;background-color:rgba(247,250,252,var(--bg-opacity))}.sm\:focus\:bg-gray-200:focus{--bg-opacity:1;background-color:#edf2f7;background-color:rgba(237,242,247,var(--bg-opacity))}.sm\:focus\:bg-gray-300:focus{--bg-opacity:1;background-color:#e2e8f0;background-color:rgba(226,232,240,var(--bg-opacity))}.sm\:focus\:bg-gray-400:focus{--bg-opacity:1;background-color:#cbd5e0;background-color:rgba(203,213,224,var(--bg-opacity))}.sm\:focus\:bg-gray-500:focus{--bg-opacity:1;background-color:#a0aec0;background-color:rgba(160,174,192,var(--bg-opacity))}.sm\:focus\:bg-gray-600:focus{--bg-opacity:1;background-color:#718096;background-color:rgba(113,128,150,var(--bg-opacity))}.sm\:focus\:bg-gray-700:focus{--bg-opacity:1;background-color:#4a5568;background-color:rgba(74,85,104,var(--bg-opacity))}.sm\:focus\:bg-gray-800:focus{--bg-opacity:1;background-color:#2d3748;background-color:rgba(45,55,72,var(--bg-opacity))}.sm\:focus\:bg-gray-900:focus{--bg-opacity:1;background-color:#1a202c;background-color:rgba(26,32,44,var(--bg-opacity))}.sm\:focus\:bg-red-100:focus{--bg-opacity:1;background-color:#fff5f5;background-color:rgba(255,245,245,var(--bg-opacity))}.sm\:focus\:bg-red-200:focus{--bg-opacity:1;background-color:#fed7d7;background-color:rgba(254,215,215,var(--bg-opacity))}.sm\:focus\:bg-red-300:focus{--bg-opacity:1;background-color:#feb2b2;background-color:rgba(254,178,178,var(--bg-opacity))}.sm\:focus\:bg-red-400:focus{--bg-opacity:1;background-color:#fc8181;background-color:rgba(252,129,129,var(--bg-opacity))}.sm\:focus\:bg-red-500:focus{--bg-opacity:1;background-color:#f56565;background-color:rgba(245,101,101,var(--bg-opacity))}.sm\:focus\:bg-red-600:focus{--bg-opacity:1;background-color:#e53e3e;background-color:rgba(229,62,62,var(--bg-opacity))}.sm\:focus\:bg-red-700:focus{--bg-opacity:1;background-color:#c53030;background-color:rgba(197,48,48,var(--bg-opacity))}.sm\:focus\:bg-red-800:focus{--bg-opacity:1;background-color:#9b2c2c;background-color:rgba(155,44,44,var(--bg-opacity))}.sm\:focus\:bg-red-900:focus{--bg-opacity:1;background-color:#742a2a;background-color:rgba(116,42,42,var(--bg-opacity))}.sm\:focus\:bg-orange-100:focus{--bg-opacity:1;background-color:#fffaf0;background-color:rgba(255,250,240,var(--bg-opacity))}.sm\:focus\:bg-orange-200:focus{--bg-opacity:1;background-color:#feebc8;background-color:rgba(254,235,200,var(--bg-opacity))}.sm\:focus\:bg-orange-300:focus{--bg-opacity:1;background-color:#fbd38d;background-color:rgba(251,211,141,var(--bg-opacity))}.sm\:focus\:bg-orange-400:focus{--bg-opacity:1;background-color:#f6ad55;background-color:rgba(246,173,85,var(--bg-opacity))}.sm\:focus\:bg-orange-500:focus{--bg-opacity:1;background-color:#ed8936;background-color:rgba(237,137,54,var(--bg-opacity))}.sm\:focus\:bg-orange-600:focus{--bg-opacity:1;background-color:#dd6b20;background-color:rgba(221,107,32,var(--bg-opacity))}.sm\:focus\:bg-orange-700:focus{--bg-opacity:1;background-color:#c05621;background-color:rgba(192,86,33,var(--bg-opacity))}.sm\:focus\:bg-orange-800:focus{--bg-opacity:1;background-color:#9c4221;background-color:rgba(156,66,33,var(--bg-opacity))}.sm\:focus\:bg-orange-900:focus{--bg-opacity:1;background-color:#7b341e;background-color:rgba(123,52,30,var(--bg-opacity))}.sm\:focus\:bg-yellow-100:focus{--bg-opacity:1;background-color:ivory;background-color:rgba(255,255,240,var(--bg-opacity))}.sm\:focus\:bg-yellow-200:focus{--bg-opacity:1;background-color:#fefcbf;background-color:rgba(254,252,191,var(--bg-opacity))}.sm\:focus\:bg-yellow-300:focus{--bg-opacity:1;background-color:#faf089;background-color:rgba(250,240,137,var(--bg-opacity))}.sm\:focus\:bg-yellow-400:focus{--bg-opacity:1;background-color:#f6e05e;background-color:rgba(246,224,94,var(--bg-opacity))}.sm\:focus\:bg-yellow-500:focus{--bg-opacity:1;background-color:#ecc94b;background-color:rgba(236,201,75,var(--bg-opacity))}.sm\:focus\:bg-yellow-600:focus{--bg-opacity:1;background-color:#d69e2e;background-color:rgba(214,158,46,var(--bg-opacity))}.sm\:focus\:bg-yellow-700:focus{--bg-opacity:1;background-color:#b7791f;background-color:rgba(183,121,31,var(--bg-opacity))}.sm\:focus\:bg-yellow-800:focus{--bg-opacity:1;background-color:#975a16;background-color:rgba(151,90,22,var(--bg-opacity))}.sm\:focus\:bg-yellow-900:focus{--bg-opacity:1;background-color:#744210;background-color:rgba(116,66,16,var(--bg-opacity))}.sm\:focus\:bg-green-100:focus{--bg-opacity:1;background-color:#f0fff4;background-color:rgba(240,255,244,var(--bg-opacity))}.sm\:focus\:bg-green-200:focus{--bg-opacity:1;background-color:#c6f6d5;background-color:rgba(198,246,213,var(--bg-opacity))}.sm\:focus\:bg-green-300:focus{--bg-opacity:1;background-color:#9ae6b4;background-color:rgba(154,230,180,var(--bg-opacity))}.sm\:focus\:bg-green-400:focus{--bg-opacity:1;background-color:#68d391;background-color:rgba(104,211,145,var(--bg-opacity))}.sm\:focus\:bg-green-500:focus{--bg-opacity:1;background-color:#48bb78;background-color:rgba(72,187,120,var(--bg-opacity))}.sm\:focus\:bg-green-600:focus{--bg-opacity:1;background-color:#38a169;background-color:rgba(56,161,105,var(--bg-opacity))}.sm\:focus\:bg-green-700:focus{--bg-opacity:1;background-color:#2f855a;background-color:rgba(47,133,90,var(--bg-opacity))}.sm\:focus\:bg-green-800:focus{--bg-opacity:1;background-color:#276749;background-color:rgba(39,103,73,var(--bg-opacity))}.sm\:focus\:bg-green-900:focus{--bg-opacity:1;background-color:#22543d;background-color:rgba(34,84,61,var(--bg-opacity))}.sm\:focus\:bg-teal-100:focus{--bg-opacity:1;background-color:#e6fffa;background-color:rgba(230,255,250,var(--bg-opacity))}.sm\:focus\:bg-teal-200:focus{--bg-opacity:1;background-color:#b2f5ea;background-color:rgba(178,245,234,var(--bg-opacity))}.sm\:focus\:bg-teal-300:focus{--bg-opacity:1;background-color:#81e6d9;background-color:rgba(129,230,217,var(--bg-opacity))}.sm\:focus\:bg-teal-400:focus{--bg-opacity:1;background-color:#4fd1c5;background-color:rgba(79,209,197,var(--bg-opacity))}.sm\:focus\:bg-teal-500:focus{--bg-opacity:1;background-color:#38b2ac;background-color:rgba(56,178,172,var(--bg-opacity))}.sm\:focus\:bg-teal-600:focus{--bg-opacity:1;background-color:#319795;background-color:rgba(49,151,149,var(--bg-opacity))}.sm\:focus\:bg-teal-700:focus{--bg-opacity:1;background-color:#2c7a7b;background-color:rgba(44,122,123,var(--bg-opacity))}.sm\:focus\:bg-teal-800:focus{--bg-opacity:1;background-color:#285e61;background-color:rgba(40,94,97,var(--bg-opacity))}.sm\:focus\:bg-teal-900:focus{--bg-opacity:1;background-color:#234e52;background-color:rgba(35,78,82,var(--bg-opacity))}.sm\:focus\:bg-blue-100:focus{--bg-opacity:1;background-color:#ebf8ff;background-color:rgba(235,248,255,var(--bg-opacity))}.sm\:focus\:bg-blue-200:focus{--bg-opacity:1;background-color:#bee3f8;background-color:rgba(190,227,248,var(--bg-opacity))}.sm\:focus\:bg-blue-300:focus{--bg-opacity:1;background-color:#90cdf4;background-color:rgba(144,205,244,var(--bg-opacity))}.sm\:focus\:bg-blue-400:focus{--bg-opacity:1;background-color:#63b3ed;background-color:rgba(99,179,237,var(--bg-opacity))}.sm\:focus\:bg-blue-500:focus{--bg-opacity:1;background-color:#4299e1;background-color:rgba(66,153,225,var(--bg-opacity))}.sm\:focus\:bg-blue-600:focus{--bg-opacity:1;background-color:#3182ce;background-color:rgba(49,130,206,var(--bg-opacity))}.sm\:focus\:bg-blue-700:focus{--bg-opacity:1;background-color:#2b6cb0;background-color:rgba(43,108,176,var(--bg-opacity))}.sm\:focus\:bg-blue-800:focus{--bg-opacity:1;background-color:#2c5282;background-color:rgba(44,82,130,var(--bg-opacity))}.sm\:focus\:bg-blue-900:focus{--bg-opacity:1;background-color:#2a4365;background-color:rgba(42,67,101,var(--bg-opacity))}.sm\:focus\:bg-indigo-100:focus{--bg-opacity:1;background-color:#ebf4ff;background-color:rgba(235,244,255,var(--bg-opacity))}.sm\:focus\:bg-indigo-200:focus{--bg-opacity:1;background-color:#c3dafe;background-color:rgba(195,218,254,var(--bg-opacity))}.sm\:focus\:bg-indigo-300:focus{--bg-opacity:1;background-color:#a3bffa;background-color:rgba(163,191,250,var(--bg-opacity))}.sm\:focus\:bg-indigo-400:focus{--bg-opacity:1;background-color:#7f9cf5;background-color:rgba(127,156,245,var(--bg-opacity))}.sm\:focus\:bg-indigo-500:focus{--bg-opacity:1;background-color:#667eea;background-color:rgba(102,126,234,var(--bg-opacity))}.sm\:focus\:bg-indigo-600:focus{--bg-opacity:1;background-color:#5a67d8;background-color:rgba(90,103,216,var(--bg-opacity))}.sm\:focus\:bg-indigo-700:focus{--bg-opacity:1;background-color:#4c51bf;background-color:rgba(76,81,191,var(--bg-opacity))}.sm\:focus\:bg-indigo-800:focus{--bg-opacity:1;background-color:#434190;background-color:rgba(67,65,144,var(--bg-opacity))}.sm\:focus\:bg-indigo-900:focus{--bg-opacity:1;background-color:#3c366b;background-color:rgba(60,54,107,var(--bg-opacity))}.sm\:focus\:bg-purple-100:focus{--bg-opacity:1;background-color:#faf5ff;background-color:rgba(250,245,255,var(--bg-opacity))}.sm\:focus\:bg-purple-200:focus{--bg-opacity:1;background-color:#e9d8fd;background-color:rgba(233,216,253,var(--bg-opacity))}.sm\:focus\:bg-purple-300:focus{--bg-opacity:1;background-color:#d6bcfa;background-color:rgba(214,188,250,var(--bg-opacity))}.sm\:focus\:bg-purple-400:focus{--bg-opacity:1;background-color:#b794f4;background-color:rgba(183,148,244,var(--bg-opacity))}.sm\:focus\:bg-purple-500:focus{--bg-opacity:1;background-color:#9f7aea;background-color:rgba(159,122,234,var(--bg-opacity))}.sm\:focus\:bg-purple-600:focus{--bg-opacity:1;background-color:#805ad5;background-color:rgba(128,90,213,var(--bg-opacity))}.sm\:focus\:bg-purple-700:focus{--bg-opacity:1;background-color:#6b46c1;background-color:rgba(107,70,193,var(--bg-opacity))}.sm\:focus\:bg-purple-800:focus{--bg-opacity:1;background-color:#553c9a;background-color:rgba(85,60,154,var(--bg-opacity))}.sm\:focus\:bg-purple-900:focus{--bg-opacity:1;background-color:#44337a;background-color:rgba(68,51,122,var(--bg-opacity))}.sm\:focus\:bg-pink-100:focus{--bg-opacity:1;background-color:#fff5f7;background-color:rgba(255,245,247,var(--bg-opacity))}.sm\:focus\:bg-pink-200:focus{--bg-opacity:1;background-color:#fed7e2;background-color:rgba(254,215,226,var(--bg-opacity))}.sm\:focus\:bg-pink-300:focus{--bg-opacity:1;background-color:#fbb6ce;background-color:rgba(251,182,206,var(--bg-opacity))}.sm\:focus\:bg-pink-400:focus{--bg-opacity:1;background-color:#f687b3;background-color:rgba(246,135,179,var(--bg-opacity))}.sm\:focus\:bg-pink-500:focus{--bg-opacity:1;background-color:#ed64a6;background-color:rgba(237,100,166,var(--bg-opacity))}.sm\:focus\:bg-pink-600:focus{--bg-opacity:1;background-color:#d53f8c;background-color:rgba(213,63,140,var(--bg-opacity))}.sm\:focus\:bg-pink-700:focus{--bg-opacity:1;background-color:#b83280;background-color:rgba(184,50,128,var(--bg-opacity))}.sm\:focus\:bg-pink-800:focus{--bg-opacity:1;background-color:#97266d;background-color:rgba(151,38,109,var(--bg-opacity))}.sm\:focus\:bg-pink-900:focus{--bg-opacity:1;background-color:#702459;background-color:rgba(112,36,89,var(--bg-opacity))}.sm\:bg-none{background-image:none}.sm\:bg-gradient-to-t{background-image:linear-gradient(to top,var(--gradient-color-stops))}.sm\:bg-gradient-to-tr{background-image:linear-gradient(to top right,var(--gradient-color-stops))}.sm\:bg-gradient-to-r{background-image:linear-gradient(to right,var(--gradient-color-stops))}.sm\:bg-gradient-to-br{background-image:linear-gradient(to bottom right,var(--gradient-color-stops))}.sm\:bg-gradient-to-b{background-image:linear-gradient(to bottom,var(--gradient-color-stops))}.sm\:bg-gradient-to-bl{background-image:linear-gradient(to bottom left,var(--gradient-color-stops))}.sm\:bg-gradient-to-l{background-image:linear-gradient(to left,var(--gradient-color-stops))}.sm\:bg-gradient-to-tl{background-image:linear-gradient(to top left,var(--gradient-color-stops))}.sm\:from-transparent{--gradient-from-color:transparent;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(0, 0, 0, 0))}.sm\:from-current{--gradient-from-color:currentColor;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 255, 255, 0))}.sm\:from-black{--gradient-from-color:#000;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(0, 0, 0, 0))}.sm\:from-white{--gradient-from-color:#fff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 255, 255, 0))}.sm\:from-gray-100{--gradient-from-color:#f7fafc;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(247, 250, 252, 0))}.sm\:from-gray-200{--gradient-from-color:#edf2f7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(237, 242, 247, 0))}.sm\:from-gray-300{--gradient-from-color:#e2e8f0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(226, 232, 240, 0))}.sm\:from-gray-400{--gradient-from-color:#cbd5e0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(203, 213, 224, 0))}.sm\:from-gray-500{--gradient-from-color:#a0aec0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(160, 174, 192, 0))}.sm\:from-gray-600{--gradient-from-color:#718096;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(113, 128, 150, 0))}.sm\:from-gray-700{--gradient-from-color:#4a5568;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(74, 85, 104, 0))}.sm\:from-gray-800{--gradient-from-color:#2d3748;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(45, 55, 72, 0))}.sm\:from-gray-900{--gradient-from-color:#1a202c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(26, 32, 44, 0))}.sm\:from-red-100{--gradient-from-color:#fff5f5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 245, 245, 0))}.sm\:from-red-200{--gradient-from-color:#fed7d7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(254, 215, 215, 0))}.sm\:from-red-300{--gradient-from-color:#feb2b2;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(254, 178, 178, 0))}.sm\:from-red-400{--gradient-from-color:#fc8181;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(252, 129, 129, 0))}.sm\:from-red-500{--gradient-from-color:#f56565;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(245, 101, 101, 0))}.sm\:from-red-600{--gradient-from-color:#e53e3e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(229, 62, 62, 0))}.sm\:from-red-700{--gradient-from-color:#c53030;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(197, 48, 48, 0))}.sm\:from-red-800{--gradient-from-color:#9b2c2c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(155, 44, 44, 0))}.sm\:from-red-900{--gradient-from-color:#742a2a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(116, 42, 42, 0))}.sm\:from-orange-100{--gradient-from-color:#fffaf0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 250, 240, 0))}.sm\:from-orange-200{--gradient-from-color:#feebc8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(254, 235, 200, 0))}.sm\:from-orange-300{--gradient-from-color:#fbd38d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(251, 211, 141, 0))}.sm\:from-orange-400{--gradient-from-color:#f6ad55;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(246, 173, 85, 0))}.sm\:from-orange-500{--gradient-from-color:#ed8936;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(237, 137, 54, 0))}.sm\:from-orange-600{--gradient-from-color:#dd6b20;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(221, 107, 32, 0))}.sm\:from-orange-700{--gradient-from-color:#c05621;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(192, 86, 33, 0))}.sm\:from-orange-800{--gradient-from-color:#9c4221;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(156, 66, 33, 0))}.sm\:from-orange-900{--gradient-from-color:#7b341e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(123, 52, 30, 0))}.sm\:from-yellow-100{--gradient-from-color:#fffff0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 255, 240, 0))}.sm\:from-yellow-200{--gradient-from-color:#fefcbf;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(254, 252, 191, 0))}.sm\:from-yellow-300{--gradient-from-color:#faf089;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(250, 240, 137, 0))}.sm\:from-yellow-400{--gradient-from-color:#f6e05e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(246, 224, 94, 0))}.sm\:from-yellow-500{--gradient-from-color:#ecc94b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(236, 201, 75, 0))}.sm\:from-yellow-600{--gradient-from-color:#d69e2e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(214, 158, 46, 0))}.sm\:from-yellow-700{--gradient-from-color:#b7791f;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(183, 121, 31, 0))}.sm\:from-yellow-800{--gradient-from-color:#975a16;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(151, 90, 22, 0))}.sm\:from-yellow-900{--gradient-from-color:#744210;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(116, 66, 16, 0))}.sm\:from-green-100{--gradient-from-color:#f0fff4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(240, 255, 244, 0))}.sm\:from-green-200{--gradient-from-color:#c6f6d5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(198, 246, 213, 0))}.sm\:from-green-300{--gradient-from-color:#9ae6b4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(154, 230, 180, 0))}.sm\:from-green-400{--gradient-from-color:#68d391;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(104, 211, 145, 0))}.sm\:from-green-500{--gradient-from-color:#48bb78;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(72, 187, 120, 0))}.sm\:from-green-600{--gradient-from-color:#38a169;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(56, 161, 105, 0))}.sm\:from-green-700{--gradient-from-color:#2f855a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(47, 133, 90, 0))}.sm\:from-green-800{--gradient-from-color:#276749;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(39, 103, 73, 0))}.sm\:from-green-900{--gradient-from-color:#22543d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(34, 84, 61, 0))}.sm\:from-teal-100{--gradient-from-color:#e6fffa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(230, 255, 250, 0))}.sm\:from-teal-200{--gradient-from-color:#b2f5ea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(178, 245, 234, 0))}.sm\:from-teal-300{--gradient-from-color:#81e6d9;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(129, 230, 217, 0))}.sm\:from-teal-400{--gradient-from-color:#4fd1c5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(79, 209, 197, 0))}.sm\:from-teal-500{--gradient-from-color:#38b2ac;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(56, 178, 172, 0))}.sm\:from-teal-600{--gradient-from-color:#319795;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(49, 151, 149, 0))}.sm\:from-teal-700{--gradient-from-color:#2c7a7b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(44, 122, 123, 0))}.sm\:from-teal-800{--gradient-from-color:#285e61;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(40, 94, 97, 0))}.sm\:from-teal-900{--gradient-from-color:#234e52;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(35, 78, 82, 0))}.sm\:from-blue-100{--gradient-from-color:#ebf8ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(235, 248, 255, 0))}.sm\:from-blue-200{--gradient-from-color:#bee3f8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(190, 227, 248, 0))}.sm\:from-blue-300{--gradient-from-color:#90cdf4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(144, 205, 244, 0))}.sm\:from-blue-400{--gradient-from-color:#63b3ed;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(99, 179, 237, 0))}.sm\:from-blue-500{--gradient-from-color:#4299e1;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(66, 153, 225, 0))}.sm\:from-blue-600{--gradient-from-color:#3182ce;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(49, 130, 206, 0))}.sm\:from-blue-700{--gradient-from-color:#2b6cb0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(43, 108, 176, 0))}.sm\:from-blue-800{--gradient-from-color:#2c5282;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(44, 82, 130, 0))}.sm\:from-blue-900{--gradient-from-color:#2a4365;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(42, 67, 101, 0))}.sm\:from-indigo-100{--gradient-from-color:#ebf4ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(235, 244, 255, 0))}.sm\:from-indigo-200{--gradient-from-color:#c3dafe;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(195, 218, 254, 0))}.sm\:from-indigo-300{--gradient-from-color:#a3bffa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(163, 191, 250, 0))}.sm\:from-indigo-400{--gradient-from-color:#7f9cf5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(127, 156, 245, 0))}.sm\:from-indigo-500{--gradient-from-color:#667eea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(102, 126, 234, 0))}.sm\:from-indigo-600{--gradient-from-color:#5a67d8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(90, 103, 216, 0))}.sm\:from-indigo-700{--gradient-from-color:#4c51bf;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(76, 81, 191, 0))}.sm\:from-indigo-800{--gradient-from-color:#434190;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(67, 65, 144, 0))}.sm\:from-indigo-900{--gradient-from-color:#3c366b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(60, 54, 107, 0))}.sm\:from-purple-100{--gradient-from-color:#faf5ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(250, 245, 255, 0))}.sm\:from-purple-200{--gradient-from-color:#e9d8fd;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(233, 216, 253, 0))}.sm\:from-purple-300{--gradient-from-color:#d6bcfa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(214, 188, 250, 0))}.sm\:from-purple-400{--gradient-from-color:#b794f4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(183, 148, 244, 0))}.sm\:from-purple-500{--gradient-from-color:#9f7aea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(159, 122, 234, 0))}.sm\:from-purple-600{--gradient-from-color:#805ad5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(128, 90, 213, 0))}.sm\:from-purple-700{--gradient-from-color:#6b46c1;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(107, 70, 193, 0))}.sm\:from-purple-800{--gradient-from-color:#553c9a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(85, 60, 154, 0))}.sm\:from-purple-900{--gradient-from-color:#44337a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(68, 51, 122, 0))}.sm\:from-pink-100{--gradient-from-color:#fff5f7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 245, 247, 0))}.sm\:from-pink-200{--gradient-from-color:#fed7e2;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(254, 215, 226, 0))}.sm\:from-pink-300{--gradient-from-color:#fbb6ce;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(251, 182, 206, 0))}.sm\:from-pink-400{--gradient-from-color:#f687b3;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(246, 135, 179, 0))}.sm\:from-pink-500{--gradient-from-color:#ed64a6;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(237, 100, 166, 0))}.sm\:from-pink-600{--gradient-from-color:#d53f8c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(213, 63, 140, 0))}.sm\:from-pink-700{--gradient-from-color:#b83280;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(184, 50, 128, 0))}.sm\:from-pink-800{--gradient-from-color:#97266d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(151, 38, 109, 0))}.sm\:from-pink-900{--gradient-from-color:#702459;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(112, 36, 89, 0))}.sm\:via-transparent{--gradient-via-color:transparent;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(0, 0, 0, 0))}.sm\:via-current{--gradient-via-color:currentColor;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 255, 255, 0))}.sm\:via-black{--gradient-via-color:#000;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(0, 0, 0, 0))}.sm\:via-white{--gradient-via-color:#fff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 255, 255, 0))}.sm\:via-gray-100{--gradient-via-color:#f7fafc;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(247, 250, 252, 0))}.sm\:via-gray-200{--gradient-via-color:#edf2f7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(237, 242, 247, 0))}.sm\:via-gray-300{--gradient-via-color:#e2e8f0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(226, 232, 240, 0))}.sm\:via-gray-400{--gradient-via-color:#cbd5e0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(203, 213, 224, 0))}.sm\:via-gray-500{--gradient-via-color:#a0aec0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(160, 174, 192, 0))}.sm\:via-gray-600{--gradient-via-color:#718096;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(113, 128, 150, 0))}.sm\:via-gray-700{--gradient-via-color:#4a5568;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(74, 85, 104, 0))}.sm\:via-gray-800{--gradient-via-color:#2d3748;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(45, 55, 72, 0))}.sm\:via-gray-900{--gradient-via-color:#1a202c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(26, 32, 44, 0))}.sm\:via-red-100{--gradient-via-color:#fff5f5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 245, 245, 0))}.sm\:via-red-200{--gradient-via-color:#fed7d7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(254, 215, 215, 0))}.sm\:via-red-300{--gradient-via-color:#feb2b2;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(254, 178, 178, 0))}.sm\:via-red-400{--gradient-via-color:#fc8181;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(252, 129, 129, 0))}.sm\:via-red-500{--gradient-via-color:#f56565;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(245, 101, 101, 0))}.sm\:via-red-600{--gradient-via-color:#e53e3e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(229, 62, 62, 0))}.sm\:via-red-700{--gradient-via-color:#c53030;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(197, 48, 48, 0))}.sm\:via-red-800{--gradient-via-color:#9b2c2c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(155, 44, 44, 0))}.sm\:via-red-900{--gradient-via-color:#742a2a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(116, 42, 42, 0))}.sm\:via-orange-100{--gradient-via-color:#fffaf0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 250, 240, 0))}.sm\:via-orange-200{--gradient-via-color:#feebc8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(254, 235, 200, 0))}.sm\:via-orange-300{--gradient-via-color:#fbd38d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(251, 211, 141, 0))}.sm\:via-orange-400{--gradient-via-color:#f6ad55;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(246, 173, 85, 0))}.sm\:via-orange-500{--gradient-via-color:#ed8936;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(237, 137, 54, 0))}.sm\:via-orange-600{--gradient-via-color:#dd6b20;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(221, 107, 32, 0))}.sm\:via-orange-700{--gradient-via-color:#c05621;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(192, 86, 33, 0))}.sm\:via-orange-800{--gradient-via-color:#9c4221;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(156, 66, 33, 0))}.sm\:via-orange-900{--gradient-via-color:#7b341e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(123, 52, 30, 0))}.sm\:via-yellow-100{--gradient-via-color:#fffff0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 255, 240, 0))}.sm\:via-yellow-200{--gradient-via-color:#fefcbf;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(254, 252, 191, 0))}.sm\:via-yellow-300{--gradient-via-color:#faf089;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(250, 240, 137, 0))}.sm\:via-yellow-400{--gradient-via-color:#f6e05e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(246, 224, 94, 0))}.sm\:via-yellow-500{--gradient-via-color:#ecc94b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(236, 201, 75, 0))}.sm\:via-yellow-600{--gradient-via-color:#d69e2e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(214, 158, 46, 0))}.sm\:via-yellow-700{--gradient-via-color:#b7791f;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(183, 121, 31, 0))}.sm\:via-yellow-800{--gradient-via-color:#975a16;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(151, 90, 22, 0))}.sm\:via-yellow-900{--gradient-via-color:#744210;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(116, 66, 16, 0))}.sm\:via-green-100{--gradient-via-color:#f0fff4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(240, 255, 244, 0))}.sm\:via-green-200{--gradient-via-color:#c6f6d5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(198, 246, 213, 0))}.sm\:via-green-300{--gradient-via-color:#9ae6b4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(154, 230, 180, 0))}.sm\:via-green-400{--gradient-via-color:#68d391;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(104, 211, 145, 0))}.sm\:via-green-500{--gradient-via-color:#48bb78;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(72, 187, 120, 0))}.sm\:via-green-600{--gradient-via-color:#38a169;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(56, 161, 105, 0))}.sm\:via-green-700{--gradient-via-color:#2f855a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(47, 133, 90, 0))}.sm\:via-green-800{--gradient-via-color:#276749;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(39, 103, 73, 0))}.sm\:via-green-900{--gradient-via-color:#22543d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(34, 84, 61, 0))}.sm\:via-teal-100{--gradient-via-color:#e6fffa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(230, 255, 250, 0))}.sm\:via-teal-200{--gradient-via-color:#b2f5ea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(178, 245, 234, 0))}.sm\:via-teal-300{--gradient-via-color:#81e6d9;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(129, 230, 217, 0))}.sm\:via-teal-400{--gradient-via-color:#4fd1c5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(79, 209, 197, 0))}.sm\:via-teal-500{--gradient-via-color:#38b2ac;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(56, 178, 172, 0))}.sm\:via-teal-600{--gradient-via-color:#319795;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(49, 151, 149, 0))}.sm\:via-teal-700{--gradient-via-color:#2c7a7b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(44, 122, 123, 0))}.sm\:via-teal-800{--gradient-via-color:#285e61;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(40, 94, 97, 0))}.sm\:via-teal-900{--gradient-via-color:#234e52;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(35, 78, 82, 0))}.sm\:via-blue-100{--gradient-via-color:#ebf8ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(235, 248, 255, 0))}.sm\:via-blue-200{--gradient-via-color:#bee3f8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(190, 227, 248, 0))}.sm\:via-blue-300{--gradient-via-color:#90cdf4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(144, 205, 244, 0))}.sm\:via-blue-400{--gradient-via-color:#63b3ed;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(99, 179, 237, 0))}.sm\:via-blue-500{--gradient-via-color:#4299e1;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(66, 153, 225, 0))}.sm\:via-blue-600{--gradient-via-color:#3182ce;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(49, 130, 206, 0))}.sm\:via-blue-700{--gradient-via-color:#2b6cb0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(43, 108, 176, 0))}.sm\:via-blue-800{--gradient-via-color:#2c5282;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(44, 82, 130, 0))}.sm\:via-blue-900{--gradient-via-color:#2a4365;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(42, 67, 101, 0))}.sm\:via-indigo-100{--gradient-via-color:#ebf4ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(235, 244, 255, 0))}.sm\:via-indigo-200{--gradient-via-color:#c3dafe;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(195, 218, 254, 0))}.sm\:via-indigo-300{--gradient-via-color:#a3bffa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(163, 191, 250, 0))}.sm\:via-indigo-400{--gradient-via-color:#7f9cf5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(127, 156, 245, 0))}.sm\:via-indigo-500{--gradient-via-color:#667eea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(102, 126, 234, 0))}.sm\:via-indigo-600{--gradient-via-color:#5a67d8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(90, 103, 216, 0))}.sm\:via-indigo-700{--gradient-via-color:#4c51bf;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(76, 81, 191, 0))}.sm\:via-indigo-800{--gradient-via-color:#434190;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(67, 65, 144, 0))}.sm\:via-indigo-900{--gradient-via-color:#3c366b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(60, 54, 107, 0))}.sm\:via-purple-100{--gradient-via-color:#faf5ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(250, 245, 255, 0))}.sm\:via-purple-200{--gradient-via-color:#e9d8fd;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(233, 216, 253, 0))}.sm\:via-purple-300{--gradient-via-color:#d6bcfa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(214, 188, 250, 0))}.sm\:via-purple-400{--gradient-via-color:#b794f4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(183, 148, 244, 0))}.sm\:via-purple-500{--gradient-via-color:#9f7aea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(159, 122, 234, 0))}.sm\:via-purple-600{--gradient-via-color:#805ad5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(128, 90, 213, 0))}.sm\:via-purple-700{--gradient-via-color:#6b46c1;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(107, 70, 193, 0))}.sm\:via-purple-800{--gradient-via-color:#553c9a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(85, 60, 154, 0))}.sm\:via-purple-900{--gradient-via-color:#44337a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(68, 51, 122, 0))}.sm\:via-pink-100{--gradient-via-color:#fff5f7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 245, 247, 0))}.sm\:via-pink-200{--gradient-via-color:#fed7e2;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(254, 215, 226, 0))}.sm\:via-pink-300{--gradient-via-color:#fbb6ce;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(251, 182, 206, 0))}.sm\:via-pink-400{--gradient-via-color:#f687b3;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(246, 135, 179, 0))}.sm\:via-pink-500{--gradient-via-color:#ed64a6;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(237, 100, 166, 0))}.sm\:via-pink-600{--gradient-via-color:#d53f8c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(213, 63, 140, 0))}.sm\:via-pink-700{--gradient-via-color:#b83280;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(184, 50, 128, 0))}.sm\:via-pink-800{--gradient-via-color:#97266d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(151, 38, 109, 0))}.sm\:via-pink-900{--gradient-via-color:#702459;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(112, 36, 89, 0))}.sm\:to-transparent{--gradient-to-color:transparent}.sm\:to-current{--gradient-to-color:currentColor}.sm\:to-black{--gradient-to-color:#000}.sm\:to-white{--gradient-to-color:#fff}.sm\:to-gray-100{--gradient-to-color:#f7fafc}.sm\:to-gray-200{--gradient-to-color:#edf2f7}.sm\:to-gray-300{--gradient-to-color:#e2e8f0}.sm\:to-gray-400{--gradient-to-color:#cbd5e0}.sm\:to-gray-500{--gradient-to-color:#a0aec0}.sm\:to-gray-600{--gradient-to-color:#718096}.sm\:to-gray-700{--gradient-to-color:#4a5568}.sm\:to-gray-800{--gradient-to-color:#2d3748}.sm\:to-gray-900{--gradient-to-color:#1a202c}.sm\:to-red-100{--gradient-to-color:#fff5f5}.sm\:to-red-200{--gradient-to-color:#fed7d7}.sm\:to-red-300{--gradient-to-color:#feb2b2}.sm\:to-red-400{--gradient-to-color:#fc8181}.sm\:to-red-500{--gradient-to-color:#f56565}.sm\:to-red-600{--gradient-to-color:#e53e3e}.sm\:to-red-700{--gradient-to-color:#c53030}.sm\:to-red-800{--gradient-to-color:#9b2c2c}.sm\:to-red-900{--gradient-to-color:#742a2a}.sm\:to-orange-100{--gradient-to-color:#fffaf0}.sm\:to-orange-200{--gradient-to-color:#feebc8}.sm\:to-orange-300{--gradient-to-color:#fbd38d}.sm\:to-orange-400{--gradient-to-color:#f6ad55}.sm\:to-orange-500{--gradient-to-color:#ed8936}.sm\:to-orange-600{--gradient-to-color:#dd6b20}.sm\:to-orange-700{--gradient-to-color:#c05621}.sm\:to-orange-800{--gradient-to-color:#9c4221}.sm\:to-orange-900{--gradient-to-color:#7b341e}.sm\:to-yellow-100{--gradient-to-color:#fffff0}.sm\:to-yellow-200{--gradient-to-color:#fefcbf}.sm\:to-yellow-300{--gradient-to-color:#faf089}.sm\:to-yellow-400{--gradient-to-color:#f6e05e}.sm\:to-yellow-500{--gradient-to-color:#ecc94b}.sm\:to-yellow-600{--gradient-to-color:#d69e2e}.sm\:to-yellow-700{--gradient-to-color:#b7791f}.sm\:to-yellow-800{--gradient-to-color:#975a16}.sm\:to-yellow-900{--gradient-to-color:#744210}.sm\:to-green-100{--gradient-to-color:#f0fff4}.sm\:to-green-200{--gradient-to-color:#c6f6d5}.sm\:to-green-300{--gradient-to-color:#9ae6b4}.sm\:to-green-400{--gradient-to-color:#68d391}.sm\:to-green-500{--gradient-to-color:#48bb78}.sm\:to-green-600{--gradient-to-color:#38a169}.sm\:to-green-700{--gradient-to-color:#2f855a}.sm\:to-green-800{--gradient-to-color:#276749}.sm\:to-green-900{--gradient-to-color:#22543d}.sm\:to-teal-100{--gradient-to-color:#e6fffa}.sm\:to-teal-200{--gradient-to-color:#b2f5ea}.sm\:to-teal-300{--gradient-to-color:#81e6d9}.sm\:to-teal-400{--gradient-to-color:#4fd1c5}.sm\:to-teal-500{--gradient-to-color:#38b2ac}.sm\:to-teal-600{--gradient-to-color:#319795}.sm\:to-teal-700{--gradient-to-color:#2c7a7b}.sm\:to-teal-800{--gradient-to-color:#285e61}.sm\:to-teal-900{--gradient-to-color:#234e52}.sm\:to-blue-100{--gradient-to-color:#ebf8ff}.sm\:to-blue-200{--gradient-to-color:#bee3f8}.sm\:to-blue-300{--gradient-to-color:#90cdf4}.sm\:to-blue-400{--gradient-to-color:#63b3ed}.sm\:to-blue-500{--gradient-to-color:#4299e1}.sm\:to-blue-600{--gradient-to-color:#3182ce}.sm\:to-blue-700{--gradient-to-color:#2b6cb0}.sm\:to-blue-800{--gradient-to-color:#2c5282}.sm\:to-blue-900{--gradient-to-color:#2a4365}.sm\:to-indigo-100{--gradient-to-color:#ebf4ff}.sm\:to-indigo-200{--gradient-to-color:#c3dafe}.sm\:to-indigo-300{--gradient-to-color:#a3bffa}.sm\:to-indigo-400{--gradient-to-color:#7f9cf5}.sm\:to-indigo-500{--gradient-to-color:#667eea}.sm\:to-indigo-600{--gradient-to-color:#5a67d8}.sm\:to-indigo-700{--gradient-to-color:#4c51bf}.sm\:to-indigo-800{--gradient-to-color:#434190}.sm\:to-indigo-900{--gradient-to-color:#3c366b}.sm\:to-purple-100{--gradient-to-color:#faf5ff}.sm\:to-purple-200{--gradient-to-color:#e9d8fd}.sm\:to-purple-300{--gradient-to-color:#d6bcfa}.sm\:to-purple-400{--gradient-to-color:#b794f4}.sm\:to-purple-500{--gradient-to-color:#9f7aea}.sm\:to-purple-600{--gradient-to-color:#805ad5}.sm\:to-purple-700{--gradient-to-color:#6b46c1}.sm\:to-purple-800{--gradient-to-color:#553c9a}.sm\:to-purple-900{--gradient-to-color:#44337a}.sm\:to-pink-100{--gradient-to-color:#fff5f7}.sm\:to-pink-200{--gradient-to-color:#fed7e2}.sm\:to-pink-300{--gradient-to-color:#fbb6ce}.sm\:to-pink-400{--gradient-to-color:#f687b3}.sm\:to-pink-500{--gradient-to-color:#ed64a6}.sm\:to-pink-600{--gradient-to-color:#d53f8c}.sm\:to-pink-700{--gradient-to-color:#b83280}.sm\:to-pink-800{--gradient-to-color:#97266d}.sm\:to-pink-900{--gradient-to-color:#702459}.sm\:hover\:from-transparent:hover{--gradient-from-color:transparent;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(0, 0, 0, 0))}.sm\:hover\:from-current:hover{--gradient-from-color:currentColor;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 255, 255, 0))}.sm\:hover\:from-black:hover{--gradient-from-color:#000;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(0, 0, 0, 0))}.sm\:hover\:from-white:hover{--gradient-from-color:#fff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 255, 255, 0))}.sm\:hover\:from-gray-100:hover{--gradient-from-color:#f7fafc;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(247, 250, 252, 0))}.sm\:hover\:from-gray-200:hover{--gradient-from-color:#edf2f7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(237, 242, 247, 0))}.sm\:hover\:from-gray-300:hover{--gradient-from-color:#e2e8f0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(226, 232, 240, 0))}.sm\:hover\:from-gray-400:hover{--gradient-from-color:#cbd5e0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(203, 213, 224, 0))}.sm\:hover\:from-gray-500:hover{--gradient-from-color:#a0aec0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(160, 174, 192, 0))}.sm\:hover\:from-gray-600:hover{--gradient-from-color:#718096;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(113, 128, 150, 0))}.sm\:hover\:from-gray-700:hover{--gradient-from-color:#4a5568;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(74, 85, 104, 0))}.sm\:hover\:from-gray-800:hover{--gradient-from-color:#2d3748;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(45, 55, 72, 0))}.sm\:hover\:from-gray-900:hover{--gradient-from-color:#1a202c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(26, 32, 44, 0))}.sm\:hover\:from-red-100:hover{--gradient-from-color:#fff5f5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 245, 245, 0))}.sm\:hover\:from-red-200:hover{--gradient-from-color:#fed7d7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(254, 215, 215, 0))}.sm\:hover\:from-red-300:hover{--gradient-from-color:#feb2b2;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(254, 178, 178, 0))}.sm\:hover\:from-red-400:hover{--gradient-from-color:#fc8181;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(252, 129, 129, 0))}.sm\:hover\:from-red-500:hover{--gradient-from-color:#f56565;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(245, 101, 101, 0))}.sm\:hover\:from-red-600:hover{--gradient-from-color:#e53e3e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(229, 62, 62, 0))}.sm\:hover\:from-red-700:hover{--gradient-from-color:#c53030;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(197, 48, 48, 0))}.sm\:hover\:from-red-800:hover{--gradient-from-color:#9b2c2c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(155, 44, 44, 0))}.sm\:hover\:from-red-900:hover{--gradient-from-color:#742a2a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(116, 42, 42, 0))}.sm\:hover\:from-orange-100:hover{--gradient-from-color:#fffaf0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 250, 240, 0))}.sm\:hover\:from-orange-200:hover{--gradient-from-color:#feebc8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(254, 235, 200, 0))}.sm\:hover\:from-orange-300:hover{--gradient-from-color:#fbd38d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(251, 211, 141, 0))}.sm\:hover\:from-orange-400:hover{--gradient-from-color:#f6ad55;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(246, 173, 85, 0))}.sm\:hover\:from-orange-500:hover{--gradient-from-color:#ed8936;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(237, 137, 54, 0))}.sm\:hover\:from-orange-600:hover{--gradient-from-color:#dd6b20;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(221, 107, 32, 0))}.sm\:hover\:from-orange-700:hover{--gradient-from-color:#c05621;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(192, 86, 33, 0))}.sm\:hover\:from-orange-800:hover{--gradient-from-color:#9c4221;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(156, 66, 33, 0))}.sm\:hover\:from-orange-900:hover{--gradient-from-color:#7b341e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(123, 52, 30, 0))}.sm\:hover\:from-yellow-100:hover{--gradient-from-color:#fffff0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 255, 240, 0))}.sm\:hover\:from-yellow-200:hover{--gradient-from-color:#fefcbf;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(254, 252, 191, 0))}.sm\:hover\:from-yellow-300:hover{--gradient-from-color:#faf089;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(250, 240, 137, 0))}.sm\:hover\:from-yellow-400:hover{--gradient-from-color:#f6e05e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(246, 224, 94, 0))}.sm\:hover\:from-yellow-500:hover{--gradient-from-color:#ecc94b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(236, 201, 75, 0))}.sm\:hover\:from-yellow-600:hover{--gradient-from-color:#d69e2e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(214, 158, 46, 0))}.sm\:hover\:from-yellow-700:hover{--gradient-from-color:#b7791f;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(183, 121, 31, 0))}.sm\:hover\:from-yellow-800:hover{--gradient-from-color:#975a16;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(151, 90, 22, 0))}.sm\:hover\:from-yellow-900:hover{--gradient-from-color:#744210;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(116, 66, 16, 0))}.sm\:hover\:from-green-100:hover{--gradient-from-color:#f0fff4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(240, 255, 244, 0))}.sm\:hover\:from-green-200:hover{--gradient-from-color:#c6f6d5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(198, 246, 213, 0))}.sm\:hover\:from-green-300:hover{--gradient-from-color:#9ae6b4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(154, 230, 180, 0))}.sm\:hover\:from-green-400:hover{--gradient-from-color:#68d391;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(104, 211, 145, 0))}.sm\:hover\:from-green-500:hover{--gradient-from-color:#48bb78;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(72, 187, 120, 0))}.sm\:hover\:from-green-600:hover{--gradient-from-color:#38a169;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(56, 161, 105, 0))}.sm\:hover\:from-green-700:hover{--gradient-from-color:#2f855a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(47, 133, 90, 0))}.sm\:hover\:from-green-800:hover{--gradient-from-color:#276749;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(39, 103, 73, 0))}.sm\:hover\:from-green-900:hover{--gradient-from-color:#22543d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(34, 84, 61, 0))}.sm\:hover\:from-teal-100:hover{--gradient-from-color:#e6fffa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(230, 255, 250, 0))}.sm\:hover\:from-teal-200:hover{--gradient-from-color:#b2f5ea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(178, 245, 234, 0))}.sm\:hover\:from-teal-300:hover{--gradient-from-color:#81e6d9;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(129, 230, 217, 0))}.sm\:hover\:from-teal-400:hover{--gradient-from-color:#4fd1c5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(79, 209, 197, 0))}.sm\:hover\:from-teal-500:hover{--gradient-from-color:#38b2ac;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(56, 178, 172, 0))}.sm\:hover\:from-teal-600:hover{--gradient-from-color:#319795;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(49, 151, 149, 0))}.sm\:hover\:from-teal-700:hover{--gradient-from-color:#2c7a7b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(44, 122, 123, 0))}.sm\:hover\:from-teal-800:hover{--gradient-from-color:#285e61;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(40, 94, 97, 0))}.sm\:hover\:from-teal-900:hover{--gradient-from-color:#234e52;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(35, 78, 82, 0))}.sm\:hover\:from-blue-100:hover{--gradient-from-color:#ebf8ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(235, 248, 255, 0))}.sm\:hover\:from-blue-200:hover{--gradient-from-color:#bee3f8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(190, 227, 248, 0))}.sm\:hover\:from-blue-300:hover{--gradient-from-color:#90cdf4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(144, 205, 244, 0))}.sm\:hover\:from-blue-400:hover{--gradient-from-color:#63b3ed;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(99, 179, 237, 0))}.sm\:hover\:from-blue-500:hover{--gradient-from-color:#4299e1;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(66, 153, 225, 0))}.sm\:hover\:from-blue-600:hover{--gradient-from-color:#3182ce;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(49, 130, 206, 0))}.sm\:hover\:from-blue-700:hover{--gradient-from-color:#2b6cb0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(43, 108, 176, 0))}.sm\:hover\:from-blue-800:hover{--gradient-from-color:#2c5282;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(44, 82, 130, 0))}.sm\:hover\:from-blue-900:hover{--gradient-from-color:#2a4365;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(42, 67, 101, 0))}.sm\:hover\:from-indigo-100:hover{--gradient-from-color:#ebf4ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(235, 244, 255, 0))}.sm\:hover\:from-indigo-200:hover{--gradient-from-color:#c3dafe;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(195, 218, 254, 0))}.sm\:hover\:from-indigo-300:hover{--gradient-from-color:#a3bffa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(163, 191, 250, 0))}.sm\:hover\:from-indigo-400:hover{--gradient-from-color:#7f9cf5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(127, 156, 245, 0))}.sm\:hover\:from-indigo-500:hover{--gradient-from-color:#667eea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(102, 126, 234, 0))}.sm\:hover\:from-indigo-600:hover{--gradient-from-color:#5a67d8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(90, 103, 216, 0))}.sm\:hover\:from-indigo-700:hover{--gradient-from-color:#4c51bf;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(76, 81, 191, 0))}.sm\:hover\:from-indigo-800:hover{--gradient-from-color:#434190;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(67, 65, 144, 0))}.sm\:hover\:from-indigo-900:hover{--gradient-from-color:#3c366b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(60, 54, 107, 0))}.sm\:hover\:from-purple-100:hover{--gradient-from-color:#faf5ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(250, 245, 255, 0))}.sm\:hover\:from-purple-200:hover{--gradient-from-color:#e9d8fd;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(233, 216, 253, 0))}.sm\:hover\:from-purple-300:hover{--gradient-from-color:#d6bcfa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(214, 188, 250, 0))}.sm\:hover\:from-purple-400:hover{--gradient-from-color:#b794f4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(183, 148, 244, 0))}.sm\:hover\:from-purple-500:hover{--gradient-from-color:#9f7aea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(159, 122, 234, 0))}.sm\:hover\:from-purple-600:hover{--gradient-from-color:#805ad5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(128, 90, 213, 0))}.sm\:hover\:from-purple-700:hover{--gradient-from-color:#6b46c1;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(107, 70, 193, 0))}.sm\:hover\:from-purple-800:hover{--gradient-from-color:#553c9a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(85, 60, 154, 0))}.sm\:hover\:from-purple-900:hover{--gradient-from-color:#44337a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(68, 51, 122, 0))}.sm\:hover\:from-pink-100:hover{--gradient-from-color:#fff5f7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 245, 247, 0))}.sm\:hover\:from-pink-200:hover{--gradient-from-color:#fed7e2;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(254, 215, 226, 0))}.sm\:hover\:from-pink-300:hover{--gradient-from-color:#fbb6ce;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(251, 182, 206, 0))}.sm\:hover\:from-pink-400:hover{--gradient-from-color:#f687b3;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(246, 135, 179, 0))}.sm\:hover\:from-pink-500:hover{--gradient-from-color:#ed64a6;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(237, 100, 166, 0))}.sm\:hover\:from-pink-600:hover{--gradient-from-color:#d53f8c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(213, 63, 140, 0))}.sm\:hover\:from-pink-700:hover{--gradient-from-color:#b83280;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(184, 50, 128, 0))}.sm\:hover\:from-pink-800:hover{--gradient-from-color:#97266d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(151, 38, 109, 0))}.sm\:hover\:from-pink-900:hover{--gradient-from-color:#702459;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(112, 36, 89, 0))}.sm\:hover\:via-transparent:hover{--gradient-via-color:transparent;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(0, 0, 0, 0))}.sm\:hover\:via-current:hover{--gradient-via-color:currentColor;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 255, 255, 0))}.sm\:hover\:via-black:hover{--gradient-via-color:#000;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(0, 0, 0, 0))}.sm\:hover\:via-white:hover{--gradient-via-color:#fff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 255, 255, 0))}.sm\:hover\:via-gray-100:hover{--gradient-via-color:#f7fafc;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(247, 250, 252, 0))}.sm\:hover\:via-gray-200:hover{--gradient-via-color:#edf2f7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(237, 242, 247, 0))}.sm\:hover\:via-gray-300:hover{--gradient-via-color:#e2e8f0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(226, 232, 240, 0))}.sm\:hover\:via-gray-400:hover{--gradient-via-color:#cbd5e0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(203, 213, 224, 0))}.sm\:hover\:via-gray-500:hover{--gradient-via-color:#a0aec0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(160, 174, 192, 0))}.sm\:hover\:via-gray-600:hover{--gradient-via-color:#718096;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(113, 128, 150, 0))}.sm\:hover\:via-gray-700:hover{--gradient-via-color:#4a5568;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(74, 85, 104, 0))}.sm\:hover\:via-gray-800:hover{--gradient-via-color:#2d3748;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(45, 55, 72, 0))}.sm\:hover\:via-gray-900:hover{--gradient-via-color:#1a202c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(26, 32, 44, 0))}.sm\:hover\:via-red-100:hover{--gradient-via-color:#fff5f5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 245, 245, 0))}.sm\:hover\:via-red-200:hover{--gradient-via-color:#fed7d7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(254, 215, 215, 0))}.sm\:hover\:via-red-300:hover{--gradient-via-color:#feb2b2;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(254, 178, 178, 0))}.sm\:hover\:via-red-400:hover{--gradient-via-color:#fc8181;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(252, 129, 129, 0))}.sm\:hover\:via-red-500:hover{--gradient-via-color:#f56565;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(245, 101, 101, 0))}.sm\:hover\:via-red-600:hover{--gradient-via-color:#e53e3e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(229, 62, 62, 0))}.sm\:hover\:via-red-700:hover{--gradient-via-color:#c53030;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(197, 48, 48, 0))}.sm\:hover\:via-red-800:hover{--gradient-via-color:#9b2c2c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(155, 44, 44, 0))}.sm\:hover\:via-red-900:hover{--gradient-via-color:#742a2a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(116, 42, 42, 0))}.sm\:hover\:via-orange-100:hover{--gradient-via-color:#fffaf0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 250, 240, 0))}.sm\:hover\:via-orange-200:hover{--gradient-via-color:#feebc8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(254, 235, 200, 0))}.sm\:hover\:via-orange-300:hover{--gradient-via-color:#fbd38d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(251, 211, 141, 0))}.sm\:hover\:via-orange-400:hover{--gradient-via-color:#f6ad55;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(246, 173, 85, 0))}.sm\:hover\:via-orange-500:hover{--gradient-via-color:#ed8936;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(237, 137, 54, 0))}.sm\:hover\:via-orange-600:hover{--gradient-via-color:#dd6b20;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(221, 107, 32, 0))}.sm\:hover\:via-orange-700:hover{--gradient-via-color:#c05621;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(192, 86, 33, 0))}.sm\:hover\:via-orange-800:hover{--gradient-via-color:#9c4221;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(156, 66, 33, 0))}.sm\:hover\:via-orange-900:hover{--gradient-via-color:#7b341e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(123, 52, 30, 0))}.sm\:hover\:via-yellow-100:hover{--gradient-via-color:#fffff0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 255, 240, 0))}.sm\:hover\:via-yellow-200:hover{--gradient-via-color:#fefcbf;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(254, 252, 191, 0))}.sm\:hover\:via-yellow-300:hover{--gradient-via-color:#faf089;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(250, 240, 137, 0))}.sm\:hover\:via-yellow-400:hover{--gradient-via-color:#f6e05e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(246, 224, 94, 0))}.sm\:hover\:via-yellow-500:hover{--gradient-via-color:#ecc94b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(236, 201, 75, 0))}.sm\:hover\:via-yellow-600:hover{--gradient-via-color:#d69e2e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(214, 158, 46, 0))}.sm\:hover\:via-yellow-700:hover{--gradient-via-color:#b7791f;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(183, 121, 31, 0))}.sm\:hover\:via-yellow-800:hover{--gradient-via-color:#975a16;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(151, 90, 22, 0))}.sm\:hover\:via-yellow-900:hover{--gradient-via-color:#744210;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(116, 66, 16, 0))}.sm\:hover\:via-green-100:hover{--gradient-via-color:#f0fff4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(240, 255, 244, 0))}.sm\:hover\:via-green-200:hover{--gradient-via-color:#c6f6d5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(198, 246, 213, 0))}.sm\:hover\:via-green-300:hover{--gradient-via-color:#9ae6b4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(154, 230, 180, 0))}.sm\:hover\:via-green-400:hover{--gradient-via-color:#68d391;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(104, 211, 145, 0))}.sm\:hover\:via-green-500:hover{--gradient-via-color:#48bb78;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(72, 187, 120, 0))}.sm\:hover\:via-green-600:hover{--gradient-via-color:#38a169;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(56, 161, 105, 0))}.sm\:hover\:via-green-700:hover{--gradient-via-color:#2f855a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(47, 133, 90, 0))}.sm\:hover\:via-green-800:hover{--gradient-via-color:#276749;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(39, 103, 73, 0))}.sm\:hover\:via-green-900:hover{--gradient-via-color:#22543d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(34, 84, 61, 0))}.sm\:hover\:via-teal-100:hover{--gradient-via-color:#e6fffa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(230, 255, 250, 0))}.sm\:hover\:via-teal-200:hover{--gradient-via-color:#b2f5ea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(178, 245, 234, 0))}.sm\:hover\:via-teal-300:hover{--gradient-via-color:#81e6d9;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(129, 230, 217, 0))}.sm\:hover\:via-teal-400:hover{--gradient-via-color:#4fd1c5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(79, 209, 197, 0))}.sm\:hover\:via-teal-500:hover{--gradient-via-color:#38b2ac;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(56, 178, 172, 0))}.sm\:hover\:via-teal-600:hover{--gradient-via-color:#319795;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(49, 151, 149, 0))}.sm\:hover\:via-teal-700:hover{--gradient-via-color:#2c7a7b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(44, 122, 123, 0))}.sm\:hover\:via-teal-800:hover{--gradient-via-color:#285e61;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(40, 94, 97, 0))}.sm\:hover\:via-teal-900:hover{--gradient-via-color:#234e52;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(35, 78, 82, 0))}.sm\:hover\:via-blue-100:hover{--gradient-via-color:#ebf8ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(235, 248, 255, 0))}.sm\:hover\:via-blue-200:hover{--gradient-via-color:#bee3f8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(190, 227, 248, 0))}.sm\:hover\:via-blue-300:hover{--gradient-via-color:#90cdf4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(144, 205, 244, 0))}.sm\:hover\:via-blue-400:hover{--gradient-via-color:#63b3ed;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(99, 179, 237, 0))}.sm\:hover\:via-blue-500:hover{--gradient-via-color:#4299e1;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(66, 153, 225, 0))}.sm\:hover\:via-blue-600:hover{--gradient-via-color:#3182ce;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(49, 130, 206, 0))}.sm\:hover\:via-blue-700:hover{--gradient-via-color:#2b6cb0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(43, 108, 176, 0))}.sm\:hover\:via-blue-800:hover{--gradient-via-color:#2c5282;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(44, 82, 130, 0))}.sm\:hover\:via-blue-900:hover{--gradient-via-color:#2a4365;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(42, 67, 101, 0))}.sm\:hover\:via-indigo-100:hover{--gradient-via-color:#ebf4ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(235, 244, 255, 0))}.sm\:hover\:via-indigo-200:hover{--gradient-via-color:#c3dafe;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(195, 218, 254, 0))}.sm\:hover\:via-indigo-300:hover{--gradient-via-color:#a3bffa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(163, 191, 250, 0))}.sm\:hover\:via-indigo-400:hover{--gradient-via-color:#7f9cf5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(127, 156, 245, 0))}.sm\:hover\:via-indigo-500:hover{--gradient-via-color:#667eea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(102, 126, 234, 0))}.sm\:hover\:via-indigo-600:hover{--gradient-via-color:#5a67d8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(90, 103, 216, 0))}.sm\:hover\:via-indigo-700:hover{--gradient-via-color:#4c51bf;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(76, 81, 191, 0))}.sm\:hover\:via-indigo-800:hover{--gradient-via-color:#434190;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(67, 65, 144, 0))}.sm\:hover\:via-indigo-900:hover{--gradient-via-color:#3c366b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(60, 54, 107, 0))}.sm\:hover\:via-purple-100:hover{--gradient-via-color:#faf5ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(250, 245, 255, 0))}.sm\:hover\:via-purple-200:hover{--gradient-via-color:#e9d8fd;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(233, 216, 253, 0))}.sm\:hover\:via-purple-300:hover{--gradient-via-color:#d6bcfa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(214, 188, 250, 0))}.sm\:hover\:via-purple-400:hover{--gradient-via-color:#b794f4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(183, 148, 244, 0))}.sm\:hover\:via-purple-500:hover{--gradient-via-color:#9f7aea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(159, 122, 234, 0))}.sm\:hover\:via-purple-600:hover{--gradient-via-color:#805ad5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(128, 90, 213, 0))}.sm\:hover\:via-purple-700:hover{--gradient-via-color:#6b46c1;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(107, 70, 193, 0))}.sm\:hover\:via-purple-800:hover{--gradient-via-color:#553c9a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(85, 60, 154, 0))}.sm\:hover\:via-purple-900:hover{--gradient-via-color:#44337a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(68, 51, 122, 0))}.sm\:hover\:via-pink-100:hover{--gradient-via-color:#fff5f7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 245, 247, 0))}.sm\:hover\:via-pink-200:hover{--gradient-via-color:#fed7e2;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(254, 215, 226, 0))}.sm\:hover\:via-pink-300:hover{--gradient-via-color:#fbb6ce;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(251, 182, 206, 0))}.sm\:hover\:via-pink-400:hover{--gradient-via-color:#f687b3;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(246, 135, 179, 0))}.sm\:hover\:via-pink-500:hover{--gradient-via-color:#ed64a6;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(237, 100, 166, 0))}.sm\:hover\:via-pink-600:hover{--gradient-via-color:#d53f8c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(213, 63, 140, 0))}.sm\:hover\:via-pink-700:hover{--gradient-via-color:#b83280;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(184, 50, 128, 0))}.sm\:hover\:via-pink-800:hover{--gradient-via-color:#97266d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(151, 38, 109, 0))}.sm\:hover\:via-pink-900:hover{--gradient-via-color:#702459;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(112, 36, 89, 0))}.sm\:hover\:to-transparent:hover{--gradient-to-color:transparent}.sm\:hover\:to-current:hover{--gradient-to-color:currentColor}.sm\:hover\:to-black:hover{--gradient-to-color:#000}.sm\:hover\:to-white:hover{--gradient-to-color:#fff}.sm\:hover\:to-gray-100:hover{--gradient-to-color:#f7fafc}.sm\:hover\:to-gray-200:hover{--gradient-to-color:#edf2f7}.sm\:hover\:to-gray-300:hover{--gradient-to-color:#e2e8f0}.sm\:hover\:to-gray-400:hover{--gradient-to-color:#cbd5e0}.sm\:hover\:to-gray-500:hover{--gradient-to-color:#a0aec0}.sm\:hover\:to-gray-600:hover{--gradient-to-color:#718096}.sm\:hover\:to-gray-700:hover{--gradient-to-color:#4a5568}.sm\:hover\:to-gray-800:hover{--gradient-to-color:#2d3748}.sm\:hover\:to-gray-900:hover{--gradient-to-color:#1a202c}.sm\:hover\:to-red-100:hover{--gradient-to-color:#fff5f5}.sm\:hover\:to-red-200:hover{--gradient-to-color:#fed7d7}.sm\:hover\:to-red-300:hover{--gradient-to-color:#feb2b2}.sm\:hover\:to-red-400:hover{--gradient-to-color:#fc8181}.sm\:hover\:to-red-500:hover{--gradient-to-color:#f56565}.sm\:hover\:to-red-600:hover{--gradient-to-color:#e53e3e}.sm\:hover\:to-red-700:hover{--gradient-to-color:#c53030}.sm\:hover\:to-red-800:hover{--gradient-to-color:#9b2c2c}.sm\:hover\:to-red-900:hover{--gradient-to-color:#742a2a}.sm\:hover\:to-orange-100:hover{--gradient-to-color:#fffaf0}.sm\:hover\:to-orange-200:hover{--gradient-to-color:#feebc8}.sm\:hover\:to-orange-300:hover{--gradient-to-color:#fbd38d}.sm\:hover\:to-orange-400:hover{--gradient-to-color:#f6ad55}.sm\:hover\:to-orange-500:hover{--gradient-to-color:#ed8936}.sm\:hover\:to-orange-600:hover{--gradient-to-color:#dd6b20}.sm\:hover\:to-orange-700:hover{--gradient-to-color:#c05621}.sm\:hover\:to-orange-800:hover{--gradient-to-color:#9c4221}.sm\:hover\:to-orange-900:hover{--gradient-to-color:#7b341e}.sm\:hover\:to-yellow-100:hover{--gradient-to-color:#fffff0}.sm\:hover\:to-yellow-200:hover{--gradient-to-color:#fefcbf}.sm\:hover\:to-yellow-300:hover{--gradient-to-color:#faf089}.sm\:hover\:to-yellow-400:hover{--gradient-to-color:#f6e05e}.sm\:hover\:to-yellow-500:hover{--gradient-to-color:#ecc94b}.sm\:hover\:to-yellow-600:hover{--gradient-to-color:#d69e2e}.sm\:hover\:to-yellow-700:hover{--gradient-to-color:#b7791f}.sm\:hover\:to-yellow-800:hover{--gradient-to-color:#975a16}.sm\:hover\:to-yellow-900:hover{--gradient-to-color:#744210}.sm\:hover\:to-green-100:hover{--gradient-to-color:#f0fff4}.sm\:hover\:to-green-200:hover{--gradient-to-color:#c6f6d5}.sm\:hover\:to-green-300:hover{--gradient-to-color:#9ae6b4}.sm\:hover\:to-green-400:hover{--gradient-to-color:#68d391}.sm\:hover\:to-green-500:hover{--gradient-to-color:#48bb78}.sm\:hover\:to-green-600:hover{--gradient-to-color:#38a169}.sm\:hover\:to-green-700:hover{--gradient-to-color:#2f855a}.sm\:hover\:to-green-800:hover{--gradient-to-color:#276749}.sm\:hover\:to-green-900:hover{--gradient-to-color:#22543d}.sm\:hover\:to-teal-100:hover{--gradient-to-color:#e6fffa}.sm\:hover\:to-teal-200:hover{--gradient-to-color:#b2f5ea}.sm\:hover\:to-teal-300:hover{--gradient-to-color:#81e6d9}.sm\:hover\:to-teal-400:hover{--gradient-to-color:#4fd1c5}.sm\:hover\:to-teal-500:hover{--gradient-to-color:#38b2ac}.sm\:hover\:to-teal-600:hover{--gradient-to-color:#319795}.sm\:hover\:to-teal-700:hover{--gradient-to-color:#2c7a7b}.sm\:hover\:to-teal-800:hover{--gradient-to-color:#285e61}.sm\:hover\:to-teal-900:hover{--gradient-to-color:#234e52}.sm\:hover\:to-blue-100:hover{--gradient-to-color:#ebf8ff}.sm\:hover\:to-blue-200:hover{--gradient-to-color:#bee3f8}.sm\:hover\:to-blue-300:hover{--gradient-to-color:#90cdf4}.sm\:hover\:to-blue-400:hover{--gradient-to-color:#63b3ed}.sm\:hover\:to-blue-500:hover{--gradient-to-color:#4299e1}.sm\:hover\:to-blue-600:hover{--gradient-to-color:#3182ce}.sm\:hover\:to-blue-700:hover{--gradient-to-color:#2b6cb0}.sm\:hover\:to-blue-800:hover{--gradient-to-color:#2c5282}.sm\:hover\:to-blue-900:hover{--gradient-to-color:#2a4365}.sm\:hover\:to-indigo-100:hover{--gradient-to-color:#ebf4ff}.sm\:hover\:to-indigo-200:hover{--gradient-to-color:#c3dafe}.sm\:hover\:to-indigo-300:hover{--gradient-to-color:#a3bffa}.sm\:hover\:to-indigo-400:hover{--gradient-to-color:#7f9cf5}.sm\:hover\:to-indigo-500:hover{--gradient-to-color:#667eea}.sm\:hover\:to-indigo-600:hover{--gradient-to-color:#5a67d8}.sm\:hover\:to-indigo-700:hover{--gradient-to-color:#4c51bf}.sm\:hover\:to-indigo-800:hover{--gradient-to-color:#434190}.sm\:hover\:to-indigo-900:hover{--gradient-to-color:#3c366b}.sm\:hover\:to-purple-100:hover{--gradient-to-color:#faf5ff}.sm\:hover\:to-purple-200:hover{--gradient-to-color:#e9d8fd}.sm\:hover\:to-purple-300:hover{--gradient-to-color:#d6bcfa}.sm\:hover\:to-purple-400:hover{--gradient-to-color:#b794f4}.sm\:hover\:to-purple-500:hover{--gradient-to-color:#9f7aea}.sm\:hover\:to-purple-600:hover{--gradient-to-color:#805ad5}.sm\:hover\:to-purple-700:hover{--gradient-to-color:#6b46c1}.sm\:hover\:to-purple-800:hover{--gradient-to-color:#553c9a}.sm\:hover\:to-purple-900:hover{--gradient-to-color:#44337a}.sm\:hover\:to-pink-100:hover{--gradient-to-color:#fff5f7}.sm\:hover\:to-pink-200:hover{--gradient-to-color:#fed7e2}.sm\:hover\:to-pink-300:hover{--gradient-to-color:#fbb6ce}.sm\:hover\:to-pink-400:hover{--gradient-to-color:#f687b3}.sm\:hover\:to-pink-500:hover{--gradient-to-color:#ed64a6}.sm\:hover\:to-pink-600:hover{--gradient-to-color:#d53f8c}.sm\:hover\:to-pink-700:hover{--gradient-to-color:#b83280}.sm\:hover\:to-pink-800:hover{--gradient-to-color:#97266d}.sm\:hover\:to-pink-900:hover{--gradient-to-color:#702459}.sm\:focus\:from-transparent:focus{--gradient-from-color:transparent;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(0, 0, 0, 0))}.sm\:focus\:from-current:focus{--gradient-from-color:currentColor;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 255, 255, 0))}.sm\:focus\:from-black:focus{--gradient-from-color:#000;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(0, 0, 0, 0))}.sm\:focus\:from-white:focus{--gradient-from-color:#fff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 255, 255, 0))}.sm\:focus\:from-gray-100:focus{--gradient-from-color:#f7fafc;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(247, 250, 252, 0))}.sm\:focus\:from-gray-200:focus{--gradient-from-color:#edf2f7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(237, 242, 247, 0))}.sm\:focus\:from-gray-300:focus{--gradient-from-color:#e2e8f0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(226, 232, 240, 0))}.sm\:focus\:from-gray-400:focus{--gradient-from-color:#cbd5e0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(203, 213, 224, 0))}.sm\:focus\:from-gray-500:focus{--gradient-from-color:#a0aec0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(160, 174, 192, 0))}.sm\:focus\:from-gray-600:focus{--gradient-from-color:#718096;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(113, 128, 150, 0))}.sm\:focus\:from-gray-700:focus{--gradient-from-color:#4a5568;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(74, 85, 104, 0))}.sm\:focus\:from-gray-800:focus{--gradient-from-color:#2d3748;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(45, 55, 72, 0))}.sm\:focus\:from-gray-900:focus{--gradient-from-color:#1a202c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(26, 32, 44, 0))}.sm\:focus\:from-red-100:focus{--gradient-from-color:#fff5f5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 245, 245, 0))}.sm\:focus\:from-red-200:focus{--gradient-from-color:#fed7d7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(254, 215, 215, 0))}.sm\:focus\:from-red-300:focus{--gradient-from-color:#feb2b2;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(254, 178, 178, 0))}.sm\:focus\:from-red-400:focus{--gradient-from-color:#fc8181;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(252, 129, 129, 0))}.sm\:focus\:from-red-500:focus{--gradient-from-color:#f56565;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(245, 101, 101, 0))}.sm\:focus\:from-red-600:focus{--gradient-from-color:#e53e3e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(229, 62, 62, 0))}.sm\:focus\:from-red-700:focus{--gradient-from-color:#c53030;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(197, 48, 48, 0))}.sm\:focus\:from-red-800:focus{--gradient-from-color:#9b2c2c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(155, 44, 44, 0))}.sm\:focus\:from-red-900:focus{--gradient-from-color:#742a2a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(116, 42, 42, 0))}.sm\:focus\:from-orange-100:focus{--gradient-from-color:#fffaf0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 250, 240, 0))}.sm\:focus\:from-orange-200:focus{--gradient-from-color:#feebc8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(254, 235, 200, 0))}.sm\:focus\:from-orange-300:focus{--gradient-from-color:#fbd38d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(251, 211, 141, 0))}.sm\:focus\:from-orange-400:focus{--gradient-from-color:#f6ad55;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(246, 173, 85, 0))}.sm\:focus\:from-orange-500:focus{--gradient-from-color:#ed8936;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(237, 137, 54, 0))}.sm\:focus\:from-orange-600:focus{--gradient-from-color:#dd6b20;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(221, 107, 32, 0))}.sm\:focus\:from-orange-700:focus{--gradient-from-color:#c05621;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(192, 86, 33, 0))}.sm\:focus\:from-orange-800:focus{--gradient-from-color:#9c4221;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(156, 66, 33, 0))}.sm\:focus\:from-orange-900:focus{--gradient-from-color:#7b341e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(123, 52, 30, 0))}.sm\:focus\:from-yellow-100:focus{--gradient-from-color:#fffff0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 255, 240, 0))}.sm\:focus\:from-yellow-200:focus{--gradient-from-color:#fefcbf;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(254, 252, 191, 0))}.sm\:focus\:from-yellow-300:focus{--gradient-from-color:#faf089;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(250, 240, 137, 0))}.sm\:focus\:from-yellow-400:focus{--gradient-from-color:#f6e05e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(246, 224, 94, 0))}.sm\:focus\:from-yellow-500:focus{--gradient-from-color:#ecc94b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(236, 201, 75, 0))}.sm\:focus\:from-yellow-600:focus{--gradient-from-color:#d69e2e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(214, 158, 46, 0))}.sm\:focus\:from-yellow-700:focus{--gradient-from-color:#b7791f;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(183, 121, 31, 0))}.sm\:focus\:from-yellow-800:focus{--gradient-from-color:#975a16;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(151, 90, 22, 0))}.sm\:focus\:from-yellow-900:focus{--gradient-from-color:#744210;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(116, 66, 16, 0))}.sm\:focus\:from-green-100:focus{--gradient-from-color:#f0fff4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(240, 255, 244, 0))}.sm\:focus\:from-green-200:focus{--gradient-from-color:#c6f6d5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(198, 246, 213, 0))}.sm\:focus\:from-green-300:focus{--gradient-from-color:#9ae6b4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(154, 230, 180, 0))}.sm\:focus\:from-green-400:focus{--gradient-from-color:#68d391;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(104, 211, 145, 0))}.sm\:focus\:from-green-500:focus{--gradient-from-color:#48bb78;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(72, 187, 120, 0))}.sm\:focus\:from-green-600:focus{--gradient-from-color:#38a169;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(56, 161, 105, 0))}.sm\:focus\:from-green-700:focus{--gradient-from-color:#2f855a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(47, 133, 90, 0))}.sm\:focus\:from-green-800:focus{--gradient-from-color:#276749;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(39, 103, 73, 0))}.sm\:focus\:from-green-900:focus{--gradient-from-color:#22543d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(34, 84, 61, 0))}.sm\:focus\:from-teal-100:focus{--gradient-from-color:#e6fffa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(230, 255, 250, 0))}.sm\:focus\:from-teal-200:focus{--gradient-from-color:#b2f5ea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(178, 245, 234, 0))}.sm\:focus\:from-teal-300:focus{--gradient-from-color:#81e6d9;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(129, 230, 217, 0))}.sm\:focus\:from-teal-400:focus{--gradient-from-color:#4fd1c5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(79, 209, 197, 0))}.sm\:focus\:from-teal-500:focus{--gradient-from-color:#38b2ac;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(56, 178, 172, 0))}.sm\:focus\:from-teal-600:focus{--gradient-from-color:#319795;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(49, 151, 149, 0))}.sm\:focus\:from-teal-700:focus{--gradient-from-color:#2c7a7b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(44, 122, 123, 0))}.sm\:focus\:from-teal-800:focus{--gradient-from-color:#285e61;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(40, 94, 97, 0))}.sm\:focus\:from-teal-900:focus{--gradient-from-color:#234e52;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(35, 78, 82, 0))}.sm\:focus\:from-blue-100:focus{--gradient-from-color:#ebf8ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(235, 248, 255, 0))}.sm\:focus\:from-blue-200:focus{--gradient-from-color:#bee3f8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(190, 227, 248, 0))}.sm\:focus\:from-blue-300:focus{--gradient-from-color:#90cdf4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(144, 205, 244, 0))}.sm\:focus\:from-blue-400:focus{--gradient-from-color:#63b3ed;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(99, 179, 237, 0))}.sm\:focus\:from-blue-500:focus{--gradient-from-color:#4299e1;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(66, 153, 225, 0))}.sm\:focus\:from-blue-600:focus{--gradient-from-color:#3182ce;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(49, 130, 206, 0))}.sm\:focus\:from-blue-700:focus{--gradient-from-color:#2b6cb0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(43, 108, 176, 0))}.sm\:focus\:from-blue-800:focus{--gradient-from-color:#2c5282;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(44, 82, 130, 0))}.sm\:focus\:from-blue-900:focus{--gradient-from-color:#2a4365;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(42, 67, 101, 0))}.sm\:focus\:from-indigo-100:focus{--gradient-from-color:#ebf4ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(235, 244, 255, 0))}.sm\:focus\:from-indigo-200:focus{--gradient-from-color:#c3dafe;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(195, 218, 254, 0))}.sm\:focus\:from-indigo-300:focus{--gradient-from-color:#a3bffa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(163, 191, 250, 0))}.sm\:focus\:from-indigo-400:focus{--gradient-from-color:#7f9cf5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(127, 156, 245, 0))}.sm\:focus\:from-indigo-500:focus{--gradient-from-color:#667eea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(102, 126, 234, 0))}.sm\:focus\:from-indigo-600:focus{--gradient-from-color:#5a67d8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(90, 103, 216, 0))}.sm\:focus\:from-indigo-700:focus{--gradient-from-color:#4c51bf;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(76, 81, 191, 0))}.sm\:focus\:from-indigo-800:focus{--gradient-from-color:#434190;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(67, 65, 144, 0))}.sm\:focus\:from-indigo-900:focus{--gradient-from-color:#3c366b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(60, 54, 107, 0))}.sm\:focus\:from-purple-100:focus{--gradient-from-color:#faf5ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(250, 245, 255, 0))}.sm\:focus\:from-purple-200:focus{--gradient-from-color:#e9d8fd;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(233, 216, 253, 0))}.sm\:focus\:from-purple-300:focus{--gradient-from-color:#d6bcfa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(214, 188, 250, 0))}.sm\:focus\:from-purple-400:focus{--gradient-from-color:#b794f4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(183, 148, 244, 0))}.sm\:focus\:from-purple-500:focus{--gradient-from-color:#9f7aea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(159, 122, 234, 0))}.sm\:focus\:from-purple-600:focus{--gradient-from-color:#805ad5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(128, 90, 213, 0))}.sm\:focus\:from-purple-700:focus{--gradient-from-color:#6b46c1;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(107, 70, 193, 0))}.sm\:focus\:from-purple-800:focus{--gradient-from-color:#553c9a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(85, 60, 154, 0))}.sm\:focus\:from-purple-900:focus{--gradient-from-color:#44337a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(68, 51, 122, 0))}.sm\:focus\:from-pink-100:focus{--gradient-from-color:#fff5f7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 245, 247, 0))}.sm\:focus\:from-pink-200:focus{--gradient-from-color:#fed7e2;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(254, 215, 226, 0))}.sm\:focus\:from-pink-300:focus{--gradient-from-color:#fbb6ce;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(251, 182, 206, 0))}.sm\:focus\:from-pink-400:focus{--gradient-from-color:#f687b3;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(246, 135, 179, 0))}.sm\:focus\:from-pink-500:focus{--gradient-from-color:#ed64a6;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(237, 100, 166, 0))}.sm\:focus\:from-pink-600:focus{--gradient-from-color:#d53f8c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(213, 63, 140, 0))}.sm\:focus\:from-pink-700:focus{--gradient-from-color:#b83280;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(184, 50, 128, 0))}.sm\:focus\:from-pink-800:focus{--gradient-from-color:#97266d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(151, 38, 109, 0))}.sm\:focus\:from-pink-900:focus{--gradient-from-color:#702459;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(112, 36, 89, 0))}.sm\:focus\:via-transparent:focus{--gradient-via-color:transparent;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(0, 0, 0, 0))}.sm\:focus\:via-current:focus{--gradient-via-color:currentColor;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 255, 255, 0))}.sm\:focus\:via-black:focus{--gradient-via-color:#000;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(0, 0, 0, 0))}.sm\:focus\:via-white:focus{--gradient-via-color:#fff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 255, 255, 0))}.sm\:focus\:via-gray-100:focus{--gradient-via-color:#f7fafc;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(247, 250, 252, 0))}.sm\:focus\:via-gray-200:focus{--gradient-via-color:#edf2f7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(237, 242, 247, 0))}.sm\:focus\:via-gray-300:focus{--gradient-via-color:#e2e8f0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(226, 232, 240, 0))}.sm\:focus\:via-gray-400:focus{--gradient-via-color:#cbd5e0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(203, 213, 224, 0))}.sm\:focus\:via-gray-500:focus{--gradient-via-color:#a0aec0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(160, 174, 192, 0))}.sm\:focus\:via-gray-600:focus{--gradient-via-color:#718096;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(113, 128, 150, 0))}.sm\:focus\:via-gray-700:focus{--gradient-via-color:#4a5568;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(74, 85, 104, 0))}.sm\:focus\:via-gray-800:focus{--gradient-via-color:#2d3748;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(45, 55, 72, 0))}.sm\:focus\:via-gray-900:focus{--gradient-via-color:#1a202c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(26, 32, 44, 0))}.sm\:focus\:via-red-100:focus{--gradient-via-color:#fff5f5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 245, 245, 0))}.sm\:focus\:via-red-200:focus{--gradient-via-color:#fed7d7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(254, 215, 215, 0))}.sm\:focus\:via-red-300:focus{--gradient-via-color:#feb2b2;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(254, 178, 178, 0))}.sm\:focus\:via-red-400:focus{--gradient-via-color:#fc8181;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(252, 129, 129, 0))}.sm\:focus\:via-red-500:focus{--gradient-via-color:#f56565;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(245, 101, 101, 0))}.sm\:focus\:via-red-600:focus{--gradient-via-color:#e53e3e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(229, 62, 62, 0))}.sm\:focus\:via-red-700:focus{--gradient-via-color:#c53030;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(197, 48, 48, 0))}.sm\:focus\:via-red-800:focus{--gradient-via-color:#9b2c2c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(155, 44, 44, 0))}.sm\:focus\:via-red-900:focus{--gradient-via-color:#742a2a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(116, 42, 42, 0))}.sm\:focus\:via-orange-100:focus{--gradient-via-color:#fffaf0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 250, 240, 0))}.sm\:focus\:via-orange-200:focus{--gradient-via-color:#feebc8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(254, 235, 200, 0))}.sm\:focus\:via-orange-300:focus{--gradient-via-color:#fbd38d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(251, 211, 141, 0))}.sm\:focus\:via-orange-400:focus{--gradient-via-color:#f6ad55;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(246, 173, 85, 0))}.sm\:focus\:via-orange-500:focus{--gradient-via-color:#ed8936;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(237, 137, 54, 0))}.sm\:focus\:via-orange-600:focus{--gradient-via-color:#dd6b20;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(221, 107, 32, 0))}.sm\:focus\:via-orange-700:focus{--gradient-via-color:#c05621;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(192, 86, 33, 0))}.sm\:focus\:via-orange-800:focus{--gradient-via-color:#9c4221;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(156, 66, 33, 0))}.sm\:focus\:via-orange-900:focus{--gradient-via-color:#7b341e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(123, 52, 30, 0))}.sm\:focus\:via-yellow-100:focus{--gradient-via-color:#fffff0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 255, 240, 0))}.sm\:focus\:via-yellow-200:focus{--gradient-via-color:#fefcbf;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(254, 252, 191, 0))}.sm\:focus\:via-yellow-300:focus{--gradient-via-color:#faf089;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(250, 240, 137, 0))}.sm\:focus\:via-yellow-400:focus{--gradient-via-color:#f6e05e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(246, 224, 94, 0))}.sm\:focus\:via-yellow-500:focus{--gradient-via-color:#ecc94b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(236, 201, 75, 0))}.sm\:focus\:via-yellow-600:focus{--gradient-via-color:#d69e2e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(214, 158, 46, 0))}.sm\:focus\:via-yellow-700:focus{--gradient-via-color:#b7791f;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(183, 121, 31, 0))}.sm\:focus\:via-yellow-800:focus{--gradient-via-color:#975a16;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(151, 90, 22, 0))}.sm\:focus\:via-yellow-900:focus{--gradient-via-color:#744210;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(116, 66, 16, 0))}.sm\:focus\:via-green-100:focus{--gradient-via-color:#f0fff4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(240, 255, 244, 0))}.sm\:focus\:via-green-200:focus{--gradient-via-color:#c6f6d5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(198, 246, 213, 0))}.sm\:focus\:via-green-300:focus{--gradient-via-color:#9ae6b4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(154, 230, 180, 0))}.sm\:focus\:via-green-400:focus{--gradient-via-color:#68d391;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(104, 211, 145, 0))}.sm\:focus\:via-green-500:focus{--gradient-via-color:#48bb78;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(72, 187, 120, 0))}.sm\:focus\:via-green-600:focus{--gradient-via-color:#38a169;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(56, 161, 105, 0))}.sm\:focus\:via-green-700:focus{--gradient-via-color:#2f855a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(47, 133, 90, 0))}.sm\:focus\:via-green-800:focus{--gradient-via-color:#276749;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(39, 103, 73, 0))}.sm\:focus\:via-green-900:focus{--gradient-via-color:#22543d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(34, 84, 61, 0))}.sm\:focus\:via-teal-100:focus{--gradient-via-color:#e6fffa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(230, 255, 250, 0))}.sm\:focus\:via-teal-200:focus{--gradient-via-color:#b2f5ea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(178, 245, 234, 0))}.sm\:focus\:via-teal-300:focus{--gradient-via-color:#81e6d9;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(129, 230, 217, 0))}.sm\:focus\:via-teal-400:focus{--gradient-via-color:#4fd1c5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(79, 209, 197, 0))}.sm\:focus\:via-teal-500:focus{--gradient-via-color:#38b2ac;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(56, 178, 172, 0))}.sm\:focus\:via-teal-600:focus{--gradient-via-color:#319795;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(49, 151, 149, 0))}.sm\:focus\:via-teal-700:focus{--gradient-via-color:#2c7a7b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(44, 122, 123, 0))}.sm\:focus\:via-teal-800:focus{--gradient-via-color:#285e61;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(40, 94, 97, 0))}.sm\:focus\:via-teal-900:focus{--gradient-via-color:#234e52;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(35, 78, 82, 0))}.sm\:focus\:via-blue-100:focus{--gradient-via-color:#ebf8ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(235, 248, 255, 0))}.sm\:focus\:via-blue-200:focus{--gradient-via-color:#bee3f8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(190, 227, 248, 0))}.sm\:focus\:via-blue-300:focus{--gradient-via-color:#90cdf4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(144, 205, 244, 0))}.sm\:focus\:via-blue-400:focus{--gradient-via-color:#63b3ed;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(99, 179, 237, 0))}.sm\:focus\:via-blue-500:focus{--gradient-via-color:#4299e1;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(66, 153, 225, 0))}.sm\:focus\:via-blue-600:focus{--gradient-via-color:#3182ce;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(49, 130, 206, 0))}.sm\:focus\:via-blue-700:focus{--gradient-via-color:#2b6cb0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(43, 108, 176, 0))}.sm\:focus\:via-blue-800:focus{--gradient-via-color:#2c5282;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(44, 82, 130, 0))}.sm\:focus\:via-blue-900:focus{--gradient-via-color:#2a4365;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(42, 67, 101, 0))}.sm\:focus\:via-indigo-100:focus{--gradient-via-color:#ebf4ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(235, 244, 255, 0))}.sm\:focus\:via-indigo-200:focus{--gradient-via-color:#c3dafe;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(195, 218, 254, 0))}.sm\:focus\:via-indigo-300:focus{--gradient-via-color:#a3bffa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(163, 191, 250, 0))}.sm\:focus\:via-indigo-400:focus{--gradient-via-color:#7f9cf5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(127, 156, 245, 0))}.sm\:focus\:via-indigo-500:focus{--gradient-via-color:#667eea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(102, 126, 234, 0))}.sm\:focus\:via-indigo-600:focus{--gradient-via-color:#5a67d8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(90, 103, 216, 0))}.sm\:focus\:via-indigo-700:focus{--gradient-via-color:#4c51bf;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(76, 81, 191, 0))}.sm\:focus\:via-indigo-800:focus{--gradient-via-color:#434190;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(67, 65, 144, 0))}.sm\:focus\:via-indigo-900:focus{--gradient-via-color:#3c366b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(60, 54, 107, 0))}.sm\:focus\:via-purple-100:focus{--gradient-via-color:#faf5ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(250, 245, 255, 0))}.sm\:focus\:via-purple-200:focus{--gradient-via-color:#e9d8fd;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(233, 216, 253, 0))}.sm\:focus\:via-purple-300:focus{--gradient-via-color:#d6bcfa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(214, 188, 250, 0))}.sm\:focus\:via-purple-400:focus{--gradient-via-color:#b794f4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(183, 148, 244, 0))}.sm\:focus\:via-purple-500:focus{--gradient-via-color:#9f7aea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(159, 122, 234, 0))}.sm\:focus\:via-purple-600:focus{--gradient-via-color:#805ad5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(128, 90, 213, 0))}.sm\:focus\:via-purple-700:focus{--gradient-via-color:#6b46c1;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(107, 70, 193, 0))}.sm\:focus\:via-purple-800:focus{--gradient-via-color:#553c9a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(85, 60, 154, 0))}.sm\:focus\:via-purple-900:focus{--gradient-via-color:#44337a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(68, 51, 122, 0))}.sm\:focus\:via-pink-100:focus{--gradient-via-color:#fff5f7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 245, 247, 0))}.sm\:focus\:via-pink-200:focus{--gradient-via-color:#fed7e2;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(254, 215, 226, 0))}.sm\:focus\:via-pink-300:focus{--gradient-via-color:#fbb6ce;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(251, 182, 206, 0))}.sm\:focus\:via-pink-400:focus{--gradient-via-color:#f687b3;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(246, 135, 179, 0))}.sm\:focus\:via-pink-500:focus{--gradient-via-color:#ed64a6;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(237, 100, 166, 0))}.sm\:focus\:via-pink-600:focus{--gradient-via-color:#d53f8c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(213, 63, 140, 0))}.sm\:focus\:via-pink-700:focus{--gradient-via-color:#b83280;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(184, 50, 128, 0))}.sm\:focus\:via-pink-800:focus{--gradient-via-color:#97266d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(151, 38, 109, 0))}.sm\:focus\:via-pink-900:focus{--gradient-via-color:#702459;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(112, 36, 89, 0))}.sm\:focus\:to-transparent:focus{--gradient-to-color:transparent}.sm\:focus\:to-current:focus{--gradient-to-color:currentColor}.sm\:focus\:to-black:focus{--gradient-to-color:#000}.sm\:focus\:to-white:focus{--gradient-to-color:#fff}.sm\:focus\:to-gray-100:focus{--gradient-to-color:#f7fafc}.sm\:focus\:to-gray-200:focus{--gradient-to-color:#edf2f7}.sm\:focus\:to-gray-300:focus{--gradient-to-color:#e2e8f0}.sm\:focus\:to-gray-400:focus{--gradient-to-color:#cbd5e0}.sm\:focus\:to-gray-500:focus{--gradient-to-color:#a0aec0}.sm\:focus\:to-gray-600:focus{--gradient-to-color:#718096}.sm\:focus\:to-gray-700:focus{--gradient-to-color:#4a5568}.sm\:focus\:to-gray-800:focus{--gradient-to-color:#2d3748}.sm\:focus\:to-gray-900:focus{--gradient-to-color:#1a202c}.sm\:focus\:to-red-100:focus{--gradient-to-color:#fff5f5}.sm\:focus\:to-red-200:focus{--gradient-to-color:#fed7d7}.sm\:focus\:to-red-300:focus{--gradient-to-color:#feb2b2}.sm\:focus\:to-red-400:focus{--gradient-to-color:#fc8181}.sm\:focus\:to-red-500:focus{--gradient-to-color:#f56565}.sm\:focus\:to-red-600:focus{--gradient-to-color:#e53e3e}.sm\:focus\:to-red-700:focus{--gradient-to-color:#c53030}.sm\:focus\:to-red-800:focus{--gradient-to-color:#9b2c2c}.sm\:focus\:to-red-900:focus{--gradient-to-color:#742a2a}.sm\:focus\:to-orange-100:focus{--gradient-to-color:#fffaf0}.sm\:focus\:to-orange-200:focus{--gradient-to-color:#feebc8}.sm\:focus\:to-orange-300:focus{--gradient-to-color:#fbd38d}.sm\:focus\:to-orange-400:focus{--gradient-to-color:#f6ad55}.sm\:focus\:to-orange-500:focus{--gradient-to-color:#ed8936}.sm\:focus\:to-orange-600:focus{--gradient-to-color:#dd6b20}.sm\:focus\:to-orange-700:focus{--gradient-to-color:#c05621}.sm\:focus\:to-orange-800:focus{--gradient-to-color:#9c4221}.sm\:focus\:to-orange-900:focus{--gradient-to-color:#7b341e}.sm\:focus\:to-yellow-100:focus{--gradient-to-color:#fffff0}.sm\:focus\:to-yellow-200:focus{--gradient-to-color:#fefcbf}.sm\:focus\:to-yellow-300:focus{--gradient-to-color:#faf089}.sm\:focus\:to-yellow-400:focus{--gradient-to-color:#f6e05e}.sm\:focus\:to-yellow-500:focus{--gradient-to-color:#ecc94b}.sm\:focus\:to-yellow-600:focus{--gradient-to-color:#d69e2e}.sm\:focus\:to-yellow-700:focus{--gradient-to-color:#b7791f}.sm\:focus\:to-yellow-800:focus{--gradient-to-color:#975a16}.sm\:focus\:to-yellow-900:focus{--gradient-to-color:#744210}.sm\:focus\:to-green-100:focus{--gradient-to-color:#f0fff4}.sm\:focus\:to-green-200:focus{--gradient-to-color:#c6f6d5}.sm\:focus\:to-green-300:focus{--gradient-to-color:#9ae6b4}.sm\:focus\:to-green-400:focus{--gradient-to-color:#68d391}.sm\:focus\:to-green-500:focus{--gradient-to-color:#48bb78}.sm\:focus\:to-green-600:focus{--gradient-to-color:#38a169}.sm\:focus\:to-green-700:focus{--gradient-to-color:#2f855a}.sm\:focus\:to-green-800:focus{--gradient-to-color:#276749}.sm\:focus\:to-green-900:focus{--gradient-to-color:#22543d}.sm\:focus\:to-teal-100:focus{--gradient-to-color:#e6fffa}.sm\:focus\:to-teal-200:focus{--gradient-to-color:#b2f5ea}.sm\:focus\:to-teal-300:focus{--gradient-to-color:#81e6d9}.sm\:focus\:to-teal-400:focus{--gradient-to-color:#4fd1c5}.sm\:focus\:to-teal-500:focus{--gradient-to-color:#38b2ac}.sm\:focus\:to-teal-600:focus{--gradient-to-color:#319795}.sm\:focus\:to-teal-700:focus{--gradient-to-color:#2c7a7b}.sm\:focus\:to-teal-800:focus{--gradient-to-color:#285e61}.sm\:focus\:to-teal-900:focus{--gradient-to-color:#234e52}.sm\:focus\:to-blue-100:focus{--gradient-to-color:#ebf8ff}.sm\:focus\:to-blue-200:focus{--gradient-to-color:#bee3f8}.sm\:focus\:to-blue-300:focus{--gradient-to-color:#90cdf4}.sm\:focus\:to-blue-400:focus{--gradient-to-color:#63b3ed}.sm\:focus\:to-blue-500:focus{--gradient-to-color:#4299e1}.sm\:focus\:to-blue-600:focus{--gradient-to-color:#3182ce}.sm\:focus\:to-blue-700:focus{--gradient-to-color:#2b6cb0}.sm\:focus\:to-blue-800:focus{--gradient-to-color:#2c5282}.sm\:focus\:to-blue-900:focus{--gradient-to-color:#2a4365}.sm\:focus\:to-indigo-100:focus{--gradient-to-color:#ebf4ff}.sm\:focus\:to-indigo-200:focus{--gradient-to-color:#c3dafe}.sm\:focus\:to-indigo-300:focus{--gradient-to-color:#a3bffa}.sm\:focus\:to-indigo-400:focus{--gradient-to-color:#7f9cf5}.sm\:focus\:to-indigo-500:focus{--gradient-to-color:#667eea}.sm\:focus\:to-indigo-600:focus{--gradient-to-color:#5a67d8}.sm\:focus\:to-indigo-700:focus{--gradient-to-color:#4c51bf}.sm\:focus\:to-indigo-800:focus{--gradient-to-color:#434190}.sm\:focus\:to-indigo-900:focus{--gradient-to-color:#3c366b}.sm\:focus\:to-purple-100:focus{--gradient-to-color:#faf5ff}.sm\:focus\:to-purple-200:focus{--gradient-to-color:#e9d8fd}.sm\:focus\:to-purple-300:focus{--gradient-to-color:#d6bcfa}.sm\:focus\:to-purple-400:focus{--gradient-to-color:#b794f4}.sm\:focus\:to-purple-500:focus{--gradient-to-color:#9f7aea}.sm\:focus\:to-purple-600:focus{--gradient-to-color:#805ad5}.sm\:focus\:to-purple-700:focus{--gradient-to-color:#6b46c1}.sm\:focus\:to-purple-800:focus{--gradient-to-color:#553c9a}.sm\:focus\:to-purple-900:focus{--gradient-to-color:#44337a}.sm\:focus\:to-pink-100:focus{--gradient-to-color:#fff5f7}.sm\:focus\:to-pink-200:focus{--gradient-to-color:#fed7e2}.sm\:focus\:to-pink-300:focus{--gradient-to-color:#fbb6ce}.sm\:focus\:to-pink-400:focus{--gradient-to-color:#f687b3}.sm\:focus\:to-pink-500:focus{--gradient-to-color:#ed64a6}.sm\:focus\:to-pink-600:focus{--gradient-to-color:#d53f8c}.sm\:focus\:to-pink-700:focus{--gradient-to-color:#b83280}.sm\:focus\:to-pink-800:focus{--gradient-to-color:#97266d}.sm\:focus\:to-pink-900:focus{--gradient-to-color:#702459}.sm\:bg-opacity-0{--bg-opacity:0}.sm\:bg-opacity-25{--bg-opacity:0.25}.sm\:bg-opacity-50{--bg-opacity:0.5}.sm\:bg-opacity-75{--bg-opacity:0.75}.sm\:bg-opacity-100{--bg-opacity:1}.sm\:hover\:bg-opacity-0:hover{--bg-opacity:0}.sm\:hover\:bg-opacity-25:hover{--bg-opacity:0.25}.sm\:hover\:bg-opacity-50:hover{--bg-opacity:0.5}.sm\:hover\:bg-opacity-75:hover{--bg-opacity:0.75}.sm\:hover\:bg-opacity-100:hover{--bg-opacity:1}.sm\:focus\:bg-opacity-0:focus{--bg-opacity:0}.sm\:focus\:bg-opacity-25:focus{--bg-opacity:0.25}.sm\:focus\:bg-opacity-50:focus{--bg-opacity:0.5}.sm\:focus\:bg-opacity-75:focus{--bg-opacity:0.75}.sm\:focus\:bg-opacity-100:focus{--bg-opacity:1}.sm\:bg-bottom{background-position:bottom}.sm\:bg-center{background-position:center}.sm\:bg-left{background-position:left}.sm\:bg-left-bottom{background-position:left bottom}.sm\:bg-left-top{background-position:left top}.sm\:bg-right{background-position:right}.sm\:bg-right-bottom{background-position:right bottom}.sm\:bg-right-top{background-position:right top}.sm\:bg-top{background-position:top}.sm\:bg-repeat{background-repeat:repeat}.sm\:bg-no-repeat{background-repeat:no-repeat}.sm\:bg-repeat-x{background-repeat:repeat-x}.sm\:bg-repeat-y{background-repeat:repeat-y}.sm\:bg-repeat-round{background-repeat:round}.sm\:bg-repeat-space{background-repeat:space}.sm\:bg-auto{background-size:auto}.sm\:bg-cover{background-size:cover}.sm\:bg-contain{background-size:contain}.sm\:border-collapse{border-collapse:collapse}.sm\:border-separate{border-collapse:separate}.sm\:border-transparent{border-color:transparent}.sm\:border-current{border-color:currentColor}.sm\:border-black{--border-opacity:1;border-color:#000;border-color:rgba(0,0,0,var(--border-opacity))}.sm\:border-white{--border-opacity:1;border-color:#fff;border-color:rgba(255,255,255,var(--border-opacity))}.sm\:border-gray-100{--border-opacity:1;border-color:#f7fafc;border-color:rgba(247,250,252,var(--border-opacity))}.sm\:border-gray-200{--border-opacity:1;border-color:#edf2f7;border-color:rgba(237,242,247,var(--border-opacity))}.sm\:border-gray-300{--border-opacity:1;border-color:#e2e8f0;border-color:rgba(226,232,240,var(--border-opacity))}.sm\:border-gray-400{--border-opacity:1;border-color:#cbd5e0;border-color:rgba(203,213,224,var(--border-opacity))}.sm\:border-gray-500{--border-opacity:1;border-color:#a0aec0;border-color:rgba(160,174,192,var(--border-opacity))}.sm\:border-gray-600{--border-opacity:1;border-color:#718096;border-color:rgba(113,128,150,var(--border-opacity))}.sm\:border-gray-700{--border-opacity:1;border-color:#4a5568;border-color:rgba(74,85,104,var(--border-opacity))}.sm\:border-gray-800{--border-opacity:1;border-color:#2d3748;border-color:rgba(45,55,72,var(--border-opacity))}.sm\:border-gray-900{--border-opacity:1;border-color:#1a202c;border-color:rgba(26,32,44,var(--border-opacity))}.sm\:border-red-100{--border-opacity:1;border-color:#fff5f5;border-color:rgba(255,245,245,var(--border-opacity))}.sm\:border-red-200{--border-opacity:1;border-color:#fed7d7;border-color:rgba(254,215,215,var(--border-opacity))}.sm\:border-red-300{--border-opacity:1;border-color:#feb2b2;border-color:rgba(254,178,178,var(--border-opacity))}.sm\:border-red-400{--border-opacity:1;border-color:#fc8181;border-color:rgba(252,129,129,var(--border-opacity))}.sm\:border-red-500{--border-opacity:1;border-color:#f56565;border-color:rgba(245,101,101,var(--border-opacity))}.sm\:border-red-600{--border-opacity:1;border-color:#e53e3e;border-color:rgba(229,62,62,var(--border-opacity))}.sm\:border-red-700{--border-opacity:1;border-color:#c53030;border-color:rgba(197,48,48,var(--border-opacity))}.sm\:border-red-800{--border-opacity:1;border-color:#9b2c2c;border-color:rgba(155,44,44,var(--border-opacity))}.sm\:border-red-900{--border-opacity:1;border-color:#742a2a;border-color:rgba(116,42,42,var(--border-opacity))}.sm\:border-orange-100{--border-opacity:1;border-color:#fffaf0;border-color:rgba(255,250,240,var(--border-opacity))}.sm\:border-orange-200{--border-opacity:1;border-color:#feebc8;border-color:rgba(254,235,200,var(--border-opacity))}.sm\:border-orange-300{--border-opacity:1;border-color:#fbd38d;border-color:rgba(251,211,141,var(--border-opacity))}.sm\:border-orange-400{--border-opacity:1;border-color:#f6ad55;border-color:rgba(246,173,85,var(--border-opacity))}.sm\:border-orange-500{--border-opacity:1;border-color:#ed8936;border-color:rgba(237,137,54,var(--border-opacity))}.sm\:border-orange-600{--border-opacity:1;border-color:#dd6b20;border-color:rgba(221,107,32,var(--border-opacity))}.sm\:border-orange-700{--border-opacity:1;border-color:#c05621;border-color:rgba(192,86,33,var(--border-opacity))}.sm\:border-orange-800{--border-opacity:1;border-color:#9c4221;border-color:rgba(156,66,33,var(--border-opacity))}.sm\:border-orange-900{--border-opacity:1;border-color:#7b341e;border-color:rgba(123,52,30,var(--border-opacity))}.sm\:border-yellow-100{--border-opacity:1;border-color:ivory;border-color:rgba(255,255,240,var(--border-opacity))}.sm\:border-yellow-200{--border-opacity:1;border-color:#fefcbf;border-color:rgba(254,252,191,var(--border-opacity))}.sm\:border-yellow-300{--border-opacity:1;border-color:#faf089;border-color:rgba(250,240,137,var(--border-opacity))}.sm\:border-yellow-400{--border-opacity:1;border-color:#f6e05e;border-color:rgba(246,224,94,var(--border-opacity))}.sm\:border-yellow-500{--border-opacity:1;border-color:#ecc94b;border-color:rgba(236,201,75,var(--border-opacity))}.sm\:border-yellow-600{--border-opacity:1;border-color:#d69e2e;border-color:rgba(214,158,46,var(--border-opacity))}.sm\:border-yellow-700{--border-opacity:1;border-color:#b7791f;border-color:rgba(183,121,31,var(--border-opacity))}.sm\:border-yellow-800{--border-opacity:1;border-color:#975a16;border-color:rgba(151,90,22,var(--border-opacity))}.sm\:border-yellow-900{--border-opacity:1;border-color:#744210;border-color:rgba(116,66,16,var(--border-opacity))}.sm\:border-green-100{--border-opacity:1;border-color:#f0fff4;border-color:rgba(240,255,244,var(--border-opacity))}.sm\:border-green-200{--border-opacity:1;border-color:#c6f6d5;border-color:rgba(198,246,213,var(--border-opacity))}.sm\:border-green-300{--border-opacity:1;border-color:#9ae6b4;border-color:rgba(154,230,180,var(--border-opacity))}.sm\:border-green-400{--border-opacity:1;border-color:#68d391;border-color:rgba(104,211,145,var(--border-opacity))}.sm\:border-green-500{--border-opacity:1;border-color:#48bb78;border-color:rgba(72,187,120,var(--border-opacity))}.sm\:border-green-600{--border-opacity:1;border-color:#38a169;border-color:rgba(56,161,105,var(--border-opacity))}.sm\:border-green-700{--border-opacity:1;border-color:#2f855a;border-color:rgba(47,133,90,var(--border-opacity))}.sm\:border-green-800{--border-opacity:1;border-color:#276749;border-color:rgba(39,103,73,var(--border-opacity))}.sm\:border-green-900{--border-opacity:1;border-color:#22543d;border-color:rgba(34,84,61,var(--border-opacity))}.sm\:border-teal-100{--border-opacity:1;border-color:#e6fffa;border-color:rgba(230,255,250,var(--border-opacity))}.sm\:border-teal-200{--border-opacity:1;border-color:#b2f5ea;border-color:rgba(178,245,234,var(--border-opacity))}.sm\:border-teal-300{--border-opacity:1;border-color:#81e6d9;border-color:rgba(129,230,217,var(--border-opacity))}.sm\:border-teal-400{--border-opacity:1;border-color:#4fd1c5;border-color:rgba(79,209,197,var(--border-opacity))}.sm\:border-teal-500{--border-opacity:1;border-color:#38b2ac;border-color:rgba(56,178,172,var(--border-opacity))}.sm\:border-teal-600{--border-opacity:1;border-color:#319795;border-color:rgba(49,151,149,var(--border-opacity))}.sm\:border-teal-700{--border-opacity:1;border-color:#2c7a7b;border-color:rgba(44,122,123,var(--border-opacity))}.sm\:border-teal-800{--border-opacity:1;border-color:#285e61;border-color:rgba(40,94,97,var(--border-opacity))}.sm\:border-teal-900{--border-opacity:1;border-color:#234e52;border-color:rgba(35,78,82,var(--border-opacity))}.sm\:border-blue-100{--border-opacity:1;border-color:#ebf8ff;border-color:rgba(235,248,255,var(--border-opacity))}.sm\:border-blue-200{--border-opacity:1;border-color:#bee3f8;border-color:rgba(190,227,248,var(--border-opacity))}.sm\:border-blue-300{--border-opacity:1;border-color:#90cdf4;border-color:rgba(144,205,244,var(--border-opacity))}.sm\:border-blue-400{--border-opacity:1;border-color:#63b3ed;border-color:rgba(99,179,237,var(--border-opacity))}.sm\:border-blue-500{--border-opacity:1;border-color:#4299e1;border-color:rgba(66,153,225,var(--border-opacity))}.sm\:border-blue-600{--border-opacity:1;border-color:#3182ce;border-color:rgba(49,130,206,var(--border-opacity))}.sm\:border-blue-700{--border-opacity:1;border-color:#2b6cb0;border-color:rgba(43,108,176,var(--border-opacity))}.sm\:border-blue-800{--border-opacity:1;border-color:#2c5282;border-color:rgba(44,82,130,var(--border-opacity))}.sm\:border-blue-900{--border-opacity:1;border-color:#2a4365;border-color:rgba(42,67,101,var(--border-opacity))}.sm\:border-indigo-100{--border-opacity:1;border-color:#ebf4ff;border-color:rgba(235,244,255,var(--border-opacity))}.sm\:border-indigo-200{--border-opacity:1;border-color:#c3dafe;border-color:rgba(195,218,254,var(--border-opacity))}.sm\:border-indigo-300{--border-opacity:1;border-color:#a3bffa;border-color:rgba(163,191,250,var(--border-opacity))}.sm\:border-indigo-400{--border-opacity:1;border-color:#7f9cf5;border-color:rgba(127,156,245,var(--border-opacity))}.sm\:border-indigo-500{--border-opacity:1;border-color:#667eea;border-color:rgba(102,126,234,var(--border-opacity))}.sm\:border-indigo-600{--border-opacity:1;border-color:#5a67d8;border-color:rgba(90,103,216,var(--border-opacity))}.sm\:border-indigo-700{--border-opacity:1;border-color:#4c51bf;border-color:rgba(76,81,191,var(--border-opacity))}.sm\:border-indigo-800{--border-opacity:1;border-color:#434190;border-color:rgba(67,65,144,var(--border-opacity))}.sm\:border-indigo-900{--border-opacity:1;border-color:#3c366b;border-color:rgba(60,54,107,var(--border-opacity))}.sm\:border-purple-100{--border-opacity:1;border-color:#faf5ff;border-color:rgba(250,245,255,var(--border-opacity))}.sm\:border-purple-200{--border-opacity:1;border-color:#e9d8fd;border-color:rgba(233,216,253,var(--border-opacity))}.sm\:border-purple-300{--border-opacity:1;border-color:#d6bcfa;border-color:rgba(214,188,250,var(--border-opacity))}.sm\:border-purple-400{--border-opacity:1;border-color:#b794f4;border-color:rgba(183,148,244,var(--border-opacity))}.sm\:border-purple-500{--border-opacity:1;border-color:#9f7aea;border-color:rgba(159,122,234,var(--border-opacity))}.sm\:border-purple-600{--border-opacity:1;border-color:#805ad5;border-color:rgba(128,90,213,var(--border-opacity))}.sm\:border-purple-700{--border-opacity:1;border-color:#6b46c1;border-color:rgba(107,70,193,var(--border-opacity))}.sm\:border-purple-800{--border-opacity:1;border-color:#553c9a;border-color:rgba(85,60,154,var(--border-opacity))}.sm\:border-purple-900{--border-opacity:1;border-color:#44337a;border-color:rgba(68,51,122,var(--border-opacity))}.sm\:border-pink-100{--border-opacity:1;border-color:#fff5f7;border-color:rgba(255,245,247,var(--border-opacity))}.sm\:border-pink-200{--border-opacity:1;border-color:#fed7e2;border-color:rgba(254,215,226,var(--border-opacity))}.sm\:border-pink-300{--border-opacity:1;border-color:#fbb6ce;border-color:rgba(251,182,206,var(--border-opacity))}.sm\:border-pink-400{--border-opacity:1;border-color:#f687b3;border-color:rgba(246,135,179,var(--border-opacity))}.sm\:border-pink-500{--border-opacity:1;border-color:#ed64a6;border-color:rgba(237,100,166,var(--border-opacity))}.sm\:border-pink-600{--border-opacity:1;border-color:#d53f8c;border-color:rgba(213,63,140,var(--border-opacity))}.sm\:border-pink-700{--border-opacity:1;border-color:#b83280;border-color:rgba(184,50,128,var(--border-opacity))}.sm\:border-pink-800{--border-opacity:1;border-color:#97266d;border-color:rgba(151,38,109,var(--border-opacity))}.sm\:border-pink-900{--border-opacity:1;border-color:#702459;border-color:rgba(112,36,89,var(--border-opacity))}.sm\:hover\:border-transparent:hover{border-color:transparent}.sm\:hover\:border-current:hover{border-color:currentColor}.sm\:hover\:border-black:hover{--border-opacity:1;border-color:#000;border-color:rgba(0,0,0,var(--border-opacity))}.sm\:hover\:border-white:hover{--border-opacity:1;border-color:#fff;border-color:rgba(255,255,255,var(--border-opacity))}.sm\:hover\:border-gray-100:hover{--border-opacity:1;border-color:#f7fafc;border-color:rgba(247,250,252,var(--border-opacity))}.sm\:hover\:border-gray-200:hover{--border-opacity:1;border-color:#edf2f7;border-color:rgba(237,242,247,var(--border-opacity))}.sm\:hover\:border-gray-300:hover{--border-opacity:1;border-color:#e2e8f0;border-color:rgba(226,232,240,var(--border-opacity))}.sm\:hover\:border-gray-400:hover{--border-opacity:1;border-color:#cbd5e0;border-color:rgba(203,213,224,var(--border-opacity))}.sm\:hover\:border-gray-500:hover{--border-opacity:1;border-color:#a0aec0;border-color:rgba(160,174,192,var(--border-opacity))}.sm\:hover\:border-gray-600:hover{--border-opacity:1;border-color:#718096;border-color:rgba(113,128,150,var(--border-opacity))}.sm\:hover\:border-gray-700:hover{--border-opacity:1;border-color:#4a5568;border-color:rgba(74,85,104,var(--border-opacity))}.sm\:hover\:border-gray-800:hover{--border-opacity:1;border-color:#2d3748;border-color:rgba(45,55,72,var(--border-opacity))}.sm\:hover\:border-gray-900:hover{--border-opacity:1;border-color:#1a202c;border-color:rgba(26,32,44,var(--border-opacity))}.sm\:hover\:border-red-100:hover{--border-opacity:1;border-color:#fff5f5;border-color:rgba(255,245,245,var(--border-opacity))}.sm\:hover\:border-red-200:hover{--border-opacity:1;border-color:#fed7d7;border-color:rgba(254,215,215,var(--border-opacity))}.sm\:hover\:border-red-300:hover{--border-opacity:1;border-color:#feb2b2;border-color:rgba(254,178,178,var(--border-opacity))}.sm\:hover\:border-red-400:hover{--border-opacity:1;border-color:#fc8181;border-color:rgba(252,129,129,var(--border-opacity))}.sm\:hover\:border-red-500:hover{--border-opacity:1;border-color:#f56565;border-color:rgba(245,101,101,var(--border-opacity))}.sm\:hover\:border-red-600:hover{--border-opacity:1;border-color:#e53e3e;border-color:rgba(229,62,62,var(--border-opacity))}.sm\:hover\:border-red-700:hover{--border-opacity:1;border-color:#c53030;border-color:rgba(197,48,48,var(--border-opacity))}.sm\:hover\:border-red-800:hover{--border-opacity:1;border-color:#9b2c2c;border-color:rgba(155,44,44,var(--border-opacity))}.sm\:hover\:border-red-900:hover{--border-opacity:1;border-color:#742a2a;border-color:rgba(116,42,42,var(--border-opacity))}.sm\:hover\:border-orange-100:hover{--border-opacity:1;border-color:#fffaf0;border-color:rgba(255,250,240,var(--border-opacity))}.sm\:hover\:border-orange-200:hover{--border-opacity:1;border-color:#feebc8;border-color:rgba(254,235,200,var(--border-opacity))}.sm\:hover\:border-orange-300:hover{--border-opacity:1;border-color:#fbd38d;border-color:rgba(251,211,141,var(--border-opacity))}.sm\:hover\:border-orange-400:hover{--border-opacity:1;border-color:#f6ad55;border-color:rgba(246,173,85,var(--border-opacity))}.sm\:hover\:border-orange-500:hover{--border-opacity:1;border-color:#ed8936;border-color:rgba(237,137,54,var(--border-opacity))}.sm\:hover\:border-orange-600:hover{--border-opacity:1;border-color:#dd6b20;border-color:rgba(221,107,32,var(--border-opacity))}.sm\:hover\:border-orange-700:hover{--border-opacity:1;border-color:#c05621;border-color:rgba(192,86,33,var(--border-opacity))}.sm\:hover\:border-orange-800:hover{--border-opacity:1;border-color:#9c4221;border-color:rgba(156,66,33,var(--border-opacity))}.sm\:hover\:border-orange-900:hover{--border-opacity:1;border-color:#7b341e;border-color:rgba(123,52,30,var(--border-opacity))}.sm\:hover\:border-yellow-100:hover{--border-opacity:1;border-color:ivory;border-color:rgba(255,255,240,var(--border-opacity))}.sm\:hover\:border-yellow-200:hover{--border-opacity:1;border-color:#fefcbf;border-color:rgba(254,252,191,var(--border-opacity))}.sm\:hover\:border-yellow-300:hover{--border-opacity:1;border-color:#faf089;border-color:rgba(250,240,137,var(--border-opacity))}.sm\:hover\:border-yellow-400:hover{--border-opacity:1;border-color:#f6e05e;border-color:rgba(246,224,94,var(--border-opacity))}.sm\:hover\:border-yellow-500:hover{--border-opacity:1;border-color:#ecc94b;border-color:rgba(236,201,75,var(--border-opacity))}.sm\:hover\:border-yellow-600:hover{--border-opacity:1;border-color:#d69e2e;border-color:rgba(214,158,46,var(--border-opacity))}.sm\:hover\:border-yellow-700:hover{--border-opacity:1;border-color:#b7791f;border-color:rgba(183,121,31,var(--border-opacity))}.sm\:hover\:border-yellow-800:hover{--border-opacity:1;border-color:#975a16;border-color:rgba(151,90,22,var(--border-opacity))}.sm\:hover\:border-yellow-900:hover{--border-opacity:1;border-color:#744210;border-color:rgba(116,66,16,var(--border-opacity))}.sm\:hover\:border-green-100:hover{--border-opacity:1;border-color:#f0fff4;border-color:rgba(240,255,244,var(--border-opacity))}.sm\:hover\:border-green-200:hover{--border-opacity:1;border-color:#c6f6d5;border-color:rgba(198,246,213,var(--border-opacity))}.sm\:hover\:border-green-300:hover{--border-opacity:1;border-color:#9ae6b4;border-color:rgba(154,230,180,var(--border-opacity))}.sm\:hover\:border-green-400:hover{--border-opacity:1;border-color:#68d391;border-color:rgba(104,211,145,var(--border-opacity))}.sm\:hover\:border-green-500:hover{--border-opacity:1;border-color:#48bb78;border-color:rgba(72,187,120,var(--border-opacity))}.sm\:hover\:border-green-600:hover{--border-opacity:1;border-color:#38a169;border-color:rgba(56,161,105,var(--border-opacity))}.sm\:hover\:border-green-700:hover{--border-opacity:1;border-color:#2f855a;border-color:rgba(47,133,90,var(--border-opacity))}.sm\:hover\:border-green-800:hover{--border-opacity:1;border-color:#276749;border-color:rgba(39,103,73,var(--border-opacity))}.sm\:hover\:border-green-900:hover{--border-opacity:1;border-color:#22543d;border-color:rgba(34,84,61,var(--border-opacity))}.sm\:hover\:border-teal-100:hover{--border-opacity:1;border-color:#e6fffa;border-color:rgba(230,255,250,var(--border-opacity))}.sm\:hover\:border-teal-200:hover{--border-opacity:1;border-color:#b2f5ea;border-color:rgba(178,245,234,var(--border-opacity))}.sm\:hover\:border-teal-300:hover{--border-opacity:1;border-color:#81e6d9;border-color:rgba(129,230,217,var(--border-opacity))}.sm\:hover\:border-teal-400:hover{--border-opacity:1;border-color:#4fd1c5;border-color:rgba(79,209,197,var(--border-opacity))}.sm\:hover\:border-teal-500:hover{--border-opacity:1;border-color:#38b2ac;border-color:rgba(56,178,172,var(--border-opacity))}.sm\:hover\:border-teal-600:hover{--border-opacity:1;border-color:#319795;border-color:rgba(49,151,149,var(--border-opacity))}.sm\:hover\:border-teal-700:hover{--border-opacity:1;border-color:#2c7a7b;border-color:rgba(44,122,123,var(--border-opacity))}.sm\:hover\:border-teal-800:hover{--border-opacity:1;border-color:#285e61;border-color:rgba(40,94,97,var(--border-opacity))}.sm\:hover\:border-teal-900:hover{--border-opacity:1;border-color:#234e52;border-color:rgba(35,78,82,var(--border-opacity))}.sm\:hover\:border-blue-100:hover{--border-opacity:1;border-color:#ebf8ff;border-color:rgba(235,248,255,var(--border-opacity))}.sm\:hover\:border-blue-200:hover{--border-opacity:1;border-color:#bee3f8;border-color:rgba(190,227,248,var(--border-opacity))}.sm\:hover\:border-blue-300:hover{--border-opacity:1;border-color:#90cdf4;border-color:rgba(144,205,244,var(--border-opacity))}.sm\:hover\:border-blue-400:hover{--border-opacity:1;border-color:#63b3ed;border-color:rgba(99,179,237,var(--border-opacity))}.sm\:hover\:border-blue-500:hover{--border-opacity:1;border-color:#4299e1;border-color:rgba(66,153,225,var(--border-opacity))}.sm\:hover\:border-blue-600:hover{--border-opacity:1;border-color:#3182ce;border-color:rgba(49,130,206,var(--border-opacity))}.sm\:hover\:border-blue-700:hover{--border-opacity:1;border-color:#2b6cb0;border-color:rgba(43,108,176,var(--border-opacity))}.sm\:hover\:border-blue-800:hover{--border-opacity:1;border-color:#2c5282;border-color:rgba(44,82,130,var(--border-opacity))}.sm\:hover\:border-blue-900:hover{--border-opacity:1;border-color:#2a4365;border-color:rgba(42,67,101,var(--border-opacity))}.sm\:hover\:border-indigo-100:hover{--border-opacity:1;border-color:#ebf4ff;border-color:rgba(235,244,255,var(--border-opacity))}.sm\:hover\:border-indigo-200:hover{--border-opacity:1;border-color:#c3dafe;border-color:rgba(195,218,254,var(--border-opacity))}.sm\:hover\:border-indigo-300:hover{--border-opacity:1;border-color:#a3bffa;border-color:rgba(163,191,250,var(--border-opacity))}.sm\:hover\:border-indigo-400:hover{--border-opacity:1;border-color:#7f9cf5;border-color:rgba(127,156,245,var(--border-opacity))}.sm\:hover\:border-indigo-500:hover{--border-opacity:1;border-color:#667eea;border-color:rgba(102,126,234,var(--border-opacity))}.sm\:hover\:border-indigo-600:hover{--border-opacity:1;border-color:#5a67d8;border-color:rgba(90,103,216,var(--border-opacity))}.sm\:hover\:border-indigo-700:hover{--border-opacity:1;border-color:#4c51bf;border-color:rgba(76,81,191,var(--border-opacity))}.sm\:hover\:border-indigo-800:hover{--border-opacity:1;border-color:#434190;border-color:rgba(67,65,144,var(--border-opacity))}.sm\:hover\:border-indigo-900:hover{--border-opacity:1;border-color:#3c366b;border-color:rgba(60,54,107,var(--border-opacity))}.sm\:hover\:border-purple-100:hover{--border-opacity:1;border-color:#faf5ff;border-color:rgba(250,245,255,var(--border-opacity))}.sm\:hover\:border-purple-200:hover{--border-opacity:1;border-color:#e9d8fd;border-color:rgba(233,216,253,var(--border-opacity))}.sm\:hover\:border-purple-300:hover{--border-opacity:1;border-color:#d6bcfa;border-color:rgba(214,188,250,var(--border-opacity))}.sm\:hover\:border-purple-400:hover{--border-opacity:1;border-color:#b794f4;border-color:rgba(183,148,244,var(--border-opacity))}.sm\:hover\:border-purple-500:hover{--border-opacity:1;border-color:#9f7aea;border-color:rgba(159,122,234,var(--border-opacity))}.sm\:hover\:border-purple-600:hover{--border-opacity:1;border-color:#805ad5;border-color:rgba(128,90,213,var(--border-opacity))}.sm\:hover\:border-purple-700:hover{--border-opacity:1;border-color:#6b46c1;border-color:rgba(107,70,193,var(--border-opacity))}.sm\:hover\:border-purple-800:hover{--border-opacity:1;border-color:#553c9a;border-color:rgba(85,60,154,var(--border-opacity))}.sm\:hover\:border-purple-900:hover{--border-opacity:1;border-color:#44337a;border-color:rgba(68,51,122,var(--border-opacity))}.sm\:hover\:border-pink-100:hover{--border-opacity:1;border-color:#fff5f7;border-color:rgba(255,245,247,var(--border-opacity))}.sm\:hover\:border-pink-200:hover{--border-opacity:1;border-color:#fed7e2;border-color:rgba(254,215,226,var(--border-opacity))}.sm\:hover\:border-pink-300:hover{--border-opacity:1;border-color:#fbb6ce;border-color:rgba(251,182,206,var(--border-opacity))}.sm\:hover\:border-pink-400:hover{--border-opacity:1;border-color:#f687b3;border-color:rgba(246,135,179,var(--border-opacity))}.sm\:hover\:border-pink-500:hover{--border-opacity:1;border-color:#ed64a6;border-color:rgba(237,100,166,var(--border-opacity))}.sm\:hover\:border-pink-600:hover{--border-opacity:1;border-color:#d53f8c;border-color:rgba(213,63,140,var(--border-opacity))}.sm\:hover\:border-pink-700:hover{--border-opacity:1;border-color:#b83280;border-color:rgba(184,50,128,var(--border-opacity))}.sm\:hover\:border-pink-800:hover{--border-opacity:1;border-color:#97266d;border-color:rgba(151,38,109,var(--border-opacity))}.sm\:hover\:border-pink-900:hover{--border-opacity:1;border-color:#702459;border-color:rgba(112,36,89,var(--border-opacity))}.sm\:focus\:border-transparent:focus{border-color:transparent}.sm\:focus\:border-current:focus{border-color:currentColor}.sm\:focus\:border-black:focus{--border-opacity:1;border-color:#000;border-color:rgba(0,0,0,var(--border-opacity))}.sm\:focus\:border-white:focus{--border-opacity:1;border-color:#fff;border-color:rgba(255,255,255,var(--border-opacity))}.sm\:focus\:border-gray-100:focus{--border-opacity:1;border-color:#f7fafc;border-color:rgba(247,250,252,var(--border-opacity))}.sm\:focus\:border-gray-200:focus{--border-opacity:1;border-color:#edf2f7;border-color:rgba(237,242,247,var(--border-opacity))}.sm\:focus\:border-gray-300:focus{--border-opacity:1;border-color:#e2e8f0;border-color:rgba(226,232,240,var(--border-opacity))}.sm\:focus\:border-gray-400:focus{--border-opacity:1;border-color:#cbd5e0;border-color:rgba(203,213,224,var(--border-opacity))}.sm\:focus\:border-gray-500:focus{--border-opacity:1;border-color:#a0aec0;border-color:rgba(160,174,192,var(--border-opacity))}.sm\:focus\:border-gray-600:focus{--border-opacity:1;border-color:#718096;border-color:rgba(113,128,150,var(--border-opacity))}.sm\:focus\:border-gray-700:focus{--border-opacity:1;border-color:#4a5568;border-color:rgba(74,85,104,var(--border-opacity))}.sm\:focus\:border-gray-800:focus{--border-opacity:1;border-color:#2d3748;border-color:rgba(45,55,72,var(--border-opacity))}.sm\:focus\:border-gray-900:focus{--border-opacity:1;border-color:#1a202c;border-color:rgba(26,32,44,var(--border-opacity))}.sm\:focus\:border-red-100:focus{--border-opacity:1;border-color:#fff5f5;border-color:rgba(255,245,245,var(--border-opacity))}.sm\:focus\:border-red-200:focus{--border-opacity:1;border-color:#fed7d7;border-color:rgba(254,215,215,var(--border-opacity))}.sm\:focus\:border-red-300:focus{--border-opacity:1;border-color:#feb2b2;border-color:rgba(254,178,178,var(--border-opacity))}.sm\:focus\:border-red-400:focus{--border-opacity:1;border-color:#fc8181;border-color:rgba(252,129,129,var(--border-opacity))}.sm\:focus\:border-red-500:focus{--border-opacity:1;border-color:#f56565;border-color:rgba(245,101,101,var(--border-opacity))}.sm\:focus\:border-red-600:focus{--border-opacity:1;border-color:#e53e3e;border-color:rgba(229,62,62,var(--border-opacity))}.sm\:focus\:border-red-700:focus{--border-opacity:1;border-color:#c53030;border-color:rgba(197,48,48,var(--border-opacity))}.sm\:focus\:border-red-800:focus{--border-opacity:1;border-color:#9b2c2c;border-color:rgba(155,44,44,var(--border-opacity))}.sm\:focus\:border-red-900:focus{--border-opacity:1;border-color:#742a2a;border-color:rgba(116,42,42,var(--border-opacity))}.sm\:focus\:border-orange-100:focus{--border-opacity:1;border-color:#fffaf0;border-color:rgba(255,250,240,var(--border-opacity))}.sm\:focus\:border-orange-200:focus{--border-opacity:1;border-color:#feebc8;border-color:rgba(254,235,200,var(--border-opacity))}.sm\:focus\:border-orange-300:focus{--border-opacity:1;border-color:#fbd38d;border-color:rgba(251,211,141,var(--border-opacity))}.sm\:focus\:border-orange-400:focus{--border-opacity:1;border-color:#f6ad55;border-color:rgba(246,173,85,var(--border-opacity))}.sm\:focus\:border-orange-500:focus{--border-opacity:1;border-color:#ed8936;border-color:rgba(237,137,54,var(--border-opacity))}.sm\:focus\:border-orange-600:focus{--border-opacity:1;border-color:#dd6b20;border-color:rgba(221,107,32,var(--border-opacity))}.sm\:focus\:border-orange-700:focus{--border-opacity:1;border-color:#c05621;border-color:rgba(192,86,33,var(--border-opacity))}.sm\:focus\:border-orange-800:focus{--border-opacity:1;border-color:#9c4221;border-color:rgba(156,66,33,var(--border-opacity))}.sm\:focus\:border-orange-900:focus{--border-opacity:1;border-color:#7b341e;border-color:rgba(123,52,30,var(--border-opacity))}.sm\:focus\:border-yellow-100:focus{--border-opacity:1;border-color:ivory;border-color:rgba(255,255,240,var(--border-opacity))}.sm\:focus\:border-yellow-200:focus{--border-opacity:1;border-color:#fefcbf;border-color:rgba(254,252,191,var(--border-opacity))}.sm\:focus\:border-yellow-300:focus{--border-opacity:1;border-color:#faf089;border-color:rgba(250,240,137,var(--border-opacity))}.sm\:focus\:border-yellow-400:focus{--border-opacity:1;border-color:#f6e05e;border-color:rgba(246,224,94,var(--border-opacity))}.sm\:focus\:border-yellow-500:focus{--border-opacity:1;border-color:#ecc94b;border-color:rgba(236,201,75,var(--border-opacity))}.sm\:focus\:border-yellow-600:focus{--border-opacity:1;border-color:#d69e2e;border-color:rgba(214,158,46,var(--border-opacity))}.sm\:focus\:border-yellow-700:focus{--border-opacity:1;border-color:#b7791f;border-color:rgba(183,121,31,var(--border-opacity))}.sm\:focus\:border-yellow-800:focus{--border-opacity:1;border-color:#975a16;border-color:rgba(151,90,22,var(--border-opacity))}.sm\:focus\:border-yellow-900:focus{--border-opacity:1;border-color:#744210;border-color:rgba(116,66,16,var(--border-opacity))}.sm\:focus\:border-green-100:focus{--border-opacity:1;border-color:#f0fff4;border-color:rgba(240,255,244,var(--border-opacity))}.sm\:focus\:border-green-200:focus{--border-opacity:1;border-color:#c6f6d5;border-color:rgba(198,246,213,var(--border-opacity))}.sm\:focus\:border-green-300:focus{--border-opacity:1;border-color:#9ae6b4;border-color:rgba(154,230,180,var(--border-opacity))}.sm\:focus\:border-green-400:focus{--border-opacity:1;border-color:#68d391;border-color:rgba(104,211,145,var(--border-opacity))}.sm\:focus\:border-green-500:focus{--border-opacity:1;border-color:#48bb78;border-color:rgba(72,187,120,var(--border-opacity))}.sm\:focus\:border-green-600:focus{--border-opacity:1;border-color:#38a169;border-color:rgba(56,161,105,var(--border-opacity))}.sm\:focus\:border-green-700:focus{--border-opacity:1;border-color:#2f855a;border-color:rgba(47,133,90,var(--border-opacity))}.sm\:focus\:border-green-800:focus{--border-opacity:1;border-color:#276749;border-color:rgba(39,103,73,var(--border-opacity))}.sm\:focus\:border-green-900:focus{--border-opacity:1;border-color:#22543d;border-color:rgba(34,84,61,var(--border-opacity))}.sm\:focus\:border-teal-100:focus{--border-opacity:1;border-color:#e6fffa;border-color:rgba(230,255,250,var(--border-opacity))}.sm\:focus\:border-teal-200:focus{--border-opacity:1;border-color:#b2f5ea;border-color:rgba(178,245,234,var(--border-opacity))}.sm\:focus\:border-teal-300:focus{--border-opacity:1;border-color:#81e6d9;border-color:rgba(129,230,217,var(--border-opacity))}.sm\:focus\:border-teal-400:focus{--border-opacity:1;border-color:#4fd1c5;border-color:rgba(79,209,197,var(--border-opacity))}.sm\:focus\:border-teal-500:focus{--border-opacity:1;border-color:#38b2ac;border-color:rgba(56,178,172,var(--border-opacity))}.sm\:focus\:border-teal-600:focus{--border-opacity:1;border-color:#319795;border-color:rgba(49,151,149,var(--border-opacity))}.sm\:focus\:border-teal-700:focus{--border-opacity:1;border-color:#2c7a7b;border-color:rgba(44,122,123,var(--border-opacity))}.sm\:focus\:border-teal-800:focus{--border-opacity:1;border-color:#285e61;border-color:rgba(40,94,97,var(--border-opacity))}.sm\:focus\:border-teal-900:focus{--border-opacity:1;border-color:#234e52;border-color:rgba(35,78,82,var(--border-opacity))}.sm\:focus\:border-blue-100:focus{--border-opacity:1;border-color:#ebf8ff;border-color:rgba(235,248,255,var(--border-opacity))}.sm\:focus\:border-blue-200:focus{--border-opacity:1;border-color:#bee3f8;border-color:rgba(190,227,248,var(--border-opacity))}.sm\:focus\:border-blue-300:focus{--border-opacity:1;border-color:#90cdf4;border-color:rgba(144,205,244,var(--border-opacity))}.sm\:focus\:border-blue-400:focus{--border-opacity:1;border-color:#63b3ed;border-color:rgba(99,179,237,var(--border-opacity))}.sm\:focus\:border-blue-500:focus{--border-opacity:1;border-color:#4299e1;border-color:rgba(66,153,225,var(--border-opacity))}.sm\:focus\:border-blue-600:focus{--border-opacity:1;border-color:#3182ce;border-color:rgba(49,130,206,var(--border-opacity))}.sm\:focus\:border-blue-700:focus{--border-opacity:1;border-color:#2b6cb0;border-color:rgba(43,108,176,var(--border-opacity))}.sm\:focus\:border-blue-800:focus{--border-opacity:1;border-color:#2c5282;border-color:rgba(44,82,130,var(--border-opacity))}.sm\:focus\:border-blue-900:focus{--border-opacity:1;border-color:#2a4365;border-color:rgba(42,67,101,var(--border-opacity))}.sm\:focus\:border-indigo-100:focus{--border-opacity:1;border-color:#ebf4ff;border-color:rgba(235,244,255,var(--border-opacity))}.sm\:focus\:border-indigo-200:focus{--border-opacity:1;border-color:#c3dafe;border-color:rgba(195,218,254,var(--border-opacity))}.sm\:focus\:border-indigo-300:focus{--border-opacity:1;border-color:#a3bffa;border-color:rgba(163,191,250,var(--border-opacity))}.sm\:focus\:border-indigo-400:focus{--border-opacity:1;border-color:#7f9cf5;border-color:rgba(127,156,245,var(--border-opacity))}.sm\:focus\:border-indigo-500:focus{--border-opacity:1;border-color:#667eea;border-color:rgba(102,126,234,var(--border-opacity))}.sm\:focus\:border-indigo-600:focus{--border-opacity:1;border-color:#5a67d8;border-color:rgba(90,103,216,var(--border-opacity))}.sm\:focus\:border-indigo-700:focus{--border-opacity:1;border-color:#4c51bf;border-color:rgba(76,81,191,var(--border-opacity))}.sm\:focus\:border-indigo-800:focus{--border-opacity:1;border-color:#434190;border-color:rgba(67,65,144,var(--border-opacity))}.sm\:focus\:border-indigo-900:focus{--border-opacity:1;border-color:#3c366b;border-color:rgba(60,54,107,var(--border-opacity))}.sm\:focus\:border-purple-100:focus{--border-opacity:1;border-color:#faf5ff;border-color:rgba(250,245,255,var(--border-opacity))}.sm\:focus\:border-purple-200:focus{--border-opacity:1;border-color:#e9d8fd;border-color:rgba(233,216,253,var(--border-opacity))}.sm\:focus\:border-purple-300:focus{--border-opacity:1;border-color:#d6bcfa;border-color:rgba(214,188,250,var(--border-opacity))}.sm\:focus\:border-purple-400:focus{--border-opacity:1;border-color:#b794f4;border-color:rgba(183,148,244,var(--border-opacity))}.sm\:focus\:border-purple-500:focus{--border-opacity:1;border-color:#9f7aea;border-color:rgba(159,122,234,var(--border-opacity))}.sm\:focus\:border-purple-600:focus{--border-opacity:1;border-color:#805ad5;border-color:rgba(128,90,213,var(--border-opacity))}.sm\:focus\:border-purple-700:focus{--border-opacity:1;border-color:#6b46c1;border-color:rgba(107,70,193,var(--border-opacity))}.sm\:focus\:border-purple-800:focus{--border-opacity:1;border-color:#553c9a;border-color:rgba(85,60,154,var(--border-opacity))}.sm\:focus\:border-purple-900:focus{--border-opacity:1;border-color:#44337a;border-color:rgba(68,51,122,var(--border-opacity))}.sm\:focus\:border-pink-100:focus{--border-opacity:1;border-color:#fff5f7;border-color:rgba(255,245,247,var(--border-opacity))}.sm\:focus\:border-pink-200:focus{--border-opacity:1;border-color:#fed7e2;border-color:rgba(254,215,226,var(--border-opacity))}.sm\:focus\:border-pink-300:focus{--border-opacity:1;border-color:#fbb6ce;border-color:rgba(251,182,206,var(--border-opacity))}.sm\:focus\:border-pink-400:focus{--border-opacity:1;border-color:#f687b3;border-color:rgba(246,135,179,var(--border-opacity))}.sm\:focus\:border-pink-500:focus{--border-opacity:1;border-color:#ed64a6;border-color:rgba(237,100,166,var(--border-opacity))}.sm\:focus\:border-pink-600:focus{--border-opacity:1;border-color:#d53f8c;border-color:rgba(213,63,140,var(--border-opacity))}.sm\:focus\:border-pink-700:focus{--border-opacity:1;border-color:#b83280;border-color:rgba(184,50,128,var(--border-opacity))}.sm\:focus\:border-pink-800:focus{--border-opacity:1;border-color:#97266d;border-color:rgba(151,38,109,var(--border-opacity))}.sm\:focus\:border-pink-900:focus{--border-opacity:1;border-color:#702459;border-color:rgba(112,36,89,var(--border-opacity))}.sm\:border-opacity-0{--border-opacity:0}.sm\:border-opacity-25{--border-opacity:0.25}.sm\:border-opacity-50{--border-opacity:0.5}.sm\:border-opacity-75{--border-opacity:0.75}.sm\:border-opacity-100{--border-opacity:1}.sm\:hover\:border-opacity-0:hover{--border-opacity:0}.sm\:hover\:border-opacity-25:hover{--border-opacity:0.25}.sm\:hover\:border-opacity-50:hover{--border-opacity:0.5}.sm\:hover\:border-opacity-75:hover{--border-opacity:0.75}.sm\:hover\:border-opacity-100:hover{--border-opacity:1}.sm\:focus\:border-opacity-0:focus{--border-opacity:0}.sm\:focus\:border-opacity-25:focus{--border-opacity:0.25}.sm\:focus\:border-opacity-50:focus{--border-opacity:0.5}.sm\:focus\:border-opacity-75:focus{--border-opacity:0.75}.sm\:focus\:border-opacity-100:focus{--border-opacity:1}.sm\:rounded-none{border-radius:0}.sm\:rounded-sm{border-radius:.125rem}.sm\:rounded{border-radius:.25rem}.sm\:rounded-md{border-radius:.375rem}.sm\:rounded-lg{border-radius:.5rem}.sm\:rounded-xl{border-radius:.75rem}.sm\:rounded-2xl{border-radius:1rem}.sm\:rounded-3xl{border-radius:1.5rem}.sm\:rounded-full{border-radius:9999px}.sm\:rounded-t-none{border-top-left-radius:0;border-top-right-radius:0}.sm\:rounded-r-none{border-top-right-radius:0;border-bottom-right-radius:0}.sm\:rounded-b-none{border-bottom-right-radius:0;border-bottom-left-radius:0}.sm\:rounded-l-none{border-top-left-radius:0;border-bottom-left-radius:0}.sm\:rounded-t-sm{border-top-left-radius:.125rem;border-top-right-radius:.125rem}.sm\:rounded-r-sm{border-top-right-radius:.125rem;border-bottom-right-radius:.125rem}.sm\:rounded-b-sm{border-bottom-right-radius:.125rem;border-bottom-left-radius:.125rem}.sm\:rounded-l-sm{border-top-left-radius:.125rem;border-bottom-left-radius:.125rem}.sm\:rounded-t{border-top-left-radius:.25rem;border-top-right-radius:.25rem}.sm\:rounded-r{border-top-right-radius:.25rem;border-bottom-right-radius:.25rem}.sm\:rounded-b{border-bottom-right-radius:.25rem;border-bottom-left-radius:.25rem}.sm\:rounded-l{border-top-left-radius:.25rem;border-bottom-left-radius:.25rem}.sm\:rounded-t-md{border-top-left-radius:.375rem;border-top-right-radius:.375rem}.sm\:rounded-r-md{border-top-right-radius:.375rem;border-bottom-right-radius:.375rem}.sm\:rounded-b-md{border-bottom-right-radius:.375rem;border-bottom-left-radius:.375rem}.sm\:rounded-l-md{border-top-left-radius:.375rem;border-bottom-left-radius:.375rem}.sm\:rounded-t-lg{border-top-left-radius:.5rem;border-top-right-radius:.5rem}.sm\:rounded-r-lg{border-top-right-radius:.5rem;border-bottom-right-radius:.5rem}.sm\:rounded-b-lg{border-bottom-right-radius:.5rem;border-bottom-left-radius:.5rem}.sm\:rounded-l-lg{border-top-left-radius:.5rem;border-bottom-left-radius:.5rem}.sm\:rounded-t-xl{border-top-left-radius:.75rem;border-top-right-radius:.75rem}.sm\:rounded-r-xl{border-top-right-radius:.75rem;border-bottom-right-radius:.75rem}.sm\:rounded-b-xl{border-bottom-right-radius:.75rem;border-bottom-left-radius:.75rem}.sm\:rounded-l-xl{border-top-left-radius:.75rem;border-bottom-left-radius:.75rem}.sm\:rounded-t-2xl{border-top-left-radius:1rem;border-top-right-radius:1rem}.sm\:rounded-r-2xl{border-top-right-radius:1rem;border-bottom-right-radius:1rem}.sm\:rounded-b-2xl{border-bottom-right-radius:1rem;border-bottom-left-radius:1rem}.sm\:rounded-l-2xl{border-top-left-radius:1rem;border-bottom-left-radius:1rem}.sm\:rounded-t-3xl{border-top-left-radius:1.5rem;border-top-right-radius:1.5rem}.sm\:rounded-r-3xl{border-top-right-radius:1.5rem;border-bottom-right-radius:1.5rem}.sm\:rounded-b-3xl{border-bottom-right-radius:1.5rem;border-bottom-left-radius:1.5rem}.sm\:rounded-l-3xl{border-top-left-radius:1.5rem;border-bottom-left-radius:1.5rem}.sm\:rounded-t-full{border-top-left-radius:9999px;border-top-right-radius:9999px}.sm\:rounded-r-full{border-top-right-radius:9999px;border-bottom-right-radius:9999px}.sm\:rounded-b-full{border-bottom-right-radius:9999px;border-bottom-left-radius:9999px}.sm\:rounded-l-full{border-top-left-radius:9999px;border-bottom-left-radius:9999px}.sm\:rounded-tl-none{border-top-left-radius:0}.sm\:rounded-tr-none{border-top-right-radius:0}.sm\:rounded-br-none{border-bottom-right-radius:0}.sm\:rounded-bl-none{border-bottom-left-radius:0}.sm\:rounded-tl-sm{border-top-left-radius:.125rem}.sm\:rounded-tr-sm{border-top-right-radius:.125rem}.sm\:rounded-br-sm{border-bottom-right-radius:.125rem}.sm\:rounded-bl-sm{border-bottom-left-radius:.125rem}.sm\:rounded-tl{border-top-left-radius:.25rem}.sm\:rounded-tr{border-top-right-radius:.25rem}.sm\:rounded-br{border-bottom-right-radius:.25rem}.sm\:rounded-bl{border-bottom-left-radius:.25rem}.sm\:rounded-tl-md{border-top-left-radius:.375rem}.sm\:rounded-tr-md{border-top-right-radius:.375rem}.sm\:rounded-br-md{border-bottom-right-radius:.375rem}.sm\:rounded-bl-md{border-bottom-left-radius:.375rem}.sm\:rounded-tl-lg{border-top-left-radius:.5rem}.sm\:rounded-tr-lg{border-top-right-radius:.5rem}.sm\:rounded-br-lg{border-bottom-right-radius:.5rem}.sm\:rounded-bl-lg{border-bottom-left-radius:.5rem}.sm\:rounded-tl-xl{border-top-left-radius:.75rem}.sm\:rounded-tr-xl{border-top-right-radius:.75rem}.sm\:rounded-br-xl{border-bottom-right-radius:.75rem}.sm\:rounded-bl-xl{border-bottom-left-radius:.75rem}.sm\:rounded-tl-2xl{border-top-left-radius:1rem}.sm\:rounded-tr-2xl{border-top-right-radius:1rem}.sm\:rounded-br-2xl{border-bottom-right-radius:1rem}.sm\:rounded-bl-2xl{border-bottom-left-radius:1rem}.sm\:rounded-tl-3xl{border-top-left-radius:1.5rem}.sm\:rounded-tr-3xl{border-top-right-radius:1.5rem}.sm\:rounded-br-3xl{border-bottom-right-radius:1.5rem}.sm\:rounded-bl-3xl{border-bottom-left-radius:1.5rem}.sm\:rounded-tl-full{border-top-left-radius:9999px}.sm\:rounded-tr-full{border-top-right-radius:9999px}.sm\:rounded-br-full{border-bottom-right-radius:9999px}.sm\:rounded-bl-full{border-bottom-left-radius:9999px}.sm\:border-solid{border-style:solid}.sm\:border-dashed{border-style:dashed}.sm\:border-dotted{border-style:dotted}.sm\:border-double{border-style:double}.sm\:border-none{border-style:none}.sm\:border-0{border-width:0}.sm\:border-2{border-width:2px}.sm\:border-4{border-width:4px}.sm\:border-8{border-width:8px}.sm\:border{border-width:1px}.sm\:border-t-0{border-top-width:0}.sm\:border-r-0{border-right-width:0}.sm\:border-b-0{border-bottom-width:0}.sm\:border-l-0{border-left-width:0}.sm\:border-t-2{border-top-width:2px}.sm\:border-r-2{border-right-width:2px}.sm\:border-b-2{border-bottom-width:2px}.sm\:border-l-2{border-left-width:2px}.sm\:border-t-4{border-top-width:4px}.sm\:border-r-4{border-right-width:4px}.sm\:border-b-4{border-bottom-width:4px}.sm\:border-l-4{border-left-width:4px}.sm\:border-t-8{border-top-width:8px}.sm\:border-r-8{border-right-width:8px}.sm\:border-b-8{border-bottom-width:8px}.sm\:border-l-8{border-left-width:8px}.sm\:border-t{border-top-width:1px}.sm\:border-r{border-right-width:1px}.sm\:border-b{border-bottom-width:1px}.sm\:border-l{border-left-width:1px}.sm\:box-border{box-sizing:border-box}.sm\:box-content{box-sizing:content-box}.sm\:cursor-auto{cursor:auto}.sm\:cursor-default{cursor:default}.sm\:cursor-pointer{cursor:pointer}.sm\:cursor-wait{cursor:wait}.sm\:cursor-text{cursor:text}.sm\:cursor-move{cursor:move}.sm\:cursor-not-allowed{cursor:not-allowed}.sm\:block{display:block}.sm\:inline-block{display:inline-block}.sm\:inline{display:inline}.sm\:flex{display:flex}.sm\:inline-flex{display:inline-flex}.sm\:table{display:table}.sm\:table-caption{display:table-caption}.sm\:table-cell{display:table-cell}.sm\:table-column{display:table-column}.sm\:table-column-group{display:table-column-group}.sm\:table-footer-group{display:table-footer-group}.sm\:table-header-group{display:table-header-group}.sm\:table-row-group{display:table-row-group}.sm\:table-row{display:table-row}.sm\:flow-root{display:flow-root}.sm\:grid{display:grid}.sm\:inline-grid{display:inline-grid}.sm\:contents{display:contents}.sm\:hidden{display:none}.sm\:flex-row{flex-direction:row}.sm\:flex-row-reverse{flex-direction:row-reverse}.sm\:flex-col{flex-direction:column}.sm\:flex-col-reverse{flex-direction:column-reverse}.sm\:flex-wrap{flex-wrap:wrap}.sm\:flex-wrap-reverse{flex-wrap:wrap-reverse}.sm\:flex-no-wrap{flex-wrap:nowrap}.sm\:place-items-auto{place-items:auto}.sm\:place-items-start{place-items:start}.sm\:place-items-end{place-items:end}.sm\:place-items-center{place-items:center}.sm\:place-items-stretch{place-items:stretch}.sm\:place-content-center{place-content:center}.sm\:place-content-start{place-content:start}.sm\:place-content-end{place-content:end}.sm\:place-content-between{place-content:space-between}.sm\:place-content-around{place-content:space-around}.sm\:place-content-evenly{place-content:space-evenly}.sm\:place-content-stretch{place-content:stretch}.sm\:place-self-auto{place-self:auto}.sm\:place-self-start{place-self:start}.sm\:place-self-end{place-self:end}.sm\:place-self-center{place-self:center}.sm\:place-self-stretch{place-self:stretch}.sm\:items-start{align-items:flex-start}.sm\:items-end{align-items:flex-end}.sm\:items-center{align-items:center}.sm\:items-baseline{align-items:baseline}.sm\:items-stretch{align-items:stretch}.sm\:content-center{align-content:center}.sm\:content-start{align-content:flex-start}.sm\:content-end{align-content:flex-end}.sm\:content-between{align-content:space-between}.sm\:content-around{align-content:space-around}.sm\:content-evenly{align-content:space-evenly}.sm\:self-auto{align-self:auto}.sm\:self-start{align-self:flex-start}.sm\:self-end{align-self:flex-end}.sm\:self-center{align-self:center}.sm\:self-stretch{align-self:stretch}.sm\:justify-items-auto{justify-items:auto}.sm\:justify-items-start{justify-items:start}.sm\:justify-items-end{justify-items:end}.sm\:justify-items-center{justify-items:center}.sm\:justify-items-stretch{justify-items:stretch}.sm\:justify-start{justify-content:flex-start}.sm\:justify-end{justify-content:flex-end}.sm\:justify-center{justify-content:center}.sm\:justify-between{justify-content:space-between}.sm\:justify-around{justify-content:space-around}.sm\:justify-evenly{justify-content:space-evenly}.sm\:justify-self-auto{justify-self:auto}.sm\:justify-self-start{justify-self:start}.sm\:justify-self-end{justify-self:end}.sm\:justify-self-center{justify-self:center}.sm\:justify-self-stretch{justify-self:stretch}.sm\:flex-1{flex:1 1 0%}.sm\:flex-auto{flex:1 1 auto}.sm\:flex-initial{flex:0 1 auto}.sm\:flex-none{flex:none}.sm\:flex-grow-0{flex-grow:0}.sm\:flex-grow{flex-grow:1}.sm\:flex-shrink-0{flex-shrink:0}.sm\:flex-shrink{flex-shrink:1}.sm\:order-1{order:1}.sm\:order-2{order:2}.sm\:order-3{order:3}.sm\:order-4{order:4}.sm\:order-5{order:5}.sm\:order-6{order:6}.sm\:order-7{order:7}.sm\:order-8{order:8}.sm\:order-9{order:9}.sm\:order-10{order:10}.sm\:order-11{order:11}.sm\:order-12{order:12}.sm\:order-first{order:-9999}.sm\:order-last{order:9999}.sm\:order-none{order:0}.sm\:float-right{float:right}.sm\:float-left{float:left}.sm\:float-none{float:none}.sm\:clearfix:after{content:"";display:table;clear:both}.sm\:clear-left{clear:left}.sm\:clear-right{clear:right}.sm\:clear-both{clear:both}.sm\:clear-none{clear:none}.sm\:font-sans{font-family:system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji"}.sm\:font-serif{font-family:Georgia,Cambria,"Times New Roman",Times,serif}.sm\:font-mono{font-family:Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace}.sm\:font-hairline{font-weight:100}.sm\:font-thin{font-weight:200}.sm\:font-light{font-weight:300}.sm\:font-normal{font-weight:400}.sm\:font-medium{font-weight:500}.sm\:font-semibold{font-weight:600}.sm\:font-bold{font-weight:700}.sm\:font-extrabold{font-weight:800}.sm\:font-black{font-weight:900}.sm\:hover\:font-hairline:hover{font-weight:100}.sm\:hover\:font-thin:hover{font-weight:200}.sm\:hover\:font-light:hover{font-weight:300}.sm\:hover\:font-normal:hover{font-weight:400}.sm\:hover\:font-medium:hover{font-weight:500}.sm\:hover\:font-semibold:hover{font-weight:600}.sm\:hover\:font-bold:hover{font-weight:700}.sm\:hover\:font-extrabold:hover{font-weight:800}.sm\:hover\:font-black:hover{font-weight:900}.sm\:focus\:font-hairline:focus{font-weight:100}.sm\:focus\:font-thin:focus{font-weight:200}.sm\:focus\:font-light:focus{font-weight:300}.sm\:focus\:font-normal:focus{font-weight:400}.sm\:focus\:font-medium:focus{font-weight:500}.sm\:focus\:font-semibold:focus{font-weight:600}.sm\:focus\:font-bold:focus{font-weight:700}.sm\:focus\:font-extrabold:focus{font-weight:800}.sm\:focus\:font-black:focus{font-weight:900}.sm\:h-0{height:0}.sm\:h-1{height:.25rem}.sm\:h-2{height:.5rem}.sm\:h-3{height:.75rem}.sm\:h-4{height:1rem}.sm\:h-5{height:1.25rem}.sm\:h-6{height:1.5rem}.sm\:h-8{height:2rem}.sm\:h-10{height:2.5rem}.sm\:h-12{height:3rem}.sm\:h-16{height:4rem}.sm\:h-20{height:5rem}.sm\:h-24{height:6rem}.sm\:h-32{height:8rem}.sm\:h-40{height:10rem}.sm\:h-48{height:12rem}.sm\:h-56{height:14rem}.sm\:h-64{height:16rem}.sm\:h-auto{height:auto}.sm\:h-px{height:1px}.sm\:h-full{height:100%}.sm\:h-screen{height:100vh}.sm\:text-xs{font-size:.75rem}.sm\:text-sm{font-size:.875rem}.sm\:text-base{font-size:1rem}.sm\:text-lg{font-size:1.125rem}.sm\:text-xl{font-size:1.25rem}.sm\:text-2xl{font-size:1.5rem}.sm\:text-3xl{font-size:1.875rem}.sm\:text-4xl{font-size:2.25rem}.sm\:text-5xl{font-size:3rem}.sm\:text-6xl{font-size:4rem}.sm\:leading-3{line-height:.75rem}.sm\:leading-4{line-height:1rem}.sm\:leading-5{line-height:1.25rem}.sm\:leading-6{line-height:1.5rem}.sm\:leading-7{line-height:1.75rem}.sm\:leading-8{line-height:2rem}.sm\:leading-9{line-height:2.25rem}.sm\:leading-10{line-height:2.5rem}.sm\:leading-none{line-height:1}.sm\:leading-tight{line-height:1.25}.sm\:leading-snug{line-height:1.375}.sm\:leading-normal{line-height:1.5}.sm\:leading-relaxed{line-height:1.625}.sm\:leading-loose{line-height:2}.sm\:list-inside{list-style-position:inside}.sm\:list-outside{list-style-position:outside}.sm\:list-none{list-style-type:none}.sm\:list-disc{list-style-type:disc}.sm\:list-decimal{list-style-type:decimal}.sm\:m-0{margin:0}.sm\:m-1{margin:.25rem}.sm\:m-2{margin:.5rem}.sm\:m-3{margin:.75rem}.sm\:m-4{margin:1rem}.sm\:m-5{margin:1.25rem}.sm\:m-6{margin:1.5rem}.sm\:m-8{margin:2rem}.sm\:m-10{margin:2.5rem}.sm\:m-12{margin:3rem}.sm\:m-16{margin:4rem}.sm\:m-20{margin:5rem}.sm\:m-24{margin:6rem}.sm\:m-32{margin:8rem}.sm\:m-40{margin:10rem}.sm\:m-48{margin:12rem}.sm\:m-56{margin:14rem}.sm\:m-64{margin:16rem}.sm\:m-auto{margin:auto}.sm\:m-px{margin:1px}.sm\:-m-1{margin:-.25rem}.sm\:-m-2{margin:-.5rem}.sm\:-m-3{margin:-.75rem}.sm\:-m-4{margin:-1rem}.sm\:-m-5{margin:-1.25rem}.sm\:-m-6{margin:-1.5rem}.sm\:-m-8{margin:-2rem}.sm\:-m-10{margin:-2.5rem}.sm\:-m-12{margin:-3rem}.sm\:-m-16{margin:-4rem}.sm\:-m-20{margin:-5rem}.sm\:-m-24{margin:-6rem}.sm\:-m-32{margin:-8rem}.sm\:-m-40{margin:-10rem}.sm\:-m-48{margin:-12rem}.sm\:-m-56{margin:-14rem}.sm\:-m-64{margin:-16rem}.sm\:-m-px{margin:-1px}.sm\:my-0{margin-top:0;margin-bottom:0}.sm\:mx-0{margin-left:0;margin-right:0}.sm\:my-1{margin-top:.25rem;margin-bottom:.25rem}.sm\:mx-1{margin-left:.25rem;margin-right:.25rem}.sm\:my-2{margin-top:.5rem;margin-bottom:.5rem}.sm\:mx-2{margin-left:.5rem;margin-right:.5rem}.sm\:my-3{margin-top:.75rem;margin-bottom:.75rem}.sm\:mx-3{margin-left:.75rem;margin-right:.75rem}.sm\:my-4{margin-top:1rem;margin-bottom:1rem}.sm\:mx-4{margin-left:1rem;margin-right:1rem}.sm\:my-5{margin-top:1.25rem;margin-bottom:1.25rem}.sm\:mx-5{margin-left:1.25rem;margin-right:1.25rem}.sm\:my-6{margin-top:1.5rem;margin-bottom:1.5rem}.sm\:mx-6{margin-left:1.5rem;margin-right:1.5rem}.sm\:my-8{margin-top:2rem;margin-bottom:2rem}.sm\:mx-8{margin-left:2rem;margin-right:2rem}.sm\:my-10{margin-top:2.5rem;margin-bottom:2.5rem}.sm\:mx-10{margin-left:2.5rem;margin-right:2.5rem}.sm\:my-12{margin-top:3rem;margin-bottom:3rem}.sm\:mx-12{margin-left:3rem;margin-right:3rem}.sm\:my-16{margin-top:4rem;margin-bottom:4rem}.sm\:mx-16{margin-left:4rem;margin-right:4rem}.sm\:my-20{margin-top:5rem;margin-bottom:5rem}.sm\:mx-20{margin-left:5rem;margin-right:5rem}.sm\:my-24{margin-top:6rem;margin-bottom:6rem}.sm\:mx-24{margin-left:6rem;margin-right:6rem}.sm\:my-32{margin-top:8rem;margin-bottom:8rem}.sm\:mx-32{margin-left:8rem;margin-right:8rem}.sm\:my-40{margin-top:10rem;margin-bottom:10rem}.sm\:mx-40{margin-left:10rem;margin-right:10rem}.sm\:my-48{margin-top:12rem;margin-bottom:12rem}.sm\:mx-48{margin-left:12rem;margin-right:12rem}.sm\:my-56{margin-top:14rem;margin-bottom:14rem}.sm\:mx-56{margin-left:14rem;margin-right:14rem}.sm\:my-64{margin-top:16rem;margin-bottom:16rem}.sm\:mx-64{margin-left:16rem;margin-right:16rem}.sm\:my-auto{margin-top:auto;margin-bottom:auto}.sm\:mx-auto{margin-left:auto;margin-right:auto}.sm\:my-px{margin-top:1px;margin-bottom:1px}.sm\:mx-px{margin-left:1px;margin-right:1px}.sm\:-my-1{margin-top:-.25rem;margin-bottom:-.25rem}.sm\:-mx-1{margin-left:-.25rem;margin-right:-.25rem}.sm\:-my-2{margin-top:-.5rem;margin-bottom:-.5rem}.sm\:-mx-2{margin-left:-.5rem;margin-right:-.5rem}.sm\:-my-3{margin-top:-.75rem;margin-bottom:-.75rem}.sm\:-mx-3{margin-left:-.75rem;margin-right:-.75rem}.sm\:-my-4{margin-top:-1rem;margin-bottom:-1rem}.sm\:-mx-4{margin-left:-1rem;margin-right:-1rem}.sm\:-my-5{margin-top:-1.25rem;margin-bottom:-1.25rem}.sm\:-mx-5{margin-left:-1.25rem;margin-right:-1.25rem}.sm\:-my-6{margin-top:-1.5rem;margin-bottom:-1.5rem}.sm\:-mx-6{margin-left:-1.5rem;margin-right:-1.5rem}.sm\:-my-8{margin-top:-2rem;margin-bottom:-2rem}.sm\:-mx-8{margin-left:-2rem;margin-right:-2rem}.sm\:-my-10{margin-top:-2.5rem;margin-bottom:-2.5rem}.sm\:-mx-10{margin-left:-2.5rem;margin-right:-2.5rem}.sm\:-my-12{margin-top:-3rem;margin-bottom:-3rem}.sm\:-mx-12{margin-left:-3rem;margin-right:-3rem}.sm\:-my-16{margin-top:-4rem;margin-bottom:-4rem}.sm\:-mx-16{margin-left:-4rem;margin-right:-4rem}.sm\:-my-20{margin-top:-5rem;margin-bottom:-5rem}.sm\:-mx-20{margin-left:-5rem;margin-right:-5rem}.sm\:-my-24{margin-top:-6rem;margin-bottom:-6rem}.sm\:-mx-24{margin-left:-6rem;margin-right:-6rem}.sm\:-my-32{margin-top:-8rem;margin-bottom:-8rem}.sm\:-mx-32{margin-left:-8rem;margin-right:-8rem}.sm\:-my-40{margin-top:-10rem;margin-bottom:-10rem}.sm\:-mx-40{margin-left:-10rem;margin-right:-10rem}.sm\:-my-48{margin-top:-12rem;margin-bottom:-12rem}.sm\:-mx-48{margin-left:-12rem;margin-right:-12rem}.sm\:-my-56{margin-top:-14rem;margin-bottom:-14rem}.sm\:-mx-56{margin-left:-14rem;margin-right:-14rem}.sm\:-my-64{margin-top:-16rem;margin-bottom:-16rem}.sm\:-mx-64{margin-left:-16rem;margin-right:-16rem}.sm\:-my-px{margin-top:-1px;margin-bottom:-1px}.sm\:-mx-px{margin-left:-1px;margin-right:-1px}.sm\:mt-0{margin-top:0}.sm\:mr-0{margin-right:0}.sm\:mb-0{margin-bottom:0}.sm\:ml-0{margin-left:0}.sm\:mt-1{margin-top:.25rem}.sm\:mr-1{margin-right:.25rem}.sm\:mb-1{margin-bottom:.25rem}.sm\:ml-1{margin-left:.25rem}.sm\:mt-2{margin-top:.5rem}.sm\:mr-2{margin-right:.5rem}.sm\:mb-2{margin-bottom:.5rem}.sm\:ml-2{margin-left:.5rem}.sm\:mt-3{margin-top:.75rem}.sm\:mr-3{margin-right:.75rem}.sm\:mb-3{margin-bottom:.75rem}.sm\:ml-3{margin-left:.75rem}.sm\:mt-4{margin-top:1rem}.sm\:mr-4{margin-right:1rem}.sm\:mb-4{margin-bottom:1rem}.sm\:ml-4{margin-left:1rem}.sm\:mt-5{margin-top:1.25rem}.sm\:mr-5{margin-right:1.25rem}.sm\:mb-5{margin-bottom:1.25rem}.sm\:ml-5{margin-left:1.25rem}.sm\:mt-6{margin-top:1.5rem}.sm\:mr-6{margin-right:1.5rem}.sm\:mb-6{margin-bottom:1.5rem}.sm\:ml-6{margin-left:1.5rem}.sm\:mt-8{margin-top:2rem}.sm\:mr-8{margin-right:2rem}.sm\:mb-8{margin-bottom:2rem}.sm\:ml-8{margin-left:2rem}.sm\:mt-10{margin-top:2.5rem}.sm\:mr-10{margin-right:2.5rem}.sm\:mb-10{margin-bottom:2.5rem}.sm\:ml-10{margin-left:2.5rem}.sm\:mt-12{margin-top:3rem}.sm\:mr-12{margin-right:3rem}.sm\:mb-12{margin-bottom:3rem}.sm\:ml-12{margin-left:3rem}.sm\:mt-16{margin-top:4rem}.sm\:mr-16{margin-right:4rem}.sm\:mb-16{margin-bottom:4rem}.sm\:ml-16{margin-left:4rem}.sm\:mt-20{margin-top:5rem}.sm\:mr-20{margin-right:5rem}.sm\:mb-20{margin-bottom:5rem}.sm\:ml-20{margin-left:5rem}.sm\:mt-24{margin-top:6rem}.sm\:mr-24{margin-right:6rem}.sm\:mb-24{margin-bottom:6rem}.sm\:ml-24{margin-left:6rem}.sm\:mt-32{margin-top:8rem}.sm\:mr-32{margin-right:8rem}.sm\:mb-32{margin-bottom:8rem}.sm\:ml-32{margin-left:8rem}.sm\:mt-40{margin-top:10rem}.sm\:mr-40{margin-right:10rem}.sm\:mb-40{margin-bottom:10rem}.sm\:ml-40{margin-left:10rem}.sm\:mt-48{margin-top:12rem}.sm\:mr-48{margin-right:12rem}.sm\:mb-48{margin-bottom:12rem}.sm\:ml-48{margin-left:12rem}.sm\:mt-56{margin-top:14rem}.sm\:mr-56{margin-right:14rem}.sm\:mb-56{margin-bottom:14rem}.sm\:ml-56{margin-left:14rem}.sm\:mt-64{margin-top:16rem}.sm\:mr-64{margin-right:16rem}.sm\:mb-64{margin-bottom:16rem}.sm\:ml-64{margin-left:16rem}.sm\:mt-auto{margin-top:auto}.sm\:mr-auto{margin-right:auto}.sm\:mb-auto{margin-bottom:auto}.sm\:ml-auto{margin-left:auto}.sm\:mt-px{margin-top:1px}.sm\:mr-px{margin-right:1px}.sm\:mb-px{margin-bottom:1px}.sm\:ml-px{margin-left:1px}.sm\:-mt-1{margin-top:-.25rem}.sm\:-mr-1{margin-right:-.25rem}.sm\:-mb-1{margin-bottom:-.25rem}.sm\:-ml-1{margin-left:-.25rem}.sm\:-mt-2{margin-top:-.5rem}.sm\:-mr-2{margin-right:-.5rem}.sm\:-mb-2{margin-bottom:-.5rem}.sm\:-ml-2{margin-left:-.5rem}.sm\:-mt-3{margin-top:-.75rem}.sm\:-mr-3{margin-right:-.75rem}.sm\:-mb-3{margin-bottom:-.75rem}.sm\:-ml-3{margin-left:-.75rem}.sm\:-mt-4{margin-top:-1rem}.sm\:-mr-4{margin-right:-1rem}.sm\:-mb-4{margin-bottom:-1rem}.sm\:-ml-4{margin-left:-1rem}.sm\:-mt-5{margin-top:-1.25rem}.sm\:-mr-5{margin-right:-1.25rem}.sm\:-mb-5{margin-bottom:-1.25rem}.sm\:-ml-5{margin-left:-1.25rem}.sm\:-mt-6{margin-top:-1.5rem}.sm\:-mr-6{margin-right:-1.5rem}.sm\:-mb-6{margin-bottom:-1.5rem}.sm\:-ml-6{margin-left:-1.5rem}.sm\:-mt-8{margin-top:-2rem}.sm\:-mr-8{margin-right:-2rem}.sm\:-mb-8{margin-bottom:-2rem}.sm\:-ml-8{margin-left:-2rem}.sm\:-mt-10{margin-top:-2.5rem}.sm\:-mr-10{margin-right:-2.5rem}.sm\:-mb-10{margin-bottom:-2.5rem}.sm\:-ml-10{margin-left:-2.5rem}.sm\:-mt-12{margin-top:-3rem}.sm\:-mr-12{margin-right:-3rem}.sm\:-mb-12{margin-bottom:-3rem}.sm\:-ml-12{margin-left:-3rem}.sm\:-mt-16{margin-top:-4rem}.sm\:-mr-16{margin-right:-4rem}.sm\:-mb-16{margin-bottom:-4rem}.sm\:-ml-16{margin-left:-4rem}.sm\:-mt-20{margin-top:-5rem}.sm\:-mr-20{margin-right:-5rem}.sm\:-mb-20{margin-bottom:-5rem}.sm\:-ml-20{margin-left:-5rem}.sm\:-mt-24{margin-top:-6rem}.sm\:-mr-24{margin-right:-6rem}.sm\:-mb-24{margin-bottom:-6rem}.sm\:-ml-24{margin-left:-6rem}.sm\:-mt-32{margin-top:-8rem}.sm\:-mr-32{margin-right:-8rem}.sm\:-mb-32{margin-bottom:-8rem}.sm\:-ml-32{margin-left:-8rem}.sm\:-mt-40{margin-top:-10rem}.sm\:-mr-40{margin-right:-10rem}.sm\:-mb-40{margin-bottom:-10rem}.sm\:-ml-40{margin-left:-10rem}.sm\:-mt-48{margin-top:-12rem}.sm\:-mr-48{margin-right:-12rem}.sm\:-mb-48{margin-bottom:-12rem}.sm\:-ml-48{margin-left:-12rem}.sm\:-mt-56{margin-top:-14rem}.sm\:-mr-56{margin-right:-14rem}.sm\:-mb-56{margin-bottom:-14rem}.sm\:-ml-56{margin-left:-14rem}.sm\:-mt-64{margin-top:-16rem}.sm\:-mr-64{margin-right:-16rem}.sm\:-mb-64{margin-bottom:-16rem}.sm\:-ml-64{margin-left:-16rem}.sm\:-mt-px{margin-top:-1px}.sm\:-mr-px{margin-right:-1px}.sm\:-mb-px{margin-bottom:-1px}.sm\:-ml-px{margin-left:-1px}.sm\:max-h-full{max-height:100%}.sm\:max-h-screen{max-height:100vh}.sm\:max-w-none{max-width:none}.sm\:max-w-xs{max-width:20rem}.sm\:max-w-sm{max-width:24rem}.sm\:max-w-md{max-width:28rem}.sm\:max-w-lg{max-width:32rem}.sm\:max-w-xl{max-width:36rem}.sm\:max-w-2xl{max-width:42rem}.sm\:max-w-3xl{max-width:48rem}.sm\:max-w-4xl{max-width:56rem}.sm\:max-w-5xl{max-width:64rem}.sm\:max-w-6xl{max-width:72rem}.sm\:max-w-full{max-width:100%}.sm\:max-w-screen-sm{max-width:640px}.sm\:max-w-screen-md{max-width:768px}.sm\:max-w-screen-lg{max-width:1024px}.sm\:max-w-screen-xl{max-width:1280px}.sm\:min-h-0{min-height:0}.sm\:min-h-full{min-height:100%}.sm\:min-h-screen{min-height:100vh}.sm\:min-w-0{min-width:0}.sm\:min-w-full{min-width:100%}.sm\:object-contain{object-fit:contain}.sm\:object-cover{object-fit:cover}.sm\:object-fill{object-fit:fill}.sm\:object-none{object-fit:none}.sm\:object-scale-down{object-fit:scale-down}.sm\:object-bottom{object-position:bottom}.sm\:object-center{object-position:center}.sm\:object-left{object-position:left}.sm\:object-left-bottom{object-position:left bottom}.sm\:object-left-top{object-position:left top}.sm\:object-right{object-position:right}.sm\:object-right-bottom{object-position:right bottom}.sm\:object-right-top{object-position:right top}.sm\:object-top{object-position:top}.sm\:opacity-0{opacity:0}.sm\:opacity-25{opacity:.25}.sm\:opacity-50{opacity:.5}.sm\:opacity-75{opacity:.75}.sm\:opacity-100{opacity:1}.sm\:hover\:opacity-0:hover{opacity:0}.sm\:hover\:opacity-25:hover{opacity:.25}.sm\:hover\:opacity-50:hover{opacity:.5}.sm\:hover\:opacity-75:hover{opacity:.75}.sm\:hover\:opacity-100:hover{opacity:1}.sm\:focus\:opacity-0:focus{opacity:0}.sm\:focus\:opacity-25:focus{opacity:.25}.sm\:focus\:opacity-50:focus{opacity:.5}.sm\:focus\:opacity-75:focus{opacity:.75}.sm\:focus\:opacity-100:focus{opacity:1}.sm\:outline-none{outline:2px solid transparent;outline-offset:2px}.sm\:outline-white{outline:2px dotted #fff;outline-offset:2px}.sm\:outline-black{outline:2px dotted #000;outline-offset:2px}.sm\:focus\:outline-none:focus{outline:2px solid transparent;outline-offset:2px}.sm\:focus\:outline-white:focus{outline:2px dotted #fff;outline-offset:2px}.sm\:focus\:outline-black:focus{outline:2px dotted #000;outline-offset:2px}.sm\:overflow-auto{overflow:auto}.sm\:overflow-hidden{overflow:hidden}.sm\:overflow-visible{overflow:visible}.sm\:overflow-scroll{overflow:scroll}.sm\:overflow-x-auto{overflow-x:auto}.sm\:overflow-y-auto{overflow-y:auto}.sm\:overflow-x-hidden{overflow-x:hidden}.sm\:overflow-y-hidden{overflow-y:hidden}.sm\:overflow-x-visible{overflow-x:visible}.sm\:overflow-y-visible{overflow-y:visible}.sm\:overflow-x-scroll{overflow-x:scroll}.sm\:overflow-y-scroll{overflow-y:scroll}.sm\:scrolling-touch{-webkit-overflow-scrolling:touch}.sm\:scrolling-auto{-webkit-overflow-scrolling:auto}.sm\:overscroll-auto{-ms-scroll-chaining:chained;overscroll-behavior:auto}.sm\:overscroll-contain{-ms-scroll-chaining:none;overscroll-behavior:contain}.sm\:overscroll-none{-ms-scroll-chaining:none;overscroll-behavior:none}.sm\:overscroll-y-auto{overscroll-behavior-y:auto}.sm\:overscroll-y-contain{overscroll-behavior-y:contain}.sm\:overscroll-y-none{overscroll-behavior-y:none}.sm\:overscroll-x-auto{overscroll-behavior-x:auto}.sm\:overscroll-x-contain{overscroll-behavior-x:contain}.sm\:overscroll-x-none{overscroll-behavior-x:none}.sm\:p-0{padding:0}.sm\:p-1{padding:.25rem}.sm\:p-2{padding:.5rem}.sm\:p-3{padding:.75rem}.sm\:p-4{padding:1rem}.sm\:p-5{padding:1.25rem}.sm\:p-6{padding:1.5rem}.sm\:p-8{padding:2rem}.sm\:p-10{padding:2.5rem}.sm\:p-12{padding:3rem}.sm\:p-16{padding:4rem}.sm\:p-20{padding:5rem}.sm\:p-24{padding:6rem}.sm\:p-32{padding:8rem}.sm\:p-40{padding:10rem}.sm\:p-48{padding:12rem}.sm\:p-56{padding:14rem}.sm\:p-64{padding:16rem}.sm\:p-px{padding:1px}.sm\:py-0{padding-top:0;padding-bottom:0}.sm\:px-0{padding-left:0;padding-right:0}.sm\:py-1{padding-top:.25rem;padding-bottom:.25rem}.sm\:px-1{padding-left:.25rem;padding-right:.25rem}.sm\:py-2{padding-top:.5rem;padding-bottom:.5rem}.sm\:px-2{padding-left:.5rem;padding-right:.5rem}.sm\:py-3{padding-top:.75rem;padding-bottom:.75rem}.sm\:px-3{padding-left:.75rem;padding-right:.75rem}.sm\:py-4{padding-top:1rem;padding-bottom:1rem}.sm\:px-4{padding-left:1rem;padding-right:1rem}.sm\:py-5{padding-top:1.25rem;padding-bottom:1.25rem}.sm\:px-5{padding-left:1.25rem;padding-right:1.25rem}.sm\:py-6{padding-top:1.5rem;padding-bottom:1.5rem}.sm\:px-6{padding-left:1.5rem;padding-right:1.5rem}.sm\:py-8{padding-top:2rem;padding-bottom:2rem}.sm\:px-8{padding-left:2rem;padding-right:2rem}.sm\:py-10{padding-top:2.5rem;padding-bottom:2.5rem}.sm\:px-10{padding-left:2.5rem;padding-right:2.5rem}.sm\:py-12{padding-top:3rem;padding-bottom:3rem}.sm\:px-12{padding-left:3rem;padding-right:3rem}.sm\:py-16{padding-top:4rem;padding-bottom:4rem}.sm\:px-16{padding-left:4rem;padding-right:4rem}.sm\:py-20{padding-top:5rem;padding-bottom:5rem}.sm\:px-20{padding-left:5rem;padding-right:5rem}.sm\:py-24{padding-top:6rem;padding-bottom:6rem}.sm\:px-24{padding-left:6rem;padding-right:6rem}.sm\:py-32{padding-top:8rem;padding-bottom:8rem}.sm\:px-32{padding-left:8rem;padding-right:8rem}.sm\:py-40{padding-top:10rem;padding-bottom:10rem}.sm\:px-40{padding-left:10rem;padding-right:10rem}.sm\:py-48{padding-top:12rem;padding-bottom:12rem}.sm\:px-48{padding-left:12rem;padding-right:12rem}.sm\:py-56{padding-top:14rem;padding-bottom:14rem}.sm\:px-56{padding-left:14rem;padding-right:14rem}.sm\:py-64{padding-top:16rem;padding-bottom:16rem}.sm\:px-64{padding-left:16rem;padding-right:16rem}.sm\:py-px{padding-top:1px;padding-bottom:1px}.sm\:px-px{padding-left:1px;padding-right:1px}.sm\:pt-0{padding-top:0}.sm\:pr-0{padding-right:0}.sm\:pb-0{padding-bottom:0}.sm\:pl-0{padding-left:0}.sm\:pt-1{padding-top:.25rem}.sm\:pr-1{padding-right:.25rem}.sm\:pb-1{padding-bottom:.25rem}.sm\:pl-1{padding-left:.25rem}.sm\:pt-2{padding-top:.5rem}.sm\:pr-2{padding-right:.5rem}.sm\:pb-2{padding-bottom:.5rem}.sm\:pl-2{padding-left:.5rem}.sm\:pt-3{padding-top:.75rem}.sm\:pr-3{padding-right:.75rem}.sm\:pb-3{padding-bottom:.75rem}.sm\:pl-3{padding-left:.75rem}.sm\:pt-4{padding-top:1rem}.sm\:pr-4{padding-right:1rem}.sm\:pb-4{padding-bottom:1rem}.sm\:pl-4{padding-left:1rem}.sm\:pt-5{padding-top:1.25rem}.sm\:pr-5{padding-right:1.25rem}.sm\:pb-5{padding-bottom:1.25rem}.sm\:pl-5{padding-left:1.25rem}.sm\:pt-6{padding-top:1.5rem}.sm\:pr-6{padding-right:1.5rem}.sm\:pb-6{padding-bottom:1.5rem}.sm\:pl-6{padding-left:1.5rem}.sm\:pt-8{padding-top:2rem}.sm\:pr-8{padding-right:2rem}.sm\:pb-8{padding-bottom:2rem}.sm\:pl-8{padding-left:2rem}.sm\:pt-10{padding-top:2.5rem}.sm\:pr-10{padding-right:2.5rem}.sm\:pb-10{padding-bottom:2.5rem}.sm\:pl-10{padding-left:2.5rem}.sm\:pt-12{padding-top:3rem}.sm\:pr-12{padding-right:3rem}.sm\:pb-12{padding-bottom:3rem}.sm\:pl-12{padding-left:3rem}.sm\:pt-16{padding-top:4rem}.sm\:pr-16{padding-right:4rem}.sm\:pb-16{padding-bottom:4rem}.sm\:pl-16{padding-left:4rem}.sm\:pt-20{padding-top:5rem}.sm\:pr-20{padding-right:5rem}.sm\:pb-20{padding-bottom:5rem}.sm\:pl-20{padding-left:5rem}.sm\:pt-24{padding-top:6rem}.sm\:pr-24{padding-right:6rem}.sm\:pb-24{padding-bottom:6rem}.sm\:pl-24{padding-left:6rem}.sm\:pt-32{padding-top:8rem}.sm\:pr-32{padding-right:8rem}.sm\:pb-32{padding-bottom:8rem}.sm\:pl-32{padding-left:8rem}.sm\:pt-40{padding-top:10rem}.sm\:pr-40{padding-right:10rem}.sm\:pb-40{padding-bottom:10rem}.sm\:pl-40{padding-left:10rem}.sm\:pt-48{padding-top:12rem}.sm\:pr-48{padding-right:12rem}.sm\:pb-48{padding-bottom:12rem}.sm\:pl-48{padding-left:12rem}.sm\:pt-56{padding-top:14rem}.sm\:pr-56{padding-right:14rem}.sm\:pb-56{padding-bottom:14rem}.sm\:pl-56{padding-left:14rem}.sm\:pt-64{padding-top:16rem}.sm\:pr-64{padding-right:16rem}.sm\:pb-64{padding-bottom:16rem}.sm\:pl-64{padding-left:16rem}.sm\:pt-px{padding-top:1px}.sm\:pr-px{padding-right:1px}.sm\:pb-px{padding-bottom:1px}.sm\:pl-px{padding-left:1px}.sm\:placeholder-transparent:-ms-input-placeholder{color:transparent}.sm\:placeholder-transparent::-ms-input-placeholder{color:transparent}.sm\:placeholder-transparent::placeholder{color:transparent}.sm\:placeholder-current:-ms-input-placeholder{color:currentColor}.sm\:placeholder-current::-ms-input-placeholder{color:currentColor}.sm\:placeholder-current::placeholder{color:currentColor}.sm\:placeholder-black:-ms-input-placeholder{--placeholder-opacity:1;color:#000;color:rgba(0,0,0,var(--placeholder-opacity))}.sm\:placeholder-black::-ms-input-placeholder{--placeholder-opacity:1;color:#000;color:rgba(0,0,0,var(--placeholder-opacity))}.sm\:placeholder-black::placeholder{--placeholder-opacity:1;color:#000;color:rgba(0,0,0,var(--placeholder-opacity))}.sm\:placeholder-white:-ms-input-placeholder{--placeholder-opacity:1;color:#fff;color:rgba(255,255,255,var(--placeholder-opacity))}.sm\:placeholder-white::-ms-input-placeholder{--placeholder-opacity:1;color:#fff;color:rgba(255,255,255,var(--placeholder-opacity))}.sm\:placeholder-white::placeholder{--placeholder-opacity:1;color:#fff;color:rgba(255,255,255,var(--placeholder-opacity))}.sm\:placeholder-gray-100:-ms-input-placeholder{--placeholder-opacity:1;color:#f7fafc;color:rgba(247,250,252,var(--placeholder-opacity))}.sm\:placeholder-gray-100::-ms-input-placeholder{--placeholder-opacity:1;color:#f7fafc;color:rgba(247,250,252,var(--placeholder-opacity))}.sm\:placeholder-gray-100::placeholder{--placeholder-opacity:1;color:#f7fafc;color:rgba(247,250,252,var(--placeholder-opacity))}.sm\:placeholder-gray-200:-ms-input-placeholder{--placeholder-opacity:1;color:#edf2f7;color:rgba(237,242,247,var(--placeholder-opacity))}.sm\:placeholder-gray-200::-ms-input-placeholder{--placeholder-opacity:1;color:#edf2f7;color:rgba(237,242,247,var(--placeholder-opacity))}.sm\:placeholder-gray-200::placeholder{--placeholder-opacity:1;color:#edf2f7;color:rgba(237,242,247,var(--placeholder-opacity))}.sm\:placeholder-gray-300:-ms-input-placeholder{--placeholder-opacity:1;color:#e2e8f0;color:rgba(226,232,240,var(--placeholder-opacity))}.sm\:placeholder-gray-300::-ms-input-placeholder{--placeholder-opacity:1;color:#e2e8f0;color:rgba(226,232,240,var(--placeholder-opacity))}.sm\:placeholder-gray-300::placeholder{--placeholder-opacity:1;color:#e2e8f0;color:rgba(226,232,240,var(--placeholder-opacity))}.sm\:placeholder-gray-400:-ms-input-placeholder{--placeholder-opacity:1;color:#cbd5e0;color:rgba(203,213,224,var(--placeholder-opacity))}.sm\:placeholder-gray-400::-ms-input-placeholder{--placeholder-opacity:1;color:#cbd5e0;color:rgba(203,213,224,var(--placeholder-opacity))}.sm\:placeholder-gray-400::placeholder{--placeholder-opacity:1;color:#cbd5e0;color:rgba(203,213,224,var(--placeholder-opacity))}.sm\:placeholder-gray-500:-ms-input-placeholder{--placeholder-opacity:1;color:#a0aec0;color:rgba(160,174,192,var(--placeholder-opacity))}.sm\:placeholder-gray-500::-ms-input-placeholder{--placeholder-opacity:1;color:#a0aec0;color:rgba(160,174,192,var(--placeholder-opacity))}.sm\:placeholder-gray-500::placeholder{--placeholder-opacity:1;color:#a0aec0;color:rgba(160,174,192,var(--placeholder-opacity))}.sm\:placeholder-gray-600:-ms-input-placeholder{--placeholder-opacity:1;color:#718096;color:rgba(113,128,150,var(--placeholder-opacity))}.sm\:placeholder-gray-600::-ms-input-placeholder{--placeholder-opacity:1;color:#718096;color:rgba(113,128,150,var(--placeholder-opacity))}.sm\:placeholder-gray-600::placeholder{--placeholder-opacity:1;color:#718096;color:rgba(113,128,150,var(--placeholder-opacity))}.sm\:placeholder-gray-700:-ms-input-placeholder{--placeholder-opacity:1;color:#4a5568;color:rgba(74,85,104,var(--placeholder-opacity))}.sm\:placeholder-gray-700::-ms-input-placeholder{--placeholder-opacity:1;color:#4a5568;color:rgba(74,85,104,var(--placeholder-opacity))}.sm\:placeholder-gray-700::placeholder{--placeholder-opacity:1;color:#4a5568;color:rgba(74,85,104,var(--placeholder-opacity))}.sm\:placeholder-gray-800:-ms-input-placeholder{--placeholder-opacity:1;color:#2d3748;color:rgba(45,55,72,var(--placeholder-opacity))}.sm\:placeholder-gray-800::-ms-input-placeholder{--placeholder-opacity:1;color:#2d3748;color:rgba(45,55,72,var(--placeholder-opacity))}.sm\:placeholder-gray-800::placeholder{--placeholder-opacity:1;color:#2d3748;color:rgba(45,55,72,var(--placeholder-opacity))}.sm\:placeholder-gray-900:-ms-input-placeholder{--placeholder-opacity:1;color:#1a202c;color:rgba(26,32,44,var(--placeholder-opacity))}.sm\:placeholder-gray-900::-ms-input-placeholder{--placeholder-opacity:1;color:#1a202c;color:rgba(26,32,44,var(--placeholder-opacity))}.sm\:placeholder-gray-900::placeholder{--placeholder-opacity:1;color:#1a202c;color:rgba(26,32,44,var(--placeholder-opacity))}.sm\:placeholder-red-100:-ms-input-placeholder{--placeholder-opacity:1;color:#fff5f5;color:rgba(255,245,245,var(--placeholder-opacity))}.sm\:placeholder-red-100::-ms-input-placeholder{--placeholder-opacity:1;color:#fff5f5;color:rgba(255,245,245,var(--placeholder-opacity))}.sm\:placeholder-red-100::placeholder{--placeholder-opacity:1;color:#fff5f5;color:rgba(255,245,245,var(--placeholder-opacity))}.sm\:placeholder-red-200:-ms-input-placeholder{--placeholder-opacity:1;color:#fed7d7;color:rgba(254,215,215,var(--placeholder-opacity))}.sm\:placeholder-red-200::-ms-input-placeholder{--placeholder-opacity:1;color:#fed7d7;color:rgba(254,215,215,var(--placeholder-opacity))}.sm\:placeholder-red-200::placeholder{--placeholder-opacity:1;color:#fed7d7;color:rgba(254,215,215,var(--placeholder-opacity))}.sm\:placeholder-red-300:-ms-input-placeholder{--placeholder-opacity:1;color:#feb2b2;color:rgba(254,178,178,var(--placeholder-opacity))}.sm\:placeholder-red-300::-ms-input-placeholder{--placeholder-opacity:1;color:#feb2b2;color:rgba(254,178,178,var(--placeholder-opacity))}.sm\:placeholder-red-300::placeholder{--placeholder-opacity:1;color:#feb2b2;color:rgba(254,178,178,var(--placeholder-opacity))}.sm\:placeholder-red-400:-ms-input-placeholder{--placeholder-opacity:1;color:#fc8181;color:rgba(252,129,129,var(--placeholder-opacity))}.sm\:placeholder-red-400::-ms-input-placeholder{--placeholder-opacity:1;color:#fc8181;color:rgba(252,129,129,var(--placeholder-opacity))}.sm\:placeholder-red-400::placeholder{--placeholder-opacity:1;color:#fc8181;color:rgba(252,129,129,var(--placeholder-opacity))}.sm\:placeholder-red-500:-ms-input-placeholder{--placeholder-opacity:1;color:#f56565;color:rgba(245,101,101,var(--placeholder-opacity))}.sm\:placeholder-red-500::-ms-input-placeholder{--placeholder-opacity:1;color:#f56565;color:rgba(245,101,101,var(--placeholder-opacity))}.sm\:placeholder-red-500::placeholder{--placeholder-opacity:1;color:#f56565;color:rgba(245,101,101,var(--placeholder-opacity))}.sm\:placeholder-red-600:-ms-input-placeholder{--placeholder-opacity:1;color:#e53e3e;color:rgba(229,62,62,var(--placeholder-opacity))}.sm\:placeholder-red-600::-ms-input-placeholder{--placeholder-opacity:1;color:#e53e3e;color:rgba(229,62,62,var(--placeholder-opacity))}.sm\:placeholder-red-600::placeholder{--placeholder-opacity:1;color:#e53e3e;color:rgba(229,62,62,var(--placeholder-opacity))}.sm\:placeholder-red-700:-ms-input-placeholder{--placeholder-opacity:1;color:#c53030;color:rgba(197,48,48,var(--placeholder-opacity))}.sm\:placeholder-red-700::-ms-input-placeholder{--placeholder-opacity:1;color:#c53030;color:rgba(197,48,48,var(--placeholder-opacity))}.sm\:placeholder-red-700::placeholder{--placeholder-opacity:1;color:#c53030;color:rgba(197,48,48,var(--placeholder-opacity))}.sm\:placeholder-red-800:-ms-input-placeholder{--placeholder-opacity:1;color:#9b2c2c;color:rgba(155,44,44,var(--placeholder-opacity))}.sm\:placeholder-red-800::-ms-input-placeholder{--placeholder-opacity:1;color:#9b2c2c;color:rgba(155,44,44,var(--placeholder-opacity))}.sm\:placeholder-red-800::placeholder{--placeholder-opacity:1;color:#9b2c2c;color:rgba(155,44,44,var(--placeholder-opacity))}.sm\:placeholder-red-900:-ms-input-placeholder{--placeholder-opacity:1;color:#742a2a;color:rgba(116,42,42,var(--placeholder-opacity))}.sm\:placeholder-red-900::-ms-input-placeholder{--placeholder-opacity:1;color:#742a2a;color:rgba(116,42,42,var(--placeholder-opacity))}.sm\:placeholder-red-900::placeholder{--placeholder-opacity:1;color:#742a2a;color:rgba(116,42,42,var(--placeholder-opacity))}.sm\:placeholder-orange-100:-ms-input-placeholder{--placeholder-opacity:1;color:#fffaf0;color:rgba(255,250,240,var(--placeholder-opacity))}.sm\:placeholder-orange-100::-ms-input-placeholder{--placeholder-opacity:1;color:#fffaf0;color:rgba(255,250,240,var(--placeholder-opacity))}.sm\:placeholder-orange-100::placeholder{--placeholder-opacity:1;color:#fffaf0;color:rgba(255,250,240,var(--placeholder-opacity))}.sm\:placeholder-orange-200:-ms-input-placeholder{--placeholder-opacity:1;color:#feebc8;color:rgba(254,235,200,var(--placeholder-opacity))}.sm\:placeholder-orange-200::-ms-input-placeholder{--placeholder-opacity:1;color:#feebc8;color:rgba(254,235,200,var(--placeholder-opacity))}.sm\:placeholder-orange-200::placeholder{--placeholder-opacity:1;color:#feebc8;color:rgba(254,235,200,var(--placeholder-opacity))}.sm\:placeholder-orange-300:-ms-input-placeholder{--placeholder-opacity:1;color:#fbd38d;color:rgba(251,211,141,var(--placeholder-opacity))}.sm\:placeholder-orange-300::-ms-input-placeholder{--placeholder-opacity:1;color:#fbd38d;color:rgba(251,211,141,var(--placeholder-opacity))}.sm\:placeholder-orange-300::placeholder{--placeholder-opacity:1;color:#fbd38d;color:rgba(251,211,141,var(--placeholder-opacity))}.sm\:placeholder-orange-400:-ms-input-placeholder{--placeholder-opacity:1;color:#f6ad55;color:rgba(246,173,85,var(--placeholder-opacity))}.sm\:placeholder-orange-400::-ms-input-placeholder{--placeholder-opacity:1;color:#f6ad55;color:rgba(246,173,85,var(--placeholder-opacity))}.sm\:placeholder-orange-400::placeholder{--placeholder-opacity:1;color:#f6ad55;color:rgba(246,173,85,var(--placeholder-opacity))}.sm\:placeholder-orange-500:-ms-input-placeholder{--placeholder-opacity:1;color:#ed8936;color:rgba(237,137,54,var(--placeholder-opacity))}.sm\:placeholder-orange-500::-ms-input-placeholder{--placeholder-opacity:1;color:#ed8936;color:rgba(237,137,54,var(--placeholder-opacity))}.sm\:placeholder-orange-500::placeholder{--placeholder-opacity:1;color:#ed8936;color:rgba(237,137,54,var(--placeholder-opacity))}.sm\:placeholder-orange-600:-ms-input-placeholder{--placeholder-opacity:1;color:#dd6b20;color:rgba(221,107,32,var(--placeholder-opacity))}.sm\:placeholder-orange-600::-ms-input-placeholder{--placeholder-opacity:1;color:#dd6b20;color:rgba(221,107,32,var(--placeholder-opacity))}.sm\:placeholder-orange-600::placeholder{--placeholder-opacity:1;color:#dd6b20;color:rgba(221,107,32,var(--placeholder-opacity))}.sm\:placeholder-orange-700:-ms-input-placeholder{--placeholder-opacity:1;color:#c05621;color:rgba(192,86,33,var(--placeholder-opacity))}.sm\:placeholder-orange-700::-ms-input-placeholder{--placeholder-opacity:1;color:#c05621;color:rgba(192,86,33,var(--placeholder-opacity))}.sm\:placeholder-orange-700::placeholder{--placeholder-opacity:1;color:#c05621;color:rgba(192,86,33,var(--placeholder-opacity))}.sm\:placeholder-orange-800:-ms-input-placeholder{--placeholder-opacity:1;color:#9c4221;color:rgba(156,66,33,var(--placeholder-opacity))}.sm\:placeholder-orange-800::-ms-input-placeholder{--placeholder-opacity:1;color:#9c4221;color:rgba(156,66,33,var(--placeholder-opacity))}.sm\:placeholder-orange-800::placeholder{--placeholder-opacity:1;color:#9c4221;color:rgba(156,66,33,var(--placeholder-opacity))}.sm\:placeholder-orange-900:-ms-input-placeholder{--placeholder-opacity:1;color:#7b341e;color:rgba(123,52,30,var(--placeholder-opacity))}.sm\:placeholder-orange-900::-ms-input-placeholder{--placeholder-opacity:1;color:#7b341e;color:rgba(123,52,30,var(--placeholder-opacity))}.sm\:placeholder-orange-900::placeholder{--placeholder-opacity:1;color:#7b341e;color:rgba(123,52,30,var(--placeholder-opacity))}.sm\:placeholder-yellow-100:-ms-input-placeholder{--placeholder-opacity:1;color:ivory;color:rgba(255,255,240,var(--placeholder-opacity))}.sm\:placeholder-yellow-100::-ms-input-placeholder{--placeholder-opacity:1;color:ivory;color:rgba(255,255,240,var(--placeholder-opacity))}.sm\:placeholder-yellow-100::placeholder{--placeholder-opacity:1;color:ivory;color:rgba(255,255,240,var(--placeholder-opacity))}.sm\:placeholder-yellow-200:-ms-input-placeholder{--placeholder-opacity:1;color:#fefcbf;color:rgba(254,252,191,var(--placeholder-opacity))}.sm\:placeholder-yellow-200::-ms-input-placeholder{--placeholder-opacity:1;color:#fefcbf;color:rgba(254,252,191,var(--placeholder-opacity))}.sm\:placeholder-yellow-200::placeholder{--placeholder-opacity:1;color:#fefcbf;color:rgba(254,252,191,var(--placeholder-opacity))}.sm\:placeholder-yellow-300:-ms-input-placeholder{--placeholder-opacity:1;color:#faf089;color:rgba(250,240,137,var(--placeholder-opacity))}.sm\:placeholder-yellow-300::-ms-input-placeholder{--placeholder-opacity:1;color:#faf089;color:rgba(250,240,137,var(--placeholder-opacity))}.sm\:placeholder-yellow-300::placeholder{--placeholder-opacity:1;color:#faf089;color:rgba(250,240,137,var(--placeholder-opacity))}.sm\:placeholder-yellow-400:-ms-input-placeholder{--placeholder-opacity:1;color:#f6e05e;color:rgba(246,224,94,var(--placeholder-opacity))}.sm\:placeholder-yellow-400::-ms-input-placeholder{--placeholder-opacity:1;color:#f6e05e;color:rgba(246,224,94,var(--placeholder-opacity))}.sm\:placeholder-yellow-400::placeholder{--placeholder-opacity:1;color:#f6e05e;color:rgba(246,224,94,var(--placeholder-opacity))}.sm\:placeholder-yellow-500:-ms-input-placeholder{--placeholder-opacity:1;color:#ecc94b;color:rgba(236,201,75,var(--placeholder-opacity))}.sm\:placeholder-yellow-500::-ms-input-placeholder{--placeholder-opacity:1;color:#ecc94b;color:rgba(236,201,75,var(--placeholder-opacity))}.sm\:placeholder-yellow-500::placeholder{--placeholder-opacity:1;color:#ecc94b;color:rgba(236,201,75,var(--placeholder-opacity))}.sm\:placeholder-yellow-600:-ms-input-placeholder{--placeholder-opacity:1;color:#d69e2e;color:rgba(214,158,46,var(--placeholder-opacity))}.sm\:placeholder-yellow-600::-ms-input-placeholder{--placeholder-opacity:1;color:#d69e2e;color:rgba(214,158,46,var(--placeholder-opacity))}.sm\:placeholder-yellow-600::placeholder{--placeholder-opacity:1;color:#d69e2e;color:rgba(214,158,46,var(--placeholder-opacity))}.sm\:placeholder-yellow-700:-ms-input-placeholder{--placeholder-opacity:1;color:#b7791f;color:rgba(183,121,31,var(--placeholder-opacity))}.sm\:placeholder-yellow-700::-ms-input-placeholder{--placeholder-opacity:1;color:#b7791f;color:rgba(183,121,31,var(--placeholder-opacity))}.sm\:placeholder-yellow-700::placeholder{--placeholder-opacity:1;color:#b7791f;color:rgba(183,121,31,var(--placeholder-opacity))}.sm\:placeholder-yellow-800:-ms-input-placeholder{--placeholder-opacity:1;color:#975a16;color:rgba(151,90,22,var(--placeholder-opacity))}.sm\:placeholder-yellow-800::-ms-input-placeholder{--placeholder-opacity:1;color:#975a16;color:rgba(151,90,22,var(--placeholder-opacity))}.sm\:placeholder-yellow-800::placeholder{--placeholder-opacity:1;color:#975a16;color:rgba(151,90,22,var(--placeholder-opacity))}.sm\:placeholder-yellow-900:-ms-input-placeholder{--placeholder-opacity:1;color:#744210;color:rgba(116,66,16,var(--placeholder-opacity))}.sm\:placeholder-yellow-900::-ms-input-placeholder{--placeholder-opacity:1;color:#744210;color:rgba(116,66,16,var(--placeholder-opacity))}.sm\:placeholder-yellow-900::placeholder{--placeholder-opacity:1;color:#744210;color:rgba(116,66,16,var(--placeholder-opacity))}.sm\:placeholder-green-100:-ms-input-placeholder{--placeholder-opacity:1;color:#f0fff4;color:rgba(240,255,244,var(--placeholder-opacity))}.sm\:placeholder-green-100::-ms-input-placeholder{--placeholder-opacity:1;color:#f0fff4;color:rgba(240,255,244,var(--placeholder-opacity))}.sm\:placeholder-green-100::placeholder{--placeholder-opacity:1;color:#f0fff4;color:rgba(240,255,244,var(--placeholder-opacity))}.sm\:placeholder-green-200:-ms-input-placeholder{--placeholder-opacity:1;color:#c6f6d5;color:rgba(198,246,213,var(--placeholder-opacity))}.sm\:placeholder-green-200::-ms-input-placeholder{--placeholder-opacity:1;color:#c6f6d5;color:rgba(198,246,213,var(--placeholder-opacity))}.sm\:placeholder-green-200::placeholder{--placeholder-opacity:1;color:#c6f6d5;color:rgba(198,246,213,var(--placeholder-opacity))}.sm\:placeholder-green-300:-ms-input-placeholder{--placeholder-opacity:1;color:#9ae6b4;color:rgba(154,230,180,var(--placeholder-opacity))}.sm\:placeholder-green-300::-ms-input-placeholder{--placeholder-opacity:1;color:#9ae6b4;color:rgba(154,230,180,var(--placeholder-opacity))}.sm\:placeholder-green-300::placeholder{--placeholder-opacity:1;color:#9ae6b4;color:rgba(154,230,180,var(--placeholder-opacity))}.sm\:placeholder-green-400:-ms-input-placeholder{--placeholder-opacity:1;color:#68d391;color:rgba(104,211,145,var(--placeholder-opacity))}.sm\:placeholder-green-400::-ms-input-placeholder{--placeholder-opacity:1;color:#68d391;color:rgba(104,211,145,var(--placeholder-opacity))}.sm\:placeholder-green-400::placeholder{--placeholder-opacity:1;color:#68d391;color:rgba(104,211,145,var(--placeholder-opacity))}.sm\:placeholder-green-500:-ms-input-placeholder{--placeholder-opacity:1;color:#48bb78;color:rgba(72,187,120,var(--placeholder-opacity))}.sm\:placeholder-green-500::-ms-input-placeholder{--placeholder-opacity:1;color:#48bb78;color:rgba(72,187,120,var(--placeholder-opacity))}.sm\:placeholder-green-500::placeholder{--placeholder-opacity:1;color:#48bb78;color:rgba(72,187,120,var(--placeholder-opacity))}.sm\:placeholder-green-600:-ms-input-placeholder{--placeholder-opacity:1;color:#38a169;color:rgba(56,161,105,var(--placeholder-opacity))}.sm\:placeholder-green-600::-ms-input-placeholder{--placeholder-opacity:1;color:#38a169;color:rgba(56,161,105,var(--placeholder-opacity))}.sm\:placeholder-green-600::placeholder{--placeholder-opacity:1;color:#38a169;color:rgba(56,161,105,var(--placeholder-opacity))}.sm\:placeholder-green-700:-ms-input-placeholder{--placeholder-opacity:1;color:#2f855a;color:rgba(47,133,90,var(--placeholder-opacity))}.sm\:placeholder-green-700::-ms-input-placeholder{--placeholder-opacity:1;color:#2f855a;color:rgba(47,133,90,var(--placeholder-opacity))}.sm\:placeholder-green-700::placeholder{--placeholder-opacity:1;color:#2f855a;color:rgba(47,133,90,var(--placeholder-opacity))}.sm\:placeholder-green-800:-ms-input-placeholder{--placeholder-opacity:1;color:#276749;color:rgba(39,103,73,var(--placeholder-opacity))}.sm\:placeholder-green-800::-ms-input-placeholder{--placeholder-opacity:1;color:#276749;color:rgba(39,103,73,var(--placeholder-opacity))}.sm\:placeholder-green-800::placeholder{--placeholder-opacity:1;color:#276749;color:rgba(39,103,73,var(--placeholder-opacity))}.sm\:placeholder-green-900:-ms-input-placeholder{--placeholder-opacity:1;color:#22543d;color:rgba(34,84,61,var(--placeholder-opacity))}.sm\:placeholder-green-900::-ms-input-placeholder{--placeholder-opacity:1;color:#22543d;color:rgba(34,84,61,var(--placeholder-opacity))}.sm\:placeholder-green-900::placeholder{--placeholder-opacity:1;color:#22543d;color:rgba(34,84,61,var(--placeholder-opacity))}.sm\:placeholder-teal-100:-ms-input-placeholder{--placeholder-opacity:1;color:#e6fffa;color:rgba(230,255,250,var(--placeholder-opacity))}.sm\:placeholder-teal-100::-ms-input-placeholder{--placeholder-opacity:1;color:#e6fffa;color:rgba(230,255,250,var(--placeholder-opacity))}.sm\:placeholder-teal-100::placeholder{--placeholder-opacity:1;color:#e6fffa;color:rgba(230,255,250,var(--placeholder-opacity))}.sm\:placeholder-teal-200:-ms-input-placeholder{--placeholder-opacity:1;color:#b2f5ea;color:rgba(178,245,234,var(--placeholder-opacity))}.sm\:placeholder-teal-200::-ms-input-placeholder{--placeholder-opacity:1;color:#b2f5ea;color:rgba(178,245,234,var(--placeholder-opacity))}.sm\:placeholder-teal-200::placeholder{--placeholder-opacity:1;color:#b2f5ea;color:rgba(178,245,234,var(--placeholder-opacity))}.sm\:placeholder-teal-300:-ms-input-placeholder{--placeholder-opacity:1;color:#81e6d9;color:rgba(129,230,217,var(--placeholder-opacity))}.sm\:placeholder-teal-300::-ms-input-placeholder{--placeholder-opacity:1;color:#81e6d9;color:rgba(129,230,217,var(--placeholder-opacity))}.sm\:placeholder-teal-300::placeholder{--placeholder-opacity:1;color:#81e6d9;color:rgba(129,230,217,var(--placeholder-opacity))}.sm\:placeholder-teal-400:-ms-input-placeholder{--placeholder-opacity:1;color:#4fd1c5;color:rgba(79,209,197,var(--placeholder-opacity))}.sm\:placeholder-teal-400::-ms-input-placeholder{--placeholder-opacity:1;color:#4fd1c5;color:rgba(79,209,197,var(--placeholder-opacity))}.sm\:placeholder-teal-400::placeholder{--placeholder-opacity:1;color:#4fd1c5;color:rgba(79,209,197,var(--placeholder-opacity))}.sm\:placeholder-teal-500:-ms-input-placeholder{--placeholder-opacity:1;color:#38b2ac;color:rgba(56,178,172,var(--placeholder-opacity))}.sm\:placeholder-teal-500::-ms-input-placeholder{--placeholder-opacity:1;color:#38b2ac;color:rgba(56,178,172,var(--placeholder-opacity))}.sm\:placeholder-teal-500::placeholder{--placeholder-opacity:1;color:#38b2ac;color:rgba(56,178,172,var(--placeholder-opacity))}.sm\:placeholder-teal-600:-ms-input-placeholder{--placeholder-opacity:1;color:#319795;color:rgba(49,151,149,var(--placeholder-opacity))}.sm\:placeholder-teal-600::-ms-input-placeholder{--placeholder-opacity:1;color:#319795;color:rgba(49,151,149,var(--placeholder-opacity))}.sm\:placeholder-teal-600::placeholder{--placeholder-opacity:1;color:#319795;color:rgba(49,151,149,var(--placeholder-opacity))}.sm\:placeholder-teal-700:-ms-input-placeholder{--placeholder-opacity:1;color:#2c7a7b;color:rgba(44,122,123,var(--placeholder-opacity))}.sm\:placeholder-teal-700::-ms-input-placeholder{--placeholder-opacity:1;color:#2c7a7b;color:rgba(44,122,123,var(--placeholder-opacity))}.sm\:placeholder-teal-700::placeholder{--placeholder-opacity:1;color:#2c7a7b;color:rgba(44,122,123,var(--placeholder-opacity))}.sm\:placeholder-teal-800:-ms-input-placeholder{--placeholder-opacity:1;color:#285e61;color:rgba(40,94,97,var(--placeholder-opacity))}.sm\:placeholder-teal-800::-ms-input-placeholder{--placeholder-opacity:1;color:#285e61;color:rgba(40,94,97,var(--placeholder-opacity))}.sm\:placeholder-teal-800::placeholder{--placeholder-opacity:1;color:#285e61;color:rgba(40,94,97,var(--placeholder-opacity))}.sm\:placeholder-teal-900:-ms-input-placeholder{--placeholder-opacity:1;color:#234e52;color:rgba(35,78,82,var(--placeholder-opacity))}.sm\:placeholder-teal-900::-ms-input-placeholder{--placeholder-opacity:1;color:#234e52;color:rgba(35,78,82,var(--placeholder-opacity))}.sm\:placeholder-teal-900::placeholder{--placeholder-opacity:1;color:#234e52;color:rgba(35,78,82,var(--placeholder-opacity))}.sm\:placeholder-blue-100:-ms-input-placeholder{--placeholder-opacity:1;color:#ebf8ff;color:rgba(235,248,255,var(--placeholder-opacity))}.sm\:placeholder-blue-100::-ms-input-placeholder{--placeholder-opacity:1;color:#ebf8ff;color:rgba(235,248,255,var(--placeholder-opacity))}.sm\:placeholder-blue-100::placeholder{--placeholder-opacity:1;color:#ebf8ff;color:rgba(235,248,255,var(--placeholder-opacity))}.sm\:placeholder-blue-200:-ms-input-placeholder{--placeholder-opacity:1;color:#bee3f8;color:rgba(190,227,248,var(--placeholder-opacity))}.sm\:placeholder-blue-200::-ms-input-placeholder{--placeholder-opacity:1;color:#bee3f8;color:rgba(190,227,248,var(--placeholder-opacity))}.sm\:placeholder-blue-200::placeholder{--placeholder-opacity:1;color:#bee3f8;color:rgba(190,227,248,var(--placeholder-opacity))}.sm\:placeholder-blue-300:-ms-input-placeholder{--placeholder-opacity:1;color:#90cdf4;color:rgba(144,205,244,var(--placeholder-opacity))}.sm\:placeholder-blue-300::-ms-input-placeholder{--placeholder-opacity:1;color:#90cdf4;color:rgba(144,205,244,var(--placeholder-opacity))}.sm\:placeholder-blue-300::placeholder{--placeholder-opacity:1;color:#90cdf4;color:rgba(144,205,244,var(--placeholder-opacity))}.sm\:placeholder-blue-400:-ms-input-placeholder{--placeholder-opacity:1;color:#63b3ed;color:rgba(99,179,237,var(--placeholder-opacity))}.sm\:placeholder-blue-400::-ms-input-placeholder{--placeholder-opacity:1;color:#63b3ed;color:rgba(99,179,237,var(--placeholder-opacity))}.sm\:placeholder-blue-400::placeholder{--placeholder-opacity:1;color:#63b3ed;color:rgba(99,179,237,var(--placeholder-opacity))}.sm\:placeholder-blue-500:-ms-input-placeholder{--placeholder-opacity:1;color:#4299e1;color:rgba(66,153,225,var(--placeholder-opacity))}.sm\:placeholder-blue-500::-ms-input-placeholder{--placeholder-opacity:1;color:#4299e1;color:rgba(66,153,225,var(--placeholder-opacity))}.sm\:placeholder-blue-500::placeholder{--placeholder-opacity:1;color:#4299e1;color:rgba(66,153,225,var(--placeholder-opacity))}.sm\:placeholder-blue-600:-ms-input-placeholder{--placeholder-opacity:1;color:#3182ce;color:rgba(49,130,206,var(--placeholder-opacity))}.sm\:placeholder-blue-600::-ms-input-placeholder{--placeholder-opacity:1;color:#3182ce;color:rgba(49,130,206,var(--placeholder-opacity))}.sm\:placeholder-blue-600::placeholder{--placeholder-opacity:1;color:#3182ce;color:rgba(49,130,206,var(--placeholder-opacity))}.sm\:placeholder-blue-700:-ms-input-placeholder{--placeholder-opacity:1;color:#2b6cb0;color:rgba(43,108,176,var(--placeholder-opacity))}.sm\:placeholder-blue-700::-ms-input-placeholder{--placeholder-opacity:1;color:#2b6cb0;color:rgba(43,108,176,var(--placeholder-opacity))}.sm\:placeholder-blue-700::placeholder{--placeholder-opacity:1;color:#2b6cb0;color:rgba(43,108,176,var(--placeholder-opacity))}.sm\:placeholder-blue-800:-ms-input-placeholder{--placeholder-opacity:1;color:#2c5282;color:rgba(44,82,130,var(--placeholder-opacity))}.sm\:placeholder-blue-800::-ms-input-placeholder{--placeholder-opacity:1;color:#2c5282;color:rgba(44,82,130,var(--placeholder-opacity))}.sm\:placeholder-blue-800::placeholder{--placeholder-opacity:1;color:#2c5282;color:rgba(44,82,130,var(--placeholder-opacity))}.sm\:placeholder-blue-900:-ms-input-placeholder{--placeholder-opacity:1;color:#2a4365;color:rgba(42,67,101,var(--placeholder-opacity))}.sm\:placeholder-blue-900::-ms-input-placeholder{--placeholder-opacity:1;color:#2a4365;color:rgba(42,67,101,var(--placeholder-opacity))}.sm\:placeholder-blue-900::placeholder{--placeholder-opacity:1;color:#2a4365;color:rgba(42,67,101,var(--placeholder-opacity))}.sm\:placeholder-indigo-100:-ms-input-placeholder{--placeholder-opacity:1;color:#ebf4ff;color:rgba(235,244,255,var(--placeholder-opacity))}.sm\:placeholder-indigo-100::-ms-input-placeholder{--placeholder-opacity:1;color:#ebf4ff;color:rgba(235,244,255,var(--placeholder-opacity))}.sm\:placeholder-indigo-100::placeholder{--placeholder-opacity:1;color:#ebf4ff;color:rgba(235,244,255,var(--placeholder-opacity))}.sm\:placeholder-indigo-200:-ms-input-placeholder{--placeholder-opacity:1;color:#c3dafe;color:rgba(195,218,254,var(--placeholder-opacity))}.sm\:placeholder-indigo-200::-ms-input-placeholder{--placeholder-opacity:1;color:#c3dafe;color:rgba(195,218,254,var(--placeholder-opacity))}.sm\:placeholder-indigo-200::placeholder{--placeholder-opacity:1;color:#c3dafe;color:rgba(195,218,254,var(--placeholder-opacity))}.sm\:placeholder-indigo-300:-ms-input-placeholder{--placeholder-opacity:1;color:#a3bffa;color:rgba(163,191,250,var(--placeholder-opacity))}.sm\:placeholder-indigo-300::-ms-input-placeholder{--placeholder-opacity:1;color:#a3bffa;color:rgba(163,191,250,var(--placeholder-opacity))}.sm\:placeholder-indigo-300::placeholder{--placeholder-opacity:1;color:#a3bffa;color:rgba(163,191,250,var(--placeholder-opacity))}.sm\:placeholder-indigo-400:-ms-input-placeholder{--placeholder-opacity:1;color:#7f9cf5;color:rgba(127,156,245,var(--placeholder-opacity))}.sm\:placeholder-indigo-400::-ms-input-placeholder{--placeholder-opacity:1;color:#7f9cf5;color:rgba(127,156,245,var(--placeholder-opacity))}.sm\:placeholder-indigo-400::placeholder{--placeholder-opacity:1;color:#7f9cf5;color:rgba(127,156,245,var(--placeholder-opacity))}.sm\:placeholder-indigo-500:-ms-input-placeholder{--placeholder-opacity:1;color:#667eea;color:rgba(102,126,234,var(--placeholder-opacity))}.sm\:placeholder-indigo-500::-ms-input-placeholder{--placeholder-opacity:1;color:#667eea;color:rgba(102,126,234,var(--placeholder-opacity))}.sm\:placeholder-indigo-500::placeholder{--placeholder-opacity:1;color:#667eea;color:rgba(102,126,234,var(--placeholder-opacity))}.sm\:placeholder-indigo-600:-ms-input-placeholder{--placeholder-opacity:1;color:#5a67d8;color:rgba(90,103,216,var(--placeholder-opacity))}.sm\:placeholder-indigo-600::-ms-input-placeholder{--placeholder-opacity:1;color:#5a67d8;color:rgba(90,103,216,var(--placeholder-opacity))}.sm\:placeholder-indigo-600::placeholder{--placeholder-opacity:1;color:#5a67d8;color:rgba(90,103,216,var(--placeholder-opacity))}.sm\:placeholder-indigo-700:-ms-input-placeholder{--placeholder-opacity:1;color:#4c51bf;color:rgba(76,81,191,var(--placeholder-opacity))}.sm\:placeholder-indigo-700::-ms-input-placeholder{--placeholder-opacity:1;color:#4c51bf;color:rgba(76,81,191,var(--placeholder-opacity))}.sm\:placeholder-indigo-700::placeholder{--placeholder-opacity:1;color:#4c51bf;color:rgba(76,81,191,var(--placeholder-opacity))}.sm\:placeholder-indigo-800:-ms-input-placeholder{--placeholder-opacity:1;color:#434190;color:rgba(67,65,144,var(--placeholder-opacity))}.sm\:placeholder-indigo-800::-ms-input-placeholder{--placeholder-opacity:1;color:#434190;color:rgba(67,65,144,var(--placeholder-opacity))}.sm\:placeholder-indigo-800::placeholder{--placeholder-opacity:1;color:#434190;color:rgba(67,65,144,var(--placeholder-opacity))}.sm\:placeholder-indigo-900:-ms-input-placeholder{--placeholder-opacity:1;color:#3c366b;color:rgba(60,54,107,var(--placeholder-opacity))}.sm\:placeholder-indigo-900::-ms-input-placeholder{--placeholder-opacity:1;color:#3c366b;color:rgba(60,54,107,var(--placeholder-opacity))}.sm\:placeholder-indigo-900::placeholder{--placeholder-opacity:1;color:#3c366b;color:rgba(60,54,107,var(--placeholder-opacity))}.sm\:placeholder-purple-100:-ms-input-placeholder{--placeholder-opacity:1;color:#faf5ff;color:rgba(250,245,255,var(--placeholder-opacity))}.sm\:placeholder-purple-100::-ms-input-placeholder{--placeholder-opacity:1;color:#faf5ff;color:rgba(250,245,255,var(--placeholder-opacity))}.sm\:placeholder-purple-100::placeholder{--placeholder-opacity:1;color:#faf5ff;color:rgba(250,245,255,var(--placeholder-opacity))}.sm\:placeholder-purple-200:-ms-input-placeholder{--placeholder-opacity:1;color:#e9d8fd;color:rgba(233,216,253,var(--placeholder-opacity))}.sm\:placeholder-purple-200::-ms-input-placeholder{--placeholder-opacity:1;color:#e9d8fd;color:rgba(233,216,253,var(--placeholder-opacity))}.sm\:placeholder-purple-200::placeholder{--placeholder-opacity:1;color:#e9d8fd;color:rgba(233,216,253,var(--placeholder-opacity))}.sm\:placeholder-purple-300:-ms-input-placeholder{--placeholder-opacity:1;color:#d6bcfa;color:rgba(214,188,250,var(--placeholder-opacity))}.sm\:placeholder-purple-300::-ms-input-placeholder{--placeholder-opacity:1;color:#d6bcfa;color:rgba(214,188,250,var(--placeholder-opacity))}.sm\:placeholder-purple-300::placeholder{--placeholder-opacity:1;color:#d6bcfa;color:rgba(214,188,250,var(--placeholder-opacity))}.sm\:placeholder-purple-400:-ms-input-placeholder{--placeholder-opacity:1;color:#b794f4;color:rgba(183,148,244,var(--placeholder-opacity))}.sm\:placeholder-purple-400::-ms-input-placeholder{--placeholder-opacity:1;color:#b794f4;color:rgba(183,148,244,var(--placeholder-opacity))}.sm\:placeholder-purple-400::placeholder{--placeholder-opacity:1;color:#b794f4;color:rgba(183,148,244,var(--placeholder-opacity))}.sm\:placeholder-purple-500:-ms-input-placeholder{--placeholder-opacity:1;color:#9f7aea;color:rgba(159,122,234,var(--placeholder-opacity))}.sm\:placeholder-purple-500::-ms-input-placeholder{--placeholder-opacity:1;color:#9f7aea;color:rgba(159,122,234,var(--placeholder-opacity))}.sm\:placeholder-purple-500::placeholder{--placeholder-opacity:1;color:#9f7aea;color:rgba(159,122,234,var(--placeholder-opacity))}.sm\:placeholder-purple-600:-ms-input-placeholder{--placeholder-opacity:1;color:#805ad5;color:rgba(128,90,213,var(--placeholder-opacity))}.sm\:placeholder-purple-600::-ms-input-placeholder{--placeholder-opacity:1;color:#805ad5;color:rgba(128,90,213,var(--placeholder-opacity))}.sm\:placeholder-purple-600::placeholder{--placeholder-opacity:1;color:#805ad5;color:rgba(128,90,213,var(--placeholder-opacity))}.sm\:placeholder-purple-700:-ms-input-placeholder{--placeholder-opacity:1;color:#6b46c1;color:rgba(107,70,193,var(--placeholder-opacity))}.sm\:placeholder-purple-700::-ms-input-placeholder{--placeholder-opacity:1;color:#6b46c1;color:rgba(107,70,193,var(--placeholder-opacity))}.sm\:placeholder-purple-700::placeholder{--placeholder-opacity:1;color:#6b46c1;color:rgba(107,70,193,var(--placeholder-opacity))}.sm\:placeholder-purple-800:-ms-input-placeholder{--placeholder-opacity:1;color:#553c9a;color:rgba(85,60,154,var(--placeholder-opacity))}.sm\:placeholder-purple-800::-ms-input-placeholder{--placeholder-opacity:1;color:#553c9a;color:rgba(85,60,154,var(--placeholder-opacity))}.sm\:placeholder-purple-800::placeholder{--placeholder-opacity:1;color:#553c9a;color:rgba(85,60,154,var(--placeholder-opacity))}.sm\:placeholder-purple-900:-ms-input-placeholder{--placeholder-opacity:1;color:#44337a;color:rgba(68,51,122,var(--placeholder-opacity))}.sm\:placeholder-purple-900::-ms-input-placeholder{--placeholder-opacity:1;color:#44337a;color:rgba(68,51,122,var(--placeholder-opacity))}.sm\:placeholder-purple-900::placeholder{--placeholder-opacity:1;color:#44337a;color:rgba(68,51,122,var(--placeholder-opacity))}.sm\:placeholder-pink-100:-ms-input-placeholder{--placeholder-opacity:1;color:#fff5f7;color:rgba(255,245,247,var(--placeholder-opacity))}.sm\:placeholder-pink-100::-ms-input-placeholder{--placeholder-opacity:1;color:#fff5f7;color:rgba(255,245,247,var(--placeholder-opacity))}.sm\:placeholder-pink-100::placeholder{--placeholder-opacity:1;color:#fff5f7;color:rgba(255,245,247,var(--placeholder-opacity))}.sm\:placeholder-pink-200:-ms-input-placeholder{--placeholder-opacity:1;color:#fed7e2;color:rgba(254,215,226,var(--placeholder-opacity))}.sm\:placeholder-pink-200::-ms-input-placeholder{--placeholder-opacity:1;color:#fed7e2;color:rgba(254,215,226,var(--placeholder-opacity))}.sm\:placeholder-pink-200::placeholder{--placeholder-opacity:1;color:#fed7e2;color:rgba(254,215,226,var(--placeholder-opacity))}.sm\:placeholder-pink-300:-ms-input-placeholder{--placeholder-opacity:1;color:#fbb6ce;color:rgba(251,182,206,var(--placeholder-opacity))}.sm\:placeholder-pink-300::-ms-input-placeholder{--placeholder-opacity:1;color:#fbb6ce;color:rgba(251,182,206,var(--placeholder-opacity))}.sm\:placeholder-pink-300::placeholder{--placeholder-opacity:1;color:#fbb6ce;color:rgba(251,182,206,var(--placeholder-opacity))}.sm\:placeholder-pink-400:-ms-input-placeholder{--placeholder-opacity:1;color:#f687b3;color:rgba(246,135,179,var(--placeholder-opacity))}.sm\:placeholder-pink-400::-ms-input-placeholder{--placeholder-opacity:1;color:#f687b3;color:rgba(246,135,179,var(--placeholder-opacity))}.sm\:placeholder-pink-400::placeholder{--placeholder-opacity:1;color:#f687b3;color:rgba(246,135,179,var(--placeholder-opacity))}.sm\:placeholder-pink-500:-ms-input-placeholder{--placeholder-opacity:1;color:#ed64a6;color:rgba(237,100,166,var(--placeholder-opacity))}.sm\:placeholder-pink-500::-ms-input-placeholder{--placeholder-opacity:1;color:#ed64a6;color:rgba(237,100,166,var(--placeholder-opacity))}.sm\:placeholder-pink-500::placeholder{--placeholder-opacity:1;color:#ed64a6;color:rgba(237,100,166,var(--placeholder-opacity))}.sm\:placeholder-pink-600:-ms-input-placeholder{--placeholder-opacity:1;color:#d53f8c;color:rgba(213,63,140,var(--placeholder-opacity))}.sm\:placeholder-pink-600::-ms-input-placeholder{--placeholder-opacity:1;color:#d53f8c;color:rgba(213,63,140,var(--placeholder-opacity))}.sm\:placeholder-pink-600::placeholder{--placeholder-opacity:1;color:#d53f8c;color:rgba(213,63,140,var(--placeholder-opacity))}.sm\:placeholder-pink-700:-ms-input-placeholder{--placeholder-opacity:1;color:#b83280;color:rgba(184,50,128,var(--placeholder-opacity))}.sm\:placeholder-pink-700::-ms-input-placeholder{--placeholder-opacity:1;color:#b83280;color:rgba(184,50,128,var(--placeholder-opacity))}.sm\:placeholder-pink-700::placeholder{--placeholder-opacity:1;color:#b83280;color:rgba(184,50,128,var(--placeholder-opacity))}.sm\:placeholder-pink-800:-ms-input-placeholder{--placeholder-opacity:1;color:#97266d;color:rgba(151,38,109,var(--placeholder-opacity))}.sm\:placeholder-pink-800::-ms-input-placeholder{--placeholder-opacity:1;color:#97266d;color:rgba(151,38,109,var(--placeholder-opacity))}.sm\:placeholder-pink-800::placeholder{--placeholder-opacity:1;color:#97266d;color:rgba(151,38,109,var(--placeholder-opacity))}.sm\:placeholder-pink-900:-ms-input-placeholder{--placeholder-opacity:1;color:#702459;color:rgba(112,36,89,var(--placeholder-opacity))}.sm\:placeholder-pink-900::-ms-input-placeholder{--placeholder-opacity:1;color:#702459;color:rgba(112,36,89,var(--placeholder-opacity))}.sm\:placeholder-pink-900::placeholder{--placeholder-opacity:1;color:#702459;color:rgba(112,36,89,var(--placeholder-opacity))}.sm\:focus\:placeholder-transparent:focus:-ms-input-placeholder{color:transparent}.sm\:focus\:placeholder-transparent:focus::-ms-input-placeholder{color:transparent}.sm\:focus\:placeholder-transparent:focus::placeholder{color:transparent}.sm\:focus\:placeholder-current:focus:-ms-input-placeholder{color:currentColor}.sm\:focus\:placeholder-current:focus::-ms-input-placeholder{color:currentColor}.sm\:focus\:placeholder-current:focus::placeholder{color:currentColor}.sm\:focus\:placeholder-black:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#000;color:rgba(0,0,0,var(--placeholder-opacity))}.sm\:focus\:placeholder-black:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#000;color:rgba(0,0,0,var(--placeholder-opacity))}.sm\:focus\:placeholder-black:focus::placeholder{--placeholder-opacity:1;color:#000;color:rgba(0,0,0,var(--placeholder-opacity))}.sm\:focus\:placeholder-white:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#fff;color:rgba(255,255,255,var(--placeholder-opacity))}.sm\:focus\:placeholder-white:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#fff;color:rgba(255,255,255,var(--placeholder-opacity))}.sm\:focus\:placeholder-white:focus::placeholder{--placeholder-opacity:1;color:#fff;color:rgba(255,255,255,var(--placeholder-opacity))}.sm\:focus\:placeholder-gray-100:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#f7fafc;color:rgba(247,250,252,var(--placeholder-opacity))}.sm\:focus\:placeholder-gray-100:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#f7fafc;color:rgba(247,250,252,var(--placeholder-opacity))}.sm\:focus\:placeholder-gray-100:focus::placeholder{--placeholder-opacity:1;color:#f7fafc;color:rgba(247,250,252,var(--placeholder-opacity))}.sm\:focus\:placeholder-gray-200:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#edf2f7;color:rgba(237,242,247,var(--placeholder-opacity))}.sm\:focus\:placeholder-gray-200:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#edf2f7;color:rgba(237,242,247,var(--placeholder-opacity))}.sm\:focus\:placeholder-gray-200:focus::placeholder{--placeholder-opacity:1;color:#edf2f7;color:rgba(237,242,247,var(--placeholder-opacity))}.sm\:focus\:placeholder-gray-300:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#e2e8f0;color:rgba(226,232,240,var(--placeholder-opacity))}.sm\:focus\:placeholder-gray-300:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#e2e8f0;color:rgba(226,232,240,var(--placeholder-opacity))}.sm\:focus\:placeholder-gray-300:focus::placeholder{--placeholder-opacity:1;color:#e2e8f0;color:rgba(226,232,240,var(--placeholder-opacity))}.sm\:focus\:placeholder-gray-400:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#cbd5e0;color:rgba(203,213,224,var(--placeholder-opacity))}.sm\:focus\:placeholder-gray-400:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#cbd5e0;color:rgba(203,213,224,var(--placeholder-opacity))}.sm\:focus\:placeholder-gray-400:focus::placeholder{--placeholder-opacity:1;color:#cbd5e0;color:rgba(203,213,224,var(--placeholder-opacity))}.sm\:focus\:placeholder-gray-500:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#a0aec0;color:rgba(160,174,192,var(--placeholder-opacity))}.sm\:focus\:placeholder-gray-500:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#a0aec0;color:rgba(160,174,192,var(--placeholder-opacity))}.sm\:focus\:placeholder-gray-500:focus::placeholder{--placeholder-opacity:1;color:#a0aec0;color:rgba(160,174,192,var(--placeholder-opacity))}.sm\:focus\:placeholder-gray-600:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#718096;color:rgba(113,128,150,var(--placeholder-opacity))}.sm\:focus\:placeholder-gray-600:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#718096;color:rgba(113,128,150,var(--placeholder-opacity))}.sm\:focus\:placeholder-gray-600:focus::placeholder{--placeholder-opacity:1;color:#718096;color:rgba(113,128,150,var(--placeholder-opacity))}.sm\:focus\:placeholder-gray-700:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#4a5568;color:rgba(74,85,104,var(--placeholder-opacity))}.sm\:focus\:placeholder-gray-700:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#4a5568;color:rgba(74,85,104,var(--placeholder-opacity))}.sm\:focus\:placeholder-gray-700:focus::placeholder{--placeholder-opacity:1;color:#4a5568;color:rgba(74,85,104,var(--placeholder-opacity))}.sm\:focus\:placeholder-gray-800:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#2d3748;color:rgba(45,55,72,var(--placeholder-opacity))}.sm\:focus\:placeholder-gray-800:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#2d3748;color:rgba(45,55,72,var(--placeholder-opacity))}.sm\:focus\:placeholder-gray-800:focus::placeholder{--placeholder-opacity:1;color:#2d3748;color:rgba(45,55,72,var(--placeholder-opacity))}.sm\:focus\:placeholder-gray-900:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#1a202c;color:rgba(26,32,44,var(--placeholder-opacity))}.sm\:focus\:placeholder-gray-900:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#1a202c;color:rgba(26,32,44,var(--placeholder-opacity))}.sm\:focus\:placeholder-gray-900:focus::placeholder{--placeholder-opacity:1;color:#1a202c;color:rgba(26,32,44,var(--placeholder-opacity))}.sm\:focus\:placeholder-red-100:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#fff5f5;color:rgba(255,245,245,var(--placeholder-opacity))}.sm\:focus\:placeholder-red-100:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#fff5f5;color:rgba(255,245,245,var(--placeholder-opacity))}.sm\:focus\:placeholder-red-100:focus::placeholder{--placeholder-opacity:1;color:#fff5f5;color:rgba(255,245,245,var(--placeholder-opacity))}.sm\:focus\:placeholder-red-200:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#fed7d7;color:rgba(254,215,215,var(--placeholder-opacity))}.sm\:focus\:placeholder-red-200:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#fed7d7;color:rgba(254,215,215,var(--placeholder-opacity))}.sm\:focus\:placeholder-red-200:focus::placeholder{--placeholder-opacity:1;color:#fed7d7;color:rgba(254,215,215,var(--placeholder-opacity))}.sm\:focus\:placeholder-red-300:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#feb2b2;color:rgba(254,178,178,var(--placeholder-opacity))}.sm\:focus\:placeholder-red-300:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#feb2b2;color:rgba(254,178,178,var(--placeholder-opacity))}.sm\:focus\:placeholder-red-300:focus::placeholder{--placeholder-opacity:1;color:#feb2b2;color:rgba(254,178,178,var(--placeholder-opacity))}.sm\:focus\:placeholder-red-400:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#fc8181;color:rgba(252,129,129,var(--placeholder-opacity))}.sm\:focus\:placeholder-red-400:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#fc8181;color:rgba(252,129,129,var(--placeholder-opacity))}.sm\:focus\:placeholder-red-400:focus::placeholder{--placeholder-opacity:1;color:#fc8181;color:rgba(252,129,129,var(--placeholder-opacity))}.sm\:focus\:placeholder-red-500:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#f56565;color:rgba(245,101,101,var(--placeholder-opacity))}.sm\:focus\:placeholder-red-500:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#f56565;color:rgba(245,101,101,var(--placeholder-opacity))}.sm\:focus\:placeholder-red-500:focus::placeholder{--placeholder-opacity:1;color:#f56565;color:rgba(245,101,101,var(--placeholder-opacity))}.sm\:focus\:placeholder-red-600:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#e53e3e;color:rgba(229,62,62,var(--placeholder-opacity))}.sm\:focus\:placeholder-red-600:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#e53e3e;color:rgba(229,62,62,var(--placeholder-opacity))}.sm\:focus\:placeholder-red-600:focus::placeholder{--placeholder-opacity:1;color:#e53e3e;color:rgba(229,62,62,var(--placeholder-opacity))}.sm\:focus\:placeholder-red-700:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#c53030;color:rgba(197,48,48,var(--placeholder-opacity))}.sm\:focus\:placeholder-red-700:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#c53030;color:rgba(197,48,48,var(--placeholder-opacity))}.sm\:focus\:placeholder-red-700:focus::placeholder{--placeholder-opacity:1;color:#c53030;color:rgba(197,48,48,var(--placeholder-opacity))}.sm\:focus\:placeholder-red-800:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#9b2c2c;color:rgba(155,44,44,var(--placeholder-opacity))}.sm\:focus\:placeholder-red-800:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#9b2c2c;color:rgba(155,44,44,var(--placeholder-opacity))}.sm\:focus\:placeholder-red-800:focus::placeholder{--placeholder-opacity:1;color:#9b2c2c;color:rgba(155,44,44,var(--placeholder-opacity))}.sm\:focus\:placeholder-red-900:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#742a2a;color:rgba(116,42,42,var(--placeholder-opacity))}.sm\:focus\:placeholder-red-900:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#742a2a;color:rgba(116,42,42,var(--placeholder-opacity))}.sm\:focus\:placeholder-red-900:focus::placeholder{--placeholder-opacity:1;color:#742a2a;color:rgba(116,42,42,var(--placeholder-opacity))}.sm\:focus\:placeholder-orange-100:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#fffaf0;color:rgba(255,250,240,var(--placeholder-opacity))}.sm\:focus\:placeholder-orange-100:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#fffaf0;color:rgba(255,250,240,var(--placeholder-opacity))}.sm\:focus\:placeholder-orange-100:focus::placeholder{--placeholder-opacity:1;color:#fffaf0;color:rgba(255,250,240,var(--placeholder-opacity))}.sm\:focus\:placeholder-orange-200:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#feebc8;color:rgba(254,235,200,var(--placeholder-opacity))}.sm\:focus\:placeholder-orange-200:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#feebc8;color:rgba(254,235,200,var(--placeholder-opacity))}.sm\:focus\:placeholder-orange-200:focus::placeholder{--placeholder-opacity:1;color:#feebc8;color:rgba(254,235,200,var(--placeholder-opacity))}.sm\:focus\:placeholder-orange-300:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#fbd38d;color:rgba(251,211,141,var(--placeholder-opacity))}.sm\:focus\:placeholder-orange-300:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#fbd38d;color:rgba(251,211,141,var(--placeholder-opacity))}.sm\:focus\:placeholder-orange-300:focus::placeholder{--placeholder-opacity:1;color:#fbd38d;color:rgba(251,211,141,var(--placeholder-opacity))}.sm\:focus\:placeholder-orange-400:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#f6ad55;color:rgba(246,173,85,var(--placeholder-opacity))}.sm\:focus\:placeholder-orange-400:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#f6ad55;color:rgba(246,173,85,var(--placeholder-opacity))}.sm\:focus\:placeholder-orange-400:focus::placeholder{--placeholder-opacity:1;color:#f6ad55;color:rgba(246,173,85,var(--placeholder-opacity))}.sm\:focus\:placeholder-orange-500:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#ed8936;color:rgba(237,137,54,var(--placeholder-opacity))}.sm\:focus\:placeholder-orange-500:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#ed8936;color:rgba(237,137,54,var(--placeholder-opacity))}.sm\:focus\:placeholder-orange-500:focus::placeholder{--placeholder-opacity:1;color:#ed8936;color:rgba(237,137,54,var(--placeholder-opacity))}.sm\:focus\:placeholder-orange-600:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#dd6b20;color:rgba(221,107,32,var(--placeholder-opacity))}.sm\:focus\:placeholder-orange-600:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#dd6b20;color:rgba(221,107,32,var(--placeholder-opacity))}.sm\:focus\:placeholder-orange-600:focus::placeholder{--placeholder-opacity:1;color:#dd6b20;color:rgba(221,107,32,var(--placeholder-opacity))}.sm\:focus\:placeholder-orange-700:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#c05621;color:rgba(192,86,33,var(--placeholder-opacity))}.sm\:focus\:placeholder-orange-700:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#c05621;color:rgba(192,86,33,var(--placeholder-opacity))}.sm\:focus\:placeholder-orange-700:focus::placeholder{--placeholder-opacity:1;color:#c05621;color:rgba(192,86,33,var(--placeholder-opacity))}.sm\:focus\:placeholder-orange-800:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#9c4221;color:rgba(156,66,33,var(--placeholder-opacity))}.sm\:focus\:placeholder-orange-800:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#9c4221;color:rgba(156,66,33,var(--placeholder-opacity))}.sm\:focus\:placeholder-orange-800:focus::placeholder{--placeholder-opacity:1;color:#9c4221;color:rgba(156,66,33,var(--placeholder-opacity))}.sm\:focus\:placeholder-orange-900:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#7b341e;color:rgba(123,52,30,var(--placeholder-opacity))}.sm\:focus\:placeholder-orange-900:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#7b341e;color:rgba(123,52,30,var(--placeholder-opacity))}.sm\:focus\:placeholder-orange-900:focus::placeholder{--placeholder-opacity:1;color:#7b341e;color:rgba(123,52,30,var(--placeholder-opacity))}.sm\:focus\:placeholder-yellow-100:focus:-ms-input-placeholder{--placeholder-opacity:1;color:ivory;color:rgba(255,255,240,var(--placeholder-opacity))}.sm\:focus\:placeholder-yellow-100:focus::-ms-input-placeholder{--placeholder-opacity:1;color:ivory;color:rgba(255,255,240,var(--placeholder-opacity))}.sm\:focus\:placeholder-yellow-100:focus::placeholder{--placeholder-opacity:1;color:ivory;color:rgba(255,255,240,var(--placeholder-opacity))}.sm\:focus\:placeholder-yellow-200:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#fefcbf;color:rgba(254,252,191,var(--placeholder-opacity))}.sm\:focus\:placeholder-yellow-200:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#fefcbf;color:rgba(254,252,191,var(--placeholder-opacity))}.sm\:focus\:placeholder-yellow-200:focus::placeholder{--placeholder-opacity:1;color:#fefcbf;color:rgba(254,252,191,var(--placeholder-opacity))}.sm\:focus\:placeholder-yellow-300:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#faf089;color:rgba(250,240,137,var(--placeholder-opacity))}.sm\:focus\:placeholder-yellow-300:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#faf089;color:rgba(250,240,137,var(--placeholder-opacity))}.sm\:focus\:placeholder-yellow-300:focus::placeholder{--placeholder-opacity:1;color:#faf089;color:rgba(250,240,137,var(--placeholder-opacity))}.sm\:focus\:placeholder-yellow-400:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#f6e05e;color:rgba(246,224,94,var(--placeholder-opacity))}.sm\:focus\:placeholder-yellow-400:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#f6e05e;color:rgba(246,224,94,var(--placeholder-opacity))}.sm\:focus\:placeholder-yellow-400:focus::placeholder{--placeholder-opacity:1;color:#f6e05e;color:rgba(246,224,94,var(--placeholder-opacity))}.sm\:focus\:placeholder-yellow-500:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#ecc94b;color:rgba(236,201,75,var(--placeholder-opacity))}.sm\:focus\:placeholder-yellow-500:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#ecc94b;color:rgba(236,201,75,var(--placeholder-opacity))}.sm\:focus\:placeholder-yellow-500:focus::placeholder{--placeholder-opacity:1;color:#ecc94b;color:rgba(236,201,75,var(--placeholder-opacity))}.sm\:focus\:placeholder-yellow-600:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#d69e2e;color:rgba(214,158,46,var(--placeholder-opacity))}.sm\:focus\:placeholder-yellow-600:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#d69e2e;color:rgba(214,158,46,var(--placeholder-opacity))}.sm\:focus\:placeholder-yellow-600:focus::placeholder{--placeholder-opacity:1;color:#d69e2e;color:rgba(214,158,46,var(--placeholder-opacity))}.sm\:focus\:placeholder-yellow-700:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#b7791f;color:rgba(183,121,31,var(--placeholder-opacity))}.sm\:focus\:placeholder-yellow-700:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#b7791f;color:rgba(183,121,31,var(--placeholder-opacity))}.sm\:focus\:placeholder-yellow-700:focus::placeholder{--placeholder-opacity:1;color:#b7791f;color:rgba(183,121,31,var(--placeholder-opacity))}.sm\:focus\:placeholder-yellow-800:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#975a16;color:rgba(151,90,22,var(--placeholder-opacity))}.sm\:focus\:placeholder-yellow-800:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#975a16;color:rgba(151,90,22,var(--placeholder-opacity))}.sm\:focus\:placeholder-yellow-800:focus::placeholder{--placeholder-opacity:1;color:#975a16;color:rgba(151,90,22,var(--placeholder-opacity))}.sm\:focus\:placeholder-yellow-900:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#744210;color:rgba(116,66,16,var(--placeholder-opacity))}.sm\:focus\:placeholder-yellow-900:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#744210;color:rgba(116,66,16,var(--placeholder-opacity))}.sm\:focus\:placeholder-yellow-900:focus::placeholder{--placeholder-opacity:1;color:#744210;color:rgba(116,66,16,var(--placeholder-opacity))}.sm\:focus\:placeholder-green-100:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#f0fff4;color:rgba(240,255,244,var(--placeholder-opacity))}.sm\:focus\:placeholder-green-100:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#f0fff4;color:rgba(240,255,244,var(--placeholder-opacity))}.sm\:focus\:placeholder-green-100:focus::placeholder{--placeholder-opacity:1;color:#f0fff4;color:rgba(240,255,244,var(--placeholder-opacity))}.sm\:focus\:placeholder-green-200:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#c6f6d5;color:rgba(198,246,213,var(--placeholder-opacity))}.sm\:focus\:placeholder-green-200:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#c6f6d5;color:rgba(198,246,213,var(--placeholder-opacity))}.sm\:focus\:placeholder-green-200:focus::placeholder{--placeholder-opacity:1;color:#c6f6d5;color:rgba(198,246,213,var(--placeholder-opacity))}.sm\:focus\:placeholder-green-300:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#9ae6b4;color:rgba(154,230,180,var(--placeholder-opacity))}.sm\:focus\:placeholder-green-300:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#9ae6b4;color:rgba(154,230,180,var(--placeholder-opacity))}.sm\:focus\:placeholder-green-300:focus::placeholder{--placeholder-opacity:1;color:#9ae6b4;color:rgba(154,230,180,var(--placeholder-opacity))}.sm\:focus\:placeholder-green-400:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#68d391;color:rgba(104,211,145,var(--placeholder-opacity))}.sm\:focus\:placeholder-green-400:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#68d391;color:rgba(104,211,145,var(--placeholder-opacity))}.sm\:focus\:placeholder-green-400:focus::placeholder{--placeholder-opacity:1;color:#68d391;color:rgba(104,211,145,var(--placeholder-opacity))}.sm\:focus\:placeholder-green-500:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#48bb78;color:rgba(72,187,120,var(--placeholder-opacity))}.sm\:focus\:placeholder-green-500:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#48bb78;color:rgba(72,187,120,var(--placeholder-opacity))}.sm\:focus\:placeholder-green-500:focus::placeholder{--placeholder-opacity:1;color:#48bb78;color:rgba(72,187,120,var(--placeholder-opacity))}.sm\:focus\:placeholder-green-600:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#38a169;color:rgba(56,161,105,var(--placeholder-opacity))}.sm\:focus\:placeholder-green-600:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#38a169;color:rgba(56,161,105,var(--placeholder-opacity))}.sm\:focus\:placeholder-green-600:focus::placeholder{--placeholder-opacity:1;color:#38a169;color:rgba(56,161,105,var(--placeholder-opacity))}.sm\:focus\:placeholder-green-700:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#2f855a;color:rgba(47,133,90,var(--placeholder-opacity))}.sm\:focus\:placeholder-green-700:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#2f855a;color:rgba(47,133,90,var(--placeholder-opacity))}.sm\:focus\:placeholder-green-700:focus::placeholder{--placeholder-opacity:1;color:#2f855a;color:rgba(47,133,90,var(--placeholder-opacity))}.sm\:focus\:placeholder-green-800:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#276749;color:rgba(39,103,73,var(--placeholder-opacity))}.sm\:focus\:placeholder-green-800:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#276749;color:rgba(39,103,73,var(--placeholder-opacity))}.sm\:focus\:placeholder-green-800:focus::placeholder{--placeholder-opacity:1;color:#276749;color:rgba(39,103,73,var(--placeholder-opacity))}.sm\:focus\:placeholder-green-900:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#22543d;color:rgba(34,84,61,var(--placeholder-opacity))}.sm\:focus\:placeholder-green-900:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#22543d;color:rgba(34,84,61,var(--placeholder-opacity))}.sm\:focus\:placeholder-green-900:focus::placeholder{--placeholder-opacity:1;color:#22543d;color:rgba(34,84,61,var(--placeholder-opacity))}.sm\:focus\:placeholder-teal-100:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#e6fffa;color:rgba(230,255,250,var(--placeholder-opacity))}.sm\:focus\:placeholder-teal-100:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#e6fffa;color:rgba(230,255,250,var(--placeholder-opacity))}.sm\:focus\:placeholder-teal-100:focus::placeholder{--placeholder-opacity:1;color:#e6fffa;color:rgba(230,255,250,var(--placeholder-opacity))}.sm\:focus\:placeholder-teal-200:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#b2f5ea;color:rgba(178,245,234,var(--placeholder-opacity))}.sm\:focus\:placeholder-teal-200:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#b2f5ea;color:rgba(178,245,234,var(--placeholder-opacity))}.sm\:focus\:placeholder-teal-200:focus::placeholder{--placeholder-opacity:1;color:#b2f5ea;color:rgba(178,245,234,var(--placeholder-opacity))}.sm\:focus\:placeholder-teal-300:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#81e6d9;color:rgba(129,230,217,var(--placeholder-opacity))}.sm\:focus\:placeholder-teal-300:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#81e6d9;color:rgba(129,230,217,var(--placeholder-opacity))}.sm\:focus\:placeholder-teal-300:focus::placeholder{--placeholder-opacity:1;color:#81e6d9;color:rgba(129,230,217,var(--placeholder-opacity))}.sm\:focus\:placeholder-teal-400:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#4fd1c5;color:rgba(79,209,197,var(--placeholder-opacity))}.sm\:focus\:placeholder-teal-400:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#4fd1c5;color:rgba(79,209,197,var(--placeholder-opacity))}.sm\:focus\:placeholder-teal-400:focus::placeholder{--placeholder-opacity:1;color:#4fd1c5;color:rgba(79,209,197,var(--placeholder-opacity))}.sm\:focus\:placeholder-teal-500:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#38b2ac;color:rgba(56,178,172,var(--placeholder-opacity))}.sm\:focus\:placeholder-teal-500:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#38b2ac;color:rgba(56,178,172,var(--placeholder-opacity))}.sm\:focus\:placeholder-teal-500:focus::placeholder{--placeholder-opacity:1;color:#38b2ac;color:rgba(56,178,172,var(--placeholder-opacity))}.sm\:focus\:placeholder-teal-600:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#319795;color:rgba(49,151,149,var(--placeholder-opacity))}.sm\:focus\:placeholder-teal-600:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#319795;color:rgba(49,151,149,var(--placeholder-opacity))}.sm\:focus\:placeholder-teal-600:focus::placeholder{--placeholder-opacity:1;color:#319795;color:rgba(49,151,149,var(--placeholder-opacity))}.sm\:focus\:placeholder-teal-700:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#2c7a7b;color:rgba(44,122,123,var(--placeholder-opacity))}.sm\:focus\:placeholder-teal-700:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#2c7a7b;color:rgba(44,122,123,var(--placeholder-opacity))}.sm\:focus\:placeholder-teal-700:focus::placeholder{--placeholder-opacity:1;color:#2c7a7b;color:rgba(44,122,123,var(--placeholder-opacity))}.sm\:focus\:placeholder-teal-800:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#285e61;color:rgba(40,94,97,var(--placeholder-opacity))}.sm\:focus\:placeholder-teal-800:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#285e61;color:rgba(40,94,97,var(--placeholder-opacity))}.sm\:focus\:placeholder-teal-800:focus::placeholder{--placeholder-opacity:1;color:#285e61;color:rgba(40,94,97,var(--placeholder-opacity))}.sm\:focus\:placeholder-teal-900:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#234e52;color:rgba(35,78,82,var(--placeholder-opacity))}.sm\:focus\:placeholder-teal-900:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#234e52;color:rgba(35,78,82,var(--placeholder-opacity))}.sm\:focus\:placeholder-teal-900:focus::placeholder{--placeholder-opacity:1;color:#234e52;color:rgba(35,78,82,var(--placeholder-opacity))}.sm\:focus\:placeholder-blue-100:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#ebf8ff;color:rgba(235,248,255,var(--placeholder-opacity))}.sm\:focus\:placeholder-blue-100:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#ebf8ff;color:rgba(235,248,255,var(--placeholder-opacity))}.sm\:focus\:placeholder-blue-100:focus::placeholder{--placeholder-opacity:1;color:#ebf8ff;color:rgba(235,248,255,var(--placeholder-opacity))}.sm\:focus\:placeholder-blue-200:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#bee3f8;color:rgba(190,227,248,var(--placeholder-opacity))}.sm\:focus\:placeholder-blue-200:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#bee3f8;color:rgba(190,227,248,var(--placeholder-opacity))}.sm\:focus\:placeholder-blue-200:focus::placeholder{--placeholder-opacity:1;color:#bee3f8;color:rgba(190,227,248,var(--placeholder-opacity))}.sm\:focus\:placeholder-blue-300:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#90cdf4;color:rgba(144,205,244,var(--placeholder-opacity))}.sm\:focus\:placeholder-blue-300:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#90cdf4;color:rgba(144,205,244,var(--placeholder-opacity))}.sm\:focus\:placeholder-blue-300:focus::placeholder{--placeholder-opacity:1;color:#90cdf4;color:rgba(144,205,244,var(--placeholder-opacity))}.sm\:focus\:placeholder-blue-400:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#63b3ed;color:rgba(99,179,237,var(--placeholder-opacity))}.sm\:focus\:placeholder-blue-400:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#63b3ed;color:rgba(99,179,237,var(--placeholder-opacity))}.sm\:focus\:placeholder-blue-400:focus::placeholder{--placeholder-opacity:1;color:#63b3ed;color:rgba(99,179,237,var(--placeholder-opacity))}.sm\:focus\:placeholder-blue-500:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#4299e1;color:rgba(66,153,225,var(--placeholder-opacity))}.sm\:focus\:placeholder-blue-500:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#4299e1;color:rgba(66,153,225,var(--placeholder-opacity))}.sm\:focus\:placeholder-blue-500:focus::placeholder{--placeholder-opacity:1;color:#4299e1;color:rgba(66,153,225,var(--placeholder-opacity))}.sm\:focus\:placeholder-blue-600:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#3182ce;color:rgba(49,130,206,var(--placeholder-opacity))}.sm\:focus\:placeholder-blue-600:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#3182ce;color:rgba(49,130,206,var(--placeholder-opacity))}.sm\:focus\:placeholder-blue-600:focus::placeholder{--placeholder-opacity:1;color:#3182ce;color:rgba(49,130,206,var(--placeholder-opacity))}.sm\:focus\:placeholder-blue-700:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#2b6cb0;color:rgba(43,108,176,var(--placeholder-opacity))}.sm\:focus\:placeholder-blue-700:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#2b6cb0;color:rgba(43,108,176,var(--placeholder-opacity))}.sm\:focus\:placeholder-blue-700:focus::placeholder{--placeholder-opacity:1;color:#2b6cb0;color:rgba(43,108,176,var(--placeholder-opacity))}.sm\:focus\:placeholder-blue-800:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#2c5282;color:rgba(44,82,130,var(--placeholder-opacity))}.sm\:focus\:placeholder-blue-800:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#2c5282;color:rgba(44,82,130,var(--placeholder-opacity))}.sm\:focus\:placeholder-blue-800:focus::placeholder{--placeholder-opacity:1;color:#2c5282;color:rgba(44,82,130,var(--placeholder-opacity))}.sm\:focus\:placeholder-blue-900:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#2a4365;color:rgba(42,67,101,var(--placeholder-opacity))}.sm\:focus\:placeholder-blue-900:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#2a4365;color:rgba(42,67,101,var(--placeholder-opacity))}.sm\:focus\:placeholder-blue-900:focus::placeholder{--placeholder-opacity:1;color:#2a4365;color:rgba(42,67,101,var(--placeholder-opacity))}.sm\:focus\:placeholder-indigo-100:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#ebf4ff;color:rgba(235,244,255,var(--placeholder-opacity))}.sm\:focus\:placeholder-indigo-100:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#ebf4ff;color:rgba(235,244,255,var(--placeholder-opacity))}.sm\:focus\:placeholder-indigo-100:focus::placeholder{--placeholder-opacity:1;color:#ebf4ff;color:rgba(235,244,255,var(--placeholder-opacity))}.sm\:focus\:placeholder-indigo-200:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#c3dafe;color:rgba(195,218,254,var(--placeholder-opacity))}.sm\:focus\:placeholder-indigo-200:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#c3dafe;color:rgba(195,218,254,var(--placeholder-opacity))}.sm\:focus\:placeholder-indigo-200:focus::placeholder{--placeholder-opacity:1;color:#c3dafe;color:rgba(195,218,254,var(--placeholder-opacity))}.sm\:focus\:placeholder-indigo-300:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#a3bffa;color:rgba(163,191,250,var(--placeholder-opacity))}.sm\:focus\:placeholder-indigo-300:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#a3bffa;color:rgba(163,191,250,var(--placeholder-opacity))}.sm\:focus\:placeholder-indigo-300:focus::placeholder{--placeholder-opacity:1;color:#a3bffa;color:rgba(163,191,250,var(--placeholder-opacity))}.sm\:focus\:placeholder-indigo-400:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#7f9cf5;color:rgba(127,156,245,var(--placeholder-opacity))}.sm\:focus\:placeholder-indigo-400:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#7f9cf5;color:rgba(127,156,245,var(--placeholder-opacity))}.sm\:focus\:placeholder-indigo-400:focus::placeholder{--placeholder-opacity:1;color:#7f9cf5;color:rgba(127,156,245,var(--placeholder-opacity))}.sm\:focus\:placeholder-indigo-500:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#667eea;color:rgba(102,126,234,var(--placeholder-opacity))}.sm\:focus\:placeholder-indigo-500:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#667eea;color:rgba(102,126,234,var(--placeholder-opacity))}.sm\:focus\:placeholder-indigo-500:focus::placeholder{--placeholder-opacity:1;color:#667eea;color:rgba(102,126,234,var(--placeholder-opacity))}.sm\:focus\:placeholder-indigo-600:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#5a67d8;color:rgba(90,103,216,var(--placeholder-opacity))}.sm\:focus\:placeholder-indigo-600:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#5a67d8;color:rgba(90,103,216,var(--placeholder-opacity))}.sm\:focus\:placeholder-indigo-600:focus::placeholder{--placeholder-opacity:1;color:#5a67d8;color:rgba(90,103,216,var(--placeholder-opacity))}.sm\:focus\:placeholder-indigo-700:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#4c51bf;color:rgba(76,81,191,var(--placeholder-opacity))}.sm\:focus\:placeholder-indigo-700:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#4c51bf;color:rgba(76,81,191,var(--placeholder-opacity))}.sm\:focus\:placeholder-indigo-700:focus::placeholder{--placeholder-opacity:1;color:#4c51bf;color:rgba(76,81,191,var(--placeholder-opacity))}.sm\:focus\:placeholder-indigo-800:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#434190;color:rgba(67,65,144,var(--placeholder-opacity))}.sm\:focus\:placeholder-indigo-800:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#434190;color:rgba(67,65,144,var(--placeholder-opacity))}.sm\:focus\:placeholder-indigo-800:focus::placeholder{--placeholder-opacity:1;color:#434190;color:rgba(67,65,144,var(--placeholder-opacity))}.sm\:focus\:placeholder-indigo-900:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#3c366b;color:rgba(60,54,107,var(--placeholder-opacity))}.sm\:focus\:placeholder-indigo-900:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#3c366b;color:rgba(60,54,107,var(--placeholder-opacity))}.sm\:focus\:placeholder-indigo-900:focus::placeholder{--placeholder-opacity:1;color:#3c366b;color:rgba(60,54,107,var(--placeholder-opacity))}.sm\:focus\:placeholder-purple-100:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#faf5ff;color:rgba(250,245,255,var(--placeholder-opacity))}.sm\:focus\:placeholder-purple-100:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#faf5ff;color:rgba(250,245,255,var(--placeholder-opacity))}.sm\:focus\:placeholder-purple-100:focus::placeholder{--placeholder-opacity:1;color:#faf5ff;color:rgba(250,245,255,var(--placeholder-opacity))}.sm\:focus\:placeholder-purple-200:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#e9d8fd;color:rgba(233,216,253,var(--placeholder-opacity))}.sm\:focus\:placeholder-purple-200:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#e9d8fd;color:rgba(233,216,253,var(--placeholder-opacity))}.sm\:focus\:placeholder-purple-200:focus::placeholder{--placeholder-opacity:1;color:#e9d8fd;color:rgba(233,216,253,var(--placeholder-opacity))}.sm\:focus\:placeholder-purple-300:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#d6bcfa;color:rgba(214,188,250,var(--placeholder-opacity))}.sm\:focus\:placeholder-purple-300:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#d6bcfa;color:rgba(214,188,250,var(--placeholder-opacity))}.sm\:focus\:placeholder-purple-300:focus::placeholder{--placeholder-opacity:1;color:#d6bcfa;color:rgba(214,188,250,var(--placeholder-opacity))}.sm\:focus\:placeholder-purple-400:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#b794f4;color:rgba(183,148,244,var(--placeholder-opacity))}.sm\:focus\:placeholder-purple-400:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#b794f4;color:rgba(183,148,244,var(--placeholder-opacity))}.sm\:focus\:placeholder-purple-400:focus::placeholder{--placeholder-opacity:1;color:#b794f4;color:rgba(183,148,244,var(--placeholder-opacity))}.sm\:focus\:placeholder-purple-500:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#9f7aea;color:rgba(159,122,234,var(--placeholder-opacity))}.sm\:focus\:placeholder-purple-500:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#9f7aea;color:rgba(159,122,234,var(--placeholder-opacity))}.sm\:focus\:placeholder-purple-500:focus::placeholder{--placeholder-opacity:1;color:#9f7aea;color:rgba(159,122,234,var(--placeholder-opacity))}.sm\:focus\:placeholder-purple-600:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#805ad5;color:rgba(128,90,213,var(--placeholder-opacity))}.sm\:focus\:placeholder-purple-600:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#805ad5;color:rgba(128,90,213,var(--placeholder-opacity))}.sm\:focus\:placeholder-purple-600:focus::placeholder{--placeholder-opacity:1;color:#805ad5;color:rgba(128,90,213,var(--placeholder-opacity))}.sm\:focus\:placeholder-purple-700:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#6b46c1;color:rgba(107,70,193,var(--placeholder-opacity))}.sm\:focus\:placeholder-purple-700:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#6b46c1;color:rgba(107,70,193,var(--placeholder-opacity))}.sm\:focus\:placeholder-purple-700:focus::placeholder{--placeholder-opacity:1;color:#6b46c1;color:rgba(107,70,193,var(--placeholder-opacity))}.sm\:focus\:placeholder-purple-800:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#553c9a;color:rgba(85,60,154,var(--placeholder-opacity))}.sm\:focus\:placeholder-purple-800:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#553c9a;color:rgba(85,60,154,var(--placeholder-opacity))}.sm\:focus\:placeholder-purple-800:focus::placeholder{--placeholder-opacity:1;color:#553c9a;color:rgba(85,60,154,var(--placeholder-opacity))}.sm\:focus\:placeholder-purple-900:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#44337a;color:rgba(68,51,122,var(--placeholder-opacity))}.sm\:focus\:placeholder-purple-900:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#44337a;color:rgba(68,51,122,var(--placeholder-opacity))}.sm\:focus\:placeholder-purple-900:focus::placeholder{--placeholder-opacity:1;color:#44337a;color:rgba(68,51,122,var(--placeholder-opacity))}.sm\:focus\:placeholder-pink-100:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#fff5f7;color:rgba(255,245,247,var(--placeholder-opacity))}.sm\:focus\:placeholder-pink-100:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#fff5f7;color:rgba(255,245,247,var(--placeholder-opacity))}.sm\:focus\:placeholder-pink-100:focus::placeholder{--placeholder-opacity:1;color:#fff5f7;color:rgba(255,245,247,var(--placeholder-opacity))}.sm\:focus\:placeholder-pink-200:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#fed7e2;color:rgba(254,215,226,var(--placeholder-opacity))}.sm\:focus\:placeholder-pink-200:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#fed7e2;color:rgba(254,215,226,var(--placeholder-opacity))}.sm\:focus\:placeholder-pink-200:focus::placeholder{--placeholder-opacity:1;color:#fed7e2;color:rgba(254,215,226,var(--placeholder-opacity))}.sm\:focus\:placeholder-pink-300:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#fbb6ce;color:rgba(251,182,206,var(--placeholder-opacity))}.sm\:focus\:placeholder-pink-300:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#fbb6ce;color:rgba(251,182,206,var(--placeholder-opacity))}.sm\:focus\:placeholder-pink-300:focus::placeholder{--placeholder-opacity:1;color:#fbb6ce;color:rgba(251,182,206,var(--placeholder-opacity))}.sm\:focus\:placeholder-pink-400:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#f687b3;color:rgba(246,135,179,var(--placeholder-opacity))}.sm\:focus\:placeholder-pink-400:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#f687b3;color:rgba(246,135,179,var(--placeholder-opacity))}.sm\:focus\:placeholder-pink-400:focus::placeholder{--placeholder-opacity:1;color:#f687b3;color:rgba(246,135,179,var(--placeholder-opacity))}.sm\:focus\:placeholder-pink-500:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#ed64a6;color:rgba(237,100,166,var(--placeholder-opacity))}.sm\:focus\:placeholder-pink-500:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#ed64a6;color:rgba(237,100,166,var(--placeholder-opacity))}.sm\:focus\:placeholder-pink-500:focus::placeholder{--placeholder-opacity:1;color:#ed64a6;color:rgba(237,100,166,var(--placeholder-opacity))}.sm\:focus\:placeholder-pink-600:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#d53f8c;color:rgba(213,63,140,var(--placeholder-opacity))}.sm\:focus\:placeholder-pink-600:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#d53f8c;color:rgba(213,63,140,var(--placeholder-opacity))}.sm\:focus\:placeholder-pink-600:focus::placeholder{--placeholder-opacity:1;color:#d53f8c;color:rgba(213,63,140,var(--placeholder-opacity))}.sm\:focus\:placeholder-pink-700:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#b83280;color:rgba(184,50,128,var(--placeholder-opacity))}.sm\:focus\:placeholder-pink-700:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#b83280;color:rgba(184,50,128,var(--placeholder-opacity))}.sm\:focus\:placeholder-pink-700:focus::placeholder{--placeholder-opacity:1;color:#b83280;color:rgba(184,50,128,var(--placeholder-opacity))}.sm\:focus\:placeholder-pink-800:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#97266d;color:rgba(151,38,109,var(--placeholder-opacity))}.sm\:focus\:placeholder-pink-800:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#97266d;color:rgba(151,38,109,var(--placeholder-opacity))}.sm\:focus\:placeholder-pink-800:focus::placeholder{--placeholder-opacity:1;color:#97266d;color:rgba(151,38,109,var(--placeholder-opacity))}.sm\:focus\:placeholder-pink-900:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#702459;color:rgba(112,36,89,var(--placeholder-opacity))}.sm\:focus\:placeholder-pink-900:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#702459;color:rgba(112,36,89,var(--placeholder-opacity))}.sm\:focus\:placeholder-pink-900:focus::placeholder{--placeholder-opacity:1;color:#702459;color:rgba(112,36,89,var(--placeholder-opacity))}.sm\:placeholder-opacity-0:-ms-input-placeholder{--placeholder-opacity:0}.sm\:placeholder-opacity-0::-ms-input-placeholder{--placeholder-opacity:0}.sm\:placeholder-opacity-0::placeholder{--placeholder-opacity:0}.sm\:placeholder-opacity-25:-ms-input-placeholder{--placeholder-opacity:0.25}.sm\:placeholder-opacity-25::-ms-input-placeholder{--placeholder-opacity:0.25}.sm\:placeholder-opacity-25::placeholder{--placeholder-opacity:0.25}.sm\:placeholder-opacity-50:-ms-input-placeholder{--placeholder-opacity:0.5}.sm\:placeholder-opacity-50::-ms-input-placeholder{--placeholder-opacity:0.5}.sm\:placeholder-opacity-50::placeholder{--placeholder-opacity:0.5}.sm\:placeholder-opacity-75:-ms-input-placeholder{--placeholder-opacity:0.75}.sm\:placeholder-opacity-75::-ms-input-placeholder{--placeholder-opacity:0.75}.sm\:placeholder-opacity-75::placeholder{--placeholder-opacity:0.75}.sm\:placeholder-opacity-100:-ms-input-placeholder{--placeholder-opacity:1}.sm\:placeholder-opacity-100::-ms-input-placeholder{--placeholder-opacity:1}.sm\:placeholder-opacity-100::placeholder{--placeholder-opacity:1}.sm\:focus\:placeholder-opacity-0:focus:-ms-input-placeholder{--placeholder-opacity:0}.sm\:focus\:placeholder-opacity-0:focus::-ms-input-placeholder{--placeholder-opacity:0}.sm\:focus\:placeholder-opacity-0:focus::placeholder{--placeholder-opacity:0}.sm\:focus\:placeholder-opacity-25:focus:-ms-input-placeholder{--placeholder-opacity:0.25}.sm\:focus\:placeholder-opacity-25:focus::-ms-input-placeholder{--placeholder-opacity:0.25}.sm\:focus\:placeholder-opacity-25:focus::placeholder{--placeholder-opacity:0.25}.sm\:focus\:placeholder-opacity-50:focus:-ms-input-placeholder{--placeholder-opacity:0.5}.sm\:focus\:placeholder-opacity-50:focus::-ms-input-placeholder{--placeholder-opacity:0.5}.sm\:focus\:placeholder-opacity-50:focus::placeholder{--placeholder-opacity:0.5}.sm\:focus\:placeholder-opacity-75:focus:-ms-input-placeholder{--placeholder-opacity:0.75}.sm\:focus\:placeholder-opacity-75:focus::-ms-input-placeholder{--placeholder-opacity:0.75}.sm\:focus\:placeholder-opacity-75:focus::placeholder{--placeholder-opacity:0.75}.sm\:focus\:placeholder-opacity-100:focus:-ms-input-placeholder{--placeholder-opacity:1}.sm\:focus\:placeholder-opacity-100:focus::-ms-input-placeholder{--placeholder-opacity:1}.sm\:focus\:placeholder-opacity-100:focus::placeholder{--placeholder-opacity:1}.sm\:pointer-events-none{pointer-events:none}.sm\:pointer-events-auto{pointer-events:auto}.sm\:static{position:static}.sm\:fixed{position:fixed}.sm\:absolute{position:absolute}.sm\:relative{position:relative}.sm\:sticky{position:-webkit-sticky;position:sticky}.sm\:inset-0{top:0;right:0;bottom:0;left:0}.sm\:inset-auto{top:auto;right:auto;bottom:auto;left:auto}.sm\:inset-y-0{top:0;bottom:0}.sm\:inset-x-0{right:0;left:0}.sm\:inset-y-auto{top:auto;bottom:auto}.sm\:inset-x-auto{right:auto;left:auto}.sm\:top-0{top:0}.sm\:right-0{right:0}.sm\:bottom-0{bottom:0}.sm\:left-0{left:0}.sm\:top-auto{top:auto}.sm\:right-auto{right:auto}.sm\:bottom-auto{bottom:auto}.sm\:left-auto{left:auto}.sm\:resize-none{resize:none}.sm\:resize-y{resize:vertical}.sm\:resize-x{resize:horizontal}.sm\:resize{resize:both}.sm\:shadow-xs{box-shadow:0 0 0 1px rgba(0,0,0,.05)}.sm\:shadow-sm{box-shadow:0 1px 2px 0 rgba(0,0,0,.05)}.sm\:shadow{box-shadow:0 1px 3px 0 rgba(0,0,0,.1),0 1px 2px 0 rgba(0,0,0,.06)}.sm\:shadow-md{box-shadow:0 4px 6px -1px rgba(0,0,0,.1),0 2px 4px -1px rgba(0,0,0,.06)}.sm\:shadow-lg{box-shadow:0 10px 15px -3px rgba(0,0,0,.1),0 4px 6px -2px rgba(0,0,0,.05)}.sm\:shadow-xl{box-shadow:0 20px 25px -5px rgba(0,0,0,.1),0 10px 10px -5px rgba(0,0,0,.04)}.sm\:shadow-2xl{box-shadow:0 25px 50px -12px rgba(0,0,0,.25)}.sm\:shadow-inner{box-shadow:inset 0 2px 4px 0 rgba(0,0,0,.06)}.sm\:shadow-outline{box-shadow:0 0 0 3px rgba(66,153,225,.5)}.sm\:shadow-none{box-shadow:none}.sm\:hover\:shadow-xs:hover{box-shadow:0 0 0 1px rgba(0,0,0,.05)}.sm\:hover\:shadow-sm:hover{box-shadow:0 1px 2px 0 rgba(0,0,0,.05)}.sm\:hover\:shadow:hover{box-shadow:0 1px 3px 0 rgba(0,0,0,.1),0 1px 2px 0 rgba(0,0,0,.06)}.sm\:hover\:shadow-md:hover{box-shadow:0 4px 6px -1px rgba(0,0,0,.1),0 2px 4px -1px rgba(0,0,0,.06)}.sm\:hover\:shadow-lg:hover{box-shadow:0 10px 15px -3px rgba(0,0,0,.1),0 4px 6px -2px rgba(0,0,0,.05)}.sm\:hover\:shadow-xl:hover{box-shadow:0 20px 25px -5px rgba(0,0,0,.1),0 10px 10px -5px rgba(0,0,0,.04)}.sm\:hover\:shadow-2xl:hover{box-shadow:0 25px 50px -12px rgba(0,0,0,.25)}.sm\:hover\:shadow-inner:hover{box-shadow:inset 0 2px 4px 0 rgba(0,0,0,.06)}.sm\:hover\:shadow-outline:hover{box-shadow:0 0 0 3px rgba(66,153,225,.5)}.sm\:hover\:shadow-none:hover{box-shadow:none}.sm\:focus\:shadow-xs:focus{box-shadow:0 0 0 1px rgba(0,0,0,.05)}.sm\:focus\:shadow-sm:focus{box-shadow:0 1px 2px 0 rgba(0,0,0,.05)}.sm\:focus\:shadow:focus{box-shadow:0 1px 3px 0 rgba(0,0,0,.1),0 1px 2px 0 rgba(0,0,0,.06)}.sm\:focus\:shadow-md:focus{box-shadow:0 4px 6px -1px rgba(0,0,0,.1),0 2px 4px -1px rgba(0,0,0,.06)}.sm\:focus\:shadow-lg:focus{box-shadow:0 10px 15px -3px rgba(0,0,0,.1),0 4px 6px -2px rgba(0,0,0,.05)}.sm\:focus\:shadow-xl:focus{box-shadow:0 20px 25px -5px rgba(0,0,0,.1),0 10px 10px -5px rgba(0,0,0,.04)}.sm\:focus\:shadow-2xl:focus{box-shadow:0 25px 50px -12px rgba(0,0,0,.25)}.sm\:focus\:shadow-inner:focus{box-shadow:inset 0 2px 4px 0 rgba(0,0,0,.06)}.sm\:focus\:shadow-outline:focus{box-shadow:0 0 0 3px rgba(66,153,225,.5)}.sm\:focus\:shadow-none:focus{box-shadow:none}.sm\:fill-current{fill:currentColor}.sm\:stroke-current{stroke:currentColor}.sm\:stroke-0{stroke-width:0}.sm\:stroke-1{stroke-width:1}.sm\:stroke-2{stroke-width:2}.sm\:table-auto{table-layout:auto}.sm\:table-fixed{table-layout:fixed}.sm\:text-left{text-align:left}.sm\:text-center{text-align:center}.sm\:text-right{text-align:right}.sm\:text-justify{text-align:justify}.sm\:text-transparent{color:transparent}.sm\:text-current{color:currentColor}.sm\:text-black{--text-opacity:1;color:#000;color:rgba(0,0,0,var(--text-opacity))}.sm\:text-white{--text-opacity:1;color:#fff;color:rgba(255,255,255,var(--text-opacity))}.sm\:text-gray-100{--text-opacity:1;color:#f7fafc;color:rgba(247,250,252,var(--text-opacity))}.sm\:text-gray-200{--text-opacity:1;color:#edf2f7;color:rgba(237,242,247,var(--text-opacity))}.sm\:text-gray-300{--text-opacity:1;color:#e2e8f0;color:rgba(226,232,240,var(--text-opacity))}.sm\:text-gray-400{--text-opacity:1;color:#cbd5e0;color:rgba(203,213,224,var(--text-opacity))}.sm\:text-gray-500{--text-opacity:1;color:#a0aec0;color:rgba(160,174,192,var(--text-opacity))}.sm\:text-gray-600{--text-opacity:1;color:#718096;color:rgba(113,128,150,var(--text-opacity))}.sm\:text-gray-700{--text-opacity:1;color:#4a5568;color:rgba(74,85,104,var(--text-opacity))}.sm\:text-gray-800{--text-opacity:1;color:#2d3748;color:rgba(45,55,72,var(--text-opacity))}.sm\:text-gray-900{--text-opacity:1;color:#1a202c;color:rgba(26,32,44,var(--text-opacity))}.sm\:text-red-100{--text-opacity:1;color:#fff5f5;color:rgba(255,245,245,var(--text-opacity))}.sm\:text-red-200{--text-opacity:1;color:#fed7d7;color:rgba(254,215,215,var(--text-opacity))}.sm\:text-red-300{--text-opacity:1;color:#feb2b2;color:rgba(254,178,178,var(--text-opacity))}.sm\:text-red-400{--text-opacity:1;color:#fc8181;color:rgba(252,129,129,var(--text-opacity))}.sm\:text-red-500{--text-opacity:1;color:#f56565;color:rgba(245,101,101,var(--text-opacity))}.sm\:text-red-600{--text-opacity:1;color:#e53e3e;color:rgba(229,62,62,var(--text-opacity))}.sm\:text-red-700{--text-opacity:1;color:#c53030;color:rgba(197,48,48,var(--text-opacity))}.sm\:text-red-800{--text-opacity:1;color:#9b2c2c;color:rgba(155,44,44,var(--text-opacity))}.sm\:text-red-900{--text-opacity:1;color:#742a2a;color:rgba(116,42,42,var(--text-opacity))}.sm\:text-orange-100{--text-opacity:1;color:#fffaf0;color:rgba(255,250,240,var(--text-opacity))}.sm\:text-orange-200{--text-opacity:1;color:#feebc8;color:rgba(254,235,200,var(--text-opacity))}.sm\:text-orange-300{--text-opacity:1;color:#fbd38d;color:rgba(251,211,141,var(--text-opacity))}.sm\:text-orange-400{--text-opacity:1;color:#f6ad55;color:rgba(246,173,85,var(--text-opacity))}.sm\:text-orange-500{--text-opacity:1;color:#ed8936;color:rgba(237,137,54,var(--text-opacity))}.sm\:text-orange-600{--text-opacity:1;color:#dd6b20;color:rgba(221,107,32,var(--text-opacity))}.sm\:text-orange-700{--text-opacity:1;color:#c05621;color:rgba(192,86,33,var(--text-opacity))}.sm\:text-orange-800{--text-opacity:1;color:#9c4221;color:rgba(156,66,33,var(--text-opacity))}.sm\:text-orange-900{--text-opacity:1;color:#7b341e;color:rgba(123,52,30,var(--text-opacity))}.sm\:text-yellow-100{--text-opacity:1;color:ivory;color:rgba(255,255,240,var(--text-opacity))}.sm\:text-yellow-200{--text-opacity:1;color:#fefcbf;color:rgba(254,252,191,var(--text-opacity))}.sm\:text-yellow-300{--text-opacity:1;color:#faf089;color:rgba(250,240,137,var(--text-opacity))}.sm\:text-yellow-400{--text-opacity:1;color:#f6e05e;color:rgba(246,224,94,var(--text-opacity))}.sm\:text-yellow-500{--text-opacity:1;color:#ecc94b;color:rgba(236,201,75,var(--text-opacity))}.sm\:text-yellow-600{--text-opacity:1;color:#d69e2e;color:rgba(214,158,46,var(--text-opacity))}.sm\:text-yellow-700{--text-opacity:1;color:#b7791f;color:rgba(183,121,31,var(--text-opacity))}.sm\:text-yellow-800{--text-opacity:1;color:#975a16;color:rgba(151,90,22,var(--text-opacity))}.sm\:text-yellow-900{--text-opacity:1;color:#744210;color:rgba(116,66,16,var(--text-opacity))}.sm\:text-green-100{--text-opacity:1;color:#f0fff4;color:rgba(240,255,244,var(--text-opacity))}.sm\:text-green-200{--text-opacity:1;color:#c6f6d5;color:rgba(198,246,213,var(--text-opacity))}.sm\:text-green-300{--text-opacity:1;color:#9ae6b4;color:rgba(154,230,180,var(--text-opacity))}.sm\:text-green-400{--text-opacity:1;color:#68d391;color:rgba(104,211,145,var(--text-opacity))}.sm\:text-green-500{--text-opacity:1;color:#48bb78;color:rgba(72,187,120,var(--text-opacity))}.sm\:text-green-600{--text-opacity:1;color:#38a169;color:rgba(56,161,105,var(--text-opacity))}.sm\:text-green-700{--text-opacity:1;color:#2f855a;color:rgba(47,133,90,var(--text-opacity))}.sm\:text-green-800{--text-opacity:1;color:#276749;color:rgba(39,103,73,var(--text-opacity))}.sm\:text-green-900{--text-opacity:1;color:#22543d;color:rgba(34,84,61,var(--text-opacity))}.sm\:text-teal-100{--text-opacity:1;color:#e6fffa;color:rgba(230,255,250,var(--text-opacity))}.sm\:text-teal-200{--text-opacity:1;color:#b2f5ea;color:rgba(178,245,234,var(--text-opacity))}.sm\:text-teal-300{--text-opacity:1;color:#81e6d9;color:rgba(129,230,217,var(--text-opacity))}.sm\:text-teal-400{--text-opacity:1;color:#4fd1c5;color:rgba(79,209,197,var(--text-opacity))}.sm\:text-teal-500{--text-opacity:1;color:#38b2ac;color:rgba(56,178,172,var(--text-opacity))}.sm\:text-teal-600{--text-opacity:1;color:#319795;color:rgba(49,151,149,var(--text-opacity))}.sm\:text-teal-700{--text-opacity:1;color:#2c7a7b;color:rgba(44,122,123,var(--text-opacity))}.sm\:text-teal-800{--text-opacity:1;color:#285e61;color:rgba(40,94,97,var(--text-opacity))}.sm\:text-teal-900{--text-opacity:1;color:#234e52;color:rgba(35,78,82,var(--text-opacity))}.sm\:text-blue-100{--text-opacity:1;color:#ebf8ff;color:rgba(235,248,255,var(--text-opacity))}.sm\:text-blue-200{--text-opacity:1;color:#bee3f8;color:rgba(190,227,248,var(--text-opacity))}.sm\:text-blue-300{--text-opacity:1;color:#90cdf4;color:rgba(144,205,244,var(--text-opacity))}.sm\:text-blue-400{--text-opacity:1;color:#63b3ed;color:rgba(99,179,237,var(--text-opacity))}.sm\:text-blue-500{--text-opacity:1;color:#4299e1;color:rgba(66,153,225,var(--text-opacity))}.sm\:text-blue-600{--text-opacity:1;color:#3182ce;color:rgba(49,130,206,var(--text-opacity))}.sm\:text-blue-700{--text-opacity:1;color:#2b6cb0;color:rgba(43,108,176,var(--text-opacity))}.sm\:text-blue-800{--text-opacity:1;color:#2c5282;color:rgba(44,82,130,var(--text-opacity))}.sm\:text-blue-900{--text-opacity:1;color:#2a4365;color:rgba(42,67,101,var(--text-opacity))}.sm\:text-indigo-100{--text-opacity:1;color:#ebf4ff;color:rgba(235,244,255,var(--text-opacity))}.sm\:text-indigo-200{--text-opacity:1;color:#c3dafe;color:rgba(195,218,254,var(--text-opacity))}.sm\:text-indigo-300{--text-opacity:1;color:#a3bffa;color:rgba(163,191,250,var(--text-opacity))}.sm\:text-indigo-400{--text-opacity:1;color:#7f9cf5;color:rgba(127,156,245,var(--text-opacity))}.sm\:text-indigo-500{--text-opacity:1;color:#667eea;color:rgba(102,126,234,var(--text-opacity))}.sm\:text-indigo-600{--text-opacity:1;color:#5a67d8;color:rgba(90,103,216,var(--text-opacity))}.sm\:text-indigo-700{--text-opacity:1;color:#4c51bf;color:rgba(76,81,191,var(--text-opacity))}.sm\:text-indigo-800{--text-opacity:1;color:#434190;color:rgba(67,65,144,var(--text-opacity))}.sm\:text-indigo-900{--text-opacity:1;color:#3c366b;color:rgba(60,54,107,var(--text-opacity))}.sm\:text-purple-100{--text-opacity:1;color:#faf5ff;color:rgba(250,245,255,var(--text-opacity))}.sm\:text-purple-200{--text-opacity:1;color:#e9d8fd;color:rgba(233,216,253,var(--text-opacity))}.sm\:text-purple-300{--text-opacity:1;color:#d6bcfa;color:rgba(214,188,250,var(--text-opacity))}.sm\:text-purple-400{--text-opacity:1;color:#b794f4;color:rgba(183,148,244,var(--text-opacity))}.sm\:text-purple-500{--text-opacity:1;color:#9f7aea;color:rgba(159,122,234,var(--text-opacity))}.sm\:text-purple-600{--text-opacity:1;color:#805ad5;color:rgba(128,90,213,var(--text-opacity))}.sm\:text-purple-700{--text-opacity:1;color:#6b46c1;color:rgba(107,70,193,var(--text-opacity))}.sm\:text-purple-800{--text-opacity:1;color:#553c9a;color:rgba(85,60,154,var(--text-opacity))}.sm\:text-purple-900{--text-opacity:1;color:#44337a;color:rgba(68,51,122,var(--text-opacity))}.sm\:text-pink-100{--text-opacity:1;color:#fff5f7;color:rgba(255,245,247,var(--text-opacity))}.sm\:text-pink-200{--text-opacity:1;color:#fed7e2;color:rgba(254,215,226,var(--text-opacity))}.sm\:text-pink-300{--text-opacity:1;color:#fbb6ce;color:rgba(251,182,206,var(--text-opacity))}.sm\:text-pink-400{--text-opacity:1;color:#f687b3;color:rgba(246,135,179,var(--text-opacity))}.sm\:text-pink-500{--text-opacity:1;color:#ed64a6;color:rgba(237,100,166,var(--text-opacity))}.sm\:text-pink-600{--text-opacity:1;color:#d53f8c;color:rgba(213,63,140,var(--text-opacity))}.sm\:text-pink-700{--text-opacity:1;color:#b83280;color:rgba(184,50,128,var(--text-opacity))}.sm\:text-pink-800{--text-opacity:1;color:#97266d;color:rgba(151,38,109,var(--text-opacity))}.sm\:text-pink-900{--text-opacity:1;color:#702459;color:rgba(112,36,89,var(--text-opacity))}.sm\:hover\:text-transparent:hover{color:transparent}.sm\:hover\:text-current:hover{color:currentColor}.sm\:hover\:text-black:hover{--text-opacity:1;color:#000;color:rgba(0,0,0,var(--text-opacity))}.sm\:hover\:text-white:hover{--text-opacity:1;color:#fff;color:rgba(255,255,255,var(--text-opacity))}.sm\:hover\:text-gray-100:hover{--text-opacity:1;color:#f7fafc;color:rgba(247,250,252,var(--text-opacity))}.sm\:hover\:text-gray-200:hover{--text-opacity:1;color:#edf2f7;color:rgba(237,242,247,var(--text-opacity))}.sm\:hover\:text-gray-300:hover{--text-opacity:1;color:#e2e8f0;color:rgba(226,232,240,var(--text-opacity))}.sm\:hover\:text-gray-400:hover{--text-opacity:1;color:#cbd5e0;color:rgba(203,213,224,var(--text-opacity))}.sm\:hover\:text-gray-500:hover{--text-opacity:1;color:#a0aec0;color:rgba(160,174,192,var(--text-opacity))}.sm\:hover\:text-gray-600:hover{--text-opacity:1;color:#718096;color:rgba(113,128,150,var(--text-opacity))}.sm\:hover\:text-gray-700:hover{--text-opacity:1;color:#4a5568;color:rgba(74,85,104,var(--text-opacity))}.sm\:hover\:text-gray-800:hover{--text-opacity:1;color:#2d3748;color:rgba(45,55,72,var(--text-opacity))}.sm\:hover\:text-gray-900:hover{--text-opacity:1;color:#1a202c;color:rgba(26,32,44,var(--text-opacity))}.sm\:hover\:text-red-100:hover{--text-opacity:1;color:#fff5f5;color:rgba(255,245,245,var(--text-opacity))}.sm\:hover\:text-red-200:hover{--text-opacity:1;color:#fed7d7;color:rgba(254,215,215,var(--text-opacity))}.sm\:hover\:text-red-300:hover{--text-opacity:1;color:#feb2b2;color:rgba(254,178,178,var(--text-opacity))}.sm\:hover\:text-red-400:hover{--text-opacity:1;color:#fc8181;color:rgba(252,129,129,var(--text-opacity))}.sm\:hover\:text-red-500:hover{--text-opacity:1;color:#f56565;color:rgba(245,101,101,var(--text-opacity))}.sm\:hover\:text-red-600:hover{--text-opacity:1;color:#e53e3e;color:rgba(229,62,62,var(--text-opacity))}.sm\:hover\:text-red-700:hover{--text-opacity:1;color:#c53030;color:rgba(197,48,48,var(--text-opacity))}.sm\:hover\:text-red-800:hover{--text-opacity:1;color:#9b2c2c;color:rgba(155,44,44,var(--text-opacity))}.sm\:hover\:text-red-900:hover{--text-opacity:1;color:#742a2a;color:rgba(116,42,42,var(--text-opacity))}.sm\:hover\:text-orange-100:hover{--text-opacity:1;color:#fffaf0;color:rgba(255,250,240,var(--text-opacity))}.sm\:hover\:text-orange-200:hover{--text-opacity:1;color:#feebc8;color:rgba(254,235,200,var(--text-opacity))}.sm\:hover\:text-orange-300:hover{--text-opacity:1;color:#fbd38d;color:rgba(251,211,141,var(--text-opacity))}.sm\:hover\:text-orange-400:hover{--text-opacity:1;color:#f6ad55;color:rgba(246,173,85,var(--text-opacity))}.sm\:hover\:text-orange-500:hover{--text-opacity:1;color:#ed8936;color:rgba(237,137,54,var(--text-opacity))}.sm\:hover\:text-orange-600:hover{--text-opacity:1;color:#dd6b20;color:rgba(221,107,32,var(--text-opacity))}.sm\:hover\:text-orange-700:hover{--text-opacity:1;color:#c05621;color:rgba(192,86,33,var(--text-opacity))}.sm\:hover\:text-orange-800:hover{--text-opacity:1;color:#9c4221;color:rgba(156,66,33,var(--text-opacity))}.sm\:hover\:text-orange-900:hover{--text-opacity:1;color:#7b341e;color:rgba(123,52,30,var(--text-opacity))}.sm\:hover\:text-yellow-100:hover{--text-opacity:1;color:ivory;color:rgba(255,255,240,var(--text-opacity))}.sm\:hover\:text-yellow-200:hover{--text-opacity:1;color:#fefcbf;color:rgba(254,252,191,var(--text-opacity))}.sm\:hover\:text-yellow-300:hover{--text-opacity:1;color:#faf089;color:rgba(250,240,137,var(--text-opacity))}.sm\:hover\:text-yellow-400:hover{--text-opacity:1;color:#f6e05e;color:rgba(246,224,94,var(--text-opacity))}.sm\:hover\:text-yellow-500:hover{--text-opacity:1;color:#ecc94b;color:rgba(236,201,75,var(--text-opacity))}.sm\:hover\:text-yellow-600:hover{--text-opacity:1;color:#d69e2e;color:rgba(214,158,46,var(--text-opacity))}.sm\:hover\:text-yellow-700:hover{--text-opacity:1;color:#b7791f;color:rgba(183,121,31,var(--text-opacity))}.sm\:hover\:text-yellow-800:hover{--text-opacity:1;color:#975a16;color:rgba(151,90,22,var(--text-opacity))}.sm\:hover\:text-yellow-900:hover{--text-opacity:1;color:#744210;color:rgba(116,66,16,var(--text-opacity))}.sm\:hover\:text-green-100:hover{--text-opacity:1;color:#f0fff4;color:rgba(240,255,244,var(--text-opacity))}.sm\:hover\:text-green-200:hover{--text-opacity:1;color:#c6f6d5;color:rgba(198,246,213,var(--text-opacity))}.sm\:hover\:text-green-300:hover{--text-opacity:1;color:#9ae6b4;color:rgba(154,230,180,var(--text-opacity))}.sm\:hover\:text-green-400:hover{--text-opacity:1;color:#68d391;color:rgba(104,211,145,var(--text-opacity))}.sm\:hover\:text-green-500:hover{--text-opacity:1;color:#48bb78;color:rgba(72,187,120,var(--text-opacity))}.sm\:hover\:text-green-600:hover{--text-opacity:1;color:#38a169;color:rgba(56,161,105,var(--text-opacity))}.sm\:hover\:text-green-700:hover{--text-opacity:1;color:#2f855a;color:rgba(47,133,90,var(--text-opacity))}.sm\:hover\:text-green-800:hover{--text-opacity:1;color:#276749;color:rgba(39,103,73,var(--text-opacity))}.sm\:hover\:text-green-900:hover{--text-opacity:1;color:#22543d;color:rgba(34,84,61,var(--text-opacity))}.sm\:hover\:text-teal-100:hover{--text-opacity:1;color:#e6fffa;color:rgba(230,255,250,var(--text-opacity))}.sm\:hover\:text-teal-200:hover{--text-opacity:1;color:#b2f5ea;color:rgba(178,245,234,var(--text-opacity))}.sm\:hover\:text-teal-300:hover{--text-opacity:1;color:#81e6d9;color:rgba(129,230,217,var(--text-opacity))}.sm\:hover\:text-teal-400:hover{--text-opacity:1;color:#4fd1c5;color:rgba(79,209,197,var(--text-opacity))}.sm\:hover\:text-teal-500:hover{--text-opacity:1;color:#38b2ac;color:rgba(56,178,172,var(--text-opacity))}.sm\:hover\:text-teal-600:hover{--text-opacity:1;color:#319795;color:rgba(49,151,149,var(--text-opacity))}.sm\:hover\:text-teal-700:hover{--text-opacity:1;color:#2c7a7b;color:rgba(44,122,123,var(--text-opacity))}.sm\:hover\:text-teal-800:hover{--text-opacity:1;color:#285e61;color:rgba(40,94,97,var(--text-opacity))}.sm\:hover\:text-teal-900:hover{--text-opacity:1;color:#234e52;color:rgba(35,78,82,var(--text-opacity))}.sm\:hover\:text-blue-100:hover{--text-opacity:1;color:#ebf8ff;color:rgba(235,248,255,var(--text-opacity))}.sm\:hover\:text-blue-200:hover{--text-opacity:1;color:#bee3f8;color:rgba(190,227,248,var(--text-opacity))}.sm\:hover\:text-blue-300:hover{--text-opacity:1;color:#90cdf4;color:rgba(144,205,244,var(--text-opacity))}.sm\:hover\:text-blue-400:hover{--text-opacity:1;color:#63b3ed;color:rgba(99,179,237,var(--text-opacity))}.sm\:hover\:text-blue-500:hover{--text-opacity:1;color:#4299e1;color:rgba(66,153,225,var(--text-opacity))}.sm\:hover\:text-blue-600:hover{--text-opacity:1;color:#3182ce;color:rgba(49,130,206,var(--text-opacity))}.sm\:hover\:text-blue-700:hover{--text-opacity:1;color:#2b6cb0;color:rgba(43,108,176,var(--text-opacity))}.sm\:hover\:text-blue-800:hover{--text-opacity:1;color:#2c5282;color:rgba(44,82,130,var(--text-opacity))}.sm\:hover\:text-blue-900:hover{--text-opacity:1;color:#2a4365;color:rgba(42,67,101,var(--text-opacity))}.sm\:hover\:text-indigo-100:hover{--text-opacity:1;color:#ebf4ff;color:rgba(235,244,255,var(--text-opacity))}.sm\:hover\:text-indigo-200:hover{--text-opacity:1;color:#c3dafe;color:rgba(195,218,254,var(--text-opacity))}.sm\:hover\:text-indigo-300:hover{--text-opacity:1;color:#a3bffa;color:rgba(163,191,250,var(--text-opacity))}.sm\:hover\:text-indigo-400:hover{--text-opacity:1;color:#7f9cf5;color:rgba(127,156,245,var(--text-opacity))}.sm\:hover\:text-indigo-500:hover{--text-opacity:1;color:#667eea;color:rgba(102,126,234,var(--text-opacity))}.sm\:hover\:text-indigo-600:hover{--text-opacity:1;color:#5a67d8;color:rgba(90,103,216,var(--text-opacity))}.sm\:hover\:text-indigo-700:hover{--text-opacity:1;color:#4c51bf;color:rgba(76,81,191,var(--text-opacity))}.sm\:hover\:text-indigo-800:hover{--text-opacity:1;color:#434190;color:rgba(67,65,144,var(--text-opacity))}.sm\:hover\:text-indigo-900:hover{--text-opacity:1;color:#3c366b;color:rgba(60,54,107,var(--text-opacity))}.sm\:hover\:text-purple-100:hover{--text-opacity:1;color:#faf5ff;color:rgba(250,245,255,var(--text-opacity))}.sm\:hover\:text-purple-200:hover{--text-opacity:1;color:#e9d8fd;color:rgba(233,216,253,var(--text-opacity))}.sm\:hover\:text-purple-300:hover{--text-opacity:1;color:#d6bcfa;color:rgba(214,188,250,var(--text-opacity))}.sm\:hover\:text-purple-400:hover{--text-opacity:1;color:#b794f4;color:rgba(183,148,244,var(--text-opacity))}.sm\:hover\:text-purple-500:hover{--text-opacity:1;color:#9f7aea;color:rgba(159,122,234,var(--text-opacity))}.sm\:hover\:text-purple-600:hover{--text-opacity:1;color:#805ad5;color:rgba(128,90,213,var(--text-opacity))}.sm\:hover\:text-purple-700:hover{--text-opacity:1;color:#6b46c1;color:rgba(107,70,193,var(--text-opacity))}.sm\:hover\:text-purple-800:hover{--text-opacity:1;color:#553c9a;color:rgba(85,60,154,var(--text-opacity))}.sm\:hover\:text-purple-900:hover{--text-opacity:1;color:#44337a;color:rgba(68,51,122,var(--text-opacity))}.sm\:hover\:text-pink-100:hover{--text-opacity:1;color:#fff5f7;color:rgba(255,245,247,var(--text-opacity))}.sm\:hover\:text-pink-200:hover{--text-opacity:1;color:#fed7e2;color:rgba(254,215,226,var(--text-opacity))}.sm\:hover\:text-pink-300:hover{--text-opacity:1;color:#fbb6ce;color:rgba(251,182,206,var(--text-opacity))}.sm\:hover\:text-pink-400:hover{--text-opacity:1;color:#f687b3;color:rgba(246,135,179,var(--text-opacity))}.sm\:hover\:text-pink-500:hover{--text-opacity:1;color:#ed64a6;color:rgba(237,100,166,var(--text-opacity))}.sm\:hover\:text-pink-600:hover{--text-opacity:1;color:#d53f8c;color:rgba(213,63,140,var(--text-opacity))}.sm\:hover\:text-pink-700:hover{--text-opacity:1;color:#b83280;color:rgba(184,50,128,var(--text-opacity))}.sm\:hover\:text-pink-800:hover{--text-opacity:1;color:#97266d;color:rgba(151,38,109,var(--text-opacity))}.sm\:hover\:text-pink-900:hover{--text-opacity:1;color:#702459;color:rgba(112,36,89,var(--text-opacity))}.sm\:focus\:text-transparent:focus{color:transparent}.sm\:focus\:text-current:focus{color:currentColor}.sm\:focus\:text-black:focus{--text-opacity:1;color:#000;color:rgba(0,0,0,var(--text-opacity))}.sm\:focus\:text-white:focus{--text-opacity:1;color:#fff;color:rgba(255,255,255,var(--text-opacity))}.sm\:focus\:text-gray-100:focus{--text-opacity:1;color:#f7fafc;color:rgba(247,250,252,var(--text-opacity))}.sm\:focus\:text-gray-200:focus{--text-opacity:1;color:#edf2f7;color:rgba(237,242,247,var(--text-opacity))}.sm\:focus\:text-gray-300:focus{--text-opacity:1;color:#e2e8f0;color:rgba(226,232,240,var(--text-opacity))}.sm\:focus\:text-gray-400:focus{--text-opacity:1;color:#cbd5e0;color:rgba(203,213,224,var(--text-opacity))}.sm\:focus\:text-gray-500:focus{--text-opacity:1;color:#a0aec0;color:rgba(160,174,192,var(--text-opacity))}.sm\:focus\:text-gray-600:focus{--text-opacity:1;color:#718096;color:rgba(113,128,150,var(--text-opacity))}.sm\:focus\:text-gray-700:focus{--text-opacity:1;color:#4a5568;color:rgba(74,85,104,var(--text-opacity))}.sm\:focus\:text-gray-800:focus{--text-opacity:1;color:#2d3748;color:rgba(45,55,72,var(--text-opacity))}.sm\:focus\:text-gray-900:focus{--text-opacity:1;color:#1a202c;color:rgba(26,32,44,var(--text-opacity))}.sm\:focus\:text-red-100:focus{--text-opacity:1;color:#fff5f5;color:rgba(255,245,245,var(--text-opacity))}.sm\:focus\:text-red-200:focus{--text-opacity:1;color:#fed7d7;color:rgba(254,215,215,var(--text-opacity))}.sm\:focus\:text-red-300:focus{--text-opacity:1;color:#feb2b2;color:rgba(254,178,178,var(--text-opacity))}.sm\:focus\:text-red-400:focus{--text-opacity:1;color:#fc8181;color:rgba(252,129,129,var(--text-opacity))}.sm\:focus\:text-red-500:focus{--text-opacity:1;color:#f56565;color:rgba(245,101,101,var(--text-opacity))}.sm\:focus\:text-red-600:focus{--text-opacity:1;color:#e53e3e;color:rgba(229,62,62,var(--text-opacity))}.sm\:focus\:text-red-700:focus{--text-opacity:1;color:#c53030;color:rgba(197,48,48,var(--text-opacity))}.sm\:focus\:text-red-800:focus{--text-opacity:1;color:#9b2c2c;color:rgba(155,44,44,var(--text-opacity))}.sm\:focus\:text-red-900:focus{--text-opacity:1;color:#742a2a;color:rgba(116,42,42,var(--text-opacity))}.sm\:focus\:text-orange-100:focus{--text-opacity:1;color:#fffaf0;color:rgba(255,250,240,var(--text-opacity))}.sm\:focus\:text-orange-200:focus{--text-opacity:1;color:#feebc8;color:rgba(254,235,200,var(--text-opacity))}.sm\:focus\:text-orange-300:focus{--text-opacity:1;color:#fbd38d;color:rgba(251,211,141,var(--text-opacity))}.sm\:focus\:text-orange-400:focus{--text-opacity:1;color:#f6ad55;color:rgba(246,173,85,var(--text-opacity))}.sm\:focus\:text-orange-500:focus{--text-opacity:1;color:#ed8936;color:rgba(237,137,54,var(--text-opacity))}.sm\:focus\:text-orange-600:focus{--text-opacity:1;color:#dd6b20;color:rgba(221,107,32,var(--text-opacity))}.sm\:focus\:text-orange-700:focus{--text-opacity:1;color:#c05621;color:rgba(192,86,33,var(--text-opacity))}.sm\:focus\:text-orange-800:focus{--text-opacity:1;color:#9c4221;color:rgba(156,66,33,var(--text-opacity))}.sm\:focus\:text-orange-900:focus{--text-opacity:1;color:#7b341e;color:rgba(123,52,30,var(--text-opacity))}.sm\:focus\:text-yellow-100:focus{--text-opacity:1;color:ivory;color:rgba(255,255,240,var(--text-opacity))}.sm\:focus\:text-yellow-200:focus{--text-opacity:1;color:#fefcbf;color:rgba(254,252,191,var(--text-opacity))}.sm\:focus\:text-yellow-300:focus{--text-opacity:1;color:#faf089;color:rgba(250,240,137,var(--text-opacity))}.sm\:focus\:text-yellow-400:focus{--text-opacity:1;color:#f6e05e;color:rgba(246,224,94,var(--text-opacity))}.sm\:focus\:text-yellow-500:focus{--text-opacity:1;color:#ecc94b;color:rgba(236,201,75,var(--text-opacity))}.sm\:focus\:text-yellow-600:focus{--text-opacity:1;color:#d69e2e;color:rgba(214,158,46,var(--text-opacity))}.sm\:focus\:text-yellow-700:focus{--text-opacity:1;color:#b7791f;color:rgba(183,121,31,var(--text-opacity))}.sm\:focus\:text-yellow-800:focus{--text-opacity:1;color:#975a16;color:rgba(151,90,22,var(--text-opacity))}.sm\:focus\:text-yellow-900:focus{--text-opacity:1;color:#744210;color:rgba(116,66,16,var(--text-opacity))}.sm\:focus\:text-green-100:focus{--text-opacity:1;color:#f0fff4;color:rgba(240,255,244,var(--text-opacity))}.sm\:focus\:text-green-200:focus{--text-opacity:1;color:#c6f6d5;color:rgba(198,246,213,var(--text-opacity))}.sm\:focus\:text-green-300:focus{--text-opacity:1;color:#9ae6b4;color:rgba(154,230,180,var(--text-opacity))}.sm\:focus\:text-green-400:focus{--text-opacity:1;color:#68d391;color:rgba(104,211,145,var(--text-opacity))}.sm\:focus\:text-green-500:focus{--text-opacity:1;color:#48bb78;color:rgba(72,187,120,var(--text-opacity))}.sm\:focus\:text-green-600:focus{--text-opacity:1;color:#38a169;color:rgba(56,161,105,var(--text-opacity))}.sm\:focus\:text-green-700:focus{--text-opacity:1;color:#2f855a;color:rgba(47,133,90,var(--text-opacity))}.sm\:focus\:text-green-800:focus{--text-opacity:1;color:#276749;color:rgba(39,103,73,var(--text-opacity))}.sm\:focus\:text-green-900:focus{--text-opacity:1;color:#22543d;color:rgba(34,84,61,var(--text-opacity))}.sm\:focus\:text-teal-100:focus{--text-opacity:1;color:#e6fffa;color:rgba(230,255,250,var(--text-opacity))}.sm\:focus\:text-teal-200:focus{--text-opacity:1;color:#b2f5ea;color:rgba(178,245,234,var(--text-opacity))}.sm\:focus\:text-teal-300:focus{--text-opacity:1;color:#81e6d9;color:rgba(129,230,217,var(--text-opacity))}.sm\:focus\:text-teal-400:focus{--text-opacity:1;color:#4fd1c5;color:rgba(79,209,197,var(--text-opacity))}.sm\:focus\:text-teal-500:focus{--text-opacity:1;color:#38b2ac;color:rgba(56,178,172,var(--text-opacity))}.sm\:focus\:text-teal-600:focus{--text-opacity:1;color:#319795;color:rgba(49,151,149,var(--text-opacity))}.sm\:focus\:text-teal-700:focus{--text-opacity:1;color:#2c7a7b;color:rgba(44,122,123,var(--text-opacity))}.sm\:focus\:text-teal-800:focus{--text-opacity:1;color:#285e61;color:rgba(40,94,97,var(--text-opacity))}.sm\:focus\:text-teal-900:focus{--text-opacity:1;color:#234e52;color:rgba(35,78,82,var(--text-opacity))}.sm\:focus\:text-blue-100:focus{--text-opacity:1;color:#ebf8ff;color:rgba(235,248,255,var(--text-opacity))}.sm\:focus\:text-blue-200:focus{--text-opacity:1;color:#bee3f8;color:rgba(190,227,248,var(--text-opacity))}.sm\:focus\:text-blue-300:focus{--text-opacity:1;color:#90cdf4;color:rgba(144,205,244,var(--text-opacity))}.sm\:focus\:text-blue-400:focus{--text-opacity:1;color:#63b3ed;color:rgba(99,179,237,var(--text-opacity))}.sm\:focus\:text-blue-500:focus{--text-opacity:1;color:#4299e1;color:rgba(66,153,225,var(--text-opacity))}.sm\:focus\:text-blue-600:focus{--text-opacity:1;color:#3182ce;color:rgba(49,130,206,var(--text-opacity))}.sm\:focus\:text-blue-700:focus{--text-opacity:1;color:#2b6cb0;color:rgba(43,108,176,var(--text-opacity))}.sm\:focus\:text-blue-800:focus{--text-opacity:1;color:#2c5282;color:rgba(44,82,130,var(--text-opacity))}.sm\:focus\:text-blue-900:focus{--text-opacity:1;color:#2a4365;color:rgba(42,67,101,var(--text-opacity))}.sm\:focus\:text-indigo-100:focus{--text-opacity:1;color:#ebf4ff;color:rgba(235,244,255,var(--text-opacity))}.sm\:focus\:text-indigo-200:focus{--text-opacity:1;color:#c3dafe;color:rgba(195,218,254,var(--text-opacity))}.sm\:focus\:text-indigo-300:focus{--text-opacity:1;color:#a3bffa;color:rgba(163,191,250,var(--text-opacity))}.sm\:focus\:text-indigo-400:focus{--text-opacity:1;color:#7f9cf5;color:rgba(127,156,245,var(--text-opacity))}.sm\:focus\:text-indigo-500:focus{--text-opacity:1;color:#667eea;color:rgba(102,126,234,var(--text-opacity))}.sm\:focus\:text-indigo-600:focus{--text-opacity:1;color:#5a67d8;color:rgba(90,103,216,var(--text-opacity))}.sm\:focus\:text-indigo-700:focus{--text-opacity:1;color:#4c51bf;color:rgba(76,81,191,var(--text-opacity))}.sm\:focus\:text-indigo-800:focus{--text-opacity:1;color:#434190;color:rgba(67,65,144,var(--text-opacity))}.sm\:focus\:text-indigo-900:focus{--text-opacity:1;color:#3c366b;color:rgba(60,54,107,var(--text-opacity))}.sm\:focus\:text-purple-100:focus{--text-opacity:1;color:#faf5ff;color:rgba(250,245,255,var(--text-opacity))}.sm\:focus\:text-purple-200:focus{--text-opacity:1;color:#e9d8fd;color:rgba(233,216,253,var(--text-opacity))}.sm\:focus\:text-purple-300:focus{--text-opacity:1;color:#d6bcfa;color:rgba(214,188,250,var(--text-opacity))}.sm\:focus\:text-purple-400:focus{--text-opacity:1;color:#b794f4;color:rgba(183,148,244,var(--text-opacity))}.sm\:focus\:text-purple-500:focus{--text-opacity:1;color:#9f7aea;color:rgba(159,122,234,var(--text-opacity))}.sm\:focus\:text-purple-600:focus{--text-opacity:1;color:#805ad5;color:rgba(128,90,213,var(--text-opacity))}.sm\:focus\:text-purple-700:focus{--text-opacity:1;color:#6b46c1;color:rgba(107,70,193,var(--text-opacity))}.sm\:focus\:text-purple-800:focus{--text-opacity:1;color:#553c9a;color:rgba(85,60,154,var(--text-opacity))}.sm\:focus\:text-purple-900:focus{--text-opacity:1;color:#44337a;color:rgba(68,51,122,var(--text-opacity))}.sm\:focus\:text-pink-100:focus{--text-opacity:1;color:#fff5f7;color:rgba(255,245,247,var(--text-opacity))}.sm\:focus\:text-pink-200:focus{--text-opacity:1;color:#fed7e2;color:rgba(254,215,226,var(--text-opacity))}.sm\:focus\:text-pink-300:focus{--text-opacity:1;color:#fbb6ce;color:rgba(251,182,206,var(--text-opacity))}.sm\:focus\:text-pink-400:focus{--text-opacity:1;color:#f687b3;color:rgba(246,135,179,var(--text-opacity))}.sm\:focus\:text-pink-500:focus{--text-opacity:1;color:#ed64a6;color:rgba(237,100,166,var(--text-opacity))}.sm\:focus\:text-pink-600:focus{--text-opacity:1;color:#d53f8c;color:rgba(213,63,140,var(--text-opacity))}.sm\:focus\:text-pink-700:focus{--text-opacity:1;color:#b83280;color:rgba(184,50,128,var(--text-opacity))}.sm\:focus\:text-pink-800:focus{--text-opacity:1;color:#97266d;color:rgba(151,38,109,var(--text-opacity))}.sm\:focus\:text-pink-900:focus{--text-opacity:1;color:#702459;color:rgba(112,36,89,var(--text-opacity))}.sm\:text-opacity-0{--text-opacity:0}.sm\:text-opacity-25{--text-opacity:0.25}.sm\:text-opacity-50{--text-opacity:0.5}.sm\:text-opacity-75{--text-opacity:0.75}.sm\:text-opacity-100{--text-opacity:1}.sm\:hover\:text-opacity-0:hover{--text-opacity:0}.sm\:hover\:text-opacity-25:hover{--text-opacity:0.25}.sm\:hover\:text-opacity-50:hover{--text-opacity:0.5}.sm\:hover\:text-opacity-75:hover{--text-opacity:0.75}.sm\:hover\:text-opacity-100:hover{--text-opacity:1}.sm\:focus\:text-opacity-0:focus{--text-opacity:0}.sm\:focus\:text-opacity-25:focus{--text-opacity:0.25}.sm\:focus\:text-opacity-50:focus{--text-opacity:0.5}.sm\:focus\:text-opacity-75:focus{--text-opacity:0.75}.sm\:focus\:text-opacity-100:focus{--text-opacity:1}.sm\:italic{font-style:italic}.sm\:not-italic{font-style:normal}.sm\:uppercase{text-transform:uppercase}.sm\:lowercase{text-transform:lowercase}.sm\:capitalize{text-transform:capitalize}.sm\:normal-case{text-transform:none}.sm\:underline{text-decoration:underline}.sm\:line-through{text-decoration:line-through}.sm\:no-underline{text-decoration:none}.sm\:hover\:underline:hover{text-decoration:underline}.sm\:hover\:line-through:hover{text-decoration:line-through}.sm\:hover\:no-underline:hover{text-decoration:none}.sm\:focus\:underline:focus{text-decoration:underline}.sm\:focus\:line-through:focus{text-decoration:line-through}.sm\:focus\:no-underline:focus{text-decoration:none}.sm\:antialiased{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.sm\:subpixel-antialiased{-webkit-font-smoothing:auto;-moz-osx-font-smoothing:auto}.sm\:diagonal-fractions,.sm\:lining-nums,.sm\:oldstyle-nums,.sm\:ordinal,.sm\:proportional-nums,.sm\:slashed-zero,.sm\:stacked-fractions,.sm\:tabular-nums{--font-variant-numeric-ordinal:var(--tailwind-empty, );/*!*//*!*/--font-variant-numeric-slashed-zero:var(--tailwind-empty, );/*!*//*!*/--font-variant-numeric-figure:var(--tailwind-empty, );/*!*//*!*/--font-variant-numeric-spacing:var(--tailwind-empty, );/*!*//*!*/--font-variant-numeric-fraction:var(--tailwind-empty, );/*!*//*!*/font-variant-numeric:var(--font-variant-numeric-ordinal) var(--font-variant-numeric-slashed-zero) var(--font-variant-numeric-figure) var(--font-variant-numeric-spacing) var(--font-variant-numeric-fraction)}.sm\:normal-nums{font-variant-numeric:normal}.sm\:ordinal{--font-variant-numeric-ordinal:ordinal}.sm\:slashed-zero{--font-variant-numeric-slashed-zero:slashed-zero}.sm\:lining-nums{--font-variant-numeric-figure:lining-nums}.sm\:oldstyle-nums{--font-variant-numeric-figure:oldstyle-nums}.sm\:proportional-nums{--font-variant-numeric-spacing:proportional-nums}.sm\:tabular-nums{--font-variant-numeric-spacing:tabular-nums}.sm\:diagonal-fractions{--font-variant-numeric-fraction:diagonal-fractions}.sm\:stacked-fractions{--font-variant-numeric-fraction:stacked-fractions}.sm\:tracking-tighter{letter-spacing:-.05em}.sm\:tracking-tight{letter-spacing:-.025em}.sm\:tracking-normal{letter-spacing:0}.sm\:tracking-wide{letter-spacing:.025em}.sm\:tracking-wider{letter-spacing:.05em}.sm\:tracking-widest{letter-spacing:.1em}.sm\:select-none{-webkit-user-select:none;-ms-user-select:none;user-select:none}.sm\:select-text{-webkit-user-select:text;-ms-user-select:text;user-select:text}.sm\:select-all{-webkit-user-select:all;-ms-user-select:all;user-select:all}.sm\:select-auto{-webkit-user-select:auto;-ms-user-select:auto;user-select:auto}.sm\:align-baseline{vertical-align:baseline}.sm\:align-top{vertical-align:top}.sm\:align-middle{vertical-align:middle}.sm\:align-bottom{vertical-align:bottom}.sm\:align-text-top{vertical-align:text-top}.sm\:align-text-bottom{vertical-align:text-bottom}.sm\:visible{visibility:visible}.sm\:invisible{visibility:hidden}.sm\:whitespace-normal{white-space:normal}.sm\:whitespace-no-wrap{white-space:nowrap}.sm\:whitespace-pre{white-space:pre}.sm\:whitespace-pre-line{white-space:pre-line}.sm\:whitespace-pre-wrap{white-space:pre-wrap}.sm\:break-normal{word-wrap:normal;overflow-wrap:normal;word-break:normal}.sm\:break-words{word-wrap:break-word;overflow-wrap:break-word}.sm\:break-all{word-break:break-all}.sm\:truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.sm\:w-0{width:0}.sm\:w-1{width:.25rem}.sm\:w-2{width:.5rem}.sm\:w-3{width:.75rem}.sm\:w-4{width:1rem}.sm\:w-5{width:1.25rem}.sm\:w-6{width:1.5rem}.sm\:w-8{width:2rem}.sm\:w-10{width:2.5rem}.sm\:w-12{width:3rem}.sm\:w-16{width:4rem}.sm\:w-20{width:5rem}.sm\:w-24{width:6rem}.sm\:w-32{width:8rem}.sm\:w-40{width:10rem}.sm\:w-48{width:12rem}.sm\:w-56{width:14rem}.sm\:w-64{width:16rem}.sm\:w-auto{width:auto}.sm\:w-px{width:1px}.sm\:w-1\/2{width:50%}.sm\:w-1\/3{width:33.333333%}.sm\:w-2\/3{width:66.666667%}.sm\:w-1\/4{width:25%}.sm\:w-2\/4{width:50%}.sm\:w-3\/4{width:75%}.sm\:w-1\/5{width:20%}.sm\:w-2\/5{width:40%}.sm\:w-3\/5{width:60%}.sm\:w-4\/5{width:80%}.sm\:w-1\/6{width:16.666667%}.sm\:w-2\/6{width:33.333333%}.sm\:w-3\/6{width:50%}.sm\:w-4\/6{width:66.666667%}.sm\:w-5\/6{width:83.333333%}.sm\:w-1\/12{width:8.333333%}.sm\:w-2\/12{width:16.666667%}.sm\:w-3\/12{width:25%}.sm\:w-4\/12{width:33.333333%}.sm\:w-5\/12{width:41.666667%}.sm\:w-6\/12{width:50%}.sm\:w-7\/12{width:58.333333%}.sm\:w-8\/12{width:66.666667%}.sm\:w-9\/12{width:75%}.sm\:w-10\/12{width:83.333333%}.sm\:w-11\/12{width:91.666667%}.sm\:w-full{width:100%}.sm\:w-screen{width:100vw}.sm\:z-0{z-index:0}.sm\:z-10{z-index:10}.sm\:z-20{z-index:20}.sm\:z-30{z-index:30}.sm\:z-40{z-index:40}.sm\:z-50{z-index:50}.sm\:z-auto{z-index:auto}.sm\:gap-0{grid-gap:0;gap:0}.sm\:gap-1{grid-gap:.25rem;gap:.25rem}.sm\:gap-2{grid-gap:.5rem;gap:.5rem}.sm\:gap-3{grid-gap:.75rem;gap:.75rem}.sm\:gap-4{grid-gap:1rem;gap:1rem}.sm\:gap-5{grid-gap:1.25rem;gap:1.25rem}.sm\:gap-6{grid-gap:1.5rem;gap:1.5rem}.sm\:gap-8{grid-gap:2rem;gap:2rem}.sm\:gap-10{grid-gap:2.5rem;gap:2.5rem}.sm\:gap-12{grid-gap:3rem;gap:3rem}.sm\:gap-16{grid-gap:4rem;gap:4rem}.sm\:gap-20{grid-gap:5rem;gap:5rem}.sm\:gap-24{grid-gap:6rem;gap:6rem}.sm\:gap-32{grid-gap:8rem;gap:8rem}.sm\:gap-40{grid-gap:10rem;gap:10rem}.sm\:gap-48{grid-gap:12rem;gap:12rem}.sm\:gap-56{grid-gap:14rem;gap:14rem}.sm\:gap-64{grid-gap:16rem;gap:16rem}.sm\:gap-px{grid-gap:1px;gap:1px}.sm\:col-gap-0{grid-column-gap:0;column-gap:0}.sm\:col-gap-1{grid-column-gap:.25rem;column-gap:.25rem}.sm\:col-gap-2{grid-column-gap:.5rem;column-gap:.5rem}.sm\:col-gap-3{grid-column-gap:.75rem;column-gap:.75rem}.sm\:col-gap-4{grid-column-gap:1rem;column-gap:1rem}.sm\:col-gap-5{grid-column-gap:1.25rem;column-gap:1.25rem}.sm\:col-gap-6{grid-column-gap:1.5rem;column-gap:1.5rem}.sm\:col-gap-8{grid-column-gap:2rem;column-gap:2rem}.sm\:col-gap-10{grid-column-gap:2.5rem;column-gap:2.5rem}.sm\:col-gap-12{grid-column-gap:3rem;column-gap:3rem}.sm\:col-gap-16{grid-column-gap:4rem;column-gap:4rem}.sm\:col-gap-20{grid-column-gap:5rem;column-gap:5rem}.sm\:col-gap-24{grid-column-gap:6rem;column-gap:6rem}.sm\:col-gap-32{grid-column-gap:8rem;column-gap:8rem}.sm\:col-gap-40{grid-column-gap:10rem;column-gap:10rem}.sm\:col-gap-48{grid-column-gap:12rem;column-gap:12rem}.sm\:col-gap-56{grid-column-gap:14rem;column-gap:14rem}.sm\:col-gap-64{grid-column-gap:16rem;column-gap:16rem}.sm\:col-gap-px{grid-column-gap:1px;column-gap:1px}.sm\:gap-x-0{grid-column-gap:0;column-gap:0}.sm\:gap-x-1{grid-column-gap:.25rem;column-gap:.25rem}.sm\:gap-x-2{grid-column-gap:.5rem;column-gap:.5rem}.sm\:gap-x-3{grid-column-gap:.75rem;column-gap:.75rem}.sm\:gap-x-4{grid-column-gap:1rem;column-gap:1rem}.sm\:gap-x-5{grid-column-gap:1.25rem;column-gap:1.25rem}.sm\:gap-x-6{grid-column-gap:1.5rem;column-gap:1.5rem}.sm\:gap-x-8{grid-column-gap:2rem;column-gap:2rem}.sm\:gap-x-10{grid-column-gap:2.5rem;column-gap:2.5rem}.sm\:gap-x-12{grid-column-gap:3rem;column-gap:3rem}.sm\:gap-x-16{grid-column-gap:4rem;column-gap:4rem}.sm\:gap-x-20{grid-column-gap:5rem;column-gap:5rem}.sm\:gap-x-24{grid-column-gap:6rem;column-gap:6rem}.sm\:gap-x-32{grid-column-gap:8rem;column-gap:8rem}.sm\:gap-x-40{grid-column-gap:10rem;column-gap:10rem}.sm\:gap-x-48{grid-column-gap:12rem;column-gap:12rem}.sm\:gap-x-56{grid-column-gap:14rem;column-gap:14rem}.sm\:gap-x-64{grid-column-gap:16rem;column-gap:16rem}.sm\:gap-x-px{grid-column-gap:1px;column-gap:1px}.sm\:row-gap-0{grid-row-gap:0;row-gap:0}.sm\:row-gap-1{grid-row-gap:.25rem;row-gap:.25rem}.sm\:row-gap-2{grid-row-gap:.5rem;row-gap:.5rem}.sm\:row-gap-3{grid-row-gap:.75rem;row-gap:.75rem}.sm\:row-gap-4{grid-row-gap:1rem;row-gap:1rem}.sm\:row-gap-5{grid-row-gap:1.25rem;row-gap:1.25rem}.sm\:row-gap-6{grid-row-gap:1.5rem;row-gap:1.5rem}.sm\:row-gap-8{grid-row-gap:2rem;row-gap:2rem}.sm\:row-gap-10{grid-row-gap:2.5rem;row-gap:2.5rem}.sm\:row-gap-12{grid-row-gap:3rem;row-gap:3rem}.sm\:row-gap-16{grid-row-gap:4rem;row-gap:4rem}.sm\:row-gap-20{grid-row-gap:5rem;row-gap:5rem}.sm\:row-gap-24{grid-row-gap:6rem;row-gap:6rem}.sm\:row-gap-32{grid-row-gap:8rem;row-gap:8rem}.sm\:row-gap-40{grid-row-gap:10rem;row-gap:10rem}.sm\:row-gap-48{grid-row-gap:12rem;row-gap:12rem}.sm\:row-gap-56{grid-row-gap:14rem;row-gap:14rem}.sm\:row-gap-64{grid-row-gap:16rem;row-gap:16rem}.sm\:row-gap-px{grid-row-gap:1px;row-gap:1px}.sm\:gap-y-0{grid-row-gap:0;row-gap:0}.sm\:gap-y-1{grid-row-gap:.25rem;row-gap:.25rem}.sm\:gap-y-2{grid-row-gap:.5rem;row-gap:.5rem}.sm\:gap-y-3{grid-row-gap:.75rem;row-gap:.75rem}.sm\:gap-y-4{grid-row-gap:1rem;row-gap:1rem}.sm\:gap-y-5{grid-row-gap:1.25rem;row-gap:1.25rem}.sm\:gap-y-6{grid-row-gap:1.5rem;row-gap:1.5rem}.sm\:gap-y-8{grid-row-gap:2rem;row-gap:2rem}.sm\:gap-y-10{grid-row-gap:2.5rem;row-gap:2.5rem}.sm\:gap-y-12{grid-row-gap:3rem;row-gap:3rem}.sm\:gap-y-16{grid-row-gap:4rem;row-gap:4rem}.sm\:gap-y-20{grid-row-gap:5rem;row-gap:5rem}.sm\:gap-y-24{grid-row-gap:6rem;row-gap:6rem}.sm\:gap-y-32{grid-row-gap:8rem;row-gap:8rem}.sm\:gap-y-40{grid-row-gap:10rem;row-gap:10rem}.sm\:gap-y-48{grid-row-gap:12rem;row-gap:12rem}.sm\:gap-y-56{grid-row-gap:14rem;row-gap:14rem}.sm\:gap-y-64{grid-row-gap:16rem;row-gap:16rem}.sm\:gap-y-px{grid-row-gap:1px;row-gap:1px}.sm\:grid-flow-row{grid-auto-flow:row}.sm\:grid-flow-col{grid-auto-flow:column}.sm\:grid-flow-row-dense{grid-auto-flow:row dense}.sm\:grid-flow-col-dense{grid-auto-flow:column dense}.sm\:grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.sm\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.sm\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.sm\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.sm\:grid-cols-5{grid-template-columns:repeat(5,minmax(0,1fr))}.sm\:grid-cols-6{grid-template-columns:repeat(6,minmax(0,1fr))}.sm\:grid-cols-7{grid-template-columns:repeat(7,minmax(0,1fr))}.sm\:grid-cols-8{grid-template-columns:repeat(8,minmax(0,1fr))}.sm\:grid-cols-9{grid-template-columns:repeat(9,minmax(0,1fr))}.sm\:grid-cols-10{grid-template-columns:repeat(10,minmax(0,1fr))}.sm\:grid-cols-11{grid-template-columns:repeat(11,minmax(0,1fr))}.sm\:grid-cols-12{grid-template-columns:repeat(12,minmax(0,1fr))}.sm\:grid-cols-none{grid-template-columns:none}.sm\:auto-cols-auto{grid-auto-columns:auto}.sm\:auto-cols-min{grid-auto-columns:-webkit-min-content;grid-auto-columns:min-content}.sm\:auto-cols-max{grid-auto-columns:-webkit-max-content;grid-auto-columns:max-content}.sm\:auto-cols-fr{grid-auto-columns:minmax(0,1fr)}.sm\:col-auto{grid-column:auto}.sm\:col-span-1{grid-column:span 1/span 1}.sm\:col-span-2{grid-column:span 2/span 2}.sm\:col-span-3{grid-column:span 3/span 3}.sm\:col-span-4{grid-column:span 4/span 4}.sm\:col-span-5{grid-column:span 5/span 5}.sm\:col-span-6{grid-column:span 6/span 6}.sm\:col-span-7{grid-column:span 7/span 7}.sm\:col-span-8{grid-column:span 8/span 8}.sm\:col-span-9{grid-column:span 9/span 9}.sm\:col-span-10{grid-column:span 10/span 10}.sm\:col-span-11{grid-column:span 11/span 11}.sm\:col-span-12{grid-column:span 12/span 12}.sm\:col-span-full{grid-column:1/-1}.sm\:col-start-1{grid-column-start:1}.sm\:col-start-2{grid-column-start:2}.sm\:col-start-3{grid-column-start:3}.sm\:col-start-4{grid-column-start:4}.sm\:col-start-5{grid-column-start:5}.sm\:col-start-6{grid-column-start:6}.sm\:col-start-7{grid-column-start:7}.sm\:col-start-8{grid-column-start:8}.sm\:col-start-9{grid-column-start:9}.sm\:col-start-10{grid-column-start:10}.sm\:col-start-11{grid-column-start:11}.sm\:col-start-12{grid-column-start:12}.sm\:col-start-13{grid-column-start:13}.sm\:col-start-auto{grid-column-start:auto}.sm\:col-end-1{grid-column-end:1}.sm\:col-end-2{grid-column-end:2}.sm\:col-end-3{grid-column-end:3}.sm\:col-end-4{grid-column-end:4}.sm\:col-end-5{grid-column-end:5}.sm\:col-end-6{grid-column-end:6}.sm\:col-end-7{grid-column-end:7}.sm\:col-end-8{grid-column-end:8}.sm\:col-end-9{grid-column-end:9}.sm\:col-end-10{grid-column-end:10}.sm\:col-end-11{grid-column-end:11}.sm\:col-end-12{grid-column-end:12}.sm\:col-end-13{grid-column-end:13}.sm\:col-end-auto{grid-column-end:auto}.sm\:grid-rows-1{grid-template-rows:repeat(1,minmax(0,1fr))}.sm\:grid-rows-2{grid-template-rows:repeat(2,minmax(0,1fr))}.sm\:grid-rows-3{grid-template-rows:repeat(3,minmax(0,1fr))}.sm\:grid-rows-4{grid-template-rows:repeat(4,minmax(0,1fr))}.sm\:grid-rows-5{grid-template-rows:repeat(5,minmax(0,1fr))}.sm\:grid-rows-6{grid-template-rows:repeat(6,minmax(0,1fr))}.sm\:grid-rows-none{grid-template-rows:none}.sm\:auto-rows-auto{grid-auto-rows:auto}.sm\:auto-rows-min{grid-auto-rows:-webkit-min-content;grid-auto-rows:min-content}.sm\:auto-rows-max{grid-auto-rows:-webkit-max-content;grid-auto-rows:max-content}.sm\:auto-rows-fr{grid-auto-rows:minmax(0,1fr)}.sm\:row-auto{grid-row:auto}.sm\:row-span-1{grid-row:span 1/span 1}.sm\:row-span-2{grid-row:span 2/span 2}.sm\:row-span-3{grid-row:span 3/span 3}.sm\:row-span-4{grid-row:span 4/span 4}.sm\:row-span-5{grid-row:span 5/span 5}.sm\:row-span-6{grid-row:span 6/span 6}.sm\:row-span-full{grid-row:1/-1}.sm\:row-start-1{grid-row-start:1}.sm\:row-start-2{grid-row-start:2}.sm\:row-start-3{grid-row-start:3}.sm\:row-start-4{grid-row-start:4}.sm\:row-start-5{grid-row-start:5}.sm\:row-start-6{grid-row-start:6}.sm\:row-start-7{grid-row-start:7}.sm\:row-start-auto{grid-row-start:auto}.sm\:row-end-1{grid-row-end:1}.sm\:row-end-2{grid-row-end:2}.sm\:row-end-3{grid-row-end:3}.sm\:row-end-4{grid-row-end:4}.sm\:row-end-5{grid-row-end:5}.sm\:row-end-6{grid-row-end:6}.sm\:row-end-7{grid-row-end:7}.sm\:row-end-auto{grid-row-end:auto}.sm\:transform{--transform-translate-x:0;--transform-translate-y:0;--transform-rotate:0;--transform-skew-x:0;--transform-skew-y:0;--transform-scale-x:1;--transform-scale-y:1;transform:translateX(var(--transform-translate-x)) translateY(var(--transform-translate-y)) rotate(var(--transform-rotate)) skewX(var(--transform-skew-x)) skewY(var(--transform-skew-y)) scaleX(var(--transform-scale-x)) scaleY(var(--transform-scale-y))}.sm\:transform-none{transform:none}.sm\:origin-center{transform-origin:center}.sm\:origin-top{transform-origin:top}.sm\:origin-top-right{transform-origin:top right}.sm\:origin-right{transform-origin:right}.sm\:origin-bottom-right{transform-origin:bottom right}.sm\:origin-bottom{transform-origin:bottom}.sm\:origin-bottom-left{transform-origin:bottom left}.sm\:origin-left{transform-origin:left}.sm\:origin-top-left{transform-origin:top left}.sm\:scale-0{--transform-scale-x:0;--transform-scale-y:0}.sm\:scale-50{--transform-scale-x:.5;--transform-scale-y:.5}.sm\:scale-75{--transform-scale-x:.75;--transform-scale-y:.75}.sm\:scale-90{--transform-scale-x:.9;--transform-scale-y:.9}.sm\:scale-95{--transform-scale-x:.95;--transform-scale-y:.95}.sm\:scale-100{--transform-scale-x:1;--transform-scale-y:1}.sm\:scale-105{--transform-scale-x:1.05;--transform-scale-y:1.05}.sm\:scale-110{--transform-scale-x:1.1;--transform-scale-y:1.1}.sm\:scale-125{--transform-scale-x:1.25;--transform-scale-y:1.25}.sm\:scale-150{--transform-scale-x:1.5;--transform-scale-y:1.5}.sm\:scale-x-0{--transform-scale-x:0}.sm\:scale-x-50{--transform-scale-x:.5}.sm\:scale-x-75{--transform-scale-x:.75}.sm\:scale-x-90{--transform-scale-x:.9}.sm\:scale-x-95{--transform-scale-x:.95}.sm\:scale-x-100{--transform-scale-x:1}.sm\:scale-x-105{--transform-scale-x:1.05}.sm\:scale-x-110{--transform-scale-x:1.1}.sm\:scale-x-125{--transform-scale-x:1.25}.sm\:scale-x-150{--transform-scale-x:1.5}.sm\:scale-y-0{--transform-scale-y:0}.sm\:scale-y-50{--transform-scale-y:.5}.sm\:scale-y-75{--transform-scale-y:.75}.sm\:scale-y-90{--transform-scale-y:.9}.sm\:scale-y-95{--transform-scale-y:.95}.sm\:scale-y-100{--transform-scale-y:1}.sm\:scale-y-105{--transform-scale-y:1.05}.sm\:scale-y-110{--transform-scale-y:1.1}.sm\:scale-y-125{--transform-scale-y:1.25}.sm\:scale-y-150{--transform-scale-y:1.5}.sm\:hover\:scale-0:hover{--transform-scale-x:0;--transform-scale-y:0}.sm\:hover\:scale-50:hover{--transform-scale-x:.5;--transform-scale-y:.5}.sm\:hover\:scale-75:hover{--transform-scale-x:.75;--transform-scale-y:.75}.sm\:hover\:scale-90:hover{--transform-scale-x:.9;--transform-scale-y:.9}.sm\:hover\:scale-95:hover{--transform-scale-x:.95;--transform-scale-y:.95}.sm\:hover\:scale-100:hover{--transform-scale-x:1;--transform-scale-y:1}.sm\:hover\:scale-105:hover{--transform-scale-x:1.05;--transform-scale-y:1.05}.sm\:hover\:scale-110:hover{--transform-scale-x:1.1;--transform-scale-y:1.1}.sm\:hover\:scale-125:hover{--transform-scale-x:1.25;--transform-scale-y:1.25}.sm\:hover\:scale-150:hover{--transform-scale-x:1.5;--transform-scale-y:1.5}.sm\:hover\:scale-x-0:hover{--transform-scale-x:0}.sm\:hover\:scale-x-50:hover{--transform-scale-x:.5}.sm\:hover\:scale-x-75:hover{--transform-scale-x:.75}.sm\:hover\:scale-x-90:hover{--transform-scale-x:.9}.sm\:hover\:scale-x-95:hover{--transform-scale-x:.95}.sm\:hover\:scale-x-100:hover{--transform-scale-x:1}.sm\:hover\:scale-x-105:hover{--transform-scale-x:1.05}.sm\:hover\:scale-x-110:hover{--transform-scale-x:1.1}.sm\:hover\:scale-x-125:hover{--transform-scale-x:1.25}.sm\:hover\:scale-x-150:hover{--transform-scale-x:1.5}.sm\:hover\:scale-y-0:hover{--transform-scale-y:0}.sm\:hover\:scale-y-50:hover{--transform-scale-y:.5}.sm\:hover\:scale-y-75:hover{--transform-scale-y:.75}.sm\:hover\:scale-y-90:hover{--transform-scale-y:.9}.sm\:hover\:scale-y-95:hover{--transform-scale-y:.95}.sm\:hover\:scale-y-100:hover{--transform-scale-y:1}.sm\:hover\:scale-y-105:hover{--transform-scale-y:1.05}.sm\:hover\:scale-y-110:hover{--transform-scale-y:1.1}.sm\:hover\:scale-y-125:hover{--transform-scale-y:1.25}.sm\:hover\:scale-y-150:hover{--transform-scale-y:1.5}.sm\:focus\:scale-0:focus{--transform-scale-x:0;--transform-scale-y:0}.sm\:focus\:scale-50:focus{--transform-scale-x:.5;--transform-scale-y:.5}.sm\:focus\:scale-75:focus{--transform-scale-x:.75;--transform-scale-y:.75}.sm\:focus\:scale-90:focus{--transform-scale-x:.9;--transform-scale-y:.9}.sm\:focus\:scale-95:focus{--transform-scale-x:.95;--transform-scale-y:.95}.sm\:focus\:scale-100:focus{--transform-scale-x:1;--transform-scale-y:1}.sm\:focus\:scale-105:focus{--transform-scale-x:1.05;--transform-scale-y:1.05}.sm\:focus\:scale-110:focus{--transform-scale-x:1.1;--transform-scale-y:1.1}.sm\:focus\:scale-125:focus{--transform-scale-x:1.25;--transform-scale-y:1.25}.sm\:focus\:scale-150:focus{--transform-scale-x:1.5;--transform-scale-y:1.5}.sm\:focus\:scale-x-0:focus{--transform-scale-x:0}.sm\:focus\:scale-x-50:focus{--transform-scale-x:.5}.sm\:focus\:scale-x-75:focus{--transform-scale-x:.75}.sm\:focus\:scale-x-90:focus{--transform-scale-x:.9}.sm\:focus\:scale-x-95:focus{--transform-scale-x:.95}.sm\:focus\:scale-x-100:focus{--transform-scale-x:1}.sm\:focus\:scale-x-105:focus{--transform-scale-x:1.05}.sm\:focus\:scale-x-110:focus{--transform-scale-x:1.1}.sm\:focus\:scale-x-125:focus{--transform-scale-x:1.25}.sm\:focus\:scale-x-150:focus{--transform-scale-x:1.5}.sm\:focus\:scale-y-0:focus{--transform-scale-y:0}.sm\:focus\:scale-y-50:focus{--transform-scale-y:.5}.sm\:focus\:scale-y-75:focus{--transform-scale-y:.75}.sm\:focus\:scale-y-90:focus{--transform-scale-y:.9}.sm\:focus\:scale-y-95:focus{--transform-scale-y:.95}.sm\:focus\:scale-y-100:focus{--transform-scale-y:1}.sm\:focus\:scale-y-105:focus{--transform-scale-y:1.05}.sm\:focus\:scale-y-110:focus{--transform-scale-y:1.1}.sm\:focus\:scale-y-125:focus{--transform-scale-y:1.25}.sm\:focus\:scale-y-150:focus{--transform-scale-y:1.5}.sm\:rotate-0{--transform-rotate:0}.sm\:rotate-1{--transform-rotate:1deg}.sm\:rotate-2{--transform-rotate:2deg}.sm\:rotate-3{--transform-rotate:3deg}.sm\:rotate-6{--transform-rotate:6deg}.sm\:rotate-12{--transform-rotate:12deg}.sm\:rotate-45{--transform-rotate:45deg}.sm\:rotate-90{--transform-rotate:90deg}.sm\:rotate-180{--transform-rotate:180deg}.sm\:-rotate-180{--transform-rotate:-180deg}.sm\:-rotate-90{--transform-rotate:-90deg}.sm\:-rotate-45{--transform-rotate:-45deg}.sm\:-rotate-12{--transform-rotate:-12deg}.sm\:-rotate-6{--transform-rotate:-6deg}.sm\:-rotate-3{--transform-rotate:-3deg}.sm\:-rotate-2{--transform-rotate:-2deg}.sm\:-rotate-1{--transform-rotate:-1deg}.sm\:hover\:rotate-0:hover{--transform-rotate:0}.sm\:hover\:rotate-1:hover{--transform-rotate:1deg}.sm\:hover\:rotate-2:hover{--transform-rotate:2deg}.sm\:hover\:rotate-3:hover{--transform-rotate:3deg}.sm\:hover\:rotate-6:hover{--transform-rotate:6deg}.sm\:hover\:rotate-12:hover{--transform-rotate:12deg}.sm\:hover\:rotate-45:hover{--transform-rotate:45deg}.sm\:hover\:rotate-90:hover{--transform-rotate:90deg}.sm\:hover\:rotate-180:hover{--transform-rotate:180deg}.sm\:hover\:-rotate-180:hover{--transform-rotate:-180deg}.sm\:hover\:-rotate-90:hover{--transform-rotate:-90deg}.sm\:hover\:-rotate-45:hover{--transform-rotate:-45deg}.sm\:hover\:-rotate-12:hover{--transform-rotate:-12deg}.sm\:hover\:-rotate-6:hover{--transform-rotate:-6deg}.sm\:hover\:-rotate-3:hover{--transform-rotate:-3deg}.sm\:hover\:-rotate-2:hover{--transform-rotate:-2deg}.sm\:hover\:-rotate-1:hover{--transform-rotate:-1deg}.sm\:focus\:rotate-0:focus{--transform-rotate:0}.sm\:focus\:rotate-1:focus{--transform-rotate:1deg}.sm\:focus\:rotate-2:focus{--transform-rotate:2deg}.sm\:focus\:rotate-3:focus{--transform-rotate:3deg}.sm\:focus\:rotate-6:focus{--transform-rotate:6deg}.sm\:focus\:rotate-12:focus{--transform-rotate:12deg}.sm\:focus\:rotate-45:focus{--transform-rotate:45deg}.sm\:focus\:rotate-90:focus{--transform-rotate:90deg}.sm\:focus\:rotate-180:focus{--transform-rotate:180deg}.sm\:focus\:-rotate-180:focus{--transform-rotate:-180deg}.sm\:focus\:-rotate-90:focus{--transform-rotate:-90deg}.sm\:focus\:-rotate-45:focus{--transform-rotate:-45deg}.sm\:focus\:-rotate-12:focus{--transform-rotate:-12deg}.sm\:focus\:-rotate-6:focus{--transform-rotate:-6deg}.sm\:focus\:-rotate-3:focus{--transform-rotate:-3deg}.sm\:focus\:-rotate-2:focus{--transform-rotate:-2deg}.sm\:focus\:-rotate-1:focus{--transform-rotate:-1deg}.sm\:translate-x-0{--transform-translate-x:0}.sm\:translate-x-1{--transform-translate-x:0.25rem}.sm\:translate-x-2{--transform-translate-x:0.5rem}.sm\:translate-x-3{--transform-translate-x:0.75rem}.sm\:translate-x-4{--transform-translate-x:1rem}.sm\:translate-x-5{--transform-translate-x:1.25rem}.sm\:translate-x-6{--transform-translate-x:1.5rem}.sm\:translate-x-8{--transform-translate-x:2rem}.sm\:translate-x-10{--transform-translate-x:2.5rem}.sm\:translate-x-12{--transform-translate-x:3rem}.sm\:translate-x-16{--transform-translate-x:4rem}.sm\:translate-x-20{--transform-translate-x:5rem}.sm\:translate-x-24{--transform-translate-x:6rem}.sm\:translate-x-32{--transform-translate-x:8rem}.sm\:translate-x-40{--transform-translate-x:10rem}.sm\:translate-x-48{--transform-translate-x:12rem}.sm\:translate-x-56{--transform-translate-x:14rem}.sm\:translate-x-64{--transform-translate-x:16rem}.sm\:translate-x-px{--transform-translate-x:1px}.sm\:-translate-x-1{--transform-translate-x:-0.25rem}.sm\:-translate-x-2{--transform-translate-x:-0.5rem}.sm\:-translate-x-3{--transform-translate-x:-0.75rem}.sm\:-translate-x-4{--transform-translate-x:-1rem}.sm\:-translate-x-5{--transform-translate-x:-1.25rem}.sm\:-translate-x-6{--transform-translate-x:-1.5rem}.sm\:-translate-x-8{--transform-translate-x:-2rem}.sm\:-translate-x-10{--transform-translate-x:-2.5rem}.sm\:-translate-x-12{--transform-translate-x:-3rem}.sm\:-translate-x-16{--transform-translate-x:-4rem}.sm\:-translate-x-20{--transform-translate-x:-5rem}.sm\:-translate-x-24{--transform-translate-x:-6rem}.sm\:-translate-x-32{--transform-translate-x:-8rem}.sm\:-translate-x-40{--transform-translate-x:-10rem}.sm\:-translate-x-48{--transform-translate-x:-12rem}.sm\:-translate-x-56{--transform-translate-x:-14rem}.sm\:-translate-x-64{--transform-translate-x:-16rem}.sm\:-translate-x-px{--transform-translate-x:-1px}.sm\:-translate-x-full{--transform-translate-x:-100%}.sm\:-translate-x-1\/2{--transform-translate-x:-50%}.sm\:translate-x-1\/2{--transform-translate-x:50%}.sm\:translate-x-full{--transform-translate-x:100%}.sm\:translate-y-0{--transform-translate-y:0}.sm\:translate-y-1{--transform-translate-y:0.25rem}.sm\:translate-y-2{--transform-translate-y:0.5rem}.sm\:translate-y-3{--transform-translate-y:0.75rem}.sm\:translate-y-4{--transform-translate-y:1rem}.sm\:translate-y-5{--transform-translate-y:1.25rem}.sm\:translate-y-6{--transform-translate-y:1.5rem}.sm\:translate-y-8{--transform-translate-y:2rem}.sm\:translate-y-10{--transform-translate-y:2.5rem}.sm\:translate-y-12{--transform-translate-y:3rem}.sm\:translate-y-16{--transform-translate-y:4rem}.sm\:translate-y-20{--transform-translate-y:5rem}.sm\:translate-y-24{--transform-translate-y:6rem}.sm\:translate-y-32{--transform-translate-y:8rem}.sm\:translate-y-40{--transform-translate-y:10rem}.sm\:translate-y-48{--transform-translate-y:12rem}.sm\:translate-y-56{--transform-translate-y:14rem}.sm\:translate-y-64{--transform-translate-y:16rem}.sm\:translate-y-px{--transform-translate-y:1px}.sm\:-translate-y-1{--transform-translate-y:-0.25rem}.sm\:-translate-y-2{--transform-translate-y:-0.5rem}.sm\:-translate-y-3{--transform-translate-y:-0.75rem}.sm\:-translate-y-4{--transform-translate-y:-1rem}.sm\:-translate-y-5{--transform-translate-y:-1.25rem}.sm\:-translate-y-6{--transform-translate-y:-1.5rem}.sm\:-translate-y-8{--transform-translate-y:-2rem}.sm\:-translate-y-10{--transform-translate-y:-2.5rem}.sm\:-translate-y-12{--transform-translate-y:-3rem}.sm\:-translate-y-16{--transform-translate-y:-4rem}.sm\:-translate-y-20{--transform-translate-y:-5rem}.sm\:-translate-y-24{--transform-translate-y:-6rem}.sm\:-translate-y-32{--transform-translate-y:-8rem}.sm\:-translate-y-40{--transform-translate-y:-10rem}.sm\:-translate-y-48{--transform-translate-y:-12rem}.sm\:-translate-y-56{--transform-translate-y:-14rem}.sm\:-translate-y-64{--transform-translate-y:-16rem}.sm\:-translate-y-px{--transform-translate-y:-1px}.sm\:-translate-y-full{--transform-translate-y:-100%}.sm\:-translate-y-1\/2{--transform-translate-y:-50%}.sm\:translate-y-1\/2{--transform-translate-y:50%}.sm\:translate-y-full{--transform-translate-y:100%}.sm\:hover\:translate-x-0:hover{--transform-translate-x:0}.sm\:hover\:translate-x-1:hover{--transform-translate-x:0.25rem}.sm\:hover\:translate-x-2:hover{--transform-translate-x:0.5rem}.sm\:hover\:translate-x-3:hover{--transform-translate-x:0.75rem}.sm\:hover\:translate-x-4:hover{--transform-translate-x:1rem}.sm\:hover\:translate-x-5:hover{--transform-translate-x:1.25rem}.sm\:hover\:translate-x-6:hover{--transform-translate-x:1.5rem}.sm\:hover\:translate-x-8:hover{--transform-translate-x:2rem}.sm\:hover\:translate-x-10:hover{--transform-translate-x:2.5rem}.sm\:hover\:translate-x-12:hover{--transform-translate-x:3rem}.sm\:hover\:translate-x-16:hover{--transform-translate-x:4rem}.sm\:hover\:translate-x-20:hover{--transform-translate-x:5rem}.sm\:hover\:translate-x-24:hover{--transform-translate-x:6rem}.sm\:hover\:translate-x-32:hover{--transform-translate-x:8rem}.sm\:hover\:translate-x-40:hover{--transform-translate-x:10rem}.sm\:hover\:translate-x-48:hover{--transform-translate-x:12rem}.sm\:hover\:translate-x-56:hover{--transform-translate-x:14rem}.sm\:hover\:translate-x-64:hover{--transform-translate-x:16rem}.sm\:hover\:translate-x-px:hover{--transform-translate-x:1px}.sm\:hover\:-translate-x-1:hover{--transform-translate-x:-0.25rem}.sm\:hover\:-translate-x-2:hover{--transform-translate-x:-0.5rem}.sm\:hover\:-translate-x-3:hover{--transform-translate-x:-0.75rem}.sm\:hover\:-translate-x-4:hover{--transform-translate-x:-1rem}.sm\:hover\:-translate-x-5:hover{--transform-translate-x:-1.25rem}.sm\:hover\:-translate-x-6:hover{--transform-translate-x:-1.5rem}.sm\:hover\:-translate-x-8:hover{--transform-translate-x:-2rem}.sm\:hover\:-translate-x-10:hover{--transform-translate-x:-2.5rem}.sm\:hover\:-translate-x-12:hover{--transform-translate-x:-3rem}.sm\:hover\:-translate-x-16:hover{--transform-translate-x:-4rem}.sm\:hover\:-translate-x-20:hover{--transform-translate-x:-5rem}.sm\:hover\:-translate-x-24:hover{--transform-translate-x:-6rem}.sm\:hover\:-translate-x-32:hover{--transform-translate-x:-8rem}.sm\:hover\:-translate-x-40:hover{--transform-translate-x:-10rem}.sm\:hover\:-translate-x-48:hover{--transform-translate-x:-12rem}.sm\:hover\:-translate-x-56:hover{--transform-translate-x:-14rem}.sm\:hover\:-translate-x-64:hover{--transform-translate-x:-16rem}.sm\:hover\:-translate-x-px:hover{--transform-translate-x:-1px}.sm\:hover\:-translate-x-full:hover{--transform-translate-x:-100%}.sm\:hover\:-translate-x-1\/2:hover{--transform-translate-x:-50%}.sm\:hover\:translate-x-1\/2:hover{--transform-translate-x:50%}.sm\:hover\:translate-x-full:hover{--transform-translate-x:100%}.sm\:hover\:translate-y-0:hover{--transform-translate-y:0}.sm\:hover\:translate-y-1:hover{--transform-translate-y:0.25rem}.sm\:hover\:translate-y-2:hover{--transform-translate-y:0.5rem}.sm\:hover\:translate-y-3:hover{--transform-translate-y:0.75rem}.sm\:hover\:translate-y-4:hover{--transform-translate-y:1rem}.sm\:hover\:translate-y-5:hover{--transform-translate-y:1.25rem}.sm\:hover\:translate-y-6:hover{--transform-translate-y:1.5rem}.sm\:hover\:translate-y-8:hover{--transform-translate-y:2rem}.sm\:hover\:translate-y-10:hover{--transform-translate-y:2.5rem}.sm\:hover\:translate-y-12:hover{--transform-translate-y:3rem}.sm\:hover\:translate-y-16:hover{--transform-translate-y:4rem}.sm\:hover\:translate-y-20:hover{--transform-translate-y:5rem}.sm\:hover\:translate-y-24:hover{--transform-translate-y:6rem}.sm\:hover\:translate-y-32:hover{--transform-translate-y:8rem}.sm\:hover\:translate-y-40:hover{--transform-translate-y:10rem}.sm\:hover\:translate-y-48:hover{--transform-translate-y:12rem}.sm\:hover\:translate-y-56:hover{--transform-translate-y:14rem}.sm\:hover\:translate-y-64:hover{--transform-translate-y:16rem}.sm\:hover\:translate-y-px:hover{--transform-translate-y:1px}.sm\:hover\:-translate-y-1:hover{--transform-translate-y:-0.25rem}.sm\:hover\:-translate-y-2:hover{--transform-translate-y:-0.5rem}.sm\:hover\:-translate-y-3:hover{--transform-translate-y:-0.75rem}.sm\:hover\:-translate-y-4:hover{--transform-translate-y:-1rem}.sm\:hover\:-translate-y-5:hover{--transform-translate-y:-1.25rem}.sm\:hover\:-translate-y-6:hover{--transform-translate-y:-1.5rem}.sm\:hover\:-translate-y-8:hover{--transform-translate-y:-2rem}.sm\:hover\:-translate-y-10:hover{--transform-translate-y:-2.5rem}.sm\:hover\:-translate-y-12:hover{--transform-translate-y:-3rem}.sm\:hover\:-translate-y-16:hover{--transform-translate-y:-4rem}.sm\:hover\:-translate-y-20:hover{--transform-translate-y:-5rem}.sm\:hover\:-translate-y-24:hover{--transform-translate-y:-6rem}.sm\:hover\:-translate-y-32:hover{--transform-translate-y:-8rem}.sm\:hover\:-translate-y-40:hover{--transform-translate-y:-10rem}.sm\:hover\:-translate-y-48:hover{--transform-translate-y:-12rem}.sm\:hover\:-translate-y-56:hover{--transform-translate-y:-14rem}.sm\:hover\:-translate-y-64:hover{--transform-translate-y:-16rem}.sm\:hover\:-translate-y-px:hover{--transform-translate-y:-1px}.sm\:hover\:-translate-y-full:hover{--transform-translate-y:-100%}.sm\:hover\:-translate-y-1\/2:hover{--transform-translate-y:-50%}.sm\:hover\:translate-y-1\/2:hover{--transform-translate-y:50%}.sm\:hover\:translate-y-full:hover{--transform-translate-y:100%}.sm\:focus\:translate-x-0:focus{--transform-translate-x:0}.sm\:focus\:translate-x-1:focus{--transform-translate-x:0.25rem}.sm\:focus\:translate-x-2:focus{--transform-translate-x:0.5rem}.sm\:focus\:translate-x-3:focus{--transform-translate-x:0.75rem}.sm\:focus\:translate-x-4:focus{--transform-translate-x:1rem}.sm\:focus\:translate-x-5:focus{--transform-translate-x:1.25rem}.sm\:focus\:translate-x-6:focus{--transform-translate-x:1.5rem}.sm\:focus\:translate-x-8:focus{--transform-translate-x:2rem}.sm\:focus\:translate-x-10:focus{--transform-translate-x:2.5rem}.sm\:focus\:translate-x-12:focus{--transform-translate-x:3rem}.sm\:focus\:translate-x-16:focus{--transform-translate-x:4rem}.sm\:focus\:translate-x-20:focus{--transform-translate-x:5rem}.sm\:focus\:translate-x-24:focus{--transform-translate-x:6rem}.sm\:focus\:translate-x-32:focus{--transform-translate-x:8rem}.sm\:focus\:translate-x-40:focus{--transform-translate-x:10rem}.sm\:focus\:translate-x-48:focus{--transform-translate-x:12rem}.sm\:focus\:translate-x-56:focus{--transform-translate-x:14rem}.sm\:focus\:translate-x-64:focus{--transform-translate-x:16rem}.sm\:focus\:translate-x-px:focus{--transform-translate-x:1px}.sm\:focus\:-translate-x-1:focus{--transform-translate-x:-0.25rem}.sm\:focus\:-translate-x-2:focus{--transform-translate-x:-0.5rem}.sm\:focus\:-translate-x-3:focus{--transform-translate-x:-0.75rem}.sm\:focus\:-translate-x-4:focus{--transform-translate-x:-1rem}.sm\:focus\:-translate-x-5:focus{--transform-translate-x:-1.25rem}.sm\:focus\:-translate-x-6:focus{--transform-translate-x:-1.5rem}.sm\:focus\:-translate-x-8:focus{--transform-translate-x:-2rem}.sm\:focus\:-translate-x-10:focus{--transform-translate-x:-2.5rem}.sm\:focus\:-translate-x-12:focus{--transform-translate-x:-3rem}.sm\:focus\:-translate-x-16:focus{--transform-translate-x:-4rem}.sm\:focus\:-translate-x-20:focus{--transform-translate-x:-5rem}.sm\:focus\:-translate-x-24:focus{--transform-translate-x:-6rem}.sm\:focus\:-translate-x-32:focus{--transform-translate-x:-8rem}.sm\:focus\:-translate-x-40:focus{--transform-translate-x:-10rem}.sm\:focus\:-translate-x-48:focus{--transform-translate-x:-12rem}.sm\:focus\:-translate-x-56:focus{--transform-translate-x:-14rem}.sm\:focus\:-translate-x-64:focus{--transform-translate-x:-16rem}.sm\:focus\:-translate-x-px:focus{--transform-translate-x:-1px}.sm\:focus\:-translate-x-full:focus{--transform-translate-x:-100%}.sm\:focus\:-translate-x-1\/2:focus{--transform-translate-x:-50%}.sm\:focus\:translate-x-1\/2:focus{--transform-translate-x:50%}.sm\:focus\:translate-x-full:focus{--transform-translate-x:100%}.sm\:focus\:translate-y-0:focus{--transform-translate-y:0}.sm\:focus\:translate-y-1:focus{--transform-translate-y:0.25rem}.sm\:focus\:translate-y-2:focus{--transform-translate-y:0.5rem}.sm\:focus\:translate-y-3:focus{--transform-translate-y:0.75rem}.sm\:focus\:translate-y-4:focus{--transform-translate-y:1rem}.sm\:focus\:translate-y-5:focus{--transform-translate-y:1.25rem}.sm\:focus\:translate-y-6:focus{--transform-translate-y:1.5rem}.sm\:focus\:translate-y-8:focus{--transform-translate-y:2rem}.sm\:focus\:translate-y-10:focus{--transform-translate-y:2.5rem}.sm\:focus\:translate-y-12:focus{--transform-translate-y:3rem}.sm\:focus\:translate-y-16:focus{--transform-translate-y:4rem}.sm\:focus\:translate-y-20:focus{--transform-translate-y:5rem}.sm\:focus\:translate-y-24:focus{--transform-translate-y:6rem}.sm\:focus\:translate-y-32:focus{--transform-translate-y:8rem}.sm\:focus\:translate-y-40:focus{--transform-translate-y:10rem}.sm\:focus\:translate-y-48:focus{--transform-translate-y:12rem}.sm\:focus\:translate-y-56:focus{--transform-translate-y:14rem}.sm\:focus\:translate-y-64:focus{--transform-translate-y:16rem}.sm\:focus\:translate-y-px:focus{--transform-translate-y:1px}.sm\:focus\:-translate-y-1:focus{--transform-translate-y:-0.25rem}.sm\:focus\:-translate-y-2:focus{--transform-translate-y:-0.5rem}.sm\:focus\:-translate-y-3:focus{--transform-translate-y:-0.75rem}.sm\:focus\:-translate-y-4:focus{--transform-translate-y:-1rem}.sm\:focus\:-translate-y-5:focus{--transform-translate-y:-1.25rem}.sm\:focus\:-translate-y-6:focus{--transform-translate-y:-1.5rem}.sm\:focus\:-translate-y-8:focus{--transform-translate-y:-2rem}.sm\:focus\:-translate-y-10:focus{--transform-translate-y:-2.5rem}.sm\:focus\:-translate-y-12:focus{--transform-translate-y:-3rem}.sm\:focus\:-translate-y-16:focus{--transform-translate-y:-4rem}.sm\:focus\:-translate-y-20:focus{--transform-translate-y:-5rem}.sm\:focus\:-translate-y-24:focus{--transform-translate-y:-6rem}.sm\:focus\:-translate-y-32:focus{--transform-translate-y:-8rem}.sm\:focus\:-translate-y-40:focus{--transform-translate-y:-10rem}.sm\:focus\:-translate-y-48:focus{--transform-translate-y:-12rem}.sm\:focus\:-translate-y-56:focus{--transform-translate-y:-14rem}.sm\:focus\:-translate-y-64:focus{--transform-translate-y:-16rem}.sm\:focus\:-translate-y-px:focus{--transform-translate-y:-1px}.sm\:focus\:-translate-y-full:focus{--transform-translate-y:-100%}.sm\:focus\:-translate-y-1\/2:focus{--transform-translate-y:-50%}.sm\:focus\:translate-y-1\/2:focus{--transform-translate-y:50%}.sm\:focus\:translate-y-full:focus{--transform-translate-y:100%}.sm\:skew-x-0{--transform-skew-x:0}.sm\:skew-x-1{--transform-skew-x:1deg}.sm\:skew-x-2{--transform-skew-x:2deg}.sm\:skew-x-3{--transform-skew-x:3deg}.sm\:skew-x-6{--transform-skew-x:6deg}.sm\:skew-x-12{--transform-skew-x:12deg}.sm\:-skew-x-12{--transform-skew-x:-12deg}.sm\:-skew-x-6{--transform-skew-x:-6deg}.sm\:-skew-x-3{--transform-skew-x:-3deg}.sm\:-skew-x-2{--transform-skew-x:-2deg}.sm\:-skew-x-1{--transform-skew-x:-1deg}.sm\:skew-y-0{--transform-skew-y:0}.sm\:skew-y-1{--transform-skew-y:1deg}.sm\:skew-y-2{--transform-skew-y:2deg}.sm\:skew-y-3{--transform-skew-y:3deg}.sm\:skew-y-6{--transform-skew-y:6deg}.sm\:skew-y-12{--transform-skew-y:12deg}.sm\:-skew-y-12{--transform-skew-y:-12deg}.sm\:-skew-y-6{--transform-skew-y:-6deg}.sm\:-skew-y-3{--transform-skew-y:-3deg}.sm\:-skew-y-2{--transform-skew-y:-2deg}.sm\:-skew-y-1{--transform-skew-y:-1deg}.sm\:hover\:skew-x-0:hover{--transform-skew-x:0}.sm\:hover\:skew-x-1:hover{--transform-skew-x:1deg}.sm\:hover\:skew-x-2:hover{--transform-skew-x:2deg}.sm\:hover\:skew-x-3:hover{--transform-skew-x:3deg}.sm\:hover\:skew-x-6:hover{--transform-skew-x:6deg}.sm\:hover\:skew-x-12:hover{--transform-skew-x:12deg}.sm\:hover\:-skew-x-12:hover{--transform-skew-x:-12deg}.sm\:hover\:-skew-x-6:hover{--transform-skew-x:-6deg}.sm\:hover\:-skew-x-3:hover{--transform-skew-x:-3deg}.sm\:hover\:-skew-x-2:hover{--transform-skew-x:-2deg}.sm\:hover\:-skew-x-1:hover{--transform-skew-x:-1deg}.sm\:hover\:skew-y-0:hover{--transform-skew-y:0}.sm\:hover\:skew-y-1:hover{--transform-skew-y:1deg}.sm\:hover\:skew-y-2:hover{--transform-skew-y:2deg}.sm\:hover\:skew-y-3:hover{--transform-skew-y:3deg}.sm\:hover\:skew-y-6:hover{--transform-skew-y:6deg}.sm\:hover\:skew-y-12:hover{--transform-skew-y:12deg}.sm\:hover\:-skew-y-12:hover{--transform-skew-y:-12deg}.sm\:hover\:-skew-y-6:hover{--transform-skew-y:-6deg}.sm\:hover\:-skew-y-3:hover{--transform-skew-y:-3deg}.sm\:hover\:-skew-y-2:hover{--transform-skew-y:-2deg}.sm\:hover\:-skew-y-1:hover{--transform-skew-y:-1deg}.sm\:focus\:skew-x-0:focus{--transform-skew-x:0}.sm\:focus\:skew-x-1:focus{--transform-skew-x:1deg}.sm\:focus\:skew-x-2:focus{--transform-skew-x:2deg}.sm\:focus\:skew-x-3:focus{--transform-skew-x:3deg}.sm\:focus\:skew-x-6:focus{--transform-skew-x:6deg}.sm\:focus\:skew-x-12:focus{--transform-skew-x:12deg}.sm\:focus\:-skew-x-12:focus{--transform-skew-x:-12deg}.sm\:focus\:-skew-x-6:focus{--transform-skew-x:-6deg}.sm\:focus\:-skew-x-3:focus{--transform-skew-x:-3deg}.sm\:focus\:-skew-x-2:focus{--transform-skew-x:-2deg}.sm\:focus\:-skew-x-1:focus{--transform-skew-x:-1deg}.sm\:focus\:skew-y-0:focus{--transform-skew-y:0}.sm\:focus\:skew-y-1:focus{--transform-skew-y:1deg}.sm\:focus\:skew-y-2:focus{--transform-skew-y:2deg}.sm\:focus\:skew-y-3:focus{--transform-skew-y:3deg}.sm\:focus\:skew-y-6:focus{--transform-skew-y:6deg}.sm\:focus\:skew-y-12:focus{--transform-skew-y:12deg}.sm\:focus\:-skew-y-12:focus{--transform-skew-y:-12deg}.sm\:focus\:-skew-y-6:focus{--transform-skew-y:-6deg}.sm\:focus\:-skew-y-3:focus{--transform-skew-y:-3deg}.sm\:focus\:-skew-y-2:focus{--transform-skew-y:-2deg}.sm\:focus\:-skew-y-1:focus{--transform-skew-y:-1deg}.sm\:transition-none{transition-property:none}.sm\:transition-all{transition-property:all}.sm\:transition{transition-property:background-color,border-color,color,fill,stroke,opacity,box-shadow,transform}.sm\:transition-colors{transition-property:background-color,border-color,color,fill,stroke}.sm\:transition-opacity{transition-property:opacity}.sm\:transition-shadow{transition-property:box-shadow}.sm\:transition-transform{transition-property:transform}.sm\:ease-linear{transition-timing-function:linear}.sm\:ease-in{transition-timing-function:cubic-bezier(.4,0,1,1)}.sm\:ease-out{transition-timing-function:cubic-bezier(0,0,.2,1)}.sm\:ease-in-out{transition-timing-function:cubic-bezier(.4,0,.2,1)}.sm\:duration-75{transition-duration:75ms}.sm\:duration-100{transition-duration:.1s}.sm\:duration-150{transition-duration:150ms}.sm\:duration-200{transition-duration:.2s}.sm\:duration-300{transition-duration:.3s}.sm\:duration-500{transition-duration:.5s}.sm\:duration-700{transition-duration:.7s}.sm\:duration-1000{transition-duration:1s}.sm\:delay-75{transition-delay:75ms}.sm\:delay-100{transition-delay:.1s}.sm\:delay-150{transition-delay:150ms}.sm\:delay-200{transition-delay:.2s}.sm\:delay-300{transition-delay:.3s}.sm\:delay-500{transition-delay:.5s}.sm\:delay-700{transition-delay:.7s}.sm\:delay-1000{transition-delay:1s}.sm\:animate-none{animation:none}.sm\:animate-spin{animation:spin 1s linear infinite}.sm\:animate-ping{animation:ping 1s cubic-bezier(0,0,.2,1) infinite}.sm\:animate-pulse{animation:pulse 2s cubic-bezier(.4,0,.6,1) infinite}.sm\:animate-bounce{animation:bounce 1s infinite}}@media (min-width:768px){.md\:container{width:100%}@media (min-width:640px){.md\:container{max-width:640px}}@media (min-width:768px){.md\:container{max-width:768px}}@media (min-width:1024px){.md\:container{max-width:1024px}}@media (min-width:1280px){.md\:container{max-width:1280px}}.md\:space-y-0>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(0px * calc(1 - var(--space-y-reverse)));margin-bottom:calc(0px * var(--space-y-reverse))}.md\:space-x-0>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(0px * var(--space-x-reverse));margin-left:calc(0px * calc(1 - var(--space-x-reverse)))}.md\:space-y-1>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(.25rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(.25rem * var(--space-y-reverse))}.md\:space-x-1>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(.25rem * var(--space-x-reverse));margin-left:calc(.25rem * calc(1 - var(--space-x-reverse)))}.md\:space-y-2>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(.5rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(.5rem * var(--space-y-reverse))}.md\:space-x-2>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(.5rem * var(--space-x-reverse));margin-left:calc(.5rem * calc(1 - var(--space-x-reverse)))}.md\:space-y-3>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(.75rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(.75rem * var(--space-y-reverse))}.md\:space-x-3>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(.75rem * var(--space-x-reverse));margin-left:calc(.75rem * calc(1 - var(--space-x-reverse)))}.md\:space-y-4>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(1rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(1rem * var(--space-y-reverse))}.md\:space-x-4>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(1rem * var(--space-x-reverse));margin-left:calc(1rem * calc(1 - var(--space-x-reverse)))}.md\:space-y-5>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(1.25rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(1.25rem * var(--space-y-reverse))}.md\:space-x-5>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(1.25rem * var(--space-x-reverse));margin-left:calc(1.25rem * calc(1 - var(--space-x-reverse)))}.md\:space-y-6>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(1.5rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(1.5rem * var(--space-y-reverse))}.md\:space-x-6>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(1.5rem * var(--space-x-reverse));margin-left:calc(1.5rem * calc(1 - var(--space-x-reverse)))}.md\:space-y-8>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(2rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(2rem * var(--space-y-reverse))}.md\:space-x-8>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(2rem * var(--space-x-reverse));margin-left:calc(2rem * calc(1 - var(--space-x-reverse)))}.md\:space-y-10>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(2.5rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(2.5rem * var(--space-y-reverse))}.md\:space-x-10>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(2.5rem * var(--space-x-reverse));margin-left:calc(2.5rem * calc(1 - var(--space-x-reverse)))}.md\:space-y-12>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(3rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(3rem * var(--space-y-reverse))}.md\:space-x-12>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(3rem * var(--space-x-reverse));margin-left:calc(3rem * calc(1 - var(--space-x-reverse)))}.md\:space-y-16>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(4rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(4rem * var(--space-y-reverse))}.md\:space-x-16>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(4rem * var(--space-x-reverse));margin-left:calc(4rem * calc(1 - var(--space-x-reverse)))}.md\:space-y-20>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(5rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(5rem * var(--space-y-reverse))}.md\:space-x-20>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(5rem * var(--space-x-reverse));margin-left:calc(5rem * calc(1 - var(--space-x-reverse)))}.md\:space-y-24>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(6rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(6rem * var(--space-y-reverse))}.md\:space-x-24>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(6rem * var(--space-x-reverse));margin-left:calc(6rem * calc(1 - var(--space-x-reverse)))}.md\:space-y-32>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(8rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(8rem * var(--space-y-reverse))}.md\:space-x-32>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(8rem * var(--space-x-reverse));margin-left:calc(8rem * calc(1 - var(--space-x-reverse)))}.md\:space-y-40>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(10rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(10rem * var(--space-y-reverse))}.md\:space-x-40>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(10rem * var(--space-x-reverse));margin-left:calc(10rem * calc(1 - var(--space-x-reverse)))}.md\:space-y-48>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(12rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(12rem * var(--space-y-reverse))}.md\:space-x-48>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(12rem * var(--space-x-reverse));margin-left:calc(12rem * calc(1 - var(--space-x-reverse)))}.md\:space-y-56>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(14rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(14rem * var(--space-y-reverse))}.md\:space-x-56>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(14rem * var(--space-x-reverse));margin-left:calc(14rem * calc(1 - var(--space-x-reverse)))}.md\:space-y-64>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(16rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(16rem * var(--space-y-reverse))}.md\:space-x-64>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(16rem * var(--space-x-reverse));margin-left:calc(16rem * calc(1 - var(--space-x-reverse)))}.md\:space-y-px>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(1px * calc(1 - var(--space-y-reverse)));margin-bottom:calc(1px * var(--space-y-reverse))}.md\:space-x-px>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(1px * var(--space-x-reverse));margin-left:calc(1px * calc(1 - var(--space-x-reverse)))}.md\:-space-y-1>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-.25rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-.25rem * var(--space-y-reverse))}.md\:-space-x-1>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-.25rem * var(--space-x-reverse));margin-left:calc(-.25rem * calc(1 - var(--space-x-reverse)))}.md\:-space-y-2>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-.5rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-.5rem * var(--space-y-reverse))}.md\:-space-x-2>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-.5rem * var(--space-x-reverse));margin-left:calc(-.5rem * calc(1 - var(--space-x-reverse)))}.md\:-space-y-3>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-.75rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-.75rem * var(--space-y-reverse))}.md\:-space-x-3>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-.75rem * var(--space-x-reverse));margin-left:calc(-.75rem * calc(1 - var(--space-x-reverse)))}.md\:-space-y-4>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-1rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-1rem * var(--space-y-reverse))}.md\:-space-x-4>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-1rem * var(--space-x-reverse));margin-left:calc(-1rem * calc(1 - var(--space-x-reverse)))}.md\:-space-y-5>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-1.25rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-1.25rem * var(--space-y-reverse))}.md\:-space-x-5>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-1.25rem * var(--space-x-reverse));margin-left:calc(-1.25rem * calc(1 - var(--space-x-reverse)))}.md\:-space-y-6>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-1.5rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-1.5rem * var(--space-y-reverse))}.md\:-space-x-6>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-1.5rem * var(--space-x-reverse));margin-left:calc(-1.5rem * calc(1 - var(--space-x-reverse)))}.md\:-space-y-8>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-2rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-2rem * var(--space-y-reverse))}.md\:-space-x-8>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-2rem * var(--space-x-reverse));margin-left:calc(-2rem * calc(1 - var(--space-x-reverse)))}.md\:-space-y-10>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-2.5rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-2.5rem * var(--space-y-reverse))}.md\:-space-x-10>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-2.5rem * var(--space-x-reverse));margin-left:calc(-2.5rem * calc(1 - var(--space-x-reverse)))}.md\:-space-y-12>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-3rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-3rem * var(--space-y-reverse))}.md\:-space-x-12>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-3rem * var(--space-x-reverse));margin-left:calc(-3rem * calc(1 - var(--space-x-reverse)))}.md\:-space-y-16>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-4rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-4rem * var(--space-y-reverse))}.md\:-space-x-16>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-4rem * var(--space-x-reverse));margin-left:calc(-4rem * calc(1 - var(--space-x-reverse)))}.md\:-space-y-20>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-5rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-5rem * var(--space-y-reverse))}.md\:-space-x-20>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-5rem * var(--space-x-reverse));margin-left:calc(-5rem * calc(1 - var(--space-x-reverse)))}.md\:-space-y-24>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-6rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-6rem * var(--space-y-reverse))}.md\:-space-x-24>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-6rem * var(--space-x-reverse));margin-left:calc(-6rem * calc(1 - var(--space-x-reverse)))}.md\:-space-y-32>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-8rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-8rem * var(--space-y-reverse))}.md\:-space-x-32>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-8rem * var(--space-x-reverse));margin-left:calc(-8rem * calc(1 - var(--space-x-reverse)))}.md\:-space-y-40>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-10rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-10rem * var(--space-y-reverse))}.md\:-space-x-40>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-10rem * var(--space-x-reverse));margin-left:calc(-10rem * calc(1 - var(--space-x-reverse)))}.md\:-space-y-48>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-12rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-12rem * var(--space-y-reverse))}.md\:-space-x-48>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-12rem * var(--space-x-reverse));margin-left:calc(-12rem * calc(1 - var(--space-x-reverse)))}.md\:-space-y-56>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-14rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-14rem * var(--space-y-reverse))}.md\:-space-x-56>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-14rem * var(--space-x-reverse));margin-left:calc(-14rem * calc(1 - var(--space-x-reverse)))}.md\:-space-y-64>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-16rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-16rem * var(--space-y-reverse))}.md\:-space-x-64>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-16rem * var(--space-x-reverse));margin-left:calc(-16rem * calc(1 - var(--space-x-reverse)))}.md\:-space-y-px>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-1px * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-1px * var(--space-y-reverse))}.md\:-space-x-px>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-1px * var(--space-x-reverse));margin-left:calc(-1px * calc(1 - var(--space-x-reverse)))}.md\:space-y-reverse>:not(template)~:not(template){--space-y-reverse:1}.md\:space-x-reverse>:not(template)~:not(template){--space-x-reverse:1}.md\:divide-y-0>:not(template)~:not(template){--divide-y-reverse:0;border-top-width:calc(0px * calc(1 - var(--divide-y-reverse)));border-bottom-width:calc(0px * var(--divide-y-reverse))}.md\:divide-x-0>:not(template)~:not(template){--divide-x-reverse:0;border-right-width:calc(0px * var(--divide-x-reverse));border-left-width:calc(0px * calc(1 - var(--divide-x-reverse)))}.md\:divide-y-2>:not(template)~:not(template){--divide-y-reverse:0;border-top-width:calc(2px * calc(1 - var(--divide-y-reverse)));border-bottom-width:calc(2px * var(--divide-y-reverse))}.md\:divide-x-2>:not(template)~:not(template){--divide-x-reverse:0;border-right-width:calc(2px * var(--divide-x-reverse));border-left-width:calc(2px * calc(1 - var(--divide-x-reverse)))}.md\:divide-y-4>:not(template)~:not(template){--divide-y-reverse:0;border-top-width:calc(4px * calc(1 - var(--divide-y-reverse)));border-bottom-width:calc(4px * var(--divide-y-reverse))}.md\:divide-x-4>:not(template)~:not(template){--divide-x-reverse:0;border-right-width:calc(4px * var(--divide-x-reverse));border-left-width:calc(4px * calc(1 - var(--divide-x-reverse)))}.md\:divide-y-8>:not(template)~:not(template){--divide-y-reverse:0;border-top-width:calc(8px * calc(1 - var(--divide-y-reverse)));border-bottom-width:calc(8px * var(--divide-y-reverse))}.md\:divide-x-8>:not(template)~:not(template){--divide-x-reverse:0;border-right-width:calc(8px * var(--divide-x-reverse));border-left-width:calc(8px * calc(1 - var(--divide-x-reverse)))}.md\:divide-y>:not(template)~:not(template){--divide-y-reverse:0;border-top-width:calc(1px * calc(1 - var(--divide-y-reverse)));border-bottom-width:calc(1px * var(--divide-y-reverse))}.md\:divide-x>:not(template)~:not(template){--divide-x-reverse:0;border-right-width:calc(1px * var(--divide-x-reverse));border-left-width:calc(1px * calc(1 - var(--divide-x-reverse)))}.md\:divide-y-reverse>:not(template)~:not(template){--divide-y-reverse:1}.md\:divide-x-reverse>:not(template)~:not(template){--divide-x-reverse:1}.md\:divide-transparent>:not(template)~:not(template){border-color:transparent}.md\:divide-current>:not(template)~:not(template){border-color:currentColor}.md\:divide-black>:not(template)~:not(template){--divide-opacity:1;border-color:#000;border-color:rgba(0,0,0,var(--divide-opacity))}.md\:divide-white>:not(template)~:not(template){--divide-opacity:1;border-color:#fff;border-color:rgba(255,255,255,var(--divide-opacity))}.md\:divide-gray-100>:not(template)~:not(template){--divide-opacity:1;border-color:#f7fafc;border-color:rgba(247,250,252,var(--divide-opacity))}.md\:divide-gray-200>:not(template)~:not(template){--divide-opacity:1;border-color:#edf2f7;border-color:rgba(237,242,247,var(--divide-opacity))}.md\:divide-gray-300>:not(template)~:not(template){--divide-opacity:1;border-color:#e2e8f0;border-color:rgba(226,232,240,var(--divide-opacity))}.md\:divide-gray-400>:not(template)~:not(template){--divide-opacity:1;border-color:#cbd5e0;border-color:rgba(203,213,224,var(--divide-opacity))}.md\:divide-gray-500>:not(template)~:not(template){--divide-opacity:1;border-color:#a0aec0;border-color:rgba(160,174,192,var(--divide-opacity))}.md\:divide-gray-600>:not(template)~:not(template){--divide-opacity:1;border-color:#718096;border-color:rgba(113,128,150,var(--divide-opacity))}.md\:divide-gray-700>:not(template)~:not(template){--divide-opacity:1;border-color:#4a5568;border-color:rgba(74,85,104,var(--divide-opacity))}.md\:divide-gray-800>:not(template)~:not(template){--divide-opacity:1;border-color:#2d3748;border-color:rgba(45,55,72,var(--divide-opacity))}.md\:divide-gray-900>:not(template)~:not(template){--divide-opacity:1;border-color:#1a202c;border-color:rgba(26,32,44,var(--divide-opacity))}.md\:divide-red-100>:not(template)~:not(template){--divide-opacity:1;border-color:#fff5f5;border-color:rgba(255,245,245,var(--divide-opacity))}.md\:divide-red-200>:not(template)~:not(template){--divide-opacity:1;border-color:#fed7d7;border-color:rgba(254,215,215,var(--divide-opacity))}.md\:divide-red-300>:not(template)~:not(template){--divide-opacity:1;border-color:#feb2b2;border-color:rgba(254,178,178,var(--divide-opacity))}.md\:divide-red-400>:not(template)~:not(template){--divide-opacity:1;border-color:#fc8181;border-color:rgba(252,129,129,var(--divide-opacity))}.md\:divide-red-500>:not(template)~:not(template){--divide-opacity:1;border-color:#f56565;border-color:rgba(245,101,101,var(--divide-opacity))}.md\:divide-red-600>:not(template)~:not(template){--divide-opacity:1;border-color:#e53e3e;border-color:rgba(229,62,62,var(--divide-opacity))}.md\:divide-red-700>:not(template)~:not(template){--divide-opacity:1;border-color:#c53030;border-color:rgba(197,48,48,var(--divide-opacity))}.md\:divide-red-800>:not(template)~:not(template){--divide-opacity:1;border-color:#9b2c2c;border-color:rgba(155,44,44,var(--divide-opacity))}.md\:divide-red-900>:not(template)~:not(template){--divide-opacity:1;border-color:#742a2a;border-color:rgba(116,42,42,var(--divide-opacity))}.md\:divide-orange-100>:not(template)~:not(template){--divide-opacity:1;border-color:#fffaf0;border-color:rgba(255,250,240,var(--divide-opacity))}.md\:divide-orange-200>:not(template)~:not(template){--divide-opacity:1;border-color:#feebc8;border-color:rgba(254,235,200,var(--divide-opacity))}.md\:divide-orange-300>:not(template)~:not(template){--divide-opacity:1;border-color:#fbd38d;border-color:rgba(251,211,141,var(--divide-opacity))}.md\:divide-orange-400>:not(template)~:not(template){--divide-opacity:1;border-color:#f6ad55;border-color:rgba(246,173,85,var(--divide-opacity))}.md\:divide-orange-500>:not(template)~:not(template){--divide-opacity:1;border-color:#ed8936;border-color:rgba(237,137,54,var(--divide-opacity))}.md\:divide-orange-600>:not(template)~:not(template){--divide-opacity:1;border-color:#dd6b20;border-color:rgba(221,107,32,var(--divide-opacity))}.md\:divide-orange-700>:not(template)~:not(template){--divide-opacity:1;border-color:#c05621;border-color:rgba(192,86,33,var(--divide-opacity))}.md\:divide-orange-800>:not(template)~:not(template){--divide-opacity:1;border-color:#9c4221;border-color:rgba(156,66,33,var(--divide-opacity))}.md\:divide-orange-900>:not(template)~:not(template){--divide-opacity:1;border-color:#7b341e;border-color:rgba(123,52,30,var(--divide-opacity))}.md\:divide-yellow-100>:not(template)~:not(template){--divide-opacity:1;border-color:ivory;border-color:rgba(255,255,240,var(--divide-opacity))}.md\:divide-yellow-200>:not(template)~:not(template){--divide-opacity:1;border-color:#fefcbf;border-color:rgba(254,252,191,var(--divide-opacity))}.md\:divide-yellow-300>:not(template)~:not(template){--divide-opacity:1;border-color:#faf089;border-color:rgba(250,240,137,var(--divide-opacity))}.md\:divide-yellow-400>:not(template)~:not(template){--divide-opacity:1;border-color:#f6e05e;border-color:rgba(246,224,94,var(--divide-opacity))}.md\:divide-yellow-500>:not(template)~:not(template){--divide-opacity:1;border-color:#ecc94b;border-color:rgba(236,201,75,var(--divide-opacity))}.md\:divide-yellow-600>:not(template)~:not(template){--divide-opacity:1;border-color:#d69e2e;border-color:rgba(214,158,46,var(--divide-opacity))}.md\:divide-yellow-700>:not(template)~:not(template){--divide-opacity:1;border-color:#b7791f;border-color:rgba(183,121,31,var(--divide-opacity))}.md\:divide-yellow-800>:not(template)~:not(template){--divide-opacity:1;border-color:#975a16;border-color:rgba(151,90,22,var(--divide-opacity))}.md\:divide-yellow-900>:not(template)~:not(template){--divide-opacity:1;border-color:#744210;border-color:rgba(116,66,16,var(--divide-opacity))}.md\:divide-green-100>:not(template)~:not(template){--divide-opacity:1;border-color:#f0fff4;border-color:rgba(240,255,244,var(--divide-opacity))}.md\:divide-green-200>:not(template)~:not(template){--divide-opacity:1;border-color:#c6f6d5;border-color:rgba(198,246,213,var(--divide-opacity))}.md\:divide-green-300>:not(template)~:not(template){--divide-opacity:1;border-color:#9ae6b4;border-color:rgba(154,230,180,var(--divide-opacity))}.md\:divide-green-400>:not(template)~:not(template){--divide-opacity:1;border-color:#68d391;border-color:rgba(104,211,145,var(--divide-opacity))}.md\:divide-green-500>:not(template)~:not(template){--divide-opacity:1;border-color:#48bb78;border-color:rgba(72,187,120,var(--divide-opacity))}.md\:divide-green-600>:not(template)~:not(template){--divide-opacity:1;border-color:#38a169;border-color:rgba(56,161,105,var(--divide-opacity))}.md\:divide-green-700>:not(template)~:not(template){--divide-opacity:1;border-color:#2f855a;border-color:rgba(47,133,90,var(--divide-opacity))}.md\:divide-green-800>:not(template)~:not(template){--divide-opacity:1;border-color:#276749;border-color:rgba(39,103,73,var(--divide-opacity))}.md\:divide-green-900>:not(template)~:not(template){--divide-opacity:1;border-color:#22543d;border-color:rgba(34,84,61,var(--divide-opacity))}.md\:divide-teal-100>:not(template)~:not(template){--divide-opacity:1;border-color:#e6fffa;border-color:rgba(230,255,250,var(--divide-opacity))}.md\:divide-teal-200>:not(template)~:not(template){--divide-opacity:1;border-color:#b2f5ea;border-color:rgba(178,245,234,var(--divide-opacity))}.md\:divide-teal-300>:not(template)~:not(template){--divide-opacity:1;border-color:#81e6d9;border-color:rgba(129,230,217,var(--divide-opacity))}.md\:divide-teal-400>:not(template)~:not(template){--divide-opacity:1;border-color:#4fd1c5;border-color:rgba(79,209,197,var(--divide-opacity))}.md\:divide-teal-500>:not(template)~:not(template){--divide-opacity:1;border-color:#38b2ac;border-color:rgba(56,178,172,var(--divide-opacity))}.md\:divide-teal-600>:not(template)~:not(template){--divide-opacity:1;border-color:#319795;border-color:rgba(49,151,149,var(--divide-opacity))}.md\:divide-teal-700>:not(template)~:not(template){--divide-opacity:1;border-color:#2c7a7b;border-color:rgba(44,122,123,var(--divide-opacity))}.md\:divide-teal-800>:not(template)~:not(template){--divide-opacity:1;border-color:#285e61;border-color:rgba(40,94,97,var(--divide-opacity))}.md\:divide-teal-900>:not(template)~:not(template){--divide-opacity:1;border-color:#234e52;border-color:rgba(35,78,82,var(--divide-opacity))}.md\:divide-blue-100>:not(template)~:not(template){--divide-opacity:1;border-color:#ebf8ff;border-color:rgba(235,248,255,var(--divide-opacity))}.md\:divide-blue-200>:not(template)~:not(template){--divide-opacity:1;border-color:#bee3f8;border-color:rgba(190,227,248,var(--divide-opacity))}.md\:divide-blue-300>:not(template)~:not(template){--divide-opacity:1;border-color:#90cdf4;border-color:rgba(144,205,244,var(--divide-opacity))}.md\:divide-blue-400>:not(template)~:not(template){--divide-opacity:1;border-color:#63b3ed;border-color:rgba(99,179,237,var(--divide-opacity))}.md\:divide-blue-500>:not(template)~:not(template){--divide-opacity:1;border-color:#4299e1;border-color:rgba(66,153,225,var(--divide-opacity))}.md\:divide-blue-600>:not(template)~:not(template){--divide-opacity:1;border-color:#3182ce;border-color:rgba(49,130,206,var(--divide-opacity))}.md\:divide-blue-700>:not(template)~:not(template){--divide-opacity:1;border-color:#2b6cb0;border-color:rgba(43,108,176,var(--divide-opacity))}.md\:divide-blue-800>:not(template)~:not(template){--divide-opacity:1;border-color:#2c5282;border-color:rgba(44,82,130,var(--divide-opacity))}.md\:divide-blue-900>:not(template)~:not(template){--divide-opacity:1;border-color:#2a4365;border-color:rgba(42,67,101,var(--divide-opacity))}.md\:divide-indigo-100>:not(template)~:not(template){--divide-opacity:1;border-color:#ebf4ff;border-color:rgba(235,244,255,var(--divide-opacity))}.md\:divide-indigo-200>:not(template)~:not(template){--divide-opacity:1;border-color:#c3dafe;border-color:rgba(195,218,254,var(--divide-opacity))}.md\:divide-indigo-300>:not(template)~:not(template){--divide-opacity:1;border-color:#a3bffa;border-color:rgba(163,191,250,var(--divide-opacity))}.md\:divide-indigo-400>:not(template)~:not(template){--divide-opacity:1;border-color:#7f9cf5;border-color:rgba(127,156,245,var(--divide-opacity))}.md\:divide-indigo-500>:not(template)~:not(template){--divide-opacity:1;border-color:#667eea;border-color:rgba(102,126,234,var(--divide-opacity))}.md\:divide-indigo-600>:not(template)~:not(template){--divide-opacity:1;border-color:#5a67d8;border-color:rgba(90,103,216,var(--divide-opacity))}.md\:divide-indigo-700>:not(template)~:not(template){--divide-opacity:1;border-color:#4c51bf;border-color:rgba(76,81,191,var(--divide-opacity))}.md\:divide-indigo-800>:not(template)~:not(template){--divide-opacity:1;border-color:#434190;border-color:rgba(67,65,144,var(--divide-opacity))}.md\:divide-indigo-900>:not(template)~:not(template){--divide-opacity:1;border-color:#3c366b;border-color:rgba(60,54,107,var(--divide-opacity))}.md\:divide-purple-100>:not(template)~:not(template){--divide-opacity:1;border-color:#faf5ff;border-color:rgba(250,245,255,var(--divide-opacity))}.md\:divide-purple-200>:not(template)~:not(template){--divide-opacity:1;border-color:#e9d8fd;border-color:rgba(233,216,253,var(--divide-opacity))}.md\:divide-purple-300>:not(template)~:not(template){--divide-opacity:1;border-color:#d6bcfa;border-color:rgba(214,188,250,var(--divide-opacity))}.md\:divide-purple-400>:not(template)~:not(template){--divide-opacity:1;border-color:#b794f4;border-color:rgba(183,148,244,var(--divide-opacity))}.md\:divide-purple-500>:not(template)~:not(template){--divide-opacity:1;border-color:#9f7aea;border-color:rgba(159,122,234,var(--divide-opacity))}.md\:divide-purple-600>:not(template)~:not(template){--divide-opacity:1;border-color:#805ad5;border-color:rgba(128,90,213,var(--divide-opacity))}.md\:divide-purple-700>:not(template)~:not(template){--divide-opacity:1;border-color:#6b46c1;border-color:rgba(107,70,193,var(--divide-opacity))}.md\:divide-purple-800>:not(template)~:not(template){--divide-opacity:1;border-color:#553c9a;border-color:rgba(85,60,154,var(--divide-opacity))}.md\:divide-purple-900>:not(template)~:not(template){--divide-opacity:1;border-color:#44337a;border-color:rgba(68,51,122,var(--divide-opacity))}.md\:divide-pink-100>:not(template)~:not(template){--divide-opacity:1;border-color:#fff5f7;border-color:rgba(255,245,247,var(--divide-opacity))}.md\:divide-pink-200>:not(template)~:not(template){--divide-opacity:1;border-color:#fed7e2;border-color:rgba(254,215,226,var(--divide-opacity))}.md\:divide-pink-300>:not(template)~:not(template){--divide-opacity:1;border-color:#fbb6ce;border-color:rgba(251,182,206,var(--divide-opacity))}.md\:divide-pink-400>:not(template)~:not(template){--divide-opacity:1;border-color:#f687b3;border-color:rgba(246,135,179,var(--divide-opacity))}.md\:divide-pink-500>:not(template)~:not(template){--divide-opacity:1;border-color:#ed64a6;border-color:rgba(237,100,166,var(--divide-opacity))}.md\:divide-pink-600>:not(template)~:not(template){--divide-opacity:1;border-color:#d53f8c;border-color:rgba(213,63,140,var(--divide-opacity))}.md\:divide-pink-700>:not(template)~:not(template){--divide-opacity:1;border-color:#b83280;border-color:rgba(184,50,128,var(--divide-opacity))}.md\:divide-pink-800>:not(template)~:not(template){--divide-opacity:1;border-color:#97266d;border-color:rgba(151,38,109,var(--divide-opacity))}.md\:divide-pink-900>:not(template)~:not(template){--divide-opacity:1;border-color:#702459;border-color:rgba(112,36,89,var(--divide-opacity))}.md\:divide-solid>:not(template)~:not(template){border-style:solid}.md\:divide-dashed>:not(template)~:not(template){border-style:dashed}.md\:divide-dotted>:not(template)~:not(template){border-style:dotted}.md\:divide-double>:not(template)~:not(template){border-style:double}.md\:divide-none>:not(template)~:not(template){border-style:none}.md\:divide-opacity-0>:not(template)~:not(template){--divide-opacity:0}.md\:divide-opacity-25>:not(template)~:not(template){--divide-opacity:0.25}.md\:divide-opacity-50>:not(template)~:not(template){--divide-opacity:0.5}.md\:divide-opacity-75>:not(template)~:not(template){--divide-opacity:0.75}.md\:divide-opacity-100>:not(template)~:not(template){--divide-opacity:1}.md\:sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border-width:0}.md\:not-sr-only{position:static;width:auto;height:auto;padding:0;margin:0;overflow:visible;clip:auto;white-space:normal}.md\:focus\:sr-only:focus{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border-width:0}.md\:focus\:not-sr-only:focus{position:static;width:auto;height:auto;padding:0;margin:0;overflow:visible;clip:auto;white-space:normal}.md\:appearance-none{-webkit-appearance:none;-moz-appearance:none;appearance:none}.md\:bg-fixed{background-attachment:fixed}.md\:bg-local{background-attachment:local}.md\:bg-scroll{background-attachment:scroll}.md\:bg-clip-border{background-clip:border-box}.md\:bg-clip-padding{background-clip:padding-box}.md\:bg-clip-content{background-clip:content-box}.md\:bg-clip-text{-webkit-background-clip:text;background-clip:text}.md\:bg-transparent{background-color:transparent}.md\:bg-current{background-color:currentColor}.md\:bg-black{--bg-opacity:1;background-color:#000;background-color:rgba(0,0,0,var(--bg-opacity))}.md\:bg-white{--bg-opacity:1;background-color:#fff;background-color:rgba(255,255,255,var(--bg-opacity))}.md\:bg-gray-100{--bg-opacity:1;background-color:#f7fafc;background-color:rgba(247,250,252,var(--bg-opacity))}.md\:bg-gray-200{--bg-opacity:1;background-color:#edf2f7;background-color:rgba(237,242,247,var(--bg-opacity))}.md\:bg-gray-300{--bg-opacity:1;background-color:#e2e8f0;background-color:rgba(226,232,240,var(--bg-opacity))}.md\:bg-gray-400{--bg-opacity:1;background-color:#cbd5e0;background-color:rgba(203,213,224,var(--bg-opacity))}.md\:bg-gray-500{--bg-opacity:1;background-color:#a0aec0;background-color:rgba(160,174,192,var(--bg-opacity))}.md\:bg-gray-600{--bg-opacity:1;background-color:#718096;background-color:rgba(113,128,150,var(--bg-opacity))}.md\:bg-gray-700{--bg-opacity:1;background-color:#4a5568;background-color:rgba(74,85,104,var(--bg-opacity))}.md\:bg-gray-800{--bg-opacity:1;background-color:#2d3748;background-color:rgba(45,55,72,var(--bg-opacity))}.md\:bg-gray-900{--bg-opacity:1;background-color:#1a202c;background-color:rgba(26,32,44,var(--bg-opacity))}.md\:bg-red-100{--bg-opacity:1;background-color:#fff5f5;background-color:rgba(255,245,245,var(--bg-opacity))}.md\:bg-red-200{--bg-opacity:1;background-color:#fed7d7;background-color:rgba(254,215,215,var(--bg-opacity))}.md\:bg-red-300{--bg-opacity:1;background-color:#feb2b2;background-color:rgba(254,178,178,var(--bg-opacity))}.md\:bg-red-400{--bg-opacity:1;background-color:#fc8181;background-color:rgba(252,129,129,var(--bg-opacity))}.md\:bg-red-500{--bg-opacity:1;background-color:#f56565;background-color:rgba(245,101,101,var(--bg-opacity))}.md\:bg-red-600{--bg-opacity:1;background-color:#e53e3e;background-color:rgba(229,62,62,var(--bg-opacity))}.md\:bg-red-700{--bg-opacity:1;background-color:#c53030;background-color:rgba(197,48,48,var(--bg-opacity))}.md\:bg-red-800{--bg-opacity:1;background-color:#9b2c2c;background-color:rgba(155,44,44,var(--bg-opacity))}.md\:bg-red-900{--bg-opacity:1;background-color:#742a2a;background-color:rgba(116,42,42,var(--bg-opacity))}.md\:bg-orange-100{--bg-opacity:1;background-color:#fffaf0;background-color:rgba(255,250,240,var(--bg-opacity))}.md\:bg-orange-200{--bg-opacity:1;background-color:#feebc8;background-color:rgba(254,235,200,var(--bg-opacity))}.md\:bg-orange-300{--bg-opacity:1;background-color:#fbd38d;background-color:rgba(251,211,141,var(--bg-opacity))}.md\:bg-orange-400{--bg-opacity:1;background-color:#f6ad55;background-color:rgba(246,173,85,var(--bg-opacity))}.md\:bg-orange-500{--bg-opacity:1;background-color:#ed8936;background-color:rgba(237,137,54,var(--bg-opacity))}.md\:bg-orange-600{--bg-opacity:1;background-color:#dd6b20;background-color:rgba(221,107,32,var(--bg-opacity))}.md\:bg-orange-700{--bg-opacity:1;background-color:#c05621;background-color:rgba(192,86,33,var(--bg-opacity))}.md\:bg-orange-800{--bg-opacity:1;background-color:#9c4221;background-color:rgba(156,66,33,var(--bg-opacity))}.md\:bg-orange-900{--bg-opacity:1;background-color:#7b341e;background-color:rgba(123,52,30,var(--bg-opacity))}.md\:bg-yellow-100{--bg-opacity:1;background-color:ivory;background-color:rgba(255,255,240,var(--bg-opacity))}.md\:bg-yellow-200{--bg-opacity:1;background-color:#fefcbf;background-color:rgba(254,252,191,var(--bg-opacity))}.md\:bg-yellow-300{--bg-opacity:1;background-color:#faf089;background-color:rgba(250,240,137,var(--bg-opacity))}.md\:bg-yellow-400{--bg-opacity:1;background-color:#f6e05e;background-color:rgba(246,224,94,var(--bg-opacity))}.md\:bg-yellow-500{--bg-opacity:1;background-color:#ecc94b;background-color:rgba(236,201,75,var(--bg-opacity))}.md\:bg-yellow-600{--bg-opacity:1;background-color:#d69e2e;background-color:rgba(214,158,46,var(--bg-opacity))}.md\:bg-yellow-700{--bg-opacity:1;background-color:#b7791f;background-color:rgba(183,121,31,var(--bg-opacity))}.md\:bg-yellow-800{--bg-opacity:1;background-color:#975a16;background-color:rgba(151,90,22,var(--bg-opacity))}.md\:bg-yellow-900{--bg-opacity:1;background-color:#744210;background-color:rgba(116,66,16,var(--bg-opacity))}.md\:bg-green-100{--bg-opacity:1;background-color:#f0fff4;background-color:rgba(240,255,244,var(--bg-opacity))}.md\:bg-green-200{--bg-opacity:1;background-color:#c6f6d5;background-color:rgba(198,246,213,var(--bg-opacity))}.md\:bg-green-300{--bg-opacity:1;background-color:#9ae6b4;background-color:rgba(154,230,180,var(--bg-opacity))}.md\:bg-green-400{--bg-opacity:1;background-color:#68d391;background-color:rgba(104,211,145,var(--bg-opacity))}.md\:bg-green-500{--bg-opacity:1;background-color:#48bb78;background-color:rgba(72,187,120,var(--bg-opacity))}.md\:bg-green-600{--bg-opacity:1;background-color:#38a169;background-color:rgba(56,161,105,var(--bg-opacity))}.md\:bg-green-700{--bg-opacity:1;background-color:#2f855a;background-color:rgba(47,133,90,var(--bg-opacity))}.md\:bg-green-800{--bg-opacity:1;background-color:#276749;background-color:rgba(39,103,73,var(--bg-opacity))}.md\:bg-green-900{--bg-opacity:1;background-color:#22543d;background-color:rgba(34,84,61,var(--bg-opacity))}.md\:bg-teal-100{--bg-opacity:1;background-color:#e6fffa;background-color:rgba(230,255,250,var(--bg-opacity))}.md\:bg-teal-200{--bg-opacity:1;background-color:#b2f5ea;background-color:rgba(178,245,234,var(--bg-opacity))}.md\:bg-teal-300{--bg-opacity:1;background-color:#81e6d9;background-color:rgba(129,230,217,var(--bg-opacity))}.md\:bg-teal-400{--bg-opacity:1;background-color:#4fd1c5;background-color:rgba(79,209,197,var(--bg-opacity))}.md\:bg-teal-500{--bg-opacity:1;background-color:#38b2ac;background-color:rgba(56,178,172,var(--bg-opacity))}.md\:bg-teal-600{--bg-opacity:1;background-color:#319795;background-color:rgba(49,151,149,var(--bg-opacity))}.md\:bg-teal-700{--bg-opacity:1;background-color:#2c7a7b;background-color:rgba(44,122,123,var(--bg-opacity))}.md\:bg-teal-800{--bg-opacity:1;background-color:#285e61;background-color:rgba(40,94,97,var(--bg-opacity))}.md\:bg-teal-900{--bg-opacity:1;background-color:#234e52;background-color:rgba(35,78,82,var(--bg-opacity))}.md\:bg-blue-100{--bg-opacity:1;background-color:#ebf8ff;background-color:rgba(235,248,255,var(--bg-opacity))}.md\:bg-blue-200{--bg-opacity:1;background-color:#bee3f8;background-color:rgba(190,227,248,var(--bg-opacity))}.md\:bg-blue-300{--bg-opacity:1;background-color:#90cdf4;background-color:rgba(144,205,244,var(--bg-opacity))}.md\:bg-blue-400{--bg-opacity:1;background-color:#63b3ed;background-color:rgba(99,179,237,var(--bg-opacity))}.md\:bg-blue-500{--bg-opacity:1;background-color:#4299e1;background-color:rgba(66,153,225,var(--bg-opacity))}.md\:bg-blue-600{--bg-opacity:1;background-color:#3182ce;background-color:rgba(49,130,206,var(--bg-opacity))}.md\:bg-blue-700{--bg-opacity:1;background-color:#2b6cb0;background-color:rgba(43,108,176,var(--bg-opacity))}.md\:bg-blue-800{--bg-opacity:1;background-color:#2c5282;background-color:rgba(44,82,130,var(--bg-opacity))}.md\:bg-blue-900{--bg-opacity:1;background-color:#2a4365;background-color:rgba(42,67,101,var(--bg-opacity))}.md\:bg-indigo-100{--bg-opacity:1;background-color:#ebf4ff;background-color:rgba(235,244,255,var(--bg-opacity))}.md\:bg-indigo-200{--bg-opacity:1;background-color:#c3dafe;background-color:rgba(195,218,254,var(--bg-opacity))}.md\:bg-indigo-300{--bg-opacity:1;background-color:#a3bffa;background-color:rgba(163,191,250,var(--bg-opacity))}.md\:bg-indigo-400{--bg-opacity:1;background-color:#7f9cf5;background-color:rgba(127,156,245,var(--bg-opacity))}.md\:bg-indigo-500{--bg-opacity:1;background-color:#667eea;background-color:rgba(102,126,234,var(--bg-opacity))}.md\:bg-indigo-600{--bg-opacity:1;background-color:#5a67d8;background-color:rgba(90,103,216,var(--bg-opacity))}.md\:bg-indigo-700{--bg-opacity:1;background-color:#4c51bf;background-color:rgba(76,81,191,var(--bg-opacity))}.md\:bg-indigo-800{--bg-opacity:1;background-color:#434190;background-color:rgba(67,65,144,var(--bg-opacity))}.md\:bg-indigo-900{--bg-opacity:1;background-color:#3c366b;background-color:rgba(60,54,107,var(--bg-opacity))}.md\:bg-purple-100{--bg-opacity:1;background-color:#faf5ff;background-color:rgba(250,245,255,var(--bg-opacity))}.md\:bg-purple-200{--bg-opacity:1;background-color:#e9d8fd;background-color:rgba(233,216,253,var(--bg-opacity))}.md\:bg-purple-300{--bg-opacity:1;background-color:#d6bcfa;background-color:rgba(214,188,250,var(--bg-opacity))}.md\:bg-purple-400{--bg-opacity:1;background-color:#b794f4;background-color:rgba(183,148,244,var(--bg-opacity))}.md\:bg-purple-500{--bg-opacity:1;background-color:#9f7aea;background-color:rgba(159,122,234,var(--bg-opacity))}.md\:bg-purple-600{--bg-opacity:1;background-color:#805ad5;background-color:rgba(128,90,213,var(--bg-opacity))}.md\:bg-purple-700{--bg-opacity:1;background-color:#6b46c1;background-color:rgba(107,70,193,var(--bg-opacity))}.md\:bg-purple-800{--bg-opacity:1;background-color:#553c9a;background-color:rgba(85,60,154,var(--bg-opacity))}.md\:bg-purple-900{--bg-opacity:1;background-color:#44337a;background-color:rgba(68,51,122,var(--bg-opacity))}.md\:bg-pink-100{--bg-opacity:1;background-color:#fff5f7;background-color:rgba(255,245,247,var(--bg-opacity))}.md\:bg-pink-200{--bg-opacity:1;background-color:#fed7e2;background-color:rgba(254,215,226,var(--bg-opacity))}.md\:bg-pink-300{--bg-opacity:1;background-color:#fbb6ce;background-color:rgba(251,182,206,var(--bg-opacity))}.md\:bg-pink-400{--bg-opacity:1;background-color:#f687b3;background-color:rgba(246,135,179,var(--bg-opacity))}.md\:bg-pink-500{--bg-opacity:1;background-color:#ed64a6;background-color:rgba(237,100,166,var(--bg-opacity))}.md\:bg-pink-600{--bg-opacity:1;background-color:#d53f8c;background-color:rgba(213,63,140,var(--bg-opacity))}.md\:bg-pink-700{--bg-opacity:1;background-color:#b83280;background-color:rgba(184,50,128,var(--bg-opacity))}.md\:bg-pink-800{--bg-opacity:1;background-color:#97266d;background-color:rgba(151,38,109,var(--bg-opacity))}.md\:bg-pink-900{--bg-opacity:1;background-color:#702459;background-color:rgba(112,36,89,var(--bg-opacity))}.md\:hover\:bg-transparent:hover{background-color:transparent}.md\:hover\:bg-current:hover{background-color:currentColor}.md\:hover\:bg-black:hover{--bg-opacity:1;background-color:#000;background-color:rgba(0,0,0,var(--bg-opacity))}.md\:hover\:bg-white:hover{--bg-opacity:1;background-color:#fff;background-color:rgba(255,255,255,var(--bg-opacity))}.md\:hover\:bg-gray-100:hover{--bg-opacity:1;background-color:#f7fafc;background-color:rgba(247,250,252,var(--bg-opacity))}.md\:hover\:bg-gray-200:hover{--bg-opacity:1;background-color:#edf2f7;background-color:rgba(237,242,247,var(--bg-opacity))}.md\:hover\:bg-gray-300:hover{--bg-opacity:1;background-color:#e2e8f0;background-color:rgba(226,232,240,var(--bg-opacity))}.md\:hover\:bg-gray-400:hover{--bg-opacity:1;background-color:#cbd5e0;background-color:rgba(203,213,224,var(--bg-opacity))}.md\:hover\:bg-gray-500:hover{--bg-opacity:1;background-color:#a0aec0;background-color:rgba(160,174,192,var(--bg-opacity))}.md\:hover\:bg-gray-600:hover{--bg-opacity:1;background-color:#718096;background-color:rgba(113,128,150,var(--bg-opacity))}.md\:hover\:bg-gray-700:hover{--bg-opacity:1;background-color:#4a5568;background-color:rgba(74,85,104,var(--bg-opacity))}.md\:hover\:bg-gray-800:hover{--bg-opacity:1;background-color:#2d3748;background-color:rgba(45,55,72,var(--bg-opacity))}.md\:hover\:bg-gray-900:hover{--bg-opacity:1;background-color:#1a202c;background-color:rgba(26,32,44,var(--bg-opacity))}.md\:hover\:bg-red-100:hover{--bg-opacity:1;background-color:#fff5f5;background-color:rgba(255,245,245,var(--bg-opacity))}.md\:hover\:bg-red-200:hover{--bg-opacity:1;background-color:#fed7d7;background-color:rgba(254,215,215,var(--bg-opacity))}.md\:hover\:bg-red-300:hover{--bg-opacity:1;background-color:#feb2b2;background-color:rgba(254,178,178,var(--bg-opacity))}.md\:hover\:bg-red-400:hover{--bg-opacity:1;background-color:#fc8181;background-color:rgba(252,129,129,var(--bg-opacity))}.md\:hover\:bg-red-500:hover{--bg-opacity:1;background-color:#f56565;background-color:rgba(245,101,101,var(--bg-opacity))}.md\:hover\:bg-red-600:hover{--bg-opacity:1;background-color:#e53e3e;background-color:rgba(229,62,62,var(--bg-opacity))}.md\:hover\:bg-red-700:hover{--bg-opacity:1;background-color:#c53030;background-color:rgba(197,48,48,var(--bg-opacity))}.md\:hover\:bg-red-800:hover{--bg-opacity:1;background-color:#9b2c2c;background-color:rgba(155,44,44,var(--bg-opacity))}.md\:hover\:bg-red-900:hover{--bg-opacity:1;background-color:#742a2a;background-color:rgba(116,42,42,var(--bg-opacity))}.md\:hover\:bg-orange-100:hover{--bg-opacity:1;background-color:#fffaf0;background-color:rgba(255,250,240,var(--bg-opacity))}.md\:hover\:bg-orange-200:hover{--bg-opacity:1;background-color:#feebc8;background-color:rgba(254,235,200,var(--bg-opacity))}.md\:hover\:bg-orange-300:hover{--bg-opacity:1;background-color:#fbd38d;background-color:rgba(251,211,141,var(--bg-opacity))}.md\:hover\:bg-orange-400:hover{--bg-opacity:1;background-color:#f6ad55;background-color:rgba(246,173,85,var(--bg-opacity))}.md\:hover\:bg-orange-500:hover{--bg-opacity:1;background-color:#ed8936;background-color:rgba(237,137,54,var(--bg-opacity))}.md\:hover\:bg-orange-600:hover{--bg-opacity:1;background-color:#dd6b20;background-color:rgba(221,107,32,var(--bg-opacity))}.md\:hover\:bg-orange-700:hover{--bg-opacity:1;background-color:#c05621;background-color:rgba(192,86,33,var(--bg-opacity))}.md\:hover\:bg-orange-800:hover{--bg-opacity:1;background-color:#9c4221;background-color:rgba(156,66,33,var(--bg-opacity))}.md\:hover\:bg-orange-900:hover{--bg-opacity:1;background-color:#7b341e;background-color:rgba(123,52,30,var(--bg-opacity))}.md\:hover\:bg-yellow-100:hover{--bg-opacity:1;background-color:ivory;background-color:rgba(255,255,240,var(--bg-opacity))}.md\:hover\:bg-yellow-200:hover{--bg-opacity:1;background-color:#fefcbf;background-color:rgba(254,252,191,var(--bg-opacity))}.md\:hover\:bg-yellow-300:hover{--bg-opacity:1;background-color:#faf089;background-color:rgba(250,240,137,var(--bg-opacity))}.md\:hover\:bg-yellow-400:hover{--bg-opacity:1;background-color:#f6e05e;background-color:rgba(246,224,94,var(--bg-opacity))}.md\:hover\:bg-yellow-500:hover{--bg-opacity:1;background-color:#ecc94b;background-color:rgba(236,201,75,var(--bg-opacity))}.md\:hover\:bg-yellow-600:hover{--bg-opacity:1;background-color:#d69e2e;background-color:rgba(214,158,46,var(--bg-opacity))}.md\:hover\:bg-yellow-700:hover{--bg-opacity:1;background-color:#b7791f;background-color:rgba(183,121,31,var(--bg-opacity))}.md\:hover\:bg-yellow-800:hover{--bg-opacity:1;background-color:#975a16;background-color:rgba(151,90,22,var(--bg-opacity))}.md\:hover\:bg-yellow-900:hover{--bg-opacity:1;background-color:#744210;background-color:rgba(116,66,16,var(--bg-opacity))}.md\:hover\:bg-green-100:hover{--bg-opacity:1;background-color:#f0fff4;background-color:rgba(240,255,244,var(--bg-opacity))}.md\:hover\:bg-green-200:hover{--bg-opacity:1;background-color:#c6f6d5;background-color:rgba(198,246,213,var(--bg-opacity))}.md\:hover\:bg-green-300:hover{--bg-opacity:1;background-color:#9ae6b4;background-color:rgba(154,230,180,var(--bg-opacity))}.md\:hover\:bg-green-400:hover{--bg-opacity:1;background-color:#68d391;background-color:rgba(104,211,145,var(--bg-opacity))}.md\:hover\:bg-green-500:hover{--bg-opacity:1;background-color:#48bb78;background-color:rgba(72,187,120,var(--bg-opacity))}.md\:hover\:bg-green-600:hover{--bg-opacity:1;background-color:#38a169;background-color:rgba(56,161,105,var(--bg-opacity))}.md\:hover\:bg-green-700:hover{--bg-opacity:1;background-color:#2f855a;background-color:rgba(47,133,90,var(--bg-opacity))}.md\:hover\:bg-green-800:hover{--bg-opacity:1;background-color:#276749;background-color:rgba(39,103,73,var(--bg-opacity))}.md\:hover\:bg-green-900:hover{--bg-opacity:1;background-color:#22543d;background-color:rgba(34,84,61,var(--bg-opacity))}.md\:hover\:bg-teal-100:hover{--bg-opacity:1;background-color:#e6fffa;background-color:rgba(230,255,250,var(--bg-opacity))}.md\:hover\:bg-teal-200:hover{--bg-opacity:1;background-color:#b2f5ea;background-color:rgba(178,245,234,var(--bg-opacity))}.md\:hover\:bg-teal-300:hover{--bg-opacity:1;background-color:#81e6d9;background-color:rgba(129,230,217,var(--bg-opacity))}.md\:hover\:bg-teal-400:hover{--bg-opacity:1;background-color:#4fd1c5;background-color:rgba(79,209,197,var(--bg-opacity))}.md\:hover\:bg-teal-500:hover{--bg-opacity:1;background-color:#38b2ac;background-color:rgba(56,178,172,var(--bg-opacity))}.md\:hover\:bg-teal-600:hover{--bg-opacity:1;background-color:#319795;background-color:rgba(49,151,149,var(--bg-opacity))}.md\:hover\:bg-teal-700:hover{--bg-opacity:1;background-color:#2c7a7b;background-color:rgba(44,122,123,var(--bg-opacity))}.md\:hover\:bg-teal-800:hover{--bg-opacity:1;background-color:#285e61;background-color:rgba(40,94,97,var(--bg-opacity))}.md\:hover\:bg-teal-900:hover{--bg-opacity:1;background-color:#234e52;background-color:rgba(35,78,82,var(--bg-opacity))}.md\:hover\:bg-blue-100:hover{--bg-opacity:1;background-color:#ebf8ff;background-color:rgba(235,248,255,var(--bg-opacity))}.md\:hover\:bg-blue-200:hover{--bg-opacity:1;background-color:#bee3f8;background-color:rgba(190,227,248,var(--bg-opacity))}.md\:hover\:bg-blue-300:hover{--bg-opacity:1;background-color:#90cdf4;background-color:rgba(144,205,244,var(--bg-opacity))}.md\:hover\:bg-blue-400:hover{--bg-opacity:1;background-color:#63b3ed;background-color:rgba(99,179,237,var(--bg-opacity))}.md\:hover\:bg-blue-500:hover{--bg-opacity:1;background-color:#4299e1;background-color:rgba(66,153,225,var(--bg-opacity))}.md\:hover\:bg-blue-600:hover{--bg-opacity:1;background-color:#3182ce;background-color:rgba(49,130,206,var(--bg-opacity))}.md\:hover\:bg-blue-700:hover{--bg-opacity:1;background-color:#2b6cb0;background-color:rgba(43,108,176,var(--bg-opacity))}.md\:hover\:bg-blue-800:hover{--bg-opacity:1;background-color:#2c5282;background-color:rgba(44,82,130,var(--bg-opacity))}.md\:hover\:bg-blue-900:hover{--bg-opacity:1;background-color:#2a4365;background-color:rgba(42,67,101,var(--bg-opacity))}.md\:hover\:bg-indigo-100:hover{--bg-opacity:1;background-color:#ebf4ff;background-color:rgba(235,244,255,var(--bg-opacity))}.md\:hover\:bg-indigo-200:hover{--bg-opacity:1;background-color:#c3dafe;background-color:rgba(195,218,254,var(--bg-opacity))}.md\:hover\:bg-indigo-300:hover{--bg-opacity:1;background-color:#a3bffa;background-color:rgba(163,191,250,var(--bg-opacity))}.md\:hover\:bg-indigo-400:hover{--bg-opacity:1;background-color:#7f9cf5;background-color:rgba(127,156,245,var(--bg-opacity))}.md\:hover\:bg-indigo-500:hover{--bg-opacity:1;background-color:#667eea;background-color:rgba(102,126,234,var(--bg-opacity))}.md\:hover\:bg-indigo-600:hover{--bg-opacity:1;background-color:#5a67d8;background-color:rgba(90,103,216,var(--bg-opacity))}.md\:hover\:bg-indigo-700:hover{--bg-opacity:1;background-color:#4c51bf;background-color:rgba(76,81,191,var(--bg-opacity))}.md\:hover\:bg-indigo-800:hover{--bg-opacity:1;background-color:#434190;background-color:rgba(67,65,144,var(--bg-opacity))}.md\:hover\:bg-indigo-900:hover{--bg-opacity:1;background-color:#3c366b;background-color:rgba(60,54,107,var(--bg-opacity))}.md\:hover\:bg-purple-100:hover{--bg-opacity:1;background-color:#faf5ff;background-color:rgba(250,245,255,var(--bg-opacity))}.md\:hover\:bg-purple-200:hover{--bg-opacity:1;background-color:#e9d8fd;background-color:rgba(233,216,253,var(--bg-opacity))}.md\:hover\:bg-purple-300:hover{--bg-opacity:1;background-color:#d6bcfa;background-color:rgba(214,188,250,var(--bg-opacity))}.md\:hover\:bg-purple-400:hover{--bg-opacity:1;background-color:#b794f4;background-color:rgba(183,148,244,var(--bg-opacity))}.md\:hover\:bg-purple-500:hover{--bg-opacity:1;background-color:#9f7aea;background-color:rgba(159,122,234,var(--bg-opacity))}.md\:hover\:bg-purple-600:hover{--bg-opacity:1;background-color:#805ad5;background-color:rgba(128,90,213,var(--bg-opacity))}.md\:hover\:bg-purple-700:hover{--bg-opacity:1;background-color:#6b46c1;background-color:rgba(107,70,193,var(--bg-opacity))}.md\:hover\:bg-purple-800:hover{--bg-opacity:1;background-color:#553c9a;background-color:rgba(85,60,154,var(--bg-opacity))}.md\:hover\:bg-purple-900:hover{--bg-opacity:1;background-color:#44337a;background-color:rgba(68,51,122,var(--bg-opacity))}.md\:hover\:bg-pink-100:hover{--bg-opacity:1;background-color:#fff5f7;background-color:rgba(255,245,247,var(--bg-opacity))}.md\:hover\:bg-pink-200:hover{--bg-opacity:1;background-color:#fed7e2;background-color:rgba(254,215,226,var(--bg-opacity))}.md\:hover\:bg-pink-300:hover{--bg-opacity:1;background-color:#fbb6ce;background-color:rgba(251,182,206,var(--bg-opacity))}.md\:hover\:bg-pink-400:hover{--bg-opacity:1;background-color:#f687b3;background-color:rgba(246,135,179,var(--bg-opacity))}.md\:hover\:bg-pink-500:hover{--bg-opacity:1;background-color:#ed64a6;background-color:rgba(237,100,166,var(--bg-opacity))}.md\:hover\:bg-pink-600:hover{--bg-opacity:1;background-color:#d53f8c;background-color:rgba(213,63,140,var(--bg-opacity))}.md\:hover\:bg-pink-700:hover{--bg-opacity:1;background-color:#b83280;background-color:rgba(184,50,128,var(--bg-opacity))}.md\:hover\:bg-pink-800:hover{--bg-opacity:1;background-color:#97266d;background-color:rgba(151,38,109,var(--bg-opacity))}.md\:hover\:bg-pink-900:hover{--bg-opacity:1;background-color:#702459;background-color:rgba(112,36,89,var(--bg-opacity))}.md\:focus\:bg-transparent:focus{background-color:transparent}.md\:focus\:bg-current:focus{background-color:currentColor}.md\:focus\:bg-black:focus{--bg-opacity:1;background-color:#000;background-color:rgba(0,0,0,var(--bg-opacity))}.md\:focus\:bg-white:focus{--bg-opacity:1;background-color:#fff;background-color:rgba(255,255,255,var(--bg-opacity))}.md\:focus\:bg-gray-100:focus{--bg-opacity:1;background-color:#f7fafc;background-color:rgba(247,250,252,var(--bg-opacity))}.md\:focus\:bg-gray-200:focus{--bg-opacity:1;background-color:#edf2f7;background-color:rgba(237,242,247,var(--bg-opacity))}.md\:focus\:bg-gray-300:focus{--bg-opacity:1;background-color:#e2e8f0;background-color:rgba(226,232,240,var(--bg-opacity))}.md\:focus\:bg-gray-400:focus{--bg-opacity:1;background-color:#cbd5e0;background-color:rgba(203,213,224,var(--bg-opacity))}.md\:focus\:bg-gray-500:focus{--bg-opacity:1;background-color:#a0aec0;background-color:rgba(160,174,192,var(--bg-opacity))}.md\:focus\:bg-gray-600:focus{--bg-opacity:1;background-color:#718096;background-color:rgba(113,128,150,var(--bg-opacity))}.md\:focus\:bg-gray-700:focus{--bg-opacity:1;background-color:#4a5568;background-color:rgba(74,85,104,var(--bg-opacity))}.md\:focus\:bg-gray-800:focus{--bg-opacity:1;background-color:#2d3748;background-color:rgba(45,55,72,var(--bg-opacity))}.md\:focus\:bg-gray-900:focus{--bg-opacity:1;background-color:#1a202c;background-color:rgba(26,32,44,var(--bg-opacity))}.md\:focus\:bg-red-100:focus{--bg-opacity:1;background-color:#fff5f5;background-color:rgba(255,245,245,var(--bg-opacity))}.md\:focus\:bg-red-200:focus{--bg-opacity:1;background-color:#fed7d7;background-color:rgba(254,215,215,var(--bg-opacity))}.md\:focus\:bg-red-300:focus{--bg-opacity:1;background-color:#feb2b2;background-color:rgba(254,178,178,var(--bg-opacity))}.md\:focus\:bg-red-400:focus{--bg-opacity:1;background-color:#fc8181;background-color:rgba(252,129,129,var(--bg-opacity))}.md\:focus\:bg-red-500:focus{--bg-opacity:1;background-color:#f56565;background-color:rgba(245,101,101,var(--bg-opacity))}.md\:focus\:bg-red-600:focus{--bg-opacity:1;background-color:#e53e3e;background-color:rgba(229,62,62,var(--bg-opacity))}.md\:focus\:bg-red-700:focus{--bg-opacity:1;background-color:#c53030;background-color:rgba(197,48,48,var(--bg-opacity))}.md\:focus\:bg-red-800:focus{--bg-opacity:1;background-color:#9b2c2c;background-color:rgba(155,44,44,var(--bg-opacity))}.md\:focus\:bg-red-900:focus{--bg-opacity:1;background-color:#742a2a;background-color:rgba(116,42,42,var(--bg-opacity))}.md\:focus\:bg-orange-100:focus{--bg-opacity:1;background-color:#fffaf0;background-color:rgba(255,250,240,var(--bg-opacity))}.md\:focus\:bg-orange-200:focus{--bg-opacity:1;background-color:#feebc8;background-color:rgba(254,235,200,var(--bg-opacity))}.md\:focus\:bg-orange-300:focus{--bg-opacity:1;background-color:#fbd38d;background-color:rgba(251,211,141,var(--bg-opacity))}.md\:focus\:bg-orange-400:focus{--bg-opacity:1;background-color:#f6ad55;background-color:rgba(246,173,85,var(--bg-opacity))}.md\:focus\:bg-orange-500:focus{--bg-opacity:1;background-color:#ed8936;background-color:rgba(237,137,54,var(--bg-opacity))}.md\:focus\:bg-orange-600:focus{--bg-opacity:1;background-color:#dd6b20;background-color:rgba(221,107,32,var(--bg-opacity))}.md\:focus\:bg-orange-700:focus{--bg-opacity:1;background-color:#c05621;background-color:rgba(192,86,33,var(--bg-opacity))}.md\:focus\:bg-orange-800:focus{--bg-opacity:1;background-color:#9c4221;background-color:rgba(156,66,33,var(--bg-opacity))}.md\:focus\:bg-orange-900:focus{--bg-opacity:1;background-color:#7b341e;background-color:rgba(123,52,30,var(--bg-opacity))}.md\:focus\:bg-yellow-100:focus{--bg-opacity:1;background-color:ivory;background-color:rgba(255,255,240,var(--bg-opacity))}.md\:focus\:bg-yellow-200:focus{--bg-opacity:1;background-color:#fefcbf;background-color:rgba(254,252,191,var(--bg-opacity))}.md\:focus\:bg-yellow-300:focus{--bg-opacity:1;background-color:#faf089;background-color:rgba(250,240,137,var(--bg-opacity))}.md\:focus\:bg-yellow-400:focus{--bg-opacity:1;background-color:#f6e05e;background-color:rgba(246,224,94,var(--bg-opacity))}.md\:focus\:bg-yellow-500:focus{--bg-opacity:1;background-color:#ecc94b;background-color:rgba(236,201,75,var(--bg-opacity))}.md\:focus\:bg-yellow-600:focus{--bg-opacity:1;background-color:#d69e2e;background-color:rgba(214,158,46,var(--bg-opacity))}.md\:focus\:bg-yellow-700:focus{--bg-opacity:1;background-color:#b7791f;background-color:rgba(183,121,31,var(--bg-opacity))}.md\:focus\:bg-yellow-800:focus{--bg-opacity:1;background-color:#975a16;background-color:rgba(151,90,22,var(--bg-opacity))}.md\:focus\:bg-yellow-900:focus{--bg-opacity:1;background-color:#744210;background-color:rgba(116,66,16,var(--bg-opacity))}.md\:focus\:bg-green-100:focus{--bg-opacity:1;background-color:#f0fff4;background-color:rgba(240,255,244,var(--bg-opacity))}.md\:focus\:bg-green-200:focus{--bg-opacity:1;background-color:#c6f6d5;background-color:rgba(198,246,213,var(--bg-opacity))}.md\:focus\:bg-green-300:focus{--bg-opacity:1;background-color:#9ae6b4;background-color:rgba(154,230,180,var(--bg-opacity))}.md\:focus\:bg-green-400:focus{--bg-opacity:1;background-color:#68d391;background-color:rgba(104,211,145,var(--bg-opacity))}.md\:focus\:bg-green-500:focus{--bg-opacity:1;background-color:#48bb78;background-color:rgba(72,187,120,var(--bg-opacity))}.md\:focus\:bg-green-600:focus{--bg-opacity:1;background-color:#38a169;background-color:rgba(56,161,105,var(--bg-opacity))}.md\:focus\:bg-green-700:focus{--bg-opacity:1;background-color:#2f855a;background-color:rgba(47,133,90,var(--bg-opacity))}.md\:focus\:bg-green-800:focus{--bg-opacity:1;background-color:#276749;background-color:rgba(39,103,73,var(--bg-opacity))}.md\:focus\:bg-green-900:focus{--bg-opacity:1;background-color:#22543d;background-color:rgba(34,84,61,var(--bg-opacity))}.md\:focus\:bg-teal-100:focus{--bg-opacity:1;background-color:#e6fffa;background-color:rgba(230,255,250,var(--bg-opacity))}.md\:focus\:bg-teal-200:focus{--bg-opacity:1;background-color:#b2f5ea;background-color:rgba(178,245,234,var(--bg-opacity))}.md\:focus\:bg-teal-300:focus{--bg-opacity:1;background-color:#81e6d9;background-color:rgba(129,230,217,var(--bg-opacity))}.md\:focus\:bg-teal-400:focus{--bg-opacity:1;background-color:#4fd1c5;background-color:rgba(79,209,197,var(--bg-opacity))}.md\:focus\:bg-teal-500:focus{--bg-opacity:1;background-color:#38b2ac;background-color:rgba(56,178,172,var(--bg-opacity))}.md\:focus\:bg-teal-600:focus{--bg-opacity:1;background-color:#319795;background-color:rgba(49,151,149,var(--bg-opacity))}.md\:focus\:bg-teal-700:focus{--bg-opacity:1;background-color:#2c7a7b;background-color:rgba(44,122,123,var(--bg-opacity))}.md\:focus\:bg-teal-800:focus{--bg-opacity:1;background-color:#285e61;background-color:rgba(40,94,97,var(--bg-opacity))}.md\:focus\:bg-teal-900:focus{--bg-opacity:1;background-color:#234e52;background-color:rgba(35,78,82,var(--bg-opacity))}.md\:focus\:bg-blue-100:focus{--bg-opacity:1;background-color:#ebf8ff;background-color:rgba(235,248,255,var(--bg-opacity))}.md\:focus\:bg-blue-200:focus{--bg-opacity:1;background-color:#bee3f8;background-color:rgba(190,227,248,var(--bg-opacity))}.md\:focus\:bg-blue-300:focus{--bg-opacity:1;background-color:#90cdf4;background-color:rgba(144,205,244,var(--bg-opacity))}.md\:focus\:bg-blue-400:focus{--bg-opacity:1;background-color:#63b3ed;background-color:rgba(99,179,237,var(--bg-opacity))}.md\:focus\:bg-blue-500:focus{--bg-opacity:1;background-color:#4299e1;background-color:rgba(66,153,225,var(--bg-opacity))}.md\:focus\:bg-blue-600:focus{--bg-opacity:1;background-color:#3182ce;background-color:rgba(49,130,206,var(--bg-opacity))}.md\:focus\:bg-blue-700:focus{--bg-opacity:1;background-color:#2b6cb0;background-color:rgba(43,108,176,var(--bg-opacity))}.md\:focus\:bg-blue-800:focus{--bg-opacity:1;background-color:#2c5282;background-color:rgba(44,82,130,var(--bg-opacity))}.md\:focus\:bg-blue-900:focus{--bg-opacity:1;background-color:#2a4365;background-color:rgba(42,67,101,var(--bg-opacity))}.md\:focus\:bg-indigo-100:focus{--bg-opacity:1;background-color:#ebf4ff;background-color:rgba(235,244,255,var(--bg-opacity))}.md\:focus\:bg-indigo-200:focus{--bg-opacity:1;background-color:#c3dafe;background-color:rgba(195,218,254,var(--bg-opacity))}.md\:focus\:bg-indigo-300:focus{--bg-opacity:1;background-color:#a3bffa;background-color:rgba(163,191,250,var(--bg-opacity))}.md\:focus\:bg-indigo-400:focus{--bg-opacity:1;background-color:#7f9cf5;background-color:rgba(127,156,245,var(--bg-opacity))}.md\:focus\:bg-indigo-500:focus{--bg-opacity:1;background-color:#667eea;background-color:rgba(102,126,234,var(--bg-opacity))}.md\:focus\:bg-indigo-600:focus{--bg-opacity:1;background-color:#5a67d8;background-color:rgba(90,103,216,var(--bg-opacity))}.md\:focus\:bg-indigo-700:focus{--bg-opacity:1;background-color:#4c51bf;background-color:rgba(76,81,191,var(--bg-opacity))}.md\:focus\:bg-indigo-800:focus{--bg-opacity:1;background-color:#434190;background-color:rgba(67,65,144,var(--bg-opacity))}.md\:focus\:bg-indigo-900:focus{--bg-opacity:1;background-color:#3c366b;background-color:rgba(60,54,107,var(--bg-opacity))}.md\:focus\:bg-purple-100:focus{--bg-opacity:1;background-color:#faf5ff;background-color:rgba(250,245,255,var(--bg-opacity))}.md\:focus\:bg-purple-200:focus{--bg-opacity:1;background-color:#e9d8fd;background-color:rgba(233,216,253,var(--bg-opacity))}.md\:focus\:bg-purple-300:focus{--bg-opacity:1;background-color:#d6bcfa;background-color:rgba(214,188,250,var(--bg-opacity))}.md\:focus\:bg-purple-400:focus{--bg-opacity:1;background-color:#b794f4;background-color:rgba(183,148,244,var(--bg-opacity))}.md\:focus\:bg-purple-500:focus{--bg-opacity:1;background-color:#9f7aea;background-color:rgba(159,122,234,var(--bg-opacity))}.md\:focus\:bg-purple-600:focus{--bg-opacity:1;background-color:#805ad5;background-color:rgba(128,90,213,var(--bg-opacity))}.md\:focus\:bg-purple-700:focus{--bg-opacity:1;background-color:#6b46c1;background-color:rgba(107,70,193,var(--bg-opacity))}.md\:focus\:bg-purple-800:focus{--bg-opacity:1;background-color:#553c9a;background-color:rgba(85,60,154,var(--bg-opacity))}.md\:focus\:bg-purple-900:focus{--bg-opacity:1;background-color:#44337a;background-color:rgba(68,51,122,var(--bg-opacity))}.md\:focus\:bg-pink-100:focus{--bg-opacity:1;background-color:#fff5f7;background-color:rgba(255,245,247,var(--bg-opacity))}.md\:focus\:bg-pink-200:focus{--bg-opacity:1;background-color:#fed7e2;background-color:rgba(254,215,226,var(--bg-opacity))}.md\:focus\:bg-pink-300:focus{--bg-opacity:1;background-color:#fbb6ce;background-color:rgba(251,182,206,var(--bg-opacity))}.md\:focus\:bg-pink-400:focus{--bg-opacity:1;background-color:#f687b3;background-color:rgba(246,135,179,var(--bg-opacity))}.md\:focus\:bg-pink-500:focus{--bg-opacity:1;background-color:#ed64a6;background-color:rgba(237,100,166,var(--bg-opacity))}.md\:focus\:bg-pink-600:focus{--bg-opacity:1;background-color:#d53f8c;background-color:rgba(213,63,140,var(--bg-opacity))}.md\:focus\:bg-pink-700:focus{--bg-opacity:1;background-color:#b83280;background-color:rgba(184,50,128,var(--bg-opacity))}.md\:focus\:bg-pink-800:focus{--bg-opacity:1;background-color:#97266d;background-color:rgba(151,38,109,var(--bg-opacity))}.md\:focus\:bg-pink-900:focus{--bg-opacity:1;background-color:#702459;background-color:rgba(112,36,89,var(--bg-opacity))}.md\:bg-none{background-image:none}.md\:bg-gradient-to-t{background-image:linear-gradient(to top,var(--gradient-color-stops))}.md\:bg-gradient-to-tr{background-image:linear-gradient(to top right,var(--gradient-color-stops))}.md\:bg-gradient-to-r{background-image:linear-gradient(to right,var(--gradient-color-stops))}.md\:bg-gradient-to-br{background-image:linear-gradient(to bottom right,var(--gradient-color-stops))}.md\:bg-gradient-to-b{background-image:linear-gradient(to bottom,var(--gradient-color-stops))}.md\:bg-gradient-to-bl{background-image:linear-gradient(to bottom left,var(--gradient-color-stops))}.md\:bg-gradient-to-l{background-image:linear-gradient(to left,var(--gradient-color-stops))}.md\:bg-gradient-to-tl{background-image:linear-gradient(to top left,var(--gradient-color-stops))}.md\:from-transparent{--gradient-from-color:transparent;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(0, 0, 0, 0))}.md\:from-current{--gradient-from-color:currentColor;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 255, 255, 0))}.md\:from-black{--gradient-from-color:#000;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(0, 0, 0, 0))}.md\:from-white{--gradient-from-color:#fff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 255, 255, 0))}.md\:from-gray-100{--gradient-from-color:#f7fafc;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(247, 250, 252, 0))}.md\:from-gray-200{--gradient-from-color:#edf2f7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(237, 242, 247, 0))}.md\:from-gray-300{--gradient-from-color:#e2e8f0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(226, 232, 240, 0))}.md\:from-gray-400{--gradient-from-color:#cbd5e0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(203, 213, 224, 0))}.md\:from-gray-500{--gradient-from-color:#a0aec0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(160, 174, 192, 0))}.md\:from-gray-600{--gradient-from-color:#718096;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(113, 128, 150, 0))}.md\:from-gray-700{--gradient-from-color:#4a5568;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(74, 85, 104, 0))}.md\:from-gray-800{--gradient-from-color:#2d3748;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(45, 55, 72, 0))}.md\:from-gray-900{--gradient-from-color:#1a202c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(26, 32, 44, 0))}.md\:from-red-100{--gradient-from-color:#fff5f5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 245, 245, 0))}.md\:from-red-200{--gradient-from-color:#fed7d7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(254, 215, 215, 0))}.md\:from-red-300{--gradient-from-color:#feb2b2;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(254, 178, 178, 0))}.md\:from-red-400{--gradient-from-color:#fc8181;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(252, 129, 129, 0))}.md\:from-red-500{--gradient-from-color:#f56565;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(245, 101, 101, 0))}.md\:from-red-600{--gradient-from-color:#e53e3e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(229, 62, 62, 0))}.md\:from-red-700{--gradient-from-color:#c53030;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(197, 48, 48, 0))}.md\:from-red-800{--gradient-from-color:#9b2c2c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(155, 44, 44, 0))}.md\:from-red-900{--gradient-from-color:#742a2a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(116, 42, 42, 0))}.md\:from-orange-100{--gradient-from-color:#fffaf0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 250, 240, 0))}.md\:from-orange-200{--gradient-from-color:#feebc8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(254, 235, 200, 0))}.md\:from-orange-300{--gradient-from-color:#fbd38d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(251, 211, 141, 0))}.md\:from-orange-400{--gradient-from-color:#f6ad55;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(246, 173, 85, 0))}.md\:from-orange-500{--gradient-from-color:#ed8936;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(237, 137, 54, 0))}.md\:from-orange-600{--gradient-from-color:#dd6b20;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(221, 107, 32, 0))}.md\:from-orange-700{--gradient-from-color:#c05621;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(192, 86, 33, 0))}.md\:from-orange-800{--gradient-from-color:#9c4221;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(156, 66, 33, 0))}.md\:from-orange-900{--gradient-from-color:#7b341e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(123, 52, 30, 0))}.md\:from-yellow-100{--gradient-from-color:#fffff0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 255, 240, 0))}.md\:from-yellow-200{--gradient-from-color:#fefcbf;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(254, 252, 191, 0))}.md\:from-yellow-300{--gradient-from-color:#faf089;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(250, 240, 137, 0))}.md\:from-yellow-400{--gradient-from-color:#f6e05e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(246, 224, 94, 0))}.md\:from-yellow-500{--gradient-from-color:#ecc94b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(236, 201, 75, 0))}.md\:from-yellow-600{--gradient-from-color:#d69e2e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(214, 158, 46, 0))}.md\:from-yellow-700{--gradient-from-color:#b7791f;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(183, 121, 31, 0))}.md\:from-yellow-800{--gradient-from-color:#975a16;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(151, 90, 22, 0))}.md\:from-yellow-900{--gradient-from-color:#744210;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(116, 66, 16, 0))}.md\:from-green-100{--gradient-from-color:#f0fff4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(240, 255, 244, 0))}.md\:from-green-200{--gradient-from-color:#c6f6d5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(198, 246, 213, 0))}.md\:from-green-300{--gradient-from-color:#9ae6b4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(154, 230, 180, 0))}.md\:from-green-400{--gradient-from-color:#68d391;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(104, 211, 145, 0))}.md\:from-green-500{--gradient-from-color:#48bb78;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(72, 187, 120, 0))}.md\:from-green-600{--gradient-from-color:#38a169;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(56, 161, 105, 0))}.md\:from-green-700{--gradient-from-color:#2f855a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(47, 133, 90, 0))}.md\:from-green-800{--gradient-from-color:#276749;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(39, 103, 73, 0))}.md\:from-green-900{--gradient-from-color:#22543d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(34, 84, 61, 0))}.md\:from-teal-100{--gradient-from-color:#e6fffa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(230, 255, 250, 0))}.md\:from-teal-200{--gradient-from-color:#b2f5ea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(178, 245, 234, 0))}.md\:from-teal-300{--gradient-from-color:#81e6d9;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(129, 230, 217, 0))}.md\:from-teal-400{--gradient-from-color:#4fd1c5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(79, 209, 197, 0))}.md\:from-teal-500{--gradient-from-color:#38b2ac;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(56, 178, 172, 0))}.md\:from-teal-600{--gradient-from-color:#319795;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(49, 151, 149, 0))}.md\:from-teal-700{--gradient-from-color:#2c7a7b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(44, 122, 123, 0))}.md\:from-teal-800{--gradient-from-color:#285e61;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(40, 94, 97, 0))}.md\:from-teal-900{--gradient-from-color:#234e52;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(35, 78, 82, 0))}.md\:from-blue-100{--gradient-from-color:#ebf8ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(235, 248, 255, 0))}.md\:from-blue-200{--gradient-from-color:#bee3f8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(190, 227, 248, 0))}.md\:from-blue-300{--gradient-from-color:#90cdf4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(144, 205, 244, 0))}.md\:from-blue-400{--gradient-from-color:#63b3ed;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(99, 179, 237, 0))}.md\:from-blue-500{--gradient-from-color:#4299e1;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(66, 153, 225, 0))}.md\:from-blue-600{--gradient-from-color:#3182ce;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(49, 130, 206, 0))}.md\:from-blue-700{--gradient-from-color:#2b6cb0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(43, 108, 176, 0))}.md\:from-blue-800{--gradient-from-color:#2c5282;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(44, 82, 130, 0))}.md\:from-blue-900{--gradient-from-color:#2a4365;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(42, 67, 101, 0))}.md\:from-indigo-100{--gradient-from-color:#ebf4ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(235, 244, 255, 0))}.md\:from-indigo-200{--gradient-from-color:#c3dafe;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(195, 218, 254, 0))}.md\:from-indigo-300{--gradient-from-color:#a3bffa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(163, 191, 250, 0))}.md\:from-indigo-400{--gradient-from-color:#7f9cf5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(127, 156, 245, 0))}.md\:from-indigo-500{--gradient-from-color:#667eea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(102, 126, 234, 0))}.md\:from-indigo-600{--gradient-from-color:#5a67d8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(90, 103, 216, 0))}.md\:from-indigo-700{--gradient-from-color:#4c51bf;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(76, 81, 191, 0))}.md\:from-indigo-800{--gradient-from-color:#434190;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(67, 65, 144, 0))}.md\:from-indigo-900{--gradient-from-color:#3c366b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(60, 54, 107, 0))}.md\:from-purple-100{--gradient-from-color:#faf5ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(250, 245, 255, 0))}.md\:from-purple-200{--gradient-from-color:#e9d8fd;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(233, 216, 253, 0))}.md\:from-purple-300{--gradient-from-color:#d6bcfa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(214, 188, 250, 0))}.md\:from-purple-400{--gradient-from-color:#b794f4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(183, 148, 244, 0))}.md\:from-purple-500{--gradient-from-color:#9f7aea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(159, 122, 234, 0))}.md\:from-purple-600{--gradient-from-color:#805ad5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(128, 90, 213, 0))}.md\:from-purple-700{--gradient-from-color:#6b46c1;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(107, 70, 193, 0))}.md\:from-purple-800{--gradient-from-color:#553c9a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(85, 60, 154, 0))}.md\:from-purple-900{--gradient-from-color:#44337a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(68, 51, 122, 0))}.md\:from-pink-100{--gradient-from-color:#fff5f7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 245, 247, 0))}.md\:from-pink-200{--gradient-from-color:#fed7e2;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(254, 215, 226, 0))}.md\:from-pink-300{--gradient-from-color:#fbb6ce;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(251, 182, 206, 0))}.md\:from-pink-400{--gradient-from-color:#f687b3;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(246, 135, 179, 0))}.md\:from-pink-500{--gradient-from-color:#ed64a6;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(237, 100, 166, 0))}.md\:from-pink-600{--gradient-from-color:#d53f8c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(213, 63, 140, 0))}.md\:from-pink-700{--gradient-from-color:#b83280;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(184, 50, 128, 0))}.md\:from-pink-800{--gradient-from-color:#97266d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(151, 38, 109, 0))}.md\:from-pink-900{--gradient-from-color:#702459;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(112, 36, 89, 0))}.md\:via-transparent{--gradient-via-color:transparent;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(0, 0, 0, 0))}.md\:via-current{--gradient-via-color:currentColor;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 255, 255, 0))}.md\:via-black{--gradient-via-color:#000;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(0, 0, 0, 0))}.md\:via-white{--gradient-via-color:#fff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 255, 255, 0))}.md\:via-gray-100{--gradient-via-color:#f7fafc;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(247, 250, 252, 0))}.md\:via-gray-200{--gradient-via-color:#edf2f7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(237, 242, 247, 0))}.md\:via-gray-300{--gradient-via-color:#e2e8f0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(226, 232, 240, 0))}.md\:via-gray-400{--gradient-via-color:#cbd5e0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(203, 213, 224, 0))}.md\:via-gray-500{--gradient-via-color:#a0aec0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(160, 174, 192, 0))}.md\:via-gray-600{--gradient-via-color:#718096;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(113, 128, 150, 0))}.md\:via-gray-700{--gradient-via-color:#4a5568;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(74, 85, 104, 0))}.md\:via-gray-800{--gradient-via-color:#2d3748;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(45, 55, 72, 0))}.md\:via-gray-900{--gradient-via-color:#1a202c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(26, 32, 44, 0))}.md\:via-red-100{--gradient-via-color:#fff5f5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 245, 245, 0))}.md\:via-red-200{--gradient-via-color:#fed7d7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(254, 215, 215, 0))}.md\:via-red-300{--gradient-via-color:#feb2b2;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(254, 178, 178, 0))}.md\:via-red-400{--gradient-via-color:#fc8181;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(252, 129, 129, 0))}.md\:via-red-500{--gradient-via-color:#f56565;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(245, 101, 101, 0))}.md\:via-red-600{--gradient-via-color:#e53e3e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(229, 62, 62, 0))}.md\:via-red-700{--gradient-via-color:#c53030;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(197, 48, 48, 0))}.md\:via-red-800{--gradient-via-color:#9b2c2c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(155, 44, 44, 0))}.md\:via-red-900{--gradient-via-color:#742a2a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(116, 42, 42, 0))}.md\:via-orange-100{--gradient-via-color:#fffaf0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 250, 240, 0))}.md\:via-orange-200{--gradient-via-color:#feebc8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(254, 235, 200, 0))}.md\:via-orange-300{--gradient-via-color:#fbd38d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(251, 211, 141, 0))}.md\:via-orange-400{--gradient-via-color:#f6ad55;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(246, 173, 85, 0))}.md\:via-orange-500{--gradient-via-color:#ed8936;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(237, 137, 54, 0))}.md\:via-orange-600{--gradient-via-color:#dd6b20;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(221, 107, 32, 0))}.md\:via-orange-700{--gradient-via-color:#c05621;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(192, 86, 33, 0))}.md\:via-orange-800{--gradient-via-color:#9c4221;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(156, 66, 33, 0))}.md\:via-orange-900{--gradient-via-color:#7b341e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(123, 52, 30, 0))}.md\:via-yellow-100{--gradient-via-color:#fffff0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 255, 240, 0))}.md\:via-yellow-200{--gradient-via-color:#fefcbf;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(254, 252, 191, 0))}.md\:via-yellow-300{--gradient-via-color:#faf089;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(250, 240, 137, 0))}.md\:via-yellow-400{--gradient-via-color:#f6e05e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(246, 224, 94, 0))}.md\:via-yellow-500{--gradient-via-color:#ecc94b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(236, 201, 75, 0))}.md\:via-yellow-600{--gradient-via-color:#d69e2e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(214, 158, 46, 0))}.md\:via-yellow-700{--gradient-via-color:#b7791f;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(183, 121, 31, 0))}.md\:via-yellow-800{--gradient-via-color:#975a16;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(151, 90, 22, 0))}.md\:via-yellow-900{--gradient-via-color:#744210;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(116, 66, 16, 0))}.md\:via-green-100{--gradient-via-color:#f0fff4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(240, 255, 244, 0))}.md\:via-green-200{--gradient-via-color:#c6f6d5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(198, 246, 213, 0))}.md\:via-green-300{--gradient-via-color:#9ae6b4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(154, 230, 180, 0))}.md\:via-green-400{--gradient-via-color:#68d391;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(104, 211, 145, 0))}.md\:via-green-500{--gradient-via-color:#48bb78;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(72, 187, 120, 0))}.md\:via-green-600{--gradient-via-color:#38a169;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(56, 161, 105, 0))}.md\:via-green-700{--gradient-via-color:#2f855a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(47, 133, 90, 0))}.md\:via-green-800{--gradient-via-color:#276749;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(39, 103, 73, 0))}.md\:via-green-900{--gradient-via-color:#22543d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(34, 84, 61, 0))}.md\:via-teal-100{--gradient-via-color:#e6fffa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(230, 255, 250, 0))}.md\:via-teal-200{--gradient-via-color:#b2f5ea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(178, 245, 234, 0))}.md\:via-teal-300{--gradient-via-color:#81e6d9;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(129, 230, 217, 0))}.md\:via-teal-400{--gradient-via-color:#4fd1c5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(79, 209, 197, 0))}.md\:via-teal-500{--gradient-via-color:#38b2ac;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(56, 178, 172, 0))}.md\:via-teal-600{--gradient-via-color:#319795;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(49, 151, 149, 0))}.md\:via-teal-700{--gradient-via-color:#2c7a7b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(44, 122, 123, 0))}.md\:via-teal-800{--gradient-via-color:#285e61;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(40, 94, 97, 0))}.md\:via-teal-900{--gradient-via-color:#234e52;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(35, 78, 82, 0))}.md\:via-blue-100{--gradient-via-color:#ebf8ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(235, 248, 255, 0))}.md\:via-blue-200{--gradient-via-color:#bee3f8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(190, 227, 248, 0))}.md\:via-blue-300{--gradient-via-color:#90cdf4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(144, 205, 244, 0))}.md\:via-blue-400{--gradient-via-color:#63b3ed;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(99, 179, 237, 0))}.md\:via-blue-500{--gradient-via-color:#4299e1;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(66, 153, 225, 0))}.md\:via-blue-600{--gradient-via-color:#3182ce;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(49, 130, 206, 0))}.md\:via-blue-700{--gradient-via-color:#2b6cb0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(43, 108, 176, 0))}.md\:via-blue-800{--gradient-via-color:#2c5282;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(44, 82, 130, 0))}.md\:via-blue-900{--gradient-via-color:#2a4365;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(42, 67, 101, 0))}.md\:via-indigo-100{--gradient-via-color:#ebf4ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(235, 244, 255, 0))}.md\:via-indigo-200{--gradient-via-color:#c3dafe;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(195, 218, 254, 0))}.md\:via-indigo-300{--gradient-via-color:#a3bffa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(163, 191, 250, 0))}.md\:via-indigo-400{--gradient-via-color:#7f9cf5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(127, 156, 245, 0))}.md\:via-indigo-500{--gradient-via-color:#667eea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(102, 126, 234, 0))}.md\:via-indigo-600{--gradient-via-color:#5a67d8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(90, 103, 216, 0))}.md\:via-indigo-700{--gradient-via-color:#4c51bf;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(76, 81, 191, 0))}.md\:via-indigo-800{--gradient-via-color:#434190;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(67, 65, 144, 0))}.md\:via-indigo-900{--gradient-via-color:#3c366b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(60, 54, 107, 0))}.md\:via-purple-100{--gradient-via-color:#faf5ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(250, 245, 255, 0))}.md\:via-purple-200{--gradient-via-color:#e9d8fd;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(233, 216, 253, 0))}.md\:via-purple-300{--gradient-via-color:#d6bcfa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(214, 188, 250, 0))}.md\:via-purple-400{--gradient-via-color:#b794f4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(183, 148, 244, 0))}.md\:via-purple-500{--gradient-via-color:#9f7aea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(159, 122, 234, 0))}.md\:via-purple-600{--gradient-via-color:#805ad5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(128, 90, 213, 0))}.md\:via-purple-700{--gradient-via-color:#6b46c1;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(107, 70, 193, 0))}.md\:via-purple-800{--gradient-via-color:#553c9a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(85, 60, 154, 0))}.md\:via-purple-900{--gradient-via-color:#44337a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(68, 51, 122, 0))}.md\:via-pink-100{--gradient-via-color:#fff5f7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 245, 247, 0))}.md\:via-pink-200{--gradient-via-color:#fed7e2;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(254, 215, 226, 0))}.md\:via-pink-300{--gradient-via-color:#fbb6ce;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(251, 182, 206, 0))}.md\:via-pink-400{--gradient-via-color:#f687b3;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(246, 135, 179, 0))}.md\:via-pink-500{--gradient-via-color:#ed64a6;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(237, 100, 166, 0))}.md\:via-pink-600{--gradient-via-color:#d53f8c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(213, 63, 140, 0))}.md\:via-pink-700{--gradient-via-color:#b83280;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(184, 50, 128, 0))}.md\:via-pink-800{--gradient-via-color:#97266d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(151, 38, 109, 0))}.md\:via-pink-900{--gradient-via-color:#702459;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(112, 36, 89, 0))}.md\:to-transparent{--gradient-to-color:transparent}.md\:to-current{--gradient-to-color:currentColor}.md\:to-black{--gradient-to-color:#000}.md\:to-white{--gradient-to-color:#fff}.md\:to-gray-100{--gradient-to-color:#f7fafc}.md\:to-gray-200{--gradient-to-color:#edf2f7}.md\:to-gray-300{--gradient-to-color:#e2e8f0}.md\:to-gray-400{--gradient-to-color:#cbd5e0}.md\:to-gray-500{--gradient-to-color:#a0aec0}.md\:to-gray-600{--gradient-to-color:#718096}.md\:to-gray-700{--gradient-to-color:#4a5568}.md\:to-gray-800{--gradient-to-color:#2d3748}.md\:to-gray-900{--gradient-to-color:#1a202c}.md\:to-red-100{--gradient-to-color:#fff5f5}.md\:to-red-200{--gradient-to-color:#fed7d7}.md\:to-red-300{--gradient-to-color:#feb2b2}.md\:to-red-400{--gradient-to-color:#fc8181}.md\:to-red-500{--gradient-to-color:#f56565}.md\:to-red-600{--gradient-to-color:#e53e3e}.md\:to-red-700{--gradient-to-color:#c53030}.md\:to-red-800{--gradient-to-color:#9b2c2c}.md\:to-red-900{--gradient-to-color:#742a2a}.md\:to-orange-100{--gradient-to-color:#fffaf0}.md\:to-orange-200{--gradient-to-color:#feebc8}.md\:to-orange-300{--gradient-to-color:#fbd38d}.md\:to-orange-400{--gradient-to-color:#f6ad55}.md\:to-orange-500{--gradient-to-color:#ed8936}.md\:to-orange-600{--gradient-to-color:#dd6b20}.md\:to-orange-700{--gradient-to-color:#c05621}.md\:to-orange-800{--gradient-to-color:#9c4221}.md\:to-orange-900{--gradient-to-color:#7b341e}.md\:to-yellow-100{--gradient-to-color:#fffff0}.md\:to-yellow-200{--gradient-to-color:#fefcbf}.md\:to-yellow-300{--gradient-to-color:#faf089}.md\:to-yellow-400{--gradient-to-color:#f6e05e}.md\:to-yellow-500{--gradient-to-color:#ecc94b}.md\:to-yellow-600{--gradient-to-color:#d69e2e}.md\:to-yellow-700{--gradient-to-color:#b7791f}.md\:to-yellow-800{--gradient-to-color:#975a16}.md\:to-yellow-900{--gradient-to-color:#744210}.md\:to-green-100{--gradient-to-color:#f0fff4}.md\:to-green-200{--gradient-to-color:#c6f6d5}.md\:to-green-300{--gradient-to-color:#9ae6b4}.md\:to-green-400{--gradient-to-color:#68d391}.md\:to-green-500{--gradient-to-color:#48bb78}.md\:to-green-600{--gradient-to-color:#38a169}.md\:to-green-700{--gradient-to-color:#2f855a}.md\:to-green-800{--gradient-to-color:#276749}.md\:to-green-900{--gradient-to-color:#22543d}.md\:to-teal-100{--gradient-to-color:#e6fffa}.md\:to-teal-200{--gradient-to-color:#b2f5ea}.md\:to-teal-300{--gradient-to-color:#81e6d9}.md\:to-teal-400{--gradient-to-color:#4fd1c5}.md\:to-teal-500{--gradient-to-color:#38b2ac}.md\:to-teal-600{--gradient-to-color:#319795}.md\:to-teal-700{--gradient-to-color:#2c7a7b}.md\:to-teal-800{--gradient-to-color:#285e61}.md\:to-teal-900{--gradient-to-color:#234e52}.md\:to-blue-100{--gradient-to-color:#ebf8ff}.md\:to-blue-200{--gradient-to-color:#bee3f8}.md\:to-blue-300{--gradient-to-color:#90cdf4}.md\:to-blue-400{--gradient-to-color:#63b3ed}.md\:to-blue-500{--gradient-to-color:#4299e1}.md\:to-blue-600{--gradient-to-color:#3182ce}.md\:to-blue-700{--gradient-to-color:#2b6cb0}.md\:to-blue-800{--gradient-to-color:#2c5282}.md\:to-blue-900{--gradient-to-color:#2a4365}.md\:to-indigo-100{--gradient-to-color:#ebf4ff}.md\:to-indigo-200{--gradient-to-color:#c3dafe}.md\:to-indigo-300{--gradient-to-color:#a3bffa}.md\:to-indigo-400{--gradient-to-color:#7f9cf5}.md\:to-indigo-500{--gradient-to-color:#667eea}.md\:to-indigo-600{--gradient-to-color:#5a67d8}.md\:to-indigo-700{--gradient-to-color:#4c51bf}.md\:to-indigo-800{--gradient-to-color:#434190}.md\:to-indigo-900{--gradient-to-color:#3c366b}.md\:to-purple-100{--gradient-to-color:#faf5ff}.md\:to-purple-200{--gradient-to-color:#e9d8fd}.md\:to-purple-300{--gradient-to-color:#d6bcfa}.md\:to-purple-400{--gradient-to-color:#b794f4}.md\:to-purple-500{--gradient-to-color:#9f7aea}.md\:to-purple-600{--gradient-to-color:#805ad5}.md\:to-purple-700{--gradient-to-color:#6b46c1}.md\:to-purple-800{--gradient-to-color:#553c9a}.md\:to-purple-900{--gradient-to-color:#44337a}.md\:to-pink-100{--gradient-to-color:#fff5f7}.md\:to-pink-200{--gradient-to-color:#fed7e2}.md\:to-pink-300{--gradient-to-color:#fbb6ce}.md\:to-pink-400{--gradient-to-color:#f687b3}.md\:to-pink-500{--gradient-to-color:#ed64a6}.md\:to-pink-600{--gradient-to-color:#d53f8c}.md\:to-pink-700{--gradient-to-color:#b83280}.md\:to-pink-800{--gradient-to-color:#97266d}.md\:to-pink-900{--gradient-to-color:#702459}.md\:hover\:from-transparent:hover{--gradient-from-color:transparent;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(0, 0, 0, 0))}.md\:hover\:from-current:hover{--gradient-from-color:currentColor;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 255, 255, 0))}.md\:hover\:from-black:hover{--gradient-from-color:#000;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(0, 0, 0, 0))}.md\:hover\:from-white:hover{--gradient-from-color:#fff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 255, 255, 0))}.md\:hover\:from-gray-100:hover{--gradient-from-color:#f7fafc;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(247, 250, 252, 0))}.md\:hover\:from-gray-200:hover{--gradient-from-color:#edf2f7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(237, 242, 247, 0))}.md\:hover\:from-gray-300:hover{--gradient-from-color:#e2e8f0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(226, 232, 240, 0))}.md\:hover\:from-gray-400:hover{--gradient-from-color:#cbd5e0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(203, 213, 224, 0))}.md\:hover\:from-gray-500:hover{--gradient-from-color:#a0aec0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(160, 174, 192, 0))}.md\:hover\:from-gray-600:hover{--gradient-from-color:#718096;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(113, 128, 150, 0))}.md\:hover\:from-gray-700:hover{--gradient-from-color:#4a5568;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(74, 85, 104, 0))}.md\:hover\:from-gray-800:hover{--gradient-from-color:#2d3748;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(45, 55, 72, 0))}.md\:hover\:from-gray-900:hover{--gradient-from-color:#1a202c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(26, 32, 44, 0))}.md\:hover\:from-red-100:hover{--gradient-from-color:#fff5f5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 245, 245, 0))}.md\:hover\:from-red-200:hover{--gradient-from-color:#fed7d7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(254, 215, 215, 0))}.md\:hover\:from-red-300:hover{--gradient-from-color:#feb2b2;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(254, 178, 178, 0))}.md\:hover\:from-red-400:hover{--gradient-from-color:#fc8181;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(252, 129, 129, 0))}.md\:hover\:from-red-500:hover{--gradient-from-color:#f56565;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(245, 101, 101, 0))}.md\:hover\:from-red-600:hover{--gradient-from-color:#e53e3e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(229, 62, 62, 0))}.md\:hover\:from-red-700:hover{--gradient-from-color:#c53030;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(197, 48, 48, 0))}.md\:hover\:from-red-800:hover{--gradient-from-color:#9b2c2c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(155, 44, 44, 0))}.md\:hover\:from-red-900:hover{--gradient-from-color:#742a2a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(116, 42, 42, 0))}.md\:hover\:from-orange-100:hover{--gradient-from-color:#fffaf0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 250, 240, 0))}.md\:hover\:from-orange-200:hover{--gradient-from-color:#feebc8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(254, 235, 200, 0))}.md\:hover\:from-orange-300:hover{--gradient-from-color:#fbd38d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(251, 211, 141, 0))}.md\:hover\:from-orange-400:hover{--gradient-from-color:#f6ad55;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(246, 173, 85, 0))}.md\:hover\:from-orange-500:hover{--gradient-from-color:#ed8936;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(237, 137, 54, 0))}.md\:hover\:from-orange-600:hover{--gradient-from-color:#dd6b20;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(221, 107, 32, 0))}.md\:hover\:from-orange-700:hover{--gradient-from-color:#c05621;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(192, 86, 33, 0))}.md\:hover\:from-orange-800:hover{--gradient-from-color:#9c4221;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(156, 66, 33, 0))}.md\:hover\:from-orange-900:hover{--gradient-from-color:#7b341e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(123, 52, 30, 0))}.md\:hover\:from-yellow-100:hover{--gradient-from-color:#fffff0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 255, 240, 0))}.md\:hover\:from-yellow-200:hover{--gradient-from-color:#fefcbf;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(254, 252, 191, 0))}.md\:hover\:from-yellow-300:hover{--gradient-from-color:#faf089;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(250, 240, 137, 0))}.md\:hover\:from-yellow-400:hover{--gradient-from-color:#f6e05e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(246, 224, 94, 0))}.md\:hover\:from-yellow-500:hover{--gradient-from-color:#ecc94b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(236, 201, 75, 0))}.md\:hover\:from-yellow-600:hover{--gradient-from-color:#d69e2e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(214, 158, 46, 0))}.md\:hover\:from-yellow-700:hover{--gradient-from-color:#b7791f;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(183, 121, 31, 0))}.md\:hover\:from-yellow-800:hover{--gradient-from-color:#975a16;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(151, 90, 22, 0))}.md\:hover\:from-yellow-900:hover{--gradient-from-color:#744210;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(116, 66, 16, 0))}.md\:hover\:from-green-100:hover{--gradient-from-color:#f0fff4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(240, 255, 244, 0))}.md\:hover\:from-green-200:hover{--gradient-from-color:#c6f6d5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(198, 246, 213, 0))}.md\:hover\:from-green-300:hover{--gradient-from-color:#9ae6b4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(154, 230, 180, 0))}.md\:hover\:from-green-400:hover{--gradient-from-color:#68d391;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(104, 211, 145, 0))}.md\:hover\:from-green-500:hover{--gradient-from-color:#48bb78;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(72, 187, 120, 0))}.md\:hover\:from-green-600:hover{--gradient-from-color:#38a169;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(56, 161, 105, 0))}.md\:hover\:from-green-700:hover{--gradient-from-color:#2f855a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(47, 133, 90, 0))}.md\:hover\:from-green-800:hover{--gradient-from-color:#276749;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(39, 103, 73, 0))}.md\:hover\:from-green-900:hover{--gradient-from-color:#22543d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(34, 84, 61, 0))}.md\:hover\:from-teal-100:hover{--gradient-from-color:#e6fffa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(230, 255, 250, 0))}.md\:hover\:from-teal-200:hover{--gradient-from-color:#b2f5ea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(178, 245, 234, 0))}.md\:hover\:from-teal-300:hover{--gradient-from-color:#81e6d9;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(129, 230, 217, 0))}.md\:hover\:from-teal-400:hover{--gradient-from-color:#4fd1c5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(79, 209, 197, 0))}.md\:hover\:from-teal-500:hover{--gradient-from-color:#38b2ac;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(56, 178, 172, 0))}.md\:hover\:from-teal-600:hover{--gradient-from-color:#319795;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(49, 151, 149, 0))}.md\:hover\:from-teal-700:hover{--gradient-from-color:#2c7a7b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(44, 122, 123, 0))}.md\:hover\:from-teal-800:hover{--gradient-from-color:#285e61;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(40, 94, 97, 0))}.md\:hover\:from-teal-900:hover{--gradient-from-color:#234e52;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(35, 78, 82, 0))}.md\:hover\:from-blue-100:hover{--gradient-from-color:#ebf8ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(235, 248, 255, 0))}.md\:hover\:from-blue-200:hover{--gradient-from-color:#bee3f8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(190, 227, 248, 0))}.md\:hover\:from-blue-300:hover{--gradient-from-color:#90cdf4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(144, 205, 244, 0))}.md\:hover\:from-blue-400:hover{--gradient-from-color:#63b3ed;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(99, 179, 237, 0))}.md\:hover\:from-blue-500:hover{--gradient-from-color:#4299e1;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(66, 153, 225, 0))}.md\:hover\:from-blue-600:hover{--gradient-from-color:#3182ce;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(49, 130, 206, 0))}.md\:hover\:from-blue-700:hover{--gradient-from-color:#2b6cb0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(43, 108, 176, 0))}.md\:hover\:from-blue-800:hover{--gradient-from-color:#2c5282;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(44, 82, 130, 0))}.md\:hover\:from-blue-900:hover{--gradient-from-color:#2a4365;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(42, 67, 101, 0))}.md\:hover\:from-indigo-100:hover{--gradient-from-color:#ebf4ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(235, 244, 255, 0))}.md\:hover\:from-indigo-200:hover{--gradient-from-color:#c3dafe;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(195, 218, 254, 0))}.md\:hover\:from-indigo-300:hover{--gradient-from-color:#a3bffa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(163, 191, 250, 0))}.md\:hover\:from-indigo-400:hover{--gradient-from-color:#7f9cf5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(127, 156, 245, 0))}.md\:hover\:from-indigo-500:hover{--gradient-from-color:#667eea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(102, 126, 234, 0))}.md\:hover\:from-indigo-600:hover{--gradient-from-color:#5a67d8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(90, 103, 216, 0))}.md\:hover\:from-indigo-700:hover{--gradient-from-color:#4c51bf;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(76, 81, 191, 0))}.md\:hover\:from-indigo-800:hover{--gradient-from-color:#434190;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(67, 65, 144, 0))}.md\:hover\:from-indigo-900:hover{--gradient-from-color:#3c366b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(60, 54, 107, 0))}.md\:hover\:from-purple-100:hover{--gradient-from-color:#faf5ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(250, 245, 255, 0))}.md\:hover\:from-purple-200:hover{--gradient-from-color:#e9d8fd;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(233, 216, 253, 0))}.md\:hover\:from-purple-300:hover{--gradient-from-color:#d6bcfa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(214, 188, 250, 0))}.md\:hover\:from-purple-400:hover{--gradient-from-color:#b794f4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(183, 148, 244, 0))}.md\:hover\:from-purple-500:hover{--gradient-from-color:#9f7aea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(159, 122, 234, 0))}.md\:hover\:from-purple-600:hover{--gradient-from-color:#805ad5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(128, 90, 213, 0))}.md\:hover\:from-purple-700:hover{--gradient-from-color:#6b46c1;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(107, 70, 193, 0))}.md\:hover\:from-purple-800:hover{--gradient-from-color:#553c9a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(85, 60, 154, 0))}.md\:hover\:from-purple-900:hover{--gradient-from-color:#44337a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(68, 51, 122, 0))}.md\:hover\:from-pink-100:hover{--gradient-from-color:#fff5f7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 245, 247, 0))}.md\:hover\:from-pink-200:hover{--gradient-from-color:#fed7e2;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(254, 215, 226, 0))}.md\:hover\:from-pink-300:hover{--gradient-from-color:#fbb6ce;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(251, 182, 206, 0))}.md\:hover\:from-pink-400:hover{--gradient-from-color:#f687b3;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(246, 135, 179, 0))}.md\:hover\:from-pink-500:hover{--gradient-from-color:#ed64a6;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(237, 100, 166, 0))}.md\:hover\:from-pink-600:hover{--gradient-from-color:#d53f8c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(213, 63, 140, 0))}.md\:hover\:from-pink-700:hover{--gradient-from-color:#b83280;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(184, 50, 128, 0))}.md\:hover\:from-pink-800:hover{--gradient-from-color:#97266d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(151, 38, 109, 0))}.md\:hover\:from-pink-900:hover{--gradient-from-color:#702459;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(112, 36, 89, 0))}.md\:hover\:via-transparent:hover{--gradient-via-color:transparent;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(0, 0, 0, 0))}.md\:hover\:via-current:hover{--gradient-via-color:currentColor;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 255, 255, 0))}.md\:hover\:via-black:hover{--gradient-via-color:#000;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(0, 0, 0, 0))}.md\:hover\:via-white:hover{--gradient-via-color:#fff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 255, 255, 0))}.md\:hover\:via-gray-100:hover{--gradient-via-color:#f7fafc;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(247, 250, 252, 0))}.md\:hover\:via-gray-200:hover{--gradient-via-color:#edf2f7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(237, 242, 247, 0))}.md\:hover\:via-gray-300:hover{--gradient-via-color:#e2e8f0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(226, 232, 240, 0))}.md\:hover\:via-gray-400:hover{--gradient-via-color:#cbd5e0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(203, 213, 224, 0))}.md\:hover\:via-gray-500:hover{--gradient-via-color:#a0aec0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(160, 174, 192, 0))}.md\:hover\:via-gray-600:hover{--gradient-via-color:#718096;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(113, 128, 150, 0))}.md\:hover\:via-gray-700:hover{--gradient-via-color:#4a5568;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(74, 85, 104, 0))}.md\:hover\:via-gray-800:hover{--gradient-via-color:#2d3748;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(45, 55, 72, 0))}.md\:hover\:via-gray-900:hover{--gradient-via-color:#1a202c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(26, 32, 44, 0))}.md\:hover\:via-red-100:hover{--gradient-via-color:#fff5f5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 245, 245, 0))}.md\:hover\:via-red-200:hover{--gradient-via-color:#fed7d7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(254, 215, 215, 0))}.md\:hover\:via-red-300:hover{--gradient-via-color:#feb2b2;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(254, 178, 178, 0))}.md\:hover\:via-red-400:hover{--gradient-via-color:#fc8181;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(252, 129, 129, 0))}.md\:hover\:via-red-500:hover{--gradient-via-color:#f56565;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(245, 101, 101, 0))}.md\:hover\:via-red-600:hover{--gradient-via-color:#e53e3e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(229, 62, 62, 0))}.md\:hover\:via-red-700:hover{--gradient-via-color:#c53030;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(197, 48, 48, 0))}.md\:hover\:via-red-800:hover{--gradient-via-color:#9b2c2c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(155, 44, 44, 0))}.md\:hover\:via-red-900:hover{--gradient-via-color:#742a2a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(116, 42, 42, 0))}.md\:hover\:via-orange-100:hover{--gradient-via-color:#fffaf0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 250, 240, 0))}.md\:hover\:via-orange-200:hover{--gradient-via-color:#feebc8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(254, 235, 200, 0))}.md\:hover\:via-orange-300:hover{--gradient-via-color:#fbd38d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(251, 211, 141, 0))}.md\:hover\:via-orange-400:hover{--gradient-via-color:#f6ad55;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(246, 173, 85, 0))}.md\:hover\:via-orange-500:hover{--gradient-via-color:#ed8936;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(237, 137, 54, 0))}.md\:hover\:via-orange-600:hover{--gradient-via-color:#dd6b20;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(221, 107, 32, 0))}.md\:hover\:via-orange-700:hover{--gradient-via-color:#c05621;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(192, 86, 33, 0))}.md\:hover\:via-orange-800:hover{--gradient-via-color:#9c4221;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(156, 66, 33, 0))}.md\:hover\:via-orange-900:hover{--gradient-via-color:#7b341e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(123, 52, 30, 0))}.md\:hover\:via-yellow-100:hover{--gradient-via-color:#fffff0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 255, 240, 0))}.md\:hover\:via-yellow-200:hover{--gradient-via-color:#fefcbf;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(254, 252, 191, 0))}.md\:hover\:via-yellow-300:hover{--gradient-via-color:#faf089;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(250, 240, 137, 0))}.md\:hover\:via-yellow-400:hover{--gradient-via-color:#f6e05e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(246, 224, 94, 0))}.md\:hover\:via-yellow-500:hover{--gradient-via-color:#ecc94b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(236, 201, 75, 0))}.md\:hover\:via-yellow-600:hover{--gradient-via-color:#d69e2e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(214, 158, 46, 0))}.md\:hover\:via-yellow-700:hover{--gradient-via-color:#b7791f;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(183, 121, 31, 0))}.md\:hover\:via-yellow-800:hover{--gradient-via-color:#975a16;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(151, 90, 22, 0))}.md\:hover\:via-yellow-900:hover{--gradient-via-color:#744210;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(116, 66, 16, 0))}.md\:hover\:via-green-100:hover{--gradient-via-color:#f0fff4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(240, 255, 244, 0))}.md\:hover\:via-green-200:hover{--gradient-via-color:#c6f6d5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(198, 246, 213, 0))}.md\:hover\:via-green-300:hover{--gradient-via-color:#9ae6b4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(154, 230, 180, 0))}.md\:hover\:via-green-400:hover{--gradient-via-color:#68d391;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(104, 211, 145, 0))}.md\:hover\:via-green-500:hover{--gradient-via-color:#48bb78;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(72, 187, 120, 0))}.md\:hover\:via-green-600:hover{--gradient-via-color:#38a169;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(56, 161, 105, 0))}.md\:hover\:via-green-700:hover{--gradient-via-color:#2f855a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(47, 133, 90, 0))}.md\:hover\:via-green-800:hover{--gradient-via-color:#276749;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(39, 103, 73, 0))}.md\:hover\:via-green-900:hover{--gradient-via-color:#22543d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(34, 84, 61, 0))}.md\:hover\:via-teal-100:hover{--gradient-via-color:#e6fffa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(230, 255, 250, 0))}.md\:hover\:via-teal-200:hover{--gradient-via-color:#b2f5ea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(178, 245, 234, 0))}.md\:hover\:via-teal-300:hover{--gradient-via-color:#81e6d9;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(129, 230, 217, 0))}.md\:hover\:via-teal-400:hover{--gradient-via-color:#4fd1c5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(79, 209, 197, 0))}.md\:hover\:via-teal-500:hover{--gradient-via-color:#38b2ac;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(56, 178, 172, 0))}.md\:hover\:via-teal-600:hover{--gradient-via-color:#319795;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(49, 151, 149, 0))}.md\:hover\:via-teal-700:hover{--gradient-via-color:#2c7a7b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(44, 122, 123, 0))}.md\:hover\:via-teal-800:hover{--gradient-via-color:#285e61;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(40, 94, 97, 0))}.md\:hover\:via-teal-900:hover{--gradient-via-color:#234e52;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(35, 78, 82, 0))}.md\:hover\:via-blue-100:hover{--gradient-via-color:#ebf8ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(235, 248, 255, 0))}.md\:hover\:via-blue-200:hover{--gradient-via-color:#bee3f8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(190, 227, 248, 0))}.md\:hover\:via-blue-300:hover{--gradient-via-color:#90cdf4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(144, 205, 244, 0))}.md\:hover\:via-blue-400:hover{--gradient-via-color:#63b3ed;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(99, 179, 237, 0))}.md\:hover\:via-blue-500:hover{--gradient-via-color:#4299e1;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(66, 153, 225, 0))}.md\:hover\:via-blue-600:hover{--gradient-via-color:#3182ce;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(49, 130, 206, 0))}.md\:hover\:via-blue-700:hover{--gradient-via-color:#2b6cb0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(43, 108, 176, 0))}.md\:hover\:via-blue-800:hover{--gradient-via-color:#2c5282;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(44, 82, 130, 0))}.md\:hover\:via-blue-900:hover{--gradient-via-color:#2a4365;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(42, 67, 101, 0))}.md\:hover\:via-indigo-100:hover{--gradient-via-color:#ebf4ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(235, 244, 255, 0))}.md\:hover\:via-indigo-200:hover{--gradient-via-color:#c3dafe;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(195, 218, 254, 0))}.md\:hover\:via-indigo-300:hover{--gradient-via-color:#a3bffa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(163, 191, 250, 0))}.md\:hover\:via-indigo-400:hover{--gradient-via-color:#7f9cf5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(127, 156, 245, 0))}.md\:hover\:via-indigo-500:hover{--gradient-via-color:#667eea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(102, 126, 234, 0))}.md\:hover\:via-indigo-600:hover{--gradient-via-color:#5a67d8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(90, 103, 216, 0))}.md\:hover\:via-indigo-700:hover{--gradient-via-color:#4c51bf;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(76, 81, 191, 0))}.md\:hover\:via-indigo-800:hover{--gradient-via-color:#434190;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(67, 65, 144, 0))}.md\:hover\:via-indigo-900:hover{--gradient-via-color:#3c366b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(60, 54, 107, 0))}.md\:hover\:via-purple-100:hover{--gradient-via-color:#faf5ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(250, 245, 255, 0))}.md\:hover\:via-purple-200:hover{--gradient-via-color:#e9d8fd;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(233, 216, 253, 0))}.md\:hover\:via-purple-300:hover{--gradient-via-color:#d6bcfa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(214, 188, 250, 0))}.md\:hover\:via-purple-400:hover{--gradient-via-color:#b794f4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(183, 148, 244, 0))}.md\:hover\:via-purple-500:hover{--gradient-via-color:#9f7aea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(159, 122, 234, 0))}.md\:hover\:via-purple-600:hover{--gradient-via-color:#805ad5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(128, 90, 213, 0))}.md\:hover\:via-purple-700:hover{--gradient-via-color:#6b46c1;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(107, 70, 193, 0))}.md\:hover\:via-purple-800:hover{--gradient-via-color:#553c9a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(85, 60, 154, 0))}.md\:hover\:via-purple-900:hover{--gradient-via-color:#44337a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(68, 51, 122, 0))}.md\:hover\:via-pink-100:hover{--gradient-via-color:#fff5f7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 245, 247, 0))}.md\:hover\:via-pink-200:hover{--gradient-via-color:#fed7e2;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(254, 215, 226, 0))}.md\:hover\:via-pink-300:hover{--gradient-via-color:#fbb6ce;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(251, 182, 206, 0))}.md\:hover\:via-pink-400:hover{--gradient-via-color:#f687b3;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(246, 135, 179, 0))}.md\:hover\:via-pink-500:hover{--gradient-via-color:#ed64a6;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(237, 100, 166, 0))}.md\:hover\:via-pink-600:hover{--gradient-via-color:#d53f8c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(213, 63, 140, 0))}.md\:hover\:via-pink-700:hover{--gradient-via-color:#b83280;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(184, 50, 128, 0))}.md\:hover\:via-pink-800:hover{--gradient-via-color:#97266d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(151, 38, 109, 0))}.md\:hover\:via-pink-900:hover{--gradient-via-color:#702459;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(112, 36, 89, 0))}.md\:hover\:to-transparent:hover{--gradient-to-color:transparent}.md\:hover\:to-current:hover{--gradient-to-color:currentColor}.md\:hover\:to-black:hover{--gradient-to-color:#000}.md\:hover\:to-white:hover{--gradient-to-color:#fff}.md\:hover\:to-gray-100:hover{--gradient-to-color:#f7fafc}.md\:hover\:to-gray-200:hover{--gradient-to-color:#edf2f7}.md\:hover\:to-gray-300:hover{--gradient-to-color:#e2e8f0}.md\:hover\:to-gray-400:hover{--gradient-to-color:#cbd5e0}.md\:hover\:to-gray-500:hover{--gradient-to-color:#a0aec0}.md\:hover\:to-gray-600:hover{--gradient-to-color:#718096}.md\:hover\:to-gray-700:hover{--gradient-to-color:#4a5568}.md\:hover\:to-gray-800:hover{--gradient-to-color:#2d3748}.md\:hover\:to-gray-900:hover{--gradient-to-color:#1a202c}.md\:hover\:to-red-100:hover{--gradient-to-color:#fff5f5}.md\:hover\:to-red-200:hover{--gradient-to-color:#fed7d7}.md\:hover\:to-red-300:hover{--gradient-to-color:#feb2b2}.md\:hover\:to-red-400:hover{--gradient-to-color:#fc8181}.md\:hover\:to-red-500:hover{--gradient-to-color:#f56565}.md\:hover\:to-red-600:hover{--gradient-to-color:#e53e3e}.md\:hover\:to-red-700:hover{--gradient-to-color:#c53030}.md\:hover\:to-red-800:hover{--gradient-to-color:#9b2c2c}.md\:hover\:to-red-900:hover{--gradient-to-color:#742a2a}.md\:hover\:to-orange-100:hover{--gradient-to-color:#fffaf0}.md\:hover\:to-orange-200:hover{--gradient-to-color:#feebc8}.md\:hover\:to-orange-300:hover{--gradient-to-color:#fbd38d}.md\:hover\:to-orange-400:hover{--gradient-to-color:#f6ad55}.md\:hover\:to-orange-500:hover{--gradient-to-color:#ed8936}.md\:hover\:to-orange-600:hover{--gradient-to-color:#dd6b20}.md\:hover\:to-orange-700:hover{--gradient-to-color:#c05621}.md\:hover\:to-orange-800:hover{--gradient-to-color:#9c4221}.md\:hover\:to-orange-900:hover{--gradient-to-color:#7b341e}.md\:hover\:to-yellow-100:hover{--gradient-to-color:#fffff0}.md\:hover\:to-yellow-200:hover{--gradient-to-color:#fefcbf}.md\:hover\:to-yellow-300:hover{--gradient-to-color:#faf089}.md\:hover\:to-yellow-400:hover{--gradient-to-color:#f6e05e}.md\:hover\:to-yellow-500:hover{--gradient-to-color:#ecc94b}.md\:hover\:to-yellow-600:hover{--gradient-to-color:#d69e2e}.md\:hover\:to-yellow-700:hover{--gradient-to-color:#b7791f}.md\:hover\:to-yellow-800:hover{--gradient-to-color:#975a16}.md\:hover\:to-yellow-900:hover{--gradient-to-color:#744210}.md\:hover\:to-green-100:hover{--gradient-to-color:#f0fff4}.md\:hover\:to-green-200:hover{--gradient-to-color:#c6f6d5}.md\:hover\:to-green-300:hover{--gradient-to-color:#9ae6b4}.md\:hover\:to-green-400:hover{--gradient-to-color:#68d391}.md\:hover\:to-green-500:hover{--gradient-to-color:#48bb78}.md\:hover\:to-green-600:hover{--gradient-to-color:#38a169}.md\:hover\:to-green-700:hover{--gradient-to-color:#2f855a}.md\:hover\:to-green-800:hover{--gradient-to-color:#276749}.md\:hover\:to-green-900:hover{--gradient-to-color:#22543d}.md\:hover\:to-teal-100:hover{--gradient-to-color:#e6fffa}.md\:hover\:to-teal-200:hover{--gradient-to-color:#b2f5ea}.md\:hover\:to-teal-300:hover{--gradient-to-color:#81e6d9}.md\:hover\:to-teal-400:hover{--gradient-to-color:#4fd1c5}.md\:hover\:to-teal-500:hover{--gradient-to-color:#38b2ac}.md\:hover\:to-teal-600:hover{--gradient-to-color:#319795}.md\:hover\:to-teal-700:hover{--gradient-to-color:#2c7a7b}.md\:hover\:to-teal-800:hover{--gradient-to-color:#285e61}.md\:hover\:to-teal-900:hover{--gradient-to-color:#234e52}.md\:hover\:to-blue-100:hover{--gradient-to-color:#ebf8ff}.md\:hover\:to-blue-200:hover{--gradient-to-color:#bee3f8}.md\:hover\:to-blue-300:hover{--gradient-to-color:#90cdf4}.md\:hover\:to-blue-400:hover{--gradient-to-color:#63b3ed}.md\:hover\:to-blue-500:hover{--gradient-to-color:#4299e1}.md\:hover\:to-blue-600:hover{--gradient-to-color:#3182ce}.md\:hover\:to-blue-700:hover{--gradient-to-color:#2b6cb0}.md\:hover\:to-blue-800:hover{--gradient-to-color:#2c5282}.md\:hover\:to-blue-900:hover{--gradient-to-color:#2a4365}.md\:hover\:to-indigo-100:hover{--gradient-to-color:#ebf4ff}.md\:hover\:to-indigo-200:hover{--gradient-to-color:#c3dafe}.md\:hover\:to-indigo-300:hover{--gradient-to-color:#a3bffa}.md\:hover\:to-indigo-400:hover{--gradient-to-color:#7f9cf5}.md\:hover\:to-indigo-500:hover{--gradient-to-color:#667eea}.md\:hover\:to-indigo-600:hover{--gradient-to-color:#5a67d8}.md\:hover\:to-indigo-700:hover{--gradient-to-color:#4c51bf}.md\:hover\:to-indigo-800:hover{--gradient-to-color:#434190}.md\:hover\:to-indigo-900:hover{--gradient-to-color:#3c366b}.md\:hover\:to-purple-100:hover{--gradient-to-color:#faf5ff}.md\:hover\:to-purple-200:hover{--gradient-to-color:#e9d8fd}.md\:hover\:to-purple-300:hover{--gradient-to-color:#d6bcfa}.md\:hover\:to-purple-400:hover{--gradient-to-color:#b794f4}.md\:hover\:to-purple-500:hover{--gradient-to-color:#9f7aea}.md\:hover\:to-purple-600:hover{--gradient-to-color:#805ad5}.md\:hover\:to-purple-700:hover{--gradient-to-color:#6b46c1}.md\:hover\:to-purple-800:hover{--gradient-to-color:#553c9a}.md\:hover\:to-purple-900:hover{--gradient-to-color:#44337a}.md\:hover\:to-pink-100:hover{--gradient-to-color:#fff5f7}.md\:hover\:to-pink-200:hover{--gradient-to-color:#fed7e2}.md\:hover\:to-pink-300:hover{--gradient-to-color:#fbb6ce}.md\:hover\:to-pink-400:hover{--gradient-to-color:#f687b3}.md\:hover\:to-pink-500:hover{--gradient-to-color:#ed64a6}.md\:hover\:to-pink-600:hover{--gradient-to-color:#d53f8c}.md\:hover\:to-pink-700:hover{--gradient-to-color:#b83280}.md\:hover\:to-pink-800:hover{--gradient-to-color:#97266d}.md\:hover\:to-pink-900:hover{--gradient-to-color:#702459}.md\:focus\:from-transparent:focus{--gradient-from-color:transparent;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(0, 0, 0, 0))}.md\:focus\:from-current:focus{--gradient-from-color:currentColor;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 255, 255, 0))}.md\:focus\:from-black:focus{--gradient-from-color:#000;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(0, 0, 0, 0))}.md\:focus\:from-white:focus{--gradient-from-color:#fff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 255, 255, 0))}.md\:focus\:from-gray-100:focus{--gradient-from-color:#f7fafc;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(247, 250, 252, 0))}.md\:focus\:from-gray-200:focus{--gradient-from-color:#edf2f7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(237, 242, 247, 0))}.md\:focus\:from-gray-300:focus{--gradient-from-color:#e2e8f0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(226, 232, 240, 0))}.md\:focus\:from-gray-400:focus{--gradient-from-color:#cbd5e0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(203, 213, 224, 0))}.md\:focus\:from-gray-500:focus{--gradient-from-color:#a0aec0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(160, 174, 192, 0))}.md\:focus\:from-gray-600:focus{--gradient-from-color:#718096;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(113, 128, 150, 0))}.md\:focus\:from-gray-700:focus{--gradient-from-color:#4a5568;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(74, 85, 104, 0))}.md\:focus\:from-gray-800:focus{--gradient-from-color:#2d3748;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(45, 55, 72, 0))}.md\:focus\:from-gray-900:focus{--gradient-from-color:#1a202c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(26, 32, 44, 0))}.md\:focus\:from-red-100:focus{--gradient-from-color:#fff5f5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 245, 245, 0))}.md\:focus\:from-red-200:focus{--gradient-from-color:#fed7d7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(254, 215, 215, 0))}.md\:focus\:from-red-300:focus{--gradient-from-color:#feb2b2;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(254, 178, 178, 0))}.md\:focus\:from-red-400:focus{--gradient-from-color:#fc8181;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(252, 129, 129, 0))}.md\:focus\:from-red-500:focus{--gradient-from-color:#f56565;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(245, 101, 101, 0))}.md\:focus\:from-red-600:focus{--gradient-from-color:#e53e3e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(229, 62, 62, 0))}.md\:focus\:from-red-700:focus{--gradient-from-color:#c53030;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(197, 48, 48, 0))}.md\:focus\:from-red-800:focus{--gradient-from-color:#9b2c2c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(155, 44, 44, 0))}.md\:focus\:from-red-900:focus{--gradient-from-color:#742a2a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(116, 42, 42, 0))}.md\:focus\:from-orange-100:focus{--gradient-from-color:#fffaf0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 250, 240, 0))}.md\:focus\:from-orange-200:focus{--gradient-from-color:#feebc8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(254, 235, 200, 0))}.md\:focus\:from-orange-300:focus{--gradient-from-color:#fbd38d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(251, 211, 141, 0))}.md\:focus\:from-orange-400:focus{--gradient-from-color:#f6ad55;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(246, 173, 85, 0))}.md\:focus\:from-orange-500:focus{--gradient-from-color:#ed8936;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(237, 137, 54, 0))}.md\:focus\:from-orange-600:focus{--gradient-from-color:#dd6b20;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(221, 107, 32, 0))}.md\:focus\:from-orange-700:focus{--gradient-from-color:#c05621;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(192, 86, 33, 0))}.md\:focus\:from-orange-800:focus{--gradient-from-color:#9c4221;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(156, 66, 33, 0))}.md\:focus\:from-orange-900:focus{--gradient-from-color:#7b341e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(123, 52, 30, 0))}.md\:focus\:from-yellow-100:focus{--gradient-from-color:#fffff0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 255, 240, 0))}.md\:focus\:from-yellow-200:focus{--gradient-from-color:#fefcbf;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(254, 252, 191, 0))}.md\:focus\:from-yellow-300:focus{--gradient-from-color:#faf089;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(250, 240, 137, 0))}.md\:focus\:from-yellow-400:focus{--gradient-from-color:#f6e05e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(246, 224, 94, 0))}.md\:focus\:from-yellow-500:focus{--gradient-from-color:#ecc94b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(236, 201, 75, 0))}.md\:focus\:from-yellow-600:focus{--gradient-from-color:#d69e2e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(214, 158, 46, 0))}.md\:focus\:from-yellow-700:focus{--gradient-from-color:#b7791f;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(183, 121, 31, 0))}.md\:focus\:from-yellow-800:focus{--gradient-from-color:#975a16;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(151, 90, 22, 0))}.md\:focus\:from-yellow-900:focus{--gradient-from-color:#744210;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(116, 66, 16, 0))}.md\:focus\:from-green-100:focus{--gradient-from-color:#f0fff4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(240, 255, 244, 0))}.md\:focus\:from-green-200:focus{--gradient-from-color:#c6f6d5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(198, 246, 213, 0))}.md\:focus\:from-green-300:focus{--gradient-from-color:#9ae6b4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(154, 230, 180, 0))}.md\:focus\:from-green-400:focus{--gradient-from-color:#68d391;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(104, 211, 145, 0))}.md\:focus\:from-green-500:focus{--gradient-from-color:#48bb78;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(72, 187, 120, 0))}.md\:focus\:from-green-600:focus{--gradient-from-color:#38a169;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(56, 161, 105, 0))}.md\:focus\:from-green-700:focus{--gradient-from-color:#2f855a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(47, 133, 90, 0))}.md\:focus\:from-green-800:focus{--gradient-from-color:#276749;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(39, 103, 73, 0))}.md\:focus\:from-green-900:focus{--gradient-from-color:#22543d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(34, 84, 61, 0))}.md\:focus\:from-teal-100:focus{--gradient-from-color:#e6fffa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(230, 255, 250, 0))}.md\:focus\:from-teal-200:focus{--gradient-from-color:#b2f5ea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(178, 245, 234, 0))}.md\:focus\:from-teal-300:focus{--gradient-from-color:#81e6d9;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(129, 230, 217, 0))}.md\:focus\:from-teal-400:focus{--gradient-from-color:#4fd1c5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(79, 209, 197, 0))}.md\:focus\:from-teal-500:focus{--gradient-from-color:#38b2ac;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(56, 178, 172, 0))}.md\:focus\:from-teal-600:focus{--gradient-from-color:#319795;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(49, 151, 149, 0))}.md\:focus\:from-teal-700:focus{--gradient-from-color:#2c7a7b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(44, 122, 123, 0))}.md\:focus\:from-teal-800:focus{--gradient-from-color:#285e61;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(40, 94, 97, 0))}.md\:focus\:from-teal-900:focus{--gradient-from-color:#234e52;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(35, 78, 82, 0))}.md\:focus\:from-blue-100:focus{--gradient-from-color:#ebf8ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(235, 248, 255, 0))}.md\:focus\:from-blue-200:focus{--gradient-from-color:#bee3f8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(190, 227, 248, 0))}.md\:focus\:from-blue-300:focus{--gradient-from-color:#90cdf4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(144, 205, 244, 0))}.md\:focus\:from-blue-400:focus{--gradient-from-color:#63b3ed;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(99, 179, 237, 0))}.md\:focus\:from-blue-500:focus{--gradient-from-color:#4299e1;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(66, 153, 225, 0))}.md\:focus\:from-blue-600:focus{--gradient-from-color:#3182ce;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(49, 130, 206, 0))}.md\:focus\:from-blue-700:focus{--gradient-from-color:#2b6cb0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(43, 108, 176, 0))}.md\:focus\:from-blue-800:focus{--gradient-from-color:#2c5282;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(44, 82, 130, 0))}.md\:focus\:from-blue-900:focus{--gradient-from-color:#2a4365;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(42, 67, 101, 0))}.md\:focus\:from-indigo-100:focus{--gradient-from-color:#ebf4ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(235, 244, 255, 0))}.md\:focus\:from-indigo-200:focus{--gradient-from-color:#c3dafe;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(195, 218, 254, 0))}.md\:focus\:from-indigo-300:focus{--gradient-from-color:#a3bffa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(163, 191, 250, 0))}.md\:focus\:from-indigo-400:focus{--gradient-from-color:#7f9cf5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(127, 156, 245, 0))}.md\:focus\:from-indigo-500:focus{--gradient-from-color:#667eea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(102, 126, 234, 0))}.md\:focus\:from-indigo-600:focus{--gradient-from-color:#5a67d8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(90, 103, 216, 0))}.md\:focus\:from-indigo-700:focus{--gradient-from-color:#4c51bf;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(76, 81, 191, 0))}.md\:focus\:from-indigo-800:focus{--gradient-from-color:#434190;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(67, 65, 144, 0))}.md\:focus\:from-indigo-900:focus{--gradient-from-color:#3c366b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(60, 54, 107, 0))}.md\:focus\:from-purple-100:focus{--gradient-from-color:#faf5ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(250, 245, 255, 0))}.md\:focus\:from-purple-200:focus{--gradient-from-color:#e9d8fd;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(233, 216, 253, 0))}.md\:focus\:from-purple-300:focus{--gradient-from-color:#d6bcfa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(214, 188, 250, 0))}.md\:focus\:from-purple-400:focus{--gradient-from-color:#b794f4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(183, 148, 244, 0))}.md\:focus\:from-purple-500:focus{--gradient-from-color:#9f7aea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(159, 122, 234, 0))}.md\:focus\:from-purple-600:focus{--gradient-from-color:#805ad5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(128, 90, 213, 0))}.md\:focus\:from-purple-700:focus{--gradient-from-color:#6b46c1;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(107, 70, 193, 0))}.md\:focus\:from-purple-800:focus{--gradient-from-color:#553c9a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(85, 60, 154, 0))}.md\:focus\:from-purple-900:focus{--gradient-from-color:#44337a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(68, 51, 122, 0))}.md\:focus\:from-pink-100:focus{--gradient-from-color:#fff5f7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 245, 247, 0))}.md\:focus\:from-pink-200:focus{--gradient-from-color:#fed7e2;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(254, 215, 226, 0))}.md\:focus\:from-pink-300:focus{--gradient-from-color:#fbb6ce;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(251, 182, 206, 0))}.md\:focus\:from-pink-400:focus{--gradient-from-color:#f687b3;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(246, 135, 179, 0))}.md\:focus\:from-pink-500:focus{--gradient-from-color:#ed64a6;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(237, 100, 166, 0))}.md\:focus\:from-pink-600:focus{--gradient-from-color:#d53f8c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(213, 63, 140, 0))}.md\:focus\:from-pink-700:focus{--gradient-from-color:#b83280;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(184, 50, 128, 0))}.md\:focus\:from-pink-800:focus{--gradient-from-color:#97266d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(151, 38, 109, 0))}.md\:focus\:from-pink-900:focus{--gradient-from-color:#702459;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(112, 36, 89, 0))}.md\:focus\:via-transparent:focus{--gradient-via-color:transparent;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(0, 0, 0, 0))}.md\:focus\:via-current:focus{--gradient-via-color:currentColor;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 255, 255, 0))}.md\:focus\:via-black:focus{--gradient-via-color:#000;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(0, 0, 0, 0))}.md\:focus\:via-white:focus{--gradient-via-color:#fff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 255, 255, 0))}.md\:focus\:via-gray-100:focus{--gradient-via-color:#f7fafc;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(247, 250, 252, 0))}.md\:focus\:via-gray-200:focus{--gradient-via-color:#edf2f7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(237, 242, 247, 0))}.md\:focus\:via-gray-300:focus{--gradient-via-color:#e2e8f0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(226, 232, 240, 0))}.md\:focus\:via-gray-400:focus{--gradient-via-color:#cbd5e0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(203, 213, 224, 0))}.md\:focus\:via-gray-500:focus{--gradient-via-color:#a0aec0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(160, 174, 192, 0))}.md\:focus\:via-gray-600:focus{--gradient-via-color:#718096;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(113, 128, 150, 0))}.md\:focus\:via-gray-700:focus{--gradient-via-color:#4a5568;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(74, 85, 104, 0))}.md\:focus\:via-gray-800:focus{--gradient-via-color:#2d3748;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(45, 55, 72, 0))}.md\:focus\:via-gray-900:focus{--gradient-via-color:#1a202c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(26, 32, 44, 0))}.md\:focus\:via-red-100:focus{--gradient-via-color:#fff5f5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 245, 245, 0))}.md\:focus\:via-red-200:focus{--gradient-via-color:#fed7d7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(254, 215, 215, 0))}.md\:focus\:via-red-300:focus{--gradient-via-color:#feb2b2;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(254, 178, 178, 0))}.md\:focus\:via-red-400:focus{--gradient-via-color:#fc8181;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(252, 129, 129, 0))}.md\:focus\:via-red-500:focus{--gradient-via-color:#f56565;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(245, 101, 101, 0))}.md\:focus\:via-red-600:focus{--gradient-via-color:#e53e3e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(229, 62, 62, 0))}.md\:focus\:via-red-700:focus{--gradient-via-color:#c53030;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(197, 48, 48, 0))}.md\:focus\:via-red-800:focus{--gradient-via-color:#9b2c2c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(155, 44, 44, 0))}.md\:focus\:via-red-900:focus{--gradient-via-color:#742a2a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(116, 42, 42, 0))}.md\:focus\:via-orange-100:focus{--gradient-via-color:#fffaf0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 250, 240, 0))}.md\:focus\:via-orange-200:focus{--gradient-via-color:#feebc8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(254, 235, 200, 0))}.md\:focus\:via-orange-300:focus{--gradient-via-color:#fbd38d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(251, 211, 141, 0))}.md\:focus\:via-orange-400:focus{--gradient-via-color:#f6ad55;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(246, 173, 85, 0))}.md\:focus\:via-orange-500:focus{--gradient-via-color:#ed8936;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(237, 137, 54, 0))}.md\:focus\:via-orange-600:focus{--gradient-via-color:#dd6b20;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(221, 107, 32, 0))}.md\:focus\:via-orange-700:focus{--gradient-via-color:#c05621;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(192, 86, 33, 0))}.md\:focus\:via-orange-800:focus{--gradient-via-color:#9c4221;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(156, 66, 33, 0))}.md\:focus\:via-orange-900:focus{--gradient-via-color:#7b341e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(123, 52, 30, 0))}.md\:focus\:via-yellow-100:focus{--gradient-via-color:#fffff0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 255, 240, 0))}.md\:focus\:via-yellow-200:focus{--gradient-via-color:#fefcbf;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(254, 252, 191, 0))}.md\:focus\:via-yellow-300:focus{--gradient-via-color:#faf089;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(250, 240, 137, 0))}.md\:focus\:via-yellow-400:focus{--gradient-via-color:#f6e05e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(246, 224, 94, 0))}.md\:focus\:via-yellow-500:focus{--gradient-via-color:#ecc94b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(236, 201, 75, 0))}.md\:focus\:via-yellow-600:focus{--gradient-via-color:#d69e2e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(214, 158, 46, 0))}.md\:focus\:via-yellow-700:focus{--gradient-via-color:#b7791f;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(183, 121, 31, 0))}.md\:focus\:via-yellow-800:focus{--gradient-via-color:#975a16;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(151, 90, 22, 0))}.md\:focus\:via-yellow-900:focus{--gradient-via-color:#744210;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(116, 66, 16, 0))}.md\:focus\:via-green-100:focus{--gradient-via-color:#f0fff4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(240, 255, 244, 0))}.md\:focus\:via-green-200:focus{--gradient-via-color:#c6f6d5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(198, 246, 213, 0))}.md\:focus\:via-green-300:focus{--gradient-via-color:#9ae6b4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(154, 230, 180, 0))}.md\:focus\:via-green-400:focus{--gradient-via-color:#68d391;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(104, 211, 145, 0))}.md\:focus\:via-green-500:focus{--gradient-via-color:#48bb78;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(72, 187, 120, 0))}.md\:focus\:via-green-600:focus{--gradient-via-color:#38a169;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(56, 161, 105, 0))}.md\:focus\:via-green-700:focus{--gradient-via-color:#2f855a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(47, 133, 90, 0))}.md\:focus\:via-green-800:focus{--gradient-via-color:#276749;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(39, 103, 73, 0))}.md\:focus\:via-green-900:focus{--gradient-via-color:#22543d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(34, 84, 61, 0))}.md\:focus\:via-teal-100:focus{--gradient-via-color:#e6fffa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(230, 255, 250, 0))}.md\:focus\:via-teal-200:focus{--gradient-via-color:#b2f5ea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(178, 245, 234, 0))}.md\:focus\:via-teal-300:focus{--gradient-via-color:#81e6d9;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(129, 230, 217, 0))}.md\:focus\:via-teal-400:focus{--gradient-via-color:#4fd1c5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(79, 209, 197, 0))}.md\:focus\:via-teal-500:focus{--gradient-via-color:#38b2ac;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(56, 178, 172, 0))}.md\:focus\:via-teal-600:focus{--gradient-via-color:#319795;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(49, 151, 149, 0))}.md\:focus\:via-teal-700:focus{--gradient-via-color:#2c7a7b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(44, 122, 123, 0))}.md\:focus\:via-teal-800:focus{--gradient-via-color:#285e61;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(40, 94, 97, 0))}.md\:focus\:via-teal-900:focus{--gradient-via-color:#234e52;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(35, 78, 82, 0))}.md\:focus\:via-blue-100:focus{--gradient-via-color:#ebf8ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(235, 248, 255, 0))}.md\:focus\:via-blue-200:focus{--gradient-via-color:#bee3f8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(190, 227, 248, 0))}.md\:focus\:via-blue-300:focus{--gradient-via-color:#90cdf4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(144, 205, 244, 0))}.md\:focus\:via-blue-400:focus{--gradient-via-color:#63b3ed;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(99, 179, 237, 0))}.md\:focus\:via-blue-500:focus{--gradient-via-color:#4299e1;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(66, 153, 225, 0))}.md\:focus\:via-blue-600:focus{--gradient-via-color:#3182ce;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(49, 130, 206, 0))}.md\:focus\:via-blue-700:focus{--gradient-via-color:#2b6cb0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(43, 108, 176, 0))}.md\:focus\:via-blue-800:focus{--gradient-via-color:#2c5282;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(44, 82, 130, 0))}.md\:focus\:via-blue-900:focus{--gradient-via-color:#2a4365;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(42, 67, 101, 0))}.md\:focus\:via-indigo-100:focus{--gradient-via-color:#ebf4ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(235, 244, 255, 0))}.md\:focus\:via-indigo-200:focus{--gradient-via-color:#c3dafe;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(195, 218, 254, 0))}.md\:focus\:via-indigo-300:focus{--gradient-via-color:#a3bffa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(163, 191, 250, 0))}.md\:focus\:via-indigo-400:focus{--gradient-via-color:#7f9cf5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(127, 156, 245, 0))}.md\:focus\:via-indigo-500:focus{--gradient-via-color:#667eea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(102, 126, 234, 0))}.md\:focus\:via-indigo-600:focus{--gradient-via-color:#5a67d8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(90, 103, 216, 0))}.md\:focus\:via-indigo-700:focus{--gradient-via-color:#4c51bf;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(76, 81, 191, 0))}.md\:focus\:via-indigo-800:focus{--gradient-via-color:#434190;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(67, 65, 144, 0))}.md\:focus\:via-indigo-900:focus{--gradient-via-color:#3c366b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(60, 54, 107, 0))}.md\:focus\:via-purple-100:focus{--gradient-via-color:#faf5ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(250, 245, 255, 0))}.md\:focus\:via-purple-200:focus{--gradient-via-color:#e9d8fd;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(233, 216, 253, 0))}.md\:focus\:via-purple-300:focus{--gradient-via-color:#d6bcfa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(214, 188, 250, 0))}.md\:focus\:via-purple-400:focus{--gradient-via-color:#b794f4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(183, 148, 244, 0))}.md\:focus\:via-purple-500:focus{--gradient-via-color:#9f7aea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(159, 122, 234, 0))}.md\:focus\:via-purple-600:focus{--gradient-via-color:#805ad5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(128, 90, 213, 0))}.md\:focus\:via-purple-700:focus{--gradient-via-color:#6b46c1;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(107, 70, 193, 0))}.md\:focus\:via-purple-800:focus{--gradient-via-color:#553c9a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(85, 60, 154, 0))}.md\:focus\:via-purple-900:focus{--gradient-via-color:#44337a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(68, 51, 122, 0))}.md\:focus\:via-pink-100:focus{--gradient-via-color:#fff5f7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 245, 247, 0))}.md\:focus\:via-pink-200:focus{--gradient-via-color:#fed7e2;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(254, 215, 226, 0))}.md\:focus\:via-pink-300:focus{--gradient-via-color:#fbb6ce;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(251, 182, 206, 0))}.md\:focus\:via-pink-400:focus{--gradient-via-color:#f687b3;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(246, 135, 179, 0))}.md\:focus\:via-pink-500:focus{--gradient-via-color:#ed64a6;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(237, 100, 166, 0))}.md\:focus\:via-pink-600:focus{--gradient-via-color:#d53f8c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(213, 63, 140, 0))}.md\:focus\:via-pink-700:focus{--gradient-via-color:#b83280;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(184, 50, 128, 0))}.md\:focus\:via-pink-800:focus{--gradient-via-color:#97266d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(151, 38, 109, 0))}.md\:focus\:via-pink-900:focus{--gradient-via-color:#702459;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(112, 36, 89, 0))}.md\:focus\:to-transparent:focus{--gradient-to-color:transparent}.md\:focus\:to-current:focus{--gradient-to-color:currentColor}.md\:focus\:to-black:focus{--gradient-to-color:#000}.md\:focus\:to-white:focus{--gradient-to-color:#fff}.md\:focus\:to-gray-100:focus{--gradient-to-color:#f7fafc}.md\:focus\:to-gray-200:focus{--gradient-to-color:#edf2f7}.md\:focus\:to-gray-300:focus{--gradient-to-color:#e2e8f0}.md\:focus\:to-gray-400:focus{--gradient-to-color:#cbd5e0}.md\:focus\:to-gray-500:focus{--gradient-to-color:#a0aec0}.md\:focus\:to-gray-600:focus{--gradient-to-color:#718096}.md\:focus\:to-gray-700:focus{--gradient-to-color:#4a5568}.md\:focus\:to-gray-800:focus{--gradient-to-color:#2d3748}.md\:focus\:to-gray-900:focus{--gradient-to-color:#1a202c}.md\:focus\:to-red-100:focus{--gradient-to-color:#fff5f5}.md\:focus\:to-red-200:focus{--gradient-to-color:#fed7d7}.md\:focus\:to-red-300:focus{--gradient-to-color:#feb2b2}.md\:focus\:to-red-400:focus{--gradient-to-color:#fc8181}.md\:focus\:to-red-500:focus{--gradient-to-color:#f56565}.md\:focus\:to-red-600:focus{--gradient-to-color:#e53e3e}.md\:focus\:to-red-700:focus{--gradient-to-color:#c53030}.md\:focus\:to-red-800:focus{--gradient-to-color:#9b2c2c}.md\:focus\:to-red-900:focus{--gradient-to-color:#742a2a}.md\:focus\:to-orange-100:focus{--gradient-to-color:#fffaf0}.md\:focus\:to-orange-200:focus{--gradient-to-color:#feebc8}.md\:focus\:to-orange-300:focus{--gradient-to-color:#fbd38d}.md\:focus\:to-orange-400:focus{--gradient-to-color:#f6ad55}.md\:focus\:to-orange-500:focus{--gradient-to-color:#ed8936}.md\:focus\:to-orange-600:focus{--gradient-to-color:#dd6b20}.md\:focus\:to-orange-700:focus{--gradient-to-color:#c05621}.md\:focus\:to-orange-800:focus{--gradient-to-color:#9c4221}.md\:focus\:to-orange-900:focus{--gradient-to-color:#7b341e}.md\:focus\:to-yellow-100:focus{--gradient-to-color:#fffff0}.md\:focus\:to-yellow-200:focus{--gradient-to-color:#fefcbf}.md\:focus\:to-yellow-300:focus{--gradient-to-color:#faf089}.md\:focus\:to-yellow-400:focus{--gradient-to-color:#f6e05e}.md\:focus\:to-yellow-500:focus{--gradient-to-color:#ecc94b}.md\:focus\:to-yellow-600:focus{--gradient-to-color:#d69e2e}.md\:focus\:to-yellow-700:focus{--gradient-to-color:#b7791f}.md\:focus\:to-yellow-800:focus{--gradient-to-color:#975a16}.md\:focus\:to-yellow-900:focus{--gradient-to-color:#744210}.md\:focus\:to-green-100:focus{--gradient-to-color:#f0fff4}.md\:focus\:to-green-200:focus{--gradient-to-color:#c6f6d5}.md\:focus\:to-green-300:focus{--gradient-to-color:#9ae6b4}.md\:focus\:to-green-400:focus{--gradient-to-color:#68d391}.md\:focus\:to-green-500:focus{--gradient-to-color:#48bb78}.md\:focus\:to-green-600:focus{--gradient-to-color:#38a169}.md\:focus\:to-green-700:focus{--gradient-to-color:#2f855a}.md\:focus\:to-green-800:focus{--gradient-to-color:#276749}.md\:focus\:to-green-900:focus{--gradient-to-color:#22543d}.md\:focus\:to-teal-100:focus{--gradient-to-color:#e6fffa}.md\:focus\:to-teal-200:focus{--gradient-to-color:#b2f5ea}.md\:focus\:to-teal-300:focus{--gradient-to-color:#81e6d9}.md\:focus\:to-teal-400:focus{--gradient-to-color:#4fd1c5}.md\:focus\:to-teal-500:focus{--gradient-to-color:#38b2ac}.md\:focus\:to-teal-600:focus{--gradient-to-color:#319795}.md\:focus\:to-teal-700:focus{--gradient-to-color:#2c7a7b}.md\:focus\:to-teal-800:focus{--gradient-to-color:#285e61}.md\:focus\:to-teal-900:focus{--gradient-to-color:#234e52}.md\:focus\:to-blue-100:focus{--gradient-to-color:#ebf8ff}.md\:focus\:to-blue-200:focus{--gradient-to-color:#bee3f8}.md\:focus\:to-blue-300:focus{--gradient-to-color:#90cdf4}.md\:focus\:to-blue-400:focus{--gradient-to-color:#63b3ed}.md\:focus\:to-blue-500:focus{--gradient-to-color:#4299e1}.md\:focus\:to-blue-600:focus{--gradient-to-color:#3182ce}.md\:focus\:to-blue-700:focus{--gradient-to-color:#2b6cb0}.md\:focus\:to-blue-800:focus{--gradient-to-color:#2c5282}.md\:focus\:to-blue-900:focus{--gradient-to-color:#2a4365}.md\:focus\:to-indigo-100:focus{--gradient-to-color:#ebf4ff}.md\:focus\:to-indigo-200:focus{--gradient-to-color:#c3dafe}.md\:focus\:to-indigo-300:focus{--gradient-to-color:#a3bffa}.md\:focus\:to-indigo-400:focus{--gradient-to-color:#7f9cf5}.md\:focus\:to-indigo-500:focus{--gradient-to-color:#667eea}.md\:focus\:to-indigo-600:focus{--gradient-to-color:#5a67d8}.md\:focus\:to-indigo-700:focus{--gradient-to-color:#4c51bf}.md\:focus\:to-indigo-800:focus{--gradient-to-color:#434190}.md\:focus\:to-indigo-900:focus{--gradient-to-color:#3c366b}.md\:focus\:to-purple-100:focus{--gradient-to-color:#faf5ff}.md\:focus\:to-purple-200:focus{--gradient-to-color:#e9d8fd}.md\:focus\:to-purple-300:focus{--gradient-to-color:#d6bcfa}.md\:focus\:to-purple-400:focus{--gradient-to-color:#b794f4}.md\:focus\:to-purple-500:focus{--gradient-to-color:#9f7aea}.md\:focus\:to-purple-600:focus{--gradient-to-color:#805ad5}.md\:focus\:to-purple-700:focus{--gradient-to-color:#6b46c1}.md\:focus\:to-purple-800:focus{--gradient-to-color:#553c9a}.md\:focus\:to-purple-900:focus{--gradient-to-color:#44337a}.md\:focus\:to-pink-100:focus{--gradient-to-color:#fff5f7}.md\:focus\:to-pink-200:focus{--gradient-to-color:#fed7e2}.md\:focus\:to-pink-300:focus{--gradient-to-color:#fbb6ce}.md\:focus\:to-pink-400:focus{--gradient-to-color:#f687b3}.md\:focus\:to-pink-500:focus{--gradient-to-color:#ed64a6}.md\:focus\:to-pink-600:focus{--gradient-to-color:#d53f8c}.md\:focus\:to-pink-700:focus{--gradient-to-color:#b83280}.md\:focus\:to-pink-800:focus{--gradient-to-color:#97266d}.md\:focus\:to-pink-900:focus{--gradient-to-color:#702459}.md\:bg-opacity-0{--bg-opacity:0}.md\:bg-opacity-25{--bg-opacity:0.25}.md\:bg-opacity-50{--bg-opacity:0.5}.md\:bg-opacity-75{--bg-opacity:0.75}.md\:bg-opacity-100{--bg-opacity:1}.md\:hover\:bg-opacity-0:hover{--bg-opacity:0}.md\:hover\:bg-opacity-25:hover{--bg-opacity:0.25}.md\:hover\:bg-opacity-50:hover{--bg-opacity:0.5}.md\:hover\:bg-opacity-75:hover{--bg-opacity:0.75}.md\:hover\:bg-opacity-100:hover{--bg-opacity:1}.md\:focus\:bg-opacity-0:focus{--bg-opacity:0}.md\:focus\:bg-opacity-25:focus{--bg-opacity:0.25}.md\:focus\:bg-opacity-50:focus{--bg-opacity:0.5}.md\:focus\:bg-opacity-75:focus{--bg-opacity:0.75}.md\:focus\:bg-opacity-100:focus{--bg-opacity:1}.md\:bg-bottom{background-position:bottom}.md\:bg-center{background-position:center}.md\:bg-left{background-position:left}.md\:bg-left-bottom{background-position:left bottom}.md\:bg-left-top{background-position:left top}.md\:bg-right{background-position:right}.md\:bg-right-bottom{background-position:right bottom}.md\:bg-right-top{background-position:right top}.md\:bg-top{background-position:top}.md\:bg-repeat{background-repeat:repeat}.md\:bg-no-repeat{background-repeat:no-repeat}.md\:bg-repeat-x{background-repeat:repeat-x}.md\:bg-repeat-y{background-repeat:repeat-y}.md\:bg-repeat-round{background-repeat:round}.md\:bg-repeat-space{background-repeat:space}.md\:bg-auto{background-size:auto}.md\:bg-cover{background-size:cover}.md\:bg-contain{background-size:contain}.md\:border-collapse{border-collapse:collapse}.md\:border-separate{border-collapse:separate}.md\:border-transparent{border-color:transparent}.md\:border-current{border-color:currentColor}.md\:border-black{--border-opacity:1;border-color:#000;border-color:rgba(0,0,0,var(--border-opacity))}.md\:border-white{--border-opacity:1;border-color:#fff;border-color:rgba(255,255,255,var(--border-opacity))}.md\:border-gray-100{--border-opacity:1;border-color:#f7fafc;border-color:rgba(247,250,252,var(--border-opacity))}.md\:border-gray-200{--border-opacity:1;border-color:#edf2f7;border-color:rgba(237,242,247,var(--border-opacity))}.md\:border-gray-300{--border-opacity:1;border-color:#e2e8f0;border-color:rgba(226,232,240,var(--border-opacity))}.md\:border-gray-400{--border-opacity:1;border-color:#cbd5e0;border-color:rgba(203,213,224,var(--border-opacity))}.md\:border-gray-500{--border-opacity:1;border-color:#a0aec0;border-color:rgba(160,174,192,var(--border-opacity))}.md\:border-gray-600{--border-opacity:1;border-color:#718096;border-color:rgba(113,128,150,var(--border-opacity))}.md\:border-gray-700{--border-opacity:1;border-color:#4a5568;border-color:rgba(74,85,104,var(--border-opacity))}.md\:border-gray-800{--border-opacity:1;border-color:#2d3748;border-color:rgba(45,55,72,var(--border-opacity))}.md\:border-gray-900{--border-opacity:1;border-color:#1a202c;border-color:rgba(26,32,44,var(--border-opacity))}.md\:border-red-100{--border-opacity:1;border-color:#fff5f5;border-color:rgba(255,245,245,var(--border-opacity))}.md\:border-red-200{--border-opacity:1;border-color:#fed7d7;border-color:rgba(254,215,215,var(--border-opacity))}.md\:border-red-300{--border-opacity:1;border-color:#feb2b2;border-color:rgba(254,178,178,var(--border-opacity))}.md\:border-red-400{--border-opacity:1;border-color:#fc8181;border-color:rgba(252,129,129,var(--border-opacity))}.md\:border-red-500{--border-opacity:1;border-color:#f56565;border-color:rgba(245,101,101,var(--border-opacity))}.md\:border-red-600{--border-opacity:1;border-color:#e53e3e;border-color:rgba(229,62,62,var(--border-opacity))}.md\:border-red-700{--border-opacity:1;border-color:#c53030;border-color:rgba(197,48,48,var(--border-opacity))}.md\:border-red-800{--border-opacity:1;border-color:#9b2c2c;border-color:rgba(155,44,44,var(--border-opacity))}.md\:border-red-900{--border-opacity:1;border-color:#742a2a;border-color:rgba(116,42,42,var(--border-opacity))}.md\:border-orange-100{--border-opacity:1;border-color:#fffaf0;border-color:rgba(255,250,240,var(--border-opacity))}.md\:border-orange-200{--border-opacity:1;border-color:#feebc8;border-color:rgba(254,235,200,var(--border-opacity))}.md\:border-orange-300{--border-opacity:1;border-color:#fbd38d;border-color:rgba(251,211,141,var(--border-opacity))}.md\:border-orange-400{--border-opacity:1;border-color:#f6ad55;border-color:rgba(246,173,85,var(--border-opacity))}.md\:border-orange-500{--border-opacity:1;border-color:#ed8936;border-color:rgba(237,137,54,var(--border-opacity))}.md\:border-orange-600{--border-opacity:1;border-color:#dd6b20;border-color:rgba(221,107,32,var(--border-opacity))}.md\:border-orange-700{--border-opacity:1;border-color:#c05621;border-color:rgba(192,86,33,var(--border-opacity))}.md\:border-orange-800{--border-opacity:1;border-color:#9c4221;border-color:rgba(156,66,33,var(--border-opacity))}.md\:border-orange-900{--border-opacity:1;border-color:#7b341e;border-color:rgba(123,52,30,var(--border-opacity))}.md\:border-yellow-100{--border-opacity:1;border-color:ivory;border-color:rgba(255,255,240,var(--border-opacity))}.md\:border-yellow-200{--border-opacity:1;border-color:#fefcbf;border-color:rgba(254,252,191,var(--border-opacity))}.md\:border-yellow-300{--border-opacity:1;border-color:#faf089;border-color:rgba(250,240,137,var(--border-opacity))}.md\:border-yellow-400{--border-opacity:1;border-color:#f6e05e;border-color:rgba(246,224,94,var(--border-opacity))}.md\:border-yellow-500{--border-opacity:1;border-color:#ecc94b;border-color:rgba(236,201,75,var(--border-opacity))}.md\:border-yellow-600{--border-opacity:1;border-color:#d69e2e;border-color:rgba(214,158,46,var(--border-opacity))}.md\:border-yellow-700{--border-opacity:1;border-color:#b7791f;border-color:rgba(183,121,31,var(--border-opacity))}.md\:border-yellow-800{--border-opacity:1;border-color:#975a16;border-color:rgba(151,90,22,var(--border-opacity))}.md\:border-yellow-900{--border-opacity:1;border-color:#744210;border-color:rgba(116,66,16,var(--border-opacity))}.md\:border-green-100{--border-opacity:1;border-color:#f0fff4;border-color:rgba(240,255,244,var(--border-opacity))}.md\:border-green-200{--border-opacity:1;border-color:#c6f6d5;border-color:rgba(198,246,213,var(--border-opacity))}.md\:border-green-300{--border-opacity:1;border-color:#9ae6b4;border-color:rgba(154,230,180,var(--border-opacity))}.md\:border-green-400{--border-opacity:1;border-color:#68d391;border-color:rgba(104,211,145,var(--border-opacity))}.md\:border-green-500{--border-opacity:1;border-color:#48bb78;border-color:rgba(72,187,120,var(--border-opacity))}.md\:border-green-600{--border-opacity:1;border-color:#38a169;border-color:rgba(56,161,105,var(--border-opacity))}.md\:border-green-700{--border-opacity:1;border-color:#2f855a;border-color:rgba(47,133,90,var(--border-opacity))}.md\:border-green-800{--border-opacity:1;border-color:#276749;border-color:rgba(39,103,73,var(--border-opacity))}.md\:border-green-900{--border-opacity:1;border-color:#22543d;border-color:rgba(34,84,61,var(--border-opacity))}.md\:border-teal-100{--border-opacity:1;border-color:#e6fffa;border-color:rgba(230,255,250,var(--border-opacity))}.md\:border-teal-200{--border-opacity:1;border-color:#b2f5ea;border-color:rgba(178,245,234,var(--border-opacity))}.md\:border-teal-300{--border-opacity:1;border-color:#81e6d9;border-color:rgba(129,230,217,var(--border-opacity))}.md\:border-teal-400{--border-opacity:1;border-color:#4fd1c5;border-color:rgba(79,209,197,var(--border-opacity))}.md\:border-teal-500{--border-opacity:1;border-color:#38b2ac;border-color:rgba(56,178,172,var(--border-opacity))}.md\:border-teal-600{--border-opacity:1;border-color:#319795;border-color:rgba(49,151,149,var(--border-opacity))}.md\:border-teal-700{--border-opacity:1;border-color:#2c7a7b;border-color:rgba(44,122,123,var(--border-opacity))}.md\:border-teal-800{--border-opacity:1;border-color:#285e61;border-color:rgba(40,94,97,var(--border-opacity))}.md\:border-teal-900{--border-opacity:1;border-color:#234e52;border-color:rgba(35,78,82,var(--border-opacity))}.md\:border-blue-100{--border-opacity:1;border-color:#ebf8ff;border-color:rgba(235,248,255,var(--border-opacity))}.md\:border-blue-200{--border-opacity:1;border-color:#bee3f8;border-color:rgba(190,227,248,var(--border-opacity))}.md\:border-blue-300{--border-opacity:1;border-color:#90cdf4;border-color:rgba(144,205,244,var(--border-opacity))}.md\:border-blue-400{--border-opacity:1;border-color:#63b3ed;border-color:rgba(99,179,237,var(--border-opacity))}.md\:border-blue-500{--border-opacity:1;border-color:#4299e1;border-color:rgba(66,153,225,var(--border-opacity))}.md\:border-blue-600{--border-opacity:1;border-color:#3182ce;border-color:rgba(49,130,206,var(--border-opacity))}.md\:border-blue-700{--border-opacity:1;border-color:#2b6cb0;border-color:rgba(43,108,176,var(--border-opacity))}.md\:border-blue-800{--border-opacity:1;border-color:#2c5282;border-color:rgba(44,82,130,var(--border-opacity))}.md\:border-blue-900{--border-opacity:1;border-color:#2a4365;border-color:rgba(42,67,101,var(--border-opacity))}.md\:border-indigo-100{--border-opacity:1;border-color:#ebf4ff;border-color:rgba(235,244,255,var(--border-opacity))}.md\:border-indigo-200{--border-opacity:1;border-color:#c3dafe;border-color:rgba(195,218,254,var(--border-opacity))}.md\:border-indigo-300{--border-opacity:1;border-color:#a3bffa;border-color:rgba(163,191,250,var(--border-opacity))}.md\:border-indigo-400{--border-opacity:1;border-color:#7f9cf5;border-color:rgba(127,156,245,var(--border-opacity))}.md\:border-indigo-500{--border-opacity:1;border-color:#667eea;border-color:rgba(102,126,234,var(--border-opacity))}.md\:border-indigo-600{--border-opacity:1;border-color:#5a67d8;border-color:rgba(90,103,216,var(--border-opacity))}.md\:border-indigo-700{--border-opacity:1;border-color:#4c51bf;border-color:rgba(76,81,191,var(--border-opacity))}.md\:border-indigo-800{--border-opacity:1;border-color:#434190;border-color:rgba(67,65,144,var(--border-opacity))}.md\:border-indigo-900{--border-opacity:1;border-color:#3c366b;border-color:rgba(60,54,107,var(--border-opacity))}.md\:border-purple-100{--border-opacity:1;border-color:#faf5ff;border-color:rgba(250,245,255,var(--border-opacity))}.md\:border-purple-200{--border-opacity:1;border-color:#e9d8fd;border-color:rgba(233,216,253,var(--border-opacity))}.md\:border-purple-300{--border-opacity:1;border-color:#d6bcfa;border-color:rgba(214,188,250,var(--border-opacity))}.md\:border-purple-400{--border-opacity:1;border-color:#b794f4;border-color:rgba(183,148,244,var(--border-opacity))}.md\:border-purple-500{--border-opacity:1;border-color:#9f7aea;border-color:rgba(159,122,234,var(--border-opacity))}.md\:border-purple-600{--border-opacity:1;border-color:#805ad5;border-color:rgba(128,90,213,var(--border-opacity))}.md\:border-purple-700{--border-opacity:1;border-color:#6b46c1;border-color:rgba(107,70,193,var(--border-opacity))}.md\:border-purple-800{--border-opacity:1;border-color:#553c9a;border-color:rgba(85,60,154,var(--border-opacity))}.md\:border-purple-900{--border-opacity:1;border-color:#44337a;border-color:rgba(68,51,122,var(--border-opacity))}.md\:border-pink-100{--border-opacity:1;border-color:#fff5f7;border-color:rgba(255,245,247,var(--border-opacity))}.md\:border-pink-200{--border-opacity:1;border-color:#fed7e2;border-color:rgba(254,215,226,var(--border-opacity))}.md\:border-pink-300{--border-opacity:1;border-color:#fbb6ce;border-color:rgba(251,182,206,var(--border-opacity))}.md\:border-pink-400{--border-opacity:1;border-color:#f687b3;border-color:rgba(246,135,179,var(--border-opacity))}.md\:border-pink-500{--border-opacity:1;border-color:#ed64a6;border-color:rgba(237,100,166,var(--border-opacity))}.md\:border-pink-600{--border-opacity:1;border-color:#d53f8c;border-color:rgba(213,63,140,var(--border-opacity))}.md\:border-pink-700{--border-opacity:1;border-color:#b83280;border-color:rgba(184,50,128,var(--border-opacity))}.md\:border-pink-800{--border-opacity:1;border-color:#97266d;border-color:rgba(151,38,109,var(--border-opacity))}.md\:border-pink-900{--border-opacity:1;border-color:#702459;border-color:rgba(112,36,89,var(--border-opacity))}.md\:hover\:border-transparent:hover{border-color:transparent}.md\:hover\:border-current:hover{border-color:currentColor}.md\:hover\:border-black:hover{--border-opacity:1;border-color:#000;border-color:rgba(0,0,0,var(--border-opacity))}.md\:hover\:border-white:hover{--border-opacity:1;border-color:#fff;border-color:rgba(255,255,255,var(--border-opacity))}.md\:hover\:border-gray-100:hover{--border-opacity:1;border-color:#f7fafc;border-color:rgba(247,250,252,var(--border-opacity))}.md\:hover\:border-gray-200:hover{--border-opacity:1;border-color:#edf2f7;border-color:rgba(237,242,247,var(--border-opacity))}.md\:hover\:border-gray-300:hover{--border-opacity:1;border-color:#e2e8f0;border-color:rgba(226,232,240,var(--border-opacity))}.md\:hover\:border-gray-400:hover{--border-opacity:1;border-color:#cbd5e0;border-color:rgba(203,213,224,var(--border-opacity))}.md\:hover\:border-gray-500:hover{--border-opacity:1;border-color:#a0aec0;border-color:rgba(160,174,192,var(--border-opacity))}.md\:hover\:border-gray-600:hover{--border-opacity:1;border-color:#718096;border-color:rgba(113,128,150,var(--border-opacity))}.md\:hover\:border-gray-700:hover{--border-opacity:1;border-color:#4a5568;border-color:rgba(74,85,104,var(--border-opacity))}.md\:hover\:border-gray-800:hover{--border-opacity:1;border-color:#2d3748;border-color:rgba(45,55,72,var(--border-opacity))}.md\:hover\:border-gray-900:hover{--border-opacity:1;border-color:#1a202c;border-color:rgba(26,32,44,var(--border-opacity))}.md\:hover\:border-red-100:hover{--border-opacity:1;border-color:#fff5f5;border-color:rgba(255,245,245,var(--border-opacity))}.md\:hover\:border-red-200:hover{--border-opacity:1;border-color:#fed7d7;border-color:rgba(254,215,215,var(--border-opacity))}.md\:hover\:border-red-300:hover{--border-opacity:1;border-color:#feb2b2;border-color:rgba(254,178,178,var(--border-opacity))}.md\:hover\:border-red-400:hover{--border-opacity:1;border-color:#fc8181;border-color:rgba(252,129,129,var(--border-opacity))}.md\:hover\:border-red-500:hover{--border-opacity:1;border-color:#f56565;border-color:rgba(245,101,101,var(--border-opacity))}.md\:hover\:border-red-600:hover{--border-opacity:1;border-color:#e53e3e;border-color:rgba(229,62,62,var(--border-opacity))}.md\:hover\:border-red-700:hover{--border-opacity:1;border-color:#c53030;border-color:rgba(197,48,48,var(--border-opacity))}.md\:hover\:border-red-800:hover{--border-opacity:1;border-color:#9b2c2c;border-color:rgba(155,44,44,var(--border-opacity))}.md\:hover\:border-red-900:hover{--border-opacity:1;border-color:#742a2a;border-color:rgba(116,42,42,var(--border-opacity))}.md\:hover\:border-orange-100:hover{--border-opacity:1;border-color:#fffaf0;border-color:rgba(255,250,240,var(--border-opacity))}.md\:hover\:border-orange-200:hover{--border-opacity:1;border-color:#feebc8;border-color:rgba(254,235,200,var(--border-opacity))}.md\:hover\:border-orange-300:hover{--border-opacity:1;border-color:#fbd38d;border-color:rgba(251,211,141,var(--border-opacity))}.md\:hover\:border-orange-400:hover{--border-opacity:1;border-color:#f6ad55;border-color:rgba(246,173,85,var(--border-opacity))}.md\:hover\:border-orange-500:hover{--border-opacity:1;border-color:#ed8936;border-color:rgba(237,137,54,var(--border-opacity))}.md\:hover\:border-orange-600:hover{--border-opacity:1;border-color:#dd6b20;border-color:rgba(221,107,32,var(--border-opacity))}.md\:hover\:border-orange-700:hover{--border-opacity:1;border-color:#c05621;border-color:rgba(192,86,33,var(--border-opacity))}.md\:hover\:border-orange-800:hover{--border-opacity:1;border-color:#9c4221;border-color:rgba(156,66,33,var(--border-opacity))}.md\:hover\:border-orange-900:hover{--border-opacity:1;border-color:#7b341e;border-color:rgba(123,52,30,var(--border-opacity))}.md\:hover\:border-yellow-100:hover{--border-opacity:1;border-color:ivory;border-color:rgba(255,255,240,var(--border-opacity))}.md\:hover\:border-yellow-200:hover{--border-opacity:1;border-color:#fefcbf;border-color:rgba(254,252,191,var(--border-opacity))}.md\:hover\:border-yellow-300:hover{--border-opacity:1;border-color:#faf089;border-color:rgba(250,240,137,var(--border-opacity))}.md\:hover\:border-yellow-400:hover{--border-opacity:1;border-color:#f6e05e;border-color:rgba(246,224,94,var(--border-opacity))}.md\:hover\:border-yellow-500:hover{--border-opacity:1;border-color:#ecc94b;border-color:rgba(236,201,75,var(--border-opacity))}.md\:hover\:border-yellow-600:hover{--border-opacity:1;border-color:#d69e2e;border-color:rgba(214,158,46,var(--border-opacity))}.md\:hover\:border-yellow-700:hover{--border-opacity:1;border-color:#b7791f;border-color:rgba(183,121,31,var(--border-opacity))}.md\:hover\:border-yellow-800:hover{--border-opacity:1;border-color:#975a16;border-color:rgba(151,90,22,var(--border-opacity))}.md\:hover\:border-yellow-900:hover{--border-opacity:1;border-color:#744210;border-color:rgba(116,66,16,var(--border-opacity))}.md\:hover\:border-green-100:hover{--border-opacity:1;border-color:#f0fff4;border-color:rgba(240,255,244,var(--border-opacity))}.md\:hover\:border-green-200:hover{--border-opacity:1;border-color:#c6f6d5;border-color:rgba(198,246,213,var(--border-opacity))}.md\:hover\:border-green-300:hover{--border-opacity:1;border-color:#9ae6b4;border-color:rgba(154,230,180,var(--border-opacity))}.md\:hover\:border-green-400:hover{--border-opacity:1;border-color:#68d391;border-color:rgba(104,211,145,var(--border-opacity))}.md\:hover\:border-green-500:hover{--border-opacity:1;border-color:#48bb78;border-color:rgba(72,187,120,var(--border-opacity))}.md\:hover\:border-green-600:hover{--border-opacity:1;border-color:#38a169;border-color:rgba(56,161,105,var(--border-opacity))}.md\:hover\:border-green-700:hover{--border-opacity:1;border-color:#2f855a;border-color:rgba(47,133,90,var(--border-opacity))}.md\:hover\:border-green-800:hover{--border-opacity:1;border-color:#276749;border-color:rgba(39,103,73,var(--border-opacity))}.md\:hover\:border-green-900:hover{--border-opacity:1;border-color:#22543d;border-color:rgba(34,84,61,var(--border-opacity))}.md\:hover\:border-teal-100:hover{--border-opacity:1;border-color:#e6fffa;border-color:rgba(230,255,250,var(--border-opacity))}.md\:hover\:border-teal-200:hover{--border-opacity:1;border-color:#b2f5ea;border-color:rgba(178,245,234,var(--border-opacity))}.md\:hover\:border-teal-300:hover{--border-opacity:1;border-color:#81e6d9;border-color:rgba(129,230,217,var(--border-opacity))}.md\:hover\:border-teal-400:hover{--border-opacity:1;border-color:#4fd1c5;border-color:rgba(79,209,197,var(--border-opacity))}.md\:hover\:border-teal-500:hover{--border-opacity:1;border-color:#38b2ac;border-color:rgba(56,178,172,var(--border-opacity))}.md\:hover\:border-teal-600:hover{--border-opacity:1;border-color:#319795;border-color:rgba(49,151,149,var(--border-opacity))}.md\:hover\:border-teal-700:hover{--border-opacity:1;border-color:#2c7a7b;border-color:rgba(44,122,123,var(--border-opacity))}.md\:hover\:border-teal-800:hover{--border-opacity:1;border-color:#285e61;border-color:rgba(40,94,97,var(--border-opacity))}.md\:hover\:border-teal-900:hover{--border-opacity:1;border-color:#234e52;border-color:rgba(35,78,82,var(--border-opacity))}.md\:hover\:border-blue-100:hover{--border-opacity:1;border-color:#ebf8ff;border-color:rgba(235,248,255,var(--border-opacity))}.md\:hover\:border-blue-200:hover{--border-opacity:1;border-color:#bee3f8;border-color:rgba(190,227,248,var(--border-opacity))}.md\:hover\:border-blue-300:hover{--border-opacity:1;border-color:#90cdf4;border-color:rgba(144,205,244,var(--border-opacity))}.md\:hover\:border-blue-400:hover{--border-opacity:1;border-color:#63b3ed;border-color:rgba(99,179,237,var(--border-opacity))}.md\:hover\:border-blue-500:hover{--border-opacity:1;border-color:#4299e1;border-color:rgba(66,153,225,var(--border-opacity))}.md\:hover\:border-blue-600:hover{--border-opacity:1;border-color:#3182ce;border-color:rgba(49,130,206,var(--border-opacity))}.md\:hover\:border-blue-700:hover{--border-opacity:1;border-color:#2b6cb0;border-color:rgba(43,108,176,var(--border-opacity))}.md\:hover\:border-blue-800:hover{--border-opacity:1;border-color:#2c5282;border-color:rgba(44,82,130,var(--border-opacity))}.md\:hover\:border-blue-900:hover{--border-opacity:1;border-color:#2a4365;border-color:rgba(42,67,101,var(--border-opacity))}.md\:hover\:border-indigo-100:hover{--border-opacity:1;border-color:#ebf4ff;border-color:rgba(235,244,255,var(--border-opacity))}.md\:hover\:border-indigo-200:hover{--border-opacity:1;border-color:#c3dafe;border-color:rgba(195,218,254,var(--border-opacity))}.md\:hover\:border-indigo-300:hover{--border-opacity:1;border-color:#a3bffa;border-color:rgba(163,191,250,var(--border-opacity))}.md\:hover\:border-indigo-400:hover{--border-opacity:1;border-color:#7f9cf5;border-color:rgba(127,156,245,var(--border-opacity))}.md\:hover\:border-indigo-500:hover{--border-opacity:1;border-color:#667eea;border-color:rgba(102,126,234,var(--border-opacity))}.md\:hover\:border-indigo-600:hover{--border-opacity:1;border-color:#5a67d8;border-color:rgba(90,103,216,var(--border-opacity))}.md\:hover\:border-indigo-700:hover{--border-opacity:1;border-color:#4c51bf;border-color:rgba(76,81,191,var(--border-opacity))}.md\:hover\:border-indigo-800:hover{--border-opacity:1;border-color:#434190;border-color:rgba(67,65,144,var(--border-opacity))}.md\:hover\:border-indigo-900:hover{--border-opacity:1;border-color:#3c366b;border-color:rgba(60,54,107,var(--border-opacity))}.md\:hover\:border-purple-100:hover{--border-opacity:1;border-color:#faf5ff;border-color:rgba(250,245,255,var(--border-opacity))}.md\:hover\:border-purple-200:hover{--border-opacity:1;border-color:#e9d8fd;border-color:rgba(233,216,253,var(--border-opacity))}.md\:hover\:border-purple-300:hover{--border-opacity:1;border-color:#d6bcfa;border-color:rgba(214,188,250,var(--border-opacity))}.md\:hover\:border-purple-400:hover{--border-opacity:1;border-color:#b794f4;border-color:rgba(183,148,244,var(--border-opacity))}.md\:hover\:border-purple-500:hover{--border-opacity:1;border-color:#9f7aea;border-color:rgba(159,122,234,var(--border-opacity))}.md\:hover\:border-purple-600:hover{--border-opacity:1;border-color:#805ad5;border-color:rgba(128,90,213,var(--border-opacity))}.md\:hover\:border-purple-700:hover{--border-opacity:1;border-color:#6b46c1;border-color:rgba(107,70,193,var(--border-opacity))}.md\:hover\:border-purple-800:hover{--border-opacity:1;border-color:#553c9a;border-color:rgba(85,60,154,var(--border-opacity))}.md\:hover\:border-purple-900:hover{--border-opacity:1;border-color:#44337a;border-color:rgba(68,51,122,var(--border-opacity))}.md\:hover\:border-pink-100:hover{--border-opacity:1;border-color:#fff5f7;border-color:rgba(255,245,247,var(--border-opacity))}.md\:hover\:border-pink-200:hover{--border-opacity:1;border-color:#fed7e2;border-color:rgba(254,215,226,var(--border-opacity))}.md\:hover\:border-pink-300:hover{--border-opacity:1;border-color:#fbb6ce;border-color:rgba(251,182,206,var(--border-opacity))}.md\:hover\:border-pink-400:hover{--border-opacity:1;border-color:#f687b3;border-color:rgba(246,135,179,var(--border-opacity))}.md\:hover\:border-pink-500:hover{--border-opacity:1;border-color:#ed64a6;border-color:rgba(237,100,166,var(--border-opacity))}.md\:hover\:border-pink-600:hover{--border-opacity:1;border-color:#d53f8c;border-color:rgba(213,63,140,var(--border-opacity))}.md\:hover\:border-pink-700:hover{--border-opacity:1;border-color:#b83280;border-color:rgba(184,50,128,var(--border-opacity))}.md\:hover\:border-pink-800:hover{--border-opacity:1;border-color:#97266d;border-color:rgba(151,38,109,var(--border-opacity))}.md\:hover\:border-pink-900:hover{--border-opacity:1;border-color:#702459;border-color:rgba(112,36,89,var(--border-opacity))}.md\:focus\:border-transparent:focus{border-color:transparent}.md\:focus\:border-current:focus{border-color:currentColor}.md\:focus\:border-black:focus{--border-opacity:1;border-color:#000;border-color:rgba(0,0,0,var(--border-opacity))}.md\:focus\:border-white:focus{--border-opacity:1;border-color:#fff;border-color:rgba(255,255,255,var(--border-opacity))}.md\:focus\:border-gray-100:focus{--border-opacity:1;border-color:#f7fafc;border-color:rgba(247,250,252,var(--border-opacity))}.md\:focus\:border-gray-200:focus{--border-opacity:1;border-color:#edf2f7;border-color:rgba(237,242,247,var(--border-opacity))}.md\:focus\:border-gray-300:focus{--border-opacity:1;border-color:#e2e8f0;border-color:rgba(226,232,240,var(--border-opacity))}.md\:focus\:border-gray-400:focus{--border-opacity:1;border-color:#cbd5e0;border-color:rgba(203,213,224,var(--border-opacity))}.md\:focus\:border-gray-500:focus{--border-opacity:1;border-color:#a0aec0;border-color:rgba(160,174,192,var(--border-opacity))}.md\:focus\:border-gray-600:focus{--border-opacity:1;border-color:#718096;border-color:rgba(113,128,150,var(--border-opacity))}.md\:focus\:border-gray-700:focus{--border-opacity:1;border-color:#4a5568;border-color:rgba(74,85,104,var(--border-opacity))}.md\:focus\:border-gray-800:focus{--border-opacity:1;border-color:#2d3748;border-color:rgba(45,55,72,var(--border-opacity))}.md\:focus\:border-gray-900:focus{--border-opacity:1;border-color:#1a202c;border-color:rgba(26,32,44,var(--border-opacity))}.md\:focus\:border-red-100:focus{--border-opacity:1;border-color:#fff5f5;border-color:rgba(255,245,245,var(--border-opacity))}.md\:focus\:border-red-200:focus{--border-opacity:1;border-color:#fed7d7;border-color:rgba(254,215,215,var(--border-opacity))}.md\:focus\:border-red-300:focus{--border-opacity:1;border-color:#feb2b2;border-color:rgba(254,178,178,var(--border-opacity))}.md\:focus\:border-red-400:focus{--border-opacity:1;border-color:#fc8181;border-color:rgba(252,129,129,var(--border-opacity))}.md\:focus\:border-red-500:focus{--border-opacity:1;border-color:#f56565;border-color:rgba(245,101,101,var(--border-opacity))}.md\:focus\:border-red-600:focus{--border-opacity:1;border-color:#e53e3e;border-color:rgba(229,62,62,var(--border-opacity))}.md\:focus\:border-red-700:focus{--border-opacity:1;border-color:#c53030;border-color:rgba(197,48,48,var(--border-opacity))}.md\:focus\:border-red-800:focus{--border-opacity:1;border-color:#9b2c2c;border-color:rgba(155,44,44,var(--border-opacity))}.md\:focus\:border-red-900:focus{--border-opacity:1;border-color:#742a2a;border-color:rgba(116,42,42,var(--border-opacity))}.md\:focus\:border-orange-100:focus{--border-opacity:1;border-color:#fffaf0;border-color:rgba(255,250,240,var(--border-opacity))}.md\:focus\:border-orange-200:focus{--border-opacity:1;border-color:#feebc8;border-color:rgba(254,235,200,var(--border-opacity))}.md\:focus\:border-orange-300:focus{--border-opacity:1;border-color:#fbd38d;border-color:rgba(251,211,141,var(--border-opacity))}.md\:focus\:border-orange-400:focus{--border-opacity:1;border-color:#f6ad55;border-color:rgba(246,173,85,var(--border-opacity))}.md\:focus\:border-orange-500:focus{--border-opacity:1;border-color:#ed8936;border-color:rgba(237,137,54,var(--border-opacity))}.md\:focus\:border-orange-600:focus{--border-opacity:1;border-color:#dd6b20;border-color:rgba(221,107,32,var(--border-opacity))}.md\:focus\:border-orange-700:focus{--border-opacity:1;border-color:#c05621;border-color:rgba(192,86,33,var(--border-opacity))}.md\:focus\:border-orange-800:focus{--border-opacity:1;border-color:#9c4221;border-color:rgba(156,66,33,var(--border-opacity))}.md\:focus\:border-orange-900:focus{--border-opacity:1;border-color:#7b341e;border-color:rgba(123,52,30,var(--border-opacity))}.md\:focus\:border-yellow-100:focus{--border-opacity:1;border-color:ivory;border-color:rgba(255,255,240,var(--border-opacity))}.md\:focus\:border-yellow-200:focus{--border-opacity:1;border-color:#fefcbf;border-color:rgba(254,252,191,var(--border-opacity))}.md\:focus\:border-yellow-300:focus{--border-opacity:1;border-color:#faf089;border-color:rgba(250,240,137,var(--border-opacity))}.md\:focus\:border-yellow-400:focus{--border-opacity:1;border-color:#f6e05e;border-color:rgba(246,224,94,var(--border-opacity))}.md\:focus\:border-yellow-500:focus{--border-opacity:1;border-color:#ecc94b;border-color:rgba(236,201,75,var(--border-opacity))}.md\:focus\:border-yellow-600:focus{--border-opacity:1;border-color:#d69e2e;border-color:rgba(214,158,46,var(--border-opacity))}.md\:focus\:border-yellow-700:focus{--border-opacity:1;border-color:#b7791f;border-color:rgba(183,121,31,var(--border-opacity))}.md\:focus\:border-yellow-800:focus{--border-opacity:1;border-color:#975a16;border-color:rgba(151,90,22,var(--border-opacity))}.md\:focus\:border-yellow-900:focus{--border-opacity:1;border-color:#744210;border-color:rgba(116,66,16,var(--border-opacity))}.md\:focus\:border-green-100:focus{--border-opacity:1;border-color:#f0fff4;border-color:rgba(240,255,244,var(--border-opacity))}.md\:focus\:border-green-200:focus{--border-opacity:1;border-color:#c6f6d5;border-color:rgba(198,246,213,var(--border-opacity))}.md\:focus\:border-green-300:focus{--border-opacity:1;border-color:#9ae6b4;border-color:rgba(154,230,180,var(--border-opacity))}.md\:focus\:border-green-400:focus{--border-opacity:1;border-color:#68d391;border-color:rgba(104,211,145,var(--border-opacity))}.md\:focus\:border-green-500:focus{--border-opacity:1;border-color:#48bb78;border-color:rgba(72,187,120,var(--border-opacity))}.md\:focus\:border-green-600:focus{--border-opacity:1;border-color:#38a169;border-color:rgba(56,161,105,var(--border-opacity))}.md\:focus\:border-green-700:focus{--border-opacity:1;border-color:#2f855a;border-color:rgba(47,133,90,var(--border-opacity))}.md\:focus\:border-green-800:focus{--border-opacity:1;border-color:#276749;border-color:rgba(39,103,73,var(--border-opacity))}.md\:focus\:border-green-900:focus{--border-opacity:1;border-color:#22543d;border-color:rgba(34,84,61,var(--border-opacity))}.md\:focus\:border-teal-100:focus{--border-opacity:1;border-color:#e6fffa;border-color:rgba(230,255,250,var(--border-opacity))}.md\:focus\:border-teal-200:focus{--border-opacity:1;border-color:#b2f5ea;border-color:rgba(178,245,234,var(--border-opacity))}.md\:focus\:border-teal-300:focus{--border-opacity:1;border-color:#81e6d9;border-color:rgba(129,230,217,var(--border-opacity))}.md\:focus\:border-teal-400:focus{--border-opacity:1;border-color:#4fd1c5;border-color:rgba(79,209,197,var(--border-opacity))}.md\:focus\:border-teal-500:focus{--border-opacity:1;border-color:#38b2ac;border-color:rgba(56,178,172,var(--border-opacity))}.md\:focus\:border-teal-600:focus{--border-opacity:1;border-color:#319795;border-color:rgba(49,151,149,var(--border-opacity))}.md\:focus\:border-teal-700:focus{--border-opacity:1;border-color:#2c7a7b;border-color:rgba(44,122,123,var(--border-opacity))}.md\:focus\:border-teal-800:focus{--border-opacity:1;border-color:#285e61;border-color:rgba(40,94,97,var(--border-opacity))}.md\:focus\:border-teal-900:focus{--border-opacity:1;border-color:#234e52;border-color:rgba(35,78,82,var(--border-opacity))}.md\:focus\:border-blue-100:focus{--border-opacity:1;border-color:#ebf8ff;border-color:rgba(235,248,255,var(--border-opacity))}.md\:focus\:border-blue-200:focus{--border-opacity:1;border-color:#bee3f8;border-color:rgba(190,227,248,var(--border-opacity))}.md\:focus\:border-blue-300:focus{--border-opacity:1;border-color:#90cdf4;border-color:rgba(144,205,244,var(--border-opacity))}.md\:focus\:border-blue-400:focus{--border-opacity:1;border-color:#63b3ed;border-color:rgba(99,179,237,var(--border-opacity))}.md\:focus\:border-blue-500:focus{--border-opacity:1;border-color:#4299e1;border-color:rgba(66,153,225,var(--border-opacity))}.md\:focus\:border-blue-600:focus{--border-opacity:1;border-color:#3182ce;border-color:rgba(49,130,206,var(--border-opacity))}.md\:focus\:border-blue-700:focus{--border-opacity:1;border-color:#2b6cb0;border-color:rgba(43,108,176,var(--border-opacity))}.md\:focus\:border-blue-800:focus{--border-opacity:1;border-color:#2c5282;border-color:rgba(44,82,130,var(--border-opacity))}.md\:focus\:border-blue-900:focus{--border-opacity:1;border-color:#2a4365;border-color:rgba(42,67,101,var(--border-opacity))}.md\:focus\:border-indigo-100:focus{--border-opacity:1;border-color:#ebf4ff;border-color:rgba(235,244,255,var(--border-opacity))}.md\:focus\:border-indigo-200:focus{--border-opacity:1;border-color:#c3dafe;border-color:rgba(195,218,254,var(--border-opacity))}.md\:focus\:border-indigo-300:focus{--border-opacity:1;border-color:#a3bffa;border-color:rgba(163,191,250,var(--border-opacity))}.md\:focus\:border-indigo-400:focus{--border-opacity:1;border-color:#7f9cf5;border-color:rgba(127,156,245,var(--border-opacity))}.md\:focus\:border-indigo-500:focus{--border-opacity:1;border-color:#667eea;border-color:rgba(102,126,234,var(--border-opacity))}.md\:focus\:border-indigo-600:focus{--border-opacity:1;border-color:#5a67d8;border-color:rgba(90,103,216,var(--border-opacity))}.md\:focus\:border-indigo-700:focus{--border-opacity:1;border-color:#4c51bf;border-color:rgba(76,81,191,var(--border-opacity))}.md\:focus\:border-indigo-800:focus{--border-opacity:1;border-color:#434190;border-color:rgba(67,65,144,var(--border-opacity))}.md\:focus\:border-indigo-900:focus{--border-opacity:1;border-color:#3c366b;border-color:rgba(60,54,107,var(--border-opacity))}.md\:focus\:border-purple-100:focus{--border-opacity:1;border-color:#faf5ff;border-color:rgba(250,245,255,var(--border-opacity))}.md\:focus\:border-purple-200:focus{--border-opacity:1;border-color:#e9d8fd;border-color:rgba(233,216,253,var(--border-opacity))}.md\:focus\:border-purple-300:focus{--border-opacity:1;border-color:#d6bcfa;border-color:rgba(214,188,250,var(--border-opacity))}.md\:focus\:border-purple-400:focus{--border-opacity:1;border-color:#b794f4;border-color:rgba(183,148,244,var(--border-opacity))}.md\:focus\:border-purple-500:focus{--border-opacity:1;border-color:#9f7aea;border-color:rgba(159,122,234,var(--border-opacity))}.md\:focus\:border-purple-600:focus{--border-opacity:1;border-color:#805ad5;border-color:rgba(128,90,213,var(--border-opacity))}.md\:focus\:border-purple-700:focus{--border-opacity:1;border-color:#6b46c1;border-color:rgba(107,70,193,var(--border-opacity))}.md\:focus\:border-purple-800:focus{--border-opacity:1;border-color:#553c9a;border-color:rgba(85,60,154,var(--border-opacity))}.md\:focus\:border-purple-900:focus{--border-opacity:1;border-color:#44337a;border-color:rgba(68,51,122,var(--border-opacity))}.md\:focus\:border-pink-100:focus{--border-opacity:1;border-color:#fff5f7;border-color:rgba(255,245,247,var(--border-opacity))}.md\:focus\:border-pink-200:focus{--border-opacity:1;border-color:#fed7e2;border-color:rgba(254,215,226,var(--border-opacity))}.md\:focus\:border-pink-300:focus{--border-opacity:1;border-color:#fbb6ce;border-color:rgba(251,182,206,var(--border-opacity))}.md\:focus\:border-pink-400:focus{--border-opacity:1;border-color:#f687b3;border-color:rgba(246,135,179,var(--border-opacity))}.md\:focus\:border-pink-500:focus{--border-opacity:1;border-color:#ed64a6;border-color:rgba(237,100,166,var(--border-opacity))}.md\:focus\:border-pink-600:focus{--border-opacity:1;border-color:#d53f8c;border-color:rgba(213,63,140,var(--border-opacity))}.md\:focus\:border-pink-700:focus{--border-opacity:1;border-color:#b83280;border-color:rgba(184,50,128,var(--border-opacity))}.md\:focus\:border-pink-800:focus{--border-opacity:1;border-color:#97266d;border-color:rgba(151,38,109,var(--border-opacity))}.md\:focus\:border-pink-900:focus{--border-opacity:1;border-color:#702459;border-color:rgba(112,36,89,var(--border-opacity))}.md\:border-opacity-0{--border-opacity:0}.md\:border-opacity-25{--border-opacity:0.25}.md\:border-opacity-50{--border-opacity:0.5}.md\:border-opacity-75{--border-opacity:0.75}.md\:border-opacity-100{--border-opacity:1}.md\:hover\:border-opacity-0:hover{--border-opacity:0}.md\:hover\:border-opacity-25:hover{--border-opacity:0.25}.md\:hover\:border-opacity-50:hover{--border-opacity:0.5}.md\:hover\:border-opacity-75:hover{--border-opacity:0.75}.md\:hover\:border-opacity-100:hover{--border-opacity:1}.md\:focus\:border-opacity-0:focus{--border-opacity:0}.md\:focus\:border-opacity-25:focus{--border-opacity:0.25}.md\:focus\:border-opacity-50:focus{--border-opacity:0.5}.md\:focus\:border-opacity-75:focus{--border-opacity:0.75}.md\:focus\:border-opacity-100:focus{--border-opacity:1}.md\:rounded-none{border-radius:0}.md\:rounded-sm{border-radius:.125rem}.md\:rounded{border-radius:.25rem}.md\:rounded-md{border-radius:.375rem}.md\:rounded-lg{border-radius:.5rem}.md\:rounded-xl{border-radius:.75rem}.md\:rounded-2xl{border-radius:1rem}.md\:rounded-3xl{border-radius:1.5rem}.md\:rounded-full{border-radius:9999px}.md\:rounded-t-none{border-top-left-radius:0;border-top-right-radius:0}.md\:rounded-r-none{border-top-right-radius:0;border-bottom-right-radius:0}.md\:rounded-b-none{border-bottom-right-radius:0;border-bottom-left-radius:0}.md\:rounded-l-none{border-top-left-radius:0;border-bottom-left-radius:0}.md\:rounded-t-sm{border-top-left-radius:.125rem;border-top-right-radius:.125rem}.md\:rounded-r-sm{border-top-right-radius:.125rem;border-bottom-right-radius:.125rem}.md\:rounded-b-sm{border-bottom-right-radius:.125rem;border-bottom-left-radius:.125rem}.md\:rounded-l-sm{border-top-left-radius:.125rem;border-bottom-left-radius:.125rem}.md\:rounded-t{border-top-left-radius:.25rem;border-top-right-radius:.25rem}.md\:rounded-r{border-top-right-radius:.25rem;border-bottom-right-radius:.25rem}.md\:rounded-b{border-bottom-right-radius:.25rem;border-bottom-left-radius:.25rem}.md\:rounded-l{border-top-left-radius:.25rem;border-bottom-left-radius:.25rem}.md\:rounded-t-md{border-top-left-radius:.375rem;border-top-right-radius:.375rem}.md\:rounded-r-md{border-top-right-radius:.375rem;border-bottom-right-radius:.375rem}.md\:rounded-b-md{border-bottom-right-radius:.375rem;border-bottom-left-radius:.375rem}.md\:rounded-l-md{border-top-left-radius:.375rem;border-bottom-left-radius:.375rem}.md\:rounded-t-lg{border-top-left-radius:.5rem;border-top-right-radius:.5rem}.md\:rounded-r-lg{border-top-right-radius:.5rem;border-bottom-right-radius:.5rem}.md\:rounded-b-lg{border-bottom-right-radius:.5rem;border-bottom-left-radius:.5rem}.md\:rounded-l-lg{border-top-left-radius:.5rem;border-bottom-left-radius:.5rem}.md\:rounded-t-xl{border-top-left-radius:.75rem;border-top-right-radius:.75rem}.md\:rounded-r-xl{border-top-right-radius:.75rem;border-bottom-right-radius:.75rem}.md\:rounded-b-xl{border-bottom-right-radius:.75rem;border-bottom-left-radius:.75rem}.md\:rounded-l-xl{border-top-left-radius:.75rem;border-bottom-left-radius:.75rem}.md\:rounded-t-2xl{border-top-left-radius:1rem;border-top-right-radius:1rem}.md\:rounded-r-2xl{border-top-right-radius:1rem;border-bottom-right-radius:1rem}.md\:rounded-b-2xl{border-bottom-right-radius:1rem;border-bottom-left-radius:1rem}.md\:rounded-l-2xl{border-top-left-radius:1rem;border-bottom-left-radius:1rem}.md\:rounded-t-3xl{border-top-left-radius:1.5rem;border-top-right-radius:1.5rem}.md\:rounded-r-3xl{border-top-right-radius:1.5rem;border-bottom-right-radius:1.5rem}.md\:rounded-b-3xl{border-bottom-right-radius:1.5rem;border-bottom-left-radius:1.5rem}.md\:rounded-l-3xl{border-top-left-radius:1.5rem;border-bottom-left-radius:1.5rem}.md\:rounded-t-full{border-top-left-radius:9999px;border-top-right-radius:9999px}.md\:rounded-r-full{border-top-right-radius:9999px;border-bottom-right-radius:9999px}.md\:rounded-b-full{border-bottom-right-radius:9999px;border-bottom-left-radius:9999px}.md\:rounded-l-full{border-top-left-radius:9999px;border-bottom-left-radius:9999px}.md\:rounded-tl-none{border-top-left-radius:0}.md\:rounded-tr-none{border-top-right-radius:0}.md\:rounded-br-none{border-bottom-right-radius:0}.md\:rounded-bl-none{border-bottom-left-radius:0}.md\:rounded-tl-sm{border-top-left-radius:.125rem}.md\:rounded-tr-sm{border-top-right-radius:.125rem}.md\:rounded-br-sm{border-bottom-right-radius:.125rem}.md\:rounded-bl-sm{border-bottom-left-radius:.125rem}.md\:rounded-tl{border-top-left-radius:.25rem}.md\:rounded-tr{border-top-right-radius:.25rem}.md\:rounded-br{border-bottom-right-radius:.25rem}.md\:rounded-bl{border-bottom-left-radius:.25rem}.md\:rounded-tl-md{border-top-left-radius:.375rem}.md\:rounded-tr-md{border-top-right-radius:.375rem}.md\:rounded-br-md{border-bottom-right-radius:.375rem}.md\:rounded-bl-md{border-bottom-left-radius:.375rem}.md\:rounded-tl-lg{border-top-left-radius:.5rem}.md\:rounded-tr-lg{border-top-right-radius:.5rem}.md\:rounded-br-lg{border-bottom-right-radius:.5rem}.md\:rounded-bl-lg{border-bottom-left-radius:.5rem}.md\:rounded-tl-xl{border-top-left-radius:.75rem}.md\:rounded-tr-xl{border-top-right-radius:.75rem}.md\:rounded-br-xl{border-bottom-right-radius:.75rem}.md\:rounded-bl-xl{border-bottom-left-radius:.75rem}.md\:rounded-tl-2xl{border-top-left-radius:1rem}.md\:rounded-tr-2xl{border-top-right-radius:1rem}.md\:rounded-br-2xl{border-bottom-right-radius:1rem}.md\:rounded-bl-2xl{border-bottom-left-radius:1rem}.md\:rounded-tl-3xl{border-top-left-radius:1.5rem}.md\:rounded-tr-3xl{border-top-right-radius:1.5rem}.md\:rounded-br-3xl{border-bottom-right-radius:1.5rem}.md\:rounded-bl-3xl{border-bottom-left-radius:1.5rem}.md\:rounded-tl-full{border-top-left-radius:9999px}.md\:rounded-tr-full{border-top-right-radius:9999px}.md\:rounded-br-full{border-bottom-right-radius:9999px}.md\:rounded-bl-full{border-bottom-left-radius:9999px}.md\:border-solid{border-style:solid}.md\:border-dashed{border-style:dashed}.md\:border-dotted{border-style:dotted}.md\:border-double{border-style:double}.md\:border-none{border-style:none}.md\:border-0{border-width:0}.md\:border-2{border-width:2px}.md\:border-4{border-width:4px}.md\:border-8{border-width:8px}.md\:border{border-width:1px}.md\:border-t-0{border-top-width:0}.md\:border-r-0{border-right-width:0}.md\:border-b-0{border-bottom-width:0}.md\:border-l-0{border-left-width:0}.md\:border-t-2{border-top-width:2px}.md\:border-r-2{border-right-width:2px}.md\:border-b-2{border-bottom-width:2px}.md\:border-l-2{border-left-width:2px}.md\:border-t-4{border-top-width:4px}.md\:border-r-4{border-right-width:4px}.md\:border-b-4{border-bottom-width:4px}.md\:border-l-4{border-left-width:4px}.md\:border-t-8{border-top-width:8px}.md\:border-r-8{border-right-width:8px}.md\:border-b-8{border-bottom-width:8px}.md\:border-l-8{border-left-width:8px}.md\:border-t{border-top-width:1px}.md\:border-r{border-right-width:1px}.md\:border-b{border-bottom-width:1px}.md\:border-l{border-left-width:1px}.md\:box-border{box-sizing:border-box}.md\:box-content{box-sizing:content-box}.md\:cursor-auto{cursor:auto}.md\:cursor-default{cursor:default}.md\:cursor-pointer{cursor:pointer}.md\:cursor-wait{cursor:wait}.md\:cursor-text{cursor:text}.md\:cursor-move{cursor:move}.md\:cursor-not-allowed{cursor:not-allowed}.md\:block{display:block}.md\:inline-block{display:inline-block}.md\:inline{display:inline}.md\:flex{display:flex}.md\:inline-flex{display:inline-flex}.md\:table{display:table}.md\:table-caption{display:table-caption}.md\:table-cell{display:table-cell}.md\:table-column{display:table-column}.md\:table-column-group{display:table-column-group}.md\:table-footer-group{display:table-footer-group}.md\:table-header-group{display:table-header-group}.md\:table-row-group{display:table-row-group}.md\:table-row{display:table-row}.md\:flow-root{display:flow-root}.md\:grid{display:grid}.md\:inline-grid{display:inline-grid}.md\:contents{display:contents}.md\:hidden{display:none}.md\:flex-row{flex-direction:row}.md\:flex-row-reverse{flex-direction:row-reverse}.md\:flex-col{flex-direction:column}.md\:flex-col-reverse{flex-direction:column-reverse}.md\:flex-wrap{flex-wrap:wrap}.md\:flex-wrap-reverse{flex-wrap:wrap-reverse}.md\:flex-no-wrap{flex-wrap:nowrap}.md\:place-items-auto{place-items:auto}.md\:place-items-start{place-items:start}.md\:place-items-end{place-items:end}.md\:place-items-center{place-items:center}.md\:place-items-stretch{place-items:stretch}.md\:place-content-center{place-content:center}.md\:place-content-start{place-content:start}.md\:place-content-end{place-content:end}.md\:place-content-between{place-content:space-between}.md\:place-content-around{place-content:space-around}.md\:place-content-evenly{place-content:space-evenly}.md\:place-content-stretch{place-content:stretch}.md\:place-self-auto{place-self:auto}.md\:place-self-start{place-self:start}.md\:place-self-end{place-self:end}.md\:place-self-center{place-self:center}.md\:place-self-stretch{place-self:stretch}.md\:items-start{align-items:flex-start}.md\:items-end{align-items:flex-end}.md\:items-center{align-items:center}.md\:items-baseline{align-items:baseline}.md\:items-stretch{align-items:stretch}.md\:content-center{align-content:center}.md\:content-start{align-content:flex-start}.md\:content-end{align-content:flex-end}.md\:content-between{align-content:space-between}.md\:content-around{align-content:space-around}.md\:content-evenly{align-content:space-evenly}.md\:self-auto{align-self:auto}.md\:self-start{align-self:flex-start}.md\:self-end{align-self:flex-end}.md\:self-center{align-self:center}.md\:self-stretch{align-self:stretch}.md\:justify-items-auto{justify-items:auto}.md\:justify-items-start{justify-items:start}.md\:justify-items-end{justify-items:end}.md\:justify-items-center{justify-items:center}.md\:justify-items-stretch{justify-items:stretch}.md\:justify-start{justify-content:flex-start}.md\:justify-end{justify-content:flex-end}.md\:justify-center{justify-content:center}.md\:justify-between{justify-content:space-between}.md\:justify-around{justify-content:space-around}.md\:justify-evenly{justify-content:space-evenly}.md\:justify-self-auto{justify-self:auto}.md\:justify-self-start{justify-self:start}.md\:justify-self-end{justify-self:end}.md\:justify-self-center{justify-self:center}.md\:justify-self-stretch{justify-self:stretch}.md\:flex-1{flex:1 1 0%}.md\:flex-auto{flex:1 1 auto}.md\:flex-initial{flex:0 1 auto}.md\:flex-none{flex:none}.md\:flex-grow-0{flex-grow:0}.md\:flex-grow{flex-grow:1}.md\:flex-shrink-0{flex-shrink:0}.md\:flex-shrink{flex-shrink:1}.md\:order-1{order:1}.md\:order-2{order:2}.md\:order-3{order:3}.md\:order-4{order:4}.md\:order-5{order:5}.md\:order-6{order:6}.md\:order-7{order:7}.md\:order-8{order:8}.md\:order-9{order:9}.md\:order-10{order:10}.md\:order-11{order:11}.md\:order-12{order:12}.md\:order-first{order:-9999}.md\:order-last{order:9999}.md\:order-none{order:0}.md\:float-right{float:right}.md\:float-left{float:left}.md\:float-none{float:none}.md\:clearfix:after{content:"";display:table;clear:both}.md\:clear-left{clear:left}.md\:clear-right{clear:right}.md\:clear-both{clear:both}.md\:clear-none{clear:none}.md\:font-sans{font-family:system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji"}.md\:font-serif{font-family:Georgia,Cambria,"Times New Roman",Times,serif}.md\:font-mono{font-family:Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace}.md\:font-hairline{font-weight:100}.md\:font-thin{font-weight:200}.md\:font-light{font-weight:300}.md\:font-normal{font-weight:400}.md\:font-medium{font-weight:500}.md\:font-semibold{font-weight:600}.md\:font-bold{font-weight:700}.md\:font-extrabold{font-weight:800}.md\:font-black{font-weight:900}.md\:hover\:font-hairline:hover{font-weight:100}.md\:hover\:font-thin:hover{font-weight:200}.md\:hover\:font-light:hover{font-weight:300}.md\:hover\:font-normal:hover{font-weight:400}.md\:hover\:font-medium:hover{font-weight:500}.md\:hover\:font-semibold:hover{font-weight:600}.md\:hover\:font-bold:hover{font-weight:700}.md\:hover\:font-extrabold:hover{font-weight:800}.md\:hover\:font-black:hover{font-weight:900}.md\:focus\:font-hairline:focus{font-weight:100}.md\:focus\:font-thin:focus{font-weight:200}.md\:focus\:font-light:focus{font-weight:300}.md\:focus\:font-normal:focus{font-weight:400}.md\:focus\:font-medium:focus{font-weight:500}.md\:focus\:font-semibold:focus{font-weight:600}.md\:focus\:font-bold:focus{font-weight:700}.md\:focus\:font-extrabold:focus{font-weight:800}.md\:focus\:font-black:focus{font-weight:900}.md\:h-0{height:0}.md\:h-1{height:.25rem}.md\:h-2{height:.5rem}.md\:h-3{height:.75rem}.md\:h-4{height:1rem}.md\:h-5{height:1.25rem}.md\:h-6{height:1.5rem}.md\:h-8{height:2rem}.md\:h-10{height:2.5rem}.md\:h-12{height:3rem}.md\:h-16{height:4rem}.md\:h-20{height:5rem}.md\:h-24{height:6rem}.md\:h-32{height:8rem}.md\:h-40{height:10rem}.md\:h-48{height:12rem}.md\:h-56{height:14rem}.md\:h-64{height:16rem}.md\:h-auto{height:auto}.md\:h-px{height:1px}.md\:h-full{height:100%}.md\:h-screen{height:100vh}.md\:text-xs{font-size:.75rem}.md\:text-sm{font-size:.875rem}.md\:text-base{font-size:1rem}.md\:text-lg{font-size:1.125rem}.md\:text-xl{font-size:1.25rem}.md\:text-2xl{font-size:1.5rem}.md\:text-3xl{font-size:1.875rem}.md\:text-4xl{font-size:2.25rem}.md\:text-5xl{font-size:3rem}.md\:text-6xl{font-size:4rem}.md\:leading-3{line-height:.75rem}.md\:leading-4{line-height:1rem}.md\:leading-5{line-height:1.25rem}.md\:leading-6{line-height:1.5rem}.md\:leading-7{line-height:1.75rem}.md\:leading-8{line-height:2rem}.md\:leading-9{line-height:2.25rem}.md\:leading-10{line-height:2.5rem}.md\:leading-none{line-height:1}.md\:leading-tight{line-height:1.25}.md\:leading-snug{line-height:1.375}.md\:leading-normal{line-height:1.5}.md\:leading-relaxed{line-height:1.625}.md\:leading-loose{line-height:2}.md\:list-inside{list-style-position:inside}.md\:list-outside{list-style-position:outside}.md\:list-none{list-style-type:none}.md\:list-disc{list-style-type:disc}.md\:list-decimal{list-style-type:decimal}.md\:m-0{margin:0}.md\:m-1{margin:.25rem}.md\:m-2{margin:.5rem}.md\:m-3{margin:.75rem}.md\:m-4{margin:1rem}.md\:m-5{margin:1.25rem}.md\:m-6{margin:1.5rem}.md\:m-8{margin:2rem}.md\:m-10{margin:2.5rem}.md\:m-12{margin:3rem}.md\:m-16{margin:4rem}.md\:m-20{margin:5rem}.md\:m-24{margin:6rem}.md\:m-32{margin:8rem}.md\:m-40{margin:10rem}.md\:m-48{margin:12rem}.md\:m-56{margin:14rem}.md\:m-64{margin:16rem}.md\:m-auto{margin:auto}.md\:m-px{margin:1px}.md\:-m-1{margin:-.25rem}.md\:-m-2{margin:-.5rem}.md\:-m-3{margin:-.75rem}.md\:-m-4{margin:-1rem}.md\:-m-5{margin:-1.25rem}.md\:-m-6{margin:-1.5rem}.md\:-m-8{margin:-2rem}.md\:-m-10{margin:-2.5rem}.md\:-m-12{margin:-3rem}.md\:-m-16{margin:-4rem}.md\:-m-20{margin:-5rem}.md\:-m-24{margin:-6rem}.md\:-m-32{margin:-8rem}.md\:-m-40{margin:-10rem}.md\:-m-48{margin:-12rem}.md\:-m-56{margin:-14rem}.md\:-m-64{margin:-16rem}.md\:-m-px{margin:-1px}.md\:my-0{margin-top:0;margin-bottom:0}.md\:mx-0{margin-left:0;margin-right:0}.md\:my-1{margin-top:.25rem;margin-bottom:.25rem}.md\:mx-1{margin-left:.25rem;margin-right:.25rem}.md\:my-2{margin-top:.5rem;margin-bottom:.5rem}.md\:mx-2{margin-left:.5rem;margin-right:.5rem}.md\:my-3{margin-top:.75rem;margin-bottom:.75rem}.md\:mx-3{margin-left:.75rem;margin-right:.75rem}.md\:my-4{margin-top:1rem;margin-bottom:1rem}.md\:mx-4{margin-left:1rem;margin-right:1rem}.md\:my-5{margin-top:1.25rem;margin-bottom:1.25rem}.md\:mx-5{margin-left:1.25rem;margin-right:1.25rem}.md\:my-6{margin-top:1.5rem;margin-bottom:1.5rem}.md\:mx-6{margin-left:1.5rem;margin-right:1.5rem}.md\:my-8{margin-top:2rem;margin-bottom:2rem}.md\:mx-8{margin-left:2rem;margin-right:2rem}.md\:my-10{margin-top:2.5rem;margin-bottom:2.5rem}.md\:mx-10{margin-left:2.5rem;margin-right:2.5rem}.md\:my-12{margin-top:3rem;margin-bottom:3rem}.md\:mx-12{margin-left:3rem;margin-right:3rem}.md\:my-16{margin-top:4rem;margin-bottom:4rem}.md\:mx-16{margin-left:4rem;margin-right:4rem}.md\:my-20{margin-top:5rem;margin-bottom:5rem}.md\:mx-20{margin-left:5rem;margin-right:5rem}.md\:my-24{margin-top:6rem;margin-bottom:6rem}.md\:mx-24{margin-left:6rem;margin-right:6rem}.md\:my-32{margin-top:8rem;margin-bottom:8rem}.md\:mx-32{margin-left:8rem;margin-right:8rem}.md\:my-40{margin-top:10rem;margin-bottom:10rem}.md\:mx-40{margin-left:10rem;margin-right:10rem}.md\:my-48{margin-top:12rem;margin-bottom:12rem}.md\:mx-48{margin-left:12rem;margin-right:12rem}.md\:my-56{margin-top:14rem;margin-bottom:14rem}.md\:mx-56{margin-left:14rem;margin-right:14rem}.md\:my-64{margin-top:16rem;margin-bottom:16rem}.md\:mx-64{margin-left:16rem;margin-right:16rem}.md\:my-auto{margin-top:auto;margin-bottom:auto}.md\:mx-auto{margin-left:auto;margin-right:auto}.md\:my-px{margin-top:1px;margin-bottom:1px}.md\:mx-px{margin-left:1px;margin-right:1px}.md\:-my-1{margin-top:-.25rem;margin-bottom:-.25rem}.md\:-mx-1{margin-left:-.25rem;margin-right:-.25rem}.md\:-my-2{margin-top:-.5rem;margin-bottom:-.5rem}.md\:-mx-2{margin-left:-.5rem;margin-right:-.5rem}.md\:-my-3{margin-top:-.75rem;margin-bottom:-.75rem}.md\:-mx-3{margin-left:-.75rem;margin-right:-.75rem}.md\:-my-4{margin-top:-1rem;margin-bottom:-1rem}.md\:-mx-4{margin-left:-1rem;margin-right:-1rem}.md\:-my-5{margin-top:-1.25rem;margin-bottom:-1.25rem}.md\:-mx-5{margin-left:-1.25rem;margin-right:-1.25rem}.md\:-my-6{margin-top:-1.5rem;margin-bottom:-1.5rem}.md\:-mx-6{margin-left:-1.5rem;margin-right:-1.5rem}.md\:-my-8{margin-top:-2rem;margin-bottom:-2rem}.md\:-mx-8{margin-left:-2rem;margin-right:-2rem}.md\:-my-10{margin-top:-2.5rem;margin-bottom:-2.5rem}.md\:-mx-10{margin-left:-2.5rem;margin-right:-2.5rem}.md\:-my-12{margin-top:-3rem;margin-bottom:-3rem}.md\:-mx-12{margin-left:-3rem;margin-right:-3rem}.md\:-my-16{margin-top:-4rem;margin-bottom:-4rem}.md\:-mx-16{margin-left:-4rem;margin-right:-4rem}.md\:-my-20{margin-top:-5rem;margin-bottom:-5rem}.md\:-mx-20{margin-left:-5rem;margin-right:-5rem}.md\:-my-24{margin-top:-6rem;margin-bottom:-6rem}.md\:-mx-24{margin-left:-6rem;margin-right:-6rem}.md\:-my-32{margin-top:-8rem;margin-bottom:-8rem}.md\:-mx-32{margin-left:-8rem;margin-right:-8rem}.md\:-my-40{margin-top:-10rem;margin-bottom:-10rem}.md\:-mx-40{margin-left:-10rem;margin-right:-10rem}.md\:-my-48{margin-top:-12rem;margin-bottom:-12rem}.md\:-mx-48{margin-left:-12rem;margin-right:-12rem}.md\:-my-56{margin-top:-14rem;margin-bottom:-14rem}.md\:-mx-56{margin-left:-14rem;margin-right:-14rem}.md\:-my-64{margin-top:-16rem;margin-bottom:-16rem}.md\:-mx-64{margin-left:-16rem;margin-right:-16rem}.md\:-my-px{margin-top:-1px;margin-bottom:-1px}.md\:-mx-px{margin-left:-1px;margin-right:-1px}.md\:mt-0{margin-top:0}.md\:mr-0{margin-right:0}.md\:mb-0{margin-bottom:0}.md\:ml-0{margin-left:0}.md\:mt-1{margin-top:.25rem}.md\:mr-1{margin-right:.25rem}.md\:mb-1{margin-bottom:.25rem}.md\:ml-1{margin-left:.25rem}.md\:mt-2{margin-top:.5rem}.md\:mr-2{margin-right:.5rem}.md\:mb-2{margin-bottom:.5rem}.md\:ml-2{margin-left:.5rem}.md\:mt-3{margin-top:.75rem}.md\:mr-3{margin-right:.75rem}.md\:mb-3{margin-bottom:.75rem}.md\:ml-3{margin-left:.75rem}.md\:mt-4{margin-top:1rem}.md\:mr-4{margin-right:1rem}.md\:mb-4{margin-bottom:1rem}.md\:ml-4{margin-left:1rem}.md\:mt-5{margin-top:1.25rem}.md\:mr-5{margin-right:1.25rem}.md\:mb-5{margin-bottom:1.25rem}.md\:ml-5{margin-left:1.25rem}.md\:mt-6{margin-top:1.5rem}.md\:mr-6{margin-right:1.5rem}.md\:mb-6{margin-bottom:1.5rem}.md\:ml-6{margin-left:1.5rem}.md\:mt-8{margin-top:2rem}.md\:mr-8{margin-right:2rem}.md\:mb-8{margin-bottom:2rem}.md\:ml-8{margin-left:2rem}.md\:mt-10{margin-top:2.5rem}.md\:mr-10{margin-right:2.5rem}.md\:mb-10{margin-bottom:2.5rem}.md\:ml-10{margin-left:2.5rem}.md\:mt-12{margin-top:3rem}.md\:mr-12{margin-right:3rem}.md\:mb-12{margin-bottom:3rem}.md\:ml-12{margin-left:3rem}.md\:mt-16{margin-top:4rem}.md\:mr-16{margin-right:4rem}.md\:mb-16{margin-bottom:4rem}.md\:ml-16{margin-left:4rem}.md\:mt-20{margin-top:5rem}.md\:mr-20{margin-right:5rem}.md\:mb-20{margin-bottom:5rem}.md\:ml-20{margin-left:5rem}.md\:mt-24{margin-top:6rem}.md\:mr-24{margin-right:6rem}.md\:mb-24{margin-bottom:6rem}.md\:ml-24{margin-left:6rem}.md\:mt-32{margin-top:8rem}.md\:mr-32{margin-right:8rem}.md\:mb-32{margin-bottom:8rem}.md\:ml-32{margin-left:8rem}.md\:mt-40{margin-top:10rem}.md\:mr-40{margin-right:10rem}.md\:mb-40{margin-bottom:10rem}.md\:ml-40{margin-left:10rem}.md\:mt-48{margin-top:12rem}.md\:mr-48{margin-right:12rem}.md\:mb-48{margin-bottom:12rem}.md\:ml-48{margin-left:12rem}.md\:mt-56{margin-top:14rem}.md\:mr-56{margin-right:14rem}.md\:mb-56{margin-bottom:14rem}.md\:ml-56{margin-left:14rem}.md\:mt-64{margin-top:16rem}.md\:mr-64{margin-right:16rem}.md\:mb-64{margin-bottom:16rem}.md\:ml-64{margin-left:16rem}.md\:mt-auto{margin-top:auto}.md\:mr-auto{margin-right:auto}.md\:mb-auto{margin-bottom:auto}.md\:ml-auto{margin-left:auto}.md\:mt-px{margin-top:1px}.md\:mr-px{margin-right:1px}.md\:mb-px{margin-bottom:1px}.md\:ml-px{margin-left:1px}.md\:-mt-1{margin-top:-.25rem}.md\:-mr-1{margin-right:-.25rem}.md\:-mb-1{margin-bottom:-.25rem}.md\:-ml-1{margin-left:-.25rem}.md\:-mt-2{margin-top:-.5rem}.md\:-mr-2{margin-right:-.5rem}.md\:-mb-2{margin-bottom:-.5rem}.md\:-ml-2{margin-left:-.5rem}.md\:-mt-3{margin-top:-.75rem}.md\:-mr-3{margin-right:-.75rem}.md\:-mb-3{margin-bottom:-.75rem}.md\:-ml-3{margin-left:-.75rem}.md\:-mt-4{margin-top:-1rem}.md\:-mr-4{margin-right:-1rem}.md\:-mb-4{margin-bottom:-1rem}.md\:-ml-4{margin-left:-1rem}.md\:-mt-5{margin-top:-1.25rem}.md\:-mr-5{margin-right:-1.25rem}.md\:-mb-5{margin-bottom:-1.25rem}.md\:-ml-5{margin-left:-1.25rem}.md\:-mt-6{margin-top:-1.5rem}.md\:-mr-6{margin-right:-1.5rem}.md\:-mb-6{margin-bottom:-1.5rem}.md\:-ml-6{margin-left:-1.5rem}.md\:-mt-8{margin-top:-2rem}.md\:-mr-8{margin-right:-2rem}.md\:-mb-8{margin-bottom:-2rem}.md\:-ml-8{margin-left:-2rem}.md\:-mt-10{margin-top:-2.5rem}.md\:-mr-10{margin-right:-2.5rem}.md\:-mb-10{margin-bottom:-2.5rem}.md\:-ml-10{margin-left:-2.5rem}.md\:-mt-12{margin-top:-3rem}.md\:-mr-12{margin-right:-3rem}.md\:-mb-12{margin-bottom:-3rem}.md\:-ml-12{margin-left:-3rem}.md\:-mt-16{margin-top:-4rem}.md\:-mr-16{margin-right:-4rem}.md\:-mb-16{margin-bottom:-4rem}.md\:-ml-16{margin-left:-4rem}.md\:-mt-20{margin-top:-5rem}.md\:-mr-20{margin-right:-5rem}.md\:-mb-20{margin-bottom:-5rem}.md\:-ml-20{margin-left:-5rem}.md\:-mt-24{margin-top:-6rem}.md\:-mr-24{margin-right:-6rem}.md\:-mb-24{margin-bottom:-6rem}.md\:-ml-24{margin-left:-6rem}.md\:-mt-32{margin-top:-8rem}.md\:-mr-32{margin-right:-8rem}.md\:-mb-32{margin-bottom:-8rem}.md\:-ml-32{margin-left:-8rem}.md\:-mt-40{margin-top:-10rem}.md\:-mr-40{margin-right:-10rem}.md\:-mb-40{margin-bottom:-10rem}.md\:-ml-40{margin-left:-10rem}.md\:-mt-48{margin-top:-12rem}.md\:-mr-48{margin-right:-12rem}.md\:-mb-48{margin-bottom:-12rem}.md\:-ml-48{margin-left:-12rem}.md\:-mt-56{margin-top:-14rem}.md\:-mr-56{margin-right:-14rem}.md\:-mb-56{margin-bottom:-14rem}.md\:-ml-56{margin-left:-14rem}.md\:-mt-64{margin-top:-16rem}.md\:-mr-64{margin-right:-16rem}.md\:-mb-64{margin-bottom:-16rem}.md\:-ml-64{margin-left:-16rem}.md\:-mt-px{margin-top:-1px}.md\:-mr-px{margin-right:-1px}.md\:-mb-px{margin-bottom:-1px}.md\:-ml-px{margin-left:-1px}.md\:max-h-full{max-height:100%}.md\:max-h-screen{max-height:100vh}.md\:max-w-none{max-width:none}.md\:max-w-xs{max-width:20rem}.md\:max-w-sm{max-width:24rem}.md\:max-w-md{max-width:28rem}.md\:max-w-lg{max-width:32rem}.md\:max-w-xl{max-width:36rem}.md\:max-w-2xl{max-width:42rem}.md\:max-w-3xl{max-width:48rem}.md\:max-w-4xl{max-width:56rem}.md\:max-w-5xl{max-width:64rem}.md\:max-w-6xl{max-width:72rem}.md\:max-w-full{max-width:100%}.md\:max-w-screen-sm{max-width:640px}.md\:max-w-screen-md{max-width:768px}.md\:max-w-screen-lg{max-width:1024px}.md\:max-w-screen-xl{max-width:1280px}.md\:min-h-0{min-height:0}.md\:min-h-full{min-height:100%}.md\:min-h-screen{min-height:100vh}.md\:min-w-0{min-width:0}.md\:min-w-full{min-width:100%}.md\:object-contain{object-fit:contain}.md\:object-cover{object-fit:cover}.md\:object-fill{object-fit:fill}.md\:object-none{object-fit:none}.md\:object-scale-down{object-fit:scale-down}.md\:object-bottom{object-position:bottom}.md\:object-center{object-position:center}.md\:object-left{object-position:left}.md\:object-left-bottom{object-position:left bottom}.md\:object-left-top{object-position:left top}.md\:object-right{object-position:right}.md\:object-right-bottom{object-position:right bottom}.md\:object-right-top{object-position:right top}.md\:object-top{object-position:top}.md\:opacity-0{opacity:0}.md\:opacity-25{opacity:.25}.md\:opacity-50{opacity:.5}.md\:opacity-75{opacity:.75}.md\:opacity-100{opacity:1}.md\:hover\:opacity-0:hover{opacity:0}.md\:hover\:opacity-25:hover{opacity:.25}.md\:hover\:opacity-50:hover{opacity:.5}.md\:hover\:opacity-75:hover{opacity:.75}.md\:hover\:opacity-100:hover{opacity:1}.md\:focus\:opacity-0:focus{opacity:0}.md\:focus\:opacity-25:focus{opacity:.25}.md\:focus\:opacity-50:focus{opacity:.5}.md\:focus\:opacity-75:focus{opacity:.75}.md\:focus\:opacity-100:focus{opacity:1}.md\:outline-none{outline:2px solid transparent;outline-offset:2px}.md\:outline-white{outline:2px dotted #fff;outline-offset:2px}.md\:outline-black{outline:2px dotted #000;outline-offset:2px}.md\:focus\:outline-none:focus{outline:2px solid transparent;outline-offset:2px}.md\:focus\:outline-white:focus{outline:2px dotted #fff;outline-offset:2px}.md\:focus\:outline-black:focus{outline:2px dotted #000;outline-offset:2px}.md\:overflow-auto{overflow:auto}.md\:overflow-hidden{overflow:hidden}.md\:overflow-visible{overflow:visible}.md\:overflow-scroll{overflow:scroll}.md\:overflow-x-auto{overflow-x:auto}.md\:overflow-y-auto{overflow-y:auto}.md\:overflow-x-hidden{overflow-x:hidden}.md\:overflow-y-hidden{overflow-y:hidden}.md\:overflow-x-visible{overflow-x:visible}.md\:overflow-y-visible{overflow-y:visible}.md\:overflow-x-scroll{overflow-x:scroll}.md\:overflow-y-scroll{overflow-y:scroll}.md\:scrolling-touch{-webkit-overflow-scrolling:touch}.md\:scrolling-auto{-webkit-overflow-scrolling:auto}.md\:overscroll-auto{-ms-scroll-chaining:chained;overscroll-behavior:auto}.md\:overscroll-contain{-ms-scroll-chaining:none;overscroll-behavior:contain}.md\:overscroll-none{-ms-scroll-chaining:none;overscroll-behavior:none}.md\:overscroll-y-auto{overscroll-behavior-y:auto}.md\:overscroll-y-contain{overscroll-behavior-y:contain}.md\:overscroll-y-none{overscroll-behavior-y:none}.md\:overscroll-x-auto{overscroll-behavior-x:auto}.md\:overscroll-x-contain{overscroll-behavior-x:contain}.md\:overscroll-x-none{overscroll-behavior-x:none}.md\:p-0{padding:0}.md\:p-1{padding:.25rem}.md\:p-2{padding:.5rem}.md\:p-3{padding:.75rem}.md\:p-4{padding:1rem}.md\:p-5{padding:1.25rem}.md\:p-6{padding:1.5rem}.md\:p-8{padding:2rem}.md\:p-10{padding:2.5rem}.md\:p-12{padding:3rem}.md\:p-16{padding:4rem}.md\:p-20{padding:5rem}.md\:p-24{padding:6rem}.md\:p-32{padding:8rem}.md\:p-40{padding:10rem}.md\:p-48{padding:12rem}.md\:p-56{padding:14rem}.md\:p-64{padding:16rem}.md\:p-px{padding:1px}.md\:py-0{padding-top:0;padding-bottom:0}.md\:px-0{padding-left:0;padding-right:0}.md\:py-1{padding-top:.25rem;padding-bottom:.25rem}.md\:px-1{padding-left:.25rem;padding-right:.25rem}.md\:py-2{padding-top:.5rem;padding-bottom:.5rem}.md\:px-2{padding-left:.5rem;padding-right:.5rem}.md\:py-3{padding-top:.75rem;padding-bottom:.75rem}.md\:px-3{padding-left:.75rem;padding-right:.75rem}.md\:py-4{padding-top:1rem;padding-bottom:1rem}.md\:px-4{padding-left:1rem;padding-right:1rem}.md\:py-5{padding-top:1.25rem;padding-bottom:1.25rem}.md\:px-5{padding-left:1.25rem;padding-right:1.25rem}.md\:py-6{padding-top:1.5rem;padding-bottom:1.5rem}.md\:px-6{padding-left:1.5rem;padding-right:1.5rem}.md\:py-8{padding-top:2rem;padding-bottom:2rem}.md\:px-8{padding-left:2rem;padding-right:2rem}.md\:py-10{padding-top:2.5rem;padding-bottom:2.5rem}.md\:px-10{padding-left:2.5rem;padding-right:2.5rem}.md\:py-12{padding-top:3rem;padding-bottom:3rem}.md\:px-12{padding-left:3rem;padding-right:3rem}.md\:py-16{padding-top:4rem;padding-bottom:4rem}.md\:px-16{padding-left:4rem;padding-right:4rem}.md\:py-20{padding-top:5rem;padding-bottom:5rem}.md\:px-20{padding-left:5rem;padding-right:5rem}.md\:py-24{padding-top:6rem;padding-bottom:6rem}.md\:px-24{padding-left:6rem;padding-right:6rem}.md\:py-32{padding-top:8rem;padding-bottom:8rem}.md\:px-32{padding-left:8rem;padding-right:8rem}.md\:py-40{padding-top:10rem;padding-bottom:10rem}.md\:px-40{padding-left:10rem;padding-right:10rem}.md\:py-48{padding-top:12rem;padding-bottom:12rem}.md\:px-48{padding-left:12rem;padding-right:12rem}.md\:py-56{padding-top:14rem;padding-bottom:14rem}.md\:px-56{padding-left:14rem;padding-right:14rem}.md\:py-64{padding-top:16rem;padding-bottom:16rem}.md\:px-64{padding-left:16rem;padding-right:16rem}.md\:py-px{padding-top:1px;padding-bottom:1px}.md\:px-px{padding-left:1px;padding-right:1px}.md\:pt-0{padding-top:0}.md\:pr-0{padding-right:0}.md\:pb-0{padding-bottom:0}.md\:pl-0{padding-left:0}.md\:pt-1{padding-top:.25rem}.md\:pr-1{padding-right:.25rem}.md\:pb-1{padding-bottom:.25rem}.md\:pl-1{padding-left:.25rem}.md\:pt-2{padding-top:.5rem}.md\:pr-2{padding-right:.5rem}.md\:pb-2{padding-bottom:.5rem}.md\:pl-2{padding-left:.5rem}.md\:pt-3{padding-top:.75rem}.md\:pr-3{padding-right:.75rem}.md\:pb-3{padding-bottom:.75rem}.md\:pl-3{padding-left:.75rem}.md\:pt-4{padding-top:1rem}.md\:pr-4{padding-right:1rem}.md\:pb-4{padding-bottom:1rem}.md\:pl-4{padding-left:1rem}.md\:pt-5{padding-top:1.25rem}.md\:pr-5{padding-right:1.25rem}.md\:pb-5{padding-bottom:1.25rem}.md\:pl-5{padding-left:1.25rem}.md\:pt-6{padding-top:1.5rem}.md\:pr-6{padding-right:1.5rem}.md\:pb-6{padding-bottom:1.5rem}.md\:pl-6{padding-left:1.5rem}.md\:pt-8{padding-top:2rem}.md\:pr-8{padding-right:2rem}.md\:pb-8{padding-bottom:2rem}.md\:pl-8{padding-left:2rem}.md\:pt-10{padding-top:2.5rem}.md\:pr-10{padding-right:2.5rem}.md\:pb-10{padding-bottom:2.5rem}.md\:pl-10{padding-left:2.5rem}.md\:pt-12{padding-top:3rem}.md\:pr-12{padding-right:3rem}.md\:pb-12{padding-bottom:3rem}.md\:pl-12{padding-left:3rem}.md\:pt-16{padding-top:4rem}.md\:pr-16{padding-right:4rem}.md\:pb-16{padding-bottom:4rem}.md\:pl-16{padding-left:4rem}.md\:pt-20{padding-top:5rem}.md\:pr-20{padding-right:5rem}.md\:pb-20{padding-bottom:5rem}.md\:pl-20{padding-left:5rem}.md\:pt-24{padding-top:6rem}.md\:pr-24{padding-right:6rem}.md\:pb-24{padding-bottom:6rem}.md\:pl-24{padding-left:6rem}.md\:pt-32{padding-top:8rem}.md\:pr-32{padding-right:8rem}.md\:pb-32{padding-bottom:8rem}.md\:pl-32{padding-left:8rem}.md\:pt-40{padding-top:10rem}.md\:pr-40{padding-right:10rem}.md\:pb-40{padding-bottom:10rem}.md\:pl-40{padding-left:10rem}.md\:pt-48{padding-top:12rem}.md\:pr-48{padding-right:12rem}.md\:pb-48{padding-bottom:12rem}.md\:pl-48{padding-left:12rem}.md\:pt-56{padding-top:14rem}.md\:pr-56{padding-right:14rem}.md\:pb-56{padding-bottom:14rem}.md\:pl-56{padding-left:14rem}.md\:pt-64{padding-top:16rem}.md\:pr-64{padding-right:16rem}.md\:pb-64{padding-bottom:16rem}.md\:pl-64{padding-left:16rem}.md\:pt-px{padding-top:1px}.md\:pr-px{padding-right:1px}.md\:pb-px{padding-bottom:1px}.md\:pl-px{padding-left:1px}.md\:placeholder-transparent:-ms-input-placeholder{color:transparent}.md\:placeholder-transparent::-ms-input-placeholder{color:transparent}.md\:placeholder-transparent::placeholder{color:transparent}.md\:placeholder-current:-ms-input-placeholder{color:currentColor}.md\:placeholder-current::-ms-input-placeholder{color:currentColor}.md\:placeholder-current::placeholder{color:currentColor}.md\:placeholder-black:-ms-input-placeholder{--placeholder-opacity:1;color:#000;color:rgba(0,0,0,var(--placeholder-opacity))}.md\:placeholder-black::-ms-input-placeholder{--placeholder-opacity:1;color:#000;color:rgba(0,0,0,var(--placeholder-opacity))}.md\:placeholder-black::placeholder{--placeholder-opacity:1;color:#000;color:rgba(0,0,0,var(--placeholder-opacity))}.md\:placeholder-white:-ms-input-placeholder{--placeholder-opacity:1;color:#fff;color:rgba(255,255,255,var(--placeholder-opacity))}.md\:placeholder-white::-ms-input-placeholder{--placeholder-opacity:1;color:#fff;color:rgba(255,255,255,var(--placeholder-opacity))}.md\:placeholder-white::placeholder{--placeholder-opacity:1;color:#fff;color:rgba(255,255,255,var(--placeholder-opacity))}.md\:placeholder-gray-100:-ms-input-placeholder{--placeholder-opacity:1;color:#f7fafc;color:rgba(247,250,252,var(--placeholder-opacity))}.md\:placeholder-gray-100::-ms-input-placeholder{--placeholder-opacity:1;color:#f7fafc;color:rgba(247,250,252,var(--placeholder-opacity))}.md\:placeholder-gray-100::placeholder{--placeholder-opacity:1;color:#f7fafc;color:rgba(247,250,252,var(--placeholder-opacity))}.md\:placeholder-gray-200:-ms-input-placeholder{--placeholder-opacity:1;color:#edf2f7;color:rgba(237,242,247,var(--placeholder-opacity))}.md\:placeholder-gray-200::-ms-input-placeholder{--placeholder-opacity:1;color:#edf2f7;color:rgba(237,242,247,var(--placeholder-opacity))}.md\:placeholder-gray-200::placeholder{--placeholder-opacity:1;color:#edf2f7;color:rgba(237,242,247,var(--placeholder-opacity))}.md\:placeholder-gray-300:-ms-input-placeholder{--placeholder-opacity:1;color:#e2e8f0;color:rgba(226,232,240,var(--placeholder-opacity))}.md\:placeholder-gray-300::-ms-input-placeholder{--placeholder-opacity:1;color:#e2e8f0;color:rgba(226,232,240,var(--placeholder-opacity))}.md\:placeholder-gray-300::placeholder{--placeholder-opacity:1;color:#e2e8f0;color:rgba(226,232,240,var(--placeholder-opacity))}.md\:placeholder-gray-400:-ms-input-placeholder{--placeholder-opacity:1;color:#cbd5e0;color:rgba(203,213,224,var(--placeholder-opacity))}.md\:placeholder-gray-400::-ms-input-placeholder{--placeholder-opacity:1;color:#cbd5e0;color:rgba(203,213,224,var(--placeholder-opacity))}.md\:placeholder-gray-400::placeholder{--placeholder-opacity:1;color:#cbd5e0;color:rgba(203,213,224,var(--placeholder-opacity))}.md\:placeholder-gray-500:-ms-input-placeholder{--placeholder-opacity:1;color:#a0aec0;color:rgba(160,174,192,var(--placeholder-opacity))}.md\:placeholder-gray-500::-ms-input-placeholder{--placeholder-opacity:1;color:#a0aec0;color:rgba(160,174,192,var(--placeholder-opacity))}.md\:placeholder-gray-500::placeholder{--placeholder-opacity:1;color:#a0aec0;color:rgba(160,174,192,var(--placeholder-opacity))}.md\:placeholder-gray-600:-ms-input-placeholder{--placeholder-opacity:1;color:#718096;color:rgba(113,128,150,var(--placeholder-opacity))}.md\:placeholder-gray-600::-ms-input-placeholder{--placeholder-opacity:1;color:#718096;color:rgba(113,128,150,var(--placeholder-opacity))}.md\:placeholder-gray-600::placeholder{--placeholder-opacity:1;color:#718096;color:rgba(113,128,150,var(--placeholder-opacity))}.md\:placeholder-gray-700:-ms-input-placeholder{--placeholder-opacity:1;color:#4a5568;color:rgba(74,85,104,var(--placeholder-opacity))}.md\:placeholder-gray-700::-ms-input-placeholder{--placeholder-opacity:1;color:#4a5568;color:rgba(74,85,104,var(--placeholder-opacity))}.md\:placeholder-gray-700::placeholder{--placeholder-opacity:1;color:#4a5568;color:rgba(74,85,104,var(--placeholder-opacity))}.md\:placeholder-gray-800:-ms-input-placeholder{--placeholder-opacity:1;color:#2d3748;color:rgba(45,55,72,var(--placeholder-opacity))}.md\:placeholder-gray-800::-ms-input-placeholder{--placeholder-opacity:1;color:#2d3748;color:rgba(45,55,72,var(--placeholder-opacity))}.md\:placeholder-gray-800::placeholder{--placeholder-opacity:1;color:#2d3748;color:rgba(45,55,72,var(--placeholder-opacity))}.md\:placeholder-gray-900:-ms-input-placeholder{--placeholder-opacity:1;color:#1a202c;color:rgba(26,32,44,var(--placeholder-opacity))}.md\:placeholder-gray-900::-ms-input-placeholder{--placeholder-opacity:1;color:#1a202c;color:rgba(26,32,44,var(--placeholder-opacity))}.md\:placeholder-gray-900::placeholder{--placeholder-opacity:1;color:#1a202c;color:rgba(26,32,44,var(--placeholder-opacity))}.md\:placeholder-red-100:-ms-input-placeholder{--placeholder-opacity:1;color:#fff5f5;color:rgba(255,245,245,var(--placeholder-opacity))}.md\:placeholder-red-100::-ms-input-placeholder{--placeholder-opacity:1;color:#fff5f5;color:rgba(255,245,245,var(--placeholder-opacity))}.md\:placeholder-red-100::placeholder{--placeholder-opacity:1;color:#fff5f5;color:rgba(255,245,245,var(--placeholder-opacity))}.md\:placeholder-red-200:-ms-input-placeholder{--placeholder-opacity:1;color:#fed7d7;color:rgba(254,215,215,var(--placeholder-opacity))}.md\:placeholder-red-200::-ms-input-placeholder{--placeholder-opacity:1;color:#fed7d7;color:rgba(254,215,215,var(--placeholder-opacity))}.md\:placeholder-red-200::placeholder{--placeholder-opacity:1;color:#fed7d7;color:rgba(254,215,215,var(--placeholder-opacity))}.md\:placeholder-red-300:-ms-input-placeholder{--placeholder-opacity:1;color:#feb2b2;color:rgba(254,178,178,var(--placeholder-opacity))}.md\:placeholder-red-300::-ms-input-placeholder{--placeholder-opacity:1;color:#feb2b2;color:rgba(254,178,178,var(--placeholder-opacity))}.md\:placeholder-red-300::placeholder{--placeholder-opacity:1;color:#feb2b2;color:rgba(254,178,178,var(--placeholder-opacity))}.md\:placeholder-red-400:-ms-input-placeholder{--placeholder-opacity:1;color:#fc8181;color:rgba(252,129,129,var(--placeholder-opacity))}.md\:placeholder-red-400::-ms-input-placeholder{--placeholder-opacity:1;color:#fc8181;color:rgba(252,129,129,var(--placeholder-opacity))}.md\:placeholder-red-400::placeholder{--placeholder-opacity:1;color:#fc8181;color:rgba(252,129,129,var(--placeholder-opacity))}.md\:placeholder-red-500:-ms-input-placeholder{--placeholder-opacity:1;color:#f56565;color:rgba(245,101,101,var(--placeholder-opacity))}.md\:placeholder-red-500::-ms-input-placeholder{--placeholder-opacity:1;color:#f56565;color:rgba(245,101,101,var(--placeholder-opacity))}.md\:placeholder-red-500::placeholder{--placeholder-opacity:1;color:#f56565;color:rgba(245,101,101,var(--placeholder-opacity))}.md\:placeholder-red-600:-ms-input-placeholder{--placeholder-opacity:1;color:#e53e3e;color:rgba(229,62,62,var(--placeholder-opacity))}.md\:placeholder-red-600::-ms-input-placeholder{--placeholder-opacity:1;color:#e53e3e;color:rgba(229,62,62,var(--placeholder-opacity))}.md\:placeholder-red-600::placeholder{--placeholder-opacity:1;color:#e53e3e;color:rgba(229,62,62,var(--placeholder-opacity))}.md\:placeholder-red-700:-ms-input-placeholder{--placeholder-opacity:1;color:#c53030;color:rgba(197,48,48,var(--placeholder-opacity))}.md\:placeholder-red-700::-ms-input-placeholder{--placeholder-opacity:1;color:#c53030;color:rgba(197,48,48,var(--placeholder-opacity))}.md\:placeholder-red-700::placeholder{--placeholder-opacity:1;color:#c53030;color:rgba(197,48,48,var(--placeholder-opacity))}.md\:placeholder-red-800:-ms-input-placeholder{--placeholder-opacity:1;color:#9b2c2c;color:rgba(155,44,44,var(--placeholder-opacity))}.md\:placeholder-red-800::-ms-input-placeholder{--placeholder-opacity:1;color:#9b2c2c;color:rgba(155,44,44,var(--placeholder-opacity))}.md\:placeholder-red-800::placeholder{--placeholder-opacity:1;color:#9b2c2c;color:rgba(155,44,44,var(--placeholder-opacity))}.md\:placeholder-red-900:-ms-input-placeholder{--placeholder-opacity:1;color:#742a2a;color:rgba(116,42,42,var(--placeholder-opacity))}.md\:placeholder-red-900::-ms-input-placeholder{--placeholder-opacity:1;color:#742a2a;color:rgba(116,42,42,var(--placeholder-opacity))}.md\:placeholder-red-900::placeholder{--placeholder-opacity:1;color:#742a2a;color:rgba(116,42,42,var(--placeholder-opacity))}.md\:placeholder-orange-100:-ms-input-placeholder{--placeholder-opacity:1;color:#fffaf0;color:rgba(255,250,240,var(--placeholder-opacity))}.md\:placeholder-orange-100::-ms-input-placeholder{--placeholder-opacity:1;color:#fffaf0;color:rgba(255,250,240,var(--placeholder-opacity))}.md\:placeholder-orange-100::placeholder{--placeholder-opacity:1;color:#fffaf0;color:rgba(255,250,240,var(--placeholder-opacity))}.md\:placeholder-orange-200:-ms-input-placeholder{--placeholder-opacity:1;color:#feebc8;color:rgba(254,235,200,var(--placeholder-opacity))}.md\:placeholder-orange-200::-ms-input-placeholder{--placeholder-opacity:1;color:#feebc8;color:rgba(254,235,200,var(--placeholder-opacity))}.md\:placeholder-orange-200::placeholder{--placeholder-opacity:1;color:#feebc8;color:rgba(254,235,200,var(--placeholder-opacity))}.md\:placeholder-orange-300:-ms-input-placeholder{--placeholder-opacity:1;color:#fbd38d;color:rgba(251,211,141,var(--placeholder-opacity))}.md\:placeholder-orange-300::-ms-input-placeholder{--placeholder-opacity:1;color:#fbd38d;color:rgba(251,211,141,var(--placeholder-opacity))}.md\:placeholder-orange-300::placeholder{--placeholder-opacity:1;color:#fbd38d;color:rgba(251,211,141,var(--placeholder-opacity))}.md\:placeholder-orange-400:-ms-input-placeholder{--placeholder-opacity:1;color:#f6ad55;color:rgba(246,173,85,var(--placeholder-opacity))}.md\:placeholder-orange-400::-ms-input-placeholder{--placeholder-opacity:1;color:#f6ad55;color:rgba(246,173,85,var(--placeholder-opacity))}.md\:placeholder-orange-400::placeholder{--placeholder-opacity:1;color:#f6ad55;color:rgba(246,173,85,var(--placeholder-opacity))}.md\:placeholder-orange-500:-ms-input-placeholder{--placeholder-opacity:1;color:#ed8936;color:rgba(237,137,54,var(--placeholder-opacity))}.md\:placeholder-orange-500::-ms-input-placeholder{--placeholder-opacity:1;color:#ed8936;color:rgba(237,137,54,var(--placeholder-opacity))}.md\:placeholder-orange-500::placeholder{--placeholder-opacity:1;color:#ed8936;color:rgba(237,137,54,var(--placeholder-opacity))}.md\:placeholder-orange-600:-ms-input-placeholder{--placeholder-opacity:1;color:#dd6b20;color:rgba(221,107,32,var(--placeholder-opacity))}.md\:placeholder-orange-600::-ms-input-placeholder{--placeholder-opacity:1;color:#dd6b20;color:rgba(221,107,32,var(--placeholder-opacity))}.md\:placeholder-orange-600::placeholder{--placeholder-opacity:1;color:#dd6b20;color:rgba(221,107,32,var(--placeholder-opacity))}.md\:placeholder-orange-700:-ms-input-placeholder{--placeholder-opacity:1;color:#c05621;color:rgba(192,86,33,var(--placeholder-opacity))}.md\:placeholder-orange-700::-ms-input-placeholder{--placeholder-opacity:1;color:#c05621;color:rgba(192,86,33,var(--placeholder-opacity))}.md\:placeholder-orange-700::placeholder{--placeholder-opacity:1;color:#c05621;color:rgba(192,86,33,var(--placeholder-opacity))}.md\:placeholder-orange-800:-ms-input-placeholder{--placeholder-opacity:1;color:#9c4221;color:rgba(156,66,33,var(--placeholder-opacity))}.md\:placeholder-orange-800::-ms-input-placeholder{--placeholder-opacity:1;color:#9c4221;color:rgba(156,66,33,var(--placeholder-opacity))}.md\:placeholder-orange-800::placeholder{--placeholder-opacity:1;color:#9c4221;color:rgba(156,66,33,var(--placeholder-opacity))}.md\:placeholder-orange-900:-ms-input-placeholder{--placeholder-opacity:1;color:#7b341e;color:rgba(123,52,30,var(--placeholder-opacity))}.md\:placeholder-orange-900::-ms-input-placeholder{--placeholder-opacity:1;color:#7b341e;color:rgba(123,52,30,var(--placeholder-opacity))}.md\:placeholder-orange-900::placeholder{--placeholder-opacity:1;color:#7b341e;color:rgba(123,52,30,var(--placeholder-opacity))}.md\:placeholder-yellow-100:-ms-input-placeholder{--placeholder-opacity:1;color:ivory;color:rgba(255,255,240,var(--placeholder-opacity))}.md\:placeholder-yellow-100::-ms-input-placeholder{--placeholder-opacity:1;color:ivory;color:rgba(255,255,240,var(--placeholder-opacity))}.md\:placeholder-yellow-100::placeholder{--placeholder-opacity:1;color:ivory;color:rgba(255,255,240,var(--placeholder-opacity))}.md\:placeholder-yellow-200:-ms-input-placeholder{--placeholder-opacity:1;color:#fefcbf;color:rgba(254,252,191,var(--placeholder-opacity))}.md\:placeholder-yellow-200::-ms-input-placeholder{--placeholder-opacity:1;color:#fefcbf;color:rgba(254,252,191,var(--placeholder-opacity))}.md\:placeholder-yellow-200::placeholder{--placeholder-opacity:1;color:#fefcbf;color:rgba(254,252,191,var(--placeholder-opacity))}.md\:placeholder-yellow-300:-ms-input-placeholder{--placeholder-opacity:1;color:#faf089;color:rgba(250,240,137,var(--placeholder-opacity))}.md\:placeholder-yellow-300::-ms-input-placeholder{--placeholder-opacity:1;color:#faf089;color:rgba(250,240,137,var(--placeholder-opacity))}.md\:placeholder-yellow-300::placeholder{--placeholder-opacity:1;color:#faf089;color:rgba(250,240,137,var(--placeholder-opacity))}.md\:placeholder-yellow-400:-ms-input-placeholder{--placeholder-opacity:1;color:#f6e05e;color:rgba(246,224,94,var(--placeholder-opacity))}.md\:placeholder-yellow-400::-ms-input-placeholder{--placeholder-opacity:1;color:#f6e05e;color:rgba(246,224,94,var(--placeholder-opacity))}.md\:placeholder-yellow-400::placeholder{--placeholder-opacity:1;color:#f6e05e;color:rgba(246,224,94,var(--placeholder-opacity))}.md\:placeholder-yellow-500:-ms-input-placeholder{--placeholder-opacity:1;color:#ecc94b;color:rgba(236,201,75,var(--placeholder-opacity))}.md\:placeholder-yellow-500::-ms-input-placeholder{--placeholder-opacity:1;color:#ecc94b;color:rgba(236,201,75,var(--placeholder-opacity))}.md\:placeholder-yellow-500::placeholder{--placeholder-opacity:1;color:#ecc94b;color:rgba(236,201,75,var(--placeholder-opacity))}.md\:placeholder-yellow-600:-ms-input-placeholder{--placeholder-opacity:1;color:#d69e2e;color:rgba(214,158,46,var(--placeholder-opacity))}.md\:placeholder-yellow-600::-ms-input-placeholder{--placeholder-opacity:1;color:#d69e2e;color:rgba(214,158,46,var(--placeholder-opacity))}.md\:placeholder-yellow-600::placeholder{--placeholder-opacity:1;color:#d69e2e;color:rgba(214,158,46,var(--placeholder-opacity))}.md\:placeholder-yellow-700:-ms-input-placeholder{--placeholder-opacity:1;color:#b7791f;color:rgba(183,121,31,var(--placeholder-opacity))}.md\:placeholder-yellow-700::-ms-input-placeholder{--placeholder-opacity:1;color:#b7791f;color:rgba(183,121,31,var(--placeholder-opacity))}.md\:placeholder-yellow-700::placeholder{--placeholder-opacity:1;color:#b7791f;color:rgba(183,121,31,var(--placeholder-opacity))}.md\:placeholder-yellow-800:-ms-input-placeholder{--placeholder-opacity:1;color:#975a16;color:rgba(151,90,22,var(--placeholder-opacity))}.md\:placeholder-yellow-800::-ms-input-placeholder{--placeholder-opacity:1;color:#975a16;color:rgba(151,90,22,var(--placeholder-opacity))}.md\:placeholder-yellow-800::placeholder{--placeholder-opacity:1;color:#975a16;color:rgba(151,90,22,var(--placeholder-opacity))}.md\:placeholder-yellow-900:-ms-input-placeholder{--placeholder-opacity:1;color:#744210;color:rgba(116,66,16,var(--placeholder-opacity))}.md\:placeholder-yellow-900::-ms-input-placeholder{--placeholder-opacity:1;color:#744210;color:rgba(116,66,16,var(--placeholder-opacity))}.md\:placeholder-yellow-900::placeholder{--placeholder-opacity:1;color:#744210;color:rgba(116,66,16,var(--placeholder-opacity))}.md\:placeholder-green-100:-ms-input-placeholder{--placeholder-opacity:1;color:#f0fff4;color:rgba(240,255,244,var(--placeholder-opacity))}.md\:placeholder-green-100::-ms-input-placeholder{--placeholder-opacity:1;color:#f0fff4;color:rgba(240,255,244,var(--placeholder-opacity))}.md\:placeholder-green-100::placeholder{--placeholder-opacity:1;color:#f0fff4;color:rgba(240,255,244,var(--placeholder-opacity))}.md\:placeholder-green-200:-ms-input-placeholder{--placeholder-opacity:1;color:#c6f6d5;color:rgba(198,246,213,var(--placeholder-opacity))}.md\:placeholder-green-200::-ms-input-placeholder{--placeholder-opacity:1;color:#c6f6d5;color:rgba(198,246,213,var(--placeholder-opacity))}.md\:placeholder-green-200::placeholder{--placeholder-opacity:1;color:#c6f6d5;color:rgba(198,246,213,var(--placeholder-opacity))}.md\:placeholder-green-300:-ms-input-placeholder{--placeholder-opacity:1;color:#9ae6b4;color:rgba(154,230,180,var(--placeholder-opacity))}.md\:placeholder-green-300::-ms-input-placeholder{--placeholder-opacity:1;color:#9ae6b4;color:rgba(154,230,180,var(--placeholder-opacity))}.md\:placeholder-green-300::placeholder{--placeholder-opacity:1;color:#9ae6b4;color:rgba(154,230,180,var(--placeholder-opacity))}.md\:placeholder-green-400:-ms-input-placeholder{--placeholder-opacity:1;color:#68d391;color:rgba(104,211,145,var(--placeholder-opacity))}.md\:placeholder-green-400::-ms-input-placeholder{--placeholder-opacity:1;color:#68d391;color:rgba(104,211,145,var(--placeholder-opacity))}.md\:placeholder-green-400::placeholder{--placeholder-opacity:1;color:#68d391;color:rgba(104,211,145,var(--placeholder-opacity))}.md\:placeholder-green-500:-ms-input-placeholder{--placeholder-opacity:1;color:#48bb78;color:rgba(72,187,120,var(--placeholder-opacity))}.md\:placeholder-green-500::-ms-input-placeholder{--placeholder-opacity:1;color:#48bb78;color:rgba(72,187,120,var(--placeholder-opacity))}.md\:placeholder-green-500::placeholder{--placeholder-opacity:1;color:#48bb78;color:rgba(72,187,120,var(--placeholder-opacity))}.md\:placeholder-green-600:-ms-input-placeholder{--placeholder-opacity:1;color:#38a169;color:rgba(56,161,105,var(--placeholder-opacity))}.md\:placeholder-green-600::-ms-input-placeholder{--placeholder-opacity:1;color:#38a169;color:rgba(56,161,105,var(--placeholder-opacity))}.md\:placeholder-green-600::placeholder{--placeholder-opacity:1;color:#38a169;color:rgba(56,161,105,var(--placeholder-opacity))}.md\:placeholder-green-700:-ms-input-placeholder{--placeholder-opacity:1;color:#2f855a;color:rgba(47,133,90,var(--placeholder-opacity))}.md\:placeholder-green-700::-ms-input-placeholder{--placeholder-opacity:1;color:#2f855a;color:rgba(47,133,90,var(--placeholder-opacity))}.md\:placeholder-green-700::placeholder{--placeholder-opacity:1;color:#2f855a;color:rgba(47,133,90,var(--placeholder-opacity))}.md\:placeholder-green-800:-ms-input-placeholder{--placeholder-opacity:1;color:#276749;color:rgba(39,103,73,var(--placeholder-opacity))}.md\:placeholder-green-800::-ms-input-placeholder{--placeholder-opacity:1;color:#276749;color:rgba(39,103,73,var(--placeholder-opacity))}.md\:placeholder-green-800::placeholder{--placeholder-opacity:1;color:#276749;color:rgba(39,103,73,var(--placeholder-opacity))}.md\:placeholder-green-900:-ms-input-placeholder{--placeholder-opacity:1;color:#22543d;color:rgba(34,84,61,var(--placeholder-opacity))}.md\:placeholder-green-900::-ms-input-placeholder{--placeholder-opacity:1;color:#22543d;color:rgba(34,84,61,var(--placeholder-opacity))}.md\:placeholder-green-900::placeholder{--placeholder-opacity:1;color:#22543d;color:rgba(34,84,61,var(--placeholder-opacity))}.md\:placeholder-teal-100:-ms-input-placeholder{--placeholder-opacity:1;color:#e6fffa;color:rgba(230,255,250,var(--placeholder-opacity))}.md\:placeholder-teal-100::-ms-input-placeholder{--placeholder-opacity:1;color:#e6fffa;color:rgba(230,255,250,var(--placeholder-opacity))}.md\:placeholder-teal-100::placeholder{--placeholder-opacity:1;color:#e6fffa;color:rgba(230,255,250,var(--placeholder-opacity))}.md\:placeholder-teal-200:-ms-input-placeholder{--placeholder-opacity:1;color:#b2f5ea;color:rgba(178,245,234,var(--placeholder-opacity))}.md\:placeholder-teal-200::-ms-input-placeholder{--placeholder-opacity:1;color:#b2f5ea;color:rgba(178,245,234,var(--placeholder-opacity))}.md\:placeholder-teal-200::placeholder{--placeholder-opacity:1;color:#b2f5ea;color:rgba(178,245,234,var(--placeholder-opacity))}.md\:placeholder-teal-300:-ms-input-placeholder{--placeholder-opacity:1;color:#81e6d9;color:rgba(129,230,217,var(--placeholder-opacity))}.md\:placeholder-teal-300::-ms-input-placeholder{--placeholder-opacity:1;color:#81e6d9;color:rgba(129,230,217,var(--placeholder-opacity))}.md\:placeholder-teal-300::placeholder{--placeholder-opacity:1;color:#81e6d9;color:rgba(129,230,217,var(--placeholder-opacity))}.md\:placeholder-teal-400:-ms-input-placeholder{--placeholder-opacity:1;color:#4fd1c5;color:rgba(79,209,197,var(--placeholder-opacity))}.md\:placeholder-teal-400::-ms-input-placeholder{--placeholder-opacity:1;color:#4fd1c5;color:rgba(79,209,197,var(--placeholder-opacity))}.md\:placeholder-teal-400::placeholder{--placeholder-opacity:1;color:#4fd1c5;color:rgba(79,209,197,var(--placeholder-opacity))}.md\:placeholder-teal-500:-ms-input-placeholder{--placeholder-opacity:1;color:#38b2ac;color:rgba(56,178,172,var(--placeholder-opacity))}.md\:placeholder-teal-500::-ms-input-placeholder{--placeholder-opacity:1;color:#38b2ac;color:rgba(56,178,172,var(--placeholder-opacity))}.md\:placeholder-teal-500::placeholder{--placeholder-opacity:1;color:#38b2ac;color:rgba(56,178,172,var(--placeholder-opacity))}.md\:placeholder-teal-600:-ms-input-placeholder{--placeholder-opacity:1;color:#319795;color:rgba(49,151,149,var(--placeholder-opacity))}.md\:placeholder-teal-600::-ms-input-placeholder{--placeholder-opacity:1;color:#319795;color:rgba(49,151,149,var(--placeholder-opacity))}.md\:placeholder-teal-600::placeholder{--placeholder-opacity:1;color:#319795;color:rgba(49,151,149,var(--placeholder-opacity))}.md\:placeholder-teal-700:-ms-input-placeholder{--placeholder-opacity:1;color:#2c7a7b;color:rgba(44,122,123,var(--placeholder-opacity))}.md\:placeholder-teal-700::-ms-input-placeholder{--placeholder-opacity:1;color:#2c7a7b;color:rgba(44,122,123,var(--placeholder-opacity))}.md\:placeholder-teal-700::placeholder{--placeholder-opacity:1;color:#2c7a7b;color:rgba(44,122,123,var(--placeholder-opacity))}.md\:placeholder-teal-800:-ms-input-placeholder{--placeholder-opacity:1;color:#285e61;color:rgba(40,94,97,var(--placeholder-opacity))}.md\:placeholder-teal-800::-ms-input-placeholder{--placeholder-opacity:1;color:#285e61;color:rgba(40,94,97,var(--placeholder-opacity))}.md\:placeholder-teal-800::placeholder{--placeholder-opacity:1;color:#285e61;color:rgba(40,94,97,var(--placeholder-opacity))}.md\:placeholder-teal-900:-ms-input-placeholder{--placeholder-opacity:1;color:#234e52;color:rgba(35,78,82,var(--placeholder-opacity))}.md\:placeholder-teal-900::-ms-input-placeholder{--placeholder-opacity:1;color:#234e52;color:rgba(35,78,82,var(--placeholder-opacity))}.md\:placeholder-teal-900::placeholder{--placeholder-opacity:1;color:#234e52;color:rgba(35,78,82,var(--placeholder-opacity))}.md\:placeholder-blue-100:-ms-input-placeholder{--placeholder-opacity:1;color:#ebf8ff;color:rgba(235,248,255,var(--placeholder-opacity))}.md\:placeholder-blue-100::-ms-input-placeholder{--placeholder-opacity:1;color:#ebf8ff;color:rgba(235,248,255,var(--placeholder-opacity))}.md\:placeholder-blue-100::placeholder{--placeholder-opacity:1;color:#ebf8ff;color:rgba(235,248,255,var(--placeholder-opacity))}.md\:placeholder-blue-200:-ms-input-placeholder{--placeholder-opacity:1;color:#bee3f8;color:rgba(190,227,248,var(--placeholder-opacity))}.md\:placeholder-blue-200::-ms-input-placeholder{--placeholder-opacity:1;color:#bee3f8;color:rgba(190,227,248,var(--placeholder-opacity))}.md\:placeholder-blue-200::placeholder{--placeholder-opacity:1;color:#bee3f8;color:rgba(190,227,248,var(--placeholder-opacity))}.md\:placeholder-blue-300:-ms-input-placeholder{--placeholder-opacity:1;color:#90cdf4;color:rgba(144,205,244,var(--placeholder-opacity))}.md\:placeholder-blue-300::-ms-input-placeholder{--placeholder-opacity:1;color:#90cdf4;color:rgba(144,205,244,var(--placeholder-opacity))}.md\:placeholder-blue-300::placeholder{--placeholder-opacity:1;color:#90cdf4;color:rgba(144,205,244,var(--placeholder-opacity))}.md\:placeholder-blue-400:-ms-input-placeholder{--placeholder-opacity:1;color:#63b3ed;color:rgba(99,179,237,var(--placeholder-opacity))}.md\:placeholder-blue-400::-ms-input-placeholder{--placeholder-opacity:1;color:#63b3ed;color:rgba(99,179,237,var(--placeholder-opacity))}.md\:placeholder-blue-400::placeholder{--placeholder-opacity:1;color:#63b3ed;color:rgba(99,179,237,var(--placeholder-opacity))}.md\:placeholder-blue-500:-ms-input-placeholder{--placeholder-opacity:1;color:#4299e1;color:rgba(66,153,225,var(--placeholder-opacity))}.md\:placeholder-blue-500::-ms-input-placeholder{--placeholder-opacity:1;color:#4299e1;color:rgba(66,153,225,var(--placeholder-opacity))}.md\:placeholder-blue-500::placeholder{--placeholder-opacity:1;color:#4299e1;color:rgba(66,153,225,var(--placeholder-opacity))}.md\:placeholder-blue-600:-ms-input-placeholder{--placeholder-opacity:1;color:#3182ce;color:rgba(49,130,206,var(--placeholder-opacity))}.md\:placeholder-blue-600::-ms-input-placeholder{--placeholder-opacity:1;color:#3182ce;color:rgba(49,130,206,var(--placeholder-opacity))}.md\:placeholder-blue-600::placeholder{--placeholder-opacity:1;color:#3182ce;color:rgba(49,130,206,var(--placeholder-opacity))}.md\:placeholder-blue-700:-ms-input-placeholder{--placeholder-opacity:1;color:#2b6cb0;color:rgba(43,108,176,var(--placeholder-opacity))}.md\:placeholder-blue-700::-ms-input-placeholder{--placeholder-opacity:1;color:#2b6cb0;color:rgba(43,108,176,var(--placeholder-opacity))}.md\:placeholder-blue-700::placeholder{--placeholder-opacity:1;color:#2b6cb0;color:rgba(43,108,176,var(--placeholder-opacity))}.md\:placeholder-blue-800:-ms-input-placeholder{--placeholder-opacity:1;color:#2c5282;color:rgba(44,82,130,var(--placeholder-opacity))}.md\:placeholder-blue-800::-ms-input-placeholder{--placeholder-opacity:1;color:#2c5282;color:rgba(44,82,130,var(--placeholder-opacity))}.md\:placeholder-blue-800::placeholder{--placeholder-opacity:1;color:#2c5282;color:rgba(44,82,130,var(--placeholder-opacity))}.md\:placeholder-blue-900:-ms-input-placeholder{--placeholder-opacity:1;color:#2a4365;color:rgba(42,67,101,var(--placeholder-opacity))}.md\:placeholder-blue-900::-ms-input-placeholder{--placeholder-opacity:1;color:#2a4365;color:rgba(42,67,101,var(--placeholder-opacity))}.md\:placeholder-blue-900::placeholder{--placeholder-opacity:1;color:#2a4365;color:rgba(42,67,101,var(--placeholder-opacity))}.md\:placeholder-indigo-100:-ms-input-placeholder{--placeholder-opacity:1;color:#ebf4ff;color:rgba(235,244,255,var(--placeholder-opacity))}.md\:placeholder-indigo-100::-ms-input-placeholder{--placeholder-opacity:1;color:#ebf4ff;color:rgba(235,244,255,var(--placeholder-opacity))}.md\:placeholder-indigo-100::placeholder{--placeholder-opacity:1;color:#ebf4ff;color:rgba(235,244,255,var(--placeholder-opacity))}.md\:placeholder-indigo-200:-ms-input-placeholder{--placeholder-opacity:1;color:#c3dafe;color:rgba(195,218,254,var(--placeholder-opacity))}.md\:placeholder-indigo-200::-ms-input-placeholder{--placeholder-opacity:1;color:#c3dafe;color:rgba(195,218,254,var(--placeholder-opacity))}.md\:placeholder-indigo-200::placeholder{--placeholder-opacity:1;color:#c3dafe;color:rgba(195,218,254,var(--placeholder-opacity))}.md\:placeholder-indigo-300:-ms-input-placeholder{--placeholder-opacity:1;color:#a3bffa;color:rgba(163,191,250,var(--placeholder-opacity))}.md\:placeholder-indigo-300::-ms-input-placeholder{--placeholder-opacity:1;color:#a3bffa;color:rgba(163,191,250,var(--placeholder-opacity))}.md\:placeholder-indigo-300::placeholder{--placeholder-opacity:1;color:#a3bffa;color:rgba(163,191,250,var(--placeholder-opacity))}.md\:placeholder-indigo-400:-ms-input-placeholder{--placeholder-opacity:1;color:#7f9cf5;color:rgba(127,156,245,var(--placeholder-opacity))}.md\:placeholder-indigo-400::-ms-input-placeholder{--placeholder-opacity:1;color:#7f9cf5;color:rgba(127,156,245,var(--placeholder-opacity))}.md\:placeholder-indigo-400::placeholder{--placeholder-opacity:1;color:#7f9cf5;color:rgba(127,156,245,var(--placeholder-opacity))}.md\:placeholder-indigo-500:-ms-input-placeholder{--placeholder-opacity:1;color:#667eea;color:rgba(102,126,234,var(--placeholder-opacity))}.md\:placeholder-indigo-500::-ms-input-placeholder{--placeholder-opacity:1;color:#667eea;color:rgba(102,126,234,var(--placeholder-opacity))}.md\:placeholder-indigo-500::placeholder{--placeholder-opacity:1;color:#667eea;color:rgba(102,126,234,var(--placeholder-opacity))}.md\:placeholder-indigo-600:-ms-input-placeholder{--placeholder-opacity:1;color:#5a67d8;color:rgba(90,103,216,var(--placeholder-opacity))}.md\:placeholder-indigo-600::-ms-input-placeholder{--placeholder-opacity:1;color:#5a67d8;color:rgba(90,103,216,var(--placeholder-opacity))}.md\:placeholder-indigo-600::placeholder{--placeholder-opacity:1;color:#5a67d8;color:rgba(90,103,216,var(--placeholder-opacity))}.md\:placeholder-indigo-700:-ms-input-placeholder{--placeholder-opacity:1;color:#4c51bf;color:rgba(76,81,191,var(--placeholder-opacity))}.md\:placeholder-indigo-700::-ms-input-placeholder{--placeholder-opacity:1;color:#4c51bf;color:rgba(76,81,191,var(--placeholder-opacity))}.md\:placeholder-indigo-700::placeholder{--placeholder-opacity:1;color:#4c51bf;color:rgba(76,81,191,var(--placeholder-opacity))}.md\:placeholder-indigo-800:-ms-input-placeholder{--placeholder-opacity:1;color:#434190;color:rgba(67,65,144,var(--placeholder-opacity))}.md\:placeholder-indigo-800::-ms-input-placeholder{--placeholder-opacity:1;color:#434190;color:rgba(67,65,144,var(--placeholder-opacity))}.md\:placeholder-indigo-800::placeholder{--placeholder-opacity:1;color:#434190;color:rgba(67,65,144,var(--placeholder-opacity))}.md\:placeholder-indigo-900:-ms-input-placeholder{--placeholder-opacity:1;color:#3c366b;color:rgba(60,54,107,var(--placeholder-opacity))}.md\:placeholder-indigo-900::-ms-input-placeholder{--placeholder-opacity:1;color:#3c366b;color:rgba(60,54,107,var(--placeholder-opacity))}.md\:placeholder-indigo-900::placeholder{--placeholder-opacity:1;color:#3c366b;color:rgba(60,54,107,var(--placeholder-opacity))}.md\:placeholder-purple-100:-ms-input-placeholder{--placeholder-opacity:1;color:#faf5ff;color:rgba(250,245,255,var(--placeholder-opacity))}.md\:placeholder-purple-100::-ms-input-placeholder{--placeholder-opacity:1;color:#faf5ff;color:rgba(250,245,255,var(--placeholder-opacity))}.md\:placeholder-purple-100::placeholder{--placeholder-opacity:1;color:#faf5ff;color:rgba(250,245,255,var(--placeholder-opacity))}.md\:placeholder-purple-200:-ms-input-placeholder{--placeholder-opacity:1;color:#e9d8fd;color:rgba(233,216,253,var(--placeholder-opacity))}.md\:placeholder-purple-200::-ms-input-placeholder{--placeholder-opacity:1;color:#e9d8fd;color:rgba(233,216,253,var(--placeholder-opacity))}.md\:placeholder-purple-200::placeholder{--placeholder-opacity:1;color:#e9d8fd;color:rgba(233,216,253,var(--placeholder-opacity))}.md\:placeholder-purple-300:-ms-input-placeholder{--placeholder-opacity:1;color:#d6bcfa;color:rgba(214,188,250,var(--placeholder-opacity))}.md\:placeholder-purple-300::-ms-input-placeholder{--placeholder-opacity:1;color:#d6bcfa;color:rgba(214,188,250,var(--placeholder-opacity))}.md\:placeholder-purple-300::placeholder{--placeholder-opacity:1;color:#d6bcfa;color:rgba(214,188,250,var(--placeholder-opacity))}.md\:placeholder-purple-400:-ms-input-placeholder{--placeholder-opacity:1;color:#b794f4;color:rgba(183,148,244,var(--placeholder-opacity))}.md\:placeholder-purple-400::-ms-input-placeholder{--placeholder-opacity:1;color:#b794f4;color:rgba(183,148,244,var(--placeholder-opacity))}.md\:placeholder-purple-400::placeholder{--placeholder-opacity:1;color:#b794f4;color:rgba(183,148,244,var(--placeholder-opacity))}.md\:placeholder-purple-500:-ms-input-placeholder{--placeholder-opacity:1;color:#9f7aea;color:rgba(159,122,234,var(--placeholder-opacity))}.md\:placeholder-purple-500::-ms-input-placeholder{--placeholder-opacity:1;color:#9f7aea;color:rgba(159,122,234,var(--placeholder-opacity))}.md\:placeholder-purple-500::placeholder{--placeholder-opacity:1;color:#9f7aea;color:rgba(159,122,234,var(--placeholder-opacity))}.md\:placeholder-purple-600:-ms-input-placeholder{--placeholder-opacity:1;color:#805ad5;color:rgba(128,90,213,var(--placeholder-opacity))}.md\:placeholder-purple-600::-ms-input-placeholder{--placeholder-opacity:1;color:#805ad5;color:rgba(128,90,213,var(--placeholder-opacity))}.md\:placeholder-purple-600::placeholder{--placeholder-opacity:1;color:#805ad5;color:rgba(128,90,213,var(--placeholder-opacity))}.md\:placeholder-purple-700:-ms-input-placeholder{--placeholder-opacity:1;color:#6b46c1;color:rgba(107,70,193,var(--placeholder-opacity))}.md\:placeholder-purple-700::-ms-input-placeholder{--placeholder-opacity:1;color:#6b46c1;color:rgba(107,70,193,var(--placeholder-opacity))}.md\:placeholder-purple-700::placeholder{--placeholder-opacity:1;color:#6b46c1;color:rgba(107,70,193,var(--placeholder-opacity))}.md\:placeholder-purple-800:-ms-input-placeholder{--placeholder-opacity:1;color:#553c9a;color:rgba(85,60,154,var(--placeholder-opacity))}.md\:placeholder-purple-800::-ms-input-placeholder{--placeholder-opacity:1;color:#553c9a;color:rgba(85,60,154,var(--placeholder-opacity))}.md\:placeholder-purple-800::placeholder{--placeholder-opacity:1;color:#553c9a;color:rgba(85,60,154,var(--placeholder-opacity))}.md\:placeholder-purple-900:-ms-input-placeholder{--placeholder-opacity:1;color:#44337a;color:rgba(68,51,122,var(--placeholder-opacity))}.md\:placeholder-purple-900::-ms-input-placeholder{--placeholder-opacity:1;color:#44337a;color:rgba(68,51,122,var(--placeholder-opacity))}.md\:placeholder-purple-900::placeholder{--placeholder-opacity:1;color:#44337a;color:rgba(68,51,122,var(--placeholder-opacity))}.md\:placeholder-pink-100:-ms-input-placeholder{--placeholder-opacity:1;color:#fff5f7;color:rgba(255,245,247,var(--placeholder-opacity))}.md\:placeholder-pink-100::-ms-input-placeholder{--placeholder-opacity:1;color:#fff5f7;color:rgba(255,245,247,var(--placeholder-opacity))}.md\:placeholder-pink-100::placeholder{--placeholder-opacity:1;color:#fff5f7;color:rgba(255,245,247,var(--placeholder-opacity))}.md\:placeholder-pink-200:-ms-input-placeholder{--placeholder-opacity:1;color:#fed7e2;color:rgba(254,215,226,var(--placeholder-opacity))}.md\:placeholder-pink-200::-ms-input-placeholder{--placeholder-opacity:1;color:#fed7e2;color:rgba(254,215,226,var(--placeholder-opacity))}.md\:placeholder-pink-200::placeholder{--placeholder-opacity:1;color:#fed7e2;color:rgba(254,215,226,var(--placeholder-opacity))}.md\:placeholder-pink-300:-ms-input-placeholder{--placeholder-opacity:1;color:#fbb6ce;color:rgba(251,182,206,var(--placeholder-opacity))}.md\:placeholder-pink-300::-ms-input-placeholder{--placeholder-opacity:1;color:#fbb6ce;color:rgba(251,182,206,var(--placeholder-opacity))}.md\:placeholder-pink-300::placeholder{--placeholder-opacity:1;color:#fbb6ce;color:rgba(251,182,206,var(--placeholder-opacity))}.md\:placeholder-pink-400:-ms-input-placeholder{--placeholder-opacity:1;color:#f687b3;color:rgba(246,135,179,var(--placeholder-opacity))}.md\:placeholder-pink-400::-ms-input-placeholder{--placeholder-opacity:1;color:#f687b3;color:rgba(246,135,179,var(--placeholder-opacity))}.md\:placeholder-pink-400::placeholder{--placeholder-opacity:1;color:#f687b3;color:rgba(246,135,179,var(--placeholder-opacity))}.md\:placeholder-pink-500:-ms-input-placeholder{--placeholder-opacity:1;color:#ed64a6;color:rgba(237,100,166,var(--placeholder-opacity))}.md\:placeholder-pink-500::-ms-input-placeholder{--placeholder-opacity:1;color:#ed64a6;color:rgba(237,100,166,var(--placeholder-opacity))}.md\:placeholder-pink-500::placeholder{--placeholder-opacity:1;color:#ed64a6;color:rgba(237,100,166,var(--placeholder-opacity))}.md\:placeholder-pink-600:-ms-input-placeholder{--placeholder-opacity:1;color:#d53f8c;color:rgba(213,63,140,var(--placeholder-opacity))}.md\:placeholder-pink-600::-ms-input-placeholder{--placeholder-opacity:1;color:#d53f8c;color:rgba(213,63,140,var(--placeholder-opacity))}.md\:placeholder-pink-600::placeholder{--placeholder-opacity:1;color:#d53f8c;color:rgba(213,63,140,var(--placeholder-opacity))}.md\:placeholder-pink-700:-ms-input-placeholder{--placeholder-opacity:1;color:#b83280;color:rgba(184,50,128,var(--placeholder-opacity))}.md\:placeholder-pink-700::-ms-input-placeholder{--placeholder-opacity:1;color:#b83280;color:rgba(184,50,128,var(--placeholder-opacity))}.md\:placeholder-pink-700::placeholder{--placeholder-opacity:1;color:#b83280;color:rgba(184,50,128,var(--placeholder-opacity))}.md\:placeholder-pink-800:-ms-input-placeholder{--placeholder-opacity:1;color:#97266d;color:rgba(151,38,109,var(--placeholder-opacity))}.md\:placeholder-pink-800::-ms-input-placeholder{--placeholder-opacity:1;color:#97266d;color:rgba(151,38,109,var(--placeholder-opacity))}.md\:placeholder-pink-800::placeholder{--placeholder-opacity:1;color:#97266d;color:rgba(151,38,109,var(--placeholder-opacity))}.md\:placeholder-pink-900:-ms-input-placeholder{--placeholder-opacity:1;color:#702459;color:rgba(112,36,89,var(--placeholder-opacity))}.md\:placeholder-pink-900::-ms-input-placeholder{--placeholder-opacity:1;color:#702459;color:rgba(112,36,89,var(--placeholder-opacity))}.md\:placeholder-pink-900::placeholder{--placeholder-opacity:1;color:#702459;color:rgba(112,36,89,var(--placeholder-opacity))}.md\:focus\:placeholder-transparent:focus:-ms-input-placeholder{color:transparent}.md\:focus\:placeholder-transparent:focus::-ms-input-placeholder{color:transparent}.md\:focus\:placeholder-transparent:focus::placeholder{color:transparent}.md\:focus\:placeholder-current:focus:-ms-input-placeholder{color:currentColor}.md\:focus\:placeholder-current:focus::-ms-input-placeholder{color:currentColor}.md\:focus\:placeholder-current:focus::placeholder{color:currentColor}.md\:focus\:placeholder-black:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#000;color:rgba(0,0,0,var(--placeholder-opacity))}.md\:focus\:placeholder-black:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#000;color:rgba(0,0,0,var(--placeholder-opacity))}.md\:focus\:placeholder-black:focus::placeholder{--placeholder-opacity:1;color:#000;color:rgba(0,0,0,var(--placeholder-opacity))}.md\:focus\:placeholder-white:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#fff;color:rgba(255,255,255,var(--placeholder-opacity))}.md\:focus\:placeholder-white:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#fff;color:rgba(255,255,255,var(--placeholder-opacity))}.md\:focus\:placeholder-white:focus::placeholder{--placeholder-opacity:1;color:#fff;color:rgba(255,255,255,var(--placeholder-opacity))}.md\:focus\:placeholder-gray-100:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#f7fafc;color:rgba(247,250,252,var(--placeholder-opacity))}.md\:focus\:placeholder-gray-100:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#f7fafc;color:rgba(247,250,252,var(--placeholder-opacity))}.md\:focus\:placeholder-gray-100:focus::placeholder{--placeholder-opacity:1;color:#f7fafc;color:rgba(247,250,252,var(--placeholder-opacity))}.md\:focus\:placeholder-gray-200:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#edf2f7;color:rgba(237,242,247,var(--placeholder-opacity))}.md\:focus\:placeholder-gray-200:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#edf2f7;color:rgba(237,242,247,var(--placeholder-opacity))}.md\:focus\:placeholder-gray-200:focus::placeholder{--placeholder-opacity:1;color:#edf2f7;color:rgba(237,242,247,var(--placeholder-opacity))}.md\:focus\:placeholder-gray-300:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#e2e8f0;color:rgba(226,232,240,var(--placeholder-opacity))}.md\:focus\:placeholder-gray-300:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#e2e8f0;color:rgba(226,232,240,var(--placeholder-opacity))}.md\:focus\:placeholder-gray-300:focus::placeholder{--placeholder-opacity:1;color:#e2e8f0;color:rgba(226,232,240,var(--placeholder-opacity))}.md\:focus\:placeholder-gray-400:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#cbd5e0;color:rgba(203,213,224,var(--placeholder-opacity))}.md\:focus\:placeholder-gray-400:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#cbd5e0;color:rgba(203,213,224,var(--placeholder-opacity))}.md\:focus\:placeholder-gray-400:focus::placeholder{--placeholder-opacity:1;color:#cbd5e0;color:rgba(203,213,224,var(--placeholder-opacity))}.md\:focus\:placeholder-gray-500:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#a0aec0;color:rgba(160,174,192,var(--placeholder-opacity))}.md\:focus\:placeholder-gray-500:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#a0aec0;color:rgba(160,174,192,var(--placeholder-opacity))}.md\:focus\:placeholder-gray-500:focus::placeholder{--placeholder-opacity:1;color:#a0aec0;color:rgba(160,174,192,var(--placeholder-opacity))}.md\:focus\:placeholder-gray-600:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#718096;color:rgba(113,128,150,var(--placeholder-opacity))}.md\:focus\:placeholder-gray-600:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#718096;color:rgba(113,128,150,var(--placeholder-opacity))}.md\:focus\:placeholder-gray-600:focus::placeholder{--placeholder-opacity:1;color:#718096;color:rgba(113,128,150,var(--placeholder-opacity))}.md\:focus\:placeholder-gray-700:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#4a5568;color:rgba(74,85,104,var(--placeholder-opacity))}.md\:focus\:placeholder-gray-700:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#4a5568;color:rgba(74,85,104,var(--placeholder-opacity))}.md\:focus\:placeholder-gray-700:focus::placeholder{--placeholder-opacity:1;color:#4a5568;color:rgba(74,85,104,var(--placeholder-opacity))}.md\:focus\:placeholder-gray-800:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#2d3748;color:rgba(45,55,72,var(--placeholder-opacity))}.md\:focus\:placeholder-gray-800:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#2d3748;color:rgba(45,55,72,var(--placeholder-opacity))}.md\:focus\:placeholder-gray-800:focus::placeholder{--placeholder-opacity:1;color:#2d3748;color:rgba(45,55,72,var(--placeholder-opacity))}.md\:focus\:placeholder-gray-900:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#1a202c;color:rgba(26,32,44,var(--placeholder-opacity))}.md\:focus\:placeholder-gray-900:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#1a202c;color:rgba(26,32,44,var(--placeholder-opacity))}.md\:focus\:placeholder-gray-900:focus::placeholder{--placeholder-opacity:1;color:#1a202c;color:rgba(26,32,44,var(--placeholder-opacity))}.md\:focus\:placeholder-red-100:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#fff5f5;color:rgba(255,245,245,var(--placeholder-opacity))}.md\:focus\:placeholder-red-100:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#fff5f5;color:rgba(255,245,245,var(--placeholder-opacity))}.md\:focus\:placeholder-red-100:focus::placeholder{--placeholder-opacity:1;color:#fff5f5;color:rgba(255,245,245,var(--placeholder-opacity))}.md\:focus\:placeholder-red-200:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#fed7d7;color:rgba(254,215,215,var(--placeholder-opacity))}.md\:focus\:placeholder-red-200:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#fed7d7;color:rgba(254,215,215,var(--placeholder-opacity))}.md\:focus\:placeholder-red-200:focus::placeholder{--placeholder-opacity:1;color:#fed7d7;color:rgba(254,215,215,var(--placeholder-opacity))}.md\:focus\:placeholder-red-300:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#feb2b2;color:rgba(254,178,178,var(--placeholder-opacity))}.md\:focus\:placeholder-red-300:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#feb2b2;color:rgba(254,178,178,var(--placeholder-opacity))}.md\:focus\:placeholder-red-300:focus::placeholder{--placeholder-opacity:1;color:#feb2b2;color:rgba(254,178,178,var(--placeholder-opacity))}.md\:focus\:placeholder-red-400:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#fc8181;color:rgba(252,129,129,var(--placeholder-opacity))}.md\:focus\:placeholder-red-400:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#fc8181;color:rgba(252,129,129,var(--placeholder-opacity))}.md\:focus\:placeholder-red-400:focus::placeholder{--placeholder-opacity:1;color:#fc8181;color:rgba(252,129,129,var(--placeholder-opacity))}.md\:focus\:placeholder-red-500:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#f56565;color:rgba(245,101,101,var(--placeholder-opacity))}.md\:focus\:placeholder-red-500:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#f56565;color:rgba(245,101,101,var(--placeholder-opacity))}.md\:focus\:placeholder-red-500:focus::placeholder{--placeholder-opacity:1;color:#f56565;color:rgba(245,101,101,var(--placeholder-opacity))}.md\:focus\:placeholder-red-600:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#e53e3e;color:rgba(229,62,62,var(--placeholder-opacity))}.md\:focus\:placeholder-red-600:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#e53e3e;color:rgba(229,62,62,var(--placeholder-opacity))}.md\:focus\:placeholder-red-600:focus::placeholder{--placeholder-opacity:1;color:#e53e3e;color:rgba(229,62,62,var(--placeholder-opacity))}.md\:focus\:placeholder-red-700:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#c53030;color:rgba(197,48,48,var(--placeholder-opacity))}.md\:focus\:placeholder-red-700:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#c53030;color:rgba(197,48,48,var(--placeholder-opacity))}.md\:focus\:placeholder-red-700:focus::placeholder{--placeholder-opacity:1;color:#c53030;color:rgba(197,48,48,var(--placeholder-opacity))}.md\:focus\:placeholder-red-800:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#9b2c2c;color:rgba(155,44,44,var(--placeholder-opacity))}.md\:focus\:placeholder-red-800:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#9b2c2c;color:rgba(155,44,44,var(--placeholder-opacity))}.md\:focus\:placeholder-red-800:focus::placeholder{--placeholder-opacity:1;color:#9b2c2c;color:rgba(155,44,44,var(--placeholder-opacity))}.md\:focus\:placeholder-red-900:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#742a2a;color:rgba(116,42,42,var(--placeholder-opacity))}.md\:focus\:placeholder-red-900:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#742a2a;color:rgba(116,42,42,var(--placeholder-opacity))}.md\:focus\:placeholder-red-900:focus::placeholder{--placeholder-opacity:1;color:#742a2a;color:rgba(116,42,42,var(--placeholder-opacity))}.md\:focus\:placeholder-orange-100:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#fffaf0;color:rgba(255,250,240,var(--placeholder-opacity))}.md\:focus\:placeholder-orange-100:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#fffaf0;color:rgba(255,250,240,var(--placeholder-opacity))}.md\:focus\:placeholder-orange-100:focus::placeholder{--placeholder-opacity:1;color:#fffaf0;color:rgba(255,250,240,var(--placeholder-opacity))}.md\:focus\:placeholder-orange-200:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#feebc8;color:rgba(254,235,200,var(--placeholder-opacity))}.md\:focus\:placeholder-orange-200:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#feebc8;color:rgba(254,235,200,var(--placeholder-opacity))}.md\:focus\:placeholder-orange-200:focus::placeholder{--placeholder-opacity:1;color:#feebc8;color:rgba(254,235,200,var(--placeholder-opacity))}.md\:focus\:placeholder-orange-300:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#fbd38d;color:rgba(251,211,141,var(--placeholder-opacity))}.md\:focus\:placeholder-orange-300:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#fbd38d;color:rgba(251,211,141,var(--placeholder-opacity))}.md\:focus\:placeholder-orange-300:focus::placeholder{--placeholder-opacity:1;color:#fbd38d;color:rgba(251,211,141,var(--placeholder-opacity))}.md\:focus\:placeholder-orange-400:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#f6ad55;color:rgba(246,173,85,var(--placeholder-opacity))}.md\:focus\:placeholder-orange-400:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#f6ad55;color:rgba(246,173,85,var(--placeholder-opacity))}.md\:focus\:placeholder-orange-400:focus::placeholder{--placeholder-opacity:1;color:#f6ad55;color:rgba(246,173,85,var(--placeholder-opacity))}.md\:focus\:placeholder-orange-500:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#ed8936;color:rgba(237,137,54,var(--placeholder-opacity))}.md\:focus\:placeholder-orange-500:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#ed8936;color:rgba(237,137,54,var(--placeholder-opacity))}.md\:focus\:placeholder-orange-500:focus::placeholder{--placeholder-opacity:1;color:#ed8936;color:rgba(237,137,54,var(--placeholder-opacity))}.md\:focus\:placeholder-orange-600:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#dd6b20;color:rgba(221,107,32,var(--placeholder-opacity))}.md\:focus\:placeholder-orange-600:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#dd6b20;color:rgba(221,107,32,var(--placeholder-opacity))}.md\:focus\:placeholder-orange-600:focus::placeholder{--placeholder-opacity:1;color:#dd6b20;color:rgba(221,107,32,var(--placeholder-opacity))}.md\:focus\:placeholder-orange-700:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#c05621;color:rgba(192,86,33,var(--placeholder-opacity))}.md\:focus\:placeholder-orange-700:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#c05621;color:rgba(192,86,33,var(--placeholder-opacity))}.md\:focus\:placeholder-orange-700:focus::placeholder{--placeholder-opacity:1;color:#c05621;color:rgba(192,86,33,var(--placeholder-opacity))}.md\:focus\:placeholder-orange-800:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#9c4221;color:rgba(156,66,33,var(--placeholder-opacity))}.md\:focus\:placeholder-orange-800:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#9c4221;color:rgba(156,66,33,var(--placeholder-opacity))}.md\:focus\:placeholder-orange-800:focus::placeholder{--placeholder-opacity:1;color:#9c4221;color:rgba(156,66,33,var(--placeholder-opacity))}.md\:focus\:placeholder-orange-900:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#7b341e;color:rgba(123,52,30,var(--placeholder-opacity))}.md\:focus\:placeholder-orange-900:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#7b341e;color:rgba(123,52,30,var(--placeholder-opacity))}.md\:focus\:placeholder-orange-900:focus::placeholder{--placeholder-opacity:1;color:#7b341e;color:rgba(123,52,30,var(--placeholder-opacity))}.md\:focus\:placeholder-yellow-100:focus:-ms-input-placeholder{--placeholder-opacity:1;color:ivory;color:rgba(255,255,240,var(--placeholder-opacity))}.md\:focus\:placeholder-yellow-100:focus::-ms-input-placeholder{--placeholder-opacity:1;color:ivory;color:rgba(255,255,240,var(--placeholder-opacity))}.md\:focus\:placeholder-yellow-100:focus::placeholder{--placeholder-opacity:1;color:ivory;color:rgba(255,255,240,var(--placeholder-opacity))}.md\:focus\:placeholder-yellow-200:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#fefcbf;color:rgba(254,252,191,var(--placeholder-opacity))}.md\:focus\:placeholder-yellow-200:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#fefcbf;color:rgba(254,252,191,var(--placeholder-opacity))}.md\:focus\:placeholder-yellow-200:focus::placeholder{--placeholder-opacity:1;color:#fefcbf;color:rgba(254,252,191,var(--placeholder-opacity))}.md\:focus\:placeholder-yellow-300:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#faf089;color:rgba(250,240,137,var(--placeholder-opacity))}.md\:focus\:placeholder-yellow-300:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#faf089;color:rgba(250,240,137,var(--placeholder-opacity))}.md\:focus\:placeholder-yellow-300:focus::placeholder{--placeholder-opacity:1;color:#faf089;color:rgba(250,240,137,var(--placeholder-opacity))}.md\:focus\:placeholder-yellow-400:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#f6e05e;color:rgba(246,224,94,var(--placeholder-opacity))}.md\:focus\:placeholder-yellow-400:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#f6e05e;color:rgba(246,224,94,var(--placeholder-opacity))}.md\:focus\:placeholder-yellow-400:focus::placeholder{--placeholder-opacity:1;color:#f6e05e;color:rgba(246,224,94,var(--placeholder-opacity))}.md\:focus\:placeholder-yellow-500:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#ecc94b;color:rgba(236,201,75,var(--placeholder-opacity))}.md\:focus\:placeholder-yellow-500:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#ecc94b;color:rgba(236,201,75,var(--placeholder-opacity))}.md\:focus\:placeholder-yellow-500:focus::placeholder{--placeholder-opacity:1;color:#ecc94b;color:rgba(236,201,75,var(--placeholder-opacity))}.md\:focus\:placeholder-yellow-600:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#d69e2e;color:rgba(214,158,46,var(--placeholder-opacity))}.md\:focus\:placeholder-yellow-600:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#d69e2e;color:rgba(214,158,46,var(--placeholder-opacity))}.md\:focus\:placeholder-yellow-600:focus::placeholder{--placeholder-opacity:1;color:#d69e2e;color:rgba(214,158,46,var(--placeholder-opacity))}.md\:focus\:placeholder-yellow-700:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#b7791f;color:rgba(183,121,31,var(--placeholder-opacity))}.md\:focus\:placeholder-yellow-700:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#b7791f;color:rgba(183,121,31,var(--placeholder-opacity))}.md\:focus\:placeholder-yellow-700:focus::placeholder{--placeholder-opacity:1;color:#b7791f;color:rgba(183,121,31,var(--placeholder-opacity))}.md\:focus\:placeholder-yellow-800:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#975a16;color:rgba(151,90,22,var(--placeholder-opacity))}.md\:focus\:placeholder-yellow-800:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#975a16;color:rgba(151,90,22,var(--placeholder-opacity))}.md\:focus\:placeholder-yellow-800:focus::placeholder{--placeholder-opacity:1;color:#975a16;color:rgba(151,90,22,var(--placeholder-opacity))}.md\:focus\:placeholder-yellow-900:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#744210;color:rgba(116,66,16,var(--placeholder-opacity))}.md\:focus\:placeholder-yellow-900:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#744210;color:rgba(116,66,16,var(--placeholder-opacity))}.md\:focus\:placeholder-yellow-900:focus::placeholder{--placeholder-opacity:1;color:#744210;color:rgba(116,66,16,var(--placeholder-opacity))}.md\:focus\:placeholder-green-100:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#f0fff4;color:rgba(240,255,244,var(--placeholder-opacity))}.md\:focus\:placeholder-green-100:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#f0fff4;color:rgba(240,255,244,var(--placeholder-opacity))}.md\:focus\:placeholder-green-100:focus::placeholder{--placeholder-opacity:1;color:#f0fff4;color:rgba(240,255,244,var(--placeholder-opacity))}.md\:focus\:placeholder-green-200:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#c6f6d5;color:rgba(198,246,213,var(--placeholder-opacity))}.md\:focus\:placeholder-green-200:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#c6f6d5;color:rgba(198,246,213,var(--placeholder-opacity))}.md\:focus\:placeholder-green-200:focus::placeholder{--placeholder-opacity:1;color:#c6f6d5;color:rgba(198,246,213,var(--placeholder-opacity))}.md\:focus\:placeholder-green-300:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#9ae6b4;color:rgba(154,230,180,var(--placeholder-opacity))}.md\:focus\:placeholder-green-300:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#9ae6b4;color:rgba(154,230,180,var(--placeholder-opacity))}.md\:focus\:placeholder-green-300:focus::placeholder{--placeholder-opacity:1;color:#9ae6b4;color:rgba(154,230,180,var(--placeholder-opacity))}.md\:focus\:placeholder-green-400:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#68d391;color:rgba(104,211,145,var(--placeholder-opacity))}.md\:focus\:placeholder-green-400:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#68d391;color:rgba(104,211,145,var(--placeholder-opacity))}.md\:focus\:placeholder-green-400:focus::placeholder{--placeholder-opacity:1;color:#68d391;color:rgba(104,211,145,var(--placeholder-opacity))}.md\:focus\:placeholder-green-500:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#48bb78;color:rgba(72,187,120,var(--placeholder-opacity))}.md\:focus\:placeholder-green-500:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#48bb78;color:rgba(72,187,120,var(--placeholder-opacity))}.md\:focus\:placeholder-green-500:focus::placeholder{--placeholder-opacity:1;color:#48bb78;color:rgba(72,187,120,var(--placeholder-opacity))}.md\:focus\:placeholder-green-600:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#38a169;color:rgba(56,161,105,var(--placeholder-opacity))}.md\:focus\:placeholder-green-600:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#38a169;color:rgba(56,161,105,var(--placeholder-opacity))}.md\:focus\:placeholder-green-600:focus::placeholder{--placeholder-opacity:1;color:#38a169;color:rgba(56,161,105,var(--placeholder-opacity))}.md\:focus\:placeholder-green-700:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#2f855a;color:rgba(47,133,90,var(--placeholder-opacity))}.md\:focus\:placeholder-green-700:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#2f855a;color:rgba(47,133,90,var(--placeholder-opacity))}.md\:focus\:placeholder-green-700:focus::placeholder{--placeholder-opacity:1;color:#2f855a;color:rgba(47,133,90,var(--placeholder-opacity))}.md\:focus\:placeholder-green-800:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#276749;color:rgba(39,103,73,var(--placeholder-opacity))}.md\:focus\:placeholder-green-800:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#276749;color:rgba(39,103,73,var(--placeholder-opacity))}.md\:focus\:placeholder-green-800:focus::placeholder{--placeholder-opacity:1;color:#276749;color:rgba(39,103,73,var(--placeholder-opacity))}.md\:focus\:placeholder-green-900:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#22543d;color:rgba(34,84,61,var(--placeholder-opacity))}.md\:focus\:placeholder-green-900:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#22543d;color:rgba(34,84,61,var(--placeholder-opacity))}.md\:focus\:placeholder-green-900:focus::placeholder{--placeholder-opacity:1;color:#22543d;color:rgba(34,84,61,var(--placeholder-opacity))}.md\:focus\:placeholder-teal-100:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#e6fffa;color:rgba(230,255,250,var(--placeholder-opacity))}.md\:focus\:placeholder-teal-100:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#e6fffa;color:rgba(230,255,250,var(--placeholder-opacity))}.md\:focus\:placeholder-teal-100:focus::placeholder{--placeholder-opacity:1;color:#e6fffa;color:rgba(230,255,250,var(--placeholder-opacity))}.md\:focus\:placeholder-teal-200:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#b2f5ea;color:rgba(178,245,234,var(--placeholder-opacity))}.md\:focus\:placeholder-teal-200:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#b2f5ea;color:rgba(178,245,234,var(--placeholder-opacity))}.md\:focus\:placeholder-teal-200:focus::placeholder{--placeholder-opacity:1;color:#b2f5ea;color:rgba(178,245,234,var(--placeholder-opacity))}.md\:focus\:placeholder-teal-300:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#81e6d9;color:rgba(129,230,217,var(--placeholder-opacity))}.md\:focus\:placeholder-teal-300:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#81e6d9;color:rgba(129,230,217,var(--placeholder-opacity))}.md\:focus\:placeholder-teal-300:focus::placeholder{--placeholder-opacity:1;color:#81e6d9;color:rgba(129,230,217,var(--placeholder-opacity))}.md\:focus\:placeholder-teal-400:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#4fd1c5;color:rgba(79,209,197,var(--placeholder-opacity))}.md\:focus\:placeholder-teal-400:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#4fd1c5;color:rgba(79,209,197,var(--placeholder-opacity))}.md\:focus\:placeholder-teal-400:focus::placeholder{--placeholder-opacity:1;color:#4fd1c5;color:rgba(79,209,197,var(--placeholder-opacity))}.md\:focus\:placeholder-teal-500:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#38b2ac;color:rgba(56,178,172,var(--placeholder-opacity))}.md\:focus\:placeholder-teal-500:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#38b2ac;color:rgba(56,178,172,var(--placeholder-opacity))}.md\:focus\:placeholder-teal-500:focus::placeholder{--placeholder-opacity:1;color:#38b2ac;color:rgba(56,178,172,var(--placeholder-opacity))}.md\:focus\:placeholder-teal-600:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#319795;color:rgba(49,151,149,var(--placeholder-opacity))}.md\:focus\:placeholder-teal-600:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#319795;color:rgba(49,151,149,var(--placeholder-opacity))}.md\:focus\:placeholder-teal-600:focus::placeholder{--placeholder-opacity:1;color:#319795;color:rgba(49,151,149,var(--placeholder-opacity))}.md\:focus\:placeholder-teal-700:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#2c7a7b;color:rgba(44,122,123,var(--placeholder-opacity))}.md\:focus\:placeholder-teal-700:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#2c7a7b;color:rgba(44,122,123,var(--placeholder-opacity))}.md\:focus\:placeholder-teal-700:focus::placeholder{--placeholder-opacity:1;color:#2c7a7b;color:rgba(44,122,123,var(--placeholder-opacity))}.md\:focus\:placeholder-teal-800:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#285e61;color:rgba(40,94,97,var(--placeholder-opacity))}.md\:focus\:placeholder-teal-800:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#285e61;color:rgba(40,94,97,var(--placeholder-opacity))}.md\:focus\:placeholder-teal-800:focus::placeholder{--placeholder-opacity:1;color:#285e61;color:rgba(40,94,97,var(--placeholder-opacity))}.md\:focus\:placeholder-teal-900:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#234e52;color:rgba(35,78,82,var(--placeholder-opacity))}.md\:focus\:placeholder-teal-900:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#234e52;color:rgba(35,78,82,var(--placeholder-opacity))}.md\:focus\:placeholder-teal-900:focus::placeholder{--placeholder-opacity:1;color:#234e52;color:rgba(35,78,82,var(--placeholder-opacity))}.md\:focus\:placeholder-blue-100:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#ebf8ff;color:rgba(235,248,255,var(--placeholder-opacity))}.md\:focus\:placeholder-blue-100:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#ebf8ff;color:rgba(235,248,255,var(--placeholder-opacity))}.md\:focus\:placeholder-blue-100:focus::placeholder{--placeholder-opacity:1;color:#ebf8ff;color:rgba(235,248,255,var(--placeholder-opacity))}.md\:focus\:placeholder-blue-200:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#bee3f8;color:rgba(190,227,248,var(--placeholder-opacity))}.md\:focus\:placeholder-blue-200:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#bee3f8;color:rgba(190,227,248,var(--placeholder-opacity))}.md\:focus\:placeholder-blue-200:focus::placeholder{--placeholder-opacity:1;color:#bee3f8;color:rgba(190,227,248,var(--placeholder-opacity))}.md\:focus\:placeholder-blue-300:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#90cdf4;color:rgba(144,205,244,var(--placeholder-opacity))}.md\:focus\:placeholder-blue-300:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#90cdf4;color:rgba(144,205,244,var(--placeholder-opacity))}.md\:focus\:placeholder-blue-300:focus::placeholder{--placeholder-opacity:1;color:#90cdf4;color:rgba(144,205,244,var(--placeholder-opacity))}.md\:focus\:placeholder-blue-400:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#63b3ed;color:rgba(99,179,237,var(--placeholder-opacity))}.md\:focus\:placeholder-blue-400:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#63b3ed;color:rgba(99,179,237,var(--placeholder-opacity))}.md\:focus\:placeholder-blue-400:focus::placeholder{--placeholder-opacity:1;color:#63b3ed;color:rgba(99,179,237,var(--placeholder-opacity))}.md\:focus\:placeholder-blue-500:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#4299e1;color:rgba(66,153,225,var(--placeholder-opacity))}.md\:focus\:placeholder-blue-500:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#4299e1;color:rgba(66,153,225,var(--placeholder-opacity))}.md\:focus\:placeholder-blue-500:focus::placeholder{--placeholder-opacity:1;color:#4299e1;color:rgba(66,153,225,var(--placeholder-opacity))}.md\:focus\:placeholder-blue-600:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#3182ce;color:rgba(49,130,206,var(--placeholder-opacity))}.md\:focus\:placeholder-blue-600:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#3182ce;color:rgba(49,130,206,var(--placeholder-opacity))}.md\:focus\:placeholder-blue-600:focus::placeholder{--placeholder-opacity:1;color:#3182ce;color:rgba(49,130,206,var(--placeholder-opacity))}.md\:focus\:placeholder-blue-700:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#2b6cb0;color:rgba(43,108,176,var(--placeholder-opacity))}.md\:focus\:placeholder-blue-700:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#2b6cb0;color:rgba(43,108,176,var(--placeholder-opacity))}.md\:focus\:placeholder-blue-700:focus::placeholder{--placeholder-opacity:1;color:#2b6cb0;color:rgba(43,108,176,var(--placeholder-opacity))}.md\:focus\:placeholder-blue-800:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#2c5282;color:rgba(44,82,130,var(--placeholder-opacity))}.md\:focus\:placeholder-blue-800:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#2c5282;color:rgba(44,82,130,var(--placeholder-opacity))}.md\:focus\:placeholder-blue-800:focus::placeholder{--placeholder-opacity:1;color:#2c5282;color:rgba(44,82,130,var(--placeholder-opacity))}.md\:focus\:placeholder-blue-900:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#2a4365;color:rgba(42,67,101,var(--placeholder-opacity))}.md\:focus\:placeholder-blue-900:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#2a4365;color:rgba(42,67,101,var(--placeholder-opacity))}.md\:focus\:placeholder-blue-900:focus::placeholder{--placeholder-opacity:1;color:#2a4365;color:rgba(42,67,101,var(--placeholder-opacity))}.md\:focus\:placeholder-indigo-100:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#ebf4ff;color:rgba(235,244,255,var(--placeholder-opacity))}.md\:focus\:placeholder-indigo-100:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#ebf4ff;color:rgba(235,244,255,var(--placeholder-opacity))}.md\:focus\:placeholder-indigo-100:focus::placeholder{--placeholder-opacity:1;color:#ebf4ff;color:rgba(235,244,255,var(--placeholder-opacity))}.md\:focus\:placeholder-indigo-200:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#c3dafe;color:rgba(195,218,254,var(--placeholder-opacity))}.md\:focus\:placeholder-indigo-200:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#c3dafe;color:rgba(195,218,254,var(--placeholder-opacity))}.md\:focus\:placeholder-indigo-200:focus::placeholder{--placeholder-opacity:1;color:#c3dafe;color:rgba(195,218,254,var(--placeholder-opacity))}.md\:focus\:placeholder-indigo-300:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#a3bffa;color:rgba(163,191,250,var(--placeholder-opacity))}.md\:focus\:placeholder-indigo-300:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#a3bffa;color:rgba(163,191,250,var(--placeholder-opacity))}.md\:focus\:placeholder-indigo-300:focus::placeholder{--placeholder-opacity:1;color:#a3bffa;color:rgba(163,191,250,var(--placeholder-opacity))}.md\:focus\:placeholder-indigo-400:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#7f9cf5;color:rgba(127,156,245,var(--placeholder-opacity))}.md\:focus\:placeholder-indigo-400:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#7f9cf5;color:rgba(127,156,245,var(--placeholder-opacity))}.md\:focus\:placeholder-indigo-400:focus::placeholder{--placeholder-opacity:1;color:#7f9cf5;color:rgba(127,156,245,var(--placeholder-opacity))}.md\:focus\:placeholder-indigo-500:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#667eea;color:rgba(102,126,234,var(--placeholder-opacity))}.md\:focus\:placeholder-indigo-500:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#667eea;color:rgba(102,126,234,var(--placeholder-opacity))}.md\:focus\:placeholder-indigo-500:focus::placeholder{--placeholder-opacity:1;color:#667eea;color:rgba(102,126,234,var(--placeholder-opacity))}.md\:focus\:placeholder-indigo-600:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#5a67d8;color:rgba(90,103,216,var(--placeholder-opacity))}.md\:focus\:placeholder-indigo-600:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#5a67d8;color:rgba(90,103,216,var(--placeholder-opacity))}.md\:focus\:placeholder-indigo-600:focus::placeholder{--placeholder-opacity:1;color:#5a67d8;color:rgba(90,103,216,var(--placeholder-opacity))}.md\:focus\:placeholder-indigo-700:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#4c51bf;color:rgba(76,81,191,var(--placeholder-opacity))}.md\:focus\:placeholder-indigo-700:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#4c51bf;color:rgba(76,81,191,var(--placeholder-opacity))}.md\:focus\:placeholder-indigo-700:focus::placeholder{--placeholder-opacity:1;color:#4c51bf;color:rgba(76,81,191,var(--placeholder-opacity))}.md\:focus\:placeholder-indigo-800:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#434190;color:rgba(67,65,144,var(--placeholder-opacity))}.md\:focus\:placeholder-indigo-800:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#434190;color:rgba(67,65,144,var(--placeholder-opacity))}.md\:focus\:placeholder-indigo-800:focus::placeholder{--placeholder-opacity:1;color:#434190;color:rgba(67,65,144,var(--placeholder-opacity))}.md\:focus\:placeholder-indigo-900:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#3c366b;color:rgba(60,54,107,var(--placeholder-opacity))}.md\:focus\:placeholder-indigo-900:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#3c366b;color:rgba(60,54,107,var(--placeholder-opacity))}.md\:focus\:placeholder-indigo-900:focus::placeholder{--placeholder-opacity:1;color:#3c366b;color:rgba(60,54,107,var(--placeholder-opacity))}.md\:focus\:placeholder-purple-100:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#faf5ff;color:rgba(250,245,255,var(--placeholder-opacity))}.md\:focus\:placeholder-purple-100:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#faf5ff;color:rgba(250,245,255,var(--placeholder-opacity))}.md\:focus\:placeholder-purple-100:focus::placeholder{--placeholder-opacity:1;color:#faf5ff;color:rgba(250,245,255,var(--placeholder-opacity))}.md\:focus\:placeholder-purple-200:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#e9d8fd;color:rgba(233,216,253,var(--placeholder-opacity))}.md\:focus\:placeholder-purple-200:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#e9d8fd;color:rgba(233,216,253,var(--placeholder-opacity))}.md\:focus\:placeholder-purple-200:focus::placeholder{--placeholder-opacity:1;color:#e9d8fd;color:rgba(233,216,253,var(--placeholder-opacity))}.md\:focus\:placeholder-purple-300:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#d6bcfa;color:rgba(214,188,250,var(--placeholder-opacity))}.md\:focus\:placeholder-purple-300:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#d6bcfa;color:rgba(214,188,250,var(--placeholder-opacity))}.md\:focus\:placeholder-purple-300:focus::placeholder{--placeholder-opacity:1;color:#d6bcfa;color:rgba(214,188,250,var(--placeholder-opacity))}.md\:focus\:placeholder-purple-400:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#b794f4;color:rgba(183,148,244,var(--placeholder-opacity))}.md\:focus\:placeholder-purple-400:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#b794f4;color:rgba(183,148,244,var(--placeholder-opacity))}.md\:focus\:placeholder-purple-400:focus::placeholder{--placeholder-opacity:1;color:#b794f4;color:rgba(183,148,244,var(--placeholder-opacity))}.md\:focus\:placeholder-purple-500:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#9f7aea;color:rgba(159,122,234,var(--placeholder-opacity))}.md\:focus\:placeholder-purple-500:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#9f7aea;color:rgba(159,122,234,var(--placeholder-opacity))}.md\:focus\:placeholder-purple-500:focus::placeholder{--placeholder-opacity:1;color:#9f7aea;color:rgba(159,122,234,var(--placeholder-opacity))}.md\:focus\:placeholder-purple-600:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#805ad5;color:rgba(128,90,213,var(--placeholder-opacity))}.md\:focus\:placeholder-purple-600:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#805ad5;color:rgba(128,90,213,var(--placeholder-opacity))}.md\:focus\:placeholder-purple-600:focus::placeholder{--placeholder-opacity:1;color:#805ad5;color:rgba(128,90,213,var(--placeholder-opacity))}.md\:focus\:placeholder-purple-700:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#6b46c1;color:rgba(107,70,193,var(--placeholder-opacity))}.md\:focus\:placeholder-purple-700:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#6b46c1;color:rgba(107,70,193,var(--placeholder-opacity))}.md\:focus\:placeholder-purple-700:focus::placeholder{--placeholder-opacity:1;color:#6b46c1;color:rgba(107,70,193,var(--placeholder-opacity))}.md\:focus\:placeholder-purple-800:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#553c9a;color:rgba(85,60,154,var(--placeholder-opacity))}.md\:focus\:placeholder-purple-800:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#553c9a;color:rgba(85,60,154,var(--placeholder-opacity))}.md\:focus\:placeholder-purple-800:focus::placeholder{--placeholder-opacity:1;color:#553c9a;color:rgba(85,60,154,var(--placeholder-opacity))}.md\:focus\:placeholder-purple-900:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#44337a;color:rgba(68,51,122,var(--placeholder-opacity))}.md\:focus\:placeholder-purple-900:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#44337a;color:rgba(68,51,122,var(--placeholder-opacity))}.md\:focus\:placeholder-purple-900:focus::placeholder{--placeholder-opacity:1;color:#44337a;color:rgba(68,51,122,var(--placeholder-opacity))}.md\:focus\:placeholder-pink-100:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#fff5f7;color:rgba(255,245,247,var(--placeholder-opacity))}.md\:focus\:placeholder-pink-100:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#fff5f7;color:rgba(255,245,247,var(--placeholder-opacity))}.md\:focus\:placeholder-pink-100:focus::placeholder{--placeholder-opacity:1;color:#fff5f7;color:rgba(255,245,247,var(--placeholder-opacity))}.md\:focus\:placeholder-pink-200:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#fed7e2;color:rgba(254,215,226,var(--placeholder-opacity))}.md\:focus\:placeholder-pink-200:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#fed7e2;color:rgba(254,215,226,var(--placeholder-opacity))}.md\:focus\:placeholder-pink-200:focus::placeholder{--placeholder-opacity:1;color:#fed7e2;color:rgba(254,215,226,var(--placeholder-opacity))}.md\:focus\:placeholder-pink-300:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#fbb6ce;color:rgba(251,182,206,var(--placeholder-opacity))}.md\:focus\:placeholder-pink-300:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#fbb6ce;color:rgba(251,182,206,var(--placeholder-opacity))}.md\:focus\:placeholder-pink-300:focus::placeholder{--placeholder-opacity:1;color:#fbb6ce;color:rgba(251,182,206,var(--placeholder-opacity))}.md\:focus\:placeholder-pink-400:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#f687b3;color:rgba(246,135,179,var(--placeholder-opacity))}.md\:focus\:placeholder-pink-400:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#f687b3;color:rgba(246,135,179,var(--placeholder-opacity))}.md\:focus\:placeholder-pink-400:focus::placeholder{--placeholder-opacity:1;color:#f687b3;color:rgba(246,135,179,var(--placeholder-opacity))}.md\:focus\:placeholder-pink-500:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#ed64a6;color:rgba(237,100,166,var(--placeholder-opacity))}.md\:focus\:placeholder-pink-500:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#ed64a6;color:rgba(237,100,166,var(--placeholder-opacity))}.md\:focus\:placeholder-pink-500:focus::placeholder{--placeholder-opacity:1;color:#ed64a6;color:rgba(237,100,166,var(--placeholder-opacity))}.md\:focus\:placeholder-pink-600:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#d53f8c;color:rgba(213,63,140,var(--placeholder-opacity))}.md\:focus\:placeholder-pink-600:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#d53f8c;color:rgba(213,63,140,var(--placeholder-opacity))}.md\:focus\:placeholder-pink-600:focus::placeholder{--placeholder-opacity:1;color:#d53f8c;color:rgba(213,63,140,var(--placeholder-opacity))}.md\:focus\:placeholder-pink-700:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#b83280;color:rgba(184,50,128,var(--placeholder-opacity))}.md\:focus\:placeholder-pink-700:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#b83280;color:rgba(184,50,128,var(--placeholder-opacity))}.md\:focus\:placeholder-pink-700:focus::placeholder{--placeholder-opacity:1;color:#b83280;color:rgba(184,50,128,var(--placeholder-opacity))}.md\:focus\:placeholder-pink-800:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#97266d;color:rgba(151,38,109,var(--placeholder-opacity))}.md\:focus\:placeholder-pink-800:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#97266d;color:rgba(151,38,109,var(--placeholder-opacity))}.md\:focus\:placeholder-pink-800:focus::placeholder{--placeholder-opacity:1;color:#97266d;color:rgba(151,38,109,var(--placeholder-opacity))}.md\:focus\:placeholder-pink-900:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#702459;color:rgba(112,36,89,var(--placeholder-opacity))}.md\:focus\:placeholder-pink-900:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#702459;color:rgba(112,36,89,var(--placeholder-opacity))}.md\:focus\:placeholder-pink-900:focus::placeholder{--placeholder-opacity:1;color:#702459;color:rgba(112,36,89,var(--placeholder-opacity))}.md\:placeholder-opacity-0:-ms-input-placeholder{--placeholder-opacity:0}.md\:placeholder-opacity-0::-ms-input-placeholder{--placeholder-opacity:0}.md\:placeholder-opacity-0::placeholder{--placeholder-opacity:0}.md\:placeholder-opacity-25:-ms-input-placeholder{--placeholder-opacity:0.25}.md\:placeholder-opacity-25::-ms-input-placeholder{--placeholder-opacity:0.25}.md\:placeholder-opacity-25::placeholder{--placeholder-opacity:0.25}.md\:placeholder-opacity-50:-ms-input-placeholder{--placeholder-opacity:0.5}.md\:placeholder-opacity-50::-ms-input-placeholder{--placeholder-opacity:0.5}.md\:placeholder-opacity-50::placeholder{--placeholder-opacity:0.5}.md\:placeholder-opacity-75:-ms-input-placeholder{--placeholder-opacity:0.75}.md\:placeholder-opacity-75::-ms-input-placeholder{--placeholder-opacity:0.75}.md\:placeholder-opacity-75::placeholder{--placeholder-opacity:0.75}.md\:placeholder-opacity-100:-ms-input-placeholder{--placeholder-opacity:1}.md\:placeholder-opacity-100::-ms-input-placeholder{--placeholder-opacity:1}.md\:placeholder-opacity-100::placeholder{--placeholder-opacity:1}.md\:focus\:placeholder-opacity-0:focus:-ms-input-placeholder{--placeholder-opacity:0}.md\:focus\:placeholder-opacity-0:focus::-ms-input-placeholder{--placeholder-opacity:0}.md\:focus\:placeholder-opacity-0:focus::placeholder{--placeholder-opacity:0}.md\:focus\:placeholder-opacity-25:focus:-ms-input-placeholder{--placeholder-opacity:0.25}.md\:focus\:placeholder-opacity-25:focus::-ms-input-placeholder{--placeholder-opacity:0.25}.md\:focus\:placeholder-opacity-25:focus::placeholder{--placeholder-opacity:0.25}.md\:focus\:placeholder-opacity-50:focus:-ms-input-placeholder{--placeholder-opacity:0.5}.md\:focus\:placeholder-opacity-50:focus::-ms-input-placeholder{--placeholder-opacity:0.5}.md\:focus\:placeholder-opacity-50:focus::placeholder{--placeholder-opacity:0.5}.md\:focus\:placeholder-opacity-75:focus:-ms-input-placeholder{--placeholder-opacity:0.75}.md\:focus\:placeholder-opacity-75:focus::-ms-input-placeholder{--placeholder-opacity:0.75}.md\:focus\:placeholder-opacity-75:focus::placeholder{--placeholder-opacity:0.75}.md\:focus\:placeholder-opacity-100:focus:-ms-input-placeholder{--placeholder-opacity:1}.md\:focus\:placeholder-opacity-100:focus::-ms-input-placeholder{--placeholder-opacity:1}.md\:focus\:placeholder-opacity-100:focus::placeholder{--placeholder-opacity:1}.md\:pointer-events-none{pointer-events:none}.md\:pointer-events-auto{pointer-events:auto}.md\:static{position:static}.md\:fixed{position:fixed}.md\:absolute{position:absolute}.md\:relative{position:relative}.md\:sticky{position:-webkit-sticky;position:sticky}.md\:inset-0{top:0;right:0;bottom:0;left:0}.md\:inset-auto{top:auto;right:auto;bottom:auto;left:auto}.md\:inset-y-0{top:0;bottom:0}.md\:inset-x-0{right:0;left:0}.md\:inset-y-auto{top:auto;bottom:auto}.md\:inset-x-auto{right:auto;left:auto}.md\:top-0{top:0}.md\:right-0{right:0}.md\:bottom-0{bottom:0}.md\:left-0{left:0}.md\:top-auto{top:auto}.md\:right-auto{right:auto}.md\:bottom-auto{bottom:auto}.md\:left-auto{left:auto}.md\:resize-none{resize:none}.md\:resize-y{resize:vertical}.md\:resize-x{resize:horizontal}.md\:resize{resize:both}.md\:shadow-xs{box-shadow:0 0 0 1px rgba(0,0,0,.05)}.md\:shadow-sm{box-shadow:0 1px 2px 0 rgba(0,0,0,.05)}.md\:shadow{box-shadow:0 1px 3px 0 rgba(0,0,0,.1),0 1px 2px 0 rgba(0,0,0,.06)}.md\:shadow-md{box-shadow:0 4px 6px -1px rgba(0,0,0,.1),0 2px 4px -1px rgba(0,0,0,.06)}.md\:shadow-lg{box-shadow:0 10px 15px -3px rgba(0,0,0,.1),0 4px 6px -2px rgba(0,0,0,.05)}.md\:shadow-xl{box-shadow:0 20px 25px -5px rgba(0,0,0,.1),0 10px 10px -5px rgba(0,0,0,.04)}.md\:shadow-2xl{box-shadow:0 25px 50px -12px rgba(0,0,0,.25)}.md\:shadow-inner{box-shadow:inset 0 2px 4px 0 rgba(0,0,0,.06)}.md\:shadow-outline{box-shadow:0 0 0 3px rgba(66,153,225,.5)}.md\:shadow-none{box-shadow:none}.md\:hover\:shadow-xs:hover{box-shadow:0 0 0 1px rgba(0,0,0,.05)}.md\:hover\:shadow-sm:hover{box-shadow:0 1px 2px 0 rgba(0,0,0,.05)}.md\:hover\:shadow:hover{box-shadow:0 1px 3px 0 rgba(0,0,0,.1),0 1px 2px 0 rgba(0,0,0,.06)}.md\:hover\:shadow-md:hover{box-shadow:0 4px 6px -1px rgba(0,0,0,.1),0 2px 4px -1px rgba(0,0,0,.06)}.md\:hover\:shadow-lg:hover{box-shadow:0 10px 15px -3px rgba(0,0,0,.1),0 4px 6px -2px rgba(0,0,0,.05)}.md\:hover\:shadow-xl:hover{box-shadow:0 20px 25px -5px rgba(0,0,0,.1),0 10px 10px -5px rgba(0,0,0,.04)}.md\:hover\:shadow-2xl:hover{box-shadow:0 25px 50px -12px rgba(0,0,0,.25)}.md\:hover\:shadow-inner:hover{box-shadow:inset 0 2px 4px 0 rgba(0,0,0,.06)}.md\:hover\:shadow-outline:hover{box-shadow:0 0 0 3px rgba(66,153,225,.5)}.md\:hover\:shadow-none:hover{box-shadow:none}.md\:focus\:shadow-xs:focus{box-shadow:0 0 0 1px rgba(0,0,0,.05)}.md\:focus\:shadow-sm:focus{box-shadow:0 1px 2px 0 rgba(0,0,0,.05)}.md\:focus\:shadow:focus{box-shadow:0 1px 3px 0 rgba(0,0,0,.1),0 1px 2px 0 rgba(0,0,0,.06)}.md\:focus\:shadow-md:focus{box-shadow:0 4px 6px -1px rgba(0,0,0,.1),0 2px 4px -1px rgba(0,0,0,.06)}.md\:focus\:shadow-lg:focus{box-shadow:0 10px 15px -3px rgba(0,0,0,.1),0 4px 6px -2px rgba(0,0,0,.05)}.md\:focus\:shadow-xl:focus{box-shadow:0 20px 25px -5px rgba(0,0,0,.1),0 10px 10px -5px rgba(0,0,0,.04)}.md\:focus\:shadow-2xl:focus{box-shadow:0 25px 50px -12px rgba(0,0,0,.25)}.md\:focus\:shadow-inner:focus{box-shadow:inset 0 2px 4px 0 rgba(0,0,0,.06)}.md\:focus\:shadow-outline:focus{box-shadow:0 0 0 3px rgba(66,153,225,.5)}.md\:focus\:shadow-none:focus{box-shadow:none}.md\:fill-current{fill:currentColor}.md\:stroke-current{stroke:currentColor}.md\:stroke-0{stroke-width:0}.md\:stroke-1{stroke-width:1}.md\:stroke-2{stroke-width:2}.md\:table-auto{table-layout:auto}.md\:table-fixed{table-layout:fixed}.md\:text-left{text-align:left}.md\:text-center{text-align:center}.md\:text-right{text-align:right}.md\:text-justify{text-align:justify}.md\:text-transparent{color:transparent}.md\:text-current{color:currentColor}.md\:text-black{--text-opacity:1;color:#000;color:rgba(0,0,0,var(--text-opacity))}.md\:text-white{--text-opacity:1;color:#fff;color:rgba(255,255,255,var(--text-opacity))}.md\:text-gray-100{--text-opacity:1;color:#f7fafc;color:rgba(247,250,252,var(--text-opacity))}.md\:text-gray-200{--text-opacity:1;color:#edf2f7;color:rgba(237,242,247,var(--text-opacity))}.md\:text-gray-300{--text-opacity:1;color:#e2e8f0;color:rgba(226,232,240,var(--text-opacity))}.md\:text-gray-400{--text-opacity:1;color:#cbd5e0;color:rgba(203,213,224,var(--text-opacity))}.md\:text-gray-500{--text-opacity:1;color:#a0aec0;color:rgba(160,174,192,var(--text-opacity))}.md\:text-gray-600{--text-opacity:1;color:#718096;color:rgba(113,128,150,var(--text-opacity))}.md\:text-gray-700{--text-opacity:1;color:#4a5568;color:rgba(74,85,104,var(--text-opacity))}.md\:text-gray-800{--text-opacity:1;color:#2d3748;color:rgba(45,55,72,var(--text-opacity))}.md\:text-gray-900{--text-opacity:1;color:#1a202c;color:rgba(26,32,44,var(--text-opacity))}.md\:text-red-100{--text-opacity:1;color:#fff5f5;color:rgba(255,245,245,var(--text-opacity))}.md\:text-red-200{--text-opacity:1;color:#fed7d7;color:rgba(254,215,215,var(--text-opacity))}.md\:text-red-300{--text-opacity:1;color:#feb2b2;color:rgba(254,178,178,var(--text-opacity))}.md\:text-red-400{--text-opacity:1;color:#fc8181;color:rgba(252,129,129,var(--text-opacity))}.md\:text-red-500{--text-opacity:1;color:#f56565;color:rgba(245,101,101,var(--text-opacity))}.md\:text-red-600{--text-opacity:1;color:#e53e3e;color:rgba(229,62,62,var(--text-opacity))}.md\:text-red-700{--text-opacity:1;color:#c53030;color:rgba(197,48,48,var(--text-opacity))}.md\:text-red-800{--text-opacity:1;color:#9b2c2c;color:rgba(155,44,44,var(--text-opacity))}.md\:text-red-900{--text-opacity:1;color:#742a2a;color:rgba(116,42,42,var(--text-opacity))}.md\:text-orange-100{--text-opacity:1;color:#fffaf0;color:rgba(255,250,240,var(--text-opacity))}.md\:text-orange-200{--text-opacity:1;color:#feebc8;color:rgba(254,235,200,var(--text-opacity))}.md\:text-orange-300{--text-opacity:1;color:#fbd38d;color:rgba(251,211,141,var(--text-opacity))}.md\:text-orange-400{--text-opacity:1;color:#f6ad55;color:rgba(246,173,85,var(--text-opacity))}.md\:text-orange-500{--text-opacity:1;color:#ed8936;color:rgba(237,137,54,var(--text-opacity))}.md\:text-orange-600{--text-opacity:1;color:#dd6b20;color:rgba(221,107,32,var(--text-opacity))}.md\:text-orange-700{--text-opacity:1;color:#c05621;color:rgba(192,86,33,var(--text-opacity))}.md\:text-orange-800{--text-opacity:1;color:#9c4221;color:rgba(156,66,33,var(--text-opacity))}.md\:text-orange-900{--text-opacity:1;color:#7b341e;color:rgba(123,52,30,var(--text-opacity))}.md\:text-yellow-100{--text-opacity:1;color:ivory;color:rgba(255,255,240,var(--text-opacity))}.md\:text-yellow-200{--text-opacity:1;color:#fefcbf;color:rgba(254,252,191,var(--text-opacity))}.md\:text-yellow-300{--text-opacity:1;color:#faf089;color:rgba(250,240,137,var(--text-opacity))}.md\:text-yellow-400{--text-opacity:1;color:#f6e05e;color:rgba(246,224,94,var(--text-opacity))}.md\:text-yellow-500{--text-opacity:1;color:#ecc94b;color:rgba(236,201,75,var(--text-opacity))}.md\:text-yellow-600{--text-opacity:1;color:#d69e2e;color:rgba(214,158,46,var(--text-opacity))}.md\:text-yellow-700{--text-opacity:1;color:#b7791f;color:rgba(183,121,31,var(--text-opacity))}.md\:text-yellow-800{--text-opacity:1;color:#975a16;color:rgba(151,90,22,var(--text-opacity))}.md\:text-yellow-900{--text-opacity:1;color:#744210;color:rgba(116,66,16,var(--text-opacity))}.md\:text-green-100{--text-opacity:1;color:#f0fff4;color:rgba(240,255,244,var(--text-opacity))}.md\:text-green-200{--text-opacity:1;color:#c6f6d5;color:rgba(198,246,213,var(--text-opacity))}.md\:text-green-300{--text-opacity:1;color:#9ae6b4;color:rgba(154,230,180,var(--text-opacity))}.md\:text-green-400{--text-opacity:1;color:#68d391;color:rgba(104,211,145,var(--text-opacity))}.md\:text-green-500{--text-opacity:1;color:#48bb78;color:rgba(72,187,120,var(--text-opacity))}.md\:text-green-600{--text-opacity:1;color:#38a169;color:rgba(56,161,105,var(--text-opacity))}.md\:text-green-700{--text-opacity:1;color:#2f855a;color:rgba(47,133,90,var(--text-opacity))}.md\:text-green-800{--text-opacity:1;color:#276749;color:rgba(39,103,73,var(--text-opacity))}.md\:text-green-900{--text-opacity:1;color:#22543d;color:rgba(34,84,61,var(--text-opacity))}.md\:text-teal-100{--text-opacity:1;color:#e6fffa;color:rgba(230,255,250,var(--text-opacity))}.md\:text-teal-200{--text-opacity:1;color:#b2f5ea;color:rgba(178,245,234,var(--text-opacity))}.md\:text-teal-300{--text-opacity:1;color:#81e6d9;color:rgba(129,230,217,var(--text-opacity))}.md\:text-teal-400{--text-opacity:1;color:#4fd1c5;color:rgba(79,209,197,var(--text-opacity))}.md\:text-teal-500{--text-opacity:1;color:#38b2ac;color:rgba(56,178,172,var(--text-opacity))}.md\:text-teal-600{--text-opacity:1;color:#319795;color:rgba(49,151,149,var(--text-opacity))}.md\:text-teal-700{--text-opacity:1;color:#2c7a7b;color:rgba(44,122,123,var(--text-opacity))}.md\:text-teal-800{--text-opacity:1;color:#285e61;color:rgba(40,94,97,var(--text-opacity))}.md\:text-teal-900{--text-opacity:1;color:#234e52;color:rgba(35,78,82,var(--text-opacity))}.md\:text-blue-100{--text-opacity:1;color:#ebf8ff;color:rgba(235,248,255,var(--text-opacity))}.md\:text-blue-200{--text-opacity:1;color:#bee3f8;color:rgba(190,227,248,var(--text-opacity))}.md\:text-blue-300{--text-opacity:1;color:#90cdf4;color:rgba(144,205,244,var(--text-opacity))}.md\:text-blue-400{--text-opacity:1;color:#63b3ed;color:rgba(99,179,237,var(--text-opacity))}.md\:text-blue-500{--text-opacity:1;color:#4299e1;color:rgba(66,153,225,var(--text-opacity))}.md\:text-blue-600{--text-opacity:1;color:#3182ce;color:rgba(49,130,206,var(--text-opacity))}.md\:text-blue-700{--text-opacity:1;color:#2b6cb0;color:rgba(43,108,176,var(--text-opacity))}.md\:text-blue-800{--text-opacity:1;color:#2c5282;color:rgba(44,82,130,var(--text-opacity))}.md\:text-blue-900{--text-opacity:1;color:#2a4365;color:rgba(42,67,101,var(--text-opacity))}.md\:text-indigo-100{--text-opacity:1;color:#ebf4ff;color:rgba(235,244,255,var(--text-opacity))}.md\:text-indigo-200{--text-opacity:1;color:#c3dafe;color:rgba(195,218,254,var(--text-opacity))}.md\:text-indigo-300{--text-opacity:1;color:#a3bffa;color:rgba(163,191,250,var(--text-opacity))}.md\:text-indigo-400{--text-opacity:1;color:#7f9cf5;color:rgba(127,156,245,var(--text-opacity))}.md\:text-indigo-500{--text-opacity:1;color:#667eea;color:rgba(102,126,234,var(--text-opacity))}.md\:text-indigo-600{--text-opacity:1;color:#5a67d8;color:rgba(90,103,216,var(--text-opacity))}.md\:text-indigo-700{--text-opacity:1;color:#4c51bf;color:rgba(76,81,191,var(--text-opacity))}.md\:text-indigo-800{--text-opacity:1;color:#434190;color:rgba(67,65,144,var(--text-opacity))}.md\:text-indigo-900{--text-opacity:1;color:#3c366b;color:rgba(60,54,107,var(--text-opacity))}.md\:text-purple-100{--text-opacity:1;color:#faf5ff;color:rgba(250,245,255,var(--text-opacity))}.md\:text-purple-200{--text-opacity:1;color:#e9d8fd;color:rgba(233,216,253,var(--text-opacity))}.md\:text-purple-300{--text-opacity:1;color:#d6bcfa;color:rgba(214,188,250,var(--text-opacity))}.md\:text-purple-400{--text-opacity:1;color:#b794f4;color:rgba(183,148,244,var(--text-opacity))}.md\:text-purple-500{--text-opacity:1;color:#9f7aea;color:rgba(159,122,234,var(--text-opacity))}.md\:text-purple-600{--text-opacity:1;color:#805ad5;color:rgba(128,90,213,var(--text-opacity))}.md\:text-purple-700{--text-opacity:1;color:#6b46c1;color:rgba(107,70,193,var(--text-opacity))}.md\:text-purple-800{--text-opacity:1;color:#553c9a;color:rgba(85,60,154,var(--text-opacity))}.md\:text-purple-900{--text-opacity:1;color:#44337a;color:rgba(68,51,122,var(--text-opacity))}.md\:text-pink-100{--text-opacity:1;color:#fff5f7;color:rgba(255,245,247,var(--text-opacity))}.md\:text-pink-200{--text-opacity:1;color:#fed7e2;color:rgba(254,215,226,var(--text-opacity))}.md\:text-pink-300{--text-opacity:1;color:#fbb6ce;color:rgba(251,182,206,var(--text-opacity))}.md\:text-pink-400{--text-opacity:1;color:#f687b3;color:rgba(246,135,179,var(--text-opacity))}.md\:text-pink-500{--text-opacity:1;color:#ed64a6;color:rgba(237,100,166,var(--text-opacity))}.md\:text-pink-600{--text-opacity:1;color:#d53f8c;color:rgba(213,63,140,var(--text-opacity))}.md\:text-pink-700{--text-opacity:1;color:#b83280;color:rgba(184,50,128,var(--text-opacity))}.md\:text-pink-800{--text-opacity:1;color:#97266d;color:rgba(151,38,109,var(--text-opacity))}.md\:text-pink-900{--text-opacity:1;color:#702459;color:rgba(112,36,89,var(--text-opacity))}.md\:hover\:text-transparent:hover{color:transparent}.md\:hover\:text-current:hover{color:currentColor}.md\:hover\:text-black:hover{--text-opacity:1;color:#000;color:rgba(0,0,0,var(--text-opacity))}.md\:hover\:text-white:hover{--text-opacity:1;color:#fff;color:rgba(255,255,255,var(--text-opacity))}.md\:hover\:text-gray-100:hover{--text-opacity:1;color:#f7fafc;color:rgba(247,250,252,var(--text-opacity))}.md\:hover\:text-gray-200:hover{--text-opacity:1;color:#edf2f7;color:rgba(237,242,247,var(--text-opacity))}.md\:hover\:text-gray-300:hover{--text-opacity:1;color:#e2e8f0;color:rgba(226,232,240,var(--text-opacity))}.md\:hover\:text-gray-400:hover{--text-opacity:1;color:#cbd5e0;color:rgba(203,213,224,var(--text-opacity))}.md\:hover\:text-gray-500:hover{--text-opacity:1;color:#a0aec0;color:rgba(160,174,192,var(--text-opacity))}.md\:hover\:text-gray-600:hover{--text-opacity:1;color:#718096;color:rgba(113,128,150,var(--text-opacity))}.md\:hover\:text-gray-700:hover{--text-opacity:1;color:#4a5568;color:rgba(74,85,104,var(--text-opacity))}.md\:hover\:text-gray-800:hover{--text-opacity:1;color:#2d3748;color:rgba(45,55,72,var(--text-opacity))}.md\:hover\:text-gray-900:hover{--text-opacity:1;color:#1a202c;color:rgba(26,32,44,var(--text-opacity))}.md\:hover\:text-red-100:hover{--text-opacity:1;color:#fff5f5;color:rgba(255,245,245,var(--text-opacity))}.md\:hover\:text-red-200:hover{--text-opacity:1;color:#fed7d7;color:rgba(254,215,215,var(--text-opacity))}.md\:hover\:text-red-300:hover{--text-opacity:1;color:#feb2b2;color:rgba(254,178,178,var(--text-opacity))}.md\:hover\:text-red-400:hover{--text-opacity:1;color:#fc8181;color:rgba(252,129,129,var(--text-opacity))}.md\:hover\:text-red-500:hover{--text-opacity:1;color:#f56565;color:rgba(245,101,101,var(--text-opacity))}.md\:hover\:text-red-600:hover{--text-opacity:1;color:#e53e3e;color:rgba(229,62,62,var(--text-opacity))}.md\:hover\:text-red-700:hover{--text-opacity:1;color:#c53030;color:rgba(197,48,48,var(--text-opacity))}.md\:hover\:text-red-800:hover{--text-opacity:1;color:#9b2c2c;color:rgba(155,44,44,var(--text-opacity))}.md\:hover\:text-red-900:hover{--text-opacity:1;color:#742a2a;color:rgba(116,42,42,var(--text-opacity))}.md\:hover\:text-orange-100:hover{--text-opacity:1;color:#fffaf0;color:rgba(255,250,240,var(--text-opacity))}.md\:hover\:text-orange-200:hover{--text-opacity:1;color:#feebc8;color:rgba(254,235,200,var(--text-opacity))}.md\:hover\:text-orange-300:hover{--text-opacity:1;color:#fbd38d;color:rgba(251,211,141,var(--text-opacity))}.md\:hover\:text-orange-400:hover{--text-opacity:1;color:#f6ad55;color:rgba(246,173,85,var(--text-opacity))}.md\:hover\:text-orange-500:hover{--text-opacity:1;color:#ed8936;color:rgba(237,137,54,var(--text-opacity))}.md\:hover\:text-orange-600:hover{--text-opacity:1;color:#dd6b20;color:rgba(221,107,32,var(--text-opacity))}.md\:hover\:text-orange-700:hover{--text-opacity:1;color:#c05621;color:rgba(192,86,33,var(--text-opacity))}.md\:hover\:text-orange-800:hover{--text-opacity:1;color:#9c4221;color:rgba(156,66,33,var(--text-opacity))}.md\:hover\:text-orange-900:hover{--text-opacity:1;color:#7b341e;color:rgba(123,52,30,var(--text-opacity))}.md\:hover\:text-yellow-100:hover{--text-opacity:1;color:ivory;color:rgba(255,255,240,var(--text-opacity))}.md\:hover\:text-yellow-200:hover{--text-opacity:1;color:#fefcbf;color:rgba(254,252,191,var(--text-opacity))}.md\:hover\:text-yellow-300:hover{--text-opacity:1;color:#faf089;color:rgba(250,240,137,var(--text-opacity))}.md\:hover\:text-yellow-400:hover{--text-opacity:1;color:#f6e05e;color:rgba(246,224,94,var(--text-opacity))}.md\:hover\:text-yellow-500:hover{--text-opacity:1;color:#ecc94b;color:rgba(236,201,75,var(--text-opacity))}.md\:hover\:text-yellow-600:hover{--text-opacity:1;color:#d69e2e;color:rgba(214,158,46,var(--text-opacity))}.md\:hover\:text-yellow-700:hover{--text-opacity:1;color:#b7791f;color:rgba(183,121,31,var(--text-opacity))}.md\:hover\:text-yellow-800:hover{--text-opacity:1;color:#975a16;color:rgba(151,90,22,var(--text-opacity))}.md\:hover\:text-yellow-900:hover{--text-opacity:1;color:#744210;color:rgba(116,66,16,var(--text-opacity))}.md\:hover\:text-green-100:hover{--text-opacity:1;color:#f0fff4;color:rgba(240,255,244,var(--text-opacity))}.md\:hover\:text-green-200:hover{--text-opacity:1;color:#c6f6d5;color:rgba(198,246,213,var(--text-opacity))}.md\:hover\:text-green-300:hover{--text-opacity:1;color:#9ae6b4;color:rgba(154,230,180,var(--text-opacity))}.md\:hover\:text-green-400:hover{--text-opacity:1;color:#68d391;color:rgba(104,211,145,var(--text-opacity))}.md\:hover\:text-green-500:hover{--text-opacity:1;color:#48bb78;color:rgba(72,187,120,var(--text-opacity))}.md\:hover\:text-green-600:hover{--text-opacity:1;color:#38a169;color:rgba(56,161,105,var(--text-opacity))}.md\:hover\:text-green-700:hover{--text-opacity:1;color:#2f855a;color:rgba(47,133,90,var(--text-opacity))}.md\:hover\:text-green-800:hover{--text-opacity:1;color:#276749;color:rgba(39,103,73,var(--text-opacity))}.md\:hover\:text-green-900:hover{--text-opacity:1;color:#22543d;color:rgba(34,84,61,var(--text-opacity))}.md\:hover\:text-teal-100:hover{--text-opacity:1;color:#e6fffa;color:rgba(230,255,250,var(--text-opacity))}.md\:hover\:text-teal-200:hover{--text-opacity:1;color:#b2f5ea;color:rgba(178,245,234,var(--text-opacity))}.md\:hover\:text-teal-300:hover{--text-opacity:1;color:#81e6d9;color:rgba(129,230,217,var(--text-opacity))}.md\:hover\:text-teal-400:hover{--text-opacity:1;color:#4fd1c5;color:rgba(79,209,197,var(--text-opacity))}.md\:hover\:text-teal-500:hover{--text-opacity:1;color:#38b2ac;color:rgba(56,178,172,var(--text-opacity))}.md\:hover\:text-teal-600:hover{--text-opacity:1;color:#319795;color:rgba(49,151,149,var(--text-opacity))}.md\:hover\:text-teal-700:hover{--text-opacity:1;color:#2c7a7b;color:rgba(44,122,123,var(--text-opacity))}.md\:hover\:text-teal-800:hover{--text-opacity:1;color:#285e61;color:rgba(40,94,97,var(--text-opacity))}.md\:hover\:text-teal-900:hover{--text-opacity:1;color:#234e52;color:rgba(35,78,82,var(--text-opacity))}.md\:hover\:text-blue-100:hover{--text-opacity:1;color:#ebf8ff;color:rgba(235,248,255,var(--text-opacity))}.md\:hover\:text-blue-200:hover{--text-opacity:1;color:#bee3f8;color:rgba(190,227,248,var(--text-opacity))}.md\:hover\:text-blue-300:hover{--text-opacity:1;color:#90cdf4;color:rgba(144,205,244,var(--text-opacity))}.md\:hover\:text-blue-400:hover{--text-opacity:1;color:#63b3ed;color:rgba(99,179,237,var(--text-opacity))}.md\:hover\:text-blue-500:hover{--text-opacity:1;color:#4299e1;color:rgba(66,153,225,var(--text-opacity))}.md\:hover\:text-blue-600:hover{--text-opacity:1;color:#3182ce;color:rgba(49,130,206,var(--text-opacity))}.md\:hover\:text-blue-700:hover{--text-opacity:1;color:#2b6cb0;color:rgba(43,108,176,var(--text-opacity))}.md\:hover\:text-blue-800:hover{--text-opacity:1;color:#2c5282;color:rgba(44,82,130,var(--text-opacity))}.md\:hover\:text-blue-900:hover{--text-opacity:1;color:#2a4365;color:rgba(42,67,101,var(--text-opacity))}.md\:hover\:text-indigo-100:hover{--text-opacity:1;color:#ebf4ff;color:rgba(235,244,255,var(--text-opacity))}.md\:hover\:text-indigo-200:hover{--text-opacity:1;color:#c3dafe;color:rgba(195,218,254,var(--text-opacity))}.md\:hover\:text-indigo-300:hover{--text-opacity:1;color:#a3bffa;color:rgba(163,191,250,var(--text-opacity))}.md\:hover\:text-indigo-400:hover{--text-opacity:1;color:#7f9cf5;color:rgba(127,156,245,var(--text-opacity))}.md\:hover\:text-indigo-500:hover{--text-opacity:1;color:#667eea;color:rgba(102,126,234,var(--text-opacity))}.md\:hover\:text-indigo-600:hover{--text-opacity:1;color:#5a67d8;color:rgba(90,103,216,var(--text-opacity))}.md\:hover\:text-indigo-700:hover{--text-opacity:1;color:#4c51bf;color:rgba(76,81,191,var(--text-opacity))}.md\:hover\:text-indigo-800:hover{--text-opacity:1;color:#434190;color:rgba(67,65,144,var(--text-opacity))}.md\:hover\:text-indigo-900:hover{--text-opacity:1;color:#3c366b;color:rgba(60,54,107,var(--text-opacity))}.md\:hover\:text-purple-100:hover{--text-opacity:1;color:#faf5ff;color:rgba(250,245,255,var(--text-opacity))}.md\:hover\:text-purple-200:hover{--text-opacity:1;color:#e9d8fd;color:rgba(233,216,253,var(--text-opacity))}.md\:hover\:text-purple-300:hover{--text-opacity:1;color:#d6bcfa;color:rgba(214,188,250,var(--text-opacity))}.md\:hover\:text-purple-400:hover{--text-opacity:1;color:#b794f4;color:rgba(183,148,244,var(--text-opacity))}.md\:hover\:text-purple-500:hover{--text-opacity:1;color:#9f7aea;color:rgba(159,122,234,var(--text-opacity))}.md\:hover\:text-purple-600:hover{--text-opacity:1;color:#805ad5;color:rgba(128,90,213,var(--text-opacity))}.md\:hover\:text-purple-700:hover{--text-opacity:1;color:#6b46c1;color:rgba(107,70,193,var(--text-opacity))}.md\:hover\:text-purple-800:hover{--text-opacity:1;color:#553c9a;color:rgba(85,60,154,var(--text-opacity))}.md\:hover\:text-purple-900:hover{--text-opacity:1;color:#44337a;color:rgba(68,51,122,var(--text-opacity))}.md\:hover\:text-pink-100:hover{--text-opacity:1;color:#fff5f7;color:rgba(255,245,247,var(--text-opacity))}.md\:hover\:text-pink-200:hover{--text-opacity:1;color:#fed7e2;color:rgba(254,215,226,var(--text-opacity))}.md\:hover\:text-pink-300:hover{--text-opacity:1;color:#fbb6ce;color:rgba(251,182,206,var(--text-opacity))}.md\:hover\:text-pink-400:hover{--text-opacity:1;color:#f687b3;color:rgba(246,135,179,var(--text-opacity))}.md\:hover\:text-pink-500:hover{--text-opacity:1;color:#ed64a6;color:rgba(237,100,166,var(--text-opacity))}.md\:hover\:text-pink-600:hover{--text-opacity:1;color:#d53f8c;color:rgba(213,63,140,var(--text-opacity))}.md\:hover\:text-pink-700:hover{--text-opacity:1;color:#b83280;color:rgba(184,50,128,var(--text-opacity))}.md\:hover\:text-pink-800:hover{--text-opacity:1;color:#97266d;color:rgba(151,38,109,var(--text-opacity))}.md\:hover\:text-pink-900:hover{--text-opacity:1;color:#702459;color:rgba(112,36,89,var(--text-opacity))}.md\:focus\:text-transparent:focus{color:transparent}.md\:focus\:text-current:focus{color:currentColor}.md\:focus\:text-black:focus{--text-opacity:1;color:#000;color:rgba(0,0,0,var(--text-opacity))}.md\:focus\:text-white:focus{--text-opacity:1;color:#fff;color:rgba(255,255,255,var(--text-opacity))}.md\:focus\:text-gray-100:focus{--text-opacity:1;color:#f7fafc;color:rgba(247,250,252,var(--text-opacity))}.md\:focus\:text-gray-200:focus{--text-opacity:1;color:#edf2f7;color:rgba(237,242,247,var(--text-opacity))}.md\:focus\:text-gray-300:focus{--text-opacity:1;color:#e2e8f0;color:rgba(226,232,240,var(--text-opacity))}.md\:focus\:text-gray-400:focus{--text-opacity:1;color:#cbd5e0;color:rgba(203,213,224,var(--text-opacity))}.md\:focus\:text-gray-500:focus{--text-opacity:1;color:#a0aec0;color:rgba(160,174,192,var(--text-opacity))}.md\:focus\:text-gray-600:focus{--text-opacity:1;color:#718096;color:rgba(113,128,150,var(--text-opacity))}.md\:focus\:text-gray-700:focus{--text-opacity:1;color:#4a5568;color:rgba(74,85,104,var(--text-opacity))}.md\:focus\:text-gray-800:focus{--text-opacity:1;color:#2d3748;color:rgba(45,55,72,var(--text-opacity))}.md\:focus\:text-gray-900:focus{--text-opacity:1;color:#1a202c;color:rgba(26,32,44,var(--text-opacity))}.md\:focus\:text-red-100:focus{--text-opacity:1;color:#fff5f5;color:rgba(255,245,245,var(--text-opacity))}.md\:focus\:text-red-200:focus{--text-opacity:1;color:#fed7d7;color:rgba(254,215,215,var(--text-opacity))}.md\:focus\:text-red-300:focus{--text-opacity:1;color:#feb2b2;color:rgba(254,178,178,var(--text-opacity))}.md\:focus\:text-red-400:focus{--text-opacity:1;color:#fc8181;color:rgba(252,129,129,var(--text-opacity))}.md\:focus\:text-red-500:focus{--text-opacity:1;color:#f56565;color:rgba(245,101,101,var(--text-opacity))}.md\:focus\:text-red-600:focus{--text-opacity:1;color:#e53e3e;color:rgba(229,62,62,var(--text-opacity))}.md\:focus\:text-red-700:focus{--text-opacity:1;color:#c53030;color:rgba(197,48,48,var(--text-opacity))}.md\:focus\:text-red-800:focus{--text-opacity:1;color:#9b2c2c;color:rgba(155,44,44,var(--text-opacity))}.md\:focus\:text-red-900:focus{--text-opacity:1;color:#742a2a;color:rgba(116,42,42,var(--text-opacity))}.md\:focus\:text-orange-100:focus{--text-opacity:1;color:#fffaf0;color:rgba(255,250,240,var(--text-opacity))}.md\:focus\:text-orange-200:focus{--text-opacity:1;color:#feebc8;color:rgba(254,235,200,var(--text-opacity))}.md\:focus\:text-orange-300:focus{--text-opacity:1;color:#fbd38d;color:rgba(251,211,141,var(--text-opacity))}.md\:focus\:text-orange-400:focus{--text-opacity:1;color:#f6ad55;color:rgba(246,173,85,var(--text-opacity))}.md\:focus\:text-orange-500:focus{--text-opacity:1;color:#ed8936;color:rgba(237,137,54,var(--text-opacity))}.md\:focus\:text-orange-600:focus{--text-opacity:1;color:#dd6b20;color:rgba(221,107,32,var(--text-opacity))}.md\:focus\:text-orange-700:focus{--text-opacity:1;color:#c05621;color:rgba(192,86,33,var(--text-opacity))}.md\:focus\:text-orange-800:focus{--text-opacity:1;color:#9c4221;color:rgba(156,66,33,var(--text-opacity))}.md\:focus\:text-orange-900:focus{--text-opacity:1;color:#7b341e;color:rgba(123,52,30,var(--text-opacity))}.md\:focus\:text-yellow-100:focus{--text-opacity:1;color:ivory;color:rgba(255,255,240,var(--text-opacity))}.md\:focus\:text-yellow-200:focus{--text-opacity:1;color:#fefcbf;color:rgba(254,252,191,var(--text-opacity))}.md\:focus\:text-yellow-300:focus{--text-opacity:1;color:#faf089;color:rgba(250,240,137,var(--text-opacity))}.md\:focus\:text-yellow-400:focus{--text-opacity:1;color:#f6e05e;color:rgba(246,224,94,var(--text-opacity))}.md\:focus\:text-yellow-500:focus{--text-opacity:1;color:#ecc94b;color:rgba(236,201,75,var(--text-opacity))}.md\:focus\:text-yellow-600:focus{--text-opacity:1;color:#d69e2e;color:rgba(214,158,46,var(--text-opacity))}.md\:focus\:text-yellow-700:focus{--text-opacity:1;color:#b7791f;color:rgba(183,121,31,var(--text-opacity))}.md\:focus\:text-yellow-800:focus{--text-opacity:1;color:#975a16;color:rgba(151,90,22,var(--text-opacity))}.md\:focus\:text-yellow-900:focus{--text-opacity:1;color:#744210;color:rgba(116,66,16,var(--text-opacity))}.md\:focus\:text-green-100:focus{--text-opacity:1;color:#f0fff4;color:rgba(240,255,244,var(--text-opacity))}.md\:focus\:text-green-200:focus{--text-opacity:1;color:#c6f6d5;color:rgba(198,246,213,var(--text-opacity))}.md\:focus\:text-green-300:focus{--text-opacity:1;color:#9ae6b4;color:rgba(154,230,180,var(--text-opacity))}.md\:focus\:text-green-400:focus{--text-opacity:1;color:#68d391;color:rgba(104,211,145,var(--text-opacity))}.md\:focus\:text-green-500:focus{--text-opacity:1;color:#48bb78;color:rgba(72,187,120,var(--text-opacity))}.md\:focus\:text-green-600:focus{--text-opacity:1;color:#38a169;color:rgba(56,161,105,var(--text-opacity))}.md\:focus\:text-green-700:focus{--text-opacity:1;color:#2f855a;color:rgba(47,133,90,var(--text-opacity))}.md\:focus\:text-green-800:focus{--text-opacity:1;color:#276749;color:rgba(39,103,73,var(--text-opacity))}.md\:focus\:text-green-900:focus{--text-opacity:1;color:#22543d;color:rgba(34,84,61,var(--text-opacity))}.md\:focus\:text-teal-100:focus{--text-opacity:1;color:#e6fffa;color:rgba(230,255,250,var(--text-opacity))}.md\:focus\:text-teal-200:focus{--text-opacity:1;color:#b2f5ea;color:rgba(178,245,234,var(--text-opacity))}.md\:focus\:text-teal-300:focus{--text-opacity:1;color:#81e6d9;color:rgba(129,230,217,var(--text-opacity))}.md\:focus\:text-teal-400:focus{--text-opacity:1;color:#4fd1c5;color:rgba(79,209,197,var(--text-opacity))}.md\:focus\:text-teal-500:focus{--text-opacity:1;color:#38b2ac;color:rgba(56,178,172,var(--text-opacity))}.md\:focus\:text-teal-600:focus{--text-opacity:1;color:#319795;color:rgba(49,151,149,var(--text-opacity))}.md\:focus\:text-teal-700:focus{--text-opacity:1;color:#2c7a7b;color:rgba(44,122,123,var(--text-opacity))}.md\:focus\:text-teal-800:focus{--text-opacity:1;color:#285e61;color:rgba(40,94,97,var(--text-opacity))}.md\:focus\:text-teal-900:focus{--text-opacity:1;color:#234e52;color:rgba(35,78,82,var(--text-opacity))}.md\:focus\:text-blue-100:focus{--text-opacity:1;color:#ebf8ff;color:rgba(235,248,255,var(--text-opacity))}.md\:focus\:text-blue-200:focus{--text-opacity:1;color:#bee3f8;color:rgba(190,227,248,var(--text-opacity))}.md\:focus\:text-blue-300:focus{--text-opacity:1;color:#90cdf4;color:rgba(144,205,244,var(--text-opacity))}.md\:focus\:text-blue-400:focus{--text-opacity:1;color:#63b3ed;color:rgba(99,179,237,var(--text-opacity))}.md\:focus\:text-blue-500:focus{--text-opacity:1;color:#4299e1;color:rgba(66,153,225,var(--text-opacity))}.md\:focus\:text-blue-600:focus{--text-opacity:1;color:#3182ce;color:rgba(49,130,206,var(--text-opacity))}.md\:focus\:text-blue-700:focus{--text-opacity:1;color:#2b6cb0;color:rgba(43,108,176,var(--text-opacity))}.md\:focus\:text-blue-800:focus{--text-opacity:1;color:#2c5282;color:rgba(44,82,130,var(--text-opacity))}.md\:focus\:text-blue-900:focus{--text-opacity:1;color:#2a4365;color:rgba(42,67,101,var(--text-opacity))}.md\:focus\:text-indigo-100:focus{--text-opacity:1;color:#ebf4ff;color:rgba(235,244,255,var(--text-opacity))}.md\:focus\:text-indigo-200:focus{--text-opacity:1;color:#c3dafe;color:rgba(195,218,254,var(--text-opacity))}.md\:focus\:text-indigo-300:focus{--text-opacity:1;color:#a3bffa;color:rgba(163,191,250,var(--text-opacity))}.md\:focus\:text-indigo-400:focus{--text-opacity:1;color:#7f9cf5;color:rgba(127,156,245,var(--text-opacity))}.md\:focus\:text-indigo-500:focus{--text-opacity:1;color:#667eea;color:rgba(102,126,234,var(--text-opacity))}.md\:focus\:text-indigo-600:focus{--text-opacity:1;color:#5a67d8;color:rgba(90,103,216,var(--text-opacity))}.md\:focus\:text-indigo-700:focus{--text-opacity:1;color:#4c51bf;color:rgba(76,81,191,var(--text-opacity))}.md\:focus\:text-indigo-800:focus{--text-opacity:1;color:#434190;color:rgba(67,65,144,var(--text-opacity))}.md\:focus\:text-indigo-900:focus{--text-opacity:1;color:#3c366b;color:rgba(60,54,107,var(--text-opacity))}.md\:focus\:text-purple-100:focus{--text-opacity:1;color:#faf5ff;color:rgba(250,245,255,var(--text-opacity))}.md\:focus\:text-purple-200:focus{--text-opacity:1;color:#e9d8fd;color:rgba(233,216,253,var(--text-opacity))}.md\:focus\:text-purple-300:focus{--text-opacity:1;color:#d6bcfa;color:rgba(214,188,250,var(--text-opacity))}.md\:focus\:text-purple-400:focus{--text-opacity:1;color:#b794f4;color:rgba(183,148,244,var(--text-opacity))}.md\:focus\:text-purple-500:focus{--text-opacity:1;color:#9f7aea;color:rgba(159,122,234,var(--text-opacity))}.md\:focus\:text-purple-600:focus{--text-opacity:1;color:#805ad5;color:rgba(128,90,213,var(--text-opacity))}.md\:focus\:text-purple-700:focus{--text-opacity:1;color:#6b46c1;color:rgba(107,70,193,var(--text-opacity))}.md\:focus\:text-purple-800:focus{--text-opacity:1;color:#553c9a;color:rgba(85,60,154,var(--text-opacity))}.md\:focus\:text-purple-900:focus{--text-opacity:1;color:#44337a;color:rgba(68,51,122,var(--text-opacity))}.md\:focus\:text-pink-100:focus{--text-opacity:1;color:#fff5f7;color:rgba(255,245,247,var(--text-opacity))}.md\:focus\:text-pink-200:focus{--text-opacity:1;color:#fed7e2;color:rgba(254,215,226,var(--text-opacity))}.md\:focus\:text-pink-300:focus{--text-opacity:1;color:#fbb6ce;color:rgba(251,182,206,var(--text-opacity))}.md\:focus\:text-pink-400:focus{--text-opacity:1;color:#f687b3;color:rgba(246,135,179,var(--text-opacity))}.md\:focus\:text-pink-500:focus{--text-opacity:1;color:#ed64a6;color:rgba(237,100,166,var(--text-opacity))}.md\:focus\:text-pink-600:focus{--text-opacity:1;color:#d53f8c;color:rgba(213,63,140,var(--text-opacity))}.md\:focus\:text-pink-700:focus{--text-opacity:1;color:#b83280;color:rgba(184,50,128,var(--text-opacity))}.md\:focus\:text-pink-800:focus{--text-opacity:1;color:#97266d;color:rgba(151,38,109,var(--text-opacity))}.md\:focus\:text-pink-900:focus{--text-opacity:1;color:#702459;color:rgba(112,36,89,var(--text-opacity))}.md\:text-opacity-0{--text-opacity:0}.md\:text-opacity-25{--text-opacity:0.25}.md\:text-opacity-50{--text-opacity:0.5}.md\:text-opacity-75{--text-opacity:0.75}.md\:text-opacity-100{--text-opacity:1}.md\:hover\:text-opacity-0:hover{--text-opacity:0}.md\:hover\:text-opacity-25:hover{--text-opacity:0.25}.md\:hover\:text-opacity-50:hover{--text-opacity:0.5}.md\:hover\:text-opacity-75:hover{--text-opacity:0.75}.md\:hover\:text-opacity-100:hover{--text-opacity:1}.md\:focus\:text-opacity-0:focus{--text-opacity:0}.md\:focus\:text-opacity-25:focus{--text-opacity:0.25}.md\:focus\:text-opacity-50:focus{--text-opacity:0.5}.md\:focus\:text-opacity-75:focus{--text-opacity:0.75}.md\:focus\:text-opacity-100:focus{--text-opacity:1}.md\:italic{font-style:italic}.md\:not-italic{font-style:normal}.md\:uppercase{text-transform:uppercase}.md\:lowercase{text-transform:lowercase}.md\:capitalize{text-transform:capitalize}.md\:normal-case{text-transform:none}.md\:underline{text-decoration:underline}.md\:line-through{text-decoration:line-through}.md\:no-underline{text-decoration:none}.md\:hover\:underline:hover{text-decoration:underline}.md\:hover\:line-through:hover{text-decoration:line-through}.md\:hover\:no-underline:hover{text-decoration:none}.md\:focus\:underline:focus{text-decoration:underline}.md\:focus\:line-through:focus{text-decoration:line-through}.md\:focus\:no-underline:focus{text-decoration:none}.md\:antialiased{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.md\:subpixel-antialiased{-webkit-font-smoothing:auto;-moz-osx-font-smoothing:auto}.md\:diagonal-fractions,.md\:lining-nums,.md\:oldstyle-nums,.md\:ordinal,.md\:proportional-nums,.md\:slashed-zero,.md\:stacked-fractions,.md\:tabular-nums{--font-variant-numeric-ordinal:var(--tailwind-empty, );/*!*//*!*/--font-variant-numeric-slashed-zero:var(--tailwind-empty, );/*!*//*!*/--font-variant-numeric-figure:var(--tailwind-empty, );/*!*//*!*/--font-variant-numeric-spacing:var(--tailwind-empty, );/*!*//*!*/--font-variant-numeric-fraction:var(--tailwind-empty, );/*!*//*!*/font-variant-numeric:var(--font-variant-numeric-ordinal) var(--font-variant-numeric-slashed-zero) var(--font-variant-numeric-figure) var(--font-variant-numeric-spacing) var(--font-variant-numeric-fraction)}.md\:normal-nums{font-variant-numeric:normal}.md\:ordinal{--font-variant-numeric-ordinal:ordinal}.md\:slashed-zero{--font-variant-numeric-slashed-zero:slashed-zero}.md\:lining-nums{--font-variant-numeric-figure:lining-nums}.md\:oldstyle-nums{--font-variant-numeric-figure:oldstyle-nums}.md\:proportional-nums{--font-variant-numeric-spacing:proportional-nums}.md\:tabular-nums{--font-variant-numeric-spacing:tabular-nums}.md\:diagonal-fractions{--font-variant-numeric-fraction:diagonal-fractions}.md\:stacked-fractions{--font-variant-numeric-fraction:stacked-fractions}.md\:tracking-tighter{letter-spacing:-.05em}.md\:tracking-tight{letter-spacing:-.025em}.md\:tracking-normal{letter-spacing:0}.md\:tracking-wide{letter-spacing:.025em}.md\:tracking-wider{letter-spacing:.05em}.md\:tracking-widest{letter-spacing:.1em}.md\:select-none{-webkit-user-select:none;-ms-user-select:none;user-select:none}.md\:select-text{-webkit-user-select:text;-ms-user-select:text;user-select:text}.md\:select-all{-webkit-user-select:all;-ms-user-select:all;user-select:all}.md\:select-auto{-webkit-user-select:auto;-ms-user-select:auto;user-select:auto}.md\:align-baseline{vertical-align:baseline}.md\:align-top{vertical-align:top}.md\:align-middle{vertical-align:middle}.md\:align-bottom{vertical-align:bottom}.md\:align-text-top{vertical-align:text-top}.md\:align-text-bottom{vertical-align:text-bottom}.md\:visible{visibility:visible}.md\:invisible{visibility:hidden}.md\:whitespace-normal{white-space:normal}.md\:whitespace-no-wrap{white-space:nowrap}.md\:whitespace-pre{white-space:pre}.md\:whitespace-pre-line{white-space:pre-line}.md\:whitespace-pre-wrap{white-space:pre-wrap}.md\:break-normal{word-wrap:normal;overflow-wrap:normal;word-break:normal}.md\:break-words{word-wrap:break-word;overflow-wrap:break-word}.md\:break-all{word-break:break-all}.md\:truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.md\:w-0{width:0}.md\:w-1{width:.25rem}.md\:w-2{width:.5rem}.md\:w-3{width:.75rem}.md\:w-4{width:1rem}.md\:w-5{width:1.25rem}.md\:w-6{width:1.5rem}.md\:w-8{width:2rem}.md\:w-10{width:2.5rem}.md\:w-12{width:3rem}.md\:w-16{width:4rem}.md\:w-20{width:5rem}.md\:w-24{width:6rem}.md\:w-32{width:8rem}.md\:w-40{width:10rem}.md\:w-48{width:12rem}.md\:w-56{width:14rem}.md\:w-64{width:16rem}.md\:w-auto{width:auto}.md\:w-px{width:1px}.md\:w-1\/2{width:50%}.md\:w-1\/3{width:33.333333%}.md\:w-2\/3{width:66.666667%}.md\:w-1\/4{width:25%}.md\:w-2\/4{width:50%}.md\:w-3\/4{width:75%}.md\:w-1\/5{width:20%}.md\:w-2\/5{width:40%}.md\:w-3\/5{width:60%}.md\:w-4\/5{width:80%}.md\:w-1\/6{width:16.666667%}.md\:w-2\/6{width:33.333333%}.md\:w-3\/6{width:50%}.md\:w-4\/6{width:66.666667%}.md\:w-5\/6{width:83.333333%}.md\:w-1\/12{width:8.333333%}.md\:w-2\/12{width:16.666667%}.md\:w-3\/12{width:25%}.md\:w-4\/12{width:33.333333%}.md\:w-5\/12{width:41.666667%}.md\:w-6\/12{width:50%}.md\:w-7\/12{width:58.333333%}.md\:w-8\/12{width:66.666667%}.md\:w-9\/12{width:75%}.md\:w-10\/12{width:83.333333%}.md\:w-11\/12{width:91.666667%}.md\:w-full{width:100%}.md\:w-screen{width:100vw}.md\:z-0{z-index:0}.md\:z-10{z-index:10}.md\:z-20{z-index:20}.md\:z-30{z-index:30}.md\:z-40{z-index:40}.md\:z-50{z-index:50}.md\:z-auto{z-index:auto}.md\:gap-0{grid-gap:0;gap:0}.md\:gap-1{grid-gap:.25rem;gap:.25rem}.md\:gap-2{grid-gap:.5rem;gap:.5rem}.md\:gap-3{grid-gap:.75rem;gap:.75rem}.md\:gap-4{grid-gap:1rem;gap:1rem}.md\:gap-5{grid-gap:1.25rem;gap:1.25rem}.md\:gap-6{grid-gap:1.5rem;gap:1.5rem}.md\:gap-8{grid-gap:2rem;gap:2rem}.md\:gap-10{grid-gap:2.5rem;gap:2.5rem}.md\:gap-12{grid-gap:3rem;gap:3rem}.md\:gap-16{grid-gap:4rem;gap:4rem}.md\:gap-20{grid-gap:5rem;gap:5rem}.md\:gap-24{grid-gap:6rem;gap:6rem}.md\:gap-32{grid-gap:8rem;gap:8rem}.md\:gap-40{grid-gap:10rem;gap:10rem}.md\:gap-48{grid-gap:12rem;gap:12rem}.md\:gap-56{grid-gap:14rem;gap:14rem}.md\:gap-64{grid-gap:16rem;gap:16rem}.md\:gap-px{grid-gap:1px;gap:1px}.md\:col-gap-0{grid-column-gap:0;column-gap:0}.md\:col-gap-1{grid-column-gap:.25rem;column-gap:.25rem}.md\:col-gap-2{grid-column-gap:.5rem;column-gap:.5rem}.md\:col-gap-3{grid-column-gap:.75rem;column-gap:.75rem}.md\:col-gap-4{grid-column-gap:1rem;column-gap:1rem}.md\:col-gap-5{grid-column-gap:1.25rem;column-gap:1.25rem}.md\:col-gap-6{grid-column-gap:1.5rem;column-gap:1.5rem}.md\:col-gap-8{grid-column-gap:2rem;column-gap:2rem}.md\:col-gap-10{grid-column-gap:2.5rem;column-gap:2.5rem}.md\:col-gap-12{grid-column-gap:3rem;column-gap:3rem}.md\:col-gap-16{grid-column-gap:4rem;column-gap:4rem}.md\:col-gap-20{grid-column-gap:5rem;column-gap:5rem}.md\:col-gap-24{grid-column-gap:6rem;column-gap:6rem}.md\:col-gap-32{grid-column-gap:8rem;column-gap:8rem}.md\:col-gap-40{grid-column-gap:10rem;column-gap:10rem}.md\:col-gap-48{grid-column-gap:12rem;column-gap:12rem}.md\:col-gap-56{grid-column-gap:14rem;column-gap:14rem}.md\:col-gap-64{grid-column-gap:16rem;column-gap:16rem}.md\:col-gap-px{grid-column-gap:1px;column-gap:1px}.md\:gap-x-0{grid-column-gap:0;column-gap:0}.md\:gap-x-1{grid-column-gap:.25rem;column-gap:.25rem}.md\:gap-x-2{grid-column-gap:.5rem;column-gap:.5rem}.md\:gap-x-3{grid-column-gap:.75rem;column-gap:.75rem}.md\:gap-x-4{grid-column-gap:1rem;column-gap:1rem}.md\:gap-x-5{grid-column-gap:1.25rem;column-gap:1.25rem}.md\:gap-x-6{grid-column-gap:1.5rem;column-gap:1.5rem}.md\:gap-x-8{grid-column-gap:2rem;column-gap:2rem}.md\:gap-x-10{grid-column-gap:2.5rem;column-gap:2.5rem}.md\:gap-x-12{grid-column-gap:3rem;column-gap:3rem}.md\:gap-x-16{grid-column-gap:4rem;column-gap:4rem}.md\:gap-x-20{grid-column-gap:5rem;column-gap:5rem}.md\:gap-x-24{grid-column-gap:6rem;column-gap:6rem}.md\:gap-x-32{grid-column-gap:8rem;column-gap:8rem}.md\:gap-x-40{grid-column-gap:10rem;column-gap:10rem}.md\:gap-x-48{grid-column-gap:12rem;column-gap:12rem}.md\:gap-x-56{grid-column-gap:14rem;column-gap:14rem}.md\:gap-x-64{grid-column-gap:16rem;column-gap:16rem}.md\:gap-x-px{grid-column-gap:1px;column-gap:1px}.md\:row-gap-0{grid-row-gap:0;row-gap:0}.md\:row-gap-1{grid-row-gap:.25rem;row-gap:.25rem}.md\:row-gap-2{grid-row-gap:.5rem;row-gap:.5rem}.md\:row-gap-3{grid-row-gap:.75rem;row-gap:.75rem}.md\:row-gap-4{grid-row-gap:1rem;row-gap:1rem}.md\:row-gap-5{grid-row-gap:1.25rem;row-gap:1.25rem}.md\:row-gap-6{grid-row-gap:1.5rem;row-gap:1.5rem}.md\:row-gap-8{grid-row-gap:2rem;row-gap:2rem}.md\:row-gap-10{grid-row-gap:2.5rem;row-gap:2.5rem}.md\:row-gap-12{grid-row-gap:3rem;row-gap:3rem}.md\:row-gap-16{grid-row-gap:4rem;row-gap:4rem}.md\:row-gap-20{grid-row-gap:5rem;row-gap:5rem}.md\:row-gap-24{grid-row-gap:6rem;row-gap:6rem}.md\:row-gap-32{grid-row-gap:8rem;row-gap:8rem}.md\:row-gap-40{grid-row-gap:10rem;row-gap:10rem}.md\:row-gap-48{grid-row-gap:12rem;row-gap:12rem}.md\:row-gap-56{grid-row-gap:14rem;row-gap:14rem}.md\:row-gap-64{grid-row-gap:16rem;row-gap:16rem}.md\:row-gap-px{grid-row-gap:1px;row-gap:1px}.md\:gap-y-0{grid-row-gap:0;row-gap:0}.md\:gap-y-1{grid-row-gap:.25rem;row-gap:.25rem}.md\:gap-y-2{grid-row-gap:.5rem;row-gap:.5rem}.md\:gap-y-3{grid-row-gap:.75rem;row-gap:.75rem}.md\:gap-y-4{grid-row-gap:1rem;row-gap:1rem}.md\:gap-y-5{grid-row-gap:1.25rem;row-gap:1.25rem}.md\:gap-y-6{grid-row-gap:1.5rem;row-gap:1.5rem}.md\:gap-y-8{grid-row-gap:2rem;row-gap:2rem}.md\:gap-y-10{grid-row-gap:2.5rem;row-gap:2.5rem}.md\:gap-y-12{grid-row-gap:3rem;row-gap:3rem}.md\:gap-y-16{grid-row-gap:4rem;row-gap:4rem}.md\:gap-y-20{grid-row-gap:5rem;row-gap:5rem}.md\:gap-y-24{grid-row-gap:6rem;row-gap:6rem}.md\:gap-y-32{grid-row-gap:8rem;row-gap:8rem}.md\:gap-y-40{grid-row-gap:10rem;row-gap:10rem}.md\:gap-y-48{grid-row-gap:12rem;row-gap:12rem}.md\:gap-y-56{grid-row-gap:14rem;row-gap:14rem}.md\:gap-y-64{grid-row-gap:16rem;row-gap:16rem}.md\:gap-y-px{grid-row-gap:1px;row-gap:1px}.md\:grid-flow-row{grid-auto-flow:row}.md\:grid-flow-col{grid-auto-flow:column}.md\:grid-flow-row-dense{grid-auto-flow:row dense}.md\:grid-flow-col-dense{grid-auto-flow:column dense}.md\:grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.md\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.md\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.md\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.md\:grid-cols-5{grid-template-columns:repeat(5,minmax(0,1fr))}.md\:grid-cols-6{grid-template-columns:repeat(6,minmax(0,1fr))}.md\:grid-cols-7{grid-template-columns:repeat(7,minmax(0,1fr))}.md\:grid-cols-8{grid-template-columns:repeat(8,minmax(0,1fr))}.md\:grid-cols-9{grid-template-columns:repeat(9,minmax(0,1fr))}.md\:grid-cols-10{grid-template-columns:repeat(10,minmax(0,1fr))}.md\:grid-cols-11{grid-template-columns:repeat(11,minmax(0,1fr))}.md\:grid-cols-12{grid-template-columns:repeat(12,minmax(0,1fr))}.md\:grid-cols-none{grid-template-columns:none}.md\:auto-cols-auto{grid-auto-columns:auto}.md\:auto-cols-min{grid-auto-columns:-webkit-min-content;grid-auto-columns:min-content}.md\:auto-cols-max{grid-auto-columns:-webkit-max-content;grid-auto-columns:max-content}.md\:auto-cols-fr{grid-auto-columns:minmax(0,1fr)}.md\:col-auto{grid-column:auto}.md\:col-span-1{grid-column:span 1/span 1}.md\:col-span-2{grid-column:span 2/span 2}.md\:col-span-3{grid-column:span 3/span 3}.md\:col-span-4{grid-column:span 4/span 4}.md\:col-span-5{grid-column:span 5/span 5}.md\:col-span-6{grid-column:span 6/span 6}.md\:col-span-7{grid-column:span 7/span 7}.md\:col-span-8{grid-column:span 8/span 8}.md\:col-span-9{grid-column:span 9/span 9}.md\:col-span-10{grid-column:span 10/span 10}.md\:col-span-11{grid-column:span 11/span 11}.md\:col-span-12{grid-column:span 12/span 12}.md\:col-span-full{grid-column:1/-1}.md\:col-start-1{grid-column-start:1}.md\:col-start-2{grid-column-start:2}.md\:col-start-3{grid-column-start:3}.md\:col-start-4{grid-column-start:4}.md\:col-start-5{grid-column-start:5}.md\:col-start-6{grid-column-start:6}.md\:col-start-7{grid-column-start:7}.md\:col-start-8{grid-column-start:8}.md\:col-start-9{grid-column-start:9}.md\:col-start-10{grid-column-start:10}.md\:col-start-11{grid-column-start:11}.md\:col-start-12{grid-column-start:12}.md\:col-start-13{grid-column-start:13}.md\:col-start-auto{grid-column-start:auto}.md\:col-end-1{grid-column-end:1}.md\:col-end-2{grid-column-end:2}.md\:col-end-3{grid-column-end:3}.md\:col-end-4{grid-column-end:4}.md\:col-end-5{grid-column-end:5}.md\:col-end-6{grid-column-end:6}.md\:col-end-7{grid-column-end:7}.md\:col-end-8{grid-column-end:8}.md\:col-end-9{grid-column-end:9}.md\:col-end-10{grid-column-end:10}.md\:col-end-11{grid-column-end:11}.md\:col-end-12{grid-column-end:12}.md\:col-end-13{grid-column-end:13}.md\:col-end-auto{grid-column-end:auto}.md\:grid-rows-1{grid-template-rows:repeat(1,minmax(0,1fr))}.md\:grid-rows-2{grid-template-rows:repeat(2,minmax(0,1fr))}.md\:grid-rows-3{grid-template-rows:repeat(3,minmax(0,1fr))}.md\:grid-rows-4{grid-template-rows:repeat(4,minmax(0,1fr))}.md\:grid-rows-5{grid-template-rows:repeat(5,minmax(0,1fr))}.md\:grid-rows-6{grid-template-rows:repeat(6,minmax(0,1fr))}.md\:grid-rows-none{grid-template-rows:none}.md\:auto-rows-auto{grid-auto-rows:auto}.md\:auto-rows-min{grid-auto-rows:-webkit-min-content;grid-auto-rows:min-content}.md\:auto-rows-max{grid-auto-rows:-webkit-max-content;grid-auto-rows:max-content}.md\:auto-rows-fr{grid-auto-rows:minmax(0,1fr)}.md\:row-auto{grid-row:auto}.md\:row-span-1{grid-row:span 1/span 1}.md\:row-span-2{grid-row:span 2/span 2}.md\:row-span-3{grid-row:span 3/span 3}.md\:row-span-4{grid-row:span 4/span 4}.md\:row-span-5{grid-row:span 5/span 5}.md\:row-span-6{grid-row:span 6/span 6}.md\:row-span-full{grid-row:1/-1}.md\:row-start-1{grid-row-start:1}.md\:row-start-2{grid-row-start:2}.md\:row-start-3{grid-row-start:3}.md\:row-start-4{grid-row-start:4}.md\:row-start-5{grid-row-start:5}.md\:row-start-6{grid-row-start:6}.md\:row-start-7{grid-row-start:7}.md\:row-start-auto{grid-row-start:auto}.md\:row-end-1{grid-row-end:1}.md\:row-end-2{grid-row-end:2}.md\:row-end-3{grid-row-end:3}.md\:row-end-4{grid-row-end:4}.md\:row-end-5{grid-row-end:5}.md\:row-end-6{grid-row-end:6}.md\:row-end-7{grid-row-end:7}.md\:row-end-auto{grid-row-end:auto}.md\:transform{--transform-translate-x:0;--transform-translate-y:0;--transform-rotate:0;--transform-skew-x:0;--transform-skew-y:0;--transform-scale-x:1;--transform-scale-y:1;transform:translateX(var(--transform-translate-x)) translateY(var(--transform-translate-y)) rotate(var(--transform-rotate)) skewX(var(--transform-skew-x)) skewY(var(--transform-skew-y)) scaleX(var(--transform-scale-x)) scaleY(var(--transform-scale-y))}.md\:transform-none{transform:none}.md\:origin-center{transform-origin:center}.md\:origin-top{transform-origin:top}.md\:origin-top-right{transform-origin:top right}.md\:origin-right{transform-origin:right}.md\:origin-bottom-right{transform-origin:bottom right}.md\:origin-bottom{transform-origin:bottom}.md\:origin-bottom-left{transform-origin:bottom left}.md\:origin-left{transform-origin:left}.md\:origin-top-left{transform-origin:top left}.md\:scale-0{--transform-scale-x:0;--transform-scale-y:0}.md\:scale-50{--transform-scale-x:.5;--transform-scale-y:.5}.md\:scale-75{--transform-scale-x:.75;--transform-scale-y:.75}.md\:scale-90{--transform-scale-x:.9;--transform-scale-y:.9}.md\:scale-95{--transform-scale-x:.95;--transform-scale-y:.95}.md\:scale-100{--transform-scale-x:1;--transform-scale-y:1}.md\:scale-105{--transform-scale-x:1.05;--transform-scale-y:1.05}.md\:scale-110{--transform-scale-x:1.1;--transform-scale-y:1.1}.md\:scale-125{--transform-scale-x:1.25;--transform-scale-y:1.25}.md\:scale-150{--transform-scale-x:1.5;--transform-scale-y:1.5}.md\:scale-x-0{--transform-scale-x:0}.md\:scale-x-50{--transform-scale-x:.5}.md\:scale-x-75{--transform-scale-x:.75}.md\:scale-x-90{--transform-scale-x:.9}.md\:scale-x-95{--transform-scale-x:.95}.md\:scale-x-100{--transform-scale-x:1}.md\:scale-x-105{--transform-scale-x:1.05}.md\:scale-x-110{--transform-scale-x:1.1}.md\:scale-x-125{--transform-scale-x:1.25}.md\:scale-x-150{--transform-scale-x:1.5}.md\:scale-y-0{--transform-scale-y:0}.md\:scale-y-50{--transform-scale-y:.5}.md\:scale-y-75{--transform-scale-y:.75}.md\:scale-y-90{--transform-scale-y:.9}.md\:scale-y-95{--transform-scale-y:.95}.md\:scale-y-100{--transform-scale-y:1}.md\:scale-y-105{--transform-scale-y:1.05}.md\:scale-y-110{--transform-scale-y:1.1}.md\:scale-y-125{--transform-scale-y:1.25}.md\:scale-y-150{--transform-scale-y:1.5}.md\:hover\:scale-0:hover{--transform-scale-x:0;--transform-scale-y:0}.md\:hover\:scale-50:hover{--transform-scale-x:.5;--transform-scale-y:.5}.md\:hover\:scale-75:hover{--transform-scale-x:.75;--transform-scale-y:.75}.md\:hover\:scale-90:hover{--transform-scale-x:.9;--transform-scale-y:.9}.md\:hover\:scale-95:hover{--transform-scale-x:.95;--transform-scale-y:.95}.md\:hover\:scale-100:hover{--transform-scale-x:1;--transform-scale-y:1}.md\:hover\:scale-105:hover{--transform-scale-x:1.05;--transform-scale-y:1.05}.md\:hover\:scale-110:hover{--transform-scale-x:1.1;--transform-scale-y:1.1}.md\:hover\:scale-125:hover{--transform-scale-x:1.25;--transform-scale-y:1.25}.md\:hover\:scale-150:hover{--transform-scale-x:1.5;--transform-scale-y:1.5}.md\:hover\:scale-x-0:hover{--transform-scale-x:0}.md\:hover\:scale-x-50:hover{--transform-scale-x:.5}.md\:hover\:scale-x-75:hover{--transform-scale-x:.75}.md\:hover\:scale-x-90:hover{--transform-scale-x:.9}.md\:hover\:scale-x-95:hover{--transform-scale-x:.95}.md\:hover\:scale-x-100:hover{--transform-scale-x:1}.md\:hover\:scale-x-105:hover{--transform-scale-x:1.05}.md\:hover\:scale-x-110:hover{--transform-scale-x:1.1}.md\:hover\:scale-x-125:hover{--transform-scale-x:1.25}.md\:hover\:scale-x-150:hover{--transform-scale-x:1.5}.md\:hover\:scale-y-0:hover{--transform-scale-y:0}.md\:hover\:scale-y-50:hover{--transform-scale-y:.5}.md\:hover\:scale-y-75:hover{--transform-scale-y:.75}.md\:hover\:scale-y-90:hover{--transform-scale-y:.9}.md\:hover\:scale-y-95:hover{--transform-scale-y:.95}.md\:hover\:scale-y-100:hover{--transform-scale-y:1}.md\:hover\:scale-y-105:hover{--transform-scale-y:1.05}.md\:hover\:scale-y-110:hover{--transform-scale-y:1.1}.md\:hover\:scale-y-125:hover{--transform-scale-y:1.25}.md\:hover\:scale-y-150:hover{--transform-scale-y:1.5}.md\:focus\:scale-0:focus{--transform-scale-x:0;--transform-scale-y:0}.md\:focus\:scale-50:focus{--transform-scale-x:.5;--transform-scale-y:.5}.md\:focus\:scale-75:focus{--transform-scale-x:.75;--transform-scale-y:.75}.md\:focus\:scale-90:focus{--transform-scale-x:.9;--transform-scale-y:.9}.md\:focus\:scale-95:focus{--transform-scale-x:.95;--transform-scale-y:.95}.md\:focus\:scale-100:focus{--transform-scale-x:1;--transform-scale-y:1}.md\:focus\:scale-105:focus{--transform-scale-x:1.05;--transform-scale-y:1.05}.md\:focus\:scale-110:focus{--transform-scale-x:1.1;--transform-scale-y:1.1}.md\:focus\:scale-125:focus{--transform-scale-x:1.25;--transform-scale-y:1.25}.md\:focus\:scale-150:focus{--transform-scale-x:1.5;--transform-scale-y:1.5}.md\:focus\:scale-x-0:focus{--transform-scale-x:0}.md\:focus\:scale-x-50:focus{--transform-scale-x:.5}.md\:focus\:scale-x-75:focus{--transform-scale-x:.75}.md\:focus\:scale-x-90:focus{--transform-scale-x:.9}.md\:focus\:scale-x-95:focus{--transform-scale-x:.95}.md\:focus\:scale-x-100:focus{--transform-scale-x:1}.md\:focus\:scale-x-105:focus{--transform-scale-x:1.05}.md\:focus\:scale-x-110:focus{--transform-scale-x:1.1}.md\:focus\:scale-x-125:focus{--transform-scale-x:1.25}.md\:focus\:scale-x-150:focus{--transform-scale-x:1.5}.md\:focus\:scale-y-0:focus{--transform-scale-y:0}.md\:focus\:scale-y-50:focus{--transform-scale-y:.5}.md\:focus\:scale-y-75:focus{--transform-scale-y:.75}.md\:focus\:scale-y-90:focus{--transform-scale-y:.9}.md\:focus\:scale-y-95:focus{--transform-scale-y:.95}.md\:focus\:scale-y-100:focus{--transform-scale-y:1}.md\:focus\:scale-y-105:focus{--transform-scale-y:1.05}.md\:focus\:scale-y-110:focus{--transform-scale-y:1.1}.md\:focus\:scale-y-125:focus{--transform-scale-y:1.25}.md\:focus\:scale-y-150:focus{--transform-scale-y:1.5}.md\:rotate-0{--transform-rotate:0}.md\:rotate-1{--transform-rotate:1deg}.md\:rotate-2{--transform-rotate:2deg}.md\:rotate-3{--transform-rotate:3deg}.md\:rotate-6{--transform-rotate:6deg}.md\:rotate-12{--transform-rotate:12deg}.md\:rotate-45{--transform-rotate:45deg}.md\:rotate-90{--transform-rotate:90deg}.md\:rotate-180{--transform-rotate:180deg}.md\:-rotate-180{--transform-rotate:-180deg}.md\:-rotate-90{--transform-rotate:-90deg}.md\:-rotate-45{--transform-rotate:-45deg}.md\:-rotate-12{--transform-rotate:-12deg}.md\:-rotate-6{--transform-rotate:-6deg}.md\:-rotate-3{--transform-rotate:-3deg}.md\:-rotate-2{--transform-rotate:-2deg}.md\:-rotate-1{--transform-rotate:-1deg}.md\:hover\:rotate-0:hover{--transform-rotate:0}.md\:hover\:rotate-1:hover{--transform-rotate:1deg}.md\:hover\:rotate-2:hover{--transform-rotate:2deg}.md\:hover\:rotate-3:hover{--transform-rotate:3deg}.md\:hover\:rotate-6:hover{--transform-rotate:6deg}.md\:hover\:rotate-12:hover{--transform-rotate:12deg}.md\:hover\:rotate-45:hover{--transform-rotate:45deg}.md\:hover\:rotate-90:hover{--transform-rotate:90deg}.md\:hover\:rotate-180:hover{--transform-rotate:180deg}.md\:hover\:-rotate-180:hover{--transform-rotate:-180deg}.md\:hover\:-rotate-90:hover{--transform-rotate:-90deg}.md\:hover\:-rotate-45:hover{--transform-rotate:-45deg}.md\:hover\:-rotate-12:hover{--transform-rotate:-12deg}.md\:hover\:-rotate-6:hover{--transform-rotate:-6deg}.md\:hover\:-rotate-3:hover{--transform-rotate:-3deg}.md\:hover\:-rotate-2:hover{--transform-rotate:-2deg}.md\:hover\:-rotate-1:hover{--transform-rotate:-1deg}.md\:focus\:rotate-0:focus{--transform-rotate:0}.md\:focus\:rotate-1:focus{--transform-rotate:1deg}.md\:focus\:rotate-2:focus{--transform-rotate:2deg}.md\:focus\:rotate-3:focus{--transform-rotate:3deg}.md\:focus\:rotate-6:focus{--transform-rotate:6deg}.md\:focus\:rotate-12:focus{--transform-rotate:12deg}.md\:focus\:rotate-45:focus{--transform-rotate:45deg}.md\:focus\:rotate-90:focus{--transform-rotate:90deg}.md\:focus\:rotate-180:focus{--transform-rotate:180deg}.md\:focus\:-rotate-180:focus{--transform-rotate:-180deg}.md\:focus\:-rotate-90:focus{--transform-rotate:-90deg}.md\:focus\:-rotate-45:focus{--transform-rotate:-45deg}.md\:focus\:-rotate-12:focus{--transform-rotate:-12deg}.md\:focus\:-rotate-6:focus{--transform-rotate:-6deg}.md\:focus\:-rotate-3:focus{--transform-rotate:-3deg}.md\:focus\:-rotate-2:focus{--transform-rotate:-2deg}.md\:focus\:-rotate-1:focus{--transform-rotate:-1deg}.md\:translate-x-0{--transform-translate-x:0}.md\:translate-x-1{--transform-translate-x:0.25rem}.md\:translate-x-2{--transform-translate-x:0.5rem}.md\:translate-x-3{--transform-translate-x:0.75rem}.md\:translate-x-4{--transform-translate-x:1rem}.md\:translate-x-5{--transform-translate-x:1.25rem}.md\:translate-x-6{--transform-translate-x:1.5rem}.md\:translate-x-8{--transform-translate-x:2rem}.md\:translate-x-10{--transform-translate-x:2.5rem}.md\:translate-x-12{--transform-translate-x:3rem}.md\:translate-x-16{--transform-translate-x:4rem}.md\:translate-x-20{--transform-translate-x:5rem}.md\:translate-x-24{--transform-translate-x:6rem}.md\:translate-x-32{--transform-translate-x:8rem}.md\:translate-x-40{--transform-translate-x:10rem}.md\:translate-x-48{--transform-translate-x:12rem}.md\:translate-x-56{--transform-translate-x:14rem}.md\:translate-x-64{--transform-translate-x:16rem}.md\:translate-x-px{--transform-translate-x:1px}.md\:-translate-x-1{--transform-translate-x:-0.25rem}.md\:-translate-x-2{--transform-translate-x:-0.5rem}.md\:-translate-x-3{--transform-translate-x:-0.75rem}.md\:-translate-x-4{--transform-translate-x:-1rem}.md\:-translate-x-5{--transform-translate-x:-1.25rem}.md\:-translate-x-6{--transform-translate-x:-1.5rem}.md\:-translate-x-8{--transform-translate-x:-2rem}.md\:-translate-x-10{--transform-translate-x:-2.5rem}.md\:-translate-x-12{--transform-translate-x:-3rem}.md\:-translate-x-16{--transform-translate-x:-4rem}.md\:-translate-x-20{--transform-translate-x:-5rem}.md\:-translate-x-24{--transform-translate-x:-6rem}.md\:-translate-x-32{--transform-translate-x:-8rem}.md\:-translate-x-40{--transform-translate-x:-10rem}.md\:-translate-x-48{--transform-translate-x:-12rem}.md\:-translate-x-56{--transform-translate-x:-14rem}.md\:-translate-x-64{--transform-translate-x:-16rem}.md\:-translate-x-px{--transform-translate-x:-1px}.md\:-translate-x-full{--transform-translate-x:-100%}.md\:-translate-x-1\/2{--transform-translate-x:-50%}.md\:translate-x-1\/2{--transform-translate-x:50%}.md\:translate-x-full{--transform-translate-x:100%}.md\:translate-y-0{--transform-translate-y:0}.md\:translate-y-1{--transform-translate-y:0.25rem}.md\:translate-y-2{--transform-translate-y:0.5rem}.md\:translate-y-3{--transform-translate-y:0.75rem}.md\:translate-y-4{--transform-translate-y:1rem}.md\:translate-y-5{--transform-translate-y:1.25rem}.md\:translate-y-6{--transform-translate-y:1.5rem}.md\:translate-y-8{--transform-translate-y:2rem}.md\:translate-y-10{--transform-translate-y:2.5rem}.md\:translate-y-12{--transform-translate-y:3rem}.md\:translate-y-16{--transform-translate-y:4rem}.md\:translate-y-20{--transform-translate-y:5rem}.md\:translate-y-24{--transform-translate-y:6rem}.md\:translate-y-32{--transform-translate-y:8rem}.md\:translate-y-40{--transform-translate-y:10rem}.md\:translate-y-48{--transform-translate-y:12rem}.md\:translate-y-56{--transform-translate-y:14rem}.md\:translate-y-64{--transform-translate-y:16rem}.md\:translate-y-px{--transform-translate-y:1px}.md\:-translate-y-1{--transform-translate-y:-0.25rem}.md\:-translate-y-2{--transform-translate-y:-0.5rem}.md\:-translate-y-3{--transform-translate-y:-0.75rem}.md\:-translate-y-4{--transform-translate-y:-1rem}.md\:-translate-y-5{--transform-translate-y:-1.25rem}.md\:-translate-y-6{--transform-translate-y:-1.5rem}.md\:-translate-y-8{--transform-translate-y:-2rem}.md\:-translate-y-10{--transform-translate-y:-2.5rem}.md\:-translate-y-12{--transform-translate-y:-3rem}.md\:-translate-y-16{--transform-translate-y:-4rem}.md\:-translate-y-20{--transform-translate-y:-5rem}.md\:-translate-y-24{--transform-translate-y:-6rem}.md\:-translate-y-32{--transform-translate-y:-8rem}.md\:-translate-y-40{--transform-translate-y:-10rem}.md\:-translate-y-48{--transform-translate-y:-12rem}.md\:-translate-y-56{--transform-translate-y:-14rem}.md\:-translate-y-64{--transform-translate-y:-16rem}.md\:-translate-y-px{--transform-translate-y:-1px}.md\:-translate-y-full{--transform-translate-y:-100%}.md\:-translate-y-1\/2{--transform-translate-y:-50%}.md\:translate-y-1\/2{--transform-translate-y:50%}.md\:translate-y-full{--transform-translate-y:100%}.md\:hover\:translate-x-0:hover{--transform-translate-x:0}.md\:hover\:translate-x-1:hover{--transform-translate-x:0.25rem}.md\:hover\:translate-x-2:hover{--transform-translate-x:0.5rem}.md\:hover\:translate-x-3:hover{--transform-translate-x:0.75rem}.md\:hover\:translate-x-4:hover{--transform-translate-x:1rem}.md\:hover\:translate-x-5:hover{--transform-translate-x:1.25rem}.md\:hover\:translate-x-6:hover{--transform-translate-x:1.5rem}.md\:hover\:translate-x-8:hover{--transform-translate-x:2rem}.md\:hover\:translate-x-10:hover{--transform-translate-x:2.5rem}.md\:hover\:translate-x-12:hover{--transform-translate-x:3rem}.md\:hover\:translate-x-16:hover{--transform-translate-x:4rem}.md\:hover\:translate-x-20:hover{--transform-translate-x:5rem}.md\:hover\:translate-x-24:hover{--transform-translate-x:6rem}.md\:hover\:translate-x-32:hover{--transform-translate-x:8rem}.md\:hover\:translate-x-40:hover{--transform-translate-x:10rem}.md\:hover\:translate-x-48:hover{--transform-translate-x:12rem}.md\:hover\:translate-x-56:hover{--transform-translate-x:14rem}.md\:hover\:translate-x-64:hover{--transform-translate-x:16rem}.md\:hover\:translate-x-px:hover{--transform-translate-x:1px}.md\:hover\:-translate-x-1:hover{--transform-translate-x:-0.25rem}.md\:hover\:-translate-x-2:hover{--transform-translate-x:-0.5rem}.md\:hover\:-translate-x-3:hover{--transform-translate-x:-0.75rem}.md\:hover\:-translate-x-4:hover{--transform-translate-x:-1rem}.md\:hover\:-translate-x-5:hover{--transform-translate-x:-1.25rem}.md\:hover\:-translate-x-6:hover{--transform-translate-x:-1.5rem}.md\:hover\:-translate-x-8:hover{--transform-translate-x:-2rem}.md\:hover\:-translate-x-10:hover{--transform-translate-x:-2.5rem}.md\:hover\:-translate-x-12:hover{--transform-translate-x:-3rem}.md\:hover\:-translate-x-16:hover{--transform-translate-x:-4rem}.md\:hover\:-translate-x-20:hover{--transform-translate-x:-5rem}.md\:hover\:-translate-x-24:hover{--transform-translate-x:-6rem}.md\:hover\:-translate-x-32:hover{--transform-translate-x:-8rem}.md\:hover\:-translate-x-40:hover{--transform-translate-x:-10rem}.md\:hover\:-translate-x-48:hover{--transform-translate-x:-12rem}.md\:hover\:-translate-x-56:hover{--transform-translate-x:-14rem}.md\:hover\:-translate-x-64:hover{--transform-translate-x:-16rem}.md\:hover\:-translate-x-px:hover{--transform-translate-x:-1px}.md\:hover\:-translate-x-full:hover{--transform-translate-x:-100%}.md\:hover\:-translate-x-1\/2:hover{--transform-translate-x:-50%}.md\:hover\:translate-x-1\/2:hover{--transform-translate-x:50%}.md\:hover\:translate-x-full:hover{--transform-translate-x:100%}.md\:hover\:translate-y-0:hover{--transform-translate-y:0}.md\:hover\:translate-y-1:hover{--transform-translate-y:0.25rem}.md\:hover\:translate-y-2:hover{--transform-translate-y:0.5rem}.md\:hover\:translate-y-3:hover{--transform-translate-y:0.75rem}.md\:hover\:translate-y-4:hover{--transform-translate-y:1rem}.md\:hover\:translate-y-5:hover{--transform-translate-y:1.25rem}.md\:hover\:translate-y-6:hover{--transform-translate-y:1.5rem}.md\:hover\:translate-y-8:hover{--transform-translate-y:2rem}.md\:hover\:translate-y-10:hover{--transform-translate-y:2.5rem}.md\:hover\:translate-y-12:hover{--transform-translate-y:3rem}.md\:hover\:translate-y-16:hover{--transform-translate-y:4rem}.md\:hover\:translate-y-20:hover{--transform-translate-y:5rem}.md\:hover\:translate-y-24:hover{--transform-translate-y:6rem}.md\:hover\:translate-y-32:hover{--transform-translate-y:8rem}.md\:hover\:translate-y-40:hover{--transform-translate-y:10rem}.md\:hover\:translate-y-48:hover{--transform-translate-y:12rem}.md\:hover\:translate-y-56:hover{--transform-translate-y:14rem}.md\:hover\:translate-y-64:hover{--transform-translate-y:16rem}.md\:hover\:translate-y-px:hover{--transform-translate-y:1px}.md\:hover\:-translate-y-1:hover{--transform-translate-y:-0.25rem}.md\:hover\:-translate-y-2:hover{--transform-translate-y:-0.5rem}.md\:hover\:-translate-y-3:hover{--transform-translate-y:-0.75rem}.md\:hover\:-translate-y-4:hover{--transform-translate-y:-1rem}.md\:hover\:-translate-y-5:hover{--transform-translate-y:-1.25rem}.md\:hover\:-translate-y-6:hover{--transform-translate-y:-1.5rem}.md\:hover\:-translate-y-8:hover{--transform-translate-y:-2rem}.md\:hover\:-translate-y-10:hover{--transform-translate-y:-2.5rem}.md\:hover\:-translate-y-12:hover{--transform-translate-y:-3rem}.md\:hover\:-translate-y-16:hover{--transform-translate-y:-4rem}.md\:hover\:-translate-y-20:hover{--transform-translate-y:-5rem}.md\:hover\:-translate-y-24:hover{--transform-translate-y:-6rem}.md\:hover\:-translate-y-32:hover{--transform-translate-y:-8rem}.md\:hover\:-translate-y-40:hover{--transform-translate-y:-10rem}.md\:hover\:-translate-y-48:hover{--transform-translate-y:-12rem}.md\:hover\:-translate-y-56:hover{--transform-translate-y:-14rem}.md\:hover\:-translate-y-64:hover{--transform-translate-y:-16rem}.md\:hover\:-translate-y-px:hover{--transform-translate-y:-1px}.md\:hover\:-translate-y-full:hover{--transform-translate-y:-100%}.md\:hover\:-translate-y-1\/2:hover{--transform-translate-y:-50%}.md\:hover\:translate-y-1\/2:hover{--transform-translate-y:50%}.md\:hover\:translate-y-full:hover{--transform-translate-y:100%}.md\:focus\:translate-x-0:focus{--transform-translate-x:0}.md\:focus\:translate-x-1:focus{--transform-translate-x:0.25rem}.md\:focus\:translate-x-2:focus{--transform-translate-x:0.5rem}.md\:focus\:translate-x-3:focus{--transform-translate-x:0.75rem}.md\:focus\:translate-x-4:focus{--transform-translate-x:1rem}.md\:focus\:translate-x-5:focus{--transform-translate-x:1.25rem}.md\:focus\:translate-x-6:focus{--transform-translate-x:1.5rem}.md\:focus\:translate-x-8:focus{--transform-translate-x:2rem}.md\:focus\:translate-x-10:focus{--transform-translate-x:2.5rem}.md\:focus\:translate-x-12:focus{--transform-translate-x:3rem}.md\:focus\:translate-x-16:focus{--transform-translate-x:4rem}.md\:focus\:translate-x-20:focus{--transform-translate-x:5rem}.md\:focus\:translate-x-24:focus{--transform-translate-x:6rem}.md\:focus\:translate-x-32:focus{--transform-translate-x:8rem}.md\:focus\:translate-x-40:focus{--transform-translate-x:10rem}.md\:focus\:translate-x-48:focus{--transform-translate-x:12rem}.md\:focus\:translate-x-56:focus{--transform-translate-x:14rem}.md\:focus\:translate-x-64:focus{--transform-translate-x:16rem}.md\:focus\:translate-x-px:focus{--transform-translate-x:1px}.md\:focus\:-translate-x-1:focus{--transform-translate-x:-0.25rem}.md\:focus\:-translate-x-2:focus{--transform-translate-x:-0.5rem}.md\:focus\:-translate-x-3:focus{--transform-translate-x:-0.75rem}.md\:focus\:-translate-x-4:focus{--transform-translate-x:-1rem}.md\:focus\:-translate-x-5:focus{--transform-translate-x:-1.25rem}.md\:focus\:-translate-x-6:focus{--transform-translate-x:-1.5rem}.md\:focus\:-translate-x-8:focus{--transform-translate-x:-2rem}.md\:focus\:-translate-x-10:focus{--transform-translate-x:-2.5rem}.md\:focus\:-translate-x-12:focus{--transform-translate-x:-3rem}.md\:focus\:-translate-x-16:focus{--transform-translate-x:-4rem}.md\:focus\:-translate-x-20:focus{--transform-translate-x:-5rem}.md\:focus\:-translate-x-24:focus{--transform-translate-x:-6rem}.md\:focus\:-translate-x-32:focus{--transform-translate-x:-8rem}.md\:focus\:-translate-x-40:focus{--transform-translate-x:-10rem}.md\:focus\:-translate-x-48:focus{--transform-translate-x:-12rem}.md\:focus\:-translate-x-56:focus{--transform-translate-x:-14rem}.md\:focus\:-translate-x-64:focus{--transform-translate-x:-16rem}.md\:focus\:-translate-x-px:focus{--transform-translate-x:-1px}.md\:focus\:-translate-x-full:focus{--transform-translate-x:-100%}.md\:focus\:-translate-x-1\/2:focus{--transform-translate-x:-50%}.md\:focus\:translate-x-1\/2:focus{--transform-translate-x:50%}.md\:focus\:translate-x-full:focus{--transform-translate-x:100%}.md\:focus\:translate-y-0:focus{--transform-translate-y:0}.md\:focus\:translate-y-1:focus{--transform-translate-y:0.25rem}.md\:focus\:translate-y-2:focus{--transform-translate-y:0.5rem}.md\:focus\:translate-y-3:focus{--transform-translate-y:0.75rem}.md\:focus\:translate-y-4:focus{--transform-translate-y:1rem}.md\:focus\:translate-y-5:focus{--transform-translate-y:1.25rem}.md\:focus\:translate-y-6:focus{--transform-translate-y:1.5rem}.md\:focus\:translate-y-8:focus{--transform-translate-y:2rem}.md\:focus\:translate-y-10:focus{--transform-translate-y:2.5rem}.md\:focus\:translate-y-12:focus{--transform-translate-y:3rem}.md\:focus\:translate-y-16:focus{--transform-translate-y:4rem}.md\:focus\:translate-y-20:focus{--transform-translate-y:5rem}.md\:focus\:translate-y-24:focus{--transform-translate-y:6rem}.md\:focus\:translate-y-32:focus{--transform-translate-y:8rem}.md\:focus\:translate-y-40:focus{--transform-translate-y:10rem}.md\:focus\:translate-y-48:focus{--transform-translate-y:12rem}.md\:focus\:translate-y-56:focus{--transform-translate-y:14rem}.md\:focus\:translate-y-64:focus{--transform-translate-y:16rem}.md\:focus\:translate-y-px:focus{--transform-translate-y:1px}.md\:focus\:-translate-y-1:focus{--transform-translate-y:-0.25rem}.md\:focus\:-translate-y-2:focus{--transform-translate-y:-0.5rem}.md\:focus\:-translate-y-3:focus{--transform-translate-y:-0.75rem}.md\:focus\:-translate-y-4:focus{--transform-translate-y:-1rem}.md\:focus\:-translate-y-5:focus{--transform-translate-y:-1.25rem}.md\:focus\:-translate-y-6:focus{--transform-translate-y:-1.5rem}.md\:focus\:-translate-y-8:focus{--transform-translate-y:-2rem}.md\:focus\:-translate-y-10:focus{--transform-translate-y:-2.5rem}.md\:focus\:-translate-y-12:focus{--transform-translate-y:-3rem}.md\:focus\:-translate-y-16:focus{--transform-translate-y:-4rem}.md\:focus\:-translate-y-20:focus{--transform-translate-y:-5rem}.md\:focus\:-translate-y-24:focus{--transform-translate-y:-6rem}.md\:focus\:-translate-y-32:focus{--transform-translate-y:-8rem}.md\:focus\:-translate-y-40:focus{--transform-translate-y:-10rem}.md\:focus\:-translate-y-48:focus{--transform-translate-y:-12rem}.md\:focus\:-translate-y-56:focus{--transform-translate-y:-14rem}.md\:focus\:-translate-y-64:focus{--transform-translate-y:-16rem}.md\:focus\:-translate-y-px:focus{--transform-translate-y:-1px}.md\:focus\:-translate-y-full:focus{--transform-translate-y:-100%}.md\:focus\:-translate-y-1\/2:focus{--transform-translate-y:-50%}.md\:focus\:translate-y-1\/2:focus{--transform-translate-y:50%}.md\:focus\:translate-y-full:focus{--transform-translate-y:100%}.md\:skew-x-0{--transform-skew-x:0}.md\:skew-x-1{--transform-skew-x:1deg}.md\:skew-x-2{--transform-skew-x:2deg}.md\:skew-x-3{--transform-skew-x:3deg}.md\:skew-x-6{--transform-skew-x:6deg}.md\:skew-x-12{--transform-skew-x:12deg}.md\:-skew-x-12{--transform-skew-x:-12deg}.md\:-skew-x-6{--transform-skew-x:-6deg}.md\:-skew-x-3{--transform-skew-x:-3deg}.md\:-skew-x-2{--transform-skew-x:-2deg}.md\:-skew-x-1{--transform-skew-x:-1deg}.md\:skew-y-0{--transform-skew-y:0}.md\:skew-y-1{--transform-skew-y:1deg}.md\:skew-y-2{--transform-skew-y:2deg}.md\:skew-y-3{--transform-skew-y:3deg}.md\:skew-y-6{--transform-skew-y:6deg}.md\:skew-y-12{--transform-skew-y:12deg}.md\:-skew-y-12{--transform-skew-y:-12deg}.md\:-skew-y-6{--transform-skew-y:-6deg}.md\:-skew-y-3{--transform-skew-y:-3deg}.md\:-skew-y-2{--transform-skew-y:-2deg}.md\:-skew-y-1{--transform-skew-y:-1deg}.md\:hover\:skew-x-0:hover{--transform-skew-x:0}.md\:hover\:skew-x-1:hover{--transform-skew-x:1deg}.md\:hover\:skew-x-2:hover{--transform-skew-x:2deg}.md\:hover\:skew-x-3:hover{--transform-skew-x:3deg}.md\:hover\:skew-x-6:hover{--transform-skew-x:6deg}.md\:hover\:skew-x-12:hover{--transform-skew-x:12deg}.md\:hover\:-skew-x-12:hover{--transform-skew-x:-12deg}.md\:hover\:-skew-x-6:hover{--transform-skew-x:-6deg}.md\:hover\:-skew-x-3:hover{--transform-skew-x:-3deg}.md\:hover\:-skew-x-2:hover{--transform-skew-x:-2deg}.md\:hover\:-skew-x-1:hover{--transform-skew-x:-1deg}.md\:hover\:skew-y-0:hover{--transform-skew-y:0}.md\:hover\:skew-y-1:hover{--transform-skew-y:1deg}.md\:hover\:skew-y-2:hover{--transform-skew-y:2deg}.md\:hover\:skew-y-3:hover{--transform-skew-y:3deg}.md\:hover\:skew-y-6:hover{--transform-skew-y:6deg}.md\:hover\:skew-y-12:hover{--transform-skew-y:12deg}.md\:hover\:-skew-y-12:hover{--transform-skew-y:-12deg}.md\:hover\:-skew-y-6:hover{--transform-skew-y:-6deg}.md\:hover\:-skew-y-3:hover{--transform-skew-y:-3deg}.md\:hover\:-skew-y-2:hover{--transform-skew-y:-2deg}.md\:hover\:-skew-y-1:hover{--transform-skew-y:-1deg}.md\:focus\:skew-x-0:focus{--transform-skew-x:0}.md\:focus\:skew-x-1:focus{--transform-skew-x:1deg}.md\:focus\:skew-x-2:focus{--transform-skew-x:2deg}.md\:focus\:skew-x-3:focus{--transform-skew-x:3deg}.md\:focus\:skew-x-6:focus{--transform-skew-x:6deg}.md\:focus\:skew-x-12:focus{--transform-skew-x:12deg}.md\:focus\:-skew-x-12:focus{--transform-skew-x:-12deg}.md\:focus\:-skew-x-6:focus{--transform-skew-x:-6deg}.md\:focus\:-skew-x-3:focus{--transform-skew-x:-3deg}.md\:focus\:-skew-x-2:focus{--transform-skew-x:-2deg}.md\:focus\:-skew-x-1:focus{--transform-skew-x:-1deg}.md\:focus\:skew-y-0:focus{--transform-skew-y:0}.md\:focus\:skew-y-1:focus{--transform-skew-y:1deg}.md\:focus\:skew-y-2:focus{--transform-skew-y:2deg}.md\:focus\:skew-y-3:focus{--transform-skew-y:3deg}.md\:focus\:skew-y-6:focus{--transform-skew-y:6deg}.md\:focus\:skew-y-12:focus{--transform-skew-y:12deg}.md\:focus\:-skew-y-12:focus{--transform-skew-y:-12deg}.md\:focus\:-skew-y-6:focus{--transform-skew-y:-6deg}.md\:focus\:-skew-y-3:focus{--transform-skew-y:-3deg}.md\:focus\:-skew-y-2:focus{--transform-skew-y:-2deg}.md\:focus\:-skew-y-1:focus{--transform-skew-y:-1deg}.md\:transition-none{transition-property:none}.md\:transition-all{transition-property:all}.md\:transition{transition-property:background-color,border-color,color,fill,stroke,opacity,box-shadow,transform}.md\:transition-colors{transition-property:background-color,border-color,color,fill,stroke}.md\:transition-opacity{transition-property:opacity}.md\:transition-shadow{transition-property:box-shadow}.md\:transition-transform{transition-property:transform}.md\:ease-linear{transition-timing-function:linear}.md\:ease-in{transition-timing-function:cubic-bezier(.4,0,1,1)}.md\:ease-out{transition-timing-function:cubic-bezier(0,0,.2,1)}.md\:ease-in-out{transition-timing-function:cubic-bezier(.4,0,.2,1)}.md\:duration-75{transition-duration:75ms}.md\:duration-100{transition-duration:.1s}.md\:duration-150{transition-duration:150ms}.md\:duration-200{transition-duration:.2s}.md\:duration-300{transition-duration:.3s}.md\:duration-500{transition-duration:.5s}.md\:duration-700{transition-duration:.7s}.md\:duration-1000{transition-duration:1s}.md\:delay-75{transition-delay:75ms}.md\:delay-100{transition-delay:.1s}.md\:delay-150{transition-delay:150ms}.md\:delay-200{transition-delay:.2s}.md\:delay-300{transition-delay:.3s}.md\:delay-500{transition-delay:.5s}.md\:delay-700{transition-delay:.7s}.md\:delay-1000{transition-delay:1s}.md\:animate-none{animation:none}.md\:animate-spin{animation:spin 1s linear infinite}.md\:animate-ping{animation:ping 1s cubic-bezier(0,0,.2,1) infinite}.md\:animate-pulse{animation:pulse 2s cubic-bezier(.4,0,.6,1) infinite}.md\:animate-bounce{animation:bounce 1s infinite}}@media (min-width:1024px){.lg\:container{width:100%}@media (min-width:640px){.lg\:container{max-width:640px}}@media (min-width:768px){.lg\:container{max-width:768px}}@media (min-width:1024px){.lg\:container{max-width:1024px}}@media (min-width:1280px){.lg\:container{max-width:1280px}}.lg\:space-y-0>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(0px * calc(1 - var(--space-y-reverse)));margin-bottom:calc(0px * var(--space-y-reverse))}.lg\:space-x-0>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(0px * var(--space-x-reverse));margin-left:calc(0px * calc(1 - var(--space-x-reverse)))}.lg\:space-y-1>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(.25rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(.25rem * var(--space-y-reverse))}.lg\:space-x-1>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(.25rem * var(--space-x-reverse));margin-left:calc(.25rem * calc(1 - var(--space-x-reverse)))}.lg\:space-y-2>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(.5rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(.5rem * var(--space-y-reverse))}.lg\:space-x-2>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(.5rem * var(--space-x-reverse));margin-left:calc(.5rem * calc(1 - var(--space-x-reverse)))}.lg\:space-y-3>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(.75rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(.75rem * var(--space-y-reverse))}.lg\:space-x-3>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(.75rem * var(--space-x-reverse));margin-left:calc(.75rem * calc(1 - var(--space-x-reverse)))}.lg\:space-y-4>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(1rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(1rem * var(--space-y-reverse))}.lg\:space-x-4>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(1rem * var(--space-x-reverse));margin-left:calc(1rem * calc(1 - var(--space-x-reverse)))}.lg\:space-y-5>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(1.25rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(1.25rem * var(--space-y-reverse))}.lg\:space-x-5>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(1.25rem * var(--space-x-reverse));margin-left:calc(1.25rem * calc(1 - var(--space-x-reverse)))}.lg\:space-y-6>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(1.5rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(1.5rem * var(--space-y-reverse))}.lg\:space-x-6>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(1.5rem * var(--space-x-reverse));margin-left:calc(1.5rem * calc(1 - var(--space-x-reverse)))}.lg\:space-y-8>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(2rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(2rem * var(--space-y-reverse))}.lg\:space-x-8>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(2rem * var(--space-x-reverse));margin-left:calc(2rem * calc(1 - var(--space-x-reverse)))}.lg\:space-y-10>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(2.5rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(2.5rem * var(--space-y-reverse))}.lg\:space-x-10>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(2.5rem * var(--space-x-reverse));margin-left:calc(2.5rem * calc(1 - var(--space-x-reverse)))}.lg\:space-y-12>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(3rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(3rem * var(--space-y-reverse))}.lg\:space-x-12>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(3rem * var(--space-x-reverse));margin-left:calc(3rem * calc(1 - var(--space-x-reverse)))}.lg\:space-y-16>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(4rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(4rem * var(--space-y-reverse))}.lg\:space-x-16>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(4rem * var(--space-x-reverse));margin-left:calc(4rem * calc(1 - var(--space-x-reverse)))}.lg\:space-y-20>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(5rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(5rem * var(--space-y-reverse))}.lg\:space-x-20>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(5rem * var(--space-x-reverse));margin-left:calc(5rem * calc(1 - var(--space-x-reverse)))}.lg\:space-y-24>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(6rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(6rem * var(--space-y-reverse))}.lg\:space-x-24>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(6rem * var(--space-x-reverse));margin-left:calc(6rem * calc(1 - var(--space-x-reverse)))}.lg\:space-y-32>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(8rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(8rem * var(--space-y-reverse))}.lg\:space-x-32>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(8rem * var(--space-x-reverse));margin-left:calc(8rem * calc(1 - var(--space-x-reverse)))}.lg\:space-y-40>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(10rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(10rem * var(--space-y-reverse))}.lg\:space-x-40>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(10rem * var(--space-x-reverse));margin-left:calc(10rem * calc(1 - var(--space-x-reverse)))}.lg\:space-y-48>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(12rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(12rem * var(--space-y-reverse))}.lg\:space-x-48>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(12rem * var(--space-x-reverse));margin-left:calc(12rem * calc(1 - var(--space-x-reverse)))}.lg\:space-y-56>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(14rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(14rem * var(--space-y-reverse))}.lg\:space-x-56>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(14rem * var(--space-x-reverse));margin-left:calc(14rem * calc(1 - var(--space-x-reverse)))}.lg\:space-y-64>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(16rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(16rem * var(--space-y-reverse))}.lg\:space-x-64>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(16rem * var(--space-x-reverse));margin-left:calc(16rem * calc(1 - var(--space-x-reverse)))}.lg\:space-y-px>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(1px * calc(1 - var(--space-y-reverse)));margin-bottom:calc(1px * var(--space-y-reverse))}.lg\:space-x-px>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(1px * var(--space-x-reverse));margin-left:calc(1px * calc(1 - var(--space-x-reverse)))}.lg\:-space-y-1>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-.25rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-.25rem * var(--space-y-reverse))}.lg\:-space-x-1>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-.25rem * var(--space-x-reverse));margin-left:calc(-.25rem * calc(1 - var(--space-x-reverse)))}.lg\:-space-y-2>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-.5rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-.5rem * var(--space-y-reverse))}.lg\:-space-x-2>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-.5rem * var(--space-x-reverse));margin-left:calc(-.5rem * calc(1 - var(--space-x-reverse)))}.lg\:-space-y-3>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-.75rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-.75rem * var(--space-y-reverse))}.lg\:-space-x-3>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-.75rem * var(--space-x-reverse));margin-left:calc(-.75rem * calc(1 - var(--space-x-reverse)))}.lg\:-space-y-4>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-1rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-1rem * var(--space-y-reverse))}.lg\:-space-x-4>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-1rem * var(--space-x-reverse));margin-left:calc(-1rem * calc(1 - var(--space-x-reverse)))}.lg\:-space-y-5>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-1.25rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-1.25rem * var(--space-y-reverse))}.lg\:-space-x-5>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-1.25rem * var(--space-x-reverse));margin-left:calc(-1.25rem * calc(1 - var(--space-x-reverse)))}.lg\:-space-y-6>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-1.5rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-1.5rem * var(--space-y-reverse))}.lg\:-space-x-6>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-1.5rem * var(--space-x-reverse));margin-left:calc(-1.5rem * calc(1 - var(--space-x-reverse)))}.lg\:-space-y-8>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-2rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-2rem * var(--space-y-reverse))}.lg\:-space-x-8>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-2rem * var(--space-x-reverse));margin-left:calc(-2rem * calc(1 - var(--space-x-reverse)))}.lg\:-space-y-10>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-2.5rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-2.5rem * var(--space-y-reverse))}.lg\:-space-x-10>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-2.5rem * var(--space-x-reverse));margin-left:calc(-2.5rem * calc(1 - var(--space-x-reverse)))}.lg\:-space-y-12>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-3rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-3rem * var(--space-y-reverse))}.lg\:-space-x-12>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-3rem * var(--space-x-reverse));margin-left:calc(-3rem * calc(1 - var(--space-x-reverse)))}.lg\:-space-y-16>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-4rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-4rem * var(--space-y-reverse))}.lg\:-space-x-16>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-4rem * var(--space-x-reverse));margin-left:calc(-4rem * calc(1 - var(--space-x-reverse)))}.lg\:-space-y-20>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-5rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-5rem * var(--space-y-reverse))}.lg\:-space-x-20>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-5rem * var(--space-x-reverse));margin-left:calc(-5rem * calc(1 - var(--space-x-reverse)))}.lg\:-space-y-24>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-6rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-6rem * var(--space-y-reverse))}.lg\:-space-x-24>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-6rem * var(--space-x-reverse));margin-left:calc(-6rem * calc(1 - var(--space-x-reverse)))}.lg\:-space-y-32>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-8rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-8rem * var(--space-y-reverse))}.lg\:-space-x-32>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-8rem * var(--space-x-reverse));margin-left:calc(-8rem * calc(1 - var(--space-x-reverse)))}.lg\:-space-y-40>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-10rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-10rem * var(--space-y-reverse))}.lg\:-space-x-40>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-10rem * var(--space-x-reverse));margin-left:calc(-10rem * calc(1 - var(--space-x-reverse)))}.lg\:-space-y-48>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-12rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-12rem * var(--space-y-reverse))}.lg\:-space-x-48>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-12rem * var(--space-x-reverse));margin-left:calc(-12rem * calc(1 - var(--space-x-reverse)))}.lg\:-space-y-56>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-14rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-14rem * var(--space-y-reverse))}.lg\:-space-x-56>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-14rem * var(--space-x-reverse));margin-left:calc(-14rem * calc(1 - var(--space-x-reverse)))}.lg\:-space-y-64>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-16rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-16rem * var(--space-y-reverse))}.lg\:-space-x-64>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-16rem * var(--space-x-reverse));margin-left:calc(-16rem * calc(1 - var(--space-x-reverse)))}.lg\:-space-y-px>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-1px * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-1px * var(--space-y-reverse))}.lg\:-space-x-px>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-1px * var(--space-x-reverse));margin-left:calc(-1px * calc(1 - var(--space-x-reverse)))}.lg\:space-y-reverse>:not(template)~:not(template){--space-y-reverse:1}.lg\:space-x-reverse>:not(template)~:not(template){--space-x-reverse:1}.lg\:divide-y-0>:not(template)~:not(template){--divide-y-reverse:0;border-top-width:calc(0px * calc(1 - var(--divide-y-reverse)));border-bottom-width:calc(0px * var(--divide-y-reverse))}.lg\:divide-x-0>:not(template)~:not(template){--divide-x-reverse:0;border-right-width:calc(0px * var(--divide-x-reverse));border-left-width:calc(0px * calc(1 - var(--divide-x-reverse)))}.lg\:divide-y-2>:not(template)~:not(template){--divide-y-reverse:0;border-top-width:calc(2px * calc(1 - var(--divide-y-reverse)));border-bottom-width:calc(2px * var(--divide-y-reverse))}.lg\:divide-x-2>:not(template)~:not(template){--divide-x-reverse:0;border-right-width:calc(2px * var(--divide-x-reverse));border-left-width:calc(2px * calc(1 - var(--divide-x-reverse)))}.lg\:divide-y-4>:not(template)~:not(template){--divide-y-reverse:0;border-top-width:calc(4px * calc(1 - var(--divide-y-reverse)));border-bottom-width:calc(4px * var(--divide-y-reverse))}.lg\:divide-x-4>:not(template)~:not(template){--divide-x-reverse:0;border-right-width:calc(4px * var(--divide-x-reverse));border-left-width:calc(4px * calc(1 - var(--divide-x-reverse)))}.lg\:divide-y-8>:not(template)~:not(template){--divide-y-reverse:0;border-top-width:calc(8px * calc(1 - var(--divide-y-reverse)));border-bottom-width:calc(8px * var(--divide-y-reverse))}.lg\:divide-x-8>:not(template)~:not(template){--divide-x-reverse:0;border-right-width:calc(8px * var(--divide-x-reverse));border-left-width:calc(8px * calc(1 - var(--divide-x-reverse)))}.lg\:divide-y>:not(template)~:not(template){--divide-y-reverse:0;border-top-width:calc(1px * calc(1 - var(--divide-y-reverse)));border-bottom-width:calc(1px * var(--divide-y-reverse))}.lg\:divide-x>:not(template)~:not(template){--divide-x-reverse:0;border-right-width:calc(1px * var(--divide-x-reverse));border-left-width:calc(1px * calc(1 - var(--divide-x-reverse)))}.lg\:divide-y-reverse>:not(template)~:not(template){--divide-y-reverse:1}.lg\:divide-x-reverse>:not(template)~:not(template){--divide-x-reverse:1}.lg\:divide-transparent>:not(template)~:not(template){border-color:transparent}.lg\:divide-current>:not(template)~:not(template){border-color:currentColor}.lg\:divide-black>:not(template)~:not(template){--divide-opacity:1;border-color:#000;border-color:rgba(0,0,0,var(--divide-opacity))}.lg\:divide-white>:not(template)~:not(template){--divide-opacity:1;border-color:#fff;border-color:rgba(255,255,255,var(--divide-opacity))}.lg\:divide-gray-100>:not(template)~:not(template){--divide-opacity:1;border-color:#f7fafc;border-color:rgba(247,250,252,var(--divide-opacity))}.lg\:divide-gray-200>:not(template)~:not(template){--divide-opacity:1;border-color:#edf2f7;border-color:rgba(237,242,247,var(--divide-opacity))}.lg\:divide-gray-300>:not(template)~:not(template){--divide-opacity:1;border-color:#e2e8f0;border-color:rgba(226,232,240,var(--divide-opacity))}.lg\:divide-gray-400>:not(template)~:not(template){--divide-opacity:1;border-color:#cbd5e0;border-color:rgba(203,213,224,var(--divide-opacity))}.lg\:divide-gray-500>:not(template)~:not(template){--divide-opacity:1;border-color:#a0aec0;border-color:rgba(160,174,192,var(--divide-opacity))}.lg\:divide-gray-600>:not(template)~:not(template){--divide-opacity:1;border-color:#718096;border-color:rgba(113,128,150,var(--divide-opacity))}.lg\:divide-gray-700>:not(template)~:not(template){--divide-opacity:1;border-color:#4a5568;border-color:rgba(74,85,104,var(--divide-opacity))}.lg\:divide-gray-800>:not(template)~:not(template){--divide-opacity:1;border-color:#2d3748;border-color:rgba(45,55,72,var(--divide-opacity))}.lg\:divide-gray-900>:not(template)~:not(template){--divide-opacity:1;border-color:#1a202c;border-color:rgba(26,32,44,var(--divide-opacity))}.lg\:divide-red-100>:not(template)~:not(template){--divide-opacity:1;border-color:#fff5f5;border-color:rgba(255,245,245,var(--divide-opacity))}.lg\:divide-red-200>:not(template)~:not(template){--divide-opacity:1;border-color:#fed7d7;border-color:rgba(254,215,215,var(--divide-opacity))}.lg\:divide-red-300>:not(template)~:not(template){--divide-opacity:1;border-color:#feb2b2;border-color:rgba(254,178,178,var(--divide-opacity))}.lg\:divide-red-400>:not(template)~:not(template){--divide-opacity:1;border-color:#fc8181;border-color:rgba(252,129,129,var(--divide-opacity))}.lg\:divide-red-500>:not(template)~:not(template){--divide-opacity:1;border-color:#f56565;border-color:rgba(245,101,101,var(--divide-opacity))}.lg\:divide-red-600>:not(template)~:not(template){--divide-opacity:1;border-color:#e53e3e;border-color:rgba(229,62,62,var(--divide-opacity))}.lg\:divide-red-700>:not(template)~:not(template){--divide-opacity:1;border-color:#c53030;border-color:rgba(197,48,48,var(--divide-opacity))}.lg\:divide-red-800>:not(template)~:not(template){--divide-opacity:1;border-color:#9b2c2c;border-color:rgba(155,44,44,var(--divide-opacity))}.lg\:divide-red-900>:not(template)~:not(template){--divide-opacity:1;border-color:#742a2a;border-color:rgba(116,42,42,var(--divide-opacity))}.lg\:divide-orange-100>:not(template)~:not(template){--divide-opacity:1;border-color:#fffaf0;border-color:rgba(255,250,240,var(--divide-opacity))}.lg\:divide-orange-200>:not(template)~:not(template){--divide-opacity:1;border-color:#feebc8;border-color:rgba(254,235,200,var(--divide-opacity))}.lg\:divide-orange-300>:not(template)~:not(template){--divide-opacity:1;border-color:#fbd38d;border-color:rgba(251,211,141,var(--divide-opacity))}.lg\:divide-orange-400>:not(template)~:not(template){--divide-opacity:1;border-color:#f6ad55;border-color:rgba(246,173,85,var(--divide-opacity))}.lg\:divide-orange-500>:not(template)~:not(template){--divide-opacity:1;border-color:#ed8936;border-color:rgba(237,137,54,var(--divide-opacity))}.lg\:divide-orange-600>:not(template)~:not(template){--divide-opacity:1;border-color:#dd6b20;border-color:rgba(221,107,32,var(--divide-opacity))}.lg\:divide-orange-700>:not(template)~:not(template){--divide-opacity:1;border-color:#c05621;border-color:rgba(192,86,33,var(--divide-opacity))}.lg\:divide-orange-800>:not(template)~:not(template){--divide-opacity:1;border-color:#9c4221;border-color:rgba(156,66,33,var(--divide-opacity))}.lg\:divide-orange-900>:not(template)~:not(template){--divide-opacity:1;border-color:#7b341e;border-color:rgba(123,52,30,var(--divide-opacity))}.lg\:divide-yellow-100>:not(template)~:not(template){--divide-opacity:1;border-color:ivory;border-color:rgba(255,255,240,var(--divide-opacity))}.lg\:divide-yellow-200>:not(template)~:not(template){--divide-opacity:1;border-color:#fefcbf;border-color:rgba(254,252,191,var(--divide-opacity))}.lg\:divide-yellow-300>:not(template)~:not(template){--divide-opacity:1;border-color:#faf089;border-color:rgba(250,240,137,var(--divide-opacity))}.lg\:divide-yellow-400>:not(template)~:not(template){--divide-opacity:1;border-color:#f6e05e;border-color:rgba(246,224,94,var(--divide-opacity))}.lg\:divide-yellow-500>:not(template)~:not(template){--divide-opacity:1;border-color:#ecc94b;border-color:rgba(236,201,75,var(--divide-opacity))}.lg\:divide-yellow-600>:not(template)~:not(template){--divide-opacity:1;border-color:#d69e2e;border-color:rgba(214,158,46,var(--divide-opacity))}.lg\:divide-yellow-700>:not(template)~:not(template){--divide-opacity:1;border-color:#b7791f;border-color:rgba(183,121,31,var(--divide-opacity))}.lg\:divide-yellow-800>:not(template)~:not(template){--divide-opacity:1;border-color:#975a16;border-color:rgba(151,90,22,var(--divide-opacity))}.lg\:divide-yellow-900>:not(template)~:not(template){--divide-opacity:1;border-color:#744210;border-color:rgba(116,66,16,var(--divide-opacity))}.lg\:divide-green-100>:not(template)~:not(template){--divide-opacity:1;border-color:#f0fff4;border-color:rgba(240,255,244,var(--divide-opacity))}.lg\:divide-green-200>:not(template)~:not(template){--divide-opacity:1;border-color:#c6f6d5;border-color:rgba(198,246,213,var(--divide-opacity))}.lg\:divide-green-300>:not(template)~:not(template){--divide-opacity:1;border-color:#9ae6b4;border-color:rgba(154,230,180,var(--divide-opacity))}.lg\:divide-green-400>:not(template)~:not(template){--divide-opacity:1;border-color:#68d391;border-color:rgba(104,211,145,var(--divide-opacity))}.lg\:divide-green-500>:not(template)~:not(template){--divide-opacity:1;border-color:#48bb78;border-color:rgba(72,187,120,var(--divide-opacity))}.lg\:divide-green-600>:not(template)~:not(template){--divide-opacity:1;border-color:#38a169;border-color:rgba(56,161,105,var(--divide-opacity))}.lg\:divide-green-700>:not(template)~:not(template){--divide-opacity:1;border-color:#2f855a;border-color:rgba(47,133,90,var(--divide-opacity))}.lg\:divide-green-800>:not(template)~:not(template){--divide-opacity:1;border-color:#276749;border-color:rgba(39,103,73,var(--divide-opacity))}.lg\:divide-green-900>:not(template)~:not(template){--divide-opacity:1;border-color:#22543d;border-color:rgba(34,84,61,var(--divide-opacity))}.lg\:divide-teal-100>:not(template)~:not(template){--divide-opacity:1;border-color:#e6fffa;border-color:rgba(230,255,250,var(--divide-opacity))}.lg\:divide-teal-200>:not(template)~:not(template){--divide-opacity:1;border-color:#b2f5ea;border-color:rgba(178,245,234,var(--divide-opacity))}.lg\:divide-teal-300>:not(template)~:not(template){--divide-opacity:1;border-color:#81e6d9;border-color:rgba(129,230,217,var(--divide-opacity))}.lg\:divide-teal-400>:not(template)~:not(template){--divide-opacity:1;border-color:#4fd1c5;border-color:rgba(79,209,197,var(--divide-opacity))}.lg\:divide-teal-500>:not(template)~:not(template){--divide-opacity:1;border-color:#38b2ac;border-color:rgba(56,178,172,var(--divide-opacity))}.lg\:divide-teal-600>:not(template)~:not(template){--divide-opacity:1;border-color:#319795;border-color:rgba(49,151,149,var(--divide-opacity))}.lg\:divide-teal-700>:not(template)~:not(template){--divide-opacity:1;border-color:#2c7a7b;border-color:rgba(44,122,123,var(--divide-opacity))}.lg\:divide-teal-800>:not(template)~:not(template){--divide-opacity:1;border-color:#285e61;border-color:rgba(40,94,97,var(--divide-opacity))}.lg\:divide-teal-900>:not(template)~:not(template){--divide-opacity:1;border-color:#234e52;border-color:rgba(35,78,82,var(--divide-opacity))}.lg\:divide-blue-100>:not(template)~:not(template){--divide-opacity:1;border-color:#ebf8ff;border-color:rgba(235,248,255,var(--divide-opacity))}.lg\:divide-blue-200>:not(template)~:not(template){--divide-opacity:1;border-color:#bee3f8;border-color:rgba(190,227,248,var(--divide-opacity))}.lg\:divide-blue-300>:not(template)~:not(template){--divide-opacity:1;border-color:#90cdf4;border-color:rgba(144,205,244,var(--divide-opacity))}.lg\:divide-blue-400>:not(template)~:not(template){--divide-opacity:1;border-color:#63b3ed;border-color:rgba(99,179,237,var(--divide-opacity))}.lg\:divide-blue-500>:not(template)~:not(template){--divide-opacity:1;border-color:#4299e1;border-color:rgba(66,153,225,var(--divide-opacity))}.lg\:divide-blue-600>:not(template)~:not(template){--divide-opacity:1;border-color:#3182ce;border-color:rgba(49,130,206,var(--divide-opacity))}.lg\:divide-blue-700>:not(template)~:not(template){--divide-opacity:1;border-color:#2b6cb0;border-color:rgba(43,108,176,var(--divide-opacity))}.lg\:divide-blue-800>:not(template)~:not(template){--divide-opacity:1;border-color:#2c5282;border-color:rgba(44,82,130,var(--divide-opacity))}.lg\:divide-blue-900>:not(template)~:not(template){--divide-opacity:1;border-color:#2a4365;border-color:rgba(42,67,101,var(--divide-opacity))}.lg\:divide-indigo-100>:not(template)~:not(template){--divide-opacity:1;border-color:#ebf4ff;border-color:rgba(235,244,255,var(--divide-opacity))}.lg\:divide-indigo-200>:not(template)~:not(template){--divide-opacity:1;border-color:#c3dafe;border-color:rgba(195,218,254,var(--divide-opacity))}.lg\:divide-indigo-300>:not(template)~:not(template){--divide-opacity:1;border-color:#a3bffa;border-color:rgba(163,191,250,var(--divide-opacity))}.lg\:divide-indigo-400>:not(template)~:not(template){--divide-opacity:1;border-color:#7f9cf5;border-color:rgba(127,156,245,var(--divide-opacity))}.lg\:divide-indigo-500>:not(template)~:not(template){--divide-opacity:1;border-color:#667eea;border-color:rgba(102,126,234,var(--divide-opacity))}.lg\:divide-indigo-600>:not(template)~:not(template){--divide-opacity:1;border-color:#5a67d8;border-color:rgba(90,103,216,var(--divide-opacity))}.lg\:divide-indigo-700>:not(template)~:not(template){--divide-opacity:1;border-color:#4c51bf;border-color:rgba(76,81,191,var(--divide-opacity))}.lg\:divide-indigo-800>:not(template)~:not(template){--divide-opacity:1;border-color:#434190;border-color:rgba(67,65,144,var(--divide-opacity))}.lg\:divide-indigo-900>:not(template)~:not(template){--divide-opacity:1;border-color:#3c366b;border-color:rgba(60,54,107,var(--divide-opacity))}.lg\:divide-purple-100>:not(template)~:not(template){--divide-opacity:1;border-color:#faf5ff;border-color:rgba(250,245,255,var(--divide-opacity))}.lg\:divide-purple-200>:not(template)~:not(template){--divide-opacity:1;border-color:#e9d8fd;border-color:rgba(233,216,253,var(--divide-opacity))}.lg\:divide-purple-300>:not(template)~:not(template){--divide-opacity:1;border-color:#d6bcfa;border-color:rgba(214,188,250,var(--divide-opacity))}.lg\:divide-purple-400>:not(template)~:not(template){--divide-opacity:1;border-color:#b794f4;border-color:rgba(183,148,244,var(--divide-opacity))}.lg\:divide-purple-500>:not(template)~:not(template){--divide-opacity:1;border-color:#9f7aea;border-color:rgba(159,122,234,var(--divide-opacity))}.lg\:divide-purple-600>:not(template)~:not(template){--divide-opacity:1;border-color:#805ad5;border-color:rgba(128,90,213,var(--divide-opacity))}.lg\:divide-purple-700>:not(template)~:not(template){--divide-opacity:1;border-color:#6b46c1;border-color:rgba(107,70,193,var(--divide-opacity))}.lg\:divide-purple-800>:not(template)~:not(template){--divide-opacity:1;border-color:#553c9a;border-color:rgba(85,60,154,var(--divide-opacity))}.lg\:divide-purple-900>:not(template)~:not(template){--divide-opacity:1;border-color:#44337a;border-color:rgba(68,51,122,var(--divide-opacity))}.lg\:divide-pink-100>:not(template)~:not(template){--divide-opacity:1;border-color:#fff5f7;border-color:rgba(255,245,247,var(--divide-opacity))}.lg\:divide-pink-200>:not(template)~:not(template){--divide-opacity:1;border-color:#fed7e2;border-color:rgba(254,215,226,var(--divide-opacity))}.lg\:divide-pink-300>:not(template)~:not(template){--divide-opacity:1;border-color:#fbb6ce;border-color:rgba(251,182,206,var(--divide-opacity))}.lg\:divide-pink-400>:not(template)~:not(template){--divide-opacity:1;border-color:#f687b3;border-color:rgba(246,135,179,var(--divide-opacity))}.lg\:divide-pink-500>:not(template)~:not(template){--divide-opacity:1;border-color:#ed64a6;border-color:rgba(237,100,166,var(--divide-opacity))}.lg\:divide-pink-600>:not(template)~:not(template){--divide-opacity:1;border-color:#d53f8c;border-color:rgba(213,63,140,var(--divide-opacity))}.lg\:divide-pink-700>:not(template)~:not(template){--divide-opacity:1;border-color:#b83280;border-color:rgba(184,50,128,var(--divide-opacity))}.lg\:divide-pink-800>:not(template)~:not(template){--divide-opacity:1;border-color:#97266d;border-color:rgba(151,38,109,var(--divide-opacity))}.lg\:divide-pink-900>:not(template)~:not(template){--divide-opacity:1;border-color:#702459;border-color:rgba(112,36,89,var(--divide-opacity))}.lg\:divide-solid>:not(template)~:not(template){border-style:solid}.lg\:divide-dashed>:not(template)~:not(template){border-style:dashed}.lg\:divide-dotted>:not(template)~:not(template){border-style:dotted}.lg\:divide-double>:not(template)~:not(template){border-style:double}.lg\:divide-none>:not(template)~:not(template){border-style:none}.lg\:divide-opacity-0>:not(template)~:not(template){--divide-opacity:0}.lg\:divide-opacity-25>:not(template)~:not(template){--divide-opacity:0.25}.lg\:divide-opacity-50>:not(template)~:not(template){--divide-opacity:0.5}.lg\:divide-opacity-75>:not(template)~:not(template){--divide-opacity:0.75}.lg\:divide-opacity-100>:not(template)~:not(template){--divide-opacity:1}.lg\:sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border-width:0}.lg\:not-sr-only{position:static;width:auto;height:auto;padding:0;margin:0;overflow:visible;clip:auto;white-space:normal}.lg\:focus\:sr-only:focus{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border-width:0}.lg\:focus\:not-sr-only:focus{position:static;width:auto;height:auto;padding:0;margin:0;overflow:visible;clip:auto;white-space:normal}.lg\:appearance-none{-webkit-appearance:none;-moz-appearance:none;appearance:none}.lg\:bg-fixed{background-attachment:fixed}.lg\:bg-local{background-attachment:local}.lg\:bg-scroll{background-attachment:scroll}.lg\:bg-clip-border{background-clip:border-box}.lg\:bg-clip-padding{background-clip:padding-box}.lg\:bg-clip-content{background-clip:content-box}.lg\:bg-clip-text{-webkit-background-clip:text;background-clip:text}.lg\:bg-transparent{background-color:transparent}.lg\:bg-current{background-color:currentColor}.lg\:bg-black{--bg-opacity:1;background-color:#000;background-color:rgba(0,0,0,var(--bg-opacity))}.lg\:bg-white{--bg-opacity:1;background-color:#fff;background-color:rgba(255,255,255,var(--bg-opacity))}.lg\:bg-gray-100{--bg-opacity:1;background-color:#f7fafc;background-color:rgba(247,250,252,var(--bg-opacity))}.lg\:bg-gray-200{--bg-opacity:1;background-color:#edf2f7;background-color:rgba(237,242,247,var(--bg-opacity))}.lg\:bg-gray-300{--bg-opacity:1;background-color:#e2e8f0;background-color:rgba(226,232,240,var(--bg-opacity))}.lg\:bg-gray-400{--bg-opacity:1;background-color:#cbd5e0;background-color:rgba(203,213,224,var(--bg-opacity))}.lg\:bg-gray-500{--bg-opacity:1;background-color:#a0aec0;background-color:rgba(160,174,192,var(--bg-opacity))}.lg\:bg-gray-600{--bg-opacity:1;background-color:#718096;background-color:rgba(113,128,150,var(--bg-opacity))}.lg\:bg-gray-700{--bg-opacity:1;background-color:#4a5568;background-color:rgba(74,85,104,var(--bg-opacity))}.lg\:bg-gray-800{--bg-opacity:1;background-color:#2d3748;background-color:rgba(45,55,72,var(--bg-opacity))}.lg\:bg-gray-900{--bg-opacity:1;background-color:#1a202c;background-color:rgba(26,32,44,var(--bg-opacity))}.lg\:bg-red-100{--bg-opacity:1;background-color:#fff5f5;background-color:rgba(255,245,245,var(--bg-opacity))}.lg\:bg-red-200{--bg-opacity:1;background-color:#fed7d7;background-color:rgba(254,215,215,var(--bg-opacity))}.lg\:bg-red-300{--bg-opacity:1;background-color:#feb2b2;background-color:rgba(254,178,178,var(--bg-opacity))}.lg\:bg-red-400{--bg-opacity:1;background-color:#fc8181;background-color:rgba(252,129,129,var(--bg-opacity))}.lg\:bg-red-500{--bg-opacity:1;background-color:#f56565;background-color:rgba(245,101,101,var(--bg-opacity))}.lg\:bg-red-600{--bg-opacity:1;background-color:#e53e3e;background-color:rgba(229,62,62,var(--bg-opacity))}.lg\:bg-red-700{--bg-opacity:1;background-color:#c53030;background-color:rgba(197,48,48,var(--bg-opacity))}.lg\:bg-red-800{--bg-opacity:1;background-color:#9b2c2c;background-color:rgba(155,44,44,var(--bg-opacity))}.lg\:bg-red-900{--bg-opacity:1;background-color:#742a2a;background-color:rgba(116,42,42,var(--bg-opacity))}.lg\:bg-orange-100{--bg-opacity:1;background-color:#fffaf0;background-color:rgba(255,250,240,var(--bg-opacity))}.lg\:bg-orange-200{--bg-opacity:1;background-color:#feebc8;background-color:rgba(254,235,200,var(--bg-opacity))}.lg\:bg-orange-300{--bg-opacity:1;background-color:#fbd38d;background-color:rgba(251,211,141,var(--bg-opacity))}.lg\:bg-orange-400{--bg-opacity:1;background-color:#f6ad55;background-color:rgba(246,173,85,var(--bg-opacity))}.lg\:bg-orange-500{--bg-opacity:1;background-color:#ed8936;background-color:rgba(237,137,54,var(--bg-opacity))}.lg\:bg-orange-600{--bg-opacity:1;background-color:#dd6b20;background-color:rgba(221,107,32,var(--bg-opacity))}.lg\:bg-orange-700{--bg-opacity:1;background-color:#c05621;background-color:rgba(192,86,33,var(--bg-opacity))}.lg\:bg-orange-800{--bg-opacity:1;background-color:#9c4221;background-color:rgba(156,66,33,var(--bg-opacity))}.lg\:bg-orange-900{--bg-opacity:1;background-color:#7b341e;background-color:rgba(123,52,30,var(--bg-opacity))}.lg\:bg-yellow-100{--bg-opacity:1;background-color:ivory;background-color:rgba(255,255,240,var(--bg-opacity))}.lg\:bg-yellow-200{--bg-opacity:1;background-color:#fefcbf;background-color:rgba(254,252,191,var(--bg-opacity))}.lg\:bg-yellow-300{--bg-opacity:1;background-color:#faf089;background-color:rgba(250,240,137,var(--bg-opacity))}.lg\:bg-yellow-400{--bg-opacity:1;background-color:#f6e05e;background-color:rgba(246,224,94,var(--bg-opacity))}.lg\:bg-yellow-500{--bg-opacity:1;background-color:#ecc94b;background-color:rgba(236,201,75,var(--bg-opacity))}.lg\:bg-yellow-600{--bg-opacity:1;background-color:#d69e2e;background-color:rgba(214,158,46,var(--bg-opacity))}.lg\:bg-yellow-700{--bg-opacity:1;background-color:#b7791f;background-color:rgba(183,121,31,var(--bg-opacity))}.lg\:bg-yellow-800{--bg-opacity:1;background-color:#975a16;background-color:rgba(151,90,22,var(--bg-opacity))}.lg\:bg-yellow-900{--bg-opacity:1;background-color:#744210;background-color:rgba(116,66,16,var(--bg-opacity))}.lg\:bg-green-100{--bg-opacity:1;background-color:#f0fff4;background-color:rgba(240,255,244,var(--bg-opacity))}.lg\:bg-green-200{--bg-opacity:1;background-color:#c6f6d5;background-color:rgba(198,246,213,var(--bg-opacity))}.lg\:bg-green-300{--bg-opacity:1;background-color:#9ae6b4;background-color:rgba(154,230,180,var(--bg-opacity))}.lg\:bg-green-400{--bg-opacity:1;background-color:#68d391;background-color:rgba(104,211,145,var(--bg-opacity))}.lg\:bg-green-500{--bg-opacity:1;background-color:#48bb78;background-color:rgba(72,187,120,var(--bg-opacity))}.lg\:bg-green-600{--bg-opacity:1;background-color:#38a169;background-color:rgba(56,161,105,var(--bg-opacity))}.lg\:bg-green-700{--bg-opacity:1;background-color:#2f855a;background-color:rgba(47,133,90,var(--bg-opacity))}.lg\:bg-green-800{--bg-opacity:1;background-color:#276749;background-color:rgba(39,103,73,var(--bg-opacity))}.lg\:bg-green-900{--bg-opacity:1;background-color:#22543d;background-color:rgba(34,84,61,var(--bg-opacity))}.lg\:bg-teal-100{--bg-opacity:1;background-color:#e6fffa;background-color:rgba(230,255,250,var(--bg-opacity))}.lg\:bg-teal-200{--bg-opacity:1;background-color:#b2f5ea;background-color:rgba(178,245,234,var(--bg-opacity))}.lg\:bg-teal-300{--bg-opacity:1;background-color:#81e6d9;background-color:rgba(129,230,217,var(--bg-opacity))}.lg\:bg-teal-400{--bg-opacity:1;background-color:#4fd1c5;background-color:rgba(79,209,197,var(--bg-opacity))}.lg\:bg-teal-500{--bg-opacity:1;background-color:#38b2ac;background-color:rgba(56,178,172,var(--bg-opacity))}.lg\:bg-teal-600{--bg-opacity:1;background-color:#319795;background-color:rgba(49,151,149,var(--bg-opacity))}.lg\:bg-teal-700{--bg-opacity:1;background-color:#2c7a7b;background-color:rgba(44,122,123,var(--bg-opacity))}.lg\:bg-teal-800{--bg-opacity:1;background-color:#285e61;background-color:rgba(40,94,97,var(--bg-opacity))}.lg\:bg-teal-900{--bg-opacity:1;background-color:#234e52;background-color:rgba(35,78,82,var(--bg-opacity))}.lg\:bg-blue-100{--bg-opacity:1;background-color:#ebf8ff;background-color:rgba(235,248,255,var(--bg-opacity))}.lg\:bg-blue-200{--bg-opacity:1;background-color:#bee3f8;background-color:rgba(190,227,248,var(--bg-opacity))}.lg\:bg-blue-300{--bg-opacity:1;background-color:#90cdf4;background-color:rgba(144,205,244,var(--bg-opacity))}.lg\:bg-blue-400{--bg-opacity:1;background-color:#63b3ed;background-color:rgba(99,179,237,var(--bg-opacity))}.lg\:bg-blue-500{--bg-opacity:1;background-color:#4299e1;background-color:rgba(66,153,225,var(--bg-opacity))}.lg\:bg-blue-600{--bg-opacity:1;background-color:#3182ce;background-color:rgba(49,130,206,var(--bg-opacity))}.lg\:bg-blue-700{--bg-opacity:1;background-color:#2b6cb0;background-color:rgba(43,108,176,var(--bg-opacity))}.lg\:bg-blue-800{--bg-opacity:1;background-color:#2c5282;background-color:rgba(44,82,130,var(--bg-opacity))}.lg\:bg-blue-900{--bg-opacity:1;background-color:#2a4365;background-color:rgba(42,67,101,var(--bg-opacity))}.lg\:bg-indigo-100{--bg-opacity:1;background-color:#ebf4ff;background-color:rgba(235,244,255,var(--bg-opacity))}.lg\:bg-indigo-200{--bg-opacity:1;background-color:#c3dafe;background-color:rgba(195,218,254,var(--bg-opacity))}.lg\:bg-indigo-300{--bg-opacity:1;background-color:#a3bffa;background-color:rgba(163,191,250,var(--bg-opacity))}.lg\:bg-indigo-400{--bg-opacity:1;background-color:#7f9cf5;background-color:rgba(127,156,245,var(--bg-opacity))}.lg\:bg-indigo-500{--bg-opacity:1;background-color:#667eea;background-color:rgba(102,126,234,var(--bg-opacity))}.lg\:bg-indigo-600{--bg-opacity:1;background-color:#5a67d8;background-color:rgba(90,103,216,var(--bg-opacity))}.lg\:bg-indigo-700{--bg-opacity:1;background-color:#4c51bf;background-color:rgba(76,81,191,var(--bg-opacity))}.lg\:bg-indigo-800{--bg-opacity:1;background-color:#434190;background-color:rgba(67,65,144,var(--bg-opacity))}.lg\:bg-indigo-900{--bg-opacity:1;background-color:#3c366b;background-color:rgba(60,54,107,var(--bg-opacity))}.lg\:bg-purple-100{--bg-opacity:1;background-color:#faf5ff;background-color:rgba(250,245,255,var(--bg-opacity))}.lg\:bg-purple-200{--bg-opacity:1;background-color:#e9d8fd;background-color:rgba(233,216,253,var(--bg-opacity))}.lg\:bg-purple-300{--bg-opacity:1;background-color:#d6bcfa;background-color:rgba(214,188,250,var(--bg-opacity))}.lg\:bg-purple-400{--bg-opacity:1;background-color:#b794f4;background-color:rgba(183,148,244,var(--bg-opacity))}.lg\:bg-purple-500{--bg-opacity:1;background-color:#9f7aea;background-color:rgba(159,122,234,var(--bg-opacity))}.lg\:bg-purple-600{--bg-opacity:1;background-color:#805ad5;background-color:rgba(128,90,213,var(--bg-opacity))}.lg\:bg-purple-700{--bg-opacity:1;background-color:#6b46c1;background-color:rgba(107,70,193,var(--bg-opacity))}.lg\:bg-purple-800{--bg-opacity:1;background-color:#553c9a;background-color:rgba(85,60,154,var(--bg-opacity))}.lg\:bg-purple-900{--bg-opacity:1;background-color:#44337a;background-color:rgba(68,51,122,var(--bg-opacity))}.lg\:bg-pink-100{--bg-opacity:1;background-color:#fff5f7;background-color:rgba(255,245,247,var(--bg-opacity))}.lg\:bg-pink-200{--bg-opacity:1;background-color:#fed7e2;background-color:rgba(254,215,226,var(--bg-opacity))}.lg\:bg-pink-300{--bg-opacity:1;background-color:#fbb6ce;background-color:rgba(251,182,206,var(--bg-opacity))}.lg\:bg-pink-400{--bg-opacity:1;background-color:#f687b3;background-color:rgba(246,135,179,var(--bg-opacity))}.lg\:bg-pink-500{--bg-opacity:1;background-color:#ed64a6;background-color:rgba(237,100,166,var(--bg-opacity))}.lg\:bg-pink-600{--bg-opacity:1;background-color:#d53f8c;background-color:rgba(213,63,140,var(--bg-opacity))}.lg\:bg-pink-700{--bg-opacity:1;background-color:#b83280;background-color:rgba(184,50,128,var(--bg-opacity))}.lg\:bg-pink-800{--bg-opacity:1;background-color:#97266d;background-color:rgba(151,38,109,var(--bg-opacity))}.lg\:bg-pink-900{--bg-opacity:1;background-color:#702459;background-color:rgba(112,36,89,var(--bg-opacity))}.lg\:hover\:bg-transparent:hover{background-color:transparent}.lg\:hover\:bg-current:hover{background-color:currentColor}.lg\:hover\:bg-black:hover{--bg-opacity:1;background-color:#000;background-color:rgba(0,0,0,var(--bg-opacity))}.lg\:hover\:bg-white:hover{--bg-opacity:1;background-color:#fff;background-color:rgba(255,255,255,var(--bg-opacity))}.lg\:hover\:bg-gray-100:hover{--bg-opacity:1;background-color:#f7fafc;background-color:rgba(247,250,252,var(--bg-opacity))}.lg\:hover\:bg-gray-200:hover{--bg-opacity:1;background-color:#edf2f7;background-color:rgba(237,242,247,var(--bg-opacity))}.lg\:hover\:bg-gray-300:hover{--bg-opacity:1;background-color:#e2e8f0;background-color:rgba(226,232,240,var(--bg-opacity))}.lg\:hover\:bg-gray-400:hover{--bg-opacity:1;background-color:#cbd5e0;background-color:rgba(203,213,224,var(--bg-opacity))}.lg\:hover\:bg-gray-500:hover{--bg-opacity:1;background-color:#a0aec0;background-color:rgba(160,174,192,var(--bg-opacity))}.lg\:hover\:bg-gray-600:hover{--bg-opacity:1;background-color:#718096;background-color:rgba(113,128,150,var(--bg-opacity))}.lg\:hover\:bg-gray-700:hover{--bg-opacity:1;background-color:#4a5568;background-color:rgba(74,85,104,var(--bg-opacity))}.lg\:hover\:bg-gray-800:hover{--bg-opacity:1;background-color:#2d3748;background-color:rgba(45,55,72,var(--bg-opacity))}.lg\:hover\:bg-gray-900:hover{--bg-opacity:1;background-color:#1a202c;background-color:rgba(26,32,44,var(--bg-opacity))}.lg\:hover\:bg-red-100:hover{--bg-opacity:1;background-color:#fff5f5;background-color:rgba(255,245,245,var(--bg-opacity))}.lg\:hover\:bg-red-200:hover{--bg-opacity:1;background-color:#fed7d7;background-color:rgba(254,215,215,var(--bg-opacity))}.lg\:hover\:bg-red-300:hover{--bg-opacity:1;background-color:#feb2b2;background-color:rgba(254,178,178,var(--bg-opacity))}.lg\:hover\:bg-red-400:hover{--bg-opacity:1;background-color:#fc8181;background-color:rgba(252,129,129,var(--bg-opacity))}.lg\:hover\:bg-red-500:hover{--bg-opacity:1;background-color:#f56565;background-color:rgba(245,101,101,var(--bg-opacity))}.lg\:hover\:bg-red-600:hover{--bg-opacity:1;background-color:#e53e3e;background-color:rgba(229,62,62,var(--bg-opacity))}.lg\:hover\:bg-red-700:hover{--bg-opacity:1;background-color:#c53030;background-color:rgba(197,48,48,var(--bg-opacity))}.lg\:hover\:bg-red-800:hover{--bg-opacity:1;background-color:#9b2c2c;background-color:rgba(155,44,44,var(--bg-opacity))}.lg\:hover\:bg-red-900:hover{--bg-opacity:1;background-color:#742a2a;background-color:rgba(116,42,42,var(--bg-opacity))}.lg\:hover\:bg-orange-100:hover{--bg-opacity:1;background-color:#fffaf0;background-color:rgba(255,250,240,var(--bg-opacity))}.lg\:hover\:bg-orange-200:hover{--bg-opacity:1;background-color:#feebc8;background-color:rgba(254,235,200,var(--bg-opacity))}.lg\:hover\:bg-orange-300:hover{--bg-opacity:1;background-color:#fbd38d;background-color:rgba(251,211,141,var(--bg-opacity))}.lg\:hover\:bg-orange-400:hover{--bg-opacity:1;background-color:#f6ad55;background-color:rgba(246,173,85,var(--bg-opacity))}.lg\:hover\:bg-orange-500:hover{--bg-opacity:1;background-color:#ed8936;background-color:rgba(237,137,54,var(--bg-opacity))}.lg\:hover\:bg-orange-600:hover{--bg-opacity:1;background-color:#dd6b20;background-color:rgba(221,107,32,var(--bg-opacity))}.lg\:hover\:bg-orange-700:hover{--bg-opacity:1;background-color:#c05621;background-color:rgba(192,86,33,var(--bg-opacity))}.lg\:hover\:bg-orange-800:hover{--bg-opacity:1;background-color:#9c4221;background-color:rgba(156,66,33,var(--bg-opacity))}.lg\:hover\:bg-orange-900:hover{--bg-opacity:1;background-color:#7b341e;background-color:rgba(123,52,30,var(--bg-opacity))}.lg\:hover\:bg-yellow-100:hover{--bg-opacity:1;background-color:ivory;background-color:rgba(255,255,240,var(--bg-opacity))}.lg\:hover\:bg-yellow-200:hover{--bg-opacity:1;background-color:#fefcbf;background-color:rgba(254,252,191,var(--bg-opacity))}.lg\:hover\:bg-yellow-300:hover{--bg-opacity:1;background-color:#faf089;background-color:rgba(250,240,137,var(--bg-opacity))}.lg\:hover\:bg-yellow-400:hover{--bg-opacity:1;background-color:#f6e05e;background-color:rgba(246,224,94,var(--bg-opacity))}.lg\:hover\:bg-yellow-500:hover{--bg-opacity:1;background-color:#ecc94b;background-color:rgba(236,201,75,var(--bg-opacity))}.lg\:hover\:bg-yellow-600:hover{--bg-opacity:1;background-color:#d69e2e;background-color:rgba(214,158,46,var(--bg-opacity))}.lg\:hover\:bg-yellow-700:hover{--bg-opacity:1;background-color:#b7791f;background-color:rgba(183,121,31,var(--bg-opacity))}.lg\:hover\:bg-yellow-800:hover{--bg-opacity:1;background-color:#975a16;background-color:rgba(151,90,22,var(--bg-opacity))}.lg\:hover\:bg-yellow-900:hover{--bg-opacity:1;background-color:#744210;background-color:rgba(116,66,16,var(--bg-opacity))}.lg\:hover\:bg-green-100:hover{--bg-opacity:1;background-color:#f0fff4;background-color:rgba(240,255,244,var(--bg-opacity))}.lg\:hover\:bg-green-200:hover{--bg-opacity:1;background-color:#c6f6d5;background-color:rgba(198,246,213,var(--bg-opacity))}.lg\:hover\:bg-green-300:hover{--bg-opacity:1;background-color:#9ae6b4;background-color:rgba(154,230,180,var(--bg-opacity))}.lg\:hover\:bg-green-400:hover{--bg-opacity:1;background-color:#68d391;background-color:rgba(104,211,145,var(--bg-opacity))}.lg\:hover\:bg-green-500:hover{--bg-opacity:1;background-color:#48bb78;background-color:rgba(72,187,120,var(--bg-opacity))}.lg\:hover\:bg-green-600:hover{--bg-opacity:1;background-color:#38a169;background-color:rgba(56,161,105,var(--bg-opacity))}.lg\:hover\:bg-green-700:hover{--bg-opacity:1;background-color:#2f855a;background-color:rgba(47,133,90,var(--bg-opacity))}.lg\:hover\:bg-green-800:hover{--bg-opacity:1;background-color:#276749;background-color:rgba(39,103,73,var(--bg-opacity))}.lg\:hover\:bg-green-900:hover{--bg-opacity:1;background-color:#22543d;background-color:rgba(34,84,61,var(--bg-opacity))}.lg\:hover\:bg-teal-100:hover{--bg-opacity:1;background-color:#e6fffa;background-color:rgba(230,255,250,var(--bg-opacity))}.lg\:hover\:bg-teal-200:hover{--bg-opacity:1;background-color:#b2f5ea;background-color:rgba(178,245,234,var(--bg-opacity))}.lg\:hover\:bg-teal-300:hover{--bg-opacity:1;background-color:#81e6d9;background-color:rgba(129,230,217,var(--bg-opacity))}.lg\:hover\:bg-teal-400:hover{--bg-opacity:1;background-color:#4fd1c5;background-color:rgba(79,209,197,var(--bg-opacity))}.lg\:hover\:bg-teal-500:hover{--bg-opacity:1;background-color:#38b2ac;background-color:rgba(56,178,172,var(--bg-opacity))}.lg\:hover\:bg-teal-600:hover{--bg-opacity:1;background-color:#319795;background-color:rgba(49,151,149,var(--bg-opacity))}.lg\:hover\:bg-teal-700:hover{--bg-opacity:1;background-color:#2c7a7b;background-color:rgba(44,122,123,var(--bg-opacity))}.lg\:hover\:bg-teal-800:hover{--bg-opacity:1;background-color:#285e61;background-color:rgba(40,94,97,var(--bg-opacity))}.lg\:hover\:bg-teal-900:hover{--bg-opacity:1;background-color:#234e52;background-color:rgba(35,78,82,var(--bg-opacity))}.lg\:hover\:bg-blue-100:hover{--bg-opacity:1;background-color:#ebf8ff;background-color:rgba(235,248,255,var(--bg-opacity))}.lg\:hover\:bg-blue-200:hover{--bg-opacity:1;background-color:#bee3f8;background-color:rgba(190,227,248,var(--bg-opacity))}.lg\:hover\:bg-blue-300:hover{--bg-opacity:1;background-color:#90cdf4;background-color:rgba(144,205,244,var(--bg-opacity))}.lg\:hover\:bg-blue-400:hover{--bg-opacity:1;background-color:#63b3ed;background-color:rgba(99,179,237,var(--bg-opacity))}.lg\:hover\:bg-blue-500:hover{--bg-opacity:1;background-color:#4299e1;background-color:rgba(66,153,225,var(--bg-opacity))}.lg\:hover\:bg-blue-600:hover{--bg-opacity:1;background-color:#3182ce;background-color:rgba(49,130,206,var(--bg-opacity))}.lg\:hover\:bg-blue-700:hover{--bg-opacity:1;background-color:#2b6cb0;background-color:rgba(43,108,176,var(--bg-opacity))}.lg\:hover\:bg-blue-800:hover{--bg-opacity:1;background-color:#2c5282;background-color:rgba(44,82,130,var(--bg-opacity))}.lg\:hover\:bg-blue-900:hover{--bg-opacity:1;background-color:#2a4365;background-color:rgba(42,67,101,var(--bg-opacity))}.lg\:hover\:bg-indigo-100:hover{--bg-opacity:1;background-color:#ebf4ff;background-color:rgba(235,244,255,var(--bg-opacity))}.lg\:hover\:bg-indigo-200:hover{--bg-opacity:1;background-color:#c3dafe;background-color:rgba(195,218,254,var(--bg-opacity))}.lg\:hover\:bg-indigo-300:hover{--bg-opacity:1;background-color:#a3bffa;background-color:rgba(163,191,250,var(--bg-opacity))}.lg\:hover\:bg-indigo-400:hover{--bg-opacity:1;background-color:#7f9cf5;background-color:rgba(127,156,245,var(--bg-opacity))}.lg\:hover\:bg-indigo-500:hover{--bg-opacity:1;background-color:#667eea;background-color:rgba(102,126,234,var(--bg-opacity))}.lg\:hover\:bg-indigo-600:hover{--bg-opacity:1;background-color:#5a67d8;background-color:rgba(90,103,216,var(--bg-opacity))}.lg\:hover\:bg-indigo-700:hover{--bg-opacity:1;background-color:#4c51bf;background-color:rgba(76,81,191,var(--bg-opacity))}.lg\:hover\:bg-indigo-800:hover{--bg-opacity:1;background-color:#434190;background-color:rgba(67,65,144,var(--bg-opacity))}.lg\:hover\:bg-indigo-900:hover{--bg-opacity:1;background-color:#3c366b;background-color:rgba(60,54,107,var(--bg-opacity))}.lg\:hover\:bg-purple-100:hover{--bg-opacity:1;background-color:#faf5ff;background-color:rgba(250,245,255,var(--bg-opacity))}.lg\:hover\:bg-purple-200:hover{--bg-opacity:1;background-color:#e9d8fd;background-color:rgba(233,216,253,var(--bg-opacity))}.lg\:hover\:bg-purple-300:hover{--bg-opacity:1;background-color:#d6bcfa;background-color:rgba(214,188,250,var(--bg-opacity))}.lg\:hover\:bg-purple-400:hover{--bg-opacity:1;background-color:#b794f4;background-color:rgba(183,148,244,var(--bg-opacity))}.lg\:hover\:bg-purple-500:hover{--bg-opacity:1;background-color:#9f7aea;background-color:rgba(159,122,234,var(--bg-opacity))}.lg\:hover\:bg-purple-600:hover{--bg-opacity:1;background-color:#805ad5;background-color:rgba(128,90,213,var(--bg-opacity))}.lg\:hover\:bg-purple-700:hover{--bg-opacity:1;background-color:#6b46c1;background-color:rgba(107,70,193,var(--bg-opacity))}.lg\:hover\:bg-purple-800:hover{--bg-opacity:1;background-color:#553c9a;background-color:rgba(85,60,154,var(--bg-opacity))}.lg\:hover\:bg-purple-900:hover{--bg-opacity:1;background-color:#44337a;background-color:rgba(68,51,122,var(--bg-opacity))}.lg\:hover\:bg-pink-100:hover{--bg-opacity:1;background-color:#fff5f7;background-color:rgba(255,245,247,var(--bg-opacity))}.lg\:hover\:bg-pink-200:hover{--bg-opacity:1;background-color:#fed7e2;background-color:rgba(254,215,226,var(--bg-opacity))}.lg\:hover\:bg-pink-300:hover{--bg-opacity:1;background-color:#fbb6ce;background-color:rgba(251,182,206,var(--bg-opacity))}.lg\:hover\:bg-pink-400:hover{--bg-opacity:1;background-color:#f687b3;background-color:rgba(246,135,179,var(--bg-opacity))}.lg\:hover\:bg-pink-500:hover{--bg-opacity:1;background-color:#ed64a6;background-color:rgba(237,100,166,var(--bg-opacity))}.lg\:hover\:bg-pink-600:hover{--bg-opacity:1;background-color:#d53f8c;background-color:rgba(213,63,140,var(--bg-opacity))}.lg\:hover\:bg-pink-700:hover{--bg-opacity:1;background-color:#b83280;background-color:rgba(184,50,128,var(--bg-opacity))}.lg\:hover\:bg-pink-800:hover{--bg-opacity:1;background-color:#97266d;background-color:rgba(151,38,109,var(--bg-opacity))}.lg\:hover\:bg-pink-900:hover{--bg-opacity:1;background-color:#702459;background-color:rgba(112,36,89,var(--bg-opacity))}.lg\:focus\:bg-transparent:focus{background-color:transparent}.lg\:focus\:bg-current:focus{background-color:currentColor}.lg\:focus\:bg-black:focus{--bg-opacity:1;background-color:#000;background-color:rgba(0,0,0,var(--bg-opacity))}.lg\:focus\:bg-white:focus{--bg-opacity:1;background-color:#fff;background-color:rgba(255,255,255,var(--bg-opacity))}.lg\:focus\:bg-gray-100:focus{--bg-opacity:1;background-color:#f7fafc;background-color:rgba(247,250,252,var(--bg-opacity))}.lg\:focus\:bg-gray-200:focus{--bg-opacity:1;background-color:#edf2f7;background-color:rgba(237,242,247,var(--bg-opacity))}.lg\:focus\:bg-gray-300:focus{--bg-opacity:1;background-color:#e2e8f0;background-color:rgba(226,232,240,var(--bg-opacity))}.lg\:focus\:bg-gray-400:focus{--bg-opacity:1;background-color:#cbd5e0;background-color:rgba(203,213,224,var(--bg-opacity))}.lg\:focus\:bg-gray-500:focus{--bg-opacity:1;background-color:#a0aec0;background-color:rgba(160,174,192,var(--bg-opacity))}.lg\:focus\:bg-gray-600:focus{--bg-opacity:1;background-color:#718096;background-color:rgba(113,128,150,var(--bg-opacity))}.lg\:focus\:bg-gray-700:focus{--bg-opacity:1;background-color:#4a5568;background-color:rgba(74,85,104,var(--bg-opacity))}.lg\:focus\:bg-gray-800:focus{--bg-opacity:1;background-color:#2d3748;background-color:rgba(45,55,72,var(--bg-opacity))}.lg\:focus\:bg-gray-900:focus{--bg-opacity:1;background-color:#1a202c;background-color:rgba(26,32,44,var(--bg-opacity))}.lg\:focus\:bg-red-100:focus{--bg-opacity:1;background-color:#fff5f5;background-color:rgba(255,245,245,var(--bg-opacity))}.lg\:focus\:bg-red-200:focus{--bg-opacity:1;background-color:#fed7d7;background-color:rgba(254,215,215,var(--bg-opacity))}.lg\:focus\:bg-red-300:focus{--bg-opacity:1;background-color:#feb2b2;background-color:rgba(254,178,178,var(--bg-opacity))}.lg\:focus\:bg-red-400:focus{--bg-opacity:1;background-color:#fc8181;background-color:rgba(252,129,129,var(--bg-opacity))}.lg\:focus\:bg-red-500:focus{--bg-opacity:1;background-color:#f56565;background-color:rgba(245,101,101,var(--bg-opacity))}.lg\:focus\:bg-red-600:focus{--bg-opacity:1;background-color:#e53e3e;background-color:rgba(229,62,62,var(--bg-opacity))}.lg\:focus\:bg-red-700:focus{--bg-opacity:1;background-color:#c53030;background-color:rgba(197,48,48,var(--bg-opacity))}.lg\:focus\:bg-red-800:focus{--bg-opacity:1;background-color:#9b2c2c;background-color:rgba(155,44,44,var(--bg-opacity))}.lg\:focus\:bg-red-900:focus{--bg-opacity:1;background-color:#742a2a;background-color:rgba(116,42,42,var(--bg-opacity))}.lg\:focus\:bg-orange-100:focus{--bg-opacity:1;background-color:#fffaf0;background-color:rgba(255,250,240,var(--bg-opacity))}.lg\:focus\:bg-orange-200:focus{--bg-opacity:1;background-color:#feebc8;background-color:rgba(254,235,200,var(--bg-opacity))}.lg\:focus\:bg-orange-300:focus{--bg-opacity:1;background-color:#fbd38d;background-color:rgba(251,211,141,var(--bg-opacity))}.lg\:focus\:bg-orange-400:focus{--bg-opacity:1;background-color:#f6ad55;background-color:rgba(246,173,85,var(--bg-opacity))}.lg\:focus\:bg-orange-500:focus{--bg-opacity:1;background-color:#ed8936;background-color:rgba(237,137,54,var(--bg-opacity))}.lg\:focus\:bg-orange-600:focus{--bg-opacity:1;background-color:#dd6b20;background-color:rgba(221,107,32,var(--bg-opacity))}.lg\:focus\:bg-orange-700:focus{--bg-opacity:1;background-color:#c05621;background-color:rgba(192,86,33,var(--bg-opacity))}.lg\:focus\:bg-orange-800:focus{--bg-opacity:1;background-color:#9c4221;background-color:rgba(156,66,33,var(--bg-opacity))}.lg\:focus\:bg-orange-900:focus{--bg-opacity:1;background-color:#7b341e;background-color:rgba(123,52,30,var(--bg-opacity))}.lg\:focus\:bg-yellow-100:focus{--bg-opacity:1;background-color:ivory;background-color:rgba(255,255,240,var(--bg-opacity))}.lg\:focus\:bg-yellow-200:focus{--bg-opacity:1;background-color:#fefcbf;background-color:rgba(254,252,191,var(--bg-opacity))}.lg\:focus\:bg-yellow-300:focus{--bg-opacity:1;background-color:#faf089;background-color:rgba(250,240,137,var(--bg-opacity))}.lg\:focus\:bg-yellow-400:focus{--bg-opacity:1;background-color:#f6e05e;background-color:rgba(246,224,94,var(--bg-opacity))}.lg\:focus\:bg-yellow-500:focus{--bg-opacity:1;background-color:#ecc94b;background-color:rgba(236,201,75,var(--bg-opacity))}.lg\:focus\:bg-yellow-600:focus{--bg-opacity:1;background-color:#d69e2e;background-color:rgba(214,158,46,var(--bg-opacity))}.lg\:focus\:bg-yellow-700:focus{--bg-opacity:1;background-color:#b7791f;background-color:rgba(183,121,31,var(--bg-opacity))}.lg\:focus\:bg-yellow-800:focus{--bg-opacity:1;background-color:#975a16;background-color:rgba(151,90,22,var(--bg-opacity))}.lg\:focus\:bg-yellow-900:focus{--bg-opacity:1;background-color:#744210;background-color:rgba(116,66,16,var(--bg-opacity))}.lg\:focus\:bg-green-100:focus{--bg-opacity:1;background-color:#f0fff4;background-color:rgba(240,255,244,var(--bg-opacity))}.lg\:focus\:bg-green-200:focus{--bg-opacity:1;background-color:#c6f6d5;background-color:rgba(198,246,213,var(--bg-opacity))}.lg\:focus\:bg-green-300:focus{--bg-opacity:1;background-color:#9ae6b4;background-color:rgba(154,230,180,var(--bg-opacity))}.lg\:focus\:bg-green-400:focus{--bg-opacity:1;background-color:#68d391;background-color:rgba(104,211,145,var(--bg-opacity))}.lg\:focus\:bg-green-500:focus{--bg-opacity:1;background-color:#48bb78;background-color:rgba(72,187,120,var(--bg-opacity))}.lg\:focus\:bg-green-600:focus{--bg-opacity:1;background-color:#38a169;background-color:rgba(56,161,105,var(--bg-opacity))}.lg\:focus\:bg-green-700:focus{--bg-opacity:1;background-color:#2f855a;background-color:rgba(47,133,90,var(--bg-opacity))}.lg\:focus\:bg-green-800:focus{--bg-opacity:1;background-color:#276749;background-color:rgba(39,103,73,var(--bg-opacity))}.lg\:focus\:bg-green-900:focus{--bg-opacity:1;background-color:#22543d;background-color:rgba(34,84,61,var(--bg-opacity))}.lg\:focus\:bg-teal-100:focus{--bg-opacity:1;background-color:#e6fffa;background-color:rgba(230,255,250,var(--bg-opacity))}.lg\:focus\:bg-teal-200:focus{--bg-opacity:1;background-color:#b2f5ea;background-color:rgba(178,245,234,var(--bg-opacity))}.lg\:focus\:bg-teal-300:focus{--bg-opacity:1;background-color:#81e6d9;background-color:rgba(129,230,217,var(--bg-opacity))}.lg\:focus\:bg-teal-400:focus{--bg-opacity:1;background-color:#4fd1c5;background-color:rgba(79,209,197,var(--bg-opacity))}.lg\:focus\:bg-teal-500:focus{--bg-opacity:1;background-color:#38b2ac;background-color:rgba(56,178,172,var(--bg-opacity))}.lg\:focus\:bg-teal-600:focus{--bg-opacity:1;background-color:#319795;background-color:rgba(49,151,149,var(--bg-opacity))}.lg\:focus\:bg-teal-700:focus{--bg-opacity:1;background-color:#2c7a7b;background-color:rgba(44,122,123,var(--bg-opacity))}.lg\:focus\:bg-teal-800:focus{--bg-opacity:1;background-color:#285e61;background-color:rgba(40,94,97,var(--bg-opacity))}.lg\:focus\:bg-teal-900:focus{--bg-opacity:1;background-color:#234e52;background-color:rgba(35,78,82,var(--bg-opacity))}.lg\:focus\:bg-blue-100:focus{--bg-opacity:1;background-color:#ebf8ff;background-color:rgba(235,248,255,var(--bg-opacity))}.lg\:focus\:bg-blue-200:focus{--bg-opacity:1;background-color:#bee3f8;background-color:rgba(190,227,248,var(--bg-opacity))}.lg\:focus\:bg-blue-300:focus{--bg-opacity:1;background-color:#90cdf4;background-color:rgba(144,205,244,var(--bg-opacity))}.lg\:focus\:bg-blue-400:focus{--bg-opacity:1;background-color:#63b3ed;background-color:rgba(99,179,237,var(--bg-opacity))}.lg\:focus\:bg-blue-500:focus{--bg-opacity:1;background-color:#4299e1;background-color:rgba(66,153,225,var(--bg-opacity))}.lg\:focus\:bg-blue-600:focus{--bg-opacity:1;background-color:#3182ce;background-color:rgba(49,130,206,var(--bg-opacity))}.lg\:focus\:bg-blue-700:focus{--bg-opacity:1;background-color:#2b6cb0;background-color:rgba(43,108,176,var(--bg-opacity))}.lg\:focus\:bg-blue-800:focus{--bg-opacity:1;background-color:#2c5282;background-color:rgba(44,82,130,var(--bg-opacity))}.lg\:focus\:bg-blue-900:focus{--bg-opacity:1;background-color:#2a4365;background-color:rgba(42,67,101,var(--bg-opacity))}.lg\:focus\:bg-indigo-100:focus{--bg-opacity:1;background-color:#ebf4ff;background-color:rgba(235,244,255,var(--bg-opacity))}.lg\:focus\:bg-indigo-200:focus{--bg-opacity:1;background-color:#c3dafe;background-color:rgba(195,218,254,var(--bg-opacity))}.lg\:focus\:bg-indigo-300:focus{--bg-opacity:1;background-color:#a3bffa;background-color:rgba(163,191,250,var(--bg-opacity))}.lg\:focus\:bg-indigo-400:focus{--bg-opacity:1;background-color:#7f9cf5;background-color:rgba(127,156,245,var(--bg-opacity))}.lg\:focus\:bg-indigo-500:focus{--bg-opacity:1;background-color:#667eea;background-color:rgba(102,126,234,var(--bg-opacity))}.lg\:focus\:bg-indigo-600:focus{--bg-opacity:1;background-color:#5a67d8;background-color:rgba(90,103,216,var(--bg-opacity))}.lg\:focus\:bg-indigo-700:focus{--bg-opacity:1;background-color:#4c51bf;background-color:rgba(76,81,191,var(--bg-opacity))}.lg\:focus\:bg-indigo-800:focus{--bg-opacity:1;background-color:#434190;background-color:rgba(67,65,144,var(--bg-opacity))}.lg\:focus\:bg-indigo-900:focus{--bg-opacity:1;background-color:#3c366b;background-color:rgba(60,54,107,var(--bg-opacity))}.lg\:focus\:bg-purple-100:focus{--bg-opacity:1;background-color:#faf5ff;background-color:rgba(250,245,255,var(--bg-opacity))}.lg\:focus\:bg-purple-200:focus{--bg-opacity:1;background-color:#e9d8fd;background-color:rgba(233,216,253,var(--bg-opacity))}.lg\:focus\:bg-purple-300:focus{--bg-opacity:1;background-color:#d6bcfa;background-color:rgba(214,188,250,var(--bg-opacity))}.lg\:focus\:bg-purple-400:focus{--bg-opacity:1;background-color:#b794f4;background-color:rgba(183,148,244,var(--bg-opacity))}.lg\:focus\:bg-purple-500:focus{--bg-opacity:1;background-color:#9f7aea;background-color:rgba(159,122,234,var(--bg-opacity))}.lg\:focus\:bg-purple-600:focus{--bg-opacity:1;background-color:#805ad5;background-color:rgba(128,90,213,var(--bg-opacity))}.lg\:focus\:bg-purple-700:focus{--bg-opacity:1;background-color:#6b46c1;background-color:rgba(107,70,193,var(--bg-opacity))}.lg\:focus\:bg-purple-800:focus{--bg-opacity:1;background-color:#553c9a;background-color:rgba(85,60,154,var(--bg-opacity))}.lg\:focus\:bg-purple-900:focus{--bg-opacity:1;background-color:#44337a;background-color:rgba(68,51,122,var(--bg-opacity))}.lg\:focus\:bg-pink-100:focus{--bg-opacity:1;background-color:#fff5f7;background-color:rgba(255,245,247,var(--bg-opacity))}.lg\:focus\:bg-pink-200:focus{--bg-opacity:1;background-color:#fed7e2;background-color:rgba(254,215,226,var(--bg-opacity))}.lg\:focus\:bg-pink-300:focus{--bg-opacity:1;background-color:#fbb6ce;background-color:rgba(251,182,206,var(--bg-opacity))}.lg\:focus\:bg-pink-400:focus{--bg-opacity:1;background-color:#f687b3;background-color:rgba(246,135,179,var(--bg-opacity))}.lg\:focus\:bg-pink-500:focus{--bg-opacity:1;background-color:#ed64a6;background-color:rgba(237,100,166,var(--bg-opacity))}.lg\:focus\:bg-pink-600:focus{--bg-opacity:1;background-color:#d53f8c;background-color:rgba(213,63,140,var(--bg-opacity))}.lg\:focus\:bg-pink-700:focus{--bg-opacity:1;background-color:#b83280;background-color:rgba(184,50,128,var(--bg-opacity))}.lg\:focus\:bg-pink-800:focus{--bg-opacity:1;background-color:#97266d;background-color:rgba(151,38,109,var(--bg-opacity))}.lg\:focus\:bg-pink-900:focus{--bg-opacity:1;background-color:#702459;background-color:rgba(112,36,89,var(--bg-opacity))}.lg\:bg-none{background-image:none}.lg\:bg-gradient-to-t{background-image:linear-gradient(to top,var(--gradient-color-stops))}.lg\:bg-gradient-to-tr{background-image:linear-gradient(to top right,var(--gradient-color-stops))}.lg\:bg-gradient-to-r{background-image:linear-gradient(to right,var(--gradient-color-stops))}.lg\:bg-gradient-to-br{background-image:linear-gradient(to bottom right,var(--gradient-color-stops))}.lg\:bg-gradient-to-b{background-image:linear-gradient(to bottom,var(--gradient-color-stops))}.lg\:bg-gradient-to-bl{background-image:linear-gradient(to bottom left,var(--gradient-color-stops))}.lg\:bg-gradient-to-l{background-image:linear-gradient(to left,var(--gradient-color-stops))}.lg\:bg-gradient-to-tl{background-image:linear-gradient(to top left,var(--gradient-color-stops))}.lg\:from-transparent{--gradient-from-color:transparent;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(0, 0, 0, 0))}.lg\:from-current{--gradient-from-color:currentColor;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 255, 255, 0))}.lg\:from-black{--gradient-from-color:#000;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(0, 0, 0, 0))}.lg\:from-white{--gradient-from-color:#fff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 255, 255, 0))}.lg\:from-gray-100{--gradient-from-color:#f7fafc;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(247, 250, 252, 0))}.lg\:from-gray-200{--gradient-from-color:#edf2f7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(237, 242, 247, 0))}.lg\:from-gray-300{--gradient-from-color:#e2e8f0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(226, 232, 240, 0))}.lg\:from-gray-400{--gradient-from-color:#cbd5e0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(203, 213, 224, 0))}.lg\:from-gray-500{--gradient-from-color:#a0aec0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(160, 174, 192, 0))}.lg\:from-gray-600{--gradient-from-color:#718096;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(113, 128, 150, 0))}.lg\:from-gray-700{--gradient-from-color:#4a5568;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(74, 85, 104, 0))}.lg\:from-gray-800{--gradient-from-color:#2d3748;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(45, 55, 72, 0))}.lg\:from-gray-900{--gradient-from-color:#1a202c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(26, 32, 44, 0))}.lg\:from-red-100{--gradient-from-color:#fff5f5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 245, 245, 0))}.lg\:from-red-200{--gradient-from-color:#fed7d7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(254, 215, 215, 0))}.lg\:from-red-300{--gradient-from-color:#feb2b2;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(254, 178, 178, 0))}.lg\:from-red-400{--gradient-from-color:#fc8181;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(252, 129, 129, 0))}.lg\:from-red-500{--gradient-from-color:#f56565;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(245, 101, 101, 0))}.lg\:from-red-600{--gradient-from-color:#e53e3e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(229, 62, 62, 0))}.lg\:from-red-700{--gradient-from-color:#c53030;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(197, 48, 48, 0))}.lg\:from-red-800{--gradient-from-color:#9b2c2c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(155, 44, 44, 0))}.lg\:from-red-900{--gradient-from-color:#742a2a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(116, 42, 42, 0))}.lg\:from-orange-100{--gradient-from-color:#fffaf0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 250, 240, 0))}.lg\:from-orange-200{--gradient-from-color:#feebc8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(254, 235, 200, 0))}.lg\:from-orange-300{--gradient-from-color:#fbd38d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(251, 211, 141, 0))}.lg\:from-orange-400{--gradient-from-color:#f6ad55;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(246, 173, 85, 0))}.lg\:from-orange-500{--gradient-from-color:#ed8936;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(237, 137, 54, 0))}.lg\:from-orange-600{--gradient-from-color:#dd6b20;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(221, 107, 32, 0))}.lg\:from-orange-700{--gradient-from-color:#c05621;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(192, 86, 33, 0))}.lg\:from-orange-800{--gradient-from-color:#9c4221;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(156, 66, 33, 0))}.lg\:from-orange-900{--gradient-from-color:#7b341e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(123, 52, 30, 0))}.lg\:from-yellow-100{--gradient-from-color:#fffff0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 255, 240, 0))}.lg\:from-yellow-200{--gradient-from-color:#fefcbf;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(254, 252, 191, 0))}.lg\:from-yellow-300{--gradient-from-color:#faf089;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(250, 240, 137, 0))}.lg\:from-yellow-400{--gradient-from-color:#f6e05e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(246, 224, 94, 0))}.lg\:from-yellow-500{--gradient-from-color:#ecc94b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(236, 201, 75, 0))}.lg\:from-yellow-600{--gradient-from-color:#d69e2e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(214, 158, 46, 0))}.lg\:from-yellow-700{--gradient-from-color:#b7791f;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(183, 121, 31, 0))}.lg\:from-yellow-800{--gradient-from-color:#975a16;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(151, 90, 22, 0))}.lg\:from-yellow-900{--gradient-from-color:#744210;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(116, 66, 16, 0))}.lg\:from-green-100{--gradient-from-color:#f0fff4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(240, 255, 244, 0))}.lg\:from-green-200{--gradient-from-color:#c6f6d5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(198, 246, 213, 0))}.lg\:from-green-300{--gradient-from-color:#9ae6b4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(154, 230, 180, 0))}.lg\:from-green-400{--gradient-from-color:#68d391;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(104, 211, 145, 0))}.lg\:from-green-500{--gradient-from-color:#48bb78;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(72, 187, 120, 0))}.lg\:from-green-600{--gradient-from-color:#38a169;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(56, 161, 105, 0))}.lg\:from-green-700{--gradient-from-color:#2f855a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(47, 133, 90, 0))}.lg\:from-green-800{--gradient-from-color:#276749;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(39, 103, 73, 0))}.lg\:from-green-900{--gradient-from-color:#22543d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(34, 84, 61, 0))}.lg\:from-teal-100{--gradient-from-color:#e6fffa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(230, 255, 250, 0))}.lg\:from-teal-200{--gradient-from-color:#b2f5ea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(178, 245, 234, 0))}.lg\:from-teal-300{--gradient-from-color:#81e6d9;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(129, 230, 217, 0))}.lg\:from-teal-400{--gradient-from-color:#4fd1c5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(79, 209, 197, 0))}.lg\:from-teal-500{--gradient-from-color:#38b2ac;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(56, 178, 172, 0))}.lg\:from-teal-600{--gradient-from-color:#319795;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(49, 151, 149, 0))}.lg\:from-teal-700{--gradient-from-color:#2c7a7b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(44, 122, 123, 0))}.lg\:from-teal-800{--gradient-from-color:#285e61;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(40, 94, 97, 0))}.lg\:from-teal-900{--gradient-from-color:#234e52;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(35, 78, 82, 0))}.lg\:from-blue-100{--gradient-from-color:#ebf8ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(235, 248, 255, 0))}.lg\:from-blue-200{--gradient-from-color:#bee3f8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(190, 227, 248, 0))}.lg\:from-blue-300{--gradient-from-color:#90cdf4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(144, 205, 244, 0))}.lg\:from-blue-400{--gradient-from-color:#63b3ed;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(99, 179, 237, 0))}.lg\:from-blue-500{--gradient-from-color:#4299e1;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(66, 153, 225, 0))}.lg\:from-blue-600{--gradient-from-color:#3182ce;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(49, 130, 206, 0))}.lg\:from-blue-700{--gradient-from-color:#2b6cb0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(43, 108, 176, 0))}.lg\:from-blue-800{--gradient-from-color:#2c5282;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(44, 82, 130, 0))}.lg\:from-blue-900{--gradient-from-color:#2a4365;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(42, 67, 101, 0))}.lg\:from-indigo-100{--gradient-from-color:#ebf4ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(235, 244, 255, 0))}.lg\:from-indigo-200{--gradient-from-color:#c3dafe;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(195, 218, 254, 0))}.lg\:from-indigo-300{--gradient-from-color:#a3bffa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(163, 191, 250, 0))}.lg\:from-indigo-400{--gradient-from-color:#7f9cf5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(127, 156, 245, 0))}.lg\:from-indigo-500{--gradient-from-color:#667eea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(102, 126, 234, 0))}.lg\:from-indigo-600{--gradient-from-color:#5a67d8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(90, 103, 216, 0))}.lg\:from-indigo-700{--gradient-from-color:#4c51bf;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(76, 81, 191, 0))}.lg\:from-indigo-800{--gradient-from-color:#434190;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(67, 65, 144, 0))}.lg\:from-indigo-900{--gradient-from-color:#3c366b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(60, 54, 107, 0))}.lg\:from-purple-100{--gradient-from-color:#faf5ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(250, 245, 255, 0))}.lg\:from-purple-200{--gradient-from-color:#e9d8fd;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(233, 216, 253, 0))}.lg\:from-purple-300{--gradient-from-color:#d6bcfa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(214, 188, 250, 0))}.lg\:from-purple-400{--gradient-from-color:#b794f4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(183, 148, 244, 0))}.lg\:from-purple-500{--gradient-from-color:#9f7aea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(159, 122, 234, 0))}.lg\:from-purple-600{--gradient-from-color:#805ad5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(128, 90, 213, 0))}.lg\:from-purple-700{--gradient-from-color:#6b46c1;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(107, 70, 193, 0))}.lg\:from-purple-800{--gradient-from-color:#553c9a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(85, 60, 154, 0))}.lg\:from-purple-900{--gradient-from-color:#44337a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(68, 51, 122, 0))}.lg\:from-pink-100{--gradient-from-color:#fff5f7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 245, 247, 0))}.lg\:from-pink-200{--gradient-from-color:#fed7e2;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(254, 215, 226, 0))}.lg\:from-pink-300{--gradient-from-color:#fbb6ce;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(251, 182, 206, 0))}.lg\:from-pink-400{--gradient-from-color:#f687b3;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(246, 135, 179, 0))}.lg\:from-pink-500{--gradient-from-color:#ed64a6;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(237, 100, 166, 0))}.lg\:from-pink-600{--gradient-from-color:#d53f8c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(213, 63, 140, 0))}.lg\:from-pink-700{--gradient-from-color:#b83280;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(184, 50, 128, 0))}.lg\:from-pink-800{--gradient-from-color:#97266d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(151, 38, 109, 0))}.lg\:from-pink-900{--gradient-from-color:#702459;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(112, 36, 89, 0))}.lg\:via-transparent{--gradient-via-color:transparent;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(0, 0, 0, 0))}.lg\:via-current{--gradient-via-color:currentColor;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 255, 255, 0))}.lg\:via-black{--gradient-via-color:#000;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(0, 0, 0, 0))}.lg\:via-white{--gradient-via-color:#fff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 255, 255, 0))}.lg\:via-gray-100{--gradient-via-color:#f7fafc;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(247, 250, 252, 0))}.lg\:via-gray-200{--gradient-via-color:#edf2f7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(237, 242, 247, 0))}.lg\:via-gray-300{--gradient-via-color:#e2e8f0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(226, 232, 240, 0))}.lg\:via-gray-400{--gradient-via-color:#cbd5e0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(203, 213, 224, 0))}.lg\:via-gray-500{--gradient-via-color:#a0aec0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(160, 174, 192, 0))}.lg\:via-gray-600{--gradient-via-color:#718096;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(113, 128, 150, 0))}.lg\:via-gray-700{--gradient-via-color:#4a5568;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(74, 85, 104, 0))}.lg\:via-gray-800{--gradient-via-color:#2d3748;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(45, 55, 72, 0))}.lg\:via-gray-900{--gradient-via-color:#1a202c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(26, 32, 44, 0))}.lg\:via-red-100{--gradient-via-color:#fff5f5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 245, 245, 0))}.lg\:via-red-200{--gradient-via-color:#fed7d7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(254, 215, 215, 0))}.lg\:via-red-300{--gradient-via-color:#feb2b2;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(254, 178, 178, 0))}.lg\:via-red-400{--gradient-via-color:#fc8181;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(252, 129, 129, 0))}.lg\:via-red-500{--gradient-via-color:#f56565;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(245, 101, 101, 0))}.lg\:via-red-600{--gradient-via-color:#e53e3e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(229, 62, 62, 0))}.lg\:via-red-700{--gradient-via-color:#c53030;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(197, 48, 48, 0))}.lg\:via-red-800{--gradient-via-color:#9b2c2c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(155, 44, 44, 0))}.lg\:via-red-900{--gradient-via-color:#742a2a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(116, 42, 42, 0))}.lg\:via-orange-100{--gradient-via-color:#fffaf0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 250, 240, 0))}.lg\:via-orange-200{--gradient-via-color:#feebc8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(254, 235, 200, 0))}.lg\:via-orange-300{--gradient-via-color:#fbd38d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(251, 211, 141, 0))}.lg\:via-orange-400{--gradient-via-color:#f6ad55;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(246, 173, 85, 0))}.lg\:via-orange-500{--gradient-via-color:#ed8936;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(237, 137, 54, 0))}.lg\:via-orange-600{--gradient-via-color:#dd6b20;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(221, 107, 32, 0))}.lg\:via-orange-700{--gradient-via-color:#c05621;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(192, 86, 33, 0))}.lg\:via-orange-800{--gradient-via-color:#9c4221;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(156, 66, 33, 0))}.lg\:via-orange-900{--gradient-via-color:#7b341e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(123, 52, 30, 0))}.lg\:via-yellow-100{--gradient-via-color:#fffff0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 255, 240, 0))}.lg\:via-yellow-200{--gradient-via-color:#fefcbf;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(254, 252, 191, 0))}.lg\:via-yellow-300{--gradient-via-color:#faf089;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(250, 240, 137, 0))}.lg\:via-yellow-400{--gradient-via-color:#f6e05e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(246, 224, 94, 0))}.lg\:via-yellow-500{--gradient-via-color:#ecc94b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(236, 201, 75, 0))}.lg\:via-yellow-600{--gradient-via-color:#d69e2e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(214, 158, 46, 0))}.lg\:via-yellow-700{--gradient-via-color:#b7791f;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(183, 121, 31, 0))}.lg\:via-yellow-800{--gradient-via-color:#975a16;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(151, 90, 22, 0))}.lg\:via-yellow-900{--gradient-via-color:#744210;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(116, 66, 16, 0))}.lg\:via-green-100{--gradient-via-color:#f0fff4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(240, 255, 244, 0))}.lg\:via-green-200{--gradient-via-color:#c6f6d5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(198, 246, 213, 0))}.lg\:via-green-300{--gradient-via-color:#9ae6b4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(154, 230, 180, 0))}.lg\:via-green-400{--gradient-via-color:#68d391;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(104, 211, 145, 0))}.lg\:via-green-500{--gradient-via-color:#48bb78;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(72, 187, 120, 0))}.lg\:via-green-600{--gradient-via-color:#38a169;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(56, 161, 105, 0))}.lg\:via-green-700{--gradient-via-color:#2f855a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(47, 133, 90, 0))}.lg\:via-green-800{--gradient-via-color:#276749;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(39, 103, 73, 0))}.lg\:via-green-900{--gradient-via-color:#22543d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(34, 84, 61, 0))}.lg\:via-teal-100{--gradient-via-color:#e6fffa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(230, 255, 250, 0))}.lg\:via-teal-200{--gradient-via-color:#b2f5ea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(178, 245, 234, 0))}.lg\:via-teal-300{--gradient-via-color:#81e6d9;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(129, 230, 217, 0))}.lg\:via-teal-400{--gradient-via-color:#4fd1c5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(79, 209, 197, 0))}.lg\:via-teal-500{--gradient-via-color:#38b2ac;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(56, 178, 172, 0))}.lg\:via-teal-600{--gradient-via-color:#319795;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(49, 151, 149, 0))}.lg\:via-teal-700{--gradient-via-color:#2c7a7b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(44, 122, 123, 0))}.lg\:via-teal-800{--gradient-via-color:#285e61;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(40, 94, 97, 0))}.lg\:via-teal-900{--gradient-via-color:#234e52;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(35, 78, 82, 0))}.lg\:via-blue-100{--gradient-via-color:#ebf8ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(235, 248, 255, 0))}.lg\:via-blue-200{--gradient-via-color:#bee3f8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(190, 227, 248, 0))}.lg\:via-blue-300{--gradient-via-color:#90cdf4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(144, 205, 244, 0))}.lg\:via-blue-400{--gradient-via-color:#63b3ed;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(99, 179, 237, 0))}.lg\:via-blue-500{--gradient-via-color:#4299e1;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(66, 153, 225, 0))}.lg\:via-blue-600{--gradient-via-color:#3182ce;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(49, 130, 206, 0))}.lg\:via-blue-700{--gradient-via-color:#2b6cb0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(43, 108, 176, 0))}.lg\:via-blue-800{--gradient-via-color:#2c5282;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(44, 82, 130, 0))}.lg\:via-blue-900{--gradient-via-color:#2a4365;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(42, 67, 101, 0))}.lg\:via-indigo-100{--gradient-via-color:#ebf4ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(235, 244, 255, 0))}.lg\:via-indigo-200{--gradient-via-color:#c3dafe;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(195, 218, 254, 0))}.lg\:via-indigo-300{--gradient-via-color:#a3bffa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(163, 191, 250, 0))}.lg\:via-indigo-400{--gradient-via-color:#7f9cf5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(127, 156, 245, 0))}.lg\:via-indigo-500{--gradient-via-color:#667eea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(102, 126, 234, 0))}.lg\:via-indigo-600{--gradient-via-color:#5a67d8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(90, 103, 216, 0))}.lg\:via-indigo-700{--gradient-via-color:#4c51bf;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(76, 81, 191, 0))}.lg\:via-indigo-800{--gradient-via-color:#434190;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(67, 65, 144, 0))}.lg\:via-indigo-900{--gradient-via-color:#3c366b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(60, 54, 107, 0))}.lg\:via-purple-100{--gradient-via-color:#faf5ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(250, 245, 255, 0))}.lg\:via-purple-200{--gradient-via-color:#e9d8fd;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(233, 216, 253, 0))}.lg\:via-purple-300{--gradient-via-color:#d6bcfa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(214, 188, 250, 0))}.lg\:via-purple-400{--gradient-via-color:#b794f4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(183, 148, 244, 0))}.lg\:via-purple-500{--gradient-via-color:#9f7aea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(159, 122, 234, 0))}.lg\:via-purple-600{--gradient-via-color:#805ad5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(128, 90, 213, 0))}.lg\:via-purple-700{--gradient-via-color:#6b46c1;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(107, 70, 193, 0))}.lg\:via-purple-800{--gradient-via-color:#553c9a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(85, 60, 154, 0))}.lg\:via-purple-900{--gradient-via-color:#44337a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(68, 51, 122, 0))}.lg\:via-pink-100{--gradient-via-color:#fff5f7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 245, 247, 0))}.lg\:via-pink-200{--gradient-via-color:#fed7e2;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(254, 215, 226, 0))}.lg\:via-pink-300{--gradient-via-color:#fbb6ce;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(251, 182, 206, 0))}.lg\:via-pink-400{--gradient-via-color:#f687b3;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(246, 135, 179, 0))}.lg\:via-pink-500{--gradient-via-color:#ed64a6;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(237, 100, 166, 0))}.lg\:via-pink-600{--gradient-via-color:#d53f8c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(213, 63, 140, 0))}.lg\:via-pink-700{--gradient-via-color:#b83280;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(184, 50, 128, 0))}.lg\:via-pink-800{--gradient-via-color:#97266d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(151, 38, 109, 0))}.lg\:via-pink-900{--gradient-via-color:#702459;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(112, 36, 89, 0))}.lg\:to-transparent{--gradient-to-color:transparent}.lg\:to-current{--gradient-to-color:currentColor}.lg\:to-black{--gradient-to-color:#000}.lg\:to-white{--gradient-to-color:#fff}.lg\:to-gray-100{--gradient-to-color:#f7fafc}.lg\:to-gray-200{--gradient-to-color:#edf2f7}.lg\:to-gray-300{--gradient-to-color:#e2e8f0}.lg\:to-gray-400{--gradient-to-color:#cbd5e0}.lg\:to-gray-500{--gradient-to-color:#a0aec0}.lg\:to-gray-600{--gradient-to-color:#718096}.lg\:to-gray-700{--gradient-to-color:#4a5568}.lg\:to-gray-800{--gradient-to-color:#2d3748}.lg\:to-gray-900{--gradient-to-color:#1a202c}.lg\:to-red-100{--gradient-to-color:#fff5f5}.lg\:to-red-200{--gradient-to-color:#fed7d7}.lg\:to-red-300{--gradient-to-color:#feb2b2}.lg\:to-red-400{--gradient-to-color:#fc8181}.lg\:to-red-500{--gradient-to-color:#f56565}.lg\:to-red-600{--gradient-to-color:#e53e3e}.lg\:to-red-700{--gradient-to-color:#c53030}.lg\:to-red-800{--gradient-to-color:#9b2c2c}.lg\:to-red-900{--gradient-to-color:#742a2a}.lg\:to-orange-100{--gradient-to-color:#fffaf0}.lg\:to-orange-200{--gradient-to-color:#feebc8}.lg\:to-orange-300{--gradient-to-color:#fbd38d}.lg\:to-orange-400{--gradient-to-color:#f6ad55}.lg\:to-orange-500{--gradient-to-color:#ed8936}.lg\:to-orange-600{--gradient-to-color:#dd6b20}.lg\:to-orange-700{--gradient-to-color:#c05621}.lg\:to-orange-800{--gradient-to-color:#9c4221}.lg\:to-orange-900{--gradient-to-color:#7b341e}.lg\:to-yellow-100{--gradient-to-color:#fffff0}.lg\:to-yellow-200{--gradient-to-color:#fefcbf}.lg\:to-yellow-300{--gradient-to-color:#faf089}.lg\:to-yellow-400{--gradient-to-color:#f6e05e}.lg\:to-yellow-500{--gradient-to-color:#ecc94b}.lg\:to-yellow-600{--gradient-to-color:#d69e2e}.lg\:to-yellow-700{--gradient-to-color:#b7791f}.lg\:to-yellow-800{--gradient-to-color:#975a16}.lg\:to-yellow-900{--gradient-to-color:#744210}.lg\:to-green-100{--gradient-to-color:#f0fff4}.lg\:to-green-200{--gradient-to-color:#c6f6d5}.lg\:to-green-300{--gradient-to-color:#9ae6b4}.lg\:to-green-400{--gradient-to-color:#68d391}.lg\:to-green-500{--gradient-to-color:#48bb78}.lg\:to-green-600{--gradient-to-color:#38a169}.lg\:to-green-700{--gradient-to-color:#2f855a}.lg\:to-green-800{--gradient-to-color:#276749}.lg\:to-green-900{--gradient-to-color:#22543d}.lg\:to-teal-100{--gradient-to-color:#e6fffa}.lg\:to-teal-200{--gradient-to-color:#b2f5ea}.lg\:to-teal-300{--gradient-to-color:#81e6d9}.lg\:to-teal-400{--gradient-to-color:#4fd1c5}.lg\:to-teal-500{--gradient-to-color:#38b2ac}.lg\:to-teal-600{--gradient-to-color:#319795}.lg\:to-teal-700{--gradient-to-color:#2c7a7b}.lg\:to-teal-800{--gradient-to-color:#285e61}.lg\:to-teal-900{--gradient-to-color:#234e52}.lg\:to-blue-100{--gradient-to-color:#ebf8ff}.lg\:to-blue-200{--gradient-to-color:#bee3f8}.lg\:to-blue-300{--gradient-to-color:#90cdf4}.lg\:to-blue-400{--gradient-to-color:#63b3ed}.lg\:to-blue-500{--gradient-to-color:#4299e1}.lg\:to-blue-600{--gradient-to-color:#3182ce}.lg\:to-blue-700{--gradient-to-color:#2b6cb0}.lg\:to-blue-800{--gradient-to-color:#2c5282}.lg\:to-blue-900{--gradient-to-color:#2a4365}.lg\:to-indigo-100{--gradient-to-color:#ebf4ff}.lg\:to-indigo-200{--gradient-to-color:#c3dafe}.lg\:to-indigo-300{--gradient-to-color:#a3bffa}.lg\:to-indigo-400{--gradient-to-color:#7f9cf5}.lg\:to-indigo-500{--gradient-to-color:#667eea}.lg\:to-indigo-600{--gradient-to-color:#5a67d8}.lg\:to-indigo-700{--gradient-to-color:#4c51bf}.lg\:to-indigo-800{--gradient-to-color:#434190}.lg\:to-indigo-900{--gradient-to-color:#3c366b}.lg\:to-purple-100{--gradient-to-color:#faf5ff}.lg\:to-purple-200{--gradient-to-color:#e9d8fd}.lg\:to-purple-300{--gradient-to-color:#d6bcfa}.lg\:to-purple-400{--gradient-to-color:#b794f4}.lg\:to-purple-500{--gradient-to-color:#9f7aea}.lg\:to-purple-600{--gradient-to-color:#805ad5}.lg\:to-purple-700{--gradient-to-color:#6b46c1}.lg\:to-purple-800{--gradient-to-color:#553c9a}.lg\:to-purple-900{--gradient-to-color:#44337a}.lg\:to-pink-100{--gradient-to-color:#fff5f7}.lg\:to-pink-200{--gradient-to-color:#fed7e2}.lg\:to-pink-300{--gradient-to-color:#fbb6ce}.lg\:to-pink-400{--gradient-to-color:#f687b3}.lg\:to-pink-500{--gradient-to-color:#ed64a6}.lg\:to-pink-600{--gradient-to-color:#d53f8c}.lg\:to-pink-700{--gradient-to-color:#b83280}.lg\:to-pink-800{--gradient-to-color:#97266d}.lg\:to-pink-900{--gradient-to-color:#702459}.lg\:hover\:from-transparent:hover{--gradient-from-color:transparent;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(0, 0, 0, 0))}.lg\:hover\:from-current:hover{--gradient-from-color:currentColor;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 255, 255, 0))}.lg\:hover\:from-black:hover{--gradient-from-color:#000;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(0, 0, 0, 0))}.lg\:hover\:from-white:hover{--gradient-from-color:#fff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 255, 255, 0))}.lg\:hover\:from-gray-100:hover{--gradient-from-color:#f7fafc;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(247, 250, 252, 0))}.lg\:hover\:from-gray-200:hover{--gradient-from-color:#edf2f7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(237, 242, 247, 0))}.lg\:hover\:from-gray-300:hover{--gradient-from-color:#e2e8f0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(226, 232, 240, 0))}.lg\:hover\:from-gray-400:hover{--gradient-from-color:#cbd5e0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(203, 213, 224, 0))}.lg\:hover\:from-gray-500:hover{--gradient-from-color:#a0aec0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(160, 174, 192, 0))}.lg\:hover\:from-gray-600:hover{--gradient-from-color:#718096;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(113, 128, 150, 0))}.lg\:hover\:from-gray-700:hover{--gradient-from-color:#4a5568;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(74, 85, 104, 0))}.lg\:hover\:from-gray-800:hover{--gradient-from-color:#2d3748;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(45, 55, 72, 0))}.lg\:hover\:from-gray-900:hover{--gradient-from-color:#1a202c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(26, 32, 44, 0))}.lg\:hover\:from-red-100:hover{--gradient-from-color:#fff5f5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 245, 245, 0))}.lg\:hover\:from-red-200:hover{--gradient-from-color:#fed7d7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(254, 215, 215, 0))}.lg\:hover\:from-red-300:hover{--gradient-from-color:#feb2b2;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(254, 178, 178, 0))}.lg\:hover\:from-red-400:hover{--gradient-from-color:#fc8181;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(252, 129, 129, 0))}.lg\:hover\:from-red-500:hover{--gradient-from-color:#f56565;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(245, 101, 101, 0))}.lg\:hover\:from-red-600:hover{--gradient-from-color:#e53e3e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(229, 62, 62, 0))}.lg\:hover\:from-red-700:hover{--gradient-from-color:#c53030;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(197, 48, 48, 0))}.lg\:hover\:from-red-800:hover{--gradient-from-color:#9b2c2c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(155, 44, 44, 0))}.lg\:hover\:from-red-900:hover{--gradient-from-color:#742a2a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(116, 42, 42, 0))}.lg\:hover\:from-orange-100:hover{--gradient-from-color:#fffaf0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 250, 240, 0))}.lg\:hover\:from-orange-200:hover{--gradient-from-color:#feebc8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(254, 235, 200, 0))}.lg\:hover\:from-orange-300:hover{--gradient-from-color:#fbd38d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(251, 211, 141, 0))}.lg\:hover\:from-orange-400:hover{--gradient-from-color:#f6ad55;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(246, 173, 85, 0))}.lg\:hover\:from-orange-500:hover{--gradient-from-color:#ed8936;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(237, 137, 54, 0))}.lg\:hover\:from-orange-600:hover{--gradient-from-color:#dd6b20;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(221, 107, 32, 0))}.lg\:hover\:from-orange-700:hover{--gradient-from-color:#c05621;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(192, 86, 33, 0))}.lg\:hover\:from-orange-800:hover{--gradient-from-color:#9c4221;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(156, 66, 33, 0))}.lg\:hover\:from-orange-900:hover{--gradient-from-color:#7b341e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(123, 52, 30, 0))}.lg\:hover\:from-yellow-100:hover{--gradient-from-color:#fffff0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 255, 240, 0))}.lg\:hover\:from-yellow-200:hover{--gradient-from-color:#fefcbf;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(254, 252, 191, 0))}.lg\:hover\:from-yellow-300:hover{--gradient-from-color:#faf089;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(250, 240, 137, 0))}.lg\:hover\:from-yellow-400:hover{--gradient-from-color:#f6e05e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(246, 224, 94, 0))}.lg\:hover\:from-yellow-500:hover{--gradient-from-color:#ecc94b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(236, 201, 75, 0))}.lg\:hover\:from-yellow-600:hover{--gradient-from-color:#d69e2e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(214, 158, 46, 0))}.lg\:hover\:from-yellow-700:hover{--gradient-from-color:#b7791f;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(183, 121, 31, 0))}.lg\:hover\:from-yellow-800:hover{--gradient-from-color:#975a16;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(151, 90, 22, 0))}.lg\:hover\:from-yellow-900:hover{--gradient-from-color:#744210;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(116, 66, 16, 0))}.lg\:hover\:from-green-100:hover{--gradient-from-color:#f0fff4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(240, 255, 244, 0))}.lg\:hover\:from-green-200:hover{--gradient-from-color:#c6f6d5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(198, 246, 213, 0))}.lg\:hover\:from-green-300:hover{--gradient-from-color:#9ae6b4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(154, 230, 180, 0))}.lg\:hover\:from-green-400:hover{--gradient-from-color:#68d391;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(104, 211, 145, 0))}.lg\:hover\:from-green-500:hover{--gradient-from-color:#48bb78;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(72, 187, 120, 0))}.lg\:hover\:from-green-600:hover{--gradient-from-color:#38a169;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(56, 161, 105, 0))}.lg\:hover\:from-green-700:hover{--gradient-from-color:#2f855a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(47, 133, 90, 0))}.lg\:hover\:from-green-800:hover{--gradient-from-color:#276749;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(39, 103, 73, 0))}.lg\:hover\:from-green-900:hover{--gradient-from-color:#22543d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(34, 84, 61, 0))}.lg\:hover\:from-teal-100:hover{--gradient-from-color:#e6fffa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(230, 255, 250, 0))}.lg\:hover\:from-teal-200:hover{--gradient-from-color:#b2f5ea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(178, 245, 234, 0))}.lg\:hover\:from-teal-300:hover{--gradient-from-color:#81e6d9;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(129, 230, 217, 0))}.lg\:hover\:from-teal-400:hover{--gradient-from-color:#4fd1c5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(79, 209, 197, 0))}.lg\:hover\:from-teal-500:hover{--gradient-from-color:#38b2ac;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(56, 178, 172, 0))}.lg\:hover\:from-teal-600:hover{--gradient-from-color:#319795;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(49, 151, 149, 0))}.lg\:hover\:from-teal-700:hover{--gradient-from-color:#2c7a7b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(44, 122, 123, 0))}.lg\:hover\:from-teal-800:hover{--gradient-from-color:#285e61;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(40, 94, 97, 0))}.lg\:hover\:from-teal-900:hover{--gradient-from-color:#234e52;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(35, 78, 82, 0))}.lg\:hover\:from-blue-100:hover{--gradient-from-color:#ebf8ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(235, 248, 255, 0))}.lg\:hover\:from-blue-200:hover{--gradient-from-color:#bee3f8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(190, 227, 248, 0))}.lg\:hover\:from-blue-300:hover{--gradient-from-color:#90cdf4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(144, 205, 244, 0))}.lg\:hover\:from-blue-400:hover{--gradient-from-color:#63b3ed;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(99, 179, 237, 0))}.lg\:hover\:from-blue-500:hover{--gradient-from-color:#4299e1;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(66, 153, 225, 0))}.lg\:hover\:from-blue-600:hover{--gradient-from-color:#3182ce;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(49, 130, 206, 0))}.lg\:hover\:from-blue-700:hover{--gradient-from-color:#2b6cb0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(43, 108, 176, 0))}.lg\:hover\:from-blue-800:hover{--gradient-from-color:#2c5282;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(44, 82, 130, 0))}.lg\:hover\:from-blue-900:hover{--gradient-from-color:#2a4365;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(42, 67, 101, 0))}.lg\:hover\:from-indigo-100:hover{--gradient-from-color:#ebf4ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(235, 244, 255, 0))}.lg\:hover\:from-indigo-200:hover{--gradient-from-color:#c3dafe;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(195, 218, 254, 0))}.lg\:hover\:from-indigo-300:hover{--gradient-from-color:#a3bffa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(163, 191, 250, 0))}.lg\:hover\:from-indigo-400:hover{--gradient-from-color:#7f9cf5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(127, 156, 245, 0))}.lg\:hover\:from-indigo-500:hover{--gradient-from-color:#667eea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(102, 126, 234, 0))}.lg\:hover\:from-indigo-600:hover{--gradient-from-color:#5a67d8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(90, 103, 216, 0))}.lg\:hover\:from-indigo-700:hover{--gradient-from-color:#4c51bf;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(76, 81, 191, 0))}.lg\:hover\:from-indigo-800:hover{--gradient-from-color:#434190;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(67, 65, 144, 0))}.lg\:hover\:from-indigo-900:hover{--gradient-from-color:#3c366b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(60, 54, 107, 0))}.lg\:hover\:from-purple-100:hover{--gradient-from-color:#faf5ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(250, 245, 255, 0))}.lg\:hover\:from-purple-200:hover{--gradient-from-color:#e9d8fd;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(233, 216, 253, 0))}.lg\:hover\:from-purple-300:hover{--gradient-from-color:#d6bcfa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(214, 188, 250, 0))}.lg\:hover\:from-purple-400:hover{--gradient-from-color:#b794f4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(183, 148, 244, 0))}.lg\:hover\:from-purple-500:hover{--gradient-from-color:#9f7aea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(159, 122, 234, 0))}.lg\:hover\:from-purple-600:hover{--gradient-from-color:#805ad5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(128, 90, 213, 0))}.lg\:hover\:from-purple-700:hover{--gradient-from-color:#6b46c1;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(107, 70, 193, 0))}.lg\:hover\:from-purple-800:hover{--gradient-from-color:#553c9a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(85, 60, 154, 0))}.lg\:hover\:from-purple-900:hover{--gradient-from-color:#44337a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(68, 51, 122, 0))}.lg\:hover\:from-pink-100:hover{--gradient-from-color:#fff5f7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 245, 247, 0))}.lg\:hover\:from-pink-200:hover{--gradient-from-color:#fed7e2;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(254, 215, 226, 0))}.lg\:hover\:from-pink-300:hover{--gradient-from-color:#fbb6ce;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(251, 182, 206, 0))}.lg\:hover\:from-pink-400:hover{--gradient-from-color:#f687b3;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(246, 135, 179, 0))}.lg\:hover\:from-pink-500:hover{--gradient-from-color:#ed64a6;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(237, 100, 166, 0))}.lg\:hover\:from-pink-600:hover{--gradient-from-color:#d53f8c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(213, 63, 140, 0))}.lg\:hover\:from-pink-700:hover{--gradient-from-color:#b83280;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(184, 50, 128, 0))}.lg\:hover\:from-pink-800:hover{--gradient-from-color:#97266d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(151, 38, 109, 0))}.lg\:hover\:from-pink-900:hover{--gradient-from-color:#702459;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(112, 36, 89, 0))}.lg\:hover\:via-transparent:hover{--gradient-via-color:transparent;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(0, 0, 0, 0))}.lg\:hover\:via-current:hover{--gradient-via-color:currentColor;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 255, 255, 0))}.lg\:hover\:via-black:hover{--gradient-via-color:#000;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(0, 0, 0, 0))}.lg\:hover\:via-white:hover{--gradient-via-color:#fff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 255, 255, 0))}.lg\:hover\:via-gray-100:hover{--gradient-via-color:#f7fafc;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(247, 250, 252, 0))}.lg\:hover\:via-gray-200:hover{--gradient-via-color:#edf2f7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(237, 242, 247, 0))}.lg\:hover\:via-gray-300:hover{--gradient-via-color:#e2e8f0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(226, 232, 240, 0))}.lg\:hover\:via-gray-400:hover{--gradient-via-color:#cbd5e0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(203, 213, 224, 0))}.lg\:hover\:via-gray-500:hover{--gradient-via-color:#a0aec0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(160, 174, 192, 0))}.lg\:hover\:via-gray-600:hover{--gradient-via-color:#718096;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(113, 128, 150, 0))}.lg\:hover\:via-gray-700:hover{--gradient-via-color:#4a5568;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(74, 85, 104, 0))}.lg\:hover\:via-gray-800:hover{--gradient-via-color:#2d3748;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(45, 55, 72, 0))}.lg\:hover\:via-gray-900:hover{--gradient-via-color:#1a202c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(26, 32, 44, 0))}.lg\:hover\:via-red-100:hover{--gradient-via-color:#fff5f5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 245, 245, 0))}.lg\:hover\:via-red-200:hover{--gradient-via-color:#fed7d7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(254, 215, 215, 0))}.lg\:hover\:via-red-300:hover{--gradient-via-color:#feb2b2;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(254, 178, 178, 0))}.lg\:hover\:via-red-400:hover{--gradient-via-color:#fc8181;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(252, 129, 129, 0))}.lg\:hover\:via-red-500:hover{--gradient-via-color:#f56565;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(245, 101, 101, 0))}.lg\:hover\:via-red-600:hover{--gradient-via-color:#e53e3e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(229, 62, 62, 0))}.lg\:hover\:via-red-700:hover{--gradient-via-color:#c53030;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(197, 48, 48, 0))}.lg\:hover\:via-red-800:hover{--gradient-via-color:#9b2c2c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(155, 44, 44, 0))}.lg\:hover\:via-red-900:hover{--gradient-via-color:#742a2a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(116, 42, 42, 0))}.lg\:hover\:via-orange-100:hover{--gradient-via-color:#fffaf0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 250, 240, 0))}.lg\:hover\:via-orange-200:hover{--gradient-via-color:#feebc8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(254, 235, 200, 0))}.lg\:hover\:via-orange-300:hover{--gradient-via-color:#fbd38d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(251, 211, 141, 0))}.lg\:hover\:via-orange-400:hover{--gradient-via-color:#f6ad55;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(246, 173, 85, 0))}.lg\:hover\:via-orange-500:hover{--gradient-via-color:#ed8936;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(237, 137, 54, 0))}.lg\:hover\:via-orange-600:hover{--gradient-via-color:#dd6b20;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(221, 107, 32, 0))}.lg\:hover\:via-orange-700:hover{--gradient-via-color:#c05621;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(192, 86, 33, 0))}.lg\:hover\:via-orange-800:hover{--gradient-via-color:#9c4221;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(156, 66, 33, 0))}.lg\:hover\:via-orange-900:hover{--gradient-via-color:#7b341e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(123, 52, 30, 0))}.lg\:hover\:via-yellow-100:hover{--gradient-via-color:#fffff0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 255, 240, 0))}.lg\:hover\:via-yellow-200:hover{--gradient-via-color:#fefcbf;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(254, 252, 191, 0))}.lg\:hover\:via-yellow-300:hover{--gradient-via-color:#faf089;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(250, 240, 137, 0))}.lg\:hover\:via-yellow-400:hover{--gradient-via-color:#f6e05e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(246, 224, 94, 0))}.lg\:hover\:via-yellow-500:hover{--gradient-via-color:#ecc94b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(236, 201, 75, 0))}.lg\:hover\:via-yellow-600:hover{--gradient-via-color:#d69e2e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(214, 158, 46, 0))}.lg\:hover\:via-yellow-700:hover{--gradient-via-color:#b7791f;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(183, 121, 31, 0))}.lg\:hover\:via-yellow-800:hover{--gradient-via-color:#975a16;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(151, 90, 22, 0))}.lg\:hover\:via-yellow-900:hover{--gradient-via-color:#744210;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(116, 66, 16, 0))}.lg\:hover\:via-green-100:hover{--gradient-via-color:#f0fff4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(240, 255, 244, 0))}.lg\:hover\:via-green-200:hover{--gradient-via-color:#c6f6d5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(198, 246, 213, 0))}.lg\:hover\:via-green-300:hover{--gradient-via-color:#9ae6b4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(154, 230, 180, 0))}.lg\:hover\:via-green-400:hover{--gradient-via-color:#68d391;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(104, 211, 145, 0))}.lg\:hover\:via-green-500:hover{--gradient-via-color:#48bb78;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(72, 187, 120, 0))}.lg\:hover\:via-green-600:hover{--gradient-via-color:#38a169;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(56, 161, 105, 0))}.lg\:hover\:via-green-700:hover{--gradient-via-color:#2f855a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(47, 133, 90, 0))}.lg\:hover\:via-green-800:hover{--gradient-via-color:#276749;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(39, 103, 73, 0))}.lg\:hover\:via-green-900:hover{--gradient-via-color:#22543d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(34, 84, 61, 0))}.lg\:hover\:via-teal-100:hover{--gradient-via-color:#e6fffa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(230, 255, 250, 0))}.lg\:hover\:via-teal-200:hover{--gradient-via-color:#b2f5ea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(178, 245, 234, 0))}.lg\:hover\:via-teal-300:hover{--gradient-via-color:#81e6d9;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(129, 230, 217, 0))}.lg\:hover\:via-teal-400:hover{--gradient-via-color:#4fd1c5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(79, 209, 197, 0))}.lg\:hover\:via-teal-500:hover{--gradient-via-color:#38b2ac;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(56, 178, 172, 0))}.lg\:hover\:via-teal-600:hover{--gradient-via-color:#319795;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(49, 151, 149, 0))}.lg\:hover\:via-teal-700:hover{--gradient-via-color:#2c7a7b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(44, 122, 123, 0))}.lg\:hover\:via-teal-800:hover{--gradient-via-color:#285e61;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(40, 94, 97, 0))}.lg\:hover\:via-teal-900:hover{--gradient-via-color:#234e52;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(35, 78, 82, 0))}.lg\:hover\:via-blue-100:hover{--gradient-via-color:#ebf8ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(235, 248, 255, 0))}.lg\:hover\:via-blue-200:hover{--gradient-via-color:#bee3f8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(190, 227, 248, 0))}.lg\:hover\:via-blue-300:hover{--gradient-via-color:#90cdf4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(144, 205, 244, 0))}.lg\:hover\:via-blue-400:hover{--gradient-via-color:#63b3ed;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(99, 179, 237, 0))}.lg\:hover\:via-blue-500:hover{--gradient-via-color:#4299e1;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(66, 153, 225, 0))}.lg\:hover\:via-blue-600:hover{--gradient-via-color:#3182ce;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(49, 130, 206, 0))}.lg\:hover\:via-blue-700:hover{--gradient-via-color:#2b6cb0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(43, 108, 176, 0))}.lg\:hover\:via-blue-800:hover{--gradient-via-color:#2c5282;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(44, 82, 130, 0))}.lg\:hover\:via-blue-900:hover{--gradient-via-color:#2a4365;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(42, 67, 101, 0))}.lg\:hover\:via-indigo-100:hover{--gradient-via-color:#ebf4ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(235, 244, 255, 0))}.lg\:hover\:via-indigo-200:hover{--gradient-via-color:#c3dafe;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(195, 218, 254, 0))}.lg\:hover\:via-indigo-300:hover{--gradient-via-color:#a3bffa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(163, 191, 250, 0))}.lg\:hover\:via-indigo-400:hover{--gradient-via-color:#7f9cf5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(127, 156, 245, 0))}.lg\:hover\:via-indigo-500:hover{--gradient-via-color:#667eea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(102, 126, 234, 0))}.lg\:hover\:via-indigo-600:hover{--gradient-via-color:#5a67d8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(90, 103, 216, 0))}.lg\:hover\:via-indigo-700:hover{--gradient-via-color:#4c51bf;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(76, 81, 191, 0))}.lg\:hover\:via-indigo-800:hover{--gradient-via-color:#434190;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(67, 65, 144, 0))}.lg\:hover\:via-indigo-900:hover{--gradient-via-color:#3c366b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(60, 54, 107, 0))}.lg\:hover\:via-purple-100:hover{--gradient-via-color:#faf5ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(250, 245, 255, 0))}.lg\:hover\:via-purple-200:hover{--gradient-via-color:#e9d8fd;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(233, 216, 253, 0))}.lg\:hover\:via-purple-300:hover{--gradient-via-color:#d6bcfa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(214, 188, 250, 0))}.lg\:hover\:via-purple-400:hover{--gradient-via-color:#b794f4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(183, 148, 244, 0))}.lg\:hover\:via-purple-500:hover{--gradient-via-color:#9f7aea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(159, 122, 234, 0))}.lg\:hover\:via-purple-600:hover{--gradient-via-color:#805ad5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(128, 90, 213, 0))}.lg\:hover\:via-purple-700:hover{--gradient-via-color:#6b46c1;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(107, 70, 193, 0))}.lg\:hover\:via-purple-800:hover{--gradient-via-color:#553c9a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(85, 60, 154, 0))}.lg\:hover\:via-purple-900:hover{--gradient-via-color:#44337a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(68, 51, 122, 0))}.lg\:hover\:via-pink-100:hover{--gradient-via-color:#fff5f7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 245, 247, 0))}.lg\:hover\:via-pink-200:hover{--gradient-via-color:#fed7e2;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(254, 215, 226, 0))}.lg\:hover\:via-pink-300:hover{--gradient-via-color:#fbb6ce;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(251, 182, 206, 0))}.lg\:hover\:via-pink-400:hover{--gradient-via-color:#f687b3;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(246, 135, 179, 0))}.lg\:hover\:via-pink-500:hover{--gradient-via-color:#ed64a6;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(237, 100, 166, 0))}.lg\:hover\:via-pink-600:hover{--gradient-via-color:#d53f8c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(213, 63, 140, 0))}.lg\:hover\:via-pink-700:hover{--gradient-via-color:#b83280;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(184, 50, 128, 0))}.lg\:hover\:via-pink-800:hover{--gradient-via-color:#97266d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(151, 38, 109, 0))}.lg\:hover\:via-pink-900:hover{--gradient-via-color:#702459;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(112, 36, 89, 0))}.lg\:hover\:to-transparent:hover{--gradient-to-color:transparent}.lg\:hover\:to-current:hover{--gradient-to-color:currentColor}.lg\:hover\:to-black:hover{--gradient-to-color:#000}.lg\:hover\:to-white:hover{--gradient-to-color:#fff}.lg\:hover\:to-gray-100:hover{--gradient-to-color:#f7fafc}.lg\:hover\:to-gray-200:hover{--gradient-to-color:#edf2f7}.lg\:hover\:to-gray-300:hover{--gradient-to-color:#e2e8f0}.lg\:hover\:to-gray-400:hover{--gradient-to-color:#cbd5e0}.lg\:hover\:to-gray-500:hover{--gradient-to-color:#a0aec0}.lg\:hover\:to-gray-600:hover{--gradient-to-color:#718096}.lg\:hover\:to-gray-700:hover{--gradient-to-color:#4a5568}.lg\:hover\:to-gray-800:hover{--gradient-to-color:#2d3748}.lg\:hover\:to-gray-900:hover{--gradient-to-color:#1a202c}.lg\:hover\:to-red-100:hover{--gradient-to-color:#fff5f5}.lg\:hover\:to-red-200:hover{--gradient-to-color:#fed7d7}.lg\:hover\:to-red-300:hover{--gradient-to-color:#feb2b2}.lg\:hover\:to-red-400:hover{--gradient-to-color:#fc8181}.lg\:hover\:to-red-500:hover{--gradient-to-color:#f56565}.lg\:hover\:to-red-600:hover{--gradient-to-color:#e53e3e}.lg\:hover\:to-red-700:hover{--gradient-to-color:#c53030}.lg\:hover\:to-red-800:hover{--gradient-to-color:#9b2c2c}.lg\:hover\:to-red-900:hover{--gradient-to-color:#742a2a}.lg\:hover\:to-orange-100:hover{--gradient-to-color:#fffaf0}.lg\:hover\:to-orange-200:hover{--gradient-to-color:#feebc8}.lg\:hover\:to-orange-300:hover{--gradient-to-color:#fbd38d}.lg\:hover\:to-orange-400:hover{--gradient-to-color:#f6ad55}.lg\:hover\:to-orange-500:hover{--gradient-to-color:#ed8936}.lg\:hover\:to-orange-600:hover{--gradient-to-color:#dd6b20}.lg\:hover\:to-orange-700:hover{--gradient-to-color:#c05621}.lg\:hover\:to-orange-800:hover{--gradient-to-color:#9c4221}.lg\:hover\:to-orange-900:hover{--gradient-to-color:#7b341e}.lg\:hover\:to-yellow-100:hover{--gradient-to-color:#fffff0}.lg\:hover\:to-yellow-200:hover{--gradient-to-color:#fefcbf}.lg\:hover\:to-yellow-300:hover{--gradient-to-color:#faf089}.lg\:hover\:to-yellow-400:hover{--gradient-to-color:#f6e05e}.lg\:hover\:to-yellow-500:hover{--gradient-to-color:#ecc94b}.lg\:hover\:to-yellow-600:hover{--gradient-to-color:#d69e2e}.lg\:hover\:to-yellow-700:hover{--gradient-to-color:#b7791f}.lg\:hover\:to-yellow-800:hover{--gradient-to-color:#975a16}.lg\:hover\:to-yellow-900:hover{--gradient-to-color:#744210}.lg\:hover\:to-green-100:hover{--gradient-to-color:#f0fff4}.lg\:hover\:to-green-200:hover{--gradient-to-color:#c6f6d5}.lg\:hover\:to-green-300:hover{--gradient-to-color:#9ae6b4}.lg\:hover\:to-green-400:hover{--gradient-to-color:#68d391}.lg\:hover\:to-green-500:hover{--gradient-to-color:#48bb78}.lg\:hover\:to-green-600:hover{--gradient-to-color:#38a169}.lg\:hover\:to-green-700:hover{--gradient-to-color:#2f855a}.lg\:hover\:to-green-800:hover{--gradient-to-color:#276749}.lg\:hover\:to-green-900:hover{--gradient-to-color:#22543d}.lg\:hover\:to-teal-100:hover{--gradient-to-color:#e6fffa}.lg\:hover\:to-teal-200:hover{--gradient-to-color:#b2f5ea}.lg\:hover\:to-teal-300:hover{--gradient-to-color:#81e6d9}.lg\:hover\:to-teal-400:hover{--gradient-to-color:#4fd1c5}.lg\:hover\:to-teal-500:hover{--gradient-to-color:#38b2ac}.lg\:hover\:to-teal-600:hover{--gradient-to-color:#319795}.lg\:hover\:to-teal-700:hover{--gradient-to-color:#2c7a7b}.lg\:hover\:to-teal-800:hover{--gradient-to-color:#285e61}.lg\:hover\:to-teal-900:hover{--gradient-to-color:#234e52}.lg\:hover\:to-blue-100:hover{--gradient-to-color:#ebf8ff}.lg\:hover\:to-blue-200:hover{--gradient-to-color:#bee3f8}.lg\:hover\:to-blue-300:hover{--gradient-to-color:#90cdf4}.lg\:hover\:to-blue-400:hover{--gradient-to-color:#63b3ed}.lg\:hover\:to-blue-500:hover{--gradient-to-color:#4299e1}.lg\:hover\:to-blue-600:hover{--gradient-to-color:#3182ce}.lg\:hover\:to-blue-700:hover{--gradient-to-color:#2b6cb0}.lg\:hover\:to-blue-800:hover{--gradient-to-color:#2c5282}.lg\:hover\:to-blue-900:hover{--gradient-to-color:#2a4365}.lg\:hover\:to-indigo-100:hover{--gradient-to-color:#ebf4ff}.lg\:hover\:to-indigo-200:hover{--gradient-to-color:#c3dafe}.lg\:hover\:to-indigo-300:hover{--gradient-to-color:#a3bffa}.lg\:hover\:to-indigo-400:hover{--gradient-to-color:#7f9cf5}.lg\:hover\:to-indigo-500:hover{--gradient-to-color:#667eea}.lg\:hover\:to-indigo-600:hover{--gradient-to-color:#5a67d8}.lg\:hover\:to-indigo-700:hover{--gradient-to-color:#4c51bf}.lg\:hover\:to-indigo-800:hover{--gradient-to-color:#434190}.lg\:hover\:to-indigo-900:hover{--gradient-to-color:#3c366b}.lg\:hover\:to-purple-100:hover{--gradient-to-color:#faf5ff}.lg\:hover\:to-purple-200:hover{--gradient-to-color:#e9d8fd}.lg\:hover\:to-purple-300:hover{--gradient-to-color:#d6bcfa}.lg\:hover\:to-purple-400:hover{--gradient-to-color:#b794f4}.lg\:hover\:to-purple-500:hover{--gradient-to-color:#9f7aea}.lg\:hover\:to-purple-600:hover{--gradient-to-color:#805ad5}.lg\:hover\:to-purple-700:hover{--gradient-to-color:#6b46c1}.lg\:hover\:to-purple-800:hover{--gradient-to-color:#553c9a}.lg\:hover\:to-purple-900:hover{--gradient-to-color:#44337a}.lg\:hover\:to-pink-100:hover{--gradient-to-color:#fff5f7}.lg\:hover\:to-pink-200:hover{--gradient-to-color:#fed7e2}.lg\:hover\:to-pink-300:hover{--gradient-to-color:#fbb6ce}.lg\:hover\:to-pink-400:hover{--gradient-to-color:#f687b3}.lg\:hover\:to-pink-500:hover{--gradient-to-color:#ed64a6}.lg\:hover\:to-pink-600:hover{--gradient-to-color:#d53f8c}.lg\:hover\:to-pink-700:hover{--gradient-to-color:#b83280}.lg\:hover\:to-pink-800:hover{--gradient-to-color:#97266d}.lg\:hover\:to-pink-900:hover{--gradient-to-color:#702459}.lg\:focus\:from-transparent:focus{--gradient-from-color:transparent;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(0, 0, 0, 0))}.lg\:focus\:from-current:focus{--gradient-from-color:currentColor;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 255, 255, 0))}.lg\:focus\:from-black:focus{--gradient-from-color:#000;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(0, 0, 0, 0))}.lg\:focus\:from-white:focus{--gradient-from-color:#fff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 255, 255, 0))}.lg\:focus\:from-gray-100:focus{--gradient-from-color:#f7fafc;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(247, 250, 252, 0))}.lg\:focus\:from-gray-200:focus{--gradient-from-color:#edf2f7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(237, 242, 247, 0))}.lg\:focus\:from-gray-300:focus{--gradient-from-color:#e2e8f0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(226, 232, 240, 0))}.lg\:focus\:from-gray-400:focus{--gradient-from-color:#cbd5e0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(203, 213, 224, 0))}.lg\:focus\:from-gray-500:focus{--gradient-from-color:#a0aec0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(160, 174, 192, 0))}.lg\:focus\:from-gray-600:focus{--gradient-from-color:#718096;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(113, 128, 150, 0))}.lg\:focus\:from-gray-700:focus{--gradient-from-color:#4a5568;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(74, 85, 104, 0))}.lg\:focus\:from-gray-800:focus{--gradient-from-color:#2d3748;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(45, 55, 72, 0))}.lg\:focus\:from-gray-900:focus{--gradient-from-color:#1a202c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(26, 32, 44, 0))}.lg\:focus\:from-red-100:focus{--gradient-from-color:#fff5f5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 245, 245, 0))}.lg\:focus\:from-red-200:focus{--gradient-from-color:#fed7d7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(254, 215, 215, 0))}.lg\:focus\:from-red-300:focus{--gradient-from-color:#feb2b2;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(254, 178, 178, 0))}.lg\:focus\:from-red-400:focus{--gradient-from-color:#fc8181;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(252, 129, 129, 0))}.lg\:focus\:from-red-500:focus{--gradient-from-color:#f56565;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(245, 101, 101, 0))}.lg\:focus\:from-red-600:focus{--gradient-from-color:#e53e3e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(229, 62, 62, 0))}.lg\:focus\:from-red-700:focus{--gradient-from-color:#c53030;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(197, 48, 48, 0))}.lg\:focus\:from-red-800:focus{--gradient-from-color:#9b2c2c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(155, 44, 44, 0))}.lg\:focus\:from-red-900:focus{--gradient-from-color:#742a2a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(116, 42, 42, 0))}.lg\:focus\:from-orange-100:focus{--gradient-from-color:#fffaf0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 250, 240, 0))}.lg\:focus\:from-orange-200:focus{--gradient-from-color:#feebc8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(254, 235, 200, 0))}.lg\:focus\:from-orange-300:focus{--gradient-from-color:#fbd38d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(251, 211, 141, 0))}.lg\:focus\:from-orange-400:focus{--gradient-from-color:#f6ad55;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(246, 173, 85, 0))}.lg\:focus\:from-orange-500:focus{--gradient-from-color:#ed8936;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(237, 137, 54, 0))}.lg\:focus\:from-orange-600:focus{--gradient-from-color:#dd6b20;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(221, 107, 32, 0))}.lg\:focus\:from-orange-700:focus{--gradient-from-color:#c05621;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(192, 86, 33, 0))}.lg\:focus\:from-orange-800:focus{--gradient-from-color:#9c4221;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(156, 66, 33, 0))}.lg\:focus\:from-orange-900:focus{--gradient-from-color:#7b341e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(123, 52, 30, 0))}.lg\:focus\:from-yellow-100:focus{--gradient-from-color:#fffff0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 255, 240, 0))}.lg\:focus\:from-yellow-200:focus{--gradient-from-color:#fefcbf;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(254, 252, 191, 0))}.lg\:focus\:from-yellow-300:focus{--gradient-from-color:#faf089;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(250, 240, 137, 0))}.lg\:focus\:from-yellow-400:focus{--gradient-from-color:#f6e05e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(246, 224, 94, 0))}.lg\:focus\:from-yellow-500:focus{--gradient-from-color:#ecc94b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(236, 201, 75, 0))}.lg\:focus\:from-yellow-600:focus{--gradient-from-color:#d69e2e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(214, 158, 46, 0))}.lg\:focus\:from-yellow-700:focus{--gradient-from-color:#b7791f;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(183, 121, 31, 0))}.lg\:focus\:from-yellow-800:focus{--gradient-from-color:#975a16;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(151, 90, 22, 0))}.lg\:focus\:from-yellow-900:focus{--gradient-from-color:#744210;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(116, 66, 16, 0))}.lg\:focus\:from-green-100:focus{--gradient-from-color:#f0fff4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(240, 255, 244, 0))}.lg\:focus\:from-green-200:focus{--gradient-from-color:#c6f6d5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(198, 246, 213, 0))}.lg\:focus\:from-green-300:focus{--gradient-from-color:#9ae6b4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(154, 230, 180, 0))}.lg\:focus\:from-green-400:focus{--gradient-from-color:#68d391;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(104, 211, 145, 0))}.lg\:focus\:from-green-500:focus{--gradient-from-color:#48bb78;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(72, 187, 120, 0))}.lg\:focus\:from-green-600:focus{--gradient-from-color:#38a169;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(56, 161, 105, 0))}.lg\:focus\:from-green-700:focus{--gradient-from-color:#2f855a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(47, 133, 90, 0))}.lg\:focus\:from-green-800:focus{--gradient-from-color:#276749;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(39, 103, 73, 0))}.lg\:focus\:from-green-900:focus{--gradient-from-color:#22543d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(34, 84, 61, 0))}.lg\:focus\:from-teal-100:focus{--gradient-from-color:#e6fffa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(230, 255, 250, 0))}.lg\:focus\:from-teal-200:focus{--gradient-from-color:#b2f5ea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(178, 245, 234, 0))}.lg\:focus\:from-teal-300:focus{--gradient-from-color:#81e6d9;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(129, 230, 217, 0))}.lg\:focus\:from-teal-400:focus{--gradient-from-color:#4fd1c5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(79, 209, 197, 0))}.lg\:focus\:from-teal-500:focus{--gradient-from-color:#38b2ac;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(56, 178, 172, 0))}.lg\:focus\:from-teal-600:focus{--gradient-from-color:#319795;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(49, 151, 149, 0))}.lg\:focus\:from-teal-700:focus{--gradient-from-color:#2c7a7b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(44, 122, 123, 0))}.lg\:focus\:from-teal-800:focus{--gradient-from-color:#285e61;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(40, 94, 97, 0))}.lg\:focus\:from-teal-900:focus{--gradient-from-color:#234e52;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(35, 78, 82, 0))}.lg\:focus\:from-blue-100:focus{--gradient-from-color:#ebf8ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(235, 248, 255, 0))}.lg\:focus\:from-blue-200:focus{--gradient-from-color:#bee3f8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(190, 227, 248, 0))}.lg\:focus\:from-blue-300:focus{--gradient-from-color:#90cdf4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(144, 205, 244, 0))}.lg\:focus\:from-blue-400:focus{--gradient-from-color:#63b3ed;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(99, 179, 237, 0))}.lg\:focus\:from-blue-500:focus{--gradient-from-color:#4299e1;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(66, 153, 225, 0))}.lg\:focus\:from-blue-600:focus{--gradient-from-color:#3182ce;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(49, 130, 206, 0))}.lg\:focus\:from-blue-700:focus{--gradient-from-color:#2b6cb0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(43, 108, 176, 0))}.lg\:focus\:from-blue-800:focus{--gradient-from-color:#2c5282;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(44, 82, 130, 0))}.lg\:focus\:from-blue-900:focus{--gradient-from-color:#2a4365;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(42, 67, 101, 0))}.lg\:focus\:from-indigo-100:focus{--gradient-from-color:#ebf4ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(235, 244, 255, 0))}.lg\:focus\:from-indigo-200:focus{--gradient-from-color:#c3dafe;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(195, 218, 254, 0))}.lg\:focus\:from-indigo-300:focus{--gradient-from-color:#a3bffa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(163, 191, 250, 0))}.lg\:focus\:from-indigo-400:focus{--gradient-from-color:#7f9cf5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(127, 156, 245, 0))}.lg\:focus\:from-indigo-500:focus{--gradient-from-color:#667eea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(102, 126, 234, 0))}.lg\:focus\:from-indigo-600:focus{--gradient-from-color:#5a67d8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(90, 103, 216, 0))}.lg\:focus\:from-indigo-700:focus{--gradient-from-color:#4c51bf;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(76, 81, 191, 0))}.lg\:focus\:from-indigo-800:focus{--gradient-from-color:#434190;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(67, 65, 144, 0))}.lg\:focus\:from-indigo-900:focus{--gradient-from-color:#3c366b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(60, 54, 107, 0))}.lg\:focus\:from-purple-100:focus{--gradient-from-color:#faf5ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(250, 245, 255, 0))}.lg\:focus\:from-purple-200:focus{--gradient-from-color:#e9d8fd;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(233, 216, 253, 0))}.lg\:focus\:from-purple-300:focus{--gradient-from-color:#d6bcfa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(214, 188, 250, 0))}.lg\:focus\:from-purple-400:focus{--gradient-from-color:#b794f4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(183, 148, 244, 0))}.lg\:focus\:from-purple-500:focus{--gradient-from-color:#9f7aea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(159, 122, 234, 0))}.lg\:focus\:from-purple-600:focus{--gradient-from-color:#805ad5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(128, 90, 213, 0))}.lg\:focus\:from-purple-700:focus{--gradient-from-color:#6b46c1;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(107, 70, 193, 0))}.lg\:focus\:from-purple-800:focus{--gradient-from-color:#553c9a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(85, 60, 154, 0))}.lg\:focus\:from-purple-900:focus{--gradient-from-color:#44337a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(68, 51, 122, 0))}.lg\:focus\:from-pink-100:focus{--gradient-from-color:#fff5f7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 245, 247, 0))}.lg\:focus\:from-pink-200:focus{--gradient-from-color:#fed7e2;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(254, 215, 226, 0))}.lg\:focus\:from-pink-300:focus{--gradient-from-color:#fbb6ce;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(251, 182, 206, 0))}.lg\:focus\:from-pink-400:focus{--gradient-from-color:#f687b3;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(246, 135, 179, 0))}.lg\:focus\:from-pink-500:focus{--gradient-from-color:#ed64a6;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(237, 100, 166, 0))}.lg\:focus\:from-pink-600:focus{--gradient-from-color:#d53f8c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(213, 63, 140, 0))}.lg\:focus\:from-pink-700:focus{--gradient-from-color:#b83280;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(184, 50, 128, 0))}.lg\:focus\:from-pink-800:focus{--gradient-from-color:#97266d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(151, 38, 109, 0))}.lg\:focus\:from-pink-900:focus{--gradient-from-color:#702459;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(112, 36, 89, 0))}.lg\:focus\:via-transparent:focus{--gradient-via-color:transparent;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(0, 0, 0, 0))}.lg\:focus\:via-current:focus{--gradient-via-color:currentColor;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 255, 255, 0))}.lg\:focus\:via-black:focus{--gradient-via-color:#000;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(0, 0, 0, 0))}.lg\:focus\:via-white:focus{--gradient-via-color:#fff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 255, 255, 0))}.lg\:focus\:via-gray-100:focus{--gradient-via-color:#f7fafc;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(247, 250, 252, 0))}.lg\:focus\:via-gray-200:focus{--gradient-via-color:#edf2f7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(237, 242, 247, 0))}.lg\:focus\:via-gray-300:focus{--gradient-via-color:#e2e8f0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(226, 232, 240, 0))}.lg\:focus\:via-gray-400:focus{--gradient-via-color:#cbd5e0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(203, 213, 224, 0))}.lg\:focus\:via-gray-500:focus{--gradient-via-color:#a0aec0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(160, 174, 192, 0))}.lg\:focus\:via-gray-600:focus{--gradient-via-color:#718096;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(113, 128, 150, 0))}.lg\:focus\:via-gray-700:focus{--gradient-via-color:#4a5568;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(74, 85, 104, 0))}.lg\:focus\:via-gray-800:focus{--gradient-via-color:#2d3748;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(45, 55, 72, 0))}.lg\:focus\:via-gray-900:focus{--gradient-via-color:#1a202c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(26, 32, 44, 0))}.lg\:focus\:via-red-100:focus{--gradient-via-color:#fff5f5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 245, 245, 0))}.lg\:focus\:via-red-200:focus{--gradient-via-color:#fed7d7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(254, 215, 215, 0))}.lg\:focus\:via-red-300:focus{--gradient-via-color:#feb2b2;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(254, 178, 178, 0))}.lg\:focus\:via-red-400:focus{--gradient-via-color:#fc8181;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(252, 129, 129, 0))}.lg\:focus\:via-red-500:focus{--gradient-via-color:#f56565;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(245, 101, 101, 0))}.lg\:focus\:via-red-600:focus{--gradient-via-color:#e53e3e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(229, 62, 62, 0))}.lg\:focus\:via-red-700:focus{--gradient-via-color:#c53030;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(197, 48, 48, 0))}.lg\:focus\:via-red-800:focus{--gradient-via-color:#9b2c2c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(155, 44, 44, 0))}.lg\:focus\:via-red-900:focus{--gradient-via-color:#742a2a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(116, 42, 42, 0))}.lg\:focus\:via-orange-100:focus{--gradient-via-color:#fffaf0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 250, 240, 0))}.lg\:focus\:via-orange-200:focus{--gradient-via-color:#feebc8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(254, 235, 200, 0))}.lg\:focus\:via-orange-300:focus{--gradient-via-color:#fbd38d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(251, 211, 141, 0))}.lg\:focus\:via-orange-400:focus{--gradient-via-color:#f6ad55;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(246, 173, 85, 0))}.lg\:focus\:via-orange-500:focus{--gradient-via-color:#ed8936;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(237, 137, 54, 0))}.lg\:focus\:via-orange-600:focus{--gradient-via-color:#dd6b20;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(221, 107, 32, 0))}.lg\:focus\:via-orange-700:focus{--gradient-via-color:#c05621;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(192, 86, 33, 0))}.lg\:focus\:via-orange-800:focus{--gradient-via-color:#9c4221;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(156, 66, 33, 0))}.lg\:focus\:via-orange-900:focus{--gradient-via-color:#7b341e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(123, 52, 30, 0))}.lg\:focus\:via-yellow-100:focus{--gradient-via-color:#fffff0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 255, 240, 0))}.lg\:focus\:via-yellow-200:focus{--gradient-via-color:#fefcbf;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(254, 252, 191, 0))}.lg\:focus\:via-yellow-300:focus{--gradient-via-color:#faf089;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(250, 240, 137, 0))}.lg\:focus\:via-yellow-400:focus{--gradient-via-color:#f6e05e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(246, 224, 94, 0))}.lg\:focus\:via-yellow-500:focus{--gradient-via-color:#ecc94b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(236, 201, 75, 0))}.lg\:focus\:via-yellow-600:focus{--gradient-via-color:#d69e2e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(214, 158, 46, 0))}.lg\:focus\:via-yellow-700:focus{--gradient-via-color:#b7791f;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(183, 121, 31, 0))}.lg\:focus\:via-yellow-800:focus{--gradient-via-color:#975a16;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(151, 90, 22, 0))}.lg\:focus\:via-yellow-900:focus{--gradient-via-color:#744210;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(116, 66, 16, 0))}.lg\:focus\:via-green-100:focus{--gradient-via-color:#f0fff4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(240, 255, 244, 0))}.lg\:focus\:via-green-200:focus{--gradient-via-color:#c6f6d5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(198, 246, 213, 0))}.lg\:focus\:via-green-300:focus{--gradient-via-color:#9ae6b4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(154, 230, 180, 0))}.lg\:focus\:via-green-400:focus{--gradient-via-color:#68d391;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(104, 211, 145, 0))}.lg\:focus\:via-green-500:focus{--gradient-via-color:#48bb78;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(72, 187, 120, 0))}.lg\:focus\:via-green-600:focus{--gradient-via-color:#38a169;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(56, 161, 105, 0))}.lg\:focus\:via-green-700:focus{--gradient-via-color:#2f855a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(47, 133, 90, 0))}.lg\:focus\:via-green-800:focus{--gradient-via-color:#276749;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(39, 103, 73, 0))}.lg\:focus\:via-green-900:focus{--gradient-via-color:#22543d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(34, 84, 61, 0))}.lg\:focus\:via-teal-100:focus{--gradient-via-color:#e6fffa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(230, 255, 250, 0))}.lg\:focus\:via-teal-200:focus{--gradient-via-color:#b2f5ea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(178, 245, 234, 0))}.lg\:focus\:via-teal-300:focus{--gradient-via-color:#81e6d9;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(129, 230, 217, 0))}.lg\:focus\:via-teal-400:focus{--gradient-via-color:#4fd1c5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(79, 209, 197, 0))}.lg\:focus\:via-teal-500:focus{--gradient-via-color:#38b2ac;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(56, 178, 172, 0))}.lg\:focus\:via-teal-600:focus{--gradient-via-color:#319795;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(49, 151, 149, 0))}.lg\:focus\:via-teal-700:focus{--gradient-via-color:#2c7a7b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(44, 122, 123, 0))}.lg\:focus\:via-teal-800:focus{--gradient-via-color:#285e61;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(40, 94, 97, 0))}.lg\:focus\:via-teal-900:focus{--gradient-via-color:#234e52;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(35, 78, 82, 0))}.lg\:focus\:via-blue-100:focus{--gradient-via-color:#ebf8ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(235, 248, 255, 0))}.lg\:focus\:via-blue-200:focus{--gradient-via-color:#bee3f8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(190, 227, 248, 0))}.lg\:focus\:via-blue-300:focus{--gradient-via-color:#90cdf4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(144, 205, 244, 0))}.lg\:focus\:via-blue-400:focus{--gradient-via-color:#63b3ed;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(99, 179, 237, 0))}.lg\:focus\:via-blue-500:focus{--gradient-via-color:#4299e1;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(66, 153, 225, 0))}.lg\:focus\:via-blue-600:focus{--gradient-via-color:#3182ce;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(49, 130, 206, 0))}.lg\:focus\:via-blue-700:focus{--gradient-via-color:#2b6cb0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(43, 108, 176, 0))}.lg\:focus\:via-blue-800:focus{--gradient-via-color:#2c5282;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(44, 82, 130, 0))}.lg\:focus\:via-blue-900:focus{--gradient-via-color:#2a4365;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(42, 67, 101, 0))}.lg\:focus\:via-indigo-100:focus{--gradient-via-color:#ebf4ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(235, 244, 255, 0))}.lg\:focus\:via-indigo-200:focus{--gradient-via-color:#c3dafe;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(195, 218, 254, 0))}.lg\:focus\:via-indigo-300:focus{--gradient-via-color:#a3bffa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(163, 191, 250, 0))}.lg\:focus\:via-indigo-400:focus{--gradient-via-color:#7f9cf5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(127, 156, 245, 0))}.lg\:focus\:via-indigo-500:focus{--gradient-via-color:#667eea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(102, 126, 234, 0))}.lg\:focus\:via-indigo-600:focus{--gradient-via-color:#5a67d8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(90, 103, 216, 0))}.lg\:focus\:via-indigo-700:focus{--gradient-via-color:#4c51bf;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(76, 81, 191, 0))}.lg\:focus\:via-indigo-800:focus{--gradient-via-color:#434190;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(67, 65, 144, 0))}.lg\:focus\:via-indigo-900:focus{--gradient-via-color:#3c366b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(60, 54, 107, 0))}.lg\:focus\:via-purple-100:focus{--gradient-via-color:#faf5ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(250, 245, 255, 0))}.lg\:focus\:via-purple-200:focus{--gradient-via-color:#e9d8fd;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(233, 216, 253, 0))}.lg\:focus\:via-purple-300:focus{--gradient-via-color:#d6bcfa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(214, 188, 250, 0))}.lg\:focus\:via-purple-400:focus{--gradient-via-color:#b794f4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(183, 148, 244, 0))}.lg\:focus\:via-purple-500:focus{--gradient-via-color:#9f7aea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(159, 122, 234, 0))}.lg\:focus\:via-purple-600:focus{--gradient-via-color:#805ad5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(128, 90, 213, 0))}.lg\:focus\:via-purple-700:focus{--gradient-via-color:#6b46c1;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(107, 70, 193, 0))}.lg\:focus\:via-purple-800:focus{--gradient-via-color:#553c9a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(85, 60, 154, 0))}.lg\:focus\:via-purple-900:focus{--gradient-via-color:#44337a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(68, 51, 122, 0))}.lg\:focus\:via-pink-100:focus{--gradient-via-color:#fff5f7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 245, 247, 0))}.lg\:focus\:via-pink-200:focus{--gradient-via-color:#fed7e2;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(254, 215, 226, 0))}.lg\:focus\:via-pink-300:focus{--gradient-via-color:#fbb6ce;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(251, 182, 206, 0))}.lg\:focus\:via-pink-400:focus{--gradient-via-color:#f687b3;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(246, 135, 179, 0))}.lg\:focus\:via-pink-500:focus{--gradient-via-color:#ed64a6;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(237, 100, 166, 0))}.lg\:focus\:via-pink-600:focus{--gradient-via-color:#d53f8c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(213, 63, 140, 0))}.lg\:focus\:via-pink-700:focus{--gradient-via-color:#b83280;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(184, 50, 128, 0))}.lg\:focus\:via-pink-800:focus{--gradient-via-color:#97266d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(151, 38, 109, 0))}.lg\:focus\:via-pink-900:focus{--gradient-via-color:#702459;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(112, 36, 89, 0))}.lg\:focus\:to-transparent:focus{--gradient-to-color:transparent}.lg\:focus\:to-current:focus{--gradient-to-color:currentColor}.lg\:focus\:to-black:focus{--gradient-to-color:#000}.lg\:focus\:to-white:focus{--gradient-to-color:#fff}.lg\:focus\:to-gray-100:focus{--gradient-to-color:#f7fafc}.lg\:focus\:to-gray-200:focus{--gradient-to-color:#edf2f7}.lg\:focus\:to-gray-300:focus{--gradient-to-color:#e2e8f0}.lg\:focus\:to-gray-400:focus{--gradient-to-color:#cbd5e0}.lg\:focus\:to-gray-500:focus{--gradient-to-color:#a0aec0}.lg\:focus\:to-gray-600:focus{--gradient-to-color:#718096}.lg\:focus\:to-gray-700:focus{--gradient-to-color:#4a5568}.lg\:focus\:to-gray-800:focus{--gradient-to-color:#2d3748}.lg\:focus\:to-gray-900:focus{--gradient-to-color:#1a202c}.lg\:focus\:to-red-100:focus{--gradient-to-color:#fff5f5}.lg\:focus\:to-red-200:focus{--gradient-to-color:#fed7d7}.lg\:focus\:to-red-300:focus{--gradient-to-color:#feb2b2}.lg\:focus\:to-red-400:focus{--gradient-to-color:#fc8181}.lg\:focus\:to-red-500:focus{--gradient-to-color:#f56565}.lg\:focus\:to-red-600:focus{--gradient-to-color:#e53e3e}.lg\:focus\:to-red-700:focus{--gradient-to-color:#c53030}.lg\:focus\:to-red-800:focus{--gradient-to-color:#9b2c2c}.lg\:focus\:to-red-900:focus{--gradient-to-color:#742a2a}.lg\:focus\:to-orange-100:focus{--gradient-to-color:#fffaf0}.lg\:focus\:to-orange-200:focus{--gradient-to-color:#feebc8}.lg\:focus\:to-orange-300:focus{--gradient-to-color:#fbd38d}.lg\:focus\:to-orange-400:focus{--gradient-to-color:#f6ad55}.lg\:focus\:to-orange-500:focus{--gradient-to-color:#ed8936}.lg\:focus\:to-orange-600:focus{--gradient-to-color:#dd6b20}.lg\:focus\:to-orange-700:focus{--gradient-to-color:#c05621}.lg\:focus\:to-orange-800:focus{--gradient-to-color:#9c4221}.lg\:focus\:to-orange-900:focus{--gradient-to-color:#7b341e}.lg\:focus\:to-yellow-100:focus{--gradient-to-color:#fffff0}.lg\:focus\:to-yellow-200:focus{--gradient-to-color:#fefcbf}.lg\:focus\:to-yellow-300:focus{--gradient-to-color:#faf089}.lg\:focus\:to-yellow-400:focus{--gradient-to-color:#f6e05e}.lg\:focus\:to-yellow-500:focus{--gradient-to-color:#ecc94b}.lg\:focus\:to-yellow-600:focus{--gradient-to-color:#d69e2e}.lg\:focus\:to-yellow-700:focus{--gradient-to-color:#b7791f}.lg\:focus\:to-yellow-800:focus{--gradient-to-color:#975a16}.lg\:focus\:to-yellow-900:focus{--gradient-to-color:#744210}.lg\:focus\:to-green-100:focus{--gradient-to-color:#f0fff4}.lg\:focus\:to-green-200:focus{--gradient-to-color:#c6f6d5}.lg\:focus\:to-green-300:focus{--gradient-to-color:#9ae6b4}.lg\:focus\:to-green-400:focus{--gradient-to-color:#68d391}.lg\:focus\:to-green-500:focus{--gradient-to-color:#48bb78}.lg\:focus\:to-green-600:focus{--gradient-to-color:#38a169}.lg\:focus\:to-green-700:focus{--gradient-to-color:#2f855a}.lg\:focus\:to-green-800:focus{--gradient-to-color:#276749}.lg\:focus\:to-green-900:focus{--gradient-to-color:#22543d}.lg\:focus\:to-teal-100:focus{--gradient-to-color:#e6fffa}.lg\:focus\:to-teal-200:focus{--gradient-to-color:#b2f5ea}.lg\:focus\:to-teal-300:focus{--gradient-to-color:#81e6d9}.lg\:focus\:to-teal-400:focus{--gradient-to-color:#4fd1c5}.lg\:focus\:to-teal-500:focus{--gradient-to-color:#38b2ac}.lg\:focus\:to-teal-600:focus{--gradient-to-color:#319795}.lg\:focus\:to-teal-700:focus{--gradient-to-color:#2c7a7b}.lg\:focus\:to-teal-800:focus{--gradient-to-color:#285e61}.lg\:focus\:to-teal-900:focus{--gradient-to-color:#234e52}.lg\:focus\:to-blue-100:focus{--gradient-to-color:#ebf8ff}.lg\:focus\:to-blue-200:focus{--gradient-to-color:#bee3f8}.lg\:focus\:to-blue-300:focus{--gradient-to-color:#90cdf4}.lg\:focus\:to-blue-400:focus{--gradient-to-color:#63b3ed}.lg\:focus\:to-blue-500:focus{--gradient-to-color:#4299e1}.lg\:focus\:to-blue-600:focus{--gradient-to-color:#3182ce}.lg\:focus\:to-blue-700:focus{--gradient-to-color:#2b6cb0}.lg\:focus\:to-blue-800:focus{--gradient-to-color:#2c5282}.lg\:focus\:to-blue-900:focus{--gradient-to-color:#2a4365}.lg\:focus\:to-indigo-100:focus{--gradient-to-color:#ebf4ff}.lg\:focus\:to-indigo-200:focus{--gradient-to-color:#c3dafe}.lg\:focus\:to-indigo-300:focus{--gradient-to-color:#a3bffa}.lg\:focus\:to-indigo-400:focus{--gradient-to-color:#7f9cf5}.lg\:focus\:to-indigo-500:focus{--gradient-to-color:#667eea}.lg\:focus\:to-indigo-600:focus{--gradient-to-color:#5a67d8}.lg\:focus\:to-indigo-700:focus{--gradient-to-color:#4c51bf}.lg\:focus\:to-indigo-800:focus{--gradient-to-color:#434190}.lg\:focus\:to-indigo-900:focus{--gradient-to-color:#3c366b}.lg\:focus\:to-purple-100:focus{--gradient-to-color:#faf5ff}.lg\:focus\:to-purple-200:focus{--gradient-to-color:#e9d8fd}.lg\:focus\:to-purple-300:focus{--gradient-to-color:#d6bcfa}.lg\:focus\:to-purple-400:focus{--gradient-to-color:#b794f4}.lg\:focus\:to-purple-500:focus{--gradient-to-color:#9f7aea}.lg\:focus\:to-purple-600:focus{--gradient-to-color:#805ad5}.lg\:focus\:to-purple-700:focus{--gradient-to-color:#6b46c1}.lg\:focus\:to-purple-800:focus{--gradient-to-color:#553c9a}.lg\:focus\:to-purple-900:focus{--gradient-to-color:#44337a}.lg\:focus\:to-pink-100:focus{--gradient-to-color:#fff5f7}.lg\:focus\:to-pink-200:focus{--gradient-to-color:#fed7e2}.lg\:focus\:to-pink-300:focus{--gradient-to-color:#fbb6ce}.lg\:focus\:to-pink-400:focus{--gradient-to-color:#f687b3}.lg\:focus\:to-pink-500:focus{--gradient-to-color:#ed64a6}.lg\:focus\:to-pink-600:focus{--gradient-to-color:#d53f8c}.lg\:focus\:to-pink-700:focus{--gradient-to-color:#b83280}.lg\:focus\:to-pink-800:focus{--gradient-to-color:#97266d}.lg\:focus\:to-pink-900:focus{--gradient-to-color:#702459}.lg\:bg-opacity-0{--bg-opacity:0}.lg\:bg-opacity-25{--bg-opacity:0.25}.lg\:bg-opacity-50{--bg-opacity:0.5}.lg\:bg-opacity-75{--bg-opacity:0.75}.lg\:bg-opacity-100{--bg-opacity:1}.lg\:hover\:bg-opacity-0:hover{--bg-opacity:0}.lg\:hover\:bg-opacity-25:hover{--bg-opacity:0.25}.lg\:hover\:bg-opacity-50:hover{--bg-opacity:0.5}.lg\:hover\:bg-opacity-75:hover{--bg-opacity:0.75}.lg\:hover\:bg-opacity-100:hover{--bg-opacity:1}.lg\:focus\:bg-opacity-0:focus{--bg-opacity:0}.lg\:focus\:bg-opacity-25:focus{--bg-opacity:0.25}.lg\:focus\:bg-opacity-50:focus{--bg-opacity:0.5}.lg\:focus\:bg-opacity-75:focus{--bg-opacity:0.75}.lg\:focus\:bg-opacity-100:focus{--bg-opacity:1}.lg\:bg-bottom{background-position:bottom}.lg\:bg-center{background-position:center}.lg\:bg-left{background-position:left}.lg\:bg-left-bottom{background-position:left bottom}.lg\:bg-left-top{background-position:left top}.lg\:bg-right{background-position:right}.lg\:bg-right-bottom{background-position:right bottom}.lg\:bg-right-top{background-position:right top}.lg\:bg-top{background-position:top}.lg\:bg-repeat{background-repeat:repeat}.lg\:bg-no-repeat{background-repeat:no-repeat}.lg\:bg-repeat-x{background-repeat:repeat-x}.lg\:bg-repeat-y{background-repeat:repeat-y}.lg\:bg-repeat-round{background-repeat:round}.lg\:bg-repeat-space{background-repeat:space}.lg\:bg-auto{background-size:auto}.lg\:bg-cover{background-size:cover}.lg\:bg-contain{background-size:contain}.lg\:border-collapse{border-collapse:collapse}.lg\:border-separate{border-collapse:separate}.lg\:border-transparent{border-color:transparent}.lg\:border-current{border-color:currentColor}.lg\:border-black{--border-opacity:1;border-color:#000;border-color:rgba(0,0,0,var(--border-opacity))}.lg\:border-white{--border-opacity:1;border-color:#fff;border-color:rgba(255,255,255,var(--border-opacity))}.lg\:border-gray-100{--border-opacity:1;border-color:#f7fafc;border-color:rgba(247,250,252,var(--border-opacity))}.lg\:border-gray-200{--border-opacity:1;border-color:#edf2f7;border-color:rgba(237,242,247,var(--border-opacity))}.lg\:border-gray-300{--border-opacity:1;border-color:#e2e8f0;border-color:rgba(226,232,240,var(--border-opacity))}.lg\:border-gray-400{--border-opacity:1;border-color:#cbd5e0;border-color:rgba(203,213,224,var(--border-opacity))}.lg\:border-gray-500{--border-opacity:1;border-color:#a0aec0;border-color:rgba(160,174,192,var(--border-opacity))}.lg\:border-gray-600{--border-opacity:1;border-color:#718096;border-color:rgba(113,128,150,var(--border-opacity))}.lg\:border-gray-700{--border-opacity:1;border-color:#4a5568;border-color:rgba(74,85,104,var(--border-opacity))}.lg\:border-gray-800{--border-opacity:1;border-color:#2d3748;border-color:rgba(45,55,72,var(--border-opacity))}.lg\:border-gray-900{--border-opacity:1;border-color:#1a202c;border-color:rgba(26,32,44,var(--border-opacity))}.lg\:border-red-100{--border-opacity:1;border-color:#fff5f5;border-color:rgba(255,245,245,var(--border-opacity))}.lg\:border-red-200{--border-opacity:1;border-color:#fed7d7;border-color:rgba(254,215,215,var(--border-opacity))}.lg\:border-red-300{--border-opacity:1;border-color:#feb2b2;border-color:rgba(254,178,178,var(--border-opacity))}.lg\:border-red-400{--border-opacity:1;border-color:#fc8181;border-color:rgba(252,129,129,var(--border-opacity))}.lg\:border-red-500{--border-opacity:1;border-color:#f56565;border-color:rgba(245,101,101,var(--border-opacity))}.lg\:border-red-600{--border-opacity:1;border-color:#e53e3e;border-color:rgba(229,62,62,var(--border-opacity))}.lg\:border-red-700{--border-opacity:1;border-color:#c53030;border-color:rgba(197,48,48,var(--border-opacity))}.lg\:border-red-800{--border-opacity:1;border-color:#9b2c2c;border-color:rgba(155,44,44,var(--border-opacity))}.lg\:border-red-900{--border-opacity:1;border-color:#742a2a;border-color:rgba(116,42,42,var(--border-opacity))}.lg\:border-orange-100{--border-opacity:1;border-color:#fffaf0;border-color:rgba(255,250,240,var(--border-opacity))}.lg\:border-orange-200{--border-opacity:1;border-color:#feebc8;border-color:rgba(254,235,200,var(--border-opacity))}.lg\:border-orange-300{--border-opacity:1;border-color:#fbd38d;border-color:rgba(251,211,141,var(--border-opacity))}.lg\:border-orange-400{--border-opacity:1;border-color:#f6ad55;border-color:rgba(246,173,85,var(--border-opacity))}.lg\:border-orange-500{--border-opacity:1;border-color:#ed8936;border-color:rgba(237,137,54,var(--border-opacity))}.lg\:border-orange-600{--border-opacity:1;border-color:#dd6b20;border-color:rgba(221,107,32,var(--border-opacity))}.lg\:border-orange-700{--border-opacity:1;border-color:#c05621;border-color:rgba(192,86,33,var(--border-opacity))}.lg\:border-orange-800{--border-opacity:1;border-color:#9c4221;border-color:rgba(156,66,33,var(--border-opacity))}.lg\:border-orange-900{--border-opacity:1;border-color:#7b341e;border-color:rgba(123,52,30,var(--border-opacity))}.lg\:border-yellow-100{--border-opacity:1;border-color:ivory;border-color:rgba(255,255,240,var(--border-opacity))}.lg\:border-yellow-200{--border-opacity:1;border-color:#fefcbf;border-color:rgba(254,252,191,var(--border-opacity))}.lg\:border-yellow-300{--border-opacity:1;border-color:#faf089;border-color:rgba(250,240,137,var(--border-opacity))}.lg\:border-yellow-400{--border-opacity:1;border-color:#f6e05e;border-color:rgba(246,224,94,var(--border-opacity))}.lg\:border-yellow-500{--border-opacity:1;border-color:#ecc94b;border-color:rgba(236,201,75,var(--border-opacity))}.lg\:border-yellow-600{--border-opacity:1;border-color:#d69e2e;border-color:rgba(214,158,46,var(--border-opacity))}.lg\:border-yellow-700{--border-opacity:1;border-color:#b7791f;border-color:rgba(183,121,31,var(--border-opacity))}.lg\:border-yellow-800{--border-opacity:1;border-color:#975a16;border-color:rgba(151,90,22,var(--border-opacity))}.lg\:border-yellow-900{--border-opacity:1;border-color:#744210;border-color:rgba(116,66,16,var(--border-opacity))}.lg\:border-green-100{--border-opacity:1;border-color:#f0fff4;border-color:rgba(240,255,244,var(--border-opacity))}.lg\:border-green-200{--border-opacity:1;border-color:#c6f6d5;border-color:rgba(198,246,213,var(--border-opacity))}.lg\:border-green-300{--border-opacity:1;border-color:#9ae6b4;border-color:rgba(154,230,180,var(--border-opacity))}.lg\:border-green-400{--border-opacity:1;border-color:#68d391;border-color:rgba(104,211,145,var(--border-opacity))}.lg\:border-green-500{--border-opacity:1;border-color:#48bb78;border-color:rgba(72,187,120,var(--border-opacity))}.lg\:border-green-600{--border-opacity:1;border-color:#38a169;border-color:rgba(56,161,105,var(--border-opacity))}.lg\:border-green-700{--border-opacity:1;border-color:#2f855a;border-color:rgba(47,133,90,var(--border-opacity))}.lg\:border-green-800{--border-opacity:1;border-color:#276749;border-color:rgba(39,103,73,var(--border-opacity))}.lg\:border-green-900{--border-opacity:1;border-color:#22543d;border-color:rgba(34,84,61,var(--border-opacity))}.lg\:border-teal-100{--border-opacity:1;border-color:#e6fffa;border-color:rgba(230,255,250,var(--border-opacity))}.lg\:border-teal-200{--border-opacity:1;border-color:#b2f5ea;border-color:rgba(178,245,234,var(--border-opacity))}.lg\:border-teal-300{--border-opacity:1;border-color:#81e6d9;border-color:rgba(129,230,217,var(--border-opacity))}.lg\:border-teal-400{--border-opacity:1;border-color:#4fd1c5;border-color:rgba(79,209,197,var(--border-opacity))}.lg\:border-teal-500{--border-opacity:1;border-color:#38b2ac;border-color:rgba(56,178,172,var(--border-opacity))}.lg\:border-teal-600{--border-opacity:1;border-color:#319795;border-color:rgba(49,151,149,var(--border-opacity))}.lg\:border-teal-700{--border-opacity:1;border-color:#2c7a7b;border-color:rgba(44,122,123,var(--border-opacity))}.lg\:border-teal-800{--border-opacity:1;border-color:#285e61;border-color:rgba(40,94,97,var(--border-opacity))}.lg\:border-teal-900{--border-opacity:1;border-color:#234e52;border-color:rgba(35,78,82,var(--border-opacity))}.lg\:border-blue-100{--border-opacity:1;border-color:#ebf8ff;border-color:rgba(235,248,255,var(--border-opacity))}.lg\:border-blue-200{--border-opacity:1;border-color:#bee3f8;border-color:rgba(190,227,248,var(--border-opacity))}.lg\:border-blue-300{--border-opacity:1;border-color:#90cdf4;border-color:rgba(144,205,244,var(--border-opacity))}.lg\:border-blue-400{--border-opacity:1;border-color:#63b3ed;border-color:rgba(99,179,237,var(--border-opacity))}.lg\:border-blue-500{--border-opacity:1;border-color:#4299e1;border-color:rgba(66,153,225,var(--border-opacity))}.lg\:border-blue-600{--border-opacity:1;border-color:#3182ce;border-color:rgba(49,130,206,var(--border-opacity))}.lg\:border-blue-700{--border-opacity:1;border-color:#2b6cb0;border-color:rgba(43,108,176,var(--border-opacity))}.lg\:border-blue-800{--border-opacity:1;border-color:#2c5282;border-color:rgba(44,82,130,var(--border-opacity))}.lg\:border-blue-900{--border-opacity:1;border-color:#2a4365;border-color:rgba(42,67,101,var(--border-opacity))}.lg\:border-indigo-100{--border-opacity:1;border-color:#ebf4ff;border-color:rgba(235,244,255,var(--border-opacity))}.lg\:border-indigo-200{--border-opacity:1;border-color:#c3dafe;border-color:rgba(195,218,254,var(--border-opacity))}.lg\:border-indigo-300{--border-opacity:1;border-color:#a3bffa;border-color:rgba(163,191,250,var(--border-opacity))}.lg\:border-indigo-400{--border-opacity:1;border-color:#7f9cf5;border-color:rgba(127,156,245,var(--border-opacity))}.lg\:border-indigo-500{--border-opacity:1;border-color:#667eea;border-color:rgba(102,126,234,var(--border-opacity))}.lg\:border-indigo-600{--border-opacity:1;border-color:#5a67d8;border-color:rgba(90,103,216,var(--border-opacity))}.lg\:border-indigo-700{--border-opacity:1;border-color:#4c51bf;border-color:rgba(76,81,191,var(--border-opacity))}.lg\:border-indigo-800{--border-opacity:1;border-color:#434190;border-color:rgba(67,65,144,var(--border-opacity))}.lg\:border-indigo-900{--border-opacity:1;border-color:#3c366b;border-color:rgba(60,54,107,var(--border-opacity))}.lg\:border-purple-100{--border-opacity:1;border-color:#faf5ff;border-color:rgba(250,245,255,var(--border-opacity))}.lg\:border-purple-200{--border-opacity:1;border-color:#e9d8fd;border-color:rgba(233,216,253,var(--border-opacity))}.lg\:border-purple-300{--border-opacity:1;border-color:#d6bcfa;border-color:rgba(214,188,250,var(--border-opacity))}.lg\:border-purple-400{--border-opacity:1;border-color:#b794f4;border-color:rgba(183,148,244,var(--border-opacity))}.lg\:border-purple-500{--border-opacity:1;border-color:#9f7aea;border-color:rgba(159,122,234,var(--border-opacity))}.lg\:border-purple-600{--border-opacity:1;border-color:#805ad5;border-color:rgba(128,90,213,var(--border-opacity))}.lg\:border-purple-700{--border-opacity:1;border-color:#6b46c1;border-color:rgba(107,70,193,var(--border-opacity))}.lg\:border-purple-800{--border-opacity:1;border-color:#553c9a;border-color:rgba(85,60,154,var(--border-opacity))}.lg\:border-purple-900{--border-opacity:1;border-color:#44337a;border-color:rgba(68,51,122,var(--border-opacity))}.lg\:border-pink-100{--border-opacity:1;border-color:#fff5f7;border-color:rgba(255,245,247,var(--border-opacity))}.lg\:border-pink-200{--border-opacity:1;border-color:#fed7e2;border-color:rgba(254,215,226,var(--border-opacity))}.lg\:border-pink-300{--border-opacity:1;border-color:#fbb6ce;border-color:rgba(251,182,206,var(--border-opacity))}.lg\:border-pink-400{--border-opacity:1;border-color:#f687b3;border-color:rgba(246,135,179,var(--border-opacity))}.lg\:border-pink-500{--border-opacity:1;border-color:#ed64a6;border-color:rgba(237,100,166,var(--border-opacity))}.lg\:border-pink-600{--border-opacity:1;border-color:#d53f8c;border-color:rgba(213,63,140,var(--border-opacity))}.lg\:border-pink-700{--border-opacity:1;border-color:#b83280;border-color:rgba(184,50,128,var(--border-opacity))}.lg\:border-pink-800{--border-opacity:1;border-color:#97266d;border-color:rgba(151,38,109,var(--border-opacity))}.lg\:border-pink-900{--border-opacity:1;border-color:#702459;border-color:rgba(112,36,89,var(--border-opacity))}.lg\:hover\:border-transparent:hover{border-color:transparent}.lg\:hover\:border-current:hover{border-color:currentColor}.lg\:hover\:border-black:hover{--border-opacity:1;border-color:#000;border-color:rgba(0,0,0,var(--border-opacity))}.lg\:hover\:border-white:hover{--border-opacity:1;border-color:#fff;border-color:rgba(255,255,255,var(--border-opacity))}.lg\:hover\:border-gray-100:hover{--border-opacity:1;border-color:#f7fafc;border-color:rgba(247,250,252,var(--border-opacity))}.lg\:hover\:border-gray-200:hover{--border-opacity:1;border-color:#edf2f7;border-color:rgba(237,242,247,var(--border-opacity))}.lg\:hover\:border-gray-300:hover{--border-opacity:1;border-color:#e2e8f0;border-color:rgba(226,232,240,var(--border-opacity))}.lg\:hover\:border-gray-400:hover{--border-opacity:1;border-color:#cbd5e0;border-color:rgba(203,213,224,var(--border-opacity))}.lg\:hover\:border-gray-500:hover{--border-opacity:1;border-color:#a0aec0;border-color:rgba(160,174,192,var(--border-opacity))}.lg\:hover\:border-gray-600:hover{--border-opacity:1;border-color:#718096;border-color:rgba(113,128,150,var(--border-opacity))}.lg\:hover\:border-gray-700:hover{--border-opacity:1;border-color:#4a5568;border-color:rgba(74,85,104,var(--border-opacity))}.lg\:hover\:border-gray-800:hover{--border-opacity:1;border-color:#2d3748;border-color:rgba(45,55,72,var(--border-opacity))}.lg\:hover\:border-gray-900:hover{--border-opacity:1;border-color:#1a202c;border-color:rgba(26,32,44,var(--border-opacity))}.lg\:hover\:border-red-100:hover{--border-opacity:1;border-color:#fff5f5;border-color:rgba(255,245,245,var(--border-opacity))}.lg\:hover\:border-red-200:hover{--border-opacity:1;border-color:#fed7d7;border-color:rgba(254,215,215,var(--border-opacity))}.lg\:hover\:border-red-300:hover{--border-opacity:1;border-color:#feb2b2;border-color:rgba(254,178,178,var(--border-opacity))}.lg\:hover\:border-red-400:hover{--border-opacity:1;border-color:#fc8181;border-color:rgba(252,129,129,var(--border-opacity))}.lg\:hover\:border-red-500:hover{--border-opacity:1;border-color:#f56565;border-color:rgba(245,101,101,var(--border-opacity))}.lg\:hover\:border-red-600:hover{--border-opacity:1;border-color:#e53e3e;border-color:rgba(229,62,62,var(--border-opacity))}.lg\:hover\:border-red-700:hover{--border-opacity:1;border-color:#c53030;border-color:rgba(197,48,48,var(--border-opacity))}.lg\:hover\:border-red-800:hover{--border-opacity:1;border-color:#9b2c2c;border-color:rgba(155,44,44,var(--border-opacity))}.lg\:hover\:border-red-900:hover{--border-opacity:1;border-color:#742a2a;border-color:rgba(116,42,42,var(--border-opacity))}.lg\:hover\:border-orange-100:hover{--border-opacity:1;border-color:#fffaf0;border-color:rgba(255,250,240,var(--border-opacity))}.lg\:hover\:border-orange-200:hover{--border-opacity:1;border-color:#feebc8;border-color:rgba(254,235,200,var(--border-opacity))}.lg\:hover\:border-orange-300:hover{--border-opacity:1;border-color:#fbd38d;border-color:rgba(251,211,141,var(--border-opacity))}.lg\:hover\:border-orange-400:hover{--border-opacity:1;border-color:#f6ad55;border-color:rgba(246,173,85,var(--border-opacity))}.lg\:hover\:border-orange-500:hover{--border-opacity:1;border-color:#ed8936;border-color:rgba(237,137,54,var(--border-opacity))}.lg\:hover\:border-orange-600:hover{--border-opacity:1;border-color:#dd6b20;border-color:rgba(221,107,32,var(--border-opacity))}.lg\:hover\:border-orange-700:hover{--border-opacity:1;border-color:#c05621;border-color:rgba(192,86,33,var(--border-opacity))}.lg\:hover\:border-orange-800:hover{--border-opacity:1;border-color:#9c4221;border-color:rgba(156,66,33,var(--border-opacity))}.lg\:hover\:border-orange-900:hover{--border-opacity:1;border-color:#7b341e;border-color:rgba(123,52,30,var(--border-opacity))}.lg\:hover\:border-yellow-100:hover{--border-opacity:1;border-color:ivory;border-color:rgba(255,255,240,var(--border-opacity))}.lg\:hover\:border-yellow-200:hover{--border-opacity:1;border-color:#fefcbf;border-color:rgba(254,252,191,var(--border-opacity))}.lg\:hover\:border-yellow-300:hover{--border-opacity:1;border-color:#faf089;border-color:rgba(250,240,137,var(--border-opacity))}.lg\:hover\:border-yellow-400:hover{--border-opacity:1;border-color:#f6e05e;border-color:rgba(246,224,94,var(--border-opacity))}.lg\:hover\:border-yellow-500:hover{--border-opacity:1;border-color:#ecc94b;border-color:rgba(236,201,75,var(--border-opacity))}.lg\:hover\:border-yellow-600:hover{--border-opacity:1;border-color:#d69e2e;border-color:rgba(214,158,46,var(--border-opacity))}.lg\:hover\:border-yellow-700:hover{--border-opacity:1;border-color:#b7791f;border-color:rgba(183,121,31,var(--border-opacity))}.lg\:hover\:border-yellow-800:hover{--border-opacity:1;border-color:#975a16;border-color:rgba(151,90,22,var(--border-opacity))}.lg\:hover\:border-yellow-900:hover{--border-opacity:1;border-color:#744210;border-color:rgba(116,66,16,var(--border-opacity))}.lg\:hover\:border-green-100:hover{--border-opacity:1;border-color:#f0fff4;border-color:rgba(240,255,244,var(--border-opacity))}.lg\:hover\:border-green-200:hover{--border-opacity:1;border-color:#c6f6d5;border-color:rgba(198,246,213,var(--border-opacity))}.lg\:hover\:border-green-300:hover{--border-opacity:1;border-color:#9ae6b4;border-color:rgba(154,230,180,var(--border-opacity))}.lg\:hover\:border-green-400:hover{--border-opacity:1;border-color:#68d391;border-color:rgba(104,211,145,var(--border-opacity))}.lg\:hover\:border-green-500:hover{--border-opacity:1;border-color:#48bb78;border-color:rgba(72,187,120,var(--border-opacity))}.lg\:hover\:border-green-600:hover{--border-opacity:1;border-color:#38a169;border-color:rgba(56,161,105,var(--border-opacity))}.lg\:hover\:border-green-700:hover{--border-opacity:1;border-color:#2f855a;border-color:rgba(47,133,90,var(--border-opacity))}.lg\:hover\:border-green-800:hover{--border-opacity:1;border-color:#276749;border-color:rgba(39,103,73,var(--border-opacity))}.lg\:hover\:border-green-900:hover{--border-opacity:1;border-color:#22543d;border-color:rgba(34,84,61,var(--border-opacity))}.lg\:hover\:border-teal-100:hover{--border-opacity:1;border-color:#e6fffa;border-color:rgba(230,255,250,var(--border-opacity))}.lg\:hover\:border-teal-200:hover{--border-opacity:1;border-color:#b2f5ea;border-color:rgba(178,245,234,var(--border-opacity))}.lg\:hover\:border-teal-300:hover{--border-opacity:1;border-color:#81e6d9;border-color:rgba(129,230,217,var(--border-opacity))}.lg\:hover\:border-teal-400:hover{--border-opacity:1;border-color:#4fd1c5;border-color:rgba(79,209,197,var(--border-opacity))}.lg\:hover\:border-teal-500:hover{--border-opacity:1;border-color:#38b2ac;border-color:rgba(56,178,172,var(--border-opacity))}.lg\:hover\:border-teal-600:hover{--border-opacity:1;border-color:#319795;border-color:rgba(49,151,149,var(--border-opacity))}.lg\:hover\:border-teal-700:hover{--border-opacity:1;border-color:#2c7a7b;border-color:rgba(44,122,123,var(--border-opacity))}.lg\:hover\:border-teal-800:hover{--border-opacity:1;border-color:#285e61;border-color:rgba(40,94,97,var(--border-opacity))}.lg\:hover\:border-teal-900:hover{--border-opacity:1;border-color:#234e52;border-color:rgba(35,78,82,var(--border-opacity))}.lg\:hover\:border-blue-100:hover{--border-opacity:1;border-color:#ebf8ff;border-color:rgba(235,248,255,var(--border-opacity))}.lg\:hover\:border-blue-200:hover{--border-opacity:1;border-color:#bee3f8;border-color:rgba(190,227,248,var(--border-opacity))}.lg\:hover\:border-blue-300:hover{--border-opacity:1;border-color:#90cdf4;border-color:rgba(144,205,244,var(--border-opacity))}.lg\:hover\:border-blue-400:hover{--border-opacity:1;border-color:#63b3ed;border-color:rgba(99,179,237,var(--border-opacity))}.lg\:hover\:border-blue-500:hover{--border-opacity:1;border-color:#4299e1;border-color:rgba(66,153,225,var(--border-opacity))}.lg\:hover\:border-blue-600:hover{--border-opacity:1;border-color:#3182ce;border-color:rgba(49,130,206,var(--border-opacity))}.lg\:hover\:border-blue-700:hover{--border-opacity:1;border-color:#2b6cb0;border-color:rgba(43,108,176,var(--border-opacity))}.lg\:hover\:border-blue-800:hover{--border-opacity:1;border-color:#2c5282;border-color:rgba(44,82,130,var(--border-opacity))}.lg\:hover\:border-blue-900:hover{--border-opacity:1;border-color:#2a4365;border-color:rgba(42,67,101,var(--border-opacity))}.lg\:hover\:border-indigo-100:hover{--border-opacity:1;border-color:#ebf4ff;border-color:rgba(235,244,255,var(--border-opacity))}.lg\:hover\:border-indigo-200:hover{--border-opacity:1;border-color:#c3dafe;border-color:rgba(195,218,254,var(--border-opacity))}.lg\:hover\:border-indigo-300:hover{--border-opacity:1;border-color:#a3bffa;border-color:rgba(163,191,250,var(--border-opacity))}.lg\:hover\:border-indigo-400:hover{--border-opacity:1;border-color:#7f9cf5;border-color:rgba(127,156,245,var(--border-opacity))}.lg\:hover\:border-indigo-500:hover{--border-opacity:1;border-color:#667eea;border-color:rgba(102,126,234,var(--border-opacity))}.lg\:hover\:border-indigo-600:hover{--border-opacity:1;border-color:#5a67d8;border-color:rgba(90,103,216,var(--border-opacity))}.lg\:hover\:border-indigo-700:hover{--border-opacity:1;border-color:#4c51bf;border-color:rgba(76,81,191,var(--border-opacity))}.lg\:hover\:border-indigo-800:hover{--border-opacity:1;border-color:#434190;border-color:rgba(67,65,144,var(--border-opacity))}.lg\:hover\:border-indigo-900:hover{--border-opacity:1;border-color:#3c366b;border-color:rgba(60,54,107,var(--border-opacity))}.lg\:hover\:border-purple-100:hover{--border-opacity:1;border-color:#faf5ff;border-color:rgba(250,245,255,var(--border-opacity))}.lg\:hover\:border-purple-200:hover{--border-opacity:1;border-color:#e9d8fd;border-color:rgba(233,216,253,var(--border-opacity))}.lg\:hover\:border-purple-300:hover{--border-opacity:1;border-color:#d6bcfa;border-color:rgba(214,188,250,var(--border-opacity))}.lg\:hover\:border-purple-400:hover{--border-opacity:1;border-color:#b794f4;border-color:rgba(183,148,244,var(--border-opacity))}.lg\:hover\:border-purple-500:hover{--border-opacity:1;border-color:#9f7aea;border-color:rgba(159,122,234,var(--border-opacity))}.lg\:hover\:border-purple-600:hover{--border-opacity:1;border-color:#805ad5;border-color:rgba(128,90,213,var(--border-opacity))}.lg\:hover\:border-purple-700:hover{--border-opacity:1;border-color:#6b46c1;border-color:rgba(107,70,193,var(--border-opacity))}.lg\:hover\:border-purple-800:hover{--border-opacity:1;border-color:#553c9a;border-color:rgba(85,60,154,var(--border-opacity))}.lg\:hover\:border-purple-900:hover{--border-opacity:1;border-color:#44337a;border-color:rgba(68,51,122,var(--border-opacity))}.lg\:hover\:border-pink-100:hover{--border-opacity:1;border-color:#fff5f7;border-color:rgba(255,245,247,var(--border-opacity))}.lg\:hover\:border-pink-200:hover{--border-opacity:1;border-color:#fed7e2;border-color:rgba(254,215,226,var(--border-opacity))}.lg\:hover\:border-pink-300:hover{--border-opacity:1;border-color:#fbb6ce;border-color:rgba(251,182,206,var(--border-opacity))}.lg\:hover\:border-pink-400:hover{--border-opacity:1;border-color:#f687b3;border-color:rgba(246,135,179,var(--border-opacity))}.lg\:hover\:border-pink-500:hover{--border-opacity:1;border-color:#ed64a6;border-color:rgba(237,100,166,var(--border-opacity))}.lg\:hover\:border-pink-600:hover{--border-opacity:1;border-color:#d53f8c;border-color:rgba(213,63,140,var(--border-opacity))}.lg\:hover\:border-pink-700:hover{--border-opacity:1;border-color:#b83280;border-color:rgba(184,50,128,var(--border-opacity))}.lg\:hover\:border-pink-800:hover{--border-opacity:1;border-color:#97266d;border-color:rgba(151,38,109,var(--border-opacity))}.lg\:hover\:border-pink-900:hover{--border-opacity:1;border-color:#702459;border-color:rgba(112,36,89,var(--border-opacity))}.lg\:focus\:border-transparent:focus{border-color:transparent}.lg\:focus\:border-current:focus{border-color:currentColor}.lg\:focus\:border-black:focus{--border-opacity:1;border-color:#000;border-color:rgba(0,0,0,var(--border-opacity))}.lg\:focus\:border-white:focus{--border-opacity:1;border-color:#fff;border-color:rgba(255,255,255,var(--border-opacity))}.lg\:focus\:border-gray-100:focus{--border-opacity:1;border-color:#f7fafc;border-color:rgba(247,250,252,var(--border-opacity))}.lg\:focus\:border-gray-200:focus{--border-opacity:1;border-color:#edf2f7;border-color:rgba(237,242,247,var(--border-opacity))}.lg\:focus\:border-gray-300:focus{--border-opacity:1;border-color:#e2e8f0;border-color:rgba(226,232,240,var(--border-opacity))}.lg\:focus\:border-gray-400:focus{--border-opacity:1;border-color:#cbd5e0;border-color:rgba(203,213,224,var(--border-opacity))}.lg\:focus\:border-gray-500:focus{--border-opacity:1;border-color:#a0aec0;border-color:rgba(160,174,192,var(--border-opacity))}.lg\:focus\:border-gray-600:focus{--border-opacity:1;border-color:#718096;border-color:rgba(113,128,150,var(--border-opacity))}.lg\:focus\:border-gray-700:focus{--border-opacity:1;border-color:#4a5568;border-color:rgba(74,85,104,var(--border-opacity))}.lg\:focus\:border-gray-800:focus{--border-opacity:1;border-color:#2d3748;border-color:rgba(45,55,72,var(--border-opacity))}.lg\:focus\:border-gray-900:focus{--border-opacity:1;border-color:#1a202c;border-color:rgba(26,32,44,var(--border-opacity))}.lg\:focus\:border-red-100:focus{--border-opacity:1;border-color:#fff5f5;border-color:rgba(255,245,245,var(--border-opacity))}.lg\:focus\:border-red-200:focus{--border-opacity:1;border-color:#fed7d7;border-color:rgba(254,215,215,var(--border-opacity))}.lg\:focus\:border-red-300:focus{--border-opacity:1;border-color:#feb2b2;border-color:rgba(254,178,178,var(--border-opacity))}.lg\:focus\:border-red-400:focus{--border-opacity:1;border-color:#fc8181;border-color:rgba(252,129,129,var(--border-opacity))}.lg\:focus\:border-red-500:focus{--border-opacity:1;border-color:#f56565;border-color:rgba(245,101,101,var(--border-opacity))}.lg\:focus\:border-red-600:focus{--border-opacity:1;border-color:#e53e3e;border-color:rgba(229,62,62,var(--border-opacity))}.lg\:focus\:border-red-700:focus{--border-opacity:1;border-color:#c53030;border-color:rgba(197,48,48,var(--border-opacity))}.lg\:focus\:border-red-800:focus{--border-opacity:1;border-color:#9b2c2c;border-color:rgba(155,44,44,var(--border-opacity))}.lg\:focus\:border-red-900:focus{--border-opacity:1;border-color:#742a2a;border-color:rgba(116,42,42,var(--border-opacity))}.lg\:focus\:border-orange-100:focus{--border-opacity:1;border-color:#fffaf0;border-color:rgba(255,250,240,var(--border-opacity))}.lg\:focus\:border-orange-200:focus{--border-opacity:1;border-color:#feebc8;border-color:rgba(254,235,200,var(--border-opacity))}.lg\:focus\:border-orange-300:focus{--border-opacity:1;border-color:#fbd38d;border-color:rgba(251,211,141,var(--border-opacity))}.lg\:focus\:border-orange-400:focus{--border-opacity:1;border-color:#f6ad55;border-color:rgba(246,173,85,var(--border-opacity))}.lg\:focus\:border-orange-500:focus{--border-opacity:1;border-color:#ed8936;border-color:rgba(237,137,54,var(--border-opacity))}.lg\:focus\:border-orange-600:focus{--border-opacity:1;border-color:#dd6b20;border-color:rgba(221,107,32,var(--border-opacity))}.lg\:focus\:border-orange-700:focus{--border-opacity:1;border-color:#c05621;border-color:rgba(192,86,33,var(--border-opacity))}.lg\:focus\:border-orange-800:focus{--border-opacity:1;border-color:#9c4221;border-color:rgba(156,66,33,var(--border-opacity))}.lg\:focus\:border-orange-900:focus{--border-opacity:1;border-color:#7b341e;border-color:rgba(123,52,30,var(--border-opacity))}.lg\:focus\:border-yellow-100:focus{--border-opacity:1;border-color:ivory;border-color:rgba(255,255,240,var(--border-opacity))}.lg\:focus\:border-yellow-200:focus{--border-opacity:1;border-color:#fefcbf;border-color:rgba(254,252,191,var(--border-opacity))}.lg\:focus\:border-yellow-300:focus{--border-opacity:1;border-color:#faf089;border-color:rgba(250,240,137,var(--border-opacity))}.lg\:focus\:border-yellow-400:focus{--border-opacity:1;border-color:#f6e05e;border-color:rgba(246,224,94,var(--border-opacity))}.lg\:focus\:border-yellow-500:focus{--border-opacity:1;border-color:#ecc94b;border-color:rgba(236,201,75,var(--border-opacity))}.lg\:focus\:border-yellow-600:focus{--border-opacity:1;border-color:#d69e2e;border-color:rgba(214,158,46,var(--border-opacity))}.lg\:focus\:border-yellow-700:focus{--border-opacity:1;border-color:#b7791f;border-color:rgba(183,121,31,var(--border-opacity))}.lg\:focus\:border-yellow-800:focus{--border-opacity:1;border-color:#975a16;border-color:rgba(151,90,22,var(--border-opacity))}.lg\:focus\:border-yellow-900:focus{--border-opacity:1;border-color:#744210;border-color:rgba(116,66,16,var(--border-opacity))}.lg\:focus\:border-green-100:focus{--border-opacity:1;border-color:#f0fff4;border-color:rgba(240,255,244,var(--border-opacity))}.lg\:focus\:border-green-200:focus{--border-opacity:1;border-color:#c6f6d5;border-color:rgba(198,246,213,var(--border-opacity))}.lg\:focus\:border-green-300:focus{--border-opacity:1;border-color:#9ae6b4;border-color:rgba(154,230,180,var(--border-opacity))}.lg\:focus\:border-green-400:focus{--border-opacity:1;border-color:#68d391;border-color:rgba(104,211,145,var(--border-opacity))}.lg\:focus\:border-green-500:focus{--border-opacity:1;border-color:#48bb78;border-color:rgba(72,187,120,var(--border-opacity))}.lg\:focus\:border-green-600:focus{--border-opacity:1;border-color:#38a169;border-color:rgba(56,161,105,var(--border-opacity))}.lg\:focus\:border-green-700:focus{--border-opacity:1;border-color:#2f855a;border-color:rgba(47,133,90,var(--border-opacity))}.lg\:focus\:border-green-800:focus{--border-opacity:1;border-color:#276749;border-color:rgba(39,103,73,var(--border-opacity))}.lg\:focus\:border-green-900:focus{--border-opacity:1;border-color:#22543d;border-color:rgba(34,84,61,var(--border-opacity))}.lg\:focus\:border-teal-100:focus{--border-opacity:1;border-color:#e6fffa;border-color:rgba(230,255,250,var(--border-opacity))}.lg\:focus\:border-teal-200:focus{--border-opacity:1;border-color:#b2f5ea;border-color:rgba(178,245,234,var(--border-opacity))}.lg\:focus\:border-teal-300:focus{--border-opacity:1;border-color:#81e6d9;border-color:rgba(129,230,217,var(--border-opacity))}.lg\:focus\:border-teal-400:focus{--border-opacity:1;border-color:#4fd1c5;border-color:rgba(79,209,197,var(--border-opacity))}.lg\:focus\:border-teal-500:focus{--border-opacity:1;border-color:#38b2ac;border-color:rgba(56,178,172,var(--border-opacity))}.lg\:focus\:border-teal-600:focus{--border-opacity:1;border-color:#319795;border-color:rgba(49,151,149,var(--border-opacity))}.lg\:focus\:border-teal-700:focus{--border-opacity:1;border-color:#2c7a7b;border-color:rgba(44,122,123,var(--border-opacity))}.lg\:focus\:border-teal-800:focus{--border-opacity:1;border-color:#285e61;border-color:rgba(40,94,97,var(--border-opacity))}.lg\:focus\:border-teal-900:focus{--border-opacity:1;border-color:#234e52;border-color:rgba(35,78,82,var(--border-opacity))}.lg\:focus\:border-blue-100:focus{--border-opacity:1;border-color:#ebf8ff;border-color:rgba(235,248,255,var(--border-opacity))}.lg\:focus\:border-blue-200:focus{--border-opacity:1;border-color:#bee3f8;border-color:rgba(190,227,248,var(--border-opacity))}.lg\:focus\:border-blue-300:focus{--border-opacity:1;border-color:#90cdf4;border-color:rgba(144,205,244,var(--border-opacity))}.lg\:focus\:border-blue-400:focus{--border-opacity:1;border-color:#63b3ed;border-color:rgba(99,179,237,var(--border-opacity))}.lg\:focus\:border-blue-500:focus{--border-opacity:1;border-color:#4299e1;border-color:rgba(66,153,225,var(--border-opacity))}.lg\:focus\:border-blue-600:focus{--border-opacity:1;border-color:#3182ce;border-color:rgba(49,130,206,var(--border-opacity))}.lg\:focus\:border-blue-700:focus{--border-opacity:1;border-color:#2b6cb0;border-color:rgba(43,108,176,var(--border-opacity))}.lg\:focus\:border-blue-800:focus{--border-opacity:1;border-color:#2c5282;border-color:rgba(44,82,130,var(--border-opacity))}.lg\:focus\:border-blue-900:focus{--border-opacity:1;border-color:#2a4365;border-color:rgba(42,67,101,var(--border-opacity))}.lg\:focus\:border-indigo-100:focus{--border-opacity:1;border-color:#ebf4ff;border-color:rgba(235,244,255,var(--border-opacity))}.lg\:focus\:border-indigo-200:focus{--border-opacity:1;border-color:#c3dafe;border-color:rgba(195,218,254,var(--border-opacity))}.lg\:focus\:border-indigo-300:focus{--border-opacity:1;border-color:#a3bffa;border-color:rgba(163,191,250,var(--border-opacity))}.lg\:focus\:border-indigo-400:focus{--border-opacity:1;border-color:#7f9cf5;border-color:rgba(127,156,245,var(--border-opacity))}.lg\:focus\:border-indigo-500:focus{--border-opacity:1;border-color:#667eea;border-color:rgba(102,126,234,var(--border-opacity))}.lg\:focus\:border-indigo-600:focus{--border-opacity:1;border-color:#5a67d8;border-color:rgba(90,103,216,var(--border-opacity))}.lg\:focus\:border-indigo-700:focus{--border-opacity:1;border-color:#4c51bf;border-color:rgba(76,81,191,var(--border-opacity))}.lg\:focus\:border-indigo-800:focus{--border-opacity:1;border-color:#434190;border-color:rgba(67,65,144,var(--border-opacity))}.lg\:focus\:border-indigo-900:focus{--border-opacity:1;border-color:#3c366b;border-color:rgba(60,54,107,var(--border-opacity))}.lg\:focus\:border-purple-100:focus{--border-opacity:1;border-color:#faf5ff;border-color:rgba(250,245,255,var(--border-opacity))}.lg\:focus\:border-purple-200:focus{--border-opacity:1;border-color:#e9d8fd;border-color:rgba(233,216,253,var(--border-opacity))}.lg\:focus\:border-purple-300:focus{--border-opacity:1;border-color:#d6bcfa;border-color:rgba(214,188,250,var(--border-opacity))}.lg\:focus\:border-purple-400:focus{--border-opacity:1;border-color:#b794f4;border-color:rgba(183,148,244,var(--border-opacity))}.lg\:focus\:border-purple-500:focus{--border-opacity:1;border-color:#9f7aea;border-color:rgba(159,122,234,var(--border-opacity))}.lg\:focus\:border-purple-600:focus{--border-opacity:1;border-color:#805ad5;border-color:rgba(128,90,213,var(--border-opacity))}.lg\:focus\:border-purple-700:focus{--border-opacity:1;border-color:#6b46c1;border-color:rgba(107,70,193,var(--border-opacity))}.lg\:focus\:border-purple-800:focus{--border-opacity:1;border-color:#553c9a;border-color:rgba(85,60,154,var(--border-opacity))}.lg\:focus\:border-purple-900:focus{--border-opacity:1;border-color:#44337a;border-color:rgba(68,51,122,var(--border-opacity))}.lg\:focus\:border-pink-100:focus{--border-opacity:1;border-color:#fff5f7;border-color:rgba(255,245,247,var(--border-opacity))}.lg\:focus\:border-pink-200:focus{--border-opacity:1;border-color:#fed7e2;border-color:rgba(254,215,226,var(--border-opacity))}.lg\:focus\:border-pink-300:focus{--border-opacity:1;border-color:#fbb6ce;border-color:rgba(251,182,206,var(--border-opacity))}.lg\:focus\:border-pink-400:focus{--border-opacity:1;border-color:#f687b3;border-color:rgba(246,135,179,var(--border-opacity))}.lg\:focus\:border-pink-500:focus{--border-opacity:1;border-color:#ed64a6;border-color:rgba(237,100,166,var(--border-opacity))}.lg\:focus\:border-pink-600:focus{--border-opacity:1;border-color:#d53f8c;border-color:rgba(213,63,140,var(--border-opacity))}.lg\:focus\:border-pink-700:focus{--border-opacity:1;border-color:#b83280;border-color:rgba(184,50,128,var(--border-opacity))}.lg\:focus\:border-pink-800:focus{--border-opacity:1;border-color:#97266d;border-color:rgba(151,38,109,var(--border-opacity))}.lg\:focus\:border-pink-900:focus{--border-opacity:1;border-color:#702459;border-color:rgba(112,36,89,var(--border-opacity))}.lg\:border-opacity-0{--border-opacity:0}.lg\:border-opacity-25{--border-opacity:0.25}.lg\:border-opacity-50{--border-opacity:0.5}.lg\:border-opacity-75{--border-opacity:0.75}.lg\:border-opacity-100{--border-opacity:1}.lg\:hover\:border-opacity-0:hover{--border-opacity:0}.lg\:hover\:border-opacity-25:hover{--border-opacity:0.25}.lg\:hover\:border-opacity-50:hover{--border-opacity:0.5}.lg\:hover\:border-opacity-75:hover{--border-opacity:0.75}.lg\:hover\:border-opacity-100:hover{--border-opacity:1}.lg\:focus\:border-opacity-0:focus{--border-opacity:0}.lg\:focus\:border-opacity-25:focus{--border-opacity:0.25}.lg\:focus\:border-opacity-50:focus{--border-opacity:0.5}.lg\:focus\:border-opacity-75:focus{--border-opacity:0.75}.lg\:focus\:border-opacity-100:focus{--border-opacity:1}.lg\:rounded-none{border-radius:0}.lg\:rounded-sm{border-radius:.125rem}.lg\:rounded{border-radius:.25rem}.lg\:rounded-md{border-radius:.375rem}.lg\:rounded-lg{border-radius:.5rem}.lg\:rounded-xl{border-radius:.75rem}.lg\:rounded-2xl{border-radius:1rem}.lg\:rounded-3xl{border-radius:1.5rem}.lg\:rounded-full{border-radius:9999px}.lg\:rounded-t-none{border-top-left-radius:0;border-top-right-radius:0}.lg\:rounded-r-none{border-top-right-radius:0;border-bottom-right-radius:0}.lg\:rounded-b-none{border-bottom-right-radius:0;border-bottom-left-radius:0}.lg\:rounded-l-none{border-top-left-radius:0;border-bottom-left-radius:0}.lg\:rounded-t-sm{border-top-left-radius:.125rem;border-top-right-radius:.125rem}.lg\:rounded-r-sm{border-top-right-radius:.125rem;border-bottom-right-radius:.125rem}.lg\:rounded-b-sm{border-bottom-right-radius:.125rem;border-bottom-left-radius:.125rem}.lg\:rounded-l-sm{border-top-left-radius:.125rem;border-bottom-left-radius:.125rem}.lg\:rounded-t{border-top-left-radius:.25rem;border-top-right-radius:.25rem}.lg\:rounded-r{border-top-right-radius:.25rem;border-bottom-right-radius:.25rem}.lg\:rounded-b{border-bottom-right-radius:.25rem;border-bottom-left-radius:.25rem}.lg\:rounded-l{border-top-left-radius:.25rem;border-bottom-left-radius:.25rem}.lg\:rounded-t-md{border-top-left-radius:.375rem;border-top-right-radius:.375rem}.lg\:rounded-r-md{border-top-right-radius:.375rem;border-bottom-right-radius:.375rem}.lg\:rounded-b-md{border-bottom-right-radius:.375rem;border-bottom-left-radius:.375rem}.lg\:rounded-l-md{border-top-left-radius:.375rem;border-bottom-left-radius:.375rem}.lg\:rounded-t-lg{border-top-left-radius:.5rem;border-top-right-radius:.5rem}.lg\:rounded-r-lg{border-top-right-radius:.5rem;border-bottom-right-radius:.5rem}.lg\:rounded-b-lg{border-bottom-right-radius:.5rem;border-bottom-left-radius:.5rem}.lg\:rounded-l-lg{border-top-left-radius:.5rem;border-bottom-left-radius:.5rem}.lg\:rounded-t-xl{border-top-left-radius:.75rem;border-top-right-radius:.75rem}.lg\:rounded-r-xl{border-top-right-radius:.75rem;border-bottom-right-radius:.75rem}.lg\:rounded-b-xl{border-bottom-right-radius:.75rem;border-bottom-left-radius:.75rem}.lg\:rounded-l-xl{border-top-left-radius:.75rem;border-bottom-left-radius:.75rem}.lg\:rounded-t-2xl{border-top-left-radius:1rem;border-top-right-radius:1rem}.lg\:rounded-r-2xl{border-top-right-radius:1rem;border-bottom-right-radius:1rem}.lg\:rounded-b-2xl{border-bottom-right-radius:1rem;border-bottom-left-radius:1rem}.lg\:rounded-l-2xl{border-top-left-radius:1rem;border-bottom-left-radius:1rem}.lg\:rounded-t-3xl{border-top-left-radius:1.5rem;border-top-right-radius:1.5rem}.lg\:rounded-r-3xl{border-top-right-radius:1.5rem;border-bottom-right-radius:1.5rem}.lg\:rounded-b-3xl{border-bottom-right-radius:1.5rem;border-bottom-left-radius:1.5rem}.lg\:rounded-l-3xl{border-top-left-radius:1.5rem;border-bottom-left-radius:1.5rem}.lg\:rounded-t-full{border-top-left-radius:9999px;border-top-right-radius:9999px}.lg\:rounded-r-full{border-top-right-radius:9999px;border-bottom-right-radius:9999px}.lg\:rounded-b-full{border-bottom-right-radius:9999px;border-bottom-left-radius:9999px}.lg\:rounded-l-full{border-top-left-radius:9999px;border-bottom-left-radius:9999px}.lg\:rounded-tl-none{border-top-left-radius:0}.lg\:rounded-tr-none{border-top-right-radius:0}.lg\:rounded-br-none{border-bottom-right-radius:0}.lg\:rounded-bl-none{border-bottom-left-radius:0}.lg\:rounded-tl-sm{border-top-left-radius:.125rem}.lg\:rounded-tr-sm{border-top-right-radius:.125rem}.lg\:rounded-br-sm{border-bottom-right-radius:.125rem}.lg\:rounded-bl-sm{border-bottom-left-radius:.125rem}.lg\:rounded-tl{border-top-left-radius:.25rem}.lg\:rounded-tr{border-top-right-radius:.25rem}.lg\:rounded-br{border-bottom-right-radius:.25rem}.lg\:rounded-bl{border-bottom-left-radius:.25rem}.lg\:rounded-tl-md{border-top-left-radius:.375rem}.lg\:rounded-tr-md{border-top-right-radius:.375rem}.lg\:rounded-br-md{border-bottom-right-radius:.375rem}.lg\:rounded-bl-md{border-bottom-left-radius:.375rem}.lg\:rounded-tl-lg{border-top-left-radius:.5rem}.lg\:rounded-tr-lg{border-top-right-radius:.5rem}.lg\:rounded-br-lg{border-bottom-right-radius:.5rem}.lg\:rounded-bl-lg{border-bottom-left-radius:.5rem}.lg\:rounded-tl-xl{border-top-left-radius:.75rem}.lg\:rounded-tr-xl{border-top-right-radius:.75rem}.lg\:rounded-br-xl{border-bottom-right-radius:.75rem}.lg\:rounded-bl-xl{border-bottom-left-radius:.75rem}.lg\:rounded-tl-2xl{border-top-left-radius:1rem}.lg\:rounded-tr-2xl{border-top-right-radius:1rem}.lg\:rounded-br-2xl{border-bottom-right-radius:1rem}.lg\:rounded-bl-2xl{border-bottom-left-radius:1rem}.lg\:rounded-tl-3xl{border-top-left-radius:1.5rem}.lg\:rounded-tr-3xl{border-top-right-radius:1.5rem}.lg\:rounded-br-3xl{border-bottom-right-radius:1.5rem}.lg\:rounded-bl-3xl{border-bottom-left-radius:1.5rem}.lg\:rounded-tl-full{border-top-left-radius:9999px}.lg\:rounded-tr-full{border-top-right-radius:9999px}.lg\:rounded-br-full{border-bottom-right-radius:9999px}.lg\:rounded-bl-full{border-bottom-left-radius:9999px}.lg\:border-solid{border-style:solid}.lg\:border-dashed{border-style:dashed}.lg\:border-dotted{border-style:dotted}.lg\:border-double{border-style:double}.lg\:border-none{border-style:none}.lg\:border-0{border-width:0}.lg\:border-2{border-width:2px}.lg\:border-4{border-width:4px}.lg\:border-8{border-width:8px}.lg\:border{border-width:1px}.lg\:border-t-0{border-top-width:0}.lg\:border-r-0{border-right-width:0}.lg\:border-b-0{border-bottom-width:0}.lg\:border-l-0{border-left-width:0}.lg\:border-t-2{border-top-width:2px}.lg\:border-r-2{border-right-width:2px}.lg\:border-b-2{border-bottom-width:2px}.lg\:border-l-2{border-left-width:2px}.lg\:border-t-4{border-top-width:4px}.lg\:border-r-4{border-right-width:4px}.lg\:border-b-4{border-bottom-width:4px}.lg\:border-l-4{border-left-width:4px}.lg\:border-t-8{border-top-width:8px}.lg\:border-r-8{border-right-width:8px}.lg\:border-b-8{border-bottom-width:8px}.lg\:border-l-8{border-left-width:8px}.lg\:border-t{border-top-width:1px}.lg\:border-r{border-right-width:1px}.lg\:border-b{border-bottom-width:1px}.lg\:border-l{border-left-width:1px}.lg\:box-border{box-sizing:border-box}.lg\:box-content{box-sizing:content-box}.lg\:cursor-auto{cursor:auto}.lg\:cursor-default{cursor:default}.lg\:cursor-pointer{cursor:pointer}.lg\:cursor-wait{cursor:wait}.lg\:cursor-text{cursor:text}.lg\:cursor-move{cursor:move}.lg\:cursor-not-allowed{cursor:not-allowed}.lg\:block{display:block}.lg\:inline-block{display:inline-block}.lg\:inline{display:inline}.lg\:flex{display:flex}.lg\:inline-flex{display:inline-flex}.lg\:table{display:table}.lg\:table-caption{display:table-caption}.lg\:table-cell{display:table-cell}.lg\:table-column{display:table-column}.lg\:table-column-group{display:table-column-group}.lg\:table-footer-group{display:table-footer-group}.lg\:table-header-group{display:table-header-group}.lg\:table-row-group{display:table-row-group}.lg\:table-row{display:table-row}.lg\:flow-root{display:flow-root}.lg\:grid{display:grid}.lg\:inline-grid{display:inline-grid}.lg\:contents{display:contents}.lg\:hidden{display:none}.lg\:flex-row{flex-direction:row}.lg\:flex-row-reverse{flex-direction:row-reverse}.lg\:flex-col{flex-direction:column}.lg\:flex-col-reverse{flex-direction:column-reverse}.lg\:flex-wrap{flex-wrap:wrap}.lg\:flex-wrap-reverse{flex-wrap:wrap-reverse}.lg\:flex-no-wrap{flex-wrap:nowrap}.lg\:place-items-auto{place-items:auto}.lg\:place-items-start{place-items:start}.lg\:place-items-end{place-items:end}.lg\:place-items-center{place-items:center}.lg\:place-items-stretch{place-items:stretch}.lg\:place-content-center{place-content:center}.lg\:place-content-start{place-content:start}.lg\:place-content-end{place-content:end}.lg\:place-content-between{place-content:space-between}.lg\:place-content-around{place-content:space-around}.lg\:place-content-evenly{place-content:space-evenly}.lg\:place-content-stretch{place-content:stretch}.lg\:place-self-auto{place-self:auto}.lg\:place-self-start{place-self:start}.lg\:place-self-end{place-self:end}.lg\:place-self-center{place-self:center}.lg\:place-self-stretch{place-self:stretch}.lg\:items-start{align-items:flex-start}.lg\:items-end{align-items:flex-end}.lg\:items-center{align-items:center}.lg\:items-baseline{align-items:baseline}.lg\:items-stretch{align-items:stretch}.lg\:content-center{align-content:center}.lg\:content-start{align-content:flex-start}.lg\:content-end{align-content:flex-end}.lg\:content-between{align-content:space-between}.lg\:content-around{align-content:space-around}.lg\:content-evenly{align-content:space-evenly}.lg\:self-auto{align-self:auto}.lg\:self-start{align-self:flex-start}.lg\:self-end{align-self:flex-end}.lg\:self-center{align-self:center}.lg\:self-stretch{align-self:stretch}.lg\:justify-items-auto{justify-items:auto}.lg\:justify-items-start{justify-items:start}.lg\:justify-items-end{justify-items:end}.lg\:justify-items-center{justify-items:center}.lg\:justify-items-stretch{justify-items:stretch}.lg\:justify-start{justify-content:flex-start}.lg\:justify-end{justify-content:flex-end}.lg\:justify-center{justify-content:center}.lg\:justify-between{justify-content:space-between}.lg\:justify-around{justify-content:space-around}.lg\:justify-evenly{justify-content:space-evenly}.lg\:justify-self-auto{justify-self:auto}.lg\:justify-self-start{justify-self:start}.lg\:justify-self-end{justify-self:end}.lg\:justify-self-center{justify-self:center}.lg\:justify-self-stretch{justify-self:stretch}.lg\:flex-1{flex:1 1 0%}.lg\:flex-auto{flex:1 1 auto}.lg\:flex-initial{flex:0 1 auto}.lg\:flex-none{flex:none}.lg\:flex-grow-0{flex-grow:0}.lg\:flex-grow{flex-grow:1}.lg\:flex-shrink-0{flex-shrink:0}.lg\:flex-shrink{flex-shrink:1}.lg\:order-1{order:1}.lg\:order-2{order:2}.lg\:order-3{order:3}.lg\:order-4{order:4}.lg\:order-5{order:5}.lg\:order-6{order:6}.lg\:order-7{order:7}.lg\:order-8{order:8}.lg\:order-9{order:9}.lg\:order-10{order:10}.lg\:order-11{order:11}.lg\:order-12{order:12}.lg\:order-first{order:-9999}.lg\:order-last{order:9999}.lg\:order-none{order:0}.lg\:float-right{float:right}.lg\:float-left{float:left}.lg\:float-none{float:none}.lg\:clearfix:after{content:"";display:table;clear:both}.lg\:clear-left{clear:left}.lg\:clear-right{clear:right}.lg\:clear-both{clear:both}.lg\:clear-none{clear:none}.lg\:font-sans{font-family:system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji"}.lg\:font-serif{font-family:Georgia,Cambria,"Times New Roman",Times,serif}.lg\:font-mono{font-family:Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace}.lg\:font-hairline{font-weight:100}.lg\:font-thin{font-weight:200}.lg\:font-light{font-weight:300}.lg\:font-normal{font-weight:400}.lg\:font-medium{font-weight:500}.lg\:font-semibold{font-weight:600}.lg\:font-bold{font-weight:700}.lg\:font-extrabold{font-weight:800}.lg\:font-black{font-weight:900}.lg\:hover\:font-hairline:hover{font-weight:100}.lg\:hover\:font-thin:hover{font-weight:200}.lg\:hover\:font-light:hover{font-weight:300}.lg\:hover\:font-normal:hover{font-weight:400}.lg\:hover\:font-medium:hover{font-weight:500}.lg\:hover\:font-semibold:hover{font-weight:600}.lg\:hover\:font-bold:hover{font-weight:700}.lg\:hover\:font-extrabold:hover{font-weight:800}.lg\:hover\:font-black:hover{font-weight:900}.lg\:focus\:font-hairline:focus{font-weight:100}.lg\:focus\:font-thin:focus{font-weight:200}.lg\:focus\:font-light:focus{font-weight:300}.lg\:focus\:font-normal:focus{font-weight:400}.lg\:focus\:font-medium:focus{font-weight:500}.lg\:focus\:font-semibold:focus{font-weight:600}.lg\:focus\:font-bold:focus{font-weight:700}.lg\:focus\:font-extrabold:focus{font-weight:800}.lg\:focus\:font-black:focus{font-weight:900}.lg\:h-0{height:0}.lg\:h-1{height:.25rem}.lg\:h-2{height:.5rem}.lg\:h-3{height:.75rem}.lg\:h-4{height:1rem}.lg\:h-5{height:1.25rem}.lg\:h-6{height:1.5rem}.lg\:h-8{height:2rem}.lg\:h-10{height:2.5rem}.lg\:h-12{height:3rem}.lg\:h-16{height:4rem}.lg\:h-20{height:5rem}.lg\:h-24{height:6rem}.lg\:h-32{height:8rem}.lg\:h-40{height:10rem}.lg\:h-48{height:12rem}.lg\:h-56{height:14rem}.lg\:h-64{height:16rem}.lg\:h-auto{height:auto}.lg\:h-px{height:1px}.lg\:h-full{height:100%}.lg\:h-screen{height:100vh}.lg\:text-xs{font-size:.75rem}.lg\:text-sm{font-size:.875rem}.lg\:text-base{font-size:1rem}.lg\:text-lg{font-size:1.125rem}.lg\:text-xl{font-size:1.25rem}.lg\:text-2xl{font-size:1.5rem}.lg\:text-3xl{font-size:1.875rem}.lg\:text-4xl{font-size:2.25rem}.lg\:text-5xl{font-size:3rem}.lg\:text-6xl{font-size:4rem}.lg\:leading-3{line-height:.75rem}.lg\:leading-4{line-height:1rem}.lg\:leading-5{line-height:1.25rem}.lg\:leading-6{line-height:1.5rem}.lg\:leading-7{line-height:1.75rem}.lg\:leading-8{line-height:2rem}.lg\:leading-9{line-height:2.25rem}.lg\:leading-10{line-height:2.5rem}.lg\:leading-none{line-height:1}.lg\:leading-tight{line-height:1.25}.lg\:leading-snug{line-height:1.375}.lg\:leading-normal{line-height:1.5}.lg\:leading-relaxed{line-height:1.625}.lg\:leading-loose{line-height:2}.lg\:list-inside{list-style-position:inside}.lg\:list-outside{list-style-position:outside}.lg\:list-none{list-style-type:none}.lg\:list-disc{list-style-type:disc}.lg\:list-decimal{list-style-type:decimal}.lg\:m-0{margin:0}.lg\:m-1{margin:.25rem}.lg\:m-2{margin:.5rem}.lg\:m-3{margin:.75rem}.lg\:m-4{margin:1rem}.lg\:m-5{margin:1.25rem}.lg\:m-6{margin:1.5rem}.lg\:m-8{margin:2rem}.lg\:m-10{margin:2.5rem}.lg\:m-12{margin:3rem}.lg\:m-16{margin:4rem}.lg\:m-20{margin:5rem}.lg\:m-24{margin:6rem}.lg\:m-32{margin:8rem}.lg\:m-40{margin:10rem}.lg\:m-48{margin:12rem}.lg\:m-56{margin:14rem}.lg\:m-64{margin:16rem}.lg\:m-auto{margin:auto}.lg\:m-px{margin:1px}.lg\:-m-1{margin:-.25rem}.lg\:-m-2{margin:-.5rem}.lg\:-m-3{margin:-.75rem}.lg\:-m-4{margin:-1rem}.lg\:-m-5{margin:-1.25rem}.lg\:-m-6{margin:-1.5rem}.lg\:-m-8{margin:-2rem}.lg\:-m-10{margin:-2.5rem}.lg\:-m-12{margin:-3rem}.lg\:-m-16{margin:-4rem}.lg\:-m-20{margin:-5rem}.lg\:-m-24{margin:-6rem}.lg\:-m-32{margin:-8rem}.lg\:-m-40{margin:-10rem}.lg\:-m-48{margin:-12rem}.lg\:-m-56{margin:-14rem}.lg\:-m-64{margin:-16rem}.lg\:-m-px{margin:-1px}.lg\:my-0{margin-top:0;margin-bottom:0}.lg\:mx-0{margin-left:0;margin-right:0}.lg\:my-1{margin-top:.25rem;margin-bottom:.25rem}.lg\:mx-1{margin-left:.25rem;margin-right:.25rem}.lg\:my-2{margin-top:.5rem;margin-bottom:.5rem}.lg\:mx-2{margin-left:.5rem;margin-right:.5rem}.lg\:my-3{margin-top:.75rem;margin-bottom:.75rem}.lg\:mx-3{margin-left:.75rem;margin-right:.75rem}.lg\:my-4{margin-top:1rem;margin-bottom:1rem}.lg\:mx-4{margin-left:1rem;margin-right:1rem}.lg\:my-5{margin-top:1.25rem;margin-bottom:1.25rem}.lg\:mx-5{margin-left:1.25rem;margin-right:1.25rem}.lg\:my-6{margin-top:1.5rem;margin-bottom:1.5rem}.lg\:mx-6{margin-left:1.5rem;margin-right:1.5rem}.lg\:my-8{margin-top:2rem;margin-bottom:2rem}.lg\:mx-8{margin-left:2rem;margin-right:2rem}.lg\:my-10{margin-top:2.5rem;margin-bottom:2.5rem}.lg\:mx-10{margin-left:2.5rem;margin-right:2.5rem}.lg\:my-12{margin-top:3rem;margin-bottom:3rem}.lg\:mx-12{margin-left:3rem;margin-right:3rem}.lg\:my-16{margin-top:4rem;margin-bottom:4rem}.lg\:mx-16{margin-left:4rem;margin-right:4rem}.lg\:my-20{margin-top:5rem;margin-bottom:5rem}.lg\:mx-20{margin-left:5rem;margin-right:5rem}.lg\:my-24{margin-top:6rem;margin-bottom:6rem}.lg\:mx-24{margin-left:6rem;margin-right:6rem}.lg\:my-32{margin-top:8rem;margin-bottom:8rem}.lg\:mx-32{margin-left:8rem;margin-right:8rem}.lg\:my-40{margin-top:10rem;margin-bottom:10rem}.lg\:mx-40{margin-left:10rem;margin-right:10rem}.lg\:my-48{margin-top:12rem;margin-bottom:12rem}.lg\:mx-48{margin-left:12rem;margin-right:12rem}.lg\:my-56{margin-top:14rem;margin-bottom:14rem}.lg\:mx-56{margin-left:14rem;margin-right:14rem}.lg\:my-64{margin-top:16rem;margin-bottom:16rem}.lg\:mx-64{margin-left:16rem;margin-right:16rem}.lg\:my-auto{margin-top:auto;margin-bottom:auto}.lg\:mx-auto{margin-left:auto;margin-right:auto}.lg\:my-px{margin-top:1px;margin-bottom:1px}.lg\:mx-px{margin-left:1px;margin-right:1px}.lg\:-my-1{margin-top:-.25rem;margin-bottom:-.25rem}.lg\:-mx-1{margin-left:-.25rem;margin-right:-.25rem}.lg\:-my-2{margin-top:-.5rem;margin-bottom:-.5rem}.lg\:-mx-2{margin-left:-.5rem;margin-right:-.5rem}.lg\:-my-3{margin-top:-.75rem;margin-bottom:-.75rem}.lg\:-mx-3{margin-left:-.75rem;margin-right:-.75rem}.lg\:-my-4{margin-top:-1rem;margin-bottom:-1rem}.lg\:-mx-4{margin-left:-1rem;margin-right:-1rem}.lg\:-my-5{margin-top:-1.25rem;margin-bottom:-1.25rem}.lg\:-mx-5{margin-left:-1.25rem;margin-right:-1.25rem}.lg\:-my-6{margin-top:-1.5rem;margin-bottom:-1.5rem}.lg\:-mx-6{margin-left:-1.5rem;margin-right:-1.5rem}.lg\:-my-8{margin-top:-2rem;margin-bottom:-2rem}.lg\:-mx-8{margin-left:-2rem;margin-right:-2rem}.lg\:-my-10{margin-top:-2.5rem;margin-bottom:-2.5rem}.lg\:-mx-10{margin-left:-2.5rem;margin-right:-2.5rem}.lg\:-my-12{margin-top:-3rem;margin-bottom:-3rem}.lg\:-mx-12{margin-left:-3rem;margin-right:-3rem}.lg\:-my-16{margin-top:-4rem;margin-bottom:-4rem}.lg\:-mx-16{margin-left:-4rem;margin-right:-4rem}.lg\:-my-20{margin-top:-5rem;margin-bottom:-5rem}.lg\:-mx-20{margin-left:-5rem;margin-right:-5rem}.lg\:-my-24{margin-top:-6rem;margin-bottom:-6rem}.lg\:-mx-24{margin-left:-6rem;margin-right:-6rem}.lg\:-my-32{margin-top:-8rem;margin-bottom:-8rem}.lg\:-mx-32{margin-left:-8rem;margin-right:-8rem}.lg\:-my-40{margin-top:-10rem;margin-bottom:-10rem}.lg\:-mx-40{margin-left:-10rem;margin-right:-10rem}.lg\:-my-48{margin-top:-12rem;margin-bottom:-12rem}.lg\:-mx-48{margin-left:-12rem;margin-right:-12rem}.lg\:-my-56{margin-top:-14rem;margin-bottom:-14rem}.lg\:-mx-56{margin-left:-14rem;margin-right:-14rem}.lg\:-my-64{margin-top:-16rem;margin-bottom:-16rem}.lg\:-mx-64{margin-left:-16rem;margin-right:-16rem}.lg\:-my-px{margin-top:-1px;margin-bottom:-1px}.lg\:-mx-px{margin-left:-1px;margin-right:-1px}.lg\:mt-0{margin-top:0}.lg\:mr-0{margin-right:0}.lg\:mb-0{margin-bottom:0}.lg\:ml-0{margin-left:0}.lg\:mt-1{margin-top:.25rem}.lg\:mr-1{margin-right:.25rem}.lg\:mb-1{margin-bottom:.25rem}.lg\:ml-1{margin-left:.25rem}.lg\:mt-2{margin-top:.5rem}.lg\:mr-2{margin-right:.5rem}.lg\:mb-2{margin-bottom:.5rem}.lg\:ml-2{margin-left:.5rem}.lg\:mt-3{margin-top:.75rem}.lg\:mr-3{margin-right:.75rem}.lg\:mb-3{margin-bottom:.75rem}.lg\:ml-3{margin-left:.75rem}.lg\:mt-4{margin-top:1rem}.lg\:mr-4{margin-right:1rem}.lg\:mb-4{margin-bottom:1rem}.lg\:ml-4{margin-left:1rem}.lg\:mt-5{margin-top:1.25rem}.lg\:mr-5{margin-right:1.25rem}.lg\:mb-5{margin-bottom:1.25rem}.lg\:ml-5{margin-left:1.25rem}.lg\:mt-6{margin-top:1.5rem}.lg\:mr-6{margin-right:1.5rem}.lg\:mb-6{margin-bottom:1.5rem}.lg\:ml-6{margin-left:1.5rem}.lg\:mt-8{margin-top:2rem}.lg\:mr-8{margin-right:2rem}.lg\:mb-8{margin-bottom:2rem}.lg\:ml-8{margin-left:2rem}.lg\:mt-10{margin-top:2.5rem}.lg\:mr-10{margin-right:2.5rem}.lg\:mb-10{margin-bottom:2.5rem}.lg\:ml-10{margin-left:2.5rem}.lg\:mt-12{margin-top:3rem}.lg\:mr-12{margin-right:3rem}.lg\:mb-12{margin-bottom:3rem}.lg\:ml-12{margin-left:3rem}.lg\:mt-16{margin-top:4rem}.lg\:mr-16{margin-right:4rem}.lg\:mb-16{margin-bottom:4rem}.lg\:ml-16{margin-left:4rem}.lg\:mt-20{margin-top:5rem}.lg\:mr-20{margin-right:5rem}.lg\:mb-20{margin-bottom:5rem}.lg\:ml-20{margin-left:5rem}.lg\:mt-24{margin-top:6rem}.lg\:mr-24{margin-right:6rem}.lg\:mb-24{margin-bottom:6rem}.lg\:ml-24{margin-left:6rem}.lg\:mt-32{margin-top:8rem}.lg\:mr-32{margin-right:8rem}.lg\:mb-32{margin-bottom:8rem}.lg\:ml-32{margin-left:8rem}.lg\:mt-40{margin-top:10rem}.lg\:mr-40{margin-right:10rem}.lg\:mb-40{margin-bottom:10rem}.lg\:ml-40{margin-left:10rem}.lg\:mt-48{margin-top:12rem}.lg\:mr-48{margin-right:12rem}.lg\:mb-48{margin-bottom:12rem}.lg\:ml-48{margin-left:12rem}.lg\:mt-56{margin-top:14rem}.lg\:mr-56{margin-right:14rem}.lg\:mb-56{margin-bottom:14rem}.lg\:ml-56{margin-left:14rem}.lg\:mt-64{margin-top:16rem}.lg\:mr-64{margin-right:16rem}.lg\:mb-64{margin-bottom:16rem}.lg\:ml-64{margin-left:16rem}.lg\:mt-auto{margin-top:auto}.lg\:mr-auto{margin-right:auto}.lg\:mb-auto{margin-bottom:auto}.lg\:ml-auto{margin-left:auto}.lg\:mt-px{margin-top:1px}.lg\:mr-px{margin-right:1px}.lg\:mb-px{margin-bottom:1px}.lg\:ml-px{margin-left:1px}.lg\:-mt-1{margin-top:-.25rem}.lg\:-mr-1{margin-right:-.25rem}.lg\:-mb-1{margin-bottom:-.25rem}.lg\:-ml-1{margin-left:-.25rem}.lg\:-mt-2{margin-top:-.5rem}.lg\:-mr-2{margin-right:-.5rem}.lg\:-mb-2{margin-bottom:-.5rem}.lg\:-ml-2{margin-left:-.5rem}.lg\:-mt-3{margin-top:-.75rem}.lg\:-mr-3{margin-right:-.75rem}.lg\:-mb-3{margin-bottom:-.75rem}.lg\:-ml-3{margin-left:-.75rem}.lg\:-mt-4{margin-top:-1rem}.lg\:-mr-4{margin-right:-1rem}.lg\:-mb-4{margin-bottom:-1rem}.lg\:-ml-4{margin-left:-1rem}.lg\:-mt-5{margin-top:-1.25rem}.lg\:-mr-5{margin-right:-1.25rem}.lg\:-mb-5{margin-bottom:-1.25rem}.lg\:-ml-5{margin-left:-1.25rem}.lg\:-mt-6{margin-top:-1.5rem}.lg\:-mr-6{margin-right:-1.5rem}.lg\:-mb-6{margin-bottom:-1.5rem}.lg\:-ml-6{margin-left:-1.5rem}.lg\:-mt-8{margin-top:-2rem}.lg\:-mr-8{margin-right:-2rem}.lg\:-mb-8{margin-bottom:-2rem}.lg\:-ml-8{margin-left:-2rem}.lg\:-mt-10{margin-top:-2.5rem}.lg\:-mr-10{margin-right:-2.5rem}.lg\:-mb-10{margin-bottom:-2.5rem}.lg\:-ml-10{margin-left:-2.5rem}.lg\:-mt-12{margin-top:-3rem}.lg\:-mr-12{margin-right:-3rem}.lg\:-mb-12{margin-bottom:-3rem}.lg\:-ml-12{margin-left:-3rem}.lg\:-mt-16{margin-top:-4rem}.lg\:-mr-16{margin-right:-4rem}.lg\:-mb-16{margin-bottom:-4rem}.lg\:-ml-16{margin-left:-4rem}.lg\:-mt-20{margin-top:-5rem}.lg\:-mr-20{margin-right:-5rem}.lg\:-mb-20{margin-bottom:-5rem}.lg\:-ml-20{margin-left:-5rem}.lg\:-mt-24{margin-top:-6rem}.lg\:-mr-24{margin-right:-6rem}.lg\:-mb-24{margin-bottom:-6rem}.lg\:-ml-24{margin-left:-6rem}.lg\:-mt-32{margin-top:-8rem}.lg\:-mr-32{margin-right:-8rem}.lg\:-mb-32{margin-bottom:-8rem}.lg\:-ml-32{margin-left:-8rem}.lg\:-mt-40{margin-top:-10rem}.lg\:-mr-40{margin-right:-10rem}.lg\:-mb-40{margin-bottom:-10rem}.lg\:-ml-40{margin-left:-10rem}.lg\:-mt-48{margin-top:-12rem}.lg\:-mr-48{margin-right:-12rem}.lg\:-mb-48{margin-bottom:-12rem}.lg\:-ml-48{margin-left:-12rem}.lg\:-mt-56{margin-top:-14rem}.lg\:-mr-56{margin-right:-14rem}.lg\:-mb-56{margin-bottom:-14rem}.lg\:-ml-56{margin-left:-14rem}.lg\:-mt-64{margin-top:-16rem}.lg\:-mr-64{margin-right:-16rem}.lg\:-mb-64{margin-bottom:-16rem}.lg\:-ml-64{margin-left:-16rem}.lg\:-mt-px{margin-top:-1px}.lg\:-mr-px{margin-right:-1px}.lg\:-mb-px{margin-bottom:-1px}.lg\:-ml-px{margin-left:-1px}.lg\:max-h-full{max-height:100%}.lg\:max-h-screen{max-height:100vh}.lg\:max-w-none{max-width:none}.lg\:max-w-xs{max-width:20rem}.lg\:max-w-sm{max-width:24rem}.lg\:max-w-md{max-width:28rem}.lg\:max-w-lg{max-width:32rem}.lg\:max-w-xl{max-width:36rem}.lg\:max-w-2xl{max-width:42rem}.lg\:max-w-3xl{max-width:48rem}.lg\:max-w-4xl{max-width:56rem}.lg\:max-w-5xl{max-width:64rem}.lg\:max-w-6xl{max-width:72rem}.lg\:max-w-full{max-width:100%}.lg\:max-w-screen-sm{max-width:640px}.lg\:max-w-screen-md{max-width:768px}.lg\:max-w-screen-lg{max-width:1024px}.lg\:max-w-screen-xl{max-width:1280px}.lg\:min-h-0{min-height:0}.lg\:min-h-full{min-height:100%}.lg\:min-h-screen{min-height:100vh}.lg\:min-w-0{min-width:0}.lg\:min-w-full{min-width:100%}.lg\:object-contain{object-fit:contain}.lg\:object-cover{object-fit:cover}.lg\:object-fill{object-fit:fill}.lg\:object-none{object-fit:none}.lg\:object-scale-down{object-fit:scale-down}.lg\:object-bottom{object-position:bottom}.lg\:object-center{object-position:center}.lg\:object-left{object-position:left}.lg\:object-left-bottom{object-position:left bottom}.lg\:object-left-top{object-position:left top}.lg\:object-right{object-position:right}.lg\:object-right-bottom{object-position:right bottom}.lg\:object-right-top{object-position:right top}.lg\:object-top{object-position:top}.lg\:opacity-0{opacity:0}.lg\:opacity-25{opacity:.25}.lg\:opacity-50{opacity:.5}.lg\:opacity-75{opacity:.75}.lg\:opacity-100{opacity:1}.lg\:hover\:opacity-0:hover{opacity:0}.lg\:hover\:opacity-25:hover{opacity:.25}.lg\:hover\:opacity-50:hover{opacity:.5}.lg\:hover\:opacity-75:hover{opacity:.75}.lg\:hover\:opacity-100:hover{opacity:1}.lg\:focus\:opacity-0:focus{opacity:0}.lg\:focus\:opacity-25:focus{opacity:.25}.lg\:focus\:opacity-50:focus{opacity:.5}.lg\:focus\:opacity-75:focus{opacity:.75}.lg\:focus\:opacity-100:focus{opacity:1}.lg\:outline-none{outline:2px solid transparent;outline-offset:2px}.lg\:outline-white{outline:2px dotted #fff;outline-offset:2px}.lg\:outline-black{outline:2px dotted #000;outline-offset:2px}.lg\:focus\:outline-none:focus{outline:2px solid transparent;outline-offset:2px}.lg\:focus\:outline-white:focus{outline:2px dotted #fff;outline-offset:2px}.lg\:focus\:outline-black:focus{outline:2px dotted #000;outline-offset:2px}.lg\:overflow-auto{overflow:auto}.lg\:overflow-hidden{overflow:hidden}.lg\:overflow-visible{overflow:visible}.lg\:overflow-scroll{overflow:scroll}.lg\:overflow-x-auto{overflow-x:auto}.lg\:overflow-y-auto{overflow-y:auto}.lg\:overflow-x-hidden{overflow-x:hidden}.lg\:overflow-y-hidden{overflow-y:hidden}.lg\:overflow-x-visible{overflow-x:visible}.lg\:overflow-y-visible{overflow-y:visible}.lg\:overflow-x-scroll{overflow-x:scroll}.lg\:overflow-y-scroll{overflow-y:scroll}.lg\:scrolling-touch{-webkit-overflow-scrolling:touch}.lg\:scrolling-auto{-webkit-overflow-scrolling:auto}.lg\:overscroll-auto{-ms-scroll-chaining:chained;overscroll-behavior:auto}.lg\:overscroll-contain{-ms-scroll-chaining:none;overscroll-behavior:contain}.lg\:overscroll-none{-ms-scroll-chaining:none;overscroll-behavior:none}.lg\:overscroll-y-auto{overscroll-behavior-y:auto}.lg\:overscroll-y-contain{overscroll-behavior-y:contain}.lg\:overscroll-y-none{overscroll-behavior-y:none}.lg\:overscroll-x-auto{overscroll-behavior-x:auto}.lg\:overscroll-x-contain{overscroll-behavior-x:contain}.lg\:overscroll-x-none{overscroll-behavior-x:none}.lg\:p-0{padding:0}.lg\:p-1{padding:.25rem}.lg\:p-2{padding:.5rem}.lg\:p-3{padding:.75rem}.lg\:p-4{padding:1rem}.lg\:p-5{padding:1.25rem}.lg\:p-6{padding:1.5rem}.lg\:p-8{padding:2rem}.lg\:p-10{padding:2.5rem}.lg\:p-12{padding:3rem}.lg\:p-16{padding:4rem}.lg\:p-20{padding:5rem}.lg\:p-24{padding:6rem}.lg\:p-32{padding:8rem}.lg\:p-40{padding:10rem}.lg\:p-48{padding:12rem}.lg\:p-56{padding:14rem}.lg\:p-64{padding:16rem}.lg\:p-px{padding:1px}.lg\:py-0{padding-top:0;padding-bottom:0}.lg\:px-0{padding-left:0;padding-right:0}.lg\:py-1{padding-top:.25rem;padding-bottom:.25rem}.lg\:px-1{padding-left:.25rem;padding-right:.25rem}.lg\:py-2{padding-top:.5rem;padding-bottom:.5rem}.lg\:px-2{padding-left:.5rem;padding-right:.5rem}.lg\:py-3{padding-top:.75rem;padding-bottom:.75rem}.lg\:px-3{padding-left:.75rem;padding-right:.75rem}.lg\:py-4{padding-top:1rem;padding-bottom:1rem}.lg\:px-4{padding-left:1rem;padding-right:1rem}.lg\:py-5{padding-top:1.25rem;padding-bottom:1.25rem}.lg\:px-5{padding-left:1.25rem;padding-right:1.25rem}.lg\:py-6{padding-top:1.5rem;padding-bottom:1.5rem}.lg\:px-6{padding-left:1.5rem;padding-right:1.5rem}.lg\:py-8{padding-top:2rem;padding-bottom:2rem}.lg\:px-8{padding-left:2rem;padding-right:2rem}.lg\:py-10{padding-top:2.5rem;padding-bottom:2.5rem}.lg\:px-10{padding-left:2.5rem;padding-right:2.5rem}.lg\:py-12{padding-top:3rem;padding-bottom:3rem}.lg\:px-12{padding-left:3rem;padding-right:3rem}.lg\:py-16{padding-top:4rem;padding-bottom:4rem}.lg\:px-16{padding-left:4rem;padding-right:4rem}.lg\:py-20{padding-top:5rem;padding-bottom:5rem}.lg\:px-20{padding-left:5rem;padding-right:5rem}.lg\:py-24{padding-top:6rem;padding-bottom:6rem}.lg\:px-24{padding-left:6rem;padding-right:6rem}.lg\:py-32{padding-top:8rem;padding-bottom:8rem}.lg\:px-32{padding-left:8rem;padding-right:8rem}.lg\:py-40{padding-top:10rem;padding-bottom:10rem}.lg\:px-40{padding-left:10rem;padding-right:10rem}.lg\:py-48{padding-top:12rem;padding-bottom:12rem}.lg\:px-48{padding-left:12rem;padding-right:12rem}.lg\:py-56{padding-top:14rem;padding-bottom:14rem}.lg\:px-56{padding-left:14rem;padding-right:14rem}.lg\:py-64{padding-top:16rem;padding-bottom:16rem}.lg\:px-64{padding-left:16rem;padding-right:16rem}.lg\:py-px{padding-top:1px;padding-bottom:1px}.lg\:px-px{padding-left:1px;padding-right:1px}.lg\:pt-0{padding-top:0}.lg\:pr-0{padding-right:0}.lg\:pb-0{padding-bottom:0}.lg\:pl-0{padding-left:0}.lg\:pt-1{padding-top:.25rem}.lg\:pr-1{padding-right:.25rem}.lg\:pb-1{padding-bottom:.25rem}.lg\:pl-1{padding-left:.25rem}.lg\:pt-2{padding-top:.5rem}.lg\:pr-2{padding-right:.5rem}.lg\:pb-2{padding-bottom:.5rem}.lg\:pl-2{padding-left:.5rem}.lg\:pt-3{padding-top:.75rem}.lg\:pr-3{padding-right:.75rem}.lg\:pb-3{padding-bottom:.75rem}.lg\:pl-3{padding-left:.75rem}.lg\:pt-4{padding-top:1rem}.lg\:pr-4{padding-right:1rem}.lg\:pb-4{padding-bottom:1rem}.lg\:pl-4{padding-left:1rem}.lg\:pt-5{padding-top:1.25rem}.lg\:pr-5{padding-right:1.25rem}.lg\:pb-5{padding-bottom:1.25rem}.lg\:pl-5{padding-left:1.25rem}.lg\:pt-6{padding-top:1.5rem}.lg\:pr-6{padding-right:1.5rem}.lg\:pb-6{padding-bottom:1.5rem}.lg\:pl-6{padding-left:1.5rem}.lg\:pt-8{padding-top:2rem}.lg\:pr-8{padding-right:2rem}.lg\:pb-8{padding-bottom:2rem}.lg\:pl-8{padding-left:2rem}.lg\:pt-10{padding-top:2.5rem}.lg\:pr-10{padding-right:2.5rem}.lg\:pb-10{padding-bottom:2.5rem}.lg\:pl-10{padding-left:2.5rem}.lg\:pt-12{padding-top:3rem}.lg\:pr-12{padding-right:3rem}.lg\:pb-12{padding-bottom:3rem}.lg\:pl-12{padding-left:3rem}.lg\:pt-16{padding-top:4rem}.lg\:pr-16{padding-right:4rem}.lg\:pb-16{padding-bottom:4rem}.lg\:pl-16{padding-left:4rem}.lg\:pt-20{padding-top:5rem}.lg\:pr-20{padding-right:5rem}.lg\:pb-20{padding-bottom:5rem}.lg\:pl-20{padding-left:5rem}.lg\:pt-24{padding-top:6rem}.lg\:pr-24{padding-right:6rem}.lg\:pb-24{padding-bottom:6rem}.lg\:pl-24{padding-left:6rem}.lg\:pt-32{padding-top:8rem}.lg\:pr-32{padding-right:8rem}.lg\:pb-32{padding-bottom:8rem}.lg\:pl-32{padding-left:8rem}.lg\:pt-40{padding-top:10rem}.lg\:pr-40{padding-right:10rem}.lg\:pb-40{padding-bottom:10rem}.lg\:pl-40{padding-left:10rem}.lg\:pt-48{padding-top:12rem}.lg\:pr-48{padding-right:12rem}.lg\:pb-48{padding-bottom:12rem}.lg\:pl-48{padding-left:12rem}.lg\:pt-56{padding-top:14rem}.lg\:pr-56{padding-right:14rem}.lg\:pb-56{padding-bottom:14rem}.lg\:pl-56{padding-left:14rem}.lg\:pt-64{padding-top:16rem}.lg\:pr-64{padding-right:16rem}.lg\:pb-64{padding-bottom:16rem}.lg\:pl-64{padding-left:16rem}.lg\:pt-px{padding-top:1px}.lg\:pr-px{padding-right:1px}.lg\:pb-px{padding-bottom:1px}.lg\:pl-px{padding-left:1px}.lg\:placeholder-transparent:-ms-input-placeholder{color:transparent}.lg\:placeholder-transparent::-ms-input-placeholder{color:transparent}.lg\:placeholder-transparent::placeholder{color:transparent}.lg\:placeholder-current:-ms-input-placeholder{color:currentColor}.lg\:placeholder-current::-ms-input-placeholder{color:currentColor}.lg\:placeholder-current::placeholder{color:currentColor}.lg\:placeholder-black:-ms-input-placeholder{--placeholder-opacity:1;color:#000;color:rgba(0,0,0,var(--placeholder-opacity))}.lg\:placeholder-black::-ms-input-placeholder{--placeholder-opacity:1;color:#000;color:rgba(0,0,0,var(--placeholder-opacity))}.lg\:placeholder-black::placeholder{--placeholder-opacity:1;color:#000;color:rgba(0,0,0,var(--placeholder-opacity))}.lg\:placeholder-white:-ms-input-placeholder{--placeholder-opacity:1;color:#fff;color:rgba(255,255,255,var(--placeholder-opacity))}.lg\:placeholder-white::-ms-input-placeholder{--placeholder-opacity:1;color:#fff;color:rgba(255,255,255,var(--placeholder-opacity))}.lg\:placeholder-white::placeholder{--placeholder-opacity:1;color:#fff;color:rgba(255,255,255,var(--placeholder-opacity))}.lg\:placeholder-gray-100:-ms-input-placeholder{--placeholder-opacity:1;color:#f7fafc;color:rgba(247,250,252,var(--placeholder-opacity))}.lg\:placeholder-gray-100::-ms-input-placeholder{--placeholder-opacity:1;color:#f7fafc;color:rgba(247,250,252,var(--placeholder-opacity))}.lg\:placeholder-gray-100::placeholder{--placeholder-opacity:1;color:#f7fafc;color:rgba(247,250,252,var(--placeholder-opacity))}.lg\:placeholder-gray-200:-ms-input-placeholder{--placeholder-opacity:1;color:#edf2f7;color:rgba(237,242,247,var(--placeholder-opacity))}.lg\:placeholder-gray-200::-ms-input-placeholder{--placeholder-opacity:1;color:#edf2f7;color:rgba(237,242,247,var(--placeholder-opacity))}.lg\:placeholder-gray-200::placeholder{--placeholder-opacity:1;color:#edf2f7;color:rgba(237,242,247,var(--placeholder-opacity))}.lg\:placeholder-gray-300:-ms-input-placeholder{--placeholder-opacity:1;color:#e2e8f0;color:rgba(226,232,240,var(--placeholder-opacity))}.lg\:placeholder-gray-300::-ms-input-placeholder{--placeholder-opacity:1;color:#e2e8f0;color:rgba(226,232,240,var(--placeholder-opacity))}.lg\:placeholder-gray-300::placeholder{--placeholder-opacity:1;color:#e2e8f0;color:rgba(226,232,240,var(--placeholder-opacity))}.lg\:placeholder-gray-400:-ms-input-placeholder{--placeholder-opacity:1;color:#cbd5e0;color:rgba(203,213,224,var(--placeholder-opacity))}.lg\:placeholder-gray-400::-ms-input-placeholder{--placeholder-opacity:1;color:#cbd5e0;color:rgba(203,213,224,var(--placeholder-opacity))}.lg\:placeholder-gray-400::placeholder{--placeholder-opacity:1;color:#cbd5e0;color:rgba(203,213,224,var(--placeholder-opacity))}.lg\:placeholder-gray-500:-ms-input-placeholder{--placeholder-opacity:1;color:#a0aec0;color:rgba(160,174,192,var(--placeholder-opacity))}.lg\:placeholder-gray-500::-ms-input-placeholder{--placeholder-opacity:1;color:#a0aec0;color:rgba(160,174,192,var(--placeholder-opacity))}.lg\:placeholder-gray-500::placeholder{--placeholder-opacity:1;color:#a0aec0;color:rgba(160,174,192,var(--placeholder-opacity))}.lg\:placeholder-gray-600:-ms-input-placeholder{--placeholder-opacity:1;color:#718096;color:rgba(113,128,150,var(--placeholder-opacity))}.lg\:placeholder-gray-600::-ms-input-placeholder{--placeholder-opacity:1;color:#718096;color:rgba(113,128,150,var(--placeholder-opacity))}.lg\:placeholder-gray-600::placeholder{--placeholder-opacity:1;color:#718096;color:rgba(113,128,150,var(--placeholder-opacity))}.lg\:placeholder-gray-700:-ms-input-placeholder{--placeholder-opacity:1;color:#4a5568;color:rgba(74,85,104,var(--placeholder-opacity))}.lg\:placeholder-gray-700::-ms-input-placeholder{--placeholder-opacity:1;color:#4a5568;color:rgba(74,85,104,var(--placeholder-opacity))}.lg\:placeholder-gray-700::placeholder{--placeholder-opacity:1;color:#4a5568;color:rgba(74,85,104,var(--placeholder-opacity))}.lg\:placeholder-gray-800:-ms-input-placeholder{--placeholder-opacity:1;color:#2d3748;color:rgba(45,55,72,var(--placeholder-opacity))}.lg\:placeholder-gray-800::-ms-input-placeholder{--placeholder-opacity:1;color:#2d3748;color:rgba(45,55,72,var(--placeholder-opacity))}.lg\:placeholder-gray-800::placeholder{--placeholder-opacity:1;color:#2d3748;color:rgba(45,55,72,var(--placeholder-opacity))}.lg\:placeholder-gray-900:-ms-input-placeholder{--placeholder-opacity:1;color:#1a202c;color:rgba(26,32,44,var(--placeholder-opacity))}.lg\:placeholder-gray-900::-ms-input-placeholder{--placeholder-opacity:1;color:#1a202c;color:rgba(26,32,44,var(--placeholder-opacity))}.lg\:placeholder-gray-900::placeholder{--placeholder-opacity:1;color:#1a202c;color:rgba(26,32,44,var(--placeholder-opacity))}.lg\:placeholder-red-100:-ms-input-placeholder{--placeholder-opacity:1;color:#fff5f5;color:rgba(255,245,245,var(--placeholder-opacity))}.lg\:placeholder-red-100::-ms-input-placeholder{--placeholder-opacity:1;color:#fff5f5;color:rgba(255,245,245,var(--placeholder-opacity))}.lg\:placeholder-red-100::placeholder{--placeholder-opacity:1;color:#fff5f5;color:rgba(255,245,245,var(--placeholder-opacity))}.lg\:placeholder-red-200:-ms-input-placeholder{--placeholder-opacity:1;color:#fed7d7;color:rgba(254,215,215,var(--placeholder-opacity))}.lg\:placeholder-red-200::-ms-input-placeholder{--placeholder-opacity:1;color:#fed7d7;color:rgba(254,215,215,var(--placeholder-opacity))}.lg\:placeholder-red-200::placeholder{--placeholder-opacity:1;color:#fed7d7;color:rgba(254,215,215,var(--placeholder-opacity))}.lg\:placeholder-red-300:-ms-input-placeholder{--placeholder-opacity:1;color:#feb2b2;color:rgba(254,178,178,var(--placeholder-opacity))}.lg\:placeholder-red-300::-ms-input-placeholder{--placeholder-opacity:1;color:#feb2b2;color:rgba(254,178,178,var(--placeholder-opacity))}.lg\:placeholder-red-300::placeholder{--placeholder-opacity:1;color:#feb2b2;color:rgba(254,178,178,var(--placeholder-opacity))}.lg\:placeholder-red-400:-ms-input-placeholder{--placeholder-opacity:1;color:#fc8181;color:rgba(252,129,129,var(--placeholder-opacity))}.lg\:placeholder-red-400::-ms-input-placeholder{--placeholder-opacity:1;color:#fc8181;color:rgba(252,129,129,var(--placeholder-opacity))}.lg\:placeholder-red-400::placeholder{--placeholder-opacity:1;color:#fc8181;color:rgba(252,129,129,var(--placeholder-opacity))}.lg\:placeholder-red-500:-ms-input-placeholder{--placeholder-opacity:1;color:#f56565;color:rgba(245,101,101,var(--placeholder-opacity))}.lg\:placeholder-red-500::-ms-input-placeholder{--placeholder-opacity:1;color:#f56565;color:rgba(245,101,101,var(--placeholder-opacity))}.lg\:placeholder-red-500::placeholder{--placeholder-opacity:1;color:#f56565;color:rgba(245,101,101,var(--placeholder-opacity))}.lg\:placeholder-red-600:-ms-input-placeholder{--placeholder-opacity:1;color:#e53e3e;color:rgba(229,62,62,var(--placeholder-opacity))}.lg\:placeholder-red-600::-ms-input-placeholder{--placeholder-opacity:1;color:#e53e3e;color:rgba(229,62,62,var(--placeholder-opacity))}.lg\:placeholder-red-600::placeholder{--placeholder-opacity:1;color:#e53e3e;color:rgba(229,62,62,var(--placeholder-opacity))}.lg\:placeholder-red-700:-ms-input-placeholder{--placeholder-opacity:1;color:#c53030;color:rgba(197,48,48,var(--placeholder-opacity))}.lg\:placeholder-red-700::-ms-input-placeholder{--placeholder-opacity:1;color:#c53030;color:rgba(197,48,48,var(--placeholder-opacity))}.lg\:placeholder-red-700::placeholder{--placeholder-opacity:1;color:#c53030;color:rgba(197,48,48,var(--placeholder-opacity))}.lg\:placeholder-red-800:-ms-input-placeholder{--placeholder-opacity:1;color:#9b2c2c;color:rgba(155,44,44,var(--placeholder-opacity))}.lg\:placeholder-red-800::-ms-input-placeholder{--placeholder-opacity:1;color:#9b2c2c;color:rgba(155,44,44,var(--placeholder-opacity))}.lg\:placeholder-red-800::placeholder{--placeholder-opacity:1;color:#9b2c2c;color:rgba(155,44,44,var(--placeholder-opacity))}.lg\:placeholder-red-900:-ms-input-placeholder{--placeholder-opacity:1;color:#742a2a;color:rgba(116,42,42,var(--placeholder-opacity))}.lg\:placeholder-red-900::-ms-input-placeholder{--placeholder-opacity:1;color:#742a2a;color:rgba(116,42,42,var(--placeholder-opacity))}.lg\:placeholder-red-900::placeholder{--placeholder-opacity:1;color:#742a2a;color:rgba(116,42,42,var(--placeholder-opacity))}.lg\:placeholder-orange-100:-ms-input-placeholder{--placeholder-opacity:1;color:#fffaf0;color:rgba(255,250,240,var(--placeholder-opacity))}.lg\:placeholder-orange-100::-ms-input-placeholder{--placeholder-opacity:1;color:#fffaf0;color:rgba(255,250,240,var(--placeholder-opacity))}.lg\:placeholder-orange-100::placeholder{--placeholder-opacity:1;color:#fffaf0;color:rgba(255,250,240,var(--placeholder-opacity))}.lg\:placeholder-orange-200:-ms-input-placeholder{--placeholder-opacity:1;color:#feebc8;color:rgba(254,235,200,var(--placeholder-opacity))}.lg\:placeholder-orange-200::-ms-input-placeholder{--placeholder-opacity:1;color:#feebc8;color:rgba(254,235,200,var(--placeholder-opacity))}.lg\:placeholder-orange-200::placeholder{--placeholder-opacity:1;color:#feebc8;color:rgba(254,235,200,var(--placeholder-opacity))}.lg\:placeholder-orange-300:-ms-input-placeholder{--placeholder-opacity:1;color:#fbd38d;color:rgba(251,211,141,var(--placeholder-opacity))}.lg\:placeholder-orange-300::-ms-input-placeholder{--placeholder-opacity:1;color:#fbd38d;color:rgba(251,211,141,var(--placeholder-opacity))}.lg\:placeholder-orange-300::placeholder{--placeholder-opacity:1;color:#fbd38d;color:rgba(251,211,141,var(--placeholder-opacity))}.lg\:placeholder-orange-400:-ms-input-placeholder{--placeholder-opacity:1;color:#f6ad55;color:rgba(246,173,85,var(--placeholder-opacity))}.lg\:placeholder-orange-400::-ms-input-placeholder{--placeholder-opacity:1;color:#f6ad55;color:rgba(246,173,85,var(--placeholder-opacity))}.lg\:placeholder-orange-400::placeholder{--placeholder-opacity:1;color:#f6ad55;color:rgba(246,173,85,var(--placeholder-opacity))}.lg\:placeholder-orange-500:-ms-input-placeholder{--placeholder-opacity:1;color:#ed8936;color:rgba(237,137,54,var(--placeholder-opacity))}.lg\:placeholder-orange-500::-ms-input-placeholder{--placeholder-opacity:1;color:#ed8936;color:rgba(237,137,54,var(--placeholder-opacity))}.lg\:placeholder-orange-500::placeholder{--placeholder-opacity:1;color:#ed8936;color:rgba(237,137,54,var(--placeholder-opacity))}.lg\:placeholder-orange-600:-ms-input-placeholder{--placeholder-opacity:1;color:#dd6b20;color:rgba(221,107,32,var(--placeholder-opacity))}.lg\:placeholder-orange-600::-ms-input-placeholder{--placeholder-opacity:1;color:#dd6b20;color:rgba(221,107,32,var(--placeholder-opacity))}.lg\:placeholder-orange-600::placeholder{--placeholder-opacity:1;color:#dd6b20;color:rgba(221,107,32,var(--placeholder-opacity))}.lg\:placeholder-orange-700:-ms-input-placeholder{--placeholder-opacity:1;color:#c05621;color:rgba(192,86,33,var(--placeholder-opacity))}.lg\:placeholder-orange-700::-ms-input-placeholder{--placeholder-opacity:1;color:#c05621;color:rgba(192,86,33,var(--placeholder-opacity))}.lg\:placeholder-orange-700::placeholder{--placeholder-opacity:1;color:#c05621;color:rgba(192,86,33,var(--placeholder-opacity))}.lg\:placeholder-orange-800:-ms-input-placeholder{--placeholder-opacity:1;color:#9c4221;color:rgba(156,66,33,var(--placeholder-opacity))}.lg\:placeholder-orange-800::-ms-input-placeholder{--placeholder-opacity:1;color:#9c4221;color:rgba(156,66,33,var(--placeholder-opacity))}.lg\:placeholder-orange-800::placeholder{--placeholder-opacity:1;color:#9c4221;color:rgba(156,66,33,var(--placeholder-opacity))}.lg\:placeholder-orange-900:-ms-input-placeholder{--placeholder-opacity:1;color:#7b341e;color:rgba(123,52,30,var(--placeholder-opacity))}.lg\:placeholder-orange-900::-ms-input-placeholder{--placeholder-opacity:1;color:#7b341e;color:rgba(123,52,30,var(--placeholder-opacity))}.lg\:placeholder-orange-900::placeholder{--placeholder-opacity:1;color:#7b341e;color:rgba(123,52,30,var(--placeholder-opacity))}.lg\:placeholder-yellow-100:-ms-input-placeholder{--placeholder-opacity:1;color:ivory;color:rgba(255,255,240,var(--placeholder-opacity))}.lg\:placeholder-yellow-100::-ms-input-placeholder{--placeholder-opacity:1;color:ivory;color:rgba(255,255,240,var(--placeholder-opacity))}.lg\:placeholder-yellow-100::placeholder{--placeholder-opacity:1;color:ivory;color:rgba(255,255,240,var(--placeholder-opacity))}.lg\:placeholder-yellow-200:-ms-input-placeholder{--placeholder-opacity:1;color:#fefcbf;color:rgba(254,252,191,var(--placeholder-opacity))}.lg\:placeholder-yellow-200::-ms-input-placeholder{--placeholder-opacity:1;color:#fefcbf;color:rgba(254,252,191,var(--placeholder-opacity))}.lg\:placeholder-yellow-200::placeholder{--placeholder-opacity:1;color:#fefcbf;color:rgba(254,252,191,var(--placeholder-opacity))}.lg\:placeholder-yellow-300:-ms-input-placeholder{--placeholder-opacity:1;color:#faf089;color:rgba(250,240,137,var(--placeholder-opacity))}.lg\:placeholder-yellow-300::-ms-input-placeholder{--placeholder-opacity:1;color:#faf089;color:rgba(250,240,137,var(--placeholder-opacity))}.lg\:placeholder-yellow-300::placeholder{--placeholder-opacity:1;color:#faf089;color:rgba(250,240,137,var(--placeholder-opacity))}.lg\:placeholder-yellow-400:-ms-input-placeholder{--placeholder-opacity:1;color:#f6e05e;color:rgba(246,224,94,var(--placeholder-opacity))}.lg\:placeholder-yellow-400::-ms-input-placeholder{--placeholder-opacity:1;color:#f6e05e;color:rgba(246,224,94,var(--placeholder-opacity))}.lg\:placeholder-yellow-400::placeholder{--placeholder-opacity:1;color:#f6e05e;color:rgba(246,224,94,var(--placeholder-opacity))}.lg\:placeholder-yellow-500:-ms-input-placeholder{--placeholder-opacity:1;color:#ecc94b;color:rgba(236,201,75,var(--placeholder-opacity))}.lg\:placeholder-yellow-500::-ms-input-placeholder{--placeholder-opacity:1;color:#ecc94b;color:rgba(236,201,75,var(--placeholder-opacity))}.lg\:placeholder-yellow-500::placeholder{--placeholder-opacity:1;color:#ecc94b;color:rgba(236,201,75,var(--placeholder-opacity))}.lg\:placeholder-yellow-600:-ms-input-placeholder{--placeholder-opacity:1;color:#d69e2e;color:rgba(214,158,46,var(--placeholder-opacity))}.lg\:placeholder-yellow-600::-ms-input-placeholder{--placeholder-opacity:1;color:#d69e2e;color:rgba(214,158,46,var(--placeholder-opacity))}.lg\:placeholder-yellow-600::placeholder{--placeholder-opacity:1;color:#d69e2e;color:rgba(214,158,46,var(--placeholder-opacity))}.lg\:placeholder-yellow-700:-ms-input-placeholder{--placeholder-opacity:1;color:#b7791f;color:rgba(183,121,31,var(--placeholder-opacity))}.lg\:placeholder-yellow-700::-ms-input-placeholder{--placeholder-opacity:1;color:#b7791f;color:rgba(183,121,31,var(--placeholder-opacity))}.lg\:placeholder-yellow-700::placeholder{--placeholder-opacity:1;color:#b7791f;color:rgba(183,121,31,var(--placeholder-opacity))}.lg\:placeholder-yellow-800:-ms-input-placeholder{--placeholder-opacity:1;color:#975a16;color:rgba(151,90,22,var(--placeholder-opacity))}.lg\:placeholder-yellow-800::-ms-input-placeholder{--placeholder-opacity:1;color:#975a16;color:rgba(151,90,22,var(--placeholder-opacity))}.lg\:placeholder-yellow-800::placeholder{--placeholder-opacity:1;color:#975a16;color:rgba(151,90,22,var(--placeholder-opacity))}.lg\:placeholder-yellow-900:-ms-input-placeholder{--placeholder-opacity:1;color:#744210;color:rgba(116,66,16,var(--placeholder-opacity))}.lg\:placeholder-yellow-900::-ms-input-placeholder{--placeholder-opacity:1;color:#744210;color:rgba(116,66,16,var(--placeholder-opacity))}.lg\:placeholder-yellow-900::placeholder{--placeholder-opacity:1;color:#744210;color:rgba(116,66,16,var(--placeholder-opacity))}.lg\:placeholder-green-100:-ms-input-placeholder{--placeholder-opacity:1;color:#f0fff4;color:rgba(240,255,244,var(--placeholder-opacity))}.lg\:placeholder-green-100::-ms-input-placeholder{--placeholder-opacity:1;color:#f0fff4;color:rgba(240,255,244,var(--placeholder-opacity))}.lg\:placeholder-green-100::placeholder{--placeholder-opacity:1;color:#f0fff4;color:rgba(240,255,244,var(--placeholder-opacity))}.lg\:placeholder-green-200:-ms-input-placeholder{--placeholder-opacity:1;color:#c6f6d5;color:rgba(198,246,213,var(--placeholder-opacity))}.lg\:placeholder-green-200::-ms-input-placeholder{--placeholder-opacity:1;color:#c6f6d5;color:rgba(198,246,213,var(--placeholder-opacity))}.lg\:placeholder-green-200::placeholder{--placeholder-opacity:1;color:#c6f6d5;color:rgba(198,246,213,var(--placeholder-opacity))}.lg\:placeholder-green-300:-ms-input-placeholder{--placeholder-opacity:1;color:#9ae6b4;color:rgba(154,230,180,var(--placeholder-opacity))}.lg\:placeholder-green-300::-ms-input-placeholder{--placeholder-opacity:1;color:#9ae6b4;color:rgba(154,230,180,var(--placeholder-opacity))}.lg\:placeholder-green-300::placeholder{--placeholder-opacity:1;color:#9ae6b4;color:rgba(154,230,180,var(--placeholder-opacity))}.lg\:placeholder-green-400:-ms-input-placeholder{--placeholder-opacity:1;color:#68d391;color:rgba(104,211,145,var(--placeholder-opacity))}.lg\:placeholder-green-400::-ms-input-placeholder{--placeholder-opacity:1;color:#68d391;color:rgba(104,211,145,var(--placeholder-opacity))}.lg\:placeholder-green-400::placeholder{--placeholder-opacity:1;color:#68d391;color:rgba(104,211,145,var(--placeholder-opacity))}.lg\:placeholder-green-500:-ms-input-placeholder{--placeholder-opacity:1;color:#48bb78;color:rgba(72,187,120,var(--placeholder-opacity))}.lg\:placeholder-green-500::-ms-input-placeholder{--placeholder-opacity:1;color:#48bb78;color:rgba(72,187,120,var(--placeholder-opacity))}.lg\:placeholder-green-500::placeholder{--placeholder-opacity:1;color:#48bb78;color:rgba(72,187,120,var(--placeholder-opacity))}.lg\:placeholder-green-600:-ms-input-placeholder{--placeholder-opacity:1;color:#38a169;color:rgba(56,161,105,var(--placeholder-opacity))}.lg\:placeholder-green-600::-ms-input-placeholder{--placeholder-opacity:1;color:#38a169;color:rgba(56,161,105,var(--placeholder-opacity))}.lg\:placeholder-green-600::placeholder{--placeholder-opacity:1;color:#38a169;color:rgba(56,161,105,var(--placeholder-opacity))}.lg\:placeholder-green-700:-ms-input-placeholder{--placeholder-opacity:1;color:#2f855a;color:rgba(47,133,90,var(--placeholder-opacity))}.lg\:placeholder-green-700::-ms-input-placeholder{--placeholder-opacity:1;color:#2f855a;color:rgba(47,133,90,var(--placeholder-opacity))}.lg\:placeholder-green-700::placeholder{--placeholder-opacity:1;color:#2f855a;color:rgba(47,133,90,var(--placeholder-opacity))}.lg\:placeholder-green-800:-ms-input-placeholder{--placeholder-opacity:1;color:#276749;color:rgba(39,103,73,var(--placeholder-opacity))}.lg\:placeholder-green-800::-ms-input-placeholder{--placeholder-opacity:1;color:#276749;color:rgba(39,103,73,var(--placeholder-opacity))}.lg\:placeholder-green-800::placeholder{--placeholder-opacity:1;color:#276749;color:rgba(39,103,73,var(--placeholder-opacity))}.lg\:placeholder-green-900:-ms-input-placeholder{--placeholder-opacity:1;color:#22543d;color:rgba(34,84,61,var(--placeholder-opacity))}.lg\:placeholder-green-900::-ms-input-placeholder{--placeholder-opacity:1;color:#22543d;color:rgba(34,84,61,var(--placeholder-opacity))}.lg\:placeholder-green-900::placeholder{--placeholder-opacity:1;color:#22543d;color:rgba(34,84,61,var(--placeholder-opacity))}.lg\:placeholder-teal-100:-ms-input-placeholder{--placeholder-opacity:1;color:#e6fffa;color:rgba(230,255,250,var(--placeholder-opacity))}.lg\:placeholder-teal-100::-ms-input-placeholder{--placeholder-opacity:1;color:#e6fffa;color:rgba(230,255,250,var(--placeholder-opacity))}.lg\:placeholder-teal-100::placeholder{--placeholder-opacity:1;color:#e6fffa;color:rgba(230,255,250,var(--placeholder-opacity))}.lg\:placeholder-teal-200:-ms-input-placeholder{--placeholder-opacity:1;color:#b2f5ea;color:rgba(178,245,234,var(--placeholder-opacity))}.lg\:placeholder-teal-200::-ms-input-placeholder{--placeholder-opacity:1;color:#b2f5ea;color:rgba(178,245,234,var(--placeholder-opacity))}.lg\:placeholder-teal-200::placeholder{--placeholder-opacity:1;color:#b2f5ea;color:rgba(178,245,234,var(--placeholder-opacity))}.lg\:placeholder-teal-300:-ms-input-placeholder{--placeholder-opacity:1;color:#81e6d9;color:rgba(129,230,217,var(--placeholder-opacity))}.lg\:placeholder-teal-300::-ms-input-placeholder{--placeholder-opacity:1;color:#81e6d9;color:rgba(129,230,217,var(--placeholder-opacity))}.lg\:placeholder-teal-300::placeholder{--placeholder-opacity:1;color:#81e6d9;color:rgba(129,230,217,var(--placeholder-opacity))}.lg\:placeholder-teal-400:-ms-input-placeholder{--placeholder-opacity:1;color:#4fd1c5;color:rgba(79,209,197,var(--placeholder-opacity))}.lg\:placeholder-teal-400::-ms-input-placeholder{--placeholder-opacity:1;color:#4fd1c5;color:rgba(79,209,197,var(--placeholder-opacity))}.lg\:placeholder-teal-400::placeholder{--placeholder-opacity:1;color:#4fd1c5;color:rgba(79,209,197,var(--placeholder-opacity))}.lg\:placeholder-teal-500:-ms-input-placeholder{--placeholder-opacity:1;color:#38b2ac;color:rgba(56,178,172,var(--placeholder-opacity))}.lg\:placeholder-teal-500::-ms-input-placeholder{--placeholder-opacity:1;color:#38b2ac;color:rgba(56,178,172,var(--placeholder-opacity))}.lg\:placeholder-teal-500::placeholder{--placeholder-opacity:1;color:#38b2ac;color:rgba(56,178,172,var(--placeholder-opacity))}.lg\:placeholder-teal-600:-ms-input-placeholder{--placeholder-opacity:1;color:#319795;color:rgba(49,151,149,var(--placeholder-opacity))}.lg\:placeholder-teal-600::-ms-input-placeholder{--placeholder-opacity:1;color:#319795;color:rgba(49,151,149,var(--placeholder-opacity))}.lg\:placeholder-teal-600::placeholder{--placeholder-opacity:1;color:#319795;color:rgba(49,151,149,var(--placeholder-opacity))}.lg\:placeholder-teal-700:-ms-input-placeholder{--placeholder-opacity:1;color:#2c7a7b;color:rgba(44,122,123,var(--placeholder-opacity))}.lg\:placeholder-teal-700::-ms-input-placeholder{--placeholder-opacity:1;color:#2c7a7b;color:rgba(44,122,123,var(--placeholder-opacity))}.lg\:placeholder-teal-700::placeholder{--placeholder-opacity:1;color:#2c7a7b;color:rgba(44,122,123,var(--placeholder-opacity))}.lg\:placeholder-teal-800:-ms-input-placeholder{--placeholder-opacity:1;color:#285e61;color:rgba(40,94,97,var(--placeholder-opacity))}.lg\:placeholder-teal-800::-ms-input-placeholder{--placeholder-opacity:1;color:#285e61;color:rgba(40,94,97,var(--placeholder-opacity))}.lg\:placeholder-teal-800::placeholder{--placeholder-opacity:1;color:#285e61;color:rgba(40,94,97,var(--placeholder-opacity))}.lg\:placeholder-teal-900:-ms-input-placeholder{--placeholder-opacity:1;color:#234e52;color:rgba(35,78,82,var(--placeholder-opacity))}.lg\:placeholder-teal-900::-ms-input-placeholder{--placeholder-opacity:1;color:#234e52;color:rgba(35,78,82,var(--placeholder-opacity))}.lg\:placeholder-teal-900::placeholder{--placeholder-opacity:1;color:#234e52;color:rgba(35,78,82,var(--placeholder-opacity))}.lg\:placeholder-blue-100:-ms-input-placeholder{--placeholder-opacity:1;color:#ebf8ff;color:rgba(235,248,255,var(--placeholder-opacity))}.lg\:placeholder-blue-100::-ms-input-placeholder{--placeholder-opacity:1;color:#ebf8ff;color:rgba(235,248,255,var(--placeholder-opacity))}.lg\:placeholder-blue-100::placeholder{--placeholder-opacity:1;color:#ebf8ff;color:rgba(235,248,255,var(--placeholder-opacity))}.lg\:placeholder-blue-200:-ms-input-placeholder{--placeholder-opacity:1;color:#bee3f8;color:rgba(190,227,248,var(--placeholder-opacity))}.lg\:placeholder-blue-200::-ms-input-placeholder{--placeholder-opacity:1;color:#bee3f8;color:rgba(190,227,248,var(--placeholder-opacity))}.lg\:placeholder-blue-200::placeholder{--placeholder-opacity:1;color:#bee3f8;color:rgba(190,227,248,var(--placeholder-opacity))}.lg\:placeholder-blue-300:-ms-input-placeholder{--placeholder-opacity:1;color:#90cdf4;color:rgba(144,205,244,var(--placeholder-opacity))}.lg\:placeholder-blue-300::-ms-input-placeholder{--placeholder-opacity:1;color:#90cdf4;color:rgba(144,205,244,var(--placeholder-opacity))}.lg\:placeholder-blue-300::placeholder{--placeholder-opacity:1;color:#90cdf4;color:rgba(144,205,244,var(--placeholder-opacity))}.lg\:placeholder-blue-400:-ms-input-placeholder{--placeholder-opacity:1;color:#63b3ed;color:rgba(99,179,237,var(--placeholder-opacity))}.lg\:placeholder-blue-400::-ms-input-placeholder{--placeholder-opacity:1;color:#63b3ed;color:rgba(99,179,237,var(--placeholder-opacity))}.lg\:placeholder-blue-400::placeholder{--placeholder-opacity:1;color:#63b3ed;color:rgba(99,179,237,var(--placeholder-opacity))}.lg\:placeholder-blue-500:-ms-input-placeholder{--placeholder-opacity:1;color:#4299e1;color:rgba(66,153,225,var(--placeholder-opacity))}.lg\:placeholder-blue-500::-ms-input-placeholder{--placeholder-opacity:1;color:#4299e1;color:rgba(66,153,225,var(--placeholder-opacity))}.lg\:placeholder-blue-500::placeholder{--placeholder-opacity:1;color:#4299e1;color:rgba(66,153,225,var(--placeholder-opacity))}.lg\:placeholder-blue-600:-ms-input-placeholder{--placeholder-opacity:1;color:#3182ce;color:rgba(49,130,206,var(--placeholder-opacity))}.lg\:placeholder-blue-600::-ms-input-placeholder{--placeholder-opacity:1;color:#3182ce;color:rgba(49,130,206,var(--placeholder-opacity))}.lg\:placeholder-blue-600::placeholder{--placeholder-opacity:1;color:#3182ce;color:rgba(49,130,206,var(--placeholder-opacity))}.lg\:placeholder-blue-700:-ms-input-placeholder{--placeholder-opacity:1;color:#2b6cb0;color:rgba(43,108,176,var(--placeholder-opacity))}.lg\:placeholder-blue-700::-ms-input-placeholder{--placeholder-opacity:1;color:#2b6cb0;color:rgba(43,108,176,var(--placeholder-opacity))}.lg\:placeholder-blue-700::placeholder{--placeholder-opacity:1;color:#2b6cb0;color:rgba(43,108,176,var(--placeholder-opacity))}.lg\:placeholder-blue-800:-ms-input-placeholder{--placeholder-opacity:1;color:#2c5282;color:rgba(44,82,130,var(--placeholder-opacity))}.lg\:placeholder-blue-800::-ms-input-placeholder{--placeholder-opacity:1;color:#2c5282;color:rgba(44,82,130,var(--placeholder-opacity))}.lg\:placeholder-blue-800::placeholder{--placeholder-opacity:1;color:#2c5282;color:rgba(44,82,130,var(--placeholder-opacity))}.lg\:placeholder-blue-900:-ms-input-placeholder{--placeholder-opacity:1;color:#2a4365;color:rgba(42,67,101,var(--placeholder-opacity))}.lg\:placeholder-blue-900::-ms-input-placeholder{--placeholder-opacity:1;color:#2a4365;color:rgba(42,67,101,var(--placeholder-opacity))}.lg\:placeholder-blue-900::placeholder{--placeholder-opacity:1;color:#2a4365;color:rgba(42,67,101,var(--placeholder-opacity))}.lg\:placeholder-indigo-100:-ms-input-placeholder{--placeholder-opacity:1;color:#ebf4ff;color:rgba(235,244,255,var(--placeholder-opacity))}.lg\:placeholder-indigo-100::-ms-input-placeholder{--placeholder-opacity:1;color:#ebf4ff;color:rgba(235,244,255,var(--placeholder-opacity))}.lg\:placeholder-indigo-100::placeholder{--placeholder-opacity:1;color:#ebf4ff;color:rgba(235,244,255,var(--placeholder-opacity))}.lg\:placeholder-indigo-200:-ms-input-placeholder{--placeholder-opacity:1;color:#c3dafe;color:rgba(195,218,254,var(--placeholder-opacity))}.lg\:placeholder-indigo-200::-ms-input-placeholder{--placeholder-opacity:1;color:#c3dafe;color:rgba(195,218,254,var(--placeholder-opacity))}.lg\:placeholder-indigo-200::placeholder{--placeholder-opacity:1;color:#c3dafe;color:rgba(195,218,254,var(--placeholder-opacity))}.lg\:placeholder-indigo-300:-ms-input-placeholder{--placeholder-opacity:1;color:#a3bffa;color:rgba(163,191,250,var(--placeholder-opacity))}.lg\:placeholder-indigo-300::-ms-input-placeholder{--placeholder-opacity:1;color:#a3bffa;color:rgba(163,191,250,var(--placeholder-opacity))}.lg\:placeholder-indigo-300::placeholder{--placeholder-opacity:1;color:#a3bffa;color:rgba(163,191,250,var(--placeholder-opacity))}.lg\:placeholder-indigo-400:-ms-input-placeholder{--placeholder-opacity:1;color:#7f9cf5;color:rgba(127,156,245,var(--placeholder-opacity))}.lg\:placeholder-indigo-400::-ms-input-placeholder{--placeholder-opacity:1;color:#7f9cf5;color:rgba(127,156,245,var(--placeholder-opacity))}.lg\:placeholder-indigo-400::placeholder{--placeholder-opacity:1;color:#7f9cf5;color:rgba(127,156,245,var(--placeholder-opacity))}.lg\:placeholder-indigo-500:-ms-input-placeholder{--placeholder-opacity:1;color:#667eea;color:rgba(102,126,234,var(--placeholder-opacity))}.lg\:placeholder-indigo-500::-ms-input-placeholder{--placeholder-opacity:1;color:#667eea;color:rgba(102,126,234,var(--placeholder-opacity))}.lg\:placeholder-indigo-500::placeholder{--placeholder-opacity:1;color:#667eea;color:rgba(102,126,234,var(--placeholder-opacity))}.lg\:placeholder-indigo-600:-ms-input-placeholder{--placeholder-opacity:1;color:#5a67d8;color:rgba(90,103,216,var(--placeholder-opacity))}.lg\:placeholder-indigo-600::-ms-input-placeholder{--placeholder-opacity:1;color:#5a67d8;color:rgba(90,103,216,var(--placeholder-opacity))}.lg\:placeholder-indigo-600::placeholder{--placeholder-opacity:1;color:#5a67d8;color:rgba(90,103,216,var(--placeholder-opacity))}.lg\:placeholder-indigo-700:-ms-input-placeholder{--placeholder-opacity:1;color:#4c51bf;color:rgba(76,81,191,var(--placeholder-opacity))}.lg\:placeholder-indigo-700::-ms-input-placeholder{--placeholder-opacity:1;color:#4c51bf;color:rgba(76,81,191,var(--placeholder-opacity))}.lg\:placeholder-indigo-700::placeholder{--placeholder-opacity:1;color:#4c51bf;color:rgba(76,81,191,var(--placeholder-opacity))}.lg\:placeholder-indigo-800:-ms-input-placeholder{--placeholder-opacity:1;color:#434190;color:rgba(67,65,144,var(--placeholder-opacity))}.lg\:placeholder-indigo-800::-ms-input-placeholder{--placeholder-opacity:1;color:#434190;color:rgba(67,65,144,var(--placeholder-opacity))}.lg\:placeholder-indigo-800::placeholder{--placeholder-opacity:1;color:#434190;color:rgba(67,65,144,var(--placeholder-opacity))}.lg\:placeholder-indigo-900:-ms-input-placeholder{--placeholder-opacity:1;color:#3c366b;color:rgba(60,54,107,var(--placeholder-opacity))}.lg\:placeholder-indigo-900::-ms-input-placeholder{--placeholder-opacity:1;color:#3c366b;color:rgba(60,54,107,var(--placeholder-opacity))}.lg\:placeholder-indigo-900::placeholder{--placeholder-opacity:1;color:#3c366b;color:rgba(60,54,107,var(--placeholder-opacity))}.lg\:placeholder-purple-100:-ms-input-placeholder{--placeholder-opacity:1;color:#faf5ff;color:rgba(250,245,255,var(--placeholder-opacity))}.lg\:placeholder-purple-100::-ms-input-placeholder{--placeholder-opacity:1;color:#faf5ff;color:rgba(250,245,255,var(--placeholder-opacity))}.lg\:placeholder-purple-100::placeholder{--placeholder-opacity:1;color:#faf5ff;color:rgba(250,245,255,var(--placeholder-opacity))}.lg\:placeholder-purple-200:-ms-input-placeholder{--placeholder-opacity:1;color:#e9d8fd;color:rgba(233,216,253,var(--placeholder-opacity))}.lg\:placeholder-purple-200::-ms-input-placeholder{--placeholder-opacity:1;color:#e9d8fd;color:rgba(233,216,253,var(--placeholder-opacity))}.lg\:placeholder-purple-200::placeholder{--placeholder-opacity:1;color:#e9d8fd;color:rgba(233,216,253,var(--placeholder-opacity))}.lg\:placeholder-purple-300:-ms-input-placeholder{--placeholder-opacity:1;color:#d6bcfa;color:rgba(214,188,250,var(--placeholder-opacity))}.lg\:placeholder-purple-300::-ms-input-placeholder{--placeholder-opacity:1;color:#d6bcfa;color:rgba(214,188,250,var(--placeholder-opacity))}.lg\:placeholder-purple-300::placeholder{--placeholder-opacity:1;color:#d6bcfa;color:rgba(214,188,250,var(--placeholder-opacity))}.lg\:placeholder-purple-400:-ms-input-placeholder{--placeholder-opacity:1;color:#b794f4;color:rgba(183,148,244,var(--placeholder-opacity))}.lg\:placeholder-purple-400::-ms-input-placeholder{--placeholder-opacity:1;color:#b794f4;color:rgba(183,148,244,var(--placeholder-opacity))}.lg\:placeholder-purple-400::placeholder{--placeholder-opacity:1;color:#b794f4;color:rgba(183,148,244,var(--placeholder-opacity))}.lg\:placeholder-purple-500:-ms-input-placeholder{--placeholder-opacity:1;color:#9f7aea;color:rgba(159,122,234,var(--placeholder-opacity))}.lg\:placeholder-purple-500::-ms-input-placeholder{--placeholder-opacity:1;color:#9f7aea;color:rgba(159,122,234,var(--placeholder-opacity))}.lg\:placeholder-purple-500::placeholder{--placeholder-opacity:1;color:#9f7aea;color:rgba(159,122,234,var(--placeholder-opacity))}.lg\:placeholder-purple-600:-ms-input-placeholder{--placeholder-opacity:1;color:#805ad5;color:rgba(128,90,213,var(--placeholder-opacity))}.lg\:placeholder-purple-600::-ms-input-placeholder{--placeholder-opacity:1;color:#805ad5;color:rgba(128,90,213,var(--placeholder-opacity))}.lg\:placeholder-purple-600::placeholder{--placeholder-opacity:1;color:#805ad5;color:rgba(128,90,213,var(--placeholder-opacity))}.lg\:placeholder-purple-700:-ms-input-placeholder{--placeholder-opacity:1;color:#6b46c1;color:rgba(107,70,193,var(--placeholder-opacity))}.lg\:placeholder-purple-700::-ms-input-placeholder{--placeholder-opacity:1;color:#6b46c1;color:rgba(107,70,193,var(--placeholder-opacity))}.lg\:placeholder-purple-700::placeholder{--placeholder-opacity:1;color:#6b46c1;color:rgba(107,70,193,var(--placeholder-opacity))}.lg\:placeholder-purple-800:-ms-input-placeholder{--placeholder-opacity:1;color:#553c9a;color:rgba(85,60,154,var(--placeholder-opacity))}.lg\:placeholder-purple-800::-ms-input-placeholder{--placeholder-opacity:1;color:#553c9a;color:rgba(85,60,154,var(--placeholder-opacity))}.lg\:placeholder-purple-800::placeholder{--placeholder-opacity:1;color:#553c9a;color:rgba(85,60,154,var(--placeholder-opacity))}.lg\:placeholder-purple-900:-ms-input-placeholder{--placeholder-opacity:1;color:#44337a;color:rgba(68,51,122,var(--placeholder-opacity))}.lg\:placeholder-purple-900::-ms-input-placeholder{--placeholder-opacity:1;color:#44337a;color:rgba(68,51,122,var(--placeholder-opacity))}.lg\:placeholder-purple-900::placeholder{--placeholder-opacity:1;color:#44337a;color:rgba(68,51,122,var(--placeholder-opacity))}.lg\:placeholder-pink-100:-ms-input-placeholder{--placeholder-opacity:1;color:#fff5f7;color:rgba(255,245,247,var(--placeholder-opacity))}.lg\:placeholder-pink-100::-ms-input-placeholder{--placeholder-opacity:1;color:#fff5f7;color:rgba(255,245,247,var(--placeholder-opacity))}.lg\:placeholder-pink-100::placeholder{--placeholder-opacity:1;color:#fff5f7;color:rgba(255,245,247,var(--placeholder-opacity))}.lg\:placeholder-pink-200:-ms-input-placeholder{--placeholder-opacity:1;color:#fed7e2;color:rgba(254,215,226,var(--placeholder-opacity))}.lg\:placeholder-pink-200::-ms-input-placeholder{--placeholder-opacity:1;color:#fed7e2;color:rgba(254,215,226,var(--placeholder-opacity))}.lg\:placeholder-pink-200::placeholder{--placeholder-opacity:1;color:#fed7e2;color:rgba(254,215,226,var(--placeholder-opacity))}.lg\:placeholder-pink-300:-ms-input-placeholder{--placeholder-opacity:1;color:#fbb6ce;color:rgba(251,182,206,var(--placeholder-opacity))}.lg\:placeholder-pink-300::-ms-input-placeholder{--placeholder-opacity:1;color:#fbb6ce;color:rgba(251,182,206,var(--placeholder-opacity))}.lg\:placeholder-pink-300::placeholder{--placeholder-opacity:1;color:#fbb6ce;color:rgba(251,182,206,var(--placeholder-opacity))}.lg\:placeholder-pink-400:-ms-input-placeholder{--placeholder-opacity:1;color:#f687b3;color:rgba(246,135,179,var(--placeholder-opacity))}.lg\:placeholder-pink-400::-ms-input-placeholder{--placeholder-opacity:1;color:#f687b3;color:rgba(246,135,179,var(--placeholder-opacity))}.lg\:placeholder-pink-400::placeholder{--placeholder-opacity:1;color:#f687b3;color:rgba(246,135,179,var(--placeholder-opacity))}.lg\:placeholder-pink-500:-ms-input-placeholder{--placeholder-opacity:1;color:#ed64a6;color:rgba(237,100,166,var(--placeholder-opacity))}.lg\:placeholder-pink-500::-ms-input-placeholder{--placeholder-opacity:1;color:#ed64a6;color:rgba(237,100,166,var(--placeholder-opacity))}.lg\:placeholder-pink-500::placeholder{--placeholder-opacity:1;color:#ed64a6;color:rgba(237,100,166,var(--placeholder-opacity))}.lg\:placeholder-pink-600:-ms-input-placeholder{--placeholder-opacity:1;color:#d53f8c;color:rgba(213,63,140,var(--placeholder-opacity))}.lg\:placeholder-pink-600::-ms-input-placeholder{--placeholder-opacity:1;color:#d53f8c;color:rgba(213,63,140,var(--placeholder-opacity))}.lg\:placeholder-pink-600::placeholder{--placeholder-opacity:1;color:#d53f8c;color:rgba(213,63,140,var(--placeholder-opacity))}.lg\:placeholder-pink-700:-ms-input-placeholder{--placeholder-opacity:1;color:#b83280;color:rgba(184,50,128,var(--placeholder-opacity))}.lg\:placeholder-pink-700::-ms-input-placeholder{--placeholder-opacity:1;color:#b83280;color:rgba(184,50,128,var(--placeholder-opacity))}.lg\:placeholder-pink-700::placeholder{--placeholder-opacity:1;color:#b83280;color:rgba(184,50,128,var(--placeholder-opacity))}.lg\:placeholder-pink-800:-ms-input-placeholder{--placeholder-opacity:1;color:#97266d;color:rgba(151,38,109,var(--placeholder-opacity))}.lg\:placeholder-pink-800::-ms-input-placeholder{--placeholder-opacity:1;color:#97266d;color:rgba(151,38,109,var(--placeholder-opacity))}.lg\:placeholder-pink-800::placeholder{--placeholder-opacity:1;color:#97266d;color:rgba(151,38,109,var(--placeholder-opacity))}.lg\:placeholder-pink-900:-ms-input-placeholder{--placeholder-opacity:1;color:#702459;color:rgba(112,36,89,var(--placeholder-opacity))}.lg\:placeholder-pink-900::-ms-input-placeholder{--placeholder-opacity:1;color:#702459;color:rgba(112,36,89,var(--placeholder-opacity))}.lg\:placeholder-pink-900::placeholder{--placeholder-opacity:1;color:#702459;color:rgba(112,36,89,var(--placeholder-opacity))}.lg\:focus\:placeholder-transparent:focus:-ms-input-placeholder{color:transparent}.lg\:focus\:placeholder-transparent:focus::-ms-input-placeholder{color:transparent}.lg\:focus\:placeholder-transparent:focus::placeholder{color:transparent}.lg\:focus\:placeholder-current:focus:-ms-input-placeholder{color:currentColor}.lg\:focus\:placeholder-current:focus::-ms-input-placeholder{color:currentColor}.lg\:focus\:placeholder-current:focus::placeholder{color:currentColor}.lg\:focus\:placeholder-black:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#000;color:rgba(0,0,0,var(--placeholder-opacity))}.lg\:focus\:placeholder-black:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#000;color:rgba(0,0,0,var(--placeholder-opacity))}.lg\:focus\:placeholder-black:focus::placeholder{--placeholder-opacity:1;color:#000;color:rgba(0,0,0,var(--placeholder-opacity))}.lg\:focus\:placeholder-white:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#fff;color:rgba(255,255,255,var(--placeholder-opacity))}.lg\:focus\:placeholder-white:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#fff;color:rgba(255,255,255,var(--placeholder-opacity))}.lg\:focus\:placeholder-white:focus::placeholder{--placeholder-opacity:1;color:#fff;color:rgba(255,255,255,var(--placeholder-opacity))}.lg\:focus\:placeholder-gray-100:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#f7fafc;color:rgba(247,250,252,var(--placeholder-opacity))}.lg\:focus\:placeholder-gray-100:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#f7fafc;color:rgba(247,250,252,var(--placeholder-opacity))}.lg\:focus\:placeholder-gray-100:focus::placeholder{--placeholder-opacity:1;color:#f7fafc;color:rgba(247,250,252,var(--placeholder-opacity))}.lg\:focus\:placeholder-gray-200:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#edf2f7;color:rgba(237,242,247,var(--placeholder-opacity))}.lg\:focus\:placeholder-gray-200:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#edf2f7;color:rgba(237,242,247,var(--placeholder-opacity))}.lg\:focus\:placeholder-gray-200:focus::placeholder{--placeholder-opacity:1;color:#edf2f7;color:rgba(237,242,247,var(--placeholder-opacity))}.lg\:focus\:placeholder-gray-300:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#e2e8f0;color:rgba(226,232,240,var(--placeholder-opacity))}.lg\:focus\:placeholder-gray-300:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#e2e8f0;color:rgba(226,232,240,var(--placeholder-opacity))}.lg\:focus\:placeholder-gray-300:focus::placeholder{--placeholder-opacity:1;color:#e2e8f0;color:rgba(226,232,240,var(--placeholder-opacity))}.lg\:focus\:placeholder-gray-400:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#cbd5e0;color:rgba(203,213,224,var(--placeholder-opacity))}.lg\:focus\:placeholder-gray-400:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#cbd5e0;color:rgba(203,213,224,var(--placeholder-opacity))}.lg\:focus\:placeholder-gray-400:focus::placeholder{--placeholder-opacity:1;color:#cbd5e0;color:rgba(203,213,224,var(--placeholder-opacity))}.lg\:focus\:placeholder-gray-500:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#a0aec0;color:rgba(160,174,192,var(--placeholder-opacity))}.lg\:focus\:placeholder-gray-500:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#a0aec0;color:rgba(160,174,192,var(--placeholder-opacity))}.lg\:focus\:placeholder-gray-500:focus::placeholder{--placeholder-opacity:1;color:#a0aec0;color:rgba(160,174,192,var(--placeholder-opacity))}.lg\:focus\:placeholder-gray-600:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#718096;color:rgba(113,128,150,var(--placeholder-opacity))}.lg\:focus\:placeholder-gray-600:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#718096;color:rgba(113,128,150,var(--placeholder-opacity))}.lg\:focus\:placeholder-gray-600:focus::placeholder{--placeholder-opacity:1;color:#718096;color:rgba(113,128,150,var(--placeholder-opacity))}.lg\:focus\:placeholder-gray-700:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#4a5568;color:rgba(74,85,104,var(--placeholder-opacity))}.lg\:focus\:placeholder-gray-700:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#4a5568;color:rgba(74,85,104,var(--placeholder-opacity))}.lg\:focus\:placeholder-gray-700:focus::placeholder{--placeholder-opacity:1;color:#4a5568;color:rgba(74,85,104,var(--placeholder-opacity))}.lg\:focus\:placeholder-gray-800:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#2d3748;color:rgba(45,55,72,var(--placeholder-opacity))}.lg\:focus\:placeholder-gray-800:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#2d3748;color:rgba(45,55,72,var(--placeholder-opacity))}.lg\:focus\:placeholder-gray-800:focus::placeholder{--placeholder-opacity:1;color:#2d3748;color:rgba(45,55,72,var(--placeholder-opacity))}.lg\:focus\:placeholder-gray-900:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#1a202c;color:rgba(26,32,44,var(--placeholder-opacity))}.lg\:focus\:placeholder-gray-900:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#1a202c;color:rgba(26,32,44,var(--placeholder-opacity))}.lg\:focus\:placeholder-gray-900:focus::placeholder{--placeholder-opacity:1;color:#1a202c;color:rgba(26,32,44,var(--placeholder-opacity))}.lg\:focus\:placeholder-red-100:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#fff5f5;color:rgba(255,245,245,var(--placeholder-opacity))}.lg\:focus\:placeholder-red-100:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#fff5f5;color:rgba(255,245,245,var(--placeholder-opacity))}.lg\:focus\:placeholder-red-100:focus::placeholder{--placeholder-opacity:1;color:#fff5f5;color:rgba(255,245,245,var(--placeholder-opacity))}.lg\:focus\:placeholder-red-200:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#fed7d7;color:rgba(254,215,215,var(--placeholder-opacity))}.lg\:focus\:placeholder-red-200:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#fed7d7;color:rgba(254,215,215,var(--placeholder-opacity))}.lg\:focus\:placeholder-red-200:focus::placeholder{--placeholder-opacity:1;color:#fed7d7;color:rgba(254,215,215,var(--placeholder-opacity))}.lg\:focus\:placeholder-red-300:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#feb2b2;color:rgba(254,178,178,var(--placeholder-opacity))}.lg\:focus\:placeholder-red-300:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#feb2b2;color:rgba(254,178,178,var(--placeholder-opacity))}.lg\:focus\:placeholder-red-300:focus::placeholder{--placeholder-opacity:1;color:#feb2b2;color:rgba(254,178,178,var(--placeholder-opacity))}.lg\:focus\:placeholder-red-400:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#fc8181;color:rgba(252,129,129,var(--placeholder-opacity))}.lg\:focus\:placeholder-red-400:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#fc8181;color:rgba(252,129,129,var(--placeholder-opacity))}.lg\:focus\:placeholder-red-400:focus::placeholder{--placeholder-opacity:1;color:#fc8181;color:rgba(252,129,129,var(--placeholder-opacity))}.lg\:focus\:placeholder-red-500:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#f56565;color:rgba(245,101,101,var(--placeholder-opacity))}.lg\:focus\:placeholder-red-500:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#f56565;color:rgba(245,101,101,var(--placeholder-opacity))}.lg\:focus\:placeholder-red-500:focus::placeholder{--placeholder-opacity:1;color:#f56565;color:rgba(245,101,101,var(--placeholder-opacity))}.lg\:focus\:placeholder-red-600:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#e53e3e;color:rgba(229,62,62,var(--placeholder-opacity))}.lg\:focus\:placeholder-red-600:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#e53e3e;color:rgba(229,62,62,var(--placeholder-opacity))}.lg\:focus\:placeholder-red-600:focus::placeholder{--placeholder-opacity:1;color:#e53e3e;color:rgba(229,62,62,var(--placeholder-opacity))}.lg\:focus\:placeholder-red-700:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#c53030;color:rgba(197,48,48,var(--placeholder-opacity))}.lg\:focus\:placeholder-red-700:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#c53030;color:rgba(197,48,48,var(--placeholder-opacity))}.lg\:focus\:placeholder-red-700:focus::placeholder{--placeholder-opacity:1;color:#c53030;color:rgba(197,48,48,var(--placeholder-opacity))}.lg\:focus\:placeholder-red-800:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#9b2c2c;color:rgba(155,44,44,var(--placeholder-opacity))}.lg\:focus\:placeholder-red-800:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#9b2c2c;color:rgba(155,44,44,var(--placeholder-opacity))}.lg\:focus\:placeholder-red-800:focus::placeholder{--placeholder-opacity:1;color:#9b2c2c;color:rgba(155,44,44,var(--placeholder-opacity))}.lg\:focus\:placeholder-red-900:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#742a2a;color:rgba(116,42,42,var(--placeholder-opacity))}.lg\:focus\:placeholder-red-900:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#742a2a;color:rgba(116,42,42,var(--placeholder-opacity))}.lg\:focus\:placeholder-red-900:focus::placeholder{--placeholder-opacity:1;color:#742a2a;color:rgba(116,42,42,var(--placeholder-opacity))}.lg\:focus\:placeholder-orange-100:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#fffaf0;color:rgba(255,250,240,var(--placeholder-opacity))}.lg\:focus\:placeholder-orange-100:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#fffaf0;color:rgba(255,250,240,var(--placeholder-opacity))}.lg\:focus\:placeholder-orange-100:focus::placeholder{--placeholder-opacity:1;color:#fffaf0;color:rgba(255,250,240,var(--placeholder-opacity))}.lg\:focus\:placeholder-orange-200:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#feebc8;color:rgba(254,235,200,var(--placeholder-opacity))}.lg\:focus\:placeholder-orange-200:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#feebc8;color:rgba(254,235,200,var(--placeholder-opacity))}.lg\:focus\:placeholder-orange-200:focus::placeholder{--placeholder-opacity:1;color:#feebc8;color:rgba(254,235,200,var(--placeholder-opacity))}.lg\:focus\:placeholder-orange-300:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#fbd38d;color:rgba(251,211,141,var(--placeholder-opacity))}.lg\:focus\:placeholder-orange-300:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#fbd38d;color:rgba(251,211,141,var(--placeholder-opacity))}.lg\:focus\:placeholder-orange-300:focus::placeholder{--placeholder-opacity:1;color:#fbd38d;color:rgba(251,211,141,var(--placeholder-opacity))}.lg\:focus\:placeholder-orange-400:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#f6ad55;color:rgba(246,173,85,var(--placeholder-opacity))}.lg\:focus\:placeholder-orange-400:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#f6ad55;color:rgba(246,173,85,var(--placeholder-opacity))}.lg\:focus\:placeholder-orange-400:focus::placeholder{--placeholder-opacity:1;color:#f6ad55;color:rgba(246,173,85,var(--placeholder-opacity))}.lg\:focus\:placeholder-orange-500:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#ed8936;color:rgba(237,137,54,var(--placeholder-opacity))}.lg\:focus\:placeholder-orange-500:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#ed8936;color:rgba(237,137,54,var(--placeholder-opacity))}.lg\:focus\:placeholder-orange-500:focus::placeholder{--placeholder-opacity:1;color:#ed8936;color:rgba(237,137,54,var(--placeholder-opacity))}.lg\:focus\:placeholder-orange-600:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#dd6b20;color:rgba(221,107,32,var(--placeholder-opacity))}.lg\:focus\:placeholder-orange-600:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#dd6b20;color:rgba(221,107,32,var(--placeholder-opacity))}.lg\:focus\:placeholder-orange-600:focus::placeholder{--placeholder-opacity:1;color:#dd6b20;color:rgba(221,107,32,var(--placeholder-opacity))}.lg\:focus\:placeholder-orange-700:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#c05621;color:rgba(192,86,33,var(--placeholder-opacity))}.lg\:focus\:placeholder-orange-700:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#c05621;color:rgba(192,86,33,var(--placeholder-opacity))}.lg\:focus\:placeholder-orange-700:focus::placeholder{--placeholder-opacity:1;color:#c05621;color:rgba(192,86,33,var(--placeholder-opacity))}.lg\:focus\:placeholder-orange-800:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#9c4221;color:rgba(156,66,33,var(--placeholder-opacity))}.lg\:focus\:placeholder-orange-800:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#9c4221;color:rgba(156,66,33,var(--placeholder-opacity))}.lg\:focus\:placeholder-orange-800:focus::placeholder{--placeholder-opacity:1;color:#9c4221;color:rgba(156,66,33,var(--placeholder-opacity))}.lg\:focus\:placeholder-orange-900:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#7b341e;color:rgba(123,52,30,var(--placeholder-opacity))}.lg\:focus\:placeholder-orange-900:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#7b341e;color:rgba(123,52,30,var(--placeholder-opacity))}.lg\:focus\:placeholder-orange-900:focus::placeholder{--placeholder-opacity:1;color:#7b341e;color:rgba(123,52,30,var(--placeholder-opacity))}.lg\:focus\:placeholder-yellow-100:focus:-ms-input-placeholder{--placeholder-opacity:1;color:ivory;color:rgba(255,255,240,var(--placeholder-opacity))}.lg\:focus\:placeholder-yellow-100:focus::-ms-input-placeholder{--placeholder-opacity:1;color:ivory;color:rgba(255,255,240,var(--placeholder-opacity))}.lg\:focus\:placeholder-yellow-100:focus::placeholder{--placeholder-opacity:1;color:ivory;color:rgba(255,255,240,var(--placeholder-opacity))}.lg\:focus\:placeholder-yellow-200:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#fefcbf;color:rgba(254,252,191,var(--placeholder-opacity))}.lg\:focus\:placeholder-yellow-200:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#fefcbf;color:rgba(254,252,191,var(--placeholder-opacity))}.lg\:focus\:placeholder-yellow-200:focus::placeholder{--placeholder-opacity:1;color:#fefcbf;color:rgba(254,252,191,var(--placeholder-opacity))}.lg\:focus\:placeholder-yellow-300:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#faf089;color:rgba(250,240,137,var(--placeholder-opacity))}.lg\:focus\:placeholder-yellow-300:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#faf089;color:rgba(250,240,137,var(--placeholder-opacity))}.lg\:focus\:placeholder-yellow-300:focus::placeholder{--placeholder-opacity:1;color:#faf089;color:rgba(250,240,137,var(--placeholder-opacity))}.lg\:focus\:placeholder-yellow-400:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#f6e05e;color:rgba(246,224,94,var(--placeholder-opacity))}.lg\:focus\:placeholder-yellow-400:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#f6e05e;color:rgba(246,224,94,var(--placeholder-opacity))}.lg\:focus\:placeholder-yellow-400:focus::placeholder{--placeholder-opacity:1;color:#f6e05e;color:rgba(246,224,94,var(--placeholder-opacity))}.lg\:focus\:placeholder-yellow-500:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#ecc94b;color:rgba(236,201,75,var(--placeholder-opacity))}.lg\:focus\:placeholder-yellow-500:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#ecc94b;color:rgba(236,201,75,var(--placeholder-opacity))}.lg\:focus\:placeholder-yellow-500:focus::placeholder{--placeholder-opacity:1;color:#ecc94b;color:rgba(236,201,75,var(--placeholder-opacity))}.lg\:focus\:placeholder-yellow-600:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#d69e2e;color:rgba(214,158,46,var(--placeholder-opacity))}.lg\:focus\:placeholder-yellow-600:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#d69e2e;color:rgba(214,158,46,var(--placeholder-opacity))}.lg\:focus\:placeholder-yellow-600:focus::placeholder{--placeholder-opacity:1;color:#d69e2e;color:rgba(214,158,46,var(--placeholder-opacity))}.lg\:focus\:placeholder-yellow-700:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#b7791f;color:rgba(183,121,31,var(--placeholder-opacity))}.lg\:focus\:placeholder-yellow-700:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#b7791f;color:rgba(183,121,31,var(--placeholder-opacity))}.lg\:focus\:placeholder-yellow-700:focus::placeholder{--placeholder-opacity:1;color:#b7791f;color:rgba(183,121,31,var(--placeholder-opacity))}.lg\:focus\:placeholder-yellow-800:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#975a16;color:rgba(151,90,22,var(--placeholder-opacity))}.lg\:focus\:placeholder-yellow-800:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#975a16;color:rgba(151,90,22,var(--placeholder-opacity))}.lg\:focus\:placeholder-yellow-800:focus::placeholder{--placeholder-opacity:1;color:#975a16;color:rgba(151,90,22,var(--placeholder-opacity))}.lg\:focus\:placeholder-yellow-900:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#744210;color:rgba(116,66,16,var(--placeholder-opacity))}.lg\:focus\:placeholder-yellow-900:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#744210;color:rgba(116,66,16,var(--placeholder-opacity))}.lg\:focus\:placeholder-yellow-900:focus::placeholder{--placeholder-opacity:1;color:#744210;color:rgba(116,66,16,var(--placeholder-opacity))}.lg\:focus\:placeholder-green-100:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#f0fff4;color:rgba(240,255,244,var(--placeholder-opacity))}.lg\:focus\:placeholder-green-100:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#f0fff4;color:rgba(240,255,244,var(--placeholder-opacity))}.lg\:focus\:placeholder-green-100:focus::placeholder{--placeholder-opacity:1;color:#f0fff4;color:rgba(240,255,244,var(--placeholder-opacity))}.lg\:focus\:placeholder-green-200:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#c6f6d5;color:rgba(198,246,213,var(--placeholder-opacity))}.lg\:focus\:placeholder-green-200:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#c6f6d5;color:rgba(198,246,213,var(--placeholder-opacity))}.lg\:focus\:placeholder-green-200:focus::placeholder{--placeholder-opacity:1;color:#c6f6d5;color:rgba(198,246,213,var(--placeholder-opacity))}.lg\:focus\:placeholder-green-300:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#9ae6b4;color:rgba(154,230,180,var(--placeholder-opacity))}.lg\:focus\:placeholder-green-300:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#9ae6b4;color:rgba(154,230,180,var(--placeholder-opacity))}.lg\:focus\:placeholder-green-300:focus::placeholder{--placeholder-opacity:1;color:#9ae6b4;color:rgba(154,230,180,var(--placeholder-opacity))}.lg\:focus\:placeholder-green-400:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#68d391;color:rgba(104,211,145,var(--placeholder-opacity))}.lg\:focus\:placeholder-green-400:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#68d391;color:rgba(104,211,145,var(--placeholder-opacity))}.lg\:focus\:placeholder-green-400:focus::placeholder{--placeholder-opacity:1;color:#68d391;color:rgba(104,211,145,var(--placeholder-opacity))}.lg\:focus\:placeholder-green-500:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#48bb78;color:rgba(72,187,120,var(--placeholder-opacity))}.lg\:focus\:placeholder-green-500:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#48bb78;color:rgba(72,187,120,var(--placeholder-opacity))}.lg\:focus\:placeholder-green-500:focus::placeholder{--placeholder-opacity:1;color:#48bb78;color:rgba(72,187,120,var(--placeholder-opacity))}.lg\:focus\:placeholder-green-600:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#38a169;color:rgba(56,161,105,var(--placeholder-opacity))}.lg\:focus\:placeholder-green-600:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#38a169;color:rgba(56,161,105,var(--placeholder-opacity))}.lg\:focus\:placeholder-green-600:focus::placeholder{--placeholder-opacity:1;color:#38a169;color:rgba(56,161,105,var(--placeholder-opacity))}.lg\:focus\:placeholder-green-700:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#2f855a;color:rgba(47,133,90,var(--placeholder-opacity))}.lg\:focus\:placeholder-green-700:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#2f855a;color:rgba(47,133,90,var(--placeholder-opacity))}.lg\:focus\:placeholder-green-700:focus::placeholder{--placeholder-opacity:1;color:#2f855a;color:rgba(47,133,90,var(--placeholder-opacity))}.lg\:focus\:placeholder-green-800:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#276749;color:rgba(39,103,73,var(--placeholder-opacity))}.lg\:focus\:placeholder-green-800:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#276749;color:rgba(39,103,73,var(--placeholder-opacity))}.lg\:focus\:placeholder-green-800:focus::placeholder{--placeholder-opacity:1;color:#276749;color:rgba(39,103,73,var(--placeholder-opacity))}.lg\:focus\:placeholder-green-900:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#22543d;color:rgba(34,84,61,var(--placeholder-opacity))}.lg\:focus\:placeholder-green-900:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#22543d;color:rgba(34,84,61,var(--placeholder-opacity))}.lg\:focus\:placeholder-green-900:focus::placeholder{--placeholder-opacity:1;color:#22543d;color:rgba(34,84,61,var(--placeholder-opacity))}.lg\:focus\:placeholder-teal-100:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#e6fffa;color:rgba(230,255,250,var(--placeholder-opacity))}.lg\:focus\:placeholder-teal-100:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#e6fffa;color:rgba(230,255,250,var(--placeholder-opacity))}.lg\:focus\:placeholder-teal-100:focus::placeholder{--placeholder-opacity:1;color:#e6fffa;color:rgba(230,255,250,var(--placeholder-opacity))}.lg\:focus\:placeholder-teal-200:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#b2f5ea;color:rgba(178,245,234,var(--placeholder-opacity))}.lg\:focus\:placeholder-teal-200:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#b2f5ea;color:rgba(178,245,234,var(--placeholder-opacity))}.lg\:focus\:placeholder-teal-200:focus::placeholder{--placeholder-opacity:1;color:#b2f5ea;color:rgba(178,245,234,var(--placeholder-opacity))}.lg\:focus\:placeholder-teal-300:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#81e6d9;color:rgba(129,230,217,var(--placeholder-opacity))}.lg\:focus\:placeholder-teal-300:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#81e6d9;color:rgba(129,230,217,var(--placeholder-opacity))}.lg\:focus\:placeholder-teal-300:focus::placeholder{--placeholder-opacity:1;color:#81e6d9;color:rgba(129,230,217,var(--placeholder-opacity))}.lg\:focus\:placeholder-teal-400:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#4fd1c5;color:rgba(79,209,197,var(--placeholder-opacity))}.lg\:focus\:placeholder-teal-400:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#4fd1c5;color:rgba(79,209,197,var(--placeholder-opacity))}.lg\:focus\:placeholder-teal-400:focus::placeholder{--placeholder-opacity:1;color:#4fd1c5;color:rgba(79,209,197,var(--placeholder-opacity))}.lg\:focus\:placeholder-teal-500:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#38b2ac;color:rgba(56,178,172,var(--placeholder-opacity))}.lg\:focus\:placeholder-teal-500:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#38b2ac;color:rgba(56,178,172,var(--placeholder-opacity))}.lg\:focus\:placeholder-teal-500:focus::placeholder{--placeholder-opacity:1;color:#38b2ac;color:rgba(56,178,172,var(--placeholder-opacity))}.lg\:focus\:placeholder-teal-600:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#319795;color:rgba(49,151,149,var(--placeholder-opacity))}.lg\:focus\:placeholder-teal-600:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#319795;color:rgba(49,151,149,var(--placeholder-opacity))}.lg\:focus\:placeholder-teal-600:focus::placeholder{--placeholder-opacity:1;color:#319795;color:rgba(49,151,149,var(--placeholder-opacity))}.lg\:focus\:placeholder-teal-700:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#2c7a7b;color:rgba(44,122,123,var(--placeholder-opacity))}.lg\:focus\:placeholder-teal-700:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#2c7a7b;color:rgba(44,122,123,var(--placeholder-opacity))}.lg\:focus\:placeholder-teal-700:focus::placeholder{--placeholder-opacity:1;color:#2c7a7b;color:rgba(44,122,123,var(--placeholder-opacity))}.lg\:focus\:placeholder-teal-800:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#285e61;color:rgba(40,94,97,var(--placeholder-opacity))}.lg\:focus\:placeholder-teal-800:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#285e61;color:rgba(40,94,97,var(--placeholder-opacity))}.lg\:focus\:placeholder-teal-800:focus::placeholder{--placeholder-opacity:1;color:#285e61;color:rgba(40,94,97,var(--placeholder-opacity))}.lg\:focus\:placeholder-teal-900:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#234e52;color:rgba(35,78,82,var(--placeholder-opacity))}.lg\:focus\:placeholder-teal-900:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#234e52;color:rgba(35,78,82,var(--placeholder-opacity))}.lg\:focus\:placeholder-teal-900:focus::placeholder{--placeholder-opacity:1;color:#234e52;color:rgba(35,78,82,var(--placeholder-opacity))}.lg\:focus\:placeholder-blue-100:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#ebf8ff;color:rgba(235,248,255,var(--placeholder-opacity))}.lg\:focus\:placeholder-blue-100:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#ebf8ff;color:rgba(235,248,255,var(--placeholder-opacity))}.lg\:focus\:placeholder-blue-100:focus::placeholder{--placeholder-opacity:1;color:#ebf8ff;color:rgba(235,248,255,var(--placeholder-opacity))}.lg\:focus\:placeholder-blue-200:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#bee3f8;color:rgba(190,227,248,var(--placeholder-opacity))}.lg\:focus\:placeholder-blue-200:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#bee3f8;color:rgba(190,227,248,var(--placeholder-opacity))}.lg\:focus\:placeholder-blue-200:focus::placeholder{--placeholder-opacity:1;color:#bee3f8;color:rgba(190,227,248,var(--placeholder-opacity))}.lg\:focus\:placeholder-blue-300:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#90cdf4;color:rgba(144,205,244,var(--placeholder-opacity))}.lg\:focus\:placeholder-blue-300:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#90cdf4;color:rgba(144,205,244,var(--placeholder-opacity))}.lg\:focus\:placeholder-blue-300:focus::placeholder{--placeholder-opacity:1;color:#90cdf4;color:rgba(144,205,244,var(--placeholder-opacity))}.lg\:focus\:placeholder-blue-400:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#63b3ed;color:rgba(99,179,237,var(--placeholder-opacity))}.lg\:focus\:placeholder-blue-400:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#63b3ed;color:rgba(99,179,237,var(--placeholder-opacity))}.lg\:focus\:placeholder-blue-400:focus::placeholder{--placeholder-opacity:1;color:#63b3ed;color:rgba(99,179,237,var(--placeholder-opacity))}.lg\:focus\:placeholder-blue-500:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#4299e1;color:rgba(66,153,225,var(--placeholder-opacity))}.lg\:focus\:placeholder-blue-500:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#4299e1;color:rgba(66,153,225,var(--placeholder-opacity))}.lg\:focus\:placeholder-blue-500:focus::placeholder{--placeholder-opacity:1;color:#4299e1;color:rgba(66,153,225,var(--placeholder-opacity))}.lg\:focus\:placeholder-blue-600:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#3182ce;color:rgba(49,130,206,var(--placeholder-opacity))}.lg\:focus\:placeholder-blue-600:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#3182ce;color:rgba(49,130,206,var(--placeholder-opacity))}.lg\:focus\:placeholder-blue-600:focus::placeholder{--placeholder-opacity:1;color:#3182ce;color:rgba(49,130,206,var(--placeholder-opacity))}.lg\:focus\:placeholder-blue-700:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#2b6cb0;color:rgba(43,108,176,var(--placeholder-opacity))}.lg\:focus\:placeholder-blue-700:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#2b6cb0;color:rgba(43,108,176,var(--placeholder-opacity))}.lg\:focus\:placeholder-blue-700:focus::placeholder{--placeholder-opacity:1;color:#2b6cb0;color:rgba(43,108,176,var(--placeholder-opacity))}.lg\:focus\:placeholder-blue-800:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#2c5282;color:rgba(44,82,130,var(--placeholder-opacity))}.lg\:focus\:placeholder-blue-800:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#2c5282;color:rgba(44,82,130,var(--placeholder-opacity))}.lg\:focus\:placeholder-blue-800:focus::placeholder{--placeholder-opacity:1;color:#2c5282;color:rgba(44,82,130,var(--placeholder-opacity))}.lg\:focus\:placeholder-blue-900:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#2a4365;color:rgba(42,67,101,var(--placeholder-opacity))}.lg\:focus\:placeholder-blue-900:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#2a4365;color:rgba(42,67,101,var(--placeholder-opacity))}.lg\:focus\:placeholder-blue-900:focus::placeholder{--placeholder-opacity:1;color:#2a4365;color:rgba(42,67,101,var(--placeholder-opacity))}.lg\:focus\:placeholder-indigo-100:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#ebf4ff;color:rgba(235,244,255,var(--placeholder-opacity))}.lg\:focus\:placeholder-indigo-100:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#ebf4ff;color:rgba(235,244,255,var(--placeholder-opacity))}.lg\:focus\:placeholder-indigo-100:focus::placeholder{--placeholder-opacity:1;color:#ebf4ff;color:rgba(235,244,255,var(--placeholder-opacity))}.lg\:focus\:placeholder-indigo-200:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#c3dafe;color:rgba(195,218,254,var(--placeholder-opacity))}.lg\:focus\:placeholder-indigo-200:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#c3dafe;color:rgba(195,218,254,var(--placeholder-opacity))}.lg\:focus\:placeholder-indigo-200:focus::placeholder{--placeholder-opacity:1;color:#c3dafe;color:rgba(195,218,254,var(--placeholder-opacity))}.lg\:focus\:placeholder-indigo-300:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#a3bffa;color:rgba(163,191,250,var(--placeholder-opacity))}.lg\:focus\:placeholder-indigo-300:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#a3bffa;color:rgba(163,191,250,var(--placeholder-opacity))}.lg\:focus\:placeholder-indigo-300:focus::placeholder{--placeholder-opacity:1;color:#a3bffa;color:rgba(163,191,250,var(--placeholder-opacity))}.lg\:focus\:placeholder-indigo-400:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#7f9cf5;color:rgba(127,156,245,var(--placeholder-opacity))}.lg\:focus\:placeholder-indigo-400:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#7f9cf5;color:rgba(127,156,245,var(--placeholder-opacity))}.lg\:focus\:placeholder-indigo-400:focus::placeholder{--placeholder-opacity:1;color:#7f9cf5;color:rgba(127,156,245,var(--placeholder-opacity))}.lg\:focus\:placeholder-indigo-500:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#667eea;color:rgba(102,126,234,var(--placeholder-opacity))}.lg\:focus\:placeholder-indigo-500:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#667eea;color:rgba(102,126,234,var(--placeholder-opacity))}.lg\:focus\:placeholder-indigo-500:focus::placeholder{--placeholder-opacity:1;color:#667eea;color:rgba(102,126,234,var(--placeholder-opacity))}.lg\:focus\:placeholder-indigo-600:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#5a67d8;color:rgba(90,103,216,var(--placeholder-opacity))}.lg\:focus\:placeholder-indigo-600:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#5a67d8;color:rgba(90,103,216,var(--placeholder-opacity))}.lg\:focus\:placeholder-indigo-600:focus::placeholder{--placeholder-opacity:1;color:#5a67d8;color:rgba(90,103,216,var(--placeholder-opacity))}.lg\:focus\:placeholder-indigo-700:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#4c51bf;color:rgba(76,81,191,var(--placeholder-opacity))}.lg\:focus\:placeholder-indigo-700:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#4c51bf;color:rgba(76,81,191,var(--placeholder-opacity))}.lg\:focus\:placeholder-indigo-700:focus::placeholder{--placeholder-opacity:1;color:#4c51bf;color:rgba(76,81,191,var(--placeholder-opacity))}.lg\:focus\:placeholder-indigo-800:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#434190;color:rgba(67,65,144,var(--placeholder-opacity))}.lg\:focus\:placeholder-indigo-800:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#434190;color:rgba(67,65,144,var(--placeholder-opacity))}.lg\:focus\:placeholder-indigo-800:focus::placeholder{--placeholder-opacity:1;color:#434190;color:rgba(67,65,144,var(--placeholder-opacity))}.lg\:focus\:placeholder-indigo-900:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#3c366b;color:rgba(60,54,107,var(--placeholder-opacity))}.lg\:focus\:placeholder-indigo-900:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#3c366b;color:rgba(60,54,107,var(--placeholder-opacity))}.lg\:focus\:placeholder-indigo-900:focus::placeholder{--placeholder-opacity:1;color:#3c366b;color:rgba(60,54,107,var(--placeholder-opacity))}.lg\:focus\:placeholder-purple-100:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#faf5ff;color:rgba(250,245,255,var(--placeholder-opacity))}.lg\:focus\:placeholder-purple-100:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#faf5ff;color:rgba(250,245,255,var(--placeholder-opacity))}.lg\:focus\:placeholder-purple-100:focus::placeholder{--placeholder-opacity:1;color:#faf5ff;color:rgba(250,245,255,var(--placeholder-opacity))}.lg\:focus\:placeholder-purple-200:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#e9d8fd;color:rgba(233,216,253,var(--placeholder-opacity))}.lg\:focus\:placeholder-purple-200:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#e9d8fd;color:rgba(233,216,253,var(--placeholder-opacity))}.lg\:focus\:placeholder-purple-200:focus::placeholder{--placeholder-opacity:1;color:#e9d8fd;color:rgba(233,216,253,var(--placeholder-opacity))}.lg\:focus\:placeholder-purple-300:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#d6bcfa;color:rgba(214,188,250,var(--placeholder-opacity))}.lg\:focus\:placeholder-purple-300:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#d6bcfa;color:rgba(214,188,250,var(--placeholder-opacity))}.lg\:focus\:placeholder-purple-300:focus::placeholder{--placeholder-opacity:1;color:#d6bcfa;color:rgba(214,188,250,var(--placeholder-opacity))}.lg\:focus\:placeholder-purple-400:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#b794f4;color:rgba(183,148,244,var(--placeholder-opacity))}.lg\:focus\:placeholder-purple-400:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#b794f4;color:rgba(183,148,244,var(--placeholder-opacity))}.lg\:focus\:placeholder-purple-400:focus::placeholder{--placeholder-opacity:1;color:#b794f4;color:rgba(183,148,244,var(--placeholder-opacity))}.lg\:focus\:placeholder-purple-500:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#9f7aea;color:rgba(159,122,234,var(--placeholder-opacity))}.lg\:focus\:placeholder-purple-500:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#9f7aea;color:rgba(159,122,234,var(--placeholder-opacity))}.lg\:focus\:placeholder-purple-500:focus::placeholder{--placeholder-opacity:1;color:#9f7aea;color:rgba(159,122,234,var(--placeholder-opacity))}.lg\:focus\:placeholder-purple-600:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#805ad5;color:rgba(128,90,213,var(--placeholder-opacity))}.lg\:focus\:placeholder-purple-600:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#805ad5;color:rgba(128,90,213,var(--placeholder-opacity))}.lg\:focus\:placeholder-purple-600:focus::placeholder{--placeholder-opacity:1;color:#805ad5;color:rgba(128,90,213,var(--placeholder-opacity))}.lg\:focus\:placeholder-purple-700:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#6b46c1;color:rgba(107,70,193,var(--placeholder-opacity))}.lg\:focus\:placeholder-purple-700:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#6b46c1;color:rgba(107,70,193,var(--placeholder-opacity))}.lg\:focus\:placeholder-purple-700:focus::placeholder{--placeholder-opacity:1;color:#6b46c1;color:rgba(107,70,193,var(--placeholder-opacity))}.lg\:focus\:placeholder-purple-800:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#553c9a;color:rgba(85,60,154,var(--placeholder-opacity))}.lg\:focus\:placeholder-purple-800:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#553c9a;color:rgba(85,60,154,var(--placeholder-opacity))}.lg\:focus\:placeholder-purple-800:focus::placeholder{--placeholder-opacity:1;color:#553c9a;color:rgba(85,60,154,var(--placeholder-opacity))}.lg\:focus\:placeholder-purple-900:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#44337a;color:rgba(68,51,122,var(--placeholder-opacity))}.lg\:focus\:placeholder-purple-900:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#44337a;color:rgba(68,51,122,var(--placeholder-opacity))}.lg\:focus\:placeholder-purple-900:focus::placeholder{--placeholder-opacity:1;color:#44337a;color:rgba(68,51,122,var(--placeholder-opacity))}.lg\:focus\:placeholder-pink-100:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#fff5f7;color:rgba(255,245,247,var(--placeholder-opacity))}.lg\:focus\:placeholder-pink-100:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#fff5f7;color:rgba(255,245,247,var(--placeholder-opacity))}.lg\:focus\:placeholder-pink-100:focus::placeholder{--placeholder-opacity:1;color:#fff5f7;color:rgba(255,245,247,var(--placeholder-opacity))}.lg\:focus\:placeholder-pink-200:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#fed7e2;color:rgba(254,215,226,var(--placeholder-opacity))}.lg\:focus\:placeholder-pink-200:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#fed7e2;color:rgba(254,215,226,var(--placeholder-opacity))}.lg\:focus\:placeholder-pink-200:focus::placeholder{--placeholder-opacity:1;color:#fed7e2;color:rgba(254,215,226,var(--placeholder-opacity))}.lg\:focus\:placeholder-pink-300:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#fbb6ce;color:rgba(251,182,206,var(--placeholder-opacity))}.lg\:focus\:placeholder-pink-300:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#fbb6ce;color:rgba(251,182,206,var(--placeholder-opacity))}.lg\:focus\:placeholder-pink-300:focus::placeholder{--placeholder-opacity:1;color:#fbb6ce;color:rgba(251,182,206,var(--placeholder-opacity))}.lg\:focus\:placeholder-pink-400:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#f687b3;color:rgba(246,135,179,var(--placeholder-opacity))}.lg\:focus\:placeholder-pink-400:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#f687b3;color:rgba(246,135,179,var(--placeholder-opacity))}.lg\:focus\:placeholder-pink-400:focus::placeholder{--placeholder-opacity:1;color:#f687b3;color:rgba(246,135,179,var(--placeholder-opacity))}.lg\:focus\:placeholder-pink-500:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#ed64a6;color:rgba(237,100,166,var(--placeholder-opacity))}.lg\:focus\:placeholder-pink-500:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#ed64a6;color:rgba(237,100,166,var(--placeholder-opacity))}.lg\:focus\:placeholder-pink-500:focus::placeholder{--placeholder-opacity:1;color:#ed64a6;color:rgba(237,100,166,var(--placeholder-opacity))}.lg\:focus\:placeholder-pink-600:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#d53f8c;color:rgba(213,63,140,var(--placeholder-opacity))}.lg\:focus\:placeholder-pink-600:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#d53f8c;color:rgba(213,63,140,var(--placeholder-opacity))}.lg\:focus\:placeholder-pink-600:focus::placeholder{--placeholder-opacity:1;color:#d53f8c;color:rgba(213,63,140,var(--placeholder-opacity))}.lg\:focus\:placeholder-pink-700:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#b83280;color:rgba(184,50,128,var(--placeholder-opacity))}.lg\:focus\:placeholder-pink-700:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#b83280;color:rgba(184,50,128,var(--placeholder-opacity))}.lg\:focus\:placeholder-pink-700:focus::placeholder{--placeholder-opacity:1;color:#b83280;color:rgba(184,50,128,var(--placeholder-opacity))}.lg\:focus\:placeholder-pink-800:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#97266d;color:rgba(151,38,109,var(--placeholder-opacity))}.lg\:focus\:placeholder-pink-800:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#97266d;color:rgba(151,38,109,var(--placeholder-opacity))}.lg\:focus\:placeholder-pink-800:focus::placeholder{--placeholder-opacity:1;color:#97266d;color:rgba(151,38,109,var(--placeholder-opacity))}.lg\:focus\:placeholder-pink-900:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#702459;color:rgba(112,36,89,var(--placeholder-opacity))}.lg\:focus\:placeholder-pink-900:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#702459;color:rgba(112,36,89,var(--placeholder-opacity))}.lg\:focus\:placeholder-pink-900:focus::placeholder{--placeholder-opacity:1;color:#702459;color:rgba(112,36,89,var(--placeholder-opacity))}.lg\:placeholder-opacity-0:-ms-input-placeholder{--placeholder-opacity:0}.lg\:placeholder-opacity-0::-ms-input-placeholder{--placeholder-opacity:0}.lg\:placeholder-opacity-0::placeholder{--placeholder-opacity:0}.lg\:placeholder-opacity-25:-ms-input-placeholder{--placeholder-opacity:0.25}.lg\:placeholder-opacity-25::-ms-input-placeholder{--placeholder-opacity:0.25}.lg\:placeholder-opacity-25::placeholder{--placeholder-opacity:0.25}.lg\:placeholder-opacity-50:-ms-input-placeholder{--placeholder-opacity:0.5}.lg\:placeholder-opacity-50::-ms-input-placeholder{--placeholder-opacity:0.5}.lg\:placeholder-opacity-50::placeholder{--placeholder-opacity:0.5}.lg\:placeholder-opacity-75:-ms-input-placeholder{--placeholder-opacity:0.75}.lg\:placeholder-opacity-75::-ms-input-placeholder{--placeholder-opacity:0.75}.lg\:placeholder-opacity-75::placeholder{--placeholder-opacity:0.75}.lg\:placeholder-opacity-100:-ms-input-placeholder{--placeholder-opacity:1}.lg\:placeholder-opacity-100::-ms-input-placeholder{--placeholder-opacity:1}.lg\:placeholder-opacity-100::placeholder{--placeholder-opacity:1}.lg\:focus\:placeholder-opacity-0:focus:-ms-input-placeholder{--placeholder-opacity:0}.lg\:focus\:placeholder-opacity-0:focus::-ms-input-placeholder{--placeholder-opacity:0}.lg\:focus\:placeholder-opacity-0:focus::placeholder{--placeholder-opacity:0}.lg\:focus\:placeholder-opacity-25:focus:-ms-input-placeholder{--placeholder-opacity:0.25}.lg\:focus\:placeholder-opacity-25:focus::-ms-input-placeholder{--placeholder-opacity:0.25}.lg\:focus\:placeholder-opacity-25:focus::placeholder{--placeholder-opacity:0.25}.lg\:focus\:placeholder-opacity-50:focus:-ms-input-placeholder{--placeholder-opacity:0.5}.lg\:focus\:placeholder-opacity-50:focus::-ms-input-placeholder{--placeholder-opacity:0.5}.lg\:focus\:placeholder-opacity-50:focus::placeholder{--placeholder-opacity:0.5}.lg\:focus\:placeholder-opacity-75:focus:-ms-input-placeholder{--placeholder-opacity:0.75}.lg\:focus\:placeholder-opacity-75:focus::-ms-input-placeholder{--placeholder-opacity:0.75}.lg\:focus\:placeholder-opacity-75:focus::placeholder{--placeholder-opacity:0.75}.lg\:focus\:placeholder-opacity-100:focus:-ms-input-placeholder{--placeholder-opacity:1}.lg\:focus\:placeholder-opacity-100:focus::-ms-input-placeholder{--placeholder-opacity:1}.lg\:focus\:placeholder-opacity-100:focus::placeholder{--placeholder-opacity:1}.lg\:pointer-events-none{pointer-events:none}.lg\:pointer-events-auto{pointer-events:auto}.lg\:static{position:static}.lg\:fixed{position:fixed}.lg\:absolute{position:absolute}.lg\:relative{position:relative}.lg\:sticky{position:-webkit-sticky;position:sticky}.lg\:inset-0{top:0;right:0;bottom:0;left:0}.lg\:inset-auto{top:auto;right:auto;bottom:auto;left:auto}.lg\:inset-y-0{top:0;bottom:0}.lg\:inset-x-0{right:0;left:0}.lg\:inset-y-auto{top:auto;bottom:auto}.lg\:inset-x-auto{right:auto;left:auto}.lg\:top-0{top:0}.lg\:right-0{right:0}.lg\:bottom-0{bottom:0}.lg\:left-0{left:0}.lg\:top-auto{top:auto}.lg\:right-auto{right:auto}.lg\:bottom-auto{bottom:auto}.lg\:left-auto{left:auto}.lg\:resize-none{resize:none}.lg\:resize-y{resize:vertical}.lg\:resize-x{resize:horizontal}.lg\:resize{resize:both}.lg\:shadow-xs{box-shadow:0 0 0 1px rgba(0,0,0,.05)}.lg\:shadow-sm{box-shadow:0 1px 2px 0 rgba(0,0,0,.05)}.lg\:shadow{box-shadow:0 1px 3px 0 rgba(0,0,0,.1),0 1px 2px 0 rgba(0,0,0,.06)}.lg\:shadow-md{box-shadow:0 4px 6px -1px rgba(0,0,0,.1),0 2px 4px -1px rgba(0,0,0,.06)}.lg\:shadow-lg{box-shadow:0 10px 15px -3px rgba(0,0,0,.1),0 4px 6px -2px rgba(0,0,0,.05)}.lg\:shadow-xl{box-shadow:0 20px 25px -5px rgba(0,0,0,.1),0 10px 10px -5px rgba(0,0,0,.04)}.lg\:shadow-2xl{box-shadow:0 25px 50px -12px rgba(0,0,0,.25)}.lg\:shadow-inner{box-shadow:inset 0 2px 4px 0 rgba(0,0,0,.06)}.lg\:shadow-outline{box-shadow:0 0 0 3px rgba(66,153,225,.5)}.lg\:shadow-none{box-shadow:none}.lg\:hover\:shadow-xs:hover{box-shadow:0 0 0 1px rgba(0,0,0,.05)}.lg\:hover\:shadow-sm:hover{box-shadow:0 1px 2px 0 rgba(0,0,0,.05)}.lg\:hover\:shadow:hover{box-shadow:0 1px 3px 0 rgba(0,0,0,.1),0 1px 2px 0 rgba(0,0,0,.06)}.lg\:hover\:shadow-md:hover{box-shadow:0 4px 6px -1px rgba(0,0,0,.1),0 2px 4px -1px rgba(0,0,0,.06)}.lg\:hover\:shadow-lg:hover{box-shadow:0 10px 15px -3px rgba(0,0,0,.1),0 4px 6px -2px rgba(0,0,0,.05)}.lg\:hover\:shadow-xl:hover{box-shadow:0 20px 25px -5px rgba(0,0,0,.1),0 10px 10px -5px rgba(0,0,0,.04)}.lg\:hover\:shadow-2xl:hover{box-shadow:0 25px 50px -12px rgba(0,0,0,.25)}.lg\:hover\:shadow-inner:hover{box-shadow:inset 0 2px 4px 0 rgba(0,0,0,.06)}.lg\:hover\:shadow-outline:hover{box-shadow:0 0 0 3px rgba(66,153,225,.5)}.lg\:hover\:shadow-none:hover{box-shadow:none}.lg\:focus\:shadow-xs:focus{box-shadow:0 0 0 1px rgba(0,0,0,.05)}.lg\:focus\:shadow-sm:focus{box-shadow:0 1px 2px 0 rgba(0,0,0,.05)}.lg\:focus\:shadow:focus{box-shadow:0 1px 3px 0 rgba(0,0,0,.1),0 1px 2px 0 rgba(0,0,0,.06)}.lg\:focus\:shadow-md:focus{box-shadow:0 4px 6px -1px rgba(0,0,0,.1),0 2px 4px -1px rgba(0,0,0,.06)}.lg\:focus\:shadow-lg:focus{box-shadow:0 10px 15px -3px rgba(0,0,0,.1),0 4px 6px -2px rgba(0,0,0,.05)}.lg\:focus\:shadow-xl:focus{box-shadow:0 20px 25px -5px rgba(0,0,0,.1),0 10px 10px -5px rgba(0,0,0,.04)}.lg\:focus\:shadow-2xl:focus{box-shadow:0 25px 50px -12px rgba(0,0,0,.25)}.lg\:focus\:shadow-inner:focus{box-shadow:inset 0 2px 4px 0 rgba(0,0,0,.06)}.lg\:focus\:shadow-outline:focus{box-shadow:0 0 0 3px rgba(66,153,225,.5)}.lg\:focus\:shadow-none:focus{box-shadow:none}.lg\:fill-current{fill:currentColor}.lg\:stroke-current{stroke:currentColor}.lg\:stroke-0{stroke-width:0}.lg\:stroke-1{stroke-width:1}.lg\:stroke-2{stroke-width:2}.lg\:table-auto{table-layout:auto}.lg\:table-fixed{table-layout:fixed}.lg\:text-left{text-align:left}.lg\:text-center{text-align:center}.lg\:text-right{text-align:right}.lg\:text-justify{text-align:justify}.lg\:text-transparent{color:transparent}.lg\:text-current{color:currentColor}.lg\:text-black{--text-opacity:1;color:#000;color:rgba(0,0,0,var(--text-opacity))}.lg\:text-white{--text-opacity:1;color:#fff;color:rgba(255,255,255,var(--text-opacity))}.lg\:text-gray-100{--text-opacity:1;color:#f7fafc;color:rgba(247,250,252,var(--text-opacity))}.lg\:text-gray-200{--text-opacity:1;color:#edf2f7;color:rgba(237,242,247,var(--text-opacity))}.lg\:text-gray-300{--text-opacity:1;color:#e2e8f0;color:rgba(226,232,240,var(--text-opacity))}.lg\:text-gray-400{--text-opacity:1;color:#cbd5e0;color:rgba(203,213,224,var(--text-opacity))}.lg\:text-gray-500{--text-opacity:1;color:#a0aec0;color:rgba(160,174,192,var(--text-opacity))}.lg\:text-gray-600{--text-opacity:1;color:#718096;color:rgba(113,128,150,var(--text-opacity))}.lg\:text-gray-700{--text-opacity:1;color:#4a5568;color:rgba(74,85,104,var(--text-opacity))}.lg\:text-gray-800{--text-opacity:1;color:#2d3748;color:rgba(45,55,72,var(--text-opacity))}.lg\:text-gray-900{--text-opacity:1;color:#1a202c;color:rgba(26,32,44,var(--text-opacity))}.lg\:text-red-100{--text-opacity:1;color:#fff5f5;color:rgba(255,245,245,var(--text-opacity))}.lg\:text-red-200{--text-opacity:1;color:#fed7d7;color:rgba(254,215,215,var(--text-opacity))}.lg\:text-red-300{--text-opacity:1;color:#feb2b2;color:rgba(254,178,178,var(--text-opacity))}.lg\:text-red-400{--text-opacity:1;color:#fc8181;color:rgba(252,129,129,var(--text-opacity))}.lg\:text-red-500{--text-opacity:1;color:#f56565;color:rgba(245,101,101,var(--text-opacity))}.lg\:text-red-600{--text-opacity:1;color:#e53e3e;color:rgba(229,62,62,var(--text-opacity))}.lg\:text-red-700{--text-opacity:1;color:#c53030;color:rgba(197,48,48,var(--text-opacity))}.lg\:text-red-800{--text-opacity:1;color:#9b2c2c;color:rgba(155,44,44,var(--text-opacity))}.lg\:text-red-900{--text-opacity:1;color:#742a2a;color:rgba(116,42,42,var(--text-opacity))}.lg\:text-orange-100{--text-opacity:1;color:#fffaf0;color:rgba(255,250,240,var(--text-opacity))}.lg\:text-orange-200{--text-opacity:1;color:#feebc8;color:rgba(254,235,200,var(--text-opacity))}.lg\:text-orange-300{--text-opacity:1;color:#fbd38d;color:rgba(251,211,141,var(--text-opacity))}.lg\:text-orange-400{--text-opacity:1;color:#f6ad55;color:rgba(246,173,85,var(--text-opacity))}.lg\:text-orange-500{--text-opacity:1;color:#ed8936;color:rgba(237,137,54,var(--text-opacity))}.lg\:text-orange-600{--text-opacity:1;color:#dd6b20;color:rgba(221,107,32,var(--text-opacity))}.lg\:text-orange-700{--text-opacity:1;color:#c05621;color:rgba(192,86,33,var(--text-opacity))}.lg\:text-orange-800{--text-opacity:1;color:#9c4221;color:rgba(156,66,33,var(--text-opacity))}.lg\:text-orange-900{--text-opacity:1;color:#7b341e;color:rgba(123,52,30,var(--text-opacity))}.lg\:text-yellow-100{--text-opacity:1;color:ivory;color:rgba(255,255,240,var(--text-opacity))}.lg\:text-yellow-200{--text-opacity:1;color:#fefcbf;color:rgba(254,252,191,var(--text-opacity))}.lg\:text-yellow-300{--text-opacity:1;color:#faf089;color:rgba(250,240,137,var(--text-opacity))}.lg\:text-yellow-400{--text-opacity:1;color:#f6e05e;color:rgba(246,224,94,var(--text-opacity))}.lg\:text-yellow-500{--text-opacity:1;color:#ecc94b;color:rgba(236,201,75,var(--text-opacity))}.lg\:text-yellow-600{--text-opacity:1;color:#d69e2e;color:rgba(214,158,46,var(--text-opacity))}.lg\:text-yellow-700{--text-opacity:1;color:#b7791f;color:rgba(183,121,31,var(--text-opacity))}.lg\:text-yellow-800{--text-opacity:1;color:#975a16;color:rgba(151,90,22,var(--text-opacity))}.lg\:text-yellow-900{--text-opacity:1;color:#744210;color:rgba(116,66,16,var(--text-opacity))}.lg\:text-green-100{--text-opacity:1;color:#f0fff4;color:rgba(240,255,244,var(--text-opacity))}.lg\:text-green-200{--text-opacity:1;color:#c6f6d5;color:rgba(198,246,213,var(--text-opacity))}.lg\:text-green-300{--text-opacity:1;color:#9ae6b4;color:rgba(154,230,180,var(--text-opacity))}.lg\:text-green-400{--text-opacity:1;color:#68d391;color:rgba(104,211,145,var(--text-opacity))}.lg\:text-green-500{--text-opacity:1;color:#48bb78;color:rgba(72,187,120,var(--text-opacity))}.lg\:text-green-600{--text-opacity:1;color:#38a169;color:rgba(56,161,105,var(--text-opacity))}.lg\:text-green-700{--text-opacity:1;color:#2f855a;color:rgba(47,133,90,var(--text-opacity))}.lg\:text-green-800{--text-opacity:1;color:#276749;color:rgba(39,103,73,var(--text-opacity))}.lg\:text-green-900{--text-opacity:1;color:#22543d;color:rgba(34,84,61,var(--text-opacity))}.lg\:text-teal-100{--text-opacity:1;color:#e6fffa;color:rgba(230,255,250,var(--text-opacity))}.lg\:text-teal-200{--text-opacity:1;color:#b2f5ea;color:rgba(178,245,234,var(--text-opacity))}.lg\:text-teal-300{--text-opacity:1;color:#81e6d9;color:rgba(129,230,217,var(--text-opacity))}.lg\:text-teal-400{--text-opacity:1;color:#4fd1c5;color:rgba(79,209,197,var(--text-opacity))}.lg\:text-teal-500{--text-opacity:1;color:#38b2ac;color:rgba(56,178,172,var(--text-opacity))}.lg\:text-teal-600{--text-opacity:1;color:#319795;color:rgba(49,151,149,var(--text-opacity))}.lg\:text-teal-700{--text-opacity:1;color:#2c7a7b;color:rgba(44,122,123,var(--text-opacity))}.lg\:text-teal-800{--text-opacity:1;color:#285e61;color:rgba(40,94,97,var(--text-opacity))}.lg\:text-teal-900{--text-opacity:1;color:#234e52;color:rgba(35,78,82,var(--text-opacity))}.lg\:text-blue-100{--text-opacity:1;color:#ebf8ff;color:rgba(235,248,255,var(--text-opacity))}.lg\:text-blue-200{--text-opacity:1;color:#bee3f8;color:rgba(190,227,248,var(--text-opacity))}.lg\:text-blue-300{--text-opacity:1;color:#90cdf4;color:rgba(144,205,244,var(--text-opacity))}.lg\:text-blue-400{--text-opacity:1;color:#63b3ed;color:rgba(99,179,237,var(--text-opacity))}.lg\:text-blue-500{--text-opacity:1;color:#4299e1;color:rgba(66,153,225,var(--text-opacity))}.lg\:text-blue-600{--text-opacity:1;color:#3182ce;color:rgba(49,130,206,var(--text-opacity))}.lg\:text-blue-700{--text-opacity:1;color:#2b6cb0;color:rgba(43,108,176,var(--text-opacity))}.lg\:text-blue-800{--text-opacity:1;color:#2c5282;color:rgba(44,82,130,var(--text-opacity))}.lg\:text-blue-900{--text-opacity:1;color:#2a4365;color:rgba(42,67,101,var(--text-opacity))}.lg\:text-indigo-100{--text-opacity:1;color:#ebf4ff;color:rgba(235,244,255,var(--text-opacity))}.lg\:text-indigo-200{--text-opacity:1;color:#c3dafe;color:rgba(195,218,254,var(--text-opacity))}.lg\:text-indigo-300{--text-opacity:1;color:#a3bffa;color:rgba(163,191,250,var(--text-opacity))}.lg\:text-indigo-400{--text-opacity:1;color:#7f9cf5;color:rgba(127,156,245,var(--text-opacity))}.lg\:text-indigo-500{--text-opacity:1;color:#667eea;color:rgba(102,126,234,var(--text-opacity))}.lg\:text-indigo-600{--text-opacity:1;color:#5a67d8;color:rgba(90,103,216,var(--text-opacity))}.lg\:text-indigo-700{--text-opacity:1;color:#4c51bf;color:rgba(76,81,191,var(--text-opacity))}.lg\:text-indigo-800{--text-opacity:1;color:#434190;color:rgba(67,65,144,var(--text-opacity))}.lg\:text-indigo-900{--text-opacity:1;color:#3c366b;color:rgba(60,54,107,var(--text-opacity))}.lg\:text-purple-100{--text-opacity:1;color:#faf5ff;color:rgba(250,245,255,var(--text-opacity))}.lg\:text-purple-200{--text-opacity:1;color:#e9d8fd;color:rgba(233,216,253,var(--text-opacity))}.lg\:text-purple-300{--text-opacity:1;color:#d6bcfa;color:rgba(214,188,250,var(--text-opacity))}.lg\:text-purple-400{--text-opacity:1;color:#b794f4;color:rgba(183,148,244,var(--text-opacity))}.lg\:text-purple-500{--text-opacity:1;color:#9f7aea;color:rgba(159,122,234,var(--text-opacity))}.lg\:text-purple-600{--text-opacity:1;color:#805ad5;color:rgba(128,90,213,var(--text-opacity))}.lg\:text-purple-700{--text-opacity:1;color:#6b46c1;color:rgba(107,70,193,var(--text-opacity))}.lg\:text-purple-800{--text-opacity:1;color:#553c9a;color:rgba(85,60,154,var(--text-opacity))}.lg\:text-purple-900{--text-opacity:1;color:#44337a;color:rgba(68,51,122,var(--text-opacity))}.lg\:text-pink-100{--text-opacity:1;color:#fff5f7;color:rgba(255,245,247,var(--text-opacity))}.lg\:text-pink-200{--text-opacity:1;color:#fed7e2;color:rgba(254,215,226,var(--text-opacity))}.lg\:text-pink-300{--text-opacity:1;color:#fbb6ce;color:rgba(251,182,206,var(--text-opacity))}.lg\:text-pink-400{--text-opacity:1;color:#f687b3;color:rgba(246,135,179,var(--text-opacity))}.lg\:text-pink-500{--text-opacity:1;color:#ed64a6;color:rgba(237,100,166,var(--text-opacity))}.lg\:text-pink-600{--text-opacity:1;color:#d53f8c;color:rgba(213,63,140,var(--text-opacity))}.lg\:text-pink-700{--text-opacity:1;color:#b83280;color:rgba(184,50,128,var(--text-opacity))}.lg\:text-pink-800{--text-opacity:1;color:#97266d;color:rgba(151,38,109,var(--text-opacity))}.lg\:text-pink-900{--text-opacity:1;color:#702459;color:rgba(112,36,89,var(--text-opacity))}.lg\:hover\:text-transparent:hover{color:transparent}.lg\:hover\:text-current:hover{color:currentColor}.lg\:hover\:text-black:hover{--text-opacity:1;color:#000;color:rgba(0,0,0,var(--text-opacity))}.lg\:hover\:text-white:hover{--text-opacity:1;color:#fff;color:rgba(255,255,255,var(--text-opacity))}.lg\:hover\:text-gray-100:hover{--text-opacity:1;color:#f7fafc;color:rgba(247,250,252,var(--text-opacity))}.lg\:hover\:text-gray-200:hover{--text-opacity:1;color:#edf2f7;color:rgba(237,242,247,var(--text-opacity))}.lg\:hover\:text-gray-300:hover{--text-opacity:1;color:#e2e8f0;color:rgba(226,232,240,var(--text-opacity))}.lg\:hover\:text-gray-400:hover{--text-opacity:1;color:#cbd5e0;color:rgba(203,213,224,var(--text-opacity))}.lg\:hover\:text-gray-500:hover{--text-opacity:1;color:#a0aec0;color:rgba(160,174,192,var(--text-opacity))}.lg\:hover\:text-gray-600:hover{--text-opacity:1;color:#718096;color:rgba(113,128,150,var(--text-opacity))}.lg\:hover\:text-gray-700:hover{--text-opacity:1;color:#4a5568;color:rgba(74,85,104,var(--text-opacity))}.lg\:hover\:text-gray-800:hover{--text-opacity:1;color:#2d3748;color:rgba(45,55,72,var(--text-opacity))}.lg\:hover\:text-gray-900:hover{--text-opacity:1;color:#1a202c;color:rgba(26,32,44,var(--text-opacity))}.lg\:hover\:text-red-100:hover{--text-opacity:1;color:#fff5f5;color:rgba(255,245,245,var(--text-opacity))}.lg\:hover\:text-red-200:hover{--text-opacity:1;color:#fed7d7;color:rgba(254,215,215,var(--text-opacity))}.lg\:hover\:text-red-300:hover{--text-opacity:1;color:#feb2b2;color:rgba(254,178,178,var(--text-opacity))}.lg\:hover\:text-red-400:hover{--text-opacity:1;color:#fc8181;color:rgba(252,129,129,var(--text-opacity))}.lg\:hover\:text-red-500:hover{--text-opacity:1;color:#f56565;color:rgba(245,101,101,var(--text-opacity))}.lg\:hover\:text-red-600:hover{--text-opacity:1;color:#e53e3e;color:rgba(229,62,62,var(--text-opacity))}.lg\:hover\:text-red-700:hover{--text-opacity:1;color:#c53030;color:rgba(197,48,48,var(--text-opacity))}.lg\:hover\:text-red-800:hover{--text-opacity:1;color:#9b2c2c;color:rgba(155,44,44,var(--text-opacity))}.lg\:hover\:text-red-900:hover{--text-opacity:1;color:#742a2a;color:rgba(116,42,42,var(--text-opacity))}.lg\:hover\:text-orange-100:hover{--text-opacity:1;color:#fffaf0;color:rgba(255,250,240,var(--text-opacity))}.lg\:hover\:text-orange-200:hover{--text-opacity:1;color:#feebc8;color:rgba(254,235,200,var(--text-opacity))}.lg\:hover\:text-orange-300:hover{--text-opacity:1;color:#fbd38d;color:rgba(251,211,141,var(--text-opacity))}.lg\:hover\:text-orange-400:hover{--text-opacity:1;color:#f6ad55;color:rgba(246,173,85,var(--text-opacity))}.lg\:hover\:text-orange-500:hover{--text-opacity:1;color:#ed8936;color:rgba(237,137,54,var(--text-opacity))}.lg\:hover\:text-orange-600:hover{--text-opacity:1;color:#dd6b20;color:rgba(221,107,32,var(--text-opacity))}.lg\:hover\:text-orange-700:hover{--text-opacity:1;color:#c05621;color:rgba(192,86,33,var(--text-opacity))}.lg\:hover\:text-orange-800:hover{--text-opacity:1;color:#9c4221;color:rgba(156,66,33,var(--text-opacity))}.lg\:hover\:text-orange-900:hover{--text-opacity:1;color:#7b341e;color:rgba(123,52,30,var(--text-opacity))}.lg\:hover\:text-yellow-100:hover{--text-opacity:1;color:ivory;color:rgba(255,255,240,var(--text-opacity))}.lg\:hover\:text-yellow-200:hover{--text-opacity:1;color:#fefcbf;color:rgba(254,252,191,var(--text-opacity))}.lg\:hover\:text-yellow-300:hover{--text-opacity:1;color:#faf089;color:rgba(250,240,137,var(--text-opacity))}.lg\:hover\:text-yellow-400:hover{--text-opacity:1;color:#f6e05e;color:rgba(246,224,94,var(--text-opacity))}.lg\:hover\:text-yellow-500:hover{--text-opacity:1;color:#ecc94b;color:rgba(236,201,75,var(--text-opacity))}.lg\:hover\:text-yellow-600:hover{--text-opacity:1;color:#d69e2e;color:rgba(214,158,46,var(--text-opacity))}.lg\:hover\:text-yellow-700:hover{--text-opacity:1;color:#b7791f;color:rgba(183,121,31,var(--text-opacity))}.lg\:hover\:text-yellow-800:hover{--text-opacity:1;color:#975a16;color:rgba(151,90,22,var(--text-opacity))}.lg\:hover\:text-yellow-900:hover{--text-opacity:1;color:#744210;color:rgba(116,66,16,var(--text-opacity))}.lg\:hover\:text-green-100:hover{--text-opacity:1;color:#f0fff4;color:rgba(240,255,244,var(--text-opacity))}.lg\:hover\:text-green-200:hover{--text-opacity:1;color:#c6f6d5;color:rgba(198,246,213,var(--text-opacity))}.lg\:hover\:text-green-300:hover{--text-opacity:1;color:#9ae6b4;color:rgba(154,230,180,var(--text-opacity))}.lg\:hover\:text-green-400:hover{--text-opacity:1;color:#68d391;color:rgba(104,211,145,var(--text-opacity))}.lg\:hover\:text-green-500:hover{--text-opacity:1;color:#48bb78;color:rgba(72,187,120,var(--text-opacity))}.lg\:hover\:text-green-600:hover{--text-opacity:1;color:#38a169;color:rgba(56,161,105,var(--text-opacity))}.lg\:hover\:text-green-700:hover{--text-opacity:1;color:#2f855a;color:rgba(47,133,90,var(--text-opacity))}.lg\:hover\:text-green-800:hover{--text-opacity:1;color:#276749;color:rgba(39,103,73,var(--text-opacity))}.lg\:hover\:text-green-900:hover{--text-opacity:1;color:#22543d;color:rgba(34,84,61,var(--text-opacity))}.lg\:hover\:text-teal-100:hover{--text-opacity:1;color:#e6fffa;color:rgba(230,255,250,var(--text-opacity))}.lg\:hover\:text-teal-200:hover{--text-opacity:1;color:#b2f5ea;color:rgba(178,245,234,var(--text-opacity))}.lg\:hover\:text-teal-300:hover{--text-opacity:1;color:#81e6d9;color:rgba(129,230,217,var(--text-opacity))}.lg\:hover\:text-teal-400:hover{--text-opacity:1;color:#4fd1c5;color:rgba(79,209,197,var(--text-opacity))}.lg\:hover\:text-teal-500:hover{--text-opacity:1;color:#38b2ac;color:rgba(56,178,172,var(--text-opacity))}.lg\:hover\:text-teal-600:hover{--text-opacity:1;color:#319795;color:rgba(49,151,149,var(--text-opacity))}.lg\:hover\:text-teal-700:hover{--text-opacity:1;color:#2c7a7b;color:rgba(44,122,123,var(--text-opacity))}.lg\:hover\:text-teal-800:hover{--text-opacity:1;color:#285e61;color:rgba(40,94,97,var(--text-opacity))}.lg\:hover\:text-teal-900:hover{--text-opacity:1;color:#234e52;color:rgba(35,78,82,var(--text-opacity))}.lg\:hover\:text-blue-100:hover{--text-opacity:1;color:#ebf8ff;color:rgba(235,248,255,var(--text-opacity))}.lg\:hover\:text-blue-200:hover{--text-opacity:1;color:#bee3f8;color:rgba(190,227,248,var(--text-opacity))}.lg\:hover\:text-blue-300:hover{--text-opacity:1;color:#90cdf4;color:rgba(144,205,244,var(--text-opacity))}.lg\:hover\:text-blue-400:hover{--text-opacity:1;color:#63b3ed;color:rgba(99,179,237,var(--text-opacity))}.lg\:hover\:text-blue-500:hover{--text-opacity:1;color:#4299e1;color:rgba(66,153,225,var(--text-opacity))}.lg\:hover\:text-blue-600:hover{--text-opacity:1;color:#3182ce;color:rgba(49,130,206,var(--text-opacity))}.lg\:hover\:text-blue-700:hover{--text-opacity:1;color:#2b6cb0;color:rgba(43,108,176,var(--text-opacity))}.lg\:hover\:text-blue-800:hover{--text-opacity:1;color:#2c5282;color:rgba(44,82,130,var(--text-opacity))}.lg\:hover\:text-blue-900:hover{--text-opacity:1;color:#2a4365;color:rgba(42,67,101,var(--text-opacity))}.lg\:hover\:text-indigo-100:hover{--text-opacity:1;color:#ebf4ff;color:rgba(235,244,255,var(--text-opacity))}.lg\:hover\:text-indigo-200:hover{--text-opacity:1;color:#c3dafe;color:rgba(195,218,254,var(--text-opacity))}.lg\:hover\:text-indigo-300:hover{--text-opacity:1;color:#a3bffa;color:rgba(163,191,250,var(--text-opacity))}.lg\:hover\:text-indigo-400:hover{--text-opacity:1;color:#7f9cf5;color:rgba(127,156,245,var(--text-opacity))}.lg\:hover\:text-indigo-500:hover{--text-opacity:1;color:#667eea;color:rgba(102,126,234,var(--text-opacity))}.lg\:hover\:text-indigo-600:hover{--text-opacity:1;color:#5a67d8;color:rgba(90,103,216,var(--text-opacity))}.lg\:hover\:text-indigo-700:hover{--text-opacity:1;color:#4c51bf;color:rgba(76,81,191,var(--text-opacity))}.lg\:hover\:text-indigo-800:hover{--text-opacity:1;color:#434190;color:rgba(67,65,144,var(--text-opacity))}.lg\:hover\:text-indigo-900:hover{--text-opacity:1;color:#3c366b;color:rgba(60,54,107,var(--text-opacity))}.lg\:hover\:text-purple-100:hover{--text-opacity:1;color:#faf5ff;color:rgba(250,245,255,var(--text-opacity))}.lg\:hover\:text-purple-200:hover{--text-opacity:1;color:#e9d8fd;color:rgba(233,216,253,var(--text-opacity))}.lg\:hover\:text-purple-300:hover{--text-opacity:1;color:#d6bcfa;color:rgba(214,188,250,var(--text-opacity))}.lg\:hover\:text-purple-400:hover{--text-opacity:1;color:#b794f4;color:rgba(183,148,244,var(--text-opacity))}.lg\:hover\:text-purple-500:hover{--text-opacity:1;color:#9f7aea;color:rgba(159,122,234,var(--text-opacity))}.lg\:hover\:text-purple-600:hover{--text-opacity:1;color:#805ad5;color:rgba(128,90,213,var(--text-opacity))}.lg\:hover\:text-purple-700:hover{--text-opacity:1;color:#6b46c1;color:rgba(107,70,193,var(--text-opacity))}.lg\:hover\:text-purple-800:hover{--text-opacity:1;color:#553c9a;color:rgba(85,60,154,var(--text-opacity))}.lg\:hover\:text-purple-900:hover{--text-opacity:1;color:#44337a;color:rgba(68,51,122,var(--text-opacity))}.lg\:hover\:text-pink-100:hover{--text-opacity:1;color:#fff5f7;color:rgba(255,245,247,var(--text-opacity))}.lg\:hover\:text-pink-200:hover{--text-opacity:1;color:#fed7e2;color:rgba(254,215,226,var(--text-opacity))}.lg\:hover\:text-pink-300:hover{--text-opacity:1;color:#fbb6ce;color:rgba(251,182,206,var(--text-opacity))}.lg\:hover\:text-pink-400:hover{--text-opacity:1;color:#f687b3;color:rgba(246,135,179,var(--text-opacity))}.lg\:hover\:text-pink-500:hover{--text-opacity:1;color:#ed64a6;color:rgba(237,100,166,var(--text-opacity))}.lg\:hover\:text-pink-600:hover{--text-opacity:1;color:#d53f8c;color:rgba(213,63,140,var(--text-opacity))}.lg\:hover\:text-pink-700:hover{--text-opacity:1;color:#b83280;color:rgba(184,50,128,var(--text-opacity))}.lg\:hover\:text-pink-800:hover{--text-opacity:1;color:#97266d;color:rgba(151,38,109,var(--text-opacity))}.lg\:hover\:text-pink-900:hover{--text-opacity:1;color:#702459;color:rgba(112,36,89,var(--text-opacity))}.lg\:focus\:text-transparent:focus{color:transparent}.lg\:focus\:text-current:focus{color:currentColor}.lg\:focus\:text-black:focus{--text-opacity:1;color:#000;color:rgba(0,0,0,var(--text-opacity))}.lg\:focus\:text-white:focus{--text-opacity:1;color:#fff;color:rgba(255,255,255,var(--text-opacity))}.lg\:focus\:text-gray-100:focus{--text-opacity:1;color:#f7fafc;color:rgba(247,250,252,var(--text-opacity))}.lg\:focus\:text-gray-200:focus{--text-opacity:1;color:#edf2f7;color:rgba(237,242,247,var(--text-opacity))}.lg\:focus\:text-gray-300:focus{--text-opacity:1;color:#e2e8f0;color:rgba(226,232,240,var(--text-opacity))}.lg\:focus\:text-gray-400:focus{--text-opacity:1;color:#cbd5e0;color:rgba(203,213,224,var(--text-opacity))}.lg\:focus\:text-gray-500:focus{--text-opacity:1;color:#a0aec0;color:rgba(160,174,192,var(--text-opacity))}.lg\:focus\:text-gray-600:focus{--text-opacity:1;color:#718096;color:rgba(113,128,150,var(--text-opacity))}.lg\:focus\:text-gray-700:focus{--text-opacity:1;color:#4a5568;color:rgba(74,85,104,var(--text-opacity))}.lg\:focus\:text-gray-800:focus{--text-opacity:1;color:#2d3748;color:rgba(45,55,72,var(--text-opacity))}.lg\:focus\:text-gray-900:focus{--text-opacity:1;color:#1a202c;color:rgba(26,32,44,var(--text-opacity))}.lg\:focus\:text-red-100:focus{--text-opacity:1;color:#fff5f5;color:rgba(255,245,245,var(--text-opacity))}.lg\:focus\:text-red-200:focus{--text-opacity:1;color:#fed7d7;color:rgba(254,215,215,var(--text-opacity))}.lg\:focus\:text-red-300:focus{--text-opacity:1;color:#feb2b2;color:rgba(254,178,178,var(--text-opacity))}.lg\:focus\:text-red-400:focus{--text-opacity:1;color:#fc8181;color:rgba(252,129,129,var(--text-opacity))}.lg\:focus\:text-red-500:focus{--text-opacity:1;color:#f56565;color:rgba(245,101,101,var(--text-opacity))}.lg\:focus\:text-red-600:focus{--text-opacity:1;color:#e53e3e;color:rgba(229,62,62,var(--text-opacity))}.lg\:focus\:text-red-700:focus{--text-opacity:1;color:#c53030;color:rgba(197,48,48,var(--text-opacity))}.lg\:focus\:text-red-800:focus{--text-opacity:1;color:#9b2c2c;color:rgba(155,44,44,var(--text-opacity))}.lg\:focus\:text-red-900:focus{--text-opacity:1;color:#742a2a;color:rgba(116,42,42,var(--text-opacity))}.lg\:focus\:text-orange-100:focus{--text-opacity:1;color:#fffaf0;color:rgba(255,250,240,var(--text-opacity))}.lg\:focus\:text-orange-200:focus{--text-opacity:1;color:#feebc8;color:rgba(254,235,200,var(--text-opacity))}.lg\:focus\:text-orange-300:focus{--text-opacity:1;color:#fbd38d;color:rgba(251,211,141,var(--text-opacity))}.lg\:focus\:text-orange-400:focus{--text-opacity:1;color:#f6ad55;color:rgba(246,173,85,var(--text-opacity))}.lg\:focus\:text-orange-500:focus{--text-opacity:1;color:#ed8936;color:rgba(237,137,54,var(--text-opacity))}.lg\:focus\:text-orange-600:focus{--text-opacity:1;color:#dd6b20;color:rgba(221,107,32,var(--text-opacity))}.lg\:focus\:text-orange-700:focus{--text-opacity:1;color:#c05621;color:rgba(192,86,33,var(--text-opacity))}.lg\:focus\:text-orange-800:focus{--text-opacity:1;color:#9c4221;color:rgba(156,66,33,var(--text-opacity))}.lg\:focus\:text-orange-900:focus{--text-opacity:1;color:#7b341e;color:rgba(123,52,30,var(--text-opacity))}.lg\:focus\:text-yellow-100:focus{--text-opacity:1;color:ivory;color:rgba(255,255,240,var(--text-opacity))}.lg\:focus\:text-yellow-200:focus{--text-opacity:1;color:#fefcbf;color:rgba(254,252,191,var(--text-opacity))}.lg\:focus\:text-yellow-300:focus{--text-opacity:1;color:#faf089;color:rgba(250,240,137,var(--text-opacity))}.lg\:focus\:text-yellow-400:focus{--text-opacity:1;color:#f6e05e;color:rgba(246,224,94,var(--text-opacity))}.lg\:focus\:text-yellow-500:focus{--text-opacity:1;color:#ecc94b;color:rgba(236,201,75,var(--text-opacity))}.lg\:focus\:text-yellow-600:focus{--text-opacity:1;color:#d69e2e;color:rgba(214,158,46,var(--text-opacity))}.lg\:focus\:text-yellow-700:focus{--text-opacity:1;color:#b7791f;color:rgba(183,121,31,var(--text-opacity))}.lg\:focus\:text-yellow-800:focus{--text-opacity:1;color:#975a16;color:rgba(151,90,22,var(--text-opacity))}.lg\:focus\:text-yellow-900:focus{--text-opacity:1;color:#744210;color:rgba(116,66,16,var(--text-opacity))}.lg\:focus\:text-green-100:focus{--text-opacity:1;color:#f0fff4;color:rgba(240,255,244,var(--text-opacity))}.lg\:focus\:text-green-200:focus{--text-opacity:1;color:#c6f6d5;color:rgba(198,246,213,var(--text-opacity))}.lg\:focus\:text-green-300:focus{--text-opacity:1;color:#9ae6b4;color:rgba(154,230,180,var(--text-opacity))}.lg\:focus\:text-green-400:focus{--text-opacity:1;color:#68d391;color:rgba(104,211,145,var(--text-opacity))}.lg\:focus\:text-green-500:focus{--text-opacity:1;color:#48bb78;color:rgba(72,187,120,var(--text-opacity))}.lg\:focus\:text-green-600:focus{--text-opacity:1;color:#38a169;color:rgba(56,161,105,var(--text-opacity))}.lg\:focus\:text-green-700:focus{--text-opacity:1;color:#2f855a;color:rgba(47,133,90,var(--text-opacity))}.lg\:focus\:text-green-800:focus{--text-opacity:1;color:#276749;color:rgba(39,103,73,var(--text-opacity))}.lg\:focus\:text-green-900:focus{--text-opacity:1;color:#22543d;color:rgba(34,84,61,var(--text-opacity))}.lg\:focus\:text-teal-100:focus{--text-opacity:1;color:#e6fffa;color:rgba(230,255,250,var(--text-opacity))}.lg\:focus\:text-teal-200:focus{--text-opacity:1;color:#b2f5ea;color:rgba(178,245,234,var(--text-opacity))}.lg\:focus\:text-teal-300:focus{--text-opacity:1;color:#81e6d9;color:rgba(129,230,217,var(--text-opacity))}.lg\:focus\:text-teal-400:focus{--text-opacity:1;color:#4fd1c5;color:rgba(79,209,197,var(--text-opacity))}.lg\:focus\:text-teal-500:focus{--text-opacity:1;color:#38b2ac;color:rgba(56,178,172,var(--text-opacity))}.lg\:focus\:text-teal-600:focus{--text-opacity:1;color:#319795;color:rgba(49,151,149,var(--text-opacity))}.lg\:focus\:text-teal-700:focus{--text-opacity:1;color:#2c7a7b;color:rgba(44,122,123,var(--text-opacity))}.lg\:focus\:text-teal-800:focus{--text-opacity:1;color:#285e61;color:rgba(40,94,97,var(--text-opacity))}.lg\:focus\:text-teal-900:focus{--text-opacity:1;color:#234e52;color:rgba(35,78,82,var(--text-opacity))}.lg\:focus\:text-blue-100:focus{--text-opacity:1;color:#ebf8ff;color:rgba(235,248,255,var(--text-opacity))}.lg\:focus\:text-blue-200:focus{--text-opacity:1;color:#bee3f8;color:rgba(190,227,248,var(--text-opacity))}.lg\:focus\:text-blue-300:focus{--text-opacity:1;color:#90cdf4;color:rgba(144,205,244,var(--text-opacity))}.lg\:focus\:text-blue-400:focus{--text-opacity:1;color:#63b3ed;color:rgba(99,179,237,var(--text-opacity))}.lg\:focus\:text-blue-500:focus{--text-opacity:1;color:#4299e1;color:rgba(66,153,225,var(--text-opacity))}.lg\:focus\:text-blue-600:focus{--text-opacity:1;color:#3182ce;color:rgba(49,130,206,var(--text-opacity))}.lg\:focus\:text-blue-700:focus{--text-opacity:1;color:#2b6cb0;color:rgba(43,108,176,var(--text-opacity))}.lg\:focus\:text-blue-800:focus{--text-opacity:1;color:#2c5282;color:rgba(44,82,130,var(--text-opacity))}.lg\:focus\:text-blue-900:focus{--text-opacity:1;color:#2a4365;color:rgba(42,67,101,var(--text-opacity))}.lg\:focus\:text-indigo-100:focus{--text-opacity:1;color:#ebf4ff;color:rgba(235,244,255,var(--text-opacity))}.lg\:focus\:text-indigo-200:focus{--text-opacity:1;color:#c3dafe;color:rgba(195,218,254,var(--text-opacity))}.lg\:focus\:text-indigo-300:focus{--text-opacity:1;color:#a3bffa;color:rgba(163,191,250,var(--text-opacity))}.lg\:focus\:text-indigo-400:focus{--text-opacity:1;color:#7f9cf5;color:rgba(127,156,245,var(--text-opacity))}.lg\:focus\:text-indigo-500:focus{--text-opacity:1;color:#667eea;color:rgba(102,126,234,var(--text-opacity))}.lg\:focus\:text-indigo-600:focus{--text-opacity:1;color:#5a67d8;color:rgba(90,103,216,var(--text-opacity))}.lg\:focus\:text-indigo-700:focus{--text-opacity:1;color:#4c51bf;color:rgba(76,81,191,var(--text-opacity))}.lg\:focus\:text-indigo-800:focus{--text-opacity:1;color:#434190;color:rgba(67,65,144,var(--text-opacity))}.lg\:focus\:text-indigo-900:focus{--text-opacity:1;color:#3c366b;color:rgba(60,54,107,var(--text-opacity))}.lg\:focus\:text-purple-100:focus{--text-opacity:1;color:#faf5ff;color:rgba(250,245,255,var(--text-opacity))}.lg\:focus\:text-purple-200:focus{--text-opacity:1;color:#e9d8fd;color:rgba(233,216,253,var(--text-opacity))}.lg\:focus\:text-purple-300:focus{--text-opacity:1;color:#d6bcfa;color:rgba(214,188,250,var(--text-opacity))}.lg\:focus\:text-purple-400:focus{--text-opacity:1;color:#b794f4;color:rgba(183,148,244,var(--text-opacity))}.lg\:focus\:text-purple-500:focus{--text-opacity:1;color:#9f7aea;color:rgba(159,122,234,var(--text-opacity))}.lg\:focus\:text-purple-600:focus{--text-opacity:1;color:#805ad5;color:rgba(128,90,213,var(--text-opacity))}.lg\:focus\:text-purple-700:focus{--text-opacity:1;color:#6b46c1;color:rgba(107,70,193,var(--text-opacity))}.lg\:focus\:text-purple-800:focus{--text-opacity:1;color:#553c9a;color:rgba(85,60,154,var(--text-opacity))}.lg\:focus\:text-purple-900:focus{--text-opacity:1;color:#44337a;color:rgba(68,51,122,var(--text-opacity))}.lg\:focus\:text-pink-100:focus{--text-opacity:1;color:#fff5f7;color:rgba(255,245,247,var(--text-opacity))}.lg\:focus\:text-pink-200:focus{--text-opacity:1;color:#fed7e2;color:rgba(254,215,226,var(--text-opacity))}.lg\:focus\:text-pink-300:focus{--text-opacity:1;color:#fbb6ce;color:rgba(251,182,206,var(--text-opacity))}.lg\:focus\:text-pink-400:focus{--text-opacity:1;color:#f687b3;color:rgba(246,135,179,var(--text-opacity))}.lg\:focus\:text-pink-500:focus{--text-opacity:1;color:#ed64a6;color:rgba(237,100,166,var(--text-opacity))}.lg\:focus\:text-pink-600:focus{--text-opacity:1;color:#d53f8c;color:rgba(213,63,140,var(--text-opacity))}.lg\:focus\:text-pink-700:focus{--text-opacity:1;color:#b83280;color:rgba(184,50,128,var(--text-opacity))}.lg\:focus\:text-pink-800:focus{--text-opacity:1;color:#97266d;color:rgba(151,38,109,var(--text-opacity))}.lg\:focus\:text-pink-900:focus{--text-opacity:1;color:#702459;color:rgba(112,36,89,var(--text-opacity))}.lg\:text-opacity-0{--text-opacity:0}.lg\:text-opacity-25{--text-opacity:0.25}.lg\:text-opacity-50{--text-opacity:0.5}.lg\:text-opacity-75{--text-opacity:0.75}.lg\:text-opacity-100{--text-opacity:1}.lg\:hover\:text-opacity-0:hover{--text-opacity:0}.lg\:hover\:text-opacity-25:hover{--text-opacity:0.25}.lg\:hover\:text-opacity-50:hover{--text-opacity:0.5}.lg\:hover\:text-opacity-75:hover{--text-opacity:0.75}.lg\:hover\:text-opacity-100:hover{--text-opacity:1}.lg\:focus\:text-opacity-0:focus{--text-opacity:0}.lg\:focus\:text-opacity-25:focus{--text-opacity:0.25}.lg\:focus\:text-opacity-50:focus{--text-opacity:0.5}.lg\:focus\:text-opacity-75:focus{--text-opacity:0.75}.lg\:focus\:text-opacity-100:focus{--text-opacity:1}.lg\:italic{font-style:italic}.lg\:not-italic{font-style:normal}.lg\:uppercase{text-transform:uppercase}.lg\:lowercase{text-transform:lowercase}.lg\:capitalize{text-transform:capitalize}.lg\:normal-case{text-transform:none}.lg\:underline{text-decoration:underline}.lg\:line-through{text-decoration:line-through}.lg\:no-underline{text-decoration:none}.lg\:hover\:underline:hover{text-decoration:underline}.lg\:hover\:line-through:hover{text-decoration:line-through}.lg\:hover\:no-underline:hover{text-decoration:none}.lg\:focus\:underline:focus{text-decoration:underline}.lg\:focus\:line-through:focus{text-decoration:line-through}.lg\:focus\:no-underline:focus{text-decoration:none}.lg\:antialiased{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.lg\:subpixel-antialiased{-webkit-font-smoothing:auto;-moz-osx-font-smoothing:auto}.lg\:diagonal-fractions,.lg\:lining-nums,.lg\:oldstyle-nums,.lg\:ordinal,.lg\:proportional-nums,.lg\:slashed-zero,.lg\:stacked-fractions,.lg\:tabular-nums{--font-variant-numeric-ordinal:var(--tailwind-empty, );/*!*//*!*/--font-variant-numeric-slashed-zero:var(--tailwind-empty, );/*!*//*!*/--font-variant-numeric-figure:var(--tailwind-empty, );/*!*//*!*/--font-variant-numeric-spacing:var(--tailwind-empty, );/*!*//*!*/--font-variant-numeric-fraction:var(--tailwind-empty, );/*!*//*!*/font-variant-numeric:var(--font-variant-numeric-ordinal) var(--font-variant-numeric-slashed-zero) var(--font-variant-numeric-figure) var(--font-variant-numeric-spacing) var(--font-variant-numeric-fraction)}.lg\:normal-nums{font-variant-numeric:normal}.lg\:ordinal{--font-variant-numeric-ordinal:ordinal}.lg\:slashed-zero{--font-variant-numeric-slashed-zero:slashed-zero}.lg\:lining-nums{--font-variant-numeric-figure:lining-nums}.lg\:oldstyle-nums{--font-variant-numeric-figure:oldstyle-nums}.lg\:proportional-nums{--font-variant-numeric-spacing:proportional-nums}.lg\:tabular-nums{--font-variant-numeric-spacing:tabular-nums}.lg\:diagonal-fractions{--font-variant-numeric-fraction:diagonal-fractions}.lg\:stacked-fractions{--font-variant-numeric-fraction:stacked-fractions}.lg\:tracking-tighter{letter-spacing:-.05em}.lg\:tracking-tight{letter-spacing:-.025em}.lg\:tracking-normal{letter-spacing:0}.lg\:tracking-wide{letter-spacing:.025em}.lg\:tracking-wider{letter-spacing:.05em}.lg\:tracking-widest{letter-spacing:.1em}.lg\:select-none{-webkit-user-select:none;-ms-user-select:none;user-select:none}.lg\:select-text{-webkit-user-select:text;-ms-user-select:text;user-select:text}.lg\:select-all{-webkit-user-select:all;-ms-user-select:all;user-select:all}.lg\:select-auto{-webkit-user-select:auto;-ms-user-select:auto;user-select:auto}.lg\:align-baseline{vertical-align:baseline}.lg\:align-top{vertical-align:top}.lg\:align-middle{vertical-align:middle}.lg\:align-bottom{vertical-align:bottom}.lg\:align-text-top{vertical-align:text-top}.lg\:align-text-bottom{vertical-align:text-bottom}.lg\:visible{visibility:visible}.lg\:invisible{visibility:hidden}.lg\:whitespace-normal{white-space:normal}.lg\:whitespace-no-wrap{white-space:nowrap}.lg\:whitespace-pre{white-space:pre}.lg\:whitespace-pre-line{white-space:pre-line}.lg\:whitespace-pre-wrap{white-space:pre-wrap}.lg\:break-normal{word-wrap:normal;overflow-wrap:normal;word-break:normal}.lg\:break-words{word-wrap:break-word;overflow-wrap:break-word}.lg\:break-all{word-break:break-all}.lg\:truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.lg\:w-0{width:0}.lg\:w-1{width:.25rem}.lg\:w-2{width:.5rem}.lg\:w-3{width:.75rem}.lg\:w-4{width:1rem}.lg\:w-5{width:1.25rem}.lg\:w-6{width:1.5rem}.lg\:w-8{width:2rem}.lg\:w-10{width:2.5rem}.lg\:w-12{width:3rem}.lg\:w-16{width:4rem}.lg\:w-20{width:5rem}.lg\:w-24{width:6rem}.lg\:w-32{width:8rem}.lg\:w-40{width:10rem}.lg\:w-48{width:12rem}.lg\:w-56{width:14rem}.lg\:w-64{width:16rem}.lg\:w-auto{width:auto}.lg\:w-px{width:1px}.lg\:w-1\/2{width:50%}.lg\:w-1\/3{width:33.333333%}.lg\:w-2\/3{width:66.666667%}.lg\:w-1\/4{width:25%}.lg\:w-2\/4{width:50%}.lg\:w-3\/4{width:75%}.lg\:w-1\/5{width:20%}.lg\:w-2\/5{width:40%}.lg\:w-3\/5{width:60%}.lg\:w-4\/5{width:80%}.lg\:w-1\/6{width:16.666667%}.lg\:w-2\/6{width:33.333333%}.lg\:w-3\/6{width:50%}.lg\:w-4\/6{width:66.666667%}.lg\:w-5\/6{width:83.333333%}.lg\:w-1\/12{width:8.333333%}.lg\:w-2\/12{width:16.666667%}.lg\:w-3\/12{width:25%}.lg\:w-4\/12{width:33.333333%}.lg\:w-5\/12{width:41.666667%}.lg\:w-6\/12{width:50%}.lg\:w-7\/12{width:58.333333%}.lg\:w-8\/12{width:66.666667%}.lg\:w-9\/12{width:75%}.lg\:w-10\/12{width:83.333333%}.lg\:w-11\/12{width:91.666667%}.lg\:w-full{width:100%}.lg\:w-screen{width:100vw}.lg\:z-0{z-index:0}.lg\:z-10{z-index:10}.lg\:z-20{z-index:20}.lg\:z-30{z-index:30}.lg\:z-40{z-index:40}.lg\:z-50{z-index:50}.lg\:z-auto{z-index:auto}.lg\:gap-0{grid-gap:0;gap:0}.lg\:gap-1{grid-gap:.25rem;gap:.25rem}.lg\:gap-2{grid-gap:.5rem;gap:.5rem}.lg\:gap-3{grid-gap:.75rem;gap:.75rem}.lg\:gap-4{grid-gap:1rem;gap:1rem}.lg\:gap-5{grid-gap:1.25rem;gap:1.25rem}.lg\:gap-6{grid-gap:1.5rem;gap:1.5rem}.lg\:gap-8{grid-gap:2rem;gap:2rem}.lg\:gap-10{grid-gap:2.5rem;gap:2.5rem}.lg\:gap-12{grid-gap:3rem;gap:3rem}.lg\:gap-16{grid-gap:4rem;gap:4rem}.lg\:gap-20{grid-gap:5rem;gap:5rem}.lg\:gap-24{grid-gap:6rem;gap:6rem}.lg\:gap-32{grid-gap:8rem;gap:8rem}.lg\:gap-40{grid-gap:10rem;gap:10rem}.lg\:gap-48{grid-gap:12rem;gap:12rem}.lg\:gap-56{grid-gap:14rem;gap:14rem}.lg\:gap-64{grid-gap:16rem;gap:16rem}.lg\:gap-px{grid-gap:1px;gap:1px}.lg\:col-gap-0{grid-column-gap:0;column-gap:0}.lg\:col-gap-1{grid-column-gap:.25rem;column-gap:.25rem}.lg\:col-gap-2{grid-column-gap:.5rem;column-gap:.5rem}.lg\:col-gap-3{grid-column-gap:.75rem;column-gap:.75rem}.lg\:col-gap-4{grid-column-gap:1rem;column-gap:1rem}.lg\:col-gap-5{grid-column-gap:1.25rem;column-gap:1.25rem}.lg\:col-gap-6{grid-column-gap:1.5rem;column-gap:1.5rem}.lg\:col-gap-8{grid-column-gap:2rem;column-gap:2rem}.lg\:col-gap-10{grid-column-gap:2.5rem;column-gap:2.5rem}.lg\:col-gap-12{grid-column-gap:3rem;column-gap:3rem}.lg\:col-gap-16{grid-column-gap:4rem;column-gap:4rem}.lg\:col-gap-20{grid-column-gap:5rem;column-gap:5rem}.lg\:col-gap-24{grid-column-gap:6rem;column-gap:6rem}.lg\:col-gap-32{grid-column-gap:8rem;column-gap:8rem}.lg\:col-gap-40{grid-column-gap:10rem;column-gap:10rem}.lg\:col-gap-48{grid-column-gap:12rem;column-gap:12rem}.lg\:col-gap-56{grid-column-gap:14rem;column-gap:14rem}.lg\:col-gap-64{grid-column-gap:16rem;column-gap:16rem}.lg\:col-gap-px{grid-column-gap:1px;column-gap:1px}.lg\:gap-x-0{grid-column-gap:0;column-gap:0}.lg\:gap-x-1{grid-column-gap:.25rem;column-gap:.25rem}.lg\:gap-x-2{grid-column-gap:.5rem;column-gap:.5rem}.lg\:gap-x-3{grid-column-gap:.75rem;column-gap:.75rem}.lg\:gap-x-4{grid-column-gap:1rem;column-gap:1rem}.lg\:gap-x-5{grid-column-gap:1.25rem;column-gap:1.25rem}.lg\:gap-x-6{grid-column-gap:1.5rem;column-gap:1.5rem}.lg\:gap-x-8{grid-column-gap:2rem;column-gap:2rem}.lg\:gap-x-10{grid-column-gap:2.5rem;column-gap:2.5rem}.lg\:gap-x-12{grid-column-gap:3rem;column-gap:3rem}.lg\:gap-x-16{grid-column-gap:4rem;column-gap:4rem}.lg\:gap-x-20{grid-column-gap:5rem;column-gap:5rem}.lg\:gap-x-24{grid-column-gap:6rem;column-gap:6rem}.lg\:gap-x-32{grid-column-gap:8rem;column-gap:8rem}.lg\:gap-x-40{grid-column-gap:10rem;column-gap:10rem}.lg\:gap-x-48{grid-column-gap:12rem;column-gap:12rem}.lg\:gap-x-56{grid-column-gap:14rem;column-gap:14rem}.lg\:gap-x-64{grid-column-gap:16rem;column-gap:16rem}.lg\:gap-x-px{grid-column-gap:1px;column-gap:1px}.lg\:row-gap-0{grid-row-gap:0;row-gap:0}.lg\:row-gap-1{grid-row-gap:.25rem;row-gap:.25rem}.lg\:row-gap-2{grid-row-gap:.5rem;row-gap:.5rem}.lg\:row-gap-3{grid-row-gap:.75rem;row-gap:.75rem}.lg\:row-gap-4{grid-row-gap:1rem;row-gap:1rem}.lg\:row-gap-5{grid-row-gap:1.25rem;row-gap:1.25rem}.lg\:row-gap-6{grid-row-gap:1.5rem;row-gap:1.5rem}.lg\:row-gap-8{grid-row-gap:2rem;row-gap:2rem}.lg\:row-gap-10{grid-row-gap:2.5rem;row-gap:2.5rem}.lg\:row-gap-12{grid-row-gap:3rem;row-gap:3rem}.lg\:row-gap-16{grid-row-gap:4rem;row-gap:4rem}.lg\:row-gap-20{grid-row-gap:5rem;row-gap:5rem}.lg\:row-gap-24{grid-row-gap:6rem;row-gap:6rem}.lg\:row-gap-32{grid-row-gap:8rem;row-gap:8rem}.lg\:row-gap-40{grid-row-gap:10rem;row-gap:10rem}.lg\:row-gap-48{grid-row-gap:12rem;row-gap:12rem}.lg\:row-gap-56{grid-row-gap:14rem;row-gap:14rem}.lg\:row-gap-64{grid-row-gap:16rem;row-gap:16rem}.lg\:row-gap-px{grid-row-gap:1px;row-gap:1px}.lg\:gap-y-0{grid-row-gap:0;row-gap:0}.lg\:gap-y-1{grid-row-gap:.25rem;row-gap:.25rem}.lg\:gap-y-2{grid-row-gap:.5rem;row-gap:.5rem}.lg\:gap-y-3{grid-row-gap:.75rem;row-gap:.75rem}.lg\:gap-y-4{grid-row-gap:1rem;row-gap:1rem}.lg\:gap-y-5{grid-row-gap:1.25rem;row-gap:1.25rem}.lg\:gap-y-6{grid-row-gap:1.5rem;row-gap:1.5rem}.lg\:gap-y-8{grid-row-gap:2rem;row-gap:2rem}.lg\:gap-y-10{grid-row-gap:2.5rem;row-gap:2.5rem}.lg\:gap-y-12{grid-row-gap:3rem;row-gap:3rem}.lg\:gap-y-16{grid-row-gap:4rem;row-gap:4rem}.lg\:gap-y-20{grid-row-gap:5rem;row-gap:5rem}.lg\:gap-y-24{grid-row-gap:6rem;row-gap:6rem}.lg\:gap-y-32{grid-row-gap:8rem;row-gap:8rem}.lg\:gap-y-40{grid-row-gap:10rem;row-gap:10rem}.lg\:gap-y-48{grid-row-gap:12rem;row-gap:12rem}.lg\:gap-y-56{grid-row-gap:14rem;row-gap:14rem}.lg\:gap-y-64{grid-row-gap:16rem;row-gap:16rem}.lg\:gap-y-px{grid-row-gap:1px;row-gap:1px}.lg\:grid-flow-row{grid-auto-flow:row}.lg\:grid-flow-col{grid-auto-flow:column}.lg\:grid-flow-row-dense{grid-auto-flow:row dense}.lg\:grid-flow-col-dense{grid-auto-flow:column dense}.lg\:grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.lg\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.lg\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.lg\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.lg\:grid-cols-5{grid-template-columns:repeat(5,minmax(0,1fr))}.lg\:grid-cols-6{grid-template-columns:repeat(6,minmax(0,1fr))}.lg\:grid-cols-7{grid-template-columns:repeat(7,minmax(0,1fr))}.lg\:grid-cols-8{grid-template-columns:repeat(8,minmax(0,1fr))}.lg\:grid-cols-9{grid-template-columns:repeat(9,minmax(0,1fr))}.lg\:grid-cols-10{grid-template-columns:repeat(10,minmax(0,1fr))}.lg\:grid-cols-11{grid-template-columns:repeat(11,minmax(0,1fr))}.lg\:grid-cols-12{grid-template-columns:repeat(12,minmax(0,1fr))}.lg\:grid-cols-none{grid-template-columns:none}.lg\:auto-cols-auto{grid-auto-columns:auto}.lg\:auto-cols-min{grid-auto-columns:-webkit-min-content;grid-auto-columns:min-content}.lg\:auto-cols-max{grid-auto-columns:-webkit-max-content;grid-auto-columns:max-content}.lg\:auto-cols-fr{grid-auto-columns:minmax(0,1fr)}.lg\:col-auto{grid-column:auto}.lg\:col-span-1{grid-column:span 1/span 1}.lg\:col-span-2{grid-column:span 2/span 2}.lg\:col-span-3{grid-column:span 3/span 3}.lg\:col-span-4{grid-column:span 4/span 4}.lg\:col-span-5{grid-column:span 5/span 5}.lg\:col-span-6{grid-column:span 6/span 6}.lg\:col-span-7{grid-column:span 7/span 7}.lg\:col-span-8{grid-column:span 8/span 8}.lg\:col-span-9{grid-column:span 9/span 9}.lg\:col-span-10{grid-column:span 10/span 10}.lg\:col-span-11{grid-column:span 11/span 11}.lg\:col-span-12{grid-column:span 12/span 12}.lg\:col-span-full{grid-column:1/-1}.lg\:col-start-1{grid-column-start:1}.lg\:col-start-2{grid-column-start:2}.lg\:col-start-3{grid-column-start:3}.lg\:col-start-4{grid-column-start:4}.lg\:col-start-5{grid-column-start:5}.lg\:col-start-6{grid-column-start:6}.lg\:col-start-7{grid-column-start:7}.lg\:col-start-8{grid-column-start:8}.lg\:col-start-9{grid-column-start:9}.lg\:col-start-10{grid-column-start:10}.lg\:col-start-11{grid-column-start:11}.lg\:col-start-12{grid-column-start:12}.lg\:col-start-13{grid-column-start:13}.lg\:col-start-auto{grid-column-start:auto}.lg\:col-end-1{grid-column-end:1}.lg\:col-end-2{grid-column-end:2}.lg\:col-end-3{grid-column-end:3}.lg\:col-end-4{grid-column-end:4}.lg\:col-end-5{grid-column-end:5}.lg\:col-end-6{grid-column-end:6}.lg\:col-end-7{grid-column-end:7}.lg\:col-end-8{grid-column-end:8}.lg\:col-end-9{grid-column-end:9}.lg\:col-end-10{grid-column-end:10}.lg\:col-end-11{grid-column-end:11}.lg\:col-end-12{grid-column-end:12}.lg\:col-end-13{grid-column-end:13}.lg\:col-end-auto{grid-column-end:auto}.lg\:grid-rows-1{grid-template-rows:repeat(1,minmax(0,1fr))}.lg\:grid-rows-2{grid-template-rows:repeat(2,minmax(0,1fr))}.lg\:grid-rows-3{grid-template-rows:repeat(3,minmax(0,1fr))}.lg\:grid-rows-4{grid-template-rows:repeat(4,minmax(0,1fr))}.lg\:grid-rows-5{grid-template-rows:repeat(5,minmax(0,1fr))}.lg\:grid-rows-6{grid-template-rows:repeat(6,minmax(0,1fr))}.lg\:grid-rows-none{grid-template-rows:none}.lg\:auto-rows-auto{grid-auto-rows:auto}.lg\:auto-rows-min{grid-auto-rows:-webkit-min-content;grid-auto-rows:min-content}.lg\:auto-rows-max{grid-auto-rows:-webkit-max-content;grid-auto-rows:max-content}.lg\:auto-rows-fr{grid-auto-rows:minmax(0,1fr)}.lg\:row-auto{grid-row:auto}.lg\:row-span-1{grid-row:span 1/span 1}.lg\:row-span-2{grid-row:span 2/span 2}.lg\:row-span-3{grid-row:span 3/span 3}.lg\:row-span-4{grid-row:span 4/span 4}.lg\:row-span-5{grid-row:span 5/span 5}.lg\:row-span-6{grid-row:span 6/span 6}.lg\:row-span-full{grid-row:1/-1}.lg\:row-start-1{grid-row-start:1}.lg\:row-start-2{grid-row-start:2}.lg\:row-start-3{grid-row-start:3}.lg\:row-start-4{grid-row-start:4}.lg\:row-start-5{grid-row-start:5}.lg\:row-start-6{grid-row-start:6}.lg\:row-start-7{grid-row-start:7}.lg\:row-start-auto{grid-row-start:auto}.lg\:row-end-1{grid-row-end:1}.lg\:row-end-2{grid-row-end:2}.lg\:row-end-3{grid-row-end:3}.lg\:row-end-4{grid-row-end:4}.lg\:row-end-5{grid-row-end:5}.lg\:row-end-6{grid-row-end:6}.lg\:row-end-7{grid-row-end:7}.lg\:row-end-auto{grid-row-end:auto}.lg\:transform{--transform-translate-x:0;--transform-translate-y:0;--transform-rotate:0;--transform-skew-x:0;--transform-skew-y:0;--transform-scale-x:1;--transform-scale-y:1;transform:translateX(var(--transform-translate-x)) translateY(var(--transform-translate-y)) rotate(var(--transform-rotate)) skewX(var(--transform-skew-x)) skewY(var(--transform-skew-y)) scaleX(var(--transform-scale-x)) scaleY(var(--transform-scale-y))}.lg\:transform-none{transform:none}.lg\:origin-center{transform-origin:center}.lg\:origin-top{transform-origin:top}.lg\:origin-top-right{transform-origin:top right}.lg\:origin-right{transform-origin:right}.lg\:origin-bottom-right{transform-origin:bottom right}.lg\:origin-bottom{transform-origin:bottom}.lg\:origin-bottom-left{transform-origin:bottom left}.lg\:origin-left{transform-origin:left}.lg\:origin-top-left{transform-origin:top left}.lg\:scale-0{--transform-scale-x:0;--transform-scale-y:0}.lg\:scale-50{--transform-scale-x:.5;--transform-scale-y:.5}.lg\:scale-75{--transform-scale-x:.75;--transform-scale-y:.75}.lg\:scale-90{--transform-scale-x:.9;--transform-scale-y:.9}.lg\:scale-95{--transform-scale-x:.95;--transform-scale-y:.95}.lg\:scale-100{--transform-scale-x:1;--transform-scale-y:1}.lg\:scale-105{--transform-scale-x:1.05;--transform-scale-y:1.05}.lg\:scale-110{--transform-scale-x:1.1;--transform-scale-y:1.1}.lg\:scale-125{--transform-scale-x:1.25;--transform-scale-y:1.25}.lg\:scale-150{--transform-scale-x:1.5;--transform-scale-y:1.5}.lg\:scale-x-0{--transform-scale-x:0}.lg\:scale-x-50{--transform-scale-x:.5}.lg\:scale-x-75{--transform-scale-x:.75}.lg\:scale-x-90{--transform-scale-x:.9}.lg\:scale-x-95{--transform-scale-x:.95}.lg\:scale-x-100{--transform-scale-x:1}.lg\:scale-x-105{--transform-scale-x:1.05}.lg\:scale-x-110{--transform-scale-x:1.1}.lg\:scale-x-125{--transform-scale-x:1.25}.lg\:scale-x-150{--transform-scale-x:1.5}.lg\:scale-y-0{--transform-scale-y:0}.lg\:scale-y-50{--transform-scale-y:.5}.lg\:scale-y-75{--transform-scale-y:.75}.lg\:scale-y-90{--transform-scale-y:.9}.lg\:scale-y-95{--transform-scale-y:.95}.lg\:scale-y-100{--transform-scale-y:1}.lg\:scale-y-105{--transform-scale-y:1.05}.lg\:scale-y-110{--transform-scale-y:1.1}.lg\:scale-y-125{--transform-scale-y:1.25}.lg\:scale-y-150{--transform-scale-y:1.5}.lg\:hover\:scale-0:hover{--transform-scale-x:0;--transform-scale-y:0}.lg\:hover\:scale-50:hover{--transform-scale-x:.5;--transform-scale-y:.5}.lg\:hover\:scale-75:hover{--transform-scale-x:.75;--transform-scale-y:.75}.lg\:hover\:scale-90:hover{--transform-scale-x:.9;--transform-scale-y:.9}.lg\:hover\:scale-95:hover{--transform-scale-x:.95;--transform-scale-y:.95}.lg\:hover\:scale-100:hover{--transform-scale-x:1;--transform-scale-y:1}.lg\:hover\:scale-105:hover{--transform-scale-x:1.05;--transform-scale-y:1.05}.lg\:hover\:scale-110:hover{--transform-scale-x:1.1;--transform-scale-y:1.1}.lg\:hover\:scale-125:hover{--transform-scale-x:1.25;--transform-scale-y:1.25}.lg\:hover\:scale-150:hover{--transform-scale-x:1.5;--transform-scale-y:1.5}.lg\:hover\:scale-x-0:hover{--transform-scale-x:0}.lg\:hover\:scale-x-50:hover{--transform-scale-x:.5}.lg\:hover\:scale-x-75:hover{--transform-scale-x:.75}.lg\:hover\:scale-x-90:hover{--transform-scale-x:.9}.lg\:hover\:scale-x-95:hover{--transform-scale-x:.95}.lg\:hover\:scale-x-100:hover{--transform-scale-x:1}.lg\:hover\:scale-x-105:hover{--transform-scale-x:1.05}.lg\:hover\:scale-x-110:hover{--transform-scale-x:1.1}.lg\:hover\:scale-x-125:hover{--transform-scale-x:1.25}.lg\:hover\:scale-x-150:hover{--transform-scale-x:1.5}.lg\:hover\:scale-y-0:hover{--transform-scale-y:0}.lg\:hover\:scale-y-50:hover{--transform-scale-y:.5}.lg\:hover\:scale-y-75:hover{--transform-scale-y:.75}.lg\:hover\:scale-y-90:hover{--transform-scale-y:.9}.lg\:hover\:scale-y-95:hover{--transform-scale-y:.95}.lg\:hover\:scale-y-100:hover{--transform-scale-y:1}.lg\:hover\:scale-y-105:hover{--transform-scale-y:1.05}.lg\:hover\:scale-y-110:hover{--transform-scale-y:1.1}.lg\:hover\:scale-y-125:hover{--transform-scale-y:1.25}.lg\:hover\:scale-y-150:hover{--transform-scale-y:1.5}.lg\:focus\:scale-0:focus{--transform-scale-x:0;--transform-scale-y:0}.lg\:focus\:scale-50:focus{--transform-scale-x:.5;--transform-scale-y:.5}.lg\:focus\:scale-75:focus{--transform-scale-x:.75;--transform-scale-y:.75}.lg\:focus\:scale-90:focus{--transform-scale-x:.9;--transform-scale-y:.9}.lg\:focus\:scale-95:focus{--transform-scale-x:.95;--transform-scale-y:.95}.lg\:focus\:scale-100:focus{--transform-scale-x:1;--transform-scale-y:1}.lg\:focus\:scale-105:focus{--transform-scale-x:1.05;--transform-scale-y:1.05}.lg\:focus\:scale-110:focus{--transform-scale-x:1.1;--transform-scale-y:1.1}.lg\:focus\:scale-125:focus{--transform-scale-x:1.25;--transform-scale-y:1.25}.lg\:focus\:scale-150:focus{--transform-scale-x:1.5;--transform-scale-y:1.5}.lg\:focus\:scale-x-0:focus{--transform-scale-x:0}.lg\:focus\:scale-x-50:focus{--transform-scale-x:.5}.lg\:focus\:scale-x-75:focus{--transform-scale-x:.75}.lg\:focus\:scale-x-90:focus{--transform-scale-x:.9}.lg\:focus\:scale-x-95:focus{--transform-scale-x:.95}.lg\:focus\:scale-x-100:focus{--transform-scale-x:1}.lg\:focus\:scale-x-105:focus{--transform-scale-x:1.05}.lg\:focus\:scale-x-110:focus{--transform-scale-x:1.1}.lg\:focus\:scale-x-125:focus{--transform-scale-x:1.25}.lg\:focus\:scale-x-150:focus{--transform-scale-x:1.5}.lg\:focus\:scale-y-0:focus{--transform-scale-y:0}.lg\:focus\:scale-y-50:focus{--transform-scale-y:.5}.lg\:focus\:scale-y-75:focus{--transform-scale-y:.75}.lg\:focus\:scale-y-90:focus{--transform-scale-y:.9}.lg\:focus\:scale-y-95:focus{--transform-scale-y:.95}.lg\:focus\:scale-y-100:focus{--transform-scale-y:1}.lg\:focus\:scale-y-105:focus{--transform-scale-y:1.05}.lg\:focus\:scale-y-110:focus{--transform-scale-y:1.1}.lg\:focus\:scale-y-125:focus{--transform-scale-y:1.25}.lg\:focus\:scale-y-150:focus{--transform-scale-y:1.5}.lg\:rotate-0{--transform-rotate:0}.lg\:rotate-1{--transform-rotate:1deg}.lg\:rotate-2{--transform-rotate:2deg}.lg\:rotate-3{--transform-rotate:3deg}.lg\:rotate-6{--transform-rotate:6deg}.lg\:rotate-12{--transform-rotate:12deg}.lg\:rotate-45{--transform-rotate:45deg}.lg\:rotate-90{--transform-rotate:90deg}.lg\:rotate-180{--transform-rotate:180deg}.lg\:-rotate-180{--transform-rotate:-180deg}.lg\:-rotate-90{--transform-rotate:-90deg}.lg\:-rotate-45{--transform-rotate:-45deg}.lg\:-rotate-12{--transform-rotate:-12deg}.lg\:-rotate-6{--transform-rotate:-6deg}.lg\:-rotate-3{--transform-rotate:-3deg}.lg\:-rotate-2{--transform-rotate:-2deg}.lg\:-rotate-1{--transform-rotate:-1deg}.lg\:hover\:rotate-0:hover{--transform-rotate:0}.lg\:hover\:rotate-1:hover{--transform-rotate:1deg}.lg\:hover\:rotate-2:hover{--transform-rotate:2deg}.lg\:hover\:rotate-3:hover{--transform-rotate:3deg}.lg\:hover\:rotate-6:hover{--transform-rotate:6deg}.lg\:hover\:rotate-12:hover{--transform-rotate:12deg}.lg\:hover\:rotate-45:hover{--transform-rotate:45deg}.lg\:hover\:rotate-90:hover{--transform-rotate:90deg}.lg\:hover\:rotate-180:hover{--transform-rotate:180deg}.lg\:hover\:-rotate-180:hover{--transform-rotate:-180deg}.lg\:hover\:-rotate-90:hover{--transform-rotate:-90deg}.lg\:hover\:-rotate-45:hover{--transform-rotate:-45deg}.lg\:hover\:-rotate-12:hover{--transform-rotate:-12deg}.lg\:hover\:-rotate-6:hover{--transform-rotate:-6deg}.lg\:hover\:-rotate-3:hover{--transform-rotate:-3deg}.lg\:hover\:-rotate-2:hover{--transform-rotate:-2deg}.lg\:hover\:-rotate-1:hover{--transform-rotate:-1deg}.lg\:focus\:rotate-0:focus{--transform-rotate:0}.lg\:focus\:rotate-1:focus{--transform-rotate:1deg}.lg\:focus\:rotate-2:focus{--transform-rotate:2deg}.lg\:focus\:rotate-3:focus{--transform-rotate:3deg}.lg\:focus\:rotate-6:focus{--transform-rotate:6deg}.lg\:focus\:rotate-12:focus{--transform-rotate:12deg}.lg\:focus\:rotate-45:focus{--transform-rotate:45deg}.lg\:focus\:rotate-90:focus{--transform-rotate:90deg}.lg\:focus\:rotate-180:focus{--transform-rotate:180deg}.lg\:focus\:-rotate-180:focus{--transform-rotate:-180deg}.lg\:focus\:-rotate-90:focus{--transform-rotate:-90deg}.lg\:focus\:-rotate-45:focus{--transform-rotate:-45deg}.lg\:focus\:-rotate-12:focus{--transform-rotate:-12deg}.lg\:focus\:-rotate-6:focus{--transform-rotate:-6deg}.lg\:focus\:-rotate-3:focus{--transform-rotate:-3deg}.lg\:focus\:-rotate-2:focus{--transform-rotate:-2deg}.lg\:focus\:-rotate-1:focus{--transform-rotate:-1deg}.lg\:translate-x-0{--transform-translate-x:0}.lg\:translate-x-1{--transform-translate-x:0.25rem}.lg\:translate-x-2{--transform-translate-x:0.5rem}.lg\:translate-x-3{--transform-translate-x:0.75rem}.lg\:translate-x-4{--transform-translate-x:1rem}.lg\:translate-x-5{--transform-translate-x:1.25rem}.lg\:translate-x-6{--transform-translate-x:1.5rem}.lg\:translate-x-8{--transform-translate-x:2rem}.lg\:translate-x-10{--transform-translate-x:2.5rem}.lg\:translate-x-12{--transform-translate-x:3rem}.lg\:translate-x-16{--transform-translate-x:4rem}.lg\:translate-x-20{--transform-translate-x:5rem}.lg\:translate-x-24{--transform-translate-x:6rem}.lg\:translate-x-32{--transform-translate-x:8rem}.lg\:translate-x-40{--transform-translate-x:10rem}.lg\:translate-x-48{--transform-translate-x:12rem}.lg\:translate-x-56{--transform-translate-x:14rem}.lg\:translate-x-64{--transform-translate-x:16rem}.lg\:translate-x-px{--transform-translate-x:1px}.lg\:-translate-x-1{--transform-translate-x:-0.25rem}.lg\:-translate-x-2{--transform-translate-x:-0.5rem}.lg\:-translate-x-3{--transform-translate-x:-0.75rem}.lg\:-translate-x-4{--transform-translate-x:-1rem}.lg\:-translate-x-5{--transform-translate-x:-1.25rem}.lg\:-translate-x-6{--transform-translate-x:-1.5rem}.lg\:-translate-x-8{--transform-translate-x:-2rem}.lg\:-translate-x-10{--transform-translate-x:-2.5rem}.lg\:-translate-x-12{--transform-translate-x:-3rem}.lg\:-translate-x-16{--transform-translate-x:-4rem}.lg\:-translate-x-20{--transform-translate-x:-5rem}.lg\:-translate-x-24{--transform-translate-x:-6rem}.lg\:-translate-x-32{--transform-translate-x:-8rem}.lg\:-translate-x-40{--transform-translate-x:-10rem}.lg\:-translate-x-48{--transform-translate-x:-12rem}.lg\:-translate-x-56{--transform-translate-x:-14rem}.lg\:-translate-x-64{--transform-translate-x:-16rem}.lg\:-translate-x-px{--transform-translate-x:-1px}.lg\:-translate-x-full{--transform-translate-x:-100%}.lg\:-translate-x-1\/2{--transform-translate-x:-50%}.lg\:translate-x-1\/2{--transform-translate-x:50%}.lg\:translate-x-full{--transform-translate-x:100%}.lg\:translate-y-0{--transform-translate-y:0}.lg\:translate-y-1{--transform-translate-y:0.25rem}.lg\:translate-y-2{--transform-translate-y:0.5rem}.lg\:translate-y-3{--transform-translate-y:0.75rem}.lg\:translate-y-4{--transform-translate-y:1rem}.lg\:translate-y-5{--transform-translate-y:1.25rem}.lg\:translate-y-6{--transform-translate-y:1.5rem}.lg\:translate-y-8{--transform-translate-y:2rem}.lg\:translate-y-10{--transform-translate-y:2.5rem}.lg\:translate-y-12{--transform-translate-y:3rem}.lg\:translate-y-16{--transform-translate-y:4rem}.lg\:translate-y-20{--transform-translate-y:5rem}.lg\:translate-y-24{--transform-translate-y:6rem}.lg\:translate-y-32{--transform-translate-y:8rem}.lg\:translate-y-40{--transform-translate-y:10rem}.lg\:translate-y-48{--transform-translate-y:12rem}.lg\:translate-y-56{--transform-translate-y:14rem}.lg\:translate-y-64{--transform-translate-y:16rem}.lg\:translate-y-px{--transform-translate-y:1px}.lg\:-translate-y-1{--transform-translate-y:-0.25rem}.lg\:-translate-y-2{--transform-translate-y:-0.5rem}.lg\:-translate-y-3{--transform-translate-y:-0.75rem}.lg\:-translate-y-4{--transform-translate-y:-1rem}.lg\:-translate-y-5{--transform-translate-y:-1.25rem}.lg\:-translate-y-6{--transform-translate-y:-1.5rem}.lg\:-translate-y-8{--transform-translate-y:-2rem}.lg\:-translate-y-10{--transform-translate-y:-2.5rem}.lg\:-translate-y-12{--transform-translate-y:-3rem}.lg\:-translate-y-16{--transform-translate-y:-4rem}.lg\:-translate-y-20{--transform-translate-y:-5rem}.lg\:-translate-y-24{--transform-translate-y:-6rem}.lg\:-translate-y-32{--transform-translate-y:-8rem}.lg\:-translate-y-40{--transform-translate-y:-10rem}.lg\:-translate-y-48{--transform-translate-y:-12rem}.lg\:-translate-y-56{--transform-translate-y:-14rem}.lg\:-translate-y-64{--transform-translate-y:-16rem}.lg\:-translate-y-px{--transform-translate-y:-1px}.lg\:-translate-y-full{--transform-translate-y:-100%}.lg\:-translate-y-1\/2{--transform-translate-y:-50%}.lg\:translate-y-1\/2{--transform-translate-y:50%}.lg\:translate-y-full{--transform-translate-y:100%}.lg\:hover\:translate-x-0:hover{--transform-translate-x:0}.lg\:hover\:translate-x-1:hover{--transform-translate-x:0.25rem}.lg\:hover\:translate-x-2:hover{--transform-translate-x:0.5rem}.lg\:hover\:translate-x-3:hover{--transform-translate-x:0.75rem}.lg\:hover\:translate-x-4:hover{--transform-translate-x:1rem}.lg\:hover\:translate-x-5:hover{--transform-translate-x:1.25rem}.lg\:hover\:translate-x-6:hover{--transform-translate-x:1.5rem}.lg\:hover\:translate-x-8:hover{--transform-translate-x:2rem}.lg\:hover\:translate-x-10:hover{--transform-translate-x:2.5rem}.lg\:hover\:translate-x-12:hover{--transform-translate-x:3rem}.lg\:hover\:translate-x-16:hover{--transform-translate-x:4rem}.lg\:hover\:translate-x-20:hover{--transform-translate-x:5rem}.lg\:hover\:translate-x-24:hover{--transform-translate-x:6rem}.lg\:hover\:translate-x-32:hover{--transform-translate-x:8rem}.lg\:hover\:translate-x-40:hover{--transform-translate-x:10rem}.lg\:hover\:translate-x-48:hover{--transform-translate-x:12rem}.lg\:hover\:translate-x-56:hover{--transform-translate-x:14rem}.lg\:hover\:translate-x-64:hover{--transform-translate-x:16rem}.lg\:hover\:translate-x-px:hover{--transform-translate-x:1px}.lg\:hover\:-translate-x-1:hover{--transform-translate-x:-0.25rem}.lg\:hover\:-translate-x-2:hover{--transform-translate-x:-0.5rem}.lg\:hover\:-translate-x-3:hover{--transform-translate-x:-0.75rem}.lg\:hover\:-translate-x-4:hover{--transform-translate-x:-1rem}.lg\:hover\:-translate-x-5:hover{--transform-translate-x:-1.25rem}.lg\:hover\:-translate-x-6:hover{--transform-translate-x:-1.5rem}.lg\:hover\:-translate-x-8:hover{--transform-translate-x:-2rem}.lg\:hover\:-translate-x-10:hover{--transform-translate-x:-2.5rem}.lg\:hover\:-translate-x-12:hover{--transform-translate-x:-3rem}.lg\:hover\:-translate-x-16:hover{--transform-translate-x:-4rem}.lg\:hover\:-translate-x-20:hover{--transform-translate-x:-5rem}.lg\:hover\:-translate-x-24:hover{--transform-translate-x:-6rem}.lg\:hover\:-translate-x-32:hover{--transform-translate-x:-8rem}.lg\:hover\:-translate-x-40:hover{--transform-translate-x:-10rem}.lg\:hover\:-translate-x-48:hover{--transform-translate-x:-12rem}.lg\:hover\:-translate-x-56:hover{--transform-translate-x:-14rem}.lg\:hover\:-translate-x-64:hover{--transform-translate-x:-16rem}.lg\:hover\:-translate-x-px:hover{--transform-translate-x:-1px}.lg\:hover\:-translate-x-full:hover{--transform-translate-x:-100%}.lg\:hover\:-translate-x-1\/2:hover{--transform-translate-x:-50%}.lg\:hover\:translate-x-1\/2:hover{--transform-translate-x:50%}.lg\:hover\:translate-x-full:hover{--transform-translate-x:100%}.lg\:hover\:translate-y-0:hover{--transform-translate-y:0}.lg\:hover\:translate-y-1:hover{--transform-translate-y:0.25rem}.lg\:hover\:translate-y-2:hover{--transform-translate-y:0.5rem}.lg\:hover\:translate-y-3:hover{--transform-translate-y:0.75rem}.lg\:hover\:translate-y-4:hover{--transform-translate-y:1rem}.lg\:hover\:translate-y-5:hover{--transform-translate-y:1.25rem}.lg\:hover\:translate-y-6:hover{--transform-translate-y:1.5rem}.lg\:hover\:translate-y-8:hover{--transform-translate-y:2rem}.lg\:hover\:translate-y-10:hover{--transform-translate-y:2.5rem}.lg\:hover\:translate-y-12:hover{--transform-translate-y:3rem}.lg\:hover\:translate-y-16:hover{--transform-translate-y:4rem}.lg\:hover\:translate-y-20:hover{--transform-translate-y:5rem}.lg\:hover\:translate-y-24:hover{--transform-translate-y:6rem}.lg\:hover\:translate-y-32:hover{--transform-translate-y:8rem}.lg\:hover\:translate-y-40:hover{--transform-translate-y:10rem}.lg\:hover\:translate-y-48:hover{--transform-translate-y:12rem}.lg\:hover\:translate-y-56:hover{--transform-translate-y:14rem}.lg\:hover\:translate-y-64:hover{--transform-translate-y:16rem}.lg\:hover\:translate-y-px:hover{--transform-translate-y:1px}.lg\:hover\:-translate-y-1:hover{--transform-translate-y:-0.25rem}.lg\:hover\:-translate-y-2:hover{--transform-translate-y:-0.5rem}.lg\:hover\:-translate-y-3:hover{--transform-translate-y:-0.75rem}.lg\:hover\:-translate-y-4:hover{--transform-translate-y:-1rem}.lg\:hover\:-translate-y-5:hover{--transform-translate-y:-1.25rem}.lg\:hover\:-translate-y-6:hover{--transform-translate-y:-1.5rem}.lg\:hover\:-translate-y-8:hover{--transform-translate-y:-2rem}.lg\:hover\:-translate-y-10:hover{--transform-translate-y:-2.5rem}.lg\:hover\:-translate-y-12:hover{--transform-translate-y:-3rem}.lg\:hover\:-translate-y-16:hover{--transform-translate-y:-4rem}.lg\:hover\:-translate-y-20:hover{--transform-translate-y:-5rem}.lg\:hover\:-translate-y-24:hover{--transform-translate-y:-6rem}.lg\:hover\:-translate-y-32:hover{--transform-translate-y:-8rem}.lg\:hover\:-translate-y-40:hover{--transform-translate-y:-10rem}.lg\:hover\:-translate-y-48:hover{--transform-translate-y:-12rem}.lg\:hover\:-translate-y-56:hover{--transform-translate-y:-14rem}.lg\:hover\:-translate-y-64:hover{--transform-translate-y:-16rem}.lg\:hover\:-translate-y-px:hover{--transform-translate-y:-1px}.lg\:hover\:-translate-y-full:hover{--transform-translate-y:-100%}.lg\:hover\:-translate-y-1\/2:hover{--transform-translate-y:-50%}.lg\:hover\:translate-y-1\/2:hover{--transform-translate-y:50%}.lg\:hover\:translate-y-full:hover{--transform-translate-y:100%}.lg\:focus\:translate-x-0:focus{--transform-translate-x:0}.lg\:focus\:translate-x-1:focus{--transform-translate-x:0.25rem}.lg\:focus\:translate-x-2:focus{--transform-translate-x:0.5rem}.lg\:focus\:translate-x-3:focus{--transform-translate-x:0.75rem}.lg\:focus\:translate-x-4:focus{--transform-translate-x:1rem}.lg\:focus\:translate-x-5:focus{--transform-translate-x:1.25rem}.lg\:focus\:translate-x-6:focus{--transform-translate-x:1.5rem}.lg\:focus\:translate-x-8:focus{--transform-translate-x:2rem}.lg\:focus\:translate-x-10:focus{--transform-translate-x:2.5rem}.lg\:focus\:translate-x-12:focus{--transform-translate-x:3rem}.lg\:focus\:translate-x-16:focus{--transform-translate-x:4rem}.lg\:focus\:translate-x-20:focus{--transform-translate-x:5rem}.lg\:focus\:translate-x-24:focus{--transform-translate-x:6rem}.lg\:focus\:translate-x-32:focus{--transform-translate-x:8rem}.lg\:focus\:translate-x-40:focus{--transform-translate-x:10rem}.lg\:focus\:translate-x-48:focus{--transform-translate-x:12rem}.lg\:focus\:translate-x-56:focus{--transform-translate-x:14rem}.lg\:focus\:translate-x-64:focus{--transform-translate-x:16rem}.lg\:focus\:translate-x-px:focus{--transform-translate-x:1px}.lg\:focus\:-translate-x-1:focus{--transform-translate-x:-0.25rem}.lg\:focus\:-translate-x-2:focus{--transform-translate-x:-0.5rem}.lg\:focus\:-translate-x-3:focus{--transform-translate-x:-0.75rem}.lg\:focus\:-translate-x-4:focus{--transform-translate-x:-1rem}.lg\:focus\:-translate-x-5:focus{--transform-translate-x:-1.25rem}.lg\:focus\:-translate-x-6:focus{--transform-translate-x:-1.5rem}.lg\:focus\:-translate-x-8:focus{--transform-translate-x:-2rem}.lg\:focus\:-translate-x-10:focus{--transform-translate-x:-2.5rem}.lg\:focus\:-translate-x-12:focus{--transform-translate-x:-3rem}.lg\:focus\:-translate-x-16:focus{--transform-translate-x:-4rem}.lg\:focus\:-translate-x-20:focus{--transform-translate-x:-5rem}.lg\:focus\:-translate-x-24:focus{--transform-translate-x:-6rem}.lg\:focus\:-translate-x-32:focus{--transform-translate-x:-8rem}.lg\:focus\:-translate-x-40:focus{--transform-translate-x:-10rem}.lg\:focus\:-translate-x-48:focus{--transform-translate-x:-12rem}.lg\:focus\:-translate-x-56:focus{--transform-translate-x:-14rem}.lg\:focus\:-translate-x-64:focus{--transform-translate-x:-16rem}.lg\:focus\:-translate-x-px:focus{--transform-translate-x:-1px}.lg\:focus\:-translate-x-full:focus{--transform-translate-x:-100%}.lg\:focus\:-translate-x-1\/2:focus{--transform-translate-x:-50%}.lg\:focus\:translate-x-1\/2:focus{--transform-translate-x:50%}.lg\:focus\:translate-x-full:focus{--transform-translate-x:100%}.lg\:focus\:translate-y-0:focus{--transform-translate-y:0}.lg\:focus\:translate-y-1:focus{--transform-translate-y:0.25rem}.lg\:focus\:translate-y-2:focus{--transform-translate-y:0.5rem}.lg\:focus\:translate-y-3:focus{--transform-translate-y:0.75rem}.lg\:focus\:translate-y-4:focus{--transform-translate-y:1rem}.lg\:focus\:translate-y-5:focus{--transform-translate-y:1.25rem}.lg\:focus\:translate-y-6:focus{--transform-translate-y:1.5rem}.lg\:focus\:translate-y-8:focus{--transform-translate-y:2rem}.lg\:focus\:translate-y-10:focus{--transform-translate-y:2.5rem}.lg\:focus\:translate-y-12:focus{--transform-translate-y:3rem}.lg\:focus\:translate-y-16:focus{--transform-translate-y:4rem}.lg\:focus\:translate-y-20:focus{--transform-translate-y:5rem}.lg\:focus\:translate-y-24:focus{--transform-translate-y:6rem}.lg\:focus\:translate-y-32:focus{--transform-translate-y:8rem}.lg\:focus\:translate-y-40:focus{--transform-translate-y:10rem}.lg\:focus\:translate-y-48:focus{--transform-translate-y:12rem}.lg\:focus\:translate-y-56:focus{--transform-translate-y:14rem}.lg\:focus\:translate-y-64:focus{--transform-translate-y:16rem}.lg\:focus\:translate-y-px:focus{--transform-translate-y:1px}.lg\:focus\:-translate-y-1:focus{--transform-translate-y:-0.25rem}.lg\:focus\:-translate-y-2:focus{--transform-translate-y:-0.5rem}.lg\:focus\:-translate-y-3:focus{--transform-translate-y:-0.75rem}.lg\:focus\:-translate-y-4:focus{--transform-translate-y:-1rem}.lg\:focus\:-translate-y-5:focus{--transform-translate-y:-1.25rem}.lg\:focus\:-translate-y-6:focus{--transform-translate-y:-1.5rem}.lg\:focus\:-translate-y-8:focus{--transform-translate-y:-2rem}.lg\:focus\:-translate-y-10:focus{--transform-translate-y:-2.5rem}.lg\:focus\:-translate-y-12:focus{--transform-translate-y:-3rem}.lg\:focus\:-translate-y-16:focus{--transform-translate-y:-4rem}.lg\:focus\:-translate-y-20:focus{--transform-translate-y:-5rem}.lg\:focus\:-translate-y-24:focus{--transform-translate-y:-6rem}.lg\:focus\:-translate-y-32:focus{--transform-translate-y:-8rem}.lg\:focus\:-translate-y-40:focus{--transform-translate-y:-10rem}.lg\:focus\:-translate-y-48:focus{--transform-translate-y:-12rem}.lg\:focus\:-translate-y-56:focus{--transform-translate-y:-14rem}.lg\:focus\:-translate-y-64:focus{--transform-translate-y:-16rem}.lg\:focus\:-translate-y-px:focus{--transform-translate-y:-1px}.lg\:focus\:-translate-y-full:focus{--transform-translate-y:-100%}.lg\:focus\:-translate-y-1\/2:focus{--transform-translate-y:-50%}.lg\:focus\:translate-y-1\/2:focus{--transform-translate-y:50%}.lg\:focus\:translate-y-full:focus{--transform-translate-y:100%}.lg\:skew-x-0{--transform-skew-x:0}.lg\:skew-x-1{--transform-skew-x:1deg}.lg\:skew-x-2{--transform-skew-x:2deg}.lg\:skew-x-3{--transform-skew-x:3deg}.lg\:skew-x-6{--transform-skew-x:6deg}.lg\:skew-x-12{--transform-skew-x:12deg}.lg\:-skew-x-12{--transform-skew-x:-12deg}.lg\:-skew-x-6{--transform-skew-x:-6deg}.lg\:-skew-x-3{--transform-skew-x:-3deg}.lg\:-skew-x-2{--transform-skew-x:-2deg}.lg\:-skew-x-1{--transform-skew-x:-1deg}.lg\:skew-y-0{--transform-skew-y:0}.lg\:skew-y-1{--transform-skew-y:1deg}.lg\:skew-y-2{--transform-skew-y:2deg}.lg\:skew-y-3{--transform-skew-y:3deg}.lg\:skew-y-6{--transform-skew-y:6deg}.lg\:skew-y-12{--transform-skew-y:12deg}.lg\:-skew-y-12{--transform-skew-y:-12deg}.lg\:-skew-y-6{--transform-skew-y:-6deg}.lg\:-skew-y-3{--transform-skew-y:-3deg}.lg\:-skew-y-2{--transform-skew-y:-2deg}.lg\:-skew-y-1{--transform-skew-y:-1deg}.lg\:hover\:skew-x-0:hover{--transform-skew-x:0}.lg\:hover\:skew-x-1:hover{--transform-skew-x:1deg}.lg\:hover\:skew-x-2:hover{--transform-skew-x:2deg}.lg\:hover\:skew-x-3:hover{--transform-skew-x:3deg}.lg\:hover\:skew-x-6:hover{--transform-skew-x:6deg}.lg\:hover\:skew-x-12:hover{--transform-skew-x:12deg}.lg\:hover\:-skew-x-12:hover{--transform-skew-x:-12deg}.lg\:hover\:-skew-x-6:hover{--transform-skew-x:-6deg}.lg\:hover\:-skew-x-3:hover{--transform-skew-x:-3deg}.lg\:hover\:-skew-x-2:hover{--transform-skew-x:-2deg}.lg\:hover\:-skew-x-1:hover{--transform-skew-x:-1deg}.lg\:hover\:skew-y-0:hover{--transform-skew-y:0}.lg\:hover\:skew-y-1:hover{--transform-skew-y:1deg}.lg\:hover\:skew-y-2:hover{--transform-skew-y:2deg}.lg\:hover\:skew-y-3:hover{--transform-skew-y:3deg}.lg\:hover\:skew-y-6:hover{--transform-skew-y:6deg}.lg\:hover\:skew-y-12:hover{--transform-skew-y:12deg}.lg\:hover\:-skew-y-12:hover{--transform-skew-y:-12deg}.lg\:hover\:-skew-y-6:hover{--transform-skew-y:-6deg}.lg\:hover\:-skew-y-3:hover{--transform-skew-y:-3deg}.lg\:hover\:-skew-y-2:hover{--transform-skew-y:-2deg}.lg\:hover\:-skew-y-1:hover{--transform-skew-y:-1deg}.lg\:focus\:skew-x-0:focus{--transform-skew-x:0}.lg\:focus\:skew-x-1:focus{--transform-skew-x:1deg}.lg\:focus\:skew-x-2:focus{--transform-skew-x:2deg}.lg\:focus\:skew-x-3:focus{--transform-skew-x:3deg}.lg\:focus\:skew-x-6:focus{--transform-skew-x:6deg}.lg\:focus\:skew-x-12:focus{--transform-skew-x:12deg}.lg\:focus\:-skew-x-12:focus{--transform-skew-x:-12deg}.lg\:focus\:-skew-x-6:focus{--transform-skew-x:-6deg}.lg\:focus\:-skew-x-3:focus{--transform-skew-x:-3deg}.lg\:focus\:-skew-x-2:focus{--transform-skew-x:-2deg}.lg\:focus\:-skew-x-1:focus{--transform-skew-x:-1deg}.lg\:focus\:skew-y-0:focus{--transform-skew-y:0}.lg\:focus\:skew-y-1:focus{--transform-skew-y:1deg}.lg\:focus\:skew-y-2:focus{--transform-skew-y:2deg}.lg\:focus\:skew-y-3:focus{--transform-skew-y:3deg}.lg\:focus\:skew-y-6:focus{--transform-skew-y:6deg}.lg\:focus\:skew-y-12:focus{--transform-skew-y:12deg}.lg\:focus\:-skew-y-12:focus{--transform-skew-y:-12deg}.lg\:focus\:-skew-y-6:focus{--transform-skew-y:-6deg}.lg\:focus\:-skew-y-3:focus{--transform-skew-y:-3deg}.lg\:focus\:-skew-y-2:focus{--transform-skew-y:-2deg}.lg\:focus\:-skew-y-1:focus{--transform-skew-y:-1deg}.lg\:transition-none{transition-property:none}.lg\:transition-all{transition-property:all}.lg\:transition{transition-property:background-color,border-color,color,fill,stroke,opacity,box-shadow,transform}.lg\:transition-colors{transition-property:background-color,border-color,color,fill,stroke}.lg\:transition-opacity{transition-property:opacity}.lg\:transition-shadow{transition-property:box-shadow}.lg\:transition-transform{transition-property:transform}.lg\:ease-linear{transition-timing-function:linear}.lg\:ease-in{transition-timing-function:cubic-bezier(.4,0,1,1)}.lg\:ease-out{transition-timing-function:cubic-bezier(0,0,.2,1)}.lg\:ease-in-out{transition-timing-function:cubic-bezier(.4,0,.2,1)}.lg\:duration-75{transition-duration:75ms}.lg\:duration-100{transition-duration:.1s}.lg\:duration-150{transition-duration:150ms}.lg\:duration-200{transition-duration:.2s}.lg\:duration-300{transition-duration:.3s}.lg\:duration-500{transition-duration:.5s}.lg\:duration-700{transition-duration:.7s}.lg\:duration-1000{transition-duration:1s}.lg\:delay-75{transition-delay:75ms}.lg\:delay-100{transition-delay:.1s}.lg\:delay-150{transition-delay:150ms}.lg\:delay-200{transition-delay:.2s}.lg\:delay-300{transition-delay:.3s}.lg\:delay-500{transition-delay:.5s}.lg\:delay-700{transition-delay:.7s}.lg\:delay-1000{transition-delay:1s}.lg\:animate-none{animation:none}.lg\:animate-spin{animation:spin 1s linear infinite}.lg\:animate-ping{animation:ping 1s cubic-bezier(0,0,.2,1) infinite}.lg\:animate-pulse{animation:pulse 2s cubic-bezier(.4,0,.6,1) infinite}.lg\:animate-bounce{animation:bounce 1s infinite}}@media (min-width:1280px){.xl\:container{width:100%}@media (min-width:640px){.xl\:container{max-width:640px}}@media (min-width:768px){.xl\:container{max-width:768px}}@media (min-width:1024px){.xl\:container{max-width:1024px}}@media (min-width:1280px){.xl\:container{max-width:1280px}}.xl\:space-y-0>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(0px * calc(1 - var(--space-y-reverse)));margin-bottom:calc(0px * var(--space-y-reverse))}.xl\:space-x-0>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(0px * var(--space-x-reverse));margin-left:calc(0px * calc(1 - var(--space-x-reverse)))}.xl\:space-y-1>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(.25rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(.25rem * var(--space-y-reverse))}.xl\:space-x-1>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(.25rem * var(--space-x-reverse));margin-left:calc(.25rem * calc(1 - var(--space-x-reverse)))}.xl\:space-y-2>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(.5rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(.5rem * var(--space-y-reverse))}.xl\:space-x-2>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(.5rem * var(--space-x-reverse));margin-left:calc(.5rem * calc(1 - var(--space-x-reverse)))}.xl\:space-y-3>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(.75rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(.75rem * var(--space-y-reverse))}.xl\:space-x-3>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(.75rem * var(--space-x-reverse));margin-left:calc(.75rem * calc(1 - var(--space-x-reverse)))}.xl\:space-y-4>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(1rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(1rem * var(--space-y-reverse))}.xl\:space-x-4>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(1rem * var(--space-x-reverse));margin-left:calc(1rem * calc(1 - var(--space-x-reverse)))}.xl\:space-y-5>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(1.25rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(1.25rem * var(--space-y-reverse))}.xl\:space-x-5>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(1.25rem * var(--space-x-reverse));margin-left:calc(1.25rem * calc(1 - var(--space-x-reverse)))}.xl\:space-y-6>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(1.5rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(1.5rem * var(--space-y-reverse))}.xl\:space-x-6>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(1.5rem * var(--space-x-reverse));margin-left:calc(1.5rem * calc(1 - var(--space-x-reverse)))}.xl\:space-y-8>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(2rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(2rem * var(--space-y-reverse))}.xl\:space-x-8>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(2rem * var(--space-x-reverse));margin-left:calc(2rem * calc(1 - var(--space-x-reverse)))}.xl\:space-y-10>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(2.5rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(2.5rem * var(--space-y-reverse))}.xl\:space-x-10>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(2.5rem * var(--space-x-reverse));margin-left:calc(2.5rem * calc(1 - var(--space-x-reverse)))}.xl\:space-y-12>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(3rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(3rem * var(--space-y-reverse))}.xl\:space-x-12>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(3rem * var(--space-x-reverse));margin-left:calc(3rem * calc(1 - var(--space-x-reverse)))}.xl\:space-y-16>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(4rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(4rem * var(--space-y-reverse))}.xl\:space-x-16>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(4rem * var(--space-x-reverse));margin-left:calc(4rem * calc(1 - var(--space-x-reverse)))}.xl\:space-y-20>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(5rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(5rem * var(--space-y-reverse))}.xl\:space-x-20>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(5rem * var(--space-x-reverse));margin-left:calc(5rem * calc(1 - var(--space-x-reverse)))}.xl\:space-y-24>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(6rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(6rem * var(--space-y-reverse))}.xl\:space-x-24>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(6rem * var(--space-x-reverse));margin-left:calc(6rem * calc(1 - var(--space-x-reverse)))}.xl\:space-y-32>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(8rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(8rem * var(--space-y-reverse))}.xl\:space-x-32>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(8rem * var(--space-x-reverse));margin-left:calc(8rem * calc(1 - var(--space-x-reverse)))}.xl\:space-y-40>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(10rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(10rem * var(--space-y-reverse))}.xl\:space-x-40>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(10rem * var(--space-x-reverse));margin-left:calc(10rem * calc(1 - var(--space-x-reverse)))}.xl\:space-y-48>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(12rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(12rem * var(--space-y-reverse))}.xl\:space-x-48>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(12rem * var(--space-x-reverse));margin-left:calc(12rem * calc(1 - var(--space-x-reverse)))}.xl\:space-y-56>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(14rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(14rem * var(--space-y-reverse))}.xl\:space-x-56>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(14rem * var(--space-x-reverse));margin-left:calc(14rem * calc(1 - var(--space-x-reverse)))}.xl\:space-y-64>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(16rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(16rem * var(--space-y-reverse))}.xl\:space-x-64>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(16rem * var(--space-x-reverse));margin-left:calc(16rem * calc(1 - var(--space-x-reverse)))}.xl\:space-y-px>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(1px * calc(1 - var(--space-y-reverse)));margin-bottom:calc(1px * var(--space-y-reverse))}.xl\:space-x-px>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(1px * var(--space-x-reverse));margin-left:calc(1px * calc(1 - var(--space-x-reverse)))}.xl\:-space-y-1>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-.25rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-.25rem * var(--space-y-reverse))}.xl\:-space-x-1>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-.25rem * var(--space-x-reverse));margin-left:calc(-.25rem * calc(1 - var(--space-x-reverse)))}.xl\:-space-y-2>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-.5rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-.5rem * var(--space-y-reverse))}.xl\:-space-x-2>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-.5rem * var(--space-x-reverse));margin-left:calc(-.5rem * calc(1 - var(--space-x-reverse)))}.xl\:-space-y-3>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-.75rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-.75rem * var(--space-y-reverse))}.xl\:-space-x-3>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-.75rem * var(--space-x-reverse));margin-left:calc(-.75rem * calc(1 - var(--space-x-reverse)))}.xl\:-space-y-4>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-1rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-1rem * var(--space-y-reverse))}.xl\:-space-x-4>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-1rem * var(--space-x-reverse));margin-left:calc(-1rem * calc(1 - var(--space-x-reverse)))}.xl\:-space-y-5>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-1.25rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-1.25rem * var(--space-y-reverse))}.xl\:-space-x-5>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-1.25rem * var(--space-x-reverse));margin-left:calc(-1.25rem * calc(1 - var(--space-x-reverse)))}.xl\:-space-y-6>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-1.5rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-1.5rem * var(--space-y-reverse))}.xl\:-space-x-6>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-1.5rem * var(--space-x-reverse));margin-left:calc(-1.5rem * calc(1 - var(--space-x-reverse)))}.xl\:-space-y-8>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-2rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-2rem * var(--space-y-reverse))}.xl\:-space-x-8>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-2rem * var(--space-x-reverse));margin-left:calc(-2rem * calc(1 - var(--space-x-reverse)))}.xl\:-space-y-10>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-2.5rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-2.5rem * var(--space-y-reverse))}.xl\:-space-x-10>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-2.5rem * var(--space-x-reverse));margin-left:calc(-2.5rem * calc(1 - var(--space-x-reverse)))}.xl\:-space-y-12>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-3rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-3rem * var(--space-y-reverse))}.xl\:-space-x-12>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-3rem * var(--space-x-reverse));margin-left:calc(-3rem * calc(1 - var(--space-x-reverse)))}.xl\:-space-y-16>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-4rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-4rem * var(--space-y-reverse))}.xl\:-space-x-16>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-4rem * var(--space-x-reverse));margin-left:calc(-4rem * calc(1 - var(--space-x-reverse)))}.xl\:-space-y-20>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-5rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-5rem * var(--space-y-reverse))}.xl\:-space-x-20>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-5rem * var(--space-x-reverse));margin-left:calc(-5rem * calc(1 - var(--space-x-reverse)))}.xl\:-space-y-24>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-6rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-6rem * var(--space-y-reverse))}.xl\:-space-x-24>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-6rem * var(--space-x-reverse));margin-left:calc(-6rem * calc(1 - var(--space-x-reverse)))}.xl\:-space-y-32>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-8rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-8rem * var(--space-y-reverse))}.xl\:-space-x-32>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-8rem * var(--space-x-reverse));margin-left:calc(-8rem * calc(1 - var(--space-x-reverse)))}.xl\:-space-y-40>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-10rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-10rem * var(--space-y-reverse))}.xl\:-space-x-40>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-10rem * var(--space-x-reverse));margin-left:calc(-10rem * calc(1 - var(--space-x-reverse)))}.xl\:-space-y-48>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-12rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-12rem * var(--space-y-reverse))}.xl\:-space-x-48>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-12rem * var(--space-x-reverse));margin-left:calc(-12rem * calc(1 - var(--space-x-reverse)))}.xl\:-space-y-56>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-14rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-14rem * var(--space-y-reverse))}.xl\:-space-x-56>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-14rem * var(--space-x-reverse));margin-left:calc(-14rem * calc(1 - var(--space-x-reverse)))}.xl\:-space-y-64>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-16rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-16rem * var(--space-y-reverse))}.xl\:-space-x-64>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-16rem * var(--space-x-reverse));margin-left:calc(-16rem * calc(1 - var(--space-x-reverse)))}.xl\:-space-y-px>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-1px * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-1px * var(--space-y-reverse))}.xl\:-space-x-px>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-1px * var(--space-x-reverse));margin-left:calc(-1px * calc(1 - var(--space-x-reverse)))}.xl\:space-y-reverse>:not(template)~:not(template){--space-y-reverse:1}.xl\:space-x-reverse>:not(template)~:not(template){--space-x-reverse:1}.xl\:divide-y-0>:not(template)~:not(template){--divide-y-reverse:0;border-top-width:calc(0px * calc(1 - var(--divide-y-reverse)));border-bottom-width:calc(0px * var(--divide-y-reverse))}.xl\:divide-x-0>:not(template)~:not(template){--divide-x-reverse:0;border-right-width:calc(0px * var(--divide-x-reverse));border-left-width:calc(0px * calc(1 - var(--divide-x-reverse)))}.xl\:divide-y-2>:not(template)~:not(template){--divide-y-reverse:0;border-top-width:calc(2px * calc(1 - var(--divide-y-reverse)));border-bottom-width:calc(2px * var(--divide-y-reverse))}.xl\:divide-x-2>:not(template)~:not(template){--divide-x-reverse:0;border-right-width:calc(2px * var(--divide-x-reverse));border-left-width:calc(2px * calc(1 - var(--divide-x-reverse)))}.xl\:divide-y-4>:not(template)~:not(template){--divide-y-reverse:0;border-top-width:calc(4px * calc(1 - var(--divide-y-reverse)));border-bottom-width:calc(4px * var(--divide-y-reverse))}.xl\:divide-x-4>:not(template)~:not(template){--divide-x-reverse:0;border-right-width:calc(4px * var(--divide-x-reverse));border-left-width:calc(4px * calc(1 - var(--divide-x-reverse)))}.xl\:divide-y-8>:not(template)~:not(template){--divide-y-reverse:0;border-top-width:calc(8px * calc(1 - var(--divide-y-reverse)));border-bottom-width:calc(8px * var(--divide-y-reverse))}.xl\:divide-x-8>:not(template)~:not(template){--divide-x-reverse:0;border-right-width:calc(8px * var(--divide-x-reverse));border-left-width:calc(8px * calc(1 - var(--divide-x-reverse)))}.xl\:divide-y>:not(template)~:not(template){--divide-y-reverse:0;border-top-width:calc(1px * calc(1 - var(--divide-y-reverse)));border-bottom-width:calc(1px * var(--divide-y-reverse))}.xl\:divide-x>:not(template)~:not(template){--divide-x-reverse:0;border-right-width:calc(1px * var(--divide-x-reverse));border-left-width:calc(1px * calc(1 - var(--divide-x-reverse)))}.xl\:divide-y-reverse>:not(template)~:not(template){--divide-y-reverse:1}.xl\:divide-x-reverse>:not(template)~:not(template){--divide-x-reverse:1}.xl\:divide-transparent>:not(template)~:not(template){border-color:transparent}.xl\:divide-current>:not(template)~:not(template){border-color:currentColor}.xl\:divide-black>:not(template)~:not(template){--divide-opacity:1;border-color:#000;border-color:rgba(0,0,0,var(--divide-opacity))}.xl\:divide-white>:not(template)~:not(template){--divide-opacity:1;border-color:#fff;border-color:rgba(255,255,255,var(--divide-opacity))}.xl\:divide-gray-100>:not(template)~:not(template){--divide-opacity:1;border-color:#f7fafc;border-color:rgba(247,250,252,var(--divide-opacity))}.xl\:divide-gray-200>:not(template)~:not(template){--divide-opacity:1;border-color:#edf2f7;border-color:rgba(237,242,247,var(--divide-opacity))}.xl\:divide-gray-300>:not(template)~:not(template){--divide-opacity:1;border-color:#e2e8f0;border-color:rgba(226,232,240,var(--divide-opacity))}.xl\:divide-gray-400>:not(template)~:not(template){--divide-opacity:1;border-color:#cbd5e0;border-color:rgba(203,213,224,var(--divide-opacity))}.xl\:divide-gray-500>:not(template)~:not(template){--divide-opacity:1;border-color:#a0aec0;border-color:rgba(160,174,192,var(--divide-opacity))}.xl\:divide-gray-600>:not(template)~:not(template){--divide-opacity:1;border-color:#718096;border-color:rgba(113,128,150,var(--divide-opacity))}.xl\:divide-gray-700>:not(template)~:not(template){--divide-opacity:1;border-color:#4a5568;border-color:rgba(74,85,104,var(--divide-opacity))}.xl\:divide-gray-800>:not(template)~:not(template){--divide-opacity:1;border-color:#2d3748;border-color:rgba(45,55,72,var(--divide-opacity))}.xl\:divide-gray-900>:not(template)~:not(template){--divide-opacity:1;border-color:#1a202c;border-color:rgba(26,32,44,var(--divide-opacity))}.xl\:divide-red-100>:not(template)~:not(template){--divide-opacity:1;border-color:#fff5f5;border-color:rgba(255,245,245,var(--divide-opacity))}.xl\:divide-red-200>:not(template)~:not(template){--divide-opacity:1;border-color:#fed7d7;border-color:rgba(254,215,215,var(--divide-opacity))}.xl\:divide-red-300>:not(template)~:not(template){--divide-opacity:1;border-color:#feb2b2;border-color:rgba(254,178,178,var(--divide-opacity))}.xl\:divide-red-400>:not(template)~:not(template){--divide-opacity:1;border-color:#fc8181;border-color:rgba(252,129,129,var(--divide-opacity))}.xl\:divide-red-500>:not(template)~:not(template){--divide-opacity:1;border-color:#f56565;border-color:rgba(245,101,101,var(--divide-opacity))}.xl\:divide-red-600>:not(template)~:not(template){--divide-opacity:1;border-color:#e53e3e;border-color:rgba(229,62,62,var(--divide-opacity))}.xl\:divide-red-700>:not(template)~:not(template){--divide-opacity:1;border-color:#c53030;border-color:rgba(197,48,48,var(--divide-opacity))}.xl\:divide-red-800>:not(template)~:not(template){--divide-opacity:1;border-color:#9b2c2c;border-color:rgba(155,44,44,var(--divide-opacity))}.xl\:divide-red-900>:not(template)~:not(template){--divide-opacity:1;border-color:#742a2a;border-color:rgba(116,42,42,var(--divide-opacity))}.xl\:divide-orange-100>:not(template)~:not(template){--divide-opacity:1;border-color:#fffaf0;border-color:rgba(255,250,240,var(--divide-opacity))}.xl\:divide-orange-200>:not(template)~:not(template){--divide-opacity:1;border-color:#feebc8;border-color:rgba(254,235,200,var(--divide-opacity))}.xl\:divide-orange-300>:not(template)~:not(template){--divide-opacity:1;border-color:#fbd38d;border-color:rgba(251,211,141,var(--divide-opacity))}.xl\:divide-orange-400>:not(template)~:not(template){--divide-opacity:1;border-color:#f6ad55;border-color:rgba(246,173,85,var(--divide-opacity))}.xl\:divide-orange-500>:not(template)~:not(template){--divide-opacity:1;border-color:#ed8936;border-color:rgba(237,137,54,var(--divide-opacity))}.xl\:divide-orange-600>:not(template)~:not(template){--divide-opacity:1;border-color:#dd6b20;border-color:rgba(221,107,32,var(--divide-opacity))}.xl\:divide-orange-700>:not(template)~:not(template){--divide-opacity:1;border-color:#c05621;border-color:rgba(192,86,33,var(--divide-opacity))}.xl\:divide-orange-800>:not(template)~:not(template){--divide-opacity:1;border-color:#9c4221;border-color:rgba(156,66,33,var(--divide-opacity))}.xl\:divide-orange-900>:not(template)~:not(template){--divide-opacity:1;border-color:#7b341e;border-color:rgba(123,52,30,var(--divide-opacity))}.xl\:divide-yellow-100>:not(template)~:not(template){--divide-opacity:1;border-color:ivory;border-color:rgba(255,255,240,var(--divide-opacity))}.xl\:divide-yellow-200>:not(template)~:not(template){--divide-opacity:1;border-color:#fefcbf;border-color:rgba(254,252,191,var(--divide-opacity))}.xl\:divide-yellow-300>:not(template)~:not(template){--divide-opacity:1;border-color:#faf089;border-color:rgba(250,240,137,var(--divide-opacity))}.xl\:divide-yellow-400>:not(template)~:not(template){--divide-opacity:1;border-color:#f6e05e;border-color:rgba(246,224,94,var(--divide-opacity))}.xl\:divide-yellow-500>:not(template)~:not(template){--divide-opacity:1;border-color:#ecc94b;border-color:rgba(236,201,75,var(--divide-opacity))}.xl\:divide-yellow-600>:not(template)~:not(template){--divide-opacity:1;border-color:#d69e2e;border-color:rgba(214,158,46,var(--divide-opacity))}.xl\:divide-yellow-700>:not(template)~:not(template){--divide-opacity:1;border-color:#b7791f;border-color:rgba(183,121,31,var(--divide-opacity))}.xl\:divide-yellow-800>:not(template)~:not(template){--divide-opacity:1;border-color:#975a16;border-color:rgba(151,90,22,var(--divide-opacity))}.xl\:divide-yellow-900>:not(template)~:not(template){--divide-opacity:1;border-color:#744210;border-color:rgba(116,66,16,var(--divide-opacity))}.xl\:divide-green-100>:not(template)~:not(template){--divide-opacity:1;border-color:#f0fff4;border-color:rgba(240,255,244,var(--divide-opacity))}.xl\:divide-green-200>:not(template)~:not(template){--divide-opacity:1;border-color:#c6f6d5;border-color:rgba(198,246,213,var(--divide-opacity))}.xl\:divide-green-300>:not(template)~:not(template){--divide-opacity:1;border-color:#9ae6b4;border-color:rgba(154,230,180,var(--divide-opacity))}.xl\:divide-green-400>:not(template)~:not(template){--divide-opacity:1;border-color:#68d391;border-color:rgba(104,211,145,var(--divide-opacity))}.xl\:divide-green-500>:not(template)~:not(template){--divide-opacity:1;border-color:#48bb78;border-color:rgba(72,187,120,var(--divide-opacity))}.xl\:divide-green-600>:not(template)~:not(template){--divide-opacity:1;border-color:#38a169;border-color:rgba(56,161,105,var(--divide-opacity))}.xl\:divide-green-700>:not(template)~:not(template){--divide-opacity:1;border-color:#2f855a;border-color:rgba(47,133,90,var(--divide-opacity))}.xl\:divide-green-800>:not(template)~:not(template){--divide-opacity:1;border-color:#276749;border-color:rgba(39,103,73,var(--divide-opacity))}.xl\:divide-green-900>:not(template)~:not(template){--divide-opacity:1;border-color:#22543d;border-color:rgba(34,84,61,var(--divide-opacity))}.xl\:divide-teal-100>:not(template)~:not(template){--divide-opacity:1;border-color:#e6fffa;border-color:rgba(230,255,250,var(--divide-opacity))}.xl\:divide-teal-200>:not(template)~:not(template){--divide-opacity:1;border-color:#b2f5ea;border-color:rgba(178,245,234,var(--divide-opacity))}.xl\:divide-teal-300>:not(template)~:not(template){--divide-opacity:1;border-color:#81e6d9;border-color:rgba(129,230,217,var(--divide-opacity))}.xl\:divide-teal-400>:not(template)~:not(template){--divide-opacity:1;border-color:#4fd1c5;border-color:rgba(79,209,197,var(--divide-opacity))}.xl\:divide-teal-500>:not(template)~:not(template){--divide-opacity:1;border-color:#38b2ac;border-color:rgba(56,178,172,var(--divide-opacity))}.xl\:divide-teal-600>:not(template)~:not(template){--divide-opacity:1;border-color:#319795;border-color:rgba(49,151,149,var(--divide-opacity))}.xl\:divide-teal-700>:not(template)~:not(template){--divide-opacity:1;border-color:#2c7a7b;border-color:rgba(44,122,123,var(--divide-opacity))}.xl\:divide-teal-800>:not(template)~:not(template){--divide-opacity:1;border-color:#285e61;border-color:rgba(40,94,97,var(--divide-opacity))}.xl\:divide-teal-900>:not(template)~:not(template){--divide-opacity:1;border-color:#234e52;border-color:rgba(35,78,82,var(--divide-opacity))}.xl\:divide-blue-100>:not(template)~:not(template){--divide-opacity:1;border-color:#ebf8ff;border-color:rgba(235,248,255,var(--divide-opacity))}.xl\:divide-blue-200>:not(template)~:not(template){--divide-opacity:1;border-color:#bee3f8;border-color:rgba(190,227,248,var(--divide-opacity))}.xl\:divide-blue-300>:not(template)~:not(template){--divide-opacity:1;border-color:#90cdf4;border-color:rgba(144,205,244,var(--divide-opacity))}.xl\:divide-blue-400>:not(template)~:not(template){--divide-opacity:1;border-color:#63b3ed;border-color:rgba(99,179,237,var(--divide-opacity))}.xl\:divide-blue-500>:not(template)~:not(template){--divide-opacity:1;border-color:#4299e1;border-color:rgba(66,153,225,var(--divide-opacity))}.xl\:divide-blue-600>:not(template)~:not(template){--divide-opacity:1;border-color:#3182ce;border-color:rgba(49,130,206,var(--divide-opacity))}.xl\:divide-blue-700>:not(template)~:not(template){--divide-opacity:1;border-color:#2b6cb0;border-color:rgba(43,108,176,var(--divide-opacity))}.xl\:divide-blue-800>:not(template)~:not(template){--divide-opacity:1;border-color:#2c5282;border-color:rgba(44,82,130,var(--divide-opacity))}.xl\:divide-blue-900>:not(template)~:not(template){--divide-opacity:1;border-color:#2a4365;border-color:rgba(42,67,101,var(--divide-opacity))}.xl\:divide-indigo-100>:not(template)~:not(template){--divide-opacity:1;border-color:#ebf4ff;border-color:rgba(235,244,255,var(--divide-opacity))}.xl\:divide-indigo-200>:not(template)~:not(template){--divide-opacity:1;border-color:#c3dafe;border-color:rgba(195,218,254,var(--divide-opacity))}.xl\:divide-indigo-300>:not(template)~:not(template){--divide-opacity:1;border-color:#a3bffa;border-color:rgba(163,191,250,var(--divide-opacity))}.xl\:divide-indigo-400>:not(template)~:not(template){--divide-opacity:1;border-color:#7f9cf5;border-color:rgba(127,156,245,var(--divide-opacity))}.xl\:divide-indigo-500>:not(template)~:not(template){--divide-opacity:1;border-color:#667eea;border-color:rgba(102,126,234,var(--divide-opacity))}.xl\:divide-indigo-600>:not(template)~:not(template){--divide-opacity:1;border-color:#5a67d8;border-color:rgba(90,103,216,var(--divide-opacity))}.xl\:divide-indigo-700>:not(template)~:not(template){--divide-opacity:1;border-color:#4c51bf;border-color:rgba(76,81,191,var(--divide-opacity))}.xl\:divide-indigo-800>:not(template)~:not(template){--divide-opacity:1;border-color:#434190;border-color:rgba(67,65,144,var(--divide-opacity))}.xl\:divide-indigo-900>:not(template)~:not(template){--divide-opacity:1;border-color:#3c366b;border-color:rgba(60,54,107,var(--divide-opacity))}.xl\:divide-purple-100>:not(template)~:not(template){--divide-opacity:1;border-color:#faf5ff;border-color:rgba(250,245,255,var(--divide-opacity))}.xl\:divide-purple-200>:not(template)~:not(template){--divide-opacity:1;border-color:#e9d8fd;border-color:rgba(233,216,253,var(--divide-opacity))}.xl\:divide-purple-300>:not(template)~:not(template){--divide-opacity:1;border-color:#d6bcfa;border-color:rgba(214,188,250,var(--divide-opacity))}.xl\:divide-purple-400>:not(template)~:not(template){--divide-opacity:1;border-color:#b794f4;border-color:rgba(183,148,244,var(--divide-opacity))}.xl\:divide-purple-500>:not(template)~:not(template){--divide-opacity:1;border-color:#9f7aea;border-color:rgba(159,122,234,var(--divide-opacity))}.xl\:divide-purple-600>:not(template)~:not(template){--divide-opacity:1;border-color:#805ad5;border-color:rgba(128,90,213,var(--divide-opacity))}.xl\:divide-purple-700>:not(template)~:not(template){--divide-opacity:1;border-color:#6b46c1;border-color:rgba(107,70,193,var(--divide-opacity))}.xl\:divide-purple-800>:not(template)~:not(template){--divide-opacity:1;border-color:#553c9a;border-color:rgba(85,60,154,var(--divide-opacity))}.xl\:divide-purple-900>:not(template)~:not(template){--divide-opacity:1;border-color:#44337a;border-color:rgba(68,51,122,var(--divide-opacity))}.xl\:divide-pink-100>:not(template)~:not(template){--divide-opacity:1;border-color:#fff5f7;border-color:rgba(255,245,247,var(--divide-opacity))}.xl\:divide-pink-200>:not(template)~:not(template){--divide-opacity:1;border-color:#fed7e2;border-color:rgba(254,215,226,var(--divide-opacity))}.xl\:divide-pink-300>:not(template)~:not(template){--divide-opacity:1;border-color:#fbb6ce;border-color:rgba(251,182,206,var(--divide-opacity))}.xl\:divide-pink-400>:not(template)~:not(template){--divide-opacity:1;border-color:#f687b3;border-color:rgba(246,135,179,var(--divide-opacity))}.xl\:divide-pink-500>:not(template)~:not(template){--divide-opacity:1;border-color:#ed64a6;border-color:rgba(237,100,166,var(--divide-opacity))}.xl\:divide-pink-600>:not(template)~:not(template){--divide-opacity:1;border-color:#d53f8c;border-color:rgba(213,63,140,var(--divide-opacity))}.xl\:divide-pink-700>:not(template)~:not(template){--divide-opacity:1;border-color:#b83280;border-color:rgba(184,50,128,var(--divide-opacity))}.xl\:divide-pink-800>:not(template)~:not(template){--divide-opacity:1;border-color:#97266d;border-color:rgba(151,38,109,var(--divide-opacity))}.xl\:divide-pink-900>:not(template)~:not(template){--divide-opacity:1;border-color:#702459;border-color:rgba(112,36,89,var(--divide-opacity))}.xl\:divide-solid>:not(template)~:not(template){border-style:solid}.xl\:divide-dashed>:not(template)~:not(template){border-style:dashed}.xl\:divide-dotted>:not(template)~:not(template){border-style:dotted}.xl\:divide-double>:not(template)~:not(template){border-style:double}.xl\:divide-none>:not(template)~:not(template){border-style:none}.xl\:divide-opacity-0>:not(template)~:not(template){--divide-opacity:0}.xl\:divide-opacity-25>:not(template)~:not(template){--divide-opacity:0.25}.xl\:divide-opacity-50>:not(template)~:not(template){--divide-opacity:0.5}.xl\:divide-opacity-75>:not(template)~:not(template){--divide-opacity:0.75}.xl\:divide-opacity-100>:not(template)~:not(template){--divide-opacity:1}.xl\:sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border-width:0}.xl\:not-sr-only{position:static;width:auto;height:auto;padding:0;margin:0;overflow:visible;clip:auto;white-space:normal}.xl\:focus\:sr-only:focus{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border-width:0}.xl\:focus\:not-sr-only:focus{position:static;width:auto;height:auto;padding:0;margin:0;overflow:visible;clip:auto;white-space:normal}.xl\:appearance-none{-webkit-appearance:none;-moz-appearance:none;appearance:none}.xl\:bg-fixed{background-attachment:fixed}.xl\:bg-local{background-attachment:local}.xl\:bg-scroll{background-attachment:scroll}.xl\:bg-clip-border{background-clip:border-box}.xl\:bg-clip-padding{background-clip:padding-box}.xl\:bg-clip-content{background-clip:content-box}.xl\:bg-clip-text{-webkit-background-clip:text;background-clip:text}.xl\:bg-transparent{background-color:transparent}.xl\:bg-current{background-color:currentColor}.xl\:bg-black{--bg-opacity:1;background-color:#000;background-color:rgba(0,0,0,var(--bg-opacity))}.xl\:bg-white{--bg-opacity:1;background-color:#fff;background-color:rgba(255,255,255,var(--bg-opacity))}.xl\:bg-gray-100{--bg-opacity:1;background-color:#f7fafc;background-color:rgba(247,250,252,var(--bg-opacity))}.xl\:bg-gray-200{--bg-opacity:1;background-color:#edf2f7;background-color:rgba(237,242,247,var(--bg-opacity))}.xl\:bg-gray-300{--bg-opacity:1;background-color:#e2e8f0;background-color:rgba(226,232,240,var(--bg-opacity))}.xl\:bg-gray-400{--bg-opacity:1;background-color:#cbd5e0;background-color:rgba(203,213,224,var(--bg-opacity))}.xl\:bg-gray-500{--bg-opacity:1;background-color:#a0aec0;background-color:rgba(160,174,192,var(--bg-opacity))}.xl\:bg-gray-600{--bg-opacity:1;background-color:#718096;background-color:rgba(113,128,150,var(--bg-opacity))}.xl\:bg-gray-700{--bg-opacity:1;background-color:#4a5568;background-color:rgba(74,85,104,var(--bg-opacity))}.xl\:bg-gray-800{--bg-opacity:1;background-color:#2d3748;background-color:rgba(45,55,72,var(--bg-opacity))}.xl\:bg-gray-900{--bg-opacity:1;background-color:#1a202c;background-color:rgba(26,32,44,var(--bg-opacity))}.xl\:bg-red-100{--bg-opacity:1;background-color:#fff5f5;background-color:rgba(255,245,245,var(--bg-opacity))}.xl\:bg-red-200{--bg-opacity:1;background-color:#fed7d7;background-color:rgba(254,215,215,var(--bg-opacity))}.xl\:bg-red-300{--bg-opacity:1;background-color:#feb2b2;background-color:rgba(254,178,178,var(--bg-opacity))}.xl\:bg-red-400{--bg-opacity:1;background-color:#fc8181;background-color:rgba(252,129,129,var(--bg-opacity))}.xl\:bg-red-500{--bg-opacity:1;background-color:#f56565;background-color:rgba(245,101,101,var(--bg-opacity))}.xl\:bg-red-600{--bg-opacity:1;background-color:#e53e3e;background-color:rgba(229,62,62,var(--bg-opacity))}.xl\:bg-red-700{--bg-opacity:1;background-color:#c53030;background-color:rgba(197,48,48,var(--bg-opacity))}.xl\:bg-red-800{--bg-opacity:1;background-color:#9b2c2c;background-color:rgba(155,44,44,var(--bg-opacity))}.xl\:bg-red-900{--bg-opacity:1;background-color:#742a2a;background-color:rgba(116,42,42,var(--bg-opacity))}.xl\:bg-orange-100{--bg-opacity:1;background-color:#fffaf0;background-color:rgba(255,250,240,var(--bg-opacity))}.xl\:bg-orange-200{--bg-opacity:1;background-color:#feebc8;background-color:rgba(254,235,200,var(--bg-opacity))}.xl\:bg-orange-300{--bg-opacity:1;background-color:#fbd38d;background-color:rgba(251,211,141,var(--bg-opacity))}.xl\:bg-orange-400{--bg-opacity:1;background-color:#f6ad55;background-color:rgba(246,173,85,var(--bg-opacity))}.xl\:bg-orange-500{--bg-opacity:1;background-color:#ed8936;background-color:rgba(237,137,54,var(--bg-opacity))}.xl\:bg-orange-600{--bg-opacity:1;background-color:#dd6b20;background-color:rgba(221,107,32,var(--bg-opacity))}.xl\:bg-orange-700{--bg-opacity:1;background-color:#c05621;background-color:rgba(192,86,33,var(--bg-opacity))}.xl\:bg-orange-800{--bg-opacity:1;background-color:#9c4221;background-color:rgba(156,66,33,var(--bg-opacity))}.xl\:bg-orange-900{--bg-opacity:1;background-color:#7b341e;background-color:rgba(123,52,30,var(--bg-opacity))}.xl\:bg-yellow-100{--bg-opacity:1;background-color:ivory;background-color:rgba(255,255,240,var(--bg-opacity))}.xl\:bg-yellow-200{--bg-opacity:1;background-color:#fefcbf;background-color:rgba(254,252,191,var(--bg-opacity))}.xl\:bg-yellow-300{--bg-opacity:1;background-color:#faf089;background-color:rgba(250,240,137,var(--bg-opacity))}.xl\:bg-yellow-400{--bg-opacity:1;background-color:#f6e05e;background-color:rgba(246,224,94,var(--bg-opacity))}.xl\:bg-yellow-500{--bg-opacity:1;background-color:#ecc94b;background-color:rgba(236,201,75,var(--bg-opacity))}.xl\:bg-yellow-600{--bg-opacity:1;background-color:#d69e2e;background-color:rgba(214,158,46,var(--bg-opacity))}.xl\:bg-yellow-700{--bg-opacity:1;background-color:#b7791f;background-color:rgba(183,121,31,var(--bg-opacity))}.xl\:bg-yellow-800{--bg-opacity:1;background-color:#975a16;background-color:rgba(151,90,22,var(--bg-opacity))}.xl\:bg-yellow-900{--bg-opacity:1;background-color:#744210;background-color:rgba(116,66,16,var(--bg-opacity))}.xl\:bg-green-100{--bg-opacity:1;background-color:#f0fff4;background-color:rgba(240,255,244,var(--bg-opacity))}.xl\:bg-green-200{--bg-opacity:1;background-color:#c6f6d5;background-color:rgba(198,246,213,var(--bg-opacity))}.xl\:bg-green-300{--bg-opacity:1;background-color:#9ae6b4;background-color:rgba(154,230,180,var(--bg-opacity))}.xl\:bg-green-400{--bg-opacity:1;background-color:#68d391;background-color:rgba(104,211,145,var(--bg-opacity))}.xl\:bg-green-500{--bg-opacity:1;background-color:#48bb78;background-color:rgba(72,187,120,var(--bg-opacity))}.xl\:bg-green-600{--bg-opacity:1;background-color:#38a169;background-color:rgba(56,161,105,var(--bg-opacity))}.xl\:bg-green-700{--bg-opacity:1;background-color:#2f855a;background-color:rgba(47,133,90,var(--bg-opacity))}.xl\:bg-green-800{--bg-opacity:1;background-color:#276749;background-color:rgba(39,103,73,var(--bg-opacity))}.xl\:bg-green-900{--bg-opacity:1;background-color:#22543d;background-color:rgba(34,84,61,var(--bg-opacity))}.xl\:bg-teal-100{--bg-opacity:1;background-color:#e6fffa;background-color:rgba(230,255,250,var(--bg-opacity))}.xl\:bg-teal-200{--bg-opacity:1;background-color:#b2f5ea;background-color:rgba(178,245,234,var(--bg-opacity))}.xl\:bg-teal-300{--bg-opacity:1;background-color:#81e6d9;background-color:rgba(129,230,217,var(--bg-opacity))}.xl\:bg-teal-400{--bg-opacity:1;background-color:#4fd1c5;background-color:rgba(79,209,197,var(--bg-opacity))}.xl\:bg-teal-500{--bg-opacity:1;background-color:#38b2ac;background-color:rgba(56,178,172,var(--bg-opacity))}.xl\:bg-teal-600{--bg-opacity:1;background-color:#319795;background-color:rgba(49,151,149,var(--bg-opacity))}.xl\:bg-teal-700{--bg-opacity:1;background-color:#2c7a7b;background-color:rgba(44,122,123,var(--bg-opacity))}.xl\:bg-teal-800{--bg-opacity:1;background-color:#285e61;background-color:rgba(40,94,97,var(--bg-opacity))}.xl\:bg-teal-900{--bg-opacity:1;background-color:#234e52;background-color:rgba(35,78,82,var(--bg-opacity))}.xl\:bg-blue-100{--bg-opacity:1;background-color:#ebf8ff;background-color:rgba(235,248,255,var(--bg-opacity))}.xl\:bg-blue-200{--bg-opacity:1;background-color:#bee3f8;background-color:rgba(190,227,248,var(--bg-opacity))}.xl\:bg-blue-300{--bg-opacity:1;background-color:#90cdf4;background-color:rgba(144,205,244,var(--bg-opacity))}.xl\:bg-blue-400{--bg-opacity:1;background-color:#63b3ed;background-color:rgba(99,179,237,var(--bg-opacity))}.xl\:bg-blue-500{--bg-opacity:1;background-color:#4299e1;background-color:rgba(66,153,225,var(--bg-opacity))}.xl\:bg-blue-600{--bg-opacity:1;background-color:#3182ce;background-color:rgba(49,130,206,var(--bg-opacity))}.xl\:bg-blue-700{--bg-opacity:1;background-color:#2b6cb0;background-color:rgba(43,108,176,var(--bg-opacity))}.xl\:bg-blue-800{--bg-opacity:1;background-color:#2c5282;background-color:rgba(44,82,130,var(--bg-opacity))}.xl\:bg-blue-900{--bg-opacity:1;background-color:#2a4365;background-color:rgba(42,67,101,var(--bg-opacity))}.xl\:bg-indigo-100{--bg-opacity:1;background-color:#ebf4ff;background-color:rgba(235,244,255,var(--bg-opacity))}.xl\:bg-indigo-200{--bg-opacity:1;background-color:#c3dafe;background-color:rgba(195,218,254,var(--bg-opacity))}.xl\:bg-indigo-300{--bg-opacity:1;background-color:#a3bffa;background-color:rgba(163,191,250,var(--bg-opacity))}.xl\:bg-indigo-400{--bg-opacity:1;background-color:#7f9cf5;background-color:rgba(127,156,245,var(--bg-opacity))}.xl\:bg-indigo-500{--bg-opacity:1;background-color:#667eea;background-color:rgba(102,126,234,var(--bg-opacity))}.xl\:bg-indigo-600{--bg-opacity:1;background-color:#5a67d8;background-color:rgba(90,103,216,var(--bg-opacity))}.xl\:bg-indigo-700{--bg-opacity:1;background-color:#4c51bf;background-color:rgba(76,81,191,var(--bg-opacity))}.xl\:bg-indigo-800{--bg-opacity:1;background-color:#434190;background-color:rgba(67,65,144,var(--bg-opacity))}.xl\:bg-indigo-900{--bg-opacity:1;background-color:#3c366b;background-color:rgba(60,54,107,var(--bg-opacity))}.xl\:bg-purple-100{--bg-opacity:1;background-color:#faf5ff;background-color:rgba(250,245,255,var(--bg-opacity))}.xl\:bg-purple-200{--bg-opacity:1;background-color:#e9d8fd;background-color:rgba(233,216,253,var(--bg-opacity))}.xl\:bg-purple-300{--bg-opacity:1;background-color:#d6bcfa;background-color:rgba(214,188,250,var(--bg-opacity))}.xl\:bg-purple-400{--bg-opacity:1;background-color:#b794f4;background-color:rgba(183,148,244,var(--bg-opacity))}.xl\:bg-purple-500{--bg-opacity:1;background-color:#9f7aea;background-color:rgba(159,122,234,var(--bg-opacity))}.xl\:bg-purple-600{--bg-opacity:1;background-color:#805ad5;background-color:rgba(128,90,213,var(--bg-opacity))}.xl\:bg-purple-700{--bg-opacity:1;background-color:#6b46c1;background-color:rgba(107,70,193,var(--bg-opacity))}.xl\:bg-purple-800{--bg-opacity:1;background-color:#553c9a;background-color:rgba(85,60,154,var(--bg-opacity))}.xl\:bg-purple-900{--bg-opacity:1;background-color:#44337a;background-color:rgba(68,51,122,var(--bg-opacity))}.xl\:bg-pink-100{--bg-opacity:1;background-color:#fff5f7;background-color:rgba(255,245,247,var(--bg-opacity))}.xl\:bg-pink-200{--bg-opacity:1;background-color:#fed7e2;background-color:rgba(254,215,226,var(--bg-opacity))}.xl\:bg-pink-300{--bg-opacity:1;background-color:#fbb6ce;background-color:rgba(251,182,206,var(--bg-opacity))}.xl\:bg-pink-400{--bg-opacity:1;background-color:#f687b3;background-color:rgba(246,135,179,var(--bg-opacity))}.xl\:bg-pink-500{--bg-opacity:1;background-color:#ed64a6;background-color:rgba(237,100,166,var(--bg-opacity))}.xl\:bg-pink-600{--bg-opacity:1;background-color:#d53f8c;background-color:rgba(213,63,140,var(--bg-opacity))}.xl\:bg-pink-700{--bg-opacity:1;background-color:#b83280;background-color:rgba(184,50,128,var(--bg-opacity))}.xl\:bg-pink-800{--bg-opacity:1;background-color:#97266d;background-color:rgba(151,38,109,var(--bg-opacity))}.xl\:bg-pink-900{--bg-opacity:1;background-color:#702459;background-color:rgba(112,36,89,var(--bg-opacity))}.xl\:hover\:bg-transparent:hover{background-color:transparent}.xl\:hover\:bg-current:hover{background-color:currentColor}.xl\:hover\:bg-black:hover{--bg-opacity:1;background-color:#000;background-color:rgba(0,0,0,var(--bg-opacity))}.xl\:hover\:bg-white:hover{--bg-opacity:1;background-color:#fff;background-color:rgba(255,255,255,var(--bg-opacity))}.xl\:hover\:bg-gray-100:hover{--bg-opacity:1;background-color:#f7fafc;background-color:rgba(247,250,252,var(--bg-opacity))}.xl\:hover\:bg-gray-200:hover{--bg-opacity:1;background-color:#edf2f7;background-color:rgba(237,242,247,var(--bg-opacity))}.xl\:hover\:bg-gray-300:hover{--bg-opacity:1;background-color:#e2e8f0;background-color:rgba(226,232,240,var(--bg-opacity))}.xl\:hover\:bg-gray-400:hover{--bg-opacity:1;background-color:#cbd5e0;background-color:rgba(203,213,224,var(--bg-opacity))}.xl\:hover\:bg-gray-500:hover{--bg-opacity:1;background-color:#a0aec0;background-color:rgba(160,174,192,var(--bg-opacity))}.xl\:hover\:bg-gray-600:hover{--bg-opacity:1;background-color:#718096;background-color:rgba(113,128,150,var(--bg-opacity))}.xl\:hover\:bg-gray-700:hover{--bg-opacity:1;background-color:#4a5568;background-color:rgba(74,85,104,var(--bg-opacity))}.xl\:hover\:bg-gray-800:hover{--bg-opacity:1;background-color:#2d3748;background-color:rgba(45,55,72,var(--bg-opacity))}.xl\:hover\:bg-gray-900:hover{--bg-opacity:1;background-color:#1a202c;background-color:rgba(26,32,44,var(--bg-opacity))}.xl\:hover\:bg-red-100:hover{--bg-opacity:1;background-color:#fff5f5;background-color:rgba(255,245,245,var(--bg-opacity))}.xl\:hover\:bg-red-200:hover{--bg-opacity:1;background-color:#fed7d7;background-color:rgba(254,215,215,var(--bg-opacity))}.xl\:hover\:bg-red-300:hover{--bg-opacity:1;background-color:#feb2b2;background-color:rgba(254,178,178,var(--bg-opacity))}.xl\:hover\:bg-red-400:hover{--bg-opacity:1;background-color:#fc8181;background-color:rgba(252,129,129,var(--bg-opacity))}.xl\:hover\:bg-red-500:hover{--bg-opacity:1;background-color:#f56565;background-color:rgba(245,101,101,var(--bg-opacity))}.xl\:hover\:bg-red-600:hover{--bg-opacity:1;background-color:#e53e3e;background-color:rgba(229,62,62,var(--bg-opacity))}.xl\:hover\:bg-red-700:hover{--bg-opacity:1;background-color:#c53030;background-color:rgba(197,48,48,var(--bg-opacity))}.xl\:hover\:bg-red-800:hover{--bg-opacity:1;background-color:#9b2c2c;background-color:rgba(155,44,44,var(--bg-opacity))}.xl\:hover\:bg-red-900:hover{--bg-opacity:1;background-color:#742a2a;background-color:rgba(116,42,42,var(--bg-opacity))}.xl\:hover\:bg-orange-100:hover{--bg-opacity:1;background-color:#fffaf0;background-color:rgba(255,250,240,var(--bg-opacity))}.xl\:hover\:bg-orange-200:hover{--bg-opacity:1;background-color:#feebc8;background-color:rgba(254,235,200,var(--bg-opacity))}.xl\:hover\:bg-orange-300:hover{--bg-opacity:1;background-color:#fbd38d;background-color:rgba(251,211,141,var(--bg-opacity))}.xl\:hover\:bg-orange-400:hover{--bg-opacity:1;background-color:#f6ad55;background-color:rgba(246,173,85,var(--bg-opacity))}.xl\:hover\:bg-orange-500:hover{--bg-opacity:1;background-color:#ed8936;background-color:rgba(237,137,54,var(--bg-opacity))}.xl\:hover\:bg-orange-600:hover{--bg-opacity:1;background-color:#dd6b20;background-color:rgba(221,107,32,var(--bg-opacity))}.xl\:hover\:bg-orange-700:hover{--bg-opacity:1;background-color:#c05621;background-color:rgba(192,86,33,var(--bg-opacity))}.xl\:hover\:bg-orange-800:hover{--bg-opacity:1;background-color:#9c4221;background-color:rgba(156,66,33,var(--bg-opacity))}.xl\:hover\:bg-orange-900:hover{--bg-opacity:1;background-color:#7b341e;background-color:rgba(123,52,30,var(--bg-opacity))}.xl\:hover\:bg-yellow-100:hover{--bg-opacity:1;background-color:ivory;background-color:rgba(255,255,240,var(--bg-opacity))}.xl\:hover\:bg-yellow-200:hover{--bg-opacity:1;background-color:#fefcbf;background-color:rgba(254,252,191,var(--bg-opacity))}.xl\:hover\:bg-yellow-300:hover{--bg-opacity:1;background-color:#faf089;background-color:rgba(250,240,137,var(--bg-opacity))}.xl\:hover\:bg-yellow-400:hover{--bg-opacity:1;background-color:#f6e05e;background-color:rgba(246,224,94,var(--bg-opacity))}.xl\:hover\:bg-yellow-500:hover{--bg-opacity:1;background-color:#ecc94b;background-color:rgba(236,201,75,var(--bg-opacity))}.xl\:hover\:bg-yellow-600:hover{--bg-opacity:1;background-color:#d69e2e;background-color:rgba(214,158,46,var(--bg-opacity))}.xl\:hover\:bg-yellow-700:hover{--bg-opacity:1;background-color:#b7791f;background-color:rgba(183,121,31,var(--bg-opacity))}.xl\:hover\:bg-yellow-800:hover{--bg-opacity:1;background-color:#975a16;background-color:rgba(151,90,22,var(--bg-opacity))}.xl\:hover\:bg-yellow-900:hover{--bg-opacity:1;background-color:#744210;background-color:rgba(116,66,16,var(--bg-opacity))}.xl\:hover\:bg-green-100:hover{--bg-opacity:1;background-color:#f0fff4;background-color:rgba(240,255,244,var(--bg-opacity))}.xl\:hover\:bg-green-200:hover{--bg-opacity:1;background-color:#c6f6d5;background-color:rgba(198,246,213,var(--bg-opacity))}.xl\:hover\:bg-green-300:hover{--bg-opacity:1;background-color:#9ae6b4;background-color:rgba(154,230,180,var(--bg-opacity))}.xl\:hover\:bg-green-400:hover{--bg-opacity:1;background-color:#68d391;background-color:rgba(104,211,145,var(--bg-opacity))}.xl\:hover\:bg-green-500:hover{--bg-opacity:1;background-color:#48bb78;background-color:rgba(72,187,120,var(--bg-opacity))}.xl\:hover\:bg-green-600:hover{--bg-opacity:1;background-color:#38a169;background-color:rgba(56,161,105,var(--bg-opacity))}.xl\:hover\:bg-green-700:hover{--bg-opacity:1;background-color:#2f855a;background-color:rgba(47,133,90,var(--bg-opacity))}.xl\:hover\:bg-green-800:hover{--bg-opacity:1;background-color:#276749;background-color:rgba(39,103,73,var(--bg-opacity))}.xl\:hover\:bg-green-900:hover{--bg-opacity:1;background-color:#22543d;background-color:rgba(34,84,61,var(--bg-opacity))}.xl\:hover\:bg-teal-100:hover{--bg-opacity:1;background-color:#e6fffa;background-color:rgba(230,255,250,var(--bg-opacity))}.xl\:hover\:bg-teal-200:hover{--bg-opacity:1;background-color:#b2f5ea;background-color:rgba(178,245,234,var(--bg-opacity))}.xl\:hover\:bg-teal-300:hover{--bg-opacity:1;background-color:#81e6d9;background-color:rgba(129,230,217,var(--bg-opacity))}.xl\:hover\:bg-teal-400:hover{--bg-opacity:1;background-color:#4fd1c5;background-color:rgba(79,209,197,var(--bg-opacity))}.xl\:hover\:bg-teal-500:hover{--bg-opacity:1;background-color:#38b2ac;background-color:rgba(56,178,172,var(--bg-opacity))}.xl\:hover\:bg-teal-600:hover{--bg-opacity:1;background-color:#319795;background-color:rgba(49,151,149,var(--bg-opacity))}.xl\:hover\:bg-teal-700:hover{--bg-opacity:1;background-color:#2c7a7b;background-color:rgba(44,122,123,var(--bg-opacity))}.xl\:hover\:bg-teal-800:hover{--bg-opacity:1;background-color:#285e61;background-color:rgba(40,94,97,var(--bg-opacity))}.xl\:hover\:bg-teal-900:hover{--bg-opacity:1;background-color:#234e52;background-color:rgba(35,78,82,var(--bg-opacity))}.xl\:hover\:bg-blue-100:hover{--bg-opacity:1;background-color:#ebf8ff;background-color:rgba(235,248,255,var(--bg-opacity))}.xl\:hover\:bg-blue-200:hover{--bg-opacity:1;background-color:#bee3f8;background-color:rgba(190,227,248,var(--bg-opacity))}.xl\:hover\:bg-blue-300:hover{--bg-opacity:1;background-color:#90cdf4;background-color:rgba(144,205,244,var(--bg-opacity))}.xl\:hover\:bg-blue-400:hover{--bg-opacity:1;background-color:#63b3ed;background-color:rgba(99,179,237,var(--bg-opacity))}.xl\:hover\:bg-blue-500:hover{--bg-opacity:1;background-color:#4299e1;background-color:rgba(66,153,225,var(--bg-opacity))}.xl\:hover\:bg-blue-600:hover{--bg-opacity:1;background-color:#3182ce;background-color:rgba(49,130,206,var(--bg-opacity))}.xl\:hover\:bg-blue-700:hover{--bg-opacity:1;background-color:#2b6cb0;background-color:rgba(43,108,176,var(--bg-opacity))}.xl\:hover\:bg-blue-800:hover{--bg-opacity:1;background-color:#2c5282;background-color:rgba(44,82,130,var(--bg-opacity))}.xl\:hover\:bg-blue-900:hover{--bg-opacity:1;background-color:#2a4365;background-color:rgba(42,67,101,var(--bg-opacity))}.xl\:hover\:bg-indigo-100:hover{--bg-opacity:1;background-color:#ebf4ff;background-color:rgba(235,244,255,var(--bg-opacity))}.xl\:hover\:bg-indigo-200:hover{--bg-opacity:1;background-color:#c3dafe;background-color:rgba(195,218,254,var(--bg-opacity))}.xl\:hover\:bg-indigo-300:hover{--bg-opacity:1;background-color:#a3bffa;background-color:rgba(163,191,250,var(--bg-opacity))}.xl\:hover\:bg-indigo-400:hover{--bg-opacity:1;background-color:#7f9cf5;background-color:rgba(127,156,245,var(--bg-opacity))}.xl\:hover\:bg-indigo-500:hover{--bg-opacity:1;background-color:#667eea;background-color:rgba(102,126,234,var(--bg-opacity))}.xl\:hover\:bg-indigo-600:hover{--bg-opacity:1;background-color:#5a67d8;background-color:rgba(90,103,216,var(--bg-opacity))}.xl\:hover\:bg-indigo-700:hover{--bg-opacity:1;background-color:#4c51bf;background-color:rgba(76,81,191,var(--bg-opacity))}.xl\:hover\:bg-indigo-800:hover{--bg-opacity:1;background-color:#434190;background-color:rgba(67,65,144,var(--bg-opacity))}.xl\:hover\:bg-indigo-900:hover{--bg-opacity:1;background-color:#3c366b;background-color:rgba(60,54,107,var(--bg-opacity))}.xl\:hover\:bg-purple-100:hover{--bg-opacity:1;background-color:#faf5ff;background-color:rgba(250,245,255,var(--bg-opacity))}.xl\:hover\:bg-purple-200:hover{--bg-opacity:1;background-color:#e9d8fd;background-color:rgba(233,216,253,var(--bg-opacity))}.xl\:hover\:bg-purple-300:hover{--bg-opacity:1;background-color:#d6bcfa;background-color:rgba(214,188,250,var(--bg-opacity))}.xl\:hover\:bg-purple-400:hover{--bg-opacity:1;background-color:#b794f4;background-color:rgba(183,148,244,var(--bg-opacity))}.xl\:hover\:bg-purple-500:hover{--bg-opacity:1;background-color:#9f7aea;background-color:rgba(159,122,234,var(--bg-opacity))}.xl\:hover\:bg-purple-600:hover{--bg-opacity:1;background-color:#805ad5;background-color:rgba(128,90,213,var(--bg-opacity))}.xl\:hover\:bg-purple-700:hover{--bg-opacity:1;background-color:#6b46c1;background-color:rgba(107,70,193,var(--bg-opacity))}.xl\:hover\:bg-purple-800:hover{--bg-opacity:1;background-color:#553c9a;background-color:rgba(85,60,154,var(--bg-opacity))}.xl\:hover\:bg-purple-900:hover{--bg-opacity:1;background-color:#44337a;background-color:rgba(68,51,122,var(--bg-opacity))}.xl\:hover\:bg-pink-100:hover{--bg-opacity:1;background-color:#fff5f7;background-color:rgba(255,245,247,var(--bg-opacity))}.xl\:hover\:bg-pink-200:hover{--bg-opacity:1;background-color:#fed7e2;background-color:rgba(254,215,226,var(--bg-opacity))}.xl\:hover\:bg-pink-300:hover{--bg-opacity:1;background-color:#fbb6ce;background-color:rgba(251,182,206,var(--bg-opacity))}.xl\:hover\:bg-pink-400:hover{--bg-opacity:1;background-color:#f687b3;background-color:rgba(246,135,179,var(--bg-opacity))}.xl\:hover\:bg-pink-500:hover{--bg-opacity:1;background-color:#ed64a6;background-color:rgba(237,100,166,var(--bg-opacity))}.xl\:hover\:bg-pink-600:hover{--bg-opacity:1;background-color:#d53f8c;background-color:rgba(213,63,140,var(--bg-opacity))}.xl\:hover\:bg-pink-700:hover{--bg-opacity:1;background-color:#b83280;background-color:rgba(184,50,128,var(--bg-opacity))}.xl\:hover\:bg-pink-800:hover{--bg-opacity:1;background-color:#97266d;background-color:rgba(151,38,109,var(--bg-opacity))}.xl\:hover\:bg-pink-900:hover{--bg-opacity:1;background-color:#702459;background-color:rgba(112,36,89,var(--bg-opacity))}.xl\:focus\:bg-transparent:focus{background-color:transparent}.xl\:focus\:bg-current:focus{background-color:currentColor}.xl\:focus\:bg-black:focus{--bg-opacity:1;background-color:#000;background-color:rgba(0,0,0,var(--bg-opacity))}.xl\:focus\:bg-white:focus{--bg-opacity:1;background-color:#fff;background-color:rgba(255,255,255,var(--bg-opacity))}.xl\:focus\:bg-gray-100:focus{--bg-opacity:1;background-color:#f7fafc;background-color:rgba(247,250,252,var(--bg-opacity))}.xl\:focus\:bg-gray-200:focus{--bg-opacity:1;background-color:#edf2f7;background-color:rgba(237,242,247,var(--bg-opacity))}.xl\:focus\:bg-gray-300:focus{--bg-opacity:1;background-color:#e2e8f0;background-color:rgba(226,232,240,var(--bg-opacity))}.xl\:focus\:bg-gray-400:focus{--bg-opacity:1;background-color:#cbd5e0;background-color:rgba(203,213,224,var(--bg-opacity))}.xl\:focus\:bg-gray-500:focus{--bg-opacity:1;background-color:#a0aec0;background-color:rgba(160,174,192,var(--bg-opacity))}.xl\:focus\:bg-gray-600:focus{--bg-opacity:1;background-color:#718096;background-color:rgba(113,128,150,var(--bg-opacity))}.xl\:focus\:bg-gray-700:focus{--bg-opacity:1;background-color:#4a5568;background-color:rgba(74,85,104,var(--bg-opacity))}.xl\:focus\:bg-gray-800:focus{--bg-opacity:1;background-color:#2d3748;background-color:rgba(45,55,72,var(--bg-opacity))}.xl\:focus\:bg-gray-900:focus{--bg-opacity:1;background-color:#1a202c;background-color:rgba(26,32,44,var(--bg-opacity))}.xl\:focus\:bg-red-100:focus{--bg-opacity:1;background-color:#fff5f5;background-color:rgba(255,245,245,var(--bg-opacity))}.xl\:focus\:bg-red-200:focus{--bg-opacity:1;background-color:#fed7d7;background-color:rgba(254,215,215,var(--bg-opacity))}.xl\:focus\:bg-red-300:focus{--bg-opacity:1;background-color:#feb2b2;background-color:rgba(254,178,178,var(--bg-opacity))}.xl\:focus\:bg-red-400:focus{--bg-opacity:1;background-color:#fc8181;background-color:rgba(252,129,129,var(--bg-opacity))}.xl\:focus\:bg-red-500:focus{--bg-opacity:1;background-color:#f56565;background-color:rgba(245,101,101,var(--bg-opacity))}.xl\:focus\:bg-red-600:focus{--bg-opacity:1;background-color:#e53e3e;background-color:rgba(229,62,62,var(--bg-opacity))}.xl\:focus\:bg-red-700:focus{--bg-opacity:1;background-color:#c53030;background-color:rgba(197,48,48,var(--bg-opacity))}.xl\:focus\:bg-red-800:focus{--bg-opacity:1;background-color:#9b2c2c;background-color:rgba(155,44,44,var(--bg-opacity))}.xl\:focus\:bg-red-900:focus{--bg-opacity:1;background-color:#742a2a;background-color:rgba(116,42,42,var(--bg-opacity))}.xl\:focus\:bg-orange-100:focus{--bg-opacity:1;background-color:#fffaf0;background-color:rgba(255,250,240,var(--bg-opacity))}.xl\:focus\:bg-orange-200:focus{--bg-opacity:1;background-color:#feebc8;background-color:rgba(254,235,200,var(--bg-opacity))}.xl\:focus\:bg-orange-300:focus{--bg-opacity:1;background-color:#fbd38d;background-color:rgba(251,211,141,var(--bg-opacity))}.xl\:focus\:bg-orange-400:focus{--bg-opacity:1;background-color:#f6ad55;background-color:rgba(246,173,85,var(--bg-opacity))}.xl\:focus\:bg-orange-500:focus{--bg-opacity:1;background-color:#ed8936;background-color:rgba(237,137,54,var(--bg-opacity))}.xl\:focus\:bg-orange-600:focus{--bg-opacity:1;background-color:#dd6b20;background-color:rgba(221,107,32,var(--bg-opacity))}.xl\:focus\:bg-orange-700:focus{--bg-opacity:1;background-color:#c05621;background-color:rgba(192,86,33,var(--bg-opacity))}.xl\:focus\:bg-orange-800:focus{--bg-opacity:1;background-color:#9c4221;background-color:rgba(156,66,33,var(--bg-opacity))}.xl\:focus\:bg-orange-900:focus{--bg-opacity:1;background-color:#7b341e;background-color:rgba(123,52,30,var(--bg-opacity))}.xl\:focus\:bg-yellow-100:focus{--bg-opacity:1;background-color:ivory;background-color:rgba(255,255,240,var(--bg-opacity))}.xl\:focus\:bg-yellow-200:focus{--bg-opacity:1;background-color:#fefcbf;background-color:rgba(254,252,191,var(--bg-opacity))}.xl\:focus\:bg-yellow-300:focus{--bg-opacity:1;background-color:#faf089;background-color:rgba(250,240,137,var(--bg-opacity))}.xl\:focus\:bg-yellow-400:focus{--bg-opacity:1;background-color:#f6e05e;background-color:rgba(246,224,94,var(--bg-opacity))}.xl\:focus\:bg-yellow-500:focus{--bg-opacity:1;background-color:#ecc94b;background-color:rgba(236,201,75,var(--bg-opacity))}.xl\:focus\:bg-yellow-600:focus{--bg-opacity:1;background-color:#d69e2e;background-color:rgba(214,158,46,var(--bg-opacity))}.xl\:focus\:bg-yellow-700:focus{--bg-opacity:1;background-color:#b7791f;background-color:rgba(183,121,31,var(--bg-opacity))}.xl\:focus\:bg-yellow-800:focus{--bg-opacity:1;background-color:#975a16;background-color:rgba(151,90,22,var(--bg-opacity))}.xl\:focus\:bg-yellow-900:focus{--bg-opacity:1;background-color:#744210;background-color:rgba(116,66,16,var(--bg-opacity))}.xl\:focus\:bg-green-100:focus{--bg-opacity:1;background-color:#f0fff4;background-color:rgba(240,255,244,var(--bg-opacity))}.xl\:focus\:bg-green-200:focus{--bg-opacity:1;background-color:#c6f6d5;background-color:rgba(198,246,213,var(--bg-opacity))}.xl\:focus\:bg-green-300:focus{--bg-opacity:1;background-color:#9ae6b4;background-color:rgba(154,230,180,var(--bg-opacity))}.xl\:focus\:bg-green-400:focus{--bg-opacity:1;background-color:#68d391;background-color:rgba(104,211,145,var(--bg-opacity))}.xl\:focus\:bg-green-500:focus{--bg-opacity:1;background-color:#48bb78;background-color:rgba(72,187,120,var(--bg-opacity))}.xl\:focus\:bg-green-600:focus{--bg-opacity:1;background-color:#38a169;background-color:rgba(56,161,105,var(--bg-opacity))}.xl\:focus\:bg-green-700:focus{--bg-opacity:1;background-color:#2f855a;background-color:rgba(47,133,90,var(--bg-opacity))}.xl\:focus\:bg-green-800:focus{--bg-opacity:1;background-color:#276749;background-color:rgba(39,103,73,var(--bg-opacity))}.xl\:focus\:bg-green-900:focus{--bg-opacity:1;background-color:#22543d;background-color:rgba(34,84,61,var(--bg-opacity))}.xl\:focus\:bg-teal-100:focus{--bg-opacity:1;background-color:#e6fffa;background-color:rgba(230,255,250,var(--bg-opacity))}.xl\:focus\:bg-teal-200:focus{--bg-opacity:1;background-color:#b2f5ea;background-color:rgba(178,245,234,var(--bg-opacity))}.xl\:focus\:bg-teal-300:focus{--bg-opacity:1;background-color:#81e6d9;background-color:rgba(129,230,217,var(--bg-opacity))}.xl\:focus\:bg-teal-400:focus{--bg-opacity:1;background-color:#4fd1c5;background-color:rgba(79,209,197,var(--bg-opacity))}.xl\:focus\:bg-teal-500:focus{--bg-opacity:1;background-color:#38b2ac;background-color:rgba(56,178,172,var(--bg-opacity))}.xl\:focus\:bg-teal-600:focus{--bg-opacity:1;background-color:#319795;background-color:rgba(49,151,149,var(--bg-opacity))}.xl\:focus\:bg-teal-700:focus{--bg-opacity:1;background-color:#2c7a7b;background-color:rgba(44,122,123,var(--bg-opacity))}.xl\:focus\:bg-teal-800:focus{--bg-opacity:1;background-color:#285e61;background-color:rgba(40,94,97,var(--bg-opacity))}.xl\:focus\:bg-teal-900:focus{--bg-opacity:1;background-color:#234e52;background-color:rgba(35,78,82,var(--bg-opacity))}.xl\:focus\:bg-blue-100:focus{--bg-opacity:1;background-color:#ebf8ff;background-color:rgba(235,248,255,var(--bg-opacity))}.xl\:focus\:bg-blue-200:focus{--bg-opacity:1;background-color:#bee3f8;background-color:rgba(190,227,248,var(--bg-opacity))}.xl\:focus\:bg-blue-300:focus{--bg-opacity:1;background-color:#90cdf4;background-color:rgba(144,205,244,var(--bg-opacity))}.xl\:focus\:bg-blue-400:focus{--bg-opacity:1;background-color:#63b3ed;background-color:rgba(99,179,237,var(--bg-opacity))}.xl\:focus\:bg-blue-500:focus{--bg-opacity:1;background-color:#4299e1;background-color:rgba(66,153,225,var(--bg-opacity))}.xl\:focus\:bg-blue-600:focus{--bg-opacity:1;background-color:#3182ce;background-color:rgba(49,130,206,var(--bg-opacity))}.xl\:focus\:bg-blue-700:focus{--bg-opacity:1;background-color:#2b6cb0;background-color:rgba(43,108,176,var(--bg-opacity))}.xl\:focus\:bg-blue-800:focus{--bg-opacity:1;background-color:#2c5282;background-color:rgba(44,82,130,var(--bg-opacity))}.xl\:focus\:bg-blue-900:focus{--bg-opacity:1;background-color:#2a4365;background-color:rgba(42,67,101,var(--bg-opacity))}.xl\:focus\:bg-indigo-100:focus{--bg-opacity:1;background-color:#ebf4ff;background-color:rgba(235,244,255,var(--bg-opacity))}.xl\:focus\:bg-indigo-200:focus{--bg-opacity:1;background-color:#c3dafe;background-color:rgba(195,218,254,var(--bg-opacity))}.xl\:focus\:bg-indigo-300:focus{--bg-opacity:1;background-color:#a3bffa;background-color:rgba(163,191,250,var(--bg-opacity))}.xl\:focus\:bg-indigo-400:focus{--bg-opacity:1;background-color:#7f9cf5;background-color:rgba(127,156,245,var(--bg-opacity))}.xl\:focus\:bg-indigo-500:focus{--bg-opacity:1;background-color:#667eea;background-color:rgba(102,126,234,var(--bg-opacity))}.xl\:focus\:bg-indigo-600:focus{--bg-opacity:1;background-color:#5a67d8;background-color:rgba(90,103,216,var(--bg-opacity))}.xl\:focus\:bg-indigo-700:focus{--bg-opacity:1;background-color:#4c51bf;background-color:rgba(76,81,191,var(--bg-opacity))}.xl\:focus\:bg-indigo-800:focus{--bg-opacity:1;background-color:#434190;background-color:rgba(67,65,144,var(--bg-opacity))}.xl\:focus\:bg-indigo-900:focus{--bg-opacity:1;background-color:#3c366b;background-color:rgba(60,54,107,var(--bg-opacity))}.xl\:focus\:bg-purple-100:focus{--bg-opacity:1;background-color:#faf5ff;background-color:rgba(250,245,255,var(--bg-opacity))}.xl\:focus\:bg-purple-200:focus{--bg-opacity:1;background-color:#e9d8fd;background-color:rgba(233,216,253,var(--bg-opacity))}.xl\:focus\:bg-purple-300:focus{--bg-opacity:1;background-color:#d6bcfa;background-color:rgba(214,188,250,var(--bg-opacity))}.xl\:focus\:bg-purple-400:focus{--bg-opacity:1;background-color:#b794f4;background-color:rgba(183,148,244,var(--bg-opacity))}.xl\:focus\:bg-purple-500:focus{--bg-opacity:1;background-color:#9f7aea;background-color:rgba(159,122,234,var(--bg-opacity))}.xl\:focus\:bg-purple-600:focus{--bg-opacity:1;background-color:#805ad5;background-color:rgba(128,90,213,var(--bg-opacity))}.xl\:focus\:bg-purple-700:focus{--bg-opacity:1;background-color:#6b46c1;background-color:rgba(107,70,193,var(--bg-opacity))}.xl\:focus\:bg-purple-800:focus{--bg-opacity:1;background-color:#553c9a;background-color:rgba(85,60,154,var(--bg-opacity))}.xl\:focus\:bg-purple-900:focus{--bg-opacity:1;background-color:#44337a;background-color:rgba(68,51,122,var(--bg-opacity))}.xl\:focus\:bg-pink-100:focus{--bg-opacity:1;background-color:#fff5f7;background-color:rgba(255,245,247,var(--bg-opacity))}.xl\:focus\:bg-pink-200:focus{--bg-opacity:1;background-color:#fed7e2;background-color:rgba(254,215,226,var(--bg-opacity))}.xl\:focus\:bg-pink-300:focus{--bg-opacity:1;background-color:#fbb6ce;background-color:rgba(251,182,206,var(--bg-opacity))}.xl\:focus\:bg-pink-400:focus{--bg-opacity:1;background-color:#f687b3;background-color:rgba(246,135,179,var(--bg-opacity))}.xl\:focus\:bg-pink-500:focus{--bg-opacity:1;background-color:#ed64a6;background-color:rgba(237,100,166,var(--bg-opacity))}.xl\:focus\:bg-pink-600:focus{--bg-opacity:1;background-color:#d53f8c;background-color:rgba(213,63,140,var(--bg-opacity))}.xl\:focus\:bg-pink-700:focus{--bg-opacity:1;background-color:#b83280;background-color:rgba(184,50,128,var(--bg-opacity))}.xl\:focus\:bg-pink-800:focus{--bg-opacity:1;background-color:#97266d;background-color:rgba(151,38,109,var(--bg-opacity))}.xl\:focus\:bg-pink-900:focus{--bg-opacity:1;background-color:#702459;background-color:rgba(112,36,89,var(--bg-opacity))}.xl\:bg-none{background-image:none}.xl\:bg-gradient-to-t{background-image:linear-gradient(to top,var(--gradient-color-stops))}.xl\:bg-gradient-to-tr{background-image:linear-gradient(to top right,var(--gradient-color-stops))}.xl\:bg-gradient-to-r{background-image:linear-gradient(to right,var(--gradient-color-stops))}.xl\:bg-gradient-to-br{background-image:linear-gradient(to bottom right,var(--gradient-color-stops))}.xl\:bg-gradient-to-b{background-image:linear-gradient(to bottom,var(--gradient-color-stops))}.xl\:bg-gradient-to-bl{background-image:linear-gradient(to bottom left,var(--gradient-color-stops))}.xl\:bg-gradient-to-l{background-image:linear-gradient(to left,var(--gradient-color-stops))}.xl\:bg-gradient-to-tl{background-image:linear-gradient(to top left,var(--gradient-color-stops))}.xl\:from-transparent{--gradient-from-color:transparent;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(0, 0, 0, 0))}.xl\:from-current{--gradient-from-color:currentColor;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 255, 255, 0))}.xl\:from-black{--gradient-from-color:#000;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(0, 0, 0, 0))}.xl\:from-white{--gradient-from-color:#fff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 255, 255, 0))}.xl\:from-gray-100{--gradient-from-color:#f7fafc;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(247, 250, 252, 0))}.xl\:from-gray-200{--gradient-from-color:#edf2f7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(237, 242, 247, 0))}.xl\:from-gray-300{--gradient-from-color:#e2e8f0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(226, 232, 240, 0))}.xl\:from-gray-400{--gradient-from-color:#cbd5e0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(203, 213, 224, 0))}.xl\:from-gray-500{--gradient-from-color:#a0aec0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(160, 174, 192, 0))}.xl\:from-gray-600{--gradient-from-color:#718096;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(113, 128, 150, 0))}.xl\:from-gray-700{--gradient-from-color:#4a5568;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(74, 85, 104, 0))}.xl\:from-gray-800{--gradient-from-color:#2d3748;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(45, 55, 72, 0))}.xl\:from-gray-900{--gradient-from-color:#1a202c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(26, 32, 44, 0))}.xl\:from-red-100{--gradient-from-color:#fff5f5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 245, 245, 0))}.xl\:from-red-200{--gradient-from-color:#fed7d7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(254, 215, 215, 0))}.xl\:from-red-300{--gradient-from-color:#feb2b2;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(254, 178, 178, 0))}.xl\:from-red-400{--gradient-from-color:#fc8181;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(252, 129, 129, 0))}.xl\:from-red-500{--gradient-from-color:#f56565;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(245, 101, 101, 0))}.xl\:from-red-600{--gradient-from-color:#e53e3e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(229, 62, 62, 0))}.xl\:from-red-700{--gradient-from-color:#c53030;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(197, 48, 48, 0))}.xl\:from-red-800{--gradient-from-color:#9b2c2c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(155, 44, 44, 0))}.xl\:from-red-900{--gradient-from-color:#742a2a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(116, 42, 42, 0))}.xl\:from-orange-100{--gradient-from-color:#fffaf0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 250, 240, 0))}.xl\:from-orange-200{--gradient-from-color:#feebc8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(254, 235, 200, 0))}.xl\:from-orange-300{--gradient-from-color:#fbd38d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(251, 211, 141, 0))}.xl\:from-orange-400{--gradient-from-color:#f6ad55;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(246, 173, 85, 0))}.xl\:from-orange-500{--gradient-from-color:#ed8936;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(237, 137, 54, 0))}.xl\:from-orange-600{--gradient-from-color:#dd6b20;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(221, 107, 32, 0))}.xl\:from-orange-700{--gradient-from-color:#c05621;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(192, 86, 33, 0))}.xl\:from-orange-800{--gradient-from-color:#9c4221;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(156, 66, 33, 0))}.xl\:from-orange-900{--gradient-from-color:#7b341e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(123, 52, 30, 0))}.xl\:from-yellow-100{--gradient-from-color:#fffff0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 255, 240, 0))}.xl\:from-yellow-200{--gradient-from-color:#fefcbf;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(254, 252, 191, 0))}.xl\:from-yellow-300{--gradient-from-color:#faf089;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(250, 240, 137, 0))}.xl\:from-yellow-400{--gradient-from-color:#f6e05e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(246, 224, 94, 0))}.xl\:from-yellow-500{--gradient-from-color:#ecc94b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(236, 201, 75, 0))}.xl\:from-yellow-600{--gradient-from-color:#d69e2e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(214, 158, 46, 0))}.xl\:from-yellow-700{--gradient-from-color:#b7791f;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(183, 121, 31, 0))}.xl\:from-yellow-800{--gradient-from-color:#975a16;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(151, 90, 22, 0))}.xl\:from-yellow-900{--gradient-from-color:#744210;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(116, 66, 16, 0))}.xl\:from-green-100{--gradient-from-color:#f0fff4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(240, 255, 244, 0))}.xl\:from-green-200{--gradient-from-color:#c6f6d5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(198, 246, 213, 0))}.xl\:from-green-300{--gradient-from-color:#9ae6b4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(154, 230, 180, 0))}.xl\:from-green-400{--gradient-from-color:#68d391;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(104, 211, 145, 0))}.xl\:from-green-500{--gradient-from-color:#48bb78;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(72, 187, 120, 0))}.xl\:from-green-600{--gradient-from-color:#38a169;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(56, 161, 105, 0))}.xl\:from-green-700{--gradient-from-color:#2f855a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(47, 133, 90, 0))}.xl\:from-green-800{--gradient-from-color:#276749;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(39, 103, 73, 0))}.xl\:from-green-900{--gradient-from-color:#22543d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(34, 84, 61, 0))}.xl\:from-teal-100{--gradient-from-color:#e6fffa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(230, 255, 250, 0))}.xl\:from-teal-200{--gradient-from-color:#b2f5ea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(178, 245, 234, 0))}.xl\:from-teal-300{--gradient-from-color:#81e6d9;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(129, 230, 217, 0))}.xl\:from-teal-400{--gradient-from-color:#4fd1c5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(79, 209, 197, 0))}.xl\:from-teal-500{--gradient-from-color:#38b2ac;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(56, 178, 172, 0))}.xl\:from-teal-600{--gradient-from-color:#319795;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(49, 151, 149, 0))}.xl\:from-teal-700{--gradient-from-color:#2c7a7b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(44, 122, 123, 0))}.xl\:from-teal-800{--gradient-from-color:#285e61;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(40, 94, 97, 0))}.xl\:from-teal-900{--gradient-from-color:#234e52;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(35, 78, 82, 0))}.xl\:from-blue-100{--gradient-from-color:#ebf8ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(235, 248, 255, 0))}.xl\:from-blue-200{--gradient-from-color:#bee3f8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(190, 227, 248, 0))}.xl\:from-blue-300{--gradient-from-color:#90cdf4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(144, 205, 244, 0))}.xl\:from-blue-400{--gradient-from-color:#63b3ed;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(99, 179, 237, 0))}.xl\:from-blue-500{--gradient-from-color:#4299e1;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(66, 153, 225, 0))}.xl\:from-blue-600{--gradient-from-color:#3182ce;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(49, 130, 206, 0))}.xl\:from-blue-700{--gradient-from-color:#2b6cb0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(43, 108, 176, 0))}.xl\:from-blue-800{--gradient-from-color:#2c5282;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(44, 82, 130, 0))}.xl\:from-blue-900{--gradient-from-color:#2a4365;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(42, 67, 101, 0))}.xl\:from-indigo-100{--gradient-from-color:#ebf4ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(235, 244, 255, 0))}.xl\:from-indigo-200{--gradient-from-color:#c3dafe;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(195, 218, 254, 0))}.xl\:from-indigo-300{--gradient-from-color:#a3bffa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(163, 191, 250, 0))}.xl\:from-indigo-400{--gradient-from-color:#7f9cf5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(127, 156, 245, 0))}.xl\:from-indigo-500{--gradient-from-color:#667eea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(102, 126, 234, 0))}.xl\:from-indigo-600{--gradient-from-color:#5a67d8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(90, 103, 216, 0))}.xl\:from-indigo-700{--gradient-from-color:#4c51bf;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(76, 81, 191, 0))}.xl\:from-indigo-800{--gradient-from-color:#434190;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(67, 65, 144, 0))}.xl\:from-indigo-900{--gradient-from-color:#3c366b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(60, 54, 107, 0))}.xl\:from-purple-100{--gradient-from-color:#faf5ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(250, 245, 255, 0))}.xl\:from-purple-200{--gradient-from-color:#e9d8fd;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(233, 216, 253, 0))}.xl\:from-purple-300{--gradient-from-color:#d6bcfa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(214, 188, 250, 0))}.xl\:from-purple-400{--gradient-from-color:#b794f4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(183, 148, 244, 0))}.xl\:from-purple-500{--gradient-from-color:#9f7aea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(159, 122, 234, 0))}.xl\:from-purple-600{--gradient-from-color:#805ad5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(128, 90, 213, 0))}.xl\:from-purple-700{--gradient-from-color:#6b46c1;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(107, 70, 193, 0))}.xl\:from-purple-800{--gradient-from-color:#553c9a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(85, 60, 154, 0))}.xl\:from-purple-900{--gradient-from-color:#44337a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(68, 51, 122, 0))}.xl\:from-pink-100{--gradient-from-color:#fff5f7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 245, 247, 0))}.xl\:from-pink-200{--gradient-from-color:#fed7e2;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(254, 215, 226, 0))}.xl\:from-pink-300{--gradient-from-color:#fbb6ce;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(251, 182, 206, 0))}.xl\:from-pink-400{--gradient-from-color:#f687b3;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(246, 135, 179, 0))}.xl\:from-pink-500{--gradient-from-color:#ed64a6;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(237, 100, 166, 0))}.xl\:from-pink-600{--gradient-from-color:#d53f8c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(213, 63, 140, 0))}.xl\:from-pink-700{--gradient-from-color:#b83280;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(184, 50, 128, 0))}.xl\:from-pink-800{--gradient-from-color:#97266d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(151, 38, 109, 0))}.xl\:from-pink-900{--gradient-from-color:#702459;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(112, 36, 89, 0))}.xl\:via-transparent{--gradient-via-color:transparent;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(0, 0, 0, 0))}.xl\:via-current{--gradient-via-color:currentColor;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 255, 255, 0))}.xl\:via-black{--gradient-via-color:#000;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(0, 0, 0, 0))}.xl\:via-white{--gradient-via-color:#fff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 255, 255, 0))}.xl\:via-gray-100{--gradient-via-color:#f7fafc;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(247, 250, 252, 0))}.xl\:via-gray-200{--gradient-via-color:#edf2f7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(237, 242, 247, 0))}.xl\:via-gray-300{--gradient-via-color:#e2e8f0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(226, 232, 240, 0))}.xl\:via-gray-400{--gradient-via-color:#cbd5e0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(203, 213, 224, 0))}.xl\:via-gray-500{--gradient-via-color:#a0aec0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(160, 174, 192, 0))}.xl\:via-gray-600{--gradient-via-color:#718096;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(113, 128, 150, 0))}.xl\:via-gray-700{--gradient-via-color:#4a5568;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(74, 85, 104, 0))}.xl\:via-gray-800{--gradient-via-color:#2d3748;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(45, 55, 72, 0))}.xl\:via-gray-900{--gradient-via-color:#1a202c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(26, 32, 44, 0))}.xl\:via-red-100{--gradient-via-color:#fff5f5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 245, 245, 0))}.xl\:via-red-200{--gradient-via-color:#fed7d7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(254, 215, 215, 0))}.xl\:via-red-300{--gradient-via-color:#feb2b2;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(254, 178, 178, 0))}.xl\:via-red-400{--gradient-via-color:#fc8181;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(252, 129, 129, 0))}.xl\:via-red-500{--gradient-via-color:#f56565;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(245, 101, 101, 0))}.xl\:via-red-600{--gradient-via-color:#e53e3e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(229, 62, 62, 0))}.xl\:via-red-700{--gradient-via-color:#c53030;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(197, 48, 48, 0))}.xl\:via-red-800{--gradient-via-color:#9b2c2c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(155, 44, 44, 0))}.xl\:via-red-900{--gradient-via-color:#742a2a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(116, 42, 42, 0))}.xl\:via-orange-100{--gradient-via-color:#fffaf0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 250, 240, 0))}.xl\:via-orange-200{--gradient-via-color:#feebc8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(254, 235, 200, 0))}.xl\:via-orange-300{--gradient-via-color:#fbd38d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(251, 211, 141, 0))}.xl\:via-orange-400{--gradient-via-color:#f6ad55;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(246, 173, 85, 0))}.xl\:via-orange-500{--gradient-via-color:#ed8936;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(237, 137, 54, 0))}.xl\:via-orange-600{--gradient-via-color:#dd6b20;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(221, 107, 32, 0))}.xl\:via-orange-700{--gradient-via-color:#c05621;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(192, 86, 33, 0))}.xl\:via-orange-800{--gradient-via-color:#9c4221;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(156, 66, 33, 0))}.xl\:via-orange-900{--gradient-via-color:#7b341e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(123, 52, 30, 0))}.xl\:via-yellow-100{--gradient-via-color:#fffff0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 255, 240, 0))}.xl\:via-yellow-200{--gradient-via-color:#fefcbf;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(254, 252, 191, 0))}.xl\:via-yellow-300{--gradient-via-color:#faf089;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(250, 240, 137, 0))}.xl\:via-yellow-400{--gradient-via-color:#f6e05e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(246, 224, 94, 0))}.xl\:via-yellow-500{--gradient-via-color:#ecc94b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(236, 201, 75, 0))}.xl\:via-yellow-600{--gradient-via-color:#d69e2e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(214, 158, 46, 0))}.xl\:via-yellow-700{--gradient-via-color:#b7791f;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(183, 121, 31, 0))}.xl\:via-yellow-800{--gradient-via-color:#975a16;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(151, 90, 22, 0))}.xl\:via-yellow-900{--gradient-via-color:#744210;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(116, 66, 16, 0))}.xl\:via-green-100{--gradient-via-color:#f0fff4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(240, 255, 244, 0))}.xl\:via-green-200{--gradient-via-color:#c6f6d5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(198, 246, 213, 0))}.xl\:via-green-300{--gradient-via-color:#9ae6b4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(154, 230, 180, 0))}.xl\:via-green-400{--gradient-via-color:#68d391;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(104, 211, 145, 0))}.xl\:via-green-500{--gradient-via-color:#48bb78;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(72, 187, 120, 0))}.xl\:via-green-600{--gradient-via-color:#38a169;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(56, 161, 105, 0))}.xl\:via-green-700{--gradient-via-color:#2f855a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(47, 133, 90, 0))}.xl\:via-green-800{--gradient-via-color:#276749;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(39, 103, 73, 0))}.xl\:via-green-900{--gradient-via-color:#22543d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(34, 84, 61, 0))}.xl\:via-teal-100{--gradient-via-color:#e6fffa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(230, 255, 250, 0))}.xl\:via-teal-200{--gradient-via-color:#b2f5ea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(178, 245, 234, 0))}.xl\:via-teal-300{--gradient-via-color:#81e6d9;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(129, 230, 217, 0))}.xl\:via-teal-400{--gradient-via-color:#4fd1c5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(79, 209, 197, 0))}.xl\:via-teal-500{--gradient-via-color:#38b2ac;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(56, 178, 172, 0))}.xl\:via-teal-600{--gradient-via-color:#319795;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(49, 151, 149, 0))}.xl\:via-teal-700{--gradient-via-color:#2c7a7b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(44, 122, 123, 0))}.xl\:via-teal-800{--gradient-via-color:#285e61;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(40, 94, 97, 0))}.xl\:via-teal-900{--gradient-via-color:#234e52;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(35, 78, 82, 0))}.xl\:via-blue-100{--gradient-via-color:#ebf8ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(235, 248, 255, 0))}.xl\:via-blue-200{--gradient-via-color:#bee3f8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(190, 227, 248, 0))}.xl\:via-blue-300{--gradient-via-color:#90cdf4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(144, 205, 244, 0))}.xl\:via-blue-400{--gradient-via-color:#63b3ed;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(99, 179, 237, 0))}.xl\:via-blue-500{--gradient-via-color:#4299e1;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(66, 153, 225, 0))}.xl\:via-blue-600{--gradient-via-color:#3182ce;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(49, 130, 206, 0))}.xl\:via-blue-700{--gradient-via-color:#2b6cb0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(43, 108, 176, 0))}.xl\:via-blue-800{--gradient-via-color:#2c5282;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(44, 82, 130, 0))}.xl\:via-blue-900{--gradient-via-color:#2a4365;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(42, 67, 101, 0))}.xl\:via-indigo-100{--gradient-via-color:#ebf4ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(235, 244, 255, 0))}.xl\:via-indigo-200{--gradient-via-color:#c3dafe;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(195, 218, 254, 0))}.xl\:via-indigo-300{--gradient-via-color:#a3bffa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(163, 191, 250, 0))}.xl\:via-indigo-400{--gradient-via-color:#7f9cf5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(127, 156, 245, 0))}.xl\:via-indigo-500{--gradient-via-color:#667eea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(102, 126, 234, 0))}.xl\:via-indigo-600{--gradient-via-color:#5a67d8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(90, 103, 216, 0))}.xl\:via-indigo-700{--gradient-via-color:#4c51bf;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(76, 81, 191, 0))}.xl\:via-indigo-800{--gradient-via-color:#434190;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(67, 65, 144, 0))}.xl\:via-indigo-900{--gradient-via-color:#3c366b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(60, 54, 107, 0))}.xl\:via-purple-100{--gradient-via-color:#faf5ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(250, 245, 255, 0))}.xl\:via-purple-200{--gradient-via-color:#e9d8fd;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(233, 216, 253, 0))}.xl\:via-purple-300{--gradient-via-color:#d6bcfa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(214, 188, 250, 0))}.xl\:via-purple-400{--gradient-via-color:#b794f4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(183, 148, 244, 0))}.xl\:via-purple-500{--gradient-via-color:#9f7aea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(159, 122, 234, 0))}.xl\:via-purple-600{--gradient-via-color:#805ad5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(128, 90, 213, 0))}.xl\:via-purple-700{--gradient-via-color:#6b46c1;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(107, 70, 193, 0))}.xl\:via-purple-800{--gradient-via-color:#553c9a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(85, 60, 154, 0))}.xl\:via-purple-900{--gradient-via-color:#44337a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(68, 51, 122, 0))}.xl\:via-pink-100{--gradient-via-color:#fff5f7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 245, 247, 0))}.xl\:via-pink-200{--gradient-via-color:#fed7e2;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(254, 215, 226, 0))}.xl\:via-pink-300{--gradient-via-color:#fbb6ce;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(251, 182, 206, 0))}.xl\:via-pink-400{--gradient-via-color:#f687b3;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(246, 135, 179, 0))}.xl\:via-pink-500{--gradient-via-color:#ed64a6;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(237, 100, 166, 0))}.xl\:via-pink-600{--gradient-via-color:#d53f8c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(213, 63, 140, 0))}.xl\:via-pink-700{--gradient-via-color:#b83280;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(184, 50, 128, 0))}.xl\:via-pink-800{--gradient-via-color:#97266d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(151, 38, 109, 0))}.xl\:via-pink-900{--gradient-via-color:#702459;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(112, 36, 89, 0))}.xl\:to-transparent{--gradient-to-color:transparent}.xl\:to-current{--gradient-to-color:currentColor}.xl\:to-black{--gradient-to-color:#000}.xl\:to-white{--gradient-to-color:#fff}.xl\:to-gray-100{--gradient-to-color:#f7fafc}.xl\:to-gray-200{--gradient-to-color:#edf2f7}.xl\:to-gray-300{--gradient-to-color:#e2e8f0}.xl\:to-gray-400{--gradient-to-color:#cbd5e0}.xl\:to-gray-500{--gradient-to-color:#a0aec0}.xl\:to-gray-600{--gradient-to-color:#718096}.xl\:to-gray-700{--gradient-to-color:#4a5568}.xl\:to-gray-800{--gradient-to-color:#2d3748}.xl\:to-gray-900{--gradient-to-color:#1a202c}.xl\:to-red-100{--gradient-to-color:#fff5f5}.xl\:to-red-200{--gradient-to-color:#fed7d7}.xl\:to-red-300{--gradient-to-color:#feb2b2}.xl\:to-red-400{--gradient-to-color:#fc8181}.xl\:to-red-500{--gradient-to-color:#f56565}.xl\:to-red-600{--gradient-to-color:#e53e3e}.xl\:to-red-700{--gradient-to-color:#c53030}.xl\:to-red-800{--gradient-to-color:#9b2c2c}.xl\:to-red-900{--gradient-to-color:#742a2a}.xl\:to-orange-100{--gradient-to-color:#fffaf0}.xl\:to-orange-200{--gradient-to-color:#feebc8}.xl\:to-orange-300{--gradient-to-color:#fbd38d}.xl\:to-orange-400{--gradient-to-color:#f6ad55}.xl\:to-orange-500{--gradient-to-color:#ed8936}.xl\:to-orange-600{--gradient-to-color:#dd6b20}.xl\:to-orange-700{--gradient-to-color:#c05621}.xl\:to-orange-800{--gradient-to-color:#9c4221}.xl\:to-orange-900{--gradient-to-color:#7b341e}.xl\:to-yellow-100{--gradient-to-color:#fffff0}.xl\:to-yellow-200{--gradient-to-color:#fefcbf}.xl\:to-yellow-300{--gradient-to-color:#faf089}.xl\:to-yellow-400{--gradient-to-color:#f6e05e}.xl\:to-yellow-500{--gradient-to-color:#ecc94b}.xl\:to-yellow-600{--gradient-to-color:#d69e2e}.xl\:to-yellow-700{--gradient-to-color:#b7791f}.xl\:to-yellow-800{--gradient-to-color:#975a16}.xl\:to-yellow-900{--gradient-to-color:#744210}.xl\:to-green-100{--gradient-to-color:#f0fff4}.xl\:to-green-200{--gradient-to-color:#c6f6d5}.xl\:to-green-300{--gradient-to-color:#9ae6b4}.xl\:to-green-400{--gradient-to-color:#68d391}.xl\:to-green-500{--gradient-to-color:#48bb78}.xl\:to-green-600{--gradient-to-color:#38a169}.xl\:to-green-700{--gradient-to-color:#2f855a}.xl\:to-green-800{--gradient-to-color:#276749}.xl\:to-green-900{--gradient-to-color:#22543d}.xl\:to-teal-100{--gradient-to-color:#e6fffa}.xl\:to-teal-200{--gradient-to-color:#b2f5ea}.xl\:to-teal-300{--gradient-to-color:#81e6d9}.xl\:to-teal-400{--gradient-to-color:#4fd1c5}.xl\:to-teal-500{--gradient-to-color:#38b2ac}.xl\:to-teal-600{--gradient-to-color:#319795}.xl\:to-teal-700{--gradient-to-color:#2c7a7b}.xl\:to-teal-800{--gradient-to-color:#285e61}.xl\:to-teal-900{--gradient-to-color:#234e52}.xl\:to-blue-100{--gradient-to-color:#ebf8ff}.xl\:to-blue-200{--gradient-to-color:#bee3f8}.xl\:to-blue-300{--gradient-to-color:#90cdf4}.xl\:to-blue-400{--gradient-to-color:#63b3ed}.xl\:to-blue-500{--gradient-to-color:#4299e1}.xl\:to-blue-600{--gradient-to-color:#3182ce}.xl\:to-blue-700{--gradient-to-color:#2b6cb0}.xl\:to-blue-800{--gradient-to-color:#2c5282}.xl\:to-blue-900{--gradient-to-color:#2a4365}.xl\:to-indigo-100{--gradient-to-color:#ebf4ff}.xl\:to-indigo-200{--gradient-to-color:#c3dafe}.xl\:to-indigo-300{--gradient-to-color:#a3bffa}.xl\:to-indigo-400{--gradient-to-color:#7f9cf5}.xl\:to-indigo-500{--gradient-to-color:#667eea}.xl\:to-indigo-600{--gradient-to-color:#5a67d8}.xl\:to-indigo-700{--gradient-to-color:#4c51bf}.xl\:to-indigo-800{--gradient-to-color:#434190}.xl\:to-indigo-900{--gradient-to-color:#3c366b}.xl\:to-purple-100{--gradient-to-color:#faf5ff}.xl\:to-purple-200{--gradient-to-color:#e9d8fd}.xl\:to-purple-300{--gradient-to-color:#d6bcfa}.xl\:to-purple-400{--gradient-to-color:#b794f4}.xl\:to-purple-500{--gradient-to-color:#9f7aea}.xl\:to-purple-600{--gradient-to-color:#805ad5}.xl\:to-purple-700{--gradient-to-color:#6b46c1}.xl\:to-purple-800{--gradient-to-color:#553c9a}.xl\:to-purple-900{--gradient-to-color:#44337a}.xl\:to-pink-100{--gradient-to-color:#fff5f7}.xl\:to-pink-200{--gradient-to-color:#fed7e2}.xl\:to-pink-300{--gradient-to-color:#fbb6ce}.xl\:to-pink-400{--gradient-to-color:#f687b3}.xl\:to-pink-500{--gradient-to-color:#ed64a6}.xl\:to-pink-600{--gradient-to-color:#d53f8c}.xl\:to-pink-700{--gradient-to-color:#b83280}.xl\:to-pink-800{--gradient-to-color:#97266d}.xl\:to-pink-900{--gradient-to-color:#702459}.xl\:hover\:from-transparent:hover{--gradient-from-color:transparent;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(0, 0, 0, 0))}.xl\:hover\:from-current:hover{--gradient-from-color:currentColor;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 255, 255, 0))}.xl\:hover\:from-black:hover{--gradient-from-color:#000;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(0, 0, 0, 0))}.xl\:hover\:from-white:hover{--gradient-from-color:#fff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 255, 255, 0))}.xl\:hover\:from-gray-100:hover{--gradient-from-color:#f7fafc;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(247, 250, 252, 0))}.xl\:hover\:from-gray-200:hover{--gradient-from-color:#edf2f7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(237, 242, 247, 0))}.xl\:hover\:from-gray-300:hover{--gradient-from-color:#e2e8f0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(226, 232, 240, 0))}.xl\:hover\:from-gray-400:hover{--gradient-from-color:#cbd5e0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(203, 213, 224, 0))}.xl\:hover\:from-gray-500:hover{--gradient-from-color:#a0aec0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(160, 174, 192, 0))}.xl\:hover\:from-gray-600:hover{--gradient-from-color:#718096;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(113, 128, 150, 0))}.xl\:hover\:from-gray-700:hover{--gradient-from-color:#4a5568;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(74, 85, 104, 0))}.xl\:hover\:from-gray-800:hover{--gradient-from-color:#2d3748;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(45, 55, 72, 0))}.xl\:hover\:from-gray-900:hover{--gradient-from-color:#1a202c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(26, 32, 44, 0))}.xl\:hover\:from-red-100:hover{--gradient-from-color:#fff5f5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 245, 245, 0))}.xl\:hover\:from-red-200:hover{--gradient-from-color:#fed7d7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(254, 215, 215, 0))}.xl\:hover\:from-red-300:hover{--gradient-from-color:#feb2b2;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(254, 178, 178, 0))}.xl\:hover\:from-red-400:hover{--gradient-from-color:#fc8181;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(252, 129, 129, 0))}.xl\:hover\:from-red-500:hover{--gradient-from-color:#f56565;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(245, 101, 101, 0))}.xl\:hover\:from-red-600:hover{--gradient-from-color:#e53e3e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(229, 62, 62, 0))}.xl\:hover\:from-red-700:hover{--gradient-from-color:#c53030;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(197, 48, 48, 0))}.xl\:hover\:from-red-800:hover{--gradient-from-color:#9b2c2c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(155, 44, 44, 0))}.xl\:hover\:from-red-900:hover{--gradient-from-color:#742a2a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(116, 42, 42, 0))}.xl\:hover\:from-orange-100:hover{--gradient-from-color:#fffaf0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 250, 240, 0))}.xl\:hover\:from-orange-200:hover{--gradient-from-color:#feebc8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(254, 235, 200, 0))}.xl\:hover\:from-orange-300:hover{--gradient-from-color:#fbd38d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(251, 211, 141, 0))}.xl\:hover\:from-orange-400:hover{--gradient-from-color:#f6ad55;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(246, 173, 85, 0))}.xl\:hover\:from-orange-500:hover{--gradient-from-color:#ed8936;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(237, 137, 54, 0))}.xl\:hover\:from-orange-600:hover{--gradient-from-color:#dd6b20;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(221, 107, 32, 0))}.xl\:hover\:from-orange-700:hover{--gradient-from-color:#c05621;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(192, 86, 33, 0))}.xl\:hover\:from-orange-800:hover{--gradient-from-color:#9c4221;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(156, 66, 33, 0))}.xl\:hover\:from-orange-900:hover{--gradient-from-color:#7b341e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(123, 52, 30, 0))}.xl\:hover\:from-yellow-100:hover{--gradient-from-color:#fffff0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 255, 240, 0))}.xl\:hover\:from-yellow-200:hover{--gradient-from-color:#fefcbf;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(254, 252, 191, 0))}.xl\:hover\:from-yellow-300:hover{--gradient-from-color:#faf089;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(250, 240, 137, 0))}.xl\:hover\:from-yellow-400:hover{--gradient-from-color:#f6e05e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(246, 224, 94, 0))}.xl\:hover\:from-yellow-500:hover{--gradient-from-color:#ecc94b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(236, 201, 75, 0))}.xl\:hover\:from-yellow-600:hover{--gradient-from-color:#d69e2e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(214, 158, 46, 0))}.xl\:hover\:from-yellow-700:hover{--gradient-from-color:#b7791f;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(183, 121, 31, 0))}.xl\:hover\:from-yellow-800:hover{--gradient-from-color:#975a16;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(151, 90, 22, 0))}.xl\:hover\:from-yellow-900:hover{--gradient-from-color:#744210;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(116, 66, 16, 0))}.xl\:hover\:from-green-100:hover{--gradient-from-color:#f0fff4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(240, 255, 244, 0))}.xl\:hover\:from-green-200:hover{--gradient-from-color:#c6f6d5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(198, 246, 213, 0))}.xl\:hover\:from-green-300:hover{--gradient-from-color:#9ae6b4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(154, 230, 180, 0))}.xl\:hover\:from-green-400:hover{--gradient-from-color:#68d391;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(104, 211, 145, 0))}.xl\:hover\:from-green-500:hover{--gradient-from-color:#48bb78;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(72, 187, 120, 0))}.xl\:hover\:from-green-600:hover{--gradient-from-color:#38a169;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(56, 161, 105, 0))}.xl\:hover\:from-green-700:hover{--gradient-from-color:#2f855a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(47, 133, 90, 0))}.xl\:hover\:from-green-800:hover{--gradient-from-color:#276749;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(39, 103, 73, 0))}.xl\:hover\:from-green-900:hover{--gradient-from-color:#22543d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(34, 84, 61, 0))}.xl\:hover\:from-teal-100:hover{--gradient-from-color:#e6fffa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(230, 255, 250, 0))}.xl\:hover\:from-teal-200:hover{--gradient-from-color:#b2f5ea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(178, 245, 234, 0))}.xl\:hover\:from-teal-300:hover{--gradient-from-color:#81e6d9;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(129, 230, 217, 0))}.xl\:hover\:from-teal-400:hover{--gradient-from-color:#4fd1c5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(79, 209, 197, 0))}.xl\:hover\:from-teal-500:hover{--gradient-from-color:#38b2ac;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(56, 178, 172, 0))}.xl\:hover\:from-teal-600:hover{--gradient-from-color:#319795;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(49, 151, 149, 0))}.xl\:hover\:from-teal-700:hover{--gradient-from-color:#2c7a7b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(44, 122, 123, 0))}.xl\:hover\:from-teal-800:hover{--gradient-from-color:#285e61;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(40, 94, 97, 0))}.xl\:hover\:from-teal-900:hover{--gradient-from-color:#234e52;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(35, 78, 82, 0))}.xl\:hover\:from-blue-100:hover{--gradient-from-color:#ebf8ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(235, 248, 255, 0))}.xl\:hover\:from-blue-200:hover{--gradient-from-color:#bee3f8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(190, 227, 248, 0))}.xl\:hover\:from-blue-300:hover{--gradient-from-color:#90cdf4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(144, 205, 244, 0))}.xl\:hover\:from-blue-400:hover{--gradient-from-color:#63b3ed;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(99, 179, 237, 0))}.xl\:hover\:from-blue-500:hover{--gradient-from-color:#4299e1;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(66, 153, 225, 0))}.xl\:hover\:from-blue-600:hover{--gradient-from-color:#3182ce;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(49, 130, 206, 0))}.xl\:hover\:from-blue-700:hover{--gradient-from-color:#2b6cb0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(43, 108, 176, 0))}.xl\:hover\:from-blue-800:hover{--gradient-from-color:#2c5282;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(44, 82, 130, 0))}.xl\:hover\:from-blue-900:hover{--gradient-from-color:#2a4365;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(42, 67, 101, 0))}.xl\:hover\:from-indigo-100:hover{--gradient-from-color:#ebf4ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(235, 244, 255, 0))}.xl\:hover\:from-indigo-200:hover{--gradient-from-color:#c3dafe;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(195, 218, 254, 0))}.xl\:hover\:from-indigo-300:hover{--gradient-from-color:#a3bffa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(163, 191, 250, 0))}.xl\:hover\:from-indigo-400:hover{--gradient-from-color:#7f9cf5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(127, 156, 245, 0))}.xl\:hover\:from-indigo-500:hover{--gradient-from-color:#667eea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(102, 126, 234, 0))}.xl\:hover\:from-indigo-600:hover{--gradient-from-color:#5a67d8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(90, 103, 216, 0))}.xl\:hover\:from-indigo-700:hover{--gradient-from-color:#4c51bf;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(76, 81, 191, 0))}.xl\:hover\:from-indigo-800:hover{--gradient-from-color:#434190;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(67, 65, 144, 0))}.xl\:hover\:from-indigo-900:hover{--gradient-from-color:#3c366b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(60, 54, 107, 0))}.xl\:hover\:from-purple-100:hover{--gradient-from-color:#faf5ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(250, 245, 255, 0))}.xl\:hover\:from-purple-200:hover{--gradient-from-color:#e9d8fd;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(233, 216, 253, 0))}.xl\:hover\:from-purple-300:hover{--gradient-from-color:#d6bcfa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(214, 188, 250, 0))}.xl\:hover\:from-purple-400:hover{--gradient-from-color:#b794f4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(183, 148, 244, 0))}.xl\:hover\:from-purple-500:hover{--gradient-from-color:#9f7aea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(159, 122, 234, 0))}.xl\:hover\:from-purple-600:hover{--gradient-from-color:#805ad5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(128, 90, 213, 0))}.xl\:hover\:from-purple-700:hover{--gradient-from-color:#6b46c1;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(107, 70, 193, 0))}.xl\:hover\:from-purple-800:hover{--gradient-from-color:#553c9a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(85, 60, 154, 0))}.xl\:hover\:from-purple-900:hover{--gradient-from-color:#44337a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(68, 51, 122, 0))}.xl\:hover\:from-pink-100:hover{--gradient-from-color:#fff5f7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 245, 247, 0))}.xl\:hover\:from-pink-200:hover{--gradient-from-color:#fed7e2;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(254, 215, 226, 0))}.xl\:hover\:from-pink-300:hover{--gradient-from-color:#fbb6ce;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(251, 182, 206, 0))}.xl\:hover\:from-pink-400:hover{--gradient-from-color:#f687b3;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(246, 135, 179, 0))}.xl\:hover\:from-pink-500:hover{--gradient-from-color:#ed64a6;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(237, 100, 166, 0))}.xl\:hover\:from-pink-600:hover{--gradient-from-color:#d53f8c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(213, 63, 140, 0))}.xl\:hover\:from-pink-700:hover{--gradient-from-color:#b83280;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(184, 50, 128, 0))}.xl\:hover\:from-pink-800:hover{--gradient-from-color:#97266d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(151, 38, 109, 0))}.xl\:hover\:from-pink-900:hover{--gradient-from-color:#702459;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(112, 36, 89, 0))}.xl\:hover\:via-transparent:hover{--gradient-via-color:transparent;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(0, 0, 0, 0))}.xl\:hover\:via-current:hover{--gradient-via-color:currentColor;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 255, 255, 0))}.xl\:hover\:via-black:hover{--gradient-via-color:#000;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(0, 0, 0, 0))}.xl\:hover\:via-white:hover{--gradient-via-color:#fff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 255, 255, 0))}.xl\:hover\:via-gray-100:hover{--gradient-via-color:#f7fafc;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(247, 250, 252, 0))}.xl\:hover\:via-gray-200:hover{--gradient-via-color:#edf2f7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(237, 242, 247, 0))}.xl\:hover\:via-gray-300:hover{--gradient-via-color:#e2e8f0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(226, 232, 240, 0))}.xl\:hover\:via-gray-400:hover{--gradient-via-color:#cbd5e0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(203, 213, 224, 0))}.xl\:hover\:via-gray-500:hover{--gradient-via-color:#a0aec0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(160, 174, 192, 0))}.xl\:hover\:via-gray-600:hover{--gradient-via-color:#718096;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(113, 128, 150, 0))}.xl\:hover\:via-gray-700:hover{--gradient-via-color:#4a5568;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(74, 85, 104, 0))}.xl\:hover\:via-gray-800:hover{--gradient-via-color:#2d3748;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(45, 55, 72, 0))}.xl\:hover\:via-gray-900:hover{--gradient-via-color:#1a202c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(26, 32, 44, 0))}.xl\:hover\:via-red-100:hover{--gradient-via-color:#fff5f5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 245, 245, 0))}.xl\:hover\:via-red-200:hover{--gradient-via-color:#fed7d7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(254, 215, 215, 0))}.xl\:hover\:via-red-300:hover{--gradient-via-color:#feb2b2;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(254, 178, 178, 0))}.xl\:hover\:via-red-400:hover{--gradient-via-color:#fc8181;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(252, 129, 129, 0))}.xl\:hover\:via-red-500:hover{--gradient-via-color:#f56565;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(245, 101, 101, 0))}.xl\:hover\:via-red-600:hover{--gradient-via-color:#e53e3e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(229, 62, 62, 0))}.xl\:hover\:via-red-700:hover{--gradient-via-color:#c53030;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(197, 48, 48, 0))}.xl\:hover\:via-red-800:hover{--gradient-via-color:#9b2c2c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(155, 44, 44, 0))}.xl\:hover\:via-red-900:hover{--gradient-via-color:#742a2a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(116, 42, 42, 0))}.xl\:hover\:via-orange-100:hover{--gradient-via-color:#fffaf0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 250, 240, 0))}.xl\:hover\:via-orange-200:hover{--gradient-via-color:#feebc8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(254, 235, 200, 0))}.xl\:hover\:via-orange-300:hover{--gradient-via-color:#fbd38d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(251, 211, 141, 0))}.xl\:hover\:via-orange-400:hover{--gradient-via-color:#f6ad55;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(246, 173, 85, 0))}.xl\:hover\:via-orange-500:hover{--gradient-via-color:#ed8936;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(237, 137, 54, 0))}.xl\:hover\:via-orange-600:hover{--gradient-via-color:#dd6b20;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(221, 107, 32, 0))}.xl\:hover\:via-orange-700:hover{--gradient-via-color:#c05621;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(192, 86, 33, 0))}.xl\:hover\:via-orange-800:hover{--gradient-via-color:#9c4221;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(156, 66, 33, 0))}.xl\:hover\:via-orange-900:hover{--gradient-via-color:#7b341e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(123, 52, 30, 0))}.xl\:hover\:via-yellow-100:hover{--gradient-via-color:#fffff0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 255, 240, 0))}.xl\:hover\:via-yellow-200:hover{--gradient-via-color:#fefcbf;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(254, 252, 191, 0))}.xl\:hover\:via-yellow-300:hover{--gradient-via-color:#faf089;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(250, 240, 137, 0))}.xl\:hover\:via-yellow-400:hover{--gradient-via-color:#f6e05e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(246, 224, 94, 0))}.xl\:hover\:via-yellow-500:hover{--gradient-via-color:#ecc94b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(236, 201, 75, 0))}.xl\:hover\:via-yellow-600:hover{--gradient-via-color:#d69e2e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(214, 158, 46, 0))}.xl\:hover\:via-yellow-700:hover{--gradient-via-color:#b7791f;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(183, 121, 31, 0))}.xl\:hover\:via-yellow-800:hover{--gradient-via-color:#975a16;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(151, 90, 22, 0))}.xl\:hover\:via-yellow-900:hover{--gradient-via-color:#744210;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(116, 66, 16, 0))}.xl\:hover\:via-green-100:hover{--gradient-via-color:#f0fff4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(240, 255, 244, 0))}.xl\:hover\:via-green-200:hover{--gradient-via-color:#c6f6d5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(198, 246, 213, 0))}.xl\:hover\:via-green-300:hover{--gradient-via-color:#9ae6b4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(154, 230, 180, 0))}.xl\:hover\:via-green-400:hover{--gradient-via-color:#68d391;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(104, 211, 145, 0))}.xl\:hover\:via-green-500:hover{--gradient-via-color:#48bb78;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(72, 187, 120, 0))}.xl\:hover\:via-green-600:hover{--gradient-via-color:#38a169;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(56, 161, 105, 0))}.xl\:hover\:via-green-700:hover{--gradient-via-color:#2f855a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(47, 133, 90, 0))}.xl\:hover\:via-green-800:hover{--gradient-via-color:#276749;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(39, 103, 73, 0))}.xl\:hover\:via-green-900:hover{--gradient-via-color:#22543d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(34, 84, 61, 0))}.xl\:hover\:via-teal-100:hover{--gradient-via-color:#e6fffa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(230, 255, 250, 0))}.xl\:hover\:via-teal-200:hover{--gradient-via-color:#b2f5ea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(178, 245, 234, 0))}.xl\:hover\:via-teal-300:hover{--gradient-via-color:#81e6d9;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(129, 230, 217, 0))}.xl\:hover\:via-teal-400:hover{--gradient-via-color:#4fd1c5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(79, 209, 197, 0))}.xl\:hover\:via-teal-500:hover{--gradient-via-color:#38b2ac;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(56, 178, 172, 0))}.xl\:hover\:via-teal-600:hover{--gradient-via-color:#319795;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(49, 151, 149, 0))}.xl\:hover\:via-teal-700:hover{--gradient-via-color:#2c7a7b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(44, 122, 123, 0))}.xl\:hover\:via-teal-800:hover{--gradient-via-color:#285e61;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(40, 94, 97, 0))}.xl\:hover\:via-teal-900:hover{--gradient-via-color:#234e52;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(35, 78, 82, 0))}.xl\:hover\:via-blue-100:hover{--gradient-via-color:#ebf8ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(235, 248, 255, 0))}.xl\:hover\:via-blue-200:hover{--gradient-via-color:#bee3f8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(190, 227, 248, 0))}.xl\:hover\:via-blue-300:hover{--gradient-via-color:#90cdf4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(144, 205, 244, 0))}.xl\:hover\:via-blue-400:hover{--gradient-via-color:#63b3ed;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(99, 179, 237, 0))}.xl\:hover\:via-blue-500:hover{--gradient-via-color:#4299e1;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(66, 153, 225, 0))}.xl\:hover\:via-blue-600:hover{--gradient-via-color:#3182ce;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(49, 130, 206, 0))}.xl\:hover\:via-blue-700:hover{--gradient-via-color:#2b6cb0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(43, 108, 176, 0))}.xl\:hover\:via-blue-800:hover{--gradient-via-color:#2c5282;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(44, 82, 130, 0))}.xl\:hover\:via-blue-900:hover{--gradient-via-color:#2a4365;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(42, 67, 101, 0))}.xl\:hover\:via-indigo-100:hover{--gradient-via-color:#ebf4ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(235, 244, 255, 0))}.xl\:hover\:via-indigo-200:hover{--gradient-via-color:#c3dafe;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(195, 218, 254, 0))}.xl\:hover\:via-indigo-300:hover{--gradient-via-color:#a3bffa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(163, 191, 250, 0))}.xl\:hover\:via-indigo-400:hover{--gradient-via-color:#7f9cf5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(127, 156, 245, 0))}.xl\:hover\:via-indigo-500:hover{--gradient-via-color:#667eea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(102, 126, 234, 0))}.xl\:hover\:via-indigo-600:hover{--gradient-via-color:#5a67d8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(90, 103, 216, 0))}.xl\:hover\:via-indigo-700:hover{--gradient-via-color:#4c51bf;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(76, 81, 191, 0))}.xl\:hover\:via-indigo-800:hover{--gradient-via-color:#434190;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(67, 65, 144, 0))}.xl\:hover\:via-indigo-900:hover{--gradient-via-color:#3c366b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(60, 54, 107, 0))}.xl\:hover\:via-purple-100:hover{--gradient-via-color:#faf5ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(250, 245, 255, 0))}.xl\:hover\:via-purple-200:hover{--gradient-via-color:#e9d8fd;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(233, 216, 253, 0))}.xl\:hover\:via-purple-300:hover{--gradient-via-color:#d6bcfa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(214, 188, 250, 0))}.xl\:hover\:via-purple-400:hover{--gradient-via-color:#b794f4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(183, 148, 244, 0))}.xl\:hover\:via-purple-500:hover{--gradient-via-color:#9f7aea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(159, 122, 234, 0))}.xl\:hover\:via-purple-600:hover{--gradient-via-color:#805ad5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(128, 90, 213, 0))}.xl\:hover\:via-purple-700:hover{--gradient-via-color:#6b46c1;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(107, 70, 193, 0))}.xl\:hover\:via-purple-800:hover{--gradient-via-color:#553c9a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(85, 60, 154, 0))}.xl\:hover\:via-purple-900:hover{--gradient-via-color:#44337a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(68, 51, 122, 0))}.xl\:hover\:via-pink-100:hover{--gradient-via-color:#fff5f7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 245, 247, 0))}.xl\:hover\:via-pink-200:hover{--gradient-via-color:#fed7e2;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(254, 215, 226, 0))}.xl\:hover\:via-pink-300:hover{--gradient-via-color:#fbb6ce;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(251, 182, 206, 0))}.xl\:hover\:via-pink-400:hover{--gradient-via-color:#f687b3;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(246, 135, 179, 0))}.xl\:hover\:via-pink-500:hover{--gradient-via-color:#ed64a6;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(237, 100, 166, 0))}.xl\:hover\:via-pink-600:hover{--gradient-via-color:#d53f8c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(213, 63, 140, 0))}.xl\:hover\:via-pink-700:hover{--gradient-via-color:#b83280;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(184, 50, 128, 0))}.xl\:hover\:via-pink-800:hover{--gradient-via-color:#97266d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(151, 38, 109, 0))}.xl\:hover\:via-pink-900:hover{--gradient-via-color:#702459;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(112, 36, 89, 0))}.xl\:hover\:to-transparent:hover{--gradient-to-color:transparent}.xl\:hover\:to-current:hover{--gradient-to-color:currentColor}.xl\:hover\:to-black:hover{--gradient-to-color:#000}.xl\:hover\:to-white:hover{--gradient-to-color:#fff}.xl\:hover\:to-gray-100:hover{--gradient-to-color:#f7fafc}.xl\:hover\:to-gray-200:hover{--gradient-to-color:#edf2f7}.xl\:hover\:to-gray-300:hover{--gradient-to-color:#e2e8f0}.xl\:hover\:to-gray-400:hover{--gradient-to-color:#cbd5e0}.xl\:hover\:to-gray-500:hover{--gradient-to-color:#a0aec0}.xl\:hover\:to-gray-600:hover{--gradient-to-color:#718096}.xl\:hover\:to-gray-700:hover{--gradient-to-color:#4a5568}.xl\:hover\:to-gray-800:hover{--gradient-to-color:#2d3748}.xl\:hover\:to-gray-900:hover{--gradient-to-color:#1a202c}.xl\:hover\:to-red-100:hover{--gradient-to-color:#fff5f5}.xl\:hover\:to-red-200:hover{--gradient-to-color:#fed7d7}.xl\:hover\:to-red-300:hover{--gradient-to-color:#feb2b2}.xl\:hover\:to-red-400:hover{--gradient-to-color:#fc8181}.xl\:hover\:to-red-500:hover{--gradient-to-color:#f56565}.xl\:hover\:to-red-600:hover{--gradient-to-color:#e53e3e}.xl\:hover\:to-red-700:hover{--gradient-to-color:#c53030}.xl\:hover\:to-red-800:hover{--gradient-to-color:#9b2c2c}.xl\:hover\:to-red-900:hover{--gradient-to-color:#742a2a}.xl\:hover\:to-orange-100:hover{--gradient-to-color:#fffaf0}.xl\:hover\:to-orange-200:hover{--gradient-to-color:#feebc8}.xl\:hover\:to-orange-300:hover{--gradient-to-color:#fbd38d}.xl\:hover\:to-orange-400:hover{--gradient-to-color:#f6ad55}.xl\:hover\:to-orange-500:hover{--gradient-to-color:#ed8936}.xl\:hover\:to-orange-600:hover{--gradient-to-color:#dd6b20}.xl\:hover\:to-orange-700:hover{--gradient-to-color:#c05621}.xl\:hover\:to-orange-800:hover{--gradient-to-color:#9c4221}.xl\:hover\:to-orange-900:hover{--gradient-to-color:#7b341e}.xl\:hover\:to-yellow-100:hover{--gradient-to-color:#fffff0}.xl\:hover\:to-yellow-200:hover{--gradient-to-color:#fefcbf}.xl\:hover\:to-yellow-300:hover{--gradient-to-color:#faf089}.xl\:hover\:to-yellow-400:hover{--gradient-to-color:#f6e05e}.xl\:hover\:to-yellow-500:hover{--gradient-to-color:#ecc94b}.xl\:hover\:to-yellow-600:hover{--gradient-to-color:#d69e2e}.xl\:hover\:to-yellow-700:hover{--gradient-to-color:#b7791f}.xl\:hover\:to-yellow-800:hover{--gradient-to-color:#975a16}.xl\:hover\:to-yellow-900:hover{--gradient-to-color:#744210}.xl\:hover\:to-green-100:hover{--gradient-to-color:#f0fff4}.xl\:hover\:to-green-200:hover{--gradient-to-color:#c6f6d5}.xl\:hover\:to-green-300:hover{--gradient-to-color:#9ae6b4}.xl\:hover\:to-green-400:hover{--gradient-to-color:#68d391}.xl\:hover\:to-green-500:hover{--gradient-to-color:#48bb78}.xl\:hover\:to-green-600:hover{--gradient-to-color:#38a169}.xl\:hover\:to-green-700:hover{--gradient-to-color:#2f855a}.xl\:hover\:to-green-800:hover{--gradient-to-color:#276749}.xl\:hover\:to-green-900:hover{--gradient-to-color:#22543d}.xl\:hover\:to-teal-100:hover{--gradient-to-color:#e6fffa}.xl\:hover\:to-teal-200:hover{--gradient-to-color:#b2f5ea}.xl\:hover\:to-teal-300:hover{--gradient-to-color:#81e6d9}.xl\:hover\:to-teal-400:hover{--gradient-to-color:#4fd1c5}.xl\:hover\:to-teal-500:hover{--gradient-to-color:#38b2ac}.xl\:hover\:to-teal-600:hover{--gradient-to-color:#319795}.xl\:hover\:to-teal-700:hover{--gradient-to-color:#2c7a7b}.xl\:hover\:to-teal-800:hover{--gradient-to-color:#285e61}.xl\:hover\:to-teal-900:hover{--gradient-to-color:#234e52}.xl\:hover\:to-blue-100:hover{--gradient-to-color:#ebf8ff}.xl\:hover\:to-blue-200:hover{--gradient-to-color:#bee3f8}.xl\:hover\:to-blue-300:hover{--gradient-to-color:#90cdf4}.xl\:hover\:to-blue-400:hover{--gradient-to-color:#63b3ed}.xl\:hover\:to-blue-500:hover{--gradient-to-color:#4299e1}.xl\:hover\:to-blue-600:hover{--gradient-to-color:#3182ce}.xl\:hover\:to-blue-700:hover{--gradient-to-color:#2b6cb0}.xl\:hover\:to-blue-800:hover{--gradient-to-color:#2c5282}.xl\:hover\:to-blue-900:hover{--gradient-to-color:#2a4365}.xl\:hover\:to-indigo-100:hover{--gradient-to-color:#ebf4ff}.xl\:hover\:to-indigo-200:hover{--gradient-to-color:#c3dafe}.xl\:hover\:to-indigo-300:hover{--gradient-to-color:#a3bffa}.xl\:hover\:to-indigo-400:hover{--gradient-to-color:#7f9cf5}.xl\:hover\:to-indigo-500:hover{--gradient-to-color:#667eea}.xl\:hover\:to-indigo-600:hover{--gradient-to-color:#5a67d8}.xl\:hover\:to-indigo-700:hover{--gradient-to-color:#4c51bf}.xl\:hover\:to-indigo-800:hover{--gradient-to-color:#434190}.xl\:hover\:to-indigo-900:hover{--gradient-to-color:#3c366b}.xl\:hover\:to-purple-100:hover{--gradient-to-color:#faf5ff}.xl\:hover\:to-purple-200:hover{--gradient-to-color:#e9d8fd}.xl\:hover\:to-purple-300:hover{--gradient-to-color:#d6bcfa}.xl\:hover\:to-purple-400:hover{--gradient-to-color:#b794f4}.xl\:hover\:to-purple-500:hover{--gradient-to-color:#9f7aea}.xl\:hover\:to-purple-600:hover{--gradient-to-color:#805ad5}.xl\:hover\:to-purple-700:hover{--gradient-to-color:#6b46c1}.xl\:hover\:to-purple-800:hover{--gradient-to-color:#553c9a}.xl\:hover\:to-purple-900:hover{--gradient-to-color:#44337a}.xl\:hover\:to-pink-100:hover{--gradient-to-color:#fff5f7}.xl\:hover\:to-pink-200:hover{--gradient-to-color:#fed7e2}.xl\:hover\:to-pink-300:hover{--gradient-to-color:#fbb6ce}.xl\:hover\:to-pink-400:hover{--gradient-to-color:#f687b3}.xl\:hover\:to-pink-500:hover{--gradient-to-color:#ed64a6}.xl\:hover\:to-pink-600:hover{--gradient-to-color:#d53f8c}.xl\:hover\:to-pink-700:hover{--gradient-to-color:#b83280}.xl\:hover\:to-pink-800:hover{--gradient-to-color:#97266d}.xl\:hover\:to-pink-900:hover{--gradient-to-color:#702459}.xl\:focus\:from-transparent:focus{--gradient-from-color:transparent;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(0, 0, 0, 0))}.xl\:focus\:from-current:focus{--gradient-from-color:currentColor;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 255, 255, 0))}.xl\:focus\:from-black:focus{--gradient-from-color:#000;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(0, 0, 0, 0))}.xl\:focus\:from-white:focus{--gradient-from-color:#fff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 255, 255, 0))}.xl\:focus\:from-gray-100:focus{--gradient-from-color:#f7fafc;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(247, 250, 252, 0))}.xl\:focus\:from-gray-200:focus{--gradient-from-color:#edf2f7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(237, 242, 247, 0))}.xl\:focus\:from-gray-300:focus{--gradient-from-color:#e2e8f0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(226, 232, 240, 0))}.xl\:focus\:from-gray-400:focus{--gradient-from-color:#cbd5e0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(203, 213, 224, 0))}.xl\:focus\:from-gray-500:focus{--gradient-from-color:#a0aec0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(160, 174, 192, 0))}.xl\:focus\:from-gray-600:focus{--gradient-from-color:#718096;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(113, 128, 150, 0))}.xl\:focus\:from-gray-700:focus{--gradient-from-color:#4a5568;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(74, 85, 104, 0))}.xl\:focus\:from-gray-800:focus{--gradient-from-color:#2d3748;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(45, 55, 72, 0))}.xl\:focus\:from-gray-900:focus{--gradient-from-color:#1a202c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(26, 32, 44, 0))}.xl\:focus\:from-red-100:focus{--gradient-from-color:#fff5f5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 245, 245, 0))}.xl\:focus\:from-red-200:focus{--gradient-from-color:#fed7d7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(254, 215, 215, 0))}.xl\:focus\:from-red-300:focus{--gradient-from-color:#feb2b2;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(254, 178, 178, 0))}.xl\:focus\:from-red-400:focus{--gradient-from-color:#fc8181;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(252, 129, 129, 0))}.xl\:focus\:from-red-500:focus{--gradient-from-color:#f56565;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(245, 101, 101, 0))}.xl\:focus\:from-red-600:focus{--gradient-from-color:#e53e3e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(229, 62, 62, 0))}.xl\:focus\:from-red-700:focus{--gradient-from-color:#c53030;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(197, 48, 48, 0))}.xl\:focus\:from-red-800:focus{--gradient-from-color:#9b2c2c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(155, 44, 44, 0))}.xl\:focus\:from-red-900:focus{--gradient-from-color:#742a2a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(116, 42, 42, 0))}.xl\:focus\:from-orange-100:focus{--gradient-from-color:#fffaf0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 250, 240, 0))}.xl\:focus\:from-orange-200:focus{--gradient-from-color:#feebc8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(254, 235, 200, 0))}.xl\:focus\:from-orange-300:focus{--gradient-from-color:#fbd38d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(251, 211, 141, 0))}.xl\:focus\:from-orange-400:focus{--gradient-from-color:#f6ad55;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(246, 173, 85, 0))}.xl\:focus\:from-orange-500:focus{--gradient-from-color:#ed8936;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(237, 137, 54, 0))}.xl\:focus\:from-orange-600:focus{--gradient-from-color:#dd6b20;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(221, 107, 32, 0))}.xl\:focus\:from-orange-700:focus{--gradient-from-color:#c05621;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(192, 86, 33, 0))}.xl\:focus\:from-orange-800:focus{--gradient-from-color:#9c4221;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(156, 66, 33, 0))}.xl\:focus\:from-orange-900:focus{--gradient-from-color:#7b341e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(123, 52, 30, 0))}.xl\:focus\:from-yellow-100:focus{--gradient-from-color:#fffff0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 255, 240, 0))}.xl\:focus\:from-yellow-200:focus{--gradient-from-color:#fefcbf;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(254, 252, 191, 0))}.xl\:focus\:from-yellow-300:focus{--gradient-from-color:#faf089;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(250, 240, 137, 0))}.xl\:focus\:from-yellow-400:focus{--gradient-from-color:#f6e05e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(246, 224, 94, 0))}.xl\:focus\:from-yellow-500:focus{--gradient-from-color:#ecc94b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(236, 201, 75, 0))}.xl\:focus\:from-yellow-600:focus{--gradient-from-color:#d69e2e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(214, 158, 46, 0))}.xl\:focus\:from-yellow-700:focus{--gradient-from-color:#b7791f;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(183, 121, 31, 0))}.xl\:focus\:from-yellow-800:focus{--gradient-from-color:#975a16;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(151, 90, 22, 0))}.xl\:focus\:from-yellow-900:focus{--gradient-from-color:#744210;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(116, 66, 16, 0))}.xl\:focus\:from-green-100:focus{--gradient-from-color:#f0fff4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(240, 255, 244, 0))}.xl\:focus\:from-green-200:focus{--gradient-from-color:#c6f6d5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(198, 246, 213, 0))}.xl\:focus\:from-green-300:focus{--gradient-from-color:#9ae6b4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(154, 230, 180, 0))}.xl\:focus\:from-green-400:focus{--gradient-from-color:#68d391;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(104, 211, 145, 0))}.xl\:focus\:from-green-500:focus{--gradient-from-color:#48bb78;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(72, 187, 120, 0))}.xl\:focus\:from-green-600:focus{--gradient-from-color:#38a169;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(56, 161, 105, 0))}.xl\:focus\:from-green-700:focus{--gradient-from-color:#2f855a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(47, 133, 90, 0))}.xl\:focus\:from-green-800:focus{--gradient-from-color:#276749;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(39, 103, 73, 0))}.xl\:focus\:from-green-900:focus{--gradient-from-color:#22543d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(34, 84, 61, 0))}.xl\:focus\:from-teal-100:focus{--gradient-from-color:#e6fffa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(230, 255, 250, 0))}.xl\:focus\:from-teal-200:focus{--gradient-from-color:#b2f5ea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(178, 245, 234, 0))}.xl\:focus\:from-teal-300:focus{--gradient-from-color:#81e6d9;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(129, 230, 217, 0))}.xl\:focus\:from-teal-400:focus{--gradient-from-color:#4fd1c5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(79, 209, 197, 0))}.xl\:focus\:from-teal-500:focus{--gradient-from-color:#38b2ac;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(56, 178, 172, 0))}.xl\:focus\:from-teal-600:focus{--gradient-from-color:#319795;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(49, 151, 149, 0))}.xl\:focus\:from-teal-700:focus{--gradient-from-color:#2c7a7b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(44, 122, 123, 0))}.xl\:focus\:from-teal-800:focus{--gradient-from-color:#285e61;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(40, 94, 97, 0))}.xl\:focus\:from-teal-900:focus{--gradient-from-color:#234e52;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(35, 78, 82, 0))}.xl\:focus\:from-blue-100:focus{--gradient-from-color:#ebf8ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(235, 248, 255, 0))}.xl\:focus\:from-blue-200:focus{--gradient-from-color:#bee3f8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(190, 227, 248, 0))}.xl\:focus\:from-blue-300:focus{--gradient-from-color:#90cdf4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(144, 205, 244, 0))}.xl\:focus\:from-blue-400:focus{--gradient-from-color:#63b3ed;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(99, 179, 237, 0))}.xl\:focus\:from-blue-500:focus{--gradient-from-color:#4299e1;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(66, 153, 225, 0))}.xl\:focus\:from-blue-600:focus{--gradient-from-color:#3182ce;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(49, 130, 206, 0))}.xl\:focus\:from-blue-700:focus{--gradient-from-color:#2b6cb0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(43, 108, 176, 0))}.xl\:focus\:from-blue-800:focus{--gradient-from-color:#2c5282;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(44, 82, 130, 0))}.xl\:focus\:from-blue-900:focus{--gradient-from-color:#2a4365;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(42, 67, 101, 0))}.xl\:focus\:from-indigo-100:focus{--gradient-from-color:#ebf4ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(235, 244, 255, 0))}.xl\:focus\:from-indigo-200:focus{--gradient-from-color:#c3dafe;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(195, 218, 254, 0))}.xl\:focus\:from-indigo-300:focus{--gradient-from-color:#a3bffa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(163, 191, 250, 0))}.xl\:focus\:from-indigo-400:focus{--gradient-from-color:#7f9cf5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(127, 156, 245, 0))}.xl\:focus\:from-indigo-500:focus{--gradient-from-color:#667eea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(102, 126, 234, 0))}.xl\:focus\:from-indigo-600:focus{--gradient-from-color:#5a67d8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(90, 103, 216, 0))}.xl\:focus\:from-indigo-700:focus{--gradient-from-color:#4c51bf;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(76, 81, 191, 0))}.xl\:focus\:from-indigo-800:focus{--gradient-from-color:#434190;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(67, 65, 144, 0))}.xl\:focus\:from-indigo-900:focus{--gradient-from-color:#3c366b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(60, 54, 107, 0))}.xl\:focus\:from-purple-100:focus{--gradient-from-color:#faf5ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(250, 245, 255, 0))}.xl\:focus\:from-purple-200:focus{--gradient-from-color:#e9d8fd;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(233, 216, 253, 0))}.xl\:focus\:from-purple-300:focus{--gradient-from-color:#d6bcfa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(214, 188, 250, 0))}.xl\:focus\:from-purple-400:focus{--gradient-from-color:#b794f4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(183, 148, 244, 0))}.xl\:focus\:from-purple-500:focus{--gradient-from-color:#9f7aea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(159, 122, 234, 0))}.xl\:focus\:from-purple-600:focus{--gradient-from-color:#805ad5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(128, 90, 213, 0))}.xl\:focus\:from-purple-700:focus{--gradient-from-color:#6b46c1;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(107, 70, 193, 0))}.xl\:focus\:from-purple-800:focus{--gradient-from-color:#553c9a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(85, 60, 154, 0))}.xl\:focus\:from-purple-900:focus{--gradient-from-color:#44337a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(68, 51, 122, 0))}.xl\:focus\:from-pink-100:focus{--gradient-from-color:#fff5f7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 245, 247, 0))}.xl\:focus\:from-pink-200:focus{--gradient-from-color:#fed7e2;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(254, 215, 226, 0))}.xl\:focus\:from-pink-300:focus{--gradient-from-color:#fbb6ce;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(251, 182, 206, 0))}.xl\:focus\:from-pink-400:focus{--gradient-from-color:#f687b3;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(246, 135, 179, 0))}.xl\:focus\:from-pink-500:focus{--gradient-from-color:#ed64a6;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(237, 100, 166, 0))}.xl\:focus\:from-pink-600:focus{--gradient-from-color:#d53f8c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(213, 63, 140, 0))}.xl\:focus\:from-pink-700:focus{--gradient-from-color:#b83280;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(184, 50, 128, 0))}.xl\:focus\:from-pink-800:focus{--gradient-from-color:#97266d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(151, 38, 109, 0))}.xl\:focus\:from-pink-900:focus{--gradient-from-color:#702459;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(112, 36, 89, 0))}.xl\:focus\:via-transparent:focus{--gradient-via-color:transparent;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(0, 0, 0, 0))}.xl\:focus\:via-current:focus{--gradient-via-color:currentColor;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 255, 255, 0))}.xl\:focus\:via-black:focus{--gradient-via-color:#000;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(0, 0, 0, 0))}.xl\:focus\:via-white:focus{--gradient-via-color:#fff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 255, 255, 0))}.xl\:focus\:via-gray-100:focus{--gradient-via-color:#f7fafc;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(247, 250, 252, 0))}.xl\:focus\:via-gray-200:focus{--gradient-via-color:#edf2f7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(237, 242, 247, 0))}.xl\:focus\:via-gray-300:focus{--gradient-via-color:#e2e8f0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(226, 232, 240, 0))}.xl\:focus\:via-gray-400:focus{--gradient-via-color:#cbd5e0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(203, 213, 224, 0))}.xl\:focus\:via-gray-500:focus{--gradient-via-color:#a0aec0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(160, 174, 192, 0))}.xl\:focus\:via-gray-600:focus{--gradient-via-color:#718096;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(113, 128, 150, 0))}.xl\:focus\:via-gray-700:focus{--gradient-via-color:#4a5568;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(74, 85, 104, 0))}.xl\:focus\:via-gray-800:focus{--gradient-via-color:#2d3748;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(45, 55, 72, 0))}.xl\:focus\:via-gray-900:focus{--gradient-via-color:#1a202c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(26, 32, 44, 0))}.xl\:focus\:via-red-100:focus{--gradient-via-color:#fff5f5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 245, 245, 0))}.xl\:focus\:via-red-200:focus{--gradient-via-color:#fed7d7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(254, 215, 215, 0))}.xl\:focus\:via-red-300:focus{--gradient-via-color:#feb2b2;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(254, 178, 178, 0))}.xl\:focus\:via-red-400:focus{--gradient-via-color:#fc8181;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(252, 129, 129, 0))}.xl\:focus\:via-red-500:focus{--gradient-via-color:#f56565;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(245, 101, 101, 0))}.xl\:focus\:via-red-600:focus{--gradient-via-color:#e53e3e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(229, 62, 62, 0))}.xl\:focus\:via-red-700:focus{--gradient-via-color:#c53030;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(197, 48, 48, 0))}.xl\:focus\:via-red-800:focus{--gradient-via-color:#9b2c2c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(155, 44, 44, 0))}.xl\:focus\:via-red-900:focus{--gradient-via-color:#742a2a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(116, 42, 42, 0))}.xl\:focus\:via-orange-100:focus{--gradient-via-color:#fffaf0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 250, 240, 0))}.xl\:focus\:via-orange-200:focus{--gradient-via-color:#feebc8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(254, 235, 200, 0))}.xl\:focus\:via-orange-300:focus{--gradient-via-color:#fbd38d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(251, 211, 141, 0))}.xl\:focus\:via-orange-400:focus{--gradient-via-color:#f6ad55;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(246, 173, 85, 0))}.xl\:focus\:via-orange-500:focus{--gradient-via-color:#ed8936;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(237, 137, 54, 0))}.xl\:focus\:via-orange-600:focus{--gradient-via-color:#dd6b20;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(221, 107, 32, 0))}.xl\:focus\:via-orange-700:focus{--gradient-via-color:#c05621;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(192, 86, 33, 0))}.xl\:focus\:via-orange-800:focus{--gradient-via-color:#9c4221;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(156, 66, 33, 0))}.xl\:focus\:via-orange-900:focus{--gradient-via-color:#7b341e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(123, 52, 30, 0))}.xl\:focus\:via-yellow-100:focus{--gradient-via-color:#fffff0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 255, 240, 0))}.xl\:focus\:via-yellow-200:focus{--gradient-via-color:#fefcbf;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(254, 252, 191, 0))}.xl\:focus\:via-yellow-300:focus{--gradient-via-color:#faf089;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(250, 240, 137, 0))}.xl\:focus\:via-yellow-400:focus{--gradient-via-color:#f6e05e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(246, 224, 94, 0))}.xl\:focus\:via-yellow-500:focus{--gradient-via-color:#ecc94b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(236, 201, 75, 0))}.xl\:focus\:via-yellow-600:focus{--gradient-via-color:#d69e2e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(214, 158, 46, 0))}.xl\:focus\:via-yellow-700:focus{--gradient-via-color:#b7791f;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(183, 121, 31, 0))}.xl\:focus\:via-yellow-800:focus{--gradient-via-color:#975a16;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(151, 90, 22, 0))}.xl\:focus\:via-yellow-900:focus{--gradient-via-color:#744210;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(116, 66, 16, 0))}.xl\:focus\:via-green-100:focus{--gradient-via-color:#f0fff4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(240, 255, 244, 0))}.xl\:focus\:via-green-200:focus{--gradient-via-color:#c6f6d5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(198, 246, 213, 0))}.xl\:focus\:via-green-300:focus{--gradient-via-color:#9ae6b4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(154, 230, 180, 0))}.xl\:focus\:via-green-400:focus{--gradient-via-color:#68d391;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(104, 211, 145, 0))}.xl\:focus\:via-green-500:focus{--gradient-via-color:#48bb78;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(72, 187, 120, 0))}.xl\:focus\:via-green-600:focus{--gradient-via-color:#38a169;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(56, 161, 105, 0))}.xl\:focus\:via-green-700:focus{--gradient-via-color:#2f855a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(47, 133, 90, 0))}.xl\:focus\:via-green-800:focus{--gradient-via-color:#276749;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(39, 103, 73, 0))}.xl\:focus\:via-green-900:focus{--gradient-via-color:#22543d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(34, 84, 61, 0))}.xl\:focus\:via-teal-100:focus{--gradient-via-color:#e6fffa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(230, 255, 250, 0))}.xl\:focus\:via-teal-200:focus{--gradient-via-color:#b2f5ea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(178, 245, 234, 0))}.xl\:focus\:via-teal-300:focus{--gradient-via-color:#81e6d9;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(129, 230, 217, 0))}.xl\:focus\:via-teal-400:focus{--gradient-via-color:#4fd1c5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(79, 209, 197, 0))}.xl\:focus\:via-teal-500:focus{--gradient-via-color:#38b2ac;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(56, 178, 172, 0))}.xl\:focus\:via-teal-600:focus{--gradient-via-color:#319795;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(49, 151, 149, 0))}.xl\:focus\:via-teal-700:focus{--gradient-via-color:#2c7a7b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(44, 122, 123, 0))}.xl\:focus\:via-teal-800:focus{--gradient-via-color:#285e61;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(40, 94, 97, 0))}.xl\:focus\:via-teal-900:focus{--gradient-via-color:#234e52;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(35, 78, 82, 0))}.xl\:focus\:via-blue-100:focus{--gradient-via-color:#ebf8ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(235, 248, 255, 0))}.xl\:focus\:via-blue-200:focus{--gradient-via-color:#bee3f8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(190, 227, 248, 0))}.xl\:focus\:via-blue-300:focus{--gradient-via-color:#90cdf4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(144, 205, 244, 0))}.xl\:focus\:via-blue-400:focus{--gradient-via-color:#63b3ed;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(99, 179, 237, 0))}.xl\:focus\:via-blue-500:focus{--gradient-via-color:#4299e1;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(66, 153, 225, 0))}.xl\:focus\:via-blue-600:focus{--gradient-via-color:#3182ce;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(49, 130, 206, 0))}.xl\:focus\:via-blue-700:focus{--gradient-via-color:#2b6cb0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(43, 108, 176, 0))}.xl\:focus\:via-blue-800:focus{--gradient-via-color:#2c5282;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(44, 82, 130, 0))}.xl\:focus\:via-blue-900:focus{--gradient-via-color:#2a4365;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(42, 67, 101, 0))}.xl\:focus\:via-indigo-100:focus{--gradient-via-color:#ebf4ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(235, 244, 255, 0))}.xl\:focus\:via-indigo-200:focus{--gradient-via-color:#c3dafe;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(195, 218, 254, 0))}.xl\:focus\:via-indigo-300:focus{--gradient-via-color:#a3bffa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(163, 191, 250, 0))}.xl\:focus\:via-indigo-400:focus{--gradient-via-color:#7f9cf5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(127, 156, 245, 0))}.xl\:focus\:via-indigo-500:focus{--gradient-via-color:#667eea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(102, 126, 234, 0))}.xl\:focus\:via-indigo-600:focus{--gradient-via-color:#5a67d8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(90, 103, 216, 0))}.xl\:focus\:via-indigo-700:focus{--gradient-via-color:#4c51bf;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(76, 81, 191, 0))}.xl\:focus\:via-indigo-800:focus{--gradient-via-color:#434190;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(67, 65, 144, 0))}.xl\:focus\:via-indigo-900:focus{--gradient-via-color:#3c366b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(60, 54, 107, 0))}.xl\:focus\:via-purple-100:focus{--gradient-via-color:#faf5ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(250, 245, 255, 0))}.xl\:focus\:via-purple-200:focus{--gradient-via-color:#e9d8fd;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(233, 216, 253, 0))}.xl\:focus\:via-purple-300:focus{--gradient-via-color:#d6bcfa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(214, 188, 250, 0))}.xl\:focus\:via-purple-400:focus{--gradient-via-color:#b794f4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(183, 148, 244, 0))}.xl\:focus\:via-purple-500:focus{--gradient-via-color:#9f7aea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(159, 122, 234, 0))}.xl\:focus\:via-purple-600:focus{--gradient-via-color:#805ad5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(128, 90, 213, 0))}.xl\:focus\:via-purple-700:focus{--gradient-via-color:#6b46c1;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(107, 70, 193, 0))}.xl\:focus\:via-purple-800:focus{--gradient-via-color:#553c9a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(85, 60, 154, 0))}.xl\:focus\:via-purple-900:focus{--gradient-via-color:#44337a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(68, 51, 122, 0))}.xl\:focus\:via-pink-100:focus{--gradient-via-color:#fff5f7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 245, 247, 0))}.xl\:focus\:via-pink-200:focus{--gradient-via-color:#fed7e2;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(254, 215, 226, 0))}.xl\:focus\:via-pink-300:focus{--gradient-via-color:#fbb6ce;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(251, 182, 206, 0))}.xl\:focus\:via-pink-400:focus{--gradient-via-color:#f687b3;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(246, 135, 179, 0))}.xl\:focus\:via-pink-500:focus{--gradient-via-color:#ed64a6;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(237, 100, 166, 0))}.xl\:focus\:via-pink-600:focus{--gradient-via-color:#d53f8c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(213, 63, 140, 0))}.xl\:focus\:via-pink-700:focus{--gradient-via-color:#b83280;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(184, 50, 128, 0))}.xl\:focus\:via-pink-800:focus{--gradient-via-color:#97266d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(151, 38, 109, 0))}.xl\:focus\:via-pink-900:focus{--gradient-via-color:#702459;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(112, 36, 89, 0))}.xl\:focus\:to-transparent:focus{--gradient-to-color:transparent}.xl\:focus\:to-current:focus{--gradient-to-color:currentColor}.xl\:focus\:to-black:focus{--gradient-to-color:#000}.xl\:focus\:to-white:focus{--gradient-to-color:#fff}.xl\:focus\:to-gray-100:focus{--gradient-to-color:#f7fafc}.xl\:focus\:to-gray-200:focus{--gradient-to-color:#edf2f7}.xl\:focus\:to-gray-300:focus{--gradient-to-color:#e2e8f0}.xl\:focus\:to-gray-400:focus{--gradient-to-color:#cbd5e0}.xl\:focus\:to-gray-500:focus{--gradient-to-color:#a0aec0}.xl\:focus\:to-gray-600:focus{--gradient-to-color:#718096}.xl\:focus\:to-gray-700:focus{--gradient-to-color:#4a5568}.xl\:focus\:to-gray-800:focus{--gradient-to-color:#2d3748}.xl\:focus\:to-gray-900:focus{--gradient-to-color:#1a202c}.xl\:focus\:to-red-100:focus{--gradient-to-color:#fff5f5}.xl\:focus\:to-red-200:focus{--gradient-to-color:#fed7d7}.xl\:focus\:to-red-300:focus{--gradient-to-color:#feb2b2}.xl\:focus\:to-red-400:focus{--gradient-to-color:#fc8181}.xl\:focus\:to-red-500:focus{--gradient-to-color:#f56565}.xl\:focus\:to-red-600:focus{--gradient-to-color:#e53e3e}.xl\:focus\:to-red-700:focus{--gradient-to-color:#c53030}.xl\:focus\:to-red-800:focus{--gradient-to-color:#9b2c2c}.xl\:focus\:to-red-900:focus{--gradient-to-color:#742a2a}.xl\:focus\:to-orange-100:focus{--gradient-to-color:#fffaf0}.xl\:focus\:to-orange-200:focus{--gradient-to-color:#feebc8}.xl\:focus\:to-orange-300:focus{--gradient-to-color:#fbd38d}.xl\:focus\:to-orange-400:focus{--gradient-to-color:#f6ad55}.xl\:focus\:to-orange-500:focus{--gradient-to-color:#ed8936}.xl\:focus\:to-orange-600:focus{--gradient-to-color:#dd6b20}.xl\:focus\:to-orange-700:focus{--gradient-to-color:#c05621}.xl\:focus\:to-orange-800:focus{--gradient-to-color:#9c4221}.xl\:focus\:to-orange-900:focus{--gradient-to-color:#7b341e}.xl\:focus\:to-yellow-100:focus{--gradient-to-color:#fffff0}.xl\:focus\:to-yellow-200:focus{--gradient-to-color:#fefcbf}.xl\:focus\:to-yellow-300:focus{--gradient-to-color:#faf089}.xl\:focus\:to-yellow-400:focus{--gradient-to-color:#f6e05e}.xl\:focus\:to-yellow-500:focus{--gradient-to-color:#ecc94b}.xl\:focus\:to-yellow-600:focus{--gradient-to-color:#d69e2e}.xl\:focus\:to-yellow-700:focus{--gradient-to-color:#b7791f}.xl\:focus\:to-yellow-800:focus{--gradient-to-color:#975a16}.xl\:focus\:to-yellow-900:focus{--gradient-to-color:#744210}.xl\:focus\:to-green-100:focus{--gradient-to-color:#f0fff4}.xl\:focus\:to-green-200:focus{--gradient-to-color:#c6f6d5}.xl\:focus\:to-green-300:focus{--gradient-to-color:#9ae6b4}.xl\:focus\:to-green-400:focus{--gradient-to-color:#68d391}.xl\:focus\:to-green-500:focus{--gradient-to-color:#48bb78}.xl\:focus\:to-green-600:focus{--gradient-to-color:#38a169}.xl\:focus\:to-green-700:focus{--gradient-to-color:#2f855a}.xl\:focus\:to-green-800:focus{--gradient-to-color:#276749}.xl\:focus\:to-green-900:focus{--gradient-to-color:#22543d}.xl\:focus\:to-teal-100:focus{--gradient-to-color:#e6fffa}.xl\:focus\:to-teal-200:focus{--gradient-to-color:#b2f5ea}.xl\:focus\:to-teal-300:focus{--gradient-to-color:#81e6d9}.xl\:focus\:to-teal-400:focus{--gradient-to-color:#4fd1c5}.xl\:focus\:to-teal-500:focus{--gradient-to-color:#38b2ac}.xl\:focus\:to-teal-600:focus{--gradient-to-color:#319795}.xl\:focus\:to-teal-700:focus{--gradient-to-color:#2c7a7b}.xl\:focus\:to-teal-800:focus{--gradient-to-color:#285e61}.xl\:focus\:to-teal-900:focus{--gradient-to-color:#234e52}.xl\:focus\:to-blue-100:focus{--gradient-to-color:#ebf8ff}.xl\:focus\:to-blue-200:focus{--gradient-to-color:#bee3f8}.xl\:focus\:to-blue-300:focus{--gradient-to-color:#90cdf4}.xl\:focus\:to-blue-400:focus{--gradient-to-color:#63b3ed}.xl\:focus\:to-blue-500:focus{--gradient-to-color:#4299e1}.xl\:focus\:to-blue-600:focus{--gradient-to-color:#3182ce}.xl\:focus\:to-blue-700:focus{--gradient-to-color:#2b6cb0}.xl\:focus\:to-blue-800:focus{--gradient-to-color:#2c5282}.xl\:focus\:to-blue-900:focus{--gradient-to-color:#2a4365}.xl\:focus\:to-indigo-100:focus{--gradient-to-color:#ebf4ff}.xl\:focus\:to-indigo-200:focus{--gradient-to-color:#c3dafe}.xl\:focus\:to-indigo-300:focus{--gradient-to-color:#a3bffa}.xl\:focus\:to-indigo-400:focus{--gradient-to-color:#7f9cf5}.xl\:focus\:to-indigo-500:focus{--gradient-to-color:#667eea}.xl\:focus\:to-indigo-600:focus{--gradient-to-color:#5a67d8}.xl\:focus\:to-indigo-700:focus{--gradient-to-color:#4c51bf}.xl\:focus\:to-indigo-800:focus{--gradient-to-color:#434190}.xl\:focus\:to-indigo-900:focus{--gradient-to-color:#3c366b}.xl\:focus\:to-purple-100:focus{--gradient-to-color:#faf5ff}.xl\:focus\:to-purple-200:focus{--gradient-to-color:#e9d8fd}.xl\:focus\:to-purple-300:focus{--gradient-to-color:#d6bcfa}.xl\:focus\:to-purple-400:focus{--gradient-to-color:#b794f4}.xl\:focus\:to-purple-500:focus{--gradient-to-color:#9f7aea}.xl\:focus\:to-purple-600:focus{--gradient-to-color:#805ad5}.xl\:focus\:to-purple-700:focus{--gradient-to-color:#6b46c1}.xl\:focus\:to-purple-800:focus{--gradient-to-color:#553c9a}.xl\:focus\:to-purple-900:focus{--gradient-to-color:#44337a}.xl\:focus\:to-pink-100:focus{--gradient-to-color:#fff5f7}.xl\:focus\:to-pink-200:focus{--gradient-to-color:#fed7e2}.xl\:focus\:to-pink-300:focus{--gradient-to-color:#fbb6ce}.xl\:focus\:to-pink-400:focus{--gradient-to-color:#f687b3}.xl\:focus\:to-pink-500:focus{--gradient-to-color:#ed64a6}.xl\:focus\:to-pink-600:focus{--gradient-to-color:#d53f8c}.xl\:focus\:to-pink-700:focus{--gradient-to-color:#b83280}.xl\:focus\:to-pink-800:focus{--gradient-to-color:#97266d}.xl\:focus\:to-pink-900:focus{--gradient-to-color:#702459}.xl\:bg-opacity-0{--bg-opacity:0}.xl\:bg-opacity-25{--bg-opacity:0.25}.xl\:bg-opacity-50{--bg-opacity:0.5}.xl\:bg-opacity-75{--bg-opacity:0.75}.xl\:bg-opacity-100{--bg-opacity:1}.xl\:hover\:bg-opacity-0:hover{--bg-opacity:0}.xl\:hover\:bg-opacity-25:hover{--bg-opacity:0.25}.xl\:hover\:bg-opacity-50:hover{--bg-opacity:0.5}.xl\:hover\:bg-opacity-75:hover{--bg-opacity:0.75}.xl\:hover\:bg-opacity-100:hover{--bg-opacity:1}.xl\:focus\:bg-opacity-0:focus{--bg-opacity:0}.xl\:focus\:bg-opacity-25:focus{--bg-opacity:0.25}.xl\:focus\:bg-opacity-50:focus{--bg-opacity:0.5}.xl\:focus\:bg-opacity-75:focus{--bg-opacity:0.75}.xl\:focus\:bg-opacity-100:focus{--bg-opacity:1}.xl\:bg-bottom{background-position:bottom}.xl\:bg-center{background-position:center}.xl\:bg-left{background-position:left}.xl\:bg-left-bottom{background-position:left bottom}.xl\:bg-left-top{background-position:left top}.xl\:bg-right{background-position:right}.xl\:bg-right-bottom{background-position:right bottom}.xl\:bg-right-top{background-position:right top}.xl\:bg-top{background-position:top}.xl\:bg-repeat{background-repeat:repeat}.xl\:bg-no-repeat{background-repeat:no-repeat}.xl\:bg-repeat-x{background-repeat:repeat-x}.xl\:bg-repeat-y{background-repeat:repeat-y}.xl\:bg-repeat-round{background-repeat:round}.xl\:bg-repeat-space{background-repeat:space}.xl\:bg-auto{background-size:auto}.xl\:bg-cover{background-size:cover}.xl\:bg-contain{background-size:contain}.xl\:border-collapse{border-collapse:collapse}.xl\:border-separate{border-collapse:separate}.xl\:border-transparent{border-color:transparent}.xl\:border-current{border-color:currentColor}.xl\:border-black{--border-opacity:1;border-color:#000;border-color:rgba(0,0,0,var(--border-opacity))}.xl\:border-white{--border-opacity:1;border-color:#fff;border-color:rgba(255,255,255,var(--border-opacity))}.xl\:border-gray-100{--border-opacity:1;border-color:#f7fafc;border-color:rgba(247,250,252,var(--border-opacity))}.xl\:border-gray-200{--border-opacity:1;border-color:#edf2f7;border-color:rgba(237,242,247,var(--border-opacity))}.xl\:border-gray-300{--border-opacity:1;border-color:#e2e8f0;border-color:rgba(226,232,240,var(--border-opacity))}.xl\:border-gray-400{--border-opacity:1;border-color:#cbd5e0;border-color:rgba(203,213,224,var(--border-opacity))}.xl\:border-gray-500{--border-opacity:1;border-color:#a0aec0;border-color:rgba(160,174,192,var(--border-opacity))}.xl\:border-gray-600{--border-opacity:1;border-color:#718096;border-color:rgba(113,128,150,var(--border-opacity))}.xl\:border-gray-700{--border-opacity:1;border-color:#4a5568;border-color:rgba(74,85,104,var(--border-opacity))}.xl\:border-gray-800{--border-opacity:1;border-color:#2d3748;border-color:rgba(45,55,72,var(--border-opacity))}.xl\:border-gray-900{--border-opacity:1;border-color:#1a202c;border-color:rgba(26,32,44,var(--border-opacity))}.xl\:border-red-100{--border-opacity:1;border-color:#fff5f5;border-color:rgba(255,245,245,var(--border-opacity))}.xl\:border-red-200{--border-opacity:1;border-color:#fed7d7;border-color:rgba(254,215,215,var(--border-opacity))}.xl\:border-red-300{--border-opacity:1;border-color:#feb2b2;border-color:rgba(254,178,178,var(--border-opacity))}.xl\:border-red-400{--border-opacity:1;border-color:#fc8181;border-color:rgba(252,129,129,var(--border-opacity))}.xl\:border-red-500{--border-opacity:1;border-color:#f56565;border-color:rgba(245,101,101,var(--border-opacity))}.xl\:border-red-600{--border-opacity:1;border-color:#e53e3e;border-color:rgba(229,62,62,var(--border-opacity))}.xl\:border-red-700{--border-opacity:1;border-color:#c53030;border-color:rgba(197,48,48,var(--border-opacity))}.xl\:border-red-800{--border-opacity:1;border-color:#9b2c2c;border-color:rgba(155,44,44,var(--border-opacity))}.xl\:border-red-900{--border-opacity:1;border-color:#742a2a;border-color:rgba(116,42,42,var(--border-opacity))}.xl\:border-orange-100{--border-opacity:1;border-color:#fffaf0;border-color:rgba(255,250,240,var(--border-opacity))}.xl\:border-orange-200{--border-opacity:1;border-color:#feebc8;border-color:rgba(254,235,200,var(--border-opacity))}.xl\:border-orange-300{--border-opacity:1;border-color:#fbd38d;border-color:rgba(251,211,141,var(--border-opacity))}.xl\:border-orange-400{--border-opacity:1;border-color:#f6ad55;border-color:rgba(246,173,85,var(--border-opacity))}.xl\:border-orange-500{--border-opacity:1;border-color:#ed8936;border-color:rgba(237,137,54,var(--border-opacity))}.xl\:border-orange-600{--border-opacity:1;border-color:#dd6b20;border-color:rgba(221,107,32,var(--border-opacity))}.xl\:border-orange-700{--border-opacity:1;border-color:#c05621;border-color:rgba(192,86,33,var(--border-opacity))}.xl\:border-orange-800{--border-opacity:1;border-color:#9c4221;border-color:rgba(156,66,33,var(--border-opacity))}.xl\:border-orange-900{--border-opacity:1;border-color:#7b341e;border-color:rgba(123,52,30,var(--border-opacity))}.xl\:border-yellow-100{--border-opacity:1;border-color:ivory;border-color:rgba(255,255,240,var(--border-opacity))}.xl\:border-yellow-200{--border-opacity:1;border-color:#fefcbf;border-color:rgba(254,252,191,var(--border-opacity))}.xl\:border-yellow-300{--border-opacity:1;border-color:#faf089;border-color:rgba(250,240,137,var(--border-opacity))}.xl\:border-yellow-400{--border-opacity:1;border-color:#f6e05e;border-color:rgba(246,224,94,var(--border-opacity))}.xl\:border-yellow-500{--border-opacity:1;border-color:#ecc94b;border-color:rgba(236,201,75,var(--border-opacity))}.xl\:border-yellow-600{--border-opacity:1;border-color:#d69e2e;border-color:rgba(214,158,46,var(--border-opacity))}.xl\:border-yellow-700{--border-opacity:1;border-color:#b7791f;border-color:rgba(183,121,31,var(--border-opacity))}.xl\:border-yellow-800{--border-opacity:1;border-color:#975a16;border-color:rgba(151,90,22,var(--border-opacity))}.xl\:border-yellow-900{--border-opacity:1;border-color:#744210;border-color:rgba(116,66,16,var(--border-opacity))}.xl\:border-green-100{--border-opacity:1;border-color:#f0fff4;border-color:rgba(240,255,244,var(--border-opacity))}.xl\:border-green-200{--border-opacity:1;border-color:#c6f6d5;border-color:rgba(198,246,213,var(--border-opacity))}.xl\:border-green-300{--border-opacity:1;border-color:#9ae6b4;border-color:rgba(154,230,180,var(--border-opacity))}.xl\:border-green-400{--border-opacity:1;border-color:#68d391;border-color:rgba(104,211,145,var(--border-opacity))}.xl\:border-green-500{--border-opacity:1;border-color:#48bb78;border-color:rgba(72,187,120,var(--border-opacity))}.xl\:border-green-600{--border-opacity:1;border-color:#38a169;border-color:rgba(56,161,105,var(--border-opacity))}.xl\:border-green-700{--border-opacity:1;border-color:#2f855a;border-color:rgba(47,133,90,var(--border-opacity))}.xl\:border-green-800{--border-opacity:1;border-color:#276749;border-color:rgba(39,103,73,var(--border-opacity))}.xl\:border-green-900{--border-opacity:1;border-color:#22543d;border-color:rgba(34,84,61,var(--border-opacity))}.xl\:border-teal-100{--border-opacity:1;border-color:#e6fffa;border-color:rgba(230,255,250,var(--border-opacity))}.xl\:border-teal-200{--border-opacity:1;border-color:#b2f5ea;border-color:rgba(178,245,234,var(--border-opacity))}.xl\:border-teal-300{--border-opacity:1;border-color:#81e6d9;border-color:rgba(129,230,217,var(--border-opacity))}.xl\:border-teal-400{--border-opacity:1;border-color:#4fd1c5;border-color:rgba(79,209,197,var(--border-opacity))}.xl\:border-teal-500{--border-opacity:1;border-color:#38b2ac;border-color:rgba(56,178,172,var(--border-opacity))}.xl\:border-teal-600{--border-opacity:1;border-color:#319795;border-color:rgba(49,151,149,var(--border-opacity))}.xl\:border-teal-700{--border-opacity:1;border-color:#2c7a7b;border-color:rgba(44,122,123,var(--border-opacity))}.xl\:border-teal-800{--border-opacity:1;border-color:#285e61;border-color:rgba(40,94,97,var(--border-opacity))}.xl\:border-teal-900{--border-opacity:1;border-color:#234e52;border-color:rgba(35,78,82,var(--border-opacity))}.xl\:border-blue-100{--border-opacity:1;border-color:#ebf8ff;border-color:rgba(235,248,255,var(--border-opacity))}.xl\:border-blue-200{--border-opacity:1;border-color:#bee3f8;border-color:rgba(190,227,248,var(--border-opacity))}.xl\:border-blue-300{--border-opacity:1;border-color:#90cdf4;border-color:rgba(144,205,244,var(--border-opacity))}.xl\:border-blue-400{--border-opacity:1;border-color:#63b3ed;border-color:rgba(99,179,237,var(--border-opacity))}.xl\:border-blue-500{--border-opacity:1;border-color:#4299e1;border-color:rgba(66,153,225,var(--border-opacity))}.xl\:border-blue-600{--border-opacity:1;border-color:#3182ce;border-color:rgba(49,130,206,var(--border-opacity))}.xl\:border-blue-700{--border-opacity:1;border-color:#2b6cb0;border-color:rgba(43,108,176,var(--border-opacity))}.xl\:border-blue-800{--border-opacity:1;border-color:#2c5282;border-color:rgba(44,82,130,var(--border-opacity))}.xl\:border-blue-900{--border-opacity:1;border-color:#2a4365;border-color:rgba(42,67,101,var(--border-opacity))}.xl\:border-indigo-100{--border-opacity:1;border-color:#ebf4ff;border-color:rgba(235,244,255,var(--border-opacity))}.xl\:border-indigo-200{--border-opacity:1;border-color:#c3dafe;border-color:rgba(195,218,254,var(--border-opacity))}.xl\:border-indigo-300{--border-opacity:1;border-color:#a3bffa;border-color:rgba(163,191,250,var(--border-opacity))}.xl\:border-indigo-400{--border-opacity:1;border-color:#7f9cf5;border-color:rgba(127,156,245,var(--border-opacity))}.xl\:border-indigo-500{--border-opacity:1;border-color:#667eea;border-color:rgba(102,126,234,var(--border-opacity))}.xl\:border-indigo-600{--border-opacity:1;border-color:#5a67d8;border-color:rgba(90,103,216,var(--border-opacity))}.xl\:border-indigo-700{--border-opacity:1;border-color:#4c51bf;border-color:rgba(76,81,191,var(--border-opacity))}.xl\:border-indigo-800{--border-opacity:1;border-color:#434190;border-color:rgba(67,65,144,var(--border-opacity))}.xl\:border-indigo-900{--border-opacity:1;border-color:#3c366b;border-color:rgba(60,54,107,var(--border-opacity))}.xl\:border-purple-100{--border-opacity:1;border-color:#faf5ff;border-color:rgba(250,245,255,var(--border-opacity))}.xl\:border-purple-200{--border-opacity:1;border-color:#e9d8fd;border-color:rgba(233,216,253,var(--border-opacity))}.xl\:border-purple-300{--border-opacity:1;border-color:#d6bcfa;border-color:rgba(214,188,250,var(--border-opacity))}.xl\:border-purple-400{--border-opacity:1;border-color:#b794f4;border-color:rgba(183,148,244,var(--border-opacity))}.xl\:border-purple-500{--border-opacity:1;border-color:#9f7aea;border-color:rgba(159,122,234,var(--border-opacity))}.xl\:border-purple-600{--border-opacity:1;border-color:#805ad5;border-color:rgba(128,90,213,var(--border-opacity))}.xl\:border-purple-700{--border-opacity:1;border-color:#6b46c1;border-color:rgba(107,70,193,var(--border-opacity))}.xl\:border-purple-800{--border-opacity:1;border-color:#553c9a;border-color:rgba(85,60,154,var(--border-opacity))}.xl\:border-purple-900{--border-opacity:1;border-color:#44337a;border-color:rgba(68,51,122,var(--border-opacity))}.xl\:border-pink-100{--border-opacity:1;border-color:#fff5f7;border-color:rgba(255,245,247,var(--border-opacity))}.xl\:border-pink-200{--border-opacity:1;border-color:#fed7e2;border-color:rgba(254,215,226,var(--border-opacity))}.xl\:border-pink-300{--border-opacity:1;border-color:#fbb6ce;border-color:rgba(251,182,206,var(--border-opacity))}.xl\:border-pink-400{--border-opacity:1;border-color:#f687b3;border-color:rgba(246,135,179,var(--border-opacity))}.xl\:border-pink-500{--border-opacity:1;border-color:#ed64a6;border-color:rgba(237,100,166,var(--border-opacity))}.xl\:border-pink-600{--border-opacity:1;border-color:#d53f8c;border-color:rgba(213,63,140,var(--border-opacity))}.xl\:border-pink-700{--border-opacity:1;border-color:#b83280;border-color:rgba(184,50,128,var(--border-opacity))}.xl\:border-pink-800{--border-opacity:1;border-color:#97266d;border-color:rgba(151,38,109,var(--border-opacity))}.xl\:border-pink-900{--border-opacity:1;border-color:#702459;border-color:rgba(112,36,89,var(--border-opacity))}.xl\:hover\:border-transparent:hover{border-color:transparent}.xl\:hover\:border-current:hover{border-color:currentColor}.xl\:hover\:border-black:hover{--border-opacity:1;border-color:#000;border-color:rgba(0,0,0,var(--border-opacity))}.xl\:hover\:border-white:hover{--border-opacity:1;border-color:#fff;border-color:rgba(255,255,255,var(--border-opacity))}.xl\:hover\:border-gray-100:hover{--border-opacity:1;border-color:#f7fafc;border-color:rgba(247,250,252,var(--border-opacity))}.xl\:hover\:border-gray-200:hover{--border-opacity:1;border-color:#edf2f7;border-color:rgba(237,242,247,var(--border-opacity))}.xl\:hover\:border-gray-300:hover{--border-opacity:1;border-color:#e2e8f0;border-color:rgba(226,232,240,var(--border-opacity))}.xl\:hover\:border-gray-400:hover{--border-opacity:1;border-color:#cbd5e0;border-color:rgba(203,213,224,var(--border-opacity))}.xl\:hover\:border-gray-500:hover{--border-opacity:1;border-color:#a0aec0;border-color:rgba(160,174,192,var(--border-opacity))}.xl\:hover\:border-gray-600:hover{--border-opacity:1;border-color:#718096;border-color:rgba(113,128,150,var(--border-opacity))}.xl\:hover\:border-gray-700:hover{--border-opacity:1;border-color:#4a5568;border-color:rgba(74,85,104,var(--border-opacity))}.xl\:hover\:border-gray-800:hover{--border-opacity:1;border-color:#2d3748;border-color:rgba(45,55,72,var(--border-opacity))}.xl\:hover\:border-gray-900:hover{--border-opacity:1;border-color:#1a202c;border-color:rgba(26,32,44,var(--border-opacity))}.xl\:hover\:border-red-100:hover{--border-opacity:1;border-color:#fff5f5;border-color:rgba(255,245,245,var(--border-opacity))}.xl\:hover\:border-red-200:hover{--border-opacity:1;border-color:#fed7d7;border-color:rgba(254,215,215,var(--border-opacity))}.xl\:hover\:border-red-300:hover{--border-opacity:1;border-color:#feb2b2;border-color:rgba(254,178,178,var(--border-opacity))}.xl\:hover\:border-red-400:hover{--border-opacity:1;border-color:#fc8181;border-color:rgba(252,129,129,var(--border-opacity))}.xl\:hover\:border-red-500:hover{--border-opacity:1;border-color:#f56565;border-color:rgba(245,101,101,var(--border-opacity))}.xl\:hover\:border-red-600:hover{--border-opacity:1;border-color:#e53e3e;border-color:rgba(229,62,62,var(--border-opacity))}.xl\:hover\:border-red-700:hover{--border-opacity:1;border-color:#c53030;border-color:rgba(197,48,48,var(--border-opacity))}.xl\:hover\:border-red-800:hover{--border-opacity:1;border-color:#9b2c2c;border-color:rgba(155,44,44,var(--border-opacity))}.xl\:hover\:border-red-900:hover{--border-opacity:1;border-color:#742a2a;border-color:rgba(116,42,42,var(--border-opacity))}.xl\:hover\:border-orange-100:hover{--border-opacity:1;border-color:#fffaf0;border-color:rgba(255,250,240,var(--border-opacity))}.xl\:hover\:border-orange-200:hover{--border-opacity:1;border-color:#feebc8;border-color:rgba(254,235,200,var(--border-opacity))}.xl\:hover\:border-orange-300:hover{--border-opacity:1;border-color:#fbd38d;border-color:rgba(251,211,141,var(--border-opacity))}.xl\:hover\:border-orange-400:hover{--border-opacity:1;border-color:#f6ad55;border-color:rgba(246,173,85,var(--border-opacity))}.xl\:hover\:border-orange-500:hover{--border-opacity:1;border-color:#ed8936;border-color:rgba(237,137,54,var(--border-opacity))}.xl\:hover\:border-orange-600:hover{--border-opacity:1;border-color:#dd6b20;border-color:rgba(221,107,32,var(--border-opacity))}.xl\:hover\:border-orange-700:hover{--border-opacity:1;border-color:#c05621;border-color:rgba(192,86,33,var(--border-opacity))}.xl\:hover\:border-orange-800:hover{--border-opacity:1;border-color:#9c4221;border-color:rgba(156,66,33,var(--border-opacity))}.xl\:hover\:border-orange-900:hover{--border-opacity:1;border-color:#7b341e;border-color:rgba(123,52,30,var(--border-opacity))}.xl\:hover\:border-yellow-100:hover{--border-opacity:1;border-color:ivory;border-color:rgba(255,255,240,var(--border-opacity))}.xl\:hover\:border-yellow-200:hover{--border-opacity:1;border-color:#fefcbf;border-color:rgba(254,252,191,var(--border-opacity))}.xl\:hover\:border-yellow-300:hover{--border-opacity:1;border-color:#faf089;border-color:rgba(250,240,137,var(--border-opacity))}.xl\:hover\:border-yellow-400:hover{--border-opacity:1;border-color:#f6e05e;border-color:rgba(246,224,94,var(--border-opacity))}.xl\:hover\:border-yellow-500:hover{--border-opacity:1;border-color:#ecc94b;border-color:rgba(236,201,75,var(--border-opacity))}.xl\:hover\:border-yellow-600:hover{--border-opacity:1;border-color:#d69e2e;border-color:rgba(214,158,46,var(--border-opacity))}.xl\:hover\:border-yellow-700:hover{--border-opacity:1;border-color:#b7791f;border-color:rgba(183,121,31,var(--border-opacity))}.xl\:hover\:border-yellow-800:hover{--border-opacity:1;border-color:#975a16;border-color:rgba(151,90,22,var(--border-opacity))}.xl\:hover\:border-yellow-900:hover{--border-opacity:1;border-color:#744210;border-color:rgba(116,66,16,var(--border-opacity))}.xl\:hover\:border-green-100:hover{--border-opacity:1;border-color:#f0fff4;border-color:rgba(240,255,244,var(--border-opacity))}.xl\:hover\:border-green-200:hover{--border-opacity:1;border-color:#c6f6d5;border-color:rgba(198,246,213,var(--border-opacity))}.xl\:hover\:border-green-300:hover{--border-opacity:1;border-color:#9ae6b4;border-color:rgba(154,230,180,var(--border-opacity))}.xl\:hover\:border-green-400:hover{--border-opacity:1;border-color:#68d391;border-color:rgba(104,211,145,var(--border-opacity))}.xl\:hover\:border-green-500:hover{--border-opacity:1;border-color:#48bb78;border-color:rgba(72,187,120,var(--border-opacity))}.xl\:hover\:border-green-600:hover{--border-opacity:1;border-color:#38a169;border-color:rgba(56,161,105,var(--border-opacity))}.xl\:hover\:border-green-700:hover{--border-opacity:1;border-color:#2f855a;border-color:rgba(47,133,90,var(--border-opacity))}.xl\:hover\:border-green-800:hover{--border-opacity:1;border-color:#276749;border-color:rgba(39,103,73,var(--border-opacity))}.xl\:hover\:border-green-900:hover{--border-opacity:1;border-color:#22543d;border-color:rgba(34,84,61,var(--border-opacity))}.xl\:hover\:border-teal-100:hover{--border-opacity:1;border-color:#e6fffa;border-color:rgba(230,255,250,var(--border-opacity))}.xl\:hover\:border-teal-200:hover{--border-opacity:1;border-color:#b2f5ea;border-color:rgba(178,245,234,var(--border-opacity))}.xl\:hover\:border-teal-300:hover{--border-opacity:1;border-color:#81e6d9;border-color:rgba(129,230,217,var(--border-opacity))}.xl\:hover\:border-teal-400:hover{--border-opacity:1;border-color:#4fd1c5;border-color:rgba(79,209,197,var(--border-opacity))}.xl\:hover\:border-teal-500:hover{--border-opacity:1;border-color:#38b2ac;border-color:rgba(56,178,172,var(--border-opacity))}.xl\:hover\:border-teal-600:hover{--border-opacity:1;border-color:#319795;border-color:rgba(49,151,149,var(--border-opacity))}.xl\:hover\:border-teal-700:hover{--border-opacity:1;border-color:#2c7a7b;border-color:rgba(44,122,123,var(--border-opacity))}.xl\:hover\:border-teal-800:hover{--border-opacity:1;border-color:#285e61;border-color:rgba(40,94,97,var(--border-opacity))}.xl\:hover\:border-teal-900:hover{--border-opacity:1;border-color:#234e52;border-color:rgba(35,78,82,var(--border-opacity))}.xl\:hover\:border-blue-100:hover{--border-opacity:1;border-color:#ebf8ff;border-color:rgba(235,248,255,var(--border-opacity))}.xl\:hover\:border-blue-200:hover{--border-opacity:1;border-color:#bee3f8;border-color:rgba(190,227,248,var(--border-opacity))}.xl\:hover\:border-blue-300:hover{--border-opacity:1;border-color:#90cdf4;border-color:rgba(144,205,244,var(--border-opacity))}.xl\:hover\:border-blue-400:hover{--border-opacity:1;border-color:#63b3ed;border-color:rgba(99,179,237,var(--border-opacity))}.xl\:hover\:border-blue-500:hover{--border-opacity:1;border-color:#4299e1;border-color:rgba(66,153,225,var(--border-opacity))}.xl\:hover\:border-blue-600:hover{--border-opacity:1;border-color:#3182ce;border-color:rgba(49,130,206,var(--border-opacity))}.xl\:hover\:border-blue-700:hover{--border-opacity:1;border-color:#2b6cb0;border-color:rgba(43,108,176,var(--border-opacity))}.xl\:hover\:border-blue-800:hover{--border-opacity:1;border-color:#2c5282;border-color:rgba(44,82,130,var(--border-opacity))}.xl\:hover\:border-blue-900:hover{--border-opacity:1;border-color:#2a4365;border-color:rgba(42,67,101,var(--border-opacity))}.xl\:hover\:border-indigo-100:hover{--border-opacity:1;border-color:#ebf4ff;border-color:rgba(235,244,255,var(--border-opacity))}.xl\:hover\:border-indigo-200:hover{--border-opacity:1;border-color:#c3dafe;border-color:rgba(195,218,254,var(--border-opacity))}.xl\:hover\:border-indigo-300:hover{--border-opacity:1;border-color:#a3bffa;border-color:rgba(163,191,250,var(--border-opacity))}.xl\:hover\:border-indigo-400:hover{--border-opacity:1;border-color:#7f9cf5;border-color:rgba(127,156,245,var(--border-opacity))}.xl\:hover\:border-indigo-500:hover{--border-opacity:1;border-color:#667eea;border-color:rgba(102,126,234,var(--border-opacity))}.xl\:hover\:border-indigo-600:hover{--border-opacity:1;border-color:#5a67d8;border-color:rgba(90,103,216,var(--border-opacity))}.xl\:hover\:border-indigo-700:hover{--border-opacity:1;border-color:#4c51bf;border-color:rgba(76,81,191,var(--border-opacity))}.xl\:hover\:border-indigo-800:hover{--border-opacity:1;border-color:#434190;border-color:rgba(67,65,144,var(--border-opacity))}.xl\:hover\:border-indigo-900:hover{--border-opacity:1;border-color:#3c366b;border-color:rgba(60,54,107,var(--border-opacity))}.xl\:hover\:border-purple-100:hover{--border-opacity:1;border-color:#faf5ff;border-color:rgba(250,245,255,var(--border-opacity))}.xl\:hover\:border-purple-200:hover{--border-opacity:1;border-color:#e9d8fd;border-color:rgba(233,216,253,var(--border-opacity))}.xl\:hover\:border-purple-300:hover{--border-opacity:1;border-color:#d6bcfa;border-color:rgba(214,188,250,var(--border-opacity))}.xl\:hover\:border-purple-400:hover{--border-opacity:1;border-color:#b794f4;border-color:rgba(183,148,244,var(--border-opacity))}.xl\:hover\:border-purple-500:hover{--border-opacity:1;border-color:#9f7aea;border-color:rgba(159,122,234,var(--border-opacity))}.xl\:hover\:border-purple-600:hover{--border-opacity:1;border-color:#805ad5;border-color:rgba(128,90,213,var(--border-opacity))}.xl\:hover\:border-purple-700:hover{--border-opacity:1;border-color:#6b46c1;border-color:rgba(107,70,193,var(--border-opacity))}.xl\:hover\:border-purple-800:hover{--border-opacity:1;border-color:#553c9a;border-color:rgba(85,60,154,var(--border-opacity))}.xl\:hover\:border-purple-900:hover{--border-opacity:1;border-color:#44337a;border-color:rgba(68,51,122,var(--border-opacity))}.xl\:hover\:border-pink-100:hover{--border-opacity:1;border-color:#fff5f7;border-color:rgba(255,245,247,var(--border-opacity))}.xl\:hover\:border-pink-200:hover{--border-opacity:1;border-color:#fed7e2;border-color:rgba(254,215,226,var(--border-opacity))}.xl\:hover\:border-pink-300:hover{--border-opacity:1;border-color:#fbb6ce;border-color:rgba(251,182,206,var(--border-opacity))}.xl\:hover\:border-pink-400:hover{--border-opacity:1;border-color:#f687b3;border-color:rgba(246,135,179,var(--border-opacity))}.xl\:hover\:border-pink-500:hover{--border-opacity:1;border-color:#ed64a6;border-color:rgba(237,100,166,var(--border-opacity))}.xl\:hover\:border-pink-600:hover{--border-opacity:1;border-color:#d53f8c;border-color:rgba(213,63,140,var(--border-opacity))}.xl\:hover\:border-pink-700:hover{--border-opacity:1;border-color:#b83280;border-color:rgba(184,50,128,var(--border-opacity))}.xl\:hover\:border-pink-800:hover{--border-opacity:1;border-color:#97266d;border-color:rgba(151,38,109,var(--border-opacity))}.xl\:hover\:border-pink-900:hover{--border-opacity:1;border-color:#702459;border-color:rgba(112,36,89,var(--border-opacity))}.xl\:focus\:border-transparent:focus{border-color:transparent}.xl\:focus\:border-current:focus{border-color:currentColor}.xl\:focus\:border-black:focus{--border-opacity:1;border-color:#000;border-color:rgba(0,0,0,var(--border-opacity))}.xl\:focus\:border-white:focus{--border-opacity:1;border-color:#fff;border-color:rgba(255,255,255,var(--border-opacity))}.xl\:focus\:border-gray-100:focus{--border-opacity:1;border-color:#f7fafc;border-color:rgba(247,250,252,var(--border-opacity))}.xl\:focus\:border-gray-200:focus{--border-opacity:1;border-color:#edf2f7;border-color:rgba(237,242,247,var(--border-opacity))}.xl\:focus\:border-gray-300:focus{--border-opacity:1;border-color:#e2e8f0;border-color:rgba(226,232,240,var(--border-opacity))}.xl\:focus\:border-gray-400:focus{--border-opacity:1;border-color:#cbd5e0;border-color:rgba(203,213,224,var(--border-opacity))}.xl\:focus\:border-gray-500:focus{--border-opacity:1;border-color:#a0aec0;border-color:rgba(160,174,192,var(--border-opacity))}.xl\:focus\:border-gray-600:focus{--border-opacity:1;border-color:#718096;border-color:rgba(113,128,150,var(--border-opacity))}.xl\:focus\:border-gray-700:focus{--border-opacity:1;border-color:#4a5568;border-color:rgba(74,85,104,var(--border-opacity))}.xl\:focus\:border-gray-800:focus{--border-opacity:1;border-color:#2d3748;border-color:rgba(45,55,72,var(--border-opacity))}.xl\:focus\:border-gray-900:focus{--border-opacity:1;border-color:#1a202c;border-color:rgba(26,32,44,var(--border-opacity))}.xl\:focus\:border-red-100:focus{--border-opacity:1;border-color:#fff5f5;border-color:rgba(255,245,245,var(--border-opacity))}.xl\:focus\:border-red-200:focus{--border-opacity:1;border-color:#fed7d7;border-color:rgba(254,215,215,var(--border-opacity))}.xl\:focus\:border-red-300:focus{--border-opacity:1;border-color:#feb2b2;border-color:rgba(254,178,178,var(--border-opacity))}.xl\:focus\:border-red-400:focus{--border-opacity:1;border-color:#fc8181;border-color:rgba(252,129,129,var(--border-opacity))}.xl\:focus\:border-red-500:focus{--border-opacity:1;border-color:#f56565;border-color:rgba(245,101,101,var(--border-opacity))}.xl\:focus\:border-red-600:focus{--border-opacity:1;border-color:#e53e3e;border-color:rgba(229,62,62,var(--border-opacity))}.xl\:focus\:border-red-700:focus{--border-opacity:1;border-color:#c53030;border-color:rgba(197,48,48,var(--border-opacity))}.xl\:focus\:border-red-800:focus{--border-opacity:1;border-color:#9b2c2c;border-color:rgba(155,44,44,var(--border-opacity))}.xl\:focus\:border-red-900:focus{--border-opacity:1;border-color:#742a2a;border-color:rgba(116,42,42,var(--border-opacity))}.xl\:focus\:border-orange-100:focus{--border-opacity:1;border-color:#fffaf0;border-color:rgba(255,250,240,var(--border-opacity))}.xl\:focus\:border-orange-200:focus{--border-opacity:1;border-color:#feebc8;border-color:rgba(254,235,200,var(--border-opacity))}.xl\:focus\:border-orange-300:focus{--border-opacity:1;border-color:#fbd38d;border-color:rgba(251,211,141,var(--border-opacity))}.xl\:focus\:border-orange-400:focus{--border-opacity:1;border-color:#f6ad55;border-color:rgba(246,173,85,var(--border-opacity))}.xl\:focus\:border-orange-500:focus{--border-opacity:1;border-color:#ed8936;border-color:rgba(237,137,54,var(--border-opacity))}.xl\:focus\:border-orange-600:focus{--border-opacity:1;border-color:#dd6b20;border-color:rgba(221,107,32,var(--border-opacity))}.xl\:focus\:border-orange-700:focus{--border-opacity:1;border-color:#c05621;border-color:rgba(192,86,33,var(--border-opacity))}.xl\:focus\:border-orange-800:focus{--border-opacity:1;border-color:#9c4221;border-color:rgba(156,66,33,var(--border-opacity))}.xl\:focus\:border-orange-900:focus{--border-opacity:1;border-color:#7b341e;border-color:rgba(123,52,30,var(--border-opacity))}.xl\:focus\:border-yellow-100:focus{--border-opacity:1;border-color:ivory;border-color:rgba(255,255,240,var(--border-opacity))}.xl\:focus\:border-yellow-200:focus{--border-opacity:1;border-color:#fefcbf;border-color:rgba(254,252,191,var(--border-opacity))}.xl\:focus\:border-yellow-300:focus{--border-opacity:1;border-color:#faf089;border-color:rgba(250,240,137,var(--border-opacity))}.xl\:focus\:border-yellow-400:focus{--border-opacity:1;border-color:#f6e05e;border-color:rgba(246,224,94,var(--border-opacity))}.xl\:focus\:border-yellow-500:focus{--border-opacity:1;border-color:#ecc94b;border-color:rgba(236,201,75,var(--border-opacity))}.xl\:focus\:border-yellow-600:focus{--border-opacity:1;border-color:#d69e2e;border-color:rgba(214,158,46,var(--border-opacity))}.xl\:focus\:border-yellow-700:focus{--border-opacity:1;border-color:#b7791f;border-color:rgba(183,121,31,var(--border-opacity))}.xl\:focus\:border-yellow-800:focus{--border-opacity:1;border-color:#975a16;border-color:rgba(151,90,22,var(--border-opacity))}.xl\:focus\:border-yellow-900:focus{--border-opacity:1;border-color:#744210;border-color:rgba(116,66,16,var(--border-opacity))}.xl\:focus\:border-green-100:focus{--border-opacity:1;border-color:#f0fff4;border-color:rgba(240,255,244,var(--border-opacity))}.xl\:focus\:border-green-200:focus{--border-opacity:1;border-color:#c6f6d5;border-color:rgba(198,246,213,var(--border-opacity))}.xl\:focus\:border-green-300:focus{--border-opacity:1;border-color:#9ae6b4;border-color:rgba(154,230,180,var(--border-opacity))}.xl\:focus\:border-green-400:focus{--border-opacity:1;border-color:#68d391;border-color:rgba(104,211,145,var(--border-opacity))}.xl\:focus\:border-green-500:focus{--border-opacity:1;border-color:#48bb78;border-color:rgba(72,187,120,var(--border-opacity))}.xl\:focus\:border-green-600:focus{--border-opacity:1;border-color:#38a169;border-color:rgba(56,161,105,var(--border-opacity))}.xl\:focus\:border-green-700:focus{--border-opacity:1;border-color:#2f855a;border-color:rgba(47,133,90,var(--border-opacity))}.xl\:focus\:border-green-800:focus{--border-opacity:1;border-color:#276749;border-color:rgba(39,103,73,var(--border-opacity))}.xl\:focus\:border-green-900:focus{--border-opacity:1;border-color:#22543d;border-color:rgba(34,84,61,var(--border-opacity))}.xl\:focus\:border-teal-100:focus{--border-opacity:1;border-color:#e6fffa;border-color:rgba(230,255,250,var(--border-opacity))}.xl\:focus\:border-teal-200:focus{--border-opacity:1;border-color:#b2f5ea;border-color:rgba(178,245,234,var(--border-opacity))}.xl\:focus\:border-teal-300:focus{--border-opacity:1;border-color:#81e6d9;border-color:rgba(129,230,217,var(--border-opacity))}.xl\:focus\:border-teal-400:focus{--border-opacity:1;border-color:#4fd1c5;border-color:rgba(79,209,197,var(--border-opacity))}.xl\:focus\:border-teal-500:focus{--border-opacity:1;border-color:#38b2ac;border-color:rgba(56,178,172,var(--border-opacity))}.xl\:focus\:border-teal-600:focus{--border-opacity:1;border-color:#319795;border-color:rgba(49,151,149,var(--border-opacity))}.xl\:focus\:border-teal-700:focus{--border-opacity:1;border-color:#2c7a7b;border-color:rgba(44,122,123,var(--border-opacity))}.xl\:focus\:border-teal-800:focus{--border-opacity:1;border-color:#285e61;border-color:rgba(40,94,97,var(--border-opacity))}.xl\:focus\:border-teal-900:focus{--border-opacity:1;border-color:#234e52;border-color:rgba(35,78,82,var(--border-opacity))}.xl\:focus\:border-blue-100:focus{--border-opacity:1;border-color:#ebf8ff;border-color:rgba(235,248,255,var(--border-opacity))}.xl\:focus\:border-blue-200:focus{--border-opacity:1;border-color:#bee3f8;border-color:rgba(190,227,248,var(--border-opacity))}.xl\:focus\:border-blue-300:focus{--border-opacity:1;border-color:#90cdf4;border-color:rgba(144,205,244,var(--border-opacity))}.xl\:focus\:border-blue-400:focus{--border-opacity:1;border-color:#63b3ed;border-color:rgba(99,179,237,var(--border-opacity))}.xl\:focus\:border-blue-500:focus{--border-opacity:1;border-color:#4299e1;border-color:rgba(66,153,225,var(--border-opacity))}.xl\:focus\:border-blue-600:focus{--border-opacity:1;border-color:#3182ce;border-color:rgba(49,130,206,var(--border-opacity))}.xl\:focus\:border-blue-700:focus{--border-opacity:1;border-color:#2b6cb0;border-color:rgba(43,108,176,var(--border-opacity))}.xl\:focus\:border-blue-800:focus{--border-opacity:1;border-color:#2c5282;border-color:rgba(44,82,130,var(--border-opacity))}.xl\:focus\:border-blue-900:focus{--border-opacity:1;border-color:#2a4365;border-color:rgba(42,67,101,var(--border-opacity))}.xl\:focus\:border-indigo-100:focus{--border-opacity:1;border-color:#ebf4ff;border-color:rgba(235,244,255,var(--border-opacity))}.xl\:focus\:border-indigo-200:focus{--border-opacity:1;border-color:#c3dafe;border-color:rgba(195,218,254,var(--border-opacity))}.xl\:focus\:border-indigo-300:focus{--border-opacity:1;border-color:#a3bffa;border-color:rgba(163,191,250,var(--border-opacity))}.xl\:focus\:border-indigo-400:focus{--border-opacity:1;border-color:#7f9cf5;border-color:rgba(127,156,245,var(--border-opacity))}.xl\:focus\:border-indigo-500:focus{--border-opacity:1;border-color:#667eea;border-color:rgba(102,126,234,var(--border-opacity))}.xl\:focus\:border-indigo-600:focus{--border-opacity:1;border-color:#5a67d8;border-color:rgba(90,103,216,var(--border-opacity))}.xl\:focus\:border-indigo-700:focus{--border-opacity:1;border-color:#4c51bf;border-color:rgba(76,81,191,var(--border-opacity))}.xl\:focus\:border-indigo-800:focus{--border-opacity:1;border-color:#434190;border-color:rgba(67,65,144,var(--border-opacity))}.xl\:focus\:border-indigo-900:focus{--border-opacity:1;border-color:#3c366b;border-color:rgba(60,54,107,var(--border-opacity))}.xl\:focus\:border-purple-100:focus{--border-opacity:1;border-color:#faf5ff;border-color:rgba(250,245,255,var(--border-opacity))}.xl\:focus\:border-purple-200:focus{--border-opacity:1;border-color:#e9d8fd;border-color:rgba(233,216,253,var(--border-opacity))}.xl\:focus\:border-purple-300:focus{--border-opacity:1;border-color:#d6bcfa;border-color:rgba(214,188,250,var(--border-opacity))}.xl\:focus\:border-purple-400:focus{--border-opacity:1;border-color:#b794f4;border-color:rgba(183,148,244,var(--border-opacity))}.xl\:focus\:border-purple-500:focus{--border-opacity:1;border-color:#9f7aea;border-color:rgba(159,122,234,var(--border-opacity))}.xl\:focus\:border-purple-600:focus{--border-opacity:1;border-color:#805ad5;border-color:rgba(128,90,213,var(--border-opacity))}.xl\:focus\:border-purple-700:focus{--border-opacity:1;border-color:#6b46c1;border-color:rgba(107,70,193,var(--border-opacity))}.xl\:focus\:border-purple-800:focus{--border-opacity:1;border-color:#553c9a;border-color:rgba(85,60,154,var(--border-opacity))}.xl\:focus\:border-purple-900:focus{--border-opacity:1;border-color:#44337a;border-color:rgba(68,51,122,var(--border-opacity))}.xl\:focus\:border-pink-100:focus{--border-opacity:1;border-color:#fff5f7;border-color:rgba(255,245,247,var(--border-opacity))}.xl\:focus\:border-pink-200:focus{--border-opacity:1;border-color:#fed7e2;border-color:rgba(254,215,226,var(--border-opacity))}.xl\:focus\:border-pink-300:focus{--border-opacity:1;border-color:#fbb6ce;border-color:rgba(251,182,206,var(--border-opacity))}.xl\:focus\:border-pink-400:focus{--border-opacity:1;border-color:#f687b3;border-color:rgba(246,135,179,var(--border-opacity))}.xl\:focus\:border-pink-500:focus{--border-opacity:1;border-color:#ed64a6;border-color:rgba(237,100,166,var(--border-opacity))}.xl\:focus\:border-pink-600:focus{--border-opacity:1;border-color:#d53f8c;border-color:rgba(213,63,140,var(--border-opacity))}.xl\:focus\:border-pink-700:focus{--border-opacity:1;border-color:#b83280;border-color:rgba(184,50,128,var(--border-opacity))}.xl\:focus\:border-pink-800:focus{--border-opacity:1;border-color:#97266d;border-color:rgba(151,38,109,var(--border-opacity))}.xl\:focus\:border-pink-900:focus{--border-opacity:1;border-color:#702459;border-color:rgba(112,36,89,var(--border-opacity))}.xl\:border-opacity-0{--border-opacity:0}.xl\:border-opacity-25{--border-opacity:0.25}.xl\:border-opacity-50{--border-opacity:0.5}.xl\:border-opacity-75{--border-opacity:0.75}.xl\:border-opacity-100{--border-opacity:1}.xl\:hover\:border-opacity-0:hover{--border-opacity:0}.xl\:hover\:border-opacity-25:hover{--border-opacity:0.25}.xl\:hover\:border-opacity-50:hover{--border-opacity:0.5}.xl\:hover\:border-opacity-75:hover{--border-opacity:0.75}.xl\:hover\:border-opacity-100:hover{--border-opacity:1}.xl\:focus\:border-opacity-0:focus{--border-opacity:0}.xl\:focus\:border-opacity-25:focus{--border-opacity:0.25}.xl\:focus\:border-opacity-50:focus{--border-opacity:0.5}.xl\:focus\:border-opacity-75:focus{--border-opacity:0.75}.xl\:focus\:border-opacity-100:focus{--border-opacity:1}.xl\:rounded-none{border-radius:0}.xl\:rounded-sm{border-radius:.125rem}.xl\:rounded{border-radius:.25rem}.xl\:rounded-md{border-radius:.375rem}.xl\:rounded-lg{border-radius:.5rem}.xl\:rounded-xl{border-radius:.75rem}.xl\:rounded-2xl{border-radius:1rem}.xl\:rounded-3xl{border-radius:1.5rem}.xl\:rounded-full{border-radius:9999px}.xl\:rounded-t-none{border-top-left-radius:0;border-top-right-radius:0}.xl\:rounded-r-none{border-top-right-radius:0;border-bottom-right-radius:0}.xl\:rounded-b-none{border-bottom-right-radius:0;border-bottom-left-radius:0}.xl\:rounded-l-none{border-top-left-radius:0;border-bottom-left-radius:0}.xl\:rounded-t-sm{border-top-left-radius:.125rem;border-top-right-radius:.125rem}.xl\:rounded-r-sm{border-top-right-radius:.125rem;border-bottom-right-radius:.125rem}.xl\:rounded-b-sm{border-bottom-right-radius:.125rem;border-bottom-left-radius:.125rem}.xl\:rounded-l-sm{border-top-left-radius:.125rem;border-bottom-left-radius:.125rem}.xl\:rounded-t{border-top-left-radius:.25rem;border-top-right-radius:.25rem}.xl\:rounded-r{border-top-right-radius:.25rem;border-bottom-right-radius:.25rem}.xl\:rounded-b{border-bottom-right-radius:.25rem;border-bottom-left-radius:.25rem}.xl\:rounded-l{border-top-left-radius:.25rem;border-bottom-left-radius:.25rem}.xl\:rounded-t-md{border-top-left-radius:.375rem;border-top-right-radius:.375rem}.xl\:rounded-r-md{border-top-right-radius:.375rem;border-bottom-right-radius:.375rem}.xl\:rounded-b-md{border-bottom-right-radius:.375rem;border-bottom-left-radius:.375rem}.xl\:rounded-l-md{border-top-left-radius:.375rem;border-bottom-left-radius:.375rem}.xl\:rounded-t-lg{border-top-left-radius:.5rem;border-top-right-radius:.5rem}.xl\:rounded-r-lg{border-top-right-radius:.5rem;border-bottom-right-radius:.5rem}.xl\:rounded-b-lg{border-bottom-right-radius:.5rem;border-bottom-left-radius:.5rem}.xl\:rounded-l-lg{border-top-left-radius:.5rem;border-bottom-left-radius:.5rem}.xl\:rounded-t-xl{border-top-left-radius:.75rem;border-top-right-radius:.75rem}.xl\:rounded-r-xl{border-top-right-radius:.75rem;border-bottom-right-radius:.75rem}.xl\:rounded-b-xl{border-bottom-right-radius:.75rem;border-bottom-left-radius:.75rem}.xl\:rounded-l-xl{border-top-left-radius:.75rem;border-bottom-left-radius:.75rem}.xl\:rounded-t-2xl{border-top-left-radius:1rem;border-top-right-radius:1rem}.xl\:rounded-r-2xl{border-top-right-radius:1rem;border-bottom-right-radius:1rem}.xl\:rounded-b-2xl{border-bottom-right-radius:1rem;border-bottom-left-radius:1rem}.xl\:rounded-l-2xl{border-top-left-radius:1rem;border-bottom-left-radius:1rem}.xl\:rounded-t-3xl{border-top-left-radius:1.5rem;border-top-right-radius:1.5rem}.xl\:rounded-r-3xl{border-top-right-radius:1.5rem;border-bottom-right-radius:1.5rem}.xl\:rounded-b-3xl{border-bottom-right-radius:1.5rem;border-bottom-left-radius:1.5rem}.xl\:rounded-l-3xl{border-top-left-radius:1.5rem;border-bottom-left-radius:1.5rem}.xl\:rounded-t-full{border-top-left-radius:9999px;border-top-right-radius:9999px}.xl\:rounded-r-full{border-top-right-radius:9999px;border-bottom-right-radius:9999px}.xl\:rounded-b-full{border-bottom-right-radius:9999px;border-bottom-left-radius:9999px}.xl\:rounded-l-full{border-top-left-radius:9999px;border-bottom-left-radius:9999px}.xl\:rounded-tl-none{border-top-left-radius:0}.xl\:rounded-tr-none{border-top-right-radius:0}.xl\:rounded-br-none{border-bottom-right-radius:0}.xl\:rounded-bl-none{border-bottom-left-radius:0}.xl\:rounded-tl-sm{border-top-left-radius:.125rem}.xl\:rounded-tr-sm{border-top-right-radius:.125rem}.xl\:rounded-br-sm{border-bottom-right-radius:.125rem}.xl\:rounded-bl-sm{border-bottom-left-radius:.125rem}.xl\:rounded-tl{border-top-left-radius:.25rem}.xl\:rounded-tr{border-top-right-radius:.25rem}.xl\:rounded-br{border-bottom-right-radius:.25rem}.xl\:rounded-bl{border-bottom-left-radius:.25rem}.xl\:rounded-tl-md{border-top-left-radius:.375rem}.xl\:rounded-tr-md{border-top-right-radius:.375rem}.xl\:rounded-br-md{border-bottom-right-radius:.375rem}.xl\:rounded-bl-md{border-bottom-left-radius:.375rem}.xl\:rounded-tl-lg{border-top-left-radius:.5rem}.xl\:rounded-tr-lg{border-top-right-radius:.5rem}.xl\:rounded-br-lg{border-bottom-right-radius:.5rem}.xl\:rounded-bl-lg{border-bottom-left-radius:.5rem}.xl\:rounded-tl-xl{border-top-left-radius:.75rem}.xl\:rounded-tr-xl{border-top-right-radius:.75rem}.xl\:rounded-br-xl{border-bottom-right-radius:.75rem}.xl\:rounded-bl-xl{border-bottom-left-radius:.75rem}.xl\:rounded-tl-2xl{border-top-left-radius:1rem}.xl\:rounded-tr-2xl{border-top-right-radius:1rem}.xl\:rounded-br-2xl{border-bottom-right-radius:1rem}.xl\:rounded-bl-2xl{border-bottom-left-radius:1rem}.xl\:rounded-tl-3xl{border-top-left-radius:1.5rem}.xl\:rounded-tr-3xl{border-top-right-radius:1.5rem}.xl\:rounded-br-3xl{border-bottom-right-radius:1.5rem}.xl\:rounded-bl-3xl{border-bottom-left-radius:1.5rem}.xl\:rounded-tl-full{border-top-left-radius:9999px}.xl\:rounded-tr-full{border-top-right-radius:9999px}.xl\:rounded-br-full{border-bottom-right-radius:9999px}.xl\:rounded-bl-full{border-bottom-left-radius:9999px}.xl\:border-solid{border-style:solid}.xl\:border-dashed{border-style:dashed}.xl\:border-dotted{border-style:dotted}.xl\:border-double{border-style:double}.xl\:border-none{border-style:none}.xl\:border-0{border-width:0}.xl\:border-2{border-width:2px}.xl\:border-4{border-width:4px}.xl\:border-8{border-width:8px}.xl\:border{border-width:1px}.xl\:border-t-0{border-top-width:0}.xl\:border-r-0{border-right-width:0}.xl\:border-b-0{border-bottom-width:0}.xl\:border-l-0{border-left-width:0}.xl\:border-t-2{border-top-width:2px}.xl\:border-r-2{border-right-width:2px}.xl\:border-b-2{border-bottom-width:2px}.xl\:border-l-2{border-left-width:2px}.xl\:border-t-4{border-top-width:4px}.xl\:border-r-4{border-right-width:4px}.xl\:border-b-4{border-bottom-width:4px}.xl\:border-l-4{border-left-width:4px}.xl\:border-t-8{border-top-width:8px}.xl\:border-r-8{border-right-width:8px}.xl\:border-b-8{border-bottom-width:8px}.xl\:border-l-8{border-left-width:8px}.xl\:border-t{border-top-width:1px}.xl\:border-r{border-right-width:1px}.xl\:border-b{border-bottom-width:1px}.xl\:border-l{border-left-width:1px}.xl\:box-border{box-sizing:border-box}.xl\:box-content{box-sizing:content-box}.xl\:cursor-auto{cursor:auto}.xl\:cursor-default{cursor:default}.xl\:cursor-pointer{cursor:pointer}.xl\:cursor-wait{cursor:wait}.xl\:cursor-text{cursor:text}.xl\:cursor-move{cursor:move}.xl\:cursor-not-allowed{cursor:not-allowed}.xl\:block{display:block}.xl\:inline-block{display:inline-block}.xl\:inline{display:inline}.xl\:flex{display:flex}.xl\:inline-flex{display:inline-flex}.xl\:table{display:table}.xl\:table-caption{display:table-caption}.xl\:table-cell{display:table-cell}.xl\:table-column{display:table-column}.xl\:table-column-group{display:table-column-group}.xl\:table-footer-group{display:table-footer-group}.xl\:table-header-group{display:table-header-group}.xl\:table-row-group{display:table-row-group}.xl\:table-row{display:table-row}.xl\:flow-root{display:flow-root}.xl\:grid{display:grid}.xl\:inline-grid{display:inline-grid}.xl\:contents{display:contents}.xl\:hidden{display:none}.xl\:flex-row{flex-direction:row}.xl\:flex-row-reverse{flex-direction:row-reverse}.xl\:flex-col{flex-direction:column}.xl\:flex-col-reverse{flex-direction:column-reverse}.xl\:flex-wrap{flex-wrap:wrap}.xl\:flex-wrap-reverse{flex-wrap:wrap-reverse}.xl\:flex-no-wrap{flex-wrap:nowrap}.xl\:place-items-auto{place-items:auto}.xl\:place-items-start{place-items:start}.xl\:place-items-end{place-items:end}.xl\:place-items-center{place-items:center}.xl\:place-items-stretch{place-items:stretch}.xl\:place-content-center{place-content:center}.xl\:place-content-start{place-content:start}.xl\:place-content-end{place-content:end}.xl\:place-content-between{place-content:space-between}.xl\:place-content-around{place-content:space-around}.xl\:place-content-evenly{place-content:space-evenly}.xl\:place-content-stretch{place-content:stretch}.xl\:place-self-auto{place-self:auto}.xl\:place-self-start{place-self:start}.xl\:place-self-end{place-self:end}.xl\:place-self-center{place-self:center}.xl\:place-self-stretch{place-self:stretch}.xl\:items-start{align-items:flex-start}.xl\:items-end{align-items:flex-end}.xl\:items-center{align-items:center}.xl\:items-baseline{align-items:baseline}.xl\:items-stretch{align-items:stretch}.xl\:content-center{align-content:center}.xl\:content-start{align-content:flex-start}.xl\:content-end{align-content:flex-end}.xl\:content-between{align-content:space-between}.xl\:content-around{align-content:space-around}.xl\:content-evenly{align-content:space-evenly}.xl\:self-auto{align-self:auto}.xl\:self-start{align-self:flex-start}.xl\:self-end{align-self:flex-end}.xl\:self-center{align-self:center}.xl\:self-stretch{align-self:stretch}.xl\:justify-items-auto{justify-items:auto}.xl\:justify-items-start{justify-items:start}.xl\:justify-items-end{justify-items:end}.xl\:justify-items-center{justify-items:center}.xl\:justify-items-stretch{justify-items:stretch}.xl\:justify-start{justify-content:flex-start}.xl\:justify-end{justify-content:flex-end}.xl\:justify-center{justify-content:center}.xl\:justify-between{justify-content:space-between}.xl\:justify-around{justify-content:space-around}.xl\:justify-evenly{justify-content:space-evenly}.xl\:justify-self-auto{justify-self:auto}.xl\:justify-self-start{justify-self:start}.xl\:justify-self-end{justify-self:end}.xl\:justify-self-center{justify-self:center}.xl\:justify-self-stretch{justify-self:stretch}.xl\:flex-1{flex:1 1 0%}.xl\:flex-auto{flex:1 1 auto}.xl\:flex-initial{flex:0 1 auto}.xl\:flex-none{flex:none}.xl\:flex-grow-0{flex-grow:0}.xl\:flex-grow{flex-grow:1}.xl\:flex-shrink-0{flex-shrink:0}.xl\:flex-shrink{flex-shrink:1}.xl\:order-1{order:1}.xl\:order-2{order:2}.xl\:order-3{order:3}.xl\:order-4{order:4}.xl\:order-5{order:5}.xl\:order-6{order:6}.xl\:order-7{order:7}.xl\:order-8{order:8}.xl\:order-9{order:9}.xl\:order-10{order:10}.xl\:order-11{order:11}.xl\:order-12{order:12}.xl\:order-first{order:-9999}.xl\:order-last{order:9999}.xl\:order-none{order:0}.xl\:float-right{float:right}.xl\:float-left{float:left}.xl\:float-none{float:none}.xl\:clearfix:after{content:"";display:table;clear:both}.xl\:clear-left{clear:left}.xl\:clear-right{clear:right}.xl\:clear-both{clear:both}.xl\:clear-none{clear:none}.xl\:font-sans{font-family:system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji"}.xl\:font-serif{font-family:Georgia,Cambria,"Times New Roman",Times,serif}.xl\:font-mono{font-family:Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace}.xl\:font-hairline{font-weight:100}.xl\:font-thin{font-weight:200}.xl\:font-light{font-weight:300}.xl\:font-normal{font-weight:400}.xl\:font-medium{font-weight:500}.xl\:font-semibold{font-weight:600}.xl\:font-bold{font-weight:700}.xl\:font-extrabold{font-weight:800}.xl\:font-black{font-weight:900}.xl\:hover\:font-hairline:hover{font-weight:100}.xl\:hover\:font-thin:hover{font-weight:200}.xl\:hover\:font-light:hover{font-weight:300}.xl\:hover\:font-normal:hover{font-weight:400}.xl\:hover\:font-medium:hover{font-weight:500}.xl\:hover\:font-semibold:hover{font-weight:600}.xl\:hover\:font-bold:hover{font-weight:700}.xl\:hover\:font-extrabold:hover{font-weight:800}.xl\:hover\:font-black:hover{font-weight:900}.xl\:focus\:font-hairline:focus{font-weight:100}.xl\:focus\:font-thin:focus{font-weight:200}.xl\:focus\:font-light:focus{font-weight:300}.xl\:focus\:font-normal:focus{font-weight:400}.xl\:focus\:font-medium:focus{font-weight:500}.xl\:focus\:font-semibold:focus{font-weight:600}.xl\:focus\:font-bold:focus{font-weight:700}.xl\:focus\:font-extrabold:focus{font-weight:800}.xl\:focus\:font-black:focus{font-weight:900}.xl\:h-0{height:0}.xl\:h-1{height:.25rem}.xl\:h-2{height:.5rem}.xl\:h-3{height:.75rem}.xl\:h-4{height:1rem}.xl\:h-5{height:1.25rem}.xl\:h-6{height:1.5rem}.xl\:h-8{height:2rem}.xl\:h-10{height:2.5rem}.xl\:h-12{height:3rem}.xl\:h-16{height:4rem}.xl\:h-20{height:5rem}.xl\:h-24{height:6rem}.xl\:h-32{height:8rem}.xl\:h-40{height:10rem}.xl\:h-48{height:12rem}.xl\:h-56{height:14rem}.xl\:h-64{height:16rem}.xl\:h-auto{height:auto}.xl\:h-px{height:1px}.xl\:h-full{height:100%}.xl\:h-screen{height:100vh}.xl\:text-xs{font-size:.75rem}.xl\:text-sm{font-size:.875rem}.xl\:text-base{font-size:1rem}.xl\:text-lg{font-size:1.125rem}.xl\:text-xl{font-size:1.25rem}.xl\:text-2xl{font-size:1.5rem}.xl\:text-3xl{font-size:1.875rem}.xl\:text-4xl{font-size:2.25rem}.xl\:text-5xl{font-size:3rem}.xl\:text-6xl{font-size:4rem}.xl\:leading-3{line-height:.75rem}.xl\:leading-4{line-height:1rem}.xl\:leading-5{line-height:1.25rem}.xl\:leading-6{line-height:1.5rem}.xl\:leading-7{line-height:1.75rem}.xl\:leading-8{line-height:2rem}.xl\:leading-9{line-height:2.25rem}.xl\:leading-10{line-height:2.5rem}.xl\:leading-none{line-height:1}.xl\:leading-tight{line-height:1.25}.xl\:leading-snug{line-height:1.375}.xl\:leading-normal{line-height:1.5}.xl\:leading-relaxed{line-height:1.625}.xl\:leading-loose{line-height:2}.xl\:list-inside{list-style-position:inside}.xl\:list-outside{list-style-position:outside}.xl\:list-none{list-style-type:none}.xl\:list-disc{list-style-type:disc}.xl\:list-decimal{list-style-type:decimal}.xl\:m-0{margin:0}.xl\:m-1{margin:.25rem}.xl\:m-2{margin:.5rem}.xl\:m-3{margin:.75rem}.xl\:m-4{margin:1rem}.xl\:m-5{margin:1.25rem}.xl\:m-6{margin:1.5rem}.xl\:m-8{margin:2rem}.xl\:m-10{margin:2.5rem}.xl\:m-12{margin:3rem}.xl\:m-16{margin:4rem}.xl\:m-20{margin:5rem}.xl\:m-24{margin:6rem}.xl\:m-32{margin:8rem}.xl\:m-40{margin:10rem}.xl\:m-48{margin:12rem}.xl\:m-56{margin:14rem}.xl\:m-64{margin:16rem}.xl\:m-auto{margin:auto}.xl\:m-px{margin:1px}.xl\:-m-1{margin:-.25rem}.xl\:-m-2{margin:-.5rem}.xl\:-m-3{margin:-.75rem}.xl\:-m-4{margin:-1rem}.xl\:-m-5{margin:-1.25rem}.xl\:-m-6{margin:-1.5rem}.xl\:-m-8{margin:-2rem}.xl\:-m-10{margin:-2.5rem}.xl\:-m-12{margin:-3rem}.xl\:-m-16{margin:-4rem}.xl\:-m-20{margin:-5rem}.xl\:-m-24{margin:-6rem}.xl\:-m-32{margin:-8rem}.xl\:-m-40{margin:-10rem}.xl\:-m-48{margin:-12rem}.xl\:-m-56{margin:-14rem}.xl\:-m-64{margin:-16rem}.xl\:-m-px{margin:-1px}.xl\:my-0{margin-top:0;margin-bottom:0}.xl\:mx-0{margin-left:0;margin-right:0}.xl\:my-1{margin-top:.25rem;margin-bottom:.25rem}.xl\:mx-1{margin-left:.25rem;margin-right:.25rem}.xl\:my-2{margin-top:.5rem;margin-bottom:.5rem}.xl\:mx-2{margin-left:.5rem;margin-right:.5rem}.xl\:my-3{margin-top:.75rem;margin-bottom:.75rem}.xl\:mx-3{margin-left:.75rem;margin-right:.75rem}.xl\:my-4{margin-top:1rem;margin-bottom:1rem}.xl\:mx-4{margin-left:1rem;margin-right:1rem}.xl\:my-5{margin-top:1.25rem;margin-bottom:1.25rem}.xl\:mx-5{margin-left:1.25rem;margin-right:1.25rem}.xl\:my-6{margin-top:1.5rem;margin-bottom:1.5rem}.xl\:mx-6{margin-left:1.5rem;margin-right:1.5rem}.xl\:my-8{margin-top:2rem;margin-bottom:2rem}.xl\:mx-8{margin-left:2rem;margin-right:2rem}.xl\:my-10{margin-top:2.5rem;margin-bottom:2.5rem}.xl\:mx-10{margin-left:2.5rem;margin-right:2.5rem}.xl\:my-12{margin-top:3rem;margin-bottom:3rem}.xl\:mx-12{margin-left:3rem;margin-right:3rem}.xl\:my-16{margin-top:4rem;margin-bottom:4rem}.xl\:mx-16{margin-left:4rem;margin-right:4rem}.xl\:my-20{margin-top:5rem;margin-bottom:5rem}.xl\:mx-20{margin-left:5rem;margin-right:5rem}.xl\:my-24{margin-top:6rem;margin-bottom:6rem}.xl\:mx-24{margin-left:6rem;margin-right:6rem}.xl\:my-32{margin-top:8rem;margin-bottom:8rem}.xl\:mx-32{margin-left:8rem;margin-right:8rem}.xl\:my-40{margin-top:10rem;margin-bottom:10rem}.xl\:mx-40{margin-left:10rem;margin-right:10rem}.xl\:my-48{margin-top:12rem;margin-bottom:12rem}.xl\:mx-48{margin-left:12rem;margin-right:12rem}.xl\:my-56{margin-top:14rem;margin-bottom:14rem}.xl\:mx-56{margin-left:14rem;margin-right:14rem}.xl\:my-64{margin-top:16rem;margin-bottom:16rem}.xl\:mx-64{margin-left:16rem;margin-right:16rem}.xl\:my-auto{margin-top:auto;margin-bottom:auto}.xl\:mx-auto{margin-left:auto;margin-right:auto}.xl\:my-px{margin-top:1px;margin-bottom:1px}.xl\:mx-px{margin-left:1px;margin-right:1px}.xl\:-my-1{margin-top:-.25rem;margin-bottom:-.25rem}.xl\:-mx-1{margin-left:-.25rem;margin-right:-.25rem}.xl\:-my-2{margin-top:-.5rem;margin-bottom:-.5rem}.xl\:-mx-2{margin-left:-.5rem;margin-right:-.5rem}.xl\:-my-3{margin-top:-.75rem;margin-bottom:-.75rem}.xl\:-mx-3{margin-left:-.75rem;margin-right:-.75rem}.xl\:-my-4{margin-top:-1rem;margin-bottom:-1rem}.xl\:-mx-4{margin-left:-1rem;margin-right:-1rem}.xl\:-my-5{margin-top:-1.25rem;margin-bottom:-1.25rem}.xl\:-mx-5{margin-left:-1.25rem;margin-right:-1.25rem}.xl\:-my-6{margin-top:-1.5rem;margin-bottom:-1.5rem}.xl\:-mx-6{margin-left:-1.5rem;margin-right:-1.5rem}.xl\:-my-8{margin-top:-2rem;margin-bottom:-2rem}.xl\:-mx-8{margin-left:-2rem;margin-right:-2rem}.xl\:-my-10{margin-top:-2.5rem;margin-bottom:-2.5rem}.xl\:-mx-10{margin-left:-2.5rem;margin-right:-2.5rem}.xl\:-my-12{margin-top:-3rem;margin-bottom:-3rem}.xl\:-mx-12{margin-left:-3rem;margin-right:-3rem}.xl\:-my-16{margin-top:-4rem;margin-bottom:-4rem}.xl\:-mx-16{margin-left:-4rem;margin-right:-4rem}.xl\:-my-20{margin-top:-5rem;margin-bottom:-5rem}.xl\:-mx-20{margin-left:-5rem;margin-right:-5rem}.xl\:-my-24{margin-top:-6rem;margin-bottom:-6rem}.xl\:-mx-24{margin-left:-6rem;margin-right:-6rem}.xl\:-my-32{margin-top:-8rem;margin-bottom:-8rem}.xl\:-mx-32{margin-left:-8rem;margin-right:-8rem}.xl\:-my-40{margin-top:-10rem;margin-bottom:-10rem}.xl\:-mx-40{margin-left:-10rem;margin-right:-10rem}.xl\:-my-48{margin-top:-12rem;margin-bottom:-12rem}.xl\:-mx-48{margin-left:-12rem;margin-right:-12rem}.xl\:-my-56{margin-top:-14rem;margin-bottom:-14rem}.xl\:-mx-56{margin-left:-14rem;margin-right:-14rem}.xl\:-my-64{margin-top:-16rem;margin-bottom:-16rem}.xl\:-mx-64{margin-left:-16rem;margin-right:-16rem}.xl\:-my-px{margin-top:-1px;margin-bottom:-1px}.xl\:-mx-px{margin-left:-1px;margin-right:-1px}.xl\:mt-0{margin-top:0}.xl\:mr-0{margin-right:0}.xl\:mb-0{margin-bottom:0}.xl\:ml-0{margin-left:0}.xl\:mt-1{margin-top:.25rem}.xl\:mr-1{margin-right:.25rem}.xl\:mb-1{margin-bottom:.25rem}.xl\:ml-1{margin-left:.25rem}.xl\:mt-2{margin-top:.5rem}.xl\:mr-2{margin-right:.5rem}.xl\:mb-2{margin-bottom:.5rem}.xl\:ml-2{margin-left:.5rem}.xl\:mt-3{margin-top:.75rem}.xl\:mr-3{margin-right:.75rem}.xl\:mb-3{margin-bottom:.75rem}.xl\:ml-3{margin-left:.75rem}.xl\:mt-4{margin-top:1rem}.xl\:mr-4{margin-right:1rem}.xl\:mb-4{margin-bottom:1rem}.xl\:ml-4{margin-left:1rem}.xl\:mt-5{margin-top:1.25rem}.xl\:mr-5{margin-right:1.25rem}.xl\:mb-5{margin-bottom:1.25rem}.xl\:ml-5{margin-left:1.25rem}.xl\:mt-6{margin-top:1.5rem}.xl\:mr-6{margin-right:1.5rem}.xl\:mb-6{margin-bottom:1.5rem}.xl\:ml-6{margin-left:1.5rem}.xl\:mt-8{margin-top:2rem}.xl\:mr-8{margin-right:2rem}.xl\:mb-8{margin-bottom:2rem}.xl\:ml-8{margin-left:2rem}.xl\:mt-10{margin-top:2.5rem}.xl\:mr-10{margin-right:2.5rem}.xl\:mb-10{margin-bottom:2.5rem}.xl\:ml-10{margin-left:2.5rem}.xl\:mt-12{margin-top:3rem}.xl\:mr-12{margin-right:3rem}.xl\:mb-12{margin-bottom:3rem}.xl\:ml-12{margin-left:3rem}.xl\:mt-16{margin-top:4rem}.xl\:mr-16{margin-right:4rem}.xl\:mb-16{margin-bottom:4rem}.xl\:ml-16{margin-left:4rem}.xl\:mt-20{margin-top:5rem}.xl\:mr-20{margin-right:5rem}.xl\:mb-20{margin-bottom:5rem}.xl\:ml-20{margin-left:5rem}.xl\:mt-24{margin-top:6rem}.xl\:mr-24{margin-right:6rem}.xl\:mb-24{margin-bottom:6rem}.xl\:ml-24{margin-left:6rem}.xl\:mt-32{margin-top:8rem}.xl\:mr-32{margin-right:8rem}.xl\:mb-32{margin-bottom:8rem}.xl\:ml-32{margin-left:8rem}.xl\:mt-40{margin-top:10rem}.xl\:mr-40{margin-right:10rem}.xl\:mb-40{margin-bottom:10rem}.xl\:ml-40{margin-left:10rem}.xl\:mt-48{margin-top:12rem}.xl\:mr-48{margin-right:12rem}.xl\:mb-48{margin-bottom:12rem}.xl\:ml-48{margin-left:12rem}.xl\:mt-56{margin-top:14rem}.xl\:mr-56{margin-right:14rem}.xl\:mb-56{margin-bottom:14rem}.xl\:ml-56{margin-left:14rem}.xl\:mt-64{margin-top:16rem}.xl\:mr-64{margin-right:16rem}.xl\:mb-64{margin-bottom:16rem}.xl\:ml-64{margin-left:16rem}.xl\:mt-auto{margin-top:auto}.xl\:mr-auto{margin-right:auto}.xl\:mb-auto{margin-bottom:auto}.xl\:ml-auto{margin-left:auto}.xl\:mt-px{margin-top:1px}.xl\:mr-px{margin-right:1px}.xl\:mb-px{margin-bottom:1px}.xl\:ml-px{margin-left:1px}.xl\:-mt-1{margin-top:-.25rem}.xl\:-mr-1{margin-right:-.25rem}.xl\:-mb-1{margin-bottom:-.25rem}.xl\:-ml-1{margin-left:-.25rem}.xl\:-mt-2{margin-top:-.5rem}.xl\:-mr-2{margin-right:-.5rem}.xl\:-mb-2{margin-bottom:-.5rem}.xl\:-ml-2{margin-left:-.5rem}.xl\:-mt-3{margin-top:-.75rem}.xl\:-mr-3{margin-right:-.75rem}.xl\:-mb-3{margin-bottom:-.75rem}.xl\:-ml-3{margin-left:-.75rem}.xl\:-mt-4{margin-top:-1rem}.xl\:-mr-4{margin-right:-1rem}.xl\:-mb-4{margin-bottom:-1rem}.xl\:-ml-4{margin-left:-1rem}.xl\:-mt-5{margin-top:-1.25rem}.xl\:-mr-5{margin-right:-1.25rem}.xl\:-mb-5{margin-bottom:-1.25rem}.xl\:-ml-5{margin-left:-1.25rem}.xl\:-mt-6{margin-top:-1.5rem}.xl\:-mr-6{margin-right:-1.5rem}.xl\:-mb-6{margin-bottom:-1.5rem}.xl\:-ml-6{margin-left:-1.5rem}.xl\:-mt-8{margin-top:-2rem}.xl\:-mr-8{margin-right:-2rem}.xl\:-mb-8{margin-bottom:-2rem}.xl\:-ml-8{margin-left:-2rem}.xl\:-mt-10{margin-top:-2.5rem}.xl\:-mr-10{margin-right:-2.5rem}.xl\:-mb-10{margin-bottom:-2.5rem}.xl\:-ml-10{margin-left:-2.5rem}.xl\:-mt-12{margin-top:-3rem}.xl\:-mr-12{margin-right:-3rem}.xl\:-mb-12{margin-bottom:-3rem}.xl\:-ml-12{margin-left:-3rem}.xl\:-mt-16{margin-top:-4rem}.xl\:-mr-16{margin-right:-4rem}.xl\:-mb-16{margin-bottom:-4rem}.xl\:-ml-16{margin-left:-4rem}.xl\:-mt-20{margin-top:-5rem}.xl\:-mr-20{margin-right:-5rem}.xl\:-mb-20{margin-bottom:-5rem}.xl\:-ml-20{margin-left:-5rem}.xl\:-mt-24{margin-top:-6rem}.xl\:-mr-24{margin-right:-6rem}.xl\:-mb-24{margin-bottom:-6rem}.xl\:-ml-24{margin-left:-6rem}.xl\:-mt-32{margin-top:-8rem}.xl\:-mr-32{margin-right:-8rem}.xl\:-mb-32{margin-bottom:-8rem}.xl\:-ml-32{margin-left:-8rem}.xl\:-mt-40{margin-top:-10rem}.xl\:-mr-40{margin-right:-10rem}.xl\:-mb-40{margin-bottom:-10rem}.xl\:-ml-40{margin-left:-10rem}.xl\:-mt-48{margin-top:-12rem}.xl\:-mr-48{margin-right:-12rem}.xl\:-mb-48{margin-bottom:-12rem}.xl\:-ml-48{margin-left:-12rem}.xl\:-mt-56{margin-top:-14rem}.xl\:-mr-56{margin-right:-14rem}.xl\:-mb-56{margin-bottom:-14rem}.xl\:-ml-56{margin-left:-14rem}.xl\:-mt-64{margin-top:-16rem}.xl\:-mr-64{margin-right:-16rem}.xl\:-mb-64{margin-bottom:-16rem}.xl\:-ml-64{margin-left:-16rem}.xl\:-mt-px{margin-top:-1px}.xl\:-mr-px{margin-right:-1px}.xl\:-mb-px{margin-bottom:-1px}.xl\:-ml-px{margin-left:-1px}.xl\:max-h-full{max-height:100%}.xl\:max-h-screen{max-height:100vh}.xl\:max-w-none{max-width:none}.xl\:max-w-xs{max-width:20rem}.xl\:max-w-sm{max-width:24rem}.xl\:max-w-md{max-width:28rem}.xl\:max-w-lg{max-width:32rem}.xl\:max-w-xl{max-width:36rem}.xl\:max-w-2xl{max-width:42rem}.xl\:max-w-3xl{max-width:48rem}.xl\:max-w-4xl{max-width:56rem}.xl\:max-w-5xl{max-width:64rem}.xl\:max-w-6xl{max-width:72rem}.xl\:max-w-full{max-width:100%}.xl\:max-w-screen-sm{max-width:640px}.xl\:max-w-screen-md{max-width:768px}.xl\:max-w-screen-lg{max-width:1024px}.xl\:max-w-screen-xl{max-width:1280px}.xl\:min-h-0{min-height:0}.xl\:min-h-full{min-height:100%}.xl\:min-h-screen{min-height:100vh}.xl\:min-w-0{min-width:0}.xl\:min-w-full{min-width:100%}.xl\:object-contain{object-fit:contain}.xl\:object-cover{object-fit:cover}.xl\:object-fill{object-fit:fill}.xl\:object-none{object-fit:none}.xl\:object-scale-down{object-fit:scale-down}.xl\:object-bottom{object-position:bottom}.xl\:object-center{object-position:center}.xl\:object-left{object-position:left}.xl\:object-left-bottom{object-position:left bottom}.xl\:object-left-top{object-position:left top}.xl\:object-right{object-position:right}.xl\:object-right-bottom{object-position:right bottom}.xl\:object-right-top{object-position:right top}.xl\:object-top{object-position:top}.xl\:opacity-0{opacity:0}.xl\:opacity-25{opacity:.25}.xl\:opacity-50{opacity:.5}.xl\:opacity-75{opacity:.75}.xl\:opacity-100{opacity:1}.xl\:hover\:opacity-0:hover{opacity:0}.xl\:hover\:opacity-25:hover{opacity:.25}.xl\:hover\:opacity-50:hover{opacity:.5}.xl\:hover\:opacity-75:hover{opacity:.75}.xl\:hover\:opacity-100:hover{opacity:1}.xl\:focus\:opacity-0:focus{opacity:0}.xl\:focus\:opacity-25:focus{opacity:.25}.xl\:focus\:opacity-50:focus{opacity:.5}.xl\:focus\:opacity-75:focus{opacity:.75}.xl\:focus\:opacity-100:focus{opacity:1}.xl\:outline-none{outline:2px solid transparent;outline-offset:2px}.xl\:outline-white{outline:2px dotted #fff;outline-offset:2px}.xl\:outline-black{outline:2px dotted #000;outline-offset:2px}.xl\:focus\:outline-none:focus{outline:2px solid transparent;outline-offset:2px}.xl\:focus\:outline-white:focus{outline:2px dotted #fff;outline-offset:2px}.xl\:focus\:outline-black:focus{outline:2px dotted #000;outline-offset:2px}.xl\:overflow-auto{overflow:auto}.xl\:overflow-hidden{overflow:hidden}.xl\:overflow-visible{overflow:visible}.xl\:overflow-scroll{overflow:scroll}.xl\:overflow-x-auto{overflow-x:auto}.xl\:overflow-y-auto{overflow-y:auto}.xl\:overflow-x-hidden{overflow-x:hidden}.xl\:overflow-y-hidden{overflow-y:hidden}.xl\:overflow-x-visible{overflow-x:visible}.xl\:overflow-y-visible{overflow-y:visible}.xl\:overflow-x-scroll{overflow-x:scroll}.xl\:overflow-y-scroll{overflow-y:scroll}.xl\:scrolling-touch{-webkit-overflow-scrolling:touch}.xl\:scrolling-auto{-webkit-overflow-scrolling:auto}.xl\:overscroll-auto{-ms-scroll-chaining:chained;overscroll-behavior:auto}.xl\:overscroll-contain{-ms-scroll-chaining:none;overscroll-behavior:contain}.xl\:overscroll-none{-ms-scroll-chaining:none;overscroll-behavior:none}.xl\:overscroll-y-auto{overscroll-behavior-y:auto}.xl\:overscroll-y-contain{overscroll-behavior-y:contain}.xl\:overscroll-y-none{overscroll-behavior-y:none}.xl\:overscroll-x-auto{overscroll-behavior-x:auto}.xl\:overscroll-x-contain{overscroll-behavior-x:contain}.xl\:overscroll-x-none{overscroll-behavior-x:none}.xl\:p-0{padding:0}.xl\:p-1{padding:.25rem}.xl\:p-2{padding:.5rem}.xl\:p-3{padding:.75rem}.xl\:p-4{padding:1rem}.xl\:p-5{padding:1.25rem}.xl\:p-6{padding:1.5rem}.xl\:p-8{padding:2rem}.xl\:p-10{padding:2.5rem}.xl\:p-12{padding:3rem}.xl\:p-16{padding:4rem}.xl\:p-20{padding:5rem}.xl\:p-24{padding:6rem}.xl\:p-32{padding:8rem}.xl\:p-40{padding:10rem}.xl\:p-48{padding:12rem}.xl\:p-56{padding:14rem}.xl\:p-64{padding:16rem}.xl\:p-px{padding:1px}.xl\:py-0{padding-top:0;padding-bottom:0}.xl\:px-0{padding-left:0;padding-right:0}.xl\:py-1{padding-top:.25rem;padding-bottom:.25rem}.xl\:px-1{padding-left:.25rem;padding-right:.25rem}.xl\:py-2{padding-top:.5rem;padding-bottom:.5rem}.xl\:px-2{padding-left:.5rem;padding-right:.5rem}.xl\:py-3{padding-top:.75rem;padding-bottom:.75rem}.xl\:px-3{padding-left:.75rem;padding-right:.75rem}.xl\:py-4{padding-top:1rem;padding-bottom:1rem}.xl\:px-4{padding-left:1rem;padding-right:1rem}.xl\:py-5{padding-top:1.25rem;padding-bottom:1.25rem}.xl\:px-5{padding-left:1.25rem;padding-right:1.25rem}.xl\:py-6{padding-top:1.5rem;padding-bottom:1.5rem}.xl\:px-6{padding-left:1.5rem;padding-right:1.5rem}.xl\:py-8{padding-top:2rem;padding-bottom:2rem}.xl\:px-8{padding-left:2rem;padding-right:2rem}.xl\:py-10{padding-top:2.5rem;padding-bottom:2.5rem}.xl\:px-10{padding-left:2.5rem;padding-right:2.5rem}.xl\:py-12{padding-top:3rem;padding-bottom:3rem}.xl\:px-12{padding-left:3rem;padding-right:3rem}.xl\:py-16{padding-top:4rem;padding-bottom:4rem}.xl\:px-16{padding-left:4rem;padding-right:4rem}.xl\:py-20{padding-top:5rem;padding-bottom:5rem}.xl\:px-20{padding-left:5rem;padding-right:5rem}.xl\:py-24{padding-top:6rem;padding-bottom:6rem}.xl\:px-24{padding-left:6rem;padding-right:6rem}.xl\:py-32{padding-top:8rem;padding-bottom:8rem}.xl\:px-32{padding-left:8rem;padding-right:8rem}.xl\:py-40{padding-top:10rem;padding-bottom:10rem}.xl\:px-40{padding-left:10rem;padding-right:10rem}.xl\:py-48{padding-top:12rem;padding-bottom:12rem}.xl\:px-48{padding-left:12rem;padding-right:12rem}.xl\:py-56{padding-top:14rem;padding-bottom:14rem}.xl\:px-56{padding-left:14rem;padding-right:14rem}.xl\:py-64{padding-top:16rem;padding-bottom:16rem}.xl\:px-64{padding-left:16rem;padding-right:16rem}.xl\:py-px{padding-top:1px;padding-bottom:1px}.xl\:px-px{padding-left:1px;padding-right:1px}.xl\:pt-0{padding-top:0}.xl\:pr-0{padding-right:0}.xl\:pb-0{padding-bottom:0}.xl\:pl-0{padding-left:0}.xl\:pt-1{padding-top:.25rem}.xl\:pr-1{padding-right:.25rem}.xl\:pb-1{padding-bottom:.25rem}.xl\:pl-1{padding-left:.25rem}.xl\:pt-2{padding-top:.5rem}.xl\:pr-2{padding-right:.5rem}.xl\:pb-2{padding-bottom:.5rem}.xl\:pl-2{padding-left:.5rem}.xl\:pt-3{padding-top:.75rem}.xl\:pr-3{padding-right:.75rem}.xl\:pb-3{padding-bottom:.75rem}.xl\:pl-3{padding-left:.75rem}.xl\:pt-4{padding-top:1rem}.xl\:pr-4{padding-right:1rem}.xl\:pb-4{padding-bottom:1rem}.xl\:pl-4{padding-left:1rem}.xl\:pt-5{padding-top:1.25rem}.xl\:pr-5{padding-right:1.25rem}.xl\:pb-5{padding-bottom:1.25rem}.xl\:pl-5{padding-left:1.25rem}.xl\:pt-6{padding-top:1.5rem}.xl\:pr-6{padding-right:1.5rem}.xl\:pb-6{padding-bottom:1.5rem}.xl\:pl-6{padding-left:1.5rem}.xl\:pt-8{padding-top:2rem}.xl\:pr-8{padding-right:2rem}.xl\:pb-8{padding-bottom:2rem}.xl\:pl-8{padding-left:2rem}.xl\:pt-10{padding-top:2.5rem}.xl\:pr-10{padding-right:2.5rem}.xl\:pb-10{padding-bottom:2.5rem}.xl\:pl-10{padding-left:2.5rem}.xl\:pt-12{padding-top:3rem}.xl\:pr-12{padding-right:3rem}.xl\:pb-12{padding-bottom:3rem}.xl\:pl-12{padding-left:3rem}.xl\:pt-16{padding-top:4rem}.xl\:pr-16{padding-right:4rem}.xl\:pb-16{padding-bottom:4rem}.xl\:pl-16{padding-left:4rem}.xl\:pt-20{padding-top:5rem}.xl\:pr-20{padding-right:5rem}.xl\:pb-20{padding-bottom:5rem}.xl\:pl-20{padding-left:5rem}.xl\:pt-24{padding-top:6rem}.xl\:pr-24{padding-right:6rem}.xl\:pb-24{padding-bottom:6rem}.xl\:pl-24{padding-left:6rem}.xl\:pt-32{padding-top:8rem}.xl\:pr-32{padding-right:8rem}.xl\:pb-32{padding-bottom:8rem}.xl\:pl-32{padding-left:8rem}.xl\:pt-40{padding-top:10rem}.xl\:pr-40{padding-right:10rem}.xl\:pb-40{padding-bottom:10rem}.xl\:pl-40{padding-left:10rem}.xl\:pt-48{padding-top:12rem}.xl\:pr-48{padding-right:12rem}.xl\:pb-48{padding-bottom:12rem}.xl\:pl-48{padding-left:12rem}.xl\:pt-56{padding-top:14rem}.xl\:pr-56{padding-right:14rem}.xl\:pb-56{padding-bottom:14rem}.xl\:pl-56{padding-left:14rem}.xl\:pt-64{padding-top:16rem}.xl\:pr-64{padding-right:16rem}.xl\:pb-64{padding-bottom:16rem}.xl\:pl-64{padding-left:16rem}.xl\:pt-px{padding-top:1px}.xl\:pr-px{padding-right:1px}.xl\:pb-px{padding-bottom:1px}.xl\:pl-px{padding-left:1px}.xl\:placeholder-transparent:-ms-input-placeholder{color:transparent}.xl\:placeholder-transparent::-ms-input-placeholder{color:transparent}.xl\:placeholder-transparent::placeholder{color:transparent}.xl\:placeholder-current:-ms-input-placeholder{color:currentColor}.xl\:placeholder-current::-ms-input-placeholder{color:currentColor}.xl\:placeholder-current::placeholder{color:currentColor}.xl\:placeholder-black:-ms-input-placeholder{--placeholder-opacity:1;color:#000;color:rgba(0,0,0,var(--placeholder-opacity))}.xl\:placeholder-black::-ms-input-placeholder{--placeholder-opacity:1;color:#000;color:rgba(0,0,0,var(--placeholder-opacity))}.xl\:placeholder-black::placeholder{--placeholder-opacity:1;color:#000;color:rgba(0,0,0,var(--placeholder-opacity))}.xl\:placeholder-white:-ms-input-placeholder{--placeholder-opacity:1;color:#fff;color:rgba(255,255,255,var(--placeholder-opacity))}.xl\:placeholder-white::-ms-input-placeholder{--placeholder-opacity:1;color:#fff;color:rgba(255,255,255,var(--placeholder-opacity))}.xl\:placeholder-white::placeholder{--placeholder-opacity:1;color:#fff;color:rgba(255,255,255,var(--placeholder-opacity))}.xl\:placeholder-gray-100:-ms-input-placeholder{--placeholder-opacity:1;color:#f7fafc;color:rgba(247,250,252,var(--placeholder-opacity))}.xl\:placeholder-gray-100::-ms-input-placeholder{--placeholder-opacity:1;color:#f7fafc;color:rgba(247,250,252,var(--placeholder-opacity))}.xl\:placeholder-gray-100::placeholder{--placeholder-opacity:1;color:#f7fafc;color:rgba(247,250,252,var(--placeholder-opacity))}.xl\:placeholder-gray-200:-ms-input-placeholder{--placeholder-opacity:1;color:#edf2f7;color:rgba(237,242,247,var(--placeholder-opacity))}.xl\:placeholder-gray-200::-ms-input-placeholder{--placeholder-opacity:1;color:#edf2f7;color:rgba(237,242,247,var(--placeholder-opacity))}.xl\:placeholder-gray-200::placeholder{--placeholder-opacity:1;color:#edf2f7;color:rgba(237,242,247,var(--placeholder-opacity))}.xl\:placeholder-gray-300:-ms-input-placeholder{--placeholder-opacity:1;color:#e2e8f0;color:rgba(226,232,240,var(--placeholder-opacity))}.xl\:placeholder-gray-300::-ms-input-placeholder{--placeholder-opacity:1;color:#e2e8f0;color:rgba(226,232,240,var(--placeholder-opacity))}.xl\:placeholder-gray-300::placeholder{--placeholder-opacity:1;color:#e2e8f0;color:rgba(226,232,240,var(--placeholder-opacity))}.xl\:placeholder-gray-400:-ms-input-placeholder{--placeholder-opacity:1;color:#cbd5e0;color:rgba(203,213,224,var(--placeholder-opacity))}.xl\:placeholder-gray-400::-ms-input-placeholder{--placeholder-opacity:1;color:#cbd5e0;color:rgba(203,213,224,var(--placeholder-opacity))}.xl\:placeholder-gray-400::placeholder{--placeholder-opacity:1;color:#cbd5e0;color:rgba(203,213,224,var(--placeholder-opacity))}.xl\:placeholder-gray-500:-ms-input-placeholder{--placeholder-opacity:1;color:#a0aec0;color:rgba(160,174,192,var(--placeholder-opacity))}.xl\:placeholder-gray-500::-ms-input-placeholder{--placeholder-opacity:1;color:#a0aec0;color:rgba(160,174,192,var(--placeholder-opacity))}.xl\:placeholder-gray-500::placeholder{--placeholder-opacity:1;color:#a0aec0;color:rgba(160,174,192,var(--placeholder-opacity))}.xl\:placeholder-gray-600:-ms-input-placeholder{--placeholder-opacity:1;color:#718096;color:rgba(113,128,150,var(--placeholder-opacity))}.xl\:placeholder-gray-600::-ms-input-placeholder{--placeholder-opacity:1;color:#718096;color:rgba(113,128,150,var(--placeholder-opacity))}.xl\:placeholder-gray-600::placeholder{--placeholder-opacity:1;color:#718096;color:rgba(113,128,150,var(--placeholder-opacity))}.xl\:placeholder-gray-700:-ms-input-placeholder{--placeholder-opacity:1;color:#4a5568;color:rgba(74,85,104,var(--placeholder-opacity))}.xl\:placeholder-gray-700::-ms-input-placeholder{--placeholder-opacity:1;color:#4a5568;color:rgba(74,85,104,var(--placeholder-opacity))}.xl\:placeholder-gray-700::placeholder{--placeholder-opacity:1;color:#4a5568;color:rgba(74,85,104,var(--placeholder-opacity))}.xl\:placeholder-gray-800:-ms-input-placeholder{--placeholder-opacity:1;color:#2d3748;color:rgba(45,55,72,var(--placeholder-opacity))}.xl\:placeholder-gray-800::-ms-input-placeholder{--placeholder-opacity:1;color:#2d3748;color:rgba(45,55,72,var(--placeholder-opacity))}.xl\:placeholder-gray-800::placeholder{--placeholder-opacity:1;color:#2d3748;color:rgba(45,55,72,var(--placeholder-opacity))}.xl\:placeholder-gray-900:-ms-input-placeholder{--placeholder-opacity:1;color:#1a202c;color:rgba(26,32,44,var(--placeholder-opacity))}.xl\:placeholder-gray-900::-ms-input-placeholder{--placeholder-opacity:1;color:#1a202c;color:rgba(26,32,44,var(--placeholder-opacity))}.xl\:placeholder-gray-900::placeholder{--placeholder-opacity:1;color:#1a202c;color:rgba(26,32,44,var(--placeholder-opacity))}.xl\:placeholder-red-100:-ms-input-placeholder{--placeholder-opacity:1;color:#fff5f5;color:rgba(255,245,245,var(--placeholder-opacity))}.xl\:placeholder-red-100::-ms-input-placeholder{--placeholder-opacity:1;color:#fff5f5;color:rgba(255,245,245,var(--placeholder-opacity))}.xl\:placeholder-red-100::placeholder{--placeholder-opacity:1;color:#fff5f5;color:rgba(255,245,245,var(--placeholder-opacity))}.xl\:placeholder-red-200:-ms-input-placeholder{--placeholder-opacity:1;color:#fed7d7;color:rgba(254,215,215,var(--placeholder-opacity))}.xl\:placeholder-red-200::-ms-input-placeholder{--placeholder-opacity:1;color:#fed7d7;color:rgba(254,215,215,var(--placeholder-opacity))}.xl\:placeholder-red-200::placeholder{--placeholder-opacity:1;color:#fed7d7;color:rgba(254,215,215,var(--placeholder-opacity))}.xl\:placeholder-red-300:-ms-input-placeholder{--placeholder-opacity:1;color:#feb2b2;color:rgba(254,178,178,var(--placeholder-opacity))}.xl\:placeholder-red-300::-ms-input-placeholder{--placeholder-opacity:1;color:#feb2b2;color:rgba(254,178,178,var(--placeholder-opacity))}.xl\:placeholder-red-300::placeholder{--placeholder-opacity:1;color:#feb2b2;color:rgba(254,178,178,var(--placeholder-opacity))}.xl\:placeholder-red-400:-ms-input-placeholder{--placeholder-opacity:1;color:#fc8181;color:rgba(252,129,129,var(--placeholder-opacity))}.xl\:placeholder-red-400::-ms-input-placeholder{--placeholder-opacity:1;color:#fc8181;color:rgba(252,129,129,var(--placeholder-opacity))}.xl\:placeholder-red-400::placeholder{--placeholder-opacity:1;color:#fc8181;color:rgba(252,129,129,var(--placeholder-opacity))}.xl\:placeholder-red-500:-ms-input-placeholder{--placeholder-opacity:1;color:#f56565;color:rgba(245,101,101,var(--placeholder-opacity))}.xl\:placeholder-red-500::-ms-input-placeholder{--placeholder-opacity:1;color:#f56565;color:rgba(245,101,101,var(--placeholder-opacity))}.xl\:placeholder-red-500::placeholder{--placeholder-opacity:1;color:#f56565;color:rgba(245,101,101,var(--placeholder-opacity))}.xl\:placeholder-red-600:-ms-input-placeholder{--placeholder-opacity:1;color:#e53e3e;color:rgba(229,62,62,var(--placeholder-opacity))}.xl\:placeholder-red-600::-ms-input-placeholder{--placeholder-opacity:1;color:#e53e3e;color:rgba(229,62,62,var(--placeholder-opacity))}.xl\:placeholder-red-600::placeholder{--placeholder-opacity:1;color:#e53e3e;color:rgba(229,62,62,var(--placeholder-opacity))}.xl\:placeholder-red-700:-ms-input-placeholder{--placeholder-opacity:1;color:#c53030;color:rgba(197,48,48,var(--placeholder-opacity))}.xl\:placeholder-red-700::-ms-input-placeholder{--placeholder-opacity:1;color:#c53030;color:rgba(197,48,48,var(--placeholder-opacity))}.xl\:placeholder-red-700::placeholder{--placeholder-opacity:1;color:#c53030;color:rgba(197,48,48,var(--placeholder-opacity))}.xl\:placeholder-red-800:-ms-input-placeholder{--placeholder-opacity:1;color:#9b2c2c;color:rgba(155,44,44,var(--placeholder-opacity))}.xl\:placeholder-red-800::-ms-input-placeholder{--placeholder-opacity:1;color:#9b2c2c;color:rgba(155,44,44,var(--placeholder-opacity))}.xl\:placeholder-red-800::placeholder{--placeholder-opacity:1;color:#9b2c2c;color:rgba(155,44,44,var(--placeholder-opacity))}.xl\:placeholder-red-900:-ms-input-placeholder{--placeholder-opacity:1;color:#742a2a;color:rgba(116,42,42,var(--placeholder-opacity))}.xl\:placeholder-red-900::-ms-input-placeholder{--placeholder-opacity:1;color:#742a2a;color:rgba(116,42,42,var(--placeholder-opacity))}.xl\:placeholder-red-900::placeholder{--placeholder-opacity:1;color:#742a2a;color:rgba(116,42,42,var(--placeholder-opacity))}.xl\:placeholder-orange-100:-ms-input-placeholder{--placeholder-opacity:1;color:#fffaf0;color:rgba(255,250,240,var(--placeholder-opacity))}.xl\:placeholder-orange-100::-ms-input-placeholder{--placeholder-opacity:1;color:#fffaf0;color:rgba(255,250,240,var(--placeholder-opacity))}.xl\:placeholder-orange-100::placeholder{--placeholder-opacity:1;color:#fffaf0;color:rgba(255,250,240,var(--placeholder-opacity))}.xl\:placeholder-orange-200:-ms-input-placeholder{--placeholder-opacity:1;color:#feebc8;color:rgba(254,235,200,var(--placeholder-opacity))}.xl\:placeholder-orange-200::-ms-input-placeholder{--placeholder-opacity:1;color:#feebc8;color:rgba(254,235,200,var(--placeholder-opacity))}.xl\:placeholder-orange-200::placeholder{--placeholder-opacity:1;color:#feebc8;color:rgba(254,235,200,var(--placeholder-opacity))}.xl\:placeholder-orange-300:-ms-input-placeholder{--placeholder-opacity:1;color:#fbd38d;color:rgba(251,211,141,var(--placeholder-opacity))}.xl\:placeholder-orange-300::-ms-input-placeholder{--placeholder-opacity:1;color:#fbd38d;color:rgba(251,211,141,var(--placeholder-opacity))}.xl\:placeholder-orange-300::placeholder{--placeholder-opacity:1;color:#fbd38d;color:rgba(251,211,141,var(--placeholder-opacity))}.xl\:placeholder-orange-400:-ms-input-placeholder{--placeholder-opacity:1;color:#f6ad55;color:rgba(246,173,85,var(--placeholder-opacity))}.xl\:placeholder-orange-400::-ms-input-placeholder{--placeholder-opacity:1;color:#f6ad55;color:rgba(246,173,85,var(--placeholder-opacity))}.xl\:placeholder-orange-400::placeholder{--placeholder-opacity:1;color:#f6ad55;color:rgba(246,173,85,var(--placeholder-opacity))}.xl\:placeholder-orange-500:-ms-input-placeholder{--placeholder-opacity:1;color:#ed8936;color:rgba(237,137,54,var(--placeholder-opacity))}.xl\:placeholder-orange-500::-ms-input-placeholder{--placeholder-opacity:1;color:#ed8936;color:rgba(237,137,54,var(--placeholder-opacity))}.xl\:placeholder-orange-500::placeholder{--placeholder-opacity:1;color:#ed8936;color:rgba(237,137,54,var(--placeholder-opacity))}.xl\:placeholder-orange-600:-ms-input-placeholder{--placeholder-opacity:1;color:#dd6b20;color:rgba(221,107,32,var(--placeholder-opacity))}.xl\:placeholder-orange-600::-ms-input-placeholder{--placeholder-opacity:1;color:#dd6b20;color:rgba(221,107,32,var(--placeholder-opacity))}.xl\:placeholder-orange-600::placeholder{--placeholder-opacity:1;color:#dd6b20;color:rgba(221,107,32,var(--placeholder-opacity))}.xl\:placeholder-orange-700:-ms-input-placeholder{--placeholder-opacity:1;color:#c05621;color:rgba(192,86,33,var(--placeholder-opacity))}.xl\:placeholder-orange-700::-ms-input-placeholder{--placeholder-opacity:1;color:#c05621;color:rgba(192,86,33,var(--placeholder-opacity))}.xl\:placeholder-orange-700::placeholder{--placeholder-opacity:1;color:#c05621;color:rgba(192,86,33,var(--placeholder-opacity))}.xl\:placeholder-orange-800:-ms-input-placeholder{--placeholder-opacity:1;color:#9c4221;color:rgba(156,66,33,var(--placeholder-opacity))}.xl\:placeholder-orange-800::-ms-input-placeholder{--placeholder-opacity:1;color:#9c4221;color:rgba(156,66,33,var(--placeholder-opacity))}.xl\:placeholder-orange-800::placeholder{--placeholder-opacity:1;color:#9c4221;color:rgba(156,66,33,var(--placeholder-opacity))}.xl\:placeholder-orange-900:-ms-input-placeholder{--placeholder-opacity:1;color:#7b341e;color:rgba(123,52,30,var(--placeholder-opacity))}.xl\:placeholder-orange-900::-ms-input-placeholder{--placeholder-opacity:1;color:#7b341e;color:rgba(123,52,30,var(--placeholder-opacity))}.xl\:placeholder-orange-900::placeholder{--placeholder-opacity:1;color:#7b341e;color:rgba(123,52,30,var(--placeholder-opacity))}.xl\:placeholder-yellow-100:-ms-input-placeholder{--placeholder-opacity:1;color:ivory;color:rgba(255,255,240,var(--placeholder-opacity))}.xl\:placeholder-yellow-100::-ms-input-placeholder{--placeholder-opacity:1;color:ivory;color:rgba(255,255,240,var(--placeholder-opacity))}.xl\:placeholder-yellow-100::placeholder{--placeholder-opacity:1;color:ivory;color:rgba(255,255,240,var(--placeholder-opacity))}.xl\:placeholder-yellow-200:-ms-input-placeholder{--placeholder-opacity:1;color:#fefcbf;color:rgba(254,252,191,var(--placeholder-opacity))}.xl\:placeholder-yellow-200::-ms-input-placeholder{--placeholder-opacity:1;color:#fefcbf;color:rgba(254,252,191,var(--placeholder-opacity))}.xl\:placeholder-yellow-200::placeholder{--placeholder-opacity:1;color:#fefcbf;color:rgba(254,252,191,var(--placeholder-opacity))}.xl\:placeholder-yellow-300:-ms-input-placeholder{--placeholder-opacity:1;color:#faf089;color:rgba(250,240,137,var(--placeholder-opacity))}.xl\:placeholder-yellow-300::-ms-input-placeholder{--placeholder-opacity:1;color:#faf089;color:rgba(250,240,137,var(--placeholder-opacity))}.xl\:placeholder-yellow-300::placeholder{--placeholder-opacity:1;color:#faf089;color:rgba(250,240,137,var(--placeholder-opacity))}.xl\:placeholder-yellow-400:-ms-input-placeholder{--placeholder-opacity:1;color:#f6e05e;color:rgba(246,224,94,var(--placeholder-opacity))}.xl\:placeholder-yellow-400::-ms-input-placeholder{--placeholder-opacity:1;color:#f6e05e;color:rgba(246,224,94,var(--placeholder-opacity))}.xl\:placeholder-yellow-400::placeholder{--placeholder-opacity:1;color:#f6e05e;color:rgba(246,224,94,var(--placeholder-opacity))}.xl\:placeholder-yellow-500:-ms-input-placeholder{--placeholder-opacity:1;color:#ecc94b;color:rgba(236,201,75,var(--placeholder-opacity))}.xl\:placeholder-yellow-500::-ms-input-placeholder{--placeholder-opacity:1;color:#ecc94b;color:rgba(236,201,75,var(--placeholder-opacity))}.xl\:placeholder-yellow-500::placeholder{--placeholder-opacity:1;color:#ecc94b;color:rgba(236,201,75,var(--placeholder-opacity))}.xl\:placeholder-yellow-600:-ms-input-placeholder{--placeholder-opacity:1;color:#d69e2e;color:rgba(214,158,46,var(--placeholder-opacity))}.xl\:placeholder-yellow-600::-ms-input-placeholder{--placeholder-opacity:1;color:#d69e2e;color:rgba(214,158,46,var(--placeholder-opacity))}.xl\:placeholder-yellow-600::placeholder{--placeholder-opacity:1;color:#d69e2e;color:rgba(214,158,46,var(--placeholder-opacity))}.xl\:placeholder-yellow-700:-ms-input-placeholder{--placeholder-opacity:1;color:#b7791f;color:rgba(183,121,31,var(--placeholder-opacity))}.xl\:placeholder-yellow-700::-ms-input-placeholder{--placeholder-opacity:1;color:#b7791f;color:rgba(183,121,31,var(--placeholder-opacity))}.xl\:placeholder-yellow-700::placeholder{--placeholder-opacity:1;color:#b7791f;color:rgba(183,121,31,var(--placeholder-opacity))}.xl\:placeholder-yellow-800:-ms-input-placeholder{--placeholder-opacity:1;color:#975a16;color:rgba(151,90,22,var(--placeholder-opacity))}.xl\:placeholder-yellow-800::-ms-input-placeholder{--placeholder-opacity:1;color:#975a16;color:rgba(151,90,22,var(--placeholder-opacity))}.xl\:placeholder-yellow-800::placeholder{--placeholder-opacity:1;color:#975a16;color:rgba(151,90,22,var(--placeholder-opacity))}.xl\:placeholder-yellow-900:-ms-input-placeholder{--placeholder-opacity:1;color:#744210;color:rgba(116,66,16,var(--placeholder-opacity))}.xl\:placeholder-yellow-900::-ms-input-placeholder{--placeholder-opacity:1;color:#744210;color:rgba(116,66,16,var(--placeholder-opacity))}.xl\:placeholder-yellow-900::placeholder{--placeholder-opacity:1;color:#744210;color:rgba(116,66,16,var(--placeholder-opacity))}.xl\:placeholder-green-100:-ms-input-placeholder{--placeholder-opacity:1;color:#f0fff4;color:rgba(240,255,244,var(--placeholder-opacity))}.xl\:placeholder-green-100::-ms-input-placeholder{--placeholder-opacity:1;color:#f0fff4;color:rgba(240,255,244,var(--placeholder-opacity))}.xl\:placeholder-green-100::placeholder{--placeholder-opacity:1;color:#f0fff4;color:rgba(240,255,244,var(--placeholder-opacity))}.xl\:placeholder-green-200:-ms-input-placeholder{--placeholder-opacity:1;color:#c6f6d5;color:rgba(198,246,213,var(--placeholder-opacity))}.xl\:placeholder-green-200::-ms-input-placeholder{--placeholder-opacity:1;color:#c6f6d5;color:rgba(198,246,213,var(--placeholder-opacity))}.xl\:placeholder-green-200::placeholder{--placeholder-opacity:1;color:#c6f6d5;color:rgba(198,246,213,var(--placeholder-opacity))}.xl\:placeholder-green-300:-ms-input-placeholder{--placeholder-opacity:1;color:#9ae6b4;color:rgba(154,230,180,var(--placeholder-opacity))}.xl\:placeholder-green-300::-ms-input-placeholder{--placeholder-opacity:1;color:#9ae6b4;color:rgba(154,230,180,var(--placeholder-opacity))}.xl\:placeholder-green-300::placeholder{--placeholder-opacity:1;color:#9ae6b4;color:rgba(154,230,180,var(--placeholder-opacity))}.xl\:placeholder-green-400:-ms-input-placeholder{--placeholder-opacity:1;color:#68d391;color:rgba(104,211,145,var(--placeholder-opacity))}.xl\:placeholder-green-400::-ms-input-placeholder{--placeholder-opacity:1;color:#68d391;color:rgba(104,211,145,var(--placeholder-opacity))}.xl\:placeholder-green-400::placeholder{--placeholder-opacity:1;color:#68d391;color:rgba(104,211,145,var(--placeholder-opacity))}.xl\:placeholder-green-500:-ms-input-placeholder{--placeholder-opacity:1;color:#48bb78;color:rgba(72,187,120,var(--placeholder-opacity))}.xl\:placeholder-green-500::-ms-input-placeholder{--placeholder-opacity:1;color:#48bb78;color:rgba(72,187,120,var(--placeholder-opacity))}.xl\:placeholder-green-500::placeholder{--placeholder-opacity:1;color:#48bb78;color:rgba(72,187,120,var(--placeholder-opacity))}.xl\:placeholder-green-600:-ms-input-placeholder{--placeholder-opacity:1;color:#38a169;color:rgba(56,161,105,var(--placeholder-opacity))}.xl\:placeholder-green-600::-ms-input-placeholder{--placeholder-opacity:1;color:#38a169;color:rgba(56,161,105,var(--placeholder-opacity))}.xl\:placeholder-green-600::placeholder{--placeholder-opacity:1;color:#38a169;color:rgba(56,161,105,var(--placeholder-opacity))}.xl\:placeholder-green-700:-ms-input-placeholder{--placeholder-opacity:1;color:#2f855a;color:rgba(47,133,90,var(--placeholder-opacity))}.xl\:placeholder-green-700::-ms-input-placeholder{--placeholder-opacity:1;color:#2f855a;color:rgba(47,133,90,var(--placeholder-opacity))}.xl\:placeholder-green-700::placeholder{--placeholder-opacity:1;color:#2f855a;color:rgba(47,133,90,var(--placeholder-opacity))}.xl\:placeholder-green-800:-ms-input-placeholder{--placeholder-opacity:1;color:#276749;color:rgba(39,103,73,var(--placeholder-opacity))}.xl\:placeholder-green-800::-ms-input-placeholder{--placeholder-opacity:1;color:#276749;color:rgba(39,103,73,var(--placeholder-opacity))}.xl\:placeholder-green-800::placeholder{--placeholder-opacity:1;color:#276749;color:rgba(39,103,73,var(--placeholder-opacity))}.xl\:placeholder-green-900:-ms-input-placeholder{--placeholder-opacity:1;color:#22543d;color:rgba(34,84,61,var(--placeholder-opacity))}.xl\:placeholder-green-900::-ms-input-placeholder{--placeholder-opacity:1;color:#22543d;color:rgba(34,84,61,var(--placeholder-opacity))}.xl\:placeholder-green-900::placeholder{--placeholder-opacity:1;color:#22543d;color:rgba(34,84,61,var(--placeholder-opacity))}.xl\:placeholder-teal-100:-ms-input-placeholder{--placeholder-opacity:1;color:#e6fffa;color:rgba(230,255,250,var(--placeholder-opacity))}.xl\:placeholder-teal-100::-ms-input-placeholder{--placeholder-opacity:1;color:#e6fffa;color:rgba(230,255,250,var(--placeholder-opacity))}.xl\:placeholder-teal-100::placeholder{--placeholder-opacity:1;color:#e6fffa;color:rgba(230,255,250,var(--placeholder-opacity))}.xl\:placeholder-teal-200:-ms-input-placeholder{--placeholder-opacity:1;color:#b2f5ea;color:rgba(178,245,234,var(--placeholder-opacity))}.xl\:placeholder-teal-200::-ms-input-placeholder{--placeholder-opacity:1;color:#b2f5ea;color:rgba(178,245,234,var(--placeholder-opacity))}.xl\:placeholder-teal-200::placeholder{--placeholder-opacity:1;color:#b2f5ea;color:rgba(178,245,234,var(--placeholder-opacity))}.xl\:placeholder-teal-300:-ms-input-placeholder{--placeholder-opacity:1;color:#81e6d9;color:rgba(129,230,217,var(--placeholder-opacity))}.xl\:placeholder-teal-300::-ms-input-placeholder{--placeholder-opacity:1;color:#81e6d9;color:rgba(129,230,217,var(--placeholder-opacity))}.xl\:placeholder-teal-300::placeholder{--placeholder-opacity:1;color:#81e6d9;color:rgba(129,230,217,var(--placeholder-opacity))}.xl\:placeholder-teal-400:-ms-input-placeholder{--placeholder-opacity:1;color:#4fd1c5;color:rgba(79,209,197,var(--placeholder-opacity))}.xl\:placeholder-teal-400::-ms-input-placeholder{--placeholder-opacity:1;color:#4fd1c5;color:rgba(79,209,197,var(--placeholder-opacity))}.xl\:placeholder-teal-400::placeholder{--placeholder-opacity:1;color:#4fd1c5;color:rgba(79,209,197,var(--placeholder-opacity))}.xl\:placeholder-teal-500:-ms-input-placeholder{--placeholder-opacity:1;color:#38b2ac;color:rgba(56,178,172,var(--placeholder-opacity))}.xl\:placeholder-teal-500::-ms-input-placeholder{--placeholder-opacity:1;color:#38b2ac;color:rgba(56,178,172,var(--placeholder-opacity))}.xl\:placeholder-teal-500::placeholder{--placeholder-opacity:1;color:#38b2ac;color:rgba(56,178,172,var(--placeholder-opacity))}.xl\:placeholder-teal-600:-ms-input-placeholder{--placeholder-opacity:1;color:#319795;color:rgba(49,151,149,var(--placeholder-opacity))}.xl\:placeholder-teal-600::-ms-input-placeholder{--placeholder-opacity:1;color:#319795;color:rgba(49,151,149,var(--placeholder-opacity))}.xl\:placeholder-teal-600::placeholder{--placeholder-opacity:1;color:#319795;color:rgba(49,151,149,var(--placeholder-opacity))}.xl\:placeholder-teal-700:-ms-input-placeholder{--placeholder-opacity:1;color:#2c7a7b;color:rgba(44,122,123,var(--placeholder-opacity))}.xl\:placeholder-teal-700::-ms-input-placeholder{--placeholder-opacity:1;color:#2c7a7b;color:rgba(44,122,123,var(--placeholder-opacity))}.xl\:placeholder-teal-700::placeholder{--placeholder-opacity:1;color:#2c7a7b;color:rgba(44,122,123,var(--placeholder-opacity))}.xl\:placeholder-teal-800:-ms-input-placeholder{--placeholder-opacity:1;color:#285e61;color:rgba(40,94,97,var(--placeholder-opacity))}.xl\:placeholder-teal-800::-ms-input-placeholder{--placeholder-opacity:1;color:#285e61;color:rgba(40,94,97,var(--placeholder-opacity))}.xl\:placeholder-teal-800::placeholder{--placeholder-opacity:1;color:#285e61;color:rgba(40,94,97,var(--placeholder-opacity))}.xl\:placeholder-teal-900:-ms-input-placeholder{--placeholder-opacity:1;color:#234e52;color:rgba(35,78,82,var(--placeholder-opacity))}.xl\:placeholder-teal-900::-ms-input-placeholder{--placeholder-opacity:1;color:#234e52;color:rgba(35,78,82,var(--placeholder-opacity))}.xl\:placeholder-teal-900::placeholder{--placeholder-opacity:1;color:#234e52;color:rgba(35,78,82,var(--placeholder-opacity))}.xl\:placeholder-blue-100:-ms-input-placeholder{--placeholder-opacity:1;color:#ebf8ff;color:rgba(235,248,255,var(--placeholder-opacity))}.xl\:placeholder-blue-100::-ms-input-placeholder{--placeholder-opacity:1;color:#ebf8ff;color:rgba(235,248,255,var(--placeholder-opacity))}.xl\:placeholder-blue-100::placeholder{--placeholder-opacity:1;color:#ebf8ff;color:rgba(235,248,255,var(--placeholder-opacity))}.xl\:placeholder-blue-200:-ms-input-placeholder{--placeholder-opacity:1;color:#bee3f8;color:rgba(190,227,248,var(--placeholder-opacity))}.xl\:placeholder-blue-200::-ms-input-placeholder{--placeholder-opacity:1;color:#bee3f8;color:rgba(190,227,248,var(--placeholder-opacity))}.xl\:placeholder-blue-200::placeholder{--placeholder-opacity:1;color:#bee3f8;color:rgba(190,227,248,var(--placeholder-opacity))}.xl\:placeholder-blue-300:-ms-input-placeholder{--placeholder-opacity:1;color:#90cdf4;color:rgba(144,205,244,var(--placeholder-opacity))}.xl\:placeholder-blue-300::-ms-input-placeholder{--placeholder-opacity:1;color:#90cdf4;color:rgba(144,205,244,var(--placeholder-opacity))}.xl\:placeholder-blue-300::placeholder{--placeholder-opacity:1;color:#90cdf4;color:rgba(144,205,244,var(--placeholder-opacity))}.xl\:placeholder-blue-400:-ms-input-placeholder{--placeholder-opacity:1;color:#63b3ed;color:rgba(99,179,237,var(--placeholder-opacity))}.xl\:placeholder-blue-400::-ms-input-placeholder{--placeholder-opacity:1;color:#63b3ed;color:rgba(99,179,237,var(--placeholder-opacity))}.xl\:placeholder-blue-400::placeholder{--placeholder-opacity:1;color:#63b3ed;color:rgba(99,179,237,var(--placeholder-opacity))}.xl\:placeholder-blue-500:-ms-input-placeholder{--placeholder-opacity:1;color:#4299e1;color:rgba(66,153,225,var(--placeholder-opacity))}.xl\:placeholder-blue-500::-ms-input-placeholder{--placeholder-opacity:1;color:#4299e1;color:rgba(66,153,225,var(--placeholder-opacity))}.xl\:placeholder-blue-500::placeholder{--placeholder-opacity:1;color:#4299e1;color:rgba(66,153,225,var(--placeholder-opacity))}.xl\:placeholder-blue-600:-ms-input-placeholder{--placeholder-opacity:1;color:#3182ce;color:rgba(49,130,206,var(--placeholder-opacity))}.xl\:placeholder-blue-600::-ms-input-placeholder{--placeholder-opacity:1;color:#3182ce;color:rgba(49,130,206,var(--placeholder-opacity))}.xl\:placeholder-blue-600::placeholder{--placeholder-opacity:1;color:#3182ce;color:rgba(49,130,206,var(--placeholder-opacity))}.xl\:placeholder-blue-700:-ms-input-placeholder{--placeholder-opacity:1;color:#2b6cb0;color:rgba(43,108,176,var(--placeholder-opacity))}.xl\:placeholder-blue-700::-ms-input-placeholder{--placeholder-opacity:1;color:#2b6cb0;color:rgba(43,108,176,var(--placeholder-opacity))}.xl\:placeholder-blue-700::placeholder{--placeholder-opacity:1;color:#2b6cb0;color:rgba(43,108,176,var(--placeholder-opacity))}.xl\:placeholder-blue-800:-ms-input-placeholder{--placeholder-opacity:1;color:#2c5282;color:rgba(44,82,130,var(--placeholder-opacity))}.xl\:placeholder-blue-800::-ms-input-placeholder{--placeholder-opacity:1;color:#2c5282;color:rgba(44,82,130,var(--placeholder-opacity))}.xl\:placeholder-blue-800::placeholder{--placeholder-opacity:1;color:#2c5282;color:rgba(44,82,130,var(--placeholder-opacity))}.xl\:placeholder-blue-900:-ms-input-placeholder{--placeholder-opacity:1;color:#2a4365;color:rgba(42,67,101,var(--placeholder-opacity))}.xl\:placeholder-blue-900::-ms-input-placeholder{--placeholder-opacity:1;color:#2a4365;color:rgba(42,67,101,var(--placeholder-opacity))}.xl\:placeholder-blue-900::placeholder{--placeholder-opacity:1;color:#2a4365;color:rgba(42,67,101,var(--placeholder-opacity))}.xl\:placeholder-indigo-100:-ms-input-placeholder{--placeholder-opacity:1;color:#ebf4ff;color:rgba(235,244,255,var(--placeholder-opacity))}.xl\:placeholder-indigo-100::-ms-input-placeholder{--placeholder-opacity:1;color:#ebf4ff;color:rgba(235,244,255,var(--placeholder-opacity))}.xl\:placeholder-indigo-100::placeholder{--placeholder-opacity:1;color:#ebf4ff;color:rgba(235,244,255,var(--placeholder-opacity))}.xl\:placeholder-indigo-200:-ms-input-placeholder{--placeholder-opacity:1;color:#c3dafe;color:rgba(195,218,254,var(--placeholder-opacity))}.xl\:placeholder-indigo-200::-ms-input-placeholder{--placeholder-opacity:1;color:#c3dafe;color:rgba(195,218,254,var(--placeholder-opacity))}.xl\:placeholder-indigo-200::placeholder{--placeholder-opacity:1;color:#c3dafe;color:rgba(195,218,254,var(--placeholder-opacity))}.xl\:placeholder-indigo-300:-ms-input-placeholder{--placeholder-opacity:1;color:#a3bffa;color:rgba(163,191,250,var(--placeholder-opacity))}.xl\:placeholder-indigo-300::-ms-input-placeholder{--placeholder-opacity:1;color:#a3bffa;color:rgba(163,191,250,var(--placeholder-opacity))}.xl\:placeholder-indigo-300::placeholder{--placeholder-opacity:1;color:#a3bffa;color:rgba(163,191,250,var(--placeholder-opacity))}.xl\:placeholder-indigo-400:-ms-input-placeholder{--placeholder-opacity:1;color:#7f9cf5;color:rgba(127,156,245,var(--placeholder-opacity))}.xl\:placeholder-indigo-400::-ms-input-placeholder{--placeholder-opacity:1;color:#7f9cf5;color:rgba(127,156,245,var(--placeholder-opacity))}.xl\:placeholder-indigo-400::placeholder{--placeholder-opacity:1;color:#7f9cf5;color:rgba(127,156,245,var(--placeholder-opacity))}.xl\:placeholder-indigo-500:-ms-input-placeholder{--placeholder-opacity:1;color:#667eea;color:rgba(102,126,234,var(--placeholder-opacity))}.xl\:placeholder-indigo-500::-ms-input-placeholder{--placeholder-opacity:1;color:#667eea;color:rgba(102,126,234,var(--placeholder-opacity))}.xl\:placeholder-indigo-500::placeholder{--placeholder-opacity:1;color:#667eea;color:rgba(102,126,234,var(--placeholder-opacity))}.xl\:placeholder-indigo-600:-ms-input-placeholder{--placeholder-opacity:1;color:#5a67d8;color:rgba(90,103,216,var(--placeholder-opacity))}.xl\:placeholder-indigo-600::-ms-input-placeholder{--placeholder-opacity:1;color:#5a67d8;color:rgba(90,103,216,var(--placeholder-opacity))}.xl\:placeholder-indigo-600::placeholder{--placeholder-opacity:1;color:#5a67d8;color:rgba(90,103,216,var(--placeholder-opacity))}.xl\:placeholder-indigo-700:-ms-input-placeholder{--placeholder-opacity:1;color:#4c51bf;color:rgba(76,81,191,var(--placeholder-opacity))}.xl\:placeholder-indigo-700::-ms-input-placeholder{--placeholder-opacity:1;color:#4c51bf;color:rgba(76,81,191,var(--placeholder-opacity))}.xl\:placeholder-indigo-700::placeholder{--placeholder-opacity:1;color:#4c51bf;color:rgba(76,81,191,var(--placeholder-opacity))}.xl\:placeholder-indigo-800:-ms-input-placeholder{--placeholder-opacity:1;color:#434190;color:rgba(67,65,144,var(--placeholder-opacity))}.xl\:placeholder-indigo-800::-ms-input-placeholder{--placeholder-opacity:1;color:#434190;color:rgba(67,65,144,var(--placeholder-opacity))}.xl\:placeholder-indigo-800::placeholder{--placeholder-opacity:1;color:#434190;color:rgba(67,65,144,var(--placeholder-opacity))}.xl\:placeholder-indigo-900:-ms-input-placeholder{--placeholder-opacity:1;color:#3c366b;color:rgba(60,54,107,var(--placeholder-opacity))}.xl\:placeholder-indigo-900::-ms-input-placeholder{--placeholder-opacity:1;color:#3c366b;color:rgba(60,54,107,var(--placeholder-opacity))}.xl\:placeholder-indigo-900::placeholder{--placeholder-opacity:1;color:#3c366b;color:rgba(60,54,107,var(--placeholder-opacity))}.xl\:placeholder-purple-100:-ms-input-placeholder{--placeholder-opacity:1;color:#faf5ff;color:rgba(250,245,255,var(--placeholder-opacity))}.xl\:placeholder-purple-100::-ms-input-placeholder{--placeholder-opacity:1;color:#faf5ff;color:rgba(250,245,255,var(--placeholder-opacity))}.xl\:placeholder-purple-100::placeholder{--placeholder-opacity:1;color:#faf5ff;color:rgba(250,245,255,var(--placeholder-opacity))}.xl\:placeholder-purple-200:-ms-input-placeholder{--placeholder-opacity:1;color:#e9d8fd;color:rgba(233,216,253,var(--placeholder-opacity))}.xl\:placeholder-purple-200::-ms-input-placeholder{--placeholder-opacity:1;color:#e9d8fd;color:rgba(233,216,253,var(--placeholder-opacity))}.xl\:placeholder-purple-200::placeholder{--placeholder-opacity:1;color:#e9d8fd;color:rgba(233,216,253,var(--placeholder-opacity))}.xl\:placeholder-purple-300:-ms-input-placeholder{--placeholder-opacity:1;color:#d6bcfa;color:rgba(214,188,250,var(--placeholder-opacity))}.xl\:placeholder-purple-300::-ms-input-placeholder{--placeholder-opacity:1;color:#d6bcfa;color:rgba(214,188,250,var(--placeholder-opacity))}.xl\:placeholder-purple-300::placeholder{--placeholder-opacity:1;color:#d6bcfa;color:rgba(214,188,250,var(--placeholder-opacity))}.xl\:placeholder-purple-400:-ms-input-placeholder{--placeholder-opacity:1;color:#b794f4;color:rgba(183,148,244,var(--placeholder-opacity))}.xl\:placeholder-purple-400::-ms-input-placeholder{--placeholder-opacity:1;color:#b794f4;color:rgba(183,148,244,var(--placeholder-opacity))}.xl\:placeholder-purple-400::placeholder{--placeholder-opacity:1;color:#b794f4;color:rgba(183,148,244,var(--placeholder-opacity))}.xl\:placeholder-purple-500:-ms-input-placeholder{--placeholder-opacity:1;color:#9f7aea;color:rgba(159,122,234,var(--placeholder-opacity))}.xl\:placeholder-purple-500::-ms-input-placeholder{--placeholder-opacity:1;color:#9f7aea;color:rgba(159,122,234,var(--placeholder-opacity))}.xl\:placeholder-purple-500::placeholder{--placeholder-opacity:1;color:#9f7aea;color:rgba(159,122,234,var(--placeholder-opacity))}.xl\:placeholder-purple-600:-ms-input-placeholder{--placeholder-opacity:1;color:#805ad5;color:rgba(128,90,213,var(--placeholder-opacity))}.xl\:placeholder-purple-600::-ms-input-placeholder{--placeholder-opacity:1;color:#805ad5;color:rgba(128,90,213,var(--placeholder-opacity))}.xl\:placeholder-purple-600::placeholder{--placeholder-opacity:1;color:#805ad5;color:rgba(128,90,213,var(--placeholder-opacity))}.xl\:placeholder-purple-700:-ms-input-placeholder{--placeholder-opacity:1;color:#6b46c1;color:rgba(107,70,193,var(--placeholder-opacity))}.xl\:placeholder-purple-700::-ms-input-placeholder{--placeholder-opacity:1;color:#6b46c1;color:rgba(107,70,193,var(--placeholder-opacity))}.xl\:placeholder-purple-700::placeholder{--placeholder-opacity:1;color:#6b46c1;color:rgba(107,70,193,var(--placeholder-opacity))}.xl\:placeholder-purple-800:-ms-input-placeholder{--placeholder-opacity:1;color:#553c9a;color:rgba(85,60,154,var(--placeholder-opacity))}.xl\:placeholder-purple-800::-ms-input-placeholder{--placeholder-opacity:1;color:#553c9a;color:rgba(85,60,154,var(--placeholder-opacity))}.xl\:placeholder-purple-800::placeholder{--placeholder-opacity:1;color:#553c9a;color:rgba(85,60,154,var(--placeholder-opacity))}.xl\:placeholder-purple-900:-ms-input-placeholder{--placeholder-opacity:1;color:#44337a;color:rgba(68,51,122,var(--placeholder-opacity))}.xl\:placeholder-purple-900::-ms-input-placeholder{--placeholder-opacity:1;color:#44337a;color:rgba(68,51,122,var(--placeholder-opacity))}.xl\:placeholder-purple-900::placeholder{--placeholder-opacity:1;color:#44337a;color:rgba(68,51,122,var(--placeholder-opacity))}.xl\:placeholder-pink-100:-ms-input-placeholder{--placeholder-opacity:1;color:#fff5f7;color:rgba(255,245,247,var(--placeholder-opacity))}.xl\:placeholder-pink-100::-ms-input-placeholder{--placeholder-opacity:1;color:#fff5f7;color:rgba(255,245,247,var(--placeholder-opacity))}.xl\:placeholder-pink-100::placeholder{--placeholder-opacity:1;color:#fff5f7;color:rgba(255,245,247,var(--placeholder-opacity))}.xl\:placeholder-pink-200:-ms-input-placeholder{--placeholder-opacity:1;color:#fed7e2;color:rgba(254,215,226,var(--placeholder-opacity))}.xl\:placeholder-pink-200::-ms-input-placeholder{--placeholder-opacity:1;color:#fed7e2;color:rgba(254,215,226,var(--placeholder-opacity))}.xl\:placeholder-pink-200::placeholder{--placeholder-opacity:1;color:#fed7e2;color:rgba(254,215,226,var(--placeholder-opacity))}.xl\:placeholder-pink-300:-ms-input-placeholder{--placeholder-opacity:1;color:#fbb6ce;color:rgba(251,182,206,var(--placeholder-opacity))}.xl\:placeholder-pink-300::-ms-input-placeholder{--placeholder-opacity:1;color:#fbb6ce;color:rgba(251,182,206,var(--placeholder-opacity))}.xl\:placeholder-pink-300::placeholder{--placeholder-opacity:1;color:#fbb6ce;color:rgba(251,182,206,var(--placeholder-opacity))}.xl\:placeholder-pink-400:-ms-input-placeholder{--placeholder-opacity:1;color:#f687b3;color:rgba(246,135,179,var(--placeholder-opacity))}.xl\:placeholder-pink-400::-ms-input-placeholder{--placeholder-opacity:1;color:#f687b3;color:rgba(246,135,179,var(--placeholder-opacity))}.xl\:placeholder-pink-400::placeholder{--placeholder-opacity:1;color:#f687b3;color:rgba(246,135,179,var(--placeholder-opacity))}.xl\:placeholder-pink-500:-ms-input-placeholder{--placeholder-opacity:1;color:#ed64a6;color:rgba(237,100,166,var(--placeholder-opacity))}.xl\:placeholder-pink-500::-ms-input-placeholder{--placeholder-opacity:1;color:#ed64a6;color:rgba(237,100,166,var(--placeholder-opacity))}.xl\:placeholder-pink-500::placeholder{--placeholder-opacity:1;color:#ed64a6;color:rgba(237,100,166,var(--placeholder-opacity))}.xl\:placeholder-pink-600:-ms-input-placeholder{--placeholder-opacity:1;color:#d53f8c;color:rgba(213,63,140,var(--placeholder-opacity))}.xl\:placeholder-pink-600::-ms-input-placeholder{--placeholder-opacity:1;color:#d53f8c;color:rgba(213,63,140,var(--placeholder-opacity))}.xl\:placeholder-pink-600::placeholder{--placeholder-opacity:1;color:#d53f8c;color:rgba(213,63,140,var(--placeholder-opacity))}.xl\:placeholder-pink-700:-ms-input-placeholder{--placeholder-opacity:1;color:#b83280;color:rgba(184,50,128,var(--placeholder-opacity))}.xl\:placeholder-pink-700::-ms-input-placeholder{--placeholder-opacity:1;color:#b83280;color:rgba(184,50,128,var(--placeholder-opacity))}.xl\:placeholder-pink-700::placeholder{--placeholder-opacity:1;color:#b83280;color:rgba(184,50,128,var(--placeholder-opacity))}.xl\:placeholder-pink-800:-ms-input-placeholder{--placeholder-opacity:1;color:#97266d;color:rgba(151,38,109,var(--placeholder-opacity))}.xl\:placeholder-pink-800::-ms-input-placeholder{--placeholder-opacity:1;color:#97266d;color:rgba(151,38,109,var(--placeholder-opacity))}.xl\:placeholder-pink-800::placeholder{--placeholder-opacity:1;color:#97266d;color:rgba(151,38,109,var(--placeholder-opacity))}.xl\:placeholder-pink-900:-ms-input-placeholder{--placeholder-opacity:1;color:#702459;color:rgba(112,36,89,var(--placeholder-opacity))}.xl\:placeholder-pink-900::-ms-input-placeholder{--placeholder-opacity:1;color:#702459;color:rgba(112,36,89,var(--placeholder-opacity))}.xl\:placeholder-pink-900::placeholder{--placeholder-opacity:1;color:#702459;color:rgba(112,36,89,var(--placeholder-opacity))}.xl\:focus\:placeholder-transparent:focus:-ms-input-placeholder{color:transparent}.xl\:focus\:placeholder-transparent:focus::-ms-input-placeholder{color:transparent}.xl\:focus\:placeholder-transparent:focus::placeholder{color:transparent}.xl\:focus\:placeholder-current:focus:-ms-input-placeholder{color:currentColor}.xl\:focus\:placeholder-current:focus::-ms-input-placeholder{color:currentColor}.xl\:focus\:placeholder-current:focus::placeholder{color:currentColor}.xl\:focus\:placeholder-black:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#000;color:rgba(0,0,0,var(--placeholder-opacity))}.xl\:focus\:placeholder-black:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#000;color:rgba(0,0,0,var(--placeholder-opacity))}.xl\:focus\:placeholder-black:focus::placeholder{--placeholder-opacity:1;color:#000;color:rgba(0,0,0,var(--placeholder-opacity))}.xl\:focus\:placeholder-white:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#fff;color:rgba(255,255,255,var(--placeholder-opacity))}.xl\:focus\:placeholder-white:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#fff;color:rgba(255,255,255,var(--placeholder-opacity))}.xl\:focus\:placeholder-white:focus::placeholder{--placeholder-opacity:1;color:#fff;color:rgba(255,255,255,var(--placeholder-opacity))}.xl\:focus\:placeholder-gray-100:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#f7fafc;color:rgba(247,250,252,var(--placeholder-opacity))}.xl\:focus\:placeholder-gray-100:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#f7fafc;color:rgba(247,250,252,var(--placeholder-opacity))}.xl\:focus\:placeholder-gray-100:focus::placeholder{--placeholder-opacity:1;color:#f7fafc;color:rgba(247,250,252,var(--placeholder-opacity))}.xl\:focus\:placeholder-gray-200:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#edf2f7;color:rgba(237,242,247,var(--placeholder-opacity))}.xl\:focus\:placeholder-gray-200:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#edf2f7;color:rgba(237,242,247,var(--placeholder-opacity))}.xl\:focus\:placeholder-gray-200:focus::placeholder{--placeholder-opacity:1;color:#edf2f7;color:rgba(237,242,247,var(--placeholder-opacity))}.xl\:focus\:placeholder-gray-300:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#e2e8f0;color:rgba(226,232,240,var(--placeholder-opacity))}.xl\:focus\:placeholder-gray-300:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#e2e8f0;color:rgba(226,232,240,var(--placeholder-opacity))}.xl\:focus\:placeholder-gray-300:focus::placeholder{--placeholder-opacity:1;color:#e2e8f0;color:rgba(226,232,240,var(--placeholder-opacity))}.xl\:focus\:placeholder-gray-400:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#cbd5e0;color:rgba(203,213,224,var(--placeholder-opacity))}.xl\:focus\:placeholder-gray-400:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#cbd5e0;color:rgba(203,213,224,var(--placeholder-opacity))}.xl\:focus\:placeholder-gray-400:focus::placeholder{--placeholder-opacity:1;color:#cbd5e0;color:rgba(203,213,224,var(--placeholder-opacity))}.xl\:focus\:placeholder-gray-500:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#a0aec0;color:rgba(160,174,192,var(--placeholder-opacity))}.xl\:focus\:placeholder-gray-500:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#a0aec0;color:rgba(160,174,192,var(--placeholder-opacity))}.xl\:focus\:placeholder-gray-500:focus::placeholder{--placeholder-opacity:1;color:#a0aec0;color:rgba(160,174,192,var(--placeholder-opacity))}.xl\:focus\:placeholder-gray-600:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#718096;color:rgba(113,128,150,var(--placeholder-opacity))}.xl\:focus\:placeholder-gray-600:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#718096;color:rgba(113,128,150,var(--placeholder-opacity))}.xl\:focus\:placeholder-gray-600:focus::placeholder{--placeholder-opacity:1;color:#718096;color:rgba(113,128,150,var(--placeholder-opacity))}.xl\:focus\:placeholder-gray-700:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#4a5568;color:rgba(74,85,104,var(--placeholder-opacity))}.xl\:focus\:placeholder-gray-700:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#4a5568;color:rgba(74,85,104,var(--placeholder-opacity))}.xl\:focus\:placeholder-gray-700:focus::placeholder{--placeholder-opacity:1;color:#4a5568;color:rgba(74,85,104,var(--placeholder-opacity))}.xl\:focus\:placeholder-gray-800:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#2d3748;color:rgba(45,55,72,var(--placeholder-opacity))}.xl\:focus\:placeholder-gray-800:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#2d3748;color:rgba(45,55,72,var(--placeholder-opacity))}.xl\:focus\:placeholder-gray-800:focus::placeholder{--placeholder-opacity:1;color:#2d3748;color:rgba(45,55,72,var(--placeholder-opacity))}.xl\:focus\:placeholder-gray-900:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#1a202c;color:rgba(26,32,44,var(--placeholder-opacity))}.xl\:focus\:placeholder-gray-900:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#1a202c;color:rgba(26,32,44,var(--placeholder-opacity))}.xl\:focus\:placeholder-gray-900:focus::placeholder{--placeholder-opacity:1;color:#1a202c;color:rgba(26,32,44,var(--placeholder-opacity))}.xl\:focus\:placeholder-red-100:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#fff5f5;color:rgba(255,245,245,var(--placeholder-opacity))}.xl\:focus\:placeholder-red-100:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#fff5f5;color:rgba(255,245,245,var(--placeholder-opacity))}.xl\:focus\:placeholder-red-100:focus::placeholder{--placeholder-opacity:1;color:#fff5f5;color:rgba(255,245,245,var(--placeholder-opacity))}.xl\:focus\:placeholder-red-200:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#fed7d7;color:rgba(254,215,215,var(--placeholder-opacity))}.xl\:focus\:placeholder-red-200:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#fed7d7;color:rgba(254,215,215,var(--placeholder-opacity))}.xl\:focus\:placeholder-red-200:focus::placeholder{--placeholder-opacity:1;color:#fed7d7;color:rgba(254,215,215,var(--placeholder-opacity))}.xl\:focus\:placeholder-red-300:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#feb2b2;color:rgba(254,178,178,var(--placeholder-opacity))}.xl\:focus\:placeholder-red-300:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#feb2b2;color:rgba(254,178,178,var(--placeholder-opacity))}.xl\:focus\:placeholder-red-300:focus::placeholder{--placeholder-opacity:1;color:#feb2b2;color:rgba(254,178,178,var(--placeholder-opacity))}.xl\:focus\:placeholder-red-400:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#fc8181;color:rgba(252,129,129,var(--placeholder-opacity))}.xl\:focus\:placeholder-red-400:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#fc8181;color:rgba(252,129,129,var(--placeholder-opacity))}.xl\:focus\:placeholder-red-400:focus::placeholder{--placeholder-opacity:1;color:#fc8181;color:rgba(252,129,129,var(--placeholder-opacity))}.xl\:focus\:placeholder-red-500:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#f56565;color:rgba(245,101,101,var(--placeholder-opacity))}.xl\:focus\:placeholder-red-500:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#f56565;color:rgba(245,101,101,var(--placeholder-opacity))}.xl\:focus\:placeholder-red-500:focus::placeholder{--placeholder-opacity:1;color:#f56565;color:rgba(245,101,101,var(--placeholder-opacity))}.xl\:focus\:placeholder-red-600:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#e53e3e;color:rgba(229,62,62,var(--placeholder-opacity))}.xl\:focus\:placeholder-red-600:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#e53e3e;color:rgba(229,62,62,var(--placeholder-opacity))}.xl\:focus\:placeholder-red-600:focus::placeholder{--placeholder-opacity:1;color:#e53e3e;color:rgba(229,62,62,var(--placeholder-opacity))}.xl\:focus\:placeholder-red-700:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#c53030;color:rgba(197,48,48,var(--placeholder-opacity))}.xl\:focus\:placeholder-red-700:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#c53030;color:rgba(197,48,48,var(--placeholder-opacity))}.xl\:focus\:placeholder-red-700:focus::placeholder{--placeholder-opacity:1;color:#c53030;color:rgba(197,48,48,var(--placeholder-opacity))}.xl\:focus\:placeholder-red-800:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#9b2c2c;color:rgba(155,44,44,var(--placeholder-opacity))}.xl\:focus\:placeholder-red-800:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#9b2c2c;color:rgba(155,44,44,var(--placeholder-opacity))}.xl\:focus\:placeholder-red-800:focus::placeholder{--placeholder-opacity:1;color:#9b2c2c;color:rgba(155,44,44,var(--placeholder-opacity))}.xl\:focus\:placeholder-red-900:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#742a2a;color:rgba(116,42,42,var(--placeholder-opacity))}.xl\:focus\:placeholder-red-900:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#742a2a;color:rgba(116,42,42,var(--placeholder-opacity))}.xl\:focus\:placeholder-red-900:focus::placeholder{--placeholder-opacity:1;color:#742a2a;color:rgba(116,42,42,var(--placeholder-opacity))}.xl\:focus\:placeholder-orange-100:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#fffaf0;color:rgba(255,250,240,var(--placeholder-opacity))}.xl\:focus\:placeholder-orange-100:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#fffaf0;color:rgba(255,250,240,var(--placeholder-opacity))}.xl\:focus\:placeholder-orange-100:focus::placeholder{--placeholder-opacity:1;color:#fffaf0;color:rgba(255,250,240,var(--placeholder-opacity))}.xl\:focus\:placeholder-orange-200:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#feebc8;color:rgba(254,235,200,var(--placeholder-opacity))}.xl\:focus\:placeholder-orange-200:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#feebc8;color:rgba(254,235,200,var(--placeholder-opacity))}.xl\:focus\:placeholder-orange-200:focus::placeholder{--placeholder-opacity:1;color:#feebc8;color:rgba(254,235,200,var(--placeholder-opacity))}.xl\:focus\:placeholder-orange-300:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#fbd38d;color:rgba(251,211,141,var(--placeholder-opacity))}.xl\:focus\:placeholder-orange-300:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#fbd38d;color:rgba(251,211,141,var(--placeholder-opacity))}.xl\:focus\:placeholder-orange-300:focus::placeholder{--placeholder-opacity:1;color:#fbd38d;color:rgba(251,211,141,var(--placeholder-opacity))}.xl\:focus\:placeholder-orange-400:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#f6ad55;color:rgba(246,173,85,var(--placeholder-opacity))}.xl\:focus\:placeholder-orange-400:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#f6ad55;color:rgba(246,173,85,var(--placeholder-opacity))}.xl\:focus\:placeholder-orange-400:focus::placeholder{--placeholder-opacity:1;color:#f6ad55;color:rgba(246,173,85,var(--placeholder-opacity))}.xl\:focus\:placeholder-orange-500:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#ed8936;color:rgba(237,137,54,var(--placeholder-opacity))}.xl\:focus\:placeholder-orange-500:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#ed8936;color:rgba(237,137,54,var(--placeholder-opacity))}.xl\:focus\:placeholder-orange-500:focus::placeholder{--placeholder-opacity:1;color:#ed8936;color:rgba(237,137,54,var(--placeholder-opacity))}.xl\:focus\:placeholder-orange-600:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#dd6b20;color:rgba(221,107,32,var(--placeholder-opacity))}.xl\:focus\:placeholder-orange-600:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#dd6b20;color:rgba(221,107,32,var(--placeholder-opacity))}.xl\:focus\:placeholder-orange-600:focus::placeholder{--placeholder-opacity:1;color:#dd6b20;color:rgba(221,107,32,var(--placeholder-opacity))}.xl\:focus\:placeholder-orange-700:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#c05621;color:rgba(192,86,33,var(--placeholder-opacity))}.xl\:focus\:placeholder-orange-700:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#c05621;color:rgba(192,86,33,var(--placeholder-opacity))}.xl\:focus\:placeholder-orange-700:focus::placeholder{--placeholder-opacity:1;color:#c05621;color:rgba(192,86,33,var(--placeholder-opacity))}.xl\:focus\:placeholder-orange-800:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#9c4221;color:rgba(156,66,33,var(--placeholder-opacity))}.xl\:focus\:placeholder-orange-800:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#9c4221;color:rgba(156,66,33,var(--placeholder-opacity))}.xl\:focus\:placeholder-orange-800:focus::placeholder{--placeholder-opacity:1;color:#9c4221;color:rgba(156,66,33,var(--placeholder-opacity))}.xl\:focus\:placeholder-orange-900:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#7b341e;color:rgba(123,52,30,var(--placeholder-opacity))}.xl\:focus\:placeholder-orange-900:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#7b341e;color:rgba(123,52,30,var(--placeholder-opacity))}.xl\:focus\:placeholder-orange-900:focus::placeholder{--placeholder-opacity:1;color:#7b341e;color:rgba(123,52,30,var(--placeholder-opacity))}.xl\:focus\:placeholder-yellow-100:focus:-ms-input-placeholder{--placeholder-opacity:1;color:ivory;color:rgba(255,255,240,var(--placeholder-opacity))}.xl\:focus\:placeholder-yellow-100:focus::-ms-input-placeholder{--placeholder-opacity:1;color:ivory;color:rgba(255,255,240,var(--placeholder-opacity))}.xl\:focus\:placeholder-yellow-100:focus::placeholder{--placeholder-opacity:1;color:ivory;color:rgba(255,255,240,var(--placeholder-opacity))}.xl\:focus\:placeholder-yellow-200:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#fefcbf;color:rgba(254,252,191,var(--placeholder-opacity))}.xl\:focus\:placeholder-yellow-200:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#fefcbf;color:rgba(254,252,191,var(--placeholder-opacity))}.xl\:focus\:placeholder-yellow-200:focus::placeholder{--placeholder-opacity:1;color:#fefcbf;color:rgba(254,252,191,var(--placeholder-opacity))}.xl\:focus\:placeholder-yellow-300:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#faf089;color:rgba(250,240,137,var(--placeholder-opacity))}.xl\:focus\:placeholder-yellow-300:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#faf089;color:rgba(250,240,137,var(--placeholder-opacity))}.xl\:focus\:placeholder-yellow-300:focus::placeholder{--placeholder-opacity:1;color:#faf089;color:rgba(250,240,137,var(--placeholder-opacity))}.xl\:focus\:placeholder-yellow-400:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#f6e05e;color:rgba(246,224,94,var(--placeholder-opacity))}.xl\:focus\:placeholder-yellow-400:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#f6e05e;color:rgba(246,224,94,var(--placeholder-opacity))}.xl\:focus\:placeholder-yellow-400:focus::placeholder{--placeholder-opacity:1;color:#f6e05e;color:rgba(246,224,94,var(--placeholder-opacity))}.xl\:focus\:placeholder-yellow-500:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#ecc94b;color:rgba(236,201,75,var(--placeholder-opacity))}.xl\:focus\:placeholder-yellow-500:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#ecc94b;color:rgba(236,201,75,var(--placeholder-opacity))}.xl\:focus\:placeholder-yellow-500:focus::placeholder{--placeholder-opacity:1;color:#ecc94b;color:rgba(236,201,75,var(--placeholder-opacity))}.xl\:focus\:placeholder-yellow-600:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#d69e2e;color:rgba(214,158,46,var(--placeholder-opacity))}.xl\:focus\:placeholder-yellow-600:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#d69e2e;color:rgba(214,158,46,var(--placeholder-opacity))}.xl\:focus\:placeholder-yellow-600:focus::placeholder{--placeholder-opacity:1;color:#d69e2e;color:rgba(214,158,46,var(--placeholder-opacity))}.xl\:focus\:placeholder-yellow-700:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#b7791f;color:rgba(183,121,31,var(--placeholder-opacity))}.xl\:focus\:placeholder-yellow-700:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#b7791f;color:rgba(183,121,31,var(--placeholder-opacity))}.xl\:focus\:placeholder-yellow-700:focus::placeholder{--placeholder-opacity:1;color:#b7791f;color:rgba(183,121,31,var(--placeholder-opacity))}.xl\:focus\:placeholder-yellow-800:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#975a16;color:rgba(151,90,22,var(--placeholder-opacity))}.xl\:focus\:placeholder-yellow-800:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#975a16;color:rgba(151,90,22,var(--placeholder-opacity))}.xl\:focus\:placeholder-yellow-800:focus::placeholder{--placeholder-opacity:1;color:#975a16;color:rgba(151,90,22,var(--placeholder-opacity))}.xl\:focus\:placeholder-yellow-900:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#744210;color:rgba(116,66,16,var(--placeholder-opacity))}.xl\:focus\:placeholder-yellow-900:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#744210;color:rgba(116,66,16,var(--placeholder-opacity))}.xl\:focus\:placeholder-yellow-900:focus::placeholder{--placeholder-opacity:1;color:#744210;color:rgba(116,66,16,var(--placeholder-opacity))}.xl\:focus\:placeholder-green-100:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#f0fff4;color:rgba(240,255,244,var(--placeholder-opacity))}.xl\:focus\:placeholder-green-100:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#f0fff4;color:rgba(240,255,244,var(--placeholder-opacity))}.xl\:focus\:placeholder-green-100:focus::placeholder{--placeholder-opacity:1;color:#f0fff4;color:rgba(240,255,244,var(--placeholder-opacity))}.xl\:focus\:placeholder-green-200:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#c6f6d5;color:rgba(198,246,213,var(--placeholder-opacity))}.xl\:focus\:placeholder-green-200:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#c6f6d5;color:rgba(198,246,213,var(--placeholder-opacity))}.xl\:focus\:placeholder-green-200:focus::placeholder{--placeholder-opacity:1;color:#c6f6d5;color:rgba(198,246,213,var(--placeholder-opacity))}.xl\:focus\:placeholder-green-300:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#9ae6b4;color:rgba(154,230,180,var(--placeholder-opacity))}.xl\:focus\:placeholder-green-300:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#9ae6b4;color:rgba(154,230,180,var(--placeholder-opacity))}.xl\:focus\:placeholder-green-300:focus::placeholder{--placeholder-opacity:1;color:#9ae6b4;color:rgba(154,230,180,var(--placeholder-opacity))}.xl\:focus\:placeholder-green-400:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#68d391;color:rgba(104,211,145,var(--placeholder-opacity))}.xl\:focus\:placeholder-green-400:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#68d391;color:rgba(104,211,145,var(--placeholder-opacity))}.xl\:focus\:placeholder-green-400:focus::placeholder{--placeholder-opacity:1;color:#68d391;color:rgba(104,211,145,var(--placeholder-opacity))}.xl\:focus\:placeholder-green-500:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#48bb78;color:rgba(72,187,120,var(--placeholder-opacity))}.xl\:focus\:placeholder-green-500:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#48bb78;color:rgba(72,187,120,var(--placeholder-opacity))}.xl\:focus\:placeholder-green-500:focus::placeholder{--placeholder-opacity:1;color:#48bb78;color:rgba(72,187,120,var(--placeholder-opacity))}.xl\:focus\:placeholder-green-600:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#38a169;color:rgba(56,161,105,var(--placeholder-opacity))}.xl\:focus\:placeholder-green-600:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#38a169;color:rgba(56,161,105,var(--placeholder-opacity))}.xl\:focus\:placeholder-green-600:focus::placeholder{--placeholder-opacity:1;color:#38a169;color:rgba(56,161,105,var(--placeholder-opacity))}.xl\:focus\:placeholder-green-700:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#2f855a;color:rgba(47,133,90,var(--placeholder-opacity))}.xl\:focus\:placeholder-green-700:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#2f855a;color:rgba(47,133,90,var(--placeholder-opacity))}.xl\:focus\:placeholder-green-700:focus::placeholder{--placeholder-opacity:1;color:#2f855a;color:rgba(47,133,90,var(--placeholder-opacity))}.xl\:focus\:placeholder-green-800:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#276749;color:rgba(39,103,73,var(--placeholder-opacity))}.xl\:focus\:placeholder-green-800:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#276749;color:rgba(39,103,73,var(--placeholder-opacity))}.xl\:focus\:placeholder-green-800:focus::placeholder{--placeholder-opacity:1;color:#276749;color:rgba(39,103,73,var(--placeholder-opacity))}.xl\:focus\:placeholder-green-900:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#22543d;color:rgba(34,84,61,var(--placeholder-opacity))}.xl\:focus\:placeholder-green-900:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#22543d;color:rgba(34,84,61,var(--placeholder-opacity))}.xl\:focus\:placeholder-green-900:focus::placeholder{--placeholder-opacity:1;color:#22543d;color:rgba(34,84,61,var(--placeholder-opacity))}.xl\:focus\:placeholder-teal-100:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#e6fffa;color:rgba(230,255,250,var(--placeholder-opacity))}.xl\:focus\:placeholder-teal-100:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#e6fffa;color:rgba(230,255,250,var(--placeholder-opacity))}.xl\:focus\:placeholder-teal-100:focus::placeholder{--placeholder-opacity:1;color:#e6fffa;color:rgba(230,255,250,var(--placeholder-opacity))}.xl\:focus\:placeholder-teal-200:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#b2f5ea;color:rgba(178,245,234,var(--placeholder-opacity))}.xl\:focus\:placeholder-teal-200:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#b2f5ea;color:rgba(178,245,234,var(--placeholder-opacity))}.xl\:focus\:placeholder-teal-200:focus::placeholder{--placeholder-opacity:1;color:#b2f5ea;color:rgba(178,245,234,var(--placeholder-opacity))}.xl\:focus\:placeholder-teal-300:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#81e6d9;color:rgba(129,230,217,var(--placeholder-opacity))}.xl\:focus\:placeholder-teal-300:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#81e6d9;color:rgba(129,230,217,var(--placeholder-opacity))}.xl\:focus\:placeholder-teal-300:focus::placeholder{--placeholder-opacity:1;color:#81e6d9;color:rgba(129,230,217,var(--placeholder-opacity))}.xl\:focus\:placeholder-teal-400:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#4fd1c5;color:rgba(79,209,197,var(--placeholder-opacity))}.xl\:focus\:placeholder-teal-400:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#4fd1c5;color:rgba(79,209,197,var(--placeholder-opacity))}.xl\:focus\:placeholder-teal-400:focus::placeholder{--placeholder-opacity:1;color:#4fd1c5;color:rgba(79,209,197,var(--placeholder-opacity))}.xl\:focus\:placeholder-teal-500:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#38b2ac;color:rgba(56,178,172,var(--placeholder-opacity))}.xl\:focus\:placeholder-teal-500:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#38b2ac;color:rgba(56,178,172,var(--placeholder-opacity))}.xl\:focus\:placeholder-teal-500:focus::placeholder{--placeholder-opacity:1;color:#38b2ac;color:rgba(56,178,172,var(--placeholder-opacity))}.xl\:focus\:placeholder-teal-600:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#319795;color:rgba(49,151,149,var(--placeholder-opacity))}.xl\:focus\:placeholder-teal-600:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#319795;color:rgba(49,151,149,var(--placeholder-opacity))}.xl\:focus\:placeholder-teal-600:focus::placeholder{--placeholder-opacity:1;color:#319795;color:rgba(49,151,149,var(--placeholder-opacity))}.xl\:focus\:placeholder-teal-700:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#2c7a7b;color:rgba(44,122,123,var(--placeholder-opacity))}.xl\:focus\:placeholder-teal-700:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#2c7a7b;color:rgba(44,122,123,var(--placeholder-opacity))}.xl\:focus\:placeholder-teal-700:focus::placeholder{--placeholder-opacity:1;color:#2c7a7b;color:rgba(44,122,123,var(--placeholder-opacity))}.xl\:focus\:placeholder-teal-800:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#285e61;color:rgba(40,94,97,var(--placeholder-opacity))}.xl\:focus\:placeholder-teal-800:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#285e61;color:rgba(40,94,97,var(--placeholder-opacity))}.xl\:focus\:placeholder-teal-800:focus::placeholder{--placeholder-opacity:1;color:#285e61;color:rgba(40,94,97,var(--placeholder-opacity))}.xl\:focus\:placeholder-teal-900:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#234e52;color:rgba(35,78,82,var(--placeholder-opacity))}.xl\:focus\:placeholder-teal-900:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#234e52;color:rgba(35,78,82,var(--placeholder-opacity))}.xl\:focus\:placeholder-teal-900:focus::placeholder{--placeholder-opacity:1;color:#234e52;color:rgba(35,78,82,var(--placeholder-opacity))}.xl\:focus\:placeholder-blue-100:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#ebf8ff;color:rgba(235,248,255,var(--placeholder-opacity))}.xl\:focus\:placeholder-blue-100:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#ebf8ff;color:rgba(235,248,255,var(--placeholder-opacity))}.xl\:focus\:placeholder-blue-100:focus::placeholder{--placeholder-opacity:1;color:#ebf8ff;color:rgba(235,248,255,var(--placeholder-opacity))}.xl\:focus\:placeholder-blue-200:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#bee3f8;color:rgba(190,227,248,var(--placeholder-opacity))}.xl\:focus\:placeholder-blue-200:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#bee3f8;color:rgba(190,227,248,var(--placeholder-opacity))}.xl\:focus\:placeholder-blue-200:focus::placeholder{--placeholder-opacity:1;color:#bee3f8;color:rgba(190,227,248,var(--placeholder-opacity))}.xl\:focus\:placeholder-blue-300:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#90cdf4;color:rgba(144,205,244,var(--placeholder-opacity))}.xl\:focus\:placeholder-blue-300:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#90cdf4;color:rgba(144,205,244,var(--placeholder-opacity))}.xl\:focus\:placeholder-blue-300:focus::placeholder{--placeholder-opacity:1;color:#90cdf4;color:rgba(144,205,244,var(--placeholder-opacity))}.xl\:focus\:placeholder-blue-400:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#63b3ed;color:rgba(99,179,237,var(--placeholder-opacity))}.xl\:focus\:placeholder-blue-400:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#63b3ed;color:rgba(99,179,237,var(--placeholder-opacity))}.xl\:focus\:placeholder-blue-400:focus::placeholder{--placeholder-opacity:1;color:#63b3ed;color:rgba(99,179,237,var(--placeholder-opacity))}.xl\:focus\:placeholder-blue-500:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#4299e1;color:rgba(66,153,225,var(--placeholder-opacity))}.xl\:focus\:placeholder-blue-500:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#4299e1;color:rgba(66,153,225,var(--placeholder-opacity))}.xl\:focus\:placeholder-blue-500:focus::placeholder{--placeholder-opacity:1;color:#4299e1;color:rgba(66,153,225,var(--placeholder-opacity))}.xl\:focus\:placeholder-blue-600:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#3182ce;color:rgba(49,130,206,var(--placeholder-opacity))}.xl\:focus\:placeholder-blue-600:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#3182ce;color:rgba(49,130,206,var(--placeholder-opacity))}.xl\:focus\:placeholder-blue-600:focus::placeholder{--placeholder-opacity:1;color:#3182ce;color:rgba(49,130,206,var(--placeholder-opacity))}.xl\:focus\:placeholder-blue-700:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#2b6cb0;color:rgba(43,108,176,var(--placeholder-opacity))}.xl\:focus\:placeholder-blue-700:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#2b6cb0;color:rgba(43,108,176,var(--placeholder-opacity))}.xl\:focus\:placeholder-blue-700:focus::placeholder{--placeholder-opacity:1;color:#2b6cb0;color:rgba(43,108,176,var(--placeholder-opacity))}.xl\:focus\:placeholder-blue-800:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#2c5282;color:rgba(44,82,130,var(--placeholder-opacity))}.xl\:focus\:placeholder-blue-800:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#2c5282;color:rgba(44,82,130,var(--placeholder-opacity))}.xl\:focus\:placeholder-blue-800:focus::placeholder{--placeholder-opacity:1;color:#2c5282;color:rgba(44,82,130,var(--placeholder-opacity))}.xl\:focus\:placeholder-blue-900:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#2a4365;color:rgba(42,67,101,var(--placeholder-opacity))}.xl\:focus\:placeholder-blue-900:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#2a4365;color:rgba(42,67,101,var(--placeholder-opacity))}.xl\:focus\:placeholder-blue-900:focus::placeholder{--placeholder-opacity:1;color:#2a4365;color:rgba(42,67,101,var(--placeholder-opacity))}.xl\:focus\:placeholder-indigo-100:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#ebf4ff;color:rgba(235,244,255,var(--placeholder-opacity))}.xl\:focus\:placeholder-indigo-100:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#ebf4ff;color:rgba(235,244,255,var(--placeholder-opacity))}.xl\:focus\:placeholder-indigo-100:focus::placeholder{--placeholder-opacity:1;color:#ebf4ff;color:rgba(235,244,255,var(--placeholder-opacity))}.xl\:focus\:placeholder-indigo-200:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#c3dafe;color:rgba(195,218,254,var(--placeholder-opacity))}.xl\:focus\:placeholder-indigo-200:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#c3dafe;color:rgba(195,218,254,var(--placeholder-opacity))}.xl\:focus\:placeholder-indigo-200:focus::placeholder{--placeholder-opacity:1;color:#c3dafe;color:rgba(195,218,254,var(--placeholder-opacity))}.xl\:focus\:placeholder-indigo-300:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#a3bffa;color:rgba(163,191,250,var(--placeholder-opacity))}.xl\:focus\:placeholder-indigo-300:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#a3bffa;color:rgba(163,191,250,var(--placeholder-opacity))}.xl\:focus\:placeholder-indigo-300:focus::placeholder{--placeholder-opacity:1;color:#a3bffa;color:rgba(163,191,250,var(--placeholder-opacity))}.xl\:focus\:placeholder-indigo-400:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#7f9cf5;color:rgba(127,156,245,var(--placeholder-opacity))}.xl\:focus\:placeholder-indigo-400:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#7f9cf5;color:rgba(127,156,245,var(--placeholder-opacity))}.xl\:focus\:placeholder-indigo-400:focus::placeholder{--placeholder-opacity:1;color:#7f9cf5;color:rgba(127,156,245,var(--placeholder-opacity))}.xl\:focus\:placeholder-indigo-500:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#667eea;color:rgba(102,126,234,var(--placeholder-opacity))}.xl\:focus\:placeholder-indigo-500:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#667eea;color:rgba(102,126,234,var(--placeholder-opacity))}.xl\:focus\:placeholder-indigo-500:focus::placeholder{--placeholder-opacity:1;color:#667eea;color:rgba(102,126,234,var(--placeholder-opacity))}.xl\:focus\:placeholder-indigo-600:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#5a67d8;color:rgba(90,103,216,var(--placeholder-opacity))}.xl\:focus\:placeholder-indigo-600:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#5a67d8;color:rgba(90,103,216,var(--placeholder-opacity))}.xl\:focus\:placeholder-indigo-600:focus::placeholder{--placeholder-opacity:1;color:#5a67d8;color:rgba(90,103,216,var(--placeholder-opacity))}.xl\:focus\:placeholder-indigo-700:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#4c51bf;color:rgba(76,81,191,var(--placeholder-opacity))}.xl\:focus\:placeholder-indigo-700:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#4c51bf;color:rgba(76,81,191,var(--placeholder-opacity))}.xl\:focus\:placeholder-indigo-700:focus::placeholder{--placeholder-opacity:1;color:#4c51bf;color:rgba(76,81,191,var(--placeholder-opacity))}.xl\:focus\:placeholder-indigo-800:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#434190;color:rgba(67,65,144,var(--placeholder-opacity))}.xl\:focus\:placeholder-indigo-800:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#434190;color:rgba(67,65,144,var(--placeholder-opacity))}.xl\:focus\:placeholder-indigo-800:focus::placeholder{--placeholder-opacity:1;color:#434190;color:rgba(67,65,144,var(--placeholder-opacity))}.xl\:focus\:placeholder-indigo-900:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#3c366b;color:rgba(60,54,107,var(--placeholder-opacity))}.xl\:focus\:placeholder-indigo-900:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#3c366b;color:rgba(60,54,107,var(--placeholder-opacity))}.xl\:focus\:placeholder-indigo-900:focus::placeholder{--placeholder-opacity:1;color:#3c366b;color:rgba(60,54,107,var(--placeholder-opacity))}.xl\:focus\:placeholder-purple-100:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#faf5ff;color:rgba(250,245,255,var(--placeholder-opacity))}.xl\:focus\:placeholder-purple-100:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#faf5ff;color:rgba(250,245,255,var(--placeholder-opacity))}.xl\:focus\:placeholder-purple-100:focus::placeholder{--placeholder-opacity:1;color:#faf5ff;color:rgba(250,245,255,var(--placeholder-opacity))}.xl\:focus\:placeholder-purple-200:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#e9d8fd;color:rgba(233,216,253,var(--placeholder-opacity))}.xl\:focus\:placeholder-purple-200:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#e9d8fd;color:rgba(233,216,253,var(--placeholder-opacity))}.xl\:focus\:placeholder-purple-200:focus::placeholder{--placeholder-opacity:1;color:#e9d8fd;color:rgba(233,216,253,var(--placeholder-opacity))}.xl\:focus\:placeholder-purple-300:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#d6bcfa;color:rgba(214,188,250,var(--placeholder-opacity))}.xl\:focus\:placeholder-purple-300:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#d6bcfa;color:rgba(214,188,250,var(--placeholder-opacity))}.xl\:focus\:placeholder-purple-300:focus::placeholder{--placeholder-opacity:1;color:#d6bcfa;color:rgba(214,188,250,var(--placeholder-opacity))}.xl\:focus\:placeholder-purple-400:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#b794f4;color:rgba(183,148,244,var(--placeholder-opacity))}.xl\:focus\:placeholder-purple-400:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#b794f4;color:rgba(183,148,244,var(--placeholder-opacity))}.xl\:focus\:placeholder-purple-400:focus::placeholder{--placeholder-opacity:1;color:#b794f4;color:rgba(183,148,244,var(--placeholder-opacity))}.xl\:focus\:placeholder-purple-500:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#9f7aea;color:rgba(159,122,234,var(--placeholder-opacity))}.xl\:focus\:placeholder-purple-500:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#9f7aea;color:rgba(159,122,234,var(--placeholder-opacity))}.xl\:focus\:placeholder-purple-500:focus::placeholder{--placeholder-opacity:1;color:#9f7aea;color:rgba(159,122,234,var(--placeholder-opacity))}.xl\:focus\:placeholder-purple-600:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#805ad5;color:rgba(128,90,213,var(--placeholder-opacity))}.xl\:focus\:placeholder-purple-600:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#805ad5;color:rgba(128,90,213,var(--placeholder-opacity))}.xl\:focus\:placeholder-purple-600:focus::placeholder{--placeholder-opacity:1;color:#805ad5;color:rgba(128,90,213,var(--placeholder-opacity))}.xl\:focus\:placeholder-purple-700:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#6b46c1;color:rgba(107,70,193,var(--placeholder-opacity))}.xl\:focus\:placeholder-purple-700:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#6b46c1;color:rgba(107,70,193,var(--placeholder-opacity))}.xl\:focus\:placeholder-purple-700:focus::placeholder{--placeholder-opacity:1;color:#6b46c1;color:rgba(107,70,193,var(--placeholder-opacity))}.xl\:focus\:placeholder-purple-800:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#553c9a;color:rgba(85,60,154,var(--placeholder-opacity))}.xl\:focus\:placeholder-purple-800:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#553c9a;color:rgba(85,60,154,var(--placeholder-opacity))}.xl\:focus\:placeholder-purple-800:focus::placeholder{--placeholder-opacity:1;color:#553c9a;color:rgba(85,60,154,var(--placeholder-opacity))}.xl\:focus\:placeholder-purple-900:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#44337a;color:rgba(68,51,122,var(--placeholder-opacity))}.xl\:focus\:placeholder-purple-900:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#44337a;color:rgba(68,51,122,var(--placeholder-opacity))}.xl\:focus\:placeholder-purple-900:focus::placeholder{--placeholder-opacity:1;color:#44337a;color:rgba(68,51,122,var(--placeholder-opacity))}.xl\:focus\:placeholder-pink-100:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#fff5f7;color:rgba(255,245,247,var(--placeholder-opacity))}.xl\:focus\:placeholder-pink-100:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#fff5f7;color:rgba(255,245,247,var(--placeholder-opacity))}.xl\:focus\:placeholder-pink-100:focus::placeholder{--placeholder-opacity:1;color:#fff5f7;color:rgba(255,245,247,var(--placeholder-opacity))}.xl\:focus\:placeholder-pink-200:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#fed7e2;color:rgba(254,215,226,var(--placeholder-opacity))}.xl\:focus\:placeholder-pink-200:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#fed7e2;color:rgba(254,215,226,var(--placeholder-opacity))}.xl\:focus\:placeholder-pink-200:focus::placeholder{--placeholder-opacity:1;color:#fed7e2;color:rgba(254,215,226,var(--placeholder-opacity))}.xl\:focus\:placeholder-pink-300:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#fbb6ce;color:rgba(251,182,206,var(--placeholder-opacity))}.xl\:focus\:placeholder-pink-300:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#fbb6ce;color:rgba(251,182,206,var(--placeholder-opacity))}.xl\:focus\:placeholder-pink-300:focus::placeholder{--placeholder-opacity:1;color:#fbb6ce;color:rgba(251,182,206,var(--placeholder-opacity))}.xl\:focus\:placeholder-pink-400:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#f687b3;color:rgba(246,135,179,var(--placeholder-opacity))}.xl\:focus\:placeholder-pink-400:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#f687b3;color:rgba(246,135,179,var(--placeholder-opacity))}.xl\:focus\:placeholder-pink-400:focus::placeholder{--placeholder-opacity:1;color:#f687b3;color:rgba(246,135,179,var(--placeholder-opacity))}.xl\:focus\:placeholder-pink-500:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#ed64a6;color:rgba(237,100,166,var(--placeholder-opacity))}.xl\:focus\:placeholder-pink-500:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#ed64a6;color:rgba(237,100,166,var(--placeholder-opacity))}.xl\:focus\:placeholder-pink-500:focus::placeholder{--placeholder-opacity:1;color:#ed64a6;color:rgba(237,100,166,var(--placeholder-opacity))}.xl\:focus\:placeholder-pink-600:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#d53f8c;color:rgba(213,63,140,var(--placeholder-opacity))}.xl\:focus\:placeholder-pink-600:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#d53f8c;color:rgba(213,63,140,var(--placeholder-opacity))}.xl\:focus\:placeholder-pink-600:focus::placeholder{--placeholder-opacity:1;color:#d53f8c;color:rgba(213,63,140,var(--placeholder-opacity))}.xl\:focus\:placeholder-pink-700:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#b83280;color:rgba(184,50,128,var(--placeholder-opacity))}.xl\:focus\:placeholder-pink-700:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#b83280;color:rgba(184,50,128,var(--placeholder-opacity))}.xl\:focus\:placeholder-pink-700:focus::placeholder{--placeholder-opacity:1;color:#b83280;color:rgba(184,50,128,var(--placeholder-opacity))}.xl\:focus\:placeholder-pink-800:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#97266d;color:rgba(151,38,109,var(--placeholder-opacity))}.xl\:focus\:placeholder-pink-800:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#97266d;color:rgba(151,38,109,var(--placeholder-opacity))}.xl\:focus\:placeholder-pink-800:focus::placeholder{--placeholder-opacity:1;color:#97266d;color:rgba(151,38,109,var(--placeholder-opacity))}.xl\:focus\:placeholder-pink-900:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#702459;color:rgba(112,36,89,var(--placeholder-opacity))}.xl\:focus\:placeholder-pink-900:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#702459;color:rgba(112,36,89,var(--placeholder-opacity))}.xl\:focus\:placeholder-pink-900:focus::placeholder{--placeholder-opacity:1;color:#702459;color:rgba(112,36,89,var(--placeholder-opacity))}.xl\:placeholder-opacity-0:-ms-input-placeholder{--placeholder-opacity:0}.xl\:placeholder-opacity-0::-ms-input-placeholder{--placeholder-opacity:0}.xl\:placeholder-opacity-0::placeholder{--placeholder-opacity:0}.xl\:placeholder-opacity-25:-ms-input-placeholder{--placeholder-opacity:0.25}.xl\:placeholder-opacity-25::-ms-input-placeholder{--placeholder-opacity:0.25}.xl\:placeholder-opacity-25::placeholder{--placeholder-opacity:0.25}.xl\:placeholder-opacity-50:-ms-input-placeholder{--placeholder-opacity:0.5}.xl\:placeholder-opacity-50::-ms-input-placeholder{--placeholder-opacity:0.5}.xl\:placeholder-opacity-50::placeholder{--placeholder-opacity:0.5}.xl\:placeholder-opacity-75:-ms-input-placeholder{--placeholder-opacity:0.75}.xl\:placeholder-opacity-75::-ms-input-placeholder{--placeholder-opacity:0.75}.xl\:placeholder-opacity-75::placeholder{--placeholder-opacity:0.75}.xl\:placeholder-opacity-100:-ms-input-placeholder{--placeholder-opacity:1}.xl\:placeholder-opacity-100::-ms-input-placeholder{--placeholder-opacity:1}.xl\:placeholder-opacity-100::placeholder{--placeholder-opacity:1}.xl\:focus\:placeholder-opacity-0:focus:-ms-input-placeholder{--placeholder-opacity:0}.xl\:focus\:placeholder-opacity-0:focus::-ms-input-placeholder{--placeholder-opacity:0}.xl\:focus\:placeholder-opacity-0:focus::placeholder{--placeholder-opacity:0}.xl\:focus\:placeholder-opacity-25:focus:-ms-input-placeholder{--placeholder-opacity:0.25}.xl\:focus\:placeholder-opacity-25:focus::-ms-input-placeholder{--placeholder-opacity:0.25}.xl\:focus\:placeholder-opacity-25:focus::placeholder{--placeholder-opacity:0.25}.xl\:focus\:placeholder-opacity-50:focus:-ms-input-placeholder{--placeholder-opacity:0.5}.xl\:focus\:placeholder-opacity-50:focus::-ms-input-placeholder{--placeholder-opacity:0.5}.xl\:focus\:placeholder-opacity-50:focus::placeholder{--placeholder-opacity:0.5}.xl\:focus\:placeholder-opacity-75:focus:-ms-input-placeholder{--placeholder-opacity:0.75}.xl\:focus\:placeholder-opacity-75:focus::-ms-input-placeholder{--placeholder-opacity:0.75}.xl\:focus\:placeholder-opacity-75:focus::placeholder{--placeholder-opacity:0.75}.xl\:focus\:placeholder-opacity-100:focus:-ms-input-placeholder{--placeholder-opacity:1}.xl\:focus\:placeholder-opacity-100:focus::-ms-input-placeholder{--placeholder-opacity:1}.xl\:focus\:placeholder-opacity-100:focus::placeholder{--placeholder-opacity:1}.xl\:pointer-events-none{pointer-events:none}.xl\:pointer-events-auto{pointer-events:auto}.xl\:static{position:static}.xl\:fixed{position:fixed}.xl\:absolute{position:absolute}.xl\:relative{position:relative}.xl\:sticky{position:-webkit-sticky;position:sticky}.xl\:inset-0{top:0;right:0;bottom:0;left:0}.xl\:inset-auto{top:auto;right:auto;bottom:auto;left:auto}.xl\:inset-y-0{top:0;bottom:0}.xl\:inset-x-0{right:0;left:0}.xl\:inset-y-auto{top:auto;bottom:auto}.xl\:inset-x-auto{right:auto;left:auto}.xl\:top-0{top:0}.xl\:right-0{right:0}.xl\:bottom-0{bottom:0}.xl\:left-0{left:0}.xl\:top-auto{top:auto}.xl\:right-auto{right:auto}.xl\:bottom-auto{bottom:auto}.xl\:left-auto{left:auto}.xl\:resize-none{resize:none}.xl\:resize-y{resize:vertical}.xl\:resize-x{resize:horizontal}.xl\:resize{resize:both}.xl\:shadow-xs{box-shadow:0 0 0 1px rgba(0,0,0,.05)}.xl\:shadow-sm{box-shadow:0 1px 2px 0 rgba(0,0,0,.05)}.xl\:shadow{box-shadow:0 1px 3px 0 rgba(0,0,0,.1),0 1px 2px 0 rgba(0,0,0,.06)}.xl\:shadow-md{box-shadow:0 4px 6px -1px rgba(0,0,0,.1),0 2px 4px -1px rgba(0,0,0,.06)}.xl\:shadow-lg{box-shadow:0 10px 15px -3px rgba(0,0,0,.1),0 4px 6px -2px rgba(0,0,0,.05)}.xl\:shadow-xl{box-shadow:0 20px 25px -5px rgba(0,0,0,.1),0 10px 10px -5px rgba(0,0,0,.04)}.xl\:shadow-2xl{box-shadow:0 25px 50px -12px rgba(0,0,0,.25)}.xl\:shadow-inner{box-shadow:inset 0 2px 4px 0 rgba(0,0,0,.06)}.xl\:shadow-outline{box-shadow:0 0 0 3px rgba(66,153,225,.5)}.xl\:shadow-none{box-shadow:none}.xl\:hover\:shadow-xs:hover{box-shadow:0 0 0 1px rgba(0,0,0,.05)}.xl\:hover\:shadow-sm:hover{box-shadow:0 1px 2px 0 rgba(0,0,0,.05)}.xl\:hover\:shadow:hover{box-shadow:0 1px 3px 0 rgba(0,0,0,.1),0 1px 2px 0 rgba(0,0,0,.06)}.xl\:hover\:shadow-md:hover{box-shadow:0 4px 6px -1px rgba(0,0,0,.1),0 2px 4px -1px rgba(0,0,0,.06)}.xl\:hover\:shadow-lg:hover{box-shadow:0 10px 15px -3px rgba(0,0,0,.1),0 4px 6px -2px rgba(0,0,0,.05)}.xl\:hover\:shadow-xl:hover{box-shadow:0 20px 25px -5px rgba(0,0,0,.1),0 10px 10px -5px rgba(0,0,0,.04)}.xl\:hover\:shadow-2xl:hover{box-shadow:0 25px 50px -12px rgba(0,0,0,.25)}.xl\:hover\:shadow-inner:hover{box-shadow:inset 0 2px 4px 0 rgba(0,0,0,.06)}.xl\:hover\:shadow-outline:hover{box-shadow:0 0 0 3px rgba(66,153,225,.5)}.xl\:hover\:shadow-none:hover{box-shadow:none}.xl\:focus\:shadow-xs:focus{box-shadow:0 0 0 1px rgba(0,0,0,.05)}.xl\:focus\:shadow-sm:focus{box-shadow:0 1px 2px 0 rgba(0,0,0,.05)}.xl\:focus\:shadow:focus{box-shadow:0 1px 3px 0 rgba(0,0,0,.1),0 1px 2px 0 rgba(0,0,0,.06)}.xl\:focus\:shadow-md:focus{box-shadow:0 4px 6px -1px rgba(0,0,0,.1),0 2px 4px -1px rgba(0,0,0,.06)}.xl\:focus\:shadow-lg:focus{box-shadow:0 10px 15px -3px rgba(0,0,0,.1),0 4px 6px -2px rgba(0,0,0,.05)}.xl\:focus\:shadow-xl:focus{box-shadow:0 20px 25px -5px rgba(0,0,0,.1),0 10px 10px -5px rgba(0,0,0,.04)}.xl\:focus\:shadow-2xl:focus{box-shadow:0 25px 50px -12px rgba(0,0,0,.25)}.xl\:focus\:shadow-inner:focus{box-shadow:inset 0 2px 4px 0 rgba(0,0,0,.06)}.xl\:focus\:shadow-outline:focus{box-shadow:0 0 0 3px rgba(66,153,225,.5)}.xl\:focus\:shadow-none:focus{box-shadow:none}.xl\:fill-current{fill:currentColor}.xl\:stroke-current{stroke:currentColor}.xl\:stroke-0{stroke-width:0}.xl\:stroke-1{stroke-width:1}.xl\:stroke-2{stroke-width:2}.xl\:table-auto{table-layout:auto}.xl\:table-fixed{table-layout:fixed}.xl\:text-left{text-align:left}.xl\:text-center{text-align:center}.xl\:text-right{text-align:right}.xl\:text-justify{text-align:justify}.xl\:text-transparent{color:transparent}.xl\:text-current{color:currentColor}.xl\:text-black{--text-opacity:1;color:#000;color:rgba(0,0,0,var(--text-opacity))}.xl\:text-white{--text-opacity:1;color:#fff;color:rgba(255,255,255,var(--text-opacity))}.xl\:text-gray-100{--text-opacity:1;color:#f7fafc;color:rgba(247,250,252,var(--text-opacity))}.xl\:text-gray-200{--text-opacity:1;color:#edf2f7;color:rgba(237,242,247,var(--text-opacity))}.xl\:text-gray-300{--text-opacity:1;color:#e2e8f0;color:rgba(226,232,240,var(--text-opacity))}.xl\:text-gray-400{--text-opacity:1;color:#cbd5e0;color:rgba(203,213,224,var(--text-opacity))}.xl\:text-gray-500{--text-opacity:1;color:#a0aec0;color:rgba(160,174,192,var(--text-opacity))}.xl\:text-gray-600{--text-opacity:1;color:#718096;color:rgba(113,128,150,var(--text-opacity))}.xl\:text-gray-700{--text-opacity:1;color:#4a5568;color:rgba(74,85,104,var(--text-opacity))}.xl\:text-gray-800{--text-opacity:1;color:#2d3748;color:rgba(45,55,72,var(--text-opacity))}.xl\:text-gray-900{--text-opacity:1;color:#1a202c;color:rgba(26,32,44,var(--text-opacity))}.xl\:text-red-100{--text-opacity:1;color:#fff5f5;color:rgba(255,245,245,var(--text-opacity))}.xl\:text-red-200{--text-opacity:1;color:#fed7d7;color:rgba(254,215,215,var(--text-opacity))}.xl\:text-red-300{--text-opacity:1;color:#feb2b2;color:rgba(254,178,178,var(--text-opacity))}.xl\:text-red-400{--text-opacity:1;color:#fc8181;color:rgba(252,129,129,var(--text-opacity))}.xl\:text-red-500{--text-opacity:1;color:#f56565;color:rgba(245,101,101,var(--text-opacity))}.xl\:text-red-600{--text-opacity:1;color:#e53e3e;color:rgba(229,62,62,var(--text-opacity))}.xl\:text-red-700{--text-opacity:1;color:#c53030;color:rgba(197,48,48,var(--text-opacity))}.xl\:text-red-800{--text-opacity:1;color:#9b2c2c;color:rgba(155,44,44,var(--text-opacity))}.xl\:text-red-900{--text-opacity:1;color:#742a2a;color:rgba(116,42,42,var(--text-opacity))}.xl\:text-orange-100{--text-opacity:1;color:#fffaf0;color:rgba(255,250,240,var(--text-opacity))}.xl\:text-orange-200{--text-opacity:1;color:#feebc8;color:rgba(254,235,200,var(--text-opacity))}.xl\:text-orange-300{--text-opacity:1;color:#fbd38d;color:rgba(251,211,141,var(--text-opacity))}.xl\:text-orange-400{--text-opacity:1;color:#f6ad55;color:rgba(246,173,85,var(--text-opacity))}.xl\:text-orange-500{--text-opacity:1;color:#ed8936;color:rgba(237,137,54,var(--text-opacity))}.xl\:text-orange-600{--text-opacity:1;color:#dd6b20;color:rgba(221,107,32,var(--text-opacity))}.xl\:text-orange-700{--text-opacity:1;color:#c05621;color:rgba(192,86,33,var(--text-opacity))}.xl\:text-orange-800{--text-opacity:1;color:#9c4221;color:rgba(156,66,33,var(--text-opacity))}.xl\:text-orange-900{--text-opacity:1;color:#7b341e;color:rgba(123,52,30,var(--text-opacity))}.xl\:text-yellow-100{--text-opacity:1;color:ivory;color:rgba(255,255,240,var(--text-opacity))}.xl\:text-yellow-200{--text-opacity:1;color:#fefcbf;color:rgba(254,252,191,var(--text-opacity))}.xl\:text-yellow-300{--text-opacity:1;color:#faf089;color:rgba(250,240,137,var(--text-opacity))}.xl\:text-yellow-400{--text-opacity:1;color:#f6e05e;color:rgba(246,224,94,var(--text-opacity))}.xl\:text-yellow-500{--text-opacity:1;color:#ecc94b;color:rgba(236,201,75,var(--text-opacity))}.xl\:text-yellow-600{--text-opacity:1;color:#d69e2e;color:rgba(214,158,46,var(--text-opacity))}.xl\:text-yellow-700{--text-opacity:1;color:#b7791f;color:rgba(183,121,31,var(--text-opacity))}.xl\:text-yellow-800{--text-opacity:1;color:#975a16;color:rgba(151,90,22,var(--text-opacity))}.xl\:text-yellow-900{--text-opacity:1;color:#744210;color:rgba(116,66,16,var(--text-opacity))}.xl\:text-green-100{--text-opacity:1;color:#f0fff4;color:rgba(240,255,244,var(--text-opacity))}.xl\:text-green-200{--text-opacity:1;color:#c6f6d5;color:rgba(198,246,213,var(--text-opacity))}.xl\:text-green-300{--text-opacity:1;color:#9ae6b4;color:rgba(154,230,180,var(--text-opacity))}.xl\:text-green-400{--text-opacity:1;color:#68d391;color:rgba(104,211,145,var(--text-opacity))}.xl\:text-green-500{--text-opacity:1;color:#48bb78;color:rgba(72,187,120,var(--text-opacity))}.xl\:text-green-600{--text-opacity:1;color:#38a169;color:rgba(56,161,105,var(--text-opacity))}.xl\:text-green-700{--text-opacity:1;color:#2f855a;color:rgba(47,133,90,var(--text-opacity))}.xl\:text-green-800{--text-opacity:1;color:#276749;color:rgba(39,103,73,var(--text-opacity))}.xl\:text-green-900{--text-opacity:1;color:#22543d;color:rgba(34,84,61,var(--text-opacity))}.xl\:text-teal-100{--text-opacity:1;color:#e6fffa;color:rgba(230,255,250,var(--text-opacity))}.xl\:text-teal-200{--text-opacity:1;color:#b2f5ea;color:rgba(178,245,234,var(--text-opacity))}.xl\:text-teal-300{--text-opacity:1;color:#81e6d9;color:rgba(129,230,217,var(--text-opacity))}.xl\:text-teal-400{--text-opacity:1;color:#4fd1c5;color:rgba(79,209,197,var(--text-opacity))}.xl\:text-teal-500{--text-opacity:1;color:#38b2ac;color:rgba(56,178,172,var(--text-opacity))}.xl\:text-teal-600{--text-opacity:1;color:#319795;color:rgba(49,151,149,var(--text-opacity))}.xl\:text-teal-700{--text-opacity:1;color:#2c7a7b;color:rgba(44,122,123,var(--text-opacity))}.xl\:text-teal-800{--text-opacity:1;color:#285e61;color:rgba(40,94,97,var(--text-opacity))}.xl\:text-teal-900{--text-opacity:1;color:#234e52;color:rgba(35,78,82,var(--text-opacity))}.xl\:text-blue-100{--text-opacity:1;color:#ebf8ff;color:rgba(235,248,255,var(--text-opacity))}.xl\:text-blue-200{--text-opacity:1;color:#bee3f8;color:rgba(190,227,248,var(--text-opacity))}.xl\:text-blue-300{--text-opacity:1;color:#90cdf4;color:rgba(144,205,244,var(--text-opacity))}.xl\:text-blue-400{--text-opacity:1;color:#63b3ed;color:rgba(99,179,237,var(--text-opacity))}.xl\:text-blue-500{--text-opacity:1;color:#4299e1;color:rgba(66,153,225,var(--text-opacity))}.xl\:text-blue-600{--text-opacity:1;color:#3182ce;color:rgba(49,130,206,var(--text-opacity))}.xl\:text-blue-700{--text-opacity:1;color:#2b6cb0;color:rgba(43,108,176,var(--text-opacity))}.xl\:text-blue-800{--text-opacity:1;color:#2c5282;color:rgba(44,82,130,var(--text-opacity))}.xl\:text-blue-900{--text-opacity:1;color:#2a4365;color:rgba(42,67,101,var(--text-opacity))}.xl\:text-indigo-100{--text-opacity:1;color:#ebf4ff;color:rgba(235,244,255,var(--text-opacity))}.xl\:text-indigo-200{--text-opacity:1;color:#c3dafe;color:rgba(195,218,254,var(--text-opacity))}.xl\:text-indigo-300{--text-opacity:1;color:#a3bffa;color:rgba(163,191,250,var(--text-opacity))}.xl\:text-indigo-400{--text-opacity:1;color:#7f9cf5;color:rgba(127,156,245,var(--text-opacity))}.xl\:text-indigo-500{--text-opacity:1;color:#667eea;color:rgba(102,126,234,var(--text-opacity))}.xl\:text-indigo-600{--text-opacity:1;color:#5a67d8;color:rgba(90,103,216,var(--text-opacity))}.xl\:text-indigo-700{--text-opacity:1;color:#4c51bf;color:rgba(76,81,191,var(--text-opacity))}.xl\:text-indigo-800{--text-opacity:1;color:#434190;color:rgba(67,65,144,var(--text-opacity))}.xl\:text-indigo-900{--text-opacity:1;color:#3c366b;color:rgba(60,54,107,var(--text-opacity))}.xl\:text-purple-100{--text-opacity:1;color:#faf5ff;color:rgba(250,245,255,var(--text-opacity))}.xl\:text-purple-200{--text-opacity:1;color:#e9d8fd;color:rgba(233,216,253,var(--text-opacity))}.xl\:text-purple-300{--text-opacity:1;color:#d6bcfa;color:rgba(214,188,250,var(--text-opacity))}.xl\:text-purple-400{--text-opacity:1;color:#b794f4;color:rgba(183,148,244,var(--text-opacity))}.xl\:text-purple-500{--text-opacity:1;color:#9f7aea;color:rgba(159,122,234,var(--text-opacity))}.xl\:text-purple-600{--text-opacity:1;color:#805ad5;color:rgba(128,90,213,var(--text-opacity))}.xl\:text-purple-700{--text-opacity:1;color:#6b46c1;color:rgba(107,70,193,var(--text-opacity))}.xl\:text-purple-800{--text-opacity:1;color:#553c9a;color:rgba(85,60,154,var(--text-opacity))}.xl\:text-purple-900{--text-opacity:1;color:#44337a;color:rgba(68,51,122,var(--text-opacity))}.xl\:text-pink-100{--text-opacity:1;color:#fff5f7;color:rgba(255,245,247,var(--text-opacity))}.xl\:text-pink-200{--text-opacity:1;color:#fed7e2;color:rgba(254,215,226,var(--text-opacity))}.xl\:text-pink-300{--text-opacity:1;color:#fbb6ce;color:rgba(251,182,206,var(--text-opacity))}.xl\:text-pink-400{--text-opacity:1;color:#f687b3;color:rgba(246,135,179,var(--text-opacity))}.xl\:text-pink-500{--text-opacity:1;color:#ed64a6;color:rgba(237,100,166,var(--text-opacity))}.xl\:text-pink-600{--text-opacity:1;color:#d53f8c;color:rgba(213,63,140,var(--text-opacity))}.xl\:text-pink-700{--text-opacity:1;color:#b83280;color:rgba(184,50,128,var(--text-opacity))}.xl\:text-pink-800{--text-opacity:1;color:#97266d;color:rgba(151,38,109,var(--text-opacity))}.xl\:text-pink-900{--text-opacity:1;color:#702459;color:rgba(112,36,89,var(--text-opacity))}.xl\:hover\:text-transparent:hover{color:transparent}.xl\:hover\:text-current:hover{color:currentColor}.xl\:hover\:text-black:hover{--text-opacity:1;color:#000;color:rgba(0,0,0,var(--text-opacity))}.xl\:hover\:text-white:hover{--text-opacity:1;color:#fff;color:rgba(255,255,255,var(--text-opacity))}.xl\:hover\:text-gray-100:hover{--text-opacity:1;color:#f7fafc;color:rgba(247,250,252,var(--text-opacity))}.xl\:hover\:text-gray-200:hover{--text-opacity:1;color:#edf2f7;color:rgba(237,242,247,var(--text-opacity))}.xl\:hover\:text-gray-300:hover{--text-opacity:1;color:#e2e8f0;color:rgba(226,232,240,var(--text-opacity))}.xl\:hover\:text-gray-400:hover{--text-opacity:1;color:#cbd5e0;color:rgba(203,213,224,var(--text-opacity))}.xl\:hover\:text-gray-500:hover{--text-opacity:1;color:#a0aec0;color:rgba(160,174,192,var(--text-opacity))}.xl\:hover\:text-gray-600:hover{--text-opacity:1;color:#718096;color:rgba(113,128,150,var(--text-opacity))}.xl\:hover\:text-gray-700:hover{--text-opacity:1;color:#4a5568;color:rgba(74,85,104,var(--text-opacity))}.xl\:hover\:text-gray-800:hover{--text-opacity:1;color:#2d3748;color:rgba(45,55,72,var(--text-opacity))}.xl\:hover\:text-gray-900:hover{--text-opacity:1;color:#1a202c;color:rgba(26,32,44,var(--text-opacity))}.xl\:hover\:text-red-100:hover{--text-opacity:1;color:#fff5f5;color:rgba(255,245,245,var(--text-opacity))}.xl\:hover\:text-red-200:hover{--text-opacity:1;color:#fed7d7;color:rgba(254,215,215,var(--text-opacity))}.xl\:hover\:text-red-300:hover{--text-opacity:1;color:#feb2b2;color:rgba(254,178,178,var(--text-opacity))}.xl\:hover\:text-red-400:hover{--text-opacity:1;color:#fc8181;color:rgba(252,129,129,var(--text-opacity))}.xl\:hover\:text-red-500:hover{--text-opacity:1;color:#f56565;color:rgba(245,101,101,var(--text-opacity))}.xl\:hover\:text-red-600:hover{--text-opacity:1;color:#e53e3e;color:rgba(229,62,62,var(--text-opacity))}.xl\:hover\:text-red-700:hover{--text-opacity:1;color:#c53030;color:rgba(197,48,48,var(--text-opacity))}.xl\:hover\:text-red-800:hover{--text-opacity:1;color:#9b2c2c;color:rgba(155,44,44,var(--text-opacity))}.xl\:hover\:text-red-900:hover{--text-opacity:1;color:#742a2a;color:rgba(116,42,42,var(--text-opacity))}.xl\:hover\:text-orange-100:hover{--text-opacity:1;color:#fffaf0;color:rgba(255,250,240,var(--text-opacity))}.xl\:hover\:text-orange-200:hover{--text-opacity:1;color:#feebc8;color:rgba(254,235,200,var(--text-opacity))}.xl\:hover\:text-orange-300:hover{--text-opacity:1;color:#fbd38d;color:rgba(251,211,141,var(--text-opacity))}.xl\:hover\:text-orange-400:hover{--text-opacity:1;color:#f6ad55;color:rgba(246,173,85,var(--text-opacity))}.xl\:hover\:text-orange-500:hover{--text-opacity:1;color:#ed8936;color:rgba(237,137,54,var(--text-opacity))}.xl\:hover\:text-orange-600:hover{--text-opacity:1;color:#dd6b20;color:rgba(221,107,32,var(--text-opacity))}.xl\:hover\:text-orange-700:hover{--text-opacity:1;color:#c05621;color:rgba(192,86,33,var(--text-opacity))}.xl\:hover\:text-orange-800:hover{--text-opacity:1;color:#9c4221;color:rgba(156,66,33,var(--text-opacity))}.xl\:hover\:text-orange-900:hover{--text-opacity:1;color:#7b341e;color:rgba(123,52,30,var(--text-opacity))}.xl\:hover\:text-yellow-100:hover{--text-opacity:1;color:ivory;color:rgba(255,255,240,var(--text-opacity))}.xl\:hover\:text-yellow-200:hover{--text-opacity:1;color:#fefcbf;color:rgba(254,252,191,var(--text-opacity))}.xl\:hover\:text-yellow-300:hover{--text-opacity:1;color:#faf089;color:rgba(250,240,137,var(--text-opacity))}.xl\:hover\:text-yellow-400:hover{--text-opacity:1;color:#f6e05e;color:rgba(246,224,94,var(--text-opacity))}.xl\:hover\:text-yellow-500:hover{--text-opacity:1;color:#ecc94b;color:rgba(236,201,75,var(--text-opacity))}.xl\:hover\:text-yellow-600:hover{--text-opacity:1;color:#d69e2e;color:rgba(214,158,46,var(--text-opacity))}.xl\:hover\:text-yellow-700:hover{--text-opacity:1;color:#b7791f;color:rgba(183,121,31,var(--text-opacity))}.xl\:hover\:text-yellow-800:hover{--text-opacity:1;color:#975a16;color:rgba(151,90,22,var(--text-opacity))}.xl\:hover\:text-yellow-900:hover{--text-opacity:1;color:#744210;color:rgba(116,66,16,var(--text-opacity))}.xl\:hover\:text-green-100:hover{--text-opacity:1;color:#f0fff4;color:rgba(240,255,244,var(--text-opacity))}.xl\:hover\:text-green-200:hover{--text-opacity:1;color:#c6f6d5;color:rgba(198,246,213,var(--text-opacity))}.xl\:hover\:text-green-300:hover{--text-opacity:1;color:#9ae6b4;color:rgba(154,230,180,var(--text-opacity))}.xl\:hover\:text-green-400:hover{--text-opacity:1;color:#68d391;color:rgba(104,211,145,var(--text-opacity))}.xl\:hover\:text-green-500:hover{--text-opacity:1;color:#48bb78;color:rgba(72,187,120,var(--text-opacity))}.xl\:hover\:text-green-600:hover{--text-opacity:1;color:#38a169;color:rgba(56,161,105,var(--text-opacity))}.xl\:hover\:text-green-700:hover{--text-opacity:1;color:#2f855a;color:rgba(47,133,90,var(--text-opacity))}.xl\:hover\:text-green-800:hover{--text-opacity:1;color:#276749;color:rgba(39,103,73,var(--text-opacity))}.xl\:hover\:text-green-900:hover{--text-opacity:1;color:#22543d;color:rgba(34,84,61,var(--text-opacity))}.xl\:hover\:text-teal-100:hover{--text-opacity:1;color:#e6fffa;color:rgba(230,255,250,var(--text-opacity))}.xl\:hover\:text-teal-200:hover{--text-opacity:1;color:#b2f5ea;color:rgba(178,245,234,var(--text-opacity))}.xl\:hover\:text-teal-300:hover{--text-opacity:1;color:#81e6d9;color:rgba(129,230,217,var(--text-opacity))}.xl\:hover\:text-teal-400:hover{--text-opacity:1;color:#4fd1c5;color:rgba(79,209,197,var(--text-opacity))}.xl\:hover\:text-teal-500:hover{--text-opacity:1;color:#38b2ac;color:rgba(56,178,172,var(--text-opacity))}.xl\:hover\:text-teal-600:hover{--text-opacity:1;color:#319795;color:rgba(49,151,149,var(--text-opacity))}.xl\:hover\:text-teal-700:hover{--text-opacity:1;color:#2c7a7b;color:rgba(44,122,123,var(--text-opacity))}.xl\:hover\:text-teal-800:hover{--text-opacity:1;color:#285e61;color:rgba(40,94,97,var(--text-opacity))}.xl\:hover\:text-teal-900:hover{--text-opacity:1;color:#234e52;color:rgba(35,78,82,var(--text-opacity))}.xl\:hover\:text-blue-100:hover{--text-opacity:1;color:#ebf8ff;color:rgba(235,248,255,var(--text-opacity))}.xl\:hover\:text-blue-200:hover{--text-opacity:1;color:#bee3f8;color:rgba(190,227,248,var(--text-opacity))}.xl\:hover\:text-blue-300:hover{--text-opacity:1;color:#90cdf4;color:rgba(144,205,244,var(--text-opacity))}.xl\:hover\:text-blue-400:hover{--text-opacity:1;color:#63b3ed;color:rgba(99,179,237,var(--text-opacity))}.xl\:hover\:text-blue-500:hover{--text-opacity:1;color:#4299e1;color:rgba(66,153,225,var(--text-opacity))}.xl\:hover\:text-blue-600:hover{--text-opacity:1;color:#3182ce;color:rgba(49,130,206,var(--text-opacity))}.xl\:hover\:text-blue-700:hover{--text-opacity:1;color:#2b6cb0;color:rgba(43,108,176,var(--text-opacity))}.xl\:hover\:text-blue-800:hover{--text-opacity:1;color:#2c5282;color:rgba(44,82,130,var(--text-opacity))}.xl\:hover\:text-blue-900:hover{--text-opacity:1;color:#2a4365;color:rgba(42,67,101,var(--text-opacity))}.xl\:hover\:text-indigo-100:hover{--text-opacity:1;color:#ebf4ff;color:rgba(235,244,255,var(--text-opacity))}.xl\:hover\:text-indigo-200:hover{--text-opacity:1;color:#c3dafe;color:rgba(195,218,254,var(--text-opacity))}.xl\:hover\:text-indigo-300:hover{--text-opacity:1;color:#a3bffa;color:rgba(163,191,250,var(--text-opacity))}.xl\:hover\:text-indigo-400:hover{--text-opacity:1;color:#7f9cf5;color:rgba(127,156,245,var(--text-opacity))}.xl\:hover\:text-indigo-500:hover{--text-opacity:1;color:#667eea;color:rgba(102,126,234,var(--text-opacity))}.xl\:hover\:text-indigo-600:hover{--text-opacity:1;color:#5a67d8;color:rgba(90,103,216,var(--text-opacity))}.xl\:hover\:text-indigo-700:hover{--text-opacity:1;color:#4c51bf;color:rgba(76,81,191,var(--text-opacity))}.xl\:hover\:text-indigo-800:hover{--text-opacity:1;color:#434190;color:rgba(67,65,144,var(--text-opacity))}.xl\:hover\:text-indigo-900:hover{--text-opacity:1;color:#3c366b;color:rgba(60,54,107,var(--text-opacity))}.xl\:hover\:text-purple-100:hover{--text-opacity:1;color:#faf5ff;color:rgba(250,245,255,var(--text-opacity))}.xl\:hover\:text-purple-200:hover{--text-opacity:1;color:#e9d8fd;color:rgba(233,216,253,var(--text-opacity))}.xl\:hover\:text-purple-300:hover{--text-opacity:1;color:#d6bcfa;color:rgba(214,188,250,var(--text-opacity))}.xl\:hover\:text-purple-400:hover{--text-opacity:1;color:#b794f4;color:rgba(183,148,244,var(--text-opacity))}.xl\:hover\:text-purple-500:hover{--text-opacity:1;color:#9f7aea;color:rgba(159,122,234,var(--text-opacity))}.xl\:hover\:text-purple-600:hover{--text-opacity:1;color:#805ad5;color:rgba(128,90,213,var(--text-opacity))}.xl\:hover\:text-purple-700:hover{--text-opacity:1;color:#6b46c1;color:rgba(107,70,193,var(--text-opacity))}.xl\:hover\:text-purple-800:hover{--text-opacity:1;color:#553c9a;color:rgba(85,60,154,var(--text-opacity))}.xl\:hover\:text-purple-900:hover{--text-opacity:1;color:#44337a;color:rgba(68,51,122,var(--text-opacity))}.xl\:hover\:text-pink-100:hover{--text-opacity:1;color:#fff5f7;color:rgba(255,245,247,var(--text-opacity))}.xl\:hover\:text-pink-200:hover{--text-opacity:1;color:#fed7e2;color:rgba(254,215,226,var(--text-opacity))}.xl\:hover\:text-pink-300:hover{--text-opacity:1;color:#fbb6ce;color:rgba(251,182,206,var(--text-opacity))}.xl\:hover\:text-pink-400:hover{--text-opacity:1;color:#f687b3;color:rgba(246,135,179,var(--text-opacity))}.xl\:hover\:text-pink-500:hover{--text-opacity:1;color:#ed64a6;color:rgba(237,100,166,var(--text-opacity))}.xl\:hover\:text-pink-600:hover{--text-opacity:1;color:#d53f8c;color:rgba(213,63,140,var(--text-opacity))}.xl\:hover\:text-pink-700:hover{--text-opacity:1;color:#b83280;color:rgba(184,50,128,var(--text-opacity))}.xl\:hover\:text-pink-800:hover{--text-opacity:1;color:#97266d;color:rgba(151,38,109,var(--text-opacity))}.xl\:hover\:text-pink-900:hover{--text-opacity:1;color:#702459;color:rgba(112,36,89,var(--text-opacity))}.xl\:focus\:text-transparent:focus{color:transparent}.xl\:focus\:text-current:focus{color:currentColor}.xl\:focus\:text-black:focus{--text-opacity:1;color:#000;color:rgba(0,0,0,var(--text-opacity))}.xl\:focus\:text-white:focus{--text-opacity:1;color:#fff;color:rgba(255,255,255,var(--text-opacity))}.xl\:focus\:text-gray-100:focus{--text-opacity:1;color:#f7fafc;color:rgba(247,250,252,var(--text-opacity))}.xl\:focus\:text-gray-200:focus{--text-opacity:1;color:#edf2f7;color:rgba(237,242,247,var(--text-opacity))}.xl\:focus\:text-gray-300:focus{--text-opacity:1;color:#e2e8f0;color:rgba(226,232,240,var(--text-opacity))}.xl\:focus\:text-gray-400:focus{--text-opacity:1;color:#cbd5e0;color:rgba(203,213,224,var(--text-opacity))}.xl\:focus\:text-gray-500:focus{--text-opacity:1;color:#a0aec0;color:rgba(160,174,192,var(--text-opacity))}.xl\:focus\:text-gray-600:focus{--text-opacity:1;color:#718096;color:rgba(113,128,150,var(--text-opacity))}.xl\:focus\:text-gray-700:focus{--text-opacity:1;color:#4a5568;color:rgba(74,85,104,var(--text-opacity))}.xl\:focus\:text-gray-800:focus{--text-opacity:1;color:#2d3748;color:rgba(45,55,72,var(--text-opacity))}.xl\:focus\:text-gray-900:focus{--text-opacity:1;color:#1a202c;color:rgba(26,32,44,var(--text-opacity))}.xl\:focus\:text-red-100:focus{--text-opacity:1;color:#fff5f5;color:rgba(255,245,245,var(--text-opacity))}.xl\:focus\:text-red-200:focus{--text-opacity:1;color:#fed7d7;color:rgba(254,215,215,var(--text-opacity))}.xl\:focus\:text-red-300:focus{--text-opacity:1;color:#feb2b2;color:rgba(254,178,178,var(--text-opacity))}.xl\:focus\:text-red-400:focus{--text-opacity:1;color:#fc8181;color:rgba(252,129,129,var(--text-opacity))}.xl\:focus\:text-red-500:focus{--text-opacity:1;color:#f56565;color:rgba(245,101,101,var(--text-opacity))}.xl\:focus\:text-red-600:focus{--text-opacity:1;color:#e53e3e;color:rgba(229,62,62,var(--text-opacity))}.xl\:focus\:text-red-700:focus{--text-opacity:1;color:#c53030;color:rgba(197,48,48,var(--text-opacity))}.xl\:focus\:text-red-800:focus{--text-opacity:1;color:#9b2c2c;color:rgba(155,44,44,var(--text-opacity))}.xl\:focus\:text-red-900:focus{--text-opacity:1;color:#742a2a;color:rgba(116,42,42,var(--text-opacity))}.xl\:focus\:text-orange-100:focus{--text-opacity:1;color:#fffaf0;color:rgba(255,250,240,var(--text-opacity))}.xl\:focus\:text-orange-200:focus{--text-opacity:1;color:#feebc8;color:rgba(254,235,200,var(--text-opacity))}.xl\:focus\:text-orange-300:focus{--text-opacity:1;color:#fbd38d;color:rgba(251,211,141,var(--text-opacity))}.xl\:focus\:text-orange-400:focus{--text-opacity:1;color:#f6ad55;color:rgba(246,173,85,var(--text-opacity))}.xl\:focus\:text-orange-500:focus{--text-opacity:1;color:#ed8936;color:rgba(237,137,54,var(--text-opacity))}.xl\:focus\:text-orange-600:focus{--text-opacity:1;color:#dd6b20;color:rgba(221,107,32,var(--text-opacity))}.xl\:focus\:text-orange-700:focus{--text-opacity:1;color:#c05621;color:rgba(192,86,33,var(--text-opacity))}.xl\:focus\:text-orange-800:focus{--text-opacity:1;color:#9c4221;color:rgba(156,66,33,var(--text-opacity))}.xl\:focus\:text-orange-900:focus{--text-opacity:1;color:#7b341e;color:rgba(123,52,30,var(--text-opacity))}.xl\:focus\:text-yellow-100:focus{--text-opacity:1;color:ivory;color:rgba(255,255,240,var(--text-opacity))}.xl\:focus\:text-yellow-200:focus{--text-opacity:1;color:#fefcbf;color:rgba(254,252,191,var(--text-opacity))}.xl\:focus\:text-yellow-300:focus{--text-opacity:1;color:#faf089;color:rgba(250,240,137,var(--text-opacity))}.xl\:focus\:text-yellow-400:focus{--text-opacity:1;color:#f6e05e;color:rgba(246,224,94,var(--text-opacity))}.xl\:focus\:text-yellow-500:focus{--text-opacity:1;color:#ecc94b;color:rgba(236,201,75,var(--text-opacity))}.xl\:focus\:text-yellow-600:focus{--text-opacity:1;color:#d69e2e;color:rgba(214,158,46,var(--text-opacity))}.xl\:focus\:text-yellow-700:focus{--text-opacity:1;color:#b7791f;color:rgba(183,121,31,var(--text-opacity))}.xl\:focus\:text-yellow-800:focus{--text-opacity:1;color:#975a16;color:rgba(151,90,22,var(--text-opacity))}.xl\:focus\:text-yellow-900:focus{--text-opacity:1;color:#744210;color:rgba(116,66,16,var(--text-opacity))}.xl\:focus\:text-green-100:focus{--text-opacity:1;color:#f0fff4;color:rgba(240,255,244,var(--text-opacity))}.xl\:focus\:text-green-200:focus{--text-opacity:1;color:#c6f6d5;color:rgba(198,246,213,var(--text-opacity))}.xl\:focus\:text-green-300:focus{--text-opacity:1;color:#9ae6b4;color:rgba(154,230,180,var(--text-opacity))}.xl\:focus\:text-green-400:focus{--text-opacity:1;color:#68d391;color:rgba(104,211,145,var(--text-opacity))}.xl\:focus\:text-green-500:focus{--text-opacity:1;color:#48bb78;color:rgba(72,187,120,var(--text-opacity))}.xl\:focus\:text-green-600:focus{--text-opacity:1;color:#38a169;color:rgba(56,161,105,var(--text-opacity))}.xl\:focus\:text-green-700:focus{--text-opacity:1;color:#2f855a;color:rgba(47,133,90,var(--text-opacity))}.xl\:focus\:text-green-800:focus{--text-opacity:1;color:#276749;color:rgba(39,103,73,var(--text-opacity))}.xl\:focus\:text-green-900:focus{--text-opacity:1;color:#22543d;color:rgba(34,84,61,var(--text-opacity))}.xl\:focus\:text-teal-100:focus{--text-opacity:1;color:#e6fffa;color:rgba(230,255,250,var(--text-opacity))}.xl\:focus\:text-teal-200:focus{--text-opacity:1;color:#b2f5ea;color:rgba(178,245,234,var(--text-opacity))}.xl\:focus\:text-teal-300:focus{--text-opacity:1;color:#81e6d9;color:rgba(129,230,217,var(--text-opacity))}.xl\:focus\:text-teal-400:focus{--text-opacity:1;color:#4fd1c5;color:rgba(79,209,197,var(--text-opacity))}.xl\:focus\:text-teal-500:focus{--text-opacity:1;color:#38b2ac;color:rgba(56,178,172,var(--text-opacity))}.xl\:focus\:text-teal-600:focus{--text-opacity:1;color:#319795;color:rgba(49,151,149,var(--text-opacity))}.xl\:focus\:text-teal-700:focus{--text-opacity:1;color:#2c7a7b;color:rgba(44,122,123,var(--text-opacity))}.xl\:focus\:text-teal-800:focus{--text-opacity:1;color:#285e61;color:rgba(40,94,97,var(--text-opacity))}.xl\:focus\:text-teal-900:focus{--text-opacity:1;color:#234e52;color:rgba(35,78,82,var(--text-opacity))}.xl\:focus\:text-blue-100:focus{--text-opacity:1;color:#ebf8ff;color:rgba(235,248,255,var(--text-opacity))}.xl\:focus\:text-blue-200:focus{--text-opacity:1;color:#bee3f8;color:rgba(190,227,248,var(--text-opacity))}.xl\:focus\:text-blue-300:focus{--text-opacity:1;color:#90cdf4;color:rgba(144,205,244,var(--text-opacity))}.xl\:focus\:text-blue-400:focus{--text-opacity:1;color:#63b3ed;color:rgba(99,179,237,var(--text-opacity))}.xl\:focus\:text-blue-500:focus{--text-opacity:1;color:#4299e1;color:rgba(66,153,225,var(--text-opacity))}.xl\:focus\:text-blue-600:focus{--text-opacity:1;color:#3182ce;color:rgba(49,130,206,var(--text-opacity))}.xl\:focus\:text-blue-700:focus{--text-opacity:1;color:#2b6cb0;color:rgba(43,108,176,var(--text-opacity))}.xl\:focus\:text-blue-800:focus{--text-opacity:1;color:#2c5282;color:rgba(44,82,130,var(--text-opacity))}.xl\:focus\:text-blue-900:focus{--text-opacity:1;color:#2a4365;color:rgba(42,67,101,var(--text-opacity))}.xl\:focus\:text-indigo-100:focus{--text-opacity:1;color:#ebf4ff;color:rgba(235,244,255,var(--text-opacity))}.xl\:focus\:text-indigo-200:focus{--text-opacity:1;color:#c3dafe;color:rgba(195,218,254,var(--text-opacity))}.xl\:focus\:text-indigo-300:focus{--text-opacity:1;color:#a3bffa;color:rgba(163,191,250,var(--text-opacity))}.xl\:focus\:text-indigo-400:focus{--text-opacity:1;color:#7f9cf5;color:rgba(127,156,245,var(--text-opacity))}.xl\:focus\:text-indigo-500:focus{--text-opacity:1;color:#667eea;color:rgba(102,126,234,var(--text-opacity))}.xl\:focus\:text-indigo-600:focus{--text-opacity:1;color:#5a67d8;color:rgba(90,103,216,var(--text-opacity))}.xl\:focus\:text-indigo-700:focus{--text-opacity:1;color:#4c51bf;color:rgba(76,81,191,var(--text-opacity))}.xl\:focus\:text-indigo-800:focus{--text-opacity:1;color:#434190;color:rgba(67,65,144,var(--text-opacity))}.xl\:focus\:text-indigo-900:focus{--text-opacity:1;color:#3c366b;color:rgba(60,54,107,var(--text-opacity))}.xl\:focus\:text-purple-100:focus{--text-opacity:1;color:#faf5ff;color:rgba(250,245,255,var(--text-opacity))}.xl\:focus\:text-purple-200:focus{--text-opacity:1;color:#e9d8fd;color:rgba(233,216,253,var(--text-opacity))}.xl\:focus\:text-purple-300:focus{--text-opacity:1;color:#d6bcfa;color:rgba(214,188,250,var(--text-opacity))}.xl\:focus\:text-purple-400:focus{--text-opacity:1;color:#b794f4;color:rgba(183,148,244,var(--text-opacity))}.xl\:focus\:text-purple-500:focus{--text-opacity:1;color:#9f7aea;color:rgba(159,122,234,var(--text-opacity))}.xl\:focus\:text-purple-600:focus{--text-opacity:1;color:#805ad5;color:rgba(128,90,213,var(--text-opacity))}.xl\:focus\:text-purple-700:focus{--text-opacity:1;color:#6b46c1;color:rgba(107,70,193,var(--text-opacity))}.xl\:focus\:text-purple-800:focus{--text-opacity:1;color:#553c9a;color:rgba(85,60,154,var(--text-opacity))}.xl\:focus\:text-purple-900:focus{--text-opacity:1;color:#44337a;color:rgba(68,51,122,var(--text-opacity))}.xl\:focus\:text-pink-100:focus{--text-opacity:1;color:#fff5f7;color:rgba(255,245,247,var(--text-opacity))}.xl\:focus\:text-pink-200:focus{--text-opacity:1;color:#fed7e2;color:rgba(254,215,226,var(--text-opacity))}.xl\:focus\:text-pink-300:focus{--text-opacity:1;color:#fbb6ce;color:rgba(251,182,206,var(--text-opacity))}.xl\:focus\:text-pink-400:focus{--text-opacity:1;color:#f687b3;color:rgba(246,135,179,var(--text-opacity))}.xl\:focus\:text-pink-500:focus{--text-opacity:1;color:#ed64a6;color:rgba(237,100,166,var(--text-opacity))}.xl\:focus\:text-pink-600:focus{--text-opacity:1;color:#d53f8c;color:rgba(213,63,140,var(--text-opacity))}.xl\:focus\:text-pink-700:focus{--text-opacity:1;color:#b83280;color:rgba(184,50,128,var(--text-opacity))}.xl\:focus\:text-pink-800:focus{--text-opacity:1;color:#97266d;color:rgba(151,38,109,var(--text-opacity))}.xl\:focus\:text-pink-900:focus{--text-opacity:1;color:#702459;color:rgba(112,36,89,var(--text-opacity))}.xl\:text-opacity-0{--text-opacity:0}.xl\:text-opacity-25{--text-opacity:0.25}.xl\:text-opacity-50{--text-opacity:0.5}.xl\:text-opacity-75{--text-opacity:0.75}.xl\:text-opacity-100{--text-opacity:1}.xl\:hover\:text-opacity-0:hover{--text-opacity:0}.xl\:hover\:text-opacity-25:hover{--text-opacity:0.25}.xl\:hover\:text-opacity-50:hover{--text-opacity:0.5}.xl\:hover\:text-opacity-75:hover{--text-opacity:0.75}.xl\:hover\:text-opacity-100:hover{--text-opacity:1}.xl\:focus\:text-opacity-0:focus{--text-opacity:0}.xl\:focus\:text-opacity-25:focus{--text-opacity:0.25}.xl\:focus\:text-opacity-50:focus{--text-opacity:0.5}.xl\:focus\:text-opacity-75:focus{--text-opacity:0.75}.xl\:focus\:text-opacity-100:focus{--text-opacity:1}.xl\:italic{font-style:italic}.xl\:not-italic{font-style:normal}.xl\:uppercase{text-transform:uppercase}.xl\:lowercase{text-transform:lowercase}.xl\:capitalize{text-transform:capitalize}.xl\:normal-case{text-transform:none}.xl\:underline{text-decoration:underline}.xl\:line-through{text-decoration:line-through}.xl\:no-underline{text-decoration:none}.xl\:hover\:underline:hover{text-decoration:underline}.xl\:hover\:line-through:hover{text-decoration:line-through}.xl\:hover\:no-underline:hover{text-decoration:none}.xl\:focus\:underline:focus{text-decoration:underline}.xl\:focus\:line-through:focus{text-decoration:line-through}.xl\:focus\:no-underline:focus{text-decoration:none}.xl\:antialiased{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.xl\:subpixel-antialiased{-webkit-font-smoothing:auto;-moz-osx-font-smoothing:auto}.xl\:diagonal-fractions,.xl\:lining-nums,.xl\:oldstyle-nums,.xl\:ordinal,.xl\:proportional-nums,.xl\:slashed-zero,.xl\:stacked-fractions,.xl\:tabular-nums{--font-variant-numeric-ordinal:var(--tailwind-empty, );/*!*//*!*/--font-variant-numeric-slashed-zero:var(--tailwind-empty, );/*!*//*!*/--font-variant-numeric-figure:var(--tailwind-empty, );/*!*//*!*/--font-variant-numeric-spacing:var(--tailwind-empty, );/*!*//*!*/--font-variant-numeric-fraction:var(--tailwind-empty, );/*!*//*!*/font-variant-numeric:var(--font-variant-numeric-ordinal) var(--font-variant-numeric-slashed-zero) var(--font-variant-numeric-figure) var(--font-variant-numeric-spacing) var(--font-variant-numeric-fraction)}.xl\:normal-nums{font-variant-numeric:normal}.xl\:ordinal{--font-variant-numeric-ordinal:ordinal}.xl\:slashed-zero{--font-variant-numeric-slashed-zero:slashed-zero}.xl\:lining-nums{--font-variant-numeric-figure:lining-nums}.xl\:oldstyle-nums{--font-variant-numeric-figure:oldstyle-nums}.xl\:proportional-nums{--font-variant-numeric-spacing:proportional-nums}.xl\:tabular-nums{--font-variant-numeric-spacing:tabular-nums}.xl\:diagonal-fractions{--font-variant-numeric-fraction:diagonal-fractions}.xl\:stacked-fractions{--font-variant-numeric-fraction:stacked-fractions}.xl\:tracking-tighter{letter-spacing:-.05em}.xl\:tracking-tight{letter-spacing:-.025em}.xl\:tracking-normal{letter-spacing:0}.xl\:tracking-wide{letter-spacing:.025em}.xl\:tracking-wider{letter-spacing:.05em}.xl\:tracking-widest{letter-spacing:.1em}.xl\:select-none{-webkit-user-select:none;-ms-user-select:none;user-select:none}.xl\:select-text{-webkit-user-select:text;-ms-user-select:text;user-select:text}.xl\:select-all{-webkit-user-select:all;-ms-user-select:all;user-select:all}.xl\:select-auto{-webkit-user-select:auto;-ms-user-select:auto;user-select:auto}.xl\:align-baseline{vertical-align:baseline}.xl\:align-top{vertical-align:top}.xl\:align-middle{vertical-align:middle}.xl\:align-bottom{vertical-align:bottom}.xl\:align-text-top{vertical-align:text-top}.xl\:align-text-bottom{vertical-align:text-bottom}.xl\:visible{visibility:visible}.xl\:invisible{visibility:hidden}.xl\:whitespace-normal{white-space:normal}.xl\:whitespace-no-wrap{white-space:nowrap}.xl\:whitespace-pre{white-space:pre}.xl\:whitespace-pre-line{white-space:pre-line}.xl\:whitespace-pre-wrap{white-space:pre-wrap}.xl\:break-normal{word-wrap:normal;overflow-wrap:normal;word-break:normal}.xl\:break-words{word-wrap:break-word;overflow-wrap:break-word}.xl\:break-all{word-break:break-all}.xl\:truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.xl\:w-0{width:0}.xl\:w-1{width:.25rem}.xl\:w-2{width:.5rem}.xl\:w-3{width:.75rem}.xl\:w-4{width:1rem}.xl\:w-5{width:1.25rem}.xl\:w-6{width:1.5rem}.xl\:w-8{width:2rem}.xl\:w-10{width:2.5rem}.xl\:w-12{width:3rem}.xl\:w-16{width:4rem}.xl\:w-20{width:5rem}.xl\:w-24{width:6rem}.xl\:w-32{width:8rem}.xl\:w-40{width:10rem}.xl\:w-48{width:12rem}.xl\:w-56{width:14rem}.xl\:w-64{width:16rem}.xl\:w-auto{width:auto}.xl\:w-px{width:1px}.xl\:w-1\/2{width:50%}.xl\:w-1\/3{width:33.333333%}.xl\:w-2\/3{width:66.666667%}.xl\:w-1\/4{width:25%}.xl\:w-2\/4{width:50%}.xl\:w-3\/4{width:75%}.xl\:w-1\/5{width:20%}.xl\:w-2\/5{width:40%}.xl\:w-3\/5{width:60%}.xl\:w-4\/5{width:80%}.xl\:w-1\/6{width:16.666667%}.xl\:w-2\/6{width:33.333333%}.xl\:w-3\/6{width:50%}.xl\:w-4\/6{width:66.666667%}.xl\:w-5\/6{width:83.333333%}.xl\:w-1\/12{width:8.333333%}.xl\:w-2\/12{width:16.666667%}.xl\:w-3\/12{width:25%}.xl\:w-4\/12{width:33.333333%}.xl\:w-5\/12{width:41.666667%}.xl\:w-6\/12{width:50%}.xl\:w-7\/12{width:58.333333%}.xl\:w-8\/12{width:66.666667%}.xl\:w-9\/12{width:75%}.xl\:w-10\/12{width:83.333333%}.xl\:w-11\/12{width:91.666667%}.xl\:w-full{width:100%}.xl\:w-screen{width:100vw}.xl\:z-0{z-index:0}.xl\:z-10{z-index:10}.xl\:z-20{z-index:20}.xl\:z-30{z-index:30}.xl\:z-40{z-index:40}.xl\:z-50{z-index:50}.xl\:z-auto{z-index:auto}.xl\:gap-0{grid-gap:0;gap:0}.xl\:gap-1{grid-gap:.25rem;gap:.25rem}.xl\:gap-2{grid-gap:.5rem;gap:.5rem}.xl\:gap-3{grid-gap:.75rem;gap:.75rem}.xl\:gap-4{grid-gap:1rem;gap:1rem}.xl\:gap-5{grid-gap:1.25rem;gap:1.25rem}.xl\:gap-6{grid-gap:1.5rem;gap:1.5rem}.xl\:gap-8{grid-gap:2rem;gap:2rem}.xl\:gap-10{grid-gap:2.5rem;gap:2.5rem}.xl\:gap-12{grid-gap:3rem;gap:3rem}.xl\:gap-16{grid-gap:4rem;gap:4rem}.xl\:gap-20{grid-gap:5rem;gap:5rem}.xl\:gap-24{grid-gap:6rem;gap:6rem}.xl\:gap-32{grid-gap:8rem;gap:8rem}.xl\:gap-40{grid-gap:10rem;gap:10rem}.xl\:gap-48{grid-gap:12rem;gap:12rem}.xl\:gap-56{grid-gap:14rem;gap:14rem}.xl\:gap-64{grid-gap:16rem;gap:16rem}.xl\:gap-px{grid-gap:1px;gap:1px}.xl\:col-gap-0{grid-column-gap:0;column-gap:0}.xl\:col-gap-1{grid-column-gap:.25rem;column-gap:.25rem}.xl\:col-gap-2{grid-column-gap:.5rem;column-gap:.5rem}.xl\:col-gap-3{grid-column-gap:.75rem;column-gap:.75rem}.xl\:col-gap-4{grid-column-gap:1rem;column-gap:1rem}.xl\:col-gap-5{grid-column-gap:1.25rem;column-gap:1.25rem}.xl\:col-gap-6{grid-column-gap:1.5rem;column-gap:1.5rem}.xl\:col-gap-8{grid-column-gap:2rem;column-gap:2rem}.xl\:col-gap-10{grid-column-gap:2.5rem;column-gap:2.5rem}.xl\:col-gap-12{grid-column-gap:3rem;column-gap:3rem}.xl\:col-gap-16{grid-column-gap:4rem;column-gap:4rem}.xl\:col-gap-20{grid-column-gap:5rem;column-gap:5rem}.xl\:col-gap-24{grid-column-gap:6rem;column-gap:6rem}.xl\:col-gap-32{grid-column-gap:8rem;column-gap:8rem}.xl\:col-gap-40{grid-column-gap:10rem;column-gap:10rem}.xl\:col-gap-48{grid-column-gap:12rem;column-gap:12rem}.xl\:col-gap-56{grid-column-gap:14rem;column-gap:14rem}.xl\:col-gap-64{grid-column-gap:16rem;column-gap:16rem}.xl\:col-gap-px{grid-column-gap:1px;column-gap:1px}.xl\:gap-x-0{grid-column-gap:0;column-gap:0}.xl\:gap-x-1{grid-column-gap:.25rem;column-gap:.25rem}.xl\:gap-x-2{grid-column-gap:.5rem;column-gap:.5rem}.xl\:gap-x-3{grid-column-gap:.75rem;column-gap:.75rem}.xl\:gap-x-4{grid-column-gap:1rem;column-gap:1rem}.xl\:gap-x-5{grid-column-gap:1.25rem;column-gap:1.25rem}.xl\:gap-x-6{grid-column-gap:1.5rem;column-gap:1.5rem}.xl\:gap-x-8{grid-column-gap:2rem;column-gap:2rem}.xl\:gap-x-10{grid-column-gap:2.5rem;column-gap:2.5rem}.xl\:gap-x-12{grid-column-gap:3rem;column-gap:3rem}.xl\:gap-x-16{grid-column-gap:4rem;column-gap:4rem}.xl\:gap-x-20{grid-column-gap:5rem;column-gap:5rem}.xl\:gap-x-24{grid-column-gap:6rem;column-gap:6rem}.xl\:gap-x-32{grid-column-gap:8rem;column-gap:8rem}.xl\:gap-x-40{grid-column-gap:10rem;column-gap:10rem}.xl\:gap-x-48{grid-column-gap:12rem;column-gap:12rem}.xl\:gap-x-56{grid-column-gap:14rem;column-gap:14rem}.xl\:gap-x-64{grid-column-gap:16rem;column-gap:16rem}.xl\:gap-x-px{grid-column-gap:1px;column-gap:1px}.xl\:row-gap-0{grid-row-gap:0;row-gap:0}.xl\:row-gap-1{grid-row-gap:.25rem;row-gap:.25rem}.xl\:row-gap-2{grid-row-gap:.5rem;row-gap:.5rem}.xl\:row-gap-3{grid-row-gap:.75rem;row-gap:.75rem}.xl\:row-gap-4{grid-row-gap:1rem;row-gap:1rem}.xl\:row-gap-5{grid-row-gap:1.25rem;row-gap:1.25rem}.xl\:row-gap-6{grid-row-gap:1.5rem;row-gap:1.5rem}.xl\:row-gap-8{grid-row-gap:2rem;row-gap:2rem}.xl\:row-gap-10{grid-row-gap:2.5rem;row-gap:2.5rem}.xl\:row-gap-12{grid-row-gap:3rem;row-gap:3rem}.xl\:row-gap-16{grid-row-gap:4rem;row-gap:4rem}.xl\:row-gap-20{grid-row-gap:5rem;row-gap:5rem}.xl\:row-gap-24{grid-row-gap:6rem;row-gap:6rem}.xl\:row-gap-32{grid-row-gap:8rem;row-gap:8rem}.xl\:row-gap-40{grid-row-gap:10rem;row-gap:10rem}.xl\:row-gap-48{grid-row-gap:12rem;row-gap:12rem}.xl\:row-gap-56{grid-row-gap:14rem;row-gap:14rem}.xl\:row-gap-64{grid-row-gap:16rem;row-gap:16rem}.xl\:row-gap-px{grid-row-gap:1px;row-gap:1px}.xl\:gap-y-0{grid-row-gap:0;row-gap:0}.xl\:gap-y-1{grid-row-gap:.25rem;row-gap:.25rem}.xl\:gap-y-2{grid-row-gap:.5rem;row-gap:.5rem}.xl\:gap-y-3{grid-row-gap:.75rem;row-gap:.75rem}.xl\:gap-y-4{grid-row-gap:1rem;row-gap:1rem}.xl\:gap-y-5{grid-row-gap:1.25rem;row-gap:1.25rem}.xl\:gap-y-6{grid-row-gap:1.5rem;row-gap:1.5rem}.xl\:gap-y-8{grid-row-gap:2rem;row-gap:2rem}.xl\:gap-y-10{grid-row-gap:2.5rem;row-gap:2.5rem}.xl\:gap-y-12{grid-row-gap:3rem;row-gap:3rem}.xl\:gap-y-16{grid-row-gap:4rem;row-gap:4rem}.xl\:gap-y-20{grid-row-gap:5rem;row-gap:5rem}.xl\:gap-y-24{grid-row-gap:6rem;row-gap:6rem}.xl\:gap-y-32{grid-row-gap:8rem;row-gap:8rem}.xl\:gap-y-40{grid-row-gap:10rem;row-gap:10rem}.xl\:gap-y-48{grid-row-gap:12rem;row-gap:12rem}.xl\:gap-y-56{grid-row-gap:14rem;row-gap:14rem}.xl\:gap-y-64{grid-row-gap:16rem;row-gap:16rem}.xl\:gap-y-px{grid-row-gap:1px;row-gap:1px}.xl\:grid-flow-row{grid-auto-flow:row}.xl\:grid-flow-col{grid-auto-flow:column}.xl\:grid-flow-row-dense{grid-auto-flow:row dense}.xl\:grid-flow-col-dense{grid-auto-flow:column dense}.xl\:grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.xl\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.xl\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.xl\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.xl\:grid-cols-5{grid-template-columns:repeat(5,minmax(0,1fr))}.xl\:grid-cols-6{grid-template-columns:repeat(6,minmax(0,1fr))}.xl\:grid-cols-7{grid-template-columns:repeat(7,minmax(0,1fr))}.xl\:grid-cols-8{grid-template-columns:repeat(8,minmax(0,1fr))}.xl\:grid-cols-9{grid-template-columns:repeat(9,minmax(0,1fr))}.xl\:grid-cols-10{grid-template-columns:repeat(10,minmax(0,1fr))}.xl\:grid-cols-11{grid-template-columns:repeat(11,minmax(0,1fr))}.xl\:grid-cols-12{grid-template-columns:repeat(12,minmax(0,1fr))}.xl\:grid-cols-none{grid-template-columns:none}.xl\:auto-cols-auto{grid-auto-columns:auto}.xl\:auto-cols-min{grid-auto-columns:-webkit-min-content;grid-auto-columns:min-content}.xl\:auto-cols-max{grid-auto-columns:-webkit-max-content;grid-auto-columns:max-content}.xl\:auto-cols-fr{grid-auto-columns:minmax(0,1fr)}.xl\:col-auto{grid-column:auto}.xl\:col-span-1{grid-column:span 1/span 1}.xl\:col-span-2{grid-column:span 2/span 2}.xl\:col-span-3{grid-column:span 3/span 3}.xl\:col-span-4{grid-column:span 4/span 4}.xl\:col-span-5{grid-column:span 5/span 5}.xl\:col-span-6{grid-column:span 6/span 6}.xl\:col-span-7{grid-column:span 7/span 7}.xl\:col-span-8{grid-column:span 8/span 8}.xl\:col-span-9{grid-column:span 9/span 9}.xl\:col-span-10{grid-column:span 10/span 10}.xl\:col-span-11{grid-column:span 11/span 11}.xl\:col-span-12{grid-column:span 12/span 12}.xl\:col-span-full{grid-column:1/-1}.xl\:col-start-1{grid-column-start:1}.xl\:col-start-2{grid-column-start:2}.xl\:col-start-3{grid-column-start:3}.xl\:col-start-4{grid-column-start:4}.xl\:col-start-5{grid-column-start:5}.xl\:col-start-6{grid-column-start:6}.xl\:col-start-7{grid-column-start:7}.xl\:col-start-8{grid-column-start:8}.xl\:col-start-9{grid-column-start:9}.xl\:col-start-10{grid-column-start:10}.xl\:col-start-11{grid-column-start:11}.xl\:col-start-12{grid-column-start:12}.xl\:col-start-13{grid-column-start:13}.xl\:col-start-auto{grid-column-start:auto}.xl\:col-end-1{grid-column-end:1}.xl\:col-end-2{grid-column-end:2}.xl\:col-end-3{grid-column-end:3}.xl\:col-end-4{grid-column-end:4}.xl\:col-end-5{grid-column-end:5}.xl\:col-end-6{grid-column-end:6}.xl\:col-end-7{grid-column-end:7}.xl\:col-end-8{grid-column-end:8}.xl\:col-end-9{grid-column-end:9}.xl\:col-end-10{grid-column-end:10}.xl\:col-end-11{grid-column-end:11}.xl\:col-end-12{grid-column-end:12}.xl\:col-end-13{grid-column-end:13}.xl\:col-end-auto{grid-column-end:auto}.xl\:grid-rows-1{grid-template-rows:repeat(1,minmax(0,1fr))}.xl\:grid-rows-2{grid-template-rows:repeat(2,minmax(0,1fr))}.xl\:grid-rows-3{grid-template-rows:repeat(3,minmax(0,1fr))}.xl\:grid-rows-4{grid-template-rows:repeat(4,minmax(0,1fr))}.xl\:grid-rows-5{grid-template-rows:repeat(5,minmax(0,1fr))}.xl\:grid-rows-6{grid-template-rows:repeat(6,minmax(0,1fr))}.xl\:grid-rows-none{grid-template-rows:none}.xl\:auto-rows-auto{grid-auto-rows:auto}.xl\:auto-rows-min{grid-auto-rows:-webkit-min-content;grid-auto-rows:min-content}.xl\:auto-rows-max{grid-auto-rows:-webkit-max-content;grid-auto-rows:max-content}.xl\:auto-rows-fr{grid-auto-rows:minmax(0,1fr)}.xl\:row-auto{grid-row:auto}.xl\:row-span-1{grid-row:span 1/span 1}.xl\:row-span-2{grid-row:span 2/span 2}.xl\:row-span-3{grid-row:span 3/span 3}.xl\:row-span-4{grid-row:span 4/span 4}.xl\:row-span-5{grid-row:span 5/span 5}.xl\:row-span-6{grid-row:span 6/span 6}.xl\:row-span-full{grid-row:1/-1}.xl\:row-start-1{grid-row-start:1}.xl\:row-start-2{grid-row-start:2}.xl\:row-start-3{grid-row-start:3}.xl\:row-start-4{grid-row-start:4}.xl\:row-start-5{grid-row-start:5}.xl\:row-start-6{grid-row-start:6}.xl\:row-start-7{grid-row-start:7}.xl\:row-start-auto{grid-row-start:auto}.xl\:row-end-1{grid-row-end:1}.xl\:row-end-2{grid-row-end:2}.xl\:row-end-3{grid-row-end:3}.xl\:row-end-4{grid-row-end:4}.xl\:row-end-5{grid-row-end:5}.xl\:row-end-6{grid-row-end:6}.xl\:row-end-7{grid-row-end:7}.xl\:row-end-auto{grid-row-end:auto}.xl\:transform{--transform-translate-x:0;--transform-translate-y:0;--transform-rotate:0;--transform-skew-x:0;--transform-skew-y:0;--transform-scale-x:1;--transform-scale-y:1;transform:translateX(var(--transform-translate-x)) translateY(var(--transform-translate-y)) rotate(var(--transform-rotate)) skewX(var(--transform-skew-x)) skewY(var(--transform-skew-y)) scaleX(var(--transform-scale-x)) scaleY(var(--transform-scale-y))}.xl\:transform-none{transform:none}.xl\:origin-center{transform-origin:center}.xl\:origin-top{transform-origin:top}.xl\:origin-top-right{transform-origin:top right}.xl\:origin-right{transform-origin:right}.xl\:origin-bottom-right{transform-origin:bottom right}.xl\:origin-bottom{transform-origin:bottom}.xl\:origin-bottom-left{transform-origin:bottom left}.xl\:origin-left{transform-origin:left}.xl\:origin-top-left{transform-origin:top left}.xl\:scale-0{--transform-scale-x:0;--transform-scale-y:0}.xl\:scale-50{--transform-scale-x:.5;--transform-scale-y:.5}.xl\:scale-75{--transform-scale-x:.75;--transform-scale-y:.75}.xl\:scale-90{--transform-scale-x:.9;--transform-scale-y:.9}.xl\:scale-95{--transform-scale-x:.95;--transform-scale-y:.95}.xl\:scale-100{--transform-scale-x:1;--transform-scale-y:1}.xl\:scale-105{--transform-scale-x:1.05;--transform-scale-y:1.05}.xl\:scale-110{--transform-scale-x:1.1;--transform-scale-y:1.1}.xl\:scale-125{--transform-scale-x:1.25;--transform-scale-y:1.25}.xl\:scale-150{--transform-scale-x:1.5;--transform-scale-y:1.5}.xl\:scale-x-0{--transform-scale-x:0}.xl\:scale-x-50{--transform-scale-x:.5}.xl\:scale-x-75{--transform-scale-x:.75}.xl\:scale-x-90{--transform-scale-x:.9}.xl\:scale-x-95{--transform-scale-x:.95}.xl\:scale-x-100{--transform-scale-x:1}.xl\:scale-x-105{--transform-scale-x:1.05}.xl\:scale-x-110{--transform-scale-x:1.1}.xl\:scale-x-125{--transform-scale-x:1.25}.xl\:scale-x-150{--transform-scale-x:1.5}.xl\:scale-y-0{--transform-scale-y:0}.xl\:scale-y-50{--transform-scale-y:.5}.xl\:scale-y-75{--transform-scale-y:.75}.xl\:scale-y-90{--transform-scale-y:.9}.xl\:scale-y-95{--transform-scale-y:.95}.xl\:scale-y-100{--transform-scale-y:1}.xl\:scale-y-105{--transform-scale-y:1.05}.xl\:scale-y-110{--transform-scale-y:1.1}.xl\:scale-y-125{--transform-scale-y:1.25}.xl\:scale-y-150{--transform-scale-y:1.5}.xl\:hover\:scale-0:hover{--transform-scale-x:0;--transform-scale-y:0}.xl\:hover\:scale-50:hover{--transform-scale-x:.5;--transform-scale-y:.5}.xl\:hover\:scale-75:hover{--transform-scale-x:.75;--transform-scale-y:.75}.xl\:hover\:scale-90:hover{--transform-scale-x:.9;--transform-scale-y:.9}.xl\:hover\:scale-95:hover{--transform-scale-x:.95;--transform-scale-y:.95}.xl\:hover\:scale-100:hover{--transform-scale-x:1;--transform-scale-y:1}.xl\:hover\:scale-105:hover{--transform-scale-x:1.05;--transform-scale-y:1.05}.xl\:hover\:scale-110:hover{--transform-scale-x:1.1;--transform-scale-y:1.1}.xl\:hover\:scale-125:hover{--transform-scale-x:1.25;--transform-scale-y:1.25}.xl\:hover\:scale-150:hover{--transform-scale-x:1.5;--transform-scale-y:1.5}.xl\:hover\:scale-x-0:hover{--transform-scale-x:0}.xl\:hover\:scale-x-50:hover{--transform-scale-x:.5}.xl\:hover\:scale-x-75:hover{--transform-scale-x:.75}.xl\:hover\:scale-x-90:hover{--transform-scale-x:.9}.xl\:hover\:scale-x-95:hover{--transform-scale-x:.95}.xl\:hover\:scale-x-100:hover{--transform-scale-x:1}.xl\:hover\:scale-x-105:hover{--transform-scale-x:1.05}.xl\:hover\:scale-x-110:hover{--transform-scale-x:1.1}.xl\:hover\:scale-x-125:hover{--transform-scale-x:1.25}.xl\:hover\:scale-x-150:hover{--transform-scale-x:1.5}.xl\:hover\:scale-y-0:hover{--transform-scale-y:0}.xl\:hover\:scale-y-50:hover{--transform-scale-y:.5}.xl\:hover\:scale-y-75:hover{--transform-scale-y:.75}.xl\:hover\:scale-y-90:hover{--transform-scale-y:.9}.xl\:hover\:scale-y-95:hover{--transform-scale-y:.95}.xl\:hover\:scale-y-100:hover{--transform-scale-y:1}.xl\:hover\:scale-y-105:hover{--transform-scale-y:1.05}.xl\:hover\:scale-y-110:hover{--transform-scale-y:1.1}.xl\:hover\:scale-y-125:hover{--transform-scale-y:1.25}.xl\:hover\:scale-y-150:hover{--transform-scale-y:1.5}.xl\:focus\:scale-0:focus{--transform-scale-x:0;--transform-scale-y:0}.xl\:focus\:scale-50:focus{--transform-scale-x:.5;--transform-scale-y:.5}.xl\:focus\:scale-75:focus{--transform-scale-x:.75;--transform-scale-y:.75}.xl\:focus\:scale-90:focus{--transform-scale-x:.9;--transform-scale-y:.9}.xl\:focus\:scale-95:focus{--transform-scale-x:.95;--transform-scale-y:.95}.xl\:focus\:scale-100:focus{--transform-scale-x:1;--transform-scale-y:1}.xl\:focus\:scale-105:focus{--transform-scale-x:1.05;--transform-scale-y:1.05}.xl\:focus\:scale-110:focus{--transform-scale-x:1.1;--transform-scale-y:1.1}.xl\:focus\:scale-125:focus{--transform-scale-x:1.25;--transform-scale-y:1.25}.xl\:focus\:scale-150:focus{--transform-scale-x:1.5;--transform-scale-y:1.5}.xl\:focus\:scale-x-0:focus{--transform-scale-x:0}.xl\:focus\:scale-x-50:focus{--transform-scale-x:.5}.xl\:focus\:scale-x-75:focus{--transform-scale-x:.75}.xl\:focus\:scale-x-90:focus{--transform-scale-x:.9}.xl\:focus\:scale-x-95:focus{--transform-scale-x:.95}.xl\:focus\:scale-x-100:focus{--transform-scale-x:1}.xl\:focus\:scale-x-105:focus{--transform-scale-x:1.05}.xl\:focus\:scale-x-110:focus{--transform-scale-x:1.1}.xl\:focus\:scale-x-125:focus{--transform-scale-x:1.25}.xl\:focus\:scale-x-150:focus{--transform-scale-x:1.5}.xl\:focus\:scale-y-0:focus{--transform-scale-y:0}.xl\:focus\:scale-y-50:focus{--transform-scale-y:.5}.xl\:focus\:scale-y-75:focus{--transform-scale-y:.75}.xl\:focus\:scale-y-90:focus{--transform-scale-y:.9}.xl\:focus\:scale-y-95:focus{--transform-scale-y:.95}.xl\:focus\:scale-y-100:focus{--transform-scale-y:1}.xl\:focus\:scale-y-105:focus{--transform-scale-y:1.05}.xl\:focus\:scale-y-110:focus{--transform-scale-y:1.1}.xl\:focus\:scale-y-125:focus{--transform-scale-y:1.25}.xl\:focus\:scale-y-150:focus{--transform-scale-y:1.5}.xl\:rotate-0{--transform-rotate:0}.xl\:rotate-1{--transform-rotate:1deg}.xl\:rotate-2{--transform-rotate:2deg}.xl\:rotate-3{--transform-rotate:3deg}.xl\:rotate-6{--transform-rotate:6deg}.xl\:rotate-12{--transform-rotate:12deg}.xl\:rotate-45{--transform-rotate:45deg}.xl\:rotate-90{--transform-rotate:90deg}.xl\:rotate-180{--transform-rotate:180deg}.xl\:-rotate-180{--transform-rotate:-180deg}.xl\:-rotate-90{--transform-rotate:-90deg}.xl\:-rotate-45{--transform-rotate:-45deg}.xl\:-rotate-12{--transform-rotate:-12deg}.xl\:-rotate-6{--transform-rotate:-6deg}.xl\:-rotate-3{--transform-rotate:-3deg}.xl\:-rotate-2{--transform-rotate:-2deg}.xl\:-rotate-1{--transform-rotate:-1deg}.xl\:hover\:rotate-0:hover{--transform-rotate:0}.xl\:hover\:rotate-1:hover{--transform-rotate:1deg}.xl\:hover\:rotate-2:hover{--transform-rotate:2deg}.xl\:hover\:rotate-3:hover{--transform-rotate:3deg}.xl\:hover\:rotate-6:hover{--transform-rotate:6deg}.xl\:hover\:rotate-12:hover{--transform-rotate:12deg}.xl\:hover\:rotate-45:hover{--transform-rotate:45deg}.xl\:hover\:rotate-90:hover{--transform-rotate:90deg}.xl\:hover\:rotate-180:hover{--transform-rotate:180deg}.xl\:hover\:-rotate-180:hover{--transform-rotate:-180deg}.xl\:hover\:-rotate-90:hover{--transform-rotate:-90deg}.xl\:hover\:-rotate-45:hover{--transform-rotate:-45deg}.xl\:hover\:-rotate-12:hover{--transform-rotate:-12deg}.xl\:hover\:-rotate-6:hover{--transform-rotate:-6deg}.xl\:hover\:-rotate-3:hover{--transform-rotate:-3deg}.xl\:hover\:-rotate-2:hover{--transform-rotate:-2deg}.xl\:hover\:-rotate-1:hover{--transform-rotate:-1deg}.xl\:focus\:rotate-0:focus{--transform-rotate:0}.xl\:focus\:rotate-1:focus{--transform-rotate:1deg}.xl\:focus\:rotate-2:focus{--transform-rotate:2deg}.xl\:focus\:rotate-3:focus{--transform-rotate:3deg}.xl\:focus\:rotate-6:focus{--transform-rotate:6deg}.xl\:focus\:rotate-12:focus{--transform-rotate:12deg}.xl\:focus\:rotate-45:focus{--transform-rotate:45deg}.xl\:focus\:rotate-90:focus{--transform-rotate:90deg}.xl\:focus\:rotate-180:focus{--transform-rotate:180deg}.xl\:focus\:-rotate-180:focus{--transform-rotate:-180deg}.xl\:focus\:-rotate-90:focus{--transform-rotate:-90deg}.xl\:focus\:-rotate-45:focus{--transform-rotate:-45deg}.xl\:focus\:-rotate-12:focus{--transform-rotate:-12deg}.xl\:focus\:-rotate-6:focus{--transform-rotate:-6deg}.xl\:focus\:-rotate-3:focus{--transform-rotate:-3deg}.xl\:focus\:-rotate-2:focus{--transform-rotate:-2deg}.xl\:focus\:-rotate-1:focus{--transform-rotate:-1deg}.xl\:translate-x-0{--transform-translate-x:0}.xl\:translate-x-1{--transform-translate-x:0.25rem}.xl\:translate-x-2{--transform-translate-x:0.5rem}.xl\:translate-x-3{--transform-translate-x:0.75rem}.xl\:translate-x-4{--transform-translate-x:1rem}.xl\:translate-x-5{--transform-translate-x:1.25rem}.xl\:translate-x-6{--transform-translate-x:1.5rem}.xl\:translate-x-8{--transform-translate-x:2rem}.xl\:translate-x-10{--transform-translate-x:2.5rem}.xl\:translate-x-12{--transform-translate-x:3rem}.xl\:translate-x-16{--transform-translate-x:4rem}.xl\:translate-x-20{--transform-translate-x:5rem}.xl\:translate-x-24{--transform-translate-x:6rem}.xl\:translate-x-32{--transform-translate-x:8rem}.xl\:translate-x-40{--transform-translate-x:10rem}.xl\:translate-x-48{--transform-translate-x:12rem}.xl\:translate-x-56{--transform-translate-x:14rem}.xl\:translate-x-64{--transform-translate-x:16rem}.xl\:translate-x-px{--transform-translate-x:1px}.xl\:-translate-x-1{--transform-translate-x:-0.25rem}.xl\:-translate-x-2{--transform-translate-x:-0.5rem}.xl\:-translate-x-3{--transform-translate-x:-0.75rem}.xl\:-translate-x-4{--transform-translate-x:-1rem}.xl\:-translate-x-5{--transform-translate-x:-1.25rem}.xl\:-translate-x-6{--transform-translate-x:-1.5rem}.xl\:-translate-x-8{--transform-translate-x:-2rem}.xl\:-translate-x-10{--transform-translate-x:-2.5rem}.xl\:-translate-x-12{--transform-translate-x:-3rem}.xl\:-translate-x-16{--transform-translate-x:-4rem}.xl\:-translate-x-20{--transform-translate-x:-5rem}.xl\:-translate-x-24{--transform-translate-x:-6rem}.xl\:-translate-x-32{--transform-translate-x:-8rem}.xl\:-translate-x-40{--transform-translate-x:-10rem}.xl\:-translate-x-48{--transform-translate-x:-12rem}.xl\:-translate-x-56{--transform-translate-x:-14rem}.xl\:-translate-x-64{--transform-translate-x:-16rem}.xl\:-translate-x-px{--transform-translate-x:-1px}.xl\:-translate-x-full{--transform-translate-x:-100%}.xl\:-translate-x-1\/2{--transform-translate-x:-50%}.xl\:translate-x-1\/2{--transform-translate-x:50%}.xl\:translate-x-full{--transform-translate-x:100%}.xl\:translate-y-0{--transform-translate-y:0}.xl\:translate-y-1{--transform-translate-y:0.25rem}.xl\:translate-y-2{--transform-translate-y:0.5rem}.xl\:translate-y-3{--transform-translate-y:0.75rem}.xl\:translate-y-4{--transform-translate-y:1rem}.xl\:translate-y-5{--transform-translate-y:1.25rem}.xl\:translate-y-6{--transform-translate-y:1.5rem}.xl\:translate-y-8{--transform-translate-y:2rem}.xl\:translate-y-10{--transform-translate-y:2.5rem}.xl\:translate-y-12{--transform-translate-y:3rem}.xl\:translate-y-16{--transform-translate-y:4rem}.xl\:translate-y-20{--transform-translate-y:5rem}.xl\:translate-y-24{--transform-translate-y:6rem}.xl\:translate-y-32{--transform-translate-y:8rem}.xl\:translate-y-40{--transform-translate-y:10rem}.xl\:translate-y-48{--transform-translate-y:12rem}.xl\:translate-y-56{--transform-translate-y:14rem}.xl\:translate-y-64{--transform-translate-y:16rem}.xl\:translate-y-px{--transform-translate-y:1px}.xl\:-translate-y-1{--transform-translate-y:-0.25rem}.xl\:-translate-y-2{--transform-translate-y:-0.5rem}.xl\:-translate-y-3{--transform-translate-y:-0.75rem}.xl\:-translate-y-4{--transform-translate-y:-1rem}.xl\:-translate-y-5{--transform-translate-y:-1.25rem}.xl\:-translate-y-6{--transform-translate-y:-1.5rem}.xl\:-translate-y-8{--transform-translate-y:-2rem}.xl\:-translate-y-10{--transform-translate-y:-2.5rem}.xl\:-translate-y-12{--transform-translate-y:-3rem}.xl\:-translate-y-16{--transform-translate-y:-4rem}.xl\:-translate-y-20{--transform-translate-y:-5rem}.xl\:-translate-y-24{--transform-translate-y:-6rem}.xl\:-translate-y-32{--transform-translate-y:-8rem}.xl\:-translate-y-40{--transform-translate-y:-10rem}.xl\:-translate-y-48{--transform-translate-y:-12rem}.xl\:-translate-y-56{--transform-translate-y:-14rem}.xl\:-translate-y-64{--transform-translate-y:-16rem}.xl\:-translate-y-px{--transform-translate-y:-1px}.xl\:-translate-y-full{--transform-translate-y:-100%}.xl\:-translate-y-1\/2{--transform-translate-y:-50%}.xl\:translate-y-1\/2{--transform-translate-y:50%}.xl\:translate-y-full{--transform-translate-y:100%}.xl\:hover\:translate-x-0:hover{--transform-translate-x:0}.xl\:hover\:translate-x-1:hover{--transform-translate-x:0.25rem}.xl\:hover\:translate-x-2:hover{--transform-translate-x:0.5rem}.xl\:hover\:translate-x-3:hover{--transform-translate-x:0.75rem}.xl\:hover\:translate-x-4:hover{--transform-translate-x:1rem}.xl\:hover\:translate-x-5:hover{--transform-translate-x:1.25rem}.xl\:hover\:translate-x-6:hover{--transform-translate-x:1.5rem}.xl\:hover\:translate-x-8:hover{--transform-translate-x:2rem}.xl\:hover\:translate-x-10:hover{--transform-translate-x:2.5rem}.xl\:hover\:translate-x-12:hover{--transform-translate-x:3rem}.xl\:hover\:translate-x-16:hover{--transform-translate-x:4rem}.xl\:hover\:translate-x-20:hover{--transform-translate-x:5rem}.xl\:hover\:translate-x-24:hover{--transform-translate-x:6rem}.xl\:hover\:translate-x-32:hover{--transform-translate-x:8rem}.xl\:hover\:translate-x-40:hover{--transform-translate-x:10rem}.xl\:hover\:translate-x-48:hover{--transform-translate-x:12rem}.xl\:hover\:translate-x-56:hover{--transform-translate-x:14rem}.xl\:hover\:translate-x-64:hover{--transform-translate-x:16rem}.xl\:hover\:translate-x-px:hover{--transform-translate-x:1px}.xl\:hover\:-translate-x-1:hover{--transform-translate-x:-0.25rem}.xl\:hover\:-translate-x-2:hover{--transform-translate-x:-0.5rem}.xl\:hover\:-translate-x-3:hover{--transform-translate-x:-0.75rem}.xl\:hover\:-translate-x-4:hover{--transform-translate-x:-1rem}.xl\:hover\:-translate-x-5:hover{--transform-translate-x:-1.25rem}.xl\:hover\:-translate-x-6:hover{--transform-translate-x:-1.5rem}.xl\:hover\:-translate-x-8:hover{--transform-translate-x:-2rem}.xl\:hover\:-translate-x-10:hover{--transform-translate-x:-2.5rem}.xl\:hover\:-translate-x-12:hover{--transform-translate-x:-3rem}.xl\:hover\:-translate-x-16:hover{--transform-translate-x:-4rem}.xl\:hover\:-translate-x-20:hover{--transform-translate-x:-5rem}.xl\:hover\:-translate-x-24:hover{--transform-translate-x:-6rem}.xl\:hover\:-translate-x-32:hover{--transform-translate-x:-8rem}.xl\:hover\:-translate-x-40:hover{--transform-translate-x:-10rem}.xl\:hover\:-translate-x-48:hover{--transform-translate-x:-12rem}.xl\:hover\:-translate-x-56:hover{--transform-translate-x:-14rem}.xl\:hover\:-translate-x-64:hover{--transform-translate-x:-16rem}.xl\:hover\:-translate-x-px:hover{--transform-translate-x:-1px}.xl\:hover\:-translate-x-full:hover{--transform-translate-x:-100%}.xl\:hover\:-translate-x-1\/2:hover{--transform-translate-x:-50%}.xl\:hover\:translate-x-1\/2:hover{--transform-translate-x:50%}.xl\:hover\:translate-x-full:hover{--transform-translate-x:100%}.xl\:hover\:translate-y-0:hover{--transform-translate-y:0}.xl\:hover\:translate-y-1:hover{--transform-translate-y:0.25rem}.xl\:hover\:translate-y-2:hover{--transform-translate-y:0.5rem}.xl\:hover\:translate-y-3:hover{--transform-translate-y:0.75rem}.xl\:hover\:translate-y-4:hover{--transform-translate-y:1rem}.xl\:hover\:translate-y-5:hover{--transform-translate-y:1.25rem}.xl\:hover\:translate-y-6:hover{--transform-translate-y:1.5rem}.xl\:hover\:translate-y-8:hover{--transform-translate-y:2rem}.xl\:hover\:translate-y-10:hover{--transform-translate-y:2.5rem}.xl\:hover\:translate-y-12:hover{--transform-translate-y:3rem}.xl\:hover\:translate-y-16:hover{--transform-translate-y:4rem}.xl\:hover\:translate-y-20:hover{--transform-translate-y:5rem}.xl\:hover\:translate-y-24:hover{--transform-translate-y:6rem}.xl\:hover\:translate-y-32:hover{--transform-translate-y:8rem}.xl\:hover\:translate-y-40:hover{--transform-translate-y:10rem}.xl\:hover\:translate-y-48:hover{--transform-translate-y:12rem}.xl\:hover\:translate-y-56:hover{--transform-translate-y:14rem}.xl\:hover\:translate-y-64:hover{--transform-translate-y:16rem}.xl\:hover\:translate-y-px:hover{--transform-translate-y:1px}.xl\:hover\:-translate-y-1:hover{--transform-translate-y:-0.25rem}.xl\:hover\:-translate-y-2:hover{--transform-translate-y:-0.5rem}.xl\:hover\:-translate-y-3:hover{--transform-translate-y:-0.75rem}.xl\:hover\:-translate-y-4:hover{--transform-translate-y:-1rem}.xl\:hover\:-translate-y-5:hover{--transform-translate-y:-1.25rem}.xl\:hover\:-translate-y-6:hover{--transform-translate-y:-1.5rem}.xl\:hover\:-translate-y-8:hover{--transform-translate-y:-2rem}.xl\:hover\:-translate-y-10:hover{--transform-translate-y:-2.5rem}.xl\:hover\:-translate-y-12:hover{--transform-translate-y:-3rem}.xl\:hover\:-translate-y-16:hover{--transform-translate-y:-4rem}.xl\:hover\:-translate-y-20:hover{--transform-translate-y:-5rem}.xl\:hover\:-translate-y-24:hover{--transform-translate-y:-6rem}.xl\:hover\:-translate-y-32:hover{--transform-translate-y:-8rem}.xl\:hover\:-translate-y-40:hover{--transform-translate-y:-10rem}.xl\:hover\:-translate-y-48:hover{--transform-translate-y:-12rem}.xl\:hover\:-translate-y-56:hover{--transform-translate-y:-14rem}.xl\:hover\:-translate-y-64:hover{--transform-translate-y:-16rem}.xl\:hover\:-translate-y-px:hover{--transform-translate-y:-1px}.xl\:hover\:-translate-y-full:hover{--transform-translate-y:-100%}.xl\:hover\:-translate-y-1\/2:hover{--transform-translate-y:-50%}.xl\:hover\:translate-y-1\/2:hover{--transform-translate-y:50%}.xl\:hover\:translate-y-full:hover{--transform-translate-y:100%}.xl\:focus\:translate-x-0:focus{--transform-translate-x:0}.xl\:focus\:translate-x-1:focus{--transform-translate-x:0.25rem}.xl\:focus\:translate-x-2:focus{--transform-translate-x:0.5rem}.xl\:focus\:translate-x-3:focus{--transform-translate-x:0.75rem}.xl\:focus\:translate-x-4:focus{--transform-translate-x:1rem}.xl\:focus\:translate-x-5:focus{--transform-translate-x:1.25rem}.xl\:focus\:translate-x-6:focus{--transform-translate-x:1.5rem}.xl\:focus\:translate-x-8:focus{--transform-translate-x:2rem}.xl\:focus\:translate-x-10:focus{--transform-translate-x:2.5rem}.xl\:focus\:translate-x-12:focus{--transform-translate-x:3rem}.xl\:focus\:translate-x-16:focus{--transform-translate-x:4rem}.xl\:focus\:translate-x-20:focus{--transform-translate-x:5rem}.xl\:focus\:translate-x-24:focus{--transform-translate-x:6rem}.xl\:focus\:translate-x-32:focus{--transform-translate-x:8rem}.xl\:focus\:translate-x-40:focus{--transform-translate-x:10rem}.xl\:focus\:translate-x-48:focus{--transform-translate-x:12rem}.xl\:focus\:translate-x-56:focus{--transform-translate-x:14rem}.xl\:focus\:translate-x-64:focus{--transform-translate-x:16rem}.xl\:focus\:translate-x-px:focus{--transform-translate-x:1px}.xl\:focus\:-translate-x-1:focus{--transform-translate-x:-0.25rem}.xl\:focus\:-translate-x-2:focus{--transform-translate-x:-0.5rem}.xl\:focus\:-translate-x-3:focus{--transform-translate-x:-0.75rem}.xl\:focus\:-translate-x-4:focus{--transform-translate-x:-1rem}.xl\:focus\:-translate-x-5:focus{--transform-translate-x:-1.25rem}.xl\:focus\:-translate-x-6:focus{--transform-translate-x:-1.5rem}.xl\:focus\:-translate-x-8:focus{--transform-translate-x:-2rem}.xl\:focus\:-translate-x-10:focus{--transform-translate-x:-2.5rem}.xl\:focus\:-translate-x-12:focus{--transform-translate-x:-3rem}.xl\:focus\:-translate-x-16:focus{--transform-translate-x:-4rem}.xl\:focus\:-translate-x-20:focus{--transform-translate-x:-5rem}.xl\:focus\:-translate-x-24:focus{--transform-translate-x:-6rem}.xl\:focus\:-translate-x-32:focus{--transform-translate-x:-8rem}.xl\:focus\:-translate-x-40:focus{--transform-translate-x:-10rem}.xl\:focus\:-translate-x-48:focus{--transform-translate-x:-12rem}.xl\:focus\:-translate-x-56:focus{--transform-translate-x:-14rem}.xl\:focus\:-translate-x-64:focus{--transform-translate-x:-16rem}.xl\:focus\:-translate-x-px:focus{--transform-translate-x:-1px}.xl\:focus\:-translate-x-full:focus{--transform-translate-x:-100%}.xl\:focus\:-translate-x-1\/2:focus{--transform-translate-x:-50%}.xl\:focus\:translate-x-1\/2:focus{--transform-translate-x:50%}.xl\:focus\:translate-x-full:focus{--transform-translate-x:100%}.xl\:focus\:translate-y-0:focus{--transform-translate-y:0}.xl\:focus\:translate-y-1:focus{--transform-translate-y:0.25rem}.xl\:focus\:translate-y-2:focus{--transform-translate-y:0.5rem}.xl\:focus\:translate-y-3:focus{--transform-translate-y:0.75rem}.xl\:focus\:translate-y-4:focus{--transform-translate-y:1rem}.xl\:focus\:translate-y-5:focus{--transform-translate-y:1.25rem}.xl\:focus\:translate-y-6:focus{--transform-translate-y:1.5rem}.xl\:focus\:translate-y-8:focus{--transform-translate-y:2rem}.xl\:focus\:translate-y-10:focus{--transform-translate-y:2.5rem}.xl\:focus\:translate-y-12:focus{--transform-translate-y:3rem}.xl\:focus\:translate-y-16:focus{--transform-translate-y:4rem}.xl\:focus\:translate-y-20:focus{--transform-translate-y:5rem}.xl\:focus\:translate-y-24:focus{--transform-translate-y:6rem}.xl\:focus\:translate-y-32:focus{--transform-translate-y:8rem}.xl\:focus\:translate-y-40:focus{--transform-translate-y:10rem}.xl\:focus\:translate-y-48:focus{--transform-translate-y:12rem}.xl\:focus\:translate-y-56:focus{--transform-translate-y:14rem}.xl\:focus\:translate-y-64:focus{--transform-translate-y:16rem}.xl\:focus\:translate-y-px:focus{--transform-translate-y:1px}.xl\:focus\:-translate-y-1:focus{--transform-translate-y:-0.25rem}.xl\:focus\:-translate-y-2:focus{--transform-translate-y:-0.5rem}.xl\:focus\:-translate-y-3:focus{--transform-translate-y:-0.75rem}.xl\:focus\:-translate-y-4:focus{--transform-translate-y:-1rem}.xl\:focus\:-translate-y-5:focus{--transform-translate-y:-1.25rem}.xl\:focus\:-translate-y-6:focus{--transform-translate-y:-1.5rem}.xl\:focus\:-translate-y-8:focus{--transform-translate-y:-2rem}.xl\:focus\:-translate-y-10:focus{--transform-translate-y:-2.5rem}.xl\:focus\:-translate-y-12:focus{--transform-translate-y:-3rem}.xl\:focus\:-translate-y-16:focus{--transform-translate-y:-4rem}.xl\:focus\:-translate-y-20:focus{--transform-translate-y:-5rem}.xl\:focus\:-translate-y-24:focus{--transform-translate-y:-6rem}.xl\:focus\:-translate-y-32:focus{--transform-translate-y:-8rem}.xl\:focus\:-translate-y-40:focus{--transform-translate-y:-10rem}.xl\:focus\:-translate-y-48:focus{--transform-translate-y:-12rem}.xl\:focus\:-translate-y-56:focus{--transform-translate-y:-14rem}.xl\:focus\:-translate-y-64:focus{--transform-translate-y:-16rem}.xl\:focus\:-translate-y-px:focus{--transform-translate-y:-1px}.xl\:focus\:-translate-y-full:focus{--transform-translate-y:-100%}.xl\:focus\:-translate-y-1\/2:focus{--transform-translate-y:-50%}.xl\:focus\:translate-y-1\/2:focus{--transform-translate-y:50%}.xl\:focus\:translate-y-full:focus{--transform-translate-y:100%}.xl\:skew-x-0{--transform-skew-x:0}.xl\:skew-x-1{--transform-skew-x:1deg}.xl\:skew-x-2{--transform-skew-x:2deg}.xl\:skew-x-3{--transform-skew-x:3deg}.xl\:skew-x-6{--transform-skew-x:6deg}.xl\:skew-x-12{--transform-skew-x:12deg}.xl\:-skew-x-12{--transform-skew-x:-12deg}.xl\:-skew-x-6{--transform-skew-x:-6deg}.xl\:-skew-x-3{--transform-skew-x:-3deg}.xl\:-skew-x-2{--transform-skew-x:-2deg}.xl\:-skew-x-1{--transform-skew-x:-1deg}.xl\:skew-y-0{--transform-skew-y:0}.xl\:skew-y-1{--transform-skew-y:1deg}.xl\:skew-y-2{--transform-skew-y:2deg}.xl\:skew-y-3{--transform-skew-y:3deg}.xl\:skew-y-6{--transform-skew-y:6deg}.xl\:skew-y-12{--transform-skew-y:12deg}.xl\:-skew-y-12{--transform-skew-y:-12deg}.xl\:-skew-y-6{--transform-skew-y:-6deg}.xl\:-skew-y-3{--transform-skew-y:-3deg}.xl\:-skew-y-2{--transform-skew-y:-2deg}.xl\:-skew-y-1{--transform-skew-y:-1deg}.xl\:hover\:skew-x-0:hover{--transform-skew-x:0}.xl\:hover\:skew-x-1:hover{--transform-skew-x:1deg}.xl\:hover\:skew-x-2:hover{--transform-skew-x:2deg}.xl\:hover\:skew-x-3:hover{--transform-skew-x:3deg}.xl\:hover\:skew-x-6:hover{--transform-skew-x:6deg}.xl\:hover\:skew-x-12:hover{--transform-skew-x:12deg}.xl\:hover\:-skew-x-12:hover{--transform-skew-x:-12deg}.xl\:hover\:-skew-x-6:hover{--transform-skew-x:-6deg}.xl\:hover\:-skew-x-3:hover{--transform-skew-x:-3deg}.xl\:hover\:-skew-x-2:hover{--transform-skew-x:-2deg}.xl\:hover\:-skew-x-1:hover{--transform-skew-x:-1deg}.xl\:hover\:skew-y-0:hover{--transform-skew-y:0}.xl\:hover\:skew-y-1:hover{--transform-skew-y:1deg}.xl\:hover\:skew-y-2:hover{--transform-skew-y:2deg}.xl\:hover\:skew-y-3:hover{--transform-skew-y:3deg}.xl\:hover\:skew-y-6:hover{--transform-skew-y:6deg}.xl\:hover\:skew-y-12:hover{--transform-skew-y:12deg}.xl\:hover\:-skew-y-12:hover{--transform-skew-y:-12deg}.xl\:hover\:-skew-y-6:hover{--transform-skew-y:-6deg}.xl\:hover\:-skew-y-3:hover{--transform-skew-y:-3deg}.xl\:hover\:-skew-y-2:hover{--transform-skew-y:-2deg}.xl\:hover\:-skew-y-1:hover{--transform-skew-y:-1deg}.xl\:focus\:skew-x-0:focus{--transform-skew-x:0}.xl\:focus\:skew-x-1:focus{--transform-skew-x:1deg}.xl\:focus\:skew-x-2:focus{--transform-skew-x:2deg}.xl\:focus\:skew-x-3:focus{--transform-skew-x:3deg}.xl\:focus\:skew-x-6:focus{--transform-skew-x:6deg}.xl\:focus\:skew-x-12:focus{--transform-skew-x:12deg}.xl\:focus\:-skew-x-12:focus{--transform-skew-x:-12deg}.xl\:focus\:-skew-x-6:focus{--transform-skew-x:-6deg}.xl\:focus\:-skew-x-3:focus{--transform-skew-x:-3deg}.xl\:focus\:-skew-x-2:focus{--transform-skew-x:-2deg}.xl\:focus\:-skew-x-1:focus{--transform-skew-x:-1deg}.xl\:focus\:skew-y-0:focus{--transform-skew-y:0}.xl\:focus\:skew-y-1:focus{--transform-skew-y:1deg}.xl\:focus\:skew-y-2:focus{--transform-skew-y:2deg}.xl\:focus\:skew-y-3:focus{--transform-skew-y:3deg}.xl\:focus\:skew-y-6:focus{--transform-skew-y:6deg}.xl\:focus\:skew-y-12:focus{--transform-skew-y:12deg}.xl\:focus\:-skew-y-12:focus{--transform-skew-y:-12deg}.xl\:focus\:-skew-y-6:focus{--transform-skew-y:-6deg}.xl\:focus\:-skew-y-3:focus{--transform-skew-y:-3deg}.xl\:focus\:-skew-y-2:focus{--transform-skew-y:-2deg}.xl\:focus\:-skew-y-1:focus{--transform-skew-y:-1deg}.xl\:transition-none{transition-property:none}.xl\:transition-all{transition-property:all}.xl\:transition{transition-property:background-color,border-color,color,fill,stroke,opacity,box-shadow,transform}.xl\:transition-colors{transition-property:background-color,border-color,color,fill,stroke}.xl\:transition-opacity{transition-property:opacity}.xl\:transition-shadow{transition-property:box-shadow}.xl\:transition-transform{transition-property:transform}.xl\:ease-linear{transition-timing-function:linear}.xl\:ease-in{transition-timing-function:cubic-bezier(.4,0,1,1)}.xl\:ease-out{transition-timing-function:cubic-bezier(0,0,.2,1)}.xl\:ease-in-out{transition-timing-function:cubic-bezier(.4,0,.2,1)}.xl\:duration-75{transition-duration:75ms}.xl\:duration-100{transition-duration:.1s}.xl\:duration-150{transition-duration:150ms}.xl\:duration-200{transition-duration:.2s}.xl\:duration-300{transition-duration:.3s}.xl\:duration-500{transition-duration:.5s}.xl\:duration-700{transition-duration:.7s}.xl\:duration-1000{transition-duration:1s}.xl\:delay-75{transition-delay:75ms}.xl\:delay-100{transition-delay:.1s}.xl\:delay-150{transition-delay:150ms}.xl\:delay-200{transition-delay:.2s}.xl\:delay-300{transition-delay:.3s}.xl\:delay-500{transition-delay:.5s}.xl\:delay-700{transition-delay:.7s}.xl\:delay-1000{transition-delay:1s}.xl\:animate-none{animation:none}.xl\:animate-spin{animation:spin 1s linear infinite}.xl\:animate-ping{animation:ping 1s cubic-bezier(0,0,.2,1) infinite}.xl\:animate-pulse{animation:pulse 2s cubic-bezier(.4,0,.6,1) infinite}.xl\:animate-bounce{animation:bounce 1s infinite}} \ No newline at end of file diff --git a/test/configCases/css/large/tailwind.module.css b/test/configCases/css/large/tailwind.module.css new file mode 100644 index 00000000000..dc016181652 --- /dev/null +++ b/test/configCases/css/large/tailwind.module.css @@ -0,0 +1 @@ +/*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */html{line-height:1.15;-webkit-text-size-adjust:100%}body{margin:0}main{display:block}h1{font-size:2em;margin:.67em 0}hr{box-sizing:content-box;height:0;overflow:visible}pre{font-family:monospace,monospace;font-size:1em}a{background-color:transparent}abbr[title]{border-bottom:none;text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted}b,strong{font-weight:bolder}code,kbd,samp{font-family:monospace,monospace;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}img{border-style:none}button,input,optgroup,select,textarea{font-family:inherit;font-size:100%;line-height:1.15;margin:0}button,input{overflow:visible}button,select{text-transform:none}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{border-style:none;padding:0}[type=button]:-moz-focusring,[type=reset]:-moz-focusring,[type=submit]:-moz-focusring,button:-moz-focusring{outline:1px dotted ButtonText}fieldset{padding:.35em .75em .625em}legend{box-sizing:border-box;color:inherit;display:table;max-width:100%;padding:0;white-space:normal}progress{vertical-align:baseline}textarea{overflow:auto}[type=checkbox],[type=radio]{box-sizing:border-box;padding:0}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}details{display:block}summary{display:list-item}template{display:none}[hidden]{display:none}blockquote,dd,dl,figure,h1,h2,h3,h4,h5,h6,hr,p,pre{margin:0}button{background-color:transparent;background-image:none}button:focus{outline:1px dotted;outline:5px auto -webkit-focus-ring-color}fieldset{margin:0;padding:0}ol,ul{list-style:none;margin:0;padding:0}html{font-family:system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";line-height:1.5}*,::after,::before{box-sizing:border-box;border-width:0;border-style:solid;border-color:#e2e8f0}hr{border-top-width:1px}img{border-style:solid}textarea{resize:vertical}input:-ms-input-placeholder,textarea:-ms-input-placeholder{color:#a0aec0}input::-ms-input-placeholder,textarea::-ms-input-placeholder{color:#a0aec0}input::placeholder,textarea::placeholder{color:#a0aec0}[role=button],button{cursor:pointer}table{border-collapse:collapse}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}button,input,optgroup,select,textarea{padding:0;line-height:inherit;color:inherit}code,kbd,pre,samp{font-family:Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace}audio,canvas,embed,iframe,img,object,svg,video{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}.container{width:100%}@media (min-width:640px){.container{max-width:640px}}@media (min-width:768px){.container{max-width:768px}}@media (min-width:1024px){.container{max-width:1024px}}@media (min-width:1280px){.container{max-width:1280px}}.space-y-0>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(0px * calc(1 - var(--space-y-reverse)));margin-bottom:calc(0px * var(--space-y-reverse))}.space-x-0>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(0px * var(--space-x-reverse));margin-left:calc(0px * calc(1 - var(--space-x-reverse)))}.space-y-1>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(.25rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(.25rem * var(--space-y-reverse))}.space-x-1>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(.25rem * var(--space-x-reverse));margin-left:calc(.25rem * calc(1 - var(--space-x-reverse)))}.space-y-2>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(.5rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(.5rem * var(--space-y-reverse))}.space-x-2>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(.5rem * var(--space-x-reverse));margin-left:calc(.5rem * calc(1 - var(--space-x-reverse)))}.space-y-3>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(.75rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(.75rem * var(--space-y-reverse))}.space-x-3>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(.75rem * var(--space-x-reverse));margin-left:calc(.75rem * calc(1 - var(--space-x-reverse)))}.space-y-4>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(1rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(1rem * var(--space-y-reverse))}.space-x-4>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(1rem * var(--space-x-reverse));margin-left:calc(1rem * calc(1 - var(--space-x-reverse)))}.space-y-5>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(1.25rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(1.25rem * var(--space-y-reverse))}.space-x-5>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(1.25rem * var(--space-x-reverse));margin-left:calc(1.25rem * calc(1 - var(--space-x-reverse)))}.space-y-6>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(1.5rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(1.5rem * var(--space-y-reverse))}.space-x-6>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(1.5rem * var(--space-x-reverse));margin-left:calc(1.5rem * calc(1 - var(--space-x-reverse)))}.space-y-8>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(2rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(2rem * var(--space-y-reverse))}.space-x-8>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(2rem * var(--space-x-reverse));margin-left:calc(2rem * calc(1 - var(--space-x-reverse)))}.space-y-10>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(2.5rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(2.5rem * var(--space-y-reverse))}.space-x-10>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(2.5rem * var(--space-x-reverse));margin-left:calc(2.5rem * calc(1 - var(--space-x-reverse)))}.space-y-12>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(3rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(3rem * var(--space-y-reverse))}.space-x-12>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(3rem * var(--space-x-reverse));margin-left:calc(3rem * calc(1 - var(--space-x-reverse)))}.space-y-16>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(4rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(4rem * var(--space-y-reverse))}.space-x-16>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(4rem * var(--space-x-reverse));margin-left:calc(4rem * calc(1 - var(--space-x-reverse)))}.space-y-20>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(5rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(5rem * var(--space-y-reverse))}.space-x-20>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(5rem * var(--space-x-reverse));margin-left:calc(5rem * calc(1 - var(--space-x-reverse)))}.space-y-24>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(6rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(6rem * var(--space-y-reverse))}.space-x-24>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(6rem * var(--space-x-reverse));margin-left:calc(6rem * calc(1 - var(--space-x-reverse)))}.space-y-32>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(8rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(8rem * var(--space-y-reverse))}.space-x-32>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(8rem * var(--space-x-reverse));margin-left:calc(8rem * calc(1 - var(--space-x-reverse)))}.space-y-40>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(10rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(10rem * var(--space-y-reverse))}.space-x-40>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(10rem * var(--space-x-reverse));margin-left:calc(10rem * calc(1 - var(--space-x-reverse)))}.space-y-48>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(12rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(12rem * var(--space-y-reverse))}.space-x-48>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(12rem * var(--space-x-reverse));margin-left:calc(12rem * calc(1 - var(--space-x-reverse)))}.space-y-56>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(14rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(14rem * var(--space-y-reverse))}.space-x-56>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(14rem * var(--space-x-reverse));margin-left:calc(14rem * calc(1 - var(--space-x-reverse)))}.space-y-64>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(16rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(16rem * var(--space-y-reverse))}.space-x-64>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(16rem * var(--space-x-reverse));margin-left:calc(16rem * calc(1 - var(--space-x-reverse)))}.space-y-px>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(1px * calc(1 - var(--space-y-reverse)));margin-bottom:calc(1px * var(--space-y-reverse))}.space-x-px>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(1px * var(--space-x-reverse));margin-left:calc(1px * calc(1 - var(--space-x-reverse)))}.-space-y-1>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-.25rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-.25rem * var(--space-y-reverse))}.-space-x-1>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-.25rem * var(--space-x-reverse));margin-left:calc(-.25rem * calc(1 - var(--space-x-reverse)))}.-space-y-2>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-.5rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-.5rem * var(--space-y-reverse))}.-space-x-2>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-.5rem * var(--space-x-reverse));margin-left:calc(-.5rem * calc(1 - var(--space-x-reverse)))}.-space-y-3>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-.75rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-.75rem * var(--space-y-reverse))}.-space-x-3>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-.75rem * var(--space-x-reverse));margin-left:calc(-.75rem * calc(1 - var(--space-x-reverse)))}.-space-y-4>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-1rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-1rem * var(--space-y-reverse))}.-space-x-4>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-1rem * var(--space-x-reverse));margin-left:calc(-1rem * calc(1 - var(--space-x-reverse)))}.-space-y-5>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-1.25rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-1.25rem * var(--space-y-reverse))}.-space-x-5>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-1.25rem * var(--space-x-reverse));margin-left:calc(-1.25rem * calc(1 - var(--space-x-reverse)))}.-space-y-6>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-1.5rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-1.5rem * var(--space-y-reverse))}.-space-x-6>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-1.5rem * var(--space-x-reverse));margin-left:calc(-1.5rem * calc(1 - var(--space-x-reverse)))}.-space-y-8>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-2rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-2rem * var(--space-y-reverse))}.-space-x-8>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-2rem * var(--space-x-reverse));margin-left:calc(-2rem * calc(1 - var(--space-x-reverse)))}.-space-y-10>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-2.5rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-2.5rem * var(--space-y-reverse))}.-space-x-10>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-2.5rem * var(--space-x-reverse));margin-left:calc(-2.5rem * calc(1 - var(--space-x-reverse)))}.-space-y-12>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-3rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-3rem * var(--space-y-reverse))}.-space-x-12>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-3rem * var(--space-x-reverse));margin-left:calc(-3rem * calc(1 - var(--space-x-reverse)))}.-space-y-16>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-4rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-4rem * var(--space-y-reverse))}.-space-x-16>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-4rem * var(--space-x-reverse));margin-left:calc(-4rem * calc(1 - var(--space-x-reverse)))}.-space-y-20>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-5rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-5rem * var(--space-y-reverse))}.-space-x-20>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-5rem * var(--space-x-reverse));margin-left:calc(-5rem * calc(1 - var(--space-x-reverse)))}.-space-y-24>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-6rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-6rem * var(--space-y-reverse))}.-space-x-24>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-6rem * var(--space-x-reverse));margin-left:calc(-6rem * calc(1 - var(--space-x-reverse)))}.-space-y-32>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-8rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-8rem * var(--space-y-reverse))}.-space-x-32>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-8rem * var(--space-x-reverse));margin-left:calc(-8rem * calc(1 - var(--space-x-reverse)))}.-space-y-40>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-10rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-10rem * var(--space-y-reverse))}.-space-x-40>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-10rem * var(--space-x-reverse));margin-left:calc(-10rem * calc(1 - var(--space-x-reverse)))}.-space-y-48>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-12rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-12rem * var(--space-y-reverse))}.-space-x-48>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-12rem * var(--space-x-reverse));margin-left:calc(-12rem * calc(1 - var(--space-x-reverse)))}.-space-y-56>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-14rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-14rem * var(--space-y-reverse))}.-space-x-56>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-14rem * var(--space-x-reverse));margin-left:calc(-14rem * calc(1 - var(--space-x-reverse)))}.-space-y-64>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-16rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-16rem * var(--space-y-reverse))}.-space-x-64>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-16rem * var(--space-x-reverse));margin-left:calc(-16rem * calc(1 - var(--space-x-reverse)))}.-space-y-px>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-1px * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-1px * var(--space-y-reverse))}.-space-x-px>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-1px * var(--space-x-reverse));margin-left:calc(-1px * calc(1 - var(--space-x-reverse)))}.space-y-reverse>:not(template)~:not(template){--space-y-reverse:1}.space-x-reverse>:not(template)~:not(template){--space-x-reverse:1}.divide-y-0>:not(template)~:not(template){--divide-y-reverse:0;border-top-width:calc(0px * calc(1 - var(--divide-y-reverse)));border-bottom-width:calc(0px * var(--divide-y-reverse))}.divide-x-0>:not(template)~:not(template){--divide-x-reverse:0;border-right-width:calc(0px * var(--divide-x-reverse));border-left-width:calc(0px * calc(1 - var(--divide-x-reverse)))}.divide-y-2>:not(template)~:not(template){--divide-y-reverse:0;border-top-width:calc(2px * calc(1 - var(--divide-y-reverse)));border-bottom-width:calc(2px * var(--divide-y-reverse))}.divide-x-2>:not(template)~:not(template){--divide-x-reverse:0;border-right-width:calc(2px * var(--divide-x-reverse));border-left-width:calc(2px * calc(1 - var(--divide-x-reverse)))}.divide-y-4>:not(template)~:not(template){--divide-y-reverse:0;border-top-width:calc(4px * calc(1 - var(--divide-y-reverse)));border-bottom-width:calc(4px * var(--divide-y-reverse))}.divide-x-4>:not(template)~:not(template){--divide-x-reverse:0;border-right-width:calc(4px * var(--divide-x-reverse));border-left-width:calc(4px * calc(1 - var(--divide-x-reverse)))}.divide-y-8>:not(template)~:not(template){--divide-y-reverse:0;border-top-width:calc(8px * calc(1 - var(--divide-y-reverse)));border-bottom-width:calc(8px * var(--divide-y-reverse))}.divide-x-8>:not(template)~:not(template){--divide-x-reverse:0;border-right-width:calc(8px * var(--divide-x-reverse));border-left-width:calc(8px * calc(1 - var(--divide-x-reverse)))}.divide-y>:not(template)~:not(template){--divide-y-reverse:0;border-top-width:calc(1px * calc(1 - var(--divide-y-reverse)));border-bottom-width:calc(1px * var(--divide-y-reverse))}.divide-x>:not(template)~:not(template){--divide-x-reverse:0;border-right-width:calc(1px * var(--divide-x-reverse));border-left-width:calc(1px * calc(1 - var(--divide-x-reverse)))}.divide-y-reverse>:not(template)~:not(template){--divide-y-reverse:1}.divide-x-reverse>:not(template)~:not(template){--divide-x-reverse:1}.divide-transparent>:not(template)~:not(template){border-color:transparent}.divide-current>:not(template)~:not(template){border-color:currentColor}.divide-black>:not(template)~:not(template){--divide-opacity:1;border-color:#000;border-color:rgba(0,0,0,var(--divide-opacity))}.divide-white>:not(template)~:not(template){--divide-opacity:1;border-color:#fff;border-color:rgba(255,255,255,var(--divide-opacity))}.divide-gray-100>:not(template)~:not(template){--divide-opacity:1;border-color:#f7fafc;border-color:rgba(247,250,252,var(--divide-opacity))}.divide-gray-200>:not(template)~:not(template){--divide-opacity:1;border-color:#edf2f7;border-color:rgba(237,242,247,var(--divide-opacity))}.divide-gray-300>:not(template)~:not(template){--divide-opacity:1;border-color:#e2e8f0;border-color:rgba(226,232,240,var(--divide-opacity))}.divide-gray-400>:not(template)~:not(template){--divide-opacity:1;border-color:#cbd5e0;border-color:rgba(203,213,224,var(--divide-opacity))}.divide-gray-500>:not(template)~:not(template){--divide-opacity:1;border-color:#a0aec0;border-color:rgba(160,174,192,var(--divide-opacity))}.divide-gray-600>:not(template)~:not(template){--divide-opacity:1;border-color:#718096;border-color:rgba(113,128,150,var(--divide-opacity))}.divide-gray-700>:not(template)~:not(template){--divide-opacity:1;border-color:#4a5568;border-color:rgba(74,85,104,var(--divide-opacity))}.divide-gray-800>:not(template)~:not(template){--divide-opacity:1;border-color:#2d3748;border-color:rgba(45,55,72,var(--divide-opacity))}.divide-gray-900>:not(template)~:not(template){--divide-opacity:1;border-color:#1a202c;border-color:rgba(26,32,44,var(--divide-opacity))}.divide-red-100>:not(template)~:not(template){--divide-opacity:1;border-color:#fff5f5;border-color:rgba(255,245,245,var(--divide-opacity))}.divide-red-200>:not(template)~:not(template){--divide-opacity:1;border-color:#fed7d7;border-color:rgba(254,215,215,var(--divide-opacity))}.divide-red-300>:not(template)~:not(template){--divide-opacity:1;border-color:#feb2b2;border-color:rgba(254,178,178,var(--divide-opacity))}.divide-red-400>:not(template)~:not(template){--divide-opacity:1;border-color:#fc8181;border-color:rgba(252,129,129,var(--divide-opacity))}.divide-red-500>:not(template)~:not(template){--divide-opacity:1;border-color:#f56565;border-color:rgba(245,101,101,var(--divide-opacity))}.divide-red-600>:not(template)~:not(template){--divide-opacity:1;border-color:#e53e3e;border-color:rgba(229,62,62,var(--divide-opacity))}.divide-red-700>:not(template)~:not(template){--divide-opacity:1;border-color:#c53030;border-color:rgba(197,48,48,var(--divide-opacity))}.divide-red-800>:not(template)~:not(template){--divide-opacity:1;border-color:#9b2c2c;border-color:rgba(155,44,44,var(--divide-opacity))}.divide-red-900>:not(template)~:not(template){--divide-opacity:1;border-color:#742a2a;border-color:rgba(116,42,42,var(--divide-opacity))}.divide-orange-100>:not(template)~:not(template){--divide-opacity:1;border-color:#fffaf0;border-color:rgba(255,250,240,var(--divide-opacity))}.divide-orange-200>:not(template)~:not(template){--divide-opacity:1;border-color:#feebc8;border-color:rgba(254,235,200,var(--divide-opacity))}.divide-orange-300>:not(template)~:not(template){--divide-opacity:1;border-color:#fbd38d;border-color:rgba(251,211,141,var(--divide-opacity))}.divide-orange-400>:not(template)~:not(template){--divide-opacity:1;border-color:#f6ad55;border-color:rgba(246,173,85,var(--divide-opacity))}.divide-orange-500>:not(template)~:not(template){--divide-opacity:1;border-color:#ed8936;border-color:rgba(237,137,54,var(--divide-opacity))}.divide-orange-600>:not(template)~:not(template){--divide-opacity:1;border-color:#dd6b20;border-color:rgba(221,107,32,var(--divide-opacity))}.divide-orange-700>:not(template)~:not(template){--divide-opacity:1;border-color:#c05621;border-color:rgba(192,86,33,var(--divide-opacity))}.divide-orange-800>:not(template)~:not(template){--divide-opacity:1;border-color:#9c4221;border-color:rgba(156,66,33,var(--divide-opacity))}.divide-orange-900>:not(template)~:not(template){--divide-opacity:1;border-color:#7b341e;border-color:rgba(123,52,30,var(--divide-opacity))}.divide-yellow-100>:not(template)~:not(template){--divide-opacity:1;border-color:ivory;border-color:rgba(255,255,240,var(--divide-opacity))}.divide-yellow-200>:not(template)~:not(template){--divide-opacity:1;border-color:#fefcbf;border-color:rgba(254,252,191,var(--divide-opacity))}.divide-yellow-300>:not(template)~:not(template){--divide-opacity:1;border-color:#faf089;border-color:rgba(250,240,137,var(--divide-opacity))}.divide-yellow-400>:not(template)~:not(template){--divide-opacity:1;border-color:#f6e05e;border-color:rgba(246,224,94,var(--divide-opacity))}.divide-yellow-500>:not(template)~:not(template){--divide-opacity:1;border-color:#ecc94b;border-color:rgba(236,201,75,var(--divide-opacity))}.divide-yellow-600>:not(template)~:not(template){--divide-opacity:1;border-color:#d69e2e;border-color:rgba(214,158,46,var(--divide-opacity))}.divide-yellow-700>:not(template)~:not(template){--divide-opacity:1;border-color:#b7791f;border-color:rgba(183,121,31,var(--divide-opacity))}.divide-yellow-800>:not(template)~:not(template){--divide-opacity:1;border-color:#975a16;border-color:rgba(151,90,22,var(--divide-opacity))}.divide-yellow-900>:not(template)~:not(template){--divide-opacity:1;border-color:#744210;border-color:rgba(116,66,16,var(--divide-opacity))}.divide-green-100>:not(template)~:not(template){--divide-opacity:1;border-color:#f0fff4;border-color:rgba(240,255,244,var(--divide-opacity))}.divide-green-200>:not(template)~:not(template){--divide-opacity:1;border-color:#c6f6d5;border-color:rgba(198,246,213,var(--divide-opacity))}.divide-green-300>:not(template)~:not(template){--divide-opacity:1;border-color:#9ae6b4;border-color:rgba(154,230,180,var(--divide-opacity))}.divide-green-400>:not(template)~:not(template){--divide-opacity:1;border-color:#68d391;border-color:rgba(104,211,145,var(--divide-opacity))}.divide-green-500>:not(template)~:not(template){--divide-opacity:1;border-color:#48bb78;border-color:rgba(72,187,120,var(--divide-opacity))}.divide-green-600>:not(template)~:not(template){--divide-opacity:1;border-color:#38a169;border-color:rgba(56,161,105,var(--divide-opacity))}.divide-green-700>:not(template)~:not(template){--divide-opacity:1;border-color:#2f855a;border-color:rgba(47,133,90,var(--divide-opacity))}.divide-green-800>:not(template)~:not(template){--divide-opacity:1;border-color:#276749;border-color:rgba(39,103,73,var(--divide-opacity))}.divide-green-900>:not(template)~:not(template){--divide-opacity:1;border-color:#22543d;border-color:rgba(34,84,61,var(--divide-opacity))}.divide-teal-100>:not(template)~:not(template){--divide-opacity:1;border-color:#e6fffa;border-color:rgba(230,255,250,var(--divide-opacity))}.divide-teal-200>:not(template)~:not(template){--divide-opacity:1;border-color:#b2f5ea;border-color:rgba(178,245,234,var(--divide-opacity))}.divide-teal-300>:not(template)~:not(template){--divide-opacity:1;border-color:#81e6d9;border-color:rgba(129,230,217,var(--divide-opacity))}.divide-teal-400>:not(template)~:not(template){--divide-opacity:1;border-color:#4fd1c5;border-color:rgba(79,209,197,var(--divide-opacity))}.divide-teal-500>:not(template)~:not(template){--divide-opacity:1;border-color:#38b2ac;border-color:rgba(56,178,172,var(--divide-opacity))}.divide-teal-600>:not(template)~:not(template){--divide-opacity:1;border-color:#319795;border-color:rgba(49,151,149,var(--divide-opacity))}.divide-teal-700>:not(template)~:not(template){--divide-opacity:1;border-color:#2c7a7b;border-color:rgba(44,122,123,var(--divide-opacity))}.divide-teal-800>:not(template)~:not(template){--divide-opacity:1;border-color:#285e61;border-color:rgba(40,94,97,var(--divide-opacity))}.divide-teal-900>:not(template)~:not(template){--divide-opacity:1;border-color:#234e52;border-color:rgba(35,78,82,var(--divide-opacity))}.divide-blue-100>:not(template)~:not(template){--divide-opacity:1;border-color:#ebf8ff;border-color:rgba(235,248,255,var(--divide-opacity))}.divide-blue-200>:not(template)~:not(template){--divide-opacity:1;border-color:#bee3f8;border-color:rgba(190,227,248,var(--divide-opacity))}.divide-blue-300>:not(template)~:not(template){--divide-opacity:1;border-color:#90cdf4;border-color:rgba(144,205,244,var(--divide-opacity))}.divide-blue-400>:not(template)~:not(template){--divide-opacity:1;border-color:#63b3ed;border-color:rgba(99,179,237,var(--divide-opacity))}.divide-blue-500>:not(template)~:not(template){--divide-opacity:1;border-color:#4299e1;border-color:rgba(66,153,225,var(--divide-opacity))}.divide-blue-600>:not(template)~:not(template){--divide-opacity:1;border-color:#3182ce;border-color:rgba(49,130,206,var(--divide-opacity))}.divide-blue-700>:not(template)~:not(template){--divide-opacity:1;border-color:#2b6cb0;border-color:rgba(43,108,176,var(--divide-opacity))}.divide-blue-800>:not(template)~:not(template){--divide-opacity:1;border-color:#2c5282;border-color:rgba(44,82,130,var(--divide-opacity))}.divide-blue-900>:not(template)~:not(template){--divide-opacity:1;border-color:#2a4365;border-color:rgba(42,67,101,var(--divide-opacity))}.divide-indigo-100>:not(template)~:not(template){--divide-opacity:1;border-color:#ebf4ff;border-color:rgba(235,244,255,var(--divide-opacity))}.divide-indigo-200>:not(template)~:not(template){--divide-opacity:1;border-color:#c3dafe;border-color:rgba(195,218,254,var(--divide-opacity))}.divide-indigo-300>:not(template)~:not(template){--divide-opacity:1;border-color:#a3bffa;border-color:rgba(163,191,250,var(--divide-opacity))}.divide-indigo-400>:not(template)~:not(template){--divide-opacity:1;border-color:#7f9cf5;border-color:rgba(127,156,245,var(--divide-opacity))}.divide-indigo-500>:not(template)~:not(template){--divide-opacity:1;border-color:#667eea;border-color:rgba(102,126,234,var(--divide-opacity))}.divide-indigo-600>:not(template)~:not(template){--divide-opacity:1;border-color:#5a67d8;border-color:rgba(90,103,216,var(--divide-opacity))}.divide-indigo-700>:not(template)~:not(template){--divide-opacity:1;border-color:#4c51bf;border-color:rgba(76,81,191,var(--divide-opacity))}.divide-indigo-800>:not(template)~:not(template){--divide-opacity:1;border-color:#434190;border-color:rgba(67,65,144,var(--divide-opacity))}.divide-indigo-900>:not(template)~:not(template){--divide-opacity:1;border-color:#3c366b;border-color:rgba(60,54,107,var(--divide-opacity))}.divide-purple-100>:not(template)~:not(template){--divide-opacity:1;border-color:#faf5ff;border-color:rgba(250,245,255,var(--divide-opacity))}.divide-purple-200>:not(template)~:not(template){--divide-opacity:1;border-color:#e9d8fd;border-color:rgba(233,216,253,var(--divide-opacity))}.divide-purple-300>:not(template)~:not(template){--divide-opacity:1;border-color:#d6bcfa;border-color:rgba(214,188,250,var(--divide-opacity))}.divide-purple-400>:not(template)~:not(template){--divide-opacity:1;border-color:#b794f4;border-color:rgba(183,148,244,var(--divide-opacity))}.divide-purple-500>:not(template)~:not(template){--divide-opacity:1;border-color:#9f7aea;border-color:rgba(159,122,234,var(--divide-opacity))}.divide-purple-600>:not(template)~:not(template){--divide-opacity:1;border-color:#805ad5;border-color:rgba(128,90,213,var(--divide-opacity))}.divide-purple-700>:not(template)~:not(template){--divide-opacity:1;border-color:#6b46c1;border-color:rgba(107,70,193,var(--divide-opacity))}.divide-purple-800>:not(template)~:not(template){--divide-opacity:1;border-color:#553c9a;border-color:rgba(85,60,154,var(--divide-opacity))}.divide-purple-900>:not(template)~:not(template){--divide-opacity:1;border-color:#44337a;border-color:rgba(68,51,122,var(--divide-opacity))}.divide-pink-100>:not(template)~:not(template){--divide-opacity:1;border-color:#fff5f7;border-color:rgba(255,245,247,var(--divide-opacity))}.divide-pink-200>:not(template)~:not(template){--divide-opacity:1;border-color:#fed7e2;border-color:rgba(254,215,226,var(--divide-opacity))}.divide-pink-300>:not(template)~:not(template){--divide-opacity:1;border-color:#fbb6ce;border-color:rgba(251,182,206,var(--divide-opacity))}.divide-pink-400>:not(template)~:not(template){--divide-opacity:1;border-color:#f687b3;border-color:rgba(246,135,179,var(--divide-opacity))}.divide-pink-500>:not(template)~:not(template){--divide-opacity:1;border-color:#ed64a6;border-color:rgba(237,100,166,var(--divide-opacity))}.divide-pink-600>:not(template)~:not(template){--divide-opacity:1;border-color:#d53f8c;border-color:rgba(213,63,140,var(--divide-opacity))}.divide-pink-700>:not(template)~:not(template){--divide-opacity:1;border-color:#b83280;border-color:rgba(184,50,128,var(--divide-opacity))}.divide-pink-800>:not(template)~:not(template){--divide-opacity:1;border-color:#97266d;border-color:rgba(151,38,109,var(--divide-opacity))}.divide-pink-900>:not(template)~:not(template){--divide-opacity:1;border-color:#702459;border-color:rgba(112,36,89,var(--divide-opacity))}.divide-solid>:not(template)~:not(template){border-style:solid}.divide-dashed>:not(template)~:not(template){border-style:dashed}.divide-dotted>:not(template)~:not(template){border-style:dotted}.divide-double>:not(template)~:not(template){border-style:double}.divide-none>:not(template)~:not(template){border-style:none}.divide-opacity-0>:not(template)~:not(template){--divide-opacity:0}.divide-opacity-25>:not(template)~:not(template){--divide-opacity:0.25}.divide-opacity-50>:not(template)~:not(template){--divide-opacity:0.5}.divide-opacity-75>:not(template)~:not(template){--divide-opacity:0.75}.divide-opacity-100>:not(template)~:not(template){--divide-opacity:1}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border-width:0}.not-sr-only{position:static;width:auto;height:auto;padding:0;margin:0;overflow:visible;clip:auto;white-space:normal}.focus\:sr-only:focus{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border-width:0}.focus\:not-sr-only:focus{position:static;width:auto;height:auto;padding:0;margin:0;overflow:visible;clip:auto;white-space:normal}.appearance-none{-webkit-appearance:none;-moz-appearance:none;appearance:none}.bg-fixed{background-attachment:fixed}.bg-local{background-attachment:local}.bg-scroll{background-attachment:scroll}.bg-clip-border{background-clip:border-box}.bg-clip-padding{background-clip:padding-box}.bg-clip-content{background-clip:content-box}.bg-clip-text{-webkit-background-clip:text;background-clip:text}.bg-transparent{background-color:transparent}.bg-current{background-color:currentColor}.bg-black{--bg-opacity:1;background-color:#000;background-color:rgba(0,0,0,var(--bg-opacity))}.bg-white{--bg-opacity:1;background-color:#fff;background-color:rgba(255,255,255,var(--bg-opacity))}.bg-gray-100{--bg-opacity:1;background-color:#f7fafc;background-color:rgba(247,250,252,var(--bg-opacity))}.bg-gray-200{--bg-opacity:1;background-color:#edf2f7;background-color:rgba(237,242,247,var(--bg-opacity))}.bg-gray-300{--bg-opacity:1;background-color:#e2e8f0;background-color:rgba(226,232,240,var(--bg-opacity))}.bg-gray-400{--bg-opacity:1;background-color:#cbd5e0;background-color:rgba(203,213,224,var(--bg-opacity))}.bg-gray-500{--bg-opacity:1;background-color:#a0aec0;background-color:rgba(160,174,192,var(--bg-opacity))}.bg-gray-600{--bg-opacity:1;background-color:#718096;background-color:rgba(113,128,150,var(--bg-opacity))}.bg-gray-700{--bg-opacity:1;background-color:#4a5568;background-color:rgba(74,85,104,var(--bg-opacity))}.bg-gray-800{--bg-opacity:1;background-color:#2d3748;background-color:rgba(45,55,72,var(--bg-opacity))}.bg-gray-900{--bg-opacity:1;background-color:#1a202c;background-color:rgba(26,32,44,var(--bg-opacity))}.bg-red-100{--bg-opacity:1;background-color:#fff5f5;background-color:rgba(255,245,245,var(--bg-opacity))}.bg-red-200{--bg-opacity:1;background-color:#fed7d7;background-color:rgba(254,215,215,var(--bg-opacity))}.bg-red-300{--bg-opacity:1;background-color:#feb2b2;background-color:rgba(254,178,178,var(--bg-opacity))}.bg-red-400{--bg-opacity:1;background-color:#fc8181;background-color:rgba(252,129,129,var(--bg-opacity))}.bg-red-500{--bg-opacity:1;background-color:#f56565;background-color:rgba(245,101,101,var(--bg-opacity))}.bg-red-600{--bg-opacity:1;background-color:#e53e3e;background-color:rgba(229,62,62,var(--bg-opacity))}.bg-red-700{--bg-opacity:1;background-color:#c53030;background-color:rgba(197,48,48,var(--bg-opacity))}.bg-red-800{--bg-opacity:1;background-color:#9b2c2c;background-color:rgba(155,44,44,var(--bg-opacity))}.bg-red-900{--bg-opacity:1;background-color:#742a2a;background-color:rgba(116,42,42,var(--bg-opacity))}.bg-orange-100{--bg-opacity:1;background-color:#fffaf0;background-color:rgba(255,250,240,var(--bg-opacity))}.bg-orange-200{--bg-opacity:1;background-color:#feebc8;background-color:rgba(254,235,200,var(--bg-opacity))}.bg-orange-300{--bg-opacity:1;background-color:#fbd38d;background-color:rgba(251,211,141,var(--bg-opacity))}.bg-orange-400{--bg-opacity:1;background-color:#f6ad55;background-color:rgba(246,173,85,var(--bg-opacity))}.bg-orange-500{--bg-opacity:1;background-color:#ed8936;background-color:rgba(237,137,54,var(--bg-opacity))}.bg-orange-600{--bg-opacity:1;background-color:#dd6b20;background-color:rgba(221,107,32,var(--bg-opacity))}.bg-orange-700{--bg-opacity:1;background-color:#c05621;background-color:rgba(192,86,33,var(--bg-opacity))}.bg-orange-800{--bg-opacity:1;background-color:#9c4221;background-color:rgba(156,66,33,var(--bg-opacity))}.bg-orange-900{--bg-opacity:1;background-color:#7b341e;background-color:rgba(123,52,30,var(--bg-opacity))}.bg-yellow-100{--bg-opacity:1;background-color:ivory;background-color:rgba(255,255,240,var(--bg-opacity))}.bg-yellow-200{--bg-opacity:1;background-color:#fefcbf;background-color:rgba(254,252,191,var(--bg-opacity))}.bg-yellow-300{--bg-opacity:1;background-color:#faf089;background-color:rgba(250,240,137,var(--bg-opacity))}.bg-yellow-400{--bg-opacity:1;background-color:#f6e05e;background-color:rgba(246,224,94,var(--bg-opacity))}.bg-yellow-500{--bg-opacity:1;background-color:#ecc94b;background-color:rgba(236,201,75,var(--bg-opacity))}.bg-yellow-600{--bg-opacity:1;background-color:#d69e2e;background-color:rgba(214,158,46,var(--bg-opacity))}.bg-yellow-700{--bg-opacity:1;background-color:#b7791f;background-color:rgba(183,121,31,var(--bg-opacity))}.bg-yellow-800{--bg-opacity:1;background-color:#975a16;background-color:rgba(151,90,22,var(--bg-opacity))}.bg-yellow-900{--bg-opacity:1;background-color:#744210;background-color:rgba(116,66,16,var(--bg-opacity))}.bg-green-100{--bg-opacity:1;background-color:#f0fff4;background-color:rgba(240,255,244,var(--bg-opacity))}.bg-green-200{--bg-opacity:1;background-color:#c6f6d5;background-color:rgba(198,246,213,var(--bg-opacity))}.bg-green-300{--bg-opacity:1;background-color:#9ae6b4;background-color:rgba(154,230,180,var(--bg-opacity))}.bg-green-400{--bg-opacity:1;background-color:#68d391;background-color:rgba(104,211,145,var(--bg-opacity))}.bg-green-500{--bg-opacity:1;background-color:#48bb78;background-color:rgba(72,187,120,var(--bg-opacity))}.bg-green-600{--bg-opacity:1;background-color:#38a169;background-color:rgba(56,161,105,var(--bg-opacity))}.bg-green-700{--bg-opacity:1;background-color:#2f855a;background-color:rgba(47,133,90,var(--bg-opacity))}.bg-green-800{--bg-opacity:1;background-color:#276749;background-color:rgba(39,103,73,var(--bg-opacity))}.bg-green-900{--bg-opacity:1;background-color:#22543d;background-color:rgba(34,84,61,var(--bg-opacity))}.bg-teal-100{--bg-opacity:1;background-color:#e6fffa;background-color:rgba(230,255,250,var(--bg-opacity))}.bg-teal-200{--bg-opacity:1;background-color:#b2f5ea;background-color:rgba(178,245,234,var(--bg-opacity))}.bg-teal-300{--bg-opacity:1;background-color:#81e6d9;background-color:rgba(129,230,217,var(--bg-opacity))}.bg-teal-400{--bg-opacity:1;background-color:#4fd1c5;background-color:rgba(79,209,197,var(--bg-opacity))}.bg-teal-500{--bg-opacity:1;background-color:#38b2ac;background-color:rgba(56,178,172,var(--bg-opacity))}.bg-teal-600{--bg-opacity:1;background-color:#319795;background-color:rgba(49,151,149,var(--bg-opacity))}.bg-teal-700{--bg-opacity:1;background-color:#2c7a7b;background-color:rgba(44,122,123,var(--bg-opacity))}.bg-teal-800{--bg-opacity:1;background-color:#285e61;background-color:rgba(40,94,97,var(--bg-opacity))}.bg-teal-900{--bg-opacity:1;background-color:#234e52;background-color:rgba(35,78,82,var(--bg-opacity))}.bg-blue-100{--bg-opacity:1;background-color:#ebf8ff;background-color:rgba(235,248,255,var(--bg-opacity))}.bg-blue-200{--bg-opacity:1;background-color:#bee3f8;background-color:rgba(190,227,248,var(--bg-opacity))}.bg-blue-300{--bg-opacity:1;background-color:#90cdf4;background-color:rgba(144,205,244,var(--bg-opacity))}.bg-blue-400{--bg-opacity:1;background-color:#63b3ed;background-color:rgba(99,179,237,var(--bg-opacity))}.bg-blue-500{--bg-opacity:1;background-color:#4299e1;background-color:rgba(66,153,225,var(--bg-opacity))}.bg-blue-600{--bg-opacity:1;background-color:#3182ce;background-color:rgba(49,130,206,var(--bg-opacity))}.bg-blue-700{--bg-opacity:1;background-color:#2b6cb0;background-color:rgba(43,108,176,var(--bg-opacity))}.bg-blue-800{--bg-opacity:1;background-color:#2c5282;background-color:rgba(44,82,130,var(--bg-opacity))}.bg-blue-900{--bg-opacity:1;background-color:#2a4365;background-color:rgba(42,67,101,var(--bg-opacity))}.bg-indigo-100{--bg-opacity:1;background-color:#ebf4ff;background-color:rgba(235,244,255,var(--bg-opacity))}.bg-indigo-200{--bg-opacity:1;background-color:#c3dafe;background-color:rgba(195,218,254,var(--bg-opacity))}.bg-indigo-300{--bg-opacity:1;background-color:#a3bffa;background-color:rgba(163,191,250,var(--bg-opacity))}.bg-indigo-400{--bg-opacity:1;background-color:#7f9cf5;background-color:rgba(127,156,245,var(--bg-opacity))}.bg-indigo-500{--bg-opacity:1;background-color:#667eea;background-color:rgba(102,126,234,var(--bg-opacity))}.bg-indigo-600{--bg-opacity:1;background-color:#5a67d8;background-color:rgba(90,103,216,var(--bg-opacity))}.bg-indigo-700{--bg-opacity:1;background-color:#4c51bf;background-color:rgba(76,81,191,var(--bg-opacity))}.bg-indigo-800{--bg-opacity:1;background-color:#434190;background-color:rgba(67,65,144,var(--bg-opacity))}.bg-indigo-900{--bg-opacity:1;background-color:#3c366b;background-color:rgba(60,54,107,var(--bg-opacity))}.bg-purple-100{--bg-opacity:1;background-color:#faf5ff;background-color:rgba(250,245,255,var(--bg-opacity))}.bg-purple-200{--bg-opacity:1;background-color:#e9d8fd;background-color:rgba(233,216,253,var(--bg-opacity))}.bg-purple-300{--bg-opacity:1;background-color:#d6bcfa;background-color:rgba(214,188,250,var(--bg-opacity))}.bg-purple-400{--bg-opacity:1;background-color:#b794f4;background-color:rgba(183,148,244,var(--bg-opacity))}.bg-purple-500{--bg-opacity:1;background-color:#9f7aea;background-color:rgba(159,122,234,var(--bg-opacity))}.bg-purple-600{--bg-opacity:1;background-color:#805ad5;background-color:rgba(128,90,213,var(--bg-opacity))}.bg-purple-700{--bg-opacity:1;background-color:#6b46c1;background-color:rgba(107,70,193,var(--bg-opacity))}.bg-purple-800{--bg-opacity:1;background-color:#553c9a;background-color:rgba(85,60,154,var(--bg-opacity))}.bg-purple-900{--bg-opacity:1;background-color:#44337a;background-color:rgba(68,51,122,var(--bg-opacity))}.bg-pink-100{--bg-opacity:1;background-color:#fff5f7;background-color:rgba(255,245,247,var(--bg-opacity))}.bg-pink-200{--bg-opacity:1;background-color:#fed7e2;background-color:rgba(254,215,226,var(--bg-opacity))}.bg-pink-300{--bg-opacity:1;background-color:#fbb6ce;background-color:rgba(251,182,206,var(--bg-opacity))}.bg-pink-400{--bg-opacity:1;background-color:#f687b3;background-color:rgba(246,135,179,var(--bg-opacity))}.bg-pink-500{--bg-opacity:1;background-color:#ed64a6;background-color:rgba(237,100,166,var(--bg-opacity))}.bg-pink-600{--bg-opacity:1;background-color:#d53f8c;background-color:rgba(213,63,140,var(--bg-opacity))}.bg-pink-700{--bg-opacity:1;background-color:#b83280;background-color:rgba(184,50,128,var(--bg-opacity))}.bg-pink-800{--bg-opacity:1;background-color:#97266d;background-color:rgba(151,38,109,var(--bg-opacity))}.bg-pink-900{--bg-opacity:1;background-color:#702459;background-color:rgba(112,36,89,var(--bg-opacity))}.hover\:bg-transparent:hover{background-color:transparent}.hover\:bg-current:hover{background-color:currentColor}.hover\:bg-black:hover{--bg-opacity:1;background-color:#000;background-color:rgba(0,0,0,var(--bg-opacity))}.hover\:bg-white:hover{--bg-opacity:1;background-color:#fff;background-color:rgba(255,255,255,var(--bg-opacity))}.hover\:bg-gray-100:hover{--bg-opacity:1;background-color:#f7fafc;background-color:rgba(247,250,252,var(--bg-opacity))}.hover\:bg-gray-200:hover{--bg-opacity:1;background-color:#edf2f7;background-color:rgba(237,242,247,var(--bg-opacity))}.hover\:bg-gray-300:hover{--bg-opacity:1;background-color:#e2e8f0;background-color:rgba(226,232,240,var(--bg-opacity))}.hover\:bg-gray-400:hover{--bg-opacity:1;background-color:#cbd5e0;background-color:rgba(203,213,224,var(--bg-opacity))}.hover\:bg-gray-500:hover{--bg-opacity:1;background-color:#a0aec0;background-color:rgba(160,174,192,var(--bg-opacity))}.hover\:bg-gray-600:hover{--bg-opacity:1;background-color:#718096;background-color:rgba(113,128,150,var(--bg-opacity))}.hover\:bg-gray-700:hover{--bg-opacity:1;background-color:#4a5568;background-color:rgba(74,85,104,var(--bg-opacity))}.hover\:bg-gray-800:hover{--bg-opacity:1;background-color:#2d3748;background-color:rgba(45,55,72,var(--bg-opacity))}.hover\:bg-gray-900:hover{--bg-opacity:1;background-color:#1a202c;background-color:rgba(26,32,44,var(--bg-opacity))}.hover\:bg-red-100:hover{--bg-opacity:1;background-color:#fff5f5;background-color:rgba(255,245,245,var(--bg-opacity))}.hover\:bg-red-200:hover{--bg-opacity:1;background-color:#fed7d7;background-color:rgba(254,215,215,var(--bg-opacity))}.hover\:bg-red-300:hover{--bg-opacity:1;background-color:#feb2b2;background-color:rgba(254,178,178,var(--bg-opacity))}.hover\:bg-red-400:hover{--bg-opacity:1;background-color:#fc8181;background-color:rgba(252,129,129,var(--bg-opacity))}.hover\:bg-red-500:hover{--bg-opacity:1;background-color:#f56565;background-color:rgba(245,101,101,var(--bg-opacity))}.hover\:bg-red-600:hover{--bg-opacity:1;background-color:#e53e3e;background-color:rgba(229,62,62,var(--bg-opacity))}.hover\:bg-red-700:hover{--bg-opacity:1;background-color:#c53030;background-color:rgba(197,48,48,var(--bg-opacity))}.hover\:bg-red-800:hover{--bg-opacity:1;background-color:#9b2c2c;background-color:rgba(155,44,44,var(--bg-opacity))}.hover\:bg-red-900:hover{--bg-opacity:1;background-color:#742a2a;background-color:rgba(116,42,42,var(--bg-opacity))}.hover\:bg-orange-100:hover{--bg-opacity:1;background-color:#fffaf0;background-color:rgba(255,250,240,var(--bg-opacity))}.hover\:bg-orange-200:hover{--bg-opacity:1;background-color:#feebc8;background-color:rgba(254,235,200,var(--bg-opacity))}.hover\:bg-orange-300:hover{--bg-opacity:1;background-color:#fbd38d;background-color:rgba(251,211,141,var(--bg-opacity))}.hover\:bg-orange-400:hover{--bg-opacity:1;background-color:#f6ad55;background-color:rgba(246,173,85,var(--bg-opacity))}.hover\:bg-orange-500:hover{--bg-opacity:1;background-color:#ed8936;background-color:rgba(237,137,54,var(--bg-opacity))}.hover\:bg-orange-600:hover{--bg-opacity:1;background-color:#dd6b20;background-color:rgba(221,107,32,var(--bg-opacity))}.hover\:bg-orange-700:hover{--bg-opacity:1;background-color:#c05621;background-color:rgba(192,86,33,var(--bg-opacity))}.hover\:bg-orange-800:hover{--bg-opacity:1;background-color:#9c4221;background-color:rgba(156,66,33,var(--bg-opacity))}.hover\:bg-orange-900:hover{--bg-opacity:1;background-color:#7b341e;background-color:rgba(123,52,30,var(--bg-opacity))}.hover\:bg-yellow-100:hover{--bg-opacity:1;background-color:ivory;background-color:rgba(255,255,240,var(--bg-opacity))}.hover\:bg-yellow-200:hover{--bg-opacity:1;background-color:#fefcbf;background-color:rgba(254,252,191,var(--bg-opacity))}.hover\:bg-yellow-300:hover{--bg-opacity:1;background-color:#faf089;background-color:rgba(250,240,137,var(--bg-opacity))}.hover\:bg-yellow-400:hover{--bg-opacity:1;background-color:#f6e05e;background-color:rgba(246,224,94,var(--bg-opacity))}.hover\:bg-yellow-500:hover{--bg-opacity:1;background-color:#ecc94b;background-color:rgba(236,201,75,var(--bg-opacity))}.hover\:bg-yellow-600:hover{--bg-opacity:1;background-color:#d69e2e;background-color:rgba(214,158,46,var(--bg-opacity))}.hover\:bg-yellow-700:hover{--bg-opacity:1;background-color:#b7791f;background-color:rgba(183,121,31,var(--bg-opacity))}.hover\:bg-yellow-800:hover{--bg-opacity:1;background-color:#975a16;background-color:rgba(151,90,22,var(--bg-opacity))}.hover\:bg-yellow-900:hover{--bg-opacity:1;background-color:#744210;background-color:rgba(116,66,16,var(--bg-opacity))}.hover\:bg-green-100:hover{--bg-opacity:1;background-color:#f0fff4;background-color:rgba(240,255,244,var(--bg-opacity))}.hover\:bg-green-200:hover{--bg-opacity:1;background-color:#c6f6d5;background-color:rgba(198,246,213,var(--bg-opacity))}.hover\:bg-green-300:hover{--bg-opacity:1;background-color:#9ae6b4;background-color:rgba(154,230,180,var(--bg-opacity))}.hover\:bg-green-400:hover{--bg-opacity:1;background-color:#68d391;background-color:rgba(104,211,145,var(--bg-opacity))}.hover\:bg-green-500:hover{--bg-opacity:1;background-color:#48bb78;background-color:rgba(72,187,120,var(--bg-opacity))}.hover\:bg-green-600:hover{--bg-opacity:1;background-color:#38a169;background-color:rgba(56,161,105,var(--bg-opacity))}.hover\:bg-green-700:hover{--bg-opacity:1;background-color:#2f855a;background-color:rgba(47,133,90,var(--bg-opacity))}.hover\:bg-green-800:hover{--bg-opacity:1;background-color:#276749;background-color:rgba(39,103,73,var(--bg-opacity))}.hover\:bg-green-900:hover{--bg-opacity:1;background-color:#22543d;background-color:rgba(34,84,61,var(--bg-opacity))}.hover\:bg-teal-100:hover{--bg-opacity:1;background-color:#e6fffa;background-color:rgba(230,255,250,var(--bg-opacity))}.hover\:bg-teal-200:hover{--bg-opacity:1;background-color:#b2f5ea;background-color:rgba(178,245,234,var(--bg-opacity))}.hover\:bg-teal-300:hover{--bg-opacity:1;background-color:#81e6d9;background-color:rgba(129,230,217,var(--bg-opacity))}.hover\:bg-teal-400:hover{--bg-opacity:1;background-color:#4fd1c5;background-color:rgba(79,209,197,var(--bg-opacity))}.hover\:bg-teal-500:hover{--bg-opacity:1;background-color:#38b2ac;background-color:rgba(56,178,172,var(--bg-opacity))}.hover\:bg-teal-600:hover{--bg-opacity:1;background-color:#319795;background-color:rgba(49,151,149,var(--bg-opacity))}.hover\:bg-teal-700:hover{--bg-opacity:1;background-color:#2c7a7b;background-color:rgba(44,122,123,var(--bg-opacity))}.hover\:bg-teal-800:hover{--bg-opacity:1;background-color:#285e61;background-color:rgba(40,94,97,var(--bg-opacity))}.hover\:bg-teal-900:hover{--bg-opacity:1;background-color:#234e52;background-color:rgba(35,78,82,var(--bg-opacity))}.hover\:bg-blue-100:hover{--bg-opacity:1;background-color:#ebf8ff;background-color:rgba(235,248,255,var(--bg-opacity))}.hover\:bg-blue-200:hover{--bg-opacity:1;background-color:#bee3f8;background-color:rgba(190,227,248,var(--bg-opacity))}.hover\:bg-blue-300:hover{--bg-opacity:1;background-color:#90cdf4;background-color:rgba(144,205,244,var(--bg-opacity))}.hover\:bg-blue-400:hover{--bg-opacity:1;background-color:#63b3ed;background-color:rgba(99,179,237,var(--bg-opacity))}.hover\:bg-blue-500:hover{--bg-opacity:1;background-color:#4299e1;background-color:rgba(66,153,225,var(--bg-opacity))}.hover\:bg-blue-600:hover{--bg-opacity:1;background-color:#3182ce;background-color:rgba(49,130,206,var(--bg-opacity))}.hover\:bg-blue-700:hover{--bg-opacity:1;background-color:#2b6cb0;background-color:rgba(43,108,176,var(--bg-opacity))}.hover\:bg-blue-800:hover{--bg-opacity:1;background-color:#2c5282;background-color:rgba(44,82,130,var(--bg-opacity))}.hover\:bg-blue-900:hover{--bg-opacity:1;background-color:#2a4365;background-color:rgba(42,67,101,var(--bg-opacity))}.hover\:bg-indigo-100:hover{--bg-opacity:1;background-color:#ebf4ff;background-color:rgba(235,244,255,var(--bg-opacity))}.hover\:bg-indigo-200:hover{--bg-opacity:1;background-color:#c3dafe;background-color:rgba(195,218,254,var(--bg-opacity))}.hover\:bg-indigo-300:hover{--bg-opacity:1;background-color:#a3bffa;background-color:rgba(163,191,250,var(--bg-opacity))}.hover\:bg-indigo-400:hover{--bg-opacity:1;background-color:#7f9cf5;background-color:rgba(127,156,245,var(--bg-opacity))}.hover\:bg-indigo-500:hover{--bg-opacity:1;background-color:#667eea;background-color:rgba(102,126,234,var(--bg-opacity))}.hover\:bg-indigo-600:hover{--bg-opacity:1;background-color:#5a67d8;background-color:rgba(90,103,216,var(--bg-opacity))}.hover\:bg-indigo-700:hover{--bg-opacity:1;background-color:#4c51bf;background-color:rgba(76,81,191,var(--bg-opacity))}.hover\:bg-indigo-800:hover{--bg-opacity:1;background-color:#434190;background-color:rgba(67,65,144,var(--bg-opacity))}.hover\:bg-indigo-900:hover{--bg-opacity:1;background-color:#3c366b;background-color:rgba(60,54,107,var(--bg-opacity))}.hover\:bg-purple-100:hover{--bg-opacity:1;background-color:#faf5ff;background-color:rgba(250,245,255,var(--bg-opacity))}.hover\:bg-purple-200:hover{--bg-opacity:1;background-color:#e9d8fd;background-color:rgba(233,216,253,var(--bg-opacity))}.hover\:bg-purple-300:hover{--bg-opacity:1;background-color:#d6bcfa;background-color:rgba(214,188,250,var(--bg-opacity))}.hover\:bg-purple-400:hover{--bg-opacity:1;background-color:#b794f4;background-color:rgba(183,148,244,var(--bg-opacity))}.hover\:bg-purple-500:hover{--bg-opacity:1;background-color:#9f7aea;background-color:rgba(159,122,234,var(--bg-opacity))}.hover\:bg-purple-600:hover{--bg-opacity:1;background-color:#805ad5;background-color:rgba(128,90,213,var(--bg-opacity))}.hover\:bg-purple-700:hover{--bg-opacity:1;background-color:#6b46c1;background-color:rgba(107,70,193,var(--bg-opacity))}.hover\:bg-purple-800:hover{--bg-opacity:1;background-color:#553c9a;background-color:rgba(85,60,154,var(--bg-opacity))}.hover\:bg-purple-900:hover{--bg-opacity:1;background-color:#44337a;background-color:rgba(68,51,122,var(--bg-opacity))}.hover\:bg-pink-100:hover{--bg-opacity:1;background-color:#fff5f7;background-color:rgba(255,245,247,var(--bg-opacity))}.hover\:bg-pink-200:hover{--bg-opacity:1;background-color:#fed7e2;background-color:rgba(254,215,226,var(--bg-opacity))}.hover\:bg-pink-300:hover{--bg-opacity:1;background-color:#fbb6ce;background-color:rgba(251,182,206,var(--bg-opacity))}.hover\:bg-pink-400:hover{--bg-opacity:1;background-color:#f687b3;background-color:rgba(246,135,179,var(--bg-opacity))}.hover\:bg-pink-500:hover{--bg-opacity:1;background-color:#ed64a6;background-color:rgba(237,100,166,var(--bg-opacity))}.hover\:bg-pink-600:hover{--bg-opacity:1;background-color:#d53f8c;background-color:rgba(213,63,140,var(--bg-opacity))}.hover\:bg-pink-700:hover{--bg-opacity:1;background-color:#b83280;background-color:rgba(184,50,128,var(--bg-opacity))}.hover\:bg-pink-800:hover{--bg-opacity:1;background-color:#97266d;background-color:rgba(151,38,109,var(--bg-opacity))}.hover\:bg-pink-900:hover{--bg-opacity:1;background-color:#702459;background-color:rgba(112,36,89,var(--bg-opacity))}.focus\:bg-transparent:focus{background-color:transparent}.focus\:bg-current:focus{background-color:currentColor}.focus\:bg-black:focus{--bg-opacity:1;background-color:#000;background-color:rgba(0,0,0,var(--bg-opacity))}.focus\:bg-white:focus{--bg-opacity:1;background-color:#fff;background-color:rgba(255,255,255,var(--bg-opacity))}.focus\:bg-gray-100:focus{--bg-opacity:1;background-color:#f7fafc;background-color:rgba(247,250,252,var(--bg-opacity))}.focus\:bg-gray-200:focus{--bg-opacity:1;background-color:#edf2f7;background-color:rgba(237,242,247,var(--bg-opacity))}.focus\:bg-gray-300:focus{--bg-opacity:1;background-color:#e2e8f0;background-color:rgba(226,232,240,var(--bg-opacity))}.focus\:bg-gray-400:focus{--bg-opacity:1;background-color:#cbd5e0;background-color:rgba(203,213,224,var(--bg-opacity))}.focus\:bg-gray-500:focus{--bg-opacity:1;background-color:#a0aec0;background-color:rgba(160,174,192,var(--bg-opacity))}.focus\:bg-gray-600:focus{--bg-opacity:1;background-color:#718096;background-color:rgba(113,128,150,var(--bg-opacity))}.focus\:bg-gray-700:focus{--bg-opacity:1;background-color:#4a5568;background-color:rgba(74,85,104,var(--bg-opacity))}.focus\:bg-gray-800:focus{--bg-opacity:1;background-color:#2d3748;background-color:rgba(45,55,72,var(--bg-opacity))}.focus\:bg-gray-900:focus{--bg-opacity:1;background-color:#1a202c;background-color:rgba(26,32,44,var(--bg-opacity))}.focus\:bg-red-100:focus{--bg-opacity:1;background-color:#fff5f5;background-color:rgba(255,245,245,var(--bg-opacity))}.focus\:bg-red-200:focus{--bg-opacity:1;background-color:#fed7d7;background-color:rgba(254,215,215,var(--bg-opacity))}.focus\:bg-red-300:focus{--bg-opacity:1;background-color:#feb2b2;background-color:rgba(254,178,178,var(--bg-opacity))}.focus\:bg-red-400:focus{--bg-opacity:1;background-color:#fc8181;background-color:rgba(252,129,129,var(--bg-opacity))}.focus\:bg-red-500:focus{--bg-opacity:1;background-color:#f56565;background-color:rgba(245,101,101,var(--bg-opacity))}.focus\:bg-red-600:focus{--bg-opacity:1;background-color:#e53e3e;background-color:rgba(229,62,62,var(--bg-opacity))}.focus\:bg-red-700:focus{--bg-opacity:1;background-color:#c53030;background-color:rgba(197,48,48,var(--bg-opacity))}.focus\:bg-red-800:focus{--bg-opacity:1;background-color:#9b2c2c;background-color:rgba(155,44,44,var(--bg-opacity))}.focus\:bg-red-900:focus{--bg-opacity:1;background-color:#742a2a;background-color:rgba(116,42,42,var(--bg-opacity))}.focus\:bg-orange-100:focus{--bg-opacity:1;background-color:#fffaf0;background-color:rgba(255,250,240,var(--bg-opacity))}.focus\:bg-orange-200:focus{--bg-opacity:1;background-color:#feebc8;background-color:rgba(254,235,200,var(--bg-opacity))}.focus\:bg-orange-300:focus{--bg-opacity:1;background-color:#fbd38d;background-color:rgba(251,211,141,var(--bg-opacity))}.focus\:bg-orange-400:focus{--bg-opacity:1;background-color:#f6ad55;background-color:rgba(246,173,85,var(--bg-opacity))}.focus\:bg-orange-500:focus{--bg-opacity:1;background-color:#ed8936;background-color:rgba(237,137,54,var(--bg-opacity))}.focus\:bg-orange-600:focus{--bg-opacity:1;background-color:#dd6b20;background-color:rgba(221,107,32,var(--bg-opacity))}.focus\:bg-orange-700:focus{--bg-opacity:1;background-color:#c05621;background-color:rgba(192,86,33,var(--bg-opacity))}.focus\:bg-orange-800:focus{--bg-opacity:1;background-color:#9c4221;background-color:rgba(156,66,33,var(--bg-opacity))}.focus\:bg-orange-900:focus{--bg-opacity:1;background-color:#7b341e;background-color:rgba(123,52,30,var(--bg-opacity))}.focus\:bg-yellow-100:focus{--bg-opacity:1;background-color:ivory;background-color:rgba(255,255,240,var(--bg-opacity))}.focus\:bg-yellow-200:focus{--bg-opacity:1;background-color:#fefcbf;background-color:rgba(254,252,191,var(--bg-opacity))}.focus\:bg-yellow-300:focus{--bg-opacity:1;background-color:#faf089;background-color:rgba(250,240,137,var(--bg-opacity))}.focus\:bg-yellow-400:focus{--bg-opacity:1;background-color:#f6e05e;background-color:rgba(246,224,94,var(--bg-opacity))}.focus\:bg-yellow-500:focus{--bg-opacity:1;background-color:#ecc94b;background-color:rgba(236,201,75,var(--bg-opacity))}.focus\:bg-yellow-600:focus{--bg-opacity:1;background-color:#d69e2e;background-color:rgba(214,158,46,var(--bg-opacity))}.focus\:bg-yellow-700:focus{--bg-opacity:1;background-color:#b7791f;background-color:rgba(183,121,31,var(--bg-opacity))}.focus\:bg-yellow-800:focus{--bg-opacity:1;background-color:#975a16;background-color:rgba(151,90,22,var(--bg-opacity))}.focus\:bg-yellow-900:focus{--bg-opacity:1;background-color:#744210;background-color:rgba(116,66,16,var(--bg-opacity))}.focus\:bg-green-100:focus{--bg-opacity:1;background-color:#f0fff4;background-color:rgba(240,255,244,var(--bg-opacity))}.focus\:bg-green-200:focus{--bg-opacity:1;background-color:#c6f6d5;background-color:rgba(198,246,213,var(--bg-opacity))}.focus\:bg-green-300:focus{--bg-opacity:1;background-color:#9ae6b4;background-color:rgba(154,230,180,var(--bg-opacity))}.focus\:bg-green-400:focus{--bg-opacity:1;background-color:#68d391;background-color:rgba(104,211,145,var(--bg-opacity))}.focus\:bg-green-500:focus{--bg-opacity:1;background-color:#48bb78;background-color:rgba(72,187,120,var(--bg-opacity))}.focus\:bg-green-600:focus{--bg-opacity:1;background-color:#38a169;background-color:rgba(56,161,105,var(--bg-opacity))}.focus\:bg-green-700:focus{--bg-opacity:1;background-color:#2f855a;background-color:rgba(47,133,90,var(--bg-opacity))}.focus\:bg-green-800:focus{--bg-opacity:1;background-color:#276749;background-color:rgba(39,103,73,var(--bg-opacity))}.focus\:bg-green-900:focus{--bg-opacity:1;background-color:#22543d;background-color:rgba(34,84,61,var(--bg-opacity))}.focus\:bg-teal-100:focus{--bg-opacity:1;background-color:#e6fffa;background-color:rgba(230,255,250,var(--bg-opacity))}.focus\:bg-teal-200:focus{--bg-opacity:1;background-color:#b2f5ea;background-color:rgba(178,245,234,var(--bg-opacity))}.focus\:bg-teal-300:focus{--bg-opacity:1;background-color:#81e6d9;background-color:rgba(129,230,217,var(--bg-opacity))}.focus\:bg-teal-400:focus{--bg-opacity:1;background-color:#4fd1c5;background-color:rgba(79,209,197,var(--bg-opacity))}.focus\:bg-teal-500:focus{--bg-opacity:1;background-color:#38b2ac;background-color:rgba(56,178,172,var(--bg-opacity))}.focus\:bg-teal-600:focus{--bg-opacity:1;background-color:#319795;background-color:rgba(49,151,149,var(--bg-opacity))}.focus\:bg-teal-700:focus{--bg-opacity:1;background-color:#2c7a7b;background-color:rgba(44,122,123,var(--bg-opacity))}.focus\:bg-teal-800:focus{--bg-opacity:1;background-color:#285e61;background-color:rgba(40,94,97,var(--bg-opacity))}.focus\:bg-teal-900:focus{--bg-opacity:1;background-color:#234e52;background-color:rgba(35,78,82,var(--bg-opacity))}.focus\:bg-blue-100:focus{--bg-opacity:1;background-color:#ebf8ff;background-color:rgba(235,248,255,var(--bg-opacity))}.focus\:bg-blue-200:focus{--bg-opacity:1;background-color:#bee3f8;background-color:rgba(190,227,248,var(--bg-opacity))}.focus\:bg-blue-300:focus{--bg-opacity:1;background-color:#90cdf4;background-color:rgba(144,205,244,var(--bg-opacity))}.focus\:bg-blue-400:focus{--bg-opacity:1;background-color:#63b3ed;background-color:rgba(99,179,237,var(--bg-opacity))}.focus\:bg-blue-500:focus{--bg-opacity:1;background-color:#4299e1;background-color:rgba(66,153,225,var(--bg-opacity))}.focus\:bg-blue-600:focus{--bg-opacity:1;background-color:#3182ce;background-color:rgba(49,130,206,var(--bg-opacity))}.focus\:bg-blue-700:focus{--bg-opacity:1;background-color:#2b6cb0;background-color:rgba(43,108,176,var(--bg-opacity))}.focus\:bg-blue-800:focus{--bg-opacity:1;background-color:#2c5282;background-color:rgba(44,82,130,var(--bg-opacity))}.focus\:bg-blue-900:focus{--bg-opacity:1;background-color:#2a4365;background-color:rgba(42,67,101,var(--bg-opacity))}.focus\:bg-indigo-100:focus{--bg-opacity:1;background-color:#ebf4ff;background-color:rgba(235,244,255,var(--bg-opacity))}.focus\:bg-indigo-200:focus{--bg-opacity:1;background-color:#c3dafe;background-color:rgba(195,218,254,var(--bg-opacity))}.focus\:bg-indigo-300:focus{--bg-opacity:1;background-color:#a3bffa;background-color:rgba(163,191,250,var(--bg-opacity))}.focus\:bg-indigo-400:focus{--bg-opacity:1;background-color:#7f9cf5;background-color:rgba(127,156,245,var(--bg-opacity))}.focus\:bg-indigo-500:focus{--bg-opacity:1;background-color:#667eea;background-color:rgba(102,126,234,var(--bg-opacity))}.focus\:bg-indigo-600:focus{--bg-opacity:1;background-color:#5a67d8;background-color:rgba(90,103,216,var(--bg-opacity))}.focus\:bg-indigo-700:focus{--bg-opacity:1;background-color:#4c51bf;background-color:rgba(76,81,191,var(--bg-opacity))}.focus\:bg-indigo-800:focus{--bg-opacity:1;background-color:#434190;background-color:rgba(67,65,144,var(--bg-opacity))}.focus\:bg-indigo-900:focus{--bg-opacity:1;background-color:#3c366b;background-color:rgba(60,54,107,var(--bg-opacity))}.focus\:bg-purple-100:focus{--bg-opacity:1;background-color:#faf5ff;background-color:rgba(250,245,255,var(--bg-opacity))}.focus\:bg-purple-200:focus{--bg-opacity:1;background-color:#e9d8fd;background-color:rgba(233,216,253,var(--bg-opacity))}.focus\:bg-purple-300:focus{--bg-opacity:1;background-color:#d6bcfa;background-color:rgba(214,188,250,var(--bg-opacity))}.focus\:bg-purple-400:focus{--bg-opacity:1;background-color:#b794f4;background-color:rgba(183,148,244,var(--bg-opacity))}.focus\:bg-purple-500:focus{--bg-opacity:1;background-color:#9f7aea;background-color:rgba(159,122,234,var(--bg-opacity))}.focus\:bg-purple-600:focus{--bg-opacity:1;background-color:#805ad5;background-color:rgba(128,90,213,var(--bg-opacity))}.focus\:bg-purple-700:focus{--bg-opacity:1;background-color:#6b46c1;background-color:rgba(107,70,193,var(--bg-opacity))}.focus\:bg-purple-800:focus{--bg-opacity:1;background-color:#553c9a;background-color:rgba(85,60,154,var(--bg-opacity))}.focus\:bg-purple-900:focus{--bg-opacity:1;background-color:#44337a;background-color:rgba(68,51,122,var(--bg-opacity))}.focus\:bg-pink-100:focus{--bg-opacity:1;background-color:#fff5f7;background-color:rgba(255,245,247,var(--bg-opacity))}.focus\:bg-pink-200:focus{--bg-opacity:1;background-color:#fed7e2;background-color:rgba(254,215,226,var(--bg-opacity))}.focus\:bg-pink-300:focus{--bg-opacity:1;background-color:#fbb6ce;background-color:rgba(251,182,206,var(--bg-opacity))}.focus\:bg-pink-400:focus{--bg-opacity:1;background-color:#f687b3;background-color:rgba(246,135,179,var(--bg-opacity))}.focus\:bg-pink-500:focus{--bg-opacity:1;background-color:#ed64a6;background-color:rgba(237,100,166,var(--bg-opacity))}.focus\:bg-pink-600:focus{--bg-opacity:1;background-color:#d53f8c;background-color:rgba(213,63,140,var(--bg-opacity))}.focus\:bg-pink-700:focus{--bg-opacity:1;background-color:#b83280;background-color:rgba(184,50,128,var(--bg-opacity))}.focus\:bg-pink-800:focus{--bg-opacity:1;background-color:#97266d;background-color:rgba(151,38,109,var(--bg-opacity))}.focus\:bg-pink-900:focus{--bg-opacity:1;background-color:#702459;background-color:rgba(112,36,89,var(--bg-opacity))}.bg-none{background-image:none}.bg-gradient-to-t{background-image:linear-gradient(to top,var(--gradient-color-stops))}.bg-gradient-to-tr{background-image:linear-gradient(to top right,var(--gradient-color-stops))}.bg-gradient-to-r{background-image:linear-gradient(to right,var(--gradient-color-stops))}.bg-gradient-to-br{background-image:linear-gradient(to bottom right,var(--gradient-color-stops))}.bg-gradient-to-b{background-image:linear-gradient(to bottom,var(--gradient-color-stops))}.bg-gradient-to-bl{background-image:linear-gradient(to bottom left,var(--gradient-color-stops))}.bg-gradient-to-l{background-image:linear-gradient(to left,var(--gradient-color-stops))}.bg-gradient-to-tl{background-image:linear-gradient(to top left,var(--gradient-color-stops))}.from-transparent{--gradient-from-color:transparent;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(0, 0, 0, 0))}.from-current{--gradient-from-color:currentColor;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 255, 255, 0))}.from-black{--gradient-from-color:#000;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(0, 0, 0, 0))}.from-white{--gradient-from-color:#fff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 255, 255, 0))}.from-gray-100{--gradient-from-color:#f7fafc;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(247, 250, 252, 0))}.from-gray-200{--gradient-from-color:#edf2f7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(237, 242, 247, 0))}.from-gray-300{--gradient-from-color:#e2e8f0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(226, 232, 240, 0))}.from-gray-400{--gradient-from-color:#cbd5e0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(203, 213, 224, 0))}.from-gray-500{--gradient-from-color:#a0aec0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(160, 174, 192, 0))}.from-gray-600{--gradient-from-color:#718096;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(113, 128, 150, 0))}.from-gray-700{--gradient-from-color:#4a5568;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(74, 85, 104, 0))}.from-gray-800{--gradient-from-color:#2d3748;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(45, 55, 72, 0))}.from-gray-900{--gradient-from-color:#1a202c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(26, 32, 44, 0))}.from-red-100{--gradient-from-color:#fff5f5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 245, 245, 0))}.from-red-200{--gradient-from-color:#fed7d7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(254, 215, 215, 0))}.from-red-300{--gradient-from-color:#feb2b2;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(254, 178, 178, 0))}.from-red-400{--gradient-from-color:#fc8181;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(252, 129, 129, 0))}.from-red-500{--gradient-from-color:#f56565;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(245, 101, 101, 0))}.from-red-600{--gradient-from-color:#e53e3e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(229, 62, 62, 0))}.from-red-700{--gradient-from-color:#c53030;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(197, 48, 48, 0))}.from-red-800{--gradient-from-color:#9b2c2c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(155, 44, 44, 0))}.from-red-900{--gradient-from-color:#742a2a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(116, 42, 42, 0))}.from-orange-100{--gradient-from-color:#fffaf0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 250, 240, 0))}.from-orange-200{--gradient-from-color:#feebc8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(254, 235, 200, 0))}.from-orange-300{--gradient-from-color:#fbd38d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(251, 211, 141, 0))}.from-orange-400{--gradient-from-color:#f6ad55;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(246, 173, 85, 0))}.from-orange-500{--gradient-from-color:#ed8936;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(237, 137, 54, 0))}.from-orange-600{--gradient-from-color:#dd6b20;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(221, 107, 32, 0))}.from-orange-700{--gradient-from-color:#c05621;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(192, 86, 33, 0))}.from-orange-800{--gradient-from-color:#9c4221;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(156, 66, 33, 0))}.from-orange-900{--gradient-from-color:#7b341e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(123, 52, 30, 0))}.from-yellow-100{--gradient-from-color:#fffff0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 255, 240, 0))}.from-yellow-200{--gradient-from-color:#fefcbf;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(254, 252, 191, 0))}.from-yellow-300{--gradient-from-color:#faf089;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(250, 240, 137, 0))}.from-yellow-400{--gradient-from-color:#f6e05e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(246, 224, 94, 0))}.from-yellow-500{--gradient-from-color:#ecc94b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(236, 201, 75, 0))}.from-yellow-600{--gradient-from-color:#d69e2e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(214, 158, 46, 0))}.from-yellow-700{--gradient-from-color:#b7791f;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(183, 121, 31, 0))}.from-yellow-800{--gradient-from-color:#975a16;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(151, 90, 22, 0))}.from-yellow-900{--gradient-from-color:#744210;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(116, 66, 16, 0))}.from-green-100{--gradient-from-color:#f0fff4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(240, 255, 244, 0))}.from-green-200{--gradient-from-color:#c6f6d5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(198, 246, 213, 0))}.from-green-300{--gradient-from-color:#9ae6b4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(154, 230, 180, 0))}.from-green-400{--gradient-from-color:#68d391;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(104, 211, 145, 0))}.from-green-500{--gradient-from-color:#48bb78;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(72, 187, 120, 0))}.from-green-600{--gradient-from-color:#38a169;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(56, 161, 105, 0))}.from-green-700{--gradient-from-color:#2f855a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(47, 133, 90, 0))}.from-green-800{--gradient-from-color:#276749;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(39, 103, 73, 0))}.from-green-900{--gradient-from-color:#22543d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(34, 84, 61, 0))}.from-teal-100{--gradient-from-color:#e6fffa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(230, 255, 250, 0))}.from-teal-200{--gradient-from-color:#b2f5ea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(178, 245, 234, 0))}.from-teal-300{--gradient-from-color:#81e6d9;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(129, 230, 217, 0))}.from-teal-400{--gradient-from-color:#4fd1c5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(79, 209, 197, 0))}.from-teal-500{--gradient-from-color:#38b2ac;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(56, 178, 172, 0))}.from-teal-600{--gradient-from-color:#319795;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(49, 151, 149, 0))}.from-teal-700{--gradient-from-color:#2c7a7b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(44, 122, 123, 0))}.from-teal-800{--gradient-from-color:#285e61;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(40, 94, 97, 0))}.from-teal-900{--gradient-from-color:#234e52;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(35, 78, 82, 0))}.from-blue-100{--gradient-from-color:#ebf8ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(235, 248, 255, 0))}.from-blue-200{--gradient-from-color:#bee3f8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(190, 227, 248, 0))}.from-blue-300{--gradient-from-color:#90cdf4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(144, 205, 244, 0))}.from-blue-400{--gradient-from-color:#63b3ed;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(99, 179, 237, 0))}.from-blue-500{--gradient-from-color:#4299e1;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(66, 153, 225, 0))}.from-blue-600{--gradient-from-color:#3182ce;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(49, 130, 206, 0))}.from-blue-700{--gradient-from-color:#2b6cb0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(43, 108, 176, 0))}.from-blue-800{--gradient-from-color:#2c5282;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(44, 82, 130, 0))}.from-blue-900{--gradient-from-color:#2a4365;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(42, 67, 101, 0))}.from-indigo-100{--gradient-from-color:#ebf4ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(235, 244, 255, 0))}.from-indigo-200{--gradient-from-color:#c3dafe;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(195, 218, 254, 0))}.from-indigo-300{--gradient-from-color:#a3bffa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(163, 191, 250, 0))}.from-indigo-400{--gradient-from-color:#7f9cf5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(127, 156, 245, 0))}.from-indigo-500{--gradient-from-color:#667eea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(102, 126, 234, 0))}.from-indigo-600{--gradient-from-color:#5a67d8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(90, 103, 216, 0))}.from-indigo-700{--gradient-from-color:#4c51bf;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(76, 81, 191, 0))}.from-indigo-800{--gradient-from-color:#434190;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(67, 65, 144, 0))}.from-indigo-900{--gradient-from-color:#3c366b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(60, 54, 107, 0))}.from-purple-100{--gradient-from-color:#faf5ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(250, 245, 255, 0))}.from-purple-200{--gradient-from-color:#e9d8fd;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(233, 216, 253, 0))}.from-purple-300{--gradient-from-color:#d6bcfa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(214, 188, 250, 0))}.from-purple-400{--gradient-from-color:#b794f4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(183, 148, 244, 0))}.from-purple-500{--gradient-from-color:#9f7aea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(159, 122, 234, 0))}.from-purple-600{--gradient-from-color:#805ad5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(128, 90, 213, 0))}.from-purple-700{--gradient-from-color:#6b46c1;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(107, 70, 193, 0))}.from-purple-800{--gradient-from-color:#553c9a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(85, 60, 154, 0))}.from-purple-900{--gradient-from-color:#44337a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(68, 51, 122, 0))}.from-pink-100{--gradient-from-color:#fff5f7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 245, 247, 0))}.from-pink-200{--gradient-from-color:#fed7e2;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(254, 215, 226, 0))}.from-pink-300{--gradient-from-color:#fbb6ce;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(251, 182, 206, 0))}.from-pink-400{--gradient-from-color:#f687b3;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(246, 135, 179, 0))}.from-pink-500{--gradient-from-color:#ed64a6;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(237, 100, 166, 0))}.from-pink-600{--gradient-from-color:#d53f8c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(213, 63, 140, 0))}.from-pink-700{--gradient-from-color:#b83280;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(184, 50, 128, 0))}.from-pink-800{--gradient-from-color:#97266d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(151, 38, 109, 0))}.from-pink-900{--gradient-from-color:#702459;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(112, 36, 89, 0))}.via-transparent{--gradient-via-color:transparent;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(0, 0, 0, 0))}.via-current{--gradient-via-color:currentColor;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 255, 255, 0))}.via-black{--gradient-via-color:#000;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(0, 0, 0, 0))}.via-white{--gradient-via-color:#fff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 255, 255, 0))}.via-gray-100{--gradient-via-color:#f7fafc;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(247, 250, 252, 0))}.via-gray-200{--gradient-via-color:#edf2f7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(237, 242, 247, 0))}.via-gray-300{--gradient-via-color:#e2e8f0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(226, 232, 240, 0))}.via-gray-400{--gradient-via-color:#cbd5e0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(203, 213, 224, 0))}.via-gray-500{--gradient-via-color:#a0aec0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(160, 174, 192, 0))}.via-gray-600{--gradient-via-color:#718096;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(113, 128, 150, 0))}.via-gray-700{--gradient-via-color:#4a5568;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(74, 85, 104, 0))}.via-gray-800{--gradient-via-color:#2d3748;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(45, 55, 72, 0))}.via-gray-900{--gradient-via-color:#1a202c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(26, 32, 44, 0))}.via-red-100{--gradient-via-color:#fff5f5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 245, 245, 0))}.via-red-200{--gradient-via-color:#fed7d7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(254, 215, 215, 0))}.via-red-300{--gradient-via-color:#feb2b2;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(254, 178, 178, 0))}.via-red-400{--gradient-via-color:#fc8181;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(252, 129, 129, 0))}.via-red-500{--gradient-via-color:#f56565;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(245, 101, 101, 0))}.via-red-600{--gradient-via-color:#e53e3e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(229, 62, 62, 0))}.via-red-700{--gradient-via-color:#c53030;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(197, 48, 48, 0))}.via-red-800{--gradient-via-color:#9b2c2c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(155, 44, 44, 0))}.via-red-900{--gradient-via-color:#742a2a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(116, 42, 42, 0))}.via-orange-100{--gradient-via-color:#fffaf0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 250, 240, 0))}.via-orange-200{--gradient-via-color:#feebc8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(254, 235, 200, 0))}.via-orange-300{--gradient-via-color:#fbd38d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(251, 211, 141, 0))}.via-orange-400{--gradient-via-color:#f6ad55;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(246, 173, 85, 0))}.via-orange-500{--gradient-via-color:#ed8936;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(237, 137, 54, 0))}.via-orange-600{--gradient-via-color:#dd6b20;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(221, 107, 32, 0))}.via-orange-700{--gradient-via-color:#c05621;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(192, 86, 33, 0))}.via-orange-800{--gradient-via-color:#9c4221;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(156, 66, 33, 0))}.via-orange-900{--gradient-via-color:#7b341e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(123, 52, 30, 0))}.via-yellow-100{--gradient-via-color:#fffff0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 255, 240, 0))}.via-yellow-200{--gradient-via-color:#fefcbf;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(254, 252, 191, 0))}.via-yellow-300{--gradient-via-color:#faf089;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(250, 240, 137, 0))}.via-yellow-400{--gradient-via-color:#f6e05e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(246, 224, 94, 0))}.via-yellow-500{--gradient-via-color:#ecc94b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(236, 201, 75, 0))}.via-yellow-600{--gradient-via-color:#d69e2e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(214, 158, 46, 0))}.via-yellow-700{--gradient-via-color:#b7791f;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(183, 121, 31, 0))}.via-yellow-800{--gradient-via-color:#975a16;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(151, 90, 22, 0))}.via-yellow-900{--gradient-via-color:#744210;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(116, 66, 16, 0))}.via-green-100{--gradient-via-color:#f0fff4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(240, 255, 244, 0))}.via-green-200{--gradient-via-color:#c6f6d5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(198, 246, 213, 0))}.via-green-300{--gradient-via-color:#9ae6b4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(154, 230, 180, 0))}.via-green-400{--gradient-via-color:#68d391;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(104, 211, 145, 0))}.via-green-500{--gradient-via-color:#48bb78;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(72, 187, 120, 0))}.via-green-600{--gradient-via-color:#38a169;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(56, 161, 105, 0))}.via-green-700{--gradient-via-color:#2f855a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(47, 133, 90, 0))}.via-green-800{--gradient-via-color:#276749;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(39, 103, 73, 0))}.via-green-900{--gradient-via-color:#22543d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(34, 84, 61, 0))}.via-teal-100{--gradient-via-color:#e6fffa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(230, 255, 250, 0))}.via-teal-200{--gradient-via-color:#b2f5ea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(178, 245, 234, 0))}.via-teal-300{--gradient-via-color:#81e6d9;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(129, 230, 217, 0))}.via-teal-400{--gradient-via-color:#4fd1c5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(79, 209, 197, 0))}.via-teal-500{--gradient-via-color:#38b2ac;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(56, 178, 172, 0))}.via-teal-600{--gradient-via-color:#319795;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(49, 151, 149, 0))}.via-teal-700{--gradient-via-color:#2c7a7b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(44, 122, 123, 0))}.via-teal-800{--gradient-via-color:#285e61;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(40, 94, 97, 0))}.via-teal-900{--gradient-via-color:#234e52;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(35, 78, 82, 0))}.via-blue-100{--gradient-via-color:#ebf8ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(235, 248, 255, 0))}.via-blue-200{--gradient-via-color:#bee3f8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(190, 227, 248, 0))}.via-blue-300{--gradient-via-color:#90cdf4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(144, 205, 244, 0))}.via-blue-400{--gradient-via-color:#63b3ed;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(99, 179, 237, 0))}.via-blue-500{--gradient-via-color:#4299e1;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(66, 153, 225, 0))}.via-blue-600{--gradient-via-color:#3182ce;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(49, 130, 206, 0))}.via-blue-700{--gradient-via-color:#2b6cb0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(43, 108, 176, 0))}.via-blue-800{--gradient-via-color:#2c5282;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(44, 82, 130, 0))}.via-blue-900{--gradient-via-color:#2a4365;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(42, 67, 101, 0))}.via-indigo-100{--gradient-via-color:#ebf4ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(235, 244, 255, 0))}.via-indigo-200{--gradient-via-color:#c3dafe;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(195, 218, 254, 0))}.via-indigo-300{--gradient-via-color:#a3bffa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(163, 191, 250, 0))}.via-indigo-400{--gradient-via-color:#7f9cf5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(127, 156, 245, 0))}.via-indigo-500{--gradient-via-color:#667eea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(102, 126, 234, 0))}.via-indigo-600{--gradient-via-color:#5a67d8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(90, 103, 216, 0))}.via-indigo-700{--gradient-via-color:#4c51bf;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(76, 81, 191, 0))}.via-indigo-800{--gradient-via-color:#434190;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(67, 65, 144, 0))}.via-indigo-900{--gradient-via-color:#3c366b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(60, 54, 107, 0))}.via-purple-100{--gradient-via-color:#faf5ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(250, 245, 255, 0))}.via-purple-200{--gradient-via-color:#e9d8fd;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(233, 216, 253, 0))}.via-purple-300{--gradient-via-color:#d6bcfa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(214, 188, 250, 0))}.via-purple-400{--gradient-via-color:#b794f4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(183, 148, 244, 0))}.via-purple-500{--gradient-via-color:#9f7aea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(159, 122, 234, 0))}.via-purple-600{--gradient-via-color:#805ad5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(128, 90, 213, 0))}.via-purple-700{--gradient-via-color:#6b46c1;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(107, 70, 193, 0))}.via-purple-800{--gradient-via-color:#553c9a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(85, 60, 154, 0))}.via-purple-900{--gradient-via-color:#44337a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(68, 51, 122, 0))}.via-pink-100{--gradient-via-color:#fff5f7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 245, 247, 0))}.via-pink-200{--gradient-via-color:#fed7e2;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(254, 215, 226, 0))}.via-pink-300{--gradient-via-color:#fbb6ce;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(251, 182, 206, 0))}.via-pink-400{--gradient-via-color:#f687b3;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(246, 135, 179, 0))}.via-pink-500{--gradient-via-color:#ed64a6;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(237, 100, 166, 0))}.via-pink-600{--gradient-via-color:#d53f8c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(213, 63, 140, 0))}.via-pink-700{--gradient-via-color:#b83280;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(184, 50, 128, 0))}.via-pink-800{--gradient-via-color:#97266d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(151, 38, 109, 0))}.via-pink-900{--gradient-via-color:#702459;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(112, 36, 89, 0))}.to-transparent{--gradient-to-color:transparent}.to-current{--gradient-to-color:currentColor}.to-black{--gradient-to-color:#000}.to-white{--gradient-to-color:#fff}.to-gray-100{--gradient-to-color:#f7fafc}.to-gray-200{--gradient-to-color:#edf2f7}.to-gray-300{--gradient-to-color:#e2e8f0}.to-gray-400{--gradient-to-color:#cbd5e0}.to-gray-500{--gradient-to-color:#a0aec0}.to-gray-600{--gradient-to-color:#718096}.to-gray-700{--gradient-to-color:#4a5568}.to-gray-800{--gradient-to-color:#2d3748}.to-gray-900{--gradient-to-color:#1a202c}.to-red-100{--gradient-to-color:#fff5f5}.to-red-200{--gradient-to-color:#fed7d7}.to-red-300{--gradient-to-color:#feb2b2}.to-red-400{--gradient-to-color:#fc8181}.to-red-500{--gradient-to-color:#f56565}.to-red-600{--gradient-to-color:#e53e3e}.to-red-700{--gradient-to-color:#c53030}.to-red-800{--gradient-to-color:#9b2c2c}.to-red-900{--gradient-to-color:#742a2a}.to-orange-100{--gradient-to-color:#fffaf0}.to-orange-200{--gradient-to-color:#feebc8}.to-orange-300{--gradient-to-color:#fbd38d}.to-orange-400{--gradient-to-color:#f6ad55}.to-orange-500{--gradient-to-color:#ed8936}.to-orange-600{--gradient-to-color:#dd6b20}.to-orange-700{--gradient-to-color:#c05621}.to-orange-800{--gradient-to-color:#9c4221}.to-orange-900{--gradient-to-color:#7b341e}.to-yellow-100{--gradient-to-color:#fffff0}.to-yellow-200{--gradient-to-color:#fefcbf}.to-yellow-300{--gradient-to-color:#faf089}.to-yellow-400{--gradient-to-color:#f6e05e}.to-yellow-500{--gradient-to-color:#ecc94b}.to-yellow-600{--gradient-to-color:#d69e2e}.to-yellow-700{--gradient-to-color:#b7791f}.to-yellow-800{--gradient-to-color:#975a16}.to-yellow-900{--gradient-to-color:#744210}.to-green-100{--gradient-to-color:#f0fff4}.to-green-200{--gradient-to-color:#c6f6d5}.to-green-300{--gradient-to-color:#9ae6b4}.to-green-400{--gradient-to-color:#68d391}.to-green-500{--gradient-to-color:#48bb78}.to-green-600{--gradient-to-color:#38a169}.to-green-700{--gradient-to-color:#2f855a}.to-green-800{--gradient-to-color:#276749}.to-green-900{--gradient-to-color:#22543d}.to-teal-100{--gradient-to-color:#e6fffa}.to-teal-200{--gradient-to-color:#b2f5ea}.to-teal-300{--gradient-to-color:#81e6d9}.to-teal-400{--gradient-to-color:#4fd1c5}.to-teal-500{--gradient-to-color:#38b2ac}.to-teal-600{--gradient-to-color:#319795}.to-teal-700{--gradient-to-color:#2c7a7b}.to-teal-800{--gradient-to-color:#285e61}.to-teal-900{--gradient-to-color:#234e52}.to-blue-100{--gradient-to-color:#ebf8ff}.to-blue-200{--gradient-to-color:#bee3f8}.to-blue-300{--gradient-to-color:#90cdf4}.to-blue-400{--gradient-to-color:#63b3ed}.to-blue-500{--gradient-to-color:#4299e1}.to-blue-600{--gradient-to-color:#3182ce}.to-blue-700{--gradient-to-color:#2b6cb0}.to-blue-800{--gradient-to-color:#2c5282}.to-blue-900{--gradient-to-color:#2a4365}.to-indigo-100{--gradient-to-color:#ebf4ff}.to-indigo-200{--gradient-to-color:#c3dafe}.to-indigo-300{--gradient-to-color:#a3bffa}.to-indigo-400{--gradient-to-color:#7f9cf5}.to-indigo-500{--gradient-to-color:#667eea}.to-indigo-600{--gradient-to-color:#5a67d8}.to-indigo-700{--gradient-to-color:#4c51bf}.to-indigo-800{--gradient-to-color:#434190}.to-indigo-900{--gradient-to-color:#3c366b}.to-purple-100{--gradient-to-color:#faf5ff}.to-purple-200{--gradient-to-color:#e9d8fd}.to-purple-300{--gradient-to-color:#d6bcfa}.to-purple-400{--gradient-to-color:#b794f4}.to-purple-500{--gradient-to-color:#9f7aea}.to-purple-600{--gradient-to-color:#805ad5}.to-purple-700{--gradient-to-color:#6b46c1}.to-purple-800{--gradient-to-color:#553c9a}.to-purple-900{--gradient-to-color:#44337a}.to-pink-100{--gradient-to-color:#fff5f7}.to-pink-200{--gradient-to-color:#fed7e2}.to-pink-300{--gradient-to-color:#fbb6ce}.to-pink-400{--gradient-to-color:#f687b3}.to-pink-500{--gradient-to-color:#ed64a6}.to-pink-600{--gradient-to-color:#d53f8c}.to-pink-700{--gradient-to-color:#b83280}.to-pink-800{--gradient-to-color:#97266d}.to-pink-900{--gradient-to-color:#702459}.hover\:from-transparent:hover{--gradient-from-color:transparent;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(0, 0, 0, 0))}.hover\:from-current:hover{--gradient-from-color:currentColor;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 255, 255, 0))}.hover\:from-black:hover{--gradient-from-color:#000;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(0, 0, 0, 0))}.hover\:from-white:hover{--gradient-from-color:#fff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 255, 255, 0))}.hover\:from-gray-100:hover{--gradient-from-color:#f7fafc;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(247, 250, 252, 0))}.hover\:from-gray-200:hover{--gradient-from-color:#edf2f7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(237, 242, 247, 0))}.hover\:from-gray-300:hover{--gradient-from-color:#e2e8f0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(226, 232, 240, 0))}.hover\:from-gray-400:hover{--gradient-from-color:#cbd5e0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(203, 213, 224, 0))}.hover\:from-gray-500:hover{--gradient-from-color:#a0aec0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(160, 174, 192, 0))}.hover\:from-gray-600:hover{--gradient-from-color:#718096;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(113, 128, 150, 0))}.hover\:from-gray-700:hover{--gradient-from-color:#4a5568;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(74, 85, 104, 0))}.hover\:from-gray-800:hover{--gradient-from-color:#2d3748;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(45, 55, 72, 0))}.hover\:from-gray-900:hover{--gradient-from-color:#1a202c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(26, 32, 44, 0))}.hover\:from-red-100:hover{--gradient-from-color:#fff5f5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 245, 245, 0))}.hover\:from-red-200:hover{--gradient-from-color:#fed7d7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(254, 215, 215, 0))}.hover\:from-red-300:hover{--gradient-from-color:#feb2b2;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(254, 178, 178, 0))}.hover\:from-red-400:hover{--gradient-from-color:#fc8181;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(252, 129, 129, 0))}.hover\:from-red-500:hover{--gradient-from-color:#f56565;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(245, 101, 101, 0))}.hover\:from-red-600:hover{--gradient-from-color:#e53e3e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(229, 62, 62, 0))}.hover\:from-red-700:hover{--gradient-from-color:#c53030;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(197, 48, 48, 0))}.hover\:from-red-800:hover{--gradient-from-color:#9b2c2c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(155, 44, 44, 0))}.hover\:from-red-900:hover{--gradient-from-color:#742a2a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(116, 42, 42, 0))}.hover\:from-orange-100:hover{--gradient-from-color:#fffaf0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 250, 240, 0))}.hover\:from-orange-200:hover{--gradient-from-color:#feebc8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(254, 235, 200, 0))}.hover\:from-orange-300:hover{--gradient-from-color:#fbd38d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(251, 211, 141, 0))}.hover\:from-orange-400:hover{--gradient-from-color:#f6ad55;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(246, 173, 85, 0))}.hover\:from-orange-500:hover{--gradient-from-color:#ed8936;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(237, 137, 54, 0))}.hover\:from-orange-600:hover{--gradient-from-color:#dd6b20;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(221, 107, 32, 0))}.hover\:from-orange-700:hover{--gradient-from-color:#c05621;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(192, 86, 33, 0))}.hover\:from-orange-800:hover{--gradient-from-color:#9c4221;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(156, 66, 33, 0))}.hover\:from-orange-900:hover{--gradient-from-color:#7b341e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(123, 52, 30, 0))}.hover\:from-yellow-100:hover{--gradient-from-color:#fffff0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 255, 240, 0))}.hover\:from-yellow-200:hover{--gradient-from-color:#fefcbf;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(254, 252, 191, 0))}.hover\:from-yellow-300:hover{--gradient-from-color:#faf089;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(250, 240, 137, 0))}.hover\:from-yellow-400:hover{--gradient-from-color:#f6e05e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(246, 224, 94, 0))}.hover\:from-yellow-500:hover{--gradient-from-color:#ecc94b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(236, 201, 75, 0))}.hover\:from-yellow-600:hover{--gradient-from-color:#d69e2e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(214, 158, 46, 0))}.hover\:from-yellow-700:hover{--gradient-from-color:#b7791f;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(183, 121, 31, 0))}.hover\:from-yellow-800:hover{--gradient-from-color:#975a16;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(151, 90, 22, 0))}.hover\:from-yellow-900:hover{--gradient-from-color:#744210;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(116, 66, 16, 0))}.hover\:from-green-100:hover{--gradient-from-color:#f0fff4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(240, 255, 244, 0))}.hover\:from-green-200:hover{--gradient-from-color:#c6f6d5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(198, 246, 213, 0))}.hover\:from-green-300:hover{--gradient-from-color:#9ae6b4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(154, 230, 180, 0))}.hover\:from-green-400:hover{--gradient-from-color:#68d391;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(104, 211, 145, 0))}.hover\:from-green-500:hover{--gradient-from-color:#48bb78;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(72, 187, 120, 0))}.hover\:from-green-600:hover{--gradient-from-color:#38a169;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(56, 161, 105, 0))}.hover\:from-green-700:hover{--gradient-from-color:#2f855a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(47, 133, 90, 0))}.hover\:from-green-800:hover{--gradient-from-color:#276749;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(39, 103, 73, 0))}.hover\:from-green-900:hover{--gradient-from-color:#22543d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(34, 84, 61, 0))}.hover\:from-teal-100:hover{--gradient-from-color:#e6fffa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(230, 255, 250, 0))}.hover\:from-teal-200:hover{--gradient-from-color:#b2f5ea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(178, 245, 234, 0))}.hover\:from-teal-300:hover{--gradient-from-color:#81e6d9;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(129, 230, 217, 0))}.hover\:from-teal-400:hover{--gradient-from-color:#4fd1c5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(79, 209, 197, 0))}.hover\:from-teal-500:hover{--gradient-from-color:#38b2ac;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(56, 178, 172, 0))}.hover\:from-teal-600:hover{--gradient-from-color:#319795;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(49, 151, 149, 0))}.hover\:from-teal-700:hover{--gradient-from-color:#2c7a7b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(44, 122, 123, 0))}.hover\:from-teal-800:hover{--gradient-from-color:#285e61;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(40, 94, 97, 0))}.hover\:from-teal-900:hover{--gradient-from-color:#234e52;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(35, 78, 82, 0))}.hover\:from-blue-100:hover{--gradient-from-color:#ebf8ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(235, 248, 255, 0))}.hover\:from-blue-200:hover{--gradient-from-color:#bee3f8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(190, 227, 248, 0))}.hover\:from-blue-300:hover{--gradient-from-color:#90cdf4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(144, 205, 244, 0))}.hover\:from-blue-400:hover{--gradient-from-color:#63b3ed;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(99, 179, 237, 0))}.hover\:from-blue-500:hover{--gradient-from-color:#4299e1;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(66, 153, 225, 0))}.hover\:from-blue-600:hover{--gradient-from-color:#3182ce;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(49, 130, 206, 0))}.hover\:from-blue-700:hover{--gradient-from-color:#2b6cb0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(43, 108, 176, 0))}.hover\:from-blue-800:hover{--gradient-from-color:#2c5282;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(44, 82, 130, 0))}.hover\:from-blue-900:hover{--gradient-from-color:#2a4365;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(42, 67, 101, 0))}.hover\:from-indigo-100:hover{--gradient-from-color:#ebf4ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(235, 244, 255, 0))}.hover\:from-indigo-200:hover{--gradient-from-color:#c3dafe;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(195, 218, 254, 0))}.hover\:from-indigo-300:hover{--gradient-from-color:#a3bffa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(163, 191, 250, 0))}.hover\:from-indigo-400:hover{--gradient-from-color:#7f9cf5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(127, 156, 245, 0))}.hover\:from-indigo-500:hover{--gradient-from-color:#667eea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(102, 126, 234, 0))}.hover\:from-indigo-600:hover{--gradient-from-color:#5a67d8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(90, 103, 216, 0))}.hover\:from-indigo-700:hover{--gradient-from-color:#4c51bf;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(76, 81, 191, 0))}.hover\:from-indigo-800:hover{--gradient-from-color:#434190;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(67, 65, 144, 0))}.hover\:from-indigo-900:hover{--gradient-from-color:#3c366b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(60, 54, 107, 0))}.hover\:from-purple-100:hover{--gradient-from-color:#faf5ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(250, 245, 255, 0))}.hover\:from-purple-200:hover{--gradient-from-color:#e9d8fd;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(233, 216, 253, 0))}.hover\:from-purple-300:hover{--gradient-from-color:#d6bcfa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(214, 188, 250, 0))}.hover\:from-purple-400:hover{--gradient-from-color:#b794f4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(183, 148, 244, 0))}.hover\:from-purple-500:hover{--gradient-from-color:#9f7aea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(159, 122, 234, 0))}.hover\:from-purple-600:hover{--gradient-from-color:#805ad5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(128, 90, 213, 0))}.hover\:from-purple-700:hover{--gradient-from-color:#6b46c1;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(107, 70, 193, 0))}.hover\:from-purple-800:hover{--gradient-from-color:#553c9a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(85, 60, 154, 0))}.hover\:from-purple-900:hover{--gradient-from-color:#44337a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(68, 51, 122, 0))}.hover\:from-pink-100:hover{--gradient-from-color:#fff5f7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 245, 247, 0))}.hover\:from-pink-200:hover{--gradient-from-color:#fed7e2;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(254, 215, 226, 0))}.hover\:from-pink-300:hover{--gradient-from-color:#fbb6ce;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(251, 182, 206, 0))}.hover\:from-pink-400:hover{--gradient-from-color:#f687b3;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(246, 135, 179, 0))}.hover\:from-pink-500:hover{--gradient-from-color:#ed64a6;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(237, 100, 166, 0))}.hover\:from-pink-600:hover{--gradient-from-color:#d53f8c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(213, 63, 140, 0))}.hover\:from-pink-700:hover{--gradient-from-color:#b83280;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(184, 50, 128, 0))}.hover\:from-pink-800:hover{--gradient-from-color:#97266d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(151, 38, 109, 0))}.hover\:from-pink-900:hover{--gradient-from-color:#702459;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(112, 36, 89, 0))}.hover\:via-transparent:hover{--gradient-via-color:transparent;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(0, 0, 0, 0))}.hover\:via-current:hover{--gradient-via-color:currentColor;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 255, 255, 0))}.hover\:via-black:hover{--gradient-via-color:#000;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(0, 0, 0, 0))}.hover\:via-white:hover{--gradient-via-color:#fff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 255, 255, 0))}.hover\:via-gray-100:hover{--gradient-via-color:#f7fafc;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(247, 250, 252, 0))}.hover\:via-gray-200:hover{--gradient-via-color:#edf2f7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(237, 242, 247, 0))}.hover\:via-gray-300:hover{--gradient-via-color:#e2e8f0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(226, 232, 240, 0))}.hover\:via-gray-400:hover{--gradient-via-color:#cbd5e0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(203, 213, 224, 0))}.hover\:via-gray-500:hover{--gradient-via-color:#a0aec0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(160, 174, 192, 0))}.hover\:via-gray-600:hover{--gradient-via-color:#718096;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(113, 128, 150, 0))}.hover\:via-gray-700:hover{--gradient-via-color:#4a5568;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(74, 85, 104, 0))}.hover\:via-gray-800:hover{--gradient-via-color:#2d3748;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(45, 55, 72, 0))}.hover\:via-gray-900:hover{--gradient-via-color:#1a202c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(26, 32, 44, 0))}.hover\:via-red-100:hover{--gradient-via-color:#fff5f5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 245, 245, 0))}.hover\:via-red-200:hover{--gradient-via-color:#fed7d7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(254, 215, 215, 0))}.hover\:via-red-300:hover{--gradient-via-color:#feb2b2;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(254, 178, 178, 0))}.hover\:via-red-400:hover{--gradient-via-color:#fc8181;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(252, 129, 129, 0))}.hover\:via-red-500:hover{--gradient-via-color:#f56565;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(245, 101, 101, 0))}.hover\:via-red-600:hover{--gradient-via-color:#e53e3e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(229, 62, 62, 0))}.hover\:via-red-700:hover{--gradient-via-color:#c53030;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(197, 48, 48, 0))}.hover\:via-red-800:hover{--gradient-via-color:#9b2c2c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(155, 44, 44, 0))}.hover\:via-red-900:hover{--gradient-via-color:#742a2a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(116, 42, 42, 0))}.hover\:via-orange-100:hover{--gradient-via-color:#fffaf0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 250, 240, 0))}.hover\:via-orange-200:hover{--gradient-via-color:#feebc8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(254, 235, 200, 0))}.hover\:via-orange-300:hover{--gradient-via-color:#fbd38d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(251, 211, 141, 0))}.hover\:via-orange-400:hover{--gradient-via-color:#f6ad55;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(246, 173, 85, 0))}.hover\:via-orange-500:hover{--gradient-via-color:#ed8936;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(237, 137, 54, 0))}.hover\:via-orange-600:hover{--gradient-via-color:#dd6b20;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(221, 107, 32, 0))}.hover\:via-orange-700:hover{--gradient-via-color:#c05621;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(192, 86, 33, 0))}.hover\:via-orange-800:hover{--gradient-via-color:#9c4221;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(156, 66, 33, 0))}.hover\:via-orange-900:hover{--gradient-via-color:#7b341e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(123, 52, 30, 0))}.hover\:via-yellow-100:hover{--gradient-via-color:#fffff0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 255, 240, 0))}.hover\:via-yellow-200:hover{--gradient-via-color:#fefcbf;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(254, 252, 191, 0))}.hover\:via-yellow-300:hover{--gradient-via-color:#faf089;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(250, 240, 137, 0))}.hover\:via-yellow-400:hover{--gradient-via-color:#f6e05e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(246, 224, 94, 0))}.hover\:via-yellow-500:hover{--gradient-via-color:#ecc94b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(236, 201, 75, 0))}.hover\:via-yellow-600:hover{--gradient-via-color:#d69e2e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(214, 158, 46, 0))}.hover\:via-yellow-700:hover{--gradient-via-color:#b7791f;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(183, 121, 31, 0))}.hover\:via-yellow-800:hover{--gradient-via-color:#975a16;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(151, 90, 22, 0))}.hover\:via-yellow-900:hover{--gradient-via-color:#744210;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(116, 66, 16, 0))}.hover\:via-green-100:hover{--gradient-via-color:#f0fff4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(240, 255, 244, 0))}.hover\:via-green-200:hover{--gradient-via-color:#c6f6d5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(198, 246, 213, 0))}.hover\:via-green-300:hover{--gradient-via-color:#9ae6b4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(154, 230, 180, 0))}.hover\:via-green-400:hover{--gradient-via-color:#68d391;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(104, 211, 145, 0))}.hover\:via-green-500:hover{--gradient-via-color:#48bb78;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(72, 187, 120, 0))}.hover\:via-green-600:hover{--gradient-via-color:#38a169;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(56, 161, 105, 0))}.hover\:via-green-700:hover{--gradient-via-color:#2f855a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(47, 133, 90, 0))}.hover\:via-green-800:hover{--gradient-via-color:#276749;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(39, 103, 73, 0))}.hover\:via-green-900:hover{--gradient-via-color:#22543d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(34, 84, 61, 0))}.hover\:via-teal-100:hover{--gradient-via-color:#e6fffa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(230, 255, 250, 0))}.hover\:via-teal-200:hover{--gradient-via-color:#b2f5ea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(178, 245, 234, 0))}.hover\:via-teal-300:hover{--gradient-via-color:#81e6d9;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(129, 230, 217, 0))}.hover\:via-teal-400:hover{--gradient-via-color:#4fd1c5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(79, 209, 197, 0))}.hover\:via-teal-500:hover{--gradient-via-color:#38b2ac;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(56, 178, 172, 0))}.hover\:via-teal-600:hover{--gradient-via-color:#319795;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(49, 151, 149, 0))}.hover\:via-teal-700:hover{--gradient-via-color:#2c7a7b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(44, 122, 123, 0))}.hover\:via-teal-800:hover{--gradient-via-color:#285e61;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(40, 94, 97, 0))}.hover\:via-teal-900:hover{--gradient-via-color:#234e52;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(35, 78, 82, 0))}.hover\:via-blue-100:hover{--gradient-via-color:#ebf8ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(235, 248, 255, 0))}.hover\:via-blue-200:hover{--gradient-via-color:#bee3f8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(190, 227, 248, 0))}.hover\:via-blue-300:hover{--gradient-via-color:#90cdf4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(144, 205, 244, 0))}.hover\:via-blue-400:hover{--gradient-via-color:#63b3ed;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(99, 179, 237, 0))}.hover\:via-blue-500:hover{--gradient-via-color:#4299e1;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(66, 153, 225, 0))}.hover\:via-blue-600:hover{--gradient-via-color:#3182ce;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(49, 130, 206, 0))}.hover\:via-blue-700:hover{--gradient-via-color:#2b6cb0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(43, 108, 176, 0))}.hover\:via-blue-800:hover{--gradient-via-color:#2c5282;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(44, 82, 130, 0))}.hover\:via-blue-900:hover{--gradient-via-color:#2a4365;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(42, 67, 101, 0))}.hover\:via-indigo-100:hover{--gradient-via-color:#ebf4ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(235, 244, 255, 0))}.hover\:via-indigo-200:hover{--gradient-via-color:#c3dafe;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(195, 218, 254, 0))}.hover\:via-indigo-300:hover{--gradient-via-color:#a3bffa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(163, 191, 250, 0))}.hover\:via-indigo-400:hover{--gradient-via-color:#7f9cf5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(127, 156, 245, 0))}.hover\:via-indigo-500:hover{--gradient-via-color:#667eea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(102, 126, 234, 0))}.hover\:via-indigo-600:hover{--gradient-via-color:#5a67d8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(90, 103, 216, 0))}.hover\:via-indigo-700:hover{--gradient-via-color:#4c51bf;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(76, 81, 191, 0))}.hover\:via-indigo-800:hover{--gradient-via-color:#434190;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(67, 65, 144, 0))}.hover\:via-indigo-900:hover{--gradient-via-color:#3c366b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(60, 54, 107, 0))}.hover\:via-purple-100:hover{--gradient-via-color:#faf5ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(250, 245, 255, 0))}.hover\:via-purple-200:hover{--gradient-via-color:#e9d8fd;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(233, 216, 253, 0))}.hover\:via-purple-300:hover{--gradient-via-color:#d6bcfa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(214, 188, 250, 0))}.hover\:via-purple-400:hover{--gradient-via-color:#b794f4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(183, 148, 244, 0))}.hover\:via-purple-500:hover{--gradient-via-color:#9f7aea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(159, 122, 234, 0))}.hover\:via-purple-600:hover{--gradient-via-color:#805ad5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(128, 90, 213, 0))}.hover\:via-purple-700:hover{--gradient-via-color:#6b46c1;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(107, 70, 193, 0))}.hover\:via-purple-800:hover{--gradient-via-color:#553c9a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(85, 60, 154, 0))}.hover\:via-purple-900:hover{--gradient-via-color:#44337a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(68, 51, 122, 0))}.hover\:via-pink-100:hover{--gradient-via-color:#fff5f7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 245, 247, 0))}.hover\:via-pink-200:hover{--gradient-via-color:#fed7e2;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(254, 215, 226, 0))}.hover\:via-pink-300:hover{--gradient-via-color:#fbb6ce;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(251, 182, 206, 0))}.hover\:via-pink-400:hover{--gradient-via-color:#f687b3;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(246, 135, 179, 0))}.hover\:via-pink-500:hover{--gradient-via-color:#ed64a6;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(237, 100, 166, 0))}.hover\:via-pink-600:hover{--gradient-via-color:#d53f8c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(213, 63, 140, 0))}.hover\:via-pink-700:hover{--gradient-via-color:#b83280;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(184, 50, 128, 0))}.hover\:via-pink-800:hover{--gradient-via-color:#97266d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(151, 38, 109, 0))}.hover\:via-pink-900:hover{--gradient-via-color:#702459;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(112, 36, 89, 0))}.hover\:to-transparent:hover{--gradient-to-color:transparent}.hover\:to-current:hover{--gradient-to-color:currentColor}.hover\:to-black:hover{--gradient-to-color:#000}.hover\:to-white:hover{--gradient-to-color:#fff}.hover\:to-gray-100:hover{--gradient-to-color:#f7fafc}.hover\:to-gray-200:hover{--gradient-to-color:#edf2f7}.hover\:to-gray-300:hover{--gradient-to-color:#e2e8f0}.hover\:to-gray-400:hover{--gradient-to-color:#cbd5e0}.hover\:to-gray-500:hover{--gradient-to-color:#a0aec0}.hover\:to-gray-600:hover{--gradient-to-color:#718096}.hover\:to-gray-700:hover{--gradient-to-color:#4a5568}.hover\:to-gray-800:hover{--gradient-to-color:#2d3748}.hover\:to-gray-900:hover{--gradient-to-color:#1a202c}.hover\:to-red-100:hover{--gradient-to-color:#fff5f5}.hover\:to-red-200:hover{--gradient-to-color:#fed7d7}.hover\:to-red-300:hover{--gradient-to-color:#feb2b2}.hover\:to-red-400:hover{--gradient-to-color:#fc8181}.hover\:to-red-500:hover{--gradient-to-color:#f56565}.hover\:to-red-600:hover{--gradient-to-color:#e53e3e}.hover\:to-red-700:hover{--gradient-to-color:#c53030}.hover\:to-red-800:hover{--gradient-to-color:#9b2c2c}.hover\:to-red-900:hover{--gradient-to-color:#742a2a}.hover\:to-orange-100:hover{--gradient-to-color:#fffaf0}.hover\:to-orange-200:hover{--gradient-to-color:#feebc8}.hover\:to-orange-300:hover{--gradient-to-color:#fbd38d}.hover\:to-orange-400:hover{--gradient-to-color:#f6ad55}.hover\:to-orange-500:hover{--gradient-to-color:#ed8936}.hover\:to-orange-600:hover{--gradient-to-color:#dd6b20}.hover\:to-orange-700:hover{--gradient-to-color:#c05621}.hover\:to-orange-800:hover{--gradient-to-color:#9c4221}.hover\:to-orange-900:hover{--gradient-to-color:#7b341e}.hover\:to-yellow-100:hover{--gradient-to-color:#fffff0}.hover\:to-yellow-200:hover{--gradient-to-color:#fefcbf}.hover\:to-yellow-300:hover{--gradient-to-color:#faf089}.hover\:to-yellow-400:hover{--gradient-to-color:#f6e05e}.hover\:to-yellow-500:hover{--gradient-to-color:#ecc94b}.hover\:to-yellow-600:hover{--gradient-to-color:#d69e2e}.hover\:to-yellow-700:hover{--gradient-to-color:#b7791f}.hover\:to-yellow-800:hover{--gradient-to-color:#975a16}.hover\:to-yellow-900:hover{--gradient-to-color:#744210}.hover\:to-green-100:hover{--gradient-to-color:#f0fff4}.hover\:to-green-200:hover{--gradient-to-color:#c6f6d5}.hover\:to-green-300:hover{--gradient-to-color:#9ae6b4}.hover\:to-green-400:hover{--gradient-to-color:#68d391}.hover\:to-green-500:hover{--gradient-to-color:#48bb78}.hover\:to-green-600:hover{--gradient-to-color:#38a169}.hover\:to-green-700:hover{--gradient-to-color:#2f855a}.hover\:to-green-800:hover{--gradient-to-color:#276749}.hover\:to-green-900:hover{--gradient-to-color:#22543d}.hover\:to-teal-100:hover{--gradient-to-color:#e6fffa}.hover\:to-teal-200:hover{--gradient-to-color:#b2f5ea}.hover\:to-teal-300:hover{--gradient-to-color:#81e6d9}.hover\:to-teal-400:hover{--gradient-to-color:#4fd1c5}.hover\:to-teal-500:hover{--gradient-to-color:#38b2ac}.hover\:to-teal-600:hover{--gradient-to-color:#319795}.hover\:to-teal-700:hover{--gradient-to-color:#2c7a7b}.hover\:to-teal-800:hover{--gradient-to-color:#285e61}.hover\:to-teal-900:hover{--gradient-to-color:#234e52}.hover\:to-blue-100:hover{--gradient-to-color:#ebf8ff}.hover\:to-blue-200:hover{--gradient-to-color:#bee3f8}.hover\:to-blue-300:hover{--gradient-to-color:#90cdf4}.hover\:to-blue-400:hover{--gradient-to-color:#63b3ed}.hover\:to-blue-500:hover{--gradient-to-color:#4299e1}.hover\:to-blue-600:hover{--gradient-to-color:#3182ce}.hover\:to-blue-700:hover{--gradient-to-color:#2b6cb0}.hover\:to-blue-800:hover{--gradient-to-color:#2c5282}.hover\:to-blue-900:hover{--gradient-to-color:#2a4365}.hover\:to-indigo-100:hover{--gradient-to-color:#ebf4ff}.hover\:to-indigo-200:hover{--gradient-to-color:#c3dafe}.hover\:to-indigo-300:hover{--gradient-to-color:#a3bffa}.hover\:to-indigo-400:hover{--gradient-to-color:#7f9cf5}.hover\:to-indigo-500:hover{--gradient-to-color:#667eea}.hover\:to-indigo-600:hover{--gradient-to-color:#5a67d8}.hover\:to-indigo-700:hover{--gradient-to-color:#4c51bf}.hover\:to-indigo-800:hover{--gradient-to-color:#434190}.hover\:to-indigo-900:hover{--gradient-to-color:#3c366b}.hover\:to-purple-100:hover{--gradient-to-color:#faf5ff}.hover\:to-purple-200:hover{--gradient-to-color:#e9d8fd}.hover\:to-purple-300:hover{--gradient-to-color:#d6bcfa}.hover\:to-purple-400:hover{--gradient-to-color:#b794f4}.hover\:to-purple-500:hover{--gradient-to-color:#9f7aea}.hover\:to-purple-600:hover{--gradient-to-color:#805ad5}.hover\:to-purple-700:hover{--gradient-to-color:#6b46c1}.hover\:to-purple-800:hover{--gradient-to-color:#553c9a}.hover\:to-purple-900:hover{--gradient-to-color:#44337a}.hover\:to-pink-100:hover{--gradient-to-color:#fff5f7}.hover\:to-pink-200:hover{--gradient-to-color:#fed7e2}.hover\:to-pink-300:hover{--gradient-to-color:#fbb6ce}.hover\:to-pink-400:hover{--gradient-to-color:#f687b3}.hover\:to-pink-500:hover{--gradient-to-color:#ed64a6}.hover\:to-pink-600:hover{--gradient-to-color:#d53f8c}.hover\:to-pink-700:hover{--gradient-to-color:#b83280}.hover\:to-pink-800:hover{--gradient-to-color:#97266d}.hover\:to-pink-900:hover{--gradient-to-color:#702459}.focus\:from-transparent:focus{--gradient-from-color:transparent;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(0, 0, 0, 0))}.focus\:from-current:focus{--gradient-from-color:currentColor;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 255, 255, 0))}.focus\:from-black:focus{--gradient-from-color:#000;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(0, 0, 0, 0))}.focus\:from-white:focus{--gradient-from-color:#fff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 255, 255, 0))}.focus\:from-gray-100:focus{--gradient-from-color:#f7fafc;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(247, 250, 252, 0))}.focus\:from-gray-200:focus{--gradient-from-color:#edf2f7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(237, 242, 247, 0))}.focus\:from-gray-300:focus{--gradient-from-color:#e2e8f0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(226, 232, 240, 0))}.focus\:from-gray-400:focus{--gradient-from-color:#cbd5e0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(203, 213, 224, 0))}.focus\:from-gray-500:focus{--gradient-from-color:#a0aec0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(160, 174, 192, 0))}.focus\:from-gray-600:focus{--gradient-from-color:#718096;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(113, 128, 150, 0))}.focus\:from-gray-700:focus{--gradient-from-color:#4a5568;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(74, 85, 104, 0))}.focus\:from-gray-800:focus{--gradient-from-color:#2d3748;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(45, 55, 72, 0))}.focus\:from-gray-900:focus{--gradient-from-color:#1a202c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(26, 32, 44, 0))}.focus\:from-red-100:focus{--gradient-from-color:#fff5f5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 245, 245, 0))}.focus\:from-red-200:focus{--gradient-from-color:#fed7d7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(254, 215, 215, 0))}.focus\:from-red-300:focus{--gradient-from-color:#feb2b2;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(254, 178, 178, 0))}.focus\:from-red-400:focus{--gradient-from-color:#fc8181;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(252, 129, 129, 0))}.focus\:from-red-500:focus{--gradient-from-color:#f56565;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(245, 101, 101, 0))}.focus\:from-red-600:focus{--gradient-from-color:#e53e3e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(229, 62, 62, 0))}.focus\:from-red-700:focus{--gradient-from-color:#c53030;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(197, 48, 48, 0))}.focus\:from-red-800:focus{--gradient-from-color:#9b2c2c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(155, 44, 44, 0))}.focus\:from-red-900:focus{--gradient-from-color:#742a2a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(116, 42, 42, 0))}.focus\:from-orange-100:focus{--gradient-from-color:#fffaf0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 250, 240, 0))}.focus\:from-orange-200:focus{--gradient-from-color:#feebc8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(254, 235, 200, 0))}.focus\:from-orange-300:focus{--gradient-from-color:#fbd38d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(251, 211, 141, 0))}.focus\:from-orange-400:focus{--gradient-from-color:#f6ad55;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(246, 173, 85, 0))}.focus\:from-orange-500:focus{--gradient-from-color:#ed8936;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(237, 137, 54, 0))}.focus\:from-orange-600:focus{--gradient-from-color:#dd6b20;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(221, 107, 32, 0))}.focus\:from-orange-700:focus{--gradient-from-color:#c05621;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(192, 86, 33, 0))}.focus\:from-orange-800:focus{--gradient-from-color:#9c4221;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(156, 66, 33, 0))}.focus\:from-orange-900:focus{--gradient-from-color:#7b341e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(123, 52, 30, 0))}.focus\:from-yellow-100:focus{--gradient-from-color:#fffff0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 255, 240, 0))}.focus\:from-yellow-200:focus{--gradient-from-color:#fefcbf;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(254, 252, 191, 0))}.focus\:from-yellow-300:focus{--gradient-from-color:#faf089;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(250, 240, 137, 0))}.focus\:from-yellow-400:focus{--gradient-from-color:#f6e05e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(246, 224, 94, 0))}.focus\:from-yellow-500:focus{--gradient-from-color:#ecc94b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(236, 201, 75, 0))}.focus\:from-yellow-600:focus{--gradient-from-color:#d69e2e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(214, 158, 46, 0))}.focus\:from-yellow-700:focus{--gradient-from-color:#b7791f;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(183, 121, 31, 0))}.focus\:from-yellow-800:focus{--gradient-from-color:#975a16;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(151, 90, 22, 0))}.focus\:from-yellow-900:focus{--gradient-from-color:#744210;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(116, 66, 16, 0))}.focus\:from-green-100:focus{--gradient-from-color:#f0fff4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(240, 255, 244, 0))}.focus\:from-green-200:focus{--gradient-from-color:#c6f6d5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(198, 246, 213, 0))}.focus\:from-green-300:focus{--gradient-from-color:#9ae6b4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(154, 230, 180, 0))}.focus\:from-green-400:focus{--gradient-from-color:#68d391;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(104, 211, 145, 0))}.focus\:from-green-500:focus{--gradient-from-color:#48bb78;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(72, 187, 120, 0))}.focus\:from-green-600:focus{--gradient-from-color:#38a169;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(56, 161, 105, 0))}.focus\:from-green-700:focus{--gradient-from-color:#2f855a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(47, 133, 90, 0))}.focus\:from-green-800:focus{--gradient-from-color:#276749;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(39, 103, 73, 0))}.focus\:from-green-900:focus{--gradient-from-color:#22543d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(34, 84, 61, 0))}.focus\:from-teal-100:focus{--gradient-from-color:#e6fffa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(230, 255, 250, 0))}.focus\:from-teal-200:focus{--gradient-from-color:#b2f5ea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(178, 245, 234, 0))}.focus\:from-teal-300:focus{--gradient-from-color:#81e6d9;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(129, 230, 217, 0))}.focus\:from-teal-400:focus{--gradient-from-color:#4fd1c5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(79, 209, 197, 0))}.focus\:from-teal-500:focus{--gradient-from-color:#38b2ac;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(56, 178, 172, 0))}.focus\:from-teal-600:focus{--gradient-from-color:#319795;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(49, 151, 149, 0))}.focus\:from-teal-700:focus{--gradient-from-color:#2c7a7b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(44, 122, 123, 0))}.focus\:from-teal-800:focus{--gradient-from-color:#285e61;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(40, 94, 97, 0))}.focus\:from-teal-900:focus{--gradient-from-color:#234e52;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(35, 78, 82, 0))}.focus\:from-blue-100:focus{--gradient-from-color:#ebf8ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(235, 248, 255, 0))}.focus\:from-blue-200:focus{--gradient-from-color:#bee3f8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(190, 227, 248, 0))}.focus\:from-blue-300:focus{--gradient-from-color:#90cdf4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(144, 205, 244, 0))}.focus\:from-blue-400:focus{--gradient-from-color:#63b3ed;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(99, 179, 237, 0))}.focus\:from-blue-500:focus{--gradient-from-color:#4299e1;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(66, 153, 225, 0))}.focus\:from-blue-600:focus{--gradient-from-color:#3182ce;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(49, 130, 206, 0))}.focus\:from-blue-700:focus{--gradient-from-color:#2b6cb0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(43, 108, 176, 0))}.focus\:from-blue-800:focus{--gradient-from-color:#2c5282;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(44, 82, 130, 0))}.focus\:from-blue-900:focus{--gradient-from-color:#2a4365;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(42, 67, 101, 0))}.focus\:from-indigo-100:focus{--gradient-from-color:#ebf4ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(235, 244, 255, 0))}.focus\:from-indigo-200:focus{--gradient-from-color:#c3dafe;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(195, 218, 254, 0))}.focus\:from-indigo-300:focus{--gradient-from-color:#a3bffa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(163, 191, 250, 0))}.focus\:from-indigo-400:focus{--gradient-from-color:#7f9cf5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(127, 156, 245, 0))}.focus\:from-indigo-500:focus{--gradient-from-color:#667eea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(102, 126, 234, 0))}.focus\:from-indigo-600:focus{--gradient-from-color:#5a67d8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(90, 103, 216, 0))}.focus\:from-indigo-700:focus{--gradient-from-color:#4c51bf;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(76, 81, 191, 0))}.focus\:from-indigo-800:focus{--gradient-from-color:#434190;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(67, 65, 144, 0))}.focus\:from-indigo-900:focus{--gradient-from-color:#3c366b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(60, 54, 107, 0))}.focus\:from-purple-100:focus{--gradient-from-color:#faf5ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(250, 245, 255, 0))}.focus\:from-purple-200:focus{--gradient-from-color:#e9d8fd;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(233, 216, 253, 0))}.focus\:from-purple-300:focus{--gradient-from-color:#d6bcfa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(214, 188, 250, 0))}.focus\:from-purple-400:focus{--gradient-from-color:#b794f4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(183, 148, 244, 0))}.focus\:from-purple-500:focus{--gradient-from-color:#9f7aea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(159, 122, 234, 0))}.focus\:from-purple-600:focus{--gradient-from-color:#805ad5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(128, 90, 213, 0))}.focus\:from-purple-700:focus{--gradient-from-color:#6b46c1;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(107, 70, 193, 0))}.focus\:from-purple-800:focus{--gradient-from-color:#553c9a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(85, 60, 154, 0))}.focus\:from-purple-900:focus{--gradient-from-color:#44337a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(68, 51, 122, 0))}.focus\:from-pink-100:focus{--gradient-from-color:#fff5f7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 245, 247, 0))}.focus\:from-pink-200:focus{--gradient-from-color:#fed7e2;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(254, 215, 226, 0))}.focus\:from-pink-300:focus{--gradient-from-color:#fbb6ce;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(251, 182, 206, 0))}.focus\:from-pink-400:focus{--gradient-from-color:#f687b3;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(246, 135, 179, 0))}.focus\:from-pink-500:focus{--gradient-from-color:#ed64a6;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(237, 100, 166, 0))}.focus\:from-pink-600:focus{--gradient-from-color:#d53f8c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(213, 63, 140, 0))}.focus\:from-pink-700:focus{--gradient-from-color:#b83280;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(184, 50, 128, 0))}.focus\:from-pink-800:focus{--gradient-from-color:#97266d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(151, 38, 109, 0))}.focus\:from-pink-900:focus{--gradient-from-color:#702459;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(112, 36, 89, 0))}.focus\:via-transparent:focus{--gradient-via-color:transparent;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(0, 0, 0, 0))}.focus\:via-current:focus{--gradient-via-color:currentColor;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 255, 255, 0))}.focus\:via-black:focus{--gradient-via-color:#000;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(0, 0, 0, 0))}.focus\:via-white:focus{--gradient-via-color:#fff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 255, 255, 0))}.focus\:via-gray-100:focus{--gradient-via-color:#f7fafc;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(247, 250, 252, 0))}.focus\:via-gray-200:focus{--gradient-via-color:#edf2f7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(237, 242, 247, 0))}.focus\:via-gray-300:focus{--gradient-via-color:#e2e8f0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(226, 232, 240, 0))}.focus\:via-gray-400:focus{--gradient-via-color:#cbd5e0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(203, 213, 224, 0))}.focus\:via-gray-500:focus{--gradient-via-color:#a0aec0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(160, 174, 192, 0))}.focus\:via-gray-600:focus{--gradient-via-color:#718096;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(113, 128, 150, 0))}.focus\:via-gray-700:focus{--gradient-via-color:#4a5568;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(74, 85, 104, 0))}.focus\:via-gray-800:focus{--gradient-via-color:#2d3748;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(45, 55, 72, 0))}.focus\:via-gray-900:focus{--gradient-via-color:#1a202c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(26, 32, 44, 0))}.focus\:via-red-100:focus{--gradient-via-color:#fff5f5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 245, 245, 0))}.focus\:via-red-200:focus{--gradient-via-color:#fed7d7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(254, 215, 215, 0))}.focus\:via-red-300:focus{--gradient-via-color:#feb2b2;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(254, 178, 178, 0))}.focus\:via-red-400:focus{--gradient-via-color:#fc8181;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(252, 129, 129, 0))}.focus\:via-red-500:focus{--gradient-via-color:#f56565;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(245, 101, 101, 0))}.focus\:via-red-600:focus{--gradient-via-color:#e53e3e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(229, 62, 62, 0))}.focus\:via-red-700:focus{--gradient-via-color:#c53030;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(197, 48, 48, 0))}.focus\:via-red-800:focus{--gradient-via-color:#9b2c2c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(155, 44, 44, 0))}.focus\:via-red-900:focus{--gradient-via-color:#742a2a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(116, 42, 42, 0))}.focus\:via-orange-100:focus{--gradient-via-color:#fffaf0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 250, 240, 0))}.focus\:via-orange-200:focus{--gradient-via-color:#feebc8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(254, 235, 200, 0))}.focus\:via-orange-300:focus{--gradient-via-color:#fbd38d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(251, 211, 141, 0))}.focus\:via-orange-400:focus{--gradient-via-color:#f6ad55;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(246, 173, 85, 0))}.focus\:via-orange-500:focus{--gradient-via-color:#ed8936;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(237, 137, 54, 0))}.focus\:via-orange-600:focus{--gradient-via-color:#dd6b20;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(221, 107, 32, 0))}.focus\:via-orange-700:focus{--gradient-via-color:#c05621;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(192, 86, 33, 0))}.focus\:via-orange-800:focus{--gradient-via-color:#9c4221;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(156, 66, 33, 0))}.focus\:via-orange-900:focus{--gradient-via-color:#7b341e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(123, 52, 30, 0))}.focus\:via-yellow-100:focus{--gradient-via-color:#fffff0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 255, 240, 0))}.focus\:via-yellow-200:focus{--gradient-via-color:#fefcbf;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(254, 252, 191, 0))}.focus\:via-yellow-300:focus{--gradient-via-color:#faf089;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(250, 240, 137, 0))}.focus\:via-yellow-400:focus{--gradient-via-color:#f6e05e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(246, 224, 94, 0))}.focus\:via-yellow-500:focus{--gradient-via-color:#ecc94b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(236, 201, 75, 0))}.focus\:via-yellow-600:focus{--gradient-via-color:#d69e2e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(214, 158, 46, 0))}.focus\:via-yellow-700:focus{--gradient-via-color:#b7791f;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(183, 121, 31, 0))}.focus\:via-yellow-800:focus{--gradient-via-color:#975a16;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(151, 90, 22, 0))}.focus\:via-yellow-900:focus{--gradient-via-color:#744210;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(116, 66, 16, 0))}.focus\:via-green-100:focus{--gradient-via-color:#f0fff4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(240, 255, 244, 0))}.focus\:via-green-200:focus{--gradient-via-color:#c6f6d5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(198, 246, 213, 0))}.focus\:via-green-300:focus{--gradient-via-color:#9ae6b4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(154, 230, 180, 0))}.focus\:via-green-400:focus{--gradient-via-color:#68d391;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(104, 211, 145, 0))}.focus\:via-green-500:focus{--gradient-via-color:#48bb78;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(72, 187, 120, 0))}.focus\:via-green-600:focus{--gradient-via-color:#38a169;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(56, 161, 105, 0))}.focus\:via-green-700:focus{--gradient-via-color:#2f855a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(47, 133, 90, 0))}.focus\:via-green-800:focus{--gradient-via-color:#276749;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(39, 103, 73, 0))}.focus\:via-green-900:focus{--gradient-via-color:#22543d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(34, 84, 61, 0))}.focus\:via-teal-100:focus{--gradient-via-color:#e6fffa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(230, 255, 250, 0))}.focus\:via-teal-200:focus{--gradient-via-color:#b2f5ea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(178, 245, 234, 0))}.focus\:via-teal-300:focus{--gradient-via-color:#81e6d9;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(129, 230, 217, 0))}.focus\:via-teal-400:focus{--gradient-via-color:#4fd1c5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(79, 209, 197, 0))}.focus\:via-teal-500:focus{--gradient-via-color:#38b2ac;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(56, 178, 172, 0))}.focus\:via-teal-600:focus{--gradient-via-color:#319795;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(49, 151, 149, 0))}.focus\:via-teal-700:focus{--gradient-via-color:#2c7a7b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(44, 122, 123, 0))}.focus\:via-teal-800:focus{--gradient-via-color:#285e61;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(40, 94, 97, 0))}.focus\:via-teal-900:focus{--gradient-via-color:#234e52;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(35, 78, 82, 0))}.focus\:via-blue-100:focus{--gradient-via-color:#ebf8ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(235, 248, 255, 0))}.focus\:via-blue-200:focus{--gradient-via-color:#bee3f8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(190, 227, 248, 0))}.focus\:via-blue-300:focus{--gradient-via-color:#90cdf4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(144, 205, 244, 0))}.focus\:via-blue-400:focus{--gradient-via-color:#63b3ed;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(99, 179, 237, 0))}.focus\:via-blue-500:focus{--gradient-via-color:#4299e1;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(66, 153, 225, 0))}.focus\:via-blue-600:focus{--gradient-via-color:#3182ce;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(49, 130, 206, 0))}.focus\:via-blue-700:focus{--gradient-via-color:#2b6cb0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(43, 108, 176, 0))}.focus\:via-blue-800:focus{--gradient-via-color:#2c5282;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(44, 82, 130, 0))}.focus\:via-blue-900:focus{--gradient-via-color:#2a4365;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(42, 67, 101, 0))}.focus\:via-indigo-100:focus{--gradient-via-color:#ebf4ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(235, 244, 255, 0))}.focus\:via-indigo-200:focus{--gradient-via-color:#c3dafe;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(195, 218, 254, 0))}.focus\:via-indigo-300:focus{--gradient-via-color:#a3bffa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(163, 191, 250, 0))}.focus\:via-indigo-400:focus{--gradient-via-color:#7f9cf5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(127, 156, 245, 0))}.focus\:via-indigo-500:focus{--gradient-via-color:#667eea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(102, 126, 234, 0))}.focus\:via-indigo-600:focus{--gradient-via-color:#5a67d8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(90, 103, 216, 0))}.focus\:via-indigo-700:focus{--gradient-via-color:#4c51bf;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(76, 81, 191, 0))}.focus\:via-indigo-800:focus{--gradient-via-color:#434190;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(67, 65, 144, 0))}.focus\:via-indigo-900:focus{--gradient-via-color:#3c366b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(60, 54, 107, 0))}.focus\:via-purple-100:focus{--gradient-via-color:#faf5ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(250, 245, 255, 0))}.focus\:via-purple-200:focus{--gradient-via-color:#e9d8fd;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(233, 216, 253, 0))}.focus\:via-purple-300:focus{--gradient-via-color:#d6bcfa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(214, 188, 250, 0))}.focus\:via-purple-400:focus{--gradient-via-color:#b794f4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(183, 148, 244, 0))}.focus\:via-purple-500:focus{--gradient-via-color:#9f7aea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(159, 122, 234, 0))}.focus\:via-purple-600:focus{--gradient-via-color:#805ad5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(128, 90, 213, 0))}.focus\:via-purple-700:focus{--gradient-via-color:#6b46c1;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(107, 70, 193, 0))}.focus\:via-purple-800:focus{--gradient-via-color:#553c9a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(85, 60, 154, 0))}.focus\:via-purple-900:focus{--gradient-via-color:#44337a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(68, 51, 122, 0))}.focus\:via-pink-100:focus{--gradient-via-color:#fff5f7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 245, 247, 0))}.focus\:via-pink-200:focus{--gradient-via-color:#fed7e2;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(254, 215, 226, 0))}.focus\:via-pink-300:focus{--gradient-via-color:#fbb6ce;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(251, 182, 206, 0))}.focus\:via-pink-400:focus{--gradient-via-color:#f687b3;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(246, 135, 179, 0))}.focus\:via-pink-500:focus{--gradient-via-color:#ed64a6;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(237, 100, 166, 0))}.focus\:via-pink-600:focus{--gradient-via-color:#d53f8c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(213, 63, 140, 0))}.focus\:via-pink-700:focus{--gradient-via-color:#b83280;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(184, 50, 128, 0))}.focus\:via-pink-800:focus{--gradient-via-color:#97266d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(151, 38, 109, 0))}.focus\:via-pink-900:focus{--gradient-via-color:#702459;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(112, 36, 89, 0))}.focus\:to-transparent:focus{--gradient-to-color:transparent}.focus\:to-current:focus{--gradient-to-color:currentColor}.focus\:to-black:focus{--gradient-to-color:#000}.focus\:to-white:focus{--gradient-to-color:#fff}.focus\:to-gray-100:focus{--gradient-to-color:#f7fafc}.focus\:to-gray-200:focus{--gradient-to-color:#edf2f7}.focus\:to-gray-300:focus{--gradient-to-color:#e2e8f0}.focus\:to-gray-400:focus{--gradient-to-color:#cbd5e0}.focus\:to-gray-500:focus{--gradient-to-color:#a0aec0}.focus\:to-gray-600:focus{--gradient-to-color:#718096}.focus\:to-gray-700:focus{--gradient-to-color:#4a5568}.focus\:to-gray-800:focus{--gradient-to-color:#2d3748}.focus\:to-gray-900:focus{--gradient-to-color:#1a202c}.focus\:to-red-100:focus{--gradient-to-color:#fff5f5}.focus\:to-red-200:focus{--gradient-to-color:#fed7d7}.focus\:to-red-300:focus{--gradient-to-color:#feb2b2}.focus\:to-red-400:focus{--gradient-to-color:#fc8181}.focus\:to-red-500:focus{--gradient-to-color:#f56565}.focus\:to-red-600:focus{--gradient-to-color:#e53e3e}.focus\:to-red-700:focus{--gradient-to-color:#c53030}.focus\:to-red-800:focus{--gradient-to-color:#9b2c2c}.focus\:to-red-900:focus{--gradient-to-color:#742a2a}.focus\:to-orange-100:focus{--gradient-to-color:#fffaf0}.focus\:to-orange-200:focus{--gradient-to-color:#feebc8}.focus\:to-orange-300:focus{--gradient-to-color:#fbd38d}.focus\:to-orange-400:focus{--gradient-to-color:#f6ad55}.focus\:to-orange-500:focus{--gradient-to-color:#ed8936}.focus\:to-orange-600:focus{--gradient-to-color:#dd6b20}.focus\:to-orange-700:focus{--gradient-to-color:#c05621}.focus\:to-orange-800:focus{--gradient-to-color:#9c4221}.focus\:to-orange-900:focus{--gradient-to-color:#7b341e}.focus\:to-yellow-100:focus{--gradient-to-color:#fffff0}.focus\:to-yellow-200:focus{--gradient-to-color:#fefcbf}.focus\:to-yellow-300:focus{--gradient-to-color:#faf089}.focus\:to-yellow-400:focus{--gradient-to-color:#f6e05e}.focus\:to-yellow-500:focus{--gradient-to-color:#ecc94b}.focus\:to-yellow-600:focus{--gradient-to-color:#d69e2e}.focus\:to-yellow-700:focus{--gradient-to-color:#b7791f}.focus\:to-yellow-800:focus{--gradient-to-color:#975a16}.focus\:to-yellow-900:focus{--gradient-to-color:#744210}.focus\:to-green-100:focus{--gradient-to-color:#f0fff4}.focus\:to-green-200:focus{--gradient-to-color:#c6f6d5}.focus\:to-green-300:focus{--gradient-to-color:#9ae6b4}.focus\:to-green-400:focus{--gradient-to-color:#68d391}.focus\:to-green-500:focus{--gradient-to-color:#48bb78}.focus\:to-green-600:focus{--gradient-to-color:#38a169}.focus\:to-green-700:focus{--gradient-to-color:#2f855a}.focus\:to-green-800:focus{--gradient-to-color:#276749}.focus\:to-green-900:focus{--gradient-to-color:#22543d}.focus\:to-teal-100:focus{--gradient-to-color:#e6fffa}.focus\:to-teal-200:focus{--gradient-to-color:#b2f5ea}.focus\:to-teal-300:focus{--gradient-to-color:#81e6d9}.focus\:to-teal-400:focus{--gradient-to-color:#4fd1c5}.focus\:to-teal-500:focus{--gradient-to-color:#38b2ac}.focus\:to-teal-600:focus{--gradient-to-color:#319795}.focus\:to-teal-700:focus{--gradient-to-color:#2c7a7b}.focus\:to-teal-800:focus{--gradient-to-color:#285e61}.focus\:to-teal-900:focus{--gradient-to-color:#234e52}.focus\:to-blue-100:focus{--gradient-to-color:#ebf8ff}.focus\:to-blue-200:focus{--gradient-to-color:#bee3f8}.focus\:to-blue-300:focus{--gradient-to-color:#90cdf4}.focus\:to-blue-400:focus{--gradient-to-color:#63b3ed}.focus\:to-blue-500:focus{--gradient-to-color:#4299e1}.focus\:to-blue-600:focus{--gradient-to-color:#3182ce}.focus\:to-blue-700:focus{--gradient-to-color:#2b6cb0}.focus\:to-blue-800:focus{--gradient-to-color:#2c5282}.focus\:to-blue-900:focus{--gradient-to-color:#2a4365}.focus\:to-indigo-100:focus{--gradient-to-color:#ebf4ff}.focus\:to-indigo-200:focus{--gradient-to-color:#c3dafe}.focus\:to-indigo-300:focus{--gradient-to-color:#a3bffa}.focus\:to-indigo-400:focus{--gradient-to-color:#7f9cf5}.focus\:to-indigo-500:focus{--gradient-to-color:#667eea}.focus\:to-indigo-600:focus{--gradient-to-color:#5a67d8}.focus\:to-indigo-700:focus{--gradient-to-color:#4c51bf}.focus\:to-indigo-800:focus{--gradient-to-color:#434190}.focus\:to-indigo-900:focus{--gradient-to-color:#3c366b}.focus\:to-purple-100:focus{--gradient-to-color:#faf5ff}.focus\:to-purple-200:focus{--gradient-to-color:#e9d8fd}.focus\:to-purple-300:focus{--gradient-to-color:#d6bcfa}.focus\:to-purple-400:focus{--gradient-to-color:#b794f4}.focus\:to-purple-500:focus{--gradient-to-color:#9f7aea}.focus\:to-purple-600:focus{--gradient-to-color:#805ad5}.focus\:to-purple-700:focus{--gradient-to-color:#6b46c1}.focus\:to-purple-800:focus{--gradient-to-color:#553c9a}.focus\:to-purple-900:focus{--gradient-to-color:#44337a}.focus\:to-pink-100:focus{--gradient-to-color:#fff5f7}.focus\:to-pink-200:focus{--gradient-to-color:#fed7e2}.focus\:to-pink-300:focus{--gradient-to-color:#fbb6ce}.focus\:to-pink-400:focus{--gradient-to-color:#f687b3}.focus\:to-pink-500:focus{--gradient-to-color:#ed64a6}.focus\:to-pink-600:focus{--gradient-to-color:#d53f8c}.focus\:to-pink-700:focus{--gradient-to-color:#b83280}.focus\:to-pink-800:focus{--gradient-to-color:#97266d}.focus\:to-pink-900:focus{--gradient-to-color:#702459}.bg-opacity-0{--bg-opacity:0}.bg-opacity-25{--bg-opacity:0.25}.bg-opacity-50{--bg-opacity:0.5}.bg-opacity-75{--bg-opacity:0.75}.bg-opacity-100{--bg-opacity:1}.hover\:bg-opacity-0:hover{--bg-opacity:0}.hover\:bg-opacity-25:hover{--bg-opacity:0.25}.hover\:bg-opacity-50:hover{--bg-opacity:0.5}.hover\:bg-opacity-75:hover{--bg-opacity:0.75}.hover\:bg-opacity-100:hover{--bg-opacity:1}.focus\:bg-opacity-0:focus{--bg-opacity:0}.focus\:bg-opacity-25:focus{--bg-opacity:0.25}.focus\:bg-opacity-50:focus{--bg-opacity:0.5}.focus\:bg-opacity-75:focus{--bg-opacity:0.75}.focus\:bg-opacity-100:focus{--bg-opacity:1}.bg-bottom{background-position:bottom}.bg-center{background-position:center}.bg-left{background-position:left}.bg-left-bottom{background-position:left bottom}.bg-left-top{background-position:left top}.bg-right{background-position:right}.bg-right-bottom{background-position:right bottom}.bg-right-top{background-position:right top}.bg-top{background-position:top}.bg-repeat{background-repeat:repeat}.bg-no-repeat{background-repeat:no-repeat}.bg-repeat-x{background-repeat:repeat-x}.bg-repeat-y{background-repeat:repeat-y}.bg-repeat-round{background-repeat:round}.bg-repeat-space{background-repeat:space}.bg-auto{background-size:auto}.bg-cover{background-size:cover}.bg-contain{background-size:contain}.border-collapse{border-collapse:collapse}.border-separate{border-collapse:separate}.border-transparent{border-color:transparent}.border-current{border-color:currentColor}.border-black{--border-opacity:1;border-color:#000;border-color:rgba(0,0,0,var(--border-opacity))}.border-white{--border-opacity:1;border-color:#fff;border-color:rgba(255,255,255,var(--border-opacity))}.border-gray-100{--border-opacity:1;border-color:#f7fafc;border-color:rgba(247,250,252,var(--border-opacity))}.border-gray-200{--border-opacity:1;border-color:#edf2f7;border-color:rgba(237,242,247,var(--border-opacity))}.border-gray-300{--border-opacity:1;border-color:#e2e8f0;border-color:rgba(226,232,240,var(--border-opacity))}.border-gray-400{--border-opacity:1;border-color:#cbd5e0;border-color:rgba(203,213,224,var(--border-opacity))}.border-gray-500{--border-opacity:1;border-color:#a0aec0;border-color:rgba(160,174,192,var(--border-opacity))}.border-gray-600{--border-opacity:1;border-color:#718096;border-color:rgba(113,128,150,var(--border-opacity))}.border-gray-700{--border-opacity:1;border-color:#4a5568;border-color:rgba(74,85,104,var(--border-opacity))}.border-gray-800{--border-opacity:1;border-color:#2d3748;border-color:rgba(45,55,72,var(--border-opacity))}.border-gray-900{--border-opacity:1;border-color:#1a202c;border-color:rgba(26,32,44,var(--border-opacity))}.border-red-100{--border-opacity:1;border-color:#fff5f5;border-color:rgba(255,245,245,var(--border-opacity))}.border-red-200{--border-opacity:1;border-color:#fed7d7;border-color:rgba(254,215,215,var(--border-opacity))}.border-red-300{--border-opacity:1;border-color:#feb2b2;border-color:rgba(254,178,178,var(--border-opacity))}.border-red-400{--border-opacity:1;border-color:#fc8181;border-color:rgba(252,129,129,var(--border-opacity))}.border-red-500{--border-opacity:1;border-color:#f56565;border-color:rgba(245,101,101,var(--border-opacity))}.border-red-600{--border-opacity:1;border-color:#e53e3e;border-color:rgba(229,62,62,var(--border-opacity))}.border-red-700{--border-opacity:1;border-color:#c53030;border-color:rgba(197,48,48,var(--border-opacity))}.border-red-800{--border-opacity:1;border-color:#9b2c2c;border-color:rgba(155,44,44,var(--border-opacity))}.border-red-900{--border-opacity:1;border-color:#742a2a;border-color:rgba(116,42,42,var(--border-opacity))}.border-orange-100{--border-opacity:1;border-color:#fffaf0;border-color:rgba(255,250,240,var(--border-opacity))}.border-orange-200{--border-opacity:1;border-color:#feebc8;border-color:rgba(254,235,200,var(--border-opacity))}.border-orange-300{--border-opacity:1;border-color:#fbd38d;border-color:rgba(251,211,141,var(--border-opacity))}.border-orange-400{--border-opacity:1;border-color:#f6ad55;border-color:rgba(246,173,85,var(--border-opacity))}.border-orange-500{--border-opacity:1;border-color:#ed8936;border-color:rgba(237,137,54,var(--border-opacity))}.border-orange-600{--border-opacity:1;border-color:#dd6b20;border-color:rgba(221,107,32,var(--border-opacity))}.border-orange-700{--border-opacity:1;border-color:#c05621;border-color:rgba(192,86,33,var(--border-opacity))}.border-orange-800{--border-opacity:1;border-color:#9c4221;border-color:rgba(156,66,33,var(--border-opacity))}.border-orange-900{--border-opacity:1;border-color:#7b341e;border-color:rgba(123,52,30,var(--border-opacity))}.border-yellow-100{--border-opacity:1;border-color:ivory;border-color:rgba(255,255,240,var(--border-opacity))}.border-yellow-200{--border-opacity:1;border-color:#fefcbf;border-color:rgba(254,252,191,var(--border-opacity))}.border-yellow-300{--border-opacity:1;border-color:#faf089;border-color:rgba(250,240,137,var(--border-opacity))}.border-yellow-400{--border-opacity:1;border-color:#f6e05e;border-color:rgba(246,224,94,var(--border-opacity))}.border-yellow-500{--border-opacity:1;border-color:#ecc94b;border-color:rgba(236,201,75,var(--border-opacity))}.border-yellow-600{--border-opacity:1;border-color:#d69e2e;border-color:rgba(214,158,46,var(--border-opacity))}.border-yellow-700{--border-opacity:1;border-color:#b7791f;border-color:rgba(183,121,31,var(--border-opacity))}.border-yellow-800{--border-opacity:1;border-color:#975a16;border-color:rgba(151,90,22,var(--border-opacity))}.border-yellow-900{--border-opacity:1;border-color:#744210;border-color:rgba(116,66,16,var(--border-opacity))}.border-green-100{--border-opacity:1;border-color:#f0fff4;border-color:rgba(240,255,244,var(--border-opacity))}.border-green-200{--border-opacity:1;border-color:#c6f6d5;border-color:rgba(198,246,213,var(--border-opacity))}.border-green-300{--border-opacity:1;border-color:#9ae6b4;border-color:rgba(154,230,180,var(--border-opacity))}.border-green-400{--border-opacity:1;border-color:#68d391;border-color:rgba(104,211,145,var(--border-opacity))}.border-green-500{--border-opacity:1;border-color:#48bb78;border-color:rgba(72,187,120,var(--border-opacity))}.border-green-600{--border-opacity:1;border-color:#38a169;border-color:rgba(56,161,105,var(--border-opacity))}.border-green-700{--border-opacity:1;border-color:#2f855a;border-color:rgba(47,133,90,var(--border-opacity))}.border-green-800{--border-opacity:1;border-color:#276749;border-color:rgba(39,103,73,var(--border-opacity))}.border-green-900{--border-opacity:1;border-color:#22543d;border-color:rgba(34,84,61,var(--border-opacity))}.border-teal-100{--border-opacity:1;border-color:#e6fffa;border-color:rgba(230,255,250,var(--border-opacity))}.border-teal-200{--border-opacity:1;border-color:#b2f5ea;border-color:rgba(178,245,234,var(--border-opacity))}.border-teal-300{--border-opacity:1;border-color:#81e6d9;border-color:rgba(129,230,217,var(--border-opacity))}.border-teal-400{--border-opacity:1;border-color:#4fd1c5;border-color:rgba(79,209,197,var(--border-opacity))}.border-teal-500{--border-opacity:1;border-color:#38b2ac;border-color:rgba(56,178,172,var(--border-opacity))}.border-teal-600{--border-opacity:1;border-color:#319795;border-color:rgba(49,151,149,var(--border-opacity))}.border-teal-700{--border-opacity:1;border-color:#2c7a7b;border-color:rgba(44,122,123,var(--border-opacity))}.border-teal-800{--border-opacity:1;border-color:#285e61;border-color:rgba(40,94,97,var(--border-opacity))}.border-teal-900{--border-opacity:1;border-color:#234e52;border-color:rgba(35,78,82,var(--border-opacity))}.border-blue-100{--border-opacity:1;border-color:#ebf8ff;border-color:rgba(235,248,255,var(--border-opacity))}.border-blue-200{--border-opacity:1;border-color:#bee3f8;border-color:rgba(190,227,248,var(--border-opacity))}.border-blue-300{--border-opacity:1;border-color:#90cdf4;border-color:rgba(144,205,244,var(--border-opacity))}.border-blue-400{--border-opacity:1;border-color:#63b3ed;border-color:rgba(99,179,237,var(--border-opacity))}.border-blue-500{--border-opacity:1;border-color:#4299e1;border-color:rgba(66,153,225,var(--border-opacity))}.border-blue-600{--border-opacity:1;border-color:#3182ce;border-color:rgba(49,130,206,var(--border-opacity))}.border-blue-700{--border-opacity:1;border-color:#2b6cb0;border-color:rgba(43,108,176,var(--border-opacity))}.border-blue-800{--border-opacity:1;border-color:#2c5282;border-color:rgba(44,82,130,var(--border-opacity))}.border-blue-900{--border-opacity:1;border-color:#2a4365;border-color:rgba(42,67,101,var(--border-opacity))}.border-indigo-100{--border-opacity:1;border-color:#ebf4ff;border-color:rgba(235,244,255,var(--border-opacity))}.border-indigo-200{--border-opacity:1;border-color:#c3dafe;border-color:rgba(195,218,254,var(--border-opacity))}.border-indigo-300{--border-opacity:1;border-color:#a3bffa;border-color:rgba(163,191,250,var(--border-opacity))}.border-indigo-400{--border-opacity:1;border-color:#7f9cf5;border-color:rgba(127,156,245,var(--border-opacity))}.border-indigo-500{--border-opacity:1;border-color:#667eea;border-color:rgba(102,126,234,var(--border-opacity))}.border-indigo-600{--border-opacity:1;border-color:#5a67d8;border-color:rgba(90,103,216,var(--border-opacity))}.border-indigo-700{--border-opacity:1;border-color:#4c51bf;border-color:rgba(76,81,191,var(--border-opacity))}.border-indigo-800{--border-opacity:1;border-color:#434190;border-color:rgba(67,65,144,var(--border-opacity))}.border-indigo-900{--border-opacity:1;border-color:#3c366b;border-color:rgba(60,54,107,var(--border-opacity))}.border-purple-100{--border-opacity:1;border-color:#faf5ff;border-color:rgba(250,245,255,var(--border-opacity))}.border-purple-200{--border-opacity:1;border-color:#e9d8fd;border-color:rgba(233,216,253,var(--border-opacity))}.border-purple-300{--border-opacity:1;border-color:#d6bcfa;border-color:rgba(214,188,250,var(--border-opacity))}.border-purple-400{--border-opacity:1;border-color:#b794f4;border-color:rgba(183,148,244,var(--border-opacity))}.border-purple-500{--border-opacity:1;border-color:#9f7aea;border-color:rgba(159,122,234,var(--border-opacity))}.border-purple-600{--border-opacity:1;border-color:#805ad5;border-color:rgba(128,90,213,var(--border-opacity))}.border-purple-700{--border-opacity:1;border-color:#6b46c1;border-color:rgba(107,70,193,var(--border-opacity))}.border-purple-800{--border-opacity:1;border-color:#553c9a;border-color:rgba(85,60,154,var(--border-opacity))}.border-purple-900{--border-opacity:1;border-color:#44337a;border-color:rgba(68,51,122,var(--border-opacity))}.border-pink-100{--border-opacity:1;border-color:#fff5f7;border-color:rgba(255,245,247,var(--border-opacity))}.border-pink-200{--border-opacity:1;border-color:#fed7e2;border-color:rgba(254,215,226,var(--border-opacity))}.border-pink-300{--border-opacity:1;border-color:#fbb6ce;border-color:rgba(251,182,206,var(--border-opacity))}.border-pink-400{--border-opacity:1;border-color:#f687b3;border-color:rgba(246,135,179,var(--border-opacity))}.border-pink-500{--border-opacity:1;border-color:#ed64a6;border-color:rgba(237,100,166,var(--border-opacity))}.border-pink-600{--border-opacity:1;border-color:#d53f8c;border-color:rgba(213,63,140,var(--border-opacity))}.border-pink-700{--border-opacity:1;border-color:#b83280;border-color:rgba(184,50,128,var(--border-opacity))}.border-pink-800{--border-opacity:1;border-color:#97266d;border-color:rgba(151,38,109,var(--border-opacity))}.border-pink-900{--border-opacity:1;border-color:#702459;border-color:rgba(112,36,89,var(--border-opacity))}.hover\:border-transparent:hover{border-color:transparent}.hover\:border-current:hover{border-color:currentColor}.hover\:border-black:hover{--border-opacity:1;border-color:#000;border-color:rgba(0,0,0,var(--border-opacity))}.hover\:border-white:hover{--border-opacity:1;border-color:#fff;border-color:rgba(255,255,255,var(--border-opacity))}.hover\:border-gray-100:hover{--border-opacity:1;border-color:#f7fafc;border-color:rgba(247,250,252,var(--border-opacity))}.hover\:border-gray-200:hover{--border-opacity:1;border-color:#edf2f7;border-color:rgba(237,242,247,var(--border-opacity))}.hover\:border-gray-300:hover{--border-opacity:1;border-color:#e2e8f0;border-color:rgba(226,232,240,var(--border-opacity))}.hover\:border-gray-400:hover{--border-opacity:1;border-color:#cbd5e0;border-color:rgba(203,213,224,var(--border-opacity))}.hover\:border-gray-500:hover{--border-opacity:1;border-color:#a0aec0;border-color:rgba(160,174,192,var(--border-opacity))}.hover\:border-gray-600:hover{--border-opacity:1;border-color:#718096;border-color:rgba(113,128,150,var(--border-opacity))}.hover\:border-gray-700:hover{--border-opacity:1;border-color:#4a5568;border-color:rgba(74,85,104,var(--border-opacity))}.hover\:border-gray-800:hover{--border-opacity:1;border-color:#2d3748;border-color:rgba(45,55,72,var(--border-opacity))}.hover\:border-gray-900:hover{--border-opacity:1;border-color:#1a202c;border-color:rgba(26,32,44,var(--border-opacity))}.hover\:border-red-100:hover{--border-opacity:1;border-color:#fff5f5;border-color:rgba(255,245,245,var(--border-opacity))}.hover\:border-red-200:hover{--border-opacity:1;border-color:#fed7d7;border-color:rgba(254,215,215,var(--border-opacity))}.hover\:border-red-300:hover{--border-opacity:1;border-color:#feb2b2;border-color:rgba(254,178,178,var(--border-opacity))}.hover\:border-red-400:hover{--border-opacity:1;border-color:#fc8181;border-color:rgba(252,129,129,var(--border-opacity))}.hover\:border-red-500:hover{--border-opacity:1;border-color:#f56565;border-color:rgba(245,101,101,var(--border-opacity))}.hover\:border-red-600:hover{--border-opacity:1;border-color:#e53e3e;border-color:rgba(229,62,62,var(--border-opacity))}.hover\:border-red-700:hover{--border-opacity:1;border-color:#c53030;border-color:rgba(197,48,48,var(--border-opacity))}.hover\:border-red-800:hover{--border-opacity:1;border-color:#9b2c2c;border-color:rgba(155,44,44,var(--border-opacity))}.hover\:border-red-900:hover{--border-opacity:1;border-color:#742a2a;border-color:rgba(116,42,42,var(--border-opacity))}.hover\:border-orange-100:hover{--border-opacity:1;border-color:#fffaf0;border-color:rgba(255,250,240,var(--border-opacity))}.hover\:border-orange-200:hover{--border-opacity:1;border-color:#feebc8;border-color:rgba(254,235,200,var(--border-opacity))}.hover\:border-orange-300:hover{--border-opacity:1;border-color:#fbd38d;border-color:rgba(251,211,141,var(--border-opacity))}.hover\:border-orange-400:hover{--border-opacity:1;border-color:#f6ad55;border-color:rgba(246,173,85,var(--border-opacity))}.hover\:border-orange-500:hover{--border-opacity:1;border-color:#ed8936;border-color:rgba(237,137,54,var(--border-opacity))}.hover\:border-orange-600:hover{--border-opacity:1;border-color:#dd6b20;border-color:rgba(221,107,32,var(--border-opacity))}.hover\:border-orange-700:hover{--border-opacity:1;border-color:#c05621;border-color:rgba(192,86,33,var(--border-opacity))}.hover\:border-orange-800:hover{--border-opacity:1;border-color:#9c4221;border-color:rgba(156,66,33,var(--border-opacity))}.hover\:border-orange-900:hover{--border-opacity:1;border-color:#7b341e;border-color:rgba(123,52,30,var(--border-opacity))}.hover\:border-yellow-100:hover{--border-opacity:1;border-color:ivory;border-color:rgba(255,255,240,var(--border-opacity))}.hover\:border-yellow-200:hover{--border-opacity:1;border-color:#fefcbf;border-color:rgba(254,252,191,var(--border-opacity))}.hover\:border-yellow-300:hover{--border-opacity:1;border-color:#faf089;border-color:rgba(250,240,137,var(--border-opacity))}.hover\:border-yellow-400:hover{--border-opacity:1;border-color:#f6e05e;border-color:rgba(246,224,94,var(--border-opacity))}.hover\:border-yellow-500:hover{--border-opacity:1;border-color:#ecc94b;border-color:rgba(236,201,75,var(--border-opacity))}.hover\:border-yellow-600:hover{--border-opacity:1;border-color:#d69e2e;border-color:rgba(214,158,46,var(--border-opacity))}.hover\:border-yellow-700:hover{--border-opacity:1;border-color:#b7791f;border-color:rgba(183,121,31,var(--border-opacity))}.hover\:border-yellow-800:hover{--border-opacity:1;border-color:#975a16;border-color:rgba(151,90,22,var(--border-opacity))}.hover\:border-yellow-900:hover{--border-opacity:1;border-color:#744210;border-color:rgba(116,66,16,var(--border-opacity))}.hover\:border-green-100:hover{--border-opacity:1;border-color:#f0fff4;border-color:rgba(240,255,244,var(--border-opacity))}.hover\:border-green-200:hover{--border-opacity:1;border-color:#c6f6d5;border-color:rgba(198,246,213,var(--border-opacity))}.hover\:border-green-300:hover{--border-opacity:1;border-color:#9ae6b4;border-color:rgba(154,230,180,var(--border-opacity))}.hover\:border-green-400:hover{--border-opacity:1;border-color:#68d391;border-color:rgba(104,211,145,var(--border-opacity))}.hover\:border-green-500:hover{--border-opacity:1;border-color:#48bb78;border-color:rgba(72,187,120,var(--border-opacity))}.hover\:border-green-600:hover{--border-opacity:1;border-color:#38a169;border-color:rgba(56,161,105,var(--border-opacity))}.hover\:border-green-700:hover{--border-opacity:1;border-color:#2f855a;border-color:rgba(47,133,90,var(--border-opacity))}.hover\:border-green-800:hover{--border-opacity:1;border-color:#276749;border-color:rgba(39,103,73,var(--border-opacity))}.hover\:border-green-900:hover{--border-opacity:1;border-color:#22543d;border-color:rgba(34,84,61,var(--border-opacity))}.hover\:border-teal-100:hover{--border-opacity:1;border-color:#e6fffa;border-color:rgba(230,255,250,var(--border-opacity))}.hover\:border-teal-200:hover{--border-opacity:1;border-color:#b2f5ea;border-color:rgba(178,245,234,var(--border-opacity))}.hover\:border-teal-300:hover{--border-opacity:1;border-color:#81e6d9;border-color:rgba(129,230,217,var(--border-opacity))}.hover\:border-teal-400:hover{--border-opacity:1;border-color:#4fd1c5;border-color:rgba(79,209,197,var(--border-opacity))}.hover\:border-teal-500:hover{--border-opacity:1;border-color:#38b2ac;border-color:rgba(56,178,172,var(--border-opacity))}.hover\:border-teal-600:hover{--border-opacity:1;border-color:#319795;border-color:rgba(49,151,149,var(--border-opacity))}.hover\:border-teal-700:hover{--border-opacity:1;border-color:#2c7a7b;border-color:rgba(44,122,123,var(--border-opacity))}.hover\:border-teal-800:hover{--border-opacity:1;border-color:#285e61;border-color:rgba(40,94,97,var(--border-opacity))}.hover\:border-teal-900:hover{--border-opacity:1;border-color:#234e52;border-color:rgba(35,78,82,var(--border-opacity))}.hover\:border-blue-100:hover{--border-opacity:1;border-color:#ebf8ff;border-color:rgba(235,248,255,var(--border-opacity))}.hover\:border-blue-200:hover{--border-opacity:1;border-color:#bee3f8;border-color:rgba(190,227,248,var(--border-opacity))}.hover\:border-blue-300:hover{--border-opacity:1;border-color:#90cdf4;border-color:rgba(144,205,244,var(--border-opacity))}.hover\:border-blue-400:hover{--border-opacity:1;border-color:#63b3ed;border-color:rgba(99,179,237,var(--border-opacity))}.hover\:border-blue-500:hover{--border-opacity:1;border-color:#4299e1;border-color:rgba(66,153,225,var(--border-opacity))}.hover\:border-blue-600:hover{--border-opacity:1;border-color:#3182ce;border-color:rgba(49,130,206,var(--border-opacity))}.hover\:border-blue-700:hover{--border-opacity:1;border-color:#2b6cb0;border-color:rgba(43,108,176,var(--border-opacity))}.hover\:border-blue-800:hover{--border-opacity:1;border-color:#2c5282;border-color:rgba(44,82,130,var(--border-opacity))}.hover\:border-blue-900:hover{--border-opacity:1;border-color:#2a4365;border-color:rgba(42,67,101,var(--border-opacity))}.hover\:border-indigo-100:hover{--border-opacity:1;border-color:#ebf4ff;border-color:rgba(235,244,255,var(--border-opacity))}.hover\:border-indigo-200:hover{--border-opacity:1;border-color:#c3dafe;border-color:rgba(195,218,254,var(--border-opacity))}.hover\:border-indigo-300:hover{--border-opacity:1;border-color:#a3bffa;border-color:rgba(163,191,250,var(--border-opacity))}.hover\:border-indigo-400:hover{--border-opacity:1;border-color:#7f9cf5;border-color:rgba(127,156,245,var(--border-opacity))}.hover\:border-indigo-500:hover{--border-opacity:1;border-color:#667eea;border-color:rgba(102,126,234,var(--border-opacity))}.hover\:border-indigo-600:hover{--border-opacity:1;border-color:#5a67d8;border-color:rgba(90,103,216,var(--border-opacity))}.hover\:border-indigo-700:hover{--border-opacity:1;border-color:#4c51bf;border-color:rgba(76,81,191,var(--border-opacity))}.hover\:border-indigo-800:hover{--border-opacity:1;border-color:#434190;border-color:rgba(67,65,144,var(--border-opacity))}.hover\:border-indigo-900:hover{--border-opacity:1;border-color:#3c366b;border-color:rgba(60,54,107,var(--border-opacity))}.hover\:border-purple-100:hover{--border-opacity:1;border-color:#faf5ff;border-color:rgba(250,245,255,var(--border-opacity))}.hover\:border-purple-200:hover{--border-opacity:1;border-color:#e9d8fd;border-color:rgba(233,216,253,var(--border-opacity))}.hover\:border-purple-300:hover{--border-opacity:1;border-color:#d6bcfa;border-color:rgba(214,188,250,var(--border-opacity))}.hover\:border-purple-400:hover{--border-opacity:1;border-color:#b794f4;border-color:rgba(183,148,244,var(--border-opacity))}.hover\:border-purple-500:hover{--border-opacity:1;border-color:#9f7aea;border-color:rgba(159,122,234,var(--border-opacity))}.hover\:border-purple-600:hover{--border-opacity:1;border-color:#805ad5;border-color:rgba(128,90,213,var(--border-opacity))}.hover\:border-purple-700:hover{--border-opacity:1;border-color:#6b46c1;border-color:rgba(107,70,193,var(--border-opacity))}.hover\:border-purple-800:hover{--border-opacity:1;border-color:#553c9a;border-color:rgba(85,60,154,var(--border-opacity))}.hover\:border-purple-900:hover{--border-opacity:1;border-color:#44337a;border-color:rgba(68,51,122,var(--border-opacity))}.hover\:border-pink-100:hover{--border-opacity:1;border-color:#fff5f7;border-color:rgba(255,245,247,var(--border-opacity))}.hover\:border-pink-200:hover{--border-opacity:1;border-color:#fed7e2;border-color:rgba(254,215,226,var(--border-opacity))}.hover\:border-pink-300:hover{--border-opacity:1;border-color:#fbb6ce;border-color:rgba(251,182,206,var(--border-opacity))}.hover\:border-pink-400:hover{--border-opacity:1;border-color:#f687b3;border-color:rgba(246,135,179,var(--border-opacity))}.hover\:border-pink-500:hover{--border-opacity:1;border-color:#ed64a6;border-color:rgba(237,100,166,var(--border-opacity))}.hover\:border-pink-600:hover{--border-opacity:1;border-color:#d53f8c;border-color:rgba(213,63,140,var(--border-opacity))}.hover\:border-pink-700:hover{--border-opacity:1;border-color:#b83280;border-color:rgba(184,50,128,var(--border-opacity))}.hover\:border-pink-800:hover{--border-opacity:1;border-color:#97266d;border-color:rgba(151,38,109,var(--border-opacity))}.hover\:border-pink-900:hover{--border-opacity:1;border-color:#702459;border-color:rgba(112,36,89,var(--border-opacity))}.focus\:border-transparent:focus{border-color:transparent}.focus\:border-current:focus{border-color:currentColor}.focus\:border-black:focus{--border-opacity:1;border-color:#000;border-color:rgba(0,0,0,var(--border-opacity))}.focus\:border-white:focus{--border-opacity:1;border-color:#fff;border-color:rgba(255,255,255,var(--border-opacity))}.focus\:border-gray-100:focus{--border-opacity:1;border-color:#f7fafc;border-color:rgba(247,250,252,var(--border-opacity))}.focus\:border-gray-200:focus{--border-opacity:1;border-color:#edf2f7;border-color:rgba(237,242,247,var(--border-opacity))}.focus\:border-gray-300:focus{--border-opacity:1;border-color:#e2e8f0;border-color:rgba(226,232,240,var(--border-opacity))}.focus\:border-gray-400:focus{--border-opacity:1;border-color:#cbd5e0;border-color:rgba(203,213,224,var(--border-opacity))}.focus\:border-gray-500:focus{--border-opacity:1;border-color:#a0aec0;border-color:rgba(160,174,192,var(--border-opacity))}.focus\:border-gray-600:focus{--border-opacity:1;border-color:#718096;border-color:rgba(113,128,150,var(--border-opacity))}.focus\:border-gray-700:focus{--border-opacity:1;border-color:#4a5568;border-color:rgba(74,85,104,var(--border-opacity))}.focus\:border-gray-800:focus{--border-opacity:1;border-color:#2d3748;border-color:rgba(45,55,72,var(--border-opacity))}.focus\:border-gray-900:focus{--border-opacity:1;border-color:#1a202c;border-color:rgba(26,32,44,var(--border-opacity))}.focus\:border-red-100:focus{--border-opacity:1;border-color:#fff5f5;border-color:rgba(255,245,245,var(--border-opacity))}.focus\:border-red-200:focus{--border-opacity:1;border-color:#fed7d7;border-color:rgba(254,215,215,var(--border-opacity))}.focus\:border-red-300:focus{--border-opacity:1;border-color:#feb2b2;border-color:rgba(254,178,178,var(--border-opacity))}.focus\:border-red-400:focus{--border-opacity:1;border-color:#fc8181;border-color:rgba(252,129,129,var(--border-opacity))}.focus\:border-red-500:focus{--border-opacity:1;border-color:#f56565;border-color:rgba(245,101,101,var(--border-opacity))}.focus\:border-red-600:focus{--border-opacity:1;border-color:#e53e3e;border-color:rgba(229,62,62,var(--border-opacity))}.focus\:border-red-700:focus{--border-opacity:1;border-color:#c53030;border-color:rgba(197,48,48,var(--border-opacity))}.focus\:border-red-800:focus{--border-opacity:1;border-color:#9b2c2c;border-color:rgba(155,44,44,var(--border-opacity))}.focus\:border-red-900:focus{--border-opacity:1;border-color:#742a2a;border-color:rgba(116,42,42,var(--border-opacity))}.focus\:border-orange-100:focus{--border-opacity:1;border-color:#fffaf0;border-color:rgba(255,250,240,var(--border-opacity))}.focus\:border-orange-200:focus{--border-opacity:1;border-color:#feebc8;border-color:rgba(254,235,200,var(--border-opacity))}.focus\:border-orange-300:focus{--border-opacity:1;border-color:#fbd38d;border-color:rgba(251,211,141,var(--border-opacity))}.focus\:border-orange-400:focus{--border-opacity:1;border-color:#f6ad55;border-color:rgba(246,173,85,var(--border-opacity))}.focus\:border-orange-500:focus{--border-opacity:1;border-color:#ed8936;border-color:rgba(237,137,54,var(--border-opacity))}.focus\:border-orange-600:focus{--border-opacity:1;border-color:#dd6b20;border-color:rgba(221,107,32,var(--border-opacity))}.focus\:border-orange-700:focus{--border-opacity:1;border-color:#c05621;border-color:rgba(192,86,33,var(--border-opacity))}.focus\:border-orange-800:focus{--border-opacity:1;border-color:#9c4221;border-color:rgba(156,66,33,var(--border-opacity))}.focus\:border-orange-900:focus{--border-opacity:1;border-color:#7b341e;border-color:rgba(123,52,30,var(--border-opacity))}.focus\:border-yellow-100:focus{--border-opacity:1;border-color:ivory;border-color:rgba(255,255,240,var(--border-opacity))}.focus\:border-yellow-200:focus{--border-opacity:1;border-color:#fefcbf;border-color:rgba(254,252,191,var(--border-opacity))}.focus\:border-yellow-300:focus{--border-opacity:1;border-color:#faf089;border-color:rgba(250,240,137,var(--border-opacity))}.focus\:border-yellow-400:focus{--border-opacity:1;border-color:#f6e05e;border-color:rgba(246,224,94,var(--border-opacity))}.focus\:border-yellow-500:focus{--border-opacity:1;border-color:#ecc94b;border-color:rgba(236,201,75,var(--border-opacity))}.focus\:border-yellow-600:focus{--border-opacity:1;border-color:#d69e2e;border-color:rgba(214,158,46,var(--border-opacity))}.focus\:border-yellow-700:focus{--border-opacity:1;border-color:#b7791f;border-color:rgba(183,121,31,var(--border-opacity))}.focus\:border-yellow-800:focus{--border-opacity:1;border-color:#975a16;border-color:rgba(151,90,22,var(--border-opacity))}.focus\:border-yellow-900:focus{--border-opacity:1;border-color:#744210;border-color:rgba(116,66,16,var(--border-opacity))}.focus\:border-green-100:focus{--border-opacity:1;border-color:#f0fff4;border-color:rgba(240,255,244,var(--border-opacity))}.focus\:border-green-200:focus{--border-opacity:1;border-color:#c6f6d5;border-color:rgba(198,246,213,var(--border-opacity))}.focus\:border-green-300:focus{--border-opacity:1;border-color:#9ae6b4;border-color:rgba(154,230,180,var(--border-opacity))}.focus\:border-green-400:focus{--border-opacity:1;border-color:#68d391;border-color:rgba(104,211,145,var(--border-opacity))}.focus\:border-green-500:focus{--border-opacity:1;border-color:#48bb78;border-color:rgba(72,187,120,var(--border-opacity))}.focus\:border-green-600:focus{--border-opacity:1;border-color:#38a169;border-color:rgba(56,161,105,var(--border-opacity))}.focus\:border-green-700:focus{--border-opacity:1;border-color:#2f855a;border-color:rgba(47,133,90,var(--border-opacity))}.focus\:border-green-800:focus{--border-opacity:1;border-color:#276749;border-color:rgba(39,103,73,var(--border-opacity))}.focus\:border-green-900:focus{--border-opacity:1;border-color:#22543d;border-color:rgba(34,84,61,var(--border-opacity))}.focus\:border-teal-100:focus{--border-opacity:1;border-color:#e6fffa;border-color:rgba(230,255,250,var(--border-opacity))}.focus\:border-teal-200:focus{--border-opacity:1;border-color:#b2f5ea;border-color:rgba(178,245,234,var(--border-opacity))}.focus\:border-teal-300:focus{--border-opacity:1;border-color:#81e6d9;border-color:rgba(129,230,217,var(--border-opacity))}.focus\:border-teal-400:focus{--border-opacity:1;border-color:#4fd1c5;border-color:rgba(79,209,197,var(--border-opacity))}.focus\:border-teal-500:focus{--border-opacity:1;border-color:#38b2ac;border-color:rgba(56,178,172,var(--border-opacity))}.focus\:border-teal-600:focus{--border-opacity:1;border-color:#319795;border-color:rgba(49,151,149,var(--border-opacity))}.focus\:border-teal-700:focus{--border-opacity:1;border-color:#2c7a7b;border-color:rgba(44,122,123,var(--border-opacity))}.focus\:border-teal-800:focus{--border-opacity:1;border-color:#285e61;border-color:rgba(40,94,97,var(--border-opacity))}.focus\:border-teal-900:focus{--border-opacity:1;border-color:#234e52;border-color:rgba(35,78,82,var(--border-opacity))}.focus\:border-blue-100:focus{--border-opacity:1;border-color:#ebf8ff;border-color:rgba(235,248,255,var(--border-opacity))}.focus\:border-blue-200:focus{--border-opacity:1;border-color:#bee3f8;border-color:rgba(190,227,248,var(--border-opacity))}.focus\:border-blue-300:focus{--border-opacity:1;border-color:#90cdf4;border-color:rgba(144,205,244,var(--border-opacity))}.focus\:border-blue-400:focus{--border-opacity:1;border-color:#63b3ed;border-color:rgba(99,179,237,var(--border-opacity))}.focus\:border-blue-500:focus{--border-opacity:1;border-color:#4299e1;border-color:rgba(66,153,225,var(--border-opacity))}.focus\:border-blue-600:focus{--border-opacity:1;border-color:#3182ce;border-color:rgba(49,130,206,var(--border-opacity))}.focus\:border-blue-700:focus{--border-opacity:1;border-color:#2b6cb0;border-color:rgba(43,108,176,var(--border-opacity))}.focus\:border-blue-800:focus{--border-opacity:1;border-color:#2c5282;border-color:rgba(44,82,130,var(--border-opacity))}.focus\:border-blue-900:focus{--border-opacity:1;border-color:#2a4365;border-color:rgba(42,67,101,var(--border-opacity))}.focus\:border-indigo-100:focus{--border-opacity:1;border-color:#ebf4ff;border-color:rgba(235,244,255,var(--border-opacity))}.focus\:border-indigo-200:focus{--border-opacity:1;border-color:#c3dafe;border-color:rgba(195,218,254,var(--border-opacity))}.focus\:border-indigo-300:focus{--border-opacity:1;border-color:#a3bffa;border-color:rgba(163,191,250,var(--border-opacity))}.focus\:border-indigo-400:focus{--border-opacity:1;border-color:#7f9cf5;border-color:rgba(127,156,245,var(--border-opacity))}.focus\:border-indigo-500:focus{--border-opacity:1;border-color:#667eea;border-color:rgba(102,126,234,var(--border-opacity))}.focus\:border-indigo-600:focus{--border-opacity:1;border-color:#5a67d8;border-color:rgba(90,103,216,var(--border-opacity))}.focus\:border-indigo-700:focus{--border-opacity:1;border-color:#4c51bf;border-color:rgba(76,81,191,var(--border-opacity))}.focus\:border-indigo-800:focus{--border-opacity:1;border-color:#434190;border-color:rgba(67,65,144,var(--border-opacity))}.focus\:border-indigo-900:focus{--border-opacity:1;border-color:#3c366b;border-color:rgba(60,54,107,var(--border-opacity))}.focus\:border-purple-100:focus{--border-opacity:1;border-color:#faf5ff;border-color:rgba(250,245,255,var(--border-opacity))}.focus\:border-purple-200:focus{--border-opacity:1;border-color:#e9d8fd;border-color:rgba(233,216,253,var(--border-opacity))}.focus\:border-purple-300:focus{--border-opacity:1;border-color:#d6bcfa;border-color:rgba(214,188,250,var(--border-opacity))}.focus\:border-purple-400:focus{--border-opacity:1;border-color:#b794f4;border-color:rgba(183,148,244,var(--border-opacity))}.focus\:border-purple-500:focus{--border-opacity:1;border-color:#9f7aea;border-color:rgba(159,122,234,var(--border-opacity))}.focus\:border-purple-600:focus{--border-opacity:1;border-color:#805ad5;border-color:rgba(128,90,213,var(--border-opacity))}.focus\:border-purple-700:focus{--border-opacity:1;border-color:#6b46c1;border-color:rgba(107,70,193,var(--border-opacity))}.focus\:border-purple-800:focus{--border-opacity:1;border-color:#553c9a;border-color:rgba(85,60,154,var(--border-opacity))}.focus\:border-purple-900:focus{--border-opacity:1;border-color:#44337a;border-color:rgba(68,51,122,var(--border-opacity))}.focus\:border-pink-100:focus{--border-opacity:1;border-color:#fff5f7;border-color:rgba(255,245,247,var(--border-opacity))}.focus\:border-pink-200:focus{--border-opacity:1;border-color:#fed7e2;border-color:rgba(254,215,226,var(--border-opacity))}.focus\:border-pink-300:focus{--border-opacity:1;border-color:#fbb6ce;border-color:rgba(251,182,206,var(--border-opacity))}.focus\:border-pink-400:focus{--border-opacity:1;border-color:#f687b3;border-color:rgba(246,135,179,var(--border-opacity))}.focus\:border-pink-500:focus{--border-opacity:1;border-color:#ed64a6;border-color:rgba(237,100,166,var(--border-opacity))}.focus\:border-pink-600:focus{--border-opacity:1;border-color:#d53f8c;border-color:rgba(213,63,140,var(--border-opacity))}.focus\:border-pink-700:focus{--border-opacity:1;border-color:#b83280;border-color:rgba(184,50,128,var(--border-opacity))}.focus\:border-pink-800:focus{--border-opacity:1;border-color:#97266d;border-color:rgba(151,38,109,var(--border-opacity))}.focus\:border-pink-900:focus{--border-opacity:1;border-color:#702459;border-color:rgba(112,36,89,var(--border-opacity))}.border-opacity-0{--border-opacity:0}.border-opacity-25{--border-opacity:0.25}.border-opacity-50{--border-opacity:0.5}.border-opacity-75{--border-opacity:0.75}.border-opacity-100{--border-opacity:1}.hover\:border-opacity-0:hover{--border-opacity:0}.hover\:border-opacity-25:hover{--border-opacity:0.25}.hover\:border-opacity-50:hover{--border-opacity:0.5}.hover\:border-opacity-75:hover{--border-opacity:0.75}.hover\:border-opacity-100:hover{--border-opacity:1}.focus\:border-opacity-0:focus{--border-opacity:0}.focus\:border-opacity-25:focus{--border-opacity:0.25}.focus\:border-opacity-50:focus{--border-opacity:0.5}.focus\:border-opacity-75:focus{--border-opacity:0.75}.focus\:border-opacity-100:focus{--border-opacity:1}.rounded-none{border-radius:0}.rounded-sm{border-radius:.125rem}.rounded{border-radius:.25rem}.rounded-md{border-radius:.375rem}.rounded-lg{border-radius:.5rem}.rounded-xl{border-radius:.75rem}.rounded-2xl{border-radius:1rem}.rounded-3xl{border-radius:1.5rem}.rounded-full{border-radius:9999px}.rounded-t-none{border-top-left-radius:0;border-top-right-radius:0}.rounded-r-none{border-top-right-radius:0;border-bottom-right-radius:0}.rounded-b-none{border-bottom-right-radius:0;border-bottom-left-radius:0}.rounded-l-none{border-top-left-radius:0;border-bottom-left-radius:0}.rounded-t-sm{border-top-left-radius:.125rem;border-top-right-radius:.125rem}.rounded-r-sm{border-top-right-radius:.125rem;border-bottom-right-radius:.125rem}.rounded-b-sm{border-bottom-right-radius:.125rem;border-bottom-left-radius:.125rem}.rounded-l-sm{border-top-left-radius:.125rem;border-bottom-left-radius:.125rem}.rounded-t{border-top-left-radius:.25rem;border-top-right-radius:.25rem}.rounded-r{border-top-right-radius:.25rem;border-bottom-right-radius:.25rem}.rounded-b{border-bottom-right-radius:.25rem;border-bottom-left-radius:.25rem}.rounded-l{border-top-left-radius:.25rem;border-bottom-left-radius:.25rem}.rounded-t-md{border-top-left-radius:.375rem;border-top-right-radius:.375rem}.rounded-r-md{border-top-right-radius:.375rem;border-bottom-right-radius:.375rem}.rounded-b-md{border-bottom-right-radius:.375rem;border-bottom-left-radius:.375rem}.rounded-l-md{border-top-left-radius:.375rem;border-bottom-left-radius:.375rem}.rounded-t-lg{border-top-left-radius:.5rem;border-top-right-radius:.5rem}.rounded-r-lg{border-top-right-radius:.5rem;border-bottom-right-radius:.5rem}.rounded-b-lg{border-bottom-right-radius:.5rem;border-bottom-left-radius:.5rem}.rounded-l-lg{border-top-left-radius:.5rem;border-bottom-left-radius:.5rem}.rounded-t-xl{border-top-left-radius:.75rem;border-top-right-radius:.75rem}.rounded-r-xl{border-top-right-radius:.75rem;border-bottom-right-radius:.75rem}.rounded-b-xl{border-bottom-right-radius:.75rem;border-bottom-left-radius:.75rem}.rounded-l-xl{border-top-left-radius:.75rem;border-bottom-left-radius:.75rem}.rounded-t-2xl{border-top-left-radius:1rem;border-top-right-radius:1rem}.rounded-r-2xl{border-top-right-radius:1rem;border-bottom-right-radius:1rem}.rounded-b-2xl{border-bottom-right-radius:1rem;border-bottom-left-radius:1rem}.rounded-l-2xl{border-top-left-radius:1rem;border-bottom-left-radius:1rem}.rounded-t-3xl{border-top-left-radius:1.5rem;border-top-right-radius:1.5rem}.rounded-r-3xl{border-top-right-radius:1.5rem;border-bottom-right-radius:1.5rem}.rounded-b-3xl{border-bottom-right-radius:1.5rem;border-bottom-left-radius:1.5rem}.rounded-l-3xl{border-top-left-radius:1.5rem;border-bottom-left-radius:1.5rem}.rounded-t-full{border-top-left-radius:9999px;border-top-right-radius:9999px}.rounded-r-full{border-top-right-radius:9999px;border-bottom-right-radius:9999px}.rounded-b-full{border-bottom-right-radius:9999px;border-bottom-left-radius:9999px}.rounded-l-full{border-top-left-radius:9999px;border-bottom-left-radius:9999px}.rounded-tl-none{border-top-left-radius:0}.rounded-tr-none{border-top-right-radius:0}.rounded-br-none{border-bottom-right-radius:0}.rounded-bl-none{border-bottom-left-radius:0}.rounded-tl-sm{border-top-left-radius:.125rem}.rounded-tr-sm{border-top-right-radius:.125rem}.rounded-br-sm{border-bottom-right-radius:.125rem}.rounded-bl-sm{border-bottom-left-radius:.125rem}.rounded-tl{border-top-left-radius:.25rem}.rounded-tr{border-top-right-radius:.25rem}.rounded-br{border-bottom-right-radius:.25rem}.rounded-bl{border-bottom-left-radius:.25rem}.rounded-tl-md{border-top-left-radius:.375rem}.rounded-tr-md{border-top-right-radius:.375rem}.rounded-br-md{border-bottom-right-radius:.375rem}.rounded-bl-md{border-bottom-left-radius:.375rem}.rounded-tl-lg{border-top-left-radius:.5rem}.rounded-tr-lg{border-top-right-radius:.5rem}.rounded-br-lg{border-bottom-right-radius:.5rem}.rounded-bl-lg{border-bottom-left-radius:.5rem}.rounded-tl-xl{border-top-left-radius:.75rem}.rounded-tr-xl{border-top-right-radius:.75rem}.rounded-br-xl{border-bottom-right-radius:.75rem}.rounded-bl-xl{border-bottom-left-radius:.75rem}.rounded-tl-2xl{border-top-left-radius:1rem}.rounded-tr-2xl{border-top-right-radius:1rem}.rounded-br-2xl{border-bottom-right-radius:1rem}.rounded-bl-2xl{border-bottom-left-radius:1rem}.rounded-tl-3xl{border-top-left-radius:1.5rem}.rounded-tr-3xl{border-top-right-radius:1.5rem}.rounded-br-3xl{border-bottom-right-radius:1.5rem}.rounded-bl-3xl{border-bottom-left-radius:1.5rem}.rounded-tl-full{border-top-left-radius:9999px}.rounded-tr-full{border-top-right-radius:9999px}.rounded-br-full{border-bottom-right-radius:9999px}.rounded-bl-full{border-bottom-left-radius:9999px}.border-solid{border-style:solid}.border-dashed{border-style:dashed}.border-dotted{border-style:dotted}.border-double{border-style:double}.border-none{border-style:none}.border-0{border-width:0}.border-2{border-width:2px}.border-4{border-width:4px}.border-8{border-width:8px}.border{border-width:1px}.border-t-0{border-top-width:0}.border-r-0{border-right-width:0}.border-b-0{border-bottom-width:0}.border-l-0{border-left-width:0}.border-t-2{border-top-width:2px}.border-r-2{border-right-width:2px}.border-b-2{border-bottom-width:2px}.border-l-2{border-left-width:2px}.border-t-4{border-top-width:4px}.border-r-4{border-right-width:4px}.border-b-4{border-bottom-width:4px}.border-l-4{border-left-width:4px}.border-t-8{border-top-width:8px}.border-r-8{border-right-width:8px}.border-b-8{border-bottom-width:8px}.border-l-8{border-left-width:8px}.border-t{border-top-width:1px}.border-r{border-right-width:1px}.border-b{border-bottom-width:1px}.border-l{border-left-width:1px}.box-border{box-sizing:border-box}.box-content{box-sizing:content-box}.cursor-auto{cursor:auto}.cursor-default{cursor:default}.cursor-pointer{cursor:pointer}.cursor-wait{cursor:wait}.cursor-text{cursor:text}.cursor-move{cursor:move}.cursor-not-allowed{cursor:not-allowed}.block{display:block}.inline-block{display:inline-block}.inline{display:inline}.flex{display:flex}.inline-flex{display:inline-flex}.table{display:table}.table-caption{display:table-caption}.table-cell{display:table-cell}.table-column{display:table-column}.table-column-group{display:table-column-group}.table-footer-group{display:table-footer-group}.table-header-group{display:table-header-group}.table-row-group{display:table-row-group}.table-row{display:table-row}.flow-root{display:flow-root}.grid{display:grid}.inline-grid{display:inline-grid}.contents{display:contents}.hidden{display:none}.flex-row{flex-direction:row}.flex-row-reverse{flex-direction:row-reverse}.flex-col{flex-direction:column}.flex-col-reverse{flex-direction:column-reverse}.flex-wrap{flex-wrap:wrap}.flex-wrap-reverse{flex-wrap:wrap-reverse}.flex-no-wrap{flex-wrap:nowrap}.place-items-auto{place-items:auto}.place-items-start{place-items:start}.place-items-end{place-items:end}.place-items-center{place-items:center}.place-items-stretch{place-items:stretch}.place-content-center{place-content:center}.place-content-start{place-content:start}.place-content-end{place-content:end}.place-content-between{place-content:space-between}.place-content-around{place-content:space-around}.place-content-evenly{place-content:space-evenly}.place-content-stretch{place-content:stretch}.place-self-auto{place-self:auto}.place-self-start{place-self:start}.place-self-end{place-self:end}.place-self-center{place-self:center}.place-self-stretch{place-self:stretch}.items-start{align-items:flex-start}.items-end{align-items:flex-end}.items-center{align-items:center}.items-baseline{align-items:baseline}.items-stretch{align-items:stretch}.content-center{align-content:center}.content-start{align-content:flex-start}.content-end{align-content:flex-end}.content-between{align-content:space-between}.content-around{align-content:space-around}.content-evenly{align-content:space-evenly}.self-auto{align-self:auto}.self-start{align-self:flex-start}.self-end{align-self:flex-end}.self-center{align-self:center}.self-stretch{align-self:stretch}.justify-items-auto{justify-items:auto}.justify-items-start{justify-items:start}.justify-items-end{justify-items:end}.justify-items-center{justify-items:center}.justify-items-stretch{justify-items:stretch}.justify-start{justify-content:flex-start}.justify-end{justify-content:flex-end}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.justify-around{justify-content:space-around}.justify-evenly{justify-content:space-evenly}.justify-self-auto{justify-self:auto}.justify-self-start{justify-self:start}.justify-self-end{justify-self:end}.justify-self-center{justify-self:center}.justify-self-stretch{justify-self:stretch}.flex-1{flex:1 1 0%}.flex-auto{flex:1 1 auto}.flex-initial{flex:0 1 auto}.flex-none{flex:none}.flex-grow-0{flex-grow:0}.flex-grow{flex-grow:1}.flex-shrink-0{flex-shrink:0}.flex-shrink{flex-shrink:1}.order-1{order:1}.order-2{order:2}.order-3{order:3}.order-4{order:4}.order-5{order:5}.order-6{order:6}.order-7{order:7}.order-8{order:8}.order-9{order:9}.order-10{order:10}.order-11{order:11}.order-12{order:12}.order-first{order:-9999}.order-last{order:9999}.order-none{order:0}.float-right{float:right}.float-left{float:left}.float-none{float:none}.clearfix:after{content:"";display:table;clear:both}.clear-left{clear:left}.clear-right{clear:right}.clear-both{clear:both}.clear-none{clear:none}.font-sans{font-family:system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji"}.font-serif{font-family:Georgia,Cambria,"Times New Roman",Times,serif}.font-mono{font-family:Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace}.font-hairline{font-weight:100}.font-thin{font-weight:200}.font-light{font-weight:300}.font-normal{font-weight:400}.font-medium{font-weight:500}.font-semibold{font-weight:600}.font-bold{font-weight:700}.font-extrabold{font-weight:800}.font-black{font-weight:900}.hover\:font-hairline:hover{font-weight:100}.hover\:font-thin:hover{font-weight:200}.hover\:font-light:hover{font-weight:300}.hover\:font-normal:hover{font-weight:400}.hover\:font-medium:hover{font-weight:500}.hover\:font-semibold:hover{font-weight:600}.hover\:font-bold:hover{font-weight:700}.hover\:font-extrabold:hover{font-weight:800}.hover\:font-black:hover{font-weight:900}.focus\:font-hairline:focus{font-weight:100}.focus\:font-thin:focus{font-weight:200}.focus\:font-light:focus{font-weight:300}.focus\:font-normal:focus{font-weight:400}.focus\:font-medium:focus{font-weight:500}.focus\:font-semibold:focus{font-weight:600}.focus\:font-bold:focus{font-weight:700}.focus\:font-extrabold:focus{font-weight:800}.focus\:font-black:focus{font-weight:900}.h-0{height:0}.h-1{height:.25rem}.h-2{height:.5rem}.h-3{height:.75rem}.h-4{height:1rem}.h-5{height:1.25rem}.h-6{height:1.5rem}.h-8{height:2rem}.h-10{height:2.5rem}.h-12{height:3rem}.h-16{height:4rem}.h-20{height:5rem}.h-24{height:6rem}.h-32{height:8rem}.h-40{height:10rem}.h-48{height:12rem}.h-56{height:14rem}.h-64{height:16rem}.h-auto{height:auto}.h-px{height:1px}.h-full{height:100%}.h-screen{height:100vh}.text-xs{font-size:.75rem}.text-sm{font-size:.875rem}.text-base{font-size:1rem}.text-lg{font-size:1.125rem}.text-xl{font-size:1.25rem}.text-2xl{font-size:1.5rem}.text-3xl{font-size:1.875rem}.text-4xl{font-size:2.25rem}.text-5xl{font-size:3rem}.text-6xl{font-size:4rem}.leading-3{line-height:.75rem}.leading-4{line-height:1rem}.leading-5{line-height:1.25rem}.leading-6{line-height:1.5rem}.leading-7{line-height:1.75rem}.leading-8{line-height:2rem}.leading-9{line-height:2.25rem}.leading-10{line-height:2.5rem}.leading-none{line-height:1}.leading-tight{line-height:1.25}.leading-snug{line-height:1.375}.leading-normal{line-height:1.5}.leading-relaxed{line-height:1.625}.leading-loose{line-height:2}.list-inside{list-style-position:inside}.list-outside{list-style-position:outside}.list-none{list-style-type:none}.list-disc{list-style-type:disc}.list-decimal{list-style-type:decimal}.m-0{margin:0}.m-1{margin:.25rem}.m-2{margin:.5rem}.m-3{margin:.75rem}.m-4{margin:1rem}.m-5{margin:1.25rem}.m-6{margin:1.5rem}.m-8{margin:2rem}.m-10{margin:2.5rem}.m-12{margin:3rem}.m-16{margin:4rem}.m-20{margin:5rem}.m-24{margin:6rem}.m-32{margin:8rem}.m-40{margin:10rem}.m-48{margin:12rem}.m-56{margin:14rem}.m-64{margin:16rem}.m-auto{margin:auto}.m-px{margin:1px}.-m-1{margin:-.25rem}.-m-2{margin:-.5rem}.-m-3{margin:-.75rem}.-m-4{margin:-1rem}.-m-5{margin:-1.25rem}.-m-6{margin:-1.5rem}.-m-8{margin:-2rem}.-m-10{margin:-2.5rem}.-m-12{margin:-3rem}.-m-16{margin:-4rem}.-m-20{margin:-5rem}.-m-24{margin:-6rem}.-m-32{margin:-8rem}.-m-40{margin:-10rem}.-m-48{margin:-12rem}.-m-56{margin:-14rem}.-m-64{margin:-16rem}.-m-px{margin:-1px}.my-0{margin-top:0;margin-bottom:0}.mx-0{margin-left:0;margin-right:0}.my-1{margin-top:.25rem;margin-bottom:.25rem}.mx-1{margin-left:.25rem;margin-right:.25rem}.my-2{margin-top:.5rem;margin-bottom:.5rem}.mx-2{margin-left:.5rem;margin-right:.5rem}.my-3{margin-top:.75rem;margin-bottom:.75rem}.mx-3{margin-left:.75rem;margin-right:.75rem}.my-4{margin-top:1rem;margin-bottom:1rem}.mx-4{margin-left:1rem;margin-right:1rem}.my-5{margin-top:1.25rem;margin-bottom:1.25rem}.mx-5{margin-left:1.25rem;margin-right:1.25rem}.my-6{margin-top:1.5rem;margin-bottom:1.5rem}.mx-6{margin-left:1.5rem;margin-right:1.5rem}.my-8{margin-top:2rem;margin-bottom:2rem}.mx-8{margin-left:2rem;margin-right:2rem}.my-10{margin-top:2.5rem;margin-bottom:2.5rem}.mx-10{margin-left:2.5rem;margin-right:2.5rem}.my-12{margin-top:3rem;margin-bottom:3rem}.mx-12{margin-left:3rem;margin-right:3rem}.my-16{margin-top:4rem;margin-bottom:4rem}.mx-16{margin-left:4rem;margin-right:4rem}.my-20{margin-top:5rem;margin-bottom:5rem}.mx-20{margin-left:5rem;margin-right:5rem}.my-24{margin-top:6rem;margin-bottom:6rem}.mx-24{margin-left:6rem;margin-right:6rem}.my-32{margin-top:8rem;margin-bottom:8rem}.mx-32{margin-left:8rem;margin-right:8rem}.my-40{margin-top:10rem;margin-bottom:10rem}.mx-40{margin-left:10rem;margin-right:10rem}.my-48{margin-top:12rem;margin-bottom:12rem}.mx-48{margin-left:12rem;margin-right:12rem}.my-56{margin-top:14rem;margin-bottom:14rem}.mx-56{margin-left:14rem;margin-right:14rem}.my-64{margin-top:16rem;margin-bottom:16rem}.mx-64{margin-left:16rem;margin-right:16rem}.my-auto{margin-top:auto;margin-bottom:auto}.mx-auto{margin-left:auto;margin-right:auto}.my-px{margin-top:1px;margin-bottom:1px}.mx-px{margin-left:1px;margin-right:1px}.-my-1{margin-top:-.25rem;margin-bottom:-.25rem}.-mx-1{margin-left:-.25rem;margin-right:-.25rem}.-my-2{margin-top:-.5rem;margin-bottom:-.5rem}.-mx-2{margin-left:-.5rem;margin-right:-.5rem}.-my-3{margin-top:-.75rem;margin-bottom:-.75rem}.-mx-3{margin-left:-.75rem;margin-right:-.75rem}.-my-4{margin-top:-1rem;margin-bottom:-1rem}.-mx-4{margin-left:-1rem;margin-right:-1rem}.-my-5{margin-top:-1.25rem;margin-bottom:-1.25rem}.-mx-5{margin-left:-1.25rem;margin-right:-1.25rem}.-my-6{margin-top:-1.5rem;margin-bottom:-1.5rem}.-mx-6{margin-left:-1.5rem;margin-right:-1.5rem}.-my-8{margin-top:-2rem;margin-bottom:-2rem}.-mx-8{margin-left:-2rem;margin-right:-2rem}.-my-10{margin-top:-2.5rem;margin-bottom:-2.5rem}.-mx-10{margin-left:-2.5rem;margin-right:-2.5rem}.-my-12{margin-top:-3rem;margin-bottom:-3rem}.-mx-12{margin-left:-3rem;margin-right:-3rem}.-my-16{margin-top:-4rem;margin-bottom:-4rem}.-mx-16{margin-left:-4rem;margin-right:-4rem}.-my-20{margin-top:-5rem;margin-bottom:-5rem}.-mx-20{margin-left:-5rem;margin-right:-5rem}.-my-24{margin-top:-6rem;margin-bottom:-6rem}.-mx-24{margin-left:-6rem;margin-right:-6rem}.-my-32{margin-top:-8rem;margin-bottom:-8rem}.-mx-32{margin-left:-8rem;margin-right:-8rem}.-my-40{margin-top:-10rem;margin-bottom:-10rem}.-mx-40{margin-left:-10rem;margin-right:-10rem}.-my-48{margin-top:-12rem;margin-bottom:-12rem}.-mx-48{margin-left:-12rem;margin-right:-12rem}.-my-56{margin-top:-14rem;margin-bottom:-14rem}.-mx-56{margin-left:-14rem;margin-right:-14rem}.-my-64{margin-top:-16rem;margin-bottom:-16rem}.-mx-64{margin-left:-16rem;margin-right:-16rem}.-my-px{margin-top:-1px;margin-bottom:-1px}.-mx-px{margin-left:-1px;margin-right:-1px}.mt-0{margin-top:0}.mr-0{margin-right:0}.mb-0{margin-bottom:0}.ml-0{margin-left:0}.mt-1{margin-top:.25rem}.mr-1{margin-right:.25rem}.mb-1{margin-bottom:.25rem}.ml-1{margin-left:.25rem}.mt-2{margin-top:.5rem}.mr-2{margin-right:.5rem}.mb-2{margin-bottom:.5rem}.ml-2{margin-left:.5rem}.mt-3{margin-top:.75rem}.mr-3{margin-right:.75rem}.mb-3{margin-bottom:.75rem}.ml-3{margin-left:.75rem}.mt-4{margin-top:1rem}.mr-4{margin-right:1rem}.mb-4{margin-bottom:1rem}.ml-4{margin-left:1rem}.mt-5{margin-top:1.25rem}.mr-5{margin-right:1.25rem}.mb-5{margin-bottom:1.25rem}.ml-5{margin-left:1.25rem}.mt-6{margin-top:1.5rem}.mr-6{margin-right:1.5rem}.mb-6{margin-bottom:1.5rem}.ml-6{margin-left:1.5rem}.mt-8{margin-top:2rem}.mr-8{margin-right:2rem}.mb-8{margin-bottom:2rem}.ml-8{margin-left:2rem}.mt-10{margin-top:2.5rem}.mr-10{margin-right:2.5rem}.mb-10{margin-bottom:2.5rem}.ml-10{margin-left:2.5rem}.mt-12{margin-top:3rem}.mr-12{margin-right:3rem}.mb-12{margin-bottom:3rem}.ml-12{margin-left:3rem}.mt-16{margin-top:4rem}.mr-16{margin-right:4rem}.mb-16{margin-bottom:4rem}.ml-16{margin-left:4rem}.mt-20{margin-top:5rem}.mr-20{margin-right:5rem}.mb-20{margin-bottom:5rem}.ml-20{margin-left:5rem}.mt-24{margin-top:6rem}.mr-24{margin-right:6rem}.mb-24{margin-bottom:6rem}.ml-24{margin-left:6rem}.mt-32{margin-top:8rem}.mr-32{margin-right:8rem}.mb-32{margin-bottom:8rem}.ml-32{margin-left:8rem}.mt-40{margin-top:10rem}.mr-40{margin-right:10rem}.mb-40{margin-bottom:10rem}.ml-40{margin-left:10rem}.mt-48{margin-top:12rem}.mr-48{margin-right:12rem}.mb-48{margin-bottom:12rem}.ml-48{margin-left:12rem}.mt-56{margin-top:14rem}.mr-56{margin-right:14rem}.mb-56{margin-bottom:14rem}.ml-56{margin-left:14rem}.mt-64{margin-top:16rem}.mr-64{margin-right:16rem}.mb-64{margin-bottom:16rem}.ml-64{margin-left:16rem}.mt-auto{margin-top:auto}.mr-auto{margin-right:auto}.mb-auto{margin-bottom:auto}.ml-auto{margin-left:auto}.mt-px{margin-top:1px}.mr-px{margin-right:1px}.mb-px{margin-bottom:1px}.ml-px{margin-left:1px}.-mt-1{margin-top:-.25rem}.-mr-1{margin-right:-.25rem}.-mb-1{margin-bottom:-.25rem}.-ml-1{margin-left:-.25rem}.-mt-2{margin-top:-.5rem}.-mr-2{margin-right:-.5rem}.-mb-2{margin-bottom:-.5rem}.-ml-2{margin-left:-.5rem}.-mt-3{margin-top:-.75rem}.-mr-3{margin-right:-.75rem}.-mb-3{margin-bottom:-.75rem}.-ml-3{margin-left:-.75rem}.-mt-4{margin-top:-1rem}.-mr-4{margin-right:-1rem}.-mb-4{margin-bottom:-1rem}.-ml-4{margin-left:-1rem}.-mt-5{margin-top:-1.25rem}.-mr-5{margin-right:-1.25rem}.-mb-5{margin-bottom:-1.25rem}.-ml-5{margin-left:-1.25rem}.-mt-6{margin-top:-1.5rem}.-mr-6{margin-right:-1.5rem}.-mb-6{margin-bottom:-1.5rem}.-ml-6{margin-left:-1.5rem}.-mt-8{margin-top:-2rem}.-mr-8{margin-right:-2rem}.-mb-8{margin-bottom:-2rem}.-ml-8{margin-left:-2rem}.-mt-10{margin-top:-2.5rem}.-mr-10{margin-right:-2.5rem}.-mb-10{margin-bottom:-2.5rem}.-ml-10{margin-left:-2.5rem}.-mt-12{margin-top:-3rem}.-mr-12{margin-right:-3rem}.-mb-12{margin-bottom:-3rem}.-ml-12{margin-left:-3rem}.-mt-16{margin-top:-4rem}.-mr-16{margin-right:-4rem}.-mb-16{margin-bottom:-4rem}.-ml-16{margin-left:-4rem}.-mt-20{margin-top:-5rem}.-mr-20{margin-right:-5rem}.-mb-20{margin-bottom:-5rem}.-ml-20{margin-left:-5rem}.-mt-24{margin-top:-6rem}.-mr-24{margin-right:-6rem}.-mb-24{margin-bottom:-6rem}.-ml-24{margin-left:-6rem}.-mt-32{margin-top:-8rem}.-mr-32{margin-right:-8rem}.-mb-32{margin-bottom:-8rem}.-ml-32{margin-left:-8rem}.-mt-40{margin-top:-10rem}.-mr-40{margin-right:-10rem}.-mb-40{margin-bottom:-10rem}.-ml-40{margin-left:-10rem}.-mt-48{margin-top:-12rem}.-mr-48{margin-right:-12rem}.-mb-48{margin-bottom:-12rem}.-ml-48{margin-left:-12rem}.-mt-56{margin-top:-14rem}.-mr-56{margin-right:-14rem}.-mb-56{margin-bottom:-14rem}.-ml-56{margin-left:-14rem}.-mt-64{margin-top:-16rem}.-mr-64{margin-right:-16rem}.-mb-64{margin-bottom:-16rem}.-ml-64{margin-left:-16rem}.-mt-px{margin-top:-1px}.-mr-px{margin-right:-1px}.-mb-px{margin-bottom:-1px}.-ml-px{margin-left:-1px}.max-h-full{max-height:100%}.max-h-screen{max-height:100vh}.max-w-none{max-width:none}.max-w-xs{max-width:20rem}.max-w-sm{max-width:24rem}.max-w-md{max-width:28rem}.max-w-lg{max-width:32rem}.max-w-xl{max-width:36rem}.max-w-2xl{max-width:42rem}.max-w-3xl{max-width:48rem}.max-w-4xl{max-width:56rem}.max-w-5xl{max-width:64rem}.max-w-6xl{max-width:72rem}.max-w-full{max-width:100%}.max-w-screen-sm{max-width:640px}.max-w-screen-md{max-width:768px}.max-w-screen-lg{max-width:1024px}.max-w-screen-xl{max-width:1280px}.min-h-0{min-height:0}.min-h-full{min-height:100%}.min-h-screen{min-height:100vh}.min-w-0{min-width:0}.min-w-full{min-width:100%}.object-contain{object-fit:contain}.object-cover{object-fit:cover}.object-fill{object-fit:fill}.object-none{object-fit:none}.object-scale-down{object-fit:scale-down}.object-bottom{object-position:bottom}.object-center{object-position:center}.object-left{object-position:left}.object-left-bottom{object-position:left bottom}.object-left-top{object-position:left top}.object-right{object-position:right}.object-right-bottom{object-position:right bottom}.object-right-top{object-position:right top}.object-top{object-position:top}.opacity-0{opacity:0}.opacity-25{opacity:.25}.opacity-50{opacity:.5}.opacity-75{opacity:.75}.opacity-100{opacity:1}.hover\:opacity-0:hover{opacity:0}.hover\:opacity-25:hover{opacity:.25}.hover\:opacity-50:hover{opacity:.5}.hover\:opacity-75:hover{opacity:.75}.hover\:opacity-100:hover{opacity:1}.focus\:opacity-0:focus{opacity:0}.focus\:opacity-25:focus{opacity:.25}.focus\:opacity-50:focus{opacity:.5}.focus\:opacity-75:focus{opacity:.75}.focus\:opacity-100:focus{opacity:1}.outline-none{outline:2px solid transparent;outline-offset:2px}.outline-white{outline:2px dotted #fff;outline-offset:2px}.outline-black{outline:2px dotted #000;outline-offset:2px}.focus\:outline-none:focus{outline:2px solid transparent;outline-offset:2px}.focus\:outline-white:focus{outline:2px dotted #fff;outline-offset:2px}.focus\:outline-black:focus{outline:2px dotted #000;outline-offset:2px}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-visible{overflow:visible}.overflow-scroll{overflow:scroll}.overflow-x-auto{overflow-x:auto}.overflow-y-auto{overflow-y:auto}.overflow-x-hidden{overflow-x:hidden}.overflow-y-hidden{overflow-y:hidden}.overflow-x-visible{overflow-x:visible}.overflow-y-visible{overflow-y:visible}.overflow-x-scroll{overflow-x:scroll}.overflow-y-scroll{overflow-y:scroll}.scrolling-touch{-webkit-overflow-scrolling:touch}.scrolling-auto{-webkit-overflow-scrolling:auto}.overscroll-auto{-ms-scroll-chaining:chained;overscroll-behavior:auto}.overscroll-contain{-ms-scroll-chaining:none;overscroll-behavior:contain}.overscroll-none{-ms-scroll-chaining:none;overscroll-behavior:none}.overscroll-y-auto{overscroll-behavior-y:auto}.overscroll-y-contain{overscroll-behavior-y:contain}.overscroll-y-none{overscroll-behavior-y:none}.overscroll-x-auto{overscroll-behavior-x:auto}.overscroll-x-contain{overscroll-behavior-x:contain}.overscroll-x-none{overscroll-behavior-x:none}.p-0{padding:0}.p-1{padding:.25rem}.p-2{padding:.5rem}.p-3{padding:.75rem}.p-4{padding:1rem}.p-5{padding:1.25rem}.p-6{padding:1.5rem}.p-8{padding:2rem}.p-10{padding:2.5rem}.p-12{padding:3rem}.p-16{padding:4rem}.p-20{padding:5rem}.p-24{padding:6rem}.p-32{padding:8rem}.p-40{padding:10rem}.p-48{padding:12rem}.p-56{padding:14rem}.p-64{padding:16rem}.p-px{padding:1px}.py-0{padding-top:0;padding-bottom:0}.px-0{padding-left:0;padding-right:0}.py-1{padding-top:.25rem;padding-bottom:.25rem}.px-1{padding-left:.25rem;padding-right:.25rem}.py-2{padding-top:.5rem;padding-bottom:.5rem}.px-2{padding-left:.5rem;padding-right:.5rem}.py-3{padding-top:.75rem;padding-bottom:.75rem}.px-3{padding-left:.75rem;padding-right:.75rem}.py-4{padding-top:1rem;padding-bottom:1rem}.px-4{padding-left:1rem;padding-right:1rem}.py-5{padding-top:1.25rem;padding-bottom:1.25rem}.px-5{padding-left:1.25rem;padding-right:1.25rem}.py-6{padding-top:1.5rem;padding-bottom:1.5rem}.px-6{padding-left:1.5rem;padding-right:1.5rem}.py-8{padding-top:2rem;padding-bottom:2rem}.px-8{padding-left:2rem;padding-right:2rem}.py-10{padding-top:2.5rem;padding-bottom:2.5rem}.px-10{padding-left:2.5rem;padding-right:2.5rem}.py-12{padding-top:3rem;padding-bottom:3rem}.px-12{padding-left:3rem;padding-right:3rem}.py-16{padding-top:4rem;padding-bottom:4rem}.px-16{padding-left:4rem;padding-right:4rem}.py-20{padding-top:5rem;padding-bottom:5rem}.px-20{padding-left:5rem;padding-right:5rem}.py-24{padding-top:6rem;padding-bottom:6rem}.px-24{padding-left:6rem;padding-right:6rem}.py-32{padding-top:8rem;padding-bottom:8rem}.px-32{padding-left:8rem;padding-right:8rem}.py-40{padding-top:10rem;padding-bottom:10rem}.px-40{padding-left:10rem;padding-right:10rem}.py-48{padding-top:12rem;padding-bottom:12rem}.px-48{padding-left:12rem;padding-right:12rem}.py-56{padding-top:14rem;padding-bottom:14rem}.px-56{padding-left:14rem;padding-right:14rem}.py-64{padding-top:16rem;padding-bottom:16rem}.px-64{padding-left:16rem;padding-right:16rem}.py-px{padding-top:1px;padding-bottom:1px}.px-px{padding-left:1px;padding-right:1px}.pt-0{padding-top:0}.pr-0{padding-right:0}.pb-0{padding-bottom:0}.pl-0{padding-left:0}.pt-1{padding-top:.25rem}.pr-1{padding-right:.25rem}.pb-1{padding-bottom:.25rem}.pl-1{padding-left:.25rem}.pt-2{padding-top:.5rem}.pr-2{padding-right:.5rem}.pb-2{padding-bottom:.5rem}.pl-2{padding-left:.5rem}.pt-3{padding-top:.75rem}.pr-3{padding-right:.75rem}.pb-3{padding-bottom:.75rem}.pl-3{padding-left:.75rem}.pt-4{padding-top:1rem}.pr-4{padding-right:1rem}.pb-4{padding-bottom:1rem}.pl-4{padding-left:1rem}.pt-5{padding-top:1.25rem}.pr-5{padding-right:1.25rem}.pb-5{padding-bottom:1.25rem}.pl-5{padding-left:1.25rem}.pt-6{padding-top:1.5rem}.pr-6{padding-right:1.5rem}.pb-6{padding-bottom:1.5rem}.pl-6{padding-left:1.5rem}.pt-8{padding-top:2rem}.pr-8{padding-right:2rem}.pb-8{padding-bottom:2rem}.pl-8{padding-left:2rem}.pt-10{padding-top:2.5rem}.pr-10{padding-right:2.5rem}.pb-10{padding-bottom:2.5rem}.pl-10{padding-left:2.5rem}.pt-12{padding-top:3rem}.pr-12{padding-right:3rem}.pb-12{padding-bottom:3rem}.pl-12{padding-left:3rem}.pt-16{padding-top:4rem}.pr-16{padding-right:4rem}.pb-16{padding-bottom:4rem}.pl-16{padding-left:4rem}.pt-20{padding-top:5rem}.pr-20{padding-right:5rem}.pb-20{padding-bottom:5rem}.pl-20{padding-left:5rem}.pt-24{padding-top:6rem}.pr-24{padding-right:6rem}.pb-24{padding-bottom:6rem}.pl-24{padding-left:6rem}.pt-32{padding-top:8rem}.pr-32{padding-right:8rem}.pb-32{padding-bottom:8rem}.pl-32{padding-left:8rem}.pt-40{padding-top:10rem}.pr-40{padding-right:10rem}.pb-40{padding-bottom:10rem}.pl-40{padding-left:10rem}.pt-48{padding-top:12rem}.pr-48{padding-right:12rem}.pb-48{padding-bottom:12rem}.pl-48{padding-left:12rem}.pt-56{padding-top:14rem}.pr-56{padding-right:14rem}.pb-56{padding-bottom:14rem}.pl-56{padding-left:14rem}.pt-64{padding-top:16rem}.pr-64{padding-right:16rem}.pb-64{padding-bottom:16rem}.pl-64{padding-left:16rem}.pt-px{padding-top:1px}.pr-px{padding-right:1px}.pb-px{padding-bottom:1px}.pl-px{padding-left:1px}.placeholder-transparent:-ms-input-placeholder{color:transparent}.placeholder-transparent::-ms-input-placeholder{color:transparent}.placeholder-transparent::placeholder{color:transparent}.placeholder-current:-ms-input-placeholder{color:currentColor}.placeholder-current::-ms-input-placeholder{color:currentColor}.placeholder-current::placeholder{color:currentColor}.placeholder-black:-ms-input-placeholder{--placeholder-opacity:1;color:#000;color:rgba(0,0,0,var(--placeholder-opacity))}.placeholder-black::-ms-input-placeholder{--placeholder-opacity:1;color:#000;color:rgba(0,0,0,var(--placeholder-opacity))}.placeholder-black::placeholder{--placeholder-opacity:1;color:#000;color:rgba(0,0,0,var(--placeholder-opacity))}.placeholder-white:-ms-input-placeholder{--placeholder-opacity:1;color:#fff;color:rgba(255,255,255,var(--placeholder-opacity))}.placeholder-white::-ms-input-placeholder{--placeholder-opacity:1;color:#fff;color:rgba(255,255,255,var(--placeholder-opacity))}.placeholder-white::placeholder{--placeholder-opacity:1;color:#fff;color:rgba(255,255,255,var(--placeholder-opacity))}.placeholder-gray-100:-ms-input-placeholder{--placeholder-opacity:1;color:#f7fafc;color:rgba(247,250,252,var(--placeholder-opacity))}.placeholder-gray-100::-ms-input-placeholder{--placeholder-opacity:1;color:#f7fafc;color:rgba(247,250,252,var(--placeholder-opacity))}.placeholder-gray-100::placeholder{--placeholder-opacity:1;color:#f7fafc;color:rgba(247,250,252,var(--placeholder-opacity))}.placeholder-gray-200:-ms-input-placeholder{--placeholder-opacity:1;color:#edf2f7;color:rgba(237,242,247,var(--placeholder-opacity))}.placeholder-gray-200::-ms-input-placeholder{--placeholder-opacity:1;color:#edf2f7;color:rgba(237,242,247,var(--placeholder-opacity))}.placeholder-gray-200::placeholder{--placeholder-opacity:1;color:#edf2f7;color:rgba(237,242,247,var(--placeholder-opacity))}.placeholder-gray-300:-ms-input-placeholder{--placeholder-opacity:1;color:#e2e8f0;color:rgba(226,232,240,var(--placeholder-opacity))}.placeholder-gray-300::-ms-input-placeholder{--placeholder-opacity:1;color:#e2e8f0;color:rgba(226,232,240,var(--placeholder-opacity))}.placeholder-gray-300::placeholder{--placeholder-opacity:1;color:#e2e8f0;color:rgba(226,232,240,var(--placeholder-opacity))}.placeholder-gray-400:-ms-input-placeholder{--placeholder-opacity:1;color:#cbd5e0;color:rgba(203,213,224,var(--placeholder-opacity))}.placeholder-gray-400::-ms-input-placeholder{--placeholder-opacity:1;color:#cbd5e0;color:rgba(203,213,224,var(--placeholder-opacity))}.placeholder-gray-400::placeholder{--placeholder-opacity:1;color:#cbd5e0;color:rgba(203,213,224,var(--placeholder-opacity))}.placeholder-gray-500:-ms-input-placeholder{--placeholder-opacity:1;color:#a0aec0;color:rgba(160,174,192,var(--placeholder-opacity))}.placeholder-gray-500::-ms-input-placeholder{--placeholder-opacity:1;color:#a0aec0;color:rgba(160,174,192,var(--placeholder-opacity))}.placeholder-gray-500::placeholder{--placeholder-opacity:1;color:#a0aec0;color:rgba(160,174,192,var(--placeholder-opacity))}.placeholder-gray-600:-ms-input-placeholder{--placeholder-opacity:1;color:#718096;color:rgba(113,128,150,var(--placeholder-opacity))}.placeholder-gray-600::-ms-input-placeholder{--placeholder-opacity:1;color:#718096;color:rgba(113,128,150,var(--placeholder-opacity))}.placeholder-gray-600::placeholder{--placeholder-opacity:1;color:#718096;color:rgba(113,128,150,var(--placeholder-opacity))}.placeholder-gray-700:-ms-input-placeholder{--placeholder-opacity:1;color:#4a5568;color:rgba(74,85,104,var(--placeholder-opacity))}.placeholder-gray-700::-ms-input-placeholder{--placeholder-opacity:1;color:#4a5568;color:rgba(74,85,104,var(--placeholder-opacity))}.placeholder-gray-700::placeholder{--placeholder-opacity:1;color:#4a5568;color:rgba(74,85,104,var(--placeholder-opacity))}.placeholder-gray-800:-ms-input-placeholder{--placeholder-opacity:1;color:#2d3748;color:rgba(45,55,72,var(--placeholder-opacity))}.placeholder-gray-800::-ms-input-placeholder{--placeholder-opacity:1;color:#2d3748;color:rgba(45,55,72,var(--placeholder-opacity))}.placeholder-gray-800::placeholder{--placeholder-opacity:1;color:#2d3748;color:rgba(45,55,72,var(--placeholder-opacity))}.placeholder-gray-900:-ms-input-placeholder{--placeholder-opacity:1;color:#1a202c;color:rgba(26,32,44,var(--placeholder-opacity))}.placeholder-gray-900::-ms-input-placeholder{--placeholder-opacity:1;color:#1a202c;color:rgba(26,32,44,var(--placeholder-opacity))}.placeholder-gray-900::placeholder{--placeholder-opacity:1;color:#1a202c;color:rgba(26,32,44,var(--placeholder-opacity))}.placeholder-red-100:-ms-input-placeholder{--placeholder-opacity:1;color:#fff5f5;color:rgba(255,245,245,var(--placeholder-opacity))}.placeholder-red-100::-ms-input-placeholder{--placeholder-opacity:1;color:#fff5f5;color:rgba(255,245,245,var(--placeholder-opacity))}.placeholder-red-100::placeholder{--placeholder-opacity:1;color:#fff5f5;color:rgba(255,245,245,var(--placeholder-opacity))}.placeholder-red-200:-ms-input-placeholder{--placeholder-opacity:1;color:#fed7d7;color:rgba(254,215,215,var(--placeholder-opacity))}.placeholder-red-200::-ms-input-placeholder{--placeholder-opacity:1;color:#fed7d7;color:rgba(254,215,215,var(--placeholder-opacity))}.placeholder-red-200::placeholder{--placeholder-opacity:1;color:#fed7d7;color:rgba(254,215,215,var(--placeholder-opacity))}.placeholder-red-300:-ms-input-placeholder{--placeholder-opacity:1;color:#feb2b2;color:rgba(254,178,178,var(--placeholder-opacity))}.placeholder-red-300::-ms-input-placeholder{--placeholder-opacity:1;color:#feb2b2;color:rgba(254,178,178,var(--placeholder-opacity))}.placeholder-red-300::placeholder{--placeholder-opacity:1;color:#feb2b2;color:rgba(254,178,178,var(--placeholder-opacity))}.placeholder-red-400:-ms-input-placeholder{--placeholder-opacity:1;color:#fc8181;color:rgba(252,129,129,var(--placeholder-opacity))}.placeholder-red-400::-ms-input-placeholder{--placeholder-opacity:1;color:#fc8181;color:rgba(252,129,129,var(--placeholder-opacity))}.placeholder-red-400::placeholder{--placeholder-opacity:1;color:#fc8181;color:rgba(252,129,129,var(--placeholder-opacity))}.placeholder-red-500:-ms-input-placeholder{--placeholder-opacity:1;color:#f56565;color:rgba(245,101,101,var(--placeholder-opacity))}.placeholder-red-500::-ms-input-placeholder{--placeholder-opacity:1;color:#f56565;color:rgba(245,101,101,var(--placeholder-opacity))}.placeholder-red-500::placeholder{--placeholder-opacity:1;color:#f56565;color:rgba(245,101,101,var(--placeholder-opacity))}.placeholder-red-600:-ms-input-placeholder{--placeholder-opacity:1;color:#e53e3e;color:rgba(229,62,62,var(--placeholder-opacity))}.placeholder-red-600::-ms-input-placeholder{--placeholder-opacity:1;color:#e53e3e;color:rgba(229,62,62,var(--placeholder-opacity))}.placeholder-red-600::placeholder{--placeholder-opacity:1;color:#e53e3e;color:rgba(229,62,62,var(--placeholder-opacity))}.placeholder-red-700:-ms-input-placeholder{--placeholder-opacity:1;color:#c53030;color:rgba(197,48,48,var(--placeholder-opacity))}.placeholder-red-700::-ms-input-placeholder{--placeholder-opacity:1;color:#c53030;color:rgba(197,48,48,var(--placeholder-opacity))}.placeholder-red-700::placeholder{--placeholder-opacity:1;color:#c53030;color:rgba(197,48,48,var(--placeholder-opacity))}.placeholder-red-800:-ms-input-placeholder{--placeholder-opacity:1;color:#9b2c2c;color:rgba(155,44,44,var(--placeholder-opacity))}.placeholder-red-800::-ms-input-placeholder{--placeholder-opacity:1;color:#9b2c2c;color:rgba(155,44,44,var(--placeholder-opacity))}.placeholder-red-800::placeholder{--placeholder-opacity:1;color:#9b2c2c;color:rgba(155,44,44,var(--placeholder-opacity))}.placeholder-red-900:-ms-input-placeholder{--placeholder-opacity:1;color:#742a2a;color:rgba(116,42,42,var(--placeholder-opacity))}.placeholder-red-900::-ms-input-placeholder{--placeholder-opacity:1;color:#742a2a;color:rgba(116,42,42,var(--placeholder-opacity))}.placeholder-red-900::placeholder{--placeholder-opacity:1;color:#742a2a;color:rgba(116,42,42,var(--placeholder-opacity))}.placeholder-orange-100:-ms-input-placeholder{--placeholder-opacity:1;color:#fffaf0;color:rgba(255,250,240,var(--placeholder-opacity))}.placeholder-orange-100::-ms-input-placeholder{--placeholder-opacity:1;color:#fffaf0;color:rgba(255,250,240,var(--placeholder-opacity))}.placeholder-orange-100::placeholder{--placeholder-opacity:1;color:#fffaf0;color:rgba(255,250,240,var(--placeholder-opacity))}.placeholder-orange-200:-ms-input-placeholder{--placeholder-opacity:1;color:#feebc8;color:rgba(254,235,200,var(--placeholder-opacity))}.placeholder-orange-200::-ms-input-placeholder{--placeholder-opacity:1;color:#feebc8;color:rgba(254,235,200,var(--placeholder-opacity))}.placeholder-orange-200::placeholder{--placeholder-opacity:1;color:#feebc8;color:rgba(254,235,200,var(--placeholder-opacity))}.placeholder-orange-300:-ms-input-placeholder{--placeholder-opacity:1;color:#fbd38d;color:rgba(251,211,141,var(--placeholder-opacity))}.placeholder-orange-300::-ms-input-placeholder{--placeholder-opacity:1;color:#fbd38d;color:rgba(251,211,141,var(--placeholder-opacity))}.placeholder-orange-300::placeholder{--placeholder-opacity:1;color:#fbd38d;color:rgba(251,211,141,var(--placeholder-opacity))}.placeholder-orange-400:-ms-input-placeholder{--placeholder-opacity:1;color:#f6ad55;color:rgba(246,173,85,var(--placeholder-opacity))}.placeholder-orange-400::-ms-input-placeholder{--placeholder-opacity:1;color:#f6ad55;color:rgba(246,173,85,var(--placeholder-opacity))}.placeholder-orange-400::placeholder{--placeholder-opacity:1;color:#f6ad55;color:rgba(246,173,85,var(--placeholder-opacity))}.placeholder-orange-500:-ms-input-placeholder{--placeholder-opacity:1;color:#ed8936;color:rgba(237,137,54,var(--placeholder-opacity))}.placeholder-orange-500::-ms-input-placeholder{--placeholder-opacity:1;color:#ed8936;color:rgba(237,137,54,var(--placeholder-opacity))}.placeholder-orange-500::placeholder{--placeholder-opacity:1;color:#ed8936;color:rgba(237,137,54,var(--placeholder-opacity))}.placeholder-orange-600:-ms-input-placeholder{--placeholder-opacity:1;color:#dd6b20;color:rgba(221,107,32,var(--placeholder-opacity))}.placeholder-orange-600::-ms-input-placeholder{--placeholder-opacity:1;color:#dd6b20;color:rgba(221,107,32,var(--placeholder-opacity))}.placeholder-orange-600::placeholder{--placeholder-opacity:1;color:#dd6b20;color:rgba(221,107,32,var(--placeholder-opacity))}.placeholder-orange-700:-ms-input-placeholder{--placeholder-opacity:1;color:#c05621;color:rgba(192,86,33,var(--placeholder-opacity))}.placeholder-orange-700::-ms-input-placeholder{--placeholder-opacity:1;color:#c05621;color:rgba(192,86,33,var(--placeholder-opacity))}.placeholder-orange-700::placeholder{--placeholder-opacity:1;color:#c05621;color:rgba(192,86,33,var(--placeholder-opacity))}.placeholder-orange-800:-ms-input-placeholder{--placeholder-opacity:1;color:#9c4221;color:rgba(156,66,33,var(--placeholder-opacity))}.placeholder-orange-800::-ms-input-placeholder{--placeholder-opacity:1;color:#9c4221;color:rgba(156,66,33,var(--placeholder-opacity))}.placeholder-orange-800::placeholder{--placeholder-opacity:1;color:#9c4221;color:rgba(156,66,33,var(--placeholder-opacity))}.placeholder-orange-900:-ms-input-placeholder{--placeholder-opacity:1;color:#7b341e;color:rgba(123,52,30,var(--placeholder-opacity))}.placeholder-orange-900::-ms-input-placeholder{--placeholder-opacity:1;color:#7b341e;color:rgba(123,52,30,var(--placeholder-opacity))}.placeholder-orange-900::placeholder{--placeholder-opacity:1;color:#7b341e;color:rgba(123,52,30,var(--placeholder-opacity))}.placeholder-yellow-100:-ms-input-placeholder{--placeholder-opacity:1;color:ivory;color:rgba(255,255,240,var(--placeholder-opacity))}.placeholder-yellow-100::-ms-input-placeholder{--placeholder-opacity:1;color:ivory;color:rgba(255,255,240,var(--placeholder-opacity))}.placeholder-yellow-100::placeholder{--placeholder-opacity:1;color:ivory;color:rgba(255,255,240,var(--placeholder-opacity))}.placeholder-yellow-200:-ms-input-placeholder{--placeholder-opacity:1;color:#fefcbf;color:rgba(254,252,191,var(--placeholder-opacity))}.placeholder-yellow-200::-ms-input-placeholder{--placeholder-opacity:1;color:#fefcbf;color:rgba(254,252,191,var(--placeholder-opacity))}.placeholder-yellow-200::placeholder{--placeholder-opacity:1;color:#fefcbf;color:rgba(254,252,191,var(--placeholder-opacity))}.placeholder-yellow-300:-ms-input-placeholder{--placeholder-opacity:1;color:#faf089;color:rgba(250,240,137,var(--placeholder-opacity))}.placeholder-yellow-300::-ms-input-placeholder{--placeholder-opacity:1;color:#faf089;color:rgba(250,240,137,var(--placeholder-opacity))}.placeholder-yellow-300::placeholder{--placeholder-opacity:1;color:#faf089;color:rgba(250,240,137,var(--placeholder-opacity))}.placeholder-yellow-400:-ms-input-placeholder{--placeholder-opacity:1;color:#f6e05e;color:rgba(246,224,94,var(--placeholder-opacity))}.placeholder-yellow-400::-ms-input-placeholder{--placeholder-opacity:1;color:#f6e05e;color:rgba(246,224,94,var(--placeholder-opacity))}.placeholder-yellow-400::placeholder{--placeholder-opacity:1;color:#f6e05e;color:rgba(246,224,94,var(--placeholder-opacity))}.placeholder-yellow-500:-ms-input-placeholder{--placeholder-opacity:1;color:#ecc94b;color:rgba(236,201,75,var(--placeholder-opacity))}.placeholder-yellow-500::-ms-input-placeholder{--placeholder-opacity:1;color:#ecc94b;color:rgba(236,201,75,var(--placeholder-opacity))}.placeholder-yellow-500::placeholder{--placeholder-opacity:1;color:#ecc94b;color:rgba(236,201,75,var(--placeholder-opacity))}.placeholder-yellow-600:-ms-input-placeholder{--placeholder-opacity:1;color:#d69e2e;color:rgba(214,158,46,var(--placeholder-opacity))}.placeholder-yellow-600::-ms-input-placeholder{--placeholder-opacity:1;color:#d69e2e;color:rgba(214,158,46,var(--placeholder-opacity))}.placeholder-yellow-600::placeholder{--placeholder-opacity:1;color:#d69e2e;color:rgba(214,158,46,var(--placeholder-opacity))}.placeholder-yellow-700:-ms-input-placeholder{--placeholder-opacity:1;color:#b7791f;color:rgba(183,121,31,var(--placeholder-opacity))}.placeholder-yellow-700::-ms-input-placeholder{--placeholder-opacity:1;color:#b7791f;color:rgba(183,121,31,var(--placeholder-opacity))}.placeholder-yellow-700::placeholder{--placeholder-opacity:1;color:#b7791f;color:rgba(183,121,31,var(--placeholder-opacity))}.placeholder-yellow-800:-ms-input-placeholder{--placeholder-opacity:1;color:#975a16;color:rgba(151,90,22,var(--placeholder-opacity))}.placeholder-yellow-800::-ms-input-placeholder{--placeholder-opacity:1;color:#975a16;color:rgba(151,90,22,var(--placeholder-opacity))}.placeholder-yellow-800::placeholder{--placeholder-opacity:1;color:#975a16;color:rgba(151,90,22,var(--placeholder-opacity))}.placeholder-yellow-900:-ms-input-placeholder{--placeholder-opacity:1;color:#744210;color:rgba(116,66,16,var(--placeholder-opacity))}.placeholder-yellow-900::-ms-input-placeholder{--placeholder-opacity:1;color:#744210;color:rgba(116,66,16,var(--placeholder-opacity))}.placeholder-yellow-900::placeholder{--placeholder-opacity:1;color:#744210;color:rgba(116,66,16,var(--placeholder-opacity))}.placeholder-green-100:-ms-input-placeholder{--placeholder-opacity:1;color:#f0fff4;color:rgba(240,255,244,var(--placeholder-opacity))}.placeholder-green-100::-ms-input-placeholder{--placeholder-opacity:1;color:#f0fff4;color:rgba(240,255,244,var(--placeholder-opacity))}.placeholder-green-100::placeholder{--placeholder-opacity:1;color:#f0fff4;color:rgba(240,255,244,var(--placeholder-opacity))}.placeholder-green-200:-ms-input-placeholder{--placeholder-opacity:1;color:#c6f6d5;color:rgba(198,246,213,var(--placeholder-opacity))}.placeholder-green-200::-ms-input-placeholder{--placeholder-opacity:1;color:#c6f6d5;color:rgba(198,246,213,var(--placeholder-opacity))}.placeholder-green-200::placeholder{--placeholder-opacity:1;color:#c6f6d5;color:rgba(198,246,213,var(--placeholder-opacity))}.placeholder-green-300:-ms-input-placeholder{--placeholder-opacity:1;color:#9ae6b4;color:rgba(154,230,180,var(--placeholder-opacity))}.placeholder-green-300::-ms-input-placeholder{--placeholder-opacity:1;color:#9ae6b4;color:rgba(154,230,180,var(--placeholder-opacity))}.placeholder-green-300::placeholder{--placeholder-opacity:1;color:#9ae6b4;color:rgba(154,230,180,var(--placeholder-opacity))}.placeholder-green-400:-ms-input-placeholder{--placeholder-opacity:1;color:#68d391;color:rgba(104,211,145,var(--placeholder-opacity))}.placeholder-green-400::-ms-input-placeholder{--placeholder-opacity:1;color:#68d391;color:rgba(104,211,145,var(--placeholder-opacity))}.placeholder-green-400::placeholder{--placeholder-opacity:1;color:#68d391;color:rgba(104,211,145,var(--placeholder-opacity))}.placeholder-green-500:-ms-input-placeholder{--placeholder-opacity:1;color:#48bb78;color:rgba(72,187,120,var(--placeholder-opacity))}.placeholder-green-500::-ms-input-placeholder{--placeholder-opacity:1;color:#48bb78;color:rgba(72,187,120,var(--placeholder-opacity))}.placeholder-green-500::placeholder{--placeholder-opacity:1;color:#48bb78;color:rgba(72,187,120,var(--placeholder-opacity))}.placeholder-green-600:-ms-input-placeholder{--placeholder-opacity:1;color:#38a169;color:rgba(56,161,105,var(--placeholder-opacity))}.placeholder-green-600::-ms-input-placeholder{--placeholder-opacity:1;color:#38a169;color:rgba(56,161,105,var(--placeholder-opacity))}.placeholder-green-600::placeholder{--placeholder-opacity:1;color:#38a169;color:rgba(56,161,105,var(--placeholder-opacity))}.placeholder-green-700:-ms-input-placeholder{--placeholder-opacity:1;color:#2f855a;color:rgba(47,133,90,var(--placeholder-opacity))}.placeholder-green-700::-ms-input-placeholder{--placeholder-opacity:1;color:#2f855a;color:rgba(47,133,90,var(--placeholder-opacity))}.placeholder-green-700::placeholder{--placeholder-opacity:1;color:#2f855a;color:rgba(47,133,90,var(--placeholder-opacity))}.placeholder-green-800:-ms-input-placeholder{--placeholder-opacity:1;color:#276749;color:rgba(39,103,73,var(--placeholder-opacity))}.placeholder-green-800::-ms-input-placeholder{--placeholder-opacity:1;color:#276749;color:rgba(39,103,73,var(--placeholder-opacity))}.placeholder-green-800::placeholder{--placeholder-opacity:1;color:#276749;color:rgba(39,103,73,var(--placeholder-opacity))}.placeholder-green-900:-ms-input-placeholder{--placeholder-opacity:1;color:#22543d;color:rgba(34,84,61,var(--placeholder-opacity))}.placeholder-green-900::-ms-input-placeholder{--placeholder-opacity:1;color:#22543d;color:rgba(34,84,61,var(--placeholder-opacity))}.placeholder-green-900::placeholder{--placeholder-opacity:1;color:#22543d;color:rgba(34,84,61,var(--placeholder-opacity))}.placeholder-teal-100:-ms-input-placeholder{--placeholder-opacity:1;color:#e6fffa;color:rgba(230,255,250,var(--placeholder-opacity))}.placeholder-teal-100::-ms-input-placeholder{--placeholder-opacity:1;color:#e6fffa;color:rgba(230,255,250,var(--placeholder-opacity))}.placeholder-teal-100::placeholder{--placeholder-opacity:1;color:#e6fffa;color:rgba(230,255,250,var(--placeholder-opacity))}.placeholder-teal-200:-ms-input-placeholder{--placeholder-opacity:1;color:#b2f5ea;color:rgba(178,245,234,var(--placeholder-opacity))}.placeholder-teal-200::-ms-input-placeholder{--placeholder-opacity:1;color:#b2f5ea;color:rgba(178,245,234,var(--placeholder-opacity))}.placeholder-teal-200::placeholder{--placeholder-opacity:1;color:#b2f5ea;color:rgba(178,245,234,var(--placeholder-opacity))}.placeholder-teal-300:-ms-input-placeholder{--placeholder-opacity:1;color:#81e6d9;color:rgba(129,230,217,var(--placeholder-opacity))}.placeholder-teal-300::-ms-input-placeholder{--placeholder-opacity:1;color:#81e6d9;color:rgba(129,230,217,var(--placeholder-opacity))}.placeholder-teal-300::placeholder{--placeholder-opacity:1;color:#81e6d9;color:rgba(129,230,217,var(--placeholder-opacity))}.placeholder-teal-400:-ms-input-placeholder{--placeholder-opacity:1;color:#4fd1c5;color:rgba(79,209,197,var(--placeholder-opacity))}.placeholder-teal-400::-ms-input-placeholder{--placeholder-opacity:1;color:#4fd1c5;color:rgba(79,209,197,var(--placeholder-opacity))}.placeholder-teal-400::placeholder{--placeholder-opacity:1;color:#4fd1c5;color:rgba(79,209,197,var(--placeholder-opacity))}.placeholder-teal-500:-ms-input-placeholder{--placeholder-opacity:1;color:#38b2ac;color:rgba(56,178,172,var(--placeholder-opacity))}.placeholder-teal-500::-ms-input-placeholder{--placeholder-opacity:1;color:#38b2ac;color:rgba(56,178,172,var(--placeholder-opacity))}.placeholder-teal-500::placeholder{--placeholder-opacity:1;color:#38b2ac;color:rgba(56,178,172,var(--placeholder-opacity))}.placeholder-teal-600:-ms-input-placeholder{--placeholder-opacity:1;color:#319795;color:rgba(49,151,149,var(--placeholder-opacity))}.placeholder-teal-600::-ms-input-placeholder{--placeholder-opacity:1;color:#319795;color:rgba(49,151,149,var(--placeholder-opacity))}.placeholder-teal-600::placeholder{--placeholder-opacity:1;color:#319795;color:rgba(49,151,149,var(--placeholder-opacity))}.placeholder-teal-700:-ms-input-placeholder{--placeholder-opacity:1;color:#2c7a7b;color:rgba(44,122,123,var(--placeholder-opacity))}.placeholder-teal-700::-ms-input-placeholder{--placeholder-opacity:1;color:#2c7a7b;color:rgba(44,122,123,var(--placeholder-opacity))}.placeholder-teal-700::placeholder{--placeholder-opacity:1;color:#2c7a7b;color:rgba(44,122,123,var(--placeholder-opacity))}.placeholder-teal-800:-ms-input-placeholder{--placeholder-opacity:1;color:#285e61;color:rgba(40,94,97,var(--placeholder-opacity))}.placeholder-teal-800::-ms-input-placeholder{--placeholder-opacity:1;color:#285e61;color:rgba(40,94,97,var(--placeholder-opacity))}.placeholder-teal-800::placeholder{--placeholder-opacity:1;color:#285e61;color:rgba(40,94,97,var(--placeholder-opacity))}.placeholder-teal-900:-ms-input-placeholder{--placeholder-opacity:1;color:#234e52;color:rgba(35,78,82,var(--placeholder-opacity))}.placeholder-teal-900::-ms-input-placeholder{--placeholder-opacity:1;color:#234e52;color:rgba(35,78,82,var(--placeholder-opacity))}.placeholder-teal-900::placeholder{--placeholder-opacity:1;color:#234e52;color:rgba(35,78,82,var(--placeholder-opacity))}.placeholder-blue-100:-ms-input-placeholder{--placeholder-opacity:1;color:#ebf8ff;color:rgba(235,248,255,var(--placeholder-opacity))}.placeholder-blue-100::-ms-input-placeholder{--placeholder-opacity:1;color:#ebf8ff;color:rgba(235,248,255,var(--placeholder-opacity))}.placeholder-blue-100::placeholder{--placeholder-opacity:1;color:#ebf8ff;color:rgba(235,248,255,var(--placeholder-opacity))}.placeholder-blue-200:-ms-input-placeholder{--placeholder-opacity:1;color:#bee3f8;color:rgba(190,227,248,var(--placeholder-opacity))}.placeholder-blue-200::-ms-input-placeholder{--placeholder-opacity:1;color:#bee3f8;color:rgba(190,227,248,var(--placeholder-opacity))}.placeholder-blue-200::placeholder{--placeholder-opacity:1;color:#bee3f8;color:rgba(190,227,248,var(--placeholder-opacity))}.placeholder-blue-300:-ms-input-placeholder{--placeholder-opacity:1;color:#90cdf4;color:rgba(144,205,244,var(--placeholder-opacity))}.placeholder-blue-300::-ms-input-placeholder{--placeholder-opacity:1;color:#90cdf4;color:rgba(144,205,244,var(--placeholder-opacity))}.placeholder-blue-300::placeholder{--placeholder-opacity:1;color:#90cdf4;color:rgba(144,205,244,var(--placeholder-opacity))}.placeholder-blue-400:-ms-input-placeholder{--placeholder-opacity:1;color:#63b3ed;color:rgba(99,179,237,var(--placeholder-opacity))}.placeholder-blue-400::-ms-input-placeholder{--placeholder-opacity:1;color:#63b3ed;color:rgba(99,179,237,var(--placeholder-opacity))}.placeholder-blue-400::placeholder{--placeholder-opacity:1;color:#63b3ed;color:rgba(99,179,237,var(--placeholder-opacity))}.placeholder-blue-500:-ms-input-placeholder{--placeholder-opacity:1;color:#4299e1;color:rgba(66,153,225,var(--placeholder-opacity))}.placeholder-blue-500::-ms-input-placeholder{--placeholder-opacity:1;color:#4299e1;color:rgba(66,153,225,var(--placeholder-opacity))}.placeholder-blue-500::placeholder{--placeholder-opacity:1;color:#4299e1;color:rgba(66,153,225,var(--placeholder-opacity))}.placeholder-blue-600:-ms-input-placeholder{--placeholder-opacity:1;color:#3182ce;color:rgba(49,130,206,var(--placeholder-opacity))}.placeholder-blue-600::-ms-input-placeholder{--placeholder-opacity:1;color:#3182ce;color:rgba(49,130,206,var(--placeholder-opacity))}.placeholder-blue-600::placeholder{--placeholder-opacity:1;color:#3182ce;color:rgba(49,130,206,var(--placeholder-opacity))}.placeholder-blue-700:-ms-input-placeholder{--placeholder-opacity:1;color:#2b6cb0;color:rgba(43,108,176,var(--placeholder-opacity))}.placeholder-blue-700::-ms-input-placeholder{--placeholder-opacity:1;color:#2b6cb0;color:rgba(43,108,176,var(--placeholder-opacity))}.placeholder-blue-700::placeholder{--placeholder-opacity:1;color:#2b6cb0;color:rgba(43,108,176,var(--placeholder-opacity))}.placeholder-blue-800:-ms-input-placeholder{--placeholder-opacity:1;color:#2c5282;color:rgba(44,82,130,var(--placeholder-opacity))}.placeholder-blue-800::-ms-input-placeholder{--placeholder-opacity:1;color:#2c5282;color:rgba(44,82,130,var(--placeholder-opacity))}.placeholder-blue-800::placeholder{--placeholder-opacity:1;color:#2c5282;color:rgba(44,82,130,var(--placeholder-opacity))}.placeholder-blue-900:-ms-input-placeholder{--placeholder-opacity:1;color:#2a4365;color:rgba(42,67,101,var(--placeholder-opacity))}.placeholder-blue-900::-ms-input-placeholder{--placeholder-opacity:1;color:#2a4365;color:rgba(42,67,101,var(--placeholder-opacity))}.placeholder-blue-900::placeholder{--placeholder-opacity:1;color:#2a4365;color:rgba(42,67,101,var(--placeholder-opacity))}.placeholder-indigo-100:-ms-input-placeholder{--placeholder-opacity:1;color:#ebf4ff;color:rgba(235,244,255,var(--placeholder-opacity))}.placeholder-indigo-100::-ms-input-placeholder{--placeholder-opacity:1;color:#ebf4ff;color:rgba(235,244,255,var(--placeholder-opacity))}.placeholder-indigo-100::placeholder{--placeholder-opacity:1;color:#ebf4ff;color:rgba(235,244,255,var(--placeholder-opacity))}.placeholder-indigo-200:-ms-input-placeholder{--placeholder-opacity:1;color:#c3dafe;color:rgba(195,218,254,var(--placeholder-opacity))}.placeholder-indigo-200::-ms-input-placeholder{--placeholder-opacity:1;color:#c3dafe;color:rgba(195,218,254,var(--placeholder-opacity))}.placeholder-indigo-200::placeholder{--placeholder-opacity:1;color:#c3dafe;color:rgba(195,218,254,var(--placeholder-opacity))}.placeholder-indigo-300:-ms-input-placeholder{--placeholder-opacity:1;color:#a3bffa;color:rgba(163,191,250,var(--placeholder-opacity))}.placeholder-indigo-300::-ms-input-placeholder{--placeholder-opacity:1;color:#a3bffa;color:rgba(163,191,250,var(--placeholder-opacity))}.placeholder-indigo-300::placeholder{--placeholder-opacity:1;color:#a3bffa;color:rgba(163,191,250,var(--placeholder-opacity))}.placeholder-indigo-400:-ms-input-placeholder{--placeholder-opacity:1;color:#7f9cf5;color:rgba(127,156,245,var(--placeholder-opacity))}.placeholder-indigo-400::-ms-input-placeholder{--placeholder-opacity:1;color:#7f9cf5;color:rgba(127,156,245,var(--placeholder-opacity))}.placeholder-indigo-400::placeholder{--placeholder-opacity:1;color:#7f9cf5;color:rgba(127,156,245,var(--placeholder-opacity))}.placeholder-indigo-500:-ms-input-placeholder{--placeholder-opacity:1;color:#667eea;color:rgba(102,126,234,var(--placeholder-opacity))}.placeholder-indigo-500::-ms-input-placeholder{--placeholder-opacity:1;color:#667eea;color:rgba(102,126,234,var(--placeholder-opacity))}.placeholder-indigo-500::placeholder{--placeholder-opacity:1;color:#667eea;color:rgba(102,126,234,var(--placeholder-opacity))}.placeholder-indigo-600:-ms-input-placeholder{--placeholder-opacity:1;color:#5a67d8;color:rgba(90,103,216,var(--placeholder-opacity))}.placeholder-indigo-600::-ms-input-placeholder{--placeholder-opacity:1;color:#5a67d8;color:rgba(90,103,216,var(--placeholder-opacity))}.placeholder-indigo-600::placeholder{--placeholder-opacity:1;color:#5a67d8;color:rgba(90,103,216,var(--placeholder-opacity))}.placeholder-indigo-700:-ms-input-placeholder{--placeholder-opacity:1;color:#4c51bf;color:rgba(76,81,191,var(--placeholder-opacity))}.placeholder-indigo-700::-ms-input-placeholder{--placeholder-opacity:1;color:#4c51bf;color:rgba(76,81,191,var(--placeholder-opacity))}.placeholder-indigo-700::placeholder{--placeholder-opacity:1;color:#4c51bf;color:rgba(76,81,191,var(--placeholder-opacity))}.placeholder-indigo-800:-ms-input-placeholder{--placeholder-opacity:1;color:#434190;color:rgba(67,65,144,var(--placeholder-opacity))}.placeholder-indigo-800::-ms-input-placeholder{--placeholder-opacity:1;color:#434190;color:rgba(67,65,144,var(--placeholder-opacity))}.placeholder-indigo-800::placeholder{--placeholder-opacity:1;color:#434190;color:rgba(67,65,144,var(--placeholder-opacity))}.placeholder-indigo-900:-ms-input-placeholder{--placeholder-opacity:1;color:#3c366b;color:rgba(60,54,107,var(--placeholder-opacity))}.placeholder-indigo-900::-ms-input-placeholder{--placeholder-opacity:1;color:#3c366b;color:rgba(60,54,107,var(--placeholder-opacity))}.placeholder-indigo-900::placeholder{--placeholder-opacity:1;color:#3c366b;color:rgba(60,54,107,var(--placeholder-opacity))}.placeholder-purple-100:-ms-input-placeholder{--placeholder-opacity:1;color:#faf5ff;color:rgba(250,245,255,var(--placeholder-opacity))}.placeholder-purple-100::-ms-input-placeholder{--placeholder-opacity:1;color:#faf5ff;color:rgba(250,245,255,var(--placeholder-opacity))}.placeholder-purple-100::placeholder{--placeholder-opacity:1;color:#faf5ff;color:rgba(250,245,255,var(--placeholder-opacity))}.placeholder-purple-200:-ms-input-placeholder{--placeholder-opacity:1;color:#e9d8fd;color:rgba(233,216,253,var(--placeholder-opacity))}.placeholder-purple-200::-ms-input-placeholder{--placeholder-opacity:1;color:#e9d8fd;color:rgba(233,216,253,var(--placeholder-opacity))}.placeholder-purple-200::placeholder{--placeholder-opacity:1;color:#e9d8fd;color:rgba(233,216,253,var(--placeholder-opacity))}.placeholder-purple-300:-ms-input-placeholder{--placeholder-opacity:1;color:#d6bcfa;color:rgba(214,188,250,var(--placeholder-opacity))}.placeholder-purple-300::-ms-input-placeholder{--placeholder-opacity:1;color:#d6bcfa;color:rgba(214,188,250,var(--placeholder-opacity))}.placeholder-purple-300::placeholder{--placeholder-opacity:1;color:#d6bcfa;color:rgba(214,188,250,var(--placeholder-opacity))}.placeholder-purple-400:-ms-input-placeholder{--placeholder-opacity:1;color:#b794f4;color:rgba(183,148,244,var(--placeholder-opacity))}.placeholder-purple-400::-ms-input-placeholder{--placeholder-opacity:1;color:#b794f4;color:rgba(183,148,244,var(--placeholder-opacity))}.placeholder-purple-400::placeholder{--placeholder-opacity:1;color:#b794f4;color:rgba(183,148,244,var(--placeholder-opacity))}.placeholder-purple-500:-ms-input-placeholder{--placeholder-opacity:1;color:#9f7aea;color:rgba(159,122,234,var(--placeholder-opacity))}.placeholder-purple-500::-ms-input-placeholder{--placeholder-opacity:1;color:#9f7aea;color:rgba(159,122,234,var(--placeholder-opacity))}.placeholder-purple-500::placeholder{--placeholder-opacity:1;color:#9f7aea;color:rgba(159,122,234,var(--placeholder-opacity))}.placeholder-purple-600:-ms-input-placeholder{--placeholder-opacity:1;color:#805ad5;color:rgba(128,90,213,var(--placeholder-opacity))}.placeholder-purple-600::-ms-input-placeholder{--placeholder-opacity:1;color:#805ad5;color:rgba(128,90,213,var(--placeholder-opacity))}.placeholder-purple-600::placeholder{--placeholder-opacity:1;color:#805ad5;color:rgba(128,90,213,var(--placeholder-opacity))}.placeholder-purple-700:-ms-input-placeholder{--placeholder-opacity:1;color:#6b46c1;color:rgba(107,70,193,var(--placeholder-opacity))}.placeholder-purple-700::-ms-input-placeholder{--placeholder-opacity:1;color:#6b46c1;color:rgba(107,70,193,var(--placeholder-opacity))}.placeholder-purple-700::placeholder{--placeholder-opacity:1;color:#6b46c1;color:rgba(107,70,193,var(--placeholder-opacity))}.placeholder-purple-800:-ms-input-placeholder{--placeholder-opacity:1;color:#553c9a;color:rgba(85,60,154,var(--placeholder-opacity))}.placeholder-purple-800::-ms-input-placeholder{--placeholder-opacity:1;color:#553c9a;color:rgba(85,60,154,var(--placeholder-opacity))}.placeholder-purple-800::placeholder{--placeholder-opacity:1;color:#553c9a;color:rgba(85,60,154,var(--placeholder-opacity))}.placeholder-purple-900:-ms-input-placeholder{--placeholder-opacity:1;color:#44337a;color:rgba(68,51,122,var(--placeholder-opacity))}.placeholder-purple-900::-ms-input-placeholder{--placeholder-opacity:1;color:#44337a;color:rgba(68,51,122,var(--placeholder-opacity))}.placeholder-purple-900::placeholder{--placeholder-opacity:1;color:#44337a;color:rgba(68,51,122,var(--placeholder-opacity))}.placeholder-pink-100:-ms-input-placeholder{--placeholder-opacity:1;color:#fff5f7;color:rgba(255,245,247,var(--placeholder-opacity))}.placeholder-pink-100::-ms-input-placeholder{--placeholder-opacity:1;color:#fff5f7;color:rgba(255,245,247,var(--placeholder-opacity))}.placeholder-pink-100::placeholder{--placeholder-opacity:1;color:#fff5f7;color:rgba(255,245,247,var(--placeholder-opacity))}.placeholder-pink-200:-ms-input-placeholder{--placeholder-opacity:1;color:#fed7e2;color:rgba(254,215,226,var(--placeholder-opacity))}.placeholder-pink-200::-ms-input-placeholder{--placeholder-opacity:1;color:#fed7e2;color:rgba(254,215,226,var(--placeholder-opacity))}.placeholder-pink-200::placeholder{--placeholder-opacity:1;color:#fed7e2;color:rgba(254,215,226,var(--placeholder-opacity))}.placeholder-pink-300:-ms-input-placeholder{--placeholder-opacity:1;color:#fbb6ce;color:rgba(251,182,206,var(--placeholder-opacity))}.placeholder-pink-300::-ms-input-placeholder{--placeholder-opacity:1;color:#fbb6ce;color:rgba(251,182,206,var(--placeholder-opacity))}.placeholder-pink-300::placeholder{--placeholder-opacity:1;color:#fbb6ce;color:rgba(251,182,206,var(--placeholder-opacity))}.placeholder-pink-400:-ms-input-placeholder{--placeholder-opacity:1;color:#f687b3;color:rgba(246,135,179,var(--placeholder-opacity))}.placeholder-pink-400::-ms-input-placeholder{--placeholder-opacity:1;color:#f687b3;color:rgba(246,135,179,var(--placeholder-opacity))}.placeholder-pink-400::placeholder{--placeholder-opacity:1;color:#f687b3;color:rgba(246,135,179,var(--placeholder-opacity))}.placeholder-pink-500:-ms-input-placeholder{--placeholder-opacity:1;color:#ed64a6;color:rgba(237,100,166,var(--placeholder-opacity))}.placeholder-pink-500::-ms-input-placeholder{--placeholder-opacity:1;color:#ed64a6;color:rgba(237,100,166,var(--placeholder-opacity))}.placeholder-pink-500::placeholder{--placeholder-opacity:1;color:#ed64a6;color:rgba(237,100,166,var(--placeholder-opacity))}.placeholder-pink-600:-ms-input-placeholder{--placeholder-opacity:1;color:#d53f8c;color:rgba(213,63,140,var(--placeholder-opacity))}.placeholder-pink-600::-ms-input-placeholder{--placeholder-opacity:1;color:#d53f8c;color:rgba(213,63,140,var(--placeholder-opacity))}.placeholder-pink-600::placeholder{--placeholder-opacity:1;color:#d53f8c;color:rgba(213,63,140,var(--placeholder-opacity))}.placeholder-pink-700:-ms-input-placeholder{--placeholder-opacity:1;color:#b83280;color:rgba(184,50,128,var(--placeholder-opacity))}.placeholder-pink-700::-ms-input-placeholder{--placeholder-opacity:1;color:#b83280;color:rgba(184,50,128,var(--placeholder-opacity))}.placeholder-pink-700::placeholder{--placeholder-opacity:1;color:#b83280;color:rgba(184,50,128,var(--placeholder-opacity))}.placeholder-pink-800:-ms-input-placeholder{--placeholder-opacity:1;color:#97266d;color:rgba(151,38,109,var(--placeholder-opacity))}.placeholder-pink-800::-ms-input-placeholder{--placeholder-opacity:1;color:#97266d;color:rgba(151,38,109,var(--placeholder-opacity))}.placeholder-pink-800::placeholder{--placeholder-opacity:1;color:#97266d;color:rgba(151,38,109,var(--placeholder-opacity))}.placeholder-pink-900:-ms-input-placeholder{--placeholder-opacity:1;color:#702459;color:rgba(112,36,89,var(--placeholder-opacity))}.placeholder-pink-900::-ms-input-placeholder{--placeholder-opacity:1;color:#702459;color:rgba(112,36,89,var(--placeholder-opacity))}.placeholder-pink-900::placeholder{--placeholder-opacity:1;color:#702459;color:rgba(112,36,89,var(--placeholder-opacity))}.focus\:placeholder-transparent:focus:-ms-input-placeholder{color:transparent}.focus\:placeholder-transparent:focus::-ms-input-placeholder{color:transparent}.focus\:placeholder-transparent:focus::placeholder{color:transparent}.focus\:placeholder-current:focus:-ms-input-placeholder{color:currentColor}.focus\:placeholder-current:focus::-ms-input-placeholder{color:currentColor}.focus\:placeholder-current:focus::placeholder{color:currentColor}.focus\:placeholder-black:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#000;color:rgba(0,0,0,var(--placeholder-opacity))}.focus\:placeholder-black:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#000;color:rgba(0,0,0,var(--placeholder-opacity))}.focus\:placeholder-black:focus::placeholder{--placeholder-opacity:1;color:#000;color:rgba(0,0,0,var(--placeholder-opacity))}.focus\:placeholder-white:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#fff;color:rgba(255,255,255,var(--placeholder-opacity))}.focus\:placeholder-white:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#fff;color:rgba(255,255,255,var(--placeholder-opacity))}.focus\:placeholder-white:focus::placeholder{--placeholder-opacity:1;color:#fff;color:rgba(255,255,255,var(--placeholder-opacity))}.focus\:placeholder-gray-100:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#f7fafc;color:rgba(247,250,252,var(--placeholder-opacity))}.focus\:placeholder-gray-100:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#f7fafc;color:rgba(247,250,252,var(--placeholder-opacity))}.focus\:placeholder-gray-100:focus::placeholder{--placeholder-opacity:1;color:#f7fafc;color:rgba(247,250,252,var(--placeholder-opacity))}.focus\:placeholder-gray-200:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#edf2f7;color:rgba(237,242,247,var(--placeholder-opacity))}.focus\:placeholder-gray-200:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#edf2f7;color:rgba(237,242,247,var(--placeholder-opacity))}.focus\:placeholder-gray-200:focus::placeholder{--placeholder-opacity:1;color:#edf2f7;color:rgba(237,242,247,var(--placeholder-opacity))}.focus\:placeholder-gray-300:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#e2e8f0;color:rgba(226,232,240,var(--placeholder-opacity))}.focus\:placeholder-gray-300:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#e2e8f0;color:rgba(226,232,240,var(--placeholder-opacity))}.focus\:placeholder-gray-300:focus::placeholder{--placeholder-opacity:1;color:#e2e8f0;color:rgba(226,232,240,var(--placeholder-opacity))}.focus\:placeholder-gray-400:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#cbd5e0;color:rgba(203,213,224,var(--placeholder-opacity))}.focus\:placeholder-gray-400:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#cbd5e0;color:rgba(203,213,224,var(--placeholder-opacity))}.focus\:placeholder-gray-400:focus::placeholder{--placeholder-opacity:1;color:#cbd5e0;color:rgba(203,213,224,var(--placeholder-opacity))}.focus\:placeholder-gray-500:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#a0aec0;color:rgba(160,174,192,var(--placeholder-opacity))}.focus\:placeholder-gray-500:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#a0aec0;color:rgba(160,174,192,var(--placeholder-opacity))}.focus\:placeholder-gray-500:focus::placeholder{--placeholder-opacity:1;color:#a0aec0;color:rgba(160,174,192,var(--placeholder-opacity))}.focus\:placeholder-gray-600:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#718096;color:rgba(113,128,150,var(--placeholder-opacity))}.focus\:placeholder-gray-600:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#718096;color:rgba(113,128,150,var(--placeholder-opacity))}.focus\:placeholder-gray-600:focus::placeholder{--placeholder-opacity:1;color:#718096;color:rgba(113,128,150,var(--placeholder-opacity))}.focus\:placeholder-gray-700:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#4a5568;color:rgba(74,85,104,var(--placeholder-opacity))}.focus\:placeholder-gray-700:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#4a5568;color:rgba(74,85,104,var(--placeholder-opacity))}.focus\:placeholder-gray-700:focus::placeholder{--placeholder-opacity:1;color:#4a5568;color:rgba(74,85,104,var(--placeholder-opacity))}.focus\:placeholder-gray-800:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#2d3748;color:rgba(45,55,72,var(--placeholder-opacity))}.focus\:placeholder-gray-800:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#2d3748;color:rgba(45,55,72,var(--placeholder-opacity))}.focus\:placeholder-gray-800:focus::placeholder{--placeholder-opacity:1;color:#2d3748;color:rgba(45,55,72,var(--placeholder-opacity))}.focus\:placeholder-gray-900:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#1a202c;color:rgba(26,32,44,var(--placeholder-opacity))}.focus\:placeholder-gray-900:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#1a202c;color:rgba(26,32,44,var(--placeholder-opacity))}.focus\:placeholder-gray-900:focus::placeholder{--placeholder-opacity:1;color:#1a202c;color:rgba(26,32,44,var(--placeholder-opacity))}.focus\:placeholder-red-100:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#fff5f5;color:rgba(255,245,245,var(--placeholder-opacity))}.focus\:placeholder-red-100:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#fff5f5;color:rgba(255,245,245,var(--placeholder-opacity))}.focus\:placeholder-red-100:focus::placeholder{--placeholder-opacity:1;color:#fff5f5;color:rgba(255,245,245,var(--placeholder-opacity))}.focus\:placeholder-red-200:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#fed7d7;color:rgba(254,215,215,var(--placeholder-opacity))}.focus\:placeholder-red-200:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#fed7d7;color:rgba(254,215,215,var(--placeholder-opacity))}.focus\:placeholder-red-200:focus::placeholder{--placeholder-opacity:1;color:#fed7d7;color:rgba(254,215,215,var(--placeholder-opacity))}.focus\:placeholder-red-300:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#feb2b2;color:rgba(254,178,178,var(--placeholder-opacity))}.focus\:placeholder-red-300:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#feb2b2;color:rgba(254,178,178,var(--placeholder-opacity))}.focus\:placeholder-red-300:focus::placeholder{--placeholder-opacity:1;color:#feb2b2;color:rgba(254,178,178,var(--placeholder-opacity))}.focus\:placeholder-red-400:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#fc8181;color:rgba(252,129,129,var(--placeholder-opacity))}.focus\:placeholder-red-400:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#fc8181;color:rgba(252,129,129,var(--placeholder-opacity))}.focus\:placeholder-red-400:focus::placeholder{--placeholder-opacity:1;color:#fc8181;color:rgba(252,129,129,var(--placeholder-opacity))}.focus\:placeholder-red-500:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#f56565;color:rgba(245,101,101,var(--placeholder-opacity))}.focus\:placeholder-red-500:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#f56565;color:rgba(245,101,101,var(--placeholder-opacity))}.focus\:placeholder-red-500:focus::placeholder{--placeholder-opacity:1;color:#f56565;color:rgba(245,101,101,var(--placeholder-opacity))}.focus\:placeholder-red-600:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#e53e3e;color:rgba(229,62,62,var(--placeholder-opacity))}.focus\:placeholder-red-600:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#e53e3e;color:rgba(229,62,62,var(--placeholder-opacity))}.focus\:placeholder-red-600:focus::placeholder{--placeholder-opacity:1;color:#e53e3e;color:rgba(229,62,62,var(--placeholder-opacity))}.focus\:placeholder-red-700:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#c53030;color:rgba(197,48,48,var(--placeholder-opacity))}.focus\:placeholder-red-700:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#c53030;color:rgba(197,48,48,var(--placeholder-opacity))}.focus\:placeholder-red-700:focus::placeholder{--placeholder-opacity:1;color:#c53030;color:rgba(197,48,48,var(--placeholder-opacity))}.focus\:placeholder-red-800:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#9b2c2c;color:rgba(155,44,44,var(--placeholder-opacity))}.focus\:placeholder-red-800:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#9b2c2c;color:rgba(155,44,44,var(--placeholder-opacity))}.focus\:placeholder-red-800:focus::placeholder{--placeholder-opacity:1;color:#9b2c2c;color:rgba(155,44,44,var(--placeholder-opacity))}.focus\:placeholder-red-900:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#742a2a;color:rgba(116,42,42,var(--placeholder-opacity))}.focus\:placeholder-red-900:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#742a2a;color:rgba(116,42,42,var(--placeholder-opacity))}.focus\:placeholder-red-900:focus::placeholder{--placeholder-opacity:1;color:#742a2a;color:rgba(116,42,42,var(--placeholder-opacity))}.focus\:placeholder-orange-100:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#fffaf0;color:rgba(255,250,240,var(--placeholder-opacity))}.focus\:placeholder-orange-100:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#fffaf0;color:rgba(255,250,240,var(--placeholder-opacity))}.focus\:placeholder-orange-100:focus::placeholder{--placeholder-opacity:1;color:#fffaf0;color:rgba(255,250,240,var(--placeholder-opacity))}.focus\:placeholder-orange-200:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#feebc8;color:rgba(254,235,200,var(--placeholder-opacity))}.focus\:placeholder-orange-200:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#feebc8;color:rgba(254,235,200,var(--placeholder-opacity))}.focus\:placeholder-orange-200:focus::placeholder{--placeholder-opacity:1;color:#feebc8;color:rgba(254,235,200,var(--placeholder-opacity))}.focus\:placeholder-orange-300:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#fbd38d;color:rgba(251,211,141,var(--placeholder-opacity))}.focus\:placeholder-orange-300:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#fbd38d;color:rgba(251,211,141,var(--placeholder-opacity))}.focus\:placeholder-orange-300:focus::placeholder{--placeholder-opacity:1;color:#fbd38d;color:rgba(251,211,141,var(--placeholder-opacity))}.focus\:placeholder-orange-400:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#f6ad55;color:rgba(246,173,85,var(--placeholder-opacity))}.focus\:placeholder-orange-400:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#f6ad55;color:rgba(246,173,85,var(--placeholder-opacity))}.focus\:placeholder-orange-400:focus::placeholder{--placeholder-opacity:1;color:#f6ad55;color:rgba(246,173,85,var(--placeholder-opacity))}.focus\:placeholder-orange-500:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#ed8936;color:rgba(237,137,54,var(--placeholder-opacity))}.focus\:placeholder-orange-500:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#ed8936;color:rgba(237,137,54,var(--placeholder-opacity))}.focus\:placeholder-orange-500:focus::placeholder{--placeholder-opacity:1;color:#ed8936;color:rgba(237,137,54,var(--placeholder-opacity))}.focus\:placeholder-orange-600:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#dd6b20;color:rgba(221,107,32,var(--placeholder-opacity))}.focus\:placeholder-orange-600:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#dd6b20;color:rgba(221,107,32,var(--placeholder-opacity))}.focus\:placeholder-orange-600:focus::placeholder{--placeholder-opacity:1;color:#dd6b20;color:rgba(221,107,32,var(--placeholder-opacity))}.focus\:placeholder-orange-700:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#c05621;color:rgba(192,86,33,var(--placeholder-opacity))}.focus\:placeholder-orange-700:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#c05621;color:rgba(192,86,33,var(--placeholder-opacity))}.focus\:placeholder-orange-700:focus::placeholder{--placeholder-opacity:1;color:#c05621;color:rgba(192,86,33,var(--placeholder-opacity))}.focus\:placeholder-orange-800:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#9c4221;color:rgba(156,66,33,var(--placeholder-opacity))}.focus\:placeholder-orange-800:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#9c4221;color:rgba(156,66,33,var(--placeholder-opacity))}.focus\:placeholder-orange-800:focus::placeholder{--placeholder-opacity:1;color:#9c4221;color:rgba(156,66,33,var(--placeholder-opacity))}.focus\:placeholder-orange-900:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#7b341e;color:rgba(123,52,30,var(--placeholder-opacity))}.focus\:placeholder-orange-900:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#7b341e;color:rgba(123,52,30,var(--placeholder-opacity))}.focus\:placeholder-orange-900:focus::placeholder{--placeholder-opacity:1;color:#7b341e;color:rgba(123,52,30,var(--placeholder-opacity))}.focus\:placeholder-yellow-100:focus:-ms-input-placeholder{--placeholder-opacity:1;color:ivory;color:rgba(255,255,240,var(--placeholder-opacity))}.focus\:placeholder-yellow-100:focus::-ms-input-placeholder{--placeholder-opacity:1;color:ivory;color:rgba(255,255,240,var(--placeholder-opacity))}.focus\:placeholder-yellow-100:focus::placeholder{--placeholder-opacity:1;color:ivory;color:rgba(255,255,240,var(--placeholder-opacity))}.focus\:placeholder-yellow-200:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#fefcbf;color:rgba(254,252,191,var(--placeholder-opacity))}.focus\:placeholder-yellow-200:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#fefcbf;color:rgba(254,252,191,var(--placeholder-opacity))}.focus\:placeholder-yellow-200:focus::placeholder{--placeholder-opacity:1;color:#fefcbf;color:rgba(254,252,191,var(--placeholder-opacity))}.focus\:placeholder-yellow-300:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#faf089;color:rgba(250,240,137,var(--placeholder-opacity))}.focus\:placeholder-yellow-300:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#faf089;color:rgba(250,240,137,var(--placeholder-opacity))}.focus\:placeholder-yellow-300:focus::placeholder{--placeholder-opacity:1;color:#faf089;color:rgba(250,240,137,var(--placeholder-opacity))}.focus\:placeholder-yellow-400:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#f6e05e;color:rgba(246,224,94,var(--placeholder-opacity))}.focus\:placeholder-yellow-400:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#f6e05e;color:rgba(246,224,94,var(--placeholder-opacity))}.focus\:placeholder-yellow-400:focus::placeholder{--placeholder-opacity:1;color:#f6e05e;color:rgba(246,224,94,var(--placeholder-opacity))}.focus\:placeholder-yellow-500:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#ecc94b;color:rgba(236,201,75,var(--placeholder-opacity))}.focus\:placeholder-yellow-500:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#ecc94b;color:rgba(236,201,75,var(--placeholder-opacity))}.focus\:placeholder-yellow-500:focus::placeholder{--placeholder-opacity:1;color:#ecc94b;color:rgba(236,201,75,var(--placeholder-opacity))}.focus\:placeholder-yellow-600:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#d69e2e;color:rgba(214,158,46,var(--placeholder-opacity))}.focus\:placeholder-yellow-600:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#d69e2e;color:rgba(214,158,46,var(--placeholder-opacity))}.focus\:placeholder-yellow-600:focus::placeholder{--placeholder-opacity:1;color:#d69e2e;color:rgba(214,158,46,var(--placeholder-opacity))}.focus\:placeholder-yellow-700:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#b7791f;color:rgba(183,121,31,var(--placeholder-opacity))}.focus\:placeholder-yellow-700:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#b7791f;color:rgba(183,121,31,var(--placeholder-opacity))}.focus\:placeholder-yellow-700:focus::placeholder{--placeholder-opacity:1;color:#b7791f;color:rgba(183,121,31,var(--placeholder-opacity))}.focus\:placeholder-yellow-800:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#975a16;color:rgba(151,90,22,var(--placeholder-opacity))}.focus\:placeholder-yellow-800:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#975a16;color:rgba(151,90,22,var(--placeholder-opacity))}.focus\:placeholder-yellow-800:focus::placeholder{--placeholder-opacity:1;color:#975a16;color:rgba(151,90,22,var(--placeholder-opacity))}.focus\:placeholder-yellow-900:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#744210;color:rgba(116,66,16,var(--placeholder-opacity))}.focus\:placeholder-yellow-900:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#744210;color:rgba(116,66,16,var(--placeholder-opacity))}.focus\:placeholder-yellow-900:focus::placeholder{--placeholder-opacity:1;color:#744210;color:rgba(116,66,16,var(--placeholder-opacity))}.focus\:placeholder-green-100:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#f0fff4;color:rgba(240,255,244,var(--placeholder-opacity))}.focus\:placeholder-green-100:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#f0fff4;color:rgba(240,255,244,var(--placeholder-opacity))}.focus\:placeholder-green-100:focus::placeholder{--placeholder-opacity:1;color:#f0fff4;color:rgba(240,255,244,var(--placeholder-opacity))}.focus\:placeholder-green-200:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#c6f6d5;color:rgba(198,246,213,var(--placeholder-opacity))}.focus\:placeholder-green-200:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#c6f6d5;color:rgba(198,246,213,var(--placeholder-opacity))}.focus\:placeholder-green-200:focus::placeholder{--placeholder-opacity:1;color:#c6f6d5;color:rgba(198,246,213,var(--placeholder-opacity))}.focus\:placeholder-green-300:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#9ae6b4;color:rgba(154,230,180,var(--placeholder-opacity))}.focus\:placeholder-green-300:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#9ae6b4;color:rgba(154,230,180,var(--placeholder-opacity))}.focus\:placeholder-green-300:focus::placeholder{--placeholder-opacity:1;color:#9ae6b4;color:rgba(154,230,180,var(--placeholder-opacity))}.focus\:placeholder-green-400:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#68d391;color:rgba(104,211,145,var(--placeholder-opacity))}.focus\:placeholder-green-400:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#68d391;color:rgba(104,211,145,var(--placeholder-opacity))}.focus\:placeholder-green-400:focus::placeholder{--placeholder-opacity:1;color:#68d391;color:rgba(104,211,145,var(--placeholder-opacity))}.focus\:placeholder-green-500:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#48bb78;color:rgba(72,187,120,var(--placeholder-opacity))}.focus\:placeholder-green-500:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#48bb78;color:rgba(72,187,120,var(--placeholder-opacity))}.focus\:placeholder-green-500:focus::placeholder{--placeholder-opacity:1;color:#48bb78;color:rgba(72,187,120,var(--placeholder-opacity))}.focus\:placeholder-green-600:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#38a169;color:rgba(56,161,105,var(--placeholder-opacity))}.focus\:placeholder-green-600:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#38a169;color:rgba(56,161,105,var(--placeholder-opacity))}.focus\:placeholder-green-600:focus::placeholder{--placeholder-opacity:1;color:#38a169;color:rgba(56,161,105,var(--placeholder-opacity))}.focus\:placeholder-green-700:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#2f855a;color:rgba(47,133,90,var(--placeholder-opacity))}.focus\:placeholder-green-700:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#2f855a;color:rgba(47,133,90,var(--placeholder-opacity))}.focus\:placeholder-green-700:focus::placeholder{--placeholder-opacity:1;color:#2f855a;color:rgba(47,133,90,var(--placeholder-opacity))}.focus\:placeholder-green-800:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#276749;color:rgba(39,103,73,var(--placeholder-opacity))}.focus\:placeholder-green-800:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#276749;color:rgba(39,103,73,var(--placeholder-opacity))}.focus\:placeholder-green-800:focus::placeholder{--placeholder-opacity:1;color:#276749;color:rgba(39,103,73,var(--placeholder-opacity))}.focus\:placeholder-green-900:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#22543d;color:rgba(34,84,61,var(--placeholder-opacity))}.focus\:placeholder-green-900:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#22543d;color:rgba(34,84,61,var(--placeholder-opacity))}.focus\:placeholder-green-900:focus::placeholder{--placeholder-opacity:1;color:#22543d;color:rgba(34,84,61,var(--placeholder-opacity))}.focus\:placeholder-teal-100:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#e6fffa;color:rgba(230,255,250,var(--placeholder-opacity))}.focus\:placeholder-teal-100:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#e6fffa;color:rgba(230,255,250,var(--placeholder-opacity))}.focus\:placeholder-teal-100:focus::placeholder{--placeholder-opacity:1;color:#e6fffa;color:rgba(230,255,250,var(--placeholder-opacity))}.focus\:placeholder-teal-200:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#b2f5ea;color:rgba(178,245,234,var(--placeholder-opacity))}.focus\:placeholder-teal-200:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#b2f5ea;color:rgba(178,245,234,var(--placeholder-opacity))}.focus\:placeholder-teal-200:focus::placeholder{--placeholder-opacity:1;color:#b2f5ea;color:rgba(178,245,234,var(--placeholder-opacity))}.focus\:placeholder-teal-300:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#81e6d9;color:rgba(129,230,217,var(--placeholder-opacity))}.focus\:placeholder-teal-300:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#81e6d9;color:rgba(129,230,217,var(--placeholder-opacity))}.focus\:placeholder-teal-300:focus::placeholder{--placeholder-opacity:1;color:#81e6d9;color:rgba(129,230,217,var(--placeholder-opacity))}.focus\:placeholder-teal-400:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#4fd1c5;color:rgba(79,209,197,var(--placeholder-opacity))}.focus\:placeholder-teal-400:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#4fd1c5;color:rgba(79,209,197,var(--placeholder-opacity))}.focus\:placeholder-teal-400:focus::placeholder{--placeholder-opacity:1;color:#4fd1c5;color:rgba(79,209,197,var(--placeholder-opacity))}.focus\:placeholder-teal-500:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#38b2ac;color:rgba(56,178,172,var(--placeholder-opacity))}.focus\:placeholder-teal-500:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#38b2ac;color:rgba(56,178,172,var(--placeholder-opacity))}.focus\:placeholder-teal-500:focus::placeholder{--placeholder-opacity:1;color:#38b2ac;color:rgba(56,178,172,var(--placeholder-opacity))}.focus\:placeholder-teal-600:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#319795;color:rgba(49,151,149,var(--placeholder-opacity))}.focus\:placeholder-teal-600:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#319795;color:rgba(49,151,149,var(--placeholder-opacity))}.focus\:placeholder-teal-600:focus::placeholder{--placeholder-opacity:1;color:#319795;color:rgba(49,151,149,var(--placeholder-opacity))}.focus\:placeholder-teal-700:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#2c7a7b;color:rgba(44,122,123,var(--placeholder-opacity))}.focus\:placeholder-teal-700:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#2c7a7b;color:rgba(44,122,123,var(--placeholder-opacity))}.focus\:placeholder-teal-700:focus::placeholder{--placeholder-opacity:1;color:#2c7a7b;color:rgba(44,122,123,var(--placeholder-opacity))}.focus\:placeholder-teal-800:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#285e61;color:rgba(40,94,97,var(--placeholder-opacity))}.focus\:placeholder-teal-800:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#285e61;color:rgba(40,94,97,var(--placeholder-opacity))}.focus\:placeholder-teal-800:focus::placeholder{--placeholder-opacity:1;color:#285e61;color:rgba(40,94,97,var(--placeholder-opacity))}.focus\:placeholder-teal-900:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#234e52;color:rgba(35,78,82,var(--placeholder-opacity))}.focus\:placeholder-teal-900:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#234e52;color:rgba(35,78,82,var(--placeholder-opacity))}.focus\:placeholder-teal-900:focus::placeholder{--placeholder-opacity:1;color:#234e52;color:rgba(35,78,82,var(--placeholder-opacity))}.focus\:placeholder-blue-100:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#ebf8ff;color:rgba(235,248,255,var(--placeholder-opacity))}.focus\:placeholder-blue-100:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#ebf8ff;color:rgba(235,248,255,var(--placeholder-opacity))}.focus\:placeholder-blue-100:focus::placeholder{--placeholder-opacity:1;color:#ebf8ff;color:rgba(235,248,255,var(--placeholder-opacity))}.focus\:placeholder-blue-200:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#bee3f8;color:rgba(190,227,248,var(--placeholder-opacity))}.focus\:placeholder-blue-200:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#bee3f8;color:rgba(190,227,248,var(--placeholder-opacity))}.focus\:placeholder-blue-200:focus::placeholder{--placeholder-opacity:1;color:#bee3f8;color:rgba(190,227,248,var(--placeholder-opacity))}.focus\:placeholder-blue-300:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#90cdf4;color:rgba(144,205,244,var(--placeholder-opacity))}.focus\:placeholder-blue-300:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#90cdf4;color:rgba(144,205,244,var(--placeholder-opacity))}.focus\:placeholder-blue-300:focus::placeholder{--placeholder-opacity:1;color:#90cdf4;color:rgba(144,205,244,var(--placeholder-opacity))}.focus\:placeholder-blue-400:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#63b3ed;color:rgba(99,179,237,var(--placeholder-opacity))}.focus\:placeholder-blue-400:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#63b3ed;color:rgba(99,179,237,var(--placeholder-opacity))}.focus\:placeholder-blue-400:focus::placeholder{--placeholder-opacity:1;color:#63b3ed;color:rgba(99,179,237,var(--placeholder-opacity))}.focus\:placeholder-blue-500:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#4299e1;color:rgba(66,153,225,var(--placeholder-opacity))}.focus\:placeholder-blue-500:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#4299e1;color:rgba(66,153,225,var(--placeholder-opacity))}.focus\:placeholder-blue-500:focus::placeholder{--placeholder-opacity:1;color:#4299e1;color:rgba(66,153,225,var(--placeholder-opacity))}.focus\:placeholder-blue-600:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#3182ce;color:rgba(49,130,206,var(--placeholder-opacity))}.focus\:placeholder-blue-600:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#3182ce;color:rgba(49,130,206,var(--placeholder-opacity))}.focus\:placeholder-blue-600:focus::placeholder{--placeholder-opacity:1;color:#3182ce;color:rgba(49,130,206,var(--placeholder-opacity))}.focus\:placeholder-blue-700:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#2b6cb0;color:rgba(43,108,176,var(--placeholder-opacity))}.focus\:placeholder-blue-700:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#2b6cb0;color:rgba(43,108,176,var(--placeholder-opacity))}.focus\:placeholder-blue-700:focus::placeholder{--placeholder-opacity:1;color:#2b6cb0;color:rgba(43,108,176,var(--placeholder-opacity))}.focus\:placeholder-blue-800:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#2c5282;color:rgba(44,82,130,var(--placeholder-opacity))}.focus\:placeholder-blue-800:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#2c5282;color:rgba(44,82,130,var(--placeholder-opacity))}.focus\:placeholder-blue-800:focus::placeholder{--placeholder-opacity:1;color:#2c5282;color:rgba(44,82,130,var(--placeholder-opacity))}.focus\:placeholder-blue-900:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#2a4365;color:rgba(42,67,101,var(--placeholder-opacity))}.focus\:placeholder-blue-900:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#2a4365;color:rgba(42,67,101,var(--placeholder-opacity))}.focus\:placeholder-blue-900:focus::placeholder{--placeholder-opacity:1;color:#2a4365;color:rgba(42,67,101,var(--placeholder-opacity))}.focus\:placeholder-indigo-100:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#ebf4ff;color:rgba(235,244,255,var(--placeholder-opacity))}.focus\:placeholder-indigo-100:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#ebf4ff;color:rgba(235,244,255,var(--placeholder-opacity))}.focus\:placeholder-indigo-100:focus::placeholder{--placeholder-opacity:1;color:#ebf4ff;color:rgba(235,244,255,var(--placeholder-opacity))}.focus\:placeholder-indigo-200:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#c3dafe;color:rgba(195,218,254,var(--placeholder-opacity))}.focus\:placeholder-indigo-200:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#c3dafe;color:rgba(195,218,254,var(--placeholder-opacity))}.focus\:placeholder-indigo-200:focus::placeholder{--placeholder-opacity:1;color:#c3dafe;color:rgba(195,218,254,var(--placeholder-opacity))}.focus\:placeholder-indigo-300:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#a3bffa;color:rgba(163,191,250,var(--placeholder-opacity))}.focus\:placeholder-indigo-300:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#a3bffa;color:rgba(163,191,250,var(--placeholder-opacity))}.focus\:placeholder-indigo-300:focus::placeholder{--placeholder-opacity:1;color:#a3bffa;color:rgba(163,191,250,var(--placeholder-opacity))}.focus\:placeholder-indigo-400:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#7f9cf5;color:rgba(127,156,245,var(--placeholder-opacity))}.focus\:placeholder-indigo-400:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#7f9cf5;color:rgba(127,156,245,var(--placeholder-opacity))}.focus\:placeholder-indigo-400:focus::placeholder{--placeholder-opacity:1;color:#7f9cf5;color:rgba(127,156,245,var(--placeholder-opacity))}.focus\:placeholder-indigo-500:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#667eea;color:rgba(102,126,234,var(--placeholder-opacity))}.focus\:placeholder-indigo-500:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#667eea;color:rgba(102,126,234,var(--placeholder-opacity))}.focus\:placeholder-indigo-500:focus::placeholder{--placeholder-opacity:1;color:#667eea;color:rgba(102,126,234,var(--placeholder-opacity))}.focus\:placeholder-indigo-600:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#5a67d8;color:rgba(90,103,216,var(--placeholder-opacity))}.focus\:placeholder-indigo-600:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#5a67d8;color:rgba(90,103,216,var(--placeholder-opacity))}.focus\:placeholder-indigo-600:focus::placeholder{--placeholder-opacity:1;color:#5a67d8;color:rgba(90,103,216,var(--placeholder-opacity))}.focus\:placeholder-indigo-700:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#4c51bf;color:rgba(76,81,191,var(--placeholder-opacity))}.focus\:placeholder-indigo-700:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#4c51bf;color:rgba(76,81,191,var(--placeholder-opacity))}.focus\:placeholder-indigo-700:focus::placeholder{--placeholder-opacity:1;color:#4c51bf;color:rgba(76,81,191,var(--placeholder-opacity))}.focus\:placeholder-indigo-800:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#434190;color:rgba(67,65,144,var(--placeholder-opacity))}.focus\:placeholder-indigo-800:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#434190;color:rgba(67,65,144,var(--placeholder-opacity))}.focus\:placeholder-indigo-800:focus::placeholder{--placeholder-opacity:1;color:#434190;color:rgba(67,65,144,var(--placeholder-opacity))}.focus\:placeholder-indigo-900:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#3c366b;color:rgba(60,54,107,var(--placeholder-opacity))}.focus\:placeholder-indigo-900:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#3c366b;color:rgba(60,54,107,var(--placeholder-opacity))}.focus\:placeholder-indigo-900:focus::placeholder{--placeholder-opacity:1;color:#3c366b;color:rgba(60,54,107,var(--placeholder-opacity))}.focus\:placeholder-purple-100:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#faf5ff;color:rgba(250,245,255,var(--placeholder-opacity))}.focus\:placeholder-purple-100:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#faf5ff;color:rgba(250,245,255,var(--placeholder-opacity))}.focus\:placeholder-purple-100:focus::placeholder{--placeholder-opacity:1;color:#faf5ff;color:rgba(250,245,255,var(--placeholder-opacity))}.focus\:placeholder-purple-200:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#e9d8fd;color:rgba(233,216,253,var(--placeholder-opacity))}.focus\:placeholder-purple-200:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#e9d8fd;color:rgba(233,216,253,var(--placeholder-opacity))}.focus\:placeholder-purple-200:focus::placeholder{--placeholder-opacity:1;color:#e9d8fd;color:rgba(233,216,253,var(--placeholder-opacity))}.focus\:placeholder-purple-300:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#d6bcfa;color:rgba(214,188,250,var(--placeholder-opacity))}.focus\:placeholder-purple-300:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#d6bcfa;color:rgba(214,188,250,var(--placeholder-opacity))}.focus\:placeholder-purple-300:focus::placeholder{--placeholder-opacity:1;color:#d6bcfa;color:rgba(214,188,250,var(--placeholder-opacity))}.focus\:placeholder-purple-400:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#b794f4;color:rgba(183,148,244,var(--placeholder-opacity))}.focus\:placeholder-purple-400:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#b794f4;color:rgba(183,148,244,var(--placeholder-opacity))}.focus\:placeholder-purple-400:focus::placeholder{--placeholder-opacity:1;color:#b794f4;color:rgba(183,148,244,var(--placeholder-opacity))}.focus\:placeholder-purple-500:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#9f7aea;color:rgba(159,122,234,var(--placeholder-opacity))}.focus\:placeholder-purple-500:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#9f7aea;color:rgba(159,122,234,var(--placeholder-opacity))}.focus\:placeholder-purple-500:focus::placeholder{--placeholder-opacity:1;color:#9f7aea;color:rgba(159,122,234,var(--placeholder-opacity))}.focus\:placeholder-purple-600:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#805ad5;color:rgba(128,90,213,var(--placeholder-opacity))}.focus\:placeholder-purple-600:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#805ad5;color:rgba(128,90,213,var(--placeholder-opacity))}.focus\:placeholder-purple-600:focus::placeholder{--placeholder-opacity:1;color:#805ad5;color:rgba(128,90,213,var(--placeholder-opacity))}.focus\:placeholder-purple-700:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#6b46c1;color:rgba(107,70,193,var(--placeholder-opacity))}.focus\:placeholder-purple-700:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#6b46c1;color:rgba(107,70,193,var(--placeholder-opacity))}.focus\:placeholder-purple-700:focus::placeholder{--placeholder-opacity:1;color:#6b46c1;color:rgba(107,70,193,var(--placeholder-opacity))}.focus\:placeholder-purple-800:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#553c9a;color:rgba(85,60,154,var(--placeholder-opacity))}.focus\:placeholder-purple-800:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#553c9a;color:rgba(85,60,154,var(--placeholder-opacity))}.focus\:placeholder-purple-800:focus::placeholder{--placeholder-opacity:1;color:#553c9a;color:rgba(85,60,154,var(--placeholder-opacity))}.focus\:placeholder-purple-900:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#44337a;color:rgba(68,51,122,var(--placeholder-opacity))}.focus\:placeholder-purple-900:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#44337a;color:rgba(68,51,122,var(--placeholder-opacity))}.focus\:placeholder-purple-900:focus::placeholder{--placeholder-opacity:1;color:#44337a;color:rgba(68,51,122,var(--placeholder-opacity))}.focus\:placeholder-pink-100:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#fff5f7;color:rgba(255,245,247,var(--placeholder-opacity))}.focus\:placeholder-pink-100:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#fff5f7;color:rgba(255,245,247,var(--placeholder-opacity))}.focus\:placeholder-pink-100:focus::placeholder{--placeholder-opacity:1;color:#fff5f7;color:rgba(255,245,247,var(--placeholder-opacity))}.focus\:placeholder-pink-200:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#fed7e2;color:rgba(254,215,226,var(--placeholder-opacity))}.focus\:placeholder-pink-200:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#fed7e2;color:rgba(254,215,226,var(--placeholder-opacity))}.focus\:placeholder-pink-200:focus::placeholder{--placeholder-opacity:1;color:#fed7e2;color:rgba(254,215,226,var(--placeholder-opacity))}.focus\:placeholder-pink-300:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#fbb6ce;color:rgba(251,182,206,var(--placeholder-opacity))}.focus\:placeholder-pink-300:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#fbb6ce;color:rgba(251,182,206,var(--placeholder-opacity))}.focus\:placeholder-pink-300:focus::placeholder{--placeholder-opacity:1;color:#fbb6ce;color:rgba(251,182,206,var(--placeholder-opacity))}.focus\:placeholder-pink-400:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#f687b3;color:rgba(246,135,179,var(--placeholder-opacity))}.focus\:placeholder-pink-400:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#f687b3;color:rgba(246,135,179,var(--placeholder-opacity))}.focus\:placeholder-pink-400:focus::placeholder{--placeholder-opacity:1;color:#f687b3;color:rgba(246,135,179,var(--placeholder-opacity))}.focus\:placeholder-pink-500:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#ed64a6;color:rgba(237,100,166,var(--placeholder-opacity))}.focus\:placeholder-pink-500:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#ed64a6;color:rgba(237,100,166,var(--placeholder-opacity))}.focus\:placeholder-pink-500:focus::placeholder{--placeholder-opacity:1;color:#ed64a6;color:rgba(237,100,166,var(--placeholder-opacity))}.focus\:placeholder-pink-600:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#d53f8c;color:rgba(213,63,140,var(--placeholder-opacity))}.focus\:placeholder-pink-600:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#d53f8c;color:rgba(213,63,140,var(--placeholder-opacity))}.focus\:placeholder-pink-600:focus::placeholder{--placeholder-opacity:1;color:#d53f8c;color:rgba(213,63,140,var(--placeholder-opacity))}.focus\:placeholder-pink-700:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#b83280;color:rgba(184,50,128,var(--placeholder-opacity))}.focus\:placeholder-pink-700:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#b83280;color:rgba(184,50,128,var(--placeholder-opacity))}.focus\:placeholder-pink-700:focus::placeholder{--placeholder-opacity:1;color:#b83280;color:rgba(184,50,128,var(--placeholder-opacity))}.focus\:placeholder-pink-800:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#97266d;color:rgba(151,38,109,var(--placeholder-opacity))}.focus\:placeholder-pink-800:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#97266d;color:rgba(151,38,109,var(--placeholder-opacity))}.focus\:placeholder-pink-800:focus::placeholder{--placeholder-opacity:1;color:#97266d;color:rgba(151,38,109,var(--placeholder-opacity))}.focus\:placeholder-pink-900:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#702459;color:rgba(112,36,89,var(--placeholder-opacity))}.focus\:placeholder-pink-900:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#702459;color:rgba(112,36,89,var(--placeholder-opacity))}.focus\:placeholder-pink-900:focus::placeholder{--placeholder-opacity:1;color:#702459;color:rgba(112,36,89,var(--placeholder-opacity))}.placeholder-opacity-0:-ms-input-placeholder{--placeholder-opacity:0}.placeholder-opacity-0::-ms-input-placeholder{--placeholder-opacity:0}.placeholder-opacity-0::placeholder{--placeholder-opacity:0}.placeholder-opacity-25:-ms-input-placeholder{--placeholder-opacity:0.25}.placeholder-opacity-25::-ms-input-placeholder{--placeholder-opacity:0.25}.placeholder-opacity-25::placeholder{--placeholder-opacity:0.25}.placeholder-opacity-50:-ms-input-placeholder{--placeholder-opacity:0.5}.placeholder-opacity-50::-ms-input-placeholder{--placeholder-opacity:0.5}.placeholder-opacity-50::placeholder{--placeholder-opacity:0.5}.placeholder-opacity-75:-ms-input-placeholder{--placeholder-opacity:0.75}.placeholder-opacity-75::-ms-input-placeholder{--placeholder-opacity:0.75}.placeholder-opacity-75::placeholder{--placeholder-opacity:0.75}.placeholder-opacity-100:-ms-input-placeholder{--placeholder-opacity:1}.placeholder-opacity-100::-ms-input-placeholder{--placeholder-opacity:1}.placeholder-opacity-100::placeholder{--placeholder-opacity:1}.focus\:placeholder-opacity-0:focus:-ms-input-placeholder{--placeholder-opacity:0}.focus\:placeholder-opacity-0:focus::-ms-input-placeholder{--placeholder-opacity:0}.focus\:placeholder-opacity-0:focus::placeholder{--placeholder-opacity:0}.focus\:placeholder-opacity-25:focus:-ms-input-placeholder{--placeholder-opacity:0.25}.focus\:placeholder-opacity-25:focus::-ms-input-placeholder{--placeholder-opacity:0.25}.focus\:placeholder-opacity-25:focus::placeholder{--placeholder-opacity:0.25}.focus\:placeholder-opacity-50:focus:-ms-input-placeholder{--placeholder-opacity:0.5}.focus\:placeholder-opacity-50:focus::-ms-input-placeholder{--placeholder-opacity:0.5}.focus\:placeholder-opacity-50:focus::placeholder{--placeholder-opacity:0.5}.focus\:placeholder-opacity-75:focus:-ms-input-placeholder{--placeholder-opacity:0.75}.focus\:placeholder-opacity-75:focus::-ms-input-placeholder{--placeholder-opacity:0.75}.focus\:placeholder-opacity-75:focus::placeholder{--placeholder-opacity:0.75}.focus\:placeholder-opacity-100:focus:-ms-input-placeholder{--placeholder-opacity:1}.focus\:placeholder-opacity-100:focus::-ms-input-placeholder{--placeholder-opacity:1}.focus\:placeholder-opacity-100:focus::placeholder{--placeholder-opacity:1}.pointer-events-none{pointer-events:none}.pointer-events-auto{pointer-events:auto}.static{position:static}.fixed{position:fixed}.absolute{position:absolute}.relative{position:relative}.sticky{position:-webkit-sticky;position:sticky}.inset-0{top:0;right:0;bottom:0;left:0}.inset-auto{top:auto;right:auto;bottom:auto;left:auto}.inset-y-0{top:0;bottom:0}.inset-x-0{right:0;left:0}.inset-y-auto{top:auto;bottom:auto}.inset-x-auto{right:auto;left:auto}.top-0{top:0}.right-0{right:0}.bottom-0{bottom:0}.left-0{left:0}.top-auto{top:auto}.right-auto{right:auto}.bottom-auto{bottom:auto}.left-auto{left:auto}.resize-none{resize:none}.resize-y{resize:vertical}.resize-x{resize:horizontal}.resize{resize:both}.shadow-xs{box-shadow:0 0 0 1px rgba(0,0,0,.05)}.shadow-sm{box-shadow:0 1px 2px 0 rgba(0,0,0,.05)}.shadow{box-shadow:0 1px 3px 0 rgba(0,0,0,.1),0 1px 2px 0 rgba(0,0,0,.06)}.shadow-md{box-shadow:0 4px 6px -1px rgba(0,0,0,.1),0 2px 4px -1px rgba(0,0,0,.06)}.shadow-lg{box-shadow:0 10px 15px -3px rgba(0,0,0,.1),0 4px 6px -2px rgba(0,0,0,.05)}.shadow-xl{box-shadow:0 20px 25px -5px rgba(0,0,0,.1),0 10px 10px -5px rgba(0,0,0,.04)}.shadow-2xl{box-shadow:0 25px 50px -12px rgba(0,0,0,.25)}.shadow-inner{box-shadow:inset 0 2px 4px 0 rgba(0,0,0,.06)}.shadow-outline{box-shadow:0 0 0 3px rgba(66,153,225,.5)}.shadow-none{box-shadow:none}.hover\:shadow-xs:hover{box-shadow:0 0 0 1px rgba(0,0,0,.05)}.hover\:shadow-sm:hover{box-shadow:0 1px 2px 0 rgba(0,0,0,.05)}.hover\:shadow:hover{box-shadow:0 1px 3px 0 rgba(0,0,0,.1),0 1px 2px 0 rgba(0,0,0,.06)}.hover\:shadow-md:hover{box-shadow:0 4px 6px -1px rgba(0,0,0,.1),0 2px 4px -1px rgba(0,0,0,.06)}.hover\:shadow-lg:hover{box-shadow:0 10px 15px -3px rgba(0,0,0,.1),0 4px 6px -2px rgba(0,0,0,.05)}.hover\:shadow-xl:hover{box-shadow:0 20px 25px -5px rgba(0,0,0,.1),0 10px 10px -5px rgba(0,0,0,.04)}.hover\:shadow-2xl:hover{box-shadow:0 25px 50px -12px rgba(0,0,0,.25)}.hover\:shadow-inner:hover{box-shadow:inset 0 2px 4px 0 rgba(0,0,0,.06)}.hover\:shadow-outline:hover{box-shadow:0 0 0 3px rgba(66,153,225,.5)}.hover\:shadow-none:hover{box-shadow:none}.focus\:shadow-xs:focus{box-shadow:0 0 0 1px rgba(0,0,0,.05)}.focus\:shadow-sm:focus{box-shadow:0 1px 2px 0 rgba(0,0,0,.05)}.focus\:shadow:focus{box-shadow:0 1px 3px 0 rgba(0,0,0,.1),0 1px 2px 0 rgba(0,0,0,.06)}.focus\:shadow-md:focus{box-shadow:0 4px 6px -1px rgba(0,0,0,.1),0 2px 4px -1px rgba(0,0,0,.06)}.focus\:shadow-lg:focus{box-shadow:0 10px 15px -3px rgba(0,0,0,.1),0 4px 6px -2px rgba(0,0,0,.05)}.focus\:shadow-xl:focus{box-shadow:0 20px 25px -5px rgba(0,0,0,.1),0 10px 10px -5px rgba(0,0,0,.04)}.focus\:shadow-2xl:focus{box-shadow:0 25px 50px -12px rgba(0,0,0,.25)}.focus\:shadow-inner:focus{box-shadow:inset 0 2px 4px 0 rgba(0,0,0,.06)}.focus\:shadow-outline:focus{box-shadow:0 0 0 3px rgba(66,153,225,.5)}.focus\:shadow-none:focus{box-shadow:none}.fill-current{fill:currentColor}.stroke-current{stroke:currentColor}.stroke-0{stroke-width:0}.stroke-1{stroke-width:1}.stroke-2{stroke-width:2}.table-auto{table-layout:auto}.table-fixed{table-layout:fixed}.text-left{text-align:left}.text-center{text-align:center}.text-right{text-align:right}.text-justify{text-align:justify}.text-transparent{color:transparent}.text-current{color:currentColor}.text-black{--text-opacity:1;color:#000;color:rgba(0,0,0,var(--text-opacity))}.text-white{--text-opacity:1;color:#fff;color:rgba(255,255,255,var(--text-opacity))}.text-gray-100{--text-opacity:1;color:#f7fafc;color:rgba(247,250,252,var(--text-opacity))}.text-gray-200{--text-opacity:1;color:#edf2f7;color:rgba(237,242,247,var(--text-opacity))}.text-gray-300{--text-opacity:1;color:#e2e8f0;color:rgba(226,232,240,var(--text-opacity))}.text-gray-400{--text-opacity:1;color:#cbd5e0;color:rgba(203,213,224,var(--text-opacity))}.text-gray-500{--text-opacity:1;color:#a0aec0;color:rgba(160,174,192,var(--text-opacity))}.text-gray-600{--text-opacity:1;color:#718096;color:rgba(113,128,150,var(--text-opacity))}.text-gray-700{--text-opacity:1;color:#4a5568;color:rgba(74,85,104,var(--text-opacity))}.text-gray-800{--text-opacity:1;color:#2d3748;color:rgba(45,55,72,var(--text-opacity))}.text-gray-900{--text-opacity:1;color:#1a202c;color:rgba(26,32,44,var(--text-opacity))}.text-red-100{--text-opacity:1;color:#fff5f5;color:rgba(255,245,245,var(--text-opacity))}.text-red-200{--text-opacity:1;color:#fed7d7;color:rgba(254,215,215,var(--text-opacity))}.text-red-300{--text-opacity:1;color:#feb2b2;color:rgba(254,178,178,var(--text-opacity))}.text-red-400{--text-opacity:1;color:#fc8181;color:rgba(252,129,129,var(--text-opacity))}.text-red-500{--text-opacity:1;color:#f56565;color:rgba(245,101,101,var(--text-opacity))}.text-red-600{--text-opacity:1;color:#e53e3e;color:rgba(229,62,62,var(--text-opacity))}.text-red-700{--text-opacity:1;color:#c53030;color:rgba(197,48,48,var(--text-opacity))}.text-red-800{--text-opacity:1;color:#9b2c2c;color:rgba(155,44,44,var(--text-opacity))}.text-red-900{--text-opacity:1;color:#742a2a;color:rgba(116,42,42,var(--text-opacity))}.text-orange-100{--text-opacity:1;color:#fffaf0;color:rgba(255,250,240,var(--text-opacity))}.text-orange-200{--text-opacity:1;color:#feebc8;color:rgba(254,235,200,var(--text-opacity))}.text-orange-300{--text-opacity:1;color:#fbd38d;color:rgba(251,211,141,var(--text-opacity))}.text-orange-400{--text-opacity:1;color:#f6ad55;color:rgba(246,173,85,var(--text-opacity))}.text-orange-500{--text-opacity:1;color:#ed8936;color:rgba(237,137,54,var(--text-opacity))}.text-orange-600{--text-opacity:1;color:#dd6b20;color:rgba(221,107,32,var(--text-opacity))}.text-orange-700{--text-opacity:1;color:#c05621;color:rgba(192,86,33,var(--text-opacity))}.text-orange-800{--text-opacity:1;color:#9c4221;color:rgba(156,66,33,var(--text-opacity))}.text-orange-900{--text-opacity:1;color:#7b341e;color:rgba(123,52,30,var(--text-opacity))}.text-yellow-100{--text-opacity:1;color:ivory;color:rgba(255,255,240,var(--text-opacity))}.text-yellow-200{--text-opacity:1;color:#fefcbf;color:rgba(254,252,191,var(--text-opacity))}.text-yellow-300{--text-opacity:1;color:#faf089;color:rgba(250,240,137,var(--text-opacity))}.text-yellow-400{--text-opacity:1;color:#f6e05e;color:rgba(246,224,94,var(--text-opacity))}.text-yellow-500{--text-opacity:1;color:#ecc94b;color:rgba(236,201,75,var(--text-opacity))}.text-yellow-600{--text-opacity:1;color:#d69e2e;color:rgba(214,158,46,var(--text-opacity))}.text-yellow-700{--text-opacity:1;color:#b7791f;color:rgba(183,121,31,var(--text-opacity))}.text-yellow-800{--text-opacity:1;color:#975a16;color:rgba(151,90,22,var(--text-opacity))}.text-yellow-900{--text-opacity:1;color:#744210;color:rgba(116,66,16,var(--text-opacity))}.text-green-100{--text-opacity:1;color:#f0fff4;color:rgba(240,255,244,var(--text-opacity))}.text-green-200{--text-opacity:1;color:#c6f6d5;color:rgba(198,246,213,var(--text-opacity))}.text-green-300{--text-opacity:1;color:#9ae6b4;color:rgba(154,230,180,var(--text-opacity))}.text-green-400{--text-opacity:1;color:#68d391;color:rgba(104,211,145,var(--text-opacity))}.text-green-500{--text-opacity:1;color:#48bb78;color:rgba(72,187,120,var(--text-opacity))}.text-green-600{--text-opacity:1;color:#38a169;color:rgba(56,161,105,var(--text-opacity))}.text-green-700{--text-opacity:1;color:#2f855a;color:rgba(47,133,90,var(--text-opacity))}.text-green-800{--text-opacity:1;color:#276749;color:rgba(39,103,73,var(--text-opacity))}.text-green-900{--text-opacity:1;color:#22543d;color:rgba(34,84,61,var(--text-opacity))}.text-teal-100{--text-opacity:1;color:#e6fffa;color:rgba(230,255,250,var(--text-opacity))}.text-teal-200{--text-opacity:1;color:#b2f5ea;color:rgba(178,245,234,var(--text-opacity))}.text-teal-300{--text-opacity:1;color:#81e6d9;color:rgba(129,230,217,var(--text-opacity))}.text-teal-400{--text-opacity:1;color:#4fd1c5;color:rgba(79,209,197,var(--text-opacity))}.text-teal-500{--text-opacity:1;color:#38b2ac;color:rgba(56,178,172,var(--text-opacity))}.text-teal-600{--text-opacity:1;color:#319795;color:rgba(49,151,149,var(--text-opacity))}.text-teal-700{--text-opacity:1;color:#2c7a7b;color:rgba(44,122,123,var(--text-opacity))}.text-teal-800{--text-opacity:1;color:#285e61;color:rgba(40,94,97,var(--text-opacity))}.text-teal-900{--text-opacity:1;color:#234e52;color:rgba(35,78,82,var(--text-opacity))}.text-blue-100{--text-opacity:1;color:#ebf8ff;color:rgba(235,248,255,var(--text-opacity))}.text-blue-200{--text-opacity:1;color:#bee3f8;color:rgba(190,227,248,var(--text-opacity))}.text-blue-300{--text-opacity:1;color:#90cdf4;color:rgba(144,205,244,var(--text-opacity))}.text-blue-400{--text-opacity:1;color:#63b3ed;color:rgba(99,179,237,var(--text-opacity))}.text-blue-500{--text-opacity:1;color:#4299e1;color:rgba(66,153,225,var(--text-opacity))}.text-blue-600{--text-opacity:1;color:#3182ce;color:rgba(49,130,206,var(--text-opacity))}.text-blue-700{--text-opacity:1;color:#2b6cb0;color:rgba(43,108,176,var(--text-opacity))}.text-blue-800{--text-opacity:1;color:#2c5282;color:rgba(44,82,130,var(--text-opacity))}.text-blue-900{--text-opacity:1;color:#2a4365;color:rgba(42,67,101,var(--text-opacity))}.text-indigo-100{--text-opacity:1;color:#ebf4ff;color:rgba(235,244,255,var(--text-opacity))}.text-indigo-200{--text-opacity:1;color:#c3dafe;color:rgba(195,218,254,var(--text-opacity))}.text-indigo-300{--text-opacity:1;color:#a3bffa;color:rgba(163,191,250,var(--text-opacity))}.text-indigo-400{--text-opacity:1;color:#7f9cf5;color:rgba(127,156,245,var(--text-opacity))}.text-indigo-500{--text-opacity:1;color:#667eea;color:rgba(102,126,234,var(--text-opacity))}.text-indigo-600{--text-opacity:1;color:#5a67d8;color:rgba(90,103,216,var(--text-opacity))}.text-indigo-700{--text-opacity:1;color:#4c51bf;color:rgba(76,81,191,var(--text-opacity))}.text-indigo-800{--text-opacity:1;color:#434190;color:rgba(67,65,144,var(--text-opacity))}.text-indigo-900{--text-opacity:1;color:#3c366b;color:rgba(60,54,107,var(--text-opacity))}.text-purple-100{--text-opacity:1;color:#faf5ff;color:rgba(250,245,255,var(--text-opacity))}.text-purple-200{--text-opacity:1;color:#e9d8fd;color:rgba(233,216,253,var(--text-opacity))}.text-purple-300{--text-opacity:1;color:#d6bcfa;color:rgba(214,188,250,var(--text-opacity))}.text-purple-400{--text-opacity:1;color:#b794f4;color:rgba(183,148,244,var(--text-opacity))}.text-purple-500{--text-opacity:1;color:#9f7aea;color:rgba(159,122,234,var(--text-opacity))}.text-purple-600{--text-opacity:1;color:#805ad5;color:rgba(128,90,213,var(--text-opacity))}.text-purple-700{--text-opacity:1;color:#6b46c1;color:rgba(107,70,193,var(--text-opacity))}.text-purple-800{--text-opacity:1;color:#553c9a;color:rgba(85,60,154,var(--text-opacity))}.text-purple-900{--text-opacity:1;color:#44337a;color:rgba(68,51,122,var(--text-opacity))}.text-pink-100{--text-opacity:1;color:#fff5f7;color:rgba(255,245,247,var(--text-opacity))}.text-pink-200{--text-opacity:1;color:#fed7e2;color:rgba(254,215,226,var(--text-opacity))}.text-pink-300{--text-opacity:1;color:#fbb6ce;color:rgba(251,182,206,var(--text-opacity))}.text-pink-400{--text-opacity:1;color:#f687b3;color:rgba(246,135,179,var(--text-opacity))}.text-pink-500{--text-opacity:1;color:#ed64a6;color:rgba(237,100,166,var(--text-opacity))}.text-pink-600{--text-opacity:1;color:#d53f8c;color:rgba(213,63,140,var(--text-opacity))}.text-pink-700{--text-opacity:1;color:#b83280;color:rgba(184,50,128,var(--text-opacity))}.text-pink-800{--text-opacity:1;color:#97266d;color:rgba(151,38,109,var(--text-opacity))}.text-pink-900{--text-opacity:1;color:#702459;color:rgba(112,36,89,var(--text-opacity))}.hover\:text-transparent:hover{color:transparent}.hover\:text-current:hover{color:currentColor}.hover\:text-black:hover{--text-opacity:1;color:#000;color:rgba(0,0,0,var(--text-opacity))}.hover\:text-white:hover{--text-opacity:1;color:#fff;color:rgba(255,255,255,var(--text-opacity))}.hover\:text-gray-100:hover{--text-opacity:1;color:#f7fafc;color:rgba(247,250,252,var(--text-opacity))}.hover\:text-gray-200:hover{--text-opacity:1;color:#edf2f7;color:rgba(237,242,247,var(--text-opacity))}.hover\:text-gray-300:hover{--text-opacity:1;color:#e2e8f0;color:rgba(226,232,240,var(--text-opacity))}.hover\:text-gray-400:hover{--text-opacity:1;color:#cbd5e0;color:rgba(203,213,224,var(--text-opacity))}.hover\:text-gray-500:hover{--text-opacity:1;color:#a0aec0;color:rgba(160,174,192,var(--text-opacity))}.hover\:text-gray-600:hover{--text-opacity:1;color:#718096;color:rgba(113,128,150,var(--text-opacity))}.hover\:text-gray-700:hover{--text-opacity:1;color:#4a5568;color:rgba(74,85,104,var(--text-opacity))}.hover\:text-gray-800:hover{--text-opacity:1;color:#2d3748;color:rgba(45,55,72,var(--text-opacity))}.hover\:text-gray-900:hover{--text-opacity:1;color:#1a202c;color:rgba(26,32,44,var(--text-opacity))}.hover\:text-red-100:hover{--text-opacity:1;color:#fff5f5;color:rgba(255,245,245,var(--text-opacity))}.hover\:text-red-200:hover{--text-opacity:1;color:#fed7d7;color:rgba(254,215,215,var(--text-opacity))}.hover\:text-red-300:hover{--text-opacity:1;color:#feb2b2;color:rgba(254,178,178,var(--text-opacity))}.hover\:text-red-400:hover{--text-opacity:1;color:#fc8181;color:rgba(252,129,129,var(--text-opacity))}.hover\:text-red-500:hover{--text-opacity:1;color:#f56565;color:rgba(245,101,101,var(--text-opacity))}.hover\:text-red-600:hover{--text-opacity:1;color:#e53e3e;color:rgba(229,62,62,var(--text-opacity))}.hover\:text-red-700:hover{--text-opacity:1;color:#c53030;color:rgba(197,48,48,var(--text-opacity))}.hover\:text-red-800:hover{--text-opacity:1;color:#9b2c2c;color:rgba(155,44,44,var(--text-opacity))}.hover\:text-red-900:hover{--text-opacity:1;color:#742a2a;color:rgba(116,42,42,var(--text-opacity))}.hover\:text-orange-100:hover{--text-opacity:1;color:#fffaf0;color:rgba(255,250,240,var(--text-opacity))}.hover\:text-orange-200:hover{--text-opacity:1;color:#feebc8;color:rgba(254,235,200,var(--text-opacity))}.hover\:text-orange-300:hover{--text-opacity:1;color:#fbd38d;color:rgba(251,211,141,var(--text-opacity))}.hover\:text-orange-400:hover{--text-opacity:1;color:#f6ad55;color:rgba(246,173,85,var(--text-opacity))}.hover\:text-orange-500:hover{--text-opacity:1;color:#ed8936;color:rgba(237,137,54,var(--text-opacity))}.hover\:text-orange-600:hover{--text-opacity:1;color:#dd6b20;color:rgba(221,107,32,var(--text-opacity))}.hover\:text-orange-700:hover{--text-opacity:1;color:#c05621;color:rgba(192,86,33,var(--text-opacity))}.hover\:text-orange-800:hover{--text-opacity:1;color:#9c4221;color:rgba(156,66,33,var(--text-opacity))}.hover\:text-orange-900:hover{--text-opacity:1;color:#7b341e;color:rgba(123,52,30,var(--text-opacity))}.hover\:text-yellow-100:hover{--text-opacity:1;color:ivory;color:rgba(255,255,240,var(--text-opacity))}.hover\:text-yellow-200:hover{--text-opacity:1;color:#fefcbf;color:rgba(254,252,191,var(--text-opacity))}.hover\:text-yellow-300:hover{--text-opacity:1;color:#faf089;color:rgba(250,240,137,var(--text-opacity))}.hover\:text-yellow-400:hover{--text-opacity:1;color:#f6e05e;color:rgba(246,224,94,var(--text-opacity))}.hover\:text-yellow-500:hover{--text-opacity:1;color:#ecc94b;color:rgba(236,201,75,var(--text-opacity))}.hover\:text-yellow-600:hover{--text-opacity:1;color:#d69e2e;color:rgba(214,158,46,var(--text-opacity))}.hover\:text-yellow-700:hover{--text-opacity:1;color:#b7791f;color:rgba(183,121,31,var(--text-opacity))}.hover\:text-yellow-800:hover{--text-opacity:1;color:#975a16;color:rgba(151,90,22,var(--text-opacity))}.hover\:text-yellow-900:hover{--text-opacity:1;color:#744210;color:rgba(116,66,16,var(--text-opacity))}.hover\:text-green-100:hover{--text-opacity:1;color:#f0fff4;color:rgba(240,255,244,var(--text-opacity))}.hover\:text-green-200:hover{--text-opacity:1;color:#c6f6d5;color:rgba(198,246,213,var(--text-opacity))}.hover\:text-green-300:hover{--text-opacity:1;color:#9ae6b4;color:rgba(154,230,180,var(--text-opacity))}.hover\:text-green-400:hover{--text-opacity:1;color:#68d391;color:rgba(104,211,145,var(--text-opacity))}.hover\:text-green-500:hover{--text-opacity:1;color:#48bb78;color:rgba(72,187,120,var(--text-opacity))}.hover\:text-green-600:hover{--text-opacity:1;color:#38a169;color:rgba(56,161,105,var(--text-opacity))}.hover\:text-green-700:hover{--text-opacity:1;color:#2f855a;color:rgba(47,133,90,var(--text-opacity))}.hover\:text-green-800:hover{--text-opacity:1;color:#276749;color:rgba(39,103,73,var(--text-opacity))}.hover\:text-green-900:hover{--text-opacity:1;color:#22543d;color:rgba(34,84,61,var(--text-opacity))}.hover\:text-teal-100:hover{--text-opacity:1;color:#e6fffa;color:rgba(230,255,250,var(--text-opacity))}.hover\:text-teal-200:hover{--text-opacity:1;color:#b2f5ea;color:rgba(178,245,234,var(--text-opacity))}.hover\:text-teal-300:hover{--text-opacity:1;color:#81e6d9;color:rgba(129,230,217,var(--text-opacity))}.hover\:text-teal-400:hover{--text-opacity:1;color:#4fd1c5;color:rgba(79,209,197,var(--text-opacity))}.hover\:text-teal-500:hover{--text-opacity:1;color:#38b2ac;color:rgba(56,178,172,var(--text-opacity))}.hover\:text-teal-600:hover{--text-opacity:1;color:#319795;color:rgba(49,151,149,var(--text-opacity))}.hover\:text-teal-700:hover{--text-opacity:1;color:#2c7a7b;color:rgba(44,122,123,var(--text-opacity))}.hover\:text-teal-800:hover{--text-opacity:1;color:#285e61;color:rgba(40,94,97,var(--text-opacity))}.hover\:text-teal-900:hover{--text-opacity:1;color:#234e52;color:rgba(35,78,82,var(--text-opacity))}.hover\:text-blue-100:hover{--text-opacity:1;color:#ebf8ff;color:rgba(235,248,255,var(--text-opacity))}.hover\:text-blue-200:hover{--text-opacity:1;color:#bee3f8;color:rgba(190,227,248,var(--text-opacity))}.hover\:text-blue-300:hover{--text-opacity:1;color:#90cdf4;color:rgba(144,205,244,var(--text-opacity))}.hover\:text-blue-400:hover{--text-opacity:1;color:#63b3ed;color:rgba(99,179,237,var(--text-opacity))}.hover\:text-blue-500:hover{--text-opacity:1;color:#4299e1;color:rgba(66,153,225,var(--text-opacity))}.hover\:text-blue-600:hover{--text-opacity:1;color:#3182ce;color:rgba(49,130,206,var(--text-opacity))}.hover\:text-blue-700:hover{--text-opacity:1;color:#2b6cb0;color:rgba(43,108,176,var(--text-opacity))}.hover\:text-blue-800:hover{--text-opacity:1;color:#2c5282;color:rgba(44,82,130,var(--text-opacity))}.hover\:text-blue-900:hover{--text-opacity:1;color:#2a4365;color:rgba(42,67,101,var(--text-opacity))}.hover\:text-indigo-100:hover{--text-opacity:1;color:#ebf4ff;color:rgba(235,244,255,var(--text-opacity))}.hover\:text-indigo-200:hover{--text-opacity:1;color:#c3dafe;color:rgba(195,218,254,var(--text-opacity))}.hover\:text-indigo-300:hover{--text-opacity:1;color:#a3bffa;color:rgba(163,191,250,var(--text-opacity))}.hover\:text-indigo-400:hover{--text-opacity:1;color:#7f9cf5;color:rgba(127,156,245,var(--text-opacity))}.hover\:text-indigo-500:hover{--text-opacity:1;color:#667eea;color:rgba(102,126,234,var(--text-opacity))}.hover\:text-indigo-600:hover{--text-opacity:1;color:#5a67d8;color:rgba(90,103,216,var(--text-opacity))}.hover\:text-indigo-700:hover{--text-opacity:1;color:#4c51bf;color:rgba(76,81,191,var(--text-opacity))}.hover\:text-indigo-800:hover{--text-opacity:1;color:#434190;color:rgba(67,65,144,var(--text-opacity))}.hover\:text-indigo-900:hover{--text-opacity:1;color:#3c366b;color:rgba(60,54,107,var(--text-opacity))}.hover\:text-purple-100:hover{--text-opacity:1;color:#faf5ff;color:rgba(250,245,255,var(--text-opacity))}.hover\:text-purple-200:hover{--text-opacity:1;color:#e9d8fd;color:rgba(233,216,253,var(--text-opacity))}.hover\:text-purple-300:hover{--text-opacity:1;color:#d6bcfa;color:rgba(214,188,250,var(--text-opacity))}.hover\:text-purple-400:hover{--text-opacity:1;color:#b794f4;color:rgba(183,148,244,var(--text-opacity))}.hover\:text-purple-500:hover{--text-opacity:1;color:#9f7aea;color:rgba(159,122,234,var(--text-opacity))}.hover\:text-purple-600:hover{--text-opacity:1;color:#805ad5;color:rgba(128,90,213,var(--text-opacity))}.hover\:text-purple-700:hover{--text-opacity:1;color:#6b46c1;color:rgba(107,70,193,var(--text-opacity))}.hover\:text-purple-800:hover{--text-opacity:1;color:#553c9a;color:rgba(85,60,154,var(--text-opacity))}.hover\:text-purple-900:hover{--text-opacity:1;color:#44337a;color:rgba(68,51,122,var(--text-opacity))}.hover\:text-pink-100:hover{--text-opacity:1;color:#fff5f7;color:rgba(255,245,247,var(--text-opacity))}.hover\:text-pink-200:hover{--text-opacity:1;color:#fed7e2;color:rgba(254,215,226,var(--text-opacity))}.hover\:text-pink-300:hover{--text-opacity:1;color:#fbb6ce;color:rgba(251,182,206,var(--text-opacity))}.hover\:text-pink-400:hover{--text-opacity:1;color:#f687b3;color:rgba(246,135,179,var(--text-opacity))}.hover\:text-pink-500:hover{--text-opacity:1;color:#ed64a6;color:rgba(237,100,166,var(--text-opacity))}.hover\:text-pink-600:hover{--text-opacity:1;color:#d53f8c;color:rgba(213,63,140,var(--text-opacity))}.hover\:text-pink-700:hover{--text-opacity:1;color:#b83280;color:rgba(184,50,128,var(--text-opacity))}.hover\:text-pink-800:hover{--text-opacity:1;color:#97266d;color:rgba(151,38,109,var(--text-opacity))}.hover\:text-pink-900:hover{--text-opacity:1;color:#702459;color:rgba(112,36,89,var(--text-opacity))}.focus\:text-transparent:focus{color:transparent}.focus\:text-current:focus{color:currentColor}.focus\:text-black:focus{--text-opacity:1;color:#000;color:rgba(0,0,0,var(--text-opacity))}.focus\:text-white:focus{--text-opacity:1;color:#fff;color:rgba(255,255,255,var(--text-opacity))}.focus\:text-gray-100:focus{--text-opacity:1;color:#f7fafc;color:rgba(247,250,252,var(--text-opacity))}.focus\:text-gray-200:focus{--text-opacity:1;color:#edf2f7;color:rgba(237,242,247,var(--text-opacity))}.focus\:text-gray-300:focus{--text-opacity:1;color:#e2e8f0;color:rgba(226,232,240,var(--text-opacity))}.focus\:text-gray-400:focus{--text-opacity:1;color:#cbd5e0;color:rgba(203,213,224,var(--text-opacity))}.focus\:text-gray-500:focus{--text-opacity:1;color:#a0aec0;color:rgba(160,174,192,var(--text-opacity))}.focus\:text-gray-600:focus{--text-opacity:1;color:#718096;color:rgba(113,128,150,var(--text-opacity))}.focus\:text-gray-700:focus{--text-opacity:1;color:#4a5568;color:rgba(74,85,104,var(--text-opacity))}.focus\:text-gray-800:focus{--text-opacity:1;color:#2d3748;color:rgba(45,55,72,var(--text-opacity))}.focus\:text-gray-900:focus{--text-opacity:1;color:#1a202c;color:rgba(26,32,44,var(--text-opacity))}.focus\:text-red-100:focus{--text-opacity:1;color:#fff5f5;color:rgba(255,245,245,var(--text-opacity))}.focus\:text-red-200:focus{--text-opacity:1;color:#fed7d7;color:rgba(254,215,215,var(--text-opacity))}.focus\:text-red-300:focus{--text-opacity:1;color:#feb2b2;color:rgba(254,178,178,var(--text-opacity))}.focus\:text-red-400:focus{--text-opacity:1;color:#fc8181;color:rgba(252,129,129,var(--text-opacity))}.focus\:text-red-500:focus{--text-opacity:1;color:#f56565;color:rgba(245,101,101,var(--text-opacity))}.focus\:text-red-600:focus{--text-opacity:1;color:#e53e3e;color:rgba(229,62,62,var(--text-opacity))}.focus\:text-red-700:focus{--text-opacity:1;color:#c53030;color:rgba(197,48,48,var(--text-opacity))}.focus\:text-red-800:focus{--text-opacity:1;color:#9b2c2c;color:rgba(155,44,44,var(--text-opacity))}.focus\:text-red-900:focus{--text-opacity:1;color:#742a2a;color:rgba(116,42,42,var(--text-opacity))}.focus\:text-orange-100:focus{--text-opacity:1;color:#fffaf0;color:rgba(255,250,240,var(--text-opacity))}.focus\:text-orange-200:focus{--text-opacity:1;color:#feebc8;color:rgba(254,235,200,var(--text-opacity))}.focus\:text-orange-300:focus{--text-opacity:1;color:#fbd38d;color:rgba(251,211,141,var(--text-opacity))}.focus\:text-orange-400:focus{--text-opacity:1;color:#f6ad55;color:rgba(246,173,85,var(--text-opacity))}.focus\:text-orange-500:focus{--text-opacity:1;color:#ed8936;color:rgba(237,137,54,var(--text-opacity))}.focus\:text-orange-600:focus{--text-opacity:1;color:#dd6b20;color:rgba(221,107,32,var(--text-opacity))}.focus\:text-orange-700:focus{--text-opacity:1;color:#c05621;color:rgba(192,86,33,var(--text-opacity))}.focus\:text-orange-800:focus{--text-opacity:1;color:#9c4221;color:rgba(156,66,33,var(--text-opacity))}.focus\:text-orange-900:focus{--text-opacity:1;color:#7b341e;color:rgba(123,52,30,var(--text-opacity))}.focus\:text-yellow-100:focus{--text-opacity:1;color:ivory;color:rgba(255,255,240,var(--text-opacity))}.focus\:text-yellow-200:focus{--text-opacity:1;color:#fefcbf;color:rgba(254,252,191,var(--text-opacity))}.focus\:text-yellow-300:focus{--text-opacity:1;color:#faf089;color:rgba(250,240,137,var(--text-opacity))}.focus\:text-yellow-400:focus{--text-opacity:1;color:#f6e05e;color:rgba(246,224,94,var(--text-opacity))}.focus\:text-yellow-500:focus{--text-opacity:1;color:#ecc94b;color:rgba(236,201,75,var(--text-opacity))}.focus\:text-yellow-600:focus{--text-opacity:1;color:#d69e2e;color:rgba(214,158,46,var(--text-opacity))}.focus\:text-yellow-700:focus{--text-opacity:1;color:#b7791f;color:rgba(183,121,31,var(--text-opacity))}.focus\:text-yellow-800:focus{--text-opacity:1;color:#975a16;color:rgba(151,90,22,var(--text-opacity))}.focus\:text-yellow-900:focus{--text-opacity:1;color:#744210;color:rgba(116,66,16,var(--text-opacity))}.focus\:text-green-100:focus{--text-opacity:1;color:#f0fff4;color:rgba(240,255,244,var(--text-opacity))}.focus\:text-green-200:focus{--text-opacity:1;color:#c6f6d5;color:rgba(198,246,213,var(--text-opacity))}.focus\:text-green-300:focus{--text-opacity:1;color:#9ae6b4;color:rgba(154,230,180,var(--text-opacity))}.focus\:text-green-400:focus{--text-opacity:1;color:#68d391;color:rgba(104,211,145,var(--text-opacity))}.focus\:text-green-500:focus{--text-opacity:1;color:#48bb78;color:rgba(72,187,120,var(--text-opacity))}.focus\:text-green-600:focus{--text-opacity:1;color:#38a169;color:rgba(56,161,105,var(--text-opacity))}.focus\:text-green-700:focus{--text-opacity:1;color:#2f855a;color:rgba(47,133,90,var(--text-opacity))}.focus\:text-green-800:focus{--text-opacity:1;color:#276749;color:rgba(39,103,73,var(--text-opacity))}.focus\:text-green-900:focus{--text-opacity:1;color:#22543d;color:rgba(34,84,61,var(--text-opacity))}.focus\:text-teal-100:focus{--text-opacity:1;color:#e6fffa;color:rgba(230,255,250,var(--text-opacity))}.focus\:text-teal-200:focus{--text-opacity:1;color:#b2f5ea;color:rgba(178,245,234,var(--text-opacity))}.focus\:text-teal-300:focus{--text-opacity:1;color:#81e6d9;color:rgba(129,230,217,var(--text-opacity))}.focus\:text-teal-400:focus{--text-opacity:1;color:#4fd1c5;color:rgba(79,209,197,var(--text-opacity))}.focus\:text-teal-500:focus{--text-opacity:1;color:#38b2ac;color:rgba(56,178,172,var(--text-opacity))}.focus\:text-teal-600:focus{--text-opacity:1;color:#319795;color:rgba(49,151,149,var(--text-opacity))}.focus\:text-teal-700:focus{--text-opacity:1;color:#2c7a7b;color:rgba(44,122,123,var(--text-opacity))}.focus\:text-teal-800:focus{--text-opacity:1;color:#285e61;color:rgba(40,94,97,var(--text-opacity))}.focus\:text-teal-900:focus{--text-opacity:1;color:#234e52;color:rgba(35,78,82,var(--text-opacity))}.focus\:text-blue-100:focus{--text-opacity:1;color:#ebf8ff;color:rgba(235,248,255,var(--text-opacity))}.focus\:text-blue-200:focus{--text-opacity:1;color:#bee3f8;color:rgba(190,227,248,var(--text-opacity))}.focus\:text-blue-300:focus{--text-opacity:1;color:#90cdf4;color:rgba(144,205,244,var(--text-opacity))}.focus\:text-blue-400:focus{--text-opacity:1;color:#63b3ed;color:rgba(99,179,237,var(--text-opacity))}.focus\:text-blue-500:focus{--text-opacity:1;color:#4299e1;color:rgba(66,153,225,var(--text-opacity))}.focus\:text-blue-600:focus{--text-opacity:1;color:#3182ce;color:rgba(49,130,206,var(--text-opacity))}.focus\:text-blue-700:focus{--text-opacity:1;color:#2b6cb0;color:rgba(43,108,176,var(--text-opacity))}.focus\:text-blue-800:focus{--text-opacity:1;color:#2c5282;color:rgba(44,82,130,var(--text-opacity))}.focus\:text-blue-900:focus{--text-opacity:1;color:#2a4365;color:rgba(42,67,101,var(--text-opacity))}.focus\:text-indigo-100:focus{--text-opacity:1;color:#ebf4ff;color:rgba(235,244,255,var(--text-opacity))}.focus\:text-indigo-200:focus{--text-opacity:1;color:#c3dafe;color:rgba(195,218,254,var(--text-opacity))}.focus\:text-indigo-300:focus{--text-opacity:1;color:#a3bffa;color:rgba(163,191,250,var(--text-opacity))}.focus\:text-indigo-400:focus{--text-opacity:1;color:#7f9cf5;color:rgba(127,156,245,var(--text-opacity))}.focus\:text-indigo-500:focus{--text-opacity:1;color:#667eea;color:rgba(102,126,234,var(--text-opacity))}.focus\:text-indigo-600:focus{--text-opacity:1;color:#5a67d8;color:rgba(90,103,216,var(--text-opacity))}.focus\:text-indigo-700:focus{--text-opacity:1;color:#4c51bf;color:rgba(76,81,191,var(--text-opacity))}.focus\:text-indigo-800:focus{--text-opacity:1;color:#434190;color:rgba(67,65,144,var(--text-opacity))}.focus\:text-indigo-900:focus{--text-opacity:1;color:#3c366b;color:rgba(60,54,107,var(--text-opacity))}.focus\:text-purple-100:focus{--text-opacity:1;color:#faf5ff;color:rgba(250,245,255,var(--text-opacity))}.focus\:text-purple-200:focus{--text-opacity:1;color:#e9d8fd;color:rgba(233,216,253,var(--text-opacity))}.focus\:text-purple-300:focus{--text-opacity:1;color:#d6bcfa;color:rgba(214,188,250,var(--text-opacity))}.focus\:text-purple-400:focus{--text-opacity:1;color:#b794f4;color:rgba(183,148,244,var(--text-opacity))}.focus\:text-purple-500:focus{--text-opacity:1;color:#9f7aea;color:rgba(159,122,234,var(--text-opacity))}.focus\:text-purple-600:focus{--text-opacity:1;color:#805ad5;color:rgba(128,90,213,var(--text-opacity))}.focus\:text-purple-700:focus{--text-opacity:1;color:#6b46c1;color:rgba(107,70,193,var(--text-opacity))}.focus\:text-purple-800:focus{--text-opacity:1;color:#553c9a;color:rgba(85,60,154,var(--text-opacity))}.focus\:text-purple-900:focus{--text-opacity:1;color:#44337a;color:rgba(68,51,122,var(--text-opacity))}.focus\:text-pink-100:focus{--text-opacity:1;color:#fff5f7;color:rgba(255,245,247,var(--text-opacity))}.focus\:text-pink-200:focus{--text-opacity:1;color:#fed7e2;color:rgba(254,215,226,var(--text-opacity))}.focus\:text-pink-300:focus{--text-opacity:1;color:#fbb6ce;color:rgba(251,182,206,var(--text-opacity))}.focus\:text-pink-400:focus{--text-opacity:1;color:#f687b3;color:rgba(246,135,179,var(--text-opacity))}.focus\:text-pink-500:focus{--text-opacity:1;color:#ed64a6;color:rgba(237,100,166,var(--text-opacity))}.focus\:text-pink-600:focus{--text-opacity:1;color:#d53f8c;color:rgba(213,63,140,var(--text-opacity))}.focus\:text-pink-700:focus{--text-opacity:1;color:#b83280;color:rgba(184,50,128,var(--text-opacity))}.focus\:text-pink-800:focus{--text-opacity:1;color:#97266d;color:rgba(151,38,109,var(--text-opacity))}.focus\:text-pink-900:focus{--text-opacity:1;color:#702459;color:rgba(112,36,89,var(--text-opacity))}.text-opacity-0{--text-opacity:0}.text-opacity-25{--text-opacity:0.25}.text-opacity-50{--text-opacity:0.5}.text-opacity-75{--text-opacity:0.75}.text-opacity-100{--text-opacity:1}.hover\:text-opacity-0:hover{--text-opacity:0}.hover\:text-opacity-25:hover{--text-opacity:0.25}.hover\:text-opacity-50:hover{--text-opacity:0.5}.hover\:text-opacity-75:hover{--text-opacity:0.75}.hover\:text-opacity-100:hover{--text-opacity:1}.focus\:text-opacity-0:focus{--text-opacity:0}.focus\:text-opacity-25:focus{--text-opacity:0.25}.focus\:text-opacity-50:focus{--text-opacity:0.5}.focus\:text-opacity-75:focus{--text-opacity:0.75}.focus\:text-opacity-100:focus{--text-opacity:1}.italic{font-style:italic}.not-italic{font-style:normal}.uppercase{text-transform:uppercase}.lowercase{text-transform:lowercase}.capitalize{text-transform:capitalize}.normal-case{text-transform:none}.underline{text-decoration:underline}.line-through{text-decoration:line-through}.no-underline{text-decoration:none}.hover\:underline:hover{text-decoration:underline}.hover\:line-through:hover{text-decoration:line-through}.hover\:no-underline:hover{text-decoration:none}.focus\:underline:focus{text-decoration:underline}.focus\:line-through:focus{text-decoration:line-through}.focus\:no-underline:focus{text-decoration:none}.antialiased{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.subpixel-antialiased{-webkit-font-smoothing:auto;-moz-osx-font-smoothing:auto}.diagonal-fractions,.lining-nums,.oldstyle-nums,.ordinal,.proportional-nums,.slashed-zero,.stacked-fractions,.tabular-nums{--font-variant-numeric-ordinal:var(--tailwind-empty, );/*!*//*!*/--font-variant-numeric-slashed-zero:var(--tailwind-empty, );/*!*//*!*/--font-variant-numeric-figure:var(--tailwind-empty, );/*!*//*!*/--font-variant-numeric-spacing:var(--tailwind-empty, );/*!*//*!*/--font-variant-numeric-fraction:var(--tailwind-empty, );/*!*//*!*/font-variant-numeric:var(--font-variant-numeric-ordinal) var(--font-variant-numeric-slashed-zero) var(--font-variant-numeric-figure) var(--font-variant-numeric-spacing) var(--font-variant-numeric-fraction)}.normal-nums{font-variant-numeric:normal}.ordinal{--font-variant-numeric-ordinal:ordinal}.slashed-zero{--font-variant-numeric-slashed-zero:slashed-zero}.lining-nums{--font-variant-numeric-figure:lining-nums}.oldstyle-nums{--font-variant-numeric-figure:oldstyle-nums}.proportional-nums{--font-variant-numeric-spacing:proportional-nums}.tabular-nums{--font-variant-numeric-spacing:tabular-nums}.diagonal-fractions{--font-variant-numeric-fraction:diagonal-fractions}.stacked-fractions{--font-variant-numeric-fraction:stacked-fractions}.tracking-tighter{letter-spacing:-.05em}.tracking-tight{letter-spacing:-.025em}.tracking-normal{letter-spacing:0}.tracking-wide{letter-spacing:.025em}.tracking-wider{letter-spacing:.05em}.tracking-widest{letter-spacing:.1em}.select-none{-webkit-user-select:none;-ms-user-select:none;user-select:none}.select-text{-webkit-user-select:text;-ms-user-select:text;user-select:text}.select-all{-webkit-user-select:all;-ms-user-select:all;user-select:all}.select-auto{-webkit-user-select:auto;-ms-user-select:auto;user-select:auto}.align-baseline{vertical-align:baseline}.align-top{vertical-align:top}.align-middle{vertical-align:middle}.align-bottom{vertical-align:bottom}.align-text-top{vertical-align:text-top}.align-text-bottom{vertical-align:text-bottom}.visible{visibility:visible}.invisible{visibility:hidden}.whitespace-normal{white-space:normal}.whitespace-no-wrap{white-space:nowrap}.whitespace-pre{white-space:pre}.whitespace-pre-line{white-space:pre-line}.whitespace-pre-wrap{white-space:pre-wrap}.break-normal{word-wrap:normal;overflow-wrap:normal;word-break:normal}.break-words{word-wrap:break-word;overflow-wrap:break-word}.break-all{word-break:break-all}.truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.w-0{width:0}.w-1{width:.25rem}.w-2{width:.5rem}.w-3{width:.75rem}.w-4{width:1rem}.w-5{width:1.25rem}.w-6{width:1.5rem}.w-8{width:2rem}.w-10{width:2.5rem}.w-12{width:3rem}.w-16{width:4rem}.w-20{width:5rem}.w-24{width:6rem}.w-32{width:8rem}.w-40{width:10rem}.w-48{width:12rem}.w-56{width:14rem}.w-64{width:16rem}.w-auto{width:auto}.w-px{width:1px}.w-1\/2{width:50%}.w-1\/3{width:33.333333%}.w-2\/3{width:66.666667%}.w-1\/4{width:25%}.w-2\/4{width:50%}.w-3\/4{width:75%}.w-1\/5{width:20%}.w-2\/5{width:40%}.w-3\/5{width:60%}.w-4\/5{width:80%}.w-1\/6{width:16.666667%}.w-2\/6{width:33.333333%}.w-3\/6{width:50%}.w-4\/6{width:66.666667%}.w-5\/6{width:83.333333%}.w-1\/12{width:8.333333%}.w-2\/12{width:16.666667%}.w-3\/12{width:25%}.w-4\/12{width:33.333333%}.w-5\/12{width:41.666667%}.w-6\/12{width:50%}.w-7\/12{width:58.333333%}.w-8\/12{width:66.666667%}.w-9\/12{width:75%}.w-10\/12{width:83.333333%}.w-11\/12{width:91.666667%}.w-full{width:100%}.w-screen{width:100vw}.z-0{z-index:0}.z-10{z-index:10}.z-20{z-index:20}.z-30{z-index:30}.z-40{z-index:40}.z-50{z-index:50}.z-auto{z-index:auto}.gap-0{grid-gap:0;gap:0}.gap-1{grid-gap:.25rem;gap:.25rem}.gap-2{grid-gap:.5rem;gap:.5rem}.gap-3{grid-gap:.75rem;gap:.75rem}.gap-4{grid-gap:1rem;gap:1rem}.gap-5{grid-gap:1.25rem;gap:1.25rem}.gap-6{grid-gap:1.5rem;gap:1.5rem}.gap-8{grid-gap:2rem;gap:2rem}.gap-10{grid-gap:2.5rem;gap:2.5rem}.gap-12{grid-gap:3rem;gap:3rem}.gap-16{grid-gap:4rem;gap:4rem}.gap-20{grid-gap:5rem;gap:5rem}.gap-24{grid-gap:6rem;gap:6rem}.gap-32{grid-gap:8rem;gap:8rem}.gap-40{grid-gap:10rem;gap:10rem}.gap-48{grid-gap:12rem;gap:12rem}.gap-56{grid-gap:14rem;gap:14rem}.gap-64{grid-gap:16rem;gap:16rem}.gap-px{grid-gap:1px;gap:1px}.col-gap-0{grid-column-gap:0;column-gap:0}.col-gap-1{grid-column-gap:.25rem;column-gap:.25rem}.col-gap-2{grid-column-gap:.5rem;column-gap:.5rem}.col-gap-3{grid-column-gap:.75rem;column-gap:.75rem}.col-gap-4{grid-column-gap:1rem;column-gap:1rem}.col-gap-5{grid-column-gap:1.25rem;column-gap:1.25rem}.col-gap-6{grid-column-gap:1.5rem;column-gap:1.5rem}.col-gap-8{grid-column-gap:2rem;column-gap:2rem}.col-gap-10{grid-column-gap:2.5rem;column-gap:2.5rem}.col-gap-12{grid-column-gap:3rem;column-gap:3rem}.col-gap-16{grid-column-gap:4rem;column-gap:4rem}.col-gap-20{grid-column-gap:5rem;column-gap:5rem}.col-gap-24{grid-column-gap:6rem;column-gap:6rem}.col-gap-32{grid-column-gap:8rem;column-gap:8rem}.col-gap-40{grid-column-gap:10rem;column-gap:10rem}.col-gap-48{grid-column-gap:12rem;column-gap:12rem}.col-gap-56{grid-column-gap:14rem;column-gap:14rem}.col-gap-64{grid-column-gap:16rem;column-gap:16rem}.col-gap-px{grid-column-gap:1px;column-gap:1px}.gap-x-0{grid-column-gap:0;column-gap:0}.gap-x-1{grid-column-gap:.25rem;column-gap:.25rem}.gap-x-2{grid-column-gap:.5rem;column-gap:.5rem}.gap-x-3{grid-column-gap:.75rem;column-gap:.75rem}.gap-x-4{grid-column-gap:1rem;column-gap:1rem}.gap-x-5{grid-column-gap:1.25rem;column-gap:1.25rem}.gap-x-6{grid-column-gap:1.5rem;column-gap:1.5rem}.gap-x-8{grid-column-gap:2rem;column-gap:2rem}.gap-x-10{grid-column-gap:2.5rem;column-gap:2.5rem}.gap-x-12{grid-column-gap:3rem;column-gap:3rem}.gap-x-16{grid-column-gap:4rem;column-gap:4rem}.gap-x-20{grid-column-gap:5rem;column-gap:5rem}.gap-x-24{grid-column-gap:6rem;column-gap:6rem}.gap-x-32{grid-column-gap:8rem;column-gap:8rem}.gap-x-40{grid-column-gap:10rem;column-gap:10rem}.gap-x-48{grid-column-gap:12rem;column-gap:12rem}.gap-x-56{grid-column-gap:14rem;column-gap:14rem}.gap-x-64{grid-column-gap:16rem;column-gap:16rem}.gap-x-px{grid-column-gap:1px;column-gap:1px}.row-gap-0{grid-row-gap:0;row-gap:0}.row-gap-1{grid-row-gap:.25rem;row-gap:.25rem}.row-gap-2{grid-row-gap:.5rem;row-gap:.5rem}.row-gap-3{grid-row-gap:.75rem;row-gap:.75rem}.row-gap-4{grid-row-gap:1rem;row-gap:1rem}.row-gap-5{grid-row-gap:1.25rem;row-gap:1.25rem}.row-gap-6{grid-row-gap:1.5rem;row-gap:1.5rem}.row-gap-8{grid-row-gap:2rem;row-gap:2rem}.row-gap-10{grid-row-gap:2.5rem;row-gap:2.5rem}.row-gap-12{grid-row-gap:3rem;row-gap:3rem}.row-gap-16{grid-row-gap:4rem;row-gap:4rem}.row-gap-20{grid-row-gap:5rem;row-gap:5rem}.row-gap-24{grid-row-gap:6rem;row-gap:6rem}.row-gap-32{grid-row-gap:8rem;row-gap:8rem}.row-gap-40{grid-row-gap:10rem;row-gap:10rem}.row-gap-48{grid-row-gap:12rem;row-gap:12rem}.row-gap-56{grid-row-gap:14rem;row-gap:14rem}.row-gap-64{grid-row-gap:16rem;row-gap:16rem}.row-gap-px{grid-row-gap:1px;row-gap:1px}.gap-y-0{grid-row-gap:0;row-gap:0}.gap-y-1{grid-row-gap:.25rem;row-gap:.25rem}.gap-y-2{grid-row-gap:.5rem;row-gap:.5rem}.gap-y-3{grid-row-gap:.75rem;row-gap:.75rem}.gap-y-4{grid-row-gap:1rem;row-gap:1rem}.gap-y-5{grid-row-gap:1.25rem;row-gap:1.25rem}.gap-y-6{grid-row-gap:1.5rem;row-gap:1.5rem}.gap-y-8{grid-row-gap:2rem;row-gap:2rem}.gap-y-10{grid-row-gap:2.5rem;row-gap:2.5rem}.gap-y-12{grid-row-gap:3rem;row-gap:3rem}.gap-y-16{grid-row-gap:4rem;row-gap:4rem}.gap-y-20{grid-row-gap:5rem;row-gap:5rem}.gap-y-24{grid-row-gap:6rem;row-gap:6rem}.gap-y-32{grid-row-gap:8rem;row-gap:8rem}.gap-y-40{grid-row-gap:10rem;row-gap:10rem}.gap-y-48{grid-row-gap:12rem;row-gap:12rem}.gap-y-56{grid-row-gap:14rem;row-gap:14rem}.gap-y-64{grid-row-gap:16rem;row-gap:16rem}.gap-y-px{grid-row-gap:1px;row-gap:1px}.grid-flow-row{grid-auto-flow:row}.grid-flow-col{grid-auto-flow:column}.grid-flow-row-dense{grid-auto-flow:row dense}.grid-flow-col-dense{grid-auto-flow:column dense}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.grid-cols-5{grid-template-columns:repeat(5,minmax(0,1fr))}.grid-cols-6{grid-template-columns:repeat(6,minmax(0,1fr))}.grid-cols-7{grid-template-columns:repeat(7,minmax(0,1fr))}.grid-cols-8{grid-template-columns:repeat(8,minmax(0,1fr))}.grid-cols-9{grid-template-columns:repeat(9,minmax(0,1fr))}.grid-cols-10{grid-template-columns:repeat(10,minmax(0,1fr))}.grid-cols-11{grid-template-columns:repeat(11,minmax(0,1fr))}.grid-cols-12{grid-template-columns:repeat(12,minmax(0,1fr))}.grid-cols-none{grid-template-columns:none}.auto-cols-auto{grid-auto-columns:auto}.auto-cols-min{grid-auto-columns:-webkit-min-content;grid-auto-columns:min-content}.auto-cols-max{grid-auto-columns:-webkit-max-content;grid-auto-columns:max-content}.auto-cols-fr{grid-auto-columns:minmax(0,1fr)}.col-auto{grid-column:auto}.col-span-1{grid-column:span 1/span 1}.col-span-2{grid-column:span 2/span 2}.col-span-3{grid-column:span 3/span 3}.col-span-4{grid-column:span 4/span 4}.col-span-5{grid-column:span 5/span 5}.col-span-6{grid-column:span 6/span 6}.col-span-7{grid-column:span 7/span 7}.col-span-8{grid-column:span 8/span 8}.col-span-9{grid-column:span 9/span 9}.col-span-10{grid-column:span 10/span 10}.col-span-11{grid-column:span 11/span 11}.col-span-12{grid-column:span 12/span 12}.col-span-full{grid-column:1/-1}.col-start-1{grid-column-start:1}.col-start-2{grid-column-start:2}.col-start-3{grid-column-start:3}.col-start-4{grid-column-start:4}.col-start-5{grid-column-start:5}.col-start-6{grid-column-start:6}.col-start-7{grid-column-start:7}.col-start-8{grid-column-start:8}.col-start-9{grid-column-start:9}.col-start-10{grid-column-start:10}.col-start-11{grid-column-start:11}.col-start-12{grid-column-start:12}.col-start-13{grid-column-start:13}.col-start-auto{grid-column-start:auto}.col-end-1{grid-column-end:1}.col-end-2{grid-column-end:2}.col-end-3{grid-column-end:3}.col-end-4{grid-column-end:4}.col-end-5{grid-column-end:5}.col-end-6{grid-column-end:6}.col-end-7{grid-column-end:7}.col-end-8{grid-column-end:8}.col-end-9{grid-column-end:9}.col-end-10{grid-column-end:10}.col-end-11{grid-column-end:11}.col-end-12{grid-column-end:12}.col-end-13{grid-column-end:13}.col-end-auto{grid-column-end:auto}.grid-rows-1{grid-template-rows:repeat(1,minmax(0,1fr))}.grid-rows-2{grid-template-rows:repeat(2,minmax(0,1fr))}.grid-rows-3{grid-template-rows:repeat(3,minmax(0,1fr))}.grid-rows-4{grid-template-rows:repeat(4,minmax(0,1fr))}.grid-rows-5{grid-template-rows:repeat(5,minmax(0,1fr))}.grid-rows-6{grid-template-rows:repeat(6,minmax(0,1fr))}.grid-rows-none{grid-template-rows:none}.auto-rows-auto{grid-auto-rows:auto}.auto-rows-min{grid-auto-rows:-webkit-min-content;grid-auto-rows:min-content}.auto-rows-max{grid-auto-rows:-webkit-max-content;grid-auto-rows:max-content}.auto-rows-fr{grid-auto-rows:minmax(0,1fr)}.row-auto{grid-row:auto}.row-span-1{grid-row:span 1/span 1}.row-span-2{grid-row:span 2/span 2}.row-span-3{grid-row:span 3/span 3}.row-span-4{grid-row:span 4/span 4}.row-span-5{grid-row:span 5/span 5}.row-span-6{grid-row:span 6/span 6}.row-span-full{grid-row:1/-1}.row-start-1{grid-row-start:1}.row-start-2{grid-row-start:2}.row-start-3{grid-row-start:3}.row-start-4{grid-row-start:4}.row-start-5{grid-row-start:5}.row-start-6{grid-row-start:6}.row-start-7{grid-row-start:7}.row-start-auto{grid-row-start:auto}.row-end-1{grid-row-end:1}.row-end-2{grid-row-end:2}.row-end-3{grid-row-end:3}.row-end-4{grid-row-end:4}.row-end-5{grid-row-end:5}.row-end-6{grid-row-end:6}.row-end-7{grid-row-end:7}.row-end-auto{grid-row-end:auto}.transform{--transform-translate-x:0;--transform-translate-y:0;--transform-rotate:0;--transform-skew-x:0;--transform-skew-y:0;--transform-scale-x:1;--transform-scale-y:1;transform:translateX(var(--transform-translate-x)) translateY(var(--transform-translate-y)) rotate(var(--transform-rotate)) skewX(var(--transform-skew-x)) skewY(var(--transform-skew-y)) scaleX(var(--transform-scale-x)) scaleY(var(--transform-scale-y))}.transform-none{transform:none}.origin-center{transform-origin:center}.origin-top{transform-origin:top}.origin-top-right{transform-origin:top right}.origin-right{transform-origin:right}.origin-bottom-right{transform-origin:bottom right}.origin-bottom{transform-origin:bottom}.origin-bottom-left{transform-origin:bottom left}.origin-left{transform-origin:left}.origin-top-left{transform-origin:top left}.scale-0{--transform-scale-x:0;--transform-scale-y:0}.scale-50{--transform-scale-x:.5;--transform-scale-y:.5}.scale-75{--transform-scale-x:.75;--transform-scale-y:.75}.scale-90{--transform-scale-x:.9;--transform-scale-y:.9}.scale-95{--transform-scale-x:.95;--transform-scale-y:.95}.scale-100{--transform-scale-x:1;--transform-scale-y:1}.scale-105{--transform-scale-x:1.05;--transform-scale-y:1.05}.scale-110{--transform-scale-x:1.1;--transform-scale-y:1.1}.scale-125{--transform-scale-x:1.25;--transform-scale-y:1.25}.scale-150{--transform-scale-x:1.5;--transform-scale-y:1.5}.scale-x-0{--transform-scale-x:0}.scale-x-50{--transform-scale-x:.5}.scale-x-75{--transform-scale-x:.75}.scale-x-90{--transform-scale-x:.9}.scale-x-95{--transform-scale-x:.95}.scale-x-100{--transform-scale-x:1}.scale-x-105{--transform-scale-x:1.05}.scale-x-110{--transform-scale-x:1.1}.scale-x-125{--transform-scale-x:1.25}.scale-x-150{--transform-scale-x:1.5}.scale-y-0{--transform-scale-y:0}.scale-y-50{--transform-scale-y:.5}.scale-y-75{--transform-scale-y:.75}.scale-y-90{--transform-scale-y:.9}.scale-y-95{--transform-scale-y:.95}.scale-y-100{--transform-scale-y:1}.scale-y-105{--transform-scale-y:1.05}.scale-y-110{--transform-scale-y:1.1}.scale-y-125{--transform-scale-y:1.25}.scale-y-150{--transform-scale-y:1.5}.hover\:scale-0:hover{--transform-scale-x:0;--transform-scale-y:0}.hover\:scale-50:hover{--transform-scale-x:.5;--transform-scale-y:.5}.hover\:scale-75:hover{--transform-scale-x:.75;--transform-scale-y:.75}.hover\:scale-90:hover{--transform-scale-x:.9;--transform-scale-y:.9}.hover\:scale-95:hover{--transform-scale-x:.95;--transform-scale-y:.95}.hover\:scale-100:hover{--transform-scale-x:1;--transform-scale-y:1}.hover\:scale-105:hover{--transform-scale-x:1.05;--transform-scale-y:1.05}.hover\:scale-110:hover{--transform-scale-x:1.1;--transform-scale-y:1.1}.hover\:scale-125:hover{--transform-scale-x:1.25;--transform-scale-y:1.25}.hover\:scale-150:hover{--transform-scale-x:1.5;--transform-scale-y:1.5}.hover\:scale-x-0:hover{--transform-scale-x:0}.hover\:scale-x-50:hover{--transform-scale-x:.5}.hover\:scale-x-75:hover{--transform-scale-x:.75}.hover\:scale-x-90:hover{--transform-scale-x:.9}.hover\:scale-x-95:hover{--transform-scale-x:.95}.hover\:scale-x-100:hover{--transform-scale-x:1}.hover\:scale-x-105:hover{--transform-scale-x:1.05}.hover\:scale-x-110:hover{--transform-scale-x:1.1}.hover\:scale-x-125:hover{--transform-scale-x:1.25}.hover\:scale-x-150:hover{--transform-scale-x:1.5}.hover\:scale-y-0:hover{--transform-scale-y:0}.hover\:scale-y-50:hover{--transform-scale-y:.5}.hover\:scale-y-75:hover{--transform-scale-y:.75}.hover\:scale-y-90:hover{--transform-scale-y:.9}.hover\:scale-y-95:hover{--transform-scale-y:.95}.hover\:scale-y-100:hover{--transform-scale-y:1}.hover\:scale-y-105:hover{--transform-scale-y:1.05}.hover\:scale-y-110:hover{--transform-scale-y:1.1}.hover\:scale-y-125:hover{--transform-scale-y:1.25}.hover\:scale-y-150:hover{--transform-scale-y:1.5}.focus\:scale-0:focus{--transform-scale-x:0;--transform-scale-y:0}.focus\:scale-50:focus{--transform-scale-x:.5;--transform-scale-y:.5}.focus\:scale-75:focus{--transform-scale-x:.75;--transform-scale-y:.75}.focus\:scale-90:focus{--transform-scale-x:.9;--transform-scale-y:.9}.focus\:scale-95:focus{--transform-scale-x:.95;--transform-scale-y:.95}.focus\:scale-100:focus{--transform-scale-x:1;--transform-scale-y:1}.focus\:scale-105:focus{--transform-scale-x:1.05;--transform-scale-y:1.05}.focus\:scale-110:focus{--transform-scale-x:1.1;--transform-scale-y:1.1}.focus\:scale-125:focus{--transform-scale-x:1.25;--transform-scale-y:1.25}.focus\:scale-150:focus{--transform-scale-x:1.5;--transform-scale-y:1.5}.focus\:scale-x-0:focus{--transform-scale-x:0}.focus\:scale-x-50:focus{--transform-scale-x:.5}.focus\:scale-x-75:focus{--transform-scale-x:.75}.focus\:scale-x-90:focus{--transform-scale-x:.9}.focus\:scale-x-95:focus{--transform-scale-x:.95}.focus\:scale-x-100:focus{--transform-scale-x:1}.focus\:scale-x-105:focus{--transform-scale-x:1.05}.focus\:scale-x-110:focus{--transform-scale-x:1.1}.focus\:scale-x-125:focus{--transform-scale-x:1.25}.focus\:scale-x-150:focus{--transform-scale-x:1.5}.focus\:scale-y-0:focus{--transform-scale-y:0}.focus\:scale-y-50:focus{--transform-scale-y:.5}.focus\:scale-y-75:focus{--transform-scale-y:.75}.focus\:scale-y-90:focus{--transform-scale-y:.9}.focus\:scale-y-95:focus{--transform-scale-y:.95}.focus\:scale-y-100:focus{--transform-scale-y:1}.focus\:scale-y-105:focus{--transform-scale-y:1.05}.focus\:scale-y-110:focus{--transform-scale-y:1.1}.focus\:scale-y-125:focus{--transform-scale-y:1.25}.focus\:scale-y-150:focus{--transform-scale-y:1.5}.rotate-0{--transform-rotate:0}.rotate-1{--transform-rotate:1deg}.rotate-2{--transform-rotate:2deg}.rotate-3{--transform-rotate:3deg}.rotate-6{--transform-rotate:6deg}.rotate-12{--transform-rotate:12deg}.rotate-45{--transform-rotate:45deg}.rotate-90{--transform-rotate:90deg}.rotate-180{--transform-rotate:180deg}.-rotate-180{--transform-rotate:-180deg}.-rotate-90{--transform-rotate:-90deg}.-rotate-45{--transform-rotate:-45deg}.-rotate-12{--transform-rotate:-12deg}.-rotate-6{--transform-rotate:-6deg}.-rotate-3{--transform-rotate:-3deg}.-rotate-2{--transform-rotate:-2deg}.-rotate-1{--transform-rotate:-1deg}.hover\:rotate-0:hover{--transform-rotate:0}.hover\:rotate-1:hover{--transform-rotate:1deg}.hover\:rotate-2:hover{--transform-rotate:2deg}.hover\:rotate-3:hover{--transform-rotate:3deg}.hover\:rotate-6:hover{--transform-rotate:6deg}.hover\:rotate-12:hover{--transform-rotate:12deg}.hover\:rotate-45:hover{--transform-rotate:45deg}.hover\:rotate-90:hover{--transform-rotate:90deg}.hover\:rotate-180:hover{--transform-rotate:180deg}.hover\:-rotate-180:hover{--transform-rotate:-180deg}.hover\:-rotate-90:hover{--transform-rotate:-90deg}.hover\:-rotate-45:hover{--transform-rotate:-45deg}.hover\:-rotate-12:hover{--transform-rotate:-12deg}.hover\:-rotate-6:hover{--transform-rotate:-6deg}.hover\:-rotate-3:hover{--transform-rotate:-3deg}.hover\:-rotate-2:hover{--transform-rotate:-2deg}.hover\:-rotate-1:hover{--transform-rotate:-1deg}.focus\:rotate-0:focus{--transform-rotate:0}.focus\:rotate-1:focus{--transform-rotate:1deg}.focus\:rotate-2:focus{--transform-rotate:2deg}.focus\:rotate-3:focus{--transform-rotate:3deg}.focus\:rotate-6:focus{--transform-rotate:6deg}.focus\:rotate-12:focus{--transform-rotate:12deg}.focus\:rotate-45:focus{--transform-rotate:45deg}.focus\:rotate-90:focus{--transform-rotate:90deg}.focus\:rotate-180:focus{--transform-rotate:180deg}.focus\:-rotate-180:focus{--transform-rotate:-180deg}.focus\:-rotate-90:focus{--transform-rotate:-90deg}.focus\:-rotate-45:focus{--transform-rotate:-45deg}.focus\:-rotate-12:focus{--transform-rotate:-12deg}.focus\:-rotate-6:focus{--transform-rotate:-6deg}.focus\:-rotate-3:focus{--transform-rotate:-3deg}.focus\:-rotate-2:focus{--transform-rotate:-2deg}.focus\:-rotate-1:focus{--transform-rotate:-1deg}.translate-x-0{--transform-translate-x:0}.translate-x-1{--transform-translate-x:0.25rem}.translate-x-2{--transform-translate-x:0.5rem}.translate-x-3{--transform-translate-x:0.75rem}.translate-x-4{--transform-translate-x:1rem}.translate-x-5{--transform-translate-x:1.25rem}.translate-x-6{--transform-translate-x:1.5rem}.translate-x-8{--transform-translate-x:2rem}.translate-x-10{--transform-translate-x:2.5rem}.translate-x-12{--transform-translate-x:3rem}.translate-x-16{--transform-translate-x:4rem}.translate-x-20{--transform-translate-x:5rem}.translate-x-24{--transform-translate-x:6rem}.translate-x-32{--transform-translate-x:8rem}.translate-x-40{--transform-translate-x:10rem}.translate-x-48{--transform-translate-x:12rem}.translate-x-56{--transform-translate-x:14rem}.translate-x-64{--transform-translate-x:16rem}.translate-x-px{--transform-translate-x:1px}.-translate-x-1{--transform-translate-x:-0.25rem}.-translate-x-2{--transform-translate-x:-0.5rem}.-translate-x-3{--transform-translate-x:-0.75rem}.-translate-x-4{--transform-translate-x:-1rem}.-translate-x-5{--transform-translate-x:-1.25rem}.-translate-x-6{--transform-translate-x:-1.5rem}.-translate-x-8{--transform-translate-x:-2rem}.-translate-x-10{--transform-translate-x:-2.5rem}.-translate-x-12{--transform-translate-x:-3rem}.-translate-x-16{--transform-translate-x:-4rem}.-translate-x-20{--transform-translate-x:-5rem}.-translate-x-24{--transform-translate-x:-6rem}.-translate-x-32{--transform-translate-x:-8rem}.-translate-x-40{--transform-translate-x:-10rem}.-translate-x-48{--transform-translate-x:-12rem}.-translate-x-56{--transform-translate-x:-14rem}.-translate-x-64{--transform-translate-x:-16rem}.-translate-x-px{--transform-translate-x:-1px}.-translate-x-full{--transform-translate-x:-100%}.-translate-x-1\/2{--transform-translate-x:-50%}.translate-x-1\/2{--transform-translate-x:50%}.translate-x-full{--transform-translate-x:100%}.translate-y-0{--transform-translate-y:0}.translate-y-1{--transform-translate-y:0.25rem}.translate-y-2{--transform-translate-y:0.5rem}.translate-y-3{--transform-translate-y:0.75rem}.translate-y-4{--transform-translate-y:1rem}.translate-y-5{--transform-translate-y:1.25rem}.translate-y-6{--transform-translate-y:1.5rem}.translate-y-8{--transform-translate-y:2rem}.translate-y-10{--transform-translate-y:2.5rem}.translate-y-12{--transform-translate-y:3rem}.translate-y-16{--transform-translate-y:4rem}.translate-y-20{--transform-translate-y:5rem}.translate-y-24{--transform-translate-y:6rem}.translate-y-32{--transform-translate-y:8rem}.translate-y-40{--transform-translate-y:10rem}.translate-y-48{--transform-translate-y:12rem}.translate-y-56{--transform-translate-y:14rem}.translate-y-64{--transform-translate-y:16rem}.translate-y-px{--transform-translate-y:1px}.-translate-y-1{--transform-translate-y:-0.25rem}.-translate-y-2{--transform-translate-y:-0.5rem}.-translate-y-3{--transform-translate-y:-0.75rem}.-translate-y-4{--transform-translate-y:-1rem}.-translate-y-5{--transform-translate-y:-1.25rem}.-translate-y-6{--transform-translate-y:-1.5rem}.-translate-y-8{--transform-translate-y:-2rem}.-translate-y-10{--transform-translate-y:-2.5rem}.-translate-y-12{--transform-translate-y:-3rem}.-translate-y-16{--transform-translate-y:-4rem}.-translate-y-20{--transform-translate-y:-5rem}.-translate-y-24{--transform-translate-y:-6rem}.-translate-y-32{--transform-translate-y:-8rem}.-translate-y-40{--transform-translate-y:-10rem}.-translate-y-48{--transform-translate-y:-12rem}.-translate-y-56{--transform-translate-y:-14rem}.-translate-y-64{--transform-translate-y:-16rem}.-translate-y-px{--transform-translate-y:-1px}.-translate-y-full{--transform-translate-y:-100%}.-translate-y-1\/2{--transform-translate-y:-50%}.translate-y-1\/2{--transform-translate-y:50%}.translate-y-full{--transform-translate-y:100%}.hover\:translate-x-0:hover{--transform-translate-x:0}.hover\:translate-x-1:hover{--transform-translate-x:0.25rem}.hover\:translate-x-2:hover{--transform-translate-x:0.5rem}.hover\:translate-x-3:hover{--transform-translate-x:0.75rem}.hover\:translate-x-4:hover{--transform-translate-x:1rem}.hover\:translate-x-5:hover{--transform-translate-x:1.25rem}.hover\:translate-x-6:hover{--transform-translate-x:1.5rem}.hover\:translate-x-8:hover{--transform-translate-x:2rem}.hover\:translate-x-10:hover{--transform-translate-x:2.5rem}.hover\:translate-x-12:hover{--transform-translate-x:3rem}.hover\:translate-x-16:hover{--transform-translate-x:4rem}.hover\:translate-x-20:hover{--transform-translate-x:5rem}.hover\:translate-x-24:hover{--transform-translate-x:6rem}.hover\:translate-x-32:hover{--transform-translate-x:8rem}.hover\:translate-x-40:hover{--transform-translate-x:10rem}.hover\:translate-x-48:hover{--transform-translate-x:12rem}.hover\:translate-x-56:hover{--transform-translate-x:14rem}.hover\:translate-x-64:hover{--transform-translate-x:16rem}.hover\:translate-x-px:hover{--transform-translate-x:1px}.hover\:-translate-x-1:hover{--transform-translate-x:-0.25rem}.hover\:-translate-x-2:hover{--transform-translate-x:-0.5rem}.hover\:-translate-x-3:hover{--transform-translate-x:-0.75rem}.hover\:-translate-x-4:hover{--transform-translate-x:-1rem}.hover\:-translate-x-5:hover{--transform-translate-x:-1.25rem}.hover\:-translate-x-6:hover{--transform-translate-x:-1.5rem}.hover\:-translate-x-8:hover{--transform-translate-x:-2rem}.hover\:-translate-x-10:hover{--transform-translate-x:-2.5rem}.hover\:-translate-x-12:hover{--transform-translate-x:-3rem}.hover\:-translate-x-16:hover{--transform-translate-x:-4rem}.hover\:-translate-x-20:hover{--transform-translate-x:-5rem}.hover\:-translate-x-24:hover{--transform-translate-x:-6rem}.hover\:-translate-x-32:hover{--transform-translate-x:-8rem}.hover\:-translate-x-40:hover{--transform-translate-x:-10rem}.hover\:-translate-x-48:hover{--transform-translate-x:-12rem}.hover\:-translate-x-56:hover{--transform-translate-x:-14rem}.hover\:-translate-x-64:hover{--transform-translate-x:-16rem}.hover\:-translate-x-px:hover{--transform-translate-x:-1px}.hover\:-translate-x-full:hover{--transform-translate-x:-100%}.hover\:-translate-x-1\/2:hover{--transform-translate-x:-50%}.hover\:translate-x-1\/2:hover{--transform-translate-x:50%}.hover\:translate-x-full:hover{--transform-translate-x:100%}.hover\:translate-y-0:hover{--transform-translate-y:0}.hover\:translate-y-1:hover{--transform-translate-y:0.25rem}.hover\:translate-y-2:hover{--transform-translate-y:0.5rem}.hover\:translate-y-3:hover{--transform-translate-y:0.75rem}.hover\:translate-y-4:hover{--transform-translate-y:1rem}.hover\:translate-y-5:hover{--transform-translate-y:1.25rem}.hover\:translate-y-6:hover{--transform-translate-y:1.5rem}.hover\:translate-y-8:hover{--transform-translate-y:2rem}.hover\:translate-y-10:hover{--transform-translate-y:2.5rem}.hover\:translate-y-12:hover{--transform-translate-y:3rem}.hover\:translate-y-16:hover{--transform-translate-y:4rem}.hover\:translate-y-20:hover{--transform-translate-y:5rem}.hover\:translate-y-24:hover{--transform-translate-y:6rem}.hover\:translate-y-32:hover{--transform-translate-y:8rem}.hover\:translate-y-40:hover{--transform-translate-y:10rem}.hover\:translate-y-48:hover{--transform-translate-y:12rem}.hover\:translate-y-56:hover{--transform-translate-y:14rem}.hover\:translate-y-64:hover{--transform-translate-y:16rem}.hover\:translate-y-px:hover{--transform-translate-y:1px}.hover\:-translate-y-1:hover{--transform-translate-y:-0.25rem}.hover\:-translate-y-2:hover{--transform-translate-y:-0.5rem}.hover\:-translate-y-3:hover{--transform-translate-y:-0.75rem}.hover\:-translate-y-4:hover{--transform-translate-y:-1rem}.hover\:-translate-y-5:hover{--transform-translate-y:-1.25rem}.hover\:-translate-y-6:hover{--transform-translate-y:-1.5rem}.hover\:-translate-y-8:hover{--transform-translate-y:-2rem}.hover\:-translate-y-10:hover{--transform-translate-y:-2.5rem}.hover\:-translate-y-12:hover{--transform-translate-y:-3rem}.hover\:-translate-y-16:hover{--transform-translate-y:-4rem}.hover\:-translate-y-20:hover{--transform-translate-y:-5rem}.hover\:-translate-y-24:hover{--transform-translate-y:-6rem}.hover\:-translate-y-32:hover{--transform-translate-y:-8rem}.hover\:-translate-y-40:hover{--transform-translate-y:-10rem}.hover\:-translate-y-48:hover{--transform-translate-y:-12rem}.hover\:-translate-y-56:hover{--transform-translate-y:-14rem}.hover\:-translate-y-64:hover{--transform-translate-y:-16rem}.hover\:-translate-y-px:hover{--transform-translate-y:-1px}.hover\:-translate-y-full:hover{--transform-translate-y:-100%}.hover\:-translate-y-1\/2:hover{--transform-translate-y:-50%}.hover\:translate-y-1\/2:hover{--transform-translate-y:50%}.hover\:translate-y-full:hover{--transform-translate-y:100%}.focus\:translate-x-0:focus{--transform-translate-x:0}.focus\:translate-x-1:focus{--transform-translate-x:0.25rem}.focus\:translate-x-2:focus{--transform-translate-x:0.5rem}.focus\:translate-x-3:focus{--transform-translate-x:0.75rem}.focus\:translate-x-4:focus{--transform-translate-x:1rem}.focus\:translate-x-5:focus{--transform-translate-x:1.25rem}.focus\:translate-x-6:focus{--transform-translate-x:1.5rem}.focus\:translate-x-8:focus{--transform-translate-x:2rem}.focus\:translate-x-10:focus{--transform-translate-x:2.5rem}.focus\:translate-x-12:focus{--transform-translate-x:3rem}.focus\:translate-x-16:focus{--transform-translate-x:4rem}.focus\:translate-x-20:focus{--transform-translate-x:5rem}.focus\:translate-x-24:focus{--transform-translate-x:6rem}.focus\:translate-x-32:focus{--transform-translate-x:8rem}.focus\:translate-x-40:focus{--transform-translate-x:10rem}.focus\:translate-x-48:focus{--transform-translate-x:12rem}.focus\:translate-x-56:focus{--transform-translate-x:14rem}.focus\:translate-x-64:focus{--transform-translate-x:16rem}.focus\:translate-x-px:focus{--transform-translate-x:1px}.focus\:-translate-x-1:focus{--transform-translate-x:-0.25rem}.focus\:-translate-x-2:focus{--transform-translate-x:-0.5rem}.focus\:-translate-x-3:focus{--transform-translate-x:-0.75rem}.focus\:-translate-x-4:focus{--transform-translate-x:-1rem}.focus\:-translate-x-5:focus{--transform-translate-x:-1.25rem}.focus\:-translate-x-6:focus{--transform-translate-x:-1.5rem}.focus\:-translate-x-8:focus{--transform-translate-x:-2rem}.focus\:-translate-x-10:focus{--transform-translate-x:-2.5rem}.focus\:-translate-x-12:focus{--transform-translate-x:-3rem}.focus\:-translate-x-16:focus{--transform-translate-x:-4rem}.focus\:-translate-x-20:focus{--transform-translate-x:-5rem}.focus\:-translate-x-24:focus{--transform-translate-x:-6rem}.focus\:-translate-x-32:focus{--transform-translate-x:-8rem}.focus\:-translate-x-40:focus{--transform-translate-x:-10rem}.focus\:-translate-x-48:focus{--transform-translate-x:-12rem}.focus\:-translate-x-56:focus{--transform-translate-x:-14rem}.focus\:-translate-x-64:focus{--transform-translate-x:-16rem}.focus\:-translate-x-px:focus{--transform-translate-x:-1px}.focus\:-translate-x-full:focus{--transform-translate-x:-100%}.focus\:-translate-x-1\/2:focus{--transform-translate-x:-50%}.focus\:translate-x-1\/2:focus{--transform-translate-x:50%}.focus\:translate-x-full:focus{--transform-translate-x:100%}.focus\:translate-y-0:focus{--transform-translate-y:0}.focus\:translate-y-1:focus{--transform-translate-y:0.25rem}.focus\:translate-y-2:focus{--transform-translate-y:0.5rem}.focus\:translate-y-3:focus{--transform-translate-y:0.75rem}.focus\:translate-y-4:focus{--transform-translate-y:1rem}.focus\:translate-y-5:focus{--transform-translate-y:1.25rem}.focus\:translate-y-6:focus{--transform-translate-y:1.5rem}.focus\:translate-y-8:focus{--transform-translate-y:2rem}.focus\:translate-y-10:focus{--transform-translate-y:2.5rem}.focus\:translate-y-12:focus{--transform-translate-y:3rem}.focus\:translate-y-16:focus{--transform-translate-y:4rem}.focus\:translate-y-20:focus{--transform-translate-y:5rem}.focus\:translate-y-24:focus{--transform-translate-y:6rem}.focus\:translate-y-32:focus{--transform-translate-y:8rem}.focus\:translate-y-40:focus{--transform-translate-y:10rem}.focus\:translate-y-48:focus{--transform-translate-y:12rem}.focus\:translate-y-56:focus{--transform-translate-y:14rem}.focus\:translate-y-64:focus{--transform-translate-y:16rem}.focus\:translate-y-px:focus{--transform-translate-y:1px}.focus\:-translate-y-1:focus{--transform-translate-y:-0.25rem}.focus\:-translate-y-2:focus{--transform-translate-y:-0.5rem}.focus\:-translate-y-3:focus{--transform-translate-y:-0.75rem}.focus\:-translate-y-4:focus{--transform-translate-y:-1rem}.focus\:-translate-y-5:focus{--transform-translate-y:-1.25rem}.focus\:-translate-y-6:focus{--transform-translate-y:-1.5rem}.focus\:-translate-y-8:focus{--transform-translate-y:-2rem}.focus\:-translate-y-10:focus{--transform-translate-y:-2.5rem}.focus\:-translate-y-12:focus{--transform-translate-y:-3rem}.focus\:-translate-y-16:focus{--transform-translate-y:-4rem}.focus\:-translate-y-20:focus{--transform-translate-y:-5rem}.focus\:-translate-y-24:focus{--transform-translate-y:-6rem}.focus\:-translate-y-32:focus{--transform-translate-y:-8rem}.focus\:-translate-y-40:focus{--transform-translate-y:-10rem}.focus\:-translate-y-48:focus{--transform-translate-y:-12rem}.focus\:-translate-y-56:focus{--transform-translate-y:-14rem}.focus\:-translate-y-64:focus{--transform-translate-y:-16rem}.focus\:-translate-y-px:focus{--transform-translate-y:-1px}.focus\:-translate-y-full:focus{--transform-translate-y:-100%}.focus\:-translate-y-1\/2:focus{--transform-translate-y:-50%}.focus\:translate-y-1\/2:focus{--transform-translate-y:50%}.focus\:translate-y-full:focus{--transform-translate-y:100%}.skew-x-0{--transform-skew-x:0}.skew-x-1{--transform-skew-x:1deg}.skew-x-2{--transform-skew-x:2deg}.skew-x-3{--transform-skew-x:3deg}.skew-x-6{--transform-skew-x:6deg}.skew-x-12{--transform-skew-x:12deg}.-skew-x-12{--transform-skew-x:-12deg}.-skew-x-6{--transform-skew-x:-6deg}.-skew-x-3{--transform-skew-x:-3deg}.-skew-x-2{--transform-skew-x:-2deg}.-skew-x-1{--transform-skew-x:-1deg}.skew-y-0{--transform-skew-y:0}.skew-y-1{--transform-skew-y:1deg}.skew-y-2{--transform-skew-y:2deg}.skew-y-3{--transform-skew-y:3deg}.skew-y-6{--transform-skew-y:6deg}.skew-y-12{--transform-skew-y:12deg}.-skew-y-12{--transform-skew-y:-12deg}.-skew-y-6{--transform-skew-y:-6deg}.-skew-y-3{--transform-skew-y:-3deg}.-skew-y-2{--transform-skew-y:-2deg}.-skew-y-1{--transform-skew-y:-1deg}.hover\:skew-x-0:hover{--transform-skew-x:0}.hover\:skew-x-1:hover{--transform-skew-x:1deg}.hover\:skew-x-2:hover{--transform-skew-x:2deg}.hover\:skew-x-3:hover{--transform-skew-x:3deg}.hover\:skew-x-6:hover{--transform-skew-x:6deg}.hover\:skew-x-12:hover{--transform-skew-x:12deg}.hover\:-skew-x-12:hover{--transform-skew-x:-12deg}.hover\:-skew-x-6:hover{--transform-skew-x:-6deg}.hover\:-skew-x-3:hover{--transform-skew-x:-3deg}.hover\:-skew-x-2:hover{--transform-skew-x:-2deg}.hover\:-skew-x-1:hover{--transform-skew-x:-1deg}.hover\:skew-y-0:hover{--transform-skew-y:0}.hover\:skew-y-1:hover{--transform-skew-y:1deg}.hover\:skew-y-2:hover{--transform-skew-y:2deg}.hover\:skew-y-3:hover{--transform-skew-y:3deg}.hover\:skew-y-6:hover{--transform-skew-y:6deg}.hover\:skew-y-12:hover{--transform-skew-y:12deg}.hover\:-skew-y-12:hover{--transform-skew-y:-12deg}.hover\:-skew-y-6:hover{--transform-skew-y:-6deg}.hover\:-skew-y-3:hover{--transform-skew-y:-3deg}.hover\:-skew-y-2:hover{--transform-skew-y:-2deg}.hover\:-skew-y-1:hover{--transform-skew-y:-1deg}.focus\:skew-x-0:focus{--transform-skew-x:0}.focus\:skew-x-1:focus{--transform-skew-x:1deg}.focus\:skew-x-2:focus{--transform-skew-x:2deg}.focus\:skew-x-3:focus{--transform-skew-x:3deg}.focus\:skew-x-6:focus{--transform-skew-x:6deg}.focus\:skew-x-12:focus{--transform-skew-x:12deg}.focus\:-skew-x-12:focus{--transform-skew-x:-12deg}.focus\:-skew-x-6:focus{--transform-skew-x:-6deg}.focus\:-skew-x-3:focus{--transform-skew-x:-3deg}.focus\:-skew-x-2:focus{--transform-skew-x:-2deg}.focus\:-skew-x-1:focus{--transform-skew-x:-1deg}.focus\:skew-y-0:focus{--transform-skew-y:0}.focus\:skew-y-1:focus{--transform-skew-y:1deg}.focus\:skew-y-2:focus{--transform-skew-y:2deg}.focus\:skew-y-3:focus{--transform-skew-y:3deg}.focus\:skew-y-6:focus{--transform-skew-y:6deg}.focus\:skew-y-12:focus{--transform-skew-y:12deg}.focus\:-skew-y-12:focus{--transform-skew-y:-12deg}.focus\:-skew-y-6:focus{--transform-skew-y:-6deg}.focus\:-skew-y-3:focus{--transform-skew-y:-3deg}.focus\:-skew-y-2:focus{--transform-skew-y:-2deg}.focus\:-skew-y-1:focus{--transform-skew-y:-1deg}.transition-none{transition-property:none}.transition-all{transition-property:all}.transition{transition-property:background-color,border-color,color,fill,stroke,opacity,box-shadow,transform}.transition-colors{transition-property:background-color,border-color,color,fill,stroke}.transition-opacity{transition-property:opacity}.transition-shadow{transition-property:box-shadow}.transition-transform{transition-property:transform}.ease-linear{transition-timing-function:linear}.ease-in{transition-timing-function:cubic-bezier(.4,0,1,1)}.ease-out{transition-timing-function:cubic-bezier(0,0,.2,1)}.ease-in-out{transition-timing-function:cubic-bezier(.4,0,.2,1)}.duration-75{transition-duration:75ms}.duration-100{transition-duration:.1s}.duration-150{transition-duration:150ms}.duration-200{transition-duration:.2s}.duration-300{transition-duration:.3s}.duration-500{transition-duration:.5s}.duration-700{transition-duration:.7s}.duration-1000{transition-duration:1s}.delay-75{transition-delay:75ms}.delay-100{transition-delay:.1s}.delay-150{transition-delay:150ms}.delay-200{transition-delay:.2s}.delay-300{transition-delay:.3s}.delay-500{transition-delay:.5s}.delay-700{transition-delay:.7s}.delay-1000{transition-delay:1s}@keyframes spin{to{transform:rotate(360deg)}}@keyframes ping{100%,75%{transform:scale(2);opacity:0}}@keyframes pulse{50%{opacity:.5}}@keyframes bounce{0%,100%{transform:translateY(-25%);animation-timing-function:cubic-bezier(.8,0,1,1)}50%{transform:none;animation-timing-function:cubic-bezier(0,0,.2,1)}}.animate-none{animation:none}.animate-spin{animation:spin 1s linear infinite}.animate-ping{animation:ping 1s cubic-bezier(0,0,.2,1) infinite}.animate-pulse{animation:pulse 2s cubic-bezier(.4,0,.6,1) infinite}.animate-bounce{animation:bounce 1s infinite}@media (min-width:640px){.sm\:container{width:100%}@media (min-width:640px){.sm\:container{max-width:640px}}@media (min-width:768px){.sm\:container{max-width:768px}}@media (min-width:1024px){.sm\:container{max-width:1024px}}@media (min-width:1280px){.sm\:container{max-width:1280px}}.sm\:space-y-0>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(0px * calc(1 - var(--space-y-reverse)));margin-bottom:calc(0px * var(--space-y-reverse))}.sm\:space-x-0>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(0px * var(--space-x-reverse));margin-left:calc(0px * calc(1 - var(--space-x-reverse)))}.sm\:space-y-1>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(.25rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(.25rem * var(--space-y-reverse))}.sm\:space-x-1>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(.25rem * var(--space-x-reverse));margin-left:calc(.25rem * calc(1 - var(--space-x-reverse)))}.sm\:space-y-2>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(.5rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(.5rem * var(--space-y-reverse))}.sm\:space-x-2>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(.5rem * var(--space-x-reverse));margin-left:calc(.5rem * calc(1 - var(--space-x-reverse)))}.sm\:space-y-3>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(.75rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(.75rem * var(--space-y-reverse))}.sm\:space-x-3>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(.75rem * var(--space-x-reverse));margin-left:calc(.75rem * calc(1 - var(--space-x-reverse)))}.sm\:space-y-4>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(1rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(1rem * var(--space-y-reverse))}.sm\:space-x-4>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(1rem * var(--space-x-reverse));margin-left:calc(1rem * calc(1 - var(--space-x-reverse)))}.sm\:space-y-5>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(1.25rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(1.25rem * var(--space-y-reverse))}.sm\:space-x-5>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(1.25rem * var(--space-x-reverse));margin-left:calc(1.25rem * calc(1 - var(--space-x-reverse)))}.sm\:space-y-6>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(1.5rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(1.5rem * var(--space-y-reverse))}.sm\:space-x-6>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(1.5rem * var(--space-x-reverse));margin-left:calc(1.5rem * calc(1 - var(--space-x-reverse)))}.sm\:space-y-8>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(2rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(2rem * var(--space-y-reverse))}.sm\:space-x-8>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(2rem * var(--space-x-reverse));margin-left:calc(2rem * calc(1 - var(--space-x-reverse)))}.sm\:space-y-10>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(2.5rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(2.5rem * var(--space-y-reverse))}.sm\:space-x-10>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(2.5rem * var(--space-x-reverse));margin-left:calc(2.5rem * calc(1 - var(--space-x-reverse)))}.sm\:space-y-12>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(3rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(3rem * var(--space-y-reverse))}.sm\:space-x-12>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(3rem * var(--space-x-reverse));margin-left:calc(3rem * calc(1 - var(--space-x-reverse)))}.sm\:space-y-16>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(4rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(4rem * var(--space-y-reverse))}.sm\:space-x-16>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(4rem * var(--space-x-reverse));margin-left:calc(4rem * calc(1 - var(--space-x-reverse)))}.sm\:space-y-20>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(5rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(5rem * var(--space-y-reverse))}.sm\:space-x-20>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(5rem * var(--space-x-reverse));margin-left:calc(5rem * calc(1 - var(--space-x-reverse)))}.sm\:space-y-24>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(6rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(6rem * var(--space-y-reverse))}.sm\:space-x-24>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(6rem * var(--space-x-reverse));margin-left:calc(6rem * calc(1 - var(--space-x-reverse)))}.sm\:space-y-32>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(8rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(8rem * var(--space-y-reverse))}.sm\:space-x-32>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(8rem * var(--space-x-reverse));margin-left:calc(8rem * calc(1 - var(--space-x-reverse)))}.sm\:space-y-40>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(10rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(10rem * var(--space-y-reverse))}.sm\:space-x-40>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(10rem * var(--space-x-reverse));margin-left:calc(10rem * calc(1 - var(--space-x-reverse)))}.sm\:space-y-48>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(12rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(12rem * var(--space-y-reverse))}.sm\:space-x-48>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(12rem * var(--space-x-reverse));margin-left:calc(12rem * calc(1 - var(--space-x-reverse)))}.sm\:space-y-56>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(14rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(14rem * var(--space-y-reverse))}.sm\:space-x-56>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(14rem * var(--space-x-reverse));margin-left:calc(14rem * calc(1 - var(--space-x-reverse)))}.sm\:space-y-64>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(16rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(16rem * var(--space-y-reverse))}.sm\:space-x-64>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(16rem * var(--space-x-reverse));margin-left:calc(16rem * calc(1 - var(--space-x-reverse)))}.sm\:space-y-px>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(1px * calc(1 - var(--space-y-reverse)));margin-bottom:calc(1px * var(--space-y-reverse))}.sm\:space-x-px>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(1px * var(--space-x-reverse));margin-left:calc(1px * calc(1 - var(--space-x-reverse)))}.sm\:-space-y-1>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-.25rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-.25rem * var(--space-y-reverse))}.sm\:-space-x-1>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-.25rem * var(--space-x-reverse));margin-left:calc(-.25rem * calc(1 - var(--space-x-reverse)))}.sm\:-space-y-2>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-.5rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-.5rem * var(--space-y-reverse))}.sm\:-space-x-2>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-.5rem * var(--space-x-reverse));margin-left:calc(-.5rem * calc(1 - var(--space-x-reverse)))}.sm\:-space-y-3>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-.75rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-.75rem * var(--space-y-reverse))}.sm\:-space-x-3>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-.75rem * var(--space-x-reverse));margin-left:calc(-.75rem * calc(1 - var(--space-x-reverse)))}.sm\:-space-y-4>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-1rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-1rem * var(--space-y-reverse))}.sm\:-space-x-4>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-1rem * var(--space-x-reverse));margin-left:calc(-1rem * calc(1 - var(--space-x-reverse)))}.sm\:-space-y-5>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-1.25rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-1.25rem * var(--space-y-reverse))}.sm\:-space-x-5>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-1.25rem * var(--space-x-reverse));margin-left:calc(-1.25rem * calc(1 - var(--space-x-reverse)))}.sm\:-space-y-6>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-1.5rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-1.5rem * var(--space-y-reverse))}.sm\:-space-x-6>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-1.5rem * var(--space-x-reverse));margin-left:calc(-1.5rem * calc(1 - var(--space-x-reverse)))}.sm\:-space-y-8>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-2rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-2rem * var(--space-y-reverse))}.sm\:-space-x-8>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-2rem * var(--space-x-reverse));margin-left:calc(-2rem * calc(1 - var(--space-x-reverse)))}.sm\:-space-y-10>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-2.5rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-2.5rem * var(--space-y-reverse))}.sm\:-space-x-10>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-2.5rem * var(--space-x-reverse));margin-left:calc(-2.5rem * calc(1 - var(--space-x-reverse)))}.sm\:-space-y-12>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-3rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-3rem * var(--space-y-reverse))}.sm\:-space-x-12>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-3rem * var(--space-x-reverse));margin-left:calc(-3rem * calc(1 - var(--space-x-reverse)))}.sm\:-space-y-16>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-4rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-4rem * var(--space-y-reverse))}.sm\:-space-x-16>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-4rem * var(--space-x-reverse));margin-left:calc(-4rem * calc(1 - var(--space-x-reverse)))}.sm\:-space-y-20>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-5rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-5rem * var(--space-y-reverse))}.sm\:-space-x-20>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-5rem * var(--space-x-reverse));margin-left:calc(-5rem * calc(1 - var(--space-x-reverse)))}.sm\:-space-y-24>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-6rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-6rem * var(--space-y-reverse))}.sm\:-space-x-24>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-6rem * var(--space-x-reverse));margin-left:calc(-6rem * calc(1 - var(--space-x-reverse)))}.sm\:-space-y-32>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-8rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-8rem * var(--space-y-reverse))}.sm\:-space-x-32>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-8rem * var(--space-x-reverse));margin-left:calc(-8rem * calc(1 - var(--space-x-reverse)))}.sm\:-space-y-40>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-10rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-10rem * var(--space-y-reverse))}.sm\:-space-x-40>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-10rem * var(--space-x-reverse));margin-left:calc(-10rem * calc(1 - var(--space-x-reverse)))}.sm\:-space-y-48>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-12rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-12rem * var(--space-y-reverse))}.sm\:-space-x-48>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-12rem * var(--space-x-reverse));margin-left:calc(-12rem * calc(1 - var(--space-x-reverse)))}.sm\:-space-y-56>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-14rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-14rem * var(--space-y-reverse))}.sm\:-space-x-56>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-14rem * var(--space-x-reverse));margin-left:calc(-14rem * calc(1 - var(--space-x-reverse)))}.sm\:-space-y-64>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-16rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-16rem * var(--space-y-reverse))}.sm\:-space-x-64>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-16rem * var(--space-x-reverse));margin-left:calc(-16rem * calc(1 - var(--space-x-reverse)))}.sm\:-space-y-px>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-1px * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-1px * var(--space-y-reverse))}.sm\:-space-x-px>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-1px * var(--space-x-reverse));margin-left:calc(-1px * calc(1 - var(--space-x-reverse)))}.sm\:space-y-reverse>:not(template)~:not(template){--space-y-reverse:1}.sm\:space-x-reverse>:not(template)~:not(template){--space-x-reverse:1}.sm\:divide-y-0>:not(template)~:not(template){--divide-y-reverse:0;border-top-width:calc(0px * calc(1 - var(--divide-y-reverse)));border-bottom-width:calc(0px * var(--divide-y-reverse))}.sm\:divide-x-0>:not(template)~:not(template){--divide-x-reverse:0;border-right-width:calc(0px * var(--divide-x-reverse));border-left-width:calc(0px * calc(1 - var(--divide-x-reverse)))}.sm\:divide-y-2>:not(template)~:not(template){--divide-y-reverse:0;border-top-width:calc(2px * calc(1 - var(--divide-y-reverse)));border-bottom-width:calc(2px * var(--divide-y-reverse))}.sm\:divide-x-2>:not(template)~:not(template){--divide-x-reverse:0;border-right-width:calc(2px * var(--divide-x-reverse));border-left-width:calc(2px * calc(1 - var(--divide-x-reverse)))}.sm\:divide-y-4>:not(template)~:not(template){--divide-y-reverse:0;border-top-width:calc(4px * calc(1 - var(--divide-y-reverse)));border-bottom-width:calc(4px * var(--divide-y-reverse))}.sm\:divide-x-4>:not(template)~:not(template){--divide-x-reverse:0;border-right-width:calc(4px * var(--divide-x-reverse));border-left-width:calc(4px * calc(1 - var(--divide-x-reverse)))}.sm\:divide-y-8>:not(template)~:not(template){--divide-y-reverse:0;border-top-width:calc(8px * calc(1 - var(--divide-y-reverse)));border-bottom-width:calc(8px * var(--divide-y-reverse))}.sm\:divide-x-8>:not(template)~:not(template){--divide-x-reverse:0;border-right-width:calc(8px * var(--divide-x-reverse));border-left-width:calc(8px * calc(1 - var(--divide-x-reverse)))}.sm\:divide-y>:not(template)~:not(template){--divide-y-reverse:0;border-top-width:calc(1px * calc(1 - var(--divide-y-reverse)));border-bottom-width:calc(1px * var(--divide-y-reverse))}.sm\:divide-x>:not(template)~:not(template){--divide-x-reverse:0;border-right-width:calc(1px * var(--divide-x-reverse));border-left-width:calc(1px * calc(1 - var(--divide-x-reverse)))}.sm\:divide-y-reverse>:not(template)~:not(template){--divide-y-reverse:1}.sm\:divide-x-reverse>:not(template)~:not(template){--divide-x-reverse:1}.sm\:divide-transparent>:not(template)~:not(template){border-color:transparent}.sm\:divide-current>:not(template)~:not(template){border-color:currentColor}.sm\:divide-black>:not(template)~:not(template){--divide-opacity:1;border-color:#000;border-color:rgba(0,0,0,var(--divide-opacity))}.sm\:divide-white>:not(template)~:not(template){--divide-opacity:1;border-color:#fff;border-color:rgba(255,255,255,var(--divide-opacity))}.sm\:divide-gray-100>:not(template)~:not(template){--divide-opacity:1;border-color:#f7fafc;border-color:rgba(247,250,252,var(--divide-opacity))}.sm\:divide-gray-200>:not(template)~:not(template){--divide-opacity:1;border-color:#edf2f7;border-color:rgba(237,242,247,var(--divide-opacity))}.sm\:divide-gray-300>:not(template)~:not(template){--divide-opacity:1;border-color:#e2e8f0;border-color:rgba(226,232,240,var(--divide-opacity))}.sm\:divide-gray-400>:not(template)~:not(template){--divide-opacity:1;border-color:#cbd5e0;border-color:rgba(203,213,224,var(--divide-opacity))}.sm\:divide-gray-500>:not(template)~:not(template){--divide-opacity:1;border-color:#a0aec0;border-color:rgba(160,174,192,var(--divide-opacity))}.sm\:divide-gray-600>:not(template)~:not(template){--divide-opacity:1;border-color:#718096;border-color:rgba(113,128,150,var(--divide-opacity))}.sm\:divide-gray-700>:not(template)~:not(template){--divide-opacity:1;border-color:#4a5568;border-color:rgba(74,85,104,var(--divide-opacity))}.sm\:divide-gray-800>:not(template)~:not(template){--divide-opacity:1;border-color:#2d3748;border-color:rgba(45,55,72,var(--divide-opacity))}.sm\:divide-gray-900>:not(template)~:not(template){--divide-opacity:1;border-color:#1a202c;border-color:rgba(26,32,44,var(--divide-opacity))}.sm\:divide-red-100>:not(template)~:not(template){--divide-opacity:1;border-color:#fff5f5;border-color:rgba(255,245,245,var(--divide-opacity))}.sm\:divide-red-200>:not(template)~:not(template){--divide-opacity:1;border-color:#fed7d7;border-color:rgba(254,215,215,var(--divide-opacity))}.sm\:divide-red-300>:not(template)~:not(template){--divide-opacity:1;border-color:#feb2b2;border-color:rgba(254,178,178,var(--divide-opacity))}.sm\:divide-red-400>:not(template)~:not(template){--divide-opacity:1;border-color:#fc8181;border-color:rgba(252,129,129,var(--divide-opacity))}.sm\:divide-red-500>:not(template)~:not(template){--divide-opacity:1;border-color:#f56565;border-color:rgba(245,101,101,var(--divide-opacity))}.sm\:divide-red-600>:not(template)~:not(template){--divide-opacity:1;border-color:#e53e3e;border-color:rgba(229,62,62,var(--divide-opacity))}.sm\:divide-red-700>:not(template)~:not(template){--divide-opacity:1;border-color:#c53030;border-color:rgba(197,48,48,var(--divide-opacity))}.sm\:divide-red-800>:not(template)~:not(template){--divide-opacity:1;border-color:#9b2c2c;border-color:rgba(155,44,44,var(--divide-opacity))}.sm\:divide-red-900>:not(template)~:not(template){--divide-opacity:1;border-color:#742a2a;border-color:rgba(116,42,42,var(--divide-opacity))}.sm\:divide-orange-100>:not(template)~:not(template){--divide-opacity:1;border-color:#fffaf0;border-color:rgba(255,250,240,var(--divide-opacity))}.sm\:divide-orange-200>:not(template)~:not(template){--divide-opacity:1;border-color:#feebc8;border-color:rgba(254,235,200,var(--divide-opacity))}.sm\:divide-orange-300>:not(template)~:not(template){--divide-opacity:1;border-color:#fbd38d;border-color:rgba(251,211,141,var(--divide-opacity))}.sm\:divide-orange-400>:not(template)~:not(template){--divide-opacity:1;border-color:#f6ad55;border-color:rgba(246,173,85,var(--divide-opacity))}.sm\:divide-orange-500>:not(template)~:not(template){--divide-opacity:1;border-color:#ed8936;border-color:rgba(237,137,54,var(--divide-opacity))}.sm\:divide-orange-600>:not(template)~:not(template){--divide-opacity:1;border-color:#dd6b20;border-color:rgba(221,107,32,var(--divide-opacity))}.sm\:divide-orange-700>:not(template)~:not(template){--divide-opacity:1;border-color:#c05621;border-color:rgba(192,86,33,var(--divide-opacity))}.sm\:divide-orange-800>:not(template)~:not(template){--divide-opacity:1;border-color:#9c4221;border-color:rgba(156,66,33,var(--divide-opacity))}.sm\:divide-orange-900>:not(template)~:not(template){--divide-opacity:1;border-color:#7b341e;border-color:rgba(123,52,30,var(--divide-opacity))}.sm\:divide-yellow-100>:not(template)~:not(template){--divide-opacity:1;border-color:ivory;border-color:rgba(255,255,240,var(--divide-opacity))}.sm\:divide-yellow-200>:not(template)~:not(template){--divide-opacity:1;border-color:#fefcbf;border-color:rgba(254,252,191,var(--divide-opacity))}.sm\:divide-yellow-300>:not(template)~:not(template){--divide-opacity:1;border-color:#faf089;border-color:rgba(250,240,137,var(--divide-opacity))}.sm\:divide-yellow-400>:not(template)~:not(template){--divide-opacity:1;border-color:#f6e05e;border-color:rgba(246,224,94,var(--divide-opacity))}.sm\:divide-yellow-500>:not(template)~:not(template){--divide-opacity:1;border-color:#ecc94b;border-color:rgba(236,201,75,var(--divide-opacity))}.sm\:divide-yellow-600>:not(template)~:not(template){--divide-opacity:1;border-color:#d69e2e;border-color:rgba(214,158,46,var(--divide-opacity))}.sm\:divide-yellow-700>:not(template)~:not(template){--divide-opacity:1;border-color:#b7791f;border-color:rgba(183,121,31,var(--divide-opacity))}.sm\:divide-yellow-800>:not(template)~:not(template){--divide-opacity:1;border-color:#975a16;border-color:rgba(151,90,22,var(--divide-opacity))}.sm\:divide-yellow-900>:not(template)~:not(template){--divide-opacity:1;border-color:#744210;border-color:rgba(116,66,16,var(--divide-opacity))}.sm\:divide-green-100>:not(template)~:not(template){--divide-opacity:1;border-color:#f0fff4;border-color:rgba(240,255,244,var(--divide-opacity))}.sm\:divide-green-200>:not(template)~:not(template){--divide-opacity:1;border-color:#c6f6d5;border-color:rgba(198,246,213,var(--divide-opacity))}.sm\:divide-green-300>:not(template)~:not(template){--divide-opacity:1;border-color:#9ae6b4;border-color:rgba(154,230,180,var(--divide-opacity))}.sm\:divide-green-400>:not(template)~:not(template){--divide-opacity:1;border-color:#68d391;border-color:rgba(104,211,145,var(--divide-opacity))}.sm\:divide-green-500>:not(template)~:not(template){--divide-opacity:1;border-color:#48bb78;border-color:rgba(72,187,120,var(--divide-opacity))}.sm\:divide-green-600>:not(template)~:not(template){--divide-opacity:1;border-color:#38a169;border-color:rgba(56,161,105,var(--divide-opacity))}.sm\:divide-green-700>:not(template)~:not(template){--divide-opacity:1;border-color:#2f855a;border-color:rgba(47,133,90,var(--divide-opacity))}.sm\:divide-green-800>:not(template)~:not(template){--divide-opacity:1;border-color:#276749;border-color:rgba(39,103,73,var(--divide-opacity))}.sm\:divide-green-900>:not(template)~:not(template){--divide-opacity:1;border-color:#22543d;border-color:rgba(34,84,61,var(--divide-opacity))}.sm\:divide-teal-100>:not(template)~:not(template){--divide-opacity:1;border-color:#e6fffa;border-color:rgba(230,255,250,var(--divide-opacity))}.sm\:divide-teal-200>:not(template)~:not(template){--divide-opacity:1;border-color:#b2f5ea;border-color:rgba(178,245,234,var(--divide-opacity))}.sm\:divide-teal-300>:not(template)~:not(template){--divide-opacity:1;border-color:#81e6d9;border-color:rgba(129,230,217,var(--divide-opacity))}.sm\:divide-teal-400>:not(template)~:not(template){--divide-opacity:1;border-color:#4fd1c5;border-color:rgba(79,209,197,var(--divide-opacity))}.sm\:divide-teal-500>:not(template)~:not(template){--divide-opacity:1;border-color:#38b2ac;border-color:rgba(56,178,172,var(--divide-opacity))}.sm\:divide-teal-600>:not(template)~:not(template){--divide-opacity:1;border-color:#319795;border-color:rgba(49,151,149,var(--divide-opacity))}.sm\:divide-teal-700>:not(template)~:not(template){--divide-opacity:1;border-color:#2c7a7b;border-color:rgba(44,122,123,var(--divide-opacity))}.sm\:divide-teal-800>:not(template)~:not(template){--divide-opacity:1;border-color:#285e61;border-color:rgba(40,94,97,var(--divide-opacity))}.sm\:divide-teal-900>:not(template)~:not(template){--divide-opacity:1;border-color:#234e52;border-color:rgba(35,78,82,var(--divide-opacity))}.sm\:divide-blue-100>:not(template)~:not(template){--divide-opacity:1;border-color:#ebf8ff;border-color:rgba(235,248,255,var(--divide-opacity))}.sm\:divide-blue-200>:not(template)~:not(template){--divide-opacity:1;border-color:#bee3f8;border-color:rgba(190,227,248,var(--divide-opacity))}.sm\:divide-blue-300>:not(template)~:not(template){--divide-opacity:1;border-color:#90cdf4;border-color:rgba(144,205,244,var(--divide-opacity))}.sm\:divide-blue-400>:not(template)~:not(template){--divide-opacity:1;border-color:#63b3ed;border-color:rgba(99,179,237,var(--divide-opacity))}.sm\:divide-blue-500>:not(template)~:not(template){--divide-opacity:1;border-color:#4299e1;border-color:rgba(66,153,225,var(--divide-opacity))}.sm\:divide-blue-600>:not(template)~:not(template){--divide-opacity:1;border-color:#3182ce;border-color:rgba(49,130,206,var(--divide-opacity))}.sm\:divide-blue-700>:not(template)~:not(template){--divide-opacity:1;border-color:#2b6cb0;border-color:rgba(43,108,176,var(--divide-opacity))}.sm\:divide-blue-800>:not(template)~:not(template){--divide-opacity:1;border-color:#2c5282;border-color:rgba(44,82,130,var(--divide-opacity))}.sm\:divide-blue-900>:not(template)~:not(template){--divide-opacity:1;border-color:#2a4365;border-color:rgba(42,67,101,var(--divide-opacity))}.sm\:divide-indigo-100>:not(template)~:not(template){--divide-opacity:1;border-color:#ebf4ff;border-color:rgba(235,244,255,var(--divide-opacity))}.sm\:divide-indigo-200>:not(template)~:not(template){--divide-opacity:1;border-color:#c3dafe;border-color:rgba(195,218,254,var(--divide-opacity))}.sm\:divide-indigo-300>:not(template)~:not(template){--divide-opacity:1;border-color:#a3bffa;border-color:rgba(163,191,250,var(--divide-opacity))}.sm\:divide-indigo-400>:not(template)~:not(template){--divide-opacity:1;border-color:#7f9cf5;border-color:rgba(127,156,245,var(--divide-opacity))}.sm\:divide-indigo-500>:not(template)~:not(template){--divide-opacity:1;border-color:#667eea;border-color:rgba(102,126,234,var(--divide-opacity))}.sm\:divide-indigo-600>:not(template)~:not(template){--divide-opacity:1;border-color:#5a67d8;border-color:rgba(90,103,216,var(--divide-opacity))}.sm\:divide-indigo-700>:not(template)~:not(template){--divide-opacity:1;border-color:#4c51bf;border-color:rgba(76,81,191,var(--divide-opacity))}.sm\:divide-indigo-800>:not(template)~:not(template){--divide-opacity:1;border-color:#434190;border-color:rgba(67,65,144,var(--divide-opacity))}.sm\:divide-indigo-900>:not(template)~:not(template){--divide-opacity:1;border-color:#3c366b;border-color:rgba(60,54,107,var(--divide-opacity))}.sm\:divide-purple-100>:not(template)~:not(template){--divide-opacity:1;border-color:#faf5ff;border-color:rgba(250,245,255,var(--divide-opacity))}.sm\:divide-purple-200>:not(template)~:not(template){--divide-opacity:1;border-color:#e9d8fd;border-color:rgba(233,216,253,var(--divide-opacity))}.sm\:divide-purple-300>:not(template)~:not(template){--divide-opacity:1;border-color:#d6bcfa;border-color:rgba(214,188,250,var(--divide-opacity))}.sm\:divide-purple-400>:not(template)~:not(template){--divide-opacity:1;border-color:#b794f4;border-color:rgba(183,148,244,var(--divide-opacity))}.sm\:divide-purple-500>:not(template)~:not(template){--divide-opacity:1;border-color:#9f7aea;border-color:rgba(159,122,234,var(--divide-opacity))}.sm\:divide-purple-600>:not(template)~:not(template){--divide-opacity:1;border-color:#805ad5;border-color:rgba(128,90,213,var(--divide-opacity))}.sm\:divide-purple-700>:not(template)~:not(template){--divide-opacity:1;border-color:#6b46c1;border-color:rgba(107,70,193,var(--divide-opacity))}.sm\:divide-purple-800>:not(template)~:not(template){--divide-opacity:1;border-color:#553c9a;border-color:rgba(85,60,154,var(--divide-opacity))}.sm\:divide-purple-900>:not(template)~:not(template){--divide-opacity:1;border-color:#44337a;border-color:rgba(68,51,122,var(--divide-opacity))}.sm\:divide-pink-100>:not(template)~:not(template){--divide-opacity:1;border-color:#fff5f7;border-color:rgba(255,245,247,var(--divide-opacity))}.sm\:divide-pink-200>:not(template)~:not(template){--divide-opacity:1;border-color:#fed7e2;border-color:rgba(254,215,226,var(--divide-opacity))}.sm\:divide-pink-300>:not(template)~:not(template){--divide-opacity:1;border-color:#fbb6ce;border-color:rgba(251,182,206,var(--divide-opacity))}.sm\:divide-pink-400>:not(template)~:not(template){--divide-opacity:1;border-color:#f687b3;border-color:rgba(246,135,179,var(--divide-opacity))}.sm\:divide-pink-500>:not(template)~:not(template){--divide-opacity:1;border-color:#ed64a6;border-color:rgba(237,100,166,var(--divide-opacity))}.sm\:divide-pink-600>:not(template)~:not(template){--divide-opacity:1;border-color:#d53f8c;border-color:rgba(213,63,140,var(--divide-opacity))}.sm\:divide-pink-700>:not(template)~:not(template){--divide-opacity:1;border-color:#b83280;border-color:rgba(184,50,128,var(--divide-opacity))}.sm\:divide-pink-800>:not(template)~:not(template){--divide-opacity:1;border-color:#97266d;border-color:rgba(151,38,109,var(--divide-opacity))}.sm\:divide-pink-900>:not(template)~:not(template){--divide-opacity:1;border-color:#702459;border-color:rgba(112,36,89,var(--divide-opacity))}.sm\:divide-solid>:not(template)~:not(template){border-style:solid}.sm\:divide-dashed>:not(template)~:not(template){border-style:dashed}.sm\:divide-dotted>:not(template)~:not(template){border-style:dotted}.sm\:divide-double>:not(template)~:not(template){border-style:double}.sm\:divide-none>:not(template)~:not(template){border-style:none}.sm\:divide-opacity-0>:not(template)~:not(template){--divide-opacity:0}.sm\:divide-opacity-25>:not(template)~:not(template){--divide-opacity:0.25}.sm\:divide-opacity-50>:not(template)~:not(template){--divide-opacity:0.5}.sm\:divide-opacity-75>:not(template)~:not(template){--divide-opacity:0.75}.sm\:divide-opacity-100>:not(template)~:not(template){--divide-opacity:1}.sm\:sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border-width:0}.sm\:not-sr-only{position:static;width:auto;height:auto;padding:0;margin:0;overflow:visible;clip:auto;white-space:normal}.sm\:focus\:sr-only:focus{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border-width:0}.sm\:focus\:not-sr-only:focus{position:static;width:auto;height:auto;padding:0;margin:0;overflow:visible;clip:auto;white-space:normal}.sm\:appearance-none{-webkit-appearance:none;-moz-appearance:none;appearance:none}.sm\:bg-fixed{background-attachment:fixed}.sm\:bg-local{background-attachment:local}.sm\:bg-scroll{background-attachment:scroll}.sm\:bg-clip-border{background-clip:border-box}.sm\:bg-clip-padding{background-clip:padding-box}.sm\:bg-clip-content{background-clip:content-box}.sm\:bg-clip-text{-webkit-background-clip:text;background-clip:text}.sm\:bg-transparent{background-color:transparent}.sm\:bg-current{background-color:currentColor}.sm\:bg-black{--bg-opacity:1;background-color:#000;background-color:rgba(0,0,0,var(--bg-opacity))}.sm\:bg-white{--bg-opacity:1;background-color:#fff;background-color:rgba(255,255,255,var(--bg-opacity))}.sm\:bg-gray-100{--bg-opacity:1;background-color:#f7fafc;background-color:rgba(247,250,252,var(--bg-opacity))}.sm\:bg-gray-200{--bg-opacity:1;background-color:#edf2f7;background-color:rgba(237,242,247,var(--bg-opacity))}.sm\:bg-gray-300{--bg-opacity:1;background-color:#e2e8f0;background-color:rgba(226,232,240,var(--bg-opacity))}.sm\:bg-gray-400{--bg-opacity:1;background-color:#cbd5e0;background-color:rgba(203,213,224,var(--bg-opacity))}.sm\:bg-gray-500{--bg-opacity:1;background-color:#a0aec0;background-color:rgba(160,174,192,var(--bg-opacity))}.sm\:bg-gray-600{--bg-opacity:1;background-color:#718096;background-color:rgba(113,128,150,var(--bg-opacity))}.sm\:bg-gray-700{--bg-opacity:1;background-color:#4a5568;background-color:rgba(74,85,104,var(--bg-opacity))}.sm\:bg-gray-800{--bg-opacity:1;background-color:#2d3748;background-color:rgba(45,55,72,var(--bg-opacity))}.sm\:bg-gray-900{--bg-opacity:1;background-color:#1a202c;background-color:rgba(26,32,44,var(--bg-opacity))}.sm\:bg-red-100{--bg-opacity:1;background-color:#fff5f5;background-color:rgba(255,245,245,var(--bg-opacity))}.sm\:bg-red-200{--bg-opacity:1;background-color:#fed7d7;background-color:rgba(254,215,215,var(--bg-opacity))}.sm\:bg-red-300{--bg-opacity:1;background-color:#feb2b2;background-color:rgba(254,178,178,var(--bg-opacity))}.sm\:bg-red-400{--bg-opacity:1;background-color:#fc8181;background-color:rgba(252,129,129,var(--bg-opacity))}.sm\:bg-red-500{--bg-opacity:1;background-color:#f56565;background-color:rgba(245,101,101,var(--bg-opacity))}.sm\:bg-red-600{--bg-opacity:1;background-color:#e53e3e;background-color:rgba(229,62,62,var(--bg-opacity))}.sm\:bg-red-700{--bg-opacity:1;background-color:#c53030;background-color:rgba(197,48,48,var(--bg-opacity))}.sm\:bg-red-800{--bg-opacity:1;background-color:#9b2c2c;background-color:rgba(155,44,44,var(--bg-opacity))}.sm\:bg-red-900{--bg-opacity:1;background-color:#742a2a;background-color:rgba(116,42,42,var(--bg-opacity))}.sm\:bg-orange-100{--bg-opacity:1;background-color:#fffaf0;background-color:rgba(255,250,240,var(--bg-opacity))}.sm\:bg-orange-200{--bg-opacity:1;background-color:#feebc8;background-color:rgba(254,235,200,var(--bg-opacity))}.sm\:bg-orange-300{--bg-opacity:1;background-color:#fbd38d;background-color:rgba(251,211,141,var(--bg-opacity))}.sm\:bg-orange-400{--bg-opacity:1;background-color:#f6ad55;background-color:rgba(246,173,85,var(--bg-opacity))}.sm\:bg-orange-500{--bg-opacity:1;background-color:#ed8936;background-color:rgba(237,137,54,var(--bg-opacity))}.sm\:bg-orange-600{--bg-opacity:1;background-color:#dd6b20;background-color:rgba(221,107,32,var(--bg-opacity))}.sm\:bg-orange-700{--bg-opacity:1;background-color:#c05621;background-color:rgba(192,86,33,var(--bg-opacity))}.sm\:bg-orange-800{--bg-opacity:1;background-color:#9c4221;background-color:rgba(156,66,33,var(--bg-opacity))}.sm\:bg-orange-900{--bg-opacity:1;background-color:#7b341e;background-color:rgba(123,52,30,var(--bg-opacity))}.sm\:bg-yellow-100{--bg-opacity:1;background-color:ivory;background-color:rgba(255,255,240,var(--bg-opacity))}.sm\:bg-yellow-200{--bg-opacity:1;background-color:#fefcbf;background-color:rgba(254,252,191,var(--bg-opacity))}.sm\:bg-yellow-300{--bg-opacity:1;background-color:#faf089;background-color:rgba(250,240,137,var(--bg-opacity))}.sm\:bg-yellow-400{--bg-opacity:1;background-color:#f6e05e;background-color:rgba(246,224,94,var(--bg-opacity))}.sm\:bg-yellow-500{--bg-opacity:1;background-color:#ecc94b;background-color:rgba(236,201,75,var(--bg-opacity))}.sm\:bg-yellow-600{--bg-opacity:1;background-color:#d69e2e;background-color:rgba(214,158,46,var(--bg-opacity))}.sm\:bg-yellow-700{--bg-opacity:1;background-color:#b7791f;background-color:rgba(183,121,31,var(--bg-opacity))}.sm\:bg-yellow-800{--bg-opacity:1;background-color:#975a16;background-color:rgba(151,90,22,var(--bg-opacity))}.sm\:bg-yellow-900{--bg-opacity:1;background-color:#744210;background-color:rgba(116,66,16,var(--bg-opacity))}.sm\:bg-green-100{--bg-opacity:1;background-color:#f0fff4;background-color:rgba(240,255,244,var(--bg-opacity))}.sm\:bg-green-200{--bg-opacity:1;background-color:#c6f6d5;background-color:rgba(198,246,213,var(--bg-opacity))}.sm\:bg-green-300{--bg-opacity:1;background-color:#9ae6b4;background-color:rgba(154,230,180,var(--bg-opacity))}.sm\:bg-green-400{--bg-opacity:1;background-color:#68d391;background-color:rgba(104,211,145,var(--bg-opacity))}.sm\:bg-green-500{--bg-opacity:1;background-color:#48bb78;background-color:rgba(72,187,120,var(--bg-opacity))}.sm\:bg-green-600{--bg-opacity:1;background-color:#38a169;background-color:rgba(56,161,105,var(--bg-opacity))}.sm\:bg-green-700{--bg-opacity:1;background-color:#2f855a;background-color:rgba(47,133,90,var(--bg-opacity))}.sm\:bg-green-800{--bg-opacity:1;background-color:#276749;background-color:rgba(39,103,73,var(--bg-opacity))}.sm\:bg-green-900{--bg-opacity:1;background-color:#22543d;background-color:rgba(34,84,61,var(--bg-opacity))}.sm\:bg-teal-100{--bg-opacity:1;background-color:#e6fffa;background-color:rgba(230,255,250,var(--bg-opacity))}.sm\:bg-teal-200{--bg-opacity:1;background-color:#b2f5ea;background-color:rgba(178,245,234,var(--bg-opacity))}.sm\:bg-teal-300{--bg-opacity:1;background-color:#81e6d9;background-color:rgba(129,230,217,var(--bg-opacity))}.sm\:bg-teal-400{--bg-opacity:1;background-color:#4fd1c5;background-color:rgba(79,209,197,var(--bg-opacity))}.sm\:bg-teal-500{--bg-opacity:1;background-color:#38b2ac;background-color:rgba(56,178,172,var(--bg-opacity))}.sm\:bg-teal-600{--bg-opacity:1;background-color:#319795;background-color:rgba(49,151,149,var(--bg-opacity))}.sm\:bg-teal-700{--bg-opacity:1;background-color:#2c7a7b;background-color:rgba(44,122,123,var(--bg-opacity))}.sm\:bg-teal-800{--bg-opacity:1;background-color:#285e61;background-color:rgba(40,94,97,var(--bg-opacity))}.sm\:bg-teal-900{--bg-opacity:1;background-color:#234e52;background-color:rgba(35,78,82,var(--bg-opacity))}.sm\:bg-blue-100{--bg-opacity:1;background-color:#ebf8ff;background-color:rgba(235,248,255,var(--bg-opacity))}.sm\:bg-blue-200{--bg-opacity:1;background-color:#bee3f8;background-color:rgba(190,227,248,var(--bg-opacity))}.sm\:bg-blue-300{--bg-opacity:1;background-color:#90cdf4;background-color:rgba(144,205,244,var(--bg-opacity))}.sm\:bg-blue-400{--bg-opacity:1;background-color:#63b3ed;background-color:rgba(99,179,237,var(--bg-opacity))}.sm\:bg-blue-500{--bg-opacity:1;background-color:#4299e1;background-color:rgba(66,153,225,var(--bg-opacity))}.sm\:bg-blue-600{--bg-opacity:1;background-color:#3182ce;background-color:rgba(49,130,206,var(--bg-opacity))}.sm\:bg-blue-700{--bg-opacity:1;background-color:#2b6cb0;background-color:rgba(43,108,176,var(--bg-opacity))}.sm\:bg-blue-800{--bg-opacity:1;background-color:#2c5282;background-color:rgba(44,82,130,var(--bg-opacity))}.sm\:bg-blue-900{--bg-opacity:1;background-color:#2a4365;background-color:rgba(42,67,101,var(--bg-opacity))}.sm\:bg-indigo-100{--bg-opacity:1;background-color:#ebf4ff;background-color:rgba(235,244,255,var(--bg-opacity))}.sm\:bg-indigo-200{--bg-opacity:1;background-color:#c3dafe;background-color:rgba(195,218,254,var(--bg-opacity))}.sm\:bg-indigo-300{--bg-opacity:1;background-color:#a3bffa;background-color:rgba(163,191,250,var(--bg-opacity))}.sm\:bg-indigo-400{--bg-opacity:1;background-color:#7f9cf5;background-color:rgba(127,156,245,var(--bg-opacity))}.sm\:bg-indigo-500{--bg-opacity:1;background-color:#667eea;background-color:rgba(102,126,234,var(--bg-opacity))}.sm\:bg-indigo-600{--bg-opacity:1;background-color:#5a67d8;background-color:rgba(90,103,216,var(--bg-opacity))}.sm\:bg-indigo-700{--bg-opacity:1;background-color:#4c51bf;background-color:rgba(76,81,191,var(--bg-opacity))}.sm\:bg-indigo-800{--bg-opacity:1;background-color:#434190;background-color:rgba(67,65,144,var(--bg-opacity))}.sm\:bg-indigo-900{--bg-opacity:1;background-color:#3c366b;background-color:rgba(60,54,107,var(--bg-opacity))}.sm\:bg-purple-100{--bg-opacity:1;background-color:#faf5ff;background-color:rgba(250,245,255,var(--bg-opacity))}.sm\:bg-purple-200{--bg-opacity:1;background-color:#e9d8fd;background-color:rgba(233,216,253,var(--bg-opacity))}.sm\:bg-purple-300{--bg-opacity:1;background-color:#d6bcfa;background-color:rgba(214,188,250,var(--bg-opacity))}.sm\:bg-purple-400{--bg-opacity:1;background-color:#b794f4;background-color:rgba(183,148,244,var(--bg-opacity))}.sm\:bg-purple-500{--bg-opacity:1;background-color:#9f7aea;background-color:rgba(159,122,234,var(--bg-opacity))}.sm\:bg-purple-600{--bg-opacity:1;background-color:#805ad5;background-color:rgba(128,90,213,var(--bg-opacity))}.sm\:bg-purple-700{--bg-opacity:1;background-color:#6b46c1;background-color:rgba(107,70,193,var(--bg-opacity))}.sm\:bg-purple-800{--bg-opacity:1;background-color:#553c9a;background-color:rgba(85,60,154,var(--bg-opacity))}.sm\:bg-purple-900{--bg-opacity:1;background-color:#44337a;background-color:rgba(68,51,122,var(--bg-opacity))}.sm\:bg-pink-100{--bg-opacity:1;background-color:#fff5f7;background-color:rgba(255,245,247,var(--bg-opacity))}.sm\:bg-pink-200{--bg-opacity:1;background-color:#fed7e2;background-color:rgba(254,215,226,var(--bg-opacity))}.sm\:bg-pink-300{--bg-opacity:1;background-color:#fbb6ce;background-color:rgba(251,182,206,var(--bg-opacity))}.sm\:bg-pink-400{--bg-opacity:1;background-color:#f687b3;background-color:rgba(246,135,179,var(--bg-opacity))}.sm\:bg-pink-500{--bg-opacity:1;background-color:#ed64a6;background-color:rgba(237,100,166,var(--bg-opacity))}.sm\:bg-pink-600{--bg-opacity:1;background-color:#d53f8c;background-color:rgba(213,63,140,var(--bg-opacity))}.sm\:bg-pink-700{--bg-opacity:1;background-color:#b83280;background-color:rgba(184,50,128,var(--bg-opacity))}.sm\:bg-pink-800{--bg-opacity:1;background-color:#97266d;background-color:rgba(151,38,109,var(--bg-opacity))}.sm\:bg-pink-900{--bg-opacity:1;background-color:#702459;background-color:rgba(112,36,89,var(--bg-opacity))}.sm\:hover\:bg-transparent:hover{background-color:transparent}.sm\:hover\:bg-current:hover{background-color:currentColor}.sm\:hover\:bg-black:hover{--bg-opacity:1;background-color:#000;background-color:rgba(0,0,0,var(--bg-opacity))}.sm\:hover\:bg-white:hover{--bg-opacity:1;background-color:#fff;background-color:rgba(255,255,255,var(--bg-opacity))}.sm\:hover\:bg-gray-100:hover{--bg-opacity:1;background-color:#f7fafc;background-color:rgba(247,250,252,var(--bg-opacity))}.sm\:hover\:bg-gray-200:hover{--bg-opacity:1;background-color:#edf2f7;background-color:rgba(237,242,247,var(--bg-opacity))}.sm\:hover\:bg-gray-300:hover{--bg-opacity:1;background-color:#e2e8f0;background-color:rgba(226,232,240,var(--bg-opacity))}.sm\:hover\:bg-gray-400:hover{--bg-opacity:1;background-color:#cbd5e0;background-color:rgba(203,213,224,var(--bg-opacity))}.sm\:hover\:bg-gray-500:hover{--bg-opacity:1;background-color:#a0aec0;background-color:rgba(160,174,192,var(--bg-opacity))}.sm\:hover\:bg-gray-600:hover{--bg-opacity:1;background-color:#718096;background-color:rgba(113,128,150,var(--bg-opacity))}.sm\:hover\:bg-gray-700:hover{--bg-opacity:1;background-color:#4a5568;background-color:rgba(74,85,104,var(--bg-opacity))}.sm\:hover\:bg-gray-800:hover{--bg-opacity:1;background-color:#2d3748;background-color:rgba(45,55,72,var(--bg-opacity))}.sm\:hover\:bg-gray-900:hover{--bg-opacity:1;background-color:#1a202c;background-color:rgba(26,32,44,var(--bg-opacity))}.sm\:hover\:bg-red-100:hover{--bg-opacity:1;background-color:#fff5f5;background-color:rgba(255,245,245,var(--bg-opacity))}.sm\:hover\:bg-red-200:hover{--bg-opacity:1;background-color:#fed7d7;background-color:rgba(254,215,215,var(--bg-opacity))}.sm\:hover\:bg-red-300:hover{--bg-opacity:1;background-color:#feb2b2;background-color:rgba(254,178,178,var(--bg-opacity))}.sm\:hover\:bg-red-400:hover{--bg-opacity:1;background-color:#fc8181;background-color:rgba(252,129,129,var(--bg-opacity))}.sm\:hover\:bg-red-500:hover{--bg-opacity:1;background-color:#f56565;background-color:rgba(245,101,101,var(--bg-opacity))}.sm\:hover\:bg-red-600:hover{--bg-opacity:1;background-color:#e53e3e;background-color:rgba(229,62,62,var(--bg-opacity))}.sm\:hover\:bg-red-700:hover{--bg-opacity:1;background-color:#c53030;background-color:rgba(197,48,48,var(--bg-opacity))}.sm\:hover\:bg-red-800:hover{--bg-opacity:1;background-color:#9b2c2c;background-color:rgba(155,44,44,var(--bg-opacity))}.sm\:hover\:bg-red-900:hover{--bg-opacity:1;background-color:#742a2a;background-color:rgba(116,42,42,var(--bg-opacity))}.sm\:hover\:bg-orange-100:hover{--bg-opacity:1;background-color:#fffaf0;background-color:rgba(255,250,240,var(--bg-opacity))}.sm\:hover\:bg-orange-200:hover{--bg-opacity:1;background-color:#feebc8;background-color:rgba(254,235,200,var(--bg-opacity))}.sm\:hover\:bg-orange-300:hover{--bg-opacity:1;background-color:#fbd38d;background-color:rgba(251,211,141,var(--bg-opacity))}.sm\:hover\:bg-orange-400:hover{--bg-opacity:1;background-color:#f6ad55;background-color:rgba(246,173,85,var(--bg-opacity))}.sm\:hover\:bg-orange-500:hover{--bg-opacity:1;background-color:#ed8936;background-color:rgba(237,137,54,var(--bg-opacity))}.sm\:hover\:bg-orange-600:hover{--bg-opacity:1;background-color:#dd6b20;background-color:rgba(221,107,32,var(--bg-opacity))}.sm\:hover\:bg-orange-700:hover{--bg-opacity:1;background-color:#c05621;background-color:rgba(192,86,33,var(--bg-opacity))}.sm\:hover\:bg-orange-800:hover{--bg-opacity:1;background-color:#9c4221;background-color:rgba(156,66,33,var(--bg-opacity))}.sm\:hover\:bg-orange-900:hover{--bg-opacity:1;background-color:#7b341e;background-color:rgba(123,52,30,var(--bg-opacity))}.sm\:hover\:bg-yellow-100:hover{--bg-opacity:1;background-color:ivory;background-color:rgba(255,255,240,var(--bg-opacity))}.sm\:hover\:bg-yellow-200:hover{--bg-opacity:1;background-color:#fefcbf;background-color:rgba(254,252,191,var(--bg-opacity))}.sm\:hover\:bg-yellow-300:hover{--bg-opacity:1;background-color:#faf089;background-color:rgba(250,240,137,var(--bg-opacity))}.sm\:hover\:bg-yellow-400:hover{--bg-opacity:1;background-color:#f6e05e;background-color:rgba(246,224,94,var(--bg-opacity))}.sm\:hover\:bg-yellow-500:hover{--bg-opacity:1;background-color:#ecc94b;background-color:rgba(236,201,75,var(--bg-opacity))}.sm\:hover\:bg-yellow-600:hover{--bg-opacity:1;background-color:#d69e2e;background-color:rgba(214,158,46,var(--bg-opacity))}.sm\:hover\:bg-yellow-700:hover{--bg-opacity:1;background-color:#b7791f;background-color:rgba(183,121,31,var(--bg-opacity))}.sm\:hover\:bg-yellow-800:hover{--bg-opacity:1;background-color:#975a16;background-color:rgba(151,90,22,var(--bg-opacity))}.sm\:hover\:bg-yellow-900:hover{--bg-opacity:1;background-color:#744210;background-color:rgba(116,66,16,var(--bg-opacity))}.sm\:hover\:bg-green-100:hover{--bg-opacity:1;background-color:#f0fff4;background-color:rgba(240,255,244,var(--bg-opacity))}.sm\:hover\:bg-green-200:hover{--bg-opacity:1;background-color:#c6f6d5;background-color:rgba(198,246,213,var(--bg-opacity))}.sm\:hover\:bg-green-300:hover{--bg-opacity:1;background-color:#9ae6b4;background-color:rgba(154,230,180,var(--bg-opacity))}.sm\:hover\:bg-green-400:hover{--bg-opacity:1;background-color:#68d391;background-color:rgba(104,211,145,var(--bg-opacity))}.sm\:hover\:bg-green-500:hover{--bg-opacity:1;background-color:#48bb78;background-color:rgba(72,187,120,var(--bg-opacity))}.sm\:hover\:bg-green-600:hover{--bg-opacity:1;background-color:#38a169;background-color:rgba(56,161,105,var(--bg-opacity))}.sm\:hover\:bg-green-700:hover{--bg-opacity:1;background-color:#2f855a;background-color:rgba(47,133,90,var(--bg-opacity))}.sm\:hover\:bg-green-800:hover{--bg-opacity:1;background-color:#276749;background-color:rgba(39,103,73,var(--bg-opacity))}.sm\:hover\:bg-green-900:hover{--bg-opacity:1;background-color:#22543d;background-color:rgba(34,84,61,var(--bg-opacity))}.sm\:hover\:bg-teal-100:hover{--bg-opacity:1;background-color:#e6fffa;background-color:rgba(230,255,250,var(--bg-opacity))}.sm\:hover\:bg-teal-200:hover{--bg-opacity:1;background-color:#b2f5ea;background-color:rgba(178,245,234,var(--bg-opacity))}.sm\:hover\:bg-teal-300:hover{--bg-opacity:1;background-color:#81e6d9;background-color:rgba(129,230,217,var(--bg-opacity))}.sm\:hover\:bg-teal-400:hover{--bg-opacity:1;background-color:#4fd1c5;background-color:rgba(79,209,197,var(--bg-opacity))}.sm\:hover\:bg-teal-500:hover{--bg-opacity:1;background-color:#38b2ac;background-color:rgba(56,178,172,var(--bg-opacity))}.sm\:hover\:bg-teal-600:hover{--bg-opacity:1;background-color:#319795;background-color:rgba(49,151,149,var(--bg-opacity))}.sm\:hover\:bg-teal-700:hover{--bg-opacity:1;background-color:#2c7a7b;background-color:rgba(44,122,123,var(--bg-opacity))}.sm\:hover\:bg-teal-800:hover{--bg-opacity:1;background-color:#285e61;background-color:rgba(40,94,97,var(--bg-opacity))}.sm\:hover\:bg-teal-900:hover{--bg-opacity:1;background-color:#234e52;background-color:rgba(35,78,82,var(--bg-opacity))}.sm\:hover\:bg-blue-100:hover{--bg-opacity:1;background-color:#ebf8ff;background-color:rgba(235,248,255,var(--bg-opacity))}.sm\:hover\:bg-blue-200:hover{--bg-opacity:1;background-color:#bee3f8;background-color:rgba(190,227,248,var(--bg-opacity))}.sm\:hover\:bg-blue-300:hover{--bg-opacity:1;background-color:#90cdf4;background-color:rgba(144,205,244,var(--bg-opacity))}.sm\:hover\:bg-blue-400:hover{--bg-opacity:1;background-color:#63b3ed;background-color:rgba(99,179,237,var(--bg-opacity))}.sm\:hover\:bg-blue-500:hover{--bg-opacity:1;background-color:#4299e1;background-color:rgba(66,153,225,var(--bg-opacity))}.sm\:hover\:bg-blue-600:hover{--bg-opacity:1;background-color:#3182ce;background-color:rgba(49,130,206,var(--bg-opacity))}.sm\:hover\:bg-blue-700:hover{--bg-opacity:1;background-color:#2b6cb0;background-color:rgba(43,108,176,var(--bg-opacity))}.sm\:hover\:bg-blue-800:hover{--bg-opacity:1;background-color:#2c5282;background-color:rgba(44,82,130,var(--bg-opacity))}.sm\:hover\:bg-blue-900:hover{--bg-opacity:1;background-color:#2a4365;background-color:rgba(42,67,101,var(--bg-opacity))}.sm\:hover\:bg-indigo-100:hover{--bg-opacity:1;background-color:#ebf4ff;background-color:rgba(235,244,255,var(--bg-opacity))}.sm\:hover\:bg-indigo-200:hover{--bg-opacity:1;background-color:#c3dafe;background-color:rgba(195,218,254,var(--bg-opacity))}.sm\:hover\:bg-indigo-300:hover{--bg-opacity:1;background-color:#a3bffa;background-color:rgba(163,191,250,var(--bg-opacity))}.sm\:hover\:bg-indigo-400:hover{--bg-opacity:1;background-color:#7f9cf5;background-color:rgba(127,156,245,var(--bg-opacity))}.sm\:hover\:bg-indigo-500:hover{--bg-opacity:1;background-color:#667eea;background-color:rgba(102,126,234,var(--bg-opacity))}.sm\:hover\:bg-indigo-600:hover{--bg-opacity:1;background-color:#5a67d8;background-color:rgba(90,103,216,var(--bg-opacity))}.sm\:hover\:bg-indigo-700:hover{--bg-opacity:1;background-color:#4c51bf;background-color:rgba(76,81,191,var(--bg-opacity))}.sm\:hover\:bg-indigo-800:hover{--bg-opacity:1;background-color:#434190;background-color:rgba(67,65,144,var(--bg-opacity))}.sm\:hover\:bg-indigo-900:hover{--bg-opacity:1;background-color:#3c366b;background-color:rgba(60,54,107,var(--bg-opacity))}.sm\:hover\:bg-purple-100:hover{--bg-opacity:1;background-color:#faf5ff;background-color:rgba(250,245,255,var(--bg-opacity))}.sm\:hover\:bg-purple-200:hover{--bg-opacity:1;background-color:#e9d8fd;background-color:rgba(233,216,253,var(--bg-opacity))}.sm\:hover\:bg-purple-300:hover{--bg-opacity:1;background-color:#d6bcfa;background-color:rgba(214,188,250,var(--bg-opacity))}.sm\:hover\:bg-purple-400:hover{--bg-opacity:1;background-color:#b794f4;background-color:rgba(183,148,244,var(--bg-opacity))}.sm\:hover\:bg-purple-500:hover{--bg-opacity:1;background-color:#9f7aea;background-color:rgba(159,122,234,var(--bg-opacity))}.sm\:hover\:bg-purple-600:hover{--bg-opacity:1;background-color:#805ad5;background-color:rgba(128,90,213,var(--bg-opacity))}.sm\:hover\:bg-purple-700:hover{--bg-opacity:1;background-color:#6b46c1;background-color:rgba(107,70,193,var(--bg-opacity))}.sm\:hover\:bg-purple-800:hover{--bg-opacity:1;background-color:#553c9a;background-color:rgba(85,60,154,var(--bg-opacity))}.sm\:hover\:bg-purple-900:hover{--bg-opacity:1;background-color:#44337a;background-color:rgba(68,51,122,var(--bg-opacity))}.sm\:hover\:bg-pink-100:hover{--bg-opacity:1;background-color:#fff5f7;background-color:rgba(255,245,247,var(--bg-opacity))}.sm\:hover\:bg-pink-200:hover{--bg-opacity:1;background-color:#fed7e2;background-color:rgba(254,215,226,var(--bg-opacity))}.sm\:hover\:bg-pink-300:hover{--bg-opacity:1;background-color:#fbb6ce;background-color:rgba(251,182,206,var(--bg-opacity))}.sm\:hover\:bg-pink-400:hover{--bg-opacity:1;background-color:#f687b3;background-color:rgba(246,135,179,var(--bg-opacity))}.sm\:hover\:bg-pink-500:hover{--bg-opacity:1;background-color:#ed64a6;background-color:rgba(237,100,166,var(--bg-opacity))}.sm\:hover\:bg-pink-600:hover{--bg-opacity:1;background-color:#d53f8c;background-color:rgba(213,63,140,var(--bg-opacity))}.sm\:hover\:bg-pink-700:hover{--bg-opacity:1;background-color:#b83280;background-color:rgba(184,50,128,var(--bg-opacity))}.sm\:hover\:bg-pink-800:hover{--bg-opacity:1;background-color:#97266d;background-color:rgba(151,38,109,var(--bg-opacity))}.sm\:hover\:bg-pink-900:hover{--bg-opacity:1;background-color:#702459;background-color:rgba(112,36,89,var(--bg-opacity))}.sm\:focus\:bg-transparent:focus{background-color:transparent}.sm\:focus\:bg-current:focus{background-color:currentColor}.sm\:focus\:bg-black:focus{--bg-opacity:1;background-color:#000;background-color:rgba(0,0,0,var(--bg-opacity))}.sm\:focus\:bg-white:focus{--bg-opacity:1;background-color:#fff;background-color:rgba(255,255,255,var(--bg-opacity))}.sm\:focus\:bg-gray-100:focus{--bg-opacity:1;background-color:#f7fafc;background-color:rgba(247,250,252,var(--bg-opacity))}.sm\:focus\:bg-gray-200:focus{--bg-opacity:1;background-color:#edf2f7;background-color:rgba(237,242,247,var(--bg-opacity))}.sm\:focus\:bg-gray-300:focus{--bg-opacity:1;background-color:#e2e8f0;background-color:rgba(226,232,240,var(--bg-opacity))}.sm\:focus\:bg-gray-400:focus{--bg-opacity:1;background-color:#cbd5e0;background-color:rgba(203,213,224,var(--bg-opacity))}.sm\:focus\:bg-gray-500:focus{--bg-opacity:1;background-color:#a0aec0;background-color:rgba(160,174,192,var(--bg-opacity))}.sm\:focus\:bg-gray-600:focus{--bg-opacity:1;background-color:#718096;background-color:rgba(113,128,150,var(--bg-opacity))}.sm\:focus\:bg-gray-700:focus{--bg-opacity:1;background-color:#4a5568;background-color:rgba(74,85,104,var(--bg-opacity))}.sm\:focus\:bg-gray-800:focus{--bg-opacity:1;background-color:#2d3748;background-color:rgba(45,55,72,var(--bg-opacity))}.sm\:focus\:bg-gray-900:focus{--bg-opacity:1;background-color:#1a202c;background-color:rgba(26,32,44,var(--bg-opacity))}.sm\:focus\:bg-red-100:focus{--bg-opacity:1;background-color:#fff5f5;background-color:rgba(255,245,245,var(--bg-opacity))}.sm\:focus\:bg-red-200:focus{--bg-opacity:1;background-color:#fed7d7;background-color:rgba(254,215,215,var(--bg-opacity))}.sm\:focus\:bg-red-300:focus{--bg-opacity:1;background-color:#feb2b2;background-color:rgba(254,178,178,var(--bg-opacity))}.sm\:focus\:bg-red-400:focus{--bg-opacity:1;background-color:#fc8181;background-color:rgba(252,129,129,var(--bg-opacity))}.sm\:focus\:bg-red-500:focus{--bg-opacity:1;background-color:#f56565;background-color:rgba(245,101,101,var(--bg-opacity))}.sm\:focus\:bg-red-600:focus{--bg-opacity:1;background-color:#e53e3e;background-color:rgba(229,62,62,var(--bg-opacity))}.sm\:focus\:bg-red-700:focus{--bg-opacity:1;background-color:#c53030;background-color:rgba(197,48,48,var(--bg-opacity))}.sm\:focus\:bg-red-800:focus{--bg-opacity:1;background-color:#9b2c2c;background-color:rgba(155,44,44,var(--bg-opacity))}.sm\:focus\:bg-red-900:focus{--bg-opacity:1;background-color:#742a2a;background-color:rgba(116,42,42,var(--bg-opacity))}.sm\:focus\:bg-orange-100:focus{--bg-opacity:1;background-color:#fffaf0;background-color:rgba(255,250,240,var(--bg-opacity))}.sm\:focus\:bg-orange-200:focus{--bg-opacity:1;background-color:#feebc8;background-color:rgba(254,235,200,var(--bg-opacity))}.sm\:focus\:bg-orange-300:focus{--bg-opacity:1;background-color:#fbd38d;background-color:rgba(251,211,141,var(--bg-opacity))}.sm\:focus\:bg-orange-400:focus{--bg-opacity:1;background-color:#f6ad55;background-color:rgba(246,173,85,var(--bg-opacity))}.sm\:focus\:bg-orange-500:focus{--bg-opacity:1;background-color:#ed8936;background-color:rgba(237,137,54,var(--bg-opacity))}.sm\:focus\:bg-orange-600:focus{--bg-opacity:1;background-color:#dd6b20;background-color:rgba(221,107,32,var(--bg-opacity))}.sm\:focus\:bg-orange-700:focus{--bg-opacity:1;background-color:#c05621;background-color:rgba(192,86,33,var(--bg-opacity))}.sm\:focus\:bg-orange-800:focus{--bg-opacity:1;background-color:#9c4221;background-color:rgba(156,66,33,var(--bg-opacity))}.sm\:focus\:bg-orange-900:focus{--bg-opacity:1;background-color:#7b341e;background-color:rgba(123,52,30,var(--bg-opacity))}.sm\:focus\:bg-yellow-100:focus{--bg-opacity:1;background-color:ivory;background-color:rgba(255,255,240,var(--bg-opacity))}.sm\:focus\:bg-yellow-200:focus{--bg-opacity:1;background-color:#fefcbf;background-color:rgba(254,252,191,var(--bg-opacity))}.sm\:focus\:bg-yellow-300:focus{--bg-opacity:1;background-color:#faf089;background-color:rgba(250,240,137,var(--bg-opacity))}.sm\:focus\:bg-yellow-400:focus{--bg-opacity:1;background-color:#f6e05e;background-color:rgba(246,224,94,var(--bg-opacity))}.sm\:focus\:bg-yellow-500:focus{--bg-opacity:1;background-color:#ecc94b;background-color:rgba(236,201,75,var(--bg-opacity))}.sm\:focus\:bg-yellow-600:focus{--bg-opacity:1;background-color:#d69e2e;background-color:rgba(214,158,46,var(--bg-opacity))}.sm\:focus\:bg-yellow-700:focus{--bg-opacity:1;background-color:#b7791f;background-color:rgba(183,121,31,var(--bg-opacity))}.sm\:focus\:bg-yellow-800:focus{--bg-opacity:1;background-color:#975a16;background-color:rgba(151,90,22,var(--bg-opacity))}.sm\:focus\:bg-yellow-900:focus{--bg-opacity:1;background-color:#744210;background-color:rgba(116,66,16,var(--bg-opacity))}.sm\:focus\:bg-green-100:focus{--bg-opacity:1;background-color:#f0fff4;background-color:rgba(240,255,244,var(--bg-opacity))}.sm\:focus\:bg-green-200:focus{--bg-opacity:1;background-color:#c6f6d5;background-color:rgba(198,246,213,var(--bg-opacity))}.sm\:focus\:bg-green-300:focus{--bg-opacity:1;background-color:#9ae6b4;background-color:rgba(154,230,180,var(--bg-opacity))}.sm\:focus\:bg-green-400:focus{--bg-opacity:1;background-color:#68d391;background-color:rgba(104,211,145,var(--bg-opacity))}.sm\:focus\:bg-green-500:focus{--bg-opacity:1;background-color:#48bb78;background-color:rgba(72,187,120,var(--bg-opacity))}.sm\:focus\:bg-green-600:focus{--bg-opacity:1;background-color:#38a169;background-color:rgba(56,161,105,var(--bg-opacity))}.sm\:focus\:bg-green-700:focus{--bg-opacity:1;background-color:#2f855a;background-color:rgba(47,133,90,var(--bg-opacity))}.sm\:focus\:bg-green-800:focus{--bg-opacity:1;background-color:#276749;background-color:rgba(39,103,73,var(--bg-opacity))}.sm\:focus\:bg-green-900:focus{--bg-opacity:1;background-color:#22543d;background-color:rgba(34,84,61,var(--bg-opacity))}.sm\:focus\:bg-teal-100:focus{--bg-opacity:1;background-color:#e6fffa;background-color:rgba(230,255,250,var(--bg-opacity))}.sm\:focus\:bg-teal-200:focus{--bg-opacity:1;background-color:#b2f5ea;background-color:rgba(178,245,234,var(--bg-opacity))}.sm\:focus\:bg-teal-300:focus{--bg-opacity:1;background-color:#81e6d9;background-color:rgba(129,230,217,var(--bg-opacity))}.sm\:focus\:bg-teal-400:focus{--bg-opacity:1;background-color:#4fd1c5;background-color:rgba(79,209,197,var(--bg-opacity))}.sm\:focus\:bg-teal-500:focus{--bg-opacity:1;background-color:#38b2ac;background-color:rgba(56,178,172,var(--bg-opacity))}.sm\:focus\:bg-teal-600:focus{--bg-opacity:1;background-color:#319795;background-color:rgba(49,151,149,var(--bg-opacity))}.sm\:focus\:bg-teal-700:focus{--bg-opacity:1;background-color:#2c7a7b;background-color:rgba(44,122,123,var(--bg-opacity))}.sm\:focus\:bg-teal-800:focus{--bg-opacity:1;background-color:#285e61;background-color:rgba(40,94,97,var(--bg-opacity))}.sm\:focus\:bg-teal-900:focus{--bg-opacity:1;background-color:#234e52;background-color:rgba(35,78,82,var(--bg-opacity))}.sm\:focus\:bg-blue-100:focus{--bg-opacity:1;background-color:#ebf8ff;background-color:rgba(235,248,255,var(--bg-opacity))}.sm\:focus\:bg-blue-200:focus{--bg-opacity:1;background-color:#bee3f8;background-color:rgba(190,227,248,var(--bg-opacity))}.sm\:focus\:bg-blue-300:focus{--bg-opacity:1;background-color:#90cdf4;background-color:rgba(144,205,244,var(--bg-opacity))}.sm\:focus\:bg-blue-400:focus{--bg-opacity:1;background-color:#63b3ed;background-color:rgba(99,179,237,var(--bg-opacity))}.sm\:focus\:bg-blue-500:focus{--bg-opacity:1;background-color:#4299e1;background-color:rgba(66,153,225,var(--bg-opacity))}.sm\:focus\:bg-blue-600:focus{--bg-opacity:1;background-color:#3182ce;background-color:rgba(49,130,206,var(--bg-opacity))}.sm\:focus\:bg-blue-700:focus{--bg-opacity:1;background-color:#2b6cb0;background-color:rgba(43,108,176,var(--bg-opacity))}.sm\:focus\:bg-blue-800:focus{--bg-opacity:1;background-color:#2c5282;background-color:rgba(44,82,130,var(--bg-opacity))}.sm\:focus\:bg-blue-900:focus{--bg-opacity:1;background-color:#2a4365;background-color:rgba(42,67,101,var(--bg-opacity))}.sm\:focus\:bg-indigo-100:focus{--bg-opacity:1;background-color:#ebf4ff;background-color:rgba(235,244,255,var(--bg-opacity))}.sm\:focus\:bg-indigo-200:focus{--bg-opacity:1;background-color:#c3dafe;background-color:rgba(195,218,254,var(--bg-opacity))}.sm\:focus\:bg-indigo-300:focus{--bg-opacity:1;background-color:#a3bffa;background-color:rgba(163,191,250,var(--bg-opacity))}.sm\:focus\:bg-indigo-400:focus{--bg-opacity:1;background-color:#7f9cf5;background-color:rgba(127,156,245,var(--bg-opacity))}.sm\:focus\:bg-indigo-500:focus{--bg-opacity:1;background-color:#667eea;background-color:rgba(102,126,234,var(--bg-opacity))}.sm\:focus\:bg-indigo-600:focus{--bg-opacity:1;background-color:#5a67d8;background-color:rgba(90,103,216,var(--bg-opacity))}.sm\:focus\:bg-indigo-700:focus{--bg-opacity:1;background-color:#4c51bf;background-color:rgba(76,81,191,var(--bg-opacity))}.sm\:focus\:bg-indigo-800:focus{--bg-opacity:1;background-color:#434190;background-color:rgba(67,65,144,var(--bg-opacity))}.sm\:focus\:bg-indigo-900:focus{--bg-opacity:1;background-color:#3c366b;background-color:rgba(60,54,107,var(--bg-opacity))}.sm\:focus\:bg-purple-100:focus{--bg-opacity:1;background-color:#faf5ff;background-color:rgba(250,245,255,var(--bg-opacity))}.sm\:focus\:bg-purple-200:focus{--bg-opacity:1;background-color:#e9d8fd;background-color:rgba(233,216,253,var(--bg-opacity))}.sm\:focus\:bg-purple-300:focus{--bg-opacity:1;background-color:#d6bcfa;background-color:rgba(214,188,250,var(--bg-opacity))}.sm\:focus\:bg-purple-400:focus{--bg-opacity:1;background-color:#b794f4;background-color:rgba(183,148,244,var(--bg-opacity))}.sm\:focus\:bg-purple-500:focus{--bg-opacity:1;background-color:#9f7aea;background-color:rgba(159,122,234,var(--bg-opacity))}.sm\:focus\:bg-purple-600:focus{--bg-opacity:1;background-color:#805ad5;background-color:rgba(128,90,213,var(--bg-opacity))}.sm\:focus\:bg-purple-700:focus{--bg-opacity:1;background-color:#6b46c1;background-color:rgba(107,70,193,var(--bg-opacity))}.sm\:focus\:bg-purple-800:focus{--bg-opacity:1;background-color:#553c9a;background-color:rgba(85,60,154,var(--bg-opacity))}.sm\:focus\:bg-purple-900:focus{--bg-opacity:1;background-color:#44337a;background-color:rgba(68,51,122,var(--bg-opacity))}.sm\:focus\:bg-pink-100:focus{--bg-opacity:1;background-color:#fff5f7;background-color:rgba(255,245,247,var(--bg-opacity))}.sm\:focus\:bg-pink-200:focus{--bg-opacity:1;background-color:#fed7e2;background-color:rgba(254,215,226,var(--bg-opacity))}.sm\:focus\:bg-pink-300:focus{--bg-opacity:1;background-color:#fbb6ce;background-color:rgba(251,182,206,var(--bg-opacity))}.sm\:focus\:bg-pink-400:focus{--bg-opacity:1;background-color:#f687b3;background-color:rgba(246,135,179,var(--bg-opacity))}.sm\:focus\:bg-pink-500:focus{--bg-opacity:1;background-color:#ed64a6;background-color:rgba(237,100,166,var(--bg-opacity))}.sm\:focus\:bg-pink-600:focus{--bg-opacity:1;background-color:#d53f8c;background-color:rgba(213,63,140,var(--bg-opacity))}.sm\:focus\:bg-pink-700:focus{--bg-opacity:1;background-color:#b83280;background-color:rgba(184,50,128,var(--bg-opacity))}.sm\:focus\:bg-pink-800:focus{--bg-opacity:1;background-color:#97266d;background-color:rgba(151,38,109,var(--bg-opacity))}.sm\:focus\:bg-pink-900:focus{--bg-opacity:1;background-color:#702459;background-color:rgba(112,36,89,var(--bg-opacity))}.sm\:bg-none{background-image:none}.sm\:bg-gradient-to-t{background-image:linear-gradient(to top,var(--gradient-color-stops))}.sm\:bg-gradient-to-tr{background-image:linear-gradient(to top right,var(--gradient-color-stops))}.sm\:bg-gradient-to-r{background-image:linear-gradient(to right,var(--gradient-color-stops))}.sm\:bg-gradient-to-br{background-image:linear-gradient(to bottom right,var(--gradient-color-stops))}.sm\:bg-gradient-to-b{background-image:linear-gradient(to bottom,var(--gradient-color-stops))}.sm\:bg-gradient-to-bl{background-image:linear-gradient(to bottom left,var(--gradient-color-stops))}.sm\:bg-gradient-to-l{background-image:linear-gradient(to left,var(--gradient-color-stops))}.sm\:bg-gradient-to-tl{background-image:linear-gradient(to top left,var(--gradient-color-stops))}.sm\:from-transparent{--gradient-from-color:transparent;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(0, 0, 0, 0))}.sm\:from-current{--gradient-from-color:currentColor;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 255, 255, 0))}.sm\:from-black{--gradient-from-color:#000;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(0, 0, 0, 0))}.sm\:from-white{--gradient-from-color:#fff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 255, 255, 0))}.sm\:from-gray-100{--gradient-from-color:#f7fafc;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(247, 250, 252, 0))}.sm\:from-gray-200{--gradient-from-color:#edf2f7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(237, 242, 247, 0))}.sm\:from-gray-300{--gradient-from-color:#e2e8f0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(226, 232, 240, 0))}.sm\:from-gray-400{--gradient-from-color:#cbd5e0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(203, 213, 224, 0))}.sm\:from-gray-500{--gradient-from-color:#a0aec0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(160, 174, 192, 0))}.sm\:from-gray-600{--gradient-from-color:#718096;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(113, 128, 150, 0))}.sm\:from-gray-700{--gradient-from-color:#4a5568;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(74, 85, 104, 0))}.sm\:from-gray-800{--gradient-from-color:#2d3748;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(45, 55, 72, 0))}.sm\:from-gray-900{--gradient-from-color:#1a202c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(26, 32, 44, 0))}.sm\:from-red-100{--gradient-from-color:#fff5f5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 245, 245, 0))}.sm\:from-red-200{--gradient-from-color:#fed7d7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(254, 215, 215, 0))}.sm\:from-red-300{--gradient-from-color:#feb2b2;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(254, 178, 178, 0))}.sm\:from-red-400{--gradient-from-color:#fc8181;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(252, 129, 129, 0))}.sm\:from-red-500{--gradient-from-color:#f56565;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(245, 101, 101, 0))}.sm\:from-red-600{--gradient-from-color:#e53e3e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(229, 62, 62, 0))}.sm\:from-red-700{--gradient-from-color:#c53030;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(197, 48, 48, 0))}.sm\:from-red-800{--gradient-from-color:#9b2c2c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(155, 44, 44, 0))}.sm\:from-red-900{--gradient-from-color:#742a2a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(116, 42, 42, 0))}.sm\:from-orange-100{--gradient-from-color:#fffaf0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 250, 240, 0))}.sm\:from-orange-200{--gradient-from-color:#feebc8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(254, 235, 200, 0))}.sm\:from-orange-300{--gradient-from-color:#fbd38d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(251, 211, 141, 0))}.sm\:from-orange-400{--gradient-from-color:#f6ad55;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(246, 173, 85, 0))}.sm\:from-orange-500{--gradient-from-color:#ed8936;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(237, 137, 54, 0))}.sm\:from-orange-600{--gradient-from-color:#dd6b20;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(221, 107, 32, 0))}.sm\:from-orange-700{--gradient-from-color:#c05621;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(192, 86, 33, 0))}.sm\:from-orange-800{--gradient-from-color:#9c4221;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(156, 66, 33, 0))}.sm\:from-orange-900{--gradient-from-color:#7b341e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(123, 52, 30, 0))}.sm\:from-yellow-100{--gradient-from-color:#fffff0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 255, 240, 0))}.sm\:from-yellow-200{--gradient-from-color:#fefcbf;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(254, 252, 191, 0))}.sm\:from-yellow-300{--gradient-from-color:#faf089;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(250, 240, 137, 0))}.sm\:from-yellow-400{--gradient-from-color:#f6e05e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(246, 224, 94, 0))}.sm\:from-yellow-500{--gradient-from-color:#ecc94b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(236, 201, 75, 0))}.sm\:from-yellow-600{--gradient-from-color:#d69e2e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(214, 158, 46, 0))}.sm\:from-yellow-700{--gradient-from-color:#b7791f;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(183, 121, 31, 0))}.sm\:from-yellow-800{--gradient-from-color:#975a16;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(151, 90, 22, 0))}.sm\:from-yellow-900{--gradient-from-color:#744210;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(116, 66, 16, 0))}.sm\:from-green-100{--gradient-from-color:#f0fff4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(240, 255, 244, 0))}.sm\:from-green-200{--gradient-from-color:#c6f6d5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(198, 246, 213, 0))}.sm\:from-green-300{--gradient-from-color:#9ae6b4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(154, 230, 180, 0))}.sm\:from-green-400{--gradient-from-color:#68d391;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(104, 211, 145, 0))}.sm\:from-green-500{--gradient-from-color:#48bb78;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(72, 187, 120, 0))}.sm\:from-green-600{--gradient-from-color:#38a169;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(56, 161, 105, 0))}.sm\:from-green-700{--gradient-from-color:#2f855a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(47, 133, 90, 0))}.sm\:from-green-800{--gradient-from-color:#276749;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(39, 103, 73, 0))}.sm\:from-green-900{--gradient-from-color:#22543d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(34, 84, 61, 0))}.sm\:from-teal-100{--gradient-from-color:#e6fffa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(230, 255, 250, 0))}.sm\:from-teal-200{--gradient-from-color:#b2f5ea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(178, 245, 234, 0))}.sm\:from-teal-300{--gradient-from-color:#81e6d9;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(129, 230, 217, 0))}.sm\:from-teal-400{--gradient-from-color:#4fd1c5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(79, 209, 197, 0))}.sm\:from-teal-500{--gradient-from-color:#38b2ac;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(56, 178, 172, 0))}.sm\:from-teal-600{--gradient-from-color:#319795;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(49, 151, 149, 0))}.sm\:from-teal-700{--gradient-from-color:#2c7a7b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(44, 122, 123, 0))}.sm\:from-teal-800{--gradient-from-color:#285e61;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(40, 94, 97, 0))}.sm\:from-teal-900{--gradient-from-color:#234e52;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(35, 78, 82, 0))}.sm\:from-blue-100{--gradient-from-color:#ebf8ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(235, 248, 255, 0))}.sm\:from-blue-200{--gradient-from-color:#bee3f8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(190, 227, 248, 0))}.sm\:from-blue-300{--gradient-from-color:#90cdf4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(144, 205, 244, 0))}.sm\:from-blue-400{--gradient-from-color:#63b3ed;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(99, 179, 237, 0))}.sm\:from-blue-500{--gradient-from-color:#4299e1;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(66, 153, 225, 0))}.sm\:from-blue-600{--gradient-from-color:#3182ce;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(49, 130, 206, 0))}.sm\:from-blue-700{--gradient-from-color:#2b6cb0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(43, 108, 176, 0))}.sm\:from-blue-800{--gradient-from-color:#2c5282;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(44, 82, 130, 0))}.sm\:from-blue-900{--gradient-from-color:#2a4365;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(42, 67, 101, 0))}.sm\:from-indigo-100{--gradient-from-color:#ebf4ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(235, 244, 255, 0))}.sm\:from-indigo-200{--gradient-from-color:#c3dafe;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(195, 218, 254, 0))}.sm\:from-indigo-300{--gradient-from-color:#a3bffa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(163, 191, 250, 0))}.sm\:from-indigo-400{--gradient-from-color:#7f9cf5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(127, 156, 245, 0))}.sm\:from-indigo-500{--gradient-from-color:#667eea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(102, 126, 234, 0))}.sm\:from-indigo-600{--gradient-from-color:#5a67d8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(90, 103, 216, 0))}.sm\:from-indigo-700{--gradient-from-color:#4c51bf;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(76, 81, 191, 0))}.sm\:from-indigo-800{--gradient-from-color:#434190;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(67, 65, 144, 0))}.sm\:from-indigo-900{--gradient-from-color:#3c366b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(60, 54, 107, 0))}.sm\:from-purple-100{--gradient-from-color:#faf5ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(250, 245, 255, 0))}.sm\:from-purple-200{--gradient-from-color:#e9d8fd;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(233, 216, 253, 0))}.sm\:from-purple-300{--gradient-from-color:#d6bcfa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(214, 188, 250, 0))}.sm\:from-purple-400{--gradient-from-color:#b794f4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(183, 148, 244, 0))}.sm\:from-purple-500{--gradient-from-color:#9f7aea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(159, 122, 234, 0))}.sm\:from-purple-600{--gradient-from-color:#805ad5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(128, 90, 213, 0))}.sm\:from-purple-700{--gradient-from-color:#6b46c1;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(107, 70, 193, 0))}.sm\:from-purple-800{--gradient-from-color:#553c9a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(85, 60, 154, 0))}.sm\:from-purple-900{--gradient-from-color:#44337a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(68, 51, 122, 0))}.sm\:from-pink-100{--gradient-from-color:#fff5f7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 245, 247, 0))}.sm\:from-pink-200{--gradient-from-color:#fed7e2;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(254, 215, 226, 0))}.sm\:from-pink-300{--gradient-from-color:#fbb6ce;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(251, 182, 206, 0))}.sm\:from-pink-400{--gradient-from-color:#f687b3;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(246, 135, 179, 0))}.sm\:from-pink-500{--gradient-from-color:#ed64a6;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(237, 100, 166, 0))}.sm\:from-pink-600{--gradient-from-color:#d53f8c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(213, 63, 140, 0))}.sm\:from-pink-700{--gradient-from-color:#b83280;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(184, 50, 128, 0))}.sm\:from-pink-800{--gradient-from-color:#97266d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(151, 38, 109, 0))}.sm\:from-pink-900{--gradient-from-color:#702459;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(112, 36, 89, 0))}.sm\:via-transparent{--gradient-via-color:transparent;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(0, 0, 0, 0))}.sm\:via-current{--gradient-via-color:currentColor;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 255, 255, 0))}.sm\:via-black{--gradient-via-color:#000;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(0, 0, 0, 0))}.sm\:via-white{--gradient-via-color:#fff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 255, 255, 0))}.sm\:via-gray-100{--gradient-via-color:#f7fafc;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(247, 250, 252, 0))}.sm\:via-gray-200{--gradient-via-color:#edf2f7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(237, 242, 247, 0))}.sm\:via-gray-300{--gradient-via-color:#e2e8f0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(226, 232, 240, 0))}.sm\:via-gray-400{--gradient-via-color:#cbd5e0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(203, 213, 224, 0))}.sm\:via-gray-500{--gradient-via-color:#a0aec0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(160, 174, 192, 0))}.sm\:via-gray-600{--gradient-via-color:#718096;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(113, 128, 150, 0))}.sm\:via-gray-700{--gradient-via-color:#4a5568;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(74, 85, 104, 0))}.sm\:via-gray-800{--gradient-via-color:#2d3748;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(45, 55, 72, 0))}.sm\:via-gray-900{--gradient-via-color:#1a202c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(26, 32, 44, 0))}.sm\:via-red-100{--gradient-via-color:#fff5f5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 245, 245, 0))}.sm\:via-red-200{--gradient-via-color:#fed7d7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(254, 215, 215, 0))}.sm\:via-red-300{--gradient-via-color:#feb2b2;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(254, 178, 178, 0))}.sm\:via-red-400{--gradient-via-color:#fc8181;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(252, 129, 129, 0))}.sm\:via-red-500{--gradient-via-color:#f56565;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(245, 101, 101, 0))}.sm\:via-red-600{--gradient-via-color:#e53e3e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(229, 62, 62, 0))}.sm\:via-red-700{--gradient-via-color:#c53030;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(197, 48, 48, 0))}.sm\:via-red-800{--gradient-via-color:#9b2c2c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(155, 44, 44, 0))}.sm\:via-red-900{--gradient-via-color:#742a2a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(116, 42, 42, 0))}.sm\:via-orange-100{--gradient-via-color:#fffaf0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 250, 240, 0))}.sm\:via-orange-200{--gradient-via-color:#feebc8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(254, 235, 200, 0))}.sm\:via-orange-300{--gradient-via-color:#fbd38d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(251, 211, 141, 0))}.sm\:via-orange-400{--gradient-via-color:#f6ad55;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(246, 173, 85, 0))}.sm\:via-orange-500{--gradient-via-color:#ed8936;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(237, 137, 54, 0))}.sm\:via-orange-600{--gradient-via-color:#dd6b20;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(221, 107, 32, 0))}.sm\:via-orange-700{--gradient-via-color:#c05621;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(192, 86, 33, 0))}.sm\:via-orange-800{--gradient-via-color:#9c4221;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(156, 66, 33, 0))}.sm\:via-orange-900{--gradient-via-color:#7b341e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(123, 52, 30, 0))}.sm\:via-yellow-100{--gradient-via-color:#fffff0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 255, 240, 0))}.sm\:via-yellow-200{--gradient-via-color:#fefcbf;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(254, 252, 191, 0))}.sm\:via-yellow-300{--gradient-via-color:#faf089;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(250, 240, 137, 0))}.sm\:via-yellow-400{--gradient-via-color:#f6e05e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(246, 224, 94, 0))}.sm\:via-yellow-500{--gradient-via-color:#ecc94b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(236, 201, 75, 0))}.sm\:via-yellow-600{--gradient-via-color:#d69e2e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(214, 158, 46, 0))}.sm\:via-yellow-700{--gradient-via-color:#b7791f;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(183, 121, 31, 0))}.sm\:via-yellow-800{--gradient-via-color:#975a16;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(151, 90, 22, 0))}.sm\:via-yellow-900{--gradient-via-color:#744210;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(116, 66, 16, 0))}.sm\:via-green-100{--gradient-via-color:#f0fff4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(240, 255, 244, 0))}.sm\:via-green-200{--gradient-via-color:#c6f6d5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(198, 246, 213, 0))}.sm\:via-green-300{--gradient-via-color:#9ae6b4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(154, 230, 180, 0))}.sm\:via-green-400{--gradient-via-color:#68d391;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(104, 211, 145, 0))}.sm\:via-green-500{--gradient-via-color:#48bb78;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(72, 187, 120, 0))}.sm\:via-green-600{--gradient-via-color:#38a169;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(56, 161, 105, 0))}.sm\:via-green-700{--gradient-via-color:#2f855a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(47, 133, 90, 0))}.sm\:via-green-800{--gradient-via-color:#276749;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(39, 103, 73, 0))}.sm\:via-green-900{--gradient-via-color:#22543d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(34, 84, 61, 0))}.sm\:via-teal-100{--gradient-via-color:#e6fffa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(230, 255, 250, 0))}.sm\:via-teal-200{--gradient-via-color:#b2f5ea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(178, 245, 234, 0))}.sm\:via-teal-300{--gradient-via-color:#81e6d9;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(129, 230, 217, 0))}.sm\:via-teal-400{--gradient-via-color:#4fd1c5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(79, 209, 197, 0))}.sm\:via-teal-500{--gradient-via-color:#38b2ac;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(56, 178, 172, 0))}.sm\:via-teal-600{--gradient-via-color:#319795;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(49, 151, 149, 0))}.sm\:via-teal-700{--gradient-via-color:#2c7a7b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(44, 122, 123, 0))}.sm\:via-teal-800{--gradient-via-color:#285e61;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(40, 94, 97, 0))}.sm\:via-teal-900{--gradient-via-color:#234e52;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(35, 78, 82, 0))}.sm\:via-blue-100{--gradient-via-color:#ebf8ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(235, 248, 255, 0))}.sm\:via-blue-200{--gradient-via-color:#bee3f8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(190, 227, 248, 0))}.sm\:via-blue-300{--gradient-via-color:#90cdf4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(144, 205, 244, 0))}.sm\:via-blue-400{--gradient-via-color:#63b3ed;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(99, 179, 237, 0))}.sm\:via-blue-500{--gradient-via-color:#4299e1;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(66, 153, 225, 0))}.sm\:via-blue-600{--gradient-via-color:#3182ce;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(49, 130, 206, 0))}.sm\:via-blue-700{--gradient-via-color:#2b6cb0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(43, 108, 176, 0))}.sm\:via-blue-800{--gradient-via-color:#2c5282;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(44, 82, 130, 0))}.sm\:via-blue-900{--gradient-via-color:#2a4365;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(42, 67, 101, 0))}.sm\:via-indigo-100{--gradient-via-color:#ebf4ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(235, 244, 255, 0))}.sm\:via-indigo-200{--gradient-via-color:#c3dafe;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(195, 218, 254, 0))}.sm\:via-indigo-300{--gradient-via-color:#a3bffa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(163, 191, 250, 0))}.sm\:via-indigo-400{--gradient-via-color:#7f9cf5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(127, 156, 245, 0))}.sm\:via-indigo-500{--gradient-via-color:#667eea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(102, 126, 234, 0))}.sm\:via-indigo-600{--gradient-via-color:#5a67d8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(90, 103, 216, 0))}.sm\:via-indigo-700{--gradient-via-color:#4c51bf;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(76, 81, 191, 0))}.sm\:via-indigo-800{--gradient-via-color:#434190;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(67, 65, 144, 0))}.sm\:via-indigo-900{--gradient-via-color:#3c366b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(60, 54, 107, 0))}.sm\:via-purple-100{--gradient-via-color:#faf5ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(250, 245, 255, 0))}.sm\:via-purple-200{--gradient-via-color:#e9d8fd;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(233, 216, 253, 0))}.sm\:via-purple-300{--gradient-via-color:#d6bcfa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(214, 188, 250, 0))}.sm\:via-purple-400{--gradient-via-color:#b794f4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(183, 148, 244, 0))}.sm\:via-purple-500{--gradient-via-color:#9f7aea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(159, 122, 234, 0))}.sm\:via-purple-600{--gradient-via-color:#805ad5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(128, 90, 213, 0))}.sm\:via-purple-700{--gradient-via-color:#6b46c1;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(107, 70, 193, 0))}.sm\:via-purple-800{--gradient-via-color:#553c9a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(85, 60, 154, 0))}.sm\:via-purple-900{--gradient-via-color:#44337a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(68, 51, 122, 0))}.sm\:via-pink-100{--gradient-via-color:#fff5f7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 245, 247, 0))}.sm\:via-pink-200{--gradient-via-color:#fed7e2;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(254, 215, 226, 0))}.sm\:via-pink-300{--gradient-via-color:#fbb6ce;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(251, 182, 206, 0))}.sm\:via-pink-400{--gradient-via-color:#f687b3;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(246, 135, 179, 0))}.sm\:via-pink-500{--gradient-via-color:#ed64a6;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(237, 100, 166, 0))}.sm\:via-pink-600{--gradient-via-color:#d53f8c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(213, 63, 140, 0))}.sm\:via-pink-700{--gradient-via-color:#b83280;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(184, 50, 128, 0))}.sm\:via-pink-800{--gradient-via-color:#97266d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(151, 38, 109, 0))}.sm\:via-pink-900{--gradient-via-color:#702459;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(112, 36, 89, 0))}.sm\:to-transparent{--gradient-to-color:transparent}.sm\:to-current{--gradient-to-color:currentColor}.sm\:to-black{--gradient-to-color:#000}.sm\:to-white{--gradient-to-color:#fff}.sm\:to-gray-100{--gradient-to-color:#f7fafc}.sm\:to-gray-200{--gradient-to-color:#edf2f7}.sm\:to-gray-300{--gradient-to-color:#e2e8f0}.sm\:to-gray-400{--gradient-to-color:#cbd5e0}.sm\:to-gray-500{--gradient-to-color:#a0aec0}.sm\:to-gray-600{--gradient-to-color:#718096}.sm\:to-gray-700{--gradient-to-color:#4a5568}.sm\:to-gray-800{--gradient-to-color:#2d3748}.sm\:to-gray-900{--gradient-to-color:#1a202c}.sm\:to-red-100{--gradient-to-color:#fff5f5}.sm\:to-red-200{--gradient-to-color:#fed7d7}.sm\:to-red-300{--gradient-to-color:#feb2b2}.sm\:to-red-400{--gradient-to-color:#fc8181}.sm\:to-red-500{--gradient-to-color:#f56565}.sm\:to-red-600{--gradient-to-color:#e53e3e}.sm\:to-red-700{--gradient-to-color:#c53030}.sm\:to-red-800{--gradient-to-color:#9b2c2c}.sm\:to-red-900{--gradient-to-color:#742a2a}.sm\:to-orange-100{--gradient-to-color:#fffaf0}.sm\:to-orange-200{--gradient-to-color:#feebc8}.sm\:to-orange-300{--gradient-to-color:#fbd38d}.sm\:to-orange-400{--gradient-to-color:#f6ad55}.sm\:to-orange-500{--gradient-to-color:#ed8936}.sm\:to-orange-600{--gradient-to-color:#dd6b20}.sm\:to-orange-700{--gradient-to-color:#c05621}.sm\:to-orange-800{--gradient-to-color:#9c4221}.sm\:to-orange-900{--gradient-to-color:#7b341e}.sm\:to-yellow-100{--gradient-to-color:#fffff0}.sm\:to-yellow-200{--gradient-to-color:#fefcbf}.sm\:to-yellow-300{--gradient-to-color:#faf089}.sm\:to-yellow-400{--gradient-to-color:#f6e05e}.sm\:to-yellow-500{--gradient-to-color:#ecc94b}.sm\:to-yellow-600{--gradient-to-color:#d69e2e}.sm\:to-yellow-700{--gradient-to-color:#b7791f}.sm\:to-yellow-800{--gradient-to-color:#975a16}.sm\:to-yellow-900{--gradient-to-color:#744210}.sm\:to-green-100{--gradient-to-color:#f0fff4}.sm\:to-green-200{--gradient-to-color:#c6f6d5}.sm\:to-green-300{--gradient-to-color:#9ae6b4}.sm\:to-green-400{--gradient-to-color:#68d391}.sm\:to-green-500{--gradient-to-color:#48bb78}.sm\:to-green-600{--gradient-to-color:#38a169}.sm\:to-green-700{--gradient-to-color:#2f855a}.sm\:to-green-800{--gradient-to-color:#276749}.sm\:to-green-900{--gradient-to-color:#22543d}.sm\:to-teal-100{--gradient-to-color:#e6fffa}.sm\:to-teal-200{--gradient-to-color:#b2f5ea}.sm\:to-teal-300{--gradient-to-color:#81e6d9}.sm\:to-teal-400{--gradient-to-color:#4fd1c5}.sm\:to-teal-500{--gradient-to-color:#38b2ac}.sm\:to-teal-600{--gradient-to-color:#319795}.sm\:to-teal-700{--gradient-to-color:#2c7a7b}.sm\:to-teal-800{--gradient-to-color:#285e61}.sm\:to-teal-900{--gradient-to-color:#234e52}.sm\:to-blue-100{--gradient-to-color:#ebf8ff}.sm\:to-blue-200{--gradient-to-color:#bee3f8}.sm\:to-blue-300{--gradient-to-color:#90cdf4}.sm\:to-blue-400{--gradient-to-color:#63b3ed}.sm\:to-blue-500{--gradient-to-color:#4299e1}.sm\:to-blue-600{--gradient-to-color:#3182ce}.sm\:to-blue-700{--gradient-to-color:#2b6cb0}.sm\:to-blue-800{--gradient-to-color:#2c5282}.sm\:to-blue-900{--gradient-to-color:#2a4365}.sm\:to-indigo-100{--gradient-to-color:#ebf4ff}.sm\:to-indigo-200{--gradient-to-color:#c3dafe}.sm\:to-indigo-300{--gradient-to-color:#a3bffa}.sm\:to-indigo-400{--gradient-to-color:#7f9cf5}.sm\:to-indigo-500{--gradient-to-color:#667eea}.sm\:to-indigo-600{--gradient-to-color:#5a67d8}.sm\:to-indigo-700{--gradient-to-color:#4c51bf}.sm\:to-indigo-800{--gradient-to-color:#434190}.sm\:to-indigo-900{--gradient-to-color:#3c366b}.sm\:to-purple-100{--gradient-to-color:#faf5ff}.sm\:to-purple-200{--gradient-to-color:#e9d8fd}.sm\:to-purple-300{--gradient-to-color:#d6bcfa}.sm\:to-purple-400{--gradient-to-color:#b794f4}.sm\:to-purple-500{--gradient-to-color:#9f7aea}.sm\:to-purple-600{--gradient-to-color:#805ad5}.sm\:to-purple-700{--gradient-to-color:#6b46c1}.sm\:to-purple-800{--gradient-to-color:#553c9a}.sm\:to-purple-900{--gradient-to-color:#44337a}.sm\:to-pink-100{--gradient-to-color:#fff5f7}.sm\:to-pink-200{--gradient-to-color:#fed7e2}.sm\:to-pink-300{--gradient-to-color:#fbb6ce}.sm\:to-pink-400{--gradient-to-color:#f687b3}.sm\:to-pink-500{--gradient-to-color:#ed64a6}.sm\:to-pink-600{--gradient-to-color:#d53f8c}.sm\:to-pink-700{--gradient-to-color:#b83280}.sm\:to-pink-800{--gradient-to-color:#97266d}.sm\:to-pink-900{--gradient-to-color:#702459}.sm\:hover\:from-transparent:hover{--gradient-from-color:transparent;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(0, 0, 0, 0))}.sm\:hover\:from-current:hover{--gradient-from-color:currentColor;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 255, 255, 0))}.sm\:hover\:from-black:hover{--gradient-from-color:#000;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(0, 0, 0, 0))}.sm\:hover\:from-white:hover{--gradient-from-color:#fff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 255, 255, 0))}.sm\:hover\:from-gray-100:hover{--gradient-from-color:#f7fafc;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(247, 250, 252, 0))}.sm\:hover\:from-gray-200:hover{--gradient-from-color:#edf2f7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(237, 242, 247, 0))}.sm\:hover\:from-gray-300:hover{--gradient-from-color:#e2e8f0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(226, 232, 240, 0))}.sm\:hover\:from-gray-400:hover{--gradient-from-color:#cbd5e0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(203, 213, 224, 0))}.sm\:hover\:from-gray-500:hover{--gradient-from-color:#a0aec0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(160, 174, 192, 0))}.sm\:hover\:from-gray-600:hover{--gradient-from-color:#718096;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(113, 128, 150, 0))}.sm\:hover\:from-gray-700:hover{--gradient-from-color:#4a5568;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(74, 85, 104, 0))}.sm\:hover\:from-gray-800:hover{--gradient-from-color:#2d3748;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(45, 55, 72, 0))}.sm\:hover\:from-gray-900:hover{--gradient-from-color:#1a202c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(26, 32, 44, 0))}.sm\:hover\:from-red-100:hover{--gradient-from-color:#fff5f5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 245, 245, 0))}.sm\:hover\:from-red-200:hover{--gradient-from-color:#fed7d7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(254, 215, 215, 0))}.sm\:hover\:from-red-300:hover{--gradient-from-color:#feb2b2;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(254, 178, 178, 0))}.sm\:hover\:from-red-400:hover{--gradient-from-color:#fc8181;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(252, 129, 129, 0))}.sm\:hover\:from-red-500:hover{--gradient-from-color:#f56565;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(245, 101, 101, 0))}.sm\:hover\:from-red-600:hover{--gradient-from-color:#e53e3e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(229, 62, 62, 0))}.sm\:hover\:from-red-700:hover{--gradient-from-color:#c53030;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(197, 48, 48, 0))}.sm\:hover\:from-red-800:hover{--gradient-from-color:#9b2c2c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(155, 44, 44, 0))}.sm\:hover\:from-red-900:hover{--gradient-from-color:#742a2a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(116, 42, 42, 0))}.sm\:hover\:from-orange-100:hover{--gradient-from-color:#fffaf0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 250, 240, 0))}.sm\:hover\:from-orange-200:hover{--gradient-from-color:#feebc8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(254, 235, 200, 0))}.sm\:hover\:from-orange-300:hover{--gradient-from-color:#fbd38d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(251, 211, 141, 0))}.sm\:hover\:from-orange-400:hover{--gradient-from-color:#f6ad55;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(246, 173, 85, 0))}.sm\:hover\:from-orange-500:hover{--gradient-from-color:#ed8936;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(237, 137, 54, 0))}.sm\:hover\:from-orange-600:hover{--gradient-from-color:#dd6b20;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(221, 107, 32, 0))}.sm\:hover\:from-orange-700:hover{--gradient-from-color:#c05621;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(192, 86, 33, 0))}.sm\:hover\:from-orange-800:hover{--gradient-from-color:#9c4221;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(156, 66, 33, 0))}.sm\:hover\:from-orange-900:hover{--gradient-from-color:#7b341e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(123, 52, 30, 0))}.sm\:hover\:from-yellow-100:hover{--gradient-from-color:#fffff0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 255, 240, 0))}.sm\:hover\:from-yellow-200:hover{--gradient-from-color:#fefcbf;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(254, 252, 191, 0))}.sm\:hover\:from-yellow-300:hover{--gradient-from-color:#faf089;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(250, 240, 137, 0))}.sm\:hover\:from-yellow-400:hover{--gradient-from-color:#f6e05e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(246, 224, 94, 0))}.sm\:hover\:from-yellow-500:hover{--gradient-from-color:#ecc94b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(236, 201, 75, 0))}.sm\:hover\:from-yellow-600:hover{--gradient-from-color:#d69e2e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(214, 158, 46, 0))}.sm\:hover\:from-yellow-700:hover{--gradient-from-color:#b7791f;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(183, 121, 31, 0))}.sm\:hover\:from-yellow-800:hover{--gradient-from-color:#975a16;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(151, 90, 22, 0))}.sm\:hover\:from-yellow-900:hover{--gradient-from-color:#744210;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(116, 66, 16, 0))}.sm\:hover\:from-green-100:hover{--gradient-from-color:#f0fff4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(240, 255, 244, 0))}.sm\:hover\:from-green-200:hover{--gradient-from-color:#c6f6d5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(198, 246, 213, 0))}.sm\:hover\:from-green-300:hover{--gradient-from-color:#9ae6b4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(154, 230, 180, 0))}.sm\:hover\:from-green-400:hover{--gradient-from-color:#68d391;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(104, 211, 145, 0))}.sm\:hover\:from-green-500:hover{--gradient-from-color:#48bb78;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(72, 187, 120, 0))}.sm\:hover\:from-green-600:hover{--gradient-from-color:#38a169;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(56, 161, 105, 0))}.sm\:hover\:from-green-700:hover{--gradient-from-color:#2f855a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(47, 133, 90, 0))}.sm\:hover\:from-green-800:hover{--gradient-from-color:#276749;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(39, 103, 73, 0))}.sm\:hover\:from-green-900:hover{--gradient-from-color:#22543d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(34, 84, 61, 0))}.sm\:hover\:from-teal-100:hover{--gradient-from-color:#e6fffa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(230, 255, 250, 0))}.sm\:hover\:from-teal-200:hover{--gradient-from-color:#b2f5ea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(178, 245, 234, 0))}.sm\:hover\:from-teal-300:hover{--gradient-from-color:#81e6d9;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(129, 230, 217, 0))}.sm\:hover\:from-teal-400:hover{--gradient-from-color:#4fd1c5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(79, 209, 197, 0))}.sm\:hover\:from-teal-500:hover{--gradient-from-color:#38b2ac;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(56, 178, 172, 0))}.sm\:hover\:from-teal-600:hover{--gradient-from-color:#319795;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(49, 151, 149, 0))}.sm\:hover\:from-teal-700:hover{--gradient-from-color:#2c7a7b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(44, 122, 123, 0))}.sm\:hover\:from-teal-800:hover{--gradient-from-color:#285e61;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(40, 94, 97, 0))}.sm\:hover\:from-teal-900:hover{--gradient-from-color:#234e52;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(35, 78, 82, 0))}.sm\:hover\:from-blue-100:hover{--gradient-from-color:#ebf8ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(235, 248, 255, 0))}.sm\:hover\:from-blue-200:hover{--gradient-from-color:#bee3f8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(190, 227, 248, 0))}.sm\:hover\:from-blue-300:hover{--gradient-from-color:#90cdf4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(144, 205, 244, 0))}.sm\:hover\:from-blue-400:hover{--gradient-from-color:#63b3ed;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(99, 179, 237, 0))}.sm\:hover\:from-blue-500:hover{--gradient-from-color:#4299e1;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(66, 153, 225, 0))}.sm\:hover\:from-blue-600:hover{--gradient-from-color:#3182ce;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(49, 130, 206, 0))}.sm\:hover\:from-blue-700:hover{--gradient-from-color:#2b6cb0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(43, 108, 176, 0))}.sm\:hover\:from-blue-800:hover{--gradient-from-color:#2c5282;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(44, 82, 130, 0))}.sm\:hover\:from-blue-900:hover{--gradient-from-color:#2a4365;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(42, 67, 101, 0))}.sm\:hover\:from-indigo-100:hover{--gradient-from-color:#ebf4ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(235, 244, 255, 0))}.sm\:hover\:from-indigo-200:hover{--gradient-from-color:#c3dafe;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(195, 218, 254, 0))}.sm\:hover\:from-indigo-300:hover{--gradient-from-color:#a3bffa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(163, 191, 250, 0))}.sm\:hover\:from-indigo-400:hover{--gradient-from-color:#7f9cf5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(127, 156, 245, 0))}.sm\:hover\:from-indigo-500:hover{--gradient-from-color:#667eea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(102, 126, 234, 0))}.sm\:hover\:from-indigo-600:hover{--gradient-from-color:#5a67d8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(90, 103, 216, 0))}.sm\:hover\:from-indigo-700:hover{--gradient-from-color:#4c51bf;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(76, 81, 191, 0))}.sm\:hover\:from-indigo-800:hover{--gradient-from-color:#434190;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(67, 65, 144, 0))}.sm\:hover\:from-indigo-900:hover{--gradient-from-color:#3c366b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(60, 54, 107, 0))}.sm\:hover\:from-purple-100:hover{--gradient-from-color:#faf5ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(250, 245, 255, 0))}.sm\:hover\:from-purple-200:hover{--gradient-from-color:#e9d8fd;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(233, 216, 253, 0))}.sm\:hover\:from-purple-300:hover{--gradient-from-color:#d6bcfa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(214, 188, 250, 0))}.sm\:hover\:from-purple-400:hover{--gradient-from-color:#b794f4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(183, 148, 244, 0))}.sm\:hover\:from-purple-500:hover{--gradient-from-color:#9f7aea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(159, 122, 234, 0))}.sm\:hover\:from-purple-600:hover{--gradient-from-color:#805ad5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(128, 90, 213, 0))}.sm\:hover\:from-purple-700:hover{--gradient-from-color:#6b46c1;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(107, 70, 193, 0))}.sm\:hover\:from-purple-800:hover{--gradient-from-color:#553c9a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(85, 60, 154, 0))}.sm\:hover\:from-purple-900:hover{--gradient-from-color:#44337a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(68, 51, 122, 0))}.sm\:hover\:from-pink-100:hover{--gradient-from-color:#fff5f7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 245, 247, 0))}.sm\:hover\:from-pink-200:hover{--gradient-from-color:#fed7e2;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(254, 215, 226, 0))}.sm\:hover\:from-pink-300:hover{--gradient-from-color:#fbb6ce;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(251, 182, 206, 0))}.sm\:hover\:from-pink-400:hover{--gradient-from-color:#f687b3;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(246, 135, 179, 0))}.sm\:hover\:from-pink-500:hover{--gradient-from-color:#ed64a6;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(237, 100, 166, 0))}.sm\:hover\:from-pink-600:hover{--gradient-from-color:#d53f8c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(213, 63, 140, 0))}.sm\:hover\:from-pink-700:hover{--gradient-from-color:#b83280;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(184, 50, 128, 0))}.sm\:hover\:from-pink-800:hover{--gradient-from-color:#97266d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(151, 38, 109, 0))}.sm\:hover\:from-pink-900:hover{--gradient-from-color:#702459;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(112, 36, 89, 0))}.sm\:hover\:via-transparent:hover{--gradient-via-color:transparent;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(0, 0, 0, 0))}.sm\:hover\:via-current:hover{--gradient-via-color:currentColor;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 255, 255, 0))}.sm\:hover\:via-black:hover{--gradient-via-color:#000;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(0, 0, 0, 0))}.sm\:hover\:via-white:hover{--gradient-via-color:#fff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 255, 255, 0))}.sm\:hover\:via-gray-100:hover{--gradient-via-color:#f7fafc;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(247, 250, 252, 0))}.sm\:hover\:via-gray-200:hover{--gradient-via-color:#edf2f7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(237, 242, 247, 0))}.sm\:hover\:via-gray-300:hover{--gradient-via-color:#e2e8f0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(226, 232, 240, 0))}.sm\:hover\:via-gray-400:hover{--gradient-via-color:#cbd5e0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(203, 213, 224, 0))}.sm\:hover\:via-gray-500:hover{--gradient-via-color:#a0aec0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(160, 174, 192, 0))}.sm\:hover\:via-gray-600:hover{--gradient-via-color:#718096;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(113, 128, 150, 0))}.sm\:hover\:via-gray-700:hover{--gradient-via-color:#4a5568;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(74, 85, 104, 0))}.sm\:hover\:via-gray-800:hover{--gradient-via-color:#2d3748;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(45, 55, 72, 0))}.sm\:hover\:via-gray-900:hover{--gradient-via-color:#1a202c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(26, 32, 44, 0))}.sm\:hover\:via-red-100:hover{--gradient-via-color:#fff5f5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 245, 245, 0))}.sm\:hover\:via-red-200:hover{--gradient-via-color:#fed7d7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(254, 215, 215, 0))}.sm\:hover\:via-red-300:hover{--gradient-via-color:#feb2b2;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(254, 178, 178, 0))}.sm\:hover\:via-red-400:hover{--gradient-via-color:#fc8181;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(252, 129, 129, 0))}.sm\:hover\:via-red-500:hover{--gradient-via-color:#f56565;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(245, 101, 101, 0))}.sm\:hover\:via-red-600:hover{--gradient-via-color:#e53e3e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(229, 62, 62, 0))}.sm\:hover\:via-red-700:hover{--gradient-via-color:#c53030;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(197, 48, 48, 0))}.sm\:hover\:via-red-800:hover{--gradient-via-color:#9b2c2c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(155, 44, 44, 0))}.sm\:hover\:via-red-900:hover{--gradient-via-color:#742a2a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(116, 42, 42, 0))}.sm\:hover\:via-orange-100:hover{--gradient-via-color:#fffaf0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 250, 240, 0))}.sm\:hover\:via-orange-200:hover{--gradient-via-color:#feebc8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(254, 235, 200, 0))}.sm\:hover\:via-orange-300:hover{--gradient-via-color:#fbd38d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(251, 211, 141, 0))}.sm\:hover\:via-orange-400:hover{--gradient-via-color:#f6ad55;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(246, 173, 85, 0))}.sm\:hover\:via-orange-500:hover{--gradient-via-color:#ed8936;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(237, 137, 54, 0))}.sm\:hover\:via-orange-600:hover{--gradient-via-color:#dd6b20;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(221, 107, 32, 0))}.sm\:hover\:via-orange-700:hover{--gradient-via-color:#c05621;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(192, 86, 33, 0))}.sm\:hover\:via-orange-800:hover{--gradient-via-color:#9c4221;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(156, 66, 33, 0))}.sm\:hover\:via-orange-900:hover{--gradient-via-color:#7b341e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(123, 52, 30, 0))}.sm\:hover\:via-yellow-100:hover{--gradient-via-color:#fffff0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 255, 240, 0))}.sm\:hover\:via-yellow-200:hover{--gradient-via-color:#fefcbf;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(254, 252, 191, 0))}.sm\:hover\:via-yellow-300:hover{--gradient-via-color:#faf089;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(250, 240, 137, 0))}.sm\:hover\:via-yellow-400:hover{--gradient-via-color:#f6e05e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(246, 224, 94, 0))}.sm\:hover\:via-yellow-500:hover{--gradient-via-color:#ecc94b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(236, 201, 75, 0))}.sm\:hover\:via-yellow-600:hover{--gradient-via-color:#d69e2e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(214, 158, 46, 0))}.sm\:hover\:via-yellow-700:hover{--gradient-via-color:#b7791f;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(183, 121, 31, 0))}.sm\:hover\:via-yellow-800:hover{--gradient-via-color:#975a16;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(151, 90, 22, 0))}.sm\:hover\:via-yellow-900:hover{--gradient-via-color:#744210;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(116, 66, 16, 0))}.sm\:hover\:via-green-100:hover{--gradient-via-color:#f0fff4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(240, 255, 244, 0))}.sm\:hover\:via-green-200:hover{--gradient-via-color:#c6f6d5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(198, 246, 213, 0))}.sm\:hover\:via-green-300:hover{--gradient-via-color:#9ae6b4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(154, 230, 180, 0))}.sm\:hover\:via-green-400:hover{--gradient-via-color:#68d391;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(104, 211, 145, 0))}.sm\:hover\:via-green-500:hover{--gradient-via-color:#48bb78;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(72, 187, 120, 0))}.sm\:hover\:via-green-600:hover{--gradient-via-color:#38a169;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(56, 161, 105, 0))}.sm\:hover\:via-green-700:hover{--gradient-via-color:#2f855a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(47, 133, 90, 0))}.sm\:hover\:via-green-800:hover{--gradient-via-color:#276749;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(39, 103, 73, 0))}.sm\:hover\:via-green-900:hover{--gradient-via-color:#22543d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(34, 84, 61, 0))}.sm\:hover\:via-teal-100:hover{--gradient-via-color:#e6fffa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(230, 255, 250, 0))}.sm\:hover\:via-teal-200:hover{--gradient-via-color:#b2f5ea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(178, 245, 234, 0))}.sm\:hover\:via-teal-300:hover{--gradient-via-color:#81e6d9;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(129, 230, 217, 0))}.sm\:hover\:via-teal-400:hover{--gradient-via-color:#4fd1c5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(79, 209, 197, 0))}.sm\:hover\:via-teal-500:hover{--gradient-via-color:#38b2ac;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(56, 178, 172, 0))}.sm\:hover\:via-teal-600:hover{--gradient-via-color:#319795;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(49, 151, 149, 0))}.sm\:hover\:via-teal-700:hover{--gradient-via-color:#2c7a7b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(44, 122, 123, 0))}.sm\:hover\:via-teal-800:hover{--gradient-via-color:#285e61;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(40, 94, 97, 0))}.sm\:hover\:via-teal-900:hover{--gradient-via-color:#234e52;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(35, 78, 82, 0))}.sm\:hover\:via-blue-100:hover{--gradient-via-color:#ebf8ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(235, 248, 255, 0))}.sm\:hover\:via-blue-200:hover{--gradient-via-color:#bee3f8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(190, 227, 248, 0))}.sm\:hover\:via-blue-300:hover{--gradient-via-color:#90cdf4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(144, 205, 244, 0))}.sm\:hover\:via-blue-400:hover{--gradient-via-color:#63b3ed;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(99, 179, 237, 0))}.sm\:hover\:via-blue-500:hover{--gradient-via-color:#4299e1;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(66, 153, 225, 0))}.sm\:hover\:via-blue-600:hover{--gradient-via-color:#3182ce;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(49, 130, 206, 0))}.sm\:hover\:via-blue-700:hover{--gradient-via-color:#2b6cb0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(43, 108, 176, 0))}.sm\:hover\:via-blue-800:hover{--gradient-via-color:#2c5282;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(44, 82, 130, 0))}.sm\:hover\:via-blue-900:hover{--gradient-via-color:#2a4365;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(42, 67, 101, 0))}.sm\:hover\:via-indigo-100:hover{--gradient-via-color:#ebf4ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(235, 244, 255, 0))}.sm\:hover\:via-indigo-200:hover{--gradient-via-color:#c3dafe;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(195, 218, 254, 0))}.sm\:hover\:via-indigo-300:hover{--gradient-via-color:#a3bffa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(163, 191, 250, 0))}.sm\:hover\:via-indigo-400:hover{--gradient-via-color:#7f9cf5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(127, 156, 245, 0))}.sm\:hover\:via-indigo-500:hover{--gradient-via-color:#667eea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(102, 126, 234, 0))}.sm\:hover\:via-indigo-600:hover{--gradient-via-color:#5a67d8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(90, 103, 216, 0))}.sm\:hover\:via-indigo-700:hover{--gradient-via-color:#4c51bf;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(76, 81, 191, 0))}.sm\:hover\:via-indigo-800:hover{--gradient-via-color:#434190;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(67, 65, 144, 0))}.sm\:hover\:via-indigo-900:hover{--gradient-via-color:#3c366b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(60, 54, 107, 0))}.sm\:hover\:via-purple-100:hover{--gradient-via-color:#faf5ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(250, 245, 255, 0))}.sm\:hover\:via-purple-200:hover{--gradient-via-color:#e9d8fd;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(233, 216, 253, 0))}.sm\:hover\:via-purple-300:hover{--gradient-via-color:#d6bcfa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(214, 188, 250, 0))}.sm\:hover\:via-purple-400:hover{--gradient-via-color:#b794f4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(183, 148, 244, 0))}.sm\:hover\:via-purple-500:hover{--gradient-via-color:#9f7aea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(159, 122, 234, 0))}.sm\:hover\:via-purple-600:hover{--gradient-via-color:#805ad5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(128, 90, 213, 0))}.sm\:hover\:via-purple-700:hover{--gradient-via-color:#6b46c1;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(107, 70, 193, 0))}.sm\:hover\:via-purple-800:hover{--gradient-via-color:#553c9a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(85, 60, 154, 0))}.sm\:hover\:via-purple-900:hover{--gradient-via-color:#44337a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(68, 51, 122, 0))}.sm\:hover\:via-pink-100:hover{--gradient-via-color:#fff5f7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 245, 247, 0))}.sm\:hover\:via-pink-200:hover{--gradient-via-color:#fed7e2;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(254, 215, 226, 0))}.sm\:hover\:via-pink-300:hover{--gradient-via-color:#fbb6ce;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(251, 182, 206, 0))}.sm\:hover\:via-pink-400:hover{--gradient-via-color:#f687b3;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(246, 135, 179, 0))}.sm\:hover\:via-pink-500:hover{--gradient-via-color:#ed64a6;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(237, 100, 166, 0))}.sm\:hover\:via-pink-600:hover{--gradient-via-color:#d53f8c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(213, 63, 140, 0))}.sm\:hover\:via-pink-700:hover{--gradient-via-color:#b83280;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(184, 50, 128, 0))}.sm\:hover\:via-pink-800:hover{--gradient-via-color:#97266d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(151, 38, 109, 0))}.sm\:hover\:via-pink-900:hover{--gradient-via-color:#702459;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(112, 36, 89, 0))}.sm\:hover\:to-transparent:hover{--gradient-to-color:transparent}.sm\:hover\:to-current:hover{--gradient-to-color:currentColor}.sm\:hover\:to-black:hover{--gradient-to-color:#000}.sm\:hover\:to-white:hover{--gradient-to-color:#fff}.sm\:hover\:to-gray-100:hover{--gradient-to-color:#f7fafc}.sm\:hover\:to-gray-200:hover{--gradient-to-color:#edf2f7}.sm\:hover\:to-gray-300:hover{--gradient-to-color:#e2e8f0}.sm\:hover\:to-gray-400:hover{--gradient-to-color:#cbd5e0}.sm\:hover\:to-gray-500:hover{--gradient-to-color:#a0aec0}.sm\:hover\:to-gray-600:hover{--gradient-to-color:#718096}.sm\:hover\:to-gray-700:hover{--gradient-to-color:#4a5568}.sm\:hover\:to-gray-800:hover{--gradient-to-color:#2d3748}.sm\:hover\:to-gray-900:hover{--gradient-to-color:#1a202c}.sm\:hover\:to-red-100:hover{--gradient-to-color:#fff5f5}.sm\:hover\:to-red-200:hover{--gradient-to-color:#fed7d7}.sm\:hover\:to-red-300:hover{--gradient-to-color:#feb2b2}.sm\:hover\:to-red-400:hover{--gradient-to-color:#fc8181}.sm\:hover\:to-red-500:hover{--gradient-to-color:#f56565}.sm\:hover\:to-red-600:hover{--gradient-to-color:#e53e3e}.sm\:hover\:to-red-700:hover{--gradient-to-color:#c53030}.sm\:hover\:to-red-800:hover{--gradient-to-color:#9b2c2c}.sm\:hover\:to-red-900:hover{--gradient-to-color:#742a2a}.sm\:hover\:to-orange-100:hover{--gradient-to-color:#fffaf0}.sm\:hover\:to-orange-200:hover{--gradient-to-color:#feebc8}.sm\:hover\:to-orange-300:hover{--gradient-to-color:#fbd38d}.sm\:hover\:to-orange-400:hover{--gradient-to-color:#f6ad55}.sm\:hover\:to-orange-500:hover{--gradient-to-color:#ed8936}.sm\:hover\:to-orange-600:hover{--gradient-to-color:#dd6b20}.sm\:hover\:to-orange-700:hover{--gradient-to-color:#c05621}.sm\:hover\:to-orange-800:hover{--gradient-to-color:#9c4221}.sm\:hover\:to-orange-900:hover{--gradient-to-color:#7b341e}.sm\:hover\:to-yellow-100:hover{--gradient-to-color:#fffff0}.sm\:hover\:to-yellow-200:hover{--gradient-to-color:#fefcbf}.sm\:hover\:to-yellow-300:hover{--gradient-to-color:#faf089}.sm\:hover\:to-yellow-400:hover{--gradient-to-color:#f6e05e}.sm\:hover\:to-yellow-500:hover{--gradient-to-color:#ecc94b}.sm\:hover\:to-yellow-600:hover{--gradient-to-color:#d69e2e}.sm\:hover\:to-yellow-700:hover{--gradient-to-color:#b7791f}.sm\:hover\:to-yellow-800:hover{--gradient-to-color:#975a16}.sm\:hover\:to-yellow-900:hover{--gradient-to-color:#744210}.sm\:hover\:to-green-100:hover{--gradient-to-color:#f0fff4}.sm\:hover\:to-green-200:hover{--gradient-to-color:#c6f6d5}.sm\:hover\:to-green-300:hover{--gradient-to-color:#9ae6b4}.sm\:hover\:to-green-400:hover{--gradient-to-color:#68d391}.sm\:hover\:to-green-500:hover{--gradient-to-color:#48bb78}.sm\:hover\:to-green-600:hover{--gradient-to-color:#38a169}.sm\:hover\:to-green-700:hover{--gradient-to-color:#2f855a}.sm\:hover\:to-green-800:hover{--gradient-to-color:#276749}.sm\:hover\:to-green-900:hover{--gradient-to-color:#22543d}.sm\:hover\:to-teal-100:hover{--gradient-to-color:#e6fffa}.sm\:hover\:to-teal-200:hover{--gradient-to-color:#b2f5ea}.sm\:hover\:to-teal-300:hover{--gradient-to-color:#81e6d9}.sm\:hover\:to-teal-400:hover{--gradient-to-color:#4fd1c5}.sm\:hover\:to-teal-500:hover{--gradient-to-color:#38b2ac}.sm\:hover\:to-teal-600:hover{--gradient-to-color:#319795}.sm\:hover\:to-teal-700:hover{--gradient-to-color:#2c7a7b}.sm\:hover\:to-teal-800:hover{--gradient-to-color:#285e61}.sm\:hover\:to-teal-900:hover{--gradient-to-color:#234e52}.sm\:hover\:to-blue-100:hover{--gradient-to-color:#ebf8ff}.sm\:hover\:to-blue-200:hover{--gradient-to-color:#bee3f8}.sm\:hover\:to-blue-300:hover{--gradient-to-color:#90cdf4}.sm\:hover\:to-blue-400:hover{--gradient-to-color:#63b3ed}.sm\:hover\:to-blue-500:hover{--gradient-to-color:#4299e1}.sm\:hover\:to-blue-600:hover{--gradient-to-color:#3182ce}.sm\:hover\:to-blue-700:hover{--gradient-to-color:#2b6cb0}.sm\:hover\:to-blue-800:hover{--gradient-to-color:#2c5282}.sm\:hover\:to-blue-900:hover{--gradient-to-color:#2a4365}.sm\:hover\:to-indigo-100:hover{--gradient-to-color:#ebf4ff}.sm\:hover\:to-indigo-200:hover{--gradient-to-color:#c3dafe}.sm\:hover\:to-indigo-300:hover{--gradient-to-color:#a3bffa}.sm\:hover\:to-indigo-400:hover{--gradient-to-color:#7f9cf5}.sm\:hover\:to-indigo-500:hover{--gradient-to-color:#667eea}.sm\:hover\:to-indigo-600:hover{--gradient-to-color:#5a67d8}.sm\:hover\:to-indigo-700:hover{--gradient-to-color:#4c51bf}.sm\:hover\:to-indigo-800:hover{--gradient-to-color:#434190}.sm\:hover\:to-indigo-900:hover{--gradient-to-color:#3c366b}.sm\:hover\:to-purple-100:hover{--gradient-to-color:#faf5ff}.sm\:hover\:to-purple-200:hover{--gradient-to-color:#e9d8fd}.sm\:hover\:to-purple-300:hover{--gradient-to-color:#d6bcfa}.sm\:hover\:to-purple-400:hover{--gradient-to-color:#b794f4}.sm\:hover\:to-purple-500:hover{--gradient-to-color:#9f7aea}.sm\:hover\:to-purple-600:hover{--gradient-to-color:#805ad5}.sm\:hover\:to-purple-700:hover{--gradient-to-color:#6b46c1}.sm\:hover\:to-purple-800:hover{--gradient-to-color:#553c9a}.sm\:hover\:to-purple-900:hover{--gradient-to-color:#44337a}.sm\:hover\:to-pink-100:hover{--gradient-to-color:#fff5f7}.sm\:hover\:to-pink-200:hover{--gradient-to-color:#fed7e2}.sm\:hover\:to-pink-300:hover{--gradient-to-color:#fbb6ce}.sm\:hover\:to-pink-400:hover{--gradient-to-color:#f687b3}.sm\:hover\:to-pink-500:hover{--gradient-to-color:#ed64a6}.sm\:hover\:to-pink-600:hover{--gradient-to-color:#d53f8c}.sm\:hover\:to-pink-700:hover{--gradient-to-color:#b83280}.sm\:hover\:to-pink-800:hover{--gradient-to-color:#97266d}.sm\:hover\:to-pink-900:hover{--gradient-to-color:#702459}.sm\:focus\:from-transparent:focus{--gradient-from-color:transparent;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(0, 0, 0, 0))}.sm\:focus\:from-current:focus{--gradient-from-color:currentColor;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 255, 255, 0))}.sm\:focus\:from-black:focus{--gradient-from-color:#000;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(0, 0, 0, 0))}.sm\:focus\:from-white:focus{--gradient-from-color:#fff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 255, 255, 0))}.sm\:focus\:from-gray-100:focus{--gradient-from-color:#f7fafc;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(247, 250, 252, 0))}.sm\:focus\:from-gray-200:focus{--gradient-from-color:#edf2f7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(237, 242, 247, 0))}.sm\:focus\:from-gray-300:focus{--gradient-from-color:#e2e8f0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(226, 232, 240, 0))}.sm\:focus\:from-gray-400:focus{--gradient-from-color:#cbd5e0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(203, 213, 224, 0))}.sm\:focus\:from-gray-500:focus{--gradient-from-color:#a0aec0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(160, 174, 192, 0))}.sm\:focus\:from-gray-600:focus{--gradient-from-color:#718096;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(113, 128, 150, 0))}.sm\:focus\:from-gray-700:focus{--gradient-from-color:#4a5568;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(74, 85, 104, 0))}.sm\:focus\:from-gray-800:focus{--gradient-from-color:#2d3748;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(45, 55, 72, 0))}.sm\:focus\:from-gray-900:focus{--gradient-from-color:#1a202c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(26, 32, 44, 0))}.sm\:focus\:from-red-100:focus{--gradient-from-color:#fff5f5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 245, 245, 0))}.sm\:focus\:from-red-200:focus{--gradient-from-color:#fed7d7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(254, 215, 215, 0))}.sm\:focus\:from-red-300:focus{--gradient-from-color:#feb2b2;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(254, 178, 178, 0))}.sm\:focus\:from-red-400:focus{--gradient-from-color:#fc8181;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(252, 129, 129, 0))}.sm\:focus\:from-red-500:focus{--gradient-from-color:#f56565;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(245, 101, 101, 0))}.sm\:focus\:from-red-600:focus{--gradient-from-color:#e53e3e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(229, 62, 62, 0))}.sm\:focus\:from-red-700:focus{--gradient-from-color:#c53030;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(197, 48, 48, 0))}.sm\:focus\:from-red-800:focus{--gradient-from-color:#9b2c2c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(155, 44, 44, 0))}.sm\:focus\:from-red-900:focus{--gradient-from-color:#742a2a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(116, 42, 42, 0))}.sm\:focus\:from-orange-100:focus{--gradient-from-color:#fffaf0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 250, 240, 0))}.sm\:focus\:from-orange-200:focus{--gradient-from-color:#feebc8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(254, 235, 200, 0))}.sm\:focus\:from-orange-300:focus{--gradient-from-color:#fbd38d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(251, 211, 141, 0))}.sm\:focus\:from-orange-400:focus{--gradient-from-color:#f6ad55;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(246, 173, 85, 0))}.sm\:focus\:from-orange-500:focus{--gradient-from-color:#ed8936;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(237, 137, 54, 0))}.sm\:focus\:from-orange-600:focus{--gradient-from-color:#dd6b20;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(221, 107, 32, 0))}.sm\:focus\:from-orange-700:focus{--gradient-from-color:#c05621;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(192, 86, 33, 0))}.sm\:focus\:from-orange-800:focus{--gradient-from-color:#9c4221;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(156, 66, 33, 0))}.sm\:focus\:from-orange-900:focus{--gradient-from-color:#7b341e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(123, 52, 30, 0))}.sm\:focus\:from-yellow-100:focus{--gradient-from-color:#fffff0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 255, 240, 0))}.sm\:focus\:from-yellow-200:focus{--gradient-from-color:#fefcbf;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(254, 252, 191, 0))}.sm\:focus\:from-yellow-300:focus{--gradient-from-color:#faf089;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(250, 240, 137, 0))}.sm\:focus\:from-yellow-400:focus{--gradient-from-color:#f6e05e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(246, 224, 94, 0))}.sm\:focus\:from-yellow-500:focus{--gradient-from-color:#ecc94b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(236, 201, 75, 0))}.sm\:focus\:from-yellow-600:focus{--gradient-from-color:#d69e2e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(214, 158, 46, 0))}.sm\:focus\:from-yellow-700:focus{--gradient-from-color:#b7791f;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(183, 121, 31, 0))}.sm\:focus\:from-yellow-800:focus{--gradient-from-color:#975a16;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(151, 90, 22, 0))}.sm\:focus\:from-yellow-900:focus{--gradient-from-color:#744210;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(116, 66, 16, 0))}.sm\:focus\:from-green-100:focus{--gradient-from-color:#f0fff4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(240, 255, 244, 0))}.sm\:focus\:from-green-200:focus{--gradient-from-color:#c6f6d5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(198, 246, 213, 0))}.sm\:focus\:from-green-300:focus{--gradient-from-color:#9ae6b4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(154, 230, 180, 0))}.sm\:focus\:from-green-400:focus{--gradient-from-color:#68d391;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(104, 211, 145, 0))}.sm\:focus\:from-green-500:focus{--gradient-from-color:#48bb78;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(72, 187, 120, 0))}.sm\:focus\:from-green-600:focus{--gradient-from-color:#38a169;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(56, 161, 105, 0))}.sm\:focus\:from-green-700:focus{--gradient-from-color:#2f855a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(47, 133, 90, 0))}.sm\:focus\:from-green-800:focus{--gradient-from-color:#276749;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(39, 103, 73, 0))}.sm\:focus\:from-green-900:focus{--gradient-from-color:#22543d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(34, 84, 61, 0))}.sm\:focus\:from-teal-100:focus{--gradient-from-color:#e6fffa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(230, 255, 250, 0))}.sm\:focus\:from-teal-200:focus{--gradient-from-color:#b2f5ea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(178, 245, 234, 0))}.sm\:focus\:from-teal-300:focus{--gradient-from-color:#81e6d9;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(129, 230, 217, 0))}.sm\:focus\:from-teal-400:focus{--gradient-from-color:#4fd1c5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(79, 209, 197, 0))}.sm\:focus\:from-teal-500:focus{--gradient-from-color:#38b2ac;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(56, 178, 172, 0))}.sm\:focus\:from-teal-600:focus{--gradient-from-color:#319795;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(49, 151, 149, 0))}.sm\:focus\:from-teal-700:focus{--gradient-from-color:#2c7a7b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(44, 122, 123, 0))}.sm\:focus\:from-teal-800:focus{--gradient-from-color:#285e61;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(40, 94, 97, 0))}.sm\:focus\:from-teal-900:focus{--gradient-from-color:#234e52;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(35, 78, 82, 0))}.sm\:focus\:from-blue-100:focus{--gradient-from-color:#ebf8ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(235, 248, 255, 0))}.sm\:focus\:from-blue-200:focus{--gradient-from-color:#bee3f8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(190, 227, 248, 0))}.sm\:focus\:from-blue-300:focus{--gradient-from-color:#90cdf4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(144, 205, 244, 0))}.sm\:focus\:from-blue-400:focus{--gradient-from-color:#63b3ed;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(99, 179, 237, 0))}.sm\:focus\:from-blue-500:focus{--gradient-from-color:#4299e1;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(66, 153, 225, 0))}.sm\:focus\:from-blue-600:focus{--gradient-from-color:#3182ce;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(49, 130, 206, 0))}.sm\:focus\:from-blue-700:focus{--gradient-from-color:#2b6cb0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(43, 108, 176, 0))}.sm\:focus\:from-blue-800:focus{--gradient-from-color:#2c5282;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(44, 82, 130, 0))}.sm\:focus\:from-blue-900:focus{--gradient-from-color:#2a4365;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(42, 67, 101, 0))}.sm\:focus\:from-indigo-100:focus{--gradient-from-color:#ebf4ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(235, 244, 255, 0))}.sm\:focus\:from-indigo-200:focus{--gradient-from-color:#c3dafe;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(195, 218, 254, 0))}.sm\:focus\:from-indigo-300:focus{--gradient-from-color:#a3bffa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(163, 191, 250, 0))}.sm\:focus\:from-indigo-400:focus{--gradient-from-color:#7f9cf5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(127, 156, 245, 0))}.sm\:focus\:from-indigo-500:focus{--gradient-from-color:#667eea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(102, 126, 234, 0))}.sm\:focus\:from-indigo-600:focus{--gradient-from-color:#5a67d8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(90, 103, 216, 0))}.sm\:focus\:from-indigo-700:focus{--gradient-from-color:#4c51bf;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(76, 81, 191, 0))}.sm\:focus\:from-indigo-800:focus{--gradient-from-color:#434190;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(67, 65, 144, 0))}.sm\:focus\:from-indigo-900:focus{--gradient-from-color:#3c366b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(60, 54, 107, 0))}.sm\:focus\:from-purple-100:focus{--gradient-from-color:#faf5ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(250, 245, 255, 0))}.sm\:focus\:from-purple-200:focus{--gradient-from-color:#e9d8fd;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(233, 216, 253, 0))}.sm\:focus\:from-purple-300:focus{--gradient-from-color:#d6bcfa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(214, 188, 250, 0))}.sm\:focus\:from-purple-400:focus{--gradient-from-color:#b794f4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(183, 148, 244, 0))}.sm\:focus\:from-purple-500:focus{--gradient-from-color:#9f7aea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(159, 122, 234, 0))}.sm\:focus\:from-purple-600:focus{--gradient-from-color:#805ad5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(128, 90, 213, 0))}.sm\:focus\:from-purple-700:focus{--gradient-from-color:#6b46c1;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(107, 70, 193, 0))}.sm\:focus\:from-purple-800:focus{--gradient-from-color:#553c9a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(85, 60, 154, 0))}.sm\:focus\:from-purple-900:focus{--gradient-from-color:#44337a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(68, 51, 122, 0))}.sm\:focus\:from-pink-100:focus{--gradient-from-color:#fff5f7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 245, 247, 0))}.sm\:focus\:from-pink-200:focus{--gradient-from-color:#fed7e2;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(254, 215, 226, 0))}.sm\:focus\:from-pink-300:focus{--gradient-from-color:#fbb6ce;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(251, 182, 206, 0))}.sm\:focus\:from-pink-400:focus{--gradient-from-color:#f687b3;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(246, 135, 179, 0))}.sm\:focus\:from-pink-500:focus{--gradient-from-color:#ed64a6;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(237, 100, 166, 0))}.sm\:focus\:from-pink-600:focus{--gradient-from-color:#d53f8c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(213, 63, 140, 0))}.sm\:focus\:from-pink-700:focus{--gradient-from-color:#b83280;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(184, 50, 128, 0))}.sm\:focus\:from-pink-800:focus{--gradient-from-color:#97266d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(151, 38, 109, 0))}.sm\:focus\:from-pink-900:focus{--gradient-from-color:#702459;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(112, 36, 89, 0))}.sm\:focus\:via-transparent:focus{--gradient-via-color:transparent;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(0, 0, 0, 0))}.sm\:focus\:via-current:focus{--gradient-via-color:currentColor;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 255, 255, 0))}.sm\:focus\:via-black:focus{--gradient-via-color:#000;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(0, 0, 0, 0))}.sm\:focus\:via-white:focus{--gradient-via-color:#fff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 255, 255, 0))}.sm\:focus\:via-gray-100:focus{--gradient-via-color:#f7fafc;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(247, 250, 252, 0))}.sm\:focus\:via-gray-200:focus{--gradient-via-color:#edf2f7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(237, 242, 247, 0))}.sm\:focus\:via-gray-300:focus{--gradient-via-color:#e2e8f0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(226, 232, 240, 0))}.sm\:focus\:via-gray-400:focus{--gradient-via-color:#cbd5e0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(203, 213, 224, 0))}.sm\:focus\:via-gray-500:focus{--gradient-via-color:#a0aec0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(160, 174, 192, 0))}.sm\:focus\:via-gray-600:focus{--gradient-via-color:#718096;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(113, 128, 150, 0))}.sm\:focus\:via-gray-700:focus{--gradient-via-color:#4a5568;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(74, 85, 104, 0))}.sm\:focus\:via-gray-800:focus{--gradient-via-color:#2d3748;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(45, 55, 72, 0))}.sm\:focus\:via-gray-900:focus{--gradient-via-color:#1a202c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(26, 32, 44, 0))}.sm\:focus\:via-red-100:focus{--gradient-via-color:#fff5f5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 245, 245, 0))}.sm\:focus\:via-red-200:focus{--gradient-via-color:#fed7d7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(254, 215, 215, 0))}.sm\:focus\:via-red-300:focus{--gradient-via-color:#feb2b2;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(254, 178, 178, 0))}.sm\:focus\:via-red-400:focus{--gradient-via-color:#fc8181;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(252, 129, 129, 0))}.sm\:focus\:via-red-500:focus{--gradient-via-color:#f56565;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(245, 101, 101, 0))}.sm\:focus\:via-red-600:focus{--gradient-via-color:#e53e3e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(229, 62, 62, 0))}.sm\:focus\:via-red-700:focus{--gradient-via-color:#c53030;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(197, 48, 48, 0))}.sm\:focus\:via-red-800:focus{--gradient-via-color:#9b2c2c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(155, 44, 44, 0))}.sm\:focus\:via-red-900:focus{--gradient-via-color:#742a2a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(116, 42, 42, 0))}.sm\:focus\:via-orange-100:focus{--gradient-via-color:#fffaf0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 250, 240, 0))}.sm\:focus\:via-orange-200:focus{--gradient-via-color:#feebc8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(254, 235, 200, 0))}.sm\:focus\:via-orange-300:focus{--gradient-via-color:#fbd38d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(251, 211, 141, 0))}.sm\:focus\:via-orange-400:focus{--gradient-via-color:#f6ad55;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(246, 173, 85, 0))}.sm\:focus\:via-orange-500:focus{--gradient-via-color:#ed8936;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(237, 137, 54, 0))}.sm\:focus\:via-orange-600:focus{--gradient-via-color:#dd6b20;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(221, 107, 32, 0))}.sm\:focus\:via-orange-700:focus{--gradient-via-color:#c05621;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(192, 86, 33, 0))}.sm\:focus\:via-orange-800:focus{--gradient-via-color:#9c4221;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(156, 66, 33, 0))}.sm\:focus\:via-orange-900:focus{--gradient-via-color:#7b341e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(123, 52, 30, 0))}.sm\:focus\:via-yellow-100:focus{--gradient-via-color:#fffff0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 255, 240, 0))}.sm\:focus\:via-yellow-200:focus{--gradient-via-color:#fefcbf;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(254, 252, 191, 0))}.sm\:focus\:via-yellow-300:focus{--gradient-via-color:#faf089;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(250, 240, 137, 0))}.sm\:focus\:via-yellow-400:focus{--gradient-via-color:#f6e05e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(246, 224, 94, 0))}.sm\:focus\:via-yellow-500:focus{--gradient-via-color:#ecc94b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(236, 201, 75, 0))}.sm\:focus\:via-yellow-600:focus{--gradient-via-color:#d69e2e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(214, 158, 46, 0))}.sm\:focus\:via-yellow-700:focus{--gradient-via-color:#b7791f;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(183, 121, 31, 0))}.sm\:focus\:via-yellow-800:focus{--gradient-via-color:#975a16;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(151, 90, 22, 0))}.sm\:focus\:via-yellow-900:focus{--gradient-via-color:#744210;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(116, 66, 16, 0))}.sm\:focus\:via-green-100:focus{--gradient-via-color:#f0fff4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(240, 255, 244, 0))}.sm\:focus\:via-green-200:focus{--gradient-via-color:#c6f6d5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(198, 246, 213, 0))}.sm\:focus\:via-green-300:focus{--gradient-via-color:#9ae6b4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(154, 230, 180, 0))}.sm\:focus\:via-green-400:focus{--gradient-via-color:#68d391;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(104, 211, 145, 0))}.sm\:focus\:via-green-500:focus{--gradient-via-color:#48bb78;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(72, 187, 120, 0))}.sm\:focus\:via-green-600:focus{--gradient-via-color:#38a169;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(56, 161, 105, 0))}.sm\:focus\:via-green-700:focus{--gradient-via-color:#2f855a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(47, 133, 90, 0))}.sm\:focus\:via-green-800:focus{--gradient-via-color:#276749;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(39, 103, 73, 0))}.sm\:focus\:via-green-900:focus{--gradient-via-color:#22543d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(34, 84, 61, 0))}.sm\:focus\:via-teal-100:focus{--gradient-via-color:#e6fffa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(230, 255, 250, 0))}.sm\:focus\:via-teal-200:focus{--gradient-via-color:#b2f5ea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(178, 245, 234, 0))}.sm\:focus\:via-teal-300:focus{--gradient-via-color:#81e6d9;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(129, 230, 217, 0))}.sm\:focus\:via-teal-400:focus{--gradient-via-color:#4fd1c5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(79, 209, 197, 0))}.sm\:focus\:via-teal-500:focus{--gradient-via-color:#38b2ac;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(56, 178, 172, 0))}.sm\:focus\:via-teal-600:focus{--gradient-via-color:#319795;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(49, 151, 149, 0))}.sm\:focus\:via-teal-700:focus{--gradient-via-color:#2c7a7b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(44, 122, 123, 0))}.sm\:focus\:via-teal-800:focus{--gradient-via-color:#285e61;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(40, 94, 97, 0))}.sm\:focus\:via-teal-900:focus{--gradient-via-color:#234e52;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(35, 78, 82, 0))}.sm\:focus\:via-blue-100:focus{--gradient-via-color:#ebf8ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(235, 248, 255, 0))}.sm\:focus\:via-blue-200:focus{--gradient-via-color:#bee3f8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(190, 227, 248, 0))}.sm\:focus\:via-blue-300:focus{--gradient-via-color:#90cdf4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(144, 205, 244, 0))}.sm\:focus\:via-blue-400:focus{--gradient-via-color:#63b3ed;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(99, 179, 237, 0))}.sm\:focus\:via-blue-500:focus{--gradient-via-color:#4299e1;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(66, 153, 225, 0))}.sm\:focus\:via-blue-600:focus{--gradient-via-color:#3182ce;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(49, 130, 206, 0))}.sm\:focus\:via-blue-700:focus{--gradient-via-color:#2b6cb0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(43, 108, 176, 0))}.sm\:focus\:via-blue-800:focus{--gradient-via-color:#2c5282;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(44, 82, 130, 0))}.sm\:focus\:via-blue-900:focus{--gradient-via-color:#2a4365;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(42, 67, 101, 0))}.sm\:focus\:via-indigo-100:focus{--gradient-via-color:#ebf4ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(235, 244, 255, 0))}.sm\:focus\:via-indigo-200:focus{--gradient-via-color:#c3dafe;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(195, 218, 254, 0))}.sm\:focus\:via-indigo-300:focus{--gradient-via-color:#a3bffa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(163, 191, 250, 0))}.sm\:focus\:via-indigo-400:focus{--gradient-via-color:#7f9cf5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(127, 156, 245, 0))}.sm\:focus\:via-indigo-500:focus{--gradient-via-color:#667eea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(102, 126, 234, 0))}.sm\:focus\:via-indigo-600:focus{--gradient-via-color:#5a67d8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(90, 103, 216, 0))}.sm\:focus\:via-indigo-700:focus{--gradient-via-color:#4c51bf;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(76, 81, 191, 0))}.sm\:focus\:via-indigo-800:focus{--gradient-via-color:#434190;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(67, 65, 144, 0))}.sm\:focus\:via-indigo-900:focus{--gradient-via-color:#3c366b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(60, 54, 107, 0))}.sm\:focus\:via-purple-100:focus{--gradient-via-color:#faf5ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(250, 245, 255, 0))}.sm\:focus\:via-purple-200:focus{--gradient-via-color:#e9d8fd;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(233, 216, 253, 0))}.sm\:focus\:via-purple-300:focus{--gradient-via-color:#d6bcfa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(214, 188, 250, 0))}.sm\:focus\:via-purple-400:focus{--gradient-via-color:#b794f4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(183, 148, 244, 0))}.sm\:focus\:via-purple-500:focus{--gradient-via-color:#9f7aea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(159, 122, 234, 0))}.sm\:focus\:via-purple-600:focus{--gradient-via-color:#805ad5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(128, 90, 213, 0))}.sm\:focus\:via-purple-700:focus{--gradient-via-color:#6b46c1;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(107, 70, 193, 0))}.sm\:focus\:via-purple-800:focus{--gradient-via-color:#553c9a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(85, 60, 154, 0))}.sm\:focus\:via-purple-900:focus{--gradient-via-color:#44337a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(68, 51, 122, 0))}.sm\:focus\:via-pink-100:focus{--gradient-via-color:#fff5f7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 245, 247, 0))}.sm\:focus\:via-pink-200:focus{--gradient-via-color:#fed7e2;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(254, 215, 226, 0))}.sm\:focus\:via-pink-300:focus{--gradient-via-color:#fbb6ce;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(251, 182, 206, 0))}.sm\:focus\:via-pink-400:focus{--gradient-via-color:#f687b3;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(246, 135, 179, 0))}.sm\:focus\:via-pink-500:focus{--gradient-via-color:#ed64a6;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(237, 100, 166, 0))}.sm\:focus\:via-pink-600:focus{--gradient-via-color:#d53f8c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(213, 63, 140, 0))}.sm\:focus\:via-pink-700:focus{--gradient-via-color:#b83280;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(184, 50, 128, 0))}.sm\:focus\:via-pink-800:focus{--gradient-via-color:#97266d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(151, 38, 109, 0))}.sm\:focus\:via-pink-900:focus{--gradient-via-color:#702459;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(112, 36, 89, 0))}.sm\:focus\:to-transparent:focus{--gradient-to-color:transparent}.sm\:focus\:to-current:focus{--gradient-to-color:currentColor}.sm\:focus\:to-black:focus{--gradient-to-color:#000}.sm\:focus\:to-white:focus{--gradient-to-color:#fff}.sm\:focus\:to-gray-100:focus{--gradient-to-color:#f7fafc}.sm\:focus\:to-gray-200:focus{--gradient-to-color:#edf2f7}.sm\:focus\:to-gray-300:focus{--gradient-to-color:#e2e8f0}.sm\:focus\:to-gray-400:focus{--gradient-to-color:#cbd5e0}.sm\:focus\:to-gray-500:focus{--gradient-to-color:#a0aec0}.sm\:focus\:to-gray-600:focus{--gradient-to-color:#718096}.sm\:focus\:to-gray-700:focus{--gradient-to-color:#4a5568}.sm\:focus\:to-gray-800:focus{--gradient-to-color:#2d3748}.sm\:focus\:to-gray-900:focus{--gradient-to-color:#1a202c}.sm\:focus\:to-red-100:focus{--gradient-to-color:#fff5f5}.sm\:focus\:to-red-200:focus{--gradient-to-color:#fed7d7}.sm\:focus\:to-red-300:focus{--gradient-to-color:#feb2b2}.sm\:focus\:to-red-400:focus{--gradient-to-color:#fc8181}.sm\:focus\:to-red-500:focus{--gradient-to-color:#f56565}.sm\:focus\:to-red-600:focus{--gradient-to-color:#e53e3e}.sm\:focus\:to-red-700:focus{--gradient-to-color:#c53030}.sm\:focus\:to-red-800:focus{--gradient-to-color:#9b2c2c}.sm\:focus\:to-red-900:focus{--gradient-to-color:#742a2a}.sm\:focus\:to-orange-100:focus{--gradient-to-color:#fffaf0}.sm\:focus\:to-orange-200:focus{--gradient-to-color:#feebc8}.sm\:focus\:to-orange-300:focus{--gradient-to-color:#fbd38d}.sm\:focus\:to-orange-400:focus{--gradient-to-color:#f6ad55}.sm\:focus\:to-orange-500:focus{--gradient-to-color:#ed8936}.sm\:focus\:to-orange-600:focus{--gradient-to-color:#dd6b20}.sm\:focus\:to-orange-700:focus{--gradient-to-color:#c05621}.sm\:focus\:to-orange-800:focus{--gradient-to-color:#9c4221}.sm\:focus\:to-orange-900:focus{--gradient-to-color:#7b341e}.sm\:focus\:to-yellow-100:focus{--gradient-to-color:#fffff0}.sm\:focus\:to-yellow-200:focus{--gradient-to-color:#fefcbf}.sm\:focus\:to-yellow-300:focus{--gradient-to-color:#faf089}.sm\:focus\:to-yellow-400:focus{--gradient-to-color:#f6e05e}.sm\:focus\:to-yellow-500:focus{--gradient-to-color:#ecc94b}.sm\:focus\:to-yellow-600:focus{--gradient-to-color:#d69e2e}.sm\:focus\:to-yellow-700:focus{--gradient-to-color:#b7791f}.sm\:focus\:to-yellow-800:focus{--gradient-to-color:#975a16}.sm\:focus\:to-yellow-900:focus{--gradient-to-color:#744210}.sm\:focus\:to-green-100:focus{--gradient-to-color:#f0fff4}.sm\:focus\:to-green-200:focus{--gradient-to-color:#c6f6d5}.sm\:focus\:to-green-300:focus{--gradient-to-color:#9ae6b4}.sm\:focus\:to-green-400:focus{--gradient-to-color:#68d391}.sm\:focus\:to-green-500:focus{--gradient-to-color:#48bb78}.sm\:focus\:to-green-600:focus{--gradient-to-color:#38a169}.sm\:focus\:to-green-700:focus{--gradient-to-color:#2f855a}.sm\:focus\:to-green-800:focus{--gradient-to-color:#276749}.sm\:focus\:to-green-900:focus{--gradient-to-color:#22543d}.sm\:focus\:to-teal-100:focus{--gradient-to-color:#e6fffa}.sm\:focus\:to-teal-200:focus{--gradient-to-color:#b2f5ea}.sm\:focus\:to-teal-300:focus{--gradient-to-color:#81e6d9}.sm\:focus\:to-teal-400:focus{--gradient-to-color:#4fd1c5}.sm\:focus\:to-teal-500:focus{--gradient-to-color:#38b2ac}.sm\:focus\:to-teal-600:focus{--gradient-to-color:#319795}.sm\:focus\:to-teal-700:focus{--gradient-to-color:#2c7a7b}.sm\:focus\:to-teal-800:focus{--gradient-to-color:#285e61}.sm\:focus\:to-teal-900:focus{--gradient-to-color:#234e52}.sm\:focus\:to-blue-100:focus{--gradient-to-color:#ebf8ff}.sm\:focus\:to-blue-200:focus{--gradient-to-color:#bee3f8}.sm\:focus\:to-blue-300:focus{--gradient-to-color:#90cdf4}.sm\:focus\:to-blue-400:focus{--gradient-to-color:#63b3ed}.sm\:focus\:to-blue-500:focus{--gradient-to-color:#4299e1}.sm\:focus\:to-blue-600:focus{--gradient-to-color:#3182ce}.sm\:focus\:to-blue-700:focus{--gradient-to-color:#2b6cb0}.sm\:focus\:to-blue-800:focus{--gradient-to-color:#2c5282}.sm\:focus\:to-blue-900:focus{--gradient-to-color:#2a4365}.sm\:focus\:to-indigo-100:focus{--gradient-to-color:#ebf4ff}.sm\:focus\:to-indigo-200:focus{--gradient-to-color:#c3dafe}.sm\:focus\:to-indigo-300:focus{--gradient-to-color:#a3bffa}.sm\:focus\:to-indigo-400:focus{--gradient-to-color:#7f9cf5}.sm\:focus\:to-indigo-500:focus{--gradient-to-color:#667eea}.sm\:focus\:to-indigo-600:focus{--gradient-to-color:#5a67d8}.sm\:focus\:to-indigo-700:focus{--gradient-to-color:#4c51bf}.sm\:focus\:to-indigo-800:focus{--gradient-to-color:#434190}.sm\:focus\:to-indigo-900:focus{--gradient-to-color:#3c366b}.sm\:focus\:to-purple-100:focus{--gradient-to-color:#faf5ff}.sm\:focus\:to-purple-200:focus{--gradient-to-color:#e9d8fd}.sm\:focus\:to-purple-300:focus{--gradient-to-color:#d6bcfa}.sm\:focus\:to-purple-400:focus{--gradient-to-color:#b794f4}.sm\:focus\:to-purple-500:focus{--gradient-to-color:#9f7aea}.sm\:focus\:to-purple-600:focus{--gradient-to-color:#805ad5}.sm\:focus\:to-purple-700:focus{--gradient-to-color:#6b46c1}.sm\:focus\:to-purple-800:focus{--gradient-to-color:#553c9a}.sm\:focus\:to-purple-900:focus{--gradient-to-color:#44337a}.sm\:focus\:to-pink-100:focus{--gradient-to-color:#fff5f7}.sm\:focus\:to-pink-200:focus{--gradient-to-color:#fed7e2}.sm\:focus\:to-pink-300:focus{--gradient-to-color:#fbb6ce}.sm\:focus\:to-pink-400:focus{--gradient-to-color:#f687b3}.sm\:focus\:to-pink-500:focus{--gradient-to-color:#ed64a6}.sm\:focus\:to-pink-600:focus{--gradient-to-color:#d53f8c}.sm\:focus\:to-pink-700:focus{--gradient-to-color:#b83280}.sm\:focus\:to-pink-800:focus{--gradient-to-color:#97266d}.sm\:focus\:to-pink-900:focus{--gradient-to-color:#702459}.sm\:bg-opacity-0{--bg-opacity:0}.sm\:bg-opacity-25{--bg-opacity:0.25}.sm\:bg-opacity-50{--bg-opacity:0.5}.sm\:bg-opacity-75{--bg-opacity:0.75}.sm\:bg-opacity-100{--bg-opacity:1}.sm\:hover\:bg-opacity-0:hover{--bg-opacity:0}.sm\:hover\:bg-opacity-25:hover{--bg-opacity:0.25}.sm\:hover\:bg-opacity-50:hover{--bg-opacity:0.5}.sm\:hover\:bg-opacity-75:hover{--bg-opacity:0.75}.sm\:hover\:bg-opacity-100:hover{--bg-opacity:1}.sm\:focus\:bg-opacity-0:focus{--bg-opacity:0}.sm\:focus\:bg-opacity-25:focus{--bg-opacity:0.25}.sm\:focus\:bg-opacity-50:focus{--bg-opacity:0.5}.sm\:focus\:bg-opacity-75:focus{--bg-opacity:0.75}.sm\:focus\:bg-opacity-100:focus{--bg-opacity:1}.sm\:bg-bottom{background-position:bottom}.sm\:bg-center{background-position:center}.sm\:bg-left{background-position:left}.sm\:bg-left-bottom{background-position:left bottom}.sm\:bg-left-top{background-position:left top}.sm\:bg-right{background-position:right}.sm\:bg-right-bottom{background-position:right bottom}.sm\:bg-right-top{background-position:right top}.sm\:bg-top{background-position:top}.sm\:bg-repeat{background-repeat:repeat}.sm\:bg-no-repeat{background-repeat:no-repeat}.sm\:bg-repeat-x{background-repeat:repeat-x}.sm\:bg-repeat-y{background-repeat:repeat-y}.sm\:bg-repeat-round{background-repeat:round}.sm\:bg-repeat-space{background-repeat:space}.sm\:bg-auto{background-size:auto}.sm\:bg-cover{background-size:cover}.sm\:bg-contain{background-size:contain}.sm\:border-collapse{border-collapse:collapse}.sm\:border-separate{border-collapse:separate}.sm\:border-transparent{border-color:transparent}.sm\:border-current{border-color:currentColor}.sm\:border-black{--border-opacity:1;border-color:#000;border-color:rgba(0,0,0,var(--border-opacity))}.sm\:border-white{--border-opacity:1;border-color:#fff;border-color:rgba(255,255,255,var(--border-opacity))}.sm\:border-gray-100{--border-opacity:1;border-color:#f7fafc;border-color:rgba(247,250,252,var(--border-opacity))}.sm\:border-gray-200{--border-opacity:1;border-color:#edf2f7;border-color:rgba(237,242,247,var(--border-opacity))}.sm\:border-gray-300{--border-opacity:1;border-color:#e2e8f0;border-color:rgba(226,232,240,var(--border-opacity))}.sm\:border-gray-400{--border-opacity:1;border-color:#cbd5e0;border-color:rgba(203,213,224,var(--border-opacity))}.sm\:border-gray-500{--border-opacity:1;border-color:#a0aec0;border-color:rgba(160,174,192,var(--border-opacity))}.sm\:border-gray-600{--border-opacity:1;border-color:#718096;border-color:rgba(113,128,150,var(--border-opacity))}.sm\:border-gray-700{--border-opacity:1;border-color:#4a5568;border-color:rgba(74,85,104,var(--border-opacity))}.sm\:border-gray-800{--border-opacity:1;border-color:#2d3748;border-color:rgba(45,55,72,var(--border-opacity))}.sm\:border-gray-900{--border-opacity:1;border-color:#1a202c;border-color:rgba(26,32,44,var(--border-opacity))}.sm\:border-red-100{--border-opacity:1;border-color:#fff5f5;border-color:rgba(255,245,245,var(--border-opacity))}.sm\:border-red-200{--border-opacity:1;border-color:#fed7d7;border-color:rgba(254,215,215,var(--border-opacity))}.sm\:border-red-300{--border-opacity:1;border-color:#feb2b2;border-color:rgba(254,178,178,var(--border-opacity))}.sm\:border-red-400{--border-opacity:1;border-color:#fc8181;border-color:rgba(252,129,129,var(--border-opacity))}.sm\:border-red-500{--border-opacity:1;border-color:#f56565;border-color:rgba(245,101,101,var(--border-opacity))}.sm\:border-red-600{--border-opacity:1;border-color:#e53e3e;border-color:rgba(229,62,62,var(--border-opacity))}.sm\:border-red-700{--border-opacity:1;border-color:#c53030;border-color:rgba(197,48,48,var(--border-opacity))}.sm\:border-red-800{--border-opacity:1;border-color:#9b2c2c;border-color:rgba(155,44,44,var(--border-opacity))}.sm\:border-red-900{--border-opacity:1;border-color:#742a2a;border-color:rgba(116,42,42,var(--border-opacity))}.sm\:border-orange-100{--border-opacity:1;border-color:#fffaf0;border-color:rgba(255,250,240,var(--border-opacity))}.sm\:border-orange-200{--border-opacity:1;border-color:#feebc8;border-color:rgba(254,235,200,var(--border-opacity))}.sm\:border-orange-300{--border-opacity:1;border-color:#fbd38d;border-color:rgba(251,211,141,var(--border-opacity))}.sm\:border-orange-400{--border-opacity:1;border-color:#f6ad55;border-color:rgba(246,173,85,var(--border-opacity))}.sm\:border-orange-500{--border-opacity:1;border-color:#ed8936;border-color:rgba(237,137,54,var(--border-opacity))}.sm\:border-orange-600{--border-opacity:1;border-color:#dd6b20;border-color:rgba(221,107,32,var(--border-opacity))}.sm\:border-orange-700{--border-opacity:1;border-color:#c05621;border-color:rgba(192,86,33,var(--border-opacity))}.sm\:border-orange-800{--border-opacity:1;border-color:#9c4221;border-color:rgba(156,66,33,var(--border-opacity))}.sm\:border-orange-900{--border-opacity:1;border-color:#7b341e;border-color:rgba(123,52,30,var(--border-opacity))}.sm\:border-yellow-100{--border-opacity:1;border-color:ivory;border-color:rgba(255,255,240,var(--border-opacity))}.sm\:border-yellow-200{--border-opacity:1;border-color:#fefcbf;border-color:rgba(254,252,191,var(--border-opacity))}.sm\:border-yellow-300{--border-opacity:1;border-color:#faf089;border-color:rgba(250,240,137,var(--border-opacity))}.sm\:border-yellow-400{--border-opacity:1;border-color:#f6e05e;border-color:rgba(246,224,94,var(--border-opacity))}.sm\:border-yellow-500{--border-opacity:1;border-color:#ecc94b;border-color:rgba(236,201,75,var(--border-opacity))}.sm\:border-yellow-600{--border-opacity:1;border-color:#d69e2e;border-color:rgba(214,158,46,var(--border-opacity))}.sm\:border-yellow-700{--border-opacity:1;border-color:#b7791f;border-color:rgba(183,121,31,var(--border-opacity))}.sm\:border-yellow-800{--border-opacity:1;border-color:#975a16;border-color:rgba(151,90,22,var(--border-opacity))}.sm\:border-yellow-900{--border-opacity:1;border-color:#744210;border-color:rgba(116,66,16,var(--border-opacity))}.sm\:border-green-100{--border-opacity:1;border-color:#f0fff4;border-color:rgba(240,255,244,var(--border-opacity))}.sm\:border-green-200{--border-opacity:1;border-color:#c6f6d5;border-color:rgba(198,246,213,var(--border-opacity))}.sm\:border-green-300{--border-opacity:1;border-color:#9ae6b4;border-color:rgba(154,230,180,var(--border-opacity))}.sm\:border-green-400{--border-opacity:1;border-color:#68d391;border-color:rgba(104,211,145,var(--border-opacity))}.sm\:border-green-500{--border-opacity:1;border-color:#48bb78;border-color:rgba(72,187,120,var(--border-opacity))}.sm\:border-green-600{--border-opacity:1;border-color:#38a169;border-color:rgba(56,161,105,var(--border-opacity))}.sm\:border-green-700{--border-opacity:1;border-color:#2f855a;border-color:rgba(47,133,90,var(--border-opacity))}.sm\:border-green-800{--border-opacity:1;border-color:#276749;border-color:rgba(39,103,73,var(--border-opacity))}.sm\:border-green-900{--border-opacity:1;border-color:#22543d;border-color:rgba(34,84,61,var(--border-opacity))}.sm\:border-teal-100{--border-opacity:1;border-color:#e6fffa;border-color:rgba(230,255,250,var(--border-opacity))}.sm\:border-teal-200{--border-opacity:1;border-color:#b2f5ea;border-color:rgba(178,245,234,var(--border-opacity))}.sm\:border-teal-300{--border-opacity:1;border-color:#81e6d9;border-color:rgba(129,230,217,var(--border-opacity))}.sm\:border-teal-400{--border-opacity:1;border-color:#4fd1c5;border-color:rgba(79,209,197,var(--border-opacity))}.sm\:border-teal-500{--border-opacity:1;border-color:#38b2ac;border-color:rgba(56,178,172,var(--border-opacity))}.sm\:border-teal-600{--border-opacity:1;border-color:#319795;border-color:rgba(49,151,149,var(--border-opacity))}.sm\:border-teal-700{--border-opacity:1;border-color:#2c7a7b;border-color:rgba(44,122,123,var(--border-opacity))}.sm\:border-teal-800{--border-opacity:1;border-color:#285e61;border-color:rgba(40,94,97,var(--border-opacity))}.sm\:border-teal-900{--border-opacity:1;border-color:#234e52;border-color:rgba(35,78,82,var(--border-opacity))}.sm\:border-blue-100{--border-opacity:1;border-color:#ebf8ff;border-color:rgba(235,248,255,var(--border-opacity))}.sm\:border-blue-200{--border-opacity:1;border-color:#bee3f8;border-color:rgba(190,227,248,var(--border-opacity))}.sm\:border-blue-300{--border-opacity:1;border-color:#90cdf4;border-color:rgba(144,205,244,var(--border-opacity))}.sm\:border-blue-400{--border-opacity:1;border-color:#63b3ed;border-color:rgba(99,179,237,var(--border-opacity))}.sm\:border-blue-500{--border-opacity:1;border-color:#4299e1;border-color:rgba(66,153,225,var(--border-opacity))}.sm\:border-blue-600{--border-opacity:1;border-color:#3182ce;border-color:rgba(49,130,206,var(--border-opacity))}.sm\:border-blue-700{--border-opacity:1;border-color:#2b6cb0;border-color:rgba(43,108,176,var(--border-opacity))}.sm\:border-blue-800{--border-opacity:1;border-color:#2c5282;border-color:rgba(44,82,130,var(--border-opacity))}.sm\:border-blue-900{--border-opacity:1;border-color:#2a4365;border-color:rgba(42,67,101,var(--border-opacity))}.sm\:border-indigo-100{--border-opacity:1;border-color:#ebf4ff;border-color:rgba(235,244,255,var(--border-opacity))}.sm\:border-indigo-200{--border-opacity:1;border-color:#c3dafe;border-color:rgba(195,218,254,var(--border-opacity))}.sm\:border-indigo-300{--border-opacity:1;border-color:#a3bffa;border-color:rgba(163,191,250,var(--border-opacity))}.sm\:border-indigo-400{--border-opacity:1;border-color:#7f9cf5;border-color:rgba(127,156,245,var(--border-opacity))}.sm\:border-indigo-500{--border-opacity:1;border-color:#667eea;border-color:rgba(102,126,234,var(--border-opacity))}.sm\:border-indigo-600{--border-opacity:1;border-color:#5a67d8;border-color:rgba(90,103,216,var(--border-opacity))}.sm\:border-indigo-700{--border-opacity:1;border-color:#4c51bf;border-color:rgba(76,81,191,var(--border-opacity))}.sm\:border-indigo-800{--border-opacity:1;border-color:#434190;border-color:rgba(67,65,144,var(--border-opacity))}.sm\:border-indigo-900{--border-opacity:1;border-color:#3c366b;border-color:rgba(60,54,107,var(--border-opacity))}.sm\:border-purple-100{--border-opacity:1;border-color:#faf5ff;border-color:rgba(250,245,255,var(--border-opacity))}.sm\:border-purple-200{--border-opacity:1;border-color:#e9d8fd;border-color:rgba(233,216,253,var(--border-opacity))}.sm\:border-purple-300{--border-opacity:1;border-color:#d6bcfa;border-color:rgba(214,188,250,var(--border-opacity))}.sm\:border-purple-400{--border-opacity:1;border-color:#b794f4;border-color:rgba(183,148,244,var(--border-opacity))}.sm\:border-purple-500{--border-opacity:1;border-color:#9f7aea;border-color:rgba(159,122,234,var(--border-opacity))}.sm\:border-purple-600{--border-opacity:1;border-color:#805ad5;border-color:rgba(128,90,213,var(--border-opacity))}.sm\:border-purple-700{--border-opacity:1;border-color:#6b46c1;border-color:rgba(107,70,193,var(--border-opacity))}.sm\:border-purple-800{--border-opacity:1;border-color:#553c9a;border-color:rgba(85,60,154,var(--border-opacity))}.sm\:border-purple-900{--border-opacity:1;border-color:#44337a;border-color:rgba(68,51,122,var(--border-opacity))}.sm\:border-pink-100{--border-opacity:1;border-color:#fff5f7;border-color:rgba(255,245,247,var(--border-opacity))}.sm\:border-pink-200{--border-opacity:1;border-color:#fed7e2;border-color:rgba(254,215,226,var(--border-opacity))}.sm\:border-pink-300{--border-opacity:1;border-color:#fbb6ce;border-color:rgba(251,182,206,var(--border-opacity))}.sm\:border-pink-400{--border-opacity:1;border-color:#f687b3;border-color:rgba(246,135,179,var(--border-opacity))}.sm\:border-pink-500{--border-opacity:1;border-color:#ed64a6;border-color:rgba(237,100,166,var(--border-opacity))}.sm\:border-pink-600{--border-opacity:1;border-color:#d53f8c;border-color:rgba(213,63,140,var(--border-opacity))}.sm\:border-pink-700{--border-opacity:1;border-color:#b83280;border-color:rgba(184,50,128,var(--border-opacity))}.sm\:border-pink-800{--border-opacity:1;border-color:#97266d;border-color:rgba(151,38,109,var(--border-opacity))}.sm\:border-pink-900{--border-opacity:1;border-color:#702459;border-color:rgba(112,36,89,var(--border-opacity))}.sm\:hover\:border-transparent:hover{border-color:transparent}.sm\:hover\:border-current:hover{border-color:currentColor}.sm\:hover\:border-black:hover{--border-opacity:1;border-color:#000;border-color:rgba(0,0,0,var(--border-opacity))}.sm\:hover\:border-white:hover{--border-opacity:1;border-color:#fff;border-color:rgba(255,255,255,var(--border-opacity))}.sm\:hover\:border-gray-100:hover{--border-opacity:1;border-color:#f7fafc;border-color:rgba(247,250,252,var(--border-opacity))}.sm\:hover\:border-gray-200:hover{--border-opacity:1;border-color:#edf2f7;border-color:rgba(237,242,247,var(--border-opacity))}.sm\:hover\:border-gray-300:hover{--border-opacity:1;border-color:#e2e8f0;border-color:rgba(226,232,240,var(--border-opacity))}.sm\:hover\:border-gray-400:hover{--border-opacity:1;border-color:#cbd5e0;border-color:rgba(203,213,224,var(--border-opacity))}.sm\:hover\:border-gray-500:hover{--border-opacity:1;border-color:#a0aec0;border-color:rgba(160,174,192,var(--border-opacity))}.sm\:hover\:border-gray-600:hover{--border-opacity:1;border-color:#718096;border-color:rgba(113,128,150,var(--border-opacity))}.sm\:hover\:border-gray-700:hover{--border-opacity:1;border-color:#4a5568;border-color:rgba(74,85,104,var(--border-opacity))}.sm\:hover\:border-gray-800:hover{--border-opacity:1;border-color:#2d3748;border-color:rgba(45,55,72,var(--border-opacity))}.sm\:hover\:border-gray-900:hover{--border-opacity:1;border-color:#1a202c;border-color:rgba(26,32,44,var(--border-opacity))}.sm\:hover\:border-red-100:hover{--border-opacity:1;border-color:#fff5f5;border-color:rgba(255,245,245,var(--border-opacity))}.sm\:hover\:border-red-200:hover{--border-opacity:1;border-color:#fed7d7;border-color:rgba(254,215,215,var(--border-opacity))}.sm\:hover\:border-red-300:hover{--border-opacity:1;border-color:#feb2b2;border-color:rgba(254,178,178,var(--border-opacity))}.sm\:hover\:border-red-400:hover{--border-opacity:1;border-color:#fc8181;border-color:rgba(252,129,129,var(--border-opacity))}.sm\:hover\:border-red-500:hover{--border-opacity:1;border-color:#f56565;border-color:rgba(245,101,101,var(--border-opacity))}.sm\:hover\:border-red-600:hover{--border-opacity:1;border-color:#e53e3e;border-color:rgba(229,62,62,var(--border-opacity))}.sm\:hover\:border-red-700:hover{--border-opacity:1;border-color:#c53030;border-color:rgba(197,48,48,var(--border-opacity))}.sm\:hover\:border-red-800:hover{--border-opacity:1;border-color:#9b2c2c;border-color:rgba(155,44,44,var(--border-opacity))}.sm\:hover\:border-red-900:hover{--border-opacity:1;border-color:#742a2a;border-color:rgba(116,42,42,var(--border-opacity))}.sm\:hover\:border-orange-100:hover{--border-opacity:1;border-color:#fffaf0;border-color:rgba(255,250,240,var(--border-opacity))}.sm\:hover\:border-orange-200:hover{--border-opacity:1;border-color:#feebc8;border-color:rgba(254,235,200,var(--border-opacity))}.sm\:hover\:border-orange-300:hover{--border-opacity:1;border-color:#fbd38d;border-color:rgba(251,211,141,var(--border-opacity))}.sm\:hover\:border-orange-400:hover{--border-opacity:1;border-color:#f6ad55;border-color:rgba(246,173,85,var(--border-opacity))}.sm\:hover\:border-orange-500:hover{--border-opacity:1;border-color:#ed8936;border-color:rgba(237,137,54,var(--border-opacity))}.sm\:hover\:border-orange-600:hover{--border-opacity:1;border-color:#dd6b20;border-color:rgba(221,107,32,var(--border-opacity))}.sm\:hover\:border-orange-700:hover{--border-opacity:1;border-color:#c05621;border-color:rgba(192,86,33,var(--border-opacity))}.sm\:hover\:border-orange-800:hover{--border-opacity:1;border-color:#9c4221;border-color:rgba(156,66,33,var(--border-opacity))}.sm\:hover\:border-orange-900:hover{--border-opacity:1;border-color:#7b341e;border-color:rgba(123,52,30,var(--border-opacity))}.sm\:hover\:border-yellow-100:hover{--border-opacity:1;border-color:ivory;border-color:rgba(255,255,240,var(--border-opacity))}.sm\:hover\:border-yellow-200:hover{--border-opacity:1;border-color:#fefcbf;border-color:rgba(254,252,191,var(--border-opacity))}.sm\:hover\:border-yellow-300:hover{--border-opacity:1;border-color:#faf089;border-color:rgba(250,240,137,var(--border-opacity))}.sm\:hover\:border-yellow-400:hover{--border-opacity:1;border-color:#f6e05e;border-color:rgba(246,224,94,var(--border-opacity))}.sm\:hover\:border-yellow-500:hover{--border-opacity:1;border-color:#ecc94b;border-color:rgba(236,201,75,var(--border-opacity))}.sm\:hover\:border-yellow-600:hover{--border-opacity:1;border-color:#d69e2e;border-color:rgba(214,158,46,var(--border-opacity))}.sm\:hover\:border-yellow-700:hover{--border-opacity:1;border-color:#b7791f;border-color:rgba(183,121,31,var(--border-opacity))}.sm\:hover\:border-yellow-800:hover{--border-opacity:1;border-color:#975a16;border-color:rgba(151,90,22,var(--border-opacity))}.sm\:hover\:border-yellow-900:hover{--border-opacity:1;border-color:#744210;border-color:rgba(116,66,16,var(--border-opacity))}.sm\:hover\:border-green-100:hover{--border-opacity:1;border-color:#f0fff4;border-color:rgba(240,255,244,var(--border-opacity))}.sm\:hover\:border-green-200:hover{--border-opacity:1;border-color:#c6f6d5;border-color:rgba(198,246,213,var(--border-opacity))}.sm\:hover\:border-green-300:hover{--border-opacity:1;border-color:#9ae6b4;border-color:rgba(154,230,180,var(--border-opacity))}.sm\:hover\:border-green-400:hover{--border-opacity:1;border-color:#68d391;border-color:rgba(104,211,145,var(--border-opacity))}.sm\:hover\:border-green-500:hover{--border-opacity:1;border-color:#48bb78;border-color:rgba(72,187,120,var(--border-opacity))}.sm\:hover\:border-green-600:hover{--border-opacity:1;border-color:#38a169;border-color:rgba(56,161,105,var(--border-opacity))}.sm\:hover\:border-green-700:hover{--border-opacity:1;border-color:#2f855a;border-color:rgba(47,133,90,var(--border-opacity))}.sm\:hover\:border-green-800:hover{--border-opacity:1;border-color:#276749;border-color:rgba(39,103,73,var(--border-opacity))}.sm\:hover\:border-green-900:hover{--border-opacity:1;border-color:#22543d;border-color:rgba(34,84,61,var(--border-opacity))}.sm\:hover\:border-teal-100:hover{--border-opacity:1;border-color:#e6fffa;border-color:rgba(230,255,250,var(--border-opacity))}.sm\:hover\:border-teal-200:hover{--border-opacity:1;border-color:#b2f5ea;border-color:rgba(178,245,234,var(--border-opacity))}.sm\:hover\:border-teal-300:hover{--border-opacity:1;border-color:#81e6d9;border-color:rgba(129,230,217,var(--border-opacity))}.sm\:hover\:border-teal-400:hover{--border-opacity:1;border-color:#4fd1c5;border-color:rgba(79,209,197,var(--border-opacity))}.sm\:hover\:border-teal-500:hover{--border-opacity:1;border-color:#38b2ac;border-color:rgba(56,178,172,var(--border-opacity))}.sm\:hover\:border-teal-600:hover{--border-opacity:1;border-color:#319795;border-color:rgba(49,151,149,var(--border-opacity))}.sm\:hover\:border-teal-700:hover{--border-opacity:1;border-color:#2c7a7b;border-color:rgba(44,122,123,var(--border-opacity))}.sm\:hover\:border-teal-800:hover{--border-opacity:1;border-color:#285e61;border-color:rgba(40,94,97,var(--border-opacity))}.sm\:hover\:border-teal-900:hover{--border-opacity:1;border-color:#234e52;border-color:rgba(35,78,82,var(--border-opacity))}.sm\:hover\:border-blue-100:hover{--border-opacity:1;border-color:#ebf8ff;border-color:rgba(235,248,255,var(--border-opacity))}.sm\:hover\:border-blue-200:hover{--border-opacity:1;border-color:#bee3f8;border-color:rgba(190,227,248,var(--border-opacity))}.sm\:hover\:border-blue-300:hover{--border-opacity:1;border-color:#90cdf4;border-color:rgba(144,205,244,var(--border-opacity))}.sm\:hover\:border-blue-400:hover{--border-opacity:1;border-color:#63b3ed;border-color:rgba(99,179,237,var(--border-opacity))}.sm\:hover\:border-blue-500:hover{--border-opacity:1;border-color:#4299e1;border-color:rgba(66,153,225,var(--border-opacity))}.sm\:hover\:border-blue-600:hover{--border-opacity:1;border-color:#3182ce;border-color:rgba(49,130,206,var(--border-opacity))}.sm\:hover\:border-blue-700:hover{--border-opacity:1;border-color:#2b6cb0;border-color:rgba(43,108,176,var(--border-opacity))}.sm\:hover\:border-blue-800:hover{--border-opacity:1;border-color:#2c5282;border-color:rgba(44,82,130,var(--border-opacity))}.sm\:hover\:border-blue-900:hover{--border-opacity:1;border-color:#2a4365;border-color:rgba(42,67,101,var(--border-opacity))}.sm\:hover\:border-indigo-100:hover{--border-opacity:1;border-color:#ebf4ff;border-color:rgba(235,244,255,var(--border-opacity))}.sm\:hover\:border-indigo-200:hover{--border-opacity:1;border-color:#c3dafe;border-color:rgba(195,218,254,var(--border-opacity))}.sm\:hover\:border-indigo-300:hover{--border-opacity:1;border-color:#a3bffa;border-color:rgba(163,191,250,var(--border-opacity))}.sm\:hover\:border-indigo-400:hover{--border-opacity:1;border-color:#7f9cf5;border-color:rgba(127,156,245,var(--border-opacity))}.sm\:hover\:border-indigo-500:hover{--border-opacity:1;border-color:#667eea;border-color:rgba(102,126,234,var(--border-opacity))}.sm\:hover\:border-indigo-600:hover{--border-opacity:1;border-color:#5a67d8;border-color:rgba(90,103,216,var(--border-opacity))}.sm\:hover\:border-indigo-700:hover{--border-opacity:1;border-color:#4c51bf;border-color:rgba(76,81,191,var(--border-opacity))}.sm\:hover\:border-indigo-800:hover{--border-opacity:1;border-color:#434190;border-color:rgba(67,65,144,var(--border-opacity))}.sm\:hover\:border-indigo-900:hover{--border-opacity:1;border-color:#3c366b;border-color:rgba(60,54,107,var(--border-opacity))}.sm\:hover\:border-purple-100:hover{--border-opacity:1;border-color:#faf5ff;border-color:rgba(250,245,255,var(--border-opacity))}.sm\:hover\:border-purple-200:hover{--border-opacity:1;border-color:#e9d8fd;border-color:rgba(233,216,253,var(--border-opacity))}.sm\:hover\:border-purple-300:hover{--border-opacity:1;border-color:#d6bcfa;border-color:rgba(214,188,250,var(--border-opacity))}.sm\:hover\:border-purple-400:hover{--border-opacity:1;border-color:#b794f4;border-color:rgba(183,148,244,var(--border-opacity))}.sm\:hover\:border-purple-500:hover{--border-opacity:1;border-color:#9f7aea;border-color:rgba(159,122,234,var(--border-opacity))}.sm\:hover\:border-purple-600:hover{--border-opacity:1;border-color:#805ad5;border-color:rgba(128,90,213,var(--border-opacity))}.sm\:hover\:border-purple-700:hover{--border-opacity:1;border-color:#6b46c1;border-color:rgba(107,70,193,var(--border-opacity))}.sm\:hover\:border-purple-800:hover{--border-opacity:1;border-color:#553c9a;border-color:rgba(85,60,154,var(--border-opacity))}.sm\:hover\:border-purple-900:hover{--border-opacity:1;border-color:#44337a;border-color:rgba(68,51,122,var(--border-opacity))}.sm\:hover\:border-pink-100:hover{--border-opacity:1;border-color:#fff5f7;border-color:rgba(255,245,247,var(--border-opacity))}.sm\:hover\:border-pink-200:hover{--border-opacity:1;border-color:#fed7e2;border-color:rgba(254,215,226,var(--border-opacity))}.sm\:hover\:border-pink-300:hover{--border-opacity:1;border-color:#fbb6ce;border-color:rgba(251,182,206,var(--border-opacity))}.sm\:hover\:border-pink-400:hover{--border-opacity:1;border-color:#f687b3;border-color:rgba(246,135,179,var(--border-opacity))}.sm\:hover\:border-pink-500:hover{--border-opacity:1;border-color:#ed64a6;border-color:rgba(237,100,166,var(--border-opacity))}.sm\:hover\:border-pink-600:hover{--border-opacity:1;border-color:#d53f8c;border-color:rgba(213,63,140,var(--border-opacity))}.sm\:hover\:border-pink-700:hover{--border-opacity:1;border-color:#b83280;border-color:rgba(184,50,128,var(--border-opacity))}.sm\:hover\:border-pink-800:hover{--border-opacity:1;border-color:#97266d;border-color:rgba(151,38,109,var(--border-opacity))}.sm\:hover\:border-pink-900:hover{--border-opacity:1;border-color:#702459;border-color:rgba(112,36,89,var(--border-opacity))}.sm\:focus\:border-transparent:focus{border-color:transparent}.sm\:focus\:border-current:focus{border-color:currentColor}.sm\:focus\:border-black:focus{--border-opacity:1;border-color:#000;border-color:rgba(0,0,0,var(--border-opacity))}.sm\:focus\:border-white:focus{--border-opacity:1;border-color:#fff;border-color:rgba(255,255,255,var(--border-opacity))}.sm\:focus\:border-gray-100:focus{--border-opacity:1;border-color:#f7fafc;border-color:rgba(247,250,252,var(--border-opacity))}.sm\:focus\:border-gray-200:focus{--border-opacity:1;border-color:#edf2f7;border-color:rgba(237,242,247,var(--border-opacity))}.sm\:focus\:border-gray-300:focus{--border-opacity:1;border-color:#e2e8f0;border-color:rgba(226,232,240,var(--border-opacity))}.sm\:focus\:border-gray-400:focus{--border-opacity:1;border-color:#cbd5e0;border-color:rgba(203,213,224,var(--border-opacity))}.sm\:focus\:border-gray-500:focus{--border-opacity:1;border-color:#a0aec0;border-color:rgba(160,174,192,var(--border-opacity))}.sm\:focus\:border-gray-600:focus{--border-opacity:1;border-color:#718096;border-color:rgba(113,128,150,var(--border-opacity))}.sm\:focus\:border-gray-700:focus{--border-opacity:1;border-color:#4a5568;border-color:rgba(74,85,104,var(--border-opacity))}.sm\:focus\:border-gray-800:focus{--border-opacity:1;border-color:#2d3748;border-color:rgba(45,55,72,var(--border-opacity))}.sm\:focus\:border-gray-900:focus{--border-opacity:1;border-color:#1a202c;border-color:rgba(26,32,44,var(--border-opacity))}.sm\:focus\:border-red-100:focus{--border-opacity:1;border-color:#fff5f5;border-color:rgba(255,245,245,var(--border-opacity))}.sm\:focus\:border-red-200:focus{--border-opacity:1;border-color:#fed7d7;border-color:rgba(254,215,215,var(--border-opacity))}.sm\:focus\:border-red-300:focus{--border-opacity:1;border-color:#feb2b2;border-color:rgba(254,178,178,var(--border-opacity))}.sm\:focus\:border-red-400:focus{--border-opacity:1;border-color:#fc8181;border-color:rgba(252,129,129,var(--border-opacity))}.sm\:focus\:border-red-500:focus{--border-opacity:1;border-color:#f56565;border-color:rgba(245,101,101,var(--border-opacity))}.sm\:focus\:border-red-600:focus{--border-opacity:1;border-color:#e53e3e;border-color:rgba(229,62,62,var(--border-opacity))}.sm\:focus\:border-red-700:focus{--border-opacity:1;border-color:#c53030;border-color:rgba(197,48,48,var(--border-opacity))}.sm\:focus\:border-red-800:focus{--border-opacity:1;border-color:#9b2c2c;border-color:rgba(155,44,44,var(--border-opacity))}.sm\:focus\:border-red-900:focus{--border-opacity:1;border-color:#742a2a;border-color:rgba(116,42,42,var(--border-opacity))}.sm\:focus\:border-orange-100:focus{--border-opacity:1;border-color:#fffaf0;border-color:rgba(255,250,240,var(--border-opacity))}.sm\:focus\:border-orange-200:focus{--border-opacity:1;border-color:#feebc8;border-color:rgba(254,235,200,var(--border-opacity))}.sm\:focus\:border-orange-300:focus{--border-opacity:1;border-color:#fbd38d;border-color:rgba(251,211,141,var(--border-opacity))}.sm\:focus\:border-orange-400:focus{--border-opacity:1;border-color:#f6ad55;border-color:rgba(246,173,85,var(--border-opacity))}.sm\:focus\:border-orange-500:focus{--border-opacity:1;border-color:#ed8936;border-color:rgba(237,137,54,var(--border-opacity))}.sm\:focus\:border-orange-600:focus{--border-opacity:1;border-color:#dd6b20;border-color:rgba(221,107,32,var(--border-opacity))}.sm\:focus\:border-orange-700:focus{--border-opacity:1;border-color:#c05621;border-color:rgba(192,86,33,var(--border-opacity))}.sm\:focus\:border-orange-800:focus{--border-opacity:1;border-color:#9c4221;border-color:rgba(156,66,33,var(--border-opacity))}.sm\:focus\:border-orange-900:focus{--border-opacity:1;border-color:#7b341e;border-color:rgba(123,52,30,var(--border-opacity))}.sm\:focus\:border-yellow-100:focus{--border-opacity:1;border-color:ivory;border-color:rgba(255,255,240,var(--border-opacity))}.sm\:focus\:border-yellow-200:focus{--border-opacity:1;border-color:#fefcbf;border-color:rgba(254,252,191,var(--border-opacity))}.sm\:focus\:border-yellow-300:focus{--border-opacity:1;border-color:#faf089;border-color:rgba(250,240,137,var(--border-opacity))}.sm\:focus\:border-yellow-400:focus{--border-opacity:1;border-color:#f6e05e;border-color:rgba(246,224,94,var(--border-opacity))}.sm\:focus\:border-yellow-500:focus{--border-opacity:1;border-color:#ecc94b;border-color:rgba(236,201,75,var(--border-opacity))}.sm\:focus\:border-yellow-600:focus{--border-opacity:1;border-color:#d69e2e;border-color:rgba(214,158,46,var(--border-opacity))}.sm\:focus\:border-yellow-700:focus{--border-opacity:1;border-color:#b7791f;border-color:rgba(183,121,31,var(--border-opacity))}.sm\:focus\:border-yellow-800:focus{--border-opacity:1;border-color:#975a16;border-color:rgba(151,90,22,var(--border-opacity))}.sm\:focus\:border-yellow-900:focus{--border-opacity:1;border-color:#744210;border-color:rgba(116,66,16,var(--border-opacity))}.sm\:focus\:border-green-100:focus{--border-opacity:1;border-color:#f0fff4;border-color:rgba(240,255,244,var(--border-opacity))}.sm\:focus\:border-green-200:focus{--border-opacity:1;border-color:#c6f6d5;border-color:rgba(198,246,213,var(--border-opacity))}.sm\:focus\:border-green-300:focus{--border-opacity:1;border-color:#9ae6b4;border-color:rgba(154,230,180,var(--border-opacity))}.sm\:focus\:border-green-400:focus{--border-opacity:1;border-color:#68d391;border-color:rgba(104,211,145,var(--border-opacity))}.sm\:focus\:border-green-500:focus{--border-opacity:1;border-color:#48bb78;border-color:rgba(72,187,120,var(--border-opacity))}.sm\:focus\:border-green-600:focus{--border-opacity:1;border-color:#38a169;border-color:rgba(56,161,105,var(--border-opacity))}.sm\:focus\:border-green-700:focus{--border-opacity:1;border-color:#2f855a;border-color:rgba(47,133,90,var(--border-opacity))}.sm\:focus\:border-green-800:focus{--border-opacity:1;border-color:#276749;border-color:rgba(39,103,73,var(--border-opacity))}.sm\:focus\:border-green-900:focus{--border-opacity:1;border-color:#22543d;border-color:rgba(34,84,61,var(--border-opacity))}.sm\:focus\:border-teal-100:focus{--border-opacity:1;border-color:#e6fffa;border-color:rgba(230,255,250,var(--border-opacity))}.sm\:focus\:border-teal-200:focus{--border-opacity:1;border-color:#b2f5ea;border-color:rgba(178,245,234,var(--border-opacity))}.sm\:focus\:border-teal-300:focus{--border-opacity:1;border-color:#81e6d9;border-color:rgba(129,230,217,var(--border-opacity))}.sm\:focus\:border-teal-400:focus{--border-opacity:1;border-color:#4fd1c5;border-color:rgba(79,209,197,var(--border-opacity))}.sm\:focus\:border-teal-500:focus{--border-opacity:1;border-color:#38b2ac;border-color:rgba(56,178,172,var(--border-opacity))}.sm\:focus\:border-teal-600:focus{--border-opacity:1;border-color:#319795;border-color:rgba(49,151,149,var(--border-opacity))}.sm\:focus\:border-teal-700:focus{--border-opacity:1;border-color:#2c7a7b;border-color:rgba(44,122,123,var(--border-opacity))}.sm\:focus\:border-teal-800:focus{--border-opacity:1;border-color:#285e61;border-color:rgba(40,94,97,var(--border-opacity))}.sm\:focus\:border-teal-900:focus{--border-opacity:1;border-color:#234e52;border-color:rgba(35,78,82,var(--border-opacity))}.sm\:focus\:border-blue-100:focus{--border-opacity:1;border-color:#ebf8ff;border-color:rgba(235,248,255,var(--border-opacity))}.sm\:focus\:border-blue-200:focus{--border-opacity:1;border-color:#bee3f8;border-color:rgba(190,227,248,var(--border-opacity))}.sm\:focus\:border-blue-300:focus{--border-opacity:1;border-color:#90cdf4;border-color:rgba(144,205,244,var(--border-opacity))}.sm\:focus\:border-blue-400:focus{--border-opacity:1;border-color:#63b3ed;border-color:rgba(99,179,237,var(--border-opacity))}.sm\:focus\:border-blue-500:focus{--border-opacity:1;border-color:#4299e1;border-color:rgba(66,153,225,var(--border-opacity))}.sm\:focus\:border-blue-600:focus{--border-opacity:1;border-color:#3182ce;border-color:rgba(49,130,206,var(--border-opacity))}.sm\:focus\:border-blue-700:focus{--border-opacity:1;border-color:#2b6cb0;border-color:rgba(43,108,176,var(--border-opacity))}.sm\:focus\:border-blue-800:focus{--border-opacity:1;border-color:#2c5282;border-color:rgba(44,82,130,var(--border-opacity))}.sm\:focus\:border-blue-900:focus{--border-opacity:1;border-color:#2a4365;border-color:rgba(42,67,101,var(--border-opacity))}.sm\:focus\:border-indigo-100:focus{--border-opacity:1;border-color:#ebf4ff;border-color:rgba(235,244,255,var(--border-opacity))}.sm\:focus\:border-indigo-200:focus{--border-opacity:1;border-color:#c3dafe;border-color:rgba(195,218,254,var(--border-opacity))}.sm\:focus\:border-indigo-300:focus{--border-opacity:1;border-color:#a3bffa;border-color:rgba(163,191,250,var(--border-opacity))}.sm\:focus\:border-indigo-400:focus{--border-opacity:1;border-color:#7f9cf5;border-color:rgba(127,156,245,var(--border-opacity))}.sm\:focus\:border-indigo-500:focus{--border-opacity:1;border-color:#667eea;border-color:rgba(102,126,234,var(--border-opacity))}.sm\:focus\:border-indigo-600:focus{--border-opacity:1;border-color:#5a67d8;border-color:rgba(90,103,216,var(--border-opacity))}.sm\:focus\:border-indigo-700:focus{--border-opacity:1;border-color:#4c51bf;border-color:rgba(76,81,191,var(--border-opacity))}.sm\:focus\:border-indigo-800:focus{--border-opacity:1;border-color:#434190;border-color:rgba(67,65,144,var(--border-opacity))}.sm\:focus\:border-indigo-900:focus{--border-opacity:1;border-color:#3c366b;border-color:rgba(60,54,107,var(--border-opacity))}.sm\:focus\:border-purple-100:focus{--border-opacity:1;border-color:#faf5ff;border-color:rgba(250,245,255,var(--border-opacity))}.sm\:focus\:border-purple-200:focus{--border-opacity:1;border-color:#e9d8fd;border-color:rgba(233,216,253,var(--border-opacity))}.sm\:focus\:border-purple-300:focus{--border-opacity:1;border-color:#d6bcfa;border-color:rgba(214,188,250,var(--border-opacity))}.sm\:focus\:border-purple-400:focus{--border-opacity:1;border-color:#b794f4;border-color:rgba(183,148,244,var(--border-opacity))}.sm\:focus\:border-purple-500:focus{--border-opacity:1;border-color:#9f7aea;border-color:rgba(159,122,234,var(--border-opacity))}.sm\:focus\:border-purple-600:focus{--border-opacity:1;border-color:#805ad5;border-color:rgba(128,90,213,var(--border-opacity))}.sm\:focus\:border-purple-700:focus{--border-opacity:1;border-color:#6b46c1;border-color:rgba(107,70,193,var(--border-opacity))}.sm\:focus\:border-purple-800:focus{--border-opacity:1;border-color:#553c9a;border-color:rgba(85,60,154,var(--border-opacity))}.sm\:focus\:border-purple-900:focus{--border-opacity:1;border-color:#44337a;border-color:rgba(68,51,122,var(--border-opacity))}.sm\:focus\:border-pink-100:focus{--border-opacity:1;border-color:#fff5f7;border-color:rgba(255,245,247,var(--border-opacity))}.sm\:focus\:border-pink-200:focus{--border-opacity:1;border-color:#fed7e2;border-color:rgba(254,215,226,var(--border-opacity))}.sm\:focus\:border-pink-300:focus{--border-opacity:1;border-color:#fbb6ce;border-color:rgba(251,182,206,var(--border-opacity))}.sm\:focus\:border-pink-400:focus{--border-opacity:1;border-color:#f687b3;border-color:rgba(246,135,179,var(--border-opacity))}.sm\:focus\:border-pink-500:focus{--border-opacity:1;border-color:#ed64a6;border-color:rgba(237,100,166,var(--border-opacity))}.sm\:focus\:border-pink-600:focus{--border-opacity:1;border-color:#d53f8c;border-color:rgba(213,63,140,var(--border-opacity))}.sm\:focus\:border-pink-700:focus{--border-opacity:1;border-color:#b83280;border-color:rgba(184,50,128,var(--border-opacity))}.sm\:focus\:border-pink-800:focus{--border-opacity:1;border-color:#97266d;border-color:rgba(151,38,109,var(--border-opacity))}.sm\:focus\:border-pink-900:focus{--border-opacity:1;border-color:#702459;border-color:rgba(112,36,89,var(--border-opacity))}.sm\:border-opacity-0{--border-opacity:0}.sm\:border-opacity-25{--border-opacity:0.25}.sm\:border-opacity-50{--border-opacity:0.5}.sm\:border-opacity-75{--border-opacity:0.75}.sm\:border-opacity-100{--border-opacity:1}.sm\:hover\:border-opacity-0:hover{--border-opacity:0}.sm\:hover\:border-opacity-25:hover{--border-opacity:0.25}.sm\:hover\:border-opacity-50:hover{--border-opacity:0.5}.sm\:hover\:border-opacity-75:hover{--border-opacity:0.75}.sm\:hover\:border-opacity-100:hover{--border-opacity:1}.sm\:focus\:border-opacity-0:focus{--border-opacity:0}.sm\:focus\:border-opacity-25:focus{--border-opacity:0.25}.sm\:focus\:border-opacity-50:focus{--border-opacity:0.5}.sm\:focus\:border-opacity-75:focus{--border-opacity:0.75}.sm\:focus\:border-opacity-100:focus{--border-opacity:1}.sm\:rounded-none{border-radius:0}.sm\:rounded-sm{border-radius:.125rem}.sm\:rounded{border-radius:.25rem}.sm\:rounded-md{border-radius:.375rem}.sm\:rounded-lg{border-radius:.5rem}.sm\:rounded-xl{border-radius:.75rem}.sm\:rounded-2xl{border-radius:1rem}.sm\:rounded-3xl{border-radius:1.5rem}.sm\:rounded-full{border-radius:9999px}.sm\:rounded-t-none{border-top-left-radius:0;border-top-right-radius:0}.sm\:rounded-r-none{border-top-right-radius:0;border-bottom-right-radius:0}.sm\:rounded-b-none{border-bottom-right-radius:0;border-bottom-left-radius:0}.sm\:rounded-l-none{border-top-left-radius:0;border-bottom-left-radius:0}.sm\:rounded-t-sm{border-top-left-radius:.125rem;border-top-right-radius:.125rem}.sm\:rounded-r-sm{border-top-right-radius:.125rem;border-bottom-right-radius:.125rem}.sm\:rounded-b-sm{border-bottom-right-radius:.125rem;border-bottom-left-radius:.125rem}.sm\:rounded-l-sm{border-top-left-radius:.125rem;border-bottom-left-radius:.125rem}.sm\:rounded-t{border-top-left-radius:.25rem;border-top-right-radius:.25rem}.sm\:rounded-r{border-top-right-radius:.25rem;border-bottom-right-radius:.25rem}.sm\:rounded-b{border-bottom-right-radius:.25rem;border-bottom-left-radius:.25rem}.sm\:rounded-l{border-top-left-radius:.25rem;border-bottom-left-radius:.25rem}.sm\:rounded-t-md{border-top-left-radius:.375rem;border-top-right-radius:.375rem}.sm\:rounded-r-md{border-top-right-radius:.375rem;border-bottom-right-radius:.375rem}.sm\:rounded-b-md{border-bottom-right-radius:.375rem;border-bottom-left-radius:.375rem}.sm\:rounded-l-md{border-top-left-radius:.375rem;border-bottom-left-radius:.375rem}.sm\:rounded-t-lg{border-top-left-radius:.5rem;border-top-right-radius:.5rem}.sm\:rounded-r-lg{border-top-right-radius:.5rem;border-bottom-right-radius:.5rem}.sm\:rounded-b-lg{border-bottom-right-radius:.5rem;border-bottom-left-radius:.5rem}.sm\:rounded-l-lg{border-top-left-radius:.5rem;border-bottom-left-radius:.5rem}.sm\:rounded-t-xl{border-top-left-radius:.75rem;border-top-right-radius:.75rem}.sm\:rounded-r-xl{border-top-right-radius:.75rem;border-bottom-right-radius:.75rem}.sm\:rounded-b-xl{border-bottom-right-radius:.75rem;border-bottom-left-radius:.75rem}.sm\:rounded-l-xl{border-top-left-radius:.75rem;border-bottom-left-radius:.75rem}.sm\:rounded-t-2xl{border-top-left-radius:1rem;border-top-right-radius:1rem}.sm\:rounded-r-2xl{border-top-right-radius:1rem;border-bottom-right-radius:1rem}.sm\:rounded-b-2xl{border-bottom-right-radius:1rem;border-bottom-left-radius:1rem}.sm\:rounded-l-2xl{border-top-left-radius:1rem;border-bottom-left-radius:1rem}.sm\:rounded-t-3xl{border-top-left-radius:1.5rem;border-top-right-radius:1.5rem}.sm\:rounded-r-3xl{border-top-right-radius:1.5rem;border-bottom-right-radius:1.5rem}.sm\:rounded-b-3xl{border-bottom-right-radius:1.5rem;border-bottom-left-radius:1.5rem}.sm\:rounded-l-3xl{border-top-left-radius:1.5rem;border-bottom-left-radius:1.5rem}.sm\:rounded-t-full{border-top-left-radius:9999px;border-top-right-radius:9999px}.sm\:rounded-r-full{border-top-right-radius:9999px;border-bottom-right-radius:9999px}.sm\:rounded-b-full{border-bottom-right-radius:9999px;border-bottom-left-radius:9999px}.sm\:rounded-l-full{border-top-left-radius:9999px;border-bottom-left-radius:9999px}.sm\:rounded-tl-none{border-top-left-radius:0}.sm\:rounded-tr-none{border-top-right-radius:0}.sm\:rounded-br-none{border-bottom-right-radius:0}.sm\:rounded-bl-none{border-bottom-left-radius:0}.sm\:rounded-tl-sm{border-top-left-radius:.125rem}.sm\:rounded-tr-sm{border-top-right-radius:.125rem}.sm\:rounded-br-sm{border-bottom-right-radius:.125rem}.sm\:rounded-bl-sm{border-bottom-left-radius:.125rem}.sm\:rounded-tl{border-top-left-radius:.25rem}.sm\:rounded-tr{border-top-right-radius:.25rem}.sm\:rounded-br{border-bottom-right-radius:.25rem}.sm\:rounded-bl{border-bottom-left-radius:.25rem}.sm\:rounded-tl-md{border-top-left-radius:.375rem}.sm\:rounded-tr-md{border-top-right-radius:.375rem}.sm\:rounded-br-md{border-bottom-right-radius:.375rem}.sm\:rounded-bl-md{border-bottom-left-radius:.375rem}.sm\:rounded-tl-lg{border-top-left-radius:.5rem}.sm\:rounded-tr-lg{border-top-right-radius:.5rem}.sm\:rounded-br-lg{border-bottom-right-radius:.5rem}.sm\:rounded-bl-lg{border-bottom-left-radius:.5rem}.sm\:rounded-tl-xl{border-top-left-radius:.75rem}.sm\:rounded-tr-xl{border-top-right-radius:.75rem}.sm\:rounded-br-xl{border-bottom-right-radius:.75rem}.sm\:rounded-bl-xl{border-bottom-left-radius:.75rem}.sm\:rounded-tl-2xl{border-top-left-radius:1rem}.sm\:rounded-tr-2xl{border-top-right-radius:1rem}.sm\:rounded-br-2xl{border-bottom-right-radius:1rem}.sm\:rounded-bl-2xl{border-bottom-left-radius:1rem}.sm\:rounded-tl-3xl{border-top-left-radius:1.5rem}.sm\:rounded-tr-3xl{border-top-right-radius:1.5rem}.sm\:rounded-br-3xl{border-bottom-right-radius:1.5rem}.sm\:rounded-bl-3xl{border-bottom-left-radius:1.5rem}.sm\:rounded-tl-full{border-top-left-radius:9999px}.sm\:rounded-tr-full{border-top-right-radius:9999px}.sm\:rounded-br-full{border-bottom-right-radius:9999px}.sm\:rounded-bl-full{border-bottom-left-radius:9999px}.sm\:border-solid{border-style:solid}.sm\:border-dashed{border-style:dashed}.sm\:border-dotted{border-style:dotted}.sm\:border-double{border-style:double}.sm\:border-none{border-style:none}.sm\:border-0{border-width:0}.sm\:border-2{border-width:2px}.sm\:border-4{border-width:4px}.sm\:border-8{border-width:8px}.sm\:border{border-width:1px}.sm\:border-t-0{border-top-width:0}.sm\:border-r-0{border-right-width:0}.sm\:border-b-0{border-bottom-width:0}.sm\:border-l-0{border-left-width:0}.sm\:border-t-2{border-top-width:2px}.sm\:border-r-2{border-right-width:2px}.sm\:border-b-2{border-bottom-width:2px}.sm\:border-l-2{border-left-width:2px}.sm\:border-t-4{border-top-width:4px}.sm\:border-r-4{border-right-width:4px}.sm\:border-b-4{border-bottom-width:4px}.sm\:border-l-4{border-left-width:4px}.sm\:border-t-8{border-top-width:8px}.sm\:border-r-8{border-right-width:8px}.sm\:border-b-8{border-bottom-width:8px}.sm\:border-l-8{border-left-width:8px}.sm\:border-t{border-top-width:1px}.sm\:border-r{border-right-width:1px}.sm\:border-b{border-bottom-width:1px}.sm\:border-l{border-left-width:1px}.sm\:box-border{box-sizing:border-box}.sm\:box-content{box-sizing:content-box}.sm\:cursor-auto{cursor:auto}.sm\:cursor-default{cursor:default}.sm\:cursor-pointer{cursor:pointer}.sm\:cursor-wait{cursor:wait}.sm\:cursor-text{cursor:text}.sm\:cursor-move{cursor:move}.sm\:cursor-not-allowed{cursor:not-allowed}.sm\:block{display:block}.sm\:inline-block{display:inline-block}.sm\:inline{display:inline}.sm\:flex{display:flex}.sm\:inline-flex{display:inline-flex}.sm\:table{display:table}.sm\:table-caption{display:table-caption}.sm\:table-cell{display:table-cell}.sm\:table-column{display:table-column}.sm\:table-column-group{display:table-column-group}.sm\:table-footer-group{display:table-footer-group}.sm\:table-header-group{display:table-header-group}.sm\:table-row-group{display:table-row-group}.sm\:table-row{display:table-row}.sm\:flow-root{display:flow-root}.sm\:grid{display:grid}.sm\:inline-grid{display:inline-grid}.sm\:contents{display:contents}.sm\:hidden{display:none}.sm\:flex-row{flex-direction:row}.sm\:flex-row-reverse{flex-direction:row-reverse}.sm\:flex-col{flex-direction:column}.sm\:flex-col-reverse{flex-direction:column-reverse}.sm\:flex-wrap{flex-wrap:wrap}.sm\:flex-wrap-reverse{flex-wrap:wrap-reverse}.sm\:flex-no-wrap{flex-wrap:nowrap}.sm\:place-items-auto{place-items:auto}.sm\:place-items-start{place-items:start}.sm\:place-items-end{place-items:end}.sm\:place-items-center{place-items:center}.sm\:place-items-stretch{place-items:stretch}.sm\:place-content-center{place-content:center}.sm\:place-content-start{place-content:start}.sm\:place-content-end{place-content:end}.sm\:place-content-between{place-content:space-between}.sm\:place-content-around{place-content:space-around}.sm\:place-content-evenly{place-content:space-evenly}.sm\:place-content-stretch{place-content:stretch}.sm\:place-self-auto{place-self:auto}.sm\:place-self-start{place-self:start}.sm\:place-self-end{place-self:end}.sm\:place-self-center{place-self:center}.sm\:place-self-stretch{place-self:stretch}.sm\:items-start{align-items:flex-start}.sm\:items-end{align-items:flex-end}.sm\:items-center{align-items:center}.sm\:items-baseline{align-items:baseline}.sm\:items-stretch{align-items:stretch}.sm\:content-center{align-content:center}.sm\:content-start{align-content:flex-start}.sm\:content-end{align-content:flex-end}.sm\:content-between{align-content:space-between}.sm\:content-around{align-content:space-around}.sm\:content-evenly{align-content:space-evenly}.sm\:self-auto{align-self:auto}.sm\:self-start{align-self:flex-start}.sm\:self-end{align-self:flex-end}.sm\:self-center{align-self:center}.sm\:self-stretch{align-self:stretch}.sm\:justify-items-auto{justify-items:auto}.sm\:justify-items-start{justify-items:start}.sm\:justify-items-end{justify-items:end}.sm\:justify-items-center{justify-items:center}.sm\:justify-items-stretch{justify-items:stretch}.sm\:justify-start{justify-content:flex-start}.sm\:justify-end{justify-content:flex-end}.sm\:justify-center{justify-content:center}.sm\:justify-between{justify-content:space-between}.sm\:justify-around{justify-content:space-around}.sm\:justify-evenly{justify-content:space-evenly}.sm\:justify-self-auto{justify-self:auto}.sm\:justify-self-start{justify-self:start}.sm\:justify-self-end{justify-self:end}.sm\:justify-self-center{justify-self:center}.sm\:justify-self-stretch{justify-self:stretch}.sm\:flex-1{flex:1 1 0%}.sm\:flex-auto{flex:1 1 auto}.sm\:flex-initial{flex:0 1 auto}.sm\:flex-none{flex:none}.sm\:flex-grow-0{flex-grow:0}.sm\:flex-grow{flex-grow:1}.sm\:flex-shrink-0{flex-shrink:0}.sm\:flex-shrink{flex-shrink:1}.sm\:order-1{order:1}.sm\:order-2{order:2}.sm\:order-3{order:3}.sm\:order-4{order:4}.sm\:order-5{order:5}.sm\:order-6{order:6}.sm\:order-7{order:7}.sm\:order-8{order:8}.sm\:order-9{order:9}.sm\:order-10{order:10}.sm\:order-11{order:11}.sm\:order-12{order:12}.sm\:order-first{order:-9999}.sm\:order-last{order:9999}.sm\:order-none{order:0}.sm\:float-right{float:right}.sm\:float-left{float:left}.sm\:float-none{float:none}.sm\:clearfix:after{content:"";display:table;clear:both}.sm\:clear-left{clear:left}.sm\:clear-right{clear:right}.sm\:clear-both{clear:both}.sm\:clear-none{clear:none}.sm\:font-sans{font-family:system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji"}.sm\:font-serif{font-family:Georgia,Cambria,"Times New Roman",Times,serif}.sm\:font-mono{font-family:Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace}.sm\:font-hairline{font-weight:100}.sm\:font-thin{font-weight:200}.sm\:font-light{font-weight:300}.sm\:font-normal{font-weight:400}.sm\:font-medium{font-weight:500}.sm\:font-semibold{font-weight:600}.sm\:font-bold{font-weight:700}.sm\:font-extrabold{font-weight:800}.sm\:font-black{font-weight:900}.sm\:hover\:font-hairline:hover{font-weight:100}.sm\:hover\:font-thin:hover{font-weight:200}.sm\:hover\:font-light:hover{font-weight:300}.sm\:hover\:font-normal:hover{font-weight:400}.sm\:hover\:font-medium:hover{font-weight:500}.sm\:hover\:font-semibold:hover{font-weight:600}.sm\:hover\:font-bold:hover{font-weight:700}.sm\:hover\:font-extrabold:hover{font-weight:800}.sm\:hover\:font-black:hover{font-weight:900}.sm\:focus\:font-hairline:focus{font-weight:100}.sm\:focus\:font-thin:focus{font-weight:200}.sm\:focus\:font-light:focus{font-weight:300}.sm\:focus\:font-normal:focus{font-weight:400}.sm\:focus\:font-medium:focus{font-weight:500}.sm\:focus\:font-semibold:focus{font-weight:600}.sm\:focus\:font-bold:focus{font-weight:700}.sm\:focus\:font-extrabold:focus{font-weight:800}.sm\:focus\:font-black:focus{font-weight:900}.sm\:h-0{height:0}.sm\:h-1{height:.25rem}.sm\:h-2{height:.5rem}.sm\:h-3{height:.75rem}.sm\:h-4{height:1rem}.sm\:h-5{height:1.25rem}.sm\:h-6{height:1.5rem}.sm\:h-8{height:2rem}.sm\:h-10{height:2.5rem}.sm\:h-12{height:3rem}.sm\:h-16{height:4rem}.sm\:h-20{height:5rem}.sm\:h-24{height:6rem}.sm\:h-32{height:8rem}.sm\:h-40{height:10rem}.sm\:h-48{height:12rem}.sm\:h-56{height:14rem}.sm\:h-64{height:16rem}.sm\:h-auto{height:auto}.sm\:h-px{height:1px}.sm\:h-full{height:100%}.sm\:h-screen{height:100vh}.sm\:text-xs{font-size:.75rem}.sm\:text-sm{font-size:.875rem}.sm\:text-base{font-size:1rem}.sm\:text-lg{font-size:1.125rem}.sm\:text-xl{font-size:1.25rem}.sm\:text-2xl{font-size:1.5rem}.sm\:text-3xl{font-size:1.875rem}.sm\:text-4xl{font-size:2.25rem}.sm\:text-5xl{font-size:3rem}.sm\:text-6xl{font-size:4rem}.sm\:leading-3{line-height:.75rem}.sm\:leading-4{line-height:1rem}.sm\:leading-5{line-height:1.25rem}.sm\:leading-6{line-height:1.5rem}.sm\:leading-7{line-height:1.75rem}.sm\:leading-8{line-height:2rem}.sm\:leading-9{line-height:2.25rem}.sm\:leading-10{line-height:2.5rem}.sm\:leading-none{line-height:1}.sm\:leading-tight{line-height:1.25}.sm\:leading-snug{line-height:1.375}.sm\:leading-normal{line-height:1.5}.sm\:leading-relaxed{line-height:1.625}.sm\:leading-loose{line-height:2}.sm\:list-inside{list-style-position:inside}.sm\:list-outside{list-style-position:outside}.sm\:list-none{list-style-type:none}.sm\:list-disc{list-style-type:disc}.sm\:list-decimal{list-style-type:decimal}.sm\:m-0{margin:0}.sm\:m-1{margin:.25rem}.sm\:m-2{margin:.5rem}.sm\:m-3{margin:.75rem}.sm\:m-4{margin:1rem}.sm\:m-5{margin:1.25rem}.sm\:m-6{margin:1.5rem}.sm\:m-8{margin:2rem}.sm\:m-10{margin:2.5rem}.sm\:m-12{margin:3rem}.sm\:m-16{margin:4rem}.sm\:m-20{margin:5rem}.sm\:m-24{margin:6rem}.sm\:m-32{margin:8rem}.sm\:m-40{margin:10rem}.sm\:m-48{margin:12rem}.sm\:m-56{margin:14rem}.sm\:m-64{margin:16rem}.sm\:m-auto{margin:auto}.sm\:m-px{margin:1px}.sm\:-m-1{margin:-.25rem}.sm\:-m-2{margin:-.5rem}.sm\:-m-3{margin:-.75rem}.sm\:-m-4{margin:-1rem}.sm\:-m-5{margin:-1.25rem}.sm\:-m-6{margin:-1.5rem}.sm\:-m-8{margin:-2rem}.sm\:-m-10{margin:-2.5rem}.sm\:-m-12{margin:-3rem}.sm\:-m-16{margin:-4rem}.sm\:-m-20{margin:-5rem}.sm\:-m-24{margin:-6rem}.sm\:-m-32{margin:-8rem}.sm\:-m-40{margin:-10rem}.sm\:-m-48{margin:-12rem}.sm\:-m-56{margin:-14rem}.sm\:-m-64{margin:-16rem}.sm\:-m-px{margin:-1px}.sm\:my-0{margin-top:0;margin-bottom:0}.sm\:mx-0{margin-left:0;margin-right:0}.sm\:my-1{margin-top:.25rem;margin-bottom:.25rem}.sm\:mx-1{margin-left:.25rem;margin-right:.25rem}.sm\:my-2{margin-top:.5rem;margin-bottom:.5rem}.sm\:mx-2{margin-left:.5rem;margin-right:.5rem}.sm\:my-3{margin-top:.75rem;margin-bottom:.75rem}.sm\:mx-3{margin-left:.75rem;margin-right:.75rem}.sm\:my-4{margin-top:1rem;margin-bottom:1rem}.sm\:mx-4{margin-left:1rem;margin-right:1rem}.sm\:my-5{margin-top:1.25rem;margin-bottom:1.25rem}.sm\:mx-5{margin-left:1.25rem;margin-right:1.25rem}.sm\:my-6{margin-top:1.5rem;margin-bottom:1.5rem}.sm\:mx-6{margin-left:1.5rem;margin-right:1.5rem}.sm\:my-8{margin-top:2rem;margin-bottom:2rem}.sm\:mx-8{margin-left:2rem;margin-right:2rem}.sm\:my-10{margin-top:2.5rem;margin-bottom:2.5rem}.sm\:mx-10{margin-left:2.5rem;margin-right:2.5rem}.sm\:my-12{margin-top:3rem;margin-bottom:3rem}.sm\:mx-12{margin-left:3rem;margin-right:3rem}.sm\:my-16{margin-top:4rem;margin-bottom:4rem}.sm\:mx-16{margin-left:4rem;margin-right:4rem}.sm\:my-20{margin-top:5rem;margin-bottom:5rem}.sm\:mx-20{margin-left:5rem;margin-right:5rem}.sm\:my-24{margin-top:6rem;margin-bottom:6rem}.sm\:mx-24{margin-left:6rem;margin-right:6rem}.sm\:my-32{margin-top:8rem;margin-bottom:8rem}.sm\:mx-32{margin-left:8rem;margin-right:8rem}.sm\:my-40{margin-top:10rem;margin-bottom:10rem}.sm\:mx-40{margin-left:10rem;margin-right:10rem}.sm\:my-48{margin-top:12rem;margin-bottom:12rem}.sm\:mx-48{margin-left:12rem;margin-right:12rem}.sm\:my-56{margin-top:14rem;margin-bottom:14rem}.sm\:mx-56{margin-left:14rem;margin-right:14rem}.sm\:my-64{margin-top:16rem;margin-bottom:16rem}.sm\:mx-64{margin-left:16rem;margin-right:16rem}.sm\:my-auto{margin-top:auto;margin-bottom:auto}.sm\:mx-auto{margin-left:auto;margin-right:auto}.sm\:my-px{margin-top:1px;margin-bottom:1px}.sm\:mx-px{margin-left:1px;margin-right:1px}.sm\:-my-1{margin-top:-.25rem;margin-bottom:-.25rem}.sm\:-mx-1{margin-left:-.25rem;margin-right:-.25rem}.sm\:-my-2{margin-top:-.5rem;margin-bottom:-.5rem}.sm\:-mx-2{margin-left:-.5rem;margin-right:-.5rem}.sm\:-my-3{margin-top:-.75rem;margin-bottom:-.75rem}.sm\:-mx-3{margin-left:-.75rem;margin-right:-.75rem}.sm\:-my-4{margin-top:-1rem;margin-bottom:-1rem}.sm\:-mx-4{margin-left:-1rem;margin-right:-1rem}.sm\:-my-5{margin-top:-1.25rem;margin-bottom:-1.25rem}.sm\:-mx-5{margin-left:-1.25rem;margin-right:-1.25rem}.sm\:-my-6{margin-top:-1.5rem;margin-bottom:-1.5rem}.sm\:-mx-6{margin-left:-1.5rem;margin-right:-1.5rem}.sm\:-my-8{margin-top:-2rem;margin-bottom:-2rem}.sm\:-mx-8{margin-left:-2rem;margin-right:-2rem}.sm\:-my-10{margin-top:-2.5rem;margin-bottom:-2.5rem}.sm\:-mx-10{margin-left:-2.5rem;margin-right:-2.5rem}.sm\:-my-12{margin-top:-3rem;margin-bottom:-3rem}.sm\:-mx-12{margin-left:-3rem;margin-right:-3rem}.sm\:-my-16{margin-top:-4rem;margin-bottom:-4rem}.sm\:-mx-16{margin-left:-4rem;margin-right:-4rem}.sm\:-my-20{margin-top:-5rem;margin-bottom:-5rem}.sm\:-mx-20{margin-left:-5rem;margin-right:-5rem}.sm\:-my-24{margin-top:-6rem;margin-bottom:-6rem}.sm\:-mx-24{margin-left:-6rem;margin-right:-6rem}.sm\:-my-32{margin-top:-8rem;margin-bottom:-8rem}.sm\:-mx-32{margin-left:-8rem;margin-right:-8rem}.sm\:-my-40{margin-top:-10rem;margin-bottom:-10rem}.sm\:-mx-40{margin-left:-10rem;margin-right:-10rem}.sm\:-my-48{margin-top:-12rem;margin-bottom:-12rem}.sm\:-mx-48{margin-left:-12rem;margin-right:-12rem}.sm\:-my-56{margin-top:-14rem;margin-bottom:-14rem}.sm\:-mx-56{margin-left:-14rem;margin-right:-14rem}.sm\:-my-64{margin-top:-16rem;margin-bottom:-16rem}.sm\:-mx-64{margin-left:-16rem;margin-right:-16rem}.sm\:-my-px{margin-top:-1px;margin-bottom:-1px}.sm\:-mx-px{margin-left:-1px;margin-right:-1px}.sm\:mt-0{margin-top:0}.sm\:mr-0{margin-right:0}.sm\:mb-0{margin-bottom:0}.sm\:ml-0{margin-left:0}.sm\:mt-1{margin-top:.25rem}.sm\:mr-1{margin-right:.25rem}.sm\:mb-1{margin-bottom:.25rem}.sm\:ml-1{margin-left:.25rem}.sm\:mt-2{margin-top:.5rem}.sm\:mr-2{margin-right:.5rem}.sm\:mb-2{margin-bottom:.5rem}.sm\:ml-2{margin-left:.5rem}.sm\:mt-3{margin-top:.75rem}.sm\:mr-3{margin-right:.75rem}.sm\:mb-3{margin-bottom:.75rem}.sm\:ml-3{margin-left:.75rem}.sm\:mt-4{margin-top:1rem}.sm\:mr-4{margin-right:1rem}.sm\:mb-4{margin-bottom:1rem}.sm\:ml-4{margin-left:1rem}.sm\:mt-5{margin-top:1.25rem}.sm\:mr-5{margin-right:1.25rem}.sm\:mb-5{margin-bottom:1.25rem}.sm\:ml-5{margin-left:1.25rem}.sm\:mt-6{margin-top:1.5rem}.sm\:mr-6{margin-right:1.5rem}.sm\:mb-6{margin-bottom:1.5rem}.sm\:ml-6{margin-left:1.5rem}.sm\:mt-8{margin-top:2rem}.sm\:mr-8{margin-right:2rem}.sm\:mb-8{margin-bottom:2rem}.sm\:ml-8{margin-left:2rem}.sm\:mt-10{margin-top:2.5rem}.sm\:mr-10{margin-right:2.5rem}.sm\:mb-10{margin-bottom:2.5rem}.sm\:ml-10{margin-left:2.5rem}.sm\:mt-12{margin-top:3rem}.sm\:mr-12{margin-right:3rem}.sm\:mb-12{margin-bottom:3rem}.sm\:ml-12{margin-left:3rem}.sm\:mt-16{margin-top:4rem}.sm\:mr-16{margin-right:4rem}.sm\:mb-16{margin-bottom:4rem}.sm\:ml-16{margin-left:4rem}.sm\:mt-20{margin-top:5rem}.sm\:mr-20{margin-right:5rem}.sm\:mb-20{margin-bottom:5rem}.sm\:ml-20{margin-left:5rem}.sm\:mt-24{margin-top:6rem}.sm\:mr-24{margin-right:6rem}.sm\:mb-24{margin-bottom:6rem}.sm\:ml-24{margin-left:6rem}.sm\:mt-32{margin-top:8rem}.sm\:mr-32{margin-right:8rem}.sm\:mb-32{margin-bottom:8rem}.sm\:ml-32{margin-left:8rem}.sm\:mt-40{margin-top:10rem}.sm\:mr-40{margin-right:10rem}.sm\:mb-40{margin-bottom:10rem}.sm\:ml-40{margin-left:10rem}.sm\:mt-48{margin-top:12rem}.sm\:mr-48{margin-right:12rem}.sm\:mb-48{margin-bottom:12rem}.sm\:ml-48{margin-left:12rem}.sm\:mt-56{margin-top:14rem}.sm\:mr-56{margin-right:14rem}.sm\:mb-56{margin-bottom:14rem}.sm\:ml-56{margin-left:14rem}.sm\:mt-64{margin-top:16rem}.sm\:mr-64{margin-right:16rem}.sm\:mb-64{margin-bottom:16rem}.sm\:ml-64{margin-left:16rem}.sm\:mt-auto{margin-top:auto}.sm\:mr-auto{margin-right:auto}.sm\:mb-auto{margin-bottom:auto}.sm\:ml-auto{margin-left:auto}.sm\:mt-px{margin-top:1px}.sm\:mr-px{margin-right:1px}.sm\:mb-px{margin-bottom:1px}.sm\:ml-px{margin-left:1px}.sm\:-mt-1{margin-top:-.25rem}.sm\:-mr-1{margin-right:-.25rem}.sm\:-mb-1{margin-bottom:-.25rem}.sm\:-ml-1{margin-left:-.25rem}.sm\:-mt-2{margin-top:-.5rem}.sm\:-mr-2{margin-right:-.5rem}.sm\:-mb-2{margin-bottom:-.5rem}.sm\:-ml-2{margin-left:-.5rem}.sm\:-mt-3{margin-top:-.75rem}.sm\:-mr-3{margin-right:-.75rem}.sm\:-mb-3{margin-bottom:-.75rem}.sm\:-ml-3{margin-left:-.75rem}.sm\:-mt-4{margin-top:-1rem}.sm\:-mr-4{margin-right:-1rem}.sm\:-mb-4{margin-bottom:-1rem}.sm\:-ml-4{margin-left:-1rem}.sm\:-mt-5{margin-top:-1.25rem}.sm\:-mr-5{margin-right:-1.25rem}.sm\:-mb-5{margin-bottom:-1.25rem}.sm\:-ml-5{margin-left:-1.25rem}.sm\:-mt-6{margin-top:-1.5rem}.sm\:-mr-6{margin-right:-1.5rem}.sm\:-mb-6{margin-bottom:-1.5rem}.sm\:-ml-6{margin-left:-1.5rem}.sm\:-mt-8{margin-top:-2rem}.sm\:-mr-8{margin-right:-2rem}.sm\:-mb-8{margin-bottom:-2rem}.sm\:-ml-8{margin-left:-2rem}.sm\:-mt-10{margin-top:-2.5rem}.sm\:-mr-10{margin-right:-2.5rem}.sm\:-mb-10{margin-bottom:-2.5rem}.sm\:-ml-10{margin-left:-2.5rem}.sm\:-mt-12{margin-top:-3rem}.sm\:-mr-12{margin-right:-3rem}.sm\:-mb-12{margin-bottom:-3rem}.sm\:-ml-12{margin-left:-3rem}.sm\:-mt-16{margin-top:-4rem}.sm\:-mr-16{margin-right:-4rem}.sm\:-mb-16{margin-bottom:-4rem}.sm\:-ml-16{margin-left:-4rem}.sm\:-mt-20{margin-top:-5rem}.sm\:-mr-20{margin-right:-5rem}.sm\:-mb-20{margin-bottom:-5rem}.sm\:-ml-20{margin-left:-5rem}.sm\:-mt-24{margin-top:-6rem}.sm\:-mr-24{margin-right:-6rem}.sm\:-mb-24{margin-bottom:-6rem}.sm\:-ml-24{margin-left:-6rem}.sm\:-mt-32{margin-top:-8rem}.sm\:-mr-32{margin-right:-8rem}.sm\:-mb-32{margin-bottom:-8rem}.sm\:-ml-32{margin-left:-8rem}.sm\:-mt-40{margin-top:-10rem}.sm\:-mr-40{margin-right:-10rem}.sm\:-mb-40{margin-bottom:-10rem}.sm\:-ml-40{margin-left:-10rem}.sm\:-mt-48{margin-top:-12rem}.sm\:-mr-48{margin-right:-12rem}.sm\:-mb-48{margin-bottom:-12rem}.sm\:-ml-48{margin-left:-12rem}.sm\:-mt-56{margin-top:-14rem}.sm\:-mr-56{margin-right:-14rem}.sm\:-mb-56{margin-bottom:-14rem}.sm\:-ml-56{margin-left:-14rem}.sm\:-mt-64{margin-top:-16rem}.sm\:-mr-64{margin-right:-16rem}.sm\:-mb-64{margin-bottom:-16rem}.sm\:-ml-64{margin-left:-16rem}.sm\:-mt-px{margin-top:-1px}.sm\:-mr-px{margin-right:-1px}.sm\:-mb-px{margin-bottom:-1px}.sm\:-ml-px{margin-left:-1px}.sm\:max-h-full{max-height:100%}.sm\:max-h-screen{max-height:100vh}.sm\:max-w-none{max-width:none}.sm\:max-w-xs{max-width:20rem}.sm\:max-w-sm{max-width:24rem}.sm\:max-w-md{max-width:28rem}.sm\:max-w-lg{max-width:32rem}.sm\:max-w-xl{max-width:36rem}.sm\:max-w-2xl{max-width:42rem}.sm\:max-w-3xl{max-width:48rem}.sm\:max-w-4xl{max-width:56rem}.sm\:max-w-5xl{max-width:64rem}.sm\:max-w-6xl{max-width:72rem}.sm\:max-w-full{max-width:100%}.sm\:max-w-screen-sm{max-width:640px}.sm\:max-w-screen-md{max-width:768px}.sm\:max-w-screen-lg{max-width:1024px}.sm\:max-w-screen-xl{max-width:1280px}.sm\:min-h-0{min-height:0}.sm\:min-h-full{min-height:100%}.sm\:min-h-screen{min-height:100vh}.sm\:min-w-0{min-width:0}.sm\:min-w-full{min-width:100%}.sm\:object-contain{object-fit:contain}.sm\:object-cover{object-fit:cover}.sm\:object-fill{object-fit:fill}.sm\:object-none{object-fit:none}.sm\:object-scale-down{object-fit:scale-down}.sm\:object-bottom{object-position:bottom}.sm\:object-center{object-position:center}.sm\:object-left{object-position:left}.sm\:object-left-bottom{object-position:left bottom}.sm\:object-left-top{object-position:left top}.sm\:object-right{object-position:right}.sm\:object-right-bottom{object-position:right bottom}.sm\:object-right-top{object-position:right top}.sm\:object-top{object-position:top}.sm\:opacity-0{opacity:0}.sm\:opacity-25{opacity:.25}.sm\:opacity-50{opacity:.5}.sm\:opacity-75{opacity:.75}.sm\:opacity-100{opacity:1}.sm\:hover\:opacity-0:hover{opacity:0}.sm\:hover\:opacity-25:hover{opacity:.25}.sm\:hover\:opacity-50:hover{opacity:.5}.sm\:hover\:opacity-75:hover{opacity:.75}.sm\:hover\:opacity-100:hover{opacity:1}.sm\:focus\:opacity-0:focus{opacity:0}.sm\:focus\:opacity-25:focus{opacity:.25}.sm\:focus\:opacity-50:focus{opacity:.5}.sm\:focus\:opacity-75:focus{opacity:.75}.sm\:focus\:opacity-100:focus{opacity:1}.sm\:outline-none{outline:2px solid transparent;outline-offset:2px}.sm\:outline-white{outline:2px dotted #fff;outline-offset:2px}.sm\:outline-black{outline:2px dotted #000;outline-offset:2px}.sm\:focus\:outline-none:focus{outline:2px solid transparent;outline-offset:2px}.sm\:focus\:outline-white:focus{outline:2px dotted #fff;outline-offset:2px}.sm\:focus\:outline-black:focus{outline:2px dotted #000;outline-offset:2px}.sm\:overflow-auto{overflow:auto}.sm\:overflow-hidden{overflow:hidden}.sm\:overflow-visible{overflow:visible}.sm\:overflow-scroll{overflow:scroll}.sm\:overflow-x-auto{overflow-x:auto}.sm\:overflow-y-auto{overflow-y:auto}.sm\:overflow-x-hidden{overflow-x:hidden}.sm\:overflow-y-hidden{overflow-y:hidden}.sm\:overflow-x-visible{overflow-x:visible}.sm\:overflow-y-visible{overflow-y:visible}.sm\:overflow-x-scroll{overflow-x:scroll}.sm\:overflow-y-scroll{overflow-y:scroll}.sm\:scrolling-touch{-webkit-overflow-scrolling:touch}.sm\:scrolling-auto{-webkit-overflow-scrolling:auto}.sm\:overscroll-auto{-ms-scroll-chaining:chained;overscroll-behavior:auto}.sm\:overscroll-contain{-ms-scroll-chaining:none;overscroll-behavior:contain}.sm\:overscroll-none{-ms-scroll-chaining:none;overscroll-behavior:none}.sm\:overscroll-y-auto{overscroll-behavior-y:auto}.sm\:overscroll-y-contain{overscroll-behavior-y:contain}.sm\:overscroll-y-none{overscroll-behavior-y:none}.sm\:overscroll-x-auto{overscroll-behavior-x:auto}.sm\:overscroll-x-contain{overscroll-behavior-x:contain}.sm\:overscroll-x-none{overscroll-behavior-x:none}.sm\:p-0{padding:0}.sm\:p-1{padding:.25rem}.sm\:p-2{padding:.5rem}.sm\:p-3{padding:.75rem}.sm\:p-4{padding:1rem}.sm\:p-5{padding:1.25rem}.sm\:p-6{padding:1.5rem}.sm\:p-8{padding:2rem}.sm\:p-10{padding:2.5rem}.sm\:p-12{padding:3rem}.sm\:p-16{padding:4rem}.sm\:p-20{padding:5rem}.sm\:p-24{padding:6rem}.sm\:p-32{padding:8rem}.sm\:p-40{padding:10rem}.sm\:p-48{padding:12rem}.sm\:p-56{padding:14rem}.sm\:p-64{padding:16rem}.sm\:p-px{padding:1px}.sm\:py-0{padding-top:0;padding-bottom:0}.sm\:px-0{padding-left:0;padding-right:0}.sm\:py-1{padding-top:.25rem;padding-bottom:.25rem}.sm\:px-1{padding-left:.25rem;padding-right:.25rem}.sm\:py-2{padding-top:.5rem;padding-bottom:.5rem}.sm\:px-2{padding-left:.5rem;padding-right:.5rem}.sm\:py-3{padding-top:.75rem;padding-bottom:.75rem}.sm\:px-3{padding-left:.75rem;padding-right:.75rem}.sm\:py-4{padding-top:1rem;padding-bottom:1rem}.sm\:px-4{padding-left:1rem;padding-right:1rem}.sm\:py-5{padding-top:1.25rem;padding-bottom:1.25rem}.sm\:px-5{padding-left:1.25rem;padding-right:1.25rem}.sm\:py-6{padding-top:1.5rem;padding-bottom:1.5rem}.sm\:px-6{padding-left:1.5rem;padding-right:1.5rem}.sm\:py-8{padding-top:2rem;padding-bottom:2rem}.sm\:px-8{padding-left:2rem;padding-right:2rem}.sm\:py-10{padding-top:2.5rem;padding-bottom:2.5rem}.sm\:px-10{padding-left:2.5rem;padding-right:2.5rem}.sm\:py-12{padding-top:3rem;padding-bottom:3rem}.sm\:px-12{padding-left:3rem;padding-right:3rem}.sm\:py-16{padding-top:4rem;padding-bottom:4rem}.sm\:px-16{padding-left:4rem;padding-right:4rem}.sm\:py-20{padding-top:5rem;padding-bottom:5rem}.sm\:px-20{padding-left:5rem;padding-right:5rem}.sm\:py-24{padding-top:6rem;padding-bottom:6rem}.sm\:px-24{padding-left:6rem;padding-right:6rem}.sm\:py-32{padding-top:8rem;padding-bottom:8rem}.sm\:px-32{padding-left:8rem;padding-right:8rem}.sm\:py-40{padding-top:10rem;padding-bottom:10rem}.sm\:px-40{padding-left:10rem;padding-right:10rem}.sm\:py-48{padding-top:12rem;padding-bottom:12rem}.sm\:px-48{padding-left:12rem;padding-right:12rem}.sm\:py-56{padding-top:14rem;padding-bottom:14rem}.sm\:px-56{padding-left:14rem;padding-right:14rem}.sm\:py-64{padding-top:16rem;padding-bottom:16rem}.sm\:px-64{padding-left:16rem;padding-right:16rem}.sm\:py-px{padding-top:1px;padding-bottom:1px}.sm\:px-px{padding-left:1px;padding-right:1px}.sm\:pt-0{padding-top:0}.sm\:pr-0{padding-right:0}.sm\:pb-0{padding-bottom:0}.sm\:pl-0{padding-left:0}.sm\:pt-1{padding-top:.25rem}.sm\:pr-1{padding-right:.25rem}.sm\:pb-1{padding-bottom:.25rem}.sm\:pl-1{padding-left:.25rem}.sm\:pt-2{padding-top:.5rem}.sm\:pr-2{padding-right:.5rem}.sm\:pb-2{padding-bottom:.5rem}.sm\:pl-2{padding-left:.5rem}.sm\:pt-3{padding-top:.75rem}.sm\:pr-3{padding-right:.75rem}.sm\:pb-3{padding-bottom:.75rem}.sm\:pl-3{padding-left:.75rem}.sm\:pt-4{padding-top:1rem}.sm\:pr-4{padding-right:1rem}.sm\:pb-4{padding-bottom:1rem}.sm\:pl-4{padding-left:1rem}.sm\:pt-5{padding-top:1.25rem}.sm\:pr-5{padding-right:1.25rem}.sm\:pb-5{padding-bottom:1.25rem}.sm\:pl-5{padding-left:1.25rem}.sm\:pt-6{padding-top:1.5rem}.sm\:pr-6{padding-right:1.5rem}.sm\:pb-6{padding-bottom:1.5rem}.sm\:pl-6{padding-left:1.5rem}.sm\:pt-8{padding-top:2rem}.sm\:pr-8{padding-right:2rem}.sm\:pb-8{padding-bottom:2rem}.sm\:pl-8{padding-left:2rem}.sm\:pt-10{padding-top:2.5rem}.sm\:pr-10{padding-right:2.5rem}.sm\:pb-10{padding-bottom:2.5rem}.sm\:pl-10{padding-left:2.5rem}.sm\:pt-12{padding-top:3rem}.sm\:pr-12{padding-right:3rem}.sm\:pb-12{padding-bottom:3rem}.sm\:pl-12{padding-left:3rem}.sm\:pt-16{padding-top:4rem}.sm\:pr-16{padding-right:4rem}.sm\:pb-16{padding-bottom:4rem}.sm\:pl-16{padding-left:4rem}.sm\:pt-20{padding-top:5rem}.sm\:pr-20{padding-right:5rem}.sm\:pb-20{padding-bottom:5rem}.sm\:pl-20{padding-left:5rem}.sm\:pt-24{padding-top:6rem}.sm\:pr-24{padding-right:6rem}.sm\:pb-24{padding-bottom:6rem}.sm\:pl-24{padding-left:6rem}.sm\:pt-32{padding-top:8rem}.sm\:pr-32{padding-right:8rem}.sm\:pb-32{padding-bottom:8rem}.sm\:pl-32{padding-left:8rem}.sm\:pt-40{padding-top:10rem}.sm\:pr-40{padding-right:10rem}.sm\:pb-40{padding-bottom:10rem}.sm\:pl-40{padding-left:10rem}.sm\:pt-48{padding-top:12rem}.sm\:pr-48{padding-right:12rem}.sm\:pb-48{padding-bottom:12rem}.sm\:pl-48{padding-left:12rem}.sm\:pt-56{padding-top:14rem}.sm\:pr-56{padding-right:14rem}.sm\:pb-56{padding-bottom:14rem}.sm\:pl-56{padding-left:14rem}.sm\:pt-64{padding-top:16rem}.sm\:pr-64{padding-right:16rem}.sm\:pb-64{padding-bottom:16rem}.sm\:pl-64{padding-left:16rem}.sm\:pt-px{padding-top:1px}.sm\:pr-px{padding-right:1px}.sm\:pb-px{padding-bottom:1px}.sm\:pl-px{padding-left:1px}.sm\:placeholder-transparent:-ms-input-placeholder{color:transparent}.sm\:placeholder-transparent::-ms-input-placeholder{color:transparent}.sm\:placeholder-transparent::placeholder{color:transparent}.sm\:placeholder-current:-ms-input-placeholder{color:currentColor}.sm\:placeholder-current::-ms-input-placeholder{color:currentColor}.sm\:placeholder-current::placeholder{color:currentColor}.sm\:placeholder-black:-ms-input-placeholder{--placeholder-opacity:1;color:#000;color:rgba(0,0,0,var(--placeholder-opacity))}.sm\:placeholder-black::-ms-input-placeholder{--placeholder-opacity:1;color:#000;color:rgba(0,0,0,var(--placeholder-opacity))}.sm\:placeholder-black::placeholder{--placeholder-opacity:1;color:#000;color:rgba(0,0,0,var(--placeholder-opacity))}.sm\:placeholder-white:-ms-input-placeholder{--placeholder-opacity:1;color:#fff;color:rgba(255,255,255,var(--placeholder-opacity))}.sm\:placeholder-white::-ms-input-placeholder{--placeholder-opacity:1;color:#fff;color:rgba(255,255,255,var(--placeholder-opacity))}.sm\:placeholder-white::placeholder{--placeholder-opacity:1;color:#fff;color:rgba(255,255,255,var(--placeholder-opacity))}.sm\:placeholder-gray-100:-ms-input-placeholder{--placeholder-opacity:1;color:#f7fafc;color:rgba(247,250,252,var(--placeholder-opacity))}.sm\:placeholder-gray-100::-ms-input-placeholder{--placeholder-opacity:1;color:#f7fafc;color:rgba(247,250,252,var(--placeholder-opacity))}.sm\:placeholder-gray-100::placeholder{--placeholder-opacity:1;color:#f7fafc;color:rgba(247,250,252,var(--placeholder-opacity))}.sm\:placeholder-gray-200:-ms-input-placeholder{--placeholder-opacity:1;color:#edf2f7;color:rgba(237,242,247,var(--placeholder-opacity))}.sm\:placeholder-gray-200::-ms-input-placeholder{--placeholder-opacity:1;color:#edf2f7;color:rgba(237,242,247,var(--placeholder-opacity))}.sm\:placeholder-gray-200::placeholder{--placeholder-opacity:1;color:#edf2f7;color:rgba(237,242,247,var(--placeholder-opacity))}.sm\:placeholder-gray-300:-ms-input-placeholder{--placeholder-opacity:1;color:#e2e8f0;color:rgba(226,232,240,var(--placeholder-opacity))}.sm\:placeholder-gray-300::-ms-input-placeholder{--placeholder-opacity:1;color:#e2e8f0;color:rgba(226,232,240,var(--placeholder-opacity))}.sm\:placeholder-gray-300::placeholder{--placeholder-opacity:1;color:#e2e8f0;color:rgba(226,232,240,var(--placeholder-opacity))}.sm\:placeholder-gray-400:-ms-input-placeholder{--placeholder-opacity:1;color:#cbd5e0;color:rgba(203,213,224,var(--placeholder-opacity))}.sm\:placeholder-gray-400::-ms-input-placeholder{--placeholder-opacity:1;color:#cbd5e0;color:rgba(203,213,224,var(--placeholder-opacity))}.sm\:placeholder-gray-400::placeholder{--placeholder-opacity:1;color:#cbd5e0;color:rgba(203,213,224,var(--placeholder-opacity))}.sm\:placeholder-gray-500:-ms-input-placeholder{--placeholder-opacity:1;color:#a0aec0;color:rgba(160,174,192,var(--placeholder-opacity))}.sm\:placeholder-gray-500::-ms-input-placeholder{--placeholder-opacity:1;color:#a0aec0;color:rgba(160,174,192,var(--placeholder-opacity))}.sm\:placeholder-gray-500::placeholder{--placeholder-opacity:1;color:#a0aec0;color:rgba(160,174,192,var(--placeholder-opacity))}.sm\:placeholder-gray-600:-ms-input-placeholder{--placeholder-opacity:1;color:#718096;color:rgba(113,128,150,var(--placeholder-opacity))}.sm\:placeholder-gray-600::-ms-input-placeholder{--placeholder-opacity:1;color:#718096;color:rgba(113,128,150,var(--placeholder-opacity))}.sm\:placeholder-gray-600::placeholder{--placeholder-opacity:1;color:#718096;color:rgba(113,128,150,var(--placeholder-opacity))}.sm\:placeholder-gray-700:-ms-input-placeholder{--placeholder-opacity:1;color:#4a5568;color:rgba(74,85,104,var(--placeholder-opacity))}.sm\:placeholder-gray-700::-ms-input-placeholder{--placeholder-opacity:1;color:#4a5568;color:rgba(74,85,104,var(--placeholder-opacity))}.sm\:placeholder-gray-700::placeholder{--placeholder-opacity:1;color:#4a5568;color:rgba(74,85,104,var(--placeholder-opacity))}.sm\:placeholder-gray-800:-ms-input-placeholder{--placeholder-opacity:1;color:#2d3748;color:rgba(45,55,72,var(--placeholder-opacity))}.sm\:placeholder-gray-800::-ms-input-placeholder{--placeholder-opacity:1;color:#2d3748;color:rgba(45,55,72,var(--placeholder-opacity))}.sm\:placeholder-gray-800::placeholder{--placeholder-opacity:1;color:#2d3748;color:rgba(45,55,72,var(--placeholder-opacity))}.sm\:placeholder-gray-900:-ms-input-placeholder{--placeholder-opacity:1;color:#1a202c;color:rgba(26,32,44,var(--placeholder-opacity))}.sm\:placeholder-gray-900::-ms-input-placeholder{--placeholder-opacity:1;color:#1a202c;color:rgba(26,32,44,var(--placeholder-opacity))}.sm\:placeholder-gray-900::placeholder{--placeholder-opacity:1;color:#1a202c;color:rgba(26,32,44,var(--placeholder-opacity))}.sm\:placeholder-red-100:-ms-input-placeholder{--placeholder-opacity:1;color:#fff5f5;color:rgba(255,245,245,var(--placeholder-opacity))}.sm\:placeholder-red-100::-ms-input-placeholder{--placeholder-opacity:1;color:#fff5f5;color:rgba(255,245,245,var(--placeholder-opacity))}.sm\:placeholder-red-100::placeholder{--placeholder-opacity:1;color:#fff5f5;color:rgba(255,245,245,var(--placeholder-opacity))}.sm\:placeholder-red-200:-ms-input-placeholder{--placeholder-opacity:1;color:#fed7d7;color:rgba(254,215,215,var(--placeholder-opacity))}.sm\:placeholder-red-200::-ms-input-placeholder{--placeholder-opacity:1;color:#fed7d7;color:rgba(254,215,215,var(--placeholder-opacity))}.sm\:placeholder-red-200::placeholder{--placeholder-opacity:1;color:#fed7d7;color:rgba(254,215,215,var(--placeholder-opacity))}.sm\:placeholder-red-300:-ms-input-placeholder{--placeholder-opacity:1;color:#feb2b2;color:rgba(254,178,178,var(--placeholder-opacity))}.sm\:placeholder-red-300::-ms-input-placeholder{--placeholder-opacity:1;color:#feb2b2;color:rgba(254,178,178,var(--placeholder-opacity))}.sm\:placeholder-red-300::placeholder{--placeholder-opacity:1;color:#feb2b2;color:rgba(254,178,178,var(--placeholder-opacity))}.sm\:placeholder-red-400:-ms-input-placeholder{--placeholder-opacity:1;color:#fc8181;color:rgba(252,129,129,var(--placeholder-opacity))}.sm\:placeholder-red-400::-ms-input-placeholder{--placeholder-opacity:1;color:#fc8181;color:rgba(252,129,129,var(--placeholder-opacity))}.sm\:placeholder-red-400::placeholder{--placeholder-opacity:1;color:#fc8181;color:rgba(252,129,129,var(--placeholder-opacity))}.sm\:placeholder-red-500:-ms-input-placeholder{--placeholder-opacity:1;color:#f56565;color:rgba(245,101,101,var(--placeholder-opacity))}.sm\:placeholder-red-500::-ms-input-placeholder{--placeholder-opacity:1;color:#f56565;color:rgba(245,101,101,var(--placeholder-opacity))}.sm\:placeholder-red-500::placeholder{--placeholder-opacity:1;color:#f56565;color:rgba(245,101,101,var(--placeholder-opacity))}.sm\:placeholder-red-600:-ms-input-placeholder{--placeholder-opacity:1;color:#e53e3e;color:rgba(229,62,62,var(--placeholder-opacity))}.sm\:placeholder-red-600::-ms-input-placeholder{--placeholder-opacity:1;color:#e53e3e;color:rgba(229,62,62,var(--placeholder-opacity))}.sm\:placeholder-red-600::placeholder{--placeholder-opacity:1;color:#e53e3e;color:rgba(229,62,62,var(--placeholder-opacity))}.sm\:placeholder-red-700:-ms-input-placeholder{--placeholder-opacity:1;color:#c53030;color:rgba(197,48,48,var(--placeholder-opacity))}.sm\:placeholder-red-700::-ms-input-placeholder{--placeholder-opacity:1;color:#c53030;color:rgba(197,48,48,var(--placeholder-opacity))}.sm\:placeholder-red-700::placeholder{--placeholder-opacity:1;color:#c53030;color:rgba(197,48,48,var(--placeholder-opacity))}.sm\:placeholder-red-800:-ms-input-placeholder{--placeholder-opacity:1;color:#9b2c2c;color:rgba(155,44,44,var(--placeholder-opacity))}.sm\:placeholder-red-800::-ms-input-placeholder{--placeholder-opacity:1;color:#9b2c2c;color:rgba(155,44,44,var(--placeholder-opacity))}.sm\:placeholder-red-800::placeholder{--placeholder-opacity:1;color:#9b2c2c;color:rgba(155,44,44,var(--placeholder-opacity))}.sm\:placeholder-red-900:-ms-input-placeholder{--placeholder-opacity:1;color:#742a2a;color:rgba(116,42,42,var(--placeholder-opacity))}.sm\:placeholder-red-900::-ms-input-placeholder{--placeholder-opacity:1;color:#742a2a;color:rgba(116,42,42,var(--placeholder-opacity))}.sm\:placeholder-red-900::placeholder{--placeholder-opacity:1;color:#742a2a;color:rgba(116,42,42,var(--placeholder-opacity))}.sm\:placeholder-orange-100:-ms-input-placeholder{--placeholder-opacity:1;color:#fffaf0;color:rgba(255,250,240,var(--placeholder-opacity))}.sm\:placeholder-orange-100::-ms-input-placeholder{--placeholder-opacity:1;color:#fffaf0;color:rgba(255,250,240,var(--placeholder-opacity))}.sm\:placeholder-orange-100::placeholder{--placeholder-opacity:1;color:#fffaf0;color:rgba(255,250,240,var(--placeholder-opacity))}.sm\:placeholder-orange-200:-ms-input-placeholder{--placeholder-opacity:1;color:#feebc8;color:rgba(254,235,200,var(--placeholder-opacity))}.sm\:placeholder-orange-200::-ms-input-placeholder{--placeholder-opacity:1;color:#feebc8;color:rgba(254,235,200,var(--placeholder-opacity))}.sm\:placeholder-orange-200::placeholder{--placeholder-opacity:1;color:#feebc8;color:rgba(254,235,200,var(--placeholder-opacity))}.sm\:placeholder-orange-300:-ms-input-placeholder{--placeholder-opacity:1;color:#fbd38d;color:rgba(251,211,141,var(--placeholder-opacity))}.sm\:placeholder-orange-300::-ms-input-placeholder{--placeholder-opacity:1;color:#fbd38d;color:rgba(251,211,141,var(--placeholder-opacity))}.sm\:placeholder-orange-300::placeholder{--placeholder-opacity:1;color:#fbd38d;color:rgba(251,211,141,var(--placeholder-opacity))}.sm\:placeholder-orange-400:-ms-input-placeholder{--placeholder-opacity:1;color:#f6ad55;color:rgba(246,173,85,var(--placeholder-opacity))}.sm\:placeholder-orange-400::-ms-input-placeholder{--placeholder-opacity:1;color:#f6ad55;color:rgba(246,173,85,var(--placeholder-opacity))}.sm\:placeholder-orange-400::placeholder{--placeholder-opacity:1;color:#f6ad55;color:rgba(246,173,85,var(--placeholder-opacity))}.sm\:placeholder-orange-500:-ms-input-placeholder{--placeholder-opacity:1;color:#ed8936;color:rgba(237,137,54,var(--placeholder-opacity))}.sm\:placeholder-orange-500::-ms-input-placeholder{--placeholder-opacity:1;color:#ed8936;color:rgba(237,137,54,var(--placeholder-opacity))}.sm\:placeholder-orange-500::placeholder{--placeholder-opacity:1;color:#ed8936;color:rgba(237,137,54,var(--placeholder-opacity))}.sm\:placeholder-orange-600:-ms-input-placeholder{--placeholder-opacity:1;color:#dd6b20;color:rgba(221,107,32,var(--placeholder-opacity))}.sm\:placeholder-orange-600::-ms-input-placeholder{--placeholder-opacity:1;color:#dd6b20;color:rgba(221,107,32,var(--placeholder-opacity))}.sm\:placeholder-orange-600::placeholder{--placeholder-opacity:1;color:#dd6b20;color:rgba(221,107,32,var(--placeholder-opacity))}.sm\:placeholder-orange-700:-ms-input-placeholder{--placeholder-opacity:1;color:#c05621;color:rgba(192,86,33,var(--placeholder-opacity))}.sm\:placeholder-orange-700::-ms-input-placeholder{--placeholder-opacity:1;color:#c05621;color:rgba(192,86,33,var(--placeholder-opacity))}.sm\:placeholder-orange-700::placeholder{--placeholder-opacity:1;color:#c05621;color:rgba(192,86,33,var(--placeholder-opacity))}.sm\:placeholder-orange-800:-ms-input-placeholder{--placeholder-opacity:1;color:#9c4221;color:rgba(156,66,33,var(--placeholder-opacity))}.sm\:placeholder-orange-800::-ms-input-placeholder{--placeholder-opacity:1;color:#9c4221;color:rgba(156,66,33,var(--placeholder-opacity))}.sm\:placeholder-orange-800::placeholder{--placeholder-opacity:1;color:#9c4221;color:rgba(156,66,33,var(--placeholder-opacity))}.sm\:placeholder-orange-900:-ms-input-placeholder{--placeholder-opacity:1;color:#7b341e;color:rgba(123,52,30,var(--placeholder-opacity))}.sm\:placeholder-orange-900::-ms-input-placeholder{--placeholder-opacity:1;color:#7b341e;color:rgba(123,52,30,var(--placeholder-opacity))}.sm\:placeholder-orange-900::placeholder{--placeholder-opacity:1;color:#7b341e;color:rgba(123,52,30,var(--placeholder-opacity))}.sm\:placeholder-yellow-100:-ms-input-placeholder{--placeholder-opacity:1;color:ivory;color:rgba(255,255,240,var(--placeholder-opacity))}.sm\:placeholder-yellow-100::-ms-input-placeholder{--placeholder-opacity:1;color:ivory;color:rgba(255,255,240,var(--placeholder-opacity))}.sm\:placeholder-yellow-100::placeholder{--placeholder-opacity:1;color:ivory;color:rgba(255,255,240,var(--placeholder-opacity))}.sm\:placeholder-yellow-200:-ms-input-placeholder{--placeholder-opacity:1;color:#fefcbf;color:rgba(254,252,191,var(--placeholder-opacity))}.sm\:placeholder-yellow-200::-ms-input-placeholder{--placeholder-opacity:1;color:#fefcbf;color:rgba(254,252,191,var(--placeholder-opacity))}.sm\:placeholder-yellow-200::placeholder{--placeholder-opacity:1;color:#fefcbf;color:rgba(254,252,191,var(--placeholder-opacity))}.sm\:placeholder-yellow-300:-ms-input-placeholder{--placeholder-opacity:1;color:#faf089;color:rgba(250,240,137,var(--placeholder-opacity))}.sm\:placeholder-yellow-300::-ms-input-placeholder{--placeholder-opacity:1;color:#faf089;color:rgba(250,240,137,var(--placeholder-opacity))}.sm\:placeholder-yellow-300::placeholder{--placeholder-opacity:1;color:#faf089;color:rgba(250,240,137,var(--placeholder-opacity))}.sm\:placeholder-yellow-400:-ms-input-placeholder{--placeholder-opacity:1;color:#f6e05e;color:rgba(246,224,94,var(--placeholder-opacity))}.sm\:placeholder-yellow-400::-ms-input-placeholder{--placeholder-opacity:1;color:#f6e05e;color:rgba(246,224,94,var(--placeholder-opacity))}.sm\:placeholder-yellow-400::placeholder{--placeholder-opacity:1;color:#f6e05e;color:rgba(246,224,94,var(--placeholder-opacity))}.sm\:placeholder-yellow-500:-ms-input-placeholder{--placeholder-opacity:1;color:#ecc94b;color:rgba(236,201,75,var(--placeholder-opacity))}.sm\:placeholder-yellow-500::-ms-input-placeholder{--placeholder-opacity:1;color:#ecc94b;color:rgba(236,201,75,var(--placeholder-opacity))}.sm\:placeholder-yellow-500::placeholder{--placeholder-opacity:1;color:#ecc94b;color:rgba(236,201,75,var(--placeholder-opacity))}.sm\:placeholder-yellow-600:-ms-input-placeholder{--placeholder-opacity:1;color:#d69e2e;color:rgba(214,158,46,var(--placeholder-opacity))}.sm\:placeholder-yellow-600::-ms-input-placeholder{--placeholder-opacity:1;color:#d69e2e;color:rgba(214,158,46,var(--placeholder-opacity))}.sm\:placeholder-yellow-600::placeholder{--placeholder-opacity:1;color:#d69e2e;color:rgba(214,158,46,var(--placeholder-opacity))}.sm\:placeholder-yellow-700:-ms-input-placeholder{--placeholder-opacity:1;color:#b7791f;color:rgba(183,121,31,var(--placeholder-opacity))}.sm\:placeholder-yellow-700::-ms-input-placeholder{--placeholder-opacity:1;color:#b7791f;color:rgba(183,121,31,var(--placeholder-opacity))}.sm\:placeholder-yellow-700::placeholder{--placeholder-opacity:1;color:#b7791f;color:rgba(183,121,31,var(--placeholder-opacity))}.sm\:placeholder-yellow-800:-ms-input-placeholder{--placeholder-opacity:1;color:#975a16;color:rgba(151,90,22,var(--placeholder-opacity))}.sm\:placeholder-yellow-800::-ms-input-placeholder{--placeholder-opacity:1;color:#975a16;color:rgba(151,90,22,var(--placeholder-opacity))}.sm\:placeholder-yellow-800::placeholder{--placeholder-opacity:1;color:#975a16;color:rgba(151,90,22,var(--placeholder-opacity))}.sm\:placeholder-yellow-900:-ms-input-placeholder{--placeholder-opacity:1;color:#744210;color:rgba(116,66,16,var(--placeholder-opacity))}.sm\:placeholder-yellow-900::-ms-input-placeholder{--placeholder-opacity:1;color:#744210;color:rgba(116,66,16,var(--placeholder-opacity))}.sm\:placeholder-yellow-900::placeholder{--placeholder-opacity:1;color:#744210;color:rgba(116,66,16,var(--placeholder-opacity))}.sm\:placeholder-green-100:-ms-input-placeholder{--placeholder-opacity:1;color:#f0fff4;color:rgba(240,255,244,var(--placeholder-opacity))}.sm\:placeholder-green-100::-ms-input-placeholder{--placeholder-opacity:1;color:#f0fff4;color:rgba(240,255,244,var(--placeholder-opacity))}.sm\:placeholder-green-100::placeholder{--placeholder-opacity:1;color:#f0fff4;color:rgba(240,255,244,var(--placeholder-opacity))}.sm\:placeholder-green-200:-ms-input-placeholder{--placeholder-opacity:1;color:#c6f6d5;color:rgba(198,246,213,var(--placeholder-opacity))}.sm\:placeholder-green-200::-ms-input-placeholder{--placeholder-opacity:1;color:#c6f6d5;color:rgba(198,246,213,var(--placeholder-opacity))}.sm\:placeholder-green-200::placeholder{--placeholder-opacity:1;color:#c6f6d5;color:rgba(198,246,213,var(--placeholder-opacity))}.sm\:placeholder-green-300:-ms-input-placeholder{--placeholder-opacity:1;color:#9ae6b4;color:rgba(154,230,180,var(--placeholder-opacity))}.sm\:placeholder-green-300::-ms-input-placeholder{--placeholder-opacity:1;color:#9ae6b4;color:rgba(154,230,180,var(--placeholder-opacity))}.sm\:placeholder-green-300::placeholder{--placeholder-opacity:1;color:#9ae6b4;color:rgba(154,230,180,var(--placeholder-opacity))}.sm\:placeholder-green-400:-ms-input-placeholder{--placeholder-opacity:1;color:#68d391;color:rgba(104,211,145,var(--placeholder-opacity))}.sm\:placeholder-green-400::-ms-input-placeholder{--placeholder-opacity:1;color:#68d391;color:rgba(104,211,145,var(--placeholder-opacity))}.sm\:placeholder-green-400::placeholder{--placeholder-opacity:1;color:#68d391;color:rgba(104,211,145,var(--placeholder-opacity))}.sm\:placeholder-green-500:-ms-input-placeholder{--placeholder-opacity:1;color:#48bb78;color:rgba(72,187,120,var(--placeholder-opacity))}.sm\:placeholder-green-500::-ms-input-placeholder{--placeholder-opacity:1;color:#48bb78;color:rgba(72,187,120,var(--placeholder-opacity))}.sm\:placeholder-green-500::placeholder{--placeholder-opacity:1;color:#48bb78;color:rgba(72,187,120,var(--placeholder-opacity))}.sm\:placeholder-green-600:-ms-input-placeholder{--placeholder-opacity:1;color:#38a169;color:rgba(56,161,105,var(--placeholder-opacity))}.sm\:placeholder-green-600::-ms-input-placeholder{--placeholder-opacity:1;color:#38a169;color:rgba(56,161,105,var(--placeholder-opacity))}.sm\:placeholder-green-600::placeholder{--placeholder-opacity:1;color:#38a169;color:rgba(56,161,105,var(--placeholder-opacity))}.sm\:placeholder-green-700:-ms-input-placeholder{--placeholder-opacity:1;color:#2f855a;color:rgba(47,133,90,var(--placeholder-opacity))}.sm\:placeholder-green-700::-ms-input-placeholder{--placeholder-opacity:1;color:#2f855a;color:rgba(47,133,90,var(--placeholder-opacity))}.sm\:placeholder-green-700::placeholder{--placeholder-opacity:1;color:#2f855a;color:rgba(47,133,90,var(--placeholder-opacity))}.sm\:placeholder-green-800:-ms-input-placeholder{--placeholder-opacity:1;color:#276749;color:rgba(39,103,73,var(--placeholder-opacity))}.sm\:placeholder-green-800::-ms-input-placeholder{--placeholder-opacity:1;color:#276749;color:rgba(39,103,73,var(--placeholder-opacity))}.sm\:placeholder-green-800::placeholder{--placeholder-opacity:1;color:#276749;color:rgba(39,103,73,var(--placeholder-opacity))}.sm\:placeholder-green-900:-ms-input-placeholder{--placeholder-opacity:1;color:#22543d;color:rgba(34,84,61,var(--placeholder-opacity))}.sm\:placeholder-green-900::-ms-input-placeholder{--placeholder-opacity:1;color:#22543d;color:rgba(34,84,61,var(--placeholder-opacity))}.sm\:placeholder-green-900::placeholder{--placeholder-opacity:1;color:#22543d;color:rgba(34,84,61,var(--placeholder-opacity))}.sm\:placeholder-teal-100:-ms-input-placeholder{--placeholder-opacity:1;color:#e6fffa;color:rgba(230,255,250,var(--placeholder-opacity))}.sm\:placeholder-teal-100::-ms-input-placeholder{--placeholder-opacity:1;color:#e6fffa;color:rgba(230,255,250,var(--placeholder-opacity))}.sm\:placeholder-teal-100::placeholder{--placeholder-opacity:1;color:#e6fffa;color:rgba(230,255,250,var(--placeholder-opacity))}.sm\:placeholder-teal-200:-ms-input-placeholder{--placeholder-opacity:1;color:#b2f5ea;color:rgba(178,245,234,var(--placeholder-opacity))}.sm\:placeholder-teal-200::-ms-input-placeholder{--placeholder-opacity:1;color:#b2f5ea;color:rgba(178,245,234,var(--placeholder-opacity))}.sm\:placeholder-teal-200::placeholder{--placeholder-opacity:1;color:#b2f5ea;color:rgba(178,245,234,var(--placeholder-opacity))}.sm\:placeholder-teal-300:-ms-input-placeholder{--placeholder-opacity:1;color:#81e6d9;color:rgba(129,230,217,var(--placeholder-opacity))}.sm\:placeholder-teal-300::-ms-input-placeholder{--placeholder-opacity:1;color:#81e6d9;color:rgba(129,230,217,var(--placeholder-opacity))}.sm\:placeholder-teal-300::placeholder{--placeholder-opacity:1;color:#81e6d9;color:rgba(129,230,217,var(--placeholder-opacity))}.sm\:placeholder-teal-400:-ms-input-placeholder{--placeholder-opacity:1;color:#4fd1c5;color:rgba(79,209,197,var(--placeholder-opacity))}.sm\:placeholder-teal-400::-ms-input-placeholder{--placeholder-opacity:1;color:#4fd1c5;color:rgba(79,209,197,var(--placeholder-opacity))}.sm\:placeholder-teal-400::placeholder{--placeholder-opacity:1;color:#4fd1c5;color:rgba(79,209,197,var(--placeholder-opacity))}.sm\:placeholder-teal-500:-ms-input-placeholder{--placeholder-opacity:1;color:#38b2ac;color:rgba(56,178,172,var(--placeholder-opacity))}.sm\:placeholder-teal-500::-ms-input-placeholder{--placeholder-opacity:1;color:#38b2ac;color:rgba(56,178,172,var(--placeholder-opacity))}.sm\:placeholder-teal-500::placeholder{--placeholder-opacity:1;color:#38b2ac;color:rgba(56,178,172,var(--placeholder-opacity))}.sm\:placeholder-teal-600:-ms-input-placeholder{--placeholder-opacity:1;color:#319795;color:rgba(49,151,149,var(--placeholder-opacity))}.sm\:placeholder-teal-600::-ms-input-placeholder{--placeholder-opacity:1;color:#319795;color:rgba(49,151,149,var(--placeholder-opacity))}.sm\:placeholder-teal-600::placeholder{--placeholder-opacity:1;color:#319795;color:rgba(49,151,149,var(--placeholder-opacity))}.sm\:placeholder-teal-700:-ms-input-placeholder{--placeholder-opacity:1;color:#2c7a7b;color:rgba(44,122,123,var(--placeholder-opacity))}.sm\:placeholder-teal-700::-ms-input-placeholder{--placeholder-opacity:1;color:#2c7a7b;color:rgba(44,122,123,var(--placeholder-opacity))}.sm\:placeholder-teal-700::placeholder{--placeholder-opacity:1;color:#2c7a7b;color:rgba(44,122,123,var(--placeholder-opacity))}.sm\:placeholder-teal-800:-ms-input-placeholder{--placeholder-opacity:1;color:#285e61;color:rgba(40,94,97,var(--placeholder-opacity))}.sm\:placeholder-teal-800::-ms-input-placeholder{--placeholder-opacity:1;color:#285e61;color:rgba(40,94,97,var(--placeholder-opacity))}.sm\:placeholder-teal-800::placeholder{--placeholder-opacity:1;color:#285e61;color:rgba(40,94,97,var(--placeholder-opacity))}.sm\:placeholder-teal-900:-ms-input-placeholder{--placeholder-opacity:1;color:#234e52;color:rgba(35,78,82,var(--placeholder-opacity))}.sm\:placeholder-teal-900::-ms-input-placeholder{--placeholder-opacity:1;color:#234e52;color:rgba(35,78,82,var(--placeholder-opacity))}.sm\:placeholder-teal-900::placeholder{--placeholder-opacity:1;color:#234e52;color:rgba(35,78,82,var(--placeholder-opacity))}.sm\:placeholder-blue-100:-ms-input-placeholder{--placeholder-opacity:1;color:#ebf8ff;color:rgba(235,248,255,var(--placeholder-opacity))}.sm\:placeholder-blue-100::-ms-input-placeholder{--placeholder-opacity:1;color:#ebf8ff;color:rgba(235,248,255,var(--placeholder-opacity))}.sm\:placeholder-blue-100::placeholder{--placeholder-opacity:1;color:#ebf8ff;color:rgba(235,248,255,var(--placeholder-opacity))}.sm\:placeholder-blue-200:-ms-input-placeholder{--placeholder-opacity:1;color:#bee3f8;color:rgba(190,227,248,var(--placeholder-opacity))}.sm\:placeholder-blue-200::-ms-input-placeholder{--placeholder-opacity:1;color:#bee3f8;color:rgba(190,227,248,var(--placeholder-opacity))}.sm\:placeholder-blue-200::placeholder{--placeholder-opacity:1;color:#bee3f8;color:rgba(190,227,248,var(--placeholder-opacity))}.sm\:placeholder-blue-300:-ms-input-placeholder{--placeholder-opacity:1;color:#90cdf4;color:rgba(144,205,244,var(--placeholder-opacity))}.sm\:placeholder-blue-300::-ms-input-placeholder{--placeholder-opacity:1;color:#90cdf4;color:rgba(144,205,244,var(--placeholder-opacity))}.sm\:placeholder-blue-300::placeholder{--placeholder-opacity:1;color:#90cdf4;color:rgba(144,205,244,var(--placeholder-opacity))}.sm\:placeholder-blue-400:-ms-input-placeholder{--placeholder-opacity:1;color:#63b3ed;color:rgba(99,179,237,var(--placeholder-opacity))}.sm\:placeholder-blue-400::-ms-input-placeholder{--placeholder-opacity:1;color:#63b3ed;color:rgba(99,179,237,var(--placeholder-opacity))}.sm\:placeholder-blue-400::placeholder{--placeholder-opacity:1;color:#63b3ed;color:rgba(99,179,237,var(--placeholder-opacity))}.sm\:placeholder-blue-500:-ms-input-placeholder{--placeholder-opacity:1;color:#4299e1;color:rgba(66,153,225,var(--placeholder-opacity))}.sm\:placeholder-blue-500::-ms-input-placeholder{--placeholder-opacity:1;color:#4299e1;color:rgba(66,153,225,var(--placeholder-opacity))}.sm\:placeholder-blue-500::placeholder{--placeholder-opacity:1;color:#4299e1;color:rgba(66,153,225,var(--placeholder-opacity))}.sm\:placeholder-blue-600:-ms-input-placeholder{--placeholder-opacity:1;color:#3182ce;color:rgba(49,130,206,var(--placeholder-opacity))}.sm\:placeholder-blue-600::-ms-input-placeholder{--placeholder-opacity:1;color:#3182ce;color:rgba(49,130,206,var(--placeholder-opacity))}.sm\:placeholder-blue-600::placeholder{--placeholder-opacity:1;color:#3182ce;color:rgba(49,130,206,var(--placeholder-opacity))}.sm\:placeholder-blue-700:-ms-input-placeholder{--placeholder-opacity:1;color:#2b6cb0;color:rgba(43,108,176,var(--placeholder-opacity))}.sm\:placeholder-blue-700::-ms-input-placeholder{--placeholder-opacity:1;color:#2b6cb0;color:rgba(43,108,176,var(--placeholder-opacity))}.sm\:placeholder-blue-700::placeholder{--placeholder-opacity:1;color:#2b6cb0;color:rgba(43,108,176,var(--placeholder-opacity))}.sm\:placeholder-blue-800:-ms-input-placeholder{--placeholder-opacity:1;color:#2c5282;color:rgba(44,82,130,var(--placeholder-opacity))}.sm\:placeholder-blue-800::-ms-input-placeholder{--placeholder-opacity:1;color:#2c5282;color:rgba(44,82,130,var(--placeholder-opacity))}.sm\:placeholder-blue-800::placeholder{--placeholder-opacity:1;color:#2c5282;color:rgba(44,82,130,var(--placeholder-opacity))}.sm\:placeholder-blue-900:-ms-input-placeholder{--placeholder-opacity:1;color:#2a4365;color:rgba(42,67,101,var(--placeholder-opacity))}.sm\:placeholder-blue-900::-ms-input-placeholder{--placeholder-opacity:1;color:#2a4365;color:rgba(42,67,101,var(--placeholder-opacity))}.sm\:placeholder-blue-900::placeholder{--placeholder-opacity:1;color:#2a4365;color:rgba(42,67,101,var(--placeholder-opacity))}.sm\:placeholder-indigo-100:-ms-input-placeholder{--placeholder-opacity:1;color:#ebf4ff;color:rgba(235,244,255,var(--placeholder-opacity))}.sm\:placeholder-indigo-100::-ms-input-placeholder{--placeholder-opacity:1;color:#ebf4ff;color:rgba(235,244,255,var(--placeholder-opacity))}.sm\:placeholder-indigo-100::placeholder{--placeholder-opacity:1;color:#ebf4ff;color:rgba(235,244,255,var(--placeholder-opacity))}.sm\:placeholder-indigo-200:-ms-input-placeholder{--placeholder-opacity:1;color:#c3dafe;color:rgba(195,218,254,var(--placeholder-opacity))}.sm\:placeholder-indigo-200::-ms-input-placeholder{--placeholder-opacity:1;color:#c3dafe;color:rgba(195,218,254,var(--placeholder-opacity))}.sm\:placeholder-indigo-200::placeholder{--placeholder-opacity:1;color:#c3dafe;color:rgba(195,218,254,var(--placeholder-opacity))}.sm\:placeholder-indigo-300:-ms-input-placeholder{--placeholder-opacity:1;color:#a3bffa;color:rgba(163,191,250,var(--placeholder-opacity))}.sm\:placeholder-indigo-300::-ms-input-placeholder{--placeholder-opacity:1;color:#a3bffa;color:rgba(163,191,250,var(--placeholder-opacity))}.sm\:placeholder-indigo-300::placeholder{--placeholder-opacity:1;color:#a3bffa;color:rgba(163,191,250,var(--placeholder-opacity))}.sm\:placeholder-indigo-400:-ms-input-placeholder{--placeholder-opacity:1;color:#7f9cf5;color:rgba(127,156,245,var(--placeholder-opacity))}.sm\:placeholder-indigo-400::-ms-input-placeholder{--placeholder-opacity:1;color:#7f9cf5;color:rgba(127,156,245,var(--placeholder-opacity))}.sm\:placeholder-indigo-400::placeholder{--placeholder-opacity:1;color:#7f9cf5;color:rgba(127,156,245,var(--placeholder-opacity))}.sm\:placeholder-indigo-500:-ms-input-placeholder{--placeholder-opacity:1;color:#667eea;color:rgba(102,126,234,var(--placeholder-opacity))}.sm\:placeholder-indigo-500::-ms-input-placeholder{--placeholder-opacity:1;color:#667eea;color:rgba(102,126,234,var(--placeholder-opacity))}.sm\:placeholder-indigo-500::placeholder{--placeholder-opacity:1;color:#667eea;color:rgba(102,126,234,var(--placeholder-opacity))}.sm\:placeholder-indigo-600:-ms-input-placeholder{--placeholder-opacity:1;color:#5a67d8;color:rgba(90,103,216,var(--placeholder-opacity))}.sm\:placeholder-indigo-600::-ms-input-placeholder{--placeholder-opacity:1;color:#5a67d8;color:rgba(90,103,216,var(--placeholder-opacity))}.sm\:placeholder-indigo-600::placeholder{--placeholder-opacity:1;color:#5a67d8;color:rgba(90,103,216,var(--placeholder-opacity))}.sm\:placeholder-indigo-700:-ms-input-placeholder{--placeholder-opacity:1;color:#4c51bf;color:rgba(76,81,191,var(--placeholder-opacity))}.sm\:placeholder-indigo-700::-ms-input-placeholder{--placeholder-opacity:1;color:#4c51bf;color:rgba(76,81,191,var(--placeholder-opacity))}.sm\:placeholder-indigo-700::placeholder{--placeholder-opacity:1;color:#4c51bf;color:rgba(76,81,191,var(--placeholder-opacity))}.sm\:placeholder-indigo-800:-ms-input-placeholder{--placeholder-opacity:1;color:#434190;color:rgba(67,65,144,var(--placeholder-opacity))}.sm\:placeholder-indigo-800::-ms-input-placeholder{--placeholder-opacity:1;color:#434190;color:rgba(67,65,144,var(--placeholder-opacity))}.sm\:placeholder-indigo-800::placeholder{--placeholder-opacity:1;color:#434190;color:rgba(67,65,144,var(--placeholder-opacity))}.sm\:placeholder-indigo-900:-ms-input-placeholder{--placeholder-opacity:1;color:#3c366b;color:rgba(60,54,107,var(--placeholder-opacity))}.sm\:placeholder-indigo-900::-ms-input-placeholder{--placeholder-opacity:1;color:#3c366b;color:rgba(60,54,107,var(--placeholder-opacity))}.sm\:placeholder-indigo-900::placeholder{--placeholder-opacity:1;color:#3c366b;color:rgba(60,54,107,var(--placeholder-opacity))}.sm\:placeholder-purple-100:-ms-input-placeholder{--placeholder-opacity:1;color:#faf5ff;color:rgba(250,245,255,var(--placeholder-opacity))}.sm\:placeholder-purple-100::-ms-input-placeholder{--placeholder-opacity:1;color:#faf5ff;color:rgba(250,245,255,var(--placeholder-opacity))}.sm\:placeholder-purple-100::placeholder{--placeholder-opacity:1;color:#faf5ff;color:rgba(250,245,255,var(--placeholder-opacity))}.sm\:placeholder-purple-200:-ms-input-placeholder{--placeholder-opacity:1;color:#e9d8fd;color:rgba(233,216,253,var(--placeholder-opacity))}.sm\:placeholder-purple-200::-ms-input-placeholder{--placeholder-opacity:1;color:#e9d8fd;color:rgba(233,216,253,var(--placeholder-opacity))}.sm\:placeholder-purple-200::placeholder{--placeholder-opacity:1;color:#e9d8fd;color:rgba(233,216,253,var(--placeholder-opacity))}.sm\:placeholder-purple-300:-ms-input-placeholder{--placeholder-opacity:1;color:#d6bcfa;color:rgba(214,188,250,var(--placeholder-opacity))}.sm\:placeholder-purple-300::-ms-input-placeholder{--placeholder-opacity:1;color:#d6bcfa;color:rgba(214,188,250,var(--placeholder-opacity))}.sm\:placeholder-purple-300::placeholder{--placeholder-opacity:1;color:#d6bcfa;color:rgba(214,188,250,var(--placeholder-opacity))}.sm\:placeholder-purple-400:-ms-input-placeholder{--placeholder-opacity:1;color:#b794f4;color:rgba(183,148,244,var(--placeholder-opacity))}.sm\:placeholder-purple-400::-ms-input-placeholder{--placeholder-opacity:1;color:#b794f4;color:rgba(183,148,244,var(--placeholder-opacity))}.sm\:placeholder-purple-400::placeholder{--placeholder-opacity:1;color:#b794f4;color:rgba(183,148,244,var(--placeholder-opacity))}.sm\:placeholder-purple-500:-ms-input-placeholder{--placeholder-opacity:1;color:#9f7aea;color:rgba(159,122,234,var(--placeholder-opacity))}.sm\:placeholder-purple-500::-ms-input-placeholder{--placeholder-opacity:1;color:#9f7aea;color:rgba(159,122,234,var(--placeholder-opacity))}.sm\:placeholder-purple-500::placeholder{--placeholder-opacity:1;color:#9f7aea;color:rgba(159,122,234,var(--placeholder-opacity))}.sm\:placeholder-purple-600:-ms-input-placeholder{--placeholder-opacity:1;color:#805ad5;color:rgba(128,90,213,var(--placeholder-opacity))}.sm\:placeholder-purple-600::-ms-input-placeholder{--placeholder-opacity:1;color:#805ad5;color:rgba(128,90,213,var(--placeholder-opacity))}.sm\:placeholder-purple-600::placeholder{--placeholder-opacity:1;color:#805ad5;color:rgba(128,90,213,var(--placeholder-opacity))}.sm\:placeholder-purple-700:-ms-input-placeholder{--placeholder-opacity:1;color:#6b46c1;color:rgba(107,70,193,var(--placeholder-opacity))}.sm\:placeholder-purple-700::-ms-input-placeholder{--placeholder-opacity:1;color:#6b46c1;color:rgba(107,70,193,var(--placeholder-opacity))}.sm\:placeholder-purple-700::placeholder{--placeholder-opacity:1;color:#6b46c1;color:rgba(107,70,193,var(--placeholder-opacity))}.sm\:placeholder-purple-800:-ms-input-placeholder{--placeholder-opacity:1;color:#553c9a;color:rgba(85,60,154,var(--placeholder-opacity))}.sm\:placeholder-purple-800::-ms-input-placeholder{--placeholder-opacity:1;color:#553c9a;color:rgba(85,60,154,var(--placeholder-opacity))}.sm\:placeholder-purple-800::placeholder{--placeholder-opacity:1;color:#553c9a;color:rgba(85,60,154,var(--placeholder-opacity))}.sm\:placeholder-purple-900:-ms-input-placeholder{--placeholder-opacity:1;color:#44337a;color:rgba(68,51,122,var(--placeholder-opacity))}.sm\:placeholder-purple-900::-ms-input-placeholder{--placeholder-opacity:1;color:#44337a;color:rgba(68,51,122,var(--placeholder-opacity))}.sm\:placeholder-purple-900::placeholder{--placeholder-opacity:1;color:#44337a;color:rgba(68,51,122,var(--placeholder-opacity))}.sm\:placeholder-pink-100:-ms-input-placeholder{--placeholder-opacity:1;color:#fff5f7;color:rgba(255,245,247,var(--placeholder-opacity))}.sm\:placeholder-pink-100::-ms-input-placeholder{--placeholder-opacity:1;color:#fff5f7;color:rgba(255,245,247,var(--placeholder-opacity))}.sm\:placeholder-pink-100::placeholder{--placeholder-opacity:1;color:#fff5f7;color:rgba(255,245,247,var(--placeholder-opacity))}.sm\:placeholder-pink-200:-ms-input-placeholder{--placeholder-opacity:1;color:#fed7e2;color:rgba(254,215,226,var(--placeholder-opacity))}.sm\:placeholder-pink-200::-ms-input-placeholder{--placeholder-opacity:1;color:#fed7e2;color:rgba(254,215,226,var(--placeholder-opacity))}.sm\:placeholder-pink-200::placeholder{--placeholder-opacity:1;color:#fed7e2;color:rgba(254,215,226,var(--placeholder-opacity))}.sm\:placeholder-pink-300:-ms-input-placeholder{--placeholder-opacity:1;color:#fbb6ce;color:rgba(251,182,206,var(--placeholder-opacity))}.sm\:placeholder-pink-300::-ms-input-placeholder{--placeholder-opacity:1;color:#fbb6ce;color:rgba(251,182,206,var(--placeholder-opacity))}.sm\:placeholder-pink-300::placeholder{--placeholder-opacity:1;color:#fbb6ce;color:rgba(251,182,206,var(--placeholder-opacity))}.sm\:placeholder-pink-400:-ms-input-placeholder{--placeholder-opacity:1;color:#f687b3;color:rgba(246,135,179,var(--placeholder-opacity))}.sm\:placeholder-pink-400::-ms-input-placeholder{--placeholder-opacity:1;color:#f687b3;color:rgba(246,135,179,var(--placeholder-opacity))}.sm\:placeholder-pink-400::placeholder{--placeholder-opacity:1;color:#f687b3;color:rgba(246,135,179,var(--placeholder-opacity))}.sm\:placeholder-pink-500:-ms-input-placeholder{--placeholder-opacity:1;color:#ed64a6;color:rgba(237,100,166,var(--placeholder-opacity))}.sm\:placeholder-pink-500::-ms-input-placeholder{--placeholder-opacity:1;color:#ed64a6;color:rgba(237,100,166,var(--placeholder-opacity))}.sm\:placeholder-pink-500::placeholder{--placeholder-opacity:1;color:#ed64a6;color:rgba(237,100,166,var(--placeholder-opacity))}.sm\:placeholder-pink-600:-ms-input-placeholder{--placeholder-opacity:1;color:#d53f8c;color:rgba(213,63,140,var(--placeholder-opacity))}.sm\:placeholder-pink-600::-ms-input-placeholder{--placeholder-opacity:1;color:#d53f8c;color:rgba(213,63,140,var(--placeholder-opacity))}.sm\:placeholder-pink-600::placeholder{--placeholder-opacity:1;color:#d53f8c;color:rgba(213,63,140,var(--placeholder-opacity))}.sm\:placeholder-pink-700:-ms-input-placeholder{--placeholder-opacity:1;color:#b83280;color:rgba(184,50,128,var(--placeholder-opacity))}.sm\:placeholder-pink-700::-ms-input-placeholder{--placeholder-opacity:1;color:#b83280;color:rgba(184,50,128,var(--placeholder-opacity))}.sm\:placeholder-pink-700::placeholder{--placeholder-opacity:1;color:#b83280;color:rgba(184,50,128,var(--placeholder-opacity))}.sm\:placeholder-pink-800:-ms-input-placeholder{--placeholder-opacity:1;color:#97266d;color:rgba(151,38,109,var(--placeholder-opacity))}.sm\:placeholder-pink-800::-ms-input-placeholder{--placeholder-opacity:1;color:#97266d;color:rgba(151,38,109,var(--placeholder-opacity))}.sm\:placeholder-pink-800::placeholder{--placeholder-opacity:1;color:#97266d;color:rgba(151,38,109,var(--placeholder-opacity))}.sm\:placeholder-pink-900:-ms-input-placeholder{--placeholder-opacity:1;color:#702459;color:rgba(112,36,89,var(--placeholder-opacity))}.sm\:placeholder-pink-900::-ms-input-placeholder{--placeholder-opacity:1;color:#702459;color:rgba(112,36,89,var(--placeholder-opacity))}.sm\:placeholder-pink-900::placeholder{--placeholder-opacity:1;color:#702459;color:rgba(112,36,89,var(--placeholder-opacity))}.sm\:focus\:placeholder-transparent:focus:-ms-input-placeholder{color:transparent}.sm\:focus\:placeholder-transparent:focus::-ms-input-placeholder{color:transparent}.sm\:focus\:placeholder-transparent:focus::placeholder{color:transparent}.sm\:focus\:placeholder-current:focus:-ms-input-placeholder{color:currentColor}.sm\:focus\:placeholder-current:focus::-ms-input-placeholder{color:currentColor}.sm\:focus\:placeholder-current:focus::placeholder{color:currentColor}.sm\:focus\:placeholder-black:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#000;color:rgba(0,0,0,var(--placeholder-opacity))}.sm\:focus\:placeholder-black:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#000;color:rgba(0,0,0,var(--placeholder-opacity))}.sm\:focus\:placeholder-black:focus::placeholder{--placeholder-opacity:1;color:#000;color:rgba(0,0,0,var(--placeholder-opacity))}.sm\:focus\:placeholder-white:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#fff;color:rgba(255,255,255,var(--placeholder-opacity))}.sm\:focus\:placeholder-white:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#fff;color:rgba(255,255,255,var(--placeholder-opacity))}.sm\:focus\:placeholder-white:focus::placeholder{--placeholder-opacity:1;color:#fff;color:rgba(255,255,255,var(--placeholder-opacity))}.sm\:focus\:placeholder-gray-100:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#f7fafc;color:rgba(247,250,252,var(--placeholder-opacity))}.sm\:focus\:placeholder-gray-100:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#f7fafc;color:rgba(247,250,252,var(--placeholder-opacity))}.sm\:focus\:placeholder-gray-100:focus::placeholder{--placeholder-opacity:1;color:#f7fafc;color:rgba(247,250,252,var(--placeholder-opacity))}.sm\:focus\:placeholder-gray-200:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#edf2f7;color:rgba(237,242,247,var(--placeholder-opacity))}.sm\:focus\:placeholder-gray-200:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#edf2f7;color:rgba(237,242,247,var(--placeholder-opacity))}.sm\:focus\:placeholder-gray-200:focus::placeholder{--placeholder-opacity:1;color:#edf2f7;color:rgba(237,242,247,var(--placeholder-opacity))}.sm\:focus\:placeholder-gray-300:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#e2e8f0;color:rgba(226,232,240,var(--placeholder-opacity))}.sm\:focus\:placeholder-gray-300:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#e2e8f0;color:rgba(226,232,240,var(--placeholder-opacity))}.sm\:focus\:placeholder-gray-300:focus::placeholder{--placeholder-opacity:1;color:#e2e8f0;color:rgba(226,232,240,var(--placeholder-opacity))}.sm\:focus\:placeholder-gray-400:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#cbd5e0;color:rgba(203,213,224,var(--placeholder-opacity))}.sm\:focus\:placeholder-gray-400:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#cbd5e0;color:rgba(203,213,224,var(--placeholder-opacity))}.sm\:focus\:placeholder-gray-400:focus::placeholder{--placeholder-opacity:1;color:#cbd5e0;color:rgba(203,213,224,var(--placeholder-opacity))}.sm\:focus\:placeholder-gray-500:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#a0aec0;color:rgba(160,174,192,var(--placeholder-opacity))}.sm\:focus\:placeholder-gray-500:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#a0aec0;color:rgba(160,174,192,var(--placeholder-opacity))}.sm\:focus\:placeholder-gray-500:focus::placeholder{--placeholder-opacity:1;color:#a0aec0;color:rgba(160,174,192,var(--placeholder-opacity))}.sm\:focus\:placeholder-gray-600:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#718096;color:rgba(113,128,150,var(--placeholder-opacity))}.sm\:focus\:placeholder-gray-600:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#718096;color:rgba(113,128,150,var(--placeholder-opacity))}.sm\:focus\:placeholder-gray-600:focus::placeholder{--placeholder-opacity:1;color:#718096;color:rgba(113,128,150,var(--placeholder-opacity))}.sm\:focus\:placeholder-gray-700:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#4a5568;color:rgba(74,85,104,var(--placeholder-opacity))}.sm\:focus\:placeholder-gray-700:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#4a5568;color:rgba(74,85,104,var(--placeholder-opacity))}.sm\:focus\:placeholder-gray-700:focus::placeholder{--placeholder-opacity:1;color:#4a5568;color:rgba(74,85,104,var(--placeholder-opacity))}.sm\:focus\:placeholder-gray-800:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#2d3748;color:rgba(45,55,72,var(--placeholder-opacity))}.sm\:focus\:placeholder-gray-800:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#2d3748;color:rgba(45,55,72,var(--placeholder-opacity))}.sm\:focus\:placeholder-gray-800:focus::placeholder{--placeholder-opacity:1;color:#2d3748;color:rgba(45,55,72,var(--placeholder-opacity))}.sm\:focus\:placeholder-gray-900:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#1a202c;color:rgba(26,32,44,var(--placeholder-opacity))}.sm\:focus\:placeholder-gray-900:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#1a202c;color:rgba(26,32,44,var(--placeholder-opacity))}.sm\:focus\:placeholder-gray-900:focus::placeholder{--placeholder-opacity:1;color:#1a202c;color:rgba(26,32,44,var(--placeholder-opacity))}.sm\:focus\:placeholder-red-100:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#fff5f5;color:rgba(255,245,245,var(--placeholder-opacity))}.sm\:focus\:placeholder-red-100:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#fff5f5;color:rgba(255,245,245,var(--placeholder-opacity))}.sm\:focus\:placeholder-red-100:focus::placeholder{--placeholder-opacity:1;color:#fff5f5;color:rgba(255,245,245,var(--placeholder-opacity))}.sm\:focus\:placeholder-red-200:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#fed7d7;color:rgba(254,215,215,var(--placeholder-opacity))}.sm\:focus\:placeholder-red-200:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#fed7d7;color:rgba(254,215,215,var(--placeholder-opacity))}.sm\:focus\:placeholder-red-200:focus::placeholder{--placeholder-opacity:1;color:#fed7d7;color:rgba(254,215,215,var(--placeholder-opacity))}.sm\:focus\:placeholder-red-300:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#feb2b2;color:rgba(254,178,178,var(--placeholder-opacity))}.sm\:focus\:placeholder-red-300:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#feb2b2;color:rgba(254,178,178,var(--placeholder-opacity))}.sm\:focus\:placeholder-red-300:focus::placeholder{--placeholder-opacity:1;color:#feb2b2;color:rgba(254,178,178,var(--placeholder-opacity))}.sm\:focus\:placeholder-red-400:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#fc8181;color:rgba(252,129,129,var(--placeholder-opacity))}.sm\:focus\:placeholder-red-400:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#fc8181;color:rgba(252,129,129,var(--placeholder-opacity))}.sm\:focus\:placeholder-red-400:focus::placeholder{--placeholder-opacity:1;color:#fc8181;color:rgba(252,129,129,var(--placeholder-opacity))}.sm\:focus\:placeholder-red-500:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#f56565;color:rgba(245,101,101,var(--placeholder-opacity))}.sm\:focus\:placeholder-red-500:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#f56565;color:rgba(245,101,101,var(--placeholder-opacity))}.sm\:focus\:placeholder-red-500:focus::placeholder{--placeholder-opacity:1;color:#f56565;color:rgba(245,101,101,var(--placeholder-opacity))}.sm\:focus\:placeholder-red-600:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#e53e3e;color:rgba(229,62,62,var(--placeholder-opacity))}.sm\:focus\:placeholder-red-600:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#e53e3e;color:rgba(229,62,62,var(--placeholder-opacity))}.sm\:focus\:placeholder-red-600:focus::placeholder{--placeholder-opacity:1;color:#e53e3e;color:rgba(229,62,62,var(--placeholder-opacity))}.sm\:focus\:placeholder-red-700:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#c53030;color:rgba(197,48,48,var(--placeholder-opacity))}.sm\:focus\:placeholder-red-700:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#c53030;color:rgba(197,48,48,var(--placeholder-opacity))}.sm\:focus\:placeholder-red-700:focus::placeholder{--placeholder-opacity:1;color:#c53030;color:rgba(197,48,48,var(--placeholder-opacity))}.sm\:focus\:placeholder-red-800:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#9b2c2c;color:rgba(155,44,44,var(--placeholder-opacity))}.sm\:focus\:placeholder-red-800:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#9b2c2c;color:rgba(155,44,44,var(--placeholder-opacity))}.sm\:focus\:placeholder-red-800:focus::placeholder{--placeholder-opacity:1;color:#9b2c2c;color:rgba(155,44,44,var(--placeholder-opacity))}.sm\:focus\:placeholder-red-900:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#742a2a;color:rgba(116,42,42,var(--placeholder-opacity))}.sm\:focus\:placeholder-red-900:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#742a2a;color:rgba(116,42,42,var(--placeholder-opacity))}.sm\:focus\:placeholder-red-900:focus::placeholder{--placeholder-opacity:1;color:#742a2a;color:rgba(116,42,42,var(--placeholder-opacity))}.sm\:focus\:placeholder-orange-100:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#fffaf0;color:rgba(255,250,240,var(--placeholder-opacity))}.sm\:focus\:placeholder-orange-100:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#fffaf0;color:rgba(255,250,240,var(--placeholder-opacity))}.sm\:focus\:placeholder-orange-100:focus::placeholder{--placeholder-opacity:1;color:#fffaf0;color:rgba(255,250,240,var(--placeholder-opacity))}.sm\:focus\:placeholder-orange-200:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#feebc8;color:rgba(254,235,200,var(--placeholder-opacity))}.sm\:focus\:placeholder-orange-200:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#feebc8;color:rgba(254,235,200,var(--placeholder-opacity))}.sm\:focus\:placeholder-orange-200:focus::placeholder{--placeholder-opacity:1;color:#feebc8;color:rgba(254,235,200,var(--placeholder-opacity))}.sm\:focus\:placeholder-orange-300:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#fbd38d;color:rgba(251,211,141,var(--placeholder-opacity))}.sm\:focus\:placeholder-orange-300:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#fbd38d;color:rgba(251,211,141,var(--placeholder-opacity))}.sm\:focus\:placeholder-orange-300:focus::placeholder{--placeholder-opacity:1;color:#fbd38d;color:rgba(251,211,141,var(--placeholder-opacity))}.sm\:focus\:placeholder-orange-400:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#f6ad55;color:rgba(246,173,85,var(--placeholder-opacity))}.sm\:focus\:placeholder-orange-400:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#f6ad55;color:rgba(246,173,85,var(--placeholder-opacity))}.sm\:focus\:placeholder-orange-400:focus::placeholder{--placeholder-opacity:1;color:#f6ad55;color:rgba(246,173,85,var(--placeholder-opacity))}.sm\:focus\:placeholder-orange-500:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#ed8936;color:rgba(237,137,54,var(--placeholder-opacity))}.sm\:focus\:placeholder-orange-500:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#ed8936;color:rgba(237,137,54,var(--placeholder-opacity))}.sm\:focus\:placeholder-orange-500:focus::placeholder{--placeholder-opacity:1;color:#ed8936;color:rgba(237,137,54,var(--placeholder-opacity))}.sm\:focus\:placeholder-orange-600:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#dd6b20;color:rgba(221,107,32,var(--placeholder-opacity))}.sm\:focus\:placeholder-orange-600:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#dd6b20;color:rgba(221,107,32,var(--placeholder-opacity))}.sm\:focus\:placeholder-orange-600:focus::placeholder{--placeholder-opacity:1;color:#dd6b20;color:rgba(221,107,32,var(--placeholder-opacity))}.sm\:focus\:placeholder-orange-700:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#c05621;color:rgba(192,86,33,var(--placeholder-opacity))}.sm\:focus\:placeholder-orange-700:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#c05621;color:rgba(192,86,33,var(--placeholder-opacity))}.sm\:focus\:placeholder-orange-700:focus::placeholder{--placeholder-opacity:1;color:#c05621;color:rgba(192,86,33,var(--placeholder-opacity))}.sm\:focus\:placeholder-orange-800:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#9c4221;color:rgba(156,66,33,var(--placeholder-opacity))}.sm\:focus\:placeholder-orange-800:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#9c4221;color:rgba(156,66,33,var(--placeholder-opacity))}.sm\:focus\:placeholder-orange-800:focus::placeholder{--placeholder-opacity:1;color:#9c4221;color:rgba(156,66,33,var(--placeholder-opacity))}.sm\:focus\:placeholder-orange-900:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#7b341e;color:rgba(123,52,30,var(--placeholder-opacity))}.sm\:focus\:placeholder-orange-900:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#7b341e;color:rgba(123,52,30,var(--placeholder-opacity))}.sm\:focus\:placeholder-orange-900:focus::placeholder{--placeholder-opacity:1;color:#7b341e;color:rgba(123,52,30,var(--placeholder-opacity))}.sm\:focus\:placeholder-yellow-100:focus:-ms-input-placeholder{--placeholder-opacity:1;color:ivory;color:rgba(255,255,240,var(--placeholder-opacity))}.sm\:focus\:placeholder-yellow-100:focus::-ms-input-placeholder{--placeholder-opacity:1;color:ivory;color:rgba(255,255,240,var(--placeholder-opacity))}.sm\:focus\:placeholder-yellow-100:focus::placeholder{--placeholder-opacity:1;color:ivory;color:rgba(255,255,240,var(--placeholder-opacity))}.sm\:focus\:placeholder-yellow-200:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#fefcbf;color:rgba(254,252,191,var(--placeholder-opacity))}.sm\:focus\:placeholder-yellow-200:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#fefcbf;color:rgba(254,252,191,var(--placeholder-opacity))}.sm\:focus\:placeholder-yellow-200:focus::placeholder{--placeholder-opacity:1;color:#fefcbf;color:rgba(254,252,191,var(--placeholder-opacity))}.sm\:focus\:placeholder-yellow-300:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#faf089;color:rgba(250,240,137,var(--placeholder-opacity))}.sm\:focus\:placeholder-yellow-300:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#faf089;color:rgba(250,240,137,var(--placeholder-opacity))}.sm\:focus\:placeholder-yellow-300:focus::placeholder{--placeholder-opacity:1;color:#faf089;color:rgba(250,240,137,var(--placeholder-opacity))}.sm\:focus\:placeholder-yellow-400:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#f6e05e;color:rgba(246,224,94,var(--placeholder-opacity))}.sm\:focus\:placeholder-yellow-400:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#f6e05e;color:rgba(246,224,94,var(--placeholder-opacity))}.sm\:focus\:placeholder-yellow-400:focus::placeholder{--placeholder-opacity:1;color:#f6e05e;color:rgba(246,224,94,var(--placeholder-opacity))}.sm\:focus\:placeholder-yellow-500:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#ecc94b;color:rgba(236,201,75,var(--placeholder-opacity))}.sm\:focus\:placeholder-yellow-500:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#ecc94b;color:rgba(236,201,75,var(--placeholder-opacity))}.sm\:focus\:placeholder-yellow-500:focus::placeholder{--placeholder-opacity:1;color:#ecc94b;color:rgba(236,201,75,var(--placeholder-opacity))}.sm\:focus\:placeholder-yellow-600:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#d69e2e;color:rgba(214,158,46,var(--placeholder-opacity))}.sm\:focus\:placeholder-yellow-600:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#d69e2e;color:rgba(214,158,46,var(--placeholder-opacity))}.sm\:focus\:placeholder-yellow-600:focus::placeholder{--placeholder-opacity:1;color:#d69e2e;color:rgba(214,158,46,var(--placeholder-opacity))}.sm\:focus\:placeholder-yellow-700:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#b7791f;color:rgba(183,121,31,var(--placeholder-opacity))}.sm\:focus\:placeholder-yellow-700:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#b7791f;color:rgba(183,121,31,var(--placeholder-opacity))}.sm\:focus\:placeholder-yellow-700:focus::placeholder{--placeholder-opacity:1;color:#b7791f;color:rgba(183,121,31,var(--placeholder-opacity))}.sm\:focus\:placeholder-yellow-800:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#975a16;color:rgba(151,90,22,var(--placeholder-opacity))}.sm\:focus\:placeholder-yellow-800:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#975a16;color:rgba(151,90,22,var(--placeholder-opacity))}.sm\:focus\:placeholder-yellow-800:focus::placeholder{--placeholder-opacity:1;color:#975a16;color:rgba(151,90,22,var(--placeholder-opacity))}.sm\:focus\:placeholder-yellow-900:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#744210;color:rgba(116,66,16,var(--placeholder-opacity))}.sm\:focus\:placeholder-yellow-900:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#744210;color:rgba(116,66,16,var(--placeholder-opacity))}.sm\:focus\:placeholder-yellow-900:focus::placeholder{--placeholder-opacity:1;color:#744210;color:rgba(116,66,16,var(--placeholder-opacity))}.sm\:focus\:placeholder-green-100:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#f0fff4;color:rgba(240,255,244,var(--placeholder-opacity))}.sm\:focus\:placeholder-green-100:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#f0fff4;color:rgba(240,255,244,var(--placeholder-opacity))}.sm\:focus\:placeholder-green-100:focus::placeholder{--placeholder-opacity:1;color:#f0fff4;color:rgba(240,255,244,var(--placeholder-opacity))}.sm\:focus\:placeholder-green-200:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#c6f6d5;color:rgba(198,246,213,var(--placeholder-opacity))}.sm\:focus\:placeholder-green-200:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#c6f6d5;color:rgba(198,246,213,var(--placeholder-opacity))}.sm\:focus\:placeholder-green-200:focus::placeholder{--placeholder-opacity:1;color:#c6f6d5;color:rgba(198,246,213,var(--placeholder-opacity))}.sm\:focus\:placeholder-green-300:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#9ae6b4;color:rgba(154,230,180,var(--placeholder-opacity))}.sm\:focus\:placeholder-green-300:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#9ae6b4;color:rgba(154,230,180,var(--placeholder-opacity))}.sm\:focus\:placeholder-green-300:focus::placeholder{--placeholder-opacity:1;color:#9ae6b4;color:rgba(154,230,180,var(--placeholder-opacity))}.sm\:focus\:placeholder-green-400:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#68d391;color:rgba(104,211,145,var(--placeholder-opacity))}.sm\:focus\:placeholder-green-400:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#68d391;color:rgba(104,211,145,var(--placeholder-opacity))}.sm\:focus\:placeholder-green-400:focus::placeholder{--placeholder-opacity:1;color:#68d391;color:rgba(104,211,145,var(--placeholder-opacity))}.sm\:focus\:placeholder-green-500:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#48bb78;color:rgba(72,187,120,var(--placeholder-opacity))}.sm\:focus\:placeholder-green-500:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#48bb78;color:rgba(72,187,120,var(--placeholder-opacity))}.sm\:focus\:placeholder-green-500:focus::placeholder{--placeholder-opacity:1;color:#48bb78;color:rgba(72,187,120,var(--placeholder-opacity))}.sm\:focus\:placeholder-green-600:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#38a169;color:rgba(56,161,105,var(--placeholder-opacity))}.sm\:focus\:placeholder-green-600:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#38a169;color:rgba(56,161,105,var(--placeholder-opacity))}.sm\:focus\:placeholder-green-600:focus::placeholder{--placeholder-opacity:1;color:#38a169;color:rgba(56,161,105,var(--placeholder-opacity))}.sm\:focus\:placeholder-green-700:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#2f855a;color:rgba(47,133,90,var(--placeholder-opacity))}.sm\:focus\:placeholder-green-700:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#2f855a;color:rgba(47,133,90,var(--placeholder-opacity))}.sm\:focus\:placeholder-green-700:focus::placeholder{--placeholder-opacity:1;color:#2f855a;color:rgba(47,133,90,var(--placeholder-opacity))}.sm\:focus\:placeholder-green-800:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#276749;color:rgba(39,103,73,var(--placeholder-opacity))}.sm\:focus\:placeholder-green-800:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#276749;color:rgba(39,103,73,var(--placeholder-opacity))}.sm\:focus\:placeholder-green-800:focus::placeholder{--placeholder-opacity:1;color:#276749;color:rgba(39,103,73,var(--placeholder-opacity))}.sm\:focus\:placeholder-green-900:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#22543d;color:rgba(34,84,61,var(--placeholder-opacity))}.sm\:focus\:placeholder-green-900:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#22543d;color:rgba(34,84,61,var(--placeholder-opacity))}.sm\:focus\:placeholder-green-900:focus::placeholder{--placeholder-opacity:1;color:#22543d;color:rgba(34,84,61,var(--placeholder-opacity))}.sm\:focus\:placeholder-teal-100:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#e6fffa;color:rgba(230,255,250,var(--placeholder-opacity))}.sm\:focus\:placeholder-teal-100:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#e6fffa;color:rgba(230,255,250,var(--placeholder-opacity))}.sm\:focus\:placeholder-teal-100:focus::placeholder{--placeholder-opacity:1;color:#e6fffa;color:rgba(230,255,250,var(--placeholder-opacity))}.sm\:focus\:placeholder-teal-200:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#b2f5ea;color:rgba(178,245,234,var(--placeholder-opacity))}.sm\:focus\:placeholder-teal-200:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#b2f5ea;color:rgba(178,245,234,var(--placeholder-opacity))}.sm\:focus\:placeholder-teal-200:focus::placeholder{--placeholder-opacity:1;color:#b2f5ea;color:rgba(178,245,234,var(--placeholder-opacity))}.sm\:focus\:placeholder-teal-300:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#81e6d9;color:rgba(129,230,217,var(--placeholder-opacity))}.sm\:focus\:placeholder-teal-300:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#81e6d9;color:rgba(129,230,217,var(--placeholder-opacity))}.sm\:focus\:placeholder-teal-300:focus::placeholder{--placeholder-opacity:1;color:#81e6d9;color:rgba(129,230,217,var(--placeholder-opacity))}.sm\:focus\:placeholder-teal-400:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#4fd1c5;color:rgba(79,209,197,var(--placeholder-opacity))}.sm\:focus\:placeholder-teal-400:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#4fd1c5;color:rgba(79,209,197,var(--placeholder-opacity))}.sm\:focus\:placeholder-teal-400:focus::placeholder{--placeholder-opacity:1;color:#4fd1c5;color:rgba(79,209,197,var(--placeholder-opacity))}.sm\:focus\:placeholder-teal-500:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#38b2ac;color:rgba(56,178,172,var(--placeholder-opacity))}.sm\:focus\:placeholder-teal-500:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#38b2ac;color:rgba(56,178,172,var(--placeholder-opacity))}.sm\:focus\:placeholder-teal-500:focus::placeholder{--placeholder-opacity:1;color:#38b2ac;color:rgba(56,178,172,var(--placeholder-opacity))}.sm\:focus\:placeholder-teal-600:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#319795;color:rgba(49,151,149,var(--placeholder-opacity))}.sm\:focus\:placeholder-teal-600:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#319795;color:rgba(49,151,149,var(--placeholder-opacity))}.sm\:focus\:placeholder-teal-600:focus::placeholder{--placeholder-opacity:1;color:#319795;color:rgba(49,151,149,var(--placeholder-opacity))}.sm\:focus\:placeholder-teal-700:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#2c7a7b;color:rgba(44,122,123,var(--placeholder-opacity))}.sm\:focus\:placeholder-teal-700:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#2c7a7b;color:rgba(44,122,123,var(--placeholder-opacity))}.sm\:focus\:placeholder-teal-700:focus::placeholder{--placeholder-opacity:1;color:#2c7a7b;color:rgba(44,122,123,var(--placeholder-opacity))}.sm\:focus\:placeholder-teal-800:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#285e61;color:rgba(40,94,97,var(--placeholder-opacity))}.sm\:focus\:placeholder-teal-800:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#285e61;color:rgba(40,94,97,var(--placeholder-opacity))}.sm\:focus\:placeholder-teal-800:focus::placeholder{--placeholder-opacity:1;color:#285e61;color:rgba(40,94,97,var(--placeholder-opacity))}.sm\:focus\:placeholder-teal-900:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#234e52;color:rgba(35,78,82,var(--placeholder-opacity))}.sm\:focus\:placeholder-teal-900:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#234e52;color:rgba(35,78,82,var(--placeholder-opacity))}.sm\:focus\:placeholder-teal-900:focus::placeholder{--placeholder-opacity:1;color:#234e52;color:rgba(35,78,82,var(--placeholder-opacity))}.sm\:focus\:placeholder-blue-100:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#ebf8ff;color:rgba(235,248,255,var(--placeholder-opacity))}.sm\:focus\:placeholder-blue-100:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#ebf8ff;color:rgba(235,248,255,var(--placeholder-opacity))}.sm\:focus\:placeholder-blue-100:focus::placeholder{--placeholder-opacity:1;color:#ebf8ff;color:rgba(235,248,255,var(--placeholder-opacity))}.sm\:focus\:placeholder-blue-200:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#bee3f8;color:rgba(190,227,248,var(--placeholder-opacity))}.sm\:focus\:placeholder-blue-200:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#bee3f8;color:rgba(190,227,248,var(--placeholder-opacity))}.sm\:focus\:placeholder-blue-200:focus::placeholder{--placeholder-opacity:1;color:#bee3f8;color:rgba(190,227,248,var(--placeholder-opacity))}.sm\:focus\:placeholder-blue-300:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#90cdf4;color:rgba(144,205,244,var(--placeholder-opacity))}.sm\:focus\:placeholder-blue-300:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#90cdf4;color:rgba(144,205,244,var(--placeholder-opacity))}.sm\:focus\:placeholder-blue-300:focus::placeholder{--placeholder-opacity:1;color:#90cdf4;color:rgba(144,205,244,var(--placeholder-opacity))}.sm\:focus\:placeholder-blue-400:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#63b3ed;color:rgba(99,179,237,var(--placeholder-opacity))}.sm\:focus\:placeholder-blue-400:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#63b3ed;color:rgba(99,179,237,var(--placeholder-opacity))}.sm\:focus\:placeholder-blue-400:focus::placeholder{--placeholder-opacity:1;color:#63b3ed;color:rgba(99,179,237,var(--placeholder-opacity))}.sm\:focus\:placeholder-blue-500:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#4299e1;color:rgba(66,153,225,var(--placeholder-opacity))}.sm\:focus\:placeholder-blue-500:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#4299e1;color:rgba(66,153,225,var(--placeholder-opacity))}.sm\:focus\:placeholder-blue-500:focus::placeholder{--placeholder-opacity:1;color:#4299e1;color:rgba(66,153,225,var(--placeholder-opacity))}.sm\:focus\:placeholder-blue-600:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#3182ce;color:rgba(49,130,206,var(--placeholder-opacity))}.sm\:focus\:placeholder-blue-600:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#3182ce;color:rgba(49,130,206,var(--placeholder-opacity))}.sm\:focus\:placeholder-blue-600:focus::placeholder{--placeholder-opacity:1;color:#3182ce;color:rgba(49,130,206,var(--placeholder-opacity))}.sm\:focus\:placeholder-blue-700:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#2b6cb0;color:rgba(43,108,176,var(--placeholder-opacity))}.sm\:focus\:placeholder-blue-700:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#2b6cb0;color:rgba(43,108,176,var(--placeholder-opacity))}.sm\:focus\:placeholder-blue-700:focus::placeholder{--placeholder-opacity:1;color:#2b6cb0;color:rgba(43,108,176,var(--placeholder-opacity))}.sm\:focus\:placeholder-blue-800:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#2c5282;color:rgba(44,82,130,var(--placeholder-opacity))}.sm\:focus\:placeholder-blue-800:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#2c5282;color:rgba(44,82,130,var(--placeholder-opacity))}.sm\:focus\:placeholder-blue-800:focus::placeholder{--placeholder-opacity:1;color:#2c5282;color:rgba(44,82,130,var(--placeholder-opacity))}.sm\:focus\:placeholder-blue-900:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#2a4365;color:rgba(42,67,101,var(--placeholder-opacity))}.sm\:focus\:placeholder-blue-900:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#2a4365;color:rgba(42,67,101,var(--placeholder-opacity))}.sm\:focus\:placeholder-blue-900:focus::placeholder{--placeholder-opacity:1;color:#2a4365;color:rgba(42,67,101,var(--placeholder-opacity))}.sm\:focus\:placeholder-indigo-100:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#ebf4ff;color:rgba(235,244,255,var(--placeholder-opacity))}.sm\:focus\:placeholder-indigo-100:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#ebf4ff;color:rgba(235,244,255,var(--placeholder-opacity))}.sm\:focus\:placeholder-indigo-100:focus::placeholder{--placeholder-opacity:1;color:#ebf4ff;color:rgba(235,244,255,var(--placeholder-opacity))}.sm\:focus\:placeholder-indigo-200:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#c3dafe;color:rgba(195,218,254,var(--placeholder-opacity))}.sm\:focus\:placeholder-indigo-200:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#c3dafe;color:rgba(195,218,254,var(--placeholder-opacity))}.sm\:focus\:placeholder-indigo-200:focus::placeholder{--placeholder-opacity:1;color:#c3dafe;color:rgba(195,218,254,var(--placeholder-opacity))}.sm\:focus\:placeholder-indigo-300:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#a3bffa;color:rgba(163,191,250,var(--placeholder-opacity))}.sm\:focus\:placeholder-indigo-300:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#a3bffa;color:rgba(163,191,250,var(--placeholder-opacity))}.sm\:focus\:placeholder-indigo-300:focus::placeholder{--placeholder-opacity:1;color:#a3bffa;color:rgba(163,191,250,var(--placeholder-opacity))}.sm\:focus\:placeholder-indigo-400:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#7f9cf5;color:rgba(127,156,245,var(--placeholder-opacity))}.sm\:focus\:placeholder-indigo-400:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#7f9cf5;color:rgba(127,156,245,var(--placeholder-opacity))}.sm\:focus\:placeholder-indigo-400:focus::placeholder{--placeholder-opacity:1;color:#7f9cf5;color:rgba(127,156,245,var(--placeholder-opacity))}.sm\:focus\:placeholder-indigo-500:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#667eea;color:rgba(102,126,234,var(--placeholder-opacity))}.sm\:focus\:placeholder-indigo-500:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#667eea;color:rgba(102,126,234,var(--placeholder-opacity))}.sm\:focus\:placeholder-indigo-500:focus::placeholder{--placeholder-opacity:1;color:#667eea;color:rgba(102,126,234,var(--placeholder-opacity))}.sm\:focus\:placeholder-indigo-600:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#5a67d8;color:rgba(90,103,216,var(--placeholder-opacity))}.sm\:focus\:placeholder-indigo-600:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#5a67d8;color:rgba(90,103,216,var(--placeholder-opacity))}.sm\:focus\:placeholder-indigo-600:focus::placeholder{--placeholder-opacity:1;color:#5a67d8;color:rgba(90,103,216,var(--placeholder-opacity))}.sm\:focus\:placeholder-indigo-700:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#4c51bf;color:rgba(76,81,191,var(--placeholder-opacity))}.sm\:focus\:placeholder-indigo-700:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#4c51bf;color:rgba(76,81,191,var(--placeholder-opacity))}.sm\:focus\:placeholder-indigo-700:focus::placeholder{--placeholder-opacity:1;color:#4c51bf;color:rgba(76,81,191,var(--placeholder-opacity))}.sm\:focus\:placeholder-indigo-800:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#434190;color:rgba(67,65,144,var(--placeholder-opacity))}.sm\:focus\:placeholder-indigo-800:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#434190;color:rgba(67,65,144,var(--placeholder-opacity))}.sm\:focus\:placeholder-indigo-800:focus::placeholder{--placeholder-opacity:1;color:#434190;color:rgba(67,65,144,var(--placeholder-opacity))}.sm\:focus\:placeholder-indigo-900:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#3c366b;color:rgba(60,54,107,var(--placeholder-opacity))}.sm\:focus\:placeholder-indigo-900:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#3c366b;color:rgba(60,54,107,var(--placeholder-opacity))}.sm\:focus\:placeholder-indigo-900:focus::placeholder{--placeholder-opacity:1;color:#3c366b;color:rgba(60,54,107,var(--placeholder-opacity))}.sm\:focus\:placeholder-purple-100:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#faf5ff;color:rgba(250,245,255,var(--placeholder-opacity))}.sm\:focus\:placeholder-purple-100:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#faf5ff;color:rgba(250,245,255,var(--placeholder-opacity))}.sm\:focus\:placeholder-purple-100:focus::placeholder{--placeholder-opacity:1;color:#faf5ff;color:rgba(250,245,255,var(--placeholder-opacity))}.sm\:focus\:placeholder-purple-200:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#e9d8fd;color:rgba(233,216,253,var(--placeholder-opacity))}.sm\:focus\:placeholder-purple-200:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#e9d8fd;color:rgba(233,216,253,var(--placeholder-opacity))}.sm\:focus\:placeholder-purple-200:focus::placeholder{--placeholder-opacity:1;color:#e9d8fd;color:rgba(233,216,253,var(--placeholder-opacity))}.sm\:focus\:placeholder-purple-300:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#d6bcfa;color:rgba(214,188,250,var(--placeholder-opacity))}.sm\:focus\:placeholder-purple-300:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#d6bcfa;color:rgba(214,188,250,var(--placeholder-opacity))}.sm\:focus\:placeholder-purple-300:focus::placeholder{--placeholder-opacity:1;color:#d6bcfa;color:rgba(214,188,250,var(--placeholder-opacity))}.sm\:focus\:placeholder-purple-400:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#b794f4;color:rgba(183,148,244,var(--placeholder-opacity))}.sm\:focus\:placeholder-purple-400:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#b794f4;color:rgba(183,148,244,var(--placeholder-opacity))}.sm\:focus\:placeholder-purple-400:focus::placeholder{--placeholder-opacity:1;color:#b794f4;color:rgba(183,148,244,var(--placeholder-opacity))}.sm\:focus\:placeholder-purple-500:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#9f7aea;color:rgba(159,122,234,var(--placeholder-opacity))}.sm\:focus\:placeholder-purple-500:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#9f7aea;color:rgba(159,122,234,var(--placeholder-opacity))}.sm\:focus\:placeholder-purple-500:focus::placeholder{--placeholder-opacity:1;color:#9f7aea;color:rgba(159,122,234,var(--placeholder-opacity))}.sm\:focus\:placeholder-purple-600:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#805ad5;color:rgba(128,90,213,var(--placeholder-opacity))}.sm\:focus\:placeholder-purple-600:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#805ad5;color:rgba(128,90,213,var(--placeholder-opacity))}.sm\:focus\:placeholder-purple-600:focus::placeholder{--placeholder-opacity:1;color:#805ad5;color:rgba(128,90,213,var(--placeholder-opacity))}.sm\:focus\:placeholder-purple-700:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#6b46c1;color:rgba(107,70,193,var(--placeholder-opacity))}.sm\:focus\:placeholder-purple-700:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#6b46c1;color:rgba(107,70,193,var(--placeholder-opacity))}.sm\:focus\:placeholder-purple-700:focus::placeholder{--placeholder-opacity:1;color:#6b46c1;color:rgba(107,70,193,var(--placeholder-opacity))}.sm\:focus\:placeholder-purple-800:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#553c9a;color:rgba(85,60,154,var(--placeholder-opacity))}.sm\:focus\:placeholder-purple-800:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#553c9a;color:rgba(85,60,154,var(--placeholder-opacity))}.sm\:focus\:placeholder-purple-800:focus::placeholder{--placeholder-opacity:1;color:#553c9a;color:rgba(85,60,154,var(--placeholder-opacity))}.sm\:focus\:placeholder-purple-900:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#44337a;color:rgba(68,51,122,var(--placeholder-opacity))}.sm\:focus\:placeholder-purple-900:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#44337a;color:rgba(68,51,122,var(--placeholder-opacity))}.sm\:focus\:placeholder-purple-900:focus::placeholder{--placeholder-opacity:1;color:#44337a;color:rgba(68,51,122,var(--placeholder-opacity))}.sm\:focus\:placeholder-pink-100:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#fff5f7;color:rgba(255,245,247,var(--placeholder-opacity))}.sm\:focus\:placeholder-pink-100:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#fff5f7;color:rgba(255,245,247,var(--placeholder-opacity))}.sm\:focus\:placeholder-pink-100:focus::placeholder{--placeholder-opacity:1;color:#fff5f7;color:rgba(255,245,247,var(--placeholder-opacity))}.sm\:focus\:placeholder-pink-200:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#fed7e2;color:rgba(254,215,226,var(--placeholder-opacity))}.sm\:focus\:placeholder-pink-200:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#fed7e2;color:rgba(254,215,226,var(--placeholder-opacity))}.sm\:focus\:placeholder-pink-200:focus::placeholder{--placeholder-opacity:1;color:#fed7e2;color:rgba(254,215,226,var(--placeholder-opacity))}.sm\:focus\:placeholder-pink-300:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#fbb6ce;color:rgba(251,182,206,var(--placeholder-opacity))}.sm\:focus\:placeholder-pink-300:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#fbb6ce;color:rgba(251,182,206,var(--placeholder-opacity))}.sm\:focus\:placeholder-pink-300:focus::placeholder{--placeholder-opacity:1;color:#fbb6ce;color:rgba(251,182,206,var(--placeholder-opacity))}.sm\:focus\:placeholder-pink-400:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#f687b3;color:rgba(246,135,179,var(--placeholder-opacity))}.sm\:focus\:placeholder-pink-400:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#f687b3;color:rgba(246,135,179,var(--placeholder-opacity))}.sm\:focus\:placeholder-pink-400:focus::placeholder{--placeholder-opacity:1;color:#f687b3;color:rgba(246,135,179,var(--placeholder-opacity))}.sm\:focus\:placeholder-pink-500:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#ed64a6;color:rgba(237,100,166,var(--placeholder-opacity))}.sm\:focus\:placeholder-pink-500:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#ed64a6;color:rgba(237,100,166,var(--placeholder-opacity))}.sm\:focus\:placeholder-pink-500:focus::placeholder{--placeholder-opacity:1;color:#ed64a6;color:rgba(237,100,166,var(--placeholder-opacity))}.sm\:focus\:placeholder-pink-600:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#d53f8c;color:rgba(213,63,140,var(--placeholder-opacity))}.sm\:focus\:placeholder-pink-600:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#d53f8c;color:rgba(213,63,140,var(--placeholder-opacity))}.sm\:focus\:placeholder-pink-600:focus::placeholder{--placeholder-opacity:1;color:#d53f8c;color:rgba(213,63,140,var(--placeholder-opacity))}.sm\:focus\:placeholder-pink-700:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#b83280;color:rgba(184,50,128,var(--placeholder-opacity))}.sm\:focus\:placeholder-pink-700:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#b83280;color:rgba(184,50,128,var(--placeholder-opacity))}.sm\:focus\:placeholder-pink-700:focus::placeholder{--placeholder-opacity:1;color:#b83280;color:rgba(184,50,128,var(--placeholder-opacity))}.sm\:focus\:placeholder-pink-800:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#97266d;color:rgba(151,38,109,var(--placeholder-opacity))}.sm\:focus\:placeholder-pink-800:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#97266d;color:rgba(151,38,109,var(--placeholder-opacity))}.sm\:focus\:placeholder-pink-800:focus::placeholder{--placeholder-opacity:1;color:#97266d;color:rgba(151,38,109,var(--placeholder-opacity))}.sm\:focus\:placeholder-pink-900:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#702459;color:rgba(112,36,89,var(--placeholder-opacity))}.sm\:focus\:placeholder-pink-900:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#702459;color:rgba(112,36,89,var(--placeholder-opacity))}.sm\:focus\:placeholder-pink-900:focus::placeholder{--placeholder-opacity:1;color:#702459;color:rgba(112,36,89,var(--placeholder-opacity))}.sm\:placeholder-opacity-0:-ms-input-placeholder{--placeholder-opacity:0}.sm\:placeholder-opacity-0::-ms-input-placeholder{--placeholder-opacity:0}.sm\:placeholder-opacity-0::placeholder{--placeholder-opacity:0}.sm\:placeholder-opacity-25:-ms-input-placeholder{--placeholder-opacity:0.25}.sm\:placeholder-opacity-25::-ms-input-placeholder{--placeholder-opacity:0.25}.sm\:placeholder-opacity-25::placeholder{--placeholder-opacity:0.25}.sm\:placeholder-opacity-50:-ms-input-placeholder{--placeholder-opacity:0.5}.sm\:placeholder-opacity-50::-ms-input-placeholder{--placeholder-opacity:0.5}.sm\:placeholder-opacity-50::placeholder{--placeholder-opacity:0.5}.sm\:placeholder-opacity-75:-ms-input-placeholder{--placeholder-opacity:0.75}.sm\:placeholder-opacity-75::-ms-input-placeholder{--placeholder-opacity:0.75}.sm\:placeholder-opacity-75::placeholder{--placeholder-opacity:0.75}.sm\:placeholder-opacity-100:-ms-input-placeholder{--placeholder-opacity:1}.sm\:placeholder-opacity-100::-ms-input-placeholder{--placeholder-opacity:1}.sm\:placeholder-opacity-100::placeholder{--placeholder-opacity:1}.sm\:focus\:placeholder-opacity-0:focus:-ms-input-placeholder{--placeholder-opacity:0}.sm\:focus\:placeholder-opacity-0:focus::-ms-input-placeholder{--placeholder-opacity:0}.sm\:focus\:placeholder-opacity-0:focus::placeholder{--placeholder-opacity:0}.sm\:focus\:placeholder-opacity-25:focus:-ms-input-placeholder{--placeholder-opacity:0.25}.sm\:focus\:placeholder-opacity-25:focus::-ms-input-placeholder{--placeholder-opacity:0.25}.sm\:focus\:placeholder-opacity-25:focus::placeholder{--placeholder-opacity:0.25}.sm\:focus\:placeholder-opacity-50:focus:-ms-input-placeholder{--placeholder-opacity:0.5}.sm\:focus\:placeholder-opacity-50:focus::-ms-input-placeholder{--placeholder-opacity:0.5}.sm\:focus\:placeholder-opacity-50:focus::placeholder{--placeholder-opacity:0.5}.sm\:focus\:placeholder-opacity-75:focus:-ms-input-placeholder{--placeholder-opacity:0.75}.sm\:focus\:placeholder-opacity-75:focus::-ms-input-placeholder{--placeholder-opacity:0.75}.sm\:focus\:placeholder-opacity-75:focus::placeholder{--placeholder-opacity:0.75}.sm\:focus\:placeholder-opacity-100:focus:-ms-input-placeholder{--placeholder-opacity:1}.sm\:focus\:placeholder-opacity-100:focus::-ms-input-placeholder{--placeholder-opacity:1}.sm\:focus\:placeholder-opacity-100:focus::placeholder{--placeholder-opacity:1}.sm\:pointer-events-none{pointer-events:none}.sm\:pointer-events-auto{pointer-events:auto}.sm\:static{position:static}.sm\:fixed{position:fixed}.sm\:absolute{position:absolute}.sm\:relative{position:relative}.sm\:sticky{position:-webkit-sticky;position:sticky}.sm\:inset-0{top:0;right:0;bottom:0;left:0}.sm\:inset-auto{top:auto;right:auto;bottom:auto;left:auto}.sm\:inset-y-0{top:0;bottom:0}.sm\:inset-x-0{right:0;left:0}.sm\:inset-y-auto{top:auto;bottom:auto}.sm\:inset-x-auto{right:auto;left:auto}.sm\:top-0{top:0}.sm\:right-0{right:0}.sm\:bottom-0{bottom:0}.sm\:left-0{left:0}.sm\:top-auto{top:auto}.sm\:right-auto{right:auto}.sm\:bottom-auto{bottom:auto}.sm\:left-auto{left:auto}.sm\:resize-none{resize:none}.sm\:resize-y{resize:vertical}.sm\:resize-x{resize:horizontal}.sm\:resize{resize:both}.sm\:shadow-xs{box-shadow:0 0 0 1px rgba(0,0,0,.05)}.sm\:shadow-sm{box-shadow:0 1px 2px 0 rgba(0,0,0,.05)}.sm\:shadow{box-shadow:0 1px 3px 0 rgba(0,0,0,.1),0 1px 2px 0 rgba(0,0,0,.06)}.sm\:shadow-md{box-shadow:0 4px 6px -1px rgba(0,0,0,.1),0 2px 4px -1px rgba(0,0,0,.06)}.sm\:shadow-lg{box-shadow:0 10px 15px -3px rgba(0,0,0,.1),0 4px 6px -2px rgba(0,0,0,.05)}.sm\:shadow-xl{box-shadow:0 20px 25px -5px rgba(0,0,0,.1),0 10px 10px -5px rgba(0,0,0,.04)}.sm\:shadow-2xl{box-shadow:0 25px 50px -12px rgba(0,0,0,.25)}.sm\:shadow-inner{box-shadow:inset 0 2px 4px 0 rgba(0,0,0,.06)}.sm\:shadow-outline{box-shadow:0 0 0 3px rgba(66,153,225,.5)}.sm\:shadow-none{box-shadow:none}.sm\:hover\:shadow-xs:hover{box-shadow:0 0 0 1px rgba(0,0,0,.05)}.sm\:hover\:shadow-sm:hover{box-shadow:0 1px 2px 0 rgba(0,0,0,.05)}.sm\:hover\:shadow:hover{box-shadow:0 1px 3px 0 rgba(0,0,0,.1),0 1px 2px 0 rgba(0,0,0,.06)}.sm\:hover\:shadow-md:hover{box-shadow:0 4px 6px -1px rgba(0,0,0,.1),0 2px 4px -1px rgba(0,0,0,.06)}.sm\:hover\:shadow-lg:hover{box-shadow:0 10px 15px -3px rgba(0,0,0,.1),0 4px 6px -2px rgba(0,0,0,.05)}.sm\:hover\:shadow-xl:hover{box-shadow:0 20px 25px -5px rgba(0,0,0,.1),0 10px 10px -5px rgba(0,0,0,.04)}.sm\:hover\:shadow-2xl:hover{box-shadow:0 25px 50px -12px rgba(0,0,0,.25)}.sm\:hover\:shadow-inner:hover{box-shadow:inset 0 2px 4px 0 rgba(0,0,0,.06)}.sm\:hover\:shadow-outline:hover{box-shadow:0 0 0 3px rgba(66,153,225,.5)}.sm\:hover\:shadow-none:hover{box-shadow:none}.sm\:focus\:shadow-xs:focus{box-shadow:0 0 0 1px rgba(0,0,0,.05)}.sm\:focus\:shadow-sm:focus{box-shadow:0 1px 2px 0 rgba(0,0,0,.05)}.sm\:focus\:shadow:focus{box-shadow:0 1px 3px 0 rgba(0,0,0,.1),0 1px 2px 0 rgba(0,0,0,.06)}.sm\:focus\:shadow-md:focus{box-shadow:0 4px 6px -1px rgba(0,0,0,.1),0 2px 4px -1px rgba(0,0,0,.06)}.sm\:focus\:shadow-lg:focus{box-shadow:0 10px 15px -3px rgba(0,0,0,.1),0 4px 6px -2px rgba(0,0,0,.05)}.sm\:focus\:shadow-xl:focus{box-shadow:0 20px 25px -5px rgba(0,0,0,.1),0 10px 10px -5px rgba(0,0,0,.04)}.sm\:focus\:shadow-2xl:focus{box-shadow:0 25px 50px -12px rgba(0,0,0,.25)}.sm\:focus\:shadow-inner:focus{box-shadow:inset 0 2px 4px 0 rgba(0,0,0,.06)}.sm\:focus\:shadow-outline:focus{box-shadow:0 0 0 3px rgba(66,153,225,.5)}.sm\:focus\:shadow-none:focus{box-shadow:none}.sm\:fill-current{fill:currentColor}.sm\:stroke-current{stroke:currentColor}.sm\:stroke-0{stroke-width:0}.sm\:stroke-1{stroke-width:1}.sm\:stroke-2{stroke-width:2}.sm\:table-auto{table-layout:auto}.sm\:table-fixed{table-layout:fixed}.sm\:text-left{text-align:left}.sm\:text-center{text-align:center}.sm\:text-right{text-align:right}.sm\:text-justify{text-align:justify}.sm\:text-transparent{color:transparent}.sm\:text-current{color:currentColor}.sm\:text-black{--text-opacity:1;color:#000;color:rgba(0,0,0,var(--text-opacity))}.sm\:text-white{--text-opacity:1;color:#fff;color:rgba(255,255,255,var(--text-opacity))}.sm\:text-gray-100{--text-opacity:1;color:#f7fafc;color:rgba(247,250,252,var(--text-opacity))}.sm\:text-gray-200{--text-opacity:1;color:#edf2f7;color:rgba(237,242,247,var(--text-opacity))}.sm\:text-gray-300{--text-opacity:1;color:#e2e8f0;color:rgba(226,232,240,var(--text-opacity))}.sm\:text-gray-400{--text-opacity:1;color:#cbd5e0;color:rgba(203,213,224,var(--text-opacity))}.sm\:text-gray-500{--text-opacity:1;color:#a0aec0;color:rgba(160,174,192,var(--text-opacity))}.sm\:text-gray-600{--text-opacity:1;color:#718096;color:rgba(113,128,150,var(--text-opacity))}.sm\:text-gray-700{--text-opacity:1;color:#4a5568;color:rgba(74,85,104,var(--text-opacity))}.sm\:text-gray-800{--text-opacity:1;color:#2d3748;color:rgba(45,55,72,var(--text-opacity))}.sm\:text-gray-900{--text-opacity:1;color:#1a202c;color:rgba(26,32,44,var(--text-opacity))}.sm\:text-red-100{--text-opacity:1;color:#fff5f5;color:rgba(255,245,245,var(--text-opacity))}.sm\:text-red-200{--text-opacity:1;color:#fed7d7;color:rgba(254,215,215,var(--text-opacity))}.sm\:text-red-300{--text-opacity:1;color:#feb2b2;color:rgba(254,178,178,var(--text-opacity))}.sm\:text-red-400{--text-opacity:1;color:#fc8181;color:rgba(252,129,129,var(--text-opacity))}.sm\:text-red-500{--text-opacity:1;color:#f56565;color:rgba(245,101,101,var(--text-opacity))}.sm\:text-red-600{--text-opacity:1;color:#e53e3e;color:rgba(229,62,62,var(--text-opacity))}.sm\:text-red-700{--text-opacity:1;color:#c53030;color:rgba(197,48,48,var(--text-opacity))}.sm\:text-red-800{--text-opacity:1;color:#9b2c2c;color:rgba(155,44,44,var(--text-opacity))}.sm\:text-red-900{--text-opacity:1;color:#742a2a;color:rgba(116,42,42,var(--text-opacity))}.sm\:text-orange-100{--text-opacity:1;color:#fffaf0;color:rgba(255,250,240,var(--text-opacity))}.sm\:text-orange-200{--text-opacity:1;color:#feebc8;color:rgba(254,235,200,var(--text-opacity))}.sm\:text-orange-300{--text-opacity:1;color:#fbd38d;color:rgba(251,211,141,var(--text-opacity))}.sm\:text-orange-400{--text-opacity:1;color:#f6ad55;color:rgba(246,173,85,var(--text-opacity))}.sm\:text-orange-500{--text-opacity:1;color:#ed8936;color:rgba(237,137,54,var(--text-opacity))}.sm\:text-orange-600{--text-opacity:1;color:#dd6b20;color:rgba(221,107,32,var(--text-opacity))}.sm\:text-orange-700{--text-opacity:1;color:#c05621;color:rgba(192,86,33,var(--text-opacity))}.sm\:text-orange-800{--text-opacity:1;color:#9c4221;color:rgba(156,66,33,var(--text-opacity))}.sm\:text-orange-900{--text-opacity:1;color:#7b341e;color:rgba(123,52,30,var(--text-opacity))}.sm\:text-yellow-100{--text-opacity:1;color:ivory;color:rgba(255,255,240,var(--text-opacity))}.sm\:text-yellow-200{--text-opacity:1;color:#fefcbf;color:rgba(254,252,191,var(--text-opacity))}.sm\:text-yellow-300{--text-opacity:1;color:#faf089;color:rgba(250,240,137,var(--text-opacity))}.sm\:text-yellow-400{--text-opacity:1;color:#f6e05e;color:rgba(246,224,94,var(--text-opacity))}.sm\:text-yellow-500{--text-opacity:1;color:#ecc94b;color:rgba(236,201,75,var(--text-opacity))}.sm\:text-yellow-600{--text-opacity:1;color:#d69e2e;color:rgba(214,158,46,var(--text-opacity))}.sm\:text-yellow-700{--text-opacity:1;color:#b7791f;color:rgba(183,121,31,var(--text-opacity))}.sm\:text-yellow-800{--text-opacity:1;color:#975a16;color:rgba(151,90,22,var(--text-opacity))}.sm\:text-yellow-900{--text-opacity:1;color:#744210;color:rgba(116,66,16,var(--text-opacity))}.sm\:text-green-100{--text-opacity:1;color:#f0fff4;color:rgba(240,255,244,var(--text-opacity))}.sm\:text-green-200{--text-opacity:1;color:#c6f6d5;color:rgba(198,246,213,var(--text-opacity))}.sm\:text-green-300{--text-opacity:1;color:#9ae6b4;color:rgba(154,230,180,var(--text-opacity))}.sm\:text-green-400{--text-opacity:1;color:#68d391;color:rgba(104,211,145,var(--text-opacity))}.sm\:text-green-500{--text-opacity:1;color:#48bb78;color:rgba(72,187,120,var(--text-opacity))}.sm\:text-green-600{--text-opacity:1;color:#38a169;color:rgba(56,161,105,var(--text-opacity))}.sm\:text-green-700{--text-opacity:1;color:#2f855a;color:rgba(47,133,90,var(--text-opacity))}.sm\:text-green-800{--text-opacity:1;color:#276749;color:rgba(39,103,73,var(--text-opacity))}.sm\:text-green-900{--text-opacity:1;color:#22543d;color:rgba(34,84,61,var(--text-opacity))}.sm\:text-teal-100{--text-opacity:1;color:#e6fffa;color:rgba(230,255,250,var(--text-opacity))}.sm\:text-teal-200{--text-opacity:1;color:#b2f5ea;color:rgba(178,245,234,var(--text-opacity))}.sm\:text-teal-300{--text-opacity:1;color:#81e6d9;color:rgba(129,230,217,var(--text-opacity))}.sm\:text-teal-400{--text-opacity:1;color:#4fd1c5;color:rgba(79,209,197,var(--text-opacity))}.sm\:text-teal-500{--text-opacity:1;color:#38b2ac;color:rgba(56,178,172,var(--text-opacity))}.sm\:text-teal-600{--text-opacity:1;color:#319795;color:rgba(49,151,149,var(--text-opacity))}.sm\:text-teal-700{--text-opacity:1;color:#2c7a7b;color:rgba(44,122,123,var(--text-opacity))}.sm\:text-teal-800{--text-opacity:1;color:#285e61;color:rgba(40,94,97,var(--text-opacity))}.sm\:text-teal-900{--text-opacity:1;color:#234e52;color:rgba(35,78,82,var(--text-opacity))}.sm\:text-blue-100{--text-opacity:1;color:#ebf8ff;color:rgba(235,248,255,var(--text-opacity))}.sm\:text-blue-200{--text-opacity:1;color:#bee3f8;color:rgba(190,227,248,var(--text-opacity))}.sm\:text-blue-300{--text-opacity:1;color:#90cdf4;color:rgba(144,205,244,var(--text-opacity))}.sm\:text-blue-400{--text-opacity:1;color:#63b3ed;color:rgba(99,179,237,var(--text-opacity))}.sm\:text-blue-500{--text-opacity:1;color:#4299e1;color:rgba(66,153,225,var(--text-opacity))}.sm\:text-blue-600{--text-opacity:1;color:#3182ce;color:rgba(49,130,206,var(--text-opacity))}.sm\:text-blue-700{--text-opacity:1;color:#2b6cb0;color:rgba(43,108,176,var(--text-opacity))}.sm\:text-blue-800{--text-opacity:1;color:#2c5282;color:rgba(44,82,130,var(--text-opacity))}.sm\:text-blue-900{--text-opacity:1;color:#2a4365;color:rgba(42,67,101,var(--text-opacity))}.sm\:text-indigo-100{--text-opacity:1;color:#ebf4ff;color:rgba(235,244,255,var(--text-opacity))}.sm\:text-indigo-200{--text-opacity:1;color:#c3dafe;color:rgba(195,218,254,var(--text-opacity))}.sm\:text-indigo-300{--text-opacity:1;color:#a3bffa;color:rgba(163,191,250,var(--text-opacity))}.sm\:text-indigo-400{--text-opacity:1;color:#7f9cf5;color:rgba(127,156,245,var(--text-opacity))}.sm\:text-indigo-500{--text-opacity:1;color:#667eea;color:rgba(102,126,234,var(--text-opacity))}.sm\:text-indigo-600{--text-opacity:1;color:#5a67d8;color:rgba(90,103,216,var(--text-opacity))}.sm\:text-indigo-700{--text-opacity:1;color:#4c51bf;color:rgba(76,81,191,var(--text-opacity))}.sm\:text-indigo-800{--text-opacity:1;color:#434190;color:rgba(67,65,144,var(--text-opacity))}.sm\:text-indigo-900{--text-opacity:1;color:#3c366b;color:rgba(60,54,107,var(--text-opacity))}.sm\:text-purple-100{--text-opacity:1;color:#faf5ff;color:rgba(250,245,255,var(--text-opacity))}.sm\:text-purple-200{--text-opacity:1;color:#e9d8fd;color:rgba(233,216,253,var(--text-opacity))}.sm\:text-purple-300{--text-opacity:1;color:#d6bcfa;color:rgba(214,188,250,var(--text-opacity))}.sm\:text-purple-400{--text-opacity:1;color:#b794f4;color:rgba(183,148,244,var(--text-opacity))}.sm\:text-purple-500{--text-opacity:1;color:#9f7aea;color:rgba(159,122,234,var(--text-opacity))}.sm\:text-purple-600{--text-opacity:1;color:#805ad5;color:rgba(128,90,213,var(--text-opacity))}.sm\:text-purple-700{--text-opacity:1;color:#6b46c1;color:rgba(107,70,193,var(--text-opacity))}.sm\:text-purple-800{--text-opacity:1;color:#553c9a;color:rgba(85,60,154,var(--text-opacity))}.sm\:text-purple-900{--text-opacity:1;color:#44337a;color:rgba(68,51,122,var(--text-opacity))}.sm\:text-pink-100{--text-opacity:1;color:#fff5f7;color:rgba(255,245,247,var(--text-opacity))}.sm\:text-pink-200{--text-opacity:1;color:#fed7e2;color:rgba(254,215,226,var(--text-opacity))}.sm\:text-pink-300{--text-opacity:1;color:#fbb6ce;color:rgba(251,182,206,var(--text-opacity))}.sm\:text-pink-400{--text-opacity:1;color:#f687b3;color:rgba(246,135,179,var(--text-opacity))}.sm\:text-pink-500{--text-opacity:1;color:#ed64a6;color:rgba(237,100,166,var(--text-opacity))}.sm\:text-pink-600{--text-opacity:1;color:#d53f8c;color:rgba(213,63,140,var(--text-opacity))}.sm\:text-pink-700{--text-opacity:1;color:#b83280;color:rgba(184,50,128,var(--text-opacity))}.sm\:text-pink-800{--text-opacity:1;color:#97266d;color:rgba(151,38,109,var(--text-opacity))}.sm\:text-pink-900{--text-opacity:1;color:#702459;color:rgba(112,36,89,var(--text-opacity))}.sm\:hover\:text-transparent:hover{color:transparent}.sm\:hover\:text-current:hover{color:currentColor}.sm\:hover\:text-black:hover{--text-opacity:1;color:#000;color:rgba(0,0,0,var(--text-opacity))}.sm\:hover\:text-white:hover{--text-opacity:1;color:#fff;color:rgba(255,255,255,var(--text-opacity))}.sm\:hover\:text-gray-100:hover{--text-opacity:1;color:#f7fafc;color:rgba(247,250,252,var(--text-opacity))}.sm\:hover\:text-gray-200:hover{--text-opacity:1;color:#edf2f7;color:rgba(237,242,247,var(--text-opacity))}.sm\:hover\:text-gray-300:hover{--text-opacity:1;color:#e2e8f0;color:rgba(226,232,240,var(--text-opacity))}.sm\:hover\:text-gray-400:hover{--text-opacity:1;color:#cbd5e0;color:rgba(203,213,224,var(--text-opacity))}.sm\:hover\:text-gray-500:hover{--text-opacity:1;color:#a0aec0;color:rgba(160,174,192,var(--text-opacity))}.sm\:hover\:text-gray-600:hover{--text-opacity:1;color:#718096;color:rgba(113,128,150,var(--text-opacity))}.sm\:hover\:text-gray-700:hover{--text-opacity:1;color:#4a5568;color:rgba(74,85,104,var(--text-opacity))}.sm\:hover\:text-gray-800:hover{--text-opacity:1;color:#2d3748;color:rgba(45,55,72,var(--text-opacity))}.sm\:hover\:text-gray-900:hover{--text-opacity:1;color:#1a202c;color:rgba(26,32,44,var(--text-opacity))}.sm\:hover\:text-red-100:hover{--text-opacity:1;color:#fff5f5;color:rgba(255,245,245,var(--text-opacity))}.sm\:hover\:text-red-200:hover{--text-opacity:1;color:#fed7d7;color:rgba(254,215,215,var(--text-opacity))}.sm\:hover\:text-red-300:hover{--text-opacity:1;color:#feb2b2;color:rgba(254,178,178,var(--text-opacity))}.sm\:hover\:text-red-400:hover{--text-opacity:1;color:#fc8181;color:rgba(252,129,129,var(--text-opacity))}.sm\:hover\:text-red-500:hover{--text-opacity:1;color:#f56565;color:rgba(245,101,101,var(--text-opacity))}.sm\:hover\:text-red-600:hover{--text-opacity:1;color:#e53e3e;color:rgba(229,62,62,var(--text-opacity))}.sm\:hover\:text-red-700:hover{--text-opacity:1;color:#c53030;color:rgba(197,48,48,var(--text-opacity))}.sm\:hover\:text-red-800:hover{--text-opacity:1;color:#9b2c2c;color:rgba(155,44,44,var(--text-opacity))}.sm\:hover\:text-red-900:hover{--text-opacity:1;color:#742a2a;color:rgba(116,42,42,var(--text-opacity))}.sm\:hover\:text-orange-100:hover{--text-opacity:1;color:#fffaf0;color:rgba(255,250,240,var(--text-opacity))}.sm\:hover\:text-orange-200:hover{--text-opacity:1;color:#feebc8;color:rgba(254,235,200,var(--text-opacity))}.sm\:hover\:text-orange-300:hover{--text-opacity:1;color:#fbd38d;color:rgba(251,211,141,var(--text-opacity))}.sm\:hover\:text-orange-400:hover{--text-opacity:1;color:#f6ad55;color:rgba(246,173,85,var(--text-opacity))}.sm\:hover\:text-orange-500:hover{--text-opacity:1;color:#ed8936;color:rgba(237,137,54,var(--text-opacity))}.sm\:hover\:text-orange-600:hover{--text-opacity:1;color:#dd6b20;color:rgba(221,107,32,var(--text-opacity))}.sm\:hover\:text-orange-700:hover{--text-opacity:1;color:#c05621;color:rgba(192,86,33,var(--text-opacity))}.sm\:hover\:text-orange-800:hover{--text-opacity:1;color:#9c4221;color:rgba(156,66,33,var(--text-opacity))}.sm\:hover\:text-orange-900:hover{--text-opacity:1;color:#7b341e;color:rgba(123,52,30,var(--text-opacity))}.sm\:hover\:text-yellow-100:hover{--text-opacity:1;color:ivory;color:rgba(255,255,240,var(--text-opacity))}.sm\:hover\:text-yellow-200:hover{--text-opacity:1;color:#fefcbf;color:rgba(254,252,191,var(--text-opacity))}.sm\:hover\:text-yellow-300:hover{--text-opacity:1;color:#faf089;color:rgba(250,240,137,var(--text-opacity))}.sm\:hover\:text-yellow-400:hover{--text-opacity:1;color:#f6e05e;color:rgba(246,224,94,var(--text-opacity))}.sm\:hover\:text-yellow-500:hover{--text-opacity:1;color:#ecc94b;color:rgba(236,201,75,var(--text-opacity))}.sm\:hover\:text-yellow-600:hover{--text-opacity:1;color:#d69e2e;color:rgba(214,158,46,var(--text-opacity))}.sm\:hover\:text-yellow-700:hover{--text-opacity:1;color:#b7791f;color:rgba(183,121,31,var(--text-opacity))}.sm\:hover\:text-yellow-800:hover{--text-opacity:1;color:#975a16;color:rgba(151,90,22,var(--text-opacity))}.sm\:hover\:text-yellow-900:hover{--text-opacity:1;color:#744210;color:rgba(116,66,16,var(--text-opacity))}.sm\:hover\:text-green-100:hover{--text-opacity:1;color:#f0fff4;color:rgba(240,255,244,var(--text-opacity))}.sm\:hover\:text-green-200:hover{--text-opacity:1;color:#c6f6d5;color:rgba(198,246,213,var(--text-opacity))}.sm\:hover\:text-green-300:hover{--text-opacity:1;color:#9ae6b4;color:rgba(154,230,180,var(--text-opacity))}.sm\:hover\:text-green-400:hover{--text-opacity:1;color:#68d391;color:rgba(104,211,145,var(--text-opacity))}.sm\:hover\:text-green-500:hover{--text-opacity:1;color:#48bb78;color:rgba(72,187,120,var(--text-opacity))}.sm\:hover\:text-green-600:hover{--text-opacity:1;color:#38a169;color:rgba(56,161,105,var(--text-opacity))}.sm\:hover\:text-green-700:hover{--text-opacity:1;color:#2f855a;color:rgba(47,133,90,var(--text-opacity))}.sm\:hover\:text-green-800:hover{--text-opacity:1;color:#276749;color:rgba(39,103,73,var(--text-opacity))}.sm\:hover\:text-green-900:hover{--text-opacity:1;color:#22543d;color:rgba(34,84,61,var(--text-opacity))}.sm\:hover\:text-teal-100:hover{--text-opacity:1;color:#e6fffa;color:rgba(230,255,250,var(--text-opacity))}.sm\:hover\:text-teal-200:hover{--text-opacity:1;color:#b2f5ea;color:rgba(178,245,234,var(--text-opacity))}.sm\:hover\:text-teal-300:hover{--text-opacity:1;color:#81e6d9;color:rgba(129,230,217,var(--text-opacity))}.sm\:hover\:text-teal-400:hover{--text-opacity:1;color:#4fd1c5;color:rgba(79,209,197,var(--text-opacity))}.sm\:hover\:text-teal-500:hover{--text-opacity:1;color:#38b2ac;color:rgba(56,178,172,var(--text-opacity))}.sm\:hover\:text-teal-600:hover{--text-opacity:1;color:#319795;color:rgba(49,151,149,var(--text-opacity))}.sm\:hover\:text-teal-700:hover{--text-opacity:1;color:#2c7a7b;color:rgba(44,122,123,var(--text-opacity))}.sm\:hover\:text-teal-800:hover{--text-opacity:1;color:#285e61;color:rgba(40,94,97,var(--text-opacity))}.sm\:hover\:text-teal-900:hover{--text-opacity:1;color:#234e52;color:rgba(35,78,82,var(--text-opacity))}.sm\:hover\:text-blue-100:hover{--text-opacity:1;color:#ebf8ff;color:rgba(235,248,255,var(--text-opacity))}.sm\:hover\:text-blue-200:hover{--text-opacity:1;color:#bee3f8;color:rgba(190,227,248,var(--text-opacity))}.sm\:hover\:text-blue-300:hover{--text-opacity:1;color:#90cdf4;color:rgba(144,205,244,var(--text-opacity))}.sm\:hover\:text-blue-400:hover{--text-opacity:1;color:#63b3ed;color:rgba(99,179,237,var(--text-opacity))}.sm\:hover\:text-blue-500:hover{--text-opacity:1;color:#4299e1;color:rgba(66,153,225,var(--text-opacity))}.sm\:hover\:text-blue-600:hover{--text-opacity:1;color:#3182ce;color:rgba(49,130,206,var(--text-opacity))}.sm\:hover\:text-blue-700:hover{--text-opacity:1;color:#2b6cb0;color:rgba(43,108,176,var(--text-opacity))}.sm\:hover\:text-blue-800:hover{--text-opacity:1;color:#2c5282;color:rgba(44,82,130,var(--text-opacity))}.sm\:hover\:text-blue-900:hover{--text-opacity:1;color:#2a4365;color:rgba(42,67,101,var(--text-opacity))}.sm\:hover\:text-indigo-100:hover{--text-opacity:1;color:#ebf4ff;color:rgba(235,244,255,var(--text-opacity))}.sm\:hover\:text-indigo-200:hover{--text-opacity:1;color:#c3dafe;color:rgba(195,218,254,var(--text-opacity))}.sm\:hover\:text-indigo-300:hover{--text-opacity:1;color:#a3bffa;color:rgba(163,191,250,var(--text-opacity))}.sm\:hover\:text-indigo-400:hover{--text-opacity:1;color:#7f9cf5;color:rgba(127,156,245,var(--text-opacity))}.sm\:hover\:text-indigo-500:hover{--text-opacity:1;color:#667eea;color:rgba(102,126,234,var(--text-opacity))}.sm\:hover\:text-indigo-600:hover{--text-opacity:1;color:#5a67d8;color:rgba(90,103,216,var(--text-opacity))}.sm\:hover\:text-indigo-700:hover{--text-opacity:1;color:#4c51bf;color:rgba(76,81,191,var(--text-opacity))}.sm\:hover\:text-indigo-800:hover{--text-opacity:1;color:#434190;color:rgba(67,65,144,var(--text-opacity))}.sm\:hover\:text-indigo-900:hover{--text-opacity:1;color:#3c366b;color:rgba(60,54,107,var(--text-opacity))}.sm\:hover\:text-purple-100:hover{--text-opacity:1;color:#faf5ff;color:rgba(250,245,255,var(--text-opacity))}.sm\:hover\:text-purple-200:hover{--text-opacity:1;color:#e9d8fd;color:rgba(233,216,253,var(--text-opacity))}.sm\:hover\:text-purple-300:hover{--text-opacity:1;color:#d6bcfa;color:rgba(214,188,250,var(--text-opacity))}.sm\:hover\:text-purple-400:hover{--text-opacity:1;color:#b794f4;color:rgba(183,148,244,var(--text-opacity))}.sm\:hover\:text-purple-500:hover{--text-opacity:1;color:#9f7aea;color:rgba(159,122,234,var(--text-opacity))}.sm\:hover\:text-purple-600:hover{--text-opacity:1;color:#805ad5;color:rgba(128,90,213,var(--text-opacity))}.sm\:hover\:text-purple-700:hover{--text-opacity:1;color:#6b46c1;color:rgba(107,70,193,var(--text-opacity))}.sm\:hover\:text-purple-800:hover{--text-opacity:1;color:#553c9a;color:rgba(85,60,154,var(--text-opacity))}.sm\:hover\:text-purple-900:hover{--text-opacity:1;color:#44337a;color:rgba(68,51,122,var(--text-opacity))}.sm\:hover\:text-pink-100:hover{--text-opacity:1;color:#fff5f7;color:rgba(255,245,247,var(--text-opacity))}.sm\:hover\:text-pink-200:hover{--text-opacity:1;color:#fed7e2;color:rgba(254,215,226,var(--text-opacity))}.sm\:hover\:text-pink-300:hover{--text-opacity:1;color:#fbb6ce;color:rgba(251,182,206,var(--text-opacity))}.sm\:hover\:text-pink-400:hover{--text-opacity:1;color:#f687b3;color:rgba(246,135,179,var(--text-opacity))}.sm\:hover\:text-pink-500:hover{--text-opacity:1;color:#ed64a6;color:rgba(237,100,166,var(--text-opacity))}.sm\:hover\:text-pink-600:hover{--text-opacity:1;color:#d53f8c;color:rgba(213,63,140,var(--text-opacity))}.sm\:hover\:text-pink-700:hover{--text-opacity:1;color:#b83280;color:rgba(184,50,128,var(--text-opacity))}.sm\:hover\:text-pink-800:hover{--text-opacity:1;color:#97266d;color:rgba(151,38,109,var(--text-opacity))}.sm\:hover\:text-pink-900:hover{--text-opacity:1;color:#702459;color:rgba(112,36,89,var(--text-opacity))}.sm\:focus\:text-transparent:focus{color:transparent}.sm\:focus\:text-current:focus{color:currentColor}.sm\:focus\:text-black:focus{--text-opacity:1;color:#000;color:rgba(0,0,0,var(--text-opacity))}.sm\:focus\:text-white:focus{--text-opacity:1;color:#fff;color:rgba(255,255,255,var(--text-opacity))}.sm\:focus\:text-gray-100:focus{--text-opacity:1;color:#f7fafc;color:rgba(247,250,252,var(--text-opacity))}.sm\:focus\:text-gray-200:focus{--text-opacity:1;color:#edf2f7;color:rgba(237,242,247,var(--text-opacity))}.sm\:focus\:text-gray-300:focus{--text-opacity:1;color:#e2e8f0;color:rgba(226,232,240,var(--text-opacity))}.sm\:focus\:text-gray-400:focus{--text-opacity:1;color:#cbd5e0;color:rgba(203,213,224,var(--text-opacity))}.sm\:focus\:text-gray-500:focus{--text-opacity:1;color:#a0aec0;color:rgba(160,174,192,var(--text-opacity))}.sm\:focus\:text-gray-600:focus{--text-opacity:1;color:#718096;color:rgba(113,128,150,var(--text-opacity))}.sm\:focus\:text-gray-700:focus{--text-opacity:1;color:#4a5568;color:rgba(74,85,104,var(--text-opacity))}.sm\:focus\:text-gray-800:focus{--text-opacity:1;color:#2d3748;color:rgba(45,55,72,var(--text-opacity))}.sm\:focus\:text-gray-900:focus{--text-opacity:1;color:#1a202c;color:rgba(26,32,44,var(--text-opacity))}.sm\:focus\:text-red-100:focus{--text-opacity:1;color:#fff5f5;color:rgba(255,245,245,var(--text-opacity))}.sm\:focus\:text-red-200:focus{--text-opacity:1;color:#fed7d7;color:rgba(254,215,215,var(--text-opacity))}.sm\:focus\:text-red-300:focus{--text-opacity:1;color:#feb2b2;color:rgba(254,178,178,var(--text-opacity))}.sm\:focus\:text-red-400:focus{--text-opacity:1;color:#fc8181;color:rgba(252,129,129,var(--text-opacity))}.sm\:focus\:text-red-500:focus{--text-opacity:1;color:#f56565;color:rgba(245,101,101,var(--text-opacity))}.sm\:focus\:text-red-600:focus{--text-opacity:1;color:#e53e3e;color:rgba(229,62,62,var(--text-opacity))}.sm\:focus\:text-red-700:focus{--text-opacity:1;color:#c53030;color:rgba(197,48,48,var(--text-opacity))}.sm\:focus\:text-red-800:focus{--text-opacity:1;color:#9b2c2c;color:rgba(155,44,44,var(--text-opacity))}.sm\:focus\:text-red-900:focus{--text-opacity:1;color:#742a2a;color:rgba(116,42,42,var(--text-opacity))}.sm\:focus\:text-orange-100:focus{--text-opacity:1;color:#fffaf0;color:rgba(255,250,240,var(--text-opacity))}.sm\:focus\:text-orange-200:focus{--text-opacity:1;color:#feebc8;color:rgba(254,235,200,var(--text-opacity))}.sm\:focus\:text-orange-300:focus{--text-opacity:1;color:#fbd38d;color:rgba(251,211,141,var(--text-opacity))}.sm\:focus\:text-orange-400:focus{--text-opacity:1;color:#f6ad55;color:rgba(246,173,85,var(--text-opacity))}.sm\:focus\:text-orange-500:focus{--text-opacity:1;color:#ed8936;color:rgba(237,137,54,var(--text-opacity))}.sm\:focus\:text-orange-600:focus{--text-opacity:1;color:#dd6b20;color:rgba(221,107,32,var(--text-opacity))}.sm\:focus\:text-orange-700:focus{--text-opacity:1;color:#c05621;color:rgba(192,86,33,var(--text-opacity))}.sm\:focus\:text-orange-800:focus{--text-opacity:1;color:#9c4221;color:rgba(156,66,33,var(--text-opacity))}.sm\:focus\:text-orange-900:focus{--text-opacity:1;color:#7b341e;color:rgba(123,52,30,var(--text-opacity))}.sm\:focus\:text-yellow-100:focus{--text-opacity:1;color:ivory;color:rgba(255,255,240,var(--text-opacity))}.sm\:focus\:text-yellow-200:focus{--text-opacity:1;color:#fefcbf;color:rgba(254,252,191,var(--text-opacity))}.sm\:focus\:text-yellow-300:focus{--text-opacity:1;color:#faf089;color:rgba(250,240,137,var(--text-opacity))}.sm\:focus\:text-yellow-400:focus{--text-opacity:1;color:#f6e05e;color:rgba(246,224,94,var(--text-opacity))}.sm\:focus\:text-yellow-500:focus{--text-opacity:1;color:#ecc94b;color:rgba(236,201,75,var(--text-opacity))}.sm\:focus\:text-yellow-600:focus{--text-opacity:1;color:#d69e2e;color:rgba(214,158,46,var(--text-opacity))}.sm\:focus\:text-yellow-700:focus{--text-opacity:1;color:#b7791f;color:rgba(183,121,31,var(--text-opacity))}.sm\:focus\:text-yellow-800:focus{--text-opacity:1;color:#975a16;color:rgba(151,90,22,var(--text-opacity))}.sm\:focus\:text-yellow-900:focus{--text-opacity:1;color:#744210;color:rgba(116,66,16,var(--text-opacity))}.sm\:focus\:text-green-100:focus{--text-opacity:1;color:#f0fff4;color:rgba(240,255,244,var(--text-opacity))}.sm\:focus\:text-green-200:focus{--text-opacity:1;color:#c6f6d5;color:rgba(198,246,213,var(--text-opacity))}.sm\:focus\:text-green-300:focus{--text-opacity:1;color:#9ae6b4;color:rgba(154,230,180,var(--text-opacity))}.sm\:focus\:text-green-400:focus{--text-opacity:1;color:#68d391;color:rgba(104,211,145,var(--text-opacity))}.sm\:focus\:text-green-500:focus{--text-opacity:1;color:#48bb78;color:rgba(72,187,120,var(--text-opacity))}.sm\:focus\:text-green-600:focus{--text-opacity:1;color:#38a169;color:rgba(56,161,105,var(--text-opacity))}.sm\:focus\:text-green-700:focus{--text-opacity:1;color:#2f855a;color:rgba(47,133,90,var(--text-opacity))}.sm\:focus\:text-green-800:focus{--text-opacity:1;color:#276749;color:rgba(39,103,73,var(--text-opacity))}.sm\:focus\:text-green-900:focus{--text-opacity:1;color:#22543d;color:rgba(34,84,61,var(--text-opacity))}.sm\:focus\:text-teal-100:focus{--text-opacity:1;color:#e6fffa;color:rgba(230,255,250,var(--text-opacity))}.sm\:focus\:text-teal-200:focus{--text-opacity:1;color:#b2f5ea;color:rgba(178,245,234,var(--text-opacity))}.sm\:focus\:text-teal-300:focus{--text-opacity:1;color:#81e6d9;color:rgba(129,230,217,var(--text-opacity))}.sm\:focus\:text-teal-400:focus{--text-opacity:1;color:#4fd1c5;color:rgba(79,209,197,var(--text-opacity))}.sm\:focus\:text-teal-500:focus{--text-opacity:1;color:#38b2ac;color:rgba(56,178,172,var(--text-opacity))}.sm\:focus\:text-teal-600:focus{--text-opacity:1;color:#319795;color:rgba(49,151,149,var(--text-opacity))}.sm\:focus\:text-teal-700:focus{--text-opacity:1;color:#2c7a7b;color:rgba(44,122,123,var(--text-opacity))}.sm\:focus\:text-teal-800:focus{--text-opacity:1;color:#285e61;color:rgba(40,94,97,var(--text-opacity))}.sm\:focus\:text-teal-900:focus{--text-opacity:1;color:#234e52;color:rgba(35,78,82,var(--text-opacity))}.sm\:focus\:text-blue-100:focus{--text-opacity:1;color:#ebf8ff;color:rgba(235,248,255,var(--text-opacity))}.sm\:focus\:text-blue-200:focus{--text-opacity:1;color:#bee3f8;color:rgba(190,227,248,var(--text-opacity))}.sm\:focus\:text-blue-300:focus{--text-opacity:1;color:#90cdf4;color:rgba(144,205,244,var(--text-opacity))}.sm\:focus\:text-blue-400:focus{--text-opacity:1;color:#63b3ed;color:rgba(99,179,237,var(--text-opacity))}.sm\:focus\:text-blue-500:focus{--text-opacity:1;color:#4299e1;color:rgba(66,153,225,var(--text-opacity))}.sm\:focus\:text-blue-600:focus{--text-opacity:1;color:#3182ce;color:rgba(49,130,206,var(--text-opacity))}.sm\:focus\:text-blue-700:focus{--text-opacity:1;color:#2b6cb0;color:rgba(43,108,176,var(--text-opacity))}.sm\:focus\:text-blue-800:focus{--text-opacity:1;color:#2c5282;color:rgba(44,82,130,var(--text-opacity))}.sm\:focus\:text-blue-900:focus{--text-opacity:1;color:#2a4365;color:rgba(42,67,101,var(--text-opacity))}.sm\:focus\:text-indigo-100:focus{--text-opacity:1;color:#ebf4ff;color:rgba(235,244,255,var(--text-opacity))}.sm\:focus\:text-indigo-200:focus{--text-opacity:1;color:#c3dafe;color:rgba(195,218,254,var(--text-opacity))}.sm\:focus\:text-indigo-300:focus{--text-opacity:1;color:#a3bffa;color:rgba(163,191,250,var(--text-opacity))}.sm\:focus\:text-indigo-400:focus{--text-opacity:1;color:#7f9cf5;color:rgba(127,156,245,var(--text-opacity))}.sm\:focus\:text-indigo-500:focus{--text-opacity:1;color:#667eea;color:rgba(102,126,234,var(--text-opacity))}.sm\:focus\:text-indigo-600:focus{--text-opacity:1;color:#5a67d8;color:rgba(90,103,216,var(--text-opacity))}.sm\:focus\:text-indigo-700:focus{--text-opacity:1;color:#4c51bf;color:rgba(76,81,191,var(--text-opacity))}.sm\:focus\:text-indigo-800:focus{--text-opacity:1;color:#434190;color:rgba(67,65,144,var(--text-opacity))}.sm\:focus\:text-indigo-900:focus{--text-opacity:1;color:#3c366b;color:rgba(60,54,107,var(--text-opacity))}.sm\:focus\:text-purple-100:focus{--text-opacity:1;color:#faf5ff;color:rgba(250,245,255,var(--text-opacity))}.sm\:focus\:text-purple-200:focus{--text-opacity:1;color:#e9d8fd;color:rgba(233,216,253,var(--text-opacity))}.sm\:focus\:text-purple-300:focus{--text-opacity:1;color:#d6bcfa;color:rgba(214,188,250,var(--text-opacity))}.sm\:focus\:text-purple-400:focus{--text-opacity:1;color:#b794f4;color:rgba(183,148,244,var(--text-opacity))}.sm\:focus\:text-purple-500:focus{--text-opacity:1;color:#9f7aea;color:rgba(159,122,234,var(--text-opacity))}.sm\:focus\:text-purple-600:focus{--text-opacity:1;color:#805ad5;color:rgba(128,90,213,var(--text-opacity))}.sm\:focus\:text-purple-700:focus{--text-opacity:1;color:#6b46c1;color:rgba(107,70,193,var(--text-opacity))}.sm\:focus\:text-purple-800:focus{--text-opacity:1;color:#553c9a;color:rgba(85,60,154,var(--text-opacity))}.sm\:focus\:text-purple-900:focus{--text-opacity:1;color:#44337a;color:rgba(68,51,122,var(--text-opacity))}.sm\:focus\:text-pink-100:focus{--text-opacity:1;color:#fff5f7;color:rgba(255,245,247,var(--text-opacity))}.sm\:focus\:text-pink-200:focus{--text-opacity:1;color:#fed7e2;color:rgba(254,215,226,var(--text-opacity))}.sm\:focus\:text-pink-300:focus{--text-opacity:1;color:#fbb6ce;color:rgba(251,182,206,var(--text-opacity))}.sm\:focus\:text-pink-400:focus{--text-opacity:1;color:#f687b3;color:rgba(246,135,179,var(--text-opacity))}.sm\:focus\:text-pink-500:focus{--text-opacity:1;color:#ed64a6;color:rgba(237,100,166,var(--text-opacity))}.sm\:focus\:text-pink-600:focus{--text-opacity:1;color:#d53f8c;color:rgba(213,63,140,var(--text-opacity))}.sm\:focus\:text-pink-700:focus{--text-opacity:1;color:#b83280;color:rgba(184,50,128,var(--text-opacity))}.sm\:focus\:text-pink-800:focus{--text-opacity:1;color:#97266d;color:rgba(151,38,109,var(--text-opacity))}.sm\:focus\:text-pink-900:focus{--text-opacity:1;color:#702459;color:rgba(112,36,89,var(--text-opacity))}.sm\:text-opacity-0{--text-opacity:0}.sm\:text-opacity-25{--text-opacity:0.25}.sm\:text-opacity-50{--text-opacity:0.5}.sm\:text-opacity-75{--text-opacity:0.75}.sm\:text-opacity-100{--text-opacity:1}.sm\:hover\:text-opacity-0:hover{--text-opacity:0}.sm\:hover\:text-opacity-25:hover{--text-opacity:0.25}.sm\:hover\:text-opacity-50:hover{--text-opacity:0.5}.sm\:hover\:text-opacity-75:hover{--text-opacity:0.75}.sm\:hover\:text-opacity-100:hover{--text-opacity:1}.sm\:focus\:text-opacity-0:focus{--text-opacity:0}.sm\:focus\:text-opacity-25:focus{--text-opacity:0.25}.sm\:focus\:text-opacity-50:focus{--text-opacity:0.5}.sm\:focus\:text-opacity-75:focus{--text-opacity:0.75}.sm\:focus\:text-opacity-100:focus{--text-opacity:1}.sm\:italic{font-style:italic}.sm\:not-italic{font-style:normal}.sm\:uppercase{text-transform:uppercase}.sm\:lowercase{text-transform:lowercase}.sm\:capitalize{text-transform:capitalize}.sm\:normal-case{text-transform:none}.sm\:underline{text-decoration:underline}.sm\:line-through{text-decoration:line-through}.sm\:no-underline{text-decoration:none}.sm\:hover\:underline:hover{text-decoration:underline}.sm\:hover\:line-through:hover{text-decoration:line-through}.sm\:hover\:no-underline:hover{text-decoration:none}.sm\:focus\:underline:focus{text-decoration:underline}.sm\:focus\:line-through:focus{text-decoration:line-through}.sm\:focus\:no-underline:focus{text-decoration:none}.sm\:antialiased{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.sm\:subpixel-antialiased{-webkit-font-smoothing:auto;-moz-osx-font-smoothing:auto}.sm\:diagonal-fractions,.sm\:lining-nums,.sm\:oldstyle-nums,.sm\:ordinal,.sm\:proportional-nums,.sm\:slashed-zero,.sm\:stacked-fractions,.sm\:tabular-nums{--font-variant-numeric-ordinal:var(--tailwind-empty, );/*!*//*!*/--font-variant-numeric-slashed-zero:var(--tailwind-empty, );/*!*//*!*/--font-variant-numeric-figure:var(--tailwind-empty, );/*!*//*!*/--font-variant-numeric-spacing:var(--tailwind-empty, );/*!*//*!*/--font-variant-numeric-fraction:var(--tailwind-empty, );/*!*//*!*/font-variant-numeric:var(--font-variant-numeric-ordinal) var(--font-variant-numeric-slashed-zero) var(--font-variant-numeric-figure) var(--font-variant-numeric-spacing) var(--font-variant-numeric-fraction)}.sm\:normal-nums{font-variant-numeric:normal}.sm\:ordinal{--font-variant-numeric-ordinal:ordinal}.sm\:slashed-zero{--font-variant-numeric-slashed-zero:slashed-zero}.sm\:lining-nums{--font-variant-numeric-figure:lining-nums}.sm\:oldstyle-nums{--font-variant-numeric-figure:oldstyle-nums}.sm\:proportional-nums{--font-variant-numeric-spacing:proportional-nums}.sm\:tabular-nums{--font-variant-numeric-spacing:tabular-nums}.sm\:diagonal-fractions{--font-variant-numeric-fraction:diagonal-fractions}.sm\:stacked-fractions{--font-variant-numeric-fraction:stacked-fractions}.sm\:tracking-tighter{letter-spacing:-.05em}.sm\:tracking-tight{letter-spacing:-.025em}.sm\:tracking-normal{letter-spacing:0}.sm\:tracking-wide{letter-spacing:.025em}.sm\:tracking-wider{letter-spacing:.05em}.sm\:tracking-widest{letter-spacing:.1em}.sm\:select-none{-webkit-user-select:none;-ms-user-select:none;user-select:none}.sm\:select-text{-webkit-user-select:text;-ms-user-select:text;user-select:text}.sm\:select-all{-webkit-user-select:all;-ms-user-select:all;user-select:all}.sm\:select-auto{-webkit-user-select:auto;-ms-user-select:auto;user-select:auto}.sm\:align-baseline{vertical-align:baseline}.sm\:align-top{vertical-align:top}.sm\:align-middle{vertical-align:middle}.sm\:align-bottom{vertical-align:bottom}.sm\:align-text-top{vertical-align:text-top}.sm\:align-text-bottom{vertical-align:text-bottom}.sm\:visible{visibility:visible}.sm\:invisible{visibility:hidden}.sm\:whitespace-normal{white-space:normal}.sm\:whitespace-no-wrap{white-space:nowrap}.sm\:whitespace-pre{white-space:pre}.sm\:whitespace-pre-line{white-space:pre-line}.sm\:whitespace-pre-wrap{white-space:pre-wrap}.sm\:break-normal{word-wrap:normal;overflow-wrap:normal;word-break:normal}.sm\:break-words{word-wrap:break-word;overflow-wrap:break-word}.sm\:break-all{word-break:break-all}.sm\:truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.sm\:w-0{width:0}.sm\:w-1{width:.25rem}.sm\:w-2{width:.5rem}.sm\:w-3{width:.75rem}.sm\:w-4{width:1rem}.sm\:w-5{width:1.25rem}.sm\:w-6{width:1.5rem}.sm\:w-8{width:2rem}.sm\:w-10{width:2.5rem}.sm\:w-12{width:3rem}.sm\:w-16{width:4rem}.sm\:w-20{width:5rem}.sm\:w-24{width:6rem}.sm\:w-32{width:8rem}.sm\:w-40{width:10rem}.sm\:w-48{width:12rem}.sm\:w-56{width:14rem}.sm\:w-64{width:16rem}.sm\:w-auto{width:auto}.sm\:w-px{width:1px}.sm\:w-1\/2{width:50%}.sm\:w-1\/3{width:33.333333%}.sm\:w-2\/3{width:66.666667%}.sm\:w-1\/4{width:25%}.sm\:w-2\/4{width:50%}.sm\:w-3\/4{width:75%}.sm\:w-1\/5{width:20%}.sm\:w-2\/5{width:40%}.sm\:w-3\/5{width:60%}.sm\:w-4\/5{width:80%}.sm\:w-1\/6{width:16.666667%}.sm\:w-2\/6{width:33.333333%}.sm\:w-3\/6{width:50%}.sm\:w-4\/6{width:66.666667%}.sm\:w-5\/6{width:83.333333%}.sm\:w-1\/12{width:8.333333%}.sm\:w-2\/12{width:16.666667%}.sm\:w-3\/12{width:25%}.sm\:w-4\/12{width:33.333333%}.sm\:w-5\/12{width:41.666667%}.sm\:w-6\/12{width:50%}.sm\:w-7\/12{width:58.333333%}.sm\:w-8\/12{width:66.666667%}.sm\:w-9\/12{width:75%}.sm\:w-10\/12{width:83.333333%}.sm\:w-11\/12{width:91.666667%}.sm\:w-full{width:100%}.sm\:w-screen{width:100vw}.sm\:z-0{z-index:0}.sm\:z-10{z-index:10}.sm\:z-20{z-index:20}.sm\:z-30{z-index:30}.sm\:z-40{z-index:40}.sm\:z-50{z-index:50}.sm\:z-auto{z-index:auto}.sm\:gap-0{grid-gap:0;gap:0}.sm\:gap-1{grid-gap:.25rem;gap:.25rem}.sm\:gap-2{grid-gap:.5rem;gap:.5rem}.sm\:gap-3{grid-gap:.75rem;gap:.75rem}.sm\:gap-4{grid-gap:1rem;gap:1rem}.sm\:gap-5{grid-gap:1.25rem;gap:1.25rem}.sm\:gap-6{grid-gap:1.5rem;gap:1.5rem}.sm\:gap-8{grid-gap:2rem;gap:2rem}.sm\:gap-10{grid-gap:2.5rem;gap:2.5rem}.sm\:gap-12{grid-gap:3rem;gap:3rem}.sm\:gap-16{grid-gap:4rem;gap:4rem}.sm\:gap-20{grid-gap:5rem;gap:5rem}.sm\:gap-24{grid-gap:6rem;gap:6rem}.sm\:gap-32{grid-gap:8rem;gap:8rem}.sm\:gap-40{grid-gap:10rem;gap:10rem}.sm\:gap-48{grid-gap:12rem;gap:12rem}.sm\:gap-56{grid-gap:14rem;gap:14rem}.sm\:gap-64{grid-gap:16rem;gap:16rem}.sm\:gap-px{grid-gap:1px;gap:1px}.sm\:col-gap-0{grid-column-gap:0;column-gap:0}.sm\:col-gap-1{grid-column-gap:.25rem;column-gap:.25rem}.sm\:col-gap-2{grid-column-gap:.5rem;column-gap:.5rem}.sm\:col-gap-3{grid-column-gap:.75rem;column-gap:.75rem}.sm\:col-gap-4{grid-column-gap:1rem;column-gap:1rem}.sm\:col-gap-5{grid-column-gap:1.25rem;column-gap:1.25rem}.sm\:col-gap-6{grid-column-gap:1.5rem;column-gap:1.5rem}.sm\:col-gap-8{grid-column-gap:2rem;column-gap:2rem}.sm\:col-gap-10{grid-column-gap:2.5rem;column-gap:2.5rem}.sm\:col-gap-12{grid-column-gap:3rem;column-gap:3rem}.sm\:col-gap-16{grid-column-gap:4rem;column-gap:4rem}.sm\:col-gap-20{grid-column-gap:5rem;column-gap:5rem}.sm\:col-gap-24{grid-column-gap:6rem;column-gap:6rem}.sm\:col-gap-32{grid-column-gap:8rem;column-gap:8rem}.sm\:col-gap-40{grid-column-gap:10rem;column-gap:10rem}.sm\:col-gap-48{grid-column-gap:12rem;column-gap:12rem}.sm\:col-gap-56{grid-column-gap:14rem;column-gap:14rem}.sm\:col-gap-64{grid-column-gap:16rem;column-gap:16rem}.sm\:col-gap-px{grid-column-gap:1px;column-gap:1px}.sm\:gap-x-0{grid-column-gap:0;column-gap:0}.sm\:gap-x-1{grid-column-gap:.25rem;column-gap:.25rem}.sm\:gap-x-2{grid-column-gap:.5rem;column-gap:.5rem}.sm\:gap-x-3{grid-column-gap:.75rem;column-gap:.75rem}.sm\:gap-x-4{grid-column-gap:1rem;column-gap:1rem}.sm\:gap-x-5{grid-column-gap:1.25rem;column-gap:1.25rem}.sm\:gap-x-6{grid-column-gap:1.5rem;column-gap:1.5rem}.sm\:gap-x-8{grid-column-gap:2rem;column-gap:2rem}.sm\:gap-x-10{grid-column-gap:2.5rem;column-gap:2.5rem}.sm\:gap-x-12{grid-column-gap:3rem;column-gap:3rem}.sm\:gap-x-16{grid-column-gap:4rem;column-gap:4rem}.sm\:gap-x-20{grid-column-gap:5rem;column-gap:5rem}.sm\:gap-x-24{grid-column-gap:6rem;column-gap:6rem}.sm\:gap-x-32{grid-column-gap:8rem;column-gap:8rem}.sm\:gap-x-40{grid-column-gap:10rem;column-gap:10rem}.sm\:gap-x-48{grid-column-gap:12rem;column-gap:12rem}.sm\:gap-x-56{grid-column-gap:14rem;column-gap:14rem}.sm\:gap-x-64{grid-column-gap:16rem;column-gap:16rem}.sm\:gap-x-px{grid-column-gap:1px;column-gap:1px}.sm\:row-gap-0{grid-row-gap:0;row-gap:0}.sm\:row-gap-1{grid-row-gap:.25rem;row-gap:.25rem}.sm\:row-gap-2{grid-row-gap:.5rem;row-gap:.5rem}.sm\:row-gap-3{grid-row-gap:.75rem;row-gap:.75rem}.sm\:row-gap-4{grid-row-gap:1rem;row-gap:1rem}.sm\:row-gap-5{grid-row-gap:1.25rem;row-gap:1.25rem}.sm\:row-gap-6{grid-row-gap:1.5rem;row-gap:1.5rem}.sm\:row-gap-8{grid-row-gap:2rem;row-gap:2rem}.sm\:row-gap-10{grid-row-gap:2.5rem;row-gap:2.5rem}.sm\:row-gap-12{grid-row-gap:3rem;row-gap:3rem}.sm\:row-gap-16{grid-row-gap:4rem;row-gap:4rem}.sm\:row-gap-20{grid-row-gap:5rem;row-gap:5rem}.sm\:row-gap-24{grid-row-gap:6rem;row-gap:6rem}.sm\:row-gap-32{grid-row-gap:8rem;row-gap:8rem}.sm\:row-gap-40{grid-row-gap:10rem;row-gap:10rem}.sm\:row-gap-48{grid-row-gap:12rem;row-gap:12rem}.sm\:row-gap-56{grid-row-gap:14rem;row-gap:14rem}.sm\:row-gap-64{grid-row-gap:16rem;row-gap:16rem}.sm\:row-gap-px{grid-row-gap:1px;row-gap:1px}.sm\:gap-y-0{grid-row-gap:0;row-gap:0}.sm\:gap-y-1{grid-row-gap:.25rem;row-gap:.25rem}.sm\:gap-y-2{grid-row-gap:.5rem;row-gap:.5rem}.sm\:gap-y-3{grid-row-gap:.75rem;row-gap:.75rem}.sm\:gap-y-4{grid-row-gap:1rem;row-gap:1rem}.sm\:gap-y-5{grid-row-gap:1.25rem;row-gap:1.25rem}.sm\:gap-y-6{grid-row-gap:1.5rem;row-gap:1.5rem}.sm\:gap-y-8{grid-row-gap:2rem;row-gap:2rem}.sm\:gap-y-10{grid-row-gap:2.5rem;row-gap:2.5rem}.sm\:gap-y-12{grid-row-gap:3rem;row-gap:3rem}.sm\:gap-y-16{grid-row-gap:4rem;row-gap:4rem}.sm\:gap-y-20{grid-row-gap:5rem;row-gap:5rem}.sm\:gap-y-24{grid-row-gap:6rem;row-gap:6rem}.sm\:gap-y-32{grid-row-gap:8rem;row-gap:8rem}.sm\:gap-y-40{grid-row-gap:10rem;row-gap:10rem}.sm\:gap-y-48{grid-row-gap:12rem;row-gap:12rem}.sm\:gap-y-56{grid-row-gap:14rem;row-gap:14rem}.sm\:gap-y-64{grid-row-gap:16rem;row-gap:16rem}.sm\:gap-y-px{grid-row-gap:1px;row-gap:1px}.sm\:grid-flow-row{grid-auto-flow:row}.sm\:grid-flow-col{grid-auto-flow:column}.sm\:grid-flow-row-dense{grid-auto-flow:row dense}.sm\:grid-flow-col-dense{grid-auto-flow:column dense}.sm\:grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.sm\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.sm\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.sm\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.sm\:grid-cols-5{grid-template-columns:repeat(5,minmax(0,1fr))}.sm\:grid-cols-6{grid-template-columns:repeat(6,minmax(0,1fr))}.sm\:grid-cols-7{grid-template-columns:repeat(7,minmax(0,1fr))}.sm\:grid-cols-8{grid-template-columns:repeat(8,minmax(0,1fr))}.sm\:grid-cols-9{grid-template-columns:repeat(9,minmax(0,1fr))}.sm\:grid-cols-10{grid-template-columns:repeat(10,minmax(0,1fr))}.sm\:grid-cols-11{grid-template-columns:repeat(11,minmax(0,1fr))}.sm\:grid-cols-12{grid-template-columns:repeat(12,minmax(0,1fr))}.sm\:grid-cols-none{grid-template-columns:none}.sm\:auto-cols-auto{grid-auto-columns:auto}.sm\:auto-cols-min{grid-auto-columns:-webkit-min-content;grid-auto-columns:min-content}.sm\:auto-cols-max{grid-auto-columns:-webkit-max-content;grid-auto-columns:max-content}.sm\:auto-cols-fr{grid-auto-columns:minmax(0,1fr)}.sm\:col-auto{grid-column:auto}.sm\:col-span-1{grid-column:span 1/span 1}.sm\:col-span-2{grid-column:span 2/span 2}.sm\:col-span-3{grid-column:span 3/span 3}.sm\:col-span-4{grid-column:span 4/span 4}.sm\:col-span-5{grid-column:span 5/span 5}.sm\:col-span-6{grid-column:span 6/span 6}.sm\:col-span-7{grid-column:span 7/span 7}.sm\:col-span-8{grid-column:span 8/span 8}.sm\:col-span-9{grid-column:span 9/span 9}.sm\:col-span-10{grid-column:span 10/span 10}.sm\:col-span-11{grid-column:span 11/span 11}.sm\:col-span-12{grid-column:span 12/span 12}.sm\:col-span-full{grid-column:1/-1}.sm\:col-start-1{grid-column-start:1}.sm\:col-start-2{grid-column-start:2}.sm\:col-start-3{grid-column-start:3}.sm\:col-start-4{grid-column-start:4}.sm\:col-start-5{grid-column-start:5}.sm\:col-start-6{grid-column-start:6}.sm\:col-start-7{grid-column-start:7}.sm\:col-start-8{grid-column-start:8}.sm\:col-start-9{grid-column-start:9}.sm\:col-start-10{grid-column-start:10}.sm\:col-start-11{grid-column-start:11}.sm\:col-start-12{grid-column-start:12}.sm\:col-start-13{grid-column-start:13}.sm\:col-start-auto{grid-column-start:auto}.sm\:col-end-1{grid-column-end:1}.sm\:col-end-2{grid-column-end:2}.sm\:col-end-3{grid-column-end:3}.sm\:col-end-4{grid-column-end:4}.sm\:col-end-5{grid-column-end:5}.sm\:col-end-6{grid-column-end:6}.sm\:col-end-7{grid-column-end:7}.sm\:col-end-8{grid-column-end:8}.sm\:col-end-9{grid-column-end:9}.sm\:col-end-10{grid-column-end:10}.sm\:col-end-11{grid-column-end:11}.sm\:col-end-12{grid-column-end:12}.sm\:col-end-13{grid-column-end:13}.sm\:col-end-auto{grid-column-end:auto}.sm\:grid-rows-1{grid-template-rows:repeat(1,minmax(0,1fr))}.sm\:grid-rows-2{grid-template-rows:repeat(2,minmax(0,1fr))}.sm\:grid-rows-3{grid-template-rows:repeat(3,minmax(0,1fr))}.sm\:grid-rows-4{grid-template-rows:repeat(4,minmax(0,1fr))}.sm\:grid-rows-5{grid-template-rows:repeat(5,minmax(0,1fr))}.sm\:grid-rows-6{grid-template-rows:repeat(6,minmax(0,1fr))}.sm\:grid-rows-none{grid-template-rows:none}.sm\:auto-rows-auto{grid-auto-rows:auto}.sm\:auto-rows-min{grid-auto-rows:-webkit-min-content;grid-auto-rows:min-content}.sm\:auto-rows-max{grid-auto-rows:-webkit-max-content;grid-auto-rows:max-content}.sm\:auto-rows-fr{grid-auto-rows:minmax(0,1fr)}.sm\:row-auto{grid-row:auto}.sm\:row-span-1{grid-row:span 1/span 1}.sm\:row-span-2{grid-row:span 2/span 2}.sm\:row-span-3{grid-row:span 3/span 3}.sm\:row-span-4{grid-row:span 4/span 4}.sm\:row-span-5{grid-row:span 5/span 5}.sm\:row-span-6{grid-row:span 6/span 6}.sm\:row-span-full{grid-row:1/-1}.sm\:row-start-1{grid-row-start:1}.sm\:row-start-2{grid-row-start:2}.sm\:row-start-3{grid-row-start:3}.sm\:row-start-4{grid-row-start:4}.sm\:row-start-5{grid-row-start:5}.sm\:row-start-6{grid-row-start:6}.sm\:row-start-7{grid-row-start:7}.sm\:row-start-auto{grid-row-start:auto}.sm\:row-end-1{grid-row-end:1}.sm\:row-end-2{grid-row-end:2}.sm\:row-end-3{grid-row-end:3}.sm\:row-end-4{grid-row-end:4}.sm\:row-end-5{grid-row-end:5}.sm\:row-end-6{grid-row-end:6}.sm\:row-end-7{grid-row-end:7}.sm\:row-end-auto{grid-row-end:auto}.sm\:transform{--transform-translate-x:0;--transform-translate-y:0;--transform-rotate:0;--transform-skew-x:0;--transform-skew-y:0;--transform-scale-x:1;--transform-scale-y:1;transform:translateX(var(--transform-translate-x)) translateY(var(--transform-translate-y)) rotate(var(--transform-rotate)) skewX(var(--transform-skew-x)) skewY(var(--transform-skew-y)) scaleX(var(--transform-scale-x)) scaleY(var(--transform-scale-y))}.sm\:transform-none{transform:none}.sm\:origin-center{transform-origin:center}.sm\:origin-top{transform-origin:top}.sm\:origin-top-right{transform-origin:top right}.sm\:origin-right{transform-origin:right}.sm\:origin-bottom-right{transform-origin:bottom right}.sm\:origin-bottom{transform-origin:bottom}.sm\:origin-bottom-left{transform-origin:bottom left}.sm\:origin-left{transform-origin:left}.sm\:origin-top-left{transform-origin:top left}.sm\:scale-0{--transform-scale-x:0;--transform-scale-y:0}.sm\:scale-50{--transform-scale-x:.5;--transform-scale-y:.5}.sm\:scale-75{--transform-scale-x:.75;--transform-scale-y:.75}.sm\:scale-90{--transform-scale-x:.9;--transform-scale-y:.9}.sm\:scale-95{--transform-scale-x:.95;--transform-scale-y:.95}.sm\:scale-100{--transform-scale-x:1;--transform-scale-y:1}.sm\:scale-105{--transform-scale-x:1.05;--transform-scale-y:1.05}.sm\:scale-110{--transform-scale-x:1.1;--transform-scale-y:1.1}.sm\:scale-125{--transform-scale-x:1.25;--transform-scale-y:1.25}.sm\:scale-150{--transform-scale-x:1.5;--transform-scale-y:1.5}.sm\:scale-x-0{--transform-scale-x:0}.sm\:scale-x-50{--transform-scale-x:.5}.sm\:scale-x-75{--transform-scale-x:.75}.sm\:scale-x-90{--transform-scale-x:.9}.sm\:scale-x-95{--transform-scale-x:.95}.sm\:scale-x-100{--transform-scale-x:1}.sm\:scale-x-105{--transform-scale-x:1.05}.sm\:scale-x-110{--transform-scale-x:1.1}.sm\:scale-x-125{--transform-scale-x:1.25}.sm\:scale-x-150{--transform-scale-x:1.5}.sm\:scale-y-0{--transform-scale-y:0}.sm\:scale-y-50{--transform-scale-y:.5}.sm\:scale-y-75{--transform-scale-y:.75}.sm\:scale-y-90{--transform-scale-y:.9}.sm\:scale-y-95{--transform-scale-y:.95}.sm\:scale-y-100{--transform-scale-y:1}.sm\:scale-y-105{--transform-scale-y:1.05}.sm\:scale-y-110{--transform-scale-y:1.1}.sm\:scale-y-125{--transform-scale-y:1.25}.sm\:scale-y-150{--transform-scale-y:1.5}.sm\:hover\:scale-0:hover{--transform-scale-x:0;--transform-scale-y:0}.sm\:hover\:scale-50:hover{--transform-scale-x:.5;--transform-scale-y:.5}.sm\:hover\:scale-75:hover{--transform-scale-x:.75;--transform-scale-y:.75}.sm\:hover\:scale-90:hover{--transform-scale-x:.9;--transform-scale-y:.9}.sm\:hover\:scale-95:hover{--transform-scale-x:.95;--transform-scale-y:.95}.sm\:hover\:scale-100:hover{--transform-scale-x:1;--transform-scale-y:1}.sm\:hover\:scale-105:hover{--transform-scale-x:1.05;--transform-scale-y:1.05}.sm\:hover\:scale-110:hover{--transform-scale-x:1.1;--transform-scale-y:1.1}.sm\:hover\:scale-125:hover{--transform-scale-x:1.25;--transform-scale-y:1.25}.sm\:hover\:scale-150:hover{--transform-scale-x:1.5;--transform-scale-y:1.5}.sm\:hover\:scale-x-0:hover{--transform-scale-x:0}.sm\:hover\:scale-x-50:hover{--transform-scale-x:.5}.sm\:hover\:scale-x-75:hover{--transform-scale-x:.75}.sm\:hover\:scale-x-90:hover{--transform-scale-x:.9}.sm\:hover\:scale-x-95:hover{--transform-scale-x:.95}.sm\:hover\:scale-x-100:hover{--transform-scale-x:1}.sm\:hover\:scale-x-105:hover{--transform-scale-x:1.05}.sm\:hover\:scale-x-110:hover{--transform-scale-x:1.1}.sm\:hover\:scale-x-125:hover{--transform-scale-x:1.25}.sm\:hover\:scale-x-150:hover{--transform-scale-x:1.5}.sm\:hover\:scale-y-0:hover{--transform-scale-y:0}.sm\:hover\:scale-y-50:hover{--transform-scale-y:.5}.sm\:hover\:scale-y-75:hover{--transform-scale-y:.75}.sm\:hover\:scale-y-90:hover{--transform-scale-y:.9}.sm\:hover\:scale-y-95:hover{--transform-scale-y:.95}.sm\:hover\:scale-y-100:hover{--transform-scale-y:1}.sm\:hover\:scale-y-105:hover{--transform-scale-y:1.05}.sm\:hover\:scale-y-110:hover{--transform-scale-y:1.1}.sm\:hover\:scale-y-125:hover{--transform-scale-y:1.25}.sm\:hover\:scale-y-150:hover{--transform-scale-y:1.5}.sm\:focus\:scale-0:focus{--transform-scale-x:0;--transform-scale-y:0}.sm\:focus\:scale-50:focus{--transform-scale-x:.5;--transform-scale-y:.5}.sm\:focus\:scale-75:focus{--transform-scale-x:.75;--transform-scale-y:.75}.sm\:focus\:scale-90:focus{--transform-scale-x:.9;--transform-scale-y:.9}.sm\:focus\:scale-95:focus{--transform-scale-x:.95;--transform-scale-y:.95}.sm\:focus\:scale-100:focus{--transform-scale-x:1;--transform-scale-y:1}.sm\:focus\:scale-105:focus{--transform-scale-x:1.05;--transform-scale-y:1.05}.sm\:focus\:scale-110:focus{--transform-scale-x:1.1;--transform-scale-y:1.1}.sm\:focus\:scale-125:focus{--transform-scale-x:1.25;--transform-scale-y:1.25}.sm\:focus\:scale-150:focus{--transform-scale-x:1.5;--transform-scale-y:1.5}.sm\:focus\:scale-x-0:focus{--transform-scale-x:0}.sm\:focus\:scale-x-50:focus{--transform-scale-x:.5}.sm\:focus\:scale-x-75:focus{--transform-scale-x:.75}.sm\:focus\:scale-x-90:focus{--transform-scale-x:.9}.sm\:focus\:scale-x-95:focus{--transform-scale-x:.95}.sm\:focus\:scale-x-100:focus{--transform-scale-x:1}.sm\:focus\:scale-x-105:focus{--transform-scale-x:1.05}.sm\:focus\:scale-x-110:focus{--transform-scale-x:1.1}.sm\:focus\:scale-x-125:focus{--transform-scale-x:1.25}.sm\:focus\:scale-x-150:focus{--transform-scale-x:1.5}.sm\:focus\:scale-y-0:focus{--transform-scale-y:0}.sm\:focus\:scale-y-50:focus{--transform-scale-y:.5}.sm\:focus\:scale-y-75:focus{--transform-scale-y:.75}.sm\:focus\:scale-y-90:focus{--transform-scale-y:.9}.sm\:focus\:scale-y-95:focus{--transform-scale-y:.95}.sm\:focus\:scale-y-100:focus{--transform-scale-y:1}.sm\:focus\:scale-y-105:focus{--transform-scale-y:1.05}.sm\:focus\:scale-y-110:focus{--transform-scale-y:1.1}.sm\:focus\:scale-y-125:focus{--transform-scale-y:1.25}.sm\:focus\:scale-y-150:focus{--transform-scale-y:1.5}.sm\:rotate-0{--transform-rotate:0}.sm\:rotate-1{--transform-rotate:1deg}.sm\:rotate-2{--transform-rotate:2deg}.sm\:rotate-3{--transform-rotate:3deg}.sm\:rotate-6{--transform-rotate:6deg}.sm\:rotate-12{--transform-rotate:12deg}.sm\:rotate-45{--transform-rotate:45deg}.sm\:rotate-90{--transform-rotate:90deg}.sm\:rotate-180{--transform-rotate:180deg}.sm\:-rotate-180{--transform-rotate:-180deg}.sm\:-rotate-90{--transform-rotate:-90deg}.sm\:-rotate-45{--transform-rotate:-45deg}.sm\:-rotate-12{--transform-rotate:-12deg}.sm\:-rotate-6{--transform-rotate:-6deg}.sm\:-rotate-3{--transform-rotate:-3deg}.sm\:-rotate-2{--transform-rotate:-2deg}.sm\:-rotate-1{--transform-rotate:-1deg}.sm\:hover\:rotate-0:hover{--transform-rotate:0}.sm\:hover\:rotate-1:hover{--transform-rotate:1deg}.sm\:hover\:rotate-2:hover{--transform-rotate:2deg}.sm\:hover\:rotate-3:hover{--transform-rotate:3deg}.sm\:hover\:rotate-6:hover{--transform-rotate:6deg}.sm\:hover\:rotate-12:hover{--transform-rotate:12deg}.sm\:hover\:rotate-45:hover{--transform-rotate:45deg}.sm\:hover\:rotate-90:hover{--transform-rotate:90deg}.sm\:hover\:rotate-180:hover{--transform-rotate:180deg}.sm\:hover\:-rotate-180:hover{--transform-rotate:-180deg}.sm\:hover\:-rotate-90:hover{--transform-rotate:-90deg}.sm\:hover\:-rotate-45:hover{--transform-rotate:-45deg}.sm\:hover\:-rotate-12:hover{--transform-rotate:-12deg}.sm\:hover\:-rotate-6:hover{--transform-rotate:-6deg}.sm\:hover\:-rotate-3:hover{--transform-rotate:-3deg}.sm\:hover\:-rotate-2:hover{--transform-rotate:-2deg}.sm\:hover\:-rotate-1:hover{--transform-rotate:-1deg}.sm\:focus\:rotate-0:focus{--transform-rotate:0}.sm\:focus\:rotate-1:focus{--transform-rotate:1deg}.sm\:focus\:rotate-2:focus{--transform-rotate:2deg}.sm\:focus\:rotate-3:focus{--transform-rotate:3deg}.sm\:focus\:rotate-6:focus{--transform-rotate:6deg}.sm\:focus\:rotate-12:focus{--transform-rotate:12deg}.sm\:focus\:rotate-45:focus{--transform-rotate:45deg}.sm\:focus\:rotate-90:focus{--transform-rotate:90deg}.sm\:focus\:rotate-180:focus{--transform-rotate:180deg}.sm\:focus\:-rotate-180:focus{--transform-rotate:-180deg}.sm\:focus\:-rotate-90:focus{--transform-rotate:-90deg}.sm\:focus\:-rotate-45:focus{--transform-rotate:-45deg}.sm\:focus\:-rotate-12:focus{--transform-rotate:-12deg}.sm\:focus\:-rotate-6:focus{--transform-rotate:-6deg}.sm\:focus\:-rotate-3:focus{--transform-rotate:-3deg}.sm\:focus\:-rotate-2:focus{--transform-rotate:-2deg}.sm\:focus\:-rotate-1:focus{--transform-rotate:-1deg}.sm\:translate-x-0{--transform-translate-x:0}.sm\:translate-x-1{--transform-translate-x:0.25rem}.sm\:translate-x-2{--transform-translate-x:0.5rem}.sm\:translate-x-3{--transform-translate-x:0.75rem}.sm\:translate-x-4{--transform-translate-x:1rem}.sm\:translate-x-5{--transform-translate-x:1.25rem}.sm\:translate-x-6{--transform-translate-x:1.5rem}.sm\:translate-x-8{--transform-translate-x:2rem}.sm\:translate-x-10{--transform-translate-x:2.5rem}.sm\:translate-x-12{--transform-translate-x:3rem}.sm\:translate-x-16{--transform-translate-x:4rem}.sm\:translate-x-20{--transform-translate-x:5rem}.sm\:translate-x-24{--transform-translate-x:6rem}.sm\:translate-x-32{--transform-translate-x:8rem}.sm\:translate-x-40{--transform-translate-x:10rem}.sm\:translate-x-48{--transform-translate-x:12rem}.sm\:translate-x-56{--transform-translate-x:14rem}.sm\:translate-x-64{--transform-translate-x:16rem}.sm\:translate-x-px{--transform-translate-x:1px}.sm\:-translate-x-1{--transform-translate-x:-0.25rem}.sm\:-translate-x-2{--transform-translate-x:-0.5rem}.sm\:-translate-x-3{--transform-translate-x:-0.75rem}.sm\:-translate-x-4{--transform-translate-x:-1rem}.sm\:-translate-x-5{--transform-translate-x:-1.25rem}.sm\:-translate-x-6{--transform-translate-x:-1.5rem}.sm\:-translate-x-8{--transform-translate-x:-2rem}.sm\:-translate-x-10{--transform-translate-x:-2.5rem}.sm\:-translate-x-12{--transform-translate-x:-3rem}.sm\:-translate-x-16{--transform-translate-x:-4rem}.sm\:-translate-x-20{--transform-translate-x:-5rem}.sm\:-translate-x-24{--transform-translate-x:-6rem}.sm\:-translate-x-32{--transform-translate-x:-8rem}.sm\:-translate-x-40{--transform-translate-x:-10rem}.sm\:-translate-x-48{--transform-translate-x:-12rem}.sm\:-translate-x-56{--transform-translate-x:-14rem}.sm\:-translate-x-64{--transform-translate-x:-16rem}.sm\:-translate-x-px{--transform-translate-x:-1px}.sm\:-translate-x-full{--transform-translate-x:-100%}.sm\:-translate-x-1\/2{--transform-translate-x:-50%}.sm\:translate-x-1\/2{--transform-translate-x:50%}.sm\:translate-x-full{--transform-translate-x:100%}.sm\:translate-y-0{--transform-translate-y:0}.sm\:translate-y-1{--transform-translate-y:0.25rem}.sm\:translate-y-2{--transform-translate-y:0.5rem}.sm\:translate-y-3{--transform-translate-y:0.75rem}.sm\:translate-y-4{--transform-translate-y:1rem}.sm\:translate-y-5{--transform-translate-y:1.25rem}.sm\:translate-y-6{--transform-translate-y:1.5rem}.sm\:translate-y-8{--transform-translate-y:2rem}.sm\:translate-y-10{--transform-translate-y:2.5rem}.sm\:translate-y-12{--transform-translate-y:3rem}.sm\:translate-y-16{--transform-translate-y:4rem}.sm\:translate-y-20{--transform-translate-y:5rem}.sm\:translate-y-24{--transform-translate-y:6rem}.sm\:translate-y-32{--transform-translate-y:8rem}.sm\:translate-y-40{--transform-translate-y:10rem}.sm\:translate-y-48{--transform-translate-y:12rem}.sm\:translate-y-56{--transform-translate-y:14rem}.sm\:translate-y-64{--transform-translate-y:16rem}.sm\:translate-y-px{--transform-translate-y:1px}.sm\:-translate-y-1{--transform-translate-y:-0.25rem}.sm\:-translate-y-2{--transform-translate-y:-0.5rem}.sm\:-translate-y-3{--transform-translate-y:-0.75rem}.sm\:-translate-y-4{--transform-translate-y:-1rem}.sm\:-translate-y-5{--transform-translate-y:-1.25rem}.sm\:-translate-y-6{--transform-translate-y:-1.5rem}.sm\:-translate-y-8{--transform-translate-y:-2rem}.sm\:-translate-y-10{--transform-translate-y:-2.5rem}.sm\:-translate-y-12{--transform-translate-y:-3rem}.sm\:-translate-y-16{--transform-translate-y:-4rem}.sm\:-translate-y-20{--transform-translate-y:-5rem}.sm\:-translate-y-24{--transform-translate-y:-6rem}.sm\:-translate-y-32{--transform-translate-y:-8rem}.sm\:-translate-y-40{--transform-translate-y:-10rem}.sm\:-translate-y-48{--transform-translate-y:-12rem}.sm\:-translate-y-56{--transform-translate-y:-14rem}.sm\:-translate-y-64{--transform-translate-y:-16rem}.sm\:-translate-y-px{--transform-translate-y:-1px}.sm\:-translate-y-full{--transform-translate-y:-100%}.sm\:-translate-y-1\/2{--transform-translate-y:-50%}.sm\:translate-y-1\/2{--transform-translate-y:50%}.sm\:translate-y-full{--transform-translate-y:100%}.sm\:hover\:translate-x-0:hover{--transform-translate-x:0}.sm\:hover\:translate-x-1:hover{--transform-translate-x:0.25rem}.sm\:hover\:translate-x-2:hover{--transform-translate-x:0.5rem}.sm\:hover\:translate-x-3:hover{--transform-translate-x:0.75rem}.sm\:hover\:translate-x-4:hover{--transform-translate-x:1rem}.sm\:hover\:translate-x-5:hover{--transform-translate-x:1.25rem}.sm\:hover\:translate-x-6:hover{--transform-translate-x:1.5rem}.sm\:hover\:translate-x-8:hover{--transform-translate-x:2rem}.sm\:hover\:translate-x-10:hover{--transform-translate-x:2.5rem}.sm\:hover\:translate-x-12:hover{--transform-translate-x:3rem}.sm\:hover\:translate-x-16:hover{--transform-translate-x:4rem}.sm\:hover\:translate-x-20:hover{--transform-translate-x:5rem}.sm\:hover\:translate-x-24:hover{--transform-translate-x:6rem}.sm\:hover\:translate-x-32:hover{--transform-translate-x:8rem}.sm\:hover\:translate-x-40:hover{--transform-translate-x:10rem}.sm\:hover\:translate-x-48:hover{--transform-translate-x:12rem}.sm\:hover\:translate-x-56:hover{--transform-translate-x:14rem}.sm\:hover\:translate-x-64:hover{--transform-translate-x:16rem}.sm\:hover\:translate-x-px:hover{--transform-translate-x:1px}.sm\:hover\:-translate-x-1:hover{--transform-translate-x:-0.25rem}.sm\:hover\:-translate-x-2:hover{--transform-translate-x:-0.5rem}.sm\:hover\:-translate-x-3:hover{--transform-translate-x:-0.75rem}.sm\:hover\:-translate-x-4:hover{--transform-translate-x:-1rem}.sm\:hover\:-translate-x-5:hover{--transform-translate-x:-1.25rem}.sm\:hover\:-translate-x-6:hover{--transform-translate-x:-1.5rem}.sm\:hover\:-translate-x-8:hover{--transform-translate-x:-2rem}.sm\:hover\:-translate-x-10:hover{--transform-translate-x:-2.5rem}.sm\:hover\:-translate-x-12:hover{--transform-translate-x:-3rem}.sm\:hover\:-translate-x-16:hover{--transform-translate-x:-4rem}.sm\:hover\:-translate-x-20:hover{--transform-translate-x:-5rem}.sm\:hover\:-translate-x-24:hover{--transform-translate-x:-6rem}.sm\:hover\:-translate-x-32:hover{--transform-translate-x:-8rem}.sm\:hover\:-translate-x-40:hover{--transform-translate-x:-10rem}.sm\:hover\:-translate-x-48:hover{--transform-translate-x:-12rem}.sm\:hover\:-translate-x-56:hover{--transform-translate-x:-14rem}.sm\:hover\:-translate-x-64:hover{--transform-translate-x:-16rem}.sm\:hover\:-translate-x-px:hover{--transform-translate-x:-1px}.sm\:hover\:-translate-x-full:hover{--transform-translate-x:-100%}.sm\:hover\:-translate-x-1\/2:hover{--transform-translate-x:-50%}.sm\:hover\:translate-x-1\/2:hover{--transform-translate-x:50%}.sm\:hover\:translate-x-full:hover{--transform-translate-x:100%}.sm\:hover\:translate-y-0:hover{--transform-translate-y:0}.sm\:hover\:translate-y-1:hover{--transform-translate-y:0.25rem}.sm\:hover\:translate-y-2:hover{--transform-translate-y:0.5rem}.sm\:hover\:translate-y-3:hover{--transform-translate-y:0.75rem}.sm\:hover\:translate-y-4:hover{--transform-translate-y:1rem}.sm\:hover\:translate-y-5:hover{--transform-translate-y:1.25rem}.sm\:hover\:translate-y-6:hover{--transform-translate-y:1.5rem}.sm\:hover\:translate-y-8:hover{--transform-translate-y:2rem}.sm\:hover\:translate-y-10:hover{--transform-translate-y:2.5rem}.sm\:hover\:translate-y-12:hover{--transform-translate-y:3rem}.sm\:hover\:translate-y-16:hover{--transform-translate-y:4rem}.sm\:hover\:translate-y-20:hover{--transform-translate-y:5rem}.sm\:hover\:translate-y-24:hover{--transform-translate-y:6rem}.sm\:hover\:translate-y-32:hover{--transform-translate-y:8rem}.sm\:hover\:translate-y-40:hover{--transform-translate-y:10rem}.sm\:hover\:translate-y-48:hover{--transform-translate-y:12rem}.sm\:hover\:translate-y-56:hover{--transform-translate-y:14rem}.sm\:hover\:translate-y-64:hover{--transform-translate-y:16rem}.sm\:hover\:translate-y-px:hover{--transform-translate-y:1px}.sm\:hover\:-translate-y-1:hover{--transform-translate-y:-0.25rem}.sm\:hover\:-translate-y-2:hover{--transform-translate-y:-0.5rem}.sm\:hover\:-translate-y-3:hover{--transform-translate-y:-0.75rem}.sm\:hover\:-translate-y-4:hover{--transform-translate-y:-1rem}.sm\:hover\:-translate-y-5:hover{--transform-translate-y:-1.25rem}.sm\:hover\:-translate-y-6:hover{--transform-translate-y:-1.5rem}.sm\:hover\:-translate-y-8:hover{--transform-translate-y:-2rem}.sm\:hover\:-translate-y-10:hover{--transform-translate-y:-2.5rem}.sm\:hover\:-translate-y-12:hover{--transform-translate-y:-3rem}.sm\:hover\:-translate-y-16:hover{--transform-translate-y:-4rem}.sm\:hover\:-translate-y-20:hover{--transform-translate-y:-5rem}.sm\:hover\:-translate-y-24:hover{--transform-translate-y:-6rem}.sm\:hover\:-translate-y-32:hover{--transform-translate-y:-8rem}.sm\:hover\:-translate-y-40:hover{--transform-translate-y:-10rem}.sm\:hover\:-translate-y-48:hover{--transform-translate-y:-12rem}.sm\:hover\:-translate-y-56:hover{--transform-translate-y:-14rem}.sm\:hover\:-translate-y-64:hover{--transform-translate-y:-16rem}.sm\:hover\:-translate-y-px:hover{--transform-translate-y:-1px}.sm\:hover\:-translate-y-full:hover{--transform-translate-y:-100%}.sm\:hover\:-translate-y-1\/2:hover{--transform-translate-y:-50%}.sm\:hover\:translate-y-1\/2:hover{--transform-translate-y:50%}.sm\:hover\:translate-y-full:hover{--transform-translate-y:100%}.sm\:focus\:translate-x-0:focus{--transform-translate-x:0}.sm\:focus\:translate-x-1:focus{--transform-translate-x:0.25rem}.sm\:focus\:translate-x-2:focus{--transform-translate-x:0.5rem}.sm\:focus\:translate-x-3:focus{--transform-translate-x:0.75rem}.sm\:focus\:translate-x-4:focus{--transform-translate-x:1rem}.sm\:focus\:translate-x-5:focus{--transform-translate-x:1.25rem}.sm\:focus\:translate-x-6:focus{--transform-translate-x:1.5rem}.sm\:focus\:translate-x-8:focus{--transform-translate-x:2rem}.sm\:focus\:translate-x-10:focus{--transform-translate-x:2.5rem}.sm\:focus\:translate-x-12:focus{--transform-translate-x:3rem}.sm\:focus\:translate-x-16:focus{--transform-translate-x:4rem}.sm\:focus\:translate-x-20:focus{--transform-translate-x:5rem}.sm\:focus\:translate-x-24:focus{--transform-translate-x:6rem}.sm\:focus\:translate-x-32:focus{--transform-translate-x:8rem}.sm\:focus\:translate-x-40:focus{--transform-translate-x:10rem}.sm\:focus\:translate-x-48:focus{--transform-translate-x:12rem}.sm\:focus\:translate-x-56:focus{--transform-translate-x:14rem}.sm\:focus\:translate-x-64:focus{--transform-translate-x:16rem}.sm\:focus\:translate-x-px:focus{--transform-translate-x:1px}.sm\:focus\:-translate-x-1:focus{--transform-translate-x:-0.25rem}.sm\:focus\:-translate-x-2:focus{--transform-translate-x:-0.5rem}.sm\:focus\:-translate-x-3:focus{--transform-translate-x:-0.75rem}.sm\:focus\:-translate-x-4:focus{--transform-translate-x:-1rem}.sm\:focus\:-translate-x-5:focus{--transform-translate-x:-1.25rem}.sm\:focus\:-translate-x-6:focus{--transform-translate-x:-1.5rem}.sm\:focus\:-translate-x-8:focus{--transform-translate-x:-2rem}.sm\:focus\:-translate-x-10:focus{--transform-translate-x:-2.5rem}.sm\:focus\:-translate-x-12:focus{--transform-translate-x:-3rem}.sm\:focus\:-translate-x-16:focus{--transform-translate-x:-4rem}.sm\:focus\:-translate-x-20:focus{--transform-translate-x:-5rem}.sm\:focus\:-translate-x-24:focus{--transform-translate-x:-6rem}.sm\:focus\:-translate-x-32:focus{--transform-translate-x:-8rem}.sm\:focus\:-translate-x-40:focus{--transform-translate-x:-10rem}.sm\:focus\:-translate-x-48:focus{--transform-translate-x:-12rem}.sm\:focus\:-translate-x-56:focus{--transform-translate-x:-14rem}.sm\:focus\:-translate-x-64:focus{--transform-translate-x:-16rem}.sm\:focus\:-translate-x-px:focus{--transform-translate-x:-1px}.sm\:focus\:-translate-x-full:focus{--transform-translate-x:-100%}.sm\:focus\:-translate-x-1\/2:focus{--transform-translate-x:-50%}.sm\:focus\:translate-x-1\/2:focus{--transform-translate-x:50%}.sm\:focus\:translate-x-full:focus{--transform-translate-x:100%}.sm\:focus\:translate-y-0:focus{--transform-translate-y:0}.sm\:focus\:translate-y-1:focus{--transform-translate-y:0.25rem}.sm\:focus\:translate-y-2:focus{--transform-translate-y:0.5rem}.sm\:focus\:translate-y-3:focus{--transform-translate-y:0.75rem}.sm\:focus\:translate-y-4:focus{--transform-translate-y:1rem}.sm\:focus\:translate-y-5:focus{--transform-translate-y:1.25rem}.sm\:focus\:translate-y-6:focus{--transform-translate-y:1.5rem}.sm\:focus\:translate-y-8:focus{--transform-translate-y:2rem}.sm\:focus\:translate-y-10:focus{--transform-translate-y:2.5rem}.sm\:focus\:translate-y-12:focus{--transform-translate-y:3rem}.sm\:focus\:translate-y-16:focus{--transform-translate-y:4rem}.sm\:focus\:translate-y-20:focus{--transform-translate-y:5rem}.sm\:focus\:translate-y-24:focus{--transform-translate-y:6rem}.sm\:focus\:translate-y-32:focus{--transform-translate-y:8rem}.sm\:focus\:translate-y-40:focus{--transform-translate-y:10rem}.sm\:focus\:translate-y-48:focus{--transform-translate-y:12rem}.sm\:focus\:translate-y-56:focus{--transform-translate-y:14rem}.sm\:focus\:translate-y-64:focus{--transform-translate-y:16rem}.sm\:focus\:translate-y-px:focus{--transform-translate-y:1px}.sm\:focus\:-translate-y-1:focus{--transform-translate-y:-0.25rem}.sm\:focus\:-translate-y-2:focus{--transform-translate-y:-0.5rem}.sm\:focus\:-translate-y-3:focus{--transform-translate-y:-0.75rem}.sm\:focus\:-translate-y-4:focus{--transform-translate-y:-1rem}.sm\:focus\:-translate-y-5:focus{--transform-translate-y:-1.25rem}.sm\:focus\:-translate-y-6:focus{--transform-translate-y:-1.5rem}.sm\:focus\:-translate-y-8:focus{--transform-translate-y:-2rem}.sm\:focus\:-translate-y-10:focus{--transform-translate-y:-2.5rem}.sm\:focus\:-translate-y-12:focus{--transform-translate-y:-3rem}.sm\:focus\:-translate-y-16:focus{--transform-translate-y:-4rem}.sm\:focus\:-translate-y-20:focus{--transform-translate-y:-5rem}.sm\:focus\:-translate-y-24:focus{--transform-translate-y:-6rem}.sm\:focus\:-translate-y-32:focus{--transform-translate-y:-8rem}.sm\:focus\:-translate-y-40:focus{--transform-translate-y:-10rem}.sm\:focus\:-translate-y-48:focus{--transform-translate-y:-12rem}.sm\:focus\:-translate-y-56:focus{--transform-translate-y:-14rem}.sm\:focus\:-translate-y-64:focus{--transform-translate-y:-16rem}.sm\:focus\:-translate-y-px:focus{--transform-translate-y:-1px}.sm\:focus\:-translate-y-full:focus{--transform-translate-y:-100%}.sm\:focus\:-translate-y-1\/2:focus{--transform-translate-y:-50%}.sm\:focus\:translate-y-1\/2:focus{--transform-translate-y:50%}.sm\:focus\:translate-y-full:focus{--transform-translate-y:100%}.sm\:skew-x-0{--transform-skew-x:0}.sm\:skew-x-1{--transform-skew-x:1deg}.sm\:skew-x-2{--transform-skew-x:2deg}.sm\:skew-x-3{--transform-skew-x:3deg}.sm\:skew-x-6{--transform-skew-x:6deg}.sm\:skew-x-12{--transform-skew-x:12deg}.sm\:-skew-x-12{--transform-skew-x:-12deg}.sm\:-skew-x-6{--transform-skew-x:-6deg}.sm\:-skew-x-3{--transform-skew-x:-3deg}.sm\:-skew-x-2{--transform-skew-x:-2deg}.sm\:-skew-x-1{--transform-skew-x:-1deg}.sm\:skew-y-0{--transform-skew-y:0}.sm\:skew-y-1{--transform-skew-y:1deg}.sm\:skew-y-2{--transform-skew-y:2deg}.sm\:skew-y-3{--transform-skew-y:3deg}.sm\:skew-y-6{--transform-skew-y:6deg}.sm\:skew-y-12{--transform-skew-y:12deg}.sm\:-skew-y-12{--transform-skew-y:-12deg}.sm\:-skew-y-6{--transform-skew-y:-6deg}.sm\:-skew-y-3{--transform-skew-y:-3deg}.sm\:-skew-y-2{--transform-skew-y:-2deg}.sm\:-skew-y-1{--transform-skew-y:-1deg}.sm\:hover\:skew-x-0:hover{--transform-skew-x:0}.sm\:hover\:skew-x-1:hover{--transform-skew-x:1deg}.sm\:hover\:skew-x-2:hover{--transform-skew-x:2deg}.sm\:hover\:skew-x-3:hover{--transform-skew-x:3deg}.sm\:hover\:skew-x-6:hover{--transform-skew-x:6deg}.sm\:hover\:skew-x-12:hover{--transform-skew-x:12deg}.sm\:hover\:-skew-x-12:hover{--transform-skew-x:-12deg}.sm\:hover\:-skew-x-6:hover{--transform-skew-x:-6deg}.sm\:hover\:-skew-x-3:hover{--transform-skew-x:-3deg}.sm\:hover\:-skew-x-2:hover{--transform-skew-x:-2deg}.sm\:hover\:-skew-x-1:hover{--transform-skew-x:-1deg}.sm\:hover\:skew-y-0:hover{--transform-skew-y:0}.sm\:hover\:skew-y-1:hover{--transform-skew-y:1deg}.sm\:hover\:skew-y-2:hover{--transform-skew-y:2deg}.sm\:hover\:skew-y-3:hover{--transform-skew-y:3deg}.sm\:hover\:skew-y-6:hover{--transform-skew-y:6deg}.sm\:hover\:skew-y-12:hover{--transform-skew-y:12deg}.sm\:hover\:-skew-y-12:hover{--transform-skew-y:-12deg}.sm\:hover\:-skew-y-6:hover{--transform-skew-y:-6deg}.sm\:hover\:-skew-y-3:hover{--transform-skew-y:-3deg}.sm\:hover\:-skew-y-2:hover{--transform-skew-y:-2deg}.sm\:hover\:-skew-y-1:hover{--transform-skew-y:-1deg}.sm\:focus\:skew-x-0:focus{--transform-skew-x:0}.sm\:focus\:skew-x-1:focus{--transform-skew-x:1deg}.sm\:focus\:skew-x-2:focus{--transform-skew-x:2deg}.sm\:focus\:skew-x-3:focus{--transform-skew-x:3deg}.sm\:focus\:skew-x-6:focus{--transform-skew-x:6deg}.sm\:focus\:skew-x-12:focus{--transform-skew-x:12deg}.sm\:focus\:-skew-x-12:focus{--transform-skew-x:-12deg}.sm\:focus\:-skew-x-6:focus{--transform-skew-x:-6deg}.sm\:focus\:-skew-x-3:focus{--transform-skew-x:-3deg}.sm\:focus\:-skew-x-2:focus{--transform-skew-x:-2deg}.sm\:focus\:-skew-x-1:focus{--transform-skew-x:-1deg}.sm\:focus\:skew-y-0:focus{--transform-skew-y:0}.sm\:focus\:skew-y-1:focus{--transform-skew-y:1deg}.sm\:focus\:skew-y-2:focus{--transform-skew-y:2deg}.sm\:focus\:skew-y-3:focus{--transform-skew-y:3deg}.sm\:focus\:skew-y-6:focus{--transform-skew-y:6deg}.sm\:focus\:skew-y-12:focus{--transform-skew-y:12deg}.sm\:focus\:-skew-y-12:focus{--transform-skew-y:-12deg}.sm\:focus\:-skew-y-6:focus{--transform-skew-y:-6deg}.sm\:focus\:-skew-y-3:focus{--transform-skew-y:-3deg}.sm\:focus\:-skew-y-2:focus{--transform-skew-y:-2deg}.sm\:focus\:-skew-y-1:focus{--transform-skew-y:-1deg}.sm\:transition-none{transition-property:none}.sm\:transition-all{transition-property:all}.sm\:transition{transition-property:background-color,border-color,color,fill,stroke,opacity,box-shadow,transform}.sm\:transition-colors{transition-property:background-color,border-color,color,fill,stroke}.sm\:transition-opacity{transition-property:opacity}.sm\:transition-shadow{transition-property:box-shadow}.sm\:transition-transform{transition-property:transform}.sm\:ease-linear{transition-timing-function:linear}.sm\:ease-in{transition-timing-function:cubic-bezier(.4,0,1,1)}.sm\:ease-out{transition-timing-function:cubic-bezier(0,0,.2,1)}.sm\:ease-in-out{transition-timing-function:cubic-bezier(.4,0,.2,1)}.sm\:duration-75{transition-duration:75ms}.sm\:duration-100{transition-duration:.1s}.sm\:duration-150{transition-duration:150ms}.sm\:duration-200{transition-duration:.2s}.sm\:duration-300{transition-duration:.3s}.sm\:duration-500{transition-duration:.5s}.sm\:duration-700{transition-duration:.7s}.sm\:duration-1000{transition-duration:1s}.sm\:delay-75{transition-delay:75ms}.sm\:delay-100{transition-delay:.1s}.sm\:delay-150{transition-delay:150ms}.sm\:delay-200{transition-delay:.2s}.sm\:delay-300{transition-delay:.3s}.sm\:delay-500{transition-delay:.5s}.sm\:delay-700{transition-delay:.7s}.sm\:delay-1000{transition-delay:1s}.sm\:animate-none{animation:none}.sm\:animate-spin{animation:spin 1s linear infinite}.sm\:animate-ping{animation:ping 1s cubic-bezier(0,0,.2,1) infinite}.sm\:animate-pulse{animation:pulse 2s cubic-bezier(.4,0,.6,1) infinite}.sm\:animate-bounce{animation:bounce 1s infinite}}@media (min-width:768px){.md\:container{width:100%}@media (min-width:640px){.md\:container{max-width:640px}}@media (min-width:768px){.md\:container{max-width:768px}}@media (min-width:1024px){.md\:container{max-width:1024px}}@media (min-width:1280px){.md\:container{max-width:1280px}}.md\:space-y-0>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(0px * calc(1 - var(--space-y-reverse)));margin-bottom:calc(0px * var(--space-y-reverse))}.md\:space-x-0>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(0px * var(--space-x-reverse));margin-left:calc(0px * calc(1 - var(--space-x-reverse)))}.md\:space-y-1>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(.25rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(.25rem * var(--space-y-reverse))}.md\:space-x-1>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(.25rem * var(--space-x-reverse));margin-left:calc(.25rem * calc(1 - var(--space-x-reverse)))}.md\:space-y-2>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(.5rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(.5rem * var(--space-y-reverse))}.md\:space-x-2>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(.5rem * var(--space-x-reverse));margin-left:calc(.5rem * calc(1 - var(--space-x-reverse)))}.md\:space-y-3>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(.75rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(.75rem * var(--space-y-reverse))}.md\:space-x-3>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(.75rem * var(--space-x-reverse));margin-left:calc(.75rem * calc(1 - var(--space-x-reverse)))}.md\:space-y-4>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(1rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(1rem * var(--space-y-reverse))}.md\:space-x-4>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(1rem * var(--space-x-reverse));margin-left:calc(1rem * calc(1 - var(--space-x-reverse)))}.md\:space-y-5>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(1.25rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(1.25rem * var(--space-y-reverse))}.md\:space-x-5>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(1.25rem * var(--space-x-reverse));margin-left:calc(1.25rem * calc(1 - var(--space-x-reverse)))}.md\:space-y-6>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(1.5rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(1.5rem * var(--space-y-reverse))}.md\:space-x-6>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(1.5rem * var(--space-x-reverse));margin-left:calc(1.5rem * calc(1 - var(--space-x-reverse)))}.md\:space-y-8>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(2rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(2rem * var(--space-y-reverse))}.md\:space-x-8>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(2rem * var(--space-x-reverse));margin-left:calc(2rem * calc(1 - var(--space-x-reverse)))}.md\:space-y-10>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(2.5rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(2.5rem * var(--space-y-reverse))}.md\:space-x-10>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(2.5rem * var(--space-x-reverse));margin-left:calc(2.5rem * calc(1 - var(--space-x-reverse)))}.md\:space-y-12>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(3rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(3rem * var(--space-y-reverse))}.md\:space-x-12>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(3rem * var(--space-x-reverse));margin-left:calc(3rem * calc(1 - var(--space-x-reverse)))}.md\:space-y-16>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(4rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(4rem * var(--space-y-reverse))}.md\:space-x-16>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(4rem * var(--space-x-reverse));margin-left:calc(4rem * calc(1 - var(--space-x-reverse)))}.md\:space-y-20>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(5rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(5rem * var(--space-y-reverse))}.md\:space-x-20>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(5rem * var(--space-x-reverse));margin-left:calc(5rem * calc(1 - var(--space-x-reverse)))}.md\:space-y-24>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(6rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(6rem * var(--space-y-reverse))}.md\:space-x-24>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(6rem * var(--space-x-reverse));margin-left:calc(6rem * calc(1 - var(--space-x-reverse)))}.md\:space-y-32>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(8rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(8rem * var(--space-y-reverse))}.md\:space-x-32>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(8rem * var(--space-x-reverse));margin-left:calc(8rem * calc(1 - var(--space-x-reverse)))}.md\:space-y-40>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(10rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(10rem * var(--space-y-reverse))}.md\:space-x-40>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(10rem * var(--space-x-reverse));margin-left:calc(10rem * calc(1 - var(--space-x-reverse)))}.md\:space-y-48>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(12rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(12rem * var(--space-y-reverse))}.md\:space-x-48>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(12rem * var(--space-x-reverse));margin-left:calc(12rem * calc(1 - var(--space-x-reverse)))}.md\:space-y-56>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(14rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(14rem * var(--space-y-reverse))}.md\:space-x-56>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(14rem * var(--space-x-reverse));margin-left:calc(14rem * calc(1 - var(--space-x-reverse)))}.md\:space-y-64>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(16rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(16rem * var(--space-y-reverse))}.md\:space-x-64>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(16rem * var(--space-x-reverse));margin-left:calc(16rem * calc(1 - var(--space-x-reverse)))}.md\:space-y-px>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(1px * calc(1 - var(--space-y-reverse)));margin-bottom:calc(1px * var(--space-y-reverse))}.md\:space-x-px>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(1px * var(--space-x-reverse));margin-left:calc(1px * calc(1 - var(--space-x-reverse)))}.md\:-space-y-1>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-.25rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-.25rem * var(--space-y-reverse))}.md\:-space-x-1>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-.25rem * var(--space-x-reverse));margin-left:calc(-.25rem * calc(1 - var(--space-x-reverse)))}.md\:-space-y-2>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-.5rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-.5rem * var(--space-y-reverse))}.md\:-space-x-2>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-.5rem * var(--space-x-reverse));margin-left:calc(-.5rem * calc(1 - var(--space-x-reverse)))}.md\:-space-y-3>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-.75rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-.75rem * var(--space-y-reverse))}.md\:-space-x-3>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-.75rem * var(--space-x-reverse));margin-left:calc(-.75rem * calc(1 - var(--space-x-reverse)))}.md\:-space-y-4>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-1rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-1rem * var(--space-y-reverse))}.md\:-space-x-4>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-1rem * var(--space-x-reverse));margin-left:calc(-1rem * calc(1 - var(--space-x-reverse)))}.md\:-space-y-5>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-1.25rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-1.25rem * var(--space-y-reverse))}.md\:-space-x-5>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-1.25rem * var(--space-x-reverse));margin-left:calc(-1.25rem * calc(1 - var(--space-x-reverse)))}.md\:-space-y-6>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-1.5rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-1.5rem * var(--space-y-reverse))}.md\:-space-x-6>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-1.5rem * var(--space-x-reverse));margin-left:calc(-1.5rem * calc(1 - var(--space-x-reverse)))}.md\:-space-y-8>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-2rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-2rem * var(--space-y-reverse))}.md\:-space-x-8>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-2rem * var(--space-x-reverse));margin-left:calc(-2rem * calc(1 - var(--space-x-reverse)))}.md\:-space-y-10>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-2.5rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-2.5rem * var(--space-y-reverse))}.md\:-space-x-10>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-2.5rem * var(--space-x-reverse));margin-left:calc(-2.5rem * calc(1 - var(--space-x-reverse)))}.md\:-space-y-12>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-3rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-3rem * var(--space-y-reverse))}.md\:-space-x-12>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-3rem * var(--space-x-reverse));margin-left:calc(-3rem * calc(1 - var(--space-x-reverse)))}.md\:-space-y-16>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-4rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-4rem * var(--space-y-reverse))}.md\:-space-x-16>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-4rem * var(--space-x-reverse));margin-left:calc(-4rem * calc(1 - var(--space-x-reverse)))}.md\:-space-y-20>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-5rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-5rem * var(--space-y-reverse))}.md\:-space-x-20>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-5rem * var(--space-x-reverse));margin-left:calc(-5rem * calc(1 - var(--space-x-reverse)))}.md\:-space-y-24>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-6rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-6rem * var(--space-y-reverse))}.md\:-space-x-24>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-6rem * var(--space-x-reverse));margin-left:calc(-6rem * calc(1 - var(--space-x-reverse)))}.md\:-space-y-32>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-8rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-8rem * var(--space-y-reverse))}.md\:-space-x-32>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-8rem * var(--space-x-reverse));margin-left:calc(-8rem * calc(1 - var(--space-x-reverse)))}.md\:-space-y-40>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-10rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-10rem * var(--space-y-reverse))}.md\:-space-x-40>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-10rem * var(--space-x-reverse));margin-left:calc(-10rem * calc(1 - var(--space-x-reverse)))}.md\:-space-y-48>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-12rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-12rem * var(--space-y-reverse))}.md\:-space-x-48>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-12rem * var(--space-x-reverse));margin-left:calc(-12rem * calc(1 - var(--space-x-reverse)))}.md\:-space-y-56>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-14rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-14rem * var(--space-y-reverse))}.md\:-space-x-56>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-14rem * var(--space-x-reverse));margin-left:calc(-14rem * calc(1 - var(--space-x-reverse)))}.md\:-space-y-64>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-16rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-16rem * var(--space-y-reverse))}.md\:-space-x-64>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-16rem * var(--space-x-reverse));margin-left:calc(-16rem * calc(1 - var(--space-x-reverse)))}.md\:-space-y-px>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-1px * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-1px * var(--space-y-reverse))}.md\:-space-x-px>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-1px * var(--space-x-reverse));margin-left:calc(-1px * calc(1 - var(--space-x-reverse)))}.md\:space-y-reverse>:not(template)~:not(template){--space-y-reverse:1}.md\:space-x-reverse>:not(template)~:not(template){--space-x-reverse:1}.md\:divide-y-0>:not(template)~:not(template){--divide-y-reverse:0;border-top-width:calc(0px * calc(1 - var(--divide-y-reverse)));border-bottom-width:calc(0px * var(--divide-y-reverse))}.md\:divide-x-0>:not(template)~:not(template){--divide-x-reverse:0;border-right-width:calc(0px * var(--divide-x-reverse));border-left-width:calc(0px * calc(1 - var(--divide-x-reverse)))}.md\:divide-y-2>:not(template)~:not(template){--divide-y-reverse:0;border-top-width:calc(2px * calc(1 - var(--divide-y-reverse)));border-bottom-width:calc(2px * var(--divide-y-reverse))}.md\:divide-x-2>:not(template)~:not(template){--divide-x-reverse:0;border-right-width:calc(2px * var(--divide-x-reverse));border-left-width:calc(2px * calc(1 - var(--divide-x-reverse)))}.md\:divide-y-4>:not(template)~:not(template){--divide-y-reverse:0;border-top-width:calc(4px * calc(1 - var(--divide-y-reverse)));border-bottom-width:calc(4px * var(--divide-y-reverse))}.md\:divide-x-4>:not(template)~:not(template){--divide-x-reverse:0;border-right-width:calc(4px * var(--divide-x-reverse));border-left-width:calc(4px * calc(1 - var(--divide-x-reverse)))}.md\:divide-y-8>:not(template)~:not(template){--divide-y-reverse:0;border-top-width:calc(8px * calc(1 - var(--divide-y-reverse)));border-bottom-width:calc(8px * var(--divide-y-reverse))}.md\:divide-x-8>:not(template)~:not(template){--divide-x-reverse:0;border-right-width:calc(8px * var(--divide-x-reverse));border-left-width:calc(8px * calc(1 - var(--divide-x-reverse)))}.md\:divide-y>:not(template)~:not(template){--divide-y-reverse:0;border-top-width:calc(1px * calc(1 - var(--divide-y-reverse)));border-bottom-width:calc(1px * var(--divide-y-reverse))}.md\:divide-x>:not(template)~:not(template){--divide-x-reverse:0;border-right-width:calc(1px * var(--divide-x-reverse));border-left-width:calc(1px * calc(1 - var(--divide-x-reverse)))}.md\:divide-y-reverse>:not(template)~:not(template){--divide-y-reverse:1}.md\:divide-x-reverse>:not(template)~:not(template){--divide-x-reverse:1}.md\:divide-transparent>:not(template)~:not(template){border-color:transparent}.md\:divide-current>:not(template)~:not(template){border-color:currentColor}.md\:divide-black>:not(template)~:not(template){--divide-opacity:1;border-color:#000;border-color:rgba(0,0,0,var(--divide-opacity))}.md\:divide-white>:not(template)~:not(template){--divide-opacity:1;border-color:#fff;border-color:rgba(255,255,255,var(--divide-opacity))}.md\:divide-gray-100>:not(template)~:not(template){--divide-opacity:1;border-color:#f7fafc;border-color:rgba(247,250,252,var(--divide-opacity))}.md\:divide-gray-200>:not(template)~:not(template){--divide-opacity:1;border-color:#edf2f7;border-color:rgba(237,242,247,var(--divide-opacity))}.md\:divide-gray-300>:not(template)~:not(template){--divide-opacity:1;border-color:#e2e8f0;border-color:rgba(226,232,240,var(--divide-opacity))}.md\:divide-gray-400>:not(template)~:not(template){--divide-opacity:1;border-color:#cbd5e0;border-color:rgba(203,213,224,var(--divide-opacity))}.md\:divide-gray-500>:not(template)~:not(template){--divide-opacity:1;border-color:#a0aec0;border-color:rgba(160,174,192,var(--divide-opacity))}.md\:divide-gray-600>:not(template)~:not(template){--divide-opacity:1;border-color:#718096;border-color:rgba(113,128,150,var(--divide-opacity))}.md\:divide-gray-700>:not(template)~:not(template){--divide-opacity:1;border-color:#4a5568;border-color:rgba(74,85,104,var(--divide-opacity))}.md\:divide-gray-800>:not(template)~:not(template){--divide-opacity:1;border-color:#2d3748;border-color:rgba(45,55,72,var(--divide-opacity))}.md\:divide-gray-900>:not(template)~:not(template){--divide-opacity:1;border-color:#1a202c;border-color:rgba(26,32,44,var(--divide-opacity))}.md\:divide-red-100>:not(template)~:not(template){--divide-opacity:1;border-color:#fff5f5;border-color:rgba(255,245,245,var(--divide-opacity))}.md\:divide-red-200>:not(template)~:not(template){--divide-opacity:1;border-color:#fed7d7;border-color:rgba(254,215,215,var(--divide-opacity))}.md\:divide-red-300>:not(template)~:not(template){--divide-opacity:1;border-color:#feb2b2;border-color:rgba(254,178,178,var(--divide-opacity))}.md\:divide-red-400>:not(template)~:not(template){--divide-opacity:1;border-color:#fc8181;border-color:rgba(252,129,129,var(--divide-opacity))}.md\:divide-red-500>:not(template)~:not(template){--divide-opacity:1;border-color:#f56565;border-color:rgba(245,101,101,var(--divide-opacity))}.md\:divide-red-600>:not(template)~:not(template){--divide-opacity:1;border-color:#e53e3e;border-color:rgba(229,62,62,var(--divide-opacity))}.md\:divide-red-700>:not(template)~:not(template){--divide-opacity:1;border-color:#c53030;border-color:rgba(197,48,48,var(--divide-opacity))}.md\:divide-red-800>:not(template)~:not(template){--divide-opacity:1;border-color:#9b2c2c;border-color:rgba(155,44,44,var(--divide-opacity))}.md\:divide-red-900>:not(template)~:not(template){--divide-opacity:1;border-color:#742a2a;border-color:rgba(116,42,42,var(--divide-opacity))}.md\:divide-orange-100>:not(template)~:not(template){--divide-opacity:1;border-color:#fffaf0;border-color:rgba(255,250,240,var(--divide-opacity))}.md\:divide-orange-200>:not(template)~:not(template){--divide-opacity:1;border-color:#feebc8;border-color:rgba(254,235,200,var(--divide-opacity))}.md\:divide-orange-300>:not(template)~:not(template){--divide-opacity:1;border-color:#fbd38d;border-color:rgba(251,211,141,var(--divide-opacity))}.md\:divide-orange-400>:not(template)~:not(template){--divide-opacity:1;border-color:#f6ad55;border-color:rgba(246,173,85,var(--divide-opacity))}.md\:divide-orange-500>:not(template)~:not(template){--divide-opacity:1;border-color:#ed8936;border-color:rgba(237,137,54,var(--divide-opacity))}.md\:divide-orange-600>:not(template)~:not(template){--divide-opacity:1;border-color:#dd6b20;border-color:rgba(221,107,32,var(--divide-opacity))}.md\:divide-orange-700>:not(template)~:not(template){--divide-opacity:1;border-color:#c05621;border-color:rgba(192,86,33,var(--divide-opacity))}.md\:divide-orange-800>:not(template)~:not(template){--divide-opacity:1;border-color:#9c4221;border-color:rgba(156,66,33,var(--divide-opacity))}.md\:divide-orange-900>:not(template)~:not(template){--divide-opacity:1;border-color:#7b341e;border-color:rgba(123,52,30,var(--divide-opacity))}.md\:divide-yellow-100>:not(template)~:not(template){--divide-opacity:1;border-color:ivory;border-color:rgba(255,255,240,var(--divide-opacity))}.md\:divide-yellow-200>:not(template)~:not(template){--divide-opacity:1;border-color:#fefcbf;border-color:rgba(254,252,191,var(--divide-opacity))}.md\:divide-yellow-300>:not(template)~:not(template){--divide-opacity:1;border-color:#faf089;border-color:rgba(250,240,137,var(--divide-opacity))}.md\:divide-yellow-400>:not(template)~:not(template){--divide-opacity:1;border-color:#f6e05e;border-color:rgba(246,224,94,var(--divide-opacity))}.md\:divide-yellow-500>:not(template)~:not(template){--divide-opacity:1;border-color:#ecc94b;border-color:rgba(236,201,75,var(--divide-opacity))}.md\:divide-yellow-600>:not(template)~:not(template){--divide-opacity:1;border-color:#d69e2e;border-color:rgba(214,158,46,var(--divide-opacity))}.md\:divide-yellow-700>:not(template)~:not(template){--divide-opacity:1;border-color:#b7791f;border-color:rgba(183,121,31,var(--divide-opacity))}.md\:divide-yellow-800>:not(template)~:not(template){--divide-opacity:1;border-color:#975a16;border-color:rgba(151,90,22,var(--divide-opacity))}.md\:divide-yellow-900>:not(template)~:not(template){--divide-opacity:1;border-color:#744210;border-color:rgba(116,66,16,var(--divide-opacity))}.md\:divide-green-100>:not(template)~:not(template){--divide-opacity:1;border-color:#f0fff4;border-color:rgba(240,255,244,var(--divide-opacity))}.md\:divide-green-200>:not(template)~:not(template){--divide-opacity:1;border-color:#c6f6d5;border-color:rgba(198,246,213,var(--divide-opacity))}.md\:divide-green-300>:not(template)~:not(template){--divide-opacity:1;border-color:#9ae6b4;border-color:rgba(154,230,180,var(--divide-opacity))}.md\:divide-green-400>:not(template)~:not(template){--divide-opacity:1;border-color:#68d391;border-color:rgba(104,211,145,var(--divide-opacity))}.md\:divide-green-500>:not(template)~:not(template){--divide-opacity:1;border-color:#48bb78;border-color:rgba(72,187,120,var(--divide-opacity))}.md\:divide-green-600>:not(template)~:not(template){--divide-opacity:1;border-color:#38a169;border-color:rgba(56,161,105,var(--divide-opacity))}.md\:divide-green-700>:not(template)~:not(template){--divide-opacity:1;border-color:#2f855a;border-color:rgba(47,133,90,var(--divide-opacity))}.md\:divide-green-800>:not(template)~:not(template){--divide-opacity:1;border-color:#276749;border-color:rgba(39,103,73,var(--divide-opacity))}.md\:divide-green-900>:not(template)~:not(template){--divide-opacity:1;border-color:#22543d;border-color:rgba(34,84,61,var(--divide-opacity))}.md\:divide-teal-100>:not(template)~:not(template){--divide-opacity:1;border-color:#e6fffa;border-color:rgba(230,255,250,var(--divide-opacity))}.md\:divide-teal-200>:not(template)~:not(template){--divide-opacity:1;border-color:#b2f5ea;border-color:rgba(178,245,234,var(--divide-opacity))}.md\:divide-teal-300>:not(template)~:not(template){--divide-opacity:1;border-color:#81e6d9;border-color:rgba(129,230,217,var(--divide-opacity))}.md\:divide-teal-400>:not(template)~:not(template){--divide-opacity:1;border-color:#4fd1c5;border-color:rgba(79,209,197,var(--divide-opacity))}.md\:divide-teal-500>:not(template)~:not(template){--divide-opacity:1;border-color:#38b2ac;border-color:rgba(56,178,172,var(--divide-opacity))}.md\:divide-teal-600>:not(template)~:not(template){--divide-opacity:1;border-color:#319795;border-color:rgba(49,151,149,var(--divide-opacity))}.md\:divide-teal-700>:not(template)~:not(template){--divide-opacity:1;border-color:#2c7a7b;border-color:rgba(44,122,123,var(--divide-opacity))}.md\:divide-teal-800>:not(template)~:not(template){--divide-opacity:1;border-color:#285e61;border-color:rgba(40,94,97,var(--divide-opacity))}.md\:divide-teal-900>:not(template)~:not(template){--divide-opacity:1;border-color:#234e52;border-color:rgba(35,78,82,var(--divide-opacity))}.md\:divide-blue-100>:not(template)~:not(template){--divide-opacity:1;border-color:#ebf8ff;border-color:rgba(235,248,255,var(--divide-opacity))}.md\:divide-blue-200>:not(template)~:not(template){--divide-opacity:1;border-color:#bee3f8;border-color:rgba(190,227,248,var(--divide-opacity))}.md\:divide-blue-300>:not(template)~:not(template){--divide-opacity:1;border-color:#90cdf4;border-color:rgba(144,205,244,var(--divide-opacity))}.md\:divide-blue-400>:not(template)~:not(template){--divide-opacity:1;border-color:#63b3ed;border-color:rgba(99,179,237,var(--divide-opacity))}.md\:divide-blue-500>:not(template)~:not(template){--divide-opacity:1;border-color:#4299e1;border-color:rgba(66,153,225,var(--divide-opacity))}.md\:divide-blue-600>:not(template)~:not(template){--divide-opacity:1;border-color:#3182ce;border-color:rgba(49,130,206,var(--divide-opacity))}.md\:divide-blue-700>:not(template)~:not(template){--divide-opacity:1;border-color:#2b6cb0;border-color:rgba(43,108,176,var(--divide-opacity))}.md\:divide-blue-800>:not(template)~:not(template){--divide-opacity:1;border-color:#2c5282;border-color:rgba(44,82,130,var(--divide-opacity))}.md\:divide-blue-900>:not(template)~:not(template){--divide-opacity:1;border-color:#2a4365;border-color:rgba(42,67,101,var(--divide-opacity))}.md\:divide-indigo-100>:not(template)~:not(template){--divide-opacity:1;border-color:#ebf4ff;border-color:rgba(235,244,255,var(--divide-opacity))}.md\:divide-indigo-200>:not(template)~:not(template){--divide-opacity:1;border-color:#c3dafe;border-color:rgba(195,218,254,var(--divide-opacity))}.md\:divide-indigo-300>:not(template)~:not(template){--divide-opacity:1;border-color:#a3bffa;border-color:rgba(163,191,250,var(--divide-opacity))}.md\:divide-indigo-400>:not(template)~:not(template){--divide-opacity:1;border-color:#7f9cf5;border-color:rgba(127,156,245,var(--divide-opacity))}.md\:divide-indigo-500>:not(template)~:not(template){--divide-opacity:1;border-color:#667eea;border-color:rgba(102,126,234,var(--divide-opacity))}.md\:divide-indigo-600>:not(template)~:not(template){--divide-opacity:1;border-color:#5a67d8;border-color:rgba(90,103,216,var(--divide-opacity))}.md\:divide-indigo-700>:not(template)~:not(template){--divide-opacity:1;border-color:#4c51bf;border-color:rgba(76,81,191,var(--divide-opacity))}.md\:divide-indigo-800>:not(template)~:not(template){--divide-opacity:1;border-color:#434190;border-color:rgba(67,65,144,var(--divide-opacity))}.md\:divide-indigo-900>:not(template)~:not(template){--divide-opacity:1;border-color:#3c366b;border-color:rgba(60,54,107,var(--divide-opacity))}.md\:divide-purple-100>:not(template)~:not(template){--divide-opacity:1;border-color:#faf5ff;border-color:rgba(250,245,255,var(--divide-opacity))}.md\:divide-purple-200>:not(template)~:not(template){--divide-opacity:1;border-color:#e9d8fd;border-color:rgba(233,216,253,var(--divide-opacity))}.md\:divide-purple-300>:not(template)~:not(template){--divide-opacity:1;border-color:#d6bcfa;border-color:rgba(214,188,250,var(--divide-opacity))}.md\:divide-purple-400>:not(template)~:not(template){--divide-opacity:1;border-color:#b794f4;border-color:rgba(183,148,244,var(--divide-opacity))}.md\:divide-purple-500>:not(template)~:not(template){--divide-opacity:1;border-color:#9f7aea;border-color:rgba(159,122,234,var(--divide-opacity))}.md\:divide-purple-600>:not(template)~:not(template){--divide-opacity:1;border-color:#805ad5;border-color:rgba(128,90,213,var(--divide-opacity))}.md\:divide-purple-700>:not(template)~:not(template){--divide-opacity:1;border-color:#6b46c1;border-color:rgba(107,70,193,var(--divide-opacity))}.md\:divide-purple-800>:not(template)~:not(template){--divide-opacity:1;border-color:#553c9a;border-color:rgba(85,60,154,var(--divide-opacity))}.md\:divide-purple-900>:not(template)~:not(template){--divide-opacity:1;border-color:#44337a;border-color:rgba(68,51,122,var(--divide-opacity))}.md\:divide-pink-100>:not(template)~:not(template){--divide-opacity:1;border-color:#fff5f7;border-color:rgba(255,245,247,var(--divide-opacity))}.md\:divide-pink-200>:not(template)~:not(template){--divide-opacity:1;border-color:#fed7e2;border-color:rgba(254,215,226,var(--divide-opacity))}.md\:divide-pink-300>:not(template)~:not(template){--divide-opacity:1;border-color:#fbb6ce;border-color:rgba(251,182,206,var(--divide-opacity))}.md\:divide-pink-400>:not(template)~:not(template){--divide-opacity:1;border-color:#f687b3;border-color:rgba(246,135,179,var(--divide-opacity))}.md\:divide-pink-500>:not(template)~:not(template){--divide-opacity:1;border-color:#ed64a6;border-color:rgba(237,100,166,var(--divide-opacity))}.md\:divide-pink-600>:not(template)~:not(template){--divide-opacity:1;border-color:#d53f8c;border-color:rgba(213,63,140,var(--divide-opacity))}.md\:divide-pink-700>:not(template)~:not(template){--divide-opacity:1;border-color:#b83280;border-color:rgba(184,50,128,var(--divide-opacity))}.md\:divide-pink-800>:not(template)~:not(template){--divide-opacity:1;border-color:#97266d;border-color:rgba(151,38,109,var(--divide-opacity))}.md\:divide-pink-900>:not(template)~:not(template){--divide-opacity:1;border-color:#702459;border-color:rgba(112,36,89,var(--divide-opacity))}.md\:divide-solid>:not(template)~:not(template){border-style:solid}.md\:divide-dashed>:not(template)~:not(template){border-style:dashed}.md\:divide-dotted>:not(template)~:not(template){border-style:dotted}.md\:divide-double>:not(template)~:not(template){border-style:double}.md\:divide-none>:not(template)~:not(template){border-style:none}.md\:divide-opacity-0>:not(template)~:not(template){--divide-opacity:0}.md\:divide-opacity-25>:not(template)~:not(template){--divide-opacity:0.25}.md\:divide-opacity-50>:not(template)~:not(template){--divide-opacity:0.5}.md\:divide-opacity-75>:not(template)~:not(template){--divide-opacity:0.75}.md\:divide-opacity-100>:not(template)~:not(template){--divide-opacity:1}.md\:sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border-width:0}.md\:not-sr-only{position:static;width:auto;height:auto;padding:0;margin:0;overflow:visible;clip:auto;white-space:normal}.md\:focus\:sr-only:focus{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border-width:0}.md\:focus\:not-sr-only:focus{position:static;width:auto;height:auto;padding:0;margin:0;overflow:visible;clip:auto;white-space:normal}.md\:appearance-none{-webkit-appearance:none;-moz-appearance:none;appearance:none}.md\:bg-fixed{background-attachment:fixed}.md\:bg-local{background-attachment:local}.md\:bg-scroll{background-attachment:scroll}.md\:bg-clip-border{background-clip:border-box}.md\:bg-clip-padding{background-clip:padding-box}.md\:bg-clip-content{background-clip:content-box}.md\:bg-clip-text{-webkit-background-clip:text;background-clip:text}.md\:bg-transparent{background-color:transparent}.md\:bg-current{background-color:currentColor}.md\:bg-black{--bg-opacity:1;background-color:#000;background-color:rgba(0,0,0,var(--bg-opacity))}.md\:bg-white{--bg-opacity:1;background-color:#fff;background-color:rgba(255,255,255,var(--bg-opacity))}.md\:bg-gray-100{--bg-opacity:1;background-color:#f7fafc;background-color:rgba(247,250,252,var(--bg-opacity))}.md\:bg-gray-200{--bg-opacity:1;background-color:#edf2f7;background-color:rgba(237,242,247,var(--bg-opacity))}.md\:bg-gray-300{--bg-opacity:1;background-color:#e2e8f0;background-color:rgba(226,232,240,var(--bg-opacity))}.md\:bg-gray-400{--bg-opacity:1;background-color:#cbd5e0;background-color:rgba(203,213,224,var(--bg-opacity))}.md\:bg-gray-500{--bg-opacity:1;background-color:#a0aec0;background-color:rgba(160,174,192,var(--bg-opacity))}.md\:bg-gray-600{--bg-opacity:1;background-color:#718096;background-color:rgba(113,128,150,var(--bg-opacity))}.md\:bg-gray-700{--bg-opacity:1;background-color:#4a5568;background-color:rgba(74,85,104,var(--bg-opacity))}.md\:bg-gray-800{--bg-opacity:1;background-color:#2d3748;background-color:rgba(45,55,72,var(--bg-opacity))}.md\:bg-gray-900{--bg-opacity:1;background-color:#1a202c;background-color:rgba(26,32,44,var(--bg-opacity))}.md\:bg-red-100{--bg-opacity:1;background-color:#fff5f5;background-color:rgba(255,245,245,var(--bg-opacity))}.md\:bg-red-200{--bg-opacity:1;background-color:#fed7d7;background-color:rgba(254,215,215,var(--bg-opacity))}.md\:bg-red-300{--bg-opacity:1;background-color:#feb2b2;background-color:rgba(254,178,178,var(--bg-opacity))}.md\:bg-red-400{--bg-opacity:1;background-color:#fc8181;background-color:rgba(252,129,129,var(--bg-opacity))}.md\:bg-red-500{--bg-opacity:1;background-color:#f56565;background-color:rgba(245,101,101,var(--bg-opacity))}.md\:bg-red-600{--bg-opacity:1;background-color:#e53e3e;background-color:rgba(229,62,62,var(--bg-opacity))}.md\:bg-red-700{--bg-opacity:1;background-color:#c53030;background-color:rgba(197,48,48,var(--bg-opacity))}.md\:bg-red-800{--bg-opacity:1;background-color:#9b2c2c;background-color:rgba(155,44,44,var(--bg-opacity))}.md\:bg-red-900{--bg-opacity:1;background-color:#742a2a;background-color:rgba(116,42,42,var(--bg-opacity))}.md\:bg-orange-100{--bg-opacity:1;background-color:#fffaf0;background-color:rgba(255,250,240,var(--bg-opacity))}.md\:bg-orange-200{--bg-opacity:1;background-color:#feebc8;background-color:rgba(254,235,200,var(--bg-opacity))}.md\:bg-orange-300{--bg-opacity:1;background-color:#fbd38d;background-color:rgba(251,211,141,var(--bg-opacity))}.md\:bg-orange-400{--bg-opacity:1;background-color:#f6ad55;background-color:rgba(246,173,85,var(--bg-opacity))}.md\:bg-orange-500{--bg-opacity:1;background-color:#ed8936;background-color:rgba(237,137,54,var(--bg-opacity))}.md\:bg-orange-600{--bg-opacity:1;background-color:#dd6b20;background-color:rgba(221,107,32,var(--bg-opacity))}.md\:bg-orange-700{--bg-opacity:1;background-color:#c05621;background-color:rgba(192,86,33,var(--bg-opacity))}.md\:bg-orange-800{--bg-opacity:1;background-color:#9c4221;background-color:rgba(156,66,33,var(--bg-opacity))}.md\:bg-orange-900{--bg-opacity:1;background-color:#7b341e;background-color:rgba(123,52,30,var(--bg-opacity))}.md\:bg-yellow-100{--bg-opacity:1;background-color:ivory;background-color:rgba(255,255,240,var(--bg-opacity))}.md\:bg-yellow-200{--bg-opacity:1;background-color:#fefcbf;background-color:rgba(254,252,191,var(--bg-opacity))}.md\:bg-yellow-300{--bg-opacity:1;background-color:#faf089;background-color:rgba(250,240,137,var(--bg-opacity))}.md\:bg-yellow-400{--bg-opacity:1;background-color:#f6e05e;background-color:rgba(246,224,94,var(--bg-opacity))}.md\:bg-yellow-500{--bg-opacity:1;background-color:#ecc94b;background-color:rgba(236,201,75,var(--bg-opacity))}.md\:bg-yellow-600{--bg-opacity:1;background-color:#d69e2e;background-color:rgba(214,158,46,var(--bg-opacity))}.md\:bg-yellow-700{--bg-opacity:1;background-color:#b7791f;background-color:rgba(183,121,31,var(--bg-opacity))}.md\:bg-yellow-800{--bg-opacity:1;background-color:#975a16;background-color:rgba(151,90,22,var(--bg-opacity))}.md\:bg-yellow-900{--bg-opacity:1;background-color:#744210;background-color:rgba(116,66,16,var(--bg-opacity))}.md\:bg-green-100{--bg-opacity:1;background-color:#f0fff4;background-color:rgba(240,255,244,var(--bg-opacity))}.md\:bg-green-200{--bg-opacity:1;background-color:#c6f6d5;background-color:rgba(198,246,213,var(--bg-opacity))}.md\:bg-green-300{--bg-opacity:1;background-color:#9ae6b4;background-color:rgba(154,230,180,var(--bg-opacity))}.md\:bg-green-400{--bg-opacity:1;background-color:#68d391;background-color:rgba(104,211,145,var(--bg-opacity))}.md\:bg-green-500{--bg-opacity:1;background-color:#48bb78;background-color:rgba(72,187,120,var(--bg-opacity))}.md\:bg-green-600{--bg-opacity:1;background-color:#38a169;background-color:rgba(56,161,105,var(--bg-opacity))}.md\:bg-green-700{--bg-opacity:1;background-color:#2f855a;background-color:rgba(47,133,90,var(--bg-opacity))}.md\:bg-green-800{--bg-opacity:1;background-color:#276749;background-color:rgba(39,103,73,var(--bg-opacity))}.md\:bg-green-900{--bg-opacity:1;background-color:#22543d;background-color:rgba(34,84,61,var(--bg-opacity))}.md\:bg-teal-100{--bg-opacity:1;background-color:#e6fffa;background-color:rgba(230,255,250,var(--bg-opacity))}.md\:bg-teal-200{--bg-opacity:1;background-color:#b2f5ea;background-color:rgba(178,245,234,var(--bg-opacity))}.md\:bg-teal-300{--bg-opacity:1;background-color:#81e6d9;background-color:rgba(129,230,217,var(--bg-opacity))}.md\:bg-teal-400{--bg-opacity:1;background-color:#4fd1c5;background-color:rgba(79,209,197,var(--bg-opacity))}.md\:bg-teal-500{--bg-opacity:1;background-color:#38b2ac;background-color:rgba(56,178,172,var(--bg-opacity))}.md\:bg-teal-600{--bg-opacity:1;background-color:#319795;background-color:rgba(49,151,149,var(--bg-opacity))}.md\:bg-teal-700{--bg-opacity:1;background-color:#2c7a7b;background-color:rgba(44,122,123,var(--bg-opacity))}.md\:bg-teal-800{--bg-opacity:1;background-color:#285e61;background-color:rgba(40,94,97,var(--bg-opacity))}.md\:bg-teal-900{--bg-opacity:1;background-color:#234e52;background-color:rgba(35,78,82,var(--bg-opacity))}.md\:bg-blue-100{--bg-opacity:1;background-color:#ebf8ff;background-color:rgba(235,248,255,var(--bg-opacity))}.md\:bg-blue-200{--bg-opacity:1;background-color:#bee3f8;background-color:rgba(190,227,248,var(--bg-opacity))}.md\:bg-blue-300{--bg-opacity:1;background-color:#90cdf4;background-color:rgba(144,205,244,var(--bg-opacity))}.md\:bg-blue-400{--bg-opacity:1;background-color:#63b3ed;background-color:rgba(99,179,237,var(--bg-opacity))}.md\:bg-blue-500{--bg-opacity:1;background-color:#4299e1;background-color:rgba(66,153,225,var(--bg-opacity))}.md\:bg-blue-600{--bg-opacity:1;background-color:#3182ce;background-color:rgba(49,130,206,var(--bg-opacity))}.md\:bg-blue-700{--bg-opacity:1;background-color:#2b6cb0;background-color:rgba(43,108,176,var(--bg-opacity))}.md\:bg-blue-800{--bg-opacity:1;background-color:#2c5282;background-color:rgba(44,82,130,var(--bg-opacity))}.md\:bg-blue-900{--bg-opacity:1;background-color:#2a4365;background-color:rgba(42,67,101,var(--bg-opacity))}.md\:bg-indigo-100{--bg-opacity:1;background-color:#ebf4ff;background-color:rgba(235,244,255,var(--bg-opacity))}.md\:bg-indigo-200{--bg-opacity:1;background-color:#c3dafe;background-color:rgba(195,218,254,var(--bg-opacity))}.md\:bg-indigo-300{--bg-opacity:1;background-color:#a3bffa;background-color:rgba(163,191,250,var(--bg-opacity))}.md\:bg-indigo-400{--bg-opacity:1;background-color:#7f9cf5;background-color:rgba(127,156,245,var(--bg-opacity))}.md\:bg-indigo-500{--bg-opacity:1;background-color:#667eea;background-color:rgba(102,126,234,var(--bg-opacity))}.md\:bg-indigo-600{--bg-opacity:1;background-color:#5a67d8;background-color:rgba(90,103,216,var(--bg-opacity))}.md\:bg-indigo-700{--bg-opacity:1;background-color:#4c51bf;background-color:rgba(76,81,191,var(--bg-opacity))}.md\:bg-indigo-800{--bg-opacity:1;background-color:#434190;background-color:rgba(67,65,144,var(--bg-opacity))}.md\:bg-indigo-900{--bg-opacity:1;background-color:#3c366b;background-color:rgba(60,54,107,var(--bg-opacity))}.md\:bg-purple-100{--bg-opacity:1;background-color:#faf5ff;background-color:rgba(250,245,255,var(--bg-opacity))}.md\:bg-purple-200{--bg-opacity:1;background-color:#e9d8fd;background-color:rgba(233,216,253,var(--bg-opacity))}.md\:bg-purple-300{--bg-opacity:1;background-color:#d6bcfa;background-color:rgba(214,188,250,var(--bg-opacity))}.md\:bg-purple-400{--bg-opacity:1;background-color:#b794f4;background-color:rgba(183,148,244,var(--bg-opacity))}.md\:bg-purple-500{--bg-opacity:1;background-color:#9f7aea;background-color:rgba(159,122,234,var(--bg-opacity))}.md\:bg-purple-600{--bg-opacity:1;background-color:#805ad5;background-color:rgba(128,90,213,var(--bg-opacity))}.md\:bg-purple-700{--bg-opacity:1;background-color:#6b46c1;background-color:rgba(107,70,193,var(--bg-opacity))}.md\:bg-purple-800{--bg-opacity:1;background-color:#553c9a;background-color:rgba(85,60,154,var(--bg-opacity))}.md\:bg-purple-900{--bg-opacity:1;background-color:#44337a;background-color:rgba(68,51,122,var(--bg-opacity))}.md\:bg-pink-100{--bg-opacity:1;background-color:#fff5f7;background-color:rgba(255,245,247,var(--bg-opacity))}.md\:bg-pink-200{--bg-opacity:1;background-color:#fed7e2;background-color:rgba(254,215,226,var(--bg-opacity))}.md\:bg-pink-300{--bg-opacity:1;background-color:#fbb6ce;background-color:rgba(251,182,206,var(--bg-opacity))}.md\:bg-pink-400{--bg-opacity:1;background-color:#f687b3;background-color:rgba(246,135,179,var(--bg-opacity))}.md\:bg-pink-500{--bg-opacity:1;background-color:#ed64a6;background-color:rgba(237,100,166,var(--bg-opacity))}.md\:bg-pink-600{--bg-opacity:1;background-color:#d53f8c;background-color:rgba(213,63,140,var(--bg-opacity))}.md\:bg-pink-700{--bg-opacity:1;background-color:#b83280;background-color:rgba(184,50,128,var(--bg-opacity))}.md\:bg-pink-800{--bg-opacity:1;background-color:#97266d;background-color:rgba(151,38,109,var(--bg-opacity))}.md\:bg-pink-900{--bg-opacity:1;background-color:#702459;background-color:rgba(112,36,89,var(--bg-opacity))}.md\:hover\:bg-transparent:hover{background-color:transparent}.md\:hover\:bg-current:hover{background-color:currentColor}.md\:hover\:bg-black:hover{--bg-opacity:1;background-color:#000;background-color:rgba(0,0,0,var(--bg-opacity))}.md\:hover\:bg-white:hover{--bg-opacity:1;background-color:#fff;background-color:rgba(255,255,255,var(--bg-opacity))}.md\:hover\:bg-gray-100:hover{--bg-opacity:1;background-color:#f7fafc;background-color:rgba(247,250,252,var(--bg-opacity))}.md\:hover\:bg-gray-200:hover{--bg-opacity:1;background-color:#edf2f7;background-color:rgba(237,242,247,var(--bg-opacity))}.md\:hover\:bg-gray-300:hover{--bg-opacity:1;background-color:#e2e8f0;background-color:rgba(226,232,240,var(--bg-opacity))}.md\:hover\:bg-gray-400:hover{--bg-opacity:1;background-color:#cbd5e0;background-color:rgba(203,213,224,var(--bg-opacity))}.md\:hover\:bg-gray-500:hover{--bg-opacity:1;background-color:#a0aec0;background-color:rgba(160,174,192,var(--bg-opacity))}.md\:hover\:bg-gray-600:hover{--bg-opacity:1;background-color:#718096;background-color:rgba(113,128,150,var(--bg-opacity))}.md\:hover\:bg-gray-700:hover{--bg-opacity:1;background-color:#4a5568;background-color:rgba(74,85,104,var(--bg-opacity))}.md\:hover\:bg-gray-800:hover{--bg-opacity:1;background-color:#2d3748;background-color:rgba(45,55,72,var(--bg-opacity))}.md\:hover\:bg-gray-900:hover{--bg-opacity:1;background-color:#1a202c;background-color:rgba(26,32,44,var(--bg-opacity))}.md\:hover\:bg-red-100:hover{--bg-opacity:1;background-color:#fff5f5;background-color:rgba(255,245,245,var(--bg-opacity))}.md\:hover\:bg-red-200:hover{--bg-opacity:1;background-color:#fed7d7;background-color:rgba(254,215,215,var(--bg-opacity))}.md\:hover\:bg-red-300:hover{--bg-opacity:1;background-color:#feb2b2;background-color:rgba(254,178,178,var(--bg-opacity))}.md\:hover\:bg-red-400:hover{--bg-opacity:1;background-color:#fc8181;background-color:rgba(252,129,129,var(--bg-opacity))}.md\:hover\:bg-red-500:hover{--bg-opacity:1;background-color:#f56565;background-color:rgba(245,101,101,var(--bg-opacity))}.md\:hover\:bg-red-600:hover{--bg-opacity:1;background-color:#e53e3e;background-color:rgba(229,62,62,var(--bg-opacity))}.md\:hover\:bg-red-700:hover{--bg-opacity:1;background-color:#c53030;background-color:rgba(197,48,48,var(--bg-opacity))}.md\:hover\:bg-red-800:hover{--bg-opacity:1;background-color:#9b2c2c;background-color:rgba(155,44,44,var(--bg-opacity))}.md\:hover\:bg-red-900:hover{--bg-opacity:1;background-color:#742a2a;background-color:rgba(116,42,42,var(--bg-opacity))}.md\:hover\:bg-orange-100:hover{--bg-opacity:1;background-color:#fffaf0;background-color:rgba(255,250,240,var(--bg-opacity))}.md\:hover\:bg-orange-200:hover{--bg-opacity:1;background-color:#feebc8;background-color:rgba(254,235,200,var(--bg-opacity))}.md\:hover\:bg-orange-300:hover{--bg-opacity:1;background-color:#fbd38d;background-color:rgba(251,211,141,var(--bg-opacity))}.md\:hover\:bg-orange-400:hover{--bg-opacity:1;background-color:#f6ad55;background-color:rgba(246,173,85,var(--bg-opacity))}.md\:hover\:bg-orange-500:hover{--bg-opacity:1;background-color:#ed8936;background-color:rgba(237,137,54,var(--bg-opacity))}.md\:hover\:bg-orange-600:hover{--bg-opacity:1;background-color:#dd6b20;background-color:rgba(221,107,32,var(--bg-opacity))}.md\:hover\:bg-orange-700:hover{--bg-opacity:1;background-color:#c05621;background-color:rgba(192,86,33,var(--bg-opacity))}.md\:hover\:bg-orange-800:hover{--bg-opacity:1;background-color:#9c4221;background-color:rgba(156,66,33,var(--bg-opacity))}.md\:hover\:bg-orange-900:hover{--bg-opacity:1;background-color:#7b341e;background-color:rgba(123,52,30,var(--bg-opacity))}.md\:hover\:bg-yellow-100:hover{--bg-opacity:1;background-color:ivory;background-color:rgba(255,255,240,var(--bg-opacity))}.md\:hover\:bg-yellow-200:hover{--bg-opacity:1;background-color:#fefcbf;background-color:rgba(254,252,191,var(--bg-opacity))}.md\:hover\:bg-yellow-300:hover{--bg-opacity:1;background-color:#faf089;background-color:rgba(250,240,137,var(--bg-opacity))}.md\:hover\:bg-yellow-400:hover{--bg-opacity:1;background-color:#f6e05e;background-color:rgba(246,224,94,var(--bg-opacity))}.md\:hover\:bg-yellow-500:hover{--bg-opacity:1;background-color:#ecc94b;background-color:rgba(236,201,75,var(--bg-opacity))}.md\:hover\:bg-yellow-600:hover{--bg-opacity:1;background-color:#d69e2e;background-color:rgba(214,158,46,var(--bg-opacity))}.md\:hover\:bg-yellow-700:hover{--bg-opacity:1;background-color:#b7791f;background-color:rgba(183,121,31,var(--bg-opacity))}.md\:hover\:bg-yellow-800:hover{--bg-opacity:1;background-color:#975a16;background-color:rgba(151,90,22,var(--bg-opacity))}.md\:hover\:bg-yellow-900:hover{--bg-opacity:1;background-color:#744210;background-color:rgba(116,66,16,var(--bg-opacity))}.md\:hover\:bg-green-100:hover{--bg-opacity:1;background-color:#f0fff4;background-color:rgba(240,255,244,var(--bg-opacity))}.md\:hover\:bg-green-200:hover{--bg-opacity:1;background-color:#c6f6d5;background-color:rgba(198,246,213,var(--bg-opacity))}.md\:hover\:bg-green-300:hover{--bg-opacity:1;background-color:#9ae6b4;background-color:rgba(154,230,180,var(--bg-opacity))}.md\:hover\:bg-green-400:hover{--bg-opacity:1;background-color:#68d391;background-color:rgba(104,211,145,var(--bg-opacity))}.md\:hover\:bg-green-500:hover{--bg-opacity:1;background-color:#48bb78;background-color:rgba(72,187,120,var(--bg-opacity))}.md\:hover\:bg-green-600:hover{--bg-opacity:1;background-color:#38a169;background-color:rgba(56,161,105,var(--bg-opacity))}.md\:hover\:bg-green-700:hover{--bg-opacity:1;background-color:#2f855a;background-color:rgba(47,133,90,var(--bg-opacity))}.md\:hover\:bg-green-800:hover{--bg-opacity:1;background-color:#276749;background-color:rgba(39,103,73,var(--bg-opacity))}.md\:hover\:bg-green-900:hover{--bg-opacity:1;background-color:#22543d;background-color:rgba(34,84,61,var(--bg-opacity))}.md\:hover\:bg-teal-100:hover{--bg-opacity:1;background-color:#e6fffa;background-color:rgba(230,255,250,var(--bg-opacity))}.md\:hover\:bg-teal-200:hover{--bg-opacity:1;background-color:#b2f5ea;background-color:rgba(178,245,234,var(--bg-opacity))}.md\:hover\:bg-teal-300:hover{--bg-opacity:1;background-color:#81e6d9;background-color:rgba(129,230,217,var(--bg-opacity))}.md\:hover\:bg-teal-400:hover{--bg-opacity:1;background-color:#4fd1c5;background-color:rgba(79,209,197,var(--bg-opacity))}.md\:hover\:bg-teal-500:hover{--bg-opacity:1;background-color:#38b2ac;background-color:rgba(56,178,172,var(--bg-opacity))}.md\:hover\:bg-teal-600:hover{--bg-opacity:1;background-color:#319795;background-color:rgba(49,151,149,var(--bg-opacity))}.md\:hover\:bg-teal-700:hover{--bg-opacity:1;background-color:#2c7a7b;background-color:rgba(44,122,123,var(--bg-opacity))}.md\:hover\:bg-teal-800:hover{--bg-opacity:1;background-color:#285e61;background-color:rgba(40,94,97,var(--bg-opacity))}.md\:hover\:bg-teal-900:hover{--bg-opacity:1;background-color:#234e52;background-color:rgba(35,78,82,var(--bg-opacity))}.md\:hover\:bg-blue-100:hover{--bg-opacity:1;background-color:#ebf8ff;background-color:rgba(235,248,255,var(--bg-opacity))}.md\:hover\:bg-blue-200:hover{--bg-opacity:1;background-color:#bee3f8;background-color:rgba(190,227,248,var(--bg-opacity))}.md\:hover\:bg-blue-300:hover{--bg-opacity:1;background-color:#90cdf4;background-color:rgba(144,205,244,var(--bg-opacity))}.md\:hover\:bg-blue-400:hover{--bg-opacity:1;background-color:#63b3ed;background-color:rgba(99,179,237,var(--bg-opacity))}.md\:hover\:bg-blue-500:hover{--bg-opacity:1;background-color:#4299e1;background-color:rgba(66,153,225,var(--bg-opacity))}.md\:hover\:bg-blue-600:hover{--bg-opacity:1;background-color:#3182ce;background-color:rgba(49,130,206,var(--bg-opacity))}.md\:hover\:bg-blue-700:hover{--bg-opacity:1;background-color:#2b6cb0;background-color:rgba(43,108,176,var(--bg-opacity))}.md\:hover\:bg-blue-800:hover{--bg-opacity:1;background-color:#2c5282;background-color:rgba(44,82,130,var(--bg-opacity))}.md\:hover\:bg-blue-900:hover{--bg-opacity:1;background-color:#2a4365;background-color:rgba(42,67,101,var(--bg-opacity))}.md\:hover\:bg-indigo-100:hover{--bg-opacity:1;background-color:#ebf4ff;background-color:rgba(235,244,255,var(--bg-opacity))}.md\:hover\:bg-indigo-200:hover{--bg-opacity:1;background-color:#c3dafe;background-color:rgba(195,218,254,var(--bg-opacity))}.md\:hover\:bg-indigo-300:hover{--bg-opacity:1;background-color:#a3bffa;background-color:rgba(163,191,250,var(--bg-opacity))}.md\:hover\:bg-indigo-400:hover{--bg-opacity:1;background-color:#7f9cf5;background-color:rgba(127,156,245,var(--bg-opacity))}.md\:hover\:bg-indigo-500:hover{--bg-opacity:1;background-color:#667eea;background-color:rgba(102,126,234,var(--bg-opacity))}.md\:hover\:bg-indigo-600:hover{--bg-opacity:1;background-color:#5a67d8;background-color:rgba(90,103,216,var(--bg-opacity))}.md\:hover\:bg-indigo-700:hover{--bg-opacity:1;background-color:#4c51bf;background-color:rgba(76,81,191,var(--bg-opacity))}.md\:hover\:bg-indigo-800:hover{--bg-opacity:1;background-color:#434190;background-color:rgba(67,65,144,var(--bg-opacity))}.md\:hover\:bg-indigo-900:hover{--bg-opacity:1;background-color:#3c366b;background-color:rgba(60,54,107,var(--bg-opacity))}.md\:hover\:bg-purple-100:hover{--bg-opacity:1;background-color:#faf5ff;background-color:rgba(250,245,255,var(--bg-opacity))}.md\:hover\:bg-purple-200:hover{--bg-opacity:1;background-color:#e9d8fd;background-color:rgba(233,216,253,var(--bg-opacity))}.md\:hover\:bg-purple-300:hover{--bg-opacity:1;background-color:#d6bcfa;background-color:rgba(214,188,250,var(--bg-opacity))}.md\:hover\:bg-purple-400:hover{--bg-opacity:1;background-color:#b794f4;background-color:rgba(183,148,244,var(--bg-opacity))}.md\:hover\:bg-purple-500:hover{--bg-opacity:1;background-color:#9f7aea;background-color:rgba(159,122,234,var(--bg-opacity))}.md\:hover\:bg-purple-600:hover{--bg-opacity:1;background-color:#805ad5;background-color:rgba(128,90,213,var(--bg-opacity))}.md\:hover\:bg-purple-700:hover{--bg-opacity:1;background-color:#6b46c1;background-color:rgba(107,70,193,var(--bg-opacity))}.md\:hover\:bg-purple-800:hover{--bg-opacity:1;background-color:#553c9a;background-color:rgba(85,60,154,var(--bg-opacity))}.md\:hover\:bg-purple-900:hover{--bg-opacity:1;background-color:#44337a;background-color:rgba(68,51,122,var(--bg-opacity))}.md\:hover\:bg-pink-100:hover{--bg-opacity:1;background-color:#fff5f7;background-color:rgba(255,245,247,var(--bg-opacity))}.md\:hover\:bg-pink-200:hover{--bg-opacity:1;background-color:#fed7e2;background-color:rgba(254,215,226,var(--bg-opacity))}.md\:hover\:bg-pink-300:hover{--bg-opacity:1;background-color:#fbb6ce;background-color:rgba(251,182,206,var(--bg-opacity))}.md\:hover\:bg-pink-400:hover{--bg-opacity:1;background-color:#f687b3;background-color:rgba(246,135,179,var(--bg-opacity))}.md\:hover\:bg-pink-500:hover{--bg-opacity:1;background-color:#ed64a6;background-color:rgba(237,100,166,var(--bg-opacity))}.md\:hover\:bg-pink-600:hover{--bg-opacity:1;background-color:#d53f8c;background-color:rgba(213,63,140,var(--bg-opacity))}.md\:hover\:bg-pink-700:hover{--bg-opacity:1;background-color:#b83280;background-color:rgba(184,50,128,var(--bg-opacity))}.md\:hover\:bg-pink-800:hover{--bg-opacity:1;background-color:#97266d;background-color:rgba(151,38,109,var(--bg-opacity))}.md\:hover\:bg-pink-900:hover{--bg-opacity:1;background-color:#702459;background-color:rgba(112,36,89,var(--bg-opacity))}.md\:focus\:bg-transparent:focus{background-color:transparent}.md\:focus\:bg-current:focus{background-color:currentColor}.md\:focus\:bg-black:focus{--bg-opacity:1;background-color:#000;background-color:rgba(0,0,0,var(--bg-opacity))}.md\:focus\:bg-white:focus{--bg-opacity:1;background-color:#fff;background-color:rgba(255,255,255,var(--bg-opacity))}.md\:focus\:bg-gray-100:focus{--bg-opacity:1;background-color:#f7fafc;background-color:rgba(247,250,252,var(--bg-opacity))}.md\:focus\:bg-gray-200:focus{--bg-opacity:1;background-color:#edf2f7;background-color:rgba(237,242,247,var(--bg-opacity))}.md\:focus\:bg-gray-300:focus{--bg-opacity:1;background-color:#e2e8f0;background-color:rgba(226,232,240,var(--bg-opacity))}.md\:focus\:bg-gray-400:focus{--bg-opacity:1;background-color:#cbd5e0;background-color:rgba(203,213,224,var(--bg-opacity))}.md\:focus\:bg-gray-500:focus{--bg-opacity:1;background-color:#a0aec0;background-color:rgba(160,174,192,var(--bg-opacity))}.md\:focus\:bg-gray-600:focus{--bg-opacity:1;background-color:#718096;background-color:rgba(113,128,150,var(--bg-opacity))}.md\:focus\:bg-gray-700:focus{--bg-opacity:1;background-color:#4a5568;background-color:rgba(74,85,104,var(--bg-opacity))}.md\:focus\:bg-gray-800:focus{--bg-opacity:1;background-color:#2d3748;background-color:rgba(45,55,72,var(--bg-opacity))}.md\:focus\:bg-gray-900:focus{--bg-opacity:1;background-color:#1a202c;background-color:rgba(26,32,44,var(--bg-opacity))}.md\:focus\:bg-red-100:focus{--bg-opacity:1;background-color:#fff5f5;background-color:rgba(255,245,245,var(--bg-opacity))}.md\:focus\:bg-red-200:focus{--bg-opacity:1;background-color:#fed7d7;background-color:rgba(254,215,215,var(--bg-opacity))}.md\:focus\:bg-red-300:focus{--bg-opacity:1;background-color:#feb2b2;background-color:rgba(254,178,178,var(--bg-opacity))}.md\:focus\:bg-red-400:focus{--bg-opacity:1;background-color:#fc8181;background-color:rgba(252,129,129,var(--bg-opacity))}.md\:focus\:bg-red-500:focus{--bg-opacity:1;background-color:#f56565;background-color:rgba(245,101,101,var(--bg-opacity))}.md\:focus\:bg-red-600:focus{--bg-opacity:1;background-color:#e53e3e;background-color:rgba(229,62,62,var(--bg-opacity))}.md\:focus\:bg-red-700:focus{--bg-opacity:1;background-color:#c53030;background-color:rgba(197,48,48,var(--bg-opacity))}.md\:focus\:bg-red-800:focus{--bg-opacity:1;background-color:#9b2c2c;background-color:rgba(155,44,44,var(--bg-opacity))}.md\:focus\:bg-red-900:focus{--bg-opacity:1;background-color:#742a2a;background-color:rgba(116,42,42,var(--bg-opacity))}.md\:focus\:bg-orange-100:focus{--bg-opacity:1;background-color:#fffaf0;background-color:rgba(255,250,240,var(--bg-opacity))}.md\:focus\:bg-orange-200:focus{--bg-opacity:1;background-color:#feebc8;background-color:rgba(254,235,200,var(--bg-opacity))}.md\:focus\:bg-orange-300:focus{--bg-opacity:1;background-color:#fbd38d;background-color:rgba(251,211,141,var(--bg-opacity))}.md\:focus\:bg-orange-400:focus{--bg-opacity:1;background-color:#f6ad55;background-color:rgba(246,173,85,var(--bg-opacity))}.md\:focus\:bg-orange-500:focus{--bg-opacity:1;background-color:#ed8936;background-color:rgba(237,137,54,var(--bg-opacity))}.md\:focus\:bg-orange-600:focus{--bg-opacity:1;background-color:#dd6b20;background-color:rgba(221,107,32,var(--bg-opacity))}.md\:focus\:bg-orange-700:focus{--bg-opacity:1;background-color:#c05621;background-color:rgba(192,86,33,var(--bg-opacity))}.md\:focus\:bg-orange-800:focus{--bg-opacity:1;background-color:#9c4221;background-color:rgba(156,66,33,var(--bg-opacity))}.md\:focus\:bg-orange-900:focus{--bg-opacity:1;background-color:#7b341e;background-color:rgba(123,52,30,var(--bg-opacity))}.md\:focus\:bg-yellow-100:focus{--bg-opacity:1;background-color:ivory;background-color:rgba(255,255,240,var(--bg-opacity))}.md\:focus\:bg-yellow-200:focus{--bg-opacity:1;background-color:#fefcbf;background-color:rgba(254,252,191,var(--bg-opacity))}.md\:focus\:bg-yellow-300:focus{--bg-opacity:1;background-color:#faf089;background-color:rgba(250,240,137,var(--bg-opacity))}.md\:focus\:bg-yellow-400:focus{--bg-opacity:1;background-color:#f6e05e;background-color:rgba(246,224,94,var(--bg-opacity))}.md\:focus\:bg-yellow-500:focus{--bg-opacity:1;background-color:#ecc94b;background-color:rgba(236,201,75,var(--bg-opacity))}.md\:focus\:bg-yellow-600:focus{--bg-opacity:1;background-color:#d69e2e;background-color:rgba(214,158,46,var(--bg-opacity))}.md\:focus\:bg-yellow-700:focus{--bg-opacity:1;background-color:#b7791f;background-color:rgba(183,121,31,var(--bg-opacity))}.md\:focus\:bg-yellow-800:focus{--bg-opacity:1;background-color:#975a16;background-color:rgba(151,90,22,var(--bg-opacity))}.md\:focus\:bg-yellow-900:focus{--bg-opacity:1;background-color:#744210;background-color:rgba(116,66,16,var(--bg-opacity))}.md\:focus\:bg-green-100:focus{--bg-opacity:1;background-color:#f0fff4;background-color:rgba(240,255,244,var(--bg-opacity))}.md\:focus\:bg-green-200:focus{--bg-opacity:1;background-color:#c6f6d5;background-color:rgba(198,246,213,var(--bg-opacity))}.md\:focus\:bg-green-300:focus{--bg-opacity:1;background-color:#9ae6b4;background-color:rgba(154,230,180,var(--bg-opacity))}.md\:focus\:bg-green-400:focus{--bg-opacity:1;background-color:#68d391;background-color:rgba(104,211,145,var(--bg-opacity))}.md\:focus\:bg-green-500:focus{--bg-opacity:1;background-color:#48bb78;background-color:rgba(72,187,120,var(--bg-opacity))}.md\:focus\:bg-green-600:focus{--bg-opacity:1;background-color:#38a169;background-color:rgba(56,161,105,var(--bg-opacity))}.md\:focus\:bg-green-700:focus{--bg-opacity:1;background-color:#2f855a;background-color:rgba(47,133,90,var(--bg-opacity))}.md\:focus\:bg-green-800:focus{--bg-opacity:1;background-color:#276749;background-color:rgba(39,103,73,var(--bg-opacity))}.md\:focus\:bg-green-900:focus{--bg-opacity:1;background-color:#22543d;background-color:rgba(34,84,61,var(--bg-opacity))}.md\:focus\:bg-teal-100:focus{--bg-opacity:1;background-color:#e6fffa;background-color:rgba(230,255,250,var(--bg-opacity))}.md\:focus\:bg-teal-200:focus{--bg-opacity:1;background-color:#b2f5ea;background-color:rgba(178,245,234,var(--bg-opacity))}.md\:focus\:bg-teal-300:focus{--bg-opacity:1;background-color:#81e6d9;background-color:rgba(129,230,217,var(--bg-opacity))}.md\:focus\:bg-teal-400:focus{--bg-opacity:1;background-color:#4fd1c5;background-color:rgba(79,209,197,var(--bg-opacity))}.md\:focus\:bg-teal-500:focus{--bg-opacity:1;background-color:#38b2ac;background-color:rgba(56,178,172,var(--bg-opacity))}.md\:focus\:bg-teal-600:focus{--bg-opacity:1;background-color:#319795;background-color:rgba(49,151,149,var(--bg-opacity))}.md\:focus\:bg-teal-700:focus{--bg-opacity:1;background-color:#2c7a7b;background-color:rgba(44,122,123,var(--bg-opacity))}.md\:focus\:bg-teal-800:focus{--bg-opacity:1;background-color:#285e61;background-color:rgba(40,94,97,var(--bg-opacity))}.md\:focus\:bg-teal-900:focus{--bg-opacity:1;background-color:#234e52;background-color:rgba(35,78,82,var(--bg-opacity))}.md\:focus\:bg-blue-100:focus{--bg-opacity:1;background-color:#ebf8ff;background-color:rgba(235,248,255,var(--bg-opacity))}.md\:focus\:bg-blue-200:focus{--bg-opacity:1;background-color:#bee3f8;background-color:rgba(190,227,248,var(--bg-opacity))}.md\:focus\:bg-blue-300:focus{--bg-opacity:1;background-color:#90cdf4;background-color:rgba(144,205,244,var(--bg-opacity))}.md\:focus\:bg-blue-400:focus{--bg-opacity:1;background-color:#63b3ed;background-color:rgba(99,179,237,var(--bg-opacity))}.md\:focus\:bg-blue-500:focus{--bg-opacity:1;background-color:#4299e1;background-color:rgba(66,153,225,var(--bg-opacity))}.md\:focus\:bg-blue-600:focus{--bg-opacity:1;background-color:#3182ce;background-color:rgba(49,130,206,var(--bg-opacity))}.md\:focus\:bg-blue-700:focus{--bg-opacity:1;background-color:#2b6cb0;background-color:rgba(43,108,176,var(--bg-opacity))}.md\:focus\:bg-blue-800:focus{--bg-opacity:1;background-color:#2c5282;background-color:rgba(44,82,130,var(--bg-opacity))}.md\:focus\:bg-blue-900:focus{--bg-opacity:1;background-color:#2a4365;background-color:rgba(42,67,101,var(--bg-opacity))}.md\:focus\:bg-indigo-100:focus{--bg-opacity:1;background-color:#ebf4ff;background-color:rgba(235,244,255,var(--bg-opacity))}.md\:focus\:bg-indigo-200:focus{--bg-opacity:1;background-color:#c3dafe;background-color:rgba(195,218,254,var(--bg-opacity))}.md\:focus\:bg-indigo-300:focus{--bg-opacity:1;background-color:#a3bffa;background-color:rgba(163,191,250,var(--bg-opacity))}.md\:focus\:bg-indigo-400:focus{--bg-opacity:1;background-color:#7f9cf5;background-color:rgba(127,156,245,var(--bg-opacity))}.md\:focus\:bg-indigo-500:focus{--bg-opacity:1;background-color:#667eea;background-color:rgba(102,126,234,var(--bg-opacity))}.md\:focus\:bg-indigo-600:focus{--bg-opacity:1;background-color:#5a67d8;background-color:rgba(90,103,216,var(--bg-opacity))}.md\:focus\:bg-indigo-700:focus{--bg-opacity:1;background-color:#4c51bf;background-color:rgba(76,81,191,var(--bg-opacity))}.md\:focus\:bg-indigo-800:focus{--bg-opacity:1;background-color:#434190;background-color:rgba(67,65,144,var(--bg-opacity))}.md\:focus\:bg-indigo-900:focus{--bg-opacity:1;background-color:#3c366b;background-color:rgba(60,54,107,var(--bg-opacity))}.md\:focus\:bg-purple-100:focus{--bg-opacity:1;background-color:#faf5ff;background-color:rgba(250,245,255,var(--bg-opacity))}.md\:focus\:bg-purple-200:focus{--bg-opacity:1;background-color:#e9d8fd;background-color:rgba(233,216,253,var(--bg-opacity))}.md\:focus\:bg-purple-300:focus{--bg-opacity:1;background-color:#d6bcfa;background-color:rgba(214,188,250,var(--bg-opacity))}.md\:focus\:bg-purple-400:focus{--bg-opacity:1;background-color:#b794f4;background-color:rgba(183,148,244,var(--bg-opacity))}.md\:focus\:bg-purple-500:focus{--bg-opacity:1;background-color:#9f7aea;background-color:rgba(159,122,234,var(--bg-opacity))}.md\:focus\:bg-purple-600:focus{--bg-opacity:1;background-color:#805ad5;background-color:rgba(128,90,213,var(--bg-opacity))}.md\:focus\:bg-purple-700:focus{--bg-opacity:1;background-color:#6b46c1;background-color:rgba(107,70,193,var(--bg-opacity))}.md\:focus\:bg-purple-800:focus{--bg-opacity:1;background-color:#553c9a;background-color:rgba(85,60,154,var(--bg-opacity))}.md\:focus\:bg-purple-900:focus{--bg-opacity:1;background-color:#44337a;background-color:rgba(68,51,122,var(--bg-opacity))}.md\:focus\:bg-pink-100:focus{--bg-opacity:1;background-color:#fff5f7;background-color:rgba(255,245,247,var(--bg-opacity))}.md\:focus\:bg-pink-200:focus{--bg-opacity:1;background-color:#fed7e2;background-color:rgba(254,215,226,var(--bg-opacity))}.md\:focus\:bg-pink-300:focus{--bg-opacity:1;background-color:#fbb6ce;background-color:rgba(251,182,206,var(--bg-opacity))}.md\:focus\:bg-pink-400:focus{--bg-opacity:1;background-color:#f687b3;background-color:rgba(246,135,179,var(--bg-opacity))}.md\:focus\:bg-pink-500:focus{--bg-opacity:1;background-color:#ed64a6;background-color:rgba(237,100,166,var(--bg-opacity))}.md\:focus\:bg-pink-600:focus{--bg-opacity:1;background-color:#d53f8c;background-color:rgba(213,63,140,var(--bg-opacity))}.md\:focus\:bg-pink-700:focus{--bg-opacity:1;background-color:#b83280;background-color:rgba(184,50,128,var(--bg-opacity))}.md\:focus\:bg-pink-800:focus{--bg-opacity:1;background-color:#97266d;background-color:rgba(151,38,109,var(--bg-opacity))}.md\:focus\:bg-pink-900:focus{--bg-opacity:1;background-color:#702459;background-color:rgba(112,36,89,var(--bg-opacity))}.md\:bg-none{background-image:none}.md\:bg-gradient-to-t{background-image:linear-gradient(to top,var(--gradient-color-stops))}.md\:bg-gradient-to-tr{background-image:linear-gradient(to top right,var(--gradient-color-stops))}.md\:bg-gradient-to-r{background-image:linear-gradient(to right,var(--gradient-color-stops))}.md\:bg-gradient-to-br{background-image:linear-gradient(to bottom right,var(--gradient-color-stops))}.md\:bg-gradient-to-b{background-image:linear-gradient(to bottom,var(--gradient-color-stops))}.md\:bg-gradient-to-bl{background-image:linear-gradient(to bottom left,var(--gradient-color-stops))}.md\:bg-gradient-to-l{background-image:linear-gradient(to left,var(--gradient-color-stops))}.md\:bg-gradient-to-tl{background-image:linear-gradient(to top left,var(--gradient-color-stops))}.md\:from-transparent{--gradient-from-color:transparent;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(0, 0, 0, 0))}.md\:from-current{--gradient-from-color:currentColor;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 255, 255, 0))}.md\:from-black{--gradient-from-color:#000;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(0, 0, 0, 0))}.md\:from-white{--gradient-from-color:#fff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 255, 255, 0))}.md\:from-gray-100{--gradient-from-color:#f7fafc;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(247, 250, 252, 0))}.md\:from-gray-200{--gradient-from-color:#edf2f7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(237, 242, 247, 0))}.md\:from-gray-300{--gradient-from-color:#e2e8f0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(226, 232, 240, 0))}.md\:from-gray-400{--gradient-from-color:#cbd5e0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(203, 213, 224, 0))}.md\:from-gray-500{--gradient-from-color:#a0aec0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(160, 174, 192, 0))}.md\:from-gray-600{--gradient-from-color:#718096;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(113, 128, 150, 0))}.md\:from-gray-700{--gradient-from-color:#4a5568;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(74, 85, 104, 0))}.md\:from-gray-800{--gradient-from-color:#2d3748;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(45, 55, 72, 0))}.md\:from-gray-900{--gradient-from-color:#1a202c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(26, 32, 44, 0))}.md\:from-red-100{--gradient-from-color:#fff5f5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 245, 245, 0))}.md\:from-red-200{--gradient-from-color:#fed7d7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(254, 215, 215, 0))}.md\:from-red-300{--gradient-from-color:#feb2b2;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(254, 178, 178, 0))}.md\:from-red-400{--gradient-from-color:#fc8181;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(252, 129, 129, 0))}.md\:from-red-500{--gradient-from-color:#f56565;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(245, 101, 101, 0))}.md\:from-red-600{--gradient-from-color:#e53e3e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(229, 62, 62, 0))}.md\:from-red-700{--gradient-from-color:#c53030;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(197, 48, 48, 0))}.md\:from-red-800{--gradient-from-color:#9b2c2c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(155, 44, 44, 0))}.md\:from-red-900{--gradient-from-color:#742a2a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(116, 42, 42, 0))}.md\:from-orange-100{--gradient-from-color:#fffaf0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 250, 240, 0))}.md\:from-orange-200{--gradient-from-color:#feebc8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(254, 235, 200, 0))}.md\:from-orange-300{--gradient-from-color:#fbd38d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(251, 211, 141, 0))}.md\:from-orange-400{--gradient-from-color:#f6ad55;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(246, 173, 85, 0))}.md\:from-orange-500{--gradient-from-color:#ed8936;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(237, 137, 54, 0))}.md\:from-orange-600{--gradient-from-color:#dd6b20;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(221, 107, 32, 0))}.md\:from-orange-700{--gradient-from-color:#c05621;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(192, 86, 33, 0))}.md\:from-orange-800{--gradient-from-color:#9c4221;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(156, 66, 33, 0))}.md\:from-orange-900{--gradient-from-color:#7b341e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(123, 52, 30, 0))}.md\:from-yellow-100{--gradient-from-color:#fffff0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 255, 240, 0))}.md\:from-yellow-200{--gradient-from-color:#fefcbf;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(254, 252, 191, 0))}.md\:from-yellow-300{--gradient-from-color:#faf089;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(250, 240, 137, 0))}.md\:from-yellow-400{--gradient-from-color:#f6e05e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(246, 224, 94, 0))}.md\:from-yellow-500{--gradient-from-color:#ecc94b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(236, 201, 75, 0))}.md\:from-yellow-600{--gradient-from-color:#d69e2e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(214, 158, 46, 0))}.md\:from-yellow-700{--gradient-from-color:#b7791f;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(183, 121, 31, 0))}.md\:from-yellow-800{--gradient-from-color:#975a16;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(151, 90, 22, 0))}.md\:from-yellow-900{--gradient-from-color:#744210;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(116, 66, 16, 0))}.md\:from-green-100{--gradient-from-color:#f0fff4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(240, 255, 244, 0))}.md\:from-green-200{--gradient-from-color:#c6f6d5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(198, 246, 213, 0))}.md\:from-green-300{--gradient-from-color:#9ae6b4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(154, 230, 180, 0))}.md\:from-green-400{--gradient-from-color:#68d391;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(104, 211, 145, 0))}.md\:from-green-500{--gradient-from-color:#48bb78;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(72, 187, 120, 0))}.md\:from-green-600{--gradient-from-color:#38a169;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(56, 161, 105, 0))}.md\:from-green-700{--gradient-from-color:#2f855a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(47, 133, 90, 0))}.md\:from-green-800{--gradient-from-color:#276749;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(39, 103, 73, 0))}.md\:from-green-900{--gradient-from-color:#22543d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(34, 84, 61, 0))}.md\:from-teal-100{--gradient-from-color:#e6fffa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(230, 255, 250, 0))}.md\:from-teal-200{--gradient-from-color:#b2f5ea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(178, 245, 234, 0))}.md\:from-teal-300{--gradient-from-color:#81e6d9;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(129, 230, 217, 0))}.md\:from-teal-400{--gradient-from-color:#4fd1c5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(79, 209, 197, 0))}.md\:from-teal-500{--gradient-from-color:#38b2ac;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(56, 178, 172, 0))}.md\:from-teal-600{--gradient-from-color:#319795;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(49, 151, 149, 0))}.md\:from-teal-700{--gradient-from-color:#2c7a7b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(44, 122, 123, 0))}.md\:from-teal-800{--gradient-from-color:#285e61;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(40, 94, 97, 0))}.md\:from-teal-900{--gradient-from-color:#234e52;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(35, 78, 82, 0))}.md\:from-blue-100{--gradient-from-color:#ebf8ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(235, 248, 255, 0))}.md\:from-blue-200{--gradient-from-color:#bee3f8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(190, 227, 248, 0))}.md\:from-blue-300{--gradient-from-color:#90cdf4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(144, 205, 244, 0))}.md\:from-blue-400{--gradient-from-color:#63b3ed;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(99, 179, 237, 0))}.md\:from-blue-500{--gradient-from-color:#4299e1;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(66, 153, 225, 0))}.md\:from-blue-600{--gradient-from-color:#3182ce;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(49, 130, 206, 0))}.md\:from-blue-700{--gradient-from-color:#2b6cb0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(43, 108, 176, 0))}.md\:from-blue-800{--gradient-from-color:#2c5282;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(44, 82, 130, 0))}.md\:from-blue-900{--gradient-from-color:#2a4365;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(42, 67, 101, 0))}.md\:from-indigo-100{--gradient-from-color:#ebf4ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(235, 244, 255, 0))}.md\:from-indigo-200{--gradient-from-color:#c3dafe;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(195, 218, 254, 0))}.md\:from-indigo-300{--gradient-from-color:#a3bffa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(163, 191, 250, 0))}.md\:from-indigo-400{--gradient-from-color:#7f9cf5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(127, 156, 245, 0))}.md\:from-indigo-500{--gradient-from-color:#667eea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(102, 126, 234, 0))}.md\:from-indigo-600{--gradient-from-color:#5a67d8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(90, 103, 216, 0))}.md\:from-indigo-700{--gradient-from-color:#4c51bf;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(76, 81, 191, 0))}.md\:from-indigo-800{--gradient-from-color:#434190;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(67, 65, 144, 0))}.md\:from-indigo-900{--gradient-from-color:#3c366b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(60, 54, 107, 0))}.md\:from-purple-100{--gradient-from-color:#faf5ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(250, 245, 255, 0))}.md\:from-purple-200{--gradient-from-color:#e9d8fd;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(233, 216, 253, 0))}.md\:from-purple-300{--gradient-from-color:#d6bcfa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(214, 188, 250, 0))}.md\:from-purple-400{--gradient-from-color:#b794f4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(183, 148, 244, 0))}.md\:from-purple-500{--gradient-from-color:#9f7aea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(159, 122, 234, 0))}.md\:from-purple-600{--gradient-from-color:#805ad5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(128, 90, 213, 0))}.md\:from-purple-700{--gradient-from-color:#6b46c1;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(107, 70, 193, 0))}.md\:from-purple-800{--gradient-from-color:#553c9a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(85, 60, 154, 0))}.md\:from-purple-900{--gradient-from-color:#44337a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(68, 51, 122, 0))}.md\:from-pink-100{--gradient-from-color:#fff5f7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 245, 247, 0))}.md\:from-pink-200{--gradient-from-color:#fed7e2;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(254, 215, 226, 0))}.md\:from-pink-300{--gradient-from-color:#fbb6ce;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(251, 182, 206, 0))}.md\:from-pink-400{--gradient-from-color:#f687b3;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(246, 135, 179, 0))}.md\:from-pink-500{--gradient-from-color:#ed64a6;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(237, 100, 166, 0))}.md\:from-pink-600{--gradient-from-color:#d53f8c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(213, 63, 140, 0))}.md\:from-pink-700{--gradient-from-color:#b83280;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(184, 50, 128, 0))}.md\:from-pink-800{--gradient-from-color:#97266d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(151, 38, 109, 0))}.md\:from-pink-900{--gradient-from-color:#702459;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(112, 36, 89, 0))}.md\:via-transparent{--gradient-via-color:transparent;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(0, 0, 0, 0))}.md\:via-current{--gradient-via-color:currentColor;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 255, 255, 0))}.md\:via-black{--gradient-via-color:#000;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(0, 0, 0, 0))}.md\:via-white{--gradient-via-color:#fff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 255, 255, 0))}.md\:via-gray-100{--gradient-via-color:#f7fafc;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(247, 250, 252, 0))}.md\:via-gray-200{--gradient-via-color:#edf2f7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(237, 242, 247, 0))}.md\:via-gray-300{--gradient-via-color:#e2e8f0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(226, 232, 240, 0))}.md\:via-gray-400{--gradient-via-color:#cbd5e0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(203, 213, 224, 0))}.md\:via-gray-500{--gradient-via-color:#a0aec0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(160, 174, 192, 0))}.md\:via-gray-600{--gradient-via-color:#718096;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(113, 128, 150, 0))}.md\:via-gray-700{--gradient-via-color:#4a5568;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(74, 85, 104, 0))}.md\:via-gray-800{--gradient-via-color:#2d3748;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(45, 55, 72, 0))}.md\:via-gray-900{--gradient-via-color:#1a202c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(26, 32, 44, 0))}.md\:via-red-100{--gradient-via-color:#fff5f5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 245, 245, 0))}.md\:via-red-200{--gradient-via-color:#fed7d7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(254, 215, 215, 0))}.md\:via-red-300{--gradient-via-color:#feb2b2;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(254, 178, 178, 0))}.md\:via-red-400{--gradient-via-color:#fc8181;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(252, 129, 129, 0))}.md\:via-red-500{--gradient-via-color:#f56565;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(245, 101, 101, 0))}.md\:via-red-600{--gradient-via-color:#e53e3e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(229, 62, 62, 0))}.md\:via-red-700{--gradient-via-color:#c53030;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(197, 48, 48, 0))}.md\:via-red-800{--gradient-via-color:#9b2c2c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(155, 44, 44, 0))}.md\:via-red-900{--gradient-via-color:#742a2a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(116, 42, 42, 0))}.md\:via-orange-100{--gradient-via-color:#fffaf0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 250, 240, 0))}.md\:via-orange-200{--gradient-via-color:#feebc8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(254, 235, 200, 0))}.md\:via-orange-300{--gradient-via-color:#fbd38d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(251, 211, 141, 0))}.md\:via-orange-400{--gradient-via-color:#f6ad55;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(246, 173, 85, 0))}.md\:via-orange-500{--gradient-via-color:#ed8936;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(237, 137, 54, 0))}.md\:via-orange-600{--gradient-via-color:#dd6b20;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(221, 107, 32, 0))}.md\:via-orange-700{--gradient-via-color:#c05621;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(192, 86, 33, 0))}.md\:via-orange-800{--gradient-via-color:#9c4221;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(156, 66, 33, 0))}.md\:via-orange-900{--gradient-via-color:#7b341e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(123, 52, 30, 0))}.md\:via-yellow-100{--gradient-via-color:#fffff0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 255, 240, 0))}.md\:via-yellow-200{--gradient-via-color:#fefcbf;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(254, 252, 191, 0))}.md\:via-yellow-300{--gradient-via-color:#faf089;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(250, 240, 137, 0))}.md\:via-yellow-400{--gradient-via-color:#f6e05e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(246, 224, 94, 0))}.md\:via-yellow-500{--gradient-via-color:#ecc94b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(236, 201, 75, 0))}.md\:via-yellow-600{--gradient-via-color:#d69e2e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(214, 158, 46, 0))}.md\:via-yellow-700{--gradient-via-color:#b7791f;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(183, 121, 31, 0))}.md\:via-yellow-800{--gradient-via-color:#975a16;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(151, 90, 22, 0))}.md\:via-yellow-900{--gradient-via-color:#744210;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(116, 66, 16, 0))}.md\:via-green-100{--gradient-via-color:#f0fff4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(240, 255, 244, 0))}.md\:via-green-200{--gradient-via-color:#c6f6d5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(198, 246, 213, 0))}.md\:via-green-300{--gradient-via-color:#9ae6b4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(154, 230, 180, 0))}.md\:via-green-400{--gradient-via-color:#68d391;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(104, 211, 145, 0))}.md\:via-green-500{--gradient-via-color:#48bb78;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(72, 187, 120, 0))}.md\:via-green-600{--gradient-via-color:#38a169;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(56, 161, 105, 0))}.md\:via-green-700{--gradient-via-color:#2f855a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(47, 133, 90, 0))}.md\:via-green-800{--gradient-via-color:#276749;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(39, 103, 73, 0))}.md\:via-green-900{--gradient-via-color:#22543d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(34, 84, 61, 0))}.md\:via-teal-100{--gradient-via-color:#e6fffa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(230, 255, 250, 0))}.md\:via-teal-200{--gradient-via-color:#b2f5ea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(178, 245, 234, 0))}.md\:via-teal-300{--gradient-via-color:#81e6d9;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(129, 230, 217, 0))}.md\:via-teal-400{--gradient-via-color:#4fd1c5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(79, 209, 197, 0))}.md\:via-teal-500{--gradient-via-color:#38b2ac;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(56, 178, 172, 0))}.md\:via-teal-600{--gradient-via-color:#319795;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(49, 151, 149, 0))}.md\:via-teal-700{--gradient-via-color:#2c7a7b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(44, 122, 123, 0))}.md\:via-teal-800{--gradient-via-color:#285e61;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(40, 94, 97, 0))}.md\:via-teal-900{--gradient-via-color:#234e52;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(35, 78, 82, 0))}.md\:via-blue-100{--gradient-via-color:#ebf8ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(235, 248, 255, 0))}.md\:via-blue-200{--gradient-via-color:#bee3f8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(190, 227, 248, 0))}.md\:via-blue-300{--gradient-via-color:#90cdf4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(144, 205, 244, 0))}.md\:via-blue-400{--gradient-via-color:#63b3ed;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(99, 179, 237, 0))}.md\:via-blue-500{--gradient-via-color:#4299e1;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(66, 153, 225, 0))}.md\:via-blue-600{--gradient-via-color:#3182ce;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(49, 130, 206, 0))}.md\:via-blue-700{--gradient-via-color:#2b6cb0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(43, 108, 176, 0))}.md\:via-blue-800{--gradient-via-color:#2c5282;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(44, 82, 130, 0))}.md\:via-blue-900{--gradient-via-color:#2a4365;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(42, 67, 101, 0))}.md\:via-indigo-100{--gradient-via-color:#ebf4ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(235, 244, 255, 0))}.md\:via-indigo-200{--gradient-via-color:#c3dafe;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(195, 218, 254, 0))}.md\:via-indigo-300{--gradient-via-color:#a3bffa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(163, 191, 250, 0))}.md\:via-indigo-400{--gradient-via-color:#7f9cf5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(127, 156, 245, 0))}.md\:via-indigo-500{--gradient-via-color:#667eea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(102, 126, 234, 0))}.md\:via-indigo-600{--gradient-via-color:#5a67d8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(90, 103, 216, 0))}.md\:via-indigo-700{--gradient-via-color:#4c51bf;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(76, 81, 191, 0))}.md\:via-indigo-800{--gradient-via-color:#434190;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(67, 65, 144, 0))}.md\:via-indigo-900{--gradient-via-color:#3c366b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(60, 54, 107, 0))}.md\:via-purple-100{--gradient-via-color:#faf5ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(250, 245, 255, 0))}.md\:via-purple-200{--gradient-via-color:#e9d8fd;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(233, 216, 253, 0))}.md\:via-purple-300{--gradient-via-color:#d6bcfa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(214, 188, 250, 0))}.md\:via-purple-400{--gradient-via-color:#b794f4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(183, 148, 244, 0))}.md\:via-purple-500{--gradient-via-color:#9f7aea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(159, 122, 234, 0))}.md\:via-purple-600{--gradient-via-color:#805ad5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(128, 90, 213, 0))}.md\:via-purple-700{--gradient-via-color:#6b46c1;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(107, 70, 193, 0))}.md\:via-purple-800{--gradient-via-color:#553c9a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(85, 60, 154, 0))}.md\:via-purple-900{--gradient-via-color:#44337a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(68, 51, 122, 0))}.md\:via-pink-100{--gradient-via-color:#fff5f7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 245, 247, 0))}.md\:via-pink-200{--gradient-via-color:#fed7e2;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(254, 215, 226, 0))}.md\:via-pink-300{--gradient-via-color:#fbb6ce;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(251, 182, 206, 0))}.md\:via-pink-400{--gradient-via-color:#f687b3;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(246, 135, 179, 0))}.md\:via-pink-500{--gradient-via-color:#ed64a6;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(237, 100, 166, 0))}.md\:via-pink-600{--gradient-via-color:#d53f8c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(213, 63, 140, 0))}.md\:via-pink-700{--gradient-via-color:#b83280;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(184, 50, 128, 0))}.md\:via-pink-800{--gradient-via-color:#97266d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(151, 38, 109, 0))}.md\:via-pink-900{--gradient-via-color:#702459;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(112, 36, 89, 0))}.md\:to-transparent{--gradient-to-color:transparent}.md\:to-current{--gradient-to-color:currentColor}.md\:to-black{--gradient-to-color:#000}.md\:to-white{--gradient-to-color:#fff}.md\:to-gray-100{--gradient-to-color:#f7fafc}.md\:to-gray-200{--gradient-to-color:#edf2f7}.md\:to-gray-300{--gradient-to-color:#e2e8f0}.md\:to-gray-400{--gradient-to-color:#cbd5e0}.md\:to-gray-500{--gradient-to-color:#a0aec0}.md\:to-gray-600{--gradient-to-color:#718096}.md\:to-gray-700{--gradient-to-color:#4a5568}.md\:to-gray-800{--gradient-to-color:#2d3748}.md\:to-gray-900{--gradient-to-color:#1a202c}.md\:to-red-100{--gradient-to-color:#fff5f5}.md\:to-red-200{--gradient-to-color:#fed7d7}.md\:to-red-300{--gradient-to-color:#feb2b2}.md\:to-red-400{--gradient-to-color:#fc8181}.md\:to-red-500{--gradient-to-color:#f56565}.md\:to-red-600{--gradient-to-color:#e53e3e}.md\:to-red-700{--gradient-to-color:#c53030}.md\:to-red-800{--gradient-to-color:#9b2c2c}.md\:to-red-900{--gradient-to-color:#742a2a}.md\:to-orange-100{--gradient-to-color:#fffaf0}.md\:to-orange-200{--gradient-to-color:#feebc8}.md\:to-orange-300{--gradient-to-color:#fbd38d}.md\:to-orange-400{--gradient-to-color:#f6ad55}.md\:to-orange-500{--gradient-to-color:#ed8936}.md\:to-orange-600{--gradient-to-color:#dd6b20}.md\:to-orange-700{--gradient-to-color:#c05621}.md\:to-orange-800{--gradient-to-color:#9c4221}.md\:to-orange-900{--gradient-to-color:#7b341e}.md\:to-yellow-100{--gradient-to-color:#fffff0}.md\:to-yellow-200{--gradient-to-color:#fefcbf}.md\:to-yellow-300{--gradient-to-color:#faf089}.md\:to-yellow-400{--gradient-to-color:#f6e05e}.md\:to-yellow-500{--gradient-to-color:#ecc94b}.md\:to-yellow-600{--gradient-to-color:#d69e2e}.md\:to-yellow-700{--gradient-to-color:#b7791f}.md\:to-yellow-800{--gradient-to-color:#975a16}.md\:to-yellow-900{--gradient-to-color:#744210}.md\:to-green-100{--gradient-to-color:#f0fff4}.md\:to-green-200{--gradient-to-color:#c6f6d5}.md\:to-green-300{--gradient-to-color:#9ae6b4}.md\:to-green-400{--gradient-to-color:#68d391}.md\:to-green-500{--gradient-to-color:#48bb78}.md\:to-green-600{--gradient-to-color:#38a169}.md\:to-green-700{--gradient-to-color:#2f855a}.md\:to-green-800{--gradient-to-color:#276749}.md\:to-green-900{--gradient-to-color:#22543d}.md\:to-teal-100{--gradient-to-color:#e6fffa}.md\:to-teal-200{--gradient-to-color:#b2f5ea}.md\:to-teal-300{--gradient-to-color:#81e6d9}.md\:to-teal-400{--gradient-to-color:#4fd1c5}.md\:to-teal-500{--gradient-to-color:#38b2ac}.md\:to-teal-600{--gradient-to-color:#319795}.md\:to-teal-700{--gradient-to-color:#2c7a7b}.md\:to-teal-800{--gradient-to-color:#285e61}.md\:to-teal-900{--gradient-to-color:#234e52}.md\:to-blue-100{--gradient-to-color:#ebf8ff}.md\:to-blue-200{--gradient-to-color:#bee3f8}.md\:to-blue-300{--gradient-to-color:#90cdf4}.md\:to-blue-400{--gradient-to-color:#63b3ed}.md\:to-blue-500{--gradient-to-color:#4299e1}.md\:to-blue-600{--gradient-to-color:#3182ce}.md\:to-blue-700{--gradient-to-color:#2b6cb0}.md\:to-blue-800{--gradient-to-color:#2c5282}.md\:to-blue-900{--gradient-to-color:#2a4365}.md\:to-indigo-100{--gradient-to-color:#ebf4ff}.md\:to-indigo-200{--gradient-to-color:#c3dafe}.md\:to-indigo-300{--gradient-to-color:#a3bffa}.md\:to-indigo-400{--gradient-to-color:#7f9cf5}.md\:to-indigo-500{--gradient-to-color:#667eea}.md\:to-indigo-600{--gradient-to-color:#5a67d8}.md\:to-indigo-700{--gradient-to-color:#4c51bf}.md\:to-indigo-800{--gradient-to-color:#434190}.md\:to-indigo-900{--gradient-to-color:#3c366b}.md\:to-purple-100{--gradient-to-color:#faf5ff}.md\:to-purple-200{--gradient-to-color:#e9d8fd}.md\:to-purple-300{--gradient-to-color:#d6bcfa}.md\:to-purple-400{--gradient-to-color:#b794f4}.md\:to-purple-500{--gradient-to-color:#9f7aea}.md\:to-purple-600{--gradient-to-color:#805ad5}.md\:to-purple-700{--gradient-to-color:#6b46c1}.md\:to-purple-800{--gradient-to-color:#553c9a}.md\:to-purple-900{--gradient-to-color:#44337a}.md\:to-pink-100{--gradient-to-color:#fff5f7}.md\:to-pink-200{--gradient-to-color:#fed7e2}.md\:to-pink-300{--gradient-to-color:#fbb6ce}.md\:to-pink-400{--gradient-to-color:#f687b3}.md\:to-pink-500{--gradient-to-color:#ed64a6}.md\:to-pink-600{--gradient-to-color:#d53f8c}.md\:to-pink-700{--gradient-to-color:#b83280}.md\:to-pink-800{--gradient-to-color:#97266d}.md\:to-pink-900{--gradient-to-color:#702459}.md\:hover\:from-transparent:hover{--gradient-from-color:transparent;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(0, 0, 0, 0))}.md\:hover\:from-current:hover{--gradient-from-color:currentColor;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 255, 255, 0))}.md\:hover\:from-black:hover{--gradient-from-color:#000;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(0, 0, 0, 0))}.md\:hover\:from-white:hover{--gradient-from-color:#fff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 255, 255, 0))}.md\:hover\:from-gray-100:hover{--gradient-from-color:#f7fafc;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(247, 250, 252, 0))}.md\:hover\:from-gray-200:hover{--gradient-from-color:#edf2f7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(237, 242, 247, 0))}.md\:hover\:from-gray-300:hover{--gradient-from-color:#e2e8f0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(226, 232, 240, 0))}.md\:hover\:from-gray-400:hover{--gradient-from-color:#cbd5e0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(203, 213, 224, 0))}.md\:hover\:from-gray-500:hover{--gradient-from-color:#a0aec0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(160, 174, 192, 0))}.md\:hover\:from-gray-600:hover{--gradient-from-color:#718096;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(113, 128, 150, 0))}.md\:hover\:from-gray-700:hover{--gradient-from-color:#4a5568;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(74, 85, 104, 0))}.md\:hover\:from-gray-800:hover{--gradient-from-color:#2d3748;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(45, 55, 72, 0))}.md\:hover\:from-gray-900:hover{--gradient-from-color:#1a202c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(26, 32, 44, 0))}.md\:hover\:from-red-100:hover{--gradient-from-color:#fff5f5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 245, 245, 0))}.md\:hover\:from-red-200:hover{--gradient-from-color:#fed7d7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(254, 215, 215, 0))}.md\:hover\:from-red-300:hover{--gradient-from-color:#feb2b2;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(254, 178, 178, 0))}.md\:hover\:from-red-400:hover{--gradient-from-color:#fc8181;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(252, 129, 129, 0))}.md\:hover\:from-red-500:hover{--gradient-from-color:#f56565;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(245, 101, 101, 0))}.md\:hover\:from-red-600:hover{--gradient-from-color:#e53e3e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(229, 62, 62, 0))}.md\:hover\:from-red-700:hover{--gradient-from-color:#c53030;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(197, 48, 48, 0))}.md\:hover\:from-red-800:hover{--gradient-from-color:#9b2c2c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(155, 44, 44, 0))}.md\:hover\:from-red-900:hover{--gradient-from-color:#742a2a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(116, 42, 42, 0))}.md\:hover\:from-orange-100:hover{--gradient-from-color:#fffaf0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 250, 240, 0))}.md\:hover\:from-orange-200:hover{--gradient-from-color:#feebc8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(254, 235, 200, 0))}.md\:hover\:from-orange-300:hover{--gradient-from-color:#fbd38d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(251, 211, 141, 0))}.md\:hover\:from-orange-400:hover{--gradient-from-color:#f6ad55;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(246, 173, 85, 0))}.md\:hover\:from-orange-500:hover{--gradient-from-color:#ed8936;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(237, 137, 54, 0))}.md\:hover\:from-orange-600:hover{--gradient-from-color:#dd6b20;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(221, 107, 32, 0))}.md\:hover\:from-orange-700:hover{--gradient-from-color:#c05621;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(192, 86, 33, 0))}.md\:hover\:from-orange-800:hover{--gradient-from-color:#9c4221;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(156, 66, 33, 0))}.md\:hover\:from-orange-900:hover{--gradient-from-color:#7b341e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(123, 52, 30, 0))}.md\:hover\:from-yellow-100:hover{--gradient-from-color:#fffff0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 255, 240, 0))}.md\:hover\:from-yellow-200:hover{--gradient-from-color:#fefcbf;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(254, 252, 191, 0))}.md\:hover\:from-yellow-300:hover{--gradient-from-color:#faf089;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(250, 240, 137, 0))}.md\:hover\:from-yellow-400:hover{--gradient-from-color:#f6e05e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(246, 224, 94, 0))}.md\:hover\:from-yellow-500:hover{--gradient-from-color:#ecc94b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(236, 201, 75, 0))}.md\:hover\:from-yellow-600:hover{--gradient-from-color:#d69e2e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(214, 158, 46, 0))}.md\:hover\:from-yellow-700:hover{--gradient-from-color:#b7791f;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(183, 121, 31, 0))}.md\:hover\:from-yellow-800:hover{--gradient-from-color:#975a16;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(151, 90, 22, 0))}.md\:hover\:from-yellow-900:hover{--gradient-from-color:#744210;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(116, 66, 16, 0))}.md\:hover\:from-green-100:hover{--gradient-from-color:#f0fff4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(240, 255, 244, 0))}.md\:hover\:from-green-200:hover{--gradient-from-color:#c6f6d5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(198, 246, 213, 0))}.md\:hover\:from-green-300:hover{--gradient-from-color:#9ae6b4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(154, 230, 180, 0))}.md\:hover\:from-green-400:hover{--gradient-from-color:#68d391;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(104, 211, 145, 0))}.md\:hover\:from-green-500:hover{--gradient-from-color:#48bb78;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(72, 187, 120, 0))}.md\:hover\:from-green-600:hover{--gradient-from-color:#38a169;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(56, 161, 105, 0))}.md\:hover\:from-green-700:hover{--gradient-from-color:#2f855a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(47, 133, 90, 0))}.md\:hover\:from-green-800:hover{--gradient-from-color:#276749;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(39, 103, 73, 0))}.md\:hover\:from-green-900:hover{--gradient-from-color:#22543d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(34, 84, 61, 0))}.md\:hover\:from-teal-100:hover{--gradient-from-color:#e6fffa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(230, 255, 250, 0))}.md\:hover\:from-teal-200:hover{--gradient-from-color:#b2f5ea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(178, 245, 234, 0))}.md\:hover\:from-teal-300:hover{--gradient-from-color:#81e6d9;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(129, 230, 217, 0))}.md\:hover\:from-teal-400:hover{--gradient-from-color:#4fd1c5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(79, 209, 197, 0))}.md\:hover\:from-teal-500:hover{--gradient-from-color:#38b2ac;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(56, 178, 172, 0))}.md\:hover\:from-teal-600:hover{--gradient-from-color:#319795;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(49, 151, 149, 0))}.md\:hover\:from-teal-700:hover{--gradient-from-color:#2c7a7b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(44, 122, 123, 0))}.md\:hover\:from-teal-800:hover{--gradient-from-color:#285e61;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(40, 94, 97, 0))}.md\:hover\:from-teal-900:hover{--gradient-from-color:#234e52;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(35, 78, 82, 0))}.md\:hover\:from-blue-100:hover{--gradient-from-color:#ebf8ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(235, 248, 255, 0))}.md\:hover\:from-blue-200:hover{--gradient-from-color:#bee3f8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(190, 227, 248, 0))}.md\:hover\:from-blue-300:hover{--gradient-from-color:#90cdf4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(144, 205, 244, 0))}.md\:hover\:from-blue-400:hover{--gradient-from-color:#63b3ed;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(99, 179, 237, 0))}.md\:hover\:from-blue-500:hover{--gradient-from-color:#4299e1;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(66, 153, 225, 0))}.md\:hover\:from-blue-600:hover{--gradient-from-color:#3182ce;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(49, 130, 206, 0))}.md\:hover\:from-blue-700:hover{--gradient-from-color:#2b6cb0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(43, 108, 176, 0))}.md\:hover\:from-blue-800:hover{--gradient-from-color:#2c5282;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(44, 82, 130, 0))}.md\:hover\:from-blue-900:hover{--gradient-from-color:#2a4365;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(42, 67, 101, 0))}.md\:hover\:from-indigo-100:hover{--gradient-from-color:#ebf4ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(235, 244, 255, 0))}.md\:hover\:from-indigo-200:hover{--gradient-from-color:#c3dafe;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(195, 218, 254, 0))}.md\:hover\:from-indigo-300:hover{--gradient-from-color:#a3bffa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(163, 191, 250, 0))}.md\:hover\:from-indigo-400:hover{--gradient-from-color:#7f9cf5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(127, 156, 245, 0))}.md\:hover\:from-indigo-500:hover{--gradient-from-color:#667eea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(102, 126, 234, 0))}.md\:hover\:from-indigo-600:hover{--gradient-from-color:#5a67d8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(90, 103, 216, 0))}.md\:hover\:from-indigo-700:hover{--gradient-from-color:#4c51bf;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(76, 81, 191, 0))}.md\:hover\:from-indigo-800:hover{--gradient-from-color:#434190;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(67, 65, 144, 0))}.md\:hover\:from-indigo-900:hover{--gradient-from-color:#3c366b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(60, 54, 107, 0))}.md\:hover\:from-purple-100:hover{--gradient-from-color:#faf5ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(250, 245, 255, 0))}.md\:hover\:from-purple-200:hover{--gradient-from-color:#e9d8fd;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(233, 216, 253, 0))}.md\:hover\:from-purple-300:hover{--gradient-from-color:#d6bcfa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(214, 188, 250, 0))}.md\:hover\:from-purple-400:hover{--gradient-from-color:#b794f4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(183, 148, 244, 0))}.md\:hover\:from-purple-500:hover{--gradient-from-color:#9f7aea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(159, 122, 234, 0))}.md\:hover\:from-purple-600:hover{--gradient-from-color:#805ad5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(128, 90, 213, 0))}.md\:hover\:from-purple-700:hover{--gradient-from-color:#6b46c1;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(107, 70, 193, 0))}.md\:hover\:from-purple-800:hover{--gradient-from-color:#553c9a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(85, 60, 154, 0))}.md\:hover\:from-purple-900:hover{--gradient-from-color:#44337a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(68, 51, 122, 0))}.md\:hover\:from-pink-100:hover{--gradient-from-color:#fff5f7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 245, 247, 0))}.md\:hover\:from-pink-200:hover{--gradient-from-color:#fed7e2;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(254, 215, 226, 0))}.md\:hover\:from-pink-300:hover{--gradient-from-color:#fbb6ce;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(251, 182, 206, 0))}.md\:hover\:from-pink-400:hover{--gradient-from-color:#f687b3;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(246, 135, 179, 0))}.md\:hover\:from-pink-500:hover{--gradient-from-color:#ed64a6;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(237, 100, 166, 0))}.md\:hover\:from-pink-600:hover{--gradient-from-color:#d53f8c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(213, 63, 140, 0))}.md\:hover\:from-pink-700:hover{--gradient-from-color:#b83280;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(184, 50, 128, 0))}.md\:hover\:from-pink-800:hover{--gradient-from-color:#97266d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(151, 38, 109, 0))}.md\:hover\:from-pink-900:hover{--gradient-from-color:#702459;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(112, 36, 89, 0))}.md\:hover\:via-transparent:hover{--gradient-via-color:transparent;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(0, 0, 0, 0))}.md\:hover\:via-current:hover{--gradient-via-color:currentColor;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 255, 255, 0))}.md\:hover\:via-black:hover{--gradient-via-color:#000;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(0, 0, 0, 0))}.md\:hover\:via-white:hover{--gradient-via-color:#fff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 255, 255, 0))}.md\:hover\:via-gray-100:hover{--gradient-via-color:#f7fafc;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(247, 250, 252, 0))}.md\:hover\:via-gray-200:hover{--gradient-via-color:#edf2f7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(237, 242, 247, 0))}.md\:hover\:via-gray-300:hover{--gradient-via-color:#e2e8f0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(226, 232, 240, 0))}.md\:hover\:via-gray-400:hover{--gradient-via-color:#cbd5e0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(203, 213, 224, 0))}.md\:hover\:via-gray-500:hover{--gradient-via-color:#a0aec0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(160, 174, 192, 0))}.md\:hover\:via-gray-600:hover{--gradient-via-color:#718096;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(113, 128, 150, 0))}.md\:hover\:via-gray-700:hover{--gradient-via-color:#4a5568;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(74, 85, 104, 0))}.md\:hover\:via-gray-800:hover{--gradient-via-color:#2d3748;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(45, 55, 72, 0))}.md\:hover\:via-gray-900:hover{--gradient-via-color:#1a202c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(26, 32, 44, 0))}.md\:hover\:via-red-100:hover{--gradient-via-color:#fff5f5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 245, 245, 0))}.md\:hover\:via-red-200:hover{--gradient-via-color:#fed7d7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(254, 215, 215, 0))}.md\:hover\:via-red-300:hover{--gradient-via-color:#feb2b2;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(254, 178, 178, 0))}.md\:hover\:via-red-400:hover{--gradient-via-color:#fc8181;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(252, 129, 129, 0))}.md\:hover\:via-red-500:hover{--gradient-via-color:#f56565;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(245, 101, 101, 0))}.md\:hover\:via-red-600:hover{--gradient-via-color:#e53e3e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(229, 62, 62, 0))}.md\:hover\:via-red-700:hover{--gradient-via-color:#c53030;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(197, 48, 48, 0))}.md\:hover\:via-red-800:hover{--gradient-via-color:#9b2c2c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(155, 44, 44, 0))}.md\:hover\:via-red-900:hover{--gradient-via-color:#742a2a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(116, 42, 42, 0))}.md\:hover\:via-orange-100:hover{--gradient-via-color:#fffaf0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 250, 240, 0))}.md\:hover\:via-orange-200:hover{--gradient-via-color:#feebc8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(254, 235, 200, 0))}.md\:hover\:via-orange-300:hover{--gradient-via-color:#fbd38d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(251, 211, 141, 0))}.md\:hover\:via-orange-400:hover{--gradient-via-color:#f6ad55;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(246, 173, 85, 0))}.md\:hover\:via-orange-500:hover{--gradient-via-color:#ed8936;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(237, 137, 54, 0))}.md\:hover\:via-orange-600:hover{--gradient-via-color:#dd6b20;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(221, 107, 32, 0))}.md\:hover\:via-orange-700:hover{--gradient-via-color:#c05621;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(192, 86, 33, 0))}.md\:hover\:via-orange-800:hover{--gradient-via-color:#9c4221;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(156, 66, 33, 0))}.md\:hover\:via-orange-900:hover{--gradient-via-color:#7b341e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(123, 52, 30, 0))}.md\:hover\:via-yellow-100:hover{--gradient-via-color:#fffff0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 255, 240, 0))}.md\:hover\:via-yellow-200:hover{--gradient-via-color:#fefcbf;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(254, 252, 191, 0))}.md\:hover\:via-yellow-300:hover{--gradient-via-color:#faf089;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(250, 240, 137, 0))}.md\:hover\:via-yellow-400:hover{--gradient-via-color:#f6e05e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(246, 224, 94, 0))}.md\:hover\:via-yellow-500:hover{--gradient-via-color:#ecc94b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(236, 201, 75, 0))}.md\:hover\:via-yellow-600:hover{--gradient-via-color:#d69e2e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(214, 158, 46, 0))}.md\:hover\:via-yellow-700:hover{--gradient-via-color:#b7791f;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(183, 121, 31, 0))}.md\:hover\:via-yellow-800:hover{--gradient-via-color:#975a16;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(151, 90, 22, 0))}.md\:hover\:via-yellow-900:hover{--gradient-via-color:#744210;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(116, 66, 16, 0))}.md\:hover\:via-green-100:hover{--gradient-via-color:#f0fff4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(240, 255, 244, 0))}.md\:hover\:via-green-200:hover{--gradient-via-color:#c6f6d5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(198, 246, 213, 0))}.md\:hover\:via-green-300:hover{--gradient-via-color:#9ae6b4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(154, 230, 180, 0))}.md\:hover\:via-green-400:hover{--gradient-via-color:#68d391;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(104, 211, 145, 0))}.md\:hover\:via-green-500:hover{--gradient-via-color:#48bb78;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(72, 187, 120, 0))}.md\:hover\:via-green-600:hover{--gradient-via-color:#38a169;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(56, 161, 105, 0))}.md\:hover\:via-green-700:hover{--gradient-via-color:#2f855a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(47, 133, 90, 0))}.md\:hover\:via-green-800:hover{--gradient-via-color:#276749;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(39, 103, 73, 0))}.md\:hover\:via-green-900:hover{--gradient-via-color:#22543d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(34, 84, 61, 0))}.md\:hover\:via-teal-100:hover{--gradient-via-color:#e6fffa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(230, 255, 250, 0))}.md\:hover\:via-teal-200:hover{--gradient-via-color:#b2f5ea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(178, 245, 234, 0))}.md\:hover\:via-teal-300:hover{--gradient-via-color:#81e6d9;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(129, 230, 217, 0))}.md\:hover\:via-teal-400:hover{--gradient-via-color:#4fd1c5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(79, 209, 197, 0))}.md\:hover\:via-teal-500:hover{--gradient-via-color:#38b2ac;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(56, 178, 172, 0))}.md\:hover\:via-teal-600:hover{--gradient-via-color:#319795;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(49, 151, 149, 0))}.md\:hover\:via-teal-700:hover{--gradient-via-color:#2c7a7b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(44, 122, 123, 0))}.md\:hover\:via-teal-800:hover{--gradient-via-color:#285e61;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(40, 94, 97, 0))}.md\:hover\:via-teal-900:hover{--gradient-via-color:#234e52;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(35, 78, 82, 0))}.md\:hover\:via-blue-100:hover{--gradient-via-color:#ebf8ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(235, 248, 255, 0))}.md\:hover\:via-blue-200:hover{--gradient-via-color:#bee3f8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(190, 227, 248, 0))}.md\:hover\:via-blue-300:hover{--gradient-via-color:#90cdf4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(144, 205, 244, 0))}.md\:hover\:via-blue-400:hover{--gradient-via-color:#63b3ed;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(99, 179, 237, 0))}.md\:hover\:via-blue-500:hover{--gradient-via-color:#4299e1;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(66, 153, 225, 0))}.md\:hover\:via-blue-600:hover{--gradient-via-color:#3182ce;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(49, 130, 206, 0))}.md\:hover\:via-blue-700:hover{--gradient-via-color:#2b6cb0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(43, 108, 176, 0))}.md\:hover\:via-blue-800:hover{--gradient-via-color:#2c5282;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(44, 82, 130, 0))}.md\:hover\:via-blue-900:hover{--gradient-via-color:#2a4365;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(42, 67, 101, 0))}.md\:hover\:via-indigo-100:hover{--gradient-via-color:#ebf4ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(235, 244, 255, 0))}.md\:hover\:via-indigo-200:hover{--gradient-via-color:#c3dafe;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(195, 218, 254, 0))}.md\:hover\:via-indigo-300:hover{--gradient-via-color:#a3bffa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(163, 191, 250, 0))}.md\:hover\:via-indigo-400:hover{--gradient-via-color:#7f9cf5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(127, 156, 245, 0))}.md\:hover\:via-indigo-500:hover{--gradient-via-color:#667eea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(102, 126, 234, 0))}.md\:hover\:via-indigo-600:hover{--gradient-via-color:#5a67d8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(90, 103, 216, 0))}.md\:hover\:via-indigo-700:hover{--gradient-via-color:#4c51bf;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(76, 81, 191, 0))}.md\:hover\:via-indigo-800:hover{--gradient-via-color:#434190;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(67, 65, 144, 0))}.md\:hover\:via-indigo-900:hover{--gradient-via-color:#3c366b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(60, 54, 107, 0))}.md\:hover\:via-purple-100:hover{--gradient-via-color:#faf5ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(250, 245, 255, 0))}.md\:hover\:via-purple-200:hover{--gradient-via-color:#e9d8fd;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(233, 216, 253, 0))}.md\:hover\:via-purple-300:hover{--gradient-via-color:#d6bcfa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(214, 188, 250, 0))}.md\:hover\:via-purple-400:hover{--gradient-via-color:#b794f4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(183, 148, 244, 0))}.md\:hover\:via-purple-500:hover{--gradient-via-color:#9f7aea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(159, 122, 234, 0))}.md\:hover\:via-purple-600:hover{--gradient-via-color:#805ad5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(128, 90, 213, 0))}.md\:hover\:via-purple-700:hover{--gradient-via-color:#6b46c1;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(107, 70, 193, 0))}.md\:hover\:via-purple-800:hover{--gradient-via-color:#553c9a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(85, 60, 154, 0))}.md\:hover\:via-purple-900:hover{--gradient-via-color:#44337a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(68, 51, 122, 0))}.md\:hover\:via-pink-100:hover{--gradient-via-color:#fff5f7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 245, 247, 0))}.md\:hover\:via-pink-200:hover{--gradient-via-color:#fed7e2;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(254, 215, 226, 0))}.md\:hover\:via-pink-300:hover{--gradient-via-color:#fbb6ce;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(251, 182, 206, 0))}.md\:hover\:via-pink-400:hover{--gradient-via-color:#f687b3;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(246, 135, 179, 0))}.md\:hover\:via-pink-500:hover{--gradient-via-color:#ed64a6;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(237, 100, 166, 0))}.md\:hover\:via-pink-600:hover{--gradient-via-color:#d53f8c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(213, 63, 140, 0))}.md\:hover\:via-pink-700:hover{--gradient-via-color:#b83280;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(184, 50, 128, 0))}.md\:hover\:via-pink-800:hover{--gradient-via-color:#97266d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(151, 38, 109, 0))}.md\:hover\:via-pink-900:hover{--gradient-via-color:#702459;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(112, 36, 89, 0))}.md\:hover\:to-transparent:hover{--gradient-to-color:transparent}.md\:hover\:to-current:hover{--gradient-to-color:currentColor}.md\:hover\:to-black:hover{--gradient-to-color:#000}.md\:hover\:to-white:hover{--gradient-to-color:#fff}.md\:hover\:to-gray-100:hover{--gradient-to-color:#f7fafc}.md\:hover\:to-gray-200:hover{--gradient-to-color:#edf2f7}.md\:hover\:to-gray-300:hover{--gradient-to-color:#e2e8f0}.md\:hover\:to-gray-400:hover{--gradient-to-color:#cbd5e0}.md\:hover\:to-gray-500:hover{--gradient-to-color:#a0aec0}.md\:hover\:to-gray-600:hover{--gradient-to-color:#718096}.md\:hover\:to-gray-700:hover{--gradient-to-color:#4a5568}.md\:hover\:to-gray-800:hover{--gradient-to-color:#2d3748}.md\:hover\:to-gray-900:hover{--gradient-to-color:#1a202c}.md\:hover\:to-red-100:hover{--gradient-to-color:#fff5f5}.md\:hover\:to-red-200:hover{--gradient-to-color:#fed7d7}.md\:hover\:to-red-300:hover{--gradient-to-color:#feb2b2}.md\:hover\:to-red-400:hover{--gradient-to-color:#fc8181}.md\:hover\:to-red-500:hover{--gradient-to-color:#f56565}.md\:hover\:to-red-600:hover{--gradient-to-color:#e53e3e}.md\:hover\:to-red-700:hover{--gradient-to-color:#c53030}.md\:hover\:to-red-800:hover{--gradient-to-color:#9b2c2c}.md\:hover\:to-red-900:hover{--gradient-to-color:#742a2a}.md\:hover\:to-orange-100:hover{--gradient-to-color:#fffaf0}.md\:hover\:to-orange-200:hover{--gradient-to-color:#feebc8}.md\:hover\:to-orange-300:hover{--gradient-to-color:#fbd38d}.md\:hover\:to-orange-400:hover{--gradient-to-color:#f6ad55}.md\:hover\:to-orange-500:hover{--gradient-to-color:#ed8936}.md\:hover\:to-orange-600:hover{--gradient-to-color:#dd6b20}.md\:hover\:to-orange-700:hover{--gradient-to-color:#c05621}.md\:hover\:to-orange-800:hover{--gradient-to-color:#9c4221}.md\:hover\:to-orange-900:hover{--gradient-to-color:#7b341e}.md\:hover\:to-yellow-100:hover{--gradient-to-color:#fffff0}.md\:hover\:to-yellow-200:hover{--gradient-to-color:#fefcbf}.md\:hover\:to-yellow-300:hover{--gradient-to-color:#faf089}.md\:hover\:to-yellow-400:hover{--gradient-to-color:#f6e05e}.md\:hover\:to-yellow-500:hover{--gradient-to-color:#ecc94b}.md\:hover\:to-yellow-600:hover{--gradient-to-color:#d69e2e}.md\:hover\:to-yellow-700:hover{--gradient-to-color:#b7791f}.md\:hover\:to-yellow-800:hover{--gradient-to-color:#975a16}.md\:hover\:to-yellow-900:hover{--gradient-to-color:#744210}.md\:hover\:to-green-100:hover{--gradient-to-color:#f0fff4}.md\:hover\:to-green-200:hover{--gradient-to-color:#c6f6d5}.md\:hover\:to-green-300:hover{--gradient-to-color:#9ae6b4}.md\:hover\:to-green-400:hover{--gradient-to-color:#68d391}.md\:hover\:to-green-500:hover{--gradient-to-color:#48bb78}.md\:hover\:to-green-600:hover{--gradient-to-color:#38a169}.md\:hover\:to-green-700:hover{--gradient-to-color:#2f855a}.md\:hover\:to-green-800:hover{--gradient-to-color:#276749}.md\:hover\:to-green-900:hover{--gradient-to-color:#22543d}.md\:hover\:to-teal-100:hover{--gradient-to-color:#e6fffa}.md\:hover\:to-teal-200:hover{--gradient-to-color:#b2f5ea}.md\:hover\:to-teal-300:hover{--gradient-to-color:#81e6d9}.md\:hover\:to-teal-400:hover{--gradient-to-color:#4fd1c5}.md\:hover\:to-teal-500:hover{--gradient-to-color:#38b2ac}.md\:hover\:to-teal-600:hover{--gradient-to-color:#319795}.md\:hover\:to-teal-700:hover{--gradient-to-color:#2c7a7b}.md\:hover\:to-teal-800:hover{--gradient-to-color:#285e61}.md\:hover\:to-teal-900:hover{--gradient-to-color:#234e52}.md\:hover\:to-blue-100:hover{--gradient-to-color:#ebf8ff}.md\:hover\:to-blue-200:hover{--gradient-to-color:#bee3f8}.md\:hover\:to-blue-300:hover{--gradient-to-color:#90cdf4}.md\:hover\:to-blue-400:hover{--gradient-to-color:#63b3ed}.md\:hover\:to-blue-500:hover{--gradient-to-color:#4299e1}.md\:hover\:to-blue-600:hover{--gradient-to-color:#3182ce}.md\:hover\:to-blue-700:hover{--gradient-to-color:#2b6cb0}.md\:hover\:to-blue-800:hover{--gradient-to-color:#2c5282}.md\:hover\:to-blue-900:hover{--gradient-to-color:#2a4365}.md\:hover\:to-indigo-100:hover{--gradient-to-color:#ebf4ff}.md\:hover\:to-indigo-200:hover{--gradient-to-color:#c3dafe}.md\:hover\:to-indigo-300:hover{--gradient-to-color:#a3bffa}.md\:hover\:to-indigo-400:hover{--gradient-to-color:#7f9cf5}.md\:hover\:to-indigo-500:hover{--gradient-to-color:#667eea}.md\:hover\:to-indigo-600:hover{--gradient-to-color:#5a67d8}.md\:hover\:to-indigo-700:hover{--gradient-to-color:#4c51bf}.md\:hover\:to-indigo-800:hover{--gradient-to-color:#434190}.md\:hover\:to-indigo-900:hover{--gradient-to-color:#3c366b}.md\:hover\:to-purple-100:hover{--gradient-to-color:#faf5ff}.md\:hover\:to-purple-200:hover{--gradient-to-color:#e9d8fd}.md\:hover\:to-purple-300:hover{--gradient-to-color:#d6bcfa}.md\:hover\:to-purple-400:hover{--gradient-to-color:#b794f4}.md\:hover\:to-purple-500:hover{--gradient-to-color:#9f7aea}.md\:hover\:to-purple-600:hover{--gradient-to-color:#805ad5}.md\:hover\:to-purple-700:hover{--gradient-to-color:#6b46c1}.md\:hover\:to-purple-800:hover{--gradient-to-color:#553c9a}.md\:hover\:to-purple-900:hover{--gradient-to-color:#44337a}.md\:hover\:to-pink-100:hover{--gradient-to-color:#fff5f7}.md\:hover\:to-pink-200:hover{--gradient-to-color:#fed7e2}.md\:hover\:to-pink-300:hover{--gradient-to-color:#fbb6ce}.md\:hover\:to-pink-400:hover{--gradient-to-color:#f687b3}.md\:hover\:to-pink-500:hover{--gradient-to-color:#ed64a6}.md\:hover\:to-pink-600:hover{--gradient-to-color:#d53f8c}.md\:hover\:to-pink-700:hover{--gradient-to-color:#b83280}.md\:hover\:to-pink-800:hover{--gradient-to-color:#97266d}.md\:hover\:to-pink-900:hover{--gradient-to-color:#702459}.md\:focus\:from-transparent:focus{--gradient-from-color:transparent;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(0, 0, 0, 0))}.md\:focus\:from-current:focus{--gradient-from-color:currentColor;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 255, 255, 0))}.md\:focus\:from-black:focus{--gradient-from-color:#000;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(0, 0, 0, 0))}.md\:focus\:from-white:focus{--gradient-from-color:#fff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 255, 255, 0))}.md\:focus\:from-gray-100:focus{--gradient-from-color:#f7fafc;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(247, 250, 252, 0))}.md\:focus\:from-gray-200:focus{--gradient-from-color:#edf2f7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(237, 242, 247, 0))}.md\:focus\:from-gray-300:focus{--gradient-from-color:#e2e8f0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(226, 232, 240, 0))}.md\:focus\:from-gray-400:focus{--gradient-from-color:#cbd5e0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(203, 213, 224, 0))}.md\:focus\:from-gray-500:focus{--gradient-from-color:#a0aec0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(160, 174, 192, 0))}.md\:focus\:from-gray-600:focus{--gradient-from-color:#718096;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(113, 128, 150, 0))}.md\:focus\:from-gray-700:focus{--gradient-from-color:#4a5568;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(74, 85, 104, 0))}.md\:focus\:from-gray-800:focus{--gradient-from-color:#2d3748;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(45, 55, 72, 0))}.md\:focus\:from-gray-900:focus{--gradient-from-color:#1a202c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(26, 32, 44, 0))}.md\:focus\:from-red-100:focus{--gradient-from-color:#fff5f5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 245, 245, 0))}.md\:focus\:from-red-200:focus{--gradient-from-color:#fed7d7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(254, 215, 215, 0))}.md\:focus\:from-red-300:focus{--gradient-from-color:#feb2b2;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(254, 178, 178, 0))}.md\:focus\:from-red-400:focus{--gradient-from-color:#fc8181;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(252, 129, 129, 0))}.md\:focus\:from-red-500:focus{--gradient-from-color:#f56565;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(245, 101, 101, 0))}.md\:focus\:from-red-600:focus{--gradient-from-color:#e53e3e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(229, 62, 62, 0))}.md\:focus\:from-red-700:focus{--gradient-from-color:#c53030;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(197, 48, 48, 0))}.md\:focus\:from-red-800:focus{--gradient-from-color:#9b2c2c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(155, 44, 44, 0))}.md\:focus\:from-red-900:focus{--gradient-from-color:#742a2a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(116, 42, 42, 0))}.md\:focus\:from-orange-100:focus{--gradient-from-color:#fffaf0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 250, 240, 0))}.md\:focus\:from-orange-200:focus{--gradient-from-color:#feebc8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(254, 235, 200, 0))}.md\:focus\:from-orange-300:focus{--gradient-from-color:#fbd38d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(251, 211, 141, 0))}.md\:focus\:from-orange-400:focus{--gradient-from-color:#f6ad55;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(246, 173, 85, 0))}.md\:focus\:from-orange-500:focus{--gradient-from-color:#ed8936;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(237, 137, 54, 0))}.md\:focus\:from-orange-600:focus{--gradient-from-color:#dd6b20;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(221, 107, 32, 0))}.md\:focus\:from-orange-700:focus{--gradient-from-color:#c05621;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(192, 86, 33, 0))}.md\:focus\:from-orange-800:focus{--gradient-from-color:#9c4221;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(156, 66, 33, 0))}.md\:focus\:from-orange-900:focus{--gradient-from-color:#7b341e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(123, 52, 30, 0))}.md\:focus\:from-yellow-100:focus{--gradient-from-color:#fffff0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 255, 240, 0))}.md\:focus\:from-yellow-200:focus{--gradient-from-color:#fefcbf;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(254, 252, 191, 0))}.md\:focus\:from-yellow-300:focus{--gradient-from-color:#faf089;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(250, 240, 137, 0))}.md\:focus\:from-yellow-400:focus{--gradient-from-color:#f6e05e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(246, 224, 94, 0))}.md\:focus\:from-yellow-500:focus{--gradient-from-color:#ecc94b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(236, 201, 75, 0))}.md\:focus\:from-yellow-600:focus{--gradient-from-color:#d69e2e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(214, 158, 46, 0))}.md\:focus\:from-yellow-700:focus{--gradient-from-color:#b7791f;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(183, 121, 31, 0))}.md\:focus\:from-yellow-800:focus{--gradient-from-color:#975a16;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(151, 90, 22, 0))}.md\:focus\:from-yellow-900:focus{--gradient-from-color:#744210;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(116, 66, 16, 0))}.md\:focus\:from-green-100:focus{--gradient-from-color:#f0fff4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(240, 255, 244, 0))}.md\:focus\:from-green-200:focus{--gradient-from-color:#c6f6d5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(198, 246, 213, 0))}.md\:focus\:from-green-300:focus{--gradient-from-color:#9ae6b4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(154, 230, 180, 0))}.md\:focus\:from-green-400:focus{--gradient-from-color:#68d391;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(104, 211, 145, 0))}.md\:focus\:from-green-500:focus{--gradient-from-color:#48bb78;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(72, 187, 120, 0))}.md\:focus\:from-green-600:focus{--gradient-from-color:#38a169;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(56, 161, 105, 0))}.md\:focus\:from-green-700:focus{--gradient-from-color:#2f855a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(47, 133, 90, 0))}.md\:focus\:from-green-800:focus{--gradient-from-color:#276749;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(39, 103, 73, 0))}.md\:focus\:from-green-900:focus{--gradient-from-color:#22543d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(34, 84, 61, 0))}.md\:focus\:from-teal-100:focus{--gradient-from-color:#e6fffa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(230, 255, 250, 0))}.md\:focus\:from-teal-200:focus{--gradient-from-color:#b2f5ea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(178, 245, 234, 0))}.md\:focus\:from-teal-300:focus{--gradient-from-color:#81e6d9;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(129, 230, 217, 0))}.md\:focus\:from-teal-400:focus{--gradient-from-color:#4fd1c5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(79, 209, 197, 0))}.md\:focus\:from-teal-500:focus{--gradient-from-color:#38b2ac;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(56, 178, 172, 0))}.md\:focus\:from-teal-600:focus{--gradient-from-color:#319795;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(49, 151, 149, 0))}.md\:focus\:from-teal-700:focus{--gradient-from-color:#2c7a7b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(44, 122, 123, 0))}.md\:focus\:from-teal-800:focus{--gradient-from-color:#285e61;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(40, 94, 97, 0))}.md\:focus\:from-teal-900:focus{--gradient-from-color:#234e52;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(35, 78, 82, 0))}.md\:focus\:from-blue-100:focus{--gradient-from-color:#ebf8ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(235, 248, 255, 0))}.md\:focus\:from-blue-200:focus{--gradient-from-color:#bee3f8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(190, 227, 248, 0))}.md\:focus\:from-blue-300:focus{--gradient-from-color:#90cdf4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(144, 205, 244, 0))}.md\:focus\:from-blue-400:focus{--gradient-from-color:#63b3ed;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(99, 179, 237, 0))}.md\:focus\:from-blue-500:focus{--gradient-from-color:#4299e1;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(66, 153, 225, 0))}.md\:focus\:from-blue-600:focus{--gradient-from-color:#3182ce;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(49, 130, 206, 0))}.md\:focus\:from-blue-700:focus{--gradient-from-color:#2b6cb0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(43, 108, 176, 0))}.md\:focus\:from-blue-800:focus{--gradient-from-color:#2c5282;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(44, 82, 130, 0))}.md\:focus\:from-blue-900:focus{--gradient-from-color:#2a4365;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(42, 67, 101, 0))}.md\:focus\:from-indigo-100:focus{--gradient-from-color:#ebf4ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(235, 244, 255, 0))}.md\:focus\:from-indigo-200:focus{--gradient-from-color:#c3dafe;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(195, 218, 254, 0))}.md\:focus\:from-indigo-300:focus{--gradient-from-color:#a3bffa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(163, 191, 250, 0))}.md\:focus\:from-indigo-400:focus{--gradient-from-color:#7f9cf5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(127, 156, 245, 0))}.md\:focus\:from-indigo-500:focus{--gradient-from-color:#667eea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(102, 126, 234, 0))}.md\:focus\:from-indigo-600:focus{--gradient-from-color:#5a67d8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(90, 103, 216, 0))}.md\:focus\:from-indigo-700:focus{--gradient-from-color:#4c51bf;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(76, 81, 191, 0))}.md\:focus\:from-indigo-800:focus{--gradient-from-color:#434190;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(67, 65, 144, 0))}.md\:focus\:from-indigo-900:focus{--gradient-from-color:#3c366b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(60, 54, 107, 0))}.md\:focus\:from-purple-100:focus{--gradient-from-color:#faf5ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(250, 245, 255, 0))}.md\:focus\:from-purple-200:focus{--gradient-from-color:#e9d8fd;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(233, 216, 253, 0))}.md\:focus\:from-purple-300:focus{--gradient-from-color:#d6bcfa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(214, 188, 250, 0))}.md\:focus\:from-purple-400:focus{--gradient-from-color:#b794f4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(183, 148, 244, 0))}.md\:focus\:from-purple-500:focus{--gradient-from-color:#9f7aea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(159, 122, 234, 0))}.md\:focus\:from-purple-600:focus{--gradient-from-color:#805ad5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(128, 90, 213, 0))}.md\:focus\:from-purple-700:focus{--gradient-from-color:#6b46c1;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(107, 70, 193, 0))}.md\:focus\:from-purple-800:focus{--gradient-from-color:#553c9a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(85, 60, 154, 0))}.md\:focus\:from-purple-900:focus{--gradient-from-color:#44337a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(68, 51, 122, 0))}.md\:focus\:from-pink-100:focus{--gradient-from-color:#fff5f7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 245, 247, 0))}.md\:focus\:from-pink-200:focus{--gradient-from-color:#fed7e2;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(254, 215, 226, 0))}.md\:focus\:from-pink-300:focus{--gradient-from-color:#fbb6ce;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(251, 182, 206, 0))}.md\:focus\:from-pink-400:focus{--gradient-from-color:#f687b3;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(246, 135, 179, 0))}.md\:focus\:from-pink-500:focus{--gradient-from-color:#ed64a6;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(237, 100, 166, 0))}.md\:focus\:from-pink-600:focus{--gradient-from-color:#d53f8c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(213, 63, 140, 0))}.md\:focus\:from-pink-700:focus{--gradient-from-color:#b83280;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(184, 50, 128, 0))}.md\:focus\:from-pink-800:focus{--gradient-from-color:#97266d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(151, 38, 109, 0))}.md\:focus\:from-pink-900:focus{--gradient-from-color:#702459;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(112, 36, 89, 0))}.md\:focus\:via-transparent:focus{--gradient-via-color:transparent;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(0, 0, 0, 0))}.md\:focus\:via-current:focus{--gradient-via-color:currentColor;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 255, 255, 0))}.md\:focus\:via-black:focus{--gradient-via-color:#000;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(0, 0, 0, 0))}.md\:focus\:via-white:focus{--gradient-via-color:#fff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 255, 255, 0))}.md\:focus\:via-gray-100:focus{--gradient-via-color:#f7fafc;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(247, 250, 252, 0))}.md\:focus\:via-gray-200:focus{--gradient-via-color:#edf2f7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(237, 242, 247, 0))}.md\:focus\:via-gray-300:focus{--gradient-via-color:#e2e8f0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(226, 232, 240, 0))}.md\:focus\:via-gray-400:focus{--gradient-via-color:#cbd5e0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(203, 213, 224, 0))}.md\:focus\:via-gray-500:focus{--gradient-via-color:#a0aec0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(160, 174, 192, 0))}.md\:focus\:via-gray-600:focus{--gradient-via-color:#718096;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(113, 128, 150, 0))}.md\:focus\:via-gray-700:focus{--gradient-via-color:#4a5568;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(74, 85, 104, 0))}.md\:focus\:via-gray-800:focus{--gradient-via-color:#2d3748;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(45, 55, 72, 0))}.md\:focus\:via-gray-900:focus{--gradient-via-color:#1a202c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(26, 32, 44, 0))}.md\:focus\:via-red-100:focus{--gradient-via-color:#fff5f5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 245, 245, 0))}.md\:focus\:via-red-200:focus{--gradient-via-color:#fed7d7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(254, 215, 215, 0))}.md\:focus\:via-red-300:focus{--gradient-via-color:#feb2b2;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(254, 178, 178, 0))}.md\:focus\:via-red-400:focus{--gradient-via-color:#fc8181;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(252, 129, 129, 0))}.md\:focus\:via-red-500:focus{--gradient-via-color:#f56565;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(245, 101, 101, 0))}.md\:focus\:via-red-600:focus{--gradient-via-color:#e53e3e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(229, 62, 62, 0))}.md\:focus\:via-red-700:focus{--gradient-via-color:#c53030;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(197, 48, 48, 0))}.md\:focus\:via-red-800:focus{--gradient-via-color:#9b2c2c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(155, 44, 44, 0))}.md\:focus\:via-red-900:focus{--gradient-via-color:#742a2a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(116, 42, 42, 0))}.md\:focus\:via-orange-100:focus{--gradient-via-color:#fffaf0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 250, 240, 0))}.md\:focus\:via-orange-200:focus{--gradient-via-color:#feebc8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(254, 235, 200, 0))}.md\:focus\:via-orange-300:focus{--gradient-via-color:#fbd38d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(251, 211, 141, 0))}.md\:focus\:via-orange-400:focus{--gradient-via-color:#f6ad55;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(246, 173, 85, 0))}.md\:focus\:via-orange-500:focus{--gradient-via-color:#ed8936;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(237, 137, 54, 0))}.md\:focus\:via-orange-600:focus{--gradient-via-color:#dd6b20;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(221, 107, 32, 0))}.md\:focus\:via-orange-700:focus{--gradient-via-color:#c05621;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(192, 86, 33, 0))}.md\:focus\:via-orange-800:focus{--gradient-via-color:#9c4221;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(156, 66, 33, 0))}.md\:focus\:via-orange-900:focus{--gradient-via-color:#7b341e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(123, 52, 30, 0))}.md\:focus\:via-yellow-100:focus{--gradient-via-color:#fffff0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 255, 240, 0))}.md\:focus\:via-yellow-200:focus{--gradient-via-color:#fefcbf;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(254, 252, 191, 0))}.md\:focus\:via-yellow-300:focus{--gradient-via-color:#faf089;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(250, 240, 137, 0))}.md\:focus\:via-yellow-400:focus{--gradient-via-color:#f6e05e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(246, 224, 94, 0))}.md\:focus\:via-yellow-500:focus{--gradient-via-color:#ecc94b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(236, 201, 75, 0))}.md\:focus\:via-yellow-600:focus{--gradient-via-color:#d69e2e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(214, 158, 46, 0))}.md\:focus\:via-yellow-700:focus{--gradient-via-color:#b7791f;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(183, 121, 31, 0))}.md\:focus\:via-yellow-800:focus{--gradient-via-color:#975a16;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(151, 90, 22, 0))}.md\:focus\:via-yellow-900:focus{--gradient-via-color:#744210;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(116, 66, 16, 0))}.md\:focus\:via-green-100:focus{--gradient-via-color:#f0fff4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(240, 255, 244, 0))}.md\:focus\:via-green-200:focus{--gradient-via-color:#c6f6d5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(198, 246, 213, 0))}.md\:focus\:via-green-300:focus{--gradient-via-color:#9ae6b4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(154, 230, 180, 0))}.md\:focus\:via-green-400:focus{--gradient-via-color:#68d391;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(104, 211, 145, 0))}.md\:focus\:via-green-500:focus{--gradient-via-color:#48bb78;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(72, 187, 120, 0))}.md\:focus\:via-green-600:focus{--gradient-via-color:#38a169;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(56, 161, 105, 0))}.md\:focus\:via-green-700:focus{--gradient-via-color:#2f855a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(47, 133, 90, 0))}.md\:focus\:via-green-800:focus{--gradient-via-color:#276749;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(39, 103, 73, 0))}.md\:focus\:via-green-900:focus{--gradient-via-color:#22543d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(34, 84, 61, 0))}.md\:focus\:via-teal-100:focus{--gradient-via-color:#e6fffa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(230, 255, 250, 0))}.md\:focus\:via-teal-200:focus{--gradient-via-color:#b2f5ea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(178, 245, 234, 0))}.md\:focus\:via-teal-300:focus{--gradient-via-color:#81e6d9;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(129, 230, 217, 0))}.md\:focus\:via-teal-400:focus{--gradient-via-color:#4fd1c5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(79, 209, 197, 0))}.md\:focus\:via-teal-500:focus{--gradient-via-color:#38b2ac;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(56, 178, 172, 0))}.md\:focus\:via-teal-600:focus{--gradient-via-color:#319795;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(49, 151, 149, 0))}.md\:focus\:via-teal-700:focus{--gradient-via-color:#2c7a7b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(44, 122, 123, 0))}.md\:focus\:via-teal-800:focus{--gradient-via-color:#285e61;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(40, 94, 97, 0))}.md\:focus\:via-teal-900:focus{--gradient-via-color:#234e52;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(35, 78, 82, 0))}.md\:focus\:via-blue-100:focus{--gradient-via-color:#ebf8ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(235, 248, 255, 0))}.md\:focus\:via-blue-200:focus{--gradient-via-color:#bee3f8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(190, 227, 248, 0))}.md\:focus\:via-blue-300:focus{--gradient-via-color:#90cdf4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(144, 205, 244, 0))}.md\:focus\:via-blue-400:focus{--gradient-via-color:#63b3ed;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(99, 179, 237, 0))}.md\:focus\:via-blue-500:focus{--gradient-via-color:#4299e1;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(66, 153, 225, 0))}.md\:focus\:via-blue-600:focus{--gradient-via-color:#3182ce;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(49, 130, 206, 0))}.md\:focus\:via-blue-700:focus{--gradient-via-color:#2b6cb0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(43, 108, 176, 0))}.md\:focus\:via-blue-800:focus{--gradient-via-color:#2c5282;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(44, 82, 130, 0))}.md\:focus\:via-blue-900:focus{--gradient-via-color:#2a4365;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(42, 67, 101, 0))}.md\:focus\:via-indigo-100:focus{--gradient-via-color:#ebf4ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(235, 244, 255, 0))}.md\:focus\:via-indigo-200:focus{--gradient-via-color:#c3dafe;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(195, 218, 254, 0))}.md\:focus\:via-indigo-300:focus{--gradient-via-color:#a3bffa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(163, 191, 250, 0))}.md\:focus\:via-indigo-400:focus{--gradient-via-color:#7f9cf5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(127, 156, 245, 0))}.md\:focus\:via-indigo-500:focus{--gradient-via-color:#667eea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(102, 126, 234, 0))}.md\:focus\:via-indigo-600:focus{--gradient-via-color:#5a67d8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(90, 103, 216, 0))}.md\:focus\:via-indigo-700:focus{--gradient-via-color:#4c51bf;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(76, 81, 191, 0))}.md\:focus\:via-indigo-800:focus{--gradient-via-color:#434190;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(67, 65, 144, 0))}.md\:focus\:via-indigo-900:focus{--gradient-via-color:#3c366b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(60, 54, 107, 0))}.md\:focus\:via-purple-100:focus{--gradient-via-color:#faf5ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(250, 245, 255, 0))}.md\:focus\:via-purple-200:focus{--gradient-via-color:#e9d8fd;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(233, 216, 253, 0))}.md\:focus\:via-purple-300:focus{--gradient-via-color:#d6bcfa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(214, 188, 250, 0))}.md\:focus\:via-purple-400:focus{--gradient-via-color:#b794f4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(183, 148, 244, 0))}.md\:focus\:via-purple-500:focus{--gradient-via-color:#9f7aea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(159, 122, 234, 0))}.md\:focus\:via-purple-600:focus{--gradient-via-color:#805ad5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(128, 90, 213, 0))}.md\:focus\:via-purple-700:focus{--gradient-via-color:#6b46c1;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(107, 70, 193, 0))}.md\:focus\:via-purple-800:focus{--gradient-via-color:#553c9a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(85, 60, 154, 0))}.md\:focus\:via-purple-900:focus{--gradient-via-color:#44337a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(68, 51, 122, 0))}.md\:focus\:via-pink-100:focus{--gradient-via-color:#fff5f7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 245, 247, 0))}.md\:focus\:via-pink-200:focus{--gradient-via-color:#fed7e2;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(254, 215, 226, 0))}.md\:focus\:via-pink-300:focus{--gradient-via-color:#fbb6ce;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(251, 182, 206, 0))}.md\:focus\:via-pink-400:focus{--gradient-via-color:#f687b3;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(246, 135, 179, 0))}.md\:focus\:via-pink-500:focus{--gradient-via-color:#ed64a6;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(237, 100, 166, 0))}.md\:focus\:via-pink-600:focus{--gradient-via-color:#d53f8c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(213, 63, 140, 0))}.md\:focus\:via-pink-700:focus{--gradient-via-color:#b83280;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(184, 50, 128, 0))}.md\:focus\:via-pink-800:focus{--gradient-via-color:#97266d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(151, 38, 109, 0))}.md\:focus\:via-pink-900:focus{--gradient-via-color:#702459;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(112, 36, 89, 0))}.md\:focus\:to-transparent:focus{--gradient-to-color:transparent}.md\:focus\:to-current:focus{--gradient-to-color:currentColor}.md\:focus\:to-black:focus{--gradient-to-color:#000}.md\:focus\:to-white:focus{--gradient-to-color:#fff}.md\:focus\:to-gray-100:focus{--gradient-to-color:#f7fafc}.md\:focus\:to-gray-200:focus{--gradient-to-color:#edf2f7}.md\:focus\:to-gray-300:focus{--gradient-to-color:#e2e8f0}.md\:focus\:to-gray-400:focus{--gradient-to-color:#cbd5e0}.md\:focus\:to-gray-500:focus{--gradient-to-color:#a0aec0}.md\:focus\:to-gray-600:focus{--gradient-to-color:#718096}.md\:focus\:to-gray-700:focus{--gradient-to-color:#4a5568}.md\:focus\:to-gray-800:focus{--gradient-to-color:#2d3748}.md\:focus\:to-gray-900:focus{--gradient-to-color:#1a202c}.md\:focus\:to-red-100:focus{--gradient-to-color:#fff5f5}.md\:focus\:to-red-200:focus{--gradient-to-color:#fed7d7}.md\:focus\:to-red-300:focus{--gradient-to-color:#feb2b2}.md\:focus\:to-red-400:focus{--gradient-to-color:#fc8181}.md\:focus\:to-red-500:focus{--gradient-to-color:#f56565}.md\:focus\:to-red-600:focus{--gradient-to-color:#e53e3e}.md\:focus\:to-red-700:focus{--gradient-to-color:#c53030}.md\:focus\:to-red-800:focus{--gradient-to-color:#9b2c2c}.md\:focus\:to-red-900:focus{--gradient-to-color:#742a2a}.md\:focus\:to-orange-100:focus{--gradient-to-color:#fffaf0}.md\:focus\:to-orange-200:focus{--gradient-to-color:#feebc8}.md\:focus\:to-orange-300:focus{--gradient-to-color:#fbd38d}.md\:focus\:to-orange-400:focus{--gradient-to-color:#f6ad55}.md\:focus\:to-orange-500:focus{--gradient-to-color:#ed8936}.md\:focus\:to-orange-600:focus{--gradient-to-color:#dd6b20}.md\:focus\:to-orange-700:focus{--gradient-to-color:#c05621}.md\:focus\:to-orange-800:focus{--gradient-to-color:#9c4221}.md\:focus\:to-orange-900:focus{--gradient-to-color:#7b341e}.md\:focus\:to-yellow-100:focus{--gradient-to-color:#fffff0}.md\:focus\:to-yellow-200:focus{--gradient-to-color:#fefcbf}.md\:focus\:to-yellow-300:focus{--gradient-to-color:#faf089}.md\:focus\:to-yellow-400:focus{--gradient-to-color:#f6e05e}.md\:focus\:to-yellow-500:focus{--gradient-to-color:#ecc94b}.md\:focus\:to-yellow-600:focus{--gradient-to-color:#d69e2e}.md\:focus\:to-yellow-700:focus{--gradient-to-color:#b7791f}.md\:focus\:to-yellow-800:focus{--gradient-to-color:#975a16}.md\:focus\:to-yellow-900:focus{--gradient-to-color:#744210}.md\:focus\:to-green-100:focus{--gradient-to-color:#f0fff4}.md\:focus\:to-green-200:focus{--gradient-to-color:#c6f6d5}.md\:focus\:to-green-300:focus{--gradient-to-color:#9ae6b4}.md\:focus\:to-green-400:focus{--gradient-to-color:#68d391}.md\:focus\:to-green-500:focus{--gradient-to-color:#48bb78}.md\:focus\:to-green-600:focus{--gradient-to-color:#38a169}.md\:focus\:to-green-700:focus{--gradient-to-color:#2f855a}.md\:focus\:to-green-800:focus{--gradient-to-color:#276749}.md\:focus\:to-green-900:focus{--gradient-to-color:#22543d}.md\:focus\:to-teal-100:focus{--gradient-to-color:#e6fffa}.md\:focus\:to-teal-200:focus{--gradient-to-color:#b2f5ea}.md\:focus\:to-teal-300:focus{--gradient-to-color:#81e6d9}.md\:focus\:to-teal-400:focus{--gradient-to-color:#4fd1c5}.md\:focus\:to-teal-500:focus{--gradient-to-color:#38b2ac}.md\:focus\:to-teal-600:focus{--gradient-to-color:#319795}.md\:focus\:to-teal-700:focus{--gradient-to-color:#2c7a7b}.md\:focus\:to-teal-800:focus{--gradient-to-color:#285e61}.md\:focus\:to-teal-900:focus{--gradient-to-color:#234e52}.md\:focus\:to-blue-100:focus{--gradient-to-color:#ebf8ff}.md\:focus\:to-blue-200:focus{--gradient-to-color:#bee3f8}.md\:focus\:to-blue-300:focus{--gradient-to-color:#90cdf4}.md\:focus\:to-blue-400:focus{--gradient-to-color:#63b3ed}.md\:focus\:to-blue-500:focus{--gradient-to-color:#4299e1}.md\:focus\:to-blue-600:focus{--gradient-to-color:#3182ce}.md\:focus\:to-blue-700:focus{--gradient-to-color:#2b6cb0}.md\:focus\:to-blue-800:focus{--gradient-to-color:#2c5282}.md\:focus\:to-blue-900:focus{--gradient-to-color:#2a4365}.md\:focus\:to-indigo-100:focus{--gradient-to-color:#ebf4ff}.md\:focus\:to-indigo-200:focus{--gradient-to-color:#c3dafe}.md\:focus\:to-indigo-300:focus{--gradient-to-color:#a3bffa}.md\:focus\:to-indigo-400:focus{--gradient-to-color:#7f9cf5}.md\:focus\:to-indigo-500:focus{--gradient-to-color:#667eea}.md\:focus\:to-indigo-600:focus{--gradient-to-color:#5a67d8}.md\:focus\:to-indigo-700:focus{--gradient-to-color:#4c51bf}.md\:focus\:to-indigo-800:focus{--gradient-to-color:#434190}.md\:focus\:to-indigo-900:focus{--gradient-to-color:#3c366b}.md\:focus\:to-purple-100:focus{--gradient-to-color:#faf5ff}.md\:focus\:to-purple-200:focus{--gradient-to-color:#e9d8fd}.md\:focus\:to-purple-300:focus{--gradient-to-color:#d6bcfa}.md\:focus\:to-purple-400:focus{--gradient-to-color:#b794f4}.md\:focus\:to-purple-500:focus{--gradient-to-color:#9f7aea}.md\:focus\:to-purple-600:focus{--gradient-to-color:#805ad5}.md\:focus\:to-purple-700:focus{--gradient-to-color:#6b46c1}.md\:focus\:to-purple-800:focus{--gradient-to-color:#553c9a}.md\:focus\:to-purple-900:focus{--gradient-to-color:#44337a}.md\:focus\:to-pink-100:focus{--gradient-to-color:#fff5f7}.md\:focus\:to-pink-200:focus{--gradient-to-color:#fed7e2}.md\:focus\:to-pink-300:focus{--gradient-to-color:#fbb6ce}.md\:focus\:to-pink-400:focus{--gradient-to-color:#f687b3}.md\:focus\:to-pink-500:focus{--gradient-to-color:#ed64a6}.md\:focus\:to-pink-600:focus{--gradient-to-color:#d53f8c}.md\:focus\:to-pink-700:focus{--gradient-to-color:#b83280}.md\:focus\:to-pink-800:focus{--gradient-to-color:#97266d}.md\:focus\:to-pink-900:focus{--gradient-to-color:#702459}.md\:bg-opacity-0{--bg-opacity:0}.md\:bg-opacity-25{--bg-opacity:0.25}.md\:bg-opacity-50{--bg-opacity:0.5}.md\:bg-opacity-75{--bg-opacity:0.75}.md\:bg-opacity-100{--bg-opacity:1}.md\:hover\:bg-opacity-0:hover{--bg-opacity:0}.md\:hover\:bg-opacity-25:hover{--bg-opacity:0.25}.md\:hover\:bg-opacity-50:hover{--bg-opacity:0.5}.md\:hover\:bg-opacity-75:hover{--bg-opacity:0.75}.md\:hover\:bg-opacity-100:hover{--bg-opacity:1}.md\:focus\:bg-opacity-0:focus{--bg-opacity:0}.md\:focus\:bg-opacity-25:focus{--bg-opacity:0.25}.md\:focus\:bg-opacity-50:focus{--bg-opacity:0.5}.md\:focus\:bg-opacity-75:focus{--bg-opacity:0.75}.md\:focus\:bg-opacity-100:focus{--bg-opacity:1}.md\:bg-bottom{background-position:bottom}.md\:bg-center{background-position:center}.md\:bg-left{background-position:left}.md\:bg-left-bottom{background-position:left bottom}.md\:bg-left-top{background-position:left top}.md\:bg-right{background-position:right}.md\:bg-right-bottom{background-position:right bottom}.md\:bg-right-top{background-position:right top}.md\:bg-top{background-position:top}.md\:bg-repeat{background-repeat:repeat}.md\:bg-no-repeat{background-repeat:no-repeat}.md\:bg-repeat-x{background-repeat:repeat-x}.md\:bg-repeat-y{background-repeat:repeat-y}.md\:bg-repeat-round{background-repeat:round}.md\:bg-repeat-space{background-repeat:space}.md\:bg-auto{background-size:auto}.md\:bg-cover{background-size:cover}.md\:bg-contain{background-size:contain}.md\:border-collapse{border-collapse:collapse}.md\:border-separate{border-collapse:separate}.md\:border-transparent{border-color:transparent}.md\:border-current{border-color:currentColor}.md\:border-black{--border-opacity:1;border-color:#000;border-color:rgba(0,0,0,var(--border-opacity))}.md\:border-white{--border-opacity:1;border-color:#fff;border-color:rgba(255,255,255,var(--border-opacity))}.md\:border-gray-100{--border-opacity:1;border-color:#f7fafc;border-color:rgba(247,250,252,var(--border-opacity))}.md\:border-gray-200{--border-opacity:1;border-color:#edf2f7;border-color:rgba(237,242,247,var(--border-opacity))}.md\:border-gray-300{--border-opacity:1;border-color:#e2e8f0;border-color:rgba(226,232,240,var(--border-opacity))}.md\:border-gray-400{--border-opacity:1;border-color:#cbd5e0;border-color:rgba(203,213,224,var(--border-opacity))}.md\:border-gray-500{--border-opacity:1;border-color:#a0aec0;border-color:rgba(160,174,192,var(--border-opacity))}.md\:border-gray-600{--border-opacity:1;border-color:#718096;border-color:rgba(113,128,150,var(--border-opacity))}.md\:border-gray-700{--border-opacity:1;border-color:#4a5568;border-color:rgba(74,85,104,var(--border-opacity))}.md\:border-gray-800{--border-opacity:1;border-color:#2d3748;border-color:rgba(45,55,72,var(--border-opacity))}.md\:border-gray-900{--border-opacity:1;border-color:#1a202c;border-color:rgba(26,32,44,var(--border-opacity))}.md\:border-red-100{--border-opacity:1;border-color:#fff5f5;border-color:rgba(255,245,245,var(--border-opacity))}.md\:border-red-200{--border-opacity:1;border-color:#fed7d7;border-color:rgba(254,215,215,var(--border-opacity))}.md\:border-red-300{--border-opacity:1;border-color:#feb2b2;border-color:rgba(254,178,178,var(--border-opacity))}.md\:border-red-400{--border-opacity:1;border-color:#fc8181;border-color:rgba(252,129,129,var(--border-opacity))}.md\:border-red-500{--border-opacity:1;border-color:#f56565;border-color:rgba(245,101,101,var(--border-opacity))}.md\:border-red-600{--border-opacity:1;border-color:#e53e3e;border-color:rgba(229,62,62,var(--border-opacity))}.md\:border-red-700{--border-opacity:1;border-color:#c53030;border-color:rgba(197,48,48,var(--border-opacity))}.md\:border-red-800{--border-opacity:1;border-color:#9b2c2c;border-color:rgba(155,44,44,var(--border-opacity))}.md\:border-red-900{--border-opacity:1;border-color:#742a2a;border-color:rgba(116,42,42,var(--border-opacity))}.md\:border-orange-100{--border-opacity:1;border-color:#fffaf0;border-color:rgba(255,250,240,var(--border-opacity))}.md\:border-orange-200{--border-opacity:1;border-color:#feebc8;border-color:rgba(254,235,200,var(--border-opacity))}.md\:border-orange-300{--border-opacity:1;border-color:#fbd38d;border-color:rgba(251,211,141,var(--border-opacity))}.md\:border-orange-400{--border-opacity:1;border-color:#f6ad55;border-color:rgba(246,173,85,var(--border-opacity))}.md\:border-orange-500{--border-opacity:1;border-color:#ed8936;border-color:rgba(237,137,54,var(--border-opacity))}.md\:border-orange-600{--border-opacity:1;border-color:#dd6b20;border-color:rgba(221,107,32,var(--border-opacity))}.md\:border-orange-700{--border-opacity:1;border-color:#c05621;border-color:rgba(192,86,33,var(--border-opacity))}.md\:border-orange-800{--border-opacity:1;border-color:#9c4221;border-color:rgba(156,66,33,var(--border-opacity))}.md\:border-orange-900{--border-opacity:1;border-color:#7b341e;border-color:rgba(123,52,30,var(--border-opacity))}.md\:border-yellow-100{--border-opacity:1;border-color:ivory;border-color:rgba(255,255,240,var(--border-opacity))}.md\:border-yellow-200{--border-opacity:1;border-color:#fefcbf;border-color:rgba(254,252,191,var(--border-opacity))}.md\:border-yellow-300{--border-opacity:1;border-color:#faf089;border-color:rgba(250,240,137,var(--border-opacity))}.md\:border-yellow-400{--border-opacity:1;border-color:#f6e05e;border-color:rgba(246,224,94,var(--border-opacity))}.md\:border-yellow-500{--border-opacity:1;border-color:#ecc94b;border-color:rgba(236,201,75,var(--border-opacity))}.md\:border-yellow-600{--border-opacity:1;border-color:#d69e2e;border-color:rgba(214,158,46,var(--border-opacity))}.md\:border-yellow-700{--border-opacity:1;border-color:#b7791f;border-color:rgba(183,121,31,var(--border-opacity))}.md\:border-yellow-800{--border-opacity:1;border-color:#975a16;border-color:rgba(151,90,22,var(--border-opacity))}.md\:border-yellow-900{--border-opacity:1;border-color:#744210;border-color:rgba(116,66,16,var(--border-opacity))}.md\:border-green-100{--border-opacity:1;border-color:#f0fff4;border-color:rgba(240,255,244,var(--border-opacity))}.md\:border-green-200{--border-opacity:1;border-color:#c6f6d5;border-color:rgba(198,246,213,var(--border-opacity))}.md\:border-green-300{--border-opacity:1;border-color:#9ae6b4;border-color:rgba(154,230,180,var(--border-opacity))}.md\:border-green-400{--border-opacity:1;border-color:#68d391;border-color:rgba(104,211,145,var(--border-opacity))}.md\:border-green-500{--border-opacity:1;border-color:#48bb78;border-color:rgba(72,187,120,var(--border-opacity))}.md\:border-green-600{--border-opacity:1;border-color:#38a169;border-color:rgba(56,161,105,var(--border-opacity))}.md\:border-green-700{--border-opacity:1;border-color:#2f855a;border-color:rgba(47,133,90,var(--border-opacity))}.md\:border-green-800{--border-opacity:1;border-color:#276749;border-color:rgba(39,103,73,var(--border-opacity))}.md\:border-green-900{--border-opacity:1;border-color:#22543d;border-color:rgba(34,84,61,var(--border-opacity))}.md\:border-teal-100{--border-opacity:1;border-color:#e6fffa;border-color:rgba(230,255,250,var(--border-opacity))}.md\:border-teal-200{--border-opacity:1;border-color:#b2f5ea;border-color:rgba(178,245,234,var(--border-opacity))}.md\:border-teal-300{--border-opacity:1;border-color:#81e6d9;border-color:rgba(129,230,217,var(--border-opacity))}.md\:border-teal-400{--border-opacity:1;border-color:#4fd1c5;border-color:rgba(79,209,197,var(--border-opacity))}.md\:border-teal-500{--border-opacity:1;border-color:#38b2ac;border-color:rgba(56,178,172,var(--border-opacity))}.md\:border-teal-600{--border-opacity:1;border-color:#319795;border-color:rgba(49,151,149,var(--border-opacity))}.md\:border-teal-700{--border-opacity:1;border-color:#2c7a7b;border-color:rgba(44,122,123,var(--border-opacity))}.md\:border-teal-800{--border-opacity:1;border-color:#285e61;border-color:rgba(40,94,97,var(--border-opacity))}.md\:border-teal-900{--border-opacity:1;border-color:#234e52;border-color:rgba(35,78,82,var(--border-opacity))}.md\:border-blue-100{--border-opacity:1;border-color:#ebf8ff;border-color:rgba(235,248,255,var(--border-opacity))}.md\:border-blue-200{--border-opacity:1;border-color:#bee3f8;border-color:rgba(190,227,248,var(--border-opacity))}.md\:border-blue-300{--border-opacity:1;border-color:#90cdf4;border-color:rgba(144,205,244,var(--border-opacity))}.md\:border-blue-400{--border-opacity:1;border-color:#63b3ed;border-color:rgba(99,179,237,var(--border-opacity))}.md\:border-blue-500{--border-opacity:1;border-color:#4299e1;border-color:rgba(66,153,225,var(--border-opacity))}.md\:border-blue-600{--border-opacity:1;border-color:#3182ce;border-color:rgba(49,130,206,var(--border-opacity))}.md\:border-blue-700{--border-opacity:1;border-color:#2b6cb0;border-color:rgba(43,108,176,var(--border-opacity))}.md\:border-blue-800{--border-opacity:1;border-color:#2c5282;border-color:rgba(44,82,130,var(--border-opacity))}.md\:border-blue-900{--border-opacity:1;border-color:#2a4365;border-color:rgba(42,67,101,var(--border-opacity))}.md\:border-indigo-100{--border-opacity:1;border-color:#ebf4ff;border-color:rgba(235,244,255,var(--border-opacity))}.md\:border-indigo-200{--border-opacity:1;border-color:#c3dafe;border-color:rgba(195,218,254,var(--border-opacity))}.md\:border-indigo-300{--border-opacity:1;border-color:#a3bffa;border-color:rgba(163,191,250,var(--border-opacity))}.md\:border-indigo-400{--border-opacity:1;border-color:#7f9cf5;border-color:rgba(127,156,245,var(--border-opacity))}.md\:border-indigo-500{--border-opacity:1;border-color:#667eea;border-color:rgba(102,126,234,var(--border-opacity))}.md\:border-indigo-600{--border-opacity:1;border-color:#5a67d8;border-color:rgba(90,103,216,var(--border-opacity))}.md\:border-indigo-700{--border-opacity:1;border-color:#4c51bf;border-color:rgba(76,81,191,var(--border-opacity))}.md\:border-indigo-800{--border-opacity:1;border-color:#434190;border-color:rgba(67,65,144,var(--border-opacity))}.md\:border-indigo-900{--border-opacity:1;border-color:#3c366b;border-color:rgba(60,54,107,var(--border-opacity))}.md\:border-purple-100{--border-opacity:1;border-color:#faf5ff;border-color:rgba(250,245,255,var(--border-opacity))}.md\:border-purple-200{--border-opacity:1;border-color:#e9d8fd;border-color:rgba(233,216,253,var(--border-opacity))}.md\:border-purple-300{--border-opacity:1;border-color:#d6bcfa;border-color:rgba(214,188,250,var(--border-opacity))}.md\:border-purple-400{--border-opacity:1;border-color:#b794f4;border-color:rgba(183,148,244,var(--border-opacity))}.md\:border-purple-500{--border-opacity:1;border-color:#9f7aea;border-color:rgba(159,122,234,var(--border-opacity))}.md\:border-purple-600{--border-opacity:1;border-color:#805ad5;border-color:rgba(128,90,213,var(--border-opacity))}.md\:border-purple-700{--border-opacity:1;border-color:#6b46c1;border-color:rgba(107,70,193,var(--border-opacity))}.md\:border-purple-800{--border-opacity:1;border-color:#553c9a;border-color:rgba(85,60,154,var(--border-opacity))}.md\:border-purple-900{--border-opacity:1;border-color:#44337a;border-color:rgba(68,51,122,var(--border-opacity))}.md\:border-pink-100{--border-opacity:1;border-color:#fff5f7;border-color:rgba(255,245,247,var(--border-opacity))}.md\:border-pink-200{--border-opacity:1;border-color:#fed7e2;border-color:rgba(254,215,226,var(--border-opacity))}.md\:border-pink-300{--border-opacity:1;border-color:#fbb6ce;border-color:rgba(251,182,206,var(--border-opacity))}.md\:border-pink-400{--border-opacity:1;border-color:#f687b3;border-color:rgba(246,135,179,var(--border-opacity))}.md\:border-pink-500{--border-opacity:1;border-color:#ed64a6;border-color:rgba(237,100,166,var(--border-opacity))}.md\:border-pink-600{--border-opacity:1;border-color:#d53f8c;border-color:rgba(213,63,140,var(--border-opacity))}.md\:border-pink-700{--border-opacity:1;border-color:#b83280;border-color:rgba(184,50,128,var(--border-opacity))}.md\:border-pink-800{--border-opacity:1;border-color:#97266d;border-color:rgba(151,38,109,var(--border-opacity))}.md\:border-pink-900{--border-opacity:1;border-color:#702459;border-color:rgba(112,36,89,var(--border-opacity))}.md\:hover\:border-transparent:hover{border-color:transparent}.md\:hover\:border-current:hover{border-color:currentColor}.md\:hover\:border-black:hover{--border-opacity:1;border-color:#000;border-color:rgba(0,0,0,var(--border-opacity))}.md\:hover\:border-white:hover{--border-opacity:1;border-color:#fff;border-color:rgba(255,255,255,var(--border-opacity))}.md\:hover\:border-gray-100:hover{--border-opacity:1;border-color:#f7fafc;border-color:rgba(247,250,252,var(--border-opacity))}.md\:hover\:border-gray-200:hover{--border-opacity:1;border-color:#edf2f7;border-color:rgba(237,242,247,var(--border-opacity))}.md\:hover\:border-gray-300:hover{--border-opacity:1;border-color:#e2e8f0;border-color:rgba(226,232,240,var(--border-opacity))}.md\:hover\:border-gray-400:hover{--border-opacity:1;border-color:#cbd5e0;border-color:rgba(203,213,224,var(--border-opacity))}.md\:hover\:border-gray-500:hover{--border-opacity:1;border-color:#a0aec0;border-color:rgba(160,174,192,var(--border-opacity))}.md\:hover\:border-gray-600:hover{--border-opacity:1;border-color:#718096;border-color:rgba(113,128,150,var(--border-opacity))}.md\:hover\:border-gray-700:hover{--border-opacity:1;border-color:#4a5568;border-color:rgba(74,85,104,var(--border-opacity))}.md\:hover\:border-gray-800:hover{--border-opacity:1;border-color:#2d3748;border-color:rgba(45,55,72,var(--border-opacity))}.md\:hover\:border-gray-900:hover{--border-opacity:1;border-color:#1a202c;border-color:rgba(26,32,44,var(--border-opacity))}.md\:hover\:border-red-100:hover{--border-opacity:1;border-color:#fff5f5;border-color:rgba(255,245,245,var(--border-opacity))}.md\:hover\:border-red-200:hover{--border-opacity:1;border-color:#fed7d7;border-color:rgba(254,215,215,var(--border-opacity))}.md\:hover\:border-red-300:hover{--border-opacity:1;border-color:#feb2b2;border-color:rgba(254,178,178,var(--border-opacity))}.md\:hover\:border-red-400:hover{--border-opacity:1;border-color:#fc8181;border-color:rgba(252,129,129,var(--border-opacity))}.md\:hover\:border-red-500:hover{--border-opacity:1;border-color:#f56565;border-color:rgba(245,101,101,var(--border-opacity))}.md\:hover\:border-red-600:hover{--border-opacity:1;border-color:#e53e3e;border-color:rgba(229,62,62,var(--border-opacity))}.md\:hover\:border-red-700:hover{--border-opacity:1;border-color:#c53030;border-color:rgba(197,48,48,var(--border-opacity))}.md\:hover\:border-red-800:hover{--border-opacity:1;border-color:#9b2c2c;border-color:rgba(155,44,44,var(--border-opacity))}.md\:hover\:border-red-900:hover{--border-opacity:1;border-color:#742a2a;border-color:rgba(116,42,42,var(--border-opacity))}.md\:hover\:border-orange-100:hover{--border-opacity:1;border-color:#fffaf0;border-color:rgba(255,250,240,var(--border-opacity))}.md\:hover\:border-orange-200:hover{--border-opacity:1;border-color:#feebc8;border-color:rgba(254,235,200,var(--border-opacity))}.md\:hover\:border-orange-300:hover{--border-opacity:1;border-color:#fbd38d;border-color:rgba(251,211,141,var(--border-opacity))}.md\:hover\:border-orange-400:hover{--border-opacity:1;border-color:#f6ad55;border-color:rgba(246,173,85,var(--border-opacity))}.md\:hover\:border-orange-500:hover{--border-opacity:1;border-color:#ed8936;border-color:rgba(237,137,54,var(--border-opacity))}.md\:hover\:border-orange-600:hover{--border-opacity:1;border-color:#dd6b20;border-color:rgba(221,107,32,var(--border-opacity))}.md\:hover\:border-orange-700:hover{--border-opacity:1;border-color:#c05621;border-color:rgba(192,86,33,var(--border-opacity))}.md\:hover\:border-orange-800:hover{--border-opacity:1;border-color:#9c4221;border-color:rgba(156,66,33,var(--border-opacity))}.md\:hover\:border-orange-900:hover{--border-opacity:1;border-color:#7b341e;border-color:rgba(123,52,30,var(--border-opacity))}.md\:hover\:border-yellow-100:hover{--border-opacity:1;border-color:ivory;border-color:rgba(255,255,240,var(--border-opacity))}.md\:hover\:border-yellow-200:hover{--border-opacity:1;border-color:#fefcbf;border-color:rgba(254,252,191,var(--border-opacity))}.md\:hover\:border-yellow-300:hover{--border-opacity:1;border-color:#faf089;border-color:rgba(250,240,137,var(--border-opacity))}.md\:hover\:border-yellow-400:hover{--border-opacity:1;border-color:#f6e05e;border-color:rgba(246,224,94,var(--border-opacity))}.md\:hover\:border-yellow-500:hover{--border-opacity:1;border-color:#ecc94b;border-color:rgba(236,201,75,var(--border-opacity))}.md\:hover\:border-yellow-600:hover{--border-opacity:1;border-color:#d69e2e;border-color:rgba(214,158,46,var(--border-opacity))}.md\:hover\:border-yellow-700:hover{--border-opacity:1;border-color:#b7791f;border-color:rgba(183,121,31,var(--border-opacity))}.md\:hover\:border-yellow-800:hover{--border-opacity:1;border-color:#975a16;border-color:rgba(151,90,22,var(--border-opacity))}.md\:hover\:border-yellow-900:hover{--border-opacity:1;border-color:#744210;border-color:rgba(116,66,16,var(--border-opacity))}.md\:hover\:border-green-100:hover{--border-opacity:1;border-color:#f0fff4;border-color:rgba(240,255,244,var(--border-opacity))}.md\:hover\:border-green-200:hover{--border-opacity:1;border-color:#c6f6d5;border-color:rgba(198,246,213,var(--border-opacity))}.md\:hover\:border-green-300:hover{--border-opacity:1;border-color:#9ae6b4;border-color:rgba(154,230,180,var(--border-opacity))}.md\:hover\:border-green-400:hover{--border-opacity:1;border-color:#68d391;border-color:rgba(104,211,145,var(--border-opacity))}.md\:hover\:border-green-500:hover{--border-opacity:1;border-color:#48bb78;border-color:rgba(72,187,120,var(--border-opacity))}.md\:hover\:border-green-600:hover{--border-opacity:1;border-color:#38a169;border-color:rgba(56,161,105,var(--border-opacity))}.md\:hover\:border-green-700:hover{--border-opacity:1;border-color:#2f855a;border-color:rgba(47,133,90,var(--border-opacity))}.md\:hover\:border-green-800:hover{--border-opacity:1;border-color:#276749;border-color:rgba(39,103,73,var(--border-opacity))}.md\:hover\:border-green-900:hover{--border-opacity:1;border-color:#22543d;border-color:rgba(34,84,61,var(--border-opacity))}.md\:hover\:border-teal-100:hover{--border-opacity:1;border-color:#e6fffa;border-color:rgba(230,255,250,var(--border-opacity))}.md\:hover\:border-teal-200:hover{--border-opacity:1;border-color:#b2f5ea;border-color:rgba(178,245,234,var(--border-opacity))}.md\:hover\:border-teal-300:hover{--border-opacity:1;border-color:#81e6d9;border-color:rgba(129,230,217,var(--border-opacity))}.md\:hover\:border-teal-400:hover{--border-opacity:1;border-color:#4fd1c5;border-color:rgba(79,209,197,var(--border-opacity))}.md\:hover\:border-teal-500:hover{--border-opacity:1;border-color:#38b2ac;border-color:rgba(56,178,172,var(--border-opacity))}.md\:hover\:border-teal-600:hover{--border-opacity:1;border-color:#319795;border-color:rgba(49,151,149,var(--border-opacity))}.md\:hover\:border-teal-700:hover{--border-opacity:1;border-color:#2c7a7b;border-color:rgba(44,122,123,var(--border-opacity))}.md\:hover\:border-teal-800:hover{--border-opacity:1;border-color:#285e61;border-color:rgba(40,94,97,var(--border-opacity))}.md\:hover\:border-teal-900:hover{--border-opacity:1;border-color:#234e52;border-color:rgba(35,78,82,var(--border-opacity))}.md\:hover\:border-blue-100:hover{--border-opacity:1;border-color:#ebf8ff;border-color:rgba(235,248,255,var(--border-opacity))}.md\:hover\:border-blue-200:hover{--border-opacity:1;border-color:#bee3f8;border-color:rgba(190,227,248,var(--border-opacity))}.md\:hover\:border-blue-300:hover{--border-opacity:1;border-color:#90cdf4;border-color:rgba(144,205,244,var(--border-opacity))}.md\:hover\:border-blue-400:hover{--border-opacity:1;border-color:#63b3ed;border-color:rgba(99,179,237,var(--border-opacity))}.md\:hover\:border-blue-500:hover{--border-opacity:1;border-color:#4299e1;border-color:rgba(66,153,225,var(--border-opacity))}.md\:hover\:border-blue-600:hover{--border-opacity:1;border-color:#3182ce;border-color:rgba(49,130,206,var(--border-opacity))}.md\:hover\:border-blue-700:hover{--border-opacity:1;border-color:#2b6cb0;border-color:rgba(43,108,176,var(--border-opacity))}.md\:hover\:border-blue-800:hover{--border-opacity:1;border-color:#2c5282;border-color:rgba(44,82,130,var(--border-opacity))}.md\:hover\:border-blue-900:hover{--border-opacity:1;border-color:#2a4365;border-color:rgba(42,67,101,var(--border-opacity))}.md\:hover\:border-indigo-100:hover{--border-opacity:1;border-color:#ebf4ff;border-color:rgba(235,244,255,var(--border-opacity))}.md\:hover\:border-indigo-200:hover{--border-opacity:1;border-color:#c3dafe;border-color:rgba(195,218,254,var(--border-opacity))}.md\:hover\:border-indigo-300:hover{--border-opacity:1;border-color:#a3bffa;border-color:rgba(163,191,250,var(--border-opacity))}.md\:hover\:border-indigo-400:hover{--border-opacity:1;border-color:#7f9cf5;border-color:rgba(127,156,245,var(--border-opacity))}.md\:hover\:border-indigo-500:hover{--border-opacity:1;border-color:#667eea;border-color:rgba(102,126,234,var(--border-opacity))}.md\:hover\:border-indigo-600:hover{--border-opacity:1;border-color:#5a67d8;border-color:rgba(90,103,216,var(--border-opacity))}.md\:hover\:border-indigo-700:hover{--border-opacity:1;border-color:#4c51bf;border-color:rgba(76,81,191,var(--border-opacity))}.md\:hover\:border-indigo-800:hover{--border-opacity:1;border-color:#434190;border-color:rgba(67,65,144,var(--border-opacity))}.md\:hover\:border-indigo-900:hover{--border-opacity:1;border-color:#3c366b;border-color:rgba(60,54,107,var(--border-opacity))}.md\:hover\:border-purple-100:hover{--border-opacity:1;border-color:#faf5ff;border-color:rgba(250,245,255,var(--border-opacity))}.md\:hover\:border-purple-200:hover{--border-opacity:1;border-color:#e9d8fd;border-color:rgba(233,216,253,var(--border-opacity))}.md\:hover\:border-purple-300:hover{--border-opacity:1;border-color:#d6bcfa;border-color:rgba(214,188,250,var(--border-opacity))}.md\:hover\:border-purple-400:hover{--border-opacity:1;border-color:#b794f4;border-color:rgba(183,148,244,var(--border-opacity))}.md\:hover\:border-purple-500:hover{--border-opacity:1;border-color:#9f7aea;border-color:rgba(159,122,234,var(--border-opacity))}.md\:hover\:border-purple-600:hover{--border-opacity:1;border-color:#805ad5;border-color:rgba(128,90,213,var(--border-opacity))}.md\:hover\:border-purple-700:hover{--border-opacity:1;border-color:#6b46c1;border-color:rgba(107,70,193,var(--border-opacity))}.md\:hover\:border-purple-800:hover{--border-opacity:1;border-color:#553c9a;border-color:rgba(85,60,154,var(--border-opacity))}.md\:hover\:border-purple-900:hover{--border-opacity:1;border-color:#44337a;border-color:rgba(68,51,122,var(--border-opacity))}.md\:hover\:border-pink-100:hover{--border-opacity:1;border-color:#fff5f7;border-color:rgba(255,245,247,var(--border-opacity))}.md\:hover\:border-pink-200:hover{--border-opacity:1;border-color:#fed7e2;border-color:rgba(254,215,226,var(--border-opacity))}.md\:hover\:border-pink-300:hover{--border-opacity:1;border-color:#fbb6ce;border-color:rgba(251,182,206,var(--border-opacity))}.md\:hover\:border-pink-400:hover{--border-opacity:1;border-color:#f687b3;border-color:rgba(246,135,179,var(--border-opacity))}.md\:hover\:border-pink-500:hover{--border-opacity:1;border-color:#ed64a6;border-color:rgba(237,100,166,var(--border-opacity))}.md\:hover\:border-pink-600:hover{--border-opacity:1;border-color:#d53f8c;border-color:rgba(213,63,140,var(--border-opacity))}.md\:hover\:border-pink-700:hover{--border-opacity:1;border-color:#b83280;border-color:rgba(184,50,128,var(--border-opacity))}.md\:hover\:border-pink-800:hover{--border-opacity:1;border-color:#97266d;border-color:rgba(151,38,109,var(--border-opacity))}.md\:hover\:border-pink-900:hover{--border-opacity:1;border-color:#702459;border-color:rgba(112,36,89,var(--border-opacity))}.md\:focus\:border-transparent:focus{border-color:transparent}.md\:focus\:border-current:focus{border-color:currentColor}.md\:focus\:border-black:focus{--border-opacity:1;border-color:#000;border-color:rgba(0,0,0,var(--border-opacity))}.md\:focus\:border-white:focus{--border-opacity:1;border-color:#fff;border-color:rgba(255,255,255,var(--border-opacity))}.md\:focus\:border-gray-100:focus{--border-opacity:1;border-color:#f7fafc;border-color:rgba(247,250,252,var(--border-opacity))}.md\:focus\:border-gray-200:focus{--border-opacity:1;border-color:#edf2f7;border-color:rgba(237,242,247,var(--border-opacity))}.md\:focus\:border-gray-300:focus{--border-opacity:1;border-color:#e2e8f0;border-color:rgba(226,232,240,var(--border-opacity))}.md\:focus\:border-gray-400:focus{--border-opacity:1;border-color:#cbd5e0;border-color:rgba(203,213,224,var(--border-opacity))}.md\:focus\:border-gray-500:focus{--border-opacity:1;border-color:#a0aec0;border-color:rgba(160,174,192,var(--border-opacity))}.md\:focus\:border-gray-600:focus{--border-opacity:1;border-color:#718096;border-color:rgba(113,128,150,var(--border-opacity))}.md\:focus\:border-gray-700:focus{--border-opacity:1;border-color:#4a5568;border-color:rgba(74,85,104,var(--border-opacity))}.md\:focus\:border-gray-800:focus{--border-opacity:1;border-color:#2d3748;border-color:rgba(45,55,72,var(--border-opacity))}.md\:focus\:border-gray-900:focus{--border-opacity:1;border-color:#1a202c;border-color:rgba(26,32,44,var(--border-opacity))}.md\:focus\:border-red-100:focus{--border-opacity:1;border-color:#fff5f5;border-color:rgba(255,245,245,var(--border-opacity))}.md\:focus\:border-red-200:focus{--border-opacity:1;border-color:#fed7d7;border-color:rgba(254,215,215,var(--border-opacity))}.md\:focus\:border-red-300:focus{--border-opacity:1;border-color:#feb2b2;border-color:rgba(254,178,178,var(--border-opacity))}.md\:focus\:border-red-400:focus{--border-opacity:1;border-color:#fc8181;border-color:rgba(252,129,129,var(--border-opacity))}.md\:focus\:border-red-500:focus{--border-opacity:1;border-color:#f56565;border-color:rgba(245,101,101,var(--border-opacity))}.md\:focus\:border-red-600:focus{--border-opacity:1;border-color:#e53e3e;border-color:rgba(229,62,62,var(--border-opacity))}.md\:focus\:border-red-700:focus{--border-opacity:1;border-color:#c53030;border-color:rgba(197,48,48,var(--border-opacity))}.md\:focus\:border-red-800:focus{--border-opacity:1;border-color:#9b2c2c;border-color:rgba(155,44,44,var(--border-opacity))}.md\:focus\:border-red-900:focus{--border-opacity:1;border-color:#742a2a;border-color:rgba(116,42,42,var(--border-opacity))}.md\:focus\:border-orange-100:focus{--border-opacity:1;border-color:#fffaf0;border-color:rgba(255,250,240,var(--border-opacity))}.md\:focus\:border-orange-200:focus{--border-opacity:1;border-color:#feebc8;border-color:rgba(254,235,200,var(--border-opacity))}.md\:focus\:border-orange-300:focus{--border-opacity:1;border-color:#fbd38d;border-color:rgba(251,211,141,var(--border-opacity))}.md\:focus\:border-orange-400:focus{--border-opacity:1;border-color:#f6ad55;border-color:rgba(246,173,85,var(--border-opacity))}.md\:focus\:border-orange-500:focus{--border-opacity:1;border-color:#ed8936;border-color:rgba(237,137,54,var(--border-opacity))}.md\:focus\:border-orange-600:focus{--border-opacity:1;border-color:#dd6b20;border-color:rgba(221,107,32,var(--border-opacity))}.md\:focus\:border-orange-700:focus{--border-opacity:1;border-color:#c05621;border-color:rgba(192,86,33,var(--border-opacity))}.md\:focus\:border-orange-800:focus{--border-opacity:1;border-color:#9c4221;border-color:rgba(156,66,33,var(--border-opacity))}.md\:focus\:border-orange-900:focus{--border-opacity:1;border-color:#7b341e;border-color:rgba(123,52,30,var(--border-opacity))}.md\:focus\:border-yellow-100:focus{--border-opacity:1;border-color:ivory;border-color:rgba(255,255,240,var(--border-opacity))}.md\:focus\:border-yellow-200:focus{--border-opacity:1;border-color:#fefcbf;border-color:rgba(254,252,191,var(--border-opacity))}.md\:focus\:border-yellow-300:focus{--border-opacity:1;border-color:#faf089;border-color:rgba(250,240,137,var(--border-opacity))}.md\:focus\:border-yellow-400:focus{--border-opacity:1;border-color:#f6e05e;border-color:rgba(246,224,94,var(--border-opacity))}.md\:focus\:border-yellow-500:focus{--border-opacity:1;border-color:#ecc94b;border-color:rgba(236,201,75,var(--border-opacity))}.md\:focus\:border-yellow-600:focus{--border-opacity:1;border-color:#d69e2e;border-color:rgba(214,158,46,var(--border-opacity))}.md\:focus\:border-yellow-700:focus{--border-opacity:1;border-color:#b7791f;border-color:rgba(183,121,31,var(--border-opacity))}.md\:focus\:border-yellow-800:focus{--border-opacity:1;border-color:#975a16;border-color:rgba(151,90,22,var(--border-opacity))}.md\:focus\:border-yellow-900:focus{--border-opacity:1;border-color:#744210;border-color:rgba(116,66,16,var(--border-opacity))}.md\:focus\:border-green-100:focus{--border-opacity:1;border-color:#f0fff4;border-color:rgba(240,255,244,var(--border-opacity))}.md\:focus\:border-green-200:focus{--border-opacity:1;border-color:#c6f6d5;border-color:rgba(198,246,213,var(--border-opacity))}.md\:focus\:border-green-300:focus{--border-opacity:1;border-color:#9ae6b4;border-color:rgba(154,230,180,var(--border-opacity))}.md\:focus\:border-green-400:focus{--border-opacity:1;border-color:#68d391;border-color:rgba(104,211,145,var(--border-opacity))}.md\:focus\:border-green-500:focus{--border-opacity:1;border-color:#48bb78;border-color:rgba(72,187,120,var(--border-opacity))}.md\:focus\:border-green-600:focus{--border-opacity:1;border-color:#38a169;border-color:rgba(56,161,105,var(--border-opacity))}.md\:focus\:border-green-700:focus{--border-opacity:1;border-color:#2f855a;border-color:rgba(47,133,90,var(--border-opacity))}.md\:focus\:border-green-800:focus{--border-opacity:1;border-color:#276749;border-color:rgba(39,103,73,var(--border-opacity))}.md\:focus\:border-green-900:focus{--border-opacity:1;border-color:#22543d;border-color:rgba(34,84,61,var(--border-opacity))}.md\:focus\:border-teal-100:focus{--border-opacity:1;border-color:#e6fffa;border-color:rgba(230,255,250,var(--border-opacity))}.md\:focus\:border-teal-200:focus{--border-opacity:1;border-color:#b2f5ea;border-color:rgba(178,245,234,var(--border-opacity))}.md\:focus\:border-teal-300:focus{--border-opacity:1;border-color:#81e6d9;border-color:rgba(129,230,217,var(--border-opacity))}.md\:focus\:border-teal-400:focus{--border-opacity:1;border-color:#4fd1c5;border-color:rgba(79,209,197,var(--border-opacity))}.md\:focus\:border-teal-500:focus{--border-opacity:1;border-color:#38b2ac;border-color:rgba(56,178,172,var(--border-opacity))}.md\:focus\:border-teal-600:focus{--border-opacity:1;border-color:#319795;border-color:rgba(49,151,149,var(--border-opacity))}.md\:focus\:border-teal-700:focus{--border-opacity:1;border-color:#2c7a7b;border-color:rgba(44,122,123,var(--border-opacity))}.md\:focus\:border-teal-800:focus{--border-opacity:1;border-color:#285e61;border-color:rgba(40,94,97,var(--border-opacity))}.md\:focus\:border-teal-900:focus{--border-opacity:1;border-color:#234e52;border-color:rgba(35,78,82,var(--border-opacity))}.md\:focus\:border-blue-100:focus{--border-opacity:1;border-color:#ebf8ff;border-color:rgba(235,248,255,var(--border-opacity))}.md\:focus\:border-blue-200:focus{--border-opacity:1;border-color:#bee3f8;border-color:rgba(190,227,248,var(--border-opacity))}.md\:focus\:border-blue-300:focus{--border-opacity:1;border-color:#90cdf4;border-color:rgba(144,205,244,var(--border-opacity))}.md\:focus\:border-blue-400:focus{--border-opacity:1;border-color:#63b3ed;border-color:rgba(99,179,237,var(--border-opacity))}.md\:focus\:border-blue-500:focus{--border-opacity:1;border-color:#4299e1;border-color:rgba(66,153,225,var(--border-opacity))}.md\:focus\:border-blue-600:focus{--border-opacity:1;border-color:#3182ce;border-color:rgba(49,130,206,var(--border-opacity))}.md\:focus\:border-blue-700:focus{--border-opacity:1;border-color:#2b6cb0;border-color:rgba(43,108,176,var(--border-opacity))}.md\:focus\:border-blue-800:focus{--border-opacity:1;border-color:#2c5282;border-color:rgba(44,82,130,var(--border-opacity))}.md\:focus\:border-blue-900:focus{--border-opacity:1;border-color:#2a4365;border-color:rgba(42,67,101,var(--border-opacity))}.md\:focus\:border-indigo-100:focus{--border-opacity:1;border-color:#ebf4ff;border-color:rgba(235,244,255,var(--border-opacity))}.md\:focus\:border-indigo-200:focus{--border-opacity:1;border-color:#c3dafe;border-color:rgba(195,218,254,var(--border-opacity))}.md\:focus\:border-indigo-300:focus{--border-opacity:1;border-color:#a3bffa;border-color:rgba(163,191,250,var(--border-opacity))}.md\:focus\:border-indigo-400:focus{--border-opacity:1;border-color:#7f9cf5;border-color:rgba(127,156,245,var(--border-opacity))}.md\:focus\:border-indigo-500:focus{--border-opacity:1;border-color:#667eea;border-color:rgba(102,126,234,var(--border-opacity))}.md\:focus\:border-indigo-600:focus{--border-opacity:1;border-color:#5a67d8;border-color:rgba(90,103,216,var(--border-opacity))}.md\:focus\:border-indigo-700:focus{--border-opacity:1;border-color:#4c51bf;border-color:rgba(76,81,191,var(--border-opacity))}.md\:focus\:border-indigo-800:focus{--border-opacity:1;border-color:#434190;border-color:rgba(67,65,144,var(--border-opacity))}.md\:focus\:border-indigo-900:focus{--border-opacity:1;border-color:#3c366b;border-color:rgba(60,54,107,var(--border-opacity))}.md\:focus\:border-purple-100:focus{--border-opacity:1;border-color:#faf5ff;border-color:rgba(250,245,255,var(--border-opacity))}.md\:focus\:border-purple-200:focus{--border-opacity:1;border-color:#e9d8fd;border-color:rgba(233,216,253,var(--border-opacity))}.md\:focus\:border-purple-300:focus{--border-opacity:1;border-color:#d6bcfa;border-color:rgba(214,188,250,var(--border-opacity))}.md\:focus\:border-purple-400:focus{--border-opacity:1;border-color:#b794f4;border-color:rgba(183,148,244,var(--border-opacity))}.md\:focus\:border-purple-500:focus{--border-opacity:1;border-color:#9f7aea;border-color:rgba(159,122,234,var(--border-opacity))}.md\:focus\:border-purple-600:focus{--border-opacity:1;border-color:#805ad5;border-color:rgba(128,90,213,var(--border-opacity))}.md\:focus\:border-purple-700:focus{--border-opacity:1;border-color:#6b46c1;border-color:rgba(107,70,193,var(--border-opacity))}.md\:focus\:border-purple-800:focus{--border-opacity:1;border-color:#553c9a;border-color:rgba(85,60,154,var(--border-opacity))}.md\:focus\:border-purple-900:focus{--border-opacity:1;border-color:#44337a;border-color:rgba(68,51,122,var(--border-opacity))}.md\:focus\:border-pink-100:focus{--border-opacity:1;border-color:#fff5f7;border-color:rgba(255,245,247,var(--border-opacity))}.md\:focus\:border-pink-200:focus{--border-opacity:1;border-color:#fed7e2;border-color:rgba(254,215,226,var(--border-opacity))}.md\:focus\:border-pink-300:focus{--border-opacity:1;border-color:#fbb6ce;border-color:rgba(251,182,206,var(--border-opacity))}.md\:focus\:border-pink-400:focus{--border-opacity:1;border-color:#f687b3;border-color:rgba(246,135,179,var(--border-opacity))}.md\:focus\:border-pink-500:focus{--border-opacity:1;border-color:#ed64a6;border-color:rgba(237,100,166,var(--border-opacity))}.md\:focus\:border-pink-600:focus{--border-opacity:1;border-color:#d53f8c;border-color:rgba(213,63,140,var(--border-opacity))}.md\:focus\:border-pink-700:focus{--border-opacity:1;border-color:#b83280;border-color:rgba(184,50,128,var(--border-opacity))}.md\:focus\:border-pink-800:focus{--border-opacity:1;border-color:#97266d;border-color:rgba(151,38,109,var(--border-opacity))}.md\:focus\:border-pink-900:focus{--border-opacity:1;border-color:#702459;border-color:rgba(112,36,89,var(--border-opacity))}.md\:border-opacity-0{--border-opacity:0}.md\:border-opacity-25{--border-opacity:0.25}.md\:border-opacity-50{--border-opacity:0.5}.md\:border-opacity-75{--border-opacity:0.75}.md\:border-opacity-100{--border-opacity:1}.md\:hover\:border-opacity-0:hover{--border-opacity:0}.md\:hover\:border-opacity-25:hover{--border-opacity:0.25}.md\:hover\:border-opacity-50:hover{--border-opacity:0.5}.md\:hover\:border-opacity-75:hover{--border-opacity:0.75}.md\:hover\:border-opacity-100:hover{--border-opacity:1}.md\:focus\:border-opacity-0:focus{--border-opacity:0}.md\:focus\:border-opacity-25:focus{--border-opacity:0.25}.md\:focus\:border-opacity-50:focus{--border-opacity:0.5}.md\:focus\:border-opacity-75:focus{--border-opacity:0.75}.md\:focus\:border-opacity-100:focus{--border-opacity:1}.md\:rounded-none{border-radius:0}.md\:rounded-sm{border-radius:.125rem}.md\:rounded{border-radius:.25rem}.md\:rounded-md{border-radius:.375rem}.md\:rounded-lg{border-radius:.5rem}.md\:rounded-xl{border-radius:.75rem}.md\:rounded-2xl{border-radius:1rem}.md\:rounded-3xl{border-radius:1.5rem}.md\:rounded-full{border-radius:9999px}.md\:rounded-t-none{border-top-left-radius:0;border-top-right-radius:0}.md\:rounded-r-none{border-top-right-radius:0;border-bottom-right-radius:0}.md\:rounded-b-none{border-bottom-right-radius:0;border-bottom-left-radius:0}.md\:rounded-l-none{border-top-left-radius:0;border-bottom-left-radius:0}.md\:rounded-t-sm{border-top-left-radius:.125rem;border-top-right-radius:.125rem}.md\:rounded-r-sm{border-top-right-radius:.125rem;border-bottom-right-radius:.125rem}.md\:rounded-b-sm{border-bottom-right-radius:.125rem;border-bottom-left-radius:.125rem}.md\:rounded-l-sm{border-top-left-radius:.125rem;border-bottom-left-radius:.125rem}.md\:rounded-t{border-top-left-radius:.25rem;border-top-right-radius:.25rem}.md\:rounded-r{border-top-right-radius:.25rem;border-bottom-right-radius:.25rem}.md\:rounded-b{border-bottom-right-radius:.25rem;border-bottom-left-radius:.25rem}.md\:rounded-l{border-top-left-radius:.25rem;border-bottom-left-radius:.25rem}.md\:rounded-t-md{border-top-left-radius:.375rem;border-top-right-radius:.375rem}.md\:rounded-r-md{border-top-right-radius:.375rem;border-bottom-right-radius:.375rem}.md\:rounded-b-md{border-bottom-right-radius:.375rem;border-bottom-left-radius:.375rem}.md\:rounded-l-md{border-top-left-radius:.375rem;border-bottom-left-radius:.375rem}.md\:rounded-t-lg{border-top-left-radius:.5rem;border-top-right-radius:.5rem}.md\:rounded-r-lg{border-top-right-radius:.5rem;border-bottom-right-radius:.5rem}.md\:rounded-b-lg{border-bottom-right-radius:.5rem;border-bottom-left-radius:.5rem}.md\:rounded-l-lg{border-top-left-radius:.5rem;border-bottom-left-radius:.5rem}.md\:rounded-t-xl{border-top-left-radius:.75rem;border-top-right-radius:.75rem}.md\:rounded-r-xl{border-top-right-radius:.75rem;border-bottom-right-radius:.75rem}.md\:rounded-b-xl{border-bottom-right-radius:.75rem;border-bottom-left-radius:.75rem}.md\:rounded-l-xl{border-top-left-radius:.75rem;border-bottom-left-radius:.75rem}.md\:rounded-t-2xl{border-top-left-radius:1rem;border-top-right-radius:1rem}.md\:rounded-r-2xl{border-top-right-radius:1rem;border-bottom-right-radius:1rem}.md\:rounded-b-2xl{border-bottom-right-radius:1rem;border-bottom-left-radius:1rem}.md\:rounded-l-2xl{border-top-left-radius:1rem;border-bottom-left-radius:1rem}.md\:rounded-t-3xl{border-top-left-radius:1.5rem;border-top-right-radius:1.5rem}.md\:rounded-r-3xl{border-top-right-radius:1.5rem;border-bottom-right-radius:1.5rem}.md\:rounded-b-3xl{border-bottom-right-radius:1.5rem;border-bottom-left-radius:1.5rem}.md\:rounded-l-3xl{border-top-left-radius:1.5rem;border-bottom-left-radius:1.5rem}.md\:rounded-t-full{border-top-left-radius:9999px;border-top-right-radius:9999px}.md\:rounded-r-full{border-top-right-radius:9999px;border-bottom-right-radius:9999px}.md\:rounded-b-full{border-bottom-right-radius:9999px;border-bottom-left-radius:9999px}.md\:rounded-l-full{border-top-left-radius:9999px;border-bottom-left-radius:9999px}.md\:rounded-tl-none{border-top-left-radius:0}.md\:rounded-tr-none{border-top-right-radius:0}.md\:rounded-br-none{border-bottom-right-radius:0}.md\:rounded-bl-none{border-bottom-left-radius:0}.md\:rounded-tl-sm{border-top-left-radius:.125rem}.md\:rounded-tr-sm{border-top-right-radius:.125rem}.md\:rounded-br-sm{border-bottom-right-radius:.125rem}.md\:rounded-bl-sm{border-bottom-left-radius:.125rem}.md\:rounded-tl{border-top-left-radius:.25rem}.md\:rounded-tr{border-top-right-radius:.25rem}.md\:rounded-br{border-bottom-right-radius:.25rem}.md\:rounded-bl{border-bottom-left-radius:.25rem}.md\:rounded-tl-md{border-top-left-radius:.375rem}.md\:rounded-tr-md{border-top-right-radius:.375rem}.md\:rounded-br-md{border-bottom-right-radius:.375rem}.md\:rounded-bl-md{border-bottom-left-radius:.375rem}.md\:rounded-tl-lg{border-top-left-radius:.5rem}.md\:rounded-tr-lg{border-top-right-radius:.5rem}.md\:rounded-br-lg{border-bottom-right-radius:.5rem}.md\:rounded-bl-lg{border-bottom-left-radius:.5rem}.md\:rounded-tl-xl{border-top-left-radius:.75rem}.md\:rounded-tr-xl{border-top-right-radius:.75rem}.md\:rounded-br-xl{border-bottom-right-radius:.75rem}.md\:rounded-bl-xl{border-bottom-left-radius:.75rem}.md\:rounded-tl-2xl{border-top-left-radius:1rem}.md\:rounded-tr-2xl{border-top-right-radius:1rem}.md\:rounded-br-2xl{border-bottom-right-radius:1rem}.md\:rounded-bl-2xl{border-bottom-left-radius:1rem}.md\:rounded-tl-3xl{border-top-left-radius:1.5rem}.md\:rounded-tr-3xl{border-top-right-radius:1.5rem}.md\:rounded-br-3xl{border-bottom-right-radius:1.5rem}.md\:rounded-bl-3xl{border-bottom-left-radius:1.5rem}.md\:rounded-tl-full{border-top-left-radius:9999px}.md\:rounded-tr-full{border-top-right-radius:9999px}.md\:rounded-br-full{border-bottom-right-radius:9999px}.md\:rounded-bl-full{border-bottom-left-radius:9999px}.md\:border-solid{border-style:solid}.md\:border-dashed{border-style:dashed}.md\:border-dotted{border-style:dotted}.md\:border-double{border-style:double}.md\:border-none{border-style:none}.md\:border-0{border-width:0}.md\:border-2{border-width:2px}.md\:border-4{border-width:4px}.md\:border-8{border-width:8px}.md\:border{border-width:1px}.md\:border-t-0{border-top-width:0}.md\:border-r-0{border-right-width:0}.md\:border-b-0{border-bottom-width:0}.md\:border-l-0{border-left-width:0}.md\:border-t-2{border-top-width:2px}.md\:border-r-2{border-right-width:2px}.md\:border-b-2{border-bottom-width:2px}.md\:border-l-2{border-left-width:2px}.md\:border-t-4{border-top-width:4px}.md\:border-r-4{border-right-width:4px}.md\:border-b-4{border-bottom-width:4px}.md\:border-l-4{border-left-width:4px}.md\:border-t-8{border-top-width:8px}.md\:border-r-8{border-right-width:8px}.md\:border-b-8{border-bottom-width:8px}.md\:border-l-8{border-left-width:8px}.md\:border-t{border-top-width:1px}.md\:border-r{border-right-width:1px}.md\:border-b{border-bottom-width:1px}.md\:border-l{border-left-width:1px}.md\:box-border{box-sizing:border-box}.md\:box-content{box-sizing:content-box}.md\:cursor-auto{cursor:auto}.md\:cursor-default{cursor:default}.md\:cursor-pointer{cursor:pointer}.md\:cursor-wait{cursor:wait}.md\:cursor-text{cursor:text}.md\:cursor-move{cursor:move}.md\:cursor-not-allowed{cursor:not-allowed}.md\:block{display:block}.md\:inline-block{display:inline-block}.md\:inline{display:inline}.md\:flex{display:flex}.md\:inline-flex{display:inline-flex}.md\:table{display:table}.md\:table-caption{display:table-caption}.md\:table-cell{display:table-cell}.md\:table-column{display:table-column}.md\:table-column-group{display:table-column-group}.md\:table-footer-group{display:table-footer-group}.md\:table-header-group{display:table-header-group}.md\:table-row-group{display:table-row-group}.md\:table-row{display:table-row}.md\:flow-root{display:flow-root}.md\:grid{display:grid}.md\:inline-grid{display:inline-grid}.md\:contents{display:contents}.md\:hidden{display:none}.md\:flex-row{flex-direction:row}.md\:flex-row-reverse{flex-direction:row-reverse}.md\:flex-col{flex-direction:column}.md\:flex-col-reverse{flex-direction:column-reverse}.md\:flex-wrap{flex-wrap:wrap}.md\:flex-wrap-reverse{flex-wrap:wrap-reverse}.md\:flex-no-wrap{flex-wrap:nowrap}.md\:place-items-auto{place-items:auto}.md\:place-items-start{place-items:start}.md\:place-items-end{place-items:end}.md\:place-items-center{place-items:center}.md\:place-items-stretch{place-items:stretch}.md\:place-content-center{place-content:center}.md\:place-content-start{place-content:start}.md\:place-content-end{place-content:end}.md\:place-content-between{place-content:space-between}.md\:place-content-around{place-content:space-around}.md\:place-content-evenly{place-content:space-evenly}.md\:place-content-stretch{place-content:stretch}.md\:place-self-auto{place-self:auto}.md\:place-self-start{place-self:start}.md\:place-self-end{place-self:end}.md\:place-self-center{place-self:center}.md\:place-self-stretch{place-self:stretch}.md\:items-start{align-items:flex-start}.md\:items-end{align-items:flex-end}.md\:items-center{align-items:center}.md\:items-baseline{align-items:baseline}.md\:items-stretch{align-items:stretch}.md\:content-center{align-content:center}.md\:content-start{align-content:flex-start}.md\:content-end{align-content:flex-end}.md\:content-between{align-content:space-between}.md\:content-around{align-content:space-around}.md\:content-evenly{align-content:space-evenly}.md\:self-auto{align-self:auto}.md\:self-start{align-self:flex-start}.md\:self-end{align-self:flex-end}.md\:self-center{align-self:center}.md\:self-stretch{align-self:stretch}.md\:justify-items-auto{justify-items:auto}.md\:justify-items-start{justify-items:start}.md\:justify-items-end{justify-items:end}.md\:justify-items-center{justify-items:center}.md\:justify-items-stretch{justify-items:stretch}.md\:justify-start{justify-content:flex-start}.md\:justify-end{justify-content:flex-end}.md\:justify-center{justify-content:center}.md\:justify-between{justify-content:space-between}.md\:justify-around{justify-content:space-around}.md\:justify-evenly{justify-content:space-evenly}.md\:justify-self-auto{justify-self:auto}.md\:justify-self-start{justify-self:start}.md\:justify-self-end{justify-self:end}.md\:justify-self-center{justify-self:center}.md\:justify-self-stretch{justify-self:stretch}.md\:flex-1{flex:1 1 0%}.md\:flex-auto{flex:1 1 auto}.md\:flex-initial{flex:0 1 auto}.md\:flex-none{flex:none}.md\:flex-grow-0{flex-grow:0}.md\:flex-grow{flex-grow:1}.md\:flex-shrink-0{flex-shrink:0}.md\:flex-shrink{flex-shrink:1}.md\:order-1{order:1}.md\:order-2{order:2}.md\:order-3{order:3}.md\:order-4{order:4}.md\:order-5{order:5}.md\:order-6{order:6}.md\:order-7{order:7}.md\:order-8{order:8}.md\:order-9{order:9}.md\:order-10{order:10}.md\:order-11{order:11}.md\:order-12{order:12}.md\:order-first{order:-9999}.md\:order-last{order:9999}.md\:order-none{order:0}.md\:float-right{float:right}.md\:float-left{float:left}.md\:float-none{float:none}.md\:clearfix:after{content:"";display:table;clear:both}.md\:clear-left{clear:left}.md\:clear-right{clear:right}.md\:clear-both{clear:both}.md\:clear-none{clear:none}.md\:font-sans{font-family:system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji"}.md\:font-serif{font-family:Georgia,Cambria,"Times New Roman",Times,serif}.md\:font-mono{font-family:Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace}.md\:font-hairline{font-weight:100}.md\:font-thin{font-weight:200}.md\:font-light{font-weight:300}.md\:font-normal{font-weight:400}.md\:font-medium{font-weight:500}.md\:font-semibold{font-weight:600}.md\:font-bold{font-weight:700}.md\:font-extrabold{font-weight:800}.md\:font-black{font-weight:900}.md\:hover\:font-hairline:hover{font-weight:100}.md\:hover\:font-thin:hover{font-weight:200}.md\:hover\:font-light:hover{font-weight:300}.md\:hover\:font-normal:hover{font-weight:400}.md\:hover\:font-medium:hover{font-weight:500}.md\:hover\:font-semibold:hover{font-weight:600}.md\:hover\:font-bold:hover{font-weight:700}.md\:hover\:font-extrabold:hover{font-weight:800}.md\:hover\:font-black:hover{font-weight:900}.md\:focus\:font-hairline:focus{font-weight:100}.md\:focus\:font-thin:focus{font-weight:200}.md\:focus\:font-light:focus{font-weight:300}.md\:focus\:font-normal:focus{font-weight:400}.md\:focus\:font-medium:focus{font-weight:500}.md\:focus\:font-semibold:focus{font-weight:600}.md\:focus\:font-bold:focus{font-weight:700}.md\:focus\:font-extrabold:focus{font-weight:800}.md\:focus\:font-black:focus{font-weight:900}.md\:h-0{height:0}.md\:h-1{height:.25rem}.md\:h-2{height:.5rem}.md\:h-3{height:.75rem}.md\:h-4{height:1rem}.md\:h-5{height:1.25rem}.md\:h-6{height:1.5rem}.md\:h-8{height:2rem}.md\:h-10{height:2.5rem}.md\:h-12{height:3rem}.md\:h-16{height:4rem}.md\:h-20{height:5rem}.md\:h-24{height:6rem}.md\:h-32{height:8rem}.md\:h-40{height:10rem}.md\:h-48{height:12rem}.md\:h-56{height:14rem}.md\:h-64{height:16rem}.md\:h-auto{height:auto}.md\:h-px{height:1px}.md\:h-full{height:100%}.md\:h-screen{height:100vh}.md\:text-xs{font-size:.75rem}.md\:text-sm{font-size:.875rem}.md\:text-base{font-size:1rem}.md\:text-lg{font-size:1.125rem}.md\:text-xl{font-size:1.25rem}.md\:text-2xl{font-size:1.5rem}.md\:text-3xl{font-size:1.875rem}.md\:text-4xl{font-size:2.25rem}.md\:text-5xl{font-size:3rem}.md\:text-6xl{font-size:4rem}.md\:leading-3{line-height:.75rem}.md\:leading-4{line-height:1rem}.md\:leading-5{line-height:1.25rem}.md\:leading-6{line-height:1.5rem}.md\:leading-7{line-height:1.75rem}.md\:leading-8{line-height:2rem}.md\:leading-9{line-height:2.25rem}.md\:leading-10{line-height:2.5rem}.md\:leading-none{line-height:1}.md\:leading-tight{line-height:1.25}.md\:leading-snug{line-height:1.375}.md\:leading-normal{line-height:1.5}.md\:leading-relaxed{line-height:1.625}.md\:leading-loose{line-height:2}.md\:list-inside{list-style-position:inside}.md\:list-outside{list-style-position:outside}.md\:list-none{list-style-type:none}.md\:list-disc{list-style-type:disc}.md\:list-decimal{list-style-type:decimal}.md\:m-0{margin:0}.md\:m-1{margin:.25rem}.md\:m-2{margin:.5rem}.md\:m-3{margin:.75rem}.md\:m-4{margin:1rem}.md\:m-5{margin:1.25rem}.md\:m-6{margin:1.5rem}.md\:m-8{margin:2rem}.md\:m-10{margin:2.5rem}.md\:m-12{margin:3rem}.md\:m-16{margin:4rem}.md\:m-20{margin:5rem}.md\:m-24{margin:6rem}.md\:m-32{margin:8rem}.md\:m-40{margin:10rem}.md\:m-48{margin:12rem}.md\:m-56{margin:14rem}.md\:m-64{margin:16rem}.md\:m-auto{margin:auto}.md\:m-px{margin:1px}.md\:-m-1{margin:-.25rem}.md\:-m-2{margin:-.5rem}.md\:-m-3{margin:-.75rem}.md\:-m-4{margin:-1rem}.md\:-m-5{margin:-1.25rem}.md\:-m-6{margin:-1.5rem}.md\:-m-8{margin:-2rem}.md\:-m-10{margin:-2.5rem}.md\:-m-12{margin:-3rem}.md\:-m-16{margin:-4rem}.md\:-m-20{margin:-5rem}.md\:-m-24{margin:-6rem}.md\:-m-32{margin:-8rem}.md\:-m-40{margin:-10rem}.md\:-m-48{margin:-12rem}.md\:-m-56{margin:-14rem}.md\:-m-64{margin:-16rem}.md\:-m-px{margin:-1px}.md\:my-0{margin-top:0;margin-bottom:0}.md\:mx-0{margin-left:0;margin-right:0}.md\:my-1{margin-top:.25rem;margin-bottom:.25rem}.md\:mx-1{margin-left:.25rem;margin-right:.25rem}.md\:my-2{margin-top:.5rem;margin-bottom:.5rem}.md\:mx-2{margin-left:.5rem;margin-right:.5rem}.md\:my-3{margin-top:.75rem;margin-bottom:.75rem}.md\:mx-3{margin-left:.75rem;margin-right:.75rem}.md\:my-4{margin-top:1rem;margin-bottom:1rem}.md\:mx-4{margin-left:1rem;margin-right:1rem}.md\:my-5{margin-top:1.25rem;margin-bottom:1.25rem}.md\:mx-5{margin-left:1.25rem;margin-right:1.25rem}.md\:my-6{margin-top:1.5rem;margin-bottom:1.5rem}.md\:mx-6{margin-left:1.5rem;margin-right:1.5rem}.md\:my-8{margin-top:2rem;margin-bottom:2rem}.md\:mx-8{margin-left:2rem;margin-right:2rem}.md\:my-10{margin-top:2.5rem;margin-bottom:2.5rem}.md\:mx-10{margin-left:2.5rem;margin-right:2.5rem}.md\:my-12{margin-top:3rem;margin-bottom:3rem}.md\:mx-12{margin-left:3rem;margin-right:3rem}.md\:my-16{margin-top:4rem;margin-bottom:4rem}.md\:mx-16{margin-left:4rem;margin-right:4rem}.md\:my-20{margin-top:5rem;margin-bottom:5rem}.md\:mx-20{margin-left:5rem;margin-right:5rem}.md\:my-24{margin-top:6rem;margin-bottom:6rem}.md\:mx-24{margin-left:6rem;margin-right:6rem}.md\:my-32{margin-top:8rem;margin-bottom:8rem}.md\:mx-32{margin-left:8rem;margin-right:8rem}.md\:my-40{margin-top:10rem;margin-bottom:10rem}.md\:mx-40{margin-left:10rem;margin-right:10rem}.md\:my-48{margin-top:12rem;margin-bottom:12rem}.md\:mx-48{margin-left:12rem;margin-right:12rem}.md\:my-56{margin-top:14rem;margin-bottom:14rem}.md\:mx-56{margin-left:14rem;margin-right:14rem}.md\:my-64{margin-top:16rem;margin-bottom:16rem}.md\:mx-64{margin-left:16rem;margin-right:16rem}.md\:my-auto{margin-top:auto;margin-bottom:auto}.md\:mx-auto{margin-left:auto;margin-right:auto}.md\:my-px{margin-top:1px;margin-bottom:1px}.md\:mx-px{margin-left:1px;margin-right:1px}.md\:-my-1{margin-top:-.25rem;margin-bottom:-.25rem}.md\:-mx-1{margin-left:-.25rem;margin-right:-.25rem}.md\:-my-2{margin-top:-.5rem;margin-bottom:-.5rem}.md\:-mx-2{margin-left:-.5rem;margin-right:-.5rem}.md\:-my-3{margin-top:-.75rem;margin-bottom:-.75rem}.md\:-mx-3{margin-left:-.75rem;margin-right:-.75rem}.md\:-my-4{margin-top:-1rem;margin-bottom:-1rem}.md\:-mx-4{margin-left:-1rem;margin-right:-1rem}.md\:-my-5{margin-top:-1.25rem;margin-bottom:-1.25rem}.md\:-mx-5{margin-left:-1.25rem;margin-right:-1.25rem}.md\:-my-6{margin-top:-1.5rem;margin-bottom:-1.5rem}.md\:-mx-6{margin-left:-1.5rem;margin-right:-1.5rem}.md\:-my-8{margin-top:-2rem;margin-bottom:-2rem}.md\:-mx-8{margin-left:-2rem;margin-right:-2rem}.md\:-my-10{margin-top:-2.5rem;margin-bottom:-2.5rem}.md\:-mx-10{margin-left:-2.5rem;margin-right:-2.5rem}.md\:-my-12{margin-top:-3rem;margin-bottom:-3rem}.md\:-mx-12{margin-left:-3rem;margin-right:-3rem}.md\:-my-16{margin-top:-4rem;margin-bottom:-4rem}.md\:-mx-16{margin-left:-4rem;margin-right:-4rem}.md\:-my-20{margin-top:-5rem;margin-bottom:-5rem}.md\:-mx-20{margin-left:-5rem;margin-right:-5rem}.md\:-my-24{margin-top:-6rem;margin-bottom:-6rem}.md\:-mx-24{margin-left:-6rem;margin-right:-6rem}.md\:-my-32{margin-top:-8rem;margin-bottom:-8rem}.md\:-mx-32{margin-left:-8rem;margin-right:-8rem}.md\:-my-40{margin-top:-10rem;margin-bottom:-10rem}.md\:-mx-40{margin-left:-10rem;margin-right:-10rem}.md\:-my-48{margin-top:-12rem;margin-bottom:-12rem}.md\:-mx-48{margin-left:-12rem;margin-right:-12rem}.md\:-my-56{margin-top:-14rem;margin-bottom:-14rem}.md\:-mx-56{margin-left:-14rem;margin-right:-14rem}.md\:-my-64{margin-top:-16rem;margin-bottom:-16rem}.md\:-mx-64{margin-left:-16rem;margin-right:-16rem}.md\:-my-px{margin-top:-1px;margin-bottom:-1px}.md\:-mx-px{margin-left:-1px;margin-right:-1px}.md\:mt-0{margin-top:0}.md\:mr-0{margin-right:0}.md\:mb-0{margin-bottom:0}.md\:ml-0{margin-left:0}.md\:mt-1{margin-top:.25rem}.md\:mr-1{margin-right:.25rem}.md\:mb-1{margin-bottom:.25rem}.md\:ml-1{margin-left:.25rem}.md\:mt-2{margin-top:.5rem}.md\:mr-2{margin-right:.5rem}.md\:mb-2{margin-bottom:.5rem}.md\:ml-2{margin-left:.5rem}.md\:mt-3{margin-top:.75rem}.md\:mr-3{margin-right:.75rem}.md\:mb-3{margin-bottom:.75rem}.md\:ml-3{margin-left:.75rem}.md\:mt-4{margin-top:1rem}.md\:mr-4{margin-right:1rem}.md\:mb-4{margin-bottom:1rem}.md\:ml-4{margin-left:1rem}.md\:mt-5{margin-top:1.25rem}.md\:mr-5{margin-right:1.25rem}.md\:mb-5{margin-bottom:1.25rem}.md\:ml-5{margin-left:1.25rem}.md\:mt-6{margin-top:1.5rem}.md\:mr-6{margin-right:1.5rem}.md\:mb-6{margin-bottom:1.5rem}.md\:ml-6{margin-left:1.5rem}.md\:mt-8{margin-top:2rem}.md\:mr-8{margin-right:2rem}.md\:mb-8{margin-bottom:2rem}.md\:ml-8{margin-left:2rem}.md\:mt-10{margin-top:2.5rem}.md\:mr-10{margin-right:2.5rem}.md\:mb-10{margin-bottom:2.5rem}.md\:ml-10{margin-left:2.5rem}.md\:mt-12{margin-top:3rem}.md\:mr-12{margin-right:3rem}.md\:mb-12{margin-bottom:3rem}.md\:ml-12{margin-left:3rem}.md\:mt-16{margin-top:4rem}.md\:mr-16{margin-right:4rem}.md\:mb-16{margin-bottom:4rem}.md\:ml-16{margin-left:4rem}.md\:mt-20{margin-top:5rem}.md\:mr-20{margin-right:5rem}.md\:mb-20{margin-bottom:5rem}.md\:ml-20{margin-left:5rem}.md\:mt-24{margin-top:6rem}.md\:mr-24{margin-right:6rem}.md\:mb-24{margin-bottom:6rem}.md\:ml-24{margin-left:6rem}.md\:mt-32{margin-top:8rem}.md\:mr-32{margin-right:8rem}.md\:mb-32{margin-bottom:8rem}.md\:ml-32{margin-left:8rem}.md\:mt-40{margin-top:10rem}.md\:mr-40{margin-right:10rem}.md\:mb-40{margin-bottom:10rem}.md\:ml-40{margin-left:10rem}.md\:mt-48{margin-top:12rem}.md\:mr-48{margin-right:12rem}.md\:mb-48{margin-bottom:12rem}.md\:ml-48{margin-left:12rem}.md\:mt-56{margin-top:14rem}.md\:mr-56{margin-right:14rem}.md\:mb-56{margin-bottom:14rem}.md\:ml-56{margin-left:14rem}.md\:mt-64{margin-top:16rem}.md\:mr-64{margin-right:16rem}.md\:mb-64{margin-bottom:16rem}.md\:ml-64{margin-left:16rem}.md\:mt-auto{margin-top:auto}.md\:mr-auto{margin-right:auto}.md\:mb-auto{margin-bottom:auto}.md\:ml-auto{margin-left:auto}.md\:mt-px{margin-top:1px}.md\:mr-px{margin-right:1px}.md\:mb-px{margin-bottom:1px}.md\:ml-px{margin-left:1px}.md\:-mt-1{margin-top:-.25rem}.md\:-mr-1{margin-right:-.25rem}.md\:-mb-1{margin-bottom:-.25rem}.md\:-ml-1{margin-left:-.25rem}.md\:-mt-2{margin-top:-.5rem}.md\:-mr-2{margin-right:-.5rem}.md\:-mb-2{margin-bottom:-.5rem}.md\:-ml-2{margin-left:-.5rem}.md\:-mt-3{margin-top:-.75rem}.md\:-mr-3{margin-right:-.75rem}.md\:-mb-3{margin-bottom:-.75rem}.md\:-ml-3{margin-left:-.75rem}.md\:-mt-4{margin-top:-1rem}.md\:-mr-4{margin-right:-1rem}.md\:-mb-4{margin-bottom:-1rem}.md\:-ml-4{margin-left:-1rem}.md\:-mt-5{margin-top:-1.25rem}.md\:-mr-5{margin-right:-1.25rem}.md\:-mb-5{margin-bottom:-1.25rem}.md\:-ml-5{margin-left:-1.25rem}.md\:-mt-6{margin-top:-1.5rem}.md\:-mr-6{margin-right:-1.5rem}.md\:-mb-6{margin-bottom:-1.5rem}.md\:-ml-6{margin-left:-1.5rem}.md\:-mt-8{margin-top:-2rem}.md\:-mr-8{margin-right:-2rem}.md\:-mb-8{margin-bottom:-2rem}.md\:-ml-8{margin-left:-2rem}.md\:-mt-10{margin-top:-2.5rem}.md\:-mr-10{margin-right:-2.5rem}.md\:-mb-10{margin-bottom:-2.5rem}.md\:-ml-10{margin-left:-2.5rem}.md\:-mt-12{margin-top:-3rem}.md\:-mr-12{margin-right:-3rem}.md\:-mb-12{margin-bottom:-3rem}.md\:-ml-12{margin-left:-3rem}.md\:-mt-16{margin-top:-4rem}.md\:-mr-16{margin-right:-4rem}.md\:-mb-16{margin-bottom:-4rem}.md\:-ml-16{margin-left:-4rem}.md\:-mt-20{margin-top:-5rem}.md\:-mr-20{margin-right:-5rem}.md\:-mb-20{margin-bottom:-5rem}.md\:-ml-20{margin-left:-5rem}.md\:-mt-24{margin-top:-6rem}.md\:-mr-24{margin-right:-6rem}.md\:-mb-24{margin-bottom:-6rem}.md\:-ml-24{margin-left:-6rem}.md\:-mt-32{margin-top:-8rem}.md\:-mr-32{margin-right:-8rem}.md\:-mb-32{margin-bottom:-8rem}.md\:-ml-32{margin-left:-8rem}.md\:-mt-40{margin-top:-10rem}.md\:-mr-40{margin-right:-10rem}.md\:-mb-40{margin-bottom:-10rem}.md\:-ml-40{margin-left:-10rem}.md\:-mt-48{margin-top:-12rem}.md\:-mr-48{margin-right:-12rem}.md\:-mb-48{margin-bottom:-12rem}.md\:-ml-48{margin-left:-12rem}.md\:-mt-56{margin-top:-14rem}.md\:-mr-56{margin-right:-14rem}.md\:-mb-56{margin-bottom:-14rem}.md\:-ml-56{margin-left:-14rem}.md\:-mt-64{margin-top:-16rem}.md\:-mr-64{margin-right:-16rem}.md\:-mb-64{margin-bottom:-16rem}.md\:-ml-64{margin-left:-16rem}.md\:-mt-px{margin-top:-1px}.md\:-mr-px{margin-right:-1px}.md\:-mb-px{margin-bottom:-1px}.md\:-ml-px{margin-left:-1px}.md\:max-h-full{max-height:100%}.md\:max-h-screen{max-height:100vh}.md\:max-w-none{max-width:none}.md\:max-w-xs{max-width:20rem}.md\:max-w-sm{max-width:24rem}.md\:max-w-md{max-width:28rem}.md\:max-w-lg{max-width:32rem}.md\:max-w-xl{max-width:36rem}.md\:max-w-2xl{max-width:42rem}.md\:max-w-3xl{max-width:48rem}.md\:max-w-4xl{max-width:56rem}.md\:max-w-5xl{max-width:64rem}.md\:max-w-6xl{max-width:72rem}.md\:max-w-full{max-width:100%}.md\:max-w-screen-sm{max-width:640px}.md\:max-w-screen-md{max-width:768px}.md\:max-w-screen-lg{max-width:1024px}.md\:max-w-screen-xl{max-width:1280px}.md\:min-h-0{min-height:0}.md\:min-h-full{min-height:100%}.md\:min-h-screen{min-height:100vh}.md\:min-w-0{min-width:0}.md\:min-w-full{min-width:100%}.md\:object-contain{object-fit:contain}.md\:object-cover{object-fit:cover}.md\:object-fill{object-fit:fill}.md\:object-none{object-fit:none}.md\:object-scale-down{object-fit:scale-down}.md\:object-bottom{object-position:bottom}.md\:object-center{object-position:center}.md\:object-left{object-position:left}.md\:object-left-bottom{object-position:left bottom}.md\:object-left-top{object-position:left top}.md\:object-right{object-position:right}.md\:object-right-bottom{object-position:right bottom}.md\:object-right-top{object-position:right top}.md\:object-top{object-position:top}.md\:opacity-0{opacity:0}.md\:opacity-25{opacity:.25}.md\:opacity-50{opacity:.5}.md\:opacity-75{opacity:.75}.md\:opacity-100{opacity:1}.md\:hover\:opacity-0:hover{opacity:0}.md\:hover\:opacity-25:hover{opacity:.25}.md\:hover\:opacity-50:hover{opacity:.5}.md\:hover\:opacity-75:hover{opacity:.75}.md\:hover\:opacity-100:hover{opacity:1}.md\:focus\:opacity-0:focus{opacity:0}.md\:focus\:opacity-25:focus{opacity:.25}.md\:focus\:opacity-50:focus{opacity:.5}.md\:focus\:opacity-75:focus{opacity:.75}.md\:focus\:opacity-100:focus{opacity:1}.md\:outline-none{outline:2px solid transparent;outline-offset:2px}.md\:outline-white{outline:2px dotted #fff;outline-offset:2px}.md\:outline-black{outline:2px dotted #000;outline-offset:2px}.md\:focus\:outline-none:focus{outline:2px solid transparent;outline-offset:2px}.md\:focus\:outline-white:focus{outline:2px dotted #fff;outline-offset:2px}.md\:focus\:outline-black:focus{outline:2px dotted #000;outline-offset:2px}.md\:overflow-auto{overflow:auto}.md\:overflow-hidden{overflow:hidden}.md\:overflow-visible{overflow:visible}.md\:overflow-scroll{overflow:scroll}.md\:overflow-x-auto{overflow-x:auto}.md\:overflow-y-auto{overflow-y:auto}.md\:overflow-x-hidden{overflow-x:hidden}.md\:overflow-y-hidden{overflow-y:hidden}.md\:overflow-x-visible{overflow-x:visible}.md\:overflow-y-visible{overflow-y:visible}.md\:overflow-x-scroll{overflow-x:scroll}.md\:overflow-y-scroll{overflow-y:scroll}.md\:scrolling-touch{-webkit-overflow-scrolling:touch}.md\:scrolling-auto{-webkit-overflow-scrolling:auto}.md\:overscroll-auto{-ms-scroll-chaining:chained;overscroll-behavior:auto}.md\:overscroll-contain{-ms-scroll-chaining:none;overscroll-behavior:contain}.md\:overscroll-none{-ms-scroll-chaining:none;overscroll-behavior:none}.md\:overscroll-y-auto{overscroll-behavior-y:auto}.md\:overscroll-y-contain{overscroll-behavior-y:contain}.md\:overscroll-y-none{overscroll-behavior-y:none}.md\:overscroll-x-auto{overscroll-behavior-x:auto}.md\:overscroll-x-contain{overscroll-behavior-x:contain}.md\:overscroll-x-none{overscroll-behavior-x:none}.md\:p-0{padding:0}.md\:p-1{padding:.25rem}.md\:p-2{padding:.5rem}.md\:p-3{padding:.75rem}.md\:p-4{padding:1rem}.md\:p-5{padding:1.25rem}.md\:p-6{padding:1.5rem}.md\:p-8{padding:2rem}.md\:p-10{padding:2.5rem}.md\:p-12{padding:3rem}.md\:p-16{padding:4rem}.md\:p-20{padding:5rem}.md\:p-24{padding:6rem}.md\:p-32{padding:8rem}.md\:p-40{padding:10rem}.md\:p-48{padding:12rem}.md\:p-56{padding:14rem}.md\:p-64{padding:16rem}.md\:p-px{padding:1px}.md\:py-0{padding-top:0;padding-bottom:0}.md\:px-0{padding-left:0;padding-right:0}.md\:py-1{padding-top:.25rem;padding-bottom:.25rem}.md\:px-1{padding-left:.25rem;padding-right:.25rem}.md\:py-2{padding-top:.5rem;padding-bottom:.5rem}.md\:px-2{padding-left:.5rem;padding-right:.5rem}.md\:py-3{padding-top:.75rem;padding-bottom:.75rem}.md\:px-3{padding-left:.75rem;padding-right:.75rem}.md\:py-4{padding-top:1rem;padding-bottom:1rem}.md\:px-4{padding-left:1rem;padding-right:1rem}.md\:py-5{padding-top:1.25rem;padding-bottom:1.25rem}.md\:px-5{padding-left:1.25rem;padding-right:1.25rem}.md\:py-6{padding-top:1.5rem;padding-bottom:1.5rem}.md\:px-6{padding-left:1.5rem;padding-right:1.5rem}.md\:py-8{padding-top:2rem;padding-bottom:2rem}.md\:px-8{padding-left:2rem;padding-right:2rem}.md\:py-10{padding-top:2.5rem;padding-bottom:2.5rem}.md\:px-10{padding-left:2.5rem;padding-right:2.5rem}.md\:py-12{padding-top:3rem;padding-bottom:3rem}.md\:px-12{padding-left:3rem;padding-right:3rem}.md\:py-16{padding-top:4rem;padding-bottom:4rem}.md\:px-16{padding-left:4rem;padding-right:4rem}.md\:py-20{padding-top:5rem;padding-bottom:5rem}.md\:px-20{padding-left:5rem;padding-right:5rem}.md\:py-24{padding-top:6rem;padding-bottom:6rem}.md\:px-24{padding-left:6rem;padding-right:6rem}.md\:py-32{padding-top:8rem;padding-bottom:8rem}.md\:px-32{padding-left:8rem;padding-right:8rem}.md\:py-40{padding-top:10rem;padding-bottom:10rem}.md\:px-40{padding-left:10rem;padding-right:10rem}.md\:py-48{padding-top:12rem;padding-bottom:12rem}.md\:px-48{padding-left:12rem;padding-right:12rem}.md\:py-56{padding-top:14rem;padding-bottom:14rem}.md\:px-56{padding-left:14rem;padding-right:14rem}.md\:py-64{padding-top:16rem;padding-bottom:16rem}.md\:px-64{padding-left:16rem;padding-right:16rem}.md\:py-px{padding-top:1px;padding-bottom:1px}.md\:px-px{padding-left:1px;padding-right:1px}.md\:pt-0{padding-top:0}.md\:pr-0{padding-right:0}.md\:pb-0{padding-bottom:0}.md\:pl-0{padding-left:0}.md\:pt-1{padding-top:.25rem}.md\:pr-1{padding-right:.25rem}.md\:pb-1{padding-bottom:.25rem}.md\:pl-1{padding-left:.25rem}.md\:pt-2{padding-top:.5rem}.md\:pr-2{padding-right:.5rem}.md\:pb-2{padding-bottom:.5rem}.md\:pl-2{padding-left:.5rem}.md\:pt-3{padding-top:.75rem}.md\:pr-3{padding-right:.75rem}.md\:pb-3{padding-bottom:.75rem}.md\:pl-3{padding-left:.75rem}.md\:pt-4{padding-top:1rem}.md\:pr-4{padding-right:1rem}.md\:pb-4{padding-bottom:1rem}.md\:pl-4{padding-left:1rem}.md\:pt-5{padding-top:1.25rem}.md\:pr-5{padding-right:1.25rem}.md\:pb-5{padding-bottom:1.25rem}.md\:pl-5{padding-left:1.25rem}.md\:pt-6{padding-top:1.5rem}.md\:pr-6{padding-right:1.5rem}.md\:pb-6{padding-bottom:1.5rem}.md\:pl-6{padding-left:1.5rem}.md\:pt-8{padding-top:2rem}.md\:pr-8{padding-right:2rem}.md\:pb-8{padding-bottom:2rem}.md\:pl-8{padding-left:2rem}.md\:pt-10{padding-top:2.5rem}.md\:pr-10{padding-right:2.5rem}.md\:pb-10{padding-bottom:2.5rem}.md\:pl-10{padding-left:2.5rem}.md\:pt-12{padding-top:3rem}.md\:pr-12{padding-right:3rem}.md\:pb-12{padding-bottom:3rem}.md\:pl-12{padding-left:3rem}.md\:pt-16{padding-top:4rem}.md\:pr-16{padding-right:4rem}.md\:pb-16{padding-bottom:4rem}.md\:pl-16{padding-left:4rem}.md\:pt-20{padding-top:5rem}.md\:pr-20{padding-right:5rem}.md\:pb-20{padding-bottom:5rem}.md\:pl-20{padding-left:5rem}.md\:pt-24{padding-top:6rem}.md\:pr-24{padding-right:6rem}.md\:pb-24{padding-bottom:6rem}.md\:pl-24{padding-left:6rem}.md\:pt-32{padding-top:8rem}.md\:pr-32{padding-right:8rem}.md\:pb-32{padding-bottom:8rem}.md\:pl-32{padding-left:8rem}.md\:pt-40{padding-top:10rem}.md\:pr-40{padding-right:10rem}.md\:pb-40{padding-bottom:10rem}.md\:pl-40{padding-left:10rem}.md\:pt-48{padding-top:12rem}.md\:pr-48{padding-right:12rem}.md\:pb-48{padding-bottom:12rem}.md\:pl-48{padding-left:12rem}.md\:pt-56{padding-top:14rem}.md\:pr-56{padding-right:14rem}.md\:pb-56{padding-bottom:14rem}.md\:pl-56{padding-left:14rem}.md\:pt-64{padding-top:16rem}.md\:pr-64{padding-right:16rem}.md\:pb-64{padding-bottom:16rem}.md\:pl-64{padding-left:16rem}.md\:pt-px{padding-top:1px}.md\:pr-px{padding-right:1px}.md\:pb-px{padding-bottom:1px}.md\:pl-px{padding-left:1px}.md\:placeholder-transparent:-ms-input-placeholder{color:transparent}.md\:placeholder-transparent::-ms-input-placeholder{color:transparent}.md\:placeholder-transparent::placeholder{color:transparent}.md\:placeholder-current:-ms-input-placeholder{color:currentColor}.md\:placeholder-current::-ms-input-placeholder{color:currentColor}.md\:placeholder-current::placeholder{color:currentColor}.md\:placeholder-black:-ms-input-placeholder{--placeholder-opacity:1;color:#000;color:rgba(0,0,0,var(--placeholder-opacity))}.md\:placeholder-black::-ms-input-placeholder{--placeholder-opacity:1;color:#000;color:rgba(0,0,0,var(--placeholder-opacity))}.md\:placeholder-black::placeholder{--placeholder-opacity:1;color:#000;color:rgba(0,0,0,var(--placeholder-opacity))}.md\:placeholder-white:-ms-input-placeholder{--placeholder-opacity:1;color:#fff;color:rgba(255,255,255,var(--placeholder-opacity))}.md\:placeholder-white::-ms-input-placeholder{--placeholder-opacity:1;color:#fff;color:rgba(255,255,255,var(--placeholder-opacity))}.md\:placeholder-white::placeholder{--placeholder-opacity:1;color:#fff;color:rgba(255,255,255,var(--placeholder-opacity))}.md\:placeholder-gray-100:-ms-input-placeholder{--placeholder-opacity:1;color:#f7fafc;color:rgba(247,250,252,var(--placeholder-opacity))}.md\:placeholder-gray-100::-ms-input-placeholder{--placeholder-opacity:1;color:#f7fafc;color:rgba(247,250,252,var(--placeholder-opacity))}.md\:placeholder-gray-100::placeholder{--placeholder-opacity:1;color:#f7fafc;color:rgba(247,250,252,var(--placeholder-opacity))}.md\:placeholder-gray-200:-ms-input-placeholder{--placeholder-opacity:1;color:#edf2f7;color:rgba(237,242,247,var(--placeholder-opacity))}.md\:placeholder-gray-200::-ms-input-placeholder{--placeholder-opacity:1;color:#edf2f7;color:rgba(237,242,247,var(--placeholder-opacity))}.md\:placeholder-gray-200::placeholder{--placeholder-opacity:1;color:#edf2f7;color:rgba(237,242,247,var(--placeholder-opacity))}.md\:placeholder-gray-300:-ms-input-placeholder{--placeholder-opacity:1;color:#e2e8f0;color:rgba(226,232,240,var(--placeholder-opacity))}.md\:placeholder-gray-300::-ms-input-placeholder{--placeholder-opacity:1;color:#e2e8f0;color:rgba(226,232,240,var(--placeholder-opacity))}.md\:placeholder-gray-300::placeholder{--placeholder-opacity:1;color:#e2e8f0;color:rgba(226,232,240,var(--placeholder-opacity))}.md\:placeholder-gray-400:-ms-input-placeholder{--placeholder-opacity:1;color:#cbd5e0;color:rgba(203,213,224,var(--placeholder-opacity))}.md\:placeholder-gray-400::-ms-input-placeholder{--placeholder-opacity:1;color:#cbd5e0;color:rgba(203,213,224,var(--placeholder-opacity))}.md\:placeholder-gray-400::placeholder{--placeholder-opacity:1;color:#cbd5e0;color:rgba(203,213,224,var(--placeholder-opacity))}.md\:placeholder-gray-500:-ms-input-placeholder{--placeholder-opacity:1;color:#a0aec0;color:rgba(160,174,192,var(--placeholder-opacity))}.md\:placeholder-gray-500::-ms-input-placeholder{--placeholder-opacity:1;color:#a0aec0;color:rgba(160,174,192,var(--placeholder-opacity))}.md\:placeholder-gray-500::placeholder{--placeholder-opacity:1;color:#a0aec0;color:rgba(160,174,192,var(--placeholder-opacity))}.md\:placeholder-gray-600:-ms-input-placeholder{--placeholder-opacity:1;color:#718096;color:rgba(113,128,150,var(--placeholder-opacity))}.md\:placeholder-gray-600::-ms-input-placeholder{--placeholder-opacity:1;color:#718096;color:rgba(113,128,150,var(--placeholder-opacity))}.md\:placeholder-gray-600::placeholder{--placeholder-opacity:1;color:#718096;color:rgba(113,128,150,var(--placeholder-opacity))}.md\:placeholder-gray-700:-ms-input-placeholder{--placeholder-opacity:1;color:#4a5568;color:rgba(74,85,104,var(--placeholder-opacity))}.md\:placeholder-gray-700::-ms-input-placeholder{--placeholder-opacity:1;color:#4a5568;color:rgba(74,85,104,var(--placeholder-opacity))}.md\:placeholder-gray-700::placeholder{--placeholder-opacity:1;color:#4a5568;color:rgba(74,85,104,var(--placeholder-opacity))}.md\:placeholder-gray-800:-ms-input-placeholder{--placeholder-opacity:1;color:#2d3748;color:rgba(45,55,72,var(--placeholder-opacity))}.md\:placeholder-gray-800::-ms-input-placeholder{--placeholder-opacity:1;color:#2d3748;color:rgba(45,55,72,var(--placeholder-opacity))}.md\:placeholder-gray-800::placeholder{--placeholder-opacity:1;color:#2d3748;color:rgba(45,55,72,var(--placeholder-opacity))}.md\:placeholder-gray-900:-ms-input-placeholder{--placeholder-opacity:1;color:#1a202c;color:rgba(26,32,44,var(--placeholder-opacity))}.md\:placeholder-gray-900::-ms-input-placeholder{--placeholder-opacity:1;color:#1a202c;color:rgba(26,32,44,var(--placeholder-opacity))}.md\:placeholder-gray-900::placeholder{--placeholder-opacity:1;color:#1a202c;color:rgba(26,32,44,var(--placeholder-opacity))}.md\:placeholder-red-100:-ms-input-placeholder{--placeholder-opacity:1;color:#fff5f5;color:rgba(255,245,245,var(--placeholder-opacity))}.md\:placeholder-red-100::-ms-input-placeholder{--placeholder-opacity:1;color:#fff5f5;color:rgba(255,245,245,var(--placeholder-opacity))}.md\:placeholder-red-100::placeholder{--placeholder-opacity:1;color:#fff5f5;color:rgba(255,245,245,var(--placeholder-opacity))}.md\:placeholder-red-200:-ms-input-placeholder{--placeholder-opacity:1;color:#fed7d7;color:rgba(254,215,215,var(--placeholder-opacity))}.md\:placeholder-red-200::-ms-input-placeholder{--placeholder-opacity:1;color:#fed7d7;color:rgba(254,215,215,var(--placeholder-opacity))}.md\:placeholder-red-200::placeholder{--placeholder-opacity:1;color:#fed7d7;color:rgba(254,215,215,var(--placeholder-opacity))}.md\:placeholder-red-300:-ms-input-placeholder{--placeholder-opacity:1;color:#feb2b2;color:rgba(254,178,178,var(--placeholder-opacity))}.md\:placeholder-red-300::-ms-input-placeholder{--placeholder-opacity:1;color:#feb2b2;color:rgba(254,178,178,var(--placeholder-opacity))}.md\:placeholder-red-300::placeholder{--placeholder-opacity:1;color:#feb2b2;color:rgba(254,178,178,var(--placeholder-opacity))}.md\:placeholder-red-400:-ms-input-placeholder{--placeholder-opacity:1;color:#fc8181;color:rgba(252,129,129,var(--placeholder-opacity))}.md\:placeholder-red-400::-ms-input-placeholder{--placeholder-opacity:1;color:#fc8181;color:rgba(252,129,129,var(--placeholder-opacity))}.md\:placeholder-red-400::placeholder{--placeholder-opacity:1;color:#fc8181;color:rgba(252,129,129,var(--placeholder-opacity))}.md\:placeholder-red-500:-ms-input-placeholder{--placeholder-opacity:1;color:#f56565;color:rgba(245,101,101,var(--placeholder-opacity))}.md\:placeholder-red-500::-ms-input-placeholder{--placeholder-opacity:1;color:#f56565;color:rgba(245,101,101,var(--placeholder-opacity))}.md\:placeholder-red-500::placeholder{--placeholder-opacity:1;color:#f56565;color:rgba(245,101,101,var(--placeholder-opacity))}.md\:placeholder-red-600:-ms-input-placeholder{--placeholder-opacity:1;color:#e53e3e;color:rgba(229,62,62,var(--placeholder-opacity))}.md\:placeholder-red-600::-ms-input-placeholder{--placeholder-opacity:1;color:#e53e3e;color:rgba(229,62,62,var(--placeholder-opacity))}.md\:placeholder-red-600::placeholder{--placeholder-opacity:1;color:#e53e3e;color:rgba(229,62,62,var(--placeholder-opacity))}.md\:placeholder-red-700:-ms-input-placeholder{--placeholder-opacity:1;color:#c53030;color:rgba(197,48,48,var(--placeholder-opacity))}.md\:placeholder-red-700::-ms-input-placeholder{--placeholder-opacity:1;color:#c53030;color:rgba(197,48,48,var(--placeholder-opacity))}.md\:placeholder-red-700::placeholder{--placeholder-opacity:1;color:#c53030;color:rgba(197,48,48,var(--placeholder-opacity))}.md\:placeholder-red-800:-ms-input-placeholder{--placeholder-opacity:1;color:#9b2c2c;color:rgba(155,44,44,var(--placeholder-opacity))}.md\:placeholder-red-800::-ms-input-placeholder{--placeholder-opacity:1;color:#9b2c2c;color:rgba(155,44,44,var(--placeholder-opacity))}.md\:placeholder-red-800::placeholder{--placeholder-opacity:1;color:#9b2c2c;color:rgba(155,44,44,var(--placeholder-opacity))}.md\:placeholder-red-900:-ms-input-placeholder{--placeholder-opacity:1;color:#742a2a;color:rgba(116,42,42,var(--placeholder-opacity))}.md\:placeholder-red-900::-ms-input-placeholder{--placeholder-opacity:1;color:#742a2a;color:rgba(116,42,42,var(--placeholder-opacity))}.md\:placeholder-red-900::placeholder{--placeholder-opacity:1;color:#742a2a;color:rgba(116,42,42,var(--placeholder-opacity))}.md\:placeholder-orange-100:-ms-input-placeholder{--placeholder-opacity:1;color:#fffaf0;color:rgba(255,250,240,var(--placeholder-opacity))}.md\:placeholder-orange-100::-ms-input-placeholder{--placeholder-opacity:1;color:#fffaf0;color:rgba(255,250,240,var(--placeholder-opacity))}.md\:placeholder-orange-100::placeholder{--placeholder-opacity:1;color:#fffaf0;color:rgba(255,250,240,var(--placeholder-opacity))}.md\:placeholder-orange-200:-ms-input-placeholder{--placeholder-opacity:1;color:#feebc8;color:rgba(254,235,200,var(--placeholder-opacity))}.md\:placeholder-orange-200::-ms-input-placeholder{--placeholder-opacity:1;color:#feebc8;color:rgba(254,235,200,var(--placeholder-opacity))}.md\:placeholder-orange-200::placeholder{--placeholder-opacity:1;color:#feebc8;color:rgba(254,235,200,var(--placeholder-opacity))}.md\:placeholder-orange-300:-ms-input-placeholder{--placeholder-opacity:1;color:#fbd38d;color:rgba(251,211,141,var(--placeholder-opacity))}.md\:placeholder-orange-300::-ms-input-placeholder{--placeholder-opacity:1;color:#fbd38d;color:rgba(251,211,141,var(--placeholder-opacity))}.md\:placeholder-orange-300::placeholder{--placeholder-opacity:1;color:#fbd38d;color:rgba(251,211,141,var(--placeholder-opacity))}.md\:placeholder-orange-400:-ms-input-placeholder{--placeholder-opacity:1;color:#f6ad55;color:rgba(246,173,85,var(--placeholder-opacity))}.md\:placeholder-orange-400::-ms-input-placeholder{--placeholder-opacity:1;color:#f6ad55;color:rgba(246,173,85,var(--placeholder-opacity))}.md\:placeholder-orange-400::placeholder{--placeholder-opacity:1;color:#f6ad55;color:rgba(246,173,85,var(--placeholder-opacity))}.md\:placeholder-orange-500:-ms-input-placeholder{--placeholder-opacity:1;color:#ed8936;color:rgba(237,137,54,var(--placeholder-opacity))}.md\:placeholder-orange-500::-ms-input-placeholder{--placeholder-opacity:1;color:#ed8936;color:rgba(237,137,54,var(--placeholder-opacity))}.md\:placeholder-orange-500::placeholder{--placeholder-opacity:1;color:#ed8936;color:rgba(237,137,54,var(--placeholder-opacity))}.md\:placeholder-orange-600:-ms-input-placeholder{--placeholder-opacity:1;color:#dd6b20;color:rgba(221,107,32,var(--placeholder-opacity))}.md\:placeholder-orange-600::-ms-input-placeholder{--placeholder-opacity:1;color:#dd6b20;color:rgba(221,107,32,var(--placeholder-opacity))}.md\:placeholder-orange-600::placeholder{--placeholder-opacity:1;color:#dd6b20;color:rgba(221,107,32,var(--placeholder-opacity))}.md\:placeholder-orange-700:-ms-input-placeholder{--placeholder-opacity:1;color:#c05621;color:rgba(192,86,33,var(--placeholder-opacity))}.md\:placeholder-orange-700::-ms-input-placeholder{--placeholder-opacity:1;color:#c05621;color:rgba(192,86,33,var(--placeholder-opacity))}.md\:placeholder-orange-700::placeholder{--placeholder-opacity:1;color:#c05621;color:rgba(192,86,33,var(--placeholder-opacity))}.md\:placeholder-orange-800:-ms-input-placeholder{--placeholder-opacity:1;color:#9c4221;color:rgba(156,66,33,var(--placeholder-opacity))}.md\:placeholder-orange-800::-ms-input-placeholder{--placeholder-opacity:1;color:#9c4221;color:rgba(156,66,33,var(--placeholder-opacity))}.md\:placeholder-orange-800::placeholder{--placeholder-opacity:1;color:#9c4221;color:rgba(156,66,33,var(--placeholder-opacity))}.md\:placeholder-orange-900:-ms-input-placeholder{--placeholder-opacity:1;color:#7b341e;color:rgba(123,52,30,var(--placeholder-opacity))}.md\:placeholder-orange-900::-ms-input-placeholder{--placeholder-opacity:1;color:#7b341e;color:rgba(123,52,30,var(--placeholder-opacity))}.md\:placeholder-orange-900::placeholder{--placeholder-opacity:1;color:#7b341e;color:rgba(123,52,30,var(--placeholder-opacity))}.md\:placeholder-yellow-100:-ms-input-placeholder{--placeholder-opacity:1;color:ivory;color:rgba(255,255,240,var(--placeholder-opacity))}.md\:placeholder-yellow-100::-ms-input-placeholder{--placeholder-opacity:1;color:ivory;color:rgba(255,255,240,var(--placeholder-opacity))}.md\:placeholder-yellow-100::placeholder{--placeholder-opacity:1;color:ivory;color:rgba(255,255,240,var(--placeholder-opacity))}.md\:placeholder-yellow-200:-ms-input-placeholder{--placeholder-opacity:1;color:#fefcbf;color:rgba(254,252,191,var(--placeholder-opacity))}.md\:placeholder-yellow-200::-ms-input-placeholder{--placeholder-opacity:1;color:#fefcbf;color:rgba(254,252,191,var(--placeholder-opacity))}.md\:placeholder-yellow-200::placeholder{--placeholder-opacity:1;color:#fefcbf;color:rgba(254,252,191,var(--placeholder-opacity))}.md\:placeholder-yellow-300:-ms-input-placeholder{--placeholder-opacity:1;color:#faf089;color:rgba(250,240,137,var(--placeholder-opacity))}.md\:placeholder-yellow-300::-ms-input-placeholder{--placeholder-opacity:1;color:#faf089;color:rgba(250,240,137,var(--placeholder-opacity))}.md\:placeholder-yellow-300::placeholder{--placeholder-opacity:1;color:#faf089;color:rgba(250,240,137,var(--placeholder-opacity))}.md\:placeholder-yellow-400:-ms-input-placeholder{--placeholder-opacity:1;color:#f6e05e;color:rgba(246,224,94,var(--placeholder-opacity))}.md\:placeholder-yellow-400::-ms-input-placeholder{--placeholder-opacity:1;color:#f6e05e;color:rgba(246,224,94,var(--placeholder-opacity))}.md\:placeholder-yellow-400::placeholder{--placeholder-opacity:1;color:#f6e05e;color:rgba(246,224,94,var(--placeholder-opacity))}.md\:placeholder-yellow-500:-ms-input-placeholder{--placeholder-opacity:1;color:#ecc94b;color:rgba(236,201,75,var(--placeholder-opacity))}.md\:placeholder-yellow-500::-ms-input-placeholder{--placeholder-opacity:1;color:#ecc94b;color:rgba(236,201,75,var(--placeholder-opacity))}.md\:placeholder-yellow-500::placeholder{--placeholder-opacity:1;color:#ecc94b;color:rgba(236,201,75,var(--placeholder-opacity))}.md\:placeholder-yellow-600:-ms-input-placeholder{--placeholder-opacity:1;color:#d69e2e;color:rgba(214,158,46,var(--placeholder-opacity))}.md\:placeholder-yellow-600::-ms-input-placeholder{--placeholder-opacity:1;color:#d69e2e;color:rgba(214,158,46,var(--placeholder-opacity))}.md\:placeholder-yellow-600::placeholder{--placeholder-opacity:1;color:#d69e2e;color:rgba(214,158,46,var(--placeholder-opacity))}.md\:placeholder-yellow-700:-ms-input-placeholder{--placeholder-opacity:1;color:#b7791f;color:rgba(183,121,31,var(--placeholder-opacity))}.md\:placeholder-yellow-700::-ms-input-placeholder{--placeholder-opacity:1;color:#b7791f;color:rgba(183,121,31,var(--placeholder-opacity))}.md\:placeholder-yellow-700::placeholder{--placeholder-opacity:1;color:#b7791f;color:rgba(183,121,31,var(--placeholder-opacity))}.md\:placeholder-yellow-800:-ms-input-placeholder{--placeholder-opacity:1;color:#975a16;color:rgba(151,90,22,var(--placeholder-opacity))}.md\:placeholder-yellow-800::-ms-input-placeholder{--placeholder-opacity:1;color:#975a16;color:rgba(151,90,22,var(--placeholder-opacity))}.md\:placeholder-yellow-800::placeholder{--placeholder-opacity:1;color:#975a16;color:rgba(151,90,22,var(--placeholder-opacity))}.md\:placeholder-yellow-900:-ms-input-placeholder{--placeholder-opacity:1;color:#744210;color:rgba(116,66,16,var(--placeholder-opacity))}.md\:placeholder-yellow-900::-ms-input-placeholder{--placeholder-opacity:1;color:#744210;color:rgba(116,66,16,var(--placeholder-opacity))}.md\:placeholder-yellow-900::placeholder{--placeholder-opacity:1;color:#744210;color:rgba(116,66,16,var(--placeholder-opacity))}.md\:placeholder-green-100:-ms-input-placeholder{--placeholder-opacity:1;color:#f0fff4;color:rgba(240,255,244,var(--placeholder-opacity))}.md\:placeholder-green-100::-ms-input-placeholder{--placeholder-opacity:1;color:#f0fff4;color:rgba(240,255,244,var(--placeholder-opacity))}.md\:placeholder-green-100::placeholder{--placeholder-opacity:1;color:#f0fff4;color:rgba(240,255,244,var(--placeholder-opacity))}.md\:placeholder-green-200:-ms-input-placeholder{--placeholder-opacity:1;color:#c6f6d5;color:rgba(198,246,213,var(--placeholder-opacity))}.md\:placeholder-green-200::-ms-input-placeholder{--placeholder-opacity:1;color:#c6f6d5;color:rgba(198,246,213,var(--placeholder-opacity))}.md\:placeholder-green-200::placeholder{--placeholder-opacity:1;color:#c6f6d5;color:rgba(198,246,213,var(--placeholder-opacity))}.md\:placeholder-green-300:-ms-input-placeholder{--placeholder-opacity:1;color:#9ae6b4;color:rgba(154,230,180,var(--placeholder-opacity))}.md\:placeholder-green-300::-ms-input-placeholder{--placeholder-opacity:1;color:#9ae6b4;color:rgba(154,230,180,var(--placeholder-opacity))}.md\:placeholder-green-300::placeholder{--placeholder-opacity:1;color:#9ae6b4;color:rgba(154,230,180,var(--placeholder-opacity))}.md\:placeholder-green-400:-ms-input-placeholder{--placeholder-opacity:1;color:#68d391;color:rgba(104,211,145,var(--placeholder-opacity))}.md\:placeholder-green-400::-ms-input-placeholder{--placeholder-opacity:1;color:#68d391;color:rgba(104,211,145,var(--placeholder-opacity))}.md\:placeholder-green-400::placeholder{--placeholder-opacity:1;color:#68d391;color:rgba(104,211,145,var(--placeholder-opacity))}.md\:placeholder-green-500:-ms-input-placeholder{--placeholder-opacity:1;color:#48bb78;color:rgba(72,187,120,var(--placeholder-opacity))}.md\:placeholder-green-500::-ms-input-placeholder{--placeholder-opacity:1;color:#48bb78;color:rgba(72,187,120,var(--placeholder-opacity))}.md\:placeholder-green-500::placeholder{--placeholder-opacity:1;color:#48bb78;color:rgba(72,187,120,var(--placeholder-opacity))}.md\:placeholder-green-600:-ms-input-placeholder{--placeholder-opacity:1;color:#38a169;color:rgba(56,161,105,var(--placeholder-opacity))}.md\:placeholder-green-600::-ms-input-placeholder{--placeholder-opacity:1;color:#38a169;color:rgba(56,161,105,var(--placeholder-opacity))}.md\:placeholder-green-600::placeholder{--placeholder-opacity:1;color:#38a169;color:rgba(56,161,105,var(--placeholder-opacity))}.md\:placeholder-green-700:-ms-input-placeholder{--placeholder-opacity:1;color:#2f855a;color:rgba(47,133,90,var(--placeholder-opacity))}.md\:placeholder-green-700::-ms-input-placeholder{--placeholder-opacity:1;color:#2f855a;color:rgba(47,133,90,var(--placeholder-opacity))}.md\:placeholder-green-700::placeholder{--placeholder-opacity:1;color:#2f855a;color:rgba(47,133,90,var(--placeholder-opacity))}.md\:placeholder-green-800:-ms-input-placeholder{--placeholder-opacity:1;color:#276749;color:rgba(39,103,73,var(--placeholder-opacity))}.md\:placeholder-green-800::-ms-input-placeholder{--placeholder-opacity:1;color:#276749;color:rgba(39,103,73,var(--placeholder-opacity))}.md\:placeholder-green-800::placeholder{--placeholder-opacity:1;color:#276749;color:rgba(39,103,73,var(--placeholder-opacity))}.md\:placeholder-green-900:-ms-input-placeholder{--placeholder-opacity:1;color:#22543d;color:rgba(34,84,61,var(--placeholder-opacity))}.md\:placeholder-green-900::-ms-input-placeholder{--placeholder-opacity:1;color:#22543d;color:rgba(34,84,61,var(--placeholder-opacity))}.md\:placeholder-green-900::placeholder{--placeholder-opacity:1;color:#22543d;color:rgba(34,84,61,var(--placeholder-opacity))}.md\:placeholder-teal-100:-ms-input-placeholder{--placeholder-opacity:1;color:#e6fffa;color:rgba(230,255,250,var(--placeholder-opacity))}.md\:placeholder-teal-100::-ms-input-placeholder{--placeholder-opacity:1;color:#e6fffa;color:rgba(230,255,250,var(--placeholder-opacity))}.md\:placeholder-teal-100::placeholder{--placeholder-opacity:1;color:#e6fffa;color:rgba(230,255,250,var(--placeholder-opacity))}.md\:placeholder-teal-200:-ms-input-placeholder{--placeholder-opacity:1;color:#b2f5ea;color:rgba(178,245,234,var(--placeholder-opacity))}.md\:placeholder-teal-200::-ms-input-placeholder{--placeholder-opacity:1;color:#b2f5ea;color:rgba(178,245,234,var(--placeholder-opacity))}.md\:placeholder-teal-200::placeholder{--placeholder-opacity:1;color:#b2f5ea;color:rgba(178,245,234,var(--placeholder-opacity))}.md\:placeholder-teal-300:-ms-input-placeholder{--placeholder-opacity:1;color:#81e6d9;color:rgba(129,230,217,var(--placeholder-opacity))}.md\:placeholder-teal-300::-ms-input-placeholder{--placeholder-opacity:1;color:#81e6d9;color:rgba(129,230,217,var(--placeholder-opacity))}.md\:placeholder-teal-300::placeholder{--placeholder-opacity:1;color:#81e6d9;color:rgba(129,230,217,var(--placeholder-opacity))}.md\:placeholder-teal-400:-ms-input-placeholder{--placeholder-opacity:1;color:#4fd1c5;color:rgba(79,209,197,var(--placeholder-opacity))}.md\:placeholder-teal-400::-ms-input-placeholder{--placeholder-opacity:1;color:#4fd1c5;color:rgba(79,209,197,var(--placeholder-opacity))}.md\:placeholder-teal-400::placeholder{--placeholder-opacity:1;color:#4fd1c5;color:rgba(79,209,197,var(--placeholder-opacity))}.md\:placeholder-teal-500:-ms-input-placeholder{--placeholder-opacity:1;color:#38b2ac;color:rgba(56,178,172,var(--placeholder-opacity))}.md\:placeholder-teal-500::-ms-input-placeholder{--placeholder-opacity:1;color:#38b2ac;color:rgba(56,178,172,var(--placeholder-opacity))}.md\:placeholder-teal-500::placeholder{--placeholder-opacity:1;color:#38b2ac;color:rgba(56,178,172,var(--placeholder-opacity))}.md\:placeholder-teal-600:-ms-input-placeholder{--placeholder-opacity:1;color:#319795;color:rgba(49,151,149,var(--placeholder-opacity))}.md\:placeholder-teal-600::-ms-input-placeholder{--placeholder-opacity:1;color:#319795;color:rgba(49,151,149,var(--placeholder-opacity))}.md\:placeholder-teal-600::placeholder{--placeholder-opacity:1;color:#319795;color:rgba(49,151,149,var(--placeholder-opacity))}.md\:placeholder-teal-700:-ms-input-placeholder{--placeholder-opacity:1;color:#2c7a7b;color:rgba(44,122,123,var(--placeholder-opacity))}.md\:placeholder-teal-700::-ms-input-placeholder{--placeholder-opacity:1;color:#2c7a7b;color:rgba(44,122,123,var(--placeholder-opacity))}.md\:placeholder-teal-700::placeholder{--placeholder-opacity:1;color:#2c7a7b;color:rgba(44,122,123,var(--placeholder-opacity))}.md\:placeholder-teal-800:-ms-input-placeholder{--placeholder-opacity:1;color:#285e61;color:rgba(40,94,97,var(--placeholder-opacity))}.md\:placeholder-teal-800::-ms-input-placeholder{--placeholder-opacity:1;color:#285e61;color:rgba(40,94,97,var(--placeholder-opacity))}.md\:placeholder-teal-800::placeholder{--placeholder-opacity:1;color:#285e61;color:rgba(40,94,97,var(--placeholder-opacity))}.md\:placeholder-teal-900:-ms-input-placeholder{--placeholder-opacity:1;color:#234e52;color:rgba(35,78,82,var(--placeholder-opacity))}.md\:placeholder-teal-900::-ms-input-placeholder{--placeholder-opacity:1;color:#234e52;color:rgba(35,78,82,var(--placeholder-opacity))}.md\:placeholder-teal-900::placeholder{--placeholder-opacity:1;color:#234e52;color:rgba(35,78,82,var(--placeholder-opacity))}.md\:placeholder-blue-100:-ms-input-placeholder{--placeholder-opacity:1;color:#ebf8ff;color:rgba(235,248,255,var(--placeholder-opacity))}.md\:placeholder-blue-100::-ms-input-placeholder{--placeholder-opacity:1;color:#ebf8ff;color:rgba(235,248,255,var(--placeholder-opacity))}.md\:placeholder-blue-100::placeholder{--placeholder-opacity:1;color:#ebf8ff;color:rgba(235,248,255,var(--placeholder-opacity))}.md\:placeholder-blue-200:-ms-input-placeholder{--placeholder-opacity:1;color:#bee3f8;color:rgba(190,227,248,var(--placeholder-opacity))}.md\:placeholder-blue-200::-ms-input-placeholder{--placeholder-opacity:1;color:#bee3f8;color:rgba(190,227,248,var(--placeholder-opacity))}.md\:placeholder-blue-200::placeholder{--placeholder-opacity:1;color:#bee3f8;color:rgba(190,227,248,var(--placeholder-opacity))}.md\:placeholder-blue-300:-ms-input-placeholder{--placeholder-opacity:1;color:#90cdf4;color:rgba(144,205,244,var(--placeholder-opacity))}.md\:placeholder-blue-300::-ms-input-placeholder{--placeholder-opacity:1;color:#90cdf4;color:rgba(144,205,244,var(--placeholder-opacity))}.md\:placeholder-blue-300::placeholder{--placeholder-opacity:1;color:#90cdf4;color:rgba(144,205,244,var(--placeholder-opacity))}.md\:placeholder-blue-400:-ms-input-placeholder{--placeholder-opacity:1;color:#63b3ed;color:rgba(99,179,237,var(--placeholder-opacity))}.md\:placeholder-blue-400::-ms-input-placeholder{--placeholder-opacity:1;color:#63b3ed;color:rgba(99,179,237,var(--placeholder-opacity))}.md\:placeholder-blue-400::placeholder{--placeholder-opacity:1;color:#63b3ed;color:rgba(99,179,237,var(--placeholder-opacity))}.md\:placeholder-blue-500:-ms-input-placeholder{--placeholder-opacity:1;color:#4299e1;color:rgba(66,153,225,var(--placeholder-opacity))}.md\:placeholder-blue-500::-ms-input-placeholder{--placeholder-opacity:1;color:#4299e1;color:rgba(66,153,225,var(--placeholder-opacity))}.md\:placeholder-blue-500::placeholder{--placeholder-opacity:1;color:#4299e1;color:rgba(66,153,225,var(--placeholder-opacity))}.md\:placeholder-blue-600:-ms-input-placeholder{--placeholder-opacity:1;color:#3182ce;color:rgba(49,130,206,var(--placeholder-opacity))}.md\:placeholder-blue-600::-ms-input-placeholder{--placeholder-opacity:1;color:#3182ce;color:rgba(49,130,206,var(--placeholder-opacity))}.md\:placeholder-blue-600::placeholder{--placeholder-opacity:1;color:#3182ce;color:rgba(49,130,206,var(--placeholder-opacity))}.md\:placeholder-blue-700:-ms-input-placeholder{--placeholder-opacity:1;color:#2b6cb0;color:rgba(43,108,176,var(--placeholder-opacity))}.md\:placeholder-blue-700::-ms-input-placeholder{--placeholder-opacity:1;color:#2b6cb0;color:rgba(43,108,176,var(--placeholder-opacity))}.md\:placeholder-blue-700::placeholder{--placeholder-opacity:1;color:#2b6cb0;color:rgba(43,108,176,var(--placeholder-opacity))}.md\:placeholder-blue-800:-ms-input-placeholder{--placeholder-opacity:1;color:#2c5282;color:rgba(44,82,130,var(--placeholder-opacity))}.md\:placeholder-blue-800::-ms-input-placeholder{--placeholder-opacity:1;color:#2c5282;color:rgba(44,82,130,var(--placeholder-opacity))}.md\:placeholder-blue-800::placeholder{--placeholder-opacity:1;color:#2c5282;color:rgba(44,82,130,var(--placeholder-opacity))}.md\:placeholder-blue-900:-ms-input-placeholder{--placeholder-opacity:1;color:#2a4365;color:rgba(42,67,101,var(--placeholder-opacity))}.md\:placeholder-blue-900::-ms-input-placeholder{--placeholder-opacity:1;color:#2a4365;color:rgba(42,67,101,var(--placeholder-opacity))}.md\:placeholder-blue-900::placeholder{--placeholder-opacity:1;color:#2a4365;color:rgba(42,67,101,var(--placeholder-opacity))}.md\:placeholder-indigo-100:-ms-input-placeholder{--placeholder-opacity:1;color:#ebf4ff;color:rgba(235,244,255,var(--placeholder-opacity))}.md\:placeholder-indigo-100::-ms-input-placeholder{--placeholder-opacity:1;color:#ebf4ff;color:rgba(235,244,255,var(--placeholder-opacity))}.md\:placeholder-indigo-100::placeholder{--placeholder-opacity:1;color:#ebf4ff;color:rgba(235,244,255,var(--placeholder-opacity))}.md\:placeholder-indigo-200:-ms-input-placeholder{--placeholder-opacity:1;color:#c3dafe;color:rgba(195,218,254,var(--placeholder-opacity))}.md\:placeholder-indigo-200::-ms-input-placeholder{--placeholder-opacity:1;color:#c3dafe;color:rgba(195,218,254,var(--placeholder-opacity))}.md\:placeholder-indigo-200::placeholder{--placeholder-opacity:1;color:#c3dafe;color:rgba(195,218,254,var(--placeholder-opacity))}.md\:placeholder-indigo-300:-ms-input-placeholder{--placeholder-opacity:1;color:#a3bffa;color:rgba(163,191,250,var(--placeholder-opacity))}.md\:placeholder-indigo-300::-ms-input-placeholder{--placeholder-opacity:1;color:#a3bffa;color:rgba(163,191,250,var(--placeholder-opacity))}.md\:placeholder-indigo-300::placeholder{--placeholder-opacity:1;color:#a3bffa;color:rgba(163,191,250,var(--placeholder-opacity))}.md\:placeholder-indigo-400:-ms-input-placeholder{--placeholder-opacity:1;color:#7f9cf5;color:rgba(127,156,245,var(--placeholder-opacity))}.md\:placeholder-indigo-400::-ms-input-placeholder{--placeholder-opacity:1;color:#7f9cf5;color:rgba(127,156,245,var(--placeholder-opacity))}.md\:placeholder-indigo-400::placeholder{--placeholder-opacity:1;color:#7f9cf5;color:rgba(127,156,245,var(--placeholder-opacity))}.md\:placeholder-indigo-500:-ms-input-placeholder{--placeholder-opacity:1;color:#667eea;color:rgba(102,126,234,var(--placeholder-opacity))}.md\:placeholder-indigo-500::-ms-input-placeholder{--placeholder-opacity:1;color:#667eea;color:rgba(102,126,234,var(--placeholder-opacity))}.md\:placeholder-indigo-500::placeholder{--placeholder-opacity:1;color:#667eea;color:rgba(102,126,234,var(--placeholder-opacity))}.md\:placeholder-indigo-600:-ms-input-placeholder{--placeholder-opacity:1;color:#5a67d8;color:rgba(90,103,216,var(--placeholder-opacity))}.md\:placeholder-indigo-600::-ms-input-placeholder{--placeholder-opacity:1;color:#5a67d8;color:rgba(90,103,216,var(--placeholder-opacity))}.md\:placeholder-indigo-600::placeholder{--placeholder-opacity:1;color:#5a67d8;color:rgba(90,103,216,var(--placeholder-opacity))}.md\:placeholder-indigo-700:-ms-input-placeholder{--placeholder-opacity:1;color:#4c51bf;color:rgba(76,81,191,var(--placeholder-opacity))}.md\:placeholder-indigo-700::-ms-input-placeholder{--placeholder-opacity:1;color:#4c51bf;color:rgba(76,81,191,var(--placeholder-opacity))}.md\:placeholder-indigo-700::placeholder{--placeholder-opacity:1;color:#4c51bf;color:rgba(76,81,191,var(--placeholder-opacity))}.md\:placeholder-indigo-800:-ms-input-placeholder{--placeholder-opacity:1;color:#434190;color:rgba(67,65,144,var(--placeholder-opacity))}.md\:placeholder-indigo-800::-ms-input-placeholder{--placeholder-opacity:1;color:#434190;color:rgba(67,65,144,var(--placeholder-opacity))}.md\:placeholder-indigo-800::placeholder{--placeholder-opacity:1;color:#434190;color:rgba(67,65,144,var(--placeholder-opacity))}.md\:placeholder-indigo-900:-ms-input-placeholder{--placeholder-opacity:1;color:#3c366b;color:rgba(60,54,107,var(--placeholder-opacity))}.md\:placeholder-indigo-900::-ms-input-placeholder{--placeholder-opacity:1;color:#3c366b;color:rgba(60,54,107,var(--placeholder-opacity))}.md\:placeholder-indigo-900::placeholder{--placeholder-opacity:1;color:#3c366b;color:rgba(60,54,107,var(--placeholder-opacity))}.md\:placeholder-purple-100:-ms-input-placeholder{--placeholder-opacity:1;color:#faf5ff;color:rgba(250,245,255,var(--placeholder-opacity))}.md\:placeholder-purple-100::-ms-input-placeholder{--placeholder-opacity:1;color:#faf5ff;color:rgba(250,245,255,var(--placeholder-opacity))}.md\:placeholder-purple-100::placeholder{--placeholder-opacity:1;color:#faf5ff;color:rgba(250,245,255,var(--placeholder-opacity))}.md\:placeholder-purple-200:-ms-input-placeholder{--placeholder-opacity:1;color:#e9d8fd;color:rgba(233,216,253,var(--placeholder-opacity))}.md\:placeholder-purple-200::-ms-input-placeholder{--placeholder-opacity:1;color:#e9d8fd;color:rgba(233,216,253,var(--placeholder-opacity))}.md\:placeholder-purple-200::placeholder{--placeholder-opacity:1;color:#e9d8fd;color:rgba(233,216,253,var(--placeholder-opacity))}.md\:placeholder-purple-300:-ms-input-placeholder{--placeholder-opacity:1;color:#d6bcfa;color:rgba(214,188,250,var(--placeholder-opacity))}.md\:placeholder-purple-300::-ms-input-placeholder{--placeholder-opacity:1;color:#d6bcfa;color:rgba(214,188,250,var(--placeholder-opacity))}.md\:placeholder-purple-300::placeholder{--placeholder-opacity:1;color:#d6bcfa;color:rgba(214,188,250,var(--placeholder-opacity))}.md\:placeholder-purple-400:-ms-input-placeholder{--placeholder-opacity:1;color:#b794f4;color:rgba(183,148,244,var(--placeholder-opacity))}.md\:placeholder-purple-400::-ms-input-placeholder{--placeholder-opacity:1;color:#b794f4;color:rgba(183,148,244,var(--placeholder-opacity))}.md\:placeholder-purple-400::placeholder{--placeholder-opacity:1;color:#b794f4;color:rgba(183,148,244,var(--placeholder-opacity))}.md\:placeholder-purple-500:-ms-input-placeholder{--placeholder-opacity:1;color:#9f7aea;color:rgba(159,122,234,var(--placeholder-opacity))}.md\:placeholder-purple-500::-ms-input-placeholder{--placeholder-opacity:1;color:#9f7aea;color:rgba(159,122,234,var(--placeholder-opacity))}.md\:placeholder-purple-500::placeholder{--placeholder-opacity:1;color:#9f7aea;color:rgba(159,122,234,var(--placeholder-opacity))}.md\:placeholder-purple-600:-ms-input-placeholder{--placeholder-opacity:1;color:#805ad5;color:rgba(128,90,213,var(--placeholder-opacity))}.md\:placeholder-purple-600::-ms-input-placeholder{--placeholder-opacity:1;color:#805ad5;color:rgba(128,90,213,var(--placeholder-opacity))}.md\:placeholder-purple-600::placeholder{--placeholder-opacity:1;color:#805ad5;color:rgba(128,90,213,var(--placeholder-opacity))}.md\:placeholder-purple-700:-ms-input-placeholder{--placeholder-opacity:1;color:#6b46c1;color:rgba(107,70,193,var(--placeholder-opacity))}.md\:placeholder-purple-700::-ms-input-placeholder{--placeholder-opacity:1;color:#6b46c1;color:rgba(107,70,193,var(--placeholder-opacity))}.md\:placeholder-purple-700::placeholder{--placeholder-opacity:1;color:#6b46c1;color:rgba(107,70,193,var(--placeholder-opacity))}.md\:placeholder-purple-800:-ms-input-placeholder{--placeholder-opacity:1;color:#553c9a;color:rgba(85,60,154,var(--placeholder-opacity))}.md\:placeholder-purple-800::-ms-input-placeholder{--placeholder-opacity:1;color:#553c9a;color:rgba(85,60,154,var(--placeholder-opacity))}.md\:placeholder-purple-800::placeholder{--placeholder-opacity:1;color:#553c9a;color:rgba(85,60,154,var(--placeholder-opacity))}.md\:placeholder-purple-900:-ms-input-placeholder{--placeholder-opacity:1;color:#44337a;color:rgba(68,51,122,var(--placeholder-opacity))}.md\:placeholder-purple-900::-ms-input-placeholder{--placeholder-opacity:1;color:#44337a;color:rgba(68,51,122,var(--placeholder-opacity))}.md\:placeholder-purple-900::placeholder{--placeholder-opacity:1;color:#44337a;color:rgba(68,51,122,var(--placeholder-opacity))}.md\:placeholder-pink-100:-ms-input-placeholder{--placeholder-opacity:1;color:#fff5f7;color:rgba(255,245,247,var(--placeholder-opacity))}.md\:placeholder-pink-100::-ms-input-placeholder{--placeholder-opacity:1;color:#fff5f7;color:rgba(255,245,247,var(--placeholder-opacity))}.md\:placeholder-pink-100::placeholder{--placeholder-opacity:1;color:#fff5f7;color:rgba(255,245,247,var(--placeholder-opacity))}.md\:placeholder-pink-200:-ms-input-placeholder{--placeholder-opacity:1;color:#fed7e2;color:rgba(254,215,226,var(--placeholder-opacity))}.md\:placeholder-pink-200::-ms-input-placeholder{--placeholder-opacity:1;color:#fed7e2;color:rgba(254,215,226,var(--placeholder-opacity))}.md\:placeholder-pink-200::placeholder{--placeholder-opacity:1;color:#fed7e2;color:rgba(254,215,226,var(--placeholder-opacity))}.md\:placeholder-pink-300:-ms-input-placeholder{--placeholder-opacity:1;color:#fbb6ce;color:rgba(251,182,206,var(--placeholder-opacity))}.md\:placeholder-pink-300::-ms-input-placeholder{--placeholder-opacity:1;color:#fbb6ce;color:rgba(251,182,206,var(--placeholder-opacity))}.md\:placeholder-pink-300::placeholder{--placeholder-opacity:1;color:#fbb6ce;color:rgba(251,182,206,var(--placeholder-opacity))}.md\:placeholder-pink-400:-ms-input-placeholder{--placeholder-opacity:1;color:#f687b3;color:rgba(246,135,179,var(--placeholder-opacity))}.md\:placeholder-pink-400::-ms-input-placeholder{--placeholder-opacity:1;color:#f687b3;color:rgba(246,135,179,var(--placeholder-opacity))}.md\:placeholder-pink-400::placeholder{--placeholder-opacity:1;color:#f687b3;color:rgba(246,135,179,var(--placeholder-opacity))}.md\:placeholder-pink-500:-ms-input-placeholder{--placeholder-opacity:1;color:#ed64a6;color:rgba(237,100,166,var(--placeholder-opacity))}.md\:placeholder-pink-500::-ms-input-placeholder{--placeholder-opacity:1;color:#ed64a6;color:rgba(237,100,166,var(--placeholder-opacity))}.md\:placeholder-pink-500::placeholder{--placeholder-opacity:1;color:#ed64a6;color:rgba(237,100,166,var(--placeholder-opacity))}.md\:placeholder-pink-600:-ms-input-placeholder{--placeholder-opacity:1;color:#d53f8c;color:rgba(213,63,140,var(--placeholder-opacity))}.md\:placeholder-pink-600::-ms-input-placeholder{--placeholder-opacity:1;color:#d53f8c;color:rgba(213,63,140,var(--placeholder-opacity))}.md\:placeholder-pink-600::placeholder{--placeholder-opacity:1;color:#d53f8c;color:rgba(213,63,140,var(--placeholder-opacity))}.md\:placeholder-pink-700:-ms-input-placeholder{--placeholder-opacity:1;color:#b83280;color:rgba(184,50,128,var(--placeholder-opacity))}.md\:placeholder-pink-700::-ms-input-placeholder{--placeholder-opacity:1;color:#b83280;color:rgba(184,50,128,var(--placeholder-opacity))}.md\:placeholder-pink-700::placeholder{--placeholder-opacity:1;color:#b83280;color:rgba(184,50,128,var(--placeholder-opacity))}.md\:placeholder-pink-800:-ms-input-placeholder{--placeholder-opacity:1;color:#97266d;color:rgba(151,38,109,var(--placeholder-opacity))}.md\:placeholder-pink-800::-ms-input-placeholder{--placeholder-opacity:1;color:#97266d;color:rgba(151,38,109,var(--placeholder-opacity))}.md\:placeholder-pink-800::placeholder{--placeholder-opacity:1;color:#97266d;color:rgba(151,38,109,var(--placeholder-opacity))}.md\:placeholder-pink-900:-ms-input-placeholder{--placeholder-opacity:1;color:#702459;color:rgba(112,36,89,var(--placeholder-opacity))}.md\:placeholder-pink-900::-ms-input-placeholder{--placeholder-opacity:1;color:#702459;color:rgba(112,36,89,var(--placeholder-opacity))}.md\:placeholder-pink-900::placeholder{--placeholder-opacity:1;color:#702459;color:rgba(112,36,89,var(--placeholder-opacity))}.md\:focus\:placeholder-transparent:focus:-ms-input-placeholder{color:transparent}.md\:focus\:placeholder-transparent:focus::-ms-input-placeholder{color:transparent}.md\:focus\:placeholder-transparent:focus::placeholder{color:transparent}.md\:focus\:placeholder-current:focus:-ms-input-placeholder{color:currentColor}.md\:focus\:placeholder-current:focus::-ms-input-placeholder{color:currentColor}.md\:focus\:placeholder-current:focus::placeholder{color:currentColor}.md\:focus\:placeholder-black:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#000;color:rgba(0,0,0,var(--placeholder-opacity))}.md\:focus\:placeholder-black:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#000;color:rgba(0,0,0,var(--placeholder-opacity))}.md\:focus\:placeholder-black:focus::placeholder{--placeholder-opacity:1;color:#000;color:rgba(0,0,0,var(--placeholder-opacity))}.md\:focus\:placeholder-white:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#fff;color:rgba(255,255,255,var(--placeholder-opacity))}.md\:focus\:placeholder-white:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#fff;color:rgba(255,255,255,var(--placeholder-opacity))}.md\:focus\:placeholder-white:focus::placeholder{--placeholder-opacity:1;color:#fff;color:rgba(255,255,255,var(--placeholder-opacity))}.md\:focus\:placeholder-gray-100:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#f7fafc;color:rgba(247,250,252,var(--placeholder-opacity))}.md\:focus\:placeholder-gray-100:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#f7fafc;color:rgba(247,250,252,var(--placeholder-opacity))}.md\:focus\:placeholder-gray-100:focus::placeholder{--placeholder-opacity:1;color:#f7fafc;color:rgba(247,250,252,var(--placeholder-opacity))}.md\:focus\:placeholder-gray-200:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#edf2f7;color:rgba(237,242,247,var(--placeholder-opacity))}.md\:focus\:placeholder-gray-200:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#edf2f7;color:rgba(237,242,247,var(--placeholder-opacity))}.md\:focus\:placeholder-gray-200:focus::placeholder{--placeholder-opacity:1;color:#edf2f7;color:rgba(237,242,247,var(--placeholder-opacity))}.md\:focus\:placeholder-gray-300:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#e2e8f0;color:rgba(226,232,240,var(--placeholder-opacity))}.md\:focus\:placeholder-gray-300:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#e2e8f0;color:rgba(226,232,240,var(--placeholder-opacity))}.md\:focus\:placeholder-gray-300:focus::placeholder{--placeholder-opacity:1;color:#e2e8f0;color:rgba(226,232,240,var(--placeholder-opacity))}.md\:focus\:placeholder-gray-400:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#cbd5e0;color:rgba(203,213,224,var(--placeholder-opacity))}.md\:focus\:placeholder-gray-400:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#cbd5e0;color:rgba(203,213,224,var(--placeholder-opacity))}.md\:focus\:placeholder-gray-400:focus::placeholder{--placeholder-opacity:1;color:#cbd5e0;color:rgba(203,213,224,var(--placeholder-opacity))}.md\:focus\:placeholder-gray-500:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#a0aec0;color:rgba(160,174,192,var(--placeholder-opacity))}.md\:focus\:placeholder-gray-500:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#a0aec0;color:rgba(160,174,192,var(--placeholder-opacity))}.md\:focus\:placeholder-gray-500:focus::placeholder{--placeholder-opacity:1;color:#a0aec0;color:rgba(160,174,192,var(--placeholder-opacity))}.md\:focus\:placeholder-gray-600:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#718096;color:rgba(113,128,150,var(--placeholder-opacity))}.md\:focus\:placeholder-gray-600:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#718096;color:rgba(113,128,150,var(--placeholder-opacity))}.md\:focus\:placeholder-gray-600:focus::placeholder{--placeholder-opacity:1;color:#718096;color:rgba(113,128,150,var(--placeholder-opacity))}.md\:focus\:placeholder-gray-700:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#4a5568;color:rgba(74,85,104,var(--placeholder-opacity))}.md\:focus\:placeholder-gray-700:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#4a5568;color:rgba(74,85,104,var(--placeholder-opacity))}.md\:focus\:placeholder-gray-700:focus::placeholder{--placeholder-opacity:1;color:#4a5568;color:rgba(74,85,104,var(--placeholder-opacity))}.md\:focus\:placeholder-gray-800:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#2d3748;color:rgba(45,55,72,var(--placeholder-opacity))}.md\:focus\:placeholder-gray-800:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#2d3748;color:rgba(45,55,72,var(--placeholder-opacity))}.md\:focus\:placeholder-gray-800:focus::placeholder{--placeholder-opacity:1;color:#2d3748;color:rgba(45,55,72,var(--placeholder-opacity))}.md\:focus\:placeholder-gray-900:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#1a202c;color:rgba(26,32,44,var(--placeholder-opacity))}.md\:focus\:placeholder-gray-900:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#1a202c;color:rgba(26,32,44,var(--placeholder-opacity))}.md\:focus\:placeholder-gray-900:focus::placeholder{--placeholder-opacity:1;color:#1a202c;color:rgba(26,32,44,var(--placeholder-opacity))}.md\:focus\:placeholder-red-100:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#fff5f5;color:rgba(255,245,245,var(--placeholder-opacity))}.md\:focus\:placeholder-red-100:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#fff5f5;color:rgba(255,245,245,var(--placeholder-opacity))}.md\:focus\:placeholder-red-100:focus::placeholder{--placeholder-opacity:1;color:#fff5f5;color:rgba(255,245,245,var(--placeholder-opacity))}.md\:focus\:placeholder-red-200:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#fed7d7;color:rgba(254,215,215,var(--placeholder-opacity))}.md\:focus\:placeholder-red-200:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#fed7d7;color:rgba(254,215,215,var(--placeholder-opacity))}.md\:focus\:placeholder-red-200:focus::placeholder{--placeholder-opacity:1;color:#fed7d7;color:rgba(254,215,215,var(--placeholder-opacity))}.md\:focus\:placeholder-red-300:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#feb2b2;color:rgba(254,178,178,var(--placeholder-opacity))}.md\:focus\:placeholder-red-300:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#feb2b2;color:rgba(254,178,178,var(--placeholder-opacity))}.md\:focus\:placeholder-red-300:focus::placeholder{--placeholder-opacity:1;color:#feb2b2;color:rgba(254,178,178,var(--placeholder-opacity))}.md\:focus\:placeholder-red-400:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#fc8181;color:rgba(252,129,129,var(--placeholder-opacity))}.md\:focus\:placeholder-red-400:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#fc8181;color:rgba(252,129,129,var(--placeholder-opacity))}.md\:focus\:placeholder-red-400:focus::placeholder{--placeholder-opacity:1;color:#fc8181;color:rgba(252,129,129,var(--placeholder-opacity))}.md\:focus\:placeholder-red-500:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#f56565;color:rgba(245,101,101,var(--placeholder-opacity))}.md\:focus\:placeholder-red-500:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#f56565;color:rgba(245,101,101,var(--placeholder-opacity))}.md\:focus\:placeholder-red-500:focus::placeholder{--placeholder-opacity:1;color:#f56565;color:rgba(245,101,101,var(--placeholder-opacity))}.md\:focus\:placeholder-red-600:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#e53e3e;color:rgba(229,62,62,var(--placeholder-opacity))}.md\:focus\:placeholder-red-600:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#e53e3e;color:rgba(229,62,62,var(--placeholder-opacity))}.md\:focus\:placeholder-red-600:focus::placeholder{--placeholder-opacity:1;color:#e53e3e;color:rgba(229,62,62,var(--placeholder-opacity))}.md\:focus\:placeholder-red-700:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#c53030;color:rgba(197,48,48,var(--placeholder-opacity))}.md\:focus\:placeholder-red-700:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#c53030;color:rgba(197,48,48,var(--placeholder-opacity))}.md\:focus\:placeholder-red-700:focus::placeholder{--placeholder-opacity:1;color:#c53030;color:rgba(197,48,48,var(--placeholder-opacity))}.md\:focus\:placeholder-red-800:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#9b2c2c;color:rgba(155,44,44,var(--placeholder-opacity))}.md\:focus\:placeholder-red-800:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#9b2c2c;color:rgba(155,44,44,var(--placeholder-opacity))}.md\:focus\:placeholder-red-800:focus::placeholder{--placeholder-opacity:1;color:#9b2c2c;color:rgba(155,44,44,var(--placeholder-opacity))}.md\:focus\:placeholder-red-900:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#742a2a;color:rgba(116,42,42,var(--placeholder-opacity))}.md\:focus\:placeholder-red-900:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#742a2a;color:rgba(116,42,42,var(--placeholder-opacity))}.md\:focus\:placeholder-red-900:focus::placeholder{--placeholder-opacity:1;color:#742a2a;color:rgba(116,42,42,var(--placeholder-opacity))}.md\:focus\:placeholder-orange-100:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#fffaf0;color:rgba(255,250,240,var(--placeholder-opacity))}.md\:focus\:placeholder-orange-100:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#fffaf0;color:rgba(255,250,240,var(--placeholder-opacity))}.md\:focus\:placeholder-orange-100:focus::placeholder{--placeholder-opacity:1;color:#fffaf0;color:rgba(255,250,240,var(--placeholder-opacity))}.md\:focus\:placeholder-orange-200:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#feebc8;color:rgba(254,235,200,var(--placeholder-opacity))}.md\:focus\:placeholder-orange-200:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#feebc8;color:rgba(254,235,200,var(--placeholder-opacity))}.md\:focus\:placeholder-orange-200:focus::placeholder{--placeholder-opacity:1;color:#feebc8;color:rgba(254,235,200,var(--placeholder-opacity))}.md\:focus\:placeholder-orange-300:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#fbd38d;color:rgba(251,211,141,var(--placeholder-opacity))}.md\:focus\:placeholder-orange-300:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#fbd38d;color:rgba(251,211,141,var(--placeholder-opacity))}.md\:focus\:placeholder-orange-300:focus::placeholder{--placeholder-opacity:1;color:#fbd38d;color:rgba(251,211,141,var(--placeholder-opacity))}.md\:focus\:placeholder-orange-400:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#f6ad55;color:rgba(246,173,85,var(--placeholder-opacity))}.md\:focus\:placeholder-orange-400:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#f6ad55;color:rgba(246,173,85,var(--placeholder-opacity))}.md\:focus\:placeholder-orange-400:focus::placeholder{--placeholder-opacity:1;color:#f6ad55;color:rgba(246,173,85,var(--placeholder-opacity))}.md\:focus\:placeholder-orange-500:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#ed8936;color:rgba(237,137,54,var(--placeholder-opacity))}.md\:focus\:placeholder-orange-500:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#ed8936;color:rgba(237,137,54,var(--placeholder-opacity))}.md\:focus\:placeholder-orange-500:focus::placeholder{--placeholder-opacity:1;color:#ed8936;color:rgba(237,137,54,var(--placeholder-opacity))}.md\:focus\:placeholder-orange-600:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#dd6b20;color:rgba(221,107,32,var(--placeholder-opacity))}.md\:focus\:placeholder-orange-600:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#dd6b20;color:rgba(221,107,32,var(--placeholder-opacity))}.md\:focus\:placeholder-orange-600:focus::placeholder{--placeholder-opacity:1;color:#dd6b20;color:rgba(221,107,32,var(--placeholder-opacity))}.md\:focus\:placeholder-orange-700:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#c05621;color:rgba(192,86,33,var(--placeholder-opacity))}.md\:focus\:placeholder-orange-700:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#c05621;color:rgba(192,86,33,var(--placeholder-opacity))}.md\:focus\:placeholder-orange-700:focus::placeholder{--placeholder-opacity:1;color:#c05621;color:rgba(192,86,33,var(--placeholder-opacity))}.md\:focus\:placeholder-orange-800:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#9c4221;color:rgba(156,66,33,var(--placeholder-opacity))}.md\:focus\:placeholder-orange-800:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#9c4221;color:rgba(156,66,33,var(--placeholder-opacity))}.md\:focus\:placeholder-orange-800:focus::placeholder{--placeholder-opacity:1;color:#9c4221;color:rgba(156,66,33,var(--placeholder-opacity))}.md\:focus\:placeholder-orange-900:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#7b341e;color:rgba(123,52,30,var(--placeholder-opacity))}.md\:focus\:placeholder-orange-900:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#7b341e;color:rgba(123,52,30,var(--placeholder-opacity))}.md\:focus\:placeholder-orange-900:focus::placeholder{--placeholder-opacity:1;color:#7b341e;color:rgba(123,52,30,var(--placeholder-opacity))}.md\:focus\:placeholder-yellow-100:focus:-ms-input-placeholder{--placeholder-opacity:1;color:ivory;color:rgba(255,255,240,var(--placeholder-opacity))}.md\:focus\:placeholder-yellow-100:focus::-ms-input-placeholder{--placeholder-opacity:1;color:ivory;color:rgba(255,255,240,var(--placeholder-opacity))}.md\:focus\:placeholder-yellow-100:focus::placeholder{--placeholder-opacity:1;color:ivory;color:rgba(255,255,240,var(--placeholder-opacity))}.md\:focus\:placeholder-yellow-200:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#fefcbf;color:rgba(254,252,191,var(--placeholder-opacity))}.md\:focus\:placeholder-yellow-200:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#fefcbf;color:rgba(254,252,191,var(--placeholder-opacity))}.md\:focus\:placeholder-yellow-200:focus::placeholder{--placeholder-opacity:1;color:#fefcbf;color:rgba(254,252,191,var(--placeholder-opacity))}.md\:focus\:placeholder-yellow-300:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#faf089;color:rgba(250,240,137,var(--placeholder-opacity))}.md\:focus\:placeholder-yellow-300:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#faf089;color:rgba(250,240,137,var(--placeholder-opacity))}.md\:focus\:placeholder-yellow-300:focus::placeholder{--placeholder-opacity:1;color:#faf089;color:rgba(250,240,137,var(--placeholder-opacity))}.md\:focus\:placeholder-yellow-400:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#f6e05e;color:rgba(246,224,94,var(--placeholder-opacity))}.md\:focus\:placeholder-yellow-400:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#f6e05e;color:rgba(246,224,94,var(--placeholder-opacity))}.md\:focus\:placeholder-yellow-400:focus::placeholder{--placeholder-opacity:1;color:#f6e05e;color:rgba(246,224,94,var(--placeholder-opacity))}.md\:focus\:placeholder-yellow-500:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#ecc94b;color:rgba(236,201,75,var(--placeholder-opacity))}.md\:focus\:placeholder-yellow-500:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#ecc94b;color:rgba(236,201,75,var(--placeholder-opacity))}.md\:focus\:placeholder-yellow-500:focus::placeholder{--placeholder-opacity:1;color:#ecc94b;color:rgba(236,201,75,var(--placeholder-opacity))}.md\:focus\:placeholder-yellow-600:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#d69e2e;color:rgba(214,158,46,var(--placeholder-opacity))}.md\:focus\:placeholder-yellow-600:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#d69e2e;color:rgba(214,158,46,var(--placeholder-opacity))}.md\:focus\:placeholder-yellow-600:focus::placeholder{--placeholder-opacity:1;color:#d69e2e;color:rgba(214,158,46,var(--placeholder-opacity))}.md\:focus\:placeholder-yellow-700:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#b7791f;color:rgba(183,121,31,var(--placeholder-opacity))}.md\:focus\:placeholder-yellow-700:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#b7791f;color:rgba(183,121,31,var(--placeholder-opacity))}.md\:focus\:placeholder-yellow-700:focus::placeholder{--placeholder-opacity:1;color:#b7791f;color:rgba(183,121,31,var(--placeholder-opacity))}.md\:focus\:placeholder-yellow-800:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#975a16;color:rgba(151,90,22,var(--placeholder-opacity))}.md\:focus\:placeholder-yellow-800:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#975a16;color:rgba(151,90,22,var(--placeholder-opacity))}.md\:focus\:placeholder-yellow-800:focus::placeholder{--placeholder-opacity:1;color:#975a16;color:rgba(151,90,22,var(--placeholder-opacity))}.md\:focus\:placeholder-yellow-900:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#744210;color:rgba(116,66,16,var(--placeholder-opacity))}.md\:focus\:placeholder-yellow-900:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#744210;color:rgba(116,66,16,var(--placeholder-opacity))}.md\:focus\:placeholder-yellow-900:focus::placeholder{--placeholder-opacity:1;color:#744210;color:rgba(116,66,16,var(--placeholder-opacity))}.md\:focus\:placeholder-green-100:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#f0fff4;color:rgba(240,255,244,var(--placeholder-opacity))}.md\:focus\:placeholder-green-100:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#f0fff4;color:rgba(240,255,244,var(--placeholder-opacity))}.md\:focus\:placeholder-green-100:focus::placeholder{--placeholder-opacity:1;color:#f0fff4;color:rgba(240,255,244,var(--placeholder-opacity))}.md\:focus\:placeholder-green-200:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#c6f6d5;color:rgba(198,246,213,var(--placeholder-opacity))}.md\:focus\:placeholder-green-200:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#c6f6d5;color:rgba(198,246,213,var(--placeholder-opacity))}.md\:focus\:placeholder-green-200:focus::placeholder{--placeholder-opacity:1;color:#c6f6d5;color:rgba(198,246,213,var(--placeholder-opacity))}.md\:focus\:placeholder-green-300:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#9ae6b4;color:rgba(154,230,180,var(--placeholder-opacity))}.md\:focus\:placeholder-green-300:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#9ae6b4;color:rgba(154,230,180,var(--placeholder-opacity))}.md\:focus\:placeholder-green-300:focus::placeholder{--placeholder-opacity:1;color:#9ae6b4;color:rgba(154,230,180,var(--placeholder-opacity))}.md\:focus\:placeholder-green-400:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#68d391;color:rgba(104,211,145,var(--placeholder-opacity))}.md\:focus\:placeholder-green-400:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#68d391;color:rgba(104,211,145,var(--placeholder-opacity))}.md\:focus\:placeholder-green-400:focus::placeholder{--placeholder-opacity:1;color:#68d391;color:rgba(104,211,145,var(--placeholder-opacity))}.md\:focus\:placeholder-green-500:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#48bb78;color:rgba(72,187,120,var(--placeholder-opacity))}.md\:focus\:placeholder-green-500:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#48bb78;color:rgba(72,187,120,var(--placeholder-opacity))}.md\:focus\:placeholder-green-500:focus::placeholder{--placeholder-opacity:1;color:#48bb78;color:rgba(72,187,120,var(--placeholder-opacity))}.md\:focus\:placeholder-green-600:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#38a169;color:rgba(56,161,105,var(--placeholder-opacity))}.md\:focus\:placeholder-green-600:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#38a169;color:rgba(56,161,105,var(--placeholder-opacity))}.md\:focus\:placeholder-green-600:focus::placeholder{--placeholder-opacity:1;color:#38a169;color:rgba(56,161,105,var(--placeholder-opacity))}.md\:focus\:placeholder-green-700:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#2f855a;color:rgba(47,133,90,var(--placeholder-opacity))}.md\:focus\:placeholder-green-700:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#2f855a;color:rgba(47,133,90,var(--placeholder-opacity))}.md\:focus\:placeholder-green-700:focus::placeholder{--placeholder-opacity:1;color:#2f855a;color:rgba(47,133,90,var(--placeholder-opacity))}.md\:focus\:placeholder-green-800:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#276749;color:rgba(39,103,73,var(--placeholder-opacity))}.md\:focus\:placeholder-green-800:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#276749;color:rgba(39,103,73,var(--placeholder-opacity))}.md\:focus\:placeholder-green-800:focus::placeholder{--placeholder-opacity:1;color:#276749;color:rgba(39,103,73,var(--placeholder-opacity))}.md\:focus\:placeholder-green-900:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#22543d;color:rgba(34,84,61,var(--placeholder-opacity))}.md\:focus\:placeholder-green-900:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#22543d;color:rgba(34,84,61,var(--placeholder-opacity))}.md\:focus\:placeholder-green-900:focus::placeholder{--placeholder-opacity:1;color:#22543d;color:rgba(34,84,61,var(--placeholder-opacity))}.md\:focus\:placeholder-teal-100:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#e6fffa;color:rgba(230,255,250,var(--placeholder-opacity))}.md\:focus\:placeholder-teal-100:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#e6fffa;color:rgba(230,255,250,var(--placeholder-opacity))}.md\:focus\:placeholder-teal-100:focus::placeholder{--placeholder-opacity:1;color:#e6fffa;color:rgba(230,255,250,var(--placeholder-opacity))}.md\:focus\:placeholder-teal-200:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#b2f5ea;color:rgba(178,245,234,var(--placeholder-opacity))}.md\:focus\:placeholder-teal-200:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#b2f5ea;color:rgba(178,245,234,var(--placeholder-opacity))}.md\:focus\:placeholder-teal-200:focus::placeholder{--placeholder-opacity:1;color:#b2f5ea;color:rgba(178,245,234,var(--placeholder-opacity))}.md\:focus\:placeholder-teal-300:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#81e6d9;color:rgba(129,230,217,var(--placeholder-opacity))}.md\:focus\:placeholder-teal-300:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#81e6d9;color:rgba(129,230,217,var(--placeholder-opacity))}.md\:focus\:placeholder-teal-300:focus::placeholder{--placeholder-opacity:1;color:#81e6d9;color:rgba(129,230,217,var(--placeholder-opacity))}.md\:focus\:placeholder-teal-400:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#4fd1c5;color:rgba(79,209,197,var(--placeholder-opacity))}.md\:focus\:placeholder-teal-400:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#4fd1c5;color:rgba(79,209,197,var(--placeholder-opacity))}.md\:focus\:placeholder-teal-400:focus::placeholder{--placeholder-opacity:1;color:#4fd1c5;color:rgba(79,209,197,var(--placeholder-opacity))}.md\:focus\:placeholder-teal-500:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#38b2ac;color:rgba(56,178,172,var(--placeholder-opacity))}.md\:focus\:placeholder-teal-500:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#38b2ac;color:rgba(56,178,172,var(--placeholder-opacity))}.md\:focus\:placeholder-teal-500:focus::placeholder{--placeholder-opacity:1;color:#38b2ac;color:rgba(56,178,172,var(--placeholder-opacity))}.md\:focus\:placeholder-teal-600:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#319795;color:rgba(49,151,149,var(--placeholder-opacity))}.md\:focus\:placeholder-teal-600:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#319795;color:rgba(49,151,149,var(--placeholder-opacity))}.md\:focus\:placeholder-teal-600:focus::placeholder{--placeholder-opacity:1;color:#319795;color:rgba(49,151,149,var(--placeholder-opacity))}.md\:focus\:placeholder-teal-700:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#2c7a7b;color:rgba(44,122,123,var(--placeholder-opacity))}.md\:focus\:placeholder-teal-700:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#2c7a7b;color:rgba(44,122,123,var(--placeholder-opacity))}.md\:focus\:placeholder-teal-700:focus::placeholder{--placeholder-opacity:1;color:#2c7a7b;color:rgba(44,122,123,var(--placeholder-opacity))}.md\:focus\:placeholder-teal-800:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#285e61;color:rgba(40,94,97,var(--placeholder-opacity))}.md\:focus\:placeholder-teal-800:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#285e61;color:rgba(40,94,97,var(--placeholder-opacity))}.md\:focus\:placeholder-teal-800:focus::placeholder{--placeholder-opacity:1;color:#285e61;color:rgba(40,94,97,var(--placeholder-opacity))}.md\:focus\:placeholder-teal-900:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#234e52;color:rgba(35,78,82,var(--placeholder-opacity))}.md\:focus\:placeholder-teal-900:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#234e52;color:rgba(35,78,82,var(--placeholder-opacity))}.md\:focus\:placeholder-teal-900:focus::placeholder{--placeholder-opacity:1;color:#234e52;color:rgba(35,78,82,var(--placeholder-opacity))}.md\:focus\:placeholder-blue-100:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#ebf8ff;color:rgba(235,248,255,var(--placeholder-opacity))}.md\:focus\:placeholder-blue-100:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#ebf8ff;color:rgba(235,248,255,var(--placeholder-opacity))}.md\:focus\:placeholder-blue-100:focus::placeholder{--placeholder-opacity:1;color:#ebf8ff;color:rgba(235,248,255,var(--placeholder-opacity))}.md\:focus\:placeholder-blue-200:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#bee3f8;color:rgba(190,227,248,var(--placeholder-opacity))}.md\:focus\:placeholder-blue-200:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#bee3f8;color:rgba(190,227,248,var(--placeholder-opacity))}.md\:focus\:placeholder-blue-200:focus::placeholder{--placeholder-opacity:1;color:#bee3f8;color:rgba(190,227,248,var(--placeholder-opacity))}.md\:focus\:placeholder-blue-300:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#90cdf4;color:rgba(144,205,244,var(--placeholder-opacity))}.md\:focus\:placeholder-blue-300:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#90cdf4;color:rgba(144,205,244,var(--placeholder-opacity))}.md\:focus\:placeholder-blue-300:focus::placeholder{--placeholder-opacity:1;color:#90cdf4;color:rgba(144,205,244,var(--placeholder-opacity))}.md\:focus\:placeholder-blue-400:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#63b3ed;color:rgba(99,179,237,var(--placeholder-opacity))}.md\:focus\:placeholder-blue-400:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#63b3ed;color:rgba(99,179,237,var(--placeholder-opacity))}.md\:focus\:placeholder-blue-400:focus::placeholder{--placeholder-opacity:1;color:#63b3ed;color:rgba(99,179,237,var(--placeholder-opacity))}.md\:focus\:placeholder-blue-500:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#4299e1;color:rgba(66,153,225,var(--placeholder-opacity))}.md\:focus\:placeholder-blue-500:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#4299e1;color:rgba(66,153,225,var(--placeholder-opacity))}.md\:focus\:placeholder-blue-500:focus::placeholder{--placeholder-opacity:1;color:#4299e1;color:rgba(66,153,225,var(--placeholder-opacity))}.md\:focus\:placeholder-blue-600:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#3182ce;color:rgba(49,130,206,var(--placeholder-opacity))}.md\:focus\:placeholder-blue-600:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#3182ce;color:rgba(49,130,206,var(--placeholder-opacity))}.md\:focus\:placeholder-blue-600:focus::placeholder{--placeholder-opacity:1;color:#3182ce;color:rgba(49,130,206,var(--placeholder-opacity))}.md\:focus\:placeholder-blue-700:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#2b6cb0;color:rgba(43,108,176,var(--placeholder-opacity))}.md\:focus\:placeholder-blue-700:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#2b6cb0;color:rgba(43,108,176,var(--placeholder-opacity))}.md\:focus\:placeholder-blue-700:focus::placeholder{--placeholder-opacity:1;color:#2b6cb0;color:rgba(43,108,176,var(--placeholder-opacity))}.md\:focus\:placeholder-blue-800:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#2c5282;color:rgba(44,82,130,var(--placeholder-opacity))}.md\:focus\:placeholder-blue-800:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#2c5282;color:rgba(44,82,130,var(--placeholder-opacity))}.md\:focus\:placeholder-blue-800:focus::placeholder{--placeholder-opacity:1;color:#2c5282;color:rgba(44,82,130,var(--placeholder-opacity))}.md\:focus\:placeholder-blue-900:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#2a4365;color:rgba(42,67,101,var(--placeholder-opacity))}.md\:focus\:placeholder-blue-900:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#2a4365;color:rgba(42,67,101,var(--placeholder-opacity))}.md\:focus\:placeholder-blue-900:focus::placeholder{--placeholder-opacity:1;color:#2a4365;color:rgba(42,67,101,var(--placeholder-opacity))}.md\:focus\:placeholder-indigo-100:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#ebf4ff;color:rgba(235,244,255,var(--placeholder-opacity))}.md\:focus\:placeholder-indigo-100:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#ebf4ff;color:rgba(235,244,255,var(--placeholder-opacity))}.md\:focus\:placeholder-indigo-100:focus::placeholder{--placeholder-opacity:1;color:#ebf4ff;color:rgba(235,244,255,var(--placeholder-opacity))}.md\:focus\:placeholder-indigo-200:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#c3dafe;color:rgba(195,218,254,var(--placeholder-opacity))}.md\:focus\:placeholder-indigo-200:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#c3dafe;color:rgba(195,218,254,var(--placeholder-opacity))}.md\:focus\:placeholder-indigo-200:focus::placeholder{--placeholder-opacity:1;color:#c3dafe;color:rgba(195,218,254,var(--placeholder-opacity))}.md\:focus\:placeholder-indigo-300:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#a3bffa;color:rgba(163,191,250,var(--placeholder-opacity))}.md\:focus\:placeholder-indigo-300:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#a3bffa;color:rgba(163,191,250,var(--placeholder-opacity))}.md\:focus\:placeholder-indigo-300:focus::placeholder{--placeholder-opacity:1;color:#a3bffa;color:rgba(163,191,250,var(--placeholder-opacity))}.md\:focus\:placeholder-indigo-400:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#7f9cf5;color:rgba(127,156,245,var(--placeholder-opacity))}.md\:focus\:placeholder-indigo-400:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#7f9cf5;color:rgba(127,156,245,var(--placeholder-opacity))}.md\:focus\:placeholder-indigo-400:focus::placeholder{--placeholder-opacity:1;color:#7f9cf5;color:rgba(127,156,245,var(--placeholder-opacity))}.md\:focus\:placeholder-indigo-500:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#667eea;color:rgba(102,126,234,var(--placeholder-opacity))}.md\:focus\:placeholder-indigo-500:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#667eea;color:rgba(102,126,234,var(--placeholder-opacity))}.md\:focus\:placeholder-indigo-500:focus::placeholder{--placeholder-opacity:1;color:#667eea;color:rgba(102,126,234,var(--placeholder-opacity))}.md\:focus\:placeholder-indigo-600:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#5a67d8;color:rgba(90,103,216,var(--placeholder-opacity))}.md\:focus\:placeholder-indigo-600:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#5a67d8;color:rgba(90,103,216,var(--placeholder-opacity))}.md\:focus\:placeholder-indigo-600:focus::placeholder{--placeholder-opacity:1;color:#5a67d8;color:rgba(90,103,216,var(--placeholder-opacity))}.md\:focus\:placeholder-indigo-700:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#4c51bf;color:rgba(76,81,191,var(--placeholder-opacity))}.md\:focus\:placeholder-indigo-700:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#4c51bf;color:rgba(76,81,191,var(--placeholder-opacity))}.md\:focus\:placeholder-indigo-700:focus::placeholder{--placeholder-opacity:1;color:#4c51bf;color:rgba(76,81,191,var(--placeholder-opacity))}.md\:focus\:placeholder-indigo-800:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#434190;color:rgba(67,65,144,var(--placeholder-opacity))}.md\:focus\:placeholder-indigo-800:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#434190;color:rgba(67,65,144,var(--placeholder-opacity))}.md\:focus\:placeholder-indigo-800:focus::placeholder{--placeholder-opacity:1;color:#434190;color:rgba(67,65,144,var(--placeholder-opacity))}.md\:focus\:placeholder-indigo-900:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#3c366b;color:rgba(60,54,107,var(--placeholder-opacity))}.md\:focus\:placeholder-indigo-900:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#3c366b;color:rgba(60,54,107,var(--placeholder-opacity))}.md\:focus\:placeholder-indigo-900:focus::placeholder{--placeholder-opacity:1;color:#3c366b;color:rgba(60,54,107,var(--placeholder-opacity))}.md\:focus\:placeholder-purple-100:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#faf5ff;color:rgba(250,245,255,var(--placeholder-opacity))}.md\:focus\:placeholder-purple-100:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#faf5ff;color:rgba(250,245,255,var(--placeholder-opacity))}.md\:focus\:placeholder-purple-100:focus::placeholder{--placeholder-opacity:1;color:#faf5ff;color:rgba(250,245,255,var(--placeholder-opacity))}.md\:focus\:placeholder-purple-200:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#e9d8fd;color:rgba(233,216,253,var(--placeholder-opacity))}.md\:focus\:placeholder-purple-200:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#e9d8fd;color:rgba(233,216,253,var(--placeholder-opacity))}.md\:focus\:placeholder-purple-200:focus::placeholder{--placeholder-opacity:1;color:#e9d8fd;color:rgba(233,216,253,var(--placeholder-opacity))}.md\:focus\:placeholder-purple-300:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#d6bcfa;color:rgba(214,188,250,var(--placeholder-opacity))}.md\:focus\:placeholder-purple-300:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#d6bcfa;color:rgba(214,188,250,var(--placeholder-opacity))}.md\:focus\:placeholder-purple-300:focus::placeholder{--placeholder-opacity:1;color:#d6bcfa;color:rgba(214,188,250,var(--placeholder-opacity))}.md\:focus\:placeholder-purple-400:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#b794f4;color:rgba(183,148,244,var(--placeholder-opacity))}.md\:focus\:placeholder-purple-400:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#b794f4;color:rgba(183,148,244,var(--placeholder-opacity))}.md\:focus\:placeholder-purple-400:focus::placeholder{--placeholder-opacity:1;color:#b794f4;color:rgba(183,148,244,var(--placeholder-opacity))}.md\:focus\:placeholder-purple-500:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#9f7aea;color:rgba(159,122,234,var(--placeholder-opacity))}.md\:focus\:placeholder-purple-500:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#9f7aea;color:rgba(159,122,234,var(--placeholder-opacity))}.md\:focus\:placeholder-purple-500:focus::placeholder{--placeholder-opacity:1;color:#9f7aea;color:rgba(159,122,234,var(--placeholder-opacity))}.md\:focus\:placeholder-purple-600:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#805ad5;color:rgba(128,90,213,var(--placeholder-opacity))}.md\:focus\:placeholder-purple-600:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#805ad5;color:rgba(128,90,213,var(--placeholder-opacity))}.md\:focus\:placeholder-purple-600:focus::placeholder{--placeholder-opacity:1;color:#805ad5;color:rgba(128,90,213,var(--placeholder-opacity))}.md\:focus\:placeholder-purple-700:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#6b46c1;color:rgba(107,70,193,var(--placeholder-opacity))}.md\:focus\:placeholder-purple-700:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#6b46c1;color:rgba(107,70,193,var(--placeholder-opacity))}.md\:focus\:placeholder-purple-700:focus::placeholder{--placeholder-opacity:1;color:#6b46c1;color:rgba(107,70,193,var(--placeholder-opacity))}.md\:focus\:placeholder-purple-800:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#553c9a;color:rgba(85,60,154,var(--placeholder-opacity))}.md\:focus\:placeholder-purple-800:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#553c9a;color:rgba(85,60,154,var(--placeholder-opacity))}.md\:focus\:placeholder-purple-800:focus::placeholder{--placeholder-opacity:1;color:#553c9a;color:rgba(85,60,154,var(--placeholder-opacity))}.md\:focus\:placeholder-purple-900:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#44337a;color:rgba(68,51,122,var(--placeholder-opacity))}.md\:focus\:placeholder-purple-900:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#44337a;color:rgba(68,51,122,var(--placeholder-opacity))}.md\:focus\:placeholder-purple-900:focus::placeholder{--placeholder-opacity:1;color:#44337a;color:rgba(68,51,122,var(--placeholder-opacity))}.md\:focus\:placeholder-pink-100:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#fff5f7;color:rgba(255,245,247,var(--placeholder-opacity))}.md\:focus\:placeholder-pink-100:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#fff5f7;color:rgba(255,245,247,var(--placeholder-opacity))}.md\:focus\:placeholder-pink-100:focus::placeholder{--placeholder-opacity:1;color:#fff5f7;color:rgba(255,245,247,var(--placeholder-opacity))}.md\:focus\:placeholder-pink-200:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#fed7e2;color:rgba(254,215,226,var(--placeholder-opacity))}.md\:focus\:placeholder-pink-200:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#fed7e2;color:rgba(254,215,226,var(--placeholder-opacity))}.md\:focus\:placeholder-pink-200:focus::placeholder{--placeholder-opacity:1;color:#fed7e2;color:rgba(254,215,226,var(--placeholder-opacity))}.md\:focus\:placeholder-pink-300:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#fbb6ce;color:rgba(251,182,206,var(--placeholder-opacity))}.md\:focus\:placeholder-pink-300:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#fbb6ce;color:rgba(251,182,206,var(--placeholder-opacity))}.md\:focus\:placeholder-pink-300:focus::placeholder{--placeholder-opacity:1;color:#fbb6ce;color:rgba(251,182,206,var(--placeholder-opacity))}.md\:focus\:placeholder-pink-400:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#f687b3;color:rgba(246,135,179,var(--placeholder-opacity))}.md\:focus\:placeholder-pink-400:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#f687b3;color:rgba(246,135,179,var(--placeholder-opacity))}.md\:focus\:placeholder-pink-400:focus::placeholder{--placeholder-opacity:1;color:#f687b3;color:rgba(246,135,179,var(--placeholder-opacity))}.md\:focus\:placeholder-pink-500:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#ed64a6;color:rgba(237,100,166,var(--placeholder-opacity))}.md\:focus\:placeholder-pink-500:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#ed64a6;color:rgba(237,100,166,var(--placeholder-opacity))}.md\:focus\:placeholder-pink-500:focus::placeholder{--placeholder-opacity:1;color:#ed64a6;color:rgba(237,100,166,var(--placeholder-opacity))}.md\:focus\:placeholder-pink-600:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#d53f8c;color:rgba(213,63,140,var(--placeholder-opacity))}.md\:focus\:placeholder-pink-600:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#d53f8c;color:rgba(213,63,140,var(--placeholder-opacity))}.md\:focus\:placeholder-pink-600:focus::placeholder{--placeholder-opacity:1;color:#d53f8c;color:rgba(213,63,140,var(--placeholder-opacity))}.md\:focus\:placeholder-pink-700:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#b83280;color:rgba(184,50,128,var(--placeholder-opacity))}.md\:focus\:placeholder-pink-700:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#b83280;color:rgba(184,50,128,var(--placeholder-opacity))}.md\:focus\:placeholder-pink-700:focus::placeholder{--placeholder-opacity:1;color:#b83280;color:rgba(184,50,128,var(--placeholder-opacity))}.md\:focus\:placeholder-pink-800:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#97266d;color:rgba(151,38,109,var(--placeholder-opacity))}.md\:focus\:placeholder-pink-800:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#97266d;color:rgba(151,38,109,var(--placeholder-opacity))}.md\:focus\:placeholder-pink-800:focus::placeholder{--placeholder-opacity:1;color:#97266d;color:rgba(151,38,109,var(--placeholder-opacity))}.md\:focus\:placeholder-pink-900:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#702459;color:rgba(112,36,89,var(--placeholder-opacity))}.md\:focus\:placeholder-pink-900:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#702459;color:rgba(112,36,89,var(--placeholder-opacity))}.md\:focus\:placeholder-pink-900:focus::placeholder{--placeholder-opacity:1;color:#702459;color:rgba(112,36,89,var(--placeholder-opacity))}.md\:placeholder-opacity-0:-ms-input-placeholder{--placeholder-opacity:0}.md\:placeholder-opacity-0::-ms-input-placeholder{--placeholder-opacity:0}.md\:placeholder-opacity-0::placeholder{--placeholder-opacity:0}.md\:placeholder-opacity-25:-ms-input-placeholder{--placeholder-opacity:0.25}.md\:placeholder-opacity-25::-ms-input-placeholder{--placeholder-opacity:0.25}.md\:placeholder-opacity-25::placeholder{--placeholder-opacity:0.25}.md\:placeholder-opacity-50:-ms-input-placeholder{--placeholder-opacity:0.5}.md\:placeholder-opacity-50::-ms-input-placeholder{--placeholder-opacity:0.5}.md\:placeholder-opacity-50::placeholder{--placeholder-opacity:0.5}.md\:placeholder-opacity-75:-ms-input-placeholder{--placeholder-opacity:0.75}.md\:placeholder-opacity-75::-ms-input-placeholder{--placeholder-opacity:0.75}.md\:placeholder-opacity-75::placeholder{--placeholder-opacity:0.75}.md\:placeholder-opacity-100:-ms-input-placeholder{--placeholder-opacity:1}.md\:placeholder-opacity-100::-ms-input-placeholder{--placeholder-opacity:1}.md\:placeholder-opacity-100::placeholder{--placeholder-opacity:1}.md\:focus\:placeholder-opacity-0:focus:-ms-input-placeholder{--placeholder-opacity:0}.md\:focus\:placeholder-opacity-0:focus::-ms-input-placeholder{--placeholder-opacity:0}.md\:focus\:placeholder-opacity-0:focus::placeholder{--placeholder-opacity:0}.md\:focus\:placeholder-opacity-25:focus:-ms-input-placeholder{--placeholder-opacity:0.25}.md\:focus\:placeholder-opacity-25:focus::-ms-input-placeholder{--placeholder-opacity:0.25}.md\:focus\:placeholder-opacity-25:focus::placeholder{--placeholder-opacity:0.25}.md\:focus\:placeholder-opacity-50:focus:-ms-input-placeholder{--placeholder-opacity:0.5}.md\:focus\:placeholder-opacity-50:focus::-ms-input-placeholder{--placeholder-opacity:0.5}.md\:focus\:placeholder-opacity-50:focus::placeholder{--placeholder-opacity:0.5}.md\:focus\:placeholder-opacity-75:focus:-ms-input-placeholder{--placeholder-opacity:0.75}.md\:focus\:placeholder-opacity-75:focus::-ms-input-placeholder{--placeholder-opacity:0.75}.md\:focus\:placeholder-opacity-75:focus::placeholder{--placeholder-opacity:0.75}.md\:focus\:placeholder-opacity-100:focus:-ms-input-placeholder{--placeholder-opacity:1}.md\:focus\:placeholder-opacity-100:focus::-ms-input-placeholder{--placeholder-opacity:1}.md\:focus\:placeholder-opacity-100:focus::placeholder{--placeholder-opacity:1}.md\:pointer-events-none{pointer-events:none}.md\:pointer-events-auto{pointer-events:auto}.md\:static{position:static}.md\:fixed{position:fixed}.md\:absolute{position:absolute}.md\:relative{position:relative}.md\:sticky{position:-webkit-sticky;position:sticky}.md\:inset-0{top:0;right:0;bottom:0;left:0}.md\:inset-auto{top:auto;right:auto;bottom:auto;left:auto}.md\:inset-y-0{top:0;bottom:0}.md\:inset-x-0{right:0;left:0}.md\:inset-y-auto{top:auto;bottom:auto}.md\:inset-x-auto{right:auto;left:auto}.md\:top-0{top:0}.md\:right-0{right:0}.md\:bottom-0{bottom:0}.md\:left-0{left:0}.md\:top-auto{top:auto}.md\:right-auto{right:auto}.md\:bottom-auto{bottom:auto}.md\:left-auto{left:auto}.md\:resize-none{resize:none}.md\:resize-y{resize:vertical}.md\:resize-x{resize:horizontal}.md\:resize{resize:both}.md\:shadow-xs{box-shadow:0 0 0 1px rgba(0,0,0,.05)}.md\:shadow-sm{box-shadow:0 1px 2px 0 rgba(0,0,0,.05)}.md\:shadow{box-shadow:0 1px 3px 0 rgba(0,0,0,.1),0 1px 2px 0 rgba(0,0,0,.06)}.md\:shadow-md{box-shadow:0 4px 6px -1px rgba(0,0,0,.1),0 2px 4px -1px rgba(0,0,0,.06)}.md\:shadow-lg{box-shadow:0 10px 15px -3px rgba(0,0,0,.1),0 4px 6px -2px rgba(0,0,0,.05)}.md\:shadow-xl{box-shadow:0 20px 25px -5px rgba(0,0,0,.1),0 10px 10px -5px rgba(0,0,0,.04)}.md\:shadow-2xl{box-shadow:0 25px 50px -12px rgba(0,0,0,.25)}.md\:shadow-inner{box-shadow:inset 0 2px 4px 0 rgba(0,0,0,.06)}.md\:shadow-outline{box-shadow:0 0 0 3px rgba(66,153,225,.5)}.md\:shadow-none{box-shadow:none}.md\:hover\:shadow-xs:hover{box-shadow:0 0 0 1px rgba(0,0,0,.05)}.md\:hover\:shadow-sm:hover{box-shadow:0 1px 2px 0 rgba(0,0,0,.05)}.md\:hover\:shadow:hover{box-shadow:0 1px 3px 0 rgba(0,0,0,.1),0 1px 2px 0 rgba(0,0,0,.06)}.md\:hover\:shadow-md:hover{box-shadow:0 4px 6px -1px rgba(0,0,0,.1),0 2px 4px -1px rgba(0,0,0,.06)}.md\:hover\:shadow-lg:hover{box-shadow:0 10px 15px -3px rgba(0,0,0,.1),0 4px 6px -2px rgba(0,0,0,.05)}.md\:hover\:shadow-xl:hover{box-shadow:0 20px 25px -5px rgba(0,0,0,.1),0 10px 10px -5px rgba(0,0,0,.04)}.md\:hover\:shadow-2xl:hover{box-shadow:0 25px 50px -12px rgba(0,0,0,.25)}.md\:hover\:shadow-inner:hover{box-shadow:inset 0 2px 4px 0 rgba(0,0,0,.06)}.md\:hover\:shadow-outline:hover{box-shadow:0 0 0 3px rgba(66,153,225,.5)}.md\:hover\:shadow-none:hover{box-shadow:none}.md\:focus\:shadow-xs:focus{box-shadow:0 0 0 1px rgba(0,0,0,.05)}.md\:focus\:shadow-sm:focus{box-shadow:0 1px 2px 0 rgba(0,0,0,.05)}.md\:focus\:shadow:focus{box-shadow:0 1px 3px 0 rgba(0,0,0,.1),0 1px 2px 0 rgba(0,0,0,.06)}.md\:focus\:shadow-md:focus{box-shadow:0 4px 6px -1px rgba(0,0,0,.1),0 2px 4px -1px rgba(0,0,0,.06)}.md\:focus\:shadow-lg:focus{box-shadow:0 10px 15px -3px rgba(0,0,0,.1),0 4px 6px -2px rgba(0,0,0,.05)}.md\:focus\:shadow-xl:focus{box-shadow:0 20px 25px -5px rgba(0,0,0,.1),0 10px 10px -5px rgba(0,0,0,.04)}.md\:focus\:shadow-2xl:focus{box-shadow:0 25px 50px -12px rgba(0,0,0,.25)}.md\:focus\:shadow-inner:focus{box-shadow:inset 0 2px 4px 0 rgba(0,0,0,.06)}.md\:focus\:shadow-outline:focus{box-shadow:0 0 0 3px rgba(66,153,225,.5)}.md\:focus\:shadow-none:focus{box-shadow:none}.md\:fill-current{fill:currentColor}.md\:stroke-current{stroke:currentColor}.md\:stroke-0{stroke-width:0}.md\:stroke-1{stroke-width:1}.md\:stroke-2{stroke-width:2}.md\:table-auto{table-layout:auto}.md\:table-fixed{table-layout:fixed}.md\:text-left{text-align:left}.md\:text-center{text-align:center}.md\:text-right{text-align:right}.md\:text-justify{text-align:justify}.md\:text-transparent{color:transparent}.md\:text-current{color:currentColor}.md\:text-black{--text-opacity:1;color:#000;color:rgba(0,0,0,var(--text-opacity))}.md\:text-white{--text-opacity:1;color:#fff;color:rgba(255,255,255,var(--text-opacity))}.md\:text-gray-100{--text-opacity:1;color:#f7fafc;color:rgba(247,250,252,var(--text-opacity))}.md\:text-gray-200{--text-opacity:1;color:#edf2f7;color:rgba(237,242,247,var(--text-opacity))}.md\:text-gray-300{--text-opacity:1;color:#e2e8f0;color:rgba(226,232,240,var(--text-opacity))}.md\:text-gray-400{--text-opacity:1;color:#cbd5e0;color:rgba(203,213,224,var(--text-opacity))}.md\:text-gray-500{--text-opacity:1;color:#a0aec0;color:rgba(160,174,192,var(--text-opacity))}.md\:text-gray-600{--text-opacity:1;color:#718096;color:rgba(113,128,150,var(--text-opacity))}.md\:text-gray-700{--text-opacity:1;color:#4a5568;color:rgba(74,85,104,var(--text-opacity))}.md\:text-gray-800{--text-opacity:1;color:#2d3748;color:rgba(45,55,72,var(--text-opacity))}.md\:text-gray-900{--text-opacity:1;color:#1a202c;color:rgba(26,32,44,var(--text-opacity))}.md\:text-red-100{--text-opacity:1;color:#fff5f5;color:rgba(255,245,245,var(--text-opacity))}.md\:text-red-200{--text-opacity:1;color:#fed7d7;color:rgba(254,215,215,var(--text-opacity))}.md\:text-red-300{--text-opacity:1;color:#feb2b2;color:rgba(254,178,178,var(--text-opacity))}.md\:text-red-400{--text-opacity:1;color:#fc8181;color:rgba(252,129,129,var(--text-opacity))}.md\:text-red-500{--text-opacity:1;color:#f56565;color:rgba(245,101,101,var(--text-opacity))}.md\:text-red-600{--text-opacity:1;color:#e53e3e;color:rgba(229,62,62,var(--text-opacity))}.md\:text-red-700{--text-opacity:1;color:#c53030;color:rgba(197,48,48,var(--text-opacity))}.md\:text-red-800{--text-opacity:1;color:#9b2c2c;color:rgba(155,44,44,var(--text-opacity))}.md\:text-red-900{--text-opacity:1;color:#742a2a;color:rgba(116,42,42,var(--text-opacity))}.md\:text-orange-100{--text-opacity:1;color:#fffaf0;color:rgba(255,250,240,var(--text-opacity))}.md\:text-orange-200{--text-opacity:1;color:#feebc8;color:rgba(254,235,200,var(--text-opacity))}.md\:text-orange-300{--text-opacity:1;color:#fbd38d;color:rgba(251,211,141,var(--text-opacity))}.md\:text-orange-400{--text-opacity:1;color:#f6ad55;color:rgba(246,173,85,var(--text-opacity))}.md\:text-orange-500{--text-opacity:1;color:#ed8936;color:rgba(237,137,54,var(--text-opacity))}.md\:text-orange-600{--text-opacity:1;color:#dd6b20;color:rgba(221,107,32,var(--text-opacity))}.md\:text-orange-700{--text-opacity:1;color:#c05621;color:rgba(192,86,33,var(--text-opacity))}.md\:text-orange-800{--text-opacity:1;color:#9c4221;color:rgba(156,66,33,var(--text-opacity))}.md\:text-orange-900{--text-opacity:1;color:#7b341e;color:rgba(123,52,30,var(--text-opacity))}.md\:text-yellow-100{--text-opacity:1;color:ivory;color:rgba(255,255,240,var(--text-opacity))}.md\:text-yellow-200{--text-opacity:1;color:#fefcbf;color:rgba(254,252,191,var(--text-opacity))}.md\:text-yellow-300{--text-opacity:1;color:#faf089;color:rgba(250,240,137,var(--text-opacity))}.md\:text-yellow-400{--text-opacity:1;color:#f6e05e;color:rgba(246,224,94,var(--text-opacity))}.md\:text-yellow-500{--text-opacity:1;color:#ecc94b;color:rgba(236,201,75,var(--text-opacity))}.md\:text-yellow-600{--text-opacity:1;color:#d69e2e;color:rgba(214,158,46,var(--text-opacity))}.md\:text-yellow-700{--text-opacity:1;color:#b7791f;color:rgba(183,121,31,var(--text-opacity))}.md\:text-yellow-800{--text-opacity:1;color:#975a16;color:rgba(151,90,22,var(--text-opacity))}.md\:text-yellow-900{--text-opacity:1;color:#744210;color:rgba(116,66,16,var(--text-opacity))}.md\:text-green-100{--text-opacity:1;color:#f0fff4;color:rgba(240,255,244,var(--text-opacity))}.md\:text-green-200{--text-opacity:1;color:#c6f6d5;color:rgba(198,246,213,var(--text-opacity))}.md\:text-green-300{--text-opacity:1;color:#9ae6b4;color:rgba(154,230,180,var(--text-opacity))}.md\:text-green-400{--text-opacity:1;color:#68d391;color:rgba(104,211,145,var(--text-opacity))}.md\:text-green-500{--text-opacity:1;color:#48bb78;color:rgba(72,187,120,var(--text-opacity))}.md\:text-green-600{--text-opacity:1;color:#38a169;color:rgba(56,161,105,var(--text-opacity))}.md\:text-green-700{--text-opacity:1;color:#2f855a;color:rgba(47,133,90,var(--text-opacity))}.md\:text-green-800{--text-opacity:1;color:#276749;color:rgba(39,103,73,var(--text-opacity))}.md\:text-green-900{--text-opacity:1;color:#22543d;color:rgba(34,84,61,var(--text-opacity))}.md\:text-teal-100{--text-opacity:1;color:#e6fffa;color:rgba(230,255,250,var(--text-opacity))}.md\:text-teal-200{--text-opacity:1;color:#b2f5ea;color:rgba(178,245,234,var(--text-opacity))}.md\:text-teal-300{--text-opacity:1;color:#81e6d9;color:rgba(129,230,217,var(--text-opacity))}.md\:text-teal-400{--text-opacity:1;color:#4fd1c5;color:rgba(79,209,197,var(--text-opacity))}.md\:text-teal-500{--text-opacity:1;color:#38b2ac;color:rgba(56,178,172,var(--text-opacity))}.md\:text-teal-600{--text-opacity:1;color:#319795;color:rgba(49,151,149,var(--text-opacity))}.md\:text-teal-700{--text-opacity:1;color:#2c7a7b;color:rgba(44,122,123,var(--text-opacity))}.md\:text-teal-800{--text-opacity:1;color:#285e61;color:rgba(40,94,97,var(--text-opacity))}.md\:text-teal-900{--text-opacity:1;color:#234e52;color:rgba(35,78,82,var(--text-opacity))}.md\:text-blue-100{--text-opacity:1;color:#ebf8ff;color:rgba(235,248,255,var(--text-opacity))}.md\:text-blue-200{--text-opacity:1;color:#bee3f8;color:rgba(190,227,248,var(--text-opacity))}.md\:text-blue-300{--text-opacity:1;color:#90cdf4;color:rgba(144,205,244,var(--text-opacity))}.md\:text-blue-400{--text-opacity:1;color:#63b3ed;color:rgba(99,179,237,var(--text-opacity))}.md\:text-blue-500{--text-opacity:1;color:#4299e1;color:rgba(66,153,225,var(--text-opacity))}.md\:text-blue-600{--text-opacity:1;color:#3182ce;color:rgba(49,130,206,var(--text-opacity))}.md\:text-blue-700{--text-opacity:1;color:#2b6cb0;color:rgba(43,108,176,var(--text-opacity))}.md\:text-blue-800{--text-opacity:1;color:#2c5282;color:rgba(44,82,130,var(--text-opacity))}.md\:text-blue-900{--text-opacity:1;color:#2a4365;color:rgba(42,67,101,var(--text-opacity))}.md\:text-indigo-100{--text-opacity:1;color:#ebf4ff;color:rgba(235,244,255,var(--text-opacity))}.md\:text-indigo-200{--text-opacity:1;color:#c3dafe;color:rgba(195,218,254,var(--text-opacity))}.md\:text-indigo-300{--text-opacity:1;color:#a3bffa;color:rgba(163,191,250,var(--text-opacity))}.md\:text-indigo-400{--text-opacity:1;color:#7f9cf5;color:rgba(127,156,245,var(--text-opacity))}.md\:text-indigo-500{--text-opacity:1;color:#667eea;color:rgba(102,126,234,var(--text-opacity))}.md\:text-indigo-600{--text-opacity:1;color:#5a67d8;color:rgba(90,103,216,var(--text-opacity))}.md\:text-indigo-700{--text-opacity:1;color:#4c51bf;color:rgba(76,81,191,var(--text-opacity))}.md\:text-indigo-800{--text-opacity:1;color:#434190;color:rgba(67,65,144,var(--text-opacity))}.md\:text-indigo-900{--text-opacity:1;color:#3c366b;color:rgba(60,54,107,var(--text-opacity))}.md\:text-purple-100{--text-opacity:1;color:#faf5ff;color:rgba(250,245,255,var(--text-opacity))}.md\:text-purple-200{--text-opacity:1;color:#e9d8fd;color:rgba(233,216,253,var(--text-opacity))}.md\:text-purple-300{--text-opacity:1;color:#d6bcfa;color:rgba(214,188,250,var(--text-opacity))}.md\:text-purple-400{--text-opacity:1;color:#b794f4;color:rgba(183,148,244,var(--text-opacity))}.md\:text-purple-500{--text-opacity:1;color:#9f7aea;color:rgba(159,122,234,var(--text-opacity))}.md\:text-purple-600{--text-opacity:1;color:#805ad5;color:rgba(128,90,213,var(--text-opacity))}.md\:text-purple-700{--text-opacity:1;color:#6b46c1;color:rgba(107,70,193,var(--text-opacity))}.md\:text-purple-800{--text-opacity:1;color:#553c9a;color:rgba(85,60,154,var(--text-opacity))}.md\:text-purple-900{--text-opacity:1;color:#44337a;color:rgba(68,51,122,var(--text-opacity))}.md\:text-pink-100{--text-opacity:1;color:#fff5f7;color:rgba(255,245,247,var(--text-opacity))}.md\:text-pink-200{--text-opacity:1;color:#fed7e2;color:rgba(254,215,226,var(--text-opacity))}.md\:text-pink-300{--text-opacity:1;color:#fbb6ce;color:rgba(251,182,206,var(--text-opacity))}.md\:text-pink-400{--text-opacity:1;color:#f687b3;color:rgba(246,135,179,var(--text-opacity))}.md\:text-pink-500{--text-opacity:1;color:#ed64a6;color:rgba(237,100,166,var(--text-opacity))}.md\:text-pink-600{--text-opacity:1;color:#d53f8c;color:rgba(213,63,140,var(--text-opacity))}.md\:text-pink-700{--text-opacity:1;color:#b83280;color:rgba(184,50,128,var(--text-opacity))}.md\:text-pink-800{--text-opacity:1;color:#97266d;color:rgba(151,38,109,var(--text-opacity))}.md\:text-pink-900{--text-opacity:1;color:#702459;color:rgba(112,36,89,var(--text-opacity))}.md\:hover\:text-transparent:hover{color:transparent}.md\:hover\:text-current:hover{color:currentColor}.md\:hover\:text-black:hover{--text-opacity:1;color:#000;color:rgba(0,0,0,var(--text-opacity))}.md\:hover\:text-white:hover{--text-opacity:1;color:#fff;color:rgba(255,255,255,var(--text-opacity))}.md\:hover\:text-gray-100:hover{--text-opacity:1;color:#f7fafc;color:rgba(247,250,252,var(--text-opacity))}.md\:hover\:text-gray-200:hover{--text-opacity:1;color:#edf2f7;color:rgba(237,242,247,var(--text-opacity))}.md\:hover\:text-gray-300:hover{--text-opacity:1;color:#e2e8f0;color:rgba(226,232,240,var(--text-opacity))}.md\:hover\:text-gray-400:hover{--text-opacity:1;color:#cbd5e0;color:rgba(203,213,224,var(--text-opacity))}.md\:hover\:text-gray-500:hover{--text-opacity:1;color:#a0aec0;color:rgba(160,174,192,var(--text-opacity))}.md\:hover\:text-gray-600:hover{--text-opacity:1;color:#718096;color:rgba(113,128,150,var(--text-opacity))}.md\:hover\:text-gray-700:hover{--text-opacity:1;color:#4a5568;color:rgba(74,85,104,var(--text-opacity))}.md\:hover\:text-gray-800:hover{--text-opacity:1;color:#2d3748;color:rgba(45,55,72,var(--text-opacity))}.md\:hover\:text-gray-900:hover{--text-opacity:1;color:#1a202c;color:rgba(26,32,44,var(--text-opacity))}.md\:hover\:text-red-100:hover{--text-opacity:1;color:#fff5f5;color:rgba(255,245,245,var(--text-opacity))}.md\:hover\:text-red-200:hover{--text-opacity:1;color:#fed7d7;color:rgba(254,215,215,var(--text-opacity))}.md\:hover\:text-red-300:hover{--text-opacity:1;color:#feb2b2;color:rgba(254,178,178,var(--text-opacity))}.md\:hover\:text-red-400:hover{--text-opacity:1;color:#fc8181;color:rgba(252,129,129,var(--text-opacity))}.md\:hover\:text-red-500:hover{--text-opacity:1;color:#f56565;color:rgba(245,101,101,var(--text-opacity))}.md\:hover\:text-red-600:hover{--text-opacity:1;color:#e53e3e;color:rgba(229,62,62,var(--text-opacity))}.md\:hover\:text-red-700:hover{--text-opacity:1;color:#c53030;color:rgba(197,48,48,var(--text-opacity))}.md\:hover\:text-red-800:hover{--text-opacity:1;color:#9b2c2c;color:rgba(155,44,44,var(--text-opacity))}.md\:hover\:text-red-900:hover{--text-opacity:1;color:#742a2a;color:rgba(116,42,42,var(--text-opacity))}.md\:hover\:text-orange-100:hover{--text-opacity:1;color:#fffaf0;color:rgba(255,250,240,var(--text-opacity))}.md\:hover\:text-orange-200:hover{--text-opacity:1;color:#feebc8;color:rgba(254,235,200,var(--text-opacity))}.md\:hover\:text-orange-300:hover{--text-opacity:1;color:#fbd38d;color:rgba(251,211,141,var(--text-opacity))}.md\:hover\:text-orange-400:hover{--text-opacity:1;color:#f6ad55;color:rgba(246,173,85,var(--text-opacity))}.md\:hover\:text-orange-500:hover{--text-opacity:1;color:#ed8936;color:rgba(237,137,54,var(--text-opacity))}.md\:hover\:text-orange-600:hover{--text-opacity:1;color:#dd6b20;color:rgba(221,107,32,var(--text-opacity))}.md\:hover\:text-orange-700:hover{--text-opacity:1;color:#c05621;color:rgba(192,86,33,var(--text-opacity))}.md\:hover\:text-orange-800:hover{--text-opacity:1;color:#9c4221;color:rgba(156,66,33,var(--text-opacity))}.md\:hover\:text-orange-900:hover{--text-opacity:1;color:#7b341e;color:rgba(123,52,30,var(--text-opacity))}.md\:hover\:text-yellow-100:hover{--text-opacity:1;color:ivory;color:rgba(255,255,240,var(--text-opacity))}.md\:hover\:text-yellow-200:hover{--text-opacity:1;color:#fefcbf;color:rgba(254,252,191,var(--text-opacity))}.md\:hover\:text-yellow-300:hover{--text-opacity:1;color:#faf089;color:rgba(250,240,137,var(--text-opacity))}.md\:hover\:text-yellow-400:hover{--text-opacity:1;color:#f6e05e;color:rgba(246,224,94,var(--text-opacity))}.md\:hover\:text-yellow-500:hover{--text-opacity:1;color:#ecc94b;color:rgba(236,201,75,var(--text-opacity))}.md\:hover\:text-yellow-600:hover{--text-opacity:1;color:#d69e2e;color:rgba(214,158,46,var(--text-opacity))}.md\:hover\:text-yellow-700:hover{--text-opacity:1;color:#b7791f;color:rgba(183,121,31,var(--text-opacity))}.md\:hover\:text-yellow-800:hover{--text-opacity:1;color:#975a16;color:rgba(151,90,22,var(--text-opacity))}.md\:hover\:text-yellow-900:hover{--text-opacity:1;color:#744210;color:rgba(116,66,16,var(--text-opacity))}.md\:hover\:text-green-100:hover{--text-opacity:1;color:#f0fff4;color:rgba(240,255,244,var(--text-opacity))}.md\:hover\:text-green-200:hover{--text-opacity:1;color:#c6f6d5;color:rgba(198,246,213,var(--text-opacity))}.md\:hover\:text-green-300:hover{--text-opacity:1;color:#9ae6b4;color:rgba(154,230,180,var(--text-opacity))}.md\:hover\:text-green-400:hover{--text-opacity:1;color:#68d391;color:rgba(104,211,145,var(--text-opacity))}.md\:hover\:text-green-500:hover{--text-opacity:1;color:#48bb78;color:rgba(72,187,120,var(--text-opacity))}.md\:hover\:text-green-600:hover{--text-opacity:1;color:#38a169;color:rgba(56,161,105,var(--text-opacity))}.md\:hover\:text-green-700:hover{--text-opacity:1;color:#2f855a;color:rgba(47,133,90,var(--text-opacity))}.md\:hover\:text-green-800:hover{--text-opacity:1;color:#276749;color:rgba(39,103,73,var(--text-opacity))}.md\:hover\:text-green-900:hover{--text-opacity:1;color:#22543d;color:rgba(34,84,61,var(--text-opacity))}.md\:hover\:text-teal-100:hover{--text-opacity:1;color:#e6fffa;color:rgba(230,255,250,var(--text-opacity))}.md\:hover\:text-teal-200:hover{--text-opacity:1;color:#b2f5ea;color:rgba(178,245,234,var(--text-opacity))}.md\:hover\:text-teal-300:hover{--text-opacity:1;color:#81e6d9;color:rgba(129,230,217,var(--text-opacity))}.md\:hover\:text-teal-400:hover{--text-opacity:1;color:#4fd1c5;color:rgba(79,209,197,var(--text-opacity))}.md\:hover\:text-teal-500:hover{--text-opacity:1;color:#38b2ac;color:rgba(56,178,172,var(--text-opacity))}.md\:hover\:text-teal-600:hover{--text-opacity:1;color:#319795;color:rgba(49,151,149,var(--text-opacity))}.md\:hover\:text-teal-700:hover{--text-opacity:1;color:#2c7a7b;color:rgba(44,122,123,var(--text-opacity))}.md\:hover\:text-teal-800:hover{--text-opacity:1;color:#285e61;color:rgba(40,94,97,var(--text-opacity))}.md\:hover\:text-teal-900:hover{--text-opacity:1;color:#234e52;color:rgba(35,78,82,var(--text-opacity))}.md\:hover\:text-blue-100:hover{--text-opacity:1;color:#ebf8ff;color:rgba(235,248,255,var(--text-opacity))}.md\:hover\:text-blue-200:hover{--text-opacity:1;color:#bee3f8;color:rgba(190,227,248,var(--text-opacity))}.md\:hover\:text-blue-300:hover{--text-opacity:1;color:#90cdf4;color:rgba(144,205,244,var(--text-opacity))}.md\:hover\:text-blue-400:hover{--text-opacity:1;color:#63b3ed;color:rgba(99,179,237,var(--text-opacity))}.md\:hover\:text-blue-500:hover{--text-opacity:1;color:#4299e1;color:rgba(66,153,225,var(--text-opacity))}.md\:hover\:text-blue-600:hover{--text-opacity:1;color:#3182ce;color:rgba(49,130,206,var(--text-opacity))}.md\:hover\:text-blue-700:hover{--text-opacity:1;color:#2b6cb0;color:rgba(43,108,176,var(--text-opacity))}.md\:hover\:text-blue-800:hover{--text-opacity:1;color:#2c5282;color:rgba(44,82,130,var(--text-opacity))}.md\:hover\:text-blue-900:hover{--text-opacity:1;color:#2a4365;color:rgba(42,67,101,var(--text-opacity))}.md\:hover\:text-indigo-100:hover{--text-opacity:1;color:#ebf4ff;color:rgba(235,244,255,var(--text-opacity))}.md\:hover\:text-indigo-200:hover{--text-opacity:1;color:#c3dafe;color:rgba(195,218,254,var(--text-opacity))}.md\:hover\:text-indigo-300:hover{--text-opacity:1;color:#a3bffa;color:rgba(163,191,250,var(--text-opacity))}.md\:hover\:text-indigo-400:hover{--text-opacity:1;color:#7f9cf5;color:rgba(127,156,245,var(--text-opacity))}.md\:hover\:text-indigo-500:hover{--text-opacity:1;color:#667eea;color:rgba(102,126,234,var(--text-opacity))}.md\:hover\:text-indigo-600:hover{--text-opacity:1;color:#5a67d8;color:rgba(90,103,216,var(--text-opacity))}.md\:hover\:text-indigo-700:hover{--text-opacity:1;color:#4c51bf;color:rgba(76,81,191,var(--text-opacity))}.md\:hover\:text-indigo-800:hover{--text-opacity:1;color:#434190;color:rgba(67,65,144,var(--text-opacity))}.md\:hover\:text-indigo-900:hover{--text-opacity:1;color:#3c366b;color:rgba(60,54,107,var(--text-opacity))}.md\:hover\:text-purple-100:hover{--text-opacity:1;color:#faf5ff;color:rgba(250,245,255,var(--text-opacity))}.md\:hover\:text-purple-200:hover{--text-opacity:1;color:#e9d8fd;color:rgba(233,216,253,var(--text-opacity))}.md\:hover\:text-purple-300:hover{--text-opacity:1;color:#d6bcfa;color:rgba(214,188,250,var(--text-opacity))}.md\:hover\:text-purple-400:hover{--text-opacity:1;color:#b794f4;color:rgba(183,148,244,var(--text-opacity))}.md\:hover\:text-purple-500:hover{--text-opacity:1;color:#9f7aea;color:rgba(159,122,234,var(--text-opacity))}.md\:hover\:text-purple-600:hover{--text-opacity:1;color:#805ad5;color:rgba(128,90,213,var(--text-opacity))}.md\:hover\:text-purple-700:hover{--text-opacity:1;color:#6b46c1;color:rgba(107,70,193,var(--text-opacity))}.md\:hover\:text-purple-800:hover{--text-opacity:1;color:#553c9a;color:rgba(85,60,154,var(--text-opacity))}.md\:hover\:text-purple-900:hover{--text-opacity:1;color:#44337a;color:rgba(68,51,122,var(--text-opacity))}.md\:hover\:text-pink-100:hover{--text-opacity:1;color:#fff5f7;color:rgba(255,245,247,var(--text-opacity))}.md\:hover\:text-pink-200:hover{--text-opacity:1;color:#fed7e2;color:rgba(254,215,226,var(--text-opacity))}.md\:hover\:text-pink-300:hover{--text-opacity:1;color:#fbb6ce;color:rgba(251,182,206,var(--text-opacity))}.md\:hover\:text-pink-400:hover{--text-opacity:1;color:#f687b3;color:rgba(246,135,179,var(--text-opacity))}.md\:hover\:text-pink-500:hover{--text-opacity:1;color:#ed64a6;color:rgba(237,100,166,var(--text-opacity))}.md\:hover\:text-pink-600:hover{--text-opacity:1;color:#d53f8c;color:rgba(213,63,140,var(--text-opacity))}.md\:hover\:text-pink-700:hover{--text-opacity:1;color:#b83280;color:rgba(184,50,128,var(--text-opacity))}.md\:hover\:text-pink-800:hover{--text-opacity:1;color:#97266d;color:rgba(151,38,109,var(--text-opacity))}.md\:hover\:text-pink-900:hover{--text-opacity:1;color:#702459;color:rgba(112,36,89,var(--text-opacity))}.md\:focus\:text-transparent:focus{color:transparent}.md\:focus\:text-current:focus{color:currentColor}.md\:focus\:text-black:focus{--text-opacity:1;color:#000;color:rgba(0,0,0,var(--text-opacity))}.md\:focus\:text-white:focus{--text-opacity:1;color:#fff;color:rgba(255,255,255,var(--text-opacity))}.md\:focus\:text-gray-100:focus{--text-opacity:1;color:#f7fafc;color:rgba(247,250,252,var(--text-opacity))}.md\:focus\:text-gray-200:focus{--text-opacity:1;color:#edf2f7;color:rgba(237,242,247,var(--text-opacity))}.md\:focus\:text-gray-300:focus{--text-opacity:1;color:#e2e8f0;color:rgba(226,232,240,var(--text-opacity))}.md\:focus\:text-gray-400:focus{--text-opacity:1;color:#cbd5e0;color:rgba(203,213,224,var(--text-opacity))}.md\:focus\:text-gray-500:focus{--text-opacity:1;color:#a0aec0;color:rgba(160,174,192,var(--text-opacity))}.md\:focus\:text-gray-600:focus{--text-opacity:1;color:#718096;color:rgba(113,128,150,var(--text-opacity))}.md\:focus\:text-gray-700:focus{--text-opacity:1;color:#4a5568;color:rgba(74,85,104,var(--text-opacity))}.md\:focus\:text-gray-800:focus{--text-opacity:1;color:#2d3748;color:rgba(45,55,72,var(--text-opacity))}.md\:focus\:text-gray-900:focus{--text-opacity:1;color:#1a202c;color:rgba(26,32,44,var(--text-opacity))}.md\:focus\:text-red-100:focus{--text-opacity:1;color:#fff5f5;color:rgba(255,245,245,var(--text-opacity))}.md\:focus\:text-red-200:focus{--text-opacity:1;color:#fed7d7;color:rgba(254,215,215,var(--text-opacity))}.md\:focus\:text-red-300:focus{--text-opacity:1;color:#feb2b2;color:rgba(254,178,178,var(--text-opacity))}.md\:focus\:text-red-400:focus{--text-opacity:1;color:#fc8181;color:rgba(252,129,129,var(--text-opacity))}.md\:focus\:text-red-500:focus{--text-opacity:1;color:#f56565;color:rgba(245,101,101,var(--text-opacity))}.md\:focus\:text-red-600:focus{--text-opacity:1;color:#e53e3e;color:rgba(229,62,62,var(--text-opacity))}.md\:focus\:text-red-700:focus{--text-opacity:1;color:#c53030;color:rgba(197,48,48,var(--text-opacity))}.md\:focus\:text-red-800:focus{--text-opacity:1;color:#9b2c2c;color:rgba(155,44,44,var(--text-opacity))}.md\:focus\:text-red-900:focus{--text-opacity:1;color:#742a2a;color:rgba(116,42,42,var(--text-opacity))}.md\:focus\:text-orange-100:focus{--text-opacity:1;color:#fffaf0;color:rgba(255,250,240,var(--text-opacity))}.md\:focus\:text-orange-200:focus{--text-opacity:1;color:#feebc8;color:rgba(254,235,200,var(--text-opacity))}.md\:focus\:text-orange-300:focus{--text-opacity:1;color:#fbd38d;color:rgba(251,211,141,var(--text-opacity))}.md\:focus\:text-orange-400:focus{--text-opacity:1;color:#f6ad55;color:rgba(246,173,85,var(--text-opacity))}.md\:focus\:text-orange-500:focus{--text-opacity:1;color:#ed8936;color:rgba(237,137,54,var(--text-opacity))}.md\:focus\:text-orange-600:focus{--text-opacity:1;color:#dd6b20;color:rgba(221,107,32,var(--text-opacity))}.md\:focus\:text-orange-700:focus{--text-opacity:1;color:#c05621;color:rgba(192,86,33,var(--text-opacity))}.md\:focus\:text-orange-800:focus{--text-opacity:1;color:#9c4221;color:rgba(156,66,33,var(--text-opacity))}.md\:focus\:text-orange-900:focus{--text-opacity:1;color:#7b341e;color:rgba(123,52,30,var(--text-opacity))}.md\:focus\:text-yellow-100:focus{--text-opacity:1;color:ivory;color:rgba(255,255,240,var(--text-opacity))}.md\:focus\:text-yellow-200:focus{--text-opacity:1;color:#fefcbf;color:rgba(254,252,191,var(--text-opacity))}.md\:focus\:text-yellow-300:focus{--text-opacity:1;color:#faf089;color:rgba(250,240,137,var(--text-opacity))}.md\:focus\:text-yellow-400:focus{--text-opacity:1;color:#f6e05e;color:rgba(246,224,94,var(--text-opacity))}.md\:focus\:text-yellow-500:focus{--text-opacity:1;color:#ecc94b;color:rgba(236,201,75,var(--text-opacity))}.md\:focus\:text-yellow-600:focus{--text-opacity:1;color:#d69e2e;color:rgba(214,158,46,var(--text-opacity))}.md\:focus\:text-yellow-700:focus{--text-opacity:1;color:#b7791f;color:rgba(183,121,31,var(--text-opacity))}.md\:focus\:text-yellow-800:focus{--text-opacity:1;color:#975a16;color:rgba(151,90,22,var(--text-opacity))}.md\:focus\:text-yellow-900:focus{--text-opacity:1;color:#744210;color:rgba(116,66,16,var(--text-opacity))}.md\:focus\:text-green-100:focus{--text-opacity:1;color:#f0fff4;color:rgba(240,255,244,var(--text-opacity))}.md\:focus\:text-green-200:focus{--text-opacity:1;color:#c6f6d5;color:rgba(198,246,213,var(--text-opacity))}.md\:focus\:text-green-300:focus{--text-opacity:1;color:#9ae6b4;color:rgba(154,230,180,var(--text-opacity))}.md\:focus\:text-green-400:focus{--text-opacity:1;color:#68d391;color:rgba(104,211,145,var(--text-opacity))}.md\:focus\:text-green-500:focus{--text-opacity:1;color:#48bb78;color:rgba(72,187,120,var(--text-opacity))}.md\:focus\:text-green-600:focus{--text-opacity:1;color:#38a169;color:rgba(56,161,105,var(--text-opacity))}.md\:focus\:text-green-700:focus{--text-opacity:1;color:#2f855a;color:rgba(47,133,90,var(--text-opacity))}.md\:focus\:text-green-800:focus{--text-opacity:1;color:#276749;color:rgba(39,103,73,var(--text-opacity))}.md\:focus\:text-green-900:focus{--text-opacity:1;color:#22543d;color:rgba(34,84,61,var(--text-opacity))}.md\:focus\:text-teal-100:focus{--text-opacity:1;color:#e6fffa;color:rgba(230,255,250,var(--text-opacity))}.md\:focus\:text-teal-200:focus{--text-opacity:1;color:#b2f5ea;color:rgba(178,245,234,var(--text-opacity))}.md\:focus\:text-teal-300:focus{--text-opacity:1;color:#81e6d9;color:rgba(129,230,217,var(--text-opacity))}.md\:focus\:text-teal-400:focus{--text-opacity:1;color:#4fd1c5;color:rgba(79,209,197,var(--text-opacity))}.md\:focus\:text-teal-500:focus{--text-opacity:1;color:#38b2ac;color:rgba(56,178,172,var(--text-opacity))}.md\:focus\:text-teal-600:focus{--text-opacity:1;color:#319795;color:rgba(49,151,149,var(--text-opacity))}.md\:focus\:text-teal-700:focus{--text-opacity:1;color:#2c7a7b;color:rgba(44,122,123,var(--text-opacity))}.md\:focus\:text-teal-800:focus{--text-opacity:1;color:#285e61;color:rgba(40,94,97,var(--text-opacity))}.md\:focus\:text-teal-900:focus{--text-opacity:1;color:#234e52;color:rgba(35,78,82,var(--text-opacity))}.md\:focus\:text-blue-100:focus{--text-opacity:1;color:#ebf8ff;color:rgba(235,248,255,var(--text-opacity))}.md\:focus\:text-blue-200:focus{--text-opacity:1;color:#bee3f8;color:rgba(190,227,248,var(--text-opacity))}.md\:focus\:text-blue-300:focus{--text-opacity:1;color:#90cdf4;color:rgba(144,205,244,var(--text-opacity))}.md\:focus\:text-blue-400:focus{--text-opacity:1;color:#63b3ed;color:rgba(99,179,237,var(--text-opacity))}.md\:focus\:text-blue-500:focus{--text-opacity:1;color:#4299e1;color:rgba(66,153,225,var(--text-opacity))}.md\:focus\:text-blue-600:focus{--text-opacity:1;color:#3182ce;color:rgba(49,130,206,var(--text-opacity))}.md\:focus\:text-blue-700:focus{--text-opacity:1;color:#2b6cb0;color:rgba(43,108,176,var(--text-opacity))}.md\:focus\:text-blue-800:focus{--text-opacity:1;color:#2c5282;color:rgba(44,82,130,var(--text-opacity))}.md\:focus\:text-blue-900:focus{--text-opacity:1;color:#2a4365;color:rgba(42,67,101,var(--text-opacity))}.md\:focus\:text-indigo-100:focus{--text-opacity:1;color:#ebf4ff;color:rgba(235,244,255,var(--text-opacity))}.md\:focus\:text-indigo-200:focus{--text-opacity:1;color:#c3dafe;color:rgba(195,218,254,var(--text-opacity))}.md\:focus\:text-indigo-300:focus{--text-opacity:1;color:#a3bffa;color:rgba(163,191,250,var(--text-opacity))}.md\:focus\:text-indigo-400:focus{--text-opacity:1;color:#7f9cf5;color:rgba(127,156,245,var(--text-opacity))}.md\:focus\:text-indigo-500:focus{--text-opacity:1;color:#667eea;color:rgba(102,126,234,var(--text-opacity))}.md\:focus\:text-indigo-600:focus{--text-opacity:1;color:#5a67d8;color:rgba(90,103,216,var(--text-opacity))}.md\:focus\:text-indigo-700:focus{--text-opacity:1;color:#4c51bf;color:rgba(76,81,191,var(--text-opacity))}.md\:focus\:text-indigo-800:focus{--text-opacity:1;color:#434190;color:rgba(67,65,144,var(--text-opacity))}.md\:focus\:text-indigo-900:focus{--text-opacity:1;color:#3c366b;color:rgba(60,54,107,var(--text-opacity))}.md\:focus\:text-purple-100:focus{--text-opacity:1;color:#faf5ff;color:rgba(250,245,255,var(--text-opacity))}.md\:focus\:text-purple-200:focus{--text-opacity:1;color:#e9d8fd;color:rgba(233,216,253,var(--text-opacity))}.md\:focus\:text-purple-300:focus{--text-opacity:1;color:#d6bcfa;color:rgba(214,188,250,var(--text-opacity))}.md\:focus\:text-purple-400:focus{--text-opacity:1;color:#b794f4;color:rgba(183,148,244,var(--text-opacity))}.md\:focus\:text-purple-500:focus{--text-opacity:1;color:#9f7aea;color:rgba(159,122,234,var(--text-opacity))}.md\:focus\:text-purple-600:focus{--text-opacity:1;color:#805ad5;color:rgba(128,90,213,var(--text-opacity))}.md\:focus\:text-purple-700:focus{--text-opacity:1;color:#6b46c1;color:rgba(107,70,193,var(--text-opacity))}.md\:focus\:text-purple-800:focus{--text-opacity:1;color:#553c9a;color:rgba(85,60,154,var(--text-opacity))}.md\:focus\:text-purple-900:focus{--text-opacity:1;color:#44337a;color:rgba(68,51,122,var(--text-opacity))}.md\:focus\:text-pink-100:focus{--text-opacity:1;color:#fff5f7;color:rgba(255,245,247,var(--text-opacity))}.md\:focus\:text-pink-200:focus{--text-opacity:1;color:#fed7e2;color:rgba(254,215,226,var(--text-opacity))}.md\:focus\:text-pink-300:focus{--text-opacity:1;color:#fbb6ce;color:rgba(251,182,206,var(--text-opacity))}.md\:focus\:text-pink-400:focus{--text-opacity:1;color:#f687b3;color:rgba(246,135,179,var(--text-opacity))}.md\:focus\:text-pink-500:focus{--text-opacity:1;color:#ed64a6;color:rgba(237,100,166,var(--text-opacity))}.md\:focus\:text-pink-600:focus{--text-opacity:1;color:#d53f8c;color:rgba(213,63,140,var(--text-opacity))}.md\:focus\:text-pink-700:focus{--text-opacity:1;color:#b83280;color:rgba(184,50,128,var(--text-opacity))}.md\:focus\:text-pink-800:focus{--text-opacity:1;color:#97266d;color:rgba(151,38,109,var(--text-opacity))}.md\:focus\:text-pink-900:focus{--text-opacity:1;color:#702459;color:rgba(112,36,89,var(--text-opacity))}.md\:text-opacity-0{--text-opacity:0}.md\:text-opacity-25{--text-opacity:0.25}.md\:text-opacity-50{--text-opacity:0.5}.md\:text-opacity-75{--text-opacity:0.75}.md\:text-opacity-100{--text-opacity:1}.md\:hover\:text-opacity-0:hover{--text-opacity:0}.md\:hover\:text-opacity-25:hover{--text-opacity:0.25}.md\:hover\:text-opacity-50:hover{--text-opacity:0.5}.md\:hover\:text-opacity-75:hover{--text-opacity:0.75}.md\:hover\:text-opacity-100:hover{--text-opacity:1}.md\:focus\:text-opacity-0:focus{--text-opacity:0}.md\:focus\:text-opacity-25:focus{--text-opacity:0.25}.md\:focus\:text-opacity-50:focus{--text-opacity:0.5}.md\:focus\:text-opacity-75:focus{--text-opacity:0.75}.md\:focus\:text-opacity-100:focus{--text-opacity:1}.md\:italic{font-style:italic}.md\:not-italic{font-style:normal}.md\:uppercase{text-transform:uppercase}.md\:lowercase{text-transform:lowercase}.md\:capitalize{text-transform:capitalize}.md\:normal-case{text-transform:none}.md\:underline{text-decoration:underline}.md\:line-through{text-decoration:line-through}.md\:no-underline{text-decoration:none}.md\:hover\:underline:hover{text-decoration:underline}.md\:hover\:line-through:hover{text-decoration:line-through}.md\:hover\:no-underline:hover{text-decoration:none}.md\:focus\:underline:focus{text-decoration:underline}.md\:focus\:line-through:focus{text-decoration:line-through}.md\:focus\:no-underline:focus{text-decoration:none}.md\:antialiased{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.md\:subpixel-antialiased{-webkit-font-smoothing:auto;-moz-osx-font-smoothing:auto}.md\:diagonal-fractions,.md\:lining-nums,.md\:oldstyle-nums,.md\:ordinal,.md\:proportional-nums,.md\:slashed-zero,.md\:stacked-fractions,.md\:tabular-nums{--font-variant-numeric-ordinal:var(--tailwind-empty, );/*!*//*!*/--font-variant-numeric-slashed-zero:var(--tailwind-empty, );/*!*//*!*/--font-variant-numeric-figure:var(--tailwind-empty, );/*!*//*!*/--font-variant-numeric-spacing:var(--tailwind-empty, );/*!*//*!*/--font-variant-numeric-fraction:var(--tailwind-empty, );/*!*//*!*/font-variant-numeric:var(--font-variant-numeric-ordinal) var(--font-variant-numeric-slashed-zero) var(--font-variant-numeric-figure) var(--font-variant-numeric-spacing) var(--font-variant-numeric-fraction)}.md\:normal-nums{font-variant-numeric:normal}.md\:ordinal{--font-variant-numeric-ordinal:ordinal}.md\:slashed-zero{--font-variant-numeric-slashed-zero:slashed-zero}.md\:lining-nums{--font-variant-numeric-figure:lining-nums}.md\:oldstyle-nums{--font-variant-numeric-figure:oldstyle-nums}.md\:proportional-nums{--font-variant-numeric-spacing:proportional-nums}.md\:tabular-nums{--font-variant-numeric-spacing:tabular-nums}.md\:diagonal-fractions{--font-variant-numeric-fraction:diagonal-fractions}.md\:stacked-fractions{--font-variant-numeric-fraction:stacked-fractions}.md\:tracking-tighter{letter-spacing:-.05em}.md\:tracking-tight{letter-spacing:-.025em}.md\:tracking-normal{letter-spacing:0}.md\:tracking-wide{letter-spacing:.025em}.md\:tracking-wider{letter-spacing:.05em}.md\:tracking-widest{letter-spacing:.1em}.md\:select-none{-webkit-user-select:none;-ms-user-select:none;user-select:none}.md\:select-text{-webkit-user-select:text;-ms-user-select:text;user-select:text}.md\:select-all{-webkit-user-select:all;-ms-user-select:all;user-select:all}.md\:select-auto{-webkit-user-select:auto;-ms-user-select:auto;user-select:auto}.md\:align-baseline{vertical-align:baseline}.md\:align-top{vertical-align:top}.md\:align-middle{vertical-align:middle}.md\:align-bottom{vertical-align:bottom}.md\:align-text-top{vertical-align:text-top}.md\:align-text-bottom{vertical-align:text-bottom}.md\:visible{visibility:visible}.md\:invisible{visibility:hidden}.md\:whitespace-normal{white-space:normal}.md\:whitespace-no-wrap{white-space:nowrap}.md\:whitespace-pre{white-space:pre}.md\:whitespace-pre-line{white-space:pre-line}.md\:whitespace-pre-wrap{white-space:pre-wrap}.md\:break-normal{word-wrap:normal;overflow-wrap:normal;word-break:normal}.md\:break-words{word-wrap:break-word;overflow-wrap:break-word}.md\:break-all{word-break:break-all}.md\:truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.md\:w-0{width:0}.md\:w-1{width:.25rem}.md\:w-2{width:.5rem}.md\:w-3{width:.75rem}.md\:w-4{width:1rem}.md\:w-5{width:1.25rem}.md\:w-6{width:1.5rem}.md\:w-8{width:2rem}.md\:w-10{width:2.5rem}.md\:w-12{width:3rem}.md\:w-16{width:4rem}.md\:w-20{width:5rem}.md\:w-24{width:6rem}.md\:w-32{width:8rem}.md\:w-40{width:10rem}.md\:w-48{width:12rem}.md\:w-56{width:14rem}.md\:w-64{width:16rem}.md\:w-auto{width:auto}.md\:w-px{width:1px}.md\:w-1\/2{width:50%}.md\:w-1\/3{width:33.333333%}.md\:w-2\/3{width:66.666667%}.md\:w-1\/4{width:25%}.md\:w-2\/4{width:50%}.md\:w-3\/4{width:75%}.md\:w-1\/5{width:20%}.md\:w-2\/5{width:40%}.md\:w-3\/5{width:60%}.md\:w-4\/5{width:80%}.md\:w-1\/6{width:16.666667%}.md\:w-2\/6{width:33.333333%}.md\:w-3\/6{width:50%}.md\:w-4\/6{width:66.666667%}.md\:w-5\/6{width:83.333333%}.md\:w-1\/12{width:8.333333%}.md\:w-2\/12{width:16.666667%}.md\:w-3\/12{width:25%}.md\:w-4\/12{width:33.333333%}.md\:w-5\/12{width:41.666667%}.md\:w-6\/12{width:50%}.md\:w-7\/12{width:58.333333%}.md\:w-8\/12{width:66.666667%}.md\:w-9\/12{width:75%}.md\:w-10\/12{width:83.333333%}.md\:w-11\/12{width:91.666667%}.md\:w-full{width:100%}.md\:w-screen{width:100vw}.md\:z-0{z-index:0}.md\:z-10{z-index:10}.md\:z-20{z-index:20}.md\:z-30{z-index:30}.md\:z-40{z-index:40}.md\:z-50{z-index:50}.md\:z-auto{z-index:auto}.md\:gap-0{grid-gap:0;gap:0}.md\:gap-1{grid-gap:.25rem;gap:.25rem}.md\:gap-2{grid-gap:.5rem;gap:.5rem}.md\:gap-3{grid-gap:.75rem;gap:.75rem}.md\:gap-4{grid-gap:1rem;gap:1rem}.md\:gap-5{grid-gap:1.25rem;gap:1.25rem}.md\:gap-6{grid-gap:1.5rem;gap:1.5rem}.md\:gap-8{grid-gap:2rem;gap:2rem}.md\:gap-10{grid-gap:2.5rem;gap:2.5rem}.md\:gap-12{grid-gap:3rem;gap:3rem}.md\:gap-16{grid-gap:4rem;gap:4rem}.md\:gap-20{grid-gap:5rem;gap:5rem}.md\:gap-24{grid-gap:6rem;gap:6rem}.md\:gap-32{grid-gap:8rem;gap:8rem}.md\:gap-40{grid-gap:10rem;gap:10rem}.md\:gap-48{grid-gap:12rem;gap:12rem}.md\:gap-56{grid-gap:14rem;gap:14rem}.md\:gap-64{grid-gap:16rem;gap:16rem}.md\:gap-px{grid-gap:1px;gap:1px}.md\:col-gap-0{grid-column-gap:0;column-gap:0}.md\:col-gap-1{grid-column-gap:.25rem;column-gap:.25rem}.md\:col-gap-2{grid-column-gap:.5rem;column-gap:.5rem}.md\:col-gap-3{grid-column-gap:.75rem;column-gap:.75rem}.md\:col-gap-4{grid-column-gap:1rem;column-gap:1rem}.md\:col-gap-5{grid-column-gap:1.25rem;column-gap:1.25rem}.md\:col-gap-6{grid-column-gap:1.5rem;column-gap:1.5rem}.md\:col-gap-8{grid-column-gap:2rem;column-gap:2rem}.md\:col-gap-10{grid-column-gap:2.5rem;column-gap:2.5rem}.md\:col-gap-12{grid-column-gap:3rem;column-gap:3rem}.md\:col-gap-16{grid-column-gap:4rem;column-gap:4rem}.md\:col-gap-20{grid-column-gap:5rem;column-gap:5rem}.md\:col-gap-24{grid-column-gap:6rem;column-gap:6rem}.md\:col-gap-32{grid-column-gap:8rem;column-gap:8rem}.md\:col-gap-40{grid-column-gap:10rem;column-gap:10rem}.md\:col-gap-48{grid-column-gap:12rem;column-gap:12rem}.md\:col-gap-56{grid-column-gap:14rem;column-gap:14rem}.md\:col-gap-64{grid-column-gap:16rem;column-gap:16rem}.md\:col-gap-px{grid-column-gap:1px;column-gap:1px}.md\:gap-x-0{grid-column-gap:0;column-gap:0}.md\:gap-x-1{grid-column-gap:.25rem;column-gap:.25rem}.md\:gap-x-2{grid-column-gap:.5rem;column-gap:.5rem}.md\:gap-x-3{grid-column-gap:.75rem;column-gap:.75rem}.md\:gap-x-4{grid-column-gap:1rem;column-gap:1rem}.md\:gap-x-5{grid-column-gap:1.25rem;column-gap:1.25rem}.md\:gap-x-6{grid-column-gap:1.5rem;column-gap:1.5rem}.md\:gap-x-8{grid-column-gap:2rem;column-gap:2rem}.md\:gap-x-10{grid-column-gap:2.5rem;column-gap:2.5rem}.md\:gap-x-12{grid-column-gap:3rem;column-gap:3rem}.md\:gap-x-16{grid-column-gap:4rem;column-gap:4rem}.md\:gap-x-20{grid-column-gap:5rem;column-gap:5rem}.md\:gap-x-24{grid-column-gap:6rem;column-gap:6rem}.md\:gap-x-32{grid-column-gap:8rem;column-gap:8rem}.md\:gap-x-40{grid-column-gap:10rem;column-gap:10rem}.md\:gap-x-48{grid-column-gap:12rem;column-gap:12rem}.md\:gap-x-56{grid-column-gap:14rem;column-gap:14rem}.md\:gap-x-64{grid-column-gap:16rem;column-gap:16rem}.md\:gap-x-px{grid-column-gap:1px;column-gap:1px}.md\:row-gap-0{grid-row-gap:0;row-gap:0}.md\:row-gap-1{grid-row-gap:.25rem;row-gap:.25rem}.md\:row-gap-2{grid-row-gap:.5rem;row-gap:.5rem}.md\:row-gap-3{grid-row-gap:.75rem;row-gap:.75rem}.md\:row-gap-4{grid-row-gap:1rem;row-gap:1rem}.md\:row-gap-5{grid-row-gap:1.25rem;row-gap:1.25rem}.md\:row-gap-6{grid-row-gap:1.5rem;row-gap:1.5rem}.md\:row-gap-8{grid-row-gap:2rem;row-gap:2rem}.md\:row-gap-10{grid-row-gap:2.5rem;row-gap:2.5rem}.md\:row-gap-12{grid-row-gap:3rem;row-gap:3rem}.md\:row-gap-16{grid-row-gap:4rem;row-gap:4rem}.md\:row-gap-20{grid-row-gap:5rem;row-gap:5rem}.md\:row-gap-24{grid-row-gap:6rem;row-gap:6rem}.md\:row-gap-32{grid-row-gap:8rem;row-gap:8rem}.md\:row-gap-40{grid-row-gap:10rem;row-gap:10rem}.md\:row-gap-48{grid-row-gap:12rem;row-gap:12rem}.md\:row-gap-56{grid-row-gap:14rem;row-gap:14rem}.md\:row-gap-64{grid-row-gap:16rem;row-gap:16rem}.md\:row-gap-px{grid-row-gap:1px;row-gap:1px}.md\:gap-y-0{grid-row-gap:0;row-gap:0}.md\:gap-y-1{grid-row-gap:.25rem;row-gap:.25rem}.md\:gap-y-2{grid-row-gap:.5rem;row-gap:.5rem}.md\:gap-y-3{grid-row-gap:.75rem;row-gap:.75rem}.md\:gap-y-4{grid-row-gap:1rem;row-gap:1rem}.md\:gap-y-5{grid-row-gap:1.25rem;row-gap:1.25rem}.md\:gap-y-6{grid-row-gap:1.5rem;row-gap:1.5rem}.md\:gap-y-8{grid-row-gap:2rem;row-gap:2rem}.md\:gap-y-10{grid-row-gap:2.5rem;row-gap:2.5rem}.md\:gap-y-12{grid-row-gap:3rem;row-gap:3rem}.md\:gap-y-16{grid-row-gap:4rem;row-gap:4rem}.md\:gap-y-20{grid-row-gap:5rem;row-gap:5rem}.md\:gap-y-24{grid-row-gap:6rem;row-gap:6rem}.md\:gap-y-32{grid-row-gap:8rem;row-gap:8rem}.md\:gap-y-40{grid-row-gap:10rem;row-gap:10rem}.md\:gap-y-48{grid-row-gap:12rem;row-gap:12rem}.md\:gap-y-56{grid-row-gap:14rem;row-gap:14rem}.md\:gap-y-64{grid-row-gap:16rem;row-gap:16rem}.md\:gap-y-px{grid-row-gap:1px;row-gap:1px}.md\:grid-flow-row{grid-auto-flow:row}.md\:grid-flow-col{grid-auto-flow:column}.md\:grid-flow-row-dense{grid-auto-flow:row dense}.md\:grid-flow-col-dense{grid-auto-flow:column dense}.md\:grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.md\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.md\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.md\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.md\:grid-cols-5{grid-template-columns:repeat(5,minmax(0,1fr))}.md\:grid-cols-6{grid-template-columns:repeat(6,minmax(0,1fr))}.md\:grid-cols-7{grid-template-columns:repeat(7,minmax(0,1fr))}.md\:grid-cols-8{grid-template-columns:repeat(8,minmax(0,1fr))}.md\:grid-cols-9{grid-template-columns:repeat(9,minmax(0,1fr))}.md\:grid-cols-10{grid-template-columns:repeat(10,minmax(0,1fr))}.md\:grid-cols-11{grid-template-columns:repeat(11,minmax(0,1fr))}.md\:grid-cols-12{grid-template-columns:repeat(12,minmax(0,1fr))}.md\:grid-cols-none{grid-template-columns:none}.md\:auto-cols-auto{grid-auto-columns:auto}.md\:auto-cols-min{grid-auto-columns:-webkit-min-content;grid-auto-columns:min-content}.md\:auto-cols-max{grid-auto-columns:-webkit-max-content;grid-auto-columns:max-content}.md\:auto-cols-fr{grid-auto-columns:minmax(0,1fr)}.md\:col-auto{grid-column:auto}.md\:col-span-1{grid-column:span 1/span 1}.md\:col-span-2{grid-column:span 2/span 2}.md\:col-span-3{grid-column:span 3/span 3}.md\:col-span-4{grid-column:span 4/span 4}.md\:col-span-5{grid-column:span 5/span 5}.md\:col-span-6{grid-column:span 6/span 6}.md\:col-span-7{grid-column:span 7/span 7}.md\:col-span-8{grid-column:span 8/span 8}.md\:col-span-9{grid-column:span 9/span 9}.md\:col-span-10{grid-column:span 10/span 10}.md\:col-span-11{grid-column:span 11/span 11}.md\:col-span-12{grid-column:span 12/span 12}.md\:col-span-full{grid-column:1/-1}.md\:col-start-1{grid-column-start:1}.md\:col-start-2{grid-column-start:2}.md\:col-start-3{grid-column-start:3}.md\:col-start-4{grid-column-start:4}.md\:col-start-5{grid-column-start:5}.md\:col-start-6{grid-column-start:6}.md\:col-start-7{grid-column-start:7}.md\:col-start-8{grid-column-start:8}.md\:col-start-9{grid-column-start:9}.md\:col-start-10{grid-column-start:10}.md\:col-start-11{grid-column-start:11}.md\:col-start-12{grid-column-start:12}.md\:col-start-13{grid-column-start:13}.md\:col-start-auto{grid-column-start:auto}.md\:col-end-1{grid-column-end:1}.md\:col-end-2{grid-column-end:2}.md\:col-end-3{grid-column-end:3}.md\:col-end-4{grid-column-end:4}.md\:col-end-5{grid-column-end:5}.md\:col-end-6{grid-column-end:6}.md\:col-end-7{grid-column-end:7}.md\:col-end-8{grid-column-end:8}.md\:col-end-9{grid-column-end:9}.md\:col-end-10{grid-column-end:10}.md\:col-end-11{grid-column-end:11}.md\:col-end-12{grid-column-end:12}.md\:col-end-13{grid-column-end:13}.md\:col-end-auto{grid-column-end:auto}.md\:grid-rows-1{grid-template-rows:repeat(1,minmax(0,1fr))}.md\:grid-rows-2{grid-template-rows:repeat(2,minmax(0,1fr))}.md\:grid-rows-3{grid-template-rows:repeat(3,minmax(0,1fr))}.md\:grid-rows-4{grid-template-rows:repeat(4,minmax(0,1fr))}.md\:grid-rows-5{grid-template-rows:repeat(5,minmax(0,1fr))}.md\:grid-rows-6{grid-template-rows:repeat(6,minmax(0,1fr))}.md\:grid-rows-none{grid-template-rows:none}.md\:auto-rows-auto{grid-auto-rows:auto}.md\:auto-rows-min{grid-auto-rows:-webkit-min-content;grid-auto-rows:min-content}.md\:auto-rows-max{grid-auto-rows:-webkit-max-content;grid-auto-rows:max-content}.md\:auto-rows-fr{grid-auto-rows:minmax(0,1fr)}.md\:row-auto{grid-row:auto}.md\:row-span-1{grid-row:span 1/span 1}.md\:row-span-2{grid-row:span 2/span 2}.md\:row-span-3{grid-row:span 3/span 3}.md\:row-span-4{grid-row:span 4/span 4}.md\:row-span-5{grid-row:span 5/span 5}.md\:row-span-6{grid-row:span 6/span 6}.md\:row-span-full{grid-row:1/-1}.md\:row-start-1{grid-row-start:1}.md\:row-start-2{grid-row-start:2}.md\:row-start-3{grid-row-start:3}.md\:row-start-4{grid-row-start:4}.md\:row-start-5{grid-row-start:5}.md\:row-start-6{grid-row-start:6}.md\:row-start-7{grid-row-start:7}.md\:row-start-auto{grid-row-start:auto}.md\:row-end-1{grid-row-end:1}.md\:row-end-2{grid-row-end:2}.md\:row-end-3{grid-row-end:3}.md\:row-end-4{grid-row-end:4}.md\:row-end-5{grid-row-end:5}.md\:row-end-6{grid-row-end:6}.md\:row-end-7{grid-row-end:7}.md\:row-end-auto{grid-row-end:auto}.md\:transform{--transform-translate-x:0;--transform-translate-y:0;--transform-rotate:0;--transform-skew-x:0;--transform-skew-y:0;--transform-scale-x:1;--transform-scale-y:1;transform:translateX(var(--transform-translate-x)) translateY(var(--transform-translate-y)) rotate(var(--transform-rotate)) skewX(var(--transform-skew-x)) skewY(var(--transform-skew-y)) scaleX(var(--transform-scale-x)) scaleY(var(--transform-scale-y))}.md\:transform-none{transform:none}.md\:origin-center{transform-origin:center}.md\:origin-top{transform-origin:top}.md\:origin-top-right{transform-origin:top right}.md\:origin-right{transform-origin:right}.md\:origin-bottom-right{transform-origin:bottom right}.md\:origin-bottom{transform-origin:bottom}.md\:origin-bottom-left{transform-origin:bottom left}.md\:origin-left{transform-origin:left}.md\:origin-top-left{transform-origin:top left}.md\:scale-0{--transform-scale-x:0;--transform-scale-y:0}.md\:scale-50{--transform-scale-x:.5;--transform-scale-y:.5}.md\:scale-75{--transform-scale-x:.75;--transform-scale-y:.75}.md\:scale-90{--transform-scale-x:.9;--transform-scale-y:.9}.md\:scale-95{--transform-scale-x:.95;--transform-scale-y:.95}.md\:scale-100{--transform-scale-x:1;--transform-scale-y:1}.md\:scale-105{--transform-scale-x:1.05;--transform-scale-y:1.05}.md\:scale-110{--transform-scale-x:1.1;--transform-scale-y:1.1}.md\:scale-125{--transform-scale-x:1.25;--transform-scale-y:1.25}.md\:scale-150{--transform-scale-x:1.5;--transform-scale-y:1.5}.md\:scale-x-0{--transform-scale-x:0}.md\:scale-x-50{--transform-scale-x:.5}.md\:scale-x-75{--transform-scale-x:.75}.md\:scale-x-90{--transform-scale-x:.9}.md\:scale-x-95{--transform-scale-x:.95}.md\:scale-x-100{--transform-scale-x:1}.md\:scale-x-105{--transform-scale-x:1.05}.md\:scale-x-110{--transform-scale-x:1.1}.md\:scale-x-125{--transform-scale-x:1.25}.md\:scale-x-150{--transform-scale-x:1.5}.md\:scale-y-0{--transform-scale-y:0}.md\:scale-y-50{--transform-scale-y:.5}.md\:scale-y-75{--transform-scale-y:.75}.md\:scale-y-90{--transform-scale-y:.9}.md\:scale-y-95{--transform-scale-y:.95}.md\:scale-y-100{--transform-scale-y:1}.md\:scale-y-105{--transform-scale-y:1.05}.md\:scale-y-110{--transform-scale-y:1.1}.md\:scale-y-125{--transform-scale-y:1.25}.md\:scale-y-150{--transform-scale-y:1.5}.md\:hover\:scale-0:hover{--transform-scale-x:0;--transform-scale-y:0}.md\:hover\:scale-50:hover{--transform-scale-x:.5;--transform-scale-y:.5}.md\:hover\:scale-75:hover{--transform-scale-x:.75;--transform-scale-y:.75}.md\:hover\:scale-90:hover{--transform-scale-x:.9;--transform-scale-y:.9}.md\:hover\:scale-95:hover{--transform-scale-x:.95;--transform-scale-y:.95}.md\:hover\:scale-100:hover{--transform-scale-x:1;--transform-scale-y:1}.md\:hover\:scale-105:hover{--transform-scale-x:1.05;--transform-scale-y:1.05}.md\:hover\:scale-110:hover{--transform-scale-x:1.1;--transform-scale-y:1.1}.md\:hover\:scale-125:hover{--transform-scale-x:1.25;--transform-scale-y:1.25}.md\:hover\:scale-150:hover{--transform-scale-x:1.5;--transform-scale-y:1.5}.md\:hover\:scale-x-0:hover{--transform-scale-x:0}.md\:hover\:scale-x-50:hover{--transform-scale-x:.5}.md\:hover\:scale-x-75:hover{--transform-scale-x:.75}.md\:hover\:scale-x-90:hover{--transform-scale-x:.9}.md\:hover\:scale-x-95:hover{--transform-scale-x:.95}.md\:hover\:scale-x-100:hover{--transform-scale-x:1}.md\:hover\:scale-x-105:hover{--transform-scale-x:1.05}.md\:hover\:scale-x-110:hover{--transform-scale-x:1.1}.md\:hover\:scale-x-125:hover{--transform-scale-x:1.25}.md\:hover\:scale-x-150:hover{--transform-scale-x:1.5}.md\:hover\:scale-y-0:hover{--transform-scale-y:0}.md\:hover\:scale-y-50:hover{--transform-scale-y:.5}.md\:hover\:scale-y-75:hover{--transform-scale-y:.75}.md\:hover\:scale-y-90:hover{--transform-scale-y:.9}.md\:hover\:scale-y-95:hover{--transform-scale-y:.95}.md\:hover\:scale-y-100:hover{--transform-scale-y:1}.md\:hover\:scale-y-105:hover{--transform-scale-y:1.05}.md\:hover\:scale-y-110:hover{--transform-scale-y:1.1}.md\:hover\:scale-y-125:hover{--transform-scale-y:1.25}.md\:hover\:scale-y-150:hover{--transform-scale-y:1.5}.md\:focus\:scale-0:focus{--transform-scale-x:0;--transform-scale-y:0}.md\:focus\:scale-50:focus{--transform-scale-x:.5;--transform-scale-y:.5}.md\:focus\:scale-75:focus{--transform-scale-x:.75;--transform-scale-y:.75}.md\:focus\:scale-90:focus{--transform-scale-x:.9;--transform-scale-y:.9}.md\:focus\:scale-95:focus{--transform-scale-x:.95;--transform-scale-y:.95}.md\:focus\:scale-100:focus{--transform-scale-x:1;--transform-scale-y:1}.md\:focus\:scale-105:focus{--transform-scale-x:1.05;--transform-scale-y:1.05}.md\:focus\:scale-110:focus{--transform-scale-x:1.1;--transform-scale-y:1.1}.md\:focus\:scale-125:focus{--transform-scale-x:1.25;--transform-scale-y:1.25}.md\:focus\:scale-150:focus{--transform-scale-x:1.5;--transform-scale-y:1.5}.md\:focus\:scale-x-0:focus{--transform-scale-x:0}.md\:focus\:scale-x-50:focus{--transform-scale-x:.5}.md\:focus\:scale-x-75:focus{--transform-scale-x:.75}.md\:focus\:scale-x-90:focus{--transform-scale-x:.9}.md\:focus\:scale-x-95:focus{--transform-scale-x:.95}.md\:focus\:scale-x-100:focus{--transform-scale-x:1}.md\:focus\:scale-x-105:focus{--transform-scale-x:1.05}.md\:focus\:scale-x-110:focus{--transform-scale-x:1.1}.md\:focus\:scale-x-125:focus{--transform-scale-x:1.25}.md\:focus\:scale-x-150:focus{--transform-scale-x:1.5}.md\:focus\:scale-y-0:focus{--transform-scale-y:0}.md\:focus\:scale-y-50:focus{--transform-scale-y:.5}.md\:focus\:scale-y-75:focus{--transform-scale-y:.75}.md\:focus\:scale-y-90:focus{--transform-scale-y:.9}.md\:focus\:scale-y-95:focus{--transform-scale-y:.95}.md\:focus\:scale-y-100:focus{--transform-scale-y:1}.md\:focus\:scale-y-105:focus{--transform-scale-y:1.05}.md\:focus\:scale-y-110:focus{--transform-scale-y:1.1}.md\:focus\:scale-y-125:focus{--transform-scale-y:1.25}.md\:focus\:scale-y-150:focus{--transform-scale-y:1.5}.md\:rotate-0{--transform-rotate:0}.md\:rotate-1{--transform-rotate:1deg}.md\:rotate-2{--transform-rotate:2deg}.md\:rotate-3{--transform-rotate:3deg}.md\:rotate-6{--transform-rotate:6deg}.md\:rotate-12{--transform-rotate:12deg}.md\:rotate-45{--transform-rotate:45deg}.md\:rotate-90{--transform-rotate:90deg}.md\:rotate-180{--transform-rotate:180deg}.md\:-rotate-180{--transform-rotate:-180deg}.md\:-rotate-90{--transform-rotate:-90deg}.md\:-rotate-45{--transform-rotate:-45deg}.md\:-rotate-12{--transform-rotate:-12deg}.md\:-rotate-6{--transform-rotate:-6deg}.md\:-rotate-3{--transform-rotate:-3deg}.md\:-rotate-2{--transform-rotate:-2deg}.md\:-rotate-1{--transform-rotate:-1deg}.md\:hover\:rotate-0:hover{--transform-rotate:0}.md\:hover\:rotate-1:hover{--transform-rotate:1deg}.md\:hover\:rotate-2:hover{--transform-rotate:2deg}.md\:hover\:rotate-3:hover{--transform-rotate:3deg}.md\:hover\:rotate-6:hover{--transform-rotate:6deg}.md\:hover\:rotate-12:hover{--transform-rotate:12deg}.md\:hover\:rotate-45:hover{--transform-rotate:45deg}.md\:hover\:rotate-90:hover{--transform-rotate:90deg}.md\:hover\:rotate-180:hover{--transform-rotate:180deg}.md\:hover\:-rotate-180:hover{--transform-rotate:-180deg}.md\:hover\:-rotate-90:hover{--transform-rotate:-90deg}.md\:hover\:-rotate-45:hover{--transform-rotate:-45deg}.md\:hover\:-rotate-12:hover{--transform-rotate:-12deg}.md\:hover\:-rotate-6:hover{--transform-rotate:-6deg}.md\:hover\:-rotate-3:hover{--transform-rotate:-3deg}.md\:hover\:-rotate-2:hover{--transform-rotate:-2deg}.md\:hover\:-rotate-1:hover{--transform-rotate:-1deg}.md\:focus\:rotate-0:focus{--transform-rotate:0}.md\:focus\:rotate-1:focus{--transform-rotate:1deg}.md\:focus\:rotate-2:focus{--transform-rotate:2deg}.md\:focus\:rotate-3:focus{--transform-rotate:3deg}.md\:focus\:rotate-6:focus{--transform-rotate:6deg}.md\:focus\:rotate-12:focus{--transform-rotate:12deg}.md\:focus\:rotate-45:focus{--transform-rotate:45deg}.md\:focus\:rotate-90:focus{--transform-rotate:90deg}.md\:focus\:rotate-180:focus{--transform-rotate:180deg}.md\:focus\:-rotate-180:focus{--transform-rotate:-180deg}.md\:focus\:-rotate-90:focus{--transform-rotate:-90deg}.md\:focus\:-rotate-45:focus{--transform-rotate:-45deg}.md\:focus\:-rotate-12:focus{--transform-rotate:-12deg}.md\:focus\:-rotate-6:focus{--transform-rotate:-6deg}.md\:focus\:-rotate-3:focus{--transform-rotate:-3deg}.md\:focus\:-rotate-2:focus{--transform-rotate:-2deg}.md\:focus\:-rotate-1:focus{--transform-rotate:-1deg}.md\:translate-x-0{--transform-translate-x:0}.md\:translate-x-1{--transform-translate-x:0.25rem}.md\:translate-x-2{--transform-translate-x:0.5rem}.md\:translate-x-3{--transform-translate-x:0.75rem}.md\:translate-x-4{--transform-translate-x:1rem}.md\:translate-x-5{--transform-translate-x:1.25rem}.md\:translate-x-6{--transform-translate-x:1.5rem}.md\:translate-x-8{--transform-translate-x:2rem}.md\:translate-x-10{--transform-translate-x:2.5rem}.md\:translate-x-12{--transform-translate-x:3rem}.md\:translate-x-16{--transform-translate-x:4rem}.md\:translate-x-20{--transform-translate-x:5rem}.md\:translate-x-24{--transform-translate-x:6rem}.md\:translate-x-32{--transform-translate-x:8rem}.md\:translate-x-40{--transform-translate-x:10rem}.md\:translate-x-48{--transform-translate-x:12rem}.md\:translate-x-56{--transform-translate-x:14rem}.md\:translate-x-64{--transform-translate-x:16rem}.md\:translate-x-px{--transform-translate-x:1px}.md\:-translate-x-1{--transform-translate-x:-0.25rem}.md\:-translate-x-2{--transform-translate-x:-0.5rem}.md\:-translate-x-3{--transform-translate-x:-0.75rem}.md\:-translate-x-4{--transform-translate-x:-1rem}.md\:-translate-x-5{--transform-translate-x:-1.25rem}.md\:-translate-x-6{--transform-translate-x:-1.5rem}.md\:-translate-x-8{--transform-translate-x:-2rem}.md\:-translate-x-10{--transform-translate-x:-2.5rem}.md\:-translate-x-12{--transform-translate-x:-3rem}.md\:-translate-x-16{--transform-translate-x:-4rem}.md\:-translate-x-20{--transform-translate-x:-5rem}.md\:-translate-x-24{--transform-translate-x:-6rem}.md\:-translate-x-32{--transform-translate-x:-8rem}.md\:-translate-x-40{--transform-translate-x:-10rem}.md\:-translate-x-48{--transform-translate-x:-12rem}.md\:-translate-x-56{--transform-translate-x:-14rem}.md\:-translate-x-64{--transform-translate-x:-16rem}.md\:-translate-x-px{--transform-translate-x:-1px}.md\:-translate-x-full{--transform-translate-x:-100%}.md\:-translate-x-1\/2{--transform-translate-x:-50%}.md\:translate-x-1\/2{--transform-translate-x:50%}.md\:translate-x-full{--transform-translate-x:100%}.md\:translate-y-0{--transform-translate-y:0}.md\:translate-y-1{--transform-translate-y:0.25rem}.md\:translate-y-2{--transform-translate-y:0.5rem}.md\:translate-y-3{--transform-translate-y:0.75rem}.md\:translate-y-4{--transform-translate-y:1rem}.md\:translate-y-5{--transform-translate-y:1.25rem}.md\:translate-y-6{--transform-translate-y:1.5rem}.md\:translate-y-8{--transform-translate-y:2rem}.md\:translate-y-10{--transform-translate-y:2.5rem}.md\:translate-y-12{--transform-translate-y:3rem}.md\:translate-y-16{--transform-translate-y:4rem}.md\:translate-y-20{--transform-translate-y:5rem}.md\:translate-y-24{--transform-translate-y:6rem}.md\:translate-y-32{--transform-translate-y:8rem}.md\:translate-y-40{--transform-translate-y:10rem}.md\:translate-y-48{--transform-translate-y:12rem}.md\:translate-y-56{--transform-translate-y:14rem}.md\:translate-y-64{--transform-translate-y:16rem}.md\:translate-y-px{--transform-translate-y:1px}.md\:-translate-y-1{--transform-translate-y:-0.25rem}.md\:-translate-y-2{--transform-translate-y:-0.5rem}.md\:-translate-y-3{--transform-translate-y:-0.75rem}.md\:-translate-y-4{--transform-translate-y:-1rem}.md\:-translate-y-5{--transform-translate-y:-1.25rem}.md\:-translate-y-6{--transform-translate-y:-1.5rem}.md\:-translate-y-8{--transform-translate-y:-2rem}.md\:-translate-y-10{--transform-translate-y:-2.5rem}.md\:-translate-y-12{--transform-translate-y:-3rem}.md\:-translate-y-16{--transform-translate-y:-4rem}.md\:-translate-y-20{--transform-translate-y:-5rem}.md\:-translate-y-24{--transform-translate-y:-6rem}.md\:-translate-y-32{--transform-translate-y:-8rem}.md\:-translate-y-40{--transform-translate-y:-10rem}.md\:-translate-y-48{--transform-translate-y:-12rem}.md\:-translate-y-56{--transform-translate-y:-14rem}.md\:-translate-y-64{--transform-translate-y:-16rem}.md\:-translate-y-px{--transform-translate-y:-1px}.md\:-translate-y-full{--transform-translate-y:-100%}.md\:-translate-y-1\/2{--transform-translate-y:-50%}.md\:translate-y-1\/2{--transform-translate-y:50%}.md\:translate-y-full{--transform-translate-y:100%}.md\:hover\:translate-x-0:hover{--transform-translate-x:0}.md\:hover\:translate-x-1:hover{--transform-translate-x:0.25rem}.md\:hover\:translate-x-2:hover{--transform-translate-x:0.5rem}.md\:hover\:translate-x-3:hover{--transform-translate-x:0.75rem}.md\:hover\:translate-x-4:hover{--transform-translate-x:1rem}.md\:hover\:translate-x-5:hover{--transform-translate-x:1.25rem}.md\:hover\:translate-x-6:hover{--transform-translate-x:1.5rem}.md\:hover\:translate-x-8:hover{--transform-translate-x:2rem}.md\:hover\:translate-x-10:hover{--transform-translate-x:2.5rem}.md\:hover\:translate-x-12:hover{--transform-translate-x:3rem}.md\:hover\:translate-x-16:hover{--transform-translate-x:4rem}.md\:hover\:translate-x-20:hover{--transform-translate-x:5rem}.md\:hover\:translate-x-24:hover{--transform-translate-x:6rem}.md\:hover\:translate-x-32:hover{--transform-translate-x:8rem}.md\:hover\:translate-x-40:hover{--transform-translate-x:10rem}.md\:hover\:translate-x-48:hover{--transform-translate-x:12rem}.md\:hover\:translate-x-56:hover{--transform-translate-x:14rem}.md\:hover\:translate-x-64:hover{--transform-translate-x:16rem}.md\:hover\:translate-x-px:hover{--transform-translate-x:1px}.md\:hover\:-translate-x-1:hover{--transform-translate-x:-0.25rem}.md\:hover\:-translate-x-2:hover{--transform-translate-x:-0.5rem}.md\:hover\:-translate-x-3:hover{--transform-translate-x:-0.75rem}.md\:hover\:-translate-x-4:hover{--transform-translate-x:-1rem}.md\:hover\:-translate-x-5:hover{--transform-translate-x:-1.25rem}.md\:hover\:-translate-x-6:hover{--transform-translate-x:-1.5rem}.md\:hover\:-translate-x-8:hover{--transform-translate-x:-2rem}.md\:hover\:-translate-x-10:hover{--transform-translate-x:-2.5rem}.md\:hover\:-translate-x-12:hover{--transform-translate-x:-3rem}.md\:hover\:-translate-x-16:hover{--transform-translate-x:-4rem}.md\:hover\:-translate-x-20:hover{--transform-translate-x:-5rem}.md\:hover\:-translate-x-24:hover{--transform-translate-x:-6rem}.md\:hover\:-translate-x-32:hover{--transform-translate-x:-8rem}.md\:hover\:-translate-x-40:hover{--transform-translate-x:-10rem}.md\:hover\:-translate-x-48:hover{--transform-translate-x:-12rem}.md\:hover\:-translate-x-56:hover{--transform-translate-x:-14rem}.md\:hover\:-translate-x-64:hover{--transform-translate-x:-16rem}.md\:hover\:-translate-x-px:hover{--transform-translate-x:-1px}.md\:hover\:-translate-x-full:hover{--transform-translate-x:-100%}.md\:hover\:-translate-x-1\/2:hover{--transform-translate-x:-50%}.md\:hover\:translate-x-1\/2:hover{--transform-translate-x:50%}.md\:hover\:translate-x-full:hover{--transform-translate-x:100%}.md\:hover\:translate-y-0:hover{--transform-translate-y:0}.md\:hover\:translate-y-1:hover{--transform-translate-y:0.25rem}.md\:hover\:translate-y-2:hover{--transform-translate-y:0.5rem}.md\:hover\:translate-y-3:hover{--transform-translate-y:0.75rem}.md\:hover\:translate-y-4:hover{--transform-translate-y:1rem}.md\:hover\:translate-y-5:hover{--transform-translate-y:1.25rem}.md\:hover\:translate-y-6:hover{--transform-translate-y:1.5rem}.md\:hover\:translate-y-8:hover{--transform-translate-y:2rem}.md\:hover\:translate-y-10:hover{--transform-translate-y:2.5rem}.md\:hover\:translate-y-12:hover{--transform-translate-y:3rem}.md\:hover\:translate-y-16:hover{--transform-translate-y:4rem}.md\:hover\:translate-y-20:hover{--transform-translate-y:5rem}.md\:hover\:translate-y-24:hover{--transform-translate-y:6rem}.md\:hover\:translate-y-32:hover{--transform-translate-y:8rem}.md\:hover\:translate-y-40:hover{--transform-translate-y:10rem}.md\:hover\:translate-y-48:hover{--transform-translate-y:12rem}.md\:hover\:translate-y-56:hover{--transform-translate-y:14rem}.md\:hover\:translate-y-64:hover{--transform-translate-y:16rem}.md\:hover\:translate-y-px:hover{--transform-translate-y:1px}.md\:hover\:-translate-y-1:hover{--transform-translate-y:-0.25rem}.md\:hover\:-translate-y-2:hover{--transform-translate-y:-0.5rem}.md\:hover\:-translate-y-3:hover{--transform-translate-y:-0.75rem}.md\:hover\:-translate-y-4:hover{--transform-translate-y:-1rem}.md\:hover\:-translate-y-5:hover{--transform-translate-y:-1.25rem}.md\:hover\:-translate-y-6:hover{--transform-translate-y:-1.5rem}.md\:hover\:-translate-y-8:hover{--transform-translate-y:-2rem}.md\:hover\:-translate-y-10:hover{--transform-translate-y:-2.5rem}.md\:hover\:-translate-y-12:hover{--transform-translate-y:-3rem}.md\:hover\:-translate-y-16:hover{--transform-translate-y:-4rem}.md\:hover\:-translate-y-20:hover{--transform-translate-y:-5rem}.md\:hover\:-translate-y-24:hover{--transform-translate-y:-6rem}.md\:hover\:-translate-y-32:hover{--transform-translate-y:-8rem}.md\:hover\:-translate-y-40:hover{--transform-translate-y:-10rem}.md\:hover\:-translate-y-48:hover{--transform-translate-y:-12rem}.md\:hover\:-translate-y-56:hover{--transform-translate-y:-14rem}.md\:hover\:-translate-y-64:hover{--transform-translate-y:-16rem}.md\:hover\:-translate-y-px:hover{--transform-translate-y:-1px}.md\:hover\:-translate-y-full:hover{--transform-translate-y:-100%}.md\:hover\:-translate-y-1\/2:hover{--transform-translate-y:-50%}.md\:hover\:translate-y-1\/2:hover{--transform-translate-y:50%}.md\:hover\:translate-y-full:hover{--transform-translate-y:100%}.md\:focus\:translate-x-0:focus{--transform-translate-x:0}.md\:focus\:translate-x-1:focus{--transform-translate-x:0.25rem}.md\:focus\:translate-x-2:focus{--transform-translate-x:0.5rem}.md\:focus\:translate-x-3:focus{--transform-translate-x:0.75rem}.md\:focus\:translate-x-4:focus{--transform-translate-x:1rem}.md\:focus\:translate-x-5:focus{--transform-translate-x:1.25rem}.md\:focus\:translate-x-6:focus{--transform-translate-x:1.5rem}.md\:focus\:translate-x-8:focus{--transform-translate-x:2rem}.md\:focus\:translate-x-10:focus{--transform-translate-x:2.5rem}.md\:focus\:translate-x-12:focus{--transform-translate-x:3rem}.md\:focus\:translate-x-16:focus{--transform-translate-x:4rem}.md\:focus\:translate-x-20:focus{--transform-translate-x:5rem}.md\:focus\:translate-x-24:focus{--transform-translate-x:6rem}.md\:focus\:translate-x-32:focus{--transform-translate-x:8rem}.md\:focus\:translate-x-40:focus{--transform-translate-x:10rem}.md\:focus\:translate-x-48:focus{--transform-translate-x:12rem}.md\:focus\:translate-x-56:focus{--transform-translate-x:14rem}.md\:focus\:translate-x-64:focus{--transform-translate-x:16rem}.md\:focus\:translate-x-px:focus{--transform-translate-x:1px}.md\:focus\:-translate-x-1:focus{--transform-translate-x:-0.25rem}.md\:focus\:-translate-x-2:focus{--transform-translate-x:-0.5rem}.md\:focus\:-translate-x-3:focus{--transform-translate-x:-0.75rem}.md\:focus\:-translate-x-4:focus{--transform-translate-x:-1rem}.md\:focus\:-translate-x-5:focus{--transform-translate-x:-1.25rem}.md\:focus\:-translate-x-6:focus{--transform-translate-x:-1.5rem}.md\:focus\:-translate-x-8:focus{--transform-translate-x:-2rem}.md\:focus\:-translate-x-10:focus{--transform-translate-x:-2.5rem}.md\:focus\:-translate-x-12:focus{--transform-translate-x:-3rem}.md\:focus\:-translate-x-16:focus{--transform-translate-x:-4rem}.md\:focus\:-translate-x-20:focus{--transform-translate-x:-5rem}.md\:focus\:-translate-x-24:focus{--transform-translate-x:-6rem}.md\:focus\:-translate-x-32:focus{--transform-translate-x:-8rem}.md\:focus\:-translate-x-40:focus{--transform-translate-x:-10rem}.md\:focus\:-translate-x-48:focus{--transform-translate-x:-12rem}.md\:focus\:-translate-x-56:focus{--transform-translate-x:-14rem}.md\:focus\:-translate-x-64:focus{--transform-translate-x:-16rem}.md\:focus\:-translate-x-px:focus{--transform-translate-x:-1px}.md\:focus\:-translate-x-full:focus{--transform-translate-x:-100%}.md\:focus\:-translate-x-1\/2:focus{--transform-translate-x:-50%}.md\:focus\:translate-x-1\/2:focus{--transform-translate-x:50%}.md\:focus\:translate-x-full:focus{--transform-translate-x:100%}.md\:focus\:translate-y-0:focus{--transform-translate-y:0}.md\:focus\:translate-y-1:focus{--transform-translate-y:0.25rem}.md\:focus\:translate-y-2:focus{--transform-translate-y:0.5rem}.md\:focus\:translate-y-3:focus{--transform-translate-y:0.75rem}.md\:focus\:translate-y-4:focus{--transform-translate-y:1rem}.md\:focus\:translate-y-5:focus{--transform-translate-y:1.25rem}.md\:focus\:translate-y-6:focus{--transform-translate-y:1.5rem}.md\:focus\:translate-y-8:focus{--transform-translate-y:2rem}.md\:focus\:translate-y-10:focus{--transform-translate-y:2.5rem}.md\:focus\:translate-y-12:focus{--transform-translate-y:3rem}.md\:focus\:translate-y-16:focus{--transform-translate-y:4rem}.md\:focus\:translate-y-20:focus{--transform-translate-y:5rem}.md\:focus\:translate-y-24:focus{--transform-translate-y:6rem}.md\:focus\:translate-y-32:focus{--transform-translate-y:8rem}.md\:focus\:translate-y-40:focus{--transform-translate-y:10rem}.md\:focus\:translate-y-48:focus{--transform-translate-y:12rem}.md\:focus\:translate-y-56:focus{--transform-translate-y:14rem}.md\:focus\:translate-y-64:focus{--transform-translate-y:16rem}.md\:focus\:translate-y-px:focus{--transform-translate-y:1px}.md\:focus\:-translate-y-1:focus{--transform-translate-y:-0.25rem}.md\:focus\:-translate-y-2:focus{--transform-translate-y:-0.5rem}.md\:focus\:-translate-y-3:focus{--transform-translate-y:-0.75rem}.md\:focus\:-translate-y-4:focus{--transform-translate-y:-1rem}.md\:focus\:-translate-y-5:focus{--transform-translate-y:-1.25rem}.md\:focus\:-translate-y-6:focus{--transform-translate-y:-1.5rem}.md\:focus\:-translate-y-8:focus{--transform-translate-y:-2rem}.md\:focus\:-translate-y-10:focus{--transform-translate-y:-2.5rem}.md\:focus\:-translate-y-12:focus{--transform-translate-y:-3rem}.md\:focus\:-translate-y-16:focus{--transform-translate-y:-4rem}.md\:focus\:-translate-y-20:focus{--transform-translate-y:-5rem}.md\:focus\:-translate-y-24:focus{--transform-translate-y:-6rem}.md\:focus\:-translate-y-32:focus{--transform-translate-y:-8rem}.md\:focus\:-translate-y-40:focus{--transform-translate-y:-10rem}.md\:focus\:-translate-y-48:focus{--transform-translate-y:-12rem}.md\:focus\:-translate-y-56:focus{--transform-translate-y:-14rem}.md\:focus\:-translate-y-64:focus{--transform-translate-y:-16rem}.md\:focus\:-translate-y-px:focus{--transform-translate-y:-1px}.md\:focus\:-translate-y-full:focus{--transform-translate-y:-100%}.md\:focus\:-translate-y-1\/2:focus{--transform-translate-y:-50%}.md\:focus\:translate-y-1\/2:focus{--transform-translate-y:50%}.md\:focus\:translate-y-full:focus{--transform-translate-y:100%}.md\:skew-x-0{--transform-skew-x:0}.md\:skew-x-1{--transform-skew-x:1deg}.md\:skew-x-2{--transform-skew-x:2deg}.md\:skew-x-3{--transform-skew-x:3deg}.md\:skew-x-6{--transform-skew-x:6deg}.md\:skew-x-12{--transform-skew-x:12deg}.md\:-skew-x-12{--transform-skew-x:-12deg}.md\:-skew-x-6{--transform-skew-x:-6deg}.md\:-skew-x-3{--transform-skew-x:-3deg}.md\:-skew-x-2{--transform-skew-x:-2deg}.md\:-skew-x-1{--transform-skew-x:-1deg}.md\:skew-y-0{--transform-skew-y:0}.md\:skew-y-1{--transform-skew-y:1deg}.md\:skew-y-2{--transform-skew-y:2deg}.md\:skew-y-3{--transform-skew-y:3deg}.md\:skew-y-6{--transform-skew-y:6deg}.md\:skew-y-12{--transform-skew-y:12deg}.md\:-skew-y-12{--transform-skew-y:-12deg}.md\:-skew-y-6{--transform-skew-y:-6deg}.md\:-skew-y-3{--transform-skew-y:-3deg}.md\:-skew-y-2{--transform-skew-y:-2deg}.md\:-skew-y-1{--transform-skew-y:-1deg}.md\:hover\:skew-x-0:hover{--transform-skew-x:0}.md\:hover\:skew-x-1:hover{--transform-skew-x:1deg}.md\:hover\:skew-x-2:hover{--transform-skew-x:2deg}.md\:hover\:skew-x-3:hover{--transform-skew-x:3deg}.md\:hover\:skew-x-6:hover{--transform-skew-x:6deg}.md\:hover\:skew-x-12:hover{--transform-skew-x:12deg}.md\:hover\:-skew-x-12:hover{--transform-skew-x:-12deg}.md\:hover\:-skew-x-6:hover{--transform-skew-x:-6deg}.md\:hover\:-skew-x-3:hover{--transform-skew-x:-3deg}.md\:hover\:-skew-x-2:hover{--transform-skew-x:-2deg}.md\:hover\:-skew-x-1:hover{--transform-skew-x:-1deg}.md\:hover\:skew-y-0:hover{--transform-skew-y:0}.md\:hover\:skew-y-1:hover{--transform-skew-y:1deg}.md\:hover\:skew-y-2:hover{--transform-skew-y:2deg}.md\:hover\:skew-y-3:hover{--transform-skew-y:3deg}.md\:hover\:skew-y-6:hover{--transform-skew-y:6deg}.md\:hover\:skew-y-12:hover{--transform-skew-y:12deg}.md\:hover\:-skew-y-12:hover{--transform-skew-y:-12deg}.md\:hover\:-skew-y-6:hover{--transform-skew-y:-6deg}.md\:hover\:-skew-y-3:hover{--transform-skew-y:-3deg}.md\:hover\:-skew-y-2:hover{--transform-skew-y:-2deg}.md\:hover\:-skew-y-1:hover{--transform-skew-y:-1deg}.md\:focus\:skew-x-0:focus{--transform-skew-x:0}.md\:focus\:skew-x-1:focus{--transform-skew-x:1deg}.md\:focus\:skew-x-2:focus{--transform-skew-x:2deg}.md\:focus\:skew-x-3:focus{--transform-skew-x:3deg}.md\:focus\:skew-x-6:focus{--transform-skew-x:6deg}.md\:focus\:skew-x-12:focus{--transform-skew-x:12deg}.md\:focus\:-skew-x-12:focus{--transform-skew-x:-12deg}.md\:focus\:-skew-x-6:focus{--transform-skew-x:-6deg}.md\:focus\:-skew-x-3:focus{--transform-skew-x:-3deg}.md\:focus\:-skew-x-2:focus{--transform-skew-x:-2deg}.md\:focus\:-skew-x-1:focus{--transform-skew-x:-1deg}.md\:focus\:skew-y-0:focus{--transform-skew-y:0}.md\:focus\:skew-y-1:focus{--transform-skew-y:1deg}.md\:focus\:skew-y-2:focus{--transform-skew-y:2deg}.md\:focus\:skew-y-3:focus{--transform-skew-y:3deg}.md\:focus\:skew-y-6:focus{--transform-skew-y:6deg}.md\:focus\:skew-y-12:focus{--transform-skew-y:12deg}.md\:focus\:-skew-y-12:focus{--transform-skew-y:-12deg}.md\:focus\:-skew-y-6:focus{--transform-skew-y:-6deg}.md\:focus\:-skew-y-3:focus{--transform-skew-y:-3deg}.md\:focus\:-skew-y-2:focus{--transform-skew-y:-2deg}.md\:focus\:-skew-y-1:focus{--transform-skew-y:-1deg}.md\:transition-none{transition-property:none}.md\:transition-all{transition-property:all}.md\:transition{transition-property:background-color,border-color,color,fill,stroke,opacity,box-shadow,transform}.md\:transition-colors{transition-property:background-color,border-color,color,fill,stroke}.md\:transition-opacity{transition-property:opacity}.md\:transition-shadow{transition-property:box-shadow}.md\:transition-transform{transition-property:transform}.md\:ease-linear{transition-timing-function:linear}.md\:ease-in{transition-timing-function:cubic-bezier(.4,0,1,1)}.md\:ease-out{transition-timing-function:cubic-bezier(0,0,.2,1)}.md\:ease-in-out{transition-timing-function:cubic-bezier(.4,0,.2,1)}.md\:duration-75{transition-duration:75ms}.md\:duration-100{transition-duration:.1s}.md\:duration-150{transition-duration:150ms}.md\:duration-200{transition-duration:.2s}.md\:duration-300{transition-duration:.3s}.md\:duration-500{transition-duration:.5s}.md\:duration-700{transition-duration:.7s}.md\:duration-1000{transition-duration:1s}.md\:delay-75{transition-delay:75ms}.md\:delay-100{transition-delay:.1s}.md\:delay-150{transition-delay:150ms}.md\:delay-200{transition-delay:.2s}.md\:delay-300{transition-delay:.3s}.md\:delay-500{transition-delay:.5s}.md\:delay-700{transition-delay:.7s}.md\:delay-1000{transition-delay:1s}.md\:animate-none{animation:none}.md\:animate-spin{animation:spin 1s linear infinite}.md\:animate-ping{animation:ping 1s cubic-bezier(0,0,.2,1) infinite}.md\:animate-pulse{animation:pulse 2s cubic-bezier(.4,0,.6,1) infinite}.md\:animate-bounce{animation:bounce 1s infinite}}@media (min-width:1024px){.lg\:container{width:100%}@media (min-width:640px){.lg\:container{max-width:640px}}@media (min-width:768px){.lg\:container{max-width:768px}}@media (min-width:1024px){.lg\:container{max-width:1024px}}@media (min-width:1280px){.lg\:container{max-width:1280px}}.lg\:space-y-0>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(0px * calc(1 - var(--space-y-reverse)));margin-bottom:calc(0px * var(--space-y-reverse))}.lg\:space-x-0>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(0px * var(--space-x-reverse));margin-left:calc(0px * calc(1 - var(--space-x-reverse)))}.lg\:space-y-1>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(.25rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(.25rem * var(--space-y-reverse))}.lg\:space-x-1>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(.25rem * var(--space-x-reverse));margin-left:calc(.25rem * calc(1 - var(--space-x-reverse)))}.lg\:space-y-2>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(.5rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(.5rem * var(--space-y-reverse))}.lg\:space-x-2>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(.5rem * var(--space-x-reverse));margin-left:calc(.5rem * calc(1 - var(--space-x-reverse)))}.lg\:space-y-3>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(.75rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(.75rem * var(--space-y-reverse))}.lg\:space-x-3>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(.75rem * var(--space-x-reverse));margin-left:calc(.75rem * calc(1 - var(--space-x-reverse)))}.lg\:space-y-4>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(1rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(1rem * var(--space-y-reverse))}.lg\:space-x-4>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(1rem * var(--space-x-reverse));margin-left:calc(1rem * calc(1 - var(--space-x-reverse)))}.lg\:space-y-5>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(1.25rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(1.25rem * var(--space-y-reverse))}.lg\:space-x-5>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(1.25rem * var(--space-x-reverse));margin-left:calc(1.25rem * calc(1 - var(--space-x-reverse)))}.lg\:space-y-6>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(1.5rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(1.5rem * var(--space-y-reverse))}.lg\:space-x-6>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(1.5rem * var(--space-x-reverse));margin-left:calc(1.5rem * calc(1 - var(--space-x-reverse)))}.lg\:space-y-8>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(2rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(2rem * var(--space-y-reverse))}.lg\:space-x-8>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(2rem * var(--space-x-reverse));margin-left:calc(2rem * calc(1 - var(--space-x-reverse)))}.lg\:space-y-10>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(2.5rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(2.5rem * var(--space-y-reverse))}.lg\:space-x-10>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(2.5rem * var(--space-x-reverse));margin-left:calc(2.5rem * calc(1 - var(--space-x-reverse)))}.lg\:space-y-12>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(3rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(3rem * var(--space-y-reverse))}.lg\:space-x-12>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(3rem * var(--space-x-reverse));margin-left:calc(3rem * calc(1 - var(--space-x-reverse)))}.lg\:space-y-16>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(4rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(4rem * var(--space-y-reverse))}.lg\:space-x-16>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(4rem * var(--space-x-reverse));margin-left:calc(4rem * calc(1 - var(--space-x-reverse)))}.lg\:space-y-20>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(5rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(5rem * var(--space-y-reverse))}.lg\:space-x-20>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(5rem * var(--space-x-reverse));margin-left:calc(5rem * calc(1 - var(--space-x-reverse)))}.lg\:space-y-24>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(6rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(6rem * var(--space-y-reverse))}.lg\:space-x-24>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(6rem * var(--space-x-reverse));margin-left:calc(6rem * calc(1 - var(--space-x-reverse)))}.lg\:space-y-32>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(8rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(8rem * var(--space-y-reverse))}.lg\:space-x-32>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(8rem * var(--space-x-reverse));margin-left:calc(8rem * calc(1 - var(--space-x-reverse)))}.lg\:space-y-40>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(10rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(10rem * var(--space-y-reverse))}.lg\:space-x-40>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(10rem * var(--space-x-reverse));margin-left:calc(10rem * calc(1 - var(--space-x-reverse)))}.lg\:space-y-48>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(12rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(12rem * var(--space-y-reverse))}.lg\:space-x-48>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(12rem * var(--space-x-reverse));margin-left:calc(12rem * calc(1 - var(--space-x-reverse)))}.lg\:space-y-56>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(14rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(14rem * var(--space-y-reverse))}.lg\:space-x-56>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(14rem * var(--space-x-reverse));margin-left:calc(14rem * calc(1 - var(--space-x-reverse)))}.lg\:space-y-64>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(16rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(16rem * var(--space-y-reverse))}.lg\:space-x-64>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(16rem * var(--space-x-reverse));margin-left:calc(16rem * calc(1 - var(--space-x-reverse)))}.lg\:space-y-px>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(1px * calc(1 - var(--space-y-reverse)));margin-bottom:calc(1px * var(--space-y-reverse))}.lg\:space-x-px>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(1px * var(--space-x-reverse));margin-left:calc(1px * calc(1 - var(--space-x-reverse)))}.lg\:-space-y-1>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-.25rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-.25rem * var(--space-y-reverse))}.lg\:-space-x-1>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-.25rem * var(--space-x-reverse));margin-left:calc(-.25rem * calc(1 - var(--space-x-reverse)))}.lg\:-space-y-2>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-.5rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-.5rem * var(--space-y-reverse))}.lg\:-space-x-2>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-.5rem * var(--space-x-reverse));margin-left:calc(-.5rem * calc(1 - var(--space-x-reverse)))}.lg\:-space-y-3>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-.75rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-.75rem * var(--space-y-reverse))}.lg\:-space-x-3>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-.75rem * var(--space-x-reverse));margin-left:calc(-.75rem * calc(1 - var(--space-x-reverse)))}.lg\:-space-y-4>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-1rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-1rem * var(--space-y-reverse))}.lg\:-space-x-4>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-1rem * var(--space-x-reverse));margin-left:calc(-1rem * calc(1 - var(--space-x-reverse)))}.lg\:-space-y-5>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-1.25rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-1.25rem * var(--space-y-reverse))}.lg\:-space-x-5>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-1.25rem * var(--space-x-reverse));margin-left:calc(-1.25rem * calc(1 - var(--space-x-reverse)))}.lg\:-space-y-6>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-1.5rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-1.5rem * var(--space-y-reverse))}.lg\:-space-x-6>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-1.5rem * var(--space-x-reverse));margin-left:calc(-1.5rem * calc(1 - var(--space-x-reverse)))}.lg\:-space-y-8>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-2rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-2rem * var(--space-y-reverse))}.lg\:-space-x-8>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-2rem * var(--space-x-reverse));margin-left:calc(-2rem * calc(1 - var(--space-x-reverse)))}.lg\:-space-y-10>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-2.5rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-2.5rem * var(--space-y-reverse))}.lg\:-space-x-10>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-2.5rem * var(--space-x-reverse));margin-left:calc(-2.5rem * calc(1 - var(--space-x-reverse)))}.lg\:-space-y-12>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-3rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-3rem * var(--space-y-reverse))}.lg\:-space-x-12>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-3rem * var(--space-x-reverse));margin-left:calc(-3rem * calc(1 - var(--space-x-reverse)))}.lg\:-space-y-16>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-4rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-4rem * var(--space-y-reverse))}.lg\:-space-x-16>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-4rem * var(--space-x-reverse));margin-left:calc(-4rem * calc(1 - var(--space-x-reverse)))}.lg\:-space-y-20>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-5rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-5rem * var(--space-y-reverse))}.lg\:-space-x-20>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-5rem * var(--space-x-reverse));margin-left:calc(-5rem * calc(1 - var(--space-x-reverse)))}.lg\:-space-y-24>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-6rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-6rem * var(--space-y-reverse))}.lg\:-space-x-24>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-6rem * var(--space-x-reverse));margin-left:calc(-6rem * calc(1 - var(--space-x-reverse)))}.lg\:-space-y-32>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-8rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-8rem * var(--space-y-reverse))}.lg\:-space-x-32>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-8rem * var(--space-x-reverse));margin-left:calc(-8rem * calc(1 - var(--space-x-reverse)))}.lg\:-space-y-40>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-10rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-10rem * var(--space-y-reverse))}.lg\:-space-x-40>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-10rem * var(--space-x-reverse));margin-left:calc(-10rem * calc(1 - var(--space-x-reverse)))}.lg\:-space-y-48>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-12rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-12rem * var(--space-y-reverse))}.lg\:-space-x-48>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-12rem * var(--space-x-reverse));margin-left:calc(-12rem * calc(1 - var(--space-x-reverse)))}.lg\:-space-y-56>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-14rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-14rem * var(--space-y-reverse))}.lg\:-space-x-56>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-14rem * var(--space-x-reverse));margin-left:calc(-14rem * calc(1 - var(--space-x-reverse)))}.lg\:-space-y-64>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-16rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-16rem * var(--space-y-reverse))}.lg\:-space-x-64>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-16rem * var(--space-x-reverse));margin-left:calc(-16rem * calc(1 - var(--space-x-reverse)))}.lg\:-space-y-px>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-1px * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-1px * var(--space-y-reverse))}.lg\:-space-x-px>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-1px * var(--space-x-reverse));margin-left:calc(-1px * calc(1 - var(--space-x-reverse)))}.lg\:space-y-reverse>:not(template)~:not(template){--space-y-reverse:1}.lg\:space-x-reverse>:not(template)~:not(template){--space-x-reverse:1}.lg\:divide-y-0>:not(template)~:not(template){--divide-y-reverse:0;border-top-width:calc(0px * calc(1 - var(--divide-y-reverse)));border-bottom-width:calc(0px * var(--divide-y-reverse))}.lg\:divide-x-0>:not(template)~:not(template){--divide-x-reverse:0;border-right-width:calc(0px * var(--divide-x-reverse));border-left-width:calc(0px * calc(1 - var(--divide-x-reverse)))}.lg\:divide-y-2>:not(template)~:not(template){--divide-y-reverse:0;border-top-width:calc(2px * calc(1 - var(--divide-y-reverse)));border-bottom-width:calc(2px * var(--divide-y-reverse))}.lg\:divide-x-2>:not(template)~:not(template){--divide-x-reverse:0;border-right-width:calc(2px * var(--divide-x-reverse));border-left-width:calc(2px * calc(1 - var(--divide-x-reverse)))}.lg\:divide-y-4>:not(template)~:not(template){--divide-y-reverse:0;border-top-width:calc(4px * calc(1 - var(--divide-y-reverse)));border-bottom-width:calc(4px * var(--divide-y-reverse))}.lg\:divide-x-4>:not(template)~:not(template){--divide-x-reverse:0;border-right-width:calc(4px * var(--divide-x-reverse));border-left-width:calc(4px * calc(1 - var(--divide-x-reverse)))}.lg\:divide-y-8>:not(template)~:not(template){--divide-y-reverse:0;border-top-width:calc(8px * calc(1 - var(--divide-y-reverse)));border-bottom-width:calc(8px * var(--divide-y-reverse))}.lg\:divide-x-8>:not(template)~:not(template){--divide-x-reverse:0;border-right-width:calc(8px * var(--divide-x-reverse));border-left-width:calc(8px * calc(1 - var(--divide-x-reverse)))}.lg\:divide-y>:not(template)~:not(template){--divide-y-reverse:0;border-top-width:calc(1px * calc(1 - var(--divide-y-reverse)));border-bottom-width:calc(1px * var(--divide-y-reverse))}.lg\:divide-x>:not(template)~:not(template){--divide-x-reverse:0;border-right-width:calc(1px * var(--divide-x-reverse));border-left-width:calc(1px * calc(1 - var(--divide-x-reverse)))}.lg\:divide-y-reverse>:not(template)~:not(template){--divide-y-reverse:1}.lg\:divide-x-reverse>:not(template)~:not(template){--divide-x-reverse:1}.lg\:divide-transparent>:not(template)~:not(template){border-color:transparent}.lg\:divide-current>:not(template)~:not(template){border-color:currentColor}.lg\:divide-black>:not(template)~:not(template){--divide-opacity:1;border-color:#000;border-color:rgba(0,0,0,var(--divide-opacity))}.lg\:divide-white>:not(template)~:not(template){--divide-opacity:1;border-color:#fff;border-color:rgba(255,255,255,var(--divide-opacity))}.lg\:divide-gray-100>:not(template)~:not(template){--divide-opacity:1;border-color:#f7fafc;border-color:rgba(247,250,252,var(--divide-opacity))}.lg\:divide-gray-200>:not(template)~:not(template){--divide-opacity:1;border-color:#edf2f7;border-color:rgba(237,242,247,var(--divide-opacity))}.lg\:divide-gray-300>:not(template)~:not(template){--divide-opacity:1;border-color:#e2e8f0;border-color:rgba(226,232,240,var(--divide-opacity))}.lg\:divide-gray-400>:not(template)~:not(template){--divide-opacity:1;border-color:#cbd5e0;border-color:rgba(203,213,224,var(--divide-opacity))}.lg\:divide-gray-500>:not(template)~:not(template){--divide-opacity:1;border-color:#a0aec0;border-color:rgba(160,174,192,var(--divide-opacity))}.lg\:divide-gray-600>:not(template)~:not(template){--divide-opacity:1;border-color:#718096;border-color:rgba(113,128,150,var(--divide-opacity))}.lg\:divide-gray-700>:not(template)~:not(template){--divide-opacity:1;border-color:#4a5568;border-color:rgba(74,85,104,var(--divide-opacity))}.lg\:divide-gray-800>:not(template)~:not(template){--divide-opacity:1;border-color:#2d3748;border-color:rgba(45,55,72,var(--divide-opacity))}.lg\:divide-gray-900>:not(template)~:not(template){--divide-opacity:1;border-color:#1a202c;border-color:rgba(26,32,44,var(--divide-opacity))}.lg\:divide-red-100>:not(template)~:not(template){--divide-opacity:1;border-color:#fff5f5;border-color:rgba(255,245,245,var(--divide-opacity))}.lg\:divide-red-200>:not(template)~:not(template){--divide-opacity:1;border-color:#fed7d7;border-color:rgba(254,215,215,var(--divide-opacity))}.lg\:divide-red-300>:not(template)~:not(template){--divide-opacity:1;border-color:#feb2b2;border-color:rgba(254,178,178,var(--divide-opacity))}.lg\:divide-red-400>:not(template)~:not(template){--divide-opacity:1;border-color:#fc8181;border-color:rgba(252,129,129,var(--divide-opacity))}.lg\:divide-red-500>:not(template)~:not(template){--divide-opacity:1;border-color:#f56565;border-color:rgba(245,101,101,var(--divide-opacity))}.lg\:divide-red-600>:not(template)~:not(template){--divide-opacity:1;border-color:#e53e3e;border-color:rgba(229,62,62,var(--divide-opacity))}.lg\:divide-red-700>:not(template)~:not(template){--divide-opacity:1;border-color:#c53030;border-color:rgba(197,48,48,var(--divide-opacity))}.lg\:divide-red-800>:not(template)~:not(template){--divide-opacity:1;border-color:#9b2c2c;border-color:rgba(155,44,44,var(--divide-opacity))}.lg\:divide-red-900>:not(template)~:not(template){--divide-opacity:1;border-color:#742a2a;border-color:rgba(116,42,42,var(--divide-opacity))}.lg\:divide-orange-100>:not(template)~:not(template){--divide-opacity:1;border-color:#fffaf0;border-color:rgba(255,250,240,var(--divide-opacity))}.lg\:divide-orange-200>:not(template)~:not(template){--divide-opacity:1;border-color:#feebc8;border-color:rgba(254,235,200,var(--divide-opacity))}.lg\:divide-orange-300>:not(template)~:not(template){--divide-opacity:1;border-color:#fbd38d;border-color:rgba(251,211,141,var(--divide-opacity))}.lg\:divide-orange-400>:not(template)~:not(template){--divide-opacity:1;border-color:#f6ad55;border-color:rgba(246,173,85,var(--divide-opacity))}.lg\:divide-orange-500>:not(template)~:not(template){--divide-opacity:1;border-color:#ed8936;border-color:rgba(237,137,54,var(--divide-opacity))}.lg\:divide-orange-600>:not(template)~:not(template){--divide-opacity:1;border-color:#dd6b20;border-color:rgba(221,107,32,var(--divide-opacity))}.lg\:divide-orange-700>:not(template)~:not(template){--divide-opacity:1;border-color:#c05621;border-color:rgba(192,86,33,var(--divide-opacity))}.lg\:divide-orange-800>:not(template)~:not(template){--divide-opacity:1;border-color:#9c4221;border-color:rgba(156,66,33,var(--divide-opacity))}.lg\:divide-orange-900>:not(template)~:not(template){--divide-opacity:1;border-color:#7b341e;border-color:rgba(123,52,30,var(--divide-opacity))}.lg\:divide-yellow-100>:not(template)~:not(template){--divide-opacity:1;border-color:ivory;border-color:rgba(255,255,240,var(--divide-opacity))}.lg\:divide-yellow-200>:not(template)~:not(template){--divide-opacity:1;border-color:#fefcbf;border-color:rgba(254,252,191,var(--divide-opacity))}.lg\:divide-yellow-300>:not(template)~:not(template){--divide-opacity:1;border-color:#faf089;border-color:rgba(250,240,137,var(--divide-opacity))}.lg\:divide-yellow-400>:not(template)~:not(template){--divide-opacity:1;border-color:#f6e05e;border-color:rgba(246,224,94,var(--divide-opacity))}.lg\:divide-yellow-500>:not(template)~:not(template){--divide-opacity:1;border-color:#ecc94b;border-color:rgba(236,201,75,var(--divide-opacity))}.lg\:divide-yellow-600>:not(template)~:not(template){--divide-opacity:1;border-color:#d69e2e;border-color:rgba(214,158,46,var(--divide-opacity))}.lg\:divide-yellow-700>:not(template)~:not(template){--divide-opacity:1;border-color:#b7791f;border-color:rgba(183,121,31,var(--divide-opacity))}.lg\:divide-yellow-800>:not(template)~:not(template){--divide-opacity:1;border-color:#975a16;border-color:rgba(151,90,22,var(--divide-opacity))}.lg\:divide-yellow-900>:not(template)~:not(template){--divide-opacity:1;border-color:#744210;border-color:rgba(116,66,16,var(--divide-opacity))}.lg\:divide-green-100>:not(template)~:not(template){--divide-opacity:1;border-color:#f0fff4;border-color:rgba(240,255,244,var(--divide-opacity))}.lg\:divide-green-200>:not(template)~:not(template){--divide-opacity:1;border-color:#c6f6d5;border-color:rgba(198,246,213,var(--divide-opacity))}.lg\:divide-green-300>:not(template)~:not(template){--divide-opacity:1;border-color:#9ae6b4;border-color:rgba(154,230,180,var(--divide-opacity))}.lg\:divide-green-400>:not(template)~:not(template){--divide-opacity:1;border-color:#68d391;border-color:rgba(104,211,145,var(--divide-opacity))}.lg\:divide-green-500>:not(template)~:not(template){--divide-opacity:1;border-color:#48bb78;border-color:rgba(72,187,120,var(--divide-opacity))}.lg\:divide-green-600>:not(template)~:not(template){--divide-opacity:1;border-color:#38a169;border-color:rgba(56,161,105,var(--divide-opacity))}.lg\:divide-green-700>:not(template)~:not(template){--divide-opacity:1;border-color:#2f855a;border-color:rgba(47,133,90,var(--divide-opacity))}.lg\:divide-green-800>:not(template)~:not(template){--divide-opacity:1;border-color:#276749;border-color:rgba(39,103,73,var(--divide-opacity))}.lg\:divide-green-900>:not(template)~:not(template){--divide-opacity:1;border-color:#22543d;border-color:rgba(34,84,61,var(--divide-opacity))}.lg\:divide-teal-100>:not(template)~:not(template){--divide-opacity:1;border-color:#e6fffa;border-color:rgba(230,255,250,var(--divide-opacity))}.lg\:divide-teal-200>:not(template)~:not(template){--divide-opacity:1;border-color:#b2f5ea;border-color:rgba(178,245,234,var(--divide-opacity))}.lg\:divide-teal-300>:not(template)~:not(template){--divide-opacity:1;border-color:#81e6d9;border-color:rgba(129,230,217,var(--divide-opacity))}.lg\:divide-teal-400>:not(template)~:not(template){--divide-opacity:1;border-color:#4fd1c5;border-color:rgba(79,209,197,var(--divide-opacity))}.lg\:divide-teal-500>:not(template)~:not(template){--divide-opacity:1;border-color:#38b2ac;border-color:rgba(56,178,172,var(--divide-opacity))}.lg\:divide-teal-600>:not(template)~:not(template){--divide-opacity:1;border-color:#319795;border-color:rgba(49,151,149,var(--divide-opacity))}.lg\:divide-teal-700>:not(template)~:not(template){--divide-opacity:1;border-color:#2c7a7b;border-color:rgba(44,122,123,var(--divide-opacity))}.lg\:divide-teal-800>:not(template)~:not(template){--divide-opacity:1;border-color:#285e61;border-color:rgba(40,94,97,var(--divide-opacity))}.lg\:divide-teal-900>:not(template)~:not(template){--divide-opacity:1;border-color:#234e52;border-color:rgba(35,78,82,var(--divide-opacity))}.lg\:divide-blue-100>:not(template)~:not(template){--divide-opacity:1;border-color:#ebf8ff;border-color:rgba(235,248,255,var(--divide-opacity))}.lg\:divide-blue-200>:not(template)~:not(template){--divide-opacity:1;border-color:#bee3f8;border-color:rgba(190,227,248,var(--divide-opacity))}.lg\:divide-blue-300>:not(template)~:not(template){--divide-opacity:1;border-color:#90cdf4;border-color:rgba(144,205,244,var(--divide-opacity))}.lg\:divide-blue-400>:not(template)~:not(template){--divide-opacity:1;border-color:#63b3ed;border-color:rgba(99,179,237,var(--divide-opacity))}.lg\:divide-blue-500>:not(template)~:not(template){--divide-opacity:1;border-color:#4299e1;border-color:rgba(66,153,225,var(--divide-opacity))}.lg\:divide-blue-600>:not(template)~:not(template){--divide-opacity:1;border-color:#3182ce;border-color:rgba(49,130,206,var(--divide-opacity))}.lg\:divide-blue-700>:not(template)~:not(template){--divide-opacity:1;border-color:#2b6cb0;border-color:rgba(43,108,176,var(--divide-opacity))}.lg\:divide-blue-800>:not(template)~:not(template){--divide-opacity:1;border-color:#2c5282;border-color:rgba(44,82,130,var(--divide-opacity))}.lg\:divide-blue-900>:not(template)~:not(template){--divide-opacity:1;border-color:#2a4365;border-color:rgba(42,67,101,var(--divide-opacity))}.lg\:divide-indigo-100>:not(template)~:not(template){--divide-opacity:1;border-color:#ebf4ff;border-color:rgba(235,244,255,var(--divide-opacity))}.lg\:divide-indigo-200>:not(template)~:not(template){--divide-opacity:1;border-color:#c3dafe;border-color:rgba(195,218,254,var(--divide-opacity))}.lg\:divide-indigo-300>:not(template)~:not(template){--divide-opacity:1;border-color:#a3bffa;border-color:rgba(163,191,250,var(--divide-opacity))}.lg\:divide-indigo-400>:not(template)~:not(template){--divide-opacity:1;border-color:#7f9cf5;border-color:rgba(127,156,245,var(--divide-opacity))}.lg\:divide-indigo-500>:not(template)~:not(template){--divide-opacity:1;border-color:#667eea;border-color:rgba(102,126,234,var(--divide-opacity))}.lg\:divide-indigo-600>:not(template)~:not(template){--divide-opacity:1;border-color:#5a67d8;border-color:rgba(90,103,216,var(--divide-opacity))}.lg\:divide-indigo-700>:not(template)~:not(template){--divide-opacity:1;border-color:#4c51bf;border-color:rgba(76,81,191,var(--divide-opacity))}.lg\:divide-indigo-800>:not(template)~:not(template){--divide-opacity:1;border-color:#434190;border-color:rgba(67,65,144,var(--divide-opacity))}.lg\:divide-indigo-900>:not(template)~:not(template){--divide-opacity:1;border-color:#3c366b;border-color:rgba(60,54,107,var(--divide-opacity))}.lg\:divide-purple-100>:not(template)~:not(template){--divide-opacity:1;border-color:#faf5ff;border-color:rgba(250,245,255,var(--divide-opacity))}.lg\:divide-purple-200>:not(template)~:not(template){--divide-opacity:1;border-color:#e9d8fd;border-color:rgba(233,216,253,var(--divide-opacity))}.lg\:divide-purple-300>:not(template)~:not(template){--divide-opacity:1;border-color:#d6bcfa;border-color:rgba(214,188,250,var(--divide-opacity))}.lg\:divide-purple-400>:not(template)~:not(template){--divide-opacity:1;border-color:#b794f4;border-color:rgba(183,148,244,var(--divide-opacity))}.lg\:divide-purple-500>:not(template)~:not(template){--divide-opacity:1;border-color:#9f7aea;border-color:rgba(159,122,234,var(--divide-opacity))}.lg\:divide-purple-600>:not(template)~:not(template){--divide-opacity:1;border-color:#805ad5;border-color:rgba(128,90,213,var(--divide-opacity))}.lg\:divide-purple-700>:not(template)~:not(template){--divide-opacity:1;border-color:#6b46c1;border-color:rgba(107,70,193,var(--divide-opacity))}.lg\:divide-purple-800>:not(template)~:not(template){--divide-opacity:1;border-color:#553c9a;border-color:rgba(85,60,154,var(--divide-opacity))}.lg\:divide-purple-900>:not(template)~:not(template){--divide-opacity:1;border-color:#44337a;border-color:rgba(68,51,122,var(--divide-opacity))}.lg\:divide-pink-100>:not(template)~:not(template){--divide-opacity:1;border-color:#fff5f7;border-color:rgba(255,245,247,var(--divide-opacity))}.lg\:divide-pink-200>:not(template)~:not(template){--divide-opacity:1;border-color:#fed7e2;border-color:rgba(254,215,226,var(--divide-opacity))}.lg\:divide-pink-300>:not(template)~:not(template){--divide-opacity:1;border-color:#fbb6ce;border-color:rgba(251,182,206,var(--divide-opacity))}.lg\:divide-pink-400>:not(template)~:not(template){--divide-opacity:1;border-color:#f687b3;border-color:rgba(246,135,179,var(--divide-opacity))}.lg\:divide-pink-500>:not(template)~:not(template){--divide-opacity:1;border-color:#ed64a6;border-color:rgba(237,100,166,var(--divide-opacity))}.lg\:divide-pink-600>:not(template)~:not(template){--divide-opacity:1;border-color:#d53f8c;border-color:rgba(213,63,140,var(--divide-opacity))}.lg\:divide-pink-700>:not(template)~:not(template){--divide-opacity:1;border-color:#b83280;border-color:rgba(184,50,128,var(--divide-opacity))}.lg\:divide-pink-800>:not(template)~:not(template){--divide-opacity:1;border-color:#97266d;border-color:rgba(151,38,109,var(--divide-opacity))}.lg\:divide-pink-900>:not(template)~:not(template){--divide-opacity:1;border-color:#702459;border-color:rgba(112,36,89,var(--divide-opacity))}.lg\:divide-solid>:not(template)~:not(template){border-style:solid}.lg\:divide-dashed>:not(template)~:not(template){border-style:dashed}.lg\:divide-dotted>:not(template)~:not(template){border-style:dotted}.lg\:divide-double>:not(template)~:not(template){border-style:double}.lg\:divide-none>:not(template)~:not(template){border-style:none}.lg\:divide-opacity-0>:not(template)~:not(template){--divide-opacity:0}.lg\:divide-opacity-25>:not(template)~:not(template){--divide-opacity:0.25}.lg\:divide-opacity-50>:not(template)~:not(template){--divide-opacity:0.5}.lg\:divide-opacity-75>:not(template)~:not(template){--divide-opacity:0.75}.lg\:divide-opacity-100>:not(template)~:not(template){--divide-opacity:1}.lg\:sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border-width:0}.lg\:not-sr-only{position:static;width:auto;height:auto;padding:0;margin:0;overflow:visible;clip:auto;white-space:normal}.lg\:focus\:sr-only:focus{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border-width:0}.lg\:focus\:not-sr-only:focus{position:static;width:auto;height:auto;padding:0;margin:0;overflow:visible;clip:auto;white-space:normal}.lg\:appearance-none{-webkit-appearance:none;-moz-appearance:none;appearance:none}.lg\:bg-fixed{background-attachment:fixed}.lg\:bg-local{background-attachment:local}.lg\:bg-scroll{background-attachment:scroll}.lg\:bg-clip-border{background-clip:border-box}.lg\:bg-clip-padding{background-clip:padding-box}.lg\:bg-clip-content{background-clip:content-box}.lg\:bg-clip-text{-webkit-background-clip:text;background-clip:text}.lg\:bg-transparent{background-color:transparent}.lg\:bg-current{background-color:currentColor}.lg\:bg-black{--bg-opacity:1;background-color:#000;background-color:rgba(0,0,0,var(--bg-opacity))}.lg\:bg-white{--bg-opacity:1;background-color:#fff;background-color:rgba(255,255,255,var(--bg-opacity))}.lg\:bg-gray-100{--bg-opacity:1;background-color:#f7fafc;background-color:rgba(247,250,252,var(--bg-opacity))}.lg\:bg-gray-200{--bg-opacity:1;background-color:#edf2f7;background-color:rgba(237,242,247,var(--bg-opacity))}.lg\:bg-gray-300{--bg-opacity:1;background-color:#e2e8f0;background-color:rgba(226,232,240,var(--bg-opacity))}.lg\:bg-gray-400{--bg-opacity:1;background-color:#cbd5e0;background-color:rgba(203,213,224,var(--bg-opacity))}.lg\:bg-gray-500{--bg-opacity:1;background-color:#a0aec0;background-color:rgba(160,174,192,var(--bg-opacity))}.lg\:bg-gray-600{--bg-opacity:1;background-color:#718096;background-color:rgba(113,128,150,var(--bg-opacity))}.lg\:bg-gray-700{--bg-opacity:1;background-color:#4a5568;background-color:rgba(74,85,104,var(--bg-opacity))}.lg\:bg-gray-800{--bg-opacity:1;background-color:#2d3748;background-color:rgba(45,55,72,var(--bg-opacity))}.lg\:bg-gray-900{--bg-opacity:1;background-color:#1a202c;background-color:rgba(26,32,44,var(--bg-opacity))}.lg\:bg-red-100{--bg-opacity:1;background-color:#fff5f5;background-color:rgba(255,245,245,var(--bg-opacity))}.lg\:bg-red-200{--bg-opacity:1;background-color:#fed7d7;background-color:rgba(254,215,215,var(--bg-opacity))}.lg\:bg-red-300{--bg-opacity:1;background-color:#feb2b2;background-color:rgba(254,178,178,var(--bg-opacity))}.lg\:bg-red-400{--bg-opacity:1;background-color:#fc8181;background-color:rgba(252,129,129,var(--bg-opacity))}.lg\:bg-red-500{--bg-opacity:1;background-color:#f56565;background-color:rgba(245,101,101,var(--bg-opacity))}.lg\:bg-red-600{--bg-opacity:1;background-color:#e53e3e;background-color:rgba(229,62,62,var(--bg-opacity))}.lg\:bg-red-700{--bg-opacity:1;background-color:#c53030;background-color:rgba(197,48,48,var(--bg-opacity))}.lg\:bg-red-800{--bg-opacity:1;background-color:#9b2c2c;background-color:rgba(155,44,44,var(--bg-opacity))}.lg\:bg-red-900{--bg-opacity:1;background-color:#742a2a;background-color:rgba(116,42,42,var(--bg-opacity))}.lg\:bg-orange-100{--bg-opacity:1;background-color:#fffaf0;background-color:rgba(255,250,240,var(--bg-opacity))}.lg\:bg-orange-200{--bg-opacity:1;background-color:#feebc8;background-color:rgba(254,235,200,var(--bg-opacity))}.lg\:bg-orange-300{--bg-opacity:1;background-color:#fbd38d;background-color:rgba(251,211,141,var(--bg-opacity))}.lg\:bg-orange-400{--bg-opacity:1;background-color:#f6ad55;background-color:rgba(246,173,85,var(--bg-opacity))}.lg\:bg-orange-500{--bg-opacity:1;background-color:#ed8936;background-color:rgba(237,137,54,var(--bg-opacity))}.lg\:bg-orange-600{--bg-opacity:1;background-color:#dd6b20;background-color:rgba(221,107,32,var(--bg-opacity))}.lg\:bg-orange-700{--bg-opacity:1;background-color:#c05621;background-color:rgba(192,86,33,var(--bg-opacity))}.lg\:bg-orange-800{--bg-opacity:1;background-color:#9c4221;background-color:rgba(156,66,33,var(--bg-opacity))}.lg\:bg-orange-900{--bg-opacity:1;background-color:#7b341e;background-color:rgba(123,52,30,var(--bg-opacity))}.lg\:bg-yellow-100{--bg-opacity:1;background-color:ivory;background-color:rgba(255,255,240,var(--bg-opacity))}.lg\:bg-yellow-200{--bg-opacity:1;background-color:#fefcbf;background-color:rgba(254,252,191,var(--bg-opacity))}.lg\:bg-yellow-300{--bg-opacity:1;background-color:#faf089;background-color:rgba(250,240,137,var(--bg-opacity))}.lg\:bg-yellow-400{--bg-opacity:1;background-color:#f6e05e;background-color:rgba(246,224,94,var(--bg-opacity))}.lg\:bg-yellow-500{--bg-opacity:1;background-color:#ecc94b;background-color:rgba(236,201,75,var(--bg-opacity))}.lg\:bg-yellow-600{--bg-opacity:1;background-color:#d69e2e;background-color:rgba(214,158,46,var(--bg-opacity))}.lg\:bg-yellow-700{--bg-opacity:1;background-color:#b7791f;background-color:rgba(183,121,31,var(--bg-opacity))}.lg\:bg-yellow-800{--bg-opacity:1;background-color:#975a16;background-color:rgba(151,90,22,var(--bg-opacity))}.lg\:bg-yellow-900{--bg-opacity:1;background-color:#744210;background-color:rgba(116,66,16,var(--bg-opacity))}.lg\:bg-green-100{--bg-opacity:1;background-color:#f0fff4;background-color:rgba(240,255,244,var(--bg-opacity))}.lg\:bg-green-200{--bg-opacity:1;background-color:#c6f6d5;background-color:rgba(198,246,213,var(--bg-opacity))}.lg\:bg-green-300{--bg-opacity:1;background-color:#9ae6b4;background-color:rgba(154,230,180,var(--bg-opacity))}.lg\:bg-green-400{--bg-opacity:1;background-color:#68d391;background-color:rgba(104,211,145,var(--bg-opacity))}.lg\:bg-green-500{--bg-opacity:1;background-color:#48bb78;background-color:rgba(72,187,120,var(--bg-opacity))}.lg\:bg-green-600{--bg-opacity:1;background-color:#38a169;background-color:rgba(56,161,105,var(--bg-opacity))}.lg\:bg-green-700{--bg-opacity:1;background-color:#2f855a;background-color:rgba(47,133,90,var(--bg-opacity))}.lg\:bg-green-800{--bg-opacity:1;background-color:#276749;background-color:rgba(39,103,73,var(--bg-opacity))}.lg\:bg-green-900{--bg-opacity:1;background-color:#22543d;background-color:rgba(34,84,61,var(--bg-opacity))}.lg\:bg-teal-100{--bg-opacity:1;background-color:#e6fffa;background-color:rgba(230,255,250,var(--bg-opacity))}.lg\:bg-teal-200{--bg-opacity:1;background-color:#b2f5ea;background-color:rgba(178,245,234,var(--bg-opacity))}.lg\:bg-teal-300{--bg-opacity:1;background-color:#81e6d9;background-color:rgba(129,230,217,var(--bg-opacity))}.lg\:bg-teal-400{--bg-opacity:1;background-color:#4fd1c5;background-color:rgba(79,209,197,var(--bg-opacity))}.lg\:bg-teal-500{--bg-opacity:1;background-color:#38b2ac;background-color:rgba(56,178,172,var(--bg-opacity))}.lg\:bg-teal-600{--bg-opacity:1;background-color:#319795;background-color:rgba(49,151,149,var(--bg-opacity))}.lg\:bg-teal-700{--bg-opacity:1;background-color:#2c7a7b;background-color:rgba(44,122,123,var(--bg-opacity))}.lg\:bg-teal-800{--bg-opacity:1;background-color:#285e61;background-color:rgba(40,94,97,var(--bg-opacity))}.lg\:bg-teal-900{--bg-opacity:1;background-color:#234e52;background-color:rgba(35,78,82,var(--bg-opacity))}.lg\:bg-blue-100{--bg-opacity:1;background-color:#ebf8ff;background-color:rgba(235,248,255,var(--bg-opacity))}.lg\:bg-blue-200{--bg-opacity:1;background-color:#bee3f8;background-color:rgba(190,227,248,var(--bg-opacity))}.lg\:bg-blue-300{--bg-opacity:1;background-color:#90cdf4;background-color:rgba(144,205,244,var(--bg-opacity))}.lg\:bg-blue-400{--bg-opacity:1;background-color:#63b3ed;background-color:rgba(99,179,237,var(--bg-opacity))}.lg\:bg-blue-500{--bg-opacity:1;background-color:#4299e1;background-color:rgba(66,153,225,var(--bg-opacity))}.lg\:bg-blue-600{--bg-opacity:1;background-color:#3182ce;background-color:rgba(49,130,206,var(--bg-opacity))}.lg\:bg-blue-700{--bg-opacity:1;background-color:#2b6cb0;background-color:rgba(43,108,176,var(--bg-opacity))}.lg\:bg-blue-800{--bg-opacity:1;background-color:#2c5282;background-color:rgba(44,82,130,var(--bg-opacity))}.lg\:bg-blue-900{--bg-opacity:1;background-color:#2a4365;background-color:rgba(42,67,101,var(--bg-opacity))}.lg\:bg-indigo-100{--bg-opacity:1;background-color:#ebf4ff;background-color:rgba(235,244,255,var(--bg-opacity))}.lg\:bg-indigo-200{--bg-opacity:1;background-color:#c3dafe;background-color:rgba(195,218,254,var(--bg-opacity))}.lg\:bg-indigo-300{--bg-opacity:1;background-color:#a3bffa;background-color:rgba(163,191,250,var(--bg-opacity))}.lg\:bg-indigo-400{--bg-opacity:1;background-color:#7f9cf5;background-color:rgba(127,156,245,var(--bg-opacity))}.lg\:bg-indigo-500{--bg-opacity:1;background-color:#667eea;background-color:rgba(102,126,234,var(--bg-opacity))}.lg\:bg-indigo-600{--bg-opacity:1;background-color:#5a67d8;background-color:rgba(90,103,216,var(--bg-opacity))}.lg\:bg-indigo-700{--bg-opacity:1;background-color:#4c51bf;background-color:rgba(76,81,191,var(--bg-opacity))}.lg\:bg-indigo-800{--bg-opacity:1;background-color:#434190;background-color:rgba(67,65,144,var(--bg-opacity))}.lg\:bg-indigo-900{--bg-opacity:1;background-color:#3c366b;background-color:rgba(60,54,107,var(--bg-opacity))}.lg\:bg-purple-100{--bg-opacity:1;background-color:#faf5ff;background-color:rgba(250,245,255,var(--bg-opacity))}.lg\:bg-purple-200{--bg-opacity:1;background-color:#e9d8fd;background-color:rgba(233,216,253,var(--bg-opacity))}.lg\:bg-purple-300{--bg-opacity:1;background-color:#d6bcfa;background-color:rgba(214,188,250,var(--bg-opacity))}.lg\:bg-purple-400{--bg-opacity:1;background-color:#b794f4;background-color:rgba(183,148,244,var(--bg-opacity))}.lg\:bg-purple-500{--bg-opacity:1;background-color:#9f7aea;background-color:rgba(159,122,234,var(--bg-opacity))}.lg\:bg-purple-600{--bg-opacity:1;background-color:#805ad5;background-color:rgba(128,90,213,var(--bg-opacity))}.lg\:bg-purple-700{--bg-opacity:1;background-color:#6b46c1;background-color:rgba(107,70,193,var(--bg-opacity))}.lg\:bg-purple-800{--bg-opacity:1;background-color:#553c9a;background-color:rgba(85,60,154,var(--bg-opacity))}.lg\:bg-purple-900{--bg-opacity:1;background-color:#44337a;background-color:rgba(68,51,122,var(--bg-opacity))}.lg\:bg-pink-100{--bg-opacity:1;background-color:#fff5f7;background-color:rgba(255,245,247,var(--bg-opacity))}.lg\:bg-pink-200{--bg-opacity:1;background-color:#fed7e2;background-color:rgba(254,215,226,var(--bg-opacity))}.lg\:bg-pink-300{--bg-opacity:1;background-color:#fbb6ce;background-color:rgba(251,182,206,var(--bg-opacity))}.lg\:bg-pink-400{--bg-opacity:1;background-color:#f687b3;background-color:rgba(246,135,179,var(--bg-opacity))}.lg\:bg-pink-500{--bg-opacity:1;background-color:#ed64a6;background-color:rgba(237,100,166,var(--bg-opacity))}.lg\:bg-pink-600{--bg-opacity:1;background-color:#d53f8c;background-color:rgba(213,63,140,var(--bg-opacity))}.lg\:bg-pink-700{--bg-opacity:1;background-color:#b83280;background-color:rgba(184,50,128,var(--bg-opacity))}.lg\:bg-pink-800{--bg-opacity:1;background-color:#97266d;background-color:rgba(151,38,109,var(--bg-opacity))}.lg\:bg-pink-900{--bg-opacity:1;background-color:#702459;background-color:rgba(112,36,89,var(--bg-opacity))}.lg\:hover\:bg-transparent:hover{background-color:transparent}.lg\:hover\:bg-current:hover{background-color:currentColor}.lg\:hover\:bg-black:hover{--bg-opacity:1;background-color:#000;background-color:rgba(0,0,0,var(--bg-opacity))}.lg\:hover\:bg-white:hover{--bg-opacity:1;background-color:#fff;background-color:rgba(255,255,255,var(--bg-opacity))}.lg\:hover\:bg-gray-100:hover{--bg-opacity:1;background-color:#f7fafc;background-color:rgba(247,250,252,var(--bg-opacity))}.lg\:hover\:bg-gray-200:hover{--bg-opacity:1;background-color:#edf2f7;background-color:rgba(237,242,247,var(--bg-opacity))}.lg\:hover\:bg-gray-300:hover{--bg-opacity:1;background-color:#e2e8f0;background-color:rgba(226,232,240,var(--bg-opacity))}.lg\:hover\:bg-gray-400:hover{--bg-opacity:1;background-color:#cbd5e0;background-color:rgba(203,213,224,var(--bg-opacity))}.lg\:hover\:bg-gray-500:hover{--bg-opacity:1;background-color:#a0aec0;background-color:rgba(160,174,192,var(--bg-opacity))}.lg\:hover\:bg-gray-600:hover{--bg-opacity:1;background-color:#718096;background-color:rgba(113,128,150,var(--bg-opacity))}.lg\:hover\:bg-gray-700:hover{--bg-opacity:1;background-color:#4a5568;background-color:rgba(74,85,104,var(--bg-opacity))}.lg\:hover\:bg-gray-800:hover{--bg-opacity:1;background-color:#2d3748;background-color:rgba(45,55,72,var(--bg-opacity))}.lg\:hover\:bg-gray-900:hover{--bg-opacity:1;background-color:#1a202c;background-color:rgba(26,32,44,var(--bg-opacity))}.lg\:hover\:bg-red-100:hover{--bg-opacity:1;background-color:#fff5f5;background-color:rgba(255,245,245,var(--bg-opacity))}.lg\:hover\:bg-red-200:hover{--bg-opacity:1;background-color:#fed7d7;background-color:rgba(254,215,215,var(--bg-opacity))}.lg\:hover\:bg-red-300:hover{--bg-opacity:1;background-color:#feb2b2;background-color:rgba(254,178,178,var(--bg-opacity))}.lg\:hover\:bg-red-400:hover{--bg-opacity:1;background-color:#fc8181;background-color:rgba(252,129,129,var(--bg-opacity))}.lg\:hover\:bg-red-500:hover{--bg-opacity:1;background-color:#f56565;background-color:rgba(245,101,101,var(--bg-opacity))}.lg\:hover\:bg-red-600:hover{--bg-opacity:1;background-color:#e53e3e;background-color:rgba(229,62,62,var(--bg-opacity))}.lg\:hover\:bg-red-700:hover{--bg-opacity:1;background-color:#c53030;background-color:rgba(197,48,48,var(--bg-opacity))}.lg\:hover\:bg-red-800:hover{--bg-opacity:1;background-color:#9b2c2c;background-color:rgba(155,44,44,var(--bg-opacity))}.lg\:hover\:bg-red-900:hover{--bg-opacity:1;background-color:#742a2a;background-color:rgba(116,42,42,var(--bg-opacity))}.lg\:hover\:bg-orange-100:hover{--bg-opacity:1;background-color:#fffaf0;background-color:rgba(255,250,240,var(--bg-opacity))}.lg\:hover\:bg-orange-200:hover{--bg-opacity:1;background-color:#feebc8;background-color:rgba(254,235,200,var(--bg-opacity))}.lg\:hover\:bg-orange-300:hover{--bg-opacity:1;background-color:#fbd38d;background-color:rgba(251,211,141,var(--bg-opacity))}.lg\:hover\:bg-orange-400:hover{--bg-opacity:1;background-color:#f6ad55;background-color:rgba(246,173,85,var(--bg-opacity))}.lg\:hover\:bg-orange-500:hover{--bg-opacity:1;background-color:#ed8936;background-color:rgba(237,137,54,var(--bg-opacity))}.lg\:hover\:bg-orange-600:hover{--bg-opacity:1;background-color:#dd6b20;background-color:rgba(221,107,32,var(--bg-opacity))}.lg\:hover\:bg-orange-700:hover{--bg-opacity:1;background-color:#c05621;background-color:rgba(192,86,33,var(--bg-opacity))}.lg\:hover\:bg-orange-800:hover{--bg-opacity:1;background-color:#9c4221;background-color:rgba(156,66,33,var(--bg-opacity))}.lg\:hover\:bg-orange-900:hover{--bg-opacity:1;background-color:#7b341e;background-color:rgba(123,52,30,var(--bg-opacity))}.lg\:hover\:bg-yellow-100:hover{--bg-opacity:1;background-color:ivory;background-color:rgba(255,255,240,var(--bg-opacity))}.lg\:hover\:bg-yellow-200:hover{--bg-opacity:1;background-color:#fefcbf;background-color:rgba(254,252,191,var(--bg-opacity))}.lg\:hover\:bg-yellow-300:hover{--bg-opacity:1;background-color:#faf089;background-color:rgba(250,240,137,var(--bg-opacity))}.lg\:hover\:bg-yellow-400:hover{--bg-opacity:1;background-color:#f6e05e;background-color:rgba(246,224,94,var(--bg-opacity))}.lg\:hover\:bg-yellow-500:hover{--bg-opacity:1;background-color:#ecc94b;background-color:rgba(236,201,75,var(--bg-opacity))}.lg\:hover\:bg-yellow-600:hover{--bg-opacity:1;background-color:#d69e2e;background-color:rgba(214,158,46,var(--bg-opacity))}.lg\:hover\:bg-yellow-700:hover{--bg-opacity:1;background-color:#b7791f;background-color:rgba(183,121,31,var(--bg-opacity))}.lg\:hover\:bg-yellow-800:hover{--bg-opacity:1;background-color:#975a16;background-color:rgba(151,90,22,var(--bg-opacity))}.lg\:hover\:bg-yellow-900:hover{--bg-opacity:1;background-color:#744210;background-color:rgba(116,66,16,var(--bg-opacity))}.lg\:hover\:bg-green-100:hover{--bg-opacity:1;background-color:#f0fff4;background-color:rgba(240,255,244,var(--bg-opacity))}.lg\:hover\:bg-green-200:hover{--bg-opacity:1;background-color:#c6f6d5;background-color:rgba(198,246,213,var(--bg-opacity))}.lg\:hover\:bg-green-300:hover{--bg-opacity:1;background-color:#9ae6b4;background-color:rgba(154,230,180,var(--bg-opacity))}.lg\:hover\:bg-green-400:hover{--bg-opacity:1;background-color:#68d391;background-color:rgba(104,211,145,var(--bg-opacity))}.lg\:hover\:bg-green-500:hover{--bg-opacity:1;background-color:#48bb78;background-color:rgba(72,187,120,var(--bg-opacity))}.lg\:hover\:bg-green-600:hover{--bg-opacity:1;background-color:#38a169;background-color:rgba(56,161,105,var(--bg-opacity))}.lg\:hover\:bg-green-700:hover{--bg-opacity:1;background-color:#2f855a;background-color:rgba(47,133,90,var(--bg-opacity))}.lg\:hover\:bg-green-800:hover{--bg-opacity:1;background-color:#276749;background-color:rgba(39,103,73,var(--bg-opacity))}.lg\:hover\:bg-green-900:hover{--bg-opacity:1;background-color:#22543d;background-color:rgba(34,84,61,var(--bg-opacity))}.lg\:hover\:bg-teal-100:hover{--bg-opacity:1;background-color:#e6fffa;background-color:rgba(230,255,250,var(--bg-opacity))}.lg\:hover\:bg-teal-200:hover{--bg-opacity:1;background-color:#b2f5ea;background-color:rgba(178,245,234,var(--bg-opacity))}.lg\:hover\:bg-teal-300:hover{--bg-opacity:1;background-color:#81e6d9;background-color:rgba(129,230,217,var(--bg-opacity))}.lg\:hover\:bg-teal-400:hover{--bg-opacity:1;background-color:#4fd1c5;background-color:rgba(79,209,197,var(--bg-opacity))}.lg\:hover\:bg-teal-500:hover{--bg-opacity:1;background-color:#38b2ac;background-color:rgba(56,178,172,var(--bg-opacity))}.lg\:hover\:bg-teal-600:hover{--bg-opacity:1;background-color:#319795;background-color:rgba(49,151,149,var(--bg-opacity))}.lg\:hover\:bg-teal-700:hover{--bg-opacity:1;background-color:#2c7a7b;background-color:rgba(44,122,123,var(--bg-opacity))}.lg\:hover\:bg-teal-800:hover{--bg-opacity:1;background-color:#285e61;background-color:rgba(40,94,97,var(--bg-opacity))}.lg\:hover\:bg-teal-900:hover{--bg-opacity:1;background-color:#234e52;background-color:rgba(35,78,82,var(--bg-opacity))}.lg\:hover\:bg-blue-100:hover{--bg-opacity:1;background-color:#ebf8ff;background-color:rgba(235,248,255,var(--bg-opacity))}.lg\:hover\:bg-blue-200:hover{--bg-opacity:1;background-color:#bee3f8;background-color:rgba(190,227,248,var(--bg-opacity))}.lg\:hover\:bg-blue-300:hover{--bg-opacity:1;background-color:#90cdf4;background-color:rgba(144,205,244,var(--bg-opacity))}.lg\:hover\:bg-blue-400:hover{--bg-opacity:1;background-color:#63b3ed;background-color:rgba(99,179,237,var(--bg-opacity))}.lg\:hover\:bg-blue-500:hover{--bg-opacity:1;background-color:#4299e1;background-color:rgba(66,153,225,var(--bg-opacity))}.lg\:hover\:bg-blue-600:hover{--bg-opacity:1;background-color:#3182ce;background-color:rgba(49,130,206,var(--bg-opacity))}.lg\:hover\:bg-blue-700:hover{--bg-opacity:1;background-color:#2b6cb0;background-color:rgba(43,108,176,var(--bg-opacity))}.lg\:hover\:bg-blue-800:hover{--bg-opacity:1;background-color:#2c5282;background-color:rgba(44,82,130,var(--bg-opacity))}.lg\:hover\:bg-blue-900:hover{--bg-opacity:1;background-color:#2a4365;background-color:rgba(42,67,101,var(--bg-opacity))}.lg\:hover\:bg-indigo-100:hover{--bg-opacity:1;background-color:#ebf4ff;background-color:rgba(235,244,255,var(--bg-opacity))}.lg\:hover\:bg-indigo-200:hover{--bg-opacity:1;background-color:#c3dafe;background-color:rgba(195,218,254,var(--bg-opacity))}.lg\:hover\:bg-indigo-300:hover{--bg-opacity:1;background-color:#a3bffa;background-color:rgba(163,191,250,var(--bg-opacity))}.lg\:hover\:bg-indigo-400:hover{--bg-opacity:1;background-color:#7f9cf5;background-color:rgba(127,156,245,var(--bg-opacity))}.lg\:hover\:bg-indigo-500:hover{--bg-opacity:1;background-color:#667eea;background-color:rgba(102,126,234,var(--bg-opacity))}.lg\:hover\:bg-indigo-600:hover{--bg-opacity:1;background-color:#5a67d8;background-color:rgba(90,103,216,var(--bg-opacity))}.lg\:hover\:bg-indigo-700:hover{--bg-opacity:1;background-color:#4c51bf;background-color:rgba(76,81,191,var(--bg-opacity))}.lg\:hover\:bg-indigo-800:hover{--bg-opacity:1;background-color:#434190;background-color:rgba(67,65,144,var(--bg-opacity))}.lg\:hover\:bg-indigo-900:hover{--bg-opacity:1;background-color:#3c366b;background-color:rgba(60,54,107,var(--bg-opacity))}.lg\:hover\:bg-purple-100:hover{--bg-opacity:1;background-color:#faf5ff;background-color:rgba(250,245,255,var(--bg-opacity))}.lg\:hover\:bg-purple-200:hover{--bg-opacity:1;background-color:#e9d8fd;background-color:rgba(233,216,253,var(--bg-opacity))}.lg\:hover\:bg-purple-300:hover{--bg-opacity:1;background-color:#d6bcfa;background-color:rgba(214,188,250,var(--bg-opacity))}.lg\:hover\:bg-purple-400:hover{--bg-opacity:1;background-color:#b794f4;background-color:rgba(183,148,244,var(--bg-opacity))}.lg\:hover\:bg-purple-500:hover{--bg-opacity:1;background-color:#9f7aea;background-color:rgba(159,122,234,var(--bg-opacity))}.lg\:hover\:bg-purple-600:hover{--bg-opacity:1;background-color:#805ad5;background-color:rgba(128,90,213,var(--bg-opacity))}.lg\:hover\:bg-purple-700:hover{--bg-opacity:1;background-color:#6b46c1;background-color:rgba(107,70,193,var(--bg-opacity))}.lg\:hover\:bg-purple-800:hover{--bg-opacity:1;background-color:#553c9a;background-color:rgba(85,60,154,var(--bg-opacity))}.lg\:hover\:bg-purple-900:hover{--bg-opacity:1;background-color:#44337a;background-color:rgba(68,51,122,var(--bg-opacity))}.lg\:hover\:bg-pink-100:hover{--bg-opacity:1;background-color:#fff5f7;background-color:rgba(255,245,247,var(--bg-opacity))}.lg\:hover\:bg-pink-200:hover{--bg-opacity:1;background-color:#fed7e2;background-color:rgba(254,215,226,var(--bg-opacity))}.lg\:hover\:bg-pink-300:hover{--bg-opacity:1;background-color:#fbb6ce;background-color:rgba(251,182,206,var(--bg-opacity))}.lg\:hover\:bg-pink-400:hover{--bg-opacity:1;background-color:#f687b3;background-color:rgba(246,135,179,var(--bg-opacity))}.lg\:hover\:bg-pink-500:hover{--bg-opacity:1;background-color:#ed64a6;background-color:rgba(237,100,166,var(--bg-opacity))}.lg\:hover\:bg-pink-600:hover{--bg-opacity:1;background-color:#d53f8c;background-color:rgba(213,63,140,var(--bg-opacity))}.lg\:hover\:bg-pink-700:hover{--bg-opacity:1;background-color:#b83280;background-color:rgba(184,50,128,var(--bg-opacity))}.lg\:hover\:bg-pink-800:hover{--bg-opacity:1;background-color:#97266d;background-color:rgba(151,38,109,var(--bg-opacity))}.lg\:hover\:bg-pink-900:hover{--bg-opacity:1;background-color:#702459;background-color:rgba(112,36,89,var(--bg-opacity))}.lg\:focus\:bg-transparent:focus{background-color:transparent}.lg\:focus\:bg-current:focus{background-color:currentColor}.lg\:focus\:bg-black:focus{--bg-opacity:1;background-color:#000;background-color:rgba(0,0,0,var(--bg-opacity))}.lg\:focus\:bg-white:focus{--bg-opacity:1;background-color:#fff;background-color:rgba(255,255,255,var(--bg-opacity))}.lg\:focus\:bg-gray-100:focus{--bg-opacity:1;background-color:#f7fafc;background-color:rgba(247,250,252,var(--bg-opacity))}.lg\:focus\:bg-gray-200:focus{--bg-opacity:1;background-color:#edf2f7;background-color:rgba(237,242,247,var(--bg-opacity))}.lg\:focus\:bg-gray-300:focus{--bg-opacity:1;background-color:#e2e8f0;background-color:rgba(226,232,240,var(--bg-opacity))}.lg\:focus\:bg-gray-400:focus{--bg-opacity:1;background-color:#cbd5e0;background-color:rgba(203,213,224,var(--bg-opacity))}.lg\:focus\:bg-gray-500:focus{--bg-opacity:1;background-color:#a0aec0;background-color:rgba(160,174,192,var(--bg-opacity))}.lg\:focus\:bg-gray-600:focus{--bg-opacity:1;background-color:#718096;background-color:rgba(113,128,150,var(--bg-opacity))}.lg\:focus\:bg-gray-700:focus{--bg-opacity:1;background-color:#4a5568;background-color:rgba(74,85,104,var(--bg-opacity))}.lg\:focus\:bg-gray-800:focus{--bg-opacity:1;background-color:#2d3748;background-color:rgba(45,55,72,var(--bg-opacity))}.lg\:focus\:bg-gray-900:focus{--bg-opacity:1;background-color:#1a202c;background-color:rgba(26,32,44,var(--bg-opacity))}.lg\:focus\:bg-red-100:focus{--bg-opacity:1;background-color:#fff5f5;background-color:rgba(255,245,245,var(--bg-opacity))}.lg\:focus\:bg-red-200:focus{--bg-opacity:1;background-color:#fed7d7;background-color:rgba(254,215,215,var(--bg-opacity))}.lg\:focus\:bg-red-300:focus{--bg-opacity:1;background-color:#feb2b2;background-color:rgba(254,178,178,var(--bg-opacity))}.lg\:focus\:bg-red-400:focus{--bg-opacity:1;background-color:#fc8181;background-color:rgba(252,129,129,var(--bg-opacity))}.lg\:focus\:bg-red-500:focus{--bg-opacity:1;background-color:#f56565;background-color:rgba(245,101,101,var(--bg-opacity))}.lg\:focus\:bg-red-600:focus{--bg-opacity:1;background-color:#e53e3e;background-color:rgba(229,62,62,var(--bg-opacity))}.lg\:focus\:bg-red-700:focus{--bg-opacity:1;background-color:#c53030;background-color:rgba(197,48,48,var(--bg-opacity))}.lg\:focus\:bg-red-800:focus{--bg-opacity:1;background-color:#9b2c2c;background-color:rgba(155,44,44,var(--bg-opacity))}.lg\:focus\:bg-red-900:focus{--bg-opacity:1;background-color:#742a2a;background-color:rgba(116,42,42,var(--bg-opacity))}.lg\:focus\:bg-orange-100:focus{--bg-opacity:1;background-color:#fffaf0;background-color:rgba(255,250,240,var(--bg-opacity))}.lg\:focus\:bg-orange-200:focus{--bg-opacity:1;background-color:#feebc8;background-color:rgba(254,235,200,var(--bg-opacity))}.lg\:focus\:bg-orange-300:focus{--bg-opacity:1;background-color:#fbd38d;background-color:rgba(251,211,141,var(--bg-opacity))}.lg\:focus\:bg-orange-400:focus{--bg-opacity:1;background-color:#f6ad55;background-color:rgba(246,173,85,var(--bg-opacity))}.lg\:focus\:bg-orange-500:focus{--bg-opacity:1;background-color:#ed8936;background-color:rgba(237,137,54,var(--bg-opacity))}.lg\:focus\:bg-orange-600:focus{--bg-opacity:1;background-color:#dd6b20;background-color:rgba(221,107,32,var(--bg-opacity))}.lg\:focus\:bg-orange-700:focus{--bg-opacity:1;background-color:#c05621;background-color:rgba(192,86,33,var(--bg-opacity))}.lg\:focus\:bg-orange-800:focus{--bg-opacity:1;background-color:#9c4221;background-color:rgba(156,66,33,var(--bg-opacity))}.lg\:focus\:bg-orange-900:focus{--bg-opacity:1;background-color:#7b341e;background-color:rgba(123,52,30,var(--bg-opacity))}.lg\:focus\:bg-yellow-100:focus{--bg-opacity:1;background-color:ivory;background-color:rgba(255,255,240,var(--bg-opacity))}.lg\:focus\:bg-yellow-200:focus{--bg-opacity:1;background-color:#fefcbf;background-color:rgba(254,252,191,var(--bg-opacity))}.lg\:focus\:bg-yellow-300:focus{--bg-opacity:1;background-color:#faf089;background-color:rgba(250,240,137,var(--bg-opacity))}.lg\:focus\:bg-yellow-400:focus{--bg-opacity:1;background-color:#f6e05e;background-color:rgba(246,224,94,var(--bg-opacity))}.lg\:focus\:bg-yellow-500:focus{--bg-opacity:1;background-color:#ecc94b;background-color:rgba(236,201,75,var(--bg-opacity))}.lg\:focus\:bg-yellow-600:focus{--bg-opacity:1;background-color:#d69e2e;background-color:rgba(214,158,46,var(--bg-opacity))}.lg\:focus\:bg-yellow-700:focus{--bg-opacity:1;background-color:#b7791f;background-color:rgba(183,121,31,var(--bg-opacity))}.lg\:focus\:bg-yellow-800:focus{--bg-opacity:1;background-color:#975a16;background-color:rgba(151,90,22,var(--bg-opacity))}.lg\:focus\:bg-yellow-900:focus{--bg-opacity:1;background-color:#744210;background-color:rgba(116,66,16,var(--bg-opacity))}.lg\:focus\:bg-green-100:focus{--bg-opacity:1;background-color:#f0fff4;background-color:rgba(240,255,244,var(--bg-opacity))}.lg\:focus\:bg-green-200:focus{--bg-opacity:1;background-color:#c6f6d5;background-color:rgba(198,246,213,var(--bg-opacity))}.lg\:focus\:bg-green-300:focus{--bg-opacity:1;background-color:#9ae6b4;background-color:rgba(154,230,180,var(--bg-opacity))}.lg\:focus\:bg-green-400:focus{--bg-opacity:1;background-color:#68d391;background-color:rgba(104,211,145,var(--bg-opacity))}.lg\:focus\:bg-green-500:focus{--bg-opacity:1;background-color:#48bb78;background-color:rgba(72,187,120,var(--bg-opacity))}.lg\:focus\:bg-green-600:focus{--bg-opacity:1;background-color:#38a169;background-color:rgba(56,161,105,var(--bg-opacity))}.lg\:focus\:bg-green-700:focus{--bg-opacity:1;background-color:#2f855a;background-color:rgba(47,133,90,var(--bg-opacity))}.lg\:focus\:bg-green-800:focus{--bg-opacity:1;background-color:#276749;background-color:rgba(39,103,73,var(--bg-opacity))}.lg\:focus\:bg-green-900:focus{--bg-opacity:1;background-color:#22543d;background-color:rgba(34,84,61,var(--bg-opacity))}.lg\:focus\:bg-teal-100:focus{--bg-opacity:1;background-color:#e6fffa;background-color:rgba(230,255,250,var(--bg-opacity))}.lg\:focus\:bg-teal-200:focus{--bg-opacity:1;background-color:#b2f5ea;background-color:rgba(178,245,234,var(--bg-opacity))}.lg\:focus\:bg-teal-300:focus{--bg-opacity:1;background-color:#81e6d9;background-color:rgba(129,230,217,var(--bg-opacity))}.lg\:focus\:bg-teal-400:focus{--bg-opacity:1;background-color:#4fd1c5;background-color:rgba(79,209,197,var(--bg-opacity))}.lg\:focus\:bg-teal-500:focus{--bg-opacity:1;background-color:#38b2ac;background-color:rgba(56,178,172,var(--bg-opacity))}.lg\:focus\:bg-teal-600:focus{--bg-opacity:1;background-color:#319795;background-color:rgba(49,151,149,var(--bg-opacity))}.lg\:focus\:bg-teal-700:focus{--bg-opacity:1;background-color:#2c7a7b;background-color:rgba(44,122,123,var(--bg-opacity))}.lg\:focus\:bg-teal-800:focus{--bg-opacity:1;background-color:#285e61;background-color:rgba(40,94,97,var(--bg-opacity))}.lg\:focus\:bg-teal-900:focus{--bg-opacity:1;background-color:#234e52;background-color:rgba(35,78,82,var(--bg-opacity))}.lg\:focus\:bg-blue-100:focus{--bg-opacity:1;background-color:#ebf8ff;background-color:rgba(235,248,255,var(--bg-opacity))}.lg\:focus\:bg-blue-200:focus{--bg-opacity:1;background-color:#bee3f8;background-color:rgba(190,227,248,var(--bg-opacity))}.lg\:focus\:bg-blue-300:focus{--bg-opacity:1;background-color:#90cdf4;background-color:rgba(144,205,244,var(--bg-opacity))}.lg\:focus\:bg-blue-400:focus{--bg-opacity:1;background-color:#63b3ed;background-color:rgba(99,179,237,var(--bg-opacity))}.lg\:focus\:bg-blue-500:focus{--bg-opacity:1;background-color:#4299e1;background-color:rgba(66,153,225,var(--bg-opacity))}.lg\:focus\:bg-blue-600:focus{--bg-opacity:1;background-color:#3182ce;background-color:rgba(49,130,206,var(--bg-opacity))}.lg\:focus\:bg-blue-700:focus{--bg-opacity:1;background-color:#2b6cb0;background-color:rgba(43,108,176,var(--bg-opacity))}.lg\:focus\:bg-blue-800:focus{--bg-opacity:1;background-color:#2c5282;background-color:rgba(44,82,130,var(--bg-opacity))}.lg\:focus\:bg-blue-900:focus{--bg-opacity:1;background-color:#2a4365;background-color:rgba(42,67,101,var(--bg-opacity))}.lg\:focus\:bg-indigo-100:focus{--bg-opacity:1;background-color:#ebf4ff;background-color:rgba(235,244,255,var(--bg-opacity))}.lg\:focus\:bg-indigo-200:focus{--bg-opacity:1;background-color:#c3dafe;background-color:rgba(195,218,254,var(--bg-opacity))}.lg\:focus\:bg-indigo-300:focus{--bg-opacity:1;background-color:#a3bffa;background-color:rgba(163,191,250,var(--bg-opacity))}.lg\:focus\:bg-indigo-400:focus{--bg-opacity:1;background-color:#7f9cf5;background-color:rgba(127,156,245,var(--bg-opacity))}.lg\:focus\:bg-indigo-500:focus{--bg-opacity:1;background-color:#667eea;background-color:rgba(102,126,234,var(--bg-opacity))}.lg\:focus\:bg-indigo-600:focus{--bg-opacity:1;background-color:#5a67d8;background-color:rgba(90,103,216,var(--bg-opacity))}.lg\:focus\:bg-indigo-700:focus{--bg-opacity:1;background-color:#4c51bf;background-color:rgba(76,81,191,var(--bg-opacity))}.lg\:focus\:bg-indigo-800:focus{--bg-opacity:1;background-color:#434190;background-color:rgba(67,65,144,var(--bg-opacity))}.lg\:focus\:bg-indigo-900:focus{--bg-opacity:1;background-color:#3c366b;background-color:rgba(60,54,107,var(--bg-opacity))}.lg\:focus\:bg-purple-100:focus{--bg-opacity:1;background-color:#faf5ff;background-color:rgba(250,245,255,var(--bg-opacity))}.lg\:focus\:bg-purple-200:focus{--bg-opacity:1;background-color:#e9d8fd;background-color:rgba(233,216,253,var(--bg-opacity))}.lg\:focus\:bg-purple-300:focus{--bg-opacity:1;background-color:#d6bcfa;background-color:rgba(214,188,250,var(--bg-opacity))}.lg\:focus\:bg-purple-400:focus{--bg-opacity:1;background-color:#b794f4;background-color:rgba(183,148,244,var(--bg-opacity))}.lg\:focus\:bg-purple-500:focus{--bg-opacity:1;background-color:#9f7aea;background-color:rgba(159,122,234,var(--bg-opacity))}.lg\:focus\:bg-purple-600:focus{--bg-opacity:1;background-color:#805ad5;background-color:rgba(128,90,213,var(--bg-opacity))}.lg\:focus\:bg-purple-700:focus{--bg-opacity:1;background-color:#6b46c1;background-color:rgba(107,70,193,var(--bg-opacity))}.lg\:focus\:bg-purple-800:focus{--bg-opacity:1;background-color:#553c9a;background-color:rgba(85,60,154,var(--bg-opacity))}.lg\:focus\:bg-purple-900:focus{--bg-opacity:1;background-color:#44337a;background-color:rgba(68,51,122,var(--bg-opacity))}.lg\:focus\:bg-pink-100:focus{--bg-opacity:1;background-color:#fff5f7;background-color:rgba(255,245,247,var(--bg-opacity))}.lg\:focus\:bg-pink-200:focus{--bg-opacity:1;background-color:#fed7e2;background-color:rgba(254,215,226,var(--bg-opacity))}.lg\:focus\:bg-pink-300:focus{--bg-opacity:1;background-color:#fbb6ce;background-color:rgba(251,182,206,var(--bg-opacity))}.lg\:focus\:bg-pink-400:focus{--bg-opacity:1;background-color:#f687b3;background-color:rgba(246,135,179,var(--bg-opacity))}.lg\:focus\:bg-pink-500:focus{--bg-opacity:1;background-color:#ed64a6;background-color:rgba(237,100,166,var(--bg-opacity))}.lg\:focus\:bg-pink-600:focus{--bg-opacity:1;background-color:#d53f8c;background-color:rgba(213,63,140,var(--bg-opacity))}.lg\:focus\:bg-pink-700:focus{--bg-opacity:1;background-color:#b83280;background-color:rgba(184,50,128,var(--bg-opacity))}.lg\:focus\:bg-pink-800:focus{--bg-opacity:1;background-color:#97266d;background-color:rgba(151,38,109,var(--bg-opacity))}.lg\:focus\:bg-pink-900:focus{--bg-opacity:1;background-color:#702459;background-color:rgba(112,36,89,var(--bg-opacity))}.lg\:bg-none{background-image:none}.lg\:bg-gradient-to-t{background-image:linear-gradient(to top,var(--gradient-color-stops))}.lg\:bg-gradient-to-tr{background-image:linear-gradient(to top right,var(--gradient-color-stops))}.lg\:bg-gradient-to-r{background-image:linear-gradient(to right,var(--gradient-color-stops))}.lg\:bg-gradient-to-br{background-image:linear-gradient(to bottom right,var(--gradient-color-stops))}.lg\:bg-gradient-to-b{background-image:linear-gradient(to bottom,var(--gradient-color-stops))}.lg\:bg-gradient-to-bl{background-image:linear-gradient(to bottom left,var(--gradient-color-stops))}.lg\:bg-gradient-to-l{background-image:linear-gradient(to left,var(--gradient-color-stops))}.lg\:bg-gradient-to-tl{background-image:linear-gradient(to top left,var(--gradient-color-stops))}.lg\:from-transparent{--gradient-from-color:transparent;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(0, 0, 0, 0))}.lg\:from-current{--gradient-from-color:currentColor;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 255, 255, 0))}.lg\:from-black{--gradient-from-color:#000;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(0, 0, 0, 0))}.lg\:from-white{--gradient-from-color:#fff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 255, 255, 0))}.lg\:from-gray-100{--gradient-from-color:#f7fafc;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(247, 250, 252, 0))}.lg\:from-gray-200{--gradient-from-color:#edf2f7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(237, 242, 247, 0))}.lg\:from-gray-300{--gradient-from-color:#e2e8f0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(226, 232, 240, 0))}.lg\:from-gray-400{--gradient-from-color:#cbd5e0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(203, 213, 224, 0))}.lg\:from-gray-500{--gradient-from-color:#a0aec0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(160, 174, 192, 0))}.lg\:from-gray-600{--gradient-from-color:#718096;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(113, 128, 150, 0))}.lg\:from-gray-700{--gradient-from-color:#4a5568;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(74, 85, 104, 0))}.lg\:from-gray-800{--gradient-from-color:#2d3748;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(45, 55, 72, 0))}.lg\:from-gray-900{--gradient-from-color:#1a202c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(26, 32, 44, 0))}.lg\:from-red-100{--gradient-from-color:#fff5f5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 245, 245, 0))}.lg\:from-red-200{--gradient-from-color:#fed7d7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(254, 215, 215, 0))}.lg\:from-red-300{--gradient-from-color:#feb2b2;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(254, 178, 178, 0))}.lg\:from-red-400{--gradient-from-color:#fc8181;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(252, 129, 129, 0))}.lg\:from-red-500{--gradient-from-color:#f56565;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(245, 101, 101, 0))}.lg\:from-red-600{--gradient-from-color:#e53e3e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(229, 62, 62, 0))}.lg\:from-red-700{--gradient-from-color:#c53030;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(197, 48, 48, 0))}.lg\:from-red-800{--gradient-from-color:#9b2c2c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(155, 44, 44, 0))}.lg\:from-red-900{--gradient-from-color:#742a2a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(116, 42, 42, 0))}.lg\:from-orange-100{--gradient-from-color:#fffaf0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 250, 240, 0))}.lg\:from-orange-200{--gradient-from-color:#feebc8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(254, 235, 200, 0))}.lg\:from-orange-300{--gradient-from-color:#fbd38d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(251, 211, 141, 0))}.lg\:from-orange-400{--gradient-from-color:#f6ad55;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(246, 173, 85, 0))}.lg\:from-orange-500{--gradient-from-color:#ed8936;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(237, 137, 54, 0))}.lg\:from-orange-600{--gradient-from-color:#dd6b20;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(221, 107, 32, 0))}.lg\:from-orange-700{--gradient-from-color:#c05621;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(192, 86, 33, 0))}.lg\:from-orange-800{--gradient-from-color:#9c4221;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(156, 66, 33, 0))}.lg\:from-orange-900{--gradient-from-color:#7b341e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(123, 52, 30, 0))}.lg\:from-yellow-100{--gradient-from-color:#fffff0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 255, 240, 0))}.lg\:from-yellow-200{--gradient-from-color:#fefcbf;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(254, 252, 191, 0))}.lg\:from-yellow-300{--gradient-from-color:#faf089;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(250, 240, 137, 0))}.lg\:from-yellow-400{--gradient-from-color:#f6e05e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(246, 224, 94, 0))}.lg\:from-yellow-500{--gradient-from-color:#ecc94b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(236, 201, 75, 0))}.lg\:from-yellow-600{--gradient-from-color:#d69e2e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(214, 158, 46, 0))}.lg\:from-yellow-700{--gradient-from-color:#b7791f;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(183, 121, 31, 0))}.lg\:from-yellow-800{--gradient-from-color:#975a16;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(151, 90, 22, 0))}.lg\:from-yellow-900{--gradient-from-color:#744210;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(116, 66, 16, 0))}.lg\:from-green-100{--gradient-from-color:#f0fff4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(240, 255, 244, 0))}.lg\:from-green-200{--gradient-from-color:#c6f6d5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(198, 246, 213, 0))}.lg\:from-green-300{--gradient-from-color:#9ae6b4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(154, 230, 180, 0))}.lg\:from-green-400{--gradient-from-color:#68d391;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(104, 211, 145, 0))}.lg\:from-green-500{--gradient-from-color:#48bb78;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(72, 187, 120, 0))}.lg\:from-green-600{--gradient-from-color:#38a169;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(56, 161, 105, 0))}.lg\:from-green-700{--gradient-from-color:#2f855a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(47, 133, 90, 0))}.lg\:from-green-800{--gradient-from-color:#276749;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(39, 103, 73, 0))}.lg\:from-green-900{--gradient-from-color:#22543d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(34, 84, 61, 0))}.lg\:from-teal-100{--gradient-from-color:#e6fffa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(230, 255, 250, 0))}.lg\:from-teal-200{--gradient-from-color:#b2f5ea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(178, 245, 234, 0))}.lg\:from-teal-300{--gradient-from-color:#81e6d9;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(129, 230, 217, 0))}.lg\:from-teal-400{--gradient-from-color:#4fd1c5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(79, 209, 197, 0))}.lg\:from-teal-500{--gradient-from-color:#38b2ac;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(56, 178, 172, 0))}.lg\:from-teal-600{--gradient-from-color:#319795;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(49, 151, 149, 0))}.lg\:from-teal-700{--gradient-from-color:#2c7a7b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(44, 122, 123, 0))}.lg\:from-teal-800{--gradient-from-color:#285e61;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(40, 94, 97, 0))}.lg\:from-teal-900{--gradient-from-color:#234e52;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(35, 78, 82, 0))}.lg\:from-blue-100{--gradient-from-color:#ebf8ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(235, 248, 255, 0))}.lg\:from-blue-200{--gradient-from-color:#bee3f8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(190, 227, 248, 0))}.lg\:from-blue-300{--gradient-from-color:#90cdf4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(144, 205, 244, 0))}.lg\:from-blue-400{--gradient-from-color:#63b3ed;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(99, 179, 237, 0))}.lg\:from-blue-500{--gradient-from-color:#4299e1;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(66, 153, 225, 0))}.lg\:from-blue-600{--gradient-from-color:#3182ce;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(49, 130, 206, 0))}.lg\:from-blue-700{--gradient-from-color:#2b6cb0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(43, 108, 176, 0))}.lg\:from-blue-800{--gradient-from-color:#2c5282;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(44, 82, 130, 0))}.lg\:from-blue-900{--gradient-from-color:#2a4365;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(42, 67, 101, 0))}.lg\:from-indigo-100{--gradient-from-color:#ebf4ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(235, 244, 255, 0))}.lg\:from-indigo-200{--gradient-from-color:#c3dafe;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(195, 218, 254, 0))}.lg\:from-indigo-300{--gradient-from-color:#a3bffa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(163, 191, 250, 0))}.lg\:from-indigo-400{--gradient-from-color:#7f9cf5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(127, 156, 245, 0))}.lg\:from-indigo-500{--gradient-from-color:#667eea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(102, 126, 234, 0))}.lg\:from-indigo-600{--gradient-from-color:#5a67d8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(90, 103, 216, 0))}.lg\:from-indigo-700{--gradient-from-color:#4c51bf;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(76, 81, 191, 0))}.lg\:from-indigo-800{--gradient-from-color:#434190;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(67, 65, 144, 0))}.lg\:from-indigo-900{--gradient-from-color:#3c366b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(60, 54, 107, 0))}.lg\:from-purple-100{--gradient-from-color:#faf5ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(250, 245, 255, 0))}.lg\:from-purple-200{--gradient-from-color:#e9d8fd;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(233, 216, 253, 0))}.lg\:from-purple-300{--gradient-from-color:#d6bcfa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(214, 188, 250, 0))}.lg\:from-purple-400{--gradient-from-color:#b794f4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(183, 148, 244, 0))}.lg\:from-purple-500{--gradient-from-color:#9f7aea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(159, 122, 234, 0))}.lg\:from-purple-600{--gradient-from-color:#805ad5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(128, 90, 213, 0))}.lg\:from-purple-700{--gradient-from-color:#6b46c1;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(107, 70, 193, 0))}.lg\:from-purple-800{--gradient-from-color:#553c9a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(85, 60, 154, 0))}.lg\:from-purple-900{--gradient-from-color:#44337a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(68, 51, 122, 0))}.lg\:from-pink-100{--gradient-from-color:#fff5f7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 245, 247, 0))}.lg\:from-pink-200{--gradient-from-color:#fed7e2;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(254, 215, 226, 0))}.lg\:from-pink-300{--gradient-from-color:#fbb6ce;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(251, 182, 206, 0))}.lg\:from-pink-400{--gradient-from-color:#f687b3;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(246, 135, 179, 0))}.lg\:from-pink-500{--gradient-from-color:#ed64a6;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(237, 100, 166, 0))}.lg\:from-pink-600{--gradient-from-color:#d53f8c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(213, 63, 140, 0))}.lg\:from-pink-700{--gradient-from-color:#b83280;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(184, 50, 128, 0))}.lg\:from-pink-800{--gradient-from-color:#97266d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(151, 38, 109, 0))}.lg\:from-pink-900{--gradient-from-color:#702459;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(112, 36, 89, 0))}.lg\:via-transparent{--gradient-via-color:transparent;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(0, 0, 0, 0))}.lg\:via-current{--gradient-via-color:currentColor;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 255, 255, 0))}.lg\:via-black{--gradient-via-color:#000;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(0, 0, 0, 0))}.lg\:via-white{--gradient-via-color:#fff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 255, 255, 0))}.lg\:via-gray-100{--gradient-via-color:#f7fafc;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(247, 250, 252, 0))}.lg\:via-gray-200{--gradient-via-color:#edf2f7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(237, 242, 247, 0))}.lg\:via-gray-300{--gradient-via-color:#e2e8f0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(226, 232, 240, 0))}.lg\:via-gray-400{--gradient-via-color:#cbd5e0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(203, 213, 224, 0))}.lg\:via-gray-500{--gradient-via-color:#a0aec0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(160, 174, 192, 0))}.lg\:via-gray-600{--gradient-via-color:#718096;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(113, 128, 150, 0))}.lg\:via-gray-700{--gradient-via-color:#4a5568;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(74, 85, 104, 0))}.lg\:via-gray-800{--gradient-via-color:#2d3748;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(45, 55, 72, 0))}.lg\:via-gray-900{--gradient-via-color:#1a202c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(26, 32, 44, 0))}.lg\:via-red-100{--gradient-via-color:#fff5f5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 245, 245, 0))}.lg\:via-red-200{--gradient-via-color:#fed7d7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(254, 215, 215, 0))}.lg\:via-red-300{--gradient-via-color:#feb2b2;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(254, 178, 178, 0))}.lg\:via-red-400{--gradient-via-color:#fc8181;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(252, 129, 129, 0))}.lg\:via-red-500{--gradient-via-color:#f56565;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(245, 101, 101, 0))}.lg\:via-red-600{--gradient-via-color:#e53e3e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(229, 62, 62, 0))}.lg\:via-red-700{--gradient-via-color:#c53030;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(197, 48, 48, 0))}.lg\:via-red-800{--gradient-via-color:#9b2c2c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(155, 44, 44, 0))}.lg\:via-red-900{--gradient-via-color:#742a2a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(116, 42, 42, 0))}.lg\:via-orange-100{--gradient-via-color:#fffaf0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 250, 240, 0))}.lg\:via-orange-200{--gradient-via-color:#feebc8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(254, 235, 200, 0))}.lg\:via-orange-300{--gradient-via-color:#fbd38d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(251, 211, 141, 0))}.lg\:via-orange-400{--gradient-via-color:#f6ad55;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(246, 173, 85, 0))}.lg\:via-orange-500{--gradient-via-color:#ed8936;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(237, 137, 54, 0))}.lg\:via-orange-600{--gradient-via-color:#dd6b20;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(221, 107, 32, 0))}.lg\:via-orange-700{--gradient-via-color:#c05621;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(192, 86, 33, 0))}.lg\:via-orange-800{--gradient-via-color:#9c4221;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(156, 66, 33, 0))}.lg\:via-orange-900{--gradient-via-color:#7b341e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(123, 52, 30, 0))}.lg\:via-yellow-100{--gradient-via-color:#fffff0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 255, 240, 0))}.lg\:via-yellow-200{--gradient-via-color:#fefcbf;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(254, 252, 191, 0))}.lg\:via-yellow-300{--gradient-via-color:#faf089;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(250, 240, 137, 0))}.lg\:via-yellow-400{--gradient-via-color:#f6e05e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(246, 224, 94, 0))}.lg\:via-yellow-500{--gradient-via-color:#ecc94b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(236, 201, 75, 0))}.lg\:via-yellow-600{--gradient-via-color:#d69e2e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(214, 158, 46, 0))}.lg\:via-yellow-700{--gradient-via-color:#b7791f;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(183, 121, 31, 0))}.lg\:via-yellow-800{--gradient-via-color:#975a16;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(151, 90, 22, 0))}.lg\:via-yellow-900{--gradient-via-color:#744210;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(116, 66, 16, 0))}.lg\:via-green-100{--gradient-via-color:#f0fff4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(240, 255, 244, 0))}.lg\:via-green-200{--gradient-via-color:#c6f6d5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(198, 246, 213, 0))}.lg\:via-green-300{--gradient-via-color:#9ae6b4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(154, 230, 180, 0))}.lg\:via-green-400{--gradient-via-color:#68d391;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(104, 211, 145, 0))}.lg\:via-green-500{--gradient-via-color:#48bb78;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(72, 187, 120, 0))}.lg\:via-green-600{--gradient-via-color:#38a169;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(56, 161, 105, 0))}.lg\:via-green-700{--gradient-via-color:#2f855a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(47, 133, 90, 0))}.lg\:via-green-800{--gradient-via-color:#276749;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(39, 103, 73, 0))}.lg\:via-green-900{--gradient-via-color:#22543d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(34, 84, 61, 0))}.lg\:via-teal-100{--gradient-via-color:#e6fffa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(230, 255, 250, 0))}.lg\:via-teal-200{--gradient-via-color:#b2f5ea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(178, 245, 234, 0))}.lg\:via-teal-300{--gradient-via-color:#81e6d9;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(129, 230, 217, 0))}.lg\:via-teal-400{--gradient-via-color:#4fd1c5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(79, 209, 197, 0))}.lg\:via-teal-500{--gradient-via-color:#38b2ac;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(56, 178, 172, 0))}.lg\:via-teal-600{--gradient-via-color:#319795;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(49, 151, 149, 0))}.lg\:via-teal-700{--gradient-via-color:#2c7a7b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(44, 122, 123, 0))}.lg\:via-teal-800{--gradient-via-color:#285e61;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(40, 94, 97, 0))}.lg\:via-teal-900{--gradient-via-color:#234e52;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(35, 78, 82, 0))}.lg\:via-blue-100{--gradient-via-color:#ebf8ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(235, 248, 255, 0))}.lg\:via-blue-200{--gradient-via-color:#bee3f8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(190, 227, 248, 0))}.lg\:via-blue-300{--gradient-via-color:#90cdf4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(144, 205, 244, 0))}.lg\:via-blue-400{--gradient-via-color:#63b3ed;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(99, 179, 237, 0))}.lg\:via-blue-500{--gradient-via-color:#4299e1;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(66, 153, 225, 0))}.lg\:via-blue-600{--gradient-via-color:#3182ce;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(49, 130, 206, 0))}.lg\:via-blue-700{--gradient-via-color:#2b6cb0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(43, 108, 176, 0))}.lg\:via-blue-800{--gradient-via-color:#2c5282;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(44, 82, 130, 0))}.lg\:via-blue-900{--gradient-via-color:#2a4365;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(42, 67, 101, 0))}.lg\:via-indigo-100{--gradient-via-color:#ebf4ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(235, 244, 255, 0))}.lg\:via-indigo-200{--gradient-via-color:#c3dafe;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(195, 218, 254, 0))}.lg\:via-indigo-300{--gradient-via-color:#a3bffa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(163, 191, 250, 0))}.lg\:via-indigo-400{--gradient-via-color:#7f9cf5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(127, 156, 245, 0))}.lg\:via-indigo-500{--gradient-via-color:#667eea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(102, 126, 234, 0))}.lg\:via-indigo-600{--gradient-via-color:#5a67d8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(90, 103, 216, 0))}.lg\:via-indigo-700{--gradient-via-color:#4c51bf;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(76, 81, 191, 0))}.lg\:via-indigo-800{--gradient-via-color:#434190;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(67, 65, 144, 0))}.lg\:via-indigo-900{--gradient-via-color:#3c366b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(60, 54, 107, 0))}.lg\:via-purple-100{--gradient-via-color:#faf5ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(250, 245, 255, 0))}.lg\:via-purple-200{--gradient-via-color:#e9d8fd;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(233, 216, 253, 0))}.lg\:via-purple-300{--gradient-via-color:#d6bcfa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(214, 188, 250, 0))}.lg\:via-purple-400{--gradient-via-color:#b794f4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(183, 148, 244, 0))}.lg\:via-purple-500{--gradient-via-color:#9f7aea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(159, 122, 234, 0))}.lg\:via-purple-600{--gradient-via-color:#805ad5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(128, 90, 213, 0))}.lg\:via-purple-700{--gradient-via-color:#6b46c1;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(107, 70, 193, 0))}.lg\:via-purple-800{--gradient-via-color:#553c9a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(85, 60, 154, 0))}.lg\:via-purple-900{--gradient-via-color:#44337a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(68, 51, 122, 0))}.lg\:via-pink-100{--gradient-via-color:#fff5f7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 245, 247, 0))}.lg\:via-pink-200{--gradient-via-color:#fed7e2;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(254, 215, 226, 0))}.lg\:via-pink-300{--gradient-via-color:#fbb6ce;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(251, 182, 206, 0))}.lg\:via-pink-400{--gradient-via-color:#f687b3;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(246, 135, 179, 0))}.lg\:via-pink-500{--gradient-via-color:#ed64a6;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(237, 100, 166, 0))}.lg\:via-pink-600{--gradient-via-color:#d53f8c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(213, 63, 140, 0))}.lg\:via-pink-700{--gradient-via-color:#b83280;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(184, 50, 128, 0))}.lg\:via-pink-800{--gradient-via-color:#97266d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(151, 38, 109, 0))}.lg\:via-pink-900{--gradient-via-color:#702459;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(112, 36, 89, 0))}.lg\:to-transparent{--gradient-to-color:transparent}.lg\:to-current{--gradient-to-color:currentColor}.lg\:to-black{--gradient-to-color:#000}.lg\:to-white{--gradient-to-color:#fff}.lg\:to-gray-100{--gradient-to-color:#f7fafc}.lg\:to-gray-200{--gradient-to-color:#edf2f7}.lg\:to-gray-300{--gradient-to-color:#e2e8f0}.lg\:to-gray-400{--gradient-to-color:#cbd5e0}.lg\:to-gray-500{--gradient-to-color:#a0aec0}.lg\:to-gray-600{--gradient-to-color:#718096}.lg\:to-gray-700{--gradient-to-color:#4a5568}.lg\:to-gray-800{--gradient-to-color:#2d3748}.lg\:to-gray-900{--gradient-to-color:#1a202c}.lg\:to-red-100{--gradient-to-color:#fff5f5}.lg\:to-red-200{--gradient-to-color:#fed7d7}.lg\:to-red-300{--gradient-to-color:#feb2b2}.lg\:to-red-400{--gradient-to-color:#fc8181}.lg\:to-red-500{--gradient-to-color:#f56565}.lg\:to-red-600{--gradient-to-color:#e53e3e}.lg\:to-red-700{--gradient-to-color:#c53030}.lg\:to-red-800{--gradient-to-color:#9b2c2c}.lg\:to-red-900{--gradient-to-color:#742a2a}.lg\:to-orange-100{--gradient-to-color:#fffaf0}.lg\:to-orange-200{--gradient-to-color:#feebc8}.lg\:to-orange-300{--gradient-to-color:#fbd38d}.lg\:to-orange-400{--gradient-to-color:#f6ad55}.lg\:to-orange-500{--gradient-to-color:#ed8936}.lg\:to-orange-600{--gradient-to-color:#dd6b20}.lg\:to-orange-700{--gradient-to-color:#c05621}.lg\:to-orange-800{--gradient-to-color:#9c4221}.lg\:to-orange-900{--gradient-to-color:#7b341e}.lg\:to-yellow-100{--gradient-to-color:#fffff0}.lg\:to-yellow-200{--gradient-to-color:#fefcbf}.lg\:to-yellow-300{--gradient-to-color:#faf089}.lg\:to-yellow-400{--gradient-to-color:#f6e05e}.lg\:to-yellow-500{--gradient-to-color:#ecc94b}.lg\:to-yellow-600{--gradient-to-color:#d69e2e}.lg\:to-yellow-700{--gradient-to-color:#b7791f}.lg\:to-yellow-800{--gradient-to-color:#975a16}.lg\:to-yellow-900{--gradient-to-color:#744210}.lg\:to-green-100{--gradient-to-color:#f0fff4}.lg\:to-green-200{--gradient-to-color:#c6f6d5}.lg\:to-green-300{--gradient-to-color:#9ae6b4}.lg\:to-green-400{--gradient-to-color:#68d391}.lg\:to-green-500{--gradient-to-color:#48bb78}.lg\:to-green-600{--gradient-to-color:#38a169}.lg\:to-green-700{--gradient-to-color:#2f855a}.lg\:to-green-800{--gradient-to-color:#276749}.lg\:to-green-900{--gradient-to-color:#22543d}.lg\:to-teal-100{--gradient-to-color:#e6fffa}.lg\:to-teal-200{--gradient-to-color:#b2f5ea}.lg\:to-teal-300{--gradient-to-color:#81e6d9}.lg\:to-teal-400{--gradient-to-color:#4fd1c5}.lg\:to-teal-500{--gradient-to-color:#38b2ac}.lg\:to-teal-600{--gradient-to-color:#319795}.lg\:to-teal-700{--gradient-to-color:#2c7a7b}.lg\:to-teal-800{--gradient-to-color:#285e61}.lg\:to-teal-900{--gradient-to-color:#234e52}.lg\:to-blue-100{--gradient-to-color:#ebf8ff}.lg\:to-blue-200{--gradient-to-color:#bee3f8}.lg\:to-blue-300{--gradient-to-color:#90cdf4}.lg\:to-blue-400{--gradient-to-color:#63b3ed}.lg\:to-blue-500{--gradient-to-color:#4299e1}.lg\:to-blue-600{--gradient-to-color:#3182ce}.lg\:to-blue-700{--gradient-to-color:#2b6cb0}.lg\:to-blue-800{--gradient-to-color:#2c5282}.lg\:to-blue-900{--gradient-to-color:#2a4365}.lg\:to-indigo-100{--gradient-to-color:#ebf4ff}.lg\:to-indigo-200{--gradient-to-color:#c3dafe}.lg\:to-indigo-300{--gradient-to-color:#a3bffa}.lg\:to-indigo-400{--gradient-to-color:#7f9cf5}.lg\:to-indigo-500{--gradient-to-color:#667eea}.lg\:to-indigo-600{--gradient-to-color:#5a67d8}.lg\:to-indigo-700{--gradient-to-color:#4c51bf}.lg\:to-indigo-800{--gradient-to-color:#434190}.lg\:to-indigo-900{--gradient-to-color:#3c366b}.lg\:to-purple-100{--gradient-to-color:#faf5ff}.lg\:to-purple-200{--gradient-to-color:#e9d8fd}.lg\:to-purple-300{--gradient-to-color:#d6bcfa}.lg\:to-purple-400{--gradient-to-color:#b794f4}.lg\:to-purple-500{--gradient-to-color:#9f7aea}.lg\:to-purple-600{--gradient-to-color:#805ad5}.lg\:to-purple-700{--gradient-to-color:#6b46c1}.lg\:to-purple-800{--gradient-to-color:#553c9a}.lg\:to-purple-900{--gradient-to-color:#44337a}.lg\:to-pink-100{--gradient-to-color:#fff5f7}.lg\:to-pink-200{--gradient-to-color:#fed7e2}.lg\:to-pink-300{--gradient-to-color:#fbb6ce}.lg\:to-pink-400{--gradient-to-color:#f687b3}.lg\:to-pink-500{--gradient-to-color:#ed64a6}.lg\:to-pink-600{--gradient-to-color:#d53f8c}.lg\:to-pink-700{--gradient-to-color:#b83280}.lg\:to-pink-800{--gradient-to-color:#97266d}.lg\:to-pink-900{--gradient-to-color:#702459}.lg\:hover\:from-transparent:hover{--gradient-from-color:transparent;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(0, 0, 0, 0))}.lg\:hover\:from-current:hover{--gradient-from-color:currentColor;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 255, 255, 0))}.lg\:hover\:from-black:hover{--gradient-from-color:#000;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(0, 0, 0, 0))}.lg\:hover\:from-white:hover{--gradient-from-color:#fff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 255, 255, 0))}.lg\:hover\:from-gray-100:hover{--gradient-from-color:#f7fafc;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(247, 250, 252, 0))}.lg\:hover\:from-gray-200:hover{--gradient-from-color:#edf2f7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(237, 242, 247, 0))}.lg\:hover\:from-gray-300:hover{--gradient-from-color:#e2e8f0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(226, 232, 240, 0))}.lg\:hover\:from-gray-400:hover{--gradient-from-color:#cbd5e0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(203, 213, 224, 0))}.lg\:hover\:from-gray-500:hover{--gradient-from-color:#a0aec0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(160, 174, 192, 0))}.lg\:hover\:from-gray-600:hover{--gradient-from-color:#718096;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(113, 128, 150, 0))}.lg\:hover\:from-gray-700:hover{--gradient-from-color:#4a5568;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(74, 85, 104, 0))}.lg\:hover\:from-gray-800:hover{--gradient-from-color:#2d3748;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(45, 55, 72, 0))}.lg\:hover\:from-gray-900:hover{--gradient-from-color:#1a202c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(26, 32, 44, 0))}.lg\:hover\:from-red-100:hover{--gradient-from-color:#fff5f5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 245, 245, 0))}.lg\:hover\:from-red-200:hover{--gradient-from-color:#fed7d7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(254, 215, 215, 0))}.lg\:hover\:from-red-300:hover{--gradient-from-color:#feb2b2;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(254, 178, 178, 0))}.lg\:hover\:from-red-400:hover{--gradient-from-color:#fc8181;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(252, 129, 129, 0))}.lg\:hover\:from-red-500:hover{--gradient-from-color:#f56565;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(245, 101, 101, 0))}.lg\:hover\:from-red-600:hover{--gradient-from-color:#e53e3e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(229, 62, 62, 0))}.lg\:hover\:from-red-700:hover{--gradient-from-color:#c53030;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(197, 48, 48, 0))}.lg\:hover\:from-red-800:hover{--gradient-from-color:#9b2c2c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(155, 44, 44, 0))}.lg\:hover\:from-red-900:hover{--gradient-from-color:#742a2a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(116, 42, 42, 0))}.lg\:hover\:from-orange-100:hover{--gradient-from-color:#fffaf0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 250, 240, 0))}.lg\:hover\:from-orange-200:hover{--gradient-from-color:#feebc8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(254, 235, 200, 0))}.lg\:hover\:from-orange-300:hover{--gradient-from-color:#fbd38d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(251, 211, 141, 0))}.lg\:hover\:from-orange-400:hover{--gradient-from-color:#f6ad55;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(246, 173, 85, 0))}.lg\:hover\:from-orange-500:hover{--gradient-from-color:#ed8936;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(237, 137, 54, 0))}.lg\:hover\:from-orange-600:hover{--gradient-from-color:#dd6b20;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(221, 107, 32, 0))}.lg\:hover\:from-orange-700:hover{--gradient-from-color:#c05621;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(192, 86, 33, 0))}.lg\:hover\:from-orange-800:hover{--gradient-from-color:#9c4221;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(156, 66, 33, 0))}.lg\:hover\:from-orange-900:hover{--gradient-from-color:#7b341e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(123, 52, 30, 0))}.lg\:hover\:from-yellow-100:hover{--gradient-from-color:#fffff0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 255, 240, 0))}.lg\:hover\:from-yellow-200:hover{--gradient-from-color:#fefcbf;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(254, 252, 191, 0))}.lg\:hover\:from-yellow-300:hover{--gradient-from-color:#faf089;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(250, 240, 137, 0))}.lg\:hover\:from-yellow-400:hover{--gradient-from-color:#f6e05e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(246, 224, 94, 0))}.lg\:hover\:from-yellow-500:hover{--gradient-from-color:#ecc94b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(236, 201, 75, 0))}.lg\:hover\:from-yellow-600:hover{--gradient-from-color:#d69e2e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(214, 158, 46, 0))}.lg\:hover\:from-yellow-700:hover{--gradient-from-color:#b7791f;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(183, 121, 31, 0))}.lg\:hover\:from-yellow-800:hover{--gradient-from-color:#975a16;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(151, 90, 22, 0))}.lg\:hover\:from-yellow-900:hover{--gradient-from-color:#744210;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(116, 66, 16, 0))}.lg\:hover\:from-green-100:hover{--gradient-from-color:#f0fff4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(240, 255, 244, 0))}.lg\:hover\:from-green-200:hover{--gradient-from-color:#c6f6d5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(198, 246, 213, 0))}.lg\:hover\:from-green-300:hover{--gradient-from-color:#9ae6b4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(154, 230, 180, 0))}.lg\:hover\:from-green-400:hover{--gradient-from-color:#68d391;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(104, 211, 145, 0))}.lg\:hover\:from-green-500:hover{--gradient-from-color:#48bb78;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(72, 187, 120, 0))}.lg\:hover\:from-green-600:hover{--gradient-from-color:#38a169;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(56, 161, 105, 0))}.lg\:hover\:from-green-700:hover{--gradient-from-color:#2f855a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(47, 133, 90, 0))}.lg\:hover\:from-green-800:hover{--gradient-from-color:#276749;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(39, 103, 73, 0))}.lg\:hover\:from-green-900:hover{--gradient-from-color:#22543d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(34, 84, 61, 0))}.lg\:hover\:from-teal-100:hover{--gradient-from-color:#e6fffa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(230, 255, 250, 0))}.lg\:hover\:from-teal-200:hover{--gradient-from-color:#b2f5ea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(178, 245, 234, 0))}.lg\:hover\:from-teal-300:hover{--gradient-from-color:#81e6d9;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(129, 230, 217, 0))}.lg\:hover\:from-teal-400:hover{--gradient-from-color:#4fd1c5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(79, 209, 197, 0))}.lg\:hover\:from-teal-500:hover{--gradient-from-color:#38b2ac;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(56, 178, 172, 0))}.lg\:hover\:from-teal-600:hover{--gradient-from-color:#319795;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(49, 151, 149, 0))}.lg\:hover\:from-teal-700:hover{--gradient-from-color:#2c7a7b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(44, 122, 123, 0))}.lg\:hover\:from-teal-800:hover{--gradient-from-color:#285e61;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(40, 94, 97, 0))}.lg\:hover\:from-teal-900:hover{--gradient-from-color:#234e52;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(35, 78, 82, 0))}.lg\:hover\:from-blue-100:hover{--gradient-from-color:#ebf8ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(235, 248, 255, 0))}.lg\:hover\:from-blue-200:hover{--gradient-from-color:#bee3f8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(190, 227, 248, 0))}.lg\:hover\:from-blue-300:hover{--gradient-from-color:#90cdf4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(144, 205, 244, 0))}.lg\:hover\:from-blue-400:hover{--gradient-from-color:#63b3ed;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(99, 179, 237, 0))}.lg\:hover\:from-blue-500:hover{--gradient-from-color:#4299e1;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(66, 153, 225, 0))}.lg\:hover\:from-blue-600:hover{--gradient-from-color:#3182ce;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(49, 130, 206, 0))}.lg\:hover\:from-blue-700:hover{--gradient-from-color:#2b6cb0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(43, 108, 176, 0))}.lg\:hover\:from-blue-800:hover{--gradient-from-color:#2c5282;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(44, 82, 130, 0))}.lg\:hover\:from-blue-900:hover{--gradient-from-color:#2a4365;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(42, 67, 101, 0))}.lg\:hover\:from-indigo-100:hover{--gradient-from-color:#ebf4ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(235, 244, 255, 0))}.lg\:hover\:from-indigo-200:hover{--gradient-from-color:#c3dafe;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(195, 218, 254, 0))}.lg\:hover\:from-indigo-300:hover{--gradient-from-color:#a3bffa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(163, 191, 250, 0))}.lg\:hover\:from-indigo-400:hover{--gradient-from-color:#7f9cf5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(127, 156, 245, 0))}.lg\:hover\:from-indigo-500:hover{--gradient-from-color:#667eea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(102, 126, 234, 0))}.lg\:hover\:from-indigo-600:hover{--gradient-from-color:#5a67d8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(90, 103, 216, 0))}.lg\:hover\:from-indigo-700:hover{--gradient-from-color:#4c51bf;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(76, 81, 191, 0))}.lg\:hover\:from-indigo-800:hover{--gradient-from-color:#434190;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(67, 65, 144, 0))}.lg\:hover\:from-indigo-900:hover{--gradient-from-color:#3c366b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(60, 54, 107, 0))}.lg\:hover\:from-purple-100:hover{--gradient-from-color:#faf5ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(250, 245, 255, 0))}.lg\:hover\:from-purple-200:hover{--gradient-from-color:#e9d8fd;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(233, 216, 253, 0))}.lg\:hover\:from-purple-300:hover{--gradient-from-color:#d6bcfa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(214, 188, 250, 0))}.lg\:hover\:from-purple-400:hover{--gradient-from-color:#b794f4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(183, 148, 244, 0))}.lg\:hover\:from-purple-500:hover{--gradient-from-color:#9f7aea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(159, 122, 234, 0))}.lg\:hover\:from-purple-600:hover{--gradient-from-color:#805ad5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(128, 90, 213, 0))}.lg\:hover\:from-purple-700:hover{--gradient-from-color:#6b46c1;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(107, 70, 193, 0))}.lg\:hover\:from-purple-800:hover{--gradient-from-color:#553c9a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(85, 60, 154, 0))}.lg\:hover\:from-purple-900:hover{--gradient-from-color:#44337a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(68, 51, 122, 0))}.lg\:hover\:from-pink-100:hover{--gradient-from-color:#fff5f7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 245, 247, 0))}.lg\:hover\:from-pink-200:hover{--gradient-from-color:#fed7e2;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(254, 215, 226, 0))}.lg\:hover\:from-pink-300:hover{--gradient-from-color:#fbb6ce;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(251, 182, 206, 0))}.lg\:hover\:from-pink-400:hover{--gradient-from-color:#f687b3;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(246, 135, 179, 0))}.lg\:hover\:from-pink-500:hover{--gradient-from-color:#ed64a6;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(237, 100, 166, 0))}.lg\:hover\:from-pink-600:hover{--gradient-from-color:#d53f8c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(213, 63, 140, 0))}.lg\:hover\:from-pink-700:hover{--gradient-from-color:#b83280;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(184, 50, 128, 0))}.lg\:hover\:from-pink-800:hover{--gradient-from-color:#97266d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(151, 38, 109, 0))}.lg\:hover\:from-pink-900:hover{--gradient-from-color:#702459;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(112, 36, 89, 0))}.lg\:hover\:via-transparent:hover{--gradient-via-color:transparent;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(0, 0, 0, 0))}.lg\:hover\:via-current:hover{--gradient-via-color:currentColor;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 255, 255, 0))}.lg\:hover\:via-black:hover{--gradient-via-color:#000;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(0, 0, 0, 0))}.lg\:hover\:via-white:hover{--gradient-via-color:#fff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 255, 255, 0))}.lg\:hover\:via-gray-100:hover{--gradient-via-color:#f7fafc;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(247, 250, 252, 0))}.lg\:hover\:via-gray-200:hover{--gradient-via-color:#edf2f7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(237, 242, 247, 0))}.lg\:hover\:via-gray-300:hover{--gradient-via-color:#e2e8f0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(226, 232, 240, 0))}.lg\:hover\:via-gray-400:hover{--gradient-via-color:#cbd5e0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(203, 213, 224, 0))}.lg\:hover\:via-gray-500:hover{--gradient-via-color:#a0aec0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(160, 174, 192, 0))}.lg\:hover\:via-gray-600:hover{--gradient-via-color:#718096;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(113, 128, 150, 0))}.lg\:hover\:via-gray-700:hover{--gradient-via-color:#4a5568;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(74, 85, 104, 0))}.lg\:hover\:via-gray-800:hover{--gradient-via-color:#2d3748;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(45, 55, 72, 0))}.lg\:hover\:via-gray-900:hover{--gradient-via-color:#1a202c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(26, 32, 44, 0))}.lg\:hover\:via-red-100:hover{--gradient-via-color:#fff5f5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 245, 245, 0))}.lg\:hover\:via-red-200:hover{--gradient-via-color:#fed7d7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(254, 215, 215, 0))}.lg\:hover\:via-red-300:hover{--gradient-via-color:#feb2b2;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(254, 178, 178, 0))}.lg\:hover\:via-red-400:hover{--gradient-via-color:#fc8181;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(252, 129, 129, 0))}.lg\:hover\:via-red-500:hover{--gradient-via-color:#f56565;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(245, 101, 101, 0))}.lg\:hover\:via-red-600:hover{--gradient-via-color:#e53e3e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(229, 62, 62, 0))}.lg\:hover\:via-red-700:hover{--gradient-via-color:#c53030;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(197, 48, 48, 0))}.lg\:hover\:via-red-800:hover{--gradient-via-color:#9b2c2c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(155, 44, 44, 0))}.lg\:hover\:via-red-900:hover{--gradient-via-color:#742a2a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(116, 42, 42, 0))}.lg\:hover\:via-orange-100:hover{--gradient-via-color:#fffaf0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 250, 240, 0))}.lg\:hover\:via-orange-200:hover{--gradient-via-color:#feebc8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(254, 235, 200, 0))}.lg\:hover\:via-orange-300:hover{--gradient-via-color:#fbd38d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(251, 211, 141, 0))}.lg\:hover\:via-orange-400:hover{--gradient-via-color:#f6ad55;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(246, 173, 85, 0))}.lg\:hover\:via-orange-500:hover{--gradient-via-color:#ed8936;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(237, 137, 54, 0))}.lg\:hover\:via-orange-600:hover{--gradient-via-color:#dd6b20;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(221, 107, 32, 0))}.lg\:hover\:via-orange-700:hover{--gradient-via-color:#c05621;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(192, 86, 33, 0))}.lg\:hover\:via-orange-800:hover{--gradient-via-color:#9c4221;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(156, 66, 33, 0))}.lg\:hover\:via-orange-900:hover{--gradient-via-color:#7b341e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(123, 52, 30, 0))}.lg\:hover\:via-yellow-100:hover{--gradient-via-color:#fffff0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 255, 240, 0))}.lg\:hover\:via-yellow-200:hover{--gradient-via-color:#fefcbf;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(254, 252, 191, 0))}.lg\:hover\:via-yellow-300:hover{--gradient-via-color:#faf089;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(250, 240, 137, 0))}.lg\:hover\:via-yellow-400:hover{--gradient-via-color:#f6e05e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(246, 224, 94, 0))}.lg\:hover\:via-yellow-500:hover{--gradient-via-color:#ecc94b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(236, 201, 75, 0))}.lg\:hover\:via-yellow-600:hover{--gradient-via-color:#d69e2e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(214, 158, 46, 0))}.lg\:hover\:via-yellow-700:hover{--gradient-via-color:#b7791f;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(183, 121, 31, 0))}.lg\:hover\:via-yellow-800:hover{--gradient-via-color:#975a16;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(151, 90, 22, 0))}.lg\:hover\:via-yellow-900:hover{--gradient-via-color:#744210;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(116, 66, 16, 0))}.lg\:hover\:via-green-100:hover{--gradient-via-color:#f0fff4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(240, 255, 244, 0))}.lg\:hover\:via-green-200:hover{--gradient-via-color:#c6f6d5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(198, 246, 213, 0))}.lg\:hover\:via-green-300:hover{--gradient-via-color:#9ae6b4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(154, 230, 180, 0))}.lg\:hover\:via-green-400:hover{--gradient-via-color:#68d391;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(104, 211, 145, 0))}.lg\:hover\:via-green-500:hover{--gradient-via-color:#48bb78;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(72, 187, 120, 0))}.lg\:hover\:via-green-600:hover{--gradient-via-color:#38a169;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(56, 161, 105, 0))}.lg\:hover\:via-green-700:hover{--gradient-via-color:#2f855a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(47, 133, 90, 0))}.lg\:hover\:via-green-800:hover{--gradient-via-color:#276749;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(39, 103, 73, 0))}.lg\:hover\:via-green-900:hover{--gradient-via-color:#22543d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(34, 84, 61, 0))}.lg\:hover\:via-teal-100:hover{--gradient-via-color:#e6fffa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(230, 255, 250, 0))}.lg\:hover\:via-teal-200:hover{--gradient-via-color:#b2f5ea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(178, 245, 234, 0))}.lg\:hover\:via-teal-300:hover{--gradient-via-color:#81e6d9;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(129, 230, 217, 0))}.lg\:hover\:via-teal-400:hover{--gradient-via-color:#4fd1c5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(79, 209, 197, 0))}.lg\:hover\:via-teal-500:hover{--gradient-via-color:#38b2ac;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(56, 178, 172, 0))}.lg\:hover\:via-teal-600:hover{--gradient-via-color:#319795;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(49, 151, 149, 0))}.lg\:hover\:via-teal-700:hover{--gradient-via-color:#2c7a7b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(44, 122, 123, 0))}.lg\:hover\:via-teal-800:hover{--gradient-via-color:#285e61;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(40, 94, 97, 0))}.lg\:hover\:via-teal-900:hover{--gradient-via-color:#234e52;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(35, 78, 82, 0))}.lg\:hover\:via-blue-100:hover{--gradient-via-color:#ebf8ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(235, 248, 255, 0))}.lg\:hover\:via-blue-200:hover{--gradient-via-color:#bee3f8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(190, 227, 248, 0))}.lg\:hover\:via-blue-300:hover{--gradient-via-color:#90cdf4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(144, 205, 244, 0))}.lg\:hover\:via-blue-400:hover{--gradient-via-color:#63b3ed;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(99, 179, 237, 0))}.lg\:hover\:via-blue-500:hover{--gradient-via-color:#4299e1;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(66, 153, 225, 0))}.lg\:hover\:via-blue-600:hover{--gradient-via-color:#3182ce;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(49, 130, 206, 0))}.lg\:hover\:via-blue-700:hover{--gradient-via-color:#2b6cb0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(43, 108, 176, 0))}.lg\:hover\:via-blue-800:hover{--gradient-via-color:#2c5282;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(44, 82, 130, 0))}.lg\:hover\:via-blue-900:hover{--gradient-via-color:#2a4365;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(42, 67, 101, 0))}.lg\:hover\:via-indigo-100:hover{--gradient-via-color:#ebf4ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(235, 244, 255, 0))}.lg\:hover\:via-indigo-200:hover{--gradient-via-color:#c3dafe;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(195, 218, 254, 0))}.lg\:hover\:via-indigo-300:hover{--gradient-via-color:#a3bffa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(163, 191, 250, 0))}.lg\:hover\:via-indigo-400:hover{--gradient-via-color:#7f9cf5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(127, 156, 245, 0))}.lg\:hover\:via-indigo-500:hover{--gradient-via-color:#667eea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(102, 126, 234, 0))}.lg\:hover\:via-indigo-600:hover{--gradient-via-color:#5a67d8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(90, 103, 216, 0))}.lg\:hover\:via-indigo-700:hover{--gradient-via-color:#4c51bf;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(76, 81, 191, 0))}.lg\:hover\:via-indigo-800:hover{--gradient-via-color:#434190;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(67, 65, 144, 0))}.lg\:hover\:via-indigo-900:hover{--gradient-via-color:#3c366b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(60, 54, 107, 0))}.lg\:hover\:via-purple-100:hover{--gradient-via-color:#faf5ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(250, 245, 255, 0))}.lg\:hover\:via-purple-200:hover{--gradient-via-color:#e9d8fd;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(233, 216, 253, 0))}.lg\:hover\:via-purple-300:hover{--gradient-via-color:#d6bcfa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(214, 188, 250, 0))}.lg\:hover\:via-purple-400:hover{--gradient-via-color:#b794f4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(183, 148, 244, 0))}.lg\:hover\:via-purple-500:hover{--gradient-via-color:#9f7aea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(159, 122, 234, 0))}.lg\:hover\:via-purple-600:hover{--gradient-via-color:#805ad5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(128, 90, 213, 0))}.lg\:hover\:via-purple-700:hover{--gradient-via-color:#6b46c1;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(107, 70, 193, 0))}.lg\:hover\:via-purple-800:hover{--gradient-via-color:#553c9a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(85, 60, 154, 0))}.lg\:hover\:via-purple-900:hover{--gradient-via-color:#44337a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(68, 51, 122, 0))}.lg\:hover\:via-pink-100:hover{--gradient-via-color:#fff5f7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 245, 247, 0))}.lg\:hover\:via-pink-200:hover{--gradient-via-color:#fed7e2;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(254, 215, 226, 0))}.lg\:hover\:via-pink-300:hover{--gradient-via-color:#fbb6ce;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(251, 182, 206, 0))}.lg\:hover\:via-pink-400:hover{--gradient-via-color:#f687b3;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(246, 135, 179, 0))}.lg\:hover\:via-pink-500:hover{--gradient-via-color:#ed64a6;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(237, 100, 166, 0))}.lg\:hover\:via-pink-600:hover{--gradient-via-color:#d53f8c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(213, 63, 140, 0))}.lg\:hover\:via-pink-700:hover{--gradient-via-color:#b83280;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(184, 50, 128, 0))}.lg\:hover\:via-pink-800:hover{--gradient-via-color:#97266d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(151, 38, 109, 0))}.lg\:hover\:via-pink-900:hover{--gradient-via-color:#702459;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(112, 36, 89, 0))}.lg\:hover\:to-transparent:hover{--gradient-to-color:transparent}.lg\:hover\:to-current:hover{--gradient-to-color:currentColor}.lg\:hover\:to-black:hover{--gradient-to-color:#000}.lg\:hover\:to-white:hover{--gradient-to-color:#fff}.lg\:hover\:to-gray-100:hover{--gradient-to-color:#f7fafc}.lg\:hover\:to-gray-200:hover{--gradient-to-color:#edf2f7}.lg\:hover\:to-gray-300:hover{--gradient-to-color:#e2e8f0}.lg\:hover\:to-gray-400:hover{--gradient-to-color:#cbd5e0}.lg\:hover\:to-gray-500:hover{--gradient-to-color:#a0aec0}.lg\:hover\:to-gray-600:hover{--gradient-to-color:#718096}.lg\:hover\:to-gray-700:hover{--gradient-to-color:#4a5568}.lg\:hover\:to-gray-800:hover{--gradient-to-color:#2d3748}.lg\:hover\:to-gray-900:hover{--gradient-to-color:#1a202c}.lg\:hover\:to-red-100:hover{--gradient-to-color:#fff5f5}.lg\:hover\:to-red-200:hover{--gradient-to-color:#fed7d7}.lg\:hover\:to-red-300:hover{--gradient-to-color:#feb2b2}.lg\:hover\:to-red-400:hover{--gradient-to-color:#fc8181}.lg\:hover\:to-red-500:hover{--gradient-to-color:#f56565}.lg\:hover\:to-red-600:hover{--gradient-to-color:#e53e3e}.lg\:hover\:to-red-700:hover{--gradient-to-color:#c53030}.lg\:hover\:to-red-800:hover{--gradient-to-color:#9b2c2c}.lg\:hover\:to-red-900:hover{--gradient-to-color:#742a2a}.lg\:hover\:to-orange-100:hover{--gradient-to-color:#fffaf0}.lg\:hover\:to-orange-200:hover{--gradient-to-color:#feebc8}.lg\:hover\:to-orange-300:hover{--gradient-to-color:#fbd38d}.lg\:hover\:to-orange-400:hover{--gradient-to-color:#f6ad55}.lg\:hover\:to-orange-500:hover{--gradient-to-color:#ed8936}.lg\:hover\:to-orange-600:hover{--gradient-to-color:#dd6b20}.lg\:hover\:to-orange-700:hover{--gradient-to-color:#c05621}.lg\:hover\:to-orange-800:hover{--gradient-to-color:#9c4221}.lg\:hover\:to-orange-900:hover{--gradient-to-color:#7b341e}.lg\:hover\:to-yellow-100:hover{--gradient-to-color:#fffff0}.lg\:hover\:to-yellow-200:hover{--gradient-to-color:#fefcbf}.lg\:hover\:to-yellow-300:hover{--gradient-to-color:#faf089}.lg\:hover\:to-yellow-400:hover{--gradient-to-color:#f6e05e}.lg\:hover\:to-yellow-500:hover{--gradient-to-color:#ecc94b}.lg\:hover\:to-yellow-600:hover{--gradient-to-color:#d69e2e}.lg\:hover\:to-yellow-700:hover{--gradient-to-color:#b7791f}.lg\:hover\:to-yellow-800:hover{--gradient-to-color:#975a16}.lg\:hover\:to-yellow-900:hover{--gradient-to-color:#744210}.lg\:hover\:to-green-100:hover{--gradient-to-color:#f0fff4}.lg\:hover\:to-green-200:hover{--gradient-to-color:#c6f6d5}.lg\:hover\:to-green-300:hover{--gradient-to-color:#9ae6b4}.lg\:hover\:to-green-400:hover{--gradient-to-color:#68d391}.lg\:hover\:to-green-500:hover{--gradient-to-color:#48bb78}.lg\:hover\:to-green-600:hover{--gradient-to-color:#38a169}.lg\:hover\:to-green-700:hover{--gradient-to-color:#2f855a}.lg\:hover\:to-green-800:hover{--gradient-to-color:#276749}.lg\:hover\:to-green-900:hover{--gradient-to-color:#22543d}.lg\:hover\:to-teal-100:hover{--gradient-to-color:#e6fffa}.lg\:hover\:to-teal-200:hover{--gradient-to-color:#b2f5ea}.lg\:hover\:to-teal-300:hover{--gradient-to-color:#81e6d9}.lg\:hover\:to-teal-400:hover{--gradient-to-color:#4fd1c5}.lg\:hover\:to-teal-500:hover{--gradient-to-color:#38b2ac}.lg\:hover\:to-teal-600:hover{--gradient-to-color:#319795}.lg\:hover\:to-teal-700:hover{--gradient-to-color:#2c7a7b}.lg\:hover\:to-teal-800:hover{--gradient-to-color:#285e61}.lg\:hover\:to-teal-900:hover{--gradient-to-color:#234e52}.lg\:hover\:to-blue-100:hover{--gradient-to-color:#ebf8ff}.lg\:hover\:to-blue-200:hover{--gradient-to-color:#bee3f8}.lg\:hover\:to-blue-300:hover{--gradient-to-color:#90cdf4}.lg\:hover\:to-blue-400:hover{--gradient-to-color:#63b3ed}.lg\:hover\:to-blue-500:hover{--gradient-to-color:#4299e1}.lg\:hover\:to-blue-600:hover{--gradient-to-color:#3182ce}.lg\:hover\:to-blue-700:hover{--gradient-to-color:#2b6cb0}.lg\:hover\:to-blue-800:hover{--gradient-to-color:#2c5282}.lg\:hover\:to-blue-900:hover{--gradient-to-color:#2a4365}.lg\:hover\:to-indigo-100:hover{--gradient-to-color:#ebf4ff}.lg\:hover\:to-indigo-200:hover{--gradient-to-color:#c3dafe}.lg\:hover\:to-indigo-300:hover{--gradient-to-color:#a3bffa}.lg\:hover\:to-indigo-400:hover{--gradient-to-color:#7f9cf5}.lg\:hover\:to-indigo-500:hover{--gradient-to-color:#667eea}.lg\:hover\:to-indigo-600:hover{--gradient-to-color:#5a67d8}.lg\:hover\:to-indigo-700:hover{--gradient-to-color:#4c51bf}.lg\:hover\:to-indigo-800:hover{--gradient-to-color:#434190}.lg\:hover\:to-indigo-900:hover{--gradient-to-color:#3c366b}.lg\:hover\:to-purple-100:hover{--gradient-to-color:#faf5ff}.lg\:hover\:to-purple-200:hover{--gradient-to-color:#e9d8fd}.lg\:hover\:to-purple-300:hover{--gradient-to-color:#d6bcfa}.lg\:hover\:to-purple-400:hover{--gradient-to-color:#b794f4}.lg\:hover\:to-purple-500:hover{--gradient-to-color:#9f7aea}.lg\:hover\:to-purple-600:hover{--gradient-to-color:#805ad5}.lg\:hover\:to-purple-700:hover{--gradient-to-color:#6b46c1}.lg\:hover\:to-purple-800:hover{--gradient-to-color:#553c9a}.lg\:hover\:to-purple-900:hover{--gradient-to-color:#44337a}.lg\:hover\:to-pink-100:hover{--gradient-to-color:#fff5f7}.lg\:hover\:to-pink-200:hover{--gradient-to-color:#fed7e2}.lg\:hover\:to-pink-300:hover{--gradient-to-color:#fbb6ce}.lg\:hover\:to-pink-400:hover{--gradient-to-color:#f687b3}.lg\:hover\:to-pink-500:hover{--gradient-to-color:#ed64a6}.lg\:hover\:to-pink-600:hover{--gradient-to-color:#d53f8c}.lg\:hover\:to-pink-700:hover{--gradient-to-color:#b83280}.lg\:hover\:to-pink-800:hover{--gradient-to-color:#97266d}.lg\:hover\:to-pink-900:hover{--gradient-to-color:#702459}.lg\:focus\:from-transparent:focus{--gradient-from-color:transparent;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(0, 0, 0, 0))}.lg\:focus\:from-current:focus{--gradient-from-color:currentColor;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 255, 255, 0))}.lg\:focus\:from-black:focus{--gradient-from-color:#000;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(0, 0, 0, 0))}.lg\:focus\:from-white:focus{--gradient-from-color:#fff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 255, 255, 0))}.lg\:focus\:from-gray-100:focus{--gradient-from-color:#f7fafc;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(247, 250, 252, 0))}.lg\:focus\:from-gray-200:focus{--gradient-from-color:#edf2f7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(237, 242, 247, 0))}.lg\:focus\:from-gray-300:focus{--gradient-from-color:#e2e8f0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(226, 232, 240, 0))}.lg\:focus\:from-gray-400:focus{--gradient-from-color:#cbd5e0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(203, 213, 224, 0))}.lg\:focus\:from-gray-500:focus{--gradient-from-color:#a0aec0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(160, 174, 192, 0))}.lg\:focus\:from-gray-600:focus{--gradient-from-color:#718096;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(113, 128, 150, 0))}.lg\:focus\:from-gray-700:focus{--gradient-from-color:#4a5568;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(74, 85, 104, 0))}.lg\:focus\:from-gray-800:focus{--gradient-from-color:#2d3748;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(45, 55, 72, 0))}.lg\:focus\:from-gray-900:focus{--gradient-from-color:#1a202c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(26, 32, 44, 0))}.lg\:focus\:from-red-100:focus{--gradient-from-color:#fff5f5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 245, 245, 0))}.lg\:focus\:from-red-200:focus{--gradient-from-color:#fed7d7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(254, 215, 215, 0))}.lg\:focus\:from-red-300:focus{--gradient-from-color:#feb2b2;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(254, 178, 178, 0))}.lg\:focus\:from-red-400:focus{--gradient-from-color:#fc8181;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(252, 129, 129, 0))}.lg\:focus\:from-red-500:focus{--gradient-from-color:#f56565;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(245, 101, 101, 0))}.lg\:focus\:from-red-600:focus{--gradient-from-color:#e53e3e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(229, 62, 62, 0))}.lg\:focus\:from-red-700:focus{--gradient-from-color:#c53030;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(197, 48, 48, 0))}.lg\:focus\:from-red-800:focus{--gradient-from-color:#9b2c2c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(155, 44, 44, 0))}.lg\:focus\:from-red-900:focus{--gradient-from-color:#742a2a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(116, 42, 42, 0))}.lg\:focus\:from-orange-100:focus{--gradient-from-color:#fffaf0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 250, 240, 0))}.lg\:focus\:from-orange-200:focus{--gradient-from-color:#feebc8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(254, 235, 200, 0))}.lg\:focus\:from-orange-300:focus{--gradient-from-color:#fbd38d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(251, 211, 141, 0))}.lg\:focus\:from-orange-400:focus{--gradient-from-color:#f6ad55;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(246, 173, 85, 0))}.lg\:focus\:from-orange-500:focus{--gradient-from-color:#ed8936;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(237, 137, 54, 0))}.lg\:focus\:from-orange-600:focus{--gradient-from-color:#dd6b20;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(221, 107, 32, 0))}.lg\:focus\:from-orange-700:focus{--gradient-from-color:#c05621;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(192, 86, 33, 0))}.lg\:focus\:from-orange-800:focus{--gradient-from-color:#9c4221;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(156, 66, 33, 0))}.lg\:focus\:from-orange-900:focus{--gradient-from-color:#7b341e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(123, 52, 30, 0))}.lg\:focus\:from-yellow-100:focus{--gradient-from-color:#fffff0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 255, 240, 0))}.lg\:focus\:from-yellow-200:focus{--gradient-from-color:#fefcbf;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(254, 252, 191, 0))}.lg\:focus\:from-yellow-300:focus{--gradient-from-color:#faf089;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(250, 240, 137, 0))}.lg\:focus\:from-yellow-400:focus{--gradient-from-color:#f6e05e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(246, 224, 94, 0))}.lg\:focus\:from-yellow-500:focus{--gradient-from-color:#ecc94b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(236, 201, 75, 0))}.lg\:focus\:from-yellow-600:focus{--gradient-from-color:#d69e2e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(214, 158, 46, 0))}.lg\:focus\:from-yellow-700:focus{--gradient-from-color:#b7791f;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(183, 121, 31, 0))}.lg\:focus\:from-yellow-800:focus{--gradient-from-color:#975a16;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(151, 90, 22, 0))}.lg\:focus\:from-yellow-900:focus{--gradient-from-color:#744210;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(116, 66, 16, 0))}.lg\:focus\:from-green-100:focus{--gradient-from-color:#f0fff4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(240, 255, 244, 0))}.lg\:focus\:from-green-200:focus{--gradient-from-color:#c6f6d5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(198, 246, 213, 0))}.lg\:focus\:from-green-300:focus{--gradient-from-color:#9ae6b4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(154, 230, 180, 0))}.lg\:focus\:from-green-400:focus{--gradient-from-color:#68d391;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(104, 211, 145, 0))}.lg\:focus\:from-green-500:focus{--gradient-from-color:#48bb78;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(72, 187, 120, 0))}.lg\:focus\:from-green-600:focus{--gradient-from-color:#38a169;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(56, 161, 105, 0))}.lg\:focus\:from-green-700:focus{--gradient-from-color:#2f855a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(47, 133, 90, 0))}.lg\:focus\:from-green-800:focus{--gradient-from-color:#276749;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(39, 103, 73, 0))}.lg\:focus\:from-green-900:focus{--gradient-from-color:#22543d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(34, 84, 61, 0))}.lg\:focus\:from-teal-100:focus{--gradient-from-color:#e6fffa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(230, 255, 250, 0))}.lg\:focus\:from-teal-200:focus{--gradient-from-color:#b2f5ea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(178, 245, 234, 0))}.lg\:focus\:from-teal-300:focus{--gradient-from-color:#81e6d9;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(129, 230, 217, 0))}.lg\:focus\:from-teal-400:focus{--gradient-from-color:#4fd1c5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(79, 209, 197, 0))}.lg\:focus\:from-teal-500:focus{--gradient-from-color:#38b2ac;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(56, 178, 172, 0))}.lg\:focus\:from-teal-600:focus{--gradient-from-color:#319795;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(49, 151, 149, 0))}.lg\:focus\:from-teal-700:focus{--gradient-from-color:#2c7a7b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(44, 122, 123, 0))}.lg\:focus\:from-teal-800:focus{--gradient-from-color:#285e61;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(40, 94, 97, 0))}.lg\:focus\:from-teal-900:focus{--gradient-from-color:#234e52;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(35, 78, 82, 0))}.lg\:focus\:from-blue-100:focus{--gradient-from-color:#ebf8ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(235, 248, 255, 0))}.lg\:focus\:from-blue-200:focus{--gradient-from-color:#bee3f8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(190, 227, 248, 0))}.lg\:focus\:from-blue-300:focus{--gradient-from-color:#90cdf4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(144, 205, 244, 0))}.lg\:focus\:from-blue-400:focus{--gradient-from-color:#63b3ed;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(99, 179, 237, 0))}.lg\:focus\:from-blue-500:focus{--gradient-from-color:#4299e1;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(66, 153, 225, 0))}.lg\:focus\:from-blue-600:focus{--gradient-from-color:#3182ce;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(49, 130, 206, 0))}.lg\:focus\:from-blue-700:focus{--gradient-from-color:#2b6cb0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(43, 108, 176, 0))}.lg\:focus\:from-blue-800:focus{--gradient-from-color:#2c5282;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(44, 82, 130, 0))}.lg\:focus\:from-blue-900:focus{--gradient-from-color:#2a4365;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(42, 67, 101, 0))}.lg\:focus\:from-indigo-100:focus{--gradient-from-color:#ebf4ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(235, 244, 255, 0))}.lg\:focus\:from-indigo-200:focus{--gradient-from-color:#c3dafe;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(195, 218, 254, 0))}.lg\:focus\:from-indigo-300:focus{--gradient-from-color:#a3bffa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(163, 191, 250, 0))}.lg\:focus\:from-indigo-400:focus{--gradient-from-color:#7f9cf5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(127, 156, 245, 0))}.lg\:focus\:from-indigo-500:focus{--gradient-from-color:#667eea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(102, 126, 234, 0))}.lg\:focus\:from-indigo-600:focus{--gradient-from-color:#5a67d8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(90, 103, 216, 0))}.lg\:focus\:from-indigo-700:focus{--gradient-from-color:#4c51bf;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(76, 81, 191, 0))}.lg\:focus\:from-indigo-800:focus{--gradient-from-color:#434190;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(67, 65, 144, 0))}.lg\:focus\:from-indigo-900:focus{--gradient-from-color:#3c366b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(60, 54, 107, 0))}.lg\:focus\:from-purple-100:focus{--gradient-from-color:#faf5ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(250, 245, 255, 0))}.lg\:focus\:from-purple-200:focus{--gradient-from-color:#e9d8fd;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(233, 216, 253, 0))}.lg\:focus\:from-purple-300:focus{--gradient-from-color:#d6bcfa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(214, 188, 250, 0))}.lg\:focus\:from-purple-400:focus{--gradient-from-color:#b794f4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(183, 148, 244, 0))}.lg\:focus\:from-purple-500:focus{--gradient-from-color:#9f7aea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(159, 122, 234, 0))}.lg\:focus\:from-purple-600:focus{--gradient-from-color:#805ad5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(128, 90, 213, 0))}.lg\:focus\:from-purple-700:focus{--gradient-from-color:#6b46c1;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(107, 70, 193, 0))}.lg\:focus\:from-purple-800:focus{--gradient-from-color:#553c9a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(85, 60, 154, 0))}.lg\:focus\:from-purple-900:focus{--gradient-from-color:#44337a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(68, 51, 122, 0))}.lg\:focus\:from-pink-100:focus{--gradient-from-color:#fff5f7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 245, 247, 0))}.lg\:focus\:from-pink-200:focus{--gradient-from-color:#fed7e2;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(254, 215, 226, 0))}.lg\:focus\:from-pink-300:focus{--gradient-from-color:#fbb6ce;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(251, 182, 206, 0))}.lg\:focus\:from-pink-400:focus{--gradient-from-color:#f687b3;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(246, 135, 179, 0))}.lg\:focus\:from-pink-500:focus{--gradient-from-color:#ed64a6;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(237, 100, 166, 0))}.lg\:focus\:from-pink-600:focus{--gradient-from-color:#d53f8c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(213, 63, 140, 0))}.lg\:focus\:from-pink-700:focus{--gradient-from-color:#b83280;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(184, 50, 128, 0))}.lg\:focus\:from-pink-800:focus{--gradient-from-color:#97266d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(151, 38, 109, 0))}.lg\:focus\:from-pink-900:focus{--gradient-from-color:#702459;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(112, 36, 89, 0))}.lg\:focus\:via-transparent:focus{--gradient-via-color:transparent;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(0, 0, 0, 0))}.lg\:focus\:via-current:focus{--gradient-via-color:currentColor;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 255, 255, 0))}.lg\:focus\:via-black:focus{--gradient-via-color:#000;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(0, 0, 0, 0))}.lg\:focus\:via-white:focus{--gradient-via-color:#fff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 255, 255, 0))}.lg\:focus\:via-gray-100:focus{--gradient-via-color:#f7fafc;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(247, 250, 252, 0))}.lg\:focus\:via-gray-200:focus{--gradient-via-color:#edf2f7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(237, 242, 247, 0))}.lg\:focus\:via-gray-300:focus{--gradient-via-color:#e2e8f0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(226, 232, 240, 0))}.lg\:focus\:via-gray-400:focus{--gradient-via-color:#cbd5e0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(203, 213, 224, 0))}.lg\:focus\:via-gray-500:focus{--gradient-via-color:#a0aec0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(160, 174, 192, 0))}.lg\:focus\:via-gray-600:focus{--gradient-via-color:#718096;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(113, 128, 150, 0))}.lg\:focus\:via-gray-700:focus{--gradient-via-color:#4a5568;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(74, 85, 104, 0))}.lg\:focus\:via-gray-800:focus{--gradient-via-color:#2d3748;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(45, 55, 72, 0))}.lg\:focus\:via-gray-900:focus{--gradient-via-color:#1a202c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(26, 32, 44, 0))}.lg\:focus\:via-red-100:focus{--gradient-via-color:#fff5f5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 245, 245, 0))}.lg\:focus\:via-red-200:focus{--gradient-via-color:#fed7d7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(254, 215, 215, 0))}.lg\:focus\:via-red-300:focus{--gradient-via-color:#feb2b2;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(254, 178, 178, 0))}.lg\:focus\:via-red-400:focus{--gradient-via-color:#fc8181;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(252, 129, 129, 0))}.lg\:focus\:via-red-500:focus{--gradient-via-color:#f56565;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(245, 101, 101, 0))}.lg\:focus\:via-red-600:focus{--gradient-via-color:#e53e3e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(229, 62, 62, 0))}.lg\:focus\:via-red-700:focus{--gradient-via-color:#c53030;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(197, 48, 48, 0))}.lg\:focus\:via-red-800:focus{--gradient-via-color:#9b2c2c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(155, 44, 44, 0))}.lg\:focus\:via-red-900:focus{--gradient-via-color:#742a2a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(116, 42, 42, 0))}.lg\:focus\:via-orange-100:focus{--gradient-via-color:#fffaf0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 250, 240, 0))}.lg\:focus\:via-orange-200:focus{--gradient-via-color:#feebc8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(254, 235, 200, 0))}.lg\:focus\:via-orange-300:focus{--gradient-via-color:#fbd38d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(251, 211, 141, 0))}.lg\:focus\:via-orange-400:focus{--gradient-via-color:#f6ad55;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(246, 173, 85, 0))}.lg\:focus\:via-orange-500:focus{--gradient-via-color:#ed8936;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(237, 137, 54, 0))}.lg\:focus\:via-orange-600:focus{--gradient-via-color:#dd6b20;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(221, 107, 32, 0))}.lg\:focus\:via-orange-700:focus{--gradient-via-color:#c05621;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(192, 86, 33, 0))}.lg\:focus\:via-orange-800:focus{--gradient-via-color:#9c4221;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(156, 66, 33, 0))}.lg\:focus\:via-orange-900:focus{--gradient-via-color:#7b341e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(123, 52, 30, 0))}.lg\:focus\:via-yellow-100:focus{--gradient-via-color:#fffff0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 255, 240, 0))}.lg\:focus\:via-yellow-200:focus{--gradient-via-color:#fefcbf;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(254, 252, 191, 0))}.lg\:focus\:via-yellow-300:focus{--gradient-via-color:#faf089;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(250, 240, 137, 0))}.lg\:focus\:via-yellow-400:focus{--gradient-via-color:#f6e05e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(246, 224, 94, 0))}.lg\:focus\:via-yellow-500:focus{--gradient-via-color:#ecc94b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(236, 201, 75, 0))}.lg\:focus\:via-yellow-600:focus{--gradient-via-color:#d69e2e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(214, 158, 46, 0))}.lg\:focus\:via-yellow-700:focus{--gradient-via-color:#b7791f;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(183, 121, 31, 0))}.lg\:focus\:via-yellow-800:focus{--gradient-via-color:#975a16;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(151, 90, 22, 0))}.lg\:focus\:via-yellow-900:focus{--gradient-via-color:#744210;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(116, 66, 16, 0))}.lg\:focus\:via-green-100:focus{--gradient-via-color:#f0fff4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(240, 255, 244, 0))}.lg\:focus\:via-green-200:focus{--gradient-via-color:#c6f6d5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(198, 246, 213, 0))}.lg\:focus\:via-green-300:focus{--gradient-via-color:#9ae6b4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(154, 230, 180, 0))}.lg\:focus\:via-green-400:focus{--gradient-via-color:#68d391;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(104, 211, 145, 0))}.lg\:focus\:via-green-500:focus{--gradient-via-color:#48bb78;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(72, 187, 120, 0))}.lg\:focus\:via-green-600:focus{--gradient-via-color:#38a169;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(56, 161, 105, 0))}.lg\:focus\:via-green-700:focus{--gradient-via-color:#2f855a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(47, 133, 90, 0))}.lg\:focus\:via-green-800:focus{--gradient-via-color:#276749;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(39, 103, 73, 0))}.lg\:focus\:via-green-900:focus{--gradient-via-color:#22543d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(34, 84, 61, 0))}.lg\:focus\:via-teal-100:focus{--gradient-via-color:#e6fffa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(230, 255, 250, 0))}.lg\:focus\:via-teal-200:focus{--gradient-via-color:#b2f5ea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(178, 245, 234, 0))}.lg\:focus\:via-teal-300:focus{--gradient-via-color:#81e6d9;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(129, 230, 217, 0))}.lg\:focus\:via-teal-400:focus{--gradient-via-color:#4fd1c5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(79, 209, 197, 0))}.lg\:focus\:via-teal-500:focus{--gradient-via-color:#38b2ac;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(56, 178, 172, 0))}.lg\:focus\:via-teal-600:focus{--gradient-via-color:#319795;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(49, 151, 149, 0))}.lg\:focus\:via-teal-700:focus{--gradient-via-color:#2c7a7b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(44, 122, 123, 0))}.lg\:focus\:via-teal-800:focus{--gradient-via-color:#285e61;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(40, 94, 97, 0))}.lg\:focus\:via-teal-900:focus{--gradient-via-color:#234e52;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(35, 78, 82, 0))}.lg\:focus\:via-blue-100:focus{--gradient-via-color:#ebf8ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(235, 248, 255, 0))}.lg\:focus\:via-blue-200:focus{--gradient-via-color:#bee3f8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(190, 227, 248, 0))}.lg\:focus\:via-blue-300:focus{--gradient-via-color:#90cdf4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(144, 205, 244, 0))}.lg\:focus\:via-blue-400:focus{--gradient-via-color:#63b3ed;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(99, 179, 237, 0))}.lg\:focus\:via-blue-500:focus{--gradient-via-color:#4299e1;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(66, 153, 225, 0))}.lg\:focus\:via-blue-600:focus{--gradient-via-color:#3182ce;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(49, 130, 206, 0))}.lg\:focus\:via-blue-700:focus{--gradient-via-color:#2b6cb0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(43, 108, 176, 0))}.lg\:focus\:via-blue-800:focus{--gradient-via-color:#2c5282;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(44, 82, 130, 0))}.lg\:focus\:via-blue-900:focus{--gradient-via-color:#2a4365;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(42, 67, 101, 0))}.lg\:focus\:via-indigo-100:focus{--gradient-via-color:#ebf4ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(235, 244, 255, 0))}.lg\:focus\:via-indigo-200:focus{--gradient-via-color:#c3dafe;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(195, 218, 254, 0))}.lg\:focus\:via-indigo-300:focus{--gradient-via-color:#a3bffa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(163, 191, 250, 0))}.lg\:focus\:via-indigo-400:focus{--gradient-via-color:#7f9cf5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(127, 156, 245, 0))}.lg\:focus\:via-indigo-500:focus{--gradient-via-color:#667eea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(102, 126, 234, 0))}.lg\:focus\:via-indigo-600:focus{--gradient-via-color:#5a67d8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(90, 103, 216, 0))}.lg\:focus\:via-indigo-700:focus{--gradient-via-color:#4c51bf;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(76, 81, 191, 0))}.lg\:focus\:via-indigo-800:focus{--gradient-via-color:#434190;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(67, 65, 144, 0))}.lg\:focus\:via-indigo-900:focus{--gradient-via-color:#3c366b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(60, 54, 107, 0))}.lg\:focus\:via-purple-100:focus{--gradient-via-color:#faf5ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(250, 245, 255, 0))}.lg\:focus\:via-purple-200:focus{--gradient-via-color:#e9d8fd;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(233, 216, 253, 0))}.lg\:focus\:via-purple-300:focus{--gradient-via-color:#d6bcfa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(214, 188, 250, 0))}.lg\:focus\:via-purple-400:focus{--gradient-via-color:#b794f4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(183, 148, 244, 0))}.lg\:focus\:via-purple-500:focus{--gradient-via-color:#9f7aea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(159, 122, 234, 0))}.lg\:focus\:via-purple-600:focus{--gradient-via-color:#805ad5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(128, 90, 213, 0))}.lg\:focus\:via-purple-700:focus{--gradient-via-color:#6b46c1;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(107, 70, 193, 0))}.lg\:focus\:via-purple-800:focus{--gradient-via-color:#553c9a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(85, 60, 154, 0))}.lg\:focus\:via-purple-900:focus{--gradient-via-color:#44337a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(68, 51, 122, 0))}.lg\:focus\:via-pink-100:focus{--gradient-via-color:#fff5f7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 245, 247, 0))}.lg\:focus\:via-pink-200:focus{--gradient-via-color:#fed7e2;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(254, 215, 226, 0))}.lg\:focus\:via-pink-300:focus{--gradient-via-color:#fbb6ce;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(251, 182, 206, 0))}.lg\:focus\:via-pink-400:focus{--gradient-via-color:#f687b3;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(246, 135, 179, 0))}.lg\:focus\:via-pink-500:focus{--gradient-via-color:#ed64a6;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(237, 100, 166, 0))}.lg\:focus\:via-pink-600:focus{--gradient-via-color:#d53f8c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(213, 63, 140, 0))}.lg\:focus\:via-pink-700:focus{--gradient-via-color:#b83280;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(184, 50, 128, 0))}.lg\:focus\:via-pink-800:focus{--gradient-via-color:#97266d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(151, 38, 109, 0))}.lg\:focus\:via-pink-900:focus{--gradient-via-color:#702459;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(112, 36, 89, 0))}.lg\:focus\:to-transparent:focus{--gradient-to-color:transparent}.lg\:focus\:to-current:focus{--gradient-to-color:currentColor}.lg\:focus\:to-black:focus{--gradient-to-color:#000}.lg\:focus\:to-white:focus{--gradient-to-color:#fff}.lg\:focus\:to-gray-100:focus{--gradient-to-color:#f7fafc}.lg\:focus\:to-gray-200:focus{--gradient-to-color:#edf2f7}.lg\:focus\:to-gray-300:focus{--gradient-to-color:#e2e8f0}.lg\:focus\:to-gray-400:focus{--gradient-to-color:#cbd5e0}.lg\:focus\:to-gray-500:focus{--gradient-to-color:#a0aec0}.lg\:focus\:to-gray-600:focus{--gradient-to-color:#718096}.lg\:focus\:to-gray-700:focus{--gradient-to-color:#4a5568}.lg\:focus\:to-gray-800:focus{--gradient-to-color:#2d3748}.lg\:focus\:to-gray-900:focus{--gradient-to-color:#1a202c}.lg\:focus\:to-red-100:focus{--gradient-to-color:#fff5f5}.lg\:focus\:to-red-200:focus{--gradient-to-color:#fed7d7}.lg\:focus\:to-red-300:focus{--gradient-to-color:#feb2b2}.lg\:focus\:to-red-400:focus{--gradient-to-color:#fc8181}.lg\:focus\:to-red-500:focus{--gradient-to-color:#f56565}.lg\:focus\:to-red-600:focus{--gradient-to-color:#e53e3e}.lg\:focus\:to-red-700:focus{--gradient-to-color:#c53030}.lg\:focus\:to-red-800:focus{--gradient-to-color:#9b2c2c}.lg\:focus\:to-red-900:focus{--gradient-to-color:#742a2a}.lg\:focus\:to-orange-100:focus{--gradient-to-color:#fffaf0}.lg\:focus\:to-orange-200:focus{--gradient-to-color:#feebc8}.lg\:focus\:to-orange-300:focus{--gradient-to-color:#fbd38d}.lg\:focus\:to-orange-400:focus{--gradient-to-color:#f6ad55}.lg\:focus\:to-orange-500:focus{--gradient-to-color:#ed8936}.lg\:focus\:to-orange-600:focus{--gradient-to-color:#dd6b20}.lg\:focus\:to-orange-700:focus{--gradient-to-color:#c05621}.lg\:focus\:to-orange-800:focus{--gradient-to-color:#9c4221}.lg\:focus\:to-orange-900:focus{--gradient-to-color:#7b341e}.lg\:focus\:to-yellow-100:focus{--gradient-to-color:#fffff0}.lg\:focus\:to-yellow-200:focus{--gradient-to-color:#fefcbf}.lg\:focus\:to-yellow-300:focus{--gradient-to-color:#faf089}.lg\:focus\:to-yellow-400:focus{--gradient-to-color:#f6e05e}.lg\:focus\:to-yellow-500:focus{--gradient-to-color:#ecc94b}.lg\:focus\:to-yellow-600:focus{--gradient-to-color:#d69e2e}.lg\:focus\:to-yellow-700:focus{--gradient-to-color:#b7791f}.lg\:focus\:to-yellow-800:focus{--gradient-to-color:#975a16}.lg\:focus\:to-yellow-900:focus{--gradient-to-color:#744210}.lg\:focus\:to-green-100:focus{--gradient-to-color:#f0fff4}.lg\:focus\:to-green-200:focus{--gradient-to-color:#c6f6d5}.lg\:focus\:to-green-300:focus{--gradient-to-color:#9ae6b4}.lg\:focus\:to-green-400:focus{--gradient-to-color:#68d391}.lg\:focus\:to-green-500:focus{--gradient-to-color:#48bb78}.lg\:focus\:to-green-600:focus{--gradient-to-color:#38a169}.lg\:focus\:to-green-700:focus{--gradient-to-color:#2f855a}.lg\:focus\:to-green-800:focus{--gradient-to-color:#276749}.lg\:focus\:to-green-900:focus{--gradient-to-color:#22543d}.lg\:focus\:to-teal-100:focus{--gradient-to-color:#e6fffa}.lg\:focus\:to-teal-200:focus{--gradient-to-color:#b2f5ea}.lg\:focus\:to-teal-300:focus{--gradient-to-color:#81e6d9}.lg\:focus\:to-teal-400:focus{--gradient-to-color:#4fd1c5}.lg\:focus\:to-teal-500:focus{--gradient-to-color:#38b2ac}.lg\:focus\:to-teal-600:focus{--gradient-to-color:#319795}.lg\:focus\:to-teal-700:focus{--gradient-to-color:#2c7a7b}.lg\:focus\:to-teal-800:focus{--gradient-to-color:#285e61}.lg\:focus\:to-teal-900:focus{--gradient-to-color:#234e52}.lg\:focus\:to-blue-100:focus{--gradient-to-color:#ebf8ff}.lg\:focus\:to-blue-200:focus{--gradient-to-color:#bee3f8}.lg\:focus\:to-blue-300:focus{--gradient-to-color:#90cdf4}.lg\:focus\:to-blue-400:focus{--gradient-to-color:#63b3ed}.lg\:focus\:to-blue-500:focus{--gradient-to-color:#4299e1}.lg\:focus\:to-blue-600:focus{--gradient-to-color:#3182ce}.lg\:focus\:to-blue-700:focus{--gradient-to-color:#2b6cb0}.lg\:focus\:to-blue-800:focus{--gradient-to-color:#2c5282}.lg\:focus\:to-blue-900:focus{--gradient-to-color:#2a4365}.lg\:focus\:to-indigo-100:focus{--gradient-to-color:#ebf4ff}.lg\:focus\:to-indigo-200:focus{--gradient-to-color:#c3dafe}.lg\:focus\:to-indigo-300:focus{--gradient-to-color:#a3bffa}.lg\:focus\:to-indigo-400:focus{--gradient-to-color:#7f9cf5}.lg\:focus\:to-indigo-500:focus{--gradient-to-color:#667eea}.lg\:focus\:to-indigo-600:focus{--gradient-to-color:#5a67d8}.lg\:focus\:to-indigo-700:focus{--gradient-to-color:#4c51bf}.lg\:focus\:to-indigo-800:focus{--gradient-to-color:#434190}.lg\:focus\:to-indigo-900:focus{--gradient-to-color:#3c366b}.lg\:focus\:to-purple-100:focus{--gradient-to-color:#faf5ff}.lg\:focus\:to-purple-200:focus{--gradient-to-color:#e9d8fd}.lg\:focus\:to-purple-300:focus{--gradient-to-color:#d6bcfa}.lg\:focus\:to-purple-400:focus{--gradient-to-color:#b794f4}.lg\:focus\:to-purple-500:focus{--gradient-to-color:#9f7aea}.lg\:focus\:to-purple-600:focus{--gradient-to-color:#805ad5}.lg\:focus\:to-purple-700:focus{--gradient-to-color:#6b46c1}.lg\:focus\:to-purple-800:focus{--gradient-to-color:#553c9a}.lg\:focus\:to-purple-900:focus{--gradient-to-color:#44337a}.lg\:focus\:to-pink-100:focus{--gradient-to-color:#fff5f7}.lg\:focus\:to-pink-200:focus{--gradient-to-color:#fed7e2}.lg\:focus\:to-pink-300:focus{--gradient-to-color:#fbb6ce}.lg\:focus\:to-pink-400:focus{--gradient-to-color:#f687b3}.lg\:focus\:to-pink-500:focus{--gradient-to-color:#ed64a6}.lg\:focus\:to-pink-600:focus{--gradient-to-color:#d53f8c}.lg\:focus\:to-pink-700:focus{--gradient-to-color:#b83280}.lg\:focus\:to-pink-800:focus{--gradient-to-color:#97266d}.lg\:focus\:to-pink-900:focus{--gradient-to-color:#702459}.lg\:bg-opacity-0{--bg-opacity:0}.lg\:bg-opacity-25{--bg-opacity:0.25}.lg\:bg-opacity-50{--bg-opacity:0.5}.lg\:bg-opacity-75{--bg-opacity:0.75}.lg\:bg-opacity-100{--bg-opacity:1}.lg\:hover\:bg-opacity-0:hover{--bg-opacity:0}.lg\:hover\:bg-opacity-25:hover{--bg-opacity:0.25}.lg\:hover\:bg-opacity-50:hover{--bg-opacity:0.5}.lg\:hover\:bg-opacity-75:hover{--bg-opacity:0.75}.lg\:hover\:bg-opacity-100:hover{--bg-opacity:1}.lg\:focus\:bg-opacity-0:focus{--bg-opacity:0}.lg\:focus\:bg-opacity-25:focus{--bg-opacity:0.25}.lg\:focus\:bg-opacity-50:focus{--bg-opacity:0.5}.lg\:focus\:bg-opacity-75:focus{--bg-opacity:0.75}.lg\:focus\:bg-opacity-100:focus{--bg-opacity:1}.lg\:bg-bottom{background-position:bottom}.lg\:bg-center{background-position:center}.lg\:bg-left{background-position:left}.lg\:bg-left-bottom{background-position:left bottom}.lg\:bg-left-top{background-position:left top}.lg\:bg-right{background-position:right}.lg\:bg-right-bottom{background-position:right bottom}.lg\:bg-right-top{background-position:right top}.lg\:bg-top{background-position:top}.lg\:bg-repeat{background-repeat:repeat}.lg\:bg-no-repeat{background-repeat:no-repeat}.lg\:bg-repeat-x{background-repeat:repeat-x}.lg\:bg-repeat-y{background-repeat:repeat-y}.lg\:bg-repeat-round{background-repeat:round}.lg\:bg-repeat-space{background-repeat:space}.lg\:bg-auto{background-size:auto}.lg\:bg-cover{background-size:cover}.lg\:bg-contain{background-size:contain}.lg\:border-collapse{border-collapse:collapse}.lg\:border-separate{border-collapse:separate}.lg\:border-transparent{border-color:transparent}.lg\:border-current{border-color:currentColor}.lg\:border-black{--border-opacity:1;border-color:#000;border-color:rgba(0,0,0,var(--border-opacity))}.lg\:border-white{--border-opacity:1;border-color:#fff;border-color:rgba(255,255,255,var(--border-opacity))}.lg\:border-gray-100{--border-opacity:1;border-color:#f7fafc;border-color:rgba(247,250,252,var(--border-opacity))}.lg\:border-gray-200{--border-opacity:1;border-color:#edf2f7;border-color:rgba(237,242,247,var(--border-opacity))}.lg\:border-gray-300{--border-opacity:1;border-color:#e2e8f0;border-color:rgba(226,232,240,var(--border-opacity))}.lg\:border-gray-400{--border-opacity:1;border-color:#cbd5e0;border-color:rgba(203,213,224,var(--border-opacity))}.lg\:border-gray-500{--border-opacity:1;border-color:#a0aec0;border-color:rgba(160,174,192,var(--border-opacity))}.lg\:border-gray-600{--border-opacity:1;border-color:#718096;border-color:rgba(113,128,150,var(--border-opacity))}.lg\:border-gray-700{--border-opacity:1;border-color:#4a5568;border-color:rgba(74,85,104,var(--border-opacity))}.lg\:border-gray-800{--border-opacity:1;border-color:#2d3748;border-color:rgba(45,55,72,var(--border-opacity))}.lg\:border-gray-900{--border-opacity:1;border-color:#1a202c;border-color:rgba(26,32,44,var(--border-opacity))}.lg\:border-red-100{--border-opacity:1;border-color:#fff5f5;border-color:rgba(255,245,245,var(--border-opacity))}.lg\:border-red-200{--border-opacity:1;border-color:#fed7d7;border-color:rgba(254,215,215,var(--border-opacity))}.lg\:border-red-300{--border-opacity:1;border-color:#feb2b2;border-color:rgba(254,178,178,var(--border-opacity))}.lg\:border-red-400{--border-opacity:1;border-color:#fc8181;border-color:rgba(252,129,129,var(--border-opacity))}.lg\:border-red-500{--border-opacity:1;border-color:#f56565;border-color:rgba(245,101,101,var(--border-opacity))}.lg\:border-red-600{--border-opacity:1;border-color:#e53e3e;border-color:rgba(229,62,62,var(--border-opacity))}.lg\:border-red-700{--border-opacity:1;border-color:#c53030;border-color:rgba(197,48,48,var(--border-opacity))}.lg\:border-red-800{--border-opacity:1;border-color:#9b2c2c;border-color:rgba(155,44,44,var(--border-opacity))}.lg\:border-red-900{--border-opacity:1;border-color:#742a2a;border-color:rgba(116,42,42,var(--border-opacity))}.lg\:border-orange-100{--border-opacity:1;border-color:#fffaf0;border-color:rgba(255,250,240,var(--border-opacity))}.lg\:border-orange-200{--border-opacity:1;border-color:#feebc8;border-color:rgba(254,235,200,var(--border-opacity))}.lg\:border-orange-300{--border-opacity:1;border-color:#fbd38d;border-color:rgba(251,211,141,var(--border-opacity))}.lg\:border-orange-400{--border-opacity:1;border-color:#f6ad55;border-color:rgba(246,173,85,var(--border-opacity))}.lg\:border-orange-500{--border-opacity:1;border-color:#ed8936;border-color:rgba(237,137,54,var(--border-opacity))}.lg\:border-orange-600{--border-opacity:1;border-color:#dd6b20;border-color:rgba(221,107,32,var(--border-opacity))}.lg\:border-orange-700{--border-opacity:1;border-color:#c05621;border-color:rgba(192,86,33,var(--border-opacity))}.lg\:border-orange-800{--border-opacity:1;border-color:#9c4221;border-color:rgba(156,66,33,var(--border-opacity))}.lg\:border-orange-900{--border-opacity:1;border-color:#7b341e;border-color:rgba(123,52,30,var(--border-opacity))}.lg\:border-yellow-100{--border-opacity:1;border-color:ivory;border-color:rgba(255,255,240,var(--border-opacity))}.lg\:border-yellow-200{--border-opacity:1;border-color:#fefcbf;border-color:rgba(254,252,191,var(--border-opacity))}.lg\:border-yellow-300{--border-opacity:1;border-color:#faf089;border-color:rgba(250,240,137,var(--border-opacity))}.lg\:border-yellow-400{--border-opacity:1;border-color:#f6e05e;border-color:rgba(246,224,94,var(--border-opacity))}.lg\:border-yellow-500{--border-opacity:1;border-color:#ecc94b;border-color:rgba(236,201,75,var(--border-opacity))}.lg\:border-yellow-600{--border-opacity:1;border-color:#d69e2e;border-color:rgba(214,158,46,var(--border-opacity))}.lg\:border-yellow-700{--border-opacity:1;border-color:#b7791f;border-color:rgba(183,121,31,var(--border-opacity))}.lg\:border-yellow-800{--border-opacity:1;border-color:#975a16;border-color:rgba(151,90,22,var(--border-opacity))}.lg\:border-yellow-900{--border-opacity:1;border-color:#744210;border-color:rgba(116,66,16,var(--border-opacity))}.lg\:border-green-100{--border-opacity:1;border-color:#f0fff4;border-color:rgba(240,255,244,var(--border-opacity))}.lg\:border-green-200{--border-opacity:1;border-color:#c6f6d5;border-color:rgba(198,246,213,var(--border-opacity))}.lg\:border-green-300{--border-opacity:1;border-color:#9ae6b4;border-color:rgba(154,230,180,var(--border-opacity))}.lg\:border-green-400{--border-opacity:1;border-color:#68d391;border-color:rgba(104,211,145,var(--border-opacity))}.lg\:border-green-500{--border-opacity:1;border-color:#48bb78;border-color:rgba(72,187,120,var(--border-opacity))}.lg\:border-green-600{--border-opacity:1;border-color:#38a169;border-color:rgba(56,161,105,var(--border-opacity))}.lg\:border-green-700{--border-opacity:1;border-color:#2f855a;border-color:rgba(47,133,90,var(--border-opacity))}.lg\:border-green-800{--border-opacity:1;border-color:#276749;border-color:rgba(39,103,73,var(--border-opacity))}.lg\:border-green-900{--border-opacity:1;border-color:#22543d;border-color:rgba(34,84,61,var(--border-opacity))}.lg\:border-teal-100{--border-opacity:1;border-color:#e6fffa;border-color:rgba(230,255,250,var(--border-opacity))}.lg\:border-teal-200{--border-opacity:1;border-color:#b2f5ea;border-color:rgba(178,245,234,var(--border-opacity))}.lg\:border-teal-300{--border-opacity:1;border-color:#81e6d9;border-color:rgba(129,230,217,var(--border-opacity))}.lg\:border-teal-400{--border-opacity:1;border-color:#4fd1c5;border-color:rgba(79,209,197,var(--border-opacity))}.lg\:border-teal-500{--border-opacity:1;border-color:#38b2ac;border-color:rgba(56,178,172,var(--border-opacity))}.lg\:border-teal-600{--border-opacity:1;border-color:#319795;border-color:rgba(49,151,149,var(--border-opacity))}.lg\:border-teal-700{--border-opacity:1;border-color:#2c7a7b;border-color:rgba(44,122,123,var(--border-opacity))}.lg\:border-teal-800{--border-opacity:1;border-color:#285e61;border-color:rgba(40,94,97,var(--border-opacity))}.lg\:border-teal-900{--border-opacity:1;border-color:#234e52;border-color:rgba(35,78,82,var(--border-opacity))}.lg\:border-blue-100{--border-opacity:1;border-color:#ebf8ff;border-color:rgba(235,248,255,var(--border-opacity))}.lg\:border-blue-200{--border-opacity:1;border-color:#bee3f8;border-color:rgba(190,227,248,var(--border-opacity))}.lg\:border-blue-300{--border-opacity:1;border-color:#90cdf4;border-color:rgba(144,205,244,var(--border-opacity))}.lg\:border-blue-400{--border-opacity:1;border-color:#63b3ed;border-color:rgba(99,179,237,var(--border-opacity))}.lg\:border-blue-500{--border-opacity:1;border-color:#4299e1;border-color:rgba(66,153,225,var(--border-opacity))}.lg\:border-blue-600{--border-opacity:1;border-color:#3182ce;border-color:rgba(49,130,206,var(--border-opacity))}.lg\:border-blue-700{--border-opacity:1;border-color:#2b6cb0;border-color:rgba(43,108,176,var(--border-opacity))}.lg\:border-blue-800{--border-opacity:1;border-color:#2c5282;border-color:rgba(44,82,130,var(--border-opacity))}.lg\:border-blue-900{--border-opacity:1;border-color:#2a4365;border-color:rgba(42,67,101,var(--border-opacity))}.lg\:border-indigo-100{--border-opacity:1;border-color:#ebf4ff;border-color:rgba(235,244,255,var(--border-opacity))}.lg\:border-indigo-200{--border-opacity:1;border-color:#c3dafe;border-color:rgba(195,218,254,var(--border-opacity))}.lg\:border-indigo-300{--border-opacity:1;border-color:#a3bffa;border-color:rgba(163,191,250,var(--border-opacity))}.lg\:border-indigo-400{--border-opacity:1;border-color:#7f9cf5;border-color:rgba(127,156,245,var(--border-opacity))}.lg\:border-indigo-500{--border-opacity:1;border-color:#667eea;border-color:rgba(102,126,234,var(--border-opacity))}.lg\:border-indigo-600{--border-opacity:1;border-color:#5a67d8;border-color:rgba(90,103,216,var(--border-opacity))}.lg\:border-indigo-700{--border-opacity:1;border-color:#4c51bf;border-color:rgba(76,81,191,var(--border-opacity))}.lg\:border-indigo-800{--border-opacity:1;border-color:#434190;border-color:rgba(67,65,144,var(--border-opacity))}.lg\:border-indigo-900{--border-opacity:1;border-color:#3c366b;border-color:rgba(60,54,107,var(--border-opacity))}.lg\:border-purple-100{--border-opacity:1;border-color:#faf5ff;border-color:rgba(250,245,255,var(--border-opacity))}.lg\:border-purple-200{--border-opacity:1;border-color:#e9d8fd;border-color:rgba(233,216,253,var(--border-opacity))}.lg\:border-purple-300{--border-opacity:1;border-color:#d6bcfa;border-color:rgba(214,188,250,var(--border-opacity))}.lg\:border-purple-400{--border-opacity:1;border-color:#b794f4;border-color:rgba(183,148,244,var(--border-opacity))}.lg\:border-purple-500{--border-opacity:1;border-color:#9f7aea;border-color:rgba(159,122,234,var(--border-opacity))}.lg\:border-purple-600{--border-opacity:1;border-color:#805ad5;border-color:rgba(128,90,213,var(--border-opacity))}.lg\:border-purple-700{--border-opacity:1;border-color:#6b46c1;border-color:rgba(107,70,193,var(--border-opacity))}.lg\:border-purple-800{--border-opacity:1;border-color:#553c9a;border-color:rgba(85,60,154,var(--border-opacity))}.lg\:border-purple-900{--border-opacity:1;border-color:#44337a;border-color:rgba(68,51,122,var(--border-opacity))}.lg\:border-pink-100{--border-opacity:1;border-color:#fff5f7;border-color:rgba(255,245,247,var(--border-opacity))}.lg\:border-pink-200{--border-opacity:1;border-color:#fed7e2;border-color:rgba(254,215,226,var(--border-opacity))}.lg\:border-pink-300{--border-opacity:1;border-color:#fbb6ce;border-color:rgba(251,182,206,var(--border-opacity))}.lg\:border-pink-400{--border-opacity:1;border-color:#f687b3;border-color:rgba(246,135,179,var(--border-opacity))}.lg\:border-pink-500{--border-opacity:1;border-color:#ed64a6;border-color:rgba(237,100,166,var(--border-opacity))}.lg\:border-pink-600{--border-opacity:1;border-color:#d53f8c;border-color:rgba(213,63,140,var(--border-opacity))}.lg\:border-pink-700{--border-opacity:1;border-color:#b83280;border-color:rgba(184,50,128,var(--border-opacity))}.lg\:border-pink-800{--border-opacity:1;border-color:#97266d;border-color:rgba(151,38,109,var(--border-opacity))}.lg\:border-pink-900{--border-opacity:1;border-color:#702459;border-color:rgba(112,36,89,var(--border-opacity))}.lg\:hover\:border-transparent:hover{border-color:transparent}.lg\:hover\:border-current:hover{border-color:currentColor}.lg\:hover\:border-black:hover{--border-opacity:1;border-color:#000;border-color:rgba(0,0,0,var(--border-opacity))}.lg\:hover\:border-white:hover{--border-opacity:1;border-color:#fff;border-color:rgba(255,255,255,var(--border-opacity))}.lg\:hover\:border-gray-100:hover{--border-opacity:1;border-color:#f7fafc;border-color:rgba(247,250,252,var(--border-opacity))}.lg\:hover\:border-gray-200:hover{--border-opacity:1;border-color:#edf2f7;border-color:rgba(237,242,247,var(--border-opacity))}.lg\:hover\:border-gray-300:hover{--border-opacity:1;border-color:#e2e8f0;border-color:rgba(226,232,240,var(--border-opacity))}.lg\:hover\:border-gray-400:hover{--border-opacity:1;border-color:#cbd5e0;border-color:rgba(203,213,224,var(--border-opacity))}.lg\:hover\:border-gray-500:hover{--border-opacity:1;border-color:#a0aec0;border-color:rgba(160,174,192,var(--border-opacity))}.lg\:hover\:border-gray-600:hover{--border-opacity:1;border-color:#718096;border-color:rgba(113,128,150,var(--border-opacity))}.lg\:hover\:border-gray-700:hover{--border-opacity:1;border-color:#4a5568;border-color:rgba(74,85,104,var(--border-opacity))}.lg\:hover\:border-gray-800:hover{--border-opacity:1;border-color:#2d3748;border-color:rgba(45,55,72,var(--border-opacity))}.lg\:hover\:border-gray-900:hover{--border-opacity:1;border-color:#1a202c;border-color:rgba(26,32,44,var(--border-opacity))}.lg\:hover\:border-red-100:hover{--border-opacity:1;border-color:#fff5f5;border-color:rgba(255,245,245,var(--border-opacity))}.lg\:hover\:border-red-200:hover{--border-opacity:1;border-color:#fed7d7;border-color:rgba(254,215,215,var(--border-opacity))}.lg\:hover\:border-red-300:hover{--border-opacity:1;border-color:#feb2b2;border-color:rgba(254,178,178,var(--border-opacity))}.lg\:hover\:border-red-400:hover{--border-opacity:1;border-color:#fc8181;border-color:rgba(252,129,129,var(--border-opacity))}.lg\:hover\:border-red-500:hover{--border-opacity:1;border-color:#f56565;border-color:rgba(245,101,101,var(--border-opacity))}.lg\:hover\:border-red-600:hover{--border-opacity:1;border-color:#e53e3e;border-color:rgba(229,62,62,var(--border-opacity))}.lg\:hover\:border-red-700:hover{--border-opacity:1;border-color:#c53030;border-color:rgba(197,48,48,var(--border-opacity))}.lg\:hover\:border-red-800:hover{--border-opacity:1;border-color:#9b2c2c;border-color:rgba(155,44,44,var(--border-opacity))}.lg\:hover\:border-red-900:hover{--border-opacity:1;border-color:#742a2a;border-color:rgba(116,42,42,var(--border-opacity))}.lg\:hover\:border-orange-100:hover{--border-opacity:1;border-color:#fffaf0;border-color:rgba(255,250,240,var(--border-opacity))}.lg\:hover\:border-orange-200:hover{--border-opacity:1;border-color:#feebc8;border-color:rgba(254,235,200,var(--border-opacity))}.lg\:hover\:border-orange-300:hover{--border-opacity:1;border-color:#fbd38d;border-color:rgba(251,211,141,var(--border-opacity))}.lg\:hover\:border-orange-400:hover{--border-opacity:1;border-color:#f6ad55;border-color:rgba(246,173,85,var(--border-opacity))}.lg\:hover\:border-orange-500:hover{--border-opacity:1;border-color:#ed8936;border-color:rgba(237,137,54,var(--border-opacity))}.lg\:hover\:border-orange-600:hover{--border-opacity:1;border-color:#dd6b20;border-color:rgba(221,107,32,var(--border-opacity))}.lg\:hover\:border-orange-700:hover{--border-opacity:1;border-color:#c05621;border-color:rgba(192,86,33,var(--border-opacity))}.lg\:hover\:border-orange-800:hover{--border-opacity:1;border-color:#9c4221;border-color:rgba(156,66,33,var(--border-opacity))}.lg\:hover\:border-orange-900:hover{--border-opacity:1;border-color:#7b341e;border-color:rgba(123,52,30,var(--border-opacity))}.lg\:hover\:border-yellow-100:hover{--border-opacity:1;border-color:ivory;border-color:rgba(255,255,240,var(--border-opacity))}.lg\:hover\:border-yellow-200:hover{--border-opacity:1;border-color:#fefcbf;border-color:rgba(254,252,191,var(--border-opacity))}.lg\:hover\:border-yellow-300:hover{--border-opacity:1;border-color:#faf089;border-color:rgba(250,240,137,var(--border-opacity))}.lg\:hover\:border-yellow-400:hover{--border-opacity:1;border-color:#f6e05e;border-color:rgba(246,224,94,var(--border-opacity))}.lg\:hover\:border-yellow-500:hover{--border-opacity:1;border-color:#ecc94b;border-color:rgba(236,201,75,var(--border-opacity))}.lg\:hover\:border-yellow-600:hover{--border-opacity:1;border-color:#d69e2e;border-color:rgba(214,158,46,var(--border-opacity))}.lg\:hover\:border-yellow-700:hover{--border-opacity:1;border-color:#b7791f;border-color:rgba(183,121,31,var(--border-opacity))}.lg\:hover\:border-yellow-800:hover{--border-opacity:1;border-color:#975a16;border-color:rgba(151,90,22,var(--border-opacity))}.lg\:hover\:border-yellow-900:hover{--border-opacity:1;border-color:#744210;border-color:rgba(116,66,16,var(--border-opacity))}.lg\:hover\:border-green-100:hover{--border-opacity:1;border-color:#f0fff4;border-color:rgba(240,255,244,var(--border-opacity))}.lg\:hover\:border-green-200:hover{--border-opacity:1;border-color:#c6f6d5;border-color:rgba(198,246,213,var(--border-opacity))}.lg\:hover\:border-green-300:hover{--border-opacity:1;border-color:#9ae6b4;border-color:rgba(154,230,180,var(--border-opacity))}.lg\:hover\:border-green-400:hover{--border-opacity:1;border-color:#68d391;border-color:rgba(104,211,145,var(--border-opacity))}.lg\:hover\:border-green-500:hover{--border-opacity:1;border-color:#48bb78;border-color:rgba(72,187,120,var(--border-opacity))}.lg\:hover\:border-green-600:hover{--border-opacity:1;border-color:#38a169;border-color:rgba(56,161,105,var(--border-opacity))}.lg\:hover\:border-green-700:hover{--border-opacity:1;border-color:#2f855a;border-color:rgba(47,133,90,var(--border-opacity))}.lg\:hover\:border-green-800:hover{--border-opacity:1;border-color:#276749;border-color:rgba(39,103,73,var(--border-opacity))}.lg\:hover\:border-green-900:hover{--border-opacity:1;border-color:#22543d;border-color:rgba(34,84,61,var(--border-opacity))}.lg\:hover\:border-teal-100:hover{--border-opacity:1;border-color:#e6fffa;border-color:rgba(230,255,250,var(--border-opacity))}.lg\:hover\:border-teal-200:hover{--border-opacity:1;border-color:#b2f5ea;border-color:rgba(178,245,234,var(--border-opacity))}.lg\:hover\:border-teal-300:hover{--border-opacity:1;border-color:#81e6d9;border-color:rgba(129,230,217,var(--border-opacity))}.lg\:hover\:border-teal-400:hover{--border-opacity:1;border-color:#4fd1c5;border-color:rgba(79,209,197,var(--border-opacity))}.lg\:hover\:border-teal-500:hover{--border-opacity:1;border-color:#38b2ac;border-color:rgba(56,178,172,var(--border-opacity))}.lg\:hover\:border-teal-600:hover{--border-opacity:1;border-color:#319795;border-color:rgba(49,151,149,var(--border-opacity))}.lg\:hover\:border-teal-700:hover{--border-opacity:1;border-color:#2c7a7b;border-color:rgba(44,122,123,var(--border-opacity))}.lg\:hover\:border-teal-800:hover{--border-opacity:1;border-color:#285e61;border-color:rgba(40,94,97,var(--border-opacity))}.lg\:hover\:border-teal-900:hover{--border-opacity:1;border-color:#234e52;border-color:rgba(35,78,82,var(--border-opacity))}.lg\:hover\:border-blue-100:hover{--border-opacity:1;border-color:#ebf8ff;border-color:rgba(235,248,255,var(--border-opacity))}.lg\:hover\:border-blue-200:hover{--border-opacity:1;border-color:#bee3f8;border-color:rgba(190,227,248,var(--border-opacity))}.lg\:hover\:border-blue-300:hover{--border-opacity:1;border-color:#90cdf4;border-color:rgba(144,205,244,var(--border-opacity))}.lg\:hover\:border-blue-400:hover{--border-opacity:1;border-color:#63b3ed;border-color:rgba(99,179,237,var(--border-opacity))}.lg\:hover\:border-blue-500:hover{--border-opacity:1;border-color:#4299e1;border-color:rgba(66,153,225,var(--border-opacity))}.lg\:hover\:border-blue-600:hover{--border-opacity:1;border-color:#3182ce;border-color:rgba(49,130,206,var(--border-opacity))}.lg\:hover\:border-blue-700:hover{--border-opacity:1;border-color:#2b6cb0;border-color:rgba(43,108,176,var(--border-opacity))}.lg\:hover\:border-blue-800:hover{--border-opacity:1;border-color:#2c5282;border-color:rgba(44,82,130,var(--border-opacity))}.lg\:hover\:border-blue-900:hover{--border-opacity:1;border-color:#2a4365;border-color:rgba(42,67,101,var(--border-opacity))}.lg\:hover\:border-indigo-100:hover{--border-opacity:1;border-color:#ebf4ff;border-color:rgba(235,244,255,var(--border-opacity))}.lg\:hover\:border-indigo-200:hover{--border-opacity:1;border-color:#c3dafe;border-color:rgba(195,218,254,var(--border-opacity))}.lg\:hover\:border-indigo-300:hover{--border-opacity:1;border-color:#a3bffa;border-color:rgba(163,191,250,var(--border-opacity))}.lg\:hover\:border-indigo-400:hover{--border-opacity:1;border-color:#7f9cf5;border-color:rgba(127,156,245,var(--border-opacity))}.lg\:hover\:border-indigo-500:hover{--border-opacity:1;border-color:#667eea;border-color:rgba(102,126,234,var(--border-opacity))}.lg\:hover\:border-indigo-600:hover{--border-opacity:1;border-color:#5a67d8;border-color:rgba(90,103,216,var(--border-opacity))}.lg\:hover\:border-indigo-700:hover{--border-opacity:1;border-color:#4c51bf;border-color:rgba(76,81,191,var(--border-opacity))}.lg\:hover\:border-indigo-800:hover{--border-opacity:1;border-color:#434190;border-color:rgba(67,65,144,var(--border-opacity))}.lg\:hover\:border-indigo-900:hover{--border-opacity:1;border-color:#3c366b;border-color:rgba(60,54,107,var(--border-opacity))}.lg\:hover\:border-purple-100:hover{--border-opacity:1;border-color:#faf5ff;border-color:rgba(250,245,255,var(--border-opacity))}.lg\:hover\:border-purple-200:hover{--border-opacity:1;border-color:#e9d8fd;border-color:rgba(233,216,253,var(--border-opacity))}.lg\:hover\:border-purple-300:hover{--border-opacity:1;border-color:#d6bcfa;border-color:rgba(214,188,250,var(--border-opacity))}.lg\:hover\:border-purple-400:hover{--border-opacity:1;border-color:#b794f4;border-color:rgba(183,148,244,var(--border-opacity))}.lg\:hover\:border-purple-500:hover{--border-opacity:1;border-color:#9f7aea;border-color:rgba(159,122,234,var(--border-opacity))}.lg\:hover\:border-purple-600:hover{--border-opacity:1;border-color:#805ad5;border-color:rgba(128,90,213,var(--border-opacity))}.lg\:hover\:border-purple-700:hover{--border-opacity:1;border-color:#6b46c1;border-color:rgba(107,70,193,var(--border-opacity))}.lg\:hover\:border-purple-800:hover{--border-opacity:1;border-color:#553c9a;border-color:rgba(85,60,154,var(--border-opacity))}.lg\:hover\:border-purple-900:hover{--border-opacity:1;border-color:#44337a;border-color:rgba(68,51,122,var(--border-opacity))}.lg\:hover\:border-pink-100:hover{--border-opacity:1;border-color:#fff5f7;border-color:rgba(255,245,247,var(--border-opacity))}.lg\:hover\:border-pink-200:hover{--border-opacity:1;border-color:#fed7e2;border-color:rgba(254,215,226,var(--border-opacity))}.lg\:hover\:border-pink-300:hover{--border-opacity:1;border-color:#fbb6ce;border-color:rgba(251,182,206,var(--border-opacity))}.lg\:hover\:border-pink-400:hover{--border-opacity:1;border-color:#f687b3;border-color:rgba(246,135,179,var(--border-opacity))}.lg\:hover\:border-pink-500:hover{--border-opacity:1;border-color:#ed64a6;border-color:rgba(237,100,166,var(--border-opacity))}.lg\:hover\:border-pink-600:hover{--border-opacity:1;border-color:#d53f8c;border-color:rgba(213,63,140,var(--border-opacity))}.lg\:hover\:border-pink-700:hover{--border-opacity:1;border-color:#b83280;border-color:rgba(184,50,128,var(--border-opacity))}.lg\:hover\:border-pink-800:hover{--border-opacity:1;border-color:#97266d;border-color:rgba(151,38,109,var(--border-opacity))}.lg\:hover\:border-pink-900:hover{--border-opacity:1;border-color:#702459;border-color:rgba(112,36,89,var(--border-opacity))}.lg\:focus\:border-transparent:focus{border-color:transparent}.lg\:focus\:border-current:focus{border-color:currentColor}.lg\:focus\:border-black:focus{--border-opacity:1;border-color:#000;border-color:rgba(0,0,0,var(--border-opacity))}.lg\:focus\:border-white:focus{--border-opacity:1;border-color:#fff;border-color:rgba(255,255,255,var(--border-opacity))}.lg\:focus\:border-gray-100:focus{--border-opacity:1;border-color:#f7fafc;border-color:rgba(247,250,252,var(--border-opacity))}.lg\:focus\:border-gray-200:focus{--border-opacity:1;border-color:#edf2f7;border-color:rgba(237,242,247,var(--border-opacity))}.lg\:focus\:border-gray-300:focus{--border-opacity:1;border-color:#e2e8f0;border-color:rgba(226,232,240,var(--border-opacity))}.lg\:focus\:border-gray-400:focus{--border-opacity:1;border-color:#cbd5e0;border-color:rgba(203,213,224,var(--border-opacity))}.lg\:focus\:border-gray-500:focus{--border-opacity:1;border-color:#a0aec0;border-color:rgba(160,174,192,var(--border-opacity))}.lg\:focus\:border-gray-600:focus{--border-opacity:1;border-color:#718096;border-color:rgba(113,128,150,var(--border-opacity))}.lg\:focus\:border-gray-700:focus{--border-opacity:1;border-color:#4a5568;border-color:rgba(74,85,104,var(--border-opacity))}.lg\:focus\:border-gray-800:focus{--border-opacity:1;border-color:#2d3748;border-color:rgba(45,55,72,var(--border-opacity))}.lg\:focus\:border-gray-900:focus{--border-opacity:1;border-color:#1a202c;border-color:rgba(26,32,44,var(--border-opacity))}.lg\:focus\:border-red-100:focus{--border-opacity:1;border-color:#fff5f5;border-color:rgba(255,245,245,var(--border-opacity))}.lg\:focus\:border-red-200:focus{--border-opacity:1;border-color:#fed7d7;border-color:rgba(254,215,215,var(--border-opacity))}.lg\:focus\:border-red-300:focus{--border-opacity:1;border-color:#feb2b2;border-color:rgba(254,178,178,var(--border-opacity))}.lg\:focus\:border-red-400:focus{--border-opacity:1;border-color:#fc8181;border-color:rgba(252,129,129,var(--border-opacity))}.lg\:focus\:border-red-500:focus{--border-opacity:1;border-color:#f56565;border-color:rgba(245,101,101,var(--border-opacity))}.lg\:focus\:border-red-600:focus{--border-opacity:1;border-color:#e53e3e;border-color:rgba(229,62,62,var(--border-opacity))}.lg\:focus\:border-red-700:focus{--border-opacity:1;border-color:#c53030;border-color:rgba(197,48,48,var(--border-opacity))}.lg\:focus\:border-red-800:focus{--border-opacity:1;border-color:#9b2c2c;border-color:rgba(155,44,44,var(--border-opacity))}.lg\:focus\:border-red-900:focus{--border-opacity:1;border-color:#742a2a;border-color:rgba(116,42,42,var(--border-opacity))}.lg\:focus\:border-orange-100:focus{--border-opacity:1;border-color:#fffaf0;border-color:rgba(255,250,240,var(--border-opacity))}.lg\:focus\:border-orange-200:focus{--border-opacity:1;border-color:#feebc8;border-color:rgba(254,235,200,var(--border-opacity))}.lg\:focus\:border-orange-300:focus{--border-opacity:1;border-color:#fbd38d;border-color:rgba(251,211,141,var(--border-opacity))}.lg\:focus\:border-orange-400:focus{--border-opacity:1;border-color:#f6ad55;border-color:rgba(246,173,85,var(--border-opacity))}.lg\:focus\:border-orange-500:focus{--border-opacity:1;border-color:#ed8936;border-color:rgba(237,137,54,var(--border-opacity))}.lg\:focus\:border-orange-600:focus{--border-opacity:1;border-color:#dd6b20;border-color:rgba(221,107,32,var(--border-opacity))}.lg\:focus\:border-orange-700:focus{--border-opacity:1;border-color:#c05621;border-color:rgba(192,86,33,var(--border-opacity))}.lg\:focus\:border-orange-800:focus{--border-opacity:1;border-color:#9c4221;border-color:rgba(156,66,33,var(--border-opacity))}.lg\:focus\:border-orange-900:focus{--border-opacity:1;border-color:#7b341e;border-color:rgba(123,52,30,var(--border-opacity))}.lg\:focus\:border-yellow-100:focus{--border-opacity:1;border-color:ivory;border-color:rgba(255,255,240,var(--border-opacity))}.lg\:focus\:border-yellow-200:focus{--border-opacity:1;border-color:#fefcbf;border-color:rgba(254,252,191,var(--border-opacity))}.lg\:focus\:border-yellow-300:focus{--border-opacity:1;border-color:#faf089;border-color:rgba(250,240,137,var(--border-opacity))}.lg\:focus\:border-yellow-400:focus{--border-opacity:1;border-color:#f6e05e;border-color:rgba(246,224,94,var(--border-opacity))}.lg\:focus\:border-yellow-500:focus{--border-opacity:1;border-color:#ecc94b;border-color:rgba(236,201,75,var(--border-opacity))}.lg\:focus\:border-yellow-600:focus{--border-opacity:1;border-color:#d69e2e;border-color:rgba(214,158,46,var(--border-opacity))}.lg\:focus\:border-yellow-700:focus{--border-opacity:1;border-color:#b7791f;border-color:rgba(183,121,31,var(--border-opacity))}.lg\:focus\:border-yellow-800:focus{--border-opacity:1;border-color:#975a16;border-color:rgba(151,90,22,var(--border-opacity))}.lg\:focus\:border-yellow-900:focus{--border-opacity:1;border-color:#744210;border-color:rgba(116,66,16,var(--border-opacity))}.lg\:focus\:border-green-100:focus{--border-opacity:1;border-color:#f0fff4;border-color:rgba(240,255,244,var(--border-opacity))}.lg\:focus\:border-green-200:focus{--border-opacity:1;border-color:#c6f6d5;border-color:rgba(198,246,213,var(--border-opacity))}.lg\:focus\:border-green-300:focus{--border-opacity:1;border-color:#9ae6b4;border-color:rgba(154,230,180,var(--border-opacity))}.lg\:focus\:border-green-400:focus{--border-opacity:1;border-color:#68d391;border-color:rgba(104,211,145,var(--border-opacity))}.lg\:focus\:border-green-500:focus{--border-opacity:1;border-color:#48bb78;border-color:rgba(72,187,120,var(--border-opacity))}.lg\:focus\:border-green-600:focus{--border-opacity:1;border-color:#38a169;border-color:rgba(56,161,105,var(--border-opacity))}.lg\:focus\:border-green-700:focus{--border-opacity:1;border-color:#2f855a;border-color:rgba(47,133,90,var(--border-opacity))}.lg\:focus\:border-green-800:focus{--border-opacity:1;border-color:#276749;border-color:rgba(39,103,73,var(--border-opacity))}.lg\:focus\:border-green-900:focus{--border-opacity:1;border-color:#22543d;border-color:rgba(34,84,61,var(--border-opacity))}.lg\:focus\:border-teal-100:focus{--border-opacity:1;border-color:#e6fffa;border-color:rgba(230,255,250,var(--border-opacity))}.lg\:focus\:border-teal-200:focus{--border-opacity:1;border-color:#b2f5ea;border-color:rgba(178,245,234,var(--border-opacity))}.lg\:focus\:border-teal-300:focus{--border-opacity:1;border-color:#81e6d9;border-color:rgba(129,230,217,var(--border-opacity))}.lg\:focus\:border-teal-400:focus{--border-opacity:1;border-color:#4fd1c5;border-color:rgba(79,209,197,var(--border-opacity))}.lg\:focus\:border-teal-500:focus{--border-opacity:1;border-color:#38b2ac;border-color:rgba(56,178,172,var(--border-opacity))}.lg\:focus\:border-teal-600:focus{--border-opacity:1;border-color:#319795;border-color:rgba(49,151,149,var(--border-opacity))}.lg\:focus\:border-teal-700:focus{--border-opacity:1;border-color:#2c7a7b;border-color:rgba(44,122,123,var(--border-opacity))}.lg\:focus\:border-teal-800:focus{--border-opacity:1;border-color:#285e61;border-color:rgba(40,94,97,var(--border-opacity))}.lg\:focus\:border-teal-900:focus{--border-opacity:1;border-color:#234e52;border-color:rgba(35,78,82,var(--border-opacity))}.lg\:focus\:border-blue-100:focus{--border-opacity:1;border-color:#ebf8ff;border-color:rgba(235,248,255,var(--border-opacity))}.lg\:focus\:border-blue-200:focus{--border-opacity:1;border-color:#bee3f8;border-color:rgba(190,227,248,var(--border-opacity))}.lg\:focus\:border-blue-300:focus{--border-opacity:1;border-color:#90cdf4;border-color:rgba(144,205,244,var(--border-opacity))}.lg\:focus\:border-blue-400:focus{--border-opacity:1;border-color:#63b3ed;border-color:rgba(99,179,237,var(--border-opacity))}.lg\:focus\:border-blue-500:focus{--border-opacity:1;border-color:#4299e1;border-color:rgba(66,153,225,var(--border-opacity))}.lg\:focus\:border-blue-600:focus{--border-opacity:1;border-color:#3182ce;border-color:rgba(49,130,206,var(--border-opacity))}.lg\:focus\:border-blue-700:focus{--border-opacity:1;border-color:#2b6cb0;border-color:rgba(43,108,176,var(--border-opacity))}.lg\:focus\:border-blue-800:focus{--border-opacity:1;border-color:#2c5282;border-color:rgba(44,82,130,var(--border-opacity))}.lg\:focus\:border-blue-900:focus{--border-opacity:1;border-color:#2a4365;border-color:rgba(42,67,101,var(--border-opacity))}.lg\:focus\:border-indigo-100:focus{--border-opacity:1;border-color:#ebf4ff;border-color:rgba(235,244,255,var(--border-opacity))}.lg\:focus\:border-indigo-200:focus{--border-opacity:1;border-color:#c3dafe;border-color:rgba(195,218,254,var(--border-opacity))}.lg\:focus\:border-indigo-300:focus{--border-opacity:1;border-color:#a3bffa;border-color:rgba(163,191,250,var(--border-opacity))}.lg\:focus\:border-indigo-400:focus{--border-opacity:1;border-color:#7f9cf5;border-color:rgba(127,156,245,var(--border-opacity))}.lg\:focus\:border-indigo-500:focus{--border-opacity:1;border-color:#667eea;border-color:rgba(102,126,234,var(--border-opacity))}.lg\:focus\:border-indigo-600:focus{--border-opacity:1;border-color:#5a67d8;border-color:rgba(90,103,216,var(--border-opacity))}.lg\:focus\:border-indigo-700:focus{--border-opacity:1;border-color:#4c51bf;border-color:rgba(76,81,191,var(--border-opacity))}.lg\:focus\:border-indigo-800:focus{--border-opacity:1;border-color:#434190;border-color:rgba(67,65,144,var(--border-opacity))}.lg\:focus\:border-indigo-900:focus{--border-opacity:1;border-color:#3c366b;border-color:rgba(60,54,107,var(--border-opacity))}.lg\:focus\:border-purple-100:focus{--border-opacity:1;border-color:#faf5ff;border-color:rgba(250,245,255,var(--border-opacity))}.lg\:focus\:border-purple-200:focus{--border-opacity:1;border-color:#e9d8fd;border-color:rgba(233,216,253,var(--border-opacity))}.lg\:focus\:border-purple-300:focus{--border-opacity:1;border-color:#d6bcfa;border-color:rgba(214,188,250,var(--border-opacity))}.lg\:focus\:border-purple-400:focus{--border-opacity:1;border-color:#b794f4;border-color:rgba(183,148,244,var(--border-opacity))}.lg\:focus\:border-purple-500:focus{--border-opacity:1;border-color:#9f7aea;border-color:rgba(159,122,234,var(--border-opacity))}.lg\:focus\:border-purple-600:focus{--border-opacity:1;border-color:#805ad5;border-color:rgba(128,90,213,var(--border-opacity))}.lg\:focus\:border-purple-700:focus{--border-opacity:1;border-color:#6b46c1;border-color:rgba(107,70,193,var(--border-opacity))}.lg\:focus\:border-purple-800:focus{--border-opacity:1;border-color:#553c9a;border-color:rgba(85,60,154,var(--border-opacity))}.lg\:focus\:border-purple-900:focus{--border-opacity:1;border-color:#44337a;border-color:rgba(68,51,122,var(--border-opacity))}.lg\:focus\:border-pink-100:focus{--border-opacity:1;border-color:#fff5f7;border-color:rgba(255,245,247,var(--border-opacity))}.lg\:focus\:border-pink-200:focus{--border-opacity:1;border-color:#fed7e2;border-color:rgba(254,215,226,var(--border-opacity))}.lg\:focus\:border-pink-300:focus{--border-opacity:1;border-color:#fbb6ce;border-color:rgba(251,182,206,var(--border-opacity))}.lg\:focus\:border-pink-400:focus{--border-opacity:1;border-color:#f687b3;border-color:rgba(246,135,179,var(--border-opacity))}.lg\:focus\:border-pink-500:focus{--border-opacity:1;border-color:#ed64a6;border-color:rgba(237,100,166,var(--border-opacity))}.lg\:focus\:border-pink-600:focus{--border-opacity:1;border-color:#d53f8c;border-color:rgba(213,63,140,var(--border-opacity))}.lg\:focus\:border-pink-700:focus{--border-opacity:1;border-color:#b83280;border-color:rgba(184,50,128,var(--border-opacity))}.lg\:focus\:border-pink-800:focus{--border-opacity:1;border-color:#97266d;border-color:rgba(151,38,109,var(--border-opacity))}.lg\:focus\:border-pink-900:focus{--border-opacity:1;border-color:#702459;border-color:rgba(112,36,89,var(--border-opacity))}.lg\:border-opacity-0{--border-opacity:0}.lg\:border-opacity-25{--border-opacity:0.25}.lg\:border-opacity-50{--border-opacity:0.5}.lg\:border-opacity-75{--border-opacity:0.75}.lg\:border-opacity-100{--border-opacity:1}.lg\:hover\:border-opacity-0:hover{--border-opacity:0}.lg\:hover\:border-opacity-25:hover{--border-opacity:0.25}.lg\:hover\:border-opacity-50:hover{--border-opacity:0.5}.lg\:hover\:border-opacity-75:hover{--border-opacity:0.75}.lg\:hover\:border-opacity-100:hover{--border-opacity:1}.lg\:focus\:border-opacity-0:focus{--border-opacity:0}.lg\:focus\:border-opacity-25:focus{--border-opacity:0.25}.lg\:focus\:border-opacity-50:focus{--border-opacity:0.5}.lg\:focus\:border-opacity-75:focus{--border-opacity:0.75}.lg\:focus\:border-opacity-100:focus{--border-opacity:1}.lg\:rounded-none{border-radius:0}.lg\:rounded-sm{border-radius:.125rem}.lg\:rounded{border-radius:.25rem}.lg\:rounded-md{border-radius:.375rem}.lg\:rounded-lg{border-radius:.5rem}.lg\:rounded-xl{border-radius:.75rem}.lg\:rounded-2xl{border-radius:1rem}.lg\:rounded-3xl{border-radius:1.5rem}.lg\:rounded-full{border-radius:9999px}.lg\:rounded-t-none{border-top-left-radius:0;border-top-right-radius:0}.lg\:rounded-r-none{border-top-right-radius:0;border-bottom-right-radius:0}.lg\:rounded-b-none{border-bottom-right-radius:0;border-bottom-left-radius:0}.lg\:rounded-l-none{border-top-left-radius:0;border-bottom-left-radius:0}.lg\:rounded-t-sm{border-top-left-radius:.125rem;border-top-right-radius:.125rem}.lg\:rounded-r-sm{border-top-right-radius:.125rem;border-bottom-right-radius:.125rem}.lg\:rounded-b-sm{border-bottom-right-radius:.125rem;border-bottom-left-radius:.125rem}.lg\:rounded-l-sm{border-top-left-radius:.125rem;border-bottom-left-radius:.125rem}.lg\:rounded-t{border-top-left-radius:.25rem;border-top-right-radius:.25rem}.lg\:rounded-r{border-top-right-radius:.25rem;border-bottom-right-radius:.25rem}.lg\:rounded-b{border-bottom-right-radius:.25rem;border-bottom-left-radius:.25rem}.lg\:rounded-l{border-top-left-radius:.25rem;border-bottom-left-radius:.25rem}.lg\:rounded-t-md{border-top-left-radius:.375rem;border-top-right-radius:.375rem}.lg\:rounded-r-md{border-top-right-radius:.375rem;border-bottom-right-radius:.375rem}.lg\:rounded-b-md{border-bottom-right-radius:.375rem;border-bottom-left-radius:.375rem}.lg\:rounded-l-md{border-top-left-radius:.375rem;border-bottom-left-radius:.375rem}.lg\:rounded-t-lg{border-top-left-radius:.5rem;border-top-right-radius:.5rem}.lg\:rounded-r-lg{border-top-right-radius:.5rem;border-bottom-right-radius:.5rem}.lg\:rounded-b-lg{border-bottom-right-radius:.5rem;border-bottom-left-radius:.5rem}.lg\:rounded-l-lg{border-top-left-radius:.5rem;border-bottom-left-radius:.5rem}.lg\:rounded-t-xl{border-top-left-radius:.75rem;border-top-right-radius:.75rem}.lg\:rounded-r-xl{border-top-right-radius:.75rem;border-bottom-right-radius:.75rem}.lg\:rounded-b-xl{border-bottom-right-radius:.75rem;border-bottom-left-radius:.75rem}.lg\:rounded-l-xl{border-top-left-radius:.75rem;border-bottom-left-radius:.75rem}.lg\:rounded-t-2xl{border-top-left-radius:1rem;border-top-right-radius:1rem}.lg\:rounded-r-2xl{border-top-right-radius:1rem;border-bottom-right-radius:1rem}.lg\:rounded-b-2xl{border-bottom-right-radius:1rem;border-bottom-left-radius:1rem}.lg\:rounded-l-2xl{border-top-left-radius:1rem;border-bottom-left-radius:1rem}.lg\:rounded-t-3xl{border-top-left-radius:1.5rem;border-top-right-radius:1.5rem}.lg\:rounded-r-3xl{border-top-right-radius:1.5rem;border-bottom-right-radius:1.5rem}.lg\:rounded-b-3xl{border-bottom-right-radius:1.5rem;border-bottom-left-radius:1.5rem}.lg\:rounded-l-3xl{border-top-left-radius:1.5rem;border-bottom-left-radius:1.5rem}.lg\:rounded-t-full{border-top-left-radius:9999px;border-top-right-radius:9999px}.lg\:rounded-r-full{border-top-right-radius:9999px;border-bottom-right-radius:9999px}.lg\:rounded-b-full{border-bottom-right-radius:9999px;border-bottom-left-radius:9999px}.lg\:rounded-l-full{border-top-left-radius:9999px;border-bottom-left-radius:9999px}.lg\:rounded-tl-none{border-top-left-radius:0}.lg\:rounded-tr-none{border-top-right-radius:0}.lg\:rounded-br-none{border-bottom-right-radius:0}.lg\:rounded-bl-none{border-bottom-left-radius:0}.lg\:rounded-tl-sm{border-top-left-radius:.125rem}.lg\:rounded-tr-sm{border-top-right-radius:.125rem}.lg\:rounded-br-sm{border-bottom-right-radius:.125rem}.lg\:rounded-bl-sm{border-bottom-left-radius:.125rem}.lg\:rounded-tl{border-top-left-radius:.25rem}.lg\:rounded-tr{border-top-right-radius:.25rem}.lg\:rounded-br{border-bottom-right-radius:.25rem}.lg\:rounded-bl{border-bottom-left-radius:.25rem}.lg\:rounded-tl-md{border-top-left-radius:.375rem}.lg\:rounded-tr-md{border-top-right-radius:.375rem}.lg\:rounded-br-md{border-bottom-right-radius:.375rem}.lg\:rounded-bl-md{border-bottom-left-radius:.375rem}.lg\:rounded-tl-lg{border-top-left-radius:.5rem}.lg\:rounded-tr-lg{border-top-right-radius:.5rem}.lg\:rounded-br-lg{border-bottom-right-radius:.5rem}.lg\:rounded-bl-lg{border-bottom-left-radius:.5rem}.lg\:rounded-tl-xl{border-top-left-radius:.75rem}.lg\:rounded-tr-xl{border-top-right-radius:.75rem}.lg\:rounded-br-xl{border-bottom-right-radius:.75rem}.lg\:rounded-bl-xl{border-bottom-left-radius:.75rem}.lg\:rounded-tl-2xl{border-top-left-radius:1rem}.lg\:rounded-tr-2xl{border-top-right-radius:1rem}.lg\:rounded-br-2xl{border-bottom-right-radius:1rem}.lg\:rounded-bl-2xl{border-bottom-left-radius:1rem}.lg\:rounded-tl-3xl{border-top-left-radius:1.5rem}.lg\:rounded-tr-3xl{border-top-right-radius:1.5rem}.lg\:rounded-br-3xl{border-bottom-right-radius:1.5rem}.lg\:rounded-bl-3xl{border-bottom-left-radius:1.5rem}.lg\:rounded-tl-full{border-top-left-radius:9999px}.lg\:rounded-tr-full{border-top-right-radius:9999px}.lg\:rounded-br-full{border-bottom-right-radius:9999px}.lg\:rounded-bl-full{border-bottom-left-radius:9999px}.lg\:border-solid{border-style:solid}.lg\:border-dashed{border-style:dashed}.lg\:border-dotted{border-style:dotted}.lg\:border-double{border-style:double}.lg\:border-none{border-style:none}.lg\:border-0{border-width:0}.lg\:border-2{border-width:2px}.lg\:border-4{border-width:4px}.lg\:border-8{border-width:8px}.lg\:border{border-width:1px}.lg\:border-t-0{border-top-width:0}.lg\:border-r-0{border-right-width:0}.lg\:border-b-0{border-bottom-width:0}.lg\:border-l-0{border-left-width:0}.lg\:border-t-2{border-top-width:2px}.lg\:border-r-2{border-right-width:2px}.lg\:border-b-2{border-bottom-width:2px}.lg\:border-l-2{border-left-width:2px}.lg\:border-t-4{border-top-width:4px}.lg\:border-r-4{border-right-width:4px}.lg\:border-b-4{border-bottom-width:4px}.lg\:border-l-4{border-left-width:4px}.lg\:border-t-8{border-top-width:8px}.lg\:border-r-8{border-right-width:8px}.lg\:border-b-8{border-bottom-width:8px}.lg\:border-l-8{border-left-width:8px}.lg\:border-t{border-top-width:1px}.lg\:border-r{border-right-width:1px}.lg\:border-b{border-bottom-width:1px}.lg\:border-l{border-left-width:1px}.lg\:box-border{box-sizing:border-box}.lg\:box-content{box-sizing:content-box}.lg\:cursor-auto{cursor:auto}.lg\:cursor-default{cursor:default}.lg\:cursor-pointer{cursor:pointer}.lg\:cursor-wait{cursor:wait}.lg\:cursor-text{cursor:text}.lg\:cursor-move{cursor:move}.lg\:cursor-not-allowed{cursor:not-allowed}.lg\:block{display:block}.lg\:inline-block{display:inline-block}.lg\:inline{display:inline}.lg\:flex{display:flex}.lg\:inline-flex{display:inline-flex}.lg\:table{display:table}.lg\:table-caption{display:table-caption}.lg\:table-cell{display:table-cell}.lg\:table-column{display:table-column}.lg\:table-column-group{display:table-column-group}.lg\:table-footer-group{display:table-footer-group}.lg\:table-header-group{display:table-header-group}.lg\:table-row-group{display:table-row-group}.lg\:table-row{display:table-row}.lg\:flow-root{display:flow-root}.lg\:grid{display:grid}.lg\:inline-grid{display:inline-grid}.lg\:contents{display:contents}.lg\:hidden{display:none}.lg\:flex-row{flex-direction:row}.lg\:flex-row-reverse{flex-direction:row-reverse}.lg\:flex-col{flex-direction:column}.lg\:flex-col-reverse{flex-direction:column-reverse}.lg\:flex-wrap{flex-wrap:wrap}.lg\:flex-wrap-reverse{flex-wrap:wrap-reverse}.lg\:flex-no-wrap{flex-wrap:nowrap}.lg\:place-items-auto{place-items:auto}.lg\:place-items-start{place-items:start}.lg\:place-items-end{place-items:end}.lg\:place-items-center{place-items:center}.lg\:place-items-stretch{place-items:stretch}.lg\:place-content-center{place-content:center}.lg\:place-content-start{place-content:start}.lg\:place-content-end{place-content:end}.lg\:place-content-between{place-content:space-between}.lg\:place-content-around{place-content:space-around}.lg\:place-content-evenly{place-content:space-evenly}.lg\:place-content-stretch{place-content:stretch}.lg\:place-self-auto{place-self:auto}.lg\:place-self-start{place-self:start}.lg\:place-self-end{place-self:end}.lg\:place-self-center{place-self:center}.lg\:place-self-stretch{place-self:stretch}.lg\:items-start{align-items:flex-start}.lg\:items-end{align-items:flex-end}.lg\:items-center{align-items:center}.lg\:items-baseline{align-items:baseline}.lg\:items-stretch{align-items:stretch}.lg\:content-center{align-content:center}.lg\:content-start{align-content:flex-start}.lg\:content-end{align-content:flex-end}.lg\:content-between{align-content:space-between}.lg\:content-around{align-content:space-around}.lg\:content-evenly{align-content:space-evenly}.lg\:self-auto{align-self:auto}.lg\:self-start{align-self:flex-start}.lg\:self-end{align-self:flex-end}.lg\:self-center{align-self:center}.lg\:self-stretch{align-self:stretch}.lg\:justify-items-auto{justify-items:auto}.lg\:justify-items-start{justify-items:start}.lg\:justify-items-end{justify-items:end}.lg\:justify-items-center{justify-items:center}.lg\:justify-items-stretch{justify-items:stretch}.lg\:justify-start{justify-content:flex-start}.lg\:justify-end{justify-content:flex-end}.lg\:justify-center{justify-content:center}.lg\:justify-between{justify-content:space-between}.lg\:justify-around{justify-content:space-around}.lg\:justify-evenly{justify-content:space-evenly}.lg\:justify-self-auto{justify-self:auto}.lg\:justify-self-start{justify-self:start}.lg\:justify-self-end{justify-self:end}.lg\:justify-self-center{justify-self:center}.lg\:justify-self-stretch{justify-self:stretch}.lg\:flex-1{flex:1 1 0%}.lg\:flex-auto{flex:1 1 auto}.lg\:flex-initial{flex:0 1 auto}.lg\:flex-none{flex:none}.lg\:flex-grow-0{flex-grow:0}.lg\:flex-grow{flex-grow:1}.lg\:flex-shrink-0{flex-shrink:0}.lg\:flex-shrink{flex-shrink:1}.lg\:order-1{order:1}.lg\:order-2{order:2}.lg\:order-3{order:3}.lg\:order-4{order:4}.lg\:order-5{order:5}.lg\:order-6{order:6}.lg\:order-7{order:7}.lg\:order-8{order:8}.lg\:order-9{order:9}.lg\:order-10{order:10}.lg\:order-11{order:11}.lg\:order-12{order:12}.lg\:order-first{order:-9999}.lg\:order-last{order:9999}.lg\:order-none{order:0}.lg\:float-right{float:right}.lg\:float-left{float:left}.lg\:float-none{float:none}.lg\:clearfix:after{content:"";display:table;clear:both}.lg\:clear-left{clear:left}.lg\:clear-right{clear:right}.lg\:clear-both{clear:both}.lg\:clear-none{clear:none}.lg\:font-sans{font-family:system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji"}.lg\:font-serif{font-family:Georgia,Cambria,"Times New Roman",Times,serif}.lg\:font-mono{font-family:Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace}.lg\:font-hairline{font-weight:100}.lg\:font-thin{font-weight:200}.lg\:font-light{font-weight:300}.lg\:font-normal{font-weight:400}.lg\:font-medium{font-weight:500}.lg\:font-semibold{font-weight:600}.lg\:font-bold{font-weight:700}.lg\:font-extrabold{font-weight:800}.lg\:font-black{font-weight:900}.lg\:hover\:font-hairline:hover{font-weight:100}.lg\:hover\:font-thin:hover{font-weight:200}.lg\:hover\:font-light:hover{font-weight:300}.lg\:hover\:font-normal:hover{font-weight:400}.lg\:hover\:font-medium:hover{font-weight:500}.lg\:hover\:font-semibold:hover{font-weight:600}.lg\:hover\:font-bold:hover{font-weight:700}.lg\:hover\:font-extrabold:hover{font-weight:800}.lg\:hover\:font-black:hover{font-weight:900}.lg\:focus\:font-hairline:focus{font-weight:100}.lg\:focus\:font-thin:focus{font-weight:200}.lg\:focus\:font-light:focus{font-weight:300}.lg\:focus\:font-normal:focus{font-weight:400}.lg\:focus\:font-medium:focus{font-weight:500}.lg\:focus\:font-semibold:focus{font-weight:600}.lg\:focus\:font-bold:focus{font-weight:700}.lg\:focus\:font-extrabold:focus{font-weight:800}.lg\:focus\:font-black:focus{font-weight:900}.lg\:h-0{height:0}.lg\:h-1{height:.25rem}.lg\:h-2{height:.5rem}.lg\:h-3{height:.75rem}.lg\:h-4{height:1rem}.lg\:h-5{height:1.25rem}.lg\:h-6{height:1.5rem}.lg\:h-8{height:2rem}.lg\:h-10{height:2.5rem}.lg\:h-12{height:3rem}.lg\:h-16{height:4rem}.lg\:h-20{height:5rem}.lg\:h-24{height:6rem}.lg\:h-32{height:8rem}.lg\:h-40{height:10rem}.lg\:h-48{height:12rem}.lg\:h-56{height:14rem}.lg\:h-64{height:16rem}.lg\:h-auto{height:auto}.lg\:h-px{height:1px}.lg\:h-full{height:100%}.lg\:h-screen{height:100vh}.lg\:text-xs{font-size:.75rem}.lg\:text-sm{font-size:.875rem}.lg\:text-base{font-size:1rem}.lg\:text-lg{font-size:1.125rem}.lg\:text-xl{font-size:1.25rem}.lg\:text-2xl{font-size:1.5rem}.lg\:text-3xl{font-size:1.875rem}.lg\:text-4xl{font-size:2.25rem}.lg\:text-5xl{font-size:3rem}.lg\:text-6xl{font-size:4rem}.lg\:leading-3{line-height:.75rem}.lg\:leading-4{line-height:1rem}.lg\:leading-5{line-height:1.25rem}.lg\:leading-6{line-height:1.5rem}.lg\:leading-7{line-height:1.75rem}.lg\:leading-8{line-height:2rem}.lg\:leading-9{line-height:2.25rem}.lg\:leading-10{line-height:2.5rem}.lg\:leading-none{line-height:1}.lg\:leading-tight{line-height:1.25}.lg\:leading-snug{line-height:1.375}.lg\:leading-normal{line-height:1.5}.lg\:leading-relaxed{line-height:1.625}.lg\:leading-loose{line-height:2}.lg\:list-inside{list-style-position:inside}.lg\:list-outside{list-style-position:outside}.lg\:list-none{list-style-type:none}.lg\:list-disc{list-style-type:disc}.lg\:list-decimal{list-style-type:decimal}.lg\:m-0{margin:0}.lg\:m-1{margin:.25rem}.lg\:m-2{margin:.5rem}.lg\:m-3{margin:.75rem}.lg\:m-4{margin:1rem}.lg\:m-5{margin:1.25rem}.lg\:m-6{margin:1.5rem}.lg\:m-8{margin:2rem}.lg\:m-10{margin:2.5rem}.lg\:m-12{margin:3rem}.lg\:m-16{margin:4rem}.lg\:m-20{margin:5rem}.lg\:m-24{margin:6rem}.lg\:m-32{margin:8rem}.lg\:m-40{margin:10rem}.lg\:m-48{margin:12rem}.lg\:m-56{margin:14rem}.lg\:m-64{margin:16rem}.lg\:m-auto{margin:auto}.lg\:m-px{margin:1px}.lg\:-m-1{margin:-.25rem}.lg\:-m-2{margin:-.5rem}.lg\:-m-3{margin:-.75rem}.lg\:-m-4{margin:-1rem}.lg\:-m-5{margin:-1.25rem}.lg\:-m-6{margin:-1.5rem}.lg\:-m-8{margin:-2rem}.lg\:-m-10{margin:-2.5rem}.lg\:-m-12{margin:-3rem}.lg\:-m-16{margin:-4rem}.lg\:-m-20{margin:-5rem}.lg\:-m-24{margin:-6rem}.lg\:-m-32{margin:-8rem}.lg\:-m-40{margin:-10rem}.lg\:-m-48{margin:-12rem}.lg\:-m-56{margin:-14rem}.lg\:-m-64{margin:-16rem}.lg\:-m-px{margin:-1px}.lg\:my-0{margin-top:0;margin-bottom:0}.lg\:mx-0{margin-left:0;margin-right:0}.lg\:my-1{margin-top:.25rem;margin-bottom:.25rem}.lg\:mx-1{margin-left:.25rem;margin-right:.25rem}.lg\:my-2{margin-top:.5rem;margin-bottom:.5rem}.lg\:mx-2{margin-left:.5rem;margin-right:.5rem}.lg\:my-3{margin-top:.75rem;margin-bottom:.75rem}.lg\:mx-3{margin-left:.75rem;margin-right:.75rem}.lg\:my-4{margin-top:1rem;margin-bottom:1rem}.lg\:mx-4{margin-left:1rem;margin-right:1rem}.lg\:my-5{margin-top:1.25rem;margin-bottom:1.25rem}.lg\:mx-5{margin-left:1.25rem;margin-right:1.25rem}.lg\:my-6{margin-top:1.5rem;margin-bottom:1.5rem}.lg\:mx-6{margin-left:1.5rem;margin-right:1.5rem}.lg\:my-8{margin-top:2rem;margin-bottom:2rem}.lg\:mx-8{margin-left:2rem;margin-right:2rem}.lg\:my-10{margin-top:2.5rem;margin-bottom:2.5rem}.lg\:mx-10{margin-left:2.5rem;margin-right:2.5rem}.lg\:my-12{margin-top:3rem;margin-bottom:3rem}.lg\:mx-12{margin-left:3rem;margin-right:3rem}.lg\:my-16{margin-top:4rem;margin-bottom:4rem}.lg\:mx-16{margin-left:4rem;margin-right:4rem}.lg\:my-20{margin-top:5rem;margin-bottom:5rem}.lg\:mx-20{margin-left:5rem;margin-right:5rem}.lg\:my-24{margin-top:6rem;margin-bottom:6rem}.lg\:mx-24{margin-left:6rem;margin-right:6rem}.lg\:my-32{margin-top:8rem;margin-bottom:8rem}.lg\:mx-32{margin-left:8rem;margin-right:8rem}.lg\:my-40{margin-top:10rem;margin-bottom:10rem}.lg\:mx-40{margin-left:10rem;margin-right:10rem}.lg\:my-48{margin-top:12rem;margin-bottom:12rem}.lg\:mx-48{margin-left:12rem;margin-right:12rem}.lg\:my-56{margin-top:14rem;margin-bottom:14rem}.lg\:mx-56{margin-left:14rem;margin-right:14rem}.lg\:my-64{margin-top:16rem;margin-bottom:16rem}.lg\:mx-64{margin-left:16rem;margin-right:16rem}.lg\:my-auto{margin-top:auto;margin-bottom:auto}.lg\:mx-auto{margin-left:auto;margin-right:auto}.lg\:my-px{margin-top:1px;margin-bottom:1px}.lg\:mx-px{margin-left:1px;margin-right:1px}.lg\:-my-1{margin-top:-.25rem;margin-bottom:-.25rem}.lg\:-mx-1{margin-left:-.25rem;margin-right:-.25rem}.lg\:-my-2{margin-top:-.5rem;margin-bottom:-.5rem}.lg\:-mx-2{margin-left:-.5rem;margin-right:-.5rem}.lg\:-my-3{margin-top:-.75rem;margin-bottom:-.75rem}.lg\:-mx-3{margin-left:-.75rem;margin-right:-.75rem}.lg\:-my-4{margin-top:-1rem;margin-bottom:-1rem}.lg\:-mx-4{margin-left:-1rem;margin-right:-1rem}.lg\:-my-5{margin-top:-1.25rem;margin-bottom:-1.25rem}.lg\:-mx-5{margin-left:-1.25rem;margin-right:-1.25rem}.lg\:-my-6{margin-top:-1.5rem;margin-bottom:-1.5rem}.lg\:-mx-6{margin-left:-1.5rem;margin-right:-1.5rem}.lg\:-my-8{margin-top:-2rem;margin-bottom:-2rem}.lg\:-mx-8{margin-left:-2rem;margin-right:-2rem}.lg\:-my-10{margin-top:-2.5rem;margin-bottom:-2.5rem}.lg\:-mx-10{margin-left:-2.5rem;margin-right:-2.5rem}.lg\:-my-12{margin-top:-3rem;margin-bottom:-3rem}.lg\:-mx-12{margin-left:-3rem;margin-right:-3rem}.lg\:-my-16{margin-top:-4rem;margin-bottom:-4rem}.lg\:-mx-16{margin-left:-4rem;margin-right:-4rem}.lg\:-my-20{margin-top:-5rem;margin-bottom:-5rem}.lg\:-mx-20{margin-left:-5rem;margin-right:-5rem}.lg\:-my-24{margin-top:-6rem;margin-bottom:-6rem}.lg\:-mx-24{margin-left:-6rem;margin-right:-6rem}.lg\:-my-32{margin-top:-8rem;margin-bottom:-8rem}.lg\:-mx-32{margin-left:-8rem;margin-right:-8rem}.lg\:-my-40{margin-top:-10rem;margin-bottom:-10rem}.lg\:-mx-40{margin-left:-10rem;margin-right:-10rem}.lg\:-my-48{margin-top:-12rem;margin-bottom:-12rem}.lg\:-mx-48{margin-left:-12rem;margin-right:-12rem}.lg\:-my-56{margin-top:-14rem;margin-bottom:-14rem}.lg\:-mx-56{margin-left:-14rem;margin-right:-14rem}.lg\:-my-64{margin-top:-16rem;margin-bottom:-16rem}.lg\:-mx-64{margin-left:-16rem;margin-right:-16rem}.lg\:-my-px{margin-top:-1px;margin-bottom:-1px}.lg\:-mx-px{margin-left:-1px;margin-right:-1px}.lg\:mt-0{margin-top:0}.lg\:mr-0{margin-right:0}.lg\:mb-0{margin-bottom:0}.lg\:ml-0{margin-left:0}.lg\:mt-1{margin-top:.25rem}.lg\:mr-1{margin-right:.25rem}.lg\:mb-1{margin-bottom:.25rem}.lg\:ml-1{margin-left:.25rem}.lg\:mt-2{margin-top:.5rem}.lg\:mr-2{margin-right:.5rem}.lg\:mb-2{margin-bottom:.5rem}.lg\:ml-2{margin-left:.5rem}.lg\:mt-3{margin-top:.75rem}.lg\:mr-3{margin-right:.75rem}.lg\:mb-3{margin-bottom:.75rem}.lg\:ml-3{margin-left:.75rem}.lg\:mt-4{margin-top:1rem}.lg\:mr-4{margin-right:1rem}.lg\:mb-4{margin-bottom:1rem}.lg\:ml-4{margin-left:1rem}.lg\:mt-5{margin-top:1.25rem}.lg\:mr-5{margin-right:1.25rem}.lg\:mb-5{margin-bottom:1.25rem}.lg\:ml-5{margin-left:1.25rem}.lg\:mt-6{margin-top:1.5rem}.lg\:mr-6{margin-right:1.5rem}.lg\:mb-6{margin-bottom:1.5rem}.lg\:ml-6{margin-left:1.5rem}.lg\:mt-8{margin-top:2rem}.lg\:mr-8{margin-right:2rem}.lg\:mb-8{margin-bottom:2rem}.lg\:ml-8{margin-left:2rem}.lg\:mt-10{margin-top:2.5rem}.lg\:mr-10{margin-right:2.5rem}.lg\:mb-10{margin-bottom:2.5rem}.lg\:ml-10{margin-left:2.5rem}.lg\:mt-12{margin-top:3rem}.lg\:mr-12{margin-right:3rem}.lg\:mb-12{margin-bottom:3rem}.lg\:ml-12{margin-left:3rem}.lg\:mt-16{margin-top:4rem}.lg\:mr-16{margin-right:4rem}.lg\:mb-16{margin-bottom:4rem}.lg\:ml-16{margin-left:4rem}.lg\:mt-20{margin-top:5rem}.lg\:mr-20{margin-right:5rem}.lg\:mb-20{margin-bottom:5rem}.lg\:ml-20{margin-left:5rem}.lg\:mt-24{margin-top:6rem}.lg\:mr-24{margin-right:6rem}.lg\:mb-24{margin-bottom:6rem}.lg\:ml-24{margin-left:6rem}.lg\:mt-32{margin-top:8rem}.lg\:mr-32{margin-right:8rem}.lg\:mb-32{margin-bottom:8rem}.lg\:ml-32{margin-left:8rem}.lg\:mt-40{margin-top:10rem}.lg\:mr-40{margin-right:10rem}.lg\:mb-40{margin-bottom:10rem}.lg\:ml-40{margin-left:10rem}.lg\:mt-48{margin-top:12rem}.lg\:mr-48{margin-right:12rem}.lg\:mb-48{margin-bottom:12rem}.lg\:ml-48{margin-left:12rem}.lg\:mt-56{margin-top:14rem}.lg\:mr-56{margin-right:14rem}.lg\:mb-56{margin-bottom:14rem}.lg\:ml-56{margin-left:14rem}.lg\:mt-64{margin-top:16rem}.lg\:mr-64{margin-right:16rem}.lg\:mb-64{margin-bottom:16rem}.lg\:ml-64{margin-left:16rem}.lg\:mt-auto{margin-top:auto}.lg\:mr-auto{margin-right:auto}.lg\:mb-auto{margin-bottom:auto}.lg\:ml-auto{margin-left:auto}.lg\:mt-px{margin-top:1px}.lg\:mr-px{margin-right:1px}.lg\:mb-px{margin-bottom:1px}.lg\:ml-px{margin-left:1px}.lg\:-mt-1{margin-top:-.25rem}.lg\:-mr-1{margin-right:-.25rem}.lg\:-mb-1{margin-bottom:-.25rem}.lg\:-ml-1{margin-left:-.25rem}.lg\:-mt-2{margin-top:-.5rem}.lg\:-mr-2{margin-right:-.5rem}.lg\:-mb-2{margin-bottom:-.5rem}.lg\:-ml-2{margin-left:-.5rem}.lg\:-mt-3{margin-top:-.75rem}.lg\:-mr-3{margin-right:-.75rem}.lg\:-mb-3{margin-bottom:-.75rem}.lg\:-ml-3{margin-left:-.75rem}.lg\:-mt-4{margin-top:-1rem}.lg\:-mr-4{margin-right:-1rem}.lg\:-mb-4{margin-bottom:-1rem}.lg\:-ml-4{margin-left:-1rem}.lg\:-mt-5{margin-top:-1.25rem}.lg\:-mr-5{margin-right:-1.25rem}.lg\:-mb-5{margin-bottom:-1.25rem}.lg\:-ml-5{margin-left:-1.25rem}.lg\:-mt-6{margin-top:-1.5rem}.lg\:-mr-6{margin-right:-1.5rem}.lg\:-mb-6{margin-bottom:-1.5rem}.lg\:-ml-6{margin-left:-1.5rem}.lg\:-mt-8{margin-top:-2rem}.lg\:-mr-8{margin-right:-2rem}.lg\:-mb-8{margin-bottom:-2rem}.lg\:-ml-8{margin-left:-2rem}.lg\:-mt-10{margin-top:-2.5rem}.lg\:-mr-10{margin-right:-2.5rem}.lg\:-mb-10{margin-bottom:-2.5rem}.lg\:-ml-10{margin-left:-2.5rem}.lg\:-mt-12{margin-top:-3rem}.lg\:-mr-12{margin-right:-3rem}.lg\:-mb-12{margin-bottom:-3rem}.lg\:-ml-12{margin-left:-3rem}.lg\:-mt-16{margin-top:-4rem}.lg\:-mr-16{margin-right:-4rem}.lg\:-mb-16{margin-bottom:-4rem}.lg\:-ml-16{margin-left:-4rem}.lg\:-mt-20{margin-top:-5rem}.lg\:-mr-20{margin-right:-5rem}.lg\:-mb-20{margin-bottom:-5rem}.lg\:-ml-20{margin-left:-5rem}.lg\:-mt-24{margin-top:-6rem}.lg\:-mr-24{margin-right:-6rem}.lg\:-mb-24{margin-bottom:-6rem}.lg\:-ml-24{margin-left:-6rem}.lg\:-mt-32{margin-top:-8rem}.lg\:-mr-32{margin-right:-8rem}.lg\:-mb-32{margin-bottom:-8rem}.lg\:-ml-32{margin-left:-8rem}.lg\:-mt-40{margin-top:-10rem}.lg\:-mr-40{margin-right:-10rem}.lg\:-mb-40{margin-bottom:-10rem}.lg\:-ml-40{margin-left:-10rem}.lg\:-mt-48{margin-top:-12rem}.lg\:-mr-48{margin-right:-12rem}.lg\:-mb-48{margin-bottom:-12rem}.lg\:-ml-48{margin-left:-12rem}.lg\:-mt-56{margin-top:-14rem}.lg\:-mr-56{margin-right:-14rem}.lg\:-mb-56{margin-bottom:-14rem}.lg\:-ml-56{margin-left:-14rem}.lg\:-mt-64{margin-top:-16rem}.lg\:-mr-64{margin-right:-16rem}.lg\:-mb-64{margin-bottom:-16rem}.lg\:-ml-64{margin-left:-16rem}.lg\:-mt-px{margin-top:-1px}.lg\:-mr-px{margin-right:-1px}.lg\:-mb-px{margin-bottom:-1px}.lg\:-ml-px{margin-left:-1px}.lg\:max-h-full{max-height:100%}.lg\:max-h-screen{max-height:100vh}.lg\:max-w-none{max-width:none}.lg\:max-w-xs{max-width:20rem}.lg\:max-w-sm{max-width:24rem}.lg\:max-w-md{max-width:28rem}.lg\:max-w-lg{max-width:32rem}.lg\:max-w-xl{max-width:36rem}.lg\:max-w-2xl{max-width:42rem}.lg\:max-w-3xl{max-width:48rem}.lg\:max-w-4xl{max-width:56rem}.lg\:max-w-5xl{max-width:64rem}.lg\:max-w-6xl{max-width:72rem}.lg\:max-w-full{max-width:100%}.lg\:max-w-screen-sm{max-width:640px}.lg\:max-w-screen-md{max-width:768px}.lg\:max-w-screen-lg{max-width:1024px}.lg\:max-w-screen-xl{max-width:1280px}.lg\:min-h-0{min-height:0}.lg\:min-h-full{min-height:100%}.lg\:min-h-screen{min-height:100vh}.lg\:min-w-0{min-width:0}.lg\:min-w-full{min-width:100%}.lg\:object-contain{object-fit:contain}.lg\:object-cover{object-fit:cover}.lg\:object-fill{object-fit:fill}.lg\:object-none{object-fit:none}.lg\:object-scale-down{object-fit:scale-down}.lg\:object-bottom{object-position:bottom}.lg\:object-center{object-position:center}.lg\:object-left{object-position:left}.lg\:object-left-bottom{object-position:left bottom}.lg\:object-left-top{object-position:left top}.lg\:object-right{object-position:right}.lg\:object-right-bottom{object-position:right bottom}.lg\:object-right-top{object-position:right top}.lg\:object-top{object-position:top}.lg\:opacity-0{opacity:0}.lg\:opacity-25{opacity:.25}.lg\:opacity-50{opacity:.5}.lg\:opacity-75{opacity:.75}.lg\:opacity-100{opacity:1}.lg\:hover\:opacity-0:hover{opacity:0}.lg\:hover\:opacity-25:hover{opacity:.25}.lg\:hover\:opacity-50:hover{opacity:.5}.lg\:hover\:opacity-75:hover{opacity:.75}.lg\:hover\:opacity-100:hover{opacity:1}.lg\:focus\:opacity-0:focus{opacity:0}.lg\:focus\:opacity-25:focus{opacity:.25}.lg\:focus\:opacity-50:focus{opacity:.5}.lg\:focus\:opacity-75:focus{opacity:.75}.lg\:focus\:opacity-100:focus{opacity:1}.lg\:outline-none{outline:2px solid transparent;outline-offset:2px}.lg\:outline-white{outline:2px dotted #fff;outline-offset:2px}.lg\:outline-black{outline:2px dotted #000;outline-offset:2px}.lg\:focus\:outline-none:focus{outline:2px solid transparent;outline-offset:2px}.lg\:focus\:outline-white:focus{outline:2px dotted #fff;outline-offset:2px}.lg\:focus\:outline-black:focus{outline:2px dotted #000;outline-offset:2px}.lg\:overflow-auto{overflow:auto}.lg\:overflow-hidden{overflow:hidden}.lg\:overflow-visible{overflow:visible}.lg\:overflow-scroll{overflow:scroll}.lg\:overflow-x-auto{overflow-x:auto}.lg\:overflow-y-auto{overflow-y:auto}.lg\:overflow-x-hidden{overflow-x:hidden}.lg\:overflow-y-hidden{overflow-y:hidden}.lg\:overflow-x-visible{overflow-x:visible}.lg\:overflow-y-visible{overflow-y:visible}.lg\:overflow-x-scroll{overflow-x:scroll}.lg\:overflow-y-scroll{overflow-y:scroll}.lg\:scrolling-touch{-webkit-overflow-scrolling:touch}.lg\:scrolling-auto{-webkit-overflow-scrolling:auto}.lg\:overscroll-auto{-ms-scroll-chaining:chained;overscroll-behavior:auto}.lg\:overscroll-contain{-ms-scroll-chaining:none;overscroll-behavior:contain}.lg\:overscroll-none{-ms-scroll-chaining:none;overscroll-behavior:none}.lg\:overscroll-y-auto{overscroll-behavior-y:auto}.lg\:overscroll-y-contain{overscroll-behavior-y:contain}.lg\:overscroll-y-none{overscroll-behavior-y:none}.lg\:overscroll-x-auto{overscroll-behavior-x:auto}.lg\:overscroll-x-contain{overscroll-behavior-x:contain}.lg\:overscroll-x-none{overscroll-behavior-x:none}.lg\:p-0{padding:0}.lg\:p-1{padding:.25rem}.lg\:p-2{padding:.5rem}.lg\:p-3{padding:.75rem}.lg\:p-4{padding:1rem}.lg\:p-5{padding:1.25rem}.lg\:p-6{padding:1.5rem}.lg\:p-8{padding:2rem}.lg\:p-10{padding:2.5rem}.lg\:p-12{padding:3rem}.lg\:p-16{padding:4rem}.lg\:p-20{padding:5rem}.lg\:p-24{padding:6rem}.lg\:p-32{padding:8rem}.lg\:p-40{padding:10rem}.lg\:p-48{padding:12rem}.lg\:p-56{padding:14rem}.lg\:p-64{padding:16rem}.lg\:p-px{padding:1px}.lg\:py-0{padding-top:0;padding-bottom:0}.lg\:px-0{padding-left:0;padding-right:0}.lg\:py-1{padding-top:.25rem;padding-bottom:.25rem}.lg\:px-1{padding-left:.25rem;padding-right:.25rem}.lg\:py-2{padding-top:.5rem;padding-bottom:.5rem}.lg\:px-2{padding-left:.5rem;padding-right:.5rem}.lg\:py-3{padding-top:.75rem;padding-bottom:.75rem}.lg\:px-3{padding-left:.75rem;padding-right:.75rem}.lg\:py-4{padding-top:1rem;padding-bottom:1rem}.lg\:px-4{padding-left:1rem;padding-right:1rem}.lg\:py-5{padding-top:1.25rem;padding-bottom:1.25rem}.lg\:px-5{padding-left:1.25rem;padding-right:1.25rem}.lg\:py-6{padding-top:1.5rem;padding-bottom:1.5rem}.lg\:px-6{padding-left:1.5rem;padding-right:1.5rem}.lg\:py-8{padding-top:2rem;padding-bottom:2rem}.lg\:px-8{padding-left:2rem;padding-right:2rem}.lg\:py-10{padding-top:2.5rem;padding-bottom:2.5rem}.lg\:px-10{padding-left:2.5rem;padding-right:2.5rem}.lg\:py-12{padding-top:3rem;padding-bottom:3rem}.lg\:px-12{padding-left:3rem;padding-right:3rem}.lg\:py-16{padding-top:4rem;padding-bottom:4rem}.lg\:px-16{padding-left:4rem;padding-right:4rem}.lg\:py-20{padding-top:5rem;padding-bottom:5rem}.lg\:px-20{padding-left:5rem;padding-right:5rem}.lg\:py-24{padding-top:6rem;padding-bottom:6rem}.lg\:px-24{padding-left:6rem;padding-right:6rem}.lg\:py-32{padding-top:8rem;padding-bottom:8rem}.lg\:px-32{padding-left:8rem;padding-right:8rem}.lg\:py-40{padding-top:10rem;padding-bottom:10rem}.lg\:px-40{padding-left:10rem;padding-right:10rem}.lg\:py-48{padding-top:12rem;padding-bottom:12rem}.lg\:px-48{padding-left:12rem;padding-right:12rem}.lg\:py-56{padding-top:14rem;padding-bottom:14rem}.lg\:px-56{padding-left:14rem;padding-right:14rem}.lg\:py-64{padding-top:16rem;padding-bottom:16rem}.lg\:px-64{padding-left:16rem;padding-right:16rem}.lg\:py-px{padding-top:1px;padding-bottom:1px}.lg\:px-px{padding-left:1px;padding-right:1px}.lg\:pt-0{padding-top:0}.lg\:pr-0{padding-right:0}.lg\:pb-0{padding-bottom:0}.lg\:pl-0{padding-left:0}.lg\:pt-1{padding-top:.25rem}.lg\:pr-1{padding-right:.25rem}.lg\:pb-1{padding-bottom:.25rem}.lg\:pl-1{padding-left:.25rem}.lg\:pt-2{padding-top:.5rem}.lg\:pr-2{padding-right:.5rem}.lg\:pb-2{padding-bottom:.5rem}.lg\:pl-2{padding-left:.5rem}.lg\:pt-3{padding-top:.75rem}.lg\:pr-3{padding-right:.75rem}.lg\:pb-3{padding-bottom:.75rem}.lg\:pl-3{padding-left:.75rem}.lg\:pt-4{padding-top:1rem}.lg\:pr-4{padding-right:1rem}.lg\:pb-4{padding-bottom:1rem}.lg\:pl-4{padding-left:1rem}.lg\:pt-5{padding-top:1.25rem}.lg\:pr-5{padding-right:1.25rem}.lg\:pb-5{padding-bottom:1.25rem}.lg\:pl-5{padding-left:1.25rem}.lg\:pt-6{padding-top:1.5rem}.lg\:pr-6{padding-right:1.5rem}.lg\:pb-6{padding-bottom:1.5rem}.lg\:pl-6{padding-left:1.5rem}.lg\:pt-8{padding-top:2rem}.lg\:pr-8{padding-right:2rem}.lg\:pb-8{padding-bottom:2rem}.lg\:pl-8{padding-left:2rem}.lg\:pt-10{padding-top:2.5rem}.lg\:pr-10{padding-right:2.5rem}.lg\:pb-10{padding-bottom:2.5rem}.lg\:pl-10{padding-left:2.5rem}.lg\:pt-12{padding-top:3rem}.lg\:pr-12{padding-right:3rem}.lg\:pb-12{padding-bottom:3rem}.lg\:pl-12{padding-left:3rem}.lg\:pt-16{padding-top:4rem}.lg\:pr-16{padding-right:4rem}.lg\:pb-16{padding-bottom:4rem}.lg\:pl-16{padding-left:4rem}.lg\:pt-20{padding-top:5rem}.lg\:pr-20{padding-right:5rem}.lg\:pb-20{padding-bottom:5rem}.lg\:pl-20{padding-left:5rem}.lg\:pt-24{padding-top:6rem}.lg\:pr-24{padding-right:6rem}.lg\:pb-24{padding-bottom:6rem}.lg\:pl-24{padding-left:6rem}.lg\:pt-32{padding-top:8rem}.lg\:pr-32{padding-right:8rem}.lg\:pb-32{padding-bottom:8rem}.lg\:pl-32{padding-left:8rem}.lg\:pt-40{padding-top:10rem}.lg\:pr-40{padding-right:10rem}.lg\:pb-40{padding-bottom:10rem}.lg\:pl-40{padding-left:10rem}.lg\:pt-48{padding-top:12rem}.lg\:pr-48{padding-right:12rem}.lg\:pb-48{padding-bottom:12rem}.lg\:pl-48{padding-left:12rem}.lg\:pt-56{padding-top:14rem}.lg\:pr-56{padding-right:14rem}.lg\:pb-56{padding-bottom:14rem}.lg\:pl-56{padding-left:14rem}.lg\:pt-64{padding-top:16rem}.lg\:pr-64{padding-right:16rem}.lg\:pb-64{padding-bottom:16rem}.lg\:pl-64{padding-left:16rem}.lg\:pt-px{padding-top:1px}.lg\:pr-px{padding-right:1px}.lg\:pb-px{padding-bottom:1px}.lg\:pl-px{padding-left:1px}.lg\:placeholder-transparent:-ms-input-placeholder{color:transparent}.lg\:placeholder-transparent::-ms-input-placeholder{color:transparent}.lg\:placeholder-transparent::placeholder{color:transparent}.lg\:placeholder-current:-ms-input-placeholder{color:currentColor}.lg\:placeholder-current::-ms-input-placeholder{color:currentColor}.lg\:placeholder-current::placeholder{color:currentColor}.lg\:placeholder-black:-ms-input-placeholder{--placeholder-opacity:1;color:#000;color:rgba(0,0,0,var(--placeholder-opacity))}.lg\:placeholder-black::-ms-input-placeholder{--placeholder-opacity:1;color:#000;color:rgba(0,0,0,var(--placeholder-opacity))}.lg\:placeholder-black::placeholder{--placeholder-opacity:1;color:#000;color:rgba(0,0,0,var(--placeholder-opacity))}.lg\:placeholder-white:-ms-input-placeholder{--placeholder-opacity:1;color:#fff;color:rgba(255,255,255,var(--placeholder-opacity))}.lg\:placeholder-white::-ms-input-placeholder{--placeholder-opacity:1;color:#fff;color:rgba(255,255,255,var(--placeholder-opacity))}.lg\:placeholder-white::placeholder{--placeholder-opacity:1;color:#fff;color:rgba(255,255,255,var(--placeholder-opacity))}.lg\:placeholder-gray-100:-ms-input-placeholder{--placeholder-opacity:1;color:#f7fafc;color:rgba(247,250,252,var(--placeholder-opacity))}.lg\:placeholder-gray-100::-ms-input-placeholder{--placeholder-opacity:1;color:#f7fafc;color:rgba(247,250,252,var(--placeholder-opacity))}.lg\:placeholder-gray-100::placeholder{--placeholder-opacity:1;color:#f7fafc;color:rgba(247,250,252,var(--placeholder-opacity))}.lg\:placeholder-gray-200:-ms-input-placeholder{--placeholder-opacity:1;color:#edf2f7;color:rgba(237,242,247,var(--placeholder-opacity))}.lg\:placeholder-gray-200::-ms-input-placeholder{--placeholder-opacity:1;color:#edf2f7;color:rgba(237,242,247,var(--placeholder-opacity))}.lg\:placeholder-gray-200::placeholder{--placeholder-opacity:1;color:#edf2f7;color:rgba(237,242,247,var(--placeholder-opacity))}.lg\:placeholder-gray-300:-ms-input-placeholder{--placeholder-opacity:1;color:#e2e8f0;color:rgba(226,232,240,var(--placeholder-opacity))}.lg\:placeholder-gray-300::-ms-input-placeholder{--placeholder-opacity:1;color:#e2e8f0;color:rgba(226,232,240,var(--placeholder-opacity))}.lg\:placeholder-gray-300::placeholder{--placeholder-opacity:1;color:#e2e8f0;color:rgba(226,232,240,var(--placeholder-opacity))}.lg\:placeholder-gray-400:-ms-input-placeholder{--placeholder-opacity:1;color:#cbd5e0;color:rgba(203,213,224,var(--placeholder-opacity))}.lg\:placeholder-gray-400::-ms-input-placeholder{--placeholder-opacity:1;color:#cbd5e0;color:rgba(203,213,224,var(--placeholder-opacity))}.lg\:placeholder-gray-400::placeholder{--placeholder-opacity:1;color:#cbd5e0;color:rgba(203,213,224,var(--placeholder-opacity))}.lg\:placeholder-gray-500:-ms-input-placeholder{--placeholder-opacity:1;color:#a0aec0;color:rgba(160,174,192,var(--placeholder-opacity))}.lg\:placeholder-gray-500::-ms-input-placeholder{--placeholder-opacity:1;color:#a0aec0;color:rgba(160,174,192,var(--placeholder-opacity))}.lg\:placeholder-gray-500::placeholder{--placeholder-opacity:1;color:#a0aec0;color:rgba(160,174,192,var(--placeholder-opacity))}.lg\:placeholder-gray-600:-ms-input-placeholder{--placeholder-opacity:1;color:#718096;color:rgba(113,128,150,var(--placeholder-opacity))}.lg\:placeholder-gray-600::-ms-input-placeholder{--placeholder-opacity:1;color:#718096;color:rgba(113,128,150,var(--placeholder-opacity))}.lg\:placeholder-gray-600::placeholder{--placeholder-opacity:1;color:#718096;color:rgba(113,128,150,var(--placeholder-opacity))}.lg\:placeholder-gray-700:-ms-input-placeholder{--placeholder-opacity:1;color:#4a5568;color:rgba(74,85,104,var(--placeholder-opacity))}.lg\:placeholder-gray-700::-ms-input-placeholder{--placeholder-opacity:1;color:#4a5568;color:rgba(74,85,104,var(--placeholder-opacity))}.lg\:placeholder-gray-700::placeholder{--placeholder-opacity:1;color:#4a5568;color:rgba(74,85,104,var(--placeholder-opacity))}.lg\:placeholder-gray-800:-ms-input-placeholder{--placeholder-opacity:1;color:#2d3748;color:rgba(45,55,72,var(--placeholder-opacity))}.lg\:placeholder-gray-800::-ms-input-placeholder{--placeholder-opacity:1;color:#2d3748;color:rgba(45,55,72,var(--placeholder-opacity))}.lg\:placeholder-gray-800::placeholder{--placeholder-opacity:1;color:#2d3748;color:rgba(45,55,72,var(--placeholder-opacity))}.lg\:placeholder-gray-900:-ms-input-placeholder{--placeholder-opacity:1;color:#1a202c;color:rgba(26,32,44,var(--placeholder-opacity))}.lg\:placeholder-gray-900::-ms-input-placeholder{--placeholder-opacity:1;color:#1a202c;color:rgba(26,32,44,var(--placeholder-opacity))}.lg\:placeholder-gray-900::placeholder{--placeholder-opacity:1;color:#1a202c;color:rgba(26,32,44,var(--placeholder-opacity))}.lg\:placeholder-red-100:-ms-input-placeholder{--placeholder-opacity:1;color:#fff5f5;color:rgba(255,245,245,var(--placeholder-opacity))}.lg\:placeholder-red-100::-ms-input-placeholder{--placeholder-opacity:1;color:#fff5f5;color:rgba(255,245,245,var(--placeholder-opacity))}.lg\:placeholder-red-100::placeholder{--placeholder-opacity:1;color:#fff5f5;color:rgba(255,245,245,var(--placeholder-opacity))}.lg\:placeholder-red-200:-ms-input-placeholder{--placeholder-opacity:1;color:#fed7d7;color:rgba(254,215,215,var(--placeholder-opacity))}.lg\:placeholder-red-200::-ms-input-placeholder{--placeholder-opacity:1;color:#fed7d7;color:rgba(254,215,215,var(--placeholder-opacity))}.lg\:placeholder-red-200::placeholder{--placeholder-opacity:1;color:#fed7d7;color:rgba(254,215,215,var(--placeholder-opacity))}.lg\:placeholder-red-300:-ms-input-placeholder{--placeholder-opacity:1;color:#feb2b2;color:rgba(254,178,178,var(--placeholder-opacity))}.lg\:placeholder-red-300::-ms-input-placeholder{--placeholder-opacity:1;color:#feb2b2;color:rgba(254,178,178,var(--placeholder-opacity))}.lg\:placeholder-red-300::placeholder{--placeholder-opacity:1;color:#feb2b2;color:rgba(254,178,178,var(--placeholder-opacity))}.lg\:placeholder-red-400:-ms-input-placeholder{--placeholder-opacity:1;color:#fc8181;color:rgba(252,129,129,var(--placeholder-opacity))}.lg\:placeholder-red-400::-ms-input-placeholder{--placeholder-opacity:1;color:#fc8181;color:rgba(252,129,129,var(--placeholder-opacity))}.lg\:placeholder-red-400::placeholder{--placeholder-opacity:1;color:#fc8181;color:rgba(252,129,129,var(--placeholder-opacity))}.lg\:placeholder-red-500:-ms-input-placeholder{--placeholder-opacity:1;color:#f56565;color:rgba(245,101,101,var(--placeholder-opacity))}.lg\:placeholder-red-500::-ms-input-placeholder{--placeholder-opacity:1;color:#f56565;color:rgba(245,101,101,var(--placeholder-opacity))}.lg\:placeholder-red-500::placeholder{--placeholder-opacity:1;color:#f56565;color:rgba(245,101,101,var(--placeholder-opacity))}.lg\:placeholder-red-600:-ms-input-placeholder{--placeholder-opacity:1;color:#e53e3e;color:rgba(229,62,62,var(--placeholder-opacity))}.lg\:placeholder-red-600::-ms-input-placeholder{--placeholder-opacity:1;color:#e53e3e;color:rgba(229,62,62,var(--placeholder-opacity))}.lg\:placeholder-red-600::placeholder{--placeholder-opacity:1;color:#e53e3e;color:rgba(229,62,62,var(--placeholder-opacity))}.lg\:placeholder-red-700:-ms-input-placeholder{--placeholder-opacity:1;color:#c53030;color:rgba(197,48,48,var(--placeholder-opacity))}.lg\:placeholder-red-700::-ms-input-placeholder{--placeholder-opacity:1;color:#c53030;color:rgba(197,48,48,var(--placeholder-opacity))}.lg\:placeholder-red-700::placeholder{--placeholder-opacity:1;color:#c53030;color:rgba(197,48,48,var(--placeholder-opacity))}.lg\:placeholder-red-800:-ms-input-placeholder{--placeholder-opacity:1;color:#9b2c2c;color:rgba(155,44,44,var(--placeholder-opacity))}.lg\:placeholder-red-800::-ms-input-placeholder{--placeholder-opacity:1;color:#9b2c2c;color:rgba(155,44,44,var(--placeholder-opacity))}.lg\:placeholder-red-800::placeholder{--placeholder-opacity:1;color:#9b2c2c;color:rgba(155,44,44,var(--placeholder-opacity))}.lg\:placeholder-red-900:-ms-input-placeholder{--placeholder-opacity:1;color:#742a2a;color:rgba(116,42,42,var(--placeholder-opacity))}.lg\:placeholder-red-900::-ms-input-placeholder{--placeholder-opacity:1;color:#742a2a;color:rgba(116,42,42,var(--placeholder-opacity))}.lg\:placeholder-red-900::placeholder{--placeholder-opacity:1;color:#742a2a;color:rgba(116,42,42,var(--placeholder-opacity))}.lg\:placeholder-orange-100:-ms-input-placeholder{--placeholder-opacity:1;color:#fffaf0;color:rgba(255,250,240,var(--placeholder-opacity))}.lg\:placeholder-orange-100::-ms-input-placeholder{--placeholder-opacity:1;color:#fffaf0;color:rgba(255,250,240,var(--placeholder-opacity))}.lg\:placeholder-orange-100::placeholder{--placeholder-opacity:1;color:#fffaf0;color:rgba(255,250,240,var(--placeholder-opacity))}.lg\:placeholder-orange-200:-ms-input-placeholder{--placeholder-opacity:1;color:#feebc8;color:rgba(254,235,200,var(--placeholder-opacity))}.lg\:placeholder-orange-200::-ms-input-placeholder{--placeholder-opacity:1;color:#feebc8;color:rgba(254,235,200,var(--placeholder-opacity))}.lg\:placeholder-orange-200::placeholder{--placeholder-opacity:1;color:#feebc8;color:rgba(254,235,200,var(--placeholder-opacity))}.lg\:placeholder-orange-300:-ms-input-placeholder{--placeholder-opacity:1;color:#fbd38d;color:rgba(251,211,141,var(--placeholder-opacity))}.lg\:placeholder-orange-300::-ms-input-placeholder{--placeholder-opacity:1;color:#fbd38d;color:rgba(251,211,141,var(--placeholder-opacity))}.lg\:placeholder-orange-300::placeholder{--placeholder-opacity:1;color:#fbd38d;color:rgba(251,211,141,var(--placeholder-opacity))}.lg\:placeholder-orange-400:-ms-input-placeholder{--placeholder-opacity:1;color:#f6ad55;color:rgba(246,173,85,var(--placeholder-opacity))}.lg\:placeholder-orange-400::-ms-input-placeholder{--placeholder-opacity:1;color:#f6ad55;color:rgba(246,173,85,var(--placeholder-opacity))}.lg\:placeholder-orange-400::placeholder{--placeholder-opacity:1;color:#f6ad55;color:rgba(246,173,85,var(--placeholder-opacity))}.lg\:placeholder-orange-500:-ms-input-placeholder{--placeholder-opacity:1;color:#ed8936;color:rgba(237,137,54,var(--placeholder-opacity))}.lg\:placeholder-orange-500::-ms-input-placeholder{--placeholder-opacity:1;color:#ed8936;color:rgba(237,137,54,var(--placeholder-opacity))}.lg\:placeholder-orange-500::placeholder{--placeholder-opacity:1;color:#ed8936;color:rgba(237,137,54,var(--placeholder-opacity))}.lg\:placeholder-orange-600:-ms-input-placeholder{--placeholder-opacity:1;color:#dd6b20;color:rgba(221,107,32,var(--placeholder-opacity))}.lg\:placeholder-orange-600::-ms-input-placeholder{--placeholder-opacity:1;color:#dd6b20;color:rgba(221,107,32,var(--placeholder-opacity))}.lg\:placeholder-orange-600::placeholder{--placeholder-opacity:1;color:#dd6b20;color:rgba(221,107,32,var(--placeholder-opacity))}.lg\:placeholder-orange-700:-ms-input-placeholder{--placeholder-opacity:1;color:#c05621;color:rgba(192,86,33,var(--placeholder-opacity))}.lg\:placeholder-orange-700::-ms-input-placeholder{--placeholder-opacity:1;color:#c05621;color:rgba(192,86,33,var(--placeholder-opacity))}.lg\:placeholder-orange-700::placeholder{--placeholder-opacity:1;color:#c05621;color:rgba(192,86,33,var(--placeholder-opacity))}.lg\:placeholder-orange-800:-ms-input-placeholder{--placeholder-opacity:1;color:#9c4221;color:rgba(156,66,33,var(--placeholder-opacity))}.lg\:placeholder-orange-800::-ms-input-placeholder{--placeholder-opacity:1;color:#9c4221;color:rgba(156,66,33,var(--placeholder-opacity))}.lg\:placeholder-orange-800::placeholder{--placeholder-opacity:1;color:#9c4221;color:rgba(156,66,33,var(--placeholder-opacity))}.lg\:placeholder-orange-900:-ms-input-placeholder{--placeholder-opacity:1;color:#7b341e;color:rgba(123,52,30,var(--placeholder-opacity))}.lg\:placeholder-orange-900::-ms-input-placeholder{--placeholder-opacity:1;color:#7b341e;color:rgba(123,52,30,var(--placeholder-opacity))}.lg\:placeholder-orange-900::placeholder{--placeholder-opacity:1;color:#7b341e;color:rgba(123,52,30,var(--placeholder-opacity))}.lg\:placeholder-yellow-100:-ms-input-placeholder{--placeholder-opacity:1;color:ivory;color:rgba(255,255,240,var(--placeholder-opacity))}.lg\:placeholder-yellow-100::-ms-input-placeholder{--placeholder-opacity:1;color:ivory;color:rgba(255,255,240,var(--placeholder-opacity))}.lg\:placeholder-yellow-100::placeholder{--placeholder-opacity:1;color:ivory;color:rgba(255,255,240,var(--placeholder-opacity))}.lg\:placeholder-yellow-200:-ms-input-placeholder{--placeholder-opacity:1;color:#fefcbf;color:rgba(254,252,191,var(--placeholder-opacity))}.lg\:placeholder-yellow-200::-ms-input-placeholder{--placeholder-opacity:1;color:#fefcbf;color:rgba(254,252,191,var(--placeholder-opacity))}.lg\:placeholder-yellow-200::placeholder{--placeholder-opacity:1;color:#fefcbf;color:rgba(254,252,191,var(--placeholder-opacity))}.lg\:placeholder-yellow-300:-ms-input-placeholder{--placeholder-opacity:1;color:#faf089;color:rgba(250,240,137,var(--placeholder-opacity))}.lg\:placeholder-yellow-300::-ms-input-placeholder{--placeholder-opacity:1;color:#faf089;color:rgba(250,240,137,var(--placeholder-opacity))}.lg\:placeholder-yellow-300::placeholder{--placeholder-opacity:1;color:#faf089;color:rgba(250,240,137,var(--placeholder-opacity))}.lg\:placeholder-yellow-400:-ms-input-placeholder{--placeholder-opacity:1;color:#f6e05e;color:rgba(246,224,94,var(--placeholder-opacity))}.lg\:placeholder-yellow-400::-ms-input-placeholder{--placeholder-opacity:1;color:#f6e05e;color:rgba(246,224,94,var(--placeholder-opacity))}.lg\:placeholder-yellow-400::placeholder{--placeholder-opacity:1;color:#f6e05e;color:rgba(246,224,94,var(--placeholder-opacity))}.lg\:placeholder-yellow-500:-ms-input-placeholder{--placeholder-opacity:1;color:#ecc94b;color:rgba(236,201,75,var(--placeholder-opacity))}.lg\:placeholder-yellow-500::-ms-input-placeholder{--placeholder-opacity:1;color:#ecc94b;color:rgba(236,201,75,var(--placeholder-opacity))}.lg\:placeholder-yellow-500::placeholder{--placeholder-opacity:1;color:#ecc94b;color:rgba(236,201,75,var(--placeholder-opacity))}.lg\:placeholder-yellow-600:-ms-input-placeholder{--placeholder-opacity:1;color:#d69e2e;color:rgba(214,158,46,var(--placeholder-opacity))}.lg\:placeholder-yellow-600::-ms-input-placeholder{--placeholder-opacity:1;color:#d69e2e;color:rgba(214,158,46,var(--placeholder-opacity))}.lg\:placeholder-yellow-600::placeholder{--placeholder-opacity:1;color:#d69e2e;color:rgba(214,158,46,var(--placeholder-opacity))}.lg\:placeholder-yellow-700:-ms-input-placeholder{--placeholder-opacity:1;color:#b7791f;color:rgba(183,121,31,var(--placeholder-opacity))}.lg\:placeholder-yellow-700::-ms-input-placeholder{--placeholder-opacity:1;color:#b7791f;color:rgba(183,121,31,var(--placeholder-opacity))}.lg\:placeholder-yellow-700::placeholder{--placeholder-opacity:1;color:#b7791f;color:rgba(183,121,31,var(--placeholder-opacity))}.lg\:placeholder-yellow-800:-ms-input-placeholder{--placeholder-opacity:1;color:#975a16;color:rgba(151,90,22,var(--placeholder-opacity))}.lg\:placeholder-yellow-800::-ms-input-placeholder{--placeholder-opacity:1;color:#975a16;color:rgba(151,90,22,var(--placeholder-opacity))}.lg\:placeholder-yellow-800::placeholder{--placeholder-opacity:1;color:#975a16;color:rgba(151,90,22,var(--placeholder-opacity))}.lg\:placeholder-yellow-900:-ms-input-placeholder{--placeholder-opacity:1;color:#744210;color:rgba(116,66,16,var(--placeholder-opacity))}.lg\:placeholder-yellow-900::-ms-input-placeholder{--placeholder-opacity:1;color:#744210;color:rgba(116,66,16,var(--placeholder-opacity))}.lg\:placeholder-yellow-900::placeholder{--placeholder-opacity:1;color:#744210;color:rgba(116,66,16,var(--placeholder-opacity))}.lg\:placeholder-green-100:-ms-input-placeholder{--placeholder-opacity:1;color:#f0fff4;color:rgba(240,255,244,var(--placeholder-opacity))}.lg\:placeholder-green-100::-ms-input-placeholder{--placeholder-opacity:1;color:#f0fff4;color:rgba(240,255,244,var(--placeholder-opacity))}.lg\:placeholder-green-100::placeholder{--placeholder-opacity:1;color:#f0fff4;color:rgba(240,255,244,var(--placeholder-opacity))}.lg\:placeholder-green-200:-ms-input-placeholder{--placeholder-opacity:1;color:#c6f6d5;color:rgba(198,246,213,var(--placeholder-opacity))}.lg\:placeholder-green-200::-ms-input-placeholder{--placeholder-opacity:1;color:#c6f6d5;color:rgba(198,246,213,var(--placeholder-opacity))}.lg\:placeholder-green-200::placeholder{--placeholder-opacity:1;color:#c6f6d5;color:rgba(198,246,213,var(--placeholder-opacity))}.lg\:placeholder-green-300:-ms-input-placeholder{--placeholder-opacity:1;color:#9ae6b4;color:rgba(154,230,180,var(--placeholder-opacity))}.lg\:placeholder-green-300::-ms-input-placeholder{--placeholder-opacity:1;color:#9ae6b4;color:rgba(154,230,180,var(--placeholder-opacity))}.lg\:placeholder-green-300::placeholder{--placeholder-opacity:1;color:#9ae6b4;color:rgba(154,230,180,var(--placeholder-opacity))}.lg\:placeholder-green-400:-ms-input-placeholder{--placeholder-opacity:1;color:#68d391;color:rgba(104,211,145,var(--placeholder-opacity))}.lg\:placeholder-green-400::-ms-input-placeholder{--placeholder-opacity:1;color:#68d391;color:rgba(104,211,145,var(--placeholder-opacity))}.lg\:placeholder-green-400::placeholder{--placeholder-opacity:1;color:#68d391;color:rgba(104,211,145,var(--placeholder-opacity))}.lg\:placeholder-green-500:-ms-input-placeholder{--placeholder-opacity:1;color:#48bb78;color:rgba(72,187,120,var(--placeholder-opacity))}.lg\:placeholder-green-500::-ms-input-placeholder{--placeholder-opacity:1;color:#48bb78;color:rgba(72,187,120,var(--placeholder-opacity))}.lg\:placeholder-green-500::placeholder{--placeholder-opacity:1;color:#48bb78;color:rgba(72,187,120,var(--placeholder-opacity))}.lg\:placeholder-green-600:-ms-input-placeholder{--placeholder-opacity:1;color:#38a169;color:rgba(56,161,105,var(--placeholder-opacity))}.lg\:placeholder-green-600::-ms-input-placeholder{--placeholder-opacity:1;color:#38a169;color:rgba(56,161,105,var(--placeholder-opacity))}.lg\:placeholder-green-600::placeholder{--placeholder-opacity:1;color:#38a169;color:rgba(56,161,105,var(--placeholder-opacity))}.lg\:placeholder-green-700:-ms-input-placeholder{--placeholder-opacity:1;color:#2f855a;color:rgba(47,133,90,var(--placeholder-opacity))}.lg\:placeholder-green-700::-ms-input-placeholder{--placeholder-opacity:1;color:#2f855a;color:rgba(47,133,90,var(--placeholder-opacity))}.lg\:placeholder-green-700::placeholder{--placeholder-opacity:1;color:#2f855a;color:rgba(47,133,90,var(--placeholder-opacity))}.lg\:placeholder-green-800:-ms-input-placeholder{--placeholder-opacity:1;color:#276749;color:rgba(39,103,73,var(--placeholder-opacity))}.lg\:placeholder-green-800::-ms-input-placeholder{--placeholder-opacity:1;color:#276749;color:rgba(39,103,73,var(--placeholder-opacity))}.lg\:placeholder-green-800::placeholder{--placeholder-opacity:1;color:#276749;color:rgba(39,103,73,var(--placeholder-opacity))}.lg\:placeholder-green-900:-ms-input-placeholder{--placeholder-opacity:1;color:#22543d;color:rgba(34,84,61,var(--placeholder-opacity))}.lg\:placeholder-green-900::-ms-input-placeholder{--placeholder-opacity:1;color:#22543d;color:rgba(34,84,61,var(--placeholder-opacity))}.lg\:placeholder-green-900::placeholder{--placeholder-opacity:1;color:#22543d;color:rgba(34,84,61,var(--placeholder-opacity))}.lg\:placeholder-teal-100:-ms-input-placeholder{--placeholder-opacity:1;color:#e6fffa;color:rgba(230,255,250,var(--placeholder-opacity))}.lg\:placeholder-teal-100::-ms-input-placeholder{--placeholder-opacity:1;color:#e6fffa;color:rgba(230,255,250,var(--placeholder-opacity))}.lg\:placeholder-teal-100::placeholder{--placeholder-opacity:1;color:#e6fffa;color:rgba(230,255,250,var(--placeholder-opacity))}.lg\:placeholder-teal-200:-ms-input-placeholder{--placeholder-opacity:1;color:#b2f5ea;color:rgba(178,245,234,var(--placeholder-opacity))}.lg\:placeholder-teal-200::-ms-input-placeholder{--placeholder-opacity:1;color:#b2f5ea;color:rgba(178,245,234,var(--placeholder-opacity))}.lg\:placeholder-teal-200::placeholder{--placeholder-opacity:1;color:#b2f5ea;color:rgba(178,245,234,var(--placeholder-opacity))}.lg\:placeholder-teal-300:-ms-input-placeholder{--placeholder-opacity:1;color:#81e6d9;color:rgba(129,230,217,var(--placeholder-opacity))}.lg\:placeholder-teal-300::-ms-input-placeholder{--placeholder-opacity:1;color:#81e6d9;color:rgba(129,230,217,var(--placeholder-opacity))}.lg\:placeholder-teal-300::placeholder{--placeholder-opacity:1;color:#81e6d9;color:rgba(129,230,217,var(--placeholder-opacity))}.lg\:placeholder-teal-400:-ms-input-placeholder{--placeholder-opacity:1;color:#4fd1c5;color:rgba(79,209,197,var(--placeholder-opacity))}.lg\:placeholder-teal-400::-ms-input-placeholder{--placeholder-opacity:1;color:#4fd1c5;color:rgba(79,209,197,var(--placeholder-opacity))}.lg\:placeholder-teal-400::placeholder{--placeholder-opacity:1;color:#4fd1c5;color:rgba(79,209,197,var(--placeholder-opacity))}.lg\:placeholder-teal-500:-ms-input-placeholder{--placeholder-opacity:1;color:#38b2ac;color:rgba(56,178,172,var(--placeholder-opacity))}.lg\:placeholder-teal-500::-ms-input-placeholder{--placeholder-opacity:1;color:#38b2ac;color:rgba(56,178,172,var(--placeholder-opacity))}.lg\:placeholder-teal-500::placeholder{--placeholder-opacity:1;color:#38b2ac;color:rgba(56,178,172,var(--placeholder-opacity))}.lg\:placeholder-teal-600:-ms-input-placeholder{--placeholder-opacity:1;color:#319795;color:rgba(49,151,149,var(--placeholder-opacity))}.lg\:placeholder-teal-600::-ms-input-placeholder{--placeholder-opacity:1;color:#319795;color:rgba(49,151,149,var(--placeholder-opacity))}.lg\:placeholder-teal-600::placeholder{--placeholder-opacity:1;color:#319795;color:rgba(49,151,149,var(--placeholder-opacity))}.lg\:placeholder-teal-700:-ms-input-placeholder{--placeholder-opacity:1;color:#2c7a7b;color:rgba(44,122,123,var(--placeholder-opacity))}.lg\:placeholder-teal-700::-ms-input-placeholder{--placeholder-opacity:1;color:#2c7a7b;color:rgba(44,122,123,var(--placeholder-opacity))}.lg\:placeholder-teal-700::placeholder{--placeholder-opacity:1;color:#2c7a7b;color:rgba(44,122,123,var(--placeholder-opacity))}.lg\:placeholder-teal-800:-ms-input-placeholder{--placeholder-opacity:1;color:#285e61;color:rgba(40,94,97,var(--placeholder-opacity))}.lg\:placeholder-teal-800::-ms-input-placeholder{--placeholder-opacity:1;color:#285e61;color:rgba(40,94,97,var(--placeholder-opacity))}.lg\:placeholder-teal-800::placeholder{--placeholder-opacity:1;color:#285e61;color:rgba(40,94,97,var(--placeholder-opacity))}.lg\:placeholder-teal-900:-ms-input-placeholder{--placeholder-opacity:1;color:#234e52;color:rgba(35,78,82,var(--placeholder-opacity))}.lg\:placeholder-teal-900::-ms-input-placeholder{--placeholder-opacity:1;color:#234e52;color:rgba(35,78,82,var(--placeholder-opacity))}.lg\:placeholder-teal-900::placeholder{--placeholder-opacity:1;color:#234e52;color:rgba(35,78,82,var(--placeholder-opacity))}.lg\:placeholder-blue-100:-ms-input-placeholder{--placeholder-opacity:1;color:#ebf8ff;color:rgba(235,248,255,var(--placeholder-opacity))}.lg\:placeholder-blue-100::-ms-input-placeholder{--placeholder-opacity:1;color:#ebf8ff;color:rgba(235,248,255,var(--placeholder-opacity))}.lg\:placeholder-blue-100::placeholder{--placeholder-opacity:1;color:#ebf8ff;color:rgba(235,248,255,var(--placeholder-opacity))}.lg\:placeholder-blue-200:-ms-input-placeholder{--placeholder-opacity:1;color:#bee3f8;color:rgba(190,227,248,var(--placeholder-opacity))}.lg\:placeholder-blue-200::-ms-input-placeholder{--placeholder-opacity:1;color:#bee3f8;color:rgba(190,227,248,var(--placeholder-opacity))}.lg\:placeholder-blue-200::placeholder{--placeholder-opacity:1;color:#bee3f8;color:rgba(190,227,248,var(--placeholder-opacity))}.lg\:placeholder-blue-300:-ms-input-placeholder{--placeholder-opacity:1;color:#90cdf4;color:rgba(144,205,244,var(--placeholder-opacity))}.lg\:placeholder-blue-300::-ms-input-placeholder{--placeholder-opacity:1;color:#90cdf4;color:rgba(144,205,244,var(--placeholder-opacity))}.lg\:placeholder-blue-300::placeholder{--placeholder-opacity:1;color:#90cdf4;color:rgba(144,205,244,var(--placeholder-opacity))}.lg\:placeholder-blue-400:-ms-input-placeholder{--placeholder-opacity:1;color:#63b3ed;color:rgba(99,179,237,var(--placeholder-opacity))}.lg\:placeholder-blue-400::-ms-input-placeholder{--placeholder-opacity:1;color:#63b3ed;color:rgba(99,179,237,var(--placeholder-opacity))}.lg\:placeholder-blue-400::placeholder{--placeholder-opacity:1;color:#63b3ed;color:rgba(99,179,237,var(--placeholder-opacity))}.lg\:placeholder-blue-500:-ms-input-placeholder{--placeholder-opacity:1;color:#4299e1;color:rgba(66,153,225,var(--placeholder-opacity))}.lg\:placeholder-blue-500::-ms-input-placeholder{--placeholder-opacity:1;color:#4299e1;color:rgba(66,153,225,var(--placeholder-opacity))}.lg\:placeholder-blue-500::placeholder{--placeholder-opacity:1;color:#4299e1;color:rgba(66,153,225,var(--placeholder-opacity))}.lg\:placeholder-blue-600:-ms-input-placeholder{--placeholder-opacity:1;color:#3182ce;color:rgba(49,130,206,var(--placeholder-opacity))}.lg\:placeholder-blue-600::-ms-input-placeholder{--placeholder-opacity:1;color:#3182ce;color:rgba(49,130,206,var(--placeholder-opacity))}.lg\:placeholder-blue-600::placeholder{--placeholder-opacity:1;color:#3182ce;color:rgba(49,130,206,var(--placeholder-opacity))}.lg\:placeholder-blue-700:-ms-input-placeholder{--placeholder-opacity:1;color:#2b6cb0;color:rgba(43,108,176,var(--placeholder-opacity))}.lg\:placeholder-blue-700::-ms-input-placeholder{--placeholder-opacity:1;color:#2b6cb0;color:rgba(43,108,176,var(--placeholder-opacity))}.lg\:placeholder-blue-700::placeholder{--placeholder-opacity:1;color:#2b6cb0;color:rgba(43,108,176,var(--placeholder-opacity))}.lg\:placeholder-blue-800:-ms-input-placeholder{--placeholder-opacity:1;color:#2c5282;color:rgba(44,82,130,var(--placeholder-opacity))}.lg\:placeholder-blue-800::-ms-input-placeholder{--placeholder-opacity:1;color:#2c5282;color:rgba(44,82,130,var(--placeholder-opacity))}.lg\:placeholder-blue-800::placeholder{--placeholder-opacity:1;color:#2c5282;color:rgba(44,82,130,var(--placeholder-opacity))}.lg\:placeholder-blue-900:-ms-input-placeholder{--placeholder-opacity:1;color:#2a4365;color:rgba(42,67,101,var(--placeholder-opacity))}.lg\:placeholder-blue-900::-ms-input-placeholder{--placeholder-opacity:1;color:#2a4365;color:rgba(42,67,101,var(--placeholder-opacity))}.lg\:placeholder-blue-900::placeholder{--placeholder-opacity:1;color:#2a4365;color:rgba(42,67,101,var(--placeholder-opacity))}.lg\:placeholder-indigo-100:-ms-input-placeholder{--placeholder-opacity:1;color:#ebf4ff;color:rgba(235,244,255,var(--placeholder-opacity))}.lg\:placeholder-indigo-100::-ms-input-placeholder{--placeholder-opacity:1;color:#ebf4ff;color:rgba(235,244,255,var(--placeholder-opacity))}.lg\:placeholder-indigo-100::placeholder{--placeholder-opacity:1;color:#ebf4ff;color:rgba(235,244,255,var(--placeholder-opacity))}.lg\:placeholder-indigo-200:-ms-input-placeholder{--placeholder-opacity:1;color:#c3dafe;color:rgba(195,218,254,var(--placeholder-opacity))}.lg\:placeholder-indigo-200::-ms-input-placeholder{--placeholder-opacity:1;color:#c3dafe;color:rgba(195,218,254,var(--placeholder-opacity))}.lg\:placeholder-indigo-200::placeholder{--placeholder-opacity:1;color:#c3dafe;color:rgba(195,218,254,var(--placeholder-opacity))}.lg\:placeholder-indigo-300:-ms-input-placeholder{--placeholder-opacity:1;color:#a3bffa;color:rgba(163,191,250,var(--placeholder-opacity))}.lg\:placeholder-indigo-300::-ms-input-placeholder{--placeholder-opacity:1;color:#a3bffa;color:rgba(163,191,250,var(--placeholder-opacity))}.lg\:placeholder-indigo-300::placeholder{--placeholder-opacity:1;color:#a3bffa;color:rgba(163,191,250,var(--placeholder-opacity))}.lg\:placeholder-indigo-400:-ms-input-placeholder{--placeholder-opacity:1;color:#7f9cf5;color:rgba(127,156,245,var(--placeholder-opacity))}.lg\:placeholder-indigo-400::-ms-input-placeholder{--placeholder-opacity:1;color:#7f9cf5;color:rgba(127,156,245,var(--placeholder-opacity))}.lg\:placeholder-indigo-400::placeholder{--placeholder-opacity:1;color:#7f9cf5;color:rgba(127,156,245,var(--placeholder-opacity))}.lg\:placeholder-indigo-500:-ms-input-placeholder{--placeholder-opacity:1;color:#667eea;color:rgba(102,126,234,var(--placeholder-opacity))}.lg\:placeholder-indigo-500::-ms-input-placeholder{--placeholder-opacity:1;color:#667eea;color:rgba(102,126,234,var(--placeholder-opacity))}.lg\:placeholder-indigo-500::placeholder{--placeholder-opacity:1;color:#667eea;color:rgba(102,126,234,var(--placeholder-opacity))}.lg\:placeholder-indigo-600:-ms-input-placeholder{--placeholder-opacity:1;color:#5a67d8;color:rgba(90,103,216,var(--placeholder-opacity))}.lg\:placeholder-indigo-600::-ms-input-placeholder{--placeholder-opacity:1;color:#5a67d8;color:rgba(90,103,216,var(--placeholder-opacity))}.lg\:placeholder-indigo-600::placeholder{--placeholder-opacity:1;color:#5a67d8;color:rgba(90,103,216,var(--placeholder-opacity))}.lg\:placeholder-indigo-700:-ms-input-placeholder{--placeholder-opacity:1;color:#4c51bf;color:rgba(76,81,191,var(--placeholder-opacity))}.lg\:placeholder-indigo-700::-ms-input-placeholder{--placeholder-opacity:1;color:#4c51bf;color:rgba(76,81,191,var(--placeholder-opacity))}.lg\:placeholder-indigo-700::placeholder{--placeholder-opacity:1;color:#4c51bf;color:rgba(76,81,191,var(--placeholder-opacity))}.lg\:placeholder-indigo-800:-ms-input-placeholder{--placeholder-opacity:1;color:#434190;color:rgba(67,65,144,var(--placeholder-opacity))}.lg\:placeholder-indigo-800::-ms-input-placeholder{--placeholder-opacity:1;color:#434190;color:rgba(67,65,144,var(--placeholder-opacity))}.lg\:placeholder-indigo-800::placeholder{--placeholder-opacity:1;color:#434190;color:rgba(67,65,144,var(--placeholder-opacity))}.lg\:placeholder-indigo-900:-ms-input-placeholder{--placeholder-opacity:1;color:#3c366b;color:rgba(60,54,107,var(--placeholder-opacity))}.lg\:placeholder-indigo-900::-ms-input-placeholder{--placeholder-opacity:1;color:#3c366b;color:rgba(60,54,107,var(--placeholder-opacity))}.lg\:placeholder-indigo-900::placeholder{--placeholder-opacity:1;color:#3c366b;color:rgba(60,54,107,var(--placeholder-opacity))}.lg\:placeholder-purple-100:-ms-input-placeholder{--placeholder-opacity:1;color:#faf5ff;color:rgba(250,245,255,var(--placeholder-opacity))}.lg\:placeholder-purple-100::-ms-input-placeholder{--placeholder-opacity:1;color:#faf5ff;color:rgba(250,245,255,var(--placeholder-opacity))}.lg\:placeholder-purple-100::placeholder{--placeholder-opacity:1;color:#faf5ff;color:rgba(250,245,255,var(--placeholder-opacity))}.lg\:placeholder-purple-200:-ms-input-placeholder{--placeholder-opacity:1;color:#e9d8fd;color:rgba(233,216,253,var(--placeholder-opacity))}.lg\:placeholder-purple-200::-ms-input-placeholder{--placeholder-opacity:1;color:#e9d8fd;color:rgba(233,216,253,var(--placeholder-opacity))}.lg\:placeholder-purple-200::placeholder{--placeholder-opacity:1;color:#e9d8fd;color:rgba(233,216,253,var(--placeholder-opacity))}.lg\:placeholder-purple-300:-ms-input-placeholder{--placeholder-opacity:1;color:#d6bcfa;color:rgba(214,188,250,var(--placeholder-opacity))}.lg\:placeholder-purple-300::-ms-input-placeholder{--placeholder-opacity:1;color:#d6bcfa;color:rgba(214,188,250,var(--placeholder-opacity))}.lg\:placeholder-purple-300::placeholder{--placeholder-opacity:1;color:#d6bcfa;color:rgba(214,188,250,var(--placeholder-opacity))}.lg\:placeholder-purple-400:-ms-input-placeholder{--placeholder-opacity:1;color:#b794f4;color:rgba(183,148,244,var(--placeholder-opacity))}.lg\:placeholder-purple-400::-ms-input-placeholder{--placeholder-opacity:1;color:#b794f4;color:rgba(183,148,244,var(--placeholder-opacity))}.lg\:placeholder-purple-400::placeholder{--placeholder-opacity:1;color:#b794f4;color:rgba(183,148,244,var(--placeholder-opacity))}.lg\:placeholder-purple-500:-ms-input-placeholder{--placeholder-opacity:1;color:#9f7aea;color:rgba(159,122,234,var(--placeholder-opacity))}.lg\:placeholder-purple-500::-ms-input-placeholder{--placeholder-opacity:1;color:#9f7aea;color:rgba(159,122,234,var(--placeholder-opacity))}.lg\:placeholder-purple-500::placeholder{--placeholder-opacity:1;color:#9f7aea;color:rgba(159,122,234,var(--placeholder-opacity))}.lg\:placeholder-purple-600:-ms-input-placeholder{--placeholder-opacity:1;color:#805ad5;color:rgba(128,90,213,var(--placeholder-opacity))}.lg\:placeholder-purple-600::-ms-input-placeholder{--placeholder-opacity:1;color:#805ad5;color:rgba(128,90,213,var(--placeholder-opacity))}.lg\:placeholder-purple-600::placeholder{--placeholder-opacity:1;color:#805ad5;color:rgba(128,90,213,var(--placeholder-opacity))}.lg\:placeholder-purple-700:-ms-input-placeholder{--placeholder-opacity:1;color:#6b46c1;color:rgba(107,70,193,var(--placeholder-opacity))}.lg\:placeholder-purple-700::-ms-input-placeholder{--placeholder-opacity:1;color:#6b46c1;color:rgba(107,70,193,var(--placeholder-opacity))}.lg\:placeholder-purple-700::placeholder{--placeholder-opacity:1;color:#6b46c1;color:rgba(107,70,193,var(--placeholder-opacity))}.lg\:placeholder-purple-800:-ms-input-placeholder{--placeholder-opacity:1;color:#553c9a;color:rgba(85,60,154,var(--placeholder-opacity))}.lg\:placeholder-purple-800::-ms-input-placeholder{--placeholder-opacity:1;color:#553c9a;color:rgba(85,60,154,var(--placeholder-opacity))}.lg\:placeholder-purple-800::placeholder{--placeholder-opacity:1;color:#553c9a;color:rgba(85,60,154,var(--placeholder-opacity))}.lg\:placeholder-purple-900:-ms-input-placeholder{--placeholder-opacity:1;color:#44337a;color:rgba(68,51,122,var(--placeholder-opacity))}.lg\:placeholder-purple-900::-ms-input-placeholder{--placeholder-opacity:1;color:#44337a;color:rgba(68,51,122,var(--placeholder-opacity))}.lg\:placeholder-purple-900::placeholder{--placeholder-opacity:1;color:#44337a;color:rgba(68,51,122,var(--placeholder-opacity))}.lg\:placeholder-pink-100:-ms-input-placeholder{--placeholder-opacity:1;color:#fff5f7;color:rgba(255,245,247,var(--placeholder-opacity))}.lg\:placeholder-pink-100::-ms-input-placeholder{--placeholder-opacity:1;color:#fff5f7;color:rgba(255,245,247,var(--placeholder-opacity))}.lg\:placeholder-pink-100::placeholder{--placeholder-opacity:1;color:#fff5f7;color:rgba(255,245,247,var(--placeholder-opacity))}.lg\:placeholder-pink-200:-ms-input-placeholder{--placeholder-opacity:1;color:#fed7e2;color:rgba(254,215,226,var(--placeholder-opacity))}.lg\:placeholder-pink-200::-ms-input-placeholder{--placeholder-opacity:1;color:#fed7e2;color:rgba(254,215,226,var(--placeholder-opacity))}.lg\:placeholder-pink-200::placeholder{--placeholder-opacity:1;color:#fed7e2;color:rgba(254,215,226,var(--placeholder-opacity))}.lg\:placeholder-pink-300:-ms-input-placeholder{--placeholder-opacity:1;color:#fbb6ce;color:rgba(251,182,206,var(--placeholder-opacity))}.lg\:placeholder-pink-300::-ms-input-placeholder{--placeholder-opacity:1;color:#fbb6ce;color:rgba(251,182,206,var(--placeholder-opacity))}.lg\:placeholder-pink-300::placeholder{--placeholder-opacity:1;color:#fbb6ce;color:rgba(251,182,206,var(--placeholder-opacity))}.lg\:placeholder-pink-400:-ms-input-placeholder{--placeholder-opacity:1;color:#f687b3;color:rgba(246,135,179,var(--placeholder-opacity))}.lg\:placeholder-pink-400::-ms-input-placeholder{--placeholder-opacity:1;color:#f687b3;color:rgba(246,135,179,var(--placeholder-opacity))}.lg\:placeholder-pink-400::placeholder{--placeholder-opacity:1;color:#f687b3;color:rgba(246,135,179,var(--placeholder-opacity))}.lg\:placeholder-pink-500:-ms-input-placeholder{--placeholder-opacity:1;color:#ed64a6;color:rgba(237,100,166,var(--placeholder-opacity))}.lg\:placeholder-pink-500::-ms-input-placeholder{--placeholder-opacity:1;color:#ed64a6;color:rgba(237,100,166,var(--placeholder-opacity))}.lg\:placeholder-pink-500::placeholder{--placeholder-opacity:1;color:#ed64a6;color:rgba(237,100,166,var(--placeholder-opacity))}.lg\:placeholder-pink-600:-ms-input-placeholder{--placeholder-opacity:1;color:#d53f8c;color:rgba(213,63,140,var(--placeholder-opacity))}.lg\:placeholder-pink-600::-ms-input-placeholder{--placeholder-opacity:1;color:#d53f8c;color:rgba(213,63,140,var(--placeholder-opacity))}.lg\:placeholder-pink-600::placeholder{--placeholder-opacity:1;color:#d53f8c;color:rgba(213,63,140,var(--placeholder-opacity))}.lg\:placeholder-pink-700:-ms-input-placeholder{--placeholder-opacity:1;color:#b83280;color:rgba(184,50,128,var(--placeholder-opacity))}.lg\:placeholder-pink-700::-ms-input-placeholder{--placeholder-opacity:1;color:#b83280;color:rgba(184,50,128,var(--placeholder-opacity))}.lg\:placeholder-pink-700::placeholder{--placeholder-opacity:1;color:#b83280;color:rgba(184,50,128,var(--placeholder-opacity))}.lg\:placeholder-pink-800:-ms-input-placeholder{--placeholder-opacity:1;color:#97266d;color:rgba(151,38,109,var(--placeholder-opacity))}.lg\:placeholder-pink-800::-ms-input-placeholder{--placeholder-opacity:1;color:#97266d;color:rgba(151,38,109,var(--placeholder-opacity))}.lg\:placeholder-pink-800::placeholder{--placeholder-opacity:1;color:#97266d;color:rgba(151,38,109,var(--placeholder-opacity))}.lg\:placeholder-pink-900:-ms-input-placeholder{--placeholder-opacity:1;color:#702459;color:rgba(112,36,89,var(--placeholder-opacity))}.lg\:placeholder-pink-900::-ms-input-placeholder{--placeholder-opacity:1;color:#702459;color:rgba(112,36,89,var(--placeholder-opacity))}.lg\:placeholder-pink-900::placeholder{--placeholder-opacity:1;color:#702459;color:rgba(112,36,89,var(--placeholder-opacity))}.lg\:focus\:placeholder-transparent:focus:-ms-input-placeholder{color:transparent}.lg\:focus\:placeholder-transparent:focus::-ms-input-placeholder{color:transparent}.lg\:focus\:placeholder-transparent:focus::placeholder{color:transparent}.lg\:focus\:placeholder-current:focus:-ms-input-placeholder{color:currentColor}.lg\:focus\:placeholder-current:focus::-ms-input-placeholder{color:currentColor}.lg\:focus\:placeholder-current:focus::placeholder{color:currentColor}.lg\:focus\:placeholder-black:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#000;color:rgba(0,0,0,var(--placeholder-opacity))}.lg\:focus\:placeholder-black:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#000;color:rgba(0,0,0,var(--placeholder-opacity))}.lg\:focus\:placeholder-black:focus::placeholder{--placeholder-opacity:1;color:#000;color:rgba(0,0,0,var(--placeholder-opacity))}.lg\:focus\:placeholder-white:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#fff;color:rgba(255,255,255,var(--placeholder-opacity))}.lg\:focus\:placeholder-white:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#fff;color:rgba(255,255,255,var(--placeholder-opacity))}.lg\:focus\:placeholder-white:focus::placeholder{--placeholder-opacity:1;color:#fff;color:rgba(255,255,255,var(--placeholder-opacity))}.lg\:focus\:placeholder-gray-100:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#f7fafc;color:rgba(247,250,252,var(--placeholder-opacity))}.lg\:focus\:placeholder-gray-100:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#f7fafc;color:rgba(247,250,252,var(--placeholder-opacity))}.lg\:focus\:placeholder-gray-100:focus::placeholder{--placeholder-opacity:1;color:#f7fafc;color:rgba(247,250,252,var(--placeholder-opacity))}.lg\:focus\:placeholder-gray-200:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#edf2f7;color:rgba(237,242,247,var(--placeholder-opacity))}.lg\:focus\:placeholder-gray-200:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#edf2f7;color:rgba(237,242,247,var(--placeholder-opacity))}.lg\:focus\:placeholder-gray-200:focus::placeholder{--placeholder-opacity:1;color:#edf2f7;color:rgba(237,242,247,var(--placeholder-opacity))}.lg\:focus\:placeholder-gray-300:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#e2e8f0;color:rgba(226,232,240,var(--placeholder-opacity))}.lg\:focus\:placeholder-gray-300:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#e2e8f0;color:rgba(226,232,240,var(--placeholder-opacity))}.lg\:focus\:placeholder-gray-300:focus::placeholder{--placeholder-opacity:1;color:#e2e8f0;color:rgba(226,232,240,var(--placeholder-opacity))}.lg\:focus\:placeholder-gray-400:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#cbd5e0;color:rgba(203,213,224,var(--placeholder-opacity))}.lg\:focus\:placeholder-gray-400:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#cbd5e0;color:rgba(203,213,224,var(--placeholder-opacity))}.lg\:focus\:placeholder-gray-400:focus::placeholder{--placeholder-opacity:1;color:#cbd5e0;color:rgba(203,213,224,var(--placeholder-opacity))}.lg\:focus\:placeholder-gray-500:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#a0aec0;color:rgba(160,174,192,var(--placeholder-opacity))}.lg\:focus\:placeholder-gray-500:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#a0aec0;color:rgba(160,174,192,var(--placeholder-opacity))}.lg\:focus\:placeholder-gray-500:focus::placeholder{--placeholder-opacity:1;color:#a0aec0;color:rgba(160,174,192,var(--placeholder-opacity))}.lg\:focus\:placeholder-gray-600:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#718096;color:rgba(113,128,150,var(--placeholder-opacity))}.lg\:focus\:placeholder-gray-600:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#718096;color:rgba(113,128,150,var(--placeholder-opacity))}.lg\:focus\:placeholder-gray-600:focus::placeholder{--placeholder-opacity:1;color:#718096;color:rgba(113,128,150,var(--placeholder-opacity))}.lg\:focus\:placeholder-gray-700:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#4a5568;color:rgba(74,85,104,var(--placeholder-opacity))}.lg\:focus\:placeholder-gray-700:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#4a5568;color:rgba(74,85,104,var(--placeholder-opacity))}.lg\:focus\:placeholder-gray-700:focus::placeholder{--placeholder-opacity:1;color:#4a5568;color:rgba(74,85,104,var(--placeholder-opacity))}.lg\:focus\:placeholder-gray-800:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#2d3748;color:rgba(45,55,72,var(--placeholder-opacity))}.lg\:focus\:placeholder-gray-800:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#2d3748;color:rgba(45,55,72,var(--placeholder-opacity))}.lg\:focus\:placeholder-gray-800:focus::placeholder{--placeholder-opacity:1;color:#2d3748;color:rgba(45,55,72,var(--placeholder-opacity))}.lg\:focus\:placeholder-gray-900:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#1a202c;color:rgba(26,32,44,var(--placeholder-opacity))}.lg\:focus\:placeholder-gray-900:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#1a202c;color:rgba(26,32,44,var(--placeholder-opacity))}.lg\:focus\:placeholder-gray-900:focus::placeholder{--placeholder-opacity:1;color:#1a202c;color:rgba(26,32,44,var(--placeholder-opacity))}.lg\:focus\:placeholder-red-100:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#fff5f5;color:rgba(255,245,245,var(--placeholder-opacity))}.lg\:focus\:placeholder-red-100:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#fff5f5;color:rgba(255,245,245,var(--placeholder-opacity))}.lg\:focus\:placeholder-red-100:focus::placeholder{--placeholder-opacity:1;color:#fff5f5;color:rgba(255,245,245,var(--placeholder-opacity))}.lg\:focus\:placeholder-red-200:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#fed7d7;color:rgba(254,215,215,var(--placeholder-opacity))}.lg\:focus\:placeholder-red-200:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#fed7d7;color:rgba(254,215,215,var(--placeholder-opacity))}.lg\:focus\:placeholder-red-200:focus::placeholder{--placeholder-opacity:1;color:#fed7d7;color:rgba(254,215,215,var(--placeholder-opacity))}.lg\:focus\:placeholder-red-300:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#feb2b2;color:rgba(254,178,178,var(--placeholder-opacity))}.lg\:focus\:placeholder-red-300:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#feb2b2;color:rgba(254,178,178,var(--placeholder-opacity))}.lg\:focus\:placeholder-red-300:focus::placeholder{--placeholder-opacity:1;color:#feb2b2;color:rgba(254,178,178,var(--placeholder-opacity))}.lg\:focus\:placeholder-red-400:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#fc8181;color:rgba(252,129,129,var(--placeholder-opacity))}.lg\:focus\:placeholder-red-400:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#fc8181;color:rgba(252,129,129,var(--placeholder-opacity))}.lg\:focus\:placeholder-red-400:focus::placeholder{--placeholder-opacity:1;color:#fc8181;color:rgba(252,129,129,var(--placeholder-opacity))}.lg\:focus\:placeholder-red-500:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#f56565;color:rgba(245,101,101,var(--placeholder-opacity))}.lg\:focus\:placeholder-red-500:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#f56565;color:rgba(245,101,101,var(--placeholder-opacity))}.lg\:focus\:placeholder-red-500:focus::placeholder{--placeholder-opacity:1;color:#f56565;color:rgba(245,101,101,var(--placeholder-opacity))}.lg\:focus\:placeholder-red-600:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#e53e3e;color:rgba(229,62,62,var(--placeholder-opacity))}.lg\:focus\:placeholder-red-600:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#e53e3e;color:rgba(229,62,62,var(--placeholder-opacity))}.lg\:focus\:placeholder-red-600:focus::placeholder{--placeholder-opacity:1;color:#e53e3e;color:rgba(229,62,62,var(--placeholder-opacity))}.lg\:focus\:placeholder-red-700:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#c53030;color:rgba(197,48,48,var(--placeholder-opacity))}.lg\:focus\:placeholder-red-700:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#c53030;color:rgba(197,48,48,var(--placeholder-opacity))}.lg\:focus\:placeholder-red-700:focus::placeholder{--placeholder-opacity:1;color:#c53030;color:rgba(197,48,48,var(--placeholder-opacity))}.lg\:focus\:placeholder-red-800:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#9b2c2c;color:rgba(155,44,44,var(--placeholder-opacity))}.lg\:focus\:placeholder-red-800:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#9b2c2c;color:rgba(155,44,44,var(--placeholder-opacity))}.lg\:focus\:placeholder-red-800:focus::placeholder{--placeholder-opacity:1;color:#9b2c2c;color:rgba(155,44,44,var(--placeholder-opacity))}.lg\:focus\:placeholder-red-900:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#742a2a;color:rgba(116,42,42,var(--placeholder-opacity))}.lg\:focus\:placeholder-red-900:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#742a2a;color:rgba(116,42,42,var(--placeholder-opacity))}.lg\:focus\:placeholder-red-900:focus::placeholder{--placeholder-opacity:1;color:#742a2a;color:rgba(116,42,42,var(--placeholder-opacity))}.lg\:focus\:placeholder-orange-100:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#fffaf0;color:rgba(255,250,240,var(--placeholder-opacity))}.lg\:focus\:placeholder-orange-100:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#fffaf0;color:rgba(255,250,240,var(--placeholder-opacity))}.lg\:focus\:placeholder-orange-100:focus::placeholder{--placeholder-opacity:1;color:#fffaf0;color:rgba(255,250,240,var(--placeholder-opacity))}.lg\:focus\:placeholder-orange-200:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#feebc8;color:rgba(254,235,200,var(--placeholder-opacity))}.lg\:focus\:placeholder-orange-200:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#feebc8;color:rgba(254,235,200,var(--placeholder-opacity))}.lg\:focus\:placeholder-orange-200:focus::placeholder{--placeholder-opacity:1;color:#feebc8;color:rgba(254,235,200,var(--placeholder-opacity))}.lg\:focus\:placeholder-orange-300:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#fbd38d;color:rgba(251,211,141,var(--placeholder-opacity))}.lg\:focus\:placeholder-orange-300:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#fbd38d;color:rgba(251,211,141,var(--placeholder-opacity))}.lg\:focus\:placeholder-orange-300:focus::placeholder{--placeholder-opacity:1;color:#fbd38d;color:rgba(251,211,141,var(--placeholder-opacity))}.lg\:focus\:placeholder-orange-400:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#f6ad55;color:rgba(246,173,85,var(--placeholder-opacity))}.lg\:focus\:placeholder-orange-400:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#f6ad55;color:rgba(246,173,85,var(--placeholder-opacity))}.lg\:focus\:placeholder-orange-400:focus::placeholder{--placeholder-opacity:1;color:#f6ad55;color:rgba(246,173,85,var(--placeholder-opacity))}.lg\:focus\:placeholder-orange-500:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#ed8936;color:rgba(237,137,54,var(--placeholder-opacity))}.lg\:focus\:placeholder-orange-500:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#ed8936;color:rgba(237,137,54,var(--placeholder-opacity))}.lg\:focus\:placeholder-orange-500:focus::placeholder{--placeholder-opacity:1;color:#ed8936;color:rgba(237,137,54,var(--placeholder-opacity))}.lg\:focus\:placeholder-orange-600:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#dd6b20;color:rgba(221,107,32,var(--placeholder-opacity))}.lg\:focus\:placeholder-orange-600:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#dd6b20;color:rgba(221,107,32,var(--placeholder-opacity))}.lg\:focus\:placeholder-orange-600:focus::placeholder{--placeholder-opacity:1;color:#dd6b20;color:rgba(221,107,32,var(--placeholder-opacity))}.lg\:focus\:placeholder-orange-700:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#c05621;color:rgba(192,86,33,var(--placeholder-opacity))}.lg\:focus\:placeholder-orange-700:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#c05621;color:rgba(192,86,33,var(--placeholder-opacity))}.lg\:focus\:placeholder-orange-700:focus::placeholder{--placeholder-opacity:1;color:#c05621;color:rgba(192,86,33,var(--placeholder-opacity))}.lg\:focus\:placeholder-orange-800:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#9c4221;color:rgba(156,66,33,var(--placeholder-opacity))}.lg\:focus\:placeholder-orange-800:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#9c4221;color:rgba(156,66,33,var(--placeholder-opacity))}.lg\:focus\:placeholder-orange-800:focus::placeholder{--placeholder-opacity:1;color:#9c4221;color:rgba(156,66,33,var(--placeholder-opacity))}.lg\:focus\:placeholder-orange-900:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#7b341e;color:rgba(123,52,30,var(--placeholder-opacity))}.lg\:focus\:placeholder-orange-900:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#7b341e;color:rgba(123,52,30,var(--placeholder-opacity))}.lg\:focus\:placeholder-orange-900:focus::placeholder{--placeholder-opacity:1;color:#7b341e;color:rgba(123,52,30,var(--placeholder-opacity))}.lg\:focus\:placeholder-yellow-100:focus:-ms-input-placeholder{--placeholder-opacity:1;color:ivory;color:rgba(255,255,240,var(--placeholder-opacity))}.lg\:focus\:placeholder-yellow-100:focus::-ms-input-placeholder{--placeholder-opacity:1;color:ivory;color:rgba(255,255,240,var(--placeholder-opacity))}.lg\:focus\:placeholder-yellow-100:focus::placeholder{--placeholder-opacity:1;color:ivory;color:rgba(255,255,240,var(--placeholder-opacity))}.lg\:focus\:placeholder-yellow-200:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#fefcbf;color:rgba(254,252,191,var(--placeholder-opacity))}.lg\:focus\:placeholder-yellow-200:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#fefcbf;color:rgba(254,252,191,var(--placeholder-opacity))}.lg\:focus\:placeholder-yellow-200:focus::placeholder{--placeholder-opacity:1;color:#fefcbf;color:rgba(254,252,191,var(--placeholder-opacity))}.lg\:focus\:placeholder-yellow-300:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#faf089;color:rgba(250,240,137,var(--placeholder-opacity))}.lg\:focus\:placeholder-yellow-300:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#faf089;color:rgba(250,240,137,var(--placeholder-opacity))}.lg\:focus\:placeholder-yellow-300:focus::placeholder{--placeholder-opacity:1;color:#faf089;color:rgba(250,240,137,var(--placeholder-opacity))}.lg\:focus\:placeholder-yellow-400:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#f6e05e;color:rgba(246,224,94,var(--placeholder-opacity))}.lg\:focus\:placeholder-yellow-400:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#f6e05e;color:rgba(246,224,94,var(--placeholder-opacity))}.lg\:focus\:placeholder-yellow-400:focus::placeholder{--placeholder-opacity:1;color:#f6e05e;color:rgba(246,224,94,var(--placeholder-opacity))}.lg\:focus\:placeholder-yellow-500:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#ecc94b;color:rgba(236,201,75,var(--placeholder-opacity))}.lg\:focus\:placeholder-yellow-500:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#ecc94b;color:rgba(236,201,75,var(--placeholder-opacity))}.lg\:focus\:placeholder-yellow-500:focus::placeholder{--placeholder-opacity:1;color:#ecc94b;color:rgba(236,201,75,var(--placeholder-opacity))}.lg\:focus\:placeholder-yellow-600:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#d69e2e;color:rgba(214,158,46,var(--placeholder-opacity))}.lg\:focus\:placeholder-yellow-600:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#d69e2e;color:rgba(214,158,46,var(--placeholder-opacity))}.lg\:focus\:placeholder-yellow-600:focus::placeholder{--placeholder-opacity:1;color:#d69e2e;color:rgba(214,158,46,var(--placeholder-opacity))}.lg\:focus\:placeholder-yellow-700:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#b7791f;color:rgba(183,121,31,var(--placeholder-opacity))}.lg\:focus\:placeholder-yellow-700:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#b7791f;color:rgba(183,121,31,var(--placeholder-opacity))}.lg\:focus\:placeholder-yellow-700:focus::placeholder{--placeholder-opacity:1;color:#b7791f;color:rgba(183,121,31,var(--placeholder-opacity))}.lg\:focus\:placeholder-yellow-800:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#975a16;color:rgba(151,90,22,var(--placeholder-opacity))}.lg\:focus\:placeholder-yellow-800:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#975a16;color:rgba(151,90,22,var(--placeholder-opacity))}.lg\:focus\:placeholder-yellow-800:focus::placeholder{--placeholder-opacity:1;color:#975a16;color:rgba(151,90,22,var(--placeholder-opacity))}.lg\:focus\:placeholder-yellow-900:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#744210;color:rgba(116,66,16,var(--placeholder-opacity))}.lg\:focus\:placeholder-yellow-900:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#744210;color:rgba(116,66,16,var(--placeholder-opacity))}.lg\:focus\:placeholder-yellow-900:focus::placeholder{--placeholder-opacity:1;color:#744210;color:rgba(116,66,16,var(--placeholder-opacity))}.lg\:focus\:placeholder-green-100:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#f0fff4;color:rgba(240,255,244,var(--placeholder-opacity))}.lg\:focus\:placeholder-green-100:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#f0fff4;color:rgba(240,255,244,var(--placeholder-opacity))}.lg\:focus\:placeholder-green-100:focus::placeholder{--placeholder-opacity:1;color:#f0fff4;color:rgba(240,255,244,var(--placeholder-opacity))}.lg\:focus\:placeholder-green-200:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#c6f6d5;color:rgba(198,246,213,var(--placeholder-opacity))}.lg\:focus\:placeholder-green-200:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#c6f6d5;color:rgba(198,246,213,var(--placeholder-opacity))}.lg\:focus\:placeholder-green-200:focus::placeholder{--placeholder-opacity:1;color:#c6f6d5;color:rgba(198,246,213,var(--placeholder-opacity))}.lg\:focus\:placeholder-green-300:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#9ae6b4;color:rgba(154,230,180,var(--placeholder-opacity))}.lg\:focus\:placeholder-green-300:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#9ae6b4;color:rgba(154,230,180,var(--placeholder-opacity))}.lg\:focus\:placeholder-green-300:focus::placeholder{--placeholder-opacity:1;color:#9ae6b4;color:rgba(154,230,180,var(--placeholder-opacity))}.lg\:focus\:placeholder-green-400:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#68d391;color:rgba(104,211,145,var(--placeholder-opacity))}.lg\:focus\:placeholder-green-400:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#68d391;color:rgba(104,211,145,var(--placeholder-opacity))}.lg\:focus\:placeholder-green-400:focus::placeholder{--placeholder-opacity:1;color:#68d391;color:rgba(104,211,145,var(--placeholder-opacity))}.lg\:focus\:placeholder-green-500:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#48bb78;color:rgba(72,187,120,var(--placeholder-opacity))}.lg\:focus\:placeholder-green-500:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#48bb78;color:rgba(72,187,120,var(--placeholder-opacity))}.lg\:focus\:placeholder-green-500:focus::placeholder{--placeholder-opacity:1;color:#48bb78;color:rgba(72,187,120,var(--placeholder-opacity))}.lg\:focus\:placeholder-green-600:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#38a169;color:rgba(56,161,105,var(--placeholder-opacity))}.lg\:focus\:placeholder-green-600:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#38a169;color:rgba(56,161,105,var(--placeholder-opacity))}.lg\:focus\:placeholder-green-600:focus::placeholder{--placeholder-opacity:1;color:#38a169;color:rgba(56,161,105,var(--placeholder-opacity))}.lg\:focus\:placeholder-green-700:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#2f855a;color:rgba(47,133,90,var(--placeholder-opacity))}.lg\:focus\:placeholder-green-700:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#2f855a;color:rgba(47,133,90,var(--placeholder-opacity))}.lg\:focus\:placeholder-green-700:focus::placeholder{--placeholder-opacity:1;color:#2f855a;color:rgba(47,133,90,var(--placeholder-opacity))}.lg\:focus\:placeholder-green-800:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#276749;color:rgba(39,103,73,var(--placeholder-opacity))}.lg\:focus\:placeholder-green-800:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#276749;color:rgba(39,103,73,var(--placeholder-opacity))}.lg\:focus\:placeholder-green-800:focus::placeholder{--placeholder-opacity:1;color:#276749;color:rgba(39,103,73,var(--placeholder-opacity))}.lg\:focus\:placeholder-green-900:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#22543d;color:rgba(34,84,61,var(--placeholder-opacity))}.lg\:focus\:placeholder-green-900:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#22543d;color:rgba(34,84,61,var(--placeholder-opacity))}.lg\:focus\:placeholder-green-900:focus::placeholder{--placeholder-opacity:1;color:#22543d;color:rgba(34,84,61,var(--placeholder-opacity))}.lg\:focus\:placeholder-teal-100:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#e6fffa;color:rgba(230,255,250,var(--placeholder-opacity))}.lg\:focus\:placeholder-teal-100:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#e6fffa;color:rgba(230,255,250,var(--placeholder-opacity))}.lg\:focus\:placeholder-teal-100:focus::placeholder{--placeholder-opacity:1;color:#e6fffa;color:rgba(230,255,250,var(--placeholder-opacity))}.lg\:focus\:placeholder-teal-200:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#b2f5ea;color:rgba(178,245,234,var(--placeholder-opacity))}.lg\:focus\:placeholder-teal-200:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#b2f5ea;color:rgba(178,245,234,var(--placeholder-opacity))}.lg\:focus\:placeholder-teal-200:focus::placeholder{--placeholder-opacity:1;color:#b2f5ea;color:rgba(178,245,234,var(--placeholder-opacity))}.lg\:focus\:placeholder-teal-300:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#81e6d9;color:rgba(129,230,217,var(--placeholder-opacity))}.lg\:focus\:placeholder-teal-300:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#81e6d9;color:rgba(129,230,217,var(--placeholder-opacity))}.lg\:focus\:placeholder-teal-300:focus::placeholder{--placeholder-opacity:1;color:#81e6d9;color:rgba(129,230,217,var(--placeholder-opacity))}.lg\:focus\:placeholder-teal-400:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#4fd1c5;color:rgba(79,209,197,var(--placeholder-opacity))}.lg\:focus\:placeholder-teal-400:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#4fd1c5;color:rgba(79,209,197,var(--placeholder-opacity))}.lg\:focus\:placeholder-teal-400:focus::placeholder{--placeholder-opacity:1;color:#4fd1c5;color:rgba(79,209,197,var(--placeholder-opacity))}.lg\:focus\:placeholder-teal-500:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#38b2ac;color:rgba(56,178,172,var(--placeholder-opacity))}.lg\:focus\:placeholder-teal-500:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#38b2ac;color:rgba(56,178,172,var(--placeholder-opacity))}.lg\:focus\:placeholder-teal-500:focus::placeholder{--placeholder-opacity:1;color:#38b2ac;color:rgba(56,178,172,var(--placeholder-opacity))}.lg\:focus\:placeholder-teal-600:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#319795;color:rgba(49,151,149,var(--placeholder-opacity))}.lg\:focus\:placeholder-teal-600:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#319795;color:rgba(49,151,149,var(--placeholder-opacity))}.lg\:focus\:placeholder-teal-600:focus::placeholder{--placeholder-opacity:1;color:#319795;color:rgba(49,151,149,var(--placeholder-opacity))}.lg\:focus\:placeholder-teal-700:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#2c7a7b;color:rgba(44,122,123,var(--placeholder-opacity))}.lg\:focus\:placeholder-teal-700:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#2c7a7b;color:rgba(44,122,123,var(--placeholder-opacity))}.lg\:focus\:placeholder-teal-700:focus::placeholder{--placeholder-opacity:1;color:#2c7a7b;color:rgba(44,122,123,var(--placeholder-opacity))}.lg\:focus\:placeholder-teal-800:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#285e61;color:rgba(40,94,97,var(--placeholder-opacity))}.lg\:focus\:placeholder-teal-800:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#285e61;color:rgba(40,94,97,var(--placeholder-opacity))}.lg\:focus\:placeholder-teal-800:focus::placeholder{--placeholder-opacity:1;color:#285e61;color:rgba(40,94,97,var(--placeholder-opacity))}.lg\:focus\:placeholder-teal-900:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#234e52;color:rgba(35,78,82,var(--placeholder-opacity))}.lg\:focus\:placeholder-teal-900:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#234e52;color:rgba(35,78,82,var(--placeholder-opacity))}.lg\:focus\:placeholder-teal-900:focus::placeholder{--placeholder-opacity:1;color:#234e52;color:rgba(35,78,82,var(--placeholder-opacity))}.lg\:focus\:placeholder-blue-100:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#ebf8ff;color:rgba(235,248,255,var(--placeholder-opacity))}.lg\:focus\:placeholder-blue-100:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#ebf8ff;color:rgba(235,248,255,var(--placeholder-opacity))}.lg\:focus\:placeholder-blue-100:focus::placeholder{--placeholder-opacity:1;color:#ebf8ff;color:rgba(235,248,255,var(--placeholder-opacity))}.lg\:focus\:placeholder-blue-200:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#bee3f8;color:rgba(190,227,248,var(--placeholder-opacity))}.lg\:focus\:placeholder-blue-200:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#bee3f8;color:rgba(190,227,248,var(--placeholder-opacity))}.lg\:focus\:placeholder-blue-200:focus::placeholder{--placeholder-opacity:1;color:#bee3f8;color:rgba(190,227,248,var(--placeholder-opacity))}.lg\:focus\:placeholder-blue-300:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#90cdf4;color:rgba(144,205,244,var(--placeholder-opacity))}.lg\:focus\:placeholder-blue-300:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#90cdf4;color:rgba(144,205,244,var(--placeholder-opacity))}.lg\:focus\:placeholder-blue-300:focus::placeholder{--placeholder-opacity:1;color:#90cdf4;color:rgba(144,205,244,var(--placeholder-opacity))}.lg\:focus\:placeholder-blue-400:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#63b3ed;color:rgba(99,179,237,var(--placeholder-opacity))}.lg\:focus\:placeholder-blue-400:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#63b3ed;color:rgba(99,179,237,var(--placeholder-opacity))}.lg\:focus\:placeholder-blue-400:focus::placeholder{--placeholder-opacity:1;color:#63b3ed;color:rgba(99,179,237,var(--placeholder-opacity))}.lg\:focus\:placeholder-blue-500:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#4299e1;color:rgba(66,153,225,var(--placeholder-opacity))}.lg\:focus\:placeholder-blue-500:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#4299e1;color:rgba(66,153,225,var(--placeholder-opacity))}.lg\:focus\:placeholder-blue-500:focus::placeholder{--placeholder-opacity:1;color:#4299e1;color:rgba(66,153,225,var(--placeholder-opacity))}.lg\:focus\:placeholder-blue-600:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#3182ce;color:rgba(49,130,206,var(--placeholder-opacity))}.lg\:focus\:placeholder-blue-600:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#3182ce;color:rgba(49,130,206,var(--placeholder-opacity))}.lg\:focus\:placeholder-blue-600:focus::placeholder{--placeholder-opacity:1;color:#3182ce;color:rgba(49,130,206,var(--placeholder-opacity))}.lg\:focus\:placeholder-blue-700:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#2b6cb0;color:rgba(43,108,176,var(--placeholder-opacity))}.lg\:focus\:placeholder-blue-700:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#2b6cb0;color:rgba(43,108,176,var(--placeholder-opacity))}.lg\:focus\:placeholder-blue-700:focus::placeholder{--placeholder-opacity:1;color:#2b6cb0;color:rgba(43,108,176,var(--placeholder-opacity))}.lg\:focus\:placeholder-blue-800:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#2c5282;color:rgba(44,82,130,var(--placeholder-opacity))}.lg\:focus\:placeholder-blue-800:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#2c5282;color:rgba(44,82,130,var(--placeholder-opacity))}.lg\:focus\:placeholder-blue-800:focus::placeholder{--placeholder-opacity:1;color:#2c5282;color:rgba(44,82,130,var(--placeholder-opacity))}.lg\:focus\:placeholder-blue-900:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#2a4365;color:rgba(42,67,101,var(--placeholder-opacity))}.lg\:focus\:placeholder-blue-900:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#2a4365;color:rgba(42,67,101,var(--placeholder-opacity))}.lg\:focus\:placeholder-blue-900:focus::placeholder{--placeholder-opacity:1;color:#2a4365;color:rgba(42,67,101,var(--placeholder-opacity))}.lg\:focus\:placeholder-indigo-100:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#ebf4ff;color:rgba(235,244,255,var(--placeholder-opacity))}.lg\:focus\:placeholder-indigo-100:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#ebf4ff;color:rgba(235,244,255,var(--placeholder-opacity))}.lg\:focus\:placeholder-indigo-100:focus::placeholder{--placeholder-opacity:1;color:#ebf4ff;color:rgba(235,244,255,var(--placeholder-opacity))}.lg\:focus\:placeholder-indigo-200:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#c3dafe;color:rgba(195,218,254,var(--placeholder-opacity))}.lg\:focus\:placeholder-indigo-200:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#c3dafe;color:rgba(195,218,254,var(--placeholder-opacity))}.lg\:focus\:placeholder-indigo-200:focus::placeholder{--placeholder-opacity:1;color:#c3dafe;color:rgba(195,218,254,var(--placeholder-opacity))}.lg\:focus\:placeholder-indigo-300:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#a3bffa;color:rgba(163,191,250,var(--placeholder-opacity))}.lg\:focus\:placeholder-indigo-300:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#a3bffa;color:rgba(163,191,250,var(--placeholder-opacity))}.lg\:focus\:placeholder-indigo-300:focus::placeholder{--placeholder-opacity:1;color:#a3bffa;color:rgba(163,191,250,var(--placeholder-opacity))}.lg\:focus\:placeholder-indigo-400:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#7f9cf5;color:rgba(127,156,245,var(--placeholder-opacity))}.lg\:focus\:placeholder-indigo-400:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#7f9cf5;color:rgba(127,156,245,var(--placeholder-opacity))}.lg\:focus\:placeholder-indigo-400:focus::placeholder{--placeholder-opacity:1;color:#7f9cf5;color:rgba(127,156,245,var(--placeholder-opacity))}.lg\:focus\:placeholder-indigo-500:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#667eea;color:rgba(102,126,234,var(--placeholder-opacity))}.lg\:focus\:placeholder-indigo-500:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#667eea;color:rgba(102,126,234,var(--placeholder-opacity))}.lg\:focus\:placeholder-indigo-500:focus::placeholder{--placeholder-opacity:1;color:#667eea;color:rgba(102,126,234,var(--placeholder-opacity))}.lg\:focus\:placeholder-indigo-600:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#5a67d8;color:rgba(90,103,216,var(--placeholder-opacity))}.lg\:focus\:placeholder-indigo-600:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#5a67d8;color:rgba(90,103,216,var(--placeholder-opacity))}.lg\:focus\:placeholder-indigo-600:focus::placeholder{--placeholder-opacity:1;color:#5a67d8;color:rgba(90,103,216,var(--placeholder-opacity))}.lg\:focus\:placeholder-indigo-700:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#4c51bf;color:rgba(76,81,191,var(--placeholder-opacity))}.lg\:focus\:placeholder-indigo-700:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#4c51bf;color:rgba(76,81,191,var(--placeholder-opacity))}.lg\:focus\:placeholder-indigo-700:focus::placeholder{--placeholder-opacity:1;color:#4c51bf;color:rgba(76,81,191,var(--placeholder-opacity))}.lg\:focus\:placeholder-indigo-800:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#434190;color:rgba(67,65,144,var(--placeholder-opacity))}.lg\:focus\:placeholder-indigo-800:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#434190;color:rgba(67,65,144,var(--placeholder-opacity))}.lg\:focus\:placeholder-indigo-800:focus::placeholder{--placeholder-opacity:1;color:#434190;color:rgba(67,65,144,var(--placeholder-opacity))}.lg\:focus\:placeholder-indigo-900:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#3c366b;color:rgba(60,54,107,var(--placeholder-opacity))}.lg\:focus\:placeholder-indigo-900:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#3c366b;color:rgba(60,54,107,var(--placeholder-opacity))}.lg\:focus\:placeholder-indigo-900:focus::placeholder{--placeholder-opacity:1;color:#3c366b;color:rgba(60,54,107,var(--placeholder-opacity))}.lg\:focus\:placeholder-purple-100:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#faf5ff;color:rgba(250,245,255,var(--placeholder-opacity))}.lg\:focus\:placeholder-purple-100:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#faf5ff;color:rgba(250,245,255,var(--placeholder-opacity))}.lg\:focus\:placeholder-purple-100:focus::placeholder{--placeholder-opacity:1;color:#faf5ff;color:rgba(250,245,255,var(--placeholder-opacity))}.lg\:focus\:placeholder-purple-200:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#e9d8fd;color:rgba(233,216,253,var(--placeholder-opacity))}.lg\:focus\:placeholder-purple-200:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#e9d8fd;color:rgba(233,216,253,var(--placeholder-opacity))}.lg\:focus\:placeholder-purple-200:focus::placeholder{--placeholder-opacity:1;color:#e9d8fd;color:rgba(233,216,253,var(--placeholder-opacity))}.lg\:focus\:placeholder-purple-300:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#d6bcfa;color:rgba(214,188,250,var(--placeholder-opacity))}.lg\:focus\:placeholder-purple-300:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#d6bcfa;color:rgba(214,188,250,var(--placeholder-opacity))}.lg\:focus\:placeholder-purple-300:focus::placeholder{--placeholder-opacity:1;color:#d6bcfa;color:rgba(214,188,250,var(--placeholder-opacity))}.lg\:focus\:placeholder-purple-400:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#b794f4;color:rgba(183,148,244,var(--placeholder-opacity))}.lg\:focus\:placeholder-purple-400:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#b794f4;color:rgba(183,148,244,var(--placeholder-opacity))}.lg\:focus\:placeholder-purple-400:focus::placeholder{--placeholder-opacity:1;color:#b794f4;color:rgba(183,148,244,var(--placeholder-opacity))}.lg\:focus\:placeholder-purple-500:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#9f7aea;color:rgba(159,122,234,var(--placeholder-opacity))}.lg\:focus\:placeholder-purple-500:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#9f7aea;color:rgba(159,122,234,var(--placeholder-opacity))}.lg\:focus\:placeholder-purple-500:focus::placeholder{--placeholder-opacity:1;color:#9f7aea;color:rgba(159,122,234,var(--placeholder-opacity))}.lg\:focus\:placeholder-purple-600:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#805ad5;color:rgba(128,90,213,var(--placeholder-opacity))}.lg\:focus\:placeholder-purple-600:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#805ad5;color:rgba(128,90,213,var(--placeholder-opacity))}.lg\:focus\:placeholder-purple-600:focus::placeholder{--placeholder-opacity:1;color:#805ad5;color:rgba(128,90,213,var(--placeholder-opacity))}.lg\:focus\:placeholder-purple-700:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#6b46c1;color:rgba(107,70,193,var(--placeholder-opacity))}.lg\:focus\:placeholder-purple-700:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#6b46c1;color:rgba(107,70,193,var(--placeholder-opacity))}.lg\:focus\:placeholder-purple-700:focus::placeholder{--placeholder-opacity:1;color:#6b46c1;color:rgba(107,70,193,var(--placeholder-opacity))}.lg\:focus\:placeholder-purple-800:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#553c9a;color:rgba(85,60,154,var(--placeholder-opacity))}.lg\:focus\:placeholder-purple-800:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#553c9a;color:rgba(85,60,154,var(--placeholder-opacity))}.lg\:focus\:placeholder-purple-800:focus::placeholder{--placeholder-opacity:1;color:#553c9a;color:rgba(85,60,154,var(--placeholder-opacity))}.lg\:focus\:placeholder-purple-900:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#44337a;color:rgba(68,51,122,var(--placeholder-opacity))}.lg\:focus\:placeholder-purple-900:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#44337a;color:rgba(68,51,122,var(--placeholder-opacity))}.lg\:focus\:placeholder-purple-900:focus::placeholder{--placeholder-opacity:1;color:#44337a;color:rgba(68,51,122,var(--placeholder-opacity))}.lg\:focus\:placeholder-pink-100:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#fff5f7;color:rgba(255,245,247,var(--placeholder-opacity))}.lg\:focus\:placeholder-pink-100:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#fff5f7;color:rgba(255,245,247,var(--placeholder-opacity))}.lg\:focus\:placeholder-pink-100:focus::placeholder{--placeholder-opacity:1;color:#fff5f7;color:rgba(255,245,247,var(--placeholder-opacity))}.lg\:focus\:placeholder-pink-200:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#fed7e2;color:rgba(254,215,226,var(--placeholder-opacity))}.lg\:focus\:placeholder-pink-200:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#fed7e2;color:rgba(254,215,226,var(--placeholder-opacity))}.lg\:focus\:placeholder-pink-200:focus::placeholder{--placeholder-opacity:1;color:#fed7e2;color:rgba(254,215,226,var(--placeholder-opacity))}.lg\:focus\:placeholder-pink-300:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#fbb6ce;color:rgba(251,182,206,var(--placeholder-opacity))}.lg\:focus\:placeholder-pink-300:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#fbb6ce;color:rgba(251,182,206,var(--placeholder-opacity))}.lg\:focus\:placeholder-pink-300:focus::placeholder{--placeholder-opacity:1;color:#fbb6ce;color:rgba(251,182,206,var(--placeholder-opacity))}.lg\:focus\:placeholder-pink-400:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#f687b3;color:rgba(246,135,179,var(--placeholder-opacity))}.lg\:focus\:placeholder-pink-400:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#f687b3;color:rgba(246,135,179,var(--placeholder-opacity))}.lg\:focus\:placeholder-pink-400:focus::placeholder{--placeholder-opacity:1;color:#f687b3;color:rgba(246,135,179,var(--placeholder-opacity))}.lg\:focus\:placeholder-pink-500:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#ed64a6;color:rgba(237,100,166,var(--placeholder-opacity))}.lg\:focus\:placeholder-pink-500:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#ed64a6;color:rgba(237,100,166,var(--placeholder-opacity))}.lg\:focus\:placeholder-pink-500:focus::placeholder{--placeholder-opacity:1;color:#ed64a6;color:rgba(237,100,166,var(--placeholder-opacity))}.lg\:focus\:placeholder-pink-600:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#d53f8c;color:rgba(213,63,140,var(--placeholder-opacity))}.lg\:focus\:placeholder-pink-600:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#d53f8c;color:rgba(213,63,140,var(--placeholder-opacity))}.lg\:focus\:placeholder-pink-600:focus::placeholder{--placeholder-opacity:1;color:#d53f8c;color:rgba(213,63,140,var(--placeholder-opacity))}.lg\:focus\:placeholder-pink-700:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#b83280;color:rgba(184,50,128,var(--placeholder-opacity))}.lg\:focus\:placeholder-pink-700:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#b83280;color:rgba(184,50,128,var(--placeholder-opacity))}.lg\:focus\:placeholder-pink-700:focus::placeholder{--placeholder-opacity:1;color:#b83280;color:rgba(184,50,128,var(--placeholder-opacity))}.lg\:focus\:placeholder-pink-800:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#97266d;color:rgba(151,38,109,var(--placeholder-opacity))}.lg\:focus\:placeholder-pink-800:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#97266d;color:rgba(151,38,109,var(--placeholder-opacity))}.lg\:focus\:placeholder-pink-800:focus::placeholder{--placeholder-opacity:1;color:#97266d;color:rgba(151,38,109,var(--placeholder-opacity))}.lg\:focus\:placeholder-pink-900:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#702459;color:rgba(112,36,89,var(--placeholder-opacity))}.lg\:focus\:placeholder-pink-900:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#702459;color:rgba(112,36,89,var(--placeholder-opacity))}.lg\:focus\:placeholder-pink-900:focus::placeholder{--placeholder-opacity:1;color:#702459;color:rgba(112,36,89,var(--placeholder-opacity))}.lg\:placeholder-opacity-0:-ms-input-placeholder{--placeholder-opacity:0}.lg\:placeholder-opacity-0::-ms-input-placeholder{--placeholder-opacity:0}.lg\:placeholder-opacity-0::placeholder{--placeholder-opacity:0}.lg\:placeholder-opacity-25:-ms-input-placeholder{--placeholder-opacity:0.25}.lg\:placeholder-opacity-25::-ms-input-placeholder{--placeholder-opacity:0.25}.lg\:placeholder-opacity-25::placeholder{--placeholder-opacity:0.25}.lg\:placeholder-opacity-50:-ms-input-placeholder{--placeholder-opacity:0.5}.lg\:placeholder-opacity-50::-ms-input-placeholder{--placeholder-opacity:0.5}.lg\:placeholder-opacity-50::placeholder{--placeholder-opacity:0.5}.lg\:placeholder-opacity-75:-ms-input-placeholder{--placeholder-opacity:0.75}.lg\:placeholder-opacity-75::-ms-input-placeholder{--placeholder-opacity:0.75}.lg\:placeholder-opacity-75::placeholder{--placeholder-opacity:0.75}.lg\:placeholder-opacity-100:-ms-input-placeholder{--placeholder-opacity:1}.lg\:placeholder-opacity-100::-ms-input-placeholder{--placeholder-opacity:1}.lg\:placeholder-opacity-100::placeholder{--placeholder-opacity:1}.lg\:focus\:placeholder-opacity-0:focus:-ms-input-placeholder{--placeholder-opacity:0}.lg\:focus\:placeholder-opacity-0:focus::-ms-input-placeholder{--placeholder-opacity:0}.lg\:focus\:placeholder-opacity-0:focus::placeholder{--placeholder-opacity:0}.lg\:focus\:placeholder-opacity-25:focus:-ms-input-placeholder{--placeholder-opacity:0.25}.lg\:focus\:placeholder-opacity-25:focus::-ms-input-placeholder{--placeholder-opacity:0.25}.lg\:focus\:placeholder-opacity-25:focus::placeholder{--placeholder-opacity:0.25}.lg\:focus\:placeholder-opacity-50:focus:-ms-input-placeholder{--placeholder-opacity:0.5}.lg\:focus\:placeholder-opacity-50:focus::-ms-input-placeholder{--placeholder-opacity:0.5}.lg\:focus\:placeholder-opacity-50:focus::placeholder{--placeholder-opacity:0.5}.lg\:focus\:placeholder-opacity-75:focus:-ms-input-placeholder{--placeholder-opacity:0.75}.lg\:focus\:placeholder-opacity-75:focus::-ms-input-placeholder{--placeholder-opacity:0.75}.lg\:focus\:placeholder-opacity-75:focus::placeholder{--placeholder-opacity:0.75}.lg\:focus\:placeholder-opacity-100:focus:-ms-input-placeholder{--placeholder-opacity:1}.lg\:focus\:placeholder-opacity-100:focus::-ms-input-placeholder{--placeholder-opacity:1}.lg\:focus\:placeholder-opacity-100:focus::placeholder{--placeholder-opacity:1}.lg\:pointer-events-none{pointer-events:none}.lg\:pointer-events-auto{pointer-events:auto}.lg\:static{position:static}.lg\:fixed{position:fixed}.lg\:absolute{position:absolute}.lg\:relative{position:relative}.lg\:sticky{position:-webkit-sticky;position:sticky}.lg\:inset-0{top:0;right:0;bottom:0;left:0}.lg\:inset-auto{top:auto;right:auto;bottom:auto;left:auto}.lg\:inset-y-0{top:0;bottom:0}.lg\:inset-x-0{right:0;left:0}.lg\:inset-y-auto{top:auto;bottom:auto}.lg\:inset-x-auto{right:auto;left:auto}.lg\:top-0{top:0}.lg\:right-0{right:0}.lg\:bottom-0{bottom:0}.lg\:left-0{left:0}.lg\:top-auto{top:auto}.lg\:right-auto{right:auto}.lg\:bottom-auto{bottom:auto}.lg\:left-auto{left:auto}.lg\:resize-none{resize:none}.lg\:resize-y{resize:vertical}.lg\:resize-x{resize:horizontal}.lg\:resize{resize:both}.lg\:shadow-xs{box-shadow:0 0 0 1px rgba(0,0,0,.05)}.lg\:shadow-sm{box-shadow:0 1px 2px 0 rgba(0,0,0,.05)}.lg\:shadow{box-shadow:0 1px 3px 0 rgba(0,0,0,.1),0 1px 2px 0 rgba(0,0,0,.06)}.lg\:shadow-md{box-shadow:0 4px 6px -1px rgba(0,0,0,.1),0 2px 4px -1px rgba(0,0,0,.06)}.lg\:shadow-lg{box-shadow:0 10px 15px -3px rgba(0,0,0,.1),0 4px 6px -2px rgba(0,0,0,.05)}.lg\:shadow-xl{box-shadow:0 20px 25px -5px rgba(0,0,0,.1),0 10px 10px -5px rgba(0,0,0,.04)}.lg\:shadow-2xl{box-shadow:0 25px 50px -12px rgba(0,0,0,.25)}.lg\:shadow-inner{box-shadow:inset 0 2px 4px 0 rgba(0,0,0,.06)}.lg\:shadow-outline{box-shadow:0 0 0 3px rgba(66,153,225,.5)}.lg\:shadow-none{box-shadow:none}.lg\:hover\:shadow-xs:hover{box-shadow:0 0 0 1px rgba(0,0,0,.05)}.lg\:hover\:shadow-sm:hover{box-shadow:0 1px 2px 0 rgba(0,0,0,.05)}.lg\:hover\:shadow:hover{box-shadow:0 1px 3px 0 rgba(0,0,0,.1),0 1px 2px 0 rgba(0,0,0,.06)}.lg\:hover\:shadow-md:hover{box-shadow:0 4px 6px -1px rgba(0,0,0,.1),0 2px 4px -1px rgba(0,0,0,.06)}.lg\:hover\:shadow-lg:hover{box-shadow:0 10px 15px -3px rgba(0,0,0,.1),0 4px 6px -2px rgba(0,0,0,.05)}.lg\:hover\:shadow-xl:hover{box-shadow:0 20px 25px -5px rgba(0,0,0,.1),0 10px 10px -5px rgba(0,0,0,.04)}.lg\:hover\:shadow-2xl:hover{box-shadow:0 25px 50px -12px rgba(0,0,0,.25)}.lg\:hover\:shadow-inner:hover{box-shadow:inset 0 2px 4px 0 rgba(0,0,0,.06)}.lg\:hover\:shadow-outline:hover{box-shadow:0 0 0 3px rgba(66,153,225,.5)}.lg\:hover\:shadow-none:hover{box-shadow:none}.lg\:focus\:shadow-xs:focus{box-shadow:0 0 0 1px rgba(0,0,0,.05)}.lg\:focus\:shadow-sm:focus{box-shadow:0 1px 2px 0 rgba(0,0,0,.05)}.lg\:focus\:shadow:focus{box-shadow:0 1px 3px 0 rgba(0,0,0,.1),0 1px 2px 0 rgba(0,0,0,.06)}.lg\:focus\:shadow-md:focus{box-shadow:0 4px 6px -1px rgba(0,0,0,.1),0 2px 4px -1px rgba(0,0,0,.06)}.lg\:focus\:shadow-lg:focus{box-shadow:0 10px 15px -3px rgba(0,0,0,.1),0 4px 6px -2px rgba(0,0,0,.05)}.lg\:focus\:shadow-xl:focus{box-shadow:0 20px 25px -5px rgba(0,0,0,.1),0 10px 10px -5px rgba(0,0,0,.04)}.lg\:focus\:shadow-2xl:focus{box-shadow:0 25px 50px -12px rgba(0,0,0,.25)}.lg\:focus\:shadow-inner:focus{box-shadow:inset 0 2px 4px 0 rgba(0,0,0,.06)}.lg\:focus\:shadow-outline:focus{box-shadow:0 0 0 3px rgba(66,153,225,.5)}.lg\:focus\:shadow-none:focus{box-shadow:none}.lg\:fill-current{fill:currentColor}.lg\:stroke-current{stroke:currentColor}.lg\:stroke-0{stroke-width:0}.lg\:stroke-1{stroke-width:1}.lg\:stroke-2{stroke-width:2}.lg\:table-auto{table-layout:auto}.lg\:table-fixed{table-layout:fixed}.lg\:text-left{text-align:left}.lg\:text-center{text-align:center}.lg\:text-right{text-align:right}.lg\:text-justify{text-align:justify}.lg\:text-transparent{color:transparent}.lg\:text-current{color:currentColor}.lg\:text-black{--text-opacity:1;color:#000;color:rgba(0,0,0,var(--text-opacity))}.lg\:text-white{--text-opacity:1;color:#fff;color:rgba(255,255,255,var(--text-opacity))}.lg\:text-gray-100{--text-opacity:1;color:#f7fafc;color:rgba(247,250,252,var(--text-opacity))}.lg\:text-gray-200{--text-opacity:1;color:#edf2f7;color:rgba(237,242,247,var(--text-opacity))}.lg\:text-gray-300{--text-opacity:1;color:#e2e8f0;color:rgba(226,232,240,var(--text-opacity))}.lg\:text-gray-400{--text-opacity:1;color:#cbd5e0;color:rgba(203,213,224,var(--text-opacity))}.lg\:text-gray-500{--text-opacity:1;color:#a0aec0;color:rgba(160,174,192,var(--text-opacity))}.lg\:text-gray-600{--text-opacity:1;color:#718096;color:rgba(113,128,150,var(--text-opacity))}.lg\:text-gray-700{--text-opacity:1;color:#4a5568;color:rgba(74,85,104,var(--text-opacity))}.lg\:text-gray-800{--text-opacity:1;color:#2d3748;color:rgba(45,55,72,var(--text-opacity))}.lg\:text-gray-900{--text-opacity:1;color:#1a202c;color:rgba(26,32,44,var(--text-opacity))}.lg\:text-red-100{--text-opacity:1;color:#fff5f5;color:rgba(255,245,245,var(--text-opacity))}.lg\:text-red-200{--text-opacity:1;color:#fed7d7;color:rgba(254,215,215,var(--text-opacity))}.lg\:text-red-300{--text-opacity:1;color:#feb2b2;color:rgba(254,178,178,var(--text-opacity))}.lg\:text-red-400{--text-opacity:1;color:#fc8181;color:rgba(252,129,129,var(--text-opacity))}.lg\:text-red-500{--text-opacity:1;color:#f56565;color:rgba(245,101,101,var(--text-opacity))}.lg\:text-red-600{--text-opacity:1;color:#e53e3e;color:rgba(229,62,62,var(--text-opacity))}.lg\:text-red-700{--text-opacity:1;color:#c53030;color:rgba(197,48,48,var(--text-opacity))}.lg\:text-red-800{--text-opacity:1;color:#9b2c2c;color:rgba(155,44,44,var(--text-opacity))}.lg\:text-red-900{--text-opacity:1;color:#742a2a;color:rgba(116,42,42,var(--text-opacity))}.lg\:text-orange-100{--text-opacity:1;color:#fffaf0;color:rgba(255,250,240,var(--text-opacity))}.lg\:text-orange-200{--text-opacity:1;color:#feebc8;color:rgba(254,235,200,var(--text-opacity))}.lg\:text-orange-300{--text-opacity:1;color:#fbd38d;color:rgba(251,211,141,var(--text-opacity))}.lg\:text-orange-400{--text-opacity:1;color:#f6ad55;color:rgba(246,173,85,var(--text-opacity))}.lg\:text-orange-500{--text-opacity:1;color:#ed8936;color:rgba(237,137,54,var(--text-opacity))}.lg\:text-orange-600{--text-opacity:1;color:#dd6b20;color:rgba(221,107,32,var(--text-opacity))}.lg\:text-orange-700{--text-opacity:1;color:#c05621;color:rgba(192,86,33,var(--text-opacity))}.lg\:text-orange-800{--text-opacity:1;color:#9c4221;color:rgba(156,66,33,var(--text-opacity))}.lg\:text-orange-900{--text-opacity:1;color:#7b341e;color:rgba(123,52,30,var(--text-opacity))}.lg\:text-yellow-100{--text-opacity:1;color:ivory;color:rgba(255,255,240,var(--text-opacity))}.lg\:text-yellow-200{--text-opacity:1;color:#fefcbf;color:rgba(254,252,191,var(--text-opacity))}.lg\:text-yellow-300{--text-opacity:1;color:#faf089;color:rgba(250,240,137,var(--text-opacity))}.lg\:text-yellow-400{--text-opacity:1;color:#f6e05e;color:rgba(246,224,94,var(--text-opacity))}.lg\:text-yellow-500{--text-opacity:1;color:#ecc94b;color:rgba(236,201,75,var(--text-opacity))}.lg\:text-yellow-600{--text-opacity:1;color:#d69e2e;color:rgba(214,158,46,var(--text-opacity))}.lg\:text-yellow-700{--text-opacity:1;color:#b7791f;color:rgba(183,121,31,var(--text-opacity))}.lg\:text-yellow-800{--text-opacity:1;color:#975a16;color:rgba(151,90,22,var(--text-opacity))}.lg\:text-yellow-900{--text-opacity:1;color:#744210;color:rgba(116,66,16,var(--text-opacity))}.lg\:text-green-100{--text-opacity:1;color:#f0fff4;color:rgba(240,255,244,var(--text-opacity))}.lg\:text-green-200{--text-opacity:1;color:#c6f6d5;color:rgba(198,246,213,var(--text-opacity))}.lg\:text-green-300{--text-opacity:1;color:#9ae6b4;color:rgba(154,230,180,var(--text-opacity))}.lg\:text-green-400{--text-opacity:1;color:#68d391;color:rgba(104,211,145,var(--text-opacity))}.lg\:text-green-500{--text-opacity:1;color:#48bb78;color:rgba(72,187,120,var(--text-opacity))}.lg\:text-green-600{--text-opacity:1;color:#38a169;color:rgba(56,161,105,var(--text-opacity))}.lg\:text-green-700{--text-opacity:1;color:#2f855a;color:rgba(47,133,90,var(--text-opacity))}.lg\:text-green-800{--text-opacity:1;color:#276749;color:rgba(39,103,73,var(--text-opacity))}.lg\:text-green-900{--text-opacity:1;color:#22543d;color:rgba(34,84,61,var(--text-opacity))}.lg\:text-teal-100{--text-opacity:1;color:#e6fffa;color:rgba(230,255,250,var(--text-opacity))}.lg\:text-teal-200{--text-opacity:1;color:#b2f5ea;color:rgba(178,245,234,var(--text-opacity))}.lg\:text-teal-300{--text-opacity:1;color:#81e6d9;color:rgba(129,230,217,var(--text-opacity))}.lg\:text-teal-400{--text-opacity:1;color:#4fd1c5;color:rgba(79,209,197,var(--text-opacity))}.lg\:text-teal-500{--text-opacity:1;color:#38b2ac;color:rgba(56,178,172,var(--text-opacity))}.lg\:text-teal-600{--text-opacity:1;color:#319795;color:rgba(49,151,149,var(--text-opacity))}.lg\:text-teal-700{--text-opacity:1;color:#2c7a7b;color:rgba(44,122,123,var(--text-opacity))}.lg\:text-teal-800{--text-opacity:1;color:#285e61;color:rgba(40,94,97,var(--text-opacity))}.lg\:text-teal-900{--text-opacity:1;color:#234e52;color:rgba(35,78,82,var(--text-opacity))}.lg\:text-blue-100{--text-opacity:1;color:#ebf8ff;color:rgba(235,248,255,var(--text-opacity))}.lg\:text-blue-200{--text-opacity:1;color:#bee3f8;color:rgba(190,227,248,var(--text-opacity))}.lg\:text-blue-300{--text-opacity:1;color:#90cdf4;color:rgba(144,205,244,var(--text-opacity))}.lg\:text-blue-400{--text-opacity:1;color:#63b3ed;color:rgba(99,179,237,var(--text-opacity))}.lg\:text-blue-500{--text-opacity:1;color:#4299e1;color:rgba(66,153,225,var(--text-opacity))}.lg\:text-blue-600{--text-opacity:1;color:#3182ce;color:rgba(49,130,206,var(--text-opacity))}.lg\:text-blue-700{--text-opacity:1;color:#2b6cb0;color:rgba(43,108,176,var(--text-opacity))}.lg\:text-blue-800{--text-opacity:1;color:#2c5282;color:rgba(44,82,130,var(--text-opacity))}.lg\:text-blue-900{--text-opacity:1;color:#2a4365;color:rgba(42,67,101,var(--text-opacity))}.lg\:text-indigo-100{--text-opacity:1;color:#ebf4ff;color:rgba(235,244,255,var(--text-opacity))}.lg\:text-indigo-200{--text-opacity:1;color:#c3dafe;color:rgba(195,218,254,var(--text-opacity))}.lg\:text-indigo-300{--text-opacity:1;color:#a3bffa;color:rgba(163,191,250,var(--text-opacity))}.lg\:text-indigo-400{--text-opacity:1;color:#7f9cf5;color:rgba(127,156,245,var(--text-opacity))}.lg\:text-indigo-500{--text-opacity:1;color:#667eea;color:rgba(102,126,234,var(--text-opacity))}.lg\:text-indigo-600{--text-opacity:1;color:#5a67d8;color:rgba(90,103,216,var(--text-opacity))}.lg\:text-indigo-700{--text-opacity:1;color:#4c51bf;color:rgba(76,81,191,var(--text-opacity))}.lg\:text-indigo-800{--text-opacity:1;color:#434190;color:rgba(67,65,144,var(--text-opacity))}.lg\:text-indigo-900{--text-opacity:1;color:#3c366b;color:rgba(60,54,107,var(--text-opacity))}.lg\:text-purple-100{--text-opacity:1;color:#faf5ff;color:rgba(250,245,255,var(--text-opacity))}.lg\:text-purple-200{--text-opacity:1;color:#e9d8fd;color:rgba(233,216,253,var(--text-opacity))}.lg\:text-purple-300{--text-opacity:1;color:#d6bcfa;color:rgba(214,188,250,var(--text-opacity))}.lg\:text-purple-400{--text-opacity:1;color:#b794f4;color:rgba(183,148,244,var(--text-opacity))}.lg\:text-purple-500{--text-opacity:1;color:#9f7aea;color:rgba(159,122,234,var(--text-opacity))}.lg\:text-purple-600{--text-opacity:1;color:#805ad5;color:rgba(128,90,213,var(--text-opacity))}.lg\:text-purple-700{--text-opacity:1;color:#6b46c1;color:rgba(107,70,193,var(--text-opacity))}.lg\:text-purple-800{--text-opacity:1;color:#553c9a;color:rgba(85,60,154,var(--text-opacity))}.lg\:text-purple-900{--text-opacity:1;color:#44337a;color:rgba(68,51,122,var(--text-opacity))}.lg\:text-pink-100{--text-opacity:1;color:#fff5f7;color:rgba(255,245,247,var(--text-opacity))}.lg\:text-pink-200{--text-opacity:1;color:#fed7e2;color:rgba(254,215,226,var(--text-opacity))}.lg\:text-pink-300{--text-opacity:1;color:#fbb6ce;color:rgba(251,182,206,var(--text-opacity))}.lg\:text-pink-400{--text-opacity:1;color:#f687b3;color:rgba(246,135,179,var(--text-opacity))}.lg\:text-pink-500{--text-opacity:1;color:#ed64a6;color:rgba(237,100,166,var(--text-opacity))}.lg\:text-pink-600{--text-opacity:1;color:#d53f8c;color:rgba(213,63,140,var(--text-opacity))}.lg\:text-pink-700{--text-opacity:1;color:#b83280;color:rgba(184,50,128,var(--text-opacity))}.lg\:text-pink-800{--text-opacity:1;color:#97266d;color:rgba(151,38,109,var(--text-opacity))}.lg\:text-pink-900{--text-opacity:1;color:#702459;color:rgba(112,36,89,var(--text-opacity))}.lg\:hover\:text-transparent:hover{color:transparent}.lg\:hover\:text-current:hover{color:currentColor}.lg\:hover\:text-black:hover{--text-opacity:1;color:#000;color:rgba(0,0,0,var(--text-opacity))}.lg\:hover\:text-white:hover{--text-opacity:1;color:#fff;color:rgba(255,255,255,var(--text-opacity))}.lg\:hover\:text-gray-100:hover{--text-opacity:1;color:#f7fafc;color:rgba(247,250,252,var(--text-opacity))}.lg\:hover\:text-gray-200:hover{--text-opacity:1;color:#edf2f7;color:rgba(237,242,247,var(--text-opacity))}.lg\:hover\:text-gray-300:hover{--text-opacity:1;color:#e2e8f0;color:rgba(226,232,240,var(--text-opacity))}.lg\:hover\:text-gray-400:hover{--text-opacity:1;color:#cbd5e0;color:rgba(203,213,224,var(--text-opacity))}.lg\:hover\:text-gray-500:hover{--text-opacity:1;color:#a0aec0;color:rgba(160,174,192,var(--text-opacity))}.lg\:hover\:text-gray-600:hover{--text-opacity:1;color:#718096;color:rgba(113,128,150,var(--text-opacity))}.lg\:hover\:text-gray-700:hover{--text-opacity:1;color:#4a5568;color:rgba(74,85,104,var(--text-opacity))}.lg\:hover\:text-gray-800:hover{--text-opacity:1;color:#2d3748;color:rgba(45,55,72,var(--text-opacity))}.lg\:hover\:text-gray-900:hover{--text-opacity:1;color:#1a202c;color:rgba(26,32,44,var(--text-opacity))}.lg\:hover\:text-red-100:hover{--text-opacity:1;color:#fff5f5;color:rgba(255,245,245,var(--text-opacity))}.lg\:hover\:text-red-200:hover{--text-opacity:1;color:#fed7d7;color:rgba(254,215,215,var(--text-opacity))}.lg\:hover\:text-red-300:hover{--text-opacity:1;color:#feb2b2;color:rgba(254,178,178,var(--text-opacity))}.lg\:hover\:text-red-400:hover{--text-opacity:1;color:#fc8181;color:rgba(252,129,129,var(--text-opacity))}.lg\:hover\:text-red-500:hover{--text-opacity:1;color:#f56565;color:rgba(245,101,101,var(--text-opacity))}.lg\:hover\:text-red-600:hover{--text-opacity:1;color:#e53e3e;color:rgba(229,62,62,var(--text-opacity))}.lg\:hover\:text-red-700:hover{--text-opacity:1;color:#c53030;color:rgba(197,48,48,var(--text-opacity))}.lg\:hover\:text-red-800:hover{--text-opacity:1;color:#9b2c2c;color:rgba(155,44,44,var(--text-opacity))}.lg\:hover\:text-red-900:hover{--text-opacity:1;color:#742a2a;color:rgba(116,42,42,var(--text-opacity))}.lg\:hover\:text-orange-100:hover{--text-opacity:1;color:#fffaf0;color:rgba(255,250,240,var(--text-opacity))}.lg\:hover\:text-orange-200:hover{--text-opacity:1;color:#feebc8;color:rgba(254,235,200,var(--text-opacity))}.lg\:hover\:text-orange-300:hover{--text-opacity:1;color:#fbd38d;color:rgba(251,211,141,var(--text-opacity))}.lg\:hover\:text-orange-400:hover{--text-opacity:1;color:#f6ad55;color:rgba(246,173,85,var(--text-opacity))}.lg\:hover\:text-orange-500:hover{--text-opacity:1;color:#ed8936;color:rgba(237,137,54,var(--text-opacity))}.lg\:hover\:text-orange-600:hover{--text-opacity:1;color:#dd6b20;color:rgba(221,107,32,var(--text-opacity))}.lg\:hover\:text-orange-700:hover{--text-opacity:1;color:#c05621;color:rgba(192,86,33,var(--text-opacity))}.lg\:hover\:text-orange-800:hover{--text-opacity:1;color:#9c4221;color:rgba(156,66,33,var(--text-opacity))}.lg\:hover\:text-orange-900:hover{--text-opacity:1;color:#7b341e;color:rgba(123,52,30,var(--text-opacity))}.lg\:hover\:text-yellow-100:hover{--text-opacity:1;color:ivory;color:rgba(255,255,240,var(--text-opacity))}.lg\:hover\:text-yellow-200:hover{--text-opacity:1;color:#fefcbf;color:rgba(254,252,191,var(--text-opacity))}.lg\:hover\:text-yellow-300:hover{--text-opacity:1;color:#faf089;color:rgba(250,240,137,var(--text-opacity))}.lg\:hover\:text-yellow-400:hover{--text-opacity:1;color:#f6e05e;color:rgba(246,224,94,var(--text-opacity))}.lg\:hover\:text-yellow-500:hover{--text-opacity:1;color:#ecc94b;color:rgba(236,201,75,var(--text-opacity))}.lg\:hover\:text-yellow-600:hover{--text-opacity:1;color:#d69e2e;color:rgba(214,158,46,var(--text-opacity))}.lg\:hover\:text-yellow-700:hover{--text-opacity:1;color:#b7791f;color:rgba(183,121,31,var(--text-opacity))}.lg\:hover\:text-yellow-800:hover{--text-opacity:1;color:#975a16;color:rgba(151,90,22,var(--text-opacity))}.lg\:hover\:text-yellow-900:hover{--text-opacity:1;color:#744210;color:rgba(116,66,16,var(--text-opacity))}.lg\:hover\:text-green-100:hover{--text-opacity:1;color:#f0fff4;color:rgba(240,255,244,var(--text-opacity))}.lg\:hover\:text-green-200:hover{--text-opacity:1;color:#c6f6d5;color:rgba(198,246,213,var(--text-opacity))}.lg\:hover\:text-green-300:hover{--text-opacity:1;color:#9ae6b4;color:rgba(154,230,180,var(--text-opacity))}.lg\:hover\:text-green-400:hover{--text-opacity:1;color:#68d391;color:rgba(104,211,145,var(--text-opacity))}.lg\:hover\:text-green-500:hover{--text-opacity:1;color:#48bb78;color:rgba(72,187,120,var(--text-opacity))}.lg\:hover\:text-green-600:hover{--text-opacity:1;color:#38a169;color:rgba(56,161,105,var(--text-opacity))}.lg\:hover\:text-green-700:hover{--text-opacity:1;color:#2f855a;color:rgba(47,133,90,var(--text-opacity))}.lg\:hover\:text-green-800:hover{--text-opacity:1;color:#276749;color:rgba(39,103,73,var(--text-opacity))}.lg\:hover\:text-green-900:hover{--text-opacity:1;color:#22543d;color:rgba(34,84,61,var(--text-opacity))}.lg\:hover\:text-teal-100:hover{--text-opacity:1;color:#e6fffa;color:rgba(230,255,250,var(--text-opacity))}.lg\:hover\:text-teal-200:hover{--text-opacity:1;color:#b2f5ea;color:rgba(178,245,234,var(--text-opacity))}.lg\:hover\:text-teal-300:hover{--text-opacity:1;color:#81e6d9;color:rgba(129,230,217,var(--text-opacity))}.lg\:hover\:text-teal-400:hover{--text-opacity:1;color:#4fd1c5;color:rgba(79,209,197,var(--text-opacity))}.lg\:hover\:text-teal-500:hover{--text-opacity:1;color:#38b2ac;color:rgba(56,178,172,var(--text-opacity))}.lg\:hover\:text-teal-600:hover{--text-opacity:1;color:#319795;color:rgba(49,151,149,var(--text-opacity))}.lg\:hover\:text-teal-700:hover{--text-opacity:1;color:#2c7a7b;color:rgba(44,122,123,var(--text-opacity))}.lg\:hover\:text-teal-800:hover{--text-opacity:1;color:#285e61;color:rgba(40,94,97,var(--text-opacity))}.lg\:hover\:text-teal-900:hover{--text-opacity:1;color:#234e52;color:rgba(35,78,82,var(--text-opacity))}.lg\:hover\:text-blue-100:hover{--text-opacity:1;color:#ebf8ff;color:rgba(235,248,255,var(--text-opacity))}.lg\:hover\:text-blue-200:hover{--text-opacity:1;color:#bee3f8;color:rgba(190,227,248,var(--text-opacity))}.lg\:hover\:text-blue-300:hover{--text-opacity:1;color:#90cdf4;color:rgba(144,205,244,var(--text-opacity))}.lg\:hover\:text-blue-400:hover{--text-opacity:1;color:#63b3ed;color:rgba(99,179,237,var(--text-opacity))}.lg\:hover\:text-blue-500:hover{--text-opacity:1;color:#4299e1;color:rgba(66,153,225,var(--text-opacity))}.lg\:hover\:text-blue-600:hover{--text-opacity:1;color:#3182ce;color:rgba(49,130,206,var(--text-opacity))}.lg\:hover\:text-blue-700:hover{--text-opacity:1;color:#2b6cb0;color:rgba(43,108,176,var(--text-opacity))}.lg\:hover\:text-blue-800:hover{--text-opacity:1;color:#2c5282;color:rgba(44,82,130,var(--text-opacity))}.lg\:hover\:text-blue-900:hover{--text-opacity:1;color:#2a4365;color:rgba(42,67,101,var(--text-opacity))}.lg\:hover\:text-indigo-100:hover{--text-opacity:1;color:#ebf4ff;color:rgba(235,244,255,var(--text-opacity))}.lg\:hover\:text-indigo-200:hover{--text-opacity:1;color:#c3dafe;color:rgba(195,218,254,var(--text-opacity))}.lg\:hover\:text-indigo-300:hover{--text-opacity:1;color:#a3bffa;color:rgba(163,191,250,var(--text-opacity))}.lg\:hover\:text-indigo-400:hover{--text-opacity:1;color:#7f9cf5;color:rgba(127,156,245,var(--text-opacity))}.lg\:hover\:text-indigo-500:hover{--text-opacity:1;color:#667eea;color:rgba(102,126,234,var(--text-opacity))}.lg\:hover\:text-indigo-600:hover{--text-opacity:1;color:#5a67d8;color:rgba(90,103,216,var(--text-opacity))}.lg\:hover\:text-indigo-700:hover{--text-opacity:1;color:#4c51bf;color:rgba(76,81,191,var(--text-opacity))}.lg\:hover\:text-indigo-800:hover{--text-opacity:1;color:#434190;color:rgba(67,65,144,var(--text-opacity))}.lg\:hover\:text-indigo-900:hover{--text-opacity:1;color:#3c366b;color:rgba(60,54,107,var(--text-opacity))}.lg\:hover\:text-purple-100:hover{--text-opacity:1;color:#faf5ff;color:rgba(250,245,255,var(--text-opacity))}.lg\:hover\:text-purple-200:hover{--text-opacity:1;color:#e9d8fd;color:rgba(233,216,253,var(--text-opacity))}.lg\:hover\:text-purple-300:hover{--text-opacity:1;color:#d6bcfa;color:rgba(214,188,250,var(--text-opacity))}.lg\:hover\:text-purple-400:hover{--text-opacity:1;color:#b794f4;color:rgba(183,148,244,var(--text-opacity))}.lg\:hover\:text-purple-500:hover{--text-opacity:1;color:#9f7aea;color:rgba(159,122,234,var(--text-opacity))}.lg\:hover\:text-purple-600:hover{--text-opacity:1;color:#805ad5;color:rgba(128,90,213,var(--text-opacity))}.lg\:hover\:text-purple-700:hover{--text-opacity:1;color:#6b46c1;color:rgba(107,70,193,var(--text-opacity))}.lg\:hover\:text-purple-800:hover{--text-opacity:1;color:#553c9a;color:rgba(85,60,154,var(--text-opacity))}.lg\:hover\:text-purple-900:hover{--text-opacity:1;color:#44337a;color:rgba(68,51,122,var(--text-opacity))}.lg\:hover\:text-pink-100:hover{--text-opacity:1;color:#fff5f7;color:rgba(255,245,247,var(--text-opacity))}.lg\:hover\:text-pink-200:hover{--text-opacity:1;color:#fed7e2;color:rgba(254,215,226,var(--text-opacity))}.lg\:hover\:text-pink-300:hover{--text-opacity:1;color:#fbb6ce;color:rgba(251,182,206,var(--text-opacity))}.lg\:hover\:text-pink-400:hover{--text-opacity:1;color:#f687b3;color:rgba(246,135,179,var(--text-opacity))}.lg\:hover\:text-pink-500:hover{--text-opacity:1;color:#ed64a6;color:rgba(237,100,166,var(--text-opacity))}.lg\:hover\:text-pink-600:hover{--text-opacity:1;color:#d53f8c;color:rgba(213,63,140,var(--text-opacity))}.lg\:hover\:text-pink-700:hover{--text-opacity:1;color:#b83280;color:rgba(184,50,128,var(--text-opacity))}.lg\:hover\:text-pink-800:hover{--text-opacity:1;color:#97266d;color:rgba(151,38,109,var(--text-opacity))}.lg\:hover\:text-pink-900:hover{--text-opacity:1;color:#702459;color:rgba(112,36,89,var(--text-opacity))}.lg\:focus\:text-transparent:focus{color:transparent}.lg\:focus\:text-current:focus{color:currentColor}.lg\:focus\:text-black:focus{--text-opacity:1;color:#000;color:rgba(0,0,0,var(--text-opacity))}.lg\:focus\:text-white:focus{--text-opacity:1;color:#fff;color:rgba(255,255,255,var(--text-opacity))}.lg\:focus\:text-gray-100:focus{--text-opacity:1;color:#f7fafc;color:rgba(247,250,252,var(--text-opacity))}.lg\:focus\:text-gray-200:focus{--text-opacity:1;color:#edf2f7;color:rgba(237,242,247,var(--text-opacity))}.lg\:focus\:text-gray-300:focus{--text-opacity:1;color:#e2e8f0;color:rgba(226,232,240,var(--text-opacity))}.lg\:focus\:text-gray-400:focus{--text-opacity:1;color:#cbd5e0;color:rgba(203,213,224,var(--text-opacity))}.lg\:focus\:text-gray-500:focus{--text-opacity:1;color:#a0aec0;color:rgba(160,174,192,var(--text-opacity))}.lg\:focus\:text-gray-600:focus{--text-opacity:1;color:#718096;color:rgba(113,128,150,var(--text-opacity))}.lg\:focus\:text-gray-700:focus{--text-opacity:1;color:#4a5568;color:rgba(74,85,104,var(--text-opacity))}.lg\:focus\:text-gray-800:focus{--text-opacity:1;color:#2d3748;color:rgba(45,55,72,var(--text-opacity))}.lg\:focus\:text-gray-900:focus{--text-opacity:1;color:#1a202c;color:rgba(26,32,44,var(--text-opacity))}.lg\:focus\:text-red-100:focus{--text-opacity:1;color:#fff5f5;color:rgba(255,245,245,var(--text-opacity))}.lg\:focus\:text-red-200:focus{--text-opacity:1;color:#fed7d7;color:rgba(254,215,215,var(--text-opacity))}.lg\:focus\:text-red-300:focus{--text-opacity:1;color:#feb2b2;color:rgba(254,178,178,var(--text-opacity))}.lg\:focus\:text-red-400:focus{--text-opacity:1;color:#fc8181;color:rgba(252,129,129,var(--text-opacity))}.lg\:focus\:text-red-500:focus{--text-opacity:1;color:#f56565;color:rgba(245,101,101,var(--text-opacity))}.lg\:focus\:text-red-600:focus{--text-opacity:1;color:#e53e3e;color:rgba(229,62,62,var(--text-opacity))}.lg\:focus\:text-red-700:focus{--text-opacity:1;color:#c53030;color:rgba(197,48,48,var(--text-opacity))}.lg\:focus\:text-red-800:focus{--text-opacity:1;color:#9b2c2c;color:rgba(155,44,44,var(--text-opacity))}.lg\:focus\:text-red-900:focus{--text-opacity:1;color:#742a2a;color:rgba(116,42,42,var(--text-opacity))}.lg\:focus\:text-orange-100:focus{--text-opacity:1;color:#fffaf0;color:rgba(255,250,240,var(--text-opacity))}.lg\:focus\:text-orange-200:focus{--text-opacity:1;color:#feebc8;color:rgba(254,235,200,var(--text-opacity))}.lg\:focus\:text-orange-300:focus{--text-opacity:1;color:#fbd38d;color:rgba(251,211,141,var(--text-opacity))}.lg\:focus\:text-orange-400:focus{--text-opacity:1;color:#f6ad55;color:rgba(246,173,85,var(--text-opacity))}.lg\:focus\:text-orange-500:focus{--text-opacity:1;color:#ed8936;color:rgba(237,137,54,var(--text-opacity))}.lg\:focus\:text-orange-600:focus{--text-opacity:1;color:#dd6b20;color:rgba(221,107,32,var(--text-opacity))}.lg\:focus\:text-orange-700:focus{--text-opacity:1;color:#c05621;color:rgba(192,86,33,var(--text-opacity))}.lg\:focus\:text-orange-800:focus{--text-opacity:1;color:#9c4221;color:rgba(156,66,33,var(--text-opacity))}.lg\:focus\:text-orange-900:focus{--text-opacity:1;color:#7b341e;color:rgba(123,52,30,var(--text-opacity))}.lg\:focus\:text-yellow-100:focus{--text-opacity:1;color:ivory;color:rgba(255,255,240,var(--text-opacity))}.lg\:focus\:text-yellow-200:focus{--text-opacity:1;color:#fefcbf;color:rgba(254,252,191,var(--text-opacity))}.lg\:focus\:text-yellow-300:focus{--text-opacity:1;color:#faf089;color:rgba(250,240,137,var(--text-opacity))}.lg\:focus\:text-yellow-400:focus{--text-opacity:1;color:#f6e05e;color:rgba(246,224,94,var(--text-opacity))}.lg\:focus\:text-yellow-500:focus{--text-opacity:1;color:#ecc94b;color:rgba(236,201,75,var(--text-opacity))}.lg\:focus\:text-yellow-600:focus{--text-opacity:1;color:#d69e2e;color:rgba(214,158,46,var(--text-opacity))}.lg\:focus\:text-yellow-700:focus{--text-opacity:1;color:#b7791f;color:rgba(183,121,31,var(--text-opacity))}.lg\:focus\:text-yellow-800:focus{--text-opacity:1;color:#975a16;color:rgba(151,90,22,var(--text-opacity))}.lg\:focus\:text-yellow-900:focus{--text-opacity:1;color:#744210;color:rgba(116,66,16,var(--text-opacity))}.lg\:focus\:text-green-100:focus{--text-opacity:1;color:#f0fff4;color:rgba(240,255,244,var(--text-opacity))}.lg\:focus\:text-green-200:focus{--text-opacity:1;color:#c6f6d5;color:rgba(198,246,213,var(--text-opacity))}.lg\:focus\:text-green-300:focus{--text-opacity:1;color:#9ae6b4;color:rgba(154,230,180,var(--text-opacity))}.lg\:focus\:text-green-400:focus{--text-opacity:1;color:#68d391;color:rgba(104,211,145,var(--text-opacity))}.lg\:focus\:text-green-500:focus{--text-opacity:1;color:#48bb78;color:rgba(72,187,120,var(--text-opacity))}.lg\:focus\:text-green-600:focus{--text-opacity:1;color:#38a169;color:rgba(56,161,105,var(--text-opacity))}.lg\:focus\:text-green-700:focus{--text-opacity:1;color:#2f855a;color:rgba(47,133,90,var(--text-opacity))}.lg\:focus\:text-green-800:focus{--text-opacity:1;color:#276749;color:rgba(39,103,73,var(--text-opacity))}.lg\:focus\:text-green-900:focus{--text-opacity:1;color:#22543d;color:rgba(34,84,61,var(--text-opacity))}.lg\:focus\:text-teal-100:focus{--text-opacity:1;color:#e6fffa;color:rgba(230,255,250,var(--text-opacity))}.lg\:focus\:text-teal-200:focus{--text-opacity:1;color:#b2f5ea;color:rgba(178,245,234,var(--text-opacity))}.lg\:focus\:text-teal-300:focus{--text-opacity:1;color:#81e6d9;color:rgba(129,230,217,var(--text-opacity))}.lg\:focus\:text-teal-400:focus{--text-opacity:1;color:#4fd1c5;color:rgba(79,209,197,var(--text-opacity))}.lg\:focus\:text-teal-500:focus{--text-opacity:1;color:#38b2ac;color:rgba(56,178,172,var(--text-opacity))}.lg\:focus\:text-teal-600:focus{--text-opacity:1;color:#319795;color:rgba(49,151,149,var(--text-opacity))}.lg\:focus\:text-teal-700:focus{--text-opacity:1;color:#2c7a7b;color:rgba(44,122,123,var(--text-opacity))}.lg\:focus\:text-teal-800:focus{--text-opacity:1;color:#285e61;color:rgba(40,94,97,var(--text-opacity))}.lg\:focus\:text-teal-900:focus{--text-opacity:1;color:#234e52;color:rgba(35,78,82,var(--text-opacity))}.lg\:focus\:text-blue-100:focus{--text-opacity:1;color:#ebf8ff;color:rgba(235,248,255,var(--text-opacity))}.lg\:focus\:text-blue-200:focus{--text-opacity:1;color:#bee3f8;color:rgba(190,227,248,var(--text-opacity))}.lg\:focus\:text-blue-300:focus{--text-opacity:1;color:#90cdf4;color:rgba(144,205,244,var(--text-opacity))}.lg\:focus\:text-blue-400:focus{--text-opacity:1;color:#63b3ed;color:rgba(99,179,237,var(--text-opacity))}.lg\:focus\:text-blue-500:focus{--text-opacity:1;color:#4299e1;color:rgba(66,153,225,var(--text-opacity))}.lg\:focus\:text-blue-600:focus{--text-opacity:1;color:#3182ce;color:rgba(49,130,206,var(--text-opacity))}.lg\:focus\:text-blue-700:focus{--text-opacity:1;color:#2b6cb0;color:rgba(43,108,176,var(--text-opacity))}.lg\:focus\:text-blue-800:focus{--text-opacity:1;color:#2c5282;color:rgba(44,82,130,var(--text-opacity))}.lg\:focus\:text-blue-900:focus{--text-opacity:1;color:#2a4365;color:rgba(42,67,101,var(--text-opacity))}.lg\:focus\:text-indigo-100:focus{--text-opacity:1;color:#ebf4ff;color:rgba(235,244,255,var(--text-opacity))}.lg\:focus\:text-indigo-200:focus{--text-opacity:1;color:#c3dafe;color:rgba(195,218,254,var(--text-opacity))}.lg\:focus\:text-indigo-300:focus{--text-opacity:1;color:#a3bffa;color:rgba(163,191,250,var(--text-opacity))}.lg\:focus\:text-indigo-400:focus{--text-opacity:1;color:#7f9cf5;color:rgba(127,156,245,var(--text-opacity))}.lg\:focus\:text-indigo-500:focus{--text-opacity:1;color:#667eea;color:rgba(102,126,234,var(--text-opacity))}.lg\:focus\:text-indigo-600:focus{--text-opacity:1;color:#5a67d8;color:rgba(90,103,216,var(--text-opacity))}.lg\:focus\:text-indigo-700:focus{--text-opacity:1;color:#4c51bf;color:rgba(76,81,191,var(--text-opacity))}.lg\:focus\:text-indigo-800:focus{--text-opacity:1;color:#434190;color:rgba(67,65,144,var(--text-opacity))}.lg\:focus\:text-indigo-900:focus{--text-opacity:1;color:#3c366b;color:rgba(60,54,107,var(--text-opacity))}.lg\:focus\:text-purple-100:focus{--text-opacity:1;color:#faf5ff;color:rgba(250,245,255,var(--text-opacity))}.lg\:focus\:text-purple-200:focus{--text-opacity:1;color:#e9d8fd;color:rgba(233,216,253,var(--text-opacity))}.lg\:focus\:text-purple-300:focus{--text-opacity:1;color:#d6bcfa;color:rgba(214,188,250,var(--text-opacity))}.lg\:focus\:text-purple-400:focus{--text-opacity:1;color:#b794f4;color:rgba(183,148,244,var(--text-opacity))}.lg\:focus\:text-purple-500:focus{--text-opacity:1;color:#9f7aea;color:rgba(159,122,234,var(--text-opacity))}.lg\:focus\:text-purple-600:focus{--text-opacity:1;color:#805ad5;color:rgba(128,90,213,var(--text-opacity))}.lg\:focus\:text-purple-700:focus{--text-opacity:1;color:#6b46c1;color:rgba(107,70,193,var(--text-opacity))}.lg\:focus\:text-purple-800:focus{--text-opacity:1;color:#553c9a;color:rgba(85,60,154,var(--text-opacity))}.lg\:focus\:text-purple-900:focus{--text-opacity:1;color:#44337a;color:rgba(68,51,122,var(--text-opacity))}.lg\:focus\:text-pink-100:focus{--text-opacity:1;color:#fff5f7;color:rgba(255,245,247,var(--text-opacity))}.lg\:focus\:text-pink-200:focus{--text-opacity:1;color:#fed7e2;color:rgba(254,215,226,var(--text-opacity))}.lg\:focus\:text-pink-300:focus{--text-opacity:1;color:#fbb6ce;color:rgba(251,182,206,var(--text-opacity))}.lg\:focus\:text-pink-400:focus{--text-opacity:1;color:#f687b3;color:rgba(246,135,179,var(--text-opacity))}.lg\:focus\:text-pink-500:focus{--text-opacity:1;color:#ed64a6;color:rgba(237,100,166,var(--text-opacity))}.lg\:focus\:text-pink-600:focus{--text-opacity:1;color:#d53f8c;color:rgba(213,63,140,var(--text-opacity))}.lg\:focus\:text-pink-700:focus{--text-opacity:1;color:#b83280;color:rgba(184,50,128,var(--text-opacity))}.lg\:focus\:text-pink-800:focus{--text-opacity:1;color:#97266d;color:rgba(151,38,109,var(--text-opacity))}.lg\:focus\:text-pink-900:focus{--text-opacity:1;color:#702459;color:rgba(112,36,89,var(--text-opacity))}.lg\:text-opacity-0{--text-opacity:0}.lg\:text-opacity-25{--text-opacity:0.25}.lg\:text-opacity-50{--text-opacity:0.5}.lg\:text-opacity-75{--text-opacity:0.75}.lg\:text-opacity-100{--text-opacity:1}.lg\:hover\:text-opacity-0:hover{--text-opacity:0}.lg\:hover\:text-opacity-25:hover{--text-opacity:0.25}.lg\:hover\:text-opacity-50:hover{--text-opacity:0.5}.lg\:hover\:text-opacity-75:hover{--text-opacity:0.75}.lg\:hover\:text-opacity-100:hover{--text-opacity:1}.lg\:focus\:text-opacity-0:focus{--text-opacity:0}.lg\:focus\:text-opacity-25:focus{--text-opacity:0.25}.lg\:focus\:text-opacity-50:focus{--text-opacity:0.5}.lg\:focus\:text-opacity-75:focus{--text-opacity:0.75}.lg\:focus\:text-opacity-100:focus{--text-opacity:1}.lg\:italic{font-style:italic}.lg\:not-italic{font-style:normal}.lg\:uppercase{text-transform:uppercase}.lg\:lowercase{text-transform:lowercase}.lg\:capitalize{text-transform:capitalize}.lg\:normal-case{text-transform:none}.lg\:underline{text-decoration:underline}.lg\:line-through{text-decoration:line-through}.lg\:no-underline{text-decoration:none}.lg\:hover\:underline:hover{text-decoration:underline}.lg\:hover\:line-through:hover{text-decoration:line-through}.lg\:hover\:no-underline:hover{text-decoration:none}.lg\:focus\:underline:focus{text-decoration:underline}.lg\:focus\:line-through:focus{text-decoration:line-through}.lg\:focus\:no-underline:focus{text-decoration:none}.lg\:antialiased{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.lg\:subpixel-antialiased{-webkit-font-smoothing:auto;-moz-osx-font-smoothing:auto}.lg\:diagonal-fractions,.lg\:lining-nums,.lg\:oldstyle-nums,.lg\:ordinal,.lg\:proportional-nums,.lg\:slashed-zero,.lg\:stacked-fractions,.lg\:tabular-nums{--font-variant-numeric-ordinal:var(--tailwind-empty, );/*!*//*!*/--font-variant-numeric-slashed-zero:var(--tailwind-empty, );/*!*//*!*/--font-variant-numeric-figure:var(--tailwind-empty, );/*!*//*!*/--font-variant-numeric-spacing:var(--tailwind-empty, );/*!*//*!*/--font-variant-numeric-fraction:var(--tailwind-empty, );/*!*//*!*/font-variant-numeric:var(--font-variant-numeric-ordinal) var(--font-variant-numeric-slashed-zero) var(--font-variant-numeric-figure) var(--font-variant-numeric-spacing) var(--font-variant-numeric-fraction)}.lg\:normal-nums{font-variant-numeric:normal}.lg\:ordinal{--font-variant-numeric-ordinal:ordinal}.lg\:slashed-zero{--font-variant-numeric-slashed-zero:slashed-zero}.lg\:lining-nums{--font-variant-numeric-figure:lining-nums}.lg\:oldstyle-nums{--font-variant-numeric-figure:oldstyle-nums}.lg\:proportional-nums{--font-variant-numeric-spacing:proportional-nums}.lg\:tabular-nums{--font-variant-numeric-spacing:tabular-nums}.lg\:diagonal-fractions{--font-variant-numeric-fraction:diagonal-fractions}.lg\:stacked-fractions{--font-variant-numeric-fraction:stacked-fractions}.lg\:tracking-tighter{letter-spacing:-.05em}.lg\:tracking-tight{letter-spacing:-.025em}.lg\:tracking-normal{letter-spacing:0}.lg\:tracking-wide{letter-spacing:.025em}.lg\:tracking-wider{letter-spacing:.05em}.lg\:tracking-widest{letter-spacing:.1em}.lg\:select-none{-webkit-user-select:none;-ms-user-select:none;user-select:none}.lg\:select-text{-webkit-user-select:text;-ms-user-select:text;user-select:text}.lg\:select-all{-webkit-user-select:all;-ms-user-select:all;user-select:all}.lg\:select-auto{-webkit-user-select:auto;-ms-user-select:auto;user-select:auto}.lg\:align-baseline{vertical-align:baseline}.lg\:align-top{vertical-align:top}.lg\:align-middle{vertical-align:middle}.lg\:align-bottom{vertical-align:bottom}.lg\:align-text-top{vertical-align:text-top}.lg\:align-text-bottom{vertical-align:text-bottom}.lg\:visible{visibility:visible}.lg\:invisible{visibility:hidden}.lg\:whitespace-normal{white-space:normal}.lg\:whitespace-no-wrap{white-space:nowrap}.lg\:whitespace-pre{white-space:pre}.lg\:whitespace-pre-line{white-space:pre-line}.lg\:whitespace-pre-wrap{white-space:pre-wrap}.lg\:break-normal{word-wrap:normal;overflow-wrap:normal;word-break:normal}.lg\:break-words{word-wrap:break-word;overflow-wrap:break-word}.lg\:break-all{word-break:break-all}.lg\:truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.lg\:w-0{width:0}.lg\:w-1{width:.25rem}.lg\:w-2{width:.5rem}.lg\:w-3{width:.75rem}.lg\:w-4{width:1rem}.lg\:w-5{width:1.25rem}.lg\:w-6{width:1.5rem}.lg\:w-8{width:2rem}.lg\:w-10{width:2.5rem}.lg\:w-12{width:3rem}.lg\:w-16{width:4rem}.lg\:w-20{width:5rem}.lg\:w-24{width:6rem}.lg\:w-32{width:8rem}.lg\:w-40{width:10rem}.lg\:w-48{width:12rem}.lg\:w-56{width:14rem}.lg\:w-64{width:16rem}.lg\:w-auto{width:auto}.lg\:w-px{width:1px}.lg\:w-1\/2{width:50%}.lg\:w-1\/3{width:33.333333%}.lg\:w-2\/3{width:66.666667%}.lg\:w-1\/4{width:25%}.lg\:w-2\/4{width:50%}.lg\:w-3\/4{width:75%}.lg\:w-1\/5{width:20%}.lg\:w-2\/5{width:40%}.lg\:w-3\/5{width:60%}.lg\:w-4\/5{width:80%}.lg\:w-1\/6{width:16.666667%}.lg\:w-2\/6{width:33.333333%}.lg\:w-3\/6{width:50%}.lg\:w-4\/6{width:66.666667%}.lg\:w-5\/6{width:83.333333%}.lg\:w-1\/12{width:8.333333%}.lg\:w-2\/12{width:16.666667%}.lg\:w-3\/12{width:25%}.lg\:w-4\/12{width:33.333333%}.lg\:w-5\/12{width:41.666667%}.lg\:w-6\/12{width:50%}.lg\:w-7\/12{width:58.333333%}.lg\:w-8\/12{width:66.666667%}.lg\:w-9\/12{width:75%}.lg\:w-10\/12{width:83.333333%}.lg\:w-11\/12{width:91.666667%}.lg\:w-full{width:100%}.lg\:w-screen{width:100vw}.lg\:z-0{z-index:0}.lg\:z-10{z-index:10}.lg\:z-20{z-index:20}.lg\:z-30{z-index:30}.lg\:z-40{z-index:40}.lg\:z-50{z-index:50}.lg\:z-auto{z-index:auto}.lg\:gap-0{grid-gap:0;gap:0}.lg\:gap-1{grid-gap:.25rem;gap:.25rem}.lg\:gap-2{grid-gap:.5rem;gap:.5rem}.lg\:gap-3{grid-gap:.75rem;gap:.75rem}.lg\:gap-4{grid-gap:1rem;gap:1rem}.lg\:gap-5{grid-gap:1.25rem;gap:1.25rem}.lg\:gap-6{grid-gap:1.5rem;gap:1.5rem}.lg\:gap-8{grid-gap:2rem;gap:2rem}.lg\:gap-10{grid-gap:2.5rem;gap:2.5rem}.lg\:gap-12{grid-gap:3rem;gap:3rem}.lg\:gap-16{grid-gap:4rem;gap:4rem}.lg\:gap-20{grid-gap:5rem;gap:5rem}.lg\:gap-24{grid-gap:6rem;gap:6rem}.lg\:gap-32{grid-gap:8rem;gap:8rem}.lg\:gap-40{grid-gap:10rem;gap:10rem}.lg\:gap-48{grid-gap:12rem;gap:12rem}.lg\:gap-56{grid-gap:14rem;gap:14rem}.lg\:gap-64{grid-gap:16rem;gap:16rem}.lg\:gap-px{grid-gap:1px;gap:1px}.lg\:col-gap-0{grid-column-gap:0;column-gap:0}.lg\:col-gap-1{grid-column-gap:.25rem;column-gap:.25rem}.lg\:col-gap-2{grid-column-gap:.5rem;column-gap:.5rem}.lg\:col-gap-3{grid-column-gap:.75rem;column-gap:.75rem}.lg\:col-gap-4{grid-column-gap:1rem;column-gap:1rem}.lg\:col-gap-5{grid-column-gap:1.25rem;column-gap:1.25rem}.lg\:col-gap-6{grid-column-gap:1.5rem;column-gap:1.5rem}.lg\:col-gap-8{grid-column-gap:2rem;column-gap:2rem}.lg\:col-gap-10{grid-column-gap:2.5rem;column-gap:2.5rem}.lg\:col-gap-12{grid-column-gap:3rem;column-gap:3rem}.lg\:col-gap-16{grid-column-gap:4rem;column-gap:4rem}.lg\:col-gap-20{grid-column-gap:5rem;column-gap:5rem}.lg\:col-gap-24{grid-column-gap:6rem;column-gap:6rem}.lg\:col-gap-32{grid-column-gap:8rem;column-gap:8rem}.lg\:col-gap-40{grid-column-gap:10rem;column-gap:10rem}.lg\:col-gap-48{grid-column-gap:12rem;column-gap:12rem}.lg\:col-gap-56{grid-column-gap:14rem;column-gap:14rem}.lg\:col-gap-64{grid-column-gap:16rem;column-gap:16rem}.lg\:col-gap-px{grid-column-gap:1px;column-gap:1px}.lg\:gap-x-0{grid-column-gap:0;column-gap:0}.lg\:gap-x-1{grid-column-gap:.25rem;column-gap:.25rem}.lg\:gap-x-2{grid-column-gap:.5rem;column-gap:.5rem}.lg\:gap-x-3{grid-column-gap:.75rem;column-gap:.75rem}.lg\:gap-x-4{grid-column-gap:1rem;column-gap:1rem}.lg\:gap-x-5{grid-column-gap:1.25rem;column-gap:1.25rem}.lg\:gap-x-6{grid-column-gap:1.5rem;column-gap:1.5rem}.lg\:gap-x-8{grid-column-gap:2rem;column-gap:2rem}.lg\:gap-x-10{grid-column-gap:2.5rem;column-gap:2.5rem}.lg\:gap-x-12{grid-column-gap:3rem;column-gap:3rem}.lg\:gap-x-16{grid-column-gap:4rem;column-gap:4rem}.lg\:gap-x-20{grid-column-gap:5rem;column-gap:5rem}.lg\:gap-x-24{grid-column-gap:6rem;column-gap:6rem}.lg\:gap-x-32{grid-column-gap:8rem;column-gap:8rem}.lg\:gap-x-40{grid-column-gap:10rem;column-gap:10rem}.lg\:gap-x-48{grid-column-gap:12rem;column-gap:12rem}.lg\:gap-x-56{grid-column-gap:14rem;column-gap:14rem}.lg\:gap-x-64{grid-column-gap:16rem;column-gap:16rem}.lg\:gap-x-px{grid-column-gap:1px;column-gap:1px}.lg\:row-gap-0{grid-row-gap:0;row-gap:0}.lg\:row-gap-1{grid-row-gap:.25rem;row-gap:.25rem}.lg\:row-gap-2{grid-row-gap:.5rem;row-gap:.5rem}.lg\:row-gap-3{grid-row-gap:.75rem;row-gap:.75rem}.lg\:row-gap-4{grid-row-gap:1rem;row-gap:1rem}.lg\:row-gap-5{grid-row-gap:1.25rem;row-gap:1.25rem}.lg\:row-gap-6{grid-row-gap:1.5rem;row-gap:1.5rem}.lg\:row-gap-8{grid-row-gap:2rem;row-gap:2rem}.lg\:row-gap-10{grid-row-gap:2.5rem;row-gap:2.5rem}.lg\:row-gap-12{grid-row-gap:3rem;row-gap:3rem}.lg\:row-gap-16{grid-row-gap:4rem;row-gap:4rem}.lg\:row-gap-20{grid-row-gap:5rem;row-gap:5rem}.lg\:row-gap-24{grid-row-gap:6rem;row-gap:6rem}.lg\:row-gap-32{grid-row-gap:8rem;row-gap:8rem}.lg\:row-gap-40{grid-row-gap:10rem;row-gap:10rem}.lg\:row-gap-48{grid-row-gap:12rem;row-gap:12rem}.lg\:row-gap-56{grid-row-gap:14rem;row-gap:14rem}.lg\:row-gap-64{grid-row-gap:16rem;row-gap:16rem}.lg\:row-gap-px{grid-row-gap:1px;row-gap:1px}.lg\:gap-y-0{grid-row-gap:0;row-gap:0}.lg\:gap-y-1{grid-row-gap:.25rem;row-gap:.25rem}.lg\:gap-y-2{grid-row-gap:.5rem;row-gap:.5rem}.lg\:gap-y-3{grid-row-gap:.75rem;row-gap:.75rem}.lg\:gap-y-4{grid-row-gap:1rem;row-gap:1rem}.lg\:gap-y-5{grid-row-gap:1.25rem;row-gap:1.25rem}.lg\:gap-y-6{grid-row-gap:1.5rem;row-gap:1.5rem}.lg\:gap-y-8{grid-row-gap:2rem;row-gap:2rem}.lg\:gap-y-10{grid-row-gap:2.5rem;row-gap:2.5rem}.lg\:gap-y-12{grid-row-gap:3rem;row-gap:3rem}.lg\:gap-y-16{grid-row-gap:4rem;row-gap:4rem}.lg\:gap-y-20{grid-row-gap:5rem;row-gap:5rem}.lg\:gap-y-24{grid-row-gap:6rem;row-gap:6rem}.lg\:gap-y-32{grid-row-gap:8rem;row-gap:8rem}.lg\:gap-y-40{grid-row-gap:10rem;row-gap:10rem}.lg\:gap-y-48{grid-row-gap:12rem;row-gap:12rem}.lg\:gap-y-56{grid-row-gap:14rem;row-gap:14rem}.lg\:gap-y-64{grid-row-gap:16rem;row-gap:16rem}.lg\:gap-y-px{grid-row-gap:1px;row-gap:1px}.lg\:grid-flow-row{grid-auto-flow:row}.lg\:grid-flow-col{grid-auto-flow:column}.lg\:grid-flow-row-dense{grid-auto-flow:row dense}.lg\:grid-flow-col-dense{grid-auto-flow:column dense}.lg\:grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.lg\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.lg\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.lg\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.lg\:grid-cols-5{grid-template-columns:repeat(5,minmax(0,1fr))}.lg\:grid-cols-6{grid-template-columns:repeat(6,minmax(0,1fr))}.lg\:grid-cols-7{grid-template-columns:repeat(7,minmax(0,1fr))}.lg\:grid-cols-8{grid-template-columns:repeat(8,minmax(0,1fr))}.lg\:grid-cols-9{grid-template-columns:repeat(9,minmax(0,1fr))}.lg\:grid-cols-10{grid-template-columns:repeat(10,minmax(0,1fr))}.lg\:grid-cols-11{grid-template-columns:repeat(11,minmax(0,1fr))}.lg\:grid-cols-12{grid-template-columns:repeat(12,minmax(0,1fr))}.lg\:grid-cols-none{grid-template-columns:none}.lg\:auto-cols-auto{grid-auto-columns:auto}.lg\:auto-cols-min{grid-auto-columns:-webkit-min-content;grid-auto-columns:min-content}.lg\:auto-cols-max{grid-auto-columns:-webkit-max-content;grid-auto-columns:max-content}.lg\:auto-cols-fr{grid-auto-columns:minmax(0,1fr)}.lg\:col-auto{grid-column:auto}.lg\:col-span-1{grid-column:span 1/span 1}.lg\:col-span-2{grid-column:span 2/span 2}.lg\:col-span-3{grid-column:span 3/span 3}.lg\:col-span-4{grid-column:span 4/span 4}.lg\:col-span-5{grid-column:span 5/span 5}.lg\:col-span-6{grid-column:span 6/span 6}.lg\:col-span-7{grid-column:span 7/span 7}.lg\:col-span-8{grid-column:span 8/span 8}.lg\:col-span-9{grid-column:span 9/span 9}.lg\:col-span-10{grid-column:span 10/span 10}.lg\:col-span-11{grid-column:span 11/span 11}.lg\:col-span-12{grid-column:span 12/span 12}.lg\:col-span-full{grid-column:1/-1}.lg\:col-start-1{grid-column-start:1}.lg\:col-start-2{grid-column-start:2}.lg\:col-start-3{grid-column-start:3}.lg\:col-start-4{grid-column-start:4}.lg\:col-start-5{grid-column-start:5}.lg\:col-start-6{grid-column-start:6}.lg\:col-start-7{grid-column-start:7}.lg\:col-start-8{grid-column-start:8}.lg\:col-start-9{grid-column-start:9}.lg\:col-start-10{grid-column-start:10}.lg\:col-start-11{grid-column-start:11}.lg\:col-start-12{grid-column-start:12}.lg\:col-start-13{grid-column-start:13}.lg\:col-start-auto{grid-column-start:auto}.lg\:col-end-1{grid-column-end:1}.lg\:col-end-2{grid-column-end:2}.lg\:col-end-3{grid-column-end:3}.lg\:col-end-4{grid-column-end:4}.lg\:col-end-5{grid-column-end:5}.lg\:col-end-6{grid-column-end:6}.lg\:col-end-7{grid-column-end:7}.lg\:col-end-8{grid-column-end:8}.lg\:col-end-9{grid-column-end:9}.lg\:col-end-10{grid-column-end:10}.lg\:col-end-11{grid-column-end:11}.lg\:col-end-12{grid-column-end:12}.lg\:col-end-13{grid-column-end:13}.lg\:col-end-auto{grid-column-end:auto}.lg\:grid-rows-1{grid-template-rows:repeat(1,minmax(0,1fr))}.lg\:grid-rows-2{grid-template-rows:repeat(2,minmax(0,1fr))}.lg\:grid-rows-3{grid-template-rows:repeat(3,minmax(0,1fr))}.lg\:grid-rows-4{grid-template-rows:repeat(4,minmax(0,1fr))}.lg\:grid-rows-5{grid-template-rows:repeat(5,minmax(0,1fr))}.lg\:grid-rows-6{grid-template-rows:repeat(6,minmax(0,1fr))}.lg\:grid-rows-none{grid-template-rows:none}.lg\:auto-rows-auto{grid-auto-rows:auto}.lg\:auto-rows-min{grid-auto-rows:-webkit-min-content;grid-auto-rows:min-content}.lg\:auto-rows-max{grid-auto-rows:-webkit-max-content;grid-auto-rows:max-content}.lg\:auto-rows-fr{grid-auto-rows:minmax(0,1fr)}.lg\:row-auto{grid-row:auto}.lg\:row-span-1{grid-row:span 1/span 1}.lg\:row-span-2{grid-row:span 2/span 2}.lg\:row-span-3{grid-row:span 3/span 3}.lg\:row-span-4{grid-row:span 4/span 4}.lg\:row-span-5{grid-row:span 5/span 5}.lg\:row-span-6{grid-row:span 6/span 6}.lg\:row-span-full{grid-row:1/-1}.lg\:row-start-1{grid-row-start:1}.lg\:row-start-2{grid-row-start:2}.lg\:row-start-3{grid-row-start:3}.lg\:row-start-4{grid-row-start:4}.lg\:row-start-5{grid-row-start:5}.lg\:row-start-6{grid-row-start:6}.lg\:row-start-7{grid-row-start:7}.lg\:row-start-auto{grid-row-start:auto}.lg\:row-end-1{grid-row-end:1}.lg\:row-end-2{grid-row-end:2}.lg\:row-end-3{grid-row-end:3}.lg\:row-end-4{grid-row-end:4}.lg\:row-end-5{grid-row-end:5}.lg\:row-end-6{grid-row-end:6}.lg\:row-end-7{grid-row-end:7}.lg\:row-end-auto{grid-row-end:auto}.lg\:transform{--transform-translate-x:0;--transform-translate-y:0;--transform-rotate:0;--transform-skew-x:0;--transform-skew-y:0;--transform-scale-x:1;--transform-scale-y:1;transform:translateX(var(--transform-translate-x)) translateY(var(--transform-translate-y)) rotate(var(--transform-rotate)) skewX(var(--transform-skew-x)) skewY(var(--transform-skew-y)) scaleX(var(--transform-scale-x)) scaleY(var(--transform-scale-y))}.lg\:transform-none{transform:none}.lg\:origin-center{transform-origin:center}.lg\:origin-top{transform-origin:top}.lg\:origin-top-right{transform-origin:top right}.lg\:origin-right{transform-origin:right}.lg\:origin-bottom-right{transform-origin:bottom right}.lg\:origin-bottom{transform-origin:bottom}.lg\:origin-bottom-left{transform-origin:bottom left}.lg\:origin-left{transform-origin:left}.lg\:origin-top-left{transform-origin:top left}.lg\:scale-0{--transform-scale-x:0;--transform-scale-y:0}.lg\:scale-50{--transform-scale-x:.5;--transform-scale-y:.5}.lg\:scale-75{--transform-scale-x:.75;--transform-scale-y:.75}.lg\:scale-90{--transform-scale-x:.9;--transform-scale-y:.9}.lg\:scale-95{--transform-scale-x:.95;--transform-scale-y:.95}.lg\:scale-100{--transform-scale-x:1;--transform-scale-y:1}.lg\:scale-105{--transform-scale-x:1.05;--transform-scale-y:1.05}.lg\:scale-110{--transform-scale-x:1.1;--transform-scale-y:1.1}.lg\:scale-125{--transform-scale-x:1.25;--transform-scale-y:1.25}.lg\:scale-150{--transform-scale-x:1.5;--transform-scale-y:1.5}.lg\:scale-x-0{--transform-scale-x:0}.lg\:scale-x-50{--transform-scale-x:.5}.lg\:scale-x-75{--transform-scale-x:.75}.lg\:scale-x-90{--transform-scale-x:.9}.lg\:scale-x-95{--transform-scale-x:.95}.lg\:scale-x-100{--transform-scale-x:1}.lg\:scale-x-105{--transform-scale-x:1.05}.lg\:scale-x-110{--transform-scale-x:1.1}.lg\:scale-x-125{--transform-scale-x:1.25}.lg\:scale-x-150{--transform-scale-x:1.5}.lg\:scale-y-0{--transform-scale-y:0}.lg\:scale-y-50{--transform-scale-y:.5}.lg\:scale-y-75{--transform-scale-y:.75}.lg\:scale-y-90{--transform-scale-y:.9}.lg\:scale-y-95{--transform-scale-y:.95}.lg\:scale-y-100{--transform-scale-y:1}.lg\:scale-y-105{--transform-scale-y:1.05}.lg\:scale-y-110{--transform-scale-y:1.1}.lg\:scale-y-125{--transform-scale-y:1.25}.lg\:scale-y-150{--transform-scale-y:1.5}.lg\:hover\:scale-0:hover{--transform-scale-x:0;--transform-scale-y:0}.lg\:hover\:scale-50:hover{--transform-scale-x:.5;--transform-scale-y:.5}.lg\:hover\:scale-75:hover{--transform-scale-x:.75;--transform-scale-y:.75}.lg\:hover\:scale-90:hover{--transform-scale-x:.9;--transform-scale-y:.9}.lg\:hover\:scale-95:hover{--transform-scale-x:.95;--transform-scale-y:.95}.lg\:hover\:scale-100:hover{--transform-scale-x:1;--transform-scale-y:1}.lg\:hover\:scale-105:hover{--transform-scale-x:1.05;--transform-scale-y:1.05}.lg\:hover\:scale-110:hover{--transform-scale-x:1.1;--transform-scale-y:1.1}.lg\:hover\:scale-125:hover{--transform-scale-x:1.25;--transform-scale-y:1.25}.lg\:hover\:scale-150:hover{--transform-scale-x:1.5;--transform-scale-y:1.5}.lg\:hover\:scale-x-0:hover{--transform-scale-x:0}.lg\:hover\:scale-x-50:hover{--transform-scale-x:.5}.lg\:hover\:scale-x-75:hover{--transform-scale-x:.75}.lg\:hover\:scale-x-90:hover{--transform-scale-x:.9}.lg\:hover\:scale-x-95:hover{--transform-scale-x:.95}.lg\:hover\:scale-x-100:hover{--transform-scale-x:1}.lg\:hover\:scale-x-105:hover{--transform-scale-x:1.05}.lg\:hover\:scale-x-110:hover{--transform-scale-x:1.1}.lg\:hover\:scale-x-125:hover{--transform-scale-x:1.25}.lg\:hover\:scale-x-150:hover{--transform-scale-x:1.5}.lg\:hover\:scale-y-0:hover{--transform-scale-y:0}.lg\:hover\:scale-y-50:hover{--transform-scale-y:.5}.lg\:hover\:scale-y-75:hover{--transform-scale-y:.75}.lg\:hover\:scale-y-90:hover{--transform-scale-y:.9}.lg\:hover\:scale-y-95:hover{--transform-scale-y:.95}.lg\:hover\:scale-y-100:hover{--transform-scale-y:1}.lg\:hover\:scale-y-105:hover{--transform-scale-y:1.05}.lg\:hover\:scale-y-110:hover{--transform-scale-y:1.1}.lg\:hover\:scale-y-125:hover{--transform-scale-y:1.25}.lg\:hover\:scale-y-150:hover{--transform-scale-y:1.5}.lg\:focus\:scale-0:focus{--transform-scale-x:0;--transform-scale-y:0}.lg\:focus\:scale-50:focus{--transform-scale-x:.5;--transform-scale-y:.5}.lg\:focus\:scale-75:focus{--transform-scale-x:.75;--transform-scale-y:.75}.lg\:focus\:scale-90:focus{--transform-scale-x:.9;--transform-scale-y:.9}.lg\:focus\:scale-95:focus{--transform-scale-x:.95;--transform-scale-y:.95}.lg\:focus\:scale-100:focus{--transform-scale-x:1;--transform-scale-y:1}.lg\:focus\:scale-105:focus{--transform-scale-x:1.05;--transform-scale-y:1.05}.lg\:focus\:scale-110:focus{--transform-scale-x:1.1;--transform-scale-y:1.1}.lg\:focus\:scale-125:focus{--transform-scale-x:1.25;--transform-scale-y:1.25}.lg\:focus\:scale-150:focus{--transform-scale-x:1.5;--transform-scale-y:1.5}.lg\:focus\:scale-x-0:focus{--transform-scale-x:0}.lg\:focus\:scale-x-50:focus{--transform-scale-x:.5}.lg\:focus\:scale-x-75:focus{--transform-scale-x:.75}.lg\:focus\:scale-x-90:focus{--transform-scale-x:.9}.lg\:focus\:scale-x-95:focus{--transform-scale-x:.95}.lg\:focus\:scale-x-100:focus{--transform-scale-x:1}.lg\:focus\:scale-x-105:focus{--transform-scale-x:1.05}.lg\:focus\:scale-x-110:focus{--transform-scale-x:1.1}.lg\:focus\:scale-x-125:focus{--transform-scale-x:1.25}.lg\:focus\:scale-x-150:focus{--transform-scale-x:1.5}.lg\:focus\:scale-y-0:focus{--transform-scale-y:0}.lg\:focus\:scale-y-50:focus{--transform-scale-y:.5}.lg\:focus\:scale-y-75:focus{--transform-scale-y:.75}.lg\:focus\:scale-y-90:focus{--transform-scale-y:.9}.lg\:focus\:scale-y-95:focus{--transform-scale-y:.95}.lg\:focus\:scale-y-100:focus{--transform-scale-y:1}.lg\:focus\:scale-y-105:focus{--transform-scale-y:1.05}.lg\:focus\:scale-y-110:focus{--transform-scale-y:1.1}.lg\:focus\:scale-y-125:focus{--transform-scale-y:1.25}.lg\:focus\:scale-y-150:focus{--transform-scale-y:1.5}.lg\:rotate-0{--transform-rotate:0}.lg\:rotate-1{--transform-rotate:1deg}.lg\:rotate-2{--transform-rotate:2deg}.lg\:rotate-3{--transform-rotate:3deg}.lg\:rotate-6{--transform-rotate:6deg}.lg\:rotate-12{--transform-rotate:12deg}.lg\:rotate-45{--transform-rotate:45deg}.lg\:rotate-90{--transform-rotate:90deg}.lg\:rotate-180{--transform-rotate:180deg}.lg\:-rotate-180{--transform-rotate:-180deg}.lg\:-rotate-90{--transform-rotate:-90deg}.lg\:-rotate-45{--transform-rotate:-45deg}.lg\:-rotate-12{--transform-rotate:-12deg}.lg\:-rotate-6{--transform-rotate:-6deg}.lg\:-rotate-3{--transform-rotate:-3deg}.lg\:-rotate-2{--transform-rotate:-2deg}.lg\:-rotate-1{--transform-rotate:-1deg}.lg\:hover\:rotate-0:hover{--transform-rotate:0}.lg\:hover\:rotate-1:hover{--transform-rotate:1deg}.lg\:hover\:rotate-2:hover{--transform-rotate:2deg}.lg\:hover\:rotate-3:hover{--transform-rotate:3deg}.lg\:hover\:rotate-6:hover{--transform-rotate:6deg}.lg\:hover\:rotate-12:hover{--transform-rotate:12deg}.lg\:hover\:rotate-45:hover{--transform-rotate:45deg}.lg\:hover\:rotate-90:hover{--transform-rotate:90deg}.lg\:hover\:rotate-180:hover{--transform-rotate:180deg}.lg\:hover\:-rotate-180:hover{--transform-rotate:-180deg}.lg\:hover\:-rotate-90:hover{--transform-rotate:-90deg}.lg\:hover\:-rotate-45:hover{--transform-rotate:-45deg}.lg\:hover\:-rotate-12:hover{--transform-rotate:-12deg}.lg\:hover\:-rotate-6:hover{--transform-rotate:-6deg}.lg\:hover\:-rotate-3:hover{--transform-rotate:-3deg}.lg\:hover\:-rotate-2:hover{--transform-rotate:-2deg}.lg\:hover\:-rotate-1:hover{--transform-rotate:-1deg}.lg\:focus\:rotate-0:focus{--transform-rotate:0}.lg\:focus\:rotate-1:focus{--transform-rotate:1deg}.lg\:focus\:rotate-2:focus{--transform-rotate:2deg}.lg\:focus\:rotate-3:focus{--transform-rotate:3deg}.lg\:focus\:rotate-6:focus{--transform-rotate:6deg}.lg\:focus\:rotate-12:focus{--transform-rotate:12deg}.lg\:focus\:rotate-45:focus{--transform-rotate:45deg}.lg\:focus\:rotate-90:focus{--transform-rotate:90deg}.lg\:focus\:rotate-180:focus{--transform-rotate:180deg}.lg\:focus\:-rotate-180:focus{--transform-rotate:-180deg}.lg\:focus\:-rotate-90:focus{--transform-rotate:-90deg}.lg\:focus\:-rotate-45:focus{--transform-rotate:-45deg}.lg\:focus\:-rotate-12:focus{--transform-rotate:-12deg}.lg\:focus\:-rotate-6:focus{--transform-rotate:-6deg}.lg\:focus\:-rotate-3:focus{--transform-rotate:-3deg}.lg\:focus\:-rotate-2:focus{--transform-rotate:-2deg}.lg\:focus\:-rotate-1:focus{--transform-rotate:-1deg}.lg\:translate-x-0{--transform-translate-x:0}.lg\:translate-x-1{--transform-translate-x:0.25rem}.lg\:translate-x-2{--transform-translate-x:0.5rem}.lg\:translate-x-3{--transform-translate-x:0.75rem}.lg\:translate-x-4{--transform-translate-x:1rem}.lg\:translate-x-5{--transform-translate-x:1.25rem}.lg\:translate-x-6{--transform-translate-x:1.5rem}.lg\:translate-x-8{--transform-translate-x:2rem}.lg\:translate-x-10{--transform-translate-x:2.5rem}.lg\:translate-x-12{--transform-translate-x:3rem}.lg\:translate-x-16{--transform-translate-x:4rem}.lg\:translate-x-20{--transform-translate-x:5rem}.lg\:translate-x-24{--transform-translate-x:6rem}.lg\:translate-x-32{--transform-translate-x:8rem}.lg\:translate-x-40{--transform-translate-x:10rem}.lg\:translate-x-48{--transform-translate-x:12rem}.lg\:translate-x-56{--transform-translate-x:14rem}.lg\:translate-x-64{--transform-translate-x:16rem}.lg\:translate-x-px{--transform-translate-x:1px}.lg\:-translate-x-1{--transform-translate-x:-0.25rem}.lg\:-translate-x-2{--transform-translate-x:-0.5rem}.lg\:-translate-x-3{--transform-translate-x:-0.75rem}.lg\:-translate-x-4{--transform-translate-x:-1rem}.lg\:-translate-x-5{--transform-translate-x:-1.25rem}.lg\:-translate-x-6{--transform-translate-x:-1.5rem}.lg\:-translate-x-8{--transform-translate-x:-2rem}.lg\:-translate-x-10{--transform-translate-x:-2.5rem}.lg\:-translate-x-12{--transform-translate-x:-3rem}.lg\:-translate-x-16{--transform-translate-x:-4rem}.lg\:-translate-x-20{--transform-translate-x:-5rem}.lg\:-translate-x-24{--transform-translate-x:-6rem}.lg\:-translate-x-32{--transform-translate-x:-8rem}.lg\:-translate-x-40{--transform-translate-x:-10rem}.lg\:-translate-x-48{--transform-translate-x:-12rem}.lg\:-translate-x-56{--transform-translate-x:-14rem}.lg\:-translate-x-64{--transform-translate-x:-16rem}.lg\:-translate-x-px{--transform-translate-x:-1px}.lg\:-translate-x-full{--transform-translate-x:-100%}.lg\:-translate-x-1\/2{--transform-translate-x:-50%}.lg\:translate-x-1\/2{--transform-translate-x:50%}.lg\:translate-x-full{--transform-translate-x:100%}.lg\:translate-y-0{--transform-translate-y:0}.lg\:translate-y-1{--transform-translate-y:0.25rem}.lg\:translate-y-2{--transform-translate-y:0.5rem}.lg\:translate-y-3{--transform-translate-y:0.75rem}.lg\:translate-y-4{--transform-translate-y:1rem}.lg\:translate-y-5{--transform-translate-y:1.25rem}.lg\:translate-y-6{--transform-translate-y:1.5rem}.lg\:translate-y-8{--transform-translate-y:2rem}.lg\:translate-y-10{--transform-translate-y:2.5rem}.lg\:translate-y-12{--transform-translate-y:3rem}.lg\:translate-y-16{--transform-translate-y:4rem}.lg\:translate-y-20{--transform-translate-y:5rem}.lg\:translate-y-24{--transform-translate-y:6rem}.lg\:translate-y-32{--transform-translate-y:8rem}.lg\:translate-y-40{--transform-translate-y:10rem}.lg\:translate-y-48{--transform-translate-y:12rem}.lg\:translate-y-56{--transform-translate-y:14rem}.lg\:translate-y-64{--transform-translate-y:16rem}.lg\:translate-y-px{--transform-translate-y:1px}.lg\:-translate-y-1{--transform-translate-y:-0.25rem}.lg\:-translate-y-2{--transform-translate-y:-0.5rem}.lg\:-translate-y-3{--transform-translate-y:-0.75rem}.lg\:-translate-y-4{--transform-translate-y:-1rem}.lg\:-translate-y-5{--transform-translate-y:-1.25rem}.lg\:-translate-y-6{--transform-translate-y:-1.5rem}.lg\:-translate-y-8{--transform-translate-y:-2rem}.lg\:-translate-y-10{--transform-translate-y:-2.5rem}.lg\:-translate-y-12{--transform-translate-y:-3rem}.lg\:-translate-y-16{--transform-translate-y:-4rem}.lg\:-translate-y-20{--transform-translate-y:-5rem}.lg\:-translate-y-24{--transform-translate-y:-6rem}.lg\:-translate-y-32{--transform-translate-y:-8rem}.lg\:-translate-y-40{--transform-translate-y:-10rem}.lg\:-translate-y-48{--transform-translate-y:-12rem}.lg\:-translate-y-56{--transform-translate-y:-14rem}.lg\:-translate-y-64{--transform-translate-y:-16rem}.lg\:-translate-y-px{--transform-translate-y:-1px}.lg\:-translate-y-full{--transform-translate-y:-100%}.lg\:-translate-y-1\/2{--transform-translate-y:-50%}.lg\:translate-y-1\/2{--transform-translate-y:50%}.lg\:translate-y-full{--transform-translate-y:100%}.lg\:hover\:translate-x-0:hover{--transform-translate-x:0}.lg\:hover\:translate-x-1:hover{--transform-translate-x:0.25rem}.lg\:hover\:translate-x-2:hover{--transform-translate-x:0.5rem}.lg\:hover\:translate-x-3:hover{--transform-translate-x:0.75rem}.lg\:hover\:translate-x-4:hover{--transform-translate-x:1rem}.lg\:hover\:translate-x-5:hover{--transform-translate-x:1.25rem}.lg\:hover\:translate-x-6:hover{--transform-translate-x:1.5rem}.lg\:hover\:translate-x-8:hover{--transform-translate-x:2rem}.lg\:hover\:translate-x-10:hover{--transform-translate-x:2.5rem}.lg\:hover\:translate-x-12:hover{--transform-translate-x:3rem}.lg\:hover\:translate-x-16:hover{--transform-translate-x:4rem}.lg\:hover\:translate-x-20:hover{--transform-translate-x:5rem}.lg\:hover\:translate-x-24:hover{--transform-translate-x:6rem}.lg\:hover\:translate-x-32:hover{--transform-translate-x:8rem}.lg\:hover\:translate-x-40:hover{--transform-translate-x:10rem}.lg\:hover\:translate-x-48:hover{--transform-translate-x:12rem}.lg\:hover\:translate-x-56:hover{--transform-translate-x:14rem}.lg\:hover\:translate-x-64:hover{--transform-translate-x:16rem}.lg\:hover\:translate-x-px:hover{--transform-translate-x:1px}.lg\:hover\:-translate-x-1:hover{--transform-translate-x:-0.25rem}.lg\:hover\:-translate-x-2:hover{--transform-translate-x:-0.5rem}.lg\:hover\:-translate-x-3:hover{--transform-translate-x:-0.75rem}.lg\:hover\:-translate-x-4:hover{--transform-translate-x:-1rem}.lg\:hover\:-translate-x-5:hover{--transform-translate-x:-1.25rem}.lg\:hover\:-translate-x-6:hover{--transform-translate-x:-1.5rem}.lg\:hover\:-translate-x-8:hover{--transform-translate-x:-2rem}.lg\:hover\:-translate-x-10:hover{--transform-translate-x:-2.5rem}.lg\:hover\:-translate-x-12:hover{--transform-translate-x:-3rem}.lg\:hover\:-translate-x-16:hover{--transform-translate-x:-4rem}.lg\:hover\:-translate-x-20:hover{--transform-translate-x:-5rem}.lg\:hover\:-translate-x-24:hover{--transform-translate-x:-6rem}.lg\:hover\:-translate-x-32:hover{--transform-translate-x:-8rem}.lg\:hover\:-translate-x-40:hover{--transform-translate-x:-10rem}.lg\:hover\:-translate-x-48:hover{--transform-translate-x:-12rem}.lg\:hover\:-translate-x-56:hover{--transform-translate-x:-14rem}.lg\:hover\:-translate-x-64:hover{--transform-translate-x:-16rem}.lg\:hover\:-translate-x-px:hover{--transform-translate-x:-1px}.lg\:hover\:-translate-x-full:hover{--transform-translate-x:-100%}.lg\:hover\:-translate-x-1\/2:hover{--transform-translate-x:-50%}.lg\:hover\:translate-x-1\/2:hover{--transform-translate-x:50%}.lg\:hover\:translate-x-full:hover{--transform-translate-x:100%}.lg\:hover\:translate-y-0:hover{--transform-translate-y:0}.lg\:hover\:translate-y-1:hover{--transform-translate-y:0.25rem}.lg\:hover\:translate-y-2:hover{--transform-translate-y:0.5rem}.lg\:hover\:translate-y-3:hover{--transform-translate-y:0.75rem}.lg\:hover\:translate-y-4:hover{--transform-translate-y:1rem}.lg\:hover\:translate-y-5:hover{--transform-translate-y:1.25rem}.lg\:hover\:translate-y-6:hover{--transform-translate-y:1.5rem}.lg\:hover\:translate-y-8:hover{--transform-translate-y:2rem}.lg\:hover\:translate-y-10:hover{--transform-translate-y:2.5rem}.lg\:hover\:translate-y-12:hover{--transform-translate-y:3rem}.lg\:hover\:translate-y-16:hover{--transform-translate-y:4rem}.lg\:hover\:translate-y-20:hover{--transform-translate-y:5rem}.lg\:hover\:translate-y-24:hover{--transform-translate-y:6rem}.lg\:hover\:translate-y-32:hover{--transform-translate-y:8rem}.lg\:hover\:translate-y-40:hover{--transform-translate-y:10rem}.lg\:hover\:translate-y-48:hover{--transform-translate-y:12rem}.lg\:hover\:translate-y-56:hover{--transform-translate-y:14rem}.lg\:hover\:translate-y-64:hover{--transform-translate-y:16rem}.lg\:hover\:translate-y-px:hover{--transform-translate-y:1px}.lg\:hover\:-translate-y-1:hover{--transform-translate-y:-0.25rem}.lg\:hover\:-translate-y-2:hover{--transform-translate-y:-0.5rem}.lg\:hover\:-translate-y-3:hover{--transform-translate-y:-0.75rem}.lg\:hover\:-translate-y-4:hover{--transform-translate-y:-1rem}.lg\:hover\:-translate-y-5:hover{--transform-translate-y:-1.25rem}.lg\:hover\:-translate-y-6:hover{--transform-translate-y:-1.5rem}.lg\:hover\:-translate-y-8:hover{--transform-translate-y:-2rem}.lg\:hover\:-translate-y-10:hover{--transform-translate-y:-2.5rem}.lg\:hover\:-translate-y-12:hover{--transform-translate-y:-3rem}.lg\:hover\:-translate-y-16:hover{--transform-translate-y:-4rem}.lg\:hover\:-translate-y-20:hover{--transform-translate-y:-5rem}.lg\:hover\:-translate-y-24:hover{--transform-translate-y:-6rem}.lg\:hover\:-translate-y-32:hover{--transform-translate-y:-8rem}.lg\:hover\:-translate-y-40:hover{--transform-translate-y:-10rem}.lg\:hover\:-translate-y-48:hover{--transform-translate-y:-12rem}.lg\:hover\:-translate-y-56:hover{--transform-translate-y:-14rem}.lg\:hover\:-translate-y-64:hover{--transform-translate-y:-16rem}.lg\:hover\:-translate-y-px:hover{--transform-translate-y:-1px}.lg\:hover\:-translate-y-full:hover{--transform-translate-y:-100%}.lg\:hover\:-translate-y-1\/2:hover{--transform-translate-y:-50%}.lg\:hover\:translate-y-1\/2:hover{--transform-translate-y:50%}.lg\:hover\:translate-y-full:hover{--transform-translate-y:100%}.lg\:focus\:translate-x-0:focus{--transform-translate-x:0}.lg\:focus\:translate-x-1:focus{--transform-translate-x:0.25rem}.lg\:focus\:translate-x-2:focus{--transform-translate-x:0.5rem}.lg\:focus\:translate-x-3:focus{--transform-translate-x:0.75rem}.lg\:focus\:translate-x-4:focus{--transform-translate-x:1rem}.lg\:focus\:translate-x-5:focus{--transform-translate-x:1.25rem}.lg\:focus\:translate-x-6:focus{--transform-translate-x:1.5rem}.lg\:focus\:translate-x-8:focus{--transform-translate-x:2rem}.lg\:focus\:translate-x-10:focus{--transform-translate-x:2.5rem}.lg\:focus\:translate-x-12:focus{--transform-translate-x:3rem}.lg\:focus\:translate-x-16:focus{--transform-translate-x:4rem}.lg\:focus\:translate-x-20:focus{--transform-translate-x:5rem}.lg\:focus\:translate-x-24:focus{--transform-translate-x:6rem}.lg\:focus\:translate-x-32:focus{--transform-translate-x:8rem}.lg\:focus\:translate-x-40:focus{--transform-translate-x:10rem}.lg\:focus\:translate-x-48:focus{--transform-translate-x:12rem}.lg\:focus\:translate-x-56:focus{--transform-translate-x:14rem}.lg\:focus\:translate-x-64:focus{--transform-translate-x:16rem}.lg\:focus\:translate-x-px:focus{--transform-translate-x:1px}.lg\:focus\:-translate-x-1:focus{--transform-translate-x:-0.25rem}.lg\:focus\:-translate-x-2:focus{--transform-translate-x:-0.5rem}.lg\:focus\:-translate-x-3:focus{--transform-translate-x:-0.75rem}.lg\:focus\:-translate-x-4:focus{--transform-translate-x:-1rem}.lg\:focus\:-translate-x-5:focus{--transform-translate-x:-1.25rem}.lg\:focus\:-translate-x-6:focus{--transform-translate-x:-1.5rem}.lg\:focus\:-translate-x-8:focus{--transform-translate-x:-2rem}.lg\:focus\:-translate-x-10:focus{--transform-translate-x:-2.5rem}.lg\:focus\:-translate-x-12:focus{--transform-translate-x:-3rem}.lg\:focus\:-translate-x-16:focus{--transform-translate-x:-4rem}.lg\:focus\:-translate-x-20:focus{--transform-translate-x:-5rem}.lg\:focus\:-translate-x-24:focus{--transform-translate-x:-6rem}.lg\:focus\:-translate-x-32:focus{--transform-translate-x:-8rem}.lg\:focus\:-translate-x-40:focus{--transform-translate-x:-10rem}.lg\:focus\:-translate-x-48:focus{--transform-translate-x:-12rem}.lg\:focus\:-translate-x-56:focus{--transform-translate-x:-14rem}.lg\:focus\:-translate-x-64:focus{--transform-translate-x:-16rem}.lg\:focus\:-translate-x-px:focus{--transform-translate-x:-1px}.lg\:focus\:-translate-x-full:focus{--transform-translate-x:-100%}.lg\:focus\:-translate-x-1\/2:focus{--transform-translate-x:-50%}.lg\:focus\:translate-x-1\/2:focus{--transform-translate-x:50%}.lg\:focus\:translate-x-full:focus{--transform-translate-x:100%}.lg\:focus\:translate-y-0:focus{--transform-translate-y:0}.lg\:focus\:translate-y-1:focus{--transform-translate-y:0.25rem}.lg\:focus\:translate-y-2:focus{--transform-translate-y:0.5rem}.lg\:focus\:translate-y-3:focus{--transform-translate-y:0.75rem}.lg\:focus\:translate-y-4:focus{--transform-translate-y:1rem}.lg\:focus\:translate-y-5:focus{--transform-translate-y:1.25rem}.lg\:focus\:translate-y-6:focus{--transform-translate-y:1.5rem}.lg\:focus\:translate-y-8:focus{--transform-translate-y:2rem}.lg\:focus\:translate-y-10:focus{--transform-translate-y:2.5rem}.lg\:focus\:translate-y-12:focus{--transform-translate-y:3rem}.lg\:focus\:translate-y-16:focus{--transform-translate-y:4rem}.lg\:focus\:translate-y-20:focus{--transform-translate-y:5rem}.lg\:focus\:translate-y-24:focus{--transform-translate-y:6rem}.lg\:focus\:translate-y-32:focus{--transform-translate-y:8rem}.lg\:focus\:translate-y-40:focus{--transform-translate-y:10rem}.lg\:focus\:translate-y-48:focus{--transform-translate-y:12rem}.lg\:focus\:translate-y-56:focus{--transform-translate-y:14rem}.lg\:focus\:translate-y-64:focus{--transform-translate-y:16rem}.lg\:focus\:translate-y-px:focus{--transform-translate-y:1px}.lg\:focus\:-translate-y-1:focus{--transform-translate-y:-0.25rem}.lg\:focus\:-translate-y-2:focus{--transform-translate-y:-0.5rem}.lg\:focus\:-translate-y-3:focus{--transform-translate-y:-0.75rem}.lg\:focus\:-translate-y-4:focus{--transform-translate-y:-1rem}.lg\:focus\:-translate-y-5:focus{--transform-translate-y:-1.25rem}.lg\:focus\:-translate-y-6:focus{--transform-translate-y:-1.5rem}.lg\:focus\:-translate-y-8:focus{--transform-translate-y:-2rem}.lg\:focus\:-translate-y-10:focus{--transform-translate-y:-2.5rem}.lg\:focus\:-translate-y-12:focus{--transform-translate-y:-3rem}.lg\:focus\:-translate-y-16:focus{--transform-translate-y:-4rem}.lg\:focus\:-translate-y-20:focus{--transform-translate-y:-5rem}.lg\:focus\:-translate-y-24:focus{--transform-translate-y:-6rem}.lg\:focus\:-translate-y-32:focus{--transform-translate-y:-8rem}.lg\:focus\:-translate-y-40:focus{--transform-translate-y:-10rem}.lg\:focus\:-translate-y-48:focus{--transform-translate-y:-12rem}.lg\:focus\:-translate-y-56:focus{--transform-translate-y:-14rem}.lg\:focus\:-translate-y-64:focus{--transform-translate-y:-16rem}.lg\:focus\:-translate-y-px:focus{--transform-translate-y:-1px}.lg\:focus\:-translate-y-full:focus{--transform-translate-y:-100%}.lg\:focus\:-translate-y-1\/2:focus{--transform-translate-y:-50%}.lg\:focus\:translate-y-1\/2:focus{--transform-translate-y:50%}.lg\:focus\:translate-y-full:focus{--transform-translate-y:100%}.lg\:skew-x-0{--transform-skew-x:0}.lg\:skew-x-1{--transform-skew-x:1deg}.lg\:skew-x-2{--transform-skew-x:2deg}.lg\:skew-x-3{--transform-skew-x:3deg}.lg\:skew-x-6{--transform-skew-x:6deg}.lg\:skew-x-12{--transform-skew-x:12deg}.lg\:-skew-x-12{--transform-skew-x:-12deg}.lg\:-skew-x-6{--transform-skew-x:-6deg}.lg\:-skew-x-3{--transform-skew-x:-3deg}.lg\:-skew-x-2{--transform-skew-x:-2deg}.lg\:-skew-x-1{--transform-skew-x:-1deg}.lg\:skew-y-0{--transform-skew-y:0}.lg\:skew-y-1{--transform-skew-y:1deg}.lg\:skew-y-2{--transform-skew-y:2deg}.lg\:skew-y-3{--transform-skew-y:3deg}.lg\:skew-y-6{--transform-skew-y:6deg}.lg\:skew-y-12{--transform-skew-y:12deg}.lg\:-skew-y-12{--transform-skew-y:-12deg}.lg\:-skew-y-6{--transform-skew-y:-6deg}.lg\:-skew-y-3{--transform-skew-y:-3deg}.lg\:-skew-y-2{--transform-skew-y:-2deg}.lg\:-skew-y-1{--transform-skew-y:-1deg}.lg\:hover\:skew-x-0:hover{--transform-skew-x:0}.lg\:hover\:skew-x-1:hover{--transform-skew-x:1deg}.lg\:hover\:skew-x-2:hover{--transform-skew-x:2deg}.lg\:hover\:skew-x-3:hover{--transform-skew-x:3deg}.lg\:hover\:skew-x-6:hover{--transform-skew-x:6deg}.lg\:hover\:skew-x-12:hover{--transform-skew-x:12deg}.lg\:hover\:-skew-x-12:hover{--transform-skew-x:-12deg}.lg\:hover\:-skew-x-6:hover{--transform-skew-x:-6deg}.lg\:hover\:-skew-x-3:hover{--transform-skew-x:-3deg}.lg\:hover\:-skew-x-2:hover{--transform-skew-x:-2deg}.lg\:hover\:-skew-x-1:hover{--transform-skew-x:-1deg}.lg\:hover\:skew-y-0:hover{--transform-skew-y:0}.lg\:hover\:skew-y-1:hover{--transform-skew-y:1deg}.lg\:hover\:skew-y-2:hover{--transform-skew-y:2deg}.lg\:hover\:skew-y-3:hover{--transform-skew-y:3deg}.lg\:hover\:skew-y-6:hover{--transform-skew-y:6deg}.lg\:hover\:skew-y-12:hover{--transform-skew-y:12deg}.lg\:hover\:-skew-y-12:hover{--transform-skew-y:-12deg}.lg\:hover\:-skew-y-6:hover{--transform-skew-y:-6deg}.lg\:hover\:-skew-y-3:hover{--transform-skew-y:-3deg}.lg\:hover\:-skew-y-2:hover{--transform-skew-y:-2deg}.lg\:hover\:-skew-y-1:hover{--transform-skew-y:-1deg}.lg\:focus\:skew-x-0:focus{--transform-skew-x:0}.lg\:focus\:skew-x-1:focus{--transform-skew-x:1deg}.lg\:focus\:skew-x-2:focus{--transform-skew-x:2deg}.lg\:focus\:skew-x-3:focus{--transform-skew-x:3deg}.lg\:focus\:skew-x-6:focus{--transform-skew-x:6deg}.lg\:focus\:skew-x-12:focus{--transform-skew-x:12deg}.lg\:focus\:-skew-x-12:focus{--transform-skew-x:-12deg}.lg\:focus\:-skew-x-6:focus{--transform-skew-x:-6deg}.lg\:focus\:-skew-x-3:focus{--transform-skew-x:-3deg}.lg\:focus\:-skew-x-2:focus{--transform-skew-x:-2deg}.lg\:focus\:-skew-x-1:focus{--transform-skew-x:-1deg}.lg\:focus\:skew-y-0:focus{--transform-skew-y:0}.lg\:focus\:skew-y-1:focus{--transform-skew-y:1deg}.lg\:focus\:skew-y-2:focus{--transform-skew-y:2deg}.lg\:focus\:skew-y-3:focus{--transform-skew-y:3deg}.lg\:focus\:skew-y-6:focus{--transform-skew-y:6deg}.lg\:focus\:skew-y-12:focus{--transform-skew-y:12deg}.lg\:focus\:-skew-y-12:focus{--transform-skew-y:-12deg}.lg\:focus\:-skew-y-6:focus{--transform-skew-y:-6deg}.lg\:focus\:-skew-y-3:focus{--transform-skew-y:-3deg}.lg\:focus\:-skew-y-2:focus{--transform-skew-y:-2deg}.lg\:focus\:-skew-y-1:focus{--transform-skew-y:-1deg}.lg\:transition-none{transition-property:none}.lg\:transition-all{transition-property:all}.lg\:transition{transition-property:background-color,border-color,color,fill,stroke,opacity,box-shadow,transform}.lg\:transition-colors{transition-property:background-color,border-color,color,fill,stroke}.lg\:transition-opacity{transition-property:opacity}.lg\:transition-shadow{transition-property:box-shadow}.lg\:transition-transform{transition-property:transform}.lg\:ease-linear{transition-timing-function:linear}.lg\:ease-in{transition-timing-function:cubic-bezier(.4,0,1,1)}.lg\:ease-out{transition-timing-function:cubic-bezier(0,0,.2,1)}.lg\:ease-in-out{transition-timing-function:cubic-bezier(.4,0,.2,1)}.lg\:duration-75{transition-duration:75ms}.lg\:duration-100{transition-duration:.1s}.lg\:duration-150{transition-duration:150ms}.lg\:duration-200{transition-duration:.2s}.lg\:duration-300{transition-duration:.3s}.lg\:duration-500{transition-duration:.5s}.lg\:duration-700{transition-duration:.7s}.lg\:duration-1000{transition-duration:1s}.lg\:delay-75{transition-delay:75ms}.lg\:delay-100{transition-delay:.1s}.lg\:delay-150{transition-delay:150ms}.lg\:delay-200{transition-delay:.2s}.lg\:delay-300{transition-delay:.3s}.lg\:delay-500{transition-delay:.5s}.lg\:delay-700{transition-delay:.7s}.lg\:delay-1000{transition-delay:1s}.lg\:animate-none{animation:none}.lg\:animate-spin{animation:spin 1s linear infinite}.lg\:animate-ping{animation:ping 1s cubic-bezier(0,0,.2,1) infinite}.lg\:animate-pulse{animation:pulse 2s cubic-bezier(.4,0,.6,1) infinite}.lg\:animate-bounce{animation:bounce 1s infinite}}@media (min-width:1280px){.xl\:container{width:100%}@media (min-width:640px){.xl\:container{max-width:640px}}@media (min-width:768px){.xl\:container{max-width:768px}}@media (min-width:1024px){.xl\:container{max-width:1024px}}@media (min-width:1280px){.xl\:container{max-width:1280px}}.xl\:space-y-0>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(0px * calc(1 - var(--space-y-reverse)));margin-bottom:calc(0px * var(--space-y-reverse))}.xl\:space-x-0>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(0px * var(--space-x-reverse));margin-left:calc(0px * calc(1 - var(--space-x-reverse)))}.xl\:space-y-1>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(.25rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(.25rem * var(--space-y-reverse))}.xl\:space-x-1>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(.25rem * var(--space-x-reverse));margin-left:calc(.25rem * calc(1 - var(--space-x-reverse)))}.xl\:space-y-2>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(.5rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(.5rem * var(--space-y-reverse))}.xl\:space-x-2>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(.5rem * var(--space-x-reverse));margin-left:calc(.5rem * calc(1 - var(--space-x-reverse)))}.xl\:space-y-3>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(.75rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(.75rem * var(--space-y-reverse))}.xl\:space-x-3>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(.75rem * var(--space-x-reverse));margin-left:calc(.75rem * calc(1 - var(--space-x-reverse)))}.xl\:space-y-4>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(1rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(1rem * var(--space-y-reverse))}.xl\:space-x-4>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(1rem * var(--space-x-reverse));margin-left:calc(1rem * calc(1 - var(--space-x-reverse)))}.xl\:space-y-5>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(1.25rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(1.25rem * var(--space-y-reverse))}.xl\:space-x-5>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(1.25rem * var(--space-x-reverse));margin-left:calc(1.25rem * calc(1 - var(--space-x-reverse)))}.xl\:space-y-6>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(1.5rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(1.5rem * var(--space-y-reverse))}.xl\:space-x-6>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(1.5rem * var(--space-x-reverse));margin-left:calc(1.5rem * calc(1 - var(--space-x-reverse)))}.xl\:space-y-8>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(2rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(2rem * var(--space-y-reverse))}.xl\:space-x-8>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(2rem * var(--space-x-reverse));margin-left:calc(2rem * calc(1 - var(--space-x-reverse)))}.xl\:space-y-10>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(2.5rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(2.5rem * var(--space-y-reverse))}.xl\:space-x-10>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(2.5rem * var(--space-x-reverse));margin-left:calc(2.5rem * calc(1 - var(--space-x-reverse)))}.xl\:space-y-12>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(3rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(3rem * var(--space-y-reverse))}.xl\:space-x-12>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(3rem * var(--space-x-reverse));margin-left:calc(3rem * calc(1 - var(--space-x-reverse)))}.xl\:space-y-16>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(4rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(4rem * var(--space-y-reverse))}.xl\:space-x-16>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(4rem * var(--space-x-reverse));margin-left:calc(4rem * calc(1 - var(--space-x-reverse)))}.xl\:space-y-20>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(5rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(5rem * var(--space-y-reverse))}.xl\:space-x-20>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(5rem * var(--space-x-reverse));margin-left:calc(5rem * calc(1 - var(--space-x-reverse)))}.xl\:space-y-24>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(6rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(6rem * var(--space-y-reverse))}.xl\:space-x-24>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(6rem * var(--space-x-reverse));margin-left:calc(6rem * calc(1 - var(--space-x-reverse)))}.xl\:space-y-32>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(8rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(8rem * var(--space-y-reverse))}.xl\:space-x-32>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(8rem * var(--space-x-reverse));margin-left:calc(8rem * calc(1 - var(--space-x-reverse)))}.xl\:space-y-40>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(10rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(10rem * var(--space-y-reverse))}.xl\:space-x-40>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(10rem * var(--space-x-reverse));margin-left:calc(10rem * calc(1 - var(--space-x-reverse)))}.xl\:space-y-48>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(12rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(12rem * var(--space-y-reverse))}.xl\:space-x-48>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(12rem * var(--space-x-reverse));margin-left:calc(12rem * calc(1 - var(--space-x-reverse)))}.xl\:space-y-56>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(14rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(14rem * var(--space-y-reverse))}.xl\:space-x-56>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(14rem * var(--space-x-reverse));margin-left:calc(14rem * calc(1 - var(--space-x-reverse)))}.xl\:space-y-64>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(16rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(16rem * var(--space-y-reverse))}.xl\:space-x-64>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(16rem * var(--space-x-reverse));margin-left:calc(16rem * calc(1 - var(--space-x-reverse)))}.xl\:space-y-px>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(1px * calc(1 - var(--space-y-reverse)));margin-bottom:calc(1px * var(--space-y-reverse))}.xl\:space-x-px>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(1px * var(--space-x-reverse));margin-left:calc(1px * calc(1 - var(--space-x-reverse)))}.xl\:-space-y-1>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-.25rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-.25rem * var(--space-y-reverse))}.xl\:-space-x-1>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-.25rem * var(--space-x-reverse));margin-left:calc(-.25rem * calc(1 - var(--space-x-reverse)))}.xl\:-space-y-2>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-.5rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-.5rem * var(--space-y-reverse))}.xl\:-space-x-2>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-.5rem * var(--space-x-reverse));margin-left:calc(-.5rem * calc(1 - var(--space-x-reverse)))}.xl\:-space-y-3>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-.75rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-.75rem * var(--space-y-reverse))}.xl\:-space-x-3>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-.75rem * var(--space-x-reverse));margin-left:calc(-.75rem * calc(1 - var(--space-x-reverse)))}.xl\:-space-y-4>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-1rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-1rem * var(--space-y-reverse))}.xl\:-space-x-4>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-1rem * var(--space-x-reverse));margin-left:calc(-1rem * calc(1 - var(--space-x-reverse)))}.xl\:-space-y-5>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-1.25rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-1.25rem * var(--space-y-reverse))}.xl\:-space-x-5>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-1.25rem * var(--space-x-reverse));margin-left:calc(-1.25rem * calc(1 - var(--space-x-reverse)))}.xl\:-space-y-6>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-1.5rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-1.5rem * var(--space-y-reverse))}.xl\:-space-x-6>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-1.5rem * var(--space-x-reverse));margin-left:calc(-1.5rem * calc(1 - var(--space-x-reverse)))}.xl\:-space-y-8>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-2rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-2rem * var(--space-y-reverse))}.xl\:-space-x-8>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-2rem * var(--space-x-reverse));margin-left:calc(-2rem * calc(1 - var(--space-x-reverse)))}.xl\:-space-y-10>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-2.5rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-2.5rem * var(--space-y-reverse))}.xl\:-space-x-10>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-2.5rem * var(--space-x-reverse));margin-left:calc(-2.5rem * calc(1 - var(--space-x-reverse)))}.xl\:-space-y-12>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-3rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-3rem * var(--space-y-reverse))}.xl\:-space-x-12>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-3rem * var(--space-x-reverse));margin-left:calc(-3rem * calc(1 - var(--space-x-reverse)))}.xl\:-space-y-16>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-4rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-4rem * var(--space-y-reverse))}.xl\:-space-x-16>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-4rem * var(--space-x-reverse));margin-left:calc(-4rem * calc(1 - var(--space-x-reverse)))}.xl\:-space-y-20>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-5rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-5rem * var(--space-y-reverse))}.xl\:-space-x-20>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-5rem * var(--space-x-reverse));margin-left:calc(-5rem * calc(1 - var(--space-x-reverse)))}.xl\:-space-y-24>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-6rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-6rem * var(--space-y-reverse))}.xl\:-space-x-24>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-6rem * var(--space-x-reverse));margin-left:calc(-6rem * calc(1 - var(--space-x-reverse)))}.xl\:-space-y-32>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-8rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-8rem * var(--space-y-reverse))}.xl\:-space-x-32>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-8rem * var(--space-x-reverse));margin-left:calc(-8rem * calc(1 - var(--space-x-reverse)))}.xl\:-space-y-40>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-10rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-10rem * var(--space-y-reverse))}.xl\:-space-x-40>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-10rem * var(--space-x-reverse));margin-left:calc(-10rem * calc(1 - var(--space-x-reverse)))}.xl\:-space-y-48>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-12rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-12rem * var(--space-y-reverse))}.xl\:-space-x-48>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-12rem * var(--space-x-reverse));margin-left:calc(-12rem * calc(1 - var(--space-x-reverse)))}.xl\:-space-y-56>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-14rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-14rem * var(--space-y-reverse))}.xl\:-space-x-56>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-14rem * var(--space-x-reverse));margin-left:calc(-14rem * calc(1 - var(--space-x-reverse)))}.xl\:-space-y-64>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-16rem * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-16rem * var(--space-y-reverse))}.xl\:-space-x-64>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-16rem * var(--space-x-reverse));margin-left:calc(-16rem * calc(1 - var(--space-x-reverse)))}.xl\:-space-y-px>:not(template)~:not(template){--space-y-reverse:0;margin-top:calc(-1px * calc(1 - var(--space-y-reverse)));margin-bottom:calc(-1px * var(--space-y-reverse))}.xl\:-space-x-px>:not(template)~:not(template){--space-x-reverse:0;margin-right:calc(-1px * var(--space-x-reverse));margin-left:calc(-1px * calc(1 - var(--space-x-reverse)))}.xl\:space-y-reverse>:not(template)~:not(template){--space-y-reverse:1}.xl\:space-x-reverse>:not(template)~:not(template){--space-x-reverse:1}.xl\:divide-y-0>:not(template)~:not(template){--divide-y-reverse:0;border-top-width:calc(0px * calc(1 - var(--divide-y-reverse)));border-bottom-width:calc(0px * var(--divide-y-reverse))}.xl\:divide-x-0>:not(template)~:not(template){--divide-x-reverse:0;border-right-width:calc(0px * var(--divide-x-reverse));border-left-width:calc(0px * calc(1 - var(--divide-x-reverse)))}.xl\:divide-y-2>:not(template)~:not(template){--divide-y-reverse:0;border-top-width:calc(2px * calc(1 - var(--divide-y-reverse)));border-bottom-width:calc(2px * var(--divide-y-reverse))}.xl\:divide-x-2>:not(template)~:not(template){--divide-x-reverse:0;border-right-width:calc(2px * var(--divide-x-reverse));border-left-width:calc(2px * calc(1 - var(--divide-x-reverse)))}.xl\:divide-y-4>:not(template)~:not(template){--divide-y-reverse:0;border-top-width:calc(4px * calc(1 - var(--divide-y-reverse)));border-bottom-width:calc(4px * var(--divide-y-reverse))}.xl\:divide-x-4>:not(template)~:not(template){--divide-x-reverse:0;border-right-width:calc(4px * var(--divide-x-reverse));border-left-width:calc(4px * calc(1 - var(--divide-x-reverse)))}.xl\:divide-y-8>:not(template)~:not(template){--divide-y-reverse:0;border-top-width:calc(8px * calc(1 - var(--divide-y-reverse)));border-bottom-width:calc(8px * var(--divide-y-reverse))}.xl\:divide-x-8>:not(template)~:not(template){--divide-x-reverse:0;border-right-width:calc(8px * var(--divide-x-reverse));border-left-width:calc(8px * calc(1 - var(--divide-x-reverse)))}.xl\:divide-y>:not(template)~:not(template){--divide-y-reverse:0;border-top-width:calc(1px * calc(1 - var(--divide-y-reverse)));border-bottom-width:calc(1px * var(--divide-y-reverse))}.xl\:divide-x>:not(template)~:not(template){--divide-x-reverse:0;border-right-width:calc(1px * var(--divide-x-reverse));border-left-width:calc(1px * calc(1 - var(--divide-x-reverse)))}.xl\:divide-y-reverse>:not(template)~:not(template){--divide-y-reverse:1}.xl\:divide-x-reverse>:not(template)~:not(template){--divide-x-reverse:1}.xl\:divide-transparent>:not(template)~:not(template){border-color:transparent}.xl\:divide-current>:not(template)~:not(template){border-color:currentColor}.xl\:divide-black>:not(template)~:not(template){--divide-opacity:1;border-color:#000;border-color:rgba(0,0,0,var(--divide-opacity))}.xl\:divide-white>:not(template)~:not(template){--divide-opacity:1;border-color:#fff;border-color:rgba(255,255,255,var(--divide-opacity))}.xl\:divide-gray-100>:not(template)~:not(template){--divide-opacity:1;border-color:#f7fafc;border-color:rgba(247,250,252,var(--divide-opacity))}.xl\:divide-gray-200>:not(template)~:not(template){--divide-opacity:1;border-color:#edf2f7;border-color:rgba(237,242,247,var(--divide-opacity))}.xl\:divide-gray-300>:not(template)~:not(template){--divide-opacity:1;border-color:#e2e8f0;border-color:rgba(226,232,240,var(--divide-opacity))}.xl\:divide-gray-400>:not(template)~:not(template){--divide-opacity:1;border-color:#cbd5e0;border-color:rgba(203,213,224,var(--divide-opacity))}.xl\:divide-gray-500>:not(template)~:not(template){--divide-opacity:1;border-color:#a0aec0;border-color:rgba(160,174,192,var(--divide-opacity))}.xl\:divide-gray-600>:not(template)~:not(template){--divide-opacity:1;border-color:#718096;border-color:rgba(113,128,150,var(--divide-opacity))}.xl\:divide-gray-700>:not(template)~:not(template){--divide-opacity:1;border-color:#4a5568;border-color:rgba(74,85,104,var(--divide-opacity))}.xl\:divide-gray-800>:not(template)~:not(template){--divide-opacity:1;border-color:#2d3748;border-color:rgba(45,55,72,var(--divide-opacity))}.xl\:divide-gray-900>:not(template)~:not(template){--divide-opacity:1;border-color:#1a202c;border-color:rgba(26,32,44,var(--divide-opacity))}.xl\:divide-red-100>:not(template)~:not(template){--divide-opacity:1;border-color:#fff5f5;border-color:rgba(255,245,245,var(--divide-opacity))}.xl\:divide-red-200>:not(template)~:not(template){--divide-opacity:1;border-color:#fed7d7;border-color:rgba(254,215,215,var(--divide-opacity))}.xl\:divide-red-300>:not(template)~:not(template){--divide-opacity:1;border-color:#feb2b2;border-color:rgba(254,178,178,var(--divide-opacity))}.xl\:divide-red-400>:not(template)~:not(template){--divide-opacity:1;border-color:#fc8181;border-color:rgba(252,129,129,var(--divide-opacity))}.xl\:divide-red-500>:not(template)~:not(template){--divide-opacity:1;border-color:#f56565;border-color:rgba(245,101,101,var(--divide-opacity))}.xl\:divide-red-600>:not(template)~:not(template){--divide-opacity:1;border-color:#e53e3e;border-color:rgba(229,62,62,var(--divide-opacity))}.xl\:divide-red-700>:not(template)~:not(template){--divide-opacity:1;border-color:#c53030;border-color:rgba(197,48,48,var(--divide-opacity))}.xl\:divide-red-800>:not(template)~:not(template){--divide-opacity:1;border-color:#9b2c2c;border-color:rgba(155,44,44,var(--divide-opacity))}.xl\:divide-red-900>:not(template)~:not(template){--divide-opacity:1;border-color:#742a2a;border-color:rgba(116,42,42,var(--divide-opacity))}.xl\:divide-orange-100>:not(template)~:not(template){--divide-opacity:1;border-color:#fffaf0;border-color:rgba(255,250,240,var(--divide-opacity))}.xl\:divide-orange-200>:not(template)~:not(template){--divide-opacity:1;border-color:#feebc8;border-color:rgba(254,235,200,var(--divide-opacity))}.xl\:divide-orange-300>:not(template)~:not(template){--divide-opacity:1;border-color:#fbd38d;border-color:rgba(251,211,141,var(--divide-opacity))}.xl\:divide-orange-400>:not(template)~:not(template){--divide-opacity:1;border-color:#f6ad55;border-color:rgba(246,173,85,var(--divide-opacity))}.xl\:divide-orange-500>:not(template)~:not(template){--divide-opacity:1;border-color:#ed8936;border-color:rgba(237,137,54,var(--divide-opacity))}.xl\:divide-orange-600>:not(template)~:not(template){--divide-opacity:1;border-color:#dd6b20;border-color:rgba(221,107,32,var(--divide-opacity))}.xl\:divide-orange-700>:not(template)~:not(template){--divide-opacity:1;border-color:#c05621;border-color:rgba(192,86,33,var(--divide-opacity))}.xl\:divide-orange-800>:not(template)~:not(template){--divide-opacity:1;border-color:#9c4221;border-color:rgba(156,66,33,var(--divide-opacity))}.xl\:divide-orange-900>:not(template)~:not(template){--divide-opacity:1;border-color:#7b341e;border-color:rgba(123,52,30,var(--divide-opacity))}.xl\:divide-yellow-100>:not(template)~:not(template){--divide-opacity:1;border-color:ivory;border-color:rgba(255,255,240,var(--divide-opacity))}.xl\:divide-yellow-200>:not(template)~:not(template){--divide-opacity:1;border-color:#fefcbf;border-color:rgba(254,252,191,var(--divide-opacity))}.xl\:divide-yellow-300>:not(template)~:not(template){--divide-opacity:1;border-color:#faf089;border-color:rgba(250,240,137,var(--divide-opacity))}.xl\:divide-yellow-400>:not(template)~:not(template){--divide-opacity:1;border-color:#f6e05e;border-color:rgba(246,224,94,var(--divide-opacity))}.xl\:divide-yellow-500>:not(template)~:not(template){--divide-opacity:1;border-color:#ecc94b;border-color:rgba(236,201,75,var(--divide-opacity))}.xl\:divide-yellow-600>:not(template)~:not(template){--divide-opacity:1;border-color:#d69e2e;border-color:rgba(214,158,46,var(--divide-opacity))}.xl\:divide-yellow-700>:not(template)~:not(template){--divide-opacity:1;border-color:#b7791f;border-color:rgba(183,121,31,var(--divide-opacity))}.xl\:divide-yellow-800>:not(template)~:not(template){--divide-opacity:1;border-color:#975a16;border-color:rgba(151,90,22,var(--divide-opacity))}.xl\:divide-yellow-900>:not(template)~:not(template){--divide-opacity:1;border-color:#744210;border-color:rgba(116,66,16,var(--divide-opacity))}.xl\:divide-green-100>:not(template)~:not(template){--divide-opacity:1;border-color:#f0fff4;border-color:rgba(240,255,244,var(--divide-opacity))}.xl\:divide-green-200>:not(template)~:not(template){--divide-opacity:1;border-color:#c6f6d5;border-color:rgba(198,246,213,var(--divide-opacity))}.xl\:divide-green-300>:not(template)~:not(template){--divide-opacity:1;border-color:#9ae6b4;border-color:rgba(154,230,180,var(--divide-opacity))}.xl\:divide-green-400>:not(template)~:not(template){--divide-opacity:1;border-color:#68d391;border-color:rgba(104,211,145,var(--divide-opacity))}.xl\:divide-green-500>:not(template)~:not(template){--divide-opacity:1;border-color:#48bb78;border-color:rgba(72,187,120,var(--divide-opacity))}.xl\:divide-green-600>:not(template)~:not(template){--divide-opacity:1;border-color:#38a169;border-color:rgba(56,161,105,var(--divide-opacity))}.xl\:divide-green-700>:not(template)~:not(template){--divide-opacity:1;border-color:#2f855a;border-color:rgba(47,133,90,var(--divide-opacity))}.xl\:divide-green-800>:not(template)~:not(template){--divide-opacity:1;border-color:#276749;border-color:rgba(39,103,73,var(--divide-opacity))}.xl\:divide-green-900>:not(template)~:not(template){--divide-opacity:1;border-color:#22543d;border-color:rgba(34,84,61,var(--divide-opacity))}.xl\:divide-teal-100>:not(template)~:not(template){--divide-opacity:1;border-color:#e6fffa;border-color:rgba(230,255,250,var(--divide-opacity))}.xl\:divide-teal-200>:not(template)~:not(template){--divide-opacity:1;border-color:#b2f5ea;border-color:rgba(178,245,234,var(--divide-opacity))}.xl\:divide-teal-300>:not(template)~:not(template){--divide-opacity:1;border-color:#81e6d9;border-color:rgba(129,230,217,var(--divide-opacity))}.xl\:divide-teal-400>:not(template)~:not(template){--divide-opacity:1;border-color:#4fd1c5;border-color:rgba(79,209,197,var(--divide-opacity))}.xl\:divide-teal-500>:not(template)~:not(template){--divide-opacity:1;border-color:#38b2ac;border-color:rgba(56,178,172,var(--divide-opacity))}.xl\:divide-teal-600>:not(template)~:not(template){--divide-opacity:1;border-color:#319795;border-color:rgba(49,151,149,var(--divide-opacity))}.xl\:divide-teal-700>:not(template)~:not(template){--divide-opacity:1;border-color:#2c7a7b;border-color:rgba(44,122,123,var(--divide-opacity))}.xl\:divide-teal-800>:not(template)~:not(template){--divide-opacity:1;border-color:#285e61;border-color:rgba(40,94,97,var(--divide-opacity))}.xl\:divide-teal-900>:not(template)~:not(template){--divide-opacity:1;border-color:#234e52;border-color:rgba(35,78,82,var(--divide-opacity))}.xl\:divide-blue-100>:not(template)~:not(template){--divide-opacity:1;border-color:#ebf8ff;border-color:rgba(235,248,255,var(--divide-opacity))}.xl\:divide-blue-200>:not(template)~:not(template){--divide-opacity:1;border-color:#bee3f8;border-color:rgba(190,227,248,var(--divide-opacity))}.xl\:divide-blue-300>:not(template)~:not(template){--divide-opacity:1;border-color:#90cdf4;border-color:rgba(144,205,244,var(--divide-opacity))}.xl\:divide-blue-400>:not(template)~:not(template){--divide-opacity:1;border-color:#63b3ed;border-color:rgba(99,179,237,var(--divide-opacity))}.xl\:divide-blue-500>:not(template)~:not(template){--divide-opacity:1;border-color:#4299e1;border-color:rgba(66,153,225,var(--divide-opacity))}.xl\:divide-blue-600>:not(template)~:not(template){--divide-opacity:1;border-color:#3182ce;border-color:rgba(49,130,206,var(--divide-opacity))}.xl\:divide-blue-700>:not(template)~:not(template){--divide-opacity:1;border-color:#2b6cb0;border-color:rgba(43,108,176,var(--divide-opacity))}.xl\:divide-blue-800>:not(template)~:not(template){--divide-opacity:1;border-color:#2c5282;border-color:rgba(44,82,130,var(--divide-opacity))}.xl\:divide-blue-900>:not(template)~:not(template){--divide-opacity:1;border-color:#2a4365;border-color:rgba(42,67,101,var(--divide-opacity))}.xl\:divide-indigo-100>:not(template)~:not(template){--divide-opacity:1;border-color:#ebf4ff;border-color:rgba(235,244,255,var(--divide-opacity))}.xl\:divide-indigo-200>:not(template)~:not(template){--divide-opacity:1;border-color:#c3dafe;border-color:rgba(195,218,254,var(--divide-opacity))}.xl\:divide-indigo-300>:not(template)~:not(template){--divide-opacity:1;border-color:#a3bffa;border-color:rgba(163,191,250,var(--divide-opacity))}.xl\:divide-indigo-400>:not(template)~:not(template){--divide-opacity:1;border-color:#7f9cf5;border-color:rgba(127,156,245,var(--divide-opacity))}.xl\:divide-indigo-500>:not(template)~:not(template){--divide-opacity:1;border-color:#667eea;border-color:rgba(102,126,234,var(--divide-opacity))}.xl\:divide-indigo-600>:not(template)~:not(template){--divide-opacity:1;border-color:#5a67d8;border-color:rgba(90,103,216,var(--divide-opacity))}.xl\:divide-indigo-700>:not(template)~:not(template){--divide-opacity:1;border-color:#4c51bf;border-color:rgba(76,81,191,var(--divide-opacity))}.xl\:divide-indigo-800>:not(template)~:not(template){--divide-opacity:1;border-color:#434190;border-color:rgba(67,65,144,var(--divide-opacity))}.xl\:divide-indigo-900>:not(template)~:not(template){--divide-opacity:1;border-color:#3c366b;border-color:rgba(60,54,107,var(--divide-opacity))}.xl\:divide-purple-100>:not(template)~:not(template){--divide-opacity:1;border-color:#faf5ff;border-color:rgba(250,245,255,var(--divide-opacity))}.xl\:divide-purple-200>:not(template)~:not(template){--divide-opacity:1;border-color:#e9d8fd;border-color:rgba(233,216,253,var(--divide-opacity))}.xl\:divide-purple-300>:not(template)~:not(template){--divide-opacity:1;border-color:#d6bcfa;border-color:rgba(214,188,250,var(--divide-opacity))}.xl\:divide-purple-400>:not(template)~:not(template){--divide-opacity:1;border-color:#b794f4;border-color:rgba(183,148,244,var(--divide-opacity))}.xl\:divide-purple-500>:not(template)~:not(template){--divide-opacity:1;border-color:#9f7aea;border-color:rgba(159,122,234,var(--divide-opacity))}.xl\:divide-purple-600>:not(template)~:not(template){--divide-opacity:1;border-color:#805ad5;border-color:rgba(128,90,213,var(--divide-opacity))}.xl\:divide-purple-700>:not(template)~:not(template){--divide-opacity:1;border-color:#6b46c1;border-color:rgba(107,70,193,var(--divide-opacity))}.xl\:divide-purple-800>:not(template)~:not(template){--divide-opacity:1;border-color:#553c9a;border-color:rgba(85,60,154,var(--divide-opacity))}.xl\:divide-purple-900>:not(template)~:not(template){--divide-opacity:1;border-color:#44337a;border-color:rgba(68,51,122,var(--divide-opacity))}.xl\:divide-pink-100>:not(template)~:not(template){--divide-opacity:1;border-color:#fff5f7;border-color:rgba(255,245,247,var(--divide-opacity))}.xl\:divide-pink-200>:not(template)~:not(template){--divide-opacity:1;border-color:#fed7e2;border-color:rgba(254,215,226,var(--divide-opacity))}.xl\:divide-pink-300>:not(template)~:not(template){--divide-opacity:1;border-color:#fbb6ce;border-color:rgba(251,182,206,var(--divide-opacity))}.xl\:divide-pink-400>:not(template)~:not(template){--divide-opacity:1;border-color:#f687b3;border-color:rgba(246,135,179,var(--divide-opacity))}.xl\:divide-pink-500>:not(template)~:not(template){--divide-opacity:1;border-color:#ed64a6;border-color:rgba(237,100,166,var(--divide-opacity))}.xl\:divide-pink-600>:not(template)~:not(template){--divide-opacity:1;border-color:#d53f8c;border-color:rgba(213,63,140,var(--divide-opacity))}.xl\:divide-pink-700>:not(template)~:not(template){--divide-opacity:1;border-color:#b83280;border-color:rgba(184,50,128,var(--divide-opacity))}.xl\:divide-pink-800>:not(template)~:not(template){--divide-opacity:1;border-color:#97266d;border-color:rgba(151,38,109,var(--divide-opacity))}.xl\:divide-pink-900>:not(template)~:not(template){--divide-opacity:1;border-color:#702459;border-color:rgba(112,36,89,var(--divide-opacity))}.xl\:divide-solid>:not(template)~:not(template){border-style:solid}.xl\:divide-dashed>:not(template)~:not(template){border-style:dashed}.xl\:divide-dotted>:not(template)~:not(template){border-style:dotted}.xl\:divide-double>:not(template)~:not(template){border-style:double}.xl\:divide-none>:not(template)~:not(template){border-style:none}.xl\:divide-opacity-0>:not(template)~:not(template){--divide-opacity:0}.xl\:divide-opacity-25>:not(template)~:not(template){--divide-opacity:0.25}.xl\:divide-opacity-50>:not(template)~:not(template){--divide-opacity:0.5}.xl\:divide-opacity-75>:not(template)~:not(template){--divide-opacity:0.75}.xl\:divide-opacity-100>:not(template)~:not(template){--divide-opacity:1}.xl\:sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border-width:0}.xl\:not-sr-only{position:static;width:auto;height:auto;padding:0;margin:0;overflow:visible;clip:auto;white-space:normal}.xl\:focus\:sr-only:focus{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border-width:0}.xl\:focus\:not-sr-only:focus{position:static;width:auto;height:auto;padding:0;margin:0;overflow:visible;clip:auto;white-space:normal}.xl\:appearance-none{-webkit-appearance:none;-moz-appearance:none;appearance:none}.xl\:bg-fixed{background-attachment:fixed}.xl\:bg-local{background-attachment:local}.xl\:bg-scroll{background-attachment:scroll}.xl\:bg-clip-border{background-clip:border-box}.xl\:bg-clip-padding{background-clip:padding-box}.xl\:bg-clip-content{background-clip:content-box}.xl\:bg-clip-text{-webkit-background-clip:text;background-clip:text}.xl\:bg-transparent{background-color:transparent}.xl\:bg-current{background-color:currentColor}.xl\:bg-black{--bg-opacity:1;background-color:#000;background-color:rgba(0,0,0,var(--bg-opacity))}.xl\:bg-white{--bg-opacity:1;background-color:#fff;background-color:rgba(255,255,255,var(--bg-opacity))}.xl\:bg-gray-100{--bg-opacity:1;background-color:#f7fafc;background-color:rgba(247,250,252,var(--bg-opacity))}.xl\:bg-gray-200{--bg-opacity:1;background-color:#edf2f7;background-color:rgba(237,242,247,var(--bg-opacity))}.xl\:bg-gray-300{--bg-opacity:1;background-color:#e2e8f0;background-color:rgba(226,232,240,var(--bg-opacity))}.xl\:bg-gray-400{--bg-opacity:1;background-color:#cbd5e0;background-color:rgba(203,213,224,var(--bg-opacity))}.xl\:bg-gray-500{--bg-opacity:1;background-color:#a0aec0;background-color:rgba(160,174,192,var(--bg-opacity))}.xl\:bg-gray-600{--bg-opacity:1;background-color:#718096;background-color:rgba(113,128,150,var(--bg-opacity))}.xl\:bg-gray-700{--bg-opacity:1;background-color:#4a5568;background-color:rgba(74,85,104,var(--bg-opacity))}.xl\:bg-gray-800{--bg-opacity:1;background-color:#2d3748;background-color:rgba(45,55,72,var(--bg-opacity))}.xl\:bg-gray-900{--bg-opacity:1;background-color:#1a202c;background-color:rgba(26,32,44,var(--bg-opacity))}.xl\:bg-red-100{--bg-opacity:1;background-color:#fff5f5;background-color:rgba(255,245,245,var(--bg-opacity))}.xl\:bg-red-200{--bg-opacity:1;background-color:#fed7d7;background-color:rgba(254,215,215,var(--bg-opacity))}.xl\:bg-red-300{--bg-opacity:1;background-color:#feb2b2;background-color:rgba(254,178,178,var(--bg-opacity))}.xl\:bg-red-400{--bg-opacity:1;background-color:#fc8181;background-color:rgba(252,129,129,var(--bg-opacity))}.xl\:bg-red-500{--bg-opacity:1;background-color:#f56565;background-color:rgba(245,101,101,var(--bg-opacity))}.xl\:bg-red-600{--bg-opacity:1;background-color:#e53e3e;background-color:rgba(229,62,62,var(--bg-opacity))}.xl\:bg-red-700{--bg-opacity:1;background-color:#c53030;background-color:rgba(197,48,48,var(--bg-opacity))}.xl\:bg-red-800{--bg-opacity:1;background-color:#9b2c2c;background-color:rgba(155,44,44,var(--bg-opacity))}.xl\:bg-red-900{--bg-opacity:1;background-color:#742a2a;background-color:rgba(116,42,42,var(--bg-opacity))}.xl\:bg-orange-100{--bg-opacity:1;background-color:#fffaf0;background-color:rgba(255,250,240,var(--bg-opacity))}.xl\:bg-orange-200{--bg-opacity:1;background-color:#feebc8;background-color:rgba(254,235,200,var(--bg-opacity))}.xl\:bg-orange-300{--bg-opacity:1;background-color:#fbd38d;background-color:rgba(251,211,141,var(--bg-opacity))}.xl\:bg-orange-400{--bg-opacity:1;background-color:#f6ad55;background-color:rgba(246,173,85,var(--bg-opacity))}.xl\:bg-orange-500{--bg-opacity:1;background-color:#ed8936;background-color:rgba(237,137,54,var(--bg-opacity))}.xl\:bg-orange-600{--bg-opacity:1;background-color:#dd6b20;background-color:rgba(221,107,32,var(--bg-opacity))}.xl\:bg-orange-700{--bg-opacity:1;background-color:#c05621;background-color:rgba(192,86,33,var(--bg-opacity))}.xl\:bg-orange-800{--bg-opacity:1;background-color:#9c4221;background-color:rgba(156,66,33,var(--bg-opacity))}.xl\:bg-orange-900{--bg-opacity:1;background-color:#7b341e;background-color:rgba(123,52,30,var(--bg-opacity))}.xl\:bg-yellow-100{--bg-opacity:1;background-color:ivory;background-color:rgba(255,255,240,var(--bg-opacity))}.xl\:bg-yellow-200{--bg-opacity:1;background-color:#fefcbf;background-color:rgba(254,252,191,var(--bg-opacity))}.xl\:bg-yellow-300{--bg-opacity:1;background-color:#faf089;background-color:rgba(250,240,137,var(--bg-opacity))}.xl\:bg-yellow-400{--bg-opacity:1;background-color:#f6e05e;background-color:rgba(246,224,94,var(--bg-opacity))}.xl\:bg-yellow-500{--bg-opacity:1;background-color:#ecc94b;background-color:rgba(236,201,75,var(--bg-opacity))}.xl\:bg-yellow-600{--bg-opacity:1;background-color:#d69e2e;background-color:rgba(214,158,46,var(--bg-opacity))}.xl\:bg-yellow-700{--bg-opacity:1;background-color:#b7791f;background-color:rgba(183,121,31,var(--bg-opacity))}.xl\:bg-yellow-800{--bg-opacity:1;background-color:#975a16;background-color:rgba(151,90,22,var(--bg-opacity))}.xl\:bg-yellow-900{--bg-opacity:1;background-color:#744210;background-color:rgba(116,66,16,var(--bg-opacity))}.xl\:bg-green-100{--bg-opacity:1;background-color:#f0fff4;background-color:rgba(240,255,244,var(--bg-opacity))}.xl\:bg-green-200{--bg-opacity:1;background-color:#c6f6d5;background-color:rgba(198,246,213,var(--bg-opacity))}.xl\:bg-green-300{--bg-opacity:1;background-color:#9ae6b4;background-color:rgba(154,230,180,var(--bg-opacity))}.xl\:bg-green-400{--bg-opacity:1;background-color:#68d391;background-color:rgba(104,211,145,var(--bg-opacity))}.xl\:bg-green-500{--bg-opacity:1;background-color:#48bb78;background-color:rgba(72,187,120,var(--bg-opacity))}.xl\:bg-green-600{--bg-opacity:1;background-color:#38a169;background-color:rgba(56,161,105,var(--bg-opacity))}.xl\:bg-green-700{--bg-opacity:1;background-color:#2f855a;background-color:rgba(47,133,90,var(--bg-opacity))}.xl\:bg-green-800{--bg-opacity:1;background-color:#276749;background-color:rgba(39,103,73,var(--bg-opacity))}.xl\:bg-green-900{--bg-opacity:1;background-color:#22543d;background-color:rgba(34,84,61,var(--bg-opacity))}.xl\:bg-teal-100{--bg-opacity:1;background-color:#e6fffa;background-color:rgba(230,255,250,var(--bg-opacity))}.xl\:bg-teal-200{--bg-opacity:1;background-color:#b2f5ea;background-color:rgba(178,245,234,var(--bg-opacity))}.xl\:bg-teal-300{--bg-opacity:1;background-color:#81e6d9;background-color:rgba(129,230,217,var(--bg-opacity))}.xl\:bg-teal-400{--bg-opacity:1;background-color:#4fd1c5;background-color:rgba(79,209,197,var(--bg-opacity))}.xl\:bg-teal-500{--bg-opacity:1;background-color:#38b2ac;background-color:rgba(56,178,172,var(--bg-opacity))}.xl\:bg-teal-600{--bg-opacity:1;background-color:#319795;background-color:rgba(49,151,149,var(--bg-opacity))}.xl\:bg-teal-700{--bg-opacity:1;background-color:#2c7a7b;background-color:rgba(44,122,123,var(--bg-opacity))}.xl\:bg-teal-800{--bg-opacity:1;background-color:#285e61;background-color:rgba(40,94,97,var(--bg-opacity))}.xl\:bg-teal-900{--bg-opacity:1;background-color:#234e52;background-color:rgba(35,78,82,var(--bg-opacity))}.xl\:bg-blue-100{--bg-opacity:1;background-color:#ebf8ff;background-color:rgba(235,248,255,var(--bg-opacity))}.xl\:bg-blue-200{--bg-opacity:1;background-color:#bee3f8;background-color:rgba(190,227,248,var(--bg-opacity))}.xl\:bg-blue-300{--bg-opacity:1;background-color:#90cdf4;background-color:rgba(144,205,244,var(--bg-opacity))}.xl\:bg-blue-400{--bg-opacity:1;background-color:#63b3ed;background-color:rgba(99,179,237,var(--bg-opacity))}.xl\:bg-blue-500{--bg-opacity:1;background-color:#4299e1;background-color:rgba(66,153,225,var(--bg-opacity))}.xl\:bg-blue-600{--bg-opacity:1;background-color:#3182ce;background-color:rgba(49,130,206,var(--bg-opacity))}.xl\:bg-blue-700{--bg-opacity:1;background-color:#2b6cb0;background-color:rgba(43,108,176,var(--bg-opacity))}.xl\:bg-blue-800{--bg-opacity:1;background-color:#2c5282;background-color:rgba(44,82,130,var(--bg-opacity))}.xl\:bg-blue-900{--bg-opacity:1;background-color:#2a4365;background-color:rgba(42,67,101,var(--bg-opacity))}.xl\:bg-indigo-100{--bg-opacity:1;background-color:#ebf4ff;background-color:rgba(235,244,255,var(--bg-opacity))}.xl\:bg-indigo-200{--bg-opacity:1;background-color:#c3dafe;background-color:rgba(195,218,254,var(--bg-opacity))}.xl\:bg-indigo-300{--bg-opacity:1;background-color:#a3bffa;background-color:rgba(163,191,250,var(--bg-opacity))}.xl\:bg-indigo-400{--bg-opacity:1;background-color:#7f9cf5;background-color:rgba(127,156,245,var(--bg-opacity))}.xl\:bg-indigo-500{--bg-opacity:1;background-color:#667eea;background-color:rgba(102,126,234,var(--bg-opacity))}.xl\:bg-indigo-600{--bg-opacity:1;background-color:#5a67d8;background-color:rgba(90,103,216,var(--bg-opacity))}.xl\:bg-indigo-700{--bg-opacity:1;background-color:#4c51bf;background-color:rgba(76,81,191,var(--bg-opacity))}.xl\:bg-indigo-800{--bg-opacity:1;background-color:#434190;background-color:rgba(67,65,144,var(--bg-opacity))}.xl\:bg-indigo-900{--bg-opacity:1;background-color:#3c366b;background-color:rgba(60,54,107,var(--bg-opacity))}.xl\:bg-purple-100{--bg-opacity:1;background-color:#faf5ff;background-color:rgba(250,245,255,var(--bg-opacity))}.xl\:bg-purple-200{--bg-opacity:1;background-color:#e9d8fd;background-color:rgba(233,216,253,var(--bg-opacity))}.xl\:bg-purple-300{--bg-opacity:1;background-color:#d6bcfa;background-color:rgba(214,188,250,var(--bg-opacity))}.xl\:bg-purple-400{--bg-opacity:1;background-color:#b794f4;background-color:rgba(183,148,244,var(--bg-opacity))}.xl\:bg-purple-500{--bg-opacity:1;background-color:#9f7aea;background-color:rgba(159,122,234,var(--bg-opacity))}.xl\:bg-purple-600{--bg-opacity:1;background-color:#805ad5;background-color:rgba(128,90,213,var(--bg-opacity))}.xl\:bg-purple-700{--bg-opacity:1;background-color:#6b46c1;background-color:rgba(107,70,193,var(--bg-opacity))}.xl\:bg-purple-800{--bg-opacity:1;background-color:#553c9a;background-color:rgba(85,60,154,var(--bg-opacity))}.xl\:bg-purple-900{--bg-opacity:1;background-color:#44337a;background-color:rgba(68,51,122,var(--bg-opacity))}.xl\:bg-pink-100{--bg-opacity:1;background-color:#fff5f7;background-color:rgba(255,245,247,var(--bg-opacity))}.xl\:bg-pink-200{--bg-opacity:1;background-color:#fed7e2;background-color:rgba(254,215,226,var(--bg-opacity))}.xl\:bg-pink-300{--bg-opacity:1;background-color:#fbb6ce;background-color:rgba(251,182,206,var(--bg-opacity))}.xl\:bg-pink-400{--bg-opacity:1;background-color:#f687b3;background-color:rgba(246,135,179,var(--bg-opacity))}.xl\:bg-pink-500{--bg-opacity:1;background-color:#ed64a6;background-color:rgba(237,100,166,var(--bg-opacity))}.xl\:bg-pink-600{--bg-opacity:1;background-color:#d53f8c;background-color:rgba(213,63,140,var(--bg-opacity))}.xl\:bg-pink-700{--bg-opacity:1;background-color:#b83280;background-color:rgba(184,50,128,var(--bg-opacity))}.xl\:bg-pink-800{--bg-opacity:1;background-color:#97266d;background-color:rgba(151,38,109,var(--bg-opacity))}.xl\:bg-pink-900{--bg-opacity:1;background-color:#702459;background-color:rgba(112,36,89,var(--bg-opacity))}.xl\:hover\:bg-transparent:hover{background-color:transparent}.xl\:hover\:bg-current:hover{background-color:currentColor}.xl\:hover\:bg-black:hover{--bg-opacity:1;background-color:#000;background-color:rgba(0,0,0,var(--bg-opacity))}.xl\:hover\:bg-white:hover{--bg-opacity:1;background-color:#fff;background-color:rgba(255,255,255,var(--bg-opacity))}.xl\:hover\:bg-gray-100:hover{--bg-opacity:1;background-color:#f7fafc;background-color:rgba(247,250,252,var(--bg-opacity))}.xl\:hover\:bg-gray-200:hover{--bg-opacity:1;background-color:#edf2f7;background-color:rgba(237,242,247,var(--bg-opacity))}.xl\:hover\:bg-gray-300:hover{--bg-opacity:1;background-color:#e2e8f0;background-color:rgba(226,232,240,var(--bg-opacity))}.xl\:hover\:bg-gray-400:hover{--bg-opacity:1;background-color:#cbd5e0;background-color:rgba(203,213,224,var(--bg-opacity))}.xl\:hover\:bg-gray-500:hover{--bg-opacity:1;background-color:#a0aec0;background-color:rgba(160,174,192,var(--bg-opacity))}.xl\:hover\:bg-gray-600:hover{--bg-opacity:1;background-color:#718096;background-color:rgba(113,128,150,var(--bg-opacity))}.xl\:hover\:bg-gray-700:hover{--bg-opacity:1;background-color:#4a5568;background-color:rgba(74,85,104,var(--bg-opacity))}.xl\:hover\:bg-gray-800:hover{--bg-opacity:1;background-color:#2d3748;background-color:rgba(45,55,72,var(--bg-opacity))}.xl\:hover\:bg-gray-900:hover{--bg-opacity:1;background-color:#1a202c;background-color:rgba(26,32,44,var(--bg-opacity))}.xl\:hover\:bg-red-100:hover{--bg-opacity:1;background-color:#fff5f5;background-color:rgba(255,245,245,var(--bg-opacity))}.xl\:hover\:bg-red-200:hover{--bg-opacity:1;background-color:#fed7d7;background-color:rgba(254,215,215,var(--bg-opacity))}.xl\:hover\:bg-red-300:hover{--bg-opacity:1;background-color:#feb2b2;background-color:rgba(254,178,178,var(--bg-opacity))}.xl\:hover\:bg-red-400:hover{--bg-opacity:1;background-color:#fc8181;background-color:rgba(252,129,129,var(--bg-opacity))}.xl\:hover\:bg-red-500:hover{--bg-opacity:1;background-color:#f56565;background-color:rgba(245,101,101,var(--bg-opacity))}.xl\:hover\:bg-red-600:hover{--bg-opacity:1;background-color:#e53e3e;background-color:rgba(229,62,62,var(--bg-opacity))}.xl\:hover\:bg-red-700:hover{--bg-opacity:1;background-color:#c53030;background-color:rgba(197,48,48,var(--bg-opacity))}.xl\:hover\:bg-red-800:hover{--bg-opacity:1;background-color:#9b2c2c;background-color:rgba(155,44,44,var(--bg-opacity))}.xl\:hover\:bg-red-900:hover{--bg-opacity:1;background-color:#742a2a;background-color:rgba(116,42,42,var(--bg-opacity))}.xl\:hover\:bg-orange-100:hover{--bg-opacity:1;background-color:#fffaf0;background-color:rgba(255,250,240,var(--bg-opacity))}.xl\:hover\:bg-orange-200:hover{--bg-opacity:1;background-color:#feebc8;background-color:rgba(254,235,200,var(--bg-opacity))}.xl\:hover\:bg-orange-300:hover{--bg-opacity:1;background-color:#fbd38d;background-color:rgba(251,211,141,var(--bg-opacity))}.xl\:hover\:bg-orange-400:hover{--bg-opacity:1;background-color:#f6ad55;background-color:rgba(246,173,85,var(--bg-opacity))}.xl\:hover\:bg-orange-500:hover{--bg-opacity:1;background-color:#ed8936;background-color:rgba(237,137,54,var(--bg-opacity))}.xl\:hover\:bg-orange-600:hover{--bg-opacity:1;background-color:#dd6b20;background-color:rgba(221,107,32,var(--bg-opacity))}.xl\:hover\:bg-orange-700:hover{--bg-opacity:1;background-color:#c05621;background-color:rgba(192,86,33,var(--bg-opacity))}.xl\:hover\:bg-orange-800:hover{--bg-opacity:1;background-color:#9c4221;background-color:rgba(156,66,33,var(--bg-opacity))}.xl\:hover\:bg-orange-900:hover{--bg-opacity:1;background-color:#7b341e;background-color:rgba(123,52,30,var(--bg-opacity))}.xl\:hover\:bg-yellow-100:hover{--bg-opacity:1;background-color:ivory;background-color:rgba(255,255,240,var(--bg-opacity))}.xl\:hover\:bg-yellow-200:hover{--bg-opacity:1;background-color:#fefcbf;background-color:rgba(254,252,191,var(--bg-opacity))}.xl\:hover\:bg-yellow-300:hover{--bg-opacity:1;background-color:#faf089;background-color:rgba(250,240,137,var(--bg-opacity))}.xl\:hover\:bg-yellow-400:hover{--bg-opacity:1;background-color:#f6e05e;background-color:rgba(246,224,94,var(--bg-opacity))}.xl\:hover\:bg-yellow-500:hover{--bg-opacity:1;background-color:#ecc94b;background-color:rgba(236,201,75,var(--bg-opacity))}.xl\:hover\:bg-yellow-600:hover{--bg-opacity:1;background-color:#d69e2e;background-color:rgba(214,158,46,var(--bg-opacity))}.xl\:hover\:bg-yellow-700:hover{--bg-opacity:1;background-color:#b7791f;background-color:rgba(183,121,31,var(--bg-opacity))}.xl\:hover\:bg-yellow-800:hover{--bg-opacity:1;background-color:#975a16;background-color:rgba(151,90,22,var(--bg-opacity))}.xl\:hover\:bg-yellow-900:hover{--bg-opacity:1;background-color:#744210;background-color:rgba(116,66,16,var(--bg-opacity))}.xl\:hover\:bg-green-100:hover{--bg-opacity:1;background-color:#f0fff4;background-color:rgba(240,255,244,var(--bg-opacity))}.xl\:hover\:bg-green-200:hover{--bg-opacity:1;background-color:#c6f6d5;background-color:rgba(198,246,213,var(--bg-opacity))}.xl\:hover\:bg-green-300:hover{--bg-opacity:1;background-color:#9ae6b4;background-color:rgba(154,230,180,var(--bg-opacity))}.xl\:hover\:bg-green-400:hover{--bg-opacity:1;background-color:#68d391;background-color:rgba(104,211,145,var(--bg-opacity))}.xl\:hover\:bg-green-500:hover{--bg-opacity:1;background-color:#48bb78;background-color:rgba(72,187,120,var(--bg-opacity))}.xl\:hover\:bg-green-600:hover{--bg-opacity:1;background-color:#38a169;background-color:rgba(56,161,105,var(--bg-opacity))}.xl\:hover\:bg-green-700:hover{--bg-opacity:1;background-color:#2f855a;background-color:rgba(47,133,90,var(--bg-opacity))}.xl\:hover\:bg-green-800:hover{--bg-opacity:1;background-color:#276749;background-color:rgba(39,103,73,var(--bg-opacity))}.xl\:hover\:bg-green-900:hover{--bg-opacity:1;background-color:#22543d;background-color:rgba(34,84,61,var(--bg-opacity))}.xl\:hover\:bg-teal-100:hover{--bg-opacity:1;background-color:#e6fffa;background-color:rgba(230,255,250,var(--bg-opacity))}.xl\:hover\:bg-teal-200:hover{--bg-opacity:1;background-color:#b2f5ea;background-color:rgba(178,245,234,var(--bg-opacity))}.xl\:hover\:bg-teal-300:hover{--bg-opacity:1;background-color:#81e6d9;background-color:rgba(129,230,217,var(--bg-opacity))}.xl\:hover\:bg-teal-400:hover{--bg-opacity:1;background-color:#4fd1c5;background-color:rgba(79,209,197,var(--bg-opacity))}.xl\:hover\:bg-teal-500:hover{--bg-opacity:1;background-color:#38b2ac;background-color:rgba(56,178,172,var(--bg-opacity))}.xl\:hover\:bg-teal-600:hover{--bg-opacity:1;background-color:#319795;background-color:rgba(49,151,149,var(--bg-opacity))}.xl\:hover\:bg-teal-700:hover{--bg-opacity:1;background-color:#2c7a7b;background-color:rgba(44,122,123,var(--bg-opacity))}.xl\:hover\:bg-teal-800:hover{--bg-opacity:1;background-color:#285e61;background-color:rgba(40,94,97,var(--bg-opacity))}.xl\:hover\:bg-teal-900:hover{--bg-opacity:1;background-color:#234e52;background-color:rgba(35,78,82,var(--bg-opacity))}.xl\:hover\:bg-blue-100:hover{--bg-opacity:1;background-color:#ebf8ff;background-color:rgba(235,248,255,var(--bg-opacity))}.xl\:hover\:bg-blue-200:hover{--bg-opacity:1;background-color:#bee3f8;background-color:rgba(190,227,248,var(--bg-opacity))}.xl\:hover\:bg-blue-300:hover{--bg-opacity:1;background-color:#90cdf4;background-color:rgba(144,205,244,var(--bg-opacity))}.xl\:hover\:bg-blue-400:hover{--bg-opacity:1;background-color:#63b3ed;background-color:rgba(99,179,237,var(--bg-opacity))}.xl\:hover\:bg-blue-500:hover{--bg-opacity:1;background-color:#4299e1;background-color:rgba(66,153,225,var(--bg-opacity))}.xl\:hover\:bg-blue-600:hover{--bg-opacity:1;background-color:#3182ce;background-color:rgba(49,130,206,var(--bg-opacity))}.xl\:hover\:bg-blue-700:hover{--bg-opacity:1;background-color:#2b6cb0;background-color:rgba(43,108,176,var(--bg-opacity))}.xl\:hover\:bg-blue-800:hover{--bg-opacity:1;background-color:#2c5282;background-color:rgba(44,82,130,var(--bg-opacity))}.xl\:hover\:bg-blue-900:hover{--bg-opacity:1;background-color:#2a4365;background-color:rgba(42,67,101,var(--bg-opacity))}.xl\:hover\:bg-indigo-100:hover{--bg-opacity:1;background-color:#ebf4ff;background-color:rgba(235,244,255,var(--bg-opacity))}.xl\:hover\:bg-indigo-200:hover{--bg-opacity:1;background-color:#c3dafe;background-color:rgba(195,218,254,var(--bg-opacity))}.xl\:hover\:bg-indigo-300:hover{--bg-opacity:1;background-color:#a3bffa;background-color:rgba(163,191,250,var(--bg-opacity))}.xl\:hover\:bg-indigo-400:hover{--bg-opacity:1;background-color:#7f9cf5;background-color:rgba(127,156,245,var(--bg-opacity))}.xl\:hover\:bg-indigo-500:hover{--bg-opacity:1;background-color:#667eea;background-color:rgba(102,126,234,var(--bg-opacity))}.xl\:hover\:bg-indigo-600:hover{--bg-opacity:1;background-color:#5a67d8;background-color:rgba(90,103,216,var(--bg-opacity))}.xl\:hover\:bg-indigo-700:hover{--bg-opacity:1;background-color:#4c51bf;background-color:rgba(76,81,191,var(--bg-opacity))}.xl\:hover\:bg-indigo-800:hover{--bg-opacity:1;background-color:#434190;background-color:rgba(67,65,144,var(--bg-opacity))}.xl\:hover\:bg-indigo-900:hover{--bg-opacity:1;background-color:#3c366b;background-color:rgba(60,54,107,var(--bg-opacity))}.xl\:hover\:bg-purple-100:hover{--bg-opacity:1;background-color:#faf5ff;background-color:rgba(250,245,255,var(--bg-opacity))}.xl\:hover\:bg-purple-200:hover{--bg-opacity:1;background-color:#e9d8fd;background-color:rgba(233,216,253,var(--bg-opacity))}.xl\:hover\:bg-purple-300:hover{--bg-opacity:1;background-color:#d6bcfa;background-color:rgba(214,188,250,var(--bg-opacity))}.xl\:hover\:bg-purple-400:hover{--bg-opacity:1;background-color:#b794f4;background-color:rgba(183,148,244,var(--bg-opacity))}.xl\:hover\:bg-purple-500:hover{--bg-opacity:1;background-color:#9f7aea;background-color:rgba(159,122,234,var(--bg-opacity))}.xl\:hover\:bg-purple-600:hover{--bg-opacity:1;background-color:#805ad5;background-color:rgba(128,90,213,var(--bg-opacity))}.xl\:hover\:bg-purple-700:hover{--bg-opacity:1;background-color:#6b46c1;background-color:rgba(107,70,193,var(--bg-opacity))}.xl\:hover\:bg-purple-800:hover{--bg-opacity:1;background-color:#553c9a;background-color:rgba(85,60,154,var(--bg-opacity))}.xl\:hover\:bg-purple-900:hover{--bg-opacity:1;background-color:#44337a;background-color:rgba(68,51,122,var(--bg-opacity))}.xl\:hover\:bg-pink-100:hover{--bg-opacity:1;background-color:#fff5f7;background-color:rgba(255,245,247,var(--bg-opacity))}.xl\:hover\:bg-pink-200:hover{--bg-opacity:1;background-color:#fed7e2;background-color:rgba(254,215,226,var(--bg-opacity))}.xl\:hover\:bg-pink-300:hover{--bg-opacity:1;background-color:#fbb6ce;background-color:rgba(251,182,206,var(--bg-opacity))}.xl\:hover\:bg-pink-400:hover{--bg-opacity:1;background-color:#f687b3;background-color:rgba(246,135,179,var(--bg-opacity))}.xl\:hover\:bg-pink-500:hover{--bg-opacity:1;background-color:#ed64a6;background-color:rgba(237,100,166,var(--bg-opacity))}.xl\:hover\:bg-pink-600:hover{--bg-opacity:1;background-color:#d53f8c;background-color:rgba(213,63,140,var(--bg-opacity))}.xl\:hover\:bg-pink-700:hover{--bg-opacity:1;background-color:#b83280;background-color:rgba(184,50,128,var(--bg-opacity))}.xl\:hover\:bg-pink-800:hover{--bg-opacity:1;background-color:#97266d;background-color:rgba(151,38,109,var(--bg-opacity))}.xl\:hover\:bg-pink-900:hover{--bg-opacity:1;background-color:#702459;background-color:rgba(112,36,89,var(--bg-opacity))}.xl\:focus\:bg-transparent:focus{background-color:transparent}.xl\:focus\:bg-current:focus{background-color:currentColor}.xl\:focus\:bg-black:focus{--bg-opacity:1;background-color:#000;background-color:rgba(0,0,0,var(--bg-opacity))}.xl\:focus\:bg-white:focus{--bg-opacity:1;background-color:#fff;background-color:rgba(255,255,255,var(--bg-opacity))}.xl\:focus\:bg-gray-100:focus{--bg-opacity:1;background-color:#f7fafc;background-color:rgba(247,250,252,var(--bg-opacity))}.xl\:focus\:bg-gray-200:focus{--bg-opacity:1;background-color:#edf2f7;background-color:rgba(237,242,247,var(--bg-opacity))}.xl\:focus\:bg-gray-300:focus{--bg-opacity:1;background-color:#e2e8f0;background-color:rgba(226,232,240,var(--bg-opacity))}.xl\:focus\:bg-gray-400:focus{--bg-opacity:1;background-color:#cbd5e0;background-color:rgba(203,213,224,var(--bg-opacity))}.xl\:focus\:bg-gray-500:focus{--bg-opacity:1;background-color:#a0aec0;background-color:rgba(160,174,192,var(--bg-opacity))}.xl\:focus\:bg-gray-600:focus{--bg-opacity:1;background-color:#718096;background-color:rgba(113,128,150,var(--bg-opacity))}.xl\:focus\:bg-gray-700:focus{--bg-opacity:1;background-color:#4a5568;background-color:rgba(74,85,104,var(--bg-opacity))}.xl\:focus\:bg-gray-800:focus{--bg-opacity:1;background-color:#2d3748;background-color:rgba(45,55,72,var(--bg-opacity))}.xl\:focus\:bg-gray-900:focus{--bg-opacity:1;background-color:#1a202c;background-color:rgba(26,32,44,var(--bg-opacity))}.xl\:focus\:bg-red-100:focus{--bg-opacity:1;background-color:#fff5f5;background-color:rgba(255,245,245,var(--bg-opacity))}.xl\:focus\:bg-red-200:focus{--bg-opacity:1;background-color:#fed7d7;background-color:rgba(254,215,215,var(--bg-opacity))}.xl\:focus\:bg-red-300:focus{--bg-opacity:1;background-color:#feb2b2;background-color:rgba(254,178,178,var(--bg-opacity))}.xl\:focus\:bg-red-400:focus{--bg-opacity:1;background-color:#fc8181;background-color:rgba(252,129,129,var(--bg-opacity))}.xl\:focus\:bg-red-500:focus{--bg-opacity:1;background-color:#f56565;background-color:rgba(245,101,101,var(--bg-opacity))}.xl\:focus\:bg-red-600:focus{--bg-opacity:1;background-color:#e53e3e;background-color:rgba(229,62,62,var(--bg-opacity))}.xl\:focus\:bg-red-700:focus{--bg-opacity:1;background-color:#c53030;background-color:rgba(197,48,48,var(--bg-opacity))}.xl\:focus\:bg-red-800:focus{--bg-opacity:1;background-color:#9b2c2c;background-color:rgba(155,44,44,var(--bg-opacity))}.xl\:focus\:bg-red-900:focus{--bg-opacity:1;background-color:#742a2a;background-color:rgba(116,42,42,var(--bg-opacity))}.xl\:focus\:bg-orange-100:focus{--bg-opacity:1;background-color:#fffaf0;background-color:rgba(255,250,240,var(--bg-opacity))}.xl\:focus\:bg-orange-200:focus{--bg-opacity:1;background-color:#feebc8;background-color:rgba(254,235,200,var(--bg-opacity))}.xl\:focus\:bg-orange-300:focus{--bg-opacity:1;background-color:#fbd38d;background-color:rgba(251,211,141,var(--bg-opacity))}.xl\:focus\:bg-orange-400:focus{--bg-opacity:1;background-color:#f6ad55;background-color:rgba(246,173,85,var(--bg-opacity))}.xl\:focus\:bg-orange-500:focus{--bg-opacity:1;background-color:#ed8936;background-color:rgba(237,137,54,var(--bg-opacity))}.xl\:focus\:bg-orange-600:focus{--bg-opacity:1;background-color:#dd6b20;background-color:rgba(221,107,32,var(--bg-opacity))}.xl\:focus\:bg-orange-700:focus{--bg-opacity:1;background-color:#c05621;background-color:rgba(192,86,33,var(--bg-opacity))}.xl\:focus\:bg-orange-800:focus{--bg-opacity:1;background-color:#9c4221;background-color:rgba(156,66,33,var(--bg-opacity))}.xl\:focus\:bg-orange-900:focus{--bg-opacity:1;background-color:#7b341e;background-color:rgba(123,52,30,var(--bg-opacity))}.xl\:focus\:bg-yellow-100:focus{--bg-opacity:1;background-color:ivory;background-color:rgba(255,255,240,var(--bg-opacity))}.xl\:focus\:bg-yellow-200:focus{--bg-opacity:1;background-color:#fefcbf;background-color:rgba(254,252,191,var(--bg-opacity))}.xl\:focus\:bg-yellow-300:focus{--bg-opacity:1;background-color:#faf089;background-color:rgba(250,240,137,var(--bg-opacity))}.xl\:focus\:bg-yellow-400:focus{--bg-opacity:1;background-color:#f6e05e;background-color:rgba(246,224,94,var(--bg-opacity))}.xl\:focus\:bg-yellow-500:focus{--bg-opacity:1;background-color:#ecc94b;background-color:rgba(236,201,75,var(--bg-opacity))}.xl\:focus\:bg-yellow-600:focus{--bg-opacity:1;background-color:#d69e2e;background-color:rgba(214,158,46,var(--bg-opacity))}.xl\:focus\:bg-yellow-700:focus{--bg-opacity:1;background-color:#b7791f;background-color:rgba(183,121,31,var(--bg-opacity))}.xl\:focus\:bg-yellow-800:focus{--bg-opacity:1;background-color:#975a16;background-color:rgba(151,90,22,var(--bg-opacity))}.xl\:focus\:bg-yellow-900:focus{--bg-opacity:1;background-color:#744210;background-color:rgba(116,66,16,var(--bg-opacity))}.xl\:focus\:bg-green-100:focus{--bg-opacity:1;background-color:#f0fff4;background-color:rgba(240,255,244,var(--bg-opacity))}.xl\:focus\:bg-green-200:focus{--bg-opacity:1;background-color:#c6f6d5;background-color:rgba(198,246,213,var(--bg-opacity))}.xl\:focus\:bg-green-300:focus{--bg-opacity:1;background-color:#9ae6b4;background-color:rgba(154,230,180,var(--bg-opacity))}.xl\:focus\:bg-green-400:focus{--bg-opacity:1;background-color:#68d391;background-color:rgba(104,211,145,var(--bg-opacity))}.xl\:focus\:bg-green-500:focus{--bg-opacity:1;background-color:#48bb78;background-color:rgba(72,187,120,var(--bg-opacity))}.xl\:focus\:bg-green-600:focus{--bg-opacity:1;background-color:#38a169;background-color:rgba(56,161,105,var(--bg-opacity))}.xl\:focus\:bg-green-700:focus{--bg-opacity:1;background-color:#2f855a;background-color:rgba(47,133,90,var(--bg-opacity))}.xl\:focus\:bg-green-800:focus{--bg-opacity:1;background-color:#276749;background-color:rgba(39,103,73,var(--bg-opacity))}.xl\:focus\:bg-green-900:focus{--bg-opacity:1;background-color:#22543d;background-color:rgba(34,84,61,var(--bg-opacity))}.xl\:focus\:bg-teal-100:focus{--bg-opacity:1;background-color:#e6fffa;background-color:rgba(230,255,250,var(--bg-opacity))}.xl\:focus\:bg-teal-200:focus{--bg-opacity:1;background-color:#b2f5ea;background-color:rgba(178,245,234,var(--bg-opacity))}.xl\:focus\:bg-teal-300:focus{--bg-opacity:1;background-color:#81e6d9;background-color:rgba(129,230,217,var(--bg-opacity))}.xl\:focus\:bg-teal-400:focus{--bg-opacity:1;background-color:#4fd1c5;background-color:rgba(79,209,197,var(--bg-opacity))}.xl\:focus\:bg-teal-500:focus{--bg-opacity:1;background-color:#38b2ac;background-color:rgba(56,178,172,var(--bg-opacity))}.xl\:focus\:bg-teal-600:focus{--bg-opacity:1;background-color:#319795;background-color:rgba(49,151,149,var(--bg-opacity))}.xl\:focus\:bg-teal-700:focus{--bg-opacity:1;background-color:#2c7a7b;background-color:rgba(44,122,123,var(--bg-opacity))}.xl\:focus\:bg-teal-800:focus{--bg-opacity:1;background-color:#285e61;background-color:rgba(40,94,97,var(--bg-opacity))}.xl\:focus\:bg-teal-900:focus{--bg-opacity:1;background-color:#234e52;background-color:rgba(35,78,82,var(--bg-opacity))}.xl\:focus\:bg-blue-100:focus{--bg-opacity:1;background-color:#ebf8ff;background-color:rgba(235,248,255,var(--bg-opacity))}.xl\:focus\:bg-blue-200:focus{--bg-opacity:1;background-color:#bee3f8;background-color:rgba(190,227,248,var(--bg-opacity))}.xl\:focus\:bg-blue-300:focus{--bg-opacity:1;background-color:#90cdf4;background-color:rgba(144,205,244,var(--bg-opacity))}.xl\:focus\:bg-blue-400:focus{--bg-opacity:1;background-color:#63b3ed;background-color:rgba(99,179,237,var(--bg-opacity))}.xl\:focus\:bg-blue-500:focus{--bg-opacity:1;background-color:#4299e1;background-color:rgba(66,153,225,var(--bg-opacity))}.xl\:focus\:bg-blue-600:focus{--bg-opacity:1;background-color:#3182ce;background-color:rgba(49,130,206,var(--bg-opacity))}.xl\:focus\:bg-blue-700:focus{--bg-opacity:1;background-color:#2b6cb0;background-color:rgba(43,108,176,var(--bg-opacity))}.xl\:focus\:bg-blue-800:focus{--bg-opacity:1;background-color:#2c5282;background-color:rgba(44,82,130,var(--bg-opacity))}.xl\:focus\:bg-blue-900:focus{--bg-opacity:1;background-color:#2a4365;background-color:rgba(42,67,101,var(--bg-opacity))}.xl\:focus\:bg-indigo-100:focus{--bg-opacity:1;background-color:#ebf4ff;background-color:rgba(235,244,255,var(--bg-opacity))}.xl\:focus\:bg-indigo-200:focus{--bg-opacity:1;background-color:#c3dafe;background-color:rgba(195,218,254,var(--bg-opacity))}.xl\:focus\:bg-indigo-300:focus{--bg-opacity:1;background-color:#a3bffa;background-color:rgba(163,191,250,var(--bg-opacity))}.xl\:focus\:bg-indigo-400:focus{--bg-opacity:1;background-color:#7f9cf5;background-color:rgba(127,156,245,var(--bg-opacity))}.xl\:focus\:bg-indigo-500:focus{--bg-opacity:1;background-color:#667eea;background-color:rgba(102,126,234,var(--bg-opacity))}.xl\:focus\:bg-indigo-600:focus{--bg-opacity:1;background-color:#5a67d8;background-color:rgba(90,103,216,var(--bg-opacity))}.xl\:focus\:bg-indigo-700:focus{--bg-opacity:1;background-color:#4c51bf;background-color:rgba(76,81,191,var(--bg-opacity))}.xl\:focus\:bg-indigo-800:focus{--bg-opacity:1;background-color:#434190;background-color:rgba(67,65,144,var(--bg-opacity))}.xl\:focus\:bg-indigo-900:focus{--bg-opacity:1;background-color:#3c366b;background-color:rgba(60,54,107,var(--bg-opacity))}.xl\:focus\:bg-purple-100:focus{--bg-opacity:1;background-color:#faf5ff;background-color:rgba(250,245,255,var(--bg-opacity))}.xl\:focus\:bg-purple-200:focus{--bg-opacity:1;background-color:#e9d8fd;background-color:rgba(233,216,253,var(--bg-opacity))}.xl\:focus\:bg-purple-300:focus{--bg-opacity:1;background-color:#d6bcfa;background-color:rgba(214,188,250,var(--bg-opacity))}.xl\:focus\:bg-purple-400:focus{--bg-opacity:1;background-color:#b794f4;background-color:rgba(183,148,244,var(--bg-opacity))}.xl\:focus\:bg-purple-500:focus{--bg-opacity:1;background-color:#9f7aea;background-color:rgba(159,122,234,var(--bg-opacity))}.xl\:focus\:bg-purple-600:focus{--bg-opacity:1;background-color:#805ad5;background-color:rgba(128,90,213,var(--bg-opacity))}.xl\:focus\:bg-purple-700:focus{--bg-opacity:1;background-color:#6b46c1;background-color:rgba(107,70,193,var(--bg-opacity))}.xl\:focus\:bg-purple-800:focus{--bg-opacity:1;background-color:#553c9a;background-color:rgba(85,60,154,var(--bg-opacity))}.xl\:focus\:bg-purple-900:focus{--bg-opacity:1;background-color:#44337a;background-color:rgba(68,51,122,var(--bg-opacity))}.xl\:focus\:bg-pink-100:focus{--bg-opacity:1;background-color:#fff5f7;background-color:rgba(255,245,247,var(--bg-opacity))}.xl\:focus\:bg-pink-200:focus{--bg-opacity:1;background-color:#fed7e2;background-color:rgba(254,215,226,var(--bg-opacity))}.xl\:focus\:bg-pink-300:focus{--bg-opacity:1;background-color:#fbb6ce;background-color:rgba(251,182,206,var(--bg-opacity))}.xl\:focus\:bg-pink-400:focus{--bg-opacity:1;background-color:#f687b3;background-color:rgba(246,135,179,var(--bg-opacity))}.xl\:focus\:bg-pink-500:focus{--bg-opacity:1;background-color:#ed64a6;background-color:rgba(237,100,166,var(--bg-opacity))}.xl\:focus\:bg-pink-600:focus{--bg-opacity:1;background-color:#d53f8c;background-color:rgba(213,63,140,var(--bg-opacity))}.xl\:focus\:bg-pink-700:focus{--bg-opacity:1;background-color:#b83280;background-color:rgba(184,50,128,var(--bg-opacity))}.xl\:focus\:bg-pink-800:focus{--bg-opacity:1;background-color:#97266d;background-color:rgba(151,38,109,var(--bg-opacity))}.xl\:focus\:bg-pink-900:focus{--bg-opacity:1;background-color:#702459;background-color:rgba(112,36,89,var(--bg-opacity))}.xl\:bg-none{background-image:none}.xl\:bg-gradient-to-t{background-image:linear-gradient(to top,var(--gradient-color-stops))}.xl\:bg-gradient-to-tr{background-image:linear-gradient(to top right,var(--gradient-color-stops))}.xl\:bg-gradient-to-r{background-image:linear-gradient(to right,var(--gradient-color-stops))}.xl\:bg-gradient-to-br{background-image:linear-gradient(to bottom right,var(--gradient-color-stops))}.xl\:bg-gradient-to-b{background-image:linear-gradient(to bottom,var(--gradient-color-stops))}.xl\:bg-gradient-to-bl{background-image:linear-gradient(to bottom left,var(--gradient-color-stops))}.xl\:bg-gradient-to-l{background-image:linear-gradient(to left,var(--gradient-color-stops))}.xl\:bg-gradient-to-tl{background-image:linear-gradient(to top left,var(--gradient-color-stops))}.xl\:from-transparent{--gradient-from-color:transparent;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(0, 0, 0, 0))}.xl\:from-current{--gradient-from-color:currentColor;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 255, 255, 0))}.xl\:from-black{--gradient-from-color:#000;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(0, 0, 0, 0))}.xl\:from-white{--gradient-from-color:#fff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 255, 255, 0))}.xl\:from-gray-100{--gradient-from-color:#f7fafc;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(247, 250, 252, 0))}.xl\:from-gray-200{--gradient-from-color:#edf2f7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(237, 242, 247, 0))}.xl\:from-gray-300{--gradient-from-color:#e2e8f0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(226, 232, 240, 0))}.xl\:from-gray-400{--gradient-from-color:#cbd5e0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(203, 213, 224, 0))}.xl\:from-gray-500{--gradient-from-color:#a0aec0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(160, 174, 192, 0))}.xl\:from-gray-600{--gradient-from-color:#718096;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(113, 128, 150, 0))}.xl\:from-gray-700{--gradient-from-color:#4a5568;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(74, 85, 104, 0))}.xl\:from-gray-800{--gradient-from-color:#2d3748;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(45, 55, 72, 0))}.xl\:from-gray-900{--gradient-from-color:#1a202c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(26, 32, 44, 0))}.xl\:from-red-100{--gradient-from-color:#fff5f5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 245, 245, 0))}.xl\:from-red-200{--gradient-from-color:#fed7d7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(254, 215, 215, 0))}.xl\:from-red-300{--gradient-from-color:#feb2b2;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(254, 178, 178, 0))}.xl\:from-red-400{--gradient-from-color:#fc8181;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(252, 129, 129, 0))}.xl\:from-red-500{--gradient-from-color:#f56565;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(245, 101, 101, 0))}.xl\:from-red-600{--gradient-from-color:#e53e3e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(229, 62, 62, 0))}.xl\:from-red-700{--gradient-from-color:#c53030;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(197, 48, 48, 0))}.xl\:from-red-800{--gradient-from-color:#9b2c2c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(155, 44, 44, 0))}.xl\:from-red-900{--gradient-from-color:#742a2a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(116, 42, 42, 0))}.xl\:from-orange-100{--gradient-from-color:#fffaf0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 250, 240, 0))}.xl\:from-orange-200{--gradient-from-color:#feebc8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(254, 235, 200, 0))}.xl\:from-orange-300{--gradient-from-color:#fbd38d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(251, 211, 141, 0))}.xl\:from-orange-400{--gradient-from-color:#f6ad55;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(246, 173, 85, 0))}.xl\:from-orange-500{--gradient-from-color:#ed8936;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(237, 137, 54, 0))}.xl\:from-orange-600{--gradient-from-color:#dd6b20;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(221, 107, 32, 0))}.xl\:from-orange-700{--gradient-from-color:#c05621;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(192, 86, 33, 0))}.xl\:from-orange-800{--gradient-from-color:#9c4221;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(156, 66, 33, 0))}.xl\:from-orange-900{--gradient-from-color:#7b341e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(123, 52, 30, 0))}.xl\:from-yellow-100{--gradient-from-color:#fffff0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 255, 240, 0))}.xl\:from-yellow-200{--gradient-from-color:#fefcbf;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(254, 252, 191, 0))}.xl\:from-yellow-300{--gradient-from-color:#faf089;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(250, 240, 137, 0))}.xl\:from-yellow-400{--gradient-from-color:#f6e05e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(246, 224, 94, 0))}.xl\:from-yellow-500{--gradient-from-color:#ecc94b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(236, 201, 75, 0))}.xl\:from-yellow-600{--gradient-from-color:#d69e2e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(214, 158, 46, 0))}.xl\:from-yellow-700{--gradient-from-color:#b7791f;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(183, 121, 31, 0))}.xl\:from-yellow-800{--gradient-from-color:#975a16;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(151, 90, 22, 0))}.xl\:from-yellow-900{--gradient-from-color:#744210;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(116, 66, 16, 0))}.xl\:from-green-100{--gradient-from-color:#f0fff4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(240, 255, 244, 0))}.xl\:from-green-200{--gradient-from-color:#c6f6d5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(198, 246, 213, 0))}.xl\:from-green-300{--gradient-from-color:#9ae6b4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(154, 230, 180, 0))}.xl\:from-green-400{--gradient-from-color:#68d391;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(104, 211, 145, 0))}.xl\:from-green-500{--gradient-from-color:#48bb78;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(72, 187, 120, 0))}.xl\:from-green-600{--gradient-from-color:#38a169;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(56, 161, 105, 0))}.xl\:from-green-700{--gradient-from-color:#2f855a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(47, 133, 90, 0))}.xl\:from-green-800{--gradient-from-color:#276749;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(39, 103, 73, 0))}.xl\:from-green-900{--gradient-from-color:#22543d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(34, 84, 61, 0))}.xl\:from-teal-100{--gradient-from-color:#e6fffa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(230, 255, 250, 0))}.xl\:from-teal-200{--gradient-from-color:#b2f5ea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(178, 245, 234, 0))}.xl\:from-teal-300{--gradient-from-color:#81e6d9;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(129, 230, 217, 0))}.xl\:from-teal-400{--gradient-from-color:#4fd1c5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(79, 209, 197, 0))}.xl\:from-teal-500{--gradient-from-color:#38b2ac;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(56, 178, 172, 0))}.xl\:from-teal-600{--gradient-from-color:#319795;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(49, 151, 149, 0))}.xl\:from-teal-700{--gradient-from-color:#2c7a7b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(44, 122, 123, 0))}.xl\:from-teal-800{--gradient-from-color:#285e61;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(40, 94, 97, 0))}.xl\:from-teal-900{--gradient-from-color:#234e52;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(35, 78, 82, 0))}.xl\:from-blue-100{--gradient-from-color:#ebf8ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(235, 248, 255, 0))}.xl\:from-blue-200{--gradient-from-color:#bee3f8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(190, 227, 248, 0))}.xl\:from-blue-300{--gradient-from-color:#90cdf4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(144, 205, 244, 0))}.xl\:from-blue-400{--gradient-from-color:#63b3ed;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(99, 179, 237, 0))}.xl\:from-blue-500{--gradient-from-color:#4299e1;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(66, 153, 225, 0))}.xl\:from-blue-600{--gradient-from-color:#3182ce;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(49, 130, 206, 0))}.xl\:from-blue-700{--gradient-from-color:#2b6cb0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(43, 108, 176, 0))}.xl\:from-blue-800{--gradient-from-color:#2c5282;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(44, 82, 130, 0))}.xl\:from-blue-900{--gradient-from-color:#2a4365;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(42, 67, 101, 0))}.xl\:from-indigo-100{--gradient-from-color:#ebf4ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(235, 244, 255, 0))}.xl\:from-indigo-200{--gradient-from-color:#c3dafe;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(195, 218, 254, 0))}.xl\:from-indigo-300{--gradient-from-color:#a3bffa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(163, 191, 250, 0))}.xl\:from-indigo-400{--gradient-from-color:#7f9cf5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(127, 156, 245, 0))}.xl\:from-indigo-500{--gradient-from-color:#667eea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(102, 126, 234, 0))}.xl\:from-indigo-600{--gradient-from-color:#5a67d8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(90, 103, 216, 0))}.xl\:from-indigo-700{--gradient-from-color:#4c51bf;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(76, 81, 191, 0))}.xl\:from-indigo-800{--gradient-from-color:#434190;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(67, 65, 144, 0))}.xl\:from-indigo-900{--gradient-from-color:#3c366b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(60, 54, 107, 0))}.xl\:from-purple-100{--gradient-from-color:#faf5ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(250, 245, 255, 0))}.xl\:from-purple-200{--gradient-from-color:#e9d8fd;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(233, 216, 253, 0))}.xl\:from-purple-300{--gradient-from-color:#d6bcfa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(214, 188, 250, 0))}.xl\:from-purple-400{--gradient-from-color:#b794f4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(183, 148, 244, 0))}.xl\:from-purple-500{--gradient-from-color:#9f7aea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(159, 122, 234, 0))}.xl\:from-purple-600{--gradient-from-color:#805ad5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(128, 90, 213, 0))}.xl\:from-purple-700{--gradient-from-color:#6b46c1;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(107, 70, 193, 0))}.xl\:from-purple-800{--gradient-from-color:#553c9a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(85, 60, 154, 0))}.xl\:from-purple-900{--gradient-from-color:#44337a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(68, 51, 122, 0))}.xl\:from-pink-100{--gradient-from-color:#fff5f7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 245, 247, 0))}.xl\:from-pink-200{--gradient-from-color:#fed7e2;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(254, 215, 226, 0))}.xl\:from-pink-300{--gradient-from-color:#fbb6ce;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(251, 182, 206, 0))}.xl\:from-pink-400{--gradient-from-color:#f687b3;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(246, 135, 179, 0))}.xl\:from-pink-500{--gradient-from-color:#ed64a6;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(237, 100, 166, 0))}.xl\:from-pink-600{--gradient-from-color:#d53f8c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(213, 63, 140, 0))}.xl\:from-pink-700{--gradient-from-color:#b83280;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(184, 50, 128, 0))}.xl\:from-pink-800{--gradient-from-color:#97266d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(151, 38, 109, 0))}.xl\:from-pink-900{--gradient-from-color:#702459;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(112, 36, 89, 0))}.xl\:via-transparent{--gradient-via-color:transparent;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(0, 0, 0, 0))}.xl\:via-current{--gradient-via-color:currentColor;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 255, 255, 0))}.xl\:via-black{--gradient-via-color:#000;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(0, 0, 0, 0))}.xl\:via-white{--gradient-via-color:#fff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 255, 255, 0))}.xl\:via-gray-100{--gradient-via-color:#f7fafc;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(247, 250, 252, 0))}.xl\:via-gray-200{--gradient-via-color:#edf2f7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(237, 242, 247, 0))}.xl\:via-gray-300{--gradient-via-color:#e2e8f0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(226, 232, 240, 0))}.xl\:via-gray-400{--gradient-via-color:#cbd5e0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(203, 213, 224, 0))}.xl\:via-gray-500{--gradient-via-color:#a0aec0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(160, 174, 192, 0))}.xl\:via-gray-600{--gradient-via-color:#718096;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(113, 128, 150, 0))}.xl\:via-gray-700{--gradient-via-color:#4a5568;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(74, 85, 104, 0))}.xl\:via-gray-800{--gradient-via-color:#2d3748;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(45, 55, 72, 0))}.xl\:via-gray-900{--gradient-via-color:#1a202c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(26, 32, 44, 0))}.xl\:via-red-100{--gradient-via-color:#fff5f5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 245, 245, 0))}.xl\:via-red-200{--gradient-via-color:#fed7d7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(254, 215, 215, 0))}.xl\:via-red-300{--gradient-via-color:#feb2b2;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(254, 178, 178, 0))}.xl\:via-red-400{--gradient-via-color:#fc8181;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(252, 129, 129, 0))}.xl\:via-red-500{--gradient-via-color:#f56565;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(245, 101, 101, 0))}.xl\:via-red-600{--gradient-via-color:#e53e3e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(229, 62, 62, 0))}.xl\:via-red-700{--gradient-via-color:#c53030;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(197, 48, 48, 0))}.xl\:via-red-800{--gradient-via-color:#9b2c2c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(155, 44, 44, 0))}.xl\:via-red-900{--gradient-via-color:#742a2a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(116, 42, 42, 0))}.xl\:via-orange-100{--gradient-via-color:#fffaf0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 250, 240, 0))}.xl\:via-orange-200{--gradient-via-color:#feebc8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(254, 235, 200, 0))}.xl\:via-orange-300{--gradient-via-color:#fbd38d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(251, 211, 141, 0))}.xl\:via-orange-400{--gradient-via-color:#f6ad55;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(246, 173, 85, 0))}.xl\:via-orange-500{--gradient-via-color:#ed8936;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(237, 137, 54, 0))}.xl\:via-orange-600{--gradient-via-color:#dd6b20;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(221, 107, 32, 0))}.xl\:via-orange-700{--gradient-via-color:#c05621;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(192, 86, 33, 0))}.xl\:via-orange-800{--gradient-via-color:#9c4221;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(156, 66, 33, 0))}.xl\:via-orange-900{--gradient-via-color:#7b341e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(123, 52, 30, 0))}.xl\:via-yellow-100{--gradient-via-color:#fffff0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 255, 240, 0))}.xl\:via-yellow-200{--gradient-via-color:#fefcbf;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(254, 252, 191, 0))}.xl\:via-yellow-300{--gradient-via-color:#faf089;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(250, 240, 137, 0))}.xl\:via-yellow-400{--gradient-via-color:#f6e05e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(246, 224, 94, 0))}.xl\:via-yellow-500{--gradient-via-color:#ecc94b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(236, 201, 75, 0))}.xl\:via-yellow-600{--gradient-via-color:#d69e2e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(214, 158, 46, 0))}.xl\:via-yellow-700{--gradient-via-color:#b7791f;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(183, 121, 31, 0))}.xl\:via-yellow-800{--gradient-via-color:#975a16;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(151, 90, 22, 0))}.xl\:via-yellow-900{--gradient-via-color:#744210;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(116, 66, 16, 0))}.xl\:via-green-100{--gradient-via-color:#f0fff4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(240, 255, 244, 0))}.xl\:via-green-200{--gradient-via-color:#c6f6d5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(198, 246, 213, 0))}.xl\:via-green-300{--gradient-via-color:#9ae6b4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(154, 230, 180, 0))}.xl\:via-green-400{--gradient-via-color:#68d391;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(104, 211, 145, 0))}.xl\:via-green-500{--gradient-via-color:#48bb78;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(72, 187, 120, 0))}.xl\:via-green-600{--gradient-via-color:#38a169;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(56, 161, 105, 0))}.xl\:via-green-700{--gradient-via-color:#2f855a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(47, 133, 90, 0))}.xl\:via-green-800{--gradient-via-color:#276749;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(39, 103, 73, 0))}.xl\:via-green-900{--gradient-via-color:#22543d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(34, 84, 61, 0))}.xl\:via-teal-100{--gradient-via-color:#e6fffa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(230, 255, 250, 0))}.xl\:via-teal-200{--gradient-via-color:#b2f5ea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(178, 245, 234, 0))}.xl\:via-teal-300{--gradient-via-color:#81e6d9;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(129, 230, 217, 0))}.xl\:via-teal-400{--gradient-via-color:#4fd1c5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(79, 209, 197, 0))}.xl\:via-teal-500{--gradient-via-color:#38b2ac;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(56, 178, 172, 0))}.xl\:via-teal-600{--gradient-via-color:#319795;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(49, 151, 149, 0))}.xl\:via-teal-700{--gradient-via-color:#2c7a7b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(44, 122, 123, 0))}.xl\:via-teal-800{--gradient-via-color:#285e61;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(40, 94, 97, 0))}.xl\:via-teal-900{--gradient-via-color:#234e52;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(35, 78, 82, 0))}.xl\:via-blue-100{--gradient-via-color:#ebf8ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(235, 248, 255, 0))}.xl\:via-blue-200{--gradient-via-color:#bee3f8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(190, 227, 248, 0))}.xl\:via-blue-300{--gradient-via-color:#90cdf4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(144, 205, 244, 0))}.xl\:via-blue-400{--gradient-via-color:#63b3ed;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(99, 179, 237, 0))}.xl\:via-blue-500{--gradient-via-color:#4299e1;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(66, 153, 225, 0))}.xl\:via-blue-600{--gradient-via-color:#3182ce;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(49, 130, 206, 0))}.xl\:via-blue-700{--gradient-via-color:#2b6cb0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(43, 108, 176, 0))}.xl\:via-blue-800{--gradient-via-color:#2c5282;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(44, 82, 130, 0))}.xl\:via-blue-900{--gradient-via-color:#2a4365;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(42, 67, 101, 0))}.xl\:via-indigo-100{--gradient-via-color:#ebf4ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(235, 244, 255, 0))}.xl\:via-indigo-200{--gradient-via-color:#c3dafe;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(195, 218, 254, 0))}.xl\:via-indigo-300{--gradient-via-color:#a3bffa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(163, 191, 250, 0))}.xl\:via-indigo-400{--gradient-via-color:#7f9cf5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(127, 156, 245, 0))}.xl\:via-indigo-500{--gradient-via-color:#667eea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(102, 126, 234, 0))}.xl\:via-indigo-600{--gradient-via-color:#5a67d8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(90, 103, 216, 0))}.xl\:via-indigo-700{--gradient-via-color:#4c51bf;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(76, 81, 191, 0))}.xl\:via-indigo-800{--gradient-via-color:#434190;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(67, 65, 144, 0))}.xl\:via-indigo-900{--gradient-via-color:#3c366b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(60, 54, 107, 0))}.xl\:via-purple-100{--gradient-via-color:#faf5ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(250, 245, 255, 0))}.xl\:via-purple-200{--gradient-via-color:#e9d8fd;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(233, 216, 253, 0))}.xl\:via-purple-300{--gradient-via-color:#d6bcfa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(214, 188, 250, 0))}.xl\:via-purple-400{--gradient-via-color:#b794f4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(183, 148, 244, 0))}.xl\:via-purple-500{--gradient-via-color:#9f7aea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(159, 122, 234, 0))}.xl\:via-purple-600{--gradient-via-color:#805ad5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(128, 90, 213, 0))}.xl\:via-purple-700{--gradient-via-color:#6b46c1;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(107, 70, 193, 0))}.xl\:via-purple-800{--gradient-via-color:#553c9a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(85, 60, 154, 0))}.xl\:via-purple-900{--gradient-via-color:#44337a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(68, 51, 122, 0))}.xl\:via-pink-100{--gradient-via-color:#fff5f7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 245, 247, 0))}.xl\:via-pink-200{--gradient-via-color:#fed7e2;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(254, 215, 226, 0))}.xl\:via-pink-300{--gradient-via-color:#fbb6ce;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(251, 182, 206, 0))}.xl\:via-pink-400{--gradient-via-color:#f687b3;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(246, 135, 179, 0))}.xl\:via-pink-500{--gradient-via-color:#ed64a6;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(237, 100, 166, 0))}.xl\:via-pink-600{--gradient-via-color:#d53f8c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(213, 63, 140, 0))}.xl\:via-pink-700{--gradient-via-color:#b83280;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(184, 50, 128, 0))}.xl\:via-pink-800{--gradient-via-color:#97266d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(151, 38, 109, 0))}.xl\:via-pink-900{--gradient-via-color:#702459;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(112, 36, 89, 0))}.xl\:to-transparent{--gradient-to-color:transparent}.xl\:to-current{--gradient-to-color:currentColor}.xl\:to-black{--gradient-to-color:#000}.xl\:to-white{--gradient-to-color:#fff}.xl\:to-gray-100{--gradient-to-color:#f7fafc}.xl\:to-gray-200{--gradient-to-color:#edf2f7}.xl\:to-gray-300{--gradient-to-color:#e2e8f0}.xl\:to-gray-400{--gradient-to-color:#cbd5e0}.xl\:to-gray-500{--gradient-to-color:#a0aec0}.xl\:to-gray-600{--gradient-to-color:#718096}.xl\:to-gray-700{--gradient-to-color:#4a5568}.xl\:to-gray-800{--gradient-to-color:#2d3748}.xl\:to-gray-900{--gradient-to-color:#1a202c}.xl\:to-red-100{--gradient-to-color:#fff5f5}.xl\:to-red-200{--gradient-to-color:#fed7d7}.xl\:to-red-300{--gradient-to-color:#feb2b2}.xl\:to-red-400{--gradient-to-color:#fc8181}.xl\:to-red-500{--gradient-to-color:#f56565}.xl\:to-red-600{--gradient-to-color:#e53e3e}.xl\:to-red-700{--gradient-to-color:#c53030}.xl\:to-red-800{--gradient-to-color:#9b2c2c}.xl\:to-red-900{--gradient-to-color:#742a2a}.xl\:to-orange-100{--gradient-to-color:#fffaf0}.xl\:to-orange-200{--gradient-to-color:#feebc8}.xl\:to-orange-300{--gradient-to-color:#fbd38d}.xl\:to-orange-400{--gradient-to-color:#f6ad55}.xl\:to-orange-500{--gradient-to-color:#ed8936}.xl\:to-orange-600{--gradient-to-color:#dd6b20}.xl\:to-orange-700{--gradient-to-color:#c05621}.xl\:to-orange-800{--gradient-to-color:#9c4221}.xl\:to-orange-900{--gradient-to-color:#7b341e}.xl\:to-yellow-100{--gradient-to-color:#fffff0}.xl\:to-yellow-200{--gradient-to-color:#fefcbf}.xl\:to-yellow-300{--gradient-to-color:#faf089}.xl\:to-yellow-400{--gradient-to-color:#f6e05e}.xl\:to-yellow-500{--gradient-to-color:#ecc94b}.xl\:to-yellow-600{--gradient-to-color:#d69e2e}.xl\:to-yellow-700{--gradient-to-color:#b7791f}.xl\:to-yellow-800{--gradient-to-color:#975a16}.xl\:to-yellow-900{--gradient-to-color:#744210}.xl\:to-green-100{--gradient-to-color:#f0fff4}.xl\:to-green-200{--gradient-to-color:#c6f6d5}.xl\:to-green-300{--gradient-to-color:#9ae6b4}.xl\:to-green-400{--gradient-to-color:#68d391}.xl\:to-green-500{--gradient-to-color:#48bb78}.xl\:to-green-600{--gradient-to-color:#38a169}.xl\:to-green-700{--gradient-to-color:#2f855a}.xl\:to-green-800{--gradient-to-color:#276749}.xl\:to-green-900{--gradient-to-color:#22543d}.xl\:to-teal-100{--gradient-to-color:#e6fffa}.xl\:to-teal-200{--gradient-to-color:#b2f5ea}.xl\:to-teal-300{--gradient-to-color:#81e6d9}.xl\:to-teal-400{--gradient-to-color:#4fd1c5}.xl\:to-teal-500{--gradient-to-color:#38b2ac}.xl\:to-teal-600{--gradient-to-color:#319795}.xl\:to-teal-700{--gradient-to-color:#2c7a7b}.xl\:to-teal-800{--gradient-to-color:#285e61}.xl\:to-teal-900{--gradient-to-color:#234e52}.xl\:to-blue-100{--gradient-to-color:#ebf8ff}.xl\:to-blue-200{--gradient-to-color:#bee3f8}.xl\:to-blue-300{--gradient-to-color:#90cdf4}.xl\:to-blue-400{--gradient-to-color:#63b3ed}.xl\:to-blue-500{--gradient-to-color:#4299e1}.xl\:to-blue-600{--gradient-to-color:#3182ce}.xl\:to-blue-700{--gradient-to-color:#2b6cb0}.xl\:to-blue-800{--gradient-to-color:#2c5282}.xl\:to-blue-900{--gradient-to-color:#2a4365}.xl\:to-indigo-100{--gradient-to-color:#ebf4ff}.xl\:to-indigo-200{--gradient-to-color:#c3dafe}.xl\:to-indigo-300{--gradient-to-color:#a3bffa}.xl\:to-indigo-400{--gradient-to-color:#7f9cf5}.xl\:to-indigo-500{--gradient-to-color:#667eea}.xl\:to-indigo-600{--gradient-to-color:#5a67d8}.xl\:to-indigo-700{--gradient-to-color:#4c51bf}.xl\:to-indigo-800{--gradient-to-color:#434190}.xl\:to-indigo-900{--gradient-to-color:#3c366b}.xl\:to-purple-100{--gradient-to-color:#faf5ff}.xl\:to-purple-200{--gradient-to-color:#e9d8fd}.xl\:to-purple-300{--gradient-to-color:#d6bcfa}.xl\:to-purple-400{--gradient-to-color:#b794f4}.xl\:to-purple-500{--gradient-to-color:#9f7aea}.xl\:to-purple-600{--gradient-to-color:#805ad5}.xl\:to-purple-700{--gradient-to-color:#6b46c1}.xl\:to-purple-800{--gradient-to-color:#553c9a}.xl\:to-purple-900{--gradient-to-color:#44337a}.xl\:to-pink-100{--gradient-to-color:#fff5f7}.xl\:to-pink-200{--gradient-to-color:#fed7e2}.xl\:to-pink-300{--gradient-to-color:#fbb6ce}.xl\:to-pink-400{--gradient-to-color:#f687b3}.xl\:to-pink-500{--gradient-to-color:#ed64a6}.xl\:to-pink-600{--gradient-to-color:#d53f8c}.xl\:to-pink-700{--gradient-to-color:#b83280}.xl\:to-pink-800{--gradient-to-color:#97266d}.xl\:to-pink-900{--gradient-to-color:#702459}.xl\:hover\:from-transparent:hover{--gradient-from-color:transparent;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(0, 0, 0, 0))}.xl\:hover\:from-current:hover{--gradient-from-color:currentColor;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 255, 255, 0))}.xl\:hover\:from-black:hover{--gradient-from-color:#000;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(0, 0, 0, 0))}.xl\:hover\:from-white:hover{--gradient-from-color:#fff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 255, 255, 0))}.xl\:hover\:from-gray-100:hover{--gradient-from-color:#f7fafc;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(247, 250, 252, 0))}.xl\:hover\:from-gray-200:hover{--gradient-from-color:#edf2f7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(237, 242, 247, 0))}.xl\:hover\:from-gray-300:hover{--gradient-from-color:#e2e8f0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(226, 232, 240, 0))}.xl\:hover\:from-gray-400:hover{--gradient-from-color:#cbd5e0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(203, 213, 224, 0))}.xl\:hover\:from-gray-500:hover{--gradient-from-color:#a0aec0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(160, 174, 192, 0))}.xl\:hover\:from-gray-600:hover{--gradient-from-color:#718096;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(113, 128, 150, 0))}.xl\:hover\:from-gray-700:hover{--gradient-from-color:#4a5568;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(74, 85, 104, 0))}.xl\:hover\:from-gray-800:hover{--gradient-from-color:#2d3748;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(45, 55, 72, 0))}.xl\:hover\:from-gray-900:hover{--gradient-from-color:#1a202c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(26, 32, 44, 0))}.xl\:hover\:from-red-100:hover{--gradient-from-color:#fff5f5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 245, 245, 0))}.xl\:hover\:from-red-200:hover{--gradient-from-color:#fed7d7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(254, 215, 215, 0))}.xl\:hover\:from-red-300:hover{--gradient-from-color:#feb2b2;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(254, 178, 178, 0))}.xl\:hover\:from-red-400:hover{--gradient-from-color:#fc8181;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(252, 129, 129, 0))}.xl\:hover\:from-red-500:hover{--gradient-from-color:#f56565;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(245, 101, 101, 0))}.xl\:hover\:from-red-600:hover{--gradient-from-color:#e53e3e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(229, 62, 62, 0))}.xl\:hover\:from-red-700:hover{--gradient-from-color:#c53030;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(197, 48, 48, 0))}.xl\:hover\:from-red-800:hover{--gradient-from-color:#9b2c2c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(155, 44, 44, 0))}.xl\:hover\:from-red-900:hover{--gradient-from-color:#742a2a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(116, 42, 42, 0))}.xl\:hover\:from-orange-100:hover{--gradient-from-color:#fffaf0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 250, 240, 0))}.xl\:hover\:from-orange-200:hover{--gradient-from-color:#feebc8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(254, 235, 200, 0))}.xl\:hover\:from-orange-300:hover{--gradient-from-color:#fbd38d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(251, 211, 141, 0))}.xl\:hover\:from-orange-400:hover{--gradient-from-color:#f6ad55;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(246, 173, 85, 0))}.xl\:hover\:from-orange-500:hover{--gradient-from-color:#ed8936;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(237, 137, 54, 0))}.xl\:hover\:from-orange-600:hover{--gradient-from-color:#dd6b20;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(221, 107, 32, 0))}.xl\:hover\:from-orange-700:hover{--gradient-from-color:#c05621;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(192, 86, 33, 0))}.xl\:hover\:from-orange-800:hover{--gradient-from-color:#9c4221;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(156, 66, 33, 0))}.xl\:hover\:from-orange-900:hover{--gradient-from-color:#7b341e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(123, 52, 30, 0))}.xl\:hover\:from-yellow-100:hover{--gradient-from-color:#fffff0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 255, 240, 0))}.xl\:hover\:from-yellow-200:hover{--gradient-from-color:#fefcbf;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(254, 252, 191, 0))}.xl\:hover\:from-yellow-300:hover{--gradient-from-color:#faf089;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(250, 240, 137, 0))}.xl\:hover\:from-yellow-400:hover{--gradient-from-color:#f6e05e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(246, 224, 94, 0))}.xl\:hover\:from-yellow-500:hover{--gradient-from-color:#ecc94b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(236, 201, 75, 0))}.xl\:hover\:from-yellow-600:hover{--gradient-from-color:#d69e2e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(214, 158, 46, 0))}.xl\:hover\:from-yellow-700:hover{--gradient-from-color:#b7791f;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(183, 121, 31, 0))}.xl\:hover\:from-yellow-800:hover{--gradient-from-color:#975a16;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(151, 90, 22, 0))}.xl\:hover\:from-yellow-900:hover{--gradient-from-color:#744210;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(116, 66, 16, 0))}.xl\:hover\:from-green-100:hover{--gradient-from-color:#f0fff4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(240, 255, 244, 0))}.xl\:hover\:from-green-200:hover{--gradient-from-color:#c6f6d5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(198, 246, 213, 0))}.xl\:hover\:from-green-300:hover{--gradient-from-color:#9ae6b4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(154, 230, 180, 0))}.xl\:hover\:from-green-400:hover{--gradient-from-color:#68d391;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(104, 211, 145, 0))}.xl\:hover\:from-green-500:hover{--gradient-from-color:#48bb78;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(72, 187, 120, 0))}.xl\:hover\:from-green-600:hover{--gradient-from-color:#38a169;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(56, 161, 105, 0))}.xl\:hover\:from-green-700:hover{--gradient-from-color:#2f855a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(47, 133, 90, 0))}.xl\:hover\:from-green-800:hover{--gradient-from-color:#276749;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(39, 103, 73, 0))}.xl\:hover\:from-green-900:hover{--gradient-from-color:#22543d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(34, 84, 61, 0))}.xl\:hover\:from-teal-100:hover{--gradient-from-color:#e6fffa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(230, 255, 250, 0))}.xl\:hover\:from-teal-200:hover{--gradient-from-color:#b2f5ea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(178, 245, 234, 0))}.xl\:hover\:from-teal-300:hover{--gradient-from-color:#81e6d9;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(129, 230, 217, 0))}.xl\:hover\:from-teal-400:hover{--gradient-from-color:#4fd1c5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(79, 209, 197, 0))}.xl\:hover\:from-teal-500:hover{--gradient-from-color:#38b2ac;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(56, 178, 172, 0))}.xl\:hover\:from-teal-600:hover{--gradient-from-color:#319795;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(49, 151, 149, 0))}.xl\:hover\:from-teal-700:hover{--gradient-from-color:#2c7a7b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(44, 122, 123, 0))}.xl\:hover\:from-teal-800:hover{--gradient-from-color:#285e61;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(40, 94, 97, 0))}.xl\:hover\:from-teal-900:hover{--gradient-from-color:#234e52;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(35, 78, 82, 0))}.xl\:hover\:from-blue-100:hover{--gradient-from-color:#ebf8ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(235, 248, 255, 0))}.xl\:hover\:from-blue-200:hover{--gradient-from-color:#bee3f8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(190, 227, 248, 0))}.xl\:hover\:from-blue-300:hover{--gradient-from-color:#90cdf4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(144, 205, 244, 0))}.xl\:hover\:from-blue-400:hover{--gradient-from-color:#63b3ed;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(99, 179, 237, 0))}.xl\:hover\:from-blue-500:hover{--gradient-from-color:#4299e1;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(66, 153, 225, 0))}.xl\:hover\:from-blue-600:hover{--gradient-from-color:#3182ce;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(49, 130, 206, 0))}.xl\:hover\:from-blue-700:hover{--gradient-from-color:#2b6cb0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(43, 108, 176, 0))}.xl\:hover\:from-blue-800:hover{--gradient-from-color:#2c5282;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(44, 82, 130, 0))}.xl\:hover\:from-blue-900:hover{--gradient-from-color:#2a4365;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(42, 67, 101, 0))}.xl\:hover\:from-indigo-100:hover{--gradient-from-color:#ebf4ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(235, 244, 255, 0))}.xl\:hover\:from-indigo-200:hover{--gradient-from-color:#c3dafe;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(195, 218, 254, 0))}.xl\:hover\:from-indigo-300:hover{--gradient-from-color:#a3bffa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(163, 191, 250, 0))}.xl\:hover\:from-indigo-400:hover{--gradient-from-color:#7f9cf5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(127, 156, 245, 0))}.xl\:hover\:from-indigo-500:hover{--gradient-from-color:#667eea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(102, 126, 234, 0))}.xl\:hover\:from-indigo-600:hover{--gradient-from-color:#5a67d8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(90, 103, 216, 0))}.xl\:hover\:from-indigo-700:hover{--gradient-from-color:#4c51bf;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(76, 81, 191, 0))}.xl\:hover\:from-indigo-800:hover{--gradient-from-color:#434190;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(67, 65, 144, 0))}.xl\:hover\:from-indigo-900:hover{--gradient-from-color:#3c366b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(60, 54, 107, 0))}.xl\:hover\:from-purple-100:hover{--gradient-from-color:#faf5ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(250, 245, 255, 0))}.xl\:hover\:from-purple-200:hover{--gradient-from-color:#e9d8fd;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(233, 216, 253, 0))}.xl\:hover\:from-purple-300:hover{--gradient-from-color:#d6bcfa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(214, 188, 250, 0))}.xl\:hover\:from-purple-400:hover{--gradient-from-color:#b794f4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(183, 148, 244, 0))}.xl\:hover\:from-purple-500:hover{--gradient-from-color:#9f7aea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(159, 122, 234, 0))}.xl\:hover\:from-purple-600:hover{--gradient-from-color:#805ad5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(128, 90, 213, 0))}.xl\:hover\:from-purple-700:hover{--gradient-from-color:#6b46c1;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(107, 70, 193, 0))}.xl\:hover\:from-purple-800:hover{--gradient-from-color:#553c9a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(85, 60, 154, 0))}.xl\:hover\:from-purple-900:hover{--gradient-from-color:#44337a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(68, 51, 122, 0))}.xl\:hover\:from-pink-100:hover{--gradient-from-color:#fff5f7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 245, 247, 0))}.xl\:hover\:from-pink-200:hover{--gradient-from-color:#fed7e2;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(254, 215, 226, 0))}.xl\:hover\:from-pink-300:hover{--gradient-from-color:#fbb6ce;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(251, 182, 206, 0))}.xl\:hover\:from-pink-400:hover{--gradient-from-color:#f687b3;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(246, 135, 179, 0))}.xl\:hover\:from-pink-500:hover{--gradient-from-color:#ed64a6;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(237, 100, 166, 0))}.xl\:hover\:from-pink-600:hover{--gradient-from-color:#d53f8c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(213, 63, 140, 0))}.xl\:hover\:from-pink-700:hover{--gradient-from-color:#b83280;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(184, 50, 128, 0))}.xl\:hover\:from-pink-800:hover{--gradient-from-color:#97266d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(151, 38, 109, 0))}.xl\:hover\:from-pink-900:hover{--gradient-from-color:#702459;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(112, 36, 89, 0))}.xl\:hover\:via-transparent:hover{--gradient-via-color:transparent;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(0, 0, 0, 0))}.xl\:hover\:via-current:hover{--gradient-via-color:currentColor;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 255, 255, 0))}.xl\:hover\:via-black:hover{--gradient-via-color:#000;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(0, 0, 0, 0))}.xl\:hover\:via-white:hover{--gradient-via-color:#fff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 255, 255, 0))}.xl\:hover\:via-gray-100:hover{--gradient-via-color:#f7fafc;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(247, 250, 252, 0))}.xl\:hover\:via-gray-200:hover{--gradient-via-color:#edf2f7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(237, 242, 247, 0))}.xl\:hover\:via-gray-300:hover{--gradient-via-color:#e2e8f0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(226, 232, 240, 0))}.xl\:hover\:via-gray-400:hover{--gradient-via-color:#cbd5e0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(203, 213, 224, 0))}.xl\:hover\:via-gray-500:hover{--gradient-via-color:#a0aec0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(160, 174, 192, 0))}.xl\:hover\:via-gray-600:hover{--gradient-via-color:#718096;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(113, 128, 150, 0))}.xl\:hover\:via-gray-700:hover{--gradient-via-color:#4a5568;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(74, 85, 104, 0))}.xl\:hover\:via-gray-800:hover{--gradient-via-color:#2d3748;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(45, 55, 72, 0))}.xl\:hover\:via-gray-900:hover{--gradient-via-color:#1a202c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(26, 32, 44, 0))}.xl\:hover\:via-red-100:hover{--gradient-via-color:#fff5f5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 245, 245, 0))}.xl\:hover\:via-red-200:hover{--gradient-via-color:#fed7d7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(254, 215, 215, 0))}.xl\:hover\:via-red-300:hover{--gradient-via-color:#feb2b2;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(254, 178, 178, 0))}.xl\:hover\:via-red-400:hover{--gradient-via-color:#fc8181;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(252, 129, 129, 0))}.xl\:hover\:via-red-500:hover{--gradient-via-color:#f56565;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(245, 101, 101, 0))}.xl\:hover\:via-red-600:hover{--gradient-via-color:#e53e3e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(229, 62, 62, 0))}.xl\:hover\:via-red-700:hover{--gradient-via-color:#c53030;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(197, 48, 48, 0))}.xl\:hover\:via-red-800:hover{--gradient-via-color:#9b2c2c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(155, 44, 44, 0))}.xl\:hover\:via-red-900:hover{--gradient-via-color:#742a2a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(116, 42, 42, 0))}.xl\:hover\:via-orange-100:hover{--gradient-via-color:#fffaf0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 250, 240, 0))}.xl\:hover\:via-orange-200:hover{--gradient-via-color:#feebc8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(254, 235, 200, 0))}.xl\:hover\:via-orange-300:hover{--gradient-via-color:#fbd38d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(251, 211, 141, 0))}.xl\:hover\:via-orange-400:hover{--gradient-via-color:#f6ad55;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(246, 173, 85, 0))}.xl\:hover\:via-orange-500:hover{--gradient-via-color:#ed8936;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(237, 137, 54, 0))}.xl\:hover\:via-orange-600:hover{--gradient-via-color:#dd6b20;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(221, 107, 32, 0))}.xl\:hover\:via-orange-700:hover{--gradient-via-color:#c05621;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(192, 86, 33, 0))}.xl\:hover\:via-orange-800:hover{--gradient-via-color:#9c4221;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(156, 66, 33, 0))}.xl\:hover\:via-orange-900:hover{--gradient-via-color:#7b341e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(123, 52, 30, 0))}.xl\:hover\:via-yellow-100:hover{--gradient-via-color:#fffff0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 255, 240, 0))}.xl\:hover\:via-yellow-200:hover{--gradient-via-color:#fefcbf;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(254, 252, 191, 0))}.xl\:hover\:via-yellow-300:hover{--gradient-via-color:#faf089;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(250, 240, 137, 0))}.xl\:hover\:via-yellow-400:hover{--gradient-via-color:#f6e05e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(246, 224, 94, 0))}.xl\:hover\:via-yellow-500:hover{--gradient-via-color:#ecc94b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(236, 201, 75, 0))}.xl\:hover\:via-yellow-600:hover{--gradient-via-color:#d69e2e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(214, 158, 46, 0))}.xl\:hover\:via-yellow-700:hover{--gradient-via-color:#b7791f;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(183, 121, 31, 0))}.xl\:hover\:via-yellow-800:hover{--gradient-via-color:#975a16;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(151, 90, 22, 0))}.xl\:hover\:via-yellow-900:hover{--gradient-via-color:#744210;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(116, 66, 16, 0))}.xl\:hover\:via-green-100:hover{--gradient-via-color:#f0fff4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(240, 255, 244, 0))}.xl\:hover\:via-green-200:hover{--gradient-via-color:#c6f6d5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(198, 246, 213, 0))}.xl\:hover\:via-green-300:hover{--gradient-via-color:#9ae6b4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(154, 230, 180, 0))}.xl\:hover\:via-green-400:hover{--gradient-via-color:#68d391;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(104, 211, 145, 0))}.xl\:hover\:via-green-500:hover{--gradient-via-color:#48bb78;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(72, 187, 120, 0))}.xl\:hover\:via-green-600:hover{--gradient-via-color:#38a169;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(56, 161, 105, 0))}.xl\:hover\:via-green-700:hover{--gradient-via-color:#2f855a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(47, 133, 90, 0))}.xl\:hover\:via-green-800:hover{--gradient-via-color:#276749;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(39, 103, 73, 0))}.xl\:hover\:via-green-900:hover{--gradient-via-color:#22543d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(34, 84, 61, 0))}.xl\:hover\:via-teal-100:hover{--gradient-via-color:#e6fffa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(230, 255, 250, 0))}.xl\:hover\:via-teal-200:hover{--gradient-via-color:#b2f5ea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(178, 245, 234, 0))}.xl\:hover\:via-teal-300:hover{--gradient-via-color:#81e6d9;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(129, 230, 217, 0))}.xl\:hover\:via-teal-400:hover{--gradient-via-color:#4fd1c5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(79, 209, 197, 0))}.xl\:hover\:via-teal-500:hover{--gradient-via-color:#38b2ac;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(56, 178, 172, 0))}.xl\:hover\:via-teal-600:hover{--gradient-via-color:#319795;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(49, 151, 149, 0))}.xl\:hover\:via-teal-700:hover{--gradient-via-color:#2c7a7b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(44, 122, 123, 0))}.xl\:hover\:via-teal-800:hover{--gradient-via-color:#285e61;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(40, 94, 97, 0))}.xl\:hover\:via-teal-900:hover{--gradient-via-color:#234e52;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(35, 78, 82, 0))}.xl\:hover\:via-blue-100:hover{--gradient-via-color:#ebf8ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(235, 248, 255, 0))}.xl\:hover\:via-blue-200:hover{--gradient-via-color:#bee3f8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(190, 227, 248, 0))}.xl\:hover\:via-blue-300:hover{--gradient-via-color:#90cdf4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(144, 205, 244, 0))}.xl\:hover\:via-blue-400:hover{--gradient-via-color:#63b3ed;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(99, 179, 237, 0))}.xl\:hover\:via-blue-500:hover{--gradient-via-color:#4299e1;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(66, 153, 225, 0))}.xl\:hover\:via-blue-600:hover{--gradient-via-color:#3182ce;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(49, 130, 206, 0))}.xl\:hover\:via-blue-700:hover{--gradient-via-color:#2b6cb0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(43, 108, 176, 0))}.xl\:hover\:via-blue-800:hover{--gradient-via-color:#2c5282;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(44, 82, 130, 0))}.xl\:hover\:via-blue-900:hover{--gradient-via-color:#2a4365;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(42, 67, 101, 0))}.xl\:hover\:via-indigo-100:hover{--gradient-via-color:#ebf4ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(235, 244, 255, 0))}.xl\:hover\:via-indigo-200:hover{--gradient-via-color:#c3dafe;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(195, 218, 254, 0))}.xl\:hover\:via-indigo-300:hover{--gradient-via-color:#a3bffa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(163, 191, 250, 0))}.xl\:hover\:via-indigo-400:hover{--gradient-via-color:#7f9cf5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(127, 156, 245, 0))}.xl\:hover\:via-indigo-500:hover{--gradient-via-color:#667eea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(102, 126, 234, 0))}.xl\:hover\:via-indigo-600:hover{--gradient-via-color:#5a67d8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(90, 103, 216, 0))}.xl\:hover\:via-indigo-700:hover{--gradient-via-color:#4c51bf;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(76, 81, 191, 0))}.xl\:hover\:via-indigo-800:hover{--gradient-via-color:#434190;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(67, 65, 144, 0))}.xl\:hover\:via-indigo-900:hover{--gradient-via-color:#3c366b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(60, 54, 107, 0))}.xl\:hover\:via-purple-100:hover{--gradient-via-color:#faf5ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(250, 245, 255, 0))}.xl\:hover\:via-purple-200:hover{--gradient-via-color:#e9d8fd;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(233, 216, 253, 0))}.xl\:hover\:via-purple-300:hover{--gradient-via-color:#d6bcfa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(214, 188, 250, 0))}.xl\:hover\:via-purple-400:hover{--gradient-via-color:#b794f4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(183, 148, 244, 0))}.xl\:hover\:via-purple-500:hover{--gradient-via-color:#9f7aea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(159, 122, 234, 0))}.xl\:hover\:via-purple-600:hover{--gradient-via-color:#805ad5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(128, 90, 213, 0))}.xl\:hover\:via-purple-700:hover{--gradient-via-color:#6b46c1;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(107, 70, 193, 0))}.xl\:hover\:via-purple-800:hover{--gradient-via-color:#553c9a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(85, 60, 154, 0))}.xl\:hover\:via-purple-900:hover{--gradient-via-color:#44337a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(68, 51, 122, 0))}.xl\:hover\:via-pink-100:hover{--gradient-via-color:#fff5f7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 245, 247, 0))}.xl\:hover\:via-pink-200:hover{--gradient-via-color:#fed7e2;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(254, 215, 226, 0))}.xl\:hover\:via-pink-300:hover{--gradient-via-color:#fbb6ce;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(251, 182, 206, 0))}.xl\:hover\:via-pink-400:hover{--gradient-via-color:#f687b3;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(246, 135, 179, 0))}.xl\:hover\:via-pink-500:hover{--gradient-via-color:#ed64a6;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(237, 100, 166, 0))}.xl\:hover\:via-pink-600:hover{--gradient-via-color:#d53f8c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(213, 63, 140, 0))}.xl\:hover\:via-pink-700:hover{--gradient-via-color:#b83280;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(184, 50, 128, 0))}.xl\:hover\:via-pink-800:hover{--gradient-via-color:#97266d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(151, 38, 109, 0))}.xl\:hover\:via-pink-900:hover{--gradient-via-color:#702459;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(112, 36, 89, 0))}.xl\:hover\:to-transparent:hover{--gradient-to-color:transparent}.xl\:hover\:to-current:hover{--gradient-to-color:currentColor}.xl\:hover\:to-black:hover{--gradient-to-color:#000}.xl\:hover\:to-white:hover{--gradient-to-color:#fff}.xl\:hover\:to-gray-100:hover{--gradient-to-color:#f7fafc}.xl\:hover\:to-gray-200:hover{--gradient-to-color:#edf2f7}.xl\:hover\:to-gray-300:hover{--gradient-to-color:#e2e8f0}.xl\:hover\:to-gray-400:hover{--gradient-to-color:#cbd5e0}.xl\:hover\:to-gray-500:hover{--gradient-to-color:#a0aec0}.xl\:hover\:to-gray-600:hover{--gradient-to-color:#718096}.xl\:hover\:to-gray-700:hover{--gradient-to-color:#4a5568}.xl\:hover\:to-gray-800:hover{--gradient-to-color:#2d3748}.xl\:hover\:to-gray-900:hover{--gradient-to-color:#1a202c}.xl\:hover\:to-red-100:hover{--gradient-to-color:#fff5f5}.xl\:hover\:to-red-200:hover{--gradient-to-color:#fed7d7}.xl\:hover\:to-red-300:hover{--gradient-to-color:#feb2b2}.xl\:hover\:to-red-400:hover{--gradient-to-color:#fc8181}.xl\:hover\:to-red-500:hover{--gradient-to-color:#f56565}.xl\:hover\:to-red-600:hover{--gradient-to-color:#e53e3e}.xl\:hover\:to-red-700:hover{--gradient-to-color:#c53030}.xl\:hover\:to-red-800:hover{--gradient-to-color:#9b2c2c}.xl\:hover\:to-red-900:hover{--gradient-to-color:#742a2a}.xl\:hover\:to-orange-100:hover{--gradient-to-color:#fffaf0}.xl\:hover\:to-orange-200:hover{--gradient-to-color:#feebc8}.xl\:hover\:to-orange-300:hover{--gradient-to-color:#fbd38d}.xl\:hover\:to-orange-400:hover{--gradient-to-color:#f6ad55}.xl\:hover\:to-orange-500:hover{--gradient-to-color:#ed8936}.xl\:hover\:to-orange-600:hover{--gradient-to-color:#dd6b20}.xl\:hover\:to-orange-700:hover{--gradient-to-color:#c05621}.xl\:hover\:to-orange-800:hover{--gradient-to-color:#9c4221}.xl\:hover\:to-orange-900:hover{--gradient-to-color:#7b341e}.xl\:hover\:to-yellow-100:hover{--gradient-to-color:#fffff0}.xl\:hover\:to-yellow-200:hover{--gradient-to-color:#fefcbf}.xl\:hover\:to-yellow-300:hover{--gradient-to-color:#faf089}.xl\:hover\:to-yellow-400:hover{--gradient-to-color:#f6e05e}.xl\:hover\:to-yellow-500:hover{--gradient-to-color:#ecc94b}.xl\:hover\:to-yellow-600:hover{--gradient-to-color:#d69e2e}.xl\:hover\:to-yellow-700:hover{--gradient-to-color:#b7791f}.xl\:hover\:to-yellow-800:hover{--gradient-to-color:#975a16}.xl\:hover\:to-yellow-900:hover{--gradient-to-color:#744210}.xl\:hover\:to-green-100:hover{--gradient-to-color:#f0fff4}.xl\:hover\:to-green-200:hover{--gradient-to-color:#c6f6d5}.xl\:hover\:to-green-300:hover{--gradient-to-color:#9ae6b4}.xl\:hover\:to-green-400:hover{--gradient-to-color:#68d391}.xl\:hover\:to-green-500:hover{--gradient-to-color:#48bb78}.xl\:hover\:to-green-600:hover{--gradient-to-color:#38a169}.xl\:hover\:to-green-700:hover{--gradient-to-color:#2f855a}.xl\:hover\:to-green-800:hover{--gradient-to-color:#276749}.xl\:hover\:to-green-900:hover{--gradient-to-color:#22543d}.xl\:hover\:to-teal-100:hover{--gradient-to-color:#e6fffa}.xl\:hover\:to-teal-200:hover{--gradient-to-color:#b2f5ea}.xl\:hover\:to-teal-300:hover{--gradient-to-color:#81e6d9}.xl\:hover\:to-teal-400:hover{--gradient-to-color:#4fd1c5}.xl\:hover\:to-teal-500:hover{--gradient-to-color:#38b2ac}.xl\:hover\:to-teal-600:hover{--gradient-to-color:#319795}.xl\:hover\:to-teal-700:hover{--gradient-to-color:#2c7a7b}.xl\:hover\:to-teal-800:hover{--gradient-to-color:#285e61}.xl\:hover\:to-teal-900:hover{--gradient-to-color:#234e52}.xl\:hover\:to-blue-100:hover{--gradient-to-color:#ebf8ff}.xl\:hover\:to-blue-200:hover{--gradient-to-color:#bee3f8}.xl\:hover\:to-blue-300:hover{--gradient-to-color:#90cdf4}.xl\:hover\:to-blue-400:hover{--gradient-to-color:#63b3ed}.xl\:hover\:to-blue-500:hover{--gradient-to-color:#4299e1}.xl\:hover\:to-blue-600:hover{--gradient-to-color:#3182ce}.xl\:hover\:to-blue-700:hover{--gradient-to-color:#2b6cb0}.xl\:hover\:to-blue-800:hover{--gradient-to-color:#2c5282}.xl\:hover\:to-blue-900:hover{--gradient-to-color:#2a4365}.xl\:hover\:to-indigo-100:hover{--gradient-to-color:#ebf4ff}.xl\:hover\:to-indigo-200:hover{--gradient-to-color:#c3dafe}.xl\:hover\:to-indigo-300:hover{--gradient-to-color:#a3bffa}.xl\:hover\:to-indigo-400:hover{--gradient-to-color:#7f9cf5}.xl\:hover\:to-indigo-500:hover{--gradient-to-color:#667eea}.xl\:hover\:to-indigo-600:hover{--gradient-to-color:#5a67d8}.xl\:hover\:to-indigo-700:hover{--gradient-to-color:#4c51bf}.xl\:hover\:to-indigo-800:hover{--gradient-to-color:#434190}.xl\:hover\:to-indigo-900:hover{--gradient-to-color:#3c366b}.xl\:hover\:to-purple-100:hover{--gradient-to-color:#faf5ff}.xl\:hover\:to-purple-200:hover{--gradient-to-color:#e9d8fd}.xl\:hover\:to-purple-300:hover{--gradient-to-color:#d6bcfa}.xl\:hover\:to-purple-400:hover{--gradient-to-color:#b794f4}.xl\:hover\:to-purple-500:hover{--gradient-to-color:#9f7aea}.xl\:hover\:to-purple-600:hover{--gradient-to-color:#805ad5}.xl\:hover\:to-purple-700:hover{--gradient-to-color:#6b46c1}.xl\:hover\:to-purple-800:hover{--gradient-to-color:#553c9a}.xl\:hover\:to-purple-900:hover{--gradient-to-color:#44337a}.xl\:hover\:to-pink-100:hover{--gradient-to-color:#fff5f7}.xl\:hover\:to-pink-200:hover{--gradient-to-color:#fed7e2}.xl\:hover\:to-pink-300:hover{--gradient-to-color:#fbb6ce}.xl\:hover\:to-pink-400:hover{--gradient-to-color:#f687b3}.xl\:hover\:to-pink-500:hover{--gradient-to-color:#ed64a6}.xl\:hover\:to-pink-600:hover{--gradient-to-color:#d53f8c}.xl\:hover\:to-pink-700:hover{--gradient-to-color:#b83280}.xl\:hover\:to-pink-800:hover{--gradient-to-color:#97266d}.xl\:hover\:to-pink-900:hover{--gradient-to-color:#702459}.xl\:focus\:from-transparent:focus{--gradient-from-color:transparent;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(0, 0, 0, 0))}.xl\:focus\:from-current:focus{--gradient-from-color:currentColor;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 255, 255, 0))}.xl\:focus\:from-black:focus{--gradient-from-color:#000;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(0, 0, 0, 0))}.xl\:focus\:from-white:focus{--gradient-from-color:#fff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 255, 255, 0))}.xl\:focus\:from-gray-100:focus{--gradient-from-color:#f7fafc;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(247, 250, 252, 0))}.xl\:focus\:from-gray-200:focus{--gradient-from-color:#edf2f7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(237, 242, 247, 0))}.xl\:focus\:from-gray-300:focus{--gradient-from-color:#e2e8f0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(226, 232, 240, 0))}.xl\:focus\:from-gray-400:focus{--gradient-from-color:#cbd5e0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(203, 213, 224, 0))}.xl\:focus\:from-gray-500:focus{--gradient-from-color:#a0aec0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(160, 174, 192, 0))}.xl\:focus\:from-gray-600:focus{--gradient-from-color:#718096;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(113, 128, 150, 0))}.xl\:focus\:from-gray-700:focus{--gradient-from-color:#4a5568;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(74, 85, 104, 0))}.xl\:focus\:from-gray-800:focus{--gradient-from-color:#2d3748;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(45, 55, 72, 0))}.xl\:focus\:from-gray-900:focus{--gradient-from-color:#1a202c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(26, 32, 44, 0))}.xl\:focus\:from-red-100:focus{--gradient-from-color:#fff5f5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 245, 245, 0))}.xl\:focus\:from-red-200:focus{--gradient-from-color:#fed7d7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(254, 215, 215, 0))}.xl\:focus\:from-red-300:focus{--gradient-from-color:#feb2b2;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(254, 178, 178, 0))}.xl\:focus\:from-red-400:focus{--gradient-from-color:#fc8181;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(252, 129, 129, 0))}.xl\:focus\:from-red-500:focus{--gradient-from-color:#f56565;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(245, 101, 101, 0))}.xl\:focus\:from-red-600:focus{--gradient-from-color:#e53e3e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(229, 62, 62, 0))}.xl\:focus\:from-red-700:focus{--gradient-from-color:#c53030;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(197, 48, 48, 0))}.xl\:focus\:from-red-800:focus{--gradient-from-color:#9b2c2c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(155, 44, 44, 0))}.xl\:focus\:from-red-900:focus{--gradient-from-color:#742a2a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(116, 42, 42, 0))}.xl\:focus\:from-orange-100:focus{--gradient-from-color:#fffaf0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 250, 240, 0))}.xl\:focus\:from-orange-200:focus{--gradient-from-color:#feebc8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(254, 235, 200, 0))}.xl\:focus\:from-orange-300:focus{--gradient-from-color:#fbd38d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(251, 211, 141, 0))}.xl\:focus\:from-orange-400:focus{--gradient-from-color:#f6ad55;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(246, 173, 85, 0))}.xl\:focus\:from-orange-500:focus{--gradient-from-color:#ed8936;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(237, 137, 54, 0))}.xl\:focus\:from-orange-600:focus{--gradient-from-color:#dd6b20;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(221, 107, 32, 0))}.xl\:focus\:from-orange-700:focus{--gradient-from-color:#c05621;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(192, 86, 33, 0))}.xl\:focus\:from-orange-800:focus{--gradient-from-color:#9c4221;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(156, 66, 33, 0))}.xl\:focus\:from-orange-900:focus{--gradient-from-color:#7b341e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(123, 52, 30, 0))}.xl\:focus\:from-yellow-100:focus{--gradient-from-color:#fffff0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 255, 240, 0))}.xl\:focus\:from-yellow-200:focus{--gradient-from-color:#fefcbf;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(254, 252, 191, 0))}.xl\:focus\:from-yellow-300:focus{--gradient-from-color:#faf089;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(250, 240, 137, 0))}.xl\:focus\:from-yellow-400:focus{--gradient-from-color:#f6e05e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(246, 224, 94, 0))}.xl\:focus\:from-yellow-500:focus{--gradient-from-color:#ecc94b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(236, 201, 75, 0))}.xl\:focus\:from-yellow-600:focus{--gradient-from-color:#d69e2e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(214, 158, 46, 0))}.xl\:focus\:from-yellow-700:focus{--gradient-from-color:#b7791f;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(183, 121, 31, 0))}.xl\:focus\:from-yellow-800:focus{--gradient-from-color:#975a16;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(151, 90, 22, 0))}.xl\:focus\:from-yellow-900:focus{--gradient-from-color:#744210;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(116, 66, 16, 0))}.xl\:focus\:from-green-100:focus{--gradient-from-color:#f0fff4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(240, 255, 244, 0))}.xl\:focus\:from-green-200:focus{--gradient-from-color:#c6f6d5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(198, 246, 213, 0))}.xl\:focus\:from-green-300:focus{--gradient-from-color:#9ae6b4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(154, 230, 180, 0))}.xl\:focus\:from-green-400:focus{--gradient-from-color:#68d391;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(104, 211, 145, 0))}.xl\:focus\:from-green-500:focus{--gradient-from-color:#48bb78;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(72, 187, 120, 0))}.xl\:focus\:from-green-600:focus{--gradient-from-color:#38a169;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(56, 161, 105, 0))}.xl\:focus\:from-green-700:focus{--gradient-from-color:#2f855a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(47, 133, 90, 0))}.xl\:focus\:from-green-800:focus{--gradient-from-color:#276749;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(39, 103, 73, 0))}.xl\:focus\:from-green-900:focus{--gradient-from-color:#22543d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(34, 84, 61, 0))}.xl\:focus\:from-teal-100:focus{--gradient-from-color:#e6fffa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(230, 255, 250, 0))}.xl\:focus\:from-teal-200:focus{--gradient-from-color:#b2f5ea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(178, 245, 234, 0))}.xl\:focus\:from-teal-300:focus{--gradient-from-color:#81e6d9;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(129, 230, 217, 0))}.xl\:focus\:from-teal-400:focus{--gradient-from-color:#4fd1c5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(79, 209, 197, 0))}.xl\:focus\:from-teal-500:focus{--gradient-from-color:#38b2ac;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(56, 178, 172, 0))}.xl\:focus\:from-teal-600:focus{--gradient-from-color:#319795;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(49, 151, 149, 0))}.xl\:focus\:from-teal-700:focus{--gradient-from-color:#2c7a7b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(44, 122, 123, 0))}.xl\:focus\:from-teal-800:focus{--gradient-from-color:#285e61;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(40, 94, 97, 0))}.xl\:focus\:from-teal-900:focus{--gradient-from-color:#234e52;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(35, 78, 82, 0))}.xl\:focus\:from-blue-100:focus{--gradient-from-color:#ebf8ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(235, 248, 255, 0))}.xl\:focus\:from-blue-200:focus{--gradient-from-color:#bee3f8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(190, 227, 248, 0))}.xl\:focus\:from-blue-300:focus{--gradient-from-color:#90cdf4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(144, 205, 244, 0))}.xl\:focus\:from-blue-400:focus{--gradient-from-color:#63b3ed;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(99, 179, 237, 0))}.xl\:focus\:from-blue-500:focus{--gradient-from-color:#4299e1;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(66, 153, 225, 0))}.xl\:focus\:from-blue-600:focus{--gradient-from-color:#3182ce;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(49, 130, 206, 0))}.xl\:focus\:from-blue-700:focus{--gradient-from-color:#2b6cb0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(43, 108, 176, 0))}.xl\:focus\:from-blue-800:focus{--gradient-from-color:#2c5282;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(44, 82, 130, 0))}.xl\:focus\:from-blue-900:focus{--gradient-from-color:#2a4365;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(42, 67, 101, 0))}.xl\:focus\:from-indigo-100:focus{--gradient-from-color:#ebf4ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(235, 244, 255, 0))}.xl\:focus\:from-indigo-200:focus{--gradient-from-color:#c3dafe;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(195, 218, 254, 0))}.xl\:focus\:from-indigo-300:focus{--gradient-from-color:#a3bffa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(163, 191, 250, 0))}.xl\:focus\:from-indigo-400:focus{--gradient-from-color:#7f9cf5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(127, 156, 245, 0))}.xl\:focus\:from-indigo-500:focus{--gradient-from-color:#667eea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(102, 126, 234, 0))}.xl\:focus\:from-indigo-600:focus{--gradient-from-color:#5a67d8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(90, 103, 216, 0))}.xl\:focus\:from-indigo-700:focus{--gradient-from-color:#4c51bf;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(76, 81, 191, 0))}.xl\:focus\:from-indigo-800:focus{--gradient-from-color:#434190;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(67, 65, 144, 0))}.xl\:focus\:from-indigo-900:focus{--gradient-from-color:#3c366b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(60, 54, 107, 0))}.xl\:focus\:from-purple-100:focus{--gradient-from-color:#faf5ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(250, 245, 255, 0))}.xl\:focus\:from-purple-200:focus{--gradient-from-color:#e9d8fd;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(233, 216, 253, 0))}.xl\:focus\:from-purple-300:focus{--gradient-from-color:#d6bcfa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(214, 188, 250, 0))}.xl\:focus\:from-purple-400:focus{--gradient-from-color:#b794f4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(183, 148, 244, 0))}.xl\:focus\:from-purple-500:focus{--gradient-from-color:#9f7aea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(159, 122, 234, 0))}.xl\:focus\:from-purple-600:focus{--gradient-from-color:#805ad5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(128, 90, 213, 0))}.xl\:focus\:from-purple-700:focus{--gradient-from-color:#6b46c1;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(107, 70, 193, 0))}.xl\:focus\:from-purple-800:focus{--gradient-from-color:#553c9a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(85, 60, 154, 0))}.xl\:focus\:from-purple-900:focus{--gradient-from-color:#44337a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(68, 51, 122, 0))}.xl\:focus\:from-pink-100:focus{--gradient-from-color:#fff5f7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(255, 245, 247, 0))}.xl\:focus\:from-pink-200:focus{--gradient-from-color:#fed7e2;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(254, 215, 226, 0))}.xl\:focus\:from-pink-300:focus{--gradient-from-color:#fbb6ce;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(251, 182, 206, 0))}.xl\:focus\:from-pink-400:focus{--gradient-from-color:#f687b3;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(246, 135, 179, 0))}.xl\:focus\:from-pink-500:focus{--gradient-from-color:#ed64a6;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(237, 100, 166, 0))}.xl\:focus\:from-pink-600:focus{--gradient-from-color:#d53f8c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(213, 63, 140, 0))}.xl\:focus\:from-pink-700:focus{--gradient-from-color:#b83280;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(184, 50, 128, 0))}.xl\:focus\:from-pink-800:focus{--gradient-from-color:#97266d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(151, 38, 109, 0))}.xl\:focus\:from-pink-900:focus{--gradient-from-color:#702459;--gradient-color-stops:var(--gradient-from-color),var(--gradient-to-color, rgba(112, 36, 89, 0))}.xl\:focus\:via-transparent:focus{--gradient-via-color:transparent;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(0, 0, 0, 0))}.xl\:focus\:via-current:focus{--gradient-via-color:currentColor;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 255, 255, 0))}.xl\:focus\:via-black:focus{--gradient-via-color:#000;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(0, 0, 0, 0))}.xl\:focus\:via-white:focus{--gradient-via-color:#fff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 255, 255, 0))}.xl\:focus\:via-gray-100:focus{--gradient-via-color:#f7fafc;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(247, 250, 252, 0))}.xl\:focus\:via-gray-200:focus{--gradient-via-color:#edf2f7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(237, 242, 247, 0))}.xl\:focus\:via-gray-300:focus{--gradient-via-color:#e2e8f0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(226, 232, 240, 0))}.xl\:focus\:via-gray-400:focus{--gradient-via-color:#cbd5e0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(203, 213, 224, 0))}.xl\:focus\:via-gray-500:focus{--gradient-via-color:#a0aec0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(160, 174, 192, 0))}.xl\:focus\:via-gray-600:focus{--gradient-via-color:#718096;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(113, 128, 150, 0))}.xl\:focus\:via-gray-700:focus{--gradient-via-color:#4a5568;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(74, 85, 104, 0))}.xl\:focus\:via-gray-800:focus{--gradient-via-color:#2d3748;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(45, 55, 72, 0))}.xl\:focus\:via-gray-900:focus{--gradient-via-color:#1a202c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(26, 32, 44, 0))}.xl\:focus\:via-red-100:focus{--gradient-via-color:#fff5f5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 245, 245, 0))}.xl\:focus\:via-red-200:focus{--gradient-via-color:#fed7d7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(254, 215, 215, 0))}.xl\:focus\:via-red-300:focus{--gradient-via-color:#feb2b2;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(254, 178, 178, 0))}.xl\:focus\:via-red-400:focus{--gradient-via-color:#fc8181;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(252, 129, 129, 0))}.xl\:focus\:via-red-500:focus{--gradient-via-color:#f56565;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(245, 101, 101, 0))}.xl\:focus\:via-red-600:focus{--gradient-via-color:#e53e3e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(229, 62, 62, 0))}.xl\:focus\:via-red-700:focus{--gradient-via-color:#c53030;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(197, 48, 48, 0))}.xl\:focus\:via-red-800:focus{--gradient-via-color:#9b2c2c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(155, 44, 44, 0))}.xl\:focus\:via-red-900:focus{--gradient-via-color:#742a2a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(116, 42, 42, 0))}.xl\:focus\:via-orange-100:focus{--gradient-via-color:#fffaf0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 250, 240, 0))}.xl\:focus\:via-orange-200:focus{--gradient-via-color:#feebc8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(254, 235, 200, 0))}.xl\:focus\:via-orange-300:focus{--gradient-via-color:#fbd38d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(251, 211, 141, 0))}.xl\:focus\:via-orange-400:focus{--gradient-via-color:#f6ad55;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(246, 173, 85, 0))}.xl\:focus\:via-orange-500:focus{--gradient-via-color:#ed8936;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(237, 137, 54, 0))}.xl\:focus\:via-orange-600:focus{--gradient-via-color:#dd6b20;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(221, 107, 32, 0))}.xl\:focus\:via-orange-700:focus{--gradient-via-color:#c05621;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(192, 86, 33, 0))}.xl\:focus\:via-orange-800:focus{--gradient-via-color:#9c4221;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(156, 66, 33, 0))}.xl\:focus\:via-orange-900:focus{--gradient-via-color:#7b341e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(123, 52, 30, 0))}.xl\:focus\:via-yellow-100:focus{--gradient-via-color:#fffff0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 255, 240, 0))}.xl\:focus\:via-yellow-200:focus{--gradient-via-color:#fefcbf;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(254, 252, 191, 0))}.xl\:focus\:via-yellow-300:focus{--gradient-via-color:#faf089;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(250, 240, 137, 0))}.xl\:focus\:via-yellow-400:focus{--gradient-via-color:#f6e05e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(246, 224, 94, 0))}.xl\:focus\:via-yellow-500:focus{--gradient-via-color:#ecc94b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(236, 201, 75, 0))}.xl\:focus\:via-yellow-600:focus{--gradient-via-color:#d69e2e;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(214, 158, 46, 0))}.xl\:focus\:via-yellow-700:focus{--gradient-via-color:#b7791f;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(183, 121, 31, 0))}.xl\:focus\:via-yellow-800:focus{--gradient-via-color:#975a16;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(151, 90, 22, 0))}.xl\:focus\:via-yellow-900:focus{--gradient-via-color:#744210;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(116, 66, 16, 0))}.xl\:focus\:via-green-100:focus{--gradient-via-color:#f0fff4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(240, 255, 244, 0))}.xl\:focus\:via-green-200:focus{--gradient-via-color:#c6f6d5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(198, 246, 213, 0))}.xl\:focus\:via-green-300:focus{--gradient-via-color:#9ae6b4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(154, 230, 180, 0))}.xl\:focus\:via-green-400:focus{--gradient-via-color:#68d391;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(104, 211, 145, 0))}.xl\:focus\:via-green-500:focus{--gradient-via-color:#48bb78;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(72, 187, 120, 0))}.xl\:focus\:via-green-600:focus{--gradient-via-color:#38a169;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(56, 161, 105, 0))}.xl\:focus\:via-green-700:focus{--gradient-via-color:#2f855a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(47, 133, 90, 0))}.xl\:focus\:via-green-800:focus{--gradient-via-color:#276749;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(39, 103, 73, 0))}.xl\:focus\:via-green-900:focus{--gradient-via-color:#22543d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(34, 84, 61, 0))}.xl\:focus\:via-teal-100:focus{--gradient-via-color:#e6fffa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(230, 255, 250, 0))}.xl\:focus\:via-teal-200:focus{--gradient-via-color:#b2f5ea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(178, 245, 234, 0))}.xl\:focus\:via-teal-300:focus{--gradient-via-color:#81e6d9;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(129, 230, 217, 0))}.xl\:focus\:via-teal-400:focus{--gradient-via-color:#4fd1c5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(79, 209, 197, 0))}.xl\:focus\:via-teal-500:focus{--gradient-via-color:#38b2ac;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(56, 178, 172, 0))}.xl\:focus\:via-teal-600:focus{--gradient-via-color:#319795;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(49, 151, 149, 0))}.xl\:focus\:via-teal-700:focus{--gradient-via-color:#2c7a7b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(44, 122, 123, 0))}.xl\:focus\:via-teal-800:focus{--gradient-via-color:#285e61;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(40, 94, 97, 0))}.xl\:focus\:via-teal-900:focus{--gradient-via-color:#234e52;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(35, 78, 82, 0))}.xl\:focus\:via-blue-100:focus{--gradient-via-color:#ebf8ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(235, 248, 255, 0))}.xl\:focus\:via-blue-200:focus{--gradient-via-color:#bee3f8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(190, 227, 248, 0))}.xl\:focus\:via-blue-300:focus{--gradient-via-color:#90cdf4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(144, 205, 244, 0))}.xl\:focus\:via-blue-400:focus{--gradient-via-color:#63b3ed;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(99, 179, 237, 0))}.xl\:focus\:via-blue-500:focus{--gradient-via-color:#4299e1;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(66, 153, 225, 0))}.xl\:focus\:via-blue-600:focus{--gradient-via-color:#3182ce;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(49, 130, 206, 0))}.xl\:focus\:via-blue-700:focus{--gradient-via-color:#2b6cb0;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(43, 108, 176, 0))}.xl\:focus\:via-blue-800:focus{--gradient-via-color:#2c5282;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(44, 82, 130, 0))}.xl\:focus\:via-blue-900:focus{--gradient-via-color:#2a4365;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(42, 67, 101, 0))}.xl\:focus\:via-indigo-100:focus{--gradient-via-color:#ebf4ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(235, 244, 255, 0))}.xl\:focus\:via-indigo-200:focus{--gradient-via-color:#c3dafe;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(195, 218, 254, 0))}.xl\:focus\:via-indigo-300:focus{--gradient-via-color:#a3bffa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(163, 191, 250, 0))}.xl\:focus\:via-indigo-400:focus{--gradient-via-color:#7f9cf5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(127, 156, 245, 0))}.xl\:focus\:via-indigo-500:focus{--gradient-via-color:#667eea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(102, 126, 234, 0))}.xl\:focus\:via-indigo-600:focus{--gradient-via-color:#5a67d8;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(90, 103, 216, 0))}.xl\:focus\:via-indigo-700:focus{--gradient-via-color:#4c51bf;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(76, 81, 191, 0))}.xl\:focus\:via-indigo-800:focus{--gradient-via-color:#434190;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(67, 65, 144, 0))}.xl\:focus\:via-indigo-900:focus{--gradient-via-color:#3c366b;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(60, 54, 107, 0))}.xl\:focus\:via-purple-100:focus{--gradient-via-color:#faf5ff;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(250, 245, 255, 0))}.xl\:focus\:via-purple-200:focus{--gradient-via-color:#e9d8fd;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(233, 216, 253, 0))}.xl\:focus\:via-purple-300:focus{--gradient-via-color:#d6bcfa;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(214, 188, 250, 0))}.xl\:focus\:via-purple-400:focus{--gradient-via-color:#b794f4;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(183, 148, 244, 0))}.xl\:focus\:via-purple-500:focus{--gradient-via-color:#9f7aea;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(159, 122, 234, 0))}.xl\:focus\:via-purple-600:focus{--gradient-via-color:#805ad5;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(128, 90, 213, 0))}.xl\:focus\:via-purple-700:focus{--gradient-via-color:#6b46c1;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(107, 70, 193, 0))}.xl\:focus\:via-purple-800:focus{--gradient-via-color:#553c9a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(85, 60, 154, 0))}.xl\:focus\:via-purple-900:focus{--gradient-via-color:#44337a;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(68, 51, 122, 0))}.xl\:focus\:via-pink-100:focus{--gradient-via-color:#fff5f7;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(255, 245, 247, 0))}.xl\:focus\:via-pink-200:focus{--gradient-via-color:#fed7e2;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(254, 215, 226, 0))}.xl\:focus\:via-pink-300:focus{--gradient-via-color:#fbb6ce;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(251, 182, 206, 0))}.xl\:focus\:via-pink-400:focus{--gradient-via-color:#f687b3;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(246, 135, 179, 0))}.xl\:focus\:via-pink-500:focus{--gradient-via-color:#ed64a6;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(237, 100, 166, 0))}.xl\:focus\:via-pink-600:focus{--gradient-via-color:#d53f8c;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(213, 63, 140, 0))}.xl\:focus\:via-pink-700:focus{--gradient-via-color:#b83280;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(184, 50, 128, 0))}.xl\:focus\:via-pink-800:focus{--gradient-via-color:#97266d;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(151, 38, 109, 0))}.xl\:focus\:via-pink-900:focus{--gradient-via-color:#702459;--gradient-color-stops:var(--gradient-from-color),var(--gradient-via-color),var(--gradient-to-color, rgba(112, 36, 89, 0))}.xl\:focus\:to-transparent:focus{--gradient-to-color:transparent}.xl\:focus\:to-current:focus{--gradient-to-color:currentColor}.xl\:focus\:to-black:focus{--gradient-to-color:#000}.xl\:focus\:to-white:focus{--gradient-to-color:#fff}.xl\:focus\:to-gray-100:focus{--gradient-to-color:#f7fafc}.xl\:focus\:to-gray-200:focus{--gradient-to-color:#edf2f7}.xl\:focus\:to-gray-300:focus{--gradient-to-color:#e2e8f0}.xl\:focus\:to-gray-400:focus{--gradient-to-color:#cbd5e0}.xl\:focus\:to-gray-500:focus{--gradient-to-color:#a0aec0}.xl\:focus\:to-gray-600:focus{--gradient-to-color:#718096}.xl\:focus\:to-gray-700:focus{--gradient-to-color:#4a5568}.xl\:focus\:to-gray-800:focus{--gradient-to-color:#2d3748}.xl\:focus\:to-gray-900:focus{--gradient-to-color:#1a202c}.xl\:focus\:to-red-100:focus{--gradient-to-color:#fff5f5}.xl\:focus\:to-red-200:focus{--gradient-to-color:#fed7d7}.xl\:focus\:to-red-300:focus{--gradient-to-color:#feb2b2}.xl\:focus\:to-red-400:focus{--gradient-to-color:#fc8181}.xl\:focus\:to-red-500:focus{--gradient-to-color:#f56565}.xl\:focus\:to-red-600:focus{--gradient-to-color:#e53e3e}.xl\:focus\:to-red-700:focus{--gradient-to-color:#c53030}.xl\:focus\:to-red-800:focus{--gradient-to-color:#9b2c2c}.xl\:focus\:to-red-900:focus{--gradient-to-color:#742a2a}.xl\:focus\:to-orange-100:focus{--gradient-to-color:#fffaf0}.xl\:focus\:to-orange-200:focus{--gradient-to-color:#feebc8}.xl\:focus\:to-orange-300:focus{--gradient-to-color:#fbd38d}.xl\:focus\:to-orange-400:focus{--gradient-to-color:#f6ad55}.xl\:focus\:to-orange-500:focus{--gradient-to-color:#ed8936}.xl\:focus\:to-orange-600:focus{--gradient-to-color:#dd6b20}.xl\:focus\:to-orange-700:focus{--gradient-to-color:#c05621}.xl\:focus\:to-orange-800:focus{--gradient-to-color:#9c4221}.xl\:focus\:to-orange-900:focus{--gradient-to-color:#7b341e}.xl\:focus\:to-yellow-100:focus{--gradient-to-color:#fffff0}.xl\:focus\:to-yellow-200:focus{--gradient-to-color:#fefcbf}.xl\:focus\:to-yellow-300:focus{--gradient-to-color:#faf089}.xl\:focus\:to-yellow-400:focus{--gradient-to-color:#f6e05e}.xl\:focus\:to-yellow-500:focus{--gradient-to-color:#ecc94b}.xl\:focus\:to-yellow-600:focus{--gradient-to-color:#d69e2e}.xl\:focus\:to-yellow-700:focus{--gradient-to-color:#b7791f}.xl\:focus\:to-yellow-800:focus{--gradient-to-color:#975a16}.xl\:focus\:to-yellow-900:focus{--gradient-to-color:#744210}.xl\:focus\:to-green-100:focus{--gradient-to-color:#f0fff4}.xl\:focus\:to-green-200:focus{--gradient-to-color:#c6f6d5}.xl\:focus\:to-green-300:focus{--gradient-to-color:#9ae6b4}.xl\:focus\:to-green-400:focus{--gradient-to-color:#68d391}.xl\:focus\:to-green-500:focus{--gradient-to-color:#48bb78}.xl\:focus\:to-green-600:focus{--gradient-to-color:#38a169}.xl\:focus\:to-green-700:focus{--gradient-to-color:#2f855a}.xl\:focus\:to-green-800:focus{--gradient-to-color:#276749}.xl\:focus\:to-green-900:focus{--gradient-to-color:#22543d}.xl\:focus\:to-teal-100:focus{--gradient-to-color:#e6fffa}.xl\:focus\:to-teal-200:focus{--gradient-to-color:#b2f5ea}.xl\:focus\:to-teal-300:focus{--gradient-to-color:#81e6d9}.xl\:focus\:to-teal-400:focus{--gradient-to-color:#4fd1c5}.xl\:focus\:to-teal-500:focus{--gradient-to-color:#38b2ac}.xl\:focus\:to-teal-600:focus{--gradient-to-color:#319795}.xl\:focus\:to-teal-700:focus{--gradient-to-color:#2c7a7b}.xl\:focus\:to-teal-800:focus{--gradient-to-color:#285e61}.xl\:focus\:to-teal-900:focus{--gradient-to-color:#234e52}.xl\:focus\:to-blue-100:focus{--gradient-to-color:#ebf8ff}.xl\:focus\:to-blue-200:focus{--gradient-to-color:#bee3f8}.xl\:focus\:to-blue-300:focus{--gradient-to-color:#90cdf4}.xl\:focus\:to-blue-400:focus{--gradient-to-color:#63b3ed}.xl\:focus\:to-blue-500:focus{--gradient-to-color:#4299e1}.xl\:focus\:to-blue-600:focus{--gradient-to-color:#3182ce}.xl\:focus\:to-blue-700:focus{--gradient-to-color:#2b6cb0}.xl\:focus\:to-blue-800:focus{--gradient-to-color:#2c5282}.xl\:focus\:to-blue-900:focus{--gradient-to-color:#2a4365}.xl\:focus\:to-indigo-100:focus{--gradient-to-color:#ebf4ff}.xl\:focus\:to-indigo-200:focus{--gradient-to-color:#c3dafe}.xl\:focus\:to-indigo-300:focus{--gradient-to-color:#a3bffa}.xl\:focus\:to-indigo-400:focus{--gradient-to-color:#7f9cf5}.xl\:focus\:to-indigo-500:focus{--gradient-to-color:#667eea}.xl\:focus\:to-indigo-600:focus{--gradient-to-color:#5a67d8}.xl\:focus\:to-indigo-700:focus{--gradient-to-color:#4c51bf}.xl\:focus\:to-indigo-800:focus{--gradient-to-color:#434190}.xl\:focus\:to-indigo-900:focus{--gradient-to-color:#3c366b}.xl\:focus\:to-purple-100:focus{--gradient-to-color:#faf5ff}.xl\:focus\:to-purple-200:focus{--gradient-to-color:#e9d8fd}.xl\:focus\:to-purple-300:focus{--gradient-to-color:#d6bcfa}.xl\:focus\:to-purple-400:focus{--gradient-to-color:#b794f4}.xl\:focus\:to-purple-500:focus{--gradient-to-color:#9f7aea}.xl\:focus\:to-purple-600:focus{--gradient-to-color:#805ad5}.xl\:focus\:to-purple-700:focus{--gradient-to-color:#6b46c1}.xl\:focus\:to-purple-800:focus{--gradient-to-color:#553c9a}.xl\:focus\:to-purple-900:focus{--gradient-to-color:#44337a}.xl\:focus\:to-pink-100:focus{--gradient-to-color:#fff5f7}.xl\:focus\:to-pink-200:focus{--gradient-to-color:#fed7e2}.xl\:focus\:to-pink-300:focus{--gradient-to-color:#fbb6ce}.xl\:focus\:to-pink-400:focus{--gradient-to-color:#f687b3}.xl\:focus\:to-pink-500:focus{--gradient-to-color:#ed64a6}.xl\:focus\:to-pink-600:focus{--gradient-to-color:#d53f8c}.xl\:focus\:to-pink-700:focus{--gradient-to-color:#b83280}.xl\:focus\:to-pink-800:focus{--gradient-to-color:#97266d}.xl\:focus\:to-pink-900:focus{--gradient-to-color:#702459}.xl\:bg-opacity-0{--bg-opacity:0}.xl\:bg-opacity-25{--bg-opacity:0.25}.xl\:bg-opacity-50{--bg-opacity:0.5}.xl\:bg-opacity-75{--bg-opacity:0.75}.xl\:bg-opacity-100{--bg-opacity:1}.xl\:hover\:bg-opacity-0:hover{--bg-opacity:0}.xl\:hover\:bg-opacity-25:hover{--bg-opacity:0.25}.xl\:hover\:bg-opacity-50:hover{--bg-opacity:0.5}.xl\:hover\:bg-opacity-75:hover{--bg-opacity:0.75}.xl\:hover\:bg-opacity-100:hover{--bg-opacity:1}.xl\:focus\:bg-opacity-0:focus{--bg-opacity:0}.xl\:focus\:bg-opacity-25:focus{--bg-opacity:0.25}.xl\:focus\:bg-opacity-50:focus{--bg-opacity:0.5}.xl\:focus\:bg-opacity-75:focus{--bg-opacity:0.75}.xl\:focus\:bg-opacity-100:focus{--bg-opacity:1}.xl\:bg-bottom{background-position:bottom}.xl\:bg-center{background-position:center}.xl\:bg-left{background-position:left}.xl\:bg-left-bottom{background-position:left bottom}.xl\:bg-left-top{background-position:left top}.xl\:bg-right{background-position:right}.xl\:bg-right-bottom{background-position:right bottom}.xl\:bg-right-top{background-position:right top}.xl\:bg-top{background-position:top}.xl\:bg-repeat{background-repeat:repeat}.xl\:bg-no-repeat{background-repeat:no-repeat}.xl\:bg-repeat-x{background-repeat:repeat-x}.xl\:bg-repeat-y{background-repeat:repeat-y}.xl\:bg-repeat-round{background-repeat:round}.xl\:bg-repeat-space{background-repeat:space}.xl\:bg-auto{background-size:auto}.xl\:bg-cover{background-size:cover}.xl\:bg-contain{background-size:contain}.xl\:border-collapse{border-collapse:collapse}.xl\:border-separate{border-collapse:separate}.xl\:border-transparent{border-color:transparent}.xl\:border-current{border-color:currentColor}.xl\:border-black{--border-opacity:1;border-color:#000;border-color:rgba(0,0,0,var(--border-opacity))}.xl\:border-white{--border-opacity:1;border-color:#fff;border-color:rgba(255,255,255,var(--border-opacity))}.xl\:border-gray-100{--border-opacity:1;border-color:#f7fafc;border-color:rgba(247,250,252,var(--border-opacity))}.xl\:border-gray-200{--border-opacity:1;border-color:#edf2f7;border-color:rgba(237,242,247,var(--border-opacity))}.xl\:border-gray-300{--border-opacity:1;border-color:#e2e8f0;border-color:rgba(226,232,240,var(--border-opacity))}.xl\:border-gray-400{--border-opacity:1;border-color:#cbd5e0;border-color:rgba(203,213,224,var(--border-opacity))}.xl\:border-gray-500{--border-opacity:1;border-color:#a0aec0;border-color:rgba(160,174,192,var(--border-opacity))}.xl\:border-gray-600{--border-opacity:1;border-color:#718096;border-color:rgba(113,128,150,var(--border-opacity))}.xl\:border-gray-700{--border-opacity:1;border-color:#4a5568;border-color:rgba(74,85,104,var(--border-opacity))}.xl\:border-gray-800{--border-opacity:1;border-color:#2d3748;border-color:rgba(45,55,72,var(--border-opacity))}.xl\:border-gray-900{--border-opacity:1;border-color:#1a202c;border-color:rgba(26,32,44,var(--border-opacity))}.xl\:border-red-100{--border-opacity:1;border-color:#fff5f5;border-color:rgba(255,245,245,var(--border-opacity))}.xl\:border-red-200{--border-opacity:1;border-color:#fed7d7;border-color:rgba(254,215,215,var(--border-opacity))}.xl\:border-red-300{--border-opacity:1;border-color:#feb2b2;border-color:rgba(254,178,178,var(--border-opacity))}.xl\:border-red-400{--border-opacity:1;border-color:#fc8181;border-color:rgba(252,129,129,var(--border-opacity))}.xl\:border-red-500{--border-opacity:1;border-color:#f56565;border-color:rgba(245,101,101,var(--border-opacity))}.xl\:border-red-600{--border-opacity:1;border-color:#e53e3e;border-color:rgba(229,62,62,var(--border-opacity))}.xl\:border-red-700{--border-opacity:1;border-color:#c53030;border-color:rgba(197,48,48,var(--border-opacity))}.xl\:border-red-800{--border-opacity:1;border-color:#9b2c2c;border-color:rgba(155,44,44,var(--border-opacity))}.xl\:border-red-900{--border-opacity:1;border-color:#742a2a;border-color:rgba(116,42,42,var(--border-opacity))}.xl\:border-orange-100{--border-opacity:1;border-color:#fffaf0;border-color:rgba(255,250,240,var(--border-opacity))}.xl\:border-orange-200{--border-opacity:1;border-color:#feebc8;border-color:rgba(254,235,200,var(--border-opacity))}.xl\:border-orange-300{--border-opacity:1;border-color:#fbd38d;border-color:rgba(251,211,141,var(--border-opacity))}.xl\:border-orange-400{--border-opacity:1;border-color:#f6ad55;border-color:rgba(246,173,85,var(--border-opacity))}.xl\:border-orange-500{--border-opacity:1;border-color:#ed8936;border-color:rgba(237,137,54,var(--border-opacity))}.xl\:border-orange-600{--border-opacity:1;border-color:#dd6b20;border-color:rgba(221,107,32,var(--border-opacity))}.xl\:border-orange-700{--border-opacity:1;border-color:#c05621;border-color:rgba(192,86,33,var(--border-opacity))}.xl\:border-orange-800{--border-opacity:1;border-color:#9c4221;border-color:rgba(156,66,33,var(--border-opacity))}.xl\:border-orange-900{--border-opacity:1;border-color:#7b341e;border-color:rgba(123,52,30,var(--border-opacity))}.xl\:border-yellow-100{--border-opacity:1;border-color:ivory;border-color:rgba(255,255,240,var(--border-opacity))}.xl\:border-yellow-200{--border-opacity:1;border-color:#fefcbf;border-color:rgba(254,252,191,var(--border-opacity))}.xl\:border-yellow-300{--border-opacity:1;border-color:#faf089;border-color:rgba(250,240,137,var(--border-opacity))}.xl\:border-yellow-400{--border-opacity:1;border-color:#f6e05e;border-color:rgba(246,224,94,var(--border-opacity))}.xl\:border-yellow-500{--border-opacity:1;border-color:#ecc94b;border-color:rgba(236,201,75,var(--border-opacity))}.xl\:border-yellow-600{--border-opacity:1;border-color:#d69e2e;border-color:rgba(214,158,46,var(--border-opacity))}.xl\:border-yellow-700{--border-opacity:1;border-color:#b7791f;border-color:rgba(183,121,31,var(--border-opacity))}.xl\:border-yellow-800{--border-opacity:1;border-color:#975a16;border-color:rgba(151,90,22,var(--border-opacity))}.xl\:border-yellow-900{--border-opacity:1;border-color:#744210;border-color:rgba(116,66,16,var(--border-opacity))}.xl\:border-green-100{--border-opacity:1;border-color:#f0fff4;border-color:rgba(240,255,244,var(--border-opacity))}.xl\:border-green-200{--border-opacity:1;border-color:#c6f6d5;border-color:rgba(198,246,213,var(--border-opacity))}.xl\:border-green-300{--border-opacity:1;border-color:#9ae6b4;border-color:rgba(154,230,180,var(--border-opacity))}.xl\:border-green-400{--border-opacity:1;border-color:#68d391;border-color:rgba(104,211,145,var(--border-opacity))}.xl\:border-green-500{--border-opacity:1;border-color:#48bb78;border-color:rgba(72,187,120,var(--border-opacity))}.xl\:border-green-600{--border-opacity:1;border-color:#38a169;border-color:rgba(56,161,105,var(--border-opacity))}.xl\:border-green-700{--border-opacity:1;border-color:#2f855a;border-color:rgba(47,133,90,var(--border-opacity))}.xl\:border-green-800{--border-opacity:1;border-color:#276749;border-color:rgba(39,103,73,var(--border-opacity))}.xl\:border-green-900{--border-opacity:1;border-color:#22543d;border-color:rgba(34,84,61,var(--border-opacity))}.xl\:border-teal-100{--border-opacity:1;border-color:#e6fffa;border-color:rgba(230,255,250,var(--border-opacity))}.xl\:border-teal-200{--border-opacity:1;border-color:#b2f5ea;border-color:rgba(178,245,234,var(--border-opacity))}.xl\:border-teal-300{--border-opacity:1;border-color:#81e6d9;border-color:rgba(129,230,217,var(--border-opacity))}.xl\:border-teal-400{--border-opacity:1;border-color:#4fd1c5;border-color:rgba(79,209,197,var(--border-opacity))}.xl\:border-teal-500{--border-opacity:1;border-color:#38b2ac;border-color:rgba(56,178,172,var(--border-opacity))}.xl\:border-teal-600{--border-opacity:1;border-color:#319795;border-color:rgba(49,151,149,var(--border-opacity))}.xl\:border-teal-700{--border-opacity:1;border-color:#2c7a7b;border-color:rgba(44,122,123,var(--border-opacity))}.xl\:border-teal-800{--border-opacity:1;border-color:#285e61;border-color:rgba(40,94,97,var(--border-opacity))}.xl\:border-teal-900{--border-opacity:1;border-color:#234e52;border-color:rgba(35,78,82,var(--border-opacity))}.xl\:border-blue-100{--border-opacity:1;border-color:#ebf8ff;border-color:rgba(235,248,255,var(--border-opacity))}.xl\:border-blue-200{--border-opacity:1;border-color:#bee3f8;border-color:rgba(190,227,248,var(--border-opacity))}.xl\:border-blue-300{--border-opacity:1;border-color:#90cdf4;border-color:rgba(144,205,244,var(--border-opacity))}.xl\:border-blue-400{--border-opacity:1;border-color:#63b3ed;border-color:rgba(99,179,237,var(--border-opacity))}.xl\:border-blue-500{--border-opacity:1;border-color:#4299e1;border-color:rgba(66,153,225,var(--border-opacity))}.xl\:border-blue-600{--border-opacity:1;border-color:#3182ce;border-color:rgba(49,130,206,var(--border-opacity))}.xl\:border-blue-700{--border-opacity:1;border-color:#2b6cb0;border-color:rgba(43,108,176,var(--border-opacity))}.xl\:border-blue-800{--border-opacity:1;border-color:#2c5282;border-color:rgba(44,82,130,var(--border-opacity))}.xl\:border-blue-900{--border-opacity:1;border-color:#2a4365;border-color:rgba(42,67,101,var(--border-opacity))}.xl\:border-indigo-100{--border-opacity:1;border-color:#ebf4ff;border-color:rgba(235,244,255,var(--border-opacity))}.xl\:border-indigo-200{--border-opacity:1;border-color:#c3dafe;border-color:rgba(195,218,254,var(--border-opacity))}.xl\:border-indigo-300{--border-opacity:1;border-color:#a3bffa;border-color:rgba(163,191,250,var(--border-opacity))}.xl\:border-indigo-400{--border-opacity:1;border-color:#7f9cf5;border-color:rgba(127,156,245,var(--border-opacity))}.xl\:border-indigo-500{--border-opacity:1;border-color:#667eea;border-color:rgba(102,126,234,var(--border-opacity))}.xl\:border-indigo-600{--border-opacity:1;border-color:#5a67d8;border-color:rgba(90,103,216,var(--border-opacity))}.xl\:border-indigo-700{--border-opacity:1;border-color:#4c51bf;border-color:rgba(76,81,191,var(--border-opacity))}.xl\:border-indigo-800{--border-opacity:1;border-color:#434190;border-color:rgba(67,65,144,var(--border-opacity))}.xl\:border-indigo-900{--border-opacity:1;border-color:#3c366b;border-color:rgba(60,54,107,var(--border-opacity))}.xl\:border-purple-100{--border-opacity:1;border-color:#faf5ff;border-color:rgba(250,245,255,var(--border-opacity))}.xl\:border-purple-200{--border-opacity:1;border-color:#e9d8fd;border-color:rgba(233,216,253,var(--border-opacity))}.xl\:border-purple-300{--border-opacity:1;border-color:#d6bcfa;border-color:rgba(214,188,250,var(--border-opacity))}.xl\:border-purple-400{--border-opacity:1;border-color:#b794f4;border-color:rgba(183,148,244,var(--border-opacity))}.xl\:border-purple-500{--border-opacity:1;border-color:#9f7aea;border-color:rgba(159,122,234,var(--border-opacity))}.xl\:border-purple-600{--border-opacity:1;border-color:#805ad5;border-color:rgba(128,90,213,var(--border-opacity))}.xl\:border-purple-700{--border-opacity:1;border-color:#6b46c1;border-color:rgba(107,70,193,var(--border-opacity))}.xl\:border-purple-800{--border-opacity:1;border-color:#553c9a;border-color:rgba(85,60,154,var(--border-opacity))}.xl\:border-purple-900{--border-opacity:1;border-color:#44337a;border-color:rgba(68,51,122,var(--border-opacity))}.xl\:border-pink-100{--border-opacity:1;border-color:#fff5f7;border-color:rgba(255,245,247,var(--border-opacity))}.xl\:border-pink-200{--border-opacity:1;border-color:#fed7e2;border-color:rgba(254,215,226,var(--border-opacity))}.xl\:border-pink-300{--border-opacity:1;border-color:#fbb6ce;border-color:rgba(251,182,206,var(--border-opacity))}.xl\:border-pink-400{--border-opacity:1;border-color:#f687b3;border-color:rgba(246,135,179,var(--border-opacity))}.xl\:border-pink-500{--border-opacity:1;border-color:#ed64a6;border-color:rgba(237,100,166,var(--border-opacity))}.xl\:border-pink-600{--border-opacity:1;border-color:#d53f8c;border-color:rgba(213,63,140,var(--border-opacity))}.xl\:border-pink-700{--border-opacity:1;border-color:#b83280;border-color:rgba(184,50,128,var(--border-opacity))}.xl\:border-pink-800{--border-opacity:1;border-color:#97266d;border-color:rgba(151,38,109,var(--border-opacity))}.xl\:border-pink-900{--border-opacity:1;border-color:#702459;border-color:rgba(112,36,89,var(--border-opacity))}.xl\:hover\:border-transparent:hover{border-color:transparent}.xl\:hover\:border-current:hover{border-color:currentColor}.xl\:hover\:border-black:hover{--border-opacity:1;border-color:#000;border-color:rgba(0,0,0,var(--border-opacity))}.xl\:hover\:border-white:hover{--border-opacity:1;border-color:#fff;border-color:rgba(255,255,255,var(--border-opacity))}.xl\:hover\:border-gray-100:hover{--border-opacity:1;border-color:#f7fafc;border-color:rgba(247,250,252,var(--border-opacity))}.xl\:hover\:border-gray-200:hover{--border-opacity:1;border-color:#edf2f7;border-color:rgba(237,242,247,var(--border-opacity))}.xl\:hover\:border-gray-300:hover{--border-opacity:1;border-color:#e2e8f0;border-color:rgba(226,232,240,var(--border-opacity))}.xl\:hover\:border-gray-400:hover{--border-opacity:1;border-color:#cbd5e0;border-color:rgba(203,213,224,var(--border-opacity))}.xl\:hover\:border-gray-500:hover{--border-opacity:1;border-color:#a0aec0;border-color:rgba(160,174,192,var(--border-opacity))}.xl\:hover\:border-gray-600:hover{--border-opacity:1;border-color:#718096;border-color:rgba(113,128,150,var(--border-opacity))}.xl\:hover\:border-gray-700:hover{--border-opacity:1;border-color:#4a5568;border-color:rgba(74,85,104,var(--border-opacity))}.xl\:hover\:border-gray-800:hover{--border-opacity:1;border-color:#2d3748;border-color:rgba(45,55,72,var(--border-opacity))}.xl\:hover\:border-gray-900:hover{--border-opacity:1;border-color:#1a202c;border-color:rgba(26,32,44,var(--border-opacity))}.xl\:hover\:border-red-100:hover{--border-opacity:1;border-color:#fff5f5;border-color:rgba(255,245,245,var(--border-opacity))}.xl\:hover\:border-red-200:hover{--border-opacity:1;border-color:#fed7d7;border-color:rgba(254,215,215,var(--border-opacity))}.xl\:hover\:border-red-300:hover{--border-opacity:1;border-color:#feb2b2;border-color:rgba(254,178,178,var(--border-opacity))}.xl\:hover\:border-red-400:hover{--border-opacity:1;border-color:#fc8181;border-color:rgba(252,129,129,var(--border-opacity))}.xl\:hover\:border-red-500:hover{--border-opacity:1;border-color:#f56565;border-color:rgba(245,101,101,var(--border-opacity))}.xl\:hover\:border-red-600:hover{--border-opacity:1;border-color:#e53e3e;border-color:rgba(229,62,62,var(--border-opacity))}.xl\:hover\:border-red-700:hover{--border-opacity:1;border-color:#c53030;border-color:rgba(197,48,48,var(--border-opacity))}.xl\:hover\:border-red-800:hover{--border-opacity:1;border-color:#9b2c2c;border-color:rgba(155,44,44,var(--border-opacity))}.xl\:hover\:border-red-900:hover{--border-opacity:1;border-color:#742a2a;border-color:rgba(116,42,42,var(--border-opacity))}.xl\:hover\:border-orange-100:hover{--border-opacity:1;border-color:#fffaf0;border-color:rgba(255,250,240,var(--border-opacity))}.xl\:hover\:border-orange-200:hover{--border-opacity:1;border-color:#feebc8;border-color:rgba(254,235,200,var(--border-opacity))}.xl\:hover\:border-orange-300:hover{--border-opacity:1;border-color:#fbd38d;border-color:rgba(251,211,141,var(--border-opacity))}.xl\:hover\:border-orange-400:hover{--border-opacity:1;border-color:#f6ad55;border-color:rgba(246,173,85,var(--border-opacity))}.xl\:hover\:border-orange-500:hover{--border-opacity:1;border-color:#ed8936;border-color:rgba(237,137,54,var(--border-opacity))}.xl\:hover\:border-orange-600:hover{--border-opacity:1;border-color:#dd6b20;border-color:rgba(221,107,32,var(--border-opacity))}.xl\:hover\:border-orange-700:hover{--border-opacity:1;border-color:#c05621;border-color:rgba(192,86,33,var(--border-opacity))}.xl\:hover\:border-orange-800:hover{--border-opacity:1;border-color:#9c4221;border-color:rgba(156,66,33,var(--border-opacity))}.xl\:hover\:border-orange-900:hover{--border-opacity:1;border-color:#7b341e;border-color:rgba(123,52,30,var(--border-opacity))}.xl\:hover\:border-yellow-100:hover{--border-opacity:1;border-color:ivory;border-color:rgba(255,255,240,var(--border-opacity))}.xl\:hover\:border-yellow-200:hover{--border-opacity:1;border-color:#fefcbf;border-color:rgba(254,252,191,var(--border-opacity))}.xl\:hover\:border-yellow-300:hover{--border-opacity:1;border-color:#faf089;border-color:rgba(250,240,137,var(--border-opacity))}.xl\:hover\:border-yellow-400:hover{--border-opacity:1;border-color:#f6e05e;border-color:rgba(246,224,94,var(--border-opacity))}.xl\:hover\:border-yellow-500:hover{--border-opacity:1;border-color:#ecc94b;border-color:rgba(236,201,75,var(--border-opacity))}.xl\:hover\:border-yellow-600:hover{--border-opacity:1;border-color:#d69e2e;border-color:rgba(214,158,46,var(--border-opacity))}.xl\:hover\:border-yellow-700:hover{--border-opacity:1;border-color:#b7791f;border-color:rgba(183,121,31,var(--border-opacity))}.xl\:hover\:border-yellow-800:hover{--border-opacity:1;border-color:#975a16;border-color:rgba(151,90,22,var(--border-opacity))}.xl\:hover\:border-yellow-900:hover{--border-opacity:1;border-color:#744210;border-color:rgba(116,66,16,var(--border-opacity))}.xl\:hover\:border-green-100:hover{--border-opacity:1;border-color:#f0fff4;border-color:rgba(240,255,244,var(--border-opacity))}.xl\:hover\:border-green-200:hover{--border-opacity:1;border-color:#c6f6d5;border-color:rgba(198,246,213,var(--border-opacity))}.xl\:hover\:border-green-300:hover{--border-opacity:1;border-color:#9ae6b4;border-color:rgba(154,230,180,var(--border-opacity))}.xl\:hover\:border-green-400:hover{--border-opacity:1;border-color:#68d391;border-color:rgba(104,211,145,var(--border-opacity))}.xl\:hover\:border-green-500:hover{--border-opacity:1;border-color:#48bb78;border-color:rgba(72,187,120,var(--border-opacity))}.xl\:hover\:border-green-600:hover{--border-opacity:1;border-color:#38a169;border-color:rgba(56,161,105,var(--border-opacity))}.xl\:hover\:border-green-700:hover{--border-opacity:1;border-color:#2f855a;border-color:rgba(47,133,90,var(--border-opacity))}.xl\:hover\:border-green-800:hover{--border-opacity:1;border-color:#276749;border-color:rgba(39,103,73,var(--border-opacity))}.xl\:hover\:border-green-900:hover{--border-opacity:1;border-color:#22543d;border-color:rgba(34,84,61,var(--border-opacity))}.xl\:hover\:border-teal-100:hover{--border-opacity:1;border-color:#e6fffa;border-color:rgba(230,255,250,var(--border-opacity))}.xl\:hover\:border-teal-200:hover{--border-opacity:1;border-color:#b2f5ea;border-color:rgba(178,245,234,var(--border-opacity))}.xl\:hover\:border-teal-300:hover{--border-opacity:1;border-color:#81e6d9;border-color:rgba(129,230,217,var(--border-opacity))}.xl\:hover\:border-teal-400:hover{--border-opacity:1;border-color:#4fd1c5;border-color:rgba(79,209,197,var(--border-opacity))}.xl\:hover\:border-teal-500:hover{--border-opacity:1;border-color:#38b2ac;border-color:rgba(56,178,172,var(--border-opacity))}.xl\:hover\:border-teal-600:hover{--border-opacity:1;border-color:#319795;border-color:rgba(49,151,149,var(--border-opacity))}.xl\:hover\:border-teal-700:hover{--border-opacity:1;border-color:#2c7a7b;border-color:rgba(44,122,123,var(--border-opacity))}.xl\:hover\:border-teal-800:hover{--border-opacity:1;border-color:#285e61;border-color:rgba(40,94,97,var(--border-opacity))}.xl\:hover\:border-teal-900:hover{--border-opacity:1;border-color:#234e52;border-color:rgba(35,78,82,var(--border-opacity))}.xl\:hover\:border-blue-100:hover{--border-opacity:1;border-color:#ebf8ff;border-color:rgba(235,248,255,var(--border-opacity))}.xl\:hover\:border-blue-200:hover{--border-opacity:1;border-color:#bee3f8;border-color:rgba(190,227,248,var(--border-opacity))}.xl\:hover\:border-blue-300:hover{--border-opacity:1;border-color:#90cdf4;border-color:rgba(144,205,244,var(--border-opacity))}.xl\:hover\:border-blue-400:hover{--border-opacity:1;border-color:#63b3ed;border-color:rgba(99,179,237,var(--border-opacity))}.xl\:hover\:border-blue-500:hover{--border-opacity:1;border-color:#4299e1;border-color:rgba(66,153,225,var(--border-opacity))}.xl\:hover\:border-blue-600:hover{--border-opacity:1;border-color:#3182ce;border-color:rgba(49,130,206,var(--border-opacity))}.xl\:hover\:border-blue-700:hover{--border-opacity:1;border-color:#2b6cb0;border-color:rgba(43,108,176,var(--border-opacity))}.xl\:hover\:border-blue-800:hover{--border-opacity:1;border-color:#2c5282;border-color:rgba(44,82,130,var(--border-opacity))}.xl\:hover\:border-blue-900:hover{--border-opacity:1;border-color:#2a4365;border-color:rgba(42,67,101,var(--border-opacity))}.xl\:hover\:border-indigo-100:hover{--border-opacity:1;border-color:#ebf4ff;border-color:rgba(235,244,255,var(--border-opacity))}.xl\:hover\:border-indigo-200:hover{--border-opacity:1;border-color:#c3dafe;border-color:rgba(195,218,254,var(--border-opacity))}.xl\:hover\:border-indigo-300:hover{--border-opacity:1;border-color:#a3bffa;border-color:rgba(163,191,250,var(--border-opacity))}.xl\:hover\:border-indigo-400:hover{--border-opacity:1;border-color:#7f9cf5;border-color:rgba(127,156,245,var(--border-opacity))}.xl\:hover\:border-indigo-500:hover{--border-opacity:1;border-color:#667eea;border-color:rgba(102,126,234,var(--border-opacity))}.xl\:hover\:border-indigo-600:hover{--border-opacity:1;border-color:#5a67d8;border-color:rgba(90,103,216,var(--border-opacity))}.xl\:hover\:border-indigo-700:hover{--border-opacity:1;border-color:#4c51bf;border-color:rgba(76,81,191,var(--border-opacity))}.xl\:hover\:border-indigo-800:hover{--border-opacity:1;border-color:#434190;border-color:rgba(67,65,144,var(--border-opacity))}.xl\:hover\:border-indigo-900:hover{--border-opacity:1;border-color:#3c366b;border-color:rgba(60,54,107,var(--border-opacity))}.xl\:hover\:border-purple-100:hover{--border-opacity:1;border-color:#faf5ff;border-color:rgba(250,245,255,var(--border-opacity))}.xl\:hover\:border-purple-200:hover{--border-opacity:1;border-color:#e9d8fd;border-color:rgba(233,216,253,var(--border-opacity))}.xl\:hover\:border-purple-300:hover{--border-opacity:1;border-color:#d6bcfa;border-color:rgba(214,188,250,var(--border-opacity))}.xl\:hover\:border-purple-400:hover{--border-opacity:1;border-color:#b794f4;border-color:rgba(183,148,244,var(--border-opacity))}.xl\:hover\:border-purple-500:hover{--border-opacity:1;border-color:#9f7aea;border-color:rgba(159,122,234,var(--border-opacity))}.xl\:hover\:border-purple-600:hover{--border-opacity:1;border-color:#805ad5;border-color:rgba(128,90,213,var(--border-opacity))}.xl\:hover\:border-purple-700:hover{--border-opacity:1;border-color:#6b46c1;border-color:rgba(107,70,193,var(--border-opacity))}.xl\:hover\:border-purple-800:hover{--border-opacity:1;border-color:#553c9a;border-color:rgba(85,60,154,var(--border-opacity))}.xl\:hover\:border-purple-900:hover{--border-opacity:1;border-color:#44337a;border-color:rgba(68,51,122,var(--border-opacity))}.xl\:hover\:border-pink-100:hover{--border-opacity:1;border-color:#fff5f7;border-color:rgba(255,245,247,var(--border-opacity))}.xl\:hover\:border-pink-200:hover{--border-opacity:1;border-color:#fed7e2;border-color:rgba(254,215,226,var(--border-opacity))}.xl\:hover\:border-pink-300:hover{--border-opacity:1;border-color:#fbb6ce;border-color:rgba(251,182,206,var(--border-opacity))}.xl\:hover\:border-pink-400:hover{--border-opacity:1;border-color:#f687b3;border-color:rgba(246,135,179,var(--border-opacity))}.xl\:hover\:border-pink-500:hover{--border-opacity:1;border-color:#ed64a6;border-color:rgba(237,100,166,var(--border-opacity))}.xl\:hover\:border-pink-600:hover{--border-opacity:1;border-color:#d53f8c;border-color:rgba(213,63,140,var(--border-opacity))}.xl\:hover\:border-pink-700:hover{--border-opacity:1;border-color:#b83280;border-color:rgba(184,50,128,var(--border-opacity))}.xl\:hover\:border-pink-800:hover{--border-opacity:1;border-color:#97266d;border-color:rgba(151,38,109,var(--border-opacity))}.xl\:hover\:border-pink-900:hover{--border-opacity:1;border-color:#702459;border-color:rgba(112,36,89,var(--border-opacity))}.xl\:focus\:border-transparent:focus{border-color:transparent}.xl\:focus\:border-current:focus{border-color:currentColor}.xl\:focus\:border-black:focus{--border-opacity:1;border-color:#000;border-color:rgba(0,0,0,var(--border-opacity))}.xl\:focus\:border-white:focus{--border-opacity:1;border-color:#fff;border-color:rgba(255,255,255,var(--border-opacity))}.xl\:focus\:border-gray-100:focus{--border-opacity:1;border-color:#f7fafc;border-color:rgba(247,250,252,var(--border-opacity))}.xl\:focus\:border-gray-200:focus{--border-opacity:1;border-color:#edf2f7;border-color:rgba(237,242,247,var(--border-opacity))}.xl\:focus\:border-gray-300:focus{--border-opacity:1;border-color:#e2e8f0;border-color:rgba(226,232,240,var(--border-opacity))}.xl\:focus\:border-gray-400:focus{--border-opacity:1;border-color:#cbd5e0;border-color:rgba(203,213,224,var(--border-opacity))}.xl\:focus\:border-gray-500:focus{--border-opacity:1;border-color:#a0aec0;border-color:rgba(160,174,192,var(--border-opacity))}.xl\:focus\:border-gray-600:focus{--border-opacity:1;border-color:#718096;border-color:rgba(113,128,150,var(--border-opacity))}.xl\:focus\:border-gray-700:focus{--border-opacity:1;border-color:#4a5568;border-color:rgba(74,85,104,var(--border-opacity))}.xl\:focus\:border-gray-800:focus{--border-opacity:1;border-color:#2d3748;border-color:rgba(45,55,72,var(--border-opacity))}.xl\:focus\:border-gray-900:focus{--border-opacity:1;border-color:#1a202c;border-color:rgba(26,32,44,var(--border-opacity))}.xl\:focus\:border-red-100:focus{--border-opacity:1;border-color:#fff5f5;border-color:rgba(255,245,245,var(--border-opacity))}.xl\:focus\:border-red-200:focus{--border-opacity:1;border-color:#fed7d7;border-color:rgba(254,215,215,var(--border-opacity))}.xl\:focus\:border-red-300:focus{--border-opacity:1;border-color:#feb2b2;border-color:rgba(254,178,178,var(--border-opacity))}.xl\:focus\:border-red-400:focus{--border-opacity:1;border-color:#fc8181;border-color:rgba(252,129,129,var(--border-opacity))}.xl\:focus\:border-red-500:focus{--border-opacity:1;border-color:#f56565;border-color:rgba(245,101,101,var(--border-opacity))}.xl\:focus\:border-red-600:focus{--border-opacity:1;border-color:#e53e3e;border-color:rgba(229,62,62,var(--border-opacity))}.xl\:focus\:border-red-700:focus{--border-opacity:1;border-color:#c53030;border-color:rgba(197,48,48,var(--border-opacity))}.xl\:focus\:border-red-800:focus{--border-opacity:1;border-color:#9b2c2c;border-color:rgba(155,44,44,var(--border-opacity))}.xl\:focus\:border-red-900:focus{--border-opacity:1;border-color:#742a2a;border-color:rgba(116,42,42,var(--border-opacity))}.xl\:focus\:border-orange-100:focus{--border-opacity:1;border-color:#fffaf0;border-color:rgba(255,250,240,var(--border-opacity))}.xl\:focus\:border-orange-200:focus{--border-opacity:1;border-color:#feebc8;border-color:rgba(254,235,200,var(--border-opacity))}.xl\:focus\:border-orange-300:focus{--border-opacity:1;border-color:#fbd38d;border-color:rgba(251,211,141,var(--border-opacity))}.xl\:focus\:border-orange-400:focus{--border-opacity:1;border-color:#f6ad55;border-color:rgba(246,173,85,var(--border-opacity))}.xl\:focus\:border-orange-500:focus{--border-opacity:1;border-color:#ed8936;border-color:rgba(237,137,54,var(--border-opacity))}.xl\:focus\:border-orange-600:focus{--border-opacity:1;border-color:#dd6b20;border-color:rgba(221,107,32,var(--border-opacity))}.xl\:focus\:border-orange-700:focus{--border-opacity:1;border-color:#c05621;border-color:rgba(192,86,33,var(--border-opacity))}.xl\:focus\:border-orange-800:focus{--border-opacity:1;border-color:#9c4221;border-color:rgba(156,66,33,var(--border-opacity))}.xl\:focus\:border-orange-900:focus{--border-opacity:1;border-color:#7b341e;border-color:rgba(123,52,30,var(--border-opacity))}.xl\:focus\:border-yellow-100:focus{--border-opacity:1;border-color:ivory;border-color:rgba(255,255,240,var(--border-opacity))}.xl\:focus\:border-yellow-200:focus{--border-opacity:1;border-color:#fefcbf;border-color:rgba(254,252,191,var(--border-opacity))}.xl\:focus\:border-yellow-300:focus{--border-opacity:1;border-color:#faf089;border-color:rgba(250,240,137,var(--border-opacity))}.xl\:focus\:border-yellow-400:focus{--border-opacity:1;border-color:#f6e05e;border-color:rgba(246,224,94,var(--border-opacity))}.xl\:focus\:border-yellow-500:focus{--border-opacity:1;border-color:#ecc94b;border-color:rgba(236,201,75,var(--border-opacity))}.xl\:focus\:border-yellow-600:focus{--border-opacity:1;border-color:#d69e2e;border-color:rgba(214,158,46,var(--border-opacity))}.xl\:focus\:border-yellow-700:focus{--border-opacity:1;border-color:#b7791f;border-color:rgba(183,121,31,var(--border-opacity))}.xl\:focus\:border-yellow-800:focus{--border-opacity:1;border-color:#975a16;border-color:rgba(151,90,22,var(--border-opacity))}.xl\:focus\:border-yellow-900:focus{--border-opacity:1;border-color:#744210;border-color:rgba(116,66,16,var(--border-opacity))}.xl\:focus\:border-green-100:focus{--border-opacity:1;border-color:#f0fff4;border-color:rgba(240,255,244,var(--border-opacity))}.xl\:focus\:border-green-200:focus{--border-opacity:1;border-color:#c6f6d5;border-color:rgba(198,246,213,var(--border-opacity))}.xl\:focus\:border-green-300:focus{--border-opacity:1;border-color:#9ae6b4;border-color:rgba(154,230,180,var(--border-opacity))}.xl\:focus\:border-green-400:focus{--border-opacity:1;border-color:#68d391;border-color:rgba(104,211,145,var(--border-opacity))}.xl\:focus\:border-green-500:focus{--border-opacity:1;border-color:#48bb78;border-color:rgba(72,187,120,var(--border-opacity))}.xl\:focus\:border-green-600:focus{--border-opacity:1;border-color:#38a169;border-color:rgba(56,161,105,var(--border-opacity))}.xl\:focus\:border-green-700:focus{--border-opacity:1;border-color:#2f855a;border-color:rgba(47,133,90,var(--border-opacity))}.xl\:focus\:border-green-800:focus{--border-opacity:1;border-color:#276749;border-color:rgba(39,103,73,var(--border-opacity))}.xl\:focus\:border-green-900:focus{--border-opacity:1;border-color:#22543d;border-color:rgba(34,84,61,var(--border-opacity))}.xl\:focus\:border-teal-100:focus{--border-opacity:1;border-color:#e6fffa;border-color:rgba(230,255,250,var(--border-opacity))}.xl\:focus\:border-teal-200:focus{--border-opacity:1;border-color:#b2f5ea;border-color:rgba(178,245,234,var(--border-opacity))}.xl\:focus\:border-teal-300:focus{--border-opacity:1;border-color:#81e6d9;border-color:rgba(129,230,217,var(--border-opacity))}.xl\:focus\:border-teal-400:focus{--border-opacity:1;border-color:#4fd1c5;border-color:rgba(79,209,197,var(--border-opacity))}.xl\:focus\:border-teal-500:focus{--border-opacity:1;border-color:#38b2ac;border-color:rgba(56,178,172,var(--border-opacity))}.xl\:focus\:border-teal-600:focus{--border-opacity:1;border-color:#319795;border-color:rgba(49,151,149,var(--border-opacity))}.xl\:focus\:border-teal-700:focus{--border-opacity:1;border-color:#2c7a7b;border-color:rgba(44,122,123,var(--border-opacity))}.xl\:focus\:border-teal-800:focus{--border-opacity:1;border-color:#285e61;border-color:rgba(40,94,97,var(--border-opacity))}.xl\:focus\:border-teal-900:focus{--border-opacity:1;border-color:#234e52;border-color:rgba(35,78,82,var(--border-opacity))}.xl\:focus\:border-blue-100:focus{--border-opacity:1;border-color:#ebf8ff;border-color:rgba(235,248,255,var(--border-opacity))}.xl\:focus\:border-blue-200:focus{--border-opacity:1;border-color:#bee3f8;border-color:rgba(190,227,248,var(--border-opacity))}.xl\:focus\:border-blue-300:focus{--border-opacity:1;border-color:#90cdf4;border-color:rgba(144,205,244,var(--border-opacity))}.xl\:focus\:border-blue-400:focus{--border-opacity:1;border-color:#63b3ed;border-color:rgba(99,179,237,var(--border-opacity))}.xl\:focus\:border-blue-500:focus{--border-opacity:1;border-color:#4299e1;border-color:rgba(66,153,225,var(--border-opacity))}.xl\:focus\:border-blue-600:focus{--border-opacity:1;border-color:#3182ce;border-color:rgba(49,130,206,var(--border-opacity))}.xl\:focus\:border-blue-700:focus{--border-opacity:1;border-color:#2b6cb0;border-color:rgba(43,108,176,var(--border-opacity))}.xl\:focus\:border-blue-800:focus{--border-opacity:1;border-color:#2c5282;border-color:rgba(44,82,130,var(--border-opacity))}.xl\:focus\:border-blue-900:focus{--border-opacity:1;border-color:#2a4365;border-color:rgba(42,67,101,var(--border-opacity))}.xl\:focus\:border-indigo-100:focus{--border-opacity:1;border-color:#ebf4ff;border-color:rgba(235,244,255,var(--border-opacity))}.xl\:focus\:border-indigo-200:focus{--border-opacity:1;border-color:#c3dafe;border-color:rgba(195,218,254,var(--border-opacity))}.xl\:focus\:border-indigo-300:focus{--border-opacity:1;border-color:#a3bffa;border-color:rgba(163,191,250,var(--border-opacity))}.xl\:focus\:border-indigo-400:focus{--border-opacity:1;border-color:#7f9cf5;border-color:rgba(127,156,245,var(--border-opacity))}.xl\:focus\:border-indigo-500:focus{--border-opacity:1;border-color:#667eea;border-color:rgba(102,126,234,var(--border-opacity))}.xl\:focus\:border-indigo-600:focus{--border-opacity:1;border-color:#5a67d8;border-color:rgba(90,103,216,var(--border-opacity))}.xl\:focus\:border-indigo-700:focus{--border-opacity:1;border-color:#4c51bf;border-color:rgba(76,81,191,var(--border-opacity))}.xl\:focus\:border-indigo-800:focus{--border-opacity:1;border-color:#434190;border-color:rgba(67,65,144,var(--border-opacity))}.xl\:focus\:border-indigo-900:focus{--border-opacity:1;border-color:#3c366b;border-color:rgba(60,54,107,var(--border-opacity))}.xl\:focus\:border-purple-100:focus{--border-opacity:1;border-color:#faf5ff;border-color:rgba(250,245,255,var(--border-opacity))}.xl\:focus\:border-purple-200:focus{--border-opacity:1;border-color:#e9d8fd;border-color:rgba(233,216,253,var(--border-opacity))}.xl\:focus\:border-purple-300:focus{--border-opacity:1;border-color:#d6bcfa;border-color:rgba(214,188,250,var(--border-opacity))}.xl\:focus\:border-purple-400:focus{--border-opacity:1;border-color:#b794f4;border-color:rgba(183,148,244,var(--border-opacity))}.xl\:focus\:border-purple-500:focus{--border-opacity:1;border-color:#9f7aea;border-color:rgba(159,122,234,var(--border-opacity))}.xl\:focus\:border-purple-600:focus{--border-opacity:1;border-color:#805ad5;border-color:rgba(128,90,213,var(--border-opacity))}.xl\:focus\:border-purple-700:focus{--border-opacity:1;border-color:#6b46c1;border-color:rgba(107,70,193,var(--border-opacity))}.xl\:focus\:border-purple-800:focus{--border-opacity:1;border-color:#553c9a;border-color:rgba(85,60,154,var(--border-opacity))}.xl\:focus\:border-purple-900:focus{--border-opacity:1;border-color:#44337a;border-color:rgba(68,51,122,var(--border-opacity))}.xl\:focus\:border-pink-100:focus{--border-opacity:1;border-color:#fff5f7;border-color:rgba(255,245,247,var(--border-opacity))}.xl\:focus\:border-pink-200:focus{--border-opacity:1;border-color:#fed7e2;border-color:rgba(254,215,226,var(--border-opacity))}.xl\:focus\:border-pink-300:focus{--border-opacity:1;border-color:#fbb6ce;border-color:rgba(251,182,206,var(--border-opacity))}.xl\:focus\:border-pink-400:focus{--border-opacity:1;border-color:#f687b3;border-color:rgba(246,135,179,var(--border-opacity))}.xl\:focus\:border-pink-500:focus{--border-opacity:1;border-color:#ed64a6;border-color:rgba(237,100,166,var(--border-opacity))}.xl\:focus\:border-pink-600:focus{--border-opacity:1;border-color:#d53f8c;border-color:rgba(213,63,140,var(--border-opacity))}.xl\:focus\:border-pink-700:focus{--border-opacity:1;border-color:#b83280;border-color:rgba(184,50,128,var(--border-opacity))}.xl\:focus\:border-pink-800:focus{--border-opacity:1;border-color:#97266d;border-color:rgba(151,38,109,var(--border-opacity))}.xl\:focus\:border-pink-900:focus{--border-opacity:1;border-color:#702459;border-color:rgba(112,36,89,var(--border-opacity))}.xl\:border-opacity-0{--border-opacity:0}.xl\:border-opacity-25{--border-opacity:0.25}.xl\:border-opacity-50{--border-opacity:0.5}.xl\:border-opacity-75{--border-opacity:0.75}.xl\:border-opacity-100{--border-opacity:1}.xl\:hover\:border-opacity-0:hover{--border-opacity:0}.xl\:hover\:border-opacity-25:hover{--border-opacity:0.25}.xl\:hover\:border-opacity-50:hover{--border-opacity:0.5}.xl\:hover\:border-opacity-75:hover{--border-opacity:0.75}.xl\:hover\:border-opacity-100:hover{--border-opacity:1}.xl\:focus\:border-opacity-0:focus{--border-opacity:0}.xl\:focus\:border-opacity-25:focus{--border-opacity:0.25}.xl\:focus\:border-opacity-50:focus{--border-opacity:0.5}.xl\:focus\:border-opacity-75:focus{--border-opacity:0.75}.xl\:focus\:border-opacity-100:focus{--border-opacity:1}.xl\:rounded-none{border-radius:0}.xl\:rounded-sm{border-radius:.125rem}.xl\:rounded{border-radius:.25rem}.xl\:rounded-md{border-radius:.375rem}.xl\:rounded-lg{border-radius:.5rem}.xl\:rounded-xl{border-radius:.75rem}.xl\:rounded-2xl{border-radius:1rem}.xl\:rounded-3xl{border-radius:1.5rem}.xl\:rounded-full{border-radius:9999px}.xl\:rounded-t-none{border-top-left-radius:0;border-top-right-radius:0}.xl\:rounded-r-none{border-top-right-radius:0;border-bottom-right-radius:0}.xl\:rounded-b-none{border-bottom-right-radius:0;border-bottom-left-radius:0}.xl\:rounded-l-none{border-top-left-radius:0;border-bottom-left-radius:0}.xl\:rounded-t-sm{border-top-left-radius:.125rem;border-top-right-radius:.125rem}.xl\:rounded-r-sm{border-top-right-radius:.125rem;border-bottom-right-radius:.125rem}.xl\:rounded-b-sm{border-bottom-right-radius:.125rem;border-bottom-left-radius:.125rem}.xl\:rounded-l-sm{border-top-left-radius:.125rem;border-bottom-left-radius:.125rem}.xl\:rounded-t{border-top-left-radius:.25rem;border-top-right-radius:.25rem}.xl\:rounded-r{border-top-right-radius:.25rem;border-bottom-right-radius:.25rem}.xl\:rounded-b{border-bottom-right-radius:.25rem;border-bottom-left-radius:.25rem}.xl\:rounded-l{border-top-left-radius:.25rem;border-bottom-left-radius:.25rem}.xl\:rounded-t-md{border-top-left-radius:.375rem;border-top-right-radius:.375rem}.xl\:rounded-r-md{border-top-right-radius:.375rem;border-bottom-right-radius:.375rem}.xl\:rounded-b-md{border-bottom-right-radius:.375rem;border-bottom-left-radius:.375rem}.xl\:rounded-l-md{border-top-left-radius:.375rem;border-bottom-left-radius:.375rem}.xl\:rounded-t-lg{border-top-left-radius:.5rem;border-top-right-radius:.5rem}.xl\:rounded-r-lg{border-top-right-radius:.5rem;border-bottom-right-radius:.5rem}.xl\:rounded-b-lg{border-bottom-right-radius:.5rem;border-bottom-left-radius:.5rem}.xl\:rounded-l-lg{border-top-left-radius:.5rem;border-bottom-left-radius:.5rem}.xl\:rounded-t-xl{border-top-left-radius:.75rem;border-top-right-radius:.75rem}.xl\:rounded-r-xl{border-top-right-radius:.75rem;border-bottom-right-radius:.75rem}.xl\:rounded-b-xl{border-bottom-right-radius:.75rem;border-bottom-left-radius:.75rem}.xl\:rounded-l-xl{border-top-left-radius:.75rem;border-bottom-left-radius:.75rem}.xl\:rounded-t-2xl{border-top-left-radius:1rem;border-top-right-radius:1rem}.xl\:rounded-r-2xl{border-top-right-radius:1rem;border-bottom-right-radius:1rem}.xl\:rounded-b-2xl{border-bottom-right-radius:1rem;border-bottom-left-radius:1rem}.xl\:rounded-l-2xl{border-top-left-radius:1rem;border-bottom-left-radius:1rem}.xl\:rounded-t-3xl{border-top-left-radius:1.5rem;border-top-right-radius:1.5rem}.xl\:rounded-r-3xl{border-top-right-radius:1.5rem;border-bottom-right-radius:1.5rem}.xl\:rounded-b-3xl{border-bottom-right-radius:1.5rem;border-bottom-left-radius:1.5rem}.xl\:rounded-l-3xl{border-top-left-radius:1.5rem;border-bottom-left-radius:1.5rem}.xl\:rounded-t-full{border-top-left-radius:9999px;border-top-right-radius:9999px}.xl\:rounded-r-full{border-top-right-radius:9999px;border-bottom-right-radius:9999px}.xl\:rounded-b-full{border-bottom-right-radius:9999px;border-bottom-left-radius:9999px}.xl\:rounded-l-full{border-top-left-radius:9999px;border-bottom-left-radius:9999px}.xl\:rounded-tl-none{border-top-left-radius:0}.xl\:rounded-tr-none{border-top-right-radius:0}.xl\:rounded-br-none{border-bottom-right-radius:0}.xl\:rounded-bl-none{border-bottom-left-radius:0}.xl\:rounded-tl-sm{border-top-left-radius:.125rem}.xl\:rounded-tr-sm{border-top-right-radius:.125rem}.xl\:rounded-br-sm{border-bottom-right-radius:.125rem}.xl\:rounded-bl-sm{border-bottom-left-radius:.125rem}.xl\:rounded-tl{border-top-left-radius:.25rem}.xl\:rounded-tr{border-top-right-radius:.25rem}.xl\:rounded-br{border-bottom-right-radius:.25rem}.xl\:rounded-bl{border-bottom-left-radius:.25rem}.xl\:rounded-tl-md{border-top-left-radius:.375rem}.xl\:rounded-tr-md{border-top-right-radius:.375rem}.xl\:rounded-br-md{border-bottom-right-radius:.375rem}.xl\:rounded-bl-md{border-bottom-left-radius:.375rem}.xl\:rounded-tl-lg{border-top-left-radius:.5rem}.xl\:rounded-tr-lg{border-top-right-radius:.5rem}.xl\:rounded-br-lg{border-bottom-right-radius:.5rem}.xl\:rounded-bl-lg{border-bottom-left-radius:.5rem}.xl\:rounded-tl-xl{border-top-left-radius:.75rem}.xl\:rounded-tr-xl{border-top-right-radius:.75rem}.xl\:rounded-br-xl{border-bottom-right-radius:.75rem}.xl\:rounded-bl-xl{border-bottom-left-radius:.75rem}.xl\:rounded-tl-2xl{border-top-left-radius:1rem}.xl\:rounded-tr-2xl{border-top-right-radius:1rem}.xl\:rounded-br-2xl{border-bottom-right-radius:1rem}.xl\:rounded-bl-2xl{border-bottom-left-radius:1rem}.xl\:rounded-tl-3xl{border-top-left-radius:1.5rem}.xl\:rounded-tr-3xl{border-top-right-radius:1.5rem}.xl\:rounded-br-3xl{border-bottom-right-radius:1.5rem}.xl\:rounded-bl-3xl{border-bottom-left-radius:1.5rem}.xl\:rounded-tl-full{border-top-left-radius:9999px}.xl\:rounded-tr-full{border-top-right-radius:9999px}.xl\:rounded-br-full{border-bottom-right-radius:9999px}.xl\:rounded-bl-full{border-bottom-left-radius:9999px}.xl\:border-solid{border-style:solid}.xl\:border-dashed{border-style:dashed}.xl\:border-dotted{border-style:dotted}.xl\:border-double{border-style:double}.xl\:border-none{border-style:none}.xl\:border-0{border-width:0}.xl\:border-2{border-width:2px}.xl\:border-4{border-width:4px}.xl\:border-8{border-width:8px}.xl\:border{border-width:1px}.xl\:border-t-0{border-top-width:0}.xl\:border-r-0{border-right-width:0}.xl\:border-b-0{border-bottom-width:0}.xl\:border-l-0{border-left-width:0}.xl\:border-t-2{border-top-width:2px}.xl\:border-r-2{border-right-width:2px}.xl\:border-b-2{border-bottom-width:2px}.xl\:border-l-2{border-left-width:2px}.xl\:border-t-4{border-top-width:4px}.xl\:border-r-4{border-right-width:4px}.xl\:border-b-4{border-bottom-width:4px}.xl\:border-l-4{border-left-width:4px}.xl\:border-t-8{border-top-width:8px}.xl\:border-r-8{border-right-width:8px}.xl\:border-b-8{border-bottom-width:8px}.xl\:border-l-8{border-left-width:8px}.xl\:border-t{border-top-width:1px}.xl\:border-r{border-right-width:1px}.xl\:border-b{border-bottom-width:1px}.xl\:border-l{border-left-width:1px}.xl\:box-border{box-sizing:border-box}.xl\:box-content{box-sizing:content-box}.xl\:cursor-auto{cursor:auto}.xl\:cursor-default{cursor:default}.xl\:cursor-pointer{cursor:pointer}.xl\:cursor-wait{cursor:wait}.xl\:cursor-text{cursor:text}.xl\:cursor-move{cursor:move}.xl\:cursor-not-allowed{cursor:not-allowed}.xl\:block{display:block}.xl\:inline-block{display:inline-block}.xl\:inline{display:inline}.xl\:flex{display:flex}.xl\:inline-flex{display:inline-flex}.xl\:table{display:table}.xl\:table-caption{display:table-caption}.xl\:table-cell{display:table-cell}.xl\:table-column{display:table-column}.xl\:table-column-group{display:table-column-group}.xl\:table-footer-group{display:table-footer-group}.xl\:table-header-group{display:table-header-group}.xl\:table-row-group{display:table-row-group}.xl\:table-row{display:table-row}.xl\:flow-root{display:flow-root}.xl\:grid{display:grid}.xl\:inline-grid{display:inline-grid}.xl\:contents{display:contents}.xl\:hidden{display:none}.xl\:flex-row{flex-direction:row}.xl\:flex-row-reverse{flex-direction:row-reverse}.xl\:flex-col{flex-direction:column}.xl\:flex-col-reverse{flex-direction:column-reverse}.xl\:flex-wrap{flex-wrap:wrap}.xl\:flex-wrap-reverse{flex-wrap:wrap-reverse}.xl\:flex-no-wrap{flex-wrap:nowrap}.xl\:place-items-auto{place-items:auto}.xl\:place-items-start{place-items:start}.xl\:place-items-end{place-items:end}.xl\:place-items-center{place-items:center}.xl\:place-items-stretch{place-items:stretch}.xl\:place-content-center{place-content:center}.xl\:place-content-start{place-content:start}.xl\:place-content-end{place-content:end}.xl\:place-content-between{place-content:space-between}.xl\:place-content-around{place-content:space-around}.xl\:place-content-evenly{place-content:space-evenly}.xl\:place-content-stretch{place-content:stretch}.xl\:place-self-auto{place-self:auto}.xl\:place-self-start{place-self:start}.xl\:place-self-end{place-self:end}.xl\:place-self-center{place-self:center}.xl\:place-self-stretch{place-self:stretch}.xl\:items-start{align-items:flex-start}.xl\:items-end{align-items:flex-end}.xl\:items-center{align-items:center}.xl\:items-baseline{align-items:baseline}.xl\:items-stretch{align-items:stretch}.xl\:content-center{align-content:center}.xl\:content-start{align-content:flex-start}.xl\:content-end{align-content:flex-end}.xl\:content-between{align-content:space-between}.xl\:content-around{align-content:space-around}.xl\:content-evenly{align-content:space-evenly}.xl\:self-auto{align-self:auto}.xl\:self-start{align-self:flex-start}.xl\:self-end{align-self:flex-end}.xl\:self-center{align-self:center}.xl\:self-stretch{align-self:stretch}.xl\:justify-items-auto{justify-items:auto}.xl\:justify-items-start{justify-items:start}.xl\:justify-items-end{justify-items:end}.xl\:justify-items-center{justify-items:center}.xl\:justify-items-stretch{justify-items:stretch}.xl\:justify-start{justify-content:flex-start}.xl\:justify-end{justify-content:flex-end}.xl\:justify-center{justify-content:center}.xl\:justify-between{justify-content:space-between}.xl\:justify-around{justify-content:space-around}.xl\:justify-evenly{justify-content:space-evenly}.xl\:justify-self-auto{justify-self:auto}.xl\:justify-self-start{justify-self:start}.xl\:justify-self-end{justify-self:end}.xl\:justify-self-center{justify-self:center}.xl\:justify-self-stretch{justify-self:stretch}.xl\:flex-1{flex:1 1 0%}.xl\:flex-auto{flex:1 1 auto}.xl\:flex-initial{flex:0 1 auto}.xl\:flex-none{flex:none}.xl\:flex-grow-0{flex-grow:0}.xl\:flex-grow{flex-grow:1}.xl\:flex-shrink-0{flex-shrink:0}.xl\:flex-shrink{flex-shrink:1}.xl\:order-1{order:1}.xl\:order-2{order:2}.xl\:order-3{order:3}.xl\:order-4{order:4}.xl\:order-5{order:5}.xl\:order-6{order:6}.xl\:order-7{order:7}.xl\:order-8{order:8}.xl\:order-9{order:9}.xl\:order-10{order:10}.xl\:order-11{order:11}.xl\:order-12{order:12}.xl\:order-first{order:-9999}.xl\:order-last{order:9999}.xl\:order-none{order:0}.xl\:float-right{float:right}.xl\:float-left{float:left}.xl\:float-none{float:none}.xl\:clearfix:after{content:"";display:table;clear:both}.xl\:clear-left{clear:left}.xl\:clear-right{clear:right}.xl\:clear-both{clear:both}.xl\:clear-none{clear:none}.xl\:font-sans{font-family:system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji"}.xl\:font-serif{font-family:Georgia,Cambria,"Times New Roman",Times,serif}.xl\:font-mono{font-family:Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace}.xl\:font-hairline{font-weight:100}.xl\:font-thin{font-weight:200}.xl\:font-light{font-weight:300}.xl\:font-normal{font-weight:400}.xl\:font-medium{font-weight:500}.xl\:font-semibold{font-weight:600}.xl\:font-bold{font-weight:700}.xl\:font-extrabold{font-weight:800}.xl\:font-black{font-weight:900}.xl\:hover\:font-hairline:hover{font-weight:100}.xl\:hover\:font-thin:hover{font-weight:200}.xl\:hover\:font-light:hover{font-weight:300}.xl\:hover\:font-normal:hover{font-weight:400}.xl\:hover\:font-medium:hover{font-weight:500}.xl\:hover\:font-semibold:hover{font-weight:600}.xl\:hover\:font-bold:hover{font-weight:700}.xl\:hover\:font-extrabold:hover{font-weight:800}.xl\:hover\:font-black:hover{font-weight:900}.xl\:focus\:font-hairline:focus{font-weight:100}.xl\:focus\:font-thin:focus{font-weight:200}.xl\:focus\:font-light:focus{font-weight:300}.xl\:focus\:font-normal:focus{font-weight:400}.xl\:focus\:font-medium:focus{font-weight:500}.xl\:focus\:font-semibold:focus{font-weight:600}.xl\:focus\:font-bold:focus{font-weight:700}.xl\:focus\:font-extrabold:focus{font-weight:800}.xl\:focus\:font-black:focus{font-weight:900}.xl\:h-0{height:0}.xl\:h-1{height:.25rem}.xl\:h-2{height:.5rem}.xl\:h-3{height:.75rem}.xl\:h-4{height:1rem}.xl\:h-5{height:1.25rem}.xl\:h-6{height:1.5rem}.xl\:h-8{height:2rem}.xl\:h-10{height:2.5rem}.xl\:h-12{height:3rem}.xl\:h-16{height:4rem}.xl\:h-20{height:5rem}.xl\:h-24{height:6rem}.xl\:h-32{height:8rem}.xl\:h-40{height:10rem}.xl\:h-48{height:12rem}.xl\:h-56{height:14rem}.xl\:h-64{height:16rem}.xl\:h-auto{height:auto}.xl\:h-px{height:1px}.xl\:h-full{height:100%}.xl\:h-screen{height:100vh}.xl\:text-xs{font-size:.75rem}.xl\:text-sm{font-size:.875rem}.xl\:text-base{font-size:1rem}.xl\:text-lg{font-size:1.125rem}.xl\:text-xl{font-size:1.25rem}.xl\:text-2xl{font-size:1.5rem}.xl\:text-3xl{font-size:1.875rem}.xl\:text-4xl{font-size:2.25rem}.xl\:text-5xl{font-size:3rem}.xl\:text-6xl{font-size:4rem}.xl\:leading-3{line-height:.75rem}.xl\:leading-4{line-height:1rem}.xl\:leading-5{line-height:1.25rem}.xl\:leading-6{line-height:1.5rem}.xl\:leading-7{line-height:1.75rem}.xl\:leading-8{line-height:2rem}.xl\:leading-9{line-height:2.25rem}.xl\:leading-10{line-height:2.5rem}.xl\:leading-none{line-height:1}.xl\:leading-tight{line-height:1.25}.xl\:leading-snug{line-height:1.375}.xl\:leading-normal{line-height:1.5}.xl\:leading-relaxed{line-height:1.625}.xl\:leading-loose{line-height:2}.xl\:list-inside{list-style-position:inside}.xl\:list-outside{list-style-position:outside}.xl\:list-none{list-style-type:none}.xl\:list-disc{list-style-type:disc}.xl\:list-decimal{list-style-type:decimal}.xl\:m-0{margin:0}.xl\:m-1{margin:.25rem}.xl\:m-2{margin:.5rem}.xl\:m-3{margin:.75rem}.xl\:m-4{margin:1rem}.xl\:m-5{margin:1.25rem}.xl\:m-6{margin:1.5rem}.xl\:m-8{margin:2rem}.xl\:m-10{margin:2.5rem}.xl\:m-12{margin:3rem}.xl\:m-16{margin:4rem}.xl\:m-20{margin:5rem}.xl\:m-24{margin:6rem}.xl\:m-32{margin:8rem}.xl\:m-40{margin:10rem}.xl\:m-48{margin:12rem}.xl\:m-56{margin:14rem}.xl\:m-64{margin:16rem}.xl\:m-auto{margin:auto}.xl\:m-px{margin:1px}.xl\:-m-1{margin:-.25rem}.xl\:-m-2{margin:-.5rem}.xl\:-m-3{margin:-.75rem}.xl\:-m-4{margin:-1rem}.xl\:-m-5{margin:-1.25rem}.xl\:-m-6{margin:-1.5rem}.xl\:-m-8{margin:-2rem}.xl\:-m-10{margin:-2.5rem}.xl\:-m-12{margin:-3rem}.xl\:-m-16{margin:-4rem}.xl\:-m-20{margin:-5rem}.xl\:-m-24{margin:-6rem}.xl\:-m-32{margin:-8rem}.xl\:-m-40{margin:-10rem}.xl\:-m-48{margin:-12rem}.xl\:-m-56{margin:-14rem}.xl\:-m-64{margin:-16rem}.xl\:-m-px{margin:-1px}.xl\:my-0{margin-top:0;margin-bottom:0}.xl\:mx-0{margin-left:0;margin-right:0}.xl\:my-1{margin-top:.25rem;margin-bottom:.25rem}.xl\:mx-1{margin-left:.25rem;margin-right:.25rem}.xl\:my-2{margin-top:.5rem;margin-bottom:.5rem}.xl\:mx-2{margin-left:.5rem;margin-right:.5rem}.xl\:my-3{margin-top:.75rem;margin-bottom:.75rem}.xl\:mx-3{margin-left:.75rem;margin-right:.75rem}.xl\:my-4{margin-top:1rem;margin-bottom:1rem}.xl\:mx-4{margin-left:1rem;margin-right:1rem}.xl\:my-5{margin-top:1.25rem;margin-bottom:1.25rem}.xl\:mx-5{margin-left:1.25rem;margin-right:1.25rem}.xl\:my-6{margin-top:1.5rem;margin-bottom:1.5rem}.xl\:mx-6{margin-left:1.5rem;margin-right:1.5rem}.xl\:my-8{margin-top:2rem;margin-bottom:2rem}.xl\:mx-8{margin-left:2rem;margin-right:2rem}.xl\:my-10{margin-top:2.5rem;margin-bottom:2.5rem}.xl\:mx-10{margin-left:2.5rem;margin-right:2.5rem}.xl\:my-12{margin-top:3rem;margin-bottom:3rem}.xl\:mx-12{margin-left:3rem;margin-right:3rem}.xl\:my-16{margin-top:4rem;margin-bottom:4rem}.xl\:mx-16{margin-left:4rem;margin-right:4rem}.xl\:my-20{margin-top:5rem;margin-bottom:5rem}.xl\:mx-20{margin-left:5rem;margin-right:5rem}.xl\:my-24{margin-top:6rem;margin-bottom:6rem}.xl\:mx-24{margin-left:6rem;margin-right:6rem}.xl\:my-32{margin-top:8rem;margin-bottom:8rem}.xl\:mx-32{margin-left:8rem;margin-right:8rem}.xl\:my-40{margin-top:10rem;margin-bottom:10rem}.xl\:mx-40{margin-left:10rem;margin-right:10rem}.xl\:my-48{margin-top:12rem;margin-bottom:12rem}.xl\:mx-48{margin-left:12rem;margin-right:12rem}.xl\:my-56{margin-top:14rem;margin-bottom:14rem}.xl\:mx-56{margin-left:14rem;margin-right:14rem}.xl\:my-64{margin-top:16rem;margin-bottom:16rem}.xl\:mx-64{margin-left:16rem;margin-right:16rem}.xl\:my-auto{margin-top:auto;margin-bottom:auto}.xl\:mx-auto{margin-left:auto;margin-right:auto}.xl\:my-px{margin-top:1px;margin-bottom:1px}.xl\:mx-px{margin-left:1px;margin-right:1px}.xl\:-my-1{margin-top:-.25rem;margin-bottom:-.25rem}.xl\:-mx-1{margin-left:-.25rem;margin-right:-.25rem}.xl\:-my-2{margin-top:-.5rem;margin-bottom:-.5rem}.xl\:-mx-2{margin-left:-.5rem;margin-right:-.5rem}.xl\:-my-3{margin-top:-.75rem;margin-bottom:-.75rem}.xl\:-mx-3{margin-left:-.75rem;margin-right:-.75rem}.xl\:-my-4{margin-top:-1rem;margin-bottom:-1rem}.xl\:-mx-4{margin-left:-1rem;margin-right:-1rem}.xl\:-my-5{margin-top:-1.25rem;margin-bottom:-1.25rem}.xl\:-mx-5{margin-left:-1.25rem;margin-right:-1.25rem}.xl\:-my-6{margin-top:-1.5rem;margin-bottom:-1.5rem}.xl\:-mx-6{margin-left:-1.5rem;margin-right:-1.5rem}.xl\:-my-8{margin-top:-2rem;margin-bottom:-2rem}.xl\:-mx-8{margin-left:-2rem;margin-right:-2rem}.xl\:-my-10{margin-top:-2.5rem;margin-bottom:-2.5rem}.xl\:-mx-10{margin-left:-2.5rem;margin-right:-2.5rem}.xl\:-my-12{margin-top:-3rem;margin-bottom:-3rem}.xl\:-mx-12{margin-left:-3rem;margin-right:-3rem}.xl\:-my-16{margin-top:-4rem;margin-bottom:-4rem}.xl\:-mx-16{margin-left:-4rem;margin-right:-4rem}.xl\:-my-20{margin-top:-5rem;margin-bottom:-5rem}.xl\:-mx-20{margin-left:-5rem;margin-right:-5rem}.xl\:-my-24{margin-top:-6rem;margin-bottom:-6rem}.xl\:-mx-24{margin-left:-6rem;margin-right:-6rem}.xl\:-my-32{margin-top:-8rem;margin-bottom:-8rem}.xl\:-mx-32{margin-left:-8rem;margin-right:-8rem}.xl\:-my-40{margin-top:-10rem;margin-bottom:-10rem}.xl\:-mx-40{margin-left:-10rem;margin-right:-10rem}.xl\:-my-48{margin-top:-12rem;margin-bottom:-12rem}.xl\:-mx-48{margin-left:-12rem;margin-right:-12rem}.xl\:-my-56{margin-top:-14rem;margin-bottom:-14rem}.xl\:-mx-56{margin-left:-14rem;margin-right:-14rem}.xl\:-my-64{margin-top:-16rem;margin-bottom:-16rem}.xl\:-mx-64{margin-left:-16rem;margin-right:-16rem}.xl\:-my-px{margin-top:-1px;margin-bottom:-1px}.xl\:-mx-px{margin-left:-1px;margin-right:-1px}.xl\:mt-0{margin-top:0}.xl\:mr-0{margin-right:0}.xl\:mb-0{margin-bottom:0}.xl\:ml-0{margin-left:0}.xl\:mt-1{margin-top:.25rem}.xl\:mr-1{margin-right:.25rem}.xl\:mb-1{margin-bottom:.25rem}.xl\:ml-1{margin-left:.25rem}.xl\:mt-2{margin-top:.5rem}.xl\:mr-2{margin-right:.5rem}.xl\:mb-2{margin-bottom:.5rem}.xl\:ml-2{margin-left:.5rem}.xl\:mt-3{margin-top:.75rem}.xl\:mr-3{margin-right:.75rem}.xl\:mb-3{margin-bottom:.75rem}.xl\:ml-3{margin-left:.75rem}.xl\:mt-4{margin-top:1rem}.xl\:mr-4{margin-right:1rem}.xl\:mb-4{margin-bottom:1rem}.xl\:ml-4{margin-left:1rem}.xl\:mt-5{margin-top:1.25rem}.xl\:mr-5{margin-right:1.25rem}.xl\:mb-5{margin-bottom:1.25rem}.xl\:ml-5{margin-left:1.25rem}.xl\:mt-6{margin-top:1.5rem}.xl\:mr-6{margin-right:1.5rem}.xl\:mb-6{margin-bottom:1.5rem}.xl\:ml-6{margin-left:1.5rem}.xl\:mt-8{margin-top:2rem}.xl\:mr-8{margin-right:2rem}.xl\:mb-8{margin-bottom:2rem}.xl\:ml-8{margin-left:2rem}.xl\:mt-10{margin-top:2.5rem}.xl\:mr-10{margin-right:2.5rem}.xl\:mb-10{margin-bottom:2.5rem}.xl\:ml-10{margin-left:2.5rem}.xl\:mt-12{margin-top:3rem}.xl\:mr-12{margin-right:3rem}.xl\:mb-12{margin-bottom:3rem}.xl\:ml-12{margin-left:3rem}.xl\:mt-16{margin-top:4rem}.xl\:mr-16{margin-right:4rem}.xl\:mb-16{margin-bottom:4rem}.xl\:ml-16{margin-left:4rem}.xl\:mt-20{margin-top:5rem}.xl\:mr-20{margin-right:5rem}.xl\:mb-20{margin-bottom:5rem}.xl\:ml-20{margin-left:5rem}.xl\:mt-24{margin-top:6rem}.xl\:mr-24{margin-right:6rem}.xl\:mb-24{margin-bottom:6rem}.xl\:ml-24{margin-left:6rem}.xl\:mt-32{margin-top:8rem}.xl\:mr-32{margin-right:8rem}.xl\:mb-32{margin-bottom:8rem}.xl\:ml-32{margin-left:8rem}.xl\:mt-40{margin-top:10rem}.xl\:mr-40{margin-right:10rem}.xl\:mb-40{margin-bottom:10rem}.xl\:ml-40{margin-left:10rem}.xl\:mt-48{margin-top:12rem}.xl\:mr-48{margin-right:12rem}.xl\:mb-48{margin-bottom:12rem}.xl\:ml-48{margin-left:12rem}.xl\:mt-56{margin-top:14rem}.xl\:mr-56{margin-right:14rem}.xl\:mb-56{margin-bottom:14rem}.xl\:ml-56{margin-left:14rem}.xl\:mt-64{margin-top:16rem}.xl\:mr-64{margin-right:16rem}.xl\:mb-64{margin-bottom:16rem}.xl\:ml-64{margin-left:16rem}.xl\:mt-auto{margin-top:auto}.xl\:mr-auto{margin-right:auto}.xl\:mb-auto{margin-bottom:auto}.xl\:ml-auto{margin-left:auto}.xl\:mt-px{margin-top:1px}.xl\:mr-px{margin-right:1px}.xl\:mb-px{margin-bottom:1px}.xl\:ml-px{margin-left:1px}.xl\:-mt-1{margin-top:-.25rem}.xl\:-mr-1{margin-right:-.25rem}.xl\:-mb-1{margin-bottom:-.25rem}.xl\:-ml-1{margin-left:-.25rem}.xl\:-mt-2{margin-top:-.5rem}.xl\:-mr-2{margin-right:-.5rem}.xl\:-mb-2{margin-bottom:-.5rem}.xl\:-ml-2{margin-left:-.5rem}.xl\:-mt-3{margin-top:-.75rem}.xl\:-mr-3{margin-right:-.75rem}.xl\:-mb-3{margin-bottom:-.75rem}.xl\:-ml-3{margin-left:-.75rem}.xl\:-mt-4{margin-top:-1rem}.xl\:-mr-4{margin-right:-1rem}.xl\:-mb-4{margin-bottom:-1rem}.xl\:-ml-4{margin-left:-1rem}.xl\:-mt-5{margin-top:-1.25rem}.xl\:-mr-5{margin-right:-1.25rem}.xl\:-mb-5{margin-bottom:-1.25rem}.xl\:-ml-5{margin-left:-1.25rem}.xl\:-mt-6{margin-top:-1.5rem}.xl\:-mr-6{margin-right:-1.5rem}.xl\:-mb-6{margin-bottom:-1.5rem}.xl\:-ml-6{margin-left:-1.5rem}.xl\:-mt-8{margin-top:-2rem}.xl\:-mr-8{margin-right:-2rem}.xl\:-mb-8{margin-bottom:-2rem}.xl\:-ml-8{margin-left:-2rem}.xl\:-mt-10{margin-top:-2.5rem}.xl\:-mr-10{margin-right:-2.5rem}.xl\:-mb-10{margin-bottom:-2.5rem}.xl\:-ml-10{margin-left:-2.5rem}.xl\:-mt-12{margin-top:-3rem}.xl\:-mr-12{margin-right:-3rem}.xl\:-mb-12{margin-bottom:-3rem}.xl\:-ml-12{margin-left:-3rem}.xl\:-mt-16{margin-top:-4rem}.xl\:-mr-16{margin-right:-4rem}.xl\:-mb-16{margin-bottom:-4rem}.xl\:-ml-16{margin-left:-4rem}.xl\:-mt-20{margin-top:-5rem}.xl\:-mr-20{margin-right:-5rem}.xl\:-mb-20{margin-bottom:-5rem}.xl\:-ml-20{margin-left:-5rem}.xl\:-mt-24{margin-top:-6rem}.xl\:-mr-24{margin-right:-6rem}.xl\:-mb-24{margin-bottom:-6rem}.xl\:-ml-24{margin-left:-6rem}.xl\:-mt-32{margin-top:-8rem}.xl\:-mr-32{margin-right:-8rem}.xl\:-mb-32{margin-bottom:-8rem}.xl\:-ml-32{margin-left:-8rem}.xl\:-mt-40{margin-top:-10rem}.xl\:-mr-40{margin-right:-10rem}.xl\:-mb-40{margin-bottom:-10rem}.xl\:-ml-40{margin-left:-10rem}.xl\:-mt-48{margin-top:-12rem}.xl\:-mr-48{margin-right:-12rem}.xl\:-mb-48{margin-bottom:-12rem}.xl\:-ml-48{margin-left:-12rem}.xl\:-mt-56{margin-top:-14rem}.xl\:-mr-56{margin-right:-14rem}.xl\:-mb-56{margin-bottom:-14rem}.xl\:-ml-56{margin-left:-14rem}.xl\:-mt-64{margin-top:-16rem}.xl\:-mr-64{margin-right:-16rem}.xl\:-mb-64{margin-bottom:-16rem}.xl\:-ml-64{margin-left:-16rem}.xl\:-mt-px{margin-top:-1px}.xl\:-mr-px{margin-right:-1px}.xl\:-mb-px{margin-bottom:-1px}.xl\:-ml-px{margin-left:-1px}.xl\:max-h-full{max-height:100%}.xl\:max-h-screen{max-height:100vh}.xl\:max-w-none{max-width:none}.xl\:max-w-xs{max-width:20rem}.xl\:max-w-sm{max-width:24rem}.xl\:max-w-md{max-width:28rem}.xl\:max-w-lg{max-width:32rem}.xl\:max-w-xl{max-width:36rem}.xl\:max-w-2xl{max-width:42rem}.xl\:max-w-3xl{max-width:48rem}.xl\:max-w-4xl{max-width:56rem}.xl\:max-w-5xl{max-width:64rem}.xl\:max-w-6xl{max-width:72rem}.xl\:max-w-full{max-width:100%}.xl\:max-w-screen-sm{max-width:640px}.xl\:max-w-screen-md{max-width:768px}.xl\:max-w-screen-lg{max-width:1024px}.xl\:max-w-screen-xl{max-width:1280px}.xl\:min-h-0{min-height:0}.xl\:min-h-full{min-height:100%}.xl\:min-h-screen{min-height:100vh}.xl\:min-w-0{min-width:0}.xl\:min-w-full{min-width:100%}.xl\:object-contain{object-fit:contain}.xl\:object-cover{object-fit:cover}.xl\:object-fill{object-fit:fill}.xl\:object-none{object-fit:none}.xl\:object-scale-down{object-fit:scale-down}.xl\:object-bottom{object-position:bottom}.xl\:object-center{object-position:center}.xl\:object-left{object-position:left}.xl\:object-left-bottom{object-position:left bottom}.xl\:object-left-top{object-position:left top}.xl\:object-right{object-position:right}.xl\:object-right-bottom{object-position:right bottom}.xl\:object-right-top{object-position:right top}.xl\:object-top{object-position:top}.xl\:opacity-0{opacity:0}.xl\:opacity-25{opacity:.25}.xl\:opacity-50{opacity:.5}.xl\:opacity-75{opacity:.75}.xl\:opacity-100{opacity:1}.xl\:hover\:opacity-0:hover{opacity:0}.xl\:hover\:opacity-25:hover{opacity:.25}.xl\:hover\:opacity-50:hover{opacity:.5}.xl\:hover\:opacity-75:hover{opacity:.75}.xl\:hover\:opacity-100:hover{opacity:1}.xl\:focus\:opacity-0:focus{opacity:0}.xl\:focus\:opacity-25:focus{opacity:.25}.xl\:focus\:opacity-50:focus{opacity:.5}.xl\:focus\:opacity-75:focus{opacity:.75}.xl\:focus\:opacity-100:focus{opacity:1}.xl\:outline-none{outline:2px solid transparent;outline-offset:2px}.xl\:outline-white{outline:2px dotted #fff;outline-offset:2px}.xl\:outline-black{outline:2px dotted #000;outline-offset:2px}.xl\:focus\:outline-none:focus{outline:2px solid transparent;outline-offset:2px}.xl\:focus\:outline-white:focus{outline:2px dotted #fff;outline-offset:2px}.xl\:focus\:outline-black:focus{outline:2px dotted #000;outline-offset:2px}.xl\:overflow-auto{overflow:auto}.xl\:overflow-hidden{overflow:hidden}.xl\:overflow-visible{overflow:visible}.xl\:overflow-scroll{overflow:scroll}.xl\:overflow-x-auto{overflow-x:auto}.xl\:overflow-y-auto{overflow-y:auto}.xl\:overflow-x-hidden{overflow-x:hidden}.xl\:overflow-y-hidden{overflow-y:hidden}.xl\:overflow-x-visible{overflow-x:visible}.xl\:overflow-y-visible{overflow-y:visible}.xl\:overflow-x-scroll{overflow-x:scroll}.xl\:overflow-y-scroll{overflow-y:scroll}.xl\:scrolling-touch{-webkit-overflow-scrolling:touch}.xl\:scrolling-auto{-webkit-overflow-scrolling:auto}.xl\:overscroll-auto{-ms-scroll-chaining:chained;overscroll-behavior:auto}.xl\:overscroll-contain{-ms-scroll-chaining:none;overscroll-behavior:contain}.xl\:overscroll-none{-ms-scroll-chaining:none;overscroll-behavior:none}.xl\:overscroll-y-auto{overscroll-behavior-y:auto}.xl\:overscroll-y-contain{overscroll-behavior-y:contain}.xl\:overscroll-y-none{overscroll-behavior-y:none}.xl\:overscroll-x-auto{overscroll-behavior-x:auto}.xl\:overscroll-x-contain{overscroll-behavior-x:contain}.xl\:overscroll-x-none{overscroll-behavior-x:none}.xl\:p-0{padding:0}.xl\:p-1{padding:.25rem}.xl\:p-2{padding:.5rem}.xl\:p-3{padding:.75rem}.xl\:p-4{padding:1rem}.xl\:p-5{padding:1.25rem}.xl\:p-6{padding:1.5rem}.xl\:p-8{padding:2rem}.xl\:p-10{padding:2.5rem}.xl\:p-12{padding:3rem}.xl\:p-16{padding:4rem}.xl\:p-20{padding:5rem}.xl\:p-24{padding:6rem}.xl\:p-32{padding:8rem}.xl\:p-40{padding:10rem}.xl\:p-48{padding:12rem}.xl\:p-56{padding:14rem}.xl\:p-64{padding:16rem}.xl\:p-px{padding:1px}.xl\:py-0{padding-top:0;padding-bottom:0}.xl\:px-0{padding-left:0;padding-right:0}.xl\:py-1{padding-top:.25rem;padding-bottom:.25rem}.xl\:px-1{padding-left:.25rem;padding-right:.25rem}.xl\:py-2{padding-top:.5rem;padding-bottom:.5rem}.xl\:px-2{padding-left:.5rem;padding-right:.5rem}.xl\:py-3{padding-top:.75rem;padding-bottom:.75rem}.xl\:px-3{padding-left:.75rem;padding-right:.75rem}.xl\:py-4{padding-top:1rem;padding-bottom:1rem}.xl\:px-4{padding-left:1rem;padding-right:1rem}.xl\:py-5{padding-top:1.25rem;padding-bottom:1.25rem}.xl\:px-5{padding-left:1.25rem;padding-right:1.25rem}.xl\:py-6{padding-top:1.5rem;padding-bottom:1.5rem}.xl\:px-6{padding-left:1.5rem;padding-right:1.5rem}.xl\:py-8{padding-top:2rem;padding-bottom:2rem}.xl\:px-8{padding-left:2rem;padding-right:2rem}.xl\:py-10{padding-top:2.5rem;padding-bottom:2.5rem}.xl\:px-10{padding-left:2.5rem;padding-right:2.5rem}.xl\:py-12{padding-top:3rem;padding-bottom:3rem}.xl\:px-12{padding-left:3rem;padding-right:3rem}.xl\:py-16{padding-top:4rem;padding-bottom:4rem}.xl\:px-16{padding-left:4rem;padding-right:4rem}.xl\:py-20{padding-top:5rem;padding-bottom:5rem}.xl\:px-20{padding-left:5rem;padding-right:5rem}.xl\:py-24{padding-top:6rem;padding-bottom:6rem}.xl\:px-24{padding-left:6rem;padding-right:6rem}.xl\:py-32{padding-top:8rem;padding-bottom:8rem}.xl\:px-32{padding-left:8rem;padding-right:8rem}.xl\:py-40{padding-top:10rem;padding-bottom:10rem}.xl\:px-40{padding-left:10rem;padding-right:10rem}.xl\:py-48{padding-top:12rem;padding-bottom:12rem}.xl\:px-48{padding-left:12rem;padding-right:12rem}.xl\:py-56{padding-top:14rem;padding-bottom:14rem}.xl\:px-56{padding-left:14rem;padding-right:14rem}.xl\:py-64{padding-top:16rem;padding-bottom:16rem}.xl\:px-64{padding-left:16rem;padding-right:16rem}.xl\:py-px{padding-top:1px;padding-bottom:1px}.xl\:px-px{padding-left:1px;padding-right:1px}.xl\:pt-0{padding-top:0}.xl\:pr-0{padding-right:0}.xl\:pb-0{padding-bottom:0}.xl\:pl-0{padding-left:0}.xl\:pt-1{padding-top:.25rem}.xl\:pr-1{padding-right:.25rem}.xl\:pb-1{padding-bottom:.25rem}.xl\:pl-1{padding-left:.25rem}.xl\:pt-2{padding-top:.5rem}.xl\:pr-2{padding-right:.5rem}.xl\:pb-2{padding-bottom:.5rem}.xl\:pl-2{padding-left:.5rem}.xl\:pt-3{padding-top:.75rem}.xl\:pr-3{padding-right:.75rem}.xl\:pb-3{padding-bottom:.75rem}.xl\:pl-3{padding-left:.75rem}.xl\:pt-4{padding-top:1rem}.xl\:pr-4{padding-right:1rem}.xl\:pb-4{padding-bottom:1rem}.xl\:pl-4{padding-left:1rem}.xl\:pt-5{padding-top:1.25rem}.xl\:pr-5{padding-right:1.25rem}.xl\:pb-5{padding-bottom:1.25rem}.xl\:pl-5{padding-left:1.25rem}.xl\:pt-6{padding-top:1.5rem}.xl\:pr-6{padding-right:1.5rem}.xl\:pb-6{padding-bottom:1.5rem}.xl\:pl-6{padding-left:1.5rem}.xl\:pt-8{padding-top:2rem}.xl\:pr-8{padding-right:2rem}.xl\:pb-8{padding-bottom:2rem}.xl\:pl-8{padding-left:2rem}.xl\:pt-10{padding-top:2.5rem}.xl\:pr-10{padding-right:2.5rem}.xl\:pb-10{padding-bottom:2.5rem}.xl\:pl-10{padding-left:2.5rem}.xl\:pt-12{padding-top:3rem}.xl\:pr-12{padding-right:3rem}.xl\:pb-12{padding-bottom:3rem}.xl\:pl-12{padding-left:3rem}.xl\:pt-16{padding-top:4rem}.xl\:pr-16{padding-right:4rem}.xl\:pb-16{padding-bottom:4rem}.xl\:pl-16{padding-left:4rem}.xl\:pt-20{padding-top:5rem}.xl\:pr-20{padding-right:5rem}.xl\:pb-20{padding-bottom:5rem}.xl\:pl-20{padding-left:5rem}.xl\:pt-24{padding-top:6rem}.xl\:pr-24{padding-right:6rem}.xl\:pb-24{padding-bottom:6rem}.xl\:pl-24{padding-left:6rem}.xl\:pt-32{padding-top:8rem}.xl\:pr-32{padding-right:8rem}.xl\:pb-32{padding-bottom:8rem}.xl\:pl-32{padding-left:8rem}.xl\:pt-40{padding-top:10rem}.xl\:pr-40{padding-right:10rem}.xl\:pb-40{padding-bottom:10rem}.xl\:pl-40{padding-left:10rem}.xl\:pt-48{padding-top:12rem}.xl\:pr-48{padding-right:12rem}.xl\:pb-48{padding-bottom:12rem}.xl\:pl-48{padding-left:12rem}.xl\:pt-56{padding-top:14rem}.xl\:pr-56{padding-right:14rem}.xl\:pb-56{padding-bottom:14rem}.xl\:pl-56{padding-left:14rem}.xl\:pt-64{padding-top:16rem}.xl\:pr-64{padding-right:16rem}.xl\:pb-64{padding-bottom:16rem}.xl\:pl-64{padding-left:16rem}.xl\:pt-px{padding-top:1px}.xl\:pr-px{padding-right:1px}.xl\:pb-px{padding-bottom:1px}.xl\:pl-px{padding-left:1px}.xl\:placeholder-transparent:-ms-input-placeholder{color:transparent}.xl\:placeholder-transparent::-ms-input-placeholder{color:transparent}.xl\:placeholder-transparent::placeholder{color:transparent}.xl\:placeholder-current:-ms-input-placeholder{color:currentColor}.xl\:placeholder-current::-ms-input-placeholder{color:currentColor}.xl\:placeholder-current::placeholder{color:currentColor}.xl\:placeholder-black:-ms-input-placeholder{--placeholder-opacity:1;color:#000;color:rgba(0,0,0,var(--placeholder-opacity))}.xl\:placeholder-black::-ms-input-placeholder{--placeholder-opacity:1;color:#000;color:rgba(0,0,0,var(--placeholder-opacity))}.xl\:placeholder-black::placeholder{--placeholder-opacity:1;color:#000;color:rgba(0,0,0,var(--placeholder-opacity))}.xl\:placeholder-white:-ms-input-placeholder{--placeholder-opacity:1;color:#fff;color:rgba(255,255,255,var(--placeholder-opacity))}.xl\:placeholder-white::-ms-input-placeholder{--placeholder-opacity:1;color:#fff;color:rgba(255,255,255,var(--placeholder-opacity))}.xl\:placeholder-white::placeholder{--placeholder-opacity:1;color:#fff;color:rgba(255,255,255,var(--placeholder-opacity))}.xl\:placeholder-gray-100:-ms-input-placeholder{--placeholder-opacity:1;color:#f7fafc;color:rgba(247,250,252,var(--placeholder-opacity))}.xl\:placeholder-gray-100::-ms-input-placeholder{--placeholder-opacity:1;color:#f7fafc;color:rgba(247,250,252,var(--placeholder-opacity))}.xl\:placeholder-gray-100::placeholder{--placeholder-opacity:1;color:#f7fafc;color:rgba(247,250,252,var(--placeholder-opacity))}.xl\:placeholder-gray-200:-ms-input-placeholder{--placeholder-opacity:1;color:#edf2f7;color:rgba(237,242,247,var(--placeholder-opacity))}.xl\:placeholder-gray-200::-ms-input-placeholder{--placeholder-opacity:1;color:#edf2f7;color:rgba(237,242,247,var(--placeholder-opacity))}.xl\:placeholder-gray-200::placeholder{--placeholder-opacity:1;color:#edf2f7;color:rgba(237,242,247,var(--placeholder-opacity))}.xl\:placeholder-gray-300:-ms-input-placeholder{--placeholder-opacity:1;color:#e2e8f0;color:rgba(226,232,240,var(--placeholder-opacity))}.xl\:placeholder-gray-300::-ms-input-placeholder{--placeholder-opacity:1;color:#e2e8f0;color:rgba(226,232,240,var(--placeholder-opacity))}.xl\:placeholder-gray-300::placeholder{--placeholder-opacity:1;color:#e2e8f0;color:rgba(226,232,240,var(--placeholder-opacity))}.xl\:placeholder-gray-400:-ms-input-placeholder{--placeholder-opacity:1;color:#cbd5e0;color:rgba(203,213,224,var(--placeholder-opacity))}.xl\:placeholder-gray-400::-ms-input-placeholder{--placeholder-opacity:1;color:#cbd5e0;color:rgba(203,213,224,var(--placeholder-opacity))}.xl\:placeholder-gray-400::placeholder{--placeholder-opacity:1;color:#cbd5e0;color:rgba(203,213,224,var(--placeholder-opacity))}.xl\:placeholder-gray-500:-ms-input-placeholder{--placeholder-opacity:1;color:#a0aec0;color:rgba(160,174,192,var(--placeholder-opacity))}.xl\:placeholder-gray-500::-ms-input-placeholder{--placeholder-opacity:1;color:#a0aec0;color:rgba(160,174,192,var(--placeholder-opacity))}.xl\:placeholder-gray-500::placeholder{--placeholder-opacity:1;color:#a0aec0;color:rgba(160,174,192,var(--placeholder-opacity))}.xl\:placeholder-gray-600:-ms-input-placeholder{--placeholder-opacity:1;color:#718096;color:rgba(113,128,150,var(--placeholder-opacity))}.xl\:placeholder-gray-600::-ms-input-placeholder{--placeholder-opacity:1;color:#718096;color:rgba(113,128,150,var(--placeholder-opacity))}.xl\:placeholder-gray-600::placeholder{--placeholder-opacity:1;color:#718096;color:rgba(113,128,150,var(--placeholder-opacity))}.xl\:placeholder-gray-700:-ms-input-placeholder{--placeholder-opacity:1;color:#4a5568;color:rgba(74,85,104,var(--placeholder-opacity))}.xl\:placeholder-gray-700::-ms-input-placeholder{--placeholder-opacity:1;color:#4a5568;color:rgba(74,85,104,var(--placeholder-opacity))}.xl\:placeholder-gray-700::placeholder{--placeholder-opacity:1;color:#4a5568;color:rgba(74,85,104,var(--placeholder-opacity))}.xl\:placeholder-gray-800:-ms-input-placeholder{--placeholder-opacity:1;color:#2d3748;color:rgba(45,55,72,var(--placeholder-opacity))}.xl\:placeholder-gray-800::-ms-input-placeholder{--placeholder-opacity:1;color:#2d3748;color:rgba(45,55,72,var(--placeholder-opacity))}.xl\:placeholder-gray-800::placeholder{--placeholder-opacity:1;color:#2d3748;color:rgba(45,55,72,var(--placeholder-opacity))}.xl\:placeholder-gray-900:-ms-input-placeholder{--placeholder-opacity:1;color:#1a202c;color:rgba(26,32,44,var(--placeholder-opacity))}.xl\:placeholder-gray-900::-ms-input-placeholder{--placeholder-opacity:1;color:#1a202c;color:rgba(26,32,44,var(--placeholder-opacity))}.xl\:placeholder-gray-900::placeholder{--placeholder-opacity:1;color:#1a202c;color:rgba(26,32,44,var(--placeholder-opacity))}.xl\:placeholder-red-100:-ms-input-placeholder{--placeholder-opacity:1;color:#fff5f5;color:rgba(255,245,245,var(--placeholder-opacity))}.xl\:placeholder-red-100::-ms-input-placeholder{--placeholder-opacity:1;color:#fff5f5;color:rgba(255,245,245,var(--placeholder-opacity))}.xl\:placeholder-red-100::placeholder{--placeholder-opacity:1;color:#fff5f5;color:rgba(255,245,245,var(--placeholder-opacity))}.xl\:placeholder-red-200:-ms-input-placeholder{--placeholder-opacity:1;color:#fed7d7;color:rgba(254,215,215,var(--placeholder-opacity))}.xl\:placeholder-red-200::-ms-input-placeholder{--placeholder-opacity:1;color:#fed7d7;color:rgba(254,215,215,var(--placeholder-opacity))}.xl\:placeholder-red-200::placeholder{--placeholder-opacity:1;color:#fed7d7;color:rgba(254,215,215,var(--placeholder-opacity))}.xl\:placeholder-red-300:-ms-input-placeholder{--placeholder-opacity:1;color:#feb2b2;color:rgba(254,178,178,var(--placeholder-opacity))}.xl\:placeholder-red-300::-ms-input-placeholder{--placeholder-opacity:1;color:#feb2b2;color:rgba(254,178,178,var(--placeholder-opacity))}.xl\:placeholder-red-300::placeholder{--placeholder-opacity:1;color:#feb2b2;color:rgba(254,178,178,var(--placeholder-opacity))}.xl\:placeholder-red-400:-ms-input-placeholder{--placeholder-opacity:1;color:#fc8181;color:rgba(252,129,129,var(--placeholder-opacity))}.xl\:placeholder-red-400::-ms-input-placeholder{--placeholder-opacity:1;color:#fc8181;color:rgba(252,129,129,var(--placeholder-opacity))}.xl\:placeholder-red-400::placeholder{--placeholder-opacity:1;color:#fc8181;color:rgba(252,129,129,var(--placeholder-opacity))}.xl\:placeholder-red-500:-ms-input-placeholder{--placeholder-opacity:1;color:#f56565;color:rgba(245,101,101,var(--placeholder-opacity))}.xl\:placeholder-red-500::-ms-input-placeholder{--placeholder-opacity:1;color:#f56565;color:rgba(245,101,101,var(--placeholder-opacity))}.xl\:placeholder-red-500::placeholder{--placeholder-opacity:1;color:#f56565;color:rgba(245,101,101,var(--placeholder-opacity))}.xl\:placeholder-red-600:-ms-input-placeholder{--placeholder-opacity:1;color:#e53e3e;color:rgba(229,62,62,var(--placeholder-opacity))}.xl\:placeholder-red-600::-ms-input-placeholder{--placeholder-opacity:1;color:#e53e3e;color:rgba(229,62,62,var(--placeholder-opacity))}.xl\:placeholder-red-600::placeholder{--placeholder-opacity:1;color:#e53e3e;color:rgba(229,62,62,var(--placeholder-opacity))}.xl\:placeholder-red-700:-ms-input-placeholder{--placeholder-opacity:1;color:#c53030;color:rgba(197,48,48,var(--placeholder-opacity))}.xl\:placeholder-red-700::-ms-input-placeholder{--placeholder-opacity:1;color:#c53030;color:rgba(197,48,48,var(--placeholder-opacity))}.xl\:placeholder-red-700::placeholder{--placeholder-opacity:1;color:#c53030;color:rgba(197,48,48,var(--placeholder-opacity))}.xl\:placeholder-red-800:-ms-input-placeholder{--placeholder-opacity:1;color:#9b2c2c;color:rgba(155,44,44,var(--placeholder-opacity))}.xl\:placeholder-red-800::-ms-input-placeholder{--placeholder-opacity:1;color:#9b2c2c;color:rgba(155,44,44,var(--placeholder-opacity))}.xl\:placeholder-red-800::placeholder{--placeholder-opacity:1;color:#9b2c2c;color:rgba(155,44,44,var(--placeholder-opacity))}.xl\:placeholder-red-900:-ms-input-placeholder{--placeholder-opacity:1;color:#742a2a;color:rgba(116,42,42,var(--placeholder-opacity))}.xl\:placeholder-red-900::-ms-input-placeholder{--placeholder-opacity:1;color:#742a2a;color:rgba(116,42,42,var(--placeholder-opacity))}.xl\:placeholder-red-900::placeholder{--placeholder-opacity:1;color:#742a2a;color:rgba(116,42,42,var(--placeholder-opacity))}.xl\:placeholder-orange-100:-ms-input-placeholder{--placeholder-opacity:1;color:#fffaf0;color:rgba(255,250,240,var(--placeholder-opacity))}.xl\:placeholder-orange-100::-ms-input-placeholder{--placeholder-opacity:1;color:#fffaf0;color:rgba(255,250,240,var(--placeholder-opacity))}.xl\:placeholder-orange-100::placeholder{--placeholder-opacity:1;color:#fffaf0;color:rgba(255,250,240,var(--placeholder-opacity))}.xl\:placeholder-orange-200:-ms-input-placeholder{--placeholder-opacity:1;color:#feebc8;color:rgba(254,235,200,var(--placeholder-opacity))}.xl\:placeholder-orange-200::-ms-input-placeholder{--placeholder-opacity:1;color:#feebc8;color:rgba(254,235,200,var(--placeholder-opacity))}.xl\:placeholder-orange-200::placeholder{--placeholder-opacity:1;color:#feebc8;color:rgba(254,235,200,var(--placeholder-opacity))}.xl\:placeholder-orange-300:-ms-input-placeholder{--placeholder-opacity:1;color:#fbd38d;color:rgba(251,211,141,var(--placeholder-opacity))}.xl\:placeholder-orange-300::-ms-input-placeholder{--placeholder-opacity:1;color:#fbd38d;color:rgba(251,211,141,var(--placeholder-opacity))}.xl\:placeholder-orange-300::placeholder{--placeholder-opacity:1;color:#fbd38d;color:rgba(251,211,141,var(--placeholder-opacity))}.xl\:placeholder-orange-400:-ms-input-placeholder{--placeholder-opacity:1;color:#f6ad55;color:rgba(246,173,85,var(--placeholder-opacity))}.xl\:placeholder-orange-400::-ms-input-placeholder{--placeholder-opacity:1;color:#f6ad55;color:rgba(246,173,85,var(--placeholder-opacity))}.xl\:placeholder-orange-400::placeholder{--placeholder-opacity:1;color:#f6ad55;color:rgba(246,173,85,var(--placeholder-opacity))}.xl\:placeholder-orange-500:-ms-input-placeholder{--placeholder-opacity:1;color:#ed8936;color:rgba(237,137,54,var(--placeholder-opacity))}.xl\:placeholder-orange-500::-ms-input-placeholder{--placeholder-opacity:1;color:#ed8936;color:rgba(237,137,54,var(--placeholder-opacity))}.xl\:placeholder-orange-500::placeholder{--placeholder-opacity:1;color:#ed8936;color:rgba(237,137,54,var(--placeholder-opacity))}.xl\:placeholder-orange-600:-ms-input-placeholder{--placeholder-opacity:1;color:#dd6b20;color:rgba(221,107,32,var(--placeholder-opacity))}.xl\:placeholder-orange-600::-ms-input-placeholder{--placeholder-opacity:1;color:#dd6b20;color:rgba(221,107,32,var(--placeholder-opacity))}.xl\:placeholder-orange-600::placeholder{--placeholder-opacity:1;color:#dd6b20;color:rgba(221,107,32,var(--placeholder-opacity))}.xl\:placeholder-orange-700:-ms-input-placeholder{--placeholder-opacity:1;color:#c05621;color:rgba(192,86,33,var(--placeholder-opacity))}.xl\:placeholder-orange-700::-ms-input-placeholder{--placeholder-opacity:1;color:#c05621;color:rgba(192,86,33,var(--placeholder-opacity))}.xl\:placeholder-orange-700::placeholder{--placeholder-opacity:1;color:#c05621;color:rgba(192,86,33,var(--placeholder-opacity))}.xl\:placeholder-orange-800:-ms-input-placeholder{--placeholder-opacity:1;color:#9c4221;color:rgba(156,66,33,var(--placeholder-opacity))}.xl\:placeholder-orange-800::-ms-input-placeholder{--placeholder-opacity:1;color:#9c4221;color:rgba(156,66,33,var(--placeholder-opacity))}.xl\:placeholder-orange-800::placeholder{--placeholder-opacity:1;color:#9c4221;color:rgba(156,66,33,var(--placeholder-opacity))}.xl\:placeholder-orange-900:-ms-input-placeholder{--placeholder-opacity:1;color:#7b341e;color:rgba(123,52,30,var(--placeholder-opacity))}.xl\:placeholder-orange-900::-ms-input-placeholder{--placeholder-opacity:1;color:#7b341e;color:rgba(123,52,30,var(--placeholder-opacity))}.xl\:placeholder-orange-900::placeholder{--placeholder-opacity:1;color:#7b341e;color:rgba(123,52,30,var(--placeholder-opacity))}.xl\:placeholder-yellow-100:-ms-input-placeholder{--placeholder-opacity:1;color:ivory;color:rgba(255,255,240,var(--placeholder-opacity))}.xl\:placeholder-yellow-100::-ms-input-placeholder{--placeholder-opacity:1;color:ivory;color:rgba(255,255,240,var(--placeholder-opacity))}.xl\:placeholder-yellow-100::placeholder{--placeholder-opacity:1;color:ivory;color:rgba(255,255,240,var(--placeholder-opacity))}.xl\:placeholder-yellow-200:-ms-input-placeholder{--placeholder-opacity:1;color:#fefcbf;color:rgba(254,252,191,var(--placeholder-opacity))}.xl\:placeholder-yellow-200::-ms-input-placeholder{--placeholder-opacity:1;color:#fefcbf;color:rgba(254,252,191,var(--placeholder-opacity))}.xl\:placeholder-yellow-200::placeholder{--placeholder-opacity:1;color:#fefcbf;color:rgba(254,252,191,var(--placeholder-opacity))}.xl\:placeholder-yellow-300:-ms-input-placeholder{--placeholder-opacity:1;color:#faf089;color:rgba(250,240,137,var(--placeholder-opacity))}.xl\:placeholder-yellow-300::-ms-input-placeholder{--placeholder-opacity:1;color:#faf089;color:rgba(250,240,137,var(--placeholder-opacity))}.xl\:placeholder-yellow-300::placeholder{--placeholder-opacity:1;color:#faf089;color:rgba(250,240,137,var(--placeholder-opacity))}.xl\:placeholder-yellow-400:-ms-input-placeholder{--placeholder-opacity:1;color:#f6e05e;color:rgba(246,224,94,var(--placeholder-opacity))}.xl\:placeholder-yellow-400::-ms-input-placeholder{--placeholder-opacity:1;color:#f6e05e;color:rgba(246,224,94,var(--placeholder-opacity))}.xl\:placeholder-yellow-400::placeholder{--placeholder-opacity:1;color:#f6e05e;color:rgba(246,224,94,var(--placeholder-opacity))}.xl\:placeholder-yellow-500:-ms-input-placeholder{--placeholder-opacity:1;color:#ecc94b;color:rgba(236,201,75,var(--placeholder-opacity))}.xl\:placeholder-yellow-500::-ms-input-placeholder{--placeholder-opacity:1;color:#ecc94b;color:rgba(236,201,75,var(--placeholder-opacity))}.xl\:placeholder-yellow-500::placeholder{--placeholder-opacity:1;color:#ecc94b;color:rgba(236,201,75,var(--placeholder-opacity))}.xl\:placeholder-yellow-600:-ms-input-placeholder{--placeholder-opacity:1;color:#d69e2e;color:rgba(214,158,46,var(--placeholder-opacity))}.xl\:placeholder-yellow-600::-ms-input-placeholder{--placeholder-opacity:1;color:#d69e2e;color:rgba(214,158,46,var(--placeholder-opacity))}.xl\:placeholder-yellow-600::placeholder{--placeholder-opacity:1;color:#d69e2e;color:rgba(214,158,46,var(--placeholder-opacity))}.xl\:placeholder-yellow-700:-ms-input-placeholder{--placeholder-opacity:1;color:#b7791f;color:rgba(183,121,31,var(--placeholder-opacity))}.xl\:placeholder-yellow-700::-ms-input-placeholder{--placeholder-opacity:1;color:#b7791f;color:rgba(183,121,31,var(--placeholder-opacity))}.xl\:placeholder-yellow-700::placeholder{--placeholder-opacity:1;color:#b7791f;color:rgba(183,121,31,var(--placeholder-opacity))}.xl\:placeholder-yellow-800:-ms-input-placeholder{--placeholder-opacity:1;color:#975a16;color:rgba(151,90,22,var(--placeholder-opacity))}.xl\:placeholder-yellow-800::-ms-input-placeholder{--placeholder-opacity:1;color:#975a16;color:rgba(151,90,22,var(--placeholder-opacity))}.xl\:placeholder-yellow-800::placeholder{--placeholder-opacity:1;color:#975a16;color:rgba(151,90,22,var(--placeholder-opacity))}.xl\:placeholder-yellow-900:-ms-input-placeholder{--placeholder-opacity:1;color:#744210;color:rgba(116,66,16,var(--placeholder-opacity))}.xl\:placeholder-yellow-900::-ms-input-placeholder{--placeholder-opacity:1;color:#744210;color:rgba(116,66,16,var(--placeholder-opacity))}.xl\:placeholder-yellow-900::placeholder{--placeholder-opacity:1;color:#744210;color:rgba(116,66,16,var(--placeholder-opacity))}.xl\:placeholder-green-100:-ms-input-placeholder{--placeholder-opacity:1;color:#f0fff4;color:rgba(240,255,244,var(--placeholder-opacity))}.xl\:placeholder-green-100::-ms-input-placeholder{--placeholder-opacity:1;color:#f0fff4;color:rgba(240,255,244,var(--placeholder-opacity))}.xl\:placeholder-green-100::placeholder{--placeholder-opacity:1;color:#f0fff4;color:rgba(240,255,244,var(--placeholder-opacity))}.xl\:placeholder-green-200:-ms-input-placeholder{--placeholder-opacity:1;color:#c6f6d5;color:rgba(198,246,213,var(--placeholder-opacity))}.xl\:placeholder-green-200::-ms-input-placeholder{--placeholder-opacity:1;color:#c6f6d5;color:rgba(198,246,213,var(--placeholder-opacity))}.xl\:placeholder-green-200::placeholder{--placeholder-opacity:1;color:#c6f6d5;color:rgba(198,246,213,var(--placeholder-opacity))}.xl\:placeholder-green-300:-ms-input-placeholder{--placeholder-opacity:1;color:#9ae6b4;color:rgba(154,230,180,var(--placeholder-opacity))}.xl\:placeholder-green-300::-ms-input-placeholder{--placeholder-opacity:1;color:#9ae6b4;color:rgba(154,230,180,var(--placeholder-opacity))}.xl\:placeholder-green-300::placeholder{--placeholder-opacity:1;color:#9ae6b4;color:rgba(154,230,180,var(--placeholder-opacity))}.xl\:placeholder-green-400:-ms-input-placeholder{--placeholder-opacity:1;color:#68d391;color:rgba(104,211,145,var(--placeholder-opacity))}.xl\:placeholder-green-400::-ms-input-placeholder{--placeholder-opacity:1;color:#68d391;color:rgba(104,211,145,var(--placeholder-opacity))}.xl\:placeholder-green-400::placeholder{--placeholder-opacity:1;color:#68d391;color:rgba(104,211,145,var(--placeholder-opacity))}.xl\:placeholder-green-500:-ms-input-placeholder{--placeholder-opacity:1;color:#48bb78;color:rgba(72,187,120,var(--placeholder-opacity))}.xl\:placeholder-green-500::-ms-input-placeholder{--placeholder-opacity:1;color:#48bb78;color:rgba(72,187,120,var(--placeholder-opacity))}.xl\:placeholder-green-500::placeholder{--placeholder-opacity:1;color:#48bb78;color:rgba(72,187,120,var(--placeholder-opacity))}.xl\:placeholder-green-600:-ms-input-placeholder{--placeholder-opacity:1;color:#38a169;color:rgba(56,161,105,var(--placeholder-opacity))}.xl\:placeholder-green-600::-ms-input-placeholder{--placeholder-opacity:1;color:#38a169;color:rgba(56,161,105,var(--placeholder-opacity))}.xl\:placeholder-green-600::placeholder{--placeholder-opacity:1;color:#38a169;color:rgba(56,161,105,var(--placeholder-opacity))}.xl\:placeholder-green-700:-ms-input-placeholder{--placeholder-opacity:1;color:#2f855a;color:rgba(47,133,90,var(--placeholder-opacity))}.xl\:placeholder-green-700::-ms-input-placeholder{--placeholder-opacity:1;color:#2f855a;color:rgba(47,133,90,var(--placeholder-opacity))}.xl\:placeholder-green-700::placeholder{--placeholder-opacity:1;color:#2f855a;color:rgba(47,133,90,var(--placeholder-opacity))}.xl\:placeholder-green-800:-ms-input-placeholder{--placeholder-opacity:1;color:#276749;color:rgba(39,103,73,var(--placeholder-opacity))}.xl\:placeholder-green-800::-ms-input-placeholder{--placeholder-opacity:1;color:#276749;color:rgba(39,103,73,var(--placeholder-opacity))}.xl\:placeholder-green-800::placeholder{--placeholder-opacity:1;color:#276749;color:rgba(39,103,73,var(--placeholder-opacity))}.xl\:placeholder-green-900:-ms-input-placeholder{--placeholder-opacity:1;color:#22543d;color:rgba(34,84,61,var(--placeholder-opacity))}.xl\:placeholder-green-900::-ms-input-placeholder{--placeholder-opacity:1;color:#22543d;color:rgba(34,84,61,var(--placeholder-opacity))}.xl\:placeholder-green-900::placeholder{--placeholder-opacity:1;color:#22543d;color:rgba(34,84,61,var(--placeholder-opacity))}.xl\:placeholder-teal-100:-ms-input-placeholder{--placeholder-opacity:1;color:#e6fffa;color:rgba(230,255,250,var(--placeholder-opacity))}.xl\:placeholder-teal-100::-ms-input-placeholder{--placeholder-opacity:1;color:#e6fffa;color:rgba(230,255,250,var(--placeholder-opacity))}.xl\:placeholder-teal-100::placeholder{--placeholder-opacity:1;color:#e6fffa;color:rgba(230,255,250,var(--placeholder-opacity))}.xl\:placeholder-teal-200:-ms-input-placeholder{--placeholder-opacity:1;color:#b2f5ea;color:rgba(178,245,234,var(--placeholder-opacity))}.xl\:placeholder-teal-200::-ms-input-placeholder{--placeholder-opacity:1;color:#b2f5ea;color:rgba(178,245,234,var(--placeholder-opacity))}.xl\:placeholder-teal-200::placeholder{--placeholder-opacity:1;color:#b2f5ea;color:rgba(178,245,234,var(--placeholder-opacity))}.xl\:placeholder-teal-300:-ms-input-placeholder{--placeholder-opacity:1;color:#81e6d9;color:rgba(129,230,217,var(--placeholder-opacity))}.xl\:placeholder-teal-300::-ms-input-placeholder{--placeholder-opacity:1;color:#81e6d9;color:rgba(129,230,217,var(--placeholder-opacity))}.xl\:placeholder-teal-300::placeholder{--placeholder-opacity:1;color:#81e6d9;color:rgba(129,230,217,var(--placeholder-opacity))}.xl\:placeholder-teal-400:-ms-input-placeholder{--placeholder-opacity:1;color:#4fd1c5;color:rgba(79,209,197,var(--placeholder-opacity))}.xl\:placeholder-teal-400::-ms-input-placeholder{--placeholder-opacity:1;color:#4fd1c5;color:rgba(79,209,197,var(--placeholder-opacity))}.xl\:placeholder-teal-400::placeholder{--placeholder-opacity:1;color:#4fd1c5;color:rgba(79,209,197,var(--placeholder-opacity))}.xl\:placeholder-teal-500:-ms-input-placeholder{--placeholder-opacity:1;color:#38b2ac;color:rgba(56,178,172,var(--placeholder-opacity))}.xl\:placeholder-teal-500::-ms-input-placeholder{--placeholder-opacity:1;color:#38b2ac;color:rgba(56,178,172,var(--placeholder-opacity))}.xl\:placeholder-teal-500::placeholder{--placeholder-opacity:1;color:#38b2ac;color:rgba(56,178,172,var(--placeholder-opacity))}.xl\:placeholder-teal-600:-ms-input-placeholder{--placeholder-opacity:1;color:#319795;color:rgba(49,151,149,var(--placeholder-opacity))}.xl\:placeholder-teal-600::-ms-input-placeholder{--placeholder-opacity:1;color:#319795;color:rgba(49,151,149,var(--placeholder-opacity))}.xl\:placeholder-teal-600::placeholder{--placeholder-opacity:1;color:#319795;color:rgba(49,151,149,var(--placeholder-opacity))}.xl\:placeholder-teal-700:-ms-input-placeholder{--placeholder-opacity:1;color:#2c7a7b;color:rgba(44,122,123,var(--placeholder-opacity))}.xl\:placeholder-teal-700::-ms-input-placeholder{--placeholder-opacity:1;color:#2c7a7b;color:rgba(44,122,123,var(--placeholder-opacity))}.xl\:placeholder-teal-700::placeholder{--placeholder-opacity:1;color:#2c7a7b;color:rgba(44,122,123,var(--placeholder-opacity))}.xl\:placeholder-teal-800:-ms-input-placeholder{--placeholder-opacity:1;color:#285e61;color:rgba(40,94,97,var(--placeholder-opacity))}.xl\:placeholder-teal-800::-ms-input-placeholder{--placeholder-opacity:1;color:#285e61;color:rgba(40,94,97,var(--placeholder-opacity))}.xl\:placeholder-teal-800::placeholder{--placeholder-opacity:1;color:#285e61;color:rgba(40,94,97,var(--placeholder-opacity))}.xl\:placeholder-teal-900:-ms-input-placeholder{--placeholder-opacity:1;color:#234e52;color:rgba(35,78,82,var(--placeholder-opacity))}.xl\:placeholder-teal-900::-ms-input-placeholder{--placeholder-opacity:1;color:#234e52;color:rgba(35,78,82,var(--placeholder-opacity))}.xl\:placeholder-teal-900::placeholder{--placeholder-opacity:1;color:#234e52;color:rgba(35,78,82,var(--placeholder-opacity))}.xl\:placeholder-blue-100:-ms-input-placeholder{--placeholder-opacity:1;color:#ebf8ff;color:rgba(235,248,255,var(--placeholder-opacity))}.xl\:placeholder-blue-100::-ms-input-placeholder{--placeholder-opacity:1;color:#ebf8ff;color:rgba(235,248,255,var(--placeholder-opacity))}.xl\:placeholder-blue-100::placeholder{--placeholder-opacity:1;color:#ebf8ff;color:rgba(235,248,255,var(--placeholder-opacity))}.xl\:placeholder-blue-200:-ms-input-placeholder{--placeholder-opacity:1;color:#bee3f8;color:rgba(190,227,248,var(--placeholder-opacity))}.xl\:placeholder-blue-200::-ms-input-placeholder{--placeholder-opacity:1;color:#bee3f8;color:rgba(190,227,248,var(--placeholder-opacity))}.xl\:placeholder-blue-200::placeholder{--placeholder-opacity:1;color:#bee3f8;color:rgba(190,227,248,var(--placeholder-opacity))}.xl\:placeholder-blue-300:-ms-input-placeholder{--placeholder-opacity:1;color:#90cdf4;color:rgba(144,205,244,var(--placeholder-opacity))}.xl\:placeholder-blue-300::-ms-input-placeholder{--placeholder-opacity:1;color:#90cdf4;color:rgba(144,205,244,var(--placeholder-opacity))}.xl\:placeholder-blue-300::placeholder{--placeholder-opacity:1;color:#90cdf4;color:rgba(144,205,244,var(--placeholder-opacity))}.xl\:placeholder-blue-400:-ms-input-placeholder{--placeholder-opacity:1;color:#63b3ed;color:rgba(99,179,237,var(--placeholder-opacity))}.xl\:placeholder-blue-400::-ms-input-placeholder{--placeholder-opacity:1;color:#63b3ed;color:rgba(99,179,237,var(--placeholder-opacity))}.xl\:placeholder-blue-400::placeholder{--placeholder-opacity:1;color:#63b3ed;color:rgba(99,179,237,var(--placeholder-opacity))}.xl\:placeholder-blue-500:-ms-input-placeholder{--placeholder-opacity:1;color:#4299e1;color:rgba(66,153,225,var(--placeholder-opacity))}.xl\:placeholder-blue-500::-ms-input-placeholder{--placeholder-opacity:1;color:#4299e1;color:rgba(66,153,225,var(--placeholder-opacity))}.xl\:placeholder-blue-500::placeholder{--placeholder-opacity:1;color:#4299e1;color:rgba(66,153,225,var(--placeholder-opacity))}.xl\:placeholder-blue-600:-ms-input-placeholder{--placeholder-opacity:1;color:#3182ce;color:rgba(49,130,206,var(--placeholder-opacity))}.xl\:placeholder-blue-600::-ms-input-placeholder{--placeholder-opacity:1;color:#3182ce;color:rgba(49,130,206,var(--placeholder-opacity))}.xl\:placeholder-blue-600::placeholder{--placeholder-opacity:1;color:#3182ce;color:rgba(49,130,206,var(--placeholder-opacity))}.xl\:placeholder-blue-700:-ms-input-placeholder{--placeholder-opacity:1;color:#2b6cb0;color:rgba(43,108,176,var(--placeholder-opacity))}.xl\:placeholder-blue-700::-ms-input-placeholder{--placeholder-opacity:1;color:#2b6cb0;color:rgba(43,108,176,var(--placeholder-opacity))}.xl\:placeholder-blue-700::placeholder{--placeholder-opacity:1;color:#2b6cb0;color:rgba(43,108,176,var(--placeholder-opacity))}.xl\:placeholder-blue-800:-ms-input-placeholder{--placeholder-opacity:1;color:#2c5282;color:rgba(44,82,130,var(--placeholder-opacity))}.xl\:placeholder-blue-800::-ms-input-placeholder{--placeholder-opacity:1;color:#2c5282;color:rgba(44,82,130,var(--placeholder-opacity))}.xl\:placeholder-blue-800::placeholder{--placeholder-opacity:1;color:#2c5282;color:rgba(44,82,130,var(--placeholder-opacity))}.xl\:placeholder-blue-900:-ms-input-placeholder{--placeholder-opacity:1;color:#2a4365;color:rgba(42,67,101,var(--placeholder-opacity))}.xl\:placeholder-blue-900::-ms-input-placeholder{--placeholder-opacity:1;color:#2a4365;color:rgba(42,67,101,var(--placeholder-opacity))}.xl\:placeholder-blue-900::placeholder{--placeholder-opacity:1;color:#2a4365;color:rgba(42,67,101,var(--placeholder-opacity))}.xl\:placeholder-indigo-100:-ms-input-placeholder{--placeholder-opacity:1;color:#ebf4ff;color:rgba(235,244,255,var(--placeholder-opacity))}.xl\:placeholder-indigo-100::-ms-input-placeholder{--placeholder-opacity:1;color:#ebf4ff;color:rgba(235,244,255,var(--placeholder-opacity))}.xl\:placeholder-indigo-100::placeholder{--placeholder-opacity:1;color:#ebf4ff;color:rgba(235,244,255,var(--placeholder-opacity))}.xl\:placeholder-indigo-200:-ms-input-placeholder{--placeholder-opacity:1;color:#c3dafe;color:rgba(195,218,254,var(--placeholder-opacity))}.xl\:placeholder-indigo-200::-ms-input-placeholder{--placeholder-opacity:1;color:#c3dafe;color:rgba(195,218,254,var(--placeholder-opacity))}.xl\:placeholder-indigo-200::placeholder{--placeholder-opacity:1;color:#c3dafe;color:rgba(195,218,254,var(--placeholder-opacity))}.xl\:placeholder-indigo-300:-ms-input-placeholder{--placeholder-opacity:1;color:#a3bffa;color:rgba(163,191,250,var(--placeholder-opacity))}.xl\:placeholder-indigo-300::-ms-input-placeholder{--placeholder-opacity:1;color:#a3bffa;color:rgba(163,191,250,var(--placeholder-opacity))}.xl\:placeholder-indigo-300::placeholder{--placeholder-opacity:1;color:#a3bffa;color:rgba(163,191,250,var(--placeholder-opacity))}.xl\:placeholder-indigo-400:-ms-input-placeholder{--placeholder-opacity:1;color:#7f9cf5;color:rgba(127,156,245,var(--placeholder-opacity))}.xl\:placeholder-indigo-400::-ms-input-placeholder{--placeholder-opacity:1;color:#7f9cf5;color:rgba(127,156,245,var(--placeholder-opacity))}.xl\:placeholder-indigo-400::placeholder{--placeholder-opacity:1;color:#7f9cf5;color:rgba(127,156,245,var(--placeholder-opacity))}.xl\:placeholder-indigo-500:-ms-input-placeholder{--placeholder-opacity:1;color:#667eea;color:rgba(102,126,234,var(--placeholder-opacity))}.xl\:placeholder-indigo-500::-ms-input-placeholder{--placeholder-opacity:1;color:#667eea;color:rgba(102,126,234,var(--placeholder-opacity))}.xl\:placeholder-indigo-500::placeholder{--placeholder-opacity:1;color:#667eea;color:rgba(102,126,234,var(--placeholder-opacity))}.xl\:placeholder-indigo-600:-ms-input-placeholder{--placeholder-opacity:1;color:#5a67d8;color:rgba(90,103,216,var(--placeholder-opacity))}.xl\:placeholder-indigo-600::-ms-input-placeholder{--placeholder-opacity:1;color:#5a67d8;color:rgba(90,103,216,var(--placeholder-opacity))}.xl\:placeholder-indigo-600::placeholder{--placeholder-opacity:1;color:#5a67d8;color:rgba(90,103,216,var(--placeholder-opacity))}.xl\:placeholder-indigo-700:-ms-input-placeholder{--placeholder-opacity:1;color:#4c51bf;color:rgba(76,81,191,var(--placeholder-opacity))}.xl\:placeholder-indigo-700::-ms-input-placeholder{--placeholder-opacity:1;color:#4c51bf;color:rgba(76,81,191,var(--placeholder-opacity))}.xl\:placeholder-indigo-700::placeholder{--placeholder-opacity:1;color:#4c51bf;color:rgba(76,81,191,var(--placeholder-opacity))}.xl\:placeholder-indigo-800:-ms-input-placeholder{--placeholder-opacity:1;color:#434190;color:rgba(67,65,144,var(--placeholder-opacity))}.xl\:placeholder-indigo-800::-ms-input-placeholder{--placeholder-opacity:1;color:#434190;color:rgba(67,65,144,var(--placeholder-opacity))}.xl\:placeholder-indigo-800::placeholder{--placeholder-opacity:1;color:#434190;color:rgba(67,65,144,var(--placeholder-opacity))}.xl\:placeholder-indigo-900:-ms-input-placeholder{--placeholder-opacity:1;color:#3c366b;color:rgba(60,54,107,var(--placeholder-opacity))}.xl\:placeholder-indigo-900::-ms-input-placeholder{--placeholder-opacity:1;color:#3c366b;color:rgba(60,54,107,var(--placeholder-opacity))}.xl\:placeholder-indigo-900::placeholder{--placeholder-opacity:1;color:#3c366b;color:rgba(60,54,107,var(--placeholder-opacity))}.xl\:placeholder-purple-100:-ms-input-placeholder{--placeholder-opacity:1;color:#faf5ff;color:rgba(250,245,255,var(--placeholder-opacity))}.xl\:placeholder-purple-100::-ms-input-placeholder{--placeholder-opacity:1;color:#faf5ff;color:rgba(250,245,255,var(--placeholder-opacity))}.xl\:placeholder-purple-100::placeholder{--placeholder-opacity:1;color:#faf5ff;color:rgba(250,245,255,var(--placeholder-opacity))}.xl\:placeholder-purple-200:-ms-input-placeholder{--placeholder-opacity:1;color:#e9d8fd;color:rgba(233,216,253,var(--placeholder-opacity))}.xl\:placeholder-purple-200::-ms-input-placeholder{--placeholder-opacity:1;color:#e9d8fd;color:rgba(233,216,253,var(--placeholder-opacity))}.xl\:placeholder-purple-200::placeholder{--placeholder-opacity:1;color:#e9d8fd;color:rgba(233,216,253,var(--placeholder-opacity))}.xl\:placeholder-purple-300:-ms-input-placeholder{--placeholder-opacity:1;color:#d6bcfa;color:rgba(214,188,250,var(--placeholder-opacity))}.xl\:placeholder-purple-300::-ms-input-placeholder{--placeholder-opacity:1;color:#d6bcfa;color:rgba(214,188,250,var(--placeholder-opacity))}.xl\:placeholder-purple-300::placeholder{--placeholder-opacity:1;color:#d6bcfa;color:rgba(214,188,250,var(--placeholder-opacity))}.xl\:placeholder-purple-400:-ms-input-placeholder{--placeholder-opacity:1;color:#b794f4;color:rgba(183,148,244,var(--placeholder-opacity))}.xl\:placeholder-purple-400::-ms-input-placeholder{--placeholder-opacity:1;color:#b794f4;color:rgba(183,148,244,var(--placeholder-opacity))}.xl\:placeholder-purple-400::placeholder{--placeholder-opacity:1;color:#b794f4;color:rgba(183,148,244,var(--placeholder-opacity))}.xl\:placeholder-purple-500:-ms-input-placeholder{--placeholder-opacity:1;color:#9f7aea;color:rgba(159,122,234,var(--placeholder-opacity))}.xl\:placeholder-purple-500::-ms-input-placeholder{--placeholder-opacity:1;color:#9f7aea;color:rgba(159,122,234,var(--placeholder-opacity))}.xl\:placeholder-purple-500::placeholder{--placeholder-opacity:1;color:#9f7aea;color:rgba(159,122,234,var(--placeholder-opacity))}.xl\:placeholder-purple-600:-ms-input-placeholder{--placeholder-opacity:1;color:#805ad5;color:rgba(128,90,213,var(--placeholder-opacity))}.xl\:placeholder-purple-600::-ms-input-placeholder{--placeholder-opacity:1;color:#805ad5;color:rgba(128,90,213,var(--placeholder-opacity))}.xl\:placeholder-purple-600::placeholder{--placeholder-opacity:1;color:#805ad5;color:rgba(128,90,213,var(--placeholder-opacity))}.xl\:placeholder-purple-700:-ms-input-placeholder{--placeholder-opacity:1;color:#6b46c1;color:rgba(107,70,193,var(--placeholder-opacity))}.xl\:placeholder-purple-700::-ms-input-placeholder{--placeholder-opacity:1;color:#6b46c1;color:rgba(107,70,193,var(--placeholder-opacity))}.xl\:placeholder-purple-700::placeholder{--placeholder-opacity:1;color:#6b46c1;color:rgba(107,70,193,var(--placeholder-opacity))}.xl\:placeholder-purple-800:-ms-input-placeholder{--placeholder-opacity:1;color:#553c9a;color:rgba(85,60,154,var(--placeholder-opacity))}.xl\:placeholder-purple-800::-ms-input-placeholder{--placeholder-opacity:1;color:#553c9a;color:rgba(85,60,154,var(--placeholder-opacity))}.xl\:placeholder-purple-800::placeholder{--placeholder-opacity:1;color:#553c9a;color:rgba(85,60,154,var(--placeholder-opacity))}.xl\:placeholder-purple-900:-ms-input-placeholder{--placeholder-opacity:1;color:#44337a;color:rgba(68,51,122,var(--placeholder-opacity))}.xl\:placeholder-purple-900::-ms-input-placeholder{--placeholder-opacity:1;color:#44337a;color:rgba(68,51,122,var(--placeholder-opacity))}.xl\:placeholder-purple-900::placeholder{--placeholder-opacity:1;color:#44337a;color:rgba(68,51,122,var(--placeholder-opacity))}.xl\:placeholder-pink-100:-ms-input-placeholder{--placeholder-opacity:1;color:#fff5f7;color:rgba(255,245,247,var(--placeholder-opacity))}.xl\:placeholder-pink-100::-ms-input-placeholder{--placeholder-opacity:1;color:#fff5f7;color:rgba(255,245,247,var(--placeholder-opacity))}.xl\:placeholder-pink-100::placeholder{--placeholder-opacity:1;color:#fff5f7;color:rgba(255,245,247,var(--placeholder-opacity))}.xl\:placeholder-pink-200:-ms-input-placeholder{--placeholder-opacity:1;color:#fed7e2;color:rgba(254,215,226,var(--placeholder-opacity))}.xl\:placeholder-pink-200::-ms-input-placeholder{--placeholder-opacity:1;color:#fed7e2;color:rgba(254,215,226,var(--placeholder-opacity))}.xl\:placeholder-pink-200::placeholder{--placeholder-opacity:1;color:#fed7e2;color:rgba(254,215,226,var(--placeholder-opacity))}.xl\:placeholder-pink-300:-ms-input-placeholder{--placeholder-opacity:1;color:#fbb6ce;color:rgba(251,182,206,var(--placeholder-opacity))}.xl\:placeholder-pink-300::-ms-input-placeholder{--placeholder-opacity:1;color:#fbb6ce;color:rgba(251,182,206,var(--placeholder-opacity))}.xl\:placeholder-pink-300::placeholder{--placeholder-opacity:1;color:#fbb6ce;color:rgba(251,182,206,var(--placeholder-opacity))}.xl\:placeholder-pink-400:-ms-input-placeholder{--placeholder-opacity:1;color:#f687b3;color:rgba(246,135,179,var(--placeholder-opacity))}.xl\:placeholder-pink-400::-ms-input-placeholder{--placeholder-opacity:1;color:#f687b3;color:rgba(246,135,179,var(--placeholder-opacity))}.xl\:placeholder-pink-400::placeholder{--placeholder-opacity:1;color:#f687b3;color:rgba(246,135,179,var(--placeholder-opacity))}.xl\:placeholder-pink-500:-ms-input-placeholder{--placeholder-opacity:1;color:#ed64a6;color:rgba(237,100,166,var(--placeholder-opacity))}.xl\:placeholder-pink-500::-ms-input-placeholder{--placeholder-opacity:1;color:#ed64a6;color:rgba(237,100,166,var(--placeholder-opacity))}.xl\:placeholder-pink-500::placeholder{--placeholder-opacity:1;color:#ed64a6;color:rgba(237,100,166,var(--placeholder-opacity))}.xl\:placeholder-pink-600:-ms-input-placeholder{--placeholder-opacity:1;color:#d53f8c;color:rgba(213,63,140,var(--placeholder-opacity))}.xl\:placeholder-pink-600::-ms-input-placeholder{--placeholder-opacity:1;color:#d53f8c;color:rgba(213,63,140,var(--placeholder-opacity))}.xl\:placeholder-pink-600::placeholder{--placeholder-opacity:1;color:#d53f8c;color:rgba(213,63,140,var(--placeholder-opacity))}.xl\:placeholder-pink-700:-ms-input-placeholder{--placeholder-opacity:1;color:#b83280;color:rgba(184,50,128,var(--placeholder-opacity))}.xl\:placeholder-pink-700::-ms-input-placeholder{--placeholder-opacity:1;color:#b83280;color:rgba(184,50,128,var(--placeholder-opacity))}.xl\:placeholder-pink-700::placeholder{--placeholder-opacity:1;color:#b83280;color:rgba(184,50,128,var(--placeholder-opacity))}.xl\:placeholder-pink-800:-ms-input-placeholder{--placeholder-opacity:1;color:#97266d;color:rgba(151,38,109,var(--placeholder-opacity))}.xl\:placeholder-pink-800::-ms-input-placeholder{--placeholder-opacity:1;color:#97266d;color:rgba(151,38,109,var(--placeholder-opacity))}.xl\:placeholder-pink-800::placeholder{--placeholder-opacity:1;color:#97266d;color:rgba(151,38,109,var(--placeholder-opacity))}.xl\:placeholder-pink-900:-ms-input-placeholder{--placeholder-opacity:1;color:#702459;color:rgba(112,36,89,var(--placeholder-opacity))}.xl\:placeholder-pink-900::-ms-input-placeholder{--placeholder-opacity:1;color:#702459;color:rgba(112,36,89,var(--placeholder-opacity))}.xl\:placeholder-pink-900::placeholder{--placeholder-opacity:1;color:#702459;color:rgba(112,36,89,var(--placeholder-opacity))}.xl\:focus\:placeholder-transparent:focus:-ms-input-placeholder{color:transparent}.xl\:focus\:placeholder-transparent:focus::-ms-input-placeholder{color:transparent}.xl\:focus\:placeholder-transparent:focus::placeholder{color:transparent}.xl\:focus\:placeholder-current:focus:-ms-input-placeholder{color:currentColor}.xl\:focus\:placeholder-current:focus::-ms-input-placeholder{color:currentColor}.xl\:focus\:placeholder-current:focus::placeholder{color:currentColor}.xl\:focus\:placeholder-black:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#000;color:rgba(0,0,0,var(--placeholder-opacity))}.xl\:focus\:placeholder-black:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#000;color:rgba(0,0,0,var(--placeholder-opacity))}.xl\:focus\:placeholder-black:focus::placeholder{--placeholder-opacity:1;color:#000;color:rgba(0,0,0,var(--placeholder-opacity))}.xl\:focus\:placeholder-white:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#fff;color:rgba(255,255,255,var(--placeholder-opacity))}.xl\:focus\:placeholder-white:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#fff;color:rgba(255,255,255,var(--placeholder-opacity))}.xl\:focus\:placeholder-white:focus::placeholder{--placeholder-opacity:1;color:#fff;color:rgba(255,255,255,var(--placeholder-opacity))}.xl\:focus\:placeholder-gray-100:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#f7fafc;color:rgba(247,250,252,var(--placeholder-opacity))}.xl\:focus\:placeholder-gray-100:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#f7fafc;color:rgba(247,250,252,var(--placeholder-opacity))}.xl\:focus\:placeholder-gray-100:focus::placeholder{--placeholder-opacity:1;color:#f7fafc;color:rgba(247,250,252,var(--placeholder-opacity))}.xl\:focus\:placeholder-gray-200:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#edf2f7;color:rgba(237,242,247,var(--placeholder-opacity))}.xl\:focus\:placeholder-gray-200:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#edf2f7;color:rgba(237,242,247,var(--placeholder-opacity))}.xl\:focus\:placeholder-gray-200:focus::placeholder{--placeholder-opacity:1;color:#edf2f7;color:rgba(237,242,247,var(--placeholder-opacity))}.xl\:focus\:placeholder-gray-300:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#e2e8f0;color:rgba(226,232,240,var(--placeholder-opacity))}.xl\:focus\:placeholder-gray-300:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#e2e8f0;color:rgba(226,232,240,var(--placeholder-opacity))}.xl\:focus\:placeholder-gray-300:focus::placeholder{--placeholder-opacity:1;color:#e2e8f0;color:rgba(226,232,240,var(--placeholder-opacity))}.xl\:focus\:placeholder-gray-400:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#cbd5e0;color:rgba(203,213,224,var(--placeholder-opacity))}.xl\:focus\:placeholder-gray-400:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#cbd5e0;color:rgba(203,213,224,var(--placeholder-opacity))}.xl\:focus\:placeholder-gray-400:focus::placeholder{--placeholder-opacity:1;color:#cbd5e0;color:rgba(203,213,224,var(--placeholder-opacity))}.xl\:focus\:placeholder-gray-500:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#a0aec0;color:rgba(160,174,192,var(--placeholder-opacity))}.xl\:focus\:placeholder-gray-500:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#a0aec0;color:rgba(160,174,192,var(--placeholder-opacity))}.xl\:focus\:placeholder-gray-500:focus::placeholder{--placeholder-opacity:1;color:#a0aec0;color:rgba(160,174,192,var(--placeholder-opacity))}.xl\:focus\:placeholder-gray-600:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#718096;color:rgba(113,128,150,var(--placeholder-opacity))}.xl\:focus\:placeholder-gray-600:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#718096;color:rgba(113,128,150,var(--placeholder-opacity))}.xl\:focus\:placeholder-gray-600:focus::placeholder{--placeholder-opacity:1;color:#718096;color:rgba(113,128,150,var(--placeholder-opacity))}.xl\:focus\:placeholder-gray-700:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#4a5568;color:rgba(74,85,104,var(--placeholder-opacity))}.xl\:focus\:placeholder-gray-700:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#4a5568;color:rgba(74,85,104,var(--placeholder-opacity))}.xl\:focus\:placeholder-gray-700:focus::placeholder{--placeholder-opacity:1;color:#4a5568;color:rgba(74,85,104,var(--placeholder-opacity))}.xl\:focus\:placeholder-gray-800:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#2d3748;color:rgba(45,55,72,var(--placeholder-opacity))}.xl\:focus\:placeholder-gray-800:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#2d3748;color:rgba(45,55,72,var(--placeholder-opacity))}.xl\:focus\:placeholder-gray-800:focus::placeholder{--placeholder-opacity:1;color:#2d3748;color:rgba(45,55,72,var(--placeholder-opacity))}.xl\:focus\:placeholder-gray-900:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#1a202c;color:rgba(26,32,44,var(--placeholder-opacity))}.xl\:focus\:placeholder-gray-900:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#1a202c;color:rgba(26,32,44,var(--placeholder-opacity))}.xl\:focus\:placeholder-gray-900:focus::placeholder{--placeholder-opacity:1;color:#1a202c;color:rgba(26,32,44,var(--placeholder-opacity))}.xl\:focus\:placeholder-red-100:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#fff5f5;color:rgba(255,245,245,var(--placeholder-opacity))}.xl\:focus\:placeholder-red-100:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#fff5f5;color:rgba(255,245,245,var(--placeholder-opacity))}.xl\:focus\:placeholder-red-100:focus::placeholder{--placeholder-opacity:1;color:#fff5f5;color:rgba(255,245,245,var(--placeholder-opacity))}.xl\:focus\:placeholder-red-200:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#fed7d7;color:rgba(254,215,215,var(--placeholder-opacity))}.xl\:focus\:placeholder-red-200:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#fed7d7;color:rgba(254,215,215,var(--placeholder-opacity))}.xl\:focus\:placeholder-red-200:focus::placeholder{--placeholder-opacity:1;color:#fed7d7;color:rgba(254,215,215,var(--placeholder-opacity))}.xl\:focus\:placeholder-red-300:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#feb2b2;color:rgba(254,178,178,var(--placeholder-opacity))}.xl\:focus\:placeholder-red-300:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#feb2b2;color:rgba(254,178,178,var(--placeholder-opacity))}.xl\:focus\:placeholder-red-300:focus::placeholder{--placeholder-opacity:1;color:#feb2b2;color:rgba(254,178,178,var(--placeholder-opacity))}.xl\:focus\:placeholder-red-400:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#fc8181;color:rgba(252,129,129,var(--placeholder-opacity))}.xl\:focus\:placeholder-red-400:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#fc8181;color:rgba(252,129,129,var(--placeholder-opacity))}.xl\:focus\:placeholder-red-400:focus::placeholder{--placeholder-opacity:1;color:#fc8181;color:rgba(252,129,129,var(--placeholder-opacity))}.xl\:focus\:placeholder-red-500:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#f56565;color:rgba(245,101,101,var(--placeholder-opacity))}.xl\:focus\:placeholder-red-500:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#f56565;color:rgba(245,101,101,var(--placeholder-opacity))}.xl\:focus\:placeholder-red-500:focus::placeholder{--placeholder-opacity:1;color:#f56565;color:rgba(245,101,101,var(--placeholder-opacity))}.xl\:focus\:placeholder-red-600:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#e53e3e;color:rgba(229,62,62,var(--placeholder-opacity))}.xl\:focus\:placeholder-red-600:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#e53e3e;color:rgba(229,62,62,var(--placeholder-opacity))}.xl\:focus\:placeholder-red-600:focus::placeholder{--placeholder-opacity:1;color:#e53e3e;color:rgba(229,62,62,var(--placeholder-opacity))}.xl\:focus\:placeholder-red-700:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#c53030;color:rgba(197,48,48,var(--placeholder-opacity))}.xl\:focus\:placeholder-red-700:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#c53030;color:rgba(197,48,48,var(--placeholder-opacity))}.xl\:focus\:placeholder-red-700:focus::placeholder{--placeholder-opacity:1;color:#c53030;color:rgba(197,48,48,var(--placeholder-opacity))}.xl\:focus\:placeholder-red-800:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#9b2c2c;color:rgba(155,44,44,var(--placeholder-opacity))}.xl\:focus\:placeholder-red-800:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#9b2c2c;color:rgba(155,44,44,var(--placeholder-opacity))}.xl\:focus\:placeholder-red-800:focus::placeholder{--placeholder-opacity:1;color:#9b2c2c;color:rgba(155,44,44,var(--placeholder-opacity))}.xl\:focus\:placeholder-red-900:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#742a2a;color:rgba(116,42,42,var(--placeholder-opacity))}.xl\:focus\:placeholder-red-900:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#742a2a;color:rgba(116,42,42,var(--placeholder-opacity))}.xl\:focus\:placeholder-red-900:focus::placeholder{--placeholder-opacity:1;color:#742a2a;color:rgba(116,42,42,var(--placeholder-opacity))}.xl\:focus\:placeholder-orange-100:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#fffaf0;color:rgba(255,250,240,var(--placeholder-opacity))}.xl\:focus\:placeholder-orange-100:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#fffaf0;color:rgba(255,250,240,var(--placeholder-opacity))}.xl\:focus\:placeholder-orange-100:focus::placeholder{--placeholder-opacity:1;color:#fffaf0;color:rgba(255,250,240,var(--placeholder-opacity))}.xl\:focus\:placeholder-orange-200:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#feebc8;color:rgba(254,235,200,var(--placeholder-opacity))}.xl\:focus\:placeholder-orange-200:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#feebc8;color:rgba(254,235,200,var(--placeholder-opacity))}.xl\:focus\:placeholder-orange-200:focus::placeholder{--placeholder-opacity:1;color:#feebc8;color:rgba(254,235,200,var(--placeholder-opacity))}.xl\:focus\:placeholder-orange-300:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#fbd38d;color:rgba(251,211,141,var(--placeholder-opacity))}.xl\:focus\:placeholder-orange-300:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#fbd38d;color:rgba(251,211,141,var(--placeholder-opacity))}.xl\:focus\:placeholder-orange-300:focus::placeholder{--placeholder-opacity:1;color:#fbd38d;color:rgba(251,211,141,var(--placeholder-opacity))}.xl\:focus\:placeholder-orange-400:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#f6ad55;color:rgba(246,173,85,var(--placeholder-opacity))}.xl\:focus\:placeholder-orange-400:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#f6ad55;color:rgba(246,173,85,var(--placeholder-opacity))}.xl\:focus\:placeholder-orange-400:focus::placeholder{--placeholder-opacity:1;color:#f6ad55;color:rgba(246,173,85,var(--placeholder-opacity))}.xl\:focus\:placeholder-orange-500:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#ed8936;color:rgba(237,137,54,var(--placeholder-opacity))}.xl\:focus\:placeholder-orange-500:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#ed8936;color:rgba(237,137,54,var(--placeholder-opacity))}.xl\:focus\:placeholder-orange-500:focus::placeholder{--placeholder-opacity:1;color:#ed8936;color:rgba(237,137,54,var(--placeholder-opacity))}.xl\:focus\:placeholder-orange-600:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#dd6b20;color:rgba(221,107,32,var(--placeholder-opacity))}.xl\:focus\:placeholder-orange-600:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#dd6b20;color:rgba(221,107,32,var(--placeholder-opacity))}.xl\:focus\:placeholder-orange-600:focus::placeholder{--placeholder-opacity:1;color:#dd6b20;color:rgba(221,107,32,var(--placeholder-opacity))}.xl\:focus\:placeholder-orange-700:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#c05621;color:rgba(192,86,33,var(--placeholder-opacity))}.xl\:focus\:placeholder-orange-700:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#c05621;color:rgba(192,86,33,var(--placeholder-opacity))}.xl\:focus\:placeholder-orange-700:focus::placeholder{--placeholder-opacity:1;color:#c05621;color:rgba(192,86,33,var(--placeholder-opacity))}.xl\:focus\:placeholder-orange-800:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#9c4221;color:rgba(156,66,33,var(--placeholder-opacity))}.xl\:focus\:placeholder-orange-800:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#9c4221;color:rgba(156,66,33,var(--placeholder-opacity))}.xl\:focus\:placeholder-orange-800:focus::placeholder{--placeholder-opacity:1;color:#9c4221;color:rgba(156,66,33,var(--placeholder-opacity))}.xl\:focus\:placeholder-orange-900:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#7b341e;color:rgba(123,52,30,var(--placeholder-opacity))}.xl\:focus\:placeholder-orange-900:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#7b341e;color:rgba(123,52,30,var(--placeholder-opacity))}.xl\:focus\:placeholder-orange-900:focus::placeholder{--placeholder-opacity:1;color:#7b341e;color:rgba(123,52,30,var(--placeholder-opacity))}.xl\:focus\:placeholder-yellow-100:focus:-ms-input-placeholder{--placeholder-opacity:1;color:ivory;color:rgba(255,255,240,var(--placeholder-opacity))}.xl\:focus\:placeholder-yellow-100:focus::-ms-input-placeholder{--placeholder-opacity:1;color:ivory;color:rgba(255,255,240,var(--placeholder-opacity))}.xl\:focus\:placeholder-yellow-100:focus::placeholder{--placeholder-opacity:1;color:ivory;color:rgba(255,255,240,var(--placeholder-opacity))}.xl\:focus\:placeholder-yellow-200:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#fefcbf;color:rgba(254,252,191,var(--placeholder-opacity))}.xl\:focus\:placeholder-yellow-200:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#fefcbf;color:rgba(254,252,191,var(--placeholder-opacity))}.xl\:focus\:placeholder-yellow-200:focus::placeholder{--placeholder-opacity:1;color:#fefcbf;color:rgba(254,252,191,var(--placeholder-opacity))}.xl\:focus\:placeholder-yellow-300:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#faf089;color:rgba(250,240,137,var(--placeholder-opacity))}.xl\:focus\:placeholder-yellow-300:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#faf089;color:rgba(250,240,137,var(--placeholder-opacity))}.xl\:focus\:placeholder-yellow-300:focus::placeholder{--placeholder-opacity:1;color:#faf089;color:rgba(250,240,137,var(--placeholder-opacity))}.xl\:focus\:placeholder-yellow-400:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#f6e05e;color:rgba(246,224,94,var(--placeholder-opacity))}.xl\:focus\:placeholder-yellow-400:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#f6e05e;color:rgba(246,224,94,var(--placeholder-opacity))}.xl\:focus\:placeholder-yellow-400:focus::placeholder{--placeholder-opacity:1;color:#f6e05e;color:rgba(246,224,94,var(--placeholder-opacity))}.xl\:focus\:placeholder-yellow-500:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#ecc94b;color:rgba(236,201,75,var(--placeholder-opacity))}.xl\:focus\:placeholder-yellow-500:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#ecc94b;color:rgba(236,201,75,var(--placeholder-opacity))}.xl\:focus\:placeholder-yellow-500:focus::placeholder{--placeholder-opacity:1;color:#ecc94b;color:rgba(236,201,75,var(--placeholder-opacity))}.xl\:focus\:placeholder-yellow-600:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#d69e2e;color:rgba(214,158,46,var(--placeholder-opacity))}.xl\:focus\:placeholder-yellow-600:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#d69e2e;color:rgba(214,158,46,var(--placeholder-opacity))}.xl\:focus\:placeholder-yellow-600:focus::placeholder{--placeholder-opacity:1;color:#d69e2e;color:rgba(214,158,46,var(--placeholder-opacity))}.xl\:focus\:placeholder-yellow-700:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#b7791f;color:rgba(183,121,31,var(--placeholder-opacity))}.xl\:focus\:placeholder-yellow-700:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#b7791f;color:rgba(183,121,31,var(--placeholder-opacity))}.xl\:focus\:placeholder-yellow-700:focus::placeholder{--placeholder-opacity:1;color:#b7791f;color:rgba(183,121,31,var(--placeholder-opacity))}.xl\:focus\:placeholder-yellow-800:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#975a16;color:rgba(151,90,22,var(--placeholder-opacity))}.xl\:focus\:placeholder-yellow-800:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#975a16;color:rgba(151,90,22,var(--placeholder-opacity))}.xl\:focus\:placeholder-yellow-800:focus::placeholder{--placeholder-opacity:1;color:#975a16;color:rgba(151,90,22,var(--placeholder-opacity))}.xl\:focus\:placeholder-yellow-900:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#744210;color:rgba(116,66,16,var(--placeholder-opacity))}.xl\:focus\:placeholder-yellow-900:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#744210;color:rgba(116,66,16,var(--placeholder-opacity))}.xl\:focus\:placeholder-yellow-900:focus::placeholder{--placeholder-opacity:1;color:#744210;color:rgba(116,66,16,var(--placeholder-opacity))}.xl\:focus\:placeholder-green-100:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#f0fff4;color:rgba(240,255,244,var(--placeholder-opacity))}.xl\:focus\:placeholder-green-100:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#f0fff4;color:rgba(240,255,244,var(--placeholder-opacity))}.xl\:focus\:placeholder-green-100:focus::placeholder{--placeholder-opacity:1;color:#f0fff4;color:rgba(240,255,244,var(--placeholder-opacity))}.xl\:focus\:placeholder-green-200:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#c6f6d5;color:rgba(198,246,213,var(--placeholder-opacity))}.xl\:focus\:placeholder-green-200:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#c6f6d5;color:rgba(198,246,213,var(--placeholder-opacity))}.xl\:focus\:placeholder-green-200:focus::placeholder{--placeholder-opacity:1;color:#c6f6d5;color:rgba(198,246,213,var(--placeholder-opacity))}.xl\:focus\:placeholder-green-300:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#9ae6b4;color:rgba(154,230,180,var(--placeholder-opacity))}.xl\:focus\:placeholder-green-300:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#9ae6b4;color:rgba(154,230,180,var(--placeholder-opacity))}.xl\:focus\:placeholder-green-300:focus::placeholder{--placeholder-opacity:1;color:#9ae6b4;color:rgba(154,230,180,var(--placeholder-opacity))}.xl\:focus\:placeholder-green-400:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#68d391;color:rgba(104,211,145,var(--placeholder-opacity))}.xl\:focus\:placeholder-green-400:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#68d391;color:rgba(104,211,145,var(--placeholder-opacity))}.xl\:focus\:placeholder-green-400:focus::placeholder{--placeholder-opacity:1;color:#68d391;color:rgba(104,211,145,var(--placeholder-opacity))}.xl\:focus\:placeholder-green-500:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#48bb78;color:rgba(72,187,120,var(--placeholder-opacity))}.xl\:focus\:placeholder-green-500:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#48bb78;color:rgba(72,187,120,var(--placeholder-opacity))}.xl\:focus\:placeholder-green-500:focus::placeholder{--placeholder-opacity:1;color:#48bb78;color:rgba(72,187,120,var(--placeholder-opacity))}.xl\:focus\:placeholder-green-600:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#38a169;color:rgba(56,161,105,var(--placeholder-opacity))}.xl\:focus\:placeholder-green-600:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#38a169;color:rgba(56,161,105,var(--placeholder-opacity))}.xl\:focus\:placeholder-green-600:focus::placeholder{--placeholder-opacity:1;color:#38a169;color:rgba(56,161,105,var(--placeholder-opacity))}.xl\:focus\:placeholder-green-700:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#2f855a;color:rgba(47,133,90,var(--placeholder-opacity))}.xl\:focus\:placeholder-green-700:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#2f855a;color:rgba(47,133,90,var(--placeholder-opacity))}.xl\:focus\:placeholder-green-700:focus::placeholder{--placeholder-opacity:1;color:#2f855a;color:rgba(47,133,90,var(--placeholder-opacity))}.xl\:focus\:placeholder-green-800:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#276749;color:rgba(39,103,73,var(--placeholder-opacity))}.xl\:focus\:placeholder-green-800:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#276749;color:rgba(39,103,73,var(--placeholder-opacity))}.xl\:focus\:placeholder-green-800:focus::placeholder{--placeholder-opacity:1;color:#276749;color:rgba(39,103,73,var(--placeholder-opacity))}.xl\:focus\:placeholder-green-900:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#22543d;color:rgba(34,84,61,var(--placeholder-opacity))}.xl\:focus\:placeholder-green-900:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#22543d;color:rgba(34,84,61,var(--placeholder-opacity))}.xl\:focus\:placeholder-green-900:focus::placeholder{--placeholder-opacity:1;color:#22543d;color:rgba(34,84,61,var(--placeholder-opacity))}.xl\:focus\:placeholder-teal-100:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#e6fffa;color:rgba(230,255,250,var(--placeholder-opacity))}.xl\:focus\:placeholder-teal-100:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#e6fffa;color:rgba(230,255,250,var(--placeholder-opacity))}.xl\:focus\:placeholder-teal-100:focus::placeholder{--placeholder-opacity:1;color:#e6fffa;color:rgba(230,255,250,var(--placeholder-opacity))}.xl\:focus\:placeholder-teal-200:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#b2f5ea;color:rgba(178,245,234,var(--placeholder-opacity))}.xl\:focus\:placeholder-teal-200:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#b2f5ea;color:rgba(178,245,234,var(--placeholder-opacity))}.xl\:focus\:placeholder-teal-200:focus::placeholder{--placeholder-opacity:1;color:#b2f5ea;color:rgba(178,245,234,var(--placeholder-opacity))}.xl\:focus\:placeholder-teal-300:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#81e6d9;color:rgba(129,230,217,var(--placeholder-opacity))}.xl\:focus\:placeholder-teal-300:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#81e6d9;color:rgba(129,230,217,var(--placeholder-opacity))}.xl\:focus\:placeholder-teal-300:focus::placeholder{--placeholder-opacity:1;color:#81e6d9;color:rgba(129,230,217,var(--placeholder-opacity))}.xl\:focus\:placeholder-teal-400:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#4fd1c5;color:rgba(79,209,197,var(--placeholder-opacity))}.xl\:focus\:placeholder-teal-400:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#4fd1c5;color:rgba(79,209,197,var(--placeholder-opacity))}.xl\:focus\:placeholder-teal-400:focus::placeholder{--placeholder-opacity:1;color:#4fd1c5;color:rgba(79,209,197,var(--placeholder-opacity))}.xl\:focus\:placeholder-teal-500:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#38b2ac;color:rgba(56,178,172,var(--placeholder-opacity))}.xl\:focus\:placeholder-teal-500:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#38b2ac;color:rgba(56,178,172,var(--placeholder-opacity))}.xl\:focus\:placeholder-teal-500:focus::placeholder{--placeholder-opacity:1;color:#38b2ac;color:rgba(56,178,172,var(--placeholder-opacity))}.xl\:focus\:placeholder-teal-600:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#319795;color:rgba(49,151,149,var(--placeholder-opacity))}.xl\:focus\:placeholder-teal-600:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#319795;color:rgba(49,151,149,var(--placeholder-opacity))}.xl\:focus\:placeholder-teal-600:focus::placeholder{--placeholder-opacity:1;color:#319795;color:rgba(49,151,149,var(--placeholder-opacity))}.xl\:focus\:placeholder-teal-700:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#2c7a7b;color:rgba(44,122,123,var(--placeholder-opacity))}.xl\:focus\:placeholder-teal-700:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#2c7a7b;color:rgba(44,122,123,var(--placeholder-opacity))}.xl\:focus\:placeholder-teal-700:focus::placeholder{--placeholder-opacity:1;color:#2c7a7b;color:rgba(44,122,123,var(--placeholder-opacity))}.xl\:focus\:placeholder-teal-800:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#285e61;color:rgba(40,94,97,var(--placeholder-opacity))}.xl\:focus\:placeholder-teal-800:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#285e61;color:rgba(40,94,97,var(--placeholder-opacity))}.xl\:focus\:placeholder-teal-800:focus::placeholder{--placeholder-opacity:1;color:#285e61;color:rgba(40,94,97,var(--placeholder-opacity))}.xl\:focus\:placeholder-teal-900:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#234e52;color:rgba(35,78,82,var(--placeholder-opacity))}.xl\:focus\:placeholder-teal-900:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#234e52;color:rgba(35,78,82,var(--placeholder-opacity))}.xl\:focus\:placeholder-teal-900:focus::placeholder{--placeholder-opacity:1;color:#234e52;color:rgba(35,78,82,var(--placeholder-opacity))}.xl\:focus\:placeholder-blue-100:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#ebf8ff;color:rgba(235,248,255,var(--placeholder-opacity))}.xl\:focus\:placeholder-blue-100:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#ebf8ff;color:rgba(235,248,255,var(--placeholder-opacity))}.xl\:focus\:placeholder-blue-100:focus::placeholder{--placeholder-opacity:1;color:#ebf8ff;color:rgba(235,248,255,var(--placeholder-opacity))}.xl\:focus\:placeholder-blue-200:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#bee3f8;color:rgba(190,227,248,var(--placeholder-opacity))}.xl\:focus\:placeholder-blue-200:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#bee3f8;color:rgba(190,227,248,var(--placeholder-opacity))}.xl\:focus\:placeholder-blue-200:focus::placeholder{--placeholder-opacity:1;color:#bee3f8;color:rgba(190,227,248,var(--placeholder-opacity))}.xl\:focus\:placeholder-blue-300:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#90cdf4;color:rgba(144,205,244,var(--placeholder-opacity))}.xl\:focus\:placeholder-blue-300:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#90cdf4;color:rgba(144,205,244,var(--placeholder-opacity))}.xl\:focus\:placeholder-blue-300:focus::placeholder{--placeholder-opacity:1;color:#90cdf4;color:rgba(144,205,244,var(--placeholder-opacity))}.xl\:focus\:placeholder-blue-400:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#63b3ed;color:rgba(99,179,237,var(--placeholder-opacity))}.xl\:focus\:placeholder-blue-400:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#63b3ed;color:rgba(99,179,237,var(--placeholder-opacity))}.xl\:focus\:placeholder-blue-400:focus::placeholder{--placeholder-opacity:1;color:#63b3ed;color:rgba(99,179,237,var(--placeholder-opacity))}.xl\:focus\:placeholder-blue-500:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#4299e1;color:rgba(66,153,225,var(--placeholder-opacity))}.xl\:focus\:placeholder-blue-500:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#4299e1;color:rgba(66,153,225,var(--placeholder-opacity))}.xl\:focus\:placeholder-blue-500:focus::placeholder{--placeholder-opacity:1;color:#4299e1;color:rgba(66,153,225,var(--placeholder-opacity))}.xl\:focus\:placeholder-blue-600:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#3182ce;color:rgba(49,130,206,var(--placeholder-opacity))}.xl\:focus\:placeholder-blue-600:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#3182ce;color:rgba(49,130,206,var(--placeholder-opacity))}.xl\:focus\:placeholder-blue-600:focus::placeholder{--placeholder-opacity:1;color:#3182ce;color:rgba(49,130,206,var(--placeholder-opacity))}.xl\:focus\:placeholder-blue-700:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#2b6cb0;color:rgba(43,108,176,var(--placeholder-opacity))}.xl\:focus\:placeholder-blue-700:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#2b6cb0;color:rgba(43,108,176,var(--placeholder-opacity))}.xl\:focus\:placeholder-blue-700:focus::placeholder{--placeholder-opacity:1;color:#2b6cb0;color:rgba(43,108,176,var(--placeholder-opacity))}.xl\:focus\:placeholder-blue-800:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#2c5282;color:rgba(44,82,130,var(--placeholder-opacity))}.xl\:focus\:placeholder-blue-800:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#2c5282;color:rgba(44,82,130,var(--placeholder-opacity))}.xl\:focus\:placeholder-blue-800:focus::placeholder{--placeholder-opacity:1;color:#2c5282;color:rgba(44,82,130,var(--placeholder-opacity))}.xl\:focus\:placeholder-blue-900:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#2a4365;color:rgba(42,67,101,var(--placeholder-opacity))}.xl\:focus\:placeholder-blue-900:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#2a4365;color:rgba(42,67,101,var(--placeholder-opacity))}.xl\:focus\:placeholder-blue-900:focus::placeholder{--placeholder-opacity:1;color:#2a4365;color:rgba(42,67,101,var(--placeholder-opacity))}.xl\:focus\:placeholder-indigo-100:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#ebf4ff;color:rgba(235,244,255,var(--placeholder-opacity))}.xl\:focus\:placeholder-indigo-100:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#ebf4ff;color:rgba(235,244,255,var(--placeholder-opacity))}.xl\:focus\:placeholder-indigo-100:focus::placeholder{--placeholder-opacity:1;color:#ebf4ff;color:rgba(235,244,255,var(--placeholder-opacity))}.xl\:focus\:placeholder-indigo-200:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#c3dafe;color:rgba(195,218,254,var(--placeholder-opacity))}.xl\:focus\:placeholder-indigo-200:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#c3dafe;color:rgba(195,218,254,var(--placeholder-opacity))}.xl\:focus\:placeholder-indigo-200:focus::placeholder{--placeholder-opacity:1;color:#c3dafe;color:rgba(195,218,254,var(--placeholder-opacity))}.xl\:focus\:placeholder-indigo-300:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#a3bffa;color:rgba(163,191,250,var(--placeholder-opacity))}.xl\:focus\:placeholder-indigo-300:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#a3bffa;color:rgba(163,191,250,var(--placeholder-opacity))}.xl\:focus\:placeholder-indigo-300:focus::placeholder{--placeholder-opacity:1;color:#a3bffa;color:rgba(163,191,250,var(--placeholder-opacity))}.xl\:focus\:placeholder-indigo-400:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#7f9cf5;color:rgba(127,156,245,var(--placeholder-opacity))}.xl\:focus\:placeholder-indigo-400:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#7f9cf5;color:rgba(127,156,245,var(--placeholder-opacity))}.xl\:focus\:placeholder-indigo-400:focus::placeholder{--placeholder-opacity:1;color:#7f9cf5;color:rgba(127,156,245,var(--placeholder-opacity))}.xl\:focus\:placeholder-indigo-500:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#667eea;color:rgba(102,126,234,var(--placeholder-opacity))}.xl\:focus\:placeholder-indigo-500:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#667eea;color:rgba(102,126,234,var(--placeholder-opacity))}.xl\:focus\:placeholder-indigo-500:focus::placeholder{--placeholder-opacity:1;color:#667eea;color:rgba(102,126,234,var(--placeholder-opacity))}.xl\:focus\:placeholder-indigo-600:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#5a67d8;color:rgba(90,103,216,var(--placeholder-opacity))}.xl\:focus\:placeholder-indigo-600:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#5a67d8;color:rgba(90,103,216,var(--placeholder-opacity))}.xl\:focus\:placeholder-indigo-600:focus::placeholder{--placeholder-opacity:1;color:#5a67d8;color:rgba(90,103,216,var(--placeholder-opacity))}.xl\:focus\:placeholder-indigo-700:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#4c51bf;color:rgba(76,81,191,var(--placeholder-opacity))}.xl\:focus\:placeholder-indigo-700:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#4c51bf;color:rgba(76,81,191,var(--placeholder-opacity))}.xl\:focus\:placeholder-indigo-700:focus::placeholder{--placeholder-opacity:1;color:#4c51bf;color:rgba(76,81,191,var(--placeholder-opacity))}.xl\:focus\:placeholder-indigo-800:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#434190;color:rgba(67,65,144,var(--placeholder-opacity))}.xl\:focus\:placeholder-indigo-800:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#434190;color:rgba(67,65,144,var(--placeholder-opacity))}.xl\:focus\:placeholder-indigo-800:focus::placeholder{--placeholder-opacity:1;color:#434190;color:rgba(67,65,144,var(--placeholder-opacity))}.xl\:focus\:placeholder-indigo-900:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#3c366b;color:rgba(60,54,107,var(--placeholder-opacity))}.xl\:focus\:placeholder-indigo-900:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#3c366b;color:rgba(60,54,107,var(--placeholder-opacity))}.xl\:focus\:placeholder-indigo-900:focus::placeholder{--placeholder-opacity:1;color:#3c366b;color:rgba(60,54,107,var(--placeholder-opacity))}.xl\:focus\:placeholder-purple-100:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#faf5ff;color:rgba(250,245,255,var(--placeholder-opacity))}.xl\:focus\:placeholder-purple-100:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#faf5ff;color:rgba(250,245,255,var(--placeholder-opacity))}.xl\:focus\:placeholder-purple-100:focus::placeholder{--placeholder-opacity:1;color:#faf5ff;color:rgba(250,245,255,var(--placeholder-opacity))}.xl\:focus\:placeholder-purple-200:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#e9d8fd;color:rgba(233,216,253,var(--placeholder-opacity))}.xl\:focus\:placeholder-purple-200:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#e9d8fd;color:rgba(233,216,253,var(--placeholder-opacity))}.xl\:focus\:placeholder-purple-200:focus::placeholder{--placeholder-opacity:1;color:#e9d8fd;color:rgba(233,216,253,var(--placeholder-opacity))}.xl\:focus\:placeholder-purple-300:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#d6bcfa;color:rgba(214,188,250,var(--placeholder-opacity))}.xl\:focus\:placeholder-purple-300:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#d6bcfa;color:rgba(214,188,250,var(--placeholder-opacity))}.xl\:focus\:placeholder-purple-300:focus::placeholder{--placeholder-opacity:1;color:#d6bcfa;color:rgba(214,188,250,var(--placeholder-opacity))}.xl\:focus\:placeholder-purple-400:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#b794f4;color:rgba(183,148,244,var(--placeholder-opacity))}.xl\:focus\:placeholder-purple-400:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#b794f4;color:rgba(183,148,244,var(--placeholder-opacity))}.xl\:focus\:placeholder-purple-400:focus::placeholder{--placeholder-opacity:1;color:#b794f4;color:rgba(183,148,244,var(--placeholder-opacity))}.xl\:focus\:placeholder-purple-500:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#9f7aea;color:rgba(159,122,234,var(--placeholder-opacity))}.xl\:focus\:placeholder-purple-500:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#9f7aea;color:rgba(159,122,234,var(--placeholder-opacity))}.xl\:focus\:placeholder-purple-500:focus::placeholder{--placeholder-opacity:1;color:#9f7aea;color:rgba(159,122,234,var(--placeholder-opacity))}.xl\:focus\:placeholder-purple-600:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#805ad5;color:rgba(128,90,213,var(--placeholder-opacity))}.xl\:focus\:placeholder-purple-600:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#805ad5;color:rgba(128,90,213,var(--placeholder-opacity))}.xl\:focus\:placeholder-purple-600:focus::placeholder{--placeholder-opacity:1;color:#805ad5;color:rgba(128,90,213,var(--placeholder-opacity))}.xl\:focus\:placeholder-purple-700:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#6b46c1;color:rgba(107,70,193,var(--placeholder-opacity))}.xl\:focus\:placeholder-purple-700:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#6b46c1;color:rgba(107,70,193,var(--placeholder-opacity))}.xl\:focus\:placeholder-purple-700:focus::placeholder{--placeholder-opacity:1;color:#6b46c1;color:rgba(107,70,193,var(--placeholder-opacity))}.xl\:focus\:placeholder-purple-800:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#553c9a;color:rgba(85,60,154,var(--placeholder-opacity))}.xl\:focus\:placeholder-purple-800:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#553c9a;color:rgba(85,60,154,var(--placeholder-opacity))}.xl\:focus\:placeholder-purple-800:focus::placeholder{--placeholder-opacity:1;color:#553c9a;color:rgba(85,60,154,var(--placeholder-opacity))}.xl\:focus\:placeholder-purple-900:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#44337a;color:rgba(68,51,122,var(--placeholder-opacity))}.xl\:focus\:placeholder-purple-900:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#44337a;color:rgba(68,51,122,var(--placeholder-opacity))}.xl\:focus\:placeholder-purple-900:focus::placeholder{--placeholder-opacity:1;color:#44337a;color:rgba(68,51,122,var(--placeholder-opacity))}.xl\:focus\:placeholder-pink-100:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#fff5f7;color:rgba(255,245,247,var(--placeholder-opacity))}.xl\:focus\:placeholder-pink-100:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#fff5f7;color:rgba(255,245,247,var(--placeholder-opacity))}.xl\:focus\:placeholder-pink-100:focus::placeholder{--placeholder-opacity:1;color:#fff5f7;color:rgba(255,245,247,var(--placeholder-opacity))}.xl\:focus\:placeholder-pink-200:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#fed7e2;color:rgba(254,215,226,var(--placeholder-opacity))}.xl\:focus\:placeholder-pink-200:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#fed7e2;color:rgba(254,215,226,var(--placeholder-opacity))}.xl\:focus\:placeholder-pink-200:focus::placeholder{--placeholder-opacity:1;color:#fed7e2;color:rgba(254,215,226,var(--placeholder-opacity))}.xl\:focus\:placeholder-pink-300:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#fbb6ce;color:rgba(251,182,206,var(--placeholder-opacity))}.xl\:focus\:placeholder-pink-300:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#fbb6ce;color:rgba(251,182,206,var(--placeholder-opacity))}.xl\:focus\:placeholder-pink-300:focus::placeholder{--placeholder-opacity:1;color:#fbb6ce;color:rgba(251,182,206,var(--placeholder-opacity))}.xl\:focus\:placeholder-pink-400:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#f687b3;color:rgba(246,135,179,var(--placeholder-opacity))}.xl\:focus\:placeholder-pink-400:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#f687b3;color:rgba(246,135,179,var(--placeholder-opacity))}.xl\:focus\:placeholder-pink-400:focus::placeholder{--placeholder-opacity:1;color:#f687b3;color:rgba(246,135,179,var(--placeholder-opacity))}.xl\:focus\:placeholder-pink-500:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#ed64a6;color:rgba(237,100,166,var(--placeholder-opacity))}.xl\:focus\:placeholder-pink-500:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#ed64a6;color:rgba(237,100,166,var(--placeholder-opacity))}.xl\:focus\:placeholder-pink-500:focus::placeholder{--placeholder-opacity:1;color:#ed64a6;color:rgba(237,100,166,var(--placeholder-opacity))}.xl\:focus\:placeholder-pink-600:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#d53f8c;color:rgba(213,63,140,var(--placeholder-opacity))}.xl\:focus\:placeholder-pink-600:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#d53f8c;color:rgba(213,63,140,var(--placeholder-opacity))}.xl\:focus\:placeholder-pink-600:focus::placeholder{--placeholder-opacity:1;color:#d53f8c;color:rgba(213,63,140,var(--placeholder-opacity))}.xl\:focus\:placeholder-pink-700:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#b83280;color:rgba(184,50,128,var(--placeholder-opacity))}.xl\:focus\:placeholder-pink-700:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#b83280;color:rgba(184,50,128,var(--placeholder-opacity))}.xl\:focus\:placeholder-pink-700:focus::placeholder{--placeholder-opacity:1;color:#b83280;color:rgba(184,50,128,var(--placeholder-opacity))}.xl\:focus\:placeholder-pink-800:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#97266d;color:rgba(151,38,109,var(--placeholder-opacity))}.xl\:focus\:placeholder-pink-800:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#97266d;color:rgba(151,38,109,var(--placeholder-opacity))}.xl\:focus\:placeholder-pink-800:focus::placeholder{--placeholder-opacity:1;color:#97266d;color:rgba(151,38,109,var(--placeholder-opacity))}.xl\:focus\:placeholder-pink-900:focus:-ms-input-placeholder{--placeholder-opacity:1;color:#702459;color:rgba(112,36,89,var(--placeholder-opacity))}.xl\:focus\:placeholder-pink-900:focus::-ms-input-placeholder{--placeholder-opacity:1;color:#702459;color:rgba(112,36,89,var(--placeholder-opacity))}.xl\:focus\:placeholder-pink-900:focus::placeholder{--placeholder-opacity:1;color:#702459;color:rgba(112,36,89,var(--placeholder-opacity))}.xl\:placeholder-opacity-0:-ms-input-placeholder{--placeholder-opacity:0}.xl\:placeholder-opacity-0::-ms-input-placeholder{--placeholder-opacity:0}.xl\:placeholder-opacity-0::placeholder{--placeholder-opacity:0}.xl\:placeholder-opacity-25:-ms-input-placeholder{--placeholder-opacity:0.25}.xl\:placeholder-opacity-25::-ms-input-placeholder{--placeholder-opacity:0.25}.xl\:placeholder-opacity-25::placeholder{--placeholder-opacity:0.25}.xl\:placeholder-opacity-50:-ms-input-placeholder{--placeholder-opacity:0.5}.xl\:placeholder-opacity-50::-ms-input-placeholder{--placeholder-opacity:0.5}.xl\:placeholder-opacity-50::placeholder{--placeholder-opacity:0.5}.xl\:placeholder-opacity-75:-ms-input-placeholder{--placeholder-opacity:0.75}.xl\:placeholder-opacity-75::-ms-input-placeholder{--placeholder-opacity:0.75}.xl\:placeholder-opacity-75::placeholder{--placeholder-opacity:0.75}.xl\:placeholder-opacity-100:-ms-input-placeholder{--placeholder-opacity:1}.xl\:placeholder-opacity-100::-ms-input-placeholder{--placeholder-opacity:1}.xl\:placeholder-opacity-100::placeholder{--placeholder-opacity:1}.xl\:focus\:placeholder-opacity-0:focus:-ms-input-placeholder{--placeholder-opacity:0}.xl\:focus\:placeholder-opacity-0:focus::-ms-input-placeholder{--placeholder-opacity:0}.xl\:focus\:placeholder-opacity-0:focus::placeholder{--placeholder-opacity:0}.xl\:focus\:placeholder-opacity-25:focus:-ms-input-placeholder{--placeholder-opacity:0.25}.xl\:focus\:placeholder-opacity-25:focus::-ms-input-placeholder{--placeholder-opacity:0.25}.xl\:focus\:placeholder-opacity-25:focus::placeholder{--placeholder-opacity:0.25}.xl\:focus\:placeholder-opacity-50:focus:-ms-input-placeholder{--placeholder-opacity:0.5}.xl\:focus\:placeholder-opacity-50:focus::-ms-input-placeholder{--placeholder-opacity:0.5}.xl\:focus\:placeholder-opacity-50:focus::placeholder{--placeholder-opacity:0.5}.xl\:focus\:placeholder-opacity-75:focus:-ms-input-placeholder{--placeholder-opacity:0.75}.xl\:focus\:placeholder-opacity-75:focus::-ms-input-placeholder{--placeholder-opacity:0.75}.xl\:focus\:placeholder-opacity-75:focus::placeholder{--placeholder-opacity:0.75}.xl\:focus\:placeholder-opacity-100:focus:-ms-input-placeholder{--placeholder-opacity:1}.xl\:focus\:placeholder-opacity-100:focus::-ms-input-placeholder{--placeholder-opacity:1}.xl\:focus\:placeholder-opacity-100:focus::placeholder{--placeholder-opacity:1}.xl\:pointer-events-none{pointer-events:none}.xl\:pointer-events-auto{pointer-events:auto}.xl\:static{position:static}.xl\:fixed{position:fixed}.xl\:absolute{position:absolute}.xl\:relative{position:relative}.xl\:sticky{position:-webkit-sticky;position:sticky}.xl\:inset-0{top:0;right:0;bottom:0;left:0}.xl\:inset-auto{top:auto;right:auto;bottom:auto;left:auto}.xl\:inset-y-0{top:0;bottom:0}.xl\:inset-x-0{right:0;left:0}.xl\:inset-y-auto{top:auto;bottom:auto}.xl\:inset-x-auto{right:auto;left:auto}.xl\:top-0{top:0}.xl\:right-0{right:0}.xl\:bottom-0{bottom:0}.xl\:left-0{left:0}.xl\:top-auto{top:auto}.xl\:right-auto{right:auto}.xl\:bottom-auto{bottom:auto}.xl\:left-auto{left:auto}.xl\:resize-none{resize:none}.xl\:resize-y{resize:vertical}.xl\:resize-x{resize:horizontal}.xl\:resize{resize:both}.xl\:shadow-xs{box-shadow:0 0 0 1px rgba(0,0,0,.05)}.xl\:shadow-sm{box-shadow:0 1px 2px 0 rgba(0,0,0,.05)}.xl\:shadow{box-shadow:0 1px 3px 0 rgba(0,0,0,.1),0 1px 2px 0 rgba(0,0,0,.06)}.xl\:shadow-md{box-shadow:0 4px 6px -1px rgba(0,0,0,.1),0 2px 4px -1px rgba(0,0,0,.06)}.xl\:shadow-lg{box-shadow:0 10px 15px -3px rgba(0,0,0,.1),0 4px 6px -2px rgba(0,0,0,.05)}.xl\:shadow-xl{box-shadow:0 20px 25px -5px rgba(0,0,0,.1),0 10px 10px -5px rgba(0,0,0,.04)}.xl\:shadow-2xl{box-shadow:0 25px 50px -12px rgba(0,0,0,.25)}.xl\:shadow-inner{box-shadow:inset 0 2px 4px 0 rgba(0,0,0,.06)}.xl\:shadow-outline{box-shadow:0 0 0 3px rgba(66,153,225,.5)}.xl\:shadow-none{box-shadow:none}.xl\:hover\:shadow-xs:hover{box-shadow:0 0 0 1px rgba(0,0,0,.05)}.xl\:hover\:shadow-sm:hover{box-shadow:0 1px 2px 0 rgba(0,0,0,.05)}.xl\:hover\:shadow:hover{box-shadow:0 1px 3px 0 rgba(0,0,0,.1),0 1px 2px 0 rgba(0,0,0,.06)}.xl\:hover\:shadow-md:hover{box-shadow:0 4px 6px -1px rgba(0,0,0,.1),0 2px 4px -1px rgba(0,0,0,.06)}.xl\:hover\:shadow-lg:hover{box-shadow:0 10px 15px -3px rgba(0,0,0,.1),0 4px 6px -2px rgba(0,0,0,.05)}.xl\:hover\:shadow-xl:hover{box-shadow:0 20px 25px -5px rgba(0,0,0,.1),0 10px 10px -5px rgba(0,0,0,.04)}.xl\:hover\:shadow-2xl:hover{box-shadow:0 25px 50px -12px rgba(0,0,0,.25)}.xl\:hover\:shadow-inner:hover{box-shadow:inset 0 2px 4px 0 rgba(0,0,0,.06)}.xl\:hover\:shadow-outline:hover{box-shadow:0 0 0 3px rgba(66,153,225,.5)}.xl\:hover\:shadow-none:hover{box-shadow:none}.xl\:focus\:shadow-xs:focus{box-shadow:0 0 0 1px rgba(0,0,0,.05)}.xl\:focus\:shadow-sm:focus{box-shadow:0 1px 2px 0 rgba(0,0,0,.05)}.xl\:focus\:shadow:focus{box-shadow:0 1px 3px 0 rgba(0,0,0,.1),0 1px 2px 0 rgba(0,0,0,.06)}.xl\:focus\:shadow-md:focus{box-shadow:0 4px 6px -1px rgba(0,0,0,.1),0 2px 4px -1px rgba(0,0,0,.06)}.xl\:focus\:shadow-lg:focus{box-shadow:0 10px 15px -3px rgba(0,0,0,.1),0 4px 6px -2px rgba(0,0,0,.05)}.xl\:focus\:shadow-xl:focus{box-shadow:0 20px 25px -5px rgba(0,0,0,.1),0 10px 10px -5px rgba(0,0,0,.04)}.xl\:focus\:shadow-2xl:focus{box-shadow:0 25px 50px -12px rgba(0,0,0,.25)}.xl\:focus\:shadow-inner:focus{box-shadow:inset 0 2px 4px 0 rgba(0,0,0,.06)}.xl\:focus\:shadow-outline:focus{box-shadow:0 0 0 3px rgba(66,153,225,.5)}.xl\:focus\:shadow-none:focus{box-shadow:none}.xl\:fill-current{fill:currentColor}.xl\:stroke-current{stroke:currentColor}.xl\:stroke-0{stroke-width:0}.xl\:stroke-1{stroke-width:1}.xl\:stroke-2{stroke-width:2}.xl\:table-auto{table-layout:auto}.xl\:table-fixed{table-layout:fixed}.xl\:text-left{text-align:left}.xl\:text-center{text-align:center}.xl\:text-right{text-align:right}.xl\:text-justify{text-align:justify}.xl\:text-transparent{color:transparent}.xl\:text-current{color:currentColor}.xl\:text-black{--text-opacity:1;color:#000;color:rgba(0,0,0,var(--text-opacity))}.xl\:text-white{--text-opacity:1;color:#fff;color:rgba(255,255,255,var(--text-opacity))}.xl\:text-gray-100{--text-opacity:1;color:#f7fafc;color:rgba(247,250,252,var(--text-opacity))}.xl\:text-gray-200{--text-opacity:1;color:#edf2f7;color:rgba(237,242,247,var(--text-opacity))}.xl\:text-gray-300{--text-opacity:1;color:#e2e8f0;color:rgba(226,232,240,var(--text-opacity))}.xl\:text-gray-400{--text-opacity:1;color:#cbd5e0;color:rgba(203,213,224,var(--text-opacity))}.xl\:text-gray-500{--text-opacity:1;color:#a0aec0;color:rgba(160,174,192,var(--text-opacity))}.xl\:text-gray-600{--text-opacity:1;color:#718096;color:rgba(113,128,150,var(--text-opacity))}.xl\:text-gray-700{--text-opacity:1;color:#4a5568;color:rgba(74,85,104,var(--text-opacity))}.xl\:text-gray-800{--text-opacity:1;color:#2d3748;color:rgba(45,55,72,var(--text-opacity))}.xl\:text-gray-900{--text-opacity:1;color:#1a202c;color:rgba(26,32,44,var(--text-opacity))}.xl\:text-red-100{--text-opacity:1;color:#fff5f5;color:rgba(255,245,245,var(--text-opacity))}.xl\:text-red-200{--text-opacity:1;color:#fed7d7;color:rgba(254,215,215,var(--text-opacity))}.xl\:text-red-300{--text-opacity:1;color:#feb2b2;color:rgba(254,178,178,var(--text-opacity))}.xl\:text-red-400{--text-opacity:1;color:#fc8181;color:rgba(252,129,129,var(--text-opacity))}.xl\:text-red-500{--text-opacity:1;color:#f56565;color:rgba(245,101,101,var(--text-opacity))}.xl\:text-red-600{--text-opacity:1;color:#e53e3e;color:rgba(229,62,62,var(--text-opacity))}.xl\:text-red-700{--text-opacity:1;color:#c53030;color:rgba(197,48,48,var(--text-opacity))}.xl\:text-red-800{--text-opacity:1;color:#9b2c2c;color:rgba(155,44,44,var(--text-opacity))}.xl\:text-red-900{--text-opacity:1;color:#742a2a;color:rgba(116,42,42,var(--text-opacity))}.xl\:text-orange-100{--text-opacity:1;color:#fffaf0;color:rgba(255,250,240,var(--text-opacity))}.xl\:text-orange-200{--text-opacity:1;color:#feebc8;color:rgba(254,235,200,var(--text-opacity))}.xl\:text-orange-300{--text-opacity:1;color:#fbd38d;color:rgba(251,211,141,var(--text-opacity))}.xl\:text-orange-400{--text-opacity:1;color:#f6ad55;color:rgba(246,173,85,var(--text-opacity))}.xl\:text-orange-500{--text-opacity:1;color:#ed8936;color:rgba(237,137,54,var(--text-opacity))}.xl\:text-orange-600{--text-opacity:1;color:#dd6b20;color:rgba(221,107,32,var(--text-opacity))}.xl\:text-orange-700{--text-opacity:1;color:#c05621;color:rgba(192,86,33,var(--text-opacity))}.xl\:text-orange-800{--text-opacity:1;color:#9c4221;color:rgba(156,66,33,var(--text-opacity))}.xl\:text-orange-900{--text-opacity:1;color:#7b341e;color:rgba(123,52,30,var(--text-opacity))}.xl\:text-yellow-100{--text-opacity:1;color:ivory;color:rgba(255,255,240,var(--text-opacity))}.xl\:text-yellow-200{--text-opacity:1;color:#fefcbf;color:rgba(254,252,191,var(--text-opacity))}.xl\:text-yellow-300{--text-opacity:1;color:#faf089;color:rgba(250,240,137,var(--text-opacity))}.xl\:text-yellow-400{--text-opacity:1;color:#f6e05e;color:rgba(246,224,94,var(--text-opacity))}.xl\:text-yellow-500{--text-opacity:1;color:#ecc94b;color:rgba(236,201,75,var(--text-opacity))}.xl\:text-yellow-600{--text-opacity:1;color:#d69e2e;color:rgba(214,158,46,var(--text-opacity))}.xl\:text-yellow-700{--text-opacity:1;color:#b7791f;color:rgba(183,121,31,var(--text-opacity))}.xl\:text-yellow-800{--text-opacity:1;color:#975a16;color:rgba(151,90,22,var(--text-opacity))}.xl\:text-yellow-900{--text-opacity:1;color:#744210;color:rgba(116,66,16,var(--text-opacity))}.xl\:text-green-100{--text-opacity:1;color:#f0fff4;color:rgba(240,255,244,var(--text-opacity))}.xl\:text-green-200{--text-opacity:1;color:#c6f6d5;color:rgba(198,246,213,var(--text-opacity))}.xl\:text-green-300{--text-opacity:1;color:#9ae6b4;color:rgba(154,230,180,var(--text-opacity))}.xl\:text-green-400{--text-opacity:1;color:#68d391;color:rgba(104,211,145,var(--text-opacity))}.xl\:text-green-500{--text-opacity:1;color:#48bb78;color:rgba(72,187,120,var(--text-opacity))}.xl\:text-green-600{--text-opacity:1;color:#38a169;color:rgba(56,161,105,var(--text-opacity))}.xl\:text-green-700{--text-opacity:1;color:#2f855a;color:rgba(47,133,90,var(--text-opacity))}.xl\:text-green-800{--text-opacity:1;color:#276749;color:rgba(39,103,73,var(--text-opacity))}.xl\:text-green-900{--text-opacity:1;color:#22543d;color:rgba(34,84,61,var(--text-opacity))}.xl\:text-teal-100{--text-opacity:1;color:#e6fffa;color:rgba(230,255,250,var(--text-opacity))}.xl\:text-teal-200{--text-opacity:1;color:#b2f5ea;color:rgba(178,245,234,var(--text-opacity))}.xl\:text-teal-300{--text-opacity:1;color:#81e6d9;color:rgba(129,230,217,var(--text-opacity))}.xl\:text-teal-400{--text-opacity:1;color:#4fd1c5;color:rgba(79,209,197,var(--text-opacity))}.xl\:text-teal-500{--text-opacity:1;color:#38b2ac;color:rgba(56,178,172,var(--text-opacity))}.xl\:text-teal-600{--text-opacity:1;color:#319795;color:rgba(49,151,149,var(--text-opacity))}.xl\:text-teal-700{--text-opacity:1;color:#2c7a7b;color:rgba(44,122,123,var(--text-opacity))}.xl\:text-teal-800{--text-opacity:1;color:#285e61;color:rgba(40,94,97,var(--text-opacity))}.xl\:text-teal-900{--text-opacity:1;color:#234e52;color:rgba(35,78,82,var(--text-opacity))}.xl\:text-blue-100{--text-opacity:1;color:#ebf8ff;color:rgba(235,248,255,var(--text-opacity))}.xl\:text-blue-200{--text-opacity:1;color:#bee3f8;color:rgba(190,227,248,var(--text-opacity))}.xl\:text-blue-300{--text-opacity:1;color:#90cdf4;color:rgba(144,205,244,var(--text-opacity))}.xl\:text-blue-400{--text-opacity:1;color:#63b3ed;color:rgba(99,179,237,var(--text-opacity))}.xl\:text-blue-500{--text-opacity:1;color:#4299e1;color:rgba(66,153,225,var(--text-opacity))}.xl\:text-blue-600{--text-opacity:1;color:#3182ce;color:rgba(49,130,206,var(--text-opacity))}.xl\:text-blue-700{--text-opacity:1;color:#2b6cb0;color:rgba(43,108,176,var(--text-opacity))}.xl\:text-blue-800{--text-opacity:1;color:#2c5282;color:rgba(44,82,130,var(--text-opacity))}.xl\:text-blue-900{--text-opacity:1;color:#2a4365;color:rgba(42,67,101,var(--text-opacity))}.xl\:text-indigo-100{--text-opacity:1;color:#ebf4ff;color:rgba(235,244,255,var(--text-opacity))}.xl\:text-indigo-200{--text-opacity:1;color:#c3dafe;color:rgba(195,218,254,var(--text-opacity))}.xl\:text-indigo-300{--text-opacity:1;color:#a3bffa;color:rgba(163,191,250,var(--text-opacity))}.xl\:text-indigo-400{--text-opacity:1;color:#7f9cf5;color:rgba(127,156,245,var(--text-opacity))}.xl\:text-indigo-500{--text-opacity:1;color:#667eea;color:rgba(102,126,234,var(--text-opacity))}.xl\:text-indigo-600{--text-opacity:1;color:#5a67d8;color:rgba(90,103,216,var(--text-opacity))}.xl\:text-indigo-700{--text-opacity:1;color:#4c51bf;color:rgba(76,81,191,var(--text-opacity))}.xl\:text-indigo-800{--text-opacity:1;color:#434190;color:rgba(67,65,144,var(--text-opacity))}.xl\:text-indigo-900{--text-opacity:1;color:#3c366b;color:rgba(60,54,107,var(--text-opacity))}.xl\:text-purple-100{--text-opacity:1;color:#faf5ff;color:rgba(250,245,255,var(--text-opacity))}.xl\:text-purple-200{--text-opacity:1;color:#e9d8fd;color:rgba(233,216,253,var(--text-opacity))}.xl\:text-purple-300{--text-opacity:1;color:#d6bcfa;color:rgba(214,188,250,var(--text-opacity))}.xl\:text-purple-400{--text-opacity:1;color:#b794f4;color:rgba(183,148,244,var(--text-opacity))}.xl\:text-purple-500{--text-opacity:1;color:#9f7aea;color:rgba(159,122,234,var(--text-opacity))}.xl\:text-purple-600{--text-opacity:1;color:#805ad5;color:rgba(128,90,213,var(--text-opacity))}.xl\:text-purple-700{--text-opacity:1;color:#6b46c1;color:rgba(107,70,193,var(--text-opacity))}.xl\:text-purple-800{--text-opacity:1;color:#553c9a;color:rgba(85,60,154,var(--text-opacity))}.xl\:text-purple-900{--text-opacity:1;color:#44337a;color:rgba(68,51,122,var(--text-opacity))}.xl\:text-pink-100{--text-opacity:1;color:#fff5f7;color:rgba(255,245,247,var(--text-opacity))}.xl\:text-pink-200{--text-opacity:1;color:#fed7e2;color:rgba(254,215,226,var(--text-opacity))}.xl\:text-pink-300{--text-opacity:1;color:#fbb6ce;color:rgba(251,182,206,var(--text-opacity))}.xl\:text-pink-400{--text-opacity:1;color:#f687b3;color:rgba(246,135,179,var(--text-opacity))}.xl\:text-pink-500{--text-opacity:1;color:#ed64a6;color:rgba(237,100,166,var(--text-opacity))}.xl\:text-pink-600{--text-opacity:1;color:#d53f8c;color:rgba(213,63,140,var(--text-opacity))}.xl\:text-pink-700{--text-opacity:1;color:#b83280;color:rgba(184,50,128,var(--text-opacity))}.xl\:text-pink-800{--text-opacity:1;color:#97266d;color:rgba(151,38,109,var(--text-opacity))}.xl\:text-pink-900{--text-opacity:1;color:#702459;color:rgba(112,36,89,var(--text-opacity))}.xl\:hover\:text-transparent:hover{color:transparent}.xl\:hover\:text-current:hover{color:currentColor}.xl\:hover\:text-black:hover{--text-opacity:1;color:#000;color:rgba(0,0,0,var(--text-opacity))}.xl\:hover\:text-white:hover{--text-opacity:1;color:#fff;color:rgba(255,255,255,var(--text-opacity))}.xl\:hover\:text-gray-100:hover{--text-opacity:1;color:#f7fafc;color:rgba(247,250,252,var(--text-opacity))}.xl\:hover\:text-gray-200:hover{--text-opacity:1;color:#edf2f7;color:rgba(237,242,247,var(--text-opacity))}.xl\:hover\:text-gray-300:hover{--text-opacity:1;color:#e2e8f0;color:rgba(226,232,240,var(--text-opacity))}.xl\:hover\:text-gray-400:hover{--text-opacity:1;color:#cbd5e0;color:rgba(203,213,224,var(--text-opacity))}.xl\:hover\:text-gray-500:hover{--text-opacity:1;color:#a0aec0;color:rgba(160,174,192,var(--text-opacity))}.xl\:hover\:text-gray-600:hover{--text-opacity:1;color:#718096;color:rgba(113,128,150,var(--text-opacity))}.xl\:hover\:text-gray-700:hover{--text-opacity:1;color:#4a5568;color:rgba(74,85,104,var(--text-opacity))}.xl\:hover\:text-gray-800:hover{--text-opacity:1;color:#2d3748;color:rgba(45,55,72,var(--text-opacity))}.xl\:hover\:text-gray-900:hover{--text-opacity:1;color:#1a202c;color:rgba(26,32,44,var(--text-opacity))}.xl\:hover\:text-red-100:hover{--text-opacity:1;color:#fff5f5;color:rgba(255,245,245,var(--text-opacity))}.xl\:hover\:text-red-200:hover{--text-opacity:1;color:#fed7d7;color:rgba(254,215,215,var(--text-opacity))}.xl\:hover\:text-red-300:hover{--text-opacity:1;color:#feb2b2;color:rgba(254,178,178,var(--text-opacity))}.xl\:hover\:text-red-400:hover{--text-opacity:1;color:#fc8181;color:rgba(252,129,129,var(--text-opacity))}.xl\:hover\:text-red-500:hover{--text-opacity:1;color:#f56565;color:rgba(245,101,101,var(--text-opacity))}.xl\:hover\:text-red-600:hover{--text-opacity:1;color:#e53e3e;color:rgba(229,62,62,var(--text-opacity))}.xl\:hover\:text-red-700:hover{--text-opacity:1;color:#c53030;color:rgba(197,48,48,var(--text-opacity))}.xl\:hover\:text-red-800:hover{--text-opacity:1;color:#9b2c2c;color:rgba(155,44,44,var(--text-opacity))}.xl\:hover\:text-red-900:hover{--text-opacity:1;color:#742a2a;color:rgba(116,42,42,var(--text-opacity))}.xl\:hover\:text-orange-100:hover{--text-opacity:1;color:#fffaf0;color:rgba(255,250,240,var(--text-opacity))}.xl\:hover\:text-orange-200:hover{--text-opacity:1;color:#feebc8;color:rgba(254,235,200,var(--text-opacity))}.xl\:hover\:text-orange-300:hover{--text-opacity:1;color:#fbd38d;color:rgba(251,211,141,var(--text-opacity))}.xl\:hover\:text-orange-400:hover{--text-opacity:1;color:#f6ad55;color:rgba(246,173,85,var(--text-opacity))}.xl\:hover\:text-orange-500:hover{--text-opacity:1;color:#ed8936;color:rgba(237,137,54,var(--text-opacity))}.xl\:hover\:text-orange-600:hover{--text-opacity:1;color:#dd6b20;color:rgba(221,107,32,var(--text-opacity))}.xl\:hover\:text-orange-700:hover{--text-opacity:1;color:#c05621;color:rgba(192,86,33,var(--text-opacity))}.xl\:hover\:text-orange-800:hover{--text-opacity:1;color:#9c4221;color:rgba(156,66,33,var(--text-opacity))}.xl\:hover\:text-orange-900:hover{--text-opacity:1;color:#7b341e;color:rgba(123,52,30,var(--text-opacity))}.xl\:hover\:text-yellow-100:hover{--text-opacity:1;color:ivory;color:rgba(255,255,240,var(--text-opacity))}.xl\:hover\:text-yellow-200:hover{--text-opacity:1;color:#fefcbf;color:rgba(254,252,191,var(--text-opacity))}.xl\:hover\:text-yellow-300:hover{--text-opacity:1;color:#faf089;color:rgba(250,240,137,var(--text-opacity))}.xl\:hover\:text-yellow-400:hover{--text-opacity:1;color:#f6e05e;color:rgba(246,224,94,var(--text-opacity))}.xl\:hover\:text-yellow-500:hover{--text-opacity:1;color:#ecc94b;color:rgba(236,201,75,var(--text-opacity))}.xl\:hover\:text-yellow-600:hover{--text-opacity:1;color:#d69e2e;color:rgba(214,158,46,var(--text-opacity))}.xl\:hover\:text-yellow-700:hover{--text-opacity:1;color:#b7791f;color:rgba(183,121,31,var(--text-opacity))}.xl\:hover\:text-yellow-800:hover{--text-opacity:1;color:#975a16;color:rgba(151,90,22,var(--text-opacity))}.xl\:hover\:text-yellow-900:hover{--text-opacity:1;color:#744210;color:rgba(116,66,16,var(--text-opacity))}.xl\:hover\:text-green-100:hover{--text-opacity:1;color:#f0fff4;color:rgba(240,255,244,var(--text-opacity))}.xl\:hover\:text-green-200:hover{--text-opacity:1;color:#c6f6d5;color:rgba(198,246,213,var(--text-opacity))}.xl\:hover\:text-green-300:hover{--text-opacity:1;color:#9ae6b4;color:rgba(154,230,180,var(--text-opacity))}.xl\:hover\:text-green-400:hover{--text-opacity:1;color:#68d391;color:rgba(104,211,145,var(--text-opacity))}.xl\:hover\:text-green-500:hover{--text-opacity:1;color:#48bb78;color:rgba(72,187,120,var(--text-opacity))}.xl\:hover\:text-green-600:hover{--text-opacity:1;color:#38a169;color:rgba(56,161,105,var(--text-opacity))}.xl\:hover\:text-green-700:hover{--text-opacity:1;color:#2f855a;color:rgba(47,133,90,var(--text-opacity))}.xl\:hover\:text-green-800:hover{--text-opacity:1;color:#276749;color:rgba(39,103,73,var(--text-opacity))}.xl\:hover\:text-green-900:hover{--text-opacity:1;color:#22543d;color:rgba(34,84,61,var(--text-opacity))}.xl\:hover\:text-teal-100:hover{--text-opacity:1;color:#e6fffa;color:rgba(230,255,250,var(--text-opacity))}.xl\:hover\:text-teal-200:hover{--text-opacity:1;color:#b2f5ea;color:rgba(178,245,234,var(--text-opacity))}.xl\:hover\:text-teal-300:hover{--text-opacity:1;color:#81e6d9;color:rgba(129,230,217,var(--text-opacity))}.xl\:hover\:text-teal-400:hover{--text-opacity:1;color:#4fd1c5;color:rgba(79,209,197,var(--text-opacity))}.xl\:hover\:text-teal-500:hover{--text-opacity:1;color:#38b2ac;color:rgba(56,178,172,var(--text-opacity))}.xl\:hover\:text-teal-600:hover{--text-opacity:1;color:#319795;color:rgba(49,151,149,var(--text-opacity))}.xl\:hover\:text-teal-700:hover{--text-opacity:1;color:#2c7a7b;color:rgba(44,122,123,var(--text-opacity))}.xl\:hover\:text-teal-800:hover{--text-opacity:1;color:#285e61;color:rgba(40,94,97,var(--text-opacity))}.xl\:hover\:text-teal-900:hover{--text-opacity:1;color:#234e52;color:rgba(35,78,82,var(--text-opacity))}.xl\:hover\:text-blue-100:hover{--text-opacity:1;color:#ebf8ff;color:rgba(235,248,255,var(--text-opacity))}.xl\:hover\:text-blue-200:hover{--text-opacity:1;color:#bee3f8;color:rgba(190,227,248,var(--text-opacity))}.xl\:hover\:text-blue-300:hover{--text-opacity:1;color:#90cdf4;color:rgba(144,205,244,var(--text-opacity))}.xl\:hover\:text-blue-400:hover{--text-opacity:1;color:#63b3ed;color:rgba(99,179,237,var(--text-opacity))}.xl\:hover\:text-blue-500:hover{--text-opacity:1;color:#4299e1;color:rgba(66,153,225,var(--text-opacity))}.xl\:hover\:text-blue-600:hover{--text-opacity:1;color:#3182ce;color:rgba(49,130,206,var(--text-opacity))}.xl\:hover\:text-blue-700:hover{--text-opacity:1;color:#2b6cb0;color:rgba(43,108,176,var(--text-opacity))}.xl\:hover\:text-blue-800:hover{--text-opacity:1;color:#2c5282;color:rgba(44,82,130,var(--text-opacity))}.xl\:hover\:text-blue-900:hover{--text-opacity:1;color:#2a4365;color:rgba(42,67,101,var(--text-opacity))}.xl\:hover\:text-indigo-100:hover{--text-opacity:1;color:#ebf4ff;color:rgba(235,244,255,var(--text-opacity))}.xl\:hover\:text-indigo-200:hover{--text-opacity:1;color:#c3dafe;color:rgba(195,218,254,var(--text-opacity))}.xl\:hover\:text-indigo-300:hover{--text-opacity:1;color:#a3bffa;color:rgba(163,191,250,var(--text-opacity))}.xl\:hover\:text-indigo-400:hover{--text-opacity:1;color:#7f9cf5;color:rgba(127,156,245,var(--text-opacity))}.xl\:hover\:text-indigo-500:hover{--text-opacity:1;color:#667eea;color:rgba(102,126,234,var(--text-opacity))}.xl\:hover\:text-indigo-600:hover{--text-opacity:1;color:#5a67d8;color:rgba(90,103,216,var(--text-opacity))}.xl\:hover\:text-indigo-700:hover{--text-opacity:1;color:#4c51bf;color:rgba(76,81,191,var(--text-opacity))}.xl\:hover\:text-indigo-800:hover{--text-opacity:1;color:#434190;color:rgba(67,65,144,var(--text-opacity))}.xl\:hover\:text-indigo-900:hover{--text-opacity:1;color:#3c366b;color:rgba(60,54,107,var(--text-opacity))}.xl\:hover\:text-purple-100:hover{--text-opacity:1;color:#faf5ff;color:rgba(250,245,255,var(--text-opacity))}.xl\:hover\:text-purple-200:hover{--text-opacity:1;color:#e9d8fd;color:rgba(233,216,253,var(--text-opacity))}.xl\:hover\:text-purple-300:hover{--text-opacity:1;color:#d6bcfa;color:rgba(214,188,250,var(--text-opacity))}.xl\:hover\:text-purple-400:hover{--text-opacity:1;color:#b794f4;color:rgba(183,148,244,var(--text-opacity))}.xl\:hover\:text-purple-500:hover{--text-opacity:1;color:#9f7aea;color:rgba(159,122,234,var(--text-opacity))}.xl\:hover\:text-purple-600:hover{--text-opacity:1;color:#805ad5;color:rgba(128,90,213,var(--text-opacity))}.xl\:hover\:text-purple-700:hover{--text-opacity:1;color:#6b46c1;color:rgba(107,70,193,var(--text-opacity))}.xl\:hover\:text-purple-800:hover{--text-opacity:1;color:#553c9a;color:rgba(85,60,154,var(--text-opacity))}.xl\:hover\:text-purple-900:hover{--text-opacity:1;color:#44337a;color:rgba(68,51,122,var(--text-opacity))}.xl\:hover\:text-pink-100:hover{--text-opacity:1;color:#fff5f7;color:rgba(255,245,247,var(--text-opacity))}.xl\:hover\:text-pink-200:hover{--text-opacity:1;color:#fed7e2;color:rgba(254,215,226,var(--text-opacity))}.xl\:hover\:text-pink-300:hover{--text-opacity:1;color:#fbb6ce;color:rgba(251,182,206,var(--text-opacity))}.xl\:hover\:text-pink-400:hover{--text-opacity:1;color:#f687b3;color:rgba(246,135,179,var(--text-opacity))}.xl\:hover\:text-pink-500:hover{--text-opacity:1;color:#ed64a6;color:rgba(237,100,166,var(--text-opacity))}.xl\:hover\:text-pink-600:hover{--text-opacity:1;color:#d53f8c;color:rgba(213,63,140,var(--text-opacity))}.xl\:hover\:text-pink-700:hover{--text-opacity:1;color:#b83280;color:rgba(184,50,128,var(--text-opacity))}.xl\:hover\:text-pink-800:hover{--text-opacity:1;color:#97266d;color:rgba(151,38,109,var(--text-opacity))}.xl\:hover\:text-pink-900:hover{--text-opacity:1;color:#702459;color:rgba(112,36,89,var(--text-opacity))}.xl\:focus\:text-transparent:focus{color:transparent}.xl\:focus\:text-current:focus{color:currentColor}.xl\:focus\:text-black:focus{--text-opacity:1;color:#000;color:rgba(0,0,0,var(--text-opacity))}.xl\:focus\:text-white:focus{--text-opacity:1;color:#fff;color:rgba(255,255,255,var(--text-opacity))}.xl\:focus\:text-gray-100:focus{--text-opacity:1;color:#f7fafc;color:rgba(247,250,252,var(--text-opacity))}.xl\:focus\:text-gray-200:focus{--text-opacity:1;color:#edf2f7;color:rgba(237,242,247,var(--text-opacity))}.xl\:focus\:text-gray-300:focus{--text-opacity:1;color:#e2e8f0;color:rgba(226,232,240,var(--text-opacity))}.xl\:focus\:text-gray-400:focus{--text-opacity:1;color:#cbd5e0;color:rgba(203,213,224,var(--text-opacity))}.xl\:focus\:text-gray-500:focus{--text-opacity:1;color:#a0aec0;color:rgba(160,174,192,var(--text-opacity))}.xl\:focus\:text-gray-600:focus{--text-opacity:1;color:#718096;color:rgba(113,128,150,var(--text-opacity))}.xl\:focus\:text-gray-700:focus{--text-opacity:1;color:#4a5568;color:rgba(74,85,104,var(--text-opacity))}.xl\:focus\:text-gray-800:focus{--text-opacity:1;color:#2d3748;color:rgba(45,55,72,var(--text-opacity))}.xl\:focus\:text-gray-900:focus{--text-opacity:1;color:#1a202c;color:rgba(26,32,44,var(--text-opacity))}.xl\:focus\:text-red-100:focus{--text-opacity:1;color:#fff5f5;color:rgba(255,245,245,var(--text-opacity))}.xl\:focus\:text-red-200:focus{--text-opacity:1;color:#fed7d7;color:rgba(254,215,215,var(--text-opacity))}.xl\:focus\:text-red-300:focus{--text-opacity:1;color:#feb2b2;color:rgba(254,178,178,var(--text-opacity))}.xl\:focus\:text-red-400:focus{--text-opacity:1;color:#fc8181;color:rgba(252,129,129,var(--text-opacity))}.xl\:focus\:text-red-500:focus{--text-opacity:1;color:#f56565;color:rgba(245,101,101,var(--text-opacity))}.xl\:focus\:text-red-600:focus{--text-opacity:1;color:#e53e3e;color:rgba(229,62,62,var(--text-opacity))}.xl\:focus\:text-red-700:focus{--text-opacity:1;color:#c53030;color:rgba(197,48,48,var(--text-opacity))}.xl\:focus\:text-red-800:focus{--text-opacity:1;color:#9b2c2c;color:rgba(155,44,44,var(--text-opacity))}.xl\:focus\:text-red-900:focus{--text-opacity:1;color:#742a2a;color:rgba(116,42,42,var(--text-opacity))}.xl\:focus\:text-orange-100:focus{--text-opacity:1;color:#fffaf0;color:rgba(255,250,240,var(--text-opacity))}.xl\:focus\:text-orange-200:focus{--text-opacity:1;color:#feebc8;color:rgba(254,235,200,var(--text-opacity))}.xl\:focus\:text-orange-300:focus{--text-opacity:1;color:#fbd38d;color:rgba(251,211,141,var(--text-opacity))}.xl\:focus\:text-orange-400:focus{--text-opacity:1;color:#f6ad55;color:rgba(246,173,85,var(--text-opacity))}.xl\:focus\:text-orange-500:focus{--text-opacity:1;color:#ed8936;color:rgba(237,137,54,var(--text-opacity))}.xl\:focus\:text-orange-600:focus{--text-opacity:1;color:#dd6b20;color:rgba(221,107,32,var(--text-opacity))}.xl\:focus\:text-orange-700:focus{--text-opacity:1;color:#c05621;color:rgba(192,86,33,var(--text-opacity))}.xl\:focus\:text-orange-800:focus{--text-opacity:1;color:#9c4221;color:rgba(156,66,33,var(--text-opacity))}.xl\:focus\:text-orange-900:focus{--text-opacity:1;color:#7b341e;color:rgba(123,52,30,var(--text-opacity))}.xl\:focus\:text-yellow-100:focus{--text-opacity:1;color:ivory;color:rgba(255,255,240,var(--text-opacity))}.xl\:focus\:text-yellow-200:focus{--text-opacity:1;color:#fefcbf;color:rgba(254,252,191,var(--text-opacity))}.xl\:focus\:text-yellow-300:focus{--text-opacity:1;color:#faf089;color:rgba(250,240,137,var(--text-opacity))}.xl\:focus\:text-yellow-400:focus{--text-opacity:1;color:#f6e05e;color:rgba(246,224,94,var(--text-opacity))}.xl\:focus\:text-yellow-500:focus{--text-opacity:1;color:#ecc94b;color:rgba(236,201,75,var(--text-opacity))}.xl\:focus\:text-yellow-600:focus{--text-opacity:1;color:#d69e2e;color:rgba(214,158,46,var(--text-opacity))}.xl\:focus\:text-yellow-700:focus{--text-opacity:1;color:#b7791f;color:rgba(183,121,31,var(--text-opacity))}.xl\:focus\:text-yellow-800:focus{--text-opacity:1;color:#975a16;color:rgba(151,90,22,var(--text-opacity))}.xl\:focus\:text-yellow-900:focus{--text-opacity:1;color:#744210;color:rgba(116,66,16,var(--text-opacity))}.xl\:focus\:text-green-100:focus{--text-opacity:1;color:#f0fff4;color:rgba(240,255,244,var(--text-opacity))}.xl\:focus\:text-green-200:focus{--text-opacity:1;color:#c6f6d5;color:rgba(198,246,213,var(--text-opacity))}.xl\:focus\:text-green-300:focus{--text-opacity:1;color:#9ae6b4;color:rgba(154,230,180,var(--text-opacity))}.xl\:focus\:text-green-400:focus{--text-opacity:1;color:#68d391;color:rgba(104,211,145,var(--text-opacity))}.xl\:focus\:text-green-500:focus{--text-opacity:1;color:#48bb78;color:rgba(72,187,120,var(--text-opacity))}.xl\:focus\:text-green-600:focus{--text-opacity:1;color:#38a169;color:rgba(56,161,105,var(--text-opacity))}.xl\:focus\:text-green-700:focus{--text-opacity:1;color:#2f855a;color:rgba(47,133,90,var(--text-opacity))}.xl\:focus\:text-green-800:focus{--text-opacity:1;color:#276749;color:rgba(39,103,73,var(--text-opacity))}.xl\:focus\:text-green-900:focus{--text-opacity:1;color:#22543d;color:rgba(34,84,61,var(--text-opacity))}.xl\:focus\:text-teal-100:focus{--text-opacity:1;color:#e6fffa;color:rgba(230,255,250,var(--text-opacity))}.xl\:focus\:text-teal-200:focus{--text-opacity:1;color:#b2f5ea;color:rgba(178,245,234,var(--text-opacity))}.xl\:focus\:text-teal-300:focus{--text-opacity:1;color:#81e6d9;color:rgba(129,230,217,var(--text-opacity))}.xl\:focus\:text-teal-400:focus{--text-opacity:1;color:#4fd1c5;color:rgba(79,209,197,var(--text-opacity))}.xl\:focus\:text-teal-500:focus{--text-opacity:1;color:#38b2ac;color:rgba(56,178,172,var(--text-opacity))}.xl\:focus\:text-teal-600:focus{--text-opacity:1;color:#319795;color:rgba(49,151,149,var(--text-opacity))}.xl\:focus\:text-teal-700:focus{--text-opacity:1;color:#2c7a7b;color:rgba(44,122,123,var(--text-opacity))}.xl\:focus\:text-teal-800:focus{--text-opacity:1;color:#285e61;color:rgba(40,94,97,var(--text-opacity))}.xl\:focus\:text-teal-900:focus{--text-opacity:1;color:#234e52;color:rgba(35,78,82,var(--text-opacity))}.xl\:focus\:text-blue-100:focus{--text-opacity:1;color:#ebf8ff;color:rgba(235,248,255,var(--text-opacity))}.xl\:focus\:text-blue-200:focus{--text-opacity:1;color:#bee3f8;color:rgba(190,227,248,var(--text-opacity))}.xl\:focus\:text-blue-300:focus{--text-opacity:1;color:#90cdf4;color:rgba(144,205,244,var(--text-opacity))}.xl\:focus\:text-blue-400:focus{--text-opacity:1;color:#63b3ed;color:rgba(99,179,237,var(--text-opacity))}.xl\:focus\:text-blue-500:focus{--text-opacity:1;color:#4299e1;color:rgba(66,153,225,var(--text-opacity))}.xl\:focus\:text-blue-600:focus{--text-opacity:1;color:#3182ce;color:rgba(49,130,206,var(--text-opacity))}.xl\:focus\:text-blue-700:focus{--text-opacity:1;color:#2b6cb0;color:rgba(43,108,176,var(--text-opacity))}.xl\:focus\:text-blue-800:focus{--text-opacity:1;color:#2c5282;color:rgba(44,82,130,var(--text-opacity))}.xl\:focus\:text-blue-900:focus{--text-opacity:1;color:#2a4365;color:rgba(42,67,101,var(--text-opacity))}.xl\:focus\:text-indigo-100:focus{--text-opacity:1;color:#ebf4ff;color:rgba(235,244,255,var(--text-opacity))}.xl\:focus\:text-indigo-200:focus{--text-opacity:1;color:#c3dafe;color:rgba(195,218,254,var(--text-opacity))}.xl\:focus\:text-indigo-300:focus{--text-opacity:1;color:#a3bffa;color:rgba(163,191,250,var(--text-opacity))}.xl\:focus\:text-indigo-400:focus{--text-opacity:1;color:#7f9cf5;color:rgba(127,156,245,var(--text-opacity))}.xl\:focus\:text-indigo-500:focus{--text-opacity:1;color:#667eea;color:rgba(102,126,234,var(--text-opacity))}.xl\:focus\:text-indigo-600:focus{--text-opacity:1;color:#5a67d8;color:rgba(90,103,216,var(--text-opacity))}.xl\:focus\:text-indigo-700:focus{--text-opacity:1;color:#4c51bf;color:rgba(76,81,191,var(--text-opacity))}.xl\:focus\:text-indigo-800:focus{--text-opacity:1;color:#434190;color:rgba(67,65,144,var(--text-opacity))}.xl\:focus\:text-indigo-900:focus{--text-opacity:1;color:#3c366b;color:rgba(60,54,107,var(--text-opacity))}.xl\:focus\:text-purple-100:focus{--text-opacity:1;color:#faf5ff;color:rgba(250,245,255,var(--text-opacity))}.xl\:focus\:text-purple-200:focus{--text-opacity:1;color:#e9d8fd;color:rgba(233,216,253,var(--text-opacity))}.xl\:focus\:text-purple-300:focus{--text-opacity:1;color:#d6bcfa;color:rgba(214,188,250,var(--text-opacity))}.xl\:focus\:text-purple-400:focus{--text-opacity:1;color:#b794f4;color:rgba(183,148,244,var(--text-opacity))}.xl\:focus\:text-purple-500:focus{--text-opacity:1;color:#9f7aea;color:rgba(159,122,234,var(--text-opacity))}.xl\:focus\:text-purple-600:focus{--text-opacity:1;color:#805ad5;color:rgba(128,90,213,var(--text-opacity))}.xl\:focus\:text-purple-700:focus{--text-opacity:1;color:#6b46c1;color:rgba(107,70,193,var(--text-opacity))}.xl\:focus\:text-purple-800:focus{--text-opacity:1;color:#553c9a;color:rgba(85,60,154,var(--text-opacity))}.xl\:focus\:text-purple-900:focus{--text-opacity:1;color:#44337a;color:rgba(68,51,122,var(--text-opacity))}.xl\:focus\:text-pink-100:focus{--text-opacity:1;color:#fff5f7;color:rgba(255,245,247,var(--text-opacity))}.xl\:focus\:text-pink-200:focus{--text-opacity:1;color:#fed7e2;color:rgba(254,215,226,var(--text-opacity))}.xl\:focus\:text-pink-300:focus{--text-opacity:1;color:#fbb6ce;color:rgba(251,182,206,var(--text-opacity))}.xl\:focus\:text-pink-400:focus{--text-opacity:1;color:#f687b3;color:rgba(246,135,179,var(--text-opacity))}.xl\:focus\:text-pink-500:focus{--text-opacity:1;color:#ed64a6;color:rgba(237,100,166,var(--text-opacity))}.xl\:focus\:text-pink-600:focus{--text-opacity:1;color:#d53f8c;color:rgba(213,63,140,var(--text-opacity))}.xl\:focus\:text-pink-700:focus{--text-opacity:1;color:#b83280;color:rgba(184,50,128,var(--text-opacity))}.xl\:focus\:text-pink-800:focus{--text-opacity:1;color:#97266d;color:rgba(151,38,109,var(--text-opacity))}.xl\:focus\:text-pink-900:focus{--text-opacity:1;color:#702459;color:rgba(112,36,89,var(--text-opacity))}.xl\:text-opacity-0{--text-opacity:0}.xl\:text-opacity-25{--text-opacity:0.25}.xl\:text-opacity-50{--text-opacity:0.5}.xl\:text-opacity-75{--text-opacity:0.75}.xl\:text-opacity-100{--text-opacity:1}.xl\:hover\:text-opacity-0:hover{--text-opacity:0}.xl\:hover\:text-opacity-25:hover{--text-opacity:0.25}.xl\:hover\:text-opacity-50:hover{--text-opacity:0.5}.xl\:hover\:text-opacity-75:hover{--text-opacity:0.75}.xl\:hover\:text-opacity-100:hover{--text-opacity:1}.xl\:focus\:text-opacity-0:focus{--text-opacity:0}.xl\:focus\:text-opacity-25:focus{--text-opacity:0.25}.xl\:focus\:text-opacity-50:focus{--text-opacity:0.5}.xl\:focus\:text-opacity-75:focus{--text-opacity:0.75}.xl\:focus\:text-opacity-100:focus{--text-opacity:1}.xl\:italic{font-style:italic}.xl\:not-italic{font-style:normal}.xl\:uppercase{text-transform:uppercase}.xl\:lowercase{text-transform:lowercase}.xl\:capitalize{text-transform:capitalize}.xl\:normal-case{text-transform:none}.xl\:underline{text-decoration:underline}.xl\:line-through{text-decoration:line-through}.xl\:no-underline{text-decoration:none}.xl\:hover\:underline:hover{text-decoration:underline}.xl\:hover\:line-through:hover{text-decoration:line-through}.xl\:hover\:no-underline:hover{text-decoration:none}.xl\:focus\:underline:focus{text-decoration:underline}.xl\:focus\:line-through:focus{text-decoration:line-through}.xl\:focus\:no-underline:focus{text-decoration:none}.xl\:antialiased{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.xl\:subpixel-antialiased{-webkit-font-smoothing:auto;-moz-osx-font-smoothing:auto}.xl\:diagonal-fractions,.xl\:lining-nums,.xl\:oldstyle-nums,.xl\:ordinal,.xl\:proportional-nums,.xl\:slashed-zero,.xl\:stacked-fractions,.xl\:tabular-nums{--font-variant-numeric-ordinal:var(--tailwind-empty, );/*!*//*!*/--font-variant-numeric-slashed-zero:var(--tailwind-empty, );/*!*//*!*/--font-variant-numeric-figure:var(--tailwind-empty, );/*!*//*!*/--font-variant-numeric-spacing:var(--tailwind-empty, );/*!*//*!*/--font-variant-numeric-fraction:var(--tailwind-empty, );/*!*//*!*/font-variant-numeric:var(--font-variant-numeric-ordinal) var(--font-variant-numeric-slashed-zero) var(--font-variant-numeric-figure) var(--font-variant-numeric-spacing) var(--font-variant-numeric-fraction)}.xl\:normal-nums{font-variant-numeric:normal}.xl\:ordinal{--font-variant-numeric-ordinal:ordinal}.xl\:slashed-zero{--font-variant-numeric-slashed-zero:slashed-zero}.xl\:lining-nums{--font-variant-numeric-figure:lining-nums}.xl\:oldstyle-nums{--font-variant-numeric-figure:oldstyle-nums}.xl\:proportional-nums{--font-variant-numeric-spacing:proportional-nums}.xl\:tabular-nums{--font-variant-numeric-spacing:tabular-nums}.xl\:diagonal-fractions{--font-variant-numeric-fraction:diagonal-fractions}.xl\:stacked-fractions{--font-variant-numeric-fraction:stacked-fractions}.xl\:tracking-tighter{letter-spacing:-.05em}.xl\:tracking-tight{letter-spacing:-.025em}.xl\:tracking-normal{letter-spacing:0}.xl\:tracking-wide{letter-spacing:.025em}.xl\:tracking-wider{letter-spacing:.05em}.xl\:tracking-widest{letter-spacing:.1em}.xl\:select-none{-webkit-user-select:none;-ms-user-select:none;user-select:none}.xl\:select-text{-webkit-user-select:text;-ms-user-select:text;user-select:text}.xl\:select-all{-webkit-user-select:all;-ms-user-select:all;user-select:all}.xl\:select-auto{-webkit-user-select:auto;-ms-user-select:auto;user-select:auto}.xl\:align-baseline{vertical-align:baseline}.xl\:align-top{vertical-align:top}.xl\:align-middle{vertical-align:middle}.xl\:align-bottom{vertical-align:bottom}.xl\:align-text-top{vertical-align:text-top}.xl\:align-text-bottom{vertical-align:text-bottom}.xl\:visible{visibility:visible}.xl\:invisible{visibility:hidden}.xl\:whitespace-normal{white-space:normal}.xl\:whitespace-no-wrap{white-space:nowrap}.xl\:whitespace-pre{white-space:pre}.xl\:whitespace-pre-line{white-space:pre-line}.xl\:whitespace-pre-wrap{white-space:pre-wrap}.xl\:break-normal{word-wrap:normal;overflow-wrap:normal;word-break:normal}.xl\:break-words{word-wrap:break-word;overflow-wrap:break-word}.xl\:break-all{word-break:break-all}.xl\:truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.xl\:w-0{width:0}.xl\:w-1{width:.25rem}.xl\:w-2{width:.5rem}.xl\:w-3{width:.75rem}.xl\:w-4{width:1rem}.xl\:w-5{width:1.25rem}.xl\:w-6{width:1.5rem}.xl\:w-8{width:2rem}.xl\:w-10{width:2.5rem}.xl\:w-12{width:3rem}.xl\:w-16{width:4rem}.xl\:w-20{width:5rem}.xl\:w-24{width:6rem}.xl\:w-32{width:8rem}.xl\:w-40{width:10rem}.xl\:w-48{width:12rem}.xl\:w-56{width:14rem}.xl\:w-64{width:16rem}.xl\:w-auto{width:auto}.xl\:w-px{width:1px}.xl\:w-1\/2{width:50%}.xl\:w-1\/3{width:33.333333%}.xl\:w-2\/3{width:66.666667%}.xl\:w-1\/4{width:25%}.xl\:w-2\/4{width:50%}.xl\:w-3\/4{width:75%}.xl\:w-1\/5{width:20%}.xl\:w-2\/5{width:40%}.xl\:w-3\/5{width:60%}.xl\:w-4\/5{width:80%}.xl\:w-1\/6{width:16.666667%}.xl\:w-2\/6{width:33.333333%}.xl\:w-3\/6{width:50%}.xl\:w-4\/6{width:66.666667%}.xl\:w-5\/6{width:83.333333%}.xl\:w-1\/12{width:8.333333%}.xl\:w-2\/12{width:16.666667%}.xl\:w-3\/12{width:25%}.xl\:w-4\/12{width:33.333333%}.xl\:w-5\/12{width:41.666667%}.xl\:w-6\/12{width:50%}.xl\:w-7\/12{width:58.333333%}.xl\:w-8\/12{width:66.666667%}.xl\:w-9\/12{width:75%}.xl\:w-10\/12{width:83.333333%}.xl\:w-11\/12{width:91.666667%}.xl\:w-full{width:100%}.xl\:w-screen{width:100vw}.xl\:z-0{z-index:0}.xl\:z-10{z-index:10}.xl\:z-20{z-index:20}.xl\:z-30{z-index:30}.xl\:z-40{z-index:40}.xl\:z-50{z-index:50}.xl\:z-auto{z-index:auto}.xl\:gap-0{grid-gap:0;gap:0}.xl\:gap-1{grid-gap:.25rem;gap:.25rem}.xl\:gap-2{grid-gap:.5rem;gap:.5rem}.xl\:gap-3{grid-gap:.75rem;gap:.75rem}.xl\:gap-4{grid-gap:1rem;gap:1rem}.xl\:gap-5{grid-gap:1.25rem;gap:1.25rem}.xl\:gap-6{grid-gap:1.5rem;gap:1.5rem}.xl\:gap-8{grid-gap:2rem;gap:2rem}.xl\:gap-10{grid-gap:2.5rem;gap:2.5rem}.xl\:gap-12{grid-gap:3rem;gap:3rem}.xl\:gap-16{grid-gap:4rem;gap:4rem}.xl\:gap-20{grid-gap:5rem;gap:5rem}.xl\:gap-24{grid-gap:6rem;gap:6rem}.xl\:gap-32{grid-gap:8rem;gap:8rem}.xl\:gap-40{grid-gap:10rem;gap:10rem}.xl\:gap-48{grid-gap:12rem;gap:12rem}.xl\:gap-56{grid-gap:14rem;gap:14rem}.xl\:gap-64{grid-gap:16rem;gap:16rem}.xl\:gap-px{grid-gap:1px;gap:1px}.xl\:col-gap-0{grid-column-gap:0;column-gap:0}.xl\:col-gap-1{grid-column-gap:.25rem;column-gap:.25rem}.xl\:col-gap-2{grid-column-gap:.5rem;column-gap:.5rem}.xl\:col-gap-3{grid-column-gap:.75rem;column-gap:.75rem}.xl\:col-gap-4{grid-column-gap:1rem;column-gap:1rem}.xl\:col-gap-5{grid-column-gap:1.25rem;column-gap:1.25rem}.xl\:col-gap-6{grid-column-gap:1.5rem;column-gap:1.5rem}.xl\:col-gap-8{grid-column-gap:2rem;column-gap:2rem}.xl\:col-gap-10{grid-column-gap:2.5rem;column-gap:2.5rem}.xl\:col-gap-12{grid-column-gap:3rem;column-gap:3rem}.xl\:col-gap-16{grid-column-gap:4rem;column-gap:4rem}.xl\:col-gap-20{grid-column-gap:5rem;column-gap:5rem}.xl\:col-gap-24{grid-column-gap:6rem;column-gap:6rem}.xl\:col-gap-32{grid-column-gap:8rem;column-gap:8rem}.xl\:col-gap-40{grid-column-gap:10rem;column-gap:10rem}.xl\:col-gap-48{grid-column-gap:12rem;column-gap:12rem}.xl\:col-gap-56{grid-column-gap:14rem;column-gap:14rem}.xl\:col-gap-64{grid-column-gap:16rem;column-gap:16rem}.xl\:col-gap-px{grid-column-gap:1px;column-gap:1px}.xl\:gap-x-0{grid-column-gap:0;column-gap:0}.xl\:gap-x-1{grid-column-gap:.25rem;column-gap:.25rem}.xl\:gap-x-2{grid-column-gap:.5rem;column-gap:.5rem}.xl\:gap-x-3{grid-column-gap:.75rem;column-gap:.75rem}.xl\:gap-x-4{grid-column-gap:1rem;column-gap:1rem}.xl\:gap-x-5{grid-column-gap:1.25rem;column-gap:1.25rem}.xl\:gap-x-6{grid-column-gap:1.5rem;column-gap:1.5rem}.xl\:gap-x-8{grid-column-gap:2rem;column-gap:2rem}.xl\:gap-x-10{grid-column-gap:2.5rem;column-gap:2.5rem}.xl\:gap-x-12{grid-column-gap:3rem;column-gap:3rem}.xl\:gap-x-16{grid-column-gap:4rem;column-gap:4rem}.xl\:gap-x-20{grid-column-gap:5rem;column-gap:5rem}.xl\:gap-x-24{grid-column-gap:6rem;column-gap:6rem}.xl\:gap-x-32{grid-column-gap:8rem;column-gap:8rem}.xl\:gap-x-40{grid-column-gap:10rem;column-gap:10rem}.xl\:gap-x-48{grid-column-gap:12rem;column-gap:12rem}.xl\:gap-x-56{grid-column-gap:14rem;column-gap:14rem}.xl\:gap-x-64{grid-column-gap:16rem;column-gap:16rem}.xl\:gap-x-px{grid-column-gap:1px;column-gap:1px}.xl\:row-gap-0{grid-row-gap:0;row-gap:0}.xl\:row-gap-1{grid-row-gap:.25rem;row-gap:.25rem}.xl\:row-gap-2{grid-row-gap:.5rem;row-gap:.5rem}.xl\:row-gap-3{grid-row-gap:.75rem;row-gap:.75rem}.xl\:row-gap-4{grid-row-gap:1rem;row-gap:1rem}.xl\:row-gap-5{grid-row-gap:1.25rem;row-gap:1.25rem}.xl\:row-gap-6{grid-row-gap:1.5rem;row-gap:1.5rem}.xl\:row-gap-8{grid-row-gap:2rem;row-gap:2rem}.xl\:row-gap-10{grid-row-gap:2.5rem;row-gap:2.5rem}.xl\:row-gap-12{grid-row-gap:3rem;row-gap:3rem}.xl\:row-gap-16{grid-row-gap:4rem;row-gap:4rem}.xl\:row-gap-20{grid-row-gap:5rem;row-gap:5rem}.xl\:row-gap-24{grid-row-gap:6rem;row-gap:6rem}.xl\:row-gap-32{grid-row-gap:8rem;row-gap:8rem}.xl\:row-gap-40{grid-row-gap:10rem;row-gap:10rem}.xl\:row-gap-48{grid-row-gap:12rem;row-gap:12rem}.xl\:row-gap-56{grid-row-gap:14rem;row-gap:14rem}.xl\:row-gap-64{grid-row-gap:16rem;row-gap:16rem}.xl\:row-gap-px{grid-row-gap:1px;row-gap:1px}.xl\:gap-y-0{grid-row-gap:0;row-gap:0}.xl\:gap-y-1{grid-row-gap:.25rem;row-gap:.25rem}.xl\:gap-y-2{grid-row-gap:.5rem;row-gap:.5rem}.xl\:gap-y-3{grid-row-gap:.75rem;row-gap:.75rem}.xl\:gap-y-4{grid-row-gap:1rem;row-gap:1rem}.xl\:gap-y-5{grid-row-gap:1.25rem;row-gap:1.25rem}.xl\:gap-y-6{grid-row-gap:1.5rem;row-gap:1.5rem}.xl\:gap-y-8{grid-row-gap:2rem;row-gap:2rem}.xl\:gap-y-10{grid-row-gap:2.5rem;row-gap:2.5rem}.xl\:gap-y-12{grid-row-gap:3rem;row-gap:3rem}.xl\:gap-y-16{grid-row-gap:4rem;row-gap:4rem}.xl\:gap-y-20{grid-row-gap:5rem;row-gap:5rem}.xl\:gap-y-24{grid-row-gap:6rem;row-gap:6rem}.xl\:gap-y-32{grid-row-gap:8rem;row-gap:8rem}.xl\:gap-y-40{grid-row-gap:10rem;row-gap:10rem}.xl\:gap-y-48{grid-row-gap:12rem;row-gap:12rem}.xl\:gap-y-56{grid-row-gap:14rem;row-gap:14rem}.xl\:gap-y-64{grid-row-gap:16rem;row-gap:16rem}.xl\:gap-y-px{grid-row-gap:1px;row-gap:1px}.xl\:grid-flow-row{grid-auto-flow:row}.xl\:grid-flow-col{grid-auto-flow:column}.xl\:grid-flow-row-dense{grid-auto-flow:row dense}.xl\:grid-flow-col-dense{grid-auto-flow:column dense}.xl\:grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.xl\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.xl\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.xl\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.xl\:grid-cols-5{grid-template-columns:repeat(5,minmax(0,1fr))}.xl\:grid-cols-6{grid-template-columns:repeat(6,minmax(0,1fr))}.xl\:grid-cols-7{grid-template-columns:repeat(7,minmax(0,1fr))}.xl\:grid-cols-8{grid-template-columns:repeat(8,minmax(0,1fr))}.xl\:grid-cols-9{grid-template-columns:repeat(9,minmax(0,1fr))}.xl\:grid-cols-10{grid-template-columns:repeat(10,minmax(0,1fr))}.xl\:grid-cols-11{grid-template-columns:repeat(11,minmax(0,1fr))}.xl\:grid-cols-12{grid-template-columns:repeat(12,minmax(0,1fr))}.xl\:grid-cols-none{grid-template-columns:none}.xl\:auto-cols-auto{grid-auto-columns:auto}.xl\:auto-cols-min{grid-auto-columns:-webkit-min-content;grid-auto-columns:min-content}.xl\:auto-cols-max{grid-auto-columns:-webkit-max-content;grid-auto-columns:max-content}.xl\:auto-cols-fr{grid-auto-columns:minmax(0,1fr)}.xl\:col-auto{grid-column:auto}.xl\:col-span-1{grid-column:span 1/span 1}.xl\:col-span-2{grid-column:span 2/span 2}.xl\:col-span-3{grid-column:span 3/span 3}.xl\:col-span-4{grid-column:span 4/span 4}.xl\:col-span-5{grid-column:span 5/span 5}.xl\:col-span-6{grid-column:span 6/span 6}.xl\:col-span-7{grid-column:span 7/span 7}.xl\:col-span-8{grid-column:span 8/span 8}.xl\:col-span-9{grid-column:span 9/span 9}.xl\:col-span-10{grid-column:span 10/span 10}.xl\:col-span-11{grid-column:span 11/span 11}.xl\:col-span-12{grid-column:span 12/span 12}.xl\:col-span-full{grid-column:1/-1}.xl\:col-start-1{grid-column-start:1}.xl\:col-start-2{grid-column-start:2}.xl\:col-start-3{grid-column-start:3}.xl\:col-start-4{grid-column-start:4}.xl\:col-start-5{grid-column-start:5}.xl\:col-start-6{grid-column-start:6}.xl\:col-start-7{grid-column-start:7}.xl\:col-start-8{grid-column-start:8}.xl\:col-start-9{grid-column-start:9}.xl\:col-start-10{grid-column-start:10}.xl\:col-start-11{grid-column-start:11}.xl\:col-start-12{grid-column-start:12}.xl\:col-start-13{grid-column-start:13}.xl\:col-start-auto{grid-column-start:auto}.xl\:col-end-1{grid-column-end:1}.xl\:col-end-2{grid-column-end:2}.xl\:col-end-3{grid-column-end:3}.xl\:col-end-4{grid-column-end:4}.xl\:col-end-5{grid-column-end:5}.xl\:col-end-6{grid-column-end:6}.xl\:col-end-7{grid-column-end:7}.xl\:col-end-8{grid-column-end:8}.xl\:col-end-9{grid-column-end:9}.xl\:col-end-10{grid-column-end:10}.xl\:col-end-11{grid-column-end:11}.xl\:col-end-12{grid-column-end:12}.xl\:col-end-13{grid-column-end:13}.xl\:col-end-auto{grid-column-end:auto}.xl\:grid-rows-1{grid-template-rows:repeat(1,minmax(0,1fr))}.xl\:grid-rows-2{grid-template-rows:repeat(2,minmax(0,1fr))}.xl\:grid-rows-3{grid-template-rows:repeat(3,minmax(0,1fr))}.xl\:grid-rows-4{grid-template-rows:repeat(4,minmax(0,1fr))}.xl\:grid-rows-5{grid-template-rows:repeat(5,minmax(0,1fr))}.xl\:grid-rows-6{grid-template-rows:repeat(6,minmax(0,1fr))}.xl\:grid-rows-none{grid-template-rows:none}.xl\:auto-rows-auto{grid-auto-rows:auto}.xl\:auto-rows-min{grid-auto-rows:-webkit-min-content;grid-auto-rows:min-content}.xl\:auto-rows-max{grid-auto-rows:-webkit-max-content;grid-auto-rows:max-content}.xl\:auto-rows-fr{grid-auto-rows:minmax(0,1fr)}.xl\:row-auto{grid-row:auto}.xl\:row-span-1{grid-row:span 1/span 1}.xl\:row-span-2{grid-row:span 2/span 2}.xl\:row-span-3{grid-row:span 3/span 3}.xl\:row-span-4{grid-row:span 4/span 4}.xl\:row-span-5{grid-row:span 5/span 5}.xl\:row-span-6{grid-row:span 6/span 6}.xl\:row-span-full{grid-row:1/-1}.xl\:row-start-1{grid-row-start:1}.xl\:row-start-2{grid-row-start:2}.xl\:row-start-3{grid-row-start:3}.xl\:row-start-4{grid-row-start:4}.xl\:row-start-5{grid-row-start:5}.xl\:row-start-6{grid-row-start:6}.xl\:row-start-7{grid-row-start:7}.xl\:row-start-auto{grid-row-start:auto}.xl\:row-end-1{grid-row-end:1}.xl\:row-end-2{grid-row-end:2}.xl\:row-end-3{grid-row-end:3}.xl\:row-end-4{grid-row-end:4}.xl\:row-end-5{grid-row-end:5}.xl\:row-end-6{grid-row-end:6}.xl\:row-end-7{grid-row-end:7}.xl\:row-end-auto{grid-row-end:auto}.xl\:transform{--transform-translate-x:0;--transform-translate-y:0;--transform-rotate:0;--transform-skew-x:0;--transform-skew-y:0;--transform-scale-x:1;--transform-scale-y:1;transform:translateX(var(--transform-translate-x)) translateY(var(--transform-translate-y)) rotate(var(--transform-rotate)) skewX(var(--transform-skew-x)) skewY(var(--transform-skew-y)) scaleX(var(--transform-scale-x)) scaleY(var(--transform-scale-y))}.xl\:transform-none{transform:none}.xl\:origin-center{transform-origin:center}.xl\:origin-top{transform-origin:top}.xl\:origin-top-right{transform-origin:top right}.xl\:origin-right{transform-origin:right}.xl\:origin-bottom-right{transform-origin:bottom right}.xl\:origin-bottom{transform-origin:bottom}.xl\:origin-bottom-left{transform-origin:bottom left}.xl\:origin-left{transform-origin:left}.xl\:origin-top-left{transform-origin:top left}.xl\:scale-0{--transform-scale-x:0;--transform-scale-y:0}.xl\:scale-50{--transform-scale-x:.5;--transform-scale-y:.5}.xl\:scale-75{--transform-scale-x:.75;--transform-scale-y:.75}.xl\:scale-90{--transform-scale-x:.9;--transform-scale-y:.9}.xl\:scale-95{--transform-scale-x:.95;--transform-scale-y:.95}.xl\:scale-100{--transform-scale-x:1;--transform-scale-y:1}.xl\:scale-105{--transform-scale-x:1.05;--transform-scale-y:1.05}.xl\:scale-110{--transform-scale-x:1.1;--transform-scale-y:1.1}.xl\:scale-125{--transform-scale-x:1.25;--transform-scale-y:1.25}.xl\:scale-150{--transform-scale-x:1.5;--transform-scale-y:1.5}.xl\:scale-x-0{--transform-scale-x:0}.xl\:scale-x-50{--transform-scale-x:.5}.xl\:scale-x-75{--transform-scale-x:.75}.xl\:scale-x-90{--transform-scale-x:.9}.xl\:scale-x-95{--transform-scale-x:.95}.xl\:scale-x-100{--transform-scale-x:1}.xl\:scale-x-105{--transform-scale-x:1.05}.xl\:scale-x-110{--transform-scale-x:1.1}.xl\:scale-x-125{--transform-scale-x:1.25}.xl\:scale-x-150{--transform-scale-x:1.5}.xl\:scale-y-0{--transform-scale-y:0}.xl\:scale-y-50{--transform-scale-y:.5}.xl\:scale-y-75{--transform-scale-y:.75}.xl\:scale-y-90{--transform-scale-y:.9}.xl\:scale-y-95{--transform-scale-y:.95}.xl\:scale-y-100{--transform-scale-y:1}.xl\:scale-y-105{--transform-scale-y:1.05}.xl\:scale-y-110{--transform-scale-y:1.1}.xl\:scale-y-125{--transform-scale-y:1.25}.xl\:scale-y-150{--transform-scale-y:1.5}.xl\:hover\:scale-0:hover{--transform-scale-x:0;--transform-scale-y:0}.xl\:hover\:scale-50:hover{--transform-scale-x:.5;--transform-scale-y:.5}.xl\:hover\:scale-75:hover{--transform-scale-x:.75;--transform-scale-y:.75}.xl\:hover\:scale-90:hover{--transform-scale-x:.9;--transform-scale-y:.9}.xl\:hover\:scale-95:hover{--transform-scale-x:.95;--transform-scale-y:.95}.xl\:hover\:scale-100:hover{--transform-scale-x:1;--transform-scale-y:1}.xl\:hover\:scale-105:hover{--transform-scale-x:1.05;--transform-scale-y:1.05}.xl\:hover\:scale-110:hover{--transform-scale-x:1.1;--transform-scale-y:1.1}.xl\:hover\:scale-125:hover{--transform-scale-x:1.25;--transform-scale-y:1.25}.xl\:hover\:scale-150:hover{--transform-scale-x:1.5;--transform-scale-y:1.5}.xl\:hover\:scale-x-0:hover{--transform-scale-x:0}.xl\:hover\:scale-x-50:hover{--transform-scale-x:.5}.xl\:hover\:scale-x-75:hover{--transform-scale-x:.75}.xl\:hover\:scale-x-90:hover{--transform-scale-x:.9}.xl\:hover\:scale-x-95:hover{--transform-scale-x:.95}.xl\:hover\:scale-x-100:hover{--transform-scale-x:1}.xl\:hover\:scale-x-105:hover{--transform-scale-x:1.05}.xl\:hover\:scale-x-110:hover{--transform-scale-x:1.1}.xl\:hover\:scale-x-125:hover{--transform-scale-x:1.25}.xl\:hover\:scale-x-150:hover{--transform-scale-x:1.5}.xl\:hover\:scale-y-0:hover{--transform-scale-y:0}.xl\:hover\:scale-y-50:hover{--transform-scale-y:.5}.xl\:hover\:scale-y-75:hover{--transform-scale-y:.75}.xl\:hover\:scale-y-90:hover{--transform-scale-y:.9}.xl\:hover\:scale-y-95:hover{--transform-scale-y:.95}.xl\:hover\:scale-y-100:hover{--transform-scale-y:1}.xl\:hover\:scale-y-105:hover{--transform-scale-y:1.05}.xl\:hover\:scale-y-110:hover{--transform-scale-y:1.1}.xl\:hover\:scale-y-125:hover{--transform-scale-y:1.25}.xl\:hover\:scale-y-150:hover{--transform-scale-y:1.5}.xl\:focus\:scale-0:focus{--transform-scale-x:0;--transform-scale-y:0}.xl\:focus\:scale-50:focus{--transform-scale-x:.5;--transform-scale-y:.5}.xl\:focus\:scale-75:focus{--transform-scale-x:.75;--transform-scale-y:.75}.xl\:focus\:scale-90:focus{--transform-scale-x:.9;--transform-scale-y:.9}.xl\:focus\:scale-95:focus{--transform-scale-x:.95;--transform-scale-y:.95}.xl\:focus\:scale-100:focus{--transform-scale-x:1;--transform-scale-y:1}.xl\:focus\:scale-105:focus{--transform-scale-x:1.05;--transform-scale-y:1.05}.xl\:focus\:scale-110:focus{--transform-scale-x:1.1;--transform-scale-y:1.1}.xl\:focus\:scale-125:focus{--transform-scale-x:1.25;--transform-scale-y:1.25}.xl\:focus\:scale-150:focus{--transform-scale-x:1.5;--transform-scale-y:1.5}.xl\:focus\:scale-x-0:focus{--transform-scale-x:0}.xl\:focus\:scale-x-50:focus{--transform-scale-x:.5}.xl\:focus\:scale-x-75:focus{--transform-scale-x:.75}.xl\:focus\:scale-x-90:focus{--transform-scale-x:.9}.xl\:focus\:scale-x-95:focus{--transform-scale-x:.95}.xl\:focus\:scale-x-100:focus{--transform-scale-x:1}.xl\:focus\:scale-x-105:focus{--transform-scale-x:1.05}.xl\:focus\:scale-x-110:focus{--transform-scale-x:1.1}.xl\:focus\:scale-x-125:focus{--transform-scale-x:1.25}.xl\:focus\:scale-x-150:focus{--transform-scale-x:1.5}.xl\:focus\:scale-y-0:focus{--transform-scale-y:0}.xl\:focus\:scale-y-50:focus{--transform-scale-y:.5}.xl\:focus\:scale-y-75:focus{--transform-scale-y:.75}.xl\:focus\:scale-y-90:focus{--transform-scale-y:.9}.xl\:focus\:scale-y-95:focus{--transform-scale-y:.95}.xl\:focus\:scale-y-100:focus{--transform-scale-y:1}.xl\:focus\:scale-y-105:focus{--transform-scale-y:1.05}.xl\:focus\:scale-y-110:focus{--transform-scale-y:1.1}.xl\:focus\:scale-y-125:focus{--transform-scale-y:1.25}.xl\:focus\:scale-y-150:focus{--transform-scale-y:1.5}.xl\:rotate-0{--transform-rotate:0}.xl\:rotate-1{--transform-rotate:1deg}.xl\:rotate-2{--transform-rotate:2deg}.xl\:rotate-3{--transform-rotate:3deg}.xl\:rotate-6{--transform-rotate:6deg}.xl\:rotate-12{--transform-rotate:12deg}.xl\:rotate-45{--transform-rotate:45deg}.xl\:rotate-90{--transform-rotate:90deg}.xl\:rotate-180{--transform-rotate:180deg}.xl\:-rotate-180{--transform-rotate:-180deg}.xl\:-rotate-90{--transform-rotate:-90deg}.xl\:-rotate-45{--transform-rotate:-45deg}.xl\:-rotate-12{--transform-rotate:-12deg}.xl\:-rotate-6{--transform-rotate:-6deg}.xl\:-rotate-3{--transform-rotate:-3deg}.xl\:-rotate-2{--transform-rotate:-2deg}.xl\:-rotate-1{--transform-rotate:-1deg}.xl\:hover\:rotate-0:hover{--transform-rotate:0}.xl\:hover\:rotate-1:hover{--transform-rotate:1deg}.xl\:hover\:rotate-2:hover{--transform-rotate:2deg}.xl\:hover\:rotate-3:hover{--transform-rotate:3deg}.xl\:hover\:rotate-6:hover{--transform-rotate:6deg}.xl\:hover\:rotate-12:hover{--transform-rotate:12deg}.xl\:hover\:rotate-45:hover{--transform-rotate:45deg}.xl\:hover\:rotate-90:hover{--transform-rotate:90deg}.xl\:hover\:rotate-180:hover{--transform-rotate:180deg}.xl\:hover\:-rotate-180:hover{--transform-rotate:-180deg}.xl\:hover\:-rotate-90:hover{--transform-rotate:-90deg}.xl\:hover\:-rotate-45:hover{--transform-rotate:-45deg}.xl\:hover\:-rotate-12:hover{--transform-rotate:-12deg}.xl\:hover\:-rotate-6:hover{--transform-rotate:-6deg}.xl\:hover\:-rotate-3:hover{--transform-rotate:-3deg}.xl\:hover\:-rotate-2:hover{--transform-rotate:-2deg}.xl\:hover\:-rotate-1:hover{--transform-rotate:-1deg}.xl\:focus\:rotate-0:focus{--transform-rotate:0}.xl\:focus\:rotate-1:focus{--transform-rotate:1deg}.xl\:focus\:rotate-2:focus{--transform-rotate:2deg}.xl\:focus\:rotate-3:focus{--transform-rotate:3deg}.xl\:focus\:rotate-6:focus{--transform-rotate:6deg}.xl\:focus\:rotate-12:focus{--transform-rotate:12deg}.xl\:focus\:rotate-45:focus{--transform-rotate:45deg}.xl\:focus\:rotate-90:focus{--transform-rotate:90deg}.xl\:focus\:rotate-180:focus{--transform-rotate:180deg}.xl\:focus\:-rotate-180:focus{--transform-rotate:-180deg}.xl\:focus\:-rotate-90:focus{--transform-rotate:-90deg}.xl\:focus\:-rotate-45:focus{--transform-rotate:-45deg}.xl\:focus\:-rotate-12:focus{--transform-rotate:-12deg}.xl\:focus\:-rotate-6:focus{--transform-rotate:-6deg}.xl\:focus\:-rotate-3:focus{--transform-rotate:-3deg}.xl\:focus\:-rotate-2:focus{--transform-rotate:-2deg}.xl\:focus\:-rotate-1:focus{--transform-rotate:-1deg}.xl\:translate-x-0{--transform-translate-x:0}.xl\:translate-x-1{--transform-translate-x:0.25rem}.xl\:translate-x-2{--transform-translate-x:0.5rem}.xl\:translate-x-3{--transform-translate-x:0.75rem}.xl\:translate-x-4{--transform-translate-x:1rem}.xl\:translate-x-5{--transform-translate-x:1.25rem}.xl\:translate-x-6{--transform-translate-x:1.5rem}.xl\:translate-x-8{--transform-translate-x:2rem}.xl\:translate-x-10{--transform-translate-x:2.5rem}.xl\:translate-x-12{--transform-translate-x:3rem}.xl\:translate-x-16{--transform-translate-x:4rem}.xl\:translate-x-20{--transform-translate-x:5rem}.xl\:translate-x-24{--transform-translate-x:6rem}.xl\:translate-x-32{--transform-translate-x:8rem}.xl\:translate-x-40{--transform-translate-x:10rem}.xl\:translate-x-48{--transform-translate-x:12rem}.xl\:translate-x-56{--transform-translate-x:14rem}.xl\:translate-x-64{--transform-translate-x:16rem}.xl\:translate-x-px{--transform-translate-x:1px}.xl\:-translate-x-1{--transform-translate-x:-0.25rem}.xl\:-translate-x-2{--transform-translate-x:-0.5rem}.xl\:-translate-x-3{--transform-translate-x:-0.75rem}.xl\:-translate-x-4{--transform-translate-x:-1rem}.xl\:-translate-x-5{--transform-translate-x:-1.25rem}.xl\:-translate-x-6{--transform-translate-x:-1.5rem}.xl\:-translate-x-8{--transform-translate-x:-2rem}.xl\:-translate-x-10{--transform-translate-x:-2.5rem}.xl\:-translate-x-12{--transform-translate-x:-3rem}.xl\:-translate-x-16{--transform-translate-x:-4rem}.xl\:-translate-x-20{--transform-translate-x:-5rem}.xl\:-translate-x-24{--transform-translate-x:-6rem}.xl\:-translate-x-32{--transform-translate-x:-8rem}.xl\:-translate-x-40{--transform-translate-x:-10rem}.xl\:-translate-x-48{--transform-translate-x:-12rem}.xl\:-translate-x-56{--transform-translate-x:-14rem}.xl\:-translate-x-64{--transform-translate-x:-16rem}.xl\:-translate-x-px{--transform-translate-x:-1px}.xl\:-translate-x-full{--transform-translate-x:-100%}.xl\:-translate-x-1\/2{--transform-translate-x:-50%}.xl\:translate-x-1\/2{--transform-translate-x:50%}.xl\:translate-x-full{--transform-translate-x:100%}.xl\:translate-y-0{--transform-translate-y:0}.xl\:translate-y-1{--transform-translate-y:0.25rem}.xl\:translate-y-2{--transform-translate-y:0.5rem}.xl\:translate-y-3{--transform-translate-y:0.75rem}.xl\:translate-y-4{--transform-translate-y:1rem}.xl\:translate-y-5{--transform-translate-y:1.25rem}.xl\:translate-y-6{--transform-translate-y:1.5rem}.xl\:translate-y-8{--transform-translate-y:2rem}.xl\:translate-y-10{--transform-translate-y:2.5rem}.xl\:translate-y-12{--transform-translate-y:3rem}.xl\:translate-y-16{--transform-translate-y:4rem}.xl\:translate-y-20{--transform-translate-y:5rem}.xl\:translate-y-24{--transform-translate-y:6rem}.xl\:translate-y-32{--transform-translate-y:8rem}.xl\:translate-y-40{--transform-translate-y:10rem}.xl\:translate-y-48{--transform-translate-y:12rem}.xl\:translate-y-56{--transform-translate-y:14rem}.xl\:translate-y-64{--transform-translate-y:16rem}.xl\:translate-y-px{--transform-translate-y:1px}.xl\:-translate-y-1{--transform-translate-y:-0.25rem}.xl\:-translate-y-2{--transform-translate-y:-0.5rem}.xl\:-translate-y-3{--transform-translate-y:-0.75rem}.xl\:-translate-y-4{--transform-translate-y:-1rem}.xl\:-translate-y-5{--transform-translate-y:-1.25rem}.xl\:-translate-y-6{--transform-translate-y:-1.5rem}.xl\:-translate-y-8{--transform-translate-y:-2rem}.xl\:-translate-y-10{--transform-translate-y:-2.5rem}.xl\:-translate-y-12{--transform-translate-y:-3rem}.xl\:-translate-y-16{--transform-translate-y:-4rem}.xl\:-translate-y-20{--transform-translate-y:-5rem}.xl\:-translate-y-24{--transform-translate-y:-6rem}.xl\:-translate-y-32{--transform-translate-y:-8rem}.xl\:-translate-y-40{--transform-translate-y:-10rem}.xl\:-translate-y-48{--transform-translate-y:-12rem}.xl\:-translate-y-56{--transform-translate-y:-14rem}.xl\:-translate-y-64{--transform-translate-y:-16rem}.xl\:-translate-y-px{--transform-translate-y:-1px}.xl\:-translate-y-full{--transform-translate-y:-100%}.xl\:-translate-y-1\/2{--transform-translate-y:-50%}.xl\:translate-y-1\/2{--transform-translate-y:50%}.xl\:translate-y-full{--transform-translate-y:100%}.xl\:hover\:translate-x-0:hover{--transform-translate-x:0}.xl\:hover\:translate-x-1:hover{--transform-translate-x:0.25rem}.xl\:hover\:translate-x-2:hover{--transform-translate-x:0.5rem}.xl\:hover\:translate-x-3:hover{--transform-translate-x:0.75rem}.xl\:hover\:translate-x-4:hover{--transform-translate-x:1rem}.xl\:hover\:translate-x-5:hover{--transform-translate-x:1.25rem}.xl\:hover\:translate-x-6:hover{--transform-translate-x:1.5rem}.xl\:hover\:translate-x-8:hover{--transform-translate-x:2rem}.xl\:hover\:translate-x-10:hover{--transform-translate-x:2.5rem}.xl\:hover\:translate-x-12:hover{--transform-translate-x:3rem}.xl\:hover\:translate-x-16:hover{--transform-translate-x:4rem}.xl\:hover\:translate-x-20:hover{--transform-translate-x:5rem}.xl\:hover\:translate-x-24:hover{--transform-translate-x:6rem}.xl\:hover\:translate-x-32:hover{--transform-translate-x:8rem}.xl\:hover\:translate-x-40:hover{--transform-translate-x:10rem}.xl\:hover\:translate-x-48:hover{--transform-translate-x:12rem}.xl\:hover\:translate-x-56:hover{--transform-translate-x:14rem}.xl\:hover\:translate-x-64:hover{--transform-translate-x:16rem}.xl\:hover\:translate-x-px:hover{--transform-translate-x:1px}.xl\:hover\:-translate-x-1:hover{--transform-translate-x:-0.25rem}.xl\:hover\:-translate-x-2:hover{--transform-translate-x:-0.5rem}.xl\:hover\:-translate-x-3:hover{--transform-translate-x:-0.75rem}.xl\:hover\:-translate-x-4:hover{--transform-translate-x:-1rem}.xl\:hover\:-translate-x-5:hover{--transform-translate-x:-1.25rem}.xl\:hover\:-translate-x-6:hover{--transform-translate-x:-1.5rem}.xl\:hover\:-translate-x-8:hover{--transform-translate-x:-2rem}.xl\:hover\:-translate-x-10:hover{--transform-translate-x:-2.5rem}.xl\:hover\:-translate-x-12:hover{--transform-translate-x:-3rem}.xl\:hover\:-translate-x-16:hover{--transform-translate-x:-4rem}.xl\:hover\:-translate-x-20:hover{--transform-translate-x:-5rem}.xl\:hover\:-translate-x-24:hover{--transform-translate-x:-6rem}.xl\:hover\:-translate-x-32:hover{--transform-translate-x:-8rem}.xl\:hover\:-translate-x-40:hover{--transform-translate-x:-10rem}.xl\:hover\:-translate-x-48:hover{--transform-translate-x:-12rem}.xl\:hover\:-translate-x-56:hover{--transform-translate-x:-14rem}.xl\:hover\:-translate-x-64:hover{--transform-translate-x:-16rem}.xl\:hover\:-translate-x-px:hover{--transform-translate-x:-1px}.xl\:hover\:-translate-x-full:hover{--transform-translate-x:-100%}.xl\:hover\:-translate-x-1\/2:hover{--transform-translate-x:-50%}.xl\:hover\:translate-x-1\/2:hover{--transform-translate-x:50%}.xl\:hover\:translate-x-full:hover{--transform-translate-x:100%}.xl\:hover\:translate-y-0:hover{--transform-translate-y:0}.xl\:hover\:translate-y-1:hover{--transform-translate-y:0.25rem}.xl\:hover\:translate-y-2:hover{--transform-translate-y:0.5rem}.xl\:hover\:translate-y-3:hover{--transform-translate-y:0.75rem}.xl\:hover\:translate-y-4:hover{--transform-translate-y:1rem}.xl\:hover\:translate-y-5:hover{--transform-translate-y:1.25rem}.xl\:hover\:translate-y-6:hover{--transform-translate-y:1.5rem}.xl\:hover\:translate-y-8:hover{--transform-translate-y:2rem}.xl\:hover\:translate-y-10:hover{--transform-translate-y:2.5rem}.xl\:hover\:translate-y-12:hover{--transform-translate-y:3rem}.xl\:hover\:translate-y-16:hover{--transform-translate-y:4rem}.xl\:hover\:translate-y-20:hover{--transform-translate-y:5rem}.xl\:hover\:translate-y-24:hover{--transform-translate-y:6rem}.xl\:hover\:translate-y-32:hover{--transform-translate-y:8rem}.xl\:hover\:translate-y-40:hover{--transform-translate-y:10rem}.xl\:hover\:translate-y-48:hover{--transform-translate-y:12rem}.xl\:hover\:translate-y-56:hover{--transform-translate-y:14rem}.xl\:hover\:translate-y-64:hover{--transform-translate-y:16rem}.xl\:hover\:translate-y-px:hover{--transform-translate-y:1px}.xl\:hover\:-translate-y-1:hover{--transform-translate-y:-0.25rem}.xl\:hover\:-translate-y-2:hover{--transform-translate-y:-0.5rem}.xl\:hover\:-translate-y-3:hover{--transform-translate-y:-0.75rem}.xl\:hover\:-translate-y-4:hover{--transform-translate-y:-1rem}.xl\:hover\:-translate-y-5:hover{--transform-translate-y:-1.25rem}.xl\:hover\:-translate-y-6:hover{--transform-translate-y:-1.5rem}.xl\:hover\:-translate-y-8:hover{--transform-translate-y:-2rem}.xl\:hover\:-translate-y-10:hover{--transform-translate-y:-2.5rem}.xl\:hover\:-translate-y-12:hover{--transform-translate-y:-3rem}.xl\:hover\:-translate-y-16:hover{--transform-translate-y:-4rem}.xl\:hover\:-translate-y-20:hover{--transform-translate-y:-5rem}.xl\:hover\:-translate-y-24:hover{--transform-translate-y:-6rem}.xl\:hover\:-translate-y-32:hover{--transform-translate-y:-8rem}.xl\:hover\:-translate-y-40:hover{--transform-translate-y:-10rem}.xl\:hover\:-translate-y-48:hover{--transform-translate-y:-12rem}.xl\:hover\:-translate-y-56:hover{--transform-translate-y:-14rem}.xl\:hover\:-translate-y-64:hover{--transform-translate-y:-16rem}.xl\:hover\:-translate-y-px:hover{--transform-translate-y:-1px}.xl\:hover\:-translate-y-full:hover{--transform-translate-y:-100%}.xl\:hover\:-translate-y-1\/2:hover{--transform-translate-y:-50%}.xl\:hover\:translate-y-1\/2:hover{--transform-translate-y:50%}.xl\:hover\:translate-y-full:hover{--transform-translate-y:100%}.xl\:focus\:translate-x-0:focus{--transform-translate-x:0}.xl\:focus\:translate-x-1:focus{--transform-translate-x:0.25rem}.xl\:focus\:translate-x-2:focus{--transform-translate-x:0.5rem}.xl\:focus\:translate-x-3:focus{--transform-translate-x:0.75rem}.xl\:focus\:translate-x-4:focus{--transform-translate-x:1rem}.xl\:focus\:translate-x-5:focus{--transform-translate-x:1.25rem}.xl\:focus\:translate-x-6:focus{--transform-translate-x:1.5rem}.xl\:focus\:translate-x-8:focus{--transform-translate-x:2rem}.xl\:focus\:translate-x-10:focus{--transform-translate-x:2.5rem}.xl\:focus\:translate-x-12:focus{--transform-translate-x:3rem}.xl\:focus\:translate-x-16:focus{--transform-translate-x:4rem}.xl\:focus\:translate-x-20:focus{--transform-translate-x:5rem}.xl\:focus\:translate-x-24:focus{--transform-translate-x:6rem}.xl\:focus\:translate-x-32:focus{--transform-translate-x:8rem}.xl\:focus\:translate-x-40:focus{--transform-translate-x:10rem}.xl\:focus\:translate-x-48:focus{--transform-translate-x:12rem}.xl\:focus\:translate-x-56:focus{--transform-translate-x:14rem}.xl\:focus\:translate-x-64:focus{--transform-translate-x:16rem}.xl\:focus\:translate-x-px:focus{--transform-translate-x:1px}.xl\:focus\:-translate-x-1:focus{--transform-translate-x:-0.25rem}.xl\:focus\:-translate-x-2:focus{--transform-translate-x:-0.5rem}.xl\:focus\:-translate-x-3:focus{--transform-translate-x:-0.75rem}.xl\:focus\:-translate-x-4:focus{--transform-translate-x:-1rem}.xl\:focus\:-translate-x-5:focus{--transform-translate-x:-1.25rem}.xl\:focus\:-translate-x-6:focus{--transform-translate-x:-1.5rem}.xl\:focus\:-translate-x-8:focus{--transform-translate-x:-2rem}.xl\:focus\:-translate-x-10:focus{--transform-translate-x:-2.5rem}.xl\:focus\:-translate-x-12:focus{--transform-translate-x:-3rem}.xl\:focus\:-translate-x-16:focus{--transform-translate-x:-4rem}.xl\:focus\:-translate-x-20:focus{--transform-translate-x:-5rem}.xl\:focus\:-translate-x-24:focus{--transform-translate-x:-6rem}.xl\:focus\:-translate-x-32:focus{--transform-translate-x:-8rem}.xl\:focus\:-translate-x-40:focus{--transform-translate-x:-10rem}.xl\:focus\:-translate-x-48:focus{--transform-translate-x:-12rem}.xl\:focus\:-translate-x-56:focus{--transform-translate-x:-14rem}.xl\:focus\:-translate-x-64:focus{--transform-translate-x:-16rem}.xl\:focus\:-translate-x-px:focus{--transform-translate-x:-1px}.xl\:focus\:-translate-x-full:focus{--transform-translate-x:-100%}.xl\:focus\:-translate-x-1\/2:focus{--transform-translate-x:-50%}.xl\:focus\:translate-x-1\/2:focus{--transform-translate-x:50%}.xl\:focus\:translate-x-full:focus{--transform-translate-x:100%}.xl\:focus\:translate-y-0:focus{--transform-translate-y:0}.xl\:focus\:translate-y-1:focus{--transform-translate-y:0.25rem}.xl\:focus\:translate-y-2:focus{--transform-translate-y:0.5rem}.xl\:focus\:translate-y-3:focus{--transform-translate-y:0.75rem}.xl\:focus\:translate-y-4:focus{--transform-translate-y:1rem}.xl\:focus\:translate-y-5:focus{--transform-translate-y:1.25rem}.xl\:focus\:translate-y-6:focus{--transform-translate-y:1.5rem}.xl\:focus\:translate-y-8:focus{--transform-translate-y:2rem}.xl\:focus\:translate-y-10:focus{--transform-translate-y:2.5rem}.xl\:focus\:translate-y-12:focus{--transform-translate-y:3rem}.xl\:focus\:translate-y-16:focus{--transform-translate-y:4rem}.xl\:focus\:translate-y-20:focus{--transform-translate-y:5rem}.xl\:focus\:translate-y-24:focus{--transform-translate-y:6rem}.xl\:focus\:translate-y-32:focus{--transform-translate-y:8rem}.xl\:focus\:translate-y-40:focus{--transform-translate-y:10rem}.xl\:focus\:translate-y-48:focus{--transform-translate-y:12rem}.xl\:focus\:translate-y-56:focus{--transform-translate-y:14rem}.xl\:focus\:translate-y-64:focus{--transform-translate-y:16rem}.xl\:focus\:translate-y-px:focus{--transform-translate-y:1px}.xl\:focus\:-translate-y-1:focus{--transform-translate-y:-0.25rem}.xl\:focus\:-translate-y-2:focus{--transform-translate-y:-0.5rem}.xl\:focus\:-translate-y-3:focus{--transform-translate-y:-0.75rem}.xl\:focus\:-translate-y-4:focus{--transform-translate-y:-1rem}.xl\:focus\:-translate-y-5:focus{--transform-translate-y:-1.25rem}.xl\:focus\:-translate-y-6:focus{--transform-translate-y:-1.5rem}.xl\:focus\:-translate-y-8:focus{--transform-translate-y:-2rem}.xl\:focus\:-translate-y-10:focus{--transform-translate-y:-2.5rem}.xl\:focus\:-translate-y-12:focus{--transform-translate-y:-3rem}.xl\:focus\:-translate-y-16:focus{--transform-translate-y:-4rem}.xl\:focus\:-translate-y-20:focus{--transform-translate-y:-5rem}.xl\:focus\:-translate-y-24:focus{--transform-translate-y:-6rem}.xl\:focus\:-translate-y-32:focus{--transform-translate-y:-8rem}.xl\:focus\:-translate-y-40:focus{--transform-translate-y:-10rem}.xl\:focus\:-translate-y-48:focus{--transform-translate-y:-12rem}.xl\:focus\:-translate-y-56:focus{--transform-translate-y:-14rem}.xl\:focus\:-translate-y-64:focus{--transform-translate-y:-16rem}.xl\:focus\:-translate-y-px:focus{--transform-translate-y:-1px}.xl\:focus\:-translate-y-full:focus{--transform-translate-y:-100%}.xl\:focus\:-translate-y-1\/2:focus{--transform-translate-y:-50%}.xl\:focus\:translate-y-1\/2:focus{--transform-translate-y:50%}.xl\:focus\:translate-y-full:focus{--transform-translate-y:100%}.xl\:skew-x-0{--transform-skew-x:0}.xl\:skew-x-1{--transform-skew-x:1deg}.xl\:skew-x-2{--transform-skew-x:2deg}.xl\:skew-x-3{--transform-skew-x:3deg}.xl\:skew-x-6{--transform-skew-x:6deg}.xl\:skew-x-12{--transform-skew-x:12deg}.xl\:-skew-x-12{--transform-skew-x:-12deg}.xl\:-skew-x-6{--transform-skew-x:-6deg}.xl\:-skew-x-3{--transform-skew-x:-3deg}.xl\:-skew-x-2{--transform-skew-x:-2deg}.xl\:-skew-x-1{--transform-skew-x:-1deg}.xl\:skew-y-0{--transform-skew-y:0}.xl\:skew-y-1{--transform-skew-y:1deg}.xl\:skew-y-2{--transform-skew-y:2deg}.xl\:skew-y-3{--transform-skew-y:3deg}.xl\:skew-y-6{--transform-skew-y:6deg}.xl\:skew-y-12{--transform-skew-y:12deg}.xl\:-skew-y-12{--transform-skew-y:-12deg}.xl\:-skew-y-6{--transform-skew-y:-6deg}.xl\:-skew-y-3{--transform-skew-y:-3deg}.xl\:-skew-y-2{--transform-skew-y:-2deg}.xl\:-skew-y-1{--transform-skew-y:-1deg}.xl\:hover\:skew-x-0:hover{--transform-skew-x:0}.xl\:hover\:skew-x-1:hover{--transform-skew-x:1deg}.xl\:hover\:skew-x-2:hover{--transform-skew-x:2deg}.xl\:hover\:skew-x-3:hover{--transform-skew-x:3deg}.xl\:hover\:skew-x-6:hover{--transform-skew-x:6deg}.xl\:hover\:skew-x-12:hover{--transform-skew-x:12deg}.xl\:hover\:-skew-x-12:hover{--transform-skew-x:-12deg}.xl\:hover\:-skew-x-6:hover{--transform-skew-x:-6deg}.xl\:hover\:-skew-x-3:hover{--transform-skew-x:-3deg}.xl\:hover\:-skew-x-2:hover{--transform-skew-x:-2deg}.xl\:hover\:-skew-x-1:hover{--transform-skew-x:-1deg}.xl\:hover\:skew-y-0:hover{--transform-skew-y:0}.xl\:hover\:skew-y-1:hover{--transform-skew-y:1deg}.xl\:hover\:skew-y-2:hover{--transform-skew-y:2deg}.xl\:hover\:skew-y-3:hover{--transform-skew-y:3deg}.xl\:hover\:skew-y-6:hover{--transform-skew-y:6deg}.xl\:hover\:skew-y-12:hover{--transform-skew-y:12deg}.xl\:hover\:-skew-y-12:hover{--transform-skew-y:-12deg}.xl\:hover\:-skew-y-6:hover{--transform-skew-y:-6deg}.xl\:hover\:-skew-y-3:hover{--transform-skew-y:-3deg}.xl\:hover\:-skew-y-2:hover{--transform-skew-y:-2deg}.xl\:hover\:-skew-y-1:hover{--transform-skew-y:-1deg}.xl\:focus\:skew-x-0:focus{--transform-skew-x:0}.xl\:focus\:skew-x-1:focus{--transform-skew-x:1deg}.xl\:focus\:skew-x-2:focus{--transform-skew-x:2deg}.xl\:focus\:skew-x-3:focus{--transform-skew-x:3deg}.xl\:focus\:skew-x-6:focus{--transform-skew-x:6deg}.xl\:focus\:skew-x-12:focus{--transform-skew-x:12deg}.xl\:focus\:-skew-x-12:focus{--transform-skew-x:-12deg}.xl\:focus\:-skew-x-6:focus{--transform-skew-x:-6deg}.xl\:focus\:-skew-x-3:focus{--transform-skew-x:-3deg}.xl\:focus\:-skew-x-2:focus{--transform-skew-x:-2deg}.xl\:focus\:-skew-x-1:focus{--transform-skew-x:-1deg}.xl\:focus\:skew-y-0:focus{--transform-skew-y:0}.xl\:focus\:skew-y-1:focus{--transform-skew-y:1deg}.xl\:focus\:skew-y-2:focus{--transform-skew-y:2deg}.xl\:focus\:skew-y-3:focus{--transform-skew-y:3deg}.xl\:focus\:skew-y-6:focus{--transform-skew-y:6deg}.xl\:focus\:skew-y-12:focus{--transform-skew-y:12deg}.xl\:focus\:-skew-y-12:focus{--transform-skew-y:-12deg}.xl\:focus\:-skew-y-6:focus{--transform-skew-y:-6deg}.xl\:focus\:-skew-y-3:focus{--transform-skew-y:-3deg}.xl\:focus\:-skew-y-2:focus{--transform-skew-y:-2deg}.xl\:focus\:-skew-y-1:focus{--transform-skew-y:-1deg}.xl\:transition-none{transition-property:none}.xl\:transition-all{transition-property:all}.xl\:transition{transition-property:background-color,border-color,color,fill,stroke,opacity,box-shadow,transform}.xl\:transition-colors{transition-property:background-color,border-color,color,fill,stroke}.xl\:transition-opacity{transition-property:opacity}.xl\:transition-shadow{transition-property:box-shadow}.xl\:transition-transform{transition-property:transform}.xl\:ease-linear{transition-timing-function:linear}.xl\:ease-in{transition-timing-function:cubic-bezier(.4,0,1,1)}.xl\:ease-out{transition-timing-function:cubic-bezier(0,0,.2,1)}.xl\:ease-in-out{transition-timing-function:cubic-bezier(.4,0,.2,1)}.xl\:duration-75{transition-duration:75ms}.xl\:duration-100{transition-duration:.1s}.xl\:duration-150{transition-duration:150ms}.xl\:duration-200{transition-duration:.2s}.xl\:duration-300{transition-duration:.3s}.xl\:duration-500{transition-duration:.5s}.xl\:duration-700{transition-duration:.7s}.xl\:duration-1000{transition-duration:1s}.xl\:delay-75{transition-delay:75ms}.xl\:delay-100{transition-delay:.1s}.xl\:delay-150{transition-delay:150ms}.xl\:delay-200{transition-delay:.2s}.xl\:delay-300{transition-delay:.3s}.xl\:delay-500{transition-delay:.5s}.xl\:delay-700{transition-delay:.7s}.xl\:delay-1000{transition-delay:1s}.xl\:animate-none{animation:none}.xl\:animate-spin{animation:spin 1s linear infinite}.xl\:animate-ping{animation:ping 1s cubic-bezier(0,0,.2,1) infinite}.xl\:animate-pulse{animation:pulse 2s cubic-bezier(.4,0,.6,1) infinite}.xl\:animate-bounce{animation:bounce 1s infinite}} \ No newline at end of file diff --git a/test/configCases/css/large/use-style.js b/test/configCases/css/large/use-style.js new file mode 100644 index 00000000000..8f394120676 --- /dev/null +++ b/test/configCases/css/large/use-style.js @@ -0,0 +1,5 @@ +import * as style from "./tailwind.module.css"; + +export default { + placeholder: style["placeholder-gray-700"] +}; diff --git a/test/configCases/css/large/webpack.config.js b/test/configCases/css/large/webpack.config.js new file mode 100644 index 00000000000..c6289845d73 --- /dev/null +++ b/test/configCases/css/large/webpack.config.js @@ -0,0 +1,21 @@ +/** @type {import("../../../../").Configuration[]} */ +module.exports = [ + { + target: "web", + mode: "development", + output: { + uniqueName: "my-app" + }, + experiments: { + css: true + } + }, + { + target: "web", + mode: "production", + performance: false, + experiments: { + css: true + } + } +]; diff --git a/test/configCases/css/local-ident-name/index.js b/test/configCases/css/local-ident-name/index.js new file mode 100644 index 00000000000..816c494697a --- /dev/null +++ b/test/configCases/css/local-ident-name/index.js @@ -0,0 +1,22 @@ +it("should have correct local ident for css export locals", (done) => { + Promise.all([ + import("./style.module.css"), + import("./style.module.css?hash"), + import("./style.module.css?hash-local"), + import("./style.module.css?path-name-local"), + import("./style.module.css?file-local"), + import("./style.module.css?q#f"), + import("./style.module.css?uniqueName-id-contenthash"), + import("./style.module.less"), + ]).then(([idLocal, hash, hashLocal, pathNameLocal, fileLocal, queryFragment, uniqueNameIdContenthash, less]) => { + expect(idLocal).toMatchSnapshot(); + expect(hash).toMatchSnapshot(); + expect(hashLocal).toMatchSnapshot(); + expect(pathNameLocal).toMatchSnapshot(); + expect(fileLocal).toMatchSnapshot(); + expect(queryFragment).toMatchSnapshot(); + expect(uniqueNameIdContenthash).toMatchSnapshot(); + expect(less).toMatchSnapshot(); + done() + }).catch(done) +}); diff --git a/test/configCases/css/local-ident-name/style.module.css b/test/configCases/css/local-ident-name/style.module.css new file mode 100644 index 00000000000..864a29382e0 --- /dev/null +++ b/test/configCases/css/local-ident-name/style.module.css @@ -0,0 +1,25 @@ +.btn-info_is-disabled { + color: blue; +} + +.btn--info_is-disabled_1 { + color: blue; +} + +.simple { + color: red; +} + +a { + color: yellow; +} + +:export { + foo: bar; + my-btn-info_is-disabled: value; +} + +.foo_bar { + --color-red: red; + color: var(--color-red); +} diff --git a/test/configCases/css/local-ident-name/style.module.less b/test/configCases/css/local-ident-name/style.module.less new file mode 100644 index 00000000000..864a29382e0 --- /dev/null +++ b/test/configCases/css/local-ident-name/style.module.less @@ -0,0 +1,25 @@ +.btn-info_is-disabled { + color: blue; +} + +.btn--info_is-disabled_1 { + color: blue; +} + +.simple { + color: red; +} + +a { + color: yellow; +} + +:export { + foo: bar; + my-btn-info_is-disabled: value; +} + +.foo_bar { + --color-red: red; + color: var(--color-red); +} diff --git a/test/configCases/css/local-ident-name/webpack.config.js b/test/configCases/css/local-ident-name/webpack.config.js new file mode 100644 index 00000000000..99d0a8346c2 --- /dev/null +++ b/test/configCases/css/local-ident-name/webpack.config.js @@ -0,0 +1,73 @@ +const common = { + mode: "development", + module: { + rules: [ + { + test: /\.less$/, + type: "css/auto", + use: ["less-loader"], + generator: { + localIdentName: "[path][name][ext]__[local]" + } + }, + { + test: /\.css$/, + type: "css/auto", + oneOf: [ + { + resourceQuery: /\?hash$/, + generator: { + localIdentName: "[hash]" + } + }, + { + resourceQuery: /\?hash-local$/, + generator: { + localIdentName: "[hash]-[local]" + } + }, + { + resourceQuery: /\?path-name-local$/, + generator: { + localIdentName: "[path][name]__[local]" + } + }, + { + resourceQuery: /\?file-local$/, + generator: { + localIdentName: "[file]__[local]" + } + }, + { + resourceQuery: /\?q$/, + resourceFragment: /#f$/, + generator: { + localIdentName: "[file][query][fragment]__[local]" + } + }, + { + resourceQuery: /\?uniqueName-id-contenthash$/, + generator: { + localIdentName: "[uniqueName]-[id]-[contenthash]" + } + } + ] + } + ] + }, + experiments: { + css: true + } +}; + +/** @type {import("../../../../").Configuration} */ +module.exports = [ + { + ...common, + target: "web" + }, + { + ...common, + target: "node" + } +]; diff --git a/test/configCases/css/named-exports-parser-options/index.js b/test/configCases/css/named-exports-parser-options/index.js new file mode 100644 index 00000000000..ae9c150bb90 --- /dev/null +++ b/test/configCases/css/named-exports-parser-options/index.js @@ -0,0 +1,25 @@ +import * as style1 from "./style.module.css" +import style2 from "./style.module.css?default" +import * as style3 from "./style.module.css?named" + +it("should able to import with different namedExports", () => { + expect(style1).toEqual(nsObj({ class: '-_style_module_css-class' })); + expect(style2).toEqual(nsObj({ class: '-_style_module_css_default-class' })); + expect(style3).toEqual(nsObj({ class: '-_style_module_css_named-class' })); +}); + +it("should able to import with different namedExports (async)", (done) => { + Promise.all([ + import("./style.module.css"), + import("./style.module.css?default"), + import("./style.module.css?named"), + ]).then(([style1, style2, style3]) => { + expect(style1).toEqual(nsObj({ class: '-_style_module_css-class' })); + expect(style2).toEqual(nsObj({ + class: "-_style_module_css_default-class", + default: nsObj({ class: '-_style_module_css_default-class' }) + })); + expect(style3).toEqual(nsObj({ class: '-_style_module_css_named-class' })); + done() + }, done) +}); diff --git a/test/configCases/css/named-exports-parser-options/style.module.css b/test/configCases/css/named-exports-parser-options/style.module.css new file mode 100644 index 00000000000..626e93720d0 --- /dev/null +++ b/test/configCases/css/named-exports-parser-options/style.module.css @@ -0,0 +1,3 @@ +.class { + color: red; +} diff --git a/test/configCases/css/named-exports-parser-options/webpack.config.js b/test/configCases/css/named-exports-parser-options/webpack.config.js new file mode 100644 index 00000000000..50b4c7745cf --- /dev/null +++ b/test/configCases/css/named-exports-parser-options/webpack.config.js @@ -0,0 +1,26 @@ +/** @type {import("../../../../").Configuration} */ +module.exports = { + target: "node", + mode: "development", + module: { + rules: [ + { + resourceQuery: /\?default/, + parser: { + namedExports: false + }, + type: "css/module" + }, + { + resourceQuery: /\?named/, + parser: { + namedExports: true + }, + type: "css/module" + } + ] + }, + experiments: { + css: true + } +}; diff --git a/test/configCases/css/namespace/index.js b/test/configCases/css/namespace/index.js new file mode 100644 index 00000000000..78be77a3a32 --- /dev/null +++ b/test/configCases/css/namespace/index.js @@ -0,0 +1,7 @@ +import "./style.css"; + +it("should compile with warning", done => { + const style = getComputedStyle(document.body); + expect(style.getPropertyValue("background")).toBe(" red"); + done(); +}); diff --git a/test/configCases/css/namespace/style.css b/test/configCases/css/namespace/style.css new file mode 100644 index 00000000000..e16ce897e5d --- /dev/null +++ b/test/configCases/css/namespace/style.css @@ -0,0 +1,5 @@ +@namespace svg url('http://www.w3.org/2000/svg'); + +body { + background: red; +} diff --git a/test/configCases/css/namespace/test.config.js b/test/configCases/css/namespace/test.config.js new file mode 100644 index 00000000000..0590757288f --- /dev/null +++ b/test/configCases/css/namespace/test.config.js @@ -0,0 +1,8 @@ +module.exports = { + moduleScope(scope) { + const link = scope.window.document.createElement("link"); + link.rel = "stylesheet"; + link.href = "bundle0.css"; + scope.window.document.head.appendChild(link); + } +}; diff --git a/test/configCases/css/namespace/warnings.js b/test/configCases/css/namespace/warnings.js new file mode 100644 index 00000000000..b10e066e2f7 --- /dev/null +++ b/test/configCases/css/namespace/warnings.js @@ -0,0 +1 @@ +module.exports = [/'@namespace' is not supported in bundled CSS/]; diff --git a/test/configCases/css/namespace/webpack.config.js b/test/configCases/css/namespace/webpack.config.js new file mode 100644 index 00000000000..cfb8e5c0346 --- /dev/null +++ b/test/configCases/css/namespace/webpack.config.js @@ -0,0 +1,8 @@ +/** @type {import("../../../../").Configuration} */ +module.exports = { + target: "web", + mode: "development", + experiments: { + css: true + } +}; diff --git a/test/configCases/css/pathinfo/index.js b/test/configCases/css/pathinfo/index.js new file mode 100644 index 00000000000..c1507825419 --- /dev/null +++ b/test/configCases/css/pathinfo/index.js @@ -0,0 +1,14 @@ +import * as style from "./style.css"; + +it("should compile and load style on demand", done => { + expect(style).toEqual(nsObj({})); + import("./style2.css").then(x => { + expect(x).toEqual(nsObj({})); + const style = getComputedStyle(document.body); + expect(style.getPropertyValue("background")).toBe(" red"); + expect(style.getPropertyValue("margin")).toBe(" 10px"); + expect(style.getPropertyValue("color")).toBe(" green"); + expect(style.getPropertyValue("padding")).toBe(" 20px 10px"); + done(); + }, done); +}); diff --git a/test/configCases/css/pathinfo/style-imported.css b/test/configCases/css/pathinfo/style-imported.css new file mode 100644 index 00000000000..eb0ae451455 --- /dev/null +++ b/test/configCases/css/pathinfo/style-imported.css @@ -0,0 +1,3 @@ +body { + margin: 10px; +} diff --git a/test/configCases/css/pathinfo/style.css b/test/configCases/css/pathinfo/style.css new file mode 100644 index 00000000000..ba0cfaf6561 --- /dev/null +++ b/test/configCases/css/pathinfo/style.css @@ -0,0 +1,4 @@ +@import "style-imported.css"; +body { + background: red; +} diff --git a/test/configCases/css/pathinfo/style2-imported.css b/test/configCases/css/pathinfo/style2-imported.css new file mode 100644 index 00000000000..ff9387e5d3e --- /dev/null +++ b/test/configCases/css/pathinfo/style2-imported.css @@ -0,0 +1,3 @@ +body { + padding: 20px 10px; +} diff --git a/test/configCases/css/pathinfo/style2.css b/test/configCases/css/pathinfo/style2.css new file mode 100644 index 00000000000..d80cbcd05df --- /dev/null +++ b/test/configCases/css/pathinfo/style2.css @@ -0,0 +1,4 @@ +@import "./style2-imported.css"; +body { + color: green; +} diff --git a/test/configCases/css/pathinfo/test.config.js b/test/configCases/css/pathinfo/test.config.js new file mode 100644 index 00000000000..61818ebf345 --- /dev/null +++ b/test/configCases/css/pathinfo/test.config.js @@ -0,0 +1,30 @@ +const fs = require("fs"); +const path = require("path"); + +module.exports = { + moduleScope(scope) { + const link = scope.window.document.createElement("link"); + link.rel = "stylesheet"; + link.href = "bundle0.css"; + scope.window.document.head.appendChild(link); + }, + findBundle: function (i, options) { + const source = fs.readFileSync( + path.resolve(options.output.path, "bundle0.css"), + "utf-8" + ); + + if ( + !source.includes(`/*!********************************!*\\ + !*** css ./style-imported.css ***! + \\********************************/`) && + !source.includes(`/*!***********************!*\\ + !*** css ./style.css ***! + \\***********************/`) + ) { + throw new Error("The `pathinfo` option doesn't work."); + } + + return "./bundle0.js"; + } +}; diff --git a/test/configCases/css/pathinfo/webpack.config.js b/test/configCases/css/pathinfo/webpack.config.js new file mode 100644 index 00000000000..e2848b6a973 --- /dev/null +++ b/test/configCases/css/pathinfo/webpack.config.js @@ -0,0 +1,13 @@ +/** @type {import("../../../../").Configuration} */ +module.exports = { + target: "web", + mode: "development", + devtool: false, + output: { + pathinfo: true, + cssChunkFilename: "[name].[chunkhash].css" + }, + experiments: { + css: true + } +}; diff --git a/test/configCases/css/prefer-relative-css-import/bar.modules.css b/test/configCases/css/prefer-relative-css-import/bar.modules.css new file mode 100644 index 00000000000..212af39cfba --- /dev/null +++ b/test/configCases/css/prefer-relative-css-import/bar.modules.css @@ -0,0 +1,7 @@ +body { + color: red; +} + +.bar { + color: red; +} diff --git a/test/configCases/css/prefer-relative-css-import/foo.css b/test/configCases/css/prefer-relative-css-import/foo.css new file mode 100644 index 00000000000..bb644f91459 --- /dev/null +++ b/test/configCases/css/prefer-relative-css-import/foo.css @@ -0,0 +1,7 @@ +body { + background: red; +} + +.foo { + color: red; +} diff --git a/test/configCases/css/prefer-relative-css-import/index.js b/test/configCases/css/prefer-relative-css-import/index.js new file mode 100644 index 00000000000..72ad37d8b50 --- /dev/null +++ b/test/configCases/css/prefer-relative-css-import/index.js @@ -0,0 +1,14 @@ +import * as styles1 from "./style.less"; +import * as styles2 from "./style.modules.less"; + +it("should prefer relative", () => { + expect(styles1).toEqual(nsObj({})); + expect(styles2).toEqual(nsObj({ + "style-module": "-_style_modules_less-style-module", + })); + + const style = getComputedStyle(document.body); + + expect(style.getPropertyValue("background")).toBe(" red"); + expect(style.getPropertyValue("color")).toBe(" red"); +}); diff --git a/test/configCases/css/prefer-relative-css-import/node_modules/bar.modules.css/package.json b/test/configCases/css/prefer-relative-css-import/node_modules/bar.modules.css/package.json new file mode 100644 index 00000000000..bfdbb88698b --- /dev/null +++ b/test/configCases/css/prefer-relative-css-import/node_modules/bar.modules.css/package.json @@ -0,0 +1,4 @@ +{ + "name": "bar.modules.css", + "main": "style.css" +} diff --git a/test/configCases/css/prefer-relative-css-import/node_modules/bar.modules.css/style.css b/test/configCases/css/prefer-relative-css-import/node_modules/bar.modules.css/style.css new file mode 100644 index 00000000000..36505138bc9 --- /dev/null +++ b/test/configCases/css/prefer-relative-css-import/node_modules/bar.modules.css/style.css @@ -0,0 +1,3 @@ +body { + color: blue; +} diff --git a/test/configCases/css/prefer-relative-css-import/node_modules/foo.css/package.json b/test/configCases/css/prefer-relative-css-import/node_modules/foo.css/package.json new file mode 100644 index 00000000000..f273efd2294 --- /dev/null +++ b/test/configCases/css/prefer-relative-css-import/node_modules/foo.css/package.json @@ -0,0 +1,4 @@ +{ + "name": "foo.css", + "main": "style.css" +} diff --git a/test/configCases/css/prefer-relative-css-import/node_modules/foo.css/style.css b/test/configCases/css/prefer-relative-css-import/node_modules/foo.css/style.css new file mode 100644 index 00000000000..eedeb9d0ff9 --- /dev/null +++ b/test/configCases/css/prefer-relative-css-import/node_modules/foo.css/style.css @@ -0,0 +1,3 @@ +body { + background: blue; +} diff --git a/test/configCases/css/prefer-relative-css-import/style.less b/test/configCases/css/prefer-relative-css-import/style.less new file mode 100644 index 00000000000..7aed5ec6680 --- /dev/null +++ b/test/configCases/css/prefer-relative-css-import/style.less @@ -0,0 +1,5 @@ +@import 'foo.css'; + +.style { + color: red; +} diff --git a/test/configCases/css/prefer-relative-css-import/style.modules.less b/test/configCases/css/prefer-relative-css-import/style.modules.less new file mode 100644 index 00000000000..69dc14ca454 --- /dev/null +++ b/test/configCases/css/prefer-relative-css-import/style.modules.less @@ -0,0 +1,5 @@ +@import 'bar.modules.css'; + +.style-module { + color: red; +} diff --git a/test/configCases/css/prefer-relative-css-import/test.config.js b/test/configCases/css/prefer-relative-css-import/test.config.js new file mode 100644 index 00000000000..0590757288f --- /dev/null +++ b/test/configCases/css/prefer-relative-css-import/test.config.js @@ -0,0 +1,8 @@ +module.exports = { + moduleScope(scope) { + const link = scope.window.document.createElement("link"); + link.rel = "stylesheet"; + link.href = "bundle0.css"; + scope.window.document.head.appendChild(link); + } +}; diff --git a/test/configCases/css/prefer-relative-css-import/webpack.config.js b/test/configCases/css/prefer-relative-css-import/webpack.config.js new file mode 100644 index 00000000000..b4ebfb3d73f --- /dev/null +++ b/test/configCases/css/prefer-relative-css-import/webpack.config.js @@ -0,0 +1,17 @@ +/** @type {import("../../../../").Configuration} */ +module.exports = { + target: "web", + mode: "development", + module: { + rules: [ + { + test: /\.less$/, + use: "less-loader", + type: "css/auto" + } + ] + }, + experiments: { + css: true + } +}; diff --git a/test/configCases/css/prefer-relative/bar.modules.css b/test/configCases/css/prefer-relative/bar.modules.css new file mode 100644 index 00000000000..212af39cfba --- /dev/null +++ b/test/configCases/css/prefer-relative/bar.modules.css @@ -0,0 +1,7 @@ +body { + color: red; +} + +.bar { + color: red; +} diff --git a/test/configCases/css/prefer-relative/foo.css b/test/configCases/css/prefer-relative/foo.css new file mode 100644 index 00000000000..bb644f91459 --- /dev/null +++ b/test/configCases/css/prefer-relative/foo.css @@ -0,0 +1,7 @@ +body { + background: red; +} + +.foo { + color: red; +} diff --git a/test/configCases/css/prefer-relative/index.js b/test/configCases/css/prefer-relative/index.js new file mode 100644 index 00000000000..c33b77cf780 --- /dev/null +++ b/test/configCases/css/prefer-relative/index.js @@ -0,0 +1,14 @@ +import * as styles1 from "./style.css"; +import * as styles2 from "./style.modules.css"; + +it("should prefer relative", () => { + expect(styles1).toEqual(nsObj({})); + expect(styles2).toEqual(nsObj({ + "style-module": "-_style_modules_css-style-module", + })); + + const style = getComputedStyle(document.body); + + expect(style.getPropertyValue("background")).toBe(" red"); + expect(style.getPropertyValue("color")).toBe(" red"); +}); diff --git a/test/configCases/css/prefer-relative/node_modules/bar.modules.css/package.json b/test/configCases/css/prefer-relative/node_modules/bar.modules.css/package.json new file mode 100644 index 00000000000..bfdbb88698b --- /dev/null +++ b/test/configCases/css/prefer-relative/node_modules/bar.modules.css/package.json @@ -0,0 +1,4 @@ +{ + "name": "bar.modules.css", + "main": "style.css" +} diff --git a/test/configCases/css/prefer-relative/node_modules/bar.modules.css/style.css b/test/configCases/css/prefer-relative/node_modules/bar.modules.css/style.css new file mode 100644 index 00000000000..36505138bc9 --- /dev/null +++ b/test/configCases/css/prefer-relative/node_modules/bar.modules.css/style.css @@ -0,0 +1,3 @@ +body { + color: blue; +} diff --git a/test/configCases/css/prefer-relative/node_modules/foo.css/package.json b/test/configCases/css/prefer-relative/node_modules/foo.css/package.json new file mode 100644 index 00000000000..f273efd2294 --- /dev/null +++ b/test/configCases/css/prefer-relative/node_modules/foo.css/package.json @@ -0,0 +1,4 @@ +{ + "name": "foo.css", + "main": "style.css" +} diff --git a/test/configCases/css/prefer-relative/node_modules/foo.css/style.css b/test/configCases/css/prefer-relative/node_modules/foo.css/style.css new file mode 100644 index 00000000000..eedeb9d0ff9 --- /dev/null +++ b/test/configCases/css/prefer-relative/node_modules/foo.css/style.css @@ -0,0 +1,3 @@ +body { + background: blue; +} diff --git a/test/configCases/css/prefer-relative/style.css b/test/configCases/css/prefer-relative/style.css new file mode 100644 index 00000000000..7aed5ec6680 --- /dev/null +++ b/test/configCases/css/prefer-relative/style.css @@ -0,0 +1,5 @@ +@import 'foo.css'; + +.style { + color: red; +} diff --git a/test/configCases/css/prefer-relative/style.modules.css b/test/configCases/css/prefer-relative/style.modules.css new file mode 100644 index 00000000000..69dc14ca454 --- /dev/null +++ b/test/configCases/css/prefer-relative/style.modules.css @@ -0,0 +1,5 @@ +@import 'bar.modules.css'; + +.style-module { + color: red; +} diff --git a/test/configCases/css/prefer-relative/test.config.js b/test/configCases/css/prefer-relative/test.config.js new file mode 100644 index 00000000000..0590757288f --- /dev/null +++ b/test/configCases/css/prefer-relative/test.config.js @@ -0,0 +1,8 @@ +module.exports = { + moduleScope(scope) { + const link = scope.window.document.createElement("link"); + link.rel = "stylesheet"; + link.href = "bundle0.css"; + scope.window.document.head.appendChild(link); + } +}; diff --git a/test/configCases/css/prefer-relative/webpack.config.js b/test/configCases/css/prefer-relative/webpack.config.js new file mode 100644 index 00000000000..cfb8e5c0346 --- /dev/null +++ b/test/configCases/css/prefer-relative/webpack.config.js @@ -0,0 +1,8 @@ +/** @type {import("../../../../").Configuration} */ +module.exports = { + target: "web", + mode: "development", + experiments: { + css: true + } +}; diff --git a/test/configCases/css/prefetch-preload-module/chunk1-a.css b/test/configCases/css/prefetch-preload-module/chunk1-a.css new file mode 100644 index 00000000000..195b6bcf6d2 --- /dev/null +++ b/test/configCases/css/prefetch-preload-module/chunk1-a.css @@ -0,0 +1,3 @@ +a { + color: red; +} diff --git a/test/configCases/css/prefetch-preload-module/chunk1-a.mjs b/test/configCases/css/prefetch-preload-module/chunk1-a.mjs new file mode 100644 index 00000000000..e69de29bb2d diff --git a/test/configCases/css/prefetch-preload-module/chunk1-b.mjs b/test/configCases/css/prefetch-preload-module/chunk1-b.mjs new file mode 100644 index 00000000000..e69de29bb2d diff --git a/test/configCases/css/prefetch-preload-module/chunk1-c.mjs b/test/configCases/css/prefetch-preload-module/chunk1-c.mjs new file mode 100644 index 00000000000..e69de29bb2d diff --git a/test/configCases/css/prefetch-preload-module/chunk1.css b/test/configCases/css/prefetch-preload-module/chunk1.css new file mode 100644 index 00000000000..195b6bcf6d2 --- /dev/null +++ b/test/configCases/css/prefetch-preload-module/chunk1.css @@ -0,0 +1,3 @@ +a { + color: red; +} diff --git a/test/configCases/css/prefetch-preload-module/chunk1.mjs b/test/configCases/css/prefetch-preload-module/chunk1.mjs new file mode 100644 index 00000000000..eedf378375d --- /dev/null +++ b/test/configCases/css/prefetch-preload-module/chunk1.mjs @@ -0,0 +1,6 @@ +export default function() { + import(/* webpackPrefetch: true, webpackChunkName: "chunk1-a" */ "./chunk1-a.mjs"); + import(/* webpackPreload: true, webpackChunkName: "chunk1-b" */ "./chunk1-b.mjs"); + import(/* webpackPreload: true, webpackChunkName: "chunk1-a-css" */ "./chunk1-a.css"); + import(/* webpackPrefetch: 10, webpackChunkName: "chunk1-c" */ "./chunk1-c.mjs"); +} diff --git a/test/configCases/css/prefetch-preload-module/chunk2.css b/test/configCases/css/prefetch-preload-module/chunk2.css new file mode 100644 index 00000000000..3b4cc03b68a --- /dev/null +++ b/test/configCases/css/prefetch-preload-module/chunk2.css @@ -0,0 +1,3 @@ +a { + color: blue; +} diff --git a/test/configCases/css/prefetch-preload-module/chunk2.mjs b/test/configCases/css/prefetch-preload-module/chunk2.mjs new file mode 100644 index 00000000000..1c565540ef9 --- /dev/null +++ b/test/configCases/css/prefetch-preload-module/chunk2.mjs @@ -0,0 +1,4 @@ +export default function() { + import(/* webpackPrefetch: true, webpackChunkName: "chunk1-a" */ "./chunk1-a.mjs"); + import(/* webpackPreload: true, webpackChunkName: "chunk1-b" */ "./chunk1-b.mjs"); +} diff --git a/test/configCases/css/prefetch-preload-module/index.mjs b/test/configCases/css/prefetch-preload-module/index.mjs new file mode 100644 index 00000000000..e3aa4c2ff5c --- /dev/null +++ b/test/configCases/css/prefetch-preload-module/index.mjs @@ -0,0 +1,92 @@ +// This config need to be set on initial evaluation to be effective +__webpack_nonce__ = "nonce"; +__webpack_public_path__ = "https://example.com/public/path/"; + +it("should prefetch and preload child chunks on chunk load", () => { + let link, script; + + expect(document.head._children).toHaveLength(2); + + // Test preload + link = document.head._children[0]; + expect(link._type).toBe("link"); + expect(link.rel).toBe("prefetch"); + expect(link.as).toBe("script"); + expect(link.href).toBe("https://example.com/public/path/chunk1.mjs"); + + // Test prefetch + link = document.head._children[1]; + expect(link._type).toBe("link"); + expect(link.rel).toBe("prefetch"); + expect(link.as).toBe("style"); + expect(link.href).toBe("https://example.com/public/path/chunk2-css.css"); + + const promise = import( + /* webpackChunkName: "chunk1", webpackPrefetch: true */ "./chunk1.mjs" + ); + + expect(document.head._children).toHaveLength(4); + + // Test normal script loading + link = document.head._children[2]; + expect(link._type).toBe("link"); + expect(link.rel).toBe("preload"); + expect(link.as).toBe("style"); + expect(link.href).toBe("https://example.com/public/path/chunk1-a-css.css"); + + link = document.head._children[3]; + expect(link._type).toBe("link"); + expect(link.rel).toBe("modulepreload"); + expect(link.href).toBe("https://example.com/public/path/chunk1-b.mjs"); + + return promise.then(() => { + expect(document.head._children).toHaveLength(6); + + link = document.head._children[4]; + expect(link._type).toBe("link"); + expect(link.rel).toBe("prefetch"); + expect(link.as).toBe("script"); + expect(link.href).toBe("https://example.com/public/path/chunk1-c.mjs"); + + link = document.head._children[5]; + expect(link._type).toBe("link"); + expect(link.rel).toBe("prefetch"); + expect(link.as).toBe("script"); + expect(link.href).toBe("https://example.com/public/path/chunk1-a.mjs"); + + const promise2 = import( + /* webpackChunkName: "chunk1", webpackPrefetch: true */ "./chunk1.mjs" + ); + + // Loading chunk1 again should not trigger prefetch/preload + expect(document.head._children).toHaveLength(6); + + const promise3 = import(/* webpackChunkName: "chunk2" */ "./chunk2.mjs"); + + expect(document.head._children).toHaveLength(6); + + return promise3.then(() => { + expect(document.head._children).toHaveLength(6); + + const promise4 = import(/* webpackChunkName: "chunk1-css" */ "./chunk1.css"); + + expect(document.head._children).toHaveLength(7); + + link = document.head._children[6]; + expect(link._type).toBe("link"); + expect(link.rel).toBe("stylesheet"); + expect(link.href).toBe("https://example.com/public/path/chunk1-css.css"); + expect(link.crossOrigin).toBe("anonymous"); + + const promise5 = import(/* webpackChunkName: "chunk2-css", webpackPrefetch: true */ "./chunk2.css"); + + expect(document.head._children).toHaveLength(8); + + link = document.head._children[7]; + expect(link._type).toBe("link"); + expect(link.rel).toBe("stylesheet"); + expect(link.href).toBe("https://example.com/public/path/chunk2-css.css"); + expect(link.crossOrigin).toBe("anonymous"); + }); + }); +}); diff --git a/test/configCases/css/prefetch-preload-module/webpack.config.js b/test/configCases/css/prefetch-preload-module/webpack.config.js new file mode 100644 index 00000000000..1d4d67a7068 --- /dev/null +++ b/test/configCases/css/prefetch-preload-module/webpack.config.js @@ -0,0 +1,24 @@ +/** @type {import("../../../../").Configuration} */ +module.exports = { + entry: "./index.mjs", + experiments: { + outputModule: true, + css: true + }, + name: "esm", + target: "web", + output: { + publicPath: "", + module: true, + filename: "bundle0.mjs", + chunkFilename: "[name].mjs", + crossOriginLoading: "anonymous", + chunkFormat: "module" + }, + performance: { + hints: false + }, + optimization: { + minimize: false + } +}; diff --git a/test/configCases/css/pure-css/index.js b/test/configCases/css/pure-css/index.js new file mode 100644 index 00000000000..3b26850a1e7 --- /dev/null +++ b/test/configCases/css/pure-css/index.js @@ -0,0 +1,14 @@ +import "./style.css"; + +it("should compile", done => { + const links = document.getElementsByTagName("link"); + const css = []; + + // Skip first because import it by default + for (const link of links.slice(1)) { + css.push(link.sheet.css); + } + + expect(css).toMatchSnapshot(); + done(); +}); diff --git a/test/configCases/css/pure-css/style.css b/test/configCases/css/pure-css/style.css new file mode 100644 index 00000000000..6d8da5a2a7b --- /dev/null +++ b/test/configCases/css/pure-css/style.css @@ -0,0 +1,39 @@ +@import url("../css-modules/style.module.css"); + +.class { + color: red; + background: var(--color); +} + +@keyframes test { + 0% { + color: red; + } + 100% { + color: blue; + } +} + +:local(.class) { + color: red; +} + +:local .class { + color: green; +} + +:global(.class) { + color: blue; +} + +:global .class { + color: white; +} + +:export { + foo: bar; +} + +.class { + animation: test 1s, test; +} diff --git a/test/configCases/css/pure-css/test.config.js b/test/configCases/css/pure-css/test.config.js new file mode 100644 index 00000000000..0590757288f --- /dev/null +++ b/test/configCases/css/pure-css/test.config.js @@ -0,0 +1,8 @@ +module.exports = { + moduleScope(scope) { + const link = scope.window.document.createElement("link"); + link.rel = "stylesheet"; + link.href = "bundle0.css"; + scope.window.document.head.appendChild(link); + } +}; diff --git a/test/configCases/css/pure-css/webpack.config.js b/test/configCases/css/pure-css/webpack.config.js new file mode 100644 index 00000000000..f3d73b2784e --- /dev/null +++ b/test/configCases/css/pure-css/webpack.config.js @@ -0,0 +1,20 @@ +/** @type {import("../../../../").Configuration} */ +module.exports = { + target: "web", + mode: "development", + module: { + rules: [ + { + test: /\.css$/i, + type: "css/global", + resolve: { + fullySpecified: true, + preferRelative: true + } + } + ] + }, + experiments: { + css: true + } +}; diff --git a/test/configCases/css/runtime-data-webpack/index.js b/test/configCases/css/runtime-data-webpack/index.js new file mode 100644 index 00000000000..46360d4fd0d --- /dev/null +++ b/test/configCases/css/runtime-data-webpack/index.js @@ -0,0 +1,7 @@ +import "./style.css"; + +it("should work", () => { + const computedStyle = getComputedStyle(document.body); + expect(computedStyle.getPropertyValue("color")).toBe(" red"); + expect(computedStyle.getPropertyValue("background")).toBe(" red"); +}); diff --git a/test/configCases/css/runtime-data-webpack/other-style.css b/test/configCases/css/runtime-data-webpack/other-style.css new file mode 100644 index 00000000000..575d19f7b0e --- /dev/null +++ b/test/configCases/css/runtime-data-webpack/other-style.css @@ -0,0 +1,3 @@ +body { + color: red; +} diff --git a/test/configCases/css/runtime-data-webpack/style.css b/test/configCases/css/runtime-data-webpack/style.css new file mode 100644 index 00000000000..812c07c7f78 --- /dev/null +++ b/test/configCases/css/runtime-data-webpack/style.css @@ -0,0 +1,5 @@ +@import "other-style.css"; + +body { + background: red; +} diff --git a/test/configCases/css/runtime-data-webpack/test.config.js b/test/configCases/css/runtime-data-webpack/test.config.js new file mode 100644 index 00000000000..a24512f1ae0 --- /dev/null +++ b/test/configCases/css/runtime-data-webpack/test.config.js @@ -0,0 +1,9 @@ +module.exports = { + moduleScope(scope) { + const link = scope.window.document.createElement("link"); + link.rel = "stylesheet"; + link.href = "bundle0.css"; + link.setAttribute("data-webpack", "test:chunk-main"); + scope.window.document.head.appendChild(link); + } +}; diff --git a/test/configCases/css/runtime-data-webpack/webpack.config.js b/test/configCases/css/runtime-data-webpack/webpack.config.js new file mode 100644 index 00000000000..1bf5d64a30d --- /dev/null +++ b/test/configCases/css/runtime-data-webpack/webpack.config.js @@ -0,0 +1,40 @@ +/** @type {import("../../../../").Configuration} */ +module.exports = { + target: "web", + mode: "development", + output: { + uniqueName: "test" + }, + plugins: [ + { + apply(compiler) { + compiler.hooks.compilation.tap("Test", compilation => { + compilation.hooks.processAssets.tap( + { + name: "Test", + stage: + compiler.webpack.Compilation.PROCESS_ASSETS_STAGE_OPTIMIZE_SIZE + }, + assets => { + const name = "bundle0.css"; + const code = assets[name].source(); + + compilation.updateAsset( + name, + new compiler.webpack.sources.RawSource( + `${code.replace( + "head{", + ".class, head, body{" + )}\n\n.after-head { color: red; }` + ) + ); + } + ); + }); + } + } + ], + experiments: { + css: true + } +}; diff --git a/test/configCases/css/runtime-document-head-get-computed-style/index.js b/test/configCases/css/runtime-document-head-get-computed-style/index.js new file mode 100644 index 00000000000..46360d4fd0d --- /dev/null +++ b/test/configCases/css/runtime-document-head-get-computed-style/index.js @@ -0,0 +1,7 @@ +import "./style.css"; + +it("should work", () => { + const computedStyle = getComputedStyle(document.body); + expect(computedStyle.getPropertyValue("color")).toBe(" red"); + expect(computedStyle.getPropertyValue("background")).toBe(" red"); +}); diff --git a/test/configCases/css/runtime-document-head-get-computed-style/other-style.css b/test/configCases/css/runtime-document-head-get-computed-style/other-style.css new file mode 100644 index 00000000000..575d19f7b0e --- /dev/null +++ b/test/configCases/css/runtime-document-head-get-computed-style/other-style.css @@ -0,0 +1,3 @@ +body { + color: red; +} diff --git a/test/configCases/css/runtime-document-head-get-computed-style/style.css b/test/configCases/css/runtime-document-head-get-computed-style/style.css new file mode 100644 index 00000000000..812c07c7f78 --- /dev/null +++ b/test/configCases/css/runtime-document-head-get-computed-style/style.css @@ -0,0 +1,5 @@ +@import "other-style.css"; + +body { + background: red; +} diff --git a/test/configCases/css/runtime-document-head-get-computed-style/test.config.js b/test/configCases/css/runtime-document-head-get-computed-style/test.config.js new file mode 100644 index 00000000000..0590757288f --- /dev/null +++ b/test/configCases/css/runtime-document-head-get-computed-style/test.config.js @@ -0,0 +1,8 @@ +module.exports = { + moduleScope(scope) { + const link = scope.window.document.createElement("link"); + link.rel = "stylesheet"; + link.href = "bundle0.css"; + scope.window.document.head.appendChild(link); + } +}; diff --git a/test/configCases/css/runtime-document-head-get-computed-style/webpack.config.js b/test/configCases/css/runtime-document-head-get-computed-style/webpack.config.js new file mode 100644 index 00000000000..7fb1039d0f9 --- /dev/null +++ b/test/configCases/css/runtime-document-head-get-computed-style/webpack.config.js @@ -0,0 +1,37 @@ +/** @type {import("../../../../").Configuration} */ +module.exports = { + target: "web", + mode: "development", + output: { + uniqueName: "test" + }, + plugins: [ + { + apply(compiler) { + compiler.hooks.compilation.tap("Test", compilation => { + compilation.hooks.processAssets.tap( + { + name: "Test", + stage: + compiler.webpack.Compilation.PROCESS_ASSETS_STAGE_OPTIMIZE_SIZE + }, + assets => { + const name = "bundle0.css"; + const code = assets[name].source(); + + compilation.updateAsset( + name, + new compiler.webpack.sources.RawSource( + `${code}\n\n.after-head { color: red; }` + ) + ); + } + ); + }); + } + } + ], + experiments: { + css: true + } +}; diff --git a/test/configCases/css/runtime-issue/asyncChunk.js b/test/configCases/css/runtime-issue/asyncChunk.js new file mode 100644 index 00000000000..7494648b883 --- /dev/null +++ b/test/configCases/css/runtime-issue/asyncChunk.js @@ -0,0 +1,2 @@ +import * as style from "./styles.js"; +export default style; \ No newline at end of file diff --git a/test/configCases/css/runtime-issue/asyncChunk2.js b/test/configCases/css/runtime-issue/asyncChunk2.js new file mode 100644 index 00000000000..7494648b883 --- /dev/null +++ b/test/configCases/css/runtime-issue/asyncChunk2.js @@ -0,0 +1,2 @@ +import * as style from "./styles.js"; +export default style; \ No newline at end of file diff --git a/test/configCases/css/runtime-issue/entry1.js b/test/configCases/css/runtime-issue/entry1.js new file mode 100644 index 00000000000..44f2df48d90 --- /dev/null +++ b/test/configCases/css/runtime-issue/entry1.js @@ -0,0 +1,14 @@ +const img = new URL("./img.png", import.meta.url); + +it("should allow to create css modules", done => { + import("./asyncChunk").then(({ default: x }) => { + try { + expect(img.toString()).toBe("https://test.cases/path/img.png"); + expect(x.default.class).toEqual("-_test_module_css-class"); + } catch (e) { + return done(e); + } + + done(); + }, done); +}); diff --git a/test/configCases/css/runtime-issue/entry2.js b/test/configCases/css/runtime-issue/entry2.js new file mode 100644 index 00000000000..3ea38823308 --- /dev/null +++ b/test/configCases/css/runtime-issue/entry2.js @@ -0,0 +1,14 @@ +const img = new URL("./img.png", import.meta.url); + +it("should allow to create css modules", done => { + import("./asyncChunk2").then(({ default: x }) => { + try { + expect(img.toString()).toBe("https://test.cases/path/img.png"); + expect(x.default.class).toEqual("-_test_module_css-class"); + } catch (e) { + return done(e); + } + + done(); + }, done); +}); diff --git a/test/configCases/css/runtime-issue/img.png b/test/configCases/css/runtime-issue/img.png new file mode 100644 index 00000000000..b74b839e2b8 Binary files /dev/null and b/test/configCases/css/runtime-issue/img.png differ diff --git a/test/configCases/css/runtime-issue/share.js b/test/configCases/css/runtime-issue/share.js new file mode 100644 index 00000000000..9bb91edb2e3 --- /dev/null +++ b/test/configCases/css/runtime-issue/share.js @@ -0,0 +1 @@ +const foo = `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa` diff --git a/test/configCases/css/runtime-issue/styles.js b/test/configCases/css/runtime-issue/styles.js new file mode 100644 index 00000000000..7034f505d08 --- /dev/null +++ b/test/configCases/css/runtime-issue/styles.js @@ -0,0 +1,2 @@ +import * as style from "./test.module.css"; +export default style; \ No newline at end of file diff --git a/test/configCases/css/runtime-issue/test.config.js b/test/configCases/css/runtime-issue/test.config.js new file mode 100644 index 00000000000..e5f431241af --- /dev/null +++ b/test/configCases/css/runtime-issue/test.config.js @@ -0,0 +1,21 @@ +module.exports = { + moduleScope(scope) { + const link1 = scope.window.document.createElement("link"); + link1.rel = "stylesheet"; + link1.href = "asyncChunk_js.css"; + scope.window.document.head.appendChild(link1); + const link2 = scope.window.document.createElement("link"); + link2.rel = "stylesheet"; + link2.href = "asyncChunk2_js.css"; + scope.window.document.head.appendChild(link2); + }, + findBundle: function (i, options) { + return [ + "./common-share_js-img_png.js", + "./asyncChunk_js.js", + "./main.js", + "./secondMain.js", + "./asyncChunk2_js.js" + ]; + } +}; diff --git a/test/configCases/css/runtime-issue/test.module.css b/test/configCases/css/runtime-issue/test.module.css new file mode 100644 index 00000000000..bfaebe6d7b7 --- /dev/null +++ b/test/configCases/css/runtime-issue/test.module.css @@ -0,0 +1,3 @@ +.class { + background-image: url('./img.png'); +} diff --git a/test/configCases/css/runtime-issue/webpack.config.js b/test/configCases/css/runtime-issue/webpack.config.js new file mode 100644 index 00000000000..8937b822ac1 --- /dev/null +++ b/test/configCases/css/runtime-issue/webpack.config.js @@ -0,0 +1,34 @@ +/** @type {import("../../../../").Configuration} */ +module.exports = { + target: "web", + mode: "development", + experiments: { + css: true + }, + entry: { + main: { + import: ["./share.js", "./entry1.js"] + }, + secondMain: { + import: ["./share.js", "./entry2.js"] + } + }, + optimization: { + splitChunks: { + chunks: "all", + cacheGroups: { + common: { + name: false, + chunks: "all", + test() { + return true; + } + } + } + } + }, + output: { + filename: "[name].js", + assetModuleFilename: "[name][ext]" + } +}; diff --git a/test/configCases/css/urls-css-filename/img1.png b/test/configCases/css/urls-css-filename/img1.png new file mode 100644 index 00000000000..b74b839e2b8 Binary files /dev/null and b/test/configCases/css/urls-css-filename/img1.png differ diff --git a/test/configCases/css/urls-css-filename/index.css b/test/configCases/css/urls-css-filename/index.css new file mode 100644 index 00000000000..f6776450de8 --- /dev/null +++ b/test/configCases/css/urls-css-filename/index.css @@ -0,0 +1,7 @@ +@import "./nested/index.css"; + +h1 { + same-dir: url('./img1.png'); + nested-dir: url('./nested/img2.png'); + nested-nested-dir: url('./nested/nested/img3.png'); +} diff --git a/test/configCases/css/urls-css-filename/index.js b/test/configCases/css/urls-css-filename/index.js new file mode 100644 index 00000000000..d7371181eed --- /dev/null +++ b/test/configCases/css/urls-css-filename/index.js @@ -0,0 +1,22 @@ +it(`should generate correct url public path with css filename`, done => { + const h1 = document.createElement('h1'); + document.body.appendChild(h1); + const h2 = document.createElement('h2'); + document.body.appendChild(h1); + const h3 = document.createElement('h3'); + document.body.appendChild(h1); + import("./index.css").then(x => { + try { + expect(x).toEqual(nsObj({})); + const style1 = getComputedStyle(h1); + expect(style1).toMatchSnapshot(); + const style2 = getComputedStyle(h2); + expect(style2).toMatchSnapshot(); + const style3 = getComputedStyle(h3); + expect(style3).toMatchSnapshot(); + done(); + } catch (e) { + done(e); + } + }, done); +}); diff --git a/test/configCases/css/urls-css-filename/nested/img2.png b/test/configCases/css/urls-css-filename/nested/img2.png new file mode 100644 index 00000000000..b74b839e2b8 Binary files /dev/null and b/test/configCases/css/urls-css-filename/nested/img2.png differ diff --git a/test/configCases/css/urls-css-filename/nested/index.css b/test/configCases/css/urls-css-filename/nested/index.css new file mode 100644 index 00000000000..e681e125745 --- /dev/null +++ b/test/configCases/css/urls-css-filename/nested/index.css @@ -0,0 +1,7 @@ +@import "./nested/index.css"; + +h2 { + same-dir: url('./img2.png'); + nested-dir: url('./nested/img3.png'); + outer-dir: url('../img1.png'); +} diff --git a/test/configCases/css/urls-css-filename/nested/nested/img3.png b/test/configCases/css/urls-css-filename/nested/nested/img3.png new file mode 100644 index 00000000000..b74b839e2b8 Binary files /dev/null and b/test/configCases/css/urls-css-filename/nested/nested/img3.png differ diff --git a/test/configCases/css/urls-css-filename/nested/nested/index.css b/test/configCases/css/urls-css-filename/nested/nested/index.css new file mode 100644 index 00000000000..acdd96d9881 --- /dev/null +++ b/test/configCases/css/urls-css-filename/nested/nested/index.css @@ -0,0 +1,5 @@ +h3 { + same-dir: url('./img3.png'); + outer-dir: url('../img2.png'); + outer-outer-dir: url('../../img1.png'); +} diff --git a/test/configCases/css/urls-css-filename/webpack.config.js b/test/configCases/css/urls-css-filename/webpack.config.js new file mode 100644 index 00000000000..962c11dc0bb --- /dev/null +++ b/test/configCases/css/urls-css-filename/webpack.config.js @@ -0,0 +1,66 @@ +/** @type {import("../../../../").Configuration} */ +const common = { + target: "web", + mode: "development", + devtool: false, + experiments: { + css: true + }, + optimization: { + splitChunks: { + cacheGroups: { + assetFixHack: { + type: "asset/resource", + chunks: "all", + name: "main", + enforce: true + }, + assetFixHack1: { + type: "asset/inline", + chunks: "all", + name: "main", + enforce: true + } + } + } + } +}; + +/** @type {import("../../../../").Configuration} */ +module.exports = [ + { + ...common, + output: { + publicPath: "auto", + cssChunkFilename: "bundle0/css/[name].css", + assetModuleFilename: "bundle0/assets/[name][ext]" + } + }, + { + ...common, + output: { + publicPath: "https://test.cases/path/", + cssChunkFilename: "bundle1/css/[name].css", + assetModuleFilename: "bundle1/assets/[name][ext]" + } + }, + { + ...common, + output: { + cssChunkFilename: "bundle2/css/[name].css" + }, + module: { + rules: [ + { + test: /\.png$/i, + type: "asset/resource", + generator: { + filename: "[name][ext]", + outputPath: "bundle2/assets/", + publicPath: "https://test.cases/path/bundle2/assets/" + } + } + ] + } + } +]; diff --git a/test/configCases/css/urls/font with spaces.eot b/test/configCases/css/urls/font with spaces.eot new file mode 100644 index 00000000000..e69de29bb2d diff --git a/test/configCases/css/urls/font.eot b/test/configCases/css/urls/font.eot new file mode 100644 index 00000000000..e69de29bb2d diff --git a/test/configCases/css/urls/font.svg b/test/configCases/css/urls/font.svg new file mode 100644 index 00000000000..e69de29bb2d diff --git a/test/configCases/css/urls/font.ttf b/test/configCases/css/urls/font.ttf new file mode 100644 index 00000000000..e69de29bb2d diff --git a/test/configCases/css/urls/font.woff b/test/configCases/css/urls/font.woff new file mode 100644 index 00000000000..e69de29bb2d diff --git a/test/configCases/css/urls/font.woff2 b/test/configCases/css/urls/font.woff2 new file mode 100644 index 00000000000..e69de29bb2d diff --git a/test/configCases/css/urls/img img.png b/test/configCases/css/urls/img img.png new file mode 100644 index 00000000000..b74b839e2b8 Binary files /dev/null and b/test/configCases/css/urls/img img.png differ diff --git a/test/configCases/css/urls/img'''img.png b/test/configCases/css/urls/img'''img.png new file mode 100644 index 00000000000..b74b839e2b8 Binary files /dev/null and b/test/configCases/css/urls/img'''img.png differ diff --git a/test/configCases/css/urls/img'() img.png b/test/configCases/css/urls/img'() img.png new file mode 100644 index 00000000000..b74b839e2b8 Binary files /dev/null and b/test/configCases/css/urls/img'() img.png differ diff --git a/test/configCases/css/urls/img'img.png b/test/configCases/css/urls/img'img.png new file mode 100644 index 00000000000..b74b839e2b8 Binary files /dev/null and b/test/configCases/css/urls/img'img.png differ diff --git a/test/configCases/css/urls/img(img.png b/test/configCases/css/urls/img(img.png new file mode 100644 index 00000000000..b74b839e2b8 Binary files /dev/null and b/test/configCases/css/urls/img(img.png differ diff --git a/test/configCases/css/urls/img)img.png b/test/configCases/css/urls/img)img.png new file mode 100644 index 00000000000..b74b839e2b8 Binary files /dev/null and b/test/configCases/css/urls/img)img.png differ diff --git a/test/configCases/css/urls/img.png b/test/configCases/css/urls/img.png new file mode 100644 index 00000000000..b74b839e2b8 Binary files /dev/null and b/test/configCases/css/urls/img.png differ diff --git a/test/configCases/css/urls/img1x.png b/test/configCases/css/urls/img1x.png new file mode 100644 index 00000000000..b74b839e2b8 Binary files /dev/null and b/test/configCases/css/urls/img1x.png differ diff --git a/test/configCases/css/urls/img2x.png b/test/configCases/css/urls/img2x.png new file mode 100644 index 00000000000..b74b839e2b8 Binary files /dev/null and b/test/configCases/css/urls/img2x.png differ diff --git a/test/configCases/css/urls/img3x.png b/test/configCases/css/urls/img3x.png new file mode 100644 index 00000000000..b74b839e2b8 Binary files /dev/null and b/test/configCases/css/urls/img3x.png differ diff --git a/test/configCases/css/urls/imgimg.png b/test/configCases/css/urls/imgimg.png new file mode 100644 index 00000000000..b74b839e2b8 Binary files /dev/null and b/test/configCases/css/urls/imgimg.png differ diff --git a/test/configCases/css/urls/imgn.png b/test/configCases/css/urls/imgn.png new file mode 100644 index 00000000000..b74b839e2b8 Binary files /dev/null and b/test/configCases/css/urls/imgn.png differ diff --git a/test/configCases/css/urls/index.js b/test/configCases/css/urls/index.js new file mode 100644 index 00000000000..ccf0e5d4083 --- /dev/null +++ b/test/configCases/css/urls/index.js @@ -0,0 +1,18 @@ +const testCase = (tagName, impFn) => { + it(`should be able to handle styles in ${tagName}.css`, done => { + const element = document.createElement(tagName); + document.body.appendChild(element); + impFn().then(x => { + try { + expect(x).toEqual(nsObj({})); + const style = getComputedStyle(element); + expect(style).toMatchSnapshot(); + done(); + } catch (e) { + done(e); + } + }, done); + }); +}; + +testCase("div", () => import("./spacing.css")); diff --git a/test/configCases/css/urls/nested.css b/test/configCases/css/urls/nested.css new file mode 100644 index 00000000000..fcf3dab244c --- /dev/null +++ b/test/configCases/css/urls/nested.css @@ -0,0 +1,5 @@ +@import url("#test"); + +.nested { + background: url('./img.png'); +} diff --git a/test/configCases/css/urls/nested/img-simple.png b/test/configCases/css/urls/nested/img-simple.png new file mode 100644 index 00000000000..b74b839e2b8 Binary files /dev/null and b/test/configCases/css/urls/nested/img-simple.png differ diff --git a/test/configCases/css/urls/nested/img.png b/test/configCases/css/urls/nested/img.png new file mode 100644 index 00000000000..b74b839e2b8 Binary files /dev/null and b/test/configCases/css/urls/nested/img.png differ diff --git a/test/configCases/css/urls/nested/other.png b/test/configCases/css/urls/nested/other.png new file mode 100644 index 00000000000..b74b839e2b8 Binary files /dev/null and b/test/configCases/css/urls/nested/other.png differ diff --git a/test/configCases/css/urls/node_modules/package/img.png b/test/configCases/css/urls/node_modules/package/img.png new file mode 100644 index 00000000000..b74b839e2b8 Binary files /dev/null and b/test/configCases/css/urls/node_modules/package/img.png differ diff --git a/test/configCases/css/urls/node_modules/package/package.json b/test/configCases/css/urls/node_modules/package/package.json new file mode 100644 index 00000000000..75b93e3b25a --- /dev/null +++ b/test/configCases/css/urls/node_modules/package/package.json @@ -0,0 +1,4 @@ +{ + "name": "package", + "version": "1.0.0" +} diff --git a/test/configCases/css/urls/other-img.png b/test/configCases/css/urls/other-img.png new file mode 100644 index 00000000000..b74b839e2b8 Binary files /dev/null and b/test/configCases/css/urls/other-img.png differ diff --git a/test/configCases/css/urls/spacing.css b/test/configCases/css/urls/spacing.css new file mode 100644 index 00000000000..71d12edf884 --- /dev/null +++ b/test/configCases/css/urls/spacing.css @@ -0,0 +1,603 @@ +@import "./nested.css"; + +div { + a: url('./img.png'); +} + +div { + b: url("./img.png"); +} + +div { + c: url(./img.png); +} + +div { + d: url("./img.png#hash"); +} + +div { + e: url( + "./img.png" + ); +} + +div { + f: green url( './img.png' ) xyz; +} + +div { + g: green url( "./img.png" ) xyz; +} + +div { + h: green url( ./img.png ) xyz; +} + +div { + i: green url(package/img.png) url(./img.png) xyz; +} + +div { + j: green url( "./img img.png" ) xyz; +} + +div { + k: green url( './img img.png' ) xyz; +} + +div { + l: green url(/img.png) xyz; +} + +div { + m: green URL(/img.png) xyz; +} + +div { + n: green uRl(/img.png) xyz; +} + +div { + --foo: url('./img.png'); +} + +div { + a1: url('./img.png'); +} + +div { + a2: url("./img.png"); +} + +div { + a3: url(./img.png); +} + +div { + a4: url("./img.png#hash"); +} + +div { + a5: url( + "./img.png" + ); +} + +div { + a6: green url( './img.png' ) xyz; +} + +div { + a7: green url( "./img.png" ) xyz; +} + +div { + a8: green url( ./img.png ) xyz; +} + +div { + a9: green url(package/img.png) url(./other-img.png) xyz; +} + +div { + a10: green url( "./img img.png" ) xyz; +} + +div { + a11: green url( './img img.png' ) xyz; +} + +div { + a12: green url(/img.png) xyz; +} + +div { + a13: green url(data:image/png;base64,AAA) url(http://example.com/image.jpg) url(//example.com/image.png) xyz; +} + +div { + a14: url("data:image/svg+xml;charset=utf-8,"); +} + +div { + a15: url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20viewBox%3D%270%200%2042%2026%27%20fill%3D%27%2523007aff%27%3E%3Crect%20width%3D%274%27%20height%3D%274%27%2F%3E%3Crect%20x%3D%278%27%20y%3D%271%27%20width%3D%2734%27%20height%3D%272%27%2F%3E%3Crect%20y%3D%2711%27%20width%3D%274%27%20height%3D%274%27%2F%3E%3Crect%20x%3D%278%27%20y%3D%2712%27%20width%3D%2734%27%20height%3D%272%27%2F%3E%3Crect%20y%3D%2722%27%20width%3D%274%27%20height%3D%274%27%2F%3E%3Crect%20x%3D%278%27%20y%3D%2723%27%20width%3D%2734%27%20height%3D%272%27%2F%3E%3C%2Fsvg%3E"); +} + +div { + a16: url('data:image/svg+xml;charset=utf-8,#filter'); +} + +div { + a17: url('data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D%5C%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%5C%22%3E%3Cfilter%20id%3D%5C%22filter%5C%22%3E%3CfeGaussianBlur%20in%3D%5C%22SourceAlpha%5C%22%20stdDeviation%3D%5C%220%5C%22%20%2F%3E%3CfeOffset%20dx%3D%5C%221%5C%22%20dy%3D%5C%222%5C%22%20result%3D%5C%22offsetblur%5C%22%20%2F%3E%3CfeFlood%20flood-color%3D%5C%22rgba(255%2C255%2C255%2C1)%5C%22%20%2F%3E%3CfeComposite%20in2%3D%5C%22offsetblur%5C%22%20operator%3D%5C%22in%5C%22%20%2F%3E%3CfeMerge%3E%3CfeMergeNode%20%2F%3E%3CfeMergeNode%20in%3D%5C%22SourceGraphic%5C%22%20%2F%3E%3C%2FfeMerge%3E%3C%2Ffilter%3E%3C%2Fsvg%3E%23filter'); +} + +div { + a18: url(#highlight); +} + +div { + a19: url('#line-marker'); +} + +@font-face { + a20: url(./font.woff) format('woff'), + url('./font.woff2') format('woff2'), + url("./font.eot") format('eot'), + url(./font.ttf) format('truetype'), + url("./font with spaces.eot") format("embedded-opentype"), + url('./font.svg#svgFontName') format('svg'), + url('./font.woff2?foo=bar') format('woff2'), + url("./font.eot?#iefix") format('embedded-opentype'), + url("./font with spaces.eot?#iefix") format('embedded-opentype'); +} + +@media (min-width: 500px) { + div { + a21: url("./img.png"); + } +} + +div { + a22: "do not use url(path)"; +} + +div { + a23: 'do not "use" url(path)'; +} + +div { + a24: -webkit-image-set(url('./img1x.png') 1x, url('./img2x.png') 2x) +} + +div { + a25: image-set(url('./img1x.png') 1x, url('./img2x.png') 2x) +} + +div { + a26: green url() xyz; +} + +div { + a27: green url('') xyz; +} + +div { + a28: green url("") xyz; +} + +div { + a29: green url(' ') xyz; +} + +div { + a30: green url( + ) xyz; +} + +div { + a40: green url(https://raw.githubusercontent.com/webpack/media/master/logo/icon.png) xyz; +} + +div { + a41: green url(//raw.githubusercontent.com/webpack/media/master/logo/icon.png) xyz; +} + +div { + a42: url("./img.png?foo"); +} + +div { + a43: url("./img.png?foo=bar"); +} + +div { + a44: url("./img.png?foo=bar#hash"); +} + +div { + a45: url("./img.png?foo=bar#hash"); +} + +div { + a46: url("./img.png?"); +} + +div { + a47: url('./img.png') url("data:image/svg+xml;charset=utf-8,") url('./img.png'); +} + +div { + a48: __URL__(); +} + +div { + a49: url('./nested/../nested/img-simple.png'); +} + +div { + a50: url('/nested/img-simple.png'); +} + +div { + a51: url('../urls/nested/img-simple.png'); +} + +div { + a52: url(./nested/img.png); +} + +div { + a53: url(nested/img.png); +} + +@font-face { + a54: url("//at.alicdn.com/t/font_515771_emcns5054x3whfr.eot"); +} + +div { + a55: -webkit-image-set(); + a56: -webkit-image-set(''); + a56: image-set(); + a58: image-set(''); + a59: image-set(""); + a60: image-set("" 1x); + a61: image-set(url()); + a62: image-set( + url() + ); + a63: image-set(URL()); + a64: image-set(url('')); + a65: image-set(url("")); + a66: image-set(url('') 1x); + a67: image-set(1x); + a68: image-set( + 1x + ); + a69: image-set(calc(1rem + 1px) 1x); + + a70: -webkit-image-set("./img1x.png" 1x, "./img2x.png" 2x); + a71: image-set("./img1x.png" 1x); + a72: image-set("./img1x.png" 1x, "./img2x.png" 2x); + a73: image-set("./img img.png" 1x, "./img img.png" 2x); + a74: image-set("./img1x.png" 1x, "./img2x.png" 2x), + image-set("./img1x.png" 1x, "./img2x.png" 2x); + a75: image-set( + "./img1x.png" 1x, + "./img2x.png" 2x, + "./img3x.png" 600dpi + ); + a76: image-set("./img1x.png?foo=bar" 1x); + a77: image-set("./img1x.png#hash" 1x); + a78: image-set("./img1x.png?#iefix" 1x); + + a79: -webkit-image-set(url("./img1x.png") 1x, url("./img2x.png") 2x); + a80: -webkit-image-set(url("./img1x.png") 1x); + a81: -webkit-image-set( + url("./img1x.png") 1x + ); + a82: image-set(url(./img1x.png) 1x); + a83: image-set( + url(./img1x.png) 1x + ); + a84: image-set(url("./img1x.png") 1x, url("./img2x.png") 2x); + a85: image-set( + url(./img1x.png) 1x, + url(./img2x.png) 2x, + url(./img3x.png) 600dpi + ); + a86: image-set(url("./img img.png") 1x, url("./img img.png") 2x); + + a87: image-set(url("./img1x.png") 1x, "./img2x.png" 2x); +} + +div { + a88: url(./img\img.png); + a89: url(./img\'img.png); + a90: url(./img\'\'\'img.png); + a91: url(./img\(img.png); + a92: url(./img\)img.png); + a93: url(./img\ img.png); + a94: url(./img\'\(\)\ img.png); + + a95: image-set( + url(./img\img.png) 1x, + url(./img\'\'\'img.png) 2x, + url(./img\'img.png) 3x, + url(./img\(img.png) 4x, + url(./img\)img.png) 5x, + url(./img\ img.png) 6x, + url(./img\'\(\)\ img.png) 7x + ); +} + +div { + a96: url("./img'''img.png"); + a97: url("./img'() img.png"); + a98: url("./img'img.png"); + a99: url("./img(img.png"); + a100: url("./img)img.png"); + a101: url('./img img.png'); + a102: url("./img img.png"); +} + +div { + a103: url('./img\ +(img.png'); + a104: url('./img\ +(img.png'); + a105: url('./img\ +(img.png'); + a106: url('./img\ +\ +\ +\ +(img.png'); +} + +div { + a107: url("./img%27%27%27img.png"); + a108: url("./img%27%28%29%20img.png"); + a109: url("./img%27img.png"); + a110: url("./img%28img.png"); + a111: url("./img%29img.png"); + a112: url("./img%20img.png"); + a113: url(./img%27%27%27img.png); + a114: url(./img%27%28%29%20img.png); + a115: url(./img%27img.png); + a116: url(./img%28img.png); + a117: url(./img%29img.png); + a118: url(./img%20img.png); +} + +div { + a119: url('img.png'); +} + +div { + a120: url("./img\'\'\'img.png"); + a121: url("./img\'\(\)\ img.png"); + a122: url("./img\'img.png"); + a123: url("./img\(img.png"); + a124: url("./img\)img.png"); + a125: url("./img\ img.png"); + a126: url("./\69\6D\67.png"); + a127: url(./\69\6D\67.png); + a128: url("./img\27img.png"); + a129: url("./img\'\28%29 img.png"); + a130: url(./img\'\28%29\ img.png); +} + +div { + a131: url('./img.png'); + a132: url('./img.png'); + + a133: url('./img.png?foo=bar'); + a134: url('./img.png?foo=bar'); + + a135: url('./img.png?foo=bar#hash'); + a136: url('./img.png?foo=bar#hash'); + + a137: url('./img.png?foo=bar'); + a138: url('./img.png?bar=foo'); + + a139: url('./img.png?foo=bar#foo'); + a140: url('./img.png?bar=foo#bar'); + + a141: url('./img.png?foo=1&bar=2'); + a142: url('./img.png?foo=2&bar=1'); +} + +div { + a143: url("data:image/svg+xml;charset=UTF-8,%3C%3Fxml%20version%3D%221.0%22%20encoding%3D%22utf-8%22%3F%3E%0A%3C!DOCTYPE%20svg%20PUBLIC%20%22-%2F%2FW3C%2F%2FDTD%20SVG%201.1%2F%2FEN%22%20%22http%3A%2F%2Fwww.w3.org%2FGraphics%2FSVG%2F1.1%2FDTD%2Fsvg11.dtd%22%3E%0A%3Csvg%20version%3D%221.1%22%20id%3D%22Layer_1%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20xmlns%3Axlink%3D%22http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink%22%20x%3D%220px%22%20y%3D%220px%22%0A%09%20width%3D%22191px%22%20height%3D%22191px%22%20viewBox%3D%220%200%20191%20191%22%20enable-background%3D%22new%200%200%20191%20191%22%20xml%3Aspace%3D%22preserve%22%3E%0A%3Cpath%20fill%3D%22%23636363%22%20d%3D%22M95.5%2C0C42.8%2C0%2C0%2C42.8%2C0%2C95.5S42.8%2C191%2C95.5%2C191S191%2C148.2%2C191%2C95.5S148.2%2C0%2C95.5%2C0z%20M95.5%2C187.6%0A%09c-50.848%2C0-92.1-41.25-92.1-92.1c0-50.848%2C41.252-92.1%2C92.1-92.1c50.85%2C0%2C92.1%2C41.252%2C92.1%2C92.1%0A%09C187.6%2C146.35%2C146.35%2C187.6%2C95.5%2C187.6z%22%2F%3E%0A%3Cg%3E%0A%09%3Cpath%20fill%3D%22%23636363%22%20d%3D%22M92.9%2C10v8.6H91v-6.5c-0.1%2C0.1-0.2%2C0.2-0.4%2C0.3c-0.2%2C0.1-0.3%2C0.2-0.4%2C0.2c-0.1%2C0-0.3%2C0.1-0.5%2C0.2%0A%09%09c-0.2%2C0.1-0.3%2C0.1-0.5%2C0.1v-1.6c0.5-0.1%2C0.9-0.3%2C1.4-0.5c0.5-0.2%2C0.8-0.5%2C1.2-0.7h1.1V10z%22%2F%3E%0A%09%3Cpath%20fill%3D%22%23636363%22%20d%3D%22M97.1%2C17.1h3.602v1.5h-5.6V18c0-0.4%2C0.1-0.8%2C0.2-1.2c0.1-0.4%2C0.3-0.6%2C0.5-0.9c0.2-0.3%2C0.5-0.5%2C0.7-0.7%0A%09%09c0.2-0.2%2C0.5-0.4%2C0.7-0.6c0.199-0.2%2C0.5-0.3%2C0.6-0.5c0.102-0.2%2C0.301-0.3%2C0.5-0.5c0.2-0.2%2C0.2-0.3%2C0.301-0.5%0A%09%09c0.101-0.2%2C0.101-0.3%2C0.101-0.5c0-0.4-0.101-0.6-0.3-0.8c-0.2-0.2-0.4-0.3-0.801-0.3c-0.699%2C0-1.399%2C0.3-2.101%2C0.9v-1.6%0A%09%09c0.7-0.5%2C1.5-0.7%2C2.5-0.7c0.399%2C0%2C0.8%2C0.1%2C1.101%2C0.2c0.301%2C0.1%2C0.601%2C0.3%2C0.899%2C0.5c0.3%2C0.2%2C0.399%2C0.5%2C0.5%2C0.8%0A%09%09c0.101%2C0.3%2C0.2%2C0.6%2C0.2%2C1s-0.102%2C0.7-0.2%2C1c-0.099%2C0.3-0.3%2C0.6-0.5%2C0.8c-0.2%2C0.2-0.399%2C0.5-0.7%2C0.7c-0.3%2C0.2-0.5%2C0.4-0.8%2C0.6%0A%09%09c-0.2%2C0.1-0.399%2C0.3-0.5%2C0.4s-0.3%2C0.3-0.5%2C0.4s-0.2%2C0.3-0.3%2C0.4C97.1%2C17%2C97.1%2C17%2C97.1%2C17.1z%22%2F%3E%0A%3C%2Fg%3E%0A%3Cg%3E%0A%09%3Cpath%20fill%3D%22%23636363%22%20d%3D%22M15%2C95.4c0%2C0.7-0.1%2C1.4-0.2%2C2c-0.1%2C0.6-0.4%2C1.1-0.7%2C1.5C13.8%2C99.3%2C13.4%2C99.6%2C12.9%2C99.8s-1%2C0.3-1.5%2C0.3%0A%09%09c-0.7%2C0-1.3-0.1-1.8-0.3v-1.5c0.4%2C0.3%2C1%2C0.4%2C1.6%2C0.4c0.6%2C0%2C1.1-0.2%2C1.5-0.7c0.4-0.5%2C0.5-1.1%2C0.5-1.9l0%2C0%0A%09%09C12.8%2C96.7%2C12.3%2C96.9%2C11.5%2C96.9c-0.3%2C0-0.7-0.102-1-0.2c-0.3-0.101-0.5-0.3-0.8-0.5c-0.3-0.2-0.4-0.5-0.5-0.8%0A%09%09c-0.1-0.3-0.2-0.7-0.2-1c0-0.4%2C0.1-0.8%2C0.2-1.2c0.1-0.4%2C0.3-0.7%2C0.6-0.9c0.3-0.2%2C0.6-0.5%2C0.9-0.6c0.3-0.1%2C0.8-0.2%2C1.2-0.2%0A%09%09c0.5%2C0%2C0.9%2C0.1%2C1.2%2C0.3c0.3%2C0.2%2C0.7%2C0.4%2C0.9%2C0.8s0.5%2C0.7%2C0.6%2C1.2S15%2C94.8%2C15%2C95.4z%20M13.1%2C94.4c0-0.2%2C0-0.4-0.1-0.6%0A%09%09c-0.1-0.2-0.1-0.4-0.2-0.5c-0.1-0.1-0.2-0.2-0.4-0.3c-0.2-0.1-0.3-0.1-0.5-0.1c-0.2%2C0-0.3%2C0-0.4%2C0.1s-0.3%2C0.2-0.3%2C0.3%0A%09%09c0%2C0.1-0.2%2C0.3-0.2%2C0.4c0%2C0.1-0.1%2C0.4-0.1%2C0.6c0%2C0.2%2C0%2C0.4%2C0.1%2C0.6c0.1%2C0.2%2C0.1%2C0.3%2C0.2%2C0.4c0.1%2C0.1%2C0.2%2C0.2%2C0.4%2C0.3%0A%09%09c0.2%2C0.1%2C0.3%2C0.1%2C0.5%2C0.1c0.2%2C0%2C0.3%2C0%2C0.4-0.1s0.2-0.2%2C0.3-0.3c0.1-0.1%2C0.2-0.2%2C0.2-0.4C13%2C94.7%2C13.1%2C94.6%2C13.1%2C94.4z%22%2F%3E%0A%3C%2Fg%3E%0A%3Cg%3E%0A%09%3Cpath%20fill%3D%22%23636363%22%20d%3D%22M176%2C99.7V98.1c0.6%2C0.4%2C1.2%2C0.602%2C2%2C0.602c0.5%2C0%2C0.8-0.102%2C1.1-0.301c0.301-0.199%2C0.4-0.5%2C0.4-0.801%0A%09%09c0-0.398-0.2-0.699-0.5-0.898c-0.3-0.2-0.8-0.301-1.3-0.301h-0.802V95h0.701c1.101%2C0%2C1.601-0.4%2C1.601-1.1c0-0.7-0.4-1-1.302-1%0A%09%09c-0.6%2C0-1.1%2C0.2-1.6%2C0.5v-1.5c0.6-0.3%2C1.301-0.4%2C2.1-0.4c0.9%2C0%2C1.5%2C0.2%2C2%2C0.6s0.701%2C0.9%2C0.701%2C1.5c0%2C1.1-0.601%2C1.8-1.701%2C2.1l0%2C0%0A%09%09c0.602%2C0.1%2C1.102%2C0.3%2C1.4%2C0.6s0.5%2C0.8%2C0.5%2C1.3c0%2C0.801-0.3%2C1.4-0.9%2C1.9c-0.6%2C0.5-1.398%2C0.7-2.398%2C0.7%0A%09%09C177.2%2C100.1%2C176.5%2C100%2C176%2C99.7z%22%2F%3E%0A%3C%2Fg%3E%0A%3Cg%3E%0A%09%3Cpath%20fill%3D%22%23636363%22%20d%3D%22M98.5%2C179.102c0%2C0.398-0.1%2C0.799-0.2%2C1.199C98.2%2C180.7%2C98%2C181%2C97.7%2C181.2s-0.601%2C0.5-0.9%2C0.601%0A%09%09c-0.3%2C0.1-0.7%2C0.199-1.2%2C0.199c-0.5%2C0-0.9-0.1-1.3-0.3c-0.4-0.2-0.7-0.399-0.9-0.8c-0.2-0.4-0.5-0.7-0.6-1.2%0A%09%09c-0.1-0.5-0.2-1-0.2-1.601c0-0.699%2C0.1-1.399%2C0.3-2c0.2-0.601%2C0.4-1.101%2C0.8-1.5c0.4-0.399%2C0.7-0.699%2C1.2-1c0.5-0.3%2C1-0.3%2C1.6-0.3%0A%09%09c0.6%2C0%2C1.2%2C0.101%2C1.5%2C0.199v1.5c-0.4-0.199-0.9-0.399-1.4-0.399c-0.3%2C0-0.6%2C0.101-0.8%2C0.2c-0.2%2C0.101-0.5%2C0.3-0.7%2C0.5%0A%09%09c-0.2%2C0.199-0.3%2C0.5-0.4%2C0.8c-0.1%2C0.301-0.2%2C0.7-0.2%2C1.101l0%2C0c0.4-0.601%2C1-0.8%2C1.8-0.8c0.3%2C0%2C0.7%2C0.1%2C0.9%2C0.199%0A%09%09c0.2%2C0.101%2C0.5%2C0.301%2C0.7%2C0.5c0.199%2C0.2%2C0.398%2C0.5%2C0.5%2C0.801C98.5%2C178.2%2C98.5%2C178.7%2C98.5%2C179.102z%20M96.7%2C179.2%0A%09%09c0-0.899-0.4-1.399-1.1-1.399c-0.2%2C0-0.3%2C0-0.5%2C0.1c-0.2%2C0.101-0.3%2C0.201-0.4%2C0.301c-0.1%2C0.101-0.2%2C0.199-0.2%2C0.4%0A%09%09c0%2C0.199-0.1%2C0.299-0.1%2C0.5c0%2C0.199%2C0%2C0.398%2C0.1%2C0.6s0.1%2C0.3%2C0.2%2C0.5c0.1%2C0.199%2C0.2%2C0.199%2C0.4%2C0.3c0.2%2C0.101%2C0.3%2C0.101%2C0.5%2C0.101%0A%09%09c0.2%2C0%2C0.3%2C0%2C0.5-0.101c0.2-0.101%2C0.301-0.199%2C0.301-0.3c0-0.1%2C0.199-0.301%2C0.199-0.399C96.6%2C179.7%2C96.7%2C179.4%2C96.7%2C179.2z%22%2F%3E%0A%3C%2Fg%3E%0A%3Ccircle%20fill%3D%22%23636363%22%20cx%3D%2295%22%20cy%3D%2295%22%20r%3D%227%22%2F%3E%0A%3C%2Fsvg%3E%0A") 50% 50%/191px no-repeat; +} + +div { + a144: url('%2E/img.png'); +} + +div { + a145: url("/img.png"); +} + +div { + /* TODO fix me */ + /*a146: url('./img.png', 'foo', './img.png', url('./img.png'));*/ + /*a147: image-set(url('./img.png', 'foo', './img.png', url('./img.png')) 1x, url("./img2x.png") 2x);*/ +} + +div { + a148: url('data:image/svg+xml,%3Csvg xmlns="http://www.w3.org/2000/svg"%3E%3Crect width="100%25" height="100%25" style="stroke: rgb(223,224,225); stroke-width: 2px; fill: none; stroke-dasharray: 6px 3px" /%3E%3C/svg%3E'); + a149: url('DATA:image/svg+xml,%3Csvg xmlns="http://www.w3.org/2000/svg"%3E%3Crect width="100%25" height="100%25" style="stroke: rgb(223,224,225); stroke-width: 2px; fill: none; stroke-dasharray: 6px 3px" /%3E%3C/svg%3E'); + a150: url('DATA:image/svg+xml,%3Csvg xmlns="http://www.w3.org/2000/svg"%3E%3Crect width="100%25" height="100%25" style="stroke: rgb(223,224,225); stroke-width: 2px; fill: none; stroke-dasharray: 6px 3px" /%3E%3C/svg%3E'); + a151: url('data:image/svg+xml;utf8,'); + a152: url('DATA:image/svg+xml;utf8,'); +} + +div { + a152: url("img.png"); +} + +div { + a153: url("nested/img.png"); +} + +div { + a154: url("nested/other.png"); +} + +div { + a155: url("package/img.png"); +} + +div { + a156: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23343a40' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M2 5l6 6 6-6'/%3e%3c/svg%3e"); +} + +div { + a157: url('data:image/svg+xml;utf8,'); +} + +div { + a158: src("http://www.example.com/pinkish.gif"); + --foo-bar: "http://www.example.com/pinkish.gif"; + a159: src(var(--foo)); +} + +div { + a160: url("img.png" param(--color var(--primary-color))); + a161: src("img.png" param(--color var(--primary-color))); +} + +div { + a162: url('img\ + i\ +mg.png\ + '); + +} + +div { + a163: url(" img.png "); +} + + +div { + a164: url( img.png bug); +} + +div { + a165: url(img\n.png); +} + +div { + a166: url(' data:image/svg+xml;utf8, '); +} + +div { + a167: url(http://example.com/image.jpg); + a168: url(http://example.com/image.jpg); +} + +div { + a169: url('data:,'); + a170: url('data:,'); +} + +div { + a171: image(ltr 'img.png#xywh=0,0,16,16', red); + a172: cross-fade(20% url(img.png), url(img.png)) +} + +div { + a172: image-set( + linear-gradient(blue, white) 1x, + linear-gradient(blue, green) 2x + ); + a173: image-set( + url("img.png") type("image/png"), + url("img.png") type("image/png") + ); + a174: image-set( + "img.png" 1x, + "img.png" 2x + ); + a175: image-set( + url("img.png") 1x, + url("img.png") 2x, + url("img.png") 3x + ); + a176: image-set( + "img.png" type("image/png"), + "img.png" type("image/png") + ) "img.png"; + a177: image-set( + "img.png" 1x type("image/png"), + "img.png" 2x type("image/png") + ); + a178: image-set( + "img.png" type("image/png") 1x, + "img.png" type("image/png") 2x + ); + a179: -webkit-image-set( + "img.png" 1x + ); + a180: -webkit-image-set( + url("img.png" var(--foo, "test.png")) 1x + ); +} + +div { + a181: src("img.png"); + a181: src( "img.png" ); + a182: src('img.png'); + a183: src('img.png' var(--foo, "test.png")); + a184: src(var(--foo, "test.png")); + a185: src(" img.png "); +} + +div { + a186: image-set("img.png"1x,"img.png"2x,"img.png"3x); + a187: image-set("img.png"1x,url("img.png")2x,"img.png"3x); + a188: image-set("img.png"1x,"img.png"2x,url("img.png")3x); + a189: image-set(url("img.png")1x,"img.png"2x,"img.png"3x); + a190: image-set("img.png"1x); + a191: image-set("img.png"1x/* test*/,/* test*/"img.png"2x); +} + +@supports (background-image: image-set("unknown.png"1x,"unknown.png"2x,"unknown.png"3x)) { + div { + a192: url("img.png"); + a193: image-set("img.png"1x); + } +} + +@supports (background-image: url("unknown.png" param(--test))) { + div { + a194: url("img.png"); + } +} + +@supports (background-image: url("unknown.png")) { + div { + a195: url("img.png"); + } +} + +@supports (display: grid) { + @media (min-width: 100px) { + @layer special { + div { + a196: url("img.png"); + } + } + } +} + +div { + a197: \u\r\l("img.png"); + a198: \image-\set("img.png"1x,"img.png"2x,"img.png"3x); + a199: \-webk\it-image-set("img.png"1x); + a200:-webkit-image-set("img.png"1x); +} diff --git a/test/configCases/css/urls/webpack.config.js b/test/configCases/css/urls/webpack.config.js new file mode 100644 index 00000000000..51a1701f6eb --- /dev/null +++ b/test/configCases/css/urls/webpack.config.js @@ -0,0 +1,30 @@ +/** @type {import("../../../../").Configuration} */ +module.exports = { + target: "web", + mode: "development", + devtool: false, + experiments: { + css: true + }, + output: { + assetModuleFilename: "[name].[hash][ext][query][fragment]" + }, + optimization: { + splitChunks: { + cacheGroups: { + assetFixHack: { + type: "asset/resource", + chunks: "all", + name: "main", + enforce: true + }, + assetFixHack1: { + type: "asset/inline", + chunks: "all", + name: "main", + enforce: true + } + } + } + } +}; diff --git a/test/configCases/custom-hash-function/debug-hash/files/file1.js b/test/configCases/custom-hash-function/debug-hash/files/file1.js new file mode 100644 index 00000000000..3cec1b77aad --- /dev/null +++ b/test/configCases/custom-hash-function/debug-hash/files/file1.js @@ -0,0 +1 @@ +module.exports = module.id; diff --git a/test/configCases/custom-hash-function/debug-hash/files/file10.js b/test/configCases/custom-hash-function/debug-hash/files/file10.js new file mode 100644 index 00000000000..3cec1b77aad --- /dev/null +++ b/test/configCases/custom-hash-function/debug-hash/files/file10.js @@ -0,0 +1 @@ +module.exports = module.id; diff --git a/test/configCases/custom-hash-function/debug-hash/files/file11.js b/test/configCases/custom-hash-function/debug-hash/files/file11.js new file mode 100644 index 00000000000..3cec1b77aad --- /dev/null +++ b/test/configCases/custom-hash-function/debug-hash/files/file11.js @@ -0,0 +1 @@ +module.exports = module.id; diff --git a/test/configCases/custom-hash-function/debug-hash/files/file12.js b/test/configCases/custom-hash-function/debug-hash/files/file12.js new file mode 100644 index 00000000000..3cec1b77aad --- /dev/null +++ b/test/configCases/custom-hash-function/debug-hash/files/file12.js @@ -0,0 +1 @@ +module.exports = module.id; diff --git a/test/configCases/custom-hash-function/debug-hash/files/file13.js b/test/configCases/custom-hash-function/debug-hash/files/file13.js new file mode 100644 index 00000000000..3cec1b77aad --- /dev/null +++ b/test/configCases/custom-hash-function/debug-hash/files/file13.js @@ -0,0 +1 @@ +module.exports = module.id; diff --git a/test/configCases/custom-hash-function/debug-hash/files/file14.js b/test/configCases/custom-hash-function/debug-hash/files/file14.js new file mode 100644 index 00000000000..3cec1b77aad --- /dev/null +++ b/test/configCases/custom-hash-function/debug-hash/files/file14.js @@ -0,0 +1 @@ +module.exports = module.id; diff --git a/test/configCases/custom-hash-function/debug-hash/files/file15.js b/test/configCases/custom-hash-function/debug-hash/files/file15.js new file mode 100644 index 00000000000..3cec1b77aad --- /dev/null +++ b/test/configCases/custom-hash-function/debug-hash/files/file15.js @@ -0,0 +1 @@ +module.exports = module.id; diff --git a/test/configCases/custom-hash-function/debug-hash/files/file2.js b/test/configCases/custom-hash-function/debug-hash/files/file2.js new file mode 100644 index 00000000000..3cec1b77aad --- /dev/null +++ b/test/configCases/custom-hash-function/debug-hash/files/file2.js @@ -0,0 +1 @@ +module.exports = module.id; diff --git a/test/configCases/custom-hash-function/debug-hash/files/file3.js b/test/configCases/custom-hash-function/debug-hash/files/file3.js new file mode 100644 index 00000000000..3cec1b77aad --- /dev/null +++ b/test/configCases/custom-hash-function/debug-hash/files/file3.js @@ -0,0 +1 @@ +module.exports = module.id; diff --git a/test/configCases/custom-hash-function/debug-hash/files/file4.js b/test/configCases/custom-hash-function/debug-hash/files/file4.js new file mode 100644 index 00000000000..3cec1b77aad --- /dev/null +++ b/test/configCases/custom-hash-function/debug-hash/files/file4.js @@ -0,0 +1 @@ +module.exports = module.id; diff --git a/test/configCases/custom-hash-function/debug-hash/files/file5.js b/test/configCases/custom-hash-function/debug-hash/files/file5.js new file mode 100644 index 00000000000..3cec1b77aad --- /dev/null +++ b/test/configCases/custom-hash-function/debug-hash/files/file5.js @@ -0,0 +1 @@ +module.exports = module.id; diff --git a/test/configCases/custom-hash-function/debug-hash/files/file6.js b/test/configCases/custom-hash-function/debug-hash/files/file6.js new file mode 100644 index 00000000000..3cec1b77aad --- /dev/null +++ b/test/configCases/custom-hash-function/debug-hash/files/file6.js @@ -0,0 +1 @@ +module.exports = module.id; diff --git a/test/configCases/custom-hash-function/debug-hash/files/file7.js b/test/configCases/custom-hash-function/debug-hash/files/file7.js new file mode 100644 index 00000000000..3cec1b77aad --- /dev/null +++ b/test/configCases/custom-hash-function/debug-hash/files/file7.js @@ -0,0 +1 @@ +module.exports = module.id; diff --git a/test/configCases/custom-hash-function/debug-hash/files/file8.js b/test/configCases/custom-hash-function/debug-hash/files/file8.js new file mode 100644 index 00000000000..3cec1b77aad --- /dev/null +++ b/test/configCases/custom-hash-function/debug-hash/files/file8.js @@ -0,0 +1 @@ +module.exports = module.id; diff --git a/test/configCases/custom-hash-function/debug-hash/files/file9.js b/test/configCases/custom-hash-function/debug-hash/files/file9.js new file mode 100644 index 00000000000..3cec1b77aad --- /dev/null +++ b/test/configCases/custom-hash-function/debug-hash/files/file9.js @@ -0,0 +1 @@ +module.exports = module.id; diff --git a/test/configCases/custom-hash-function/debug-hash/index.js b/test/configCases/custom-hash-function/debug-hash/index.js new file mode 100644 index 00000000000..7b74a5a384f --- /dev/null +++ b/test/configCases/custom-hash-function/debug-hash/index.js @@ -0,0 +1,8 @@ +it("debug hash should works", function () { + var ids = []; + for(var i = 1; i <= 15; i++) { + var id = require("./files/file" + i + ".js"); + expect(ids.indexOf(id)).toBe(-1); + ids.push(id); + } +}); diff --git a/test/configCases/custom-hash-function/debug-hash/webpack.config.js b/test/configCases/custom-hash-function/debug-hash/webpack.config.js new file mode 100644 index 00000000000..ee9e650c781 --- /dev/null +++ b/test/configCases/custom-hash-function/debug-hash/webpack.config.js @@ -0,0 +1,8 @@ +/** @type {import("../../../../").Configuration[]} */ +module.exports = [ + { + output: { + hashFunction: "debug" + } + } +]; diff --git a/test/configCases/custom-modules/json-custom/index.js b/test/configCases/custom-modules/json-custom/index.js index 995f4cb2e8a..adad70f603c 100644 --- a/test/configCases/custom-modules/json-custom/index.js +++ b/test/configCases/custom-modules/json-custom/index.js @@ -1,5 +1,13 @@ import toml from "../_files/data.toml"; it("should transform toml to json", () => { - expect(toml).toMatchSnapshot(); + expect(toml).toMatchObject({ + title: "TOML Example", + owner: { + name: 'Tom Preston-Werner', + organization: 'GitHub', + bio: 'GitHub Cofounder & CEO\nLikes tater tots and beer.', + dob: '1979-05-27T07:32:00.000Z' + } + }); }); diff --git a/test/configCases/custom-source-type/localization/index.js b/test/configCases/custom-source-type/localization/index.js index b24aae77623..36cde08e00e 100644 --- a/test/configCases/custom-source-type/localization/index.js +++ b/test/configCases/custom-source-type/localization/index.js @@ -4,13 +4,13 @@ it("should generate the correct output files", () => { __STATS__.children[INDEX].assets.map(asset => asset.name).sort() ).toEqual( [ - NORMAL1 && `634.bundle${INDEX}.js`, - NORMAL2 && `882.bundle${INDEX}.js`, + NORMAL1 && `286.bundle${INDEX}.js`, + NORMAL2 && `678.bundle${INDEX}.js`, `bundle${INDEX}.js`, - "localization-219.js", - CONTENT2 && "localization-551.js", - NORMAL1 && "localization-634.js", - NORMAL2 && "localization-882.js" + "localization-248.js", + NORMAL1 && "localization-286.js", + NORMAL2 && "localization-678.js", + CONTENT2 && "localization-702.js" ].filter(Boolean) ); }); @@ -37,7 +37,7 @@ if (NORMAL1) { it("should still load normal chunks", () => { if (TARGET === "web") { Promise.resolve().then(() => { - __non_webpack_require__(`./634.bundle${INDEX}.js`); + __non_webpack_require__(`./286.bundle${INDEX}.js`); }); } @@ -51,7 +51,7 @@ if (NORMAL2) { it("should still another load normal chunks", () => { if (TARGET === "web") { Promise.resolve().then(() => { - __non_webpack_require__(`./882.bundle${INDEX}.js`); + __non_webpack_require__(`./678.bundle${INDEX}.js`); }); } diff --git a/test/configCases/custom-source-type/localization/webpack.config.js b/test/configCases/custom-source-type/localization/webpack.config.js index de405aa3103..9fdbe5ab131 100644 --- a/test/configCases/custom-source-type/localization/webpack.config.js +++ b/test/configCases/custom-source-type/localization/webpack.config.js @@ -126,15 +126,11 @@ module.exports = definitions.map((defs, i) => ({ (compilation, { normalModuleFactory }) => { normalModuleFactory.hooks.createParser .for("localization") - .tap("LocalizationPlugin", () => { - return new LocalizationParser(); - }); + .tap("LocalizationPlugin", () => new LocalizationParser()); normalModuleFactory.hooks.createGenerator .for("localization") - .tap("LocalizationPlugin", () => { - return new LocalizationGenerator(); - }); + .tap("LocalizationPlugin", () => new LocalizationGenerator()); compilation.chunkTemplate.hooks.renderManifest.tap( "LocalizationPlugin", @@ -153,7 +149,7 @@ module.exports = definitions.map((defs, i) => ({ module.buildInfo.content; } return new RawSource( - "module.exports = " + JSON.stringify(data) + `module.exports = ${JSON.stringify(data)}` ); }, filenameTemplate: "localization-[id].js", diff --git a/test/configCases/delegated-hash/simple/warnings.js b/test/configCases/delegated-hash/simple/warnings.js index 5d0640d1c37..70fefa270fb 100644 --- a/test/configCases/delegated-hash/simple/warnings.js +++ b/test/configCases/delegated-hash/simple/warnings.js @@ -1,3 +1 @@ -module.exports = [ - [/hashed/, /deprecated/] -]; +module.exports = [[/hashed/, /deprecated/]]; diff --git a/test/configCases/deprecations/chunk-files/webpack.config.js b/test/configCases/deprecations/chunk-files/webpack.config.js index 9ce90994174..b393f4cfbc2 100644 --- a/test/configCases/deprecations/chunk-files/webpack.config.js +++ b/test/configCases/deprecations/chunk-files/webpack.config.js @@ -4,7 +4,10 @@ module.exports = { compiler => { compiler.hooks.done.tap("Test", ({ compilation }) => { for (const c of compilation.chunks) { - const chunk = /** @type {{ files: string[] } & import("../../../../").Chunk} */ (c); + const chunk = + /** @type {{ files: string[] } & import("../../../../").Chunk} */ ( + c + ); expect(chunk.files.length).toBe(chunk.files.size); expect(chunk.files[0]).toBe(Array.from(chunk.files)[0]); expect(chunk.files.join(",")).toBe(Array.from(chunk.files).join(",")); diff --git a/test/configCases/deprecations/invalid-dependencies/loader.js b/test/configCases/deprecations/invalid-dependencies/loader.js index 47a39616b26..71212ed09b8 100644 --- a/test/configCases/deprecations/invalid-dependencies/loader.js +++ b/test/configCases/deprecations/invalid-dependencies/loader.js @@ -1,3 +1,4 @@ +/** @type {import("../../../../").LoaderDefinition} */ module.exports = function (source) { this.addDependency("loader.js"); this.addDependency("../**/dir/*.js"); diff --git a/test/configCases/deprecations/non-unique-hash/webpack.config.js b/test/configCases/deprecations/non-unique-hash/webpack.config.js index 85ca72dd924..67d797d831e 100644 --- a/test/configCases/deprecations/non-unique-hash/webpack.config.js +++ b/test/configCases/deprecations/non-unique-hash/webpack.config.js @@ -23,7 +23,7 @@ module.exports = { )) { hashes.push(module.hash); } - }).toThrowError( + }).toThrow( /No unique hash info entry for unspecified runtime .+ \(existing runtimes: a, b\)\.\n.+opt-out via optimization\.usedExports: "global"/ ); }); diff --git a/test/configCases/devtools/eval-nosources-source-map/index.js b/test/configCases/devtools/eval-nosources-source-map/index.js new file mode 100644 index 00000000000..288699bbbd7 --- /dev/null +++ b/test/configCases/devtools/eval-nosources-source-map/index.js @@ -0,0 +1,11 @@ +it("should not include sourcesContent if noSources option is used", function() { + var fs = require("fs"); + var source = fs.readFileSync(__filename, "utf-8"); + var match = /\/\/# sourceMappingURL\s*=\s*data:application\/json;charset=utf-8;base64,(.*)\\n\/\/#/.exec(source); + var mapString = Buffer.from(match[1], 'base64').toString('utf-8'); + var map = JSON.parse(mapString); + expect(map).not.toHaveProperty("sourcesContent"); + expect(/\.js(\?.+)?$/.test(map.file)).toBe(true); +}); + +if (Math.random() < 0) require("./test.js"); diff --git a/test/configCases/devtools/eval-nosources-source-map/index.ts b/test/configCases/devtools/eval-nosources-source-map/index.ts new file mode 100644 index 00000000000..5178739ea8d --- /dev/null +++ b/test/configCases/devtools/eval-nosources-source-map/index.ts @@ -0,0 +1,11 @@ +it("should not include sourcesContent if noSources option is used", function() { + var fs = require("fs"); + var source = fs.readFileSync(__filename, "utf-8"); + var match = /\/\/# sourceMappingURL\s*=\s*data:application\/json;charset=utf-8;base64,(.*)\\n\/\/#/.exec(source); + var mapString = Buffer.from(match[1], 'base64').toString('utf-8'); + var map = JSON.parse(mapString); + expect(map).not.toHaveProperty("sourcesContent"); + expect(/\.ts(\?.+)?$/.test(map.file)).toBe(true); +}); + +if (Math.random() < 0) require("./test.js"); diff --git a/test/configCases/devtools/eval-nosources-source-map/node_modules/pkg/index.js b/test/configCases/devtools/eval-nosources-source-map/node_modules/pkg/index.js new file mode 100644 index 00000000000..d171d00eb94 --- /dev/null +++ b/test/configCases/devtools/eval-nosources-source-map/node_modules/pkg/index.js @@ -0,0 +1 @@ +import "../../index.js"; diff --git a/test/configCases/devtools/eval-nosources-source-map/test.filter.js b/test/configCases/devtools/eval-nosources-source-map/test.filter.js new file mode 100644 index 00000000000..698f2822d2d --- /dev/null +++ b/test/configCases/devtools/eval-nosources-source-map/test.filter.js @@ -0,0 +1,5 @@ +var supportsOptionalChaining = require("../../../helpers/supportsOptionalChaining"); + +module.exports = function (config) { + return supportsOptionalChaining(); +}; diff --git a/test/configCases/devtools/eval-nosources-source-map/test.js b/test/configCases/devtools/eval-nosources-source-map/test.js new file mode 100644 index 00000000000..c9d8865844b --- /dev/null +++ b/test/configCases/devtools/eval-nosources-source-map/test.js @@ -0,0 +1,3 @@ +var foo = {}; + +module.exports = foo; diff --git a/test/configCases/devtools/eval-nosources-source-map/webpack.config.js b/test/configCases/devtools/eval-nosources-source-map/webpack.config.js new file mode 100644 index 00000000000..3319debc4f8 --- /dev/null +++ b/test/configCases/devtools/eval-nosources-source-map/webpack.config.js @@ -0,0 +1,83 @@ +const devtool = "eval-nosources-source-map"; + +/** @type {import("../../../../").Configuration[]} */ +module.exports = [ + { + devtool + }, + { + devtool, + optimization: { + moduleIds: "natural" + } + }, + { + devtool, + optimization: { + moduleIds: "named" + } + }, + { + devtool, + optimization: { + moduleIds: "deterministic" + } + }, + { + devtool, + optimization: { + moduleIds: "size" + } + }, + { + entry: "./index?foo=bar", + devtool, + optimization: { + moduleIds: "named" + } + }, + { + entry: "./index.js?foo=bar", + devtool, + optimization: { + moduleIds: "named" + } + }, + { + entry: "alias", + devtool, + optimization: { + moduleIds: "named" + }, + resolve: { + alias: { + alias: "./index?foo=bar" + } + } + }, + { + entry: "pkg", + devtool, + optimization: { + moduleIds: "named" + } + }, + { + entry: "./index.ts?foo=bar", + devtool, + optimization: { + moduleIds: "named" + }, + module: { + rules: [ + { + test: /\.ts$/, + loader: "ts-loader", + options: { + transpileOnly: true + } + } + ] + } + } +]; diff --git a/test/configCases/devtools/eval-source-map/index.js b/test/configCases/devtools/eval-source-map/index.js new file mode 100644 index 00000000000..13b57720b66 --- /dev/null +++ b/test/configCases/devtools/eval-source-map/index.js @@ -0,0 +1,11 @@ +it("should not include sourcesContent if noSources option is used", function() { + var fs = require("fs"); + var source = fs.readFileSync(__filename, "utf-8"); + var match = /\/\/# sourceMappingURL\s*=\s*data:application\/json;charset=utf-8;base64,(.*)\\n\/\/#/.exec(source); + var mapString = Buffer.from(match[1], 'base64').toString('utf-8'); + var map = JSON.parse(mapString); + expect(map).toHaveProperty("sourcesContent"); + expect(/\.js(\?.+)?$/.test(map.file)).toBe(true); +}); + +if (Math.random() < 0) require("./test.js"); diff --git a/test/configCases/devtools/eval-source-map/index.ts b/test/configCases/devtools/eval-source-map/index.ts new file mode 100644 index 00000000000..bae246dd86c --- /dev/null +++ b/test/configCases/devtools/eval-source-map/index.ts @@ -0,0 +1,11 @@ +it("should not include sourcesContent if noSources option is used", function() { + var fs = require("fs"); + var source = fs.readFileSync(__filename, "utf-8"); + var match = /\/\/# sourceMappingURL\s*=\s*data:application\/json;charset=utf-8;base64,(.*)\\n\/\/#/.exec(source); + var mapString = Buffer.from(match[1], 'base64').toString('utf-8'); + var map = JSON.parse(mapString); + expect(map).toHaveProperty("sourcesContent"); + expect(/\.ts(\?.+)?$/.test(map.file)).toBe(true); +}); + +if (Math.random() < 0) require("./test.js"); diff --git a/test/configCases/devtools/eval-source-map/node_modules/pkg/index.js b/test/configCases/devtools/eval-source-map/node_modules/pkg/index.js new file mode 100644 index 00000000000..d171d00eb94 --- /dev/null +++ b/test/configCases/devtools/eval-source-map/node_modules/pkg/index.js @@ -0,0 +1 @@ +import "../../index.js"; diff --git a/test/configCases/devtools/eval-source-map/test.filter.js b/test/configCases/devtools/eval-source-map/test.filter.js new file mode 100644 index 00000000000..698f2822d2d --- /dev/null +++ b/test/configCases/devtools/eval-source-map/test.filter.js @@ -0,0 +1,5 @@ +var supportsOptionalChaining = require("../../../helpers/supportsOptionalChaining"); + +module.exports = function (config) { + return supportsOptionalChaining(); +}; diff --git a/test/configCases/devtools/eval-source-map/test.js b/test/configCases/devtools/eval-source-map/test.js new file mode 100644 index 00000000000..c9d8865844b --- /dev/null +++ b/test/configCases/devtools/eval-source-map/test.js @@ -0,0 +1,3 @@ +var foo = {}; + +module.exports = foo; diff --git a/test/configCases/devtools/eval-source-map/webpack.config.js b/test/configCases/devtools/eval-source-map/webpack.config.js new file mode 100644 index 00000000000..44225d67bb2 --- /dev/null +++ b/test/configCases/devtools/eval-source-map/webpack.config.js @@ -0,0 +1,83 @@ +const devtool = "eval-source-map"; + +/** @type {import("../../../../").Configuration[]} */ +module.exports = [ + { + devtool + }, + { + devtool, + optimization: { + moduleIds: "natural" + } + }, + { + devtool, + optimization: { + moduleIds: "named" + } + }, + { + devtool, + optimization: { + moduleIds: "deterministic" + } + }, + { + devtool, + optimization: { + moduleIds: "size" + } + }, + { + entry: "./index?foo=bar", + devtool, + optimization: { + moduleIds: "named" + } + }, + { + entry: "./index.js?foo=bar", + devtool, + optimization: { + moduleIds: "named" + } + }, + { + entry: "alias", + devtool, + optimization: { + moduleIds: "named" + }, + resolve: { + alias: { + alias: "./index?foo=bar" + } + } + }, + { + entry: "pkg", + devtool, + optimization: { + moduleIds: "named" + } + }, + { + entry: "./index.ts?foo=bar", + devtool, + optimization: { + moduleIds: "named" + }, + module: { + rules: [ + { + test: /\.ts$/, + loader: "ts-loader", + options: { + transpileOnly: true + } + } + ] + } + } +]; diff --git a/test/configCases/dll-plugin-entry/0-create-dll/test.config.js b/test/configCases/dll-plugin-entry/0-create-dll/test.config.js index 08ea6c319c8..04581a81040 100644 --- a/test/configCases/dll-plugin-entry/0-create-dll/test.config.js +++ b/test/configCases/dll-plugin-entry/0-create-dll/test.config.js @@ -1 +1 @@ -exports.noTests = true; +module.exports.noTests = true; diff --git a/test/configCases/dll-plugin-entry/1-use-dll/webpack.config.js b/test/configCases/dll-plugin-entry/1-use-dll/webpack.config.js index 461b1dc69d6..9db6069b115 100644 --- a/test/configCases/dll-plugin-entry/1-use-dll/webpack.config.js +++ b/test/configCases/dll-plugin-entry/1-use-dll/webpack.config.js @@ -7,7 +7,7 @@ module.exports = { }, plugins: [ new webpack.DllReferencePlugin({ - manifest: require("../../../js/config/dll-plugin-entry/manifest0.json"), // eslint-disable-line node/no-missing-require + manifest: require("../../../js/config/dll-plugin-entry/manifest0.json"), name: "../0-create-dll/dll.js", scope: "dll", sourceType: "commonjs2" diff --git a/test/configCases/dll-plugin-entry/2-error-non-entry/webpack.config.js b/test/configCases/dll-plugin-entry/2-error-non-entry/webpack.config.js index 461b1dc69d6..9db6069b115 100644 --- a/test/configCases/dll-plugin-entry/2-error-non-entry/webpack.config.js +++ b/test/configCases/dll-plugin-entry/2-error-non-entry/webpack.config.js @@ -7,7 +7,7 @@ module.exports = { }, plugins: [ new webpack.DllReferencePlugin({ - manifest: require("../../../js/config/dll-plugin-entry/manifest0.json"), // eslint-disable-line node/no-missing-require + manifest: require("../../../js/config/dll-plugin-entry/manifest0.json"), name: "../0-create-dll/dll.js", scope: "dll", sourceType: "commonjs2" diff --git a/test/configCases/dll-plugin-format/0-create-dll/test.config.js b/test/configCases/dll-plugin-format/0-create-dll/test.config.js index 08ea6c319c8..04581a81040 100644 --- a/test/configCases/dll-plugin-format/0-create-dll/test.config.js +++ b/test/configCases/dll-plugin-format/0-create-dll/test.config.js @@ -1 +1 @@ -exports.noTests = true; +module.exports.noTests = true; diff --git a/test/configCases/dll-plugin-side-effects/0-create-dll/test.config.js b/test/configCases/dll-plugin-side-effects/0-create-dll/test.config.js index 08ea6c319c8..04581a81040 100644 --- a/test/configCases/dll-plugin-side-effects/0-create-dll/test.config.js +++ b/test/configCases/dll-plugin-side-effects/0-create-dll/test.config.js @@ -1 +1 @@ -exports.noTests = true; +module.exports.noTests = true; diff --git a/test/configCases/dll-plugin-side-effects/1-use-dll/webpack.config.js b/test/configCases/dll-plugin-side-effects/1-use-dll/webpack.config.js index 14b447481e5..97da7ef588c 100644 --- a/test/configCases/dll-plugin-side-effects/1-use-dll/webpack.config.js +++ b/test/configCases/dll-plugin-side-effects/1-use-dll/webpack.config.js @@ -4,7 +4,7 @@ var webpack = require("../../../../"); module.exports = { plugins: [ new webpack.DllReferencePlugin({ - manifest: require("../../../js/config/dll-plugin-side-effects/manifest0.json"), // eslint-disable-line node/no-missing-require + manifest: require("../../../js/config/dll-plugin-side-effects/manifest0.json"), name: "../0-create-dll/dll.js", scope: "dll", sourceType: "commonjs2" diff --git a/test/configCases/dll-plugin/0-create-dll-with-contenthash/_d.js b/test/configCases/dll-plugin/0-create-dll-with-contenthash/_d.js new file mode 100644 index 00000000000..d108c9a3722 --- /dev/null +++ b/test/configCases/dll-plugin/0-create-dll-with-contenthash/_d.js @@ -0,0 +1 @@ +import "./d"; \ No newline at end of file diff --git a/test/configCases/dll-plugin/0-create-dll-with-contenthash/_e.js b/test/configCases/dll-plugin/0-create-dll-with-contenthash/_e.js new file mode 100644 index 00000000000..586eb3aa06b --- /dev/null +++ b/test/configCases/dll-plugin/0-create-dll-with-contenthash/_e.js @@ -0,0 +1,3 @@ +import "./e1"; +import "./e2"; +import "./e"; \ No newline at end of file diff --git a/test/configCases/dll-plugin/0-create-dll-with-contenthash/a.js b/test/configCases/dll-plugin/0-create-dll-with-contenthash/a.js new file mode 100644 index 00000000000..6cd1d0075d4 --- /dev/null +++ b/test/configCases/dll-plugin/0-create-dll-with-contenthash/a.js @@ -0,0 +1 @@ +module.exports = "a"; diff --git a/test/configCases/dll-plugin/0-create-dll-with-contenthash/b.js b/test/configCases/dll-plugin/0-create-dll-with-contenthash/b.js new file mode 100644 index 00000000000..58a90d8f841 --- /dev/null +++ b/test/configCases/dll-plugin/0-create-dll-with-contenthash/b.js @@ -0,0 +1,3 @@ +module.exports = function() { + return import("./c"); +} diff --git a/test/configCases/dll-plugin/0-create-dll-with-contenthash/c.js b/test/configCases/dll-plugin/0-create-dll-with-contenthash/c.js new file mode 100644 index 00000000000..b2091de76d6 --- /dev/null +++ b/test/configCases/dll-plugin/0-create-dll-with-contenthash/c.js @@ -0,0 +1 @@ +export default "c"; \ No newline at end of file diff --git a/test/configCases/dll-plugin/0-create-dll-with-contenthash/d.js b/test/configCases/dll-plugin/0-create-dll-with-contenthash/d.js new file mode 100644 index 00000000000..987d6d7e401 --- /dev/null +++ b/test/configCases/dll-plugin/0-create-dll-with-contenthash/d.js @@ -0,0 +1 @@ +export default "d"; diff --git a/test/configCases/dll-plugin/0-create-dll-with-contenthash/e.js b/test/configCases/dll-plugin/0-create-dll-with-contenthash/e.js new file mode 100644 index 00000000000..9fbe80f85cf --- /dev/null +++ b/test/configCases/dll-plugin/0-create-dll-with-contenthash/e.js @@ -0,0 +1,4 @@ +export * from "./e1"; +export * from "./ee2"; + +console.log.bind(console); // side effect to avoid removing module diff --git a/test/configCases/dll-plugin/0-create-dll-with-contenthash/e1.js b/test/configCases/dll-plugin/0-create-dll-with-contenthash/e1.js new file mode 100644 index 00000000000..23709cd95ff --- /dev/null +++ b/test/configCases/dll-plugin/0-create-dll-with-contenthash/e1.js @@ -0,0 +1,3 @@ +export * from "./ee1"; + +console.log.bind(console); // side effect to avoid removing module diff --git a/test/configCases/dll-plugin/0-create-dll-with-contenthash/e2.js b/test/configCases/dll-plugin/0-create-dll-with-contenthash/e2.js new file mode 100644 index 00000000000..25612746b57 --- /dev/null +++ b/test/configCases/dll-plugin/0-create-dll-with-contenthash/e2.js @@ -0,0 +1,3 @@ +export * from "./ee2"; + +console.log.bind(console); // side effect to avoid removing module diff --git a/test/configCases/dll-plugin/0-create-dll-with-contenthash/ee1.js b/test/configCases/dll-plugin/0-create-dll-with-contenthash/ee1.js new file mode 100644 index 00000000000..359c69fe3e7 --- /dev/null +++ b/test/configCases/dll-plugin/0-create-dll-with-contenthash/ee1.js @@ -0,0 +1,2 @@ +export var x1 = 123; +export var y1 = 456; \ No newline at end of file diff --git a/test/configCases/dll-plugin/0-create-dll-with-contenthash/ee2.js b/test/configCases/dll-plugin/0-create-dll-with-contenthash/ee2.js new file mode 100644 index 00000000000..634e1a91947 --- /dev/null +++ b/test/configCases/dll-plugin/0-create-dll-with-contenthash/ee2.js @@ -0,0 +1,2 @@ +export var x2 = 123; +export var y2 = 456; \ No newline at end of file diff --git a/test/configCases/dll-plugin/0-create-dll-with-contenthash/f.jsx b/test/configCases/dll-plugin/0-create-dll-with-contenthash/f.jsx new file mode 100644 index 00000000000..61445975b07 --- /dev/null +++ b/test/configCases/dll-plugin/0-create-dll-with-contenthash/f.jsx @@ -0,0 +1 @@ +module.exports = 'f'; \ No newline at end of file diff --git a/test/configCases/dll-plugin/0-create-dll-with-contenthash/g-loader.js b/test/configCases/dll-plugin/0-create-dll-with-contenthash/g-loader.js new file mode 100644 index 00000000000..c6d8a635121 --- /dev/null +++ b/test/configCases/dll-plugin/0-create-dll-with-contenthash/g-loader.js @@ -0,0 +1,4 @@ +/** @type {import("../../../../").LoaderDefinition} */ +module.exports = function (source) { + return source; +}; diff --git a/test/configCases/dll-plugin/0-create-dll-with-contenthash/g.abc.js b/test/configCases/dll-plugin/0-create-dll-with-contenthash/g.abc.js new file mode 100644 index 00000000000..483352ffbff --- /dev/null +++ b/test/configCases/dll-plugin/0-create-dll-with-contenthash/g.abc.js @@ -0,0 +1 @@ +module.exports = typeof module.id; diff --git a/test/configCases/dll-plugin/0-create-dll-with-contenthash/h.js b/test/configCases/dll-plugin/0-create-dll-with-contenthash/h.js new file mode 100644 index 00000000000..1fa89a4fb1c --- /dev/null +++ b/test/configCases/dll-plugin/0-create-dll-with-contenthash/h.js @@ -0,0 +1 @@ +export { B } from "./h1.js"; diff --git a/test/configCases/dll-plugin/0-create-dll-with-contenthash/h1.js b/test/configCases/dll-plugin/0-create-dll-with-contenthash/h1.js new file mode 100644 index 00000000000..a392743d956 --- /dev/null +++ b/test/configCases/dll-plugin/0-create-dll-with-contenthash/h1.js @@ -0,0 +1,2 @@ +export { A } from "./ha.js"; +export { B } from "./hb.js"; diff --git a/test/configCases/dll-plugin/0-create-dll-with-contenthash/ha.js b/test/configCases/dll-plugin/0-create-dll-with-contenthash/ha.js new file mode 100644 index 00000000000..6506d8d86b2 --- /dev/null +++ b/test/configCases/dll-plugin/0-create-dll-with-contenthash/ha.js @@ -0,0 +1 @@ +export const A = "A"; \ No newline at end of file diff --git a/test/configCases/dll-plugin/0-create-dll-with-contenthash/hb.js b/test/configCases/dll-plugin/0-create-dll-with-contenthash/hb.js new file mode 100644 index 00000000000..f3c1f2c5d79 --- /dev/null +++ b/test/configCases/dll-plugin/0-create-dll-with-contenthash/hb.js @@ -0,0 +1 @@ +export const B = "B"; \ No newline at end of file diff --git a/test/configCases/dll-plugin/0-create-dll-with-contenthash/test.config.js b/test/configCases/dll-plugin/0-create-dll-with-contenthash/test.config.js new file mode 100644 index 00000000000..04581a81040 --- /dev/null +++ b/test/configCases/dll-plugin/0-create-dll-with-contenthash/test.config.js @@ -0,0 +1 @@ +module.exports.noTests = true; diff --git a/test/configCases/dll-plugin/0-create-dll-with-contenthash/webpack.config.js b/test/configCases/dll-plugin/0-create-dll-with-contenthash/webpack.config.js new file mode 100644 index 00000000000..124c663928e --- /dev/null +++ b/test/configCases/dll-plugin/0-create-dll-with-contenthash/webpack.config.js @@ -0,0 +1,44 @@ +var path = require("path"); +var webpack = require("../../../../"); + +/** @type {import("../../../../").Configuration} */ +module.exports = { + entry: ["./a", "./b", "./_d", "./_e", "./f", "./g.abc", "./h"], + resolve: { + extensions: [".js", ".jsx"] + }, + output: { + filename: "dll.js", + chunkFilename: "[id].dll.js", + libraryTarget: "commonjs2" + }, + module: { + rules: [ + { + test: /\.abc\.js$/, + loader: "./g-loader.js", + options: { + test: 1 + } + }, + { + test: /0-create-dll.h/, + sideEffects: false + } + ] + }, + optimization: { + usedExports: true, + sideEffects: true + }, + plugins: [ + new webpack.DllPlugin({ + path: path.resolve( + __dirname, + "../../../js/config/dll-plugin/manifest0.json" + ), + name: "[name]_[contenthash]", + entryOnly: false + }) + ] +}; diff --git a/test/configCases/dll-plugin/0-create-dll/g-loader.js b/test/configCases/dll-plugin/0-create-dll/g-loader.js index 6e64f4af6bb..c6d8a635121 100644 --- a/test/configCases/dll-plugin/0-create-dll/g-loader.js +++ b/test/configCases/dll-plugin/0-create-dll/g-loader.js @@ -1,3 +1,4 @@ -module.exports = function(source) { +/** @type {import("../../../../").LoaderDefinition} */ +module.exports = function (source) { return source; }; diff --git a/test/configCases/dll-plugin/0-create-dll/test.config.js b/test/configCases/dll-plugin/0-create-dll/test.config.js index 08ea6c319c8..04581a81040 100644 --- a/test/configCases/dll-plugin/0-create-dll/test.config.js +++ b/test/configCases/dll-plugin/0-create-dll/test.config.js @@ -1 +1 @@ -exports.noTests = true; +module.exports.noTests = true; diff --git a/test/configCases/dll-plugin/0-issue-10475/test.config.js b/test/configCases/dll-plugin/0-issue-10475/test.config.js index 08ea6c319c8..04581a81040 100644 --- a/test/configCases/dll-plugin/0-issue-10475/test.config.js +++ b/test/configCases/dll-plugin/0-issue-10475/test.config.js @@ -1 +1 @@ -exports.noTests = true; +module.exports.noTests = true; diff --git a/test/configCases/dll-plugin/1-issue-10475/webpack.config.js b/test/configCases/dll-plugin/1-issue-10475/webpack.config.js index d1cf3a50e8b..64ccc2bd2ed 100644 --- a/test/configCases/dll-plugin/1-issue-10475/webpack.config.js +++ b/test/configCases/dll-plugin/1-issue-10475/webpack.config.js @@ -4,7 +4,7 @@ var webpack = require("../../../../"); module.exports = { plugins: [ new webpack.DllReferencePlugin({ - manifest: require("../../../js/config/dll-plugin/issue-10475.json"), // eslint-disable-line node/no-missing-require + manifest: require("../../../js/config/dll-plugin/issue-10475.json"), name: "../0-issue-10475/dll.js", scope: "dll", sourceType: "commonjs2" diff --git a/test/configCases/dll-plugin/1-use-dll/webpack.config.js b/test/configCases/dll-plugin/1-use-dll/webpack.config.js index dc432da78a6..e1d2044fc50 100644 --- a/test/configCases/dll-plugin/1-use-dll/webpack.config.js +++ b/test/configCases/dll-plugin/1-use-dll/webpack.config.js @@ -7,7 +7,7 @@ module.exports = { }, plugins: [ new webpack.DllReferencePlugin({ - manifest: require("../../../js/config/dll-plugin/manifest0.json"), // eslint-disable-line node/no-missing-require + manifest: require("../../../js/config/dll-plugin/manifest0.json"), name: "../0-create-dll/dll.js", scope: "dll", sourceType: "commonjs2", diff --git a/test/configCases/dll-plugin/2-use-dll-without-scope/webpack.config.js b/test/configCases/dll-plugin/2-use-dll-without-scope/webpack.config.js index 0f50727568e..3dabdbd25f1 100644 --- a/test/configCases/dll-plugin/2-use-dll-without-scope/webpack.config.js +++ b/test/configCases/dll-plugin/2-use-dll-without-scope/webpack.config.js @@ -26,7 +26,7 @@ module.exports = { }, plugins: [ new webpack.DllReferencePlugin({ - manifest: require("../../../js/config/dll-plugin/manifest0.json"), // eslint-disable-line node/no-missing-require + manifest: require("../../../js/config/dll-plugin/manifest0.json"), name: "../0-create-dll/dll.js", context: path.resolve(__dirname, "../0-create-dll"), sourceType: "commonjs2" diff --git a/test/configCases/dll-plugin/3-use-dll-with-hashid/warnings.js b/test/configCases/dll-plugin/3-use-dll-with-hashid/warnings.js index 5d0640d1c37..70fefa270fb 100644 --- a/test/configCases/dll-plugin/3-use-dll-with-hashid/warnings.js +++ b/test/configCases/dll-plugin/3-use-dll-with-hashid/warnings.js @@ -1,3 +1 @@ -module.exports = [ - [/hashed/, /deprecated/] -]; +module.exports = [[/hashed/, /deprecated/]]; diff --git a/test/configCases/dll-plugin/3-use-dll-with-hashid/webpack.config.js b/test/configCases/dll-plugin/3-use-dll-with-hashid/webpack.config.js index a065fa62528..9276c2d77e0 100644 --- a/test/configCases/dll-plugin/3-use-dll-with-hashid/webpack.config.js +++ b/test/configCases/dll-plugin/3-use-dll-with-hashid/webpack.config.js @@ -23,7 +23,7 @@ module.exports = { }, plugins: [ new webpack.DllReferencePlugin({ - manifest: require("../../../js/config/dll-plugin/manifest0.json"), // eslint-disable-line node/no-missing-require + manifest: require("../../../js/config/dll-plugin/manifest0.json"), name: "../0-create-dll/dll.js", context: path.resolve(__dirname, "../0-create-dll"), sourceType: "commonjs2" diff --git a/test/configCases/dll-plugin/4-use-dll-with-contenthash/e.js b/test/configCases/dll-plugin/4-use-dll-with-contenthash/e.js new file mode 100644 index 00000000000..f490fc4645b --- /dev/null +++ b/test/configCases/dll-plugin/4-use-dll-with-contenthash/e.js @@ -0,0 +1,2 @@ +export * from "dll/e1"; +export * from "dll/e2"; diff --git a/test/configCases/dll-plugin/4-use-dll-with-contenthash/index.js b/test/configCases/dll-plugin/4-use-dll-with-contenthash/index.js new file mode 100644 index 00000000000..d771fcdc8c0 --- /dev/null +++ b/test/configCases/dll-plugin/4-use-dll-with-contenthash/index.js @@ -0,0 +1,60 @@ +import d from "dll/d"; +import { x1, y2 } from "./e"; +import { x2, y1 } from "dll/e"; +import { B } from "dll/h"; + +it("should load a module from dll", function() { + expect(require("dll/a")).toBe("a"); +}); + +it("should load a module of non-default type without extension from dll", function() { + expect(require("dll/f")).toBe("f"); +}); + +it("should load an async module from dll", function(done) { + require("dll/b")() + .then(function(c) { + expect(c).toEqual(nsObj({ default: "c" })); + done(); + }) + .catch(done); +}); + +it("should load an harmony module from dll (default export)", function() { + expect(d).toBe("d"); +}); + +it("should load an harmony module from dll (star export)", function() { + expect(x1).toBe(123); + expect(x2).toBe(123); + expect(y1).toBe(456); + expect(y2).toBe(456); +}); + +it("should load a module with loader applied", function() { + expect(require("dll/g.abc.js")).toBe("number"); +}); + +it("should give modules the correct ids", function() { + expect( + Object.keys(__webpack_modules__) + .filter(m => !m.startsWith("../..")) + .sort() + ).toEqual([ + "./index.js", + "dll-reference ../0-create-dll-with-contenthash/dll.js", + "dll/a.js", + "dll/b.js", + "dll/d.js", + "dll/e.js", + "dll/e1.js", + "dll/e2.js", + "dll/f.jsx", + "dll/g.abc.js", + "dll/h.js" + ]); +}); + +it("should not crash on side-effect-free modules", function() { + expect(B).toBe("B"); +}); diff --git a/test/configCases/dll-plugin/4-use-dll-with-contenthash/webpack.config.js b/test/configCases/dll-plugin/4-use-dll-with-contenthash/webpack.config.js new file mode 100644 index 00000000000..bd045cd8bb5 --- /dev/null +++ b/test/configCases/dll-plugin/4-use-dll-with-contenthash/webpack.config.js @@ -0,0 +1,17 @@ +var webpack = require("../../../../"); + +/** @type {import("../../../../").Configuration} */ +module.exports = { + optimization: { + moduleIds: "named" + }, + plugins: [ + new webpack.DllReferencePlugin({ + manifest: require("../../../js/config/dll-plugin/manifest0.json"), + name: "../0-create-dll-with-contenthash/dll.js", + scope: "dll", + sourceType: "commonjs2", + extensions: [".js", ".jsx"] + }) + ] +}; diff --git a/test/configCases/dll-plugin/5-issue-18200/a.js b/test/configCases/dll-plugin/5-issue-18200/a.js new file mode 100644 index 00000000000..6cd1d0075d4 --- /dev/null +++ b/test/configCases/dll-plugin/5-issue-18200/a.js @@ -0,0 +1 @@ +module.exports = "a"; diff --git a/test/configCases/dll-plugin/5-issue-18200/b.js b/test/configCases/dll-plugin/5-issue-18200/b.js new file mode 100644 index 00000000000..dfbbeb621fa --- /dev/null +++ b/test/configCases/dll-plugin/5-issue-18200/b.js @@ -0,0 +1 @@ +module.exports = "b"; diff --git a/test/configCases/dll-plugin/5-issue-18200/errors.js b/test/configCases/dll-plugin/5-issue-18200/errors.js new file mode 100644 index 00000000000..48720d5cbae --- /dev/null +++ b/test/configCases/dll-plugin/5-issue-18200/errors.js @@ -0,0 +1 @@ +module.exports = [[/each chunk must have a unique path/]]; diff --git a/test/configCases/dll-plugin/5-issue-18200/webpack.config.js b/test/configCases/dll-plugin/5-issue-18200/webpack.config.js new file mode 100644 index 00000000000..d88fb4399f6 --- /dev/null +++ b/test/configCases/dll-plugin/5-issue-18200/webpack.config.js @@ -0,0 +1,22 @@ +var path = require("path"); +var webpack = require("../../../../"); + +/** @type {import("../../../../").Configuration} */ +module.exports = { + entry: { + a: "./a", + b: "./b" + }, + output: { + filename: "MyDll.[name].js", + library: "[name]_[fullhash]" + }, + plugins: [ + new webpack.DllPlugin({ + path: path.resolve( + __dirname, + "../../../js/config/dll-plugin/manifest_without_string_template.json" + ) + }) + ] +}; diff --git a/test/configCases/ecmaVersion/browserslist-config-env/webpack.config.js b/test/configCases/ecmaVersion/browserslist-config-env/webpack.config.js index 51d962293bf..47b717ab3c7 100644 --- a/test/configCases/ecmaVersion/browserslist-config-env/webpack.config.js +++ b/test/configCases/ecmaVersion/browserslist-config-env/webpack.config.js @@ -9,12 +9,19 @@ module.exports = { expect(compilation.outputOptions.environment).toMatchInlineSnapshot(` Object { "arrowFunction": false, + "asyncFunction": false, "bigIntLiteral": false, "const": false, "destructuring": false, + "document": true, "dynamicImport": false, + "dynamicImportInWorker": false, "forOf": false, + "globalThis": false, "module": false, + "nodePrefixForCoreModules": false, + "optionalChaining": false, + "templateLiteral": false, } `); expect(compilation.options.externalsPresets).toMatchInlineSnapshot(` diff --git a/test/configCases/ecmaVersion/browserslist-config/webpack.config.js b/test/configCases/ecmaVersion/browserslist-config/webpack.config.js index de46a168768..6772fe11465 100644 --- a/test/configCases/ecmaVersion/browserslist-config/webpack.config.js +++ b/test/configCases/ecmaVersion/browserslist-config/webpack.config.js @@ -9,12 +9,19 @@ module.exports = { expect(compilation.outputOptions.environment).toMatchInlineSnapshot(` Object { "arrowFunction": false, + "asyncFunction": false, "bigIntLiteral": false, "const": false, "destructuring": false, + "document": true, "dynamicImport": false, + "dynamicImportInWorker": false, "forOf": false, + "globalThis": false, "module": false, + "nodePrefixForCoreModules": false, + "optionalChaining": false, + "templateLiteral": false, } `); expect(compilation.options.externalsPresets).toMatchInlineSnapshot(` diff --git a/test/configCases/ecmaVersion/browserslist-missing/test.filter.js b/test/configCases/ecmaVersion/browserslist-missing/test.filter.js new file mode 100644 index 00000000000..d5852188b3e --- /dev/null +++ b/test/configCases/ecmaVersion/browserslist-missing/test.filter.js @@ -0,0 +1 @@ +module.exports = config => !config.cache; diff --git a/test/configCases/ecmaVersion/browserslist-query/webpack.config.js b/test/configCases/ecmaVersion/browserslist-query/webpack.config.js index 16f9a494b21..5a2b52a97aa 100644 --- a/test/configCases/ecmaVersion/browserslist-query/webpack.config.js +++ b/test/configCases/ecmaVersion/browserslist-query/webpack.config.js @@ -7,12 +7,19 @@ module.exports = { expect(compilation.outputOptions.environment).toMatchInlineSnapshot(` Object { "arrowFunction": false, + "asyncFunction": false, "bigIntLiteral": false, "const": false, "destructuring": false, + "document": true, "dynamicImport": false, + "dynamicImportInWorker": false, "forOf": false, + "globalThis": false, "module": false, + "nodePrefixForCoreModules": false, + "optionalChaining": false, + "templateLiteral": false, } `); expect(compilation.options.externalsPresets).toMatchInlineSnapshot(` diff --git a/test/configCases/ecmaVersion/browserslist/webpack.config.js b/test/configCases/ecmaVersion/browserslist/webpack.config.js index 7fda0c72cbb..cbaaab50eda 100644 --- a/test/configCases/ecmaVersion/browserslist/webpack.config.js +++ b/test/configCases/ecmaVersion/browserslist/webpack.config.js @@ -7,12 +7,19 @@ module.exports = { expect(compilation.outputOptions.environment).toMatchInlineSnapshot(` Object { "arrowFunction": true, + "asyncFunction": true, "bigIntLiteral": true, "const": true, "destructuring": true, - "dynamicImport": false, + "document": false, + "dynamicImport": true, + "dynamicImportInWorker": false, "forOf": true, - "module": false, + "globalThis": true, + "module": true, + "nodePrefixForCoreModules": true, + "optionalChaining": true, + "templateLiteral": true, } `); expect(compilation.options.externalsPresets).toMatchInlineSnapshot(` diff --git a/test/configCases/ecmaVersion/loader-context/index.js b/test/configCases/ecmaVersion/loader-context/index.js new file mode 100644 index 00000000000..71b94e507ee --- /dev/null +++ b/test/configCases/ecmaVersion/loader-context/index.js @@ -0,0 +1,9 @@ +import mod from "./loader.js!./module"; + +it("should compile and export target and environment", function() { + expect(mod.target).toBe("node"); + expect(mod.environment.globalThis).toBe(false); + expect(mod.environment.optionalChaining).toBe(true); + expect(mod.environment.templateLiteral).toBe(true); + expect(mod.environment.dynamicImportInWorker).toBe(true); +}); diff --git a/test/configCases/ecmaVersion/loader-context/loader.js b/test/configCases/ecmaVersion/loader-context/loader.js new file mode 100644 index 00000000000..1a1f276bb41 --- /dev/null +++ b/test/configCases/ecmaVersion/loader-context/loader.js @@ -0,0 +1,7 @@ +/** @type {import("../../../../types").LoaderDefinition<{}>} */ +module.exports = function loader(content) { + const target = this.target; + const environment = this.environment; + + return `export default ${JSON.stringify({ target, environment})}`; +} diff --git a/test/configCases/ecmaVersion/loader-context/module.js b/test/configCases/ecmaVersion/loader-context/module.js new file mode 100644 index 00000000000..58c57157d36 --- /dev/null +++ b/test/configCases/ecmaVersion/loader-context/module.js @@ -0,0 +1 @@ +export default "test"; diff --git a/test/configCases/ecmaVersion/loader-context/webpack.config.js b/test/configCases/ecmaVersion/loader-context/webpack.config.js new file mode 100644 index 00000000000..72cbad754c1 --- /dev/null +++ b/test/configCases/ecmaVersion/loader-context/webpack.config.js @@ -0,0 +1,10 @@ +/** @type {import("../../../../").Configuration} */ +module.exports = { + target: ["node", "es2020"], + output: { + environment: { + // Our target supports `globalThis`, but for test purposes we set it to `false` + globalThis: false + } + } +}; diff --git a/test/configCases/entry/adding-multiple-entry-points/test.config.js b/test/configCases/entry/adding-multiple-entry-points/test.config.js index 7dc1c935450..b8ab195d3ea 100644 --- a/test/configCases/entry/adding-multiple-entry-points/test.config.js +++ b/test/configCases/entry/adding-multiple-entry-points/test.config.js @@ -1,8 +1,5 @@ module.exports = { - findBundle: function() { - return [ - "./runtime~main.js", - "./main.js" - ] + findBundle: function () { + return ["./runtime~main.js", "./main.js"]; } }; diff --git a/test/configCases/entry/depend-on-advanced/other-vendors.js b/test/configCases/entry/depend-on-advanced/other-vendors.js index e68b8aef6ee..8d844056e1a 100644 --- a/test/configCases/entry/depend-on-advanced/other-vendors.js +++ b/test/configCases/entry/depend-on-advanced/other-vendors.js @@ -1,5 +1,4 @@ import lodash from "lodash"; -import isomorphicFetch from "isomorphic-fetch"; import { set } from "test"; set("ok"); diff --git a/test/configCases/entry/depend-on-advanced/page2.js b/test/configCases/entry/depend-on-advanced/page2.js new file mode 100644 index 00000000000..32f96417bc7 --- /dev/null +++ b/test/configCases/entry/depend-on-advanced/page2.js @@ -0,0 +1,26 @@ +import isomorphicFetch from "isomorphic-fetch"; +import react from "react"; +import reactDOM from "react-dom"; + +it("should be able to load the modules", () => { + expect(isomorphicFetch).toBe("isomorphic-fetch"); + expect(react).toBe("react"); + expect(reactDOM).toBe("react-dom"); +}); + +it("should have the correct modules in a lazy chunk", () => { + const promise = import(/* webpackChunkName: "lazy" */ "./lazy").then( + module => { + module.default(); + } + ); + __non_webpack_require__("./lazy.js"); + if (document.head._children[0]) document.head._children[0].onload(); + return promise; +}); + +import { value } from "test"; + +it("other-vendors should run too", () => { + expect(value).toBe("ok"); +}); diff --git a/test/configCases/entry/depend-on-advanced/page3.js b/test/configCases/entry/depend-on-advanced/page3.js new file mode 100644 index 00000000000..32f96417bc7 --- /dev/null +++ b/test/configCases/entry/depend-on-advanced/page3.js @@ -0,0 +1,26 @@ +import isomorphicFetch from "isomorphic-fetch"; +import react from "react"; +import reactDOM from "react-dom"; + +it("should be able to load the modules", () => { + expect(isomorphicFetch).toBe("isomorphic-fetch"); + expect(react).toBe("react"); + expect(reactDOM).toBe("react-dom"); +}); + +it("should have the correct modules in a lazy chunk", () => { + const promise = import(/* webpackChunkName: "lazy" */ "./lazy").then( + module => { + module.default(); + } + ); + __non_webpack_require__("./lazy.js"); + if (document.head._children[0]) document.head._children[0].onload(); + return promise; +}); + +import { value } from "test"; + +it("other-vendors should run too", () => { + expect(value).toBe("ok"); +}); diff --git a/test/configCases/entry/depend-on-advanced/test.config.js b/test/configCases/entry/depend-on-advanced/test.config.js index 588de636e28..003c340f108 100644 --- a/test/configCases/entry/depend-on-advanced/test.config.js +++ b/test/configCases/entry/depend-on-advanced/test.config.js @@ -1,11 +1,13 @@ module.exports = { - findBundle: function() { + findBundle: function () { return [ "./app.js", "./runtime.js", "./page1.js", "./react-vendors.js", - "./other-vendors.js" + "./page2.js", + "./other-vendors.js", + "./page3.js" ]; } }; diff --git a/test/configCases/entry/depend-on-advanced/webpack.config.js b/test/configCases/entry/depend-on-advanced/webpack.config.js index 0bb6c323e3c..132a9802405 100644 --- a/test/configCases/entry/depend-on-advanced/webpack.config.js +++ b/test/configCases/entry/depend-on-advanced/webpack.config.js @@ -9,6 +9,8 @@ module.exports = { return Promise.resolve({ app: { import: "./app.js", dependOn: ["other-vendors"] }, page1: { import: "./page1.js", dependOn: ["app", "react-vendors"] }, + page2: { import: "./page2.js", dependOn: ["app", "react-vendors"] }, + page3: { import: "./page3.js", dependOn: ["app"] }, "react-vendors": ["react", "react-dom", "prop-types"], "other-vendors": "./other-vendors" }); @@ -37,21 +39,29 @@ module.exports = { chunkModules[chunk.name] = new Set(); for (const module of chunkGraph.getChunkModulesIterable(chunk)) { - chunkModules[chunk.name].add(module); + chunkModules[chunk.name].add(module.identifier()); } } - expect([...chunkModules.app]).toStrictEqual( - expect.not.arrayContaining([...chunkModules["other-vendors"]]) - ); + for (const module of chunkModules["other-vendors"]) { + expect([...chunkModules.app]).not.toContain(module); + } + + for (const module of [ + ...chunkModules["other-vendors"], + ...chunkModules["react-vendors"], + ...chunkModules.app + ]) { + expect(chunkModules.page1).not.toContain(module); + expect(chunkModules.page2).not.toContain(module); + } - expect([...chunkModules.page1]).toStrictEqual( - expect.not.arrayContaining([ - ...chunkModules["other-vendors"], - ...chunkModules["react-vendors"], - ...chunkModules["app"] - ]) - ); + for (const module of [ + ...chunkModules["other-vendors"], + ...chunkModules.app + ]) { + expect([...chunkModules.page3]).not.toContain(module); + } }); }; this.hooks.compilation.tap("testcase", handler); diff --git a/test/configCases/entry/depend-on-bug/app.js b/test/configCases/entry/depend-on-bug/app.js new file mode 100644 index 00000000000..b6eb6a3130b --- /dev/null +++ b/test/configCases/entry/depend-on-bug/app.js @@ -0,0 +1 @@ +import isomorphicFetch from "isomorphic-fetch"; diff --git a/test/configCases/entry/depend-on-bug/node_modules/isomorphic-fetch.js b/test/configCases/entry/depend-on-bug/node_modules/isomorphic-fetch.js new file mode 100644 index 00000000000..ce0c36b3158 --- /dev/null +++ b/test/configCases/entry/depend-on-bug/node_modules/isomorphic-fetch.js @@ -0,0 +1 @@ +module.exports = "isomorphic-fetch"; diff --git a/test/configCases/entry/depend-on-bug/other-vendors.js b/test/configCases/entry/depend-on-bug/other-vendors.js new file mode 100644 index 00000000000..e69de29bb2d diff --git a/test/configCases/entry/depend-on-bug/page1.js b/test/configCases/entry/depend-on-bug/page1.js new file mode 100644 index 00000000000..36a7db85bbe --- /dev/null +++ b/test/configCases/entry/depend-on-bug/page1.js @@ -0,0 +1,7 @@ +import isomorphicFetch from "isomorphic-fetch"; + +it("should run", () => { + expect( + __STATS__.modules.find(m => m.name.includes("isomorphic-fetch")).chunks + ).toHaveLength(1); +}); diff --git a/test/configCases/entry/depend-on-bug/test.config.js b/test/configCases/entry/depend-on-bug/test.config.js new file mode 100644 index 00000000000..8f1c48be6ee --- /dev/null +++ b/test/configCases/entry/depend-on-bug/test.config.js @@ -0,0 +1,5 @@ +module.exports = { + findBundle: function () { + return ["./other-vendors.js", "./page1.js", "./app.js"]; + } +}; diff --git a/test/configCases/entry/depend-on-bug/webpack.config.js b/test/configCases/entry/depend-on-bug/webpack.config.js new file mode 100644 index 00000000000..e55145af4c7 --- /dev/null +++ b/test/configCases/entry/depend-on-bug/webpack.config.js @@ -0,0 +1,19 @@ +/** @typedef {import("../../../../").Compiler} Compiler */ +/** @typedef {import("../../../../").Compilation} Compilation */ +/** @typedef {import("../../../../").Configuration} Configuration */ + +/** @type {Configuration} */ +/** @type {import("../../../../").Configuration} */ +module.exports = { + entry() { + return Promise.resolve({ + app: { import: "./app.js", dependOn: ["other-vendors"] }, + page1: { import: "./page1.js", dependOn: ["app"] }, + "other-vendors": "./other-vendors" + }); + }, + target: "web", + output: { + filename: "[name].js" + } +}; diff --git a/test/configCases/entry/depend-on-non-js/a.css b/test/configCases/entry/depend-on-non-js/a.css new file mode 100644 index 00000000000..58362a94448 --- /dev/null +++ b/test/configCases/entry/depend-on-non-js/a.css @@ -0,0 +1 @@ +module.exports = [[module.id, "body { background-color: green; }"]]; diff --git a/test/configCases/entry/depend-on-non-js/a.js b/test/configCases/entry/depend-on-non-js/a.js new file mode 100644 index 00000000000..bc7652000f3 --- /dev/null +++ b/test/configCases/entry/depend-on-non-js/a.js @@ -0,0 +1 @@ +if (Math.random() < 0) require("./a.css"); diff --git a/test/configCases/entry/depend-on-non-js/b.css b/test/configCases/entry/depend-on-non-js/b.css new file mode 100644 index 00000000000..867e7070dc8 --- /dev/null +++ b/test/configCases/entry/depend-on-non-js/b.css @@ -0,0 +1 @@ +module.exports = [[module.id, "body { color: red; }"]]; diff --git a/test/configCases/entry/depend-on-non-js/b.js b/test/configCases/entry/depend-on-non-js/b.js new file mode 100644 index 00000000000..7c96074e6e3 --- /dev/null +++ b/test/configCases/entry/depend-on-non-js/b.js @@ -0,0 +1,3 @@ +if (Math.random() < 0) require("./b.css"); + +it("should run the test", () => {}); diff --git a/test/configCases/entry/depend-on-non-js/test.config.js b/test/configCases/entry/depend-on-non-js/test.config.js new file mode 100644 index 00000000000..390f166e411 --- /dev/null +++ b/test/configCases/entry/depend-on-non-js/test.config.js @@ -0,0 +1,5 @@ +module.exports = { + findBundle: function () { + return ["./runtime.js", "./a.js", "./b.js"]; + } +}; diff --git a/test/configCases/entry/depend-on-non-js/webpack.config.js b/test/configCases/entry/depend-on-non-js/webpack.config.js new file mode 100644 index 00000000000..1d85d3a86ad --- /dev/null +++ b/test/configCases/entry/depend-on-non-js/webpack.config.js @@ -0,0 +1,38 @@ +const MiniCssPlugin = require("mini-css-extract-plugin"); + +/** @type {import("../../../../").Configuration} */ +module.exports = { + entry: { + a: "./a.js", + b: { import: "./b.js", dependOn: "a" } + }, + module: { + rules: [ + { + test: /\.css$/, + loader: MiniCssPlugin.loader + } + ] + }, + output: { + filename: "[name].js" + }, + optimization: { + runtimeChunk: "single", + splitChunks: { + chunks: "all", + cacheGroups: { + styles: { + type: "css/mini-extract", + enforce: true + } + } + } + }, + target: "web", + plugins: [ + new MiniCssPlugin({ + experimentalUseImportModule: true + }) + ] +}; diff --git a/test/configCases/entry/depend-on-simple/test.config.js b/test/configCases/entry/depend-on-simple/test.config.js index 2685941d7ce..d8f78e1e848 100644 --- a/test/configCases/entry/depend-on-simple/test.config.js +++ b/test/configCases/entry/depend-on-simple/test.config.js @@ -1,5 +1,5 @@ module.exports = { - findBundle: function() { + findBundle: function () { return ["./app.js", "./react-vendors.js"]; } }; diff --git a/test/configCases/entry/descriptor/test.config.js b/test/configCases/entry/descriptor/test.config.js index 8a5b96a8434..e4c1c3811ca 100644 --- a/test/configCases/entry/descriptor/test.config.js +++ b/test/configCases/entry/descriptor/test.config.js @@ -1,8 +1,5 @@ module.exports = { - findBundle: function() { - return [ - "./a.js", - "./b.js" - ] + findBundle: function () { + return ["./a.js", "./b.js"]; } }; diff --git a/test/configCases/entry/entry-base-uri/1.jpg b/test/configCases/entry/entry-base-uri/1.jpg new file mode 100644 index 00000000000..e69de29bb2d diff --git a/test/configCases/entry/entry-base-uri/index.js b/test/configCases/entry/entry-base-uri/index.js new file mode 100644 index 00000000000..7d00291f23b --- /dev/null +++ b/test/configCases/entry/entry-base-uri/index.js @@ -0,0 +1,5 @@ +const jpg = new URL("./1.jpg", import.meta.url); + +it("should provide custom base uri", () => { + expect(jpg.toString()).toBe("my-scheme://baseuri/1.jpg"); +}); diff --git a/test/configCases/entry/entry-base-uri/webpack.config.js b/test/configCases/entry/entry-base-uri/webpack.config.js new file mode 100644 index 00000000000..283ccf45eef --- /dev/null +++ b/test/configCases/entry/entry-base-uri/webpack.config.js @@ -0,0 +1,14 @@ +/** @type {import("../../../../").Configuration} */ +module.exports = { + entry: { + bundle0: { + import: "./index.js", + baseUri: "my-scheme://baseuri", + publicPath: "/" + } + }, + output: { + assetModuleFilename: "[name][ext]" + }, + target: "web" +}; diff --git a/test/configCases/entry/function-promise/test.config.js b/test/configCases/entry/function-promise/test.config.js index 8a5b96a8434..e4c1c3811ca 100644 --- a/test/configCases/entry/function-promise/test.config.js +++ b/test/configCases/entry/function-promise/test.config.js @@ -1,8 +1,5 @@ module.exports = { - findBundle: function() { - return [ - "./a.js", - "./b.js" - ] + findBundle: function () { + return ["./a.js", "./b.js"]; } }; diff --git a/test/configCases/entry/function/test.config.js b/test/configCases/entry/function/test.config.js index 8a5b96a8434..e4c1c3811ca 100644 --- a/test/configCases/entry/function/test.config.js +++ b/test/configCases/entry/function/test.config.js @@ -1,8 +1,5 @@ module.exports = { - findBundle: function() { - return [ - "./a.js", - "./b.js" - ] + findBundle: function () { + return ["./a.js", "./b.js"]; } }; diff --git a/test/configCases/entry/issue-12562/app.js b/test/configCases/entry/issue-12562/app.js index 6d8bc6abb95..03392144212 100644 --- a/test/configCases/entry/issue-12562/app.js +++ b/test/configCases/entry/issue-12562/app.js @@ -1 +1 @@ -import("./test.js"); +it("should load", () => import("./test.js")); diff --git a/test/configCases/entry/issue-13637/index-system.js b/test/configCases/entry/issue-13637/index-system.js new file mode 100644 index 00000000000..ac93b355f7c --- /dev/null +++ b/test/configCases/entry/issue-13637/index-system.js @@ -0,0 +1,8 @@ +// This test verifies that the System.register context is made available to webpack bundles + +it("should be able to use the System.register context in entries where library.type is system", function() { + expect(__system_context__).toBeTruthy(); + expect(__system_context__.meta).toBeTruthy(); + expect(typeof __system_context__.import).toBe("function"); + expect(typeof __system_context__.meta.url).toBe("string"); +}); diff --git a/test/configCases/entry/issue-13637/index-umd.js b/test/configCases/entry/issue-13637/index-umd.js new file mode 100644 index 00000000000..73fb58795cc --- /dev/null +++ b/test/configCases/entry/issue-13637/index-umd.js @@ -0,0 +1,5 @@ +// This test verifies that the System.register context is not available for non-system entries + +it("should not be able to use the System.register context in entries where library.type is not system", function() { + expect(__system_context__).toBeUndefined(); +}); diff --git a/test/configCases/entry/issue-13637/test.config.js b/test/configCases/entry/issue-13637/test.config.js new file mode 100644 index 00000000000..c8a1db577c2 --- /dev/null +++ b/test/configCases/entry/issue-13637/test.config.js @@ -0,0 +1,16 @@ +const System = require("../../../helpers/fakeSystem"); + +module.exports = { + beforeExecute: () => { + System.init(); + }, + moduleScope(scope) { + scope.System = System; + }, + afterExecute: () => { + System.execute("(anonym)"); + }, + findBundle: function () { + return ["./main.system.js", "./main.umd.js"]; + } +}; diff --git a/test/configCases/entry/issue-13637/webpack.config.js b/test/configCases/entry/issue-13637/webpack.config.js new file mode 100644 index 00000000000..ba3c6618ca1 --- /dev/null +++ b/test/configCases/entry/issue-13637/webpack.config.js @@ -0,0 +1,23 @@ +/** @type {import("../../../../").Configuration} */ +module.exports = { + entry: { + "main-system": { + import: "./index-system.js", + library: { + type: "system" + }, + filename: "main.system.js" + }, + "main-umd": { + import: "./index-umd.js", + library: { + type: "umd" + }, + filename: "main.umd.js" + } + }, + node: { + __dirname: false, + __filename: false + } +}; diff --git a/test/configCases/entry/no-chunking/a.js b/test/configCases/entry/no-chunking/a.js new file mode 100644 index 00000000000..b5c7af9a9a2 --- /dev/null +++ b/test/configCases/entry/no-chunking/a.js @@ -0,0 +1,12 @@ +import fs from "fs"; + +it("should load chunks on demand", async () => { + expect((await import("./async")).default).toEqual(42); + expect((await (await import("./async")).nested()).default).toEqual(43); + expect(fs.readFileSync(__filename, "utf-8")).not.toContain( + "This is the" + " async chunk" + ); + expect(fs.readFileSync(__filename, "utf-8")).not.toContain( + "This is the" + " nested async chunk" + ); +}); diff --git a/test/configCases/entry/no-chunking/async.js b/test/configCases/entry/no-chunking/async.js new file mode 100644 index 00000000000..5bb02b6aef8 --- /dev/null +++ b/test/configCases/entry/no-chunking/async.js @@ -0,0 +1,3 @@ +// This is the async chunk +export default 42; +export const nested = () => import("./nested"); diff --git a/test/configCases/entry/no-chunking/b.js b/test/configCases/entry/no-chunking/b.js new file mode 100644 index 00000000000..963cac2f617 --- /dev/null +++ b/test/configCases/entry/no-chunking/b.js @@ -0,0 +1,12 @@ +import fs from "fs"; + +it("should include all async imports in the main chunk", async () => { + expect((await import("./async")).default).toEqual(42); + expect((await (await import("./async")).nested()).default).toEqual(43); + expect(fs.readFileSync(__filename, "utf-8")).toContain( + "This is the async chunk" + ); + expect(fs.readFileSync(__filename, "utf-8")).toContain( + "This is the nested async chunk" + ); +}); diff --git a/test/configCases/entry/no-chunking/nested.js b/test/configCases/entry/no-chunking/nested.js new file mode 100644 index 00000000000..423e55b22e2 --- /dev/null +++ b/test/configCases/entry/no-chunking/nested.js @@ -0,0 +1,2 @@ +// This is the nested async chunk +export default 43; diff --git a/test/configCases/entry/no-chunking/test.config.js b/test/configCases/entry/no-chunking/test.config.js new file mode 100644 index 00000000000..55b0b333c9f --- /dev/null +++ b/test/configCases/entry/no-chunking/test.config.js @@ -0,0 +1,5 @@ +module.exports = { + findBundle: function (i, options) { + return ["./a.js", "./b.js", "./c.js", "./runtime.js", "./d.js"]; + } +}; diff --git a/test/configCases/entry/no-chunking/webpack.config.js b/test/configCases/entry/no-chunking/webpack.config.js new file mode 100644 index 00000000000..3becbc09b6f --- /dev/null +++ b/test/configCases/entry/no-chunking/webpack.config.js @@ -0,0 +1,29 @@ +/** @type {import("../../../../").Configuration} */ +module.exports = { + entry: { + a: "./a.js", + b: { + import: "./b.js", + chunkLoading: false + }, + c: { + import: "./b.js", + asyncChunks: false + }, + d: { + import: "./b.js", + asyncChunks: false, + runtime: "runtime" + } + }, + output: { + filename: "[name].js" + }, + target: "web", + externals: { + fs: "commonjs fs" + }, + node: { + __filename: false + } +}; diff --git a/test/configCases/errors/asset-options-validation/errors.js b/test/configCases/errors/asset-options-validation/errors.js new file mode 100644 index 00000000000..cc7b138a373 --- /dev/null +++ b/test/configCases/errors/asset-options-validation/errors.js @@ -0,0 +1,6 @@ +module.exports = [ + [ + /Invalid generator object\. Asset Modules Plugin has been initialized using a generator object that does not match the API schema/, + /generator has an unknown property 'filename'/ + ] +]; diff --git a/test/configCases/errors/asset-options-validation/index.js b/test/configCases/errors/asset-options-validation/index.js new file mode 100644 index 00000000000..39765156136 --- /dev/null +++ b/test/configCases/errors/asset-options-validation/index.js @@ -0,0 +1 @@ +import url from "./text.txt"; diff --git a/test/configCases/errors/asset-options-validation/text.txt b/test/configCases/errors/asset-options-validation/text.txt new file mode 100644 index 00000000000..557db03de99 --- /dev/null +++ b/test/configCases/errors/asset-options-validation/text.txt @@ -0,0 +1 @@ +Hello World diff --git a/test/configCases/errors/asset-options-validation/webpack.config.js b/test/configCases/errors/asset-options-validation/webpack.config.js new file mode 100644 index 00000000000..6a2069d8c86 --- /dev/null +++ b/test/configCases/errors/asset-options-validation/webpack.config.js @@ -0,0 +1,14 @@ +/** @type {import("../../../../").Configuration} */ +module.exports = { + module: { + rules: [ + { + test: /\.txt$/, + type: "asset/inline", + generator: { + filename: "[name].txt" + } + } + ] + } +}; diff --git a/test/configCases/errors/entry-not-found/errors.js b/test/configCases/errors/entry-not-found/errors.js index fedff0a83c2..648b41f3f03 100644 --- a/test/configCases/errors/entry-not-found/errors.js +++ b/test/configCases/errors/entry-not-found/errors.js @@ -1,3 +1 @@ -module.exports = [ - [/^Module not found/, /.\/index\.js/] -]; +module.exports = [[/^Module not found/, /.\/index\.js/]]; diff --git a/test/configCases/errors/import-missing/errors.js b/test/configCases/errors/import-missing/errors.js index d4f7cb2e8cd..d85236a2c74 100644 --- a/test/configCases/errors/import-missing/errors.js +++ b/test/configCases/errors/import-missing/errors.js @@ -1,3 +1 @@ -module.exports = [ - [/Module not found/] -]; +module.exports = [[/Module not found/]]; diff --git a/test/configCases/errors/multi-entry-missing-module/index.js b/test/configCases/errors/multi-entry-missing-module/index.js index b879d93790f..b7603e051c5 100644 --- a/test/configCases/errors/multi-entry-missing-module/index.js +++ b/test/configCases/errors/multi-entry-missing-module/index.js @@ -1,5 +1,5 @@ it("should ignore missing modules as entries", function() { - // a.js and b.js should be evaulated correctly + // a.js and b.js should be evaluated correctly }); it("should use WebpackMissingModule when evaluating missing modules", function() { diff --git a/test/configCases/errors/multi-entry-missing-module/test.config.js b/test/configCases/errors/multi-entry-missing-module/test.config.js index 50494000b36..0bf2100df18 100644 --- a/test/configCases/errors/multi-entry-missing-module/test.config.js +++ b/test/configCases/errors/multi-entry-missing-module/test.config.js @@ -1,9 +1,5 @@ module.exports = { - findBundle: function() { - return [ - "./a.js", - "./b.js", - "./bundle0.js" - ] + findBundle: function () { + return ["./a.js", "./b.js", "./bundle0.js"]; } }; diff --git a/test/configCases/externals/async-externals/index.js b/test/configCases/externals/async-externals/index.js index 2970742f050..38edcffba58 100644 --- a/test/configCases/externals/async-externals/index.js +++ b/test/configCases/externals/async-externals/index.js @@ -2,6 +2,7 @@ import value from "promise-external"; import value2 from "module-promise-external"; import value3 from "object-promise-external"; import request from "import-external"; +import request2 from "module-import-external"; import "./module.mjs"; it("should allow async externals", () => { @@ -9,6 +10,7 @@ it("should allow async externals", () => { expect(value2).toBe(42); expect(value3).toEqual({ default: 42, named: true }); expect(request).toBe("/hello/world.js"); + expect(request2).toBe("/hello/world.js"); }); it("should allow to catch errors of async externals", () => { diff --git a/test/configCases/externals/async-externals/webpack.config.js b/test/configCases/externals/async-externals/webpack.config.js index cf882dbc8cc..68ccc42a6e2 100644 --- a/test/configCases/externals/async-externals/webpack.config.js +++ b/test/configCases/externals/async-externals/webpack.config.js @@ -1,4 +1,5 @@ module.exports = { + target: ["web", "es2020"], output: { libraryTarget: "commonjs-module", importFunctionName: "((name) => Promise.resolve({ request: name }))" @@ -12,6 +13,7 @@ module.exports = { "promise new Promise(resolve => setTimeout(() => resolve({ default: 42, named: true }), 100))", "failing-promise-external": "promise new Promise((resolve, reject) => setTimeout(() => reject(new Error('external reject')), 100))", - "import-external": ["import /hello/world.js", "request"] + "import-external": ["import /hello/world.js", "request"], + "module-import-external": ["module-import /hello/world.js", "request"] } }; diff --git a/test/configCases/externals/concatenated-module/index.js b/test/configCases/externals/concatenated-module/index.js new file mode 100644 index 00000000000..57a7fcb129c --- /dev/null +++ b/test/configCases/externals/concatenated-module/index.js @@ -0,0 +1,15 @@ +import fs1 from "fs"; +import fs2 from "module-fs"; +import fsPromises1 from "fs-promises"; +import fsPromises2 from "module-fs-promises"; +import path1 from "path"; +import path2 from "module-path"; +import url1 from "url"; +import url2 from "module-import-url"; + +it("should be possible to import multiple module externals", () => { + expect(fs2).toBe(fs1); + expect(path2).toBe(path1); + expect(fsPromises2).toBe(fsPromises1); + expect(url1).toBe(url2); +}); diff --git a/test/configCases/externals/concatenated-module/test.filter.js b/test/configCases/externals/concatenated-module/test.filter.js new file mode 100644 index 00000000000..4afe691c9d7 --- /dev/null +++ b/test/configCases/externals/concatenated-module/test.filter.js @@ -0,0 +1,2 @@ +module.exports = () => + !process.version.startsWith("v10.") && !process.version.startsWith("v12."); diff --git a/test/configCases/externals/concatenated-module/webpack.config.js b/test/configCases/externals/concatenated-module/webpack.config.js new file mode 100644 index 00000000000..302e048f3d9 --- /dev/null +++ b/test/configCases/externals/concatenated-module/webpack.config.js @@ -0,0 +1,27 @@ +/** @type {(variant: boolean) => import("../../../../").Configuration} */ +const config = o => ({ + externals: { + "module-fs": o ? "module fs" : "module fs/promises", + fs: o ? "node-commonjs fs" : "node-commonjs fs/promises", + "module-fs-promises": o ? ["module fs", "promises"] : "module fs/promises", + "fs-promises": o + ? ["node-commonjs fs", "promises"] + : "node-commonjs fs/promises", + "module-path": "module path", + path: "node-commonjs path", + "module-import-url": "module-import url", + url: "node-commonjs url" + }, + optimization: { + concatenateModules: true, + usedExports: true, + providedExports: true, + mangleExports: true + }, + target: "node14", + experiments: { + outputModule: true + } +}); + +module.exports = [config(false), config(true)]; diff --git a/test/configCases/externals/externals-in-commons-chunk/test.config.js b/test/configCases/externals/externals-in-commons-chunk/test.config.js index 51faf2424ad..345b63543bc 100644 --- a/test/configCases/externals/externals-in-commons-chunk/test.config.js +++ b/test/configCases/externals/externals-in-commons-chunk/test.config.js @@ -1,8 +1,5 @@ module.exports = { - findBundle: function(i, options) { - return [ - "./common.js", - "./main.js" - ] + findBundle: function (i, options) { + return ["./common.js", "./main.js"]; } }; diff --git a/test/configCases/externals/externals-in-commons-chunk/webpack.config.js b/test/configCases/externals/externals-in-commons-chunk/webpack.config.js index 67937d5e7bc..85305d390af 100644 --- a/test/configCases/externals/externals-in-commons-chunk/webpack.config.js +++ b/test/configCases/externals/externals-in-commons-chunk/webpack.config.js @@ -5,7 +5,7 @@ module.exports = { other: "./other" }, externals: { - fs: "commonjs fs", + fs: "node-commonjs fs", external: "1+2", external2: "3+4", external3: "5+6" diff --git a/test/configCases/externals/externals-system-custom/index.js b/test/configCases/externals/externals-system-custom/index.js new file mode 100644 index 00000000000..f9d4aa09a1c --- /dev/null +++ b/test/configCases/externals/externals-system-custom/index.js @@ -0,0 +1,7 @@ +// This test verifies that the System.register context is made available to webpack bundles + +it("should correctly handle externals of different type", function() { + expect(require("rootExt")).toEqual("works"); + expect(require("varExt")).toEqual("works"); + expect(require("windowExt")).toEqual("works"); +}); diff --git a/test/configCases/externals/externals-system-custom/test.config.js b/test/configCases/externals/externals-system-custom/test.config.js new file mode 100644 index 00000000000..bbe84a3313d --- /dev/null +++ b/test/configCases/externals/externals-system-custom/test.config.js @@ -0,0 +1,17 @@ +const System = require("../../../helpers/fakeSystem"); + +module.exports = { + target: "web", + beforeExecute: () => { + System.init(); + }, + moduleScope(scope) { + scope.window.windowExt = "works"; + scope.rootExt = "works"; + scope.varExt = "works"; + scope.System = System; + }, + afterExecute: () => { + System.execute("(anonym)"); + } +}; diff --git a/test/configCases/externals/externals-system-custom/webpack.config.js b/test/configCases/externals/externals-system-custom/webpack.config.js new file mode 100644 index 00000000000..16c4b3f9dad --- /dev/null +++ b/test/configCases/externals/externals-system-custom/webpack.config.js @@ -0,0 +1,16 @@ +/** @type {import("../../../../types").Configuration} */ +module.exports = { + output: { + libraryTarget: "system" + }, + target: "web", + node: { + __dirname: false, + __filename: false + }, + externals: { + rootExt: "root rootExt", + varExt: "var varExt", + windowExt: "window windowExt" + } +}; diff --git a/test/configCases/externals/externals-system/index.js b/test/configCases/externals/externals-system/index.js index b9d86894675..cddcb2700e8 100644 --- a/test/configCases/externals/externals-system/index.js +++ b/test/configCases/externals/externals-system/index.js @@ -5,7 +5,7 @@ import "external4"; * Also that when System provides the external variables to webpack that the variables get plumbed * through correctly and are usable by the webpack bundle. */ -it("should get an external from System", function() { +it("should get an external from System", function () { const external1 = require("external1"); expect(external1.default).toBe("the external1 value"); @@ -14,4 +14,8 @@ it("should get an external from System", function() { expect(external3Default).toBe("the external3 default export"); expect(namedThing).toBe("the external3 named export"); + + const external5 = require("./reexport-external.js"); + expect(external5.default).toBe("the external5 default export"); + expect(external5.namedThing).toBe("the external5 named export"); }); diff --git a/test/configCases/externals/externals-system/reexport-external.js b/test/configCases/externals/externals-system/reexport-external.js new file mode 100644 index 00000000000..07c36966c58 --- /dev/null +++ b/test/configCases/externals/externals-system/reexport-external.js @@ -0,0 +1,2 @@ +export * from "external5"; +export { default } from "external5"; diff --git a/test/configCases/externals/externals-system/test.config.js b/test/configCases/externals/externals-system/test.config.js index cb39b895bc8..5520b1daefe 100644 --- a/test/configCases/externals/externals-system/test.config.js +++ b/test/configCases/externals/externals-system/test.config.js @@ -16,6 +16,10 @@ module.exports = { external4: { default: "the external4 default export", namedThing: "the external4 named export" + }, + external5: { + default: "the external5 default export", + namedThing: "the external5 named export" } }); }, diff --git a/test/configCases/externals/externals-system/webpack.config.js b/test/configCases/externals/externals-system/webpack.config.js index 283a0ba4945..7d3ab88f06e 100644 --- a/test/configCases/externals/externals-system/webpack.config.js +++ b/test/configCases/externals/externals-system/webpack.config.js @@ -7,6 +7,7 @@ module.exports = { external1: "external1", external2: "external2", external3: "external3", - external4: "external4" + external4: "external4", + external5: "external5" } }; diff --git a/test/configCases/externals/global/index.js b/test/configCases/externals/global/index.js index 821f2376eb2..b8a5d8b0009 100644 --- a/test/configCases/externals/global/index.js +++ b/test/configCases/externals/global/index.js @@ -5,7 +5,7 @@ afterEach(done => { it("should move externals in chunks into entry chunk", function() { global.EXTERNAL_TEST_GLOBAL = 42; - // eslint-disable-next-line node/no-missing-require + // eslint-disable-next-line n/no-missing-require const result = require("external"); expect(result).toBe(42); }); diff --git a/test/configCases/externals/import-assertion/dynamic-package-str.json b/test/configCases/externals/import-assertion/dynamic-package-str.json new file mode 100644 index 00000000000..96c392e16d3 --- /dev/null +++ b/test/configCases/externals/import-assertion/dynamic-package-str.json @@ -0,0 +1,3 @@ +{ + "foo": "dynamic-str" +} diff --git a/test/configCases/externals/import-assertion/dynamic-package.json b/test/configCases/externals/import-assertion/dynamic-package.json new file mode 100644 index 00000000000..9c17f1e2263 --- /dev/null +++ b/test/configCases/externals/import-assertion/dynamic-package.json @@ -0,0 +1,3 @@ +{ + "foo": "dynamic" +} diff --git a/test/configCases/externals/import-assertion/eager.json b/test/configCases/externals/import-assertion/eager.json new file mode 100644 index 00000000000..c5c5865c41c --- /dev/null +++ b/test/configCases/externals/import-assertion/eager.json @@ -0,0 +1,3 @@ +{ + "foo": "eager" +} diff --git a/test/configCases/externals/import-assertion/index.js b/test/configCases/externals/import-assertion/index.js new file mode 100644 index 00000000000..623fb7a96f2 --- /dev/null +++ b/test/configCases/externals/import-assertion/index.js @@ -0,0 +1,55 @@ +import * as staticPkg from "./static-package.json" assert { type: "json" }; +import * as staticPkgStr from "./static-package-str.json" assert { "type": "json" }; +import * as staticPkgModuleImport from "./static-package-module-import.json" assert { type: "json" }; + +it("should allow async externals", async () => { + expect(staticPkg.default.foo).toBe("static"); + expect(staticPkgStr.default.foo).toBe("static-str"); + expect(staticPkgModuleImport.default.foo).toBe("static"); + + const dynamicPkg = await import("./dynamic-package.json", { + assert: { type: "json" } + }) + + expect(dynamicPkg.default.foo).toBe("dynamic"); + + const dynamicPkgStr = await import("./dynamic-package-str.json", { + "assert": { "type": "json" } + }) + + expect(dynamicPkgStr.default.foo).toBe("dynamic-str"); + + const eagerPkg = await import(/* webpackMode: "eager" */ "./eager.json", { + assert: { type: "json" } + }); + + expect(eagerPkg.default.foo).toBe("eager"); + + await import("./weak.json", { + assert: { type: "json" } + }); + const weakPkg = await import(/* webpackMode: "weak" */ "./weak.json", { + assert: { type: "json" } + }); + + expect(weakPkg.default.foo).toBe("weak"); + + const pkg = "pkg.json"; + const nested = await import(`./nested/${pkg}`, { + assert: { type: "json" } + }); + + expect(nested.default.foo).toBe("context-dependency"); + + const reExportPkg = await import("./re-export.js"); + + expect(reExportPkg.foo).toBe("re-export"); + + const dynamicPkgModuleImport = await import("./dynamic-package-module-import.json", { + assert: { type: "json" } + }) + + expect(dynamicPkgModuleImport.default.foo).toBe("dynamic"); +}); + +export * from "./re-export-directly.json" assert { type: "json" } diff --git a/test/configCases/externals/import-assertion/nested/pkg.json b/test/configCases/externals/import-assertion/nested/pkg.json new file mode 100644 index 00000000000..592f678a321 --- /dev/null +++ b/test/configCases/externals/import-assertion/nested/pkg.json @@ -0,0 +1,3 @@ +{ + "foo": "context-dependency" +} diff --git a/test/configCases/externals/import-assertion/re-export-directly.json b/test/configCases/externals/import-assertion/re-export-directly.json new file mode 100644 index 00000000000..726743c2781 --- /dev/null +++ b/test/configCases/externals/import-assertion/re-export-directly.json @@ -0,0 +1,3 @@ +{ + "foo": "re-export" +} diff --git a/test/configCases/externals/import-assertion/re-export.js b/test/configCases/externals/import-assertion/re-export.js new file mode 100644 index 00000000000..1983630d4d4 --- /dev/null +++ b/test/configCases/externals/import-assertion/re-export.js @@ -0,0 +1 @@ +export * from "./re-export.json" assert { type: "json" }; diff --git a/test/configCases/externals/import-assertion/re-export.json b/test/configCases/externals/import-assertion/re-export.json new file mode 100644 index 00000000000..726743c2781 --- /dev/null +++ b/test/configCases/externals/import-assertion/re-export.json @@ -0,0 +1,3 @@ +{ + "foo": "re-export" +} diff --git a/test/configCases/externals/import-assertion/static-package-str.json b/test/configCases/externals/import-assertion/static-package-str.json new file mode 100644 index 00000000000..2fdfedc73c1 --- /dev/null +++ b/test/configCases/externals/import-assertion/static-package-str.json @@ -0,0 +1,3 @@ +{ + "foo": "static-str" +} diff --git a/test/configCases/externals/import-assertion/static-package.json b/test/configCases/externals/import-assertion/static-package.json new file mode 100644 index 00000000000..5a8609f8f77 --- /dev/null +++ b/test/configCases/externals/import-assertion/static-package.json @@ -0,0 +1,3 @@ +{ + "foo": "static" +} diff --git a/test/configCases/externals/import-assertion/test.filter.js b/test/configCases/externals/import-assertion/test.filter.js new file mode 100644 index 00000000000..50efa4454ac --- /dev/null +++ b/test/configCases/externals/import-assertion/test.filter.js @@ -0,0 +1 @@ +module.exports = () => /^v(1[6-9]|21)/.test(process.version); diff --git a/test/configCases/externals/import-assertion/weak.json b/test/configCases/externals/import-assertion/weak.json new file mode 100644 index 00000000000..a2bf7635487 --- /dev/null +++ b/test/configCases/externals/import-assertion/weak.json @@ -0,0 +1,3 @@ +{ + "foo": "weak" +} diff --git a/test/configCases/externals/import-assertion/webpack.config.js b/test/configCases/externals/import-assertion/webpack.config.js new file mode 100644 index 00000000000..6514b428c16 --- /dev/null +++ b/test/configCases/externals/import-assertion/webpack.config.js @@ -0,0 +1,69 @@ +const path = require("path"); +const fs = require("fs"); +const { + Compilation, + sources: { RawSource } +} = require("../../../../"); + +/** @type {import("../../../../").Configuration} */ +module.exports = { + output: { + library: { + type: "module" + } + }, + target: ["web", "es2020"], + experiments: { + outputModule: true + }, + plugins: [ + { + apply(compiler) { + compiler.hooks.compilation.tap("html-plugin", compilation => { + compilation.hooks.processAssets.tap( + { + name: "copy-plugin", + stage: Compilation.PROCESS_ASSETS_STAGE_ADDITIONAL + }, + () => { + for (const filename of [ + "static-package.json", + "static-package-str.json", + "dynamic-package.json", + "dynamic-package-str.json", + "eager.json", + "weak.json", + "./nested/pkg.json", + "re-export.json", + "re-export-directly.json" + ]) { + const resolvedFilename = path.resolve(__dirname, filename); + const content = fs.readFileSync(resolvedFilename); + compilation.emitAsset( + filename.replace(/\.\/nested\//, ""), + new RawSource(content) + ); + } + } + ); + }); + } + } + ], + externals: { + "./static-package.json": "module ./static-package.json", + "./static-package-str.json": "module ./static-package-str.json", + "./dynamic-package.json": "import ./dynamic-package.json", + "./dynamic-package-str.json": "import ./dynamic-package-str.json", + "./eager.json": "import ./eager.json", + "./weak.json": "import ./weak.json", + "./pkg.json": "import ./pkg.json", + "./pkg": "import ./pkg", + "./re-export.json": "module ./re-export.json", + "./re-export-directly.json": "module ./re-export-directly.json", + "./static-package-module-import.json": + "module-import ./static-package.json", + "./dynamic-package-module-import.json": + "module-import ./dynamic-package.json" + } +}; diff --git a/test/configCases/externals/import-attributes/dynamic-package-str.json b/test/configCases/externals/import-attributes/dynamic-package-str.json new file mode 100644 index 00000000000..96c392e16d3 --- /dev/null +++ b/test/configCases/externals/import-attributes/dynamic-package-str.json @@ -0,0 +1,3 @@ +{ + "foo": "dynamic-str" +} diff --git a/test/configCases/externals/import-attributes/dynamic-package.json b/test/configCases/externals/import-attributes/dynamic-package.json new file mode 100644 index 00000000000..9c17f1e2263 --- /dev/null +++ b/test/configCases/externals/import-attributes/dynamic-package.json @@ -0,0 +1,3 @@ +{ + "foo": "dynamic" +} diff --git a/test/configCases/externals/import-attributes/eager.json b/test/configCases/externals/import-attributes/eager.json new file mode 100644 index 00000000000..c5c5865c41c --- /dev/null +++ b/test/configCases/externals/import-attributes/eager.json @@ -0,0 +1,3 @@ +{ + "foo": "eager" +} diff --git a/test/configCases/externals/import-attributes/index.js b/test/configCases/externals/import-attributes/index.js new file mode 100644 index 00000000000..6b83a8b2a52 --- /dev/null +++ b/test/configCases/externals/import-attributes/index.js @@ -0,0 +1,55 @@ +import * as staticPkg from "./static-package.json" with { type: "json" }; +import * as staticPkgStr from "./static-package-str.json" with { "type": "json" }; +import * as staticPkgModuleImport from "./static-package-module-import.json" with { "type": "json" }; + +it("should allow async externals", async () => { + expect(staticPkg.default.foo).toBe("static"); + expect(staticPkgStr.default.foo).toBe("static-str"); + expect(staticPkgModuleImport.default.foo).toBe("static"); + + const dynamicPkg = await import("./dynamic-package.json", { + with: { type: "json" } + }) + + expect(dynamicPkg.default.foo).toBe("dynamic"); + + const dynamicPkgStr = await import("./dynamic-package-str.json", { + "with": { "type": "json" } + }) + + expect(dynamicPkgStr.default.foo).toBe("dynamic-str"); + + const eagerPkg = await import(/* webpackMode: "eager" */ "./eager.json", { + with: { type: "json" } + }); + + expect(eagerPkg.default.foo).toBe("eager"); + + await import("./weak.json", { + with: { type: "json" } + }); + const weakPkg = await import(/* webpackMode: "weak" */ "./weak.json", { + with: { type: "json" } + }); + + expect(weakPkg.default.foo).toBe("weak"); + + const pkg = "pkg.json"; + const nested = await import(`./nested/${pkg}`, { + with: { type: "json" } + }); + + expect(nested.default.foo).toBe("context-dependency"); + + const reExportPkg = await import("./re-export.js"); + + expect(reExportPkg.foo).toBe("re-export"); + + const dynamicPkgModuleImport = await import("./dynamic-package-module-import.json", { + with: { type: "json" } + }) + + expect(dynamicPkgModuleImport.default.foo).toBe("dynamic"); +}); + +export * from "./re-export-directly.json" with { type: "json" } diff --git a/test/configCases/externals/import-attributes/nested/pkg.json b/test/configCases/externals/import-attributes/nested/pkg.json new file mode 100644 index 00000000000..592f678a321 --- /dev/null +++ b/test/configCases/externals/import-attributes/nested/pkg.json @@ -0,0 +1,3 @@ +{ + "foo": "context-dependency" +} diff --git a/test/configCases/externals/import-attributes/re-export-directly.json b/test/configCases/externals/import-attributes/re-export-directly.json new file mode 100644 index 00000000000..726743c2781 --- /dev/null +++ b/test/configCases/externals/import-attributes/re-export-directly.json @@ -0,0 +1,3 @@ +{ + "foo": "re-export" +} diff --git a/test/configCases/externals/import-attributes/re-export.js b/test/configCases/externals/import-attributes/re-export.js new file mode 100644 index 00000000000..4d59479a185 --- /dev/null +++ b/test/configCases/externals/import-attributes/re-export.js @@ -0,0 +1 @@ +export * from "./re-export.json" with { type: "json" }; diff --git a/test/configCases/externals/import-attributes/re-export.json b/test/configCases/externals/import-attributes/re-export.json new file mode 100644 index 00000000000..726743c2781 --- /dev/null +++ b/test/configCases/externals/import-attributes/re-export.json @@ -0,0 +1,3 @@ +{ + "foo": "re-export" +} diff --git a/test/configCases/externals/import-attributes/static-package-str.json b/test/configCases/externals/import-attributes/static-package-str.json new file mode 100644 index 00000000000..2fdfedc73c1 --- /dev/null +++ b/test/configCases/externals/import-attributes/static-package-str.json @@ -0,0 +1,3 @@ +{ + "foo": "static-str" +} diff --git a/test/configCases/externals/import-attributes/static-package.json b/test/configCases/externals/import-attributes/static-package.json new file mode 100644 index 00000000000..5a8609f8f77 --- /dev/null +++ b/test/configCases/externals/import-attributes/static-package.json @@ -0,0 +1,3 @@ +{ + "foo": "static" +} diff --git a/test/configCases/externals/import-attributes/test.filter.js b/test/configCases/externals/import-attributes/test.filter.js new file mode 100644 index 00000000000..2ce4d1c330e --- /dev/null +++ b/test/configCases/externals/import-attributes/test.filter.js @@ -0,0 +1 @@ +module.exports = () => /^v(2[2-9])/.test(process.version); diff --git a/test/configCases/externals/import-attributes/weak.json b/test/configCases/externals/import-attributes/weak.json new file mode 100644 index 00000000000..a2bf7635487 --- /dev/null +++ b/test/configCases/externals/import-attributes/weak.json @@ -0,0 +1,3 @@ +{ + "foo": "weak" +} diff --git a/test/configCases/externals/import-attributes/webpack.config.js b/test/configCases/externals/import-attributes/webpack.config.js new file mode 100644 index 00000000000..6514b428c16 --- /dev/null +++ b/test/configCases/externals/import-attributes/webpack.config.js @@ -0,0 +1,69 @@ +const path = require("path"); +const fs = require("fs"); +const { + Compilation, + sources: { RawSource } +} = require("../../../../"); + +/** @type {import("../../../../").Configuration} */ +module.exports = { + output: { + library: { + type: "module" + } + }, + target: ["web", "es2020"], + experiments: { + outputModule: true + }, + plugins: [ + { + apply(compiler) { + compiler.hooks.compilation.tap("html-plugin", compilation => { + compilation.hooks.processAssets.tap( + { + name: "copy-plugin", + stage: Compilation.PROCESS_ASSETS_STAGE_ADDITIONAL + }, + () => { + for (const filename of [ + "static-package.json", + "static-package-str.json", + "dynamic-package.json", + "dynamic-package-str.json", + "eager.json", + "weak.json", + "./nested/pkg.json", + "re-export.json", + "re-export-directly.json" + ]) { + const resolvedFilename = path.resolve(__dirname, filename); + const content = fs.readFileSync(resolvedFilename); + compilation.emitAsset( + filename.replace(/\.\/nested\//, ""), + new RawSource(content) + ); + } + } + ); + }); + } + } + ], + externals: { + "./static-package.json": "module ./static-package.json", + "./static-package-str.json": "module ./static-package-str.json", + "./dynamic-package.json": "import ./dynamic-package.json", + "./dynamic-package-str.json": "import ./dynamic-package-str.json", + "./eager.json": "import ./eager.json", + "./weak.json": "import ./weak.json", + "./pkg.json": "import ./pkg.json", + "./pkg": "import ./pkg", + "./re-export.json": "module ./re-export.json", + "./re-export-directly.json": "module ./re-export-directly.json", + "./static-package-module-import.json": + "module-import ./static-package.json", + "./dynamic-package-module-import.json": + "module-import ./dynamic-package.json" + } +}; diff --git a/test/configCases/externals/module-import/a.js b/test/configCases/externals/module-import/a.js new file mode 100644 index 00000000000..97b356b1b21 --- /dev/null +++ b/test/configCases/externals/module-import/a.js @@ -0,0 +1,6 @@ +import external0 from "external0"; // module +const external1 = require("external1"); // module +const external2 = require("external2"); // node-commonjs +const external3 = import("external3"); // import + +console.log(external0, external1, external2, external3); diff --git a/test/configCases/externals/module-import/index.js b/test/configCases/externals/module-import/index.js new file mode 100644 index 00000000000..4036fafe9d5 --- /dev/null +++ b/test/configCases/externals/module-import/index.js @@ -0,0 +1,10 @@ +const fs = require("fs"); +const path = require("path"); + +it("module-import should correctly get fallback type", function() { + const content = fs.readFileSync(path.resolve(__dirname, "a.js"), "utf-8"); + expect(content).toContain(`import * as __WEBPACK_EXTERNAL_MODULE_external0__ from "external0";`); // module + expect(content).toContain(`import * as __WEBPACK_EXTERNAL_MODULE_external1__ from "external1";`); // module + expect(content).toContain(`module.exports = __WEBPACK_EXTERNAL_createRequire(import.meta.url)("external2");`); // node-commonjs + expect(content).toContain(`module.exports = import("external3");`); // import +}); diff --git a/test/configCases/externals/module-import/test.config.js b/test/configCases/externals/module-import/test.config.js new file mode 100644 index 00000000000..93fd44fb16b --- /dev/null +++ b/test/configCases/externals/module-import/test.config.js @@ -0,0 +1,3 @@ +module.exports = { + findBundle: (i, options) => ["main.js"] +}; diff --git a/test/configCases/externals/module-import/webpack.config.js b/test/configCases/externals/module-import/webpack.config.js new file mode 100644 index 00000000000..3758c82bf74 --- /dev/null +++ b/test/configCases/externals/module-import/webpack.config.js @@ -0,0 +1,41 @@ +/** @type {import("../../../../types").Configuration} */ +module.exports = { + target: ["web", "es2020"], + node: { + __dirname: false, + __filename: false + }, + output: { + module: true, + filename: "[name].js" + }, + entry: { + a: "./a", + main: "./index" + }, + optimization: { + concatenateModules: true + }, + experiments: { + outputModule: true + }, + externalsType: "module-import", + externals: [ + function ( + { context, request, contextInfo, getResolve, dependencyType }, + callback + ) { + if (request === "external2") { + return callback(null, "node-commonjs external2"); + } + callback(); + }, + { + external0: "external0", + external1: "external1", + external3: "external3", + fs: "commonjs fs", + path: "commonjs path" + } + ] +}; diff --git a/test/configCases/externals/non-amd-externals-amd/index.js b/test/configCases/externals/non-amd-externals-amd/index.js new file mode 100644 index 00000000000..dda9ae39696 --- /dev/null +++ b/test/configCases/externals/non-amd-externals-amd/index.js @@ -0,0 +1,33 @@ +var fs = require("fs"); +var path = require("path"); + +var dependencyArrayRegex = /define\((\[[^\]]*\]), (function)?\(/; +var source = fs.readFileSync(path.join(__dirname, "bundle0.js"), "utf-8"); +var [, deps] = dependencyArrayRegex.exec(source); + +it("should correctly import a AMD external", function() { + var external = require("external0"); + expect(external).toBe("module 0"); +}); + +it("should contain the AMD external in the dependency array", function() { + expect(deps).toContain("\"external0\""); +}); + +it("should correctly import a non-AMD external", function() { + var external = require("external1"); + expect(external).toBe("abc"); +}); + +it("should not contain the non-AMD external in the dependency array", function() { + expect(deps).not.toContain("\"external1\""); +}); + +it("should correctly import a asset external", function() { + var asset = new URL("#hash", import.meta.url); + expect(asset.href).toBe(__webpack_base_uri__ + "#hash"); +}); + +it("should not contain asset external in the dependency array", function() { + expect(deps).not.toContain("\"#hash\""); +}); diff --git a/test/configCases/externals/non-amd-externals-amd/test.config.js b/test/configCases/externals/non-amd-externals-amd/test.config.js new file mode 100644 index 00000000000..680a119a5a8 --- /dev/null +++ b/test/configCases/externals/non-amd-externals-amd/test.config.js @@ -0,0 +1,5 @@ +module.exports = { + modules: { + external0: "module 0" + } +}; diff --git a/test/configCases/externals/non-amd-externals-amd/webpack.config.js b/test/configCases/externals/non-amd-externals-amd/webpack.config.js new file mode 100644 index 00000000000..119fba2ec7d --- /dev/null +++ b/test/configCases/externals/non-amd-externals-amd/webpack.config.js @@ -0,0 +1,26 @@ +const webpack = require("../../../../"); +/** @type {import("../../../../").Configuration} */ +module.exports = { + output: { + libraryTarget: "amd" + }, + externals: { + external0: "external0", + external1: "var 'abc'" + }, + node: { + __dirname: false, + __filename: false + }, + target: "web", + externalsPresets: { + node: true + }, + plugins: [ + new webpack.BannerPlugin({ + raw: true, + banner: + "function define(deps, fn) { fn(...deps.map(dep => require(dep))); }\n" + }) + ] +}; diff --git a/test/configCases/externals/this/index.js b/test/configCases/externals/this/index.js index ba8c1a9f804..f121aac4629 100644 --- a/test/configCases/externals/this/index.js +++ b/test/configCases/externals/this/index.js @@ -5,7 +5,7 @@ afterEach(done => { it("should import an external value assigned to global this", function() { (function() { this.EXTERNAL_TEST_GLOBAL = 42; })(); - // eslint-disable-next-line node/no-missing-require + // eslint-disable-next-line n/no-missing-require const result = require("external"); expect(result).toBe(42); }); diff --git a/test/configCases/filename-template/filename-function/webpack.config.js b/test/configCases/filename-template/filename-function/webpack.config.js index 5fb96249814..1cf3161eef3 100644 --- a/test/configCases/filename-template/filename-function/webpack.config.js +++ b/test/configCases/filename-template/filename-function/webpack.config.js @@ -5,17 +5,12 @@ module.exports = { a: "./a", b: { import: "./b", - filename: data => { - return data.chunk.name + data.chunk.name + data.chunk.name + ".js"; - } + filename: data => + `${data.chunk.name + data.chunk.name + data.chunk.name}.js` } }, output: { - filename: data => { - return data.chunk.name + data.chunk.name + ".js"; - }, - chunkFilename: data => { - return data.chunk.name + data.chunk.name + ".js"; - } + filename: data => `${data.chunk.name + data.chunk.name}.js`, + chunkFilename: data => `${data.chunk.name + data.chunk.name}.js` } }; diff --git a/test/configCases/filename-template/module-filename-template/webpack.config.js b/test/configCases/filename-template/module-filename-template/webpack.config.js index b42c6bc339a..476905d46e2 100644 --- a/test/configCases/filename-template/module-filename-template/webpack.config.js +++ b/test/configCases/filename-template/module-filename-template/webpack.config.js @@ -3,7 +3,7 @@ module.exports = { mode: "development", output: { devtoolModuleFilenameTemplate: function (info) { - return "dummy:///" + info.resourcePath; + return `dummy:///${info.resourcePath}`; } }, node: { diff --git a/test/configCases/finish-modules/simple/webpack.config.js b/test/configCases/finish-modules/simple/webpack.config.js index f1116f3141d..2d9b3ad2b3b 100644 --- a/test/configCases/finish-modules/simple/webpack.config.js +++ b/test/configCases/finish-modules/simple/webpack.config.js @@ -1,7 +1,7 @@ /** * @this {import("../../../../").Compiler} the compiler */ -var testPlugin = function () { +function testPlugin() { this.hooks.compilation.tap("TestPlugin", compilation => { compilation.hooks.finishModules.tapAsync( "TestPlugin", @@ -10,7 +10,7 @@ var testPlugin = function () { } ); }); -}; +} /** @type {import("../../../../").Configuration} */ module.exports = { diff --git a/test/configCases/graph/conditional-reexport/a.js b/test/configCases/graph/conditional-reexport/a.js new file mode 100644 index 00000000000..1733779a359 --- /dev/null +++ b/test/configCases/graph/conditional-reexport/a.js @@ -0,0 +1,5 @@ +import { utilA } from "./lib" + +it("should not emit error when running a.js (runtime a)", () => { + expect(utilA()).toBe("a"); +}) diff --git a/test/configCases/graph/conditional-reexport/b.js b/test/configCases/graph/conditional-reexport/b.js new file mode 100644 index 00000000000..dc027b6cedb --- /dev/null +++ b/test/configCases/graph/conditional-reexport/b.js @@ -0,0 +1,5 @@ +import { utilB } from "./lib" + +it("should not emit error when running b.js (runtime b)", () => { + expect(utilB()).toBe("[object Object] common"); +}) diff --git a/test/configCases/graph/conditional-reexport/lib/common/common.js b/test/configCases/graph/conditional-reexport/lib/common/common.js new file mode 100644 index 00000000000..074ca1b0a6a --- /dev/null +++ b/test/configCases/graph/conditional-reexport/lib/common/common.js @@ -0,0 +1 @@ +export const common = 'common' diff --git a/test/configCases/graph/conditional-reexport/lib/common/empty.js b/test/configCases/graph/conditional-reexport/lib/common/empty.js new file mode 100644 index 00000000000..e69de29bb2d diff --git a/test/configCases/graph/conditional-reexport/lib/common/index.js b/test/configCases/graph/conditional-reexport/lib/common/index.js new file mode 100644 index 00000000000..cbff10e4c2c --- /dev/null +++ b/test/configCases/graph/conditional-reexport/lib/common/index.js @@ -0,0 +1,2 @@ +export * from "./common" +export * from "./empty" \ No newline at end of file diff --git a/test/configCases/graph/conditional-reexport/lib/index.js b/test/configCases/graph/conditional-reexport/lib/index.js new file mode 100644 index 00000000000..076a9172f79 --- /dev/null +++ b/test/configCases/graph/conditional-reexport/lib/index.js @@ -0,0 +1,3 @@ +export * from "./util-a" +export * from "./common" +export * from "./util-b" diff --git a/test/configCases/graph/conditional-reexport/lib/util-a.js b/test/configCases/graph/conditional-reexport/lib/util-a.js new file mode 100644 index 00000000000..84de8612dba --- /dev/null +++ b/test/configCases/graph/conditional-reexport/lib/util-a.js @@ -0,0 +1,3 @@ +export function utilA() { + return 'a'; +} diff --git a/test/configCases/graph/conditional-reexport/lib/util-b.js b/test/configCases/graph/conditional-reexport/lib/util-b.js new file mode 100644 index 00000000000..dda8e9fcd46 --- /dev/null +++ b/test/configCases/graph/conditional-reexport/lib/util-b.js @@ -0,0 +1,5 @@ +import { common } from "./common" +var b = ({}).toString(); // side effect, this will keep lib/index.js exist in the output, bailout the optimization from SideEffectsFlagPlugin +export function utilB() { + return b + ' ' + common; +} diff --git a/test/configCases/graph/conditional-reexport/test.config.js b/test/configCases/graph/conditional-reexport/test.config.js new file mode 100644 index 00000000000..a7d5e357230 --- /dev/null +++ b/test/configCases/graph/conditional-reexport/test.config.js @@ -0,0 +1,5 @@ +module.exports = { + findBundle() { + return ["./lib.js", "./a.js", "./b.js"]; + } +}; diff --git a/test/configCases/graph/conditional-reexport/webpack.config.js b/test/configCases/graph/conditional-reexport/webpack.config.js new file mode 100644 index 00000000000..b8cd3217e35 --- /dev/null +++ b/test/configCases/graph/conditional-reexport/webpack.config.js @@ -0,0 +1,25 @@ +/** @type {import("webpack").Configuration} */ +module.exports = { + entry: { + a: "./a.js", + b: "./b.js" + }, + output: { + filename: "[name].js" + }, + target: "web", + mode: "production", + optimization: { + concatenateModules: false, + splitChunks: { + cacheGroups: { + lib: { + name: "lib", + test: /lib/, + chunks: "all", + minSize: 0 + } + } + } + } +}; diff --git a/test/configCases/hash-length/output-filename/test.config.js b/test/configCases/hash-length/output-filename/test.config.js index 78db3b94ed4..c1c6e547e26 100644 --- a/test/configCases/hash-length/output-filename/test.config.js +++ b/test/configCases/hash-length/output-filename/test.config.js @@ -1,15 +1,16 @@ var fs = require("fs"); -var findFile = function (files, regex) { - return files.find(function (file) { +const findFile = (files, regex) => + files.find(function (file) { if (regex.test(file)) { return true; } + + return false; }); -}; -var verifyFilenameLength = function (filename, expectedNameLength) { - expect(filename).toMatch(new RegExp("^.{" + expectedNameLength + "}$")); +const verifyFilenameLength = (filename, expectedNameLength) => { + expect(filename).toMatch(new RegExp(`^.{${expectedNameLength}}$`)); }; module.exports = { @@ -18,11 +19,11 @@ module.exports = { var bundleDetects = [ options.amd.expectedChunkFilenameLength && { - regex: new RegExp("^\\d+.bundle" + i, "i"), + regex: new RegExp(`^\\d+.bundle${i}`, "i"), expectedNameLength: options.amd.expectedChunkFilenameLength }, { - regex: new RegExp("^bundle" + i, "i"), + regex: new RegExp(`^bundle${i}`, "i"), expectedNameLength: options.amd.expectedFilenameLength } ].filter(Boolean); @@ -45,7 +46,7 @@ module.exports = { ); } - return "./" + filename; + return `./${filename}`; }, afterExecute: () => { delete global.webpackChunk; diff --git a/test/configCases/hash-length/output-filename/webpack.config.js b/test/configCases/hash-length/output-filename/webpack.config.js index be0211d9d43..88115f2f92c 100644 --- a/test/configCases/hash-length/output-filename/webpack.config.js +++ b/test/configCases/hash-length/output-filename/webpack.config.js @@ -223,11 +223,11 @@ module.exports = [ } ]; -module.exports.forEach(function (options) { +for (const options of module.exports) { options.plugins = options.plugins || []; options.plugins.push( new webpack.DefinePlugin({ NAME: JSON.stringify(options.name) }) ); -}); +} diff --git a/test/configCases/ignore/resource-and-context-contextmodule/test.js b/test/configCases/ignore/resource-and-context-contextmodule/test.js index 150d2d127e2..61d1a30584a 100644 --- a/test/configCases/ignore/resource-and-context-contextmodule/test.js +++ b/test/configCases/ignore/resource-and-context-contextmodule/test.js @@ -11,7 +11,7 @@ it("should ignore context modules that match resource regex and context", functi }).toThrowError(); }); -it("should not ignore context modules that dont match the resource", function() { +it("should not ignore context modules that do not match the resource", function() { const folderBContext = function(mod) { require("./folder-b/" + mod); }; @@ -21,7 +21,7 @@ it("should not ignore context modules that dont match the resource", function() }).not.toThrowError(); }); -it("should not ignore context modules that dont match the context", function() { +it("should not ignore context modules that do not match the context", function() { const folderBContext = function(mod) { require("./folder-a/" + mod); }; diff --git a/test/configCases/inner-graph/_helpers/entryLoader.js b/test/configCases/inner-graph/_helpers/entryLoader.js index 992500b06fa..7e129b81030 100644 --- a/test/configCases/inner-graph/_helpers/entryLoader.js +++ b/test/configCases/inner-graph/_helpers/entryLoader.js @@ -1,4 +1,5 @@ -module.exports = function() { +/** @type {import("../../../../").LoaderDefinition} */ +module.exports = function () { const { name, expect, usedExports } = JSON.parse(this.query.slice(1)); return [ `if (Math.random() < 0) require(${JSON.stringify( diff --git a/test/configCases/inner-graph/_helpers/testModuleLoader.js b/test/configCases/inner-graph/_helpers/testModuleLoader.js index 1742c4ad429..b6d54748dda 100644 --- a/test/configCases/inner-graph/_helpers/testModuleLoader.js +++ b/test/configCases/inner-graph/_helpers/testModuleLoader.js @@ -1,4 +1,5 @@ -module.exports = function() { +/** @type {import("../../../../").LoaderDefinition} */ +module.exports = function () { const usedExports = JSON.parse(this.query.slice(1)); return [ `import { ${usedExports diff --git a/test/configCases/inner-graph/class/module.js b/test/configCases/inner-graph/class/module.js index 4bc7fed26fe..244e9ee77e2 100644 --- a/test/configCases/inner-graph/class/module.js +++ b/test/configCases/inner-graph/class/module.js @@ -1,4 +1,13 @@ -import { deepEqual, equal } from "./assert"; +import { + deepEqual, + equal, + strictEqual, + notEqual, + maybeEqual, + definiteEqual, + getNameA, + getNameB +} from "./assert"; function fun1() { deepEqual(1, 1); @@ -27,3 +36,31 @@ export class ExportCls2 { this.name = equal; } } + +export class ExportCls3 { + static add = () => { + strictEqual(); + }; +} + +export class ExportCls4 { + static name = notEqual; +} + +export class ExportCls5a { + static name = getNameA(); +} + +export class ExportCls5b { + static [getNameB()] = "name"; +} + +export class ExportCls6 { + add = () => { + maybeEqual(); + }; +} + +export class ExportCls7 { + add = definiteEqual(); +} diff --git a/test/configCases/inner-graph/class/test.filter.js b/test/configCases/inner-graph/class/test.filter.js new file mode 100644 index 00000000000..25a2a20eb28 --- /dev/null +++ b/test/configCases/inner-graph/class/test.filter.js @@ -0,0 +1,5 @@ +var supportsClassFields = require("../../../helpers/supportsClassFields"); + +module.exports = function (config) { + return supportsClassFields(); +}; diff --git a/test/configCases/inner-graph/class/webpack.config.js b/test/configCases/inner-graph/class/webpack.config.js index 47bbef90696..31861b77999 100644 --- a/test/configCases/inner-graph/class/webpack.config.js +++ b/test/configCases/inner-graph/class/webpack.config.js @@ -1,27 +1,75 @@ const createTestCases = require("../_helpers/createTestCases"); +const base = ["getNameA", "getNameB"]; module.exports = createTestCases({ nothing: { usedExports: [], expect: { - "./assert": [] + "./assert": [...base] } }, ExportCls1: { usedExports: ["ExportCls1"], expect: { - "./assert": ["deepEqual"] + "./assert": [...base, "deepEqual"] } }, ExportCls2: { usedExports: ["ExportCls2"], expect: { - "./assert": ["equal"] + "./assert": [...base, "equal"] } }, - all: { + ExportCls3: { + usedExports: ["ExportCls3"], + expect: { + "./assert": [...base, "strictEqual"] + } + }, + ExportCls4: { + usedExports: ["ExportCls4"], + expect: { + "./assert": [...base, "notEqual"] + } + }, + ExportCls6: { + usedExports: ["ExportCls6"], + expect: { + "./assert": [...base, "maybeEqual"] + } + }, + ExportCls7: { + usedExports: ["ExportCls7"], + expect: { + "./assert": [...base, "definiteEqual"] + } + }, + ExportCls1_2: { usedExports: ["ExportCls1", "ExportCls2"], expect: { - "./assert": ["deepEqual", "equal"] + "./assert": [...base, "deepEqual", "equal"] + } + }, + all: { + usedExports: [ + "ExportCls1", + "ExportCls2", + "ExportCls3", + "ExportCls4", + "ExportCls5a", + "ExportCls5b", + "ExportCls6", + "ExportCls7" + ], + expect: { + "./assert": [ + ...base, + "deepEqual", + "equal", + "strictEqual", + "notEqual", + "maybeEqual", + "definiteEqual" + ] } } }); diff --git a/test/configCases/inner-graph/eval-bailout/module.js b/test/configCases/inner-graph/eval-bailout/module.js new file mode 100644 index 00000000000..ce9787c2da5 --- /dev/null +++ b/test/configCases/inner-graph/eval-bailout/module.js @@ -0,0 +1,15 @@ +import { a, b, c } from "./test"; + +export function x() { + a(); +} + +export function y() { + b(); + eval("x()"); +} + +export function z() { + c(); + y(); +} diff --git a/test/configCases/inner-graph/eval-bailout/webpack.config.js b/test/configCases/inner-graph/eval-bailout/webpack.config.js new file mode 100644 index 00000000000..5953593079c --- /dev/null +++ b/test/configCases/inner-graph/eval-bailout/webpack.config.js @@ -0,0 +1,27 @@ +const createTestCases = require("../_helpers/createTestCases"); +module.exports = createTestCases({ + nothing: { + usedExports: [], + expect: { + "./test": [] + } + }, + nonEval: { + usedExports: ["x"], + expect: { + "./test": ["a"] + } + }, + directEval: { + usedExports: ["y"], + expect: { + "./test": ["a", "b", "c"] + } + }, + indirectEval: { + usedExports: ["z"], + expect: { + "./test": ["a", "b", "c"] + } + } +}); diff --git a/test/configCases/inner-graph/issue-11678/module.js b/test/configCases/inner-graph/issue-11678/module.js index b726890d5cc..aef4899802b 100644 --- a/test/configCases/inner-graph/issue-11678/module.js +++ b/test/configCases/inner-graph/issue-11678/module.js @@ -89,7 +89,7 @@ const _positionSettings = { headerStatus: "" }, settings: { - [SETTINGS.CREATEABLE]: false, + [SETTINGS.CREATABLE]: false, [SETTINGS.DELETABLE]: false } }, @@ -466,7 +466,7 @@ async function _createToolbarTable(setEvent) { _staticData, privileges.PRIVILEGE.SICONNECTPOSITION ) && - _positionSettings.settings[SETTINGS.CREATEABLE] + _positionSettings.settings[SETTINGS.CREATABLE] ) { toolbar.add(_buttonConnectPosition(onConnectPosition)); } @@ -507,7 +507,7 @@ async function _createToolbarTable(setEvent) { _staticData, privileges.PRIVILEGE.COPYORDERPOS ) && - _positionSettings.settings[SETTINGS.CREATEABLE] + _positionSettings.settings[SETTINGS.CREATABLE] ) { toolbar.add( buttonCopyJobToOrderPos(onJobToOrderPos.bind(this, true)) @@ -525,7 +525,7 @@ async function _createToolbarTable(setEvent) { { const s = { canBeCreated: - _positionSettings.settings[SETTINGS.CREATEABLE] || false + _positionSettings.settings[SETTINGS.CREATABLE] || false }; if (s.canBeCreated) { if ( @@ -685,7 +685,7 @@ async function _createToolbarTable(setEvent) { _staticData, privileges.PRIVILEGE.SICONNECTPOSITION ) && - _positionSettings.settings[SETTINGS.CREATEABLE] + _positionSettings.settings[SETTINGS.CREATABLE] ) { toolbar.add(_buttonConnectPosition(onConnectPosition)); } @@ -765,7 +765,7 @@ async function _createToolbarTable(setEvent) { _staticData, privileges.PRIVILEGE.COPYORDERPOS ) && - _positionSettings.settings[SETTINGS.CREATEABLE] + _positionSettings.settings[SETTINGS.CREATABLE] ) { toolbar.add(buttonCopyJobToOrderPos(onJobToOrderPos.bind(this, true))); } @@ -806,7 +806,7 @@ async function _createToolbarTable(setEvent) { case buttons.STATE.ciPositionTableMenu: { const s = { - canBeCreated: _positionSettings.settings[SETTINGS.CREATEABLE] || false + canBeCreated: _positionSettings.settings[SETTINGS.CREATABLE] || false }; if (s.canBeCreated) { if ( @@ -843,7 +843,7 @@ async function _createToolbarTable(setEvent) { case buttons.STATE.ciPositionTableMenuMultiple: { const s = { - canBeCreated: _positionSettings.settings[SETTINGS.CREATEABLE] || false + canBeCreated: _positionSettings.settings[SETTINGS.CREATABLE] || false }; if (s.canBeCreated) { if ( @@ -1017,7 +1017,7 @@ export async function getDataAndShowTable( default: break; } - _positionSettings.settings[SETTINGS.CREATEABLE] = settingsData.canBeCreated; + _positionSettings.settings[SETTINGS.CREATABLE] = settingsData.canBeCreated; _positionSettings.settings[SETTINGS.DELETABLE] = settingsData.canBeDeleted; _positionSettings.settings[SETTINGS.MULTIPLEDELETE] = settingsData.showButtonDeleteAndMoveNCH; @@ -1438,7 +1438,7 @@ async function _createFormWidget(positionTypeId, headerPK, contentId = null) { _isNewDataset ) ); - const renderFormInConainter = contentId ? contentId : _getFormSelector(); + const renderFormInContainer = contentId ? contentId : _getFormSelector(); await form.initForm( _getModuleName(), positionTypeId, @@ -1447,7 +1447,7 @@ async function _createFormWidget(positionTypeId, headerPK, contentId = null) { _formData, _staticData, _isNewDataset, - renderFormInConainter, + renderFormInContainer, headerPK ); } @@ -2720,7 +2720,7 @@ function _showFormButtons(manualSetEvent) { if (manualSetEvent) { _formEvent = manualSetEvent; } - s.canBeCreated = _positionSettings.settings[SETTINGS.CREATEABLE]; + s.canBeCreated = _positionSettings.settings[SETTINGS.CREATABLE]; s.canBeDeleted = _positionSettings.settings[SETTINGS.DELETABLE]; if ( _formData && @@ -3003,7 +3003,7 @@ function _showParentTable(forceReload = true) { } } } -function _setParentModulSettings(moduleName) { +function _setParentModuleSettings(moduleName) { switch (moduleName) { case ModuleNameEnum.JOB: _parentModuleSettings = { @@ -3051,7 +3051,7 @@ export async function initialize( moduleName, previousTableTitle ) { - _setParentModulSettings(moduleName); + _setParentModuleSettings(moduleName); _tableContainerId = "#" + newContainerId; _formIdName = moduleName + "_" + newContainerId + "-form"; _previousTableTitle = previousTableTitle; @@ -3075,7 +3075,7 @@ export async function renderFormInDialog(contentId, data, addTask = false) { jpos_headertype: 1, jpos_subposno: 1 }; - _setParentModulSettings(ModuleNameEnum.JOB); + _setParentModuleSettings(ModuleNameEnum.JOB); _isFormInDialog = true; _isFormInDialogSelector = contentId; _isFormInDialogJobPK = pkForJobService; @@ -3089,7 +3089,7 @@ export async function renderFormInDialog(contentId, data, addTask = false) { getPKfromModule(), _getModuleType() ); - _positionSettings.settings[SETTINGS.CREATEABLE] = settings.canBeCreated; + _positionSettings.settings[SETTINGS.CREATABLE] = settings.canBeCreated; _positionSettings.settings[SETTINGS.DELETABLE] = settings.canBeDeleted; const emailOfCurrentUser = await employeeData.getEmplList(); _generalDataEmplLists = { diff --git a/test/configCases/inner-graph/issue-17565/module.js b/test/configCases/inner-graph/issue-17565/module.js new file mode 100644 index 00000000000..c98eb025b40 --- /dev/null +++ b/test/configCases/inner-graph/issue-17565/module.js @@ -0,0 +1,60 @@ +import { A, B, C1, C2, C3, Err } from "./test"; + +var arr1 = A, + cls = class extends Error {}, + cls1 = class { + constructor(t) { + if (!arr1.includes(t.version)) throw "invalid parquet version"; + } + async *[Symbol.asyncIterator]() { + yield ""; + } + }; + +var arr2 = B; +var cls2 = class extends Error {}, + cls3 = class { + constructor(t) { + if (!arr2.includes(t.version)) throw "invalid parquet version"; + } + async *[Symbol.asyncIterator]() { + yield ""; + } + }; + +var arr3 = C1; +var cls4 = class { + constructor() {} + }, + cls5 = class { + constructor(t) { + if (!arr3.includes(t.version)) throw "invalid parquet version"; + } + async *[Symbol.asyncIterator]() { + yield ""; + } + }; + +var arr4 = C2; +var cls6 = class { + foo = [1, 2]; + }, + cls7 = class { + constructor(t) { + if (!arr4.includes(t.version)) throw "invalid parquet version"; + } + async *[Symbol.asyncIterator]() { + yield ""; + } + }; + +var arr5 = C3; +var cls8 = class extends Err {}, + cls9 = class { + constructor(t) {} + async *[Symbol.asyncIterator]() { + yield ""; + } + }; + +export { cls1, cls3, cls5, cls7, cls9 } diff --git a/test/configCases/inner-graph/issue-17565/test.filter.js b/test/configCases/inner-graph/issue-17565/test.filter.js new file mode 100644 index 00000000000..25a2a20eb28 --- /dev/null +++ b/test/configCases/inner-graph/issue-17565/test.filter.js @@ -0,0 +1,5 @@ +var supportsClassFields = require("../../../helpers/supportsClassFields"); + +module.exports = function (config) { + return supportsClassFields(); +}; diff --git a/test/configCases/inner-graph/issue-17565/webpack.config.js b/test/configCases/inner-graph/issue-17565/webpack.config.js new file mode 100644 index 00000000000..8f29d9f872a --- /dev/null +++ b/test/configCases/inner-graph/issue-17565/webpack.config.js @@ -0,0 +1,16 @@ +const createTestCases = require("../_helpers/createTestCases"); + +module.exports = createTestCases({ + nothing: { + usedExports: [], + expect: { + "./test": ["A", "B", "C1", "C2"] + } + }, + all: { + usedExports: ["cls1", "cls3", "cls5", "cls7", "cls9"], + expect: { + "./test": ["A", "B", "C1", "C2"] + } + } +}); diff --git a/test/configCases/inner-graph/pr-18342/common/index.js b/test/configCases/inner-graph/pr-18342/common/index.js new file mode 100644 index 00000000000..f402294b264 --- /dev/null +++ b/test/configCases/inner-graph/pr-18342/common/index.js @@ -0,0 +1,5 @@ +import pure from './pure' + +export default () => { + pure() +} diff --git a/test/configCases/inner-graph/pr-18342/common/pure.js b/test/configCases/inner-graph/pr-18342/common/pure.js new file mode 100644 index 00000000000..d70ac6f068b --- /dev/null +++ b/test/configCases/inner-graph/pr-18342/common/pure.js @@ -0,0 +1,5 @@ +function pure() { + console.log('pureFn'); +} + +export default pure diff --git a/test/configCases/inner-graph/pr-18342/entry1/index.js b/test/configCases/inner-graph/pr-18342/entry1/index.js new file mode 100644 index 00000000000..d5fb94c7209 --- /dev/null +++ b/test/configCases/inner-graph/pr-18342/entry1/index.js @@ -0,0 +1,7 @@ +import common from "../common"; + +it("entry1 should compile and run", () => { + common() + console.log('entry1'); + expect(true).toBe(true) +}); diff --git a/test/configCases/inner-graph/pr-18342/entry2/index.js b/test/configCases/inner-graph/pr-18342/entry2/index.js new file mode 100644 index 00000000000..7e6ccae0d4c --- /dev/null +++ b/test/configCases/inner-graph/pr-18342/entry2/index.js @@ -0,0 +1,7 @@ +it("entry2 should compile and run", () => { + import(/* webpackChunkName: "chunk-reason-webpackChunkName" */'../common').then(common => { + common.default() + console.log('entry2'); + expect(true).toBe(true) + }) +}); diff --git a/test/configCases/inner-graph/pr-18342/entry3/a.js b/test/configCases/inner-graph/pr-18342/entry3/a.js new file mode 100644 index 00000000000..90bd54cd7f2 --- /dev/null +++ b/test/configCases/inner-graph/pr-18342/entry3/a.js @@ -0,0 +1 @@ +export default 'a' diff --git a/test/configCases/inner-graph/pr-18342/entry3/index.js b/test/configCases/inner-graph/pr-18342/entry3/index.js new file mode 100644 index 00000000000..1d863a1d7cb --- /dev/null +++ b/test/configCases/inner-graph/pr-18342/entry3/index.js @@ -0,0 +1,7 @@ +it("entry3 should compile and run", () => { + import(/* webpackChunkName: "chunk-reason-webpackChunkName" */'./a.js').then(a => { + console.log(a.default); + console.log('entry3'); + expect(true).toBe(true) + }) +}); diff --git a/test/configCases/inner-graph/pr-18342/test.config.js b/test/configCases/inner-graph/pr-18342/test.config.js new file mode 100644 index 00000000000..ce98c463c7f --- /dev/null +++ b/test/configCases/inner-graph/pr-18342/test.config.js @@ -0,0 +1,8 @@ +const findOutputFiles = require("../../../helpers/findOutputFiles"); + +module.exports = { + findBundle(_, options) { + const files = findOutputFiles(options, /^entry/); + return files; + } +}; diff --git a/test/configCases/inner-graph/pr-18342/webpack.config.js b/test/configCases/inner-graph/pr-18342/webpack.config.js new file mode 100644 index 00000000000..2d487f51dc2 --- /dev/null +++ b/test/configCases/inner-graph/pr-18342/webpack.config.js @@ -0,0 +1,26 @@ +module.exports = { + target: ["node"], + entry: { + entry1: ["./entry1/index.js"], + entry2: ["./entry2/index.js"], + entry3: ["./entry3/index.js"] + }, + output: { + filename: "[name].js", + chunkFilename: "[name].chunk.js" + }, + optimization: { + minimize: false, + runtimeChunk: true, + splitChunks: { + chunks: "initial", + cacheGroups: { + pureFn: { + test: /pure/, + enforce: true, + name: "chunk-reason-split-chunks" + } + } + } + } +}; diff --git a/test/configCases/issues/issue-11871-imports-order/a.js b/test/configCases/issues/issue-11871-imports-order/a.js new file mode 100644 index 00000000000..0f46328a84a --- /dev/null +++ b/test/configCases/issues/issue-11871-imports-order/a.js @@ -0,0 +1,4 @@ +export const W = "w"; +export const A = "a"; +export const a = "a"; +export const _12 = "12"; diff --git a/test/configCases/issues/issue-11871-imports-order/index.js b/test/configCases/issues/issue-11871-imports-order/index.js new file mode 100644 index 00000000000..9d47d73d9db --- /dev/null +++ b/test/configCases/issues/issue-11871-imports-order/index.js @@ -0,0 +1,5 @@ +import * as values from "./a.js"; + +it("imports should have correct order", () => { + expect(Object.keys(values)).toEqual(["A", "W", "_12", "a"]) +}); diff --git a/test/configCases/issues/issue-11871-imports-order/webpack.config.js b/test/configCases/issues/issue-11871-imports-order/webpack.config.js new file mode 100644 index 00000000000..1fc5ef0a294 --- /dev/null +++ b/test/configCases/issues/issue-11871-imports-order/webpack.config.js @@ -0,0 +1,23 @@ +"use strict"; + +/** @type {import("../../../../").Configuration[]} */ +module.exports = [ + { + mode: "development" + }, + { + mode: "production" + }, + { + mode: "production", + optimization: { + concatenateModules: false + } + }, + { + mode: "development", + optimization: { + concatenateModules: true + } + } +]; diff --git a/test/configCases/issues/issue-12924/index.js b/test/configCases/issues/issue-12924/index.js new file mode 100644 index 00000000000..9e0bf87e832 --- /dev/null +++ b/test/configCases/issues/issue-12924/index.js @@ -0,0 +1,3 @@ +it("should compile without error", function() { + return import(/* webpackChunkName: "one" */ "./one"); +}); diff --git a/test/configCases/issues/issue-12924/one.js b/test/configCases/issues/issue-12924/one.js new file mode 100644 index 00000000000..bd816eaba4c --- /dev/null +++ b/test/configCases/issues/issue-12924/one.js @@ -0,0 +1 @@ +module.exports = 1; diff --git a/test/configCases/issues/issue-12924/webpack.config.js b/test/configCases/issues/issue-12924/webpack.config.js new file mode 100644 index 00000000000..dab4dd4425a --- /dev/null +++ b/test/configCases/issues/issue-12924/webpack.config.js @@ -0,0 +1,20 @@ +"use strict"; + +/** @type {import("../../../../").Configuration[]} */ +module.exports = [ + { + output: { + globalObject: "null || new Function('return this')()" + } + }, + { + output: { + globalObject: "(new Function('return this'))()" + } + }, + { + output: { + globalObject: "1 > 2 ? null : new Function('return this')()" + } + } +]; diff --git a/test/configCases/issues/issue-12993/dynamic.js b/test/configCases/issues/issue-12993/dynamic.js new file mode 100644 index 00000000000..6c40343ed97 --- /dev/null +++ b/test/configCases/issues/issue-12993/dynamic.js @@ -0,0 +1 @@ +export default "dynamic"; diff --git a/test/configCases/issues/issue-12993/index.js b/test/configCases/issues/issue-12993/index.js new file mode 100644 index 00000000000..b490bb515af --- /dev/null +++ b/test/configCases/issues/issue-12993/index.js @@ -0,0 +1,6 @@ +export const main = "main"; + +it("library output should be accurate value", async () => { + expect(global.lib).toEqual(nsObj({ main: "main" })); + await import(/* webpackPrefetch: true */ "./dynamic.js"); +}); diff --git a/test/configCases/issues/issue-12993/test.config.js b/test/configCases/issues/issue-12993/test.config.js new file mode 100644 index 00000000000..7e3084c7bdf --- /dev/null +++ b/test/configCases/issues/issue-12993/test.config.js @@ -0,0 +1,5 @@ +module.exports = { + afterExecute() { + delete global.lib; + } +}; diff --git a/test/configCases/issues/issue-12993/webpack.config.js b/test/configCases/issues/issue-12993/webpack.config.js new file mode 100644 index 00000000000..f462f7e496f --- /dev/null +++ b/test/configCases/issues/issue-12993/webpack.config.js @@ -0,0 +1,17 @@ +module.exports = [ + { + mode: "development", + output: { + library: "lib", + libraryTarget: "global" + } + }, + { + mode: "development", + devtool: false, + output: { + library: "lib", + libraryTarget: "global" + } + } +]; diff --git a/test/configCases/issues/issue-14974/defer.js b/test/configCases/issues/issue-14974/defer.js new file mode 100644 index 00000000000..7e8bc9f7808 --- /dev/null +++ b/test/configCases/issues/issue-14974/defer.js @@ -0,0 +1,2 @@ +import log from "./tla.js" +log(); diff --git a/test/configCases/issues/issue-14974/index.js b/test/configCases/issues/issue-14974/index.js new file mode 100644 index 00000000000..fa5f87c45a0 --- /dev/null +++ b/test/configCases/issues/issue-14974/index.js @@ -0,0 +1,6 @@ +import "./tla.js" +const a = import("./defer.js") +import.meta.webpackHot.accept(["./defer.js"], () => {}) +it("should compile", async () => { + expect(await a).toBeTruthy(); +}); diff --git a/test/configCases/issues/issue-14974/test.filter.js b/test/configCases/issues/issue-14974/test.filter.js new file mode 100644 index 00000000000..c223174f266 --- /dev/null +++ b/test/configCases/issues/issue-14974/test.filter.js @@ -0,0 +1,3 @@ +module.exports = function () { + return process.version.slice(0, 4) !== "v10."; +}; diff --git a/test/configCases/issues/issue-14974/tla.js b/test/configCases/issues/issue-14974/tla.js new file mode 100644 index 00000000000..e9a204b4331 --- /dev/null +++ b/test/configCases/issues/issue-14974/tla.js @@ -0,0 +1,4 @@ +await Promise.resolve(); +export default function log() { + return 1; +} diff --git a/test/configCases/issues/issue-14974/webpack.config.js b/test/configCases/issues/issue-14974/webpack.config.js new file mode 100644 index 00000000000..24a11572636 --- /dev/null +++ b/test/configCases/issues/issue-14974/webpack.config.js @@ -0,0 +1,9 @@ +const { HotModuleReplacementPlugin } = require("../../../../"); + +/** @type {import("../../../../").Configuration} */ +module.exports = { + devtool: false, + experiments: { topLevelAwait: true }, + optimization: { usedExports: false, sideEffects: false }, + plugins: [new HotModuleReplacementPlugin()] +}; diff --git a/test/configCases/issues/issue-17459/bar.js b/test/configCases/issues/issue-17459/bar.js new file mode 100644 index 00000000000..801821e109c --- /dev/null +++ b/test/configCases/issues/issue-17459/bar.js @@ -0,0 +1 @@ +export default "bar"; diff --git a/test/configCases/issues/issue-17459/index.js b/test/configCases/issues/issue-17459/index.js new file mode 100644 index 00000000000..e570a856242 --- /dev/null +++ b/test/configCases/issues/issue-17459/index.js @@ -0,0 +1,21 @@ +import bar_string from './bar'; + +let other; + +function foo(value) { + other = value; +} + +var my_class = class { + constructor() { + this.bar = bar_string; + foo(bar_string); + } +}, my_instance = (new my_class()) + + +it("should mangle imports in class constructors", function() { + expect(bar_string).toBe("bar"); + expect(my_instance.bar).toBe(bar_string); + expect(other).toBe(bar_string); +}); diff --git a/test/configCases/issues/issue-17459/webpack.config.js b/test/configCases/issues/issue-17459/webpack.config.js new file mode 100644 index 00000000000..dffc81bba10 --- /dev/null +++ b/test/configCases/issues/issue-17459/webpack.config.js @@ -0,0 +1,4 @@ +/** @type {import("../../../../").Configuration} */ +module.exports = { + mode: "production" +}; diff --git a/test/configCases/issues/issue-7563/test.config.js b/test/configCases/issues/issue-7563/test.config.js index dee26555271..8b95a44bcd3 100644 --- a/test/configCases/issues/issue-7563/test.config.js +++ b/test/configCases/issues/issue-7563/test.config.js @@ -1,9 +1,9 @@ -var fs = require('fs'); +var fs = require("fs"); module.exports = { noTests: true, - findBundle: function(i, options) { - var regex = new RegExp("^bundle\." + options.name, "i"); + findBundle: function (i, options) { + var regex = new RegExp(`^bundle.${options.name}`, "i"); var files = fs.readdirSync(options.output.path); var bundle = files.find(function (file) { return regex.test(file); @@ -17,6 +17,6 @@ module.exports = { ); } - return "./" + bundle; + return `./${bundle}`; } }; diff --git a/test/configCases/issues/issue-7563/webpack.config.js b/test/configCases/issues/issue-7563/webpack.config.js index 3fcd6c3bc1a..a58f54f7657 100644 --- a/test/configCases/issues/issue-7563/webpack.config.js +++ b/test/configCases/issues/issue-7563/webpack.config.js @@ -10,56 +10,56 @@ module.exports = [ name: "webworker-all", target: "webworker", output: { - filename: "bundle.webworker-all." + testAllButHash + ".js" + filename: `bundle.webworker-all.${testAllButHash}.js` } }, { name: "webworker-hash", target: "webworker", output: { - filename: "bundle.webworker-hash." + testHash + ".js" + filename: `bundle.webworker-hash.${testHash}.js` } }, { name: "node-all", target: "node", output: { - filename: "bundle.node-all." + testAllButHash + ".js" + filename: `bundle.node-all.${testAllButHash}.js` } }, { name: "node", target: "node", output: { - filename: "bundle.node-hash." + testHash + ".js" + filename: `bundle.node-hash.${testHash}.js` } }, { name: "async-node-all", target: "async-node", output: { - filename: "bundle.async-node-all." + testAllButHash + ".js" + filename: `bundle.async-node-all.${testAllButHash}.js` } }, { name: "async-node-hash", target: "async-node", output: { - filename: "bundle.async-node-hash." + testHash + ".js" + filename: `bundle.async-node-hash.${testHash}.js` } }, { name: "web-all", target: "web", output: { - filename: "bundle.web-all." + testAllButHash + ".js" + filename: `bundle.web-all.${testAllButHash}.js` } }, { name: "web-hash", target: "web", output: { - filename: "bundle.web-hash." + testHash + ".js" + filename: `bundle.web-hash.${testHash}.js` } } ]; diff --git a/test/configCases/layer/context-and-css/dark.js b/test/configCases/layer/context-and-css/dark.js new file mode 100644 index 00000000000..fa2ef56f2c3 --- /dev/null +++ b/test/configCases/layer/context-and-css/dark.js @@ -0,0 +1,9 @@ +require.context('./test1', true, /\.less$/); +require('./test2/shared.less'); + +it("should contain only black", function() { + const style = getComputedStyle(document.body); + + expect(style["color-dark"]).toBe(" black"); + expect(style["background-dark"]).toBe(" black"); +}); diff --git a/test/configCases/layer/context-and-css/light.js b/test/configCases/layer/context-and-css/light.js new file mode 100644 index 00000000000..2f10430cf7d --- /dev/null +++ b/test/configCases/layer/context-and-css/light.js @@ -0,0 +1,9 @@ +require.context('./test1', true, /\.less$/); +require('./test2/shared.less'); + +it("should contain only white", function() { + const style = getComputedStyle(document.body); + + expect(style["color-light"]).toBe(" white"); + expect(style["background-light"]).toBe(" white"); +}); diff --git a/test/configCases/layer/context-and-css/test.config.js b/test/configCases/layer/context-and-css/test.config.js new file mode 100644 index 00000000000..19e44b49d42 --- /dev/null +++ b/test/configCases/layer/context-and-css/test.config.js @@ -0,0 +1,15 @@ +module.exports = { + moduleScope(scope) { + const light = scope.window.document.createElement("link"); + light.rel = "stylesheet"; + light.href = "light.css"; + scope.window.document.head.appendChild(light); + const dark = scope.window.document.createElement("link"); + dark.rel = "stylesheet"; + dark.href = "dark.css"; + scope.window.document.head.appendChild(dark); + }, + findBundle: function () { + return ["./runtime.js", "./light.js", "./dark.js"]; + } +}; diff --git a/test/configCases/layer/context-and-css/test1/shared.less b/test/configCases/layer/context-and-css/test1/shared.less new file mode 100644 index 00000000000..c1e0175c929 --- /dev/null +++ b/test/configCases/layer/context-and-css/test1/shared.less @@ -0,0 +1,3 @@ +body { + @{property-color}: @color; +} diff --git a/test/configCases/layer/context-and-css/test2/shared.less b/test/configCases/layer/context-and-css/test2/shared.less new file mode 100644 index 00000000000..4c32372804b --- /dev/null +++ b/test/configCases/layer/context-and-css/test2/shared.less @@ -0,0 +1,3 @@ +body { + @{property-background}: @color; +} diff --git a/test/configCases/layer/context-and-css/webpack.config.js b/test/configCases/layer/context-and-css/webpack.config.js new file mode 100644 index 00000000000..838b847cc99 --- /dev/null +++ b/test/configCases/layer/context-and-css/webpack.config.js @@ -0,0 +1,52 @@ +/** @type {import("../../../../").Configuration} */ +module.exports = { + target: "web", + entry: { + light: { import: "./light.js", layer: "light" }, + dark: { import: "./dark.js", layer: "dark" } + }, + experiments: { + layers: true, + css: true + }, + optimization: { + runtimeChunk: "single" + }, + output: { + filename: "[name].js" + }, + module: { + rules: [ + { + test: /\.less$/i, + type: "css/auto", + oneOf: [ + { + issuerLayer: "light", + use: [ + { + loader: "less-loader", + options: { + additionalData: + "@color: white; @property-color: color-light; @property-background: background-light;" + } + } + ] + }, + { + issuerLayer: "dark", + use: [ + { + loader: "less-loader", + options: { + additionalData: + "@color: black; @property-color: color-dark; @property-background: background-dark;" + } + } + ] + } + ] + } + ] + } +}; diff --git a/test/configCases/layer/context/dark.js b/test/configCases/layer/context/dark.js new file mode 100644 index 00000000000..f2975a25f24 --- /dev/null +++ b/test/configCases/layer/context/dark.js @@ -0,0 +1,12 @@ +require.context('./test1', true, /\.less$/); +require('./test2/shared.less'); + +it("should contain only black", function() { + const fs = require("fs"); + const path = require("path"); + + const source = fs.readFileSync(path.join(__dirname, "dark.css"), "utf-8"); + + expect(source.match(/black/g)).toHaveLength(2); + expect(source).not.toContain("white"); +}); diff --git a/test/configCases/layer/context/light.js b/test/configCases/layer/context/light.js new file mode 100644 index 00000000000..e3c9335a95b --- /dev/null +++ b/test/configCases/layer/context/light.js @@ -0,0 +1,12 @@ +require.context('./test1', true, /\.less$/); +require('./test2/shared.less'); + +it("should contain only white", function() { + const fs = require("fs"); + const path = require("path"); + + const source = fs.readFileSync(path.join(__dirname, "light.css"), "utf-8"); + + expect(source.match(/white/g)).toHaveLength(2); + expect(source).not.toContain("black"); +}); diff --git a/test/configCases/layer/context/test.config.js b/test/configCases/layer/context/test.config.js new file mode 100644 index 00000000000..5cb963d9e0f --- /dev/null +++ b/test/configCases/layer/context/test.config.js @@ -0,0 +1,5 @@ +module.exports = { + findBundle: function () { + return ["./light.js", "./dark.js"]; + } +}; diff --git a/test/configCases/layer/context/test1/shared.less b/test/configCases/layer/context/test1/shared.less new file mode 100644 index 00000000000..aeef901bc65 --- /dev/null +++ b/test/configCases/layer/context/test1/shared.less @@ -0,0 +1,3 @@ +.test1 { + color: @color; +} diff --git a/test/configCases/layer/context/test2/shared.less b/test/configCases/layer/context/test2/shared.less new file mode 100644 index 00000000000..2cbc230e5a1 --- /dev/null +++ b/test/configCases/layer/context/test2/shared.less @@ -0,0 +1,3 @@ +.test2 { + color: @color; +} diff --git a/test/configCases/layer/context/webpack.config.js b/test/configCases/layer/context/webpack.config.js new file mode 100644 index 00000000000..41ed5eb13ee --- /dev/null +++ b/test/configCases/layer/context/webpack.config.js @@ -0,0 +1,55 @@ +const MiniCssExtractPlugin = require("mini-css-extract-plugin"); + +/** @type {import("../../../../").Configuration} */ +module.exports = { + entry: { + light: { import: "./light.js", layer: "light" }, + dark: { import: "./dark.js", layer: "dark" } + }, + experiments: { + layers: true + }, + output: { + filename: "[name].js" + }, + plugins: [ + new MiniCssExtractPlugin({ + filename: "[name].css" + }) + ], + module: { + rules: [ + { + test: /\.less$/i, + oneOf: [ + { + issuerLayer: "light", + use: [ + MiniCssExtractPlugin.loader, + "css-loader", + { + loader: "less-loader", + options: { + additionalData: "@color: white;" + } + } + ] + }, + { + issuerLayer: "dark", + use: [ + MiniCssExtractPlugin.loader, + "css-loader", + { + loader: "less-loader", + options: { + additionalData: "@color: black;" + } + } + ] + } + ] + } + ] + } +}; diff --git a/test/configCases/layer/rules/dynamic-module-layer.js b/test/configCases/layer/rules/dynamic-module-layer.js new file mode 100644 index 00000000000..4c082635268 --- /dev/null +++ b/test/configCases/layer/rules/dynamic-module-layer.js @@ -0,0 +1,13 @@ +async function main(name) { + const { object: dynamicModuleObject } = await import(`./dynamic/${name}`); + return dynamicModuleObject; +} + +export const object = { + name: 'module entry', + layer: __webpack_layer__, + modules: [ + main('module1'), + main('module2'), + ] +}; \ No newline at end of file diff --git a/test/configCases/layer/rules/dynamic/module1.js b/test/configCases/layer/rules/dynamic/module1.js new file mode 100644 index 00000000000..2ee153c0c42 --- /dev/null +++ b/test/configCases/layer/rules/dynamic/module1.js @@ -0,0 +1,4 @@ +export const object = { + name: 'module1', + layer: __webpack_layer__, +}; \ No newline at end of file diff --git a/test/configCases/layer/rules/dynamic/module2.js b/test/configCases/layer/rules/dynamic/module2.js new file mode 100644 index 00000000000..1a9d4536add --- /dev/null +++ b/test/configCases/layer/rules/dynamic/module2.js @@ -0,0 +1,4 @@ +export const object = { + name: 'module2', + layer: __webpack_layer__ +}; \ No newline at end of file diff --git a/test/configCases/layer/rules/index.js b/test/configCases/layer/rules/index.js index 27fc81fe4b0..f41c8b5ab27 100644 --- a/test/configCases/layer/rules/index.js +++ b/test/configCases/layer/rules/index.js @@ -14,6 +14,8 @@ import { direct as otherLayerDirect } from "./module-other-layer-change"; import { reexported as otherLayerReexported } from "./module-other-layer-change"; import { __loaderValue as otherLayerValue } from "./module-other-layer-change"; +import { object as dynamicModules } from "./dynamic-module-layer" + it("should allow to duplicate modules with layers", () => { expect(direct).toBe(reexported); expect(layerDirect).toBe(layerReexported); @@ -36,3 +38,10 @@ it("apply externals based on layer", () => { expect(layerExternal1).toBe(43); expect(layerExternal2).toBe(43); }); + +it("apply layer for dynamic imports with dynamic resources", async () => { + const mods = await Promise.all(dynamicModules.modules) + expect(dynamicModules.layer).toBe('dynamic-layer') + expect(mods[0]).toMatchObject({ layer: 'dynamic-layer', name: 'module1' }) + expect(mods[1]).toMatchObject({ layer: 'dynamic-layer', name: 'module2' }) +}) diff --git a/test/configCases/layer/rules/loader.js b/test/configCases/layer/rules/loader.js index 34dbc1b1703..7e5acde631c 100644 --- a/test/configCases/layer/rules/loader.js +++ b/test/configCases/layer/rules/loader.js @@ -1,3 +1,4 @@ +/** @type {import("../../../../").LoaderDefinition<{ value: any }>} */ module.exports = function (source) { const options = this.getOptions(); return `${source} diff --git a/test/configCases/layer/rules/webpack.config.js b/test/configCases/layer/rules/webpack.config.js index 2390c9c0d82..a1dc2986b58 100644 --- a/test/configCases/layer/rules/webpack.config.js +++ b/test/configCases/layer/rules/webpack.config.js @@ -42,6 +42,10 @@ module.exports = { options: { value: "entry" } + }, + { + test: /dynamic-module-layer/, + layer: "dynamic-layer" } ] }, diff --git a/test/configCases/library/0-create-library/test.config.js b/test/configCases/library/0-create-library/test.config.js index 08ea6c319c8..04581a81040 100644 --- a/test/configCases/library/0-create-library/test.config.js +++ b/test/configCases/library/0-create-library/test.config.js @@ -1 +1 @@ -exports.noTests = true; +module.exports.noTests = true; diff --git a/test/configCases/library/0-create-library/webpack.config.js b/test/configCases/library/0-create-library/webpack.config.js index c9f302d7b4b..3136c6b7fcb 100644 --- a/test/configCases/library/0-create-library/webpack.config.js +++ b/test/configCases/library/0-create-library/webpack.config.js @@ -4,6 +4,58 @@ const webpack = require("../../../../"); module.exports = (env, { testPath }) => [ { output: { + uniqueName: "esm", + filename: "esm.js", + libraryTarget: "module" + }, + target: "node14", + resolve: { + alias: { + external: "./non-external" + } + }, + experiments: { + outputModule: true + } + }, + { + output: { + uniqueName: "modern-module", + filename: "modern-module.js", + libraryTarget: "modern-module" + }, + target: "node14", + resolve: { + alias: { + external: "./non-external" + } + }, + experiments: { + outputModule: true + } + }, + { + output: { + uniqueName: "esm-runtimeChunk", + filename: "esm-runtimeChunk/[name].js", + libraryTarget: "module" + }, + target: "node14", + resolve: { + alias: { + external: "./non-external" + } + }, + optimization: { + runtimeChunk: "single" + }, + experiments: { + outputModule: true + } + }, + { + output: { + uniqueName: "commonjs", filename: "commonjs.js", libraryTarget: "commonjs", iife: false @@ -16,6 +68,7 @@ module.exports = (env, { testPath }) => [ }, { output: { + uniqueName: "commonjs-iife", filename: "commonjs-iife.js", libraryTarget: "commonjs", iife: true @@ -28,6 +81,7 @@ module.exports = (env, { testPath }) => [ }, { output: { + uniqueName: "amd", filename: "amd.js", libraryTarget: "amd", iife: false @@ -40,6 +94,7 @@ module.exports = (env, { testPath }) => [ }, { output: { + uniqueName: "amd-iife", filename: "amd-iife.js", libraryTarget: "amd", iife: true @@ -52,6 +107,43 @@ module.exports = (env, { testPath }) => [ }, { output: { + uniqueName: "amd-runtimeChunk", + filename: "amd-runtimeChunk/[name].js", + libraryTarget: "amd", + globalObject: "global", + iife: false + }, + target: "web", + resolve: { + alias: { + external: "./non-external" + } + }, + optimization: { + runtimeChunk: "single" + } + }, + { + output: { + uniqueName: "amd-iife-runtimeChunk", + filename: "amd-iife-runtimeChunk/[name].js", + libraryTarget: "amd", + globalObject: "global", + iife: true + }, + target: "web", + resolve: { + alias: { + external: "./non-external" + } + }, + optimization: { + runtimeChunk: "single" + } + }, + { + output: { + uniqueName: "umd", filename: "umd.js", libraryTarget: "umd" }, @@ -63,6 +155,7 @@ module.exports = (env, { testPath }) => [ }, { output: { + uniqueName: "umd-default", filename: "umd-default.js", libraryTarget: "umd", libraryExport: "default" @@ -75,6 +168,7 @@ module.exports = (env, { testPath }) => [ }, { output: { + uniqueName: "this", filename: "this.js", libraryTarget: "this", iife: false @@ -87,6 +181,7 @@ module.exports = (env, { testPath }) => [ }, { output: { + uniqueName: "this-iife", filename: "this-iife.js", libraryTarget: "this", iife: true @@ -99,6 +194,7 @@ module.exports = (env, { testPath }) => [ }, { output: { + uniqueName: "var", filename: "var.js", library: ["globalName", "x", "y"], iife: false @@ -117,6 +213,7 @@ module.exports = (env, { testPath }) => [ }, { output: { + uniqueName: "var-iife", filename: "var-iife.js", library: ["globalName", "x", "y"], iife: true @@ -136,6 +233,7 @@ module.exports = (env, { testPath }) => [ { entry: "./nested.js", output: { + uniqueName: "commonjs-nested", filename: "commonjs-nested.js", libraryTarget: "commonjs", libraryExport: "NS", @@ -150,6 +248,7 @@ module.exports = (env, { testPath }) => [ { entry: "./nested.js", output: { + uniqueName: "commonjs-nested-iife", filename: "commonjs-nested-iife.js", libraryTarget: "commonjs", libraryExport: "NS", @@ -163,6 +262,7 @@ module.exports = (env, { testPath }) => [ }, { output: { + uniqueName: "commonjs2-external", filename: "commonjs2-external.js", libraryTarget: "commonjs2", iife: false @@ -171,6 +271,7 @@ module.exports = (env, { testPath }) => [ }, { output: { + uniqueName: "commonjs2-external-no-concat", filename: "commonjs2-external-no-concat.js", libraryTarget: "commonjs2", iife: false @@ -182,6 +283,7 @@ module.exports = (env, { testPath }) => [ }, { output: { + uniqueName: "commonjs2-iife-external", filename: "commonjs2-iife-external.js", libraryTarget: "commonjs2", iife: true @@ -191,6 +293,7 @@ module.exports = (env, { testPath }) => [ { mode: "development", output: { + uniqueName: "commonjs2-external-eval", filename: "commonjs2-external-eval.js", libraryTarget: "commonjs2" }, @@ -199,6 +302,7 @@ module.exports = (env, { testPath }) => [ { mode: "development", output: { + uniqueName: "commonjs2-external-eval-source-map", filename: "commonjs2-external-eval-source-map.js", libraryTarget: "commonjs2" }, @@ -207,6 +311,16 @@ module.exports = (env, { testPath }) => [ }, { output: { + uniqueName: "commonjs-static-external", + filename: "commonjs-static-external.js", + libraryTarget: "commonjs-static", + iife: false + }, + externals: ["external"] + }, + { + output: { + uniqueName: "index", filename: "index.js", path: path.resolve(testPath, "commonjs2-split-chunks"), libraryTarget: "commonjs2" @@ -232,6 +346,7 @@ module.exports = (env, { testPath }) => [ }, { output: { + uniqueName: "commonjs2-runtimeChunk", filename: "commonjs2-runtimeChunk/[name].js", libraryTarget: "commonjs2", iife: false @@ -247,6 +362,7 @@ module.exports = (env, { testPath }) => [ }, { output: { + uniqueName: "commonjs2-iife-runtimeChunk", filename: "commonjs2-iife-runtimeChunk/[name].js", libraryTarget: "commonjs2", iife: true @@ -262,6 +378,7 @@ module.exports = (env, { testPath }) => [ }, { output: { + uniqueName: "global-runtimeChunk", filename: "global-runtimeChunk/[name].js", library: ["globalName", "x", "y"], libraryTarget: "global", @@ -279,6 +396,7 @@ module.exports = (env, { testPath }) => [ }, { output: { + uniqueName: "global-iife-runtimeChunk", filename: "global-iife-runtimeChunk/[name].js", library: ["globalName", "x", "y"], libraryTarget: "global", @@ -317,6 +435,7 @@ module.exports = (env, { testPath }) => [ library: { type: "commonjs-module" }, + uniqueName: "commonjs-module", filename: "[name].js" }, resolve: { diff --git a/test/configCases/library/1-use-library/default-test-modern-module.js b/test/configCases/library/1-use-library/default-test-modern-module.js new file mode 100644 index 00000000000..13f92f0fa20 --- /dev/null +++ b/test/configCases/library/1-use-library/default-test-modern-module.js @@ -0,0 +1,5 @@ +import d from "library"; + +it("should tree-shake other exports from library (" + NAME + ")", function() { + expect(d).toBe("default-value"); +}); diff --git a/test/configCases/library/1-use-library/test.config.js b/test/configCases/library/1-use-library/test.config.js new file mode 100644 index 00000000000..ac11abf4252 --- /dev/null +++ b/test/configCases/library/1-use-library/test.config.js @@ -0,0 +1,10 @@ +module.exports = { + moduleScope(scope) { + scope.define = factory => { + scope.module.exports = factory(); + }; + }, + afterExecute() { + delete global.webpackChunk; + } +}; diff --git a/test/configCases/library/1-use-library/webpack.config.js b/test/configCases/library/1-use-library/webpack.config.js index 7e1218d614f..ca3d224a48a 100644 --- a/test/configCases/library/1-use-library/webpack.config.js +++ b/test/configCases/library/1-use-library/webpack.config.js @@ -1,7 +1,76 @@ +/** @typedef {import("../../../../").Compiler} Compiler */ +/** @typedef {import("../../../../").Compilation} Compilation */ + var webpack = require("../../../../"); var path = require("path"); /** @type {function(any, any): import("../../../../").Configuration[]} */ module.exports = (env, { testPath }) => [ + { + resolve: { + alias: { + library: path.resolve(testPath, "../0-create-library/esm.js") + } + }, + plugins: [ + new webpack.DefinePlugin({ + NAME: JSON.stringify("esm") + }) + ] + }, + { + entry: "./default-test-modern-module.js", + optimization: { + minimize: true + }, + resolve: { + alias: { + library: path.resolve(testPath, "../0-create-library/modern-module.js") + } + }, + plugins: [ + new webpack.DefinePlugin({ + NAME: JSON.stringify("modern-module-tree-shakable") + }), + /** + * @this {Compiler} compiler + */ + function () { + /** + * @param {Compilation} compilation compilation + * @returns {void} + */ + const handler = compilation => { + compilation.hooks.afterProcessAssets.tap("testcase", assets => { + for (const asset of Object.keys(assets)) { + const source = assets[asset].source(); + expect(source).not.toContain('"a"'); + expect(source).not.toContain('"b"'); + expect(source).not.toContain('"non-external"'); + // expect pure ESM export without webpack runtime + expect(source).not.toContain('"__webpack_exports__"'); + expect(source).not.toContain('"__webpack_require__"'); + } + }); + }; + this.hooks.compilation.tap("testcase", handler); + } + ] + }, + { + resolve: { + alias: { + library: path.resolve( + testPath, + "../0-create-library/esm-runtimeChunk/main.js" + ) + } + }, + plugins: [ + new webpack.DefinePlugin({ + NAME: JSON.stringify("esm-runtimeChunk") + }) + ] + }, { resolve: { alias: { @@ -50,6 +119,40 @@ module.exports = (env, { testPath }) => [ }) ] }, + { + externals: { + library: `promise (require(${JSON.stringify( + "../0-create-library/amd-runtimeChunk/runtime.js" + )}), require(${JSON.stringify( + "../0-create-library/amd-runtimeChunk/main.js" + )}))` + }, + output: { + library: { type: "commonjs-module" } + }, + plugins: [ + new webpack.DefinePlugin({ + NAME: JSON.stringify("amd-runtimeChunk") + }) + ] + }, + { + externals: { + library: `promise (require(${JSON.stringify( + "../0-create-library/amd-iife-runtimeChunk/runtime.js" + )}), require(${JSON.stringify( + "../0-create-library/amd-iife-runtimeChunk/main.js" + )}))` + }, + output: { + library: { type: "commonjs-module" } + }, + plugins: [ + new webpack.DefinePlugin({ + NAME: JSON.stringify("amd-iife-runtimeChunk") + }) + ] + }, { resolve: { alias: { @@ -214,6 +317,23 @@ module.exports = (env, { testPath }) => [ }) ] }, + { + resolve: { + alias: { + library: path.resolve( + testPath, + "../0-create-library/commonjs-static-external.js" + ), + external: path.resolve(__dirname, "node_modules/external.js") + } + }, + plugins: [ + new webpack.DefinePlugin({ + NAME: JSON.stringify("commonjs-static with external"), + TEST_EXTERNAL: true + }) + ] + }, { resolve: { alias: { diff --git a/test/configCases/library/modern-module-reexport-type/export.ts b/test/configCases/library/modern-module-reexport-type/export.ts new file mode 100644 index 00000000000..cf4f7c76069 --- /dev/null +++ b/test/configCases/library/modern-module-reexport-type/export.ts @@ -0,0 +1,2 @@ +export type T = unknown +export const value = 1 diff --git a/test/configCases/library/modern-module-reexport-type/index.ts b/test/configCases/library/modern-module-reexport-type/index.ts new file mode 100644 index 00000000000..2b23a65adce --- /dev/null +++ b/test/configCases/library/modern-module-reexport-type/index.ts @@ -0,0 +1,7 @@ +import { value, T } from './re-export' + +export { value, T } + +it("should not reexport type", function () { + expect(value).toBe(1) +}); diff --git a/test/configCases/library/modern-module-reexport-type/re-export.ts b/test/configCases/library/modern-module-reexport-type/re-export.ts new file mode 100644 index 00000000000..dfbc7a6a69a --- /dev/null +++ b/test/configCases/library/modern-module-reexport-type/re-export.ts @@ -0,0 +1 @@ +export * from './export' diff --git a/test/configCases/library/modern-module-reexport-type/test.filter.js b/test/configCases/library/modern-module-reexport-type/test.filter.js new file mode 100644 index 00000000000..698f2822d2d --- /dev/null +++ b/test/configCases/library/modern-module-reexport-type/test.filter.js @@ -0,0 +1,5 @@ +var supportsOptionalChaining = require("../../../helpers/supportsOptionalChaining"); + +module.exports = function (config) { + return supportsOptionalChaining(); +}; diff --git a/test/configCases/library/modern-module-reexport-type/tsconfig.json b/test/configCases/library/modern-module-reexport-type/tsconfig.json new file mode 100644 index 00000000000..c2bf04fb9f3 --- /dev/null +++ b/test/configCases/library/modern-module-reexport-type/tsconfig.json @@ -0,0 +1,6 @@ +// emit to esm module +{ + "compilerOptions": { + "target": "ES2015", + } +} diff --git a/test/configCases/library/modern-module-reexport-type/webpack.config.js b/test/configCases/library/modern-module-reexport-type/webpack.config.js new file mode 100644 index 00000000000..8be5ca4ad9f --- /dev/null +++ b/test/configCases/library/modern-module-reexport-type/webpack.config.js @@ -0,0 +1,41 @@ +/** @type {import("../../../../").Configuration} */ +module.exports = { + mode: "none", + entry: { main: "./index.ts" }, + ignoreWarnings: [ + warning => { + // when using swc-loader or `transpileOnly: true` with ts-loader, the warning is expected + expect(warning.message).toContain( + "export 'T' (reexported as 'T') was not found in './re-export' (possible exports: value)" + ); + return true; + } + ], + output: { + module: true, + library: { + type: "modern-module" + }, + chunkFormat: "module" + }, + experiments: { + outputModule: true + }, + resolve: { + extensions: [".ts"] + }, + optimization: { + concatenateModules: true + }, + module: { + rules: [ + { + test: /\.ts$/, + loader: "ts-loader", + options: { + transpileOnly: true + } + } + ] + } +}; diff --git a/test/configCases/library/type-assign-properties/test.config.js b/test/configCases/library/type-assign-properties/test.config.js new file mode 100644 index 00000000000..0c592459f39 --- /dev/null +++ b/test/configCases/library/type-assign-properties/test.config.js @@ -0,0 +1,5 @@ +module.exports = { + afterExecute() { + delete global.MyLibraryProperties; + } +}; diff --git a/test/configCases/library/type-assign/test.config.js b/test/configCases/library/type-assign/test.config.js new file mode 100644 index 00000000000..79a079487a5 --- /dev/null +++ b/test/configCases/library/type-assign/test.config.js @@ -0,0 +1,5 @@ +module.exports = { + afterExecute() { + delete global.MyLibrary; + } +}; diff --git a/test/configCases/loader-import-module/css/colors.js b/test/configCases/loader-import-module/css/colors.js new file mode 100644 index 00000000000..d3da74ec7a1 --- /dev/null +++ b/test/configCases/loader-import-module/css/colors.js @@ -0,0 +1,2 @@ +export const red = "#f00"; +export const green = "#0f0"; diff --git a/test/configCases/loader-import-module/css/file.jpg b/test/configCases/loader-import-module/css/file.jpg new file mode 100644 index 00000000000..fe5c6eefa79 Binary files /dev/null and b/test/configCases/loader-import-module/css/file.jpg differ diff --git a/test/configCases/loader-import-module/css/file.png b/test/configCases/loader-import-module/css/file.png new file mode 100644 index 00000000000..fb53b9dedd3 Binary files /dev/null and b/test/configCases/loader-import-module/css/file.png differ diff --git a/test/configCases/loader-import-module/css/index.js b/test/configCases/loader-import-module/css/index.js new file mode 100644 index 00000000000..9d5739c3972 --- /dev/null +++ b/test/configCases/loader-import-module/css/index.js @@ -0,0 +1,15 @@ +import stylesheet from "./stylesheet"; +import stylesheet1 from "./stylesheet?1"; +import otherStylesheet from "./other-stylesheet"; + +it("should be able to use build-time code", () => { + expect(stylesheet).toBe( + 'body { background: url("/public/assets/file.png"); color: #f00; }' + ); + expect(stylesheet1).toBe( + 'body { background: url("/public/assets/file.png?1"); color: #f00; }' + ); + expect(otherStylesheet).toBe( + 'body { background: url("/other/assets/file.jpg"); color: #0f0; }' + ); +}); diff --git a/test/configCases/loader-import-module/css/loader.js b/test/configCases/loader-import-module/css/loader.js new file mode 100644 index 00000000000..2dae62a4065 --- /dev/null +++ b/test/configCases/loader-import-module/css/loader.js @@ -0,0 +1,8 @@ +/** @type {import("../../../../").PitchLoaderDefinitionFunction} */ +exports.pitch = async function (remaining) { + const result = await this.importModule( + this.resourcePath + ".webpack[javascript/auto]" + "!=!" + remaining, + this.getOptions() + ); + return result.default || result; +}; diff --git a/test/configCases/loader-import-module/css/other-stylesheet.js b/test/configCases/loader-import-module/css/other-stylesheet.js new file mode 100644 index 00000000000..d3be25b7f28 --- /dev/null +++ b/test/configCases/loader-import-module/css/other-stylesheet.js @@ -0,0 +1,3 @@ +import { green } from "./colors.js"; +import file from "./file.jpg"; +export default `body { background: url("${file}"); color: ${green}; }`; diff --git a/test/configCases/loader-import-module/css/stylesheet.js b/test/configCases/loader-import-module/css/stylesheet.js new file mode 100644 index 00000000000..7d542e93be0 --- /dev/null +++ b/test/configCases/loader-import-module/css/stylesheet.js @@ -0,0 +1,4 @@ +import { red } from "./colors.js"; +export default `body { background: url("${ + new URL("./file.png" + __resourceQuery, import.meta.url).href +}"); color: ${red}; }`; diff --git a/test/configCases/loader-import-module/css/webpack.config.js b/test/configCases/loader-import-module/css/webpack.config.js new file mode 100644 index 00000000000..5e6e763f3a6 --- /dev/null +++ b/test/configCases/loader-import-module/css/webpack.config.js @@ -0,0 +1,69 @@ +/** @type {import("../../../../").Configuration} */ +module.exports = { + output: { + publicPath: "/public/" + }, + module: { + parser: { + javascript: { + url: "relative" + } + }, + rules: [ + { + dependency: "url", + issuer: /stylesheet\.js$/, + type: "asset/resource", + generator: { + filename: "assets/[name][ext][query]" + } + }, + { + oneOf: [ + { + test: /other-stylesheet\.js$/, + loader: "./loader", + options: { + publicPath: "/other/" + }, + type: "asset/source" + }, + { + test: /stylesheet\.js$/, + use: "./loader", + type: "asset/source" + } + ] + }, + { + test: /\.jpg$/, + loader: "file-loader", + options: { + name: "assets/[name].[ext]" + } + } + ] + }, + plugins: [ + compiler => + compiler.hooks.done.tap("test case", stats => { + try { + expect(stats.compilation.getAsset("assets/file.png")).toHaveProperty( + "info", + expect.objectContaining({ sourceFilename: "file.png" }) + ); + expect(stats.compilation.getAsset("assets/file.jpg")).toHaveProperty( + "info", + expect.objectContaining({ sourceFilename: "file.jpg" }) + ); + const { auxiliaryFiles } = stats.compilation.namedChunks.get("main"); + expect(auxiliaryFiles).toContain("assets/file.png"); + expect(auxiliaryFiles).toContain("assets/file.png?1"); + expect(auxiliaryFiles).toContain("assets/file.jpg"); + } catch (err) { + console.log(stats.toString({ colors: true, orphanModules: true })); + throw err; + } + }) + ] +}; diff --git a/test/configCases/loaders-and-plugins-falsy/basic/bar.js b/test/configCases/loaders-and-plugins-falsy/basic/bar.js new file mode 100644 index 00000000000..58c57157d36 --- /dev/null +++ b/test/configCases/loaders-and-plugins-falsy/basic/bar.js @@ -0,0 +1 @@ +export default "test"; diff --git a/test/configCases/loaders-and-plugins-falsy/basic/baz.js b/test/configCases/loaders-and-plugins-falsy/basic/baz.js new file mode 100644 index 00000000000..58c57157d36 --- /dev/null +++ b/test/configCases/loaders-and-plugins-falsy/basic/baz.js @@ -0,0 +1 @@ +export default "test"; diff --git a/test/configCases/loaders-and-plugins-falsy/basic/foo.js b/test/configCases/loaders-and-plugins-falsy/basic/foo.js new file mode 100644 index 00000000000..58c57157d36 --- /dev/null +++ b/test/configCases/loaders-and-plugins-falsy/basic/foo.js @@ -0,0 +1 @@ +export default "test"; diff --git a/test/configCases/loaders-and-plugins-falsy/basic/index.js b/test/configCases/loaders-and-plugins-falsy/basic/index.js new file mode 100644 index 00000000000..d71e4dc1d29 --- /dev/null +++ b/test/configCases/loaders-and-plugins-falsy/basic/index.js @@ -0,0 +1,12 @@ +import foo from "./foo.js?external"; +import bar from "./bar.js"; +import baz from "./baz.js?custom-use"; +import other from "./other.js"; + +it("should work with falsy plugins and loaders", function() { + expect(ONE).toBe("ONE"); + expect(foo.endsWith("?external")).toBe(true); + expect(bar).toBe("test"); + expect(baz).toBe("test"); + expect(other).toBe("NEW"); +}); diff --git a/test/configCases/loaders-and-plugins-falsy/basic/loader.js b/test/configCases/loaders-and-plugins-falsy/basic/loader.js new file mode 100644 index 00000000000..6c5f48f747e --- /dev/null +++ b/test/configCases/loaders-and-plugins-falsy/basic/loader.js @@ -0,0 +1,4 @@ +/** @type {import("../../../../").LoaderDefinition<{ value: any }>} */ +module.exports = function loader(content) { + return content.replace(/test/, "NEW"); +}; diff --git a/test/configCases/loaders-and-plugins-falsy/basic/other.js b/test/configCases/loaders-and-plugins-falsy/basic/other.js new file mode 100644 index 00000000000..58c57157d36 --- /dev/null +++ b/test/configCases/loaders-and-plugins-falsy/basic/other.js @@ -0,0 +1 @@ +export default "test"; diff --git a/test/configCases/loaders-and-plugins-falsy/basic/webpack.config.js b/test/configCases/loaders-and-plugins-falsy/basic/webpack.config.js new file mode 100644 index 00000000000..8d75b66cb7c --- /dev/null +++ b/test/configCases/loaders-and-plugins-falsy/basic/webpack.config.js @@ -0,0 +1,113 @@ +var DefinePlugin = require("../../../../").DefinePlugin; + +const nullValue = null; +const undefinedValue = undefined; +const falseValue = false; +const zeroValue = 0; +const emptyStringValue = ""; + +class FailPlugin { + apply() { + throw new Error("FailedPlugin"); + } +} + +class TestChildCompilationPlugin { + constructor(output) {} + + apply(compiler) { + compiler.hooks.make.tapAsync( + "TestChildCompilationFailurePlugin", + (compilation, cb) => { + const child = compilation.createChildCompiler( + "name", + compiler.outputOptions, + [ + undefinedValue && new FailPlugin(), + nullValue && new FailPlugin(), + falseValue && new FailPlugin(), + zeroValue && new FailPlugin(), + emptyStringValue && new FailPlugin() + ] + ); + + child.runAsChild(cb); + } + ); + } +} + +/** @type {import("../../../../").Configuration} */ +module.exports = { + // Will failed because we don't have unknown-loader + module: { + defaultRules: [ + nullValue && { + test: /\.js$/, + loader: "unknown-loader" + }, + "..." + ], + rules: [ + nullValue && { + test: /\.js$/, + loader: "unknown-loader" + }, + { + test: /foo\.js$/, + oneOf: [ + nullValue && { + resourceQuery: /inline/, + loader: "unknown-loader" + }, + { + resourceQuery: /external/, + type: "asset/resource" + } + ] + }, + { + test: /bar\.js$/, + use: [nullValue && "unknown-loader"] + }, + { + test: /baz\.js$/, + resourceQuery: /custom-use/, + use: () => [ + nullValue && { + loader: "unknown-loader" + } + ] + }, + { + test: /other\.js$/, + rules: [ + nullValue && { + loader: "unknown-loader" + }, + { + loader: "./loader.js" + } + ] + } + ] + }, + resolve: { + plugins: [undefinedValue && new FailPlugin()] + }, + plugins: [ + new DefinePlugin({ + ONE: JSON.stringify("ONE") + }), + new TestChildCompilationPlugin(), + undefinedValue && new FailPlugin(), + nullValue && new FailPlugin(), + falseValue && new FailPlugin(), + zeroValue && new FailPlugin(), + emptyStringValue && new FailPlugin() + ], + optimization: { + minimize: true, + minimizer: [nullValue && new FailPlugin()] + } +}; diff --git a/test/configCases/loaders/#-issue-14755-#/#.my b/test/configCases/loaders/#-issue-14755-#/#.my new file mode 100644 index 00000000000..19dd091730f --- /dev/null +++ b/test/configCases/loaders/#-issue-14755-#/#.my @@ -0,0 +1 @@ +[a-z] diff --git a/test/configCases/loaders/#-issue-14755-#/index.js b/test/configCases/loaders/#-issue-14755-#/index.js new file mode 100644 index 00000000000..092ef0aab48 --- /dev/null +++ b/test/configCases/loaders/#-issue-14755-#/index.js @@ -0,0 +1,6 @@ +import regexp from './#.my'; + +it("should load regexp correctly", () => { + expect(regexp.test("1")).toBe(false); + expect(regexp.test("a")).toBe(true); +}); diff --git a/test/configCases/loaders/#-issue-14755-#/node_modules/regexp-#-loader/index.js b/test/configCases/loaders/#-issue-14755-#/node_modules/regexp-#-loader/index.js new file mode 100644 index 00000000000..d7410984ab4 --- /dev/null +++ b/test/configCases/loaders/#-issue-14755-#/node_modules/regexp-#-loader/index.js @@ -0,0 +1,5 @@ +"use strict"; + +module.exports = function loader(data) { + return `export default new RegExp(${JSON.stringify(data.trim())})` +} diff --git a/test/configCases/loaders/#-issue-14755-#/node_modules/regexp-#-loader/package.json b/test/configCases/loaders/#-issue-14755-#/node_modules/regexp-#-loader/package.json new file mode 100644 index 00000000000..aa8a1ecf19e --- /dev/null +++ b/test/configCases/loaders/#-issue-14755-#/node_modules/regexp-#-loader/package.json @@ -0,0 +1,6 @@ +{ + "name": "regexp-#-loader", + "version": "1.0.0", + "dependencies": { + } +} diff --git a/test/configCases/loaders/#-issue-14755-#/webpack.config.js b/test/configCases/loaders/#-issue-14755-#/webpack.config.js new file mode 100644 index 00000000000..a8828552624 --- /dev/null +++ b/test/configCases/loaders/#-issue-14755-#/webpack.config.js @@ -0,0 +1,11 @@ +/** @type {import("../../../../").Configuration} */ +module.exports = { + module: { + rules: [ + { + test: /\.my$/, + loader: "regexp-#-loader" + } + ] + } +}; diff --git a/test/configCases/loaders/generate-ident/loader1.js b/test/configCases/loaders/generate-ident/loader1.js index 42fea46336a..0d2fcc8b593 100644 --- a/test/configCases/loaders/generate-ident/loader1.js +++ b/test/configCases/loaders/generate-ident/loader1.js @@ -1,3 +1,6 @@ -module.exports.pitch = function(remainingRequest) { - return "module.exports = require(" + JSON.stringify("!!" + remainingRequest) + ");"; +/** @type {import("../../../../").PitchLoaderDefinitionFunction} */ +module.exports.pitch = function (remainingRequest) { + return ( + "module.exports = require(" + JSON.stringify("!!" + remainingRequest) + ");" + ); }; diff --git a/test/configCases/loaders/generate-ident/loader2.js b/test/configCases/loaders/generate-ident/loader2.js index b5b133a9208..40788042801 100644 --- a/test/configCases/loaders/generate-ident/loader2.js +++ b/test/configCases/loaders/generate-ident/loader2.js @@ -1,3 +1,6 @@ -module.exports = function(source) { +/** @type {import("../../../../").LoaderDefinition<{ f(): any }>} */ +module.exports = function (source) { + if (typeof this.query === "string") + throw new Error("query must be an object"); return "module.exports = " + JSON.stringify(this.query.f()); }; diff --git a/test/configCases/loaders/hot-in-context/loader.js b/test/configCases/loaders/hot-in-context/loader.js index b497b8bc45e..608faaddb21 100644 --- a/test/configCases/loaders/hot-in-context/loader.js +++ b/test/configCases/loaders/hot-in-context/loader.js @@ -1,3 +1,4 @@ -module.exports = function() { +/** @type {import("../../../../").LoaderDefinition}} */ +module.exports = function () { return `module.exports = ${JSON.stringify(!!this.hot)};`; -} +}; diff --git a/test/configCases/loaders/import-attributes-and-assertion/index.js b/test/configCases/loaders/import-attributes-and-assertion/index.js new file mode 100644 index 00000000000..606b31f5d46 --- /dev/null +++ b/test/configCases/loaders/import-attributes-and-assertion/index.js @@ -0,0 +1,12 @@ +import one from "./pkg-1.json" assert { type: "json" }; +import two from "./pkg-2.json" with { type: "json" }; +import three from "./pkg-3.json" assert { type: "json" }; +import four from "./pkg-4.json" with { type: "json" }; + +it("import attributes and assertion should work", function() { + expect(one.type).toEqual("assert"); + expect(two.type).toEqual("with"); + expect(three.type).toEqual("assert"); + expect(four.type).toEqual("with"); +}); + diff --git a/test/configCases/loaders/import-attributes-and-assertion/loader-assert.js b/test/configCases/loaders/import-attributes-and-assertion/loader-assert.js new file mode 100644 index 00000000000..0906f985e70 --- /dev/null +++ b/test/configCases/loaders/import-attributes-and-assertion/loader-assert.js @@ -0,0 +1,4 @@ +/** @type {import("../../../../").LoaderDefinition} */ +module.exports = function (source) { + return JSON.stringify({ type: "assert" }); +}; diff --git a/test/configCases/loaders/import-attributes-and-assertion/loader-with.js b/test/configCases/loaders/import-attributes-and-assertion/loader-with.js new file mode 100644 index 00000000000..7209f804dbd --- /dev/null +++ b/test/configCases/loaders/import-attributes-and-assertion/loader-with.js @@ -0,0 +1,4 @@ +/** @type {import("../../../../").LoaderDefinition} */ +module.exports = function (source) { + return JSON.stringify({ type: "with" }); +}; diff --git a/test/configCases/loaders/import-attributes-and-assertion/pkg-1.json b/test/configCases/loaders/import-attributes-and-assertion/pkg-1.json new file mode 100644 index 00000000000..90eae66140a --- /dev/null +++ b/test/configCases/loaders/import-attributes-and-assertion/pkg-1.json @@ -0,0 +1,3 @@ +{ + "type": "none" +} diff --git a/test/configCases/loaders/import-attributes-and-assertion/pkg-2.json b/test/configCases/loaders/import-attributes-and-assertion/pkg-2.json new file mode 100644 index 00000000000..90eae66140a --- /dev/null +++ b/test/configCases/loaders/import-attributes-and-assertion/pkg-2.json @@ -0,0 +1,3 @@ +{ + "type": "none" +} diff --git a/test/configCases/loaders/import-attributes-and-assertion/pkg-3.json b/test/configCases/loaders/import-attributes-and-assertion/pkg-3.json new file mode 100644 index 00000000000..186e2ba4afd --- /dev/null +++ b/test/configCases/loaders/import-attributes-and-assertion/pkg-3.json @@ -0,0 +1,3 @@ +{ + "type": "assert" +} diff --git a/test/configCases/loaders/import-attributes-and-assertion/pkg-4.json b/test/configCases/loaders/import-attributes-and-assertion/pkg-4.json new file mode 100644 index 00000000000..88301984e31 --- /dev/null +++ b/test/configCases/loaders/import-attributes-and-assertion/pkg-4.json @@ -0,0 +1,3 @@ +{ + "type": "with" +} diff --git a/test/configCases/loaders/import-attributes-and-assertion/webpack.config.js b/test/configCases/loaders/import-attributes-and-assertion/webpack.config.js new file mode 100644 index 00000000000..05fd19f2fc3 --- /dev/null +++ b/test/configCases/loaders/import-attributes-and-assertion/webpack.config.js @@ -0,0 +1,15 @@ +/** @type {import("../../../../").Configuration} */ +module.exports = { + module: { + rules: [ + { + assert: { type: "json" }, + loader: require.resolve("./loader-assert.js") + }, + { + with: { type: "json" }, + loader: require.resolve("./loader-with.js") + } + ] + } +}; diff --git a/test/configCases/loaders/issue-3320/deprecations.js b/test/configCases/loaders/issue-3320/deprecations.js index aac17455119..f05114b9382 100644 --- a/test/configCases/loaders/issue-3320/deprecations.js +++ b/test/configCases/loaders/issue-3320/deprecations.js @@ -1,10 +1,12 @@ module.exports = [ { code: /DEP_WEBPACK_RULE_LOADER_OPTIONS_STRING/, - message: /Using a string as loader options is deprecated \(ruleSet\[1\]\.rules\[2\]\.options\)/ + message: + /Using a string as loader options is deprecated \(ruleSet\[1\]\.rules\[2\]\.options\)/ }, { code: /DEP_WEBPACK_RULE_LOADER_OPTIONS_STRING/, - message: /Using a string as loader options is deprecated \(ruleSet\[1\]\.rules\[3\]\.use\[0\]\.options\)/ + message: + /Using a string as loader options is deprecated \(ruleSet\[1\]\.rules\[3\]\.use\[0\]\.options\)/ } ]; diff --git a/test/configCases/loaders/mode-default/loader.js b/test/configCases/loaders/mode-default/loader.js index 0083d38fd1b..b9c10626bc4 100644 --- a/test/configCases/loaders/mode-default/loader.js +++ b/test/configCases/loaders/mode-default/loader.js @@ -1,3 +1,4 @@ -module.exports = function(source) { +/** @type {import("../../../../").LoaderDefinition} */ +module.exports = function (source) { return `module.exports = "${this.mode}";`; }; diff --git a/test/configCases/loaders/mode-development/loader.js b/test/configCases/loaders/mode-development/loader.js index 0083d38fd1b..b9c10626bc4 100644 --- a/test/configCases/loaders/mode-development/loader.js +++ b/test/configCases/loaders/mode-development/loader.js @@ -1,3 +1,4 @@ -module.exports = function(source) { +/** @type {import("../../../../").LoaderDefinition} */ +module.exports = function (source) { return `module.exports = "${this.mode}";`; }; diff --git a/test/configCases/loaders/mode-none/loader.js b/test/configCases/loaders/mode-none/loader.js index 0083d38fd1b..b9c10626bc4 100644 --- a/test/configCases/loaders/mode-none/loader.js +++ b/test/configCases/loaders/mode-none/loader.js @@ -1,3 +1,4 @@ -module.exports = function(source) { +/** @type {import("../../../../").LoaderDefinition} */ +module.exports = function (source) { return `module.exports = "${this.mode}";`; }; diff --git a/test/configCases/loaders/mode-production/loader.js b/test/configCases/loaders/mode-production/loader.js index 0083d38fd1b..b9c10626bc4 100644 --- a/test/configCases/loaders/mode-production/loader.js +++ b/test/configCases/loaders/mode-production/loader.js @@ -1,3 +1,4 @@ -module.exports = function(source) { +/** @type {import("../../../../").LoaderDefinition} */ +module.exports = function (source) { return `module.exports = "${this.mode}";`; }; diff --git a/test/configCases/loaders/options/infrastructure-log.js b/test/configCases/loaders/options/infrastructure-log.js new file mode 100644 index 00000000000..8ef4be52eb7 --- /dev/null +++ b/test/configCases/loaders/options/infrastructure-log.js @@ -0,0 +1,4 @@ +module.exports = [ + // We use (1|2), because both contain the problems, but due asynchronous nature the first module can be `error1` or `error2` + /^Pack got invalid because of write to: Compilation\/modules.+loaders[/\\]options[/\\]error(1|2)\.js$/ +]; diff --git a/test/configCases/loaders/options/loader-1.js b/test/configCases/loaders/options/loader-1.js index f27763418ab..18e183cbbb0 100644 --- a/test/configCases/loaders/options/loader-1.js +++ b/test/configCases/loaders/options/loader-1.js @@ -1,6 +1,7 @@ -const schema = require("./loader-1.options"); +const schema = require("./loader-1.options.json"); -module.exports = function() { +/** @type {import("../../../../").LoaderDefinition} */ +module.exports = function () { const options = this.getOptions(schema); const json = JSON.stringify(options) diff --git a/test/configCases/loaders/options/loader-2.js b/test/configCases/loaders/options/loader-2.js index b1690265227..faea214da83 100644 --- a/test/configCases/loaders/options/loader-2.js +++ b/test/configCases/loaders/options/loader-2.js @@ -1,6 +1,7 @@ -const schema = require("./loader-2.options"); +const schema = require("./loader-2.options.json"); -module.exports = function() { +/** @type {import("../../../../").LoaderDefinition} */ +module.exports = function () { const options = this.getOptions(schema); const json = JSON.stringify(options) diff --git a/test/configCases/loaders/options/loader.js b/test/configCases/loaders/options/loader.js index 5b9386651be..d1bc02fcd3c 100644 --- a/test/configCases/loaders/options/loader.js +++ b/test/configCases/loaders/options/loader.js @@ -1,9 +1,10 @@ -module.exports = function() { +/** @type {import("../../../../").LoaderDefinition} */ +module.exports = function () { const options = this.getOptions(); const json = JSON.stringify(options) - .replace(/\u2028/g, '\\u2028') - .replace(/\u2029/g, '\\u2029'); + .replace(/\u2028/g, "\\u2028") + .replace(/\u2029/g, "\\u2029"); return `module.exports = ${json}`; }; diff --git a/test/configCases/loaders/pr-14384/PluginWithLoader.js b/test/configCases/loaders/pr-14384/PluginWithLoader.js new file mode 100644 index 00000000000..74a415793b0 --- /dev/null +++ b/test/configCases/loaders/pr-14384/PluginWithLoader.js @@ -0,0 +1,26 @@ +const { NormalModule } = require("webpack"); + +const PLUGIN_NAME = "PluginWithLoader"; +const loaderPath = require.resolve("./loader.js"); + +class PluginWithLoader { + apply(compiler) { + compiler.hooks.compilation.tap(PLUGIN_NAME, compilation => { + NormalModule.getCompilationHooks(compilation).beforeLoaders.tap( + PLUGIN_NAME, + (loaders, normalModule) => { + if (normalModule.userRequest.indexOf("a.js") !== -1) { + loaders.push({ + loader: loaderPath, + options: {}, + ident: null, + type: null + }); + } + } + ); + }); + } +} + +module.exports = PluginWithLoader; diff --git a/test/configCases/loaders/pr-14384/a.js b/test/configCases/loaders/pr-14384/a.js new file mode 100644 index 00000000000..e69de29bb2d diff --git a/test/configCases/loaders/pr-14384/index.js b/test/configCases/loaders/pr-14384/index.js new file mode 100644 index 00000000000..7d6a89b89ad --- /dev/null +++ b/test/configCases/loaders/pr-14384/index.js @@ -0,0 +1,3 @@ +it("successfully loads a file that gets its only loader from a plugins beforeLoaders hook", function() { + expect(require("./a")).toBe("success"); +}); diff --git a/test/configCases/loaders/pr-14384/loader.js b/test/configCases/loaders/pr-14384/loader.js new file mode 100644 index 00000000000..27d54132d70 --- /dev/null +++ b/test/configCases/loaders/pr-14384/loader.js @@ -0,0 +1,4 @@ +/** @type {import("../../../../").LoaderDefinition} */ +module.exports = function () { + return `module.exports = "success";`; +}; diff --git a/test/configCases/loaders/pr-14384/webpack.config.js b/test/configCases/loaders/pr-14384/webpack.config.js new file mode 100644 index 00000000000..edf691513a7 --- /dev/null +++ b/test/configCases/loaders/pr-14384/webpack.config.js @@ -0,0 +1,6 @@ +const PluginWithLoader = require("./PluginWithLoader.js"); + +/** @type {import("../../../../").Configuration} */ +module.exports = { + plugins: [new PluginWithLoader()] +}; diff --git a/test/configCases/loaders/pre-post-loader/loader1.js b/test/configCases/loaders/pre-post-loader/loader1.js index 71df71135dd..bf6d1335221 100644 --- a/test/configCases/loaders/pre-post-loader/loader1.js +++ b/test/configCases/loaders/pre-post-loader/loader1.js @@ -1,3 +1,4 @@ -module.exports = function(source) { - return source + "module.exports += \" loader1\";\n"; +/** @type {import("../../../../").LoaderDefinition} */ +module.exports = function (source) { + return source + 'module.exports += " loader1";\n'; }; diff --git a/test/configCases/loaders/pre-post-loader/loader2.js b/test/configCases/loaders/pre-post-loader/loader2.js index 91497b0978b..b611c84f62b 100644 --- a/test/configCases/loaders/pre-post-loader/loader2.js +++ b/test/configCases/loaders/pre-post-loader/loader2.js @@ -1,3 +1,4 @@ -module.exports = function(source) { - return source + "module.exports += \" loader2\";\n"; +/** @type {import("../../../../").LoaderDefinition} */ +module.exports = function (source) { + return source + 'module.exports += " loader2";\n'; }; diff --git a/test/configCases/loaders/pre-post-loader/loader3.js b/test/configCases/loaders/pre-post-loader/loader3.js index 32f164287a0..ec526cbac53 100644 --- a/test/configCases/loaders/pre-post-loader/loader3.js +++ b/test/configCases/loaders/pre-post-loader/loader3.js @@ -1,3 +1,4 @@ -module.exports = function(source) { - return source + "module.exports += \" loader3\";\n"; +/** @type {import("../../../../").LoaderDefinition} */ +module.exports = function (source) { + return source + 'module.exports += " loader3";\n'; }; diff --git a/test/configCases/loaders/remaining-request/loader1.js b/test/configCases/loaders/remaining-request/loader1.js index 42fea46336a..0d2fcc8b593 100644 --- a/test/configCases/loaders/remaining-request/loader1.js +++ b/test/configCases/loaders/remaining-request/loader1.js @@ -1,3 +1,6 @@ -module.exports.pitch = function(remainingRequest) { - return "module.exports = require(" + JSON.stringify("!!" + remainingRequest) + ");"; +/** @type {import("../../../../").PitchLoaderDefinitionFunction} */ +module.exports.pitch = function (remainingRequest) { + return ( + "module.exports = require(" + JSON.stringify("!!" + remainingRequest) + ");" + ); }; diff --git a/test/configCases/loaders/remaining-request/loader2.js b/test/configCases/loaders/remaining-request/loader2.js index b5b133a9208..40788042801 100644 --- a/test/configCases/loaders/remaining-request/loader2.js +++ b/test/configCases/loaders/remaining-request/loader2.js @@ -1,3 +1,6 @@ -module.exports = function(source) { +/** @type {import("../../../../").LoaderDefinition<{ f(): any }>} */ +module.exports = function (source) { + if (typeof this.query === "string") + throw new Error("query must be an object"); return "module.exports = " + JSON.stringify(this.query.f()); }; diff --git a/test/configCases/managedPaths/futureDefaults/index.js b/test/configCases/managedPaths/futureDefaults/index.js new file mode 100644 index 00000000000..f191f157474 --- /dev/null +++ b/test/configCases/managedPaths/futureDefaults/index.js @@ -0,0 +1,5 @@ +import value from "package"; + +it("should work", () => { + expect(value).toBe(42); +}); diff --git a/test/configCases/managedPaths/futureDefaults/node_modules/package/index.js b/test/configCases/managedPaths/futureDefaults/node_modules/package/index.js new file mode 100644 index 00000000000..7a4e8a723a4 --- /dev/null +++ b/test/configCases/managedPaths/futureDefaults/node_modules/package/index.js @@ -0,0 +1 @@ +export default 42; diff --git a/test/configCases/managedPaths/futureDefaults/node_modules/package/package.json b/test/configCases/managedPaths/futureDefaults/node_modules/package/package.json new file mode 100644 index 00000000000..75b93e3b25a --- /dev/null +++ b/test/configCases/managedPaths/futureDefaults/node_modules/package/package.json @@ -0,0 +1,4 @@ +{ + "name": "package", + "version": "1.0.0" +} diff --git a/test/configCases/managedPaths/futureDefaults/webpack.config.js b/test/configCases/managedPaths/futureDefaults/webpack.config.js new file mode 100644 index 00000000000..bf94f1dd4e2 --- /dev/null +++ b/test/configCases/managedPaths/futureDefaults/webpack.config.js @@ -0,0 +1,6 @@ +/** @type {import("../../../../").Configuration} */ +module.exports = { + experiments: { + futureDefaults: true + } +}; diff --git a/test/configCases/mangle/exports-info-can-mangle/a.js b/test/configCases/mangle/exports-info-can-mangle/a.js new file mode 100644 index 00000000000..25540f9cda1 --- /dev/null +++ b/test/configCases/mangle/exports-info-can-mangle/a.js @@ -0,0 +1,2 @@ +export const aaa = "aaa"; +export const aaaCanMangle = __webpack_exports_info__.aaa.canMangle; diff --git a/test/configCases/mangle/exports-info-can-mangle/b.js b/test/configCases/mangle/exports-info-can-mangle/b.js new file mode 100644 index 00000000000..126daf82d9a --- /dev/null +++ b/test/configCases/mangle/exports-info-can-mangle/b.js @@ -0,0 +1,2 @@ +export const bbb = "bbb"; +export const bbbCanMangle = __webpack_exports_info__.bbb.canMangle; diff --git a/test/configCases/mangle/exports-info-can-mangle/c.js b/test/configCases/mangle/exports-info-can-mangle/c.js new file mode 100644 index 00000000000..68bbacdbe2b --- /dev/null +++ b/test/configCases/mangle/exports-info-can-mangle/c.js @@ -0,0 +1,6 @@ +export * as ca from "./a"; +export * as cb from "./b"; +export const caCanMangle = __webpack_exports_info__.ca.canMangle; +export const cbCanMangle = __webpack_exports_info__.cb.canMangle; +export const ca_aaaCanMangle = __webpack_exports_info__.ca.aaa.canMangle; +export const cb_bbbCanMangle = __webpack_exports_info__.cb.bbb.canMangle; \ No newline at end of file diff --git a/test/configCases/mangle/exports-info-can-mangle/index.js b/test/configCases/mangle/exports-info-can-mangle/index.js new file mode 100644 index 00000000000..69f2d5099a7 --- /dev/null +++ b/test/configCases/mangle/exports-info-can-mangle/index.js @@ -0,0 +1,23 @@ +import { aaa, aaaCanMangle } from "./a"; +import * as b from "./b" +import { ca, cb, caCanMangle, cbCanMangle, ca_aaaCanMangle, cb_bbbCanMangle } from "./c"; + +it("__webpack_exports_info__.xxx.canMangle should be correct", () => { + expect(aaa).toBe("aaa"); + expect(aaaCanMangle).toBe(true); + + const { bbb, bbbCanMangle } = b; + expect(bbb).toBe("bbb"); + expect(bbbCanMangle).toBe(true); + + expect(caCanMangle).toBe(true); + expect(cbCanMangle).toBe(true); +}); + +it("__webpack_exports_info__.xxx.yyy.canMangle should be correct", () => { + expect(ca.aaa).toBe("aaa"); + expect(ca_aaaCanMangle).toBe(aaaCanMangle); + + expect(cb.bbb).toBe("bbb"); + expect(cb_bbbCanMangle).toBe(b.bbbCanMangle); +}); diff --git a/test/configCases/mangle/exports-info-can-mangle/webpack.config.js b/test/configCases/mangle/exports-info-can-mangle/webpack.config.js new file mode 100644 index 00000000000..3d405a2e2f2 --- /dev/null +++ b/test/configCases/mangle/exports-info-can-mangle/webpack.config.js @@ -0,0 +1,8 @@ +/** @type {import("../../../../").Configuration} */ +module.exports = { + optimization: { + mangleExports: true, + usedExports: true, + providedExports: true + } +}; diff --git a/test/configCases/mangle/mangle-with-destructuring-assignment/data.json b/test/configCases/mangle/mangle-with-destructuring-assignment/data.json new file mode 100644 index 00000000000..3248ec2c36d --- /dev/null +++ b/test/configCases/mangle/mangle-with-destructuring-assignment/data.json @@ -0,0 +1,19 @@ +{ + "obj": { + "arr": [ + { + "prop1": 1, + "prop2": 2 + }, + { + "prop3": 3, + "prop4": 4 + }, + { + "prop5": 5, + "prop6": 6 + } + ] + }, + "foo": "foo" +} diff --git a/test/configCases/mangle/mangle-with-destructuring-assignment/index.js b/test/configCases/mangle/mangle-with-destructuring-assignment/index.js new file mode 100644 index 00000000000..1d460b29369 --- /dev/null +++ b/test/configCases/mangle/mangle-with-destructuring-assignment/index.js @@ -0,0 +1,94 @@ +import path from "path"; +import * as module from "./module"; +import { obj3, obj3CanMangle, obj4, obj4CanMangle } from "./reexport?side-effects" // enable side effects to ensure reexport is not skipped +import data from "./data.json"; +import data2 from "./data.json?2"; + +it("should mangle export when destructuring module", () => { + const { obj: { a, b }, objCanMangle } = module + expect(a).toBe("a"); + expect(b).toBe("b"); + expect(objCanMangle).toBe(true) +}); + +it("should mangle export when destructuring module's property", () => { + const { a, b } = module.obj2 + const { obj2CanMangle } = module + expect(a).toBe("a"); + expect(b).toBe("b"); + expect(obj2CanMangle).toBe(true) +}); + +it("should mangle export when using module dot property", () => { + expect(module.aaa).toBe("aaa"); + expect(module.aaaCanMangle).toBe(true) +}); + +it("should mangle export when destructuring module's property is a module", () => { + const { aaa, bbb } = obj3; + expect(aaa).toBe("a"); + expect(bbb).toBe("b"); + expect(obj3CanMangle).toBe(true) +}); + +it("should not mangle export when destructuring module's nested property is a module (used in unknown way)", () => { + const { nested: { obj5, obj5CanMangle } } = obj4; + expect(obj5.aaa).toBe("a"); + expect(obj5.bbb).toBe("b"); + expect(obj4CanMangle).toBe(true); + expect(obj5CanMangle).toBe(false); // obj5 is used in unknown way +}); + +it("should mangle default in namespace import", async () => { + const { default: foo, defaultCanMangle } = module; + expect(foo).toBe("default"); + expect(defaultCanMangle).toBe(true); +}); + +it("should mangle when destructuring json", async () => { + const { obj: { + "arr": [ + { prop1: p1 = 0 } + ] + } } = data; + expect(p1).toBe(1); + + const values = []; + ({ + foo: values[0], + obj: { + ["a" + "r" + "r"]: { + length: values[1], + } + } + } = data); + expect(values[0]).toBe("foo"); + expect(values[1]).toBe(3); + + const generatedJson = __non_webpack_require__(path.resolve(__dirname, "data.json.js")); + expect(generatedJson).toEqual({ + "W": { + "arr": [ + { "prop1": 1, "prop2": 2 }, + { "prop3": 3, "prop4": 4 }, + { "prop5": 5, "prop6": 6 } + ] + }, + "p": "foo" + }); +}); + +it("should mangle when destructuring json 2", async () => { + const { prop1, prop2 } = data2.obj.arr[0]; + expect(prop1).toBe(1); + expect(prop2).toBe(2); + + const generatedJson = __non_webpack_require__(path.resolve(__dirname, "data.json_2.js")); + expect(generatedJson).toEqual({ + "W": { + "Q": [ + { "X": 1, "Q": 2 }, + ], + } + }); +}); diff --git a/test/configCases/mangle/mangle-with-destructuring-assignment/module.js b/test/configCases/mangle/mangle-with-destructuring-assignment/module.js new file mode 100644 index 00000000000..d3b887767ad --- /dev/null +++ b/test/configCases/mangle/mangle-with-destructuring-assignment/module.js @@ -0,0 +1,11 @@ +export const aaa = "aaa"; +export const aaaCanMangle = __webpack_exports_info__.aaa.canMangle; + +export const obj = { a: "a", b: "b" } +export const objCanMangle = __webpack_exports_info__.obj.canMangle; + +export const obj2 = { a: "a", b: "b" } +export const obj2CanMangle = __webpack_exports_info__.obj2.canMangle; + +export default "default"; +export const defaultCanMangle = __webpack_exports_info__.default.canMangle; diff --git a/test/configCases/mangle/mangle-with-destructuring-assignment/module2.js b/test/configCases/mangle/mangle-with-destructuring-assignment/module2.js new file mode 100644 index 00000000000..e6951b14093 --- /dev/null +++ b/test/configCases/mangle/mangle-with-destructuring-assignment/module2.js @@ -0,0 +1,2 @@ +export const aaa = "a"; +export const bbb = "b"; diff --git a/test/configCases/mangle/mangle-with-destructuring-assignment/module3.js b/test/configCases/mangle/mangle-with-destructuring-assignment/module3.js new file mode 100644 index 00000000000..e6951b14093 --- /dev/null +++ b/test/configCases/mangle/mangle-with-destructuring-assignment/module3.js @@ -0,0 +1,2 @@ +export const aaa = "a"; +export const bbb = "b"; diff --git a/test/configCases/mangle/mangle-with-destructuring-assignment/reexport.js b/test/configCases/mangle/mangle-with-destructuring-assignment/reexport.js new file mode 100644 index 00000000000..a5ab8d9c607 --- /dev/null +++ b/test/configCases/mangle/mangle-with-destructuring-assignment/reexport.js @@ -0,0 +1,6 @@ +export * as obj3 from "./module2" +export const obj3CanMangle = __webpack_exports_info__.obj3.canMangle; + +import * as reexport2 from "./reexport2?side-effects" +export const obj4 = { nested: reexport2 } +export const obj4CanMangle = __webpack_exports_info__.reexport2.canMangle; diff --git a/test/configCases/mangle/mangle-with-destructuring-assignment/reexport2.js b/test/configCases/mangle/mangle-with-destructuring-assignment/reexport2.js new file mode 100644 index 00000000000..da9c4eb705a --- /dev/null +++ b/test/configCases/mangle/mangle-with-destructuring-assignment/reexport2.js @@ -0,0 +1,2 @@ +export * as obj5 from "./module3" +export const obj5CanMangle = __webpack_exports_info__.obj5.canMangle; diff --git a/test/configCases/mangle/mangle-with-destructuring-assignment/webpack.config.js b/test/configCases/mangle/mangle-with-destructuring-assignment/webpack.config.js new file mode 100644 index 00000000000..99c0d30c815 --- /dev/null +++ b/test/configCases/mangle/mangle-with-destructuring-assignment/webpack.config.js @@ -0,0 +1,48 @@ +// const { getRuntimeKey } = require("../../../../lib/util/runtime"); + +/** @type {import("../../../../").Configuration} */ +module.exports = { + module: { + rules: [ + { + resourceQuery: /side-effects/, + sideEffects: true + } + ] + }, + optimization: { + mangleExports: true, + usedExports: true, + providedExports: true, + concatenateModules: false + }, + plugins: [ + function getJsonCodeGeneratedSource(compiler) { + compiler.hooks.compilation.tap( + getJsonCodeGeneratedSource.name, + compilation => { + compilation.hooks.processAssets.tap( + getJsonCodeGeneratedSource.name, + () => { + for (const module of compilation.modules) { + if (module.type === "json") { + const { sources } = compilation.codeGenerationResults.get( + module, + "main" + ); + const source = sources.get("javascript"); + const file = compilation.getAssetPath("[name].js", { + filename: `${module + .readableIdentifier(compilation.requestShortener) + .replace(/[?#]/g, "_")}.js` + }); + compilation.emitAsset(file, source); + } + } + } + ); + } + ); + } + ] +}; diff --git a/test/configCases/mangle/mangle-with-re-export-as-default/index.js b/test/configCases/mangle/mangle-with-re-export-as-default/index.js new file mode 100644 index 00000000000..3101663c81a --- /dev/null +++ b/test/configCases/mangle/mangle-with-re-export-as-default/index.js @@ -0,0 +1,6 @@ +import namespace from "./re-exports"; + +it("should mangle exports imported", () => { + const { foo } = namespace; + expect(foo).toBe('foo') +}); diff --git a/test/configCases/mangle/mangle-with-re-export-as-default/module.js b/test/configCases/mangle/mangle-with-re-export-as-default/module.js new file mode 100644 index 00000000000..3329a7d972f --- /dev/null +++ b/test/configCases/mangle/mangle-with-re-export-as-default/module.js @@ -0,0 +1 @@ +export const foo = 'foo'; diff --git a/test/configCases/mangle/mangle-with-re-export-as-default/re-exports.js b/test/configCases/mangle/mangle-with-re-export-as-default/re-exports.js new file mode 100644 index 00000000000..a29514f469b --- /dev/null +++ b/test/configCases/mangle/mangle-with-re-export-as-default/re-exports.js @@ -0,0 +1,3 @@ +import * as namespace from './module'; + +export { namespace as default }; diff --git a/test/configCases/mangle/mangle-with-re-export-as-default/webpack.config.js b/test/configCases/mangle/mangle-with-re-export-as-default/webpack.config.js new file mode 100644 index 00000000000..1826c4c6589 --- /dev/null +++ b/test/configCases/mangle/mangle-with-re-export-as-default/webpack.config.js @@ -0,0 +1,9 @@ +/** @type {import("../../../../").Configuration} */ +module.exports = { + optimization: { + mangleExports: true, + usedExports: true, + providedExports: true, + sideEffects: false // disable reexports optimization + } +}; diff --git a/test/configCases/module-name/different-issuers-for-same-module/loader-a.js b/test/configCases/module-name/different-issuers-for-same-module/loader-a.js index bd8581ca4a4..4e8352ee90e 100644 --- a/test/configCases/module-name/different-issuers-for-same-module/loader-a.js +++ b/test/configCases/module-name/different-issuers-for-same-module/loader-a.js @@ -1,3 +1,4 @@ -module.exports = function(src) { +/** @type {import("../../../../").LoaderDefinition} */ +module.exports = function (src) { return `module.exports = "loader-a" + module.id`; }; diff --git a/test/configCases/module-name/different-issuers-for-same-module/loader-b.js b/test/configCases/module-name/different-issuers-for-same-module/loader-b.js index 5365e2fd355..7fa193f020f 100644 --- a/test/configCases/module-name/different-issuers-for-same-module/loader-b.js +++ b/test/configCases/module-name/different-issuers-for-same-module/loader-b.js @@ -1,3 +1,4 @@ -module.exports = function(src) { +/** @type {import("../../../../").LoaderDefinition} */ +module.exports = function (src) { return `module.exports = "loader-b" + module.id`; }; diff --git a/test/configCases/module/externals/imported.js b/test/configCases/module/externals/imported.js new file mode 100644 index 00000000000..f0c663f58c6 --- /dev/null +++ b/test/configCases/module/externals/imported.js @@ -0,0 +1,3 @@ +import value from "./module"; + +export default value + 2; diff --git a/test/configCases/module/externals/index.js b/test/configCases/module/externals/index.js new file mode 100644 index 00000000000..ddf9dade569 --- /dev/null +++ b/test/configCases/module/externals/index.js @@ -0,0 +1,13 @@ +import imported from "./imported.mjs"; +import value from "./module"; +import { metaUrl } from "./meta"; +const localMetaUrl = import.meta.url; + +it("should allow to use externals in concatenated modules", () => { + expect(imported).toBe(42); + expect(value).toBe(40); +}); + +it("all bundled files should have same url, when parser.javascript.importMeta === false", () => { + expect(localMetaUrl).toBe(metaUrl) +}); diff --git a/test/configCases/module/externals/meta.js b/test/configCases/module/externals/meta.js new file mode 100644 index 00000000000..eb60388df50 --- /dev/null +++ b/test/configCases/module/externals/meta.js @@ -0,0 +1 @@ +export const metaUrl = import.meta.url; \ No newline at end of file diff --git a/test/configCases/module/externals/module.js b/test/configCases/module/externals/module.js new file mode 100644 index 00000000000..03c2e17df3f --- /dev/null +++ b/test/configCases/module/externals/module.js @@ -0,0 +1 @@ +export default 40; diff --git a/test/configCases/module/externals/test.config.js b/test/configCases/module/externals/test.config.js new file mode 100644 index 00000000000..23557e2a3c9 --- /dev/null +++ b/test/configCases/module/externals/test.config.js @@ -0,0 +1,5 @@ +module.exports = { + findBundle: function () { + return "./main.mjs"; + } +}; diff --git a/test/configCases/module/externals/webpack.config.js b/test/configCases/module/externals/webpack.config.js new file mode 100644 index 00000000000..78ad7d63d86 --- /dev/null +++ b/test/configCases/module/externals/webpack.config.js @@ -0,0 +1,30 @@ +/** @type {import("../../../../").Configuration} */ +module.exports = { + module: { + parser: { + javascript: { + importMeta: false + } + } + }, + entry: { + main: "./index.js", + imported: { + import: "./imported.js", + library: { + type: "module" + } + } + }, + target: "node14", + output: { + filename: "[name].mjs" + }, + externals: "./imported.mjs", + experiments: { + outputModule: true + }, + optimization: { + concatenateModules: true + } +}; diff --git a/test/configCases/module/runtime-chunk/test.config.js b/test/configCases/module/runtime-chunk/test.config.js index d46441fe453..59523928e81 100644 --- a/test/configCases/module/runtime-chunk/test.config.js +++ b/test/configCases/module/runtime-chunk/test.config.js @@ -1,5 +1,5 @@ module.exports = { findBundle: function () { - return ["./runtime.js", "./main.js"]; + return ["./runtime.mjs", "./main.mjs"]; } }; diff --git a/test/configCases/module/runtime-chunk/webpack.config.js b/test/configCases/module/runtime-chunk/webpack.config.js index 78978ef2048..b1bdf750f81 100644 --- a/test/configCases/module/runtime-chunk/webpack.config.js +++ b/test/configCases/module/runtime-chunk/webpack.config.js @@ -1,9 +1,9 @@ /** @type {import("../../../../").Configuration} */ module.exports = { output: { - filename: "[name].js" + filename: "[name].mjs" }, - target: "web", + target: ["web", "es2020"], experiments: { outputModule: true }, diff --git a/test/configCases/module/split-chunks/index.js b/test/configCases/module/split-chunks/index.js new file mode 100644 index 00000000000..d5753c14d6b --- /dev/null +++ b/test/configCases/module/split-chunks/index.js @@ -0,0 +1,16 @@ +import value from "./separate"; +import { test as t } from "external-self"; + +it("should compile", () => { + expect(value).toBe(42); +}); +it("should circular depend on itself external", () => { + expect(test()).toBe(42); + expect(t()).toBe(42); +}); + +function test() { + return 42; +} + +export { test }; diff --git a/test/configCases/module/split-chunks/separate.js b/test/configCases/module/split-chunks/separate.js new file mode 100644 index 00000000000..7a4e8a723a4 --- /dev/null +++ b/test/configCases/module/split-chunks/separate.js @@ -0,0 +1 @@ +export default 42; diff --git a/test/configCases/module/split-chunks/test.config.js b/test/configCases/module/split-chunks/test.config.js new file mode 100644 index 00000000000..b15222e4489 --- /dev/null +++ b/test/configCases/module/split-chunks/test.config.js @@ -0,0 +1,5 @@ +module.exports = { + findBundle: function () { + return ["./runtime.mjs", "./separate.mjs", "./main.mjs"]; + } +}; diff --git a/test/configCases/module/split-chunks/webpack.config.js b/test/configCases/module/split-chunks/webpack.config.js new file mode 100644 index 00000000000..e8a91725c45 --- /dev/null +++ b/test/configCases/module/split-chunks/webpack.config.js @@ -0,0 +1,30 @@ +/** @type {import("../../../../").Configuration} */ +module.exports = { + output: { + filename: "[name].mjs", + library: { + type: "module" + } + }, + target: ["web", "es2020"], + experiments: { + outputModule: true + }, + optimization: { + minimize: true, + runtimeChunk: "single", + splitChunks: { + cacheGroups: { + separate: { + test: /separate/, + chunks: "all", + filename: "separate.mjs", + enforce: true + } + } + } + }, + externals: { + "external-self": "./main.mjs" + } +}; diff --git a/test/configCases/node/node-prefix/index.js b/test/configCases/node/node-prefix/index.js new file mode 100644 index 00000000000..84aa3bd98fd --- /dev/null +++ b/test/configCases/node/node-prefix/index.js @@ -0,0 +1,8 @@ +import vm1 from "vm"; +import vm2 from "node:vm"; + +it("should allow importing node builtin modules with the node: prefix", () => { + expect(require("node:fs")).toBe(require("fs")); + expect(require("node:path")).toBe(require("path")); + expect(vm2).toBe(vm1); +}); diff --git a/test/configCases/node/node-prefix/webpack.config.js b/test/configCases/node/node-prefix/webpack.config.js new file mode 100644 index 00000000000..029181fbeba --- /dev/null +++ b/test/configCases/node/node-prefix/webpack.config.js @@ -0,0 +1,4 @@ +/** @type {import("../../../../").Configuration} */ +module.exports = { + target: "node" +}; diff --git a/test/configCases/node/prefix-in-runtime/index.js b/test/configCases/node/prefix-in-runtime/index.js new file mode 100644 index 00000000000..592ce5991ca --- /dev/null +++ b/test/configCases/node/prefix-in-runtime/index.js @@ -0,0 +1,16 @@ +import fs from "fs"; + +it(`should have/have not 'node:' prefix ${__filename}`, () => { + const content = fs.readFileSync(__filename, "utf-8"); + + if (/bundle7\.js$/.test(__filename)) { + expect(content).toContain("require(\"fs\");"); + } else if (/(bundle1\.mjs|bundle3\.mjs|bundle6\.mjs)$/.test(__filename)) { + expect(content).toContain("from \"url\""); + expect(content).toContain("from \"module\""); + } else { + expect(content).toContain("from \"node:url\""); + expect(content).toContain("from \"node:module\""); + } +}); + diff --git a/test/configCases/node/prefix-in-runtime/test.filter.js b/test/configCases/node/prefix-in-runtime/test.filter.js new file mode 100644 index 00000000000..ce19d8618ed --- /dev/null +++ b/test/configCases/node/prefix-in-runtime/test.filter.js @@ -0,0 +1,3 @@ +module.exports = function () { + return !process.version.startsWith("v10."); +}; diff --git a/test/configCases/node/prefix-in-runtime/webpack.config.js b/test/configCases/node/prefix-in-runtime/webpack.config.js new file mode 100644 index 00000000000..c7da21b83c8 --- /dev/null +++ b/test/configCases/node/prefix-in-runtime/webpack.config.js @@ -0,0 +1,76 @@ +/** @type {import("../../../../").Configuration} */ +module.exports = [ + { + target: "node", + experiments: { + outputModule: true + }, + output: { + module: true, + chunkFormat: "module" + } + }, + { + target: "node14.17", + experiments: { + outputModule: true + }, + output: { + module: true, + chunkFormat: "module" + } + }, + { + target: "node14.18", + experiments: { + outputModule: true + }, + output: { + module: true, + chunkFormat: "module" + } + }, + { + target: "node15", + experiments: { + outputModule: true + }, + output: { + module: true, + chunkFormat: "module" + } + }, + { + target: "node16", + experiments: { + outputModule: true + }, + output: { + module: true, + chunkFormat: "module" + } + }, + { + target: "browserslist:node 14.18.0, node 16.0.0", + experiments: { + outputModule: true + }, + output: { + module: true, + chunkFormat: "module" + } + }, + { + target: "browserslist:node 14.18.0, node 15.0.0, node 16.0.0", + experiments: { + outputModule: true + }, + output: { + module: true, + chunkFormat: "module" + } + }, + { + target: "node" + } +]; diff --git a/test/configCases/optimization/hashed-module-ids/warnings.js b/test/configCases/optimization/hashed-module-ids/warnings.js index 5d0640d1c37..70fefa270fb 100644 --- a/test/configCases/optimization/hashed-module-ids/warnings.js +++ b/test/configCases/optimization/hashed-module-ids/warnings.js @@ -1,3 +1 @@ -module.exports = [ - [/hashed/, /deprecated/] -]; +module.exports = [[/hashed/, /deprecated/]]; diff --git a/test/configCases/optimization/runtime-specific-used-exports/test.config.js b/test/configCases/optimization/runtime-specific-used-exports/test.config.js index 4754b6482e8..e4c1c3811ca 100644 --- a/test/configCases/optimization/runtime-specific-used-exports/test.config.js +++ b/test/configCases/optimization/runtime-specific-used-exports/test.config.js @@ -1,8 +1,5 @@ module.exports = { - findBundle: function() { - return [ - "./a.js", - "./b.js" - ]; + findBundle: function () { + return ["./a.js", "./b.js"]; } }; diff --git a/test/configCases/optimization/runtime-specific-used-exports2/test.config.js b/test/configCases/optimization/runtime-specific-used-exports2/test.config.js index c5938acd51c..6229990acc2 100644 --- a/test/configCases/optimization/runtime-specific-used-exports2/test.config.js +++ b/test/configCases/optimization/runtime-specific-used-exports2/test.config.js @@ -1,9 +1,5 @@ module.exports = { - findBundle: function() { - return [ - "./a.js", - "./b.js", - "./c.js" - ]; + findBundle: function () { + return ["./a.js", "./b.js", "./c.js"]; } }; diff --git a/test/configCases/output-module/check-defaults/errors.js b/test/configCases/output-module/check-defaults/errors.js new file mode 100644 index 00000000000..1d4e2ba0129 --- /dev/null +++ b/test/configCases/output-module/check-defaults/errors.js @@ -0,0 +1,3 @@ +module.exports = [ + [/For the selected environment is no default ESM chunk format available/] +]; diff --git a/test/configCases/output-module/check-defaults/index.js b/test/configCases/output-module/check-defaults/index.js new file mode 100644 index 00000000000..3cd08c4fc92 --- /dev/null +++ b/test/configCases/output-module/check-defaults/index.js @@ -0,0 +1,3 @@ +it("should compile and run", () => { + expect(import.meta.url).toBe(import.meta.url); +}); diff --git a/test/configCases/output-module/check-defaults/test.filter.js b/test/configCases/output-module/check-defaults/test.filter.js new file mode 100644 index 00000000000..d5852188b3e --- /dev/null +++ b/test/configCases/output-module/check-defaults/test.filter.js @@ -0,0 +1 @@ +module.exports = config => !config.cache; diff --git a/test/configCases/output-module/check-defaults/webpack.config.js b/test/configCases/output-module/check-defaults/webpack.config.js new file mode 100644 index 00000000000..d45f42ed855 --- /dev/null +++ b/test/configCases/output-module/check-defaults/webpack.config.js @@ -0,0 +1,17 @@ +/** @type {import("../../../../").Configuration[]} */ +module.exports = [ + { + experiments: { + outputModule: true + }, + devtool: false, + target: "web" + }, + { + experiments: { + outputModule: true + }, + devtool: false, + target: "node10" + } +]; diff --git a/test/configCases/output-module/inlined-module/index.js b/test/configCases/output-module/inlined-module/index.js new file mode 100644 index 00000000000..82d834eb333 --- /dev/null +++ b/test/configCases/output-module/inlined-module/index.js @@ -0,0 +1,20 @@ +import { value as v1 } from "./module1"; +const v2 = require("./module2") +const module3Inc = require("./module3") + +const index_value = 10; +let value = 42; + +function inc() { + value++; +} + +it("single inlined module should not be wrapped in IIFE", () => { + expect(value).toBe(42); + expect(v1).toBe(undefined); + expect(v2).toBe(undefined); + expect(module3Inc).toBe(undefined); + inc(); + expect(value).toBe(43); + expect(index_value).toBe(10); +}); diff --git a/test/configCases/output-module/inlined-module/module1.js b/test/configCases/output-module/inlined-module/module1.js new file mode 100644 index 00000000000..67ebbe022de --- /dev/null +++ b/test/configCases/output-module/inlined-module/module1.js @@ -0,0 +1,3 @@ +let value; + +export { value }; diff --git a/test/configCases/output-module/inlined-module/module2.js b/test/configCases/output-module/inlined-module/module2.js new file mode 100644 index 00000000000..3e533c777ea --- /dev/null +++ b/test/configCases/output-module/inlined-module/module2.js @@ -0,0 +1,3 @@ +let value + +module.exports = value diff --git a/test/configCases/output-module/inlined-module/module3.js b/test/configCases/output-module/inlined-module/module3.js new file mode 100644 index 00000000000..5b457b1be85 --- /dev/null +++ b/test/configCases/output-module/inlined-module/module3.js @@ -0,0 +1,3 @@ +let inc + +module.exports = inc diff --git a/test/configCases/output-module/inlined-module/webpack.config.js b/test/configCases/output-module/inlined-module/webpack.config.js new file mode 100644 index 00000000000..61f4abca976 --- /dev/null +++ b/test/configCases/output-module/inlined-module/webpack.config.js @@ -0,0 +1,13 @@ +/** @type {import("../../../../").Configuration} */ +module.exports = { + output: { + module: true + }, + optimization: { + concatenateModules: true + }, + experiments: { + outputModule: true + }, + target: "es2020" +}; diff --git a/test/configCases/output-module/issue-16040/bar.css b/test/configCases/output-module/issue-16040/bar.css new file mode 100644 index 00000000000..66d9575715c --- /dev/null +++ b/test/configCases/output-module/issue-16040/bar.css @@ -0,0 +1,3 @@ +.bar { + color: #fff; +} diff --git a/test/configCases/output-module/issue-16040/bar.js b/test/configCases/output-module/issue-16040/bar.js new file mode 100644 index 00000000000..cce1f49a437 --- /dev/null +++ b/test/configCases/output-module/issue-16040/bar.js @@ -0,0 +1,7 @@ +import { countBy } from "lodash-es"; + +import "./bar.css"; + +const result = countBy([6.1, 4.2, 6.3], Math.floor); + +export default result["6"]; diff --git a/test/configCases/output-module/issue-16040/foo.css b/test/configCases/output-module/issue-16040/foo.css new file mode 100644 index 00000000000..33a418a59a8 --- /dev/null +++ b/test/configCases/output-module/issue-16040/foo.css @@ -0,0 +1,3 @@ +.foo { + color: #fff; +} diff --git a/test/configCases/output-module/issue-16040/foo.js b/test/configCases/output-module/issue-16040/foo.js new file mode 100644 index 00000000000..dd96b964c76 --- /dev/null +++ b/test/configCases/output-module/issue-16040/foo.js @@ -0,0 +1,7 @@ +import { dropRight } from "lodash-es"; + +import "./foo.css"; + +const result = dropRight([10, 20, 30], 2); + +export default result[0]; diff --git a/test/configCases/output-module/issue-16040/index.js b/test/configCases/output-module/issue-16040/index.js new file mode 100644 index 00000000000..da656cdd0f0 --- /dev/null +++ b/test/configCases/output-module/issue-16040/index.js @@ -0,0 +1,14 @@ +import foo from "./foo.js"; +import bar from "./bar.js"; + +it("should not contain non javascript chunk in the main bundle", () => { + const fs = require("fs"); + const source = fs.readFileSync(__STATS__.outputPath + "/main.mjs", "utf-8"); + + expect(__STATS__.chunks.some(c => c.names.includes("style"))).toBe(true); + // Should not import "./style.mjs";` + expect(source).not.toMatch( + /import\s\*\sas+\s__webpack_chunk_[0-9]+__\sfrom\s"\.\/style\.mjs"/g + ); + expect(foo + bar).toBe(12); +}); diff --git a/test/configCases/output-module/issue-16040/test.config.js b/test/configCases/output-module/issue-16040/test.config.js new file mode 100644 index 00000000000..d8558101ac8 --- /dev/null +++ b/test/configCases/output-module/issue-16040/test.config.js @@ -0,0 +1,5 @@ +module.exports = { + findBundle: function (i, options) { + return ["main.mjs", "vendor.mjs", "runtime.mjs"]; + } +}; diff --git a/test/configCases/output-module/issue-16040/test.filter.js b/test/configCases/output-module/issue-16040/test.filter.js new file mode 100644 index 00000000000..0d61a0f0807 --- /dev/null +++ b/test/configCases/output-module/issue-16040/test.filter.js @@ -0,0 +1,3 @@ +const supportsRequireInModule = require("../../../helpers/supportsRequireInModule"); + +module.exports = () => supportsRequireInModule(); diff --git a/test/configCases/output-module/issue-16040/webpack.config.js b/test/configCases/output-module/issue-16040/webpack.config.js new file mode 100644 index 00000000000..275e36a5232 --- /dev/null +++ b/test/configCases/output-module/issue-16040/webpack.config.js @@ -0,0 +1,77 @@ +const MiniCssExtractPlugin = require("mini-css-extract-plugin"); + +module.exports = { + mode: "production", + devtool: false, + experiments: { + outputModule: true + }, + output: { + publicPath: "/", + filename: "[name].mjs", + chunkFilename: "[name].chunk.js", + assetModuleFilename: "[hash][ext][query]", + module: true, + libraryTarget: "module", + chunkFormat: "module", + chunkLoading: "import", + environment: { + dynamicImport: true, + module: true + } + }, + + module: { + rules: [ + { + test: /\.css$/i, + use: [MiniCssExtractPlugin.loader, "css-loader"] + } + ] + }, + + plugins: [ + new MiniCssExtractPlugin({ + filename: "style.css", + chunkFilename: "[id].css" + }) + ], + + optimization: { + splitChunks: { + chunks: "all", + + cacheGroups: { + style: { + name: "style", + type: "css/mini-extract", + chunks: "all", + enforce: true + }, + + defaultVendors: { + name: "vendor", + test: /[\\/]node_modules[\\/]/, + priority: -10, + chunks: "initial", + reuseExistingChunk: true + }, + + default: { + minChunks: 2, + priority: -20, + reuseExistingChunk: true + } + } + }, + + runtimeChunk: { + name: "runtime" + }, + + // currently Webpack has bugs when setting concatenateModules to true while produce ES Module output. + // concatenateModules: false, + + minimize: false + } +}; diff --git a/test/configCases/output-module/multiple-inlined-module/index-1.js b/test/configCases/output-module/multiple-inlined-module/index-1.js new file mode 100644 index 00000000000..6cdda011abf --- /dev/null +++ b/test/configCases/output-module/multiple-inlined-module/index-1.js @@ -0,0 +1,16 @@ +import { value as v1 } from "./module1"; +const v2 = require("./module2") + +var value = 42; + +function inc() { + value++; +} + + it("multiple inlined modules should be wrapped in IIFE to isolate from other inlined modules and chunk modules", () => { + expect(value).toBe(42); + expect(v1).toBe(undefined); + expect(v2).toBe(undefined); + inc(); + expect(value).toBe(43); +}); diff --git a/test/configCases/output-module/multiple-inlined-module/index-2.js b/test/configCases/output-module/multiple-inlined-module/index-2.js new file mode 100644 index 00000000000..25e8e80449a --- /dev/null +++ b/test/configCases/output-module/multiple-inlined-module/index-2.js @@ -0,0 +1 @@ +var value = 42; diff --git a/test/configCases/output-module/multiple-inlined-module/module1.js b/test/configCases/output-module/multiple-inlined-module/module1.js new file mode 100644 index 00000000000..67ebbe022de --- /dev/null +++ b/test/configCases/output-module/multiple-inlined-module/module1.js @@ -0,0 +1,3 @@ +let value; + +export { value }; diff --git a/test/configCases/output-module/multiple-inlined-module/module2.js b/test/configCases/output-module/multiple-inlined-module/module2.js new file mode 100644 index 00000000000..3e533c777ea --- /dev/null +++ b/test/configCases/output-module/multiple-inlined-module/module2.js @@ -0,0 +1,3 @@ +let value + +module.exports = value diff --git a/test/configCases/output-module/multiple-inlined-module/webpack.config.js b/test/configCases/output-module/multiple-inlined-module/webpack.config.js new file mode 100644 index 00000000000..031c304e231 --- /dev/null +++ b/test/configCases/output-module/multiple-inlined-module/webpack.config.js @@ -0,0 +1,14 @@ +/** @type {import("../../../../").Configuration} */ +module.exports = { + entry: ["./index-1.js", "./index-2.js"], + output: { + module: true + }, + optimization: { + concatenateModules: true + }, + experiments: { + outputModule: true + }, + target: "es2020" +}; diff --git a/test/configCases/output-module/node-globals/cjs/file.js b/test/configCases/output-module/node-globals/cjs/file.js new file mode 100644 index 00000000000..be625d98678 --- /dev/null +++ b/test/configCases/output-module/node-globals/cjs/file.js @@ -0,0 +1,6 @@ +const fileURLToPath = ""; +const file = __filename; +const dir = __dirname; +const dir2 = `${__dirname}/`; + +module.exports = { file, dir, dir2 }; diff --git a/test/configCases/output-module/node-globals/cjs/package.json b/test/configCases/output-module/node-globals/cjs/package.json new file mode 100644 index 00000000000..ea5acf78f52 --- /dev/null +++ b/test/configCases/output-module/node-globals/cjs/package.json @@ -0,0 +1,4 @@ +{ + "name": "cjs", + "type": "commonjs" +} diff --git a/test/configCases/output-module/node-globals/index.js b/test/configCases/output-module/node-globals/index.js new file mode 100644 index 00000000000..350b3ba69bd --- /dev/null +++ b/test/configCases/output-module/node-globals/index.js @@ -0,0 +1,10 @@ +import { dir, dir2, file } from './cjs/file.js' + +it("should generate correct __dirname", () => { + expect(dir).toMatch(/[\\/]node-globals$/); + expect(dir2).toMatch(/[\\/]node-globals\/$/); +}); + +it("should generate correct __filename", () => { + expect(file).toMatch(/[\\/]main.mjs$/); +}); diff --git a/test/configCases/output-module/node-globals/test.config.js b/test/configCases/output-module/node-globals/test.config.js new file mode 100644 index 00000000000..1192a7afc60 --- /dev/null +++ b/test/configCases/output-module/node-globals/test.config.js @@ -0,0 +1,5 @@ +module.exports = { + findBundle() { + return "./main.mjs"; + } +}; diff --git a/test/configCases/output-module/node-globals/webpack.config.js b/test/configCases/output-module/node-globals/webpack.config.js new file mode 100644 index 00000000000..aac123421e6 --- /dev/null +++ b/test/configCases/output-module/node-globals/webpack.config.js @@ -0,0 +1,14 @@ +/** @type {import("../../../../").Configuration} */ +module.exports = { + entry: { + main: "./index.js" + }, + output: { + filename: "[name].mjs", + module: true + }, + experiments: { + outputModule: true + }, + target: "node14" +}; diff --git a/test/configCases/output-module/non-webpack-require/baz.js b/test/configCases/output-module/non-webpack-require/baz.js new file mode 100644 index 00000000000..ab1913ce984 --- /dev/null +++ b/test/configCases/output-module/non-webpack-require/baz.js @@ -0,0 +1 @@ +export default "baz module text"; diff --git a/test/configCases/output-module/non-webpack-require/index.js b/test/configCases/output-module/non-webpack-require/index.js new file mode 100644 index 00000000000..79e36df4e9f --- /dev/null +++ b/test/configCases/output-module/non-webpack-require/index.js @@ -0,0 +1,16 @@ +import { createRequire as func_create_require, builtinModules as builtin } from "module"; +import external from "external-module"; +import externalOther from "external-other-module"; +import baz from "./baz.js"; + +it("should work with __non_webpack_require__ and ES modules", function () { + const foo = __non_webpack_require__("./mod.js"); + + expect(foo).toBe("module text"); + expect(external).toBe("external module text"); + expect(externalOther).toBe("external module text"); + expect(baz).toBe("baz module text"); + expect(typeof func_create_require).toBe("function"); + expect(func_create_require(import.meta.url)("./mod.js")).toBe("module text"); + expect(typeof builtin).toBe("object") +}); diff --git a/test/configCases/output-module/non-webpack-require/mod.js b/test/configCases/output-module/non-webpack-require/mod.js new file mode 100644 index 00000000000..af5c7eea34c --- /dev/null +++ b/test/configCases/output-module/non-webpack-require/mod.js @@ -0,0 +1 @@ +module.exports = "module text"; diff --git a/test/configCases/output-module/non-webpack-require/test.filter.js b/test/configCases/output-module/non-webpack-require/test.filter.js new file mode 100644 index 00000000000..0d61a0f0807 --- /dev/null +++ b/test/configCases/output-module/non-webpack-require/test.filter.js @@ -0,0 +1,3 @@ +const supportsRequireInModule = require("../../../helpers/supportsRequireInModule"); + +module.exports = () => supportsRequireInModule(); diff --git a/test/configCases/output-module/non-webpack-require/webpack.config.js b/test/configCases/output-module/non-webpack-require/webpack.config.js new file mode 100644 index 00000000000..44c26e1c34d --- /dev/null +++ b/test/configCases/output-module/non-webpack-require/webpack.config.js @@ -0,0 +1,58 @@ +var webpack = require("../../../../"); + +/** @type {import("../../../../").Configuration} */ +module.exports = { + target: ["node", "es2020"], + experiments: { + outputModule: true + }, + output: { + module: true, + iife: true + }, + externals: { + "external-module": "node-commonjs external-module", + "external-other-module": ["node-commonjs external-module"] + }, + optimization: { + concatenateModules: false + }, + plugins: [ + { + apply(compiler) { + compiler.hooks.compilation.tap("Test", compilation => { + compilation.hooks.processAssets.tap( + { + name: "copy-webpack-plugin", + stage: + compiler.webpack.Compilation.PROCESS_ASSETS_STAGE_ADDITIONAL + }, + () => { + compilation.emitAsset( + "mod.js", + new webpack.sources.RawSource( + "module.exports = 'module text';\n" + ) + ); + } + ); + compilation.hooks.processAssets.tap( + { + name: "copy-webpack-plugin", + stage: + compiler.webpack.Compilation.PROCESS_ASSETS_STAGE_ADDITIONAL + }, + () => { + compilation.emitAsset( + "node_modules/external-module/index.js", + new webpack.sources.RawSource( + "module.exports = 'external module text';\n" + ) + ); + } + ); + }); + } + } + ] +}; diff --git a/test/configCases/output-module/reuse-webpack-esm-library/index.js b/test/configCases/output-module/reuse-webpack-esm-library/index.js new file mode 100644 index 00000000000..d62ae0367e2 --- /dev/null +++ b/test/configCases/output-module/reuse-webpack-esm-library/index.js @@ -0,0 +1,5 @@ +import { useCall } from "./lib"; + +it("should compile and run", () => { + expect(useCall()).toBe(1); +}); diff --git a/test/configCases/output-module/reuse-webpack-esm-library/lib.js b/test/configCases/output-module/reuse-webpack-esm-library/lib.js new file mode 100644 index 00000000000..cfddc0c4eca --- /dev/null +++ b/test/configCases/output-module/reuse-webpack-esm-library/lib.js @@ -0,0 +1,95 @@ +import * as __WEBPACK_EXTERNAL_MODULE_react__ from "react"; +/******/ var __webpack_modules__ = ({ + + /***/ "react": + /*!************************!*\ + !*** external "react" ***! + \************************/ + /***/ ((module) => { + + var x = y => { var x = {}; __webpack_require__.d(x, y); return x; } + var y = x => () => x + module.exports = __WEBPACK_EXTERNAL_MODULE_react__; + + /***/ }) + + /******/ }); +/************************************************************************/ +/******/ // The module cache +/******/ var __webpack_module_cache__ = {}; +/******/ +/******/ // The require function +/******/ function __webpack_require__(moduleId) { + /******/ // Check if module is in cache + /******/ var cachedModule = __webpack_module_cache__[moduleId]; + /******/ if (cachedModule !== undefined) { + /******/ return cachedModule.exports; + /******/ } + /******/ // Create a new module (and put it into the cache) + /******/ var module = __webpack_module_cache__[moduleId] = { + /******/ // no module.id needed + /******/ // no module.loaded needed + /******/ exports: {} + /******/ }; + /******/ + /******/ // Execute the module function + /******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__); + /******/ + /******/ // Return the exports of the module + /******/ return module.exports; + /******/ } +/******/ +/************************************************************************/ +/******/ /* webpack/runtime/define property getters */ +/******/ (() => { + /******/ // define getter functions for harmony exports + /******/ __webpack_require__.d = (exports, definition) => { + /******/ for(var key in definition) { + /******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) { + /******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] }); + /******/ } + /******/ } + /******/ }; + /******/ })(); +/******/ +/******/ /* webpack/runtime/hasOwnProperty shorthand */ +/******/ (() => { + /******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop)) + /******/ })(); +/******/ +/******/ /* webpack/runtime/make namespace object */ +/******/ (() => { + /******/ // define __esModule on exports + /******/ __webpack_require__.r = (exports) => { + /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { + /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); + /******/ } + /******/ Object.defineProperty(exports, '__esModule', { value: true }); + /******/ }; + /******/ })(); +/******/ +/************************************************************************/ +var __webpack_exports__ = {}; +// This entry need to be wrapped in an IIFE because it need to be isolated against other modules in the chunk. +(() => { + /*!***************************!*\ + !*** ./src/store/call.ts ***! + \***************************/ + __webpack_require__.r(__webpack_exports__); + /* harmony export */ __webpack_require__.d(__webpack_exports__, { + /* harmony export */ useCall: () => (/* binding */ useCall), + /* harmony export */ withCallManager: () => (/* binding */ withCallManager) + /* harmony export */ }); + /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react */ "react"); + + function withCallManager() { + return react__WEBPACK_IMPORTED_MODULE_0__.createElement(1); + } + function useCall() { + return withCallManager(); + } +})(); + +var __webpack_exports__useCall = __webpack_exports__.useCall; +var __webpack_exports__withCallManager = __webpack_exports__.withCallManager; +export { __webpack_exports__useCall as useCall, __webpack_exports__withCallManager as withCallManager }; diff --git a/test/configCases/output-module/reuse-webpack-esm-library/react.js b/test/configCases/output-module/reuse-webpack-esm-library/react.js new file mode 100644 index 00000000000..10a7ad78896 --- /dev/null +++ b/test/configCases/output-module/reuse-webpack-esm-library/react.js @@ -0,0 +1 @@ +export function createElement(a) { return a; } diff --git a/test/configCases/output-module/reuse-webpack-esm-library/webpack.config.js b/test/configCases/output-module/reuse-webpack-esm-library/webpack.config.js new file mode 100644 index 00000000000..8d969d27bc5 --- /dev/null +++ b/test/configCases/output-module/reuse-webpack-esm-library/webpack.config.js @@ -0,0 +1,14 @@ +const path = require("path"); +/** @type {import("../../../../").Configuration} */ +module.exports = { + mode: "development", + devtool: "eval", + optimization: { + concatenateModules: false + }, + resolve: { + alias: { + react: path.resolve(__dirname, "react") + } + } +}; diff --git a/test/configCases/output-module/simple/chunk.js b/test/configCases/output-module/simple/chunk.js new file mode 100644 index 00000000000..7a4e8a723a4 --- /dev/null +++ b/test/configCases/output-module/simple/chunk.js @@ -0,0 +1 @@ +export default 42; diff --git a/test/configCases/output-module/simple/index.js b/test/configCases/output-module/simple/index.js new file mode 100644 index 00000000000..bdf68397f44 --- /dev/null +++ b/test/configCases/output-module/simple/index.js @@ -0,0 +1,12 @@ +it("should execute as module", () => { + expect( + (function () { + return !this; + })() + ).toBe(true); +}); + +it("should be able to load a chunk", async () => { + const module = await import("./chunk"); + expect(module.default).toBe(42); +}); diff --git a/test/configCases/output-module/simple/webpack.config.js b/test/configCases/output-module/simple/webpack.config.js new file mode 100644 index 00000000000..b8e5da8c1f1 --- /dev/null +++ b/test/configCases/output-module/simple/webpack.config.js @@ -0,0 +1,7 @@ +/** @type {import("../../../../").Configuration} */ +module.exports = { + experiments: { + outputModule: true + }, + target: "node14" +}; diff --git a/test/configCases/output/chunk-format-with-runtimeChunk/index.js b/test/configCases/output/chunk-format-with-runtimeChunk/index.js new file mode 100644 index 00000000000..0acee55e319 --- /dev/null +++ b/test/configCases/output/chunk-format-with-runtimeChunk/index.js @@ -0,0 +1,3 @@ +it("should compile and run", () => { + expect(true).toBe(true) +}); diff --git a/test/configCases/output/chunk-format-with-runtimeChunk/test.config.js b/test/configCases/output/chunk-format-with-runtimeChunk/test.config.js new file mode 100644 index 00000000000..a77372a9998 --- /dev/null +++ b/test/configCases/output/chunk-format-with-runtimeChunk/test.config.js @@ -0,0 +1,5 @@ +module.exports = { + findBundle: function () { + return ["runtime.mjs", "main.mjs"]; + } +}; diff --git a/test/configCases/output/chunk-format-with-runtimeChunk/webpack.config.js b/test/configCases/output/chunk-format-with-runtimeChunk/webpack.config.js new file mode 100644 index 00000000000..4779769a381 --- /dev/null +++ b/test/configCases/output/chunk-format-with-runtimeChunk/webpack.config.js @@ -0,0 +1,17 @@ +module.exports = { + mode: "production", + entry: { + main: "./index.js" + }, + optimization: { + runtimeChunk: "single" + }, + output: { + filename: "[name].mjs", + module: true, + chunkFormat: "module" + }, + experiments: { + outputModule: true + } +}; diff --git a/test/configCases/output/function/test.config.js b/test/configCases/output/function/test.config.js index 4754b6482e8..e4c1c3811ca 100644 --- a/test/configCases/output/function/test.config.js +++ b/test/configCases/output/function/test.config.js @@ -1,8 +1,5 @@ module.exports = { - findBundle: function() { - return [ - "./a.js", - "./b.js" - ]; + findBundle: function () { + return ["./a.js", "./b.js"]; } }; diff --git a/test/configCases/output/function/webpack.config.js b/test/configCases/output/function/webpack.config.js index 85fe19d42ec..f08da2f1ae3 100644 --- a/test/configCases/output/function/webpack.config.js +++ b/test/configCases/output/function/webpack.config.js @@ -7,8 +7,7 @@ module.exports = { }; }, output: { - filename: data => { - return data.chunk.name === "a" ? `${data.chunk.name}.js` : "[name].js"; - } + filename: data => + data.chunk.name === "a" ? `${data.chunk.name}.js` : "[name].js" } }; diff --git a/test/configCases/output/import-meta-name/a.js b/test/configCases/output/import-meta-name/a.js new file mode 100644 index 00000000000..bdeb009362b --- /dev/null +++ b/test/configCases/output/import-meta-name/a.js @@ -0,0 +1 @@ +export const url = import.meta.url; diff --git a/test/configCases/output/import-meta-name/index.js b/test/configCases/output/import-meta-name/index.js new file mode 100644 index 00000000000..347bb1f5575 --- /dev/null +++ b/test/configCases/output/import-meta-name/index.js @@ -0,0 +1,9 @@ +import { url } from "./a"; + +it("should evaluate import.meta to pseudoImport.meta", () => { + expect(url).toBe("http://test.co/path/index.js"); +}); + +it("should evaluate import.meta in runtime", () => { + expect(url).toBe(import.meta.url); +}); diff --git a/test/configCases/output/import-meta-name/test.config.js b/test/configCases/output/import-meta-name/test.config.js new file mode 100644 index 00000000000..3b7d7089653 --- /dev/null +++ b/test/configCases/output/import-meta-name/test.config.js @@ -0,0 +1,5 @@ +module.exports = { + moduleScope(scope) { + scope.pseudoImport = { meta: { url: "http://test.co/path/index.js" } }; + } +}; diff --git a/test/configCases/output/import-meta-name/webpack.config.js b/test/configCases/output/import-meta-name/webpack.config.js new file mode 100644 index 00000000000..5d9667ad4f5 --- /dev/null +++ b/test/configCases/output/import-meta-name/webpack.config.js @@ -0,0 +1,13 @@ +/** @type {import("../../../../").Configuration} */ +module.exports = { + output: { + importMetaName: "pseudoImport.meta" + }, + module: { + parser: { + javascript: { + importMeta: false + } + } + } +}; diff --git a/test/configCases/output/inner-dirs-entries/test.config.js b/test/configCases/output/inner-dirs-entries/test.config.js index 6824904224c..59e45ecc267 100644 --- a/test/configCases/output/inner-dirs-entries/test.config.js +++ b/test/configCases/output/inner-dirs-entries/test.config.js @@ -1,5 +1,5 @@ module.exports = { - findBundle: function() { + findBundle: function () { return ["./a.js", "./inner-dir/b.js", "./inner-dir/deep/deep/c.js"]; } }; diff --git a/test/configCases/output/publicPath-scriptType-module/test.config.js b/test/configCases/output/publicPath-scriptType-module/test.config.js index 1a9ba98e443..c57155f16d0 100644 --- a/test/configCases/output/publicPath-scriptType-module/test.config.js +++ b/test/configCases/output/publicPath-scriptType-module/test.config.js @@ -1,8 +1,6 @@ module.exports = { - findBundle: function() { - return [ - "./index.mjs" - ]; + findBundle: function () { + return ["./index.mjs"]; }, moduleScope(scope) { scope.pseudoImport = { meta: { url: "http://test.co/path/index.js" } }; diff --git a/test/configCases/output/publicPath-web/c.js b/test/configCases/output/publicPath-web/c.js new file mode 100644 index 00000000000..d5f008e717d --- /dev/null +++ b/test/configCases/output/publicPath-web/c.js @@ -0,0 +1,5 @@ +import asset from "./asset.jpg"; + +it("should define public path", () => { + expect(asset).toBe("/other/inner1/inner2/../../asset.jpg"); +}); diff --git a/test/configCases/output/publicPath-web/d.js b/test/configCases/output/publicPath-web/d.js new file mode 100644 index 00000000000..1dc151ff189 --- /dev/null +++ b/test/configCases/output/publicPath-web/d.js @@ -0,0 +1,5 @@ +import asset from "./asset.jpg"; + +it("should define public path", () => { + expect(asset).toBe("/other/asset.jpg"); +}); diff --git a/test/configCases/output/publicPath-web/test.config.js b/test/configCases/output/publicPath-web/test.config.js index 53ecdb9cc9b..a5024d58671 100644 --- a/test/configCases/output/publicPath-web/test.config.js +++ b/test/configCases/output/publicPath-web/test.config.js @@ -1,8 +1,5 @@ module.exports = { - findBundle: function() { - return [ - "./inner1/inner2/a.js", - "./b.js" - ]; + findBundle: function () { + return ["./inner1/inner2/a.js", "./b.js"]; } }; diff --git a/test/configCases/output/publicPath-web/webpack.config.js b/test/configCases/output/publicPath-web/webpack.config.js index cdca87ddc8b..19629dedf8e 100644 --- a/test/configCases/output/publicPath-web/webpack.config.js +++ b/test/configCases/output/publicPath-web/webpack.config.js @@ -5,13 +5,20 @@ module.exports = { entry() { return { a: "./a", - b: "./b" + b: "./b", + c: { + import: "./c", + publicPath: "/other/" + }, + d: { + import: "./d", + publicPath: "/other/" + } }; }, output: { - filename: data => { - return data.chunk.name === "a" ? `inner1/inner2/[name].js` : "[name].js"; - }, + filename: data => + /^[ac]$/.test(data.chunk.name) ? "inner1/inner2/[name].js" : "[name].js", assetModuleFilename: "[name][ext]" }, module: { diff --git a/test/configCases/output/string/test.config.js b/test/configCases/output/string/test.config.js index 9af369705a3..30495784d0b 100644 --- a/test/configCases/output/string/test.config.js +++ b/test/configCases/output/string/test.config.js @@ -1,7 +1,5 @@ module.exports = { - findBundle: function() { - return [ - "./a.js" - ]; + findBundle: function () { + return ["./a.js"]; } }; diff --git a/test/configCases/output/worker-public-path/index.js b/test/configCases/output/worker-public-path/index.js new file mode 100644 index 00000000000..fa82f46bc29 --- /dev/null +++ b/test/configCases/output/worker-public-path/index.js @@ -0,0 +1,14 @@ +import { Worker } from "worker_threads"; + +it("should define public path", async () => { + const worker = new Worker(new URL("./worker.js", import.meta.url), { + type: "module" + }); + worker.postMessage("ok"); + + var fs = require("fs"), + path = require("path"); + var source = fs.readFileSync(path.join(__dirname, "main.js"), "utf-8"); + expect(source).toMatch("workerPublicPath2"); + await worker.terminate() +}); diff --git a/test/configCases/output/worker-public-path/test.config.js b/test/configCases/output/worker-public-path/test.config.js new file mode 100644 index 00000000000..392ac81b455 --- /dev/null +++ b/test/configCases/output/worker-public-path/test.config.js @@ -0,0 +1,5 @@ +module.exports = { + findBundle: function () { + return ["./main.js"]; + } +}; diff --git a/test/configCases/output/worker-public-path/test.filter.js b/test/configCases/output/worker-public-path/test.filter.js new file mode 100644 index 00000000000..7039623344e --- /dev/null +++ b/test/configCases/output/worker-public-path/test.filter.js @@ -0,0 +1,5 @@ +var supportsWorker = require("../../../helpers/supportsWorker"); + +module.exports = function (config) { + return supportsWorker(); +}; diff --git a/test/configCases/output/worker-public-path/webpack.config.js b/test/configCases/output/worker-public-path/webpack.config.js new file mode 100644 index 00000000000..a141441d354 --- /dev/null +++ b/test/configCases/output/worker-public-path/webpack.config.js @@ -0,0 +1,13 @@ +/** @type {import("../../../../").Configuration} */ +module.exports = { + mode: "none", + target: "node", + node: { + __dirname: false, + __filename: false + }, + output: { + filename: "[name].js", + workerPublicPath: "/workerPublicPath2/" + } +}; diff --git a/test/configCases/output/worker-public-path/worker.js b/test/configCases/output/worker-public-path/worker.js new file mode 100644 index 00000000000..939319f6379 --- /dev/null +++ b/test/configCases/output/worker-public-path/worker.js @@ -0,0 +1,6 @@ +function upper(str) { + return str.toUpperCase(); +} +onmessage = async event => { + postMessage(`data: ${upper(event.data)}, thanks`); +}; diff --git a/test/configCases/parsing/context/infrastructure-log.js b/test/configCases/parsing/context/infrastructure-log.js new file mode 100644 index 00000000000..e458f85280b --- /dev/null +++ b/test/configCases/parsing/context/infrastructure-log.js @@ -0,0 +1,3 @@ +module.exports = [ + /^Pack got invalid because of write to: Compilation\/modules|.+dump-file\.txt/ +]; diff --git a/test/configCases/parsing/issue-14545/index.js b/test/configCases/parsing/issue-14545/index.js new file mode 100644 index 00000000000..afaf9c0ba3e --- /dev/null +++ b/test/configCases/parsing/issue-14545/index.js @@ -0,0 +1,4 @@ +it("should generate valid code when 'require' encounters object shorthand syntax", function() { + expect(require("./module").obj.require).toEqual(require("./module").obj.r); + expect(require("./module").obj.require).toBeTypeOf("function"); +}); diff --git a/test/configCases/parsing/issue-14545/module.js b/test/configCases/parsing/issue-14545/module.js new file mode 100644 index 00000000000..0b7649cbf29 --- /dev/null +++ b/test/configCases/parsing/issue-14545/module.js @@ -0,0 +1 @@ +export const obj = {require, r: require} diff --git a/test/configCases/parsing/issue-14545/webpack.config.js b/test/configCases/parsing/issue-14545/webpack.config.js new file mode 100644 index 00000000000..91e80ba3b53 --- /dev/null +++ b/test/configCases/parsing/issue-14545/webpack.config.js @@ -0,0 +1,9 @@ +/** @type {import("../../../../").Configuration} */ +module.exports = { + module: { + unknownContextRegExp: /^\.\//, + unknownContextCritical: false, + exprContextRegExp: /^\.\//, + exprContextCritical: false + } +}; diff --git a/test/configCases/parsing/issue-14720/index.js b/test/configCases/parsing/issue-14720/index.js new file mode 100644 index 00000000000..0445694f69d --- /dev/null +++ b/test/configCases/parsing/issue-14720/index.js @@ -0,0 +1,7 @@ +it("should generate a chunk for a full require dependencies in require.ensure", done => { + require.ensure([], () => { + expect(require("./module").property).toBe(42); + expect(__STATS__.chunks.length).toBe(2); + done(); + }); +}); diff --git a/test/configCases/parsing/issue-14720/module.js b/test/configCases/parsing/issue-14720/module.js new file mode 100644 index 00000000000..5999374264e --- /dev/null +++ b/test/configCases/parsing/issue-14720/module.js @@ -0,0 +1 @@ +exports.property = 42; diff --git a/test/configCases/parsing/issue-14720/webpack.config.js b/test/configCases/parsing/issue-14720/webpack.config.js new file mode 100644 index 00000000000..dffc81bba10 --- /dev/null +++ b/test/configCases/parsing/issue-14720/webpack.config.js @@ -0,0 +1,4 @@ +/** @type {import("../../../../").Configuration} */ +module.exports = { + mode: "production" +}; diff --git a/test/configCases/parsing/issue-2942/warnings.js b/test/configCases/parsing/issue-2942/warnings.js index 217c81ed03a..b9d04875279 100644 --- a/test/configCases/parsing/issue-2942/warnings.js +++ b/test/configCases/parsing/issue-2942/warnings.js @@ -1,5 +1,5 @@ module.exports = [ [/System.register is not supported by webpack/], [/System.get is not supported by webpack/], - [/System.set is not supported by webpack/], + [/System.set is not supported by webpack/] ]; diff --git a/test/configCases/parsing/issue-9042/test.config.js b/test/configCases/parsing/issue-9042/test.config.js index 1266625deb9..59765f30dfd 100644 --- a/test/configCases/parsing/issue-9042/test.config.js +++ b/test/configCases/parsing/issue-9042/test.config.js @@ -1,5 +1,5 @@ module.exports = { - moduleScope: function(scope) { + moduleScope: function (scope) { delete scope.__dirname; delete scope.__filename; } diff --git a/test/configCases/parsing/node-stuff-plugin-off/test.config.js b/test/configCases/parsing/node-stuff-plugin-off/test.config.js index 1266625deb9..59765f30dfd 100644 --- a/test/configCases/parsing/node-stuff-plugin-off/test.config.js +++ b/test/configCases/parsing/node-stuff-plugin-off/test.config.js @@ -1,5 +1,5 @@ module.exports = { - moduleScope: function(scope) { + moduleScope: function (scope) { delete scope.__dirname; delete scope.__filename; } diff --git a/test/configCases/parsing/optional/index.js b/test/configCases/parsing/optional/index.js new file mode 100644 index 00000000000..cca013cc054 --- /dev/null +++ b/test/configCases/parsing/optional/index.js @@ -0,0 +1,11 @@ +it("should not fail for optional modules with bail", () => { + let error; + try { + require("./not-existing"); + } catch (e) { + error = e; + } + expect(() => { + throw error; + }).toThrowError(); +}); diff --git a/test/configCases/parsing/optional/warnings.js b/test/configCases/parsing/optional/warnings.js new file mode 100644 index 00000000000..e011edaca23 --- /dev/null +++ b/test/configCases/parsing/optional/warnings.js @@ -0,0 +1,7 @@ +module.exports = [ + [ + /Module not found/, + /Can't resolve '\.\/not-existing' /, + { details: /not-existing\.js/ } + ] +]; diff --git a/test/configCases/parsing/optional/webpack.config.js b/test/configCases/parsing/optional/webpack.config.js new file mode 100644 index 00000000000..61694bc0914 --- /dev/null +++ b/test/configCases/parsing/optional/webpack.config.js @@ -0,0 +1,4 @@ +/** @type {import("../../../../").Configuration} */ +module.exports = { + bail: true +}; diff --git a/test/configCases/parsing/override-strict/non-strict.js b/test/configCases/parsing/override-strict/non-strict.js new file mode 100644 index 00000000000..f8d75f943c1 --- /dev/null +++ b/test/configCases/parsing/override-strict/non-strict.js @@ -0,0 +1,2 @@ +var a = 1; +a.toString(); diff --git a/test/configCases/parsing/override-strict/strict.js b/test/configCases/parsing/override-strict/strict.js new file mode 100644 index 00000000000..01ca5ac8008 --- /dev/null +++ b/test/configCases/parsing/override-strict/strict.js @@ -0,0 +1,8 @@ +import "./non-strict" +import fs from "fs"; + +it("should not have iife for entry module when modules strict is different", () => { + const code = fs.readFileSync(__filename, 'utf-8'); + const iifeComment = ["This entry need to be wrapped in an IIFE", "because it need to be in strict mode."].join(' '); + expect(code).not.toMatch(iifeComment); +}); diff --git a/test/configCases/parsing/override-strict/webpack.config.js b/test/configCases/parsing/override-strict/webpack.config.js new file mode 100644 index 00000000000..d92a10890a5 --- /dev/null +++ b/test/configCases/parsing/override-strict/webpack.config.js @@ -0,0 +1,25 @@ +/** @type {import("../../../../").Configuration} */ +module.exports = [ + { + mode: "production", + entry: ["./strict"], + module: { + parser: { + javascript: { + overrideStrict: "strict" + } + } + } + }, + { + mode: "production", + entry: ["./strict"], + module: { + parser: { + javascript: { + overrideStrict: "non-strict" + } + } + } + } +]; diff --git a/test/configCases/parsing/requirejs/index.js b/test/configCases/parsing/requirejs/index.js index b032e27d81e..6d38fad8e66 100644 --- a/test/configCases/parsing/requirejs/index.js +++ b/test/configCases/parsing/requirejs/index.js @@ -9,12 +9,12 @@ it("should ignore require.config", function() { it("should have a require.version", function() { expect(require.version).toBeTypeOf("string"); }); -it("should have a requirejs.onError function", function() { +it("should have a requirejs.onError function", function(done) { function f(){} expect(requirejs.onError).toBeTypeOf("undefined"); // has no default handler var org = requirejs.onError; requirejs.onError = f; expect(requirejs.onError).toBe(f); requirejs.onError = org; - require(["./file.js"], function() {}); + require(["./file.js"], function() { done() }); }); diff --git a/test/configCases/parsing/url-ignore/file2.css b/test/configCases/parsing/url-ignore/file2.css new file mode 100644 index 00000000000..195b6bcf6d2 --- /dev/null +++ b/test/configCases/parsing/url-ignore/file2.css @@ -0,0 +1,3 @@ +a { + color: red; +} diff --git a/test/configCases/parsing/url-ignore/file4.css b/test/configCases/parsing/url-ignore/file4.css new file mode 100644 index 00000000000..195b6bcf6d2 --- /dev/null +++ b/test/configCases/parsing/url-ignore/file4.css @@ -0,0 +1,3 @@ +a { + color: red; +} diff --git a/test/configCases/parsing/url-ignore/index.js b/test/configCases/parsing/url-ignore/index.js new file mode 100644 index 00000000000..9c23e948bfc --- /dev/null +++ b/test/configCases/parsing/url-ignore/index.js @@ -0,0 +1,27 @@ +it("should ignore", function() { + const url = new URL(/* webpackIgnore: true */ "file1.css", import.meta.url); + expect(url.pathname.endsWith("file1.css")).toBe(true); + expect(url.pathname.includes("/public/")).toBe(false); + const url2 = new URL(/* webpackIgnore: false */ "file2.css", import.meta.url); + expect(/\/public\/.+\.css/.test(url2.pathname)).toBe(true); + const url3 = new URL(/* webpackIgnore: true */ "fil" + "e3.css", import.meta.url); + expect(url3.pathname.endsWith("file3.css")).toBe(true); + const url4 = new URL(/* webpackIgnore: false */ "fil" + "e4.css", import.meta.url); + expect(/\/public\/.+\.css/.test(url4.pathname)).toBe(true); + const url5 = new URL(/* webpackIgnore: "test" */ "file5.css", import.meta.url); + expect(url5.pathname.endsWith("file5.css")).toBe(true); + const value = "file5.css"; + const url6 = new URL(/* webpackIgnore: true */ "/dir/" + value, import.meta.url); + expect(url6.pathname.endsWith("file5.css")).toBe(true); + const args = ["file3.css", document.baseURI || self.location.href]; + const url7 = new URL(...args); + expect(url7.pathname.endsWith("file3.css")).toBe(true); + const url8 = new URL(document.baseURI || self.location.href); + expect(url8.toString()).toBe(document.baseURI || self.location.href); + const url9 = new URL(self.location.href); + expect(url9.toString()).toBe(self.location.href); + const url10 = new URL(/* webpackIgnore: true */ self.location.href); + expect(url10.toString()).toBe(self.location.href); + const url11 = new URL(/* webpackIgnore: true */ ...args); + expect(url11.pathname.endsWith("file3.css")).toBe(true); +}); diff --git a/test/configCases/parsing/url-ignore/warnings.js b/test/configCases/parsing/url-ignore/warnings.js new file mode 100644 index 00000000000..3e31c655be4 --- /dev/null +++ b/test/configCases/parsing/url-ignore/warnings.js @@ -0,0 +1 @@ +module.exports = [/`webpackIgnore` expected a boolean, but received: test./]; diff --git a/test/configCases/parsing/url-ignore/webpack.config.js b/test/configCases/parsing/url-ignore/webpack.config.js new file mode 100644 index 00000000000..9787b026dbc --- /dev/null +++ b/test/configCases/parsing/url-ignore/webpack.config.js @@ -0,0 +1,10 @@ +/** @type {import("../../../../").Configuration} */ +module.exports = { + output: { + publicPath: "/public/" + }, + experiments: { + outputModule: true + }, + target: ["web", "es2020"] +}; diff --git a/test/configCases/performance/many-async-imports/reexport.loader.js b/test/configCases/performance/many-async-imports/reexport.loader.js index f44ceced67a..3105e517fef 100644 --- a/test/configCases/performance/many-async-imports/reexport.loader.js +++ b/test/configCases/performance/many-async-imports/reexport.loader.js @@ -1,7 +1,8 @@ -module.exports = function() { +/** @type {import("../../../../").LoaderDefinition} */ +module.exports = function () { var str = "export default Promise.all([\n"; - for(var i = 0; i < 6; i++) { - for(var j = 0; j < 2; j++) { + for (var i = 0; i < 6; i++) { + for (var j = 0; j < 2; j++) { str += `import("./reexport.loader.js!?${i}"),\n`; } } diff --git a/test/configCases/performance/many-async-imports/test.filter.js b/test/configCases/performance/many-async-imports/test.filter.js index 8b7e505b1bf..a93cad202cd 100644 --- a/test/configCases/performance/many-async-imports/test.filter.js +++ b/test/configCases/performance/many-async-imports/test.filter.js @@ -1,3 +1,3 @@ -module.exports = function(config) { +module.exports = function (config) { return !/^v(4|6)/.test(process.version); }; diff --git a/test/configCases/performance/many-exports/file.loader.js b/test/configCases/performance/many-exports/file.loader.js index 6ec2268c91d..1dd13c65f5c 100644 --- a/test/configCases/performance/many-exports/file.loader.js +++ b/test/configCases/performance/many-exports/file.loader.js @@ -1,7 +1,8 @@ -module.exports = function() { +/** @type {import("../../../../").LoaderDefinition} */ +module.exports = function () { var str = ""; - for(var i = 0; i < 1000; i++) { + for (var i = 0; i < 1000; i++) { str += `export var a${i} = ${i};\n`; } return str; -} +}; diff --git a/test/configCases/performance/many-exports/reexport.loader.js b/test/configCases/performance/many-exports/reexport.loader.js index af755e8686a..e4a2a31352a 100644 --- a/test/configCases/performance/many-exports/reexport.loader.js +++ b/test/configCases/performance/many-exports/reexport.loader.js @@ -1,9 +1,10 @@ -module.exports = function() { - var str = "import * as i from \"./file.loader.js!\";\n"; +/** @type {import("../../../../").LoaderDefinition} */ +module.exports = function () { + var str = 'import * as i from "./file.loader.js!";\n'; str += "var sum = 0;\n"; - for(var i = 0; i < 1000; i++) { + for (var i = 0; i < 1000; i++) { str += `sum += i.a${i};\n`; } str += "export default sum;\n"; return str; -} +}; diff --git a/test/configCases/performance/many-exports/test.filter.js b/test/configCases/performance/many-exports/test.filter.js index 8b7e505b1bf..a93cad202cd 100644 --- a/test/configCases/performance/many-exports/test.filter.js +++ b/test/configCases/performance/many-exports/test.filter.js @@ -1,3 +1,3 @@ -module.exports = function(config) { +module.exports = function (config) { return !/^v(4|6)/.test(process.version); }; diff --git a/test/configCases/plugins/banner-plugin-hashing/test.config.js b/test/configCases/plugins/banner-plugin-hashing/test.config.js index 2d283508eea..19476fadffb 100644 --- a/test/configCases/plugins/banner-plugin-hashing/test.config.js +++ b/test/configCases/plugins/banner-plugin-hashing/test.config.js @@ -1,7 +1,5 @@ -var fs = require("fs"); - module.exports = { - findBundle: function(i, options) { + findBundle: function (i, options) { return "./dist/banner.js"; } }; diff --git a/test/configCases/plugins/banner-plugin/index.js b/test/configCases/plugins/banner-plugin/index.js index 69d83ba559a..e25486c1af1 100644 --- a/test/configCases/plugins/banner-plugin/index.js +++ b/test/configCases/plugins/banner-plugin/index.js @@ -13,11 +13,15 @@ it("should contain banner in bundle0 chunk", () => { expect(source).toMatch( "/*!\n * trim trailing whitespace\n *\n * no trailing whitespace\n */" ); + expect(source).not.toMatch(new RegExp("^/*! A test value in single file */$")); + expect(source).not.toMatch(new RegExp("^/*! Match test file */$")); }); it("should not contain banner in vendors chunk", () => { const source = fs.readFileSync(path.join(__dirname, "vendors.js"), "utf-8"); - expect(source).not.toMatch("A test value"); + expect(source).not.toMatch("/*! A test value */"); + expect(source).toMatch("/*! A test value in single file */"); + expect(source).toMatch("/*! Match test file */"); }); if (Math.random() < 0) require("./test.js"); diff --git a/test/configCases/plugins/banner-plugin/webpack.config.js b/test/configCases/plugins/banner-plugin/webpack.config.js index ced05eea136..db79e3b1d9c 100644 --- a/test/configCases/plugins/banner-plugin/webpack.config.js +++ b/test/configCases/plugins/banner-plugin/webpack.config.js @@ -19,6 +19,14 @@ module.exports = { banner: "A test value", exclude: ["vendors.js"] }), + new webpack.BannerPlugin({ + banner: "A test value in single file", + include: ["vendors.js"] + }), + new webpack.BannerPlugin({ + banner: "Match test file", + test: /vendors\.js$/ + }), new webpack.BannerPlugin({ banner: ({ chunk }) => `multiline\nbanner\n${chunk.name}` }), diff --git a/test/configCases/plugins/define-plugin/index.js b/test/configCases/plugins/define-plugin/index.js index e3cde299308..33282fba0f8 100644 --- a/test/configCases/plugins/define-plugin/index.js +++ b/test/configCases/plugins/define-plugin/index.js @@ -248,3 +248,50 @@ it("should expand properly", function() { expect(require("./dir/" + (tmp + A_DOT_J + tmp) + "s")).toBe(a); expect(require("./dir/" + (tmp + A_DOT_J) + tmp + "s")).toBe(a); }); + +it("destructuring assignment", () => { + const {used} = OBJECT2; + const {['used']: used2, used: used3} = OBJECT2.sub; + expect(used).toBe(used2); + expect(used).toBe(used3); +}); + +it('should allow shorthand property (issue #16764)', () => { + const simple = { ONE, TRUE, NULL, STRING, BIGINT, NEGATIVE_NUMBER }; + expect(simple).toStrictEqual({ + ONE: 1, + TRUE: true, + NULL: null, + STRING: "string", + BIGINT: BigInt("9007199254740993"), + NEGATIVE_NUMBER: -100.25 + }) + + const func = { FUNCTION }; + expect(func.FUNCTION(3)).toBe(4); + expect(typeof func.FUNCTION).toBe("function"); + + const code = { CODE }; + expect(code.CODE).toBe(3); + expect(typeof code.CODE).toBe("number"); + + + const regex = { REGEXP }; + expect(regex.REGEXP.toString()).toBe("/abc/i"); + expect(typeof regex.REGEXP).toBe("object"); + + const nested = { OBJECT } + expect(nested.OBJECT.SUB.FUNCTION(7)).toBe(8); + expect(nested.OBJECT.SUB.CODE).toBe(3); + expect(nested.OBJECT.SUB.UNDEFINED).toBeUndefined(); + expect(nested.OBJECT.SUB.REGEXP.toString()).toBe("/abc/i"); + expect(nested.OBJECT.SUB.STRING).toBe("string"); + + + const array = { ARRAY } + expect(array).toStrictEqual({ ARRAY: [2, ['six']] }) +}) + +it("fails for unknown property", () => { + expect(() => ({ UNKNOWN })).toThrowError("UNKNOWN is not defined") +}) \ No newline at end of file diff --git a/test/configCases/plugins/define-plugin/webpack.config.js b/test/configCases/plugins/define-plugin/webpack.config.js index 4f202b594c6..12810899a97 100644 --- a/test/configCases/plugins/define-plugin/webpack.config.js +++ b/test/configCases/plugins/define-plugin/webpack.config.js @@ -47,7 +47,15 @@ module.exports = { return module instanceof Module; } ), - A_DOT_J: '"a.j"' + A_DOT_J: '"a.j"', + OBJECT2: { + used: 1, + unused: "(() => throw new Error('unused property was rendered'))()", + sub: { + used: 1, + unused: "(() => throw new Error('unused property was rendered'))()" + } + } }) ] }; diff --git a/test/configCases/plugins/environment-plugin/errors.js b/test/configCases/plugins/environment-plugin/errors.js index b670159cab1..b393e2ba6ab 100644 --- a/test/configCases/plugins/environment-plugin/errors.js +++ b/test/configCases/plugins/environment-plugin/errors.js @@ -1,43 +1,60 @@ -const variables = ['aaa', 'bbb', 'ccc', 'ddd', 'eee', 'fff', 'ggg', 'hhh', 'iii']; -const modules = [{ - name: 'aaa', - variables: ['aaa'] -}, { - name: 'bbbccc', - variables: ['bbb', 'ccc'] -}, { - name: 'ddd', - variables: [], - allowedErrors: [ - [{compilerPath: /ddd/}, /DDD environment variable is undefined./] - ] -}, { - name: 'eeefff', - variables: ['eee', 'fff'] -}, { - name: 'ggghhh', - variables: ['ggg', 'hhh'] -}, { - name: 'iii', - variables: ['iii'] -}]; +const variables = [ + "aaa", + "bbb", + "ccc", + "ddd", + "eee", + "fff", + "ggg", + "hhh", + "iii" +]; +const modules = [ + { + name: "aaa", + variables: ["aaa"] + }, + { + name: "bbbccc", + variables: ["bbb", "ccc"] + }, + { + name: "ddd", + variables: [], + allowedErrors: [ + [{ compilerPath: /ddd/ }, /DDD environment variable is undefined./] + ] + }, + { + name: "eeefff", + variables: ["eee", "fff"] + }, + { + name: "ggghhh", + variables: ["ggg", "hhh"] + }, + { + name: "iii", + variables: ["iii"] + } +]; // build an array of regular expressions of expected errors const regex = []; -modules.forEach(module => { - variables.forEach(variable => { - if (module.variables.indexOf(variable) === -1) { +for (const module of modules) { + for (const variable of variables) { + if (!module.variables.includes(variable)) { // the module doesn't include the env variable, an error is expected when requiring the variable regex.push([ - {compilerPath: new RegExp(`${module.name}`)}, - new RegExp(`Can't resolve '${variable}'`), + { compilerPath: new RegExp(`${module.name}`) }, + new RegExp(`Can't resolve '${variable}'`) ]); } - }); - + } + if (module.allowedErrors) { - regex.push(...module.allowedErrors) + regex.push(...module.allowedErrors); } -}); +} module.exports = regex; diff --git a/test/configCases/plugins/limit-chunk-count-plugin/a.js b/test/configCases/plugins/limit-chunk-count-plugin/a.js new file mode 100644 index 00000000000..42ca9ffa910 --- /dev/null +++ b/test/configCases/plugins/limit-chunk-count-plugin/a.js @@ -0,0 +1,3 @@ +const value = (await import("./b")).default; + +export { value }; diff --git a/test/configCases/plugins/limit-chunk-count-plugin/b.js b/test/configCases/plugins/limit-chunk-count-plugin/b.js new file mode 100644 index 00000000000..d0cf1e996dd --- /dev/null +++ b/test/configCases/plugins/limit-chunk-count-plugin/b.js @@ -0,0 +1,3 @@ +const value = (await import("./c")).default; + +export default value; diff --git a/test/configCases/plugins/limit-chunk-count-plugin/c.js b/test/configCases/plugins/limit-chunk-count-plugin/c.js new file mode 100644 index 00000000000..bebcb58a8ea --- /dev/null +++ b/test/configCases/plugins/limit-chunk-count-plugin/c.js @@ -0,0 +1 @@ +export default "fine"; diff --git a/test/configCases/plugins/limit-chunk-count-plugin/index.js b/test/configCases/plugins/limit-chunk-count-plugin/index.js new file mode 100644 index 00000000000..35134a0b495 --- /dev/null +++ b/test/configCases/plugins/limit-chunk-count-plugin/index.js @@ -0,0 +1,5 @@ +it("should merge chunks", async () => { + const { value } = await import("./a"); + expect(value).toBe("fine") +}); + diff --git a/test/configCases/plugins/limit-chunk-count-plugin/test.config.js b/test/configCases/plugins/limit-chunk-count-plugin/test.config.js new file mode 100644 index 00000000000..2e3be0636e9 --- /dev/null +++ b/test/configCases/plugins/limit-chunk-count-plugin/test.config.js @@ -0,0 +1,5 @@ +module.exports = { + findBundle: function (i, options) { + return ["main.js"]; + } +}; diff --git a/test/configCases/plugins/limit-chunk-count-plugin/test.js b/test/configCases/plugins/limit-chunk-count-plugin/test.js new file mode 100644 index 00000000000..c9d8865844b --- /dev/null +++ b/test/configCases/plugins/limit-chunk-count-plugin/test.js @@ -0,0 +1,3 @@ +var foo = {}; + +module.exports = foo; diff --git a/test/configCases/plugins/limit-chunk-count-plugin/vendors.js b/test/configCases/plugins/limit-chunk-count-plugin/vendors.js new file mode 100644 index 00000000000..39ad0d4e1e0 --- /dev/null +++ b/test/configCases/plugins/limit-chunk-count-plugin/vendors.js @@ -0,0 +1,3 @@ +var bar = {}; + +module.exports = bar; diff --git a/test/configCases/plugins/limit-chunk-count-plugin/webpack.config.js b/test/configCases/plugins/limit-chunk-count-plugin/webpack.config.js new file mode 100644 index 00000000000..b53792113ee --- /dev/null +++ b/test/configCases/plugins/limit-chunk-count-plugin/webpack.config.js @@ -0,0 +1,13 @@ +var webpack = require("../../../../"); +/** @type {import("../../../../").Configuration} */ +module.exports = { + node: { + __dirname: false, + __filename: false + }, + entry: "./index.js", + output: { + filename: "[name].js" + }, + plugins: [new webpack.optimize.LimitChunkCountPlugin({ maxChunks: 1 })] +}; diff --git a/test/configCases/plugins/loader-options-plugin/loader.js b/test/configCases/plugins/loader-options-plugin/loader.js index 7374ef2b557..8fcf0774460 100644 --- a/test/configCases/plugins/loader-options-plugin/loader.js +++ b/test/configCases/plugins/loader-options-plugin/loader.js @@ -1,6 +1,10 @@ -module.exports = function() { - return "module.exports = " + JSON.stringify({ - minimize: this.minimize, - jsfile: this.jsfile - }); +/** @type {import("../../../../").LoaderDefinition<{}, { minimize: boolean, jsfile: boolean }>} */ +module.exports = function () { + return ( + "module.exports = " + + JSON.stringify({ + minimize: this.minimize, + jsfile: this.jsfile + }) + ); }; diff --git a/test/configCases/plugins/mini-css-extract-plugin/test.config.js b/test/configCases/plugins/mini-css-extract-plugin/test.config.js index 43100293483..9cfb73308ad 100644 --- a/test/configCases/plugins/mini-css-extract-plugin/test.config.js +++ b/test/configCases/plugins/mini-css-extract-plugin/test.config.js @@ -1,5 +1,5 @@ module.exports = { - findBundle: function(i, options) { - return ["a.js", "b.js", "c.js"]; + findBundle: function (i, options) { + return [`${i}_a.js`, `${i}_b.js`, `${i}_c.js`]; } }; diff --git a/test/configCases/plugins/mini-css-extract-plugin/webpack.config.js b/test/configCases/plugins/mini-css-extract-plugin/webpack.config.js index b04b470d415..3cb4577f372 100644 --- a/test/configCases/plugins/mini-css-extract-plugin/webpack.config.js +++ b/test/configCases/plugins/mini-css-extract-plugin/webpack.config.js @@ -1,7 +1,7 @@ var MCEP = require("mini-css-extract-plugin"); -/** @type {import("../../../../").Configuration} */ -module.exports = { +/** @type {(number, any) => import("../../../../").Configuration} */ +const config = (i, options) => ({ entry: { a: "./a", b: "./b", @@ -9,13 +9,20 @@ module.exports = { x: "./x" // also imports chunk but with different exports }, output: { - filename: "[name].js" + filename: `${i}_[name].js`, + pathinfo: false }, module: { rules: [ { - test: /\.css$/, - use: [MCEP.loader, "css-loader"] + oneOf: [ + { + test: /\.css$/, + use: [MCEP.loader, "css-loader"] + }, + { test: /\.js$/ }, + { type: "asset" } + ] } ] }, @@ -27,7 +34,7 @@ module.exports = { __dirname: false }, plugins: [ - new MCEP(), + new MCEP(options), compiler => { compiler.hooks.done.tap("Test", stats => { const chunkIds = stats @@ -47,4 +54,11 @@ module.exports = { }); } ] -}; +}); + +module.exports = [ + config(0), + config(1, { + experimentalUseImportModule: true + }) +]; diff --git a/test/configCases/plugins/profiling-plugin/test.config.js b/test/configCases/plugins/profiling-plugin/test.config.js new file mode 100644 index 00000000000..5ef314060c9 --- /dev/null +++ b/test/configCases/plugins/profiling-plugin/test.config.js @@ -0,0 +1,3 @@ +module.exports = { + timeout: 60000 +}; diff --git a/test/configCases/plugins/profiling-plugin/test.filter.js b/test/configCases/plugins/profiling-plugin/test.filter.js index b36fb8fa768..71a71e594ff 100644 --- a/test/configCases/plugins/profiling-plugin/test.filter.js +++ b/test/configCases/plugins/profiling-plugin/test.filter.js @@ -1,3 +1,3 @@ -module.exports = function(config) { +module.exports = function (config) { return !process.env.CI; }; diff --git a/test/configCases/plugins/progress-plugin/webpack.config.js b/test/configCases/plugins/progress-plugin/webpack.config.js index 3fc4768beba..eb6ec410014 100644 --- a/test/configCases/plugins/progress-plugin/webpack.config.js +++ b/test/configCases/plugins/progress-plugin/webpack.config.js @@ -4,7 +4,7 @@ const data = require("./data"); /** @type {import("../../../../").Configuration} */ module.exports = { externals: { - data: "commonjs " + path.resolve(__dirname, "data.js") + data: `commonjs ${path.resolve(__dirname, "data.js")}` }, plugins: [ new webpack.ProgressPlugin((value, ...messages) => { diff --git a/test/configCases/plugins/provide-plugin/a.js b/test/configCases/plugins/provide-plugin/a.js new file mode 100644 index 00000000000..f8297ed707d --- /dev/null +++ b/test/configCases/plugins/provide-plugin/a.js @@ -0,0 +1,2 @@ +export * as c from "./b"; +export * as c2 from "./harmony2"; diff --git a/test/configCases/plugins/provide-plugin/b.js b/test/configCases/plugins/provide-plugin/b.js new file mode 100644 index 00000000000..64bcdcfb6b8 --- /dev/null +++ b/test/configCases/plugins/provide-plugin/b.js @@ -0,0 +1,7 @@ +export function square(x) { + return x * x; +} + +export function cube(x) { + return x * x * x; +} diff --git a/test/configCases/plugins/provide-plugin/harmony2.js b/test/configCases/plugins/provide-plugin/harmony2.js new file mode 100644 index 00000000000..cabd2fbbb5f --- /dev/null +++ b/test/configCases/plugins/provide-plugin/harmony2.js @@ -0,0 +1,2 @@ +export const a = 1; +export const aUsed = __webpack_exports_info__.a.used; diff --git a/test/configCases/plugins/provide-plugin/index.js b/test/configCases/plugins/provide-plugin/index.js index 976ac6a2ce6..989d9ff0692 100644 --- a/test/configCases/plugins/provide-plugin/index.js +++ b/test/configCases/plugins/provide-plugin/index.js @@ -48,6 +48,11 @@ it("should provide a module for a property request", function() { expect(x).toBe("fff"); }); +it("should tree-shake unused exports", function() { + expect(aa1(2)).toBe(8); + expect(es2015_aUsed).toBe(false); +}); + it("should provide ES2015 modules", function() { expect((es2015.default)).toBe("ECMAScript 2015"); expect((es2015.alias)).toBe("ECMAScript Harmony"); diff --git a/test/configCases/plugins/provide-plugin/webpack.config.js b/test/configCases/plugins/provide-plugin/webpack.config.js index 508bb2c5719..d51e6549adf 100644 --- a/test/configCases/plugins/provide-plugin/webpack.config.js +++ b/test/configCases/plugins/provide-plugin/webpack.config.js @@ -6,6 +6,8 @@ module.exports = { aaa: "./aaa", "bbb.ccc": "./bbbccc", dddeeefff: ["./ddd", "eee", "3-f"], + aa1: ["./a", "c", "cube"], + es2015_aUsed: ["./harmony2", "aUsed"], "process.env.NODE_ENV": "./env", es2015: "./harmony", es2015_name: ["./harmony", "default"], diff --git a/test/configCases/plugins/source-map-dev-tool-plugin-append-function/index.js b/test/configCases/plugins/source-map-dev-tool-plugin-append-function/index.js new file mode 100644 index 00000000000..464fe983765 --- /dev/null +++ b/test/configCases/plugins/source-map-dev-tool-plugin-append-function/index.js @@ -0,0 +1,6 @@ +it("should have [file] replaced with chunk filename in append", function() { + const fs = require("fs"), + path = require("path"); + const source = fs.readFileSync(path.join(__dirname, "some-test.js"), "utf-8"); + expect(source).toMatch("//# sourceMappingURL=http://localhost:50505/some-test.js.map"); +}); diff --git a/test/configCases/plugins/source-map-dev-tool-plugin-append-function/test.js b/test/configCases/plugins/source-map-dev-tool-plugin-append-function/test.js new file mode 100644 index 00000000000..a6b9cb13401 --- /dev/null +++ b/test/configCases/plugins/source-map-dev-tool-plugin-append-function/test.js @@ -0,0 +1,5 @@ +const testObject = { + a: 1 +}; + +module.exports = testObject; diff --git a/test/configCases/plugins/source-map-dev-tool-plugin-append-function/webpack.config.js b/test/configCases/plugins/source-map-dev-tool-plugin-append-function/webpack.config.js new file mode 100644 index 00000000000..3fa7647084c --- /dev/null +++ b/test/configCases/plugins/source-map-dev-tool-plugin-append-function/webpack.config.js @@ -0,0 +1,26 @@ +const webpack = require("../../../../"); +const TerserPlugin = require("terser-webpack-plugin"); + +/** @type {import("../../../../types").Configuration} */ +module.exports = { + node: { + __dirname: false, + __filename: false + }, + entry: { + bundle0: ["./index.js"], + "some-test": ["./test.js"] + }, + output: { + filename: "[name].js" + }, + optimization: { + minimizer: [new TerserPlugin()] + }, + plugins: [ + new webpack.SourceMapDevToolPlugin({ + filename: "sourcemaps/[file].map", + append: data => "\n//# sourceMappingURL=http://localhost:50505/[file].map" + }) + ] +}; diff --git a/test/configCases/plugins/source-map-dev-tool-plugin/index.js b/test/configCases/plugins/source-map-dev-tool-plugin/index.js index 53b37f635a1..30bc39f5040 100644 --- a/test/configCases/plugins/source-map-dev-tool-plugin/index.js +++ b/test/configCases/plugins/source-map-dev-tool-plugin/index.js @@ -5,7 +5,7 @@ it("should contain publicPath prefix in [url] and resolve relatively to fileCont expect(source).toMatch("//# sourceMappingURL=https://10.10.10.10/project/sourcemaps/test.js.map"); }); -it("should write sourcemap file relative fo fileContext", function() { +it("should write sourcemap file relative to fileContext", function() { var fs = require("fs"), path = require("path"); expect(fs.existsSync(path.join(__dirname, "sourcemaps/test.js.map"))).toBe(true); diff --git a/test/configCases/process-assets/html-plugin/infrastructure-log.js b/test/configCases/process-assets/html-plugin/infrastructure-log.js new file mode 100644 index 00000000000..0297c93d8a7 --- /dev/null +++ b/test/configCases/process-assets/html-plugin/infrastructure-log.js @@ -0,0 +1,5 @@ +module.exports = [ + // each time returns different OriginalSource in webpack.config.js:78 + // this prevents hit in inmemory cache + /^Pack got invalid because of write to: RealContentHashPlugin|analyse|index\.html$/ +]; diff --git a/test/configCases/process-assets/html-plugin/webpack.config.js b/test/configCases/process-assets/html-plugin/webpack.config.js index d1c63c8d603..98abbd4842e 100644 --- a/test/configCases/process-assets/html-plugin/webpack.config.js +++ b/test/configCases/process-assets/html-plugin/webpack.config.js @@ -65,8 +65,8 @@ class HtmlPlugin { contenthash: Array.isArray(assetInfo.contenthash) ? [...new Set([...assetInfo.contenthash, integrity])] : assetInfo.contenthash - ? [assetInfo.contenthash, integrity] - : integrity + ? [assetInfo.contenthash, integrity] + : integrity }) ); return `